From 729dee2c1168aaf0751f548e4cafde118843cc54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D0=BE=D1=80=D0=BE=D0=B4=D0=B8=D0=BD=20=D0=A0=D0=BE?= =?UTF-8?q?=D0=BC=D0=B0=D0=BD?= Date: Sat, 26 Sep 2026 11:46:44 +0300 Subject: [PATCH] feat: parse CodeMode execute tool calls from JS script MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Парсим JS код из аргумента execute инструмента и извлекаем вызовы tools..(...) — как это делает CodeMode. Дочерние инструменты показываются в спойлере вместе с обычными. --- index.ts | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/index.ts b/index.ts index 9d11179..66c8143 100644 --- a/index.ts +++ b/index.ts @@ -131,6 +131,26 @@ async function runPlugin(ctx: any, options: any, dataDir: string) { const sessionsBySessionID = new Map() + // ============================================================================= + // Parse tool calls from CodeMode JS script + // CodeMode creates nested tools: tools..(...) + // e.g. tools.duckduckgo.search({ query: "..." }) + // ============================================================================= + + function parseCodeModeTools(code: string): string[] { + const tools: string[] = [] + // Match tools..( — nested tool calls in CodeMode + const regex = /tools\.(\w+)\.(\w+)\s*\(/g + let match + while ((match = regex.exec(code)) !== null) { + const toolName = `${match[1]}_${match[2]}` + if (!tools.includes(toolName)) { + tools.push(toolName) + } + } + return tools + } + // ============================================================================= // Event subscription — collects step data and sends messages per step // ============================================================================= @@ -208,6 +228,20 @@ async function runPlugin(ctx: any, options: any, dataDir: string) { const tool = step.tools.find(t => t.toolID === toolID) if (tool) tool.args = args } + // Parse CodeMode execute tool — extract child tool calls from JS code + if (toolID && step && args) { + let parsedArgs: any + try { parsedArgs = JSON.parse(args) } catch { continue } + const code = parsedArgs?.code || "" + if (code) { + const childTools = parseCodeModeTools(code) + for (const name of childTools) { + if (!step.tools.find(t => t.name === name)) { + step.tools.push({ toolID: `${toolID}/${name}`, name, args: "", result: "", failed: false }) + } + } + } + } continue }