@turingfocus/chat-runtime 0.1.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 A2C-SMCP contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,34 @@
1
+ import { type AnswerInteractionInput, type AnswerInteractionSuccess, type ChatGateway, type ChatSnapshot, type GatewayRequestOptions, type GatewayResult, type InterruptRunInput, type InterruptRunSuccess, type LoadConversationInput, type SendTextInput, type SendTextSuccess } from "@turingfocus/chat-protocol";
2
+ import { type SnapshotListener, type SnapshotSubscription } from "./snapshot-store.js";
3
+ export interface ChatClientOptions {
4
+ /** The instance-owned transport port. ChatClient disposes it on shutdown. */
5
+ readonly gateway: ChatGateway;
6
+ /** Receives isolated listener and best-effort subscription cleanup failures. */
7
+ readonly onUnhandledError?: ((failure: ChatClientUnhandledError) => void) | undefined;
8
+ }
9
+ export type ChatClientUnhandledErrorSource = "listener" | "subscription-cleanup";
10
+ export interface ChatClientUnhandledError {
11
+ readonly cause: unknown;
12
+ readonly conversationId?: string | undefined;
13
+ readonly source: ChatClientUnhandledErrorSource;
14
+ }
15
+ export type ChatSnapshotListener = SnapshotListener;
16
+ export type ChatClientSubscription = SnapshotSubscription;
17
+ /**
18
+ * Headless, instance-scoped owner of normalized chat state and commands.
19
+ * Each instance owns exactly one injected Gateway and its subscriptions.
20
+ */
21
+ export declare class ChatClient {
22
+ #private;
23
+ constructor(options: ChatClientOptions);
24
+ get disposed(): boolean;
25
+ getSnapshot(): ChatSnapshot | null;
26
+ subscribe(listener: ChatSnapshotListener): ChatClientSubscription;
27
+ loadConversation(input: LoadConversationInput): Promise<GatewayResult<ChatSnapshot>>;
28
+ sendText(input: SendTextInput): Promise<GatewayResult<SendTextSuccess>>;
29
+ answerInteraction(input: AnswerInteractionInput): Promise<GatewayResult<AnswerInteractionSuccess>>;
30
+ interrupt(input: InterruptRunInput): Promise<GatewayResult<InterruptRunSuccess>>;
31
+ dispose(options: GatewayRequestOptions): Promise<void>;
32
+ }
33
+ export declare const createChatClient: (options: ChatClientOptions) => ChatClient;
34
+ //# sourceMappingURL=chat-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-client.d.ts","sourceRoot":"","sources":["../src/chat-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,sBAAsB,EAC3B,KAAK,wBAAwB,EAE7B,KAAK,WAAW,EAChB,KAAK,YAAY,EAEjB,KAAK,qBAAqB,EAC1B,KAAK,aAAa,EAElB,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,EAC1B,KAAK,aAAa,EAClB,KAAK,eAAe,EACrB,MAAM,4BAA4B,CAAC;AAiBpC,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EAC1B,MAAM,qBAAqB,CAAC;AAG7B,MAAM,WAAW,iBAAiB;IAChC,6EAA6E;IAC7E,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAC9B,gFAAgF;IAChF,QAAQ,CAAC,gBAAgB,CAAC,EACxB,CAAC,CAAC,OAAO,EAAE,wBAAwB,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CAC7D;AAED,MAAM,MAAM,8BAA8B,GACxC,UAAU,GAAG,sBAAsB,CAAC;AAEtC,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7C,QAAQ,CAAC,MAAM,EAAE,8BAA8B,CAAC;CACjD;AAED,MAAM,MAAM,oBAAoB,GAAG,gBAAgB,CAAC;AACpD,MAAM,MAAM,sBAAsB,GAAG,oBAAoB,CAAC;AAuE1D;;;GAGG;AACH,qBAAa,UAAU;;gBAiBT,OAAO,EAAE,iBAAiB;IAUtC,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED,WAAW,IAAI,YAAY,GAAG,IAAI;IAIlC,SAAS,CAAC,QAAQ,EAAE,oBAAoB,GAAG,sBAAsB;IAI3D,gBAAgB,CACpB,KAAK,EAAE,qBAAqB,GAC3B,OAAO,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;IA2JjC,QAAQ,CACZ,KAAK,EAAE,aAAa,GACnB,OAAO,CAAC,aAAa,CAAC,eAAe,CAAC,CAAC;IAiBpC,iBAAiB,CACrB,KAAK,EAAE,sBAAsB,GAC5B,OAAO,CAAC,aAAa,CAAC,wBAAwB,CAAC,CAAC;IAkI7C,SAAS,CACb,KAAK,EAAE,iBAAiB,GACvB,OAAO,CAAC,aAAa,CAAC,mBAAmB,CAAC,CAAC;IAwC9C,OAAO,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;CAsUvD;AAED,eAAO,MAAM,gBAAgB,GAAI,SAAS,iBAAiB,KAAG,UACrC,CAAC"}
@@ -0,0 +1,502 @@
1
+ import { answerInteractionInputSchema, getAskUserInteractionAnswerValidationError, isGatewayOperationSupported, } from "@turingfocus/chat-protocol";
2
+ import { createGatewayNotificationQueue, } from "./gateway-notification-queue.js";
3
+ import { cloneImmutable, deepEqual } from "./immutable.js";
4
+ import { applySnapshotError, applySnapshotUpdate, createSnapshotState, rebaseSnapshotState, updateConversationId, updateSnapshotState, } from "./snapshot-state.js";
5
+ import { SnapshotStore, } from "./snapshot-store.js";
6
+ import { mergeHistoryTimeline } from "./timeline.js";
7
+ const runtimeFailure = (code, message, conversationId) => ({
8
+ ok: false,
9
+ error: cloneImmutable({
10
+ code,
11
+ message,
12
+ retryable: false,
13
+ ...(conversationId === undefined ? {} : { conversationId }),
14
+ }),
15
+ });
16
+ const MAX_RETIRED_INTERACTION_IDENTITIES = 256;
17
+ const interactionIdentityKey = ({ requestId, revision, }) => `${requestId.length}:${requestId}:${revision.length}:${revision}`;
18
+ const interactionAnswerInFlightKey = (conversationEpoch, conversationId, identity) => `${conversationEpoch}:${conversationId.length}:${conversationId}:${interactionIdentityKey(identity)}`;
19
+ const hasSameInteractionIdentity = (left, right) => {
20
+ if (left === undefined || right === undefined)
21
+ return left === right;
22
+ return left.requestId === right.requestId && left.revision === right.revision;
23
+ };
24
+ const retiredInteractionError = (conversationId) => cloneImmutable({
25
+ code: "conflict",
26
+ conversationId,
27
+ message: "A retired interaction revision cannot become pending again",
28
+ retryable: false,
29
+ });
30
+ const runCleanup = async (cleanup, onError) => {
31
+ try {
32
+ await cleanup();
33
+ }
34
+ catch (error) {
35
+ onError(error);
36
+ }
37
+ };
38
+ /**
39
+ * Headless, instance-scoped owner of normalized chat state and commands.
40
+ * Each instance owns exactly one injected Gateway and its subscriptions.
41
+ */
42
+ export class ChatClient {
43
+ #gateway;
44
+ #onUnhandledError;
45
+ #snapshotStore;
46
+ #disposed = false;
47
+ #disposePromise;
48
+ #conversationEpoch = 0;
49
+ #generation = 0;
50
+ #gatewaySubscription;
51
+ #interactionAnswersInFlight = new Set();
52
+ #retiredInteractionIdentities = new Set();
53
+ #supersededInteractionAnswers = new Set();
54
+ #historyRequestId = 0;
55
+ #loadRequestId = 0;
56
+ #pendingHandoff;
57
+ constructor(options) {
58
+ this.#gateway = options.gateway;
59
+ this.#onUnhandledError = options.onUnhandledError;
60
+ this.#snapshotStore = new SnapshotStore({
61
+ onListenerError: (cause) => {
62
+ this.#reportUnhandledError({ cause, source: "listener" });
63
+ },
64
+ });
65
+ }
66
+ get disposed() {
67
+ return this.#disposed;
68
+ }
69
+ getSnapshot() {
70
+ return this.#snapshotStore.getSnapshot();
71
+ }
72
+ subscribe(listener) {
73
+ return this.#snapshotStore.subscribe(listener);
74
+ }
75
+ async loadConversation(input) {
76
+ if (this.#disposed) {
77
+ return runtimeFailure("conflict", "ChatClient has already been disposed", input.conversationId);
78
+ }
79
+ if (input.previousCursor !== undefined)
80
+ return this.#loadHistory(input);
81
+ const requestId = ++this.#loadRequestId;
82
+ if (this.#disposed) {
83
+ return runtimeFailure("conflict", "Conversation load was superseded", input.conversationId);
84
+ }
85
+ const notificationQueue = createGatewayNotificationQueue((notification, generation) => {
86
+ if (notification.kind === "update") {
87
+ this.#applyGatewayUpdate(notification.update, generation);
88
+ }
89
+ else {
90
+ this.#applyGatewayError(notification.error, generation);
91
+ }
92
+ });
93
+ const baseline = this.#snapshotStore.state;
94
+ if (baseline?.snapshot.conversation.id === input.conversationId) {
95
+ this.#pendingHandoff = {
96
+ baseline,
97
+ conversationId: input.conversationId,
98
+ enqueue: notificationQueue.enqueue,
99
+ requestId,
100
+ sourceGeneration: this.#generation,
101
+ };
102
+ }
103
+ // Register the observer before loading the snapshot so notifications that
104
+ // occur at the snapshot boundary are buffered instead of being lost.
105
+ const subscribed = await this.#subscribeGateway(input, notificationQueue);
106
+ if (this.#disposed || requestId !== this.#loadRequestId) {
107
+ this.#clearPendingHandoff(requestId);
108
+ await this.#discardGatewaySubscription(subscribed, input);
109
+ return runtimeFailure("conflict", "Conversation load was superseded", input.conversationId);
110
+ }
111
+ const loaded = await this.#gateway.loadConversation(input);
112
+ if (!loaded.ok) {
113
+ this.#clearPendingHandoff(requestId);
114
+ await this.#discardGatewaySubscription(subscribed, input);
115
+ if (this.#disposed || requestId !== this.#loadRequestId) {
116
+ return runtimeFailure("conflict", "Conversation load was superseded", input.conversationId);
117
+ }
118
+ return loaded;
119
+ }
120
+ if (this.#disposed || requestId !== this.#loadRequestId) {
121
+ this.#clearPendingHandoff(requestId);
122
+ if (loaded.value.capabilities.liveUpdates) {
123
+ await this.#discardGatewaySubscription(subscribed, input);
124
+ }
125
+ return runtimeFailure("conflict", "Conversation load was superseded", input.conversationId);
126
+ }
127
+ if (loaded.value.conversation.id !== input.conversationId) {
128
+ this.#clearPendingHandoff(requestId);
129
+ await this.#discardGatewaySubscription(subscribed, input);
130
+ return runtimeFailure("validation", "Gateway returned a snapshot for a different conversation", input.conversationId);
131
+ }
132
+ if (loaded.value.capabilities.liveUpdates && !subscribed.ok) {
133
+ this.#clearPendingHandoff(requestId);
134
+ if (this.#disposed || requestId !== this.#loadRequestId) {
135
+ return runtimeFailure("conflict", "Conversation load was superseded", input.conversationId);
136
+ }
137
+ return subscribed;
138
+ }
139
+ if (!loaded.value.capabilities.liveUpdates) {
140
+ await this.#discardGatewaySubscription(subscribed, input);
141
+ }
142
+ if (this.#disposed || requestId !== this.#loadRequestId) {
143
+ this.#clearPendingHandoff(requestId);
144
+ await this.#discardGatewaySubscription(subscribed, input);
145
+ return runtimeFailure("conflict", "Conversation load was superseded", input.conversationId);
146
+ }
147
+ const previousSubscription = this.#gatewaySubscription;
148
+ const generation = ++this.#generation;
149
+ this.#historyRequestId += 1;
150
+ this.#gatewaySubscription =
151
+ loaded.value.capabilities.liveUpdates && subscribed.ok
152
+ ? subscribed.value
153
+ : undefined;
154
+ const loadedState = createSnapshotState(loaded.value);
155
+ const currentState = this.#snapshotStore.state;
156
+ const handoff = this.#pendingHandoff;
157
+ let nextState = handoff?.requestId === requestId && currentState !== null
158
+ ? rebaseSnapshotState(handoff.baseline, loadedState, currentState)
159
+ : loadedState;
160
+ if (currentState?.snapshot.conversation.id !==
161
+ nextState.snapshot.conversation.id) {
162
+ this.#conversationEpoch += 1;
163
+ this.#retiredInteractionIdentities.clear();
164
+ }
165
+ else if (currentState !== null) {
166
+ nextState = this.#guardInteractionTransition(currentState, nextState);
167
+ }
168
+ this.#snapshotStore.commit(nextState);
169
+ if (!this.#disposed)
170
+ notificationQueue.activate(generation);
171
+ this.#clearPendingHandoff(requestId);
172
+ await this.#runSubscriptionCleanup(() => previousSubscription?.dispose(input), input.conversationId);
173
+ if (this.#disposed ||
174
+ requestId !== this.#loadRequestId ||
175
+ generation !== this.#generation ||
176
+ this.#snapshotStore.state?.snapshot.conversation.id !==
177
+ input.conversationId) {
178
+ return runtimeFailure("conflict", "Conversation load was superseded", input.conversationId);
179
+ }
180
+ return { ok: true, value: this.#snapshotStore.state.snapshot };
181
+ }
182
+ async sendText(input) {
183
+ const state = this.#activeState(input.conversationId);
184
+ if (!state.ok)
185
+ return state;
186
+ if (!isGatewayOperationSupported(state.value.capabilities, "sendText")) {
187
+ return runtimeFailure("unsupported", "Text sending is unavailable", input.conversationId);
188
+ }
189
+ const generation = this.#generation;
190
+ const result = await this.#gateway.sendText(input);
191
+ if (!result.ok)
192
+ this.#reportError(result.error, generation);
193
+ return result;
194
+ }
195
+ async answerInteraction(input) {
196
+ const parsed = answerInteractionInputSchema.safeParse(input);
197
+ if (!parsed.success) {
198
+ return runtimeFailure("validation", "Interaction answer input is invalid", typeof input.conversationId === "string"
199
+ ? input.conversationId
200
+ : undefined);
201
+ }
202
+ const command = parsed.data;
203
+ const state = this.#activeState(command.conversationId);
204
+ if (!state.ok)
205
+ return state;
206
+ const pending = state.value.pendingInteraction;
207
+ if (pending === undefined ||
208
+ pending.requestId !== command.answer.requestId ||
209
+ pending.revision !== command.answer.revision) {
210
+ return runtimeFailure("conflict", "Interaction request is no longer pending", command.conversationId);
211
+ }
212
+ const conversationEpoch = this.#conversationEpoch;
213
+ const inFlightKey = interactionAnswerInFlightKey(conversationEpoch, command.conversationId, command.answer);
214
+ if (this.#interactionAnswersInFlight.has(inFlightKey)) {
215
+ return runtimeFailure("conflict", "Interaction request is already being answered", command.conversationId);
216
+ }
217
+ if (!isGatewayOperationSupported(state.value.capabilities, "answerInteraction") ||
218
+ this.#gateway.answerInteraction === undefined) {
219
+ return runtimeFailure("unsupported", "Interaction answers are unavailable", command.conversationId);
220
+ }
221
+ if (getAskUserInteractionAnswerValidationError(pending, command.answer) !==
222
+ undefined) {
223
+ return runtimeFailure("validation", "Interaction answers do not match the pending questions", command.conversationId);
224
+ }
225
+ this.#interactionAnswersInFlight.add(inFlightKey);
226
+ try {
227
+ const result = await this.#gateway.answerInteraction(command);
228
+ const current = this.#snapshotStore.state?.snapshot;
229
+ const sameActiveConversation = !this.#disposed &&
230
+ conversationEpoch === this.#conversationEpoch &&
231
+ current?.conversation.id === command.conversationId;
232
+ if (!sameActiveConversation) {
233
+ return runtimeFailure("conflict", "Interaction answer was superseded", command.conversationId);
234
+ }
235
+ if (this.#supersededInteractionAnswers.has(inFlightKey)) {
236
+ return runtimeFailure("conflict", "Interaction answer was superseded", command.conversationId);
237
+ }
238
+ const currentPending = current.pendingInteraction;
239
+ if (currentPending !== undefined &&
240
+ !hasSameInteractionIdentity(currentPending, pending)) {
241
+ return runtimeFailure("conflict", "Interaction answer was superseded", command.conversationId);
242
+ }
243
+ if (!result.ok) {
244
+ if (hasSameInteractionIdentity(currentPending, pending)) {
245
+ this.#reportError(result.error, this.#generation);
246
+ }
247
+ return result;
248
+ }
249
+ if (result.value.requestId !== command.answer.requestId ||
250
+ result.value.revision !== command.answer.revision) {
251
+ return runtimeFailure("validation", "Gateway acknowledged a different interaction request", command.conversationId);
252
+ }
253
+ const latest = this.#snapshotStore.latestState();
254
+ if (latest !== null &&
255
+ hasSameInteractionIdentity(latest.snapshot.pendingInteraction, pending)) {
256
+ this.#snapshotStore.commit(this.#guardInteractionTransition(latest, updateSnapshotState(latest, { pendingInteraction: undefined })));
257
+ }
258
+ return result;
259
+ }
260
+ finally {
261
+ this.#interactionAnswersInFlight.delete(inFlightKey);
262
+ this.#supersededInteractionAnswers.delete(inFlightKey);
263
+ }
264
+ }
265
+ async interrupt(input) {
266
+ const state = this.#activeState(input.conversationId);
267
+ if (!state.ok)
268
+ return state;
269
+ const run = state.value.run;
270
+ if (input.runId !== undefined && input.runId !== run?.id) {
271
+ return runtimeFailure("conflict", "Interrupt target is no longer the active run", input.conversationId);
272
+ }
273
+ if (!isGatewayOperationSupported(state.value.capabilities, "interrupt", run)) {
274
+ return runtimeFailure("unsupported", "The active run cannot be interrupted", input.conversationId);
275
+ }
276
+ const generation = this.#generation;
277
+ const runId = run.id;
278
+ // Bind "interrupt the current run" to the run observed above. Otherwise a
279
+ // Gateway that resolves the omitted runId after an async boundary could
280
+ // accidentally interrupt a replacement run.
281
+ const result = await this.#gateway.interrupt(input.runId === undefined ? { ...input, runId } : input);
282
+ if (!result.ok &&
283
+ this.#snapshotStore.state?.snapshot.run?.id === runId &&
284
+ this.#snapshotStore.state.snapshot.conversation.id ===
285
+ input.conversationId) {
286
+ this.#reportError(result.error, generation);
287
+ }
288
+ return result;
289
+ }
290
+ dispose(options) {
291
+ if (this.#disposePromise !== undefined)
292
+ return this.#disposePromise;
293
+ this.#disposed = true;
294
+ this.#conversationEpoch += 1;
295
+ this.#generation += 1;
296
+ this.#historyRequestId += 1;
297
+ this.#interactionAnswersInFlight.clear();
298
+ this.#retiredInteractionIdentities.clear();
299
+ this.#supersededInteractionAnswers.clear();
300
+ this.#loadRequestId += 1;
301
+ this.#pendingHandoff = undefined;
302
+ this.#snapshotStore.close();
303
+ const subscription = this.#gatewaySubscription;
304
+ this.#gatewaySubscription = undefined;
305
+ this.#disposePromise = Promise.allSettled([
306
+ Promise.resolve().then(() => subscription?.dispose(options)),
307
+ Promise.resolve().then(() => this.#gateway.dispose(options)),
308
+ ]).then((results) => {
309
+ const failures = results.flatMap((result) => result.status === "rejected" ? [result.reason] : []);
310
+ if (failures.length === 1)
311
+ throw failures[0];
312
+ if (failures.length > 1) {
313
+ throw new AggregateError(failures, "ChatClient failed to dispose all owned resources");
314
+ }
315
+ });
316
+ return this.#disposePromise;
317
+ }
318
+ async #loadHistory(input) {
319
+ const active = this.#activeState(input.conversationId);
320
+ if (!active.ok)
321
+ return active;
322
+ if (!isGatewayOperationSupported(active.value.capabilities, "loadHistory")) {
323
+ return runtimeFailure("unsupported", "History loading is unavailable", input.conversationId);
324
+ }
325
+ if (active.value.pageInfo.previousCursor !== input.previousCursor) {
326
+ return runtimeFailure("conflict", "History cursor is no longer current", input.conversationId);
327
+ }
328
+ const generation = this.#generation;
329
+ const requestId = ++this.#historyRequestId;
330
+ const baselineCursor = active.value.pageInfo.previousCursor;
331
+ const loaded = await this.#gateway.loadConversation(input);
332
+ if (!loaded.ok) {
333
+ if (this.#disposed ||
334
+ generation !== this.#generation ||
335
+ requestId !== this.#historyRequestId ||
336
+ this.#snapshotStore.state?.snapshot.pageInfo.previousCursor !==
337
+ baselineCursor) {
338
+ return runtimeFailure("conflict", "History load was superseded", input.conversationId);
339
+ }
340
+ this.#reportError(loaded.error, generation);
341
+ return loaded;
342
+ }
343
+ if (this.#disposed ||
344
+ generation !== this.#generation ||
345
+ requestId !== this.#historyRequestId ||
346
+ this.#snapshotStore.state?.snapshot.pageInfo.previousCursor !==
347
+ baselineCursor ||
348
+ this.#snapshotStore.state?.snapshot.conversation.id !==
349
+ input.conversationId) {
350
+ return runtimeFailure("conflict", "History load was superseded", input.conversationId);
351
+ }
352
+ if (loaded.value.conversation.id !== input.conversationId) {
353
+ return runtimeFailure("validation", "Gateway returned history for a different conversation", input.conversationId);
354
+ }
355
+ const state = this.#snapshotStore.state;
356
+ const timeline = mergeHistoryTimeline(state.timeline, loaded.value.timeline);
357
+ const pageInfo = cloneImmutable(loaded.value.pageInfo);
358
+ if (timeline !== state.timeline ||
359
+ !deepEqual(pageInfo, state.snapshot.pageInfo)) {
360
+ this.#snapshotStore.commit(updateSnapshotState(state, { timeline, pageInfo }));
361
+ }
362
+ const committed = this.#snapshotStore.state;
363
+ if (this.#disposed ||
364
+ generation !== this.#generation ||
365
+ requestId !== this.#historyRequestId ||
366
+ committed === null ||
367
+ committed.snapshot.conversation.id !== input.conversationId) {
368
+ return runtimeFailure("conflict", "History load was superseded", input.conversationId);
369
+ }
370
+ return { ok: true, value: committed.snapshot };
371
+ }
372
+ #activeState(conversationId) {
373
+ if (this.#disposed) {
374
+ return runtimeFailure("conflict", "ChatClient has already been disposed", conversationId);
375
+ }
376
+ if (this.#snapshotStore.state?.snapshot.conversation.id !== conversationId) {
377
+ return runtimeFailure("conflict", "Conversation is not active in this ChatClient", conversationId);
378
+ }
379
+ return { ok: true, value: this.#snapshotStore.state.snapshot };
380
+ }
381
+ #subscribeGateway(input, notificationQueue) {
382
+ return Promise.resolve(this.#gateway.subscribe({
383
+ conversationId: input.conversationId,
384
+ deadlineAt: input.deadlineAt,
385
+ }, {
386
+ next: (update) => notificationQueue.enqueue({ kind: "update", update }),
387
+ error: (error) => notificationQueue.enqueue({ kind: "error", error }),
388
+ }));
389
+ }
390
+ async #discardGatewaySubscription(subscribed, input) {
391
+ if (!subscribed.ok)
392
+ return;
393
+ await this.#runSubscriptionCleanup(() => subscribed.value.dispose(input), input.conversationId);
394
+ }
395
+ #clearPendingHandoff(requestId) {
396
+ if (this.#pendingHandoff?.requestId === requestId) {
397
+ this.#pendingHandoff = undefined;
398
+ }
399
+ }
400
+ #captureHandoff(notification, generation) {
401
+ const handoff = this.#pendingHandoff;
402
+ if (handoff === undefined ||
403
+ handoff.sourceGeneration !== generation ||
404
+ this.#snapshotStore.state?.snapshot.conversation.id !==
405
+ handoff.conversationId) {
406
+ return;
407
+ }
408
+ if (notification.kind === "update") {
409
+ const targetConversationId = updateConversationId(notification.update);
410
+ if (targetConversationId !== undefined &&
411
+ targetConversationId !== handoff.conversationId) {
412
+ return;
413
+ }
414
+ }
415
+ if (notification.kind === "error" &&
416
+ notification.error.conversationId !== undefined &&
417
+ notification.error.conversationId !== handoff.conversationId) {
418
+ return;
419
+ }
420
+ handoff.enqueue(notification);
421
+ }
422
+ #applyGatewayUpdate(update, generation) {
423
+ this.#captureHandoff({ kind: "update", update }, generation);
424
+ if (this.#disposed ||
425
+ generation !== this.#generation ||
426
+ this.#snapshotStore.state === null) {
427
+ return;
428
+ }
429
+ const state = this.#snapshotStore.latestState();
430
+ this.#snapshotStore.commit(this.#guardInteractionTransition(state, applySnapshotUpdate(state, update)));
431
+ }
432
+ #guardInteractionTransition(current, candidate) {
433
+ const currentInteraction = current.snapshot.pendingInteraction;
434
+ const candidateInteraction = candidate.snapshot.pendingInteraction;
435
+ if (candidateInteraction !== undefined &&
436
+ !hasSameInteractionIdentity(currentInteraction, candidateInteraction) &&
437
+ this.#retiredInteractionIdentities.has(interactionIdentityKey(candidateInteraction))) {
438
+ return updateSnapshotState(candidate, {
439
+ pendingInteraction: currentInteraction,
440
+ error: retiredInteractionError(current.snapshot.conversation.id),
441
+ });
442
+ }
443
+ if (currentInteraction !== undefined &&
444
+ !hasSameInteractionIdentity(currentInteraction, candidateInteraction)) {
445
+ if (candidateInteraction !== undefined) {
446
+ const inFlightKey = interactionAnswerInFlightKey(this.#conversationEpoch, current.snapshot.conversation.id, currentInteraction);
447
+ if (this.#interactionAnswersInFlight.has(inFlightKey)) {
448
+ this.#supersededInteractionAnswers.add(inFlightKey);
449
+ }
450
+ }
451
+ this.#retireInteractionIdentity(currentInteraction);
452
+ }
453
+ return candidate;
454
+ }
455
+ #retireInteractionIdentity(identity) {
456
+ const key = interactionIdentityKey(identity);
457
+ this.#retiredInteractionIdentities.delete(key);
458
+ this.#retiredInteractionIdentities.add(key);
459
+ while (this.#retiredInteractionIdentities.size >
460
+ MAX_RETIRED_INTERACTION_IDENTITIES) {
461
+ const oldest = this.#retiredInteractionIdentities.values().next().value;
462
+ if (oldest === undefined)
463
+ return;
464
+ this.#retiredInteractionIdentities.delete(oldest);
465
+ }
466
+ }
467
+ #applyGatewayError(error, generation) {
468
+ this.#captureHandoff({ kind: "error", error }, generation);
469
+ this.#reportError(error, generation);
470
+ }
471
+ #reportError(error, generation) {
472
+ if (this.#disposed ||
473
+ generation !== this.#generation ||
474
+ this.#snapshotStore.state === null ||
475
+ (error.conversationId !== undefined &&
476
+ error.conversationId !==
477
+ this.#snapshotStore.state.snapshot.conversation.id)) {
478
+ return;
479
+ }
480
+ const state = this.#snapshotStore.latestState();
481
+ this.#snapshotStore.commit(applySnapshotError(state, error));
482
+ }
483
+ #reportUnhandledError(failure) {
484
+ try {
485
+ this.#onUnhandledError?.(Object.freeze(failure));
486
+ }
487
+ catch {
488
+ // A diagnostic hook must not interfere with Runtime state transitions.
489
+ }
490
+ }
491
+ #runSubscriptionCleanup(cleanup, conversationId) {
492
+ return runCleanup(cleanup, (cause) => {
493
+ this.#reportUnhandledError({
494
+ cause,
495
+ conversationId,
496
+ source: "subscription-cleanup",
497
+ });
498
+ });
499
+ }
500
+ }
501
+ export const createChatClient = (options) => new ChatClient(options);
502
+ //# sourceMappingURL=chat-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-client.js","sourceRoot":"","sources":["../src/chat-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { ChatError, ChatUpdate } from "@turingfocus/chat-protocol";
2
+ export type GatewayNotification = {
3
+ readonly kind: "update";
4
+ readonly update: ChatUpdate;
5
+ } | {
6
+ readonly kind: "error";
7
+ readonly error: ChatError;
8
+ };
9
+ export interface GatewayNotificationQueue {
10
+ activate(generation: number): void;
11
+ enqueue(notification: GatewayNotification): void;
12
+ }
13
+ type GatewayNotificationDispatcher = (notification: GatewayNotification, generation: number) => void;
14
+ /** Buffers synchronous establishment notifications and drains them in FIFO order. */
15
+ export declare const createGatewayNotificationQueue: (dispatch: GatewayNotificationDispatcher) => GatewayNotificationQueue;
16
+ export {};
17
+ //# sourceMappingURL=gateway-notification-queue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gateway-notification-queue.d.ts","sourceRoot":"","sources":["../src/gateway-notification-queue.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAExE,MAAM,MAAM,mBAAmB,GAC3B;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAA;CAAE,GACxD;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAA;CAAE,CAAC;AAE1D,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,OAAO,CAAC,YAAY,EAAE,mBAAmB,GAAG,IAAI,CAAC;CAClD;AAED,KAAK,6BAA6B,GAAG,CACnC,YAAY,EAAE,mBAAmB,EACjC,UAAU,EAAE,MAAM,KACf,IAAI,CAAC;AAEV,qFAAqF;AACrF,eAAO,MAAM,8BAA8B,GACzC,UAAU,6BAA6B,KACtC,wBA4BF,CAAC"}
@@ -0,0 +1,31 @@
1
+ /** Buffers synchronous establishment notifications and drains them in FIFO order. */
2
+ export const createGatewayNotificationQueue = (dispatch) => {
3
+ const pending = [];
4
+ let generation;
5
+ let phase = "buffering";
6
+ const dispatchActive = (notification) => {
7
+ if (generation !== undefined)
8
+ dispatch(notification, generation);
9
+ };
10
+ return {
11
+ enqueue: (notification) => {
12
+ if (phase !== "active") {
13
+ pending.push(notification);
14
+ return;
15
+ }
16
+ dispatchActive(notification);
17
+ },
18
+ activate: (activeGeneration) => {
19
+ if (phase !== "buffering")
20
+ return;
21
+ generation = activeGeneration;
22
+ phase = "draining";
23
+ for (let index = 0; index < pending.length; index += 1) {
24
+ dispatchActive(pending[index]);
25
+ }
26
+ pending.length = 0;
27
+ phase = "active";
28
+ },
29
+ };
30
+ };
31
+ //# sourceMappingURL=gateway-notification-queue.js.map