"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const zod_1 = require("zod");
const zod_to_json_schema_1 = require("zod-to-json-schema");
const defineTool_1 = require("./defineTool");
const tools_1 = require("./tools");
const visualizations_1 = require("./visualizations");
describe('defineTool', () => {
    it('builds separate agent and MCP runtime views', () => {
        const agentView = tools_1.generateVisualizationToolDefinition.for('agent');
        const mcpView = tools_1.runQueryToolDefinition.for('mcp');
        expect(agentView.name).toBe('generateVisualization');
        expect(mcpView.name).toBe('run_metric_query');
        expect(mcpView.canonicalName).toBe('runQuery');
        expect(mcpView.outputSchema).toBeDefined();
    });
    it('builds spreadable agent views with output schemas', () => {
        const outputSchema = zod_1.z.object({
            result: zod_1.z.string(),
            metadata: zod_1.z.object({ status: zod_1.z.enum(['success', 'error']) }),
        });
        const tool = (0, defineTool_1.defineTool)({
            name: 'sampleAgentTool',
            title: 'Sample agent tool',
            description: 'Sample',
            availability: ['agent'],
            inputSchema: zod_1.z.object({}),
            agent: { outputSchema },
        });
        const agentView = tool.for('agent');
        expect(agentView.outputSchema).toBe(outputSchema);
        expect(agentView.toModelOutput({
            output: {
                result: 'Nope',
                metadata: { status: 'error' },
            },
        })).toEqual({ type: 'error-text', value: 'Nope' });
    });
    it('builds agent validation and keeps MCP input schemas ref-free', () => {
        const sharedSchema = zod_1.z.object({ value: zod_1.z.string() });
        const input = {
            first: { value: 'one' },
            second: { value: 'two' },
        };
        const inputSchema = zod_1.z.object({
            first: sharedSchema,
            second: sharedSchema,
        });
        const tool = (0, defineTool_1.defineTool)({
            name: 'referencedSchemaTool',
            title: 'Referenced schema tool',
            description: 'Sample',
            availability: ['agent', 'mcp'],
            inputSchema,
            mcp: {
                annotations: {
                    readOnlyHint: true,
                    destructiveHint: false,
                    idempotentHint: true,
                },
            },
        });
        const agentInputSchema = tool.for('agent').inputSchema;
        const { jsonSchema, validate } = agentInputSchema;
        expect(jsonSchema).toEqual((0, zod_to_json_schema_1.zodToJsonSchema)(inputSchema, {
            $refStrategy: 'root',
            target: 'jsonSchema7',
        }));
        expect(validate?.(input)).toEqual({
            success: true,
            value: input,
        });
        expect(validate?.({
            first: { value: 1 },
            second: { value: 'two' },
        })).toMatchObject({ success: false });
        const mcpInputSchema = tool.for('mcp').inputSchema;
        expect(mcpInputSchema).not.toBe(inputSchema);
        expect(JSON.stringify((0, zod_to_json_schema_1.zodToJsonSchema)(mcpInputSchema))).not.toContain('"$ref"');
        expect(mcpInputSchema.parse(input)).toEqual(input);
    });
    it('builds MCP result helpers', () => {
        const outputSchema = zod_1.z.object({ count: zod_1.z.number() });
        const tool = (0, defineTool_1.defineTool)({
            name: 'sampleMcpTool',
            title: 'Sample MCP tool',
            description: 'Sample',
            availability: ['mcp'],
            inputSchema: zod_1.z.object({}),
            mcp: {
                annotations: {
                    readOnlyHint: true,
                    destructiveHint: false,
                    idempotentHint: true,
                },
                structuredContentSchema: outputSchema,
            },
        });
        const mcpView = tool.for('mcp');
        expect(mcpView.outputSchema).toBe(outputSchema);
        expect(mcpView.result.text('Done')).toEqual({
            content: [{ type: 'text', text: 'Done' }],
        });
        expect(mcpView.result.error('Bad')).toEqual({
            isError: true,
            content: [{ type: 'text', text: 'Bad' }],
        });
        expect(mcpView.result.structured('Counted', { count: 1 })).toEqual({
            content: [{ type: 'text', text: 'Counted' }],
            structuredContent: { count: 1 },
        });
    });
    it('resolves descriptions with the runtime-specific name', () => {
        const tool = (0, defineTool_1.defineTool)({
            name: 'sampleTool',
            title: 'Sample tool',
            description: (name) => `Call ${name}`,
            availability: ['agent', 'mcp'],
            inputSchema: zod_1.z.object({}),
            mcp: {
                name: 'sample_tool',
                annotations: {
                    readOnlyHint: true,
                    destructiveHint: false,
                    idempotentHint: true,
                },
            },
        });
        expect(tool.for('agent').description).toBe('Call sampleTool');
        expect(tool.for('mcp').description).toBe('Call sample_tool');
    });
    it('rejects inconsistent availability config', () => {
        expect(() => (0, defineTool_1.defineTool)({
            name: 'badMcpTool',
            title: 'Bad MCP tool',
            description: 'Bad',
            availability: ['mcp'],
            inputSchema: zod_1.z.object({}),
        })).toThrow('MCP-available');
        expect(() => (0, defineTool_1.defineTool)({
            name: 'duplicateRuntimeTool',
            title: 'Duplicate runtime tool',
            description: 'Bad',
            availability: ['agent', 'agent'],
            inputSchema: zod_1.z.object({}),
        })).toThrow('duplicate runtimes');
    });
    it('keeps MCP structured output schemas limited to current structured tools', () => {
        const structuredMcpToolNames = tools_1.mcpToolDefinitions
            .map((tool) => tool.for('mcp'))
            .filter((tool) => 'outputSchema' in tool)
            .map((tool) => tool.name)
            .sort();
        expect(structuredMcpToolNames).toEqual([
            'get_query_result',
            'list_skills',
            'read_skill',
            'read_skill_resource',
            'render_chart',
            'route_agent',
            'run_ai_writeback',
            'run_metric_query',
            'run_sql',
        ]);
    });
    it('keeps ToolNameSchema aligned with agent-available definitions', () => {
        expect(new Set(visualizations_1.ToolNameSchema.options)).toEqual(new Set(tools_1.agentToolNames));
    });
});
//# sourceMappingURL=defineTool.test.js.map