@genesislcap/ai-assistant 14.488.2-GENC-1351.8 → 14.488.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 (155) hide show
  1. package/dist/ai-assistant.api.json +2024 -5141
  2. package/dist/ai-assistant.d.ts +176 -791
  3. package/dist/custom-elements.json +297 -1327
  4. package/dist/dts/components/ai-driver/ai-driver.d.ts +8 -32
  5. package/dist/dts/components/ai-driver/ai-driver.d.ts.map +1 -1
  6. package/dist/dts/components/chat-driver/chat-driver.d.ts +29 -13
  7. package/dist/dts/components/chat-driver/chat-driver.d.ts.map +1 -1
  8. package/dist/dts/components/chat-interaction-wrapper/chat-interaction-wrapper.d.ts +7 -0
  9. package/dist/dts/components/chat-interaction-wrapper/chat-interaction-wrapper.d.ts.map +1 -1
  10. package/dist/dts/components/orchestrating-driver/orchestrating-driver.d.ts +4 -15
  11. package/dist/dts/components/orchestrating-driver/orchestrating-driver.d.ts.map +1 -1
  12. package/dist/dts/components/popout-manager/popout-manager.d.ts +9 -37
  13. package/dist/dts/components/popout-manager/popout-manager.d.ts.map +1 -1
  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 +0 -70
  17. package/dist/dts/config/config.d.ts.map +1 -1
  18. package/dist/dts/config/define-stateful-agent.d.ts +1 -73
  19. package/dist/dts/config/define-stateful-agent.d.ts.map +1 -1
  20. package/dist/dts/index.d.ts +0 -1
  21. package/dist/dts/index.d.ts.map +1 -1
  22. package/dist/dts/main/main.d.ts +87 -249
  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 +0 -55
  27. package/dist/dts/main/main.types.d.ts.map +1 -1
  28. package/dist/dts/state/ai-assistant-slice.d.ts +0 -66
  29. package/dist/dts/state/ai-assistant-slice.d.ts.map +1 -1
  30. package/dist/dts/state/debug-event-log.d.ts +1 -1
  31. package/dist/dts/state/debug-event-log.d.ts.map +1 -1
  32. package/dist/dts/state/session-store.d.ts +0 -6
  33. package/dist/dts/state/session-store.d.ts.map +1 -1
  34. package/dist/dts/utils/history-transform.d.ts +0 -38
  35. package/dist/dts/utils/history-transform.d.ts.map +1 -1
  36. package/dist/dts/utils/message-partition.d.ts +0 -27
  37. package/dist/dts/utils/message-partition.d.ts.map +1 -1
  38. package/dist/esm/components/chat-driver/chat-driver.js +64 -90
  39. package/dist/esm/components/chat-driver/chat-driver.test.js +45 -0
  40. package/dist/esm/components/chat-interaction-wrapper/chat-interaction-wrapper.js +35 -5
  41. package/dist/esm/components/chat-interaction-wrapper/chat-interaction-wrapper.test.js +62 -0
  42. package/dist/esm/components/orchestrating-driver/orchestrating-driver.js +14 -32
  43. package/dist/esm/components/popout-manager/popout-manager.js +27 -76
  44. package/dist/esm/components/settings-modal/settings-modal.styles.js +0 -24
  45. package/dist/esm/components/settings-modal/settings-modal.template.js +1 -14
  46. package/dist/esm/config/define-stateful-agent.js +0 -81
  47. package/dist/esm/index.js +0 -1
  48. package/dist/esm/main/main.js +200 -755
  49. package/dist/esm/main/main.styles.js +0 -55
  50. package/dist/esm/main/main.template.js +10 -94
  51. package/dist/esm/main/main.types.js +0 -27
  52. package/dist/esm/state/ai-assistant-slice.js +25 -71
  53. package/dist/esm/state/debug-event-log.js +0 -9
  54. package/dist/esm/utils/history-transform.js +0 -101
  55. package/dist/esm/utils/message-partition.js +2 -30
  56. package/dist/esm/utils/message-partition.test.js +1 -20
  57. package/dist/tsconfig.tsbuildinfo +1 -1
  58. package/package.json +17 -17
  59. package/src/components/ai-driver/ai-driver.ts +17 -36
  60. package/src/components/chat-driver/chat-driver.test.ts +71 -0
  61. package/src/components/chat-driver/chat-driver.ts +69 -92
  62. package/src/components/chat-interaction-wrapper/chat-interaction-wrapper.test.ts +81 -0
  63. package/src/components/chat-interaction-wrapper/chat-interaction-wrapper.ts +40 -5
  64. package/src/components/orchestrating-driver/orchestrating-driver.ts +18 -36
  65. package/src/components/popout-manager/popout-manager.ts +28 -82
  66. package/src/components/settings-modal/settings-modal.styles.ts +0 -24
  67. package/src/components/settings-modal/settings-modal.template.ts +1 -27
  68. package/src/config/config.ts +0 -71
  69. package/src/config/define-stateful-agent.ts +0 -134
  70. package/src/index.ts +0 -1
  71. package/src/main/main.styles.ts +0 -55
  72. package/src/main/main.template.ts +11 -121
  73. package/src/main/main.ts +179 -738
  74. package/src/main/main.types.ts +0 -59
  75. package/src/state/ai-assistant-slice.ts +25 -120
  76. package/src/state/debug-event-log.ts +1 -20
  77. package/src/utils/history-transform.ts +0 -117
  78. package/src/utils/message-partition.test.ts +1 -27
  79. package/src/utils/message-partition.ts +2 -41
  80. package/dist/dts/components/chat-driver/chat-driver.compact.test.d.ts +0 -2
  81. package/dist/dts/components/chat-driver/chat-driver.compact.test.d.ts.map +0 -1
  82. package/dist/dts/components/orchestrating-driver/orchestrating-driver.pin.test.d.ts +0 -2
  83. package/dist/dts/components/orchestrating-driver/orchestrating-driver.pin.test.d.ts.map +0 -1
  84. package/dist/dts/state/ai-assistant-slice.test.d.ts +0 -2
  85. package/dist/dts/state/ai-assistant-slice.test.d.ts.map +0 -1
  86. package/dist/dts/state/persistence/diagnostics-cursors.d.ts +0 -40
  87. package/dist/dts/state/persistence/diagnostics-cursors.d.ts.map +0 -1
  88. package/dist/dts/state/persistence/diagnostics.d.ts +0 -58
  89. package/dist/dts/state/persistence/diagnostics.d.ts.map +0 -1
  90. package/dist/dts/state/persistence/diagnostics.test.d.ts +0 -2
  91. package/dist/dts/state/persistence/diagnostics.test.d.ts.map +0 -1
  92. package/dist/dts/state/persistence/index.d.ts +0 -7
  93. package/dist/dts/state/persistence/index.d.ts.map +0 -1
  94. package/dist/dts/state/persistence/persister-registry.d.ts +0 -17
  95. package/dist/dts/state/persistence/persister-registry.d.ts.map +0 -1
  96. package/dist/dts/state/persistence/session-persistence-provider.d.ts +0 -132
  97. package/dist/dts/state/persistence/session-persistence-provider.d.ts.map +0 -1
  98. package/dist/dts/state/persistence/session-persistence-provider.test.d.ts +0 -2
  99. package/dist/dts/state/persistence/session-persistence-provider.test.d.ts.map +0 -1
  100. package/dist/dts/state/persistence/session-persistence.integration.test.d.ts +0 -2
  101. package/dist/dts/state/persistence/session-persistence.integration.test.d.ts.map +0 -1
  102. package/dist/dts/state/persistence/session-persister.d.ts +0 -161
  103. package/dist/dts/state/persistence/session-persister.d.ts.map +0 -1
  104. package/dist/dts/state/persistence/session-persister.test.d.ts +0 -2
  105. package/dist/dts/state/persistence/session-persister.test.d.ts.map +0 -1
  106. package/dist/dts/state/persistence/session-snapshot.d.ts +0 -209
  107. package/dist/dts/state/persistence/session-snapshot.d.ts.map +0 -1
  108. package/dist/dts/state/persistence/session-snapshot.test.d.ts +0 -2
  109. package/dist/dts/state/persistence/session-snapshot.test.d.ts.map +0 -1
  110. package/dist/dts/utils/history-transform.test.d.ts +0 -2
  111. package/dist/dts/utils/history-transform.test.d.ts.map +0 -1
  112. package/dist/dts/utils/resolve-preference-baseline.d.ts +0 -43
  113. package/dist/dts/utils/resolve-preference-baseline.d.ts.map +0 -1
  114. package/dist/dts/utils/resolve-preference-baseline.test.d.ts +0 -2
  115. package/dist/dts/utils/resolve-preference-baseline.test.d.ts.map +0 -1
  116. package/dist/dts/utils/with-timeout.d.ts +0 -12
  117. package/dist/dts/utils/with-timeout.d.ts.map +0 -1
  118. package/dist/esm/components/chat-driver/chat-driver.compact.test.js +0 -93
  119. package/dist/esm/components/orchestrating-driver/orchestrating-driver.pin.test.js +0 -48
  120. package/dist/esm/state/ai-assistant-slice.test.js +0 -65
  121. package/dist/esm/state/persistence/diagnostics-cursors.js +0 -34
  122. package/dist/esm/state/persistence/diagnostics.js +0 -81
  123. package/dist/esm/state/persistence/diagnostics.test.js +0 -72
  124. package/dist/esm/state/persistence/index.js +0 -3
  125. package/dist/esm/state/persistence/persister-registry.js +0 -41
  126. package/dist/esm/state/persistence/session-persistence-provider.js +0 -95
  127. package/dist/esm/state/persistence/session-persistence-provider.test.js +0 -110
  128. package/dist/esm/state/persistence/session-persistence.integration.test.js +0 -109
  129. package/dist/esm/state/persistence/session-persister.js +0 -589
  130. package/dist/esm/state/persistence/session-persister.test.js +0 -239
  131. package/dist/esm/state/persistence/session-snapshot.js +0 -231
  132. package/dist/esm/state/persistence/session-snapshot.test.js +0 -243
  133. package/dist/esm/utils/history-transform.test.js +0 -137
  134. package/dist/esm/utils/resolve-preference-baseline.js +0 -53
  135. package/dist/esm/utils/resolve-preference-baseline.test.js +0 -69
  136. package/dist/esm/utils/with-timeout.js +0 -28
  137. package/src/components/chat-driver/chat-driver.compact.test.ts +0 -131
  138. package/src/components/orchestrating-driver/orchestrating-driver.pin.test.ts +0 -76
  139. package/src/state/ai-assistant-slice.test.ts +0 -82
  140. package/src/state/persistence/diagnostics-cursors.ts +0 -66
  141. package/src/state/persistence/diagnostics.test.ts +0 -95
  142. package/src/state/persistence/diagnostics.ts +0 -103
  143. package/src/state/persistence/index.ts +0 -10
  144. package/src/state/persistence/persister-registry.ts +0 -49
  145. package/src/state/persistence/session-persistence-provider.test.ts +0 -136
  146. package/src/state/persistence/session-persistence-provider.ts +0 -202
  147. package/src/state/persistence/session-persistence.integration.test.ts +0 -134
  148. package/src/state/persistence/session-persister.test.ts +0 -325
  149. package/src/state/persistence/session-persister.ts +0 -635
  150. package/src/state/persistence/session-snapshot.test.ts +0 -339
  151. package/src/state/persistence/session-snapshot.ts +0 -332
  152. package/src/utils/history-transform.test.ts +0 -197
  153. package/src/utils/resolve-preference-baseline.test.ts +0 -84
  154. package/src/utils/resolve-preference-baseline.ts +0 -80
  155. package/src/utils/with-timeout.ts +0 -24
