@genesislcap/ai-assistant 14.488.1 → 14.488.2-GENC-1351.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. package/dist/ai-assistant.api.json +5104 -1727
  2. package/dist/ai-assistant.d.ts +691 -102
  3. package/dist/custom-elements.json +1118 -9
  4. package/dist/dts/components/ai-driver/ai-driver.d.ts +32 -0
  5. package/dist/dts/components/ai-driver/ai-driver.d.ts.map +1 -1
  6. package/dist/dts/components/chat-driver/chat-driver.compact.test.d.ts +2 -0
  7. package/dist/dts/components/chat-driver/chat-driver.compact.test.d.ts.map +1 -0
  8. package/dist/dts/components/chat-driver/chat-driver.d.ts +16 -0
  9. package/dist/dts/components/chat-driver/chat-driver.d.ts.map +1 -1
  10. package/dist/dts/components/orchestrating-driver/orchestrating-driver.d.ts +15 -0
  11. package/dist/dts/components/orchestrating-driver/orchestrating-driver.d.ts.map +1 -1
  12. package/dist/dts/components/orchestrating-driver/orchestrating-driver.pin.test.d.ts +2 -0
  13. package/dist/dts/components/orchestrating-driver/orchestrating-driver.pin.test.d.ts.map +1 -0
  14. package/dist/dts/components/settings-modal/settings-modal.styles.d.ts.map +1 -1
  15. package/dist/dts/components/settings-modal/settings-modal.template.d.ts.map +1 -1
  16. package/dist/dts/config/config.d.ts +70 -0
  17. package/dist/dts/config/config.d.ts.map +1 -1
  18. package/dist/dts/config/define-stateful-agent.d.ts +73 -1
  19. package/dist/dts/config/define-stateful-agent.d.ts.map +1 -1
  20. package/dist/dts/index.d.ts +1 -0
  21. package/dist/dts/index.d.ts.map +1 -1
  22. package/dist/dts/main/main.d.ts +183 -63
  23. package/dist/dts/main/main.d.ts.map +1 -1
  24. package/dist/dts/main/main.styles.d.ts.map +1 -1
  25. package/dist/dts/main/main.template.d.ts.map +1 -1
  26. package/dist/dts/main/main.types.d.ts +55 -0
  27. package/dist/dts/main/main.types.d.ts.map +1 -1
  28. package/dist/dts/state/ai-assistant-slice.d.ts +66 -0
  29. package/dist/dts/state/ai-assistant-slice.d.ts.map +1 -1
  30. package/dist/dts/state/ai-assistant-slice.test.d.ts +2 -0
  31. package/dist/dts/state/ai-assistant-slice.test.d.ts.map +1 -0
  32. package/dist/dts/state/debug-event-log.d.ts +1 -1
  33. package/dist/dts/state/debug-event-log.d.ts.map +1 -1
  34. package/dist/dts/state/persistence/diagnostics-cursors.d.ts +40 -0
  35. package/dist/dts/state/persistence/diagnostics-cursors.d.ts.map +1 -0
  36. package/dist/dts/state/persistence/diagnostics.d.ts +58 -0
  37. package/dist/dts/state/persistence/diagnostics.d.ts.map +1 -0
  38. package/dist/dts/state/persistence/diagnostics.test.d.ts +2 -0
  39. package/dist/dts/state/persistence/diagnostics.test.d.ts.map +1 -0
  40. package/dist/dts/state/persistence/index.d.ts +7 -0
  41. package/dist/dts/state/persistence/index.d.ts.map +1 -0
  42. package/dist/dts/state/persistence/persister-registry.d.ts +17 -0
  43. package/dist/dts/state/persistence/persister-registry.d.ts.map +1 -0
  44. package/dist/dts/state/persistence/session-persistence-provider.d.ts +132 -0
  45. package/dist/dts/state/persistence/session-persistence-provider.d.ts.map +1 -0
  46. package/dist/dts/state/persistence/session-persistence-provider.test.d.ts +2 -0
  47. package/dist/dts/state/persistence/session-persistence-provider.test.d.ts.map +1 -0
  48. package/dist/dts/state/persistence/session-persistence.integration.test.d.ts +2 -0
  49. package/dist/dts/state/persistence/session-persistence.integration.test.d.ts.map +1 -0
  50. package/dist/dts/state/persistence/session-persister.d.ts +154 -0
  51. package/dist/dts/state/persistence/session-persister.d.ts.map +1 -0
  52. package/dist/dts/state/persistence/session-persister.test.d.ts +2 -0
  53. package/dist/dts/state/persistence/session-persister.test.d.ts.map +1 -0
  54. package/dist/dts/state/persistence/session-snapshot.d.ts +209 -0
  55. package/dist/dts/state/persistence/session-snapshot.d.ts.map +1 -0
  56. package/dist/dts/state/persistence/session-snapshot.test.d.ts +2 -0
  57. package/dist/dts/state/persistence/session-snapshot.test.d.ts.map +1 -0
  58. package/dist/dts/state/session-store.d.ts +6 -0
  59. package/dist/dts/state/session-store.d.ts.map +1 -1
  60. package/dist/dts/utils/history-transform.d.ts +38 -0
  61. package/dist/dts/utils/history-transform.d.ts.map +1 -1
  62. package/dist/dts/utils/history-transform.test.d.ts +2 -0
  63. package/dist/dts/utils/history-transform.test.d.ts.map +1 -0
  64. package/dist/dts/utils/message-partition.d.ts +27 -0
  65. package/dist/dts/utils/message-partition.d.ts.map +1 -1
  66. package/dist/dts/utils/resolve-preference-baseline.d.ts +43 -0
  67. package/dist/dts/utils/resolve-preference-baseline.d.ts.map +1 -0
  68. package/dist/dts/utils/resolve-preference-baseline.test.d.ts +2 -0
  69. package/dist/dts/utils/resolve-preference-baseline.test.d.ts.map +1 -0
  70. package/dist/dts/utils/with-timeout.d.ts +12 -0
  71. package/dist/dts/utils/with-timeout.d.ts.map +1 -0
  72. package/dist/esm/components/chat-driver/chat-driver.compact.test.js +93 -0
  73. package/dist/esm/components/chat-driver/chat-driver.js +92 -6
  74. package/dist/esm/components/orchestrating-driver/orchestrating-driver.js +32 -0
  75. package/dist/esm/components/orchestrating-driver/orchestrating-driver.pin.test.js +48 -0
  76. package/dist/esm/components/settings-modal/settings-modal.styles.js +24 -0
  77. package/dist/esm/components/settings-modal/settings-modal.template.js +14 -1
  78. package/dist/esm/config/define-stateful-agent.js +81 -0
  79. package/dist/esm/index.js +1 -0
  80. package/dist/esm/main/main.js +610 -84
  81. package/dist/esm/main/main.styles.js +55 -0
  82. package/dist/esm/main/main.template.js +94 -5
  83. package/dist/esm/main/main.types.js +27 -0
  84. package/dist/esm/state/ai-assistant-slice.js +71 -25
  85. package/dist/esm/state/ai-assistant-slice.test.js +65 -0
  86. package/dist/esm/state/debug-event-log.js +8 -0
  87. package/dist/esm/state/persistence/diagnostics-cursors.js +34 -0
  88. package/dist/esm/state/persistence/diagnostics.js +81 -0
  89. package/dist/esm/state/persistence/diagnostics.test.js +72 -0
  90. package/dist/esm/state/persistence/index.js +3 -0
  91. package/dist/esm/state/persistence/persister-registry.js +41 -0
  92. package/dist/esm/state/persistence/session-persistence-provider.js +95 -0
  93. package/dist/esm/state/persistence/session-persistence-provider.test.js +110 -0
  94. package/dist/esm/state/persistence/session-persistence.integration.test.js +109 -0
  95. package/dist/esm/state/persistence/session-persister.js +577 -0
  96. package/dist/esm/state/persistence/session-persister.test.js +239 -0
  97. package/dist/esm/state/persistence/session-snapshot.js +231 -0
  98. package/dist/esm/state/persistence/session-snapshot.test.js +243 -0
  99. package/dist/esm/utils/history-transform.js +101 -0
  100. package/dist/esm/utils/history-transform.test.js +137 -0
  101. package/dist/esm/utils/message-partition.js +30 -2
  102. package/dist/esm/utils/message-partition.test.js +20 -1
  103. package/dist/esm/utils/resolve-preference-baseline.js +53 -0
  104. package/dist/esm/utils/resolve-preference-baseline.test.js +69 -0
  105. package/dist/esm/utils/with-timeout.js +28 -0
  106. package/dist/tsconfig.tsbuildinfo +1 -1
  107. package/package.json +17 -17
  108. package/src/components/ai-driver/ai-driver.ts +36 -0
  109. package/src/components/chat-driver/chat-driver.compact.test.ts +131 -0
  110. package/src/components/chat-driver/chat-driver.ts +99 -6
  111. package/src/components/orchestrating-driver/orchestrating-driver.pin.test.ts +76 -0
  112. package/src/components/orchestrating-driver/orchestrating-driver.ts +36 -0
  113. package/src/components/settings-modal/settings-modal.styles.ts +24 -0
  114. package/src/components/settings-modal/settings-modal.template.ts +27 -1
  115. package/src/config/config.ts +71 -0
  116. package/src/config/define-stateful-agent.ts +134 -0
  117. package/src/index.ts +1 -0
  118. package/src/main/main.styles.ts +55 -0
  119. package/src/main/main.template.ts +121 -5
  120. package/src/main/main.ts +569 -64
  121. package/src/main/main.types.ts +59 -0
  122. package/src/state/ai-assistant-slice.test.ts +82 -0
  123. package/src/state/ai-assistant-slice.ts +120 -25
  124. package/src/state/debug-event-log.ts +18 -1
  125. package/src/state/persistence/diagnostics-cursors.ts +66 -0
  126. package/src/state/persistence/diagnostics.test.ts +95 -0
  127. package/src/state/persistence/diagnostics.ts +103 -0
  128. package/src/state/persistence/index.ts +10 -0
  129. package/src/state/persistence/persister-registry.ts +49 -0
  130. package/src/state/persistence/session-persistence-provider.test.ts +136 -0
  131. package/src/state/persistence/session-persistence-provider.ts +202 -0
  132. package/src/state/persistence/session-persistence.integration.test.ts +134 -0
  133. package/src/state/persistence/session-persister.test.ts +325 -0
  134. package/src/state/persistence/session-persister.ts +622 -0
  135. package/src/state/persistence/session-snapshot.test.ts +339 -0
  136. package/src/state/persistence/session-snapshot.ts +332 -0
  137. package/src/utils/history-transform.test.ts +197 -0
  138. package/src/utils/history-transform.ts +117 -0
  139. package/src/utils/message-partition.test.ts +27 -1
  140. package/src/utils/message-partition.ts +41 -2
  141. package/src/utils/resolve-preference-baseline.test.ts +84 -0
  142. package/src/utils/resolve-preference-baseline.ts +80 -0
  143. package/src/utils/with-timeout.ts +24 -0
