@burdenoff/fe-libs 2026.926.5 → 2026.927.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 (95) hide show
  1. package/dist/shared/assistant/conversation.d.ts +91 -3
  2. package/dist/shared/assistant/conversation.d.ts.map +1 -1
  3. package/dist/shared/assistant/gatewayClient.d.ts +15 -0
  4. package/dist/shared/assistant/gatewayClient.d.ts.map +1 -1
  5. package/dist/shared/assistant/gatewayClient.js +1 -1
  6. package/dist/shared/assistant/guardedStorage.d.ts +4 -2
  7. package/dist/shared/assistant/guardedStorage.d.ts.map +1 -1
  8. package/dist/shared/assistant/guardedStorage.js +1 -1
  9. package/dist/shared/assistant/history/historyApi.d.ts +38 -0
  10. package/dist/shared/assistant/history/historyApi.d.ts.map +1 -0
  11. package/dist/shared/assistant/history/historyApi.js +153 -0
  12. package/dist/shared/assistant/history/historyEngine.d.ts +96 -0
  13. package/dist/shared/assistant/history/historyEngine.d.ts.map +1 -0
  14. package/dist/shared/assistant/history/historyEngine.js +774 -0
  15. package/dist/shared/assistant/history/historyErrors.d.ts +72 -0
  16. package/dist/shared/assistant/history/historyErrors.d.ts.map +1 -0
  17. package/dist/shared/assistant/history/historyErrors.js +74 -0
  18. package/dist/shared/assistant/history/historyList.d.ts +115 -0
  19. package/dist/shared/assistant/history/historyList.d.ts.map +1 -0
  20. package/dist/shared/assistant/history/historyList.js +116 -0
  21. package/dist/shared/assistant/history/historyMapping.d.ts +65 -0
  22. package/dist/shared/assistant/history/historyMapping.d.ts.map +1 -0
  23. package/dist/shared/assistant/history/historyMapping.js +383 -0
  24. package/dist/shared/assistant/history/historyMerge.d.ts +65 -0
  25. package/dist/shared/assistant/history/historyMerge.d.ts.map +1 -0
  26. package/dist/shared/assistant/history/historyMerge.js +97 -0
  27. package/dist/shared/assistant/history/historyOperations.d.ts +24 -0
  28. package/dist/shared/assistant/history/historyOperations.d.ts.map +1 -0
  29. package/dist/shared/assistant/history/historyOperations.js +125 -0
  30. package/dist/shared/assistant/history/historyResume.d.ts +56 -0
  31. package/dist/shared/assistant/history/historyResume.d.ts.map +1 -0
  32. package/dist/shared/assistant/history/historyResume.js +55 -0
  33. package/dist/shared/assistant/history/historyStatus.d.ts +76 -0
  34. package/dist/shared/assistant/history/historyStatus.d.ts.map +1 -0
  35. package/dist/shared/assistant/history/historyStatus.js +47 -0
  36. package/dist/shared/assistant/history/historyStore.d.ts +192 -0
  37. package/dist/shared/assistant/history/historyStore.d.ts.map +1 -0
  38. package/dist/shared/assistant/history/historyStore.js +503 -0
  39. package/dist/shared/assistant/history/historyTimestamps.d.ts +11 -0
  40. package/dist/shared/assistant/history/historyTimestamps.d.ts.map +1 -0
  41. package/dist/shared/assistant/history/historyTimestamps.js +9 -0
  42. package/dist/shared/assistant/history/historyTypes.d.ts +256 -0
  43. package/dist/shared/assistant/history/historyTypes.d.ts.map +1 -0
  44. package/dist/shared/assistant/history/historyTypes.js +20 -0
  45. package/dist/shared/assistant/history/profileBoundStorage.d.ts +36 -0
  46. package/dist/shared/assistant/history/profileBoundStorage.d.ts.map +1 -0
  47. package/dist/shared/assistant/history/profileBoundStorage.js +74 -0
  48. package/dist/shared/assistant/history/stampRegistry.d.ts +84 -0
  49. package/dist/shared/assistant/history/stampRegistry.d.ts.map +1 -0
  50. package/dist/shared/assistant/history/stampRegistry.js +58 -0
  51. package/dist/shared/assistant/history/useAssistantServerHistory.d.ts +18 -0
  52. package/dist/shared/assistant/history/useAssistantServerHistory.d.ts.map +1 -0
  53. package/dist/shared/assistant/history/useAssistantServerHistory.js +12 -0
  54. package/dist/shared/assistant/i18nManifest.d.ts +18 -0
  55. package/dist/shared/assistant/i18nManifest.d.ts.map +1 -1
  56. package/dist/shared/assistant/i18nManifest.js +18 -0
  57. package/dist/shared/assistant/index.d.ts +16 -0
  58. package/dist/shared/assistant/index.d.ts.map +1 -1
  59. package/dist/shared/assistant/liveTurns.d.ts +7 -0
  60. package/dist/shared/assistant/liveTurns.d.ts.map +1 -1
  61. package/dist/shared/assistant/liveTurns.js +35 -32
  62. package/dist/shared/assistant/spokenTurns.d.ts +20 -0
  63. package/dist/shared/assistant/spokenTurns.d.ts.map +1 -1
  64. package/dist/shared/assistant/spokenTurns.js +13 -8
  65. package/dist/shared/assistant/store.d.ts +35 -1
  66. package/dist/shared/assistant/store.d.ts.map +1 -1
  67. package/dist/shared/assistant/store.js +93 -24
  68. package/dist/shared/assistant/ui/AIAssistantPanel.d.ts +16 -0
  69. package/dist/shared/assistant/ui/AIAssistantPanel.d.ts.map +1 -1
  70. package/dist/shared/assistant/ui/AIAssistantPanel.js +63 -60
  71. package/dist/shared/assistant/ui/AssistantChatArea.d.ts.map +1 -1
  72. package/dist/shared/assistant/ui/AssistantChatArea.js +730 -672
  73. package/dist/shared/assistant/ui/AssistantConversationList.d.ts +17 -0
  74. package/dist/shared/assistant/ui/AssistantConversationList.d.ts.map +1 -1
  75. package/dist/shared/assistant/ui/AssistantConversationList.js +252 -145
  76. package/dist/shared/assistant/ui/AssistantHistoryNotices.d.ts +36 -0
  77. package/dist/shared/assistant/ui/AssistantHistoryNotices.d.ts.map +1 -0
  78. package/dist/shared/assistant/ui/AssistantHistoryNotices.js +103 -0
  79. package/dist/shared/assistant/ui/AssistantOverlay.d.ts +4 -0
  80. package/dist/shared/assistant/ui/AssistantOverlay.d.ts.map +1 -1
  81. package/dist/shared/assistant/ui/AssistantOverlay.js +97 -94
  82. package/dist/shared/assistant/ui/AssistantSpokenTurnsNotice.d.ts +5 -3
  83. package/dist/shared/assistant/ui/AssistantSpokenTurnsNotice.d.ts.map +1 -1
  84. package/dist/shared/assistant/ui/composer/AssistantComposer.d.ts +6 -0
  85. package/dist/shared/assistant/ui/composer/AssistantComposer.d.ts.map +1 -1
  86. package/dist/shared/assistant/ui/composer/AssistantComposer.js +54 -54
  87. package/dist/shared/assistant/ui/voice/VoiceTranscriptDrawer.d.ts +9 -0
  88. package/dist/shared/assistant/ui/voice/VoiceTranscriptDrawer.d.ts.map +1 -1
  89. package/dist/shared/assistant/ui/voice/VoiceTranscriptDrawer.js +37 -32
  90. package/dist/shared/assistant/voice/turnVisibility.d.ts +7 -5
  91. package/dist/shared/assistant/voice/turnVisibility.d.ts.map +1 -1
  92. package/dist/shared/assistant/voice/voiceTranscript.d.ts +3 -2
  93. package/dist/shared/assistant/voice/voiceTranscript.d.ts.map +1 -1
  94. package/dist/shared-assistant.js +153 -137
  95. package/package.json +1 -1
