@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.
- package/dist/ai-assistant.api.json +6737 -3591
- package/dist/ai-assistant.d.ts +879 -183
- package/dist/custom-elements.json +1799 -650
- package/dist/dts/components/ai-driver/ai-driver.d.ts +32 -8
- package/dist/dts/components/ai-driver/ai-driver.d.ts.map +1 -1
- package/dist/dts/components/chat-driver/chat-driver.compact.test.d.ts +2 -0
- package/dist/dts/components/chat-driver/chat-driver.compact.test.d.ts.map +1 -0
- package/dist/dts/components/chat-driver/chat-driver.d.ts +13 -29
- package/dist/dts/components/chat-driver/chat-driver.d.ts.map +1 -1
- package/dist/dts/components/chat-interaction-wrapper/chat-interaction-wrapper.d.ts +0 -7
- package/dist/dts/components/chat-interaction-wrapper/chat-interaction-wrapper.d.ts.map +1 -1
- package/dist/dts/components/orchestrating-driver/orchestrating-driver.d.ts +15 -4
- package/dist/dts/components/orchestrating-driver/orchestrating-driver.d.ts.map +1 -1
- package/dist/dts/components/orchestrating-driver/orchestrating-driver.pin.test.d.ts +2 -0
- package/dist/dts/components/orchestrating-driver/orchestrating-driver.pin.test.d.ts.map +1 -0
- package/dist/dts/components/popout-manager/popout-manager.d.ts +37 -9
- package/dist/dts/components/popout-manager/popout-manager.d.ts.map +1 -1
- package/dist/dts/components/settings-modal/settings-modal.styles.d.ts.map +1 -1
- package/dist/dts/components/settings-modal/settings-modal.template.d.ts.map +1 -1
- package/dist/dts/config/config.d.ts +70 -0
- package/dist/dts/config/config.d.ts.map +1 -1
- package/dist/dts/config/define-stateful-agent.d.ts +73 -1
- package/dist/dts/config/define-stateful-agent.d.ts.map +1 -1
- package/dist/dts/index.d.ts +1 -0
- package/dist/dts/index.d.ts.map +1 -1
- package/dist/dts/main/main.d.ts +337 -91
- package/dist/dts/main/main.d.ts.map +1 -1
- package/dist/dts/main/main.styles.d.ts.map +1 -1
- package/dist/dts/main/main.template.d.ts.map +1 -1
- package/dist/dts/main/main.types.d.ts +55 -9
- package/dist/dts/main/main.types.d.ts.map +1 -1
- package/dist/dts/main/popout-interaction-gate.test.d.ts +2 -0
- package/dist/dts/main/popout-interaction-gate.test.d.ts.map +1 -0
- package/dist/dts/react.d.ts +3 -2
- package/dist/dts/state/ai-assistant-slice.d.ts +73 -0
- package/dist/dts/state/ai-assistant-slice.d.ts.map +1 -1
- package/dist/dts/state/ai-assistant-slice.test.d.ts +2 -0
- package/dist/dts/state/ai-assistant-slice.test.d.ts.map +1 -0
- package/dist/dts/state/debug-event-log.d.ts +1 -1
- package/dist/dts/state/debug-event-log.d.ts.map +1 -1
- package/dist/dts/state/persistence/diagnostics-cursors.d.ts +51 -0
- package/dist/dts/state/persistence/diagnostics-cursors.d.ts.map +1 -0
- package/dist/dts/state/persistence/diagnostics-cursors.test.d.ts +2 -0
- package/dist/dts/state/persistence/diagnostics-cursors.test.d.ts.map +1 -0
- package/dist/dts/state/persistence/diagnostics.d.ts +65 -0
- package/dist/dts/state/persistence/diagnostics.d.ts.map +1 -0
- package/dist/dts/state/persistence/diagnostics.test.d.ts +2 -0
- package/dist/dts/state/persistence/diagnostics.test.d.ts.map +1 -0
- package/dist/dts/state/persistence/index.d.ts +7 -0
- package/dist/dts/state/persistence/index.d.ts.map +1 -0
- package/dist/dts/state/persistence/persister-registry.d.ts +22 -0
- package/dist/dts/state/persistence/persister-registry.d.ts.map +1 -0
- package/dist/dts/state/persistence/session-persistence-provider.d.ts +132 -0
- package/dist/dts/state/persistence/session-persistence-provider.d.ts.map +1 -0
- package/dist/dts/state/persistence/session-persistence-provider.test.d.ts +2 -0
- package/dist/dts/state/persistence/session-persistence-provider.test.d.ts.map +1 -0
- package/dist/dts/state/persistence/session-persistence.integration.test.d.ts +2 -0
- package/dist/dts/state/persistence/session-persistence.integration.test.d.ts.map +1 -0
- package/dist/dts/state/persistence/session-persister.d.ts +173 -0
- package/dist/dts/state/persistence/session-persister.d.ts.map +1 -0
- package/dist/dts/state/persistence/session-persister.test.d.ts +2 -0
- package/dist/dts/state/persistence/session-persister.test.d.ts.map +1 -0
- package/dist/dts/state/persistence/session-snapshot.d.ts +218 -0
- package/dist/dts/state/persistence/session-snapshot.d.ts.map +1 -0
- package/dist/dts/state/persistence/session-snapshot.test.d.ts +2 -0
- package/dist/dts/state/persistence/session-snapshot.test.d.ts.map +1 -0
- package/dist/dts/state/persistence/stateful-restore.e2e.test.d.ts +2 -0
- package/dist/dts/state/persistence/stateful-restore.e2e.test.d.ts.map +1 -0
- package/dist/dts/state/session-store.d.ts +6 -0
- package/dist/dts/state/session-store.d.ts.map +1 -1
- package/dist/dts/utils/history-transform.d.ts +38 -0
- package/dist/dts/utils/history-transform.d.ts.map +1 -1
- package/dist/dts/utils/history-transform.test.d.ts +2 -0
- package/dist/dts/utils/history-transform.test.d.ts.map +1 -0
- package/dist/dts/utils/message-partition.d.ts +27 -0
- package/dist/dts/utils/message-partition.d.ts.map +1 -1
- package/dist/dts/utils/resolve-preference-baseline.d.ts +43 -0
- package/dist/dts/utils/resolve-preference-baseline.d.ts.map +1 -0
- package/dist/dts/utils/resolve-preference-baseline.test.d.ts +2 -0
- package/dist/dts/utils/resolve-preference-baseline.test.d.ts.map +1 -0
- package/dist/dts/utils/with-timeout.d.ts +12 -0
- package/dist/dts/utils/with-timeout.d.ts.map +1 -0
- package/dist/esm/components/chat-driver/chat-driver.compact.test.js +93 -0
- package/dist/esm/components/chat-driver/chat-driver.js +101 -65
- package/dist/esm/components/chat-driver/chat-driver.test.js +0 -45
- package/dist/esm/components/chat-interaction-wrapper/chat-interaction-wrapper.js +17 -35
- package/dist/esm/components/chat-interaction-wrapper/chat-interaction-wrapper.test.js +0 -62
- package/dist/esm/components/orchestrating-driver/orchestrating-driver.js +32 -14
- package/dist/esm/components/orchestrating-driver/orchestrating-driver.pin.test.js +61 -0
- package/dist/esm/components/popout-manager/popout-manager.js +76 -27
- package/dist/esm/components/settings-modal/settings-modal.styles.js +24 -0
- package/dist/esm/components/settings-modal/settings-modal.template.js +14 -1
- package/dist/esm/config/define-stateful-agent.js +81 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/main/main.js +929 -223
- package/dist/esm/main/main.styles.js +55 -0
- package/dist/esm/main/main.template.js +94 -10
- package/dist/esm/main/main.types.js +27 -0
- package/dist/esm/main/popout-interaction-gate.test.js +58 -0
- package/dist/esm/state/ai-assistant-slice.js +85 -25
- package/dist/esm/state/ai-assistant-slice.test.js +85 -0
- package/dist/esm/state/debug-event-log.js +10 -0
- package/dist/esm/state/persistence/diagnostics-cursors.js +47 -0
- package/dist/esm/state/persistence/diagnostics-cursors.test.js +30 -0
- package/dist/esm/state/persistence/diagnostics.js +81 -0
- package/dist/esm/state/persistence/diagnostics.test.js +72 -0
- package/dist/esm/state/persistence/index.js +3 -0
- package/dist/esm/state/persistence/persister-registry.js +48 -0
- package/dist/esm/state/persistence/session-persistence-provider.js +95 -0
- package/dist/esm/state/persistence/session-persistence-provider.test.js +110 -0
- package/dist/esm/state/persistence/session-persistence.integration.test.js +109 -0
- package/dist/esm/state/persistence/session-persister.js +642 -0
- package/dist/esm/state/persistence/session-persister.test.js +314 -0
- package/dist/esm/state/persistence/session-snapshot.js +240 -0
- package/dist/esm/state/persistence/session-snapshot.test.js +235 -0
- package/dist/esm/state/persistence/stateful-restore.e2e.test.js +149 -0
- package/dist/esm/utils/history-transform.js +101 -0
- package/dist/esm/utils/history-transform.test.js +137 -0
- package/dist/esm/utils/message-partition.js +30 -2
- package/dist/esm/utils/message-partition.test.js +20 -1
- package/dist/esm/utils/resolve-preference-baseline.js +53 -0
- package/dist/esm/utils/resolve-preference-baseline.test.js +69 -0
- package/dist/esm/utils/with-timeout.js +28 -0
- package/dist/react.cjs +6 -1
- package/dist/react.mjs +6 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/docs/migration-GENC-1351.md +172 -0
- package/package.json +17 -17
- package/src/components/ai-driver/ai-driver.ts +36 -17
- package/src/components/chat-driver/chat-driver.compact.test.ts +131 -0
- package/src/components/chat-driver/chat-driver.test.ts +0 -71
- package/src/components/chat-driver/chat-driver.ts +103 -70
- package/src/components/chat-interaction-wrapper/chat-interaction-wrapper.test.ts +0 -81
- package/src/components/chat-interaction-wrapper/chat-interaction-wrapper.ts +18 -41
- package/src/components/orchestrating-driver/orchestrating-driver.pin.test.ts +96 -0
- package/src/components/orchestrating-driver/orchestrating-driver.ts +36 -18
- package/src/components/popout-manager/popout-manager.ts +82 -28
- package/src/components/settings-modal/settings-modal.styles.ts +24 -0
- package/src/components/settings-modal/settings-modal.template.ts +27 -1
- package/src/config/config.ts +71 -0
- package/src/config/define-stateful-agent.ts +134 -0
- package/src/index.ts +1 -0
- package/src/main/main.styles.ts +55 -0
- package/src/main/main.template.ts +121 -11
- package/src/main/main.ts +937 -199
- package/src/main/main.types.ts +59 -10
- package/src/main/popout-interaction-gate.test.ts +92 -0
- package/src/state/ai-assistant-slice.test.ts +114 -0
- package/src/state/ai-assistant-slice.ts +134 -25
- package/src/state/debug-event-log.ts +22 -1
- package/src/state/persistence/diagnostics-cursors.test.ts +53 -0
- package/src/state/persistence/diagnostics-cursors.ts +80 -0
- package/src/state/persistence/diagnostics.test.ts +95 -0
- package/src/state/persistence/diagnostics.ts +110 -0
- package/src/state/persistence/index.ts +10 -0
- package/src/state/persistence/persister-registry.ts +55 -0
- package/src/state/persistence/session-persistence-provider.test.ts +136 -0
- package/src/state/persistence/session-persistence-provider.ts +202 -0
- package/src/state/persistence/session-persistence.integration.test.ts +134 -0
- package/src/state/persistence/session-persister.test.ts +428 -0
- package/src/state/persistence/session-persister.ts +689 -0
- package/src/state/persistence/session-snapshot.test.ts +327 -0
- package/src/state/persistence/session-snapshot.ts +340 -0
- package/src/state/persistence/stateful-restore.e2e.test.ts +221 -0
- package/src/utils/history-transform.test.ts +197 -0
- package/src/utils/history-transform.ts +117 -0
- package/src/utils/message-partition.test.ts +27 -1
- package/src/utils/message-partition.ts +41 -2
- package/src/utils/resolve-preference-baseline.test.ts +84 -0
- package/src/utils/resolve-preference-baseline.ts +80 -0
- 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 @@
|
|
|
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 @@
|
|
|
1
|
+
{"version":3,"file":"session-snapshot.test.d.ts","sourceRoot":"","sources":["../../../../src/state/persistence/session-snapshot.test.ts"],"names":[],"mappings":""}
|
|
@@ -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
|
|
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 @@
|
|
|
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;
|
|
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 @@
|
|
|
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"}
|