import { EMPTY_TOKEN_USAGE } from '../../constants/limits.js';
import { RunDiskStore } from '../../store/run/disk.js';
import { accumulateTokenUsage } from '../../types/common/index.js';
import { ZERO_COST, accumulateCost } from '../../utils/cost.js';
import { generateEmergencySaveId } from '../../utils/id.js';
export class RunPersistence {
    run;
    runStore;
    pricing;
    log;
    _sessionId;
    _threadId;
    _tenantId;
    _projectId;
    constructor(config) {
        this.pricing = config.pricing;
        this.log = config.log;
        this._sessionId = config.sessionId;
        this._threadId = config.threadId;
        this._tenantId = config.tenantId;
        this._projectId = config.projectId;
        this.runStore = new RunDiskStore({
            baseDir: config.outputDir,
            logger: config.log,
        });
        this.run = {
            id: config.runId,
            status: 'idle',
            metadata: {
                agentId: config.agentId,
                agentName: config.agentName,
                config: config.runConfig,
                provider: config.providerId,
            },
            messages: [],
            tokenUsage: { ...EMPTY_TOKEN_USAGE },
            costInfo: { ...ZERO_COST },
            currentIteration: 0,
            startedAt: Date.now(),
            parentRunId: config.parentRunId,
            depth: config.depth,
        };
    }
    get id() {
        return this.run.id;
    }
    get sessionId() {
        return this._sessionId;
    }
    get threadId() {
        return this._threadId;
    }
    get tenantId() {
        return this._tenantId;
    }
    get projectId() {
        return this._projectId;
    }
    get status() {
        return this.run.status;
    }
    get stopReason() {
        return this.run.stopReason;
    }
    get messages() {
        return this.run.messages;
    }
    get tokenUsage() {
        return this.run.tokenUsage;
    }
    get costInfo() {
        return this.run.costInfo;
    }
    get currentIteration() {
        return this.run.currentIteration;
    }
    getRun() {
        return this.run;
    }
    getSession() {
        return this.run;
    }
    getRunStore() {
        return this.runStore;
    }
    getRunDir() {
        return this.runStore.getRunDir();
    }
    async init() {
        await this.runStore.initRun(this.run.id, this.run.parentRunId);
        await this.runStore.writeRunMeta(this.run);
    }
    markRunning() {
        this.run.status = 'running';
    }
    markCompleted(stopReason) {
        this.run.status = 'completed';
        if (stopReason) {
            this.run.stopReason = stopReason;
        }
        this.run.endedAt = Date.now();
        this.resolveResult();
    }
    markFailed(error) {
        this.run.status = 'failed';
        this.run.stopReason = 'error';
        this.run.lastError = error;
        this.run.endedAt = Date.now();
    }
    markCancelled() {
        this.run.status = 'cancelled';
        this.run.stopReason = 'cancelled';
        this.run.endedAt = Date.now();
    }
    setStopReason(reason) {
        this.run.stopReason = reason;
    }
    setLastError(error) {
        this.run.lastError = error;
    }
    incrementIteration() {
        this.run.currentIteration++;
        return this.run.currentIteration;
    }
    pushMessage(message) {
        this.run.messages.push(message);
    }
    accumulateUsage(usage) {
        this.run.tokenUsage = accumulateTokenUsage(this.run.tokenUsage, usage);
        if (this.pricing) {
            this.run.costInfo = accumulateCost(this.run.costInfo, usage, this.pricing);
        }
    }
    resolveResult() {
        const lastAssistant = [...this.run.messages]
            .reverse()
            .find((m) => m.role === 'assistant' && m.content !== null);
        if (lastAssistant?.content) {
            this.run.result = lastAssistant.content;
        }
    }
    toEmergencySnapshot(signal) {
        return {
            id: generateEmergencySaveId(),
            runId: this.run.id,
            messages: this.run.messages,
            tokenUsage: this.run.tokenUsage,
            currentIteration: this.run.currentIteration,
            startedAt: this.run.startedAt,
            savedAt: Date.now(),
            processSignal: signal,
            lastError: this.run.lastError,
        };
    }
    async persist() {
        await this.runStore.writeRunMeta(this.run);
        await this.runStore.writeMessages(this.run);
        await this.runStore.addToIndex(this.run);
        if (this.run.result) {
            await this.runStore.writeReport(this.run.result);
        }
        this.log.info('Run persisted to disk', {
            runId: this.run.id,
            dir: this.runStore.getRunDir(),
        });
    }
}
//# sourceMappingURL=persistence.js.map