@ai-sdk/vue 1.1.5 → 1.1.7
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/CHANGELOG.md +17 -0
- package/dist/index.js +20 -22
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +21 -22
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# @ai-sdk/vue
|
|
2
2
|
|
|
3
|
+
## 1.1.7
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 0d2d9bf: fix (ui): empty submits (with allowEmptySubmit) create user messages
|
|
8
|
+
- 0d2d9bf: fix (ui): single assistant message with multiple tool steps
|
|
9
|
+
- Updated dependencies [0d2d9bf]
|
|
10
|
+
- @ai-sdk/ui-utils@1.1.7
|
|
11
|
+
|
|
12
|
+
## 1.1.6
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- Updated dependencies [3a602ca]
|
|
17
|
+
- @ai-sdk/provider-utils@2.1.5
|
|
18
|
+
- @ai-sdk/ui-utils@1.1.6
|
|
19
|
+
|
|
3
20
|
## 1.1.5
|
|
4
21
|
|
|
5
22
|
### Patch Changes
|
package/dist/index.js
CHANGED
|
@@ -85,8 +85,11 @@ function useChat({
|
|
|
85
85
|
const streamData = (0, import_vue.ref)(void 0);
|
|
86
86
|
let abortController = null;
|
|
87
87
|
async function triggerRequest(messagesSnapshot, { data, headers, body } = {}) {
|
|
88
|
-
var _a2;
|
|
88
|
+
var _a2, _b2, _c;
|
|
89
89
|
const messageCount = messages.value.length;
|
|
90
|
+
const maxStep = (0, import_ui_utils.extractMaxToolInvocationStep)(
|
|
91
|
+
(_a2 = messages.value[messages.value.length - 1]) == null ? void 0 : _a2.toolInvocations
|
|
92
|
+
);
|
|
90
93
|
try {
|
|
91
94
|
error.value = void 0;
|
|
92
95
|
mutateLoading(() => true);
|
|
@@ -99,7 +102,7 @@ function useChat({
|
|
|
99
102
|
headers,
|
|
100
103
|
data
|
|
101
104
|
};
|
|
102
|
-
const existingData = (
|
|
105
|
+
const existingData = (_b2 = streamData.value) != null ? _b2 : [];
|
|
103
106
|
const constructedMessagesPayload = sendExtraMessageFields ? chatRequest.messages : chatRequest.messages.map(
|
|
104
107
|
({
|
|
105
108
|
role,
|
|
@@ -137,8 +140,11 @@ function useChat({
|
|
|
137
140
|
abortController: () => abortController,
|
|
138
141
|
credentials,
|
|
139
142
|
onResponse,
|
|
140
|
-
onUpdate(
|
|
141
|
-
mutate([
|
|
143
|
+
onUpdate({ message, data: data2, replaceLastMessage }) {
|
|
144
|
+
mutate([
|
|
145
|
+
...replaceLastMessage ? chatRequest.messages.slice(0, chatRequest.messages.length - 1) : chatRequest.messages,
|
|
146
|
+
message
|
|
147
|
+
]);
|
|
142
148
|
if (data2 == null ? void 0 : data2.length) {
|
|
143
149
|
streamData.value = [...existingData, ...data2];
|
|
144
150
|
}
|
|
@@ -151,7 +157,8 @@ function useChat({
|
|
|
151
157
|
},
|
|
152
158
|
generateId: generateId2,
|
|
153
159
|
onToolCall,
|
|
154
|
-
fetch: fetch2
|
|
160
|
+
fetch: fetch2,
|
|
161
|
+
lastMessage: chatRequest.messages[chatRequest.messages.length - 1]
|
|
155
162
|
});
|
|
156
163
|
} catch (err) {
|
|
157
164
|
if (err.name === "AbortError") {
|
|
@@ -168,12 +175,14 @@ function useChat({
|
|
|
168
175
|
}
|
|
169
176
|
const lastMessage = messages.value[messages.value.length - 1];
|
|
170
177
|
if (
|
|
171
|
-
// ensure
|
|
172
|
-
|
|
173
|
-
lastMessage
|
|
178
|
+
// ensure there is a last message:
|
|
179
|
+
lastMessage != null && // ensure we actually have new messages (to prevent infinite loops in case of errors):
|
|
180
|
+
(messages.value.length > messageCount || (0, import_ui_utils.extractMaxToolInvocationStep)(lastMessage.toolInvocations) !== maxStep) && // check if the feature is enabled:
|
|
174
181
|
maxSteps && maxSteps > 1 && // check that next step is possible:
|
|
175
|
-
isAssistantMessageWithCompletedToolCalls(lastMessage) && //
|
|
176
|
-
|
|
182
|
+
isAssistantMessageWithCompletedToolCalls(lastMessage) && // check that assistant has not answered yet:
|
|
183
|
+
!lastMessage.content && // empty string or undefined
|
|
184
|
+
// limit the number of automatic steps:
|
|
185
|
+
((_c = (0, import_ui_utils.extractMaxToolInvocationStep)(lastMessage.toolInvocations)) != null ? _c : 0) < maxSteps
|
|
177
186
|
) {
|
|
178
187
|
await triggerRequest(messages.value);
|
|
179
188
|
}
|
|
@@ -232,7 +241,7 @@ function useChat({
|
|
|
232
241
|
options.experimental_attachments
|
|
233
242
|
);
|
|
234
243
|
triggerRequest(
|
|
235
|
-
|
|
244
|
+
messages.value.concat({
|
|
236
245
|
id: generateId2(),
|
|
237
246
|
createdAt: /* @__PURE__ */ new Date(),
|
|
238
247
|
content: inputValue,
|
|
@@ -287,17 +296,6 @@ function useChat({
|
|
|
287
296
|
function isAssistantMessageWithCompletedToolCalls(message) {
|
|
288
297
|
return message.role === "assistant" && message.toolInvocations && message.toolInvocations.length > 0 && message.toolInvocations.every((toolInvocation) => "result" in toolInvocation);
|
|
289
298
|
}
|
|
290
|
-
function countTrailingAssistantMessages(messages) {
|
|
291
|
-
let count = 0;
|
|
292
|
-
for (let i = messages.length - 1; i >= 0; i--) {
|
|
293
|
-
if (messages[i].role === "assistant") {
|
|
294
|
-
count++;
|
|
295
|
-
} else {
|
|
296
|
-
break;
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
return count;
|
|
300
|
-
}
|
|
301
299
|
|
|
302
300
|
// src/use-completion.ts
|
|
303
301
|
var import_ui_utils2 = require("@ai-sdk/ui-utils");
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/use-chat.ts","../src/use-completion.ts","../src/use-assistant.ts"],"sourcesContent":["export * from './use-chat';\nexport * from './use-completion';\nexport * from './use-assistant';\n","import type {\n ChatRequest,\n ChatRequestOptions,\n CreateMessage,\n JSONValue,\n Message,\n UseChatOptions,\n} from '@ai-sdk/ui-utils';\nimport {\n callChatApi,\n generateId as generateIdFunc,\n prepareAttachmentsForRequest,\n} from '@ai-sdk/ui-utils';\nimport swrv from 'swrv';\nimport type { Ref } from 'vue';\nimport { ref, unref } from 'vue';\n\nexport type { CreateMessage, Message, UseChatOptions };\n\nexport type UseChatHelpers = {\n /** Current messages in the chat */\n messages: Ref<Message[]>;\n /** The error object of the API request */\n error: Ref<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 */\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: (\n messages: Message[] | ((messages: Message[]) => Message[]),\n ) => void;\n /** The current value of the input */\n input: Ref<string>;\n /** Form submission handler to automatically reset input and append a user message */\n handleSubmit: (\n event?: { preventDefault?: () => void },\n chatRequestOptions?: ChatRequestOptions,\n ) => void;\n /** Whether the API request is in progress */\n isLoading: Ref<boolean | undefined>;\n\n /** Additional data added on the server via StreamData. */\n data: Ref<JSONValue[] | undefined>;\n /** Set the data of the chat. You can use this to transform or clear the chat data. */\n setData: (\n data:\n | JSONValue[]\n | undefined\n | ((data: JSONValue[] | undefined) => JSONValue[] | undefined),\n ) => void;\n\n addToolResult: ({\n toolCallId,\n result,\n }: {\n toolCallId: string;\n result: any;\n }) => void;\n\n /** The id of the chat */\n id: string;\n};\n\n// @ts-expect-error - some issues with the default export of useSWRV\nconst useSWRV = (swrv.default as typeof import('swrv')['default']) || swrv;\nconst store: Record<string, Message[] | undefined> = {};\n\nexport function useChat(\n {\n api = '/api/chat',\n id,\n initialMessages = [],\n initialInput = '',\n sendExtraMessageFields,\n streamProtocol = 'data',\n onResponse,\n onFinish,\n onError,\n credentials,\n headers: metadataHeaders,\n body: metadataBody,\n generateId = generateIdFunc,\n onToolCall,\n fetch,\n keepLastMessageOnError = true,\n maxSteps,\n }: UseChatOptions & {\n /**\n * Maximum number of sequential LLM calls (steps), e.g. when you use tool calls. Must be at least 1.\n * A maximum number is required to prevent infinite loops in the case of misconfigured tools.\n * By default, it's set to 1, which means that only a single LLM call is made.\n */\n maxSteps?: number;\n } = {\n maxSteps: 1,\n },\n): UseChatHelpers {\n // Generate a unique ID for the chat if not provided.\n const chatId = id ?? generateId();\n\n const key = `${api}|${chatId}`;\n const { data: messagesData, mutate: originalMutate } = useSWRV<Message[]>(\n key,\n () => store[key] || initialMessages,\n );\n\n const { data: isLoading, mutate: mutateLoading } = useSWRV<boolean>(\n `${chatId}-loading`,\n null,\n );\n\n isLoading.value ??= false;\n\n // Force the `data` to be `initialMessages` if it's `undefined`.\n messagesData.value ??= initialMessages;\n\n const mutate = (data?: Message[]) => {\n store[key] = data;\n return originalMutate();\n };\n\n // Because of the `initialData` option, the `data` will never be `undefined`.\n const messages = messagesData as Ref<Message[]>;\n\n const error = ref<undefined | Error>(undefined);\n // cannot use JSONValue[] in ref because of infinite Typescript recursion:\n const streamData = ref<undefined | unknown[]>(undefined);\n\n let abortController: AbortController | null = null;\n\n async function triggerRequest(\n messagesSnapshot: Message[],\n { data, headers, body }: ChatRequestOptions = {},\n ) {\n const messageCount = messages.value.length;\n\n try {\n error.value = undefined;\n mutateLoading(() => true);\n\n abortController = new AbortController();\n\n // Do an optimistic update to the chat state to show the updated messages\n // immediately.\n const previousMessages = messagesSnapshot;\n mutate(messagesSnapshot);\n\n const chatRequest: ChatRequest = {\n messages: messagesSnapshot,\n body,\n headers,\n data,\n };\n\n const existingData = (streamData.value ?? []) as JSONValue[];\n\n const constructedMessagesPayload = sendExtraMessageFields\n ? chatRequest.messages\n : chatRequest.messages.map(\n ({\n role,\n content,\n experimental_attachments,\n data,\n annotations,\n toolInvocations,\n }) => ({\n role,\n content,\n ...(experimental_attachments !== undefined && {\n experimental_attachments,\n }),\n ...(data !== undefined && { data }),\n ...(annotations !== undefined && { annotations }),\n ...(toolInvocations !== undefined && { toolInvocations }),\n }),\n );\n\n await callChatApi({\n api,\n body: {\n id: chatId,\n messages: constructedMessagesPayload,\n data: chatRequest.data,\n ...unref(metadataBody), // Use unref to unwrap the ref value\n ...body,\n },\n streamProtocol,\n headers: {\n ...metadataHeaders,\n ...headers,\n },\n abortController: () => abortController,\n credentials,\n onResponse,\n onUpdate(merged, data) {\n mutate([...chatRequest.messages, ...merged]);\n if (data?.length) {\n streamData.value = [...existingData, ...data];\n }\n },\n onFinish,\n restoreMessagesOnFailure() {\n // Restore the previous messages if the request fails.\n if (!keepLastMessageOnError) {\n mutate(previousMessages);\n }\n },\n generateId,\n onToolCall,\n fetch,\n });\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 error.value = err as Error;\n } finally {\n abortController = null;\n mutateLoading(() => false);\n }\n\n // auto-submit when all tool calls in the last assistant message have results:\n const lastMessage = messages.value[messages.value.length - 1];\n if (\n // ensure we actually have new messages (to prevent infinite loops in case of errors):\n messages.value.length > messageCount &&\n // ensure there is a last message:\n lastMessage != null &&\n // check if the feature is enabled:\n maxSteps &&\n maxSteps > 1 &&\n // check that next step is possible:\n isAssistantMessageWithCompletedToolCalls(lastMessage) &&\n // limit the number of automatic steps:\n countTrailingAssistantMessages(messages.value) <= maxSteps\n ) {\n await triggerRequest(messages.value);\n }\n }\n\n const append: UseChatHelpers['append'] = async (message, options) => {\n const attachmentsForRequest = await prepareAttachmentsForRequest(\n options?.experimental_attachments,\n );\n\n return triggerRequest(\n messages.value.concat({\n ...message,\n id: message.id ?? generateId(),\n createdAt: message.createdAt ?? new Date(),\n experimental_attachments:\n attachmentsForRequest.length > 0 ? attachmentsForRequest : undefined,\n }),\n options,\n );\n };\n\n const reload: UseChatHelpers['reload'] = async options => {\n const messagesSnapshot = messages.value;\n if (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\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 = (\n messagesArg: Message[] | ((messages: Message[]) => Message[]),\n ) => {\n if (typeof messagesArg === 'function') {\n messagesArg = messagesArg(messages.value);\n }\n\n mutate(messagesArg);\n };\n\n const setData = (\n dataArg:\n | JSONValue[]\n | undefined\n | ((data: JSONValue[] | undefined) => JSONValue[] | undefined),\n ) => {\n if (typeof dataArg === 'function') {\n dataArg = dataArg(streamData.value as JSONValue[] | undefined);\n }\n\n streamData.value = dataArg;\n };\n\n const input = ref(initialInput);\n\n const handleSubmit = async (\n event?: { preventDefault?: () => void },\n options: ChatRequestOptions = {},\n ) => {\n event?.preventDefault?.();\n\n const inputValue = input.value;\n\n if (!inputValue && !options.allowEmptySubmit) return;\n\n const attachmentsForRequest = await prepareAttachmentsForRequest(\n options.experimental_attachments,\n );\n\n triggerRequest(\n !inputValue && !attachmentsForRequest.length && options.allowEmptySubmit\n ? messages.value\n : messages.value.concat({\n id: generateId(),\n createdAt: new Date(),\n content: inputValue,\n role: 'user',\n experimental_attachments:\n attachmentsForRequest.length > 0\n ? attachmentsForRequest\n : undefined,\n }),\n options,\n );\n\n input.value = '';\n };\n\n const addToolResult = ({\n toolCallId,\n result,\n }: {\n toolCallId: string;\n result: any;\n }) => {\n const updatedMessages = messages.value.map((message, index, arr) =>\n // update the tool calls in the last assistant message:\n index === arr.length - 1 &&\n message.role === 'assistant' &&\n message.toolInvocations\n ? {\n ...message,\n toolInvocations: message.toolInvocations.map(toolInvocation =>\n toolInvocation.toolCallId === toolCallId\n ? {\n ...toolInvocation,\n result,\n state: 'result' as const,\n }\n : toolInvocation,\n ),\n }\n : message,\n );\n\n mutate(updatedMessages);\n\n // auto-submit when all tool calls in the last assistant message have results:\n const lastMessage = updatedMessages[updatedMessages.length - 1];\n\n if (isAssistantMessageWithCompletedToolCalls(lastMessage)) {\n triggerRequest(updatedMessages);\n }\n };\n\n return {\n id: chatId,\n messages,\n append,\n error,\n reload,\n stop,\n setMessages,\n input,\n handleSubmit,\n isLoading,\n data: streamData as Ref<undefined | JSONValue[]>,\n setData,\n addToolResult,\n };\n}\n\n/**\nCheck if the message is an assistant message with completed tool calls.\nThe message must have at least one tool invocation and all tool invocations\nmust have a result.\n */\nfunction isAssistantMessageWithCompletedToolCalls(message: Message) {\n return (\n message.role === 'assistant' &&\n message.toolInvocations &&\n message.toolInvocations.length > 0 &&\n message.toolInvocations.every(toolInvocation => 'result' in toolInvocation)\n );\n}\n\n/**\nReturns the number of trailing assistant messages in the array.\n */\nfunction countTrailingAssistantMessages(messages: Message[]) {\n let count = 0;\n for (let i = messages.length - 1; i >= 0; i--) {\n if (messages[i].role === 'assistant') {\n count++;\n } else {\n break;\n }\n }\n return count;\n}\n","import type {\n JSONValue,\n RequestOptions,\n UseCompletionOptions,\n} from '@ai-sdk/ui-utils';\nimport { callCompletionApi } from '@ai-sdk/ui-utils';\nimport swrv from 'swrv';\nimport type { Ref } from 'vue';\nimport { ref, unref } from 'vue';\n\nexport type { UseCompletionOptions };\n\nexport type UseCompletionHelpers = {\n /** The current completion result */\n completion: Ref<string>;\n /** The error object of the API request */\n error: Ref<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: Ref<string>;\n /**\n * Form submission handler to automatically reset input and append a user message\n * @example\n * ```jsx\n * <form @submit=\"handleSubmit\">\n * <input @change=\"handleInputChange\" v-model=\"input\" />\n * </form>\n * ```\n */\n handleSubmit: (event?: { preventDefault?: () => void }) => void;\n /** Whether the API request is in progress */\n isLoading: Ref<boolean | undefined>;\n\n /** Additional data added on the server via StreamData */\n data: Ref<JSONValue[] | undefined>;\n};\n\nlet uniqueId = 0;\n\n// @ts-expect-error - some issues with the default export of useSWRV\nconst useSWRV = (swrv.default as typeof import('swrv')['default']) || swrv;\nconst store: Record<string, any> = {};\n\nexport function useCompletion({\n api = '/api/completion',\n id,\n initialCompletion = '',\n initialInput = '',\n credentials,\n headers,\n body,\n streamProtocol,\n onResponse,\n onFinish,\n onError,\n fetch,\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, mutate: originalMutate } = useSWRV<string>(\n key,\n () => store[key] || initialCompletion,\n );\n\n const { data: isLoading, mutate: mutateLoading } = useSWRV<boolean>(\n `${completionId}-loading`,\n null,\n );\n\n isLoading.value ??= false;\n\n const { data: streamData, mutate: mutateStreamData } = useSWRV<\n JSONValue[] | undefined\n >(`${completionId}-data`, null);\n\n // Force the `data` to be `initialCompletion` if it's `undefined`.\n data.value ||= initialCompletion;\n\n const mutate = (data: string) => {\n store[key] = data;\n return originalMutate();\n };\n\n // Because of the `initialData` option, the `data` will never be `undefined`.\n const completion = data as Ref<string>;\n\n const error = ref<undefined | Error>(undefined);\n\n let abortController: AbortController | null = null;\n\n async function triggerRequest(prompt: string, options?: RequestOptions) {\n const existingData = (streamData.value ?? []) as JSONValue[];\n return callCompletionApi({\n api,\n prompt,\n credentials,\n headers: {\n ...headers,\n ...options?.headers,\n },\n body: {\n ...unref(body),\n ...options?.body,\n },\n streamProtocol,\n setCompletion: mutate,\n setLoading: loading => mutateLoading(() => loading),\n setError: err => {\n error.value = err;\n },\n setAbortController: controller => {\n abortController = controller;\n },\n onResponse,\n onFinish,\n onError,\n onData: data => {\n mutateStreamData(() => [...existingData, ...(data ?? [])]);\n },\n fetch,\n });\n }\n\n const complete: UseCompletionHelpers['complete'] = async (\n prompt,\n options,\n ) => {\n return triggerRequest(prompt, options);\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 = ref(initialInput);\n\n const handleSubmit = (event?: { preventDefault?: () => void }) => {\n event?.preventDefault?.();\n const inputValue = input.value;\n return inputValue ? complete(inputValue) : undefined;\n };\n\n return {\n completion,\n complete,\n error,\n stop,\n setCompletion,\n input,\n handleSubmit,\n isLoading,\n data: streamData,\n };\n}\n","/**\n * A vue.js composable function to interact with the assistant API.\n */\n\nimport { isAbortError } from '@ai-sdk/provider-utils';\nimport type {\n AssistantStatus,\n CreateMessage,\n Message,\n UseAssistantOptions,\n} from '@ai-sdk/ui-utils';\nimport { generateId, processAssistantStream } from '@ai-sdk/ui-utils';\nimport type { ComputedRef, Ref } from 'vue';\nimport { computed, readonly, ref } from 'vue';\n\nexport type UseAssistantHelpers = {\n /**\n * The current array of chat messages.\n */\n messages: Ref<Message[]>;\n\n /**\n * Update the message store with a new array of messages.\n */\n setMessages: (messagesProcessor: (messages: Message[]) => Message[]) => void;\n\n /**\n * The current thread ID.\n */\n threadId: Ref<string | undefined>;\n\n /**\n * Set the current thread ID. Specifying a thread ID will switch to that thread, if it exists. If set to 'undefined', a new thread will be created. For both cases, `threadId` will be updated with the new value and `messages` will be cleared.\n */\n setThreadId: (threadId: string | undefined) => void;\n /**\n * The current value of the input field.\n */\n input: Ref<string>;\n\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 requestOptions Additional options to pass to the API call\n */\n append: (\n message: Message | CreateMessage,\n requestOptions?: {\n data?: Record<string, string>;\n },\n ) => Promise<void>;\n\n /**\n * Abort the current request immediately, keep the generated tokens if any.\n */\n stop: ComputedRef<() => void>;\n\n /**\n * Handler for the `onChange` event of the input field to control the input's value.\n */\n handleInputChange: (e: Event & { target: HTMLInputElement }) => void;\n\n /**\n * Handler for the `onSubmit` event of the form to append a user message and reset the input.\n */\n handleSubmit: (e: Event & { target: HTMLFormElement }) => void;\n\n /**\n * Whether the assistant is currently sending a message.\n */\n isSending: ComputedRef<boolean>;\n\n /**\n * The current status of the assistant.\n */\n status: Ref<AssistantStatus>;\n\n /**\n * The current error, if any.\n */\n error: Ref<Error | undefined>;\n};\n\nexport function useAssistant({\n api,\n threadId: threadIdParam,\n credentials,\n headers,\n body,\n onError,\n}: UseAssistantOptions): UseAssistantHelpers {\n const messages: Ref<Message[]> = ref([]);\n const input: Ref<string> = ref('');\n const currentThreadId: Ref<string | undefined> = ref(undefined);\n const status: Ref<AssistantStatus> = ref('awaiting_message');\n const error: Ref<undefined | Error> = ref(undefined);\n\n const setMessages = (messageFactory: (messages: Message[]) => Message[]) => {\n messages.value = messageFactory(messages.value);\n };\n\n const setCurrentThreadId = (newThreadId: string | undefined) => {\n currentThreadId.value = newThreadId;\n messages.value = [];\n };\n\n const handleInputChange = (event: Event & { target: HTMLInputElement }) => {\n input.value = event?.target?.value;\n };\n\n const isSending = computed(() => status.value === 'in_progress');\n\n // Abort controller to cancel the current API call when required\n const abortController = ref<AbortController | null>(null);\n\n // memoized function to stop the current request when required\n const stop = computed(() => {\n return () => {\n if (abortController.value) {\n abortController.value.abort();\n abortController.value = null;\n }\n };\n });\n\n const append = async (\n message: Message | CreateMessage,\n requestOptions?: {\n data?: Record<string, string>;\n },\n ) => {\n status.value = 'in_progress';\n\n // Append the new message to the current list of messages\n const newMessage: Message = {\n ...message,\n id: message.id ?? generateId(),\n };\n\n // Update the messages list with the new message\n setMessages(messages => [...messages, newMessage]);\n\n input.value = '';\n\n const controller = new AbortController();\n\n try {\n // Assign the new controller to the abortController ref\n abortController.value = controller;\n\n const response = await fetch(api, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n },\n body: JSON.stringify({\n ...body,\n // Message Content\n message: message.content,\n\n // Always Use User Provided Thread ID When Available\n threadId: threadIdParam ?? currentThreadId.value ?? null,\n\n // Optional Request Data\n ...(requestOptions?.data && { data: requestOptions?.data }),\n }),\n signal: controller.signal,\n credentials,\n });\n\n if (!response.ok) {\n throw new Error(\n response.statusText ?? 'An error occurred while sending the message',\n );\n }\n\n if (!response.body) {\n throw new Error('The response body is empty');\n }\n\n await processAssistantStream({\n stream: response.body,\n onAssistantMessagePart(value) {\n messages.value = [\n ...messages.value,\n {\n id: value.id,\n content: value.content[0].text.value,\n role: value.role,\n },\n ];\n },\n onTextPart(value) {\n setMessages(messages => {\n const lastMessage = messages[messages.length - 1];\n lastMessage.content += value;\n\n return [...messages.slice(0, -1), lastMessage];\n });\n },\n onAssistantControlDataPart(value) {\n if (value.threadId) {\n currentThreadId.value = value.threadId;\n }\n\n setMessages(messages => {\n const lastMessage = messages[messages.length - 1];\n lastMessage.id = value.messageId;\n\n return [...messages.slice(0, -1), lastMessage];\n });\n },\n onDataMessagePart(value) {\n setMessages(messages => [\n ...messages,\n {\n id: value.id ?? generateId(),\n role: 'data',\n content: '',\n data: value.data,\n },\n ]);\n },\n onErrorPart(value) {\n error.value = new Error(value);\n },\n });\n } catch (err) {\n // If the error is an AbortError and the signal is aborted, reset the abortController and do nothing.\n if (isAbortError(err) && abortController.value?.signal.aborted) {\n abortController.value = null;\n return;\n }\n\n // If an error handler is provided, call it with the error\n if (onError && err instanceof Error) {\n onError(err);\n }\n\n error.value = err as Error;\n } finally {\n // Reset the status to 'awaiting_message' after the request is complete\n abortController.value = null;\n status.value = 'awaiting_message';\n }\n };\n\n const submitMessage = async (\n event: Event & { target: HTMLFormElement },\n requestOptions?: {\n data?: Record<string, string>;\n },\n ) => {\n event?.preventDefault?.();\n\n if (!input.value) return;\n\n append(\n {\n role: 'user',\n content: input.value,\n },\n requestOptions,\n );\n };\n\n return {\n append,\n messages,\n setMessages,\n threadId: readonly(currentThreadId),\n setThreadId: setCurrentThreadId,\n input,\n handleInputChange,\n handleSubmit: submitMessage,\n isSending,\n status,\n error,\n stop,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACQA,sBAIO;AACP,kBAAiB;AAEjB,iBAA2B;AAsE3B,IAAM,UAAW,YAAAA,QAAK,WAAgD,YAAAA;AACtE,IAAM,QAA+C,CAAC;AAE/C,SAAS,QACd;AAAA,EACE,MAAM;AAAA,EACN;AAAA,EACA,kBAAkB,CAAC;AAAA,EACnB,eAAe;AAAA,EACf;AAAA,EACA,iBAAiB;AAAA,EACjB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT,MAAM;AAAA,EACN,YAAAC,cAAa,gBAAAC;AAAA,EACb;AAAA,EACA,OAAAC;AAAA,EACA,yBAAyB;AAAA,EACzB;AACF,IAOI;AAAA,EACF,UAAU;AACZ,GACgB;AArHlB;AAuHE,QAAM,SAAS,kBAAMF,YAAW;AAEhC,QAAM,MAAM,GAAG,GAAG,IAAI,MAAM;AAC5B,QAAM,EAAE,MAAM,cAAc,QAAQ,eAAe,IAAI;AAAA,IACrD;AAAA,IACA,MAAM,MAAM,GAAG,KAAK;AAAA,EACtB;AAEA,QAAM,EAAE,MAAM,WAAW,QAAQ,cAAc,IAAI;AAAA,IACjD,GAAG,MAAM;AAAA,IACT;AAAA,EACF;AAEA,kBAAU,UAAV,sBAAU,QAAU;AAGpB,qBAAa,UAAb,yBAAa,QAAU;AAEvB,QAAM,SAAS,CAAC,SAAqB;AACnC,UAAM,GAAG,IAAI;AACb,WAAO,eAAe;AAAA,EACxB;AAGA,QAAM,WAAW;AAEjB,QAAM,YAAQ,gBAAuB,MAAS;AAE9C,QAAM,iBAAa,gBAA2B,MAAS;AAEvD,MAAI,kBAA0C;AAE9C,iBAAe,eACb,kBACA,EAAE,MAAM,SAAS,KAAK,IAAwB,CAAC,GAC/C;AA1JJ,QAAAG;AA2JI,UAAM,eAAe,SAAS,MAAM;AAEpC,QAAI;AACF,YAAM,QAAQ;AACd,oBAAc,MAAM,IAAI;AAExB,wBAAkB,IAAI,gBAAgB;AAItC,YAAM,mBAAmB;AACzB,aAAO,gBAAgB;AAEvB,YAAM,cAA2B;AAAA,QAC/B,UAAU;AAAA,QACV;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAEA,YAAM,gBAAgBA,MAAA,WAAW,UAAX,OAAAA,MAAoB,CAAC;AAE3C,YAAM,6BAA6B,yBAC/B,YAAY,WACZ,YAAY,SAAS;AAAA,QACnB,CAAC;AAAA,UACC;AAAA,UACA;AAAA,UACA;AAAA,UACA,MAAAC;AAAA,UACA;AAAA,UACA;AAAA,QACF,OAAO;AAAA,UACL;AAAA,UACA;AAAA,UACA,GAAI,6BAA6B,UAAa;AAAA,YAC5C;AAAA,UACF;AAAA,UACA,GAAIA,UAAS,UAAa,EAAE,MAAAA,MAAK;AAAA,UACjC,GAAI,gBAAgB,UAAa,EAAE,YAAY;AAAA,UAC/C,GAAI,oBAAoB,UAAa,EAAE,gBAAgB;AAAA,QACzD;AAAA,MACF;AAEJ,gBAAM,6BAAY;AAAA,QAChB;AAAA,QACA,MAAM;AAAA,UACJ,IAAI;AAAA,UACJ,UAAU;AAAA,UACV,MAAM,YAAY;AAAA,UAClB,OAAG,kBAAM,YAAY;AAAA;AAAA,UACrB,GAAG;AAAA,QACL;AAAA,QACA;AAAA,QACA,SAAS;AAAA,UACP,GAAG;AAAA,UACH,GAAG;AAAA,QACL;AAAA,QACA,iBAAiB,MAAM;AAAA,QACvB;AAAA,QACA;AAAA,QACA,SAAS,QAAQA,OAAM;AACrB,iBAAO,CAAC,GAAG,YAAY,UAAU,GAAG,MAAM,CAAC;AAC3C,cAAIA,SAAA,gBAAAA,MAAM,QAAQ;AAChB,uBAAW,QAAQ,CAAC,GAAG,cAAc,GAAGA,KAAI;AAAA,UAC9C;AAAA,QACF;AAAA,QACA;AAAA,QACA,2BAA2B;AAEzB,cAAI,CAAC,wBAAwB;AAC3B,mBAAO,gBAAgB;AAAA,UACzB;AAAA,QACF;AAAA,QACA,YAAAJ;AAAA,QACA;AAAA,QACA,OAAAE;AAAA,MACF,CAAC;AAAA,IACH,SAAS,KAAK;AAEZ,UAAK,IAAY,SAAS,cAAc;AACtC,0BAAkB;AAClB,eAAO;AAAA,MACT;AAEA,UAAI,WAAW,eAAe,OAAO;AACnC,gBAAQ,GAAG;AAAA,MACb;AAEA,YAAM,QAAQ;AAAA,IAChB,UAAE;AACA,wBAAkB;AAClB,oBAAc,MAAM,KAAK;AAAA,IAC3B;AAGA,UAAM,cAAc,SAAS,MAAM,SAAS,MAAM,SAAS,CAAC;AAC5D;AAAA;AAAA,MAEE,SAAS,MAAM,SAAS;AAAA,MAExB,eAAe;AAAA,MAEf,YACA,WAAW;AAAA,MAEX,yCAAyC,WAAW;AAAA,MAEpD,+BAA+B,SAAS,KAAK,KAAK;AAAA,MAClD;AACA,YAAM,eAAe,SAAS,KAAK;AAAA,IACrC;AAAA,EACF;AAEA,QAAM,SAAmC,OAAO,SAAS,YAAY;AA7QvE,QAAAC,KAAAE;AA8QI,UAAM,wBAAwB,UAAM;AAAA,MAClC,mCAAS;AAAA,IACX;AAEA,WAAO;AAAA,MACL,SAAS,MAAM,OAAO;AAAA,QACpB,GAAG;AAAA,QACH,KAAIF,MAAA,QAAQ,OAAR,OAAAA,MAAcH,YAAW;AAAA,QAC7B,YAAWK,MAAA,QAAQ,cAAR,OAAAA,MAAqB,oBAAI,KAAK;AAAA,QACzC,0BACE,sBAAsB,SAAS,IAAI,wBAAwB;AAAA,MAC/D,CAAC;AAAA,MACD;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAmC,OAAM,YAAW;AACxD,UAAM,mBAAmB,SAAS;AAClC,QAAI,iBAAiB,WAAW;AAAG,aAAO;AAE1C,UAAM,cAAc,iBAAiB,iBAAiB,SAAS,CAAC;AAChE,QAAI,YAAY,SAAS,aAAa;AACpC,aAAO,eAAe,iBAAiB,MAAM,GAAG,EAAE,GAAG,OAAO;AAAA,IAC9D;AAEA,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,CAClB,gBACG;AACH,QAAI,OAAO,gBAAgB,YAAY;AACrC,oBAAc,YAAY,SAAS,KAAK;AAAA,IAC1C;AAEA,WAAO,WAAW;AAAA,EACpB;AAEA,QAAM,UAAU,CACd,YAIG;AACH,QAAI,OAAO,YAAY,YAAY;AACjC,gBAAU,QAAQ,WAAW,KAAgC;AAAA,IAC/D;AAEA,eAAW,QAAQ;AAAA,EACrB;AAEA,QAAM,YAAQ,gBAAI,YAAY;AAE9B,QAAM,eAAe,OACnB,OACA,UAA8B,CAAC,MAC5B;AA7UP,QAAAF;AA8UI,KAAAA,MAAA,+BAAO,mBAAP,gBAAAA,IAAA;AAEA,UAAM,aAAa,MAAM;AAEzB,QAAI,CAAC,cAAc,CAAC,QAAQ;AAAkB;AAE9C,UAAM,wBAAwB,UAAM;AAAA,MAClC,QAAQ;AAAA,IACV;AAEA;AAAA,MACE,CAAC,cAAc,CAAC,sBAAsB,UAAU,QAAQ,mBACpD,SAAS,QACT,SAAS,MAAM,OAAO;AAAA,QACpB,IAAIH,YAAW;AAAA,QACf,WAAW,oBAAI,KAAK;AAAA,QACpB,SAAS;AAAA,QACT,MAAM;AAAA,QACN,0BACE,sBAAsB,SAAS,IAC3B,wBACA;AAAA,MACR,CAAC;AAAA,MACL;AAAA,IACF;AAEA,UAAM,QAAQ;AAAA,EAChB;AAEA,QAAM,gBAAgB,CAAC;AAAA,IACrB;AAAA,IACA;AAAA,EACF,MAGM;AACJ,UAAM,kBAAkB,SAAS,MAAM;AAAA,MAAI,CAAC,SAAS,OAAO;AAAA;AAAA,QAE1D,UAAU,IAAI,SAAS,KACvB,QAAQ,SAAS,eACjB,QAAQ,kBACJ;AAAA,UACE,GAAG;AAAA,UACH,iBAAiB,QAAQ,gBAAgB;AAAA,YAAI,oBAC3C,eAAe,eAAe,aAC1B;AAAA,cACE,GAAG;AAAA,cACH;AAAA,cACA,OAAO;AAAA,YACT,IACA;AAAA,UACN;AAAA,QACF,IACA;AAAA;AAAA,IACN;AAEA,WAAO,eAAe;AAGtB,UAAM,cAAc,gBAAgB,gBAAgB,SAAS,CAAC;AAE9D,QAAI,yCAAyC,WAAW,GAAG;AACzD,qBAAe,eAAe;AAAA,IAChC;AAAA,EACF;AAEA,SAAO;AAAA,IACL,IAAI;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM;AAAA,IACN;AAAA,IACA;AAAA,EACF;AACF;AAOA,SAAS,yCAAyC,SAAkB;AAClE,SACE,QAAQ,SAAS,eACjB,QAAQ,mBACR,QAAQ,gBAAgB,SAAS,KACjC,QAAQ,gBAAgB,MAAM,oBAAkB,YAAY,cAAc;AAE9E;AAKA,SAAS,+BAA+B,UAAqB;AAC3D,MAAI,QAAQ;AACZ,WAAS,IAAI,SAAS,SAAS,GAAG,KAAK,GAAG,KAAK;AAC7C,QAAI,SAAS,CAAC,EAAE,SAAS,aAAa;AACpC;AAAA,IACF,OAAO;AACL;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;;;ACvbA,IAAAM,mBAAkC;AAClC,IAAAC,eAAiB;AAEjB,IAAAC,cAA2B;AA2C3B,IAAI,WAAW;AAGf,IAAMC,WAAW,aAAAC,QAAK,WAAgD,aAAAA;AACtE,IAAMC,SAA6B,CAAC;AAE7B,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;AAAA,EACA;AAAA,EACA,OAAAC;AACF,IAA0B,CAAC,GAAyB;AAtEpD;AAwEE,QAAM,eAAe,MAAM,cAAc,UAAU;AAEnD,QAAM,MAAM,GAAG,GAAG,IAAI,YAAY;AAClC,QAAM,EAAE,MAAM,QAAQ,eAAe,IAAIH;AAAA,IACvC;AAAA,IACA,MAAME,OAAM,GAAG,KAAK;AAAA,EACtB;AAEA,QAAM,EAAE,MAAM,WAAW,QAAQ,cAAc,IAAIF;AAAA,IACjD,GAAG,YAAY;AAAA,IACf;AAAA,EACF;AAEA,kBAAU,UAAV,sBAAU,QAAU;AAEpB,QAAM,EAAE,MAAM,YAAY,QAAQ,iBAAiB,IAAIA,SAErD,GAAG,YAAY,SAAS,IAAI;AAG9B,OAAK,UAAL,KAAK,QAAU;AAEf,QAAM,SAAS,CAACI,UAAiB;AAC/B,IAAAF,OAAM,GAAG,IAAIE;AACb,WAAO,eAAe;AAAA,EACxB;AAGA,QAAM,aAAa;AAEnB,QAAM,YAAQ,iBAAuB,MAAS;AAE9C,MAAI,kBAA0C;AAE9C,iBAAe,eAAe,QAAgB,SAA0B;AA1G1E,QAAAC;AA2GI,UAAM,gBAAgBA,MAAA,WAAW,UAAX,OAAAA,MAAoB,CAAC;AAC3C,eAAO,oCAAkB;AAAA,MACvB;AAAA,MACA;AAAA,MACA;AAAA,MACA,SAAS;AAAA,QACP,GAAG;AAAA,QACH,GAAG,mCAAS;AAAA,MACd;AAAA,MACA,MAAM;AAAA,QACJ,OAAG,mBAAM,IAAI;AAAA,QACb,GAAG,mCAAS;AAAA,MACd;AAAA,MACA;AAAA,MACA,eAAe;AAAA,MACf,YAAY,aAAW,cAAc,MAAM,OAAO;AAAA,MAClD,UAAU,SAAO;AACf,cAAM,QAAQ;AAAA,MAChB;AAAA,MACA,oBAAoB,gBAAc;AAChC,0BAAkB;AAAA,MACpB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ,CAAAD,UAAQ;AACd,yBAAiB,MAAM,CAAC,GAAG,cAAc,GAAIA,SAAA,OAAAA,QAAQ,CAAC,CAAE,CAAC;AAAA,MAC3D;AAAA,MACA,OAAAD;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,WAA6C,OACjD,QACA,YACG;AACH,WAAO,eAAe,QAAQ,OAAO;AAAA,EACvC;AAEA,QAAM,OAAO,MAAM;AACjB,QAAI,iBAAiB;AACnB,sBAAgB,MAAM;AACtB,wBAAkB;AAAA,IACpB;AAAA,EACF;AAEA,QAAM,gBAAgB,CAACG,gBAAuB;AAC5C,WAAOA,WAAU;AAAA,EACnB;AAEA,QAAM,YAAQ,iBAAI,YAAY;AAE9B,QAAM,eAAe,CAAC,UAA4C;AA/JpE,QAAAD;AAgKI,KAAAA,MAAA,+BAAO,mBAAP,gBAAAA,IAAA;AACA,UAAM,aAAa,MAAM;AACzB,WAAO,aAAa,SAAS,UAAU,IAAI;AAAA,EAC7C;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM;AAAA,EACR;AACF;;;AC5KA,4BAA6B;AAO7B,IAAAE,mBAAmD;AAEnD,IAAAC,cAAwC;AAuEjC,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA,UAAU;AAAA,EACV;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA6C;AAC3C,QAAM,eAA2B,iBAAI,CAAC,CAAC;AACvC,QAAM,YAAqB,iBAAI,EAAE;AACjC,QAAM,sBAA2C,iBAAI,MAAS;AAC9D,QAAM,aAA+B,iBAAI,kBAAkB;AAC3D,QAAM,YAAgC,iBAAI,MAAS;AAEnD,QAAM,cAAc,CAAC,mBAAuD;AAC1E,aAAS,QAAQ,eAAe,SAAS,KAAK;AAAA,EAChD;AAEA,QAAM,qBAAqB,CAAC,gBAAoC;AAC9D,oBAAgB,QAAQ;AACxB,aAAS,QAAQ,CAAC;AAAA,EACpB;AAEA,QAAM,oBAAoB,CAAC,UAAgD;AA3G7E;AA4GI,UAAM,SAAQ,oCAAO,WAAP,mBAAe;AAAA,EAC/B;AAEA,QAAM,gBAAY,sBAAS,MAAM,OAAO,UAAU,aAAa;AAG/D,QAAM,sBAAkB,iBAA4B,IAAI;AAGxD,QAAM,WAAO,sBAAS,MAAM;AAC1B,WAAO,MAAM;AACX,UAAI,gBAAgB,OAAO;AACzB,wBAAgB,MAAM,MAAM;AAC5B,wBAAgB,QAAQ;AAAA,MAC1B;AAAA,IACF;AAAA,EACF,CAAC;AAED,QAAM,SAAS,OACb,SACA,mBAGG;AAnIP;AAoII,WAAO,QAAQ;AAGf,UAAM,aAAsB;AAAA,MAC1B,GAAG;AAAA,MACH,KAAI,aAAQ,OAAR,gBAAc,6BAAW;AAAA,IAC/B;AAGA,gBAAY,CAAAC,cAAY,CAAC,GAAGA,WAAU,UAAU,CAAC;AAEjD,UAAM,QAAQ;AAEd,UAAM,aAAa,IAAI,gBAAgB;AAEvC,QAAI;AAEF,sBAAgB,QAAQ;AAExB,YAAM,WAAW,MAAM,MAAM,KAAK;AAAA,QAChC,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,UAChB,GAAG;AAAA,QACL;AAAA,QACA,MAAM,KAAK,UAAU;AAAA,UACnB,GAAG;AAAA;AAAA,UAEH,SAAS,QAAQ;AAAA;AAAA,UAGjB,WAAU,6CAAiB,gBAAgB,UAAjC,YAA0C;AAAA;AAAA,UAGpD,IAAI,iDAAgB,SAAQ,EAAE,MAAM,iDAAgB,KAAK;AAAA,QAC3D,CAAC;AAAA,QACD,QAAQ,WAAW;AAAA,QACnB;AAAA,MACF,CAAC;AAED,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,IAAI;AAAA,WACR,cAAS,eAAT,YAAuB;AAAA,QACzB;AAAA,MACF;AAEA,UAAI,CAAC,SAAS,MAAM;AAClB,cAAM,IAAI,MAAM,4BAA4B;AAAA,MAC9C;AAEA,gBAAM,yCAAuB;AAAA,QAC3B,QAAQ,SAAS;AAAA,QACjB,uBAAuB,OAAO;AAC5B,mBAAS,QAAQ;AAAA,YACf,GAAG,SAAS;AAAA,YACZ;AAAA,cACE,IAAI,MAAM;AAAA,cACV,SAAS,MAAM,QAAQ,CAAC,EAAE,KAAK;AAAA,cAC/B,MAAM,MAAM;AAAA,YACd;AAAA,UACF;AAAA,QACF;AAAA,QACA,WAAW,OAAO;AAChB,sBAAY,CAAAA,cAAY;AACtB,kBAAM,cAAcA,UAASA,UAAS,SAAS,CAAC;AAChD,wBAAY,WAAW;AAEvB,mBAAO,CAAC,GAAGA,UAAS,MAAM,GAAG,EAAE,GAAG,WAAW;AAAA,UAC/C,CAAC;AAAA,QACH;AAAA,QACA,2BAA2B,OAAO;AAChC,cAAI,MAAM,UAAU;AAClB,4BAAgB,QAAQ,MAAM;AAAA,UAChC;AAEA,sBAAY,CAAAA,cAAY;AACtB,kBAAM,cAAcA,UAASA,UAAS,SAAS,CAAC;AAChD,wBAAY,KAAK,MAAM;AAEvB,mBAAO,CAAC,GAAGA,UAAS,MAAM,GAAG,EAAE,GAAG,WAAW;AAAA,UAC/C,CAAC;AAAA,QACH;AAAA,QACA,kBAAkB,OAAO;AACvB,sBAAY,CAAAA,cAAS;AAvN/B,gBAAAC;AAuNkC;AAAA,cACtB,GAAGD;AAAA,cACH;AAAA,gBACE,KAAIC,MAAA,MAAM,OAAN,OAAAA,UAAY,6BAAW;AAAA,gBAC3B,MAAM;AAAA,gBACN,SAAS;AAAA,gBACT,MAAM,MAAM;AAAA,cACd;AAAA,YACF;AAAA,WAAC;AAAA,QACH;AAAA,QACA,YAAY,OAAO;AACjB,gBAAM,QAAQ,IAAI,MAAM,KAAK;AAAA,QAC/B;AAAA,MACF,CAAC;AAAA,IACH,SAAS,KAAK;AAEZ,cAAI,oCAAa,GAAG,OAAK,qBAAgB,UAAhB,mBAAuB,OAAO,UAAS;AAC9D,wBAAgB,QAAQ;AACxB;AAAA,MACF;AAGA,UAAI,WAAW,eAAe,OAAO;AACnC,gBAAQ,GAAG;AAAA,MACb;AAEA,YAAM,QAAQ;AAAA,IAChB,UAAE;AAEA,sBAAgB,QAAQ;AACxB,aAAO,QAAQ;AAAA,IACjB;AAAA,EACF;AAEA,QAAM,gBAAgB,OACpB,OACA,mBAGG;AA9PP;AA+PI,yCAAO,mBAAP;AAEA,QAAI,CAAC,MAAM;AAAO;AAElB;AAAA,MACE;AAAA,QACE,MAAM;AAAA,QACN,SAAS,MAAM;AAAA,MACjB;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAU,sBAAS,eAAe;AAAA,IAClC,aAAa;AAAA,IACb;AAAA,IACA;AAAA,IACA,cAAc;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;","names":["swrv","generateId","generateIdFunc","fetch","_a","data","_b","import_ui_utils","import_swrv","import_vue","useSWRV","swrv","store","fetch","data","_a","completion","import_ui_utils","import_vue","messages","_a"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/use-chat.ts","../src/use-completion.ts","../src/use-assistant.ts"],"sourcesContent":["export * from './use-chat';\nexport * from './use-completion';\nexport * from './use-assistant';\n","import type {\n ChatRequest,\n ChatRequestOptions,\n CreateMessage,\n JSONValue,\n Message,\n UseChatOptions,\n} from '@ai-sdk/ui-utils';\nimport {\n callChatApi,\n extractMaxToolInvocationStep,\n generateId as generateIdFunc,\n prepareAttachmentsForRequest,\n} from '@ai-sdk/ui-utils';\nimport swrv from 'swrv';\nimport type { Ref } from 'vue';\nimport { ref, unref } from 'vue';\n\nexport type { CreateMessage, Message, UseChatOptions };\n\nexport type UseChatHelpers = {\n /** Current messages in the chat */\n messages: Ref<Message[]>;\n /** The error object of the API request */\n error: Ref<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 */\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: (\n messages: Message[] | ((messages: Message[]) => Message[]),\n ) => void;\n /** The current value of the input */\n input: Ref<string>;\n /** Form submission handler to automatically reset input and append a user message */\n handleSubmit: (\n event?: { preventDefault?: () => void },\n chatRequestOptions?: ChatRequestOptions,\n ) => void;\n /** Whether the API request is in progress */\n isLoading: Ref<boolean | undefined>;\n\n /** Additional data added on the server via StreamData. */\n data: Ref<JSONValue[] | undefined>;\n /** Set the data of the chat. You can use this to transform or clear the chat data. */\n setData: (\n data:\n | JSONValue[]\n | undefined\n | ((data: JSONValue[] | undefined) => JSONValue[] | undefined),\n ) => void;\n\n addToolResult: ({\n toolCallId,\n result,\n }: {\n toolCallId: string;\n result: any;\n }) => void;\n\n /** The id of the chat */\n id: string;\n};\n\n// @ts-expect-error - some issues with the default export of useSWRV\nconst useSWRV = (swrv.default as typeof import('swrv')['default']) || swrv;\nconst store: Record<string, Message[] | undefined> = {};\n\nexport function useChat(\n {\n api = '/api/chat',\n id,\n initialMessages = [],\n initialInput = '',\n sendExtraMessageFields,\n streamProtocol = 'data',\n onResponse,\n onFinish,\n onError,\n credentials,\n headers: metadataHeaders,\n body: metadataBody,\n generateId = generateIdFunc,\n onToolCall,\n fetch,\n keepLastMessageOnError = true,\n maxSteps,\n }: UseChatOptions & {\n /**\n * Maximum number of sequential LLM calls (steps), e.g. when you use tool calls. Must be at least 1.\n * A maximum number is required to prevent infinite loops in the case of misconfigured tools.\n * By default, it's set to 1, which means that only a single LLM call is made.\n */\n maxSteps?: number;\n } = {\n maxSteps: 1,\n },\n): UseChatHelpers {\n // Generate a unique ID for the chat if not provided.\n const chatId = id ?? generateId();\n\n const key = `${api}|${chatId}`;\n const { data: messagesData, mutate: originalMutate } = useSWRV<Message[]>(\n key,\n () => store[key] || initialMessages,\n );\n\n const { data: isLoading, mutate: mutateLoading } = useSWRV<boolean>(\n `${chatId}-loading`,\n null,\n );\n\n isLoading.value ??= false;\n\n // Force the `data` to be `initialMessages` if it's `undefined`.\n messagesData.value ??= initialMessages;\n\n const mutate = (data?: Message[]) => {\n store[key] = data;\n return originalMutate();\n };\n\n // Because of the `initialData` option, the `data` will never be `undefined`.\n const messages = messagesData as Ref<Message[]>;\n\n const error = ref<undefined | Error>(undefined);\n // cannot use JSONValue[] in ref because of infinite Typescript recursion:\n const streamData = ref<undefined | unknown[]>(undefined);\n\n let abortController: AbortController | null = null;\n\n async function triggerRequest(\n messagesSnapshot: Message[],\n { data, headers, body }: ChatRequestOptions = {},\n ) {\n const messageCount = messages.value.length;\n const maxStep = extractMaxToolInvocationStep(\n messages.value[messages.value.length - 1]?.toolInvocations,\n );\n\n try {\n error.value = undefined;\n mutateLoading(() => true);\n\n abortController = new AbortController();\n\n // Do an optimistic update to the chat state to show the updated messages\n // immediately.\n const previousMessages = messagesSnapshot;\n mutate(messagesSnapshot);\n\n const chatRequest: ChatRequest = {\n messages: messagesSnapshot,\n body,\n headers,\n data,\n };\n\n const existingData = (streamData.value ?? []) as JSONValue[];\n\n const constructedMessagesPayload = sendExtraMessageFields\n ? chatRequest.messages\n : chatRequest.messages.map(\n ({\n role,\n content,\n experimental_attachments,\n data,\n annotations,\n toolInvocations,\n }) => ({\n role,\n content,\n ...(experimental_attachments !== undefined && {\n experimental_attachments,\n }),\n ...(data !== undefined && { data }),\n ...(annotations !== undefined && { annotations }),\n ...(toolInvocations !== undefined && { toolInvocations }),\n }),\n );\n\n await callChatApi({\n api,\n body: {\n id: chatId,\n messages: constructedMessagesPayload,\n data: chatRequest.data,\n ...unref(metadataBody), // Use unref to unwrap the ref value\n ...body,\n },\n streamProtocol,\n headers: {\n ...metadataHeaders,\n ...headers,\n },\n abortController: () => abortController,\n credentials,\n onResponse,\n onUpdate({ message, data, replaceLastMessage }) {\n mutate([\n ...(replaceLastMessage\n ? chatRequest.messages.slice(0, chatRequest.messages.length - 1)\n : chatRequest.messages),\n message,\n ]);\n if (data?.length) {\n streamData.value = [...existingData, ...data];\n }\n },\n onFinish,\n restoreMessagesOnFailure() {\n // Restore the previous messages if the request fails.\n if (!keepLastMessageOnError) {\n mutate(previousMessages);\n }\n },\n generateId,\n onToolCall,\n fetch,\n lastMessage: chatRequest.messages[chatRequest.messages.length - 1],\n });\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 error.value = err as Error;\n } finally {\n abortController = null;\n mutateLoading(() => false);\n }\n\n // auto-submit when all tool calls in the last assistant message have results:\n const lastMessage = messages.value[messages.value.length - 1];\n if (\n // ensure there is a last message:\n lastMessage != null &&\n // ensure we actually have new messages (to prevent infinite loops in case of errors):\n (messages.value.length > messageCount ||\n extractMaxToolInvocationStep(lastMessage.toolInvocations) !==\n maxStep) &&\n // check if the feature is enabled:\n maxSteps &&\n maxSteps > 1 &&\n // check that next step is possible:\n isAssistantMessageWithCompletedToolCalls(lastMessage) &&\n // check that assistant has not answered yet:\n !lastMessage.content && // empty string or undefined\n // limit the number of automatic steps:\n (extractMaxToolInvocationStep(lastMessage.toolInvocations) ?? 0) <\n maxSteps\n ) {\n await triggerRequest(messages.value);\n }\n }\n\n const append: UseChatHelpers['append'] = async (message, options) => {\n const attachmentsForRequest = await prepareAttachmentsForRequest(\n options?.experimental_attachments,\n );\n\n return triggerRequest(\n messages.value.concat({\n ...message,\n id: message.id ?? generateId(),\n createdAt: message.createdAt ?? new Date(),\n experimental_attachments:\n attachmentsForRequest.length > 0 ? attachmentsForRequest : undefined,\n }),\n options,\n );\n };\n\n const reload: UseChatHelpers['reload'] = async options => {\n const messagesSnapshot = messages.value;\n if (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\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 = (\n messagesArg: Message[] | ((messages: Message[]) => Message[]),\n ) => {\n if (typeof messagesArg === 'function') {\n messagesArg = messagesArg(messages.value);\n }\n\n mutate(messagesArg);\n };\n\n const setData = (\n dataArg:\n | JSONValue[]\n | undefined\n | ((data: JSONValue[] | undefined) => JSONValue[] | undefined),\n ) => {\n if (typeof dataArg === 'function') {\n dataArg = dataArg(streamData.value as JSONValue[] | undefined);\n }\n\n streamData.value = dataArg;\n };\n\n const input = ref(initialInput);\n\n const handleSubmit = async (\n event?: { preventDefault?: () => void },\n options: ChatRequestOptions = {},\n ) => {\n event?.preventDefault?.();\n\n const inputValue = input.value;\n\n if (!inputValue && !options.allowEmptySubmit) return;\n\n const attachmentsForRequest = await prepareAttachmentsForRequest(\n options.experimental_attachments,\n );\n\n triggerRequest(\n messages.value.concat({\n id: generateId(),\n createdAt: new Date(),\n content: inputValue,\n role: 'user',\n experimental_attachments:\n attachmentsForRequest.length > 0 ? attachmentsForRequest : undefined,\n }),\n options,\n );\n\n input.value = '';\n };\n\n const addToolResult = ({\n toolCallId,\n result,\n }: {\n toolCallId: string;\n result: any;\n }) => {\n const updatedMessages = messages.value.map((message, index, arr) =>\n // update the tool calls in the last assistant message:\n index === arr.length - 1 &&\n message.role === 'assistant' &&\n message.toolInvocations\n ? {\n ...message,\n toolInvocations: message.toolInvocations.map(toolInvocation =>\n toolInvocation.toolCallId === toolCallId\n ? {\n ...toolInvocation,\n result,\n state: 'result' as const,\n }\n : toolInvocation,\n ),\n }\n : message,\n );\n\n mutate(updatedMessages);\n\n // auto-submit when all tool calls in the last assistant message have results:\n const lastMessage = updatedMessages[updatedMessages.length - 1];\n\n if (isAssistantMessageWithCompletedToolCalls(lastMessage)) {\n triggerRequest(updatedMessages);\n }\n };\n\n return {\n id: chatId,\n messages,\n append,\n error,\n reload,\n stop,\n setMessages,\n input,\n handleSubmit,\n isLoading,\n data: streamData as Ref<undefined | JSONValue[]>,\n setData,\n addToolResult,\n };\n}\n\n/**\nCheck if the message is an assistant message with completed tool calls.\nThe message must have at least one tool invocation and all tool invocations\nmust have a result.\n */\nfunction isAssistantMessageWithCompletedToolCalls(message: Message) {\n return (\n message.role === 'assistant' &&\n message.toolInvocations &&\n message.toolInvocations.length > 0 &&\n message.toolInvocations.every(toolInvocation => 'result' in toolInvocation)\n );\n}\n","import type {\n JSONValue,\n RequestOptions,\n UseCompletionOptions,\n} from '@ai-sdk/ui-utils';\nimport { callCompletionApi } from '@ai-sdk/ui-utils';\nimport swrv from 'swrv';\nimport type { Ref } from 'vue';\nimport { ref, unref } from 'vue';\n\nexport type { UseCompletionOptions };\n\nexport type UseCompletionHelpers = {\n /** The current completion result */\n completion: Ref<string>;\n /** The error object of the API request */\n error: Ref<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: Ref<string>;\n /**\n * Form submission handler to automatically reset input and append a user message\n * @example\n * ```jsx\n * <form @submit=\"handleSubmit\">\n * <input @change=\"handleInputChange\" v-model=\"input\" />\n * </form>\n * ```\n */\n handleSubmit: (event?: { preventDefault?: () => void }) => void;\n /** Whether the API request is in progress */\n isLoading: Ref<boolean | undefined>;\n\n /** Additional data added on the server via StreamData */\n data: Ref<JSONValue[] | undefined>;\n};\n\nlet uniqueId = 0;\n\n// @ts-expect-error - some issues with the default export of useSWRV\nconst useSWRV = (swrv.default as typeof import('swrv')['default']) || swrv;\nconst store: Record<string, any> = {};\n\nexport function useCompletion({\n api = '/api/completion',\n id,\n initialCompletion = '',\n initialInput = '',\n credentials,\n headers,\n body,\n streamProtocol,\n onResponse,\n onFinish,\n onError,\n fetch,\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, mutate: originalMutate } = useSWRV<string>(\n key,\n () => store[key] || initialCompletion,\n );\n\n const { data: isLoading, mutate: mutateLoading } = useSWRV<boolean>(\n `${completionId}-loading`,\n null,\n );\n\n isLoading.value ??= false;\n\n const { data: streamData, mutate: mutateStreamData } = useSWRV<\n JSONValue[] | undefined\n >(`${completionId}-data`, null);\n\n // Force the `data` to be `initialCompletion` if it's `undefined`.\n data.value ||= initialCompletion;\n\n const mutate = (data: string) => {\n store[key] = data;\n return originalMutate();\n };\n\n // Because of the `initialData` option, the `data` will never be `undefined`.\n const completion = data as Ref<string>;\n\n const error = ref<undefined | Error>(undefined);\n\n let abortController: AbortController | null = null;\n\n async function triggerRequest(prompt: string, options?: RequestOptions) {\n const existingData = (streamData.value ?? []) as JSONValue[];\n return callCompletionApi({\n api,\n prompt,\n credentials,\n headers: {\n ...headers,\n ...options?.headers,\n },\n body: {\n ...unref(body),\n ...options?.body,\n },\n streamProtocol,\n setCompletion: mutate,\n setLoading: loading => mutateLoading(() => loading),\n setError: err => {\n error.value = err;\n },\n setAbortController: controller => {\n abortController = controller;\n },\n onResponse,\n onFinish,\n onError,\n onData: data => {\n mutateStreamData(() => [...existingData, ...(data ?? [])]);\n },\n fetch,\n });\n }\n\n const complete: UseCompletionHelpers['complete'] = async (\n prompt,\n options,\n ) => {\n return triggerRequest(prompt, options);\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 = ref(initialInput);\n\n const handleSubmit = (event?: { preventDefault?: () => void }) => {\n event?.preventDefault?.();\n const inputValue = input.value;\n return inputValue ? complete(inputValue) : undefined;\n };\n\n return {\n completion,\n complete,\n error,\n stop,\n setCompletion,\n input,\n handleSubmit,\n isLoading,\n data: streamData,\n };\n}\n","/**\n * A vue.js composable function to interact with the assistant API.\n */\n\nimport { isAbortError } from '@ai-sdk/provider-utils';\nimport type {\n AssistantStatus,\n CreateMessage,\n Message,\n UseAssistantOptions,\n} from '@ai-sdk/ui-utils';\nimport { generateId, processAssistantStream } from '@ai-sdk/ui-utils';\nimport type { ComputedRef, Ref } from 'vue';\nimport { computed, readonly, ref } from 'vue';\n\nexport type UseAssistantHelpers = {\n /**\n * The current array of chat messages.\n */\n messages: Ref<Message[]>;\n\n /**\n * Update the message store with a new array of messages.\n */\n setMessages: (messagesProcessor: (messages: Message[]) => Message[]) => void;\n\n /**\n * The current thread ID.\n */\n threadId: Ref<string | undefined>;\n\n /**\n * Set the current thread ID. Specifying a thread ID will switch to that thread, if it exists. If set to 'undefined', a new thread will be created. For both cases, `threadId` will be updated with the new value and `messages` will be cleared.\n */\n setThreadId: (threadId: string | undefined) => void;\n /**\n * The current value of the input field.\n */\n input: Ref<string>;\n\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 requestOptions Additional options to pass to the API call\n */\n append: (\n message: Message | CreateMessage,\n requestOptions?: {\n data?: Record<string, string>;\n },\n ) => Promise<void>;\n\n /**\n * Abort the current request immediately, keep the generated tokens if any.\n */\n stop: ComputedRef<() => void>;\n\n /**\n * Handler for the `onChange` event of the input field to control the input's value.\n */\n handleInputChange: (e: Event & { target: HTMLInputElement }) => void;\n\n /**\n * Handler for the `onSubmit` event of the form to append a user message and reset the input.\n */\n handleSubmit: (e: Event & { target: HTMLFormElement }) => void;\n\n /**\n * Whether the assistant is currently sending a message.\n */\n isSending: ComputedRef<boolean>;\n\n /**\n * The current status of the assistant.\n */\n status: Ref<AssistantStatus>;\n\n /**\n * The current error, if any.\n */\n error: Ref<Error | undefined>;\n};\n\nexport function useAssistant({\n api,\n threadId: threadIdParam,\n credentials,\n headers,\n body,\n onError,\n}: UseAssistantOptions): UseAssistantHelpers {\n const messages: Ref<Message[]> = ref([]);\n const input: Ref<string> = ref('');\n const currentThreadId: Ref<string | undefined> = ref(undefined);\n const status: Ref<AssistantStatus> = ref('awaiting_message');\n const error: Ref<undefined | Error> = ref(undefined);\n\n const setMessages = (messageFactory: (messages: Message[]) => Message[]) => {\n messages.value = messageFactory(messages.value);\n };\n\n const setCurrentThreadId = (newThreadId: string | undefined) => {\n currentThreadId.value = newThreadId;\n messages.value = [];\n };\n\n const handleInputChange = (event: Event & { target: HTMLInputElement }) => {\n input.value = event?.target?.value;\n };\n\n const isSending = computed(() => status.value === 'in_progress');\n\n // Abort controller to cancel the current API call when required\n const abortController = ref<AbortController | null>(null);\n\n // memoized function to stop the current request when required\n const stop = computed(() => {\n return () => {\n if (abortController.value) {\n abortController.value.abort();\n abortController.value = null;\n }\n };\n });\n\n const append = async (\n message: Message | CreateMessage,\n requestOptions?: {\n data?: Record<string, string>;\n },\n ) => {\n status.value = 'in_progress';\n\n // Append the new message to the current list of messages\n const newMessage: Message = {\n ...message,\n id: message.id ?? generateId(),\n };\n\n // Update the messages list with the new message\n setMessages(messages => [...messages, newMessage]);\n\n input.value = '';\n\n const controller = new AbortController();\n\n try {\n // Assign the new controller to the abortController ref\n abortController.value = controller;\n\n const response = await fetch(api, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n },\n body: JSON.stringify({\n ...body,\n // Message Content\n message: message.content,\n\n // Always Use User Provided Thread ID When Available\n threadId: threadIdParam ?? currentThreadId.value ?? null,\n\n // Optional Request Data\n ...(requestOptions?.data && { data: requestOptions?.data }),\n }),\n signal: controller.signal,\n credentials,\n });\n\n if (!response.ok) {\n throw new Error(\n response.statusText ?? 'An error occurred while sending the message',\n );\n }\n\n if (!response.body) {\n throw new Error('The response body is empty');\n }\n\n await processAssistantStream({\n stream: response.body,\n onAssistantMessagePart(value) {\n messages.value = [\n ...messages.value,\n {\n id: value.id,\n content: value.content[0].text.value,\n role: value.role,\n },\n ];\n },\n onTextPart(value) {\n setMessages(messages => {\n const lastMessage = messages[messages.length - 1];\n lastMessage.content += value;\n\n return [...messages.slice(0, -1), lastMessage];\n });\n },\n onAssistantControlDataPart(value) {\n if (value.threadId) {\n currentThreadId.value = value.threadId;\n }\n\n setMessages(messages => {\n const lastMessage = messages[messages.length - 1];\n lastMessage.id = value.messageId;\n\n return [...messages.slice(0, -1), lastMessage];\n });\n },\n onDataMessagePart(value) {\n setMessages(messages => [\n ...messages,\n {\n id: value.id ?? generateId(),\n role: 'data',\n content: '',\n data: value.data,\n },\n ]);\n },\n onErrorPart(value) {\n error.value = new Error(value);\n },\n });\n } catch (err) {\n // If the error is an AbortError and the signal is aborted, reset the abortController and do nothing.\n if (isAbortError(err) && abortController.value?.signal.aborted) {\n abortController.value = null;\n return;\n }\n\n // If an error handler is provided, call it with the error\n if (onError && err instanceof Error) {\n onError(err);\n }\n\n error.value = err as Error;\n } finally {\n // Reset the status to 'awaiting_message' after the request is complete\n abortController.value = null;\n status.value = 'awaiting_message';\n }\n };\n\n const submitMessage = async (\n event: Event & { target: HTMLFormElement },\n requestOptions?: {\n data?: Record<string, string>;\n },\n ) => {\n event?.preventDefault?.();\n\n if (!input.value) return;\n\n append(\n {\n role: 'user',\n content: input.value,\n },\n requestOptions,\n );\n };\n\n return {\n append,\n messages,\n setMessages,\n threadId: readonly(currentThreadId),\n setThreadId: setCurrentThreadId,\n input,\n handleInputChange,\n handleSubmit: submitMessage,\n isSending,\n status,\n error,\n stop,\n };\n}\n"],"mappings":"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","names":["swrv","generateId","generateIdFunc","fetch","_a","_b","data","import_ui_utils","import_swrv","import_vue","useSWRV","swrv","store","fetch","data","_a","completion","import_ui_utils","import_vue","messages","_a"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// src/use-chat.ts
|
|
2
2
|
import {
|
|
3
3
|
callChatApi,
|
|
4
|
+
extractMaxToolInvocationStep,
|
|
4
5
|
generateId as generateIdFunc,
|
|
5
6
|
prepareAttachmentsForRequest
|
|
6
7
|
} from "@ai-sdk/ui-utils";
|
|
@@ -51,8 +52,11 @@ function useChat({
|
|
|
51
52
|
const streamData = ref(void 0);
|
|
52
53
|
let abortController = null;
|
|
53
54
|
async function triggerRequest(messagesSnapshot, { data, headers, body } = {}) {
|
|
54
|
-
var _a2;
|
|
55
|
+
var _a2, _b2, _c;
|
|
55
56
|
const messageCount = messages.value.length;
|
|
57
|
+
const maxStep = extractMaxToolInvocationStep(
|
|
58
|
+
(_a2 = messages.value[messages.value.length - 1]) == null ? void 0 : _a2.toolInvocations
|
|
59
|
+
);
|
|
56
60
|
try {
|
|
57
61
|
error.value = void 0;
|
|
58
62
|
mutateLoading(() => true);
|
|
@@ -65,7 +69,7 @@ function useChat({
|
|
|
65
69
|
headers,
|
|
66
70
|
data
|
|
67
71
|
};
|
|
68
|
-
const existingData = (
|
|
72
|
+
const existingData = (_b2 = streamData.value) != null ? _b2 : [];
|
|
69
73
|
const constructedMessagesPayload = sendExtraMessageFields ? chatRequest.messages : chatRequest.messages.map(
|
|
70
74
|
({
|
|
71
75
|
role,
|
|
@@ -103,8 +107,11 @@ function useChat({
|
|
|
103
107
|
abortController: () => abortController,
|
|
104
108
|
credentials,
|
|
105
109
|
onResponse,
|
|
106
|
-
onUpdate(
|
|
107
|
-
mutate([
|
|
110
|
+
onUpdate({ message, data: data2, replaceLastMessage }) {
|
|
111
|
+
mutate([
|
|
112
|
+
...replaceLastMessage ? chatRequest.messages.slice(0, chatRequest.messages.length - 1) : chatRequest.messages,
|
|
113
|
+
message
|
|
114
|
+
]);
|
|
108
115
|
if (data2 == null ? void 0 : data2.length) {
|
|
109
116
|
streamData.value = [...existingData, ...data2];
|
|
110
117
|
}
|
|
@@ -117,7 +124,8 @@ function useChat({
|
|
|
117
124
|
},
|
|
118
125
|
generateId: generateId2,
|
|
119
126
|
onToolCall,
|
|
120
|
-
fetch: fetch2
|
|
127
|
+
fetch: fetch2,
|
|
128
|
+
lastMessage: chatRequest.messages[chatRequest.messages.length - 1]
|
|
121
129
|
});
|
|
122
130
|
} catch (err) {
|
|
123
131
|
if (err.name === "AbortError") {
|
|
@@ -134,12 +142,14 @@ function useChat({
|
|
|
134
142
|
}
|
|
135
143
|
const lastMessage = messages.value[messages.value.length - 1];
|
|
136
144
|
if (
|
|
137
|
-
// ensure
|
|
138
|
-
|
|
139
|
-
lastMessage
|
|
145
|
+
// ensure there is a last message:
|
|
146
|
+
lastMessage != null && // ensure we actually have new messages (to prevent infinite loops in case of errors):
|
|
147
|
+
(messages.value.length > messageCount || extractMaxToolInvocationStep(lastMessage.toolInvocations) !== maxStep) && // check if the feature is enabled:
|
|
140
148
|
maxSteps && maxSteps > 1 && // check that next step is possible:
|
|
141
|
-
isAssistantMessageWithCompletedToolCalls(lastMessage) && //
|
|
142
|
-
|
|
149
|
+
isAssistantMessageWithCompletedToolCalls(lastMessage) && // check that assistant has not answered yet:
|
|
150
|
+
!lastMessage.content && // empty string or undefined
|
|
151
|
+
// limit the number of automatic steps:
|
|
152
|
+
((_c = extractMaxToolInvocationStep(lastMessage.toolInvocations)) != null ? _c : 0) < maxSteps
|
|
143
153
|
) {
|
|
144
154
|
await triggerRequest(messages.value);
|
|
145
155
|
}
|
|
@@ -198,7 +208,7 @@ function useChat({
|
|
|
198
208
|
options.experimental_attachments
|
|
199
209
|
);
|
|
200
210
|
triggerRequest(
|
|
201
|
-
|
|
211
|
+
messages.value.concat({
|
|
202
212
|
id: generateId2(),
|
|
203
213
|
createdAt: /* @__PURE__ */ new Date(),
|
|
204
214
|
content: inputValue,
|
|
@@ -253,17 +263,6 @@ function useChat({
|
|
|
253
263
|
function isAssistantMessageWithCompletedToolCalls(message) {
|
|
254
264
|
return message.role === "assistant" && message.toolInvocations && message.toolInvocations.length > 0 && message.toolInvocations.every((toolInvocation) => "result" in toolInvocation);
|
|
255
265
|
}
|
|
256
|
-
function countTrailingAssistantMessages(messages) {
|
|
257
|
-
let count = 0;
|
|
258
|
-
for (let i = messages.length - 1; i >= 0; i--) {
|
|
259
|
-
if (messages[i].role === "assistant") {
|
|
260
|
-
count++;
|
|
261
|
-
} else {
|
|
262
|
-
break;
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
return count;
|
|
266
|
-
}
|
|
267
266
|
|
|
268
267
|
// src/use-completion.ts
|
|
269
268
|
import { callCompletionApi } from "@ai-sdk/ui-utils";
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/use-chat.ts","../src/use-completion.ts","../src/use-assistant.ts"],"sourcesContent":["import type {\n ChatRequest,\n ChatRequestOptions,\n CreateMessage,\n JSONValue,\n Message,\n UseChatOptions,\n} from '@ai-sdk/ui-utils';\nimport {\n callChatApi,\n generateId as generateIdFunc,\n prepareAttachmentsForRequest,\n} from '@ai-sdk/ui-utils';\nimport swrv from 'swrv';\nimport type { Ref } from 'vue';\nimport { ref, unref } from 'vue';\n\nexport type { CreateMessage, Message, UseChatOptions };\n\nexport type UseChatHelpers = {\n /** Current messages in the chat */\n messages: Ref<Message[]>;\n /** The error object of the API request */\n error: Ref<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 */\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: (\n messages: Message[] | ((messages: Message[]) => Message[]),\n ) => void;\n /** The current value of the input */\n input: Ref<string>;\n /** Form submission handler to automatically reset input and append a user message */\n handleSubmit: (\n event?: { preventDefault?: () => void },\n chatRequestOptions?: ChatRequestOptions,\n ) => void;\n /** Whether the API request is in progress */\n isLoading: Ref<boolean | undefined>;\n\n /** Additional data added on the server via StreamData. */\n data: Ref<JSONValue[] | undefined>;\n /** Set the data of the chat. You can use this to transform or clear the chat data. */\n setData: (\n data:\n | JSONValue[]\n | undefined\n | ((data: JSONValue[] | undefined) => JSONValue[] | undefined),\n ) => void;\n\n addToolResult: ({\n toolCallId,\n result,\n }: {\n toolCallId: string;\n result: any;\n }) => void;\n\n /** The id of the chat */\n id: string;\n};\n\n// @ts-expect-error - some issues with the default export of useSWRV\nconst useSWRV = (swrv.default as typeof import('swrv')['default']) || swrv;\nconst store: Record<string, Message[] | undefined> = {};\n\nexport function useChat(\n {\n api = '/api/chat',\n id,\n initialMessages = [],\n initialInput = '',\n sendExtraMessageFields,\n streamProtocol = 'data',\n onResponse,\n onFinish,\n onError,\n credentials,\n headers: metadataHeaders,\n body: metadataBody,\n generateId = generateIdFunc,\n onToolCall,\n fetch,\n keepLastMessageOnError = true,\n maxSteps,\n }: UseChatOptions & {\n /**\n * Maximum number of sequential LLM calls (steps), e.g. when you use tool calls. Must be at least 1.\n * A maximum number is required to prevent infinite loops in the case of misconfigured tools.\n * By default, it's set to 1, which means that only a single LLM call is made.\n */\n maxSteps?: number;\n } = {\n maxSteps: 1,\n },\n): UseChatHelpers {\n // Generate a unique ID for the chat if not provided.\n const chatId = id ?? generateId();\n\n const key = `${api}|${chatId}`;\n const { data: messagesData, mutate: originalMutate } = useSWRV<Message[]>(\n key,\n () => store[key] || initialMessages,\n );\n\n const { data: isLoading, mutate: mutateLoading } = useSWRV<boolean>(\n `${chatId}-loading`,\n null,\n );\n\n isLoading.value ??= false;\n\n // Force the `data` to be `initialMessages` if it's `undefined`.\n messagesData.value ??= initialMessages;\n\n const mutate = (data?: Message[]) => {\n store[key] = data;\n return originalMutate();\n };\n\n // Because of the `initialData` option, the `data` will never be `undefined`.\n const messages = messagesData as Ref<Message[]>;\n\n const error = ref<undefined | Error>(undefined);\n // cannot use JSONValue[] in ref because of infinite Typescript recursion:\n const streamData = ref<undefined | unknown[]>(undefined);\n\n let abortController: AbortController | null = null;\n\n async function triggerRequest(\n messagesSnapshot: Message[],\n { data, headers, body }: ChatRequestOptions = {},\n ) {\n const messageCount = messages.value.length;\n\n try {\n error.value = undefined;\n mutateLoading(() => true);\n\n abortController = new AbortController();\n\n // Do an optimistic update to the chat state to show the updated messages\n // immediately.\n const previousMessages = messagesSnapshot;\n mutate(messagesSnapshot);\n\n const chatRequest: ChatRequest = {\n messages: messagesSnapshot,\n body,\n headers,\n data,\n };\n\n const existingData = (streamData.value ?? []) as JSONValue[];\n\n const constructedMessagesPayload = sendExtraMessageFields\n ? chatRequest.messages\n : chatRequest.messages.map(\n ({\n role,\n content,\n experimental_attachments,\n data,\n annotations,\n toolInvocations,\n }) => ({\n role,\n content,\n ...(experimental_attachments !== undefined && {\n experimental_attachments,\n }),\n ...(data !== undefined && { data }),\n ...(annotations !== undefined && { annotations }),\n ...(toolInvocations !== undefined && { toolInvocations }),\n }),\n );\n\n await callChatApi({\n api,\n body: {\n id: chatId,\n messages: constructedMessagesPayload,\n data: chatRequest.data,\n ...unref(metadataBody), // Use unref to unwrap the ref value\n ...body,\n },\n streamProtocol,\n headers: {\n ...metadataHeaders,\n ...headers,\n },\n abortController: () => abortController,\n credentials,\n onResponse,\n onUpdate(merged, data) {\n mutate([...chatRequest.messages, ...merged]);\n if (data?.length) {\n streamData.value = [...existingData, ...data];\n }\n },\n onFinish,\n restoreMessagesOnFailure() {\n // Restore the previous messages if the request fails.\n if (!keepLastMessageOnError) {\n mutate(previousMessages);\n }\n },\n generateId,\n onToolCall,\n fetch,\n });\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 error.value = err as Error;\n } finally {\n abortController = null;\n mutateLoading(() => false);\n }\n\n // auto-submit when all tool calls in the last assistant message have results:\n const lastMessage = messages.value[messages.value.length - 1];\n if (\n // ensure we actually have new messages (to prevent infinite loops in case of errors):\n messages.value.length > messageCount &&\n // ensure there is a last message:\n lastMessage != null &&\n // check if the feature is enabled:\n maxSteps &&\n maxSteps > 1 &&\n // check that next step is possible:\n isAssistantMessageWithCompletedToolCalls(lastMessage) &&\n // limit the number of automatic steps:\n countTrailingAssistantMessages(messages.value) <= maxSteps\n ) {\n await triggerRequest(messages.value);\n }\n }\n\n const append: UseChatHelpers['append'] = async (message, options) => {\n const attachmentsForRequest = await prepareAttachmentsForRequest(\n options?.experimental_attachments,\n );\n\n return triggerRequest(\n messages.value.concat({\n ...message,\n id: message.id ?? generateId(),\n createdAt: message.createdAt ?? new Date(),\n experimental_attachments:\n attachmentsForRequest.length > 0 ? attachmentsForRequest : undefined,\n }),\n options,\n );\n };\n\n const reload: UseChatHelpers['reload'] = async options => {\n const messagesSnapshot = messages.value;\n if (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\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 = (\n messagesArg: Message[] | ((messages: Message[]) => Message[]),\n ) => {\n if (typeof messagesArg === 'function') {\n messagesArg = messagesArg(messages.value);\n }\n\n mutate(messagesArg);\n };\n\n const setData = (\n dataArg:\n | JSONValue[]\n | undefined\n | ((data: JSONValue[] | undefined) => JSONValue[] | undefined),\n ) => {\n if (typeof dataArg === 'function') {\n dataArg = dataArg(streamData.value as JSONValue[] | undefined);\n }\n\n streamData.value = dataArg;\n };\n\n const input = ref(initialInput);\n\n const handleSubmit = async (\n event?: { preventDefault?: () => void },\n options: ChatRequestOptions = {},\n ) => {\n event?.preventDefault?.();\n\n const inputValue = input.value;\n\n if (!inputValue && !options.allowEmptySubmit) return;\n\n const attachmentsForRequest = await prepareAttachmentsForRequest(\n options.experimental_attachments,\n );\n\n triggerRequest(\n !inputValue && !attachmentsForRequest.length && options.allowEmptySubmit\n ? messages.value\n : messages.value.concat({\n id: generateId(),\n createdAt: new Date(),\n content: inputValue,\n role: 'user',\n experimental_attachments:\n attachmentsForRequest.length > 0\n ? attachmentsForRequest\n : undefined,\n }),\n options,\n );\n\n input.value = '';\n };\n\n const addToolResult = ({\n toolCallId,\n result,\n }: {\n toolCallId: string;\n result: any;\n }) => {\n const updatedMessages = messages.value.map((message, index, arr) =>\n // update the tool calls in the last assistant message:\n index === arr.length - 1 &&\n message.role === 'assistant' &&\n message.toolInvocations\n ? {\n ...message,\n toolInvocations: message.toolInvocations.map(toolInvocation =>\n toolInvocation.toolCallId === toolCallId\n ? {\n ...toolInvocation,\n result,\n state: 'result' as const,\n }\n : toolInvocation,\n ),\n }\n : message,\n );\n\n mutate(updatedMessages);\n\n // auto-submit when all tool calls in the last assistant message have results:\n const lastMessage = updatedMessages[updatedMessages.length - 1];\n\n if (isAssistantMessageWithCompletedToolCalls(lastMessage)) {\n triggerRequest(updatedMessages);\n }\n };\n\n return {\n id: chatId,\n messages,\n append,\n error,\n reload,\n stop,\n setMessages,\n input,\n handleSubmit,\n isLoading,\n data: streamData as Ref<undefined | JSONValue[]>,\n setData,\n addToolResult,\n };\n}\n\n/**\nCheck if the message is an assistant message with completed tool calls.\nThe message must have at least one tool invocation and all tool invocations\nmust have a result.\n */\nfunction isAssistantMessageWithCompletedToolCalls(message: Message) {\n return (\n message.role === 'assistant' &&\n message.toolInvocations &&\n message.toolInvocations.length > 0 &&\n message.toolInvocations.every(toolInvocation => 'result' in toolInvocation)\n );\n}\n\n/**\nReturns the number of trailing assistant messages in the array.\n */\nfunction countTrailingAssistantMessages(messages: Message[]) {\n let count = 0;\n for (let i = messages.length - 1; i >= 0; i--) {\n if (messages[i].role === 'assistant') {\n count++;\n } else {\n break;\n }\n }\n return count;\n}\n","import type {\n JSONValue,\n RequestOptions,\n UseCompletionOptions,\n} from '@ai-sdk/ui-utils';\nimport { callCompletionApi } from '@ai-sdk/ui-utils';\nimport swrv from 'swrv';\nimport type { Ref } from 'vue';\nimport { ref, unref } from 'vue';\n\nexport type { UseCompletionOptions };\n\nexport type UseCompletionHelpers = {\n /** The current completion result */\n completion: Ref<string>;\n /** The error object of the API request */\n error: Ref<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: Ref<string>;\n /**\n * Form submission handler to automatically reset input and append a user message\n * @example\n * ```jsx\n * <form @submit=\"handleSubmit\">\n * <input @change=\"handleInputChange\" v-model=\"input\" />\n * </form>\n * ```\n */\n handleSubmit: (event?: { preventDefault?: () => void }) => void;\n /** Whether the API request is in progress */\n isLoading: Ref<boolean | undefined>;\n\n /** Additional data added on the server via StreamData */\n data: Ref<JSONValue[] | undefined>;\n};\n\nlet uniqueId = 0;\n\n// @ts-expect-error - some issues with the default export of useSWRV\nconst useSWRV = (swrv.default as typeof import('swrv')['default']) || swrv;\nconst store: Record<string, any> = {};\n\nexport function useCompletion({\n api = '/api/completion',\n id,\n initialCompletion = '',\n initialInput = '',\n credentials,\n headers,\n body,\n streamProtocol,\n onResponse,\n onFinish,\n onError,\n fetch,\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, mutate: originalMutate } = useSWRV<string>(\n key,\n () => store[key] || initialCompletion,\n );\n\n const { data: isLoading, mutate: mutateLoading } = useSWRV<boolean>(\n `${completionId}-loading`,\n null,\n );\n\n isLoading.value ??= false;\n\n const { data: streamData, mutate: mutateStreamData } = useSWRV<\n JSONValue[] | undefined\n >(`${completionId}-data`, null);\n\n // Force the `data` to be `initialCompletion` if it's `undefined`.\n data.value ||= initialCompletion;\n\n const mutate = (data: string) => {\n store[key] = data;\n return originalMutate();\n };\n\n // Because of the `initialData` option, the `data` will never be `undefined`.\n const completion = data as Ref<string>;\n\n const error = ref<undefined | Error>(undefined);\n\n let abortController: AbortController | null = null;\n\n async function triggerRequest(prompt: string, options?: RequestOptions) {\n const existingData = (streamData.value ?? []) as JSONValue[];\n return callCompletionApi({\n api,\n prompt,\n credentials,\n headers: {\n ...headers,\n ...options?.headers,\n },\n body: {\n ...unref(body),\n ...options?.body,\n },\n streamProtocol,\n setCompletion: mutate,\n setLoading: loading => mutateLoading(() => loading),\n setError: err => {\n error.value = err;\n },\n setAbortController: controller => {\n abortController = controller;\n },\n onResponse,\n onFinish,\n onError,\n onData: data => {\n mutateStreamData(() => [...existingData, ...(data ?? [])]);\n },\n fetch,\n });\n }\n\n const complete: UseCompletionHelpers['complete'] = async (\n prompt,\n options,\n ) => {\n return triggerRequest(prompt, options);\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 = ref(initialInput);\n\n const handleSubmit = (event?: { preventDefault?: () => void }) => {\n event?.preventDefault?.();\n const inputValue = input.value;\n return inputValue ? complete(inputValue) : undefined;\n };\n\n return {\n completion,\n complete,\n error,\n stop,\n setCompletion,\n input,\n handleSubmit,\n isLoading,\n data: streamData,\n };\n}\n","/**\n * A vue.js composable function to interact with the assistant API.\n */\n\nimport { isAbortError } from '@ai-sdk/provider-utils';\nimport type {\n AssistantStatus,\n CreateMessage,\n Message,\n UseAssistantOptions,\n} from '@ai-sdk/ui-utils';\nimport { generateId, processAssistantStream } from '@ai-sdk/ui-utils';\nimport type { ComputedRef, Ref } from 'vue';\nimport { computed, readonly, ref } from 'vue';\n\nexport type UseAssistantHelpers = {\n /**\n * The current array of chat messages.\n */\n messages: Ref<Message[]>;\n\n /**\n * Update the message store with a new array of messages.\n */\n setMessages: (messagesProcessor: (messages: Message[]) => Message[]) => void;\n\n /**\n * The current thread ID.\n */\n threadId: Ref<string | undefined>;\n\n /**\n * Set the current thread ID. Specifying a thread ID will switch to that thread, if it exists. If set to 'undefined', a new thread will be created. For both cases, `threadId` will be updated with the new value and `messages` will be cleared.\n */\n setThreadId: (threadId: string | undefined) => void;\n /**\n * The current value of the input field.\n */\n input: Ref<string>;\n\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 requestOptions Additional options to pass to the API call\n */\n append: (\n message: Message | CreateMessage,\n requestOptions?: {\n data?: Record<string, string>;\n },\n ) => Promise<void>;\n\n /**\n * Abort the current request immediately, keep the generated tokens if any.\n */\n stop: ComputedRef<() => void>;\n\n /**\n * Handler for the `onChange` event of the input field to control the input's value.\n */\n handleInputChange: (e: Event & { target: HTMLInputElement }) => void;\n\n /**\n * Handler for the `onSubmit` event of the form to append a user message and reset the input.\n */\n handleSubmit: (e: Event & { target: HTMLFormElement }) => void;\n\n /**\n * Whether the assistant is currently sending a message.\n */\n isSending: ComputedRef<boolean>;\n\n /**\n * The current status of the assistant.\n */\n status: Ref<AssistantStatus>;\n\n /**\n * The current error, if any.\n */\n error: Ref<Error | undefined>;\n};\n\nexport function useAssistant({\n api,\n threadId: threadIdParam,\n credentials,\n headers,\n body,\n onError,\n}: UseAssistantOptions): UseAssistantHelpers {\n const messages: Ref<Message[]> = ref([]);\n const input: Ref<string> = ref('');\n const currentThreadId: Ref<string | undefined> = ref(undefined);\n const status: Ref<AssistantStatus> = ref('awaiting_message');\n const error: Ref<undefined | Error> = ref(undefined);\n\n const setMessages = (messageFactory: (messages: Message[]) => Message[]) => {\n messages.value = messageFactory(messages.value);\n };\n\n const setCurrentThreadId = (newThreadId: string | undefined) => {\n currentThreadId.value = newThreadId;\n messages.value = [];\n };\n\n const handleInputChange = (event: Event & { target: HTMLInputElement }) => {\n input.value = event?.target?.value;\n };\n\n const isSending = computed(() => status.value === 'in_progress');\n\n // Abort controller to cancel the current API call when required\n const abortController = ref<AbortController | null>(null);\n\n // memoized function to stop the current request when required\n const stop = computed(() => {\n return () => {\n if (abortController.value) {\n abortController.value.abort();\n abortController.value = null;\n }\n };\n });\n\n const append = async (\n message: Message | CreateMessage,\n requestOptions?: {\n data?: Record<string, string>;\n },\n ) => {\n status.value = 'in_progress';\n\n // Append the new message to the current list of messages\n const newMessage: Message = {\n ...message,\n id: message.id ?? generateId(),\n };\n\n // Update the messages list with the new message\n setMessages(messages => [...messages, newMessage]);\n\n input.value = '';\n\n const controller = new AbortController();\n\n try {\n // Assign the new controller to the abortController ref\n abortController.value = controller;\n\n const response = await fetch(api, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n },\n body: JSON.stringify({\n ...body,\n // Message Content\n message: message.content,\n\n // Always Use User Provided Thread ID When Available\n threadId: threadIdParam ?? currentThreadId.value ?? null,\n\n // Optional Request Data\n ...(requestOptions?.data && { data: requestOptions?.data }),\n }),\n signal: controller.signal,\n credentials,\n });\n\n if (!response.ok) {\n throw new Error(\n response.statusText ?? 'An error occurred while sending the message',\n );\n }\n\n if (!response.body) {\n throw new Error('The response body is empty');\n }\n\n await processAssistantStream({\n stream: response.body,\n onAssistantMessagePart(value) {\n messages.value = [\n ...messages.value,\n {\n id: value.id,\n content: value.content[0].text.value,\n role: value.role,\n },\n ];\n },\n onTextPart(value) {\n setMessages(messages => {\n const lastMessage = messages[messages.length - 1];\n lastMessage.content += value;\n\n return [...messages.slice(0, -1), lastMessage];\n });\n },\n onAssistantControlDataPart(value) {\n if (value.threadId) {\n currentThreadId.value = value.threadId;\n }\n\n setMessages(messages => {\n const lastMessage = messages[messages.length - 1];\n lastMessage.id = value.messageId;\n\n return [...messages.slice(0, -1), lastMessage];\n });\n },\n onDataMessagePart(value) {\n setMessages(messages => [\n ...messages,\n {\n id: value.id ?? generateId(),\n role: 'data',\n content: '',\n data: value.data,\n },\n ]);\n },\n onErrorPart(value) {\n error.value = new Error(value);\n },\n });\n } catch (err) {\n // If the error is an AbortError and the signal is aborted, reset the abortController and do nothing.\n if (isAbortError(err) && abortController.value?.signal.aborted) {\n abortController.value = null;\n return;\n }\n\n // If an error handler is provided, call it with the error\n if (onError && err instanceof Error) {\n onError(err);\n }\n\n error.value = err as Error;\n } finally {\n // Reset the status to 'awaiting_message' after the request is complete\n abortController.value = null;\n status.value = 'awaiting_message';\n }\n };\n\n const submitMessage = async (\n event: Event & { target: HTMLFormElement },\n requestOptions?: {\n data?: Record<string, string>;\n },\n ) => {\n event?.preventDefault?.();\n\n if (!input.value) return;\n\n append(\n {\n role: 'user',\n content: input.value,\n },\n requestOptions,\n );\n };\n\n return {\n append,\n messages,\n setMessages,\n threadId: readonly(currentThreadId),\n setThreadId: setCurrentThreadId,\n input,\n handleInputChange,\n handleSubmit: submitMessage,\n isSending,\n status,\n error,\n stop,\n };\n}\n"],"mappings":"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","names":["generateId","fetch","_a","data","_b","swrv","ref","unref","useSWRV","store","fetch","data","_a","completion","ref","messages","_a"]}
|
|
1
|
+
{"version":3,"sources":["../src/use-chat.ts","../src/use-completion.ts","../src/use-assistant.ts"],"sourcesContent":["import type {\n ChatRequest,\n ChatRequestOptions,\n CreateMessage,\n JSONValue,\n Message,\n UseChatOptions,\n} from '@ai-sdk/ui-utils';\nimport {\n callChatApi,\n extractMaxToolInvocationStep,\n generateId as generateIdFunc,\n prepareAttachmentsForRequest,\n} from '@ai-sdk/ui-utils';\nimport swrv from 'swrv';\nimport type { Ref } from 'vue';\nimport { ref, unref } from 'vue';\n\nexport type { CreateMessage, Message, UseChatOptions };\n\nexport type UseChatHelpers = {\n /** Current messages in the chat */\n messages: Ref<Message[]>;\n /** The error object of the API request */\n error: Ref<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 */\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: (\n messages: Message[] | ((messages: Message[]) => Message[]),\n ) => void;\n /** The current value of the input */\n input: Ref<string>;\n /** Form submission handler to automatically reset input and append a user message */\n handleSubmit: (\n event?: { preventDefault?: () => void },\n chatRequestOptions?: ChatRequestOptions,\n ) => void;\n /** Whether the API request is in progress */\n isLoading: Ref<boolean | undefined>;\n\n /** Additional data added on the server via StreamData. */\n data: Ref<JSONValue[] | undefined>;\n /** Set the data of the chat. You can use this to transform or clear the chat data. */\n setData: (\n data:\n | JSONValue[]\n | undefined\n | ((data: JSONValue[] | undefined) => JSONValue[] | undefined),\n ) => void;\n\n addToolResult: ({\n toolCallId,\n result,\n }: {\n toolCallId: string;\n result: any;\n }) => void;\n\n /** The id of the chat */\n id: string;\n};\n\n// @ts-expect-error - some issues with the default export of useSWRV\nconst useSWRV = (swrv.default as typeof import('swrv')['default']) || swrv;\nconst store: Record<string, Message[] | undefined> = {};\n\nexport function useChat(\n {\n api = '/api/chat',\n id,\n initialMessages = [],\n initialInput = '',\n sendExtraMessageFields,\n streamProtocol = 'data',\n onResponse,\n onFinish,\n onError,\n credentials,\n headers: metadataHeaders,\n body: metadataBody,\n generateId = generateIdFunc,\n onToolCall,\n fetch,\n keepLastMessageOnError = true,\n maxSteps,\n }: UseChatOptions & {\n /**\n * Maximum number of sequential LLM calls (steps), e.g. when you use tool calls. Must be at least 1.\n * A maximum number is required to prevent infinite loops in the case of misconfigured tools.\n * By default, it's set to 1, which means that only a single LLM call is made.\n */\n maxSteps?: number;\n } = {\n maxSteps: 1,\n },\n): UseChatHelpers {\n // Generate a unique ID for the chat if not provided.\n const chatId = id ?? generateId();\n\n const key = `${api}|${chatId}`;\n const { data: messagesData, mutate: originalMutate } = useSWRV<Message[]>(\n key,\n () => store[key] || initialMessages,\n );\n\n const { data: isLoading, mutate: mutateLoading } = useSWRV<boolean>(\n `${chatId}-loading`,\n null,\n );\n\n isLoading.value ??= false;\n\n // Force the `data` to be `initialMessages` if it's `undefined`.\n messagesData.value ??= initialMessages;\n\n const mutate = (data?: Message[]) => {\n store[key] = data;\n return originalMutate();\n };\n\n // Because of the `initialData` option, the `data` will never be `undefined`.\n const messages = messagesData as Ref<Message[]>;\n\n const error = ref<undefined | Error>(undefined);\n // cannot use JSONValue[] in ref because of infinite Typescript recursion:\n const streamData = ref<undefined | unknown[]>(undefined);\n\n let abortController: AbortController | null = null;\n\n async function triggerRequest(\n messagesSnapshot: Message[],\n { data, headers, body }: ChatRequestOptions = {},\n ) {\n const messageCount = messages.value.length;\n const maxStep = extractMaxToolInvocationStep(\n messages.value[messages.value.length - 1]?.toolInvocations,\n );\n\n try {\n error.value = undefined;\n mutateLoading(() => true);\n\n abortController = new AbortController();\n\n // Do an optimistic update to the chat state to show the updated messages\n // immediately.\n const previousMessages = messagesSnapshot;\n mutate(messagesSnapshot);\n\n const chatRequest: ChatRequest = {\n messages: messagesSnapshot,\n body,\n headers,\n data,\n };\n\n const existingData = (streamData.value ?? []) as JSONValue[];\n\n const constructedMessagesPayload = sendExtraMessageFields\n ? chatRequest.messages\n : chatRequest.messages.map(\n ({\n role,\n content,\n experimental_attachments,\n data,\n annotations,\n toolInvocations,\n }) => ({\n role,\n content,\n ...(experimental_attachments !== undefined && {\n experimental_attachments,\n }),\n ...(data !== undefined && { data }),\n ...(annotations !== undefined && { annotations }),\n ...(toolInvocations !== undefined && { toolInvocations }),\n }),\n );\n\n await callChatApi({\n api,\n body: {\n id: chatId,\n messages: constructedMessagesPayload,\n data: chatRequest.data,\n ...unref(metadataBody), // Use unref to unwrap the ref value\n ...body,\n },\n streamProtocol,\n headers: {\n ...metadataHeaders,\n ...headers,\n },\n abortController: () => abortController,\n credentials,\n onResponse,\n onUpdate({ message, data, replaceLastMessage }) {\n mutate([\n ...(replaceLastMessage\n ? chatRequest.messages.slice(0, chatRequest.messages.length - 1)\n : chatRequest.messages),\n message,\n ]);\n if (data?.length) {\n streamData.value = [...existingData, ...data];\n }\n },\n onFinish,\n restoreMessagesOnFailure() {\n // Restore the previous messages if the request fails.\n if (!keepLastMessageOnError) {\n mutate(previousMessages);\n }\n },\n generateId,\n onToolCall,\n fetch,\n lastMessage: chatRequest.messages[chatRequest.messages.length - 1],\n });\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 error.value = err as Error;\n } finally {\n abortController = null;\n mutateLoading(() => false);\n }\n\n // auto-submit when all tool calls in the last assistant message have results:\n const lastMessage = messages.value[messages.value.length - 1];\n if (\n // ensure there is a last message:\n lastMessage != null &&\n // ensure we actually have new messages (to prevent infinite loops in case of errors):\n (messages.value.length > messageCount ||\n extractMaxToolInvocationStep(lastMessage.toolInvocations) !==\n maxStep) &&\n // check if the feature is enabled:\n maxSteps &&\n maxSteps > 1 &&\n // check that next step is possible:\n isAssistantMessageWithCompletedToolCalls(lastMessage) &&\n // check that assistant has not answered yet:\n !lastMessage.content && // empty string or undefined\n // limit the number of automatic steps:\n (extractMaxToolInvocationStep(lastMessage.toolInvocations) ?? 0) <\n maxSteps\n ) {\n await triggerRequest(messages.value);\n }\n }\n\n const append: UseChatHelpers['append'] = async (message, options) => {\n const attachmentsForRequest = await prepareAttachmentsForRequest(\n options?.experimental_attachments,\n );\n\n return triggerRequest(\n messages.value.concat({\n ...message,\n id: message.id ?? generateId(),\n createdAt: message.createdAt ?? new Date(),\n experimental_attachments:\n attachmentsForRequest.length > 0 ? attachmentsForRequest : undefined,\n }),\n options,\n );\n };\n\n const reload: UseChatHelpers['reload'] = async options => {\n const messagesSnapshot = messages.value;\n if (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\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 = (\n messagesArg: Message[] | ((messages: Message[]) => Message[]),\n ) => {\n if (typeof messagesArg === 'function') {\n messagesArg = messagesArg(messages.value);\n }\n\n mutate(messagesArg);\n };\n\n const setData = (\n dataArg:\n | JSONValue[]\n | undefined\n | ((data: JSONValue[] | undefined) => JSONValue[] | undefined),\n ) => {\n if (typeof dataArg === 'function') {\n dataArg = dataArg(streamData.value as JSONValue[] | undefined);\n }\n\n streamData.value = dataArg;\n };\n\n const input = ref(initialInput);\n\n const handleSubmit = async (\n event?: { preventDefault?: () => void },\n options: ChatRequestOptions = {},\n ) => {\n event?.preventDefault?.();\n\n const inputValue = input.value;\n\n if (!inputValue && !options.allowEmptySubmit) return;\n\n const attachmentsForRequest = await prepareAttachmentsForRequest(\n options.experimental_attachments,\n );\n\n triggerRequest(\n messages.value.concat({\n id: generateId(),\n createdAt: new Date(),\n content: inputValue,\n role: 'user',\n experimental_attachments:\n attachmentsForRequest.length > 0 ? attachmentsForRequest : undefined,\n }),\n options,\n );\n\n input.value = '';\n };\n\n const addToolResult = ({\n toolCallId,\n result,\n }: {\n toolCallId: string;\n result: any;\n }) => {\n const updatedMessages = messages.value.map((message, index, arr) =>\n // update the tool calls in the last assistant message:\n index === arr.length - 1 &&\n message.role === 'assistant' &&\n message.toolInvocations\n ? {\n ...message,\n toolInvocations: message.toolInvocations.map(toolInvocation =>\n toolInvocation.toolCallId === toolCallId\n ? {\n ...toolInvocation,\n result,\n state: 'result' as const,\n }\n : toolInvocation,\n ),\n }\n : message,\n );\n\n mutate(updatedMessages);\n\n // auto-submit when all tool calls in the last assistant message have results:\n const lastMessage = updatedMessages[updatedMessages.length - 1];\n\n if (isAssistantMessageWithCompletedToolCalls(lastMessage)) {\n triggerRequest(updatedMessages);\n }\n };\n\n return {\n id: chatId,\n messages,\n append,\n error,\n reload,\n stop,\n setMessages,\n input,\n handleSubmit,\n isLoading,\n data: streamData as Ref<undefined | JSONValue[]>,\n setData,\n addToolResult,\n };\n}\n\n/**\nCheck if the message is an assistant message with completed tool calls.\nThe message must have at least one tool invocation and all tool invocations\nmust have a result.\n */\nfunction isAssistantMessageWithCompletedToolCalls(message: Message) {\n return (\n message.role === 'assistant' &&\n message.toolInvocations &&\n message.toolInvocations.length > 0 &&\n message.toolInvocations.every(toolInvocation => 'result' in toolInvocation)\n );\n}\n","import type {\n JSONValue,\n RequestOptions,\n UseCompletionOptions,\n} from '@ai-sdk/ui-utils';\nimport { callCompletionApi } from '@ai-sdk/ui-utils';\nimport swrv from 'swrv';\nimport type { Ref } from 'vue';\nimport { ref, unref } from 'vue';\n\nexport type { UseCompletionOptions };\n\nexport type UseCompletionHelpers = {\n /** The current completion result */\n completion: Ref<string>;\n /** The error object of the API request */\n error: Ref<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: Ref<string>;\n /**\n * Form submission handler to automatically reset input and append a user message\n * @example\n * ```jsx\n * <form @submit=\"handleSubmit\">\n * <input @change=\"handleInputChange\" v-model=\"input\" />\n * </form>\n * ```\n */\n handleSubmit: (event?: { preventDefault?: () => void }) => void;\n /** Whether the API request is in progress */\n isLoading: Ref<boolean | undefined>;\n\n /** Additional data added on the server via StreamData */\n data: Ref<JSONValue[] | undefined>;\n};\n\nlet uniqueId = 0;\n\n// @ts-expect-error - some issues with the default export of useSWRV\nconst useSWRV = (swrv.default as typeof import('swrv')['default']) || swrv;\nconst store: Record<string, any> = {};\n\nexport function useCompletion({\n api = '/api/completion',\n id,\n initialCompletion = '',\n initialInput = '',\n credentials,\n headers,\n body,\n streamProtocol,\n onResponse,\n onFinish,\n onError,\n fetch,\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, mutate: originalMutate } = useSWRV<string>(\n key,\n () => store[key] || initialCompletion,\n );\n\n const { data: isLoading, mutate: mutateLoading } = useSWRV<boolean>(\n `${completionId}-loading`,\n null,\n );\n\n isLoading.value ??= false;\n\n const { data: streamData, mutate: mutateStreamData } = useSWRV<\n JSONValue[] | undefined\n >(`${completionId}-data`, null);\n\n // Force the `data` to be `initialCompletion` if it's `undefined`.\n data.value ||= initialCompletion;\n\n const mutate = (data: string) => {\n store[key] = data;\n return originalMutate();\n };\n\n // Because of the `initialData` option, the `data` will never be `undefined`.\n const completion = data as Ref<string>;\n\n const error = ref<undefined | Error>(undefined);\n\n let abortController: AbortController | null = null;\n\n async function triggerRequest(prompt: string, options?: RequestOptions) {\n const existingData = (streamData.value ?? []) as JSONValue[];\n return callCompletionApi({\n api,\n prompt,\n credentials,\n headers: {\n ...headers,\n ...options?.headers,\n },\n body: {\n ...unref(body),\n ...options?.body,\n },\n streamProtocol,\n setCompletion: mutate,\n setLoading: loading => mutateLoading(() => loading),\n setError: err => {\n error.value = err;\n },\n setAbortController: controller => {\n abortController = controller;\n },\n onResponse,\n onFinish,\n onError,\n onData: data => {\n mutateStreamData(() => [...existingData, ...(data ?? [])]);\n },\n fetch,\n });\n }\n\n const complete: UseCompletionHelpers['complete'] = async (\n prompt,\n options,\n ) => {\n return triggerRequest(prompt, options);\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 = ref(initialInput);\n\n const handleSubmit = (event?: { preventDefault?: () => void }) => {\n event?.preventDefault?.();\n const inputValue = input.value;\n return inputValue ? complete(inputValue) : undefined;\n };\n\n return {\n completion,\n complete,\n error,\n stop,\n setCompletion,\n input,\n handleSubmit,\n isLoading,\n data: streamData,\n };\n}\n","/**\n * A vue.js composable function to interact with the assistant API.\n */\n\nimport { isAbortError } from '@ai-sdk/provider-utils';\nimport type {\n AssistantStatus,\n CreateMessage,\n Message,\n UseAssistantOptions,\n} from '@ai-sdk/ui-utils';\nimport { generateId, processAssistantStream } from '@ai-sdk/ui-utils';\nimport type { ComputedRef, Ref } from 'vue';\nimport { computed, readonly, ref } from 'vue';\n\nexport type UseAssistantHelpers = {\n /**\n * The current array of chat messages.\n */\n messages: Ref<Message[]>;\n\n /**\n * Update the message store with a new array of messages.\n */\n setMessages: (messagesProcessor: (messages: Message[]) => Message[]) => void;\n\n /**\n * The current thread ID.\n */\n threadId: Ref<string | undefined>;\n\n /**\n * Set the current thread ID. Specifying a thread ID will switch to that thread, if it exists. If set to 'undefined', a new thread will be created. For both cases, `threadId` will be updated with the new value and `messages` will be cleared.\n */\n setThreadId: (threadId: string | undefined) => void;\n /**\n * The current value of the input field.\n */\n input: Ref<string>;\n\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 requestOptions Additional options to pass to the API call\n */\n append: (\n message: Message | CreateMessage,\n requestOptions?: {\n data?: Record<string, string>;\n },\n ) => Promise<void>;\n\n /**\n * Abort the current request immediately, keep the generated tokens if any.\n */\n stop: ComputedRef<() => void>;\n\n /**\n * Handler for the `onChange` event of the input field to control the input's value.\n */\n handleInputChange: (e: Event & { target: HTMLInputElement }) => void;\n\n /**\n * Handler for the `onSubmit` event of the form to append a user message and reset the input.\n */\n handleSubmit: (e: Event & { target: HTMLFormElement }) => void;\n\n /**\n * Whether the assistant is currently sending a message.\n */\n isSending: ComputedRef<boolean>;\n\n /**\n * The current status of the assistant.\n */\n status: Ref<AssistantStatus>;\n\n /**\n * The current error, if any.\n */\n error: Ref<Error | undefined>;\n};\n\nexport function useAssistant({\n api,\n threadId: threadIdParam,\n credentials,\n headers,\n body,\n onError,\n}: UseAssistantOptions): UseAssistantHelpers {\n const messages: Ref<Message[]> = ref([]);\n const input: Ref<string> = ref('');\n const currentThreadId: Ref<string | undefined> = ref(undefined);\n const status: Ref<AssistantStatus> = ref('awaiting_message');\n const error: Ref<undefined | Error> = ref(undefined);\n\n const setMessages = (messageFactory: (messages: Message[]) => Message[]) => {\n messages.value = messageFactory(messages.value);\n };\n\n const setCurrentThreadId = (newThreadId: string | undefined) => {\n currentThreadId.value = newThreadId;\n messages.value = [];\n };\n\n const handleInputChange = (event: Event & { target: HTMLInputElement }) => {\n input.value = event?.target?.value;\n };\n\n const isSending = computed(() => status.value === 'in_progress');\n\n // Abort controller to cancel the current API call when required\n const abortController = ref<AbortController | null>(null);\n\n // memoized function to stop the current request when required\n const stop = computed(() => {\n return () => {\n if (abortController.value) {\n abortController.value.abort();\n abortController.value = null;\n }\n };\n });\n\n const append = async (\n message: Message | CreateMessage,\n requestOptions?: {\n data?: Record<string, string>;\n },\n ) => {\n status.value = 'in_progress';\n\n // Append the new message to the current list of messages\n const newMessage: Message = {\n ...message,\n id: message.id ?? generateId(),\n };\n\n // Update the messages list with the new message\n setMessages(messages => [...messages, newMessage]);\n\n input.value = '';\n\n const controller = new AbortController();\n\n try {\n // Assign the new controller to the abortController ref\n abortController.value = controller;\n\n const response = await fetch(api, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n },\n body: JSON.stringify({\n ...body,\n // Message Content\n message: message.content,\n\n // Always Use User Provided Thread ID When Available\n threadId: threadIdParam ?? currentThreadId.value ?? null,\n\n // Optional Request Data\n ...(requestOptions?.data && { data: requestOptions?.data }),\n }),\n signal: controller.signal,\n credentials,\n });\n\n if (!response.ok) {\n throw new Error(\n response.statusText ?? 'An error occurred while sending the message',\n );\n }\n\n if (!response.body) {\n throw new Error('The response body is empty');\n }\n\n await processAssistantStream({\n stream: response.body,\n onAssistantMessagePart(value) {\n messages.value = [\n ...messages.value,\n {\n id: value.id,\n content: value.content[0].text.value,\n role: value.role,\n },\n ];\n },\n onTextPart(value) {\n setMessages(messages => {\n const lastMessage = messages[messages.length - 1];\n lastMessage.content += value;\n\n return [...messages.slice(0, -1), lastMessage];\n });\n },\n onAssistantControlDataPart(value) {\n if (value.threadId) {\n currentThreadId.value = value.threadId;\n }\n\n setMessages(messages => {\n const lastMessage = messages[messages.length - 1];\n lastMessage.id = value.messageId;\n\n return [...messages.slice(0, -1), lastMessage];\n });\n },\n onDataMessagePart(value) {\n setMessages(messages => [\n ...messages,\n {\n id: value.id ?? generateId(),\n role: 'data',\n content: '',\n data: value.data,\n },\n ]);\n },\n onErrorPart(value) {\n error.value = new Error(value);\n },\n });\n } catch (err) {\n // If the error is an AbortError and the signal is aborted, reset the abortController and do nothing.\n if (isAbortError(err) && abortController.value?.signal.aborted) {\n abortController.value = null;\n return;\n }\n\n // If an error handler is provided, call it with the error\n if (onError && err instanceof Error) {\n onError(err);\n }\n\n error.value = err as Error;\n } finally {\n // Reset the status to 'awaiting_message' after the request is complete\n abortController.value = null;\n status.value = 'awaiting_message';\n }\n };\n\n const submitMessage = async (\n event: Event & { target: HTMLFormElement },\n requestOptions?: {\n data?: Record<string, string>;\n },\n ) => {\n event?.preventDefault?.();\n\n if (!input.value) return;\n\n append(\n {\n role: 'user',\n content: input.value,\n },\n requestOptions,\n );\n };\n\n return {\n append,\n messages,\n setMessages,\n threadId: readonly(currentThreadId),\n setThreadId: setCurrentThreadId,\n input,\n handleInputChange,\n handleSubmit: submitMessage,\n isSending,\n status,\n error,\n stop,\n };\n}\n"],"mappings":"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","names":["generateId","fetch","_a","_b","data","swrv","ref","unref","useSWRV","store","fetch","data","_a","completion","ref","messages","_a"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/vue",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.7",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
"CHANGELOG.md"
|
|
20
20
|
],
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@ai-sdk/provider-utils": "2.1.
|
|
23
|
-
"@ai-sdk/ui-utils": "1.1.
|
|
22
|
+
"@ai-sdk/provider-utils": "2.1.5",
|
|
23
|
+
"@ai-sdk/ui-utils": "1.1.7",
|
|
24
24
|
"swrv": "^1.0.4"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
"tsup": "^7.2.0",
|
|
36
36
|
"typescript": "5.6.3",
|
|
37
37
|
"vitest": "2.1.4",
|
|
38
|
-
"
|
|
39
|
-
"
|
|
38
|
+
"eslint-config-vercel-ai": "0.0.0",
|
|
39
|
+
"@vercel/ai-tsconfig": "0.0.0"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
42
|
"vue": "^3.3.4"
|