"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.findCompiledWorkflows = findCompiledWorkflows;
exports.evaluateWorkflowMatch = evaluateWorkflowMatch;
exports.extractWorkflowInputs = extractWorkflowInputs;
const llm_1 = require("../../../services/llm");
const defaults_1 = require("../../../modules/defaults");
const logger_1 = require("../../../lib/logger");
const yamlDb = __importStar(require("../../../services/yaml-workflow/db"));
const prompts_1 = require("./prompts");
/**
 * Ranked discovery of compiled YAML workflows via FTS + tag overlap.
 *
 * Callers pass their own module-level caches so each pipeline keeps
 * isolated cache instances.
 */
async function findCompiledWorkflows(prompt, caches, logPrefix = 'shared') {
    const keywords = prompt
        .toLowerCase()
        .replace(/[^a-z0-9\s-]/g, ' ')
        .split(/\s+/)
        .filter((w) => w.length > 2 && !defaults_1.STOP_WORDS.has(w));
    logger_1.loggerRegistry.debug(`[${logPrefix}:findCompiledWorkflows] keywords: [${keywords.join(',')}]`);
    let workflows;
    try {
        workflows = await yamlDb.discoverWorkflows(prompt, keywords, undefined, 5);
        logger_1.loggerRegistry.info(`[${logPrefix}:findCompiledWorkflows] ${workflows.length} candidate(s) found`);
    }
    catch (err) {
        logger_1.loggerRegistry.warn(`[${logPrefix}:findCompiledWorkflows] discovery failed: ${err.message}`);
        return { inventory: '', toolIds: [], candidates: [] };
    }
    if (workflows.length === 0) {
        return { inventory: '', toolIds: [], candidates: [] };
    }
    const toolIds = [];
    const inventoryLines = [];
    const candidates = [];
    for (const wf of workflows) {
        const qualifiedName = `yaml__${wf.name.replace(/[^a-zA-Z0-9]/g, '_')}`;
        caches.yamlWorkflowMap.set(qualifiedName, wf.name);
        caches.toolDefCache.set(qualifiedName, {
            type: 'function',
            function: {
                name: qualifiedName,
                description: `[COMPILED WORKFLOW] ${wf.description || wf.name} — deterministic, no LLM needed. ` +
                    `Tags: ${wf.tags.join(', ')}`,
                parameters: (wf.input_schema || { type: 'object', properties: {} }),
            },
        });
        toolIds.push(qualifiedName);
        const activityCount = wf.activity_manifest.filter((a) => a.type === 'worker').length;
        inventoryLines.push(`★ ${wf.name} [compiled, ${activityCount} steps, tags: ${wf.tags.join(', ')}]: ${wf.description || 'deterministic workflow'}`);
        candidates.push({
            name: wf.name,
            description: wf.description,
            original_prompt: wf.original_prompt,
            category: wf.category,
            tags: wf.tags,
            input_schema: wf.input_schema,
            tool_names: wf.activity_manifest
                .filter((a) => a.type === 'worker' && a.mcp_tool_name)
                .map((a) => a.mcp_tool_name),
            fts_rank: wf.fts_rank || 0,
        });
    }
    return { inventory: inventoryLines.join('\n'), toolIds, candidates };
}
/**
 * LLM-as-judge: does a compiled workflow match the user's intent?
 * One cheap call (secondary model, ~200 tokens) to potentially skip
 * the entire agentic loop.
 */
async function evaluateWorkflowMatch(prompt, candidates, logPrefix = 'shared') {
    logger_1.loggerRegistry.debug(`[${logPrefix}:evaluateWorkflowMatch] ${candidates.length} candidate(s)`);
    if (candidates.length === 0) {
        return { matched: false, workflowName: null, confidence: 0 };
    }
    const candidateText = candidates.map((c, i) => `${i + 1}. **${c.name}** (category: ${c.category || 'general'})\n` +
        `   Description: ${c.description || 'N/A'}\n` +
        `   Original prompt: "${c.original_prompt || 'N/A'}"\n` +
        `   Tools: ${c.tool_names.join(', ')}\n` +
        `   Input: ${JSON.stringify(c.input_schema).slice(0, 300)}`).join('\n\n');
    try {
        const response = await (0, llm_1.callLLM)({
            model: defaults_1.LLM_MODEL_SECONDARY,
            max_tokens: 200,
            temperature: 0,
            messages: [
                { role: 'system', content: prompts_1.WORKFLOW_MATCH_PROMPT },
                { role: 'user', content: `## User Request\n${prompt}\n\n## Candidate Workflows\n${candidateText}` },
            ],
        });
        const raw = response.content || '{}';
        const cleaned = raw.replace(/^```(?:json)?\s*/m, '').replace(/\s*```$/m, '').trim();
        const result = JSON.parse(cleaned);
        if (result.match && result.confidence >= 0.7) {
            logger_1.loggerRegistry.info(`[${logPrefix}:evaluateWorkflowMatch] MATCHED: ${result.workflow_name} (confidence: ${result.confidence})`);
            return { matched: true, workflowName: result.workflow_name, confidence: result.confidence };
        }
        logger_1.loggerRegistry.info(`[${logPrefix}:evaluateWorkflowMatch] no match (confidence: ${result.confidence || 0})`);
        return { matched: false, workflowName: null, confidence: result.confidence || 0 };
    }
    catch (err) {
        logger_1.loggerRegistry.warn(`[${logPrefix}:evaluateWorkflowMatch] error: ${err.message}`);
        return { matched: false, workflowName: null, confidence: 0 };
    }
}
/**
 * Extract structured inputs from the user's prompt using the matched
 * workflow's input_schema. Acts as a second confirmation gate — if the
 * LLM can't map the prompt to the schema, the match is rejected.
 */
async function extractWorkflowInputs(prompt, inputSchema, workflowName) {
    try {
        const response = await (0, llm_1.callLLM)({
            model: defaults_1.LLM_MODEL_SECONDARY,
            max_tokens: 500,
            temperature: 0,
            messages: [
                { role: 'system', content: prompts_1.EXTRACT_INPUTS_PROMPT },
                {
                    role: 'user',
                    content: `## User Request\n${prompt}\n\n` +
                        `## Workflow: ${workflowName}\n` +
                        `## Input Schema\n${JSON.stringify(inputSchema, null, 2)}`,
                },
            ],
        });
        const raw = response.content || '{}';
        const cleaned = raw.replace(/^```(?:json)?\s*/m, '').replace(/\s*```$/m, '').trim();
        const result = JSON.parse(cleaned);
        if (result._extraction_failed) {
            return { inputs: null, extracted: false };
        }
        delete result._extraction_failed;
        return { inputs: result, extracted: true };
    }
    catch {
        return { inputs: null, extracted: false };
    }
}
