import { randomUUID } from "crypto";
export function createAgentEventStream(res, options = {}) {
    let isStreamClosed = false;
    let activeBlock = null;
    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,
            });
        },
        transcript(text, language) {
            stream.send({
                type: "transcript",
                data: {
                    text,
                    language,
                },
            });
        },
        response(text, sessionId, turnId) {
            stream.send({
                type: "response",
                data: {
                    text,
                    sessionId,
                    turnId,
                },
            });
        },
        speechResponse(transcript, response, sessionId, turnId) {
            stream.send({
                type: "speech-response",
                data: {
                    transcript,
                    response,
                    sessionId,
                    turnId,
                },
            });
        },
        audioStart(mimeType, format, sampleRate, channelCount, bitsPerSample) {
            stream.send({
                type: "audio-start",
                data: {
                    mimeType,
                    format,
                    sampleRate,
                    channelCount,
                    bitsPerSample,
                },
            });
        },
        audioDelta(value) {
            stream.send({
                type: "audio-delta",
                data: {
                    base64: Buffer.from(value).toString("base64"),
                },
            });
        },
        audioDone() {
            stream.send({
                type: "audio-done",
            });
        },
        error(error) {
            stream.send({
                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;
}
