/** * Compact SESSION STATE / WORKING MEMORY block for the model. * Survives as an updatable system message; re-injected after compaction. */ export declare const SESSION_STATE_PREFIX = "SESSION STATE / WORKING MEMORY"; export interface SessionStateSnapshot { goal?: string | undefined; projectRoot?: string | undefined; packageManager?: string | undefined; planStatus?: string | undefined; planKind?: string | undefined; /** e.g. t3 in_progress "implement todo" */ openTask?: string | undefined; /** short list of pending task ids/titles */ pendingTasks?: string[] | undefined; /** short list of done task ids */ doneTasks?: string[] | undefined; featureAppRequired?: boolean | undefined; featureSeen?: boolean | undefined; scaffoldOk?: boolean | undefined; serverStarted?: boolean | undefined; serverProbedOk?: boolean | undefined; lastProbeFailed?: boolean | undefined; lastOkTool?: string | undefined; nextHint?: string | undefined; /** pentest residual one-liner */ engagementNote?: string | undefined; /** e.g. "2 running: abc123 ffuf…, def456 npm…" */ backgroundJobs?: string | undefined; } /** Build a short, high-signal state block (aim < 400 tokens). */ export declare function buildSessionStateBlock(s: SessionStateSnapshot): string; /** Infer a short next-action hint from flags (no LLM). */ export declare function inferNextHint(s: SessionStateSnapshot): string | undefined; /** * True when a system message is SESSION STATE / WORKING MEMORY. * Used so tool-protocol repair never treats these as interrupting an open * assistant/tool group (that used to drop live tool bodies and inject * "No stored body" placeholders). */ export declare function isSessionStateMessage(content: string): boolean; /** * Upsert SESSION STATE as a **trailing** system message (suffix of history). * * Why trailing (not after messages[0]): * Provider prompt caches key off a stable *prefix*. The old layout put * SESSION STATE at index 1 and rewrote it every successful tool * (`last_ok_tool`, open task, …). That single early mutation invalidated * the entire conversation prefix — matching the Bynara pattern of * ~10–11k cache (constitution only) with 45–70k fresh input. * * Trailing placement keeps system + user + prior turns byte-stable so * only the new suffix (latest tools + this block) is uncached. * * CRITICAL: call this only after the current assistant tool-call group has * all role:tool results recorded. Inserting SESSION STATE between * assistant.toolCalls and its results breaks native tool protocol: repair * then injects "No stored body" placeholders and drops the real bodies — * models thrash re-running tools that already succeeded in the UI. * * Mutates the messages array in place. */ export declare function upsertSessionStateMessage(messages: Array<{ role: string; content: string; }>, block: string): void;