fix: 修复 Tool Search 缓存失效 — deferred 工具不再动态注入 tools 数组

移除 deferred 工具的 "discover then include" 逻辑,让 tools 数组在整个会话中
保持稳定(只有 core tools + ToolSearch + ExecuteExtraTool),避免每次发现新
工具时 tools JSON 变化导致 prompt cache 失效。

同时强化工具优先级引导:core tools 优先直接调用,ToolSearch/ExecuteExtraTool
仅作为发现和调用 deferred 工具的最后手段。当模型搜索已加载的 core tool 时,
ToolSearch 返回明确的拒绝提示。

Co-Authored-By: glm-5.1[1m] <zai-org@claude-code-best.win>
This commit is contained in:
claude-code-best
2026-05-09 14:56:22 +08:00
parent 8c157f0767
commit c14b7eadd2
7 changed files with 46 additions and 31 deletions

View File

@@ -449,13 +449,14 @@ function isToolResultBlockWithStringContent(
/**
* Regex to extract tool names from ToolSearchTool text output.
* Matches: "Found N deferred tool(s): ToolA, ToolB."
* Matches: "Found N deferred tool(s): ToolA, mcp.server.ToolB."
* Uses multiline + end-of-line anchor so dots inside tool names (e.g. mcp__s__t) don't break parsing.
*/
const DISCOVERED_TOOLS_PATTERN = /Found \d+ deferred tool\(s\): ([^.]+)\./
const DISCOVERED_TOOLS_PATTERN = /^Found \d+ deferred tool\(s\): (.+)\.$/m
/**
* Extract tool names from ToolSearchTool text output.
* Format: "Found N deferred tool(s): ToolA, ToolB. ..."
* Format: "Found N deferred tool(s): ToolA, ToolB.\n..."
*/
function extractToolNamesFromText(text: string): string[] {
const match = DISCOVERED_TOOLS_PATTERN.exec(text)
@@ -501,6 +502,18 @@ export function extractDiscoveredToolNames(messages: Message[]): Set<string> {
continue
}
// Deferred-tools-delta attachments announce tools that the model should
// see as available. Include their addedNames so the filter in claude.ts
// keeps the corresponding tool schemas in the API request.
if (
msg.type === 'attachment' &&
(msg as any).attachment?.type === 'deferred_tools_delta'
) {
const added: string[] = (msg as any).attachment.addedNames ?? []
for (const name of added) discoveredTools.add(name)
continue
}
// Only user messages contain tool_result blocks (responses to tool_use)
if (msg.type !== 'user') continue