/**
 * ============================================================
 *  src/tools/index.ts —— 工具注册表 + 执行入口
 * ------------------------------------------------------------
 *  这里做两件事：
 *    1. 把所有工具集中起来导出一个 ALL_TOOLS 数组（loop.ts 会用）
 *    2. 实现 executeTool(name, rawArgs)：
 *         a. 按 name 查表
 *         b. 用 Zod safeParse 校验 arguments（LLM 给的是 JSON 字符串！）
 *         c. 调用 tool.call()，统一包装错误
 *
 *  这层是"防线"：模型给的参数永远不可信，必须 Zod 校验后才进 call()。
 * ============================================================
 */
import { askUserQuestionTool } from './ask/ask.js';
import { bashTool } from './bash/bash.js';
import { editTool } from './edit/edit.js';
import { multiEditTool } from './edit/multi-edit.js';
import { globTool } from './glob/glob.js';
import { grepTool } from './grep/grep.js';
import { readTool } from './read/read.js';
import { webfetchTool } from './webfetch/webfetch.js';
import { webbrowserTool } from './webbrowser/webbrowser.js';
import { webSearchTool } from './websearch/websearch.js';
import { writeTool } from './write/write.js';
/** 所有内置工具（顺序 = 给 LLM 呈现的顺序，不影响代码执行，但会影响模型的优先级直觉） */
export const ALL_TOOLS = [
    readTool,
    editTool,
    multiEditTool,
    writeTool,
    globTool,
    grepTool,
    webSearchTool,
    webfetchTool,
    webbrowserTool,
    bashTool,
    askUserQuestionTool,
];
/** 按名字查表 */
export function getToolByName(name) {
    return ALL_TOOLS.find((t) => t.name === name);
}
/**
 * 执行一次工具调用。
 *
 * @param name        工具名（来自 LLM 的 tool_call.function.name）
 * @param rawArguments LLM 给的参数 —— 注意这是 JSON 字符串，不是对象
 * @param signal      支持中断
 *
 * 返回 ToolResult：失败时不抛异常，把 error 写在结果里（便于把"工具失败"
 * 当成普通 tool_result 喂回 LLM，让模型自己重试或换思路）。
 */
export async function executeTool(name, rawArguments, signal) {
    // 1. 找工具
    const tool = getToolByName(name);
    if (!tool) {
        const available = ALL_TOOLS.map((t) => t.name).join(', ');
        return { ok: false, error: `未知工具 "${name}"。可用工具：${available}` };
    }
    // 2. 解析 JSON
    let parsedJson;
    try {
        parsedJson = rawArguments.length === 0 ? {} : JSON.parse(rawArguments);
    }
    catch (e) {
        return {
            ok: false,
            error: `工具参数不是合法 JSON：${e.message}\n收到的字符串：${rawArguments.slice(0, 200)}`,
        };
    }
    // 3. Zod 校验
    const checked = tool.inputSchema.safeParse(parsedJson);
    if (!checked.success) {
        const issues = checked.error.issues
            .map((i) => `  - ${i.path.join('.') || '<root>'}: ${i.message}`)
            .join('\n');
        return {
            ok: false,
            error: `参数校验失败（请检查参数名/类型）：\n${issues}`,
        };
    }
    // 4. 调用 call()，捕获意外异常
    try {
        return await tool.call(checked.data, signal);
    }
    catch (e) {
        return {
            ok: false,
            error: `工具执行抛出异常：${e.message}`,
        };
    }
}
// 导出每个工具，方便测试单独 import
export { readTool, editTool, writeTool, globTool, grepTool, webSearchTool, webfetchTool, webbrowserTool, bashTool, askUserQuestionTool };
export { multiEditTool } from './edit/multi-edit.js';
