function isRecord(value) {
    return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
}
function ensureRecord(parent, key) {
    const existing = parent[key];
    if (isRecord(existing)) {
        return existing;
    }
    const next = {};
    parent[key] = next;
    return next;
}
function pickString(...candidates) {
    for (const c of candidates) {
        if (typeof c === 'string' && c.trim().length) {
            return c.trim();
        }
    }
    return undefined;
}
function normalizeResponsesInputItem(item) {
    const type = typeof item.type === 'string' ? item.type : '';
    if (type === 'function_call') {
        const id = pickString(item.id);
        const callId = pickString(item.call_id);
        if (callId && !id) {
            item.id = callId;
        }
        else if (id && !callId) {
            item.call_id = id;
        }
        return;
    }
    if (type === 'function_call_output' || type === 'tool_result' || type === 'tool_message') {
        const id = pickString(item.id);
        const callId = pickString(item.call_id);
        const toolCallId = pickString(item.tool_call_id);
        const resolvedCall = pickString(callId, toolCallId);
        if (resolvedCall && !callId) {
            item.call_id = resolvedCall;
        }
        if (id && !callId && !toolCallId) {
            // Some upstreams only provide an id for tool output items; mirror it to both fields.
            item.call_id = id;
            item.tool_call_id = id;
        }
    }
}
function normalizeResponsesOutputItem(item) {
    const type = typeof item.type === 'string' ? item.type : '';
    if (type === 'function_call') {
        const id = pickString(item.id, item.item_id);
        const callId = pickString(item.call_id);
        if (callId && !id) {
            item.id = callId;
        }
        else if (id && !callId) {
            item.call_id = id;
        }
    }
}
function normalizeToolOutputsArray(toolOutputs) {
    if (!Array.isArray(toolOutputs))
        return;
    for (const entry of toolOutputs) {
        if (!isRecord(entry))
            continue;
        const toolCallId = pickString(entry.tool_call_id);
        const callId = pickString(entry.call_id);
        const resolved = pickString(toolCallId, callId, entry.id);
        if (resolved) {
            entry.tool_call_id = resolved;
            entry.call_id = resolved;
        }
    }
}
function normalizeChatMessages(messages) {
    if (!Array.isArray(messages))
        return;
    for (const msg of messages) {
        if (!isRecord(msg))
            continue;
        // chat tool message uses tool_call_id; mirror to call_id for downstream consumers that only look at call_id.
        const toolCallId = pickString(msg.tool_call_id);
        const callId = pickString(msg.call_id);
        const resolved = pickString(toolCallId, callId);
        if (resolved) {
            msg.tool_call_id = resolved;
            msg.call_id = resolved;
        }
        const toolCalls = msg.tool_calls;
        if (Array.isArray(toolCalls)) {
            for (const call of toolCalls) {
                if (!isRecord(call))
                    continue;
                const id = pickString(call.id);
                const callId2 = pickString(call.call_id);
                if (id && !callId2) {
                    call.call_id = id;
                }
                else if (callId2 && !id) {
                    call.id = callId2;
                }
            }
        }
    }
}
/**
 * Normalize tool-call identifiers across OpenAI-compatible payload variants.
 *
 * Goal: field-level normalization only (no rewriting/rehashing IDs):
 * - Mirror `call_id` ↔ `tool_call_id` when one side is missing.
 * - For Responses `input` / `output` function_call items, ensure `id` and `call_id` are aligned.
 *
 * This is intended to live in compatibility profiles (per-provider), not in host/provider code.
 */
export function normalizeToolCallIdsInPlace(root) {
    const record = root;
    // Responses request
    if (Array.isArray(record.input)) {
        for (const item of record.input) {
            if (isRecord(item)) {
                normalizeResponsesInputItem(item);
            }
        }
    }
    // Responses submit_tool_outputs request (common alias)
    normalizeToolOutputsArray(record.tool_outputs);
    normalizeToolOutputsArray(record.toolOutputs);
    // Responses response
    if (Array.isArray(record.output)) {
        for (const item of record.output) {
            if (isRecord(item)) {
                normalizeResponsesOutputItem(item);
            }
        }
    }
    // Chat request/response
    normalizeChatMessages(record.messages);
}
