import { randomUUID } from "node:crypto";
import { create, fromBinary, toBinary } from "@bufbuild/protobuf";
import { encodeEndStream, encodeEnvelope } from "../connectEnvelope.js";
import { StreamUnifiedChatRequestWithToolsSchema, StreamUnifiedChatResponseSchema, StreamUnifiedChatResponseWithToolsSchema, } from "../gen/aiserver/v1/aiserver_pb.js";
import { cursorRequestToOpenAI } from "../translation.js";
export function getLocalChatDecision(payload, models) {
    const request = fromBinary(StreamUnifiedChatRequestWithToolsSchema, payload);
    const modelName = request.streamUnifiedChatRequest?.modelDetails?.modelName;
    const model = models.get(modelName);
    if (model === undefined) {
        return undefined;
    }
    return { model, request };
}
export async function writeLocalChatResponse(response, decision, logger, options = {}) {
    response.statusCode = 200;
    response.setHeader("content-type", "application/connect+proto");
    const serverBubbleId = randomUUID();
    const messages = cursorRequestToOpenAI(decision.request);
    try {
        for await (const text of decision.model.provider.streamCompletion(messages, options)) {
            response.write(encodeEnvelope(toBinary(StreamUnifiedChatResponseWithToolsSchema, create(StreamUnifiedChatResponseWithToolsSchema, {
                streamUnifiedChatResponse: create(StreamUnifiedChatResponseSchema, {
                    text,
                    serverBubbleId,
                }),
                eventId: randomUUID(),
            }))));
        }
        response.end(encodeEndStream());
        logger.info("served local chat", { model: decision.model.id });
    }
    catch (error) {
        logger.error("local chat failed", {
            model: decision.model.id,
            error: error instanceof Error ? error.message : String(error),
        });
        endLocalChatFailure(response);
    }
}
function endLocalChatFailure(response) {
    if (!response.headersSent) {
        response.statusCode = 200;
        response.setHeader("content-type", "application/connect+proto");
    }
    response.end(encodeEndStream({ error: "local model failed" }));
}
