/**
 * OpenCode stream event handling.
 *
 * Converts OpenCode SDK SSE events into the unified StreamCallback format
 * used throughout the takt codebase.
 */
export function createStreamTrackingState() {
    return {
        textOffsets: new Map(),
        thinkingOffsets: new Map(),
        startedTools: new Set(),
    };
}
// ---- Stream emission helpers ----
export function emitInit(onStream, model, sessionId) {
    if (!onStream)
        return;
    onStream({
        type: 'init',
        data: {
            model,
            sessionId,
        },
    });
}
export function emitText(onStream, text) {
    if (!onStream || !text)
        return;
    onStream({ type: 'text', data: { text } });
}
export function emitThinking(onStream, thinking) {
    if (!onStream || !thinking)
        return;
    onStream({ type: 'thinking', data: { thinking } });
}
export function emitToolUse(onStream, tool, input, id) {
    if (!onStream)
        return;
    onStream({ type: 'tool_use', data: { tool, input, id } });
}
export function emitToolResult(onStream, content, isError) {
    if (!onStream)
        return;
    onStream({ type: 'tool_result', data: { content, isError } });
}
export function emitResult(onStream, success, result, sessionId) {
    if (!onStream)
        return;
    onStream({
        type: 'result',
        data: {
            result,
            sessionId,
            success,
            error: success ? undefined : result || undefined,
        },
    });
}
/** Process a message.part.updated event and emit appropriate stream events */
export function handlePartUpdated(part, delta, onStream, state) {
    if (!onStream)
        return;
    switch (part.type) {
        case 'text': {
            const textPart = part;
            if (delta) {
                emitText(onStream, delta);
            }
            else {
                const prev = state.textOffsets.get(textPart.id) ?? 0;
                if (textPart.text.length > prev) {
                    emitText(onStream, textPart.text.slice(prev));
                    state.textOffsets.set(textPart.id, textPart.text.length);
                }
            }
            break;
        }
        case 'reasoning': {
            const reasoningPart = part;
            if (delta) {
                emitThinking(onStream, delta);
            }
            else {
                const prev = state.thinkingOffsets.get(reasoningPart.id) ?? 0;
                if (reasoningPart.text.length > prev) {
                    emitThinking(onStream, reasoningPart.text.slice(prev));
                    state.thinkingOffsets.set(reasoningPart.id, reasoningPart.text.length);
                }
            }
            break;
        }
        case 'tool': {
            const toolPart = part;
            handleToolPartUpdated(toolPart, onStream, state);
            break;
        }
        default:
            break;
    }
}
function handleToolPartUpdated(toolPart, onStream, state) {
    const toolId = toolPart.callID || toolPart.id;
    if (!state.startedTools.has(toolId)) {
        emitToolUse(onStream, toolPart.tool, toolPart.state.input, toolId);
        state.startedTools.add(toolId);
    }
    switch (toolPart.state.status) {
        case 'completed':
            emitToolResult(onStream, toolPart.state.output, false);
            break;
        case 'error':
            emitToolResult(onStream, toolPart.state.error, true);
            break;
    }
}
//# sourceMappingURL=OpenCodeStreamHandler.js.map