/**
 * Pure conversion functions: owned AI Context → Shortcut backend proxy format.
 *
 * These are the types and functions that define the request contract between
 * the TS agent and the Python backend's /api/llm/* endpoints.
 *
 * Important boundary rule: this module is model-agnostic. It emits canonical
 * image/document blocks (`{ type, data, mime_type }`) and never Anthropic,
 * Gemini, or OpenAI provider payloads. Provider-family normalization lives in
 * the Python backend proxy.
 * Zero I/O — fully testable with no mocking.
 */
function imageToBackendBlock(block) {
    return {
        data: block.data,
        mime_type: block.mimeType,
        type: 'image'
    };
}
function documentToBackendBlock(block) {
    return {
        data: block.data,
        ...(block.filename ? { filename: block.filename } : {}),
        mime_type: block.mimeType,
        type: 'document'
    };
}
function contentToBackendContent(content) {
    if (typeof content === 'string')
        return content;
    const hasMedia = content.some((block) => block.type === 'image' || block.type === 'document');
    if (!hasMedia) {
        return content.map((block) => (block.type === 'text' ? block.text : '')).join('');
    }
    return content
        .filter((block) => block.type === 'text' || block.type === 'image' || block.type === 'document')
        .map((block) => {
        if (block.type === 'text')
            return { text: block.text, type: 'text' };
        if (block.type === 'image')
            return imageToBackendBlock(block);
        return documentToBackendBlock(block);
    });
}
function assistantText(content) {
    return content.map((block) => (block.type === 'text' ? block.text : '')).join('');
}
function assistantThinking(content) {
    let thinking;
    let thinkingSignature;
    for (const block of content) {
        if (block.type === 'thinking') {
            thinking = block.thinking;
            thinkingSignature = block.thinkingSignature;
        }
    }
    return { thinking, thinkingSignature };
}
function toolCallsToLc(toolCalls) {
    if (!toolCalls || toolCalls.length === 0)
        return undefined;
    return toolCalls.map((toolCall) => ({
        id: toolCall.id,
        name: toolCall.name,
        arguments: JSON.stringify(toolCall.arguments)
    }));
}
/**
 * Convert a full owned-AI context into the backend proxy message contract.
 *
 * This is intentionally not model-aware. Media is serialized as canonical
 * backend blocks; the backend decides whether those become Anthropic
 * `source`, Gemini `media`/`image_url`, or an unsupported-model error.
 */
export function convertMessages(context) {
    const result = [];
    if (context.systemPrompt) {
        result.push({ role: 'system', content: context.systemPrompt });
    }
    for (const msg of context.messages) {
        if (msg.role === 'user') {
            result.push({ role: 'human', content: contentToBackendContent(msg.content) });
        }
        else if (msg.role === 'assistant') {
            const lcMsg = { role: 'ai', content: assistantText(msg.content) };
            const { thinking, thinkingSignature } = assistantThinking(msg.content);
            const toolCalls = toolCallsToLc(msg.content.filter((c) => c.type === 'toolCall'));
            if (toolCalls)
                lcMsg.tool_calls = toolCalls;
            if (thinking)
                lcMsg.thinking = thinking;
            if (thinkingSignature)
                lcMsg.thinking_signature = thinkingSignature;
            result.push(lcMsg);
        }
        else if (msg.role === 'toolResult') {
            result.push({
                role: 'tool',
                content: contentToBackendContent(msg.content),
                tool_call_id: msg.toolCallId
            });
        }
    }
    return result;
}
/**
 * Convert owned AI Tool[] to LangChain tool format.
 * Returns undefined if no tools (backend omits the field).
 */
export function convertTools(tools) {
    if (!tools || tools.length === 0)
        return undefined;
    return tools.map((t) => ({
        name: t.name,
        description: t.description,
        parameters: t.parameters
    }));
}
//# sourceMappingURL=message-converter.js.map