@@ -79,9 +79,11 @@ export interface AssistantMessageMetadata {
79
79
  * report, "I see the same chat in the normal conversation tab, both are
80
80
  * separate, don't confuse".
81
81
  *
82
- * Stamped at send time and persisted, so the distinction survives a reload —
83
- * the chat transcript is never rehydrated from the backend, so the store is
84
- * the only source of truth for what the panel shows.
82
+ * Stamped at send time and persisted, so the distinction survives a reload.
83
+ * ★ BOFF-7335: a conversation read back from server history enters the store
84
+ * ONLY through `fromHistoryEntry` (history/historyMapping), which rebuilds
85
+ * this marker from the saved entry — `voice: true` with or without a session
86
+ * id — so a spoken turn reopened on any device is still spoken, never typed.
85
87
  */
86
88
  voice?: boolean;
87
89
  /**
@@ -149,8 +151,38 @@ export interface AssistantMessageMetadata {
149
151
  * error: the turn still closed as a normal answer.
150
152
  */
151
153
  incomplete?: true;
154
+ /**
155
+ * ★ BOFF-7335: the SAVED copy of this message was cut to fit the gateway's
156
+ * request limit (the local copy is always complete). Only ever set on a
157
+ * message read back from server history.
158
+ */
159
+ truncated?: true;
160
+ /**
161
+ * ★ BOFF-7335: structured records of what a turn proposed or did — a generic
162
+ * slot, deliberately not the approval schema. A record is history, never an
163
+ * instruction: nothing re-runs, re-approves or re-sends it on reopen, and a
164
+ * record still `proposed` when it is read back is shown as `expired`.
165
+ */
166
+ records?: readonly AssistantHistoryRecord[];
152
167
  [key: string]: unknown;
153
168
  }
