import { readFileSync, writeFileSync } from 'node:fs';
import { MemoryMaintenanceIntegrationService } from '../../../../../core/memory/maintenance-integration.js';
import { TraceSummaryService } from '../../../../../core/observability/index.js';
import { ChatSessionRecords } from '../../../../../core/chat/engine/sessions/records/index.js';
import { FileChatSessionRepository } from '../../../../../core/chat/engine/sessions/repository/index.js';
/**
 * Runs and records memory maintenance associated with a completed turn.
 */
export class ConversationTurnMemoryMaintenance {
    static async runInline(args) {
        const maintenanceInput = {
            memoryRoot: args.memoryRoot,
            llm: args.llm,
            source: args.source,
            trace: args.result.trace,
        };
        const maintenance = await new MemoryMaintenanceIntegrationService(maintenanceInput.memoryRoot).runForRecordedCandidates({
            llm: maintenanceInput.llm,
            source: maintenanceInput.source,
            trace: maintenanceInput.trace,
            maxSteps: 20,
            onTraceEvent: (event) => args.onEvent?.({
                type: 'trace',
                runId: args.result.state.runId,
                event,
                timestamp: new Date().toISOString(),
            }),
        });
        return ConversationTurnMemoryMaintenance.appendAgentLoopTrace(args.result, maintenance.events);
    }
    static scheduleBackground(args) {
        void ConversationTurnMemoryMaintenance.runBackground(args).catch((error) => {
            args.onEvent?.({
                type: 'trace',
                runId: args.runId,
                event: ConversationTurnMemoryMaintenance.createFailureEvent({
                    error,
                    trace: args.trace,
                }),
                timestamp: new Date().toISOString(),
            });
        });
    }
    static async runBackground(args) {
        const maintenanceInput = args;
        const maintenance = await new MemoryMaintenanceIntegrationService(maintenanceInput.memoryRoot).runForRecordedCandidates({
            llm: maintenanceInput.llm,
            source: maintenanceInput.source,
            trace: maintenanceInput.trace,
            maxSteps: 20,
            onTraceEvent: (event) => args.onEvent?.({
                type: 'trace',
                runId: args.runId,
                event,
                timestamp: new Date().toISOString(),
            }),
        });
        if (maintenance.events.length === 0) {
            return;
        }
        ConversationTurnMemoryMaintenance.appendEvents({
            ...args,
            events: maintenance.events,
        });
    }
    static appendEvents(args) {
        const nextTrace = [...ConversationTurnMemoryMaintenance.readTraceEvents(args.traceFile), ...args.events];
        writeFileSync(args.traceFile, `${JSON.stringify(nextTrace, null, 2)}\n`, 'utf8');
        const repository = new FileChatSessionRepository({ sessionStoragePath: args.sessionStoragePath });
        const sessions = repository.list();
        const nextSessions = sessions.map((session) => {
            if (session.id !== args.sessionId) {
                return session;
            }
            return ChatSessionRecords.touch({
                ...session,
                turns: session.turns.map((turn, index) => index === session.turns.length - 1
                    ? {
                        ...turn,
                        events: TraceSummaryService.default().summarizeTrace(nextTrace),
                    }
                    : turn),
            });
        });
        repository.save(nextSessions);
    }
    static appendAgentLoopTrace(result, events) {
        if (events.length === 0) {
            return {
                ...result,
                state: {
                    ...result.state,
                    trace: result.trace,
                },
            };
        }
        const trace = [...result.trace, ...events];
        return {
            ...result,
            trace,
            state: {
                ...result.state,
                trace,
            },
        };
    }
    static readTraceEvents(path) {
        try {
            const parsed = JSON.parse(readFileSync(path, 'utf8'));
            return Array.isArray(parsed) ? parsed : [];
        }
        catch {
            return [];
        }
    }
    static createFailureEvent(args) {
        return {
            type: 'memory.maintenance_failed',
            runId: `memory-run-${Date.now()}`,
            error: args.error instanceof Error ? args.error.message : String(args.error),
            candidateIds: [],
            step: ConversationTurnMemoryMaintenance.nextTraceStep(args.trace),
            timestamp: new Date().toISOString(),
        };
    }
    static nextTraceStep(trace) {
        return trace.reduce((max, event) => ('step' in event ? Math.max(max, event.step) : max), 0) + 1;
    }
}
//# sourceMappingURL=turn-memory-maintenance.js.map