From 8010c49d94cb70e841fe3cb2677261a388c037d1 Mon Sep 17 00:00:00 2001 From: Rin Date: Sat, 7 Feb 2026 22:00:20 +0800 Subject: [PATCH] feat(minecraft): add includeBuiltins option to get_state tool to filter REPL builtins by default Add includeBuiltins parameter to Brain.getReplState/JavaScriptPlanner.describeGlobals to optionally skip REPL builtins (skip/use/log/forget_conversation), default to excluding builtins in get_state MCP tool to reduce noise (pass includeBuiltins:true to include them), update SKILL.md documenting builtin filtering behavior, add tests verifying get_state calls getReplState with includeBuiltins flag, ad --- .../codex-skills/minecraft-debug-mcp/SKILL.md | 4 ++-- .../src/cognitive/conscious/brain.ts | 3 ++- .../src/cognitive/conscious/js-planner.ts | 24 ++++++++++++++----- .../src/cognitive/conscious/llm-agent.ts | 1 + .../src/debug/mcp-repl-server.test.ts | 18 ++++++++++++++ .../minecraft/src/debug/mcp-repl-server.ts | 8 ++++--- 6 files changed, 46 insertions(+), 12 deletions(-) diff --git a/services/minecraft/codex-skills/minecraft-debug-mcp/SKILL.md b/services/minecraft/codex-skills/minecraft-debug-mcp/SKILL.md index 759152341..bb5c162c6 100644 --- a/services/minecraft/codex-skills/minecraft-debug-mcp/SKILL.md +++ b/services/minecraft/codex-skills/minecraft-debug-mcp/SKILL.md @@ -31,7 +31,7 @@ Use this skill to run the local bot and interact with its MCP debug interface sa ## Tooling Strategy -- Use `get_state` to inspect queue/processing state. +- Use `get_state` to inspect queue/processing state and available tools/actions (skips REPL builtins by default; pass `{ includeBuiltins: true }` to include them). - Use `get_logs` with a small `limit` first. - Use `get_last_prompt` to inspect latest LLM input. - Use `execute_repl` for deep object inspection or one-off targeted calls on the running brain. @@ -43,7 +43,7 @@ Read `references/mcp-surface.md` for exact tool/resource names and argument sche ## Live-Tested Notes -- `get_state` returns a large variable snapshot; prefer it over REPL for first-pass health checks. +- `get_state` returns available tools/actions and runtime state (skips REPL builtins like `skip`, `use`, `log` by default to reduce noise; pass `{ includeBuiltins: true }` if you need to inspect them). - `get_last_prompt` can return very large payloads; call only when prompt-level debugging is needed. - `execute_repl` returns a structured result where `returnValue` is stringified; parse mentally as display output, not typed JSON. - `get_logs(limit=10)` is enough to verify whether an injected event reached REPL/executor. diff --git a/services/minecraft/src/cognitive/conscious/brain.ts b/services/minecraft/src/cognitive/conscious/brain.ts index ce45a7d58..2bc2fe576 100644 --- a/services/minecraft/src/cognitive/conscious/brain.ts +++ b/services/minecraft/src/cognitive/conscious/brain.ts @@ -272,7 +272,7 @@ export class Brain { this.runtimeMineflayer = null } - public getReplState(): { variables: PlannerGlobalDescriptor[], updatedAt: number, paused: boolean } { + public getReplState(options: { includeBuiltins?: boolean } = {}): { variables: PlannerGlobalDescriptor[], updatedAt: number, paused: boolean } { const snapshot = this.deps.reflexManager.getContextSnapshot() const replEvent: BotEvent = { type: 'system_alert', @@ -283,6 +283,7 @@ export class Brain { const variables = this.repl.describeGlobals( this.deps.taskExecutor.getAvailableActions(), this.createRuntimeGlobals(replEvent, snapshot as unknown as Record), + { includeBuiltins: options.includeBuiltins }, ) return { diff --git a/services/minecraft/src/cognitive/conscious/js-planner.ts b/services/minecraft/src/cognitive/conscious/js-planner.ts index 5088a3644..f6872f4a7 100644 --- a/services/minecraft/src/cognitive/conscious/js-planner.ts +++ b/services/minecraft/src/cognitive/conscious/js-planner.ts @@ -93,6 +93,10 @@ export interface PlannerGlobalDescriptor { preview: string } +interface DescribeGlobalsOptions { + includeBuiltins?: boolean +} + export function extractJavaScriptCandidate(input: string): string { const trimmed = input.trim() const fenced = trimmed.match(/^```(?:js|javascript|ts|typescript)?\s*([\s\S]*?)\s*```$/i) @@ -180,9 +184,15 @@ export class JavaScriptPlanner { } } - public describeGlobals(availableActions: Action[], globals: RuntimeGlobals): PlannerGlobalDescriptor[] { + public describeGlobals( + availableActions: Action[], + globals: RuntimeGlobals, + options: DescribeGlobalsOptions = {}, + ): PlannerGlobalDescriptor[] { const descriptors: PlannerGlobalDescriptor[] = [] + const includeBuiltins = options.includeBuiltins ?? true + const staticGlobals: Array> = [ { name: 'skip', kind: 'tool', readonly: true }, { name: 'use', kind: 'function', readonly: true }, @@ -251,11 +261,13 @@ export class JavaScriptPlanner { forget_conversation: this.sandbox.forget_conversation, } - for (const item of staticGlobals) { - descriptors.push({ - ...item, - preview: this.previewValue(valueByName[item.name]), - }) + if (includeBuiltins) { + for (const item of staticGlobals) { + descriptors.push({ + ...item, + preview: this.previewValue(valueByName[item.name]), + }) + } } for (const action of availableActions) { diff --git a/services/minecraft/src/cognitive/conscious/llm-agent.ts b/services/minecraft/src/cognitive/conscious/llm-agent.ts index b6c03fba9..d6d2abfa6 100644 --- a/services/minecraft/src/cognitive/conscious/llm-agent.ts +++ b/services/minecraft/src/cognitive/conscious/llm-agent.ts @@ -27,6 +27,7 @@ export class LLMAgent { constructor(private config: LLMConfig) { } private isCerebrasBaseURL(baseURL: string): boolean { + return true // TODO: REMOVE ME const normalized = baseURL.toLowerCase() return normalized.includes('cerebras.ai') || normalized.includes('cerebras.com') } diff --git a/services/minecraft/src/debug/mcp-repl-server.test.ts b/services/minecraft/src/debug/mcp-repl-server.test.ts index 85787c651..dd94360f3 100644 --- a/services/minecraft/src/debug/mcp-repl-server.test.ts +++ b/services/minecraft/src/debug/mcp-repl-server.test.ts @@ -123,6 +123,24 @@ describe('mcpReplServer', () => { })) }) + it('gets repl state via tool handler (skips builtins by default)', async () => { + const toolCall = mocks.tool.mock.calls.find(call => call[0] === 'get_state') + const handler = toolCall[2] + + await handler({}) + + expect(brain.getReplState).toHaveBeenCalledWith({ includeBuiltins: false }) + }) + + it('gets repl state via tool handler (can include builtins)', async () => { + const toolCall = mocks.tool.mock.calls.find(call => call[0] === 'get_state') + const handler = toolCall[2] + + await handler({ includeBuiltins: true }) + + expect(brain.getReplState).toHaveBeenCalledWith({ includeBuiltins: true }) + }) + it('reads brain state via resource handler', async () => { const resourceCall = mocks.resource.mock.calls.find(call => call[0] === 'brain-state') const handler = resourceCall[2] diff --git a/services/minecraft/src/debug/mcp-repl-server.ts b/services/minecraft/src/debug/mcp-repl-server.ts index 4d3d124c9..0bbc5a405 100644 --- a/services/minecraft/src/debug/mcp-repl-server.ts +++ b/services/minecraft/src/debug/mcp-repl-server.ts @@ -179,9 +179,11 @@ export class McpReplServer { this.mcpServer.tool( 'get_state', - {}, - async () => { - const result = this.brain.getReplState() + { + includeBuiltins: z.boolean().optional(), + }, + async ({ includeBuiltins }: { includeBuiltins?: boolean }) => { + const result = this.brain.getReplState({ includeBuiltins: includeBuiltins ?? false }) return { content: [{ type: 'text', text: JSON.stringify(result) }], }