feat(FN-1147): rehydrate AI sessions across server restarts
- Add recoverable-session querying in AiSessionStore and cover it with targeted store tests - Persist resume context (ip, initial plan, mission metadata) and rebuild planning/subtask/mission sessions from SQLite rows - Rehydrate recoverable sessions at server startup and resume planning/mission interviews by recreating agents with replayed conversation context - Update API flows to pass project root context and clean in-memory sessions when persisted sessions are deleted, with comprehensive regression tests
This commit is contained in:
@@ -17,9 +17,18 @@ import { WebSocketManager, type BadgeSnapshot } from "./websocket.js";
|
||||
import type { BadgePubSub } from "./badge-pubsub.js";
|
||||
import { createBadgePubSub, type BadgePubSubMessage } from "./badge-pubsub.js";
|
||||
import { AiSessionStore } from "./ai-session-store.js";
|
||||
import { setAiSessionStore as setPlanningAiSessionStore } from "./planning.js";
|
||||
import { setAiSessionStore as setSubtaskAiSessionStore } from "./subtask-breakdown.js";
|
||||
import { setAiSessionStore as setMissionAiSessionStore } from "./mission-interview.js";
|
||||
import {
|
||||
setAiSessionStore as setPlanningAiSessionStore,
|
||||
rehydrateFromStore as rehydratePlanningSessions,
|
||||
} from "./planning.js";
|
||||
import {
|
||||
setAiSessionStore as setSubtaskAiSessionStore,
|
||||
rehydrateFromStore as rehydrateSubtaskSessions,
|
||||
} from "./subtask-breakdown.js";
|
||||
import {
|
||||
setAiSessionStore as setMissionAiSessionStore,
|
||||
rehydrateFromStore as rehydrateMissionSessions,
|
||||
} from "./mission-interview.js";
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
@@ -322,6 +331,17 @@ export function createServer(store: TaskStore, options?: ServerOptions): ReturnT
|
||||
setSubtaskAiSessionStore(aiSessionStore);
|
||||
setMissionAiSessionStore(aiSessionStore);
|
||||
|
||||
const planningRehydratedCount = rehydratePlanningSessions(aiSessionStore);
|
||||
const subtaskRehydratedCount = rehydrateSubtaskSessions(aiSessionStore);
|
||||
const missionRehydratedCount = rehydrateMissionSessions(aiSessionStore);
|
||||
const totalRehydrated =
|
||||
planningRehydratedCount + subtaskRehydratedCount + missionRehydratedCount;
|
||||
if (totalRehydrated > 0) {
|
||||
console.log(
|
||||
`[server] Rehydrated ${planningRehydratedCount} planning, ${subtaskRehydratedCount} subtask, ${missionRehydratedCount} mission sessions from SQLite`,
|
||||
);
|
||||
}
|
||||
|
||||
const loadSettings = (store as { getSettings?: () => Promise<{ aiSessionTtlMs?: number; aiSessionCleanupIntervalMs?: number }> }).getSettings;
|
||||
if (typeof loadSettings === "function") {
|
||||
void loadSettings
|
||||
|
||||
Reference in New Issue
Block a user