Skip to content

Commit 59847cf

Browse files
shinohara-rinnekomeowww
authored andcommitted
feat(minecraft): add mineBlockAt tool
1 parent 9300a7d commit 59847cf

File tree

1 file changed

+34
-2
lines changed
  • services/minecraft/src/agents/action

1 file changed

+34
-2
lines changed

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

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
// TODO: move this file to action layer, and rename to `llm-actions.ts`
22
import type { Action } from '../../libs/mineflayer'
33

4+
import { Vec3 } from 'vec3'
45
import { z } from 'zod'
56

67
import { collectBlock } from '../../skills/actions/collect-block'
78
import { discard, equip, putInChest, takeFromChest } from '../../skills/actions/inventory'
8-
import { activateNearestBlock, placeBlock } from '../../skills/actions/world-interactions'
9+
import { activateNearestBlock, breakBlockAt, placeBlock } from '../../skills/actions/world-interactions'
910
import { ActionError } from '../../utils/errors'
1011
import { useLogger } from '../../utils/logger'
1112

@@ -264,7 +265,7 @@ export const actionsList: Action[] = [
264265
},
265266
{
266267
name: 'collectBlocks',
267-
description: 'Collect the nearest blocks of a given type.',
268+
description: 'Automatically collect the nearest blocks of a given type.',
268269
execution: 'sequential',
269270
schema: z.object({
270271
type: z.string().describe('The block type to collect.'),
@@ -278,6 +279,37 @@ export const actionsList: Action[] = [
278279
return `Collected [${type}] x${collected}`
279280
},
280281
},
282+
{
283+
name: 'mineBlockAt',
284+
description: 'Mine (break) a block at a specific position. Do NOT use this for regular resource collection. Use collectBlocks instead.',
285+
execution: 'sequential',
286+
schema: z.object({
287+
x: z.number().describe('The x coordinate.'),
288+
y: z.number().describe('The y coordinate.'),
289+
z: z.number().describe('The z coordinate.'),
290+
expected_block_type: z.string().optional().describe('Optional: expected block type at the position (e.g. oak_log). If provided and mismatched, the action fails.'),
291+
}),
292+
perform: mineflayer => async (x: number, y: number, z: number, expected_block_type?: string) => {
293+
const pos = new Vec3(Math.floor(x), Math.floor(y), Math.floor(z))
294+
if (expected_block_type) {
295+
const block = mineflayer.bot.blockAt(pos)
296+
if (!block) {
297+
throw new ActionError('TARGET_NOT_FOUND', `No block found at ${pos}`, { position: pos })
298+
}
299+
300+
if (block.name !== expected_block_type) {
301+
throw new ActionError('UNKNOWN', `Block type mismatch at ${pos}: expected ${expected_block_type}, got ${block.name}`, {
302+
position: pos,
303+
expected: expected_block_type,
304+
actual: block.name,
305+
})
306+
}
307+
}
308+
309+
await breakBlockAt(mineflayer, pos.x, pos.y, pos.z)
310+
return `Mined block at (${pos.x}, ${pos.y}, ${pos.z})`
311+
},
312+
},
281313
{
282314
name: 'craftRecipe',
283315
description: 'Craft the given recipe a given number of times.',

0 commit comments

Comments
 (0)