@tanstack/ai-client 0.29.0 → 0.29.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/chat-client.d.ts +6 -0
- package/dist/esm/chat-client.js +28 -4
- package/dist/esm/chat-client.js.map +1 -1
- package/dist/esm/connection-adapters.js +15 -0
- package/dist/esm/connection-adapters.js.map +1 -1
- package/dist/esm/devtools-noop.d.ts +3 -0
- package/dist/esm/devtools-noop.js +3 -0
- package/dist/esm/devtools-noop.js.map +1 -1
- package/dist/esm/devtools.d.ts +15 -1
- package/dist/esm/devtools.js +149 -10
- package/dist/esm/devtools.js.map +1 -1
- package/package.json +3 -3
- package/src/chat-client.ts +50 -8
- package/src/connection-adapters.ts +23 -0
- package/src/devtools-noop.ts +3 -0
- package/src/devtools.ts +280 -12
|
@@ -123,6 +123,12 @@ export declare class ChatClient<TTools extends ReadonlyArray<AnyClientTool> = an
|
|
|
123
123
|
private continuationPending;
|
|
124
124
|
private subscriptionAbortController;
|
|
125
125
|
private processingResolve;
|
|
126
|
+
/**
|
|
127
|
+
* `connect()` adapters push the full HTTP body into the subscribe queue, then
|
|
128
|
+
* wait until that queue is idle. After `send()` returns, every chunk from this
|
|
129
|
+
* request has been processed. Subscribe/send sockets do not drain that way.
|
|
130
|
+
*/
|
|
131
|
+
private connectionDrainsOnSend;
|
|
126
132
|
private errorReportedGeneration;
|
|
127
133
|
private streamGeneration;
|
|
128
134
|
private continuationGeneration;
|
package/dist/esm/chat-client.js
CHANGED
|
@@ -22,6 +22,16 @@ function resolveTransport(transport) {
|
|
|
22
22
|
if (fetcher) return fetcherToConnectionAdapter(fetcher);
|
|
23
23
|
throw new Error("ChatClient: either `connection` or `fetcher` is required.");
|
|
24
24
|
}
|
|
25
|
+
function connectionDrainsOnSend(connection) {
|
|
26
|
+
return "connect" in connection;
|
|
27
|
+
}
|
|
28
|
+
function isIntermediateToolTurn(chunk) {
|
|
29
|
+
if (chunk.type !== "RUN_FINISHED") return false;
|
|
30
|
+
if (chunk.outcome?.type === "interrupt") return false;
|
|
31
|
+
const extra = chunk;
|
|
32
|
+
if (extra.finishReason !== void 0) return extra.finishReason === "tool_calls";
|
|
33
|
+
return tanstackMetadata(chunk)?.finishReason === "tool_calls";
|
|
34
|
+
}
|
|
25
35
|
function normalizeQueueOption(option) {
|
|
26
36
|
const base = {
|
|
27
37
|
whenBusy: "queue",
|
|
@@ -204,6 +214,12 @@ var ChatClient = class {
|
|
|
204
214
|
continuationPending = false;
|
|
205
215
|
subscriptionAbortController = null;
|
|
206
216
|
processingResolve = null;
|
|
217
|
+
/**
|
|
218
|
+
* `connect()` adapters push the full HTTP body into the subscribe queue, then
|
|
219
|
+
* wait until that queue is idle. After `send()` returns, every chunk from this
|
|
220
|
+
* request has been processed. Subscribe/send sockets do not drain that way.
|
|
221
|
+
*/
|
|
222
|
+
connectionDrainsOnSend = false;
|
|
207
223
|
errorReportedGeneration = null;
|
|
208
224
|
streamGeneration = 0;
|
|
209
225
|
continuationGeneration = 0;
|
|
@@ -239,7 +255,9 @@ var ChatClient = class {
|
|
|
239
255
|
this.byokProvider = options.byokProvider;
|
|
240
256
|
this.context = options.context;
|
|
241
257
|
this.queueConfig = normalizeQueueOption(options.queue);
|
|
242
|
-
|
|
258
|
+
const transport = resolveTransport(options);
|
|
259
|
+
this.connectionDrainsOnSend = connectionDrainsOnSend(transport);
|
|
260
|
+
this.connection = normalizeConnectionAdapter(transport);
|
|
243
261
|
this.clientToolsRef = { current: /* @__PURE__ */ new Map() };
|
|
244
262
|
if (options.tools) for (const tool of options.tools) this.clientToolsRef.current.set(tool.name, tool);
|
|
245
263
|
this.devtoolsBridge = (options.devtoolsBridgeFactory ?? createNoOpChatDevtoolsBridge)(this.buildDevtoolsBridgeOptions(options.devtools));
|
|
@@ -374,6 +392,8 @@ var ChatClient = class {
|
|
|
374
392
|
},
|
|
375
393
|
onCustomEvent: (eventType, data, context) => {
|
|
376
394
|
if (eventType === "memory:state") this.devtoolsBridge.recordMemoryState(data);
|
|
395
|
+
if (eventType === "compaction:started" || eventType === "compaction:state" || eventType === "compaction:ended") this.devtoolsBridge.recordCompactionEvent(eventType, data);
|
|
396
|
+
if (eventType === "skills:state") this.devtoolsBridge.recordSkillsState(data);
|
|
377
397
|
this.callbacksRef.current.onCustomEvent(eventType, data, context);
|
|
378
398
|
}
|
|
379
399
|
}
|
|
@@ -562,7 +582,8 @@ var ChatClient = class {
|
|
|
562
582
|
this.clearedStreamTracker.onSessionRunError();
|
|
563
583
|
}
|
|
564
584
|
this.setSessionGenerating(this.activeRunIds.size > 0);
|
|
565
|
-
|
|
585
|
+
const skipProcessingResolve = chunk.type === "RUN_FINISHED" && isIntermediateToolTurn(chunk);
|
|
586
|
+
if (options?.resolveProcessing !== false && !skipProcessingResolve) this.resolveProcessing();
|
|
566
587
|
}
|
|
567
588
|
/**
|
|
568
589
|
* Track interrupt state off the stream's terminal events. A RUN_FINISHED with
|
|
@@ -1302,6 +1323,7 @@ var ChatClient = class {
|
|
|
1302
1323
|
this.devtoolsBridge.emitSnapshot();
|
|
1303
1324
|
await this.connection.send(messages, mergedBody, signal, runContext);
|
|
1304
1325
|
if (generation !== this.streamGeneration || signal.aborted) return false;
|
|
1326
|
+
if (this.connectionDrainsOnSend) this.resolveProcessing();
|
|
1305
1327
|
await processingComplete;
|
|
1306
1328
|
if (generation !== this.streamGeneration) return false;
|
|
1307
1329
|
if (this.status === "error") {
|
|
@@ -1710,10 +1732,12 @@ var ChatClient = class {
|
|
|
1710
1732
|
this.resetSessionGenerating();
|
|
1711
1733
|
this.setIsSubscribed(false);
|
|
1712
1734
|
this.setConnectionStatus("disconnected");
|
|
1713
|
-
|
|
1735
|
+
const transport = resolveTransport({
|
|
1714
1736
|
connection: options.connection,
|
|
1715
1737
|
fetcher: options.fetcher
|
|
1716
|
-
})
|
|
1738
|
+
});
|
|
1739
|
+
this.connectionDrainsOnSend = connectionDrainsOnSend(transport);
|
|
1740
|
+
this.connection = normalizeConnectionAdapter(transport);
|
|
1717
1741
|
if (wasSubscribed) this.subscribe();
|
|
1718
1742
|
}
|
|
1719
1743
|
if (options.body !== void 0) this.bodyOption = options.body;
|