2024-01-25 13:25:36 -08:00
import * as skills from '../library/skills.js' ;
2024-05-29 21:49:45 -05:00
import settings from '../../../settings.js' ;
2024-01-09 22:50:22 -06:00
2024-11-03 12:03:56 -05:00
function runAsAction ( actionLabel , actionFn , resume = false , timeout = - 1 ) {
2024-01-11 15:59:52 -06:00
return async function ( agent , ... args ) {
2024-11-03 12:03:12 -05:00
const actionFnWithAgent = async ( ) => {
await actionFn ( agent , ... args ) ;
2024-09-26 22:28:46 -05:00
} ;
2024-11-03 12:03:56 -05:00
const code _return = await agent . actions . runAction ( ` action: ${ actionLabel } ` , actionFnWithAgent , { timeout , resume } ) ;
2024-01-15 12:04:18 -06:00
if ( code _return . interrupted && ! code _return . timedout )
return ;
return code _return . message ;
2024-01-09 22:50:22 -06:00
}
}
export const actionsList = [
{
2024-01-11 15:59:52 -06:00
name : '!newAction' ,
2024-10-06 13:28:49 -05:00
description : 'Perform new and unknown custom behaviors that are not available as a command.' ,
params : {
2024-10-16 00:02:59 -05:00
'prompt' : { type : 'string' , description : 'A natural language prompt to guide code generation. Make a detailed step-by-step plan.' }
2024-10-06 13:28:49 -05:00
} ,
perform : async function ( agent , prompt ) {
// just ignore prompt - it is now in context in chat history
2024-01-30 16:43:30 -06:00
if ( ! settings . allow _insecure _coding )
2024-10-06 13:28:49 -05:00
return 'newAction not allowed! Code writing is disabled in settings. Notify the user.' ;
2024-02-16 11:57:48 -06:00
return await agent . coder . generateCode ( agent . history ) ;
2024-01-09 22:50:22 -06:00
}
} ,
{
name : '!stop' ,
description : 'Force stop all actions and commands that are currently executing.' ,
perform : async function ( agent ) {
2024-11-03 12:03:12 -05:00
await agent . actions . stop ( ) ;
2024-10-25 15:28:27 -10:00
agent . clearBotLogs ( ) ;
2024-11-03 12:03:12 -05:00
agent . actions . cancelResume ( ) ;
2024-04-23 20:47:01 -07:00
agent . bot . emit ( 'idle' ) ;
2024-05-04 15:42:30 -05:00
let msg = 'Agent stopped.' ;
if ( agent . self _prompter . on )
msg += ' Self-prompting still active.' ;
return msg ;
2024-01-09 22:50:22 -06:00
}
} ,
2024-08-22 15:57:20 -05:00
{
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 ;
}
} ,
2024-01-27 19:16:54 -06:00
{
name : '!restart' ,
description : 'Restart the agent process.' ,
perform : async function ( agent ) {
2024-04-20 22:18:26 -05:00
await agent . history . save ( ) ;
2024-05-08 23:59:44 -05:00
agent . cleanKill ( ) ;
2024-01-27 19:16:54 -06:00
}
} ,
{
2024-02-16 11:57:48 -06:00
name : '!clearChat' ,
2024-01-27 19:16:54 -06:00
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." ;
}
} ,
2024-01-11 15:59:52 -06:00
{
name : '!goToPlayer' ,
2024-02-25 14:13:32 -06:00
description : 'Go to the given player.' ,
2024-02-05 19:08:08 -06:00
params : {
2024-09-25 12:00:15 +10:00
'player_name' : { type : 'string' , description : 'The name of the player to go to.' } ,
2024-10-14 07:32:39 +10:00
'closeness' : { type : 'float' , description : 'How close to get to the player.' , domain : [ 0 , Infinity ] }
2024-02-05 19:08:08 -06:00
} ,
2024-11-03 12:03:12 -05:00
perform : runAsAction ( 'goToPlayer' , async ( agent , player _name , closeness ) => {
2024-02-05 19:08:08 -06:00
return await skills . goToPlayer ( agent . bot , player _name , closeness ) ;
2024-01-11 15:59:52 -06:00
} )
} ,
2024-01-11 18:04:59 -06:00
{
name : '!followPlayer' ,
2024-02-25 14:13:32 -06:00
description : 'Endlessly follow the given player. Will defend that player if self_defense mode is on.' ,
2024-02-05 19:08:08 -06:00
params : {
2024-09-25 12:00:15 +10:00
'player_name' : { type : 'string' , description : 'name of the player to follow.' } ,
2024-10-14 07:32:39 +10:00
'follow_dist' : { type : 'float' , description : 'The distance to follow from.' , domain : [ 0 , Infinity ] }
2024-02-05 19:08:08 -06:00
} ,
2024-11-03 12:03:12 -05:00
perform : runAsAction ( 'followPlayer' , async ( agent , player _name , follow _dist ) => {
2024-02-05 19:08:08 -06:00
await skills . followPlayer ( agent . bot , player _name , follow _dist ) ;
2024-09-26 22:28:46 -05:00
} , true )
2024-01-11 18:04:59 -06:00
} ,
2024-08-22 15:57:20 -05:00
{
name : '!goToBlock' ,
description : 'Go to the nearest block of a given type.' ,
params : {
2024-10-14 07:32:39 +10:00
'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 ] }
2024-08-22 15:57:20 -05:00
} ,
2024-11-03 12:03:12 -05:00
perform : runAsAction ( 'goToBlock' , async ( agent , type , closeness , range ) => {
2024-08-22 15:57:20 -05:00
await skills . goToNearestBlock ( agent . bot , type , closeness , range ) ;
} )
} ,
2024-02-02 11:54:17 -06:00
{
name : '!moveAway' ,
2024-02-25 14:13:32 -06:00
description : 'Move away from the current location in any direction by a given distance.' ,
2024-10-14 07:32:39 +10:00
params : { 'distance' : { type : 'float' , description : 'The distance to move away.' , domain : [ 0 , Infinity ] } } ,
2024-11-03 12:03:12 -05:00
perform : runAsAction ( 'moveAway' , async ( agent , distance ) => {
2024-02-02 11:54:17 -06:00
await skills . moveAway ( agent . bot , distance ) ;
} )
} ,
2024-04-27 23:28:34 -05:00
{
name : '!rememberHere' ,
description : 'Save the current location with a given name.' ,
2024-09-25 12:00:15 +10:00
params : { 'name' : { type : 'string' , description : 'The name to remember the location as.' } } ,
2024-04-27 23:28:34 -05:00
perform : async function ( agent , name ) {
const pos = agent . bot . entity . position ;
agent . memory _bank . rememberPlace ( name , pos . x , pos . y , pos . z ) ;
2024-08-22 15:57:20 -05:00
return ` Location saved as " ${ name } ". ` ;
2024-04-27 23:28:34 -05:00
}
} ,
{
name : '!goToPlace' ,
description : 'Go to a saved location.' ,
2024-09-25 12:00:15 +10:00
params : { 'name' : { type : 'string' , description : 'The name of the location to go to.' } } ,
2024-11-03 12:03:12 -05:00
perform : runAsAction ( 'goToPlace' , async ( agent , name ) => {
2024-04-27 23:28:34 -05:00
const pos = agent . memory _bank . recallPlace ( name ) ;
if ( ! pos ) {
2024-10-25 15:28:27 -10:00
skills . log ( agent . bot , ` No location named " ${ name } " saved. ` ) ;
return ;
2024-04-27 23:28:34 -05:00
}
await skills . goToPosition ( agent . bot , pos [ 0 ] , pos [ 1 ] , pos [ 2 ] , 1 ) ;
} )
} ,
2024-01-25 13:25:36 -08:00
{
name : '!givePlayer' ,
2024-02-25 14:13:32 -06:00
description : 'Give the specified item to the given player.' ,
2024-01-26 15:05:36 -06:00
params : {
2024-09-25 12:00:15 +10:00
'player_name' : { type : 'string' , description : 'The name of the player to give the item to.' } ,
2024-10-14 07:32:39 +10:00
'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 ] }
2024-01-26 15:05:36 -06:00
} ,
2024-11-03 12:03:12 -05:00
perform : runAsAction ( 'givePlayer' , async ( agent , player _name , item _name , num ) => {
2024-01-26 15:05:36 -06:00
await skills . giveToPlayer ( agent . bot , item _name , player _name , num ) ;
2024-01-25 13:25:36 -08:00
} )
} ,
2024-10-16 18:56:21 -05:00
{
name : '!consume' ,
description : 'Eat/drink the given item.' ,
params : { 'item_name' : { type : 'ItemName' , description : 'The name of the item to consume.' } } ,
2024-11-03 12:03:12 -05:00
perform : runAsAction ( 'consume' , async ( agent , item _name ) => {
2024-10-16 18:56:21 -05:00
await agent . bot . consume ( item _name ) ;
skills . log ( agent . bot , ` Consumed ${ item _name } . ` ) ;
} )
} ,
2024-09-26 22:28:46 -05:00
{
name : '!equip' ,
description : 'Equip the given item.' ,
2024-10-14 07:32:39 +10:00
params : { 'item_name' : { type : 'ItemName' , description : 'The name of the item to equip.' } } ,
2024-11-03 12:03:12 -05:00
perform : runAsAction ( 'equip' , async ( agent , item _name ) => {
2024-09-26 22:28:46 -05:00
await skills . equip ( agent . bot , item _name ) ;
} )
} ,
2024-09-27 17:03:00 -05:00
{
name : '!putInChest' ,
description : 'Put the given item in the nearest chest.' ,
params : {
2024-10-14 07:32:39 +10:00
'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 ] }
2024-09-27 17:03:00 -05:00
} ,
2024-11-03 12:03:12 -05:00
perform : runAsAction ( 'putInChest' , async ( agent , item _name , num ) => {
2024-09-27 17:03:00 -05:00
await skills . putInChest ( agent . bot , item _name , num ) ;
} )
} ,
{
name : '!takeFromChest' ,
description : 'Take the given items from the nearest chest.' ,
params : {
2024-10-14 07:32:39 +10:00
'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 ] }
2024-09-27 17:03:00 -05:00
} ,
2024-11-03 12:03:12 -05:00
perform : runAsAction ( 'takeFromChest' , async ( agent , item _name , num ) => {
2024-09-27 17:03:00 -05:00
await skills . takeFromChest ( agent . bot , item _name , num ) ;
} )
} ,
{
name : '!viewChest' ,
description : 'View the items/counts of the nearest chest.' ,
params : { } ,
2024-11-03 12:03:12 -05:00
perform : runAsAction ( 'viewChest' , async ( agent ) => {
2024-09-27 17:03:00 -05:00
await skills . viewChest ( agent . bot ) ;
} )
} ,
2024-09-26 22:28:46 -05:00
{
name : '!discard' ,
description : 'Discard the given item from the inventory.' ,
params : {
2024-10-14 07:32:39 +10:00
'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 ] }
2024-09-26 22:28:46 -05:00
} ,
2024-11-03 12:03:12 -05:00
perform : runAsAction ( 'discard' , async ( agent , item _name , num ) => {
2024-09-26 22:28:46 -05:00
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 ) ;
} )
} ,
2024-01-11 18:04:59 -06:00
{
name : '!collectBlocks' ,
description : 'Collect the nearest blocks of a given type.' ,
params : {
2024-10-14 07:32:39 +10:00
'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 ] }
2024-01-11 18:04:59 -06:00
} ,
2024-11-03 12:03:12 -05:00
perform : runAsAction ( 'collectBlocks' , async ( agent , type , num ) => {
2024-01-11 18:04:59 -06:00
await skills . collectBlock ( agent . bot , type , num ) ;
2024-09-26 22:28:46 -05:00
} , false , 10 ) // 10 minute timeout
2024-01-11 18:04:59 -06:00
} ,
2024-01-26 12:11:32 -08:00
{
name : '!collectAllBlocks' ,
description : 'Collect all the nearest blocks of a given type until told to stop.' ,
params : {
2024-10-14 07:32:39 +10:00
'type' : { type : 'BlockName' , description : 'The block type to collect.' }
2024-01-26 12:11:32 -08:00
} ,
2024-11-03 12:03:12 -05:00
perform : runAsAction ( 'collectAllBlocks' , async ( agent , type ) => {
2024-02-05 13:21:32 -06:00
let success = await skills . collectBlock ( agent . bot , type , 1 ) ;
if ( ! success )
2024-11-03 12:03:56 -05:00
agent . actions . cancelResume ( ) ;
2024-09-26 22:28:46 -05:00
} , true , 3 ) // 3 minute timeout
2024-01-26 12:11:32 -08:00
} ,
2024-01-16 15:53:27 -06:00
{
name : '!craftRecipe' ,
2024-02-25 14:13:32 -06:00
description : 'Craft the given recipe a given number of times.' ,
2024-01-16 15:53:27 -06:00
params : {
2024-10-14 07:32:39 +10:00
'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 ] }
2024-01-16 15:53:27 -06:00
} ,
2024-11-03 12:03:12 -05:00
perform : runAsAction ( 'craftRecipe' , async ( agent , recipe _name , num ) => {
2024-03-05 12:50:13 -08:00
await skills . craftRecipe ( agent . bot , recipe _name , num ) ;
} )
} ,
{
name : '!smeltItem' ,
description : 'Smelt the given item the given number of times.' ,
params : {
2024-10-16 17:38:59 +10:00
'item_name' : { type : 'ItemName' , description : 'The name of the input item to smelt.' } ,
2024-10-14 07:32:39 +10:00
'num' : { type : 'int' , description : 'The number of times to smelt the item.' , domain : [ 1 , Number . MAX _SAFE _INTEGER ] }
2024-03-05 12:50:13 -08:00
} ,
2024-11-03 12:03:12 -05:00
perform : runAsAction ( 'smeltItem' , async ( agent , item _name , num ) => {
2024-10-25 15:28:27 -10:00
let response = await skills . smeltItem ( agent . bot , item _name , num ) ;
2024-08-22 15:57:20 -05:00
if ( response . indexOf ( 'Successfully' ) !== - 1 ) {
2024-10-25 15:28:27 -10:00
// 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.' ) ;
2024-08-22 15:57:20 -05:00
}
return response ;
2024-10-25 15:28:27 -10:00
} )
2024-01-16 15:53:27 -06:00
} ,
2024-10-10 20:04:02 -05:00
{
name : '!clearFurnace' ,
2024-10-25 15:28:27 -10:00
description : 'Take all items out of the nearest furnace.' ,
2024-10-10 20:04:02 -05:00
params : { } ,
2024-11-03 12:03:12 -05:00
perform : runAsAction ( 'clearFurnace' , async ( agent ) => {
2024-10-10 20:04:02 -05:00
await skills . clearNearestFurnace ( agent . bot ) ;
} )
2024-10-25 15:28:27 -10:00
} ,
{
2024-01-16 15:53:27 -06:00
name : '!placeHere' ,
2024-02-25 14:13:32 -06:00
description : 'Place a given block in the current location. Do NOT use to build structures, only use for single blocks/torches.' ,
2024-10-16 17:38:59 +10:00
params : { 'type' : { type : 'BlockName' , description : 'The block type to place.' } } ,
2024-11-03 12:03:12 -05:00
perform : runAsAction ( 'placeHere' , async ( agent , type ) => {
2024-01-16 15:53:27 -06:00
let pos = agent . bot . entity . position ;
await skills . placeBlock ( agent . bot , type , pos . x , pos . y , pos . z ) ;
} )
} ,
2024-01-11 18:04:59 -06:00
{
name : '!attack' ,
description : 'Attack and kill the nearest entity of a given type.' ,
2024-10-16 17:32:28 +10:00
params : { 'type' : { type : 'string' , description : 'The type of entity to attack.' } } ,
2024-11-03 12:03:12 -05:00
perform : runAsAction ( 'attack' , async ( agent , type ) => {
2024-01-24 17:24:52 -06:00
await skills . attackNearest ( agent . bot , type , true ) ;
2024-01-11 18:04:59 -06:00
} )
2024-01-13 12:11:04 -06:00
} ,
2024-01-16 15:53:27 -06:00
{
name : '!goToBed' ,
description : 'Go to the nearest bed and sleep.' ,
2024-11-03 12:03:12 -05:00
perform : runAsAction ( 'goToBed' , async ( agent ) => {
2024-01-16 15:53:27 -06:00
await skills . goToBed ( agent . bot ) ;
} )
2024-02-02 11:54:17 -06:00
} ,
2024-04-19 14:02:30 -05:00
{
name : '!activate' ,
description : 'Activate the nearest object of a given type.' ,
2024-10-14 07:32:39 +10:00
params : { 'type' : { type : 'BlockName' , description : 'The type of object to activate.' } } ,
2024-11-03 12:03:12 -05:00
perform : runAsAction ( 'activate' , async ( agent , type ) => {
2024-04-19 14:02:30 -05:00
await skills . activateNearestBlock ( agent . bot , type ) ;
} )
} ,
2024-02-02 11:54:17 -06:00
{
name : '!stay' ,
description : 'Stay in the current location no matter what. Pauses all modes.' ,
2024-10-25 23:46:29 -05:00
params : { 'type' : { type : 'int' , description : 'The number of seconds to stay. -1 for forever.' , domain : [ - 1 , Number . MAX _SAFE _INTEGER ] } } ,
2024-11-03 12:03:12 -05:00
perform : runAsAction ( 'stay' , async ( agent , seconds ) => {
2024-10-25 23:46:29 -05:00
await skills . stay ( agent . bot , seconds ) ;
2024-02-02 11:54:17 -06:00
} )
2024-04-23 20:47:01 -07:00
} ,
{
2024-08-22 15:57:20 -05:00
name : '!setMode' ,
description : 'Set a mode to on or off. A mode is an automatic behavior that constantly checks and responds to the environment.' ,
2024-04-23 20:47:01 -07:00
params : {
2024-09-25 12:00:15 +10:00
'mode_name' : { type : 'string' , description : 'The name of the mode to enable.' } ,
'on' : { type : 'boolean' , description : 'Whether to enable or disable the mode.' }
2024-04-23 20:47:01 -07:00
} ,
2024-08-22 15:57:20 -05:00
perform : async function ( agent , mode _name , on ) {
const modes = agent . bot . modes ;
if ( ! modes . exists ( mode _name ) )
2024-10-25 15:28:27 -10:00
return ` Mode ${ mode _name } does not exist. ` + modes . getDocs ( ) ;
2024-08-22 15:57:20 -05:00
if ( modes . isOn ( mode _name ) === on )
2024-10-25 15:28:27 -10:00
return ` Mode ${ mode _name } is already ${ on ? 'on' : 'off' } . ` ;
2024-08-22 15:57:20 -05:00
modes . setOn ( mode _name , on ) ;
return ` Mode ${ mode _name } is now ${ on ? 'on' : 'off' } . ` ;
2024-04-23 20:47:01 -07:00
}
2024-04-30 23:07:07 -05:00
} ,
{
2024-08-22 15:57:20 -05:00
name : '!goal' ,
description : 'Set a goal prompt to endlessly work towards with continuous self-prompting.' ,
2024-04-30 23:07:07 -05:00
params : {
2024-09-25 12:00:15 +10:00
'selfPrompt' : { type : 'string' , description : 'The goal prompt.' } ,
2024-04-30 23:07:07 -05:00
} ,
perform : async function ( agent , prompt ) {
2024-05-04 15:42:30 -05:00
agent . self _prompter . start ( prompt ) ; // don't await, don't return
2024-04-30 23:07:07 -05:00
}
} ,
2024-05-04 15:42:30 -05:00
{
2024-08-22 15:57:20 -05:00
name : '!endGoal' ,
description : 'Call when you have accomplished your goal. It will stop self-prompting and the current action. ' ,
2024-05-04 15:42:30 -05:00
perform : async function ( agent ) {
2024-05-10 12:18:47 -05:00
agent . self _prompter . stop ( ) ;
2024-05-04 15:42:30 -05:00
return 'Self-prompting stopped.' ;
}
2024-08-22 15:57:20 -05:00
} ,
2024-10-18 10:46:35 -05:00
// { // 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;
// }
// },
2024-01-09 22:50:22 -06:00
] ;