mindcraft 0.1.4-0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/FAQ.md +38 -0
- package/LICENSE +21 -0
- package/README.md +255 -0
- package/andy.json +6 -0
- package/bin/mindcraft.js +80 -0
- package/keys.example.json +19 -0
- package/main.js +80 -0
- package/package.json +78 -0
- package/patches/minecraft-data+3.97.0.patch +13 -0
- package/patches/mineflayer+4.33.0.patch +54 -0
- package/patches/mineflayer-pathfinder+2.4.5.patch +265 -0
- package/patches/mineflayer-pvp+1.3.2.patch +13 -0
- package/patches/prismarine-viewer+1.33.0.patch +13 -0
- package/patches/protodef+1.19.0.patch +15 -0
- package/profiles/andy-4-reasoning.json +14 -0
- package/profiles/andy-4.json +7 -0
- package/profiles/azure.json +19 -0
- package/profiles/claude.json +7 -0
- package/profiles/claude_thinker.json +15 -0
- package/profiles/deepseek.json +7 -0
- package/profiles/defaults/_default.json +256 -0
- package/profiles/defaults/assistant.json +14 -0
- package/profiles/defaults/creative.json +14 -0
- package/profiles/defaults/god_mode.json +14 -0
- package/profiles/defaults/survival.json +14 -0
- package/profiles/freeguy.json +7 -0
- package/profiles/gemini.json +9 -0
- package/profiles/gpt.json +12 -0
- package/profiles/grok.json +7 -0
- package/profiles/llama.json +10 -0
- package/profiles/mercury.json +9 -0
- package/profiles/mistral.json +5 -0
- package/profiles/qwen.json +17 -0
- package/profiles/tasks/construction_profile.json +42 -0
- package/profiles/tasks/cooking_profile.json +11 -0
- package/profiles/tasks/crafting_profile.json +71 -0
- package/profiles/vllm.json +10 -0
- package/settings.js +64 -0
- package/src/agent/action_manager.js +177 -0
- package/src/agent/agent.js +561 -0
- package/src/agent/coder.js +229 -0
- package/src/agent/commands/actions.js +504 -0
- package/src/agent/commands/index.js +259 -0
- package/src/agent/commands/queries.js +347 -0
- package/src/agent/connection_handler.js +96 -0
- package/src/agent/conversation.js +353 -0
- package/src/agent/history.js +122 -0
- package/src/agent/library/full_state.js +89 -0
- package/src/agent/library/index.js +23 -0
- package/src/agent/library/lockdown.js +32 -0
- package/src/agent/library/skill_library.js +93 -0
- package/src/agent/library/skills.js +2093 -0
- package/src/agent/library/world.js +431 -0
- package/src/agent/memory_bank.js +25 -0
- package/src/agent/mindserver_proxy.js +136 -0
- package/src/agent/modes.js +446 -0
- package/src/agent/npc/build_goal.js +80 -0
- package/src/agent/npc/construction/dirt_shelter.json +38 -0
- package/src/agent/npc/construction/large_house.json +230 -0
- package/src/agent/npc/construction/small_stone_house.json +42 -0
- package/src/agent/npc/construction/small_wood_house.json +42 -0
- package/src/agent/npc/controller.js +261 -0
- package/src/agent/npc/data.js +50 -0
- package/src/agent/npc/item_goal.js +355 -0
- package/src/agent/npc/utils.js +126 -0
- package/src/agent/self_prompter.js +146 -0
- package/src/agent/settings.js +7 -0
- package/src/agent/speak.js +150 -0
- package/src/agent/tasks/construction_tasks.js +1104 -0
- package/src/agent/tasks/cooking_tasks.js +358 -0
- package/src/agent/tasks/tasks.js +594 -0
- package/src/agent/templates/execTemplate.js +6 -0
- package/src/agent/templates/lintTemplate.js +10 -0
- package/src/agent/vision/browser_viewer.js +8 -0
- package/src/agent/vision/camera.js +78 -0
- package/src/agent/vision/vision_interpreter.js +82 -0
- package/src/mindcraft/index.js +28 -0
- package/src/mindcraft/mcserver.js +154 -0
- package/src/mindcraft/mindcraft.js +111 -0
- package/src/mindcraft/mindserver.js +328 -0
- package/src/mindcraft/public/index.html +1253 -0
- package/src/mindcraft/public/settings_spec.json +145 -0
- package/src/mindcraft/userconfig.js +72 -0
- package/src/mindcraft-py/example.py +27 -0
- package/src/mindcraft-py/init-mindcraft.js +24 -0
- package/src/mindcraft-py/mindcraft.py +99 -0
- package/src/models/_model_map.js +89 -0
- package/src/models/azure.js +32 -0
- package/src/models/cerebras.js +61 -0
- package/src/models/claude.js +87 -0
- package/src/models/deepseek.js +59 -0
- package/src/models/gemini.js +176 -0
- package/src/models/glhf.js +71 -0
- package/src/models/gpt.js +147 -0
- package/src/models/grok.js +82 -0
- package/src/models/groq.js +95 -0
- package/src/models/huggingface.js +86 -0
- package/src/models/hyperbolic.js +114 -0
- package/src/models/lmstudio.js +74 -0
- package/src/models/mercury.js +95 -0
- package/src/models/mistral.js +94 -0
- package/src/models/novita.js +71 -0
- package/src/models/ollama.js +115 -0
- package/src/models/openrouter.js +77 -0
- package/src/models/prompter.js +366 -0
- package/src/models/qwen.js +80 -0
- package/src/models/replicate.js +60 -0
- package/src/models/vllm.js +81 -0
- package/src/process/agent_process.js +84 -0
- package/src/process/init_agent.js +54 -0
- package/src/utils/examples.js +83 -0
- package/src/utils/keys.js +34 -0
- package/src/utils/math.js +13 -0
- package/src/utils/mcdata.js +572 -0
- package/src/utils/text.js +78 -0
- package/src/utils/translator.js +30 -0
|
@@ -0,0 +1,504 @@
|
|
|
1
|
+
import * as skills from '../library/skills.js';
|
|
2
|
+
import settings from '../settings.js';
|
|
3
|
+
import convoManager from '../conversation.js';
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
function runAsAction (actionFn, resume = false, timeout = -1) {
|
|
7
|
+
let actionLabel = null; // Will be set on first use
|
|
8
|
+
|
|
9
|
+
const wrappedAction = async function (agent, ...args) {
|
|
10
|
+
// Set actionLabel only once, when the action is first created
|
|
11
|
+
if (!actionLabel) {
|
|
12
|
+
const actionObj = actionsList.find(a => a.perform === wrappedAction);
|
|
13
|
+
actionLabel = actionObj.name.substring(1); // Remove the ! prefix
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const actionFnWithAgent = async () => {
|
|
17
|
+
await actionFn(agent, ...args);
|
|
18
|
+
};
|
|
19
|
+
const code_return = await agent.actions.runAction(`action:${actionLabel}`, actionFnWithAgent, { timeout, resume });
|
|
20
|
+
if (code_return.interrupted && !code_return.timedout)
|
|
21
|
+
return;
|
|
22
|
+
return code_return.message;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return wrappedAction;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export const actionsList = [
|
|
29
|
+
{
|
|
30
|
+
name: '!newAction',
|
|
31
|
+
description: 'Perform new and unknown custom behaviors that are not available as a command.',
|
|
32
|
+
params: {
|
|
33
|
+
'prompt': { type: 'string', description: 'A natural language prompt to guide code generation. Make a detailed step-by-step plan.' }
|
|
34
|
+
},
|
|
35
|
+
perform: async function(agent, prompt) {
|
|
36
|
+
// just ignore prompt - it is now in context in chat history
|
|
37
|
+
if (!settings.allow_insecure_coding) {
|
|
38
|
+
agent.openChat('newAction is disabled. Enable with allow_insecure_coding=true in settings.js');
|
|
39
|
+
return "newAction not allowed! Code writing is disabled in settings. Notify the user.";
|
|
40
|
+
}
|
|
41
|
+
let result = "";
|
|
42
|
+
const actionFn = async () => {
|
|
43
|
+
try {
|
|
44
|
+
result = await agent.coder.generateCode(agent.history);
|
|
45
|
+
} catch (e) {
|
|
46
|
+
result = 'Error generating code: ' + e.toString();
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
await agent.actions.runAction('action:newAction', actionFn, {timeout: settings.code_timeout_mins});
|
|
50
|
+
return result;
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
name: '!stop',
|
|
55
|
+
description: 'Force stop all actions and commands that are currently executing.',
|
|
56
|
+
perform: async function (agent) {
|
|
57
|
+
await agent.actions.stop();
|
|
58
|
+
agent.clearBotLogs();
|
|
59
|
+
agent.actions.cancelResume();
|
|
60
|
+
agent.bot.emit('idle');
|
|
61
|
+
let msg = 'Agent stopped.';
|
|
62
|
+
if (agent.self_prompter.isActive())
|
|
63
|
+
msg += ' Self-prompting still active.';
|
|
64
|
+
return msg;
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
name: '!stfu',
|
|
69
|
+
description: 'Stop all chatting and self prompting, but continue current action.',
|
|
70
|
+
perform: async function (agent) {
|
|
71
|
+
agent.openChat('Shutting up.');
|
|
72
|
+
agent.shutUp();
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
name: '!restart',
|
|
78
|
+
description: 'Restart the agent process.',
|
|
79
|
+
perform: async function (agent) {
|
|
80
|
+
agent.cleanKill();
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
name: '!clearChat',
|
|
85
|
+
description: 'Clear the chat history.',
|
|
86
|
+
perform: async function (agent) {
|
|
87
|
+
agent.history.clear();
|
|
88
|
+
return agent.name + "'s chat history was cleared, starting new conversation from scratch.";
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
name: '!goToPlayer',
|
|
93
|
+
description: 'Go to the given player.',
|
|
94
|
+
params: {
|
|
95
|
+
'player_name': {type: 'string', description: 'The name of the player to go to.'},
|
|
96
|
+
'closeness': {type: 'float', description: 'How close to get to the player.', domain: [0, Infinity]}
|
|
97
|
+
},
|
|
98
|
+
perform: runAsAction(async (agent, player_name, closeness) => {
|
|
99
|
+
await skills.goToPlayer(agent.bot, player_name, closeness);
|
|
100
|
+
})
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
name: '!followPlayer',
|
|
104
|
+
description: 'Endlessly follow the given player.',
|
|
105
|
+
params: {
|
|
106
|
+
'player_name': {type: 'string', description: 'name of the player to follow.'},
|
|
107
|
+
'follow_dist': {type: 'float', description: 'The distance to follow from.', domain: [0, Infinity]}
|
|
108
|
+
},
|
|
109
|
+
perform: runAsAction(async (agent, player_name, follow_dist) => {
|
|
110
|
+
await skills.followPlayer(agent.bot, player_name, follow_dist);
|
|
111
|
+
}, true)
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
name: '!goToCoordinates',
|
|
115
|
+
description: 'Go to the given x, y, z location.',
|
|
116
|
+
params: {
|
|
117
|
+
'x': {type: 'float', description: 'The x coordinate.', domain: [-Infinity, Infinity]},
|
|
118
|
+
'y': {type: 'float', description: 'The y coordinate.', domain: [-64, 320]},
|
|
119
|
+
'z': {type: 'float', description: 'The z coordinate.', domain: [-Infinity, Infinity]},
|
|
120
|
+
'closeness': {type: 'float', description: 'How close to get to the location.', domain: [0, Infinity]}
|
|
121
|
+
},
|
|
122
|
+
perform: runAsAction(async (agent, x, y, z, closeness) => {
|
|
123
|
+
await skills.goToPosition(agent.bot, x, y, z, closeness);
|
|
124
|
+
})
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
name: '!searchForBlock',
|
|
128
|
+
description: 'Find and go to the nearest block of a given type in a given range.',
|
|
129
|
+
params: {
|
|
130
|
+
'type': { type: 'BlockName', description: 'The block type to go to.' },
|
|
131
|
+
'search_range': { type: 'float', description: 'The range to search for the block. Minimum 32.', domain: [10, 512] }
|
|
132
|
+
},
|
|
133
|
+
perform: runAsAction(async (agent, block_type, range) => {
|
|
134
|
+
if (range < 32) {
|
|
135
|
+
skills.log(agent.bot, `Minimum search range is 32.`);
|
|
136
|
+
range = 32;
|
|
137
|
+
}
|
|
138
|
+
await skills.goToNearestBlock(agent.bot, block_type, 4, range);
|
|
139
|
+
})
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
name: '!searchForEntity',
|
|
143
|
+
description: 'Find and go to the nearest entity of a given type in a given range.',
|
|
144
|
+
params: {
|
|
145
|
+
'type': { type: 'string', description: 'The type of entity to go to.' },
|
|
146
|
+
'search_range': { type: 'float', description: 'The range to search for the entity.', domain: [32, 512] }
|
|
147
|
+
},
|
|
148
|
+
perform: runAsAction(async (agent, entity_type, range) => {
|
|
149
|
+
await skills.goToNearestEntity(agent.bot, entity_type, 4, range);
|
|
150
|
+
})
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
name: '!moveAway',
|
|
154
|
+
description: 'Move away from the current location in any direction by a given distance.',
|
|
155
|
+
params: {'distance': { type: 'float', description: 'The distance to move away.', domain: [0, Infinity] }},
|
|
156
|
+
perform: runAsAction(async (agent, distance) => {
|
|
157
|
+
await skills.moveAway(agent.bot, distance);
|
|
158
|
+
})
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
name: '!rememberHere',
|
|
162
|
+
description: 'Save the current location with a given name.',
|
|
163
|
+
params: {'name': { type: 'string', description: 'The name to remember the location as.' }},
|
|
164
|
+
perform: async function (agent, name) {
|
|
165
|
+
const pos = agent.bot.entity.position;
|
|
166
|
+
agent.memory_bank.rememberPlace(name, pos.x, pos.y, pos.z);
|
|
167
|
+
return `Location saved as "${name}".`;
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
name: '!goToRememberedPlace',
|
|
172
|
+
description: 'Go to a saved location.',
|
|
173
|
+
params: {'name': { type: 'string', description: 'The name of the location to go to.' }},
|
|
174
|
+
perform: runAsAction(async (agent, name) => {
|
|
175
|
+
const pos = agent.memory_bank.recallPlace(name);
|
|
176
|
+
if (!pos) {
|
|
177
|
+
skills.log(agent.bot, `No location named "${name}" saved.`);
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
await skills.goToPosition(agent.bot, pos[0], pos[1], pos[2], 1);
|
|
181
|
+
})
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
name: '!givePlayer',
|
|
185
|
+
description: 'Give the specified item to the given player.',
|
|
186
|
+
params: {
|
|
187
|
+
'player_name': { type: 'string', description: 'The name of the player to give the item to.' },
|
|
188
|
+
'item_name': { type: 'ItemName', description: 'The name of the item to give.' },
|
|
189
|
+
'num': { type: 'int', description: 'The number of items to give.', domain: [1, Number.MAX_SAFE_INTEGER] }
|
|
190
|
+
},
|
|
191
|
+
perform: runAsAction(async (agent, player_name, item_name, num) => {
|
|
192
|
+
await skills.giveToPlayer(agent.bot, item_name, player_name, num);
|
|
193
|
+
})
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
name: '!consume',
|
|
197
|
+
description: 'Eat/drink the given item.',
|
|
198
|
+
params: {'item_name': { type: 'ItemName', description: 'The name of the item to consume.' }},
|
|
199
|
+
perform: runAsAction(async (agent, item_name) => {
|
|
200
|
+
await skills.consume(agent.bot, item_name);
|
|
201
|
+
})
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
name: '!equip',
|
|
205
|
+
description: 'Equip the given item.',
|
|
206
|
+
params: {'item_name': { type: 'ItemName', description: 'The name of the item to equip.' }},
|
|
207
|
+
perform: runAsAction(async (agent, item_name) => {
|
|
208
|
+
await skills.equip(agent.bot, item_name);
|
|
209
|
+
})
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
name: '!putInChest',
|
|
213
|
+
description: 'Put the given item in the nearest chest.',
|
|
214
|
+
params: {
|
|
215
|
+
'item_name': { type: 'ItemName', description: 'The name of the item to put in the chest.' },
|
|
216
|
+
'num': { type: 'int', description: 'The number of items to put in the chest.', domain: [1, Number.MAX_SAFE_INTEGER] }
|
|
217
|
+
},
|
|
218
|
+
perform: runAsAction(async (agent, item_name, num) => {
|
|
219
|
+
await skills.putInChest(agent.bot, item_name, num);
|
|
220
|
+
})
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
name: '!takeFromChest',
|
|
224
|
+
description: 'Take the given items from the nearest chest.',
|
|
225
|
+
params: {
|
|
226
|
+
'item_name': { type: 'ItemName', description: 'The name of the item to take.' },
|
|
227
|
+
'num': { type: 'int', description: 'The number of items to take.', domain: [1, Number.MAX_SAFE_INTEGER] }
|
|
228
|
+
},
|
|
229
|
+
perform: runAsAction(async (agent, item_name, num) => {
|
|
230
|
+
await skills.takeFromChest(agent.bot, item_name, num);
|
|
231
|
+
})
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
name: '!viewChest',
|
|
235
|
+
description: 'View the items/counts of the nearest chest.',
|
|
236
|
+
params: { },
|
|
237
|
+
perform: runAsAction(async (agent) => {
|
|
238
|
+
await skills.viewChest(agent.bot);
|
|
239
|
+
})
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
name: '!discard',
|
|
243
|
+
description: 'Discard the given item from the inventory.',
|
|
244
|
+
params: {
|
|
245
|
+
'item_name': { type: 'ItemName', description: 'The name of the item to discard.' },
|
|
246
|
+
'num': { type: 'int', description: 'The number of items to discard.', domain: [1, Number.MAX_SAFE_INTEGER] }
|
|
247
|
+
},
|
|
248
|
+
perform: runAsAction(async (agent, item_name, num) => {
|
|
249
|
+
const start_loc = agent.bot.entity.position;
|
|
250
|
+
await skills.moveAway(agent.bot, 5);
|
|
251
|
+
await skills.discard(agent.bot, item_name, num);
|
|
252
|
+
await skills.goToPosition(agent.bot, start_loc.x, start_loc.y, start_loc.z, 0);
|
|
253
|
+
})
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
name: '!collectBlocks',
|
|
257
|
+
description: 'Collect the nearest blocks of a given type.',
|
|
258
|
+
params: {
|
|
259
|
+
'type': { type: 'BlockName', description: 'The block type to collect.' },
|
|
260
|
+
'num': { type: 'int', description: 'The number of blocks to collect.', domain: [1, Number.MAX_SAFE_INTEGER] }
|
|
261
|
+
},
|
|
262
|
+
perform: runAsAction(async (agent, type, num) => {
|
|
263
|
+
await skills.collectBlock(agent.bot, type, num);
|
|
264
|
+
}, false, 10) // 10 minute timeout
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
name: '!craftRecipe',
|
|
268
|
+
description: 'Craft the given recipe a given number of times.',
|
|
269
|
+
params: {
|
|
270
|
+
'recipe_name': { type: 'ItemName', description: 'The name of the output item to craft.' },
|
|
271
|
+
'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] }
|
|
272
|
+
},
|
|
273
|
+
perform: runAsAction(async (agent, recipe_name, num) => {
|
|
274
|
+
await skills.craftRecipe(agent.bot, recipe_name, num);
|
|
275
|
+
})
|
|
276
|
+
},
|
|
277
|
+
{
|
|
278
|
+
name: '!smeltItem',
|
|
279
|
+
description: 'Smelt the given item the given number of times.',
|
|
280
|
+
params: {
|
|
281
|
+
'item_name': { type: 'ItemName', description: 'The name of the input item to smelt.' },
|
|
282
|
+
'num': { type: 'int', description: 'The number of times to smelt the item.', domain: [1, Number.MAX_SAFE_INTEGER] }
|
|
283
|
+
},
|
|
284
|
+
perform: runAsAction(async (agent, item_name, num) => {
|
|
285
|
+
let success = await skills.smeltItem(agent.bot, item_name, num);
|
|
286
|
+
if (success) {
|
|
287
|
+
setTimeout(() => {
|
|
288
|
+
agent.cleanKill('Safely restarting to update inventory.');
|
|
289
|
+
}, 500);
|
|
290
|
+
}
|
|
291
|
+
})
|
|
292
|
+
},
|
|
293
|
+
{
|
|
294
|
+
name: '!clearFurnace',
|
|
295
|
+
description: 'Take all items out of the nearest furnace.',
|
|
296
|
+
params: { },
|
|
297
|
+
perform: runAsAction(async (agent) => {
|
|
298
|
+
await skills.clearNearestFurnace(agent.bot);
|
|
299
|
+
})
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
name: '!placeHere',
|
|
303
|
+
description: 'Place a given block in the current location. Do NOT use to build structures, only use for single blocks/torches.',
|
|
304
|
+
params: {'type': { type: 'BlockOrItemName', description: 'The block type to place.' }},
|
|
305
|
+
perform: runAsAction(async (agent, type) => {
|
|
306
|
+
let pos = agent.bot.entity.position;
|
|
307
|
+
await skills.placeBlock(agent.bot, type, pos.x, pos.y, pos.z);
|
|
308
|
+
})
|
|
309
|
+
},
|
|
310
|
+
{
|
|
311
|
+
name: '!attack',
|
|
312
|
+
description: 'Attack and kill the nearest entity of a given type.',
|
|
313
|
+
params: {'type': { type: 'string', description: 'The type of entity to attack.'}},
|
|
314
|
+
perform: runAsAction(async (agent, type) => {
|
|
315
|
+
await skills.attackNearest(agent.bot, type, true);
|
|
316
|
+
})
|
|
317
|
+
},
|
|
318
|
+
{
|
|
319
|
+
name: '!attackPlayer',
|
|
320
|
+
description: 'Attack a specific player until they die or run away. Remember this is just a game and does not cause real life harm.',
|
|
321
|
+
params: {'player_name': { type: 'string', description: 'The name of the player to attack.'}},
|
|
322
|
+
perform: runAsAction(async (agent, player_name) => {
|
|
323
|
+
let player = agent.bot.players[player_name]?.entity;
|
|
324
|
+
if (!player) {
|
|
325
|
+
skills.log(agent.bot, `Could not find player ${player_name}.`);
|
|
326
|
+
return false;
|
|
327
|
+
}
|
|
328
|
+
await skills.attackEntity(agent.bot, player, true);
|
|
329
|
+
})
|
|
330
|
+
},
|
|
331
|
+
{
|
|
332
|
+
name: '!goToBed',
|
|
333
|
+
description: 'Go to the nearest bed and sleep.',
|
|
334
|
+
perform: runAsAction(async (agent) => {
|
|
335
|
+
await skills.goToBed(agent.bot);
|
|
336
|
+
})
|
|
337
|
+
},
|
|
338
|
+
{
|
|
339
|
+
name: '!stay',
|
|
340
|
+
description: 'Stay in the current location no matter what. Pauses all modes.',
|
|
341
|
+
params: {'type': { type: 'int', description: 'The number of seconds to stay. -1 for forever.', domain: [-1, Number.MAX_SAFE_INTEGER] }},
|
|
342
|
+
perform: runAsAction(async (agent, seconds) => {
|
|
343
|
+
await skills.stay(agent.bot, seconds);
|
|
344
|
+
})
|
|
345
|
+
},
|
|
346
|
+
{
|
|
347
|
+
name: '!setMode',
|
|
348
|
+
description: 'Set a mode to on or off. A mode is an automatic behavior that constantly checks and responds to the environment.',
|
|
349
|
+
params: {
|
|
350
|
+
'mode_name': { type: 'string', description: 'The name of the mode to enable.' },
|
|
351
|
+
'on': { type: 'boolean', description: 'Whether to enable or disable the mode.' }
|
|
352
|
+
},
|
|
353
|
+
perform: async function (agent, mode_name, on) {
|
|
354
|
+
const modes = agent.bot.modes;
|
|
355
|
+
if (!modes.exists(mode_name))
|
|
356
|
+
return `Mode ${mode_name} does not exist.` + modes.getDocs();
|
|
357
|
+
if (modes.isOn(mode_name) === on)
|
|
358
|
+
return `Mode ${mode_name} is already ${on ? 'on' : 'off'}.`;
|
|
359
|
+
modes.setOn(mode_name, on);
|
|
360
|
+
return `Mode ${mode_name} is now ${on ? 'on' : 'off'}.`;
|
|
361
|
+
}
|
|
362
|
+
},
|
|
363
|
+
{
|
|
364
|
+
name: '!goal',
|
|
365
|
+
description: 'Set a goal prompt to endlessly work towards with continuous self-prompting.',
|
|
366
|
+
params: {
|
|
367
|
+
'selfPrompt': { type: 'string', description: 'The goal prompt.' },
|
|
368
|
+
},
|
|
369
|
+
perform: async function (agent, prompt) {
|
|
370
|
+
if (convoManager.inConversation()) {
|
|
371
|
+
agent.self_prompter.setPromptPaused(prompt);
|
|
372
|
+
}
|
|
373
|
+
else {
|
|
374
|
+
agent.self_prompter.start(prompt);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
},
|
|
378
|
+
{
|
|
379
|
+
name: '!endGoal',
|
|
380
|
+
description: 'Call when you have accomplished your goal. It will stop self-prompting and the current action. ',
|
|
381
|
+
perform: async function (agent) {
|
|
382
|
+
agent.self_prompter.stop();
|
|
383
|
+
return 'Self-prompting stopped.';
|
|
384
|
+
}
|
|
385
|
+
},
|
|
386
|
+
{
|
|
387
|
+
name: '!showVillagerTrades',
|
|
388
|
+
description: 'Show trades of a specified villager.',
|
|
389
|
+
params: {'id': { type: 'int', description: 'The id number of the villager that you want to trade with.' }},
|
|
390
|
+
perform: runAsAction(async (agent, id) => {
|
|
391
|
+
await skills.showVillagerTrades(agent.bot, id);
|
|
392
|
+
})
|
|
393
|
+
},
|
|
394
|
+
{
|
|
395
|
+
name: '!tradeWithVillager',
|
|
396
|
+
description: 'Trade with a specified villager.',
|
|
397
|
+
params: {
|
|
398
|
+
'id': { type: 'int', description: 'The id number of the villager that you want to trade with.' },
|
|
399
|
+
'index': { type: 'int', description: 'The index of the trade you want executed (1-indexed).', domain: [1, Number.MAX_SAFE_INTEGER] },
|
|
400
|
+
'count': { type: 'int', description: 'How many times that trade should be executed.', domain: [1, Number.MAX_SAFE_INTEGER] },
|
|
401
|
+
},
|
|
402
|
+
perform: runAsAction(async (agent, id, index, count) => {
|
|
403
|
+
await skills.tradeWithVillager(agent.bot, id, index, count);
|
|
404
|
+
})
|
|
405
|
+
},
|
|
406
|
+
{
|
|
407
|
+
name: '!startConversation',
|
|
408
|
+
description: 'Start a conversation with a bot. (FOR OTHER BOTS ONLY)',
|
|
409
|
+
params: {
|
|
410
|
+
'player_name': { type: 'string', description: 'The name of the player to send the message to.' },
|
|
411
|
+
'message': { type: 'string', description: 'The message to send.' },
|
|
412
|
+
},
|
|
413
|
+
perform: async function (agent, player_name, message) {
|
|
414
|
+
if (!convoManager.isOtherAgent(player_name))
|
|
415
|
+
return player_name + ' is not a bot, cannot start conversation.';
|
|
416
|
+
if (convoManager.inConversation() && !convoManager.inConversation(player_name))
|
|
417
|
+
convoManager.forceEndCurrentConversation();
|
|
418
|
+
else if (convoManager.inConversation(player_name))
|
|
419
|
+
agent.history.add('system', 'You are already in conversation with ' + player_name + '. Don\'t use this command to talk to them.');
|
|
420
|
+
convoManager.startConversation(player_name, message);
|
|
421
|
+
}
|
|
422
|
+
},
|
|
423
|
+
{
|
|
424
|
+
name: '!endConversation',
|
|
425
|
+
description: 'End the conversation with the given bot. (FOR OTHER BOTS ONLY)',
|
|
426
|
+
params: {
|
|
427
|
+
'player_name': { type: 'string', description: 'The name of the player to end the conversation with.' }
|
|
428
|
+
},
|
|
429
|
+
perform: async function (agent, player_name) {
|
|
430
|
+
if (!convoManager.inConversation(player_name))
|
|
431
|
+
return `Not in conversation with ${player_name}.`;
|
|
432
|
+
convoManager.endConversation(player_name);
|
|
433
|
+
return `Converstaion with ${player_name} ended.`;
|
|
434
|
+
}
|
|
435
|
+
},
|
|
436
|
+
{
|
|
437
|
+
name: '!lookAtPlayer',
|
|
438
|
+
description: 'Look at a player or look in the same direction as the player.',
|
|
439
|
+
params: {
|
|
440
|
+
'player_name': { type: 'string', description: 'Name of the target player' },
|
|
441
|
+
'direction': {
|
|
442
|
+
type: 'string',
|
|
443
|
+
description: 'How to look ("at": look at the player, "with": look in the same direction as the player)',
|
|
444
|
+
}
|
|
445
|
+
},
|
|
446
|
+
perform: async function(agent, player_name, direction) {
|
|
447
|
+
if (direction !== 'at' && direction !== 'with') {
|
|
448
|
+
return "Invalid direction. Use 'at' or 'with'.";
|
|
449
|
+
}
|
|
450
|
+
if (!agent.vision_interpreter) return "Vision is unavailable (optional native deps not built).";
|
|
451
|
+
let result = "";
|
|
452
|
+
const actionFn = async () => {
|
|
453
|
+
result = await agent.vision_interpreter.lookAtPlayer(player_name, direction);
|
|
454
|
+
};
|
|
455
|
+
await agent.actions.runAction('action:lookAtPlayer', actionFn);
|
|
456
|
+
return result;
|
|
457
|
+
}
|
|
458
|
+
},
|
|
459
|
+
{
|
|
460
|
+
name: '!lookAtPosition',
|
|
461
|
+
description: 'Look at specified coordinates.',
|
|
462
|
+
params: {
|
|
463
|
+
'x': { type: 'int', description: 'x coordinate' },
|
|
464
|
+
'y': { type: 'int', description: 'y coordinate' },
|
|
465
|
+
'z': { type: 'int', description: 'z coordinate' }
|
|
466
|
+
},
|
|
467
|
+
perform: async function(agent, x, y, z) {
|
|
468
|
+
if (!agent.vision_interpreter) return "Vision is unavailable (optional native deps not built).";
|
|
469
|
+
let result = "";
|
|
470
|
+
const actionFn = async () => {
|
|
471
|
+
result = await agent.vision_interpreter.lookAtPosition(x, y, z);
|
|
472
|
+
};
|
|
473
|
+
await agent.actions.runAction('action:lookAtPosition', actionFn);
|
|
474
|
+
return result;
|
|
475
|
+
}
|
|
476
|
+
},
|
|
477
|
+
{
|
|
478
|
+
name: '!digDown',
|
|
479
|
+
description: 'Digs down a specified distance. Will stop if it reaches lava, water, or a fall of >=4 blocks below the bot.',
|
|
480
|
+
params: {'distance': { type: 'int', description: 'Distance to dig down', domain: [1, Number.MAX_SAFE_INTEGER] }},
|
|
481
|
+
perform: runAsAction(async (agent, distance) => {
|
|
482
|
+
await skills.digDown(agent.bot, distance)
|
|
483
|
+
})
|
|
484
|
+
},
|
|
485
|
+
{
|
|
486
|
+
name: '!goToSurface',
|
|
487
|
+
description: 'Moves the bot to the highest block above it (usually the surface).',
|
|
488
|
+
params: {},
|
|
489
|
+
perform: runAsAction(async (agent) => {
|
|
490
|
+
await skills.goToSurface(agent.bot);
|
|
491
|
+
})
|
|
492
|
+
},
|
|
493
|
+
{
|
|
494
|
+
name: '!useOn',
|
|
495
|
+
description: 'Use (right click) the given tool on the nearest target of the given type.',
|
|
496
|
+
params: {
|
|
497
|
+
'tool_name': { type: 'string', description: 'Name of the tool to use, or "hand" for no tool.' },
|
|
498
|
+
'target': { type: 'string', description: 'The target as an entity type, block type, or "nothing" for no target.' }
|
|
499
|
+
},
|
|
500
|
+
perform: runAsAction(async (agent, tool_name, target) => {
|
|
501
|
+
await skills.useToolOn(agent.bot, tool_name, target);
|
|
502
|
+
})
|
|
503
|
+
},
|
|
504
|
+
];
|