function isRecord(value) {
    return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
}
function stringifyUnknown(value) {
    if (typeof value === 'string')
        return value;
    if (value == null)
        return '';
    try {
        return JSON.stringify(value, null, 2);
    }
    catch {
        return String(value);
    }
}
function textFromContentBlocks(blocks) {
    if (!Array.isArray(blocks))
        return '';
    return blocks
        .map((block) => {
        if (!isRecord(block))
            return '';
        if (typeof block.text === 'string')
            return block.text;
        if (block.type === 'tool_use')
            return `Tool call: ${stringifyUnknown(block.name)}\n${stringifyUnknown(block.input)}`;
        if (block.type === 'tool_result')
            return `Tool result:\n${stringifyUnknown(block.content)}`;
        return '';
    })
        .filter(Boolean)
        .join('\n');
}
function toolName(block) {
    return stringifyUnknown(block.name || block.tool || 'tool');
}
function claudeToolUseContent(block) {
    const name = toolName(block);
    const input = stringifyUnknown(block.input);
    return input ? `Tool call: ${name}\n${input}` : `Tool call: ${name}`;
}
function claudeToolResultContent(block) {
    const content = stringifyUnknown(block.content);
    return content ? `Tool result:\n${content}` : 'Tool result';
}
function claudeBlockItemId(block, fallback) {
    if (typeof block.id === 'string')
        return block.id;
    if (typeof block.tool_use_id === 'string')
        return block.tool_use_id;
    return fallback;
}
function claudeContentBlockEvents(blocks, raw) {
    if (!Array.isArray(blocks))
        return [];
    const events = [];
    for (const [index, block] of blocks.entries()) {
        if (!isRecord(block))
            continue;
        const blockType = typeof block.type === 'string' ? block.type : '';
        if (typeof block.text === 'string' && block.text.trim()) {
            events.push({
                eventType: 'assistant_message',
                role: 'assistant',
                content: block.text,
                itemId: claudeBlockItemId(block, `claude-text-${index}`),
                raw
            });
            continue;
        }
        if (blockType === 'tool_use') {
            events.push({
                eventType: 'tool_use',
                role: 'tool',
                content: claudeToolUseContent(block),
                itemId: claudeBlockItemId(block, `claude-tool-use-${index}`),
                metadata: {
                    ...raw,
                    block,
                    richType: 'claude_tool_use',
                    toolName: toolName(block),
                    toolInput: isRecord(block.input) ? block.input : block.input ?? null
                },
                raw
            });
            continue;
        }
        if (blockType === 'tool_result') {
            const baseId = claudeBlockItemId(block, `claude-tool-result-${index}`);
            events.push({
                eventType: 'tool_result',
                role: 'tool',
                content: claudeToolResultContent(block),
                itemId: `result-${baseId}`,
                metadata: {
                    ...raw,
                    block,
                    richType: 'claude_tool_result',
                    toolResult: block.content ?? null
                },
                raw
            });
        }
    }
    return events;
}
function eventType(raw) {
    if (typeof raw.method === 'string')
        return raw.method;
    if (typeof raw.type === 'string')
        return raw.type;
    return 'codex.event';
}
function normalizedType(raw) {
    return eventType(raw).replace(/\./g, '/');
}
function itemType(item) {
    if (typeof item.type === 'string')
        return item.type;
    if (typeof item.item_type === 'string')
        return item.item_type;
    return 'item';
}
function itemId(raw) {
    if (isRecord(raw.params) && typeof raw.params.itemId === 'string')
        return raw.params.itemId;
    if (isRecord(raw.params) && isRecord(raw.params.item) && typeof raw.params.item.id === 'string')
        return raw.params.item.id;
    if (isRecord(raw.item) && typeof raw.item.id === 'string')
        return raw.item.id;
    return undefined;
}
function threadIdFromRaw(raw) {
    if (typeof raw.thread_id === 'string')
        return raw.thread_id;
    if (typeof raw.threadId === 'string')
        return raw.threadId;
    if (isRecord(raw.params) && isRecord(raw.params.thread) && typeof raw.params.thread.id === 'string') {
        return raw.params.thread.id;
    }
    if (isRecord(raw.params) && isRecord(raw.params.result) && isRecord(raw.params.result.thread) && typeof raw.params.result.thread.id === 'string') {
        return raw.params.result.thread.id;
    }
    if (isRecord(raw.result) && isRecord(raw.result.thread) && typeof raw.result.thread.id === 'string') {
        return raw.result.thread.id;
    }
    return undefined;
}
function itemContent(item) {
    if (typeof item.text === 'string' && item.text.trim())
        return item.text;
    if (typeof item.delta === 'string' && item.delta.trim())
        return item.delta;
    if (typeof item.aggregatedOutput === 'string' && item.aggregatedOutput.trim())
        return item.aggregatedOutput;
    if (typeof item.aggregated_output === 'string' && item.aggregated_output.trim())
        return item.aggregated_output;
    if (typeof item.output === 'string' && item.output.trim())
        return item.output;
    if (Array.isArray(item.content))
        return textFromContentBlocks(item.content);
    return '';
}
function itemTitle(item) {
    const currentItemType = itemType(item);
    if (currentItemType === 'plan')
        return stringifyUnknown(item.text ?? item.content ?? item.plan ?? 'Plan');
    if (currentItemType === 'contextCompaction' || currentItemType === 'compacted')
        return 'Compacting context';
    if (currentItemType === 'enteredReviewMode')
        return `Review started: ${stringifyUnknown(item.review)}`;
    if (currentItemType === 'exitedReviewMode')
        return stringifyUnknown(item.review ?? 'Review completed');
    if (currentItemType === 'mcpToolCall') {
        return `MCP tool: ${stringifyUnknown(item.server)} / ${stringifyUnknown(item.tool)}`;
    }
    if (currentItemType === 'collabToolCall')
        return `Subagent: ${stringifyUnknown(item.tool)}`;
    if (currentItemType === 'webSearch')
        return `Web search: ${stringifyUnknown(item.query)}`;
    if (currentItemType === 'imageView')
        return `Image: ${stringifyUnknown(item.path)}`;
    return stringifyUnknown(item);
}
function commandExecutionContent(item, completed = false) {
    const command = stringifyUnknown(item.command);
    const output = stringifyUnknown(item.aggregatedOutput ?? item.aggregated_output ?? item.output);
    const prefix = `$ ${command}`;
    if (completed && output)
        return `${prefix}\n${output}`;
    return output ? `${prefix}\n${output}` : prefix;
}
export function normalizeCodexEvent(raw) {
    const type = eventType(raw);
    const normalized = normalizedType(raw);
    const events = [{ eventType: type, raw }];
    if (normalized === 'thread/started' || normalized === 'thread/resumed') {
        const threadId = threadIdFromRaw(raw);
        if (threadId)
            events[0].providerSessionId = threadId;
        return events;
    }
    if (normalized === 'error') {
        events.push({
            eventType: 'error',
            role: 'error',
            content: stringifyUnknown(raw.message ?? raw.error ?? raw),
            raw
        });
        return events;
    }
    if (normalized === 'text') {
        const content = stringifyUnknown(raw.text ?? raw.value ?? raw.content);
        if (content)
            events.push({ eventType: 'text', role: 'assistant', content, raw });
        return events;
    }
    if (normalized === 'item/agentMessage/delta') {
        const content = stringifyUnknown(raw.delta ?? (isRecord(raw.params) ? raw.params.delta : undefined) ?? raw.text);
        if (content)
            events.push({ eventType: type, role: 'assistant', content, itemId: itemId(raw), raw });
        return events;
    }
    if (normalized === 'item/plan/delta') {
        const content = stringifyUnknown(raw.delta ?? (isRecord(raw.params) ? raw.params.delta : undefined) ?? raw.text);
        if (content) {
            events.push({
                eventType: type,
                role: 'tool',
                content,
                itemId: itemId(raw),
                metadata: { ...raw, richType: 'codex_plan' },
                raw
            });
        }
        return events;
    }
    if (normalized === 'turn/plan/updated') {
        const params = isRecord(raw.params) ? raw.params : raw;
        const plan = Array.isArray(params.plan)
            ? params.plan
                .map((entry) => (isRecord(entry) && typeof entry.step === 'string' ? `${entry.status ?? 'pending'}: ${entry.step}` : ''))
                .filter(Boolean)
                .join('\n')
            : '';
        events.push({
            eventType: type,
            role: 'tool',
            content: stringifyUnknown(params.explanation ?? plan ?? 'Plan updated'),
            metadata: { ...raw, richType: 'codex_plan_update' },
            raw
        });
        return events;
    }
    if (normalized === 'item/commandExecution/requestApproval' ||
        normalized === 'item/fileChange/requestApproval' ||
        normalized === 'item/permissions/requestApproval' ||
        normalized === 'item/tool/requestUserInput') {
        const params = isRecord(raw.params) ? raw.params : raw;
        events.push({
            eventType: type,
            role: 'tool',
            content: stringifyUnknown(params.reason ?? params.command ?? params),
            itemId: itemId(raw),
            metadata: { ...raw, richType: normalized.endsWith('requestUserInput') ? 'codex_user_input' : 'codex_approval' },
            raw
        });
        return events;
    }
    if (normalized === 'mcpServer/elicitation/request') {
        const params = isRecord(raw.params) ? raw.params : raw;
        events.push({
            eventType: type,
            role: 'tool',
            content: stringifyUnknown(params.message ?? params.request ?? params),
            metadata: { ...raw, richType: 'codex_mcp_elicitation' },
            raw
        });
        return events;
    }
    if (normalized === 'item/started' || normalized === 'item/completed') {
        const item = isRecord(raw.params) && isRecord(raw.params.item) ? raw.params.item : isRecord(raw.item) ? raw.item : null;
        if (!item)
            return events;
        const currentItemType = itemType(item);
        const id = itemId(raw);
        if ((currentItemType === 'agentMessage' || currentItemType === 'agent_message')) {
            const content = itemContent(item);
            if (content) {
                events.push({ eventType: type, role: 'assistant', content, itemId: id, raw });
            }
        }
        else if (currentItemType === 'plan') {
            const content = itemContent(item) || itemTitle(item);
            if (content) {
                events.push({
                    eventType: type,
                    role: 'tool',
                    content,
                    itemId: id,
                    metadata: { ...raw, richType: 'codex_plan', item },
                    raw
                });
            }
        }
        else if (currentItemType === 'commandExecution' || currentItemType === 'command_execution') {
            const content = commandExecutionContent(item, normalized === 'item/completed');
            if (content) {
                events.push({
                    eventType: type,
                    role: 'tool',
                    content,
                    itemId: id,
                    metadata: { ...raw, richType: 'codex_command', item },
                    raw
                });
            }
        }
        else if (currentItemType === 'fileChange' || currentItemType === 'file_change') {
            const content = stringifyUnknown(item);
            if (content) {
                events.push({
                    eventType: type,
                    role: 'tool',
                    content,
                    itemId: id,
                    metadata: { ...raw, richType: 'codex_file_change', item },
                    raw
                });
            }
        }
        else if (currentItemType === 'mcpToolCall' ||
            currentItemType === 'collabToolCall' ||
            currentItemType === 'webSearch' ||
            currentItemType === 'imageView' ||
            currentItemType === 'enteredReviewMode' ||
            currentItemType === 'exitedReviewMode' ||
            currentItemType === 'contextCompaction' ||
            currentItemType === 'compacted') {
            const content = itemTitle(item);
            if (content) {
                events.push({
                    eventType: type,
                    role: 'tool',
                    content,
                    itemId: id,
                    metadata: { ...raw, richType: `codex_${currentItemType}`, item },
                    raw
                });
            }
        }
    }
    return events;
}
export function normalizeClaudeEvent(raw) {
    const type = typeof raw.type === 'string' ? raw.type : 'claude.event';
    const events = [{ eventType: type, raw }];
    if (typeof raw.session_id === 'string') {
        events[0].providerSessionId = raw.session_id;
    }
    if (type === 'assistant' && isRecord(raw.message)) {
        events.push(...claudeContentBlockEvents(raw.message.content, raw));
    }
    else if (type === 'result') {
        const content = stringifyUnknown(raw.result ?? raw.message ?? raw.response);
        if (content)
            events.push({ eventType: 'result', role: 'assistant', content, raw });
    }
    else if (type === 'error') {
        events.push({
            eventType: 'error',
            role: 'error',
            content: stringifyUnknown(raw.message ?? raw.error ?? raw),
            raw
        });
    }
    else if (type.includes('partial')) {
        const content = stringifyUnknown(raw.text ?? raw.delta ?? raw.content);
        if (content)
            events.push({ eventType: type, role: 'assistant', content, raw });
    }
    return events;
}
//# sourceMappingURL=agent-normalizers.js.map