From 53bbf52697e7529e5b75b6f83089dfcb55272181 Mon Sep 17 00:00:00 2001 From: Yiorgis Gozadinos Date: Thu, 13 Aug 2026 15:20:02 +0300 Subject: [PATCH] Round-trip the capability's whole state through the browser The session store rebuilt the rag namespace from four known keys, so the evidence record never survived a turn, let alone a reload from localStorage. Compaction then ran with an empty ledger: earlier evidence was replaced by receipts retaining nothing, while the citations already in citation_index kept the UI looking correct. The UI still names the fields it reads, but everything else in the namespace passes through untouched, and seeding the namespace no longer replaces sibling namespaces. --- app/frontend/components/Chat.tsx | 1 + app/frontend/lib/sessionStorage.ts | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/app/frontend/components/Chat.tsx b/app/frontend/components/Chat.tsx index 6f1ed583..30f1f6a7 100644 --- a/app/frontend/components/Chat.tsx +++ b/app/frontend/components/Chat.tsx @@ -321,6 +321,7 @@ function ChatContentInner({ const session = getSession(sessionId); // Seed state for the capability; the backend replaces it after each run. agent.setState({ + ...agent.state, [AGUI_STATE_KEY]: normalizeRAGState(session?.ragState), }); if (session && session.messages.length > 0) { diff --git a/app/frontend/lib/sessionStorage.ts b/app/frontend/lib/sessionStorage.ts index 02caae19..69d8ac7c 100644 --- a/app/frontend/lib/sessionStorage.ts +++ b/app/frontend/lib/sessionStorage.ts @@ -11,12 +11,16 @@ export interface Citation { doc_item_refs?: string[]; } -// Matches RAGState from the backend capability. +// Matches RAGState from the backend capability. The fields named here are the +// ones this UI reads; the capability owns the rest of its namespace, including +// the evidence record that compaction builds its capsule from, so the state has +// to round-trip whole rather than be rebuilt from known keys. export interface RAGState { citation_index: Record; citations: string[]; document_filter: string | null; searches: Record; + [key: string]: unknown; } export interface StoredMessage { @@ -40,6 +44,7 @@ const ACTIVE_SESSION_KEY = "haiku.rag.activeSession"; export function normalizeRAGState(state?: Partial): RAGState { return { + ...state, citation_index: state?.citation_index ?? {}, citations: state?.citations ?? [], document_filter: state?.document_filter ?? null,