ai 2.2.29 → 2.2.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.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 +97 -11
- package/react/dist/index.js +169 -24
- package/react/dist/index.js.map +1 -1
- package/react/dist/index.mjs +169 -24
- 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.js
CHANGED
@@ -126,6 +126,23 @@ var dataMessageStreamPart = {
|
|
126
126
|
};
|
127
127
|
}
|
128
128
|
};
|
129
|
+
var toolCallStreamPart = {
|
130
|
+
code: "7",
|
131
|
+
name: "tool_calls",
|
132
|
+
parse: (value) => {
|
133
|
+
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) => {
|
134
|
+
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";
|
135
|
+
})) {
|
136
|
+
throw new Error(
|
137
|
+
'"tool_calls" parts expect an object with a ToolCallPayload.'
|
138
|
+
);
|
139
|
+
}
|
140
|
+
return {
|
141
|
+
type: "tool_calls",
|
142
|
+
value
|
143
|
+
};
|
144
|
+
}
|
145
|
+
};
|
129
146
|
var streamParts = [
|
130
147
|
textStreamPart,
|
131
148
|
functionCallStreamPart,
|
@@ -133,7 +150,8 @@ var streamParts = [
|
|
133
150
|
errorStreamPart,
|
134
151
|
assistantMessageStreamPart,
|
135
152
|
assistantControlDataStreamPart,
|
136
|
-
dataMessageStreamPart
|
153
|
+
dataMessageStreamPart,
|
154
|
+
toolCallStreamPart
|
137
155
|
];
|
138
156
|
var streamPartsByCode = {
|
139
157
|
[textStreamPart.code]: textStreamPart,
|
@@ -142,7 +160,8 @@ var streamPartsByCode = {
|
|
142
160
|
[errorStreamPart.code]: errorStreamPart,
|
143
161
|
[assistantMessageStreamPart.code]: assistantMessageStreamPart,
|
144
162
|
[assistantControlDataStreamPart.code]: assistantControlDataStreamPart,
|
145
|
-
[dataMessageStreamPart.code]: dataMessageStreamPart
|
163
|
+
[dataMessageStreamPart.code]: dataMessageStreamPart,
|
164
|
+
[toolCallStreamPart.code]: toolCallStreamPart
|
146
165
|
};
|
147
166
|
var StreamStringPrefixes = {
|
148
167
|
[textStreamPart.name]: textStreamPart.code,
|
@@ -151,7 +170,8 @@ var StreamStringPrefixes = {
|
|
151
170
|
[errorStreamPart.name]: errorStreamPart.code,
|
152
171
|
[assistantMessageStreamPart.name]: assistantMessageStreamPart.code,
|
153
172
|
[assistantControlDataStreamPart.name]: assistantControlDataStreamPart.code,
|
154
|
-
[dataMessageStreamPart.name]: dataMessageStreamPart.code
|
173
|
+
[dataMessageStreamPart.name]: dataMessageStreamPart.code,
|
174
|
+
[toolCallStreamPart.name]: toolCallStreamPart.code
|
155
175
|
};
|
156
176
|
var validCodes = streamParts.map((part) => part.code);
|
157
177
|
var parseStreamPart = (line) => {
|
@@ -277,20 +297,35 @@ async function parseComplexResponse({
|
|
277
297
|
};
|
278
298
|
functionCallMessage = prefixMap["function_call"];
|
279
299
|
}
|
300
|
+
let toolCallMessage = null;
|
301
|
+
if (type === "tool_calls") {
|
302
|
+
prefixMap["tool_calls"] = {
|
303
|
+
id: generateId(),
|
304
|
+
role: "assistant",
|
305
|
+
content: "",
|
306
|
+
tool_calls: value.tool_calls,
|
307
|
+
createdAt
|
308
|
+
};
|
309
|
+
toolCallMessage = prefixMap["tool_calls"];
|
310
|
+
}
|
280
311
|
if (type === "data") {
|
281
312
|
prefixMap["data"].push(...value);
|
282
313
|
}
|
283
314
|
const responseMessage = prefixMap["text"];
|
284
|
-
const merged = [
|
285
|
-
|
286
|
-
|
315
|
+
const merged = [
|
316
|
+
functionCallMessage,
|
317
|
+
toolCallMessage,
|
318
|
+
responseMessage
|
319
|
+
].filter(Boolean);
|
287
320
|
update(merged, [...prefixMap["data"]]);
|
288
321
|
}
|
289
322
|
onFinish == null ? void 0 : onFinish(prefixMap);
|
290
323
|
return {
|
291
|
-
messages: [
|
292
|
-
|
293
|
-
|
324
|
+
messages: [
|
325
|
+
prefixMap.text,
|
326
|
+
prefixMap.function_call,
|
327
|
+
prefixMap.tool_calls
|
328
|
+
].filter(Boolean),
|
294
329
|
data: prefixMap.data
|
295
330
|
};
|
296
331
|
}
|
@@ -376,6 +411,8 @@ async function callChatApi({
|
|
376
411
|
streamedResponse += decode(value);
|
377
412
|
if (streamedResponse.startsWith('{"function_call":')) {
|
378
413
|
responseMessage["function_call"] = streamedResponse;
|
414
|
+
} else if (streamedResponse.startsWith('{"tool_calls":')) {
|
415
|
+
responseMessage["tool_calls"] = streamedResponse;
|
379
416
|
} else {
|
380
417
|
responseMessage["content"] = streamedResponse;
|
381
418
|
}
|
@@ -390,6 +427,11 @@ async function callChatApi({
|
|
390
427
|
responseMessage["function_call"] = parsedFunctionCall;
|
391
428
|
appendMessage({ ...responseMessage });
|
392
429
|
}
|
430
|
+
if (streamedResponse.startsWith('{"tool_calls":')) {
|
431
|
+
const parsedToolCalls = JSON.parse(streamedResponse).tool_calls;
|
432
|
+
responseMessage["tool_calls"] = parsedToolCalls;
|
433
|
+
appendMessage({ ...responseMessage });
|
434
|
+
}
|
393
435
|
if (onFinish) {
|
394
436
|
onFinish(responseMessage);
|
395
437
|
}
|
@@ -401,6 +443,7 @@ async function callChatApi({
|
|
401
443
|
async function processChatStream({
|
402
444
|
getStreamedResponse,
|
403
445
|
experimental_onFunctionCall,
|
446
|
+
experimental_onToolCall,
|
404
447
|
updateChatRequest,
|
405
448
|
getCurrentMessages
|
406
449
|
}) {
|
@@ -409,12 +452,18 @@ async function processChatStream({
|
|
409
452
|
if ("messages" in messagesAndDataOrJustMessage) {
|
410
453
|
let hasFollowingResponse = false;
|
411
454
|
for (const message of messagesAndDataOrJustMessage.messages) {
|
412
|
-
if (message.function_call === void 0 || typeof message.function_call === "string") {
|
455
|
+
if ((message.function_call === void 0 || typeof message.function_call === "string") && (message.tool_calls === void 0 || typeof message.tool_calls === "string")) {
|
413
456
|
continue;
|
414
457
|
}
|
415
458
|
hasFollowingResponse = true;
|
416
459
|
if (experimental_onFunctionCall) {
|
417
460
|
const functionCall = message.function_call;
|
461
|
+
if (typeof functionCall !== "object") {
|
462
|
+
console.warn(
|
463
|
+
"experimental_onFunctionCall should not be defined when using tools"
|
464
|
+
);
|
465
|
+
continue;
|
466
|
+
}
|
418
467
|
const functionCallResponse = await experimental_onFunctionCall(
|
419
468
|
getCurrentMessages(),
|
420
469
|
functionCall
|
@@ -425,22 +474,83 @@ async function processChatStream({
|
|
425
474
|
}
|
426
475
|
updateChatRequest(functionCallResponse);
|
427
476
|
}
|
477
|
+
if (experimental_onToolCall) {
|
478
|
+
const toolCalls = message.tool_calls;
|
479
|
+
if (!Array.isArray(toolCalls) || toolCalls.some((toolCall) => typeof toolCall !== "object")) {
|
480
|
+
console.warn(
|
481
|
+
"experimental_onToolCall should not be defined when using tools"
|
482
|
+
);
|
483
|
+
continue;
|
484
|
+
}
|
485
|
+
const toolCallResponse = await experimental_onToolCall(getCurrentMessages(), toolCalls);
|
486
|
+
if (toolCallResponse === void 0) {
|
487
|
+
hasFollowingResponse = false;
|
488
|
+
break;
|
489
|
+
}
|
490
|
+
updateChatRequest(toolCallResponse);
|
491
|
+
}
|
428
492
|
}
|
429
493
|
if (!hasFollowingResponse) {
|
430
494
|
break;
|
431
495
|
}
|
432
496
|
} else {
|
497
|
+
let fixFunctionCallArguments2 = function(response) {
|
498
|
+
for (const message of response.messages) {
|
499
|
+
if (message.tool_calls !== void 0) {
|
500
|
+
for (const toolCall of message.tool_calls) {
|
501
|
+
if (typeof toolCall === "object") {
|
502
|
+
if (toolCall.function.arguments && typeof toolCall.function.arguments !== "string") {
|
503
|
+
toolCall.function.arguments = JSON.stringify(
|
504
|
+
toolCall.function.arguments
|
505
|
+
);
|
506
|
+
}
|
507
|
+
}
|
508
|
+
}
|
509
|
+
}
|
510
|
+
if (message.function_call !== void 0) {
|
511
|
+
if (typeof message.function_call === "object") {
|
512
|
+
if (message.function_call.arguments && typeof message.function_call.arguments !== "string") {
|
513
|
+
message.function_call.arguments = JSON.stringify(
|
514
|
+
message.function_call.arguments
|
515
|
+
);
|
516
|
+
}
|
517
|
+
}
|
518
|
+
}
|
519
|
+
}
|
520
|
+
};
|
521
|
+
var fixFunctionCallArguments = fixFunctionCallArguments2;
|
433
522
|
const streamedResponseMessage = messagesAndDataOrJustMessage;
|
434
|
-
if (streamedResponseMessage.function_call === void 0 || typeof streamedResponseMessage.function_call === "string") {
|
523
|
+
if ((streamedResponseMessage.function_call === void 0 || typeof streamedResponseMessage.function_call === "string") && (streamedResponseMessage.tool_calls === void 0 || typeof streamedResponseMessage.tool_calls === "string")) {
|
435
524
|
break;
|
436
525
|
}
|
437
526
|
if (experimental_onFunctionCall) {
|
438
527
|
const functionCall = streamedResponseMessage.function_call;
|
528
|
+
if (!(typeof functionCall === "object")) {
|
529
|
+
console.warn(
|
530
|
+
"experimental_onFunctionCall should not be defined when using tools"
|
531
|
+
);
|
532
|
+
continue;
|
533
|
+
}
|
439
534
|
const functionCallResponse = await experimental_onFunctionCall(getCurrentMessages(), functionCall);
|
440
535
|
if (functionCallResponse === void 0)
|
441
536
|
break;
|
537
|
+
fixFunctionCallArguments2(functionCallResponse);
|
442
538
|
updateChatRequest(functionCallResponse);
|
443
539
|
}
|
540
|
+
if (experimental_onToolCall) {
|
541
|
+
const toolCalls = streamedResponseMessage.tool_calls;
|
542
|
+
if (!(typeof toolCalls === "object")) {
|
543
|
+
console.warn(
|
544
|
+
"experimental_onToolCall should not be defined when using functions"
|
545
|
+
);
|
546
|
+
continue;
|
547
|
+
}
|
548
|
+
const toolCallResponse = await experimental_onToolCall(getCurrentMessages(), toolCalls);
|
549
|
+
if (toolCallResponse === void 0)
|
550
|
+
break;
|
551
|
+
fixFunctionCallArguments2(toolCallResponse);
|
552
|
+
updateChatRequest(toolCallResponse);
|
553
|
+
}
|
444
554
|
}
|
445
555
|
}
|
446
556
|
}
|
@@ -487,7 +597,7 @@ function useChat({
|
|
487
597
|
);
|
488
598
|
const [isLoading, setIsLoading] = (0, import_solid_js.createSignal)(false);
|
489
599
|
let abortController = null;
|
490
|
-
async function triggerRequest(messagesSnapshot, options) {
|
600
|
+
async function triggerRequest(messagesSnapshot, { options, data } = {}) {
|
491
601
|
try {
|
492
602
|
setError(void 0);
|
493
603
|
setIsLoading(true);
|
@@ -499,7 +609,8 @@ function useChat({
|
|
499
609
|
mutate(messagesSnapshot);
|
500
610
|
let chatRequest = {
|
501
611
|
messages: messagesSnapshot,
|
502
|
-
options
|
612
|
+
options,
|
613
|
+
data
|
503
614
|
};
|
504
615
|
await processChatStream({
|
505
616
|
getStreamedResponse: async () => {
|
@@ -518,6 +629,7 @@ function useChat({
|
|
518
629
|
})
|
519
630
|
),
|
520
631
|
body: {
|
632
|
+
data: chatRequest.data,
|
521
633
|
...body,
|
522
634
|
...options == null ? void 0 : options.body
|
523
635
|
},
|
@@ -528,9 +640,9 @@ function useChat({
|
|
528
640
|
abortController: () => abortController,
|
529
641
|
credentials,
|
530
642
|
onResponse,
|
531
|
-
onUpdate(merged,
|
643
|
+
onUpdate(merged, data2) {
|
532
644
|
mutate([...chatRequest.messages, ...merged]);
|
533
|
-
setStreamData([...existingData, ...
|
645
|
+
setStreamData([...existingData, ...data2 != null ? data2 : []]);
|
534
646
|
},
|
535
647
|
onFinish,
|
536
648
|
appendMessage(message) {
|
@@ -594,16 +706,19 @@ function useChat({
|
|
594
706
|
mutate(messages2);
|
595
707
|
};
|
596
708
|
const [input, setInput] = (0, import_solid_js.createSignal)(initialInput);
|
597
|
-
const handleSubmit = (e) => {
|
709
|
+
const handleSubmit = (e, options = {}) => {
|
598
710
|
e.preventDefault();
|
599
711
|
const inputValue = input();
|
600
712
|
if (!inputValue)
|
601
713
|
return;
|
602
|
-
append(
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
714
|
+
append(
|
715
|
+
{
|
716
|
+
content: inputValue,
|
717
|
+
role: "user",
|
718
|
+
createdAt: /* @__PURE__ */ new Date()
|
719
|
+
},
|
720
|
+
options
|
721
|
+
);
|
607
722
|
setInput("");
|
608
723
|
};
|
609
724
|
return {
|
package/solid/dist/index.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../index.ts","../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":["export * from './use-chat';\nexport * from './use-completion';\n","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","import_solid_js","import_solid_swr_store","import_swr_store","uniqueId","store","data","completion"]}
|
1
|
+
{"version":3,"sources":["../index.ts","../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":["export * from './use-chat';\nexport * from './use-completion';\n","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":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,sBAAyD;AACzD,6BAA4B;AAC5B,uBAA+B;;;ACa/B,IAAM,iBAAkD;AAAA,EACtD,MAAM;AAAA,EACN,MAAM;AAAA,EACN,OAAO,CAAC,UAAqB;AAC3B,QAAI,OAAO,UAAU,UAAU;AAC7B,YAAM,IAAI,MAAM,qCAAqC;AAAA,IACvD;AACA,WAAO,EAAE,MAAM,QAAQ,MAAM;AAAA,EAC/B;AACF;AAEA,IAAM,yBAIF;AAAA,EACF,MAAM;AAAA,EACN,MAAM;AAAA,EACN,OAAO,CAAC,UAAqB;AAC3B,QACE,SAAS,QACT,OAAO,UAAU,YACjB,EAAE,mBAAmB,UACrB,OAAO,MAAM,kBAAkB,YAC/B,MAAM,iBAAiB,QACvB,EAAE,UAAU,MAAM,kBAClB,EAAE,eAAe,MAAM,kBACvB,OAAO,MAAM,cAAc,SAAS,YACpC,OAAO,MAAM,cAAc,cAAc,UACzC;AACA,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,MACL,MAAM;AAAA,MACN;AAAA,IACF;AAAA,EACF;AACF;AAEA,IAAM,iBAA4D;AAAA,EAChE,MAAM;AAAA,EACN,MAAM;AAAA,EACN,OAAO,CAAC,UAAqB;AAC3B,QAAI,CAAC,MAAM,QAAQ,KAAK,GAAG;AACzB,YAAM,IAAI,MAAM,qCAAqC;AAAA,IACvD;AAEA,WAAO,EAAE,MAAM,QAAQ,MAAM;AAAA,EAC/B;AACF;AAEA,IAAM,kBAAoD;AAAA,EACxD,MAAM;AAAA,EACN,MAAM;AAAA,EACN,OAAO,CAAC,UAAqB;AAC3B,QAAI,OAAO,UAAU,UAAU;AAC7B,YAAM,IAAI,MAAM,sCAAsC;AAAA,IACxD;AACA,WAAO,EAAE,MAAM,SAAS,MAAM;AAAA,EAChC;AACF;AAEA,IAAM,6BAIF;AAAA,EACF,MAAM;AAAA,EACN,MAAM;AAAA,EACN,OAAO,CAAC,UAAqB;AAC3B,QACE,SAAS,QACT,OAAO,UAAU,YACjB,EAAE,QAAQ,UACV,EAAE,UAAU,UACZ,EAAE,aAAa,UACf,OAAO,MAAM,OAAO,YACpB,OAAO,MAAM,SAAS,YACtB,MAAM,SAAS,eACf,CAAC,MAAM,QAAQ,MAAM,OAAO,KAC5B,CAAC,MAAM,QAAQ;AAAA,MACb,UACE,QAAQ,QACR,OAAO,SAAS,YAChB,UAAU,QACV,KAAK,SAAS,UACd,UAAU,QACV,KAAK,QAAQ,QACb,OAAO,KAAK,SAAS,YACrB,WAAW,KAAK,QAChB,OAAO,KAAK,KAAK,UAAU;AAAA,IAC/B,GACA;AACA,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,MACL,MAAM;AAAA,MACN;AAAA,IACF;AAAA,EACF;AACF;AAEA,IAAM,iCAOF;AAAA,EACF,MAAM;AAAA,EACN,MAAM;AAAA,EACN,OAAO,CAAC,UAAqB;AAC3B,QACE,SAAS,QACT,OAAO,UAAU,YACjB,EAAE,cAAc,UAChB,EAAE,eAAe,UACjB,OAAO,MAAM,aAAa,YAC1B,OAAO,MAAM,cAAc,UAC3B;AACA,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,MACL,MAAM;AAAA,MACN,OAAO;AAAA,QACL,UAAU,MAAM;AAAA,QAChB,WAAW,MAAM;AAAA,MACnB;AAAA,IACF;AAAA,EACF;AACF;AAEA,IAAM,wBAAsE;AAAA,EAC1E,MAAM;AAAA,EACN,MAAM;AAAA,EACN,OAAO,CAAC,UAAqB;AAC3B,QACE,SAAS,QACT,OAAO,UAAU,YACjB,EAAE,UAAU,UACZ,EAAE,UAAU,UACZ,OAAO,MAAM,SAAS,YACtB,MAAM,SAAS,QACf;AACA,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,MACL,MAAM;AAAA,MACN;AAAA,IACF;AAAA,EACF;AACF;AAEA,IAAM,qBAIF;AAAA,EACF,MAAM;AAAA,EACN,MAAM;AAAA,EACN,OAAO,CAAC,UAAqB;AAC3B,QACE,SAAS,QACT,OAAO,UAAU,YACjB,EAAE,gBAAgB,UAClB,OAAO,MAAM,eAAe,YAC5B,MAAM,cAAc,QACpB,CAAC,MAAM,QAAQ,MAAM,UAAU,KAC/B,MAAM,WAAW,KAAK,QAAM;AAC1B,YAAM,QACJ,OAAO,OAAO,YACd,EAAE,QAAQ,OACV,OAAO,GAAG,OAAO,YACjB,EAAE,UAAU,OACZ,OAAO,GAAG,SAAS,YACnB,EAAE,cAAc,OAChB,GAAG,YAAY,QACf,OAAO,GAAG,aAAa,YACvB,EAAE,eAAe,GAAG,aACpB,OAAO,GAAG,SAAS,SAAS,YAC5B,OAAO,GAAG,SAAS,cAAc;AAAA,IACrC,CAAC,GACD;AACA,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,MACL,MAAM;AAAA,MACN;AAAA,IACF;AAAA,EACF;AACF;AAEA,IAAM,cAAc;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AA8BO,IAAM,oBAAoB;AAAA,EAC/B,CAAC,eAAe,IAAI,GAAG;AAAA,EACvB,CAAC,uBAAuB,IAAI,GAAG;AAAA,EAC/B,CAAC,eAAe,IAAI,GAAG;AAAA,EACvB,CAAC,gBAAgB,IAAI,GAAG;AAAA,EACxB,CAAC,2BAA2B,IAAI,GAAG;AAAA,EACnC,CAAC,+BAA+B,IAAI,GAAG;AAAA,EACvC,CAAC,sBAAsB,IAAI,GAAG;AAAA,EAC9B,CAAC,mBAAmB,IAAI,GAAG;AAC7B;AAwBO,IAAM,uBAAuB;AAAA,EAClC,CAAC,eAAe,IAAI,GAAG,eAAe;AAAA,EACtC,CAAC,uBAAuB,IAAI,GAAG,uBAAuB;AAAA,EACtD,CAAC,eAAe,IAAI,GAAG,eAAe;AAAA,EACtC,CAAC,gBAAgB,IAAI,GAAG,gBAAgB;AAAA,EACxC,CAAC,2BAA2B,IAAI,GAAG,2BAA2B;AAAA,EAC9D,CAAC,+BAA+B,IAAI,GAAG,+BAA+B;AAAA,EACtE,CAAC,sBAAsB,IAAI,GAAG,sBAAsB;AAAA,EACpD,CAAC,mBAAmB,IAAI,GAAG,mBAAmB;AAChD;AAEO,IAAM,aAAa,YAAY,IAAI,UAAQ,KAAK,IAAI;AASpD,IAAM,kBAAkB,CAAC,SAAiC;AAC/D,QAAM,sBAAsB,KAAK,QAAQ,GAAG;AAE5C,MAAI,wBAAwB,IAAI;AAC9B,UAAM,IAAI,MAAM,oDAAoD;AAAA,EACtE;AAEA,QAAM,SAAS,KAAK,MAAM,GAAG,mBAAmB;AAEhD,MAAI,CAAC,WAAW,SAAS,MAAwC,GAAG;AAClE,UAAM,IAAI,MAAM,+CAA+C,SAAS;AAAA,EAC1E;AAEA,QAAM,OAAO;AAEb,QAAM,YAAY,KAAK,MAAM,sBAAsB,CAAC;AACpD,QAAM,YAAuB,KAAK,MAAM,SAAS;AAEjD,SAAO,kBAAkB,IAAI,EAAE,MAAM,SAAS;AAChD;;;AC5UA,IAAM,UAAU,KAAK,WAAW,CAAC;AAGjC,SAAS,aAAa,QAAsB,aAAqB;AAC/D,QAAM,qBAAqB,IAAI,WAAW,WAAW;AAErD,MAAI,SAAS;AACb,aAAW,SAAS,QAAQ;AAC1B,uBAAmB,IAAI,OAAO,MAAM;AACpC,cAAU,MAAM;AAAA,EAClB;AACA,SAAO,SAAS;AAEhB,SAAO;AACT;AAEA,gBAAuB,eACrB,QACA;AAAA,EACE;AACF,IAEI,CAAC,GAC2B;AAIhC,QAAM,UAAU,IAAI,YAAY;AAChC,QAAM,SAAuB,CAAC;AAC9B,MAAI,cAAc;AAElB,SAAO,MAAM;AACX,UAAM,EAAE,MAAM,IAAI,MAAM,OAAO,KAAK;AAEpC,QAAI,OAAO;AACT,aAAO,KAAK,KAAK;AACjB,qBAAe,MAAM;AACrB,UAAI,MAAM,MAAM,SAAS,CAAC,MAAM,SAAS;AAEvC;AAAA,MACF;AAAA,IACF;AAEA,QAAI,OAAO,WAAW,GAAG;AACvB;AAAA,IACF;AAEA,UAAM,qBAAqB,aAAa,QAAQ,WAAW;AAC3D,kBAAc;AAEd,UAAMA,eAAc,QACjB,OAAO,oBAAoB,EAAE,QAAQ,KAAK,CAAC,EAC3C,MAAM,IAAI,EACV,OAAO,UAAQ,SAAS,EAAE,EAC1B,IAAI,eAAe;AAEtB,eAAW,cAAcA,cAAa;AACpC,YAAM;AAAA,IACR;AAGA,QAAI,0CAAe;AACjB,aAAO,OAAO;AACd;AAAA,IACF;AAAA,EACF;AACF;;;ACpEA,wBAA+B;AAQxB,IAAM,aAAS;AAAA,EACpB;AAAA,EACA;AACF;AAeA,SAAS,mBAAmB,SAAmB;AAC7C,QAAM,UAAU,IAAI,YAAY;AAEhC,MAAI,CAAC,SAAS;AACZ,WAAO,SAAU,OAAuC;AACtD,UAAI,CAAC;AAAO,eAAO;AACnB,aAAO,QAAQ,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC;AAAA,IAC/C;AAAA,EACF;AAEA,SAAO,SAAU,OAA+B;AAC9C,UAAM,UAAU,QACb,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC,EAC9B,MAAM,IAAI,EACV,OAAO,UAAQ,SAAS,EAAE;AAE7B,WAAO,QAAQ,IAAI,eAAe,EAAE,OAAO,OAAO;AAAA,EACpD;AACF;AAgBO,IAAM,iBAAiB;;;AC3C9B,eAAsB,qBAAqB;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,aAAa;AAAA,EACb,iBAAiB,MAAM,oBAAI,KAAK;AAClC,GASG;AACD,QAAM,YAAY,eAAe;AACjC,QAAM,YAAuB;AAAA,IAC3B,MAAM,CAAC;AAAA,EACT;AAGA,mBAAiB,EAAE,MAAM,MAAM,KAAK,eAAe,QAAQ;AAAA,IACzD,WAAW,OAAM,yDAAoB,aAAY;AAAA,EACnD,CAAC,GAAG;AACF,QAAI,SAAS,QAAQ;AACnB,UAAI,UAAU,MAAM,GAAG;AACrB,kBAAU,MAAM,IAAI;AAAA,UAClB,GAAG,UAAU,MAAM;AAAA,UACnB,UAAU,UAAU,MAAM,EAAE,WAAW,MAAM;AAAA,QAC/C;AAAA,MACF,OAAO;AACL,kBAAU,MAAM,IAAI;AAAA,UAClB,IAAI,WAAW;AAAA,UACf,MAAM;AAAA,UACN,SAAS;AAAA,UACT;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,QAAI,sBAAsC;AAE1C,QAAI,SAAS,iBAAiB;AAC5B,gBAAU,eAAe,IAAI;AAAA,QAC3B,IAAI,WAAW;AAAA,QACf,MAAM;AAAA,QACN,SAAS;AAAA,QACT,eAAe,MAAM;AAAA,QACrB,MAAM,MAAM,cAAc;AAAA,QAC1B;AAAA,MACF;AAEA,4BAAsB,UAAU,eAAe;AAAA,IACjD;AAEA,QAAI,kBAAkC;AAEtC,QAAI,SAAS,cAAc;AACzB,gBAAU,YAAY,IAAI;AAAA,QACxB,IAAI,WAAW;AAAA,QACf,MAAM;AAAA,QACN,SAAS;AAAA,QACT,YAAY,MAAM;AAAA,QAClB;AAAA,MACF;AAEA,wBAAkB,UAAU,YAAY;AAAA,IAC1C;AAEA,QAAI,SAAS,QAAQ;AACnB,gBAAU,MAAM,EAAE,KAAK,GAAG,KAAK;AAAA,IACjC;AAEA,UAAM,kBAAkB,UAAU,MAAM;AAGxC,UAAM,SAAS;AAAA,MACb;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,OAAO,OAAO;AAEhB,WAAO,QAAQ,CAAC,GAAG,UAAU,MAAM,CAAC,CAAC;AAAA,EACvC;AAEA,uCAAW;AAEX,SAAO;AAAA,IACL,UAAU;AAAA,MACR,UAAU;AAAA,MACV,UAAU;AAAA,MACV,UAAU;AAAA,IACZ,EAAE,OAAO,OAAO;AAAA,IAChB,MAAM,UAAU;AAAA,EAClB;AACF;;;ACxGA,eAAsB,YAAY;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAaG;AApCH;AAqCE,QAAM,WAAW,MAAM,MAAM,KAAK;AAAA,IAChC,QAAQ;AAAA,IACR,MAAM,KAAK,UAAU;AAAA,MACnB;AAAA,MACA,GAAG;AAAA,IACL,CAAC;AAAA,IACD,SAAS;AAAA,MACP,gBAAgB;AAAA,MAChB,GAAG;AAAA,IACL;AAAA,IACA,SAAQ,iFAAqB;AAAA,IAC7B;AAAA,EACF,CAAC,EAAE,MAAM,SAAO;AACd,6BAAyB;AACzB,UAAM;AAAA,EACR,CAAC;AAED,MAAI,YAAY;AACd,QAAI;AACF,YAAM,WAAW,QAAQ;AAAA,IAC3B,SAAS,KAAP;AACA,YAAM;AAAA,IACR;AAAA,EACF;AAEA,MAAI,CAAC,SAAS,IAAI;AAChB,6BAAyB;AACzB,UAAM,IAAI;AAAA,MACP,MAAM,SAAS,KAAK,KAAM;AAAA,IAC7B;AAAA,EACF;AAEA,MAAI,CAAC,SAAS,MAAM;AAClB,UAAM,IAAI,MAAM,6BAA6B;AAAA,EAC/C;AAEA,QAAM,SAAS,SAAS,KAAK,UAAU;AACvC,QAAM,gBAAgB,SAAS,QAAQ,IAAI,cAAc,MAAM;AAE/D,MAAI,eAAe;AACjB,WAAO,MAAM,qBAAqB;AAAA,MAChC;AAAA,MACA,oBACE,mBAAmB,OAAO,EAAE,SAAS,gBAAgB,EAAE,IAAI;AAAA,MAC7D,QAAQ;AAAA,MACR,SAAS,WAAW;AAClB,YAAI,YAAY,UAAU,QAAQ,MAAM;AACtC,mBAAS,UAAU,IAAI;AAAA,QACzB;AAAA,MACF;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH,OAAO;AACL,UAAM,YAAY,oBAAI,KAAK;AAC3B,UAAM,SAAS,mBAAmB,KAAK;AAGvC,QAAI,mBAAmB;AACvB,UAAM,UAAU,WAAW;AAC3B,QAAI,kBAA2B;AAAA,MAC7B,IAAI;AAAA,MACJ;AAAA,MACA,SAAS;AAAA,MACT,MAAM;AAAA,IACR;AAGA,WAAO,MAAM;AACX,YAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,UAAI,MAAM;AACR;AAAA,MACF;AAEA,0BAAoB,OAAO,KAAK;AAEhC,UAAI,iBAAiB,WAAW,mBAAmB,GAAG;AAEpD,wBAAgB,eAAe,IAAI;AAAA,MACrC,WAAW,iBAAiB,WAAW,gBAAgB,GAAG;AAExD,wBAAgB,YAAY,IAAI;AAAA,MAClC,OAAO;AACL,wBAAgB,SAAS,IAAI;AAAA,MAC/B;AAEA,oBAAc,EAAE,GAAG,gBAAgB,CAAC;AAGpC,WAAI,0DAAwB,MAAM;AAChC,eAAO,OAAO;AACd;AAAA,MACF;AAAA,IACF;AAEA,QAAI,iBAAiB,WAAW,mBAAmB,GAAG;AAEpD,YAAM,qBACJ,KAAK,MAAM,gBAAgB,EAAE;AAE/B,sBAAgB,eAAe,IAAI;AAEnC,oBAAc,EAAE,GAAG,gBAAgB,CAAC;AAAA,IACtC;AACA,QAAI,iBAAiB,WAAW,gBAAgB,GAAG;AAEjD,YAAM,kBACJ,KAAK,MAAM,gBAAgB,EAAE;AAE/B,sBAAgB,YAAY,IAAI;AAEhC,oBAAc,EAAE,GAAG,gBAAgB,CAAC;AAAA,IACtC;AAEA,QAAI,UAAU;AACZ,eAAS,eAAe;AAAA,IAC1B;AAEA,WAAO;AAAA,EACT;AACF;;;ACpJA,eAAsB,kBAAkB;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAcG;AACD,SAAO,MAAM;AAGX,UAAM,+BAA+B,MAAM,oBAAoB;AAG/D,QAAI,cAAc,8BAA8B;AAC9C,UAAI,uBAAuB;AAE3B,iBAAW,WAAW,6BAA6B,UAAU;AAE3D,aACG,QAAQ,kBAAkB,UACzB,OAAO,QAAQ,kBAAkB,cAClC,QAAQ,eAAe,UACtB,OAAO,QAAQ,eAAe,WAChC;AACA;AAAA,QACF;AAEA,+BAAuB;AAEvB,YAAI,6BAA6B;AAC/B,gBAAM,eAAe,QAAQ;AAG7B,cAAI,OAAO,iBAAiB,UAAU;AACpC,oBAAQ;AAAA,cACN;AAAA,YACF;AACA;AAAA,UACF;AAMA,gBAAM,uBACJ,MAAM;AAAA,YACJ,mBAAmB;AAAA,YACnB;AAAA,UACF;AAGF,cAAI,yBAAyB,QAAW;AACtC,mCAAuB;AACvB;AAAA,UACF;AAIA,4BAAkB,oBAAoB;AAAA,QACxC;AAEA,YAAI,yBAAyB;AAC3B,gBAAM,YAAY,QAAQ;AAG1B,cACE,CAAC,MAAM,QAAQ,SAAS,KACxB,UAAU,KAAK,cAAY,OAAO,aAAa,QAAQ,GACvD;AACA,oBAAQ;AAAA,cACN;AAAA,YACF;AACA;AAAA,UACF;AAKA,gBAAM,mBACJ,MAAM,wBAAwB,mBAAmB,GAAG,SAAS;AAG/D,cAAI,qBAAqB,QAAW;AAClC,mCAAuB;AACvB;AAAA,UACF;AAIA,4BAAkB,gBAAgB;AAAA,QACpC;AAAA,MACF;AACA,UAAI,CAAC,sBAAsB;AACzB;AAAA,MACF;AAAA,IACF,OAAO;AAqDL,UAASC,4BAAT,SAAkC,UAAuB;AACvD,mBAAW,WAAW,SAAS,UAAU;AACvC,cAAI,QAAQ,eAAe,QAAW;AACpC,uBAAW,YAAY,QAAQ,YAAY;AACzC,kBAAI,OAAO,aAAa,UAAU;AAChC,oBACE,SAAS,SAAS,aAClB,OAAO,SAAS,SAAS,cAAc,UACvC;AACA,2BAAS,SAAS,YAAY,KAAK;AAAA,oBACjC,SAAS,SAAS;AAAA,kBACpB;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AACA,cAAI,QAAQ,kBAAkB,QAAW;AACvC,gBAAI,OAAO,QAAQ,kBAAkB,UAAU;AAC7C,kBACE,QAAQ,cAAc,aACtB,OAAO,QAAQ,cAAc,cAAc,UAC3C;AACA,wBAAQ,cAAc,YAAY,KAAK;AAAA,kBACrC,QAAQ,cAAc;AAAA,gBACxB;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AA7BS,qCAAAA;AApDT,YAAM,0BAA0B;AAGhC,WACG,wBAAwB,kBAAkB,UACzC,OAAO,wBAAwB,kBAAkB,cAClD,wBAAwB,eAAe,UACtC,OAAO,wBAAwB,eAAe,WAChD;AACA;AAAA,MACF;AAGA,UAAI,6BAA6B;AAC/B,cAAM,eAAe,wBAAwB;AAC7C,YAAI,EAAE,OAAO,iBAAiB,WAAW;AACvC,kBAAQ;AAAA,YACN;AAAA,UACF;AACA;AAAA,QACF;AACA,cAAM,uBACJ,MAAM,4BAA4B,mBAAmB,GAAG,YAAY;AAGtE,YAAI,yBAAyB;AAAW;AAGxC,QAAAA,0BAAyB,oBAAoB;AAC7C,0BAAkB,oBAAoB;AAAA,MACxC;AAEA,UAAI,yBAAyB;AAC3B,cAAM,YAAY,wBAAwB;AAC1C,YAAI,EAAE,OAAO,cAAc,WAAW;AACpC,kBAAQ;AAAA,YACN;AAAA,UACF;AACA;AAAA,QACF;AACA,cAAM,mBACJ,MAAM,wBAAwB,mBAAmB,GAAG,SAAS;AAG/D,YAAI,qBAAqB;AAAW;AAGpC,QAAAA,0BAAyB,gBAAgB;AACzC,0BAAkB,gBAAgB;AAAA,MACpC;AAAA,IAiCF;AAAA,EACF;AACF;;;AN5IA,IAAI,WAAW;AAEf,IAAM,QAA+C,CAAC;AACtD,IAAM,mBAAe,iCAAoC;AAAA,EACvD,KAAK,OAAO,QAAgB;AAlE9B;AAmEI,YAAO,WAAM,GAAG,MAAT,YAAc,CAAC;AAAA,EACxB;AACF,CAAC;AAEM,SAAS,QAAQ;AAAA,EACtB,MAAM;AAAA,EACN;AAAA,EACA,kBAAkB,CAAC;AAAA,EACnB,eAAe;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,aAAa;AACf,IAAoB,CAAC,GAAmB;AAEtC,QAAM,SAAS,MAAM,QAAQ;AAE7B,QAAM,MAAM,GAAG,OAAO;AAGtB,QAAM,eAAW,oCAAY,cAAc,MAAM,CAAC,GAAG,GAAG;AAAA,IACtD,aAAa;AAAA,EACf,CAAC;AAED,QAAM,SAAS,CAAC,SAAoB;AAClC,UAAM,GAAG,IAAI;AACb,WAAO,aAAa,OAAO,CAAC,GAAG,GAAG;AAAA,MAChC,QAAQ;AAAA,MACR;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,CAAC,OAAO,QAAQ,QAAI,8BAAgC,MAAS;AACnE,QAAM,CAAC,YAAY,aAAa,QAAI;AAAA,IAClC;AAAA,EACF;AACA,QAAM,CAAC,WAAW,YAAY,QAAI,8BAAa,KAAK;AAEpD,MAAI,kBAA0C;AAC9C,iBAAe,eACb,kBACA,EAAE,SAAS,KAAK,IAAwB,CAAC,GACzC;AACA,QAAI;AACF,eAAS,MAAS;AAClB,mBAAa,IAAI;AAEjB,wBAAkB,IAAI,gBAAgB;AAEtC,YAAM,qBAAqB,MACzB,aAAa,IAAI,CAAC,GAAG,GAAG;AAAA,QACtB,kBAAkB;AAAA,MACpB,CAAC;AAIH,YAAM,mBAAmB,mBAAmB;AAC5C,aAAO,gBAAgB;AAEvB,UAAI,cAA2B;AAAA,QAC7B,UAAU;AAAA,QACV;AAAA,QACA;AAAA,MACF;AAEA,YAAM,kBAAkB;AAAA,QACtB,qBAAqB,YAAY;AA1IzC;AA2IU,gBAAM,gBAAe,gBAAW,MAAX,YAAgB,CAAC;AAEtC,iBAAO,MAAM,YAAY;AAAA,YACvB;AAAA,YACA,UAAU,yBACN,YAAY,WACZ,YAAY,SAAS;AAAA,cACnB,CAAC,EAAE,MAAM,SAAS,MAAM,cAAc,OAAO;AAAA,gBAC3C;AAAA,gBACA;AAAA,gBACA,GAAI,SAAS,UAAa,EAAE,KAAK;AAAA,gBACjC,GAAI,kBAAkB,UAAa;AAAA,kBACjC;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,YACJ,MAAM;AAAA,cACJ,MAAM,YAAY;AAAA,cAClB,GAAG;AAAA,cACH,GAAG,mCAAS;AAAA,YACd;AAAA,YACA,SAAS;AAAA,cACP,GAAG;AAAA,cACH,GAAG,mCAAS;AAAA,YACd;AAAA,YACA,iBAAiB,MAAM;AAAA,YACvB;AAAA,YACA;AAAA,YACA,SAAS,QAAQC,OAAM;AACrB,qBAAO,CAAC,GAAG,YAAY,UAAU,GAAG,MAAM,CAAC;AAC3C,4BAAc,CAAC,GAAG,cAAc,GAAIA,SAAA,OAAAA,QAAQ,CAAC,CAAE,CAAC;AAAA,YAClD;AAAA,YACA;AAAA,YACA,cAAc,SAAS;AACrB,qBAAO,CAAC,GAAG,YAAY,UAAU,OAAO,CAAC;AAAA,YAC3C;AAAA,YACA,2BAA2B;AAEzB,kBAAI,iBAAiB,WAAW,WAAW;AACzC,uBAAO,iBAAiB,IAAI;AAAA,cAC9B;AAAA,YACF;AAAA,YACA;AAAA,UACF,CAAC;AAAA,QACH;AAAA,QACA;AAAA,QACA,kBAAkB,gBAAgB;AAChC,wBAAc;AAAA,QAChB;AAAA,QACA,oBAAoB,MAAM,mBAAmB,EAAE;AAAA,MACjD,CAAC;AAED,wBAAkB;AAAA,IACpB,SAAS,KAAP;AAEA,UAAK,IAAY,SAAS,cAAc;AACtC,0BAAkB;AAClB,eAAO;AAAA,MACT;AAEA,UAAI,WAAW,eAAe,OAAO;AACnC,gBAAQ,GAAG;AAAA,MACb;AAEA,eAAS,GAAY;AAAA,IACvB,UAAE;AACA,mBAAa,KAAK;AAAA,IACpB;AAAA,EACF;AAEA,QAAM,SAAmC,OAAO,SAAS,YAAY;AAjNvE;AAkNI,QAAI,CAAC,QAAQ,IAAI;AACf,cAAQ,KAAK,WAAW;AAAA,IAC1B;AACA,WAAO;AAAA,QACJ,cAAS,MAAT,YAAc,CAAC,GAAG,OAAO,OAAkB;AAAA,MAC5C;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAmC,OAAM,YAAW;AACxD,UAAM,mBAAmB,SAAS;AAClC,QAAI,CAAC,oBAAoB,iBAAiB,WAAW;AAAG,aAAO;AAE/D,UAAM,cAAc,iBAAiB,iBAAiB,SAAS,CAAC;AAChE,QAAI,YAAY,SAAS,aAAa;AACpC,aAAO,eAAe,iBAAiB,MAAM,GAAG,EAAE,GAAG,OAAO;AAAA,IAC9D;AACA,WAAO,eAAe,kBAAkB,OAAO;AAAA,EACjD;AAEA,QAAM,OAAO,MAAM;AACjB,QAAI,iBAAiB;AACnB,sBAAgB,MAAM;AACtB,wBAAkB;AAAA,IACpB;AAAA,EACF;AAEA,QAAM,cAAc,CAACC,cAAwB;AAC3C,WAAOA,SAAQ;AAAA,EACjB;AAEA,QAAM,CAAC,OAAO,QAAQ,QAAI,8BAAa,YAAY;AAEnD,QAAM,eAAe,CAAC,GAAQ,UAA8B,CAAC,MAAM;AACjE,MAAE,eAAe;AACjB,UAAM,aAAa,MAAM;AACzB,QAAI,CAAC;AAAY;AAEjB;AAAA,MACE;AAAA,QACE,SAAS;AAAA,QACT,MAAM;AAAA,QACN,WAAW,oBAAI,KAAK;AAAA,MACtB;AAAA,MACA;AAAA,IACF;AAEA,aAAS,EAAE;AAAA,EACb;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM;AAAA,EACR;AACF;;;AOjRA,IAAAC,mBAAyD;AACzD,IAAAC,0BAA4B;AAC5B,IAAAC,oBAA+B;;;ACE/B,eAAsB,kBAAkB;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAcG;AACD,MAAI;AACF,eAAW,IAAI;AACf,aAAS,MAAS;AAElB,UAAM,kBAAkB,IAAI,gBAAgB;AAC5C,uBAAmB,eAAe;AAGlC,kBAAc,EAAE;AAEhB,UAAM,MAAM,MAAM,MAAM,KAAK;AAAA,MAC3B,QAAQ;AAAA,MACR,MAAM,KAAK,UAAU;AAAA,QACnB;AAAA,QACA,GAAG;AAAA,MACL,CAAC;AAAA,MACD;AAAA,MACA,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,GAAG;AAAA,MACL;AAAA,MACA,QAAQ,gBAAgB;AAAA,IAC1B,CAAC,EAAE,MAAM,SAAO;AACd,YAAM;AAAA,IACR,CAAC;AAED,QAAI,YAAY;AACd,UAAI;AACF,cAAM,WAAW,GAAG;AAAA,MACtB,SAAS,KAAP;AACA,cAAM;AAAA,MACR;AAAA,IACF;AAEA,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,IAAI;AAAA,QACP,MAAM,IAAI,KAAK,KAAM;AAAA,MACxB;AAAA,IACF;AAEA,QAAI,CAAC,IAAI,MAAM;AACb,YAAM,IAAI,MAAM,6BAA6B;AAAA,IAC/C;AAEA,QAAI,SAAS;AACb,UAAM,SAAS,IAAI,KAAK,UAAU;AAElC,UAAM,gBAAgB,IAAI,QAAQ,IAAI,cAAc,MAAM;AAE1D,QAAI,eAAe;AACjB,uBAAiB,EAAE,MAAM,MAAM,KAAK,eAAe,QAAQ;AAAA,QACzD,WAAW,MAAM,oBAAoB;AAAA,MACvC,CAAC,GAAG;AACF,gBAAQ,MAAM;AAAA,UACZ,KAAK,QAAQ;AACX,sBAAU;AACV,0BAAc,MAAM;AACpB;AAAA,UACF;AAAA,UACA,KAAK,QAAQ;AACX,6CAAS;AACT;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF,OAAO;AACL,YAAM,UAAU,mBAAmB;AAEnC,aAAO,MAAM;AACX,cAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,YAAI,MAAM;AACR;AAAA,QACF;AAGA,kBAAU,QAAQ,KAAK;AACvB,sBAAc,MAAM;AAGpB,YAAI,oBAAoB,MAAM;AAC5B,iBAAO,OAAO;AACd;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,QAAI,UAAU;AACZ,eAAS,QAAQ,MAAM;AAAA,IACzB;AAEA,uBAAmB,IAAI;AACvB,WAAO;AAAA,EACT,SAAS,KAAP;AAEA,QAAK,IAAY,SAAS,cAAc;AACtC,yBAAmB,IAAI;AACvB,aAAO;AAAA,IACT;AAEA,QAAI,eAAe,OAAO;AACxB,UAAI,SAAS;AACX,gBAAQ,GAAG;AAAA,MACb;AAAA,IACF;AAEA,aAAS,GAAY;AAAA,EACvB,UAAE;AACA,eAAW,KAAK;AAAA,EAClB;AACF;;;AD5FA,IAAIC,YAAW;AAEf,IAAMC,SAA6B,CAAC;AACpC,IAAM,yBAAqB,kCAA8B;AAAA,EACvD,KAAK,OAAO,QAAgB;AAtD9B;AAuDI,YAAO,KAAAA,OAAM,GAAG,MAAT,YAAc,CAAC;AAAA,EACxB;AACF,CAAC;AAEM,SAAS,cAAc;AAAA,EAC5B,MAAM;AAAA,EACN;AAAA,EACA,oBAAoB;AAAA,EACpB,eAAe;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,IAA0B,CAAC,GAAyB;AAElD,QAAM,eAAe,MAAM,cAAcD;AAEzC,QAAM,MAAM,GAAG,OAAO;AACtB,QAAM,WAAO,qCAAY,oBAAoB,MAAM,CAAC,GAAG,GAAG;AAAA,IACxD,aAAa;AAAA,EACf,CAAC;AAED,QAAM,SAAS,CAACE,UAAiB;AAC/B,IAAAD,OAAM,GAAG,IAAIC;AACb,WAAO,mBAAmB,OAAO,CAAC,GAAG,GAAG;AAAA,MACtC,MAAAA;AAAA,MACA,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAGA,QAAM,aAAa;AAEnB,QAAM,CAAC,OAAO,QAAQ,QAAI,+BAAgC,MAAS;AACnE,QAAM,CAAC,YAAY,aAAa,QAAI;AAAA,IAClC;AAAA,EACF;AACA,QAAM,CAAC,WAAW,YAAY,QAAI,+BAAa,KAAK;AAEpD,MAAI,kBAA0C;AAE9C,QAAM,WAA6C,OACjD,QACA,YACG;AArGP;AAsGI,UAAM,gBAAe,gBAAW,MAAX,YAAgB,CAAC;AACtC,WAAO,kBAAkB;AAAA,MACvB;AAAA,MACA;AAAA,MACA;AAAA,MACA,SAAS;AAAA,QACP,GAAG;AAAA,QACH,GAAG,mCAAS;AAAA,MACd;AAAA,MACA,MAAM;AAAA,QACJ,GAAG;AAAA,QACH,GAAG,mCAAS;AAAA,MACd;AAAA,MACA,eAAe;AAAA,MACf,YAAY;AAAA,MACZ;AAAA,MACA,oBAAoB,gBAAc;AAChC,0BAAkB;AAAA,MACpB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ,CAAAA,UAAQ;AACd,sBAAc,CAAC,GAAG,cAAc,GAAIA,SAAA,OAAAA,QAAQ,CAAC,CAAE,CAAC;AAAA,MAClD;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,OAAO,MAAM;AACjB,QAAI,iBAAiB;AACnB,sBAAgB,MAAM;AACtB,wBAAkB;AAAA,IACpB;AAAA,EACF;AAEA,QAAM,gBAAgB,CAACC,gBAAuB;AAC5C,WAAOA,WAAU;AAAA,EACnB;AAEA,QAAM,CAAC,OAAO,QAAQ,QAAI,+BAAa,YAAY;AAEnD,QAAM,eAAe,CAAC,MAAW;AAC/B,MAAE,eAAe;AACjB,UAAM,aAAa,MAAM;AACzB,QAAI,CAAC;AAAY;AACjB,WAAO,SAAS,UAAU;AAAA,EAC5B;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM;AAAA,EACR;AACF;","names":["streamParts","fixFunctionCallArguments","data","messages","import_solid_js","import_solid_swr_store","import_swr_store","uniqueId","store","data","completion"]}
|