import assert from "node:assert";
import { BaseChatModel, } from "@langchain/core/language_models/chat_models";
import { AIMessage } from "@langchain/core/messages";
import { MemorySaver } from "../checkpoint/memory.js";
export class FakeChatModel extends BaseChatModel {
    constructor(fields) {
        super(fields);
        Object.defineProperty(this, "responses", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        });
        this.responses = fields.responses;
    }
    _combineLLMOutput() {
        return [];
    }
    _llmType() {
        return "fake";
    }
    async _generate(messages, options, runManager) {
        if (options?.stop?.length) {
            return {
                generations: [
                    {
                        message: new AIMessage(options.stop[0]),
                        text: options.stop[0],
                    },
                ],
            };
        }
        const response = this.responses.shift();
        const text = messages.map((m) => m.content).join("\n");
        await runManager?.handleLLMNewToken(text);
        return {
            generations: [
                {
                    message: response ?? new AIMessage(text),
                    text: response ? response.content : text,
                },
            ],
            llmOutput: {},
        };
    }
}
export class MemorySaverAssertImmutable extends MemorySaver {
    constructor() {
        super();
        Object.defineProperty(this, "storageForCopies", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: {}
        });
        this.storageForCopies = {};
    }
    async put(config, checkpoint, metadata) {
        const thread_id = config.configurable?.thread_id;
        if (!this.storageForCopies[thread_id]) {
            this.storageForCopies[thread_id] = {};
        }
        // assert checkpoint hasn't been modified since last written
        const saved = await super.get(config);
        if (saved) {
            const savedId = saved.id;
            if (this.storageForCopies[thread_id][savedId]) {
                assert(JSON.stringify(saved) === this.storageForCopies[thread_id][savedId], "Checkpoint has been modified since last written");
            }
        }
        // save a copy of the checkpoint
        this.storageForCopies[thread_id][checkpoint.id] =
            this.serde.stringify(checkpoint);
        return super.put(config, checkpoint, metadata);
    }
}
