mirror of
https://github.com/kolbytn/mindcraft.git
synced 2025-04-22 06:02:07 +02:00
354 lines
16 KiB
JavaScript
354 lines
16 KiB
JavaScript
import * as skills from '../library/skills.js';
|
|
import settings from '../../../settings.js';
|
|
|
|
function runAsAction (taskLabel, actionFn, resume = false, timeout = -1) {
|
|
return async function (agent, ...args) {
|
|
const actionFnWithAgent = async () => {
|
|
await actionFn(agent, ...args);
|
|
};
|
|
const code_return = await agent.actions.runAction(`action:${taskLabel}`, actionFnWithAgent, { timeout, resume });
|
|
if (code_return.interrupted && !code_return.timedout)
|
|
return;
|
|
return code_return.message;
|
|
}
|
|
}
|
|
|
|
export const actionsList = [
|
|
{
|
|
name: '!newAction',
|
|
description: 'Perform new and unknown custom behaviors that are not available as a command.',
|
|
params: {
|
|
'prompt': { type: 'string', description: 'A natural language prompt to guide code generation. Make a detailed step-by-step plan.' }
|
|
},
|
|
perform: async function (agent, prompt) {
|
|
// just ignore prompt - it is now in context in chat history
|
|
if (!settings.allow_insecure_coding)
|
|
return 'newAction not allowed! Code writing is disabled in settings. Notify the user.';
|
|
return await agent.coder.generateCode(agent.history);
|
|
}
|
|
},
|
|
{
|
|
name: '!stop',
|
|
description: 'Force stop all actions and commands that are currently executing.',
|
|
perform: async function (agent) {
|
|
await agent.actions.stop();
|
|
agent.clearBotLogs();
|
|
agent.actions.cancelResume();
|
|
agent.bot.emit('idle');
|
|
let msg = 'Agent stopped.';
|
|
if (agent.self_prompter.on)
|
|
msg += ' Self-prompting still active.';
|
|
return msg;
|
|
}
|
|
},
|
|
{
|
|
name: '!stfu',
|
|
description: 'Stop all chatting and self prompting, but continue current action.',
|
|
perform: async function (agent) {
|
|
agent.bot.chat('Shutting up.');
|
|
agent.shutUp();
|
|
return;
|
|
}
|
|
},
|
|
{
|
|
name: '!restart',
|
|
description: 'Restart the agent process.',
|
|
perform: async function (agent) {
|
|
await agent.history.save();
|
|
agent.cleanKill();
|
|
}
|
|
},
|
|
{
|
|
name: '!clearChat',
|
|
description: 'Clear the chat history.',
|
|
perform: async function (agent) {
|
|
agent.history.clear();
|
|
return agent.name + "'s chat history was cleared, starting new conversation from scratch.";
|
|
}
|
|
},
|
|
{
|
|
name: '!goToPlayer',
|
|
description: 'Go to the given player.',
|
|
params: {
|
|
'player_name': {type: 'string', description: 'The name of the player to go to.'},
|
|
'closeness': {type: 'float', description: 'How close to get to the player.', domain: [0, Infinity]}
|
|
},
|
|
perform: runAsAction('goToPlayer', async (agent, player_name, closeness) => {
|
|
return await skills.goToPlayer(agent.bot, player_name, closeness);
|
|
})
|
|
},
|
|
{
|
|
name: '!followPlayer',
|
|
description: 'Endlessly follow the given player. Will defend that player if self_defense mode is on.',
|
|
params: {
|
|
'player_name': {type: 'string', description: 'name of the player to follow.'},
|
|
'follow_dist': {type: 'float', description: 'The distance to follow from.', domain: [0, Infinity]}
|
|
},
|
|
perform: runAsAction('followPlayer', async (agent, player_name, follow_dist) => {
|
|
await skills.followPlayer(agent.bot, player_name, follow_dist);
|
|
}, true)
|
|
},
|
|
{
|
|
name: '!goToBlock',
|
|
description: 'Go to the nearest block of a given type.',
|
|
params: {
|
|
'type': { type: 'BlockName', description: 'The block type to go to.' },
|
|
'closeness': { type: 'float', description: 'How close to get to the block.', domain: [0, Infinity] },
|
|
'search_range': { type: 'float', description: 'The distance to search for the block.', domain: [0, Infinity] }
|
|
},
|
|
perform: runAsAction('goToBlock', async (agent, type, closeness, range) => {
|
|
await skills.goToNearestBlock(agent.bot, type, closeness, range);
|
|
})
|
|
},
|
|
{
|
|
name: '!moveAway',
|
|
description: 'Move away from the current location in any direction by a given distance.',
|
|
params: {'distance': { type: 'float', description: 'The distance to move away.', domain: [0, Infinity] }},
|
|
perform: runAsAction('moveAway', async (agent, distance) => {
|
|
await skills.moveAway(agent.bot, distance);
|
|
})
|
|
},
|
|
{
|
|
name: '!rememberHere',
|
|
description: 'Save the current location with a given name.',
|
|
params: {'name': { type: 'string', description: 'The name to remember the location as.' }},
|
|
perform: async function (agent, name) {
|
|
const pos = agent.bot.entity.position;
|
|
agent.memory_bank.rememberPlace(name, pos.x, pos.y, pos.z);
|
|
return `Location saved as "${name}".`;
|
|
}
|
|
},
|
|
{
|
|
name: '!goToPlace',
|
|
description: 'Go to a saved location.',
|
|
params: {'name': { type: 'string', description: 'The name of the location to go to.' }},
|
|
perform: runAsAction('goToPlace', async (agent, name) => {
|
|
const pos = agent.memory_bank.recallPlace(name);
|
|
if (!pos) {
|
|
skills.log(agent.bot, `No location named "${name}" saved.`);
|
|
return;
|
|
}
|
|
await skills.goToPosition(agent.bot, pos[0], pos[1], pos[2], 1);
|
|
})
|
|
},
|
|
{
|
|
name: '!givePlayer',
|
|
description: 'Give the specified item to the given player.',
|
|
params: {
|
|
'player_name': { type: 'string', description: 'The name of the player to give the item to.' },
|
|
'item_name': { type: 'ItemName', description: 'The name of the item to give.' },
|
|
'num': { type: 'int', description: 'The number of items to give.', domain: [1, Number.MAX_SAFE_INTEGER] }
|
|
},
|
|
perform: runAsAction('givePlayer', async (agent, player_name, item_name, num) => {
|
|
await skills.giveToPlayer(agent.bot, item_name, player_name, num);
|
|
})
|
|
},
|
|
{
|
|
name: '!consume',
|
|
description: 'Eat/drink the given item.',
|
|
params: {'item_name': { type: 'ItemName', description: 'The name of the item to consume.' }},
|
|
perform: runAsAction('consume', async (agent, item_name) => {
|
|
await agent.bot.consume(item_name);
|
|
skills.log(agent.bot, `Consumed ${item_name}.`);
|
|
})
|
|
},
|
|
{
|
|
name: '!equip',
|
|
description: 'Equip the given item.',
|
|
params: {'item_name': { type: 'ItemName', description: 'The name of the item to equip.' }},
|
|
perform: runAsAction('equip', async (agent, item_name) => {
|
|
await skills.equip(agent.bot, item_name);
|
|
})
|
|
},
|
|
{
|
|
name: '!putInChest',
|
|
description: 'Put the given item in the nearest chest.',
|
|
params: {
|
|
'item_name': { type: 'ItemName', description: 'The name of the item to put in the chest.' },
|
|
'num': { type: 'int', description: 'The number of items to put in the chest.', domain: [1, Number.MAX_SAFE_INTEGER] }
|
|
},
|
|
perform: runAsAction('putInChest', async (agent, item_name, num) => {
|
|
await skills.putInChest(agent.bot, item_name, num);
|
|
})
|
|
},
|
|
{
|
|
name: '!takeFromChest',
|
|
description: 'Take the given items from the nearest chest.',
|
|
params: {
|
|
'item_name': { type: 'ItemName', description: 'The name of the item to take.' },
|
|
'num': { type: 'int', description: 'The number of items to take.', domain: [1, Number.MAX_SAFE_INTEGER] }
|
|
},
|
|
perform: runAsAction('takeFromChest', async (agent, item_name, num) => {
|
|
await skills.takeFromChest(agent.bot, item_name, num);
|
|
})
|
|
},
|
|
{
|
|
name: '!viewChest',
|
|
description: 'View the items/counts of the nearest chest.',
|
|
params: { },
|
|
perform: runAsAction('viewChest', async (agent) => {
|
|
await skills.viewChest(agent.bot);
|
|
})
|
|
},
|
|
{
|
|
name: '!discard',
|
|
description: 'Discard the given item from the inventory.',
|
|
params: {
|
|
'item_name': { type: 'ItemName', description: 'The name of the item to discard.' },
|
|
'num': { type: 'int', description: 'The number of items to discard.', domain: [1, Number.MAX_SAFE_INTEGER] }
|
|
},
|
|
perform: runAsAction('discard', async (agent, item_name, num) => {
|
|
const start_loc = agent.bot.entity.position;
|
|
await skills.moveAway(agent.bot, 5);
|
|
await skills.discard(agent.bot, item_name, num);
|
|
await skills.goToPosition(agent.bot, start_loc.x, start_loc.y, start_loc.z, 0);
|
|
})
|
|
},
|
|
{
|
|
name: '!collectBlocks',
|
|
description: 'Collect the nearest blocks of a given type.',
|
|
params: {
|
|
'type': { type: 'BlockName', description: 'The block type to collect.' },
|
|
'num': { type: 'int', description: 'The number of blocks to collect.', domain: [1, Number.MAX_SAFE_INTEGER] }
|
|
},
|
|
perform: runAsAction('collectBlocks', async (agent, type, num) => {
|
|
await skills.collectBlock(agent.bot, type, num);
|
|
}, false, 10) // 10 minute timeout
|
|
},
|
|
{
|
|
name: '!collectAllBlocks',
|
|
description: 'Collect all the nearest blocks of a given type until told to stop.',
|
|
params: {
|
|
'type': { type: 'BlockName', description: 'The block type to collect.' }
|
|
},
|
|
perform: runAsAction('collectAllBlocks', async (agent, type) => {
|
|
let success = await skills.collectBlock(agent.bot, type, 1);
|
|
if (!success)
|
|
agent.tasks.cancelResume();
|
|
}, true, 3) // 3 minute timeout
|
|
},
|
|
{
|
|
name: '!craftRecipe',
|
|
description: 'Craft the given recipe a given number of times.',
|
|
params: {
|
|
'recipe_name': { type: 'ItemName', description: 'The name of the output item to craft.' },
|
|
'num': { type: 'int', description: 'The number of times to craft the recipe. This is NOT the number of output items, as it may craft many more items depending on the recipe.', domain: [1, Number.MAX_SAFE_INTEGER] }
|
|
},
|
|
perform: runAsAction('craftRecipe', async (agent, recipe_name, num) => {
|
|
await skills.craftRecipe(agent.bot, recipe_name, num);
|
|
})
|
|
},
|
|
{
|
|
name: '!smeltItem',
|
|
description: 'Smelt the given item the given number of times.',
|
|
params: {
|
|
'item_name': { type: 'ItemName', description: 'The name of the input item to smelt.' },
|
|
'num': { type: 'int', description: 'The number of times to smelt the item.', domain: [1, Number.MAX_SAFE_INTEGER] }
|
|
},
|
|
perform: runAsAction('smeltItem', async (agent, item_name, num) => {
|
|
let response = await skills.smeltItem(agent.bot, item_name, num);
|
|
if (response.indexOf('Successfully') !== -1) {
|
|
// there is a bug where the bot's inventory is not updated after smelting
|
|
// only updates after a restart
|
|
agent.cleanKill(response + ' Safely restarting to update inventory.');
|
|
}
|
|
return response;
|
|
})
|
|
},
|
|
{
|
|
name: '!clearFurnace',
|
|
description: 'Take all items out of the nearest furnace.',
|
|
params: { },
|
|
perform: runAsAction('clearFurnace', async (agent) => {
|
|
await skills.clearNearestFurnace(agent.bot);
|
|
})
|
|
},
|
|
{
|
|
name: '!placeHere',
|
|
description: 'Place a given block in the current location. Do NOT use to build structures, only use for single blocks/torches.',
|
|
params: {'type': { type: 'BlockName', description: 'The block type to place.' }},
|
|
perform: runAsAction('placeHere', async (agent, type) => {
|
|
let pos = agent.bot.entity.position;
|
|
await skills.placeBlock(agent.bot, type, pos.x, pos.y, pos.z);
|
|
})
|
|
},
|
|
{
|
|
name: '!attack',
|
|
description: 'Attack and kill the nearest entity of a given type.',
|
|
params: {'type': { type: 'string', description: 'The type of entity to attack.'}},
|
|
perform: runAsAction('attack', async (agent, type) => {
|
|
await skills.attackNearest(agent.bot, type, true);
|
|
})
|
|
},
|
|
{
|
|
name: '!goToBed',
|
|
description: 'Go to the nearest bed and sleep.',
|
|
perform: runAsAction('goToBed', async (agent) => {
|
|
await skills.goToBed(agent.bot);
|
|
})
|
|
},
|
|
{
|
|
name: '!activate',
|
|
description: 'Activate the nearest object of a given type.',
|
|
params: {'type': { type: 'BlockName', description: 'The type of object to activate.' }},
|
|
perform: runAsAction('activate', async (agent, type) => {
|
|
await skills.activateNearestBlock(agent.bot, type);
|
|
})
|
|
},
|
|
{
|
|
name: '!stay',
|
|
description: 'Stay in the current location no matter what. Pauses all modes.',
|
|
params: {'type': { type: 'int', description: 'The number of seconds to stay. -1 for forever.', domain: [-1, Number.MAX_SAFE_INTEGER] }},
|
|
perform: runAsAction('stay', async (agent, seconds) => {
|
|
await skills.stay(agent.bot, seconds);
|
|
})
|
|
},
|
|
{
|
|
name: '!setMode',
|
|
description: 'Set a mode to on or off. A mode is an automatic behavior that constantly checks and responds to the environment.',
|
|
params: {
|
|
'mode_name': { type: 'string', description: 'The name of the mode to enable.' },
|
|
'on': { type: 'boolean', description: 'Whether to enable or disable the mode.' }
|
|
},
|
|
perform: async function (agent, mode_name, on) {
|
|
const modes = agent.bot.modes;
|
|
if (!modes.exists(mode_name))
|
|
return `Mode ${mode_name} does not exist.` + modes.getDocs();
|
|
if (modes.isOn(mode_name) === on)
|
|
return `Mode ${mode_name} is already ${on ? 'on' : 'off'}.`;
|
|
modes.setOn(mode_name, on);
|
|
return `Mode ${mode_name} is now ${on ? 'on' : 'off'}.`;
|
|
}
|
|
},
|
|
{
|
|
name: '!goal',
|
|
description: 'Set a goal prompt to endlessly work towards with continuous self-prompting.',
|
|
params: {
|
|
'selfPrompt': { type: 'string', description: 'The goal prompt.' },
|
|
},
|
|
perform: async function (agent, prompt) {
|
|
agent.self_prompter.start(prompt); // don't await, don't return
|
|
}
|
|
},
|
|
{
|
|
name: '!endGoal',
|
|
description: 'Call when you have accomplished your goal. It will stop self-prompting and the current action. ',
|
|
perform: async function (agent) {
|
|
agent.self_prompter.stop();
|
|
return 'Self-prompting stopped.';
|
|
}
|
|
},
|
|
// { // commented for now, causes confusion with goal command
|
|
// name: '!npcGoal',
|
|
// description: 'Set a simple goal for an item or building to automatically work towards. Do not use for complex goals.',
|
|
// params: {
|
|
// 'name': { type: 'string', description: 'The name of the goal to set. Can be item or building name. If empty will automatically choose a goal.' },
|
|
// 'quantity': { type: 'int', description: 'The quantity of the goal to set. Default is 1.', domain: [1, Number.MAX_SAFE_INTEGER] }
|
|
// },
|
|
// perform: async function (agent, name=null, quantity=1) {
|
|
// await agent.npc.setGoal(name, quantity);
|
|
// agent.bot.emit('idle'); // to trigger the goal
|
|
// return 'Set npc goal: ' + agent.npc.data.curr_goal.name;
|
|
// }
|
|
// },
|
|
];
|