@genesislcap/ai-assistant 14.490.0 → 14.491.0-FUI-2567.1

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 (171) hide show
  1. package/dist/ai-assistant.api.json +6737 -3591
  2. package/dist/ai-assistant.d.ts +879 -183
  3. package/dist/custom-elements.json +1799 -650
  4. package/dist/dts/components/ai-driver/ai-driver.d.ts +32 -8
  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 +13 -29
  9. package/dist/dts/components/chat-driver/chat-driver.d.ts.map +1 -1
  10. package/dist/dts/components/chat-interaction-wrapper/chat-interaction-wrapper.d.ts +0 -7
  11. package/dist/dts/components/chat-interaction-wrapper/chat-interaction-wrapper.d.ts.map +1 -1
  12. package/dist/dts/components/orchestrating-driver/orchestrating-driver.d.ts +15 -4
  13. package/dist/dts/components/orchestrating-driver/orchestrating-driver.d.ts.map +1 -1
  14. package/dist/dts/components/orchestrating-driver/orchestrating-driver.pin.test.d.ts +2 -0
  15. package/dist/dts/components/orchestrating-driver/orchestrating-driver.pin.test.d.ts.map +1 -0
  16. package/dist/dts/components/popout-manager/popout-manager.d.ts +37 -9
  17. package/dist/dts/components/popout-manager/popout-manager.d.ts.map +1 -1
  18. package/dist/dts/components/settings-modal/settings-modal.styles.d.ts.map +1 -1
  19. package/dist/dts/components/settings-modal/settings-modal.template.d.ts.map +1 -1
  20. package/dist/dts/config/config.d.ts +70 -0
  21. package/dist/dts/config/config.d.ts.map +1 -1
  22. package/dist/dts/config/define-stateful-agent.d.ts +73 -1
  23. package/dist/dts/config/define-stateful-agent.d.ts.map +1 -1
  24. package/dist/dts/index.d.ts +1 -0
  25. package/dist/dts/index.d.ts.map +1 -1
  26. package/dist/dts/main/main.d.ts +337 -91
  27. package/dist/dts/main/main.d.ts.map +1 -1
  28. package/dist/dts/main/main.styles.d.ts.map +1 -1
  29. package/dist/dts/main/main.template.d.ts.map +1 -1
  30. package/dist/dts/main/main.types.d.ts +55 -9
  31. package/dist/dts/main/main.types.d.ts.map +1 -1
  32. package/dist/dts/main/popout-interaction-gate.test.d.ts +2 -0
  33. package/dist/dts/main/popout-interaction-gate.test.d.ts.map +1 -0
  34. package/dist/dts/react.d.ts +3 -2
  35. package/dist/dts/state/ai-assistant-slice.d.ts +73 -0
  36. package/dist/dts/state/ai-assistant-slice.d.ts.map +1 -1
  37. package/dist/dts/state/ai-assistant-slice.test.d.ts +2 -0
  38. package/dist/dts/state/ai-assistant-slice.test.d.ts.map +1 -0
  39. package/dist/dts/state/debug-event-log.d.ts +1 -1
  40. package/dist/dts/state/debug-event-log.d.ts.map +1 -1
  41. package/dist/dts/state/persistence/diagnostics-cursors.d.ts +51 -0
  42. package/dist/dts/state/persistence/diagnostics-cursors.d.ts.map +1 -0
  43. package/dist/dts/state/persistence/diagnostics-cursors.test.d.ts +2 -0
  44. package/dist/dts/state/persistence/diagnostics-cursors.test.d.ts.map +1 -0
  45. package/dist/dts/state/persistence/diagnostics.d.ts +65 -0
  46. package/dist/dts/state/persistence/diagnostics.d.ts.map +1 -0
  47. package/dist/dts/state/persistence/diagnostics.test.d.ts +2 -0
  48. package/dist/dts/state/persistence/diagnostics.test.d.ts.map +1 -0
  49. package/dist/dts/state/persistence/index.d.ts +7 -0
  50. package/dist/dts/state/persistence/index.d.ts.map +1 -0
  51. package/dist/dts/state/persistence/persister-registry.d.ts +22 -0
  52. package/dist/dts/state/persistence/persister-registry.d.ts.map +1 -0
  53. package/dist/dts/state/persistence/session-persistence-provider.d.ts +132 -0
  54. package/dist/dts/state/persistence/session-persistence-provider.d.ts.map +1 -0
  55. package/dist/dts/state/persistence/session-persistence-provider.test.d.ts +2 -0
  56. package/dist/dts/state/persistence/session-persistence-provider.test.d.ts.map +1 -0
  57. package/dist/dts/state/persistence/session-persistence.integration.test.d.ts +2 -0
  58. package/dist/dts/state/persistence/session-persistence.integration.test.d.ts.map +1 -0
  59. package/dist/dts/state/persistence/session-persister.d.ts +173 -0
  60. package/dist/dts/state/persistence/session-persister.d.ts.map +1 -0
  61. package/dist/dts/state/persistence/session-persister.test.d.ts +2 -0
  62. package/dist/dts/state/persistence/session-persister.test.d.ts.map +1 -0
  63. package/dist/dts/state/persistence/session-snapshot.d.ts +218 -0
  64. package/dist/dts/state/persistence/session-snapshot.d.ts.map +1 -0
  65. package/dist/dts/state/persistence/session-snapshot.test.d.ts +2 -0
  66. package/dist/dts/state/persistence/session-snapshot.test.d.ts.map +1 -0
  67. package/dist/dts/state/persistence/stateful-restore.e2e.test.d.ts +2 -0
  68. package/dist/dts/state/persistence/stateful-restore.e2e.test.d.ts.map +1 -0
  69. package/dist/dts/state/session-store.d.ts +6 -0
  70. package/dist/dts/state/session-store.d.ts.map +1 -1
  71. package/dist/dts/utils/history-transform.d.ts +38 -0
  72. package/dist/dts/utils/history-transform.d.ts.map +1 -1
  73. package/dist/dts/utils/history-transform.test.d.ts +2 -0
  74. package/dist/dts/utils/history-transform.test.d.ts.map +1 -0
  75. package/dist/dts/utils/message-partition.d.ts +27 -0
  76. package/dist/dts/utils/message-partition.d.ts.map +1 -1
  77. package/dist/dts/utils/resolve-preference-baseline.d.ts +43 -0
  78. package/dist/dts/utils/resolve-preference-baseline.d.ts.map +1 -0
  79. package/dist/dts/utils/resolve-preference-baseline.test.d.ts +2 -0
  80. package/dist/dts/utils/resolve-preference-baseline.test.d.ts.map +1 -0
  81. package/dist/dts/utils/with-timeout.d.ts +12 -0
  82. package/dist/dts/utils/with-timeout.d.ts.map +1 -0
  83. package/dist/esm/components/chat-driver/chat-driver.compact.test.js +93 -0
  84. package/dist/esm/components/chat-driver/chat-driver.js +101 -65
  85. package/dist/esm/components/chat-driver/chat-driver.test.js +0 -45
  86. package/dist/esm/components/chat-interaction-wrapper/chat-interaction-wrapper.js +17 -35
  87. package/dist/esm/components/chat-interaction-wrapper/chat-interaction-wrapper.test.js +0 -62
  88. package/dist/esm/components/orchestrating-driver/orchestrating-driver.js +32 -14
  89. package/dist/esm/components/orchestrating-driver/orchestrating-driver.pin.test.js +61 -0
  90. package/dist/esm/components/popout-manager/popout-manager.js +76 -27
  91. package/dist/esm/components/settings-modal/settings-modal.styles.js +24 -0
  92. package/dist/esm/components/settings-modal/settings-modal.template.js +14 -1
  93. package/dist/esm/config/define-stateful-agent.js +81 -0
  94. package/dist/esm/index.js +1 -0
  95. package/dist/esm/main/main.js +929 -223
  96. package/dist/esm/main/main.styles.js +55 -0
  97. package/dist/esm/main/main.template.js +94 -10
  98. package/dist/esm/main/main.types.js +27 -0
  99. package/dist/esm/main/popout-interaction-gate.test.js +58 -0
  100. package/dist/esm/state/ai-assistant-slice.js +85 -25
  101. package/dist/esm/state/ai-assistant-slice.test.js +85 -0
  102. package/dist/esm/state/debug-event-log.js +10 -0
  103. package/dist/esm/state/persistence/diagnostics-cursors.js +47 -0
  104. package/dist/esm/state/persistence/diagnostics-cursors.test.js +30 -0
  105. package/dist/esm/state/persistence/diagnostics.js +81 -0
  106. package/dist/esm/state/persistence/diagnostics.test.js +72 -0
  107. package/dist/esm/state/persistence/index.js +3 -0
  108. package/dist/esm/state/persistence/persister-registry.js +48 -0
  109. package/dist/esm/state/persistence/session-persistence-provider.js +95 -0
  110. package/dist/esm/state/persistence/session-persistence-provider.test.js +110 -0
  111. package/dist/esm/state/persistence/session-persistence.integration.test.js +109 -0
  112. package/dist/esm/state/persistence/session-persister.js +642 -0
  113. package/dist/esm/state/persistence/session-persister.test.js +314 -0
  114. package/dist/esm/state/persistence/session-snapshot.js +240 -0
  115. package/dist/esm/state/persistence/session-snapshot.test.js +235 -0
  116. package/dist/esm/state/persistence/stateful-restore.e2e.test.js +149 -0
  117. package/dist/esm/utils/history-transform.js +101 -0
  118. package/dist/esm/utils/history-transform.test.js +137 -0
  119. package/dist/esm/utils/message-partition.js +30 -2
  120. package/dist/esm/utils/message-partition.test.js +20 -1
  121. package/dist/esm/utils/resolve-preference-baseline.js +53 -0
  122. package/dist/esm/utils/resolve-preference-baseline.test.js +69 -0
  123. package/dist/esm/utils/with-timeout.js +28 -0
  124. package/dist/react.cjs +6 -1
  125. package/dist/react.mjs +6 -1
  126. package/dist/tsconfig.tsbuildinfo +1 -1
  127. package/docs/migration-GENC-1351.md +172 -0
  128. package/package.json +17 -17
  129. package/src/components/ai-driver/ai-driver.ts +36 -17
  130. package/src/components/chat-driver/chat-driver.compact.test.ts +131 -0
  131. package/src/components/chat-driver/chat-driver.test.ts +0 -71
  132. package/src/components/chat-driver/chat-driver.ts +103 -70
  133. package/src/components/chat-interaction-wrapper/chat-interaction-wrapper.test.ts +0 -81
  134. package/src/components/chat-interaction-wrapper/chat-interaction-wrapper.ts +18 -41
  135. package/src/components/orchestrating-driver/orchestrating-driver.pin.test.ts +96 -0
  136. package/src/components/orchestrating-driver/orchestrating-driver.ts +36 -18
  137. package/src/components/popout-manager/popout-manager.ts +82 -28
  138. package/src/components/settings-modal/settings-modal.styles.ts +24 -0
  139. package/src/components/settings-modal/settings-modal.template.ts +27 -1
  140. package/src/config/config.ts +71 -0
  141. package/src/config/define-stateful-agent.ts +134 -0
  142. package/src/index.ts +1 -0
  143. package/src/main/main.styles.ts +55 -0
  144. package/src/main/main.template.ts +121 -11
  145. package/src/main/main.ts +937 -199
  146. package/src/main/main.types.ts +59 -10
  147. package/src/main/popout-interaction-gate.test.ts +92 -0
  148. package/src/state/ai-assistant-slice.test.ts +114 -0
  149. package/src/state/ai-assistant-slice.ts +134 -25
  150. package/src/state/debug-event-log.ts +22 -1
  151. package/src/state/persistence/diagnostics-cursors.test.ts +53 -0
  152. package/src/state/persistence/diagnostics-cursors.ts +80 -0
  153. package/src/state/persistence/diagnostics.test.ts +95 -0
  154. package/src/state/persistence/diagnostics.ts +110 -0
  155. package/src/state/persistence/index.ts +10 -0
  156. package/src/state/persistence/persister-registry.ts +55 -0
  157. package/src/state/persistence/session-persistence-provider.test.ts +136 -0
  158. package/src/state/persistence/session-persistence-provider.ts +202 -0
  159. package/src/state/persistence/session-persistence.integration.test.ts +134 -0
  160. package/src/state/persistence/session-persister.test.ts +428 -0
  161. package/src/state/persistence/session-persister.ts +689 -0
  162. package/src/state/persistence/session-snapshot.test.ts +327 -0
  163. package/src/state/persistence/session-snapshot.ts +340 -0
  164. package/src/state/persistence/stateful-restore.e2e.test.ts +221 -0
  165. package/src/utils/history-transform.test.ts +197 -0
  166. package/src/utils/history-transform.ts +117 -0
  167. package/src/utils/message-partition.test.ts +27 -1
  168. package/src/utils/message-partition.ts +41 -2
  169. package/src/utils/resolve-preference-baseline.test.ts +84 -0
  170. package/src/utils/resolve-preference-baseline.ts +80 -0
  171. package/src/utils/with-timeout.ts +24 -0
