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 { Command } from "@langchain/langgraph";
import { HumanMessage, SystemMessage } from "langchain";
import { detectUserLanguage } from "../domain/languageDetect.js";
import { adaptRawStream, normalizeInterrupts } from "./streamAdapter.js";
function toLangchainMessages(messages) {
    return messages.map((message) => message.role === "system"
        ? new SystemMessage(message.content)
        : new HumanMessage(message.content));
}
/**
 * LangChain/LangGraph implementation of {@link LlmPort}. This is the single
 * place that knows about the agent graph, model construction, and the raw
 * stream shape; the application layer talks only to the port.
 */
export class LangGraphLlm {
    constructor(runtime, modelFactory) {
        this.runtime = runtime;
        this.modelFactory = modelFactory;
    }
    streamTurn(input) {
        return __awaiter(this, void 0, void 0, function* () {
            const models = yield this.modelFactory.create(input.completionAdapter);
            const runtimeInput = "resume" in input.input
                ? new Command({ resume: input.input.resume })
                : { messages: toLangchainMessages(input.input.messages) };
            const rawStream = yield this.runtime.stream({
                models,
                input: runtimeInput,
                context: input.context,
                observability: input.observability,
                branchFromCheckpointId: input.branchFromCheckpointId,
            });
            return adaptRawStream(rawStream);
        });
    }
    detectLanguage(input) {
        return detectUserLanguage(input.completionAdapter, input.prompt, input.previousUserMessages);
    }
    getPendingInterrupts(input) {
        return __awaiter(this, void 0, void 0, function* () {
            const models = yield this.modelFactory.create(input.completionAdapter);
            const raw = yield this.runtime.getPendingInterrupts({ models, sessionId: input.sessionId });
            return normalizeInterrupts(raw);
        });
    }
    getLatestCheckpointId(input) {
        return __awaiter(this, void 0, void 0, function* () {
            const models = yield this.modelFactory.create(input.completionAdapter);
            return this.runtime.getLatestCheckpointId({ models, sessionId: input.sessionId });
        });
    }
    resetThreadCheckpoints(input) {
        return __awaiter(this, void 0, void 0, function* () {
            yield this.runtime.resetThreadCheckpoints(input.sessionId);
        });
    }
}