@@ -8,8 +8,8 @@ import type { ChatConfig } from '@genesislcap/foundation-ai';
8
8
  import type { ChatDriverResult } from '@genesislcap/foundation-ai';
9
9
  import type { ChatInputDuringExecutionMode } from '@genesislcap/foundation-ai';
10
10
  import type { ChatMessage } from '@genesislcap/foundation-ai';
11
- import { ChatToolChoice } from '@genesislcap/foundation-ai';
12
- import { ChatToolDefinition } from '@genesislcap/foundation-ai';
11
+ import type { ChatToolChoice } from '@genesislcap/foundation-ai';
12
+ import type { ChatToolDefinition } from '@genesislcap/foundation-ai';
13
13
  import type { ChatToolHandlers } from '@genesislcap/foundation-ai';
14
14
  import { GenesisElement } from '@genesislcap/web-core';
15
15
  import type { InteractionRequestOptions } from '@genesislcap/foundation-ai';
@@ -217,6 +217,40 @@ export declare interface AgentLifecycleContext {
217
217
  previousAgentName?: string;
218
218
  /** Aborted if the session disconnects mid-activation. */
219
219
  signal: AbortSignal;
220
+ /**
221
+ * A previously-serialized state image for this agent (from the agent's
222
+ * `serialize`), passed only on `onActivate` when resuming a persisted
223
+ * session. A stateful
224
+ * agent's `init` rebuilds from it — e.g. via `restoreMachine` — or starts
225
+ * fresh when it is `undefined`.
226
+ */
227
+ restored?: unknown;
228
+ }
229
+
230
+ /**
231
+ * Context passed to an agent's `resumable` predicate (GENC-1351 §5.9), evaluated
232
+ * at session-save time on the active agent (which, for a locked guided flow, is
233
+ * the flow-owner).
234
+ *
235
+ * @beta
236
+ */
237
+ export declare interface AgentPersistenceContext {
238
+ /** The agent being consulted. */
239
+ agentName: string;
240
+ /** The assistant session key — stable across reloads. */
241
+ sessionKey: string;
242
+ /**
243
+ * This agent's just-serialized state image — the value its `serialize()`
244
+ * returned for this save (or the carried-forward image). Inspect the machine
245
+ * step here. Derive the decision from this (not live closure state): the
246
+ * predicate must be a pure function of the state so a resumable snapshot stays
247
+ * resumable when re-evaluated on restore.
248
+ */
249
+ state: unknown;
250
+ /** Full conversation transcript at save time. */
251
+ messages: ReadonlyArray<ChatMessage>;
252
+ /** True when this agent currently owns the guided flow (`name === flowOwnerAgentName`). */
253
+ isFlowOwner: boolean;
220
254
  }
221
255
 
222
256
  /**
@@ -306,6 +340,41 @@ export declare interface AiAssistantAnimationDef {
306
340
  category: string;
307
341
  }
308
342
 
343
+ /**
344
+ * DOM events the `<foundation-ai-assistant>` element dispatches to its host.
345
+ * All bubble and are `composed` (they cross the shadow boundary), so a host can
346
+ * listen on the element — or any ancestor — to react. Use these constants to
347
+ * wire listeners instead of hand-typing event-name strings.
348
+ *
349
+ * An `as const` map (not a TS `enum` — this package ships none), so it serves as
350
+ * both the listener-name value and, via the same-named type below, a union.
351
+ *
352
+ * @example
353
+ * ```ts
354
+ * import { AiAssistantEvent, type SessionClearedDetail } from '@genesislcap/ai-assistant';
355
+ *
356
+ * el.addEventListener(AiAssistantEvent.SessionCleared, (e) => {
357
+ * const { agentName, agentSnapshot } = (e as CustomEvent<SessionClearedDetail>).detail;
358
+ * // …clean up external state the agent was working on…
359
+ * });
360
+ * ```
361
+ *
362
+ * @beta
363
+ */
364
+ export declare const AiAssistantEvent: {
365
+ /** Session wiped via the lifecycle menu's Clear. `detail`: `SessionClearedDetail`. */
366
+ readonly SessionCleared: "session-cleared";
367
+ /** Header pressed in `popout-mode="expand"` (drag-to-popout hosts). `detail`: `ChatHeaderMouseDownDetail`. */
368
+ readonly ChatHeaderMouseDown: "chat-header-mousedown";
369
+ };
370
+
371
+ /**
372
+ * One of the `AiAssistantEvent` event-name values.
373
+ *
374
+ * @beta
375
+ */
376
+ export declare type AiAssistantEvent = (typeof AiAssistantEvent)[keyof typeof AiAssistantEvent];
377
+
309
378
  /**
310
379
  * State of the AI assistant component.
311
380
  *
@@ -401,10 +470,41 @@ export declare interface AiDriver extends EventTarget {
401
470
  * Seed the driver's message history (called on state restore / pop-in).
402
471
  */
403
472
  loadHistory(messages: ChatMessage[]): void;