169
+ /** Where a recorded action stands. `proposed` never survives a reload (it reads back as `expired`). */
170
+ export type AssistantHistoryRecordStatus = "proposed" | "applied" | "failed" | "expired" | "cancelled";
171
+ /**
172
+ * One structured record on a message (BOFF-7335). `kind` is namespaced by the
173
+ * feature that writes it (`[a-z][a-z0-9._-]*`) and `version` versions its
174
+ * `data`, so a later feature can add records without a schema change on either
175
+ * side — and without this file knowing anything about approvals.
176
+ */
177
+ export interface AssistantHistoryRecord {
178
+ kind: string;
179
+ version: number;
180
+ status?: AssistantHistoryRecordStatus;
181
+ summary?: string;
182
+ data?: Record<string, unknown>;
183
+ /** ISO time the record was written. */
184
+ at?: string;
185
+ }
154
186
  export interface Message {
155
187
  id: string;
156
188
  role: "user" | "assistant" | "system";
@@ -161,7 +193,20 @@ export interface Message {
161
193
  output: number;
162
194
  };
163
195
  metadata?: AssistantMessageMetadata;
196
+ /**
197
+ * ★ BOFF-7335: where this message stands with server history — `pending`
198
+ * once it is queued to be saved, `saved` once the server has it (or it was
199
+ * read from the server). Absent: device-only, or history is off.
200
+ *
201
+ * Top-level, never inside `metadata`: `patchMessage` REPLACES metadata, so a
202
+ * flag kept there would be erased by the next reply update.
203
+ */
204
+ historyState?: MessageHistoryState;
205
+ /** ★ BOFF-7335: the message's position in the saved conversation (1..n), once known. */
206
+ historySeq?: number;
164
207
  }
