ai 2.2.29 → 2.2.30
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.ts +310 -130
- package/dist/index.js +705 -554
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +706 -556
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -4
- package/prompts/dist/index.d.ts +23 -2
- package/prompts/dist/index.js +14 -0
- package/prompts/dist/index.js.map +1 -1
- package/prompts/dist/index.mjs +14 -0
- package/prompts/dist/index.mjs.map +1 -1
- package/react/dist/index.d.ts +92 -10
- package/react/dist/index.js +121 -11
- package/react/dist/index.js.map +1 -1
- package/react/dist/index.mjs +121 -11
- package/react/dist/index.mjs.map +1 -1
- package/solid/dist/index.d.ts +61 -6
- package/solid/dist/index.js +136 -21
- package/solid/dist/index.js.map +1 -1
- package/solid/dist/index.mjs +136 -21
- package/solid/dist/index.mjs.map +1 -1
- package/svelte/dist/index.d.ts +52 -3
- package/svelte/dist/index.js +163 -25
- package/svelte/dist/index.js.map +1 -1
- package/svelte/dist/index.mjs +163 -25
- package/svelte/dist/index.mjs.map +1 -1
- package/vue/dist/index.d.ts +60 -5
- package/vue/dist/index.js +135 -20
- package/vue/dist/index.js.map +1 -1
- package/vue/dist/index.mjs +135 -20
- package/vue/dist/index.mjs.map +1 -1
package/solid/dist/index.mjs
CHANGED
@@ -99,6 +99,23 @@ var dataMessageStreamPart = {
|
|
99
99
|
};
|
100
100
|
}
|
101
101
|
};
|
102
|
+
var toolCallStreamPart = {
|
103
|
+
code: "7",
|
104
|
+
name: "tool_calls",
|
105
|
+
parse: (value) => {
|
106
|
+
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((tc) => {
|
107
|
+
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";
|
108
|
+
})) {
|
109
|
+
throw new Error(
|
110
|
+
'"tool_calls" parts expect an object with a ToolCallPayload.'
|
111
|
+
);
|
112
|
+
}
|
113
|
+
return {
|
114
|
+
type: "tool_calls",
|
115
|
+
value
|
116
|
+
};
|
117
|
+
}
|
118
|
+
};
|
102
119
|
var streamParts = [
|
103
120
|
textStreamPart,
|
104
121
|
functionCallStreamPart,
|
@@ -106,7 +123,8 @@ var streamParts = [
|
|
106
123
|
errorStreamPart,
|
107
124
|
assistantMessageStreamPart,
|
108
125
|
assistantControlDataStreamPart,
|
109
|
-
dataMessageStreamPart
|
126
|
+
dataMessageStreamPart,
|
127
|
+
toolCallStreamPart
|
110
128
|
];
|
111
129
|
var streamPartsByCode = {
|
112
130
|
[textStreamPart.code]: textStreamPart,
|
@@ -115,7 +133,8 @@ var streamPartsByCode = {
|
|
115
133
|
[errorStreamPart.code]: errorStreamPart,
|
116
134
|
[assistantMessageStreamPart.code]: assistantMessageStreamPart,
|
117
135
|
[assistantControlDataStreamPart.code]: assistantControlDataStreamPart,
|
118
|
-
[dataMessageStreamPart.code]: dataMessageStreamPart
|
136
|
+
[dataMessageStreamPart.code]: dataMessageStreamPart,
|
137
|
+
[toolCallStreamPart.code]: toolCallStreamPart
|
119
138
|
};
|
120
139
|
var StreamStringPrefixes = {
|
121
140
|
[textStreamPart.name]: textStreamPart.code,
|
@@ -124,7 +143,8 @@ var StreamStringPrefixes = {
|
|
124
143
|
[errorStreamPart.name]: errorStreamPart.code,
|
125
144
|
[assistantMessageStreamPart.name]: assistantMessageStreamPart.code,
|
126
145
|
[assistantControlDataStreamPart.name]: assistantControlDataStreamPart.code,
|
127
|
-
[dataMessageStreamPart.name]: dataMessageStreamPart.code
|
146
|
+
[dataMessageStreamPart.name]: dataMessageStreamPart.code,
|
147
|
+
[toolCallStreamPart.name]: toolCallStreamPart.code
|
128
148
|
};
|
129
149
|
var validCodes = streamParts.map((part) => part.code);
|
130
150
|
var parseStreamPart = (line) => {
|
@@ -250,20 +270,35 @@ async function parseComplexResponse({
|
|
250
270
|
};
|
251
271
|
functionCallMessage = prefixMap["function_call"];
|
252
272
|
}
|
273
|
+
let toolCallMessage = null;
|
274
|
+
if (type === "tool_calls") {
|
275
|
+
prefixMap["tool_calls"] = {
|
276
|
+
id: generateId(),
|
277
|
+
role: "assistant",
|
278
|
+
content: "",
|
279
|
+
tool_calls: value.tool_calls,
|
280
|
+
createdAt
|
281
|
+
};
|
282
|
+
toolCallMessage = prefixMap["tool_calls"];
|
283
|
+
}
|
253
284
|
if (type === "data") {
|
254
285
|
prefixMap["data"].push(...value);
|
255
286
|
}
|
256
287
|
const responseMessage = prefixMap["text"];
|
257
|
-
const merged = [
|
258
|
-
|
259
|
-
|
288
|
+
const merged = [
|
289
|
+
functionCallMessage,
|
290
|
+
toolCallMessage,
|
291
|
+
responseMessage
|
292
|
+
].filter(Boolean);
|
260
293
|
update(merged, [...prefixMap["data"]]);
|
261
294
|
}
|
262
295
|
onFinish == null ? void 0 : onFinish(prefixMap);
|
263
296
|
return {
|
264
|
-
messages: [
|
265
|
-
|
266
|
-
|
297
|
+
messages: [
|
298
|
+
prefixMap.text,
|
299
|
+
prefixMap.function_call,
|
300
|
+
prefixMap.tool_calls
|
301
|
+
].filter(Boolean),
|
267
302
|
data: prefixMap.data
|
268
303
|
};
|
269
304
|
}
|
@@ -349,6 +384,8 @@ async function callChatApi({
|
|
349
384
|
streamedResponse += decode(value);
|
350
385
|
if (streamedResponse.startsWith('{"function_call":')) {
|
351
386
|
responseMessage["function_call"] = streamedResponse;
|
387
|
+
} else if (streamedResponse.startsWith('{"tool_calls":')) {
|
388
|
+
responseMessage["tool_calls"] = streamedResponse;
|
352
389
|
} else {
|
353
390
|
responseMessage["content"] = streamedResponse;
|
354
391
|
}
|
@@ -363,6 +400,11 @@ async function callChatApi({
|
|
363
400
|
responseMessage["function_call"] = parsedFunctionCall;
|
364
401
|
appendMessage({ ...responseMessage });
|
365
402
|
}
|
403
|
+
if (streamedResponse.startsWith('{"tool_calls":')) {
|
404
|
+
const parsedToolCalls = JSON.parse(streamedResponse).tool_calls;
|
405
|
+
responseMessage["tool_calls"] = parsedToolCalls;
|
406
|
+
appendMessage({ ...responseMessage });
|
407
|
+
}
|
366
408
|
if (onFinish) {
|
367
409
|
onFinish(responseMessage);
|
368
410
|
}
|
@@ -374,6 +416,7 @@ async function callChatApi({
|
|
374
416
|
async function processChatStream({
|
375
417
|
getStreamedResponse,
|
376
418
|
experimental_onFunctionCall,
|
419
|
+
experimental_onToolCall,
|
377
420
|
updateChatRequest,
|
378
421
|
getCurrentMessages
|
379
422
|
}) {
|
@@ -382,12 +425,18 @@ async function processChatStream({
|
|
382
425
|
if ("messages" in messagesAndDataOrJustMessage) {
|
383
426
|
let hasFollowingResponse = false;
|
384
427
|
for (const message of messagesAndDataOrJustMessage.messages) {
|
385
|
-
if (message.function_call === void 0 || typeof message.function_call === "string") {
|
428
|
+
if ((message.function_call === void 0 || typeof message.function_call === "string") && (message.tool_calls === void 0 || typeof message.tool_calls === "string")) {
|
386
429
|
continue;
|
387
430
|
}
|
388
431
|
hasFollowingResponse = true;
|
389
432
|
if (experimental_onFunctionCall) {
|
390
433
|
const functionCall = message.function_call;
|
434
|
+
if (typeof functionCall !== "object") {
|
435
|
+
console.warn(
|
436
|
+
"experimental_onFunctionCall should not be defined when using tools"
|
437
|
+
);
|
438
|
+
continue;
|
439
|
+
}
|
391
440
|
const functionCallResponse = await experimental_onFunctionCall(
|
392
441
|
getCurrentMessages(),
|
393
442
|
functionCall
|
@@ -398,22 +447,83 @@ async function processChatStream({
|
|
398
447
|
}
|
399
448
|
updateChatRequest(functionCallResponse);
|
400
449
|
}
|
450
|
+
if (experimental_onToolCall) {
|
451
|
+
const toolCalls = message.tool_calls;
|
452
|
+
if (!Array.isArray(toolCalls) || toolCalls.some((toolCall) => typeof toolCall !== "object")) {
|
453
|
+
console.warn(
|
454
|
+
"experimental_onToolCall should not be defined when using tools"
|
455
|
+
);
|
456
|
+
continue;
|
457
|
+
}
|
458
|
+
const toolCallResponse = await experimental_onToolCall(getCurrentMessages(), toolCalls);
|
459
|
+
if (toolCallResponse === void 0) {
|
460
|
+
hasFollowingResponse = false;
|
461
|
+
break;
|
462
|
+
}
|
463
|
+
updateChatRequest(toolCallResponse);
|
464
|
+
}
|
401
465
|
}
|
402
466
|
if (!hasFollowingResponse) {
|
403
467
|
break;
|
404
468
|
}
|
405
469
|
} else {
|
470
|
+
let fixFunctionCallArguments2 = function(response) {
|
471
|
+
for (const message of response.messages) {
|
472
|
+
if (message.tool_calls !== void 0) {
|
473
|
+
for (const toolCall of message.tool_calls) {
|
474
|
+
if (typeof toolCall === "object") {
|
475
|
+
if (toolCall.function.arguments && typeof toolCall.function.arguments !== "string") {
|
476
|
+
toolCall.function.arguments = JSON.stringify(
|
477
|
+
toolCall.function.arguments
|
478
|
+
);
|
479
|
+
}
|
480
|
+
}
|
481
|
+
}
|
482
|
+
}
|
483
|
+
if (message.function_call !== void 0) {
|
484
|
+
if (typeof message.function_call === "object") {
|
485
|
+
if (message.function_call.arguments && typeof message.function_call.arguments !== "string") {
|
486
|
+
message.function_call.arguments = JSON.stringify(
|
487
|
+
message.function_call.arguments
|
488
|
+
);
|
489
|
+
}
|
490
|
+
}
|
491
|
+
}
|
492
|
+
}
|
493
|
+
};
|
494
|
+
var fixFunctionCallArguments = fixFunctionCallArguments2;
|
406
495
|
const streamedResponseMessage = messagesAndDataOrJustMessage;
|
407
|
-
if (streamedResponseMessage.function_call === void 0 || typeof streamedResponseMessage.function_call === "string") {
|
496
|
+
if ((streamedResponseMessage.function_call === void 0 || typeof streamedResponseMessage.function_call === "string") && (streamedResponseMessage.tool_calls === void 0 || typeof streamedResponseMessage.tool_calls === "string")) {
|
408
497
|
break;
|
409
498
|
}
|
410
499
|
if (experimental_onFunctionCall) {
|
411
500
|
const functionCall = streamedResponseMessage.function_call;
|
501
|
+
if (!(typeof functionCall === "object")) {
|
502
|
+
console.warn(
|
503
|
+
"experimental_onFunctionCall should not be defined when using tools"
|
504
|
+
);
|
505
|
+
continue;
|
506
|
+
}
|
412
507
|
const functionCallResponse = await experimental_onFunctionCall(getCurrentMessages(), functionCall);
|
413
508
|
if (functionCallResponse === void 0)
|
414
509
|
break;
|
510
|
+
fixFunctionCallArguments2(functionCallResponse);
|
415
511
|
updateChatRequest(functionCallResponse);
|
416
512
|
}
|
513
|
+
if (experimental_onToolCall) {
|
514
|
+
const toolCalls = streamedResponseMessage.tool_calls;
|
515
|
+
if (!(typeof toolCalls === "object")) {
|
516
|
+
console.warn(
|
517
|
+
"experimental_onToolCall should not be defined when using functions"
|
518
|
+
);
|
519
|
+
continue;
|
520
|
+
}
|
521
|
+
const toolCallResponse = await experimental_onToolCall(getCurrentMessages(), toolCalls);
|
522
|
+
if (toolCallResponse === void 0)
|
523
|
+
break;
|
524
|
+
fixFunctionCallArguments2(toolCallResponse);
|
525
|
+
updateChatRequest(toolCallResponse);
|
526
|
+
}
|
417
527
|
}
|
418
528
|
}
|
419
529
|
}
|
@@ -460,7 +570,7 @@ function useChat({
|
|
460
570
|
);
|
461
571
|
const [isLoading, setIsLoading] = createSignal(false);
|
462
572
|
let abortController = null;
|
463
|
-
async function triggerRequest(messagesSnapshot, options) {
|
573
|
+
async function triggerRequest(messagesSnapshot, { options, data } = {}) {
|
464
574
|
try {
|
465
575
|
setError(void 0);
|
466
576
|
setIsLoading(true);
|
@@ -472,7 +582,8 @@ function useChat({
|
|
472
582
|
mutate(messagesSnapshot);
|
473
583
|
let chatRequest = {
|
474
584
|
messages: messagesSnapshot,
|
475
|
-
options
|
585
|
+
options,
|
586
|
+
data
|
476
587
|
};
|
477
588
|
await processChatStream({
|
478
589
|
getStreamedResponse: async () => {
|
@@ -491,6 +602,7 @@ function useChat({
|
|
491
602
|
})
|
492
603
|
),
|
493
604
|
body: {
|
605
|
+
data: chatRequest.data,
|
494
606
|
...body,
|
495
607
|
...options == null ? void 0 : options.body
|
496
608
|
},
|
@@ -501,9 +613,9 @@ function useChat({
|
|
501
613
|
abortController: () => abortController,
|
502
614
|
credentials,
|
503
615
|
onResponse,
|
504
|
-
onUpdate(merged,
|
616
|
+
onUpdate(merged, data2) {
|
505
617
|
mutate([...chatRequest.messages, ...merged]);
|
506
|
-
setStreamData([...existingData, ...
|
618
|
+
setStreamData([...existingData, ...data2 != null ? data2 : []]);
|
507
619
|
},
|
508
620
|
onFinish,
|
509
621
|
appendMessage(message) {
|
@@ -567,16 +679,19 @@ function useChat({
|
|
567
679
|
mutate(messages2);
|
568
680
|
};
|
569
681
|
const [input, setInput] = createSignal(initialInput);
|
570
|
-
const handleSubmit = (e) => {
|
682
|
+
const handleSubmit = (e, options = {}) => {
|
571
683
|
e.preventDefault();
|
572
684
|
const inputValue = input();
|
573
685
|
if (!inputValue)
|
574
686
|
return;
|
575
|
-
append(
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
687
|
+
append(
|
688
|
+
{
|
689
|
+
content: inputValue,
|
690
|
+
role: "user",
|
691
|
+
createdAt: /* @__PURE__ */ new Date()
|
692
|
+
},
|
693
|
+
options
|
694
|
+
);
|
580
695
|
setInput("");
|
581
696
|
};
|
582
697
|
return {
|
package/solid/dist/index.mjs.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../use-chat.ts","../../shared/stream-parts.ts","../../shared/read-data-stream.ts","../../shared/utils.ts","../../shared/parse-complex-response.ts","../../shared/call-chat-api.ts","../../shared/process-chat-stream.ts","../use-completion.ts","../../shared/call-completion-api.ts"],"sourcesContent":["import { Accessor, Resource, Setter, createSignal } from 'solid-js';\nimport { useSWRStore } from 'solid-swr-store';\nimport { createSWRStore } from 'swr-store';\nimport { callChatApi } from '../shared/call-chat-api';\nimport { processChatStream } from '../shared/process-chat-stream';\nimport type {\n ChatRequest,\n CreateMessage,\n JSONValue,\n Message,\n RequestOptions,\n UseChatOptions,\n} from '../shared/types';\nimport { nanoid } from '../shared/utils';\n\nexport type { CreateMessage, Message, UseChatOptions };\n\nexport type UseChatHelpers = {\n /** Current messages in the chat */\n messages: Resource<Message[]>;\n /** The error object of the API request */\n error: Accessor<undefined | Error>;\n /**\n * Append a user message to the chat list. This triggers the API call to fetch\n * the assistant's response.\n * @param message The message to append\n * @param options Additional options to pass to the API call\n */\n append: (\n message: Message | CreateMessage,\n options?: RequestOptions,\n ) => Promise<string | null | undefined>;\n /**\n * Reload the last AI chat response for the given chat history. If the last\n * message isn't from the assistant, it will request the API to generate a\n * new response.\n */\n reload: (options?: RequestOptions) => Promise<string | null | undefined>;\n /**\n * Abort the current request immediately, keep the generated tokens if any.\n */\n stop: () => void;\n /**\n * Update the `messages` state locally. This is useful when you want to\n * edit the messages on the client, and then trigger the `reload` method\n * manually to regenerate the AI response.\n */\n setMessages: (messages: Message[]) => void;\n /** The current value of the input */\n input: Accessor<string>;\n /** Signal setter to update the input value */\n setInput: Setter<string>;\n /** Form submission handler to automatically reset input and append a user message */\n handleSubmit: (e: any) => void;\n /** Whether the API request is in progress */\n isLoading: Accessor<boolean>;\n /** Additional data added on the server via StreamData */\n data: Accessor<JSONValue[] | undefined>;\n};\n\nlet uniqueId = 0;\n\nconst store: Record<string, Message[] | undefined> = {};\nconst chatApiStore = createSWRStore<Message[], string[]>({\n get: async (key: string) => {\n return store[key] ?? [];\n },\n});\n\nexport function useChat({\n api = '/api/chat',\n id,\n initialMessages = [],\n initialInput = '',\n sendExtraMessageFields,\n experimental_onFunctionCall,\n onResponse,\n onFinish,\n onError,\n credentials,\n headers,\n body,\n generateId = nanoid,\n}: UseChatOptions = {}): UseChatHelpers {\n // Generate a unique ID for the chat if not provided.\n const chatId = id || `chat-${uniqueId++}`;\n\n const key = `${api}|${chatId}`;\n\n // Because of the `initialData` option, the `data` will never be `undefined`:\n const messages = useSWRStore(chatApiStore, () => [key], {\n initialData: initialMessages,\n }) as Resource<Message[]>;\n\n const mutate = (data: Message[]) => {\n store[key] = data;\n return chatApiStore.mutate([key], {\n status: 'success',\n data,\n });\n };\n\n const [error, setError] = createSignal<undefined | Error>(undefined);\n const [streamData, setStreamData] = createSignal<JSONValue[] | undefined>(\n undefined,\n );\n const [isLoading, setIsLoading] = createSignal(false);\n\n let abortController: AbortController | null = null;\n async function triggerRequest(\n messagesSnapshot: Message[],\n options?: RequestOptions,\n ) {\n try {\n setError(undefined);\n setIsLoading(true);\n\n abortController = new AbortController();\n\n const getCurrentMessages = () =>\n chatApiStore.get([key], {\n shouldRevalidate: false,\n });\n\n // Do an optimistic update to the chat state to show the updated messages\n // immediately.\n const previousMessages = getCurrentMessages();\n mutate(messagesSnapshot);\n\n let chatRequest: ChatRequest = {\n messages: messagesSnapshot,\n options,\n };\n\n await processChatStream({\n getStreamedResponse: async () => {\n const existingData = streamData() ?? [];\n\n return await callChatApi({\n api,\n messages: sendExtraMessageFields\n ? chatRequest.messages\n : chatRequest.messages.map(\n ({ role, content, name, function_call }) => ({\n role,\n content,\n ...(name !== undefined && { name }),\n ...(function_call !== undefined && {\n function_call,\n }),\n }),\n ),\n body: {\n ...body,\n ...options?.body,\n },\n headers: {\n ...headers,\n ...options?.headers,\n },\n abortController: () => abortController,\n credentials,\n onResponse,\n onUpdate(merged, data) {\n mutate([...chatRequest.messages, ...merged]);\n setStreamData([...existingData, ...(data ?? [])]);\n },\n onFinish,\n appendMessage(message) {\n mutate([...chatRequest.messages, message]);\n },\n restoreMessagesOnFailure() {\n // Restore the previous messages if the request fails.\n if (previousMessages.status === 'success') {\n mutate(previousMessages.data);\n }\n },\n generateId,\n });\n },\n experimental_onFunctionCall,\n updateChatRequest(newChatRequest) {\n chatRequest = newChatRequest;\n },\n getCurrentMessages: () => getCurrentMessages().data,\n });\n\n abortController = null;\n } catch (err) {\n // Ignore abort errors as they are expected.\n if ((err as any).name === 'AbortError') {\n abortController = null;\n return null;\n }\n\n if (onError && err instanceof Error) {\n onError(err);\n }\n\n setError(err as Error);\n } finally {\n setIsLoading(false);\n }\n }\n\n const append: UseChatHelpers['append'] = async (message, options) => {\n if (!message.id) {\n message.id = generateId();\n }\n return triggerRequest(\n (messages() ?? []).concat(message as Message),\n options,\n );\n };\n\n const reload: UseChatHelpers['reload'] = async options => {\n const messagesSnapshot = messages();\n if (!messagesSnapshot || messagesSnapshot.length === 0) return null;\n\n const lastMessage = messagesSnapshot[messagesSnapshot.length - 1];\n if (lastMessage.role === 'assistant') {\n return triggerRequest(messagesSnapshot.slice(0, -1), options);\n }\n return triggerRequest(messagesSnapshot, options);\n };\n\n const stop = () => {\n if (abortController) {\n abortController.abort();\n abortController = null;\n }\n };\n\n const setMessages = (messages: Message[]) => {\n mutate(messages);\n };\n\n const [input, setInput] = createSignal(initialInput);\n\n const handleSubmit = (e: any) => {\n e.preventDefault();\n const inputValue = input();\n if (!inputValue) return;\n append({\n content: inputValue,\n role: 'user',\n createdAt: new Date(),\n });\n setInput('');\n };\n\n return {\n messages,\n append,\n error,\n reload,\n stop,\n setMessages,\n input,\n setInput,\n handleSubmit,\n isLoading,\n data: streamData,\n };\n}\n","import {\n AssistantMessage,\n DataMessage,\n FunctionCall,\n JSONValue,\n} from './types';\nimport { StreamString } from './utils';\n\nexport interface StreamPart<CODE extends string, NAME extends string, TYPE> {\n code: CODE;\n name: NAME;\n parse: (value: JSONValue) => { type: NAME; value: TYPE };\n}\n\nconst textStreamPart: StreamPart<'0', 'text', string> = {\n code: '0',\n name: 'text',\n parse: (value: JSONValue) => {\n if (typeof value !== 'string') {\n throw new Error('\"text\" parts expect a string value.');\n }\n return { type: 'text', value };\n },\n};\n\nconst functionCallStreamPart: StreamPart<\n '1',\n 'function_call',\n { function_call: FunctionCall }\n> = {\n code: '1',\n name: 'function_call',\n parse: (value: JSONValue) => {\n if (\n value == null ||\n typeof value !== 'object' ||\n !('function_call' in value) ||\n typeof value.function_call !== 'object' ||\n value.function_call == null ||\n !('name' in value.function_call) ||\n !('arguments' in value.function_call) ||\n typeof value.function_call.name !== 'string' ||\n typeof value.function_call.arguments !== 'string'\n ) {\n throw new Error(\n '\"function_call\" parts expect an object with a \"function_call\" property.',\n );\n }\n\n return {\n type: 'function_call',\n value: value as unknown as { function_call: FunctionCall },\n };\n },\n};\n\nconst dataStreamPart: StreamPart<'2', 'data', Array<JSONValue>> = {\n code: '2',\n name: 'data',\n parse: (value: JSONValue) => {\n if (!Array.isArray(value)) {\n throw new Error('\"data\" parts expect an array value.');\n }\n\n return { type: 'data', value };\n },\n};\n\nconst errorStreamPart: StreamPart<'3', 'error', string> = {\n code: '3',\n name: 'error',\n parse: (value: JSONValue) => {\n if (typeof value !== 'string') {\n throw new Error('\"error\" parts expect a string value.');\n }\n return { type: 'error', value };\n },\n};\n\nconst assistantMessageStreamPart: StreamPart<\n '4',\n 'assistant_message',\n AssistantMessage\n> = {\n code: '4',\n name: 'assistant_message',\n parse: (value: JSONValue) => {\n if (\n value == null ||\n typeof value !== 'object' ||\n !('id' in value) ||\n !('role' in value) ||\n !('content' in value) ||\n typeof value.id !== 'string' ||\n typeof value.role !== 'string' ||\n value.role !== 'assistant' ||\n !Array.isArray(value.content) ||\n !value.content.every(\n item =>\n item != null &&\n typeof item === 'object' &&\n 'type' in item &&\n item.type === 'text' &&\n 'text' in item &&\n item.text != null &&\n typeof item.text === 'object' &&\n 'value' in item.text &&\n typeof item.text.value === 'string',\n )\n ) {\n throw new Error(\n '\"assistant_message\" parts expect an object with an \"id\", \"role\", and \"content\" property.',\n );\n }\n\n return {\n type: 'assistant_message',\n value: value as AssistantMessage,\n };\n },\n};\n\nconst assistantControlDataStreamPart: StreamPart<\n '5',\n 'assistant_control_data',\n {\n threadId: string;\n messageId: string;\n }\n> = {\n code: '5',\n name: 'assistant_control_data',\n parse: (value: JSONValue) => {\n if (\n value == null ||\n typeof value !== 'object' ||\n !('threadId' in value) ||\n !('messageId' in value) ||\n typeof value.threadId !== 'string' ||\n typeof value.messageId !== 'string'\n ) {\n throw new Error(\n '\"assistant_control_data\" parts expect an object with a \"threadId\" and \"messageId\" property.',\n );\n }\n\n return {\n type: 'assistant_control_data',\n value: {\n threadId: value.threadId,\n messageId: value.messageId,\n },\n };\n },\n};\n\nconst dataMessageStreamPart: StreamPart<'6', 'data_message', DataMessage> = {\n code: '6',\n name: 'data_message',\n parse: (value: JSONValue) => {\n if (\n value == null ||\n typeof value !== 'object' ||\n !('role' in value) ||\n !('data' in value) ||\n typeof value.role !== 'string' ||\n value.role !== 'data'\n ) {\n throw new Error(\n '\"data_message\" parts expect an object with a \"role\" and \"data\" property.',\n );\n }\n\n return {\n type: 'data_message',\n value: value as DataMessage,\n };\n },\n};\n\nconst streamParts = [\n textStreamPart,\n functionCallStreamPart,\n dataStreamPart,\n errorStreamPart,\n assistantMessageStreamPart,\n assistantControlDataStreamPart,\n dataMessageStreamPart,\n] as const;\n\n// union type of all stream parts\ntype StreamParts =\n | typeof textStreamPart\n | typeof functionCallStreamPart\n | typeof dataStreamPart\n | typeof errorStreamPart\n | typeof assistantMessageStreamPart\n | typeof assistantControlDataStreamPart\n | typeof dataMessageStreamPart;\n\n/**\n * Maps the type of a stream part to its value type.\n */\ntype StreamPartValueType = {\n [P in StreamParts as P['name']]: ReturnType<P['parse']>['value'];\n};\n\nexport type StreamPartType =\n | ReturnType<typeof textStreamPart.parse>\n | ReturnType<typeof functionCallStreamPart.parse>\n | ReturnType<typeof dataStreamPart.parse>\n | ReturnType<typeof errorStreamPart.parse>\n | ReturnType<typeof assistantMessageStreamPart.parse>\n | ReturnType<typeof assistantControlDataStreamPart.parse>\n | ReturnType<typeof dataMessageStreamPart.parse>;\n\nexport const streamPartsByCode = {\n [textStreamPart.code]: textStreamPart,\n [functionCallStreamPart.code]: functionCallStreamPart,\n [dataStreamPart.code]: dataStreamPart,\n [errorStreamPart.code]: errorStreamPart,\n [assistantMessageStreamPart.code]: assistantMessageStreamPart,\n [assistantControlDataStreamPart.code]: assistantControlDataStreamPart,\n [dataMessageStreamPart.code]: dataMessageStreamPart,\n} as const;\n\n/**\n * The map of prefixes for data in the stream\n *\n * - 0: Text from the LLM response\n * - 1: (OpenAI) function_call responses\n * - 2: custom JSON added by the user using `Data`\n *\n * Example:\n * ```\n * 0:Vercel\n * 0:'s\n * 0: AI\n * 0: AI\n * 0: SDK\n * 0: is great\n * 0:!\n * 2: { \"someJson\": \"value\" }\n * 1: {\"function_call\": {\"name\": \"get_current_weather\", \"arguments\": \"{\\\\n\\\\\"location\\\\\": \\\\\"Charlottesville, Virginia\\\\\",\\\\n\\\\\"format\\\\\": \\\\\"celsius\\\\\"\\\\n}\"}}\n *```\n */\nexport const StreamStringPrefixes = {\n [textStreamPart.name]: textStreamPart.code,\n [functionCallStreamPart.name]: functionCallStreamPart.code,\n [dataStreamPart.name]: dataStreamPart.code,\n [errorStreamPart.name]: errorStreamPart.code,\n [assistantMessageStreamPart.name]: assistantMessageStreamPart.code,\n [assistantControlDataStreamPart.name]: assistantControlDataStreamPart.code,\n [dataMessageStreamPart.name]: dataMessageStreamPart.code,\n} as const;\n\nexport const validCodes = streamParts.map(part => part.code);\n\n/**\n * Parses a stream part from a string.\n *\n * @param line The string to parse.\n * @returns The parsed stream part.\n * @throws An error if the string cannot be parsed.\n */\nexport const parseStreamPart = (line: string): StreamPartType => {\n const firstSeparatorIndex = line.indexOf(':');\n\n if (firstSeparatorIndex === -1) {\n throw new Error('Failed to parse stream string. No separator found.');\n }\n\n const prefix = line.slice(0, firstSeparatorIndex);\n\n if (!validCodes.includes(prefix as keyof typeof streamPartsByCode)) {\n throw new Error(`Failed to parse stream string. Invalid code ${prefix}.`);\n }\n\n const code = prefix as keyof typeof streamPartsByCode;\n\n const textValue = line.slice(firstSeparatorIndex + 1);\n const jsonValue: JSONValue = JSON.parse(textValue);\n\n return streamPartsByCode[code].parse(jsonValue);\n};\n\n/**\n * Prepends a string with a prefix from the `StreamChunkPrefixes`, JSON-ifies it,\n * and appends a new line.\n *\n * It ensures type-safety for the part type and value.\n */\nexport function formatStreamPart<T extends keyof StreamPartValueType>(\n type: T,\n value: StreamPartValueType[T],\n): StreamString {\n const streamPart = streamParts.find(part => part.name === type);\n\n if (!streamPart) {\n throw new Error(`Invalid stream part type: ${type}`);\n }\n\n return `${streamPart.code}:${JSON.stringify(value)}\\n`;\n}\n","import { StreamPartType, parseStreamPart } from './stream-parts';\n\nconst NEWLINE = '\\n'.charCodeAt(0);\n\n// concatenates all the chunks into a single Uint8Array\nfunction concatChunks(chunks: Uint8Array[], totalLength: number) {\n const concatenatedChunks = new Uint8Array(totalLength);\n\n let offset = 0;\n for (const chunk of chunks) {\n concatenatedChunks.set(chunk, offset);\n offset += chunk.length;\n }\n chunks.length = 0;\n\n return concatenatedChunks;\n}\n\nexport async function* readDataStream(\n reader: ReadableStreamDefaultReader<Uint8Array>,\n {\n isAborted,\n }: {\n isAborted?: () => boolean;\n } = {},\n): AsyncGenerator<StreamPartType> {\n // implementation note: this slightly more complex algorithm is required\n // to pass the tests in the edge environment.\n\n const decoder = new TextDecoder();\n const chunks: Uint8Array[] = [];\n let totalLength = 0;\n\n while (true) {\n const { value } = await reader.read();\n\n if (value) {\n chunks.push(value);\n totalLength += value.length;\n if (value[value.length - 1] !== NEWLINE) {\n // if the last character is not a newline, we have not read the whole JSON value\n continue;\n }\n }\n\n if (chunks.length === 0) {\n break; // we have reached the end of the stream\n }\n\n const concatenatedChunks = concatChunks(chunks, totalLength);\n totalLength = 0;\n\n const streamParts = decoder\n .decode(concatenatedChunks, { stream: true })\n .split('\\n')\n .filter(line => line !== '') // splitting leaves an empty string at the end\n .map(parseStreamPart);\n\n for (const streamPart of streamParts) {\n yield streamPart;\n }\n\n // The request has been aborted, stop reading the stream.\n if (isAborted?.()) {\n reader.cancel();\n break;\n }\n }\n}\n","import { customAlphabet } from 'nanoid/non-secure';\nimport {\n StreamPartType,\n StreamStringPrefixes,\n parseStreamPart,\n} from './stream-parts';\n\n// 7-character random string\nexport const nanoid = customAlphabet(\n '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',\n 7,\n);\n\n// simple decoder signatures:\nfunction createChunkDecoder(): (chunk: Uint8Array | undefined) => string;\nfunction createChunkDecoder(\n complex: false,\n): (chunk: Uint8Array | undefined) => string;\n// complex decoder signature:\nfunction createChunkDecoder(\n complex: true,\n): (chunk: Uint8Array | undefined) => StreamPartType[];\n// combined signature for when the client calls this function with a boolean:\nfunction createChunkDecoder(\n complex?: boolean,\n): (chunk: Uint8Array | undefined) => StreamPartType[] | string;\nfunction createChunkDecoder(complex?: boolean) {\n const decoder = new TextDecoder();\n\n if (!complex) {\n return function (chunk: Uint8Array | undefined): string {\n if (!chunk) return '';\n return decoder.decode(chunk, { stream: true });\n };\n }\n\n return function (chunk: Uint8Array | undefined) {\n const decoded = decoder\n .decode(chunk, { stream: true })\n .split('\\n')\n .filter(line => line !== ''); // splitting leaves an empty string at the end\n\n return decoded.map(parseStreamPart).filter(Boolean);\n };\n}\n\nexport { createChunkDecoder };\n\nexport const isStreamStringEqualToType = (\n type: keyof typeof StreamStringPrefixes,\n value: string,\n): value is StreamString =>\n value.startsWith(`${StreamStringPrefixes[type]}:`) && value.endsWith('\\n');\n\nexport type StreamString =\n `${(typeof StreamStringPrefixes)[keyof typeof StreamStringPrefixes]}:${string}\\n`;\n\n/**\n * A header sent to the client so it knows how to handle parsing the stream (as a deprecated text response or using the new prefixed protocol)\n */\nexport const COMPLEX_HEADER = 'X-Experimental-Stream-Data';\n","import { readDataStream } from './read-data-stream';\nimport type { FunctionCall, JSONValue, Message } from './types';\nimport { nanoid } from './utils';\n\ntype PrefixMap = {\n text?: Message;\n function_call?: Message & {\n role: 'assistant';\n function_call: FunctionCall;\n };\n data: JSONValue[];\n};\n\nexport async function parseComplexResponse({\n reader,\n abortControllerRef,\n update,\n onFinish,\n generateId = nanoid,\n getCurrentDate = () => new Date(),\n}: {\n reader: ReadableStreamDefaultReader<Uint8Array>;\n abortControllerRef?: {\n current: AbortController | null;\n };\n update: (merged: Message[], data: JSONValue[] | undefined) => void;\n onFinish?: (prefixMap: PrefixMap) => void;\n generateId?: () => string;\n getCurrentDate?: () => Date;\n}) {\n const createdAt = getCurrentDate();\n const prefixMap: PrefixMap = {\n data: [],\n };\n\n // we create a map of each prefix, and for each prefixed message we push to the map\n for await (const { type, value } of readDataStream(reader, {\n isAborted: () => abortControllerRef?.current === null,\n })) {\n if (type === 'text') {\n if (prefixMap['text']) {\n prefixMap['text'] = {\n ...prefixMap['text'],\n content: (prefixMap['text'].content || '') + value,\n };\n } else {\n prefixMap['text'] = {\n id: generateId(),\n role: 'assistant',\n content: value,\n createdAt,\n };\n }\n }\n\n let functionCallMessage: Message | null = null;\n\n if (type === 'function_call') {\n prefixMap['function_call'] = {\n id: generateId(),\n role: 'assistant',\n content: '',\n function_call: value.function_call,\n name: value.function_call.name,\n createdAt,\n };\n\n functionCallMessage = prefixMap['function_call'];\n }\n\n if (type === 'data') {\n prefixMap['data'].push(...value);\n }\n\n const responseMessage = prefixMap['text'];\n\n // We add function calls and response messages to the messages[], but data is its own thing\n const merged = [functionCallMessage, responseMessage].filter(\n Boolean,\n ) as Message[];\n\n update(merged, [...prefixMap['data']]); // make a copy of the data array\n }\n\n onFinish?.(prefixMap);\n\n return {\n messages: [prefixMap.text, prefixMap.function_call].filter(\n Boolean,\n ) as Message[],\n data: prefixMap.data,\n };\n}\n","import { parseComplexResponse } from './parse-complex-response';\nimport { FunctionCall, IdGenerator, JSONValue, Message } from './types';\nimport { COMPLEX_HEADER, createChunkDecoder } from './utils';\n\nexport async function callChatApi({\n api,\n messages,\n body,\n credentials,\n headers,\n abortController,\n appendMessage,\n restoreMessagesOnFailure,\n onResponse,\n onUpdate,\n onFinish,\n generateId,\n}: {\n api: string;\n messages: Omit<Message, 'id'>[];\n body: Record<string, any>;\n credentials?: RequestCredentials;\n headers?: HeadersInit;\n abortController?: () => AbortController | null;\n restoreMessagesOnFailure: () => void;\n appendMessage: (message: Message) => void;\n onResponse?: (response: Response) => void | Promise<void>;\n onUpdate: (merged: Message[], data: JSONValue[] | undefined) => void;\n onFinish?: (message: Message) => void;\n generateId: IdGenerator;\n}) {\n const response = await fetch(api, {\n method: 'POST',\n body: JSON.stringify({\n messages,\n ...body,\n }),\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n },\n signal: abortController?.()?.signal,\n credentials,\n }).catch(err => {\n restoreMessagesOnFailure();\n throw err;\n });\n\n if (onResponse) {\n try {\n await onResponse(response);\n } catch (err) {\n throw err;\n }\n }\n\n if (!response.ok) {\n restoreMessagesOnFailure();\n throw new Error(\n (await response.text()) || 'Failed to fetch the chat response.',\n );\n }\n\n if (!response.body) {\n throw new Error('The response body is empty.');\n }\n\n const reader = response.body.getReader();\n const isComplexMode = response.headers.get(COMPLEX_HEADER) === 'true';\n\n if (isComplexMode) {\n return await parseComplexResponse({\n reader,\n abortControllerRef:\n abortController != null ? { current: abortController() } : undefined,\n update: onUpdate,\n onFinish(prefixMap) {\n if (onFinish && prefixMap.text != null) {\n onFinish(prefixMap.text);\n }\n },\n generateId,\n });\n } else {\n const createdAt = new Date();\n const decode = createChunkDecoder(false);\n\n // TODO-STREAMDATA: Remove this once Stream Data is not experimental\n let streamedResponse = '';\n const replyId = generateId();\n let responseMessage: Message = {\n id: replyId,\n createdAt,\n content: '',\n role: 'assistant',\n };\n\n // TODO-STREAMDATA: Remove this once Stream Data is not experimental\n while (true) {\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n // Update the chat state with the new message tokens.\n streamedResponse += decode(value);\n\n if (streamedResponse.startsWith('{\"function_call\":')) {\n // While the function call is streaming, it will be a string.\n responseMessage['function_call'] = streamedResponse;\n } else {\n responseMessage['content'] = streamedResponse;\n }\n\n appendMessage({ ...responseMessage });\n\n // The request has been aborted, stop reading the stream.\n if (abortController?.() === null) {\n reader.cancel();\n break;\n }\n }\n\n if (streamedResponse.startsWith('{\"function_call\":')) {\n // Once the stream is complete, the function call is parsed into an object.\n const parsedFunctionCall: FunctionCall =\n JSON.parse(streamedResponse).function_call;\n\n responseMessage['function_call'] = parsedFunctionCall;\n\n appendMessage({ ...responseMessage });\n }\n\n if (onFinish) {\n onFinish(responseMessage);\n }\n\n return responseMessage;\n }\n}\n","import { ChatRequest, FunctionCall, JSONValue, Message } from './types';\n\nexport async function processChatStream({\n getStreamedResponse,\n experimental_onFunctionCall,\n updateChatRequest,\n getCurrentMessages,\n}: {\n getStreamedResponse: () => Promise<\n Message | { messages: Message[]; data: JSONValue[] }\n >;\n experimental_onFunctionCall?: (\n chatMessages: Message[],\n functionCall: FunctionCall,\n ) => Promise<void | ChatRequest>;\n updateChatRequest: (chatRequest: ChatRequest) => void;\n getCurrentMessages: () => Message[];\n}) {\n while (true) {\n // TODO-STREAMDATA: This should be { const { messages: streamedResponseMessages, data } =\n // await getStreamedResponse(} once Stream Data is not experimental\n const messagesAndDataOrJustMessage = await getStreamedResponse();\n\n // Using experimental stream data\n if ('messages' in messagesAndDataOrJustMessage) {\n let hasFollowingResponse = false;\n for (const message of messagesAndDataOrJustMessage.messages) {\n if (\n message.function_call === undefined ||\n typeof message.function_call === 'string'\n ) {\n continue;\n }\n hasFollowingResponse = true;\n // Streamed response is a function call, invoke the function call handler if it exists.\n if (experimental_onFunctionCall) {\n const functionCall = message.function_call;\n\n // User handles the function call in their own functionCallHandler.\n // The \"arguments\" key of the function call object will still be a string which will have to be parsed in the function handler.\n // If the \"arguments\" JSON is malformed due to model error the user will have to handle that themselves.\n\n const functionCallResponse: ChatRequest | void =\n await experimental_onFunctionCall(\n getCurrentMessages(),\n functionCall,\n );\n\n // If the user does not return anything as a result of the function call, the loop will break.\n if (functionCallResponse === undefined) {\n hasFollowingResponse = false;\n break;\n }\n\n // A function call response was returned.\n // The updated chat with function call response will be sent to the API in the next iteration of the loop.\n updateChatRequest(functionCallResponse);\n }\n }\n if (!hasFollowingResponse) {\n break;\n }\n } else {\n const streamedResponseMessage = messagesAndDataOrJustMessage;\n // TODO-STREAMDATA: Remove this once Stream Data is not experimental\n if (\n streamedResponseMessage.function_call === undefined ||\n typeof streamedResponseMessage.function_call === 'string'\n ) {\n break;\n }\n\n // Streamed response is a function call, invoke the function call handler if it exists.\n if (experimental_onFunctionCall) {\n const functionCall = streamedResponseMessage.function_call;\n const functionCallResponse: ChatRequest | void =\n await experimental_onFunctionCall(getCurrentMessages(), functionCall);\n\n // If the user does not return anything as a result of the function call, the loop will break.\n if (functionCallResponse === undefined) break;\n // A function call response was returned.\n // The updated chat with function call response will be sent to the API in the next iteration of the loop.\n updateChatRequest(functionCallResponse);\n }\n }\n }\n}\n","import { Accessor, Resource, Setter, createSignal } from 'solid-js';\nimport { useSWRStore } from 'solid-swr-store';\nimport { createSWRStore } from 'swr-store';\nimport { callCompletionApi } from '../shared/call-completion-api';\nimport type {\n JSONValue,\n RequestOptions,\n UseCompletionOptions,\n} from '../shared/types';\n\nexport type UseCompletionHelpers = {\n /** The current completion result */\n completion: Resource<string>;\n /** The error object of the API request */\n error: Accessor<undefined | Error>;\n /**\n * Send a new prompt to the API endpoint and update the completion state.\n */\n complete: (\n prompt: string,\n options?: RequestOptions,\n ) => Promise<string | null | undefined>;\n /**\n * Abort the current API request but keep the generated tokens.\n */\n stop: () => void;\n /**\n * Update the `completion` state locally.\n */\n setCompletion: (completion: string) => void;\n /** The current value of the input */\n input: Accessor<string>;\n /** Signal Setter to update the input value */\n setInput: Setter<string>;\n /**\n * Form submission handler to automatically reset input and append a user message\n * @example\n * ```jsx\n * <form onSubmit={handleSubmit}>\n * <input value={input()} />\n * </form>\n * ```\n */\n handleSubmit: (e: any) => void;\n /** Whether the API request is in progress */\n isLoading: Accessor<boolean>;\n /** Additional data added on the server via StreamData */\n data: Accessor<JSONValue[] | undefined>;\n};\n\nlet uniqueId = 0;\n\nconst store: Record<string, any> = {};\nconst completionApiStore = createSWRStore<any, string[]>({\n get: async (key: string) => {\n return store[key] ?? [];\n },\n});\n\nexport function useCompletion({\n api = '/api/completion',\n id,\n initialCompletion = '',\n initialInput = '',\n credentials,\n headers,\n body,\n onResponse,\n onFinish,\n onError,\n}: UseCompletionOptions = {}): UseCompletionHelpers {\n // Generate an unique id for the completion if not provided.\n const completionId = id || `completion-${uniqueId++}`;\n\n const key = `${api}|${completionId}`;\n const data = useSWRStore(completionApiStore, () => [key], {\n initialData: initialCompletion,\n });\n\n const mutate = (data: string) => {\n store[key] = data;\n return completionApiStore.mutate([key], {\n data,\n status: 'success',\n });\n };\n\n // Because of the `initialData` option, the `data` will never be `undefined`.\n const completion = data as Resource<string>;\n\n const [error, setError] = createSignal<undefined | Error>(undefined);\n const [streamData, setStreamData] = createSignal<JSONValue[] | undefined>(\n undefined,\n );\n const [isLoading, setIsLoading] = createSignal(false);\n\n let abortController: AbortController | null = null;\n\n const complete: UseCompletionHelpers['complete'] = async (\n prompt: string,\n options?: RequestOptions,\n ) => {\n const existingData = streamData() ?? [];\n return callCompletionApi({\n api,\n prompt,\n credentials,\n headers: {\n ...headers,\n ...options?.headers,\n },\n body: {\n ...body,\n ...options?.body,\n },\n setCompletion: mutate,\n setLoading: setIsLoading,\n setError,\n setAbortController: controller => {\n abortController = controller;\n },\n onResponse,\n onFinish,\n onError,\n onData: data => {\n setStreamData([...existingData, ...(data ?? [])]);\n },\n });\n };\n\n const stop = () => {\n if (abortController) {\n abortController.abort();\n abortController = null;\n }\n };\n\n const setCompletion = (completion: string) => {\n mutate(completion);\n };\n\n const [input, setInput] = createSignal(initialInput);\n\n const handleSubmit = (e: any) => {\n e.preventDefault();\n const inputValue = input();\n if (!inputValue) return;\n return complete(inputValue);\n };\n\n return {\n completion,\n complete,\n error,\n stop,\n setCompletion,\n input,\n setInput,\n handleSubmit,\n isLoading,\n data: streamData,\n };\n}\n","import { readDataStream } from './read-data-stream';\nimport { JSONValue } from './types';\nimport { COMPLEX_HEADER, createChunkDecoder } from './utils';\n\nexport async function callCompletionApi({\n api,\n prompt,\n credentials,\n headers,\n body,\n setCompletion,\n setLoading,\n setError,\n setAbortController,\n onResponse,\n onFinish,\n onError,\n onData,\n}: {\n api: string;\n prompt: string;\n credentials?: RequestCredentials;\n headers?: HeadersInit;\n body: Record<string, any>;\n setCompletion: (completion: string) => void;\n setLoading: (loading: boolean) => void;\n setError: (error: Error | undefined) => void;\n setAbortController: (abortController: AbortController | null) => void;\n onResponse?: (response: Response) => void | Promise<void>;\n onFinish?: (prompt: string, completion: string) => void;\n onError?: (error: Error) => void;\n onData?: (data: JSONValue[]) => void;\n}) {\n try {\n setLoading(true);\n setError(undefined);\n\n const abortController = new AbortController();\n setAbortController(abortController);\n\n // Empty the completion immediately.\n setCompletion('');\n\n const res = await fetch(api, {\n method: 'POST',\n body: JSON.stringify({\n prompt,\n ...body,\n }),\n credentials,\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n },\n signal: abortController.signal,\n }).catch(err => {\n throw err;\n });\n\n if (onResponse) {\n try {\n await onResponse(res);\n } catch (err) {\n throw err;\n }\n }\n\n if (!res.ok) {\n throw new Error(\n (await res.text()) || 'Failed to fetch the chat response.',\n );\n }\n\n if (!res.body) {\n throw new Error('The response body is empty.');\n }\n\n let result = '';\n const reader = res.body.getReader();\n\n const isComplexMode = res.headers.get(COMPLEX_HEADER) === 'true';\n\n if (isComplexMode) {\n for await (const { type, value } of readDataStream(reader, {\n isAborted: () => abortController === null,\n })) {\n switch (type) {\n case 'text': {\n result += value;\n setCompletion(result);\n break;\n }\n case 'data': {\n onData?.(value);\n break;\n }\n }\n }\n } else {\n const decoder = createChunkDecoder();\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n\n // Update the completion state with the new message tokens.\n result += decoder(value);\n setCompletion(result);\n\n // The request has been aborted, stop reading the stream.\n if (abortController === null) {\n reader.cancel();\n break;\n }\n }\n }\n\n if (onFinish) {\n onFinish(prompt, result);\n }\n\n setAbortController(null);\n return result;\n } catch (err) {\n // Ignore abort errors as they are expected.\n if ((err as any).name === 'AbortError') {\n setAbortController(null);\n return null;\n }\n\n if (err instanceof Error) {\n if (onError) {\n onError(err);\n }\n }\n\n setError(err as Error);\n } finally {\n setLoading(false);\n }\n}\n"],"mappings":"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","names":["streamParts","messages","createSignal","useSWRStore","createSWRStore","uniqueId","store","createSWRStore","useSWRStore","data","createSignal","completion"]}
|
1
|
+
{"version":3,"sources":["../use-chat.ts","../../shared/stream-parts.ts","../../shared/read-data-stream.ts","../../shared/utils.ts","../../shared/parse-complex-response.ts","../../shared/call-chat-api.ts","../../shared/process-chat-stream.ts","../use-completion.ts","../../shared/call-completion-api.ts"],"sourcesContent":["import { Accessor, Resource, Setter, createSignal } from 'solid-js';\nimport { useSWRStore } from 'solid-swr-store';\nimport { createSWRStore } from 'swr-store';\nimport { callChatApi } from '../shared/call-chat-api';\nimport { processChatStream } from '../shared/process-chat-stream';\nimport type {\n ChatRequest,\n ChatRequestOptions,\n CreateMessage,\n JSONValue,\n Message,\n UseChatOptions,\n} from '../shared/types';\nimport { nanoid } from '../shared/utils';\n\nexport type { CreateMessage, Message, UseChatOptions };\n\nexport type UseChatHelpers = {\n /** Current messages in the chat */\n messages: Resource<Message[]>;\n /** The error object of the API request */\n error: Accessor<undefined | Error>;\n /**\n * Append a user message to the chat list. This triggers the API call to fetch\n * the assistant's response.\n * @param message The message to append\n * @param options Additional options to pass to the API call\n */\n append: (\n message: Message | CreateMessage,\n chatRequestOptions?: ChatRequestOptions,\n ) => Promise<string | null | undefined>;\n /**\n * Reload the last AI chat response for the given chat history. If the last\n * message isn't from the assistant, it will request the API to generate a\n * new response.\n */\n reload: (\n chatRequestOptions?: ChatRequestOptions,\n ) => Promise<string | null | undefined>;\n /**\n * Abort the current request immediately, keep the generated tokens if any.\n */\n stop: () => void;\n /**\n * Update the `messages` state locally. This is useful when you want to\n * edit the messages on the client, and then trigger the `reload` method\n * manually to regenerate the AI response.\n */\n setMessages: (messages: Message[]) => void;\n /** The current value of the input */\n input: Accessor<string>;\n /** Signal setter to update the input value */\n setInput: Setter<string>;\n /** Form submission handler to automatically reset input and append a user message */\n handleSubmit: (e: any, chatRequestOptions?: ChatRequestOptions) => void;\n /** Whether the API request is in progress */\n isLoading: Accessor<boolean>;\n /** Additional data added on the server via StreamData */\n data: Accessor<JSONValue[] | undefined>;\n};\n\nlet uniqueId = 0;\n\nconst store: Record<string, Message[] | undefined> = {};\nconst chatApiStore = createSWRStore<Message[], string[]>({\n get: async (key: string) => {\n return store[key] ?? [];\n },\n});\n\nexport function useChat({\n api = '/api/chat',\n id,\n initialMessages = [],\n initialInput = '',\n sendExtraMessageFields,\n experimental_onFunctionCall,\n onResponse,\n onFinish,\n onError,\n credentials,\n headers,\n body,\n generateId = nanoid,\n}: UseChatOptions = {}): UseChatHelpers {\n // Generate a unique ID for the chat if not provided.\n const chatId = id || `chat-${uniqueId++}`;\n\n const key = `${api}|${chatId}`;\n\n // Because of the `initialData` option, the `data` will never be `undefined`:\n const messages = useSWRStore(chatApiStore, () => [key], {\n initialData: initialMessages,\n }) as Resource<Message[]>;\n\n const mutate = (data: Message[]) => {\n store[key] = data;\n return chatApiStore.mutate([key], {\n status: 'success',\n data,\n });\n };\n\n const [error, setError] = createSignal<undefined | Error>(undefined);\n const [streamData, setStreamData] = createSignal<JSONValue[] | undefined>(\n undefined,\n );\n const [isLoading, setIsLoading] = createSignal(false);\n\n let abortController: AbortController | null = null;\n async function triggerRequest(\n messagesSnapshot: Message[],\n { options, data }: ChatRequestOptions = {},\n ) {\n try {\n setError(undefined);\n setIsLoading(true);\n\n abortController = new AbortController();\n\n const getCurrentMessages = () =>\n chatApiStore.get([key], {\n shouldRevalidate: false,\n });\n\n // Do an optimistic update to the chat state to show the updated messages\n // immediately.\n const previousMessages = getCurrentMessages();\n mutate(messagesSnapshot);\n\n let chatRequest: ChatRequest = {\n messages: messagesSnapshot,\n options,\n data,\n };\n\n await processChatStream({\n getStreamedResponse: async () => {\n const existingData = streamData() ?? [];\n\n return await callChatApi({\n api,\n messages: sendExtraMessageFields\n ? chatRequest.messages\n : chatRequest.messages.map(\n ({ role, content, name, function_call }) => ({\n role,\n content,\n ...(name !== undefined && { name }),\n ...(function_call !== undefined && {\n function_call,\n }),\n }),\n ),\n body: {\n data: chatRequest.data,\n ...body,\n ...options?.body,\n },\n headers: {\n ...headers,\n ...options?.headers,\n },\n abortController: () => abortController,\n credentials,\n onResponse,\n onUpdate(merged, data) {\n mutate([...chatRequest.messages, ...merged]);\n setStreamData([...existingData, ...(data ?? [])]);\n },\n onFinish,\n appendMessage(message) {\n mutate([...chatRequest.messages, message]);\n },\n restoreMessagesOnFailure() {\n // Restore the previous messages if the request fails.\n if (previousMessages.status === 'success') {\n mutate(previousMessages.data);\n }\n },\n generateId,\n });\n },\n experimental_onFunctionCall,\n updateChatRequest(newChatRequest) {\n chatRequest = newChatRequest;\n },\n getCurrentMessages: () => getCurrentMessages().data,\n });\n\n abortController = null;\n } catch (err) {\n // Ignore abort errors as they are expected.\n if ((err as any).name === 'AbortError') {\n abortController = null;\n return null;\n }\n\n if (onError && err instanceof Error) {\n onError(err);\n }\n\n setError(err as Error);\n } finally {\n setIsLoading(false);\n }\n }\n\n const append: UseChatHelpers['append'] = async (message, options) => {\n if (!message.id) {\n message.id = generateId();\n }\n return triggerRequest(\n (messages() ?? []).concat(message as Message),\n options,\n );\n };\n\n const reload: UseChatHelpers['reload'] = async options => {\n const messagesSnapshot = messages();\n if (!messagesSnapshot || messagesSnapshot.length === 0) return null;\n\n const lastMessage = messagesSnapshot[messagesSnapshot.length - 1];\n if (lastMessage.role === 'assistant') {\n return triggerRequest(messagesSnapshot.slice(0, -1), options);\n }\n return triggerRequest(messagesSnapshot, options);\n };\n\n const stop = () => {\n if (abortController) {\n abortController.abort();\n abortController = null;\n }\n };\n\n const setMessages = (messages: Message[]) => {\n mutate(messages);\n };\n\n const [input, setInput] = createSignal(initialInput);\n\n const handleSubmit = (e: any, options: ChatRequestOptions = {}) => {\n e.preventDefault();\n const inputValue = input();\n if (!inputValue) return;\n\n append(\n {\n content: inputValue,\n role: 'user',\n createdAt: new Date(),\n },\n options,\n );\n\n setInput('');\n };\n\n return {\n messages,\n append,\n error,\n reload,\n stop,\n setMessages,\n input,\n setInput,\n handleSubmit,\n isLoading,\n data: streamData,\n };\n}\n","import {\n AssistantMessage,\n DataMessage,\n FunctionCall,\n JSONValue,\n ToolCall,\n} from './types';\nimport { StreamString } from './utils';\n\nexport interface StreamPart<CODE extends string, NAME extends string, TYPE> {\n code: CODE;\n name: NAME;\n parse: (value: JSONValue) => { type: NAME; value: TYPE };\n}\n\nconst textStreamPart: StreamPart<'0', 'text', string> = {\n code: '0',\n name: 'text',\n parse: (value: JSONValue) => {\n if (typeof value !== 'string') {\n throw new Error('\"text\" parts expect a string value.');\n }\n return { type: 'text', value };\n },\n};\n\nconst functionCallStreamPart: StreamPart<\n '1',\n 'function_call',\n { function_call: FunctionCall }\n> = {\n code: '1',\n name: 'function_call',\n parse: (value: JSONValue) => {\n if (\n value == null ||\n typeof value !== 'object' ||\n !('function_call' in value) ||\n typeof value.function_call !== 'object' ||\n value.function_call == null ||\n !('name' in value.function_call) ||\n !('arguments' in value.function_call) ||\n typeof value.function_call.name !== 'string' ||\n typeof value.function_call.arguments !== 'string'\n ) {\n throw new Error(\n '\"function_call\" parts expect an object with a \"function_call\" property.',\n );\n }\n\n return {\n type: 'function_call',\n value: value as unknown as { function_call: FunctionCall },\n };\n },\n};\n\nconst dataStreamPart: StreamPart<'2', 'data', Array<JSONValue>> = {\n code: '2',\n name: 'data',\n parse: (value: JSONValue) => {\n if (!Array.isArray(value)) {\n throw new Error('\"data\" parts expect an array value.');\n }\n\n return { type: 'data', value };\n },\n};\n\nconst errorStreamPart: StreamPart<'3', 'error', string> = {\n code: '3',\n name: 'error',\n parse: (value: JSONValue) => {\n if (typeof value !== 'string') {\n throw new Error('\"error\" parts expect a string value.');\n }\n return { type: 'error', value };\n },\n};\n\nconst assistantMessageStreamPart: StreamPart<\n '4',\n 'assistant_message',\n AssistantMessage\n> = {\n code: '4',\n name: 'assistant_message',\n parse: (value: JSONValue) => {\n if (\n value == null ||\n typeof value !== 'object' ||\n !('id' in value) ||\n !('role' in value) ||\n !('content' in value) ||\n typeof value.id !== 'string' ||\n typeof value.role !== 'string' ||\n value.role !== 'assistant' ||\n !Array.isArray(value.content) ||\n !value.content.every(\n item =>\n item != null &&\n typeof item === 'object' &&\n 'type' in item &&\n item.type === 'text' &&\n 'text' in item &&\n item.text != null &&\n typeof item.text === 'object' &&\n 'value' in item.text &&\n typeof item.text.value === 'string',\n )\n ) {\n throw new Error(\n '\"assistant_message\" parts expect an object with an \"id\", \"role\", and \"content\" property.',\n );\n }\n\n return {\n type: 'assistant_message',\n value: value as AssistantMessage,\n };\n },\n};\n\nconst assistantControlDataStreamPart: StreamPart<\n '5',\n 'assistant_control_data',\n {\n threadId: string;\n messageId: string;\n }\n> = {\n code: '5',\n name: 'assistant_control_data',\n parse: (value: JSONValue) => {\n if (\n value == null ||\n typeof value !== 'object' ||\n !('threadId' in value) ||\n !('messageId' in value) ||\n typeof value.threadId !== 'string' ||\n typeof value.messageId !== 'string'\n ) {\n throw new Error(\n '\"assistant_control_data\" parts expect an object with a \"threadId\" and \"messageId\" property.',\n );\n }\n\n return {\n type: 'assistant_control_data',\n value: {\n threadId: value.threadId,\n messageId: value.messageId,\n },\n };\n },\n};\n\nconst dataMessageStreamPart: StreamPart<'6', 'data_message', DataMessage> = {\n code: '6',\n name: 'data_message',\n parse: (value: JSONValue) => {\n if (\n value == null ||\n typeof value !== 'object' ||\n !('role' in value) ||\n !('data' in value) ||\n typeof value.role !== 'string' ||\n value.role !== 'data'\n ) {\n throw new Error(\n '\"data_message\" parts expect an object with a \"role\" and \"data\" property.',\n );\n }\n\n return {\n type: 'data_message',\n value: value as DataMessage,\n };\n },\n};\n\nconst toolCallStreamPart: StreamPart<\n '7',\n 'tool_calls',\n { tool_calls: ToolCall[] }\n> = {\n code: '7',\n name: 'tool_calls',\n parse: (value: JSONValue) => {\n if (\n value == null ||\n typeof value !== 'object' ||\n !('tool_calls' in value) ||\n typeof value.tool_calls !== 'object' ||\n value.tool_calls == null ||\n !Array.isArray(value.tool_calls) ||\n value.tool_calls.some(tc => {\n tc == null ||\n typeof tc !== 'object' ||\n !('id' in tc) ||\n typeof tc.id !== 'string' ||\n !('type' in tc) ||\n typeof tc.type !== 'string' ||\n !('function' in tc) ||\n tc.function == null ||\n typeof tc.function !== 'object' ||\n !('arguments' in tc.function) ||\n typeof tc.function.name !== 'string' ||\n typeof tc.function.arguments !== 'string';\n })\n ) {\n throw new Error(\n '\"tool_calls\" parts expect an object with a ToolCallPayload.',\n );\n }\n\n return {\n type: 'tool_calls',\n value: value as unknown as { tool_calls: ToolCall[] },\n };\n },\n};\n\nconst streamParts = [\n textStreamPart,\n functionCallStreamPart,\n dataStreamPart,\n errorStreamPart,\n assistantMessageStreamPart,\n assistantControlDataStreamPart,\n dataMessageStreamPart,\n toolCallStreamPart,\n] as const;\n\n// union type of all stream parts\ntype StreamParts =\n | typeof textStreamPart\n | typeof functionCallStreamPart\n | typeof dataStreamPart\n | typeof errorStreamPart\n | typeof assistantMessageStreamPart\n | typeof assistantControlDataStreamPart\n | typeof dataMessageStreamPart\n | typeof toolCallStreamPart;\n\n/**\n * Maps the type of a stream part to its value type.\n */\ntype StreamPartValueType = {\n [P in StreamParts as P['name']]: ReturnType<P['parse']>['value'];\n};\n\nexport type StreamPartType =\n | ReturnType<typeof textStreamPart.parse>\n | ReturnType<typeof functionCallStreamPart.parse>\n | ReturnType<typeof dataStreamPart.parse>\n | ReturnType<typeof errorStreamPart.parse>\n | ReturnType<typeof assistantMessageStreamPart.parse>\n | ReturnType<typeof assistantControlDataStreamPart.parse>\n | ReturnType<typeof dataMessageStreamPart.parse>\n | ReturnType<typeof toolCallStreamPart.parse>;\n\nexport const streamPartsByCode = {\n [textStreamPart.code]: textStreamPart,\n [functionCallStreamPart.code]: functionCallStreamPart,\n [dataStreamPart.code]: dataStreamPart,\n [errorStreamPart.code]: errorStreamPart,\n [assistantMessageStreamPart.code]: assistantMessageStreamPart,\n [assistantControlDataStreamPart.code]: assistantControlDataStreamPart,\n [dataMessageStreamPart.code]: dataMessageStreamPart,\n [toolCallStreamPart.code]: toolCallStreamPart,\n} as const;\n\n/**\n * The map of prefixes for data in the stream\n *\n * - 0: Text from the LLM response\n * - 1: (OpenAI) function_call responses\n * - 2: custom JSON added by the user using `Data`\n * - 6: (OpenAI) tool_call responses\n *\n * Example:\n * ```\n * 0:Vercel\n * 0:'s\n * 0: AI\n * 0: AI\n * 0: SDK\n * 0: is great\n * 0:!\n * 2: { \"someJson\": \"value\" }\n * 1: {\"function_call\": {\"name\": \"get_current_weather\", \"arguments\": \"{\\\\n\\\\\"location\\\\\": \\\\\"Charlottesville, Virginia\\\\\",\\\\n\\\\\"format\\\\\": \\\\\"celsius\\\\\"\\\\n}\"}}\n * 6: {\"tool_call\": {\"id\": \"tool_0\", \"type\": \"function\", \"function\": {\"name\": \"get_current_weather\", \"arguments\": \"{\\\\n\\\\\"location\\\\\": \\\\\"Charlottesville, Virginia\\\\\",\\\\n\\\\\"format\\\\\": \\\\\"celsius\\\\\"\\\\n}\"}}}\n *```\n */\nexport const StreamStringPrefixes = {\n [textStreamPart.name]: textStreamPart.code,\n [functionCallStreamPart.name]: functionCallStreamPart.code,\n [dataStreamPart.name]: dataStreamPart.code,\n [errorStreamPart.name]: errorStreamPart.code,\n [assistantMessageStreamPart.name]: assistantMessageStreamPart.code,\n [assistantControlDataStreamPart.name]: assistantControlDataStreamPart.code,\n [dataMessageStreamPart.name]: dataMessageStreamPart.code,\n [toolCallStreamPart.name]: toolCallStreamPart.code,\n} as const;\n\nexport const validCodes = streamParts.map(part => part.code);\n\n/**\n * Parses a stream part from a string.\n *\n * @param line The string to parse.\n * @returns The parsed stream part.\n * @throws An error if the string cannot be parsed.\n */\nexport const parseStreamPart = (line: string): StreamPartType => {\n const firstSeparatorIndex = line.indexOf(':');\n\n if (firstSeparatorIndex === -1) {\n throw new Error('Failed to parse stream string. No separator found.');\n }\n\n const prefix = line.slice(0, firstSeparatorIndex);\n\n if (!validCodes.includes(prefix as keyof typeof streamPartsByCode)) {\n throw new Error(`Failed to parse stream string. Invalid code ${prefix}.`);\n }\n\n const code = prefix as keyof typeof streamPartsByCode;\n\n const textValue = line.slice(firstSeparatorIndex + 1);\n const jsonValue: JSONValue = JSON.parse(textValue);\n\n return streamPartsByCode[code].parse(jsonValue);\n};\n\n/**\n * Prepends a string with a prefix from the `StreamChunkPrefixes`, JSON-ifies it,\n * and appends a new line.\n *\n * It ensures type-safety for the part type and value.\n */\nexport function formatStreamPart<T extends keyof StreamPartValueType>(\n type: T,\n value: StreamPartValueType[T],\n): StreamString {\n const streamPart = streamParts.find(part => part.name === type);\n\n if (!streamPart) {\n throw new Error(`Invalid stream part type: ${type}`);\n }\n\n return `${streamPart.code}:${JSON.stringify(value)}\\n`;\n}\n","import { StreamPartType, parseStreamPart } from './stream-parts';\n\nconst NEWLINE = '\\n'.charCodeAt(0);\n\n// concatenates all the chunks into a single Uint8Array\nfunction concatChunks(chunks: Uint8Array[], totalLength: number) {\n const concatenatedChunks = new Uint8Array(totalLength);\n\n let offset = 0;\n for (const chunk of chunks) {\n concatenatedChunks.set(chunk, offset);\n offset += chunk.length;\n }\n chunks.length = 0;\n\n return concatenatedChunks;\n}\n\nexport async function* readDataStream(\n reader: ReadableStreamDefaultReader<Uint8Array>,\n {\n isAborted,\n }: {\n isAborted?: () => boolean;\n } = {},\n): AsyncGenerator<StreamPartType> {\n // implementation note: this slightly more complex algorithm is required\n // to pass the tests in the edge environment.\n\n const decoder = new TextDecoder();\n const chunks: Uint8Array[] = [];\n let totalLength = 0;\n\n while (true) {\n const { value } = await reader.read();\n\n if (value) {\n chunks.push(value);\n totalLength += value.length;\n if (value[value.length - 1] !== NEWLINE) {\n // if the last character is not a newline, we have not read the whole JSON value\n continue;\n }\n }\n\n if (chunks.length === 0) {\n break; // we have reached the end of the stream\n }\n\n const concatenatedChunks = concatChunks(chunks, totalLength);\n totalLength = 0;\n\n const streamParts = decoder\n .decode(concatenatedChunks, { stream: true })\n .split('\\n')\n .filter(line => line !== '') // splitting leaves an empty string at the end\n .map(parseStreamPart);\n\n for (const streamPart of streamParts) {\n yield streamPart;\n }\n\n // The request has been aborted, stop reading the stream.\n if (isAborted?.()) {\n reader.cancel();\n break;\n }\n }\n}\n","import { customAlphabet } from 'nanoid/non-secure';\nimport {\n StreamPartType,\n StreamStringPrefixes,\n parseStreamPart,\n} from './stream-parts';\n\n// 7-character random string\nexport const nanoid = customAlphabet(\n '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',\n 7,\n);\n\n// simple decoder signatures:\nfunction createChunkDecoder(): (chunk: Uint8Array | undefined) => string;\nfunction createChunkDecoder(\n complex: false,\n): (chunk: Uint8Array | undefined) => string;\n// complex decoder signature:\nfunction createChunkDecoder(\n complex: true,\n): (chunk: Uint8Array | undefined) => StreamPartType[];\n// combined signature for when the client calls this function with a boolean:\nfunction createChunkDecoder(\n complex?: boolean,\n): (chunk: Uint8Array | undefined) => StreamPartType[] | string;\nfunction createChunkDecoder(complex?: boolean) {\n const decoder = new TextDecoder();\n\n if (!complex) {\n return function (chunk: Uint8Array | undefined): string {\n if (!chunk) return '';\n return decoder.decode(chunk, { stream: true });\n };\n }\n\n return function (chunk: Uint8Array | undefined) {\n const decoded = decoder\n .decode(chunk, { stream: true })\n .split('\\n')\n .filter(line => line !== ''); // splitting leaves an empty string at the end\n\n return decoded.map(parseStreamPart).filter(Boolean);\n };\n}\n\nexport { createChunkDecoder };\n\nexport const isStreamStringEqualToType = (\n type: keyof typeof StreamStringPrefixes,\n value: string,\n): value is StreamString =>\n value.startsWith(`${StreamStringPrefixes[type]}:`) && value.endsWith('\\n');\n\nexport type StreamString =\n `${(typeof StreamStringPrefixes)[keyof typeof StreamStringPrefixes]}:${string}\\n`;\n\n/**\n * A header sent to the client so it knows how to handle parsing the stream (as a deprecated text response or using the new prefixed protocol)\n */\nexport const COMPLEX_HEADER = 'X-Experimental-Stream-Data';\n","import { readDataStream } from './read-data-stream';\nimport type { FunctionCall, JSONValue, Message, ToolCall } from './types';\nimport { nanoid } from './utils';\n\ntype PrefixMap = {\n text?: Message;\n function_call?: Message & {\n role: 'assistant';\n function_call: FunctionCall;\n };\n tool_calls?: Message & {\n role: 'assistant';\n tool_calls: ToolCall[];\n };\n data: JSONValue[];\n};\n\nexport async function parseComplexResponse({\n reader,\n abortControllerRef,\n update,\n onFinish,\n generateId = nanoid,\n getCurrentDate = () => new Date(),\n}: {\n reader: ReadableStreamDefaultReader<Uint8Array>;\n abortControllerRef?: {\n current: AbortController | null;\n };\n update: (merged: Message[], data: JSONValue[] | undefined) => void;\n onFinish?: (prefixMap: PrefixMap) => void;\n generateId?: () => string;\n getCurrentDate?: () => Date;\n}) {\n const createdAt = getCurrentDate();\n const prefixMap: PrefixMap = {\n data: [],\n };\n\n // we create a map of each prefix, and for each prefixed message we push to the map\n for await (const { type, value } of readDataStream(reader, {\n isAborted: () => abortControllerRef?.current === null,\n })) {\n if (type === 'text') {\n if (prefixMap['text']) {\n prefixMap['text'] = {\n ...prefixMap['text'],\n content: (prefixMap['text'].content || '') + value,\n };\n } else {\n prefixMap['text'] = {\n id: generateId(),\n role: 'assistant',\n content: value,\n createdAt,\n };\n }\n }\n\n let functionCallMessage: Message | null = null;\n\n if (type === 'function_call') {\n prefixMap['function_call'] = {\n id: generateId(),\n role: 'assistant',\n content: '',\n function_call: value.function_call,\n name: value.function_call.name,\n createdAt,\n };\n\n functionCallMessage = prefixMap['function_call'];\n }\n\n let toolCallMessage: Message | null = null;\n\n if (type === 'tool_calls') {\n prefixMap['tool_calls'] = {\n id: generateId(),\n role: 'assistant',\n content: '',\n tool_calls: value.tool_calls,\n createdAt,\n };\n\n toolCallMessage = prefixMap['tool_calls'];\n }\n\n if (type === 'data') {\n prefixMap['data'].push(...value);\n }\n\n const responseMessage = prefixMap['text'];\n\n // We add function & tool calls and response messages to the messages[], but data is its own thing\n const merged = [\n functionCallMessage,\n toolCallMessage,\n responseMessage,\n ].filter(Boolean) as Message[];\n\n update(merged, [...prefixMap['data']]); // make a copy of the data array\n }\n\n onFinish?.(prefixMap);\n\n return {\n messages: [\n prefixMap.text,\n prefixMap.function_call,\n prefixMap.tool_calls,\n ].filter(Boolean) as Message[],\n data: prefixMap.data,\n };\n}\n","import { parseComplexResponse } from './parse-complex-response';\nimport {\n FunctionCall,\n IdGenerator,\n JSONValue,\n Message,\n ToolCall,\n} from './types';\nimport { COMPLEX_HEADER, createChunkDecoder } from './utils';\n\nexport async function callChatApi({\n api,\n messages,\n body,\n credentials,\n headers,\n abortController,\n appendMessage,\n restoreMessagesOnFailure,\n onResponse,\n onUpdate,\n onFinish,\n generateId,\n}: {\n api: string;\n messages: Omit<Message, 'id'>[];\n body: Record<string, any>;\n credentials?: RequestCredentials;\n headers?: HeadersInit;\n abortController?: () => AbortController | null;\n restoreMessagesOnFailure: () => void;\n appendMessage: (message: Message) => void;\n onResponse?: (response: Response) => void | Promise<void>;\n onUpdate: (merged: Message[], data: JSONValue[] | undefined) => void;\n onFinish?: (message: Message) => void;\n generateId: IdGenerator;\n}) {\n const response = await fetch(api, {\n method: 'POST',\n body: JSON.stringify({\n messages,\n ...body,\n }),\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n },\n signal: abortController?.()?.signal,\n credentials,\n }).catch(err => {\n restoreMessagesOnFailure();\n throw err;\n });\n\n if (onResponse) {\n try {\n await onResponse(response);\n } catch (err) {\n throw err;\n }\n }\n\n if (!response.ok) {\n restoreMessagesOnFailure();\n throw new Error(\n (await response.text()) || 'Failed to fetch the chat response.',\n );\n }\n\n if (!response.body) {\n throw new Error('The response body is empty.');\n }\n\n const reader = response.body.getReader();\n const isComplexMode = response.headers.get(COMPLEX_HEADER) === 'true';\n\n if (isComplexMode) {\n return await parseComplexResponse({\n reader,\n abortControllerRef:\n abortController != null ? { current: abortController() } : undefined,\n update: onUpdate,\n onFinish(prefixMap) {\n if (onFinish && prefixMap.text != null) {\n onFinish(prefixMap.text);\n }\n },\n generateId,\n });\n } else {\n const createdAt = new Date();\n const decode = createChunkDecoder(false);\n\n // TODO-STREAMDATA: Remove this once Stream Data is not experimental\n let streamedResponse = '';\n const replyId = generateId();\n let responseMessage: Message = {\n id: replyId,\n createdAt,\n content: '',\n role: 'assistant',\n };\n\n // TODO-STREAMDATA: Remove this once Stream Data is not experimental\n while (true) {\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n // Update the chat state with the new message tokens.\n streamedResponse += decode(value);\n\n if (streamedResponse.startsWith('{\"function_call\":')) {\n // While the function call is streaming, it will be a string.\n responseMessage['function_call'] = streamedResponse;\n } else if (streamedResponse.startsWith('{\"tool_calls\":')) {\n // While the tool calls are streaming, it will be a string.\n responseMessage['tool_calls'] = streamedResponse;\n } else {\n responseMessage['content'] = streamedResponse;\n }\n\n appendMessage({ ...responseMessage });\n\n // The request has been aborted, stop reading the stream.\n if (abortController?.() === null) {\n reader.cancel();\n break;\n }\n }\n\n if (streamedResponse.startsWith('{\"function_call\":')) {\n // Once the stream is complete, the function call is parsed into an object.\n const parsedFunctionCall: FunctionCall =\n JSON.parse(streamedResponse).function_call;\n\n responseMessage['function_call'] = parsedFunctionCall;\n\n appendMessage({ ...responseMessage });\n }\n if (streamedResponse.startsWith('{\"tool_calls\":')) {\n // Once the stream is complete, the tool calls are parsed into an array.\n const parsedToolCalls: ToolCall[] =\n JSON.parse(streamedResponse).tool_calls;\n\n responseMessage['tool_calls'] = parsedToolCalls;\n\n appendMessage({ ...responseMessage });\n }\n\n if (onFinish) {\n onFinish(responseMessage);\n }\n\n return responseMessage;\n }\n}\n","import {\n ChatRequest,\n FunctionCall,\n JSONValue,\n Message,\n ToolCall,\n} from './types';\n\nexport async function processChatStream({\n getStreamedResponse,\n experimental_onFunctionCall,\n experimental_onToolCall,\n updateChatRequest,\n getCurrentMessages,\n}: {\n getStreamedResponse: () => Promise<\n Message | { messages: Message[]; data: JSONValue[] }\n >;\n experimental_onFunctionCall?: (\n chatMessages: Message[],\n functionCall: FunctionCall,\n ) => Promise<void | ChatRequest>;\n experimental_onToolCall?: (\n chatMessages: Message[],\n toolCalls: ToolCall[],\n ) => Promise<void | ChatRequest>;\n updateChatRequest: (chatRequest: ChatRequest) => void;\n getCurrentMessages: () => Message[];\n}) {\n while (true) {\n // TODO-STREAMDATA: This should be { const { messages: streamedResponseMessages, data } =\n // await getStreamedResponse(} once Stream Data is not experimental\n const messagesAndDataOrJustMessage = await getStreamedResponse();\n\n // Using experimental stream data\n if ('messages' in messagesAndDataOrJustMessage) {\n let hasFollowingResponse = false;\n\n for (const message of messagesAndDataOrJustMessage.messages) {\n // See if the message has a complete function call or tool call\n if (\n (message.function_call === undefined ||\n typeof message.function_call === 'string') &&\n (message.tool_calls === undefined ||\n typeof message.tool_calls === 'string')\n ) {\n continue;\n }\n\n hasFollowingResponse = true;\n // Try to handle function call\n if (experimental_onFunctionCall) {\n const functionCall = message.function_call;\n // Make sure functionCall is an object\n // If not, we got tool calls instead of function calls\n if (typeof functionCall !== 'object') {\n console.warn(\n 'experimental_onFunctionCall should not be defined when using tools',\n );\n continue;\n }\n\n // User handles the function call in their own functionCallHandler.\n // The \"arguments\" key of the function call object will still be a string which will have to be parsed in the function handler.\n // If the \"arguments\" JSON is malformed due to model error the user will have to handle that themselves.\n\n const functionCallResponse: ChatRequest | void =\n await experimental_onFunctionCall(\n getCurrentMessages(),\n functionCall,\n );\n\n // If the user does not return anything as a result of the function call, the loop will break.\n if (functionCallResponse === undefined) {\n hasFollowingResponse = false;\n break;\n }\n\n // A function call response was returned.\n // The updated chat with function call response will be sent to the API in the next iteration of the loop.\n updateChatRequest(functionCallResponse);\n }\n // Try to handle tool call\n if (experimental_onToolCall) {\n const toolCalls = message.tool_calls;\n // Make sure toolCalls is an array of objects\n // If not, we got function calls instead of tool calls\n if (\n !Array.isArray(toolCalls) ||\n toolCalls.some(toolCall => typeof toolCall !== 'object')\n ) {\n console.warn(\n 'experimental_onToolCall should not be defined when using tools',\n );\n continue;\n }\n\n // User handles the function call in their own functionCallHandler.\n // The \"arguments\" key of the function call object will still be a string which will have to be parsed in the function handler.\n // If the \"arguments\" JSON is malformed due to model error the user will have to handle that themselves.\n const toolCallResponse: ChatRequest | void =\n await experimental_onToolCall(getCurrentMessages(), toolCalls);\n\n // If the user does not return anything as a result of the function call, the loop will break.\n if (toolCallResponse === undefined) {\n hasFollowingResponse = false;\n break;\n }\n\n // A function call response was returned.\n // The updated chat with function call response will be sent to the API in the next iteration of the loop.\n updateChatRequest(toolCallResponse);\n }\n }\n if (!hasFollowingResponse) {\n break;\n }\n } else {\n const streamedResponseMessage = messagesAndDataOrJustMessage;\n\n // TODO-STREAMDATA: Remove this once Stream Data is not experimental\n if (\n (streamedResponseMessage.function_call === undefined ||\n typeof streamedResponseMessage.function_call === 'string') &&\n (streamedResponseMessage.tool_calls === undefined ||\n typeof streamedResponseMessage.tool_calls === 'string')\n ) {\n break;\n }\n\n // If we get here and are expecting a function call, the message should have one, if not warn and continue\n if (experimental_onFunctionCall) {\n const functionCall = streamedResponseMessage.function_call;\n if (!(typeof functionCall === 'object')) {\n console.warn(\n 'experimental_onFunctionCall should not be defined when using tools',\n );\n continue;\n }\n const functionCallResponse: ChatRequest | void =\n await experimental_onFunctionCall(getCurrentMessages(), functionCall);\n\n // If the user does not return anything as a result of the function call, the loop will break.\n if (functionCallResponse === undefined) break;\n // A function call response was returned.\n // The updated chat with function call response will be sent to the API in the next iteration of the loop.\n fixFunctionCallArguments(functionCallResponse);\n updateChatRequest(functionCallResponse);\n }\n // If we get here and are expecting a tool call, the message should have one, if not warn and continue\n if (experimental_onToolCall) {\n const toolCalls = streamedResponseMessage.tool_calls;\n if (!(typeof toolCalls === 'object')) {\n console.warn(\n 'experimental_onToolCall should not be defined when using functions',\n );\n continue;\n }\n const toolCallResponse: ChatRequest | void =\n await experimental_onToolCall(getCurrentMessages(), toolCalls);\n\n // If the user does not return anything as a result of the function call, the loop will break.\n if (toolCallResponse === undefined) break;\n // A function call response was returned.\n // The updated chat with function call response will be sent to the API in the next iteration of the loop.\n fixFunctionCallArguments(toolCallResponse);\n updateChatRequest(toolCallResponse);\n }\n\n // Make sure function call arguments are sent back to the API as a string\n function fixFunctionCallArguments(response: ChatRequest) {\n for (const message of response.messages) {\n if (message.tool_calls !== undefined) {\n for (const toolCall of message.tool_calls) {\n if (typeof toolCall === 'object') {\n if (\n toolCall.function.arguments &&\n typeof toolCall.function.arguments !== 'string'\n ) {\n toolCall.function.arguments = JSON.stringify(\n toolCall.function.arguments,\n );\n }\n }\n }\n }\n if (message.function_call !== undefined) {\n if (typeof message.function_call === 'object') {\n if (\n message.function_call.arguments &&\n typeof message.function_call.arguments !== 'string'\n ) {\n message.function_call.arguments = JSON.stringify(\n message.function_call.arguments,\n );\n }\n }\n }\n }\n }\n }\n }\n}\n","import { Accessor, Resource, Setter, createSignal } from 'solid-js';\nimport { useSWRStore } from 'solid-swr-store';\nimport { createSWRStore } from 'swr-store';\nimport { callCompletionApi } from '../shared/call-completion-api';\nimport type {\n JSONValue,\n RequestOptions,\n UseCompletionOptions,\n} from '../shared/types';\n\nexport type UseCompletionHelpers = {\n /** The current completion result */\n completion: Resource<string>;\n /** The error object of the API request */\n error: Accessor<undefined | Error>;\n /**\n * Send a new prompt to the API endpoint and update the completion state.\n */\n complete: (\n prompt: string,\n options?: RequestOptions,\n ) => Promise<string | null | undefined>;\n /**\n * Abort the current API request but keep the generated tokens.\n */\n stop: () => void;\n /**\n * Update the `completion` state locally.\n */\n setCompletion: (completion: string) => void;\n /** The current value of the input */\n input: Accessor<string>;\n /** Signal Setter to update the input value */\n setInput: Setter<string>;\n /**\n * Form submission handler to automatically reset input and append a user message\n * @example\n * ```jsx\n * <form onSubmit={handleSubmit}>\n * <input value={input()} />\n * </form>\n * ```\n */\n handleSubmit: (e: any) => void;\n /** Whether the API request is in progress */\n isLoading: Accessor<boolean>;\n /** Additional data added on the server via StreamData */\n data: Accessor<JSONValue[] | undefined>;\n};\n\nlet uniqueId = 0;\n\nconst store: Record<string, any> = {};\nconst completionApiStore = createSWRStore<any, string[]>({\n get: async (key: string) => {\n return store[key] ?? [];\n },\n});\n\nexport function useCompletion({\n api = '/api/completion',\n id,\n initialCompletion = '',\n initialInput = '',\n credentials,\n headers,\n body,\n onResponse,\n onFinish,\n onError,\n}: UseCompletionOptions = {}): UseCompletionHelpers {\n // Generate an unique id for the completion if not provided.\n const completionId = id || `completion-${uniqueId++}`;\n\n const key = `${api}|${completionId}`;\n const data = useSWRStore(completionApiStore, () => [key], {\n initialData: initialCompletion,\n });\n\n const mutate = (data: string) => {\n store[key] = data;\n return completionApiStore.mutate([key], {\n data,\n status: 'success',\n });\n };\n\n // Because of the `initialData` option, the `data` will never be `undefined`.\n const completion = data as Resource<string>;\n\n const [error, setError] = createSignal<undefined | Error>(undefined);\n const [streamData, setStreamData] = createSignal<JSONValue[] | undefined>(\n undefined,\n );\n const [isLoading, setIsLoading] = createSignal(false);\n\n let abortController: AbortController | null = null;\n\n const complete: UseCompletionHelpers['complete'] = async (\n prompt: string,\n options?: RequestOptions,\n ) => {\n const existingData = streamData() ?? [];\n return callCompletionApi({\n api,\n prompt,\n credentials,\n headers: {\n ...headers,\n ...options?.headers,\n },\n body: {\n ...body,\n ...options?.body,\n },\n setCompletion: mutate,\n setLoading: setIsLoading,\n setError,\n setAbortController: controller => {\n abortController = controller;\n },\n onResponse,\n onFinish,\n onError,\n onData: data => {\n setStreamData([...existingData, ...(data ?? [])]);\n },\n });\n };\n\n const stop = () => {\n if (abortController) {\n abortController.abort();\n abortController = null;\n }\n };\n\n const setCompletion = (completion: string) => {\n mutate(completion);\n };\n\n const [input, setInput] = createSignal(initialInput);\n\n const handleSubmit = (e: any) => {\n e.preventDefault();\n const inputValue = input();\n if (!inputValue) return;\n return complete(inputValue);\n };\n\n return {\n completion,\n complete,\n error,\n stop,\n setCompletion,\n input,\n setInput,\n handleSubmit,\n isLoading,\n data: streamData,\n };\n}\n","import { readDataStream } from './read-data-stream';\nimport { JSONValue } from './types';\nimport { COMPLEX_HEADER, createChunkDecoder } from './utils';\n\nexport async function callCompletionApi({\n api,\n prompt,\n credentials,\n headers,\n body,\n setCompletion,\n setLoading,\n setError,\n setAbortController,\n onResponse,\n onFinish,\n onError,\n onData,\n}: {\n api: string;\n prompt: string;\n credentials?: RequestCredentials;\n headers?: HeadersInit;\n body: Record<string, any>;\n setCompletion: (completion: string) => void;\n setLoading: (loading: boolean) => void;\n setError: (error: Error | undefined) => void;\n setAbortController: (abortController: AbortController | null) => void;\n onResponse?: (response: Response) => void | Promise<void>;\n onFinish?: (prompt: string, completion: string) => void;\n onError?: (error: Error) => void;\n onData?: (data: JSONValue[]) => void;\n}) {\n try {\n setLoading(true);\n setError(undefined);\n\n const abortController = new AbortController();\n setAbortController(abortController);\n\n // Empty the completion immediately.\n setCompletion('');\n\n const res = await fetch(api, {\n method: 'POST',\n body: JSON.stringify({\n prompt,\n ...body,\n }),\n credentials,\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n },\n signal: abortController.signal,\n }).catch(err => {\n throw err;\n });\n\n if (onResponse) {\n try {\n await onResponse(res);\n } catch (err) {\n throw err;\n }\n }\n\n if (!res.ok) {\n throw new Error(\n (await res.text()) || 'Failed to fetch the chat response.',\n );\n }\n\n if (!res.body) {\n throw new Error('The response body is empty.');\n }\n\n let result = '';\n const reader = res.body.getReader();\n\n const isComplexMode = res.headers.get(COMPLEX_HEADER) === 'true';\n\n if (isComplexMode) {\n for await (const { type, value } of readDataStream(reader, {\n isAborted: () => abortController === null,\n })) {\n switch (type) {\n case 'text': {\n result += value;\n setCompletion(result);\n break;\n }\n case 'data': {\n onData?.(value);\n break;\n }\n }\n }\n } else {\n const decoder = createChunkDecoder();\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n\n // Update the completion state with the new message tokens.\n result += decoder(value);\n setCompletion(result);\n\n // The request has been aborted, stop reading the stream.\n if (abortController === null) {\n reader.cancel();\n break;\n }\n }\n }\n\n if (onFinish) {\n onFinish(prompt, result);\n }\n\n setAbortController(null);\n return result;\n } catch (err) {\n // Ignore abort errors as they are expected.\n if ((err as any).name === 'AbortError') {\n setAbortController(null);\n return null;\n }\n\n if (err instanceof Error) {\n if (onError) {\n onError(err);\n }\n }\n\n setError(err as Error);\n } finally {\n setLoading(false);\n }\n}\n"],"mappings":"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","names":["streamParts","fixFunctionCallArguments","data","messages","createSignal","useSWRStore","createSWRStore","uniqueId","store","createSWRStore","useSWRStore","data","createSignal","completion"]}
|