473
+ /**
474
+ * Prime per-agent restored state for a session being rehydrated. Each entry
475
+ * (keyed by agent name) is handed to that agent's `onActivate`/`init` as
476
+ * `ctx.restored` on its next activation, then consumed. Optional — only
477
+ * multi-agent drivers that own agent activation implement it.
478
+ */
479
+ primeRestoredAgentState?(snapshots: Record<string, unknown>): void;
404
480
  /**
405
481
  * Return the full, unredacted conversation history.
406
482
  */
407
483
  getRawHistory?(): readonly ChatMessage[];
484
+ /**
485
+ * The live `AgentConfig` currently active in the driver — the instance whose
486
+ * `onActivate` ran, so its `serialize`/`getDebugSnapshot` closures hold live
487
+ * state. Prefer this over looking the agent up in the host's `agents` array,
488
+ * which may mint fresh, never-activated configs. Optional — only drivers that
489
+ * retain the active config implement it.
490
+ */
491
+ getActiveAgent?(): AgentConfig | undefined;
492
+ /**
493
+ * Destructively compact older conversation turns into a single
494
+ * `compacted-summary` message (GENC-1351 §5.7), summarizing them via the
495
+ * default provider's one-shot `prompt()`. Atomic: history changes only on
496
+ * success. Resolves to the created summary message, or `null` when there is
497
+ * nothing worth compacting or the provider cannot summarize. Optional — only
498
+ * drivers that own history implement it.
499
+ */
500
+ compact?(): Promise<ChatMessage | null>;
501
+ /**
502
+ * Whether `compact()` would compact something right now — a summarizable run of
503
+ * older turns exists behind a clean boundary. The UI gates its "Compact"
504
+ * affordance on this, so the button reflects the exact history `compact()` acts
505
+ * on (GENC-1351). Optional — only history-owning drivers implement it.
506
+ */
507
+ canCompact?(): boolean;
408
508
  /**
409
509
  * Returns true if the driver is currently processing a request.
410
510
  */
@@ -528,6 +628,20 @@ export declare const ANIMATION_DEFS: {
528
628
  };
529
629
  };
530
630
 
631
+ /**
632
+ * Reassemble diagnostic entries into the `{ readme, timeline, meta }` debug-log
633
+ * shape (GENC-1351 §5.8). `timeline` = the `message`/`turn`/`event` entries sorted
634
+ * by ISO `timestamp` (kind-rank tie-break). `meta` = the **newest** `meta-snapshot`'s
635
+ * block only — a "state at export" photo, matching the single-page log. The older
636
+ * snapshots are intentionally dropped: the per-turn evolution they would show is
637
+ * already in the timeline (`turn.agentSnapshot` + `context.updated` events), so
638
+ * keeping them would just repeat the bulky, near-static `agentSummary`. `readme` =
639
+ * the passed (current) constant. Pure — reused for both the live current-page log
640
+ * and the reassembled lifetime log stitched from the persisted stream, so both
641
+ * come out shape-identical.
642
+ */
643
+ export declare function assembleDebugLog(entries: DiagnosticEntry[], readme: readonly string[]): DebugLog;
644
+
531
645
  /**
532
646
  * App-supplied settings for the platform settings modal UI Builder section.
533
647
  * Register a concrete implementation on the DI token at app bootstrap; the
@@ -742,6 +856,43 @@ declare interface BaseAgentConfig {
742
856
  * @beta
743
857
  */
744
858
  getDebugSnapshot?: () => unknown;
859
+ /**
860
+ * Returns a lossless, JSON-serializable image of the agent's state for session
861
+ * persistence — distinct from `getDebugSnapshot`, which may abbreviate for
862
+ * readability. Pass the value back to the agent on restore (as
863
+ * `ctx.restored` in its `init`) to resume. {@link defineStatefulAgent} wires a
864
+ * default that snapshots any machine-shaped state via `getPersistedSnapshot()`
865
+ * and returns plain state as-is.
866
+ *
867
+ * @beta
868
+ */
869
+ serialize?: () => unknown;
870
+ /**
871
+ * Whether the agent's current state is resumable — i.e. worth persisting so the
872
+ * session can be restored mid-flow (GENC-1351 §5.9). Consulted at save time on
873
+ * the active agent (the flow-owner during a locked flow). Return `true`
874
+ * (or leave the field absent) to persist and resume normally; return `false`
875
+ * for a point that shouldn't be resumed — the session is not persisted, and on
876
+ * return the assistant shows {@link AgentConfig.notResumableMessage} (or a
877
+ * default) and pre-fills the composer with the prompt that started the flow so
878
+ * the user can re-run it.
879
+ *
880
+ * Only consulted when the user has persistence enabled. Must be a **pure
881
+ * function of `ctx.state`** — it may be re-evaluated on a restored snapshot, so
882
+ * a resumable state must stay resumable. A thrown error is treated as `true`
883
+ * (fail-safe: never drop a resumable chat on a predicate bug).
884
+ *
885
+ * @beta
886
+ */
887
+ resumable?: (ctx: AgentPersistenceContext) => boolean | Promise<boolean>;
888
+ /**
889
+ * Message shown on return when {@link AgentConfig.resumable} returned `false`
890
+ * and the user comes back to a non-resumable session (GENC-1351 §5.9). Falls
891
+ * back to a built-in default when omitted.
892
+ *
893
+ * @beta
894
+ */
895
+ notResumableMessage?: string;
745
896
  }
746
897
 
747
898
  export { CachePolicy }
