"use strict";
/**
 * Shared utilities for agentic assertion handlers.
 * Resolves task, plan, trace, agentOutput, and definitions from test.vars and output.trusys.
 * Prefers agent_calls over tool_calls and agent_definitions over tool_definitions.
 */
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.toStr = toStr;
exports.planToString = planToString;
exports.flattenAgentCallsToToolCalls = flattenAgentCallsToToolCalls;
exports.getResolvedTrace = getResolvedTrace;
exports.applyTraceFromOutputString = applyTraceFromOutputString;
const logger_1 = __importDefault(require("../../logger"));
function toStr(value) {
    return typeof value === 'string' ? value : JSON.stringify(value ?? '', null, 2);
}
function planToString(plan) {
    return typeof plan === 'string' ? plan : JSON.stringify(plan ?? '', null, 2);
}
/**
 * Flattens nested tool_calls from agent_calls. Each agent call may have a tool_calls array;
 * returns a single array of all those tool calls. If agent_calls is not an array or entries
 * have no tool_calls, returns an empty array or the original array if it looks like direct
 * tool calls.
 */
function flattenAgentCallsToToolCalls(agentCalls) {
    if (!Array.isArray(agentCalls)) {
        return [];
    }
    const result = [];
    for (const entry of agentCalls) {
        if (entry && typeof entry === 'object') {
            const item = entry;
            if (Array.isArray(item.tool_calls)) {
                for (const tool of item.tool_calls) {
                    if (tool != null && typeof tool === 'object') {
                        result.push(tool);
                    }
                }
            }
        }
    }
    return result;
}
/**
 * Resolves task, plan, trace, agentOutput, and definitions from vars (test.vars) and
 * output.trusys. Prefers agent_calls over tool_calls and agent_definitions over tool_definitions.
 * Use the returned fields that your assertion needs; unused ones may be empty or undefined.
 */
function getResolvedTrace(output, vars, prompt) {
    const v = vars ?? {};
    let task = (v.prompt ?? prompt ?? '');
    let plan = planToString(v.plan ?? '');
    let trace = v.agent_calls ?? v.tool_calls;
    let agentOutput = toStr(v.output ?? '');
    let definitions = v.agent_definitions ?? v.tool_definitions;
    if (typeof output === 'object' && output !== null) {
        const parsed = output;
        if (typeof parsed.trusys === 'object' && parsed.trusys !== null) {
            const trusys = parsed.trusys;
            if (typeof trusys.prompt === 'string') {
                task = trusys.prompt;
            }
            if (trusys.plan !== undefined) {
                plan = planToString(trusys.plan);
            }
            if (trusys.agent_calls !== undefined) {
                trace = trusys.agent_calls;
            }
            else if (trusys.tool_calls !== undefined) {
                trace = trusys.tool_calls;
            }
            if (trusys.output !== undefined) {
                agentOutput = toStr(trusys.output);
            }
            if (trusys.agent_definitions !== undefined) {
                definitions = trusys.agent_definitions;
            }
            else if (trusys.tool_definitions !== undefined) {
                definitions = trusys.tool_definitions;
            }
        }
        // Fall back: use the non-trusys portion of the output object as agent output
        if (agentOutput === '' || agentOutput === '""') {
            const { trusys: _t, ...rest } = parsed;
            agentOutput =
                Object.keys(rest).length > 0
                    ? JSON.stringify(rest, null, 2)
                    : toStr(parsed.output ?? parsed);
        }
    }
    else if (typeof output === 'string') {
        if (agentOutput === '' || agentOutput === '""') {
            agentOutput = output;
        }
    }
    return { task, plan, trace, agentOutput, definitions };
}
/**
 * Parses outputString as JSON; if it has a trusys object, merges trusys fields into a copy of
 * testVars (preferring agent_calls over tool_calls, agent_definitions over tool_definitions)
 * and returns the merged vars and the output string to use (trusys stripped or output extracted).
 * Used by Python-based agentic handlers (argumentCorrectness, toolCorrectness, taskCompleteness).
 */
function applyTraceFromOutputString(outputString, testVars) {
    const vars = { ...testVars };
    let resultOutputString = outputString;
    try {
        const parsed = JSON.parse(outputString);
        if (parsed && typeof parsed.trusys === 'object') {
            const trusys = parsed.trusys;
            if (trusys.prompt !== undefined) {
                vars.prompt = trusys.prompt;
            }
            if (trusys.plan !== undefined) {
                vars.plan = trusys.plan;
            }
            if (trusys.agent_calls !== undefined) {
                vars.tool_calls = flattenAgentCallsToToolCalls(trusys.agent_calls);
            }
            else if (trusys.tool_calls !== undefined) {
                vars.tool_calls = trusys.tool_calls;
            }
            if (trusys.output !== undefined) {
                vars.output = trusys.output;
            }
            if (trusys.agent_definitions !== undefined) {
                vars.agent_definitions = trusys.agent_definitions;
                vars.tool_definitions = trusys.agent_definitions;
            }
            else if (trusys.tool_definitions !== undefined) {
                vars.tool_definitions = trusys.tool_definitions;
                vars.agent_definitions = trusys.tool_definitions;
            }
            const hasCalls = trusys.agent_calls !== undefined || trusys.tool_calls !== undefined;
            if (hasCalls) {
                if (parsed.output !== undefined) {
                    resultOutputString =
                        typeof parsed.output === 'string' ? parsed.output : JSON.stringify(parsed.output);
                }
                else {
                    const { trusys: _t, ...rest } = parsed;
                    resultOutputString = JSON.stringify(rest);
                }
            }
            logger_1.default.info(`vars after applying trace: ${JSON.stringify(vars, null, 2)}`);
        }
    }
    catch {
        // ignore parse errors
    }
    return { vars, outputString: resultOutputString };
}
//# sourceMappingURL=util.js.map