@@ -0,0 +1,173 @@
1
+ import type { AiDriver } from '../../components/ai-driver/ai-driver';
2
+ import type { SessionStoreReturn } from '../session-store';
3
+ import { type DiagnosticEntry } from './diagnostics';
4
+ import type { SessionPersistenceConfig, SessionPreferences } from './session-persistence-provider';
5
+ /**
6
+ * Dependencies the persister reads through — all getters so it always sees current
7
+ * state and never holds a stale reference (the driver can be rebuilt on
8
+ * agents-change, and the creating view can disconnect). Injected rather than read
9
+ * from the module registries directly so the class is unit-testable with fakes.
10
+ *
11
+ * @internal
12
+ */
13
+ export interface SessionPersisterDeps {
14
+ /** Session identity — stable for the persister's lifetime. */
15
+ stateKey: string;
16
+ /** Current host persistence config (`enabled` + `provider`). Read fresh each op. */
17
+ getPersistence: () => SessionPersistenceConfig;
18
+ /** Names of the currently-configured agents (for the restore orphan check). */
19
+ getAgentNames: () => string[];
20
+ /** The session's shared driver, or `undefined` before it exists. */
21
+ getDriver: () => AiDriver | undefined;
22
+ /** The session's shared store, or `undefined` before it exists. */
23
+ getStore: () => SessionStoreReturn | undefined;
24
+ /**
25
+ * Build the current diagnostic entries (message/turn/event/meta-snapshot). Stays
26
+ * element-owned — it reads the host's agents, active-agent debug snapshot, meta
27
+ * events, etc. — and is diffed against the shared cursors here (GENC-1351 §5.10).
28
+ */
29
+ getDiagnosticEntries: () => DiagnosticEntry[];
30
+ }
31
+ /**
32
+ * Owns **restore-core** persistence for one session (GENC-1351 §5.10) — the
33
+ * save/restore/freeze of the {@link PersistedSession} snapshot plus the
34
+ * carry-forward cache. Created once per session via `persister-registry.ts` and
35
+ * shared by every element view, so there is a single save timer and a single
36
+ * cache: the per-view double-write races (and the corruption they caused under a
37
+ * non-atomic backend) are gone by construction.
38
+ *
39
+ * Owns all provider I/O for the session: the restore-core snapshot (save/restore/
40
+ * freeze), the user-preferences blob (load/save — the element keeps only the
41
+ * `chatConfig`-defaults reconciler), and the diagnostics-append scheduling (one
42
+ * timer per session; entry-building stays element-owned via `getDiagnosticEntries`).
43
+ *
44
+ * @internal
45
+ */
46
+ export declare class SessionPersister {
47
+ private deps;
48
+ private _saveTimer?;
49
+ private _lastSaveAt;
50
+ private _diagnosticsTimer?;
51
+ private _lastDiagnosticsAt;
52
+ /**
53
+ * The flow-owner's last-known-good serialized image, carried forward when a
54
+ * post-restore autosave fires before the agent re-activates (its live capture is
55
+ * empty). Seeded on restore. See {@link reconcileAgentSnapshots}.
56
+ */
57
+ private _cache;
58
+ /**
59
+ * The loaded preferences blob (GENC-1351 §5.10 Phase 2), owned here so it's
60
+ * **shared per session** — the element's `applyPreferenceBaseline` reconciler reads
61
+ * it via {@link storedPreferences}. Kept fresh on every save, so a later re-reconcile
62
+ * uses the latest choices, not the stale startup blob. `null` = loaded, none stored.
63
+ */
64
+ private _storedPreferences;
65
+ /**
66
+ * Whether the user has changed any preference this session. **Shared per session**
67
+ * (was per-element, which let the two views disagree and one clobber the other's
68
+ * choice — issue #1). Once set, the reconciler freezes so `chatConfig` defaults
69
+ * can't overwrite a live user choice, regardless of which view toggled it.
70
+ */
71
+ private _preferencesUserChanged;
72
+ constructor(deps: SessionPersisterDeps);
73
+ /**
74
+ * Re-point the dependency getters at the currently-live element view. The
75
+ * persister outlives any single element (it's cached per session in
76
+ * `persister-registry.ts`), so when a later element mounts on the same session
77
+ * — e.g. an SPA teardown + remount — it MUST rebind, or the persister keeps
78
+ * calling the torn-down creator's `getDiagnosticEntries`/`getPersistence`/
79
+ * `getAgentNames` (which read a detached driver/store → empty), silently halting
80
+ * diagnostics + autosave capture (GENC-1351 §5.10). `stateKey` is unchanged.
81
+ *
82
+ * @internal
83
+ */
84
+ rebindDeps(deps: SessionPersisterDeps): void;
85
+ /** The loaded preferences blob (shared per session); read by the element's reconciler. */
86
+ get storedPreferences(): SessionPreferences | null;
87
+ /** True once the user has changed any preference this session (shared per session). */
88
+ get preferencesUserChanged(): boolean;
89
+ private get stateKey();
90
+ private logMeta;
91
+ /**
92
+ * Throttled autosave. Called by every view on each transcript change; the single
93
+ * shared timer coalesces them into at most one save per the provider's
94
+ * `saveDebounceMs`. `saveDebounceMs: 0` (e.g. `sessionStorage`) means save as
95
+ * soon as the current tick settles.
96
+ */
97
+ scheduleSave(): void;
98
+ /**
99
+ * Cancel a pending debounced autosave **without flushing it** (GENC-1351 §5.12).
100
+ * Called before a session switch/re-key so the outgoing transcript can never be
101
+ * written to the incoming session's file after the key changes — the clobber
102
+ * guard for in-place project switching.
103
+ */
104
+ cancelPendingSave(): void;
105
+ /**
106
+ * Capture the current session to durable storage (GENC-1351 §5.1). Reads the
107
+ * full transcript from the driver and the restorable scalars from the store, and
108
+ * captures the active stateful agent's `serialize()` into `agentSnapshots`.
109
+ */
110
+ private persistSession;
111
+ /**
112
+ * Page-reload restore (GENC-1351 §5.3). With a stored snapshot for this session,
113
+ * hydrate the store and reseed the driver so the conversation continues. No-op
114
+ * when disabled, absent, or version/host mismatched. An `interrupted` snapshot
115
+ * (§5.9) restores the conversation but shows a "start again" assistant message
116
+ * instead of rehydrating the mid-flight flow.
117
+ */
118
+ restore(): Promise<void>;
119
+ /**
120
+ * Surface a non-fatal "couldn't restore" notice after a failed restore (load
121
+ * timeout/error, or an unusable snapshot) so a vanished conversation isn't a
122
+ * silent mystery on reload (GENC-1351 §6). Reuses the display-only `system-event`
123
+ * divider (like the "Restored…" one) — stripped before persist, so it never lands
124
+ * in the fresh session's saved history. `loadHistory` is safe here: this path only
125
+ * runs when nothing was restored, so the driver is empty.
126
+ */
127
+ private showRestoreFailedNotice;
128
+ /**
129
+ * Drop the restore-core snapshot (the "remember chat" toggle-off and the Clear
130
+ * action) and reset the carry-forward cache. Diagnostics + preferences are
131
+ * separate and untouched here.
132
+ */
133
+ clearRestoreCore(): Promise<void>;
134
+ /**
135
+ * Load the remembered preferences blob (bounded by {@link RESTORE_TIMEOUT_MS}) into
136
+ * {@link storedPreferences}. A throw propagates to the caller (the element wraps it
137
+ * and falls back to config defaults); on success `null` = no provider / none stored.
138
+ */
139
+ loadPreferences(): Promise<void>;
140
+ /**
141
+ * Persist the preferences blob. Only ever called on a genuine user change, so it
142
+ * also records that (freezing the reconciler — shared per session) and keeps
143
+ * {@link storedPreferences} fresh. Fires **regardless of "remember chat"** — display
144
+ * choices are the user's — needing only a provider that implements `savePreferences`.
145
+ */
146
+ savePreferences(prefs: SessionPreferences): void;
147
+ /**
148
+ * Throttled diagnostics append (GENC-1351 §5.8). On each transcript change, if the
149
+ * provider persists diagnostics, coalesce and append the new activity since the
150
+ * last flush (coarser than the restore-core save — the log is heavy). Keyed on
151
+ * provider capability only, **independent of "remember chat"**. No-op without a
152
+ * diagnostics-capable provider, so it's free for other consumers.
153
+ */
154
+ scheduleDiagnostics(): void;
155
+ /**
156
+ * Append the diagnostic entries created since the last flush to the provider's
157
+ * forward-only stream. Best-effort — a failed write is logged and never touches
158
+ * the chat. (The cursors advance on collect, so a dropped batch isn't retried;
159
+ * acceptable for a forensic stream that isn't the source of truth.) Also called
160
+ * directly by the download path to land the current delta before reassembly.
161
+ */
162
+ flushDiagnostics(): Promise<void>;
163
+ /**
164
+ * The diagnostic entries not yet appended this load — the forward-capture delta
165
+ * (§5.8). Skips messages present at restore or already appended; emits each turn
166
+ * (by turn-index) and meta-event (by index) once; appends a `meta-snapshot` only
167
+ * when the block changed. Advances the shared per-session cursors as it goes.
168
+ */
169
+ private collectDiagnosticsDelta;
170
+ /** Cancel any pending timers. Called on explicit session teardown. */
171
+ dispose(): void;
172
+ }
173
+ //# sourceMappingURL=session-persister.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-persister.d.ts","sourceRoot":"","sources":["../../../../src/state/persistence/session-persister.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sCAAsC,CAAC;AAWrE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAyB,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AAE5E,OAAO,KAAK,EAAE,wBAAwB,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAsCnG;;;;;;;GAOG;AACH,MAAM,WAAW,oBAAoB;IACnC,8DAA8D;IAC9D,QAAQ,EAAE,MAAM,CAAC;IACjB,oFAAoF;IACpF,cAAc,EAAE,MAAM,wBAAwB,CAAC;IAC/C,+EAA+E;IAC/E,aAAa,EAAE,MAAM,MAAM,EAAE,CAAC;IAC9B,oEAAoE;IACpE,SAAS,EAAE,MAAM,QAAQ,GAAG,SAAS,CAAC;IACtC,mEAAmE;IACnE,QAAQ,EAAE,MAAM,kBAAkB,GAAG,SAAS,CAAC;IAC/C;;;;OAIG;IACH,oBAAoB,EAAE,MAAM,eAAe,EAAE,CAAC;CAC/C;AAED;;;;;;;;;;;;;;GAcG;AACH,qBAAa,gBAAgB;IA0Bf,OAAO,CAAC,IAAI;IAzBxB,OAAO,CAAC,UAAU,CAAC,CAAgC;IACnD,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,iBAAiB,CAAC,CAAgC;IAC1D,OAAO,CAAC,kBAAkB,CAAK;IAC/B;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAA+B;IAC7C;;;;;OAKG;IACH,OAAO,CAAC,kBAAkB,CAAmC;IAC7D;;;;;OAKG;IACH,OAAO,CAAC,uBAAuB,CAAS;gBAEpB,IAAI,EAAE,oBAAoB;IAE9C;;;;;;;;;;OAUG;IACH,UAAU,CAAC,IAAI,EAAE,oBAAoB,GAAG,IAAI;IAI5C,0FAA0F;IAC1F,IAAI,iBAAiB,IAAI,kBAAkB,GAAG,IAAI,CAEjD;IAED,uFAAuF;IACvF,IAAI,sBAAsB,IAAI,OAAO,CAEpC;IAED,OAAO,KAAK,QAAQ,GAEnB;IAED,OAAO,CAAC,OAAO;IAIf;;;;;OAKG;IACH,YAAY,IAAI,IAAI;IAapB;;;;;OAKG;IACH,iBAAiB,IAAI,IAAI;IAOzB;;;;OAIG;YACW,cAAc;IAsJ5B;;;;;;OAMG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAoK9B;;;;;;;OAOG;IACH,OAAO,CAAC,uBAAuB;IAU/B;;;;OAIG;IACG,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IAiBvC;;;;OAIG;IACG,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAatC;;;;;OAKG;IACH,eAAe,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI;IAchD;;;;;;OAMG;IACH,mBAAmB,IAAI,IAAI;IAiB3B;;;;;;OAMG;IACG,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IAYvC;;;;;OAKG;IACH,OAAO,CAAC,uBAAuB;IAwC/B,sEAAsE;IACtE,OAAO,IAAI,IAAI;CAMhB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=session-persister.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-persister.test.d.ts","sourceRoot":"","sources":["../../../../src/state/persistence/session-persister.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,218 @@
1
+ import type { ChatMessage } from '@genesislcap/foundation-ai';
2
+ import type { LoadSessionPayload } from '../ai-assistant-slice';
3
+ /**
4
+ * Schema version of the persisted session shape. Bump on an incompatible
5
+ * change; a snapshot whose `version` doesn't match is discarded on load rather
6
+ * than risk feeding a stale shape into restore.
7
+ *
8
+ * @public
9
+ */
10
+ export declare const PERSISTED_SESSION_VERSION = 1;
11
+ /**
12
+ * A durable, restorable snapshot of one chat session — the *restorable core* of
13
+ * the debug log (GENC-1351 §5.1/D1), captured losslessly and independently of
14
+ * the diagnostic timeline. Written by a `SessionPersistenceProvider` and read
15
+ * back on page-reload restore.
16
+ *
17
+ * @public
18
+ */
19
+ export interface PersistedSession {
20
+ /** Schema version — see {@link PERSISTED_SESSION_VERSION}. */
21
+ version: number;
22
+ /** ISO timestamp the snapshot was written. */
23
+ savedAt: string;
24
+ /** `window.location.host` at save time — restore refuses a cross-host snapshot. */
25
+ host: string;
26
+ /** The session this snapshot belongs to (the assistant's state key). */
27
+ sessionKey: string;
28
+ /** Full conversation transcript (`driver.getRawHistory()`) — the source of truth. */
29
+ messages: ChatMessage[];
30
+ /** Name of the agent active at save time, if any. */
31
+ activeAgentName?: string;
32
+ /** User's pinned agent (sticky picker choice); `null` = Auto. */
33
+ pinnedAgentName: string | null;
34
+ /** Agent that owned a guided flow at save time; `null` = none. */
35
+ flowOwnerAgentName: string | null;
36
+ /** Aggregated USD cost across the session. */
37
+ sessionCostUsd: number;
38
+ /** Provider-reported context-window usage on the last turn. */
39
+ contextTokens?: number;
40
+ /** Context-window limit for the active model. */
41
+ contextLimit?: number;
42
+ /** Active model id (e.g. `claude-sonnet-4-6`). */
43
+ activeModel?: string;
44
+ /** Name of the provider used on the last turn. */
45
+ activeProviderName?: string;
46
+ /**
47
+ * Per-stateful-agent serialized state images (each from an agent's
48
+ * `serialize()`), keyed by agent name. Handed back to the agent's
49
+ * `init({ restored })` on restore. Typically holds at most the active
50
+ * flow-owner — other stateful agents are disposed when switched away. The
51
+ * value shape is the agent's own, hence `unknown`.
52
+ */
53
+ agentSnapshots: Record<string, unknown>;
54
+ /**
55
+ * Interrupted-flow marker (GENC-1351 §5.9). Present when the session was saved
56
+ * while an agent declared its current state non-resumable (`resumable === false`).
57
+ * The **conversation is still persisted and restored in full** — only the running
58
+ * agent's flow-state is dropped (`agentSnapshots` empty, `flowOwnerAgentName`
59
+ * null), so restore does not rehydrate the mid-flight flow. On restore the
60
+ * assistant appends `message` as a normal assistant bubble and pre-fills the
61
+ * composer with `prompt` so the user can re-run it.
62
+ */
63
+ interrupted?: {
64
+ /** Shown as an assistant message on return. */
65
+ message: string;
66
+ /** The prompt that started the flow, pre-filled into the composer on return. */
67
+ prompt?: string;
68
+ };
69
+ }
70
+ /**
71
+ * Everything needed to assemble a {@link PersistedSession} except the stamped
72
+ * metadata (`version`, `savedAt`), which `createPersistedSession` fills.
73
+ *
74
+ * @internal
75
+ */
76
+ export interface PersistedSessionInput {
77
+ sessionKey: string;
78
+ host: string;
79
+ messages: ChatMessage[];
80
+ activeAgentName?: string;
81
+ pinnedAgentName: string | null;
82
+ flowOwnerAgentName: string | null;
83
+ sessionCostUsd: number;
84
+ contextTokens?: number;
85
+ contextLimit?: number;
86
+ activeModel?: string;
87
+ activeProviderName?: string;
88
+ agentSnapshots?: Record<string, unknown>;
89
+ }
90
+ /**
91
+ * Assemble a versioned {@link PersistedSession}, stamping `version` and
92
+ * `savedAt`. Pure but for the timestamp (reads the host clock at call time).
93
+ *
94
+ * @internal
95
+ */
96
+ export declare function createPersistedSession(input: PersistedSessionInput): PersistedSession;
97
+ /**
98
+ * Resolve the notice text + pre-fill prompt for an interrupted (non-resumable) flow
99
+ * (GENC-1351 §5.9). Pure — the decision half of the persist gate, split out so it's
100
+ * unit-testable independent of the save path:
101
+ * - `resumeMessage`: the agent's `notResumableMessage` when non-blank, else the
102
+ * passed default.
103
+ * - `resumePrompt`: the captured flow-activating prompt, falling back to the last
104
+ * user message in the transcript (covers a stateless agent that declines to
105
+ * persist without owning a flow); `undefined` when neither exists.
106
+ *
107
+ * @internal
108
+ */
109
+ export declare function resolveNonResumableNotice(input: {
110
+ notResumableMessage?: string;
111
+ flowActivationPrompt?: string | null;
112
+ messages: ReadonlyArray<ChatMessage>;
113
+ defaultMessage: string;
114
+ }): {
115
+ resumeMessage: string;
116
+ resumePrompt?: string;
117
+ };
118
+ /**
119
+ * Index of the last `user`-role message in `messages`, or `-1` when there is none.
120
+ * The single backward scan behind "what did the user last say" — used to slice the
121
+ * transcript to a clean boundary (`keepThroughLastUserMessage`) and to recover a
122
+ * flow-activation prompt. Allocation-free (no reversed copy).
123
+ *
124
+ * @internal
125
+ */
126
+ export declare function lastUserMessageIndex(messages: ReadonlyArray<ChatMessage>): number;
127
+ /**
128
+ * Type guard: is `value` a {@link PersistedSession} we can safely restore?
129
+ * Gates on matching schema version, same host, and a messages array — the
130
+ * minimum needed to avoid feeding a stale or cross-app blob into restore.
131
+ *
132
+ * @internal
133
+ */
134
+ export declare function isRestorableSession(value: unknown, opts: {
135
+ host: string;
136
+ version?: number;
137
+ }): value is PersistedSession;
138
+ /**
139
+ * Project a {@link PersistedSession} onto the Redux `loadSession` payload (the
140
+ * fields restored verbatim into the slice). Agent identity + machine snapshots
141
+ * are applied by the host separately.
142
+ *
143
+ * @internal
144
+ */
145
+ export declare function toLoadSessionPayload(s: PersistedSession): LoadSessionPayload;
146
+ /**
147
+ * Trim a restored transcript back to the last point a provider will accept.
148
+ *
149
+ * Autosave fires on every transcript change (GENC-1351 §5.3) so it can land
150
+ * mid-turn — meaning a snapshot can end on an *incomplete* turn:
151
+ * • an assistant `tool_use` whose `tool_result` hasn't arrived (or only some
152
+ * of its calls are answered) — an orphaned call makes the next turn invalid;
153
+ * • an empty streaming/`thinking` placeholder assistant message;
154
+ * • a pending (unresolved) interaction — a mid-`requestInteraction` turn that
155
+ * can't be resumed (explicitly unsupported).
156
+ *
157
+ * Walks back from the end, dropping such trailing messages until the transcript
158
+ * is balanced — every assistant tool call has its matching result — and ends on
159
+ * a clean boundary. Returns the input unchanged (same reference) when already
160
+ * clean. Turns a mid-turn reload into "recover to the last complete exchange"
161
+ * rather than a hard drop.
162
+ *
163
+ * @internal
164
+ */
165
+ export declare function trimToRestorableBoundary(messages: ChatMessage[]): ChatMessage[];
166
+ /**
167
+ * Keep the transcript through the **last user message** (inclusive), dropping any
168
+ * trailing assistant/tool messages after it (GENC-1351 §5.9). Used by the freeze
169
+ * fallback: when a flow goes non-resumable and there's no prior resumable snapshot
170
+ * to freeze at, we keep the conversation + the prompt that triggered the flow but
171
+ * discard the agent's in-flight work — so a reload shows the user's request, not the
172
+ * half-done agent turns. Returns the input unchanged (same ref) when it already ends
173
+ * on a user message, or when there is no user message at all (nothing to trim to).
174
+ *
175
+ * @internal
176
+ */
177
+ export declare function keepThroughLastUserMessage(messages: ChatMessage[]): ChatMessage[];
178
+ /**
179
+ * Names of agents the restored session holds machine/state snapshots for but
180
+ * which are **not** in the currently-configured agent set — their flow cannot
181
+ * resume. Common when the host's agent array is dynamic (agents gated by feature
182
+ * flags, project state, or permissions; e.g. genesis-create). Callers should
183
+ * surface these; the restore is otherwise non-fatal (the transcript and any
184
+ * known agents still restore). Returns `[]` when `knownAgentNames` is empty —
185
+ * the agent set isn't known yet, so we can't classify without false positives.
186
+ *
187
+ * @beta
188
+ */
189
+ export declare function unknownAgentSnapshots(snapshot: PersistedSession, knownAgentNames: Iterable<string>): string[];
190
+ /**
191
+ * Reconcile the per-agent `serialize()` images to persist on a session save,
192
+ * guarding against a post-restore autosave wiping a mid-flow machine (GENC-1351).
193
+ *
194
+ * A restore reads a good snapshot, but the restore's own history change fires an
195
+ * autosave **before** the pinned stateful agent re-activates — at which point the
196
+ * live capture (`getActiveAgent()?.serialize()`) is empty even though a flow is
197
+ * mid-stream. Writing that empty map would overwrite the stored machine snapshot,
198
+ * resetting the flow to its initial step on the *next* reload. So when a flow is
199
+ * owned (`flowOwnerName`) but its live image is missing, carry the last-known-good
200
+ * image forward instead of dropping it.
201
+ *
202
+ * Pure: the caller owns the `lastKnownGood` cache and its lifecycle (seeded on
203
+ * restore, reset on clear). This decides only what to persist now and what the
204
+ * cache should become — advanced only when non-empty, so an empty capture can
205
+ * never erase a good cache.
206
+ *
207
+ * @param live - Agent images captured live this save, keyed by agent name.
208
+ * @param flowOwnerName - The agent owning the in-flight flow, or `null`.
209
+ * @param lastKnownGood - The last non-empty images persisted or restored.
210
+ * @returns `snapshots` to persist, and the `cache` to remember for next time.
211
+ *
212
+ * @internal
213
+ */
214
+ export declare function reconcileAgentSnapshots(live: Record<string, unknown>, flowOwnerName: string | null, lastKnownGood: Record<string, unknown>): {
215
+ snapshots: Record<string, unknown>;
216
+ cache: Record<string, unknown>;
217
+ };
218
+ //# sourceMappingURL=session-snapshot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-snapshot.d.ts","sourceRoot":"","sources":["../../../../src/state/persistence/session-snapshot.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=session-snapshot.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-snapshot.test.d.ts","sourceRoot":"","sources":["../../../../src/state/persistence/session-snapshot.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ import '../../components/chat-driver/align-event-globals';
2
+ //# sourceMappingURL=stateful-restore.e2e.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stateful-restore.e2e.test.d.ts","sourceRoot":"","sources":["../../../../src/state/persistence/stateful-restore.e2e.test.ts"],"names":[],"mappings":"AASA,OAAO,kDAAkD,CAAC"}
@@ -19,7 +19,11 @@ declare function makeStore(devTools: boolean | undefined): import("@genesislcap/
19
19
  setActiveAgent(state: import("immer").WritableDraft<AiAssistantSessionState>, action: import("@reduxjs/toolkit").PayloadAction<Omit<import("..").AgentConfig, "toolHandlers"> | undefined>): void;
20
20
  setPinnedAgentName(state: import("immer").WritableDraft<AiAssistantSessionState>, action: import("@reduxjs/toolkit").PayloadAction<string | null>): void;
21
21
  setFlowOwnerAgentName(state: import("immer").WritableDraft<AiAssistantSessionState>, action: import("@reduxjs/toolkit").PayloadAction<string | null>): void;
22
+ setFlowActivationPrompt(state: import("immer").WritableDraft<AiAssistantSessionState>, action: import("@reduxjs/toolkit").PayloadAction<string | null>): void;
22
23
  setAgentPickerOpen(state: import("immer").WritableDraft<AiAssistantSessionState>, action: import("@reduxjs/toolkit").PayloadAction<boolean>): void;
24
+ setSessionMenuOpen(state: import("immer").WritableDraft<AiAssistantSessionState>, action: import("@reduxjs/toolkit").PayloadAction<boolean>): void;
25
+ setCompacting(state: import("immer").WritableDraft<AiAssistantSessionState>, action: import("@reduxjs/toolkit").PayloadAction<boolean>): void;
26
+ setRestoring(state: import("immer").WritableDraft<AiAssistantSessionState>, action: import("@reduxjs/toolkit").PayloadAction<boolean>): void;
23
27
  setInputValue(state: import("immer").WritableDraft<AiAssistantSessionState>, action: import("@reduxjs/toolkit").PayloadAction<string>): void;
24
28
  setLiveSubAgentTrace(state: import("immer").WritableDraft<AiAssistantSessionState>, action: import("@reduxjs/toolkit").PayloadAction<import("@genesislcap/foundation-ai").ChatMessage[]>): void;
25
29
  setLiveSubAgentName(state: import("immer").WritableDraft<AiAssistantSessionState>, action: import("@reduxjs/toolkit").PayloadAction<string | null>): void;
@@ -27,6 +31,8 @@ declare function makeStore(devTools: boolean | undefined): import("@genesislcap/
27
31
  removeInputOverride(state: import("immer").WritableDraft<AiAssistantSessionState>, action: import("@reduxjs/toolkit").PayloadAction<{
28
32
  id: string;
29
33
  }>): void;
34
+ loadSession(state: import("immer").WritableDraft<AiAssistantSessionState>, action: import("@reduxjs/toolkit").PayloadAction<import("./ai-assistant-slice").LoadSessionPayload>): void;
35
+ resetSession(state: import("immer").WritableDraft<AiAssistantSessionState>): void;
30
36
  }, "aiAssistant", "aiAssistant", {}>[]>;
31
37
  /**
32
38
  * Returns the session store for the given key, creating one if it does not
@@ -1 +1 @@
1
- {"version":3,"file":"session-store.d.ts","sourceRoot":"","sources":["../../../src/state/session-store.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,uBAAuB,EAC7B,MAAM,sBAAsB,CAAC;AAE9B,KAAK,kBAAkB,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC;AAIvD,iBAAS,SAAS,CAAC,QAAQ,EAAE,OAAO,GAAG,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;wCAM/C;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,kBAAkB,CAMnF;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEpD;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI,IAAI,CAE5C;AAED,YAAY,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,CAAC"}
1
+ {"version":3,"file":"session-store.d.ts","sourceRoot":"","sources":["../../../src/state/session-store.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,uBAAuB,EAC7B,MAAM,sBAAsB,CAAC;AAE9B,KAAK,kBAAkB,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC;AAIvD,iBAAS,SAAS,CAAC,QAAQ,EAAE,OAAO,GAAG,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wCAM/C;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,kBAAkB,CAMnF;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEpD;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI,IAAI,CAE5C;AAED,YAAY,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,CAAC"}
@@ -10,4 +10,42 @@ export declare function transformHistoryForAgent(history: ChatMessage[], agentNa
10
10
  * verbatim; older messages have their tool payloads masked.
11
11
  */
12
12
  export declare function applyHistoryCap(history: readonly ChatMessage[], cap: number): ChatMessage[];
13
+ /** Recent messages kept verbatim when compacting; everything earlier is summarized. */
14
+ export declare const COMPACT_KEEP_RECENT_MESSAGES = 4;
15
+ /** Don't bother compacting unless at least this many messages would be summarized. */
16
+ export declare const COMPACT_MIN_MESSAGES_TO_COMPACT = 4;
17
+ /**
18
+ * Index at which the verbatim tail begins — everything before it gets summarized.
19
+ * The tail starts on a clean turn boundary (a `user` message): a user message
20
+ * never appears between a `tool_use` and its `tool_result`, so cutting there
21
+ * guarantees the summarized region is tool-pair-balanced (compaction only runs
22
+ * when idle, so history is turn-complete). Returns `null` when there is nothing
23
+ * worth compacting (too short, or no earlier user boundary) — e.g. a freshly
24
+ * restored session whose only user turn is the current one.
25
+ */
26
+ export declare function findCompactionCut(history: readonly ChatMessage[]): number | null;
27
+ /**
28
+ * Build the one-shot summarizer prompt for a run of older messages (used with
29
+ * `AIProvider.prompt`). Mirrors the `<conversation_history>` block convention
30
+ * that suggestions use. Any existing `compacted-summary` at the head is folded
31
+ * in (rendered as prior-summary context), so rolling re-compaction produces one
32
+ * combined summary.
33
+ */
34
+ export declare function buildCompactionSummaryPrompt(toCompact: readonly ChatMessage[]): {
35
+ systemPrompt: string;
36
+ userMessage: string;
37
+ };
38
+ /**
39
+ * Normalize history for a provider request (GENC-1351 §5.7): translate each
40
+ * `compacted-summary` message into a `user` message that wraps its summary in a
41
+ * `<conversation_summary>` block, so the raw display-only role never reaches a
42
+ * transport. Other roles pass through untouched. Pure — returns a new array.
43
+ *
44
+ * Applied at the request-build chokepoint *before* per-agent masking, so the
45
+ * guarantee holds for every provider/transport regardless of any optional
46
+ * per-agent history transform.
47
+ */
48
+ export declare function normalizeForProvider(history: readonly ChatMessage[]): ChatMessage[];
49
+ /** Human-facing divider label for a `compacted-summary` message. */
50
+ export declare function compactionDividerLabel(m: ChatMessage): string;
13
51
  //# sourceMappingURL=history-transform.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"history-transform.d.ts","sourceRoot":"","sources":["../../../src/utils/history-transform.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAoB9D;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,WAAW,EAAE,CAKjG;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,WAAW,EAAE,CAG3F"}
1
+ {"version":3,"file":"history-transform.d.ts","sourceRoot":"","sources":["../../../src/utils/history-transform.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAoB9D;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,WAAW,EAAE,CAKjG;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,WAAW,EAAE,CAG3F;AAID,uFAAuF;AACvF,eAAO,MAAM,4BAA4B,IAAI,CAAC;AAE9C,sFAAsF;AACtF,eAAO,MAAM,+BAA+B,IAAI,CAAC;AAEjD;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,GAAG,MAAM,GAAG,IAAI,CAWhF;AAkCD;;;;;;GAMG;AACH,wBAAgB,4BAA4B,CAAC,SAAS,EAAE,SAAS,WAAW,EAAE,GAAG;IAC/E,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;CACrB,CAYA;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,GAAG,WAAW,EAAE,CAanF;AAED,oEAAoE;AACpE,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,WAAW,GAAG,MAAM,CAG7D"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=history-transform.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history-transform.test.d.ts","sourceRoot":"","sources":["../../../src/utils/history-transform.test.ts"],"names":[],"mappings":""}
@@ -1,4 +1,24 @@
1
1
  import type { ChatMessage } from '@genesislcap/foundation-ai';
2
+ /**
3
+ * Display-only session-restore notices (GENC-1351 §6): the "Restored…" divider on
4
+ * a successful reload restore, and the "Couldn't restore…" divider when a saved
5
+ * session existed but couldn't be brought back (timeout / error / unusable
6
+ * snapshot). Both are `system-event` rows, stripped from the persisted snapshot so
7
+ * they never become permanent history — and, unlike agent-switch indicators, they
8
+ * belong to the persistence ("remember chat") feature, so `filterVisibleMessages`
9
+ * gates them by `showRestoreNotices` rather than `showAgentSwitchIndicator`.
10
+ *
11
+ * @internal
12
+ */
13
+ export declare const SESSION_RESTORED_LABEL = "Restored previous conversation";
14
+ /** @internal */
15
+ export declare const SESSION_RESTORE_FAILED_LABEL = "Couldn't restore the previous conversation";
16
+ /** @internal */
17
+ export declare const isSessionRestoredMarker: (m: ChatMessage) => boolean;
18
+ /** @internal */
19
+ export declare const isSessionRestoreFailedMarker: (m: ChatMessage) => boolean;
20
+ /** Either restore notice — both display-only, stripped before persist. @internal */
21
+ export declare const isSessionNoticeMarker: (m: ChatMessage) => boolean;
2
22
  /**
3
23
  * Toggle state that drives which messages appear in the scrolling list. Mirrors
4
24
  * the cog-menu switches; `showAgentSwitchIndicator` is pre-resolved by the
@@ -10,6 +30,13 @@ export interface MessageFilterState {
10
30
  showThinkingSteps: boolean;
11
31
  showNarration: boolean;
12
32
  showAgentSwitchIndicator: boolean;
33
+ /**
34
+ * Whether session-restore notices show — driven by the persistence ("remember
35
+ * chat") toggle, since restore is that feature's concern (GENC-1351 §6). Kept
36
+ * separate from `showAgentSwitchIndicator` so those two unrelated switches don't
37
+ * cross-control each other.
38
+ */
39
+ showRestoreNotices: boolean;
13
40
  }
14
41
  /**
15
42
  * The trailing interaction to render in a pinned slot, separate from the
@@ -1 +1 @@
1
- {"version":3,"file":"message-partition.d.ts","sourceRoot":"","sources":["../../../src/utils/message-partition.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAE9D;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,aAAa,EAAE,OAAO,CAAC;IACvB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,aAAa,EAAE,OAAO,CAAC;IACvB,wBAAwB,EAAE,OAAO,CAAC;CACnC;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,WAAW,EAAE,CAG7E;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,WAAW,EAAE,EACvB,OAAO,EAAE,kBAAkB,GAC1B,WAAW,EAAE,CA8Bf"}
1
+ {"version":3,"file":"message-partition.d.ts","sourceRoot":"","sources":["../../../src/utils/message-partition.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAE9D;;;;;;;;;;GAUG;AACH,eAAO,MAAM,sBAAsB,mCAAmC,CAAC;AACvE,gBAAgB;AAChB,eAAO,MAAM,4BAA4B,+CAA+C,CAAC;AACzF,gBAAgB;AAChB,eAAO,MAAM,uBAAuB,GAAI,GAAG,WAAW,KAAG,OACU,CAAC;AACpE,gBAAgB;AAChB,eAAO,MAAM,4BAA4B,GAAI,GAAG,WAAW,KAAG,OACW,CAAC;AAC1E,oFAAoF;AACpF,eAAO,MAAM,qBAAqB,GAAI,GAAG,WAAW,KAAG,OACQ,CAAC;AAEhE;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,aAAa,EAAE,OAAO,CAAC;IACvB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,aAAa,EAAE,OAAO,CAAC;IACvB,wBAAwB,EAAE,OAAO,CAAC;IAClC;;;;;OAKG;IACH,kBAAkB,EAAE,OAAO,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,WAAW,EAAE,CAG7E;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,WAAW,EAAE,EACvB,OAAO,EAAE,kBAAkB,GAC1B,WAAW,EAAE,CAsCf"}
@@ -0,0 +1,43 @@
1
+ import type { ChatConfig } from '@genesislcap/foundation-ai';
2
+ import { type AiAssistantAnimation } from '../main/main.types';
3
+ import type { SessionPreferences } from '../state/persistence/session-persistence-provider';
4
+ /**
5
+ * The effective user-facing preference state for a freshly created session store
6
+ * (GENC-1351 #2), resolved from the two inputs that feed it.
7
+ *
8
+ * @internal
9
+ */
10
+ export interface ResolvedPreferenceBaseline {
11
+ showToolCalls: boolean;
12
+ showThinkingSteps: boolean;
13
+ showNarration: boolean;
14
+ showAgentSwitchIndicator: boolean;
15
+ enabledAnimations: AiAssistantAnimation[];
16
+ /**
17
+ * The remembered "remember chat" toggle — present only when stored prefs carried
18
+ * an `enabled` value. Left `undefined` otherwise so the caller keeps the
19
+ * host-configured default rather than forcing a value.
20
+ */
21
+ enabled?: boolean;
22
+ }
23
+ /**
24
+ * Resolve the effective preference baseline for a fresh store, applying the
25
+ * precedence (lowest → highest):
26
+ *
27
+ * slice defaults < `chatConfig.ui` defaults < stored user preferences
28
+ *
29
+ * The `chatConfig.ui` layer is the fallback when the user has no stored prefs
30
+ * (e.g. a first-ever load, or after the persistence backend is wiped) — the case
31
+ * the old "read config once on connect" path got wrong whenever `chatConfig` had
32
+ * not bound yet. Stored prefs, when present, override only the fields they carry;
33
+ * absent fields keep the config default. Pure, so the precedence is unit-testable
34
+ * independent of the element/store wiring.
35
+ *
36
+ * Config-supplied animations are normalised through {@link resolveExclusiveLoadingStyle}
37
+ * (a raw config list may name both loading styles); stored animations are applied
38
+ * as-is, since they were already normalised when saved.
39
+ *
40
+ * @internal
41
+ */
42
+ export declare function resolvePreferenceBaseline(ui: ChatConfig['ui'], stored: SessionPreferences | null | undefined): ResolvedPreferenceBaseline;
43
+ //# sourceMappingURL=resolve-preference-baseline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-preference-baseline.d.ts","sourceRoot":"","sources":["../../../src/utils/resolve-preference-baseline.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAsB,KAAK,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AACnF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mDAAmD,CAAC;AAG5F;;;;;GAKG;AACH,MAAM,WAAW,0BAA0B;IACzC,aAAa,EAAE,OAAO,CAAC;IACvB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,aAAa,EAAE,OAAO,CAAC;IACvB,wBAAwB,EAAE,OAAO,CAAC;IAClC,iBAAiB,EAAE,oBAAoB,EAAE,CAAC;IAC1C;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,yBAAyB,CACvC,EAAE,EAAE,UAAU,CAAC,IAAI,CAAC,EACpB,MAAM,EAAE,kBAAkB,GAAG,IAAI,GAAG,SAAS,GAC5C,0BAA0B,CAgC5B"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=resolve-preference-baseline.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-preference-baseline.test.d.ts","sourceRoot":"","sources":["../../../src/utils/resolve-preference-baseline.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Resolve `promise`, or **reject** if it doesn't settle within `ms`. Rejecting
3
+ * (rather than resolving to a fallback) lets restore tell a genuine timeout apart
4
+ * from a clean "nothing stored" result, so it can surface a notice for the former
5
+ * and stay silent for the latter. Because the loser of the race is abandoned, a
6
+ * late-resolving `load()` is discarded and can never clobber a now-live session;
7
+ * a late *rejection* is swallowed so it doesn't surface as an unhandled rejection.
8
+ *
9
+ * @internal
10
+ */
11
+ export declare function withTimeout<T>(promise: Promise<T>, ms: number): Promise<T>;
12
+ //# sourceMappingURL=with-timeout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"with-timeout.d.ts","sourceRoot":"","sources":["../../../src/utils/with-timeout.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,wBAAsB,WAAW,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAahF"}