/**
 * MCP TraceAdapter (D0088 slice 1).
 *
 * MCP runs our own Anthropic/OpenAI tool loop and already persists every
 * tool invocation as `metadata.toolCalls: ToolCallEntry[]`. The mapping is
 * near 1:1 onto the collector's `RawToolCall` shape; provenance is
 * `provider-metadata` (the collector's default), so this adapter just
 * normalizes the `ToolCallEntry[]` and forwards token usage + latency +
 * per-turn LLM timings.
 *
 * @see packages/eval/src/pipeline/compiler/mode-handlers/mcp-tool-provider/tool-call-record.ts
 */
function isRecord(value) {
    return typeof value === "object" && value !== null && !Array.isArray(value);
}
/** Normalize one MCP `ToolCallEntry` into the collector's `RawToolCall`. */
function toRawToolCall(entry) {
    return {
        name: entry.name,
        input: isRecord(entry.input) ? entry.input : {},
        output: entry.output,
        ...(entry.error !== undefined ? { error: entry.error } : {}),
        // D0088 — per-call wall-clock duration and the turn it ran in, so the
        // collector can emit interleaved `tool-call` timeline spans that account
        // for the time spent in MCP tool round-trips between model turns.
        ...(entry.durationMs !== undefined ? { durationMs: entry.durationMs } : {}),
        ...(entry.turnIndex !== undefined ? { turnIndex: entry.turnIndex } : {}),
    };
}
/**
 * Read the provider metadata bag — MCP attaches it at `response.metadata`,
 * but some promptfoo paths lift it to the top-level `metadata`. Prefer the
 * response envelope, fall back to top-level.
 */
function metadataOf(native) {
    return native.response?.metadata ?? native.metadata ?? {};
}
function numberArrayOrUndefined(value) {
    return Array.isArray(value) && value.every((n) => typeof n === "number")
        ? value
        : undefined;
}
export const mcpTraceAdapter = {
    mode: "mcp-server",
    toRawTrace(native) {
        const meta = metadataOf(native);
        const entries = Array.isArray(meta.toolCalls)
            ? meta.toolCalls
            : [];
        const llmTimings = numberArrayOrUndefined(meta.llmTimings);
        return {
            ...(native.response?.tokenUsage
                ? { tokenUsage: native.response.tokenUsage }
                : {}),
            ...(native.latencyMs !== undefined
                ? { latencyMs: native.latencyMs }
                : {}),
            metadata: {
                toolCalls: entries.map(toRawToolCall),
                ...(llmTimings ? { llmTimings } : {}),
            },
        };
    },
};
