"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.consumeOpenAIStream = consumeOpenAIStream;
const tslib_1 = require("tslib");
const applyContentUpdate_1 = require("./applyContentUpdate.js");
const buildFinalMessages_1 = require("./buildFinalMessages.js");
const contentPartsToMessageContent_1 = require("./contentPartsToMessageContent.js");
const getOpenAIMessageItemIdFromOutputItemAdded_1 = require("./getOpenAIMessageItemIdFromOutputItemAdded.js");
const getStreamEndResult_1 = require("./getStreamEndResult.js");
const getStreamEventContentUpdate_1 = require("./getStreamEventContentUpdate.js");
const isMessageOutputItemDoneEvent_1 = require("./isMessageOutputItemDoneEvent.js");
const isStreamEndOrErrorEvent_1 = require("./isStreamEndOrErrorEvent.js");
function waitForNextTask() {
    return new Promise((resolve) => setTimeout(resolve, 0));
}
function shouldYieldAfterUpdate(update) {
    var _a;
    return (update === null || update === void 0 ? void 0 : update.kind) === 'tool_add' && ((_a = update.status) !== null && _a !== void 0 ? _a : 'loading') === 'loading';
}
/** Consumes stream, invokes callbacks. State/setters live in caller. */
async function consumeOpenAIStream(stream, callbacks) {
    var _a, e_1, _b, _c;
    const { baseMessages, getAssistantMessageId, onAssistantMessageIdResolved, onContentUpdate, onNewMessage, onEnd, getIsCancelled, } = callbacks;
    const completedAssistantMessages = [];
    let messageIndex = 0;
    let currentAssistantMessageId = getAssistantMessageId(0);
    let contentParts = [];
    const applyContentToCurrentMessage = (parts) => {
        if (getIsCancelled())
            return;
        onContentUpdate(currentAssistantMessageId, (0, contentPartsToMessageContent_1.contentPartsToMessageContent)(parts));
    };
    try {
        try {
            for (var _d = true, stream_1 = tslib_1.__asyncValues(stream), stream_1_1; stream_1_1 = await stream_1.next(), _a = stream_1_1.done, !_a; _d = true) {
                _c = stream_1_1.value;
                _d = false;
                const event = _c;
                if (getIsCancelled())
                    return;
                const openaiMessageItemId = (0, getOpenAIMessageItemIdFromOutputItemAdded_1.getOpenAIMessageItemIdFromOutputItemAdded)(event);
                if (openaiMessageItemId && openaiMessageItemId !== currentAssistantMessageId) {
                    const previousId = currentAssistantMessageId;
                    currentAssistantMessageId = openaiMessageItemId;
                    if (!getIsCancelled()) {
                        onAssistantMessageIdResolved === null || onAssistantMessageIdResolved === void 0 ? void 0 : onAssistantMessageIdResolved(previousId, openaiMessageItemId);
                    }
                    continue;
                }
                if ((0, isStreamEndOrErrorEvent_1.isStreamEndOrErrorEvent)(event)) {
                    const finalMessages = (0, buildFinalMessages_1.buildFinalMessages)({
                        baseMessages,
                        completedAssistantMessages,
                        currentAssistantMessageId,
                        contentParts,
                    });
                    const endResult = (0, getStreamEndResult_1.getStreamEndResult)(event);
                    if (getIsCancelled())
                        return;
                    onEnd(finalMessages, endResult.status, endResult.status === 'error' ? endResult.error : undefined);
                    return;
                }
                if ((0, isMessageOutputItemDoneEvent_1.isMessageOutputItemDoneEvent)(event)) {
                    completedAssistantMessages.push({
                        id: currentAssistantMessageId,
                        content: (0, contentPartsToMessageContent_1.contentPartsToMessageContent)(contentParts),
                    });
                    messageIndex += 1;
                    currentAssistantMessageId = getAssistantMessageId(messageIndex);
                    contentParts = [];
                    if (getIsCancelled())
                        return;
                    onNewMessage(currentAssistantMessageId);
                    continue;
                }
                const update = (0, getStreamEventContentUpdate_1.getStreamEventContentUpdate)(event);
                if (!update)
                    continue;
                const nextParts = (0, applyContentUpdate_1.applyContentUpdate)(contentParts, update);
                if (nextParts !== null) {
                    contentParts = nextParts;
                    applyContentToCurrentMessage(contentParts);
                    if (shouldYieldAfterUpdate(update)) {
                        await waitForNextTask();
                        if (getIsCancelled())
                            return;
                    }
                }
            }
        }
        catch (e_1_1) { e_1 = { error: e_1_1 }; }
        finally {
            try {
                if (!_d && !_a && (_b = stream_1.return)) await _b.call(stream_1);
            }
            finally { if (e_1) throw e_1.error; }
        }
        if (!getIsCancelled()) {
            const finalMessages = (0, buildFinalMessages_1.buildFinalMessages)({
                baseMessages,
                completedAssistantMessages,
                currentAssistantMessageId,
                contentParts,
            });
            onEnd(finalMessages, 'done');
        }
    }
    catch (err) {
        if (!getIsCancelled()) {
            const finalMessages = (0, buildFinalMessages_1.buildFinalMessages)({
                baseMessages,
                completedAssistantMessages,
                currentAssistantMessageId,
                contentParts,
            });
            onEnd(finalMessages, 'error', err instanceof Error ? err : new Error(String(err)));
        }
    }
}
//# sourceMappingURL=consumeOpenAIStream.js.map