208
+ /** See `Message.historyState`. */
209
+ export type MessageHistoryState = "pending" | "saved";
165
210
  export interface Conversation {
166
211
  id: string;
167
212
  title: string;
@@ -198,6 +243,49 @@ export interface Conversation {
198
243
  * ★ `mode` stays the transport value either way: Auto never sends as itself.
199
244
  */
200
245
  routedBy?: ConversationRouting;
246
+ /**
247
+ * ★ BOFF-7335: this conversation is backed by server history. Absent means
248
+ * DEVICE-ONLY — every conversation created before history was switched on,
249
+ * or while the product had not opted in, or while no account or workspace
250
+ * was known. A device-only conversation is never uploaded later.
251
+ */
252
+ sync?: ConversationSyncStamp;
253
+ }
254
+ /**
255
+ * The server-history stamp on a conversation (BOFF-7335).
256
+ *
257
+ * ★★ The owner — product, workspace, actor — is fixed when the conversation is
258
+ * created and never changes. A turn is saved only while all three match the
259
+ * active scope, so a conversation can never be written into another
260
+ * workspace's or another account's history.
261
+ *
262
+ * ★ Every field is optional to older builds: they spread conversations and
263
+ * messages in every action and in `partialize`, so a product rolled back to an
264
+ * earlier fe-libs keeps this stamp intact instead of stripping it.
265
+ */
266
+ export interface ConversationSyncStamp {
267
+ v: 1;
268
+ product: string;
269
+ workspaceId: string;
270
+ actorId: string;
271
+ /** `created` on this device · `remote` read from the server · `legacy` saved before v2 (read-only). */
272
+ origin: "created" | "remote" | "legacy";
273
+ /** The server's own id, once known. */
274
+ serverId?: string;
275
+ /** The server revision of the conversation last applied here. */
276
+ revision?: number;
277
+ /** The highest CONTIGUOUS server `seq` held locally. */
278
+ lastSeq?: number;
279
+ /** Older messages exist on the server than are held here. */
280
+ hasOlder?: true;
281
+ /** Where "Show earlier messages" continues from. */
282
+ olderCursor?: string;
283
+ /** Renamed on this device: the server's title never overwrites it (renames are not synced). */
284
+ titleLocked?: true;
285
+ /** Why the latest turns are not being saved. */
286
+ blocked?: "quota" | "invalid" | "scope";
287
+ /** When it was last opened here (ISO), for cache eviction. */
288
+ openedAt?: string;
201
289
  }
202
290
  /**
203
291
  * How a conversation came by its mode. See `Conversation.routedBy` and
@@ -1 +1 @@
1
- {"version":3,"file":"conversation.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/conversation.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"conversation.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/conversation.ts"],"names":[],"mappings":"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"}
@@ -15,6 +15,21 @@ import { AssistantSandboxAuthContext } from './types';
15
15
  */
16
16
  export { isQuotaExhaustedError } from './quota';
17
17
  export declare function buildSandboxContextInput(workspaceId: string, authContext?: AssistantSandboxAuthContext): Record<string, unknown>;
18
+ /**
19
+ * ONE attempt, no retry — the caller owns retry.
20
+ *
21
+ * ★ Exported for server history (BOFF-7335), whose engine retries with its own
22
+ * backoff and classifier and must never be retried blindly underneath: a
23
+ * blind resend of a save that did land is harmless (saves are idempotent), but
24
+ * a hidden retry loop hides how long the gateway was actually down.
25
+ */
26
+ export declare function executeAssistantGraphQLOnce<TData>(params: {
27
+ query: string;
28
+ operationName: string;
29
+ variables: Record<string, unknown>;
30
+ workspaceId: string;
31
+ authContext?: AssistantSandboxAuthContext;
32
+ }): Promise<TData>;
18
33
  export declare function executeSandboxGraphQL<TData>(params: {
19
34
  query: string;
20
35
  operationName: string;
@@ -1 +1 @@
1
- {"version":3,"file":"gatewayClient.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/gatewayClient.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,SAAS,CAAC;AAe3D;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAEhD,wBAAgB,wBAAwB,CACtC,WAAW,EAAE,MAAM,EACnB,WAAW,CAAC,EAAE,2BAA2B,GACxC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAOzB;AAuCD,wBAAsB,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE;IACzD,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,2BAA2B,CAAC;CAC3C,GAAG,OAAO,CAAC,KAAK,CAAC,CAyBjB"}
1
+ {"version":3,"file":"gatewayClient.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/gatewayClient.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,SAAS,CAAC;AAe3D;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAEhD,wBAAgB,wBAAwB,CACtC,WAAW,EAAE,MAAM,EACnB,WAAW,CAAC,EAAE,2BAA2B,GACxC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAOzB;AAED;;;;;;;GAOG;AACH,wBAAsB,2BAA2B,CAAC,KAAK,EAAE,MAAM,EAAE;IAC/D,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,2BAA2B,CAAC;CAC3C,GAAG,OAAO,CAAC,KAAK,CAAC,CA6BjB;AAED,wBAAsB,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE;IACzD,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,2BAA2B,CAAC;CAC3C,GAAG,OAAO,CAAC,KAAK,CAAC,CAyBjB"}
@@ -48,4 +48,4 @@ async function i(e) {
48
48
  throw t;
49
49
  }
50
50
  //#endregion
51
- export { n as buildSandboxContextInput, i as executeSandboxGraphQL };
51
+ export { n as buildSandboxContextInput, r as executeAssistantGraphQLOnce, i as executeSandboxGraphQL };
@@ -23,10 +23,12 @@ import { PersistStorage } from 'zustand/middleware';
23
23
  * `onWriteError` is told about each refused write — the place to free space,
24
24
  * whose own write then persists the smaller state. It is never re-entered: a
25
25
  * write that fails while it runs is dropped without calling it again, so a
26
- * callback that writes cannot recurse.
26
+ * callback that writes cannot recurse. Its `stillFailing` answers whether the
27
+ * latest write — the one its own change caused, say — was refused as well, so
28
+ * it can free more space only when the first step was not enough.
27
29
  *
28
30
  * Reads are not wrapped: the middleware already catches a read that throws and
29
31
  * hydrates nothing.
30
32
  */
31
- export declare function createGuardedAssistantStorage<S>(storage: PersistStorage<S> | undefined, onWriteError?: (error: unknown, name: string) => void): PersistStorage<S> | undefined;
33
+ export declare function createGuardedAssistantStorage<S>(storage: PersistStorage<S> | undefined, onWriteError?: (error: unknown, name: string, stillFailing: () => boolean) => void): PersistStorage<S> | undefined;
32
34
  //# sourceMappingURL=guardedStorage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"guardedStorage.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/guardedStorage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,6BAA6B,CAAC,CAAC,EAC7C,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,SAAS,EACtC,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,GACpD,cAAc,CAAC,CAAC,CAAC,GAAG,SAAS,CA8C/B"}
1
+ {"version":3,"file":"guardedStorage.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/guardedStorage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,6BAA6B,CAAC,CAAC,EAC7C,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,SAAS,EACtC,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,OAAO,KAAK,IAAI,GACjF,cAAc,CAAC,CAAC,CAAC,GAAG,SAAS,CA8C/B"}
@@ -5,7 +5,7 @@ function e(e, t) {
5
5
  if (n || (n = !0, console.warn(`[assistant] could not save "${i}"; this page keeps working, but the change is not saved until a later save fits`, e)), !(!t || r)) {
6
6
  r = !0;
7
7
  try {
8
- t(e, i);
8
+ t(e, i, () => n);
9
9
  } catch {} finally {
10
10
  r = !1;
11
11
  }
@@ -0,0 +1,38 @@
1
+ import { AssistantHistoryChangePage, AssistantHistoryConvRef, AssistantHistoryDeletePayload, AssistantHistoryEntryPage, AssistantHistoryEntryPaging, AssistantHistoryHeaderPage, AssistantHistorySaveInput, AssistantHistorySavePayload, AssistantHistoryScope } from './historyTypes';
2
+ export interface AssistantHistoryTransport {
3
+ changes(scope: AssistantHistoryScope, page: {
4
+ first: number;
5
+ after: string | null;
6
+ }): Promise<AssistantHistoryChangePage>;
7
+ conversations(scope: AssistantHistoryScope, page: {
8
+ first: number;
9
+ after: string | null;
10
+ }): Promise<AssistantHistoryHeaderPage>;
11
+ entries(scope: AssistantHistoryScope, ref: AssistantHistoryConvRef, page: AssistantHistoryEntryPaging): Promise<AssistantHistoryEntryPage>;
12
+ save(scope: AssistantHistoryScope, input: AssistantHistorySaveInput): Promise<AssistantHistorySavePayload>;
13
+ remove(scope: AssistantHistoryScope, ref: AssistantHistoryConvRef): Promise<AssistantHistoryDeletePayload>;
14
+ }
15
+ /** The server answered, but not with a shape this client understands. Never a reason to drop. */
16
+ export declare class AssistantHistoryResponseError extends Error {
17
+ constructor(operationName: string, detail: string);
18
+ }
19
+ /** The request's workspace or account is not the active one, so it was not sent. Hold, never drop. */
20
+ export declare class AssistantHistoryScopeInactiveError extends Error {
21
+ constructor();
22
+ }
23
+ /** One GraphQL call, as `executeAssistantGraphQLOnce` makes it. Injected in tests. */
24
+ export type AssistantHistoryExecutor = <TData>(params: {
25
+ query: string;
26
+ operationName: string;
27
+ variables: Record<string, unknown>;
28
+ workspaceId: string;
29
+ }) => Promise<TData>;
30
+ export interface GatewayHistoryTransportOptions {
31
+ execute?: AssistantHistoryExecutor;
32
+ /** The app's active workspace right now (default: the one a chat turn resolves). */
33
+ activeWorkspaceId?: () => string;
34
+ /** The signed-in account right now (default: the access token's subject). */
35
+ activeActorId?: () => string | null;
36
+ }
37
+ export declare function createGatewayHistoryTransport(options?: GatewayHistoryTransportOptions): AssistantHistoryTransport;
38
+ //# sourceMappingURL=historyApi.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"historyApi.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/history/historyApi.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAqBH,OAAO,KAAK,EACV,0BAA0B,EAC1B,uBAAuB,EAEvB,6BAA6B,EAE7B,yBAAyB,EACzB,2BAA2B,EAC3B,0BAA0B,EAG1B,yBAAyB,EAEzB,2BAA2B,EAC3B,qBAAqB,EAGtB,MAAM,gBAAgB,CAAC;AAExB,MAAM,WAAW,yBAAyB;IACxC,OAAO,CACL,KAAK,EAAE,qBAAqB,EAC5B,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAC5C,OAAO,CAAC,0BAA0B,CAAC,CAAC;IACvC,aAAa,CACX,KAAK,EAAE,qBAAqB,EAC5B,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAC5C,OAAO,CAAC,0BAA0B,CAAC,CAAC;IACvC,OAAO,CACL,KAAK,EAAE,qBAAqB,EAC5B,GAAG,EAAE,uBAAuB,EAC5B,IAAI,EAAE,2BAA2B,GAChC,OAAO,CAAC,yBAAyB,CAAC,CAAC;IACtC,IAAI,CACF,KAAK,EAAE,qBAAqB,EAC5B,KAAK,EAAE,yBAAyB,GAC/B,OAAO,CAAC,2BAA2B,CAAC,CAAC;IACxC,MAAM,CACJ,KAAK,EAAE,qBAAqB,EAC5B,GAAG,EAAE,uBAAuB,GAC3B,OAAO,CAAC,6BAA6B,CAAC,CAAC;CAC3C;AAED,iGAAiG;AACjG,qBAAa,6BAA8B,SAAQ,KAAK;gBAC1C,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAIlD;AAED,sGAAsG;AACtG,qBAAa,kCAAmC,SAAQ,KAAK;;CAK5D;AAED,sFAAsF;AACtF,MAAM,MAAM,wBAAwB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE;IACrD,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,WAAW,EAAE,MAAM,CAAC;CACrB,KAAK,OAAO,CAAC,KAAK,CAAC,CAAC;AAErB,MAAM,WAAW,8BAA8B;IAC7C,OAAO,CAAC,EAAE,wBAAwB,CAAC;IACnC,oFAAoF;IACpF,iBAAiB,CAAC,EAAE,MAAM,MAAM,CAAC;IACjC,6EAA6E;IAC7E,aAAa,CAAC,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;CACrC;AAWD,wBAAgB,6BAA6B,CAC3C,OAAO,GAAE,8BAAmC,GAC3C,yBAAyB,CAgH3B"}
@@ -0,0 +1,153 @@
1
+ import { executeAssistantGraphQLOnce as e } from "../gatewayClient.js";
2
+ import { getActorId as t, getWorkspaceId as n } from "../context.js";
3
+ import { ASSISTANT_HISTORY_CHANGES_OPERATION as r, ASSISTANT_HISTORY_CHANGES_QUERY as i, ASSISTANT_HISTORY_CONVERSATIONS_OPERATION as a, ASSISTANT_HISTORY_CONVERSATIONS_QUERY as o, ASSISTANT_HISTORY_DELETE_MUTATION as s, ASSISTANT_HISTORY_DELETE_OPERATION as c, ASSISTANT_HISTORY_ENTRIES_OPERATION as l, ASSISTANT_HISTORY_ENTRIES_QUERY as u, ASSISTANT_HISTORY_SAVE_MUTATION as d, ASSISTANT_HISTORY_SAVE_OPERATION as f, buildHistoryDeleteVariables as p, buildHistoryEntriesVariables as m, buildHistoryPageVariables as h, buildHistorySaveVariables as g } from "./historyOperations.js";
4
+ import { historyTimestampToIso as _ } from "./historyTimestamps.js";
5
+ //#region src/shared/assistant/history/historyApi.ts
6
+ var v = class extends Error {
7
+ constructor(e, t) {
8
+ super(`Assistant history: unexpected ${e} response (${t})`), this.name = "AssistantHistoryResponseError";
9
+ }
10
+ }, y = class extends Error {
11
+ constructor() {
12
+ super("Assistant history: the request's workspace or account is not the active one"), this.name = "AssistantHistoryScopeInactiveError";
13
+ }
14
+ };
15
+ function b(e) {
16
+ try {
17
+ return e();
18
+ } catch {
19
+ return null;
20
+ }
21
+ }
22
+ function x(_ = {}) {
23
+ let x = _.execute ?? ((t) => e(t)), w = _.activeWorkspaceId ?? n, T = _.activeActorId ?? t, j = async (e, t, n, r) => {
24
+ if (!e.workspaceId || !e.actorId || b(w) !== e.workspaceId || b(T) !== e.actorId) throw new y();
25
+ let i = await x({
26
+ query: n,
27
+ operationName: t,
28
+ variables: r,
29
+ workspaceId: e.workspaceId
30
+ });
31
+ if (!E(i)) throw new v(t, "no data");
32
+ return i;
33
+ };
34
+ return {
35
+ async changes(e, t) {
36
+ let n = await j(e, r, i, h(e, t)), a = D(r), o = a.record(n.myAssistantHistoryChanges, "myAssistantHistoryChanges");
37
+ return {
38
+ nodes: a.list(o.nodes, "nodes").map((e) => k(a, e)),
39
+ pageInfo: O(a, o.pageInfo),
40
+ resetRequired: a.bool(o.resetRequired, "resetRequired")
41
+ };
42
+ },
43
+ async conversations(e, t) {
44
+ let n = await j(e, a, o, h(e, t)), r = D(a), i = r.record(n.myAssistantConversations, "myAssistantConversations");
45
+ return {
46
+ nodes: r.list(i.nodes, "nodes").map((e) => k(r, e)),
47
+ pageInfo: O(r, i.pageInfo)
48
+ };
49
+ },
50
+ async entries(e, t, n) {
51
+ let r = await j(e, l, u, m(e, t, n)), i = D(l), a = i.record(r.myAssistantConversationEntries, "myAssistantConversationEntries");
52
+ return {
53
+ conversation: k(i, a.conversation),
54
+ nodes: i.list(a.nodes, "nodes").map((e) => A(i, e)),
55
+ pageInfo: O(i, a.pageInfo)
56
+ };
57
+ },
58
+ async save(e, t) {
59
+ let n = await j(e, f, d, g(e, t)), r = D(f), i = r.record(n.saveMyAssistantHistoryEntries, "saveMyAssistantHistoryEntries");
60
+ return {
61
+ outcome: r.oneOf(i.outcome, S, "outcome"),
62
+ conversation: k(r, i.conversation),
63
+ entries: r.list(i.entries, "entries").map((e) => A(r, e)),
64
+ droppedMetadataKeys: r.list(i.droppedMetadataKeys, "droppedMetadataKeys").map((e) => r.string(e, "droppedMetadataKeys[]"))
65
+ };
66
+ },
67
+ async remove(e, t) {
68
+ let n = await j(e, c, s, p(e, t)), r = D(c), i = r.record(n.deleteMyAssistantConversation, "deleteMyAssistantConversation");
69
+ return {
70
+ outcome: r.oneOf(i.outcome, C, "outcome"),
71
+ conversation: i.conversation == null ? null : k(r, i.conversation)
72
+ };
73
+ }
74
+ };
75
+ }
76
+ var S = [
77
+ "APPLIED",
78
+ "ALREADY_APPLIED",
79
+ "CONVERSATION_DELETED"
80
+ ], C = [
81
+ "DELETED",
82
+ "ALREADY_DELETED",
83
+ "TOMBSTONED_UNSEEN",
84
+ "NOT_PRESENT"
85
+ ], w = [
86
+ "USER",
87
+ "ASSISTANT",
88
+ "NOTE"
89
+ ], T = [
90
+ "TURN",
91
+ "LOCAL_COMMAND",
92
+ "NOTE"
93
+ ];
94
+ function E(e) {
95
+ return typeof e == "object" && !!e && !Array.isArray(e);
96
+ }
97
+ function D(e) {
98
+ let t = (t) => {
99
+ throw new v(e, t);
100
+ };
101
+ return {
102
+ record: (e, n) => E(e) ? e : t(n),
103
+ list: (e, n) => Array.isArray(e) ? e : t(n),
104
+ string: (e, n) => typeof e == "string" ? e : t(n),
105
+ optionalString: (e, n) => e == null ? null : typeof e == "string" ? e : t(n),
106
+ int: (e, n) => typeof e == "number" && Number.isSafeInteger(e) ? e : t(n),
107
+ optionalInt: (e, n) => e == null ? null : typeof e == "number" && Number.isSafeInteger(e) ? e : t(n),
108
+ bool: (e, n) => typeof e == "boolean" ? e : t(n),
109
+ time: (e, n) => _(e) ?? t(n),
110
+ oneOf: (e, n, r) => n.find((t) => t === e) ?? t(r)
111
+ };
112
+ }
113
+ function O(e, t) {
114
+ let n = e.record(t, "pageInfo");
115
+ return {
116
+ hasNextPage: e.bool(n.hasNextPage, "pageInfo.hasNextPage"),
117
+ hasPreviousPage: e.bool(n.hasPreviousPage, "pageInfo.hasPreviousPage"),
118
+ startCursor: e.optionalString(n.startCursor, "pageInfo.startCursor"),
119
+ endCursor: e.optionalString(n.endCursor, "pageInfo.endCursor")
120
+ };
121
+ }
122
+ function k(e, t) {
123
+ let n = e.record(t, "conversation");
124
+ return {
125
+ id: e.string(n.id, "conversation.id"),
126
+ clientConversationId: e.optionalString(n.clientConversationId, "conversation.clientConversationId"),
127
+ productId: e.string(n.productId, "conversation.productId"),
128
+ title: e.optionalString(n.title, "conversation.title"),
129
+ legacy: e.bool(n.legacy, "conversation.legacy"),
130
+ revision: e.int(n.revision, "conversation.revision"),
131
+ lastMessageSeq: e.int(n.lastMessageSeq, "conversation.lastMessageSeq"),
132
+ deleted: e.bool(n.deleted, "conversation.deleted"),
133
+ deletedAt: n.deletedAt == null ? null : e.time(n.deletedAt, "conversation.deletedAt"),
134
+ createdAt: e.time(n.createdAt, "conversation.createdAt"),
135
+ updatedAt: e.time(n.updatedAt, "conversation.updatedAt")
136
+ };
137
+ }
138
+ function A(e, t) {
139
+ let n = e.record(t, "entry");
140
+ return {
141
+ id: e.string(n.id, "entry.id"),
142
+ clientMessageId: e.optionalString(n.clientMessageId, "entry.clientMessageId"),
143
+ kind: T.find((e) => e === n.kind) ?? null,
144
+ role: e.oneOf(n.role, w, "entry.role"),
145
+ content: e.string(n.content, "entry.content"),
146
+ seq: e.optionalInt(n.seq, "entry.seq"),
147
+ createdAt: e.time(n.createdAt, "entry.createdAt"),
148
+ clientCreatedAt: e.optionalString(n.clientCreatedAt, "entry.clientCreatedAt"),
149
+ metadata: E(n.metadata) ? n.metadata : null
150
+ };
151
+ }
152
+ //#endregion
153
+ export { v as AssistantHistoryResponseError, y as AssistantHistoryScopeInactiveError, x as createGatewayHistoryTransport };
@@ -0,0 +1,96 @@
1
+ import { AssistantModeConfig } from '../conversation';
2
+ import { useAssistantStore } from '../store';
3
+ import { AssistantHistoryTransport } from './historyApi';
4
+ import { AssistantHistoryStatusStore } from './historyStatus';
5
+ import { AssistantHistoryStoreHandle } from './historyStore';
6
+ import { AssistantHistoryConvKey, AssistantHistoryEntryKind, AssistantHistoryScope } from './historyTypes';
7
+ /** Time, injectable so the engine's backoff and pruning are testable without real timers. */
8
+ export interface AssistantHistoryClock {
9
+ now(): number;
10
+ setTimeout(callback: () => void, ms: number): unknown;
11
+ clearTimeout(handle: unknown): void;
12
+ }
13
+ /**
14
+ * The cross-tab drain lock (`navigator.locks` with `ifAvailable`). `held` is
15
+ * false when another tab holds it; without Web Locks every tab drains, which
16
+ * is safe because every write is idempotent.
17
+ */
18
+ export interface AssistantHistoryLocks {
19
+ request<T>(name: string, run: (held: boolean) => Promise<T>): Promise<T>;
20
+ }
21
+ export interface AssistantHistoryEngineDeps {
22
+ transport: AssistantHistoryTransport;
23
+ /**
24
+ * The persisted history store (the app's, or a fresh one in a test). It
25
+ * reads nothing until bound: the engine calls `rebind()` when it is enabled
26
+ * and whenever the active profile is no longer the one it is bound to.
27
+ */
28
+ storage: AssistantHistoryStoreHandle;
29
+ clock: AssistantHistoryClock;
30
+ /** Default: `navigator.locks` when the browser has it, otherwise none. */
31
+ locks?: AssistantHistoryLocks | null;
32
+ random?: () => number;
33
+ /** The signed-in account now (default: the access token's subject). */
34
+ readActorId?: () => string | null;
35
+ /** The app's active workspace now (default: the one a chat turn resolves). */
36
+ readWorkspaceId?: () => string;
37
+ /** The panel's store (default: the app's). */
38
+ mainStore?: typeof useAssistantStore;
39
+ /** Where loading flags, the pause and notices go (default: the app's). */
40
+ status?: AssistantHistoryStatusStore;
41
+ /** Something live in this conversation besides a turn (default: the panel's registered probe). */
42
+ isConversationBusy?: (conversationId: string) => boolean;
43
+ /** Watch the page for scope changes (1 s poll + focus, visibility, online, storage events). Default true. */
44
+ watchScope?: boolean;
45
+ log?: (message: string, detail?: unknown) => void;
46
+ }
47
+ export interface AssistantHistoryOpenOptions {
48
+ /** The product's modes: a conversation opened from the server starts in the first one that does not write. */
49
+ modes?: readonly AssistantModeConfig[];
50
+ }
51
+ export interface AssistantHistoryEngine {
52
+ /** Opt a product in (ref-counted). Returns the release. */
53
+ enable(product: string): () => void;
54
+ /** The active scope, or null when the account, workspace or product is unknown. Starts a new generation. */
55
+ setScope(scope: AssistantHistoryScope | null): void;
56
+ /** Re-read the account, workspace and profile, and follow any change (the engine also does this itself). */
57
+ refreshScope(): void;
58
+ /** A turn has committed locally: queue its entries (no-op unless every guard holds). */
59
+ recordCommittedEntries(conversationId: string, messageIds: readonly string[], kind: AssistantHistoryEntryKind, turnWorkspaceId: string): void;
60
+ /** The UI's delete while history is on: tombstone, drop unsent saves, queue the delete, remove locally. */
61
+ deleteConversation(convKey: AssistantHistoryConvKey): void;
62
+ /** Materialise a server conversation locally (if needed), open it, and load its messages. */
63
+ openConversation(convKey: AssistantHistoryConvKey, options?: AssistantHistoryOpenOptions): void;
64
+ loadEarlier(convKey: AssistantHistoryConvKey): void;
65
+ loadOlderHeaders(): void;
66
+ /** The history list was opened: retry quota-parked saves now, and pull. */
67
+ notePanelOpened(): void;
68
+ pull(reason: string): void;
69
+ drain(): void;
70
+ }
71
+ /** The engine plus what only tests and diagnostics need. */
72
+ export interface AssistantHistoryEngineHandle extends AssistantHistoryEngine {
73
+ /** Resolves once nothing the engine started is still running (timers not included). */
74
+ settled(): Promise<void>;
75
+ /** Switch off completely: every hold released, every timer cleared, every listener removed. */
76
+ dispose(): void;
77
+ }
78
+ /**
79
+ * ★★ How long after a reset a further `resetRequired` is not acted on. The
80
+ * server answers it for EVERY cursor below its tombstone floor — the pages of
81
+ * the re-pull itself included, and a cursor that stays below the floor
82
+ * because the newest rows were the ones purged — so acting on each one would
83
+ * restart the re-pull forever, keeping the oldest page and never applying a
84
+ * delete. Ignoring it is safe while everything held here was read after the
85
+ * reset: a delete of any of it is newer than the reset, and a tombstone is
86
+ * purged (what the floor is for) only long after its delete — as built, the
87
+ * row is never removed and its content goes 30 days on. Past this window the
88
+ * next one resets again: at most one reset per window.
89
+ */
90
+ export declare const ASSISTANT_HISTORY_RESET_TRUST_MS: number;
91
+ /** Real timers behind opaque handles (the clock interface does not expose the platform's handle type). */
92
+ export declare function createSystemHistoryClock(): AssistantHistoryClock;
93
+ export declare function createAssistantHistoryEngine(deps: AssistantHistoryEngineDeps): AssistantHistoryEngineHandle;
94
+ /** The app's engine: off until a panel opts in (`serverHistory`), and reads nothing before. */
95
+ export declare const assistantHistory: AssistantHistoryEngine;
96
+ //# sourceMappingURL=historyEngine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"historyEngine.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/history/historyEngine.ts"],"names":[],"mappings":"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"}