claude-code-best/packages/builtin-tools/src/tools/SearchExtraToolsTool/prompt.ts
IronRookieCoder 14f334b93d fix(search-extra-tools): return input schema in discover mode results
## Bug 详情
SearchExtraTools 的 discover: 查询模式计算了包含 description 和 inputSchema
的文本,但调用 buildSearchResult() 时只传入工具名数组,schema 信息被丢弃。
LLM 在 discover 后无法看到 MCP 等 deferred 工具的参数定义。

## 根因
Output 类型中缺少承载工具详情的字段,buildSearchResult() 和
mapToolResultToToolResultBlockParam() 均未处理 discover 模式的详情渲染。

## 修复方案
- Output 类型新增可选 details 字段(name、description、score、inputSchema)
- buildSearchResult() 接受并透传 details
- discover 分支将 TF-IDF 结果结构化传入输出
- mapToolResultToToolResultBlockParam() 新增 discover 模式渲染路径
- 更新 prompt 中 discover 模式描述,提及 input schema 和执行链

## 变更要点
- SearchExtraToolsTool.ts:4 处改动(Output schema、buildSearchResult、
  discover 分支、渲染逻辑)
- SearchExtraToolsTool.test.ts:更新 1 个测试 + 新增 1 个渲染测试
- prompt.ts:更新 discover 描述

## 自测
- 7 tests / 0 fail(新增 1 个渲染测试,更新 1 个 discover 测试)
- tsc --noEmit 无新增类型错误
- JSONL 日志验证 LLM 可正确解析返回的 schema

Co-Authored-By: CoStrict-DeepSeek-V4-Pro <deepseek-ai@claude-code-best.win>
2026-05-21 16:14:00 +08:00

66 lines
3.3 KiB
TypeScript

import { getFeatureValue_CACHED_MAY_BE_STALE } from 'src/services/analytics/growthbook.js'
import type { Tool } from 'src/Tool.js'
import { CORE_TOOLS } from 'src/constants/tools.js'
export { SEARCH_EXTRA_TOOLS_TOOL_NAME } from './constants.js'
import { SEARCH_EXTRA_TOOLS_TOOL_NAME } from './constants.js'
const PROMPT_HEAD = `Search for deferred tools by name or keyword. LOW PRIORITY — only use this tool when no core tool can accomplish the task. Core tools (Read, Edit, Write, Bash, Glob, Grep, Agent, WebFetch, WebSearch, Skill) are always available and should be used directly. This tool is for discovering additional capabilities like MCP tools, cron scheduling, worktree management, agent teams (TeamCreate, TeamDelete, SendMessage), etc.
`
// Matches isDeferredToolsDeltaEnabled in searchExtraTools.ts (not imported —
// searchExtraTools.ts imports from this file). When enabled: tools announced
// via system-reminder attachments. When disabled: prepended
// <available-deferred-tools> block (pre-gate behavior).
function getToolLocationHint(): string {
const deltaEnabled =
process.env.USER_TYPE === 'ant' ||
getFeatureValue_CACHED_MAY_BE_STALE('tengu_glacier_2xr', false)
return deltaEnabled
? 'Deferred tools appear by name in <system-reminder> messages.'
: 'Deferred tools appear by name in <available-deferred-tools> messages.'
}
const PROMPT_TAIL = ` Returns matching tool names.
IMPORTANT: ExecuteExtraTool is always available in your tool list. After this search returns tool names, you MUST call ExecuteExtraTool with {"tool_name": "<returned_name>", "params": {...}} to invoke the deferred tool. This is the ONLY way to execute deferred tools — do not read source code or analyze whether the tool is callable, just use ExecuteExtraTool directly.
Query forms:
- "select:CronCreate,Snip" — fetch these exact tools by name
- "discover:schedule cron job" — pure discovery, returns tool info (name, description, input schema) without loading. Use when you need to understand a tool's parameters before invoking it, then call ExecuteExtraTool with the discovered tool name and params.
- "notebook jupyter" — keyword search, up to max_results best matches
- "+slack send" — require "slack" in the name, rank by remaining terms`
/**
* Check if a tool should be deferred (requires SearchExtraTools to load).
* A tool is deferred if it is NOT in CORE_TOOLS and does NOT have alwaysLoad: true.
* Core tools are always loaded — never deferred.
* All other tools (non-core built-in + all MCP tools) are deferred
* and must be discovered via SearchExtraToolsTool / ExecuteExtraTool.
*/
export function isDeferredTool(tool: Tool): boolean {
// Explicit opt-out via _meta['anthropic/alwaysLoad']
if (tool.alwaysLoad === true) return false
// Core tools are always loaded — never deferred
if (CORE_TOOLS.has(tool.name)) return false
// Everything else (non-core built-in + all MCP tools) is deferred
return true
}
/**
* Format one deferred-tool line for the <available-deferred-tools> user
* message. Search hints (tool.searchHint) are not rendered — the
* hints A/B (exp_xenhnnmn0smrx4, stopped Mar 21) showed no benefit.
*/
export function formatDeferredToolLine(tool: Tool): string {
return tool.name
}
export function getPrompt(): string {
return PROMPT_HEAD + getToolLocationHint() + PROMPT_TAIL
}