UNPKG

@nanocollective/nanocoder

Version:

A local-first CLI coding agent that brings the power of agentic coding tools like Claude Code and Gemini CLI to local models or controlled APIs like OpenRouter

240 lines 7.58 kB
/** * Helper class to encapsulate tool registry management * * This class provides structured access to tool metadata and eliminates * the need to manage multiple separate registries manually. * * Benefits: * - Single source of truth for all tool metadata * - Type-safe access to tool components * - Cleaner API for tool registration and lookup * - Easier to extend with future metadata */ export class ToolRegistry { tools = new Map(); /** * Register a complete tool entry * @param entry - The ToolEntry containing all tool metadata */ register(entry) { this.tools.set(entry.name, entry); } /** * Register multiple tool entries at once * @param entries - Array of ToolEntry objects */ registerMany(entries) { for (const entry of entries) { this.register(entry); } } /** * Unregister a tool by name * @param name - The tool name */ unregister(name) { this.tools.delete(name); } /** * Unregister multiple tools by name * @param names - Array of tool names */ unregisterMany(names) { for (const name of names) { this.unregister(name); } } /** * Get a complete tool entry by name * @param name - The tool name * @returns The ToolEntry or undefined if not found */ getEntry(name) { return this.tools.get(name); } /** * Get a tool handler by name * @param name - The tool name * @returns The ToolHandler or undefined if not found */ getHandler(name) { return this.tools.get(name)?.handler; } /** * Get a tool formatter by name * @param name - The tool name * @returns The ToolFormatter or undefined if not found */ getFormatter(name) { return this.tools.get(name)?.formatter; } /** * Get a tool validator by name * @param name - The tool name * @returns The ToolValidator or undefined if not found */ getValidator(name) { return this.tools.get(name)?.validator; } /** * Get a streaming formatter by name * @param name - The tool name * @returns The StreamingFormatter or undefined if not found */ getStreamingFormatter(name) { return this.tools.get(name)?.streamingFormatter; } /** * Get the native AI SDK tool by name * @param name - The tool name * @returns The AISDKCoreTool or undefined if not found */ getTool(name) { return this.tools.get(name)?.tool; } /** * Get all handler entries as a record (compatible with old API) * @returns Record mapping tool names to handlers */ getHandlers() { const handlers = {}; for (const [name, entry] of this.tools) { handlers[name] = entry.handler; } return handlers; } /** * Get all formatter entries as a record (compatible with old API) * @returns Record mapping tool names to formatters */ getFormatters() { const formatters = {}; for (const [name, entry] of this.tools) { if (entry.formatter) { formatters[name] = entry.formatter; } } return formatters; } /** * Get all validator entries as a record (compatible with old API) * @returns Record mapping tool names to validators */ getValidators() { const validators = {}; for (const [name, entry] of this.tools) { if (entry.validator) { validators[name] = entry.validator; } } return validators; } /** * Get all native AI SDK tools as a record (compatible with old API) * Tools with validators get their execute functions wrapped so that * validation runs before execution in all code paths, including * AI SDK auto-execution which bypasses external validator checks. * @returns Record mapping tool names to AISDKCoreTool objects */ getNativeTools() { const nativeTools = {}; for (const [name, entry] of this.tools) { if (entry.validator && entry.tool.execute) { const originalExecute = entry.tool.execute; const validator = entry.validator; nativeTools[name] = { ...entry.tool, execute: async (args, options) => { const validationResult = await validator(args); if (!validationResult.valid) { throw new Error(validationResult.error); } return originalExecute.call(entry.tool, args, options); }, }; } else { nativeTools[name] = entry.tool; } } return nativeTools; } /** * Get all native AI SDK tools with execute functions removed. * The SDK still gets schemas and descriptions for the model, * but cannot auto-execute anything — tool calls are returned * for us to handle (parallel execution, confirmation, etc.). * @returns Record mapping tool names to AISDKCoreTool objects without execute */ getNativeToolsWithoutExecute() { const nativeTools = {}; for (const [name, entry] of this.tools) { const { execute: _, ...toolWithoutExecute } = entry.tool; nativeTools[name] = toolWithoutExecute; } return nativeTools; } /** * Get all tool entries * @returns Array of all ToolEntry objects */ getAllEntries() { return Array.from(this.tools.values()); } /** * Get all tool names * @returns Array of all registered tool names */ getToolNames() { return Array.from(this.tools.keys()); } /** * Check if a tool is registered * @param name - The tool name * @returns True if the tool exists, false otherwise */ hasTool(name) { return this.tools.has(name); } /** * Get the number of registered tools * @returns The count of registered tools */ getToolCount() { return this.tools.size; } /** * Clear all registered tools */ clear() { this.tools.clear(); } /** * Create a new registry from static registries (backward compatibility helper) * @param handlers - Record of tool handlers * @param tools - Record of native AI SDK tools * @param formatters - Optional record of tool formatters * @param validators - Optional record of tool validators * @param streamingFormatters - Optional record of streaming formatters * @returns New ToolRegistry instance */ static fromRegistries(handlers, tools, formatters, validators, streamingFormatters, readOnlyFlags) { const registry = new ToolRegistry(); for (const [name, handler] of Object.entries(handlers)) { const tool = tools[name]; if (tool) { registry.register({ name, handler, tool, formatter: formatters?.[name], validator: validators?.[name], streamingFormatter: streamingFormatters?.[name], readOnly: readOnlyFlags?.[name], }); } } return registry; } } //# sourceMappingURL=tool-registry.js.map