/**
 * Tool wrappers for extension event interception.
 *
 * Wraps ToolDefinitions with tool_call / tool_result event hooks so
 * extensions can block or modify tool execution.
 */
/**
 * Wrap a tool with extension callbacks for interception.
 * - Emits tool_call event before execution (can block)
 * - Emits tool_result event after execution (can modify result)
 */
export function wrapToolWithExtensions(tool, runner) {
    return {
        ...tool,
        execute: async (toolCallId, params, signal, onUpdate, ctx) => {
            // Emit tool_call event - extensions can block execution
            if (runner.hasHandlers('tool_call')) {
                try {
                    const callResult = (await runner.emitToolCall({
                        type: 'tool_call',
                        toolName: tool.name,
                        toolCallId,
                        input: params
                    }));
                    if (callResult?.block) {
                        const reason = callResult.reason || 'Tool execution was blocked by an extension';
                        throw new Error(reason);
                    }
                }
                catch (err) {
                    if (err instanceof Error) {
                        throw err;
                    }
                    throw new Error(`Extension failed, blocking execution: ${String(err)}`);
                }
            }
            // Execute the actual tool
            try {
                const result = await tool.execute(toolCallId, params, signal, onUpdate, ctx);
                // Emit tool_result event - extensions can modify the result
                if (runner.hasHandlers('tool_result')) {
                    const resultResult = await runner.emitToolResult({
                        type: 'tool_result',
                        toolName: tool.name,
                        toolCallId,
                        input: params,
                        content: result.content,
                        details: result.details,
                        isError: false
                    });
                    if (resultResult) {
                        return {
                            content: resultResult.content ?? result.content,
                            details: (resultResult.details ?? result.details)
                        };
                    }
                }
                return result;
            }
            catch (err) {
                // Emit tool_result event for errors
                if (runner.hasHandlers('tool_result')) {
                    await runner.emitToolResult({
                        type: 'tool_result',
                        toolName: tool.name,
                        toolCallId,
                        input: params,
                        content: [{ type: 'text', text: err instanceof Error ? err.message : String(err) }],
                        details: undefined,
                        isError: true
                    });
                }
                throw err;
            }
        }
    };
}
/**
 * Wrap all tools with extension callbacks.
 */
export function wrapToolsWithExtensions(tools, runner) {
    return tools.map((tool) => wrapToolWithExtensions(tool, runner));
}
//# sourceMappingURL=wrapper.js.map