/** * [WHO]: ToolRegistry class, collision detection, namespace-aware registration * [FROM]: Depends on agent-core (AgentTool type) and tool-name.ts * [TO]: Consumed by ToolOrchestrator (replaces internal Map), agent-session (rebuilds tools) * [HERE]: core/tools/tool-registry.ts - unified tool registry with namespace support * * Registry rules: * 1. Internal keys are namespaced (`functions.bash`, `git.status`) while * AgentTool.name remains unchanged for model and extension compatibility. * 2. Collision detection: * - Same namespace + same name + same description → merge (share single tool) * - Same namespace + same name + different description → collision error * - Different namespace → no collision * 3. Strict batch registration validates everything before mutating the registry. * 4. Unqualified tools use the internal `functions` namespace. */ import type { AgentTool } from "@catui/agent-core"; export { BUILTIN_NAMESPACE } from "./tool-name.js"; /** * Result of a registration attempt. */ export interface RegistrationResult { /** Whether registration succeeded. */ ok: boolean; /** If failed, the error message. */ error?: string; /** If merged with existing tool, reference to the merged entry. */ merged?: AgentTool; /** The registered tool (or the existing one if merged). */ tool?: AgentTool; } /** * Collision info for duplicate tool names. */ export interface ToolCollision { /** The canonical name that collided. */ fullName: string; /** First registration source. */ firstSource: string; /** First registration description. */ firstDescription: string; /** Attempted registration source. */ duplicateSource: string; /** Attempted registration description. */ duplicateDescription: string; } /** * Options for ToolRegistry. */ export interface ToolRegistryOptions { /** Whether to throw on collision (default: true in strict mode). */ strictMode?: boolean; /** Default namespace for tools without explicit namespace. */ defaultNamespace?: string; } /** * Central registry for all tools with namespace support and collision detection. * * Design principle: registration should fail before send-model-request, not during. * This prevents models from receiving half-broken toolsets. */ export declare class ToolRegistry { /** Map from canonical full name to registered tool. */ private _tools; /** Whether to throw on collision. */ private _strictMode; /** Default namespace for unnamespaced tools. */ private _defaultNamespace; /** Collisions detected during batch registration. */ private _collisions; constructor(options?: ToolRegistryOptions); /** * Register a single tool. * * @param tool - The tool to register * @param source - Source identifier (e.g., "builtin", "mcp:filesystem", "extension:my-ext") * @param namespace - Optional namespace override (defaults to "functions") * @returns Registration result */ register(tool: AgentTool, source: string, namespace?: string): RegistrationResult; /** * Register multiple tools in batch. * If strict mode is enabled, all registrations succeed or all fail. * * @param tools - Tools to register * @param source - Source identifier * @param namespace - Optional namespace override * @returns Array of registration results */ registerBatch(tools: AgentTool[], source: string, namespace?: string): { results: RegistrationResult[]; collisions: ToolCollision[]; }; /** * Get a tool by its full name. */ get(fullName: string): AgentTool | undefined; /** * Get a tool by namespace and local name. */ getByNamespace(namespace: string, localName: string): AgentTool | undefined; /** * Check if a tool exists. */ has(fullName: string): boolean; /** * Get all registered tools. */ getAll(): AgentTool[]; /** * Get all registered tool names (full canonical names). */ getNames(): string[]; /** * Get tools by namespace. */ getByNamespacePrefix(namespace: string): AgentTool[]; /** * Clear all registered tools. */ clear(): void; /** * Get all collisions detected. */ getCollisions(): ToolCollision[]; /** * Check if there are any collisions. */ hasCollisions(): boolean; /** * Get registry size. */ get size(): number; }