From a8c8c533d063a9d16a9c5ce0c495268c7c7f7e66 Mon Sep 17 00:00:00 2001 From: IronRookieCoder Date: Thu, 14 May 2026 15:43:31 +0800 Subject: [PATCH] fix(builtin-tools): handle undefined message_ids in SnipTool.call() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Bug 详情 调用 Snip 工具时,若模型通过 ExecuteExtraTool 传入空 params, SnipTool.call() 中访问 input.message_ids.length 会抛出 `Cannot read properties of undefined (reading 'length')`。 ## 根因 Snip 是延迟工具(非 CORE_TOOLS),需通过 ExecuteExtraTool 间接调用。 ExecuteExtraTool 将 params 直接透传给目标工具,不做 Zod schema 验证。 当 params 为空对象 {} 时,input.message_ids 为 undefined。 ## 修复方案 在 SnipTool.call() 中使用 optional chaining 安全访问 message_ids。 ## 变更要点 - packages/builtin-tools/src/tools/SnipTool/SnipTool.ts: 防御性处理空 message_ids - src/costrict/provider/auth.ts: 删除 unreachable continue(lint 自动修复) - src/services/rawDump/worker.ts: Math.pow → **(lint 自动修复) ## 自测 - 已人工验证 Co-Authored-By: Auto --- packages/builtin-tools/src/tools/SnipTool/SnipTool.ts | 5 +++-- src/costrict/provider/auth.ts | 1 - src/services/rawDump/worker.ts | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/builtin-tools/src/tools/SnipTool/SnipTool.ts b/packages/builtin-tools/src/tools/SnipTool/SnipTool.ts index 39629f2b6..777554bc2 100644 --- a/packages/builtin-tools/src/tools/SnipTool/SnipTool.ts +++ b/packages/builtin-tools/src/tools/SnipTool/SnipTool.ts @@ -82,10 +82,11 @@ Guidelines: // Snip implementation is handled by the query engine's projection system. // The tool call itself records the intent; the query engine intercepts // snip tool results and adjusts its message projection accordingly. + const count = input.message_ids?.length ?? 0 return { data: { - snipped_count: input.message_ids.length, - summary: input.reason ?? `Snipped ${input.message_ids.length} messages`, + snipped_count: count, + summary: input.reason ?? `Snipped ${count} messages`, }, } }, diff --git a/src/costrict/provider/auth.ts b/src/costrict/provider/auth.ts index 9344db0b4..dab380b0a 100644 --- a/src/costrict/provider/auth.ts +++ b/src/costrict/provider/auth.ts @@ -114,7 +114,6 @@ export async function pollLoginToken( throw new Error('Login cancelled') } if (error.message?.includes('Login failed')) throw error - continue } } diff --git a/src/services/rawDump/worker.ts b/src/services/rawDump/worker.ts index 2bf691780..6984f33c8 100644 --- a/src/services/rawDump/worker.ts +++ b/src/services/rawDump/worker.ts @@ -105,7 +105,7 @@ async function postJson( let lastError: Error | undefined for (let attempt = 0; attempt < 3; attempt++) { if (attempt > 0) { - const delay = 5000 * Math.pow(2, attempt - 1) // 5s, 10s + const delay = 5000 * 2 ** (attempt - 1) // 5s, 10s log.debug(`retrying ${endpoint} after ${delay}ms`, { attempt }) await new Promise((r) => setTimeout(r, delay)) }