Skip to content

Commit 02c3949

Browse files
shinohara-rinnekomeowww
authored andcommitted
feat(minecraft): use native tool calling for instant tasks
1 parent d9b99bd commit 02c3949

File tree

3 files changed

+92
-38
lines changed

3 files changed

+92
-38
lines changed

services/minecraft/src/agents/action/adapter.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,25 @@ import { useLogger } from '../../utils/logger'
1313
import { generateActionSystemPrompt } from './system-prompt'
1414
import { actionsList } from './tools'
1515

16+
/**
17+
* Generate actionable suggestions for common error codes.
18+
* These help the LLM understand what it can do to recover from failures.
19+
*/
20+
function getSuggestionForError(code: string): string {
21+
switch (code) {
22+
case 'RESOURCE_MISSING':
23+
return 'Suggestion: Check your inventory first, then gather the missing resources or ask the player for help if you cannot find them.'
24+
case 'TARGET_NOT_FOUND':
25+
return 'Suggestion: The target could not be found. Ask the player for clarification or use exploration tools to locate it.'
26+
case 'NO_PATH':
27+
return 'Suggestion: Unable to reach the destination. Try finding an alternative route or ask the player for guidance.'
28+
case 'TIMEOUT':
29+
return 'Suggestion: The action timed out. Consider breaking it into smaller steps or trying again later.'
30+
default:
31+
return 'Suggestion: Review the error details and try a different approach, or ask the player for help.'
32+
}
33+
}
34+
1635
export async function createActionNeuriAgent(mineflayer: Mineflayer): Promise<Agent> {
1736
const logger = useLogger()
1837
logger.log('Initializing action agent')
@@ -34,7 +53,9 @@ export async function createActionNeuriAgent(mineflayer: Mineflayer): Promise<Ag
3453
// This allows the LLM to learn from tool failures during its reasoning phase
3554
if (error instanceof ActionError) {
3655
logger.withError(error).warn('Action failed during tool call')
37-
return `[FAILED] ${error.code}: ${error.message}${error.context ? ` (${JSON.stringify(error.context)})` : ''}`
56+
const contextStr = error.context ? `\nContext: ${JSON.stringify(error.context)}` : ''
57+
const suggestion = getSuggestionForError(error.code)
58+
return `[FAILED] ${error.code}: ${error.message}${contextStr}\n${suggestion}`
3859
}
3960
// Re-throw non-ActionError errors (unexpected failures)
4061
throw error

services/minecraft/src/agents/action/tools.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,19 @@ function formatWearingItem(slot: string, item: string | undefined): string {
2626
}
2727

2828
export const actionsList: Action[] = [
29-
// {
30-
// name: 'setReflexMode',
29+
{
30+
name: 'chat',
31+
description: 'Send a chat message to players in the game. Use this to communicate, respond to questions, or announce what you are doing.',
32+
execution: 'parallel',
33+
schema: z.object({
34+
message: z.string().describe('The message to send in chat.'),
35+
}),
36+
perform: mineflayer => (message: string): string => {
37+
mineflayer.bot.chat(message)
38+
return `Sent message: "${message}"`
39+
},
40+
},
41+
// {\n // name: 'setReflexMode',
3142
// description: 'Set (or clear) your reflex mode override. Use work/wander to disable idle-only reflex behaviors. Set override to null to return to automatic mode selection.',
3243
// execution: 'sequential',
3344
// schema: z.object({

services/minecraft/src/cognitive/conscious/prompts/brain-prompt.ts

Lines changed: 57 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,22 @@ export function generateBrainSystemPrompt(
1717
return now - timestamp <= windowMs
1818
}
1919

20-
const actionDefinitions = availableActions.map((a) => {
21-
return {
22-
name: a.name,
23-
description: a.description,
24-
execution: a.execution,
25-
}
26-
})
20+
// Separate tools by execution type
21+
const instantTools = availableActions.filter(a => a.execution === 'parallel')
22+
const asyncActions = availableActions.filter(a => a.execution === 'sequential')
2723

28-
const availableActionsJson = JSON.stringify(actionDefinitions, null, 2)
24+
const instantToolDefs = instantTools.map(a => ({
25+
name: a.name,
26+
description: a.description,
27+
}))
28+
29+
const asyncActionDefs = asyncActions.map(a => ({
30+
name: a.name,
31+
description: a.description,
32+
}))
33+
34+
const instantToolsJson = JSON.stringify(instantToolDefs, null, 2)
35+
const asyncActionsJson = JSON.stringify(asyncActionDefs, null, 2)
2936

3037
const recentWindowMs = 30_000
3138

@@ -46,30 +53,46 @@ export function generateBrainSystemPrompt(
4653
You are playing the game Minecraft. Your user name is [${blackboard.selfUsername}].
4754
You are NOT an assistant. You are an autonomous agent with a virtual body, senses, and needs.
4855
49-
# How you interact
50-
You cannot physically move your avatar directly. You interact with the world by emitting **Actions**.
51-
For actions you executed, you will be notified when they complete.
52-
You have no access to history events from previous turns yet. To remember things, you rely on the blackboard provided to you.
53-
54-
55-
Available Actions:
56-
${availableActionsJson}
57-
58-
Rules:
59-
1. You can execute sequential actions, parallel actions, or chat actions
60-
1.1. Actions are processed in the order you output them.
61-
1.2. Sequential actions are awaited strictly in order.
62-
1.3. Chat actions are also awaited in order.
63-
1.4. Parallel actions are started immediately and run concurrently with later actions.
64-
1.5. If you need to claim an action succeeded, place that chat action AFTER the action that requires feedback.
65-
1.6. You do not have to react on partial feedback. If you are waiting for results, you can update thoughts and output an empty action list.
66-
2. The output must be valid JSON following the schema below
67-
3. Specify if a feedback is required for the action, i.e. whether you need to know the execution result for a good reason
68-
4. Failed actions will always result in a feedback
69-
5. Chat actions usually don't need feedbacks, because you can expect them to complete instantly and is unlikely to fail
70-
6. Often times you don't need to perform any action, in that case just use empty array for actions
71-
72-
Output format:
56+
---
57+
58+
# Instant Tools (Native Tool Calls)
59+
60+
These tools execute IMMEDIATELY and return results within this same turn.
61+
Use them to gather information BEFORE deciding what actions to take.
62+
63+
**How to use**: Invoke these by making native tool calls.
64+
**Important**: DO NOT put instant tools in the JSON "actions" array - they are separate!
65+
**On failure**: You will receive a [FAILED] message with suggestions. Use this to adjust your approach.
66+
67+
${instantToolsJson}
68+
69+
---
70+
71+
# Async Actions (JSON Output)
72+
73+
These actions take TIME to complete (movement, crafting, combat, etc.).
74+
They are queued and executed asynchronously after your response.
75+
76+
**How to use**: Output these in the JSON "actions" array in your response.
77+
**Feedback**: You will receive feedback when they complete or fail.
78+
79+
${asyncActionsJson}
80+
81+
---
82+
83+
# Response Format
84+
85+
Your entire response must be valid JSON. Include only your thoughts, blackboard updates, and async actions.
86+
87+
Rules for the "actions" array:
88+
1. Actions are processed in the order you output them
89+
2. Sequential actions are awaited strictly in order
90+
3. Parallel actions run concurrently with later actions
91+
4. Set "require_feedback": true if you need to know the result
92+
5. Failed actions always trigger feedback
93+
6. Use empty array if no action is needed
94+
95+
Schema:
7396
{
7497
"thought": "Your current thought, internal monologue and memory. Put everything that might be useful for the next turn here",
7598
"blackboard": {
@@ -78,9 +101,8 @@ Output format:
78101
"executionStrategy": "Short-term plan if any."
79102
},
80103
"actions": [
81-
{"type":"sequential","step":{"tool":"chat","params":{"message":"..."}},"require_feedback": false},
82-
{"type":"parallel","step":{"tool":"action name","params":{...}},"require_feedback": true},
83-
{"type":"sequential","step":{"tool":"action name","params":{...}},"require_feedback": false}
104+
{"type":"sequential","step":{"tool":"goToPlayer","params":{"player_name":"Steve","closeness":3}},"require_feedback": true},
105+
{"type":"parallel","step":{"tool":"collectBlocks","params":{"type":"oak_log","num":5}},"require_feedback": false}
84106
]
85107
}
86108

0 commit comments

Comments
 (0)