@@ -1195,6 +1346,22 @@ export declare class ChatDriver extends EventTarget implements AiDriver {
1195
1346
  /** Returns the current fold stack names for debugging. */
1196
1347
  getActiveFoldNames(): string[];
1197
1348
  getSuggestions(history: ChatMessage[], prompt: string, count: number, allAgentInfo?: AllAgentSummary[]): Promise<string[]>;
1349
+ /**
1350
+ * Whether `compact()` would do anything right now — a summarizable run of older
1351
+ * turns exists behind a clean boundary. Uses the same `history` `compact()`
1352
+ * acts on, so the UI's gate can't disagree with the action (GENC-1351 follow-up).
1353
+ */
1354
+ canCompact(): boolean;
1355
+ /**
1356
+ * Destructively compact older turns into a single `compacted-summary` message
1357
+ * (GENC-1351 §5.7). Summarizes everything before a clean recent-tail boundary
1358
+ * via the registry-default provider's one-shot `prompt()`, then **atomically**
1359
+ * replaces the covered turns with one summary message at the head — history is
1360
+ * mutated only on success. Rolling: any existing head summary is folded into
1361
+ * the new one. Returns the created summary message, or `null` when there is
1362
+ * nothing worth compacting or the default provider cannot summarize.
1363
+ */
1364
+ compact(): Promise<ChatMessage | null>;
1198
1365
  isBusy(): boolean;
1199
1366
  /** Register an assistant view (host) wired to this shared driver. @internal */
1200
1367
  registerHost(hostId: string): void;
@@ -1329,6 +1496,16 @@ export declare class ChatDriver extends EventTarget implements AiDriver {
1329
1496
  private appendToHistory;
1330
1497
  }
1331
1498
 
1499
+ /**
1500
+ * `detail` of the `AiAssistantEvent.ChatHeaderMouseDown` event.
1501
+ *
1502
+ * @beta
1503
+ */
1504
+ export declare interface ChatHeaderMouseDownDetail {
1505
+ clientX: number;
1506
+ clientY: number;
1507
+ }
1508
+
1332
1509
  /**
1333
1510
  * Detail payload for the `chat-header-mousedown` event fired by the assistant
1334
1511
  * in `popout-mode="expand"`.
@@ -1439,6 +1616,13 @@ export declare function createToolFold(config: {
1439
1616
  exclusive?: boolean;
1440
1617
  }): ToolFoldResult;
1441
1618
 
1619
+ /** The reassembled debug log — the exact shape `getDebugLog()` returns. @public */
1620
+ export declare interface DebugLog {
1621
+ readme: readonly string[];
1622
+ timeline: DiagnosticEntry[];
1623
+ meta: unknown;
1624
+ }
1625
+
1442
1626
  /**
1443
1627
  * Animations enabled by default when a consumer opts into the animations
1444
1628
  * feature without specifying an explicit `enabled` list. Keeps the dots loading
@@ -1492,6 +1676,25 @@ export declare function defineAgent<const T extends AgentConfig>(config: T): T;
1492
1676
  */
1493
1677
  export declare function defineStatefulAgent<S>(opts: StatefulAgentInit<S>): AgentConfig;
1494
1678
 
1679
+ /**
1680
+ * One entry in the diagnostics stream — the debug-log timeline-entry union
1681
+ * (`message` / `turn` / `event`, as `getDebugLog()` builds) plus a point-in-time
1682
+ * **`meta-snapshot`** carrying the export-time `meta` block (agent summary,
1683
+ * context, active debug snapshot, …). Kept permissive: a provider stores and
1684
+ * returns these opaquely, and reassembly reads only `kind`, `timestamp` (for
1685
+ * ordering), and `meta` (on a snapshot).
1686
+ *
1687
+ * @public
1688
+ */
1689
+ export declare interface DiagnosticEntry {
1690
+ kind: 'message' | 'turn' | 'event' | 'meta-snapshot';
1691
+ /** ISO timestamp — string-comparable, so it orders the stream chronologically. */
1692
+ timestamp?: string;
1693
+ /** Present on `meta-snapshot` entries: the export-time `meta` block. */
1694
+ meta?: unknown;
1695
+ [key: string]: unknown;
1696
+ }
1697
+
1495
1698
  /**
1496
1699
  * Expands a flat list of tool definitions into a nested tree by resolving fold
1497
1700
  * metadata from the corresponding handlers. Use this for debug output so the
@@ -1581,6 +1784,15 @@ export declare class FoundationAiAssistant extends GenesisElement {
1581
1784
  */
1582
1785
  agents?: AgentConfig[];
1583
1786
  chatConfig: ChatConfig;
1787
+ /**
1788
+ * Optional session persistence (GENC-1351). Off by default — set `enabled`
1789
+ * and a `provider` (e.g. a `WebStorageSessionProvider`) to have the assistant
1790
+ * autosave on idle and auto-restore the conversation on page reload. Exposed
1791
+ * as a top-level property (like `agents`/`providerRegistry`) rather than via
1792
+ * `chatConfig`, since the provider type lives in this package while
1793
+ * `ChatConfig` lives in `foundation-ai`.
1794
+ */
1795
+ persistence: SessionPersistenceConfig;
1584
1796
  /**
1585
1797
  * Resolved agent picker mode from `chatConfig.picker.mode`. Defaults to
1586
1798
  * `'disabled'`.
@@ -1654,6 +1866,27 @@ export declare class FoundationAiAssistant extends GenesisElement {
1654
1866
  */
1655
1867
  get agentPickerOpen(): boolean;
1656
1868
  set agentPickerOpen(value: boolean);
1869
+ /**
1870
+ * Whether the lifecycle (session) menu slide-out panel is open. Like the
1871
+ * agent picker, lives on the session store so bubble/popout stay in sync.
1872
+ */
1873
+ get sessionMenuOpen(): boolean;
1874
+ set sessionMenuOpen(value: boolean);
1875
+ /**
1876
+ * Whether a manual compaction is in flight (GENC-1351 §5.7). On the session
1877
+ * store (not element-local) so the "Compacting…" view + input-disable stay in
1878
+ * sync across pop-in/out, like the panel flags.
1879
+ */
1880
+ get compacting(): boolean;
1881
+ set compacting(value: boolean);
1882
+ /**
1883
+ * Whether a page-reload restore is in flight (GENC-1351 §6). On the session
1884
+ * store (like `compacting`) so the "Restoring…" view + input-disable stay in
1885
+ * sync across pop-in/out. Gating input while true prevents a mid-load send from
1886
+ * being clobbered when the restored history loads.
1887
+ */
1888
+ get restoring(): boolean;
1889
+ set restoring(value: boolean);
1657
1890
  /**
1658
1891
  * Name of the agent the user has pinned via the agent picker. `null` means
1659
1892
  * automatic routing (Auto). Persisted on the session store, so it survives
@@ -1747,6 +1980,14 @@ export declare class FoundationAiAssistant extends GenesisElement {
1747
1980
  appSettingsRevision: number;
1748
1981
  /** Whether the settings modal is open. */
1749
1982
  settingsOpen: boolean;
1983
+ /**
1984
+ * True while `downloadDebugLog` is building the log (GENC-1351 §5.8). Drives the
1985
+ * download button's disabled + spinner state — the lifetime-stitch path is async
1986
+ * (a provider `loadDiagnostics` round-trip), so without feedback a click looks
1987
+ * like nothing happened. Per-instance and transient (not shared/persisted): each
1988
+ * element has its own settings modal.
1989
+ */
1990
+ downloadingDebugLog: boolean;
1750
1991
  /** Active tab inside the settings modal. */
1751
1992
  settingsModalTab: SettingsModalTab;
1752
1993
  /** Bound to the design-system modal via the template ref. */
@@ -1840,6 +2081,21 @@ export declare class FoundationAiAssistant extends GenesisElement {
1840
2081
  * originating `send()` ran on a different element instance.
1841
2082
  */
1842
2083
  private _executionCompletionUnsub?;
2084
+ /**
2085
+ * True while UI preferences are being applied programmatically (config defaults
2086
+ * on connect, or a loaded-preferences restore) — suppresses the save hook so we
2087
+ * don't persist config defaults or re-persist what we just loaded. Cleared once
2088
+ * the apply completes; a genuine *user* toggle (menu switch) runs with it false
2089
+ * and saves (GENC-1351).
2090
+ */
2091
+ private _applyingPreferences;
2092
+ /**
2093
+ * Fresh-store flag (`= isNewStore`) captured in `connectedCallback`. Only a
2094
+ * freshly created store takes the config/stored-prefs baseline; an existing
2095
+ * store — a reload with a live in-realm store, or the popped-out second instance
2096
+ * — already holds the correct state, so `applyPreferenceBaseline` no-ops for it.
2097
+ */
2098
+ private _freshStore;
1843
2099
  showHalo: 'no' | 'orchestrating' | 'agent';
1844
2100
  private syncShowHalo;
1845
2101
  /** True when there is a pending (unresolved) interaction. */
@@ -1949,6 +2205,95 @@ export declare class FoundationAiAssistant extends GenesisElement {
1949
2205
  private logMeta;
1950
2206
  private readonly _agentPickerToggle;
1951
2207
  toggleAgentPicker(): void;
2208
+ /** Two-step confirm for the destructive Clear action; reset whenever the menu toggles. */
2209
+ confirmingClear: boolean;
2210
+ confirmingCompact: boolean;
2211
+ private readonly _sessionMenuToggle;
2212
+ /**
2213
+ * Whether the lifecycle-menu button shows. It occupies the stop-button slot,
2214
+ * so it only appears when idle (mutually exclusive with Stop). Needs
2215
+ * something to act on: a chat to clear/compact, or a provider to toggle.
2216
+ */
2217
+ get sessionMenuEnabled(): boolean;
2218
+ /** The persistence toggle row renders only when a provider is configured. */
2219
+ get persistenceToggleable(): boolean;
2220
+ /** Whether persistence is currently active (on + a provider) for this session. */
2221
+ get persistenceActive(): boolean;
2222
+ /**
2223
+ * Whether the menu's "Compact" action would do anything (GENC-1351 §5.7).
2224
+ * Delegates to `driver.canCompact()` so the gate uses the exact same history
2225
+ * `compact()` acts on — one source of truth. Also reads `messages`, purely to
2226
+ * stay reactive as the conversation grows: the driver's history isn't a tracked
2227
+ * observable, so the button keys its re-evaluation off the Redux mirror.
2228
+ */
2229
+ get compactable(): boolean;
2230
+ toggleSessionMenu(): void;
2231
+ /**
2232
+ * Set persistence on/off for this session (the menu switch). Reassigns the
2233
+ * `persistence` object so the `@observable` fires. Turning it **off** drops the
2234
+ * stored snapshot; **on** captures the current chat immediately. Either way the
2235
+ * *choice* is remembered in the preferences blob (`persistPreferences`) — stored
2236
+ * independently of the snapshot, so it survives the clear and re-applies on the
2237
+ * next load (GENC-1351).
2238
+ */
2239
+ setPersistenceEnabled(enabled: boolean): void;
2240
+ /** Toggle persistence (convenience / programmatic). */
2241
+ togglePersistence(): void;
2242
+ /** Snapshot the user-changeable settings into a persistable preferences blob. */
2243
+ private gatherPreferences;
2244
+ /**
2245
+ * Persist the current UI preferences whenever the user changes a setting
2246
+ * (GENC-1351). Fires **regardless of "remember chat"** — display choices are the
2247
+ * user's, not tied to whether the chat is remembered — needing only a provider
2248
+ * that implements `savePreferences`. No-op while preferences are being applied
2249
+ * programmatically (`_applyingPreferences`), so config defaults and loaded prefs
2250
+ * aren't re-saved.
2251
+ */
2252
+ private persistPreferences;
2253
+ /**
2254
+ * Apply the effective UI-preference baseline onto the live toggles for a fresh
2255
+ * store (GENC-1351 #2). Precedence, lowest → highest:
2256
+ *
2257
+ * slice defaults < `chatConfig.ui` defaults < stored user preferences
2258
+ *
2259
+ * Recomputed from scratch (not layered) on every call, because its two inputs
2260
+ * arrive at unpredictable times: `chatConfig` is a parent-supplied `@observable`
2261
+ * that may bind *after* `connectedCallback`, and stored prefs load asynchronously.
2262
+ * So it re-runs from `connectedCallback`, `chatConfigChanged`, and once
2263
+ * `loadPreferences` resolves — whichever order they happen in, the final state is
2264
+ * the same. No-op once the store isn't fresh (an existing/popped-out store owns
2265
+ * its state) or the user has toggled something (their choice then wins, and
2266
+ * `chatConfig` doesn't change post-startup in practice). Save hook suppressed so
2267
+ * applying the baseline never persists as if it were a user choice.
2268
+ *
2269
+ * This is the fix for "nuking server prefs drops to all-disabled instead of the
2270
+ * `chatConfig` defaults": stored prefs are simply absent, so the baseline falls
2271
+ * through to the config layer — which the old apply-once-on-connect path missed
2272
+ * whenever `chatConfig` hadn't bound yet.
2273
+ */
2274
+ private applyPreferenceBaseline;
2275
+ /**
2276
+ * Compact the conversation (GENC-1351 §5.7) — the menu's "Compact" action.
2277
+ * Delegates to the driver, which summarizes older turns into a single
2278
+ * `compacted-summary` message (destructive, atomic). On success records a
2279
+ * high-importance `context.compacted` meta-event capturing the summary; the
2280
+ * normal `history-updated` → autosave path then persists the smaller
2281
+ * transcript. No-op when there is nothing to compact or the provider cannot
2282
+ * summarize (the driver returns `null`).
2283
+ */
2284
+ compactSession(): Promise<void>;
2285
+ /**
2286
+ * Clear the session — the "New chat" action (GENC-1351 §5.6). Tears down the
2287
+ * active driver (firing the stateful agent's `onDeactivate` → `machine.stop()`),
2288
+ * resets the store, rebuilds a fresh driver with no history, and wipes durable
2289
+ * storage. Mirrors `agentsChanged`'s teardown, minus the history reseed.
2290
+ *
2291
+ * @fires session-cleared - After the session is wiped. `detail`:
2292
+ * `{ sessionKey, agentName?, agentSnapshot? }` — captured *before* teardown
2293
+ * so the host can clean up any external state the active agent was working
2294
+ * on (generated files, server-side scratch, etc.). Bubbles and composed.
2295
+ */
2296
+ clearSession(): Promise<void>;
1952
2297
  /**
1953
2298
  * Programmatically pin an agent by name. Returns `true` if the pin was
1954
2299
  * applied, `false` if the agent isn't in the configured agents array or
@@ -2038,68 +2383,45 @@ export declare class FoundationAiAssistant extends GenesisElement {
2038
2383
  toggleShowNarration(): void;
2039
2384
  toggleShowAgentSwitchIndicator(): void;
2040
2385
  setEnabledAnimations(animations: AiAssistantAnimation[]): void;
2041
- getDebugLog(): {
2042
- readme: readonly string[];
2043
- timeline: (TimelineMessage | {
2044
- systemPrompt: string;
2045
- turnIndex: string;
2046
- timestamp: string;
2047
- agentName?: string;
2048
- tailContext?: string;
2049
- toolNames: string[];
2050
- temperature?: number;
2051
- toolChoice?: ChatToolChoice;
2052
- agentLabel?: string;
2053
- agentSnapshot?: unknown;
2054
- kind: "turn";
2055
- } | {
2056
- index: number;
2057
- timestamp: string;
2058
- type: MetaEventType;
2059
- importance: MetaEventImportance;
2060
- detail?: Record<string, unknown>;
2061
- kind: "event";
2062
- })[];
2063
- meta: {
2064
- timestamp: string;
2065
- host: string;
2066
- agentSummary: {
2067
- toolDefinitions: string | ChatToolDefinition[];
2068
- name: string;
2069
- provider?: ProviderInput;
2070
- chatInputDuringExecution?: ChatInputDuringExecutionMode;
2071
- description?: string;
2072
- fallback?: true;
2073
- displayName?: SystemPromptInput;
2074
- systemPrompt?: SystemPromptInput;
2075
- temperature?: TemperatureInput;
2076
- toolChoice?: ToolChoiceInput;
2077
- cachePolicy?: CachePolicyInput;
2078
- tailContext?: TailContextInput;
2079
- onUnresolvedTool?: UnresolvedToolInput;
2080
- primerHistory?: ChatMessage[];
2081
- subAgents?: AgentConfig[];
2082
- manualSelection?: ManualSelectionConfig;
2083
- onActivate?: (ctx: AgentLifecycleContext) => void | Promise<void>;
2084
- onDeactivate?: (ctx: AgentLifecycleContext) => void | Promise<void>;
2085
- getDebugSnapshot?: () => unknown;
2086
- }[];
2087
- activeSystemPrompt: string;
2088
- activePrimerHistory: ChatMessage[];
2089
- activeFoldStack: string[];
2090
- context: {
2091
- model: string;
2092
- contextTokens: number;
2093
- contextLimit: number;
2094
- contextUsagePercent: number;
2095
- sessionCostUsd: number;
2096
- sessionTokensConsumed: number;
2097
- };
2098
- activeDebugSnapshot: unknown;
2099
- debug: unknown;
2100
- };
2101
- };
2102
- downloadDebugLog(): void;
2386
+ /** The live current-page debug log (`{ readme, timeline, meta }`). @public */
2387
+ getDebugLog(): DebugLog;
2388
+ /**
2389
+ * Build the current page's diagnostic entries (GENC-1351 §5.8) — the debug-log
2390
+ * timeline entries (`message`/`turn`/`event`) plus one `meta-snapshot` carrying
2391
+ * the export-time `meta` block. `getDebugLog()` reassembles these into the live
2392
+ * log; the persister's forward-capture path (`SessionPersister.flushDiagnostics`,
2393
+ * fed these via the `getDiagnosticEntries` dep) diffs them against what's already
2394
+ * been appended to the persisted stream.
2395
+ */
2396
+ private buildDiagnosticEntries;
2397
+ downloadDebugLog(): Promise<void>;
2398
+ /**
2399
+ * The log to download (GENC-1351 §5.8). When the provider persists diagnostics,
2400
+ * stitch the **whole lifetime** stream (every page load) rather than just the
2401
+ * current page's in-memory view: flush the current delta first so it's included,
2402
+ * then reassemble everything `loadDiagnostics` returns. Independent of "remember
2403
+ * chat" — diagnostics are a forensic stream keyed on provider capability, not on
2404
+ * whether the *chat* is remembered (like preferences). Falls back to the live
2405
+ * current-page log when diagnostics isn't available or the fetch fails.
2406
+ */
2407
+ private buildDownloadLog;
2408
+ /**
2409
+ * The shared per-session `SessionPersister` that owns restore-core
2410
+ * save/restore/freeze (GENC-1351 §5.10). Created once per `stateKey` and shared by
2411
+ * every element view (bubble + panel) via the registry, so there is a single save
2412
+ * timer + carry-forward cache — no per-view double-writes. The deps are getters so
2413
+ * the persister always reads the current driver/store/config and never holds a
2414
+ * stale reference. `undefined` before the session key is available.
2415
+ */
2416
+ private persister;
2417
+ /**
2418
+ * First-load persistence init for a freshly created store (GENC-1351). Restores
2419
+ * the user's remembered persistence-toggle choice — kept independently of the
2420
+ * session snapshot so it survives a clear; the host-configured `enabled` is only
2421
+ * the default for a first-ever load — then auto-restores the session when
2422
+ * persistence is (now) on.
2423
+ */
2424
+ private initPersistenceForNewStore;
2103
2425
  triggerFileInput(): void;
2104
2426
  handleFileSelect(e: Event): void;
2105
2427
  removeAttachment(attachment: ChatAttachment): void;
@@ -2285,44 +2607,6 @@ export declare interface ManualSelectionConfig {
2285
2607
  hint?: string;
2286
2608
  }
2287
2609
 
2288
- /**
2289
- * How much a reader should care about an event — lets a consumer (or an AI
2290
- * agent) filter the timeline: skip `low` UI/bookkeeping noise, skim `normal`
2291
- * session flow, or jump straight to `high` problem/limit signals when triaging.
2292
- */
2293
- declare type MetaEventImportance = 'high' | 'normal' | 'low';
2294
-
2295
- /**
2296
- * Module-level append-only timeline of meta/lifecycle events, keyed by session
2297
- * identity (the same `stateKey` space used by the driver registry and the
2298
- * session store).
2299
- *
2300
- * Why a module registry rather than the redux store or the driver:
2301
- * - **Survives the pop-in/pop-out element churn.** A single session can be
2302
- * emitted from up to two element instances (an `expand` bubble + a `collapse`
2303
- * panel) sharing one driver; keying by `stateKey` unifies them into one
2304
- * timeline.
2305
- * - **Survives driver rebuilds.** The driver is torn down and recreated when the
2306
- * host swaps the agents array (see `agentsChanged` / `deleteDriver`), so a
2307
- * driver-owned buffer would lose the timeline mid-session. The `stateKey`
2308
- * outlives the driver.
2309
- * - **Stays out of redux reactivity.** These appends never drive the UI, so
2310
- * there's no reason to pay immutable-reducer cost or flood the Redux DevTools
2311
- * action log with debug noise.
2312
- *
2313
- * Surfaced in `getDebugLog().timeline`, merged chronologically with messages and
2314
- * turn snapshots. Ring-buffered — the oldest non-`high` events are evicted first
2315
- * while `high`-importance failure events are retained — so a long-lived session
2316
- * stays bounded in normal use without ever dropping a failure signal.
2317
- *
2318
- * @internal
2319
- */
2320
- /**
2321
- * Catalogue of meta event names. This is the documented surface — extend it as
2322
- * new events are wired in (Tier 2/3 lifecycle, interaction, provider events).
2323
- */
2324
- declare type MetaEventType = 'assistant.connected' | 'assistant.disconnected' | 'assistant.popout' | 'assistant.popin' | 'driver.created' | 'driver.wired' | 'driver.unwired' | 'state.changed' | 'turn.start' | 'turn.end' | 'turn.retry' | 'turn.error' | 'tool.failed' | 'tool.unresolved' | 'subagent.started' | 'subagent.completed' | 'subagent.failed' | 'agent.handoff' | 'agent.pinned' | 'agent.unpinned' | 'provider.selected' | 'interaction.requested' | 'interaction.resolved' | 'context.updated' | 'context.threshold-crossed' | 'context.condensed' | 'panel.toggled' | 'attachment.added' | 'file.read-failed' | 'suggestions.failed';
2325
-
2326
2610
  export { ModelTagAppearance }
2327
2611
 
2328
2612
  /**
@@ -2368,6 +2652,13 @@ export declare class OrchestratingDriver extends EventTarget implements AiDriver
2368
2652
  * choice.
2369
2653
  */
2370
2654
  private flowOwnerAgentName;
2655
+ /**
2656
+ * Per-agent restored state for a rehydrated session, keyed by agent name.
2657
+ * Primed by the host on restore; each entry is passed to that agent's
2658
+ * `onActivate` as `ctx.restored` on its next activation, then deleted so a
2659
+ * later re-activation starts fresh.
2660
+ */
2661
+ private restoredAgentStates;
2371
2662
  activeAgent?: AgentConfig;
2372
2663
  constructor(providerRegistry: AIProviderRegistry, agents: AgentConfig[], options?: {
2373
2664
  sessionKey?: string;
@@ -2402,11 +2693,19 @@ export declare class OrchestratingDriver extends EventTarget implements AiDriver
2402
2693
  setFlowOwner(name: string | null): void;
2403
2694
  loadHistory(messages: ChatMessage[]): void;
2404
2695
  getRawHistory(): readonly ChatMessage[];
2696
+ /** {@inheritDoc AiDriver.compact} */
2697
+ compact(): Promise<ChatMessage | null>;
2698
+ /** {@inheritDoc AiDriver.canCompact} */
2699
+ canCompact(): boolean;
2405
2700
  /** Delegates to the inner {@link ChatDriver} — turns are captured there. */
2406
2701
  getTurnSnapshots(): ReadonlyArray<TurnSnapshot>;
2407
2702
  getSuggestions(history: ChatMessage[], prompt: string, count: number, allAgentInfo?: AllAgentSummary[]): Promise<string[]>;
2408
2703
  sendMessage(input: string, attachments?: ChatAttachment[]): Promise<ChatDriverResult>;
2409
2704
  continueFromHistory(transientPrimer?: ChatMessage[]): Promise<ChatDriverResult>;
2705
+ /** {@inheritDoc AiDriver.primeRestoredAgentState} */
2706
+ primeRestoredAgentState(snapshots: Record<string, unknown>): void;
2707
+ /** {@inheritDoc AiDriver.getActiveAgent} */
2708
+ getActiveAgent(): AgentConfig | undefined;
2410
2709
  private applyAgent;
2411
2710
  /**
2412
2711
  * Release the current stateful agent: fire `onDeactivate`, clear the
@@ -2445,6 +2744,75 @@ export declare class OrchestratingDriver extends EventTarget implements AiDriver
2445
2744
  private appendInlineMessage;
2446
2745
  }
2447
2746
 
2747
+ /**
2748
+ * Schema version of the persisted session shape. Bump on an incompatible
2749
+ * change; a snapshot whose `version` doesn't match is discarded on load rather
2750
+ * than risk feeding a stale shape into restore.
2751
+ *
2752
+ * @public
2753
+ */
2754
+ export declare const PERSISTED_SESSION_VERSION = 1;
2755
+
2756
+ /**
2757
+ * A durable, restorable snapshot of one chat session — the *restorable core* of
2758
+ * the debug log (GENC-1351 §5.1/D1), captured losslessly and independently of
2759
+ * the diagnostic timeline. Written by a `SessionPersistenceProvider` and read
2760
+ * back on page-reload restore.
2761
+ *
2762
+ * @public
2763
+ */
2764
+ export declare interface PersistedSession {
2765
+ /** Schema version — see {@link PERSISTED_SESSION_VERSION}. */
2766
+ version: number;
2767
+ /** ISO timestamp the snapshot was written. */
2768
+ savedAt: string;
2769
+ /** `window.location.host` at save time — restore refuses a cross-host snapshot. */
2770
+ host: string;
2771
+ /** The session this snapshot belongs to (the assistant's state key). */
2772
+ sessionKey: string;
2773
+ /** Full conversation transcript (`driver.getRawHistory()`) — the source of truth. */
2774
+ messages: ChatMessage[];
2775
+ /** Name of the agent active at save time, if any. */
2776
+ activeAgentName?: string;
2777
+ /** User's pinned agent (sticky picker choice); `null` = Auto. */
2778
+ pinnedAgentName: string | null;
2779
+ /** Agent that owned a guided flow at save time; `null` = none. */
2780
+ flowOwnerAgentName: string | null;
2781
+ /** Aggregated USD cost across the session. */
2782
+ sessionCostUsd: number;
2783
+ /** Provider-reported context-window usage on the last turn. */
2784
+ contextTokens?: number;
2785
+ /** Context-window limit for the active model. */
2786
+ contextLimit?: number;
2787
+ /** Active model id (e.g. `claude-sonnet-4-6`). */
2788
+ activeModel?: string;
2789
+ /** Name of the provider used on the last turn. */
2790
+ activeProviderName?: string;
2791
+ /**
2792
+ * Per-stateful-agent serialized state images (each from an agent's
2793
+ * `serialize()`), keyed by agent name. Handed back to the agent's
2794
+ * `init({ restored })` on restore. Typically holds at most the active
2795
+ * flow-owner — other stateful agents are disposed when switched away. The
2796
+ * value shape is the agent's own, hence `unknown`.
2797
+ */
2798
+ agentSnapshots: Record<string, unknown>;
2799
+ /**
2800
+ * Interrupted-flow marker (GENC-1351 §5.9). Present when the session was saved
2801
+ * while an agent declared its current state non-resumable (`resumable === false`).
2802
+ * The **conversation is still persisted and restored in full** — only the running
2803
+ * agent's flow-state is dropped (`agentSnapshots` empty, `flowOwnerAgentName`
2804
+ * null), so restore does not rehydrate the mid-flight flow. On restore the
2805
+ * assistant appends `message` as a normal assistant bubble and pre-fills the
2806
+ * composer with `prompt` so the user can re-run it.
2807
+ */
2808
+ interrupted?: {
2809
+ /** Shown as an assistant message on return. */
2810
+ message: string;
2811
+ /** The prompt that started the flow, pre-filled into the composer on return. */
2812
+ prompt?: string;
2813
+ };
2814
+ }
2815
+
2448
2816
  /**
2449
2817
  * Controls the pop-out button shown in the assistant header.
2450
2818
  * - `"expand"` — assistant is embedded in the bubble dialog; button expands it to a layout panel.
@@ -2487,6 +2855,147 @@ declare interface ResolvedCostHistoryConfig {
2487
2855
  badgeLabel: string;
2488
2856
  }
2489
2857
 
2858
+ /**
2859
+ * Restore a foundation-state-machine instance from a snapshot produced by the
2860
+ * default serializer (or `machine.getPersistedSnapshot()`). Call inside a
2861
+ * stateful agent's `init` to resume the machine in its exact prior place:
2862
+ *
2863
+ * ```ts
2864
+ * init: ({ restored }) => {
2865
+ * const machine = new MyMachine();
2866
+ * restoreMachine(machine, restored); // resume, or no-op on a fresh start
2867
+ * return { machine };
2868
+ * }
2869
+ * ```
2870
+ *
2871
+ * No-ops when there is nothing to restore (a fresh session), leaving the
2872
+ * freshly-constructed machine in its initial state.
2873
+ *
2874
+ * @param machine - the machine to restore (already constructed/started).
2875
+ * @param restored - the agent's serialized image (`ctx.restored` in `init`).
2876
+ * @param key - the property the machine occupies in the snapshot; defaults to
2877
+ * `'machine'` to match the conventional `{ machine }` state bag.
2878
+ * @beta
2879
+ */
2880
+ export declare function restoreMachine(machine: {
2881
+ stop: () => void;
2882
+ start: (options?: {
2883
+ state?: unknown;
2884
+ }) => void;
2885
+ }, restored: unknown, key?: string): void;
2886
+
2887
+ /**
2888
+ * `detail` of the `AiAssistantEvent.SessionCleared` event. Captured *before*
2889
+ * teardown so a host can tidy up whatever the active agent was working on
2890
+ * (generated files, server-side scratch, …). `agentSnapshot` is the agent's
2891
+ * `serialize()` output (a state-machine image for machine-backed agents).
2892
+ *
2893
+ * @beta
2894
+ */
2895
+ export declare interface SessionClearedDetail {
2896
+ sessionKey: string | undefined;
2897
+ agentName: string | undefined;
2898
+ agentSnapshot: unknown;
2899
+ }
2900
+
2901
+ /**
2902
+ * Host-supplied persistence configuration, passed to the assistant via its
2903
+ * `persistence` property. Persistence stays inert unless `enabled` is true and
2904
+ * a `provider` is set — so existing consumers are unaffected (GENC-1351 D2/D3).
2905
+ *
2906
+ * @public
2907
+ */
2908
+ export declare interface SessionPersistenceConfig {
2909
+ /** Master switch — persistence does nothing unless this is true. */
2910
+ enabled?: boolean;
2911
+ /** Storage backend. Required for persistence to take effect. */
2912
+ provider?: SessionPersistenceProvider;
2913
+ }
2914
+
2915
+ /**
2916
+ * Storage backend for chat-session persistence. The library ships this
2917
+ * interface only and wires nothing by default; the host app provides an
2918
+ * implementation and opts in via `chatConfig` (GENC-1351 §5.2/D2). Every method
2919
+ * is async so a server-backed provider satisfies the same contract as a
2920
+ * browser-storage one.
2921
+ *
2922
+ * @public
2923
+ */
2924
+ export declare interface SessionPersistenceProvider {
2925
+ /**
2926
+ * Minimum milliseconds between autosaves for this backend — a throttle the
2927
+ * assistant applies to its "save on every transcript change" signal. `0`
2928
+ * means save as soon as the current tick settles (coalescing only writes
2929
+ * within the same tick), which is right for synchronous, cheap storage like
2930
+ * `sessionStorage`/`localStorage`. A network/server backend should set a
2931
+ * higher value (e.g. 1000–2000) so it doesn't hammer the wire mid tool-loop.
2932
+ *
2933
+ * **Required** — not optional — so every implementation makes a deliberate
2934
+ * choice for its own write-cost profile rather than inheriting a guess.
2935
+ */
2936
+ saveDebounceMs: number;
2937
+ /** Load the snapshot for `sessionKey`, or `null` if none / unreadable. */
2938
+ load(sessionKey: string): Promise<PersistedSession | null>;
2939
+ /** Persist `snapshot` for `sessionKey`, overwriting any existing one. */
2940
+ save(sessionKey: string, snapshot: PersistedSession): Promise<void>;
2941
+ /** Remove any stored snapshot for `sessionKey`. */
2942
+ clear(sessionKey: string): Promise<void>;
2943
+ /**
2944
+ * Load the user's remembered UI preferences for `sessionKey` (GENC-1351) — the
2945
+ * "remember chat" toggle plus the cog-menu display switches. Stored
2946
+ * **independently of the session snapshot** (survives `clear`) and **independently
2947
+ * of the `enabled` toggle** — a user's display choices persist whether or not
2948
+ * they remember the chat. `undefined` means none were ever saved → the host's
2949
+ * configured `chatConfig.ui` defaults apply. Only the fields the user has changed
2950
+ * are present; absent fields keep their config default. Optional: a provider that
2951
+ * omits it simply doesn't remember preferences across reloads.
2952
+ */
2953
+ loadPreferences?(sessionKey: string): Promise<SessionPreferences | undefined>;
2954
+ /** Persist the user's UI preferences for `sessionKey` (kept across `clear`). */
2955
+ savePreferences?(sessionKey: string, preferences: SessionPreferences): Promise<void>;
2956
+ /**
2957
+ * Server-saved diagnostics (GENC-1351 §5.8) — a **forward-only append** stream
2958
+ * that lets the downloadable debug log span the whole session lifetime, not just
2959
+ * the current page load. Optional and **capacious-backends-only**: `WebStorage`
2960
+ * omits it (the log dwarfs the restore core), so the feature is simply off there.
2961
+ * The element emits *what happened* (new entries since the last flush); the
2962
+ * provider owns *how it's filed* (one object per session / per run / per day —
2963
+ * its call). Best-effort: a failed write must never affect the chat.
2964
+ *
2965
+ * Captured **independently of the `enabled` toggle** (like preferences): the
2966
+ * forensic log is orthogonal to whether the *chat* is remembered, so it runs
2967
+ * whenever a provider implements this — even with "remember chat" off.
2968
+ */
2969
+ appendDiagnostics?(sessionKey: string, entries: DiagnosticEntry[]): Promise<void>;
2970
+ /** Load the full diagnostics stream for `sessionKey` (all appends, any run), for download-reassembly. */
2971
+ loadDiagnostics?(sessionKey: string): Promise<DiagnosticEntry[]>;
2972
+ /** Hard-delete the diagnostics stream for `sessionKey`. Host/GDPR use — NOT wired to the UI Clear. */
2973
+ clearDiagnostics?(sessionKey: string): Promise<void>;
2974
+ /**
2975
+ * Min ms between diagnostics appends — coarser than `saveDebounceMs` because
2976
+ * the log is heavy. Defaults to a sensible coarse value if omitted.
2977
+ */
2978
+ diagnosticsDebounceMs?: number;
2979
+ }
2980
+
2981
+ /**
2982
+ * User-changeable settings that persist across reloads, independently of the chat
2983
+ * snapshot and of the "remember chat" toggle (GENC-1351). All optional — an absent
2984
+ * field keeps its `chatConfig.ui` default rather than being forced off.
2985
+ *
2986
+ * @public
2987
+ */
2988
+ export declare interface SessionPreferences {
2989
+ /** "Remember chat" — whether the session snapshot itself is persisted. */
2990
+ enabled?: boolean;
2991
+ showToolCalls?: boolean;
2992
+ showThinkingSteps?: boolean;
2993
+ showNarration?: boolean;
2994
+ showAgentSwitchIndicator?: boolean;
2995
+ /** Enabled loading-animation ids (`AiAssistantAnimation` values, as plain strings). */
2996
+ animations?: string[];
2997
+ }
2998
+
2490
2999
  /** Settings vs Cost tab identifiers for the modal tab bar. */
2491
3000
  declare type SettingsModalTab = 'settings' | 'cost';
2492
3001
 
@@ -2576,6 +3085,10 @@ export declare interface StatefulAgentInit<S> {
2576
3085
  /**
2577
3086
  * Construct the agent-scoped state. Called by the framework when this agent
2578
3087
  * becomes active (`onActivate`). Awaited before the agent's first turn runs.
3088
+ *
3089
+ * On a persisted-session restore, `ctx.restored` carries this agent's previous
3090
+ * `serialize` output — rebuild from it (e.g. via `restoreMachine`), or start
3091
+ * fresh when it is `undefined`.
2579
3092
  */
2580
3093
  init: (ctx: AgentLifecycleContext) => S | Promise<S>;
2581
3094
  /**
@@ -2689,8 +3202,49 @@ export declare interface StatefulAgentInit<S> {
2689
3202
  * Return value must be JSON-serializable.
2690
3203
  */
2691
3204
  getDebugSnapshot?: (state: S) => unknown;
3205
+ /**
3206
+ * Lossless serializer for session persistence — infra-agnostic. Return any
3207
+ * JSON/structured-clone-safe image of `state`.
3208
+ * • Machine agents (`{ machine }`): omit — the default snapshots every
3209
+ * machine-shaped property via `getPersistedSnapshot()`.
3210
+ * • Plain-data agents (e.g. `{ plan, cursor }`): omit too — the default
3211
+ * returns plain state as-is. Provide one only when the state holds
3212
+ * something the default can't capture.
3213
+ * Distinct from `getDebugSnapshot` (which may be lossy by design). Pair with
3214
+ * `init` reading `ctx.restored` to rebuild.
3215
+ */
3216
+ serialize?: (state: S) => unknown;
3217
+ /**
3218
+ * Whether the agent's current state is resumable — worth persisting so the
3219
+ * session restores mid-flow (GENC-1351 §5.9). Receives the **live** state bag
3220
+ * `S` (like the other per-turn resolvers), so a machine agent gates on its step
3221
+ * directly: `resumable: ({ state }) => state.machine.state !== 'confirm'`.
3222
+ * Return `false` for a point that shouldn't resume — the session isn't persisted,
3223
+ * and on return the assistant shows {@link StatefulAgentInit.notResumableMessage}
3224
+ * (or a default) and pre-fills the composer with the prompt that started the flow.
3225
+ * Only consulted with persistence enabled; a thrown error is treated as `true`
3226
+ * (fail-safe — never drop a resumable chat on a predicate bug).
3227
+ */
3228
+ resumable?: (ctx: StatefulAgentPersistenceContext<S>) => boolean | Promise<boolean>;
3229
+ /**
3230
+ * Message shown on return when {@link StatefulAgentInit.resumable} returned
3231
+ * `false`. Falls back to a built-in default when omitted.
3232
+ */
3233
+ notResumableMessage?: string;
2692
3234
  }
2693
3235
 
3236
+ /**
3237
+ * Context passed to a stateful agent's `resumable` predicate (GENC-1351 §5.9) —
3238
+ * the standard {@link AgentPersistenceContext} but with `state` as the **live**
3239
+ * state bag `S` (not the serialized image), so a machine agent can gate on its
3240
+ * current step directly.
3241
+ *
3242
+ * @beta
3243
+ */
3244
+ export declare type StatefulAgentPersistenceContext<S> = Omit<AgentPersistenceContext, 'state'> & {
3245
+ state: S;
3246
+ };
3247
+
2694
3248
  /**
2695
3249
  * A brief, professional fallback agent. States what is available without
2696
3250
  * elaboration. The `{{agents}}` placeholder is replaced at runtime by
@@ -3001,4 +3555,39 @@ export declare type UnresolvedToolInput = (ctx: UnresolvedToolContext) => string
3001
3555
  /** Person silhouette — default user avatar. */
3002
3556
  export declare const userIconSvg = "<svg viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z\" fill=\"currentColor\"/></svg>";
3003
3557
 
3558
+ /**
3559
+ * A {@link SessionPersistenceProvider} backed by a Web Storage area. Both
3560
+ * `window.sessionStorage` and `window.localStorage` implement the `Storage`
3561
+ * API, so one class serves both: point it at `sessionStorage` for
3562
+ * refresh-survival that clears on tab close (the showcase default, O6), or at
3563
+ * `localStorage` for durable local persistence.
3564
+ *
3565
+ * Opt-in: a host constructs it and passes it through `chatConfig`; the library
3566
+ * never instantiates it on its own.
3567
+ *
3568
+ * @public
3569
+ */
3570
+ export declare class WebStorageSessionProvider implements SessionPersistenceProvider {
3571
+ private readonly storage;
3572
+ private readonly keyPrefix;
3573
+ /**
3574
+ * Web storage is synchronous and cheap, so the default is `0` — save as
3575
+ * soon as the tick settles, no throttle. Override via `options.saveDebounceMs`
3576
+ * (e.g. if pointing at `localStorage` and you'd rather coalesce large writes).
3577
+ */
3578
+ readonly saveDebounceMs: number;
3579
+ constructor(storage: Storage, options?: {
3580
+ keyPrefix?: string;
3581
+ saveDebounceMs?: number;
3582
+ });
3583
+ private storageKey;
3584
+ /** Preferences key, namespaced apart from the session key so `clear` leaves it. */
3585
+ private preferencesKey;
3586
+ load(sessionKey: string): Promise<PersistedSession | null>;
3587
+ save(sessionKey: string, snapshot: PersistedSession): Promise<void>;
3588
+ clear(sessionKey: string): Promise<void>;
3589
+ loadPreferences(sessionKey: string): Promise<SessionPreferences | undefined>;
3590
+ savePreferences(sessionKey: string, preferences: SessionPreferences): Promise<void>;
3591
+ }
3592
+
3004
3593
  export { }