@tanstack/ai-client 0.31.1 → 0.32.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/README.md +42 -16
- package/dist/esm/byok/client.d.ts +5 -0
- package/dist/esm/byok/client.js +19 -2
- package/dist/esm/byok/client.js.map +1 -1
- package/dist/esm/chat-client.d.ts +31 -0
- package/dist/esm/chat-client.js +137 -10
- package/dist/esm/chat-client.js.map +1 -1
- package/dist/esm/connection-adapters.d.ts +25 -4
- package/dist/esm/connection-adapters.js +31 -12
- package/dist/esm/connection-adapters.js.map +1 -1
- package/dist/esm/generation-client.js +2 -1
- package/dist/esm/generation-client.js.map +1 -1
- package/dist/esm/types.d.ts +9 -0
- package/dist/esm/types.js.map +1 -1
- package/dist/esm/video-generation-client.js +2 -1
- package/dist/esm/video-generation-client.js.map +1 -1
- package/package.json +2 -2
- package/src/byok/client.ts +23 -2
- package/src/chat-client.ts +209 -8
- package/src/connection-adapters.ts +92 -14
- package/src/generation-client.ts +2 -0
- package/src/types.ts +9 -0
- package/src/video-generation-client.ts +2 -0
|
@@ -130,7 +130,7 @@ export interface ConnectConnectionAdapter {
|
|
|
130
130
|
* `fetchServerSentEvents` / `fetchHttpStream`, and on `stream()` /
|
|
131
131
|
* `rpcStream()` when supplied via {@link StreamConnectionHandlers}.
|
|
132
132
|
*/
|
|
133
|
-
hydrate?: (threadId: string) => Promise<ChatHydrationResult>;
|
|
133
|
+
hydrate?: (threadId: string, options?: ChatHydrateOptions) => Promise<ChatHydrationResult>;
|
|
134
134
|
}
|
|
135
135
|
/**
|
|
136
136
|
* Server-resolved hydration for a generation thread. `resumeSnapshot` is the
|
|
@@ -166,11 +166,22 @@ export interface GenerationHydrationResult {
|
|
|
166
166
|
runId: string;
|
|
167
167
|
} | null;
|
|
168
168
|
}
|
|
169
|
+
/**
|
|
170
|
+
* Optional paging for a chat hydrate GET.
|
|
171
|
+
* Omit both fields to load the full thread.
|
|
172
|
+
*/
|
|
173
|
+
export interface ChatHydrateOptions {
|
|
174
|
+
limit?: number;
|
|
175
|
+
before?: string;
|
|
176
|
+
}
|
|
169
177
|
/**
|
|
170
178
|
* Server-resolved hydration for a thread. `messages` is the stored transcript;
|
|
171
179
|
* `activeRun` is a cursor to a run still generating for the thread (or `null`).
|
|
172
180
|
* Keyed on the STABLE thread id — the client never handles a run id, so a turn
|
|
173
181
|
* that spans several runs (interrupt/tool continuations) reconnects correctly.
|
|
182
|
+
*
|
|
183
|
+
* `page` is additive. Old servers omit it; treat that as a full list
|
|
184
|
+
* (`truncated: false`).
|
|
174
185
|
*/
|
|
175
186
|
export interface ChatHydrationResult {
|
|
176
187
|
messages: Array<UIMessage>;
|
|
@@ -186,6 +197,16 @@ export interface ChatHydrationResult {
|
|
|
186
197
|
runId: string;
|
|
187
198
|
pending: Array<ChatPendingInterrupt>;
|
|
188
199
|
} | null;
|
|
200
|
+
/**
|
|
201
|
+
* Whether this window is a slice of a longer thread.
|
|
202
|
+
* `cursor` is set when `truncated` is true and is sent back as `before`.
|
|
203
|
+
*/
|
|
204
|
+
page?: {
|
|
205
|
+
truncated: false;
|
|
206
|
+
} | {
|
|
207
|
+
truncated: true;
|
|
208
|
+
cursor: string;
|
|
209
|
+
};
|
|
189
210
|
}
|
|
190
211
|
/**
|
|
191
212
|
* A {@link ConnectConnectionAdapter} that also supports joining an existing run
|
|
@@ -205,7 +226,7 @@ export interface ResumableConnectConnectionAdapter extends ConnectConnectionAdap
|
|
|
205
226
|
* JSON GET (`?threadId`), so it is transport-agnostic regardless of how the
|
|
206
227
|
* delivery stream is served.
|
|
207
228
|
*/
|
|
208
|
-
hydrate?: (threadId: string) => Promise<ChatHydrationResult>;
|
|
229
|
+
hydrate?: (threadId: string, options?: ChatHydrateOptions) => Promise<ChatHydrationResult>;
|
|
209
230
|
}
|
|
210
231
|
export interface SubscribeConnectionAdapter {
|
|
211
232
|
/**
|
|
@@ -228,7 +249,7 @@ export interface SubscribeConnectionAdapter {
|
|
|
228
249
|
* cursor). Present only when the underlying connection supports it. The client
|
|
229
250
|
* calls it on mount to re-hydrate without any app-side loader or prop.
|
|
230
251
|
*/
|
|
231
|
-
hydrate?: (threadId: string) => Promise<ChatHydrationResult>;
|
|
252
|
+
hydrate?: (threadId: string, options?: ChatHydrateOptions) => Promise<ChatHydrationResult>;
|
|
232
253
|
}
|
|
233
254
|
/**
|
|
234
255
|
* Connection adapter union.
|
|
@@ -394,7 +415,7 @@ export interface StreamConnectionHandlers {
|
|
|
394
415
|
* Server-driven chat hydration for `persistence: true`: the stored
|
|
395
416
|
* transcript for `threadId` plus a cursor to an in-flight run.
|
|
396
417
|
*/
|
|
397
|
-
hydrate?: (threadId: string) => Promise<ChatHydrationResult>;
|
|
418
|
+
hydrate?: (threadId: string, options?: ChatHydrateOptions) => Promise<ChatHydrationResult>;
|
|
398
419
|
/**
|
|
399
420
|
* Server-driven generation hydration for `persistence: true`: the last
|
|
400
421
|
* generation's resume snapshot for `threadId` plus a cursor to a run still
|
|
@@ -309,15 +309,33 @@ function errorFromXhrStatus(xhr) {
|
|
|
309
309
|
}
|
|
310
310
|
return /* @__PURE__ */ new Error(`XHR error! status: ${xhr.status} ${xhr.statusText}`);
|
|
311
311
|
}
|
|
312
|
+
function chatHydrationSearchParams(threadId, options) {
|
|
313
|
+
const values = { threadId };
|
|
314
|
+
if (options?.limit !== void 0) values.limit = String(options.limit);
|
|
315
|
+
if (options?.before !== void 0) values.before = options.before;
|
|
316
|
+
return values;
|
|
317
|
+
}
|
|
318
|
+
function readChatHydrationPage(value) {
|
|
319
|
+
if (value === null || typeof value !== "object") return { truncated: false };
|
|
320
|
+
if (!("truncated" in value) || value.truncated !== true) return { truncated: false };
|
|
321
|
+
if (!("cursor" in value) || typeof value.cursor !== "string" || value.cursor === "") return { truncated: false };
|
|
322
|
+
return {
|
|
323
|
+
truncated: true,
|
|
324
|
+
cursor: value.cursor
|
|
325
|
+
};
|
|
326
|
+
}
|
|
312
327
|
/**
|
|
313
328
|
* GET the hydration endpoint for a thread and parse its JSON `{ messages,
|
|
314
329
|
* activeRun }` body. This is the transport-agnostic reconnect probe: keyed on
|
|
315
330
|
* the STABLE thread id, it returns the stored transcript and — if a run is still
|
|
316
331
|
* generating — a cursor the caller tails via `joinRun`. Shared by every fetch/
|
|
317
332
|
* XHR adapter so the client never has to know which transport is in use.
|
|
333
|
+
*
|
|
334
|
+
* Pass `limit` / `before` to page. Old servers that omit `page` are treated as
|
|
335
|
+
* a full list (`truncated: false`).
|
|
318
336
|
*/
|
|
319
|
-
async function fetchThreadHydration(fetchClient, url, headers, credentials, threadId) {
|
|
320
|
-
const response = await fetchClient(withSearchParams(url,
|
|
337
|
+
async function fetchThreadHydration(fetchClient, url, headers, credentials, threadId, options) {
|
|
338
|
+
const response = await fetchClient(withSearchParams(url, chatHydrationSearchParams(threadId, options)), {
|
|
321
339
|
method: "GET",
|
|
322
340
|
headers: {
|
|
323
341
|
Accept: "application/json",
|
|
@@ -335,7 +353,8 @@ async function fetchThreadHydration(fetchClient, url, headers, credentials, thre
|
|
|
335
353
|
return {
|
|
336
354
|
messages: Array.isArray(data.messages) ? normalizeMessagesDates(data.messages) : [],
|
|
337
355
|
activeRun,
|
|
338
|
-
interrupts
|
|
356
|
+
interrupts,
|
|
357
|
+
page: readChatHydrationPage(data.page)
|
|
339
358
|
};
|
|
340
359
|
}
|
|
341
360
|
/**
|
|
@@ -559,7 +578,7 @@ function normalizeConnectionAdapter(connection) {
|
|
|
559
578
|
...typeof connection.joinRun === "function" ? { joinRun: (runId, abortSignal) => connection.joinRun(runId, abortSignal) } : {},
|
|
560
579
|
...(() => {
|
|
561
580
|
const hydrate = connection.hydrate;
|
|
562
|
-
return typeof hydrate === "function" ? { hydrate: (threadId) => hydrate(threadId) } : {};
|
|
581
|
+
return typeof hydrate === "function" ? { hydrate: (threadId, options) => hydrate(threadId, options) } : {};
|
|
563
582
|
})()
|
|
564
583
|
};
|
|
565
584
|
}
|
|
@@ -657,10 +676,10 @@ function fetchServerSentEvents(url, options = {}) {
|
|
|
657
676
|
credentials: resolvedOptions.credentials || "same-origin"
|
|
658
677
|
}, (response, sseSignal) => responseToSSEEvents(response, sseSignal, { runId })), signal, resolvedOptions.reconnect);
|
|
659
678
|
},
|
|
660
|
-
async hydrate(threadId) {
|
|
679
|
+
async hydrate(threadId, hydrateOptions) {
|
|
661
680
|
const resolvedUrl = typeof url === "function" ? url() : url;
|
|
662
681
|
const resolvedOptions = typeof options === "function" ? await options() : options;
|
|
663
|
-
return fetchThreadHydration(resolvedOptions.fetchClient ?? fetch, resolvedUrl, mergeHeaders(resolvedOptions.headers), resolvedOptions.credentials || "same-origin", threadId);
|
|
682
|
+
return fetchThreadHydration(resolvedOptions.fetchClient ?? fetch, resolvedUrl, mergeHeaders(resolvedOptions.headers), resolvedOptions.credentials || "same-origin", threadId, hydrateOptions);
|
|
664
683
|
},
|
|
665
684
|
async hydrateGeneration(threadId) {
|
|
666
685
|
const resolvedUrl = typeof url === "function" ? url() : url;
|
|
@@ -740,10 +759,10 @@ function fetchHttpStream(url, options = {}) {
|
|
|
740
759
|
credentials: resolvedOptions.credentials || "same-origin"
|
|
741
760
|
}, responseToNdjsonEvents), signal, resolvedOptions.reconnect);
|
|
742
761
|
},
|
|
743
|
-
async hydrate(threadId) {
|
|
762
|
+
async hydrate(threadId, hydrateOptions) {
|
|
744
763
|
const resolvedUrl = typeof url === "function" ? url() : url;
|
|
745
764
|
const resolvedOptions = typeof options === "function" ? await options() : options;
|
|
746
|
-
return fetchThreadHydration(resolvedOptions.fetchClient ?? fetch, resolvedUrl, mergeHeaders(resolvedOptions.headers), resolvedOptions.credentials || "same-origin", threadId);
|
|
765
|
+
return fetchThreadHydration(resolvedOptions.fetchClient ?? fetch, resolvedUrl, mergeHeaders(resolvedOptions.headers), resolvedOptions.credentials || "same-origin", threadId, hydrateOptions);
|
|
747
766
|
},
|
|
748
767
|
async hydrateGeneration(threadId) {
|
|
749
768
|
const resolvedUrl = typeof url === "function" ? url() : url;
|
|
@@ -921,10 +940,10 @@ function xhrServerSentEvents(url, options = {}) {
|
|
|
921
940
|
runId
|
|
922
941
|
}), resolvedOptions, "GET", [], void 0, void 0, (lines) => linesToSSEEvents(lines, { runId })), signal, resolvedOptions.reconnect);
|
|
923
942
|
},
|
|
924
|
-
async hydrate(threadId) {
|
|
943
|
+
async hydrate(threadId, hydrateOptions) {
|
|
925
944
|
const resolvedUrl = typeof url === "function" ? url() : url;
|
|
926
945
|
const resolvedOptions = await resolveXhrConnectionOptions(options);
|
|
927
|
-
return fetchThreadHydration(fetch, resolvedUrl, mergeHeaders(resolvedOptions.headers), resolvedOptions.withCredentials ? "include" : "same-origin", threadId);
|
|
946
|
+
return fetchThreadHydration(fetch, resolvedUrl, mergeHeaders(resolvedOptions.headers), resolvedOptions.withCredentials ? "include" : "same-origin", threadId, hydrateOptions);
|
|
928
947
|
},
|
|
929
948
|
async hydrateGeneration(threadId) {
|
|
930
949
|
const resolvedUrl = typeof url === "function" ? url() : url;
|
|
@@ -958,10 +977,10 @@ function xhrHttpStream(url, options = {}) {
|
|
|
958
977
|
runId
|
|
959
978
|
}), resolvedOptions, "GET", [], void 0, void 0, linesToNdjsonEvents), signal, resolvedOptions.reconnect);
|
|
960
979
|
},
|
|
961
|
-
async hydrate(threadId) {
|
|
980
|
+
async hydrate(threadId, hydrateOptions) {
|
|
962
981
|
const resolvedUrl = typeof url === "function" ? url() : url;
|
|
963
982
|
const resolvedOptions = await resolveXhrConnectionOptions(options);
|
|
964
|
-
return fetchThreadHydration(fetch, resolvedUrl, mergeHeaders(resolvedOptions.headers), resolvedOptions.withCredentials ? "include" : "same-origin", threadId);
|
|
983
|
+
return fetchThreadHydration(fetch, resolvedUrl, mergeHeaders(resolvedOptions.headers), resolvedOptions.withCredentials ? "include" : "same-origin", threadId, hydrateOptions);
|
|
965
984
|
},
|
|
966
985
|
async hydrateGeneration(threadId) {
|
|
967
986
|
const resolvedUrl = typeof url === "function" ? url() : url;
|