@@ -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 type { ChatToolChoice } from '@genesislcap/foundation-ai';
12
- import type { ChatToolDefinition } from '@genesislcap/foundation-ai';
11
+ import { ChatToolChoice } from '@genesislcap/foundation-ai';
12
+ import { 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,40 +217,6 @@ 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;
254
220
  }
255
221
 
256
222
  /**
@@ -340,41 +306,6 @@ export declare interface AiAssistantAnimationDef {
340
306
  category: string;
341
307
  }
342
308
 
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
-
378
309
  /**
379
310
  * State of the AI assistant component.
380
311
  *
@@ -424,18 +355,12 @@ export declare interface AiChatWidget {
424
355
  */
425
356
  export declare interface AiDockProvider {
426
357
  /**
427
- * Called when the user expands the bubble. The provider **moves the given
428
- * element** into its layout — e.g. via a layout factory that re-parents it into
429
- * a pane. It is the ONE live assistant element, so it must be moved by reference,
430
- * **not cloned** (a clone would be a second, dead instance). Session state
431
- * survives the move because it lives in module-level registries, not the element.
358
+ * Called when the user expands the bubble. The provider is responsible for inserting
359
+ * the element into its layout. State is held in the session store and restored
360
+ * automatically when the element connects.
432
361
  */
433
362
  onDock(element: HTMLElement): Promise<void>;
434
- /**
435
- * Called when the user collapses the panel or before navigation. By the time
436
- * this runs the manager has already moved the assistant element back into the
437
- * bubble, so the provider only needs to tear down its now-empty layout slot.
438
- */
363
+ /** Called when the user collapses the panel or before navigation. */
439
364
  onUndock(): Promise<void>;
440
365
  /**
441
366
  * Called by `collapseIfDocked` before navigation. The provider is responsible for
@@ -476,41 +401,10 @@ export declare interface AiDriver extends EventTarget {
476
401
  * Seed the driver's message history (called on state restore / pop-in).
477
402
  */
478
403
  loadHistory(messages: ChatMessage[]): void;
479
- /**
480
- * Prime per-agent restored state for a session being rehydrated. Each entry
481
- * (keyed by agent name) is handed to that agent's `onActivate`/`init` as
482
- * `ctx.restored` on its next activation, then consumed. Optional — only
483
- * multi-agent drivers that own agent activation implement it.
484
- */
485
- primeRestoredAgentState?(snapshots: Record<string, unknown>): void;
486
404
  /**
487
405
  * Return the full, unredacted conversation history.
488
406
  */
489
407
  getRawHistory?(): readonly ChatMessage[];
490
- /**
491
- * The live `AgentConfig` currently active in the driver — the instance whose
492
- * `onActivate` ran, so its `serialize`/`getDebugSnapshot` closures hold live
493
- * state. Prefer this over looking the agent up in the host's `agents` array,
494
- * which may mint fresh, never-activated configs. Optional — only drivers that
495
- * retain the active config implement it.
496
- */
497
- getActiveAgent?(): AgentConfig | undefined;
498
- /**
499
- * Destructively compact older conversation turns into a single
500
- * `compacted-summary` message (GENC-1351 §5.7), summarizing them via the
501
- * default provider's one-shot `prompt()`. Atomic: history changes only on
502
- * success. Resolves to the created summary message, or `null` when there is
503
- * nothing worth compacting or the provider cannot summarize. Optional — only
504
- * drivers that own history implement it.
505
- */
506
- compact?(): Promise<ChatMessage | null>;
507
- /**
508
- * Whether `compact()` would compact something right now — a summarizable run of
509
- * older turns exists behind a clean boundary. The UI gates its "Compact"
510
- * affordance on this, so the button reflects the exact history `compact()` acts
511
- * on (GENC-1351). Optional — only history-owning drivers implement it.
512
- */
513
- canCompact?(): boolean;
514
408
  /**
515
409
  * Returns true if the driver is currently processing a request.
516
410
  */
@@ -546,6 +440,14 @@ export declare interface AiDriver extends EventTarget {
546
440
  * Optional; the host wires the stop button to it when present.
547
441
  */
548
442
  cancel?(): void;
443
+ /** Register an assistant view (host) wired to this driver. */
444
+ registerHost?(hostId: string): void;
445
+ /** Deregister a host on unwire/disconnect. */
446
+ unregisterHost?(hostId: string): void;
447
+ /** Record the host whose subtree the user most recently interacted in (owner election signal). */
448
+ setActiveHost?(hostId: string): void;
449
+ /** First-writer-wins latch: the first host to claim an interaction id runs its side effect. */
450
+ claimSideEffect?(interactionId: string, hostId: string): boolean;
549
451
  }
550
452
 
551
453
  /**
@@ -626,20 +528,6 @@ export declare const ANIMATION_DEFS: {
626
528
  };
627
529
  };
628
530
 
629
- /**
630
- * Reassemble diagnostic entries into the `{ readme, timeline, meta }` debug-log
631
- * shape (GENC-1351 §5.8). `timeline` = the `message`/`turn`/`event` entries sorted
632
- * by ISO `timestamp` (kind-rank tie-break). `meta` = the **newest** `meta-snapshot`'s
633
- * block only — a "state at export" photo, matching the single-page log. The older
634
- * snapshots are intentionally dropped: the per-turn evolution they would show is
635
- * already in the timeline (`turn.agentSnapshot` + `context.updated` events), so
636
- * keeping them would just repeat the bulky, near-static `agentSummary`. `readme` =
637
- * the passed (current) constant. Pure — reused for both the live current-page log
638
- * and the reassembled lifetime log stitched from the persisted stream, so both
639
- * come out shape-identical.
640
- */
641
- export declare function assembleDebugLog(entries: DiagnosticEntry[], readme: readonly string[]): DebugLog;
642
-
643
531
  /**
644
532
  * App-supplied settings for the platform settings modal UI Builder section.
645
533
  * Register a concrete implementation on the DI token at app bootstrap; the
@@ -854,43 +742,6 @@ declare interface BaseAgentConfig {
854
742
  * @beta
855
743
  */
856
744
  getDebugSnapshot?: () => unknown;
857
- /**
858
- * Returns a lossless, JSON-serializable image of the agent's state for session
859
- * persistence — distinct from `getDebugSnapshot`, which may abbreviate for
860
- * readability. Pass the value back to the agent on restore (as
861
- * `ctx.restored` in its `init`) to resume. {@link defineStatefulAgent} wires a
862
- * default that snapshots any machine-shaped state via `getPersistedSnapshot()`
863
- * and returns plain state as-is.
864
- *
865
- * @beta
866
- */
867
- serialize?: () => unknown;
868
- /**
869
- * Whether the agent's current state is resumable — i.e. worth persisting so the
870
- * session can be restored mid-flow (GENC-1351 §5.9). Consulted at save time on
871
- * the active agent (the flow-owner during a locked flow). Return `true`
872
- * (or leave the field absent) to persist and resume normally; return `false`
873
- * for a point that shouldn't be resumed — the session is not persisted, and on
874
- * return the assistant shows {@link AgentConfig.notResumableMessage} (or a
875
- * default) and pre-fills the composer with the prompt that started the flow so
876
- * the user can re-run it.
877
- *
878
- * Only consulted when the user has persistence enabled. Must be a **pure
879
- * function of `ctx.state`** — it may be re-evaluated on a restored snapshot, so
880
- * a resumable state must stay resumable. A thrown error is treated as `true`
881
- * (fail-safe: never drop a resumable chat on a predicate bug).
882
- *
883
- * @beta
884
- */
885
- resumable?: (ctx: AgentPersistenceContext) => boolean | Promise<boolean>;
886
- /**
887
- * Message shown on return when {@link AgentConfig.resumable} returned `false`
888
- * and the user comes back to a non-resumable session (GENC-1351 §5.9). Falls
889
- * back to a built-in default when omitted.
890
- *
891
- * @beta
892
- */
893
- notResumableMessage?: string;
894
745
  }
