mirror of
https://github.com/kolbytn/mindcraft.git
synced 2025-07-23 08:25:19 +02:00
refactored commands into map of objects/funcs
This commit is contained in:
parent
54da4c9032
commit
126537be67
4 changed files with 119 additions and 47 deletions
77
chat.js
77
chat.js
|
@ -1,67 +1,54 @@
|
|||
import { sendRequest } from './utils/gpt.js';
|
||||
import { getHistory, addEvent } from './utils/history.js';
|
||||
import { getStats, getInventory, getBlocks, getNearbyEntities, getCraftable } from './utils/context.js';
|
||||
import { currentCode, writeCode } from './act.js';
|
||||
import { getStats, getInventory, getBlocks, getNearbyPlayers, getNearbyEntities, getCraftable } from './utils/context.js';
|
||||
import { currentCode, executeCode, writeCode } from './act.js';
|
||||
import { getCommand, getCommandDocs } from './utils/commands.js';
|
||||
|
||||
|
||||
function buildSystemMessage() {
|
||||
let message = 'You are a playful Minecraft bot that can communicate with players and move within and interact with the world.';
|
||||
message += ' Act human-like as if you were a typical Minecraft player, rather than an AI.';
|
||||
message += ' Do not give instructions unless asked, and always be brief in your responses.';
|
||||
message += '\n\nYou can use the following commands followed by to query for information about the world.';
|
||||
message += ' The query response will be returned between sets of "\`\`\`":';
|
||||
message += '\n!stats - get player and world stats (current health, time of day, etc.)';
|
||||
message += '\n!inventory - get your current inventory';
|
||||
message += '\n!blocks - get a list of nearby blocks';
|
||||
message += '\n!craftable - get a list of craftable items with your current inventory';
|
||||
message += '\n!entities - get a list of nearby players and entities';
|
||||
message += '\n!action - get the currently executing code';
|
||||
message += '\n\nYou can also execute actions such as moving and mining in Minecraft by writing javascript code.';
|
||||
message += ' To do so, simply begin a codeblock with the "!execute" command. For example:';
|
||||
message += '\n!execute\n\`\`\`\nCODE\n\`\`\`';
|
||||
function buildSystemMessage(bot) {
|
||||
let message = `You are a playful Minecraft bot that can communicate with players and move within and interact with the world.';
|
||||
Act human-like as if you were a typical Minecraft player, rather than an AI.';
|
||||
Do not give instructions unless asked, and always be brief in your responses.\n`;
|
||||
message += getCommandDocs();
|
||||
return message;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const MAX_TURNS = 5;
|
||||
export async function getChatResponse(bot, user, message) {
|
||||
addEvent(user, message);
|
||||
let turns = getHistory(user);
|
||||
let systemMessage = buildSystemMessage();
|
||||
|
||||
let botResponse = '';
|
||||
let botFinalRes = '';
|
||||
let botEvent = '';
|
||||
let res = null;
|
||||
for (let i = 0; i < 5; i++) {
|
||||
let botRes = null;
|
||||
console.log("*recieved chat:", message)
|
||||
for (let i = 0; i < MAX_TURNS; i++) {
|
||||
botRes = await sendRequest(turns, systemMessage, '\`\`\`');
|
||||
console.log(`bot response ${i}:`, botRes);
|
||||
|
||||
res = await sendRequest(turns, systemMessage, '\`\`\`');
|
||||
console.log('received chat:', res);
|
||||
|
||||
let queryRes = null;
|
||||
if (res.includes('!stats')) {
|
||||
queryRes = '\n\n!stats\n\`\`\`\n' + getStats(bot) + '\n\`\`\`';
|
||||
} else if (res.includes('!inventory')) {
|
||||
queryRes = '\n\n!inventory\n\`\`\`\n' + getInventory(bot) + '\n\`\`\`';
|
||||
} else if (res.includes('!blocks')) {
|
||||
queryRes = '\n\n!blocks\n\`\`\`\n' + getBlocks(bot) + '\n\`\`\`';
|
||||
} else if (res.includes('!craftable')) {
|
||||
queryRes = '\n\n!craftable\n\`\`\`\n' + getCraftable(bot) + '\n\`\`\`';
|
||||
} else if (res.includes('!entities')) {
|
||||
queryRes = '\n\n!entities\n\`\`\`\n' + getNearbyEntities(bot) + '\n\`\`\`';
|
||||
} else if (res.includes('!action')) {
|
||||
queryRes = '\n\n!action\n\`\`\`\n' + currentCode + '\n\`\`\`';
|
||||
} else if (res.includes('!execute')) {
|
||||
queryRes = '\n\n!execute\n\`\`\`\n' + await writeCode(bot, user, turns.concat(botResponse), botResponse) + '\n\`\`\`';
|
||||
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);
|
||||
|
||||
botEvent += `/n${command.name}/n${commandRes}`;
|
||||
if (i == 0)
|
||||
turns.push(botEvent);
|
||||
else
|
||||
turns[turns.length - 1] += botEvent;
|
||||
} else {
|
||||
botResponse += '\n' + res.trim();
|
||||
botFinalRes = botRes;
|
||||
break;
|
||||
}
|
||||
|
||||
console.log('query response:', queryRes);
|
||||
botEvent += queryRes;
|
||||
turns[turns.length - 1] += queryRes
|
||||
}
|
||||
|
||||
console.log('sending chat:', botResponse.trim());
|
||||
console.log('*bot response', botFinalRes);
|
||||
console.log('*bot event', botEvent);
|
||||
addEvent('bot', botEvent);
|
||||
return botResponse.trim();
|
||||
return botFinalRes.trim();
|
||||
}
|
||||
|
|
7
main.js
7
main.js
|
@ -6,6 +6,7 @@ import { getChatResponse } from './chat.js';
|
|||
import { executeCode } from './act.js';
|
||||
|
||||
|
||||
|
||||
async function handleMessage(username, message) {
|
||||
if (username === bot.username) return;
|
||||
console.log('received message from', username, ':', message);
|
||||
|
@ -23,7 +24,7 @@ async function handleMessage(username, message) {
|
|||
const bot = createBot({
|
||||
host: '127.0.0.1',
|
||||
port: 55916,
|
||||
username: 'andi'
|
||||
username: 'andy'
|
||||
})
|
||||
bot.loadPlugin(pathfinder)
|
||||
bot.loadPlugin(plugin)
|
||||
|
@ -32,3 +33,7 @@ console.log('bot created')
|
|||
|
||||
bot.on('chat', handleMessage);
|
||||
bot.on('whisper', handleMessage);
|
||||
|
||||
bot.once("login", () => {
|
||||
bot.chat('hello world!')
|
||||
});
|
80
utils/commands.js
Normal file
80
utils/commands.js
Normal file
|
@ -0,0 +1,80 @@
|
|||
import { getStats, getInventory, getBlocks, getNearbyPlayers, getNearbyEntities, getCraftable } from './context.js';
|
||||
import { currentCode, executeCode, writeCode } from '../act.js';
|
||||
|
||||
const pad = (str) => {
|
||||
return '\n\`\`\`\n' + str + '\n\`\`\`';
|
||||
}
|
||||
|
||||
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) {
|
||||
return pad(getStats(bot));
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "!inventory",
|
||||
description: "Get the bot's inventory.",
|
||||
perform: function (bot) {
|
||||
return pad(getInventory(bot));
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "!blocks",
|
||||
description: "Get the blocks near the bot.",
|
||||
perform: function (bot) {
|
||||
return pad(getBlocks(bot));
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "!craftable",
|
||||
description: "Get the craftable items with the bot's inventory.",
|
||||
perform: function (bot) {
|
||||
return pad(getCraftable(bot));
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "!entities",
|
||||
description: "Get the nearby players and entities.",
|
||||
perform: function (bot) {
|
||||
return pad(getNearbyPlayers(bot) + '\n' + getNearbyEntities(bot));
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "!action",
|
||||
description: "Get the currently executing code.",
|
||||
perform: function (bot) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
const commandsMap = {};
|
||||
for (let command of commandsList) {
|
||||
commandsMap[command.name] = command;
|
||||
}
|
||||
|
||||
export function getCommand(name) {
|
||||
return commandsMap[name];
|
||||
}
|
||||
|
||||
export function commandExists(name) {
|
||||
return commandsMap[name] != undefined;
|
||||
}
|
||||
|
||||
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`;
|
||||
for (let command of commandsList) {
|
||||
docs += command.name + ': ' + command.description + '\n';
|
||||
}
|
||||
return docs + '\n***\n';
|
||||
}
|
|
@ -179,5 +179,5 @@ export function getNearbyBlockTypes(bot) {
|
|||
found.push(blocks[i].name);
|
||||
}
|
||||
}
|
||||
return found;
|
||||
return Array.from(blockNames);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue