export const BUILTIN_TOOL_NAMES = [ "read", "bash", "edit", "ast_grep", "ast_edit", "ask", "debug", "ida", "eval", "github", "glob", "grep", "find", "lsp", "checkpoint", "rewind", "context_notes", "new_context", "security_scan", "task", "wait", "todo", "web_search", "write", "memory_edit", "retain", "recall", "reflect", "learn", "manage_skill", ] as const; export type BuiltinToolName = (typeof BUILTIN_TOOL_NAMES)[number]; export const HIDDEN_TOOL_NAMES = ["yield", "goal", "think"] as const; export type HiddenToolName = (typeof HIDDEN_TOOL_NAMES)[number]; const LEGACY_BUILTIN_TOOL_NAME_ALIASES: ReadonlyMap = new Map([["search", "grep"]]); const CANONICAL_TOOL_NAMES: Record = Object.fromEntries( [...BUILTIN_TOOL_NAMES, ...HIDDEN_TOOL_NAMES].map(name => [name, true]), ); /** Canonicalize built-in IDs and legacy aliases. Leave plugin names unchanged. */ export function normalizeToolName(name: string): string { const lower = name.toLowerCase(); return LEGACY_BUILTIN_TOOL_NAME_ALIASES.get(lower) ?? (Object.hasOwn(CANONICAL_TOOL_NAMES, lower) ? lower : name); } /** Normalize and deduplicate tool names while preserving first-seen order. */ export function normalizeToolNames(names: Iterable): string[] { const out: string[] = []; const seen = new Set(); for (const name of names) { const normalized = normalizeToolName(name); if (seen.has(normalized)) continue; seen.add(normalized); out.push(normalized); } return out; } /** MCP tool names carry the `mcp___` prefix minted by `createMCPToolName`. */ export function isMCPToolName(name: string): boolean { return name.startsWith("mcp__"); }