docs: 添加 ToolSearch 设计指南 + 禁用 turn-zero 工具推荐弹窗

- 新增 docs/design/tool-search-design-guide.md,涵盖架构、搜索算法、执行管道、演进历史
- 禁用 getTurnZeroSearchExtraToolsPrefetch,消除用户输入时的频繁弹窗
- inter-turn 发现机制保持不变

Co-Authored-By: glm-5-turbo <zai-org@claude-code-best.win>
This commit is contained in:
claude-code-best
2026-05-09 16:45:56 +08:00
parent bd2253846f
commit 2cf18c4c49
61 changed files with 753 additions and 423 deletions

View File

@@ -19,7 +19,7 @@ import {
FILE_READ_TOOL_NAME,
FILE_UNCHANGED_STUB,
} from '@claude-code-best/builtin-tools/tools/FileReadTool/prompt.js'
import { ToolSearchTool } from '@claude-code-best/builtin-tools/tools/ToolSearchTool/ToolSearchTool.js'
import { SearchExtraToolsTool } from '@claude-code-best/builtin-tools/tools/SearchExtraToolsTool/SearchExtraToolsTool.js'
import type { AgentId } from '../../types/ids.js'
import type {
AssistantMessage,
@@ -92,8 +92,8 @@ import {
} from '../../utils/tokens.js'
import {
extractDiscoveredToolNames,
isToolSearchEnabled,
} from '../../utils/toolSearch.js'
isSearchExtraToolsEnabled,
} from '../../utils/searchExtraTools.js'
import { getFeatureValue_CACHED_MAY_BE_STALE } from '../analytics/growthbook.js'
import {
type AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
@@ -1296,7 +1296,7 @@ async function streamCompactSummary({
// Check if tool search is enabled using the main loop's tools list.
// context.options.tools includes MCP tools merged via useMergedTools.
const useToolSearch = await isToolSearchEnabled(
const useSearchExtraTools = await isSearchExtraToolsEnabled(
context.options.mainLoopModel,
context.options.tools,
async () => appState.toolPermissionContext,
@@ -1304,19 +1304,19 @@ async function streamCompactSummary({
'compact',
)
// When tool search is enabled, include ToolSearchTool and MCP tools. They get
// When tool search is enabled, include SearchExtraToolsTool and MCP tools. They get
// defer_loading: true and don't count against context - the API filters them out
// of system_prompt_tools before token counting (see api/token_count_api/counting.py:188
// and api/public_api/messages/handler.py:324).
// Filter MCP tools from context.options.tools (not appState.mcp.tools) so we
// get the permission-filtered set from useMergedTools — same source used for
// isToolSearchEnabled above and normalizeMessagesForAPI below.
// isSearchExtraToolsEnabled above and normalizeMessagesForAPI below.
// Deduplicate by name to avoid API errors when MCP tools share names with built-in tools.
const tools: Tool[] = useToolSearch
const tools: Tool[] = useSearchExtraTools
? uniqBy(
[
FileReadTool,
ToolSearchTool,
SearchExtraToolsTool,
...context.options.tools.filter(t => t.isMcp),
],
'name',

View File

@@ -17,7 +17,7 @@ import { getSessionMemoryPath } from '../../utils/permissions/filesystem.js'
import { processSessionStartHooks } from '../../utils/sessionStart.js'
import { getTranscriptPath } from '../../utils/sessionStorage.js'
import { tokenCountFromLastAPIResponse } from '../../utils/tokens.js'
import { extractDiscoveredToolNames } from '../../utils/toolSearch.js'
import { extractDiscoveredToolNames } from '../../utils/searchExtraTools.js'
import {
getDynamicConfig_BLOCKS_ON_INIT,
getFeatureValue_CACHED_MAY_BE_STALE,