diff --git a/act.js b/act.js index f51db6c..cb6cfe9 100644 --- a/act.js +++ b/act.js @@ -63,7 +63,15 @@ Me: Sure! I'm on my way.`, \`\`\` await skills.goToPlayer(bot, 'user42'); \`\`\``, - ] + +`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'); +\`\`\``, +] } @@ -85,13 +93,13 @@ export async function executeCode(bot) { console.log('executing code...\n' + currentCode); try { - await (await import('./temp.js')).main(bot); + let ouput = await (await import('./temp.js')).main(bot); + console.log(`Code output: *\n${ouput}\n*`); } catch (err) { console.log(err); currentCode = ''; return false; } - currentCode = ''; return true; } @@ -101,26 +109,32 @@ export async function writeCode(bot, username, messages) { let turns = buildExamples(); // For now, get rid of the first 6 example messages - messages = messages.slice(6); + messages = messages.slice(8); // TODO: fix this, very spaghetti let startIndex = messages.length - 6; if (startIndex < 0) startIndex = 0; - turns.push(''); + let nextTurn = ''; for (let i = startIndex; i < messages.length; i++) { if (i % 2 == 0) { - turns[turns.length - 1] += `\n\n${username}: ${messages[i]}`; + nextTurn += `${username}: ${messages[i]}\n\n`; } else { - turns[turns.length - 1] += `\n\nMe: ${messages[i]}`; + nextTurn += `Me: ${messages[i]}\n\n`; + turns.push(nextTurn); + nextTurn = ''; } } + if (nextTurn) + turns.push(nextTurn); turns[turns.length - 1] = turns[turns.length - 1].trim(); + console.log("Action request input:", turns); let systemMessage = buildSystemMessage(bot); let actResponse = await sendRequest(turns, systemMessage); - console.log(actResponse); + console.log("Action response:", actResponse); let code = actResponse.split('\`\`\`'); + console.log(code); if (code.length <= 1) return code; if (!code[1].trim()) diff --git a/chat.js b/chat.js index a53a1bb..9de8f32 100644 --- a/chat.js +++ b/chat.js @@ -1,6 +1,6 @@ import { sendRequest } from './utils/gpt.js'; import { getHistory, addEvent } from './utils/history.js'; -import { getCommand, getCommandDocs } from './utils/commands.js'; +import { containsCommand, getCommand, getCommandDocs } from './utils/commands.js'; function buildSystemMessage(bot) { @@ -22,23 +22,24 @@ export async function getChatResponse(bot, user, message) { let botFinalRes = ''; let botEvent = ''; let botRes = null; - console.log("*recieved chat:", message) + console.log("*recieved chat:", message); for (let i = 0; i < MAX_TURNS; i++) { botRes = await sendRequest(turns, systemMessage, '\`\`\`'); - console.log(`bot response ${i}:`, botRes); - - let commandRes = null; - let firstword = botRes.trim().split(/\s+/)[0]; - let command = getCommand(firstword); - if (command) { - console.log('Executing command:', command.name) - commandRes = await command.perform(bot); + console.log(`bot response ${i}: "${botRes}"`); + let command_name = containsCommand(botRes) + if (command_name) { + let command = getCommand(command_name); + let commandRes = await command.perform(bot, user, turns.concat(botRes)); botEvent += `/n${command.name}/n${commandRes}`; if (i == 0) turns.push(botEvent); else turns[turns.length - 1] += botEvent; + if (command_name == '!execute') { + botFinalRes = "Executing Code"; + break; + } } else { botFinalRes = botRes; break; @@ -47,6 +48,6 @@ export async function getChatResponse(bot, user, message) { console.log('*bot response', botFinalRes); console.log('*bot event', botEvent); - addEvent('bot', botEvent); + addEvent('bot', turns[turns.length - 1]); return botFinalRes.trim(); } diff --git a/utils/commands.js b/utils/commands.js index 3dfe61c..413b634 100644 --- a/utils/commands.js +++ b/utils/commands.js @@ -1,5 +1,5 @@ import { getStats, getInventory, getBlocks, getNearbyEntities, getCraftable } from './context.js'; -import { currentCode, executeCode, writeCode } from '../act.js'; +import { currentCode, writeCode } from '../act.js'; const pad = (str) => { return '\n\`\`\`\n' + str + '\n\`\`\`'; @@ -9,50 +9,50 @@ const commandsList = [ { name: "!stats", description: "Get the bot's stats (name, health, food, saturation, armor, held item, position, velocity, gamemode, experience, level, effects).", - perform: function (bot) { + perform: function (bot, user, turns) { return pad(getStats(bot)); } }, { name: "!inventory", description: "Get the bot's inventory.", - perform: function (bot) { + perform: function (bot, user, turns) { return pad(getInventory(bot)); } }, { name: "!blocks", description: "Get the blocks near the bot.", - perform: function (bot) { + perform: function (bot, user, turns) { return pad(getBlocks(bot)); } }, { name: "!craftable", description: "Get the craftable items with the bot's inventory.", - perform: function (bot) { + perform: function (bot, user, turns) { return pad(getCraftable(bot)); } }, { name: "!entities", description: "Get the nearby players and entities.", - perform: function (bot) { + perform: function (bot, user, turns) { return pad(getNearbyEntities(bot)); } }, { name: "!action", description: "Get the currently executing code.", - perform: function (bot) { + perform: function (bot, user, turns) { return pad(currentCode(bot)); } }, { name: "!execute", - description: "Execute actions in the game by writing and calling javascript code with the following command: \n!execute\n\`\`\`\nCODE\n\`\`\`", - perform: function (bot) { - return writeCode(bot, user, turns.concat(botResponse), botResponse); + description: "Write javascript code to move, mine, build, or do anything else in the minecraft world. Example usage: \n!execute\n\`\`\`\nCODE\n\`\`\`", + perform: function (bot, user, turns) { + return writeCode(bot, user, turns); } } ]; @@ -66,13 +66,18 @@ export function getCommand(name) { return commandsMap[name]; } -export function commandExists(name) { - return commandsMap[name] != undefined; +export function containsCommand(message) { + for (let command of commandsList) { + if (message.includes(command.name)) { + return command.name; + } + } + return null; } export function getCommandDocs() { - let docs = `COMMAND DOCS\n***\n You can use the following commands followed by to query for information about the world. - Some are not implemented yet and will return null. Respond with only the command name to request information.\n`; + let docs = `COMMAND DOCS\n***\n You can use the following commands to query for information about the world. + The first word of your response must be a command name in order to use commands. \n`; for (let command of commandsList) { docs += command.name + ': ' + command.description + '\n'; } diff --git a/utils/history.js b/utils/history.js index 152bdf2..5e2994e 100644 --- a/utils/history.js +++ b/utils/history.js @@ -29,7 +29,14 @@ while (true) { await skills.goToPlayer(bot, 'username'); await skills.DropItem(bot, 'oak_log', 1); } -\`\`\``} +\`\`\``}, +{'source': 'all', 'message': 'come here'}, +{'source': 'bot', 'message': `Sure! I'm on my way. + +!execute +\`\`\` +await skills.goToPlayer(bot, 'user42'); +\`\`\``}, ];