mindcraft/act.js

149 lines
4 KiB
JavaScript
Raw Normal View History

2023-11-06 21:53:15 -08:00
import { writeFileSync } from 'fs';
2023-08-15 23:39:02 -07:00
2023-08-17 00:00:57 -07:00
import { getDetailedSkills, getWorldFunctions } from './utils/context.js';
2023-08-15 23:39:02 -07:00
import { sendRequest } from './utils/gpt.js';
function buildSystemMessage(bot) {
2023-08-17 00:00:57 -07:00
let message = 'You are a helpful Minecraft bot. Given the dialogue, reflect on what you are doing and generate javascript code to accomplish that goal. Use only functions listed below to write your code.';
message += "\n\n" + getDetailedSkills();
message += "\n\n" + getWorldFunctions();
2023-08-15 23:39:02 -07:00
return message;
}
function buildExamples() {
2023-09-29 15:53:16 -07:00
return [
2023-08-15 23:39:02 -07:00
`mr_steve2: Will you help me collect wood?
2023-08-17 00:00:57 -07:00
!blocks
2023-08-15 23:39:02 -07:00
\`\`\`
2023-08-17 00:00:57 -07:00
NEARBY_BLOCKS
- oak_log
- dirt
- cobblestone
2023-08-15 23:39:02 -07:00
\`\`\`
2023-08-17 00:00:57 -07:00
Me: I'd be glad to help you collect wood.`,
2023-09-29 15:53:16 -07:00
`I'm going to help mr_steve2 collect wood. The type of wood block nearby is 'oak_log'. I'll adjust my code to collect an 'oak_log' for mr_steve2.
2023-08-17 00:00:57 -07:00
\`\`\`
2023-09-29 15:53:16 -07:00
await skills.collectBlock(bot, 'oak_log');
await skills.giveToPlayer(bot, 'oak_log', 'mr_steve2');
2023-08-15 23:39:02 -07:00
\`\`\``,
`sally32: What are you doing?
2023-08-17 00:00:57 -07:00
!action
2023-08-15 23:39:02 -07:00
\`\`\`
2023-09-29 15:53:16 -07:00
await skills.equipItem(bot, 'wooden_pickaxe');
while (world.getInventory(bot).coal_ore < 10) {
await skills.collectBlock(bot, 'coal_ore');
}
2023-08-17 00:00:57 -07:00
\`\`\`
Me: I'm looking for coal. Have you seen any?
sally32: Yes, there's some in this cave, follow me.`,
`I'm going to follow sally32 to the cave and collect coal. I'll adjust my code to follow sally32 until I find coal_ore and then I'll mine it.
\`\`\`
while (true) {
2023-09-29 15:53:16 -07:00
await skills.goToPlayer(bot, 'sally32');
2023-08-17 00:00:57 -07:00
if (world.getNearbyBlocks(bot).includes('coal_ore')) {
break;
}
}
2023-09-29 15:53:16 -07:00
await skills.equipItem(bot, 'wooden_pickaxe');
while (world.getInventory(bot).coal_ore < 10) {
await skills.collectBlock(bot, 'coal_ore');
}
2023-08-15 23:39:02 -07:00
\`\`\``,
2023-08-17 00:00:57 -07:00
`user42: come here
Me: Sure! I'm on my way.`,
`I'm going to navigate to user42.
2023-08-15 23:39:02 -07:00
\`\`\`
2023-09-29 15:53:16 -07:00
await skills.goToPlayer(bot, 'user42');
2023-08-15 23:39:02 -07:00
\`\`\``,
2023-11-05 15:38:52 -06:00
`user42: execute some code that says "hello world"
Me: Okay, I'll do that now.`,
`I'm going to log "hello world" to the console.
\`\`\`
console.log('hello world');
\`\`\``,
]
2023-08-15 23:39:02 -07:00
}
2023-08-17 00:00:57 -07:00
export var currentCode = '';
export async function executeCode(bot) {
let src = "import * as skills from './utils/skills.js';";
src += "\nimport * as world from './utils/world.js';"
src += `\n\nexport async function main(bot) {\n`;
for (let line of currentCode.split('\n')) {
2023-08-15 23:39:02 -07:00
src += ` ${line}\n`;
}
src += `}\n`;
2023-11-06 21:53:15 -08:00
writeFileSync('./temp.js', src, (err) => {
2023-08-15 23:39:02 -07:00
if (err) throw err;
});
2023-08-17 00:00:57 -07:00
console.log('executing code...\n' + currentCode);
try {
2023-11-05 15:38:52 -06:00
let ouput = await (await import('./temp.js')).main(bot);
console.log(`Code output: *\n${ouput}\n*`);
2023-08-17 00:00:57 -07:00
} catch (err) {
console.log(err);
2023-09-29 12:53:56 -07:00
currentCode = '';
2023-08-17 00:00:57 -07:00
return false;
}
2023-09-29 12:53:56 -07:00
currentCode = '';
2023-08-17 00:00:57 -07:00
return true;
2023-08-15 23:39:02 -07:00
}
2023-08-17 00:00:57 -07:00
export async function writeCode(bot, username, messages) {
2023-08-15 23:39:02 -07:00
let turns = buildExamples();
2023-08-17 00:00:57 -07:00
// For now, get rid of the first 6 example messages
2023-11-05 15:38:52 -06:00
messages = messages.slice(8); // TODO: fix this, very spaghetti
2023-08-17 00:00:57 -07:00
let startIndex = messages.length - 6;
if (startIndex < 0)
startIndex = 0;
2023-11-05 15:38:52 -06:00
let nextTurn = '';
2023-08-17 00:00:57 -07:00
for (let i = startIndex; i < messages.length; i++) {
if (i % 2 == 0) {
2023-11-05 15:38:52 -06:00
nextTurn += `${username}: ${messages[i]}\n\n`;
2023-08-17 00:00:57 -07:00
} else {
2023-11-05 15:38:52 -06:00
nextTurn += `Me: ${messages[i]}\n\n`;
turns.push(nextTurn);
nextTurn = '';
2023-08-17 00:00:57 -07:00
}
}
2023-11-05 15:38:52 -06:00
if (nextTurn)
turns.push(nextTurn);
2023-08-17 00:00:57 -07:00
turns[turns.length - 1] = turns[turns.length - 1].trim();
2023-11-05 15:38:52 -06:00
console.log("Action request input:", turns);
2023-08-15 23:39:02 -07:00
let systemMessage = buildSystemMessage(bot);
let actResponse = await sendRequest(turns, systemMessage);
2023-11-05 15:38:52 -06:00
console.log("Action response:", actResponse);
2023-08-15 23:39:02 -07:00
let code = actResponse.split('\`\`\`');
2023-11-05 15:38:52 -06:00
console.log(code);
2023-08-15 23:39:02 -07:00
if (code.length <= 1)
2023-09-29 12:53:56 -07:00
return code;
2023-08-15 23:39:02 -07:00
if (!code[1].trim())
2023-09-29 12:53:56 -07:00
return code;
2023-08-15 23:39:02 -07:00
currentCode = code[1].trim();
if (currentCode.slice(0, 10) == 'javascript')
currentCode = currentCode.slice(10).trim();
2023-09-29 12:53:56 -07:00
return currentCode;
2023-08-15 23:39:02 -07:00
}