895
746
 
896
747
  export { CachePolicy }
@@ -925,6 +776,12 @@ export declare class ChatDriver extends EventTarget implements AiDriver {
925
776
  /** Epoch ms when the current turn loop began — drives the `turn.end` duration. */
926
777
  private turnStartedAt;
927
778
  private pendingInteractions;
779
+ /** Assistant host ids currently wired to this driver, in registration (insertion) order. */
780
+ private hosts;
781
+ /** The host whose subtree the user most recently interacted in — the primary owner signal. */
782
+ private lastActiveHostId?;
783
+ /** Interaction id → host id that claimed its side effect (first-writer-wins latch). */
784
+ private startedSideEffects;
928
785
  private systemPrompt?;
929
786
  /**
930
787
  * Resolved tool definitions visible to the LLM. Folds mutate this in place
@@ -1338,23 +1195,33 @@ export declare class ChatDriver extends EventTarget implements AiDriver {
1338
1195
  /** Returns the current fold stack names for debugging. */
1339
1196
  getActiveFoldNames(): string[];
1340
1197
  getSuggestions(history: ChatMessage[], prompt: string, count: number, allAgentInfo?: AllAgentSummary[]): Promise<string[]>;
1198
+ isBusy(): boolean;
1199
+ /** Register an assistant view (host) wired to this shared driver. @internal */
1200
+ registerHost(hostId: string): void;
1201
+ /** Deregister a host on unwire/disconnect. @internal */
1202
+ unregisterHost(hostId: string): void;
1341
1203
  /**
1342
- * Whether `compact()` would do anything right now — a summarizable run of older
1343
- * turns exists behind a clean boundary. Uses the same `history` `compact()`
1344
- * acts on, so the UI's gate can't disagree with the action (GENC-1351 follow-up).
1204
+ * Record the host whose subtree the user most recently interacted in — the primary signal for
1205
+ * electing which single view renders an interaction's widget. Sticky (unlike focus): it only
1206
+ * moves when the user actually uses a different assistant view, not when they click elsewhere
1207
+ * in the layout. @internal
1345
1208
  */
1346
- canCompact(): boolean;
1209
+ setActiveHost(hostId: string): void;
1347
1210
  /**
1348
- * Destructively compact older turns into a single `compacted-summary` message
1349
- * (GENC-1351 §5.7). Summarizes everything before a clean recent-tail boundary
1350
- * via the registry-default provider's one-shot `prompt()`, then **atomically**
1351
- * replaces the covered turns with one summary message at the head — history is
1352
- * mutated only on success. Rolling: any existing head summary is folded into
1353
- * the new one. Returns the created summary message, or `null` when there is
1354
- * nothing worth compacting or the default provider cannot summarize.
1211
+ * First-writer-wins latch guarding a side effect. A host claims before rendering the live
1212
+ * widget: the first host to claim an interaction id gets `true` (run it); a *different* host
1213
+ * gets `false` (render passive, do NOT re-fire). Re-claim by the SAME host returns `true`, so a
1214
+ * benign re-render of the owner keeps its widget. Single-threaded, so check-and-set is race-free
1215
+ * — the backstop that makes duplicate execution impossible even if owner election ever slips. @internal
1355
1216
  */
1356
- compact(): Promise<ChatMessage | null>;
1357
- isBusy(): boolean;
1217
+ claimSideEffect(interactionId: string, hostId: string): boolean;
1218
+ /**
1219
+ * Elect the single host that owns (renders + runs) an interaction's widget: the most-recently-
1220
+ * active host if still connected, else a deterministic default (first registered host — `Set`
1221
+ * preserves insertion order) so exactly one owner is always chosen. Returns `undefined` only when
1222
+ * no host is registered, in which case the interaction renders everywhere (fail-open) not nowhere.
1223
+ */
1224
+ private electInteractionOwner;
1358
1225
  /**
1359
1226
  * Wire a parent driver as the host for this driver's interactions. When set,
1360
1227
  * `requestInteraction` delegates upward so the widget renders in (and
@@ -1462,16 +1329,6 @@ export declare class ChatDriver extends EventTarget implements AiDriver {
1462
1329
  private appendToHistory;
1463
1330
  }
1464
1331
 
1465
- /**
1466
- * `detail` of the `AiAssistantEvent.ChatHeaderMouseDown` event.
1467
- *
1468
- * @beta
1469
- */
1470
- export declare interface ChatHeaderMouseDownDetail {
1471
- clientX: number;
1472
- clientY: number;
1473
- }
1474
-
1475
1332
  /**
1476
1333
  * Detail payload for the `chat-header-mousedown` event fired by the assistant
1477
1334
  * in `popout-mode="expand"`.
@@ -1582,13 +1439,6 @@ export declare function createToolFold(config: {
1582
1439
  exclusive?: boolean;
1583
1440
  }): ToolFoldResult;
1584
1441
 
1585
- /** The reassembled debug log — the exact shape `getDebugLog()` returns. @public */
1586
- export declare interface DebugLog {
1587
- readme: readonly string[];
1588
- timeline: DiagnosticEntry[];
1589
- meta: unknown;
1590
- }
1591
-
1592
1442
  /**
1593
1443
  * Animations enabled by default when a consumer opts into the animations
1594
1444
  * feature without specifying an explicit `enabled` list. Keeps the dots loading
@@ -1642,25 +1492,6 @@ export declare function defineAgent<const T extends AgentConfig>(config: T): T;
1642
1492
  */
1643
1493
  export declare function defineStatefulAgent<S>(opts: StatefulAgentInit<S>): AgentConfig;
1644
1494
 
1645
- /**
1646
- * One entry in the diagnostics stream — the debug-log timeline-entry union
1647
- * (`message` / `turn` / `event`, as `getDebugLog()` builds) plus a point-in-time
1648
- * **`meta-snapshot`** carrying the export-time `meta` block (agent summary,
1649
- * context, active debug snapshot, …). Kept permissive: a provider stores and
1650
- * returns these opaquely, and reassembly reads only `kind`, `timestamp` (for
1651
- * ordering), and `meta` (on a snapshot).
1652
- *
1653
- * @public
1654
- */
1655
- export declare interface DiagnosticEntry {
1656
- kind: 'message' | 'turn' | 'event' | 'meta-snapshot';
1657
- /** ISO timestamp — string-comparable, so it orders the stream chronologically. */
1658
- timestamp?: string;
1659
- /** Present on `meta-snapshot` entries: the export-time `meta` block. */
1660
- meta?: unknown;
1661
- [key: string]: unknown;
1662
- }
1663
-
1664
1495
  /**
1665
1496
  * Expands a flat list of tool definitions into a nested tree by resolving fold
1666
1497
  * metadata from the corresponding handlers. Use this for debug output so the
@@ -1713,18 +1544,6 @@ export declare class FoundationAiAssistant extends GenesisElement {
1713
1544
  appSettingsProvider: AssistantAppSettingsProvider;
1714
1545
  designSystemPrefix: string;
1715
1546
  headerTitle: string;
1716
- /**
1717
- * Explicit session/persistence key (GENC-1351 §5.12). When set, this is the
1718
- * session identity — the key for the driver/store/persister/diagnostics
1719
- * registries and the `sessionKey` passed to the persistence provider — taking
1720
- * precedence over the DOM `id`. A host that scopes persistence per-entity
1721
- * (e.g. one chat session per project) binds this to a stable per-entity id;
1722
- * changing it on a **connected** element re-keys the session in place — tears
1723
- * down the current conversation and restores the new key's — via
1724
- * `switchSession`. Falls back to `id` when unset,
1725
- * so existing consumers are unaffected.
1726
- */
1727
- sessionKey?: string;
1728
1547
  imageSrc?: string;
1729
1548
  userImageSrc?: string;
1730
1549
  /**
@@ -1762,15 +1581,6 @@ export declare class FoundationAiAssistant extends GenesisElement {
1762
1581
  */
1763
1582
  agents?: AgentConfig[];
1764
1583
  chatConfig: ChatConfig;
1765
- /**
1766
- * Optional session persistence (GENC-1351). Off by default — set `enabled`
1767
- * and a `provider` (e.g. a `WebStorageSessionProvider`) to have the assistant
1768
- * autosave on idle and auto-restore the conversation on page reload. Exposed
1769
- * as a top-level property (like `agents`/`providerRegistry`) rather than via
1770
- * `chatConfig`, since the provider type lives in this package while
1771
- * `ChatConfig` lives in `foundation-ai`.
1772
- */
1773
- persistence: SessionPersistenceConfig;
1774
1584
  /**
1775
1585
  * Resolved agent picker mode from `chatConfig.picker.mode`. Defaults to
1776
1586
  * `'disabled'`.
@@ -1787,14 +1597,6 @@ export declare class FoundationAiAssistant extends GenesisElement {
1787
1597
  debugStateFactory?: () => unknown;
1788
1598
  /** When set, enables Redux DevTools for this instance's session store. */
1789
1599
  debugRedux: boolean;
1790
- /**
1791
- * Pointer to this session's redux store. `@observable` (GENC-1351 §5.12) so that
1792
- * **swapping** it — the in-place session switch/re-key (`switchSession`) —
1793
- * forces every store-backed getter binding to re-evaluate against the NEW store.
1794
- * Without this, FAST's per-store slice tracking would leave the view subscribed
1795
- * to the old store after a swap and it wouldn't re-render. (A same-store reset via
1796
- * redux actions re-renders without this; a store *swap* needs it.)
1797
- */
1798
1600
  private _sessionRef?;
1799
1601
  get messages(): ChatMessage[];
1800
1602
  set messages(value: ChatMessage[]);
@@ -1852,27 +1654,6 @@ export declare class FoundationAiAssistant extends GenesisElement {
1852
1654
  */
1853
1655
  get agentPickerOpen(): boolean;
1854
1656
  set agentPickerOpen(value: boolean);
1855
- /**
1856
- * Whether the lifecycle (session) menu slide-out panel is open. Like the
1857
- * agent picker, lives on the session store so bubble/popout stay in sync.
1858
- */
1859
- get sessionMenuOpen(): boolean;
1860
- set sessionMenuOpen(value: boolean);
1861
- /**
1862
- * Whether a manual compaction is in flight (GENC-1351 §5.7). On the session
1863
- * store (not element-local) so the "Compacting…" view + input-disable stay in
1864
- * sync across pop-in/out, like the panel flags.
1865
- */
1866
- get compacting(): boolean;
1867
- set compacting(value: boolean);
1868
- /**
1869
- * Whether a page-reload restore is in flight (GENC-1351 §6). On the session
1870
- * store (like `compacting`) so the "Restoring…" view + input-disable stay in
1871
- * sync across pop-in/out. Gating input while true prevents a mid-load send from
1872
- * being clobbered when the restored history loads.
1873
- */
1874
- get restoring(): boolean;
1875
- set restoring(value: boolean);
1876
1657
  /**
1877
1658
  * Name of the agent the user has pinned via the agent picker. `null` means
1878
1659
  * automatic routing (Auto). Persisted on the session store, so it survives
@@ -1966,14 +1747,6 @@ export declare class FoundationAiAssistant extends GenesisElement {
1966
1747
  appSettingsRevision: number;
1967
1748
  /** Whether the settings modal is open. */
1968
1749
  settingsOpen: boolean;
1969
- /**
1970
- * True while `downloadDebugLog` is building the log (GENC-1351 §5.8). Drives the
1971
- * download button's disabled + spinner state — the lifetime-stitch path is async
1972
- * (a provider `loadDiagnostics` round-trip), so without feedback a click looks
1973
- * like nothing happened. Per-instance and transient (not shared/persisted): each
1974
- * element has its own settings modal.
1975
- */
1976
- downloadingDebugLog: boolean;
1977
1750
  /** Active tab inside the settings modal. */
1978
1751
  settingsModalTab: SettingsModalTab;
1979
1752
  /** Bound to the design-system modal via the template ref. */
@@ -2034,6 +1807,12 @@ export declare class FoundationAiAssistant extends GenesisElement {
2034
1807
  * to avoid stealing focus from elsewhere on the page.
2035
1808
  */
2036
1809
  isEngaged: boolean;
1810
+ /**
1811
+ * GENC-1410 (Error 3): stable id for this assistant view. Reported to the shared driver so it
1812
+ * can elect a single owner to render (and run) each interaction's widget when more than one view
1813
+ * (e.g. a bubble and a docked panel) is wired to the same driver — so it fires once, not per view.
1814
+ */
1815
+ private readonly hostId;
2037
1816
  private _handleGlobalInteraction;
2038
1817
  /** True when the user has intentionally scrolled away from the bottom — suppresses auto-scroll. */
2039
1818
  private _userScrolledAway;
@@ -2061,28 +1840,6 @@ export declare class FoundationAiAssistant extends GenesisElement {
2061
1840
  * originating `send()` ran on a different element instance.
2062
1841
  */
2063
1842
  private _executionCompletionUnsub?;
2064
- /**
2065
- * True while UI preferences are being applied programmatically (config defaults
2066
- * on connect, or a loaded-preferences restore) — suppresses the save hook so we
2067
- * don't persist config defaults or re-persist what we just loaded. Cleared once
2068
- * the apply completes; a genuine *user* toggle (menu switch) runs with it false
2069
- * and saves (GENC-1351).
2070
- */
2071
- private _applyingPreferences;
2072
- /**
2073
- * Fresh-store flag (`= isNewStore`) captured in `connectedCallback`. Only a
2074
- * freshly created store takes the config/stored-prefs baseline; an existing
2075
- * store — a reload with a live in-realm store, or the popped-out second instance
2076
- * — already holds the correct state, so `applyPreferenceBaseline` no-ops for it.
2077
- */
2078
- private _freshStore;
2079
- /**
2080
- * True once `connectedCallback` has fully wired the initial session (GENC-1351
2081
- * §5.12). Guards `sessionKeyChanged` so the initial, pre-connect `session-key`
2082
- * set doesn't trigger a re-key — only a genuine change to a connected element
2083
- * switches the session. Reset on disconnect.
2084
- */
2085
- private _sessionActive;
2086
1843
  showHalo: 'no' | 'orchestrating' | 'agent';
2087
1844
  private syncShowHalo;
2088
1845
  /** True when there is a pending (unresolved) interaction. */
@@ -2140,42 +1897,7 @@ export declare class FoundationAiAssistant extends GenesisElement {
2140
1897
  * the driver or remove it from the registry.
2141
1898
  */
2142
1899
  private unwireDriver;
2143
- /**
2144
- * Wire up the session identified by `key` on this element: preference baseline,
2145
- * driver (build/reuse) + wiring, restore (fresh store only), and the per-session
2146
- * view state (splash, loading-resume, suggestions, context/provider status, cost
2147
- * history). Extracted from `connectedCallback` (GENC-1351 §5.12) so an in-place
2148
- * session switch (`switchSession`) can re-run exactly this against a new
2149
- * key without re-adding element-lifetime listeners. Session-scoped only — the
2150
- * element-lifetime wiring (DOM/document/window listeners, provider-registry
2151
- * subscription, app-settings, pagehide) stays in `connectedCallback`.
2152
- */
2153
- private activateSession;
2154
1900
  connectedCallback(): void;
2155
- /**
2156
- * Switch this element to a different session **in place**, without a page reload
2157
- * (GENC-1351 §5.12) — the load-a-different-project flow. Tears down the current
2158
- * session's driver + per-key registries and restores the target key's session
2159
- * (its transcript and any mid-flow stateful agent). Fired automatically by
2160
- * `sessionKeyChanged` when a host rebinds
2161
- * `session-key` on a connected element; may also be called directly.
2162
- *
2163
- * Clobber-safe: the outgoing session's pending autosave is cancelled BEFORE the
2164
- * store swaps, so its transcript can never be written to the incoming session's
2165
- * file. Idle-only — a switch while a turn is running is refused.
2166
- *
2167
- * @param oldKey - the state key being switched away from.
2168
- * @param newKey - the state key to activate.
2169
- * @public
2170
- */
2171
- switchSession(oldKey: string, newKey: string): void;
2172
- /**
2173
- * FAST reflection hook for the `session-key` attr: a change on a **connected**
2174
- * element re-keys the session in place (GENC-1351 §5.12). Guarded by
2175
- * `_sessionActive` so the initial, pre-connect set does not switch — the first
2176
- * key is wired by `connectedCallback`.
2177
- */
2178
- sessionKeyChanged(oldValue: string | undefined, _newValue: string | undefined): void;
2179
1901
  disconnectedCallback(): void;
2180
1902
  private resolveContextLimit;
2181
1903
  private loadProviderStatuses;
@@ -2196,6 +1918,24 @@ export declare class FoundationAiAssistant extends GenesisElement {
2196
1918
  private clearLoadingTimer;
2197
1919
  private stopLoadingTimer;
2198
1920
  /** Called when the user clicks the popout button. */
1921
+ /**
1922
+ * GENC-1410 (Error 3): claim the right to run a side-effecting interaction's server work for
1923
+ * THIS view, via the shared driver's first-writer-wins latch. Returns `true` when this view may
1924
+ * run it (first/owning claimant, or a re-render of the same view), `false` when another view
1925
+ * already holds it. Fail-open when the driver has no latch. Called by `ai-chat-interaction-wrapper`.
1926
+ */
1927
+ claimSideEffect(interactionId: string): boolean;
1928
+ /**
1929
+ * GENC-1410 (Error 3): mark THIS view as the interaction owner on the shared driver, so it (not a
1930
+ * sibling view sharing the same driver) is elected to render side-effecting widgets. The bubble
1931
+ * and docked panel normally claim this automatically on the pop-in / dock lifecycle, but that
1932
+ * lifecycle only runs once `popout-mode` is active. A host that establishes a view outside that
1933
+ * lifecycle — e.g. a page that restores a docked assistant from a persisted layout before the
1934
+ * pop-out affordance is enabled — calls this to seize ownership deterministically rather than
1935
+ * leaving it to the last-interaction / first-registered fallback. Idempotent; safe to call on
1936
+ * every layout (re)establish. No-op if the driver was never wired.
1937
+ */
1938
+ claimInteractionOwnership(): void;
2199
1939
  handlePopout(): void;
2200
1940
  /** Returns a cache key for this instance, or undefined if the component has no identity. */
2201
1941
  private getStateKey;
@@ -2209,99 +1949,6 @@ export declare class FoundationAiAssistant extends GenesisElement {
2209
1949
  private logMeta;
2210
1950
  private readonly _agentPickerToggle;
2211
1951
  toggleAgentPicker(): void;
2212
- /** Two-step confirm for the destructive Clear action; reset whenever the menu toggles. */
2213
- confirmingClear: boolean;
2214
- confirmingCompact: boolean;
2215
- private readonly _sessionMenuToggle;
2216
- /**
2217
- * Whether the lifecycle-menu button shows. It occupies the stop-button slot,
2218
- * so it only appears when idle (mutually exclusive with Stop). Gated on
2219
- * persistence — the menu's actions (Compact, Clear, the "remember chat" toggle)
2220
- * only make sense with a provider configured, so it's hidden entirely without
2221
- * one. A host can additionally force it off via `chatConfig.ui.showSessionMenu:
2222
- * false` even when a provider is present (e.g. a guided onboarding flow where
2223
- * clearing/compacting mid-journey would be disruptive).
2224
- */
2225
- get sessionMenuEnabled(): boolean;
2226
- /** The persistence toggle row renders only when a provider is configured. */
2227
- get persistenceToggleable(): boolean;
2228
- /** Whether persistence is currently active (on + a provider) for this session. */
2229
- get persistenceActive(): boolean;
2230
- /**
2231
- * Whether the menu's "Compact" action would do anything (GENC-1351 §5.7).
2232
- * Delegates to `driver.canCompact()` so the gate uses the exact same history
2233
- * `compact()` acts on — one source of truth. Also reads `messages`, purely to
2234
- * stay reactive as the conversation grows: the driver's history isn't a tracked
2235
- * observable, so the button keys its re-evaluation off the Redux mirror.
2236
- */
2237
- get compactable(): boolean;
2238
- toggleSessionMenu(): void;
2239
- /**
2240
- * Set persistence on/off for this session (the menu switch). Reassigns the
2241
- * `persistence` object so the `@observable` fires. Turning it **off** drops the
2242
- * stored snapshot; **on** captures the current chat immediately. Either way the
2243
- * *choice* is remembered in the preferences blob (`persistPreferences`) — stored
2244
- * independently of the snapshot, so it survives the clear and re-applies on the
2245
- * next load (GENC-1351).
2246
- */
2247
- setPersistenceEnabled(enabled: boolean): void;
2248
- /** Toggle persistence (convenience / programmatic). */
2249
- togglePersistence(): void;
2250
- /** Snapshot the user-changeable settings into a persistable preferences blob. */
2251
- private gatherPreferences;
2252
- /**
2253
- * Persist the current UI preferences whenever the user changes a setting
2254
- * (GENC-1351). Fires **regardless of "remember chat"** — display choices are the
2255
- * user's, not tied to whether the chat is remembered — needing only a provider
2256
- * that implements `savePreferences`. No-op while preferences are being applied
2257
- * programmatically (`_applyingPreferences`), so config defaults and loaded prefs
2258
- * aren't re-saved.
2259
- */
2260
- private persistPreferences;
2261
- /**
2262
- * Apply the effective UI-preference baseline onto the live toggles for a fresh
2263
- * store (GENC-1351 #2). Precedence, lowest → highest:
2264
- *
2265
- * slice defaults < `chatConfig.ui` defaults < stored user preferences
2266
- *
2267
- * Recomputed from scratch (not layered) on every call, because its two inputs
2268
- * arrive at unpredictable times: `chatConfig` is a parent-supplied `@observable`
2269
- * that may bind *after* `connectedCallback`, and stored prefs load asynchronously.
2270
- * So it re-runs from `connectedCallback`, `chatConfigChanged`, and once
2271
- * `loadPreferences` resolves — whichever order they happen in, the final state is
2272
- * the same. No-op once the store isn't fresh (an existing/popped-out store owns
2273
- * its state) or the user has toggled something (their choice then wins, and
2274
- * `chatConfig` doesn't change post-startup in practice). Save hook suppressed so
2275
- * applying the baseline never persists as if it were a user choice.
2276
- *
2277
- * This is the fix for "nuking server prefs drops to all-disabled instead of the
2278
- * `chatConfig` defaults": stored prefs are simply absent, so the baseline falls
2279
- * through to the config layer — which the old apply-once-on-connect path missed
2280
- * whenever `chatConfig` hadn't bound yet.
2281
- */
2282
- private applyPreferenceBaseline;
2283
- /**
2284
- * Compact the conversation (GENC-1351 §5.7) — the menu's "Compact" action.
2285
- * Delegates to the driver, which summarizes older turns into a single
2286
- * `compacted-summary` message (destructive, atomic). On success records a
2287
- * high-importance `context.compacted` meta-event capturing the summary; the
2288
- * normal `history-updated` → autosave path then persists the smaller
2289
- * transcript. No-op when there is nothing to compact or the provider cannot
2290
- * summarize (the driver returns `null`).
2291
- */
2292
- compactSession(): Promise<void>;
2293
- /**
2294
- * Clear the session — the "New chat" action (GENC-1351 §5.6). Tears down the
2295
- * active driver (firing the stateful agent's `onDeactivate` → `machine.stop()`),
2296
- * resets the store, rebuilds a fresh driver with no history, and wipes durable
2297
- * storage. Mirrors `agentsChanged`'s teardown, minus the history reseed.
2298
- *
2299
- * @fires session-cleared - After the session is wiped. `detail`:
2300
- * `{ sessionKey, agentName?, agentSnapshot? }` — captured *before* teardown
2301
- * so the host can clean up any external state the active agent was working
2302
- * on (generated files, server-side scratch, etc.). Bubbles and composed.
2303
- */
2304
- clearSession(): Promise<void>;
2305
1952
  /**
2306
1953
  * Programmatically pin an agent by name. Returns `true` if the pin was
2307
1954
  * applied, `false` if the agent isn't in the configured agents array or
@@ -2391,45 +2038,68 @@ export declare class FoundationAiAssistant extends GenesisElement {
2391
2038
  toggleShowNarration(): void;
2392
2039
  toggleShowAgentSwitchIndicator(): void;
2393
2040
  setEnabledAnimations(animations: AiAssistantAnimation[]): void;
2394
- /** The live current-page debug log (`{ readme, timeline, meta }`). @public */
2395
- getDebugLog(): DebugLog;
2396
- /**
2397
- * Build the current page's diagnostic entries (GENC-1351 §5.8) — the debug-log
2398
- * timeline entries (`message`/`turn`/`event`) plus one `meta-snapshot` carrying
2399
- * the export-time `meta` block. `getDebugLog()` reassembles these into the live
2400
- * log; the persister's forward-capture path (`SessionPersister.flushDiagnostics`,
2401
- * fed these via the `getDiagnosticEntries` dep) diffs them against what's already
2402
- * been appended to the persisted stream.
2403
- */
2404
- private buildDiagnosticEntries;
2405
- downloadDebugLog(): Promise<void>;
2406
- /**
2407
- * The log to download (GENC-1351 §5.8). When the provider persists diagnostics,
2408
- * stitch the **whole lifetime** stream (every page load) rather than just the
2409
- * current page's in-memory view: flush the current delta first so it's included,
2410
- * then reassemble everything `loadDiagnostics` returns. Independent of "remember
2411
- * chat" — diagnostics are a forensic stream keyed on provider capability, not on
2412
- * whether the *chat* is remembered (like preferences). Falls back to the live
2413
- * current-page log when diagnostics isn't available or the fetch fails.
2414
- */
2415
- private buildDownloadLog;
2416
- /**
2417
- * The shared per-session `SessionPersister` that owns restore-core
2418
- * save/restore/freeze (GENC-1351 §5.10). Created once per `stateKey` and shared by
2419
- * every element view (bubble + panel) via the registry, so there is a single save
2420
- * timer + carry-forward cache — no per-view double-writes. The deps are getters so
2421
- * the persister always reads the current driver/store/config and never holds a
2422
- * stale reference. `undefined` before the session key is available.
2423
- */
2424
- private persister;
2425
- /**
2426
- * First-load persistence init for a freshly created store (GENC-1351). Restores
2427
- * the user's remembered persistence-toggle choice — kept independently of the
2428
- * session snapshot so it survives a clear; the host-configured `enabled` is only
2429
- * the default for a first-ever load — then auto-restores the session when
2430
- * persistence is (now) on.
2431
- */
2432
- private initPersistenceForNewStore;
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;
2433
2103
  triggerFileInput(): void;
2434
2104
  handleFileSelect(e: Event): void;
2435
2105
  removeAttachment(attachment: ChatAttachment): void;
@@ -2503,14 +2173,9 @@ export declare const FoundationAiAssistantTemplate: (designSystemPrefix: string)
2503
2173
  *
2504
2174
  * @remarks
2505
2175
  * Place this in the persistent app shell, wrapping a `foundation-ai-chat-bubble` that
2506
- * contains an AI assistant element in the `dialog-content` slot.
2507
- *
2508
- * GENC-1351 (Option A — single element): rather than cloning a second assistant to
2509
- * dock, this manager **moves the one real element** between the bubble and the page
2510
- * layout. One connected instance means no dual-view coordination (no shared-driver
2511
- * unwire/rewire, host election, or duplicated side-effects); the session survives the
2512
- * move because the driver/store/persister live in module-level registries keyed by the
2513
- * element's identity.
2176
+ * contains an AI assistant element in the `dialog-content` slot. The component will
2177
+ * auto-create a matching collapse-mode element for docking into pages, and will
2178
+ * control the expand button visibility based on whether a dock provider is registered.
2514
2179
  *
2515
2180
  * Pages that support docking call `aiPopoutManager.registerDockProvider()` on mount
2516
2181
  * and `aiPopoutManager.deregisterDockProvider()` on unmount.
@@ -2529,29 +2194,12 @@ export declare const FoundationAiAssistantTemplate: (designSystemPrefix: string)
2529
2194
  export declare class FoundationAiPopoutManager extends GenesisElement {
2530
2195
  /** True when a dock provider is registered — controls expand button visibility. */
2531
2196
  canDock: boolean;
2532
- /**
2533
- * The single assistant element. Captured while it's in the bubble slot and held
2534
- * across the move (it's the same instance whether docked or in the bubble), so
2535
- * pop-in can re-home it even though it's no longer a child of this manager.
2536
- */
2537
- private assistantEl;
2197
+ private collapseEl;
2538
2198
  private dockProvider;
2539
2199
  private isDocked;
2540
2200
  private unsubBus?;
2541
2201
  connectedCallback(): void;
2542
2202
  disconnectedCallback(): void;
2543
- /** Locate the assistant element currently slotted into the bubble. */
2544
- private findAssistant;
2545
- /**
2546
- * Register an externally-created assistant element and its docked state. For
2547
- * single-element hosts that create the assistant directly in a layout pane (rather
2548
- * than statically in the bubble), so the manager tracks the one element, whether it's
2549
- * currently docked (for pop-in re-homing), reflects the right `popout-mode` on it
2550
- * (drives the header button), and hides the empty bubble.
2551
- */
2552
- adoptAssistant(el: HTMLElement, docked: boolean): void;
2553
- /** Hide the floating bubble unless it currently contains the assistant. */
2554
- private syncBubbleVisibility;
2555
2203
  canDockChanged(): void;
2556
2204
  registerDockProvider(provider: AiDockProvider): void;
2557
2205
  deregisterDockProvider(): void;
@@ -2606,7 +2254,7 @@ declare interface InputOverride {
2606
2254
  */
2607
2255
  export declare type InteractionCompletedEventDetail = ChatInteractionEventsMap['interaction-completed'];
2608
2256
 
2609
- /** True when the assistant is active in the layout panel (docked) rather than the bubble. */
2257
+ /** True when the collapse-mode assistant is active in the layout panel. */
2610
2258
  export declare function isAiAssistantDocked(): boolean;
2611
2259
 
2612
2260
  /**
@@ -2637,6 +2285,44 @@ export declare interface ManualSelectionConfig {
2637
2285
  hint?: string;
2638
2286
  }
2639
2287
 
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
+
2640
2326
  export { ModelTagAppearance }
2641
2327
 
2642
2328
  /**
@@ -2682,13 +2368,6 @@ export declare class OrchestratingDriver extends EventTarget implements AiDriver
2682
2368
  * choice.
2683
2369
  */
2684
2370
  private flowOwnerAgentName;
2685
- /**
2686
- * Per-agent restored state for a rehydrated session, keyed by agent name.
2687
- * Primed by the host on restore; each entry is passed to that agent's
2688
- * `onActivate` as `ctx.restored` on its next activation, then deleted so a
2689
- * later re-activation starts fresh.
2690
- */
2691
- private restoredAgentStates;
2692
2371
  activeAgent?: AgentConfig;
2693
2372
  constructor(providerRegistry: AIProviderRegistry, agents: AgentConfig[], options?: {
2694
2373
  sessionKey?: string;
@@ -2701,6 +2380,10 @@ export declare class OrchestratingDriver extends EventTarget implements AiDriver
2701
2380
  });
2702
2381
  resolveInteraction(interactionId: string, result: unknown): void;
2703
2382
  isBusy(): boolean;
2383
+ registerHost(hostId: string): void;
2384
+ unregisterHost(hostId: string): void;
2385
+ setActiveHost(hostId: string): void;
2386
+ claimSideEffect(interactionId: string, hostId: string): boolean;
2704
2387
  /** Currently active provider name from the underlying ChatDriver. */
2705
2388
  getActiveProviderName(): string;
2706
2389
  /**
@@ -2719,19 +2402,11 @@ export declare class OrchestratingDriver extends EventTarget implements AiDriver
2719
2402
  setFlowOwner(name: string | null): void;
2720
2403
  loadHistory(messages: ChatMessage[]): void;
2721
2404
  getRawHistory(): readonly ChatMessage[];
2722
- /** {@inheritDoc AiDriver.compact} */
2723
- compact(): Promise<ChatMessage | null>;
2724
- /** {@inheritDoc AiDriver.canCompact} */
2725
- canCompact(): boolean;
2726
2405
  /** Delegates to the inner {@link ChatDriver} — turns are captured there. */
2727
2406
  getTurnSnapshots(): ReadonlyArray<TurnSnapshot>;
2728
2407
  getSuggestions(history: ChatMessage[], prompt: string, count: number, allAgentInfo?: AllAgentSummary[]): Promise<string[]>;
2729
2408
  sendMessage(input: string, attachments?: ChatAttachment[]): Promise<ChatDriverResult>;
2730
2409
  continueFromHistory(transientPrimer?: ChatMessage[]): Promise<ChatDriverResult>;
2731
- /** {@inheritDoc AiDriver.primeRestoredAgentState} */
2732
- primeRestoredAgentState(snapshots: Record<string, unknown>): void;
2733
- /** {@inheritDoc AiDriver.getActiveAgent} */
2734
- getActiveAgent(): AgentConfig | undefined;
2735
2410
  private applyAgent;
2736
2411
  /**
2737
2412
  * Release the current stateful agent: fire `onDeactivate`, clear the
@@ -2770,75 +2445,6 @@ export declare class OrchestratingDriver extends EventTarget implements AiDriver
2770
2445
  private appendInlineMessage;
2771
2446
  }
2772
2447
 
2773
- /**
2774
- * Schema version of the persisted session shape. Bump on an incompatible
2775
- * change; a snapshot whose `version` doesn't match is discarded on load rather
2776
- * than risk feeding a stale shape into restore.
2777
- *
2778
- * @public
2779
- */
2780
- export declare const PERSISTED_SESSION_VERSION = 1;
2781
-
2782
- /**
2783
- * A durable, restorable snapshot of one chat session — the *restorable core* of
2784
- * the debug log (GENC-1351 §5.1/D1), captured losslessly and independently of
2785
- * the diagnostic timeline. Written by a `SessionPersistenceProvider` and read
2786
- * back on page-reload restore.
2787
- *
2788
- * @public
2789
- */
2790
- export declare interface PersistedSession {
2791
- /** Schema version — see {@link PERSISTED_SESSION_VERSION}. */
2792
- version: number;
2793
- /** ISO timestamp the snapshot was written. */
2794
- savedAt: string;
2795
- /** `window.location.host` at save time — restore refuses a cross-host snapshot. */
2796
- host: string;
2797
- /** The session this snapshot belongs to (the assistant's state key). */
2798
- sessionKey: string;
2799
- /** Full conversation transcript (`driver.getRawHistory()`) — the source of truth. */
2800
- messages: ChatMessage[];
2801
- /** Name of the agent active at save time, if any. */
2802
- activeAgentName?: string;
2803
- /** User's pinned agent (sticky picker choice); `null` = Auto. */
2804
- pinnedAgentName: string | null;
2805
- /** Agent that owned a guided flow at save time; `null` = none. */
2806
- flowOwnerAgentName: string | null;
2807
- /** Aggregated USD cost across the session. */
2808
- sessionCostUsd: number;
2809
- /** Provider-reported context-window usage on the last turn. */
2810
- contextTokens?: number;
2811
- /** Context-window limit for the active model. */
2812
- contextLimit?: number;
2813
- /** Active model id (e.g. `claude-sonnet-4-6`). */
2814
- activeModel?: string;
2815
- /** Name of the provider used on the last turn. */
2816
- activeProviderName?: string;
2817
- /**
2818
- * Per-stateful-agent serialized state images (each from an agent's
2819
- * `serialize()`), keyed by agent name. Handed back to the agent's
2820
- * `init({ restored })` on restore. Typically holds at most the active
2821
- * flow-owner — other stateful agents are disposed when switched away. The
2822
- * value shape is the agent's own, hence `unknown`.
2823
- */
2824
- agentSnapshots: Record<string, unknown>;
2825
- /**
2826
- * Interrupted-flow marker (GENC-1351 §5.9). Present when the session was saved
2827
- * while an agent declared its current state non-resumable (`resumable === false`).
2828
- * The **conversation is still persisted and restored in full** — only the running
2829
- * agent's flow-state is dropped (`agentSnapshots` empty, `flowOwnerAgentName`
2830
- * null), so restore does not rehydrate the mid-flight flow. On restore the
2831
- * assistant appends `message` as a normal assistant bubble and pre-fills the
2832
- * composer with `prompt` so the user can re-run it.
2833
- */
2834
- interrupted?: {
2835
- /** Shown as an assistant message on return. */
2836
- message: string;
2837
- /** The prompt that started the flow, pre-filled into the composer on return. */
2838
- prompt?: string;
2839
- };
2840
- }
2841
-
2842
2448
  /**
2843
2449
  * Controls the pop-out button shown in the assistant header.
2844
2450
  * - `"expand"` — assistant is embedded in the bubble dialog; button expands it to a layout panel.
@@ -2881,147 +2487,6 @@ declare interface ResolvedCostHistoryConfig {
2881
2487
  badgeLabel: string;
2882
2488
  }
2883
2489
 
2884
- /**
2885
- * Restore a foundation-state-machine instance from a snapshot produced by the
2886
- * default serializer (or `machine.getPersistedSnapshot()`). Call inside a
2887
- * stateful agent's `init` to resume the machine in its exact prior place:
2888
- *
2889
- * ```ts
2890
- * init: ({ restored }) => {
2891
- * const machine = new MyMachine();
2892
- * restoreMachine(machine, restored); // resume, or no-op on a fresh start
2893
- * return { machine };
2894
- * }
2895
- * ```
2896
- *
2897
- * No-ops when there is nothing to restore (a fresh session), leaving the
2898
- * freshly-constructed machine in its initial state.
2899
- *
2900
- * @param machine - the machine to restore (already constructed/started).
2901
- * @param restored - the agent's serialized image (`ctx.restored` in `init`).
2902
- * @param key - the property the machine occupies in the snapshot; defaults to
2903
- * `'machine'` to match the conventional `{ machine }` state bag.
2904
- * @beta
2905
- */
2906
- export declare function restoreMachine(machine: {
2907
- stop: () => void;
2908
- start: (options?: {
2909
- state?: unknown;
2910
- }) => void;
2911
- }, restored: unknown, key?: string): void;
2912
-
2913
- /**
2914
- * `detail` of the `AiAssistantEvent.SessionCleared` event. Captured *before*
2915
- * teardown so a host can tidy up whatever the active agent was working on
2916
- * (generated files, server-side scratch, …). `agentSnapshot` is the agent's
2917
- * `serialize()` output (a state-machine image for machine-backed agents).
2918
- *
2919
- * @beta
2920
- */
2921
- export declare interface SessionClearedDetail {
2922
- sessionKey: string | undefined;
2923
- agentName: string | undefined;
2924
- agentSnapshot: unknown;
2925
- }
2926
-
2927
- /**
2928
- * Host-supplied persistence configuration, passed to the assistant via its
2929
- * `persistence` property. Persistence stays inert unless `enabled` is true and
2930
- * a `provider` is set — so existing consumers are unaffected (GENC-1351 D2/D3).
2931
- *
2932
- * @public
2933
- */
2934
- export declare interface SessionPersistenceConfig {
2935
- /** Master switch — persistence does nothing unless this is true. */
2936
- enabled?: boolean;
2937
- /** Storage backend. Required for persistence to take effect. */
2938
- provider?: SessionPersistenceProvider;
2939
- }
2940
-
2941
- /**
2942
- * Storage backend for chat-session persistence. The library ships this
2943
- * interface only and wires nothing by default; the host app provides an
2944
- * implementation and opts in via `chatConfig` (GENC-1351 §5.2/D2). Every method
2945
- * is async so a server-backed provider satisfies the same contract as a
2946
- * browser-storage one.
2947
- *
2948
- * @public
2949
- */
2950
- export declare interface SessionPersistenceProvider {
2951
- /**
2952
- * Minimum milliseconds between autosaves for this backend — a throttle the
2953
- * assistant applies to its "save on every transcript change" signal. `0`
2954
- * means save as soon as the current tick settles (coalescing only writes
2955
- * within the same tick), which is right for synchronous, cheap storage like
2956
- * `sessionStorage`/`localStorage`. A network/server backend should set a
2957
- * higher value (e.g. 1000–2000) so it doesn't hammer the wire mid tool-loop.
2958
- *
2959
- * **Required** — not optional — so every implementation makes a deliberate
2960
- * choice for its own write-cost profile rather than inheriting a guess.
2961
- */
2962
- saveDebounceMs: number;
2963
- /** Load the snapshot for `sessionKey`, or `null` if none / unreadable. */
2964
- load(sessionKey: string): Promise<PersistedSession | null>;
2965
- /** Persist `snapshot` for `sessionKey`, overwriting any existing one. */
2966
- save(sessionKey: string, snapshot: PersistedSession): Promise<void>;
2967
- /** Remove any stored snapshot for `sessionKey`. */
2968
- clear(sessionKey: string): Promise<void>;
2969
- /**
2970
- * Load the user's remembered UI preferences for `sessionKey` (GENC-1351) — the
2971
- * "remember chat" toggle plus the cog-menu display switches. Stored
2972
- * **independently of the session snapshot** (survives `clear`) and **independently
2973
- * of the `enabled` toggle** — a user's display choices persist whether or not
2974
- * they remember the chat. `undefined` means none were ever saved → the host's
2975
- * configured `chatConfig.ui` defaults apply. Only the fields the user has changed
2976
- * are present; absent fields keep their config default. Optional: a provider that
2977
- * omits it simply doesn't remember preferences across reloads.
2978
- */
2979
- loadPreferences?(sessionKey: string): Promise<SessionPreferences | undefined>;
2980
- /** Persist the user's UI preferences for `sessionKey` (kept across `clear`). */
2981
- savePreferences?(sessionKey: string, preferences: SessionPreferences): Promise<void>;
2982
- /**
2983
- * Server-saved diagnostics (GENC-1351 §5.8) — a **forward-only append** stream
2984
- * that lets the downloadable debug log span the whole session lifetime, not just
2985
- * the current page load. Optional and **capacious-backends-only**: `WebStorage`
2986
- * omits it (the log dwarfs the restore core), so the feature is simply off there.
2987
- * The element emits *what happened* (new entries since the last flush); the
2988
- * provider owns *how it's filed* (one object per session / per run / per day —
2989
- * its call). Best-effort: a failed write must never affect the chat.
2990
- *
2991
- * Captured **independently of the `enabled` toggle** (like preferences): the
2992
- * forensic log is orthogonal to whether the *chat* is remembered, so it runs
2993
- * whenever a provider implements this — even with "remember chat" off.
2994
- */
2995
- appendDiagnostics?(sessionKey: string, entries: DiagnosticEntry[]): Promise<void>;
2996
- /** Load the full diagnostics stream for `sessionKey` (all appends, any run), for download-reassembly. */
2997
- loadDiagnostics?(sessionKey: string): Promise<DiagnosticEntry[]>;
2998
- /** Hard-delete the diagnostics stream for `sessionKey`. Host/GDPR use — NOT wired to the UI Clear. */
2999
- clearDiagnostics?(sessionKey: string): Promise<void>;
3000
- /**
3001
- * Min ms between diagnostics appends — coarser than `saveDebounceMs` because
3002
- * the log is heavy. Defaults to a sensible coarse value if omitted.
3003
- */
3004
- diagnosticsDebounceMs?: number;
3005
- }
3006
-
3007
- /**
3008
- * User-changeable settings that persist across reloads, independently of the chat
3009
- * snapshot and of the "remember chat" toggle (GENC-1351). All optional — an absent
3010
- * field keeps its `chatConfig.ui` default rather than being forced off.
3011
- *
3012
- * @public
3013
- */
3014
- export declare interface SessionPreferences {
3015
- /** "Remember chat" — whether the session snapshot itself is persisted. */
3016
- enabled?: boolean;
3017
- showToolCalls?: boolean;
3018
- showThinkingSteps?: boolean;
3019
- showNarration?: boolean;
3020
- showAgentSwitchIndicator?: boolean;
3021
- /** Enabled loading-animation ids (`AiAssistantAnimation` values, as plain strings). */
3022
- animations?: string[];
3023
- }
3024
-
3025
2490
  /** Settings vs Cost tab identifiers for the modal tab bar. */
3026
2491
  declare type SettingsModalTab = 'settings' | 'cost';
3027
2492
 
@@ -3111,10 +2576,6 @@ export declare interface StatefulAgentInit<S> {
3111
2576
  /**
3112
2577
  * Construct the agent-scoped state. Called by the framework when this agent
3113
2578
  * becomes active (`onActivate`). Awaited before the agent's first turn runs.
3114
- *
3115
- * On a persisted-session restore, `ctx.restored` carries this agent's previous
3116
- * `serialize` output — rebuild from it (e.g. via `restoreMachine`), or start
3117
- * fresh when it is `undefined`.
3118
2579
  */
3119
2580
  init: (ctx: AgentLifecycleContext) => S | Promise<S>;
3120
2581
  /**
@@ -3228,49 +2689,8 @@ export declare interface StatefulAgentInit<S> {
3228
2689
  * Return value must be JSON-serializable.
3229
2690
  */
3230
2691
  getDebugSnapshot?: (state: S) => unknown;
3231
- /**
3232
- * Lossless serializer for session persistence — infra-agnostic. Return any
3233
- * JSON/structured-clone-safe image of `state`.
3234
- * • Machine agents (`{ machine }`): omit — the default snapshots every
3235
- * machine-shaped property via `getPersistedSnapshot()`.
3236
- * • Plain-data agents (e.g. `{ plan, cursor }`): omit too — the default
3237
- * returns plain state as-is. Provide one only when the state holds
3238
- * something the default can't capture.
3239
- * Distinct from `getDebugSnapshot` (which may be lossy by design). Pair with
3240
- * `init` reading `ctx.restored` to rebuild.
3241
- */
3242
- serialize?: (state: S) => unknown;
3243
- /**
3244
- * Whether the agent's current state is resumable — worth persisting so the
3245
- * session restores mid-flow (GENC-1351 §5.9). Receives the **live** state bag
3246
- * `S` (like the other per-turn resolvers), so a machine agent gates on its step
3247
- * directly: `resumable: ({ state }) => state.machine.state !== 'confirm'`.
3248
- * Return `false` for a point that shouldn't resume — the session isn't persisted,
3249
- * and on return the assistant shows {@link StatefulAgentInit.notResumableMessage}
3250
- * (or a default) and pre-fills the composer with the prompt that started the flow.
3251
- * Only consulted with persistence enabled; a thrown error is treated as `true`
3252
- * (fail-safe — never drop a resumable chat on a predicate bug).
3253
- */
3254
- resumable?: (ctx: StatefulAgentPersistenceContext<S>) => boolean | Promise<boolean>;
3255
- /**
3256
- * Message shown on return when {@link StatefulAgentInit.resumable} returned
3257
- * `false`. Falls back to a built-in default when omitted.
3258
- */
3259
- notResumableMessage?: string;
3260
2692
  }
3261
2693
 
3262
- /**
3263
- * Context passed to a stateful agent's `resumable` predicate (GENC-1351 §5.9) —
3264
- * the standard {@link AgentPersistenceContext} but with `state` as the **live**
3265
- * state bag `S` (not the serialized image), so a machine agent can gate on its
3266
- * current step directly.
3267
- *
3268
- * @beta
3269
- */
3270
- export declare type StatefulAgentPersistenceContext<S> = Omit<AgentPersistenceContext, 'state'> & {
3271
- state: S;
3272
- };
3273
-
3274
2694
  /**
3275
2695
  * A brief, professional fallback agent. States what is available without
3276
2696
  * elaboration. The `{{agents}}` placeholder is replaced at runtime by
@@ -3581,39 +3001,4 @@ export declare type UnresolvedToolInput = (ctx: UnresolvedToolContext) => string
3581
3001
  /** Person silhouette — default user avatar. */
3582
3002
  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>";
3583
3003
 
3584
- /**
3585
- * A {@link SessionPersistenceProvider} backed by a Web Storage area. Both
3586
- * `window.sessionStorage` and `window.localStorage` implement the `Storage`
3587
- * API, so one class serves both: point it at `sessionStorage` for
3588
- * refresh-survival that clears on tab close (the showcase default, O6), or at
3589
- * `localStorage` for durable local persistence.
3590
- *
3591
- * Opt-in: a host constructs it and passes it through `chatConfig`; the library
3592
- * never instantiates it on its own.
3593
- *
3594
- * @public
3595
- */
3596
- export declare class WebStorageSessionProvider implements SessionPersistenceProvider {
3597
- private readonly storage;
3598
- private readonly keyPrefix;
3599
- /**
3600
- * Web storage is synchronous and cheap, so the default is `0` — save as
3601
- * soon as the tick settles, no throttle. Override via `options.saveDebounceMs`
3602
- * (e.g. if pointing at `localStorage` and you'd rather coalesce large writes).
3603
- */
3604
- readonly saveDebounceMs: number;
3605
- constructor(storage: Storage, options?: {
3606
- keyPrefix?: string;
3607
- saveDebounceMs?: number;
3608
- });
3609
- private storageKey;
3610
- /** Preferences key, namespaced apart from the session key so `clear` leaves it. */
3611
- private preferencesKey;
3612
- load(sessionKey: string): Promise<PersistedSession | null>;
3613
- save(sessionKey: string, snapshot: PersistedSession): Promise<void>;
3614
- clear(sessionKey: string): Promise<void>;
3615
- loadPreferences(sessionKey: string): Promise<SessionPreferences | undefined>;
3616
- savePreferences(sessionKey: string, preferences: SessionPreferences): Promise<void>;
3617
- }
3618
-
3619
3004
  export { }