ai 3.1.29 → 3.1.31
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/index.d.mts +4 -563
- package/dist/index.d.ts +4 -563
- package/dist/index.js +38 -509
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +40 -497
- package/dist/index.mjs.map +1 -1
- package/package.json +17 -33
- package/prompts/dist/index.d.mts +2 -129
- package/prompts/dist/index.d.ts +2 -129
- package/prompts/dist/index.js.map +1 -1
- package/prompts/dist/index.mjs.map +1 -1
- package/react/dist/index.d.mts +9 -648
- package/react/dist/index.d.ts +9 -648
- package/react/dist/index.js +4 -1441
- package/react/dist/index.js.map +1 -1
- package/react/dist/index.mjs +9 -1429
- package/react/dist/index.mjs.map +1 -1
- package/rsc/dist/rsc-server.mjs +15 -236
- package/rsc/dist/rsc-server.mjs.map +1 -1
- package/solid/dist/index.d.mts +7 -465
- package/solid/dist/index.d.ts +7 -465
- package/solid/dist/index.js +3 -1057
- package/solid/dist/index.js.map +1 -1
- package/solid/dist/index.mjs +7 -1056
- package/solid/dist/index.mjs.map +1 -1
- package/svelte/dist/index.d.mts +12 -422
- package/svelte/dist/index.d.ts +12 -422
- package/svelte/dist/index.js +12 -768
- package/svelte/dist/index.js.map +1 -1
- package/svelte/dist/index.mjs +10 -762
- package/svelte/dist/index.mjs.map +1 -1
- package/vue/dist/index.d.mts +7 -459
- package/vue/dist/index.d.ts +7 -459
- package/vue/dist/index.js +3 -1057
- package/vue/dist/index.js.map +1 -1
- package/vue/dist/index.mjs +7 -1046
- package/vue/dist/index.mjs.map +1 -1
package/react/dist/index.mjs
CHANGED
@@ -1,1435 +1,15 @@
|
|
1
1
|
'use client'
|
2
2
|
|
3
|
-
// react/
|
4
|
-
import {
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
var
|
10
|
-
|
11
|
-
|
12
|
-
);
|
13
|
-
|
14
|
-
// shared/stream-parts.ts
|
15
|
-
var textStreamPart = {
|
16
|
-
code: "0",
|
17
|
-
name: "text",
|
18
|
-
parse: (value) => {
|
19
|
-
if (typeof value !== "string") {
|
20
|
-
throw new Error('"text" parts expect a string value.');
|
21
|
-
}
|
22
|
-
return { type: "text", value };
|
23
|
-
}
|
24
|
-
};
|
25
|
-
var functionCallStreamPart = {
|
26
|
-
code: "1",
|
27
|
-
name: "function_call",
|
28
|
-
parse: (value) => {
|
29
|
-
if (value == null || typeof value !== "object" || !("function_call" in value) || typeof value.function_call !== "object" || value.function_call == null || !("name" in value.function_call) || !("arguments" in value.function_call) || typeof value.function_call.name !== "string" || typeof value.function_call.arguments !== "string") {
|
30
|
-
throw new Error(
|
31
|
-
'"function_call" parts expect an object with a "function_call" property.'
|
32
|
-
);
|
33
|
-
}
|
34
|
-
return {
|
35
|
-
type: "function_call",
|
36
|
-
value
|
37
|
-
};
|
38
|
-
}
|
39
|
-
};
|
40
|
-
var dataStreamPart = {
|
41
|
-
code: "2",
|
42
|
-
name: "data",
|
43
|
-
parse: (value) => {
|
44
|
-
if (!Array.isArray(value)) {
|
45
|
-
throw new Error('"data" parts expect an array value.');
|
46
|
-
}
|
47
|
-
return { type: "data", value };
|
48
|
-
}
|
49
|
-
};
|
50
|
-
var errorStreamPart = {
|
51
|
-
code: "3",
|
52
|
-
name: "error",
|
53
|
-
parse: (value) => {
|
54
|
-
if (typeof value !== "string") {
|
55
|
-
throw new Error('"error" parts expect a string value.');
|
56
|
-
}
|
57
|
-
return { type: "error", value };
|
58
|
-
}
|
59
|
-
};
|
60
|
-
var assistantMessageStreamPart = {
|
61
|
-
code: "4",
|
62
|
-
name: "assistant_message",
|
63
|
-
parse: (value) => {
|
64
|
-
if (value == null || typeof value !== "object" || !("id" in value) || !("role" in value) || !("content" in value) || typeof value.id !== "string" || typeof value.role !== "string" || value.role !== "assistant" || !Array.isArray(value.content) || !value.content.every(
|
65
|
-
(item) => item != null && typeof item === "object" && "type" in item && item.type === "text" && "text" in item && item.text != null && typeof item.text === "object" && "value" in item.text && typeof item.text.value === "string"
|
66
|
-
)) {
|
67
|
-
throw new Error(
|
68
|
-
'"assistant_message" parts expect an object with an "id", "role", and "content" property.'
|
69
|
-
);
|
70
|
-
}
|
71
|
-
return {
|
72
|
-
type: "assistant_message",
|
73
|
-
value
|
74
|
-
};
|
75
|
-
}
|
76
|
-
};
|
77
|
-
var assistantControlDataStreamPart = {
|
78
|
-
code: "5",
|
79
|
-
name: "assistant_control_data",
|
80
|
-
parse: (value) => {
|
81
|
-
if (value == null || typeof value !== "object" || !("threadId" in value) || !("messageId" in value) || typeof value.threadId !== "string" || typeof value.messageId !== "string") {
|
82
|
-
throw new Error(
|
83
|
-
'"assistant_control_data" parts expect an object with a "threadId" and "messageId" property.'
|
84
|
-
);
|
85
|
-
}
|
86
|
-
return {
|
87
|
-
type: "assistant_control_data",
|
88
|
-
value: {
|
89
|
-
threadId: value.threadId,
|
90
|
-
messageId: value.messageId
|
91
|
-
}
|
92
|
-
};
|
93
|
-
}
|
94
|
-
};
|
95
|
-
var dataMessageStreamPart = {
|
96
|
-
code: "6",
|
97
|
-
name: "data_message",
|
98
|
-
parse: (value) => {
|
99
|
-
if (value == null || typeof value !== "object" || !("role" in value) || !("data" in value) || typeof value.role !== "string" || value.role !== "data") {
|
100
|
-
throw new Error(
|
101
|
-
'"data_message" parts expect an object with a "role" and "data" property.'
|
102
|
-
);
|
103
|
-
}
|
104
|
-
return {
|
105
|
-
type: "data_message",
|
106
|
-
value
|
107
|
-
};
|
108
|
-
}
|
109
|
-
};
|
110
|
-
var toolCallsStreamPart = {
|
111
|
-
code: "7",
|
112
|
-
name: "tool_calls",
|
113
|
-
parse: (value) => {
|
114
|
-
if (value == null || typeof value !== "object" || !("tool_calls" in value) || typeof value.tool_calls !== "object" || value.tool_calls == null || !Array.isArray(value.tool_calls) || value.tool_calls.some(
|
115
|
-
(tc) => tc == null || typeof tc !== "object" || !("id" in tc) || typeof tc.id !== "string" || !("type" in tc) || typeof tc.type !== "string" || !("function" in tc) || tc.function == null || typeof tc.function !== "object" || !("arguments" in tc.function) || typeof tc.function.name !== "string" || typeof tc.function.arguments !== "string"
|
116
|
-
)) {
|
117
|
-
throw new Error(
|
118
|
-
'"tool_calls" parts expect an object with a ToolCallPayload.'
|
119
|
-
);
|
120
|
-
}
|
121
|
-
return {
|
122
|
-
type: "tool_calls",
|
123
|
-
value
|
124
|
-
};
|
125
|
-
}
|
126
|
-
};
|
127
|
-
var messageAnnotationsStreamPart = {
|
128
|
-
code: "8",
|
129
|
-
name: "message_annotations",
|
130
|
-
parse: (value) => {
|
131
|
-
if (!Array.isArray(value)) {
|
132
|
-
throw new Error('"message_annotations" parts expect an array value.');
|
133
|
-
}
|
134
|
-
return { type: "message_annotations", value };
|
135
|
-
}
|
136
|
-
};
|
137
|
-
var toolCallStreamPart = {
|
138
|
-
code: "9",
|
139
|
-
name: "tool_call",
|
140
|
-
parse: (value) => {
|
141
|
-
if (value == null || typeof value !== "object" || !("toolCallId" in value) || typeof value.toolCallId !== "string" || !("toolName" in value) || typeof value.toolName !== "string" || !("args" in value) || typeof value.args !== "object") {
|
142
|
-
throw new Error(
|
143
|
-
'"tool_call" parts expect an object with a "toolCallId", "toolName", and "args" property.'
|
144
|
-
);
|
145
|
-
}
|
146
|
-
return {
|
147
|
-
type: "tool_call",
|
148
|
-
value
|
149
|
-
};
|
150
|
-
}
|
151
|
-
};
|
152
|
-
var toolResultStreamPart = {
|
153
|
-
code: "a",
|
154
|
-
name: "tool_result",
|
155
|
-
parse: (value) => {
|
156
|
-
if (value == null || typeof value !== "object" || !("toolCallId" in value) || typeof value.toolCallId !== "string" || !("toolName" in value) || typeof value.toolName !== "string" || !("args" in value) || typeof value.args !== "object" || !("result" in value)) {
|
157
|
-
throw new Error(
|
158
|
-
'"tool_result" parts expect an object with a "toolCallId", "toolName", "args", and "result" property.'
|
159
|
-
);
|
160
|
-
}
|
161
|
-
return {
|
162
|
-
type: "tool_result",
|
163
|
-
value
|
164
|
-
};
|
165
|
-
}
|
166
|
-
};
|
167
|
-
var streamParts = [
|
168
|
-
textStreamPart,
|
169
|
-
functionCallStreamPart,
|
170
|
-
dataStreamPart,
|
171
|
-
errorStreamPart,
|
172
|
-
assistantMessageStreamPart,
|
173
|
-
assistantControlDataStreamPart,
|
174
|
-
dataMessageStreamPart,
|
175
|
-
toolCallsStreamPart,
|
176
|
-
messageAnnotationsStreamPart,
|
177
|
-
toolCallStreamPart,
|
178
|
-
toolResultStreamPart
|
179
|
-
];
|
180
|
-
var streamPartsByCode = {
|
181
|
-
[textStreamPart.code]: textStreamPart,
|
182
|
-
[functionCallStreamPart.code]: functionCallStreamPart,
|
183
|
-
[dataStreamPart.code]: dataStreamPart,
|
184
|
-
[errorStreamPart.code]: errorStreamPart,
|
185
|
-
[assistantMessageStreamPart.code]: assistantMessageStreamPart,
|
186
|
-
[assistantControlDataStreamPart.code]: assistantControlDataStreamPart,
|
187
|
-
[dataMessageStreamPart.code]: dataMessageStreamPart,
|
188
|
-
[toolCallsStreamPart.code]: toolCallsStreamPart,
|
189
|
-
[messageAnnotationsStreamPart.code]: messageAnnotationsStreamPart,
|
190
|
-
[toolCallStreamPart.code]: toolCallStreamPart,
|
191
|
-
[toolResultStreamPart.code]: toolResultStreamPart
|
192
|
-
};
|
193
|
-
var StreamStringPrefixes = {
|
194
|
-
[textStreamPart.name]: textStreamPart.code,
|
195
|
-
[functionCallStreamPart.name]: functionCallStreamPart.code,
|
196
|
-
[dataStreamPart.name]: dataStreamPart.code,
|
197
|
-
[errorStreamPart.name]: errorStreamPart.code,
|
198
|
-
[assistantMessageStreamPart.name]: assistantMessageStreamPart.code,
|
199
|
-
[assistantControlDataStreamPart.name]: assistantControlDataStreamPart.code,
|
200
|
-
[dataMessageStreamPart.name]: dataMessageStreamPart.code,
|
201
|
-
[toolCallsStreamPart.name]: toolCallsStreamPart.code,
|
202
|
-
[messageAnnotationsStreamPart.name]: messageAnnotationsStreamPart.code,
|
203
|
-
[toolCallStreamPart.name]: toolCallStreamPart.code,
|
204
|
-
[toolResultStreamPart.name]: toolResultStreamPart.code
|
205
|
-
};
|
206
|
-
var validCodes = streamParts.map((part) => part.code);
|
207
|
-
var parseStreamPart = (line) => {
|
208
|
-
const firstSeparatorIndex = line.indexOf(":");
|
209
|
-
if (firstSeparatorIndex === -1) {
|
210
|
-
throw new Error("Failed to parse stream string. No separator found.");
|
211
|
-
}
|
212
|
-
const prefix = line.slice(0, firstSeparatorIndex);
|
213
|
-
if (!validCodes.includes(prefix)) {
|
214
|
-
throw new Error(`Failed to parse stream string. Invalid code ${prefix}.`);
|
215
|
-
}
|
216
|
-
const code = prefix;
|
217
|
-
const textValue = line.slice(firstSeparatorIndex + 1);
|
218
|
-
const jsonValue = JSON.parse(textValue);
|
219
|
-
return streamPartsByCode[code].parse(jsonValue);
|
220
|
-
};
|
221
|
-
|
222
|
-
// shared/read-data-stream.ts
|
223
|
-
var NEWLINE = "\n".charCodeAt(0);
|
224
|
-
function concatChunks(chunks, totalLength) {
|
225
|
-
const concatenatedChunks = new Uint8Array(totalLength);
|
226
|
-
let offset = 0;
|
227
|
-
for (const chunk of chunks) {
|
228
|
-
concatenatedChunks.set(chunk, offset);
|
229
|
-
offset += chunk.length;
|
230
|
-
}
|
231
|
-
chunks.length = 0;
|
232
|
-
return concatenatedChunks;
|
233
|
-
}
|
234
|
-
async function* readDataStream(reader, {
|
235
|
-
isAborted
|
236
|
-
} = {}) {
|
237
|
-
const decoder = new TextDecoder();
|
238
|
-
const chunks = [];
|
239
|
-
let totalLength = 0;
|
240
|
-
while (true) {
|
241
|
-
const { value } = await reader.read();
|
242
|
-
if (value) {
|
243
|
-
chunks.push(value);
|
244
|
-
totalLength += value.length;
|
245
|
-
if (value[value.length - 1] !== NEWLINE) {
|
246
|
-
continue;
|
247
|
-
}
|
248
|
-
}
|
249
|
-
if (chunks.length === 0) {
|
250
|
-
break;
|
251
|
-
}
|
252
|
-
const concatenatedChunks = concatChunks(chunks, totalLength);
|
253
|
-
totalLength = 0;
|
254
|
-
const streamParts2 = decoder.decode(concatenatedChunks, { stream: true }).split("\n").filter((line) => line !== "").map(parseStreamPart);
|
255
|
-
for (const streamPart of streamParts2) {
|
256
|
-
yield streamPart;
|
257
|
-
}
|
258
|
-
if (isAborted == null ? void 0 : isAborted()) {
|
259
|
-
reader.cancel();
|
260
|
-
break;
|
261
|
-
}
|
262
|
-
}
|
263
|
-
}
|
264
|
-
|
265
|
-
// shared/parse-complex-response.ts
|
266
|
-
function assignAnnotationsToMessage(message, annotations) {
|
267
|
-
if (!message || !annotations || !annotations.length)
|
268
|
-
return message;
|
269
|
-
return { ...message, annotations: [...annotations] };
|
270
|
-
}
|
271
|
-
async function parseComplexResponse({
|
272
|
-
reader,
|
273
|
-
abortControllerRef,
|
274
|
-
update,
|
275
|
-
onToolCall,
|
276
|
-
onFinish,
|
277
|
-
generateId: generateId2 = generateId,
|
278
|
-
getCurrentDate = () => /* @__PURE__ */ new Date()
|
279
|
-
}) {
|
280
|
-
const createdAt = getCurrentDate();
|
281
|
-
const prefixMap = {
|
282
|
-
data: []
|
283
|
-
};
|
284
|
-
let message_annotations = void 0;
|
285
|
-
for await (const { type, value } of readDataStream(reader, {
|
286
|
-
isAborted: () => (abortControllerRef == null ? void 0 : abortControllerRef.current) === null
|
287
|
-
})) {
|
288
|
-
if (type === "text") {
|
289
|
-
if (prefixMap["text"]) {
|
290
|
-
prefixMap["text"] = {
|
291
|
-
...prefixMap["text"],
|
292
|
-
content: (prefixMap["text"].content || "") + value
|
293
|
-
};
|
294
|
-
} else {
|
295
|
-
prefixMap["text"] = {
|
296
|
-
id: generateId2(),
|
297
|
-
role: "assistant",
|
298
|
-
content: value,
|
299
|
-
createdAt
|
300
|
-
};
|
301
|
-
}
|
302
|
-
}
|
303
|
-
if (type === "tool_call") {
|
304
|
-
if (prefixMap.text == null) {
|
305
|
-
prefixMap.text = {
|
306
|
-
id: generateId2(),
|
307
|
-
role: "assistant",
|
308
|
-
content: "",
|
309
|
-
createdAt
|
310
|
-
};
|
311
|
-
}
|
312
|
-
if (prefixMap.text.toolInvocations == null) {
|
313
|
-
prefixMap.text.toolInvocations = [];
|
314
|
-
}
|
315
|
-
prefixMap.text.toolInvocations.push(value);
|
316
|
-
if (onToolCall) {
|
317
|
-
const result = await onToolCall({ toolCall: value });
|
318
|
-
if (result != null) {
|
319
|
-
prefixMap.text.toolInvocations[prefixMap.text.toolInvocations.length - 1] = { ...value, result };
|
320
|
-
}
|
321
|
-
}
|
322
|
-
} else if (type === "tool_result") {
|
323
|
-
if (prefixMap.text == null) {
|
324
|
-
prefixMap.text = {
|
325
|
-
id: generateId2(),
|
326
|
-
role: "assistant",
|
327
|
-
content: "",
|
328
|
-
createdAt
|
329
|
-
};
|
330
|
-
}
|
331
|
-
if (prefixMap.text.toolInvocations == null) {
|
332
|
-
prefixMap.text.toolInvocations = [];
|
333
|
-
}
|
334
|
-
const toolInvocationIndex = prefixMap.text.toolInvocations.findIndex(
|
335
|
-
(invocation) => invocation.toolCallId === value.toolCallId
|
336
|
-
);
|
337
|
-
if (toolInvocationIndex !== -1) {
|
338
|
-
prefixMap.text.toolInvocations[toolInvocationIndex] = value;
|
339
|
-
} else {
|
340
|
-
prefixMap.text.toolInvocations.push(value);
|
341
|
-
}
|
342
|
-
}
|
343
|
-
let functionCallMessage = null;
|
344
|
-
if (type === "function_call") {
|
345
|
-
prefixMap["function_call"] = {
|
346
|
-
id: generateId2(),
|
347
|
-
role: "assistant",
|
348
|
-
content: "",
|
349
|
-
function_call: value.function_call,
|
350
|
-
name: value.function_call.name,
|
351
|
-
createdAt
|
352
|
-
};
|
353
|
-
functionCallMessage = prefixMap["function_call"];
|
354
|
-
}
|
355
|
-
let toolCallMessage = null;
|
356
|
-
if (type === "tool_calls") {
|
357
|
-
prefixMap["tool_calls"] = {
|
358
|
-
id: generateId2(),
|
359
|
-
role: "assistant",
|
360
|
-
content: "",
|
361
|
-
tool_calls: value.tool_calls,
|
362
|
-
createdAt
|
363
|
-
};
|
364
|
-
toolCallMessage = prefixMap["tool_calls"];
|
365
|
-
}
|
366
|
-
if (type === "data") {
|
367
|
-
prefixMap["data"].push(...value);
|
368
|
-
}
|
369
|
-
let responseMessage = prefixMap["text"];
|
370
|
-
if (type === "message_annotations") {
|
371
|
-
if (!message_annotations) {
|
372
|
-
message_annotations = [...value];
|
373
|
-
} else {
|
374
|
-
message_annotations.push(...value);
|
375
|
-
}
|
376
|
-
functionCallMessage = assignAnnotationsToMessage(
|
377
|
-
prefixMap["function_call"],
|
378
|
-
message_annotations
|
379
|
-
);
|
380
|
-
toolCallMessage = assignAnnotationsToMessage(
|
381
|
-
prefixMap["tool_calls"],
|
382
|
-
message_annotations
|
383
|
-
);
|
384
|
-
responseMessage = assignAnnotationsToMessage(
|
385
|
-
prefixMap["text"],
|
386
|
-
message_annotations
|
387
|
-
);
|
388
|
-
}
|
389
|
-
if (message_annotations == null ? void 0 : message_annotations.length) {
|
390
|
-
const messagePrefixKeys = [
|
391
|
-
"text",
|
392
|
-
"function_call",
|
393
|
-
"tool_calls"
|
394
|
-
];
|
395
|
-
messagePrefixKeys.forEach((key) => {
|
396
|
-
if (prefixMap[key]) {
|
397
|
-
prefixMap[key].annotations = [...message_annotations];
|
398
|
-
}
|
399
|
-
});
|
400
|
-
}
|
401
|
-
const merged = [functionCallMessage, toolCallMessage, responseMessage].filter(Boolean).map((message) => ({
|
402
|
-
...assignAnnotationsToMessage(message, message_annotations)
|
403
|
-
}));
|
404
|
-
update(merged, [...prefixMap["data"]]);
|
405
|
-
}
|
406
|
-
onFinish == null ? void 0 : onFinish(prefixMap);
|
407
|
-
return {
|
408
|
-
messages: [
|
409
|
-
prefixMap.text,
|
410
|
-
prefixMap.function_call,
|
411
|
-
prefixMap.tool_calls
|
412
|
-
].filter(Boolean),
|
413
|
-
data: prefixMap.data
|
414
|
-
};
|
415
|
-
}
|
416
|
-
|
417
|
-
// shared/utils.ts
|
418
|
-
function createChunkDecoder(complex) {
|
419
|
-
const decoder = new TextDecoder();
|
420
|
-
if (!complex) {
|
421
|
-
return function(chunk) {
|
422
|
-
if (!chunk)
|
423
|
-
return "";
|
424
|
-
return decoder.decode(chunk, { stream: true });
|
425
|
-
};
|
426
|
-
}
|
427
|
-
return function(chunk) {
|
428
|
-
const decoded = decoder.decode(chunk, { stream: true }).split("\n").filter((line) => line !== "");
|
429
|
-
return decoded.map(parseStreamPart).filter(Boolean);
|
430
|
-
};
|
431
|
-
}
|
432
|
-
|
433
|
-
// shared/call-chat-api.ts
|
434
|
-
async function callChatApi({
|
435
|
-
api,
|
436
|
-
messages,
|
437
|
-
body,
|
438
|
-
streamMode = "stream-data",
|
439
|
-
credentials,
|
440
|
-
headers,
|
441
|
-
abortController,
|
442
|
-
restoreMessagesOnFailure,
|
443
|
-
onResponse,
|
444
|
-
onUpdate,
|
445
|
-
onFinish,
|
446
|
-
onToolCall,
|
447
|
-
generateId: generateId2
|
448
|
-
}) {
|
449
|
-
var _a;
|
450
|
-
const response = await fetch(api, {
|
451
|
-
method: "POST",
|
452
|
-
body: JSON.stringify({
|
453
|
-
messages,
|
454
|
-
...body
|
455
|
-
}),
|
456
|
-
headers: {
|
457
|
-
"Content-Type": "application/json",
|
458
|
-
...headers
|
459
|
-
},
|
460
|
-
signal: (_a = abortController == null ? void 0 : abortController()) == null ? void 0 : _a.signal,
|
461
|
-
credentials
|
462
|
-
}).catch((err) => {
|
463
|
-
restoreMessagesOnFailure();
|
464
|
-
throw err;
|
465
|
-
});
|
466
|
-
if (onResponse) {
|
467
|
-
try {
|
468
|
-
await onResponse(response);
|
469
|
-
} catch (err) {
|
470
|
-
throw err;
|
471
|
-
}
|
472
|
-
}
|
473
|
-
if (!response.ok) {
|
474
|
-
restoreMessagesOnFailure();
|
475
|
-
throw new Error(
|
476
|
-
await response.text() || "Failed to fetch the chat response."
|
477
|
-
);
|
478
|
-
}
|
479
|
-
if (!response.body) {
|
480
|
-
throw new Error("The response body is empty.");
|
481
|
-
}
|
482
|
-
const reader = response.body.getReader();
|
483
|
-
switch (streamMode) {
|
484
|
-
case "text": {
|
485
|
-
const decoder = createChunkDecoder();
|
486
|
-
const resultMessage = {
|
487
|
-
id: generateId2(),
|
488
|
-
createdAt: /* @__PURE__ */ new Date(),
|
489
|
-
role: "assistant",
|
490
|
-
content: ""
|
491
|
-
};
|
492
|
-
while (true) {
|
493
|
-
const { done, value } = await reader.read();
|
494
|
-
if (done) {
|
495
|
-
break;
|
496
|
-
}
|
497
|
-
resultMessage.content += decoder(value);
|
498
|
-
resultMessage.id = generateId2();
|
499
|
-
onUpdate([{ ...resultMessage }], []);
|
500
|
-
if ((abortController == null ? void 0 : abortController()) === null) {
|
501
|
-
reader.cancel();
|
502
|
-
break;
|
503
|
-
}
|
504
|
-
}
|
505
|
-
onFinish == null ? void 0 : onFinish(resultMessage);
|
506
|
-
return {
|
507
|
-
messages: [resultMessage],
|
508
|
-
data: []
|
509
|
-
};
|
510
|
-
}
|
511
|
-
case "stream-data": {
|
512
|
-
return await parseComplexResponse({
|
513
|
-
reader,
|
514
|
-
abortControllerRef: abortController != null ? { current: abortController() } : void 0,
|
515
|
-
update: onUpdate,
|
516
|
-
onToolCall,
|
517
|
-
onFinish(prefixMap) {
|
518
|
-
if (onFinish && prefixMap.text != null) {
|
519
|
-
onFinish(prefixMap.text);
|
520
|
-
}
|
521
|
-
},
|
522
|
-
generateId: generateId2
|
523
|
-
});
|
524
|
-
}
|
525
|
-
default: {
|
526
|
-
const exhaustiveCheck = streamMode;
|
527
|
-
throw new Error(`Unknown stream mode: ${exhaustiveCheck}`);
|
528
|
-
}
|
529
|
-
}
|
530
|
-
}
|
531
|
-
|
532
|
-
// shared/process-chat-stream.ts
|
533
|
-
async function processChatStream({
|
534
|
-
getStreamedResponse: getStreamedResponse2,
|
535
|
-
experimental_onFunctionCall,
|
536
|
-
experimental_onToolCall,
|
537
|
-
updateChatRequest,
|
538
|
-
getCurrentMessages
|
539
|
-
}) {
|
540
|
-
while (true) {
|
541
|
-
const messagesAndDataOrJustMessage = await getStreamedResponse2();
|
542
|
-
if ("messages" in messagesAndDataOrJustMessage) {
|
543
|
-
let hasFollowingResponse = false;
|
544
|
-
for (const message of messagesAndDataOrJustMessage.messages) {
|
545
|
-
if ((message.function_call === void 0 || typeof message.function_call === "string") && (message.tool_calls === void 0 || typeof message.tool_calls === "string")) {
|
546
|
-
continue;
|
547
|
-
}
|
548
|
-
hasFollowingResponse = true;
|
549
|
-
if (experimental_onFunctionCall) {
|
550
|
-
const functionCall = message.function_call;
|
551
|
-
if (typeof functionCall !== "object") {
|
552
|
-
console.warn(
|
553
|
-
"experimental_onFunctionCall should not be defined when using tools"
|
554
|
-
);
|
555
|
-
continue;
|
556
|
-
}
|
557
|
-
const functionCallResponse = await experimental_onFunctionCall(
|
558
|
-
getCurrentMessages(),
|
559
|
-
functionCall
|
560
|
-
);
|
561
|
-
if (functionCallResponse === void 0) {
|
562
|
-
hasFollowingResponse = false;
|
563
|
-
break;
|
564
|
-
}
|
565
|
-
updateChatRequest(functionCallResponse);
|
566
|
-
}
|
567
|
-
if (experimental_onToolCall) {
|
568
|
-
const toolCalls = message.tool_calls;
|
569
|
-
if (!Array.isArray(toolCalls) || toolCalls.some((toolCall) => typeof toolCall !== "object")) {
|
570
|
-
console.warn(
|
571
|
-
"experimental_onToolCall should not be defined when using tools"
|
572
|
-
);
|
573
|
-
continue;
|
574
|
-
}
|
575
|
-
const toolCallResponse = await experimental_onToolCall(getCurrentMessages(), toolCalls);
|
576
|
-
if (toolCallResponse === void 0) {
|
577
|
-
hasFollowingResponse = false;
|
578
|
-
break;
|
579
|
-
}
|
580
|
-
updateChatRequest(toolCallResponse);
|
581
|
-
}
|
582
|
-
}
|
583
|
-
if (!hasFollowingResponse) {
|
584
|
-
break;
|
585
|
-
}
|
586
|
-
} else {
|
587
|
-
let fixFunctionCallArguments2 = function(response) {
|
588
|
-
for (const message of response.messages) {
|
589
|
-
if (message.tool_calls !== void 0) {
|
590
|
-
for (const toolCall of message.tool_calls) {
|
591
|
-
if (typeof toolCall === "object") {
|
592
|
-
if (toolCall.function.arguments && typeof toolCall.function.arguments !== "string") {
|
593
|
-
toolCall.function.arguments = JSON.stringify(
|
594
|
-
toolCall.function.arguments
|
595
|
-
);
|
596
|
-
}
|
597
|
-
}
|
598
|
-
}
|
599
|
-
}
|
600
|
-
if (message.function_call !== void 0) {
|
601
|
-
if (typeof message.function_call === "object") {
|
602
|
-
if (message.function_call.arguments && typeof message.function_call.arguments !== "string") {
|
603
|
-
message.function_call.arguments = JSON.stringify(
|
604
|
-
message.function_call.arguments
|
605
|
-
);
|
606
|
-
}
|
607
|
-
}
|
608
|
-
}
|
609
|
-
}
|
610
|
-
};
|
611
|
-
var fixFunctionCallArguments = fixFunctionCallArguments2;
|
612
|
-
const streamedResponseMessage = messagesAndDataOrJustMessage;
|
613
|
-
if ((streamedResponseMessage.function_call === void 0 || typeof streamedResponseMessage.function_call === "string") && (streamedResponseMessage.tool_calls === void 0 || typeof streamedResponseMessage.tool_calls === "string")) {
|
614
|
-
break;
|
615
|
-
}
|
616
|
-
if (experimental_onFunctionCall) {
|
617
|
-
const functionCall = streamedResponseMessage.function_call;
|
618
|
-
if (!(typeof functionCall === "object")) {
|
619
|
-
console.warn(
|
620
|
-
"experimental_onFunctionCall should not be defined when using tools"
|
621
|
-
);
|
622
|
-
continue;
|
623
|
-
}
|
624
|
-
const functionCallResponse = await experimental_onFunctionCall(getCurrentMessages(), functionCall);
|
625
|
-
if (functionCallResponse === void 0)
|
626
|
-
break;
|
627
|
-
fixFunctionCallArguments2(functionCallResponse);
|
628
|
-
updateChatRequest(functionCallResponse);
|
629
|
-
}
|
630
|
-
if (experimental_onToolCall) {
|
631
|
-
const toolCalls = streamedResponseMessage.tool_calls;
|
632
|
-
if (!(typeof toolCalls === "object")) {
|
633
|
-
console.warn(
|
634
|
-
"experimental_onToolCall should not be defined when using functions"
|
635
|
-
);
|
636
|
-
continue;
|
637
|
-
}
|
638
|
-
const toolCallResponse = await experimental_onToolCall(getCurrentMessages(), toolCalls);
|
639
|
-
if (toolCallResponse === void 0)
|
640
|
-
break;
|
641
|
-
fixFunctionCallArguments2(toolCallResponse);
|
642
|
-
updateChatRequest(toolCallResponse);
|
643
|
-
}
|
644
|
-
}
|
645
|
-
}
|
646
|
-
}
|
647
|
-
|
648
|
-
// react/use-chat.ts
|
649
|
-
var getStreamedResponse = async (api, chatRequest, mutate, mutateStreamData, existingData, extraMetadataRef, messagesRef, abortControllerRef, generateId2, streamMode, onFinish, onResponse, onToolCall, sendExtraMessageFields) => {
|
650
|
-
var _a, _b;
|
651
|
-
const previousMessages = messagesRef.current;
|
652
|
-
mutate(chatRequest.messages, false);
|
653
|
-
const constructedMessagesPayload = sendExtraMessageFields ? chatRequest.messages : chatRequest.messages.map(
|
654
|
-
({
|
655
|
-
role,
|
656
|
-
content,
|
657
|
-
name,
|
658
|
-
data,
|
659
|
-
annotations,
|
660
|
-
toolInvocations,
|
661
|
-
function_call,
|
662
|
-
tool_calls,
|
663
|
-
tool_call_id
|
664
|
-
}) => ({
|
665
|
-
role,
|
666
|
-
content,
|
667
|
-
...name !== void 0 && { name },
|
668
|
-
...data !== void 0 && { data },
|
669
|
-
...annotations !== void 0 && { annotations },
|
670
|
-
...toolInvocations !== void 0 && { toolInvocations },
|
671
|
-
// outdated function/tool call handling (TODO deprecate):
|
672
|
-
tool_call_id,
|
673
|
-
...function_call !== void 0 && { function_call },
|
674
|
-
...tool_calls !== void 0 && { tool_calls }
|
675
|
-
})
|
676
|
-
);
|
677
|
-
if (typeof api !== "string") {
|
678
|
-
const replyId = generateId2();
|
679
|
-
const createdAt = /* @__PURE__ */ new Date();
|
680
|
-
let responseMessage = {
|
681
|
-
id: replyId,
|
682
|
-
createdAt,
|
683
|
-
content: "",
|
684
|
-
role: "assistant"
|
685
|
-
};
|
686
|
-
async function readRow(promise) {
|
687
|
-
const { content, ui, next } = await promise;
|
688
|
-
responseMessage["content"] = content;
|
689
|
-
responseMessage["ui"] = await ui;
|
690
|
-
mutate([...chatRequest.messages, { ...responseMessage }], false);
|
691
|
-
if (next) {
|
692
|
-
await readRow(next);
|
693
|
-
}
|
694
|
-
}
|
695
|
-
try {
|
696
|
-
const promise = api({
|
697
|
-
messages: constructedMessagesPayload,
|
698
|
-
data: chatRequest.data
|
699
|
-
});
|
700
|
-
await readRow(promise);
|
701
|
-
} catch (e) {
|
702
|
-
mutate(previousMessages, false);
|
703
|
-
throw e;
|
704
|
-
}
|
705
|
-
if (onFinish) {
|
706
|
-
onFinish(responseMessage);
|
707
|
-
}
|
708
|
-
return responseMessage;
|
709
|
-
}
|
710
|
-
return await callChatApi({
|
711
|
-
api,
|
712
|
-
messages: constructedMessagesPayload,
|
713
|
-
body: {
|
714
|
-
data: chatRequest.data,
|
715
|
-
...extraMetadataRef.current.body,
|
716
|
-
...(_a = chatRequest.options) == null ? void 0 : _a.body,
|
717
|
-
...chatRequest.functions !== void 0 && {
|
718
|
-
functions: chatRequest.functions
|
719
|
-
},
|
720
|
-
...chatRequest.function_call !== void 0 && {
|
721
|
-
function_call: chatRequest.function_call
|
722
|
-
},
|
723
|
-
...chatRequest.tools !== void 0 && {
|
724
|
-
tools: chatRequest.tools
|
725
|
-
},
|
726
|
-
...chatRequest.tool_choice !== void 0 && {
|
727
|
-
tool_choice: chatRequest.tool_choice
|
728
|
-
}
|
729
|
-
},
|
730
|
-
streamMode,
|
731
|
-
credentials: extraMetadataRef.current.credentials,
|
732
|
-
headers: {
|
733
|
-
...extraMetadataRef.current.headers,
|
734
|
-
...(_b = chatRequest.options) == null ? void 0 : _b.headers
|
735
|
-
},
|
736
|
-
abortController: () => abortControllerRef.current,
|
737
|
-
restoreMessagesOnFailure() {
|
738
|
-
mutate(previousMessages, false);
|
739
|
-
},
|
740
|
-
onResponse,
|
741
|
-
onUpdate(merged, data) {
|
742
|
-
mutate([...chatRequest.messages, ...merged], false);
|
743
|
-
mutateStreamData([...existingData || [], ...data || []], false);
|
744
|
-
},
|
745
|
-
onToolCall,
|
746
|
-
onFinish,
|
747
|
-
generateId: generateId2
|
748
|
-
});
|
749
|
-
};
|
750
|
-
function useChat({
|
751
|
-
api = "/api/chat",
|
752
|
-
id,
|
753
|
-
initialMessages,
|
754
|
-
initialInput = "",
|
755
|
-
sendExtraMessageFields,
|
756
|
-
experimental_onFunctionCall,
|
757
|
-
experimental_onToolCall,
|
758
|
-
onToolCall,
|
759
|
-
experimental_maxAutomaticRoundtrips = 0,
|
760
|
-
maxAutomaticRoundtrips = experimental_maxAutomaticRoundtrips,
|
761
|
-
maxToolRoundtrips = maxAutomaticRoundtrips,
|
762
|
-
streamMode,
|
763
|
-
onResponse,
|
764
|
-
onFinish,
|
765
|
-
onError,
|
766
|
-
credentials,
|
767
|
-
headers,
|
768
|
-
body,
|
769
|
-
generateId: generateId2 = generateId
|
770
|
-
} = {}) {
|
771
|
-
const hookId = useId();
|
772
|
-
const idKey = id != null ? id : hookId;
|
773
|
-
const chatKey = typeof api === "string" ? [api, idKey] : idKey;
|
774
|
-
const [initialMessagesFallback] = useState([]);
|
775
|
-
const { data: messages, mutate } = useSWR(
|
776
|
-
[chatKey, "messages"],
|
777
|
-
null,
|
778
|
-
{ fallbackData: initialMessages != null ? initialMessages : initialMessagesFallback }
|
779
|
-
);
|
780
|
-
const { data: isLoading = false, mutate: mutateLoading } = useSWR(
|
781
|
-
[chatKey, "loading"],
|
782
|
-
null
|
783
|
-
);
|
784
|
-
const { data: streamData, mutate: mutateStreamData } = useSWR([chatKey, "streamData"], null);
|
785
|
-
const { data: error = void 0, mutate: setError } = useSWR([chatKey, "error"], null);
|
786
|
-
const messagesRef = useRef(messages || []);
|
787
|
-
useEffect(() => {
|
788
|
-
messagesRef.current = messages || [];
|
789
|
-
}, [messages]);
|
790
|
-
const abortControllerRef = useRef(null);
|
791
|
-
const extraMetadataRef = useRef({
|
792
|
-
credentials,
|
793
|
-
headers,
|
794
|
-
body
|
795
|
-
});
|
796
|
-
useEffect(() => {
|
797
|
-
extraMetadataRef.current = {
|
798
|
-
credentials,
|
799
|
-
headers,
|
800
|
-
body
|
801
|
-
};
|
802
|
-
}, [credentials, headers, body]);
|
803
|
-
const triggerRequest = useCallback(
|
804
|
-
async (chatRequest) => {
|
805
|
-
try {
|
806
|
-
mutateLoading(true);
|
807
|
-
setError(void 0);
|
808
|
-
const abortController = new AbortController();
|
809
|
-
abortControllerRef.current = abortController;
|
810
|
-
await processChatStream({
|
811
|
-
getStreamedResponse: () => getStreamedResponse(
|
812
|
-
api,
|
813
|
-
chatRequest,
|
814
|
-
mutate,
|
815
|
-
mutateStreamData,
|
816
|
-
streamData,
|
817
|
-
extraMetadataRef,
|
818
|
-
messagesRef,
|
819
|
-
abortControllerRef,
|
820
|
-
generateId2,
|
821
|
-
streamMode,
|
822
|
-
onFinish,
|
823
|
-
onResponse,
|
824
|
-
onToolCall,
|
825
|
-
sendExtraMessageFields
|
826
|
-
),
|
827
|
-
experimental_onFunctionCall,
|
828
|
-
experimental_onToolCall,
|
829
|
-
updateChatRequest: (chatRequestParam) => {
|
830
|
-
chatRequest = chatRequestParam;
|
831
|
-
},
|
832
|
-
getCurrentMessages: () => messagesRef.current
|
833
|
-
});
|
834
|
-
abortControllerRef.current = null;
|
835
|
-
} catch (err) {
|
836
|
-
if (err.name === "AbortError") {
|
837
|
-
abortControllerRef.current = null;
|
838
|
-
return null;
|
839
|
-
}
|
840
|
-
if (onError && err instanceof Error) {
|
841
|
-
onError(err);
|
842
|
-
}
|
843
|
-
setError(err);
|
844
|
-
} finally {
|
845
|
-
mutateLoading(false);
|
846
|
-
}
|
847
|
-
const messages2 = messagesRef.current;
|
848
|
-
const lastMessage = messages2[messages2.length - 1];
|
849
|
-
if (
|
850
|
-
// ensure there is a last message:
|
851
|
-
lastMessage != null && // check if the feature is enabled:
|
852
|
-
maxToolRoundtrips > 0 && // check that roundtrip is possible:
|
853
|
-
isAssistantMessageWithCompletedToolCalls(lastMessage) && // limit the number of automatic roundtrips:
|
854
|
-
countTrailingAssistantMessages(messages2) <= maxToolRoundtrips
|
855
|
-
) {
|
856
|
-
await triggerRequest({ messages: messages2 });
|
857
|
-
}
|
858
|
-
},
|
859
|
-
[
|
860
|
-
mutate,
|
861
|
-
mutateLoading,
|
862
|
-
api,
|
863
|
-
extraMetadataRef,
|
864
|
-
onResponse,
|
865
|
-
onFinish,
|
866
|
-
onError,
|
867
|
-
setError,
|
868
|
-
mutateStreamData,
|
869
|
-
streamData,
|
870
|
-
streamMode,
|
871
|
-
sendExtraMessageFields,
|
872
|
-
experimental_onFunctionCall,
|
873
|
-
experimental_onToolCall,
|
874
|
-
onToolCall,
|
875
|
-
maxToolRoundtrips,
|
876
|
-
messagesRef,
|
877
|
-
abortControllerRef,
|
878
|
-
generateId2
|
879
|
-
]
|
880
|
-
);
|
881
|
-
const append = useCallback(
|
882
|
-
async (message, {
|
883
|
-
options,
|
884
|
-
functions,
|
885
|
-
function_call,
|
886
|
-
tools,
|
887
|
-
tool_choice,
|
888
|
-
data
|
889
|
-
} = {}) => {
|
890
|
-
if (!message.id) {
|
891
|
-
message.id = generateId2();
|
892
|
-
}
|
893
|
-
const chatRequest = {
|
894
|
-
messages: messagesRef.current.concat(message),
|
895
|
-
options,
|
896
|
-
data,
|
897
|
-
...functions !== void 0 && { functions },
|
898
|
-
...function_call !== void 0 && { function_call },
|
899
|
-
...tools !== void 0 && { tools },
|
900
|
-
...tool_choice !== void 0 && { tool_choice }
|
901
|
-
};
|
902
|
-
return triggerRequest(chatRequest);
|
903
|
-
},
|
904
|
-
[triggerRequest, generateId2]
|
905
|
-
);
|
906
|
-
const reload = useCallback(
|
907
|
-
async ({
|
908
|
-
options,
|
909
|
-
functions,
|
910
|
-
function_call,
|
911
|
-
tools,
|
912
|
-
tool_choice
|
913
|
-
} = {}) => {
|
914
|
-
if (messagesRef.current.length === 0)
|
915
|
-
return null;
|
916
|
-
const lastMessage = messagesRef.current[messagesRef.current.length - 1];
|
917
|
-
if (lastMessage.role === "assistant") {
|
918
|
-
const chatRequest2 = {
|
919
|
-
messages: messagesRef.current.slice(0, -1),
|
920
|
-
options,
|
921
|
-
...functions !== void 0 && { functions },
|
922
|
-
...function_call !== void 0 && { function_call },
|
923
|
-
...tools !== void 0 && { tools },
|
924
|
-
...tool_choice !== void 0 && { tool_choice }
|
925
|
-
};
|
926
|
-
return triggerRequest(chatRequest2);
|
927
|
-
}
|
928
|
-
const chatRequest = {
|
929
|
-
messages: messagesRef.current,
|
930
|
-
options,
|
931
|
-
...functions !== void 0 && { functions },
|
932
|
-
...function_call !== void 0 && { function_call },
|
933
|
-
...tools !== void 0 && { tools },
|
934
|
-
...tool_choice !== void 0 && { tool_choice }
|
935
|
-
};
|
936
|
-
return triggerRequest(chatRequest);
|
937
|
-
},
|
938
|
-
[triggerRequest]
|
939
|
-
);
|
940
|
-
const stop = useCallback(() => {
|
941
|
-
if (abortControllerRef.current) {
|
942
|
-
abortControllerRef.current.abort();
|
943
|
-
abortControllerRef.current = null;
|
944
|
-
}
|
945
|
-
}, []);
|
946
|
-
const setMessages = useCallback(
|
947
|
-
(messages2) => {
|
948
|
-
mutate(messages2, false);
|
949
|
-
messagesRef.current = messages2;
|
950
|
-
},
|
951
|
-
[mutate]
|
952
|
-
);
|
953
|
-
const [input, setInput] = useState(initialInput);
|
954
|
-
const handleSubmit = useCallback(
|
955
|
-
(e, options = {}, metadata) => {
|
956
|
-
if (metadata) {
|
957
|
-
extraMetadataRef.current = {
|
958
|
-
...extraMetadataRef.current,
|
959
|
-
...metadata
|
960
|
-
};
|
961
|
-
}
|
962
|
-
e.preventDefault();
|
963
|
-
if (!input)
|
964
|
-
return;
|
965
|
-
append(
|
966
|
-
{
|
967
|
-
content: input,
|
968
|
-
role: "user",
|
969
|
-
createdAt: /* @__PURE__ */ new Date()
|
970
|
-
},
|
971
|
-
options
|
972
|
-
);
|
973
|
-
setInput("");
|
974
|
-
},
|
975
|
-
[input, append]
|
976
|
-
);
|
977
|
-
const handleInputChange = (e) => {
|
978
|
-
setInput(e.target.value);
|
979
|
-
};
|
980
|
-
const addToolResult = ({
|
981
|
-
toolCallId,
|
982
|
-
result
|
983
|
-
}) => {
|
984
|
-
const updatedMessages = messagesRef.current.map(
|
985
|
-
(message, index, arr) => (
|
986
|
-
// update the tool calls in the last assistant message:
|
987
|
-
index === arr.length - 1 && message.role === "assistant" && message.toolInvocations ? {
|
988
|
-
...message,
|
989
|
-
toolInvocations: message.toolInvocations.map(
|
990
|
-
(toolInvocation) => toolInvocation.toolCallId === toolCallId ? { ...toolInvocation, result } : toolInvocation
|
991
|
-
)
|
992
|
-
} : message
|
993
|
-
)
|
994
|
-
);
|
995
|
-
mutate(updatedMessages, false);
|
996
|
-
const lastMessage = updatedMessages[updatedMessages.length - 1];
|
997
|
-
if (isAssistantMessageWithCompletedToolCalls(lastMessage)) {
|
998
|
-
triggerRequest({ messages: updatedMessages });
|
999
|
-
}
|
1000
|
-
};
|
1001
|
-
return {
|
1002
|
-
messages: messages || [],
|
1003
|
-
error,
|
1004
|
-
append,
|
1005
|
-
reload,
|
1006
|
-
stop,
|
1007
|
-
setMessages,
|
1008
|
-
input,
|
1009
|
-
setInput,
|
1010
|
-
handleInputChange,
|
1011
|
-
handleSubmit,
|
1012
|
-
isLoading,
|
1013
|
-
data: streamData,
|
1014
|
-
addToolResult,
|
1015
|
-
experimental_addToolResult: addToolResult
|
1016
|
-
};
|
1017
|
-
}
|
1018
|
-
function isAssistantMessageWithCompletedToolCalls(message) {
|
1019
|
-
return message.role === "assistant" && message.toolInvocations && message.toolInvocations.length > 0 && message.toolInvocations.every((toolInvocation) => "result" in toolInvocation);
|
1020
|
-
}
|
1021
|
-
function countTrailingAssistantMessages(messages) {
|
1022
|
-
let count = 0;
|
1023
|
-
for (let i = messages.length - 1; i >= 0; i--) {
|
1024
|
-
if (messages[i].role === "assistant") {
|
1025
|
-
count++;
|
1026
|
-
} else {
|
1027
|
-
break;
|
1028
|
-
}
|
1029
|
-
}
|
1030
|
-
return count;
|
1031
|
-
}
|
1032
|
-
|
1033
|
-
// react/use-completion.ts
|
1034
|
-
import { useCallback as useCallback2, useEffect as useEffect2, useId as useId2, useRef as useRef2, useState as useState2 } from "react";
|
1035
|
-
import useSWR2 from "swr";
|
1036
|
-
|
1037
|
-
// shared/call-completion-api.ts
|
1038
|
-
async function callCompletionApi({
|
1039
|
-
api,
|
1040
|
-
prompt,
|
1041
|
-
credentials,
|
1042
|
-
headers,
|
1043
|
-
body,
|
1044
|
-
streamMode = "stream-data",
|
1045
|
-
setCompletion,
|
1046
|
-
setLoading,
|
1047
|
-
setError,
|
1048
|
-
setAbortController,
|
1049
|
-
onResponse,
|
1050
|
-
onFinish,
|
1051
|
-
onError,
|
1052
|
-
onData
|
1053
|
-
}) {
|
1054
|
-
try {
|
1055
|
-
setLoading(true);
|
1056
|
-
setError(void 0);
|
1057
|
-
const abortController = new AbortController();
|
1058
|
-
setAbortController(abortController);
|
1059
|
-
setCompletion("");
|
1060
|
-
const res = await fetch(api, {
|
1061
|
-
method: "POST",
|
1062
|
-
body: JSON.stringify({
|
1063
|
-
prompt,
|
1064
|
-
...body
|
1065
|
-
}),
|
1066
|
-
credentials,
|
1067
|
-
headers: {
|
1068
|
-
"Content-Type": "application/json",
|
1069
|
-
...headers
|
1070
|
-
},
|
1071
|
-
signal: abortController.signal
|
1072
|
-
}).catch((err) => {
|
1073
|
-
throw err;
|
1074
|
-
});
|
1075
|
-
if (onResponse) {
|
1076
|
-
try {
|
1077
|
-
await onResponse(res);
|
1078
|
-
} catch (err) {
|
1079
|
-
throw err;
|
1080
|
-
}
|
1081
|
-
}
|
1082
|
-
if (!res.ok) {
|
1083
|
-
throw new Error(
|
1084
|
-
await res.text() || "Failed to fetch the chat response."
|
1085
|
-
);
|
1086
|
-
}
|
1087
|
-
if (!res.body) {
|
1088
|
-
throw new Error("The response body is empty.");
|
1089
|
-
}
|
1090
|
-
let result = "";
|
1091
|
-
const reader = res.body.getReader();
|
1092
|
-
switch (streamMode) {
|
1093
|
-
case "text": {
|
1094
|
-
const decoder = createChunkDecoder();
|
1095
|
-
while (true) {
|
1096
|
-
const { done, value } = await reader.read();
|
1097
|
-
if (done) {
|
1098
|
-
break;
|
1099
|
-
}
|
1100
|
-
result += decoder(value);
|
1101
|
-
setCompletion(result);
|
1102
|
-
if (abortController === null) {
|
1103
|
-
reader.cancel();
|
1104
|
-
break;
|
1105
|
-
}
|
1106
|
-
}
|
1107
|
-
break;
|
1108
|
-
}
|
1109
|
-
case "stream-data": {
|
1110
|
-
for await (const { type, value } of readDataStream(reader, {
|
1111
|
-
isAborted: () => abortController === null
|
1112
|
-
})) {
|
1113
|
-
switch (type) {
|
1114
|
-
case "text": {
|
1115
|
-
result += value;
|
1116
|
-
setCompletion(result);
|
1117
|
-
break;
|
1118
|
-
}
|
1119
|
-
case "data": {
|
1120
|
-
onData == null ? void 0 : onData(value);
|
1121
|
-
break;
|
1122
|
-
}
|
1123
|
-
}
|
1124
|
-
}
|
1125
|
-
break;
|
1126
|
-
}
|
1127
|
-
default: {
|
1128
|
-
const exhaustiveCheck = streamMode;
|
1129
|
-
throw new Error(`Unknown stream mode: ${exhaustiveCheck}`);
|
1130
|
-
}
|
1131
|
-
}
|
1132
|
-
if (onFinish) {
|
1133
|
-
onFinish(prompt, result);
|
1134
|
-
}
|
1135
|
-
setAbortController(null);
|
1136
|
-
return result;
|
1137
|
-
} catch (err) {
|
1138
|
-
if (err.name === "AbortError") {
|
1139
|
-
setAbortController(null);
|
1140
|
-
return null;
|
1141
|
-
}
|
1142
|
-
if (err instanceof Error) {
|
1143
|
-
if (onError) {
|
1144
|
-
onError(err);
|
1145
|
-
}
|
1146
|
-
}
|
1147
|
-
setError(err);
|
1148
|
-
} finally {
|
1149
|
-
setLoading(false);
|
1150
|
-
}
|
1151
|
-
}
|
1152
|
-
|
1153
|
-
// react/use-completion.ts
|
1154
|
-
function useCompletion({
|
1155
|
-
api = "/api/completion",
|
1156
|
-
id,
|
1157
|
-
initialCompletion = "",
|
1158
|
-
initialInput = "",
|
1159
|
-
credentials,
|
1160
|
-
headers,
|
1161
|
-
body,
|
1162
|
-
streamMode,
|
1163
|
-
onResponse,
|
1164
|
-
onFinish,
|
1165
|
-
onError
|
1166
|
-
} = {}) {
|
1167
|
-
const hookId = useId2();
|
1168
|
-
const completionId = id || hookId;
|
1169
|
-
const { data, mutate } = useSWR2([api, completionId], null, {
|
1170
|
-
fallbackData: initialCompletion
|
1171
|
-
});
|
1172
|
-
const { data: isLoading = false, mutate: mutateLoading } = useSWR2(
|
1173
|
-
[completionId, "loading"],
|
1174
|
-
null
|
1175
|
-
);
|
1176
|
-
const { data: streamData, mutate: mutateStreamData } = useSWR2([completionId, "streamData"], null);
|
1177
|
-
const [error, setError] = useState2(void 0);
|
1178
|
-
const completion = data;
|
1179
|
-
const [abortController, setAbortController] = useState2(null);
|
1180
|
-
const extraMetadataRef = useRef2({
|
1181
|
-
credentials,
|
1182
|
-
headers,
|
1183
|
-
body
|
1184
|
-
});
|
1185
|
-
useEffect2(() => {
|
1186
|
-
extraMetadataRef.current = {
|
1187
|
-
credentials,
|
1188
|
-
headers,
|
1189
|
-
body
|
1190
|
-
};
|
1191
|
-
}, [credentials, headers, body]);
|
1192
|
-
const triggerRequest = useCallback2(
|
1193
|
-
async (prompt, options) => callCompletionApi({
|
1194
|
-
api,
|
1195
|
-
prompt,
|
1196
|
-
credentials: extraMetadataRef.current.credentials,
|
1197
|
-
headers: { ...extraMetadataRef.current.headers, ...options == null ? void 0 : options.headers },
|
1198
|
-
body: {
|
1199
|
-
...extraMetadataRef.current.body,
|
1200
|
-
...options == null ? void 0 : options.body
|
1201
|
-
},
|
1202
|
-
streamMode,
|
1203
|
-
setCompletion: (completion2) => mutate(completion2, false),
|
1204
|
-
setLoading: mutateLoading,
|
1205
|
-
setError,
|
1206
|
-
setAbortController,
|
1207
|
-
onResponse,
|
1208
|
-
onFinish,
|
1209
|
-
onError,
|
1210
|
-
onData: (data2) => {
|
1211
|
-
mutateStreamData([...streamData || [], ...data2 || []], false);
|
1212
|
-
}
|
1213
|
-
}),
|
1214
|
-
[
|
1215
|
-
mutate,
|
1216
|
-
mutateLoading,
|
1217
|
-
api,
|
1218
|
-
extraMetadataRef,
|
1219
|
-
setAbortController,
|
1220
|
-
onResponse,
|
1221
|
-
onFinish,
|
1222
|
-
onError,
|
1223
|
-
setError,
|
1224
|
-
streamData,
|
1225
|
-
streamMode,
|
1226
|
-
mutateStreamData
|
1227
|
-
]
|
1228
|
-
);
|
1229
|
-
const stop = useCallback2(() => {
|
1230
|
-
if (abortController) {
|
1231
|
-
abortController.abort();
|
1232
|
-
setAbortController(null);
|
1233
|
-
}
|
1234
|
-
}, [abortController]);
|
1235
|
-
const setCompletion = useCallback2(
|
1236
|
-
(completion2) => {
|
1237
|
-
mutate(completion2, false);
|
1238
|
-
},
|
1239
|
-
[mutate]
|
1240
|
-
);
|
1241
|
-
const complete = useCallback2(
|
1242
|
-
async (prompt, options) => {
|
1243
|
-
return triggerRequest(prompt, options);
|
1244
|
-
},
|
1245
|
-
[triggerRequest]
|
1246
|
-
);
|
1247
|
-
const [input, setInput] = useState2(initialInput);
|
1248
|
-
const handleSubmit = useCallback2(
|
1249
|
-
(e) => {
|
1250
|
-
e.preventDefault();
|
1251
|
-
if (!input)
|
1252
|
-
return;
|
1253
|
-
return complete(input);
|
1254
|
-
},
|
1255
|
-
[input, complete]
|
1256
|
-
);
|
1257
|
-
const handleInputChange = (e) => {
|
1258
|
-
setInput(e.target.value);
|
1259
|
-
};
|
1260
|
-
return {
|
1261
|
-
completion,
|
1262
|
-
complete,
|
1263
|
-
error,
|
1264
|
-
setCompletion,
|
1265
|
-
stop,
|
1266
|
-
input,
|
1267
|
-
setInput,
|
1268
|
-
handleInputChange,
|
1269
|
-
handleSubmit,
|
1270
|
-
isLoading,
|
1271
|
-
data: streamData
|
1272
|
-
};
|
1273
|
-
}
|
1274
|
-
|
1275
|
-
// react/use-assistant.ts
|
1276
|
-
import { isAbortError } from "@ai-sdk/provider-utils";
|
1277
|
-
import { useCallback as useCallback3, useRef as useRef3, useState as useState3 } from "react";
|
1278
|
-
function useAssistant({
|
1279
|
-
api,
|
1280
|
-
threadId: threadIdParam,
|
1281
|
-
credentials,
|
1282
|
-
headers,
|
1283
|
-
body,
|
1284
|
-
onError
|
1285
|
-
}) {
|
1286
|
-
const [messages, setMessages] = useState3([]);
|
1287
|
-
const [input, setInput] = useState3("");
|
1288
|
-
const [threadId, setThreadId] = useState3(void 0);
|
1289
|
-
const [status, setStatus] = useState3("awaiting_message");
|
1290
|
-
const [error, setError] = useState3(void 0);
|
1291
|
-
const handleInputChange = (event) => {
|
1292
|
-
setInput(event.target.value);
|
1293
|
-
};
|
1294
|
-
const abortControllerRef = useRef3(null);
|
1295
|
-
const stop = useCallback3(() => {
|
1296
|
-
if (abortControllerRef.current) {
|
1297
|
-
abortControllerRef.current.abort();
|
1298
|
-
abortControllerRef.current = null;
|
1299
|
-
}
|
1300
|
-
}, []);
|
1301
|
-
const append = async (message, requestOptions) => {
|
1302
|
-
var _a;
|
1303
|
-
setStatus("in_progress");
|
1304
|
-
setMessages((messages2) => {
|
1305
|
-
var _a2;
|
1306
|
-
return [
|
1307
|
-
...messages2,
|
1308
|
-
{
|
1309
|
-
...message,
|
1310
|
-
id: (_a2 = message.id) != null ? _a2 : generateId()
|
1311
|
-
}
|
1312
|
-
];
|
1313
|
-
});
|
1314
|
-
setInput("");
|
1315
|
-
const abortController = new AbortController();
|
1316
|
-
try {
|
1317
|
-
abortControllerRef.current = abortController;
|
1318
|
-
const result = await fetch(api, {
|
1319
|
-
method: "POST",
|
1320
|
-
credentials,
|
1321
|
-
signal: abortController.signal,
|
1322
|
-
headers: { "Content-Type": "application/json", ...headers },
|
1323
|
-
body: JSON.stringify({
|
1324
|
-
...body,
|
1325
|
-
// always use user-provided threadId when available:
|
1326
|
-
threadId: (_a = threadIdParam != null ? threadIdParam : threadId) != null ? _a : null,
|
1327
|
-
message: message.content,
|
1328
|
-
// optional request data:
|
1329
|
-
data: requestOptions == null ? void 0 : requestOptions.data
|
1330
|
-
})
|
1331
|
-
});
|
1332
|
-
if (result.body == null) {
|
1333
|
-
throw new Error("The response body is empty.");
|
1334
|
-
}
|
1335
|
-
for await (const { type, value } of readDataStream(
|
1336
|
-
result.body.getReader()
|
1337
|
-
)) {
|
1338
|
-
switch (type) {
|
1339
|
-
case "assistant_message": {
|
1340
|
-
setMessages((messages2) => [
|
1341
|
-
...messages2,
|
1342
|
-
{
|
1343
|
-
id: value.id,
|
1344
|
-
role: value.role,
|
1345
|
-
content: value.content[0].text.value
|
1346
|
-
}
|
1347
|
-
]);
|
1348
|
-
break;
|
1349
|
-
}
|
1350
|
-
case "text": {
|
1351
|
-
setMessages((messages2) => {
|
1352
|
-
const lastMessage = messages2[messages2.length - 1];
|
1353
|
-
return [
|
1354
|
-
...messages2.slice(0, messages2.length - 1),
|
1355
|
-
{
|
1356
|
-
id: lastMessage.id,
|
1357
|
-
role: lastMessage.role,
|
1358
|
-
content: lastMessage.content + value
|
1359
|
-
}
|
1360
|
-
];
|
1361
|
-
});
|
1362
|
-
break;
|
1363
|
-
}
|
1364
|
-
case "data_message": {
|
1365
|
-
setMessages((messages2) => {
|
1366
|
-
var _a2;
|
1367
|
-
return [
|
1368
|
-
...messages2,
|
1369
|
-
{
|
1370
|
-
id: (_a2 = value.id) != null ? _a2 : generateId(),
|
1371
|
-
role: "data",
|
1372
|
-
content: "",
|
1373
|
-
data: value.data
|
1374
|
-
}
|
1375
|
-
];
|
1376
|
-
});
|
1377
|
-
break;
|
1378
|
-
}
|
1379
|
-
case "assistant_control_data": {
|
1380
|
-
setThreadId(value.threadId);
|
1381
|
-
setMessages((messages2) => {
|
1382
|
-
const lastMessage = messages2[messages2.length - 1];
|
1383
|
-
lastMessage.id = value.messageId;
|
1384
|
-
return [...messages2.slice(0, messages2.length - 1), lastMessage];
|
1385
|
-
});
|
1386
|
-
break;
|
1387
|
-
}
|
1388
|
-
case "error": {
|
1389
|
-
setError(new Error(value));
|
1390
|
-
break;
|
1391
|
-
}
|
1392
|
-
}
|
1393
|
-
}
|
1394
|
-
} catch (error2) {
|
1395
|
-
if (isAbortError(error2) && abortController.signal.aborted) {
|
1396
|
-
abortControllerRef.current = null;
|
1397
|
-
return;
|
1398
|
-
}
|
1399
|
-
if (onError && error2 instanceof Error) {
|
1400
|
-
onError(error2);
|
1401
|
-
}
|
1402
|
-
setError(error2);
|
1403
|
-
} finally {
|
1404
|
-
abortControllerRef.current = null;
|
1405
|
-
setStatus("awaiting_message");
|
1406
|
-
}
|
1407
|
-
};
|
1408
|
-
const submitMessage = async (event, requestOptions) => {
|
1409
|
-
var _a;
|
1410
|
-
(_a = event == null ? void 0 : event.preventDefault) == null ? void 0 : _a.call(event);
|
1411
|
-
if (input === "") {
|
1412
|
-
return;
|
1413
|
-
}
|
1414
|
-
append({ role: "user", content: input }, requestOptions);
|
1415
|
-
};
|
1416
|
-
return {
|
1417
|
-
append,
|
1418
|
-
messages,
|
1419
|
-
setMessages,
|
1420
|
-
threadId,
|
1421
|
-
input,
|
1422
|
-
setInput,
|
1423
|
-
handleInputChange,
|
1424
|
-
submitMessage,
|
1425
|
-
status,
|
1426
|
-
error,
|
1427
|
-
stop
|
1428
|
-
};
|
1429
|
-
}
|
1430
|
-
var experimental_useAssistant = useAssistant;
|
3
|
+
// react/index.ts
|
4
|
+
import {
|
5
|
+
useChat as useChatReact,
|
6
|
+
useCompletion as useCompletionReact,
|
7
|
+
useAssistant as useAssistantReact
|
8
|
+
} from "@ai-sdk/react";
|
9
|
+
var useChat = useChatReact;
|
10
|
+
var useCompletion = useCompletionReact;
|
11
|
+
var useAssistant = useAssistantReact;
|
1431
12
|
export {
|
1432
|
-
experimental_useAssistant,
|
1433
13
|
useAssistant,
|
1434
14
|
useChat,
|
1435
15
|
useCompletion
|