@tanstack/ai-client 0.18.4 → 0.18.5
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/package.json +3 -3
- package/dist/esm/chat-client.d.ts +0 -264
- package/dist/esm/chat-client.js +0 -1097
- package/dist/esm/chat-client.js.map +0 -1
- package/dist/esm/client-persistor.d.ts +0 -86
- package/dist/esm/client-persistor.js +0 -243
- package/dist/esm/client-persistor.js.map +0 -1
- package/dist/esm/connection-adapters.d.ts +0 -203
- package/dist/esm/connection-adapters.js +0 -611
- package/dist/esm/connection-adapters.js.map +0 -1
- package/dist/esm/devtools-noop.d.ts +0 -63
- package/dist/esm/devtools-noop.js +0 -141
- package/dist/esm/devtools-noop.js.map +0 -1
- package/dist/esm/devtools.d.ts +0 -276
- package/dist/esm/devtools.js +0 -1178
- package/dist/esm/devtools.js.map +0 -1
- package/dist/esm/events.d.ts +0 -129
- package/dist/esm/events.js +0 -227
- package/dist/esm/events.js.map +0 -1
- package/dist/esm/generation-client.d.ts +0 -99
- package/dist/esm/generation-client.js +0 -325
- package/dist/esm/generation-client.js.map +0 -1
- package/dist/esm/generation-types.d.ts +0 -242
- package/dist/esm/generation-types.js +0 -14
- package/dist/esm/generation-types.js.map +0 -1
- package/dist/esm/index.d.ts +0 -16
- package/dist/esm/index.js +0 -44
- package/dist/esm/index.js.map +0 -1
- package/dist/esm/realtime-client.d.ts +0 -98
- package/dist/esm/realtime-client.js +0 -403
- package/dist/esm/realtime-client.js.map +0 -1
- package/dist/esm/realtime-types.d.ts +0 -78
- package/dist/esm/response-stream.d.ts +0 -7
- package/dist/esm/response-stream.js +0 -32
- package/dist/esm/response-stream.js.map +0 -1
- package/dist/esm/sse-parser.d.ts +0 -8
- package/dist/esm/sse-parser.js +0 -52
- package/dist/esm/sse-parser.js.map +0 -1
- package/dist/esm/sse-utils.d.ts +0 -1
- package/dist/esm/sse-utils.js +0 -11
- package/dist/esm/sse-utils.js.map +0 -1
- package/dist/esm/tool-types.d.ts +0 -20
- package/dist/esm/types.d.ts +0 -419
- package/dist/esm/types.js +0 -11
- package/dist/esm/types.js.map +0 -1
- package/dist/esm/video-generation-client.d.ts +0 -110
- package/dist/esm/video-generation-client.js +0 -382
- package/dist/esm/video-generation-client.js.map +0 -1
|
@@ -1,611 +0,0 @@
|
|
|
1
|
-
import { EventType, uiMessagesToWire } from "@tanstack/ai/client";
|
|
2
|
-
import { getResponseStreamReader, createResponseStreamTextDecoder } from "./response-stream.js";
|
|
3
|
-
import { parseSseDataLine } from "./sse-utils.js";
|
|
4
|
-
const chunkRunIds = /* @__PURE__ */ new WeakMap();
|
|
5
|
-
function getChunkRunId(chunk) {
|
|
6
|
-
return "runId" in chunk && typeof chunk.runId === "string" ? chunk.runId : chunkRunIds.get(chunk);
|
|
7
|
-
}
|
|
8
|
-
class StreamTruncatedError extends Error {
|
|
9
|
-
constructor() {
|
|
10
|
-
super(
|
|
11
|
-
"Stream ended with unterminated trailing data — connection was likely cut short."
|
|
12
|
-
);
|
|
13
|
-
this.name = "StreamTruncatedError";
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
function generateRunId(prefix) {
|
|
17
|
-
return `${prefix}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
18
|
-
}
|
|
19
|
-
function requireSyntheticId(value, field) {
|
|
20
|
-
if (!value) {
|
|
21
|
-
throw new Error(
|
|
22
|
-
`Cannot synthesize terminal event: ${field} not supplied via runContext and not observed in the upstream stream.`
|
|
23
|
-
);
|
|
24
|
-
}
|
|
25
|
-
return value;
|
|
26
|
-
}
|
|
27
|
-
function mergeHeaders(customHeaders) {
|
|
28
|
-
if (!customHeaders) {
|
|
29
|
-
return {};
|
|
30
|
-
}
|
|
31
|
-
if (customHeaders instanceof Headers) {
|
|
32
|
-
const result = {};
|
|
33
|
-
customHeaders.forEach((value, key) => {
|
|
34
|
-
result[key] = value;
|
|
35
|
-
});
|
|
36
|
-
return result;
|
|
37
|
-
}
|
|
38
|
-
return customHeaders;
|
|
39
|
-
}
|
|
40
|
-
async function* readStreamLines(reader, abortSignal) {
|
|
41
|
-
try {
|
|
42
|
-
const decoder = createResponseStreamTextDecoder();
|
|
43
|
-
let buffer = "";
|
|
44
|
-
while (!abortSignal?.aborted) {
|
|
45
|
-
const { done, value } = await reader.read();
|
|
46
|
-
if (done) break;
|
|
47
|
-
buffer += decoder.decode(value, { stream: true });
|
|
48
|
-
const lines = buffer.split("\n");
|
|
49
|
-
buffer = lines.pop() || "";
|
|
50
|
-
for (const line of lines) {
|
|
51
|
-
if (line.trim()) {
|
|
52
|
-
yield line;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
if (buffer.trim() && !abortSignal?.aborted) {
|
|
57
|
-
throw new StreamTruncatedError();
|
|
58
|
-
}
|
|
59
|
-
} finally {
|
|
60
|
-
reader.releaseLock();
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
async function* responseToSSEChunks(response, abortSignal) {
|
|
64
|
-
if (!response.ok) {
|
|
65
|
-
throw new Error(
|
|
66
|
-
`HTTP error! status: ${response.status} ${response.statusText}`
|
|
67
|
-
);
|
|
68
|
-
}
|
|
69
|
-
const reader = getResponseStreamReader(response);
|
|
70
|
-
let lastThreadId;
|
|
71
|
-
let lastRunId;
|
|
72
|
-
let lastModel;
|
|
73
|
-
for await (const line of readStreamLines(reader, abortSignal)) {
|
|
74
|
-
if (line.startsWith(":") || line.startsWith("event:") || line.startsWith("id:") || line.startsWith("retry:")) {
|
|
75
|
-
continue;
|
|
76
|
-
}
|
|
77
|
-
const data = parseSseDataLine(line);
|
|
78
|
-
if (data === "[DONE]") {
|
|
79
|
-
const synthetic = {
|
|
80
|
-
type: EventType.RUN_FINISHED,
|
|
81
|
-
threadId: lastThreadId ?? "",
|
|
82
|
-
runId: lastRunId ?? "",
|
|
83
|
-
model: lastModel ?? "",
|
|
84
|
-
timestamp: Date.now(),
|
|
85
|
-
finishReason: "stop"
|
|
86
|
-
};
|
|
87
|
-
yield synthetic;
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
const chunk = JSON.parse(data);
|
|
91
|
-
if ("threadId" in chunk && typeof chunk.threadId === "string") {
|
|
92
|
-
lastThreadId = chunk.threadId;
|
|
93
|
-
}
|
|
94
|
-
if ("runId" in chunk && typeof chunk.runId === "string") {
|
|
95
|
-
lastRunId = chunk.runId;
|
|
96
|
-
}
|
|
97
|
-
if ("model" in chunk && typeof chunk.model === "string") {
|
|
98
|
-
lastModel = chunk.model;
|
|
99
|
-
}
|
|
100
|
-
yield chunk;
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
function normalizeConnectionAdapter(connection) {
|
|
104
|
-
if (!connection) {
|
|
105
|
-
throw new Error("Connection adapter is required");
|
|
106
|
-
}
|
|
107
|
-
const hasConnect = "connect" in connection;
|
|
108
|
-
const hasSubscribe = "subscribe" in connection;
|
|
109
|
-
const hasSend = "send" in connection;
|
|
110
|
-
if (hasConnect && (hasSubscribe || hasSend)) {
|
|
111
|
-
throw new Error(
|
|
112
|
-
"Connection adapter must provide either connect or both subscribe and send, not both modes"
|
|
113
|
-
);
|
|
114
|
-
}
|
|
115
|
-
if (hasSubscribe && hasSend) {
|
|
116
|
-
return {
|
|
117
|
-
subscribe: connection.subscribe.bind(connection),
|
|
118
|
-
send: connection.send.bind(connection)
|
|
119
|
-
};
|
|
120
|
-
}
|
|
121
|
-
if (!hasConnect) {
|
|
122
|
-
throw new Error(
|
|
123
|
-
"Connection adapter must provide either connect or both subscribe and send"
|
|
124
|
-
);
|
|
125
|
-
}
|
|
126
|
-
let activeBuffer = [];
|
|
127
|
-
let activeWaiters = [];
|
|
128
|
-
function push(chunk, runId) {
|
|
129
|
-
if (runId) {
|
|
130
|
-
chunkRunIds.set(chunk, runId);
|
|
131
|
-
}
|
|
132
|
-
const waiter = activeWaiters.shift();
|
|
133
|
-
if (waiter) {
|
|
134
|
-
waiter(chunk);
|
|
135
|
-
} else {
|
|
136
|
-
activeBuffer.push(chunk);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
return {
|
|
140
|
-
subscribe(abortSignal) {
|
|
141
|
-
const myBuffer = activeBuffer.splice(0);
|
|
142
|
-
const myWaiters = [];
|
|
143
|
-
activeBuffer = myBuffer;
|
|
144
|
-
activeWaiters = myWaiters;
|
|
145
|
-
return (async function* () {
|
|
146
|
-
while (!abortSignal?.aborted) {
|
|
147
|
-
let chunk;
|
|
148
|
-
const buffered = myBuffer.shift();
|
|
149
|
-
if (buffered !== void 0) {
|
|
150
|
-
chunk = buffered;
|
|
151
|
-
} else {
|
|
152
|
-
chunk = await new Promise((resolve) => {
|
|
153
|
-
const onAbort = () => resolve(null);
|
|
154
|
-
myWaiters.push((c) => {
|
|
155
|
-
abortSignal?.removeEventListener("abort", onAbort);
|
|
156
|
-
resolve(c);
|
|
157
|
-
});
|
|
158
|
-
abortSignal?.addEventListener("abort", onAbort, { once: true });
|
|
159
|
-
});
|
|
160
|
-
}
|
|
161
|
-
if (chunk !== null) yield chunk;
|
|
162
|
-
}
|
|
163
|
-
})();
|
|
164
|
-
},
|
|
165
|
-
async send(messages, data, abortSignal, runContext) {
|
|
166
|
-
let hasTerminalEvent = false;
|
|
167
|
-
let upstreamThreadId;
|
|
168
|
-
let upstreamRunId;
|
|
169
|
-
try {
|
|
170
|
-
const stream2 = connection.connect(
|
|
171
|
-
messages,
|
|
172
|
-
data,
|
|
173
|
-
abortSignal,
|
|
174
|
-
runContext
|
|
175
|
-
);
|
|
176
|
-
for await (const chunk of stream2) {
|
|
177
|
-
if ("threadId" in chunk && typeof chunk.threadId === "string") {
|
|
178
|
-
upstreamThreadId = chunk.threadId;
|
|
179
|
-
}
|
|
180
|
-
if ("runId" in chunk && typeof chunk.runId === "string") {
|
|
181
|
-
upstreamRunId = chunk.runId;
|
|
182
|
-
}
|
|
183
|
-
if (chunk.type === "RUN_FINISHED" || chunk.type === "RUN_ERROR") {
|
|
184
|
-
hasTerminalEvent = true;
|
|
185
|
-
}
|
|
186
|
-
push(chunk, runContext?.runId);
|
|
187
|
-
}
|
|
188
|
-
if (!abortSignal?.aborted && !hasTerminalEvent) {
|
|
189
|
-
const synthetic = {
|
|
190
|
-
type: EventType.RUN_FINISHED,
|
|
191
|
-
threadId: requireSyntheticId(
|
|
192
|
-
upstreamThreadId ?? runContext?.threadId,
|
|
193
|
-
"threadId"
|
|
194
|
-
),
|
|
195
|
-
runId: requireSyntheticId(
|
|
196
|
-
upstreamRunId ?? runContext?.runId,
|
|
197
|
-
"runId"
|
|
198
|
-
),
|
|
199
|
-
model: "connect-wrapper",
|
|
200
|
-
timestamp: Date.now(),
|
|
201
|
-
finishReason: "stop"
|
|
202
|
-
};
|
|
203
|
-
push(synthetic);
|
|
204
|
-
}
|
|
205
|
-
} catch (err) {
|
|
206
|
-
if (!abortSignal?.aborted && !hasTerminalEvent) {
|
|
207
|
-
const message = err instanceof Error ? err.message : "Unknown error in connect()";
|
|
208
|
-
const synthetic = {
|
|
209
|
-
type: EventType.RUN_ERROR,
|
|
210
|
-
threadId: requireSyntheticId(
|
|
211
|
-
upstreamThreadId ?? runContext?.threadId,
|
|
212
|
-
"threadId"
|
|
213
|
-
),
|
|
214
|
-
runId: requireSyntheticId(
|
|
215
|
-
upstreamRunId ?? runContext?.runId,
|
|
216
|
-
"runId"
|
|
217
|
-
),
|
|
218
|
-
timestamp: Date.now(),
|
|
219
|
-
message
|
|
220
|
-
};
|
|
221
|
-
push(synthetic);
|
|
222
|
-
}
|
|
223
|
-
throw err;
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
};
|
|
227
|
-
}
|
|
228
|
-
function buildRunAgentInputBody(messages, data, runContext, options) {
|
|
229
|
-
const wireMessages = uiMessagesToWire(messages);
|
|
230
|
-
const forwardedProps = {
|
|
231
|
-
...options.body,
|
|
232
|
-
...runContext?.forwardedProps ?? {},
|
|
233
|
-
...data
|
|
234
|
-
};
|
|
235
|
-
return {
|
|
236
|
-
threadId: runContext?.threadId ?? generateRunId("thread"),
|
|
237
|
-
runId: runContext?.runId ?? generateRunId("run"),
|
|
238
|
-
...runContext?.parentRunId !== void 0 && {
|
|
239
|
-
parentRunId: runContext.parentRunId
|
|
240
|
-
},
|
|
241
|
-
state: {},
|
|
242
|
-
messages: wireMessages,
|
|
243
|
-
tools: runContext?.clientTools ?? [],
|
|
244
|
-
context: [],
|
|
245
|
-
forwardedProps,
|
|
246
|
-
// Backward-compat mirror of `forwardedProps` under the legacy field name.
|
|
247
|
-
data: { ...forwardedProps }
|
|
248
|
-
};
|
|
249
|
-
}
|
|
250
|
-
function fetchServerSentEvents(url, options = {}) {
|
|
251
|
-
return {
|
|
252
|
-
async *connect(messages, data, abortSignal, runContext) {
|
|
253
|
-
const resolvedUrl = typeof url === "function" ? url() : url;
|
|
254
|
-
const resolvedOptions = typeof options === "function" ? await options() : options;
|
|
255
|
-
const requestHeaders = {
|
|
256
|
-
"Content-Type": "application/json",
|
|
257
|
-
...mergeHeaders(resolvedOptions.headers)
|
|
258
|
-
};
|
|
259
|
-
const requestBody = buildRunAgentInputBody(
|
|
260
|
-
messages,
|
|
261
|
-
data,
|
|
262
|
-
runContext,
|
|
263
|
-
resolvedOptions
|
|
264
|
-
);
|
|
265
|
-
const fetchClient = resolvedOptions.fetchClient ?? fetch;
|
|
266
|
-
const signal = abortSignal || resolvedOptions.signal;
|
|
267
|
-
const response = await fetchClient(resolvedUrl, {
|
|
268
|
-
method: "POST",
|
|
269
|
-
headers: requestHeaders,
|
|
270
|
-
body: JSON.stringify(requestBody),
|
|
271
|
-
credentials: resolvedOptions.credentials || "same-origin",
|
|
272
|
-
...signal ? { signal } : {}
|
|
273
|
-
});
|
|
274
|
-
yield* responseToSSEChunks(response, abortSignal);
|
|
275
|
-
}
|
|
276
|
-
};
|
|
277
|
-
}
|
|
278
|
-
function fetchHttpStream(url, options = {}) {
|
|
279
|
-
return {
|
|
280
|
-
async *connect(messages, data, abortSignal, runContext) {
|
|
281
|
-
const resolvedUrl = typeof url === "function" ? url() : url;
|
|
282
|
-
const resolvedOptions = typeof options === "function" ? await options() : options;
|
|
283
|
-
const requestHeaders = {
|
|
284
|
-
"Content-Type": "application/json",
|
|
285
|
-
...mergeHeaders(resolvedOptions.headers)
|
|
286
|
-
};
|
|
287
|
-
const requestBody = buildRunAgentInputBody(
|
|
288
|
-
messages,
|
|
289
|
-
data,
|
|
290
|
-
runContext,
|
|
291
|
-
resolvedOptions
|
|
292
|
-
);
|
|
293
|
-
const fetchClient = resolvedOptions.fetchClient ?? fetch;
|
|
294
|
-
const signal = abortSignal || resolvedOptions.signal;
|
|
295
|
-
const response = await fetchClient(resolvedUrl, {
|
|
296
|
-
method: "POST",
|
|
297
|
-
headers: requestHeaders,
|
|
298
|
-
body: JSON.stringify(requestBody),
|
|
299
|
-
credentials: resolvedOptions.credentials || "same-origin",
|
|
300
|
-
...signal ? { signal } : {}
|
|
301
|
-
});
|
|
302
|
-
if (!response.ok) {
|
|
303
|
-
throw new Error(
|
|
304
|
-
`HTTP error! status: ${response.status} ${response.statusText}`
|
|
305
|
-
);
|
|
306
|
-
}
|
|
307
|
-
const reader = getResponseStreamReader(response);
|
|
308
|
-
for await (const line of readStreamLines(reader, abortSignal)) {
|
|
309
|
-
yield JSON.parse(line);
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
};
|
|
313
|
-
}
|
|
314
|
-
function createDefaultXMLHttpRequest() {
|
|
315
|
-
if (typeof globalThis.XMLHttpRequest !== "function") {
|
|
316
|
-
throw new Error("XMLHttpRequest is not available in this runtime");
|
|
317
|
-
}
|
|
318
|
-
return new globalThis.XMLHttpRequest();
|
|
319
|
-
}
|
|
320
|
-
function cleanupXhr(xhr, abortSignal, onAbort) {
|
|
321
|
-
xhr.onprogress = null;
|
|
322
|
-
xhr.onload = null;
|
|
323
|
-
xhr.onerror = null;
|
|
324
|
-
xhr.onabort = null;
|
|
325
|
-
xhr.onloadend = null;
|
|
326
|
-
if (abortSignal && onAbort) {
|
|
327
|
-
abortSignal.removeEventListener("abort", onAbort);
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
function readXhrLines(xhr, abortSignal) {
|
|
331
|
-
let offset = 0;
|
|
332
|
-
let buffer = "";
|
|
333
|
-
const lines = [];
|
|
334
|
-
const waiters = [];
|
|
335
|
-
let done = false;
|
|
336
|
-
let aborted = false;
|
|
337
|
-
let error;
|
|
338
|
-
let onAbort;
|
|
339
|
-
const wake = () => {
|
|
340
|
-
const waiter = waiters.shift();
|
|
341
|
-
waiter?.();
|
|
342
|
-
};
|
|
343
|
-
const enqueueDelta = () => {
|
|
344
|
-
if (xhr.status !== 0 && (xhr.status < 200 || xhr.status >= 300)) {
|
|
345
|
-
error = new Error(`XHR error! status: ${xhr.status} ${xhr.statusText}`);
|
|
346
|
-
done = true;
|
|
347
|
-
return;
|
|
348
|
-
}
|
|
349
|
-
const responseText = xhr.responseText;
|
|
350
|
-
if (responseText.length <= offset) {
|
|
351
|
-
return;
|
|
352
|
-
}
|
|
353
|
-
buffer += responseText.slice(offset);
|
|
354
|
-
offset = responseText.length;
|
|
355
|
-
const splitLines = buffer.split("\n");
|
|
356
|
-
buffer = splitLines.pop() ?? "";
|
|
357
|
-
for (const line of splitLines) {
|
|
358
|
-
const normalized = line.endsWith("\r") ? line.slice(0, -1) : line;
|
|
359
|
-
if (normalized.trim()) {
|
|
360
|
-
lines.push(normalized);
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
};
|
|
364
|
-
const finish = () => {
|
|
365
|
-
enqueueDelta();
|
|
366
|
-
if (xhr.status < 200 || xhr.status >= 300) {
|
|
367
|
-
error = new Error(`XHR error! status: ${xhr.status} ${xhr.statusText}`);
|
|
368
|
-
} else if (buffer.trim() && !aborted) {
|
|
369
|
-
error = new StreamTruncatedError();
|
|
370
|
-
}
|
|
371
|
-
done = true;
|
|
372
|
-
wake();
|
|
373
|
-
};
|
|
374
|
-
xhr.onprogress = () => {
|
|
375
|
-
enqueueDelta();
|
|
376
|
-
wake();
|
|
377
|
-
};
|
|
378
|
-
xhr.onload = finish;
|
|
379
|
-
xhr.onerror = () => {
|
|
380
|
-
error = new Error("XHR request failed");
|
|
381
|
-
done = true;
|
|
382
|
-
wake();
|
|
383
|
-
};
|
|
384
|
-
xhr.onabort = () => {
|
|
385
|
-
aborted = true;
|
|
386
|
-
done = true;
|
|
387
|
-
wake();
|
|
388
|
-
};
|
|
389
|
-
xhr.onloadend = () => {
|
|
390
|
-
if (!done) {
|
|
391
|
-
finish();
|
|
392
|
-
}
|
|
393
|
-
};
|
|
394
|
-
if (abortSignal) {
|
|
395
|
-
onAbort = () => {
|
|
396
|
-
aborted = true;
|
|
397
|
-
xhr.abort();
|
|
398
|
-
};
|
|
399
|
-
if (abortSignal.aborted) {
|
|
400
|
-
onAbort();
|
|
401
|
-
} else {
|
|
402
|
-
abortSignal.addEventListener("abort", onAbort, { once: true });
|
|
403
|
-
}
|
|
404
|
-
}
|
|
405
|
-
return (async function* () {
|
|
406
|
-
try {
|
|
407
|
-
while (true) {
|
|
408
|
-
const line = lines.shift();
|
|
409
|
-
if (line !== void 0) {
|
|
410
|
-
yield line;
|
|
411
|
-
continue;
|
|
412
|
-
}
|
|
413
|
-
if (error) {
|
|
414
|
-
throw error;
|
|
415
|
-
}
|
|
416
|
-
if (done || abortSignal?.aborted) {
|
|
417
|
-
return;
|
|
418
|
-
}
|
|
419
|
-
await new Promise((resolve) => {
|
|
420
|
-
waiters.push(resolve);
|
|
421
|
-
});
|
|
422
|
-
}
|
|
423
|
-
} finally {
|
|
424
|
-
cleanupXhr(xhr, abortSignal, onAbort);
|
|
425
|
-
}
|
|
426
|
-
})();
|
|
427
|
-
}
|
|
428
|
-
function createConfiguredXhrRequest(url, options, messages, data, runContext) {
|
|
429
|
-
const xhr = options.xhrFactory?.() ?? createDefaultXMLHttpRequest();
|
|
430
|
-
xhr.open("POST", url);
|
|
431
|
-
if (options.withCredentials !== void 0) {
|
|
432
|
-
xhr.withCredentials = options.withCredentials;
|
|
433
|
-
}
|
|
434
|
-
const requestHeaders = {
|
|
435
|
-
"Content-Type": "application/json",
|
|
436
|
-
...mergeHeaders(options.headers)
|
|
437
|
-
};
|
|
438
|
-
for (const [name, value] of Object.entries(requestHeaders)) {
|
|
439
|
-
xhr.setRequestHeader(name, value);
|
|
440
|
-
}
|
|
441
|
-
const requestBody = buildRunAgentInputBody(
|
|
442
|
-
messages,
|
|
443
|
-
data,
|
|
444
|
-
runContext,
|
|
445
|
-
options
|
|
446
|
-
);
|
|
447
|
-
return { xhr, body: JSON.stringify(requestBody) };
|
|
448
|
-
}
|
|
449
|
-
async function resolveXhrConnectionOptions(options) {
|
|
450
|
-
return typeof options === "function" ? await options() : options;
|
|
451
|
-
}
|
|
452
|
-
function xhrServerSentEvents(url, options = {}) {
|
|
453
|
-
return {
|
|
454
|
-
async *connect(messages, data, abortSignal, runContext) {
|
|
455
|
-
const resolvedUrl = typeof url === "function" ? url() : url;
|
|
456
|
-
const resolvedOptions = await resolveXhrConnectionOptions(options);
|
|
457
|
-
const signal = abortSignal || resolvedOptions.signal;
|
|
458
|
-
const request = createConfiguredXhrRequest(
|
|
459
|
-
resolvedUrl,
|
|
460
|
-
resolvedOptions,
|
|
461
|
-
messages,
|
|
462
|
-
data,
|
|
463
|
-
runContext
|
|
464
|
-
);
|
|
465
|
-
const lines = readXhrLines(request.xhr, signal);
|
|
466
|
-
if (signal?.aborted) {
|
|
467
|
-
await lines.next();
|
|
468
|
-
return;
|
|
469
|
-
}
|
|
470
|
-
request.xhr.send(request.body);
|
|
471
|
-
let lastThreadId;
|
|
472
|
-
let lastRunId;
|
|
473
|
-
let lastModel;
|
|
474
|
-
for await (const line of lines) {
|
|
475
|
-
if (line.startsWith(":") || line.startsWith("event:") || line.startsWith("id:") || line.startsWith("retry:")) {
|
|
476
|
-
continue;
|
|
477
|
-
}
|
|
478
|
-
const chunkData = parseSseDataLine(line);
|
|
479
|
-
if (chunkData === "[DONE]") {
|
|
480
|
-
const synthetic = {
|
|
481
|
-
type: EventType.RUN_FINISHED,
|
|
482
|
-
threadId: lastThreadId ?? runContext?.threadId ?? "",
|
|
483
|
-
runId: lastRunId ?? runContext?.runId ?? "",
|
|
484
|
-
model: lastModel ?? "",
|
|
485
|
-
timestamp: Date.now(),
|
|
486
|
-
finishReason: "stop"
|
|
487
|
-
};
|
|
488
|
-
request.xhr.abort();
|
|
489
|
-
yield synthetic;
|
|
490
|
-
return;
|
|
491
|
-
}
|
|
492
|
-
const chunk = JSON.parse(chunkData);
|
|
493
|
-
if ("threadId" in chunk && typeof chunk.threadId === "string") {
|
|
494
|
-
lastThreadId = chunk.threadId;
|
|
495
|
-
}
|
|
496
|
-
if ("runId" in chunk && typeof chunk.runId === "string") {
|
|
497
|
-
lastRunId = chunk.runId;
|
|
498
|
-
}
|
|
499
|
-
if ("model" in chunk && typeof chunk.model === "string") {
|
|
500
|
-
lastModel = chunk.model;
|
|
501
|
-
}
|
|
502
|
-
yield chunk;
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
|
-
};
|
|
506
|
-
}
|
|
507
|
-
function xhrHttpStream(url, options = {}) {
|
|
508
|
-
return {
|
|
509
|
-
async *connect(messages, data, abortSignal, runContext) {
|
|
510
|
-
const resolvedUrl = typeof url === "function" ? url() : url;
|
|
511
|
-
const resolvedOptions = await resolveXhrConnectionOptions(options);
|
|
512
|
-
const signal = abortSignal || resolvedOptions.signal;
|
|
513
|
-
const request = createConfiguredXhrRequest(
|
|
514
|
-
resolvedUrl,
|
|
515
|
-
resolvedOptions,
|
|
516
|
-
messages,
|
|
517
|
-
data,
|
|
518
|
-
runContext
|
|
519
|
-
);
|
|
520
|
-
const lines = readXhrLines(request.xhr, signal);
|
|
521
|
-
if (signal?.aborted) {
|
|
522
|
-
await lines.next();
|
|
523
|
-
return;
|
|
524
|
-
}
|
|
525
|
-
request.xhr.send(request.body);
|
|
526
|
-
for await (const line of lines) {
|
|
527
|
-
yield JSON.parse(line);
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
};
|
|
531
|
-
}
|
|
532
|
-
function stream(streamFactory) {
|
|
533
|
-
return {
|
|
534
|
-
async *connect(messages, data, abortSignal) {
|
|
535
|
-
yield* streamFactory(messages, data, abortSignal);
|
|
536
|
-
}
|
|
537
|
-
};
|
|
538
|
-
}
|
|
539
|
-
function fetcherToConnectionAdapter(fetcher) {
|
|
540
|
-
return {
|
|
541
|
-
async *connect(messages, data, abortSignal, runContext) {
|
|
542
|
-
if (!abortSignal) {
|
|
543
|
-
throw new Error(
|
|
544
|
-
"fetcherToConnectionAdapter requires an AbortSignal — the chat client always supplies one."
|
|
545
|
-
);
|
|
546
|
-
}
|
|
547
|
-
if (!runContext) {
|
|
548
|
-
throw new Error(
|
|
549
|
-
"fetcherToConnectionAdapter requires a RunAgentInputContext — the chat client always supplies one."
|
|
550
|
-
);
|
|
551
|
-
}
|
|
552
|
-
const uiMessages = messages;
|
|
553
|
-
const result = await fetcher(
|
|
554
|
-
{
|
|
555
|
-
messages: uiMessages,
|
|
556
|
-
data,
|
|
557
|
-
threadId: runContext.threadId,
|
|
558
|
-
runId: runContext.runId
|
|
559
|
-
},
|
|
560
|
-
{ signal: abortSignal }
|
|
561
|
-
);
|
|
562
|
-
if (result instanceof Response) {
|
|
563
|
-
yield* responseToSSEChunks(result, abortSignal);
|
|
564
|
-
} else {
|
|
565
|
-
yield* abortableIterable(result, abortSignal);
|
|
566
|
-
}
|
|
567
|
-
}
|
|
568
|
-
};
|
|
569
|
-
}
|
|
570
|
-
async function* abortableIterable(iterable, signal) {
|
|
571
|
-
if (signal.aborted) return;
|
|
572
|
-
const iterator = iterable[Symbol.asyncIterator]();
|
|
573
|
-
const abortPromise = new Promise(
|
|
574
|
-
(resolve) => {
|
|
575
|
-
signal.addEventListener(
|
|
576
|
-
"abort",
|
|
577
|
-
() => resolve({ done: true, value: void 0 }),
|
|
578
|
-
{ once: true }
|
|
579
|
-
);
|
|
580
|
-
}
|
|
581
|
-
);
|
|
582
|
-
try {
|
|
583
|
-
while (true) {
|
|
584
|
-
const result = await Promise.race([iterator.next(), abortPromise]);
|
|
585
|
-
if (result.done) return;
|
|
586
|
-
yield result.value;
|
|
587
|
-
}
|
|
588
|
-
} finally {
|
|
589
|
-
await iterator.return?.();
|
|
590
|
-
}
|
|
591
|
-
}
|
|
592
|
-
function rpcStream(rpcCall) {
|
|
593
|
-
return {
|
|
594
|
-
async *connect(messages, data, abortSignal) {
|
|
595
|
-
yield* rpcCall(messages, data, abortSignal);
|
|
596
|
-
}
|
|
597
|
-
};
|
|
598
|
-
}
|
|
599
|
-
export {
|
|
600
|
-
StreamTruncatedError,
|
|
601
|
-
fetchHttpStream,
|
|
602
|
-
fetchServerSentEvents,
|
|
603
|
-
fetcherToConnectionAdapter,
|
|
604
|
-
getChunkRunId,
|
|
605
|
-
normalizeConnectionAdapter,
|
|
606
|
-
rpcStream,
|
|
607
|
-
stream,
|
|
608
|
-
xhrHttpStream,
|
|
609
|
-
xhrServerSentEvents
|
|
610
|
-
};
|
|
611
|
-
//# sourceMappingURL=connection-adapters.js.map
|