fix: recover session submissions and failed turn settlement

This commit is contained in:
amosblomqvist
2026-10-25 19:45:17 +02:00
parent b277ee3e0f
commit 7d65fa8754
21 changed files with 944 additions and 94 deletions
+13 -4
View File
@@ -1,5 +1,5 @@
/**
* The chat-turn services — one named, error-contained seam per turn
* The chat-turn services — one named seam per turn
* responsibility, extracted from the chat-handler so it composes instead of
* implementing. Each takes its dependencies explicitly (storage ports, the
* job runner) — no module here imports an adapter.
@@ -26,6 +26,14 @@ import type { ChatStore, GraphStore } from "../core/ports.ts";
import type { ExtractionPipeline } from "../agent/subagents/extraction.ts";
import { ModelsNotConfiguredError, ProviderKeyMissingError } from "../core/settings.ts";
/** Distinguish a failed canonical save from later bookkeeping failures. */
export class TurnPersistenceError extends Error {
constructor(cause: unknown) {
super("The reply could not be saved.", { cause });
this.name = "TurnPersistenceError";
}
}
/**
* The canonical state write (Wave B, owner-approved 2026-09-26): append the
* turn's own messages — the agent loop's native history, provider/model/
@@ -45,7 +53,8 @@ import { ModelsNotConfiguredError, ProviderKeyMissingError } from "../core/setti
* - Plan blocks: one frozen snapshot per successful plan_init call,
* idempotent (persist replays are safe).
*
* Returns the stamped new messages (usage provenance reads them).
* Returns the stamped new messages (usage provenance reads them). Throws
* TurnPersistenceError on failure so the runner can report it before DONE.
*/
export function persistTurn(
chatStore: ChatStore,
@@ -56,7 +65,7 @@ export function persistTurn(
): LhMessage[] {
try {
const record = chatStore.getChat(chatId);
if (!record) return [];
if (!record) throw new Error(`Chat not found: ${chatId}`);
const stamped: LhMessage[] = [];
for (const m of turnMessages.slice(baseCount)) {
const message = m as LhMessage;
@@ -79,7 +88,7 @@ export function persistTurn(
return stamped;
} catch (err) {
console.error(`[chat ${chatId}] persist failed:`, err, { isAborted });
return [];
throw new TurnPersistenceError(err);
}
}