var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
import { randomUUID } from "crypto";
function createAgentEventStream(res, options = {}) {
    let isStreamClosed = false;
    let activeBlock = null;
    const isAiUiMessageStream = options.vercelAiUiMessageStream === true;
    res.writeHead(200, Object.assign({ "Content-Type": "text/event-stream", "Cache-Control": "no-cache", "Connection": "keep-alive" }, (options.vercelAiUiMessageStream
        ? { "x-vercel-ai-ui-message-stream": "v1" }
        : {})));
    const stream = {
        send(obj) {
            if (isStreamClosed || res.writableEnded || res.destroyed) {
                return;
            }
            res.write(`data: ${JSON.stringify(obj)}\n\n`);
        },
        endActiveBlock() {
            if (!activeBlock) {
                return;
            }
            stream.send({
                type: `${activeBlock.type}-end`,
                id: activeBlock.id,
            });
            activeBlock = null;
        },
        startBlock(type) {
            if ((activeBlock === null || activeBlock === void 0 ? void 0 : activeBlock.type) === type) {
                return activeBlock.id;
            }
            stream.endActiveBlock();
            const id = randomUUID();
            activeBlock = { type, id };
            stream.send({
                type: `${type}-start`,
                id,
            });
            return id;
        },
        start(messageId) {
            stream.send({
                type: "start",
                messageId,
            });
        },
        textDelta(delta) {
            const textId = stream.startBlock("text");
            stream.send({
                type: "text-delta",
                id: textId,
                delta,
            });
        },
        reasoningDelta(delta) {
            const reasoningId = stream.startBlock("reasoning");
            stream.send({
                type: "reasoning-delta",
                id: reasoningId,
                delta,
            });
        },
        toolCall(event) {
            if (options.closeActiveBlockOnToolStart && event.phase === "start") {
                stream.endActiveBlock();
            }
            stream.send({
                type: "data-tool-call",
                data: event,
            });
        },
        rendering(phase, label) {
            if (phase === "start") {
                stream.endActiveBlock();
            }
            stream.send({
                type: "data-rendering",
                data: {
                    phase,
                    label,
                },
            });
        },
        openPage(targetPath) {
            stream.send({
                type: isAiUiMessageStream ? "data-open-page" : "open-page",
                data: {
                    targetPath,
                },
            });
        },
        transcript(text, language) {
            stream.send({
                type: isAiUiMessageStream ? "data-transcript" : "transcript",
                data: {
                    text,
                    language,
                },
            });
        },
        response(text, sessionId, turnId) {
            stream.send({
                type: isAiUiMessageStream ? "data-response" : "response",
                data: {
                    text,
                    sessionId,
                    turnId,
                },
            });
        },
        speechResponse(transcript, response, sessionId, turnId) {
            stream.send({
                type: isAiUiMessageStream ? "data-speech-response" : "speech-response",
                data: {
                    transcript,
                    response,
                    sessionId,
                    turnId,
                },
            });
        },
        audioStart(mimeType, format, sampleRate, channelCount, bitsPerSample) {
            stream.send({
                type: isAiUiMessageStream ? "data-audio-start" : "audio-start",
                data: {
                    mimeType,
                    format,
                    sampleRate,
                    channelCount,
                    bitsPerSample,
                },
            });
        },
        audioDelta(value) {
            stream.send({
                type: isAiUiMessageStream ? "data-audio-delta" : "audio-delta",
                data: {
                    base64: Buffer.from(value).toString("base64"),
                },
            });
        },
        audioDone() {
            stream.send(Object.assign({ type: isAiUiMessageStream ? "data-audio-done" : "audio-done" }, (isAiUiMessageStream ? { data: {} } : {})));
        },
        error(error) {
            stream.send(isAiUiMessageStream
                ? {
                    type: "error",
                    errorText: error,
                }
                : {
                    type: "error",
                    error,
                });
        },
        end() {
            if (isStreamClosed || res.writableEnded || res.destroyed) {
                return;
            }
            stream.endActiveBlock();
            stream.send({
                type: "finish",
            });
            res.write("data: [DONE]\n\n");
            isStreamClosed = true;
            res.end();
        },
    };
    return stream;
}
export function createSseEventEmitter(res, options = {}) {
    const stream = createAgentEventStream(res, options);
    return (event) => __awaiter(this, void 0, void 0, function* () {
        switch (event.type) {
            case "turn-started":
                stream.start(event.messageId);
                break;
            case "text-delta":
                stream.textDelta(event.delta);
                break;
            case "reasoning-delta":
                stream.reasoningDelta(event.delta);
                break;
            case "tool-call":
                stream.toolCall(event.data);
                break;
            case "rendering":
                stream.rendering(event.phase, event.label);
                break;
            case "open-page":
                stream.openPage(event.targetPath);
                break;
            case "transcript":
                stream.transcript(event.text, event.language);
                break;
            case "response":
                stream.response(event.text, event.sessionId, event.turnId);
                break;
            case "speech-response":
                stream.speechResponse(event.transcript, event.response, event.sessionId, event.turnId);
                break;
            case "audio-start":
                stream.audioStart(event.mimeType, event.format, event.sampleRate, event.channelCount, event.bitsPerSample);
                break;
            case "audio-delta":
                stream.audioDelta(event.value);
                break;
            case "audio-done":
                stream.audioDone();
                break;
            case "error":
                stream.error(event.error);
                break;
            case "finish":
                stream.end();
                break;
        }
    });
}
