import { ChatLogs } from './index.js';
export class Chat {
    _tokenizer;
    options;
    _chatLogs;
    constructor(_tokenizer, options) {
        this._tokenizer = _tokenizer;
        this.options = options;
        this._chatLogs = new ChatLogs();
    }
    get chatLogs() {
        return this._chatLogs;
    }
    get tokens() {
        return this._chatLogs.tokens;
    }
    get tokenizer() {
        return this._tokenizer;
    }
    get messages() {
        return this._chatLogs.messages;
    }
    async add(type, msg) {
        const msgs = Array.isArray(msg) ? msg : [msg];
        this.addWithoutEvents(type, msgs);
        if (this.options?.onMessagesAdded) {
            await this.options.onMessagesAdded(type, msgs);
        }
    }
    addWithoutEvents(type, msg) {
        const msgs = Array.isArray(msg) ? msg : [msg];
        const msgsWithTokens = msgs.map(msg => {
            const tokens = this._tokenizer.encode(JSON.stringify(msg)).length;
            return { ...msg, tokens };
        });
        const tokens = msgsWithTokens.map(({ tokens }) => tokens);
        this._chatLogs.add(type, msgs, tokens);
    }
    async persistent(roleOrMsg, content) {
        switch (typeof roleOrMsg) {
            case 'string':
                await this.add('persistent', {
                    role: roleOrMsg,
                    content: content ?? null,
                });
                break;
            case 'object':
                await this.add('persistent', roleOrMsg);
                break;
            default:
                throw new Error(`Invalid type for roleOrMsg: ${typeof roleOrMsg}`);
        }
    }
    async temporary(roleOrMsg, content) {
        switch (typeof roleOrMsg) {
            case 'string':
                await this.add('temporary', { role: roleOrMsg, content: content ?? null });
                break;
            case 'object':
                await this.add('temporary', roleOrMsg);
                break;
            default:
                throw new Error(`Invalid type for roleOrMsg: ${typeof roleOrMsg}`);
        }
    }
    addFunction(fn) {
        const tokens = this._tokenizer.encode(JSON.stringify(fn)).length;
        this._chatLogs.addFunction(fn, tokens);
    }
    getLastMessage(type) {
        const chatLog = this._chatLogs.get(type);
        if (chatLog.msgs.length < 1) {
            return undefined;
        }
        return chatLog.msgs[chatLog.msgs.length - 1];
    }
    cloneChatLogs() {
        return this._chatLogs.clone();
    }
    cloneEmpty() {
        return new Chat(this.tokenizer);
    }
    toString() {
        return JSON.stringify(this, null, 2);
    }
    toJSON() {
        return this._chatLogs;
    }
}
