mirror of
https://github.com/kolbytn/mindcraft.git
synced 2025-08-10 09:15: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 { History } from './history.js';
|
||||
import { Coder } from './coder.js';
|
||||
import { getCommand, containsCommand } from './commands.js';
|
||||
import { containsCommand, executeCommand } from './commands.js';
|
||||
import { Events } from './events.js';
|
||||
|
||||
|
||||
|
@ -56,7 +56,7 @@ export class Agent {
|
|||
const user_command_name = containsCommand(message);
|
||||
if (user_command_name) {
|
||||
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)
|
||||
this.bot.chat(execute_res);
|
||||
else
|
||||
|
@ -73,10 +73,10 @@ export class Agent {
|
|||
if (command_name) { // contains query or command
|
||||
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)}*`);
|
||||
let execute_res = await getCommand(command_name).perform(this);
|
||||
this.bot.chat(`${pre_message} *used ${command_name.substring(1)}*`);
|
||||
let execute_res = await executeCommand(this, res);
|
||||
|
||||
console.log('Agent executed:', command_name, 'and got:', execute_res);
|
||||
|
||||
|
|
|
@ -12,21 +12,84 @@ export function getCommand(name) {
|
|||
return commandMap[name];
|
||||
}
|
||||
|
||||
const commandRegex = /!(\w+)(?:\(((?:[^)(]+|'[^']*'|"[^"]*")*)\))?/
|
||||
const argRegex = /(?:"[^"]*"|'[^']*'|[^,])+/g;
|
||||
|
||||
export function containsCommand(message) {
|
||||
for (let command of commandList) {
|
||||
if (message.includes(command.name)) {
|
||||
return command.name;
|
||||
}
|
||||
const commandMatch = message.match(commandRegex);
|
||||
if (commandMatch) {
|
||||
const commandName = "!"+commandMatch[1];
|
||||
if (commandList.some((command) => command.name === commandName))
|
||||
return commandName;
|
||||
}
|
||||
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() {
|
||||
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
|
||||
Don't use codeblocks. Only use one command in each response, trailing commands will be ignored. Use these commands frequently in your responses!\n`;
|
||||
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 or !commandName("arg1", 1.2, ...) if the command takes arguments.\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) {
|
||||
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';
|
||||
}
|
|
@ -2,10 +2,10 @@ import * as skills from '../skills.js';
|
|||
import * as world from '../world.js';
|
||||
|
||||
function wrapExecution(func) {
|
||||
return async function (agent) {
|
||||
return async function (agent, ...args) {
|
||||
agent.bot.output = '';
|
||||
agent.coder.executing = true;
|
||||
let res = await func(agent);
|
||||
let res = await func(agent, ...args);
|
||||
if (res)
|
||||
agent.bot.output += '\n' + res;
|
||||
agent.coder.executing = false;
|
||||
|
@ -16,8 +16,8 @@ function wrapExecution(func) {
|
|||
// const actionsList = [
|
||||
export const actionsList = [
|
||||
{
|
||||
name: '!execute_action',
|
||||
description: 'Write and execute code to perform custom behaviors not available as a command.',
|
||||
name: '!newAction',
|
||||
description: 'Perform new and unknown custom behaviors that are not available as a command by writing code.',
|
||||
perform: async function (agent) {
|
||||
let res = await agent.coder.generateCode(agent.history);
|
||||
if (res)
|
||||
|
@ -32,24 +32,19 @@ export const actionsList = [
|
|||
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',
|
||||
// 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',
|
||||
// name: '!followPlayer',
|
||||
// description: 'Follow 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.followPlayer(agent.bot, player_name[0]);
|
||||
// perform: wrapExecution(async (agent, player_name) => {
|
||||
// await skills.followPlayer(agent.bot, player_name);
|
||||
// })
|
||||
// },
|
||||
// {
|
||||
|
|
|
@ -96,7 +96,7 @@ export const queryList = [
|
|||
}
|
||||
},
|
||||
{
|
||||
name: "!action",
|
||||
name: "!currentAction",
|
||||
description: "Get the currently executing code.",
|
||||
perform: function (agent) {
|
||||
return pad("Current code:\n`" + agent.coder.current_code +"`");
|
||||
|
|
|
@ -15,56 +15,56 @@
|
|||
{"role": "user", "content": "greg: Collect 10 wood"},
|
||||
{"role": "assistant", "content": "Let me see what's nearby... !blocks"},
|
||||
{"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": "assistant", "content": "Okay! !craftable"},
|
||||
{"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": "assistant", "content": "!execute_action"},
|
||||
{"role": "assistant", "content": "!goToPlayer('sumixam0')"},
|
||||
{"role": "system", "content": "Code execution finished successfully."},
|
||||
{"role": "assistant", "content": "Here!"}
|
||||
],
|
||||
|
||||
[
|
||||
{"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": "assistant", "content": "Here!"}
|
||||
],
|
||||
|
||||
[
|
||||
{"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": "assistant", "content": "I'm attacking! !execute_action"},
|
||||
{"role": "assistant", "content": "I'm attacking! !newAction"},
|
||||
{"role": "system", "content": "Code Output:\nNo zombie nearby"},
|
||||
{"role": "assistant", "content": "I could not find a zombie nearby."}
|
||||
],
|
||||
|
||||
[
|
||||
{"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": "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": "assistant", "content": "Apologies, I made an error. Would you like me to try again?"}
|
||||
],
|
||||
|
||||
[
|
||||
{"role": "user", "content": "trixy88: craft some sticks"},
|
||||
{"role": "assistant", "content": "!execute_action"}
|
||||
{"role": "assistant", "content": "!newAction"}
|
||||
]
|
||||
]
|
Loading…
Add table
Reference in a new issue