mirror of
https://github.com/kolbytn/mindcraft.git
synced 2025-08-13 18:55:34 +02:00
added command param parsing
This commit is contained in:
parent
7d35ef1bfc
commit
0decd272f3
5 changed files with 100 additions and 42 deletions
|
@ -2,7 +2,7 @@ import { initBot } from '../utils/mcdata.js';
|
||||||
import { sendRequest } from '../utils/gpt.js';
|
import { sendRequest } from '../utils/gpt.js';
|
||||||
import { History } from './history.js';
|
import { History } from './history.js';
|
||||||
import { Coder } from './coder.js';
|
import { Coder } from './coder.js';
|
||||||
import { getCommand, containsCommand } from './commands.js';
|
import { containsCommand, executeCommand } from './commands.js';
|
||||||
import { Events } from './events.js';
|
import { Events } from './events.js';
|
||||||
|
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ export class Agent {
|
||||||
const user_command_name = containsCommand(message);
|
const user_command_name = containsCommand(message);
|
||||||
if (user_command_name) {
|
if (user_command_name) {
|
||||||
this.bot.chat(`*${source} used ${user_command_name.substring(1)}*`);
|
this.bot.chat(`*${source} used ${user_command_name.substring(1)}*`);
|
||||||
let execute_res = await getCommand(user_command_name).perform(this);
|
let execute_res = await executeCommand(this, message);
|
||||||
if (execute_res)
|
if (execute_res)
|
||||||
this.bot.chat(execute_res);
|
this.bot.chat(execute_res);
|
||||||
else
|
else
|
||||||
|
@ -73,10 +73,10 @@ export class Agent {
|
||||||
if (command_name) { // contains query or command
|
if (command_name) { // contains query or command
|
||||||
console.log('Query/Command response:', res);
|
console.log('Query/Command response:', res);
|
||||||
|
|
||||||
let message = res.substring(0, res.indexOf(command_name)).trim();
|
let pre_message = res.substring(0, res.indexOf(command_name)).trim();
|
||||||
|
|
||||||
this.bot.chat(`${message} *used ${command_name.substring(1)}*`);
|
this.bot.chat(`${pre_message} *used ${command_name.substring(1)}*`);
|
||||||
let execute_res = await getCommand(command_name).perform(this);
|
let execute_res = await executeCommand(this, res);
|
||||||
|
|
||||||
console.log('Agent executed:', command_name, 'and got:', execute_res);
|
console.log('Agent executed:', command_name, 'and got:', execute_res);
|
||||||
|
|
||||||
|
|
|
@ -12,21 +12,84 @@ export function getCommand(name) {
|
||||||
return commandMap[name];
|
return commandMap[name];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const commandRegex = /!(\w+)(?:\(((?:[^)(]+|'[^']*'|"[^"]*")*)\))?/
|
||||||
|
const argRegex = /(?:"[^"]*"|'[^']*'|[^,])+/g;
|
||||||
|
|
||||||
export function containsCommand(message) {
|
export function containsCommand(message) {
|
||||||
for (let command of commandList) {
|
const commandMatch = message.match(commandRegex);
|
||||||
if (message.includes(command.name)) {
|
if (commandMatch) {
|
||||||
return command.name;
|
const commandName = "!"+commandMatch[1];
|
||||||
}
|
if (commandList.some((command) => command.name === commandName))
|
||||||
|
return commandName;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function parseCommandMessage(message) {
|
||||||
|
const commandMatch = message.match(commandRegex);
|
||||||
|
if (commandMatch) {
|
||||||
|
const commandName = "!"+commandMatch[1];
|
||||||
|
if (!commandMatch[2])
|
||||||
|
return { commandName, args: [] };
|
||||||
|
let args = commandMatch[2].match(argRegex);
|
||||||
|
if (args) {
|
||||||
|
for (let i = 0; i < args.length; i++) {
|
||||||
|
args[i] = args[i].trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < args.length; i++) {
|
||||||
|
let arg = args[i];
|
||||||
|
if ((arg.startsWith('"') && arg.endsWith('"')) || (arg.startsWith("'") && arg.endsWith("'"))) {
|
||||||
|
args[i] = arg.substring(1, arg.length-1);
|
||||||
|
} else if (!isNaN(arg)) {
|
||||||
|
args[i] = Number(arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
args = [];
|
||||||
|
|
||||||
|
return { commandName, args };
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function numParams(command) {
|
||||||
|
if (!command.params)
|
||||||
|
return 0;
|
||||||
|
return Object.keys(command.params).length;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function executeCommand(agent, message) {
|
||||||
|
let parsed = parseCommandMessage(message);
|
||||||
|
if (parsed) {
|
||||||
|
const command = getCommand(parsed.commandName);
|
||||||
|
let numArgs = 0;
|
||||||
|
if (parsed.args) {
|
||||||
|
numArgs = parsed.args.length;
|
||||||
|
}
|
||||||
|
console.log('parsed command:', parsed);
|
||||||
|
if (numArgs !== numParams(command))
|
||||||
|
return `Command ${command.name} was given incorrect number of arguments`;
|
||||||
|
else
|
||||||
|
return await command.perform(agent, ...parsed.args);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return `Command is incorrectly formatted`;
|
||||||
|
}
|
||||||
|
|
||||||
export function getCommandDocs() {
|
export function getCommandDocs() {
|
||||||
let docs = `\n*Command DOCS\n You can use the following commands to perform actions and get information about the world.
|
let docs = `\n*COMMAND DOCS\n You can use the following commands to perform actions and get information about the world.
|
||||||
Use the commands with the syntax: !commandName \n
|
Use the commands with the syntax: !commandName or !commandName("arg1", 1.2, ...) if the command takes arguments.\n
|
||||||
Don't use codeblocks. Only use one command in each response, trailing commands will be ignored. Use these commands frequently in your responses!\n`;
|
Do not use codeblocks. Only use one command in each response, trailing commands will be ignored. Use these commands frequently in your responses!\n`;
|
||||||
for (let command of commandList) {
|
for (let command of commandList) {
|
||||||
docs += command.name + ': ' + command.description + '\n';
|
docs += command.name + ': ' + command.description + '\n';
|
||||||
|
if (command.params) {
|
||||||
|
docs += 'Params:\n';
|
||||||
|
for (let param in command.params) {
|
||||||
|
docs += param + ': ' + command.params[param] + '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return docs + '*\n';
|
return docs + '*\n';
|
||||||
}
|
}
|
|
@ -2,10 +2,10 @@ import * as skills from '../skills.js';
|
||||||
import * as world from '../world.js';
|
import * as world from '../world.js';
|
||||||
|
|
||||||
function wrapExecution(func) {
|
function wrapExecution(func) {
|
||||||
return async function (agent) {
|
return async function (agent, ...args) {
|
||||||
agent.bot.output = '';
|
agent.bot.output = '';
|
||||||
agent.coder.executing = true;
|
agent.coder.executing = true;
|
||||||
let res = await func(agent);
|
let res = await func(agent, ...args);
|
||||||
if (res)
|
if (res)
|
||||||
agent.bot.output += '\n' + res;
|
agent.bot.output += '\n' + res;
|
||||||
agent.coder.executing = false;
|
agent.coder.executing = false;
|
||||||
|
@ -16,8 +16,8 @@ function wrapExecution(func) {
|
||||||
// const actionsList = [
|
// const actionsList = [
|
||||||
export const actionsList = [
|
export const actionsList = [
|
||||||
{
|
{
|
||||||
name: '!execute_action',
|
name: '!newAction',
|
||||||
description: 'Write and execute code to perform custom behaviors not available as a command.',
|
description: 'Perform new and unknown custom behaviors that are not available as a command by writing code.',
|
||||||
perform: async function (agent) {
|
perform: async function (agent) {
|
||||||
let res = await agent.coder.generateCode(agent.history);
|
let res = await agent.coder.generateCode(agent.history);
|
||||||
if (res)
|
if (res)
|
||||||
|
@ -32,24 +32,19 @@ export const actionsList = [
|
||||||
return 'Agent stopped.';
|
return 'Agent stopped.';
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: '!goToPlayer',
|
||||||
|
description: 'Go to the nearest player. Ex: !goToPlayer("steve")',
|
||||||
|
params: {'player_name': '(string) The name of the player to go to.'},
|
||||||
|
perform: wrapExecution(async (agent, player_name) => {
|
||||||
|
return await skills.goToPlayer(agent.bot, player_name);
|
||||||
|
})
|
||||||
|
},
|
||||||
// {
|
// {
|
||||||
// name: '!gotoplayer',
|
// name: '!followPlayer',
|
||||||
// description: 'Go to the nearest player.',
|
|
||||||
// perform: wrapExecution(async (agent) => {
|
|
||||||
// let player_name = world.getNearbyPlayerNames(agent.bot);
|
|
||||||
// if (player_name.length == 0)
|
|
||||||
// return 'No players nearby.';
|
|
||||||
// await skills.goToPlayer(agent.bot, player_name[0]);
|
|
||||||
// })
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: '!followplayer',
|
|
||||||
// description: 'Follow the nearest player.',
|
// description: 'Follow the nearest player.',
|
||||||
// perform: wrapExecution(async (agent) => {
|
// perform: wrapExecution(async (agent, player_name) => {
|
||||||
// let player_name = world.getNearbyPlayerNames(agent.bot);
|
// await skills.followPlayer(agent.bot, player_name);
|
||||||
// if (player_name.length == 0)
|
|
||||||
// return 'No players nearby.';
|
|
||||||
// await skills.followPlayer(agent.bot, player_name[0]);
|
|
||||||
// })
|
// })
|
||||||
// },
|
// },
|
||||||
// {
|
// {
|
||||||
|
|
|
@ -96,7 +96,7 @@ export const queryList = [
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "!action",
|
name: "!currentAction",
|
||||||
description: "Get the currently executing code.",
|
description: "Get the currently executing code.",
|
||||||
perform: function (agent) {
|
perform: function (agent) {
|
||||||
return pad("Current code:\n`" + agent.coder.current_code +"`");
|
return pad("Current code:\n`" + agent.coder.current_code +"`");
|
||||||
|
|
|
@ -15,56 +15,56 @@
|
||||||
{"role": "user", "content": "greg: Collect 10 wood"},
|
{"role": "user", "content": "greg: Collect 10 wood"},
|
||||||
{"role": "assistant", "content": "Let me see what's nearby... !blocks"},
|
{"role": "assistant", "content": "Let me see what's nearby... !blocks"},
|
||||||
{"role": "system", "content": "NEARBY_BLOCKS\n- oak_log\n- dirt\n- cobblestone"},
|
{"role": "system", "content": "NEARBY_BLOCKS\n- oak_log\n- dirt\n- cobblestone"},
|
||||||
{"role": "assistant", "content": "I see some oak logs, dirt, and cobblestone. I'll collect oak logs. !execute_action"}
|
{"role": "assistant", "content": "I see some oak logs, dirt, and cobblestone. I'll collect oak logs. !newAction"}
|
||||||
],
|
],
|
||||||
|
|
||||||
[
|
[
|
||||||
{"role": "user", "content": "bobby: Craft a plank"},
|
{"role": "user", "content": "bobby: Craft a plank"},
|
||||||
{"role": "assistant", "content": "Okay! !craftable"},
|
{"role": "assistant", "content": "Okay! !craftable"},
|
||||||
{"role": "system", "content": "CRAFTABLE_ITEMS\n- spruce_planks\n- spruce_wood\n- ladder"},
|
{"role": "system", "content": "CRAFTABLE_ITEMS\n- spruce_planks\n- spruce_wood\n- ladder"},
|
||||||
{"role": "assistant", "content": "!execute_action"}
|
{"role": "assistant", "content": "!newAction"}
|
||||||
],
|
],
|
||||||
|
|
||||||
[
|
[
|
||||||
{"role": "user", "content": "zZZn98: come here"},
|
{"role": "user", "content": "zZZn98: come here"},
|
||||||
{"role": "assistant", "content": "!execute_action"},
|
{"role": "assistant", "content": "!goToPlayer('sumixam0')"},
|
||||||
{"role": "system", "content": "Code execution finished successfully."},
|
{"role": "system", "content": "Code execution finished successfully."},
|
||||||
{"role": "assistant", "content": "Here!"}
|
{"role": "assistant", "content": "Here!"}
|
||||||
],
|
],
|
||||||
|
|
||||||
[
|
[
|
||||||
{"role": "user", "content": "hanky: collect some sand and give it to me please"},
|
{"role": "user", "content": "hanky: collect some sand and give it to me please"},
|
||||||
{"role": "assistant", "content": "Collecting sand... !execute_action"},
|
{"role": "assistant", "content": "Collecting sand... !newAction"},
|
||||||
{"role": "system", "content": "Code Output:\nYou have reached player hanky.\nCode execution finished successfully."},
|
{"role": "system", "content": "Code Output:\nYou have reached player hanky.\nCode execution finished successfully."},
|
||||||
{"role": "assistant", "content": "Here!"}
|
{"role": "assistant", "content": "Here!"}
|
||||||
],
|
],
|
||||||
|
|
||||||
[
|
[
|
||||||
{"role": "user", "content": "joe: Follow me!"},
|
{"role": "user", "content": "joe: Follow me!"},
|
||||||
{"role": "assistant", "content": "Sure! !execute_action"}
|
{"role": "assistant", "content": "Sure! !newAction"}
|
||||||
],
|
],
|
||||||
|
|
||||||
[
|
[
|
||||||
{"role": "user", "content": "hanky: kill that zombie!"},
|
{"role": "user", "content": "hanky: kill that zombie!"},
|
||||||
{"role": "assistant", "content": "I'm attacking! !execute_action"},
|
{"role": "assistant", "content": "I'm attacking! !newAction"},
|
||||||
{"role": "system", "content": "Code Output:\nNo zombie nearby"},
|
{"role": "system", "content": "Code Output:\nNo zombie nearby"},
|
||||||
{"role": "assistant", "content": "I could not find a zombie nearby."}
|
{"role": "assistant", "content": "I could not find a zombie nearby."}
|
||||||
],
|
],
|
||||||
|
|
||||||
[
|
[
|
||||||
{"role": "user", "content": "billybob: stop"},
|
{"role": "user", "content": "billybob: stop"},
|
||||||
{"role": "assistant", "content": "!execute_action"}
|
{"role": "assistant", "content": "!newAction"}
|
||||||
],
|
],
|
||||||
|
|
||||||
[
|
[
|
||||||
{"role": "user", "content": "maya: go to the nearest oak log"},
|
{"role": "user", "content": "maya: go to the nearest oak log"},
|
||||||
{"role": "assistant", "content": "!execute_action`"},
|
{"role": "assistant", "content": "!newAction`"},
|
||||||
{"role": "system", "content": "Code output:\n!!Code threw exception!! Error: ReferenceError: nearestOakLog is not defined\n Write code to fix the problem and try again."},
|
{"role": "system", "content": "Code output:\n!!Code threw exception!! Error: ReferenceError: nearestOakLog is not defined\n Write code to fix the problem and try again."},
|
||||||
{"role": "assistant", "content": "Apologies, I made an error. Would you like me to try again?"}
|
{"role": "assistant", "content": "Apologies, I made an error. Would you like me to try again?"}
|
||||||
],
|
],
|
||||||
|
|
||||||
[
|
[
|
||||||
{"role": "user", "content": "trixy88: craft some sticks"},
|
{"role": "user", "content": "trixy88: craft some sticks"},
|
||||||
{"role": "assistant", "content": "!execute_action"}
|
{"role": "assistant", "content": "!newAction"}
|
||||||
]
|
]
|
||||||
]
|
]
|
Loading…
Add table
Reference in a new issue