"use strict";
// =============================================================================
// Pure Agent - Tool Registry
// Ported from Hermes tools/registry.py (simplified, no AST discovery)
// =============================================================================
Object.defineProperty(exports, "__esModule", { value: true });
exports.registry = exports.PureToolRegistry = void 0;
exports.discoverTools = discoverTools;
exports.discoverToolsAsync = discoverToolsAsync;
const logger_1 = require("./logger");
const result_types_1 = require("./result-types");
// ---------------------------------------------------------------------------
// PureToolRegistry
// ---------------------------------------------------------------------------
class PureToolRegistry {
    _tools = new Map();
    _toolsetChecks = new Map();
    _toolsetAliases = new Map();
    _generation = 0;
    // -------------------------------------------------------------------------
    // Registration
    // -------------------------------------------------------------------------
    register(entry) {
        if (this._tools.has(entry.name)) {
            (0, logger_1.getLogger)().warn(`Tool '${entry.name}' is being re-registered (overwriting)`);
        }
        this._tools.set(entry.name, entry);
        this._generation++;
        (0, logger_1.getLogger)().debug(`Registered tool: ${entry.emoji} ${entry.name} [${entry.toolset}]`);
    }
    deregister(name) {
        if (this._tools.has(name)) {
            this._tools.delete(name);
            this._generation++;
            (0, logger_1.getLogger)().debug(`Deregistered tool: ${name}`);
        }
    }
    // -------------------------------------------------------------------------
    // Toolset management
    // -------------------------------------------------------------------------
    registerToolsetCheck(toolset, checkFn) {
        this._toolsetChecks.set(toolset, checkFn);
    }
    registerToolsetAlias(alias, target) {
        this._toolsetAliases.set(alias, target);
    }
    resolveToolsetAlias(name) {
        return this._toolsetAliases.get(name) || name;
    }
    isToolsetAvailable(toolset) {
        const resolved = this.resolveToolsetAlias(toolset);
        const check = this._toolsetChecks.get(resolved);
        if (!check)
            return true; // No check registered = always available
        return check();
    }
    // -------------------------------------------------------------------------
    // Query
    // -------------------------------------------------------------------------
    getEntry(name) {
        return this._tools.get(name);
    }
    getAllToolNames() {
        return Array.from(this._tools.keys());
    }
    getToolToToolsetMap() {
        const map = new Map();
        for (const [name, entry] of this._tools) {
            map.set(name, entry.toolset);
        }
        return map;
    }
    get generation() {
        return this._generation;
    }
    // -------------------------------------------------------------------------
    // Get OpenAI-format tool definitions
    // -------------------------------------------------------------------------
    getDefinitions(toolNames) {
        const defs = [];
        for (const [name, entry] of this._tools) {
            // Filter by requested tool names
            if (toolNames && !toolNames.has(name))
                continue;
            // Check toolset availability
            if (!this.isToolsetAvailable(entry.toolset))
                continue;
            // Apply check function (if tool is conditionally available)
            if (entry.checkFn && !entry.checkFn())
                continue;
            // Build the definition
            const schema = { ...entry.schema };
            if (!schema.description)
                schema.description = entry.description;
            defs.push({
                type: 'function',
                function: {
                    name: entry.name,
                    description: schema.description || entry.description,
                    parameters: schema.parameters || { type: 'object', properties: {} },
                },
            });
        }
        return defs;
    }
    // -------------------------------------------------------------------------
    // Dispatch tool call
    // -------------------------------------------------------------------------
    async dispatch(name, args, context) {
        const entry = this._tools.get(name);
        if (!entry) {
            return (0, result_types_1.toolError)(`Unknown tool: ${name}`);
        }
        // Check toolset availability
        if (!this.isToolsetAvailable(entry.toolset)) {
            return (0, result_types_1.toolError)(`Tool '${name}' is not available (toolset '${entry.toolset}' unavailable)`);
        }
        // Apply check function
        if (entry.checkFn && !entry.checkFn()) {
            return (0, result_types_1.toolError)(`Tool '${name}' check function returned false`);
        }
        try {
            const startTime = Date.now();
            // Call the handler
            let result;
            if (entry.isAsync) {
                result = await entry.handler(args, context);
            }
            else {
                const maybeResult = entry.handler(args, context);
                result = maybeResult instanceof Promise ? await maybeResult : maybeResult;
            }
            const duration = Date.now() - startTime;
            (0, logger_1.getLogger)().debug(`Tool '${name}' completed in ${duration}ms`);
            // Enforce max result size
            if (entry.maxResultSizeChars && result.length > entry.maxResultSizeChars) {
                const truncated = result.slice(0, entry.maxResultSizeChars);
                result = truncated + `\n\n... [truncated at ${entry.maxResultSizeChars} chars]`;
            }
            return result;
        }
        catch (err) {
            const errorMsg = err?.message || String(err);
            (0, logger_1.getLogger)().error(`Tool '${name}' error: ${errorMsg}`);
            return (0, result_types_1.toolError)(`Tool execution failed: ${errorMsg}`);
        }
    }
    // -------------------------------------------------------------------------
    // Get available toolsets
    // -------------------------------------------------------------------------
    getAvailableToolsets() {
        const toolsets = new Set();
        for (const [, entry] of this._tools) {
            if (this.isToolsetAvailable(entry.toolset)) {
                toolsets.add(entry.toolset);
            }
        }
        return Array.from(toolsets);
    }
    getToolsetForTool(name) {
        return this._tools.get(name)?.toolset;
    }
    // -------------------------------------------------------------------------
    // Snapshot (for cache-busting awareness)
    // -------------------------------------------------------------------------
    getSnapshot() {
        return {
            generation: this._generation,
            toolNames: this.getAllToolNames(),
        };
    }
}
exports.PureToolRegistry = PureToolRegistry;
// ---------------------------------------------------------------------------
// Singleton registry
// ---------------------------------------------------------------------------
exports.registry = new PureToolRegistry();
// ---------------------------------------------------------------------------
// Discovery: import all tool modules to trigger self-registration
// ---------------------------------------------------------------------------
function discoverTools() {
    // Import tool modules - each module calls registry.register() at module level
    require('./tools/terminal');
    require('./tools/file-tools');
    require('./tools/browser');
    require('./tools/vision');
    require('./tools/access-file');
    require('./tools/audio-analyze');
    require('./tools/parse-document');
    require('./tools/multimodal');
    require('./memory-tool');
    require('./skills-tool');
    require('./web-tools');
    require('./todo-tool');
    require('./code-execution');
    require('./delegate-tool');
    require('./mcp-tool');
    require('./tools/mcp-resources');
    require('./cron-tool');
    require('./tools/session-search');
    require('./tools/clarify');
    require('./tools/checkpoint');
    (0, logger_1.getLogger)().info(`Discovered ${exports.registry.getAllToolNames().length} tools`);
}
async function discoverToolsAsync() {
    discoverTools();
    // MCP tools need async initialization (connecting to servers)
    try {
        const { initMCPTools } = require('./mcp-tool');
        await initMCPTools();
    }
    catch (err) {
        (0, logger_1.getLogger)().warn(`MCP async init failed: ${err.message}`);
    }
    (0, logger_1.getLogger)().info(`Total tools after async init: ${exports.registry.getAllToolNames().length}`);
}
//# sourceMappingURL=tool-registry.js.map