@ai-sdk/vue 0.0.37 → 0.0.38

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.
@@ -1,5 +1,5 @@
1
1
 
2
- > @ai-sdk/vue@0.0.37 build /home/runner/work/ai/ai/packages/vue
2
+ > @ai-sdk/vue@0.0.38 build /home/runner/work/ai/ai/packages/vue
3
3
  > tsup
4
4
 
5
5
  CLI Building entry: src/index.ts
@@ -9,13 +9,13 @@
9
9
  CLI Target: es2018
10
10
  CJS Build start
11
11
  ESM Build start
12
- CJS dist/index.js 16.19 KB
12
+ CJS dist/index.js 16.21 KB
13
13
  CJS dist/index.js.map 31.11 KB
14
- CJS ⚡️ Build success in 46ms
15
- ESM dist/index.mjs 14.07 KB
14
+ CJS ⚡️ Build success in 34ms
15
+ ESM dist/index.mjs 14.09 KB
16
16
  ESM dist/index.mjs.map 30.89 KB
17
- ESM ⚡️ Build success in 54ms
17
+ ESM ⚡️ Build success in 35ms
18
18
  DTS Build start
19
- DTS ⚡️ Build success in 5280ms
20
- DTS dist/index.d.ts 5.91 KB
21
- DTS dist/index.d.mts 5.91 KB
19
+ DTS ⚡️ Build success in 4893ms
20
+ DTS dist/index.d.ts 5.94 KB
21
+ DTS dist/index.d.mts 5.94 KB
@@ -1,4 +1,4 @@
1
1
 
2
- > @ai-sdk/vue@0.0.37 clean /home/runner/work/ai/ai/packages/vue
2
+ > @ai-sdk/vue@0.0.38 clean /home/runner/work/ai/ai/packages/vue
3
3
  > rm -rf dist
4
4
 
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @ai-sdk/vue
2
2
 
3
+ ## 0.0.38
4
+
5
+ ### Patch Changes
6
+
7
+ - 04084a3: fix (ui/vue): use body and headers metadata
8
+
3
9
  ## 0.0.37
4
10
 
5
11
  ### Patch Changes
package/dist/index.d.mts CHANGED
@@ -39,7 +39,7 @@ type UseChatHelpers = {
39
39
  /** Additional data added on the server via StreamData */
40
40
  data: Ref<JSONValue[] | undefined>;
41
41
  };
42
- declare function useChat({ api, id, initialMessages, initialInput, sendExtraMessageFields, experimental_onFunctionCall, streamMode, streamProtocol, onResponse, onFinish, onError, credentials, headers, body, generateId, fetch, keepLastMessageOnError, }?: UseChatOptions): UseChatHelpers;
42
+ declare function useChat({ api, id, initialMessages, initialInput, sendExtraMessageFields, experimental_onFunctionCall, streamMode, streamProtocol, onResponse, onFinish, onError, credentials, headers: metadataHeaders, body: metadataBody, generateId, fetch, keepLastMessageOnError, }?: UseChatOptions): UseChatHelpers;
43
43
 
44
44
  type UseCompletionHelpers = {
45
45
  /** The current completion result */
package/dist/index.d.ts CHANGED
@@ -39,7 +39,7 @@ type UseChatHelpers = {
39
39
  /** Additional data added on the server via StreamData */
40
40
  data: Ref<JSONValue[] | undefined>;
41
41
  };
42
- declare function useChat({ api, id, initialMessages, initialInput, sendExtraMessageFields, experimental_onFunctionCall, streamMode, streamProtocol, onResponse, onFinish, onError, credentials, headers, body, generateId, fetch, keepLastMessageOnError, }?: UseChatOptions): UseChatHelpers;
42
+ declare function useChat({ api, id, initialMessages, initialInput, sendExtraMessageFields, experimental_onFunctionCall, streamMode, streamProtocol, onResponse, onFinish, onError, credentials, headers: metadataHeaders, body: metadataBody, generateId, fetch, keepLastMessageOnError, }?: UseChatOptions): UseChatHelpers;
43
43
 
44
44
  type UseCompletionHelpers = {
45
45
  /** The current completion result */
package/dist/index.js CHANGED
@@ -57,8 +57,8 @@ function useChat({
57
57
  onFinish,
58
58
  onError,
59
59
  credentials,
60
- headers,
61
- body,
60
+ headers: metadataHeaders,
61
+ body: metadataBody,
62
62
  generateId: generateId2 = import_ui_utils.generateId,
63
63
  fetch: fetch2,
64
64
  keepLastMessageOnError = false
@@ -87,7 +87,7 @@ function useChat({
87
87
  const error = (0, import_vue.ref)(void 0);
88
88
  const streamData = (0, import_vue.ref)(void 0);
89
89
  let abortController = null;
90
- async function triggerRequest(messagesSnapshot, { options, data, headers: headers2, body: body2 } = {}) {
90
+ async function triggerRequest(messagesSnapshot, { options, data, headers, body } = {}) {
91
91
  try {
92
92
  error.value = void 0;
93
93
  mutateLoading(() => true);
@@ -95,8 +95,8 @@ function useChat({
95
95
  const previousMessages = messagesSnapshot;
96
96
  mutate(messagesSnapshot);
97
97
  const requestOptions = {
98
- headers: headers2 != null ? headers2 : options == null ? void 0 : options.headers,
99
- body: body2 != null ? body2 : options == null ? void 0 : options.body
98
+ headers: headers != null ? headers : options == null ? void 0 : options.headers,
99
+ body: body != null ? body : options == null ? void 0 : options.body
100
100
  };
101
101
  let chatRequest = {
102
102
  messages: messagesSnapshot,
@@ -132,13 +132,13 @@ function useChat({
132
132
  body: {
133
133
  messages: constructedMessagesPayload,
134
134
  data: chatRequest.data,
135
- ...(0, import_vue.unref)(body2),
135
+ ...(0, import_vue.unref)(metadataBody),
136
136
  // Use unref to unwrap the ref value
137
137
  ...requestOptions.body
138
138
  },
139
139
  streamProtocol,
140
140
  headers: {
141
- ...headers2,
141
+ ...metadataHeaders,
142
142
  ...requestOptions.headers
143
143
  },
144
144
  abortController: () => abortController,
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 processChatStream,\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};\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, Message[] | undefined> = {};\n\nexport function useChat({\n api = '/api/chat',\n id,\n initialMessages = [],\n initialInput = '',\n sendExtraMessageFields,\n experimental_onFunctionCall,\n streamMode,\n streamProtocol,\n onResponse,\n onFinish,\n onError,\n credentials,\n headers,\n body,\n generateId = generateIdFunc,\n fetch,\n keepLastMessageOnError = false,\n}: UseChatOptions = {}): UseChatHelpers {\n // streamMode is deprecated, use streamProtocol instead.\n if (streamMode) {\n streamProtocol ??= streamMode === 'text' ? 'text' : undefined;\n }\n\n // Generate a unique ID for the chat if not provided.\n const chatId = id || `chat-${uniqueId++}`;\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 async function triggerRequest(\n messagesSnapshot: Message[],\n { options, data, headers, body }: ChatRequestOptions = {},\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 requestOptions = {\n headers: headers ?? options?.headers,\n body: body ?? options?.body,\n };\n\n let chatRequest: ChatRequest = {\n messages: messagesSnapshot,\n options: requestOptions,\n body: requestOptions.body,\n headers: requestOptions.headers,\n data,\n };\n\n await processChatStream({\n getStreamedResponse: async () => {\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 name,\n data,\n annotations,\n function_call,\n }) => ({\n role,\n content,\n ...(name !== undefined && { name }),\n ...(data !== undefined && { data }),\n ...(annotations !== undefined && { annotations }),\n // outdated function/tool call handling (TODO deprecate):\n ...(function_call !== undefined && { function_call }),\n }),\n );\n\n return await callChatApi({\n api,\n body: {\n messages: constructedMessagesPayload,\n data: chatRequest.data,\n ...unref(body), // Use unref to unwrap the ref value\n ...requestOptions.body,\n },\n streamProtocol,\n headers: {\n ...headers,\n ...requestOptions.headers,\n },\n abortController: () => abortController,\n credentials,\n onResponse,\n onUpdate(merged, data) {\n mutate([...chatRequest.messages, ...merged]);\n streamData.value = [...existingData, ...(data ?? [])];\n },\n onFinish(message, options) {\n // workaround: sometimes the last chunk is not shown in the UI.\n // push it twice to make sure it's displayed.\n mutate([...chatRequest.messages, message]);\n onFinish?.(message, options);\n },\n restoreMessagesOnFailure() {\n // Restore the previous messages if the request fails.\n if (!keepLastMessageOnError) {\n mutate(previousMessages);\n }\n },\n generateId,\n onToolCall: undefined, // not implemented yet\n fetch,\n });\n },\n experimental_onFunctionCall,\n updateChatRequest(newChatRequest) {\n chatRequest = newChatRequest;\n },\n getCurrentMessages: () => messages.value,\n });\n\n abortController = null;\n } catch (err) {\n // Ignore abort errors as they are expected.\n if ((err as any).name === 'AbortError') {\n abortController = null;\n return null;\n }\n\n if (onError && err instanceof Error) {\n onError(err);\n }\n\n error.value = err as Error;\n } finally {\n mutateLoading(() => false);\n }\n }\n\n const append: UseChatHelpers['append'] = async (message, options) => {\n if (!message.id) {\n message.id = generateId();\n }\n\n return triggerRequest(messages.value.concat(message as Message), options);\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 input = ref(initialInput);\n\n const handleSubmit = (\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 triggerRequest(\n !inputValue && options.allowEmptySubmit\n ? messages.value\n : messages.value.concat({\n id: generateId(),\n createdAt: new Date(),\n content: inputValue,\n role: 'user',\n }),\n options,\n );\n\n input.value = '';\n };\n\n return {\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 };\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 { readDataStream, generateId } from '@ai-sdk/ui-utils';\nimport type {\n AssistantStatus,\n CreateMessage,\n Message,\n UseAssistantOptions,\n} from '@ai-sdk/ui-utils';\nimport { computed, readonly, ref } from 'vue';\nimport type { ComputedRef, 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 for await (const { type, value } of readDataStream(\n response.body.getReader(),\n )) {\n switch (type) {\n case 'assistant_message': {\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 break;\n }\n case 'assistant_control_data': {\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 break;\n }\n\n case 'text': {\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 break;\n }\n\n case 'data_message': {\n setMessages(messages => [\n ...messages,\n {\n id: value.id ?? generateId(),\n role: 'data',\n content: '',\n data: value.data,\n },\n ]);\n break;\n }\n\n case 'error': {\n error.value = new Error(value);\n }\n\n default: {\n console.error('Unknown message type:', type);\n break;\n }\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\n/**\n * @deprecated Use `useAssistant` instead.\n */\nexport const experimental_useAssistant = useAssistant;\n"],"mappings":"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","names":["swrv","generateId","generateIdFunc","fetch","headers","body","_a","data","options","import_ui_utils","import_swrv","import_vue","uniqueId","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 generateId as generateIdFunc,\n processChatStream,\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};\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, Message[] | undefined> = {};\n\nexport function useChat({\n api = '/api/chat',\n id,\n initialMessages = [],\n initialInput = '',\n sendExtraMessageFields,\n experimental_onFunctionCall,\n streamMode,\n streamProtocol,\n onResponse,\n onFinish,\n onError,\n credentials,\n headers: metadataHeaders,\n body: metadataBody,\n generateId = generateIdFunc,\n fetch,\n keepLastMessageOnError = false,\n}: UseChatOptions = {}): UseChatHelpers {\n // streamMode is deprecated, use streamProtocol instead.\n if (streamMode) {\n streamProtocol ??= streamMode === 'text' ? 'text' : undefined;\n }\n\n // Generate a unique ID for the chat if not provided.\n const chatId = id || `chat-${uniqueId++}`;\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 { options, data, headers, body }: ChatRequestOptions = {},\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 requestOptions = {\n headers: headers ?? options?.headers,\n body: body ?? options?.body,\n };\n\n let chatRequest: ChatRequest = {\n messages: messagesSnapshot,\n options: requestOptions,\n body: requestOptions.body,\n headers: requestOptions.headers,\n data,\n };\n\n await processChatStream({\n getStreamedResponse: async () => {\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 name,\n data,\n annotations,\n function_call,\n }) => ({\n role,\n content,\n ...(name !== undefined && { name }),\n ...(data !== undefined && { data }),\n ...(annotations !== undefined && { annotations }),\n // outdated function/tool call handling (TODO deprecate):\n ...(function_call !== undefined && { function_call }),\n }),\n );\n\n return await callChatApi({\n api,\n body: {\n messages: constructedMessagesPayload,\n data: chatRequest.data,\n ...unref(metadataBody), // Use unref to unwrap the ref value\n ...requestOptions.body,\n },\n streamProtocol,\n headers: {\n ...metadataHeaders,\n ...requestOptions.headers,\n },\n abortController: () => abortController,\n credentials,\n onResponse,\n onUpdate(merged, data) {\n mutate([...chatRequest.messages, ...merged]);\n streamData.value = [...existingData, ...(data ?? [])];\n },\n onFinish(message, options) {\n // workaround: sometimes the last chunk is not shown in the UI.\n // push it twice to make sure it's displayed.\n mutate([...chatRequest.messages, message]);\n onFinish?.(message, options);\n },\n restoreMessagesOnFailure() {\n // Restore the previous messages if the request fails.\n if (!keepLastMessageOnError) {\n mutate(previousMessages);\n }\n },\n generateId,\n onToolCall: undefined, // not implemented yet\n fetch,\n });\n },\n experimental_onFunctionCall,\n updateChatRequest(newChatRequest) {\n chatRequest = newChatRequest;\n },\n getCurrentMessages: () => messages.value,\n });\n\n abortController = null;\n } catch (err) {\n // Ignore abort errors as they are expected.\n if ((err as any).name === 'AbortError') {\n abortController = null;\n return null;\n }\n\n if (onError && err instanceof Error) {\n onError(err);\n }\n\n error.value = err as Error;\n } finally {\n mutateLoading(() => false);\n }\n }\n\n const append: UseChatHelpers['append'] = async (message, options) => {\n if (!message.id) {\n message.id = generateId();\n }\n\n return triggerRequest(messages.value.concat(message as Message), options);\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 input = ref(initialInput);\n\n const handleSubmit = (\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 triggerRequest(\n !inputValue && options.allowEmptySubmit\n ? messages.value\n : messages.value.concat({\n id: generateId(),\n createdAt: new Date(),\n content: inputValue,\n role: 'user',\n }),\n options,\n );\n\n input.value = '';\n };\n\n return {\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 };\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 { readDataStream, generateId } from '@ai-sdk/ui-utils';\nimport type {\n AssistantStatus,\n CreateMessage,\n Message,\n UseAssistantOptions,\n} from '@ai-sdk/ui-utils';\nimport { computed, readonly, ref } from 'vue';\nimport type { ComputedRef, 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 for await (const { type, value } of readDataStream(\n response.body.getReader(),\n )) {\n switch (type) {\n case 'assistant_message': {\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 break;\n }\n case 'assistant_control_data': {\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 break;\n }\n\n case 'text': {\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 break;\n }\n\n case 'data_message': {\n setMessages(messages => [\n ...messages,\n {\n id: value.id ?? generateId(),\n role: 'data',\n content: '',\n data: value.data,\n },\n ]);\n break;\n }\n\n case 'error': {\n error.value = new Error(value);\n }\n\n default: {\n console.error('Unknown message type:', type);\n break;\n }\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\n/**\n * @deprecated Use `useAssistant` instead.\n */\nexport const experimental_useAssistant = useAssistant;\n"],"mappings":"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","names":["swrv","generateId","generateIdFunc","fetch","_a","data","options","import_ui_utils","import_swrv","import_vue","uniqueId","useSWRV","swrv","store","fetch","data","_a","completion","import_ui_utils","import_vue","messages","_a"]}
package/dist/index.mjs CHANGED
@@ -22,8 +22,8 @@ function useChat({
22
22
  onFinish,
23
23
  onError,
24
24
  credentials,
25
- headers,
26
- body,
25
+ headers: metadataHeaders,
26
+ body: metadataBody,
27
27
  generateId: generateId2 = generateIdFunc,
28
28
  fetch: fetch2,
29
29
  keepLastMessageOnError = false
@@ -52,7 +52,7 @@ function useChat({
52
52
  const error = ref(void 0);
53
53
  const streamData = ref(void 0);
54
54
  let abortController = null;
55
- async function triggerRequest(messagesSnapshot, { options, data, headers: headers2, body: body2 } = {}) {
55
+ async function triggerRequest(messagesSnapshot, { options, data, headers, body } = {}) {
56
56
  try {
57
57
  error.value = void 0;
58
58
  mutateLoading(() => true);
@@ -60,8 +60,8 @@ function useChat({
60
60
  const previousMessages = messagesSnapshot;
61
61
  mutate(messagesSnapshot);
62
62
  const requestOptions = {
63
- headers: headers2 != null ? headers2 : options == null ? void 0 : options.headers,
64
- body: body2 != null ? body2 : options == null ? void 0 : options.body
63
+ headers: headers != null ? headers : options == null ? void 0 : options.headers,
64
+ body: body != null ? body : options == null ? void 0 : options.body
65
65
  };
66
66
  let chatRequest = {
67
67
  messages: messagesSnapshot,
@@ -97,13 +97,13 @@ function useChat({
97
97
  body: {
98
98
  messages: constructedMessagesPayload,
99
99
  data: chatRequest.data,
100
- ...unref(body2),
100
+ ...unref(metadataBody),
101
101
  // Use unref to unwrap the ref value
102
102
  ...requestOptions.body
103
103
  },
104
104
  streamProtocol,
105
105
  headers: {
106
- ...headers2,
106
+ ...metadataHeaders,
107
107
  ...requestOptions.headers
108
108
  },
109
109
  abortController: () => abortController,
@@ -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 processChatStream,\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};\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, Message[] | undefined> = {};\n\nexport function useChat({\n api = '/api/chat',\n id,\n initialMessages = [],\n initialInput = '',\n sendExtraMessageFields,\n experimental_onFunctionCall,\n streamMode,\n streamProtocol,\n onResponse,\n onFinish,\n onError,\n credentials,\n headers,\n body,\n generateId = generateIdFunc,\n fetch,\n keepLastMessageOnError = false,\n}: UseChatOptions = {}): UseChatHelpers {\n // streamMode is deprecated, use streamProtocol instead.\n if (streamMode) {\n streamProtocol ??= streamMode === 'text' ? 'text' : undefined;\n }\n\n // Generate a unique ID for the chat if not provided.\n const chatId = id || `chat-${uniqueId++}`;\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 async function triggerRequest(\n messagesSnapshot: Message[],\n { options, data, headers, body }: ChatRequestOptions = {},\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 requestOptions = {\n headers: headers ?? options?.headers,\n body: body ?? options?.body,\n };\n\n let chatRequest: ChatRequest = {\n messages: messagesSnapshot,\n options: requestOptions,\n body: requestOptions.body,\n headers: requestOptions.headers,\n data,\n };\n\n await processChatStream({\n getStreamedResponse: async () => {\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 name,\n data,\n annotations,\n function_call,\n }) => ({\n role,\n content,\n ...(name !== undefined && { name }),\n ...(data !== undefined && { data }),\n ...(annotations !== undefined && { annotations }),\n // outdated function/tool call handling (TODO deprecate):\n ...(function_call !== undefined && { function_call }),\n }),\n );\n\n return await callChatApi({\n api,\n body: {\n messages: constructedMessagesPayload,\n data: chatRequest.data,\n ...unref(body), // Use unref to unwrap the ref value\n ...requestOptions.body,\n },\n streamProtocol,\n headers: {\n ...headers,\n ...requestOptions.headers,\n },\n abortController: () => abortController,\n credentials,\n onResponse,\n onUpdate(merged, data) {\n mutate([...chatRequest.messages, ...merged]);\n streamData.value = [...existingData, ...(data ?? [])];\n },\n onFinish(message, options) {\n // workaround: sometimes the last chunk is not shown in the UI.\n // push it twice to make sure it's displayed.\n mutate([...chatRequest.messages, message]);\n onFinish?.(message, options);\n },\n restoreMessagesOnFailure() {\n // Restore the previous messages if the request fails.\n if (!keepLastMessageOnError) {\n mutate(previousMessages);\n }\n },\n generateId,\n onToolCall: undefined, // not implemented yet\n fetch,\n });\n },\n experimental_onFunctionCall,\n updateChatRequest(newChatRequest) {\n chatRequest = newChatRequest;\n },\n getCurrentMessages: () => messages.value,\n });\n\n abortController = null;\n } catch (err) {\n // Ignore abort errors as they are expected.\n if ((err as any).name === 'AbortError') {\n abortController = null;\n return null;\n }\n\n if (onError && err instanceof Error) {\n onError(err);\n }\n\n error.value = err as Error;\n } finally {\n mutateLoading(() => false);\n }\n }\n\n const append: UseChatHelpers['append'] = async (message, options) => {\n if (!message.id) {\n message.id = generateId();\n }\n\n return triggerRequest(messages.value.concat(message as Message), options);\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 input = ref(initialInput);\n\n const handleSubmit = (\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 triggerRequest(\n !inputValue && options.allowEmptySubmit\n ? messages.value\n : messages.value.concat({\n id: generateId(),\n createdAt: new Date(),\n content: inputValue,\n role: 'user',\n }),\n options,\n );\n\n input.value = '';\n };\n\n return {\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 };\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 { readDataStream, generateId } from '@ai-sdk/ui-utils';\nimport type {\n AssistantStatus,\n CreateMessage,\n Message,\n UseAssistantOptions,\n} from '@ai-sdk/ui-utils';\nimport { computed, readonly, ref } from 'vue';\nimport type { ComputedRef, 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 for await (const { type, value } of readDataStream(\n response.body.getReader(),\n )) {\n switch (type) {\n case 'assistant_message': {\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 break;\n }\n case 'assistant_control_data': {\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 break;\n }\n\n case 'text': {\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 break;\n }\n\n case 'data_message': {\n setMessages(messages => [\n ...messages,\n {\n id: value.id ?? generateId(),\n role: 'data',\n content: '',\n data: value.data,\n },\n ]);\n break;\n }\n\n case 'error': {\n error.value = new Error(value);\n }\n\n default: {\n console.error('Unknown message type:', type);\n break;\n }\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\n/**\n * @deprecated Use `useAssistant` instead.\n */\nexport const experimental_useAssistant = useAssistant;\n"],"mappings":"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","names":["generateId","fetch","headers","body","_a","data","options","swrv","ref","unref","uniqueId","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 generateId as generateIdFunc,\n processChatStream,\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};\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, Message[] | undefined> = {};\n\nexport function useChat({\n api = '/api/chat',\n id,\n initialMessages = [],\n initialInput = '',\n sendExtraMessageFields,\n experimental_onFunctionCall,\n streamMode,\n streamProtocol,\n onResponse,\n onFinish,\n onError,\n credentials,\n headers: metadataHeaders,\n body: metadataBody,\n generateId = generateIdFunc,\n fetch,\n keepLastMessageOnError = false,\n}: UseChatOptions = {}): UseChatHelpers {\n // streamMode is deprecated, use streamProtocol instead.\n if (streamMode) {\n streamProtocol ??= streamMode === 'text' ? 'text' : undefined;\n }\n\n // Generate a unique ID for the chat if not provided.\n const chatId = id || `chat-${uniqueId++}`;\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 { options, data, headers, body }: ChatRequestOptions = {},\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 requestOptions = {\n headers: headers ?? options?.headers,\n body: body ?? options?.body,\n };\n\n let chatRequest: ChatRequest = {\n messages: messagesSnapshot,\n options: requestOptions,\n body: requestOptions.body,\n headers: requestOptions.headers,\n data,\n };\n\n await processChatStream({\n getStreamedResponse: async () => {\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 name,\n data,\n annotations,\n function_call,\n }) => ({\n role,\n content,\n ...(name !== undefined && { name }),\n ...(data !== undefined && { data }),\n ...(annotations !== undefined && { annotations }),\n // outdated function/tool call handling (TODO deprecate):\n ...(function_call !== undefined && { function_call }),\n }),\n );\n\n return await callChatApi({\n api,\n body: {\n messages: constructedMessagesPayload,\n data: chatRequest.data,\n ...unref(metadataBody), // Use unref to unwrap the ref value\n ...requestOptions.body,\n },\n streamProtocol,\n headers: {\n ...metadataHeaders,\n ...requestOptions.headers,\n },\n abortController: () => abortController,\n credentials,\n onResponse,\n onUpdate(merged, data) {\n mutate([...chatRequest.messages, ...merged]);\n streamData.value = [...existingData, ...(data ?? [])];\n },\n onFinish(message, options) {\n // workaround: sometimes the last chunk is not shown in the UI.\n // push it twice to make sure it's displayed.\n mutate([...chatRequest.messages, message]);\n onFinish?.(message, options);\n },\n restoreMessagesOnFailure() {\n // Restore the previous messages if the request fails.\n if (!keepLastMessageOnError) {\n mutate(previousMessages);\n }\n },\n generateId,\n onToolCall: undefined, // not implemented yet\n fetch,\n });\n },\n experimental_onFunctionCall,\n updateChatRequest(newChatRequest) {\n chatRequest = newChatRequest;\n },\n getCurrentMessages: () => messages.value,\n });\n\n abortController = null;\n } catch (err) {\n // Ignore abort errors as they are expected.\n if ((err as any).name === 'AbortError') {\n abortController = null;\n return null;\n }\n\n if (onError && err instanceof Error) {\n onError(err);\n }\n\n error.value = err as Error;\n } finally {\n mutateLoading(() => false);\n }\n }\n\n const append: UseChatHelpers['append'] = async (message, options) => {\n if (!message.id) {\n message.id = generateId();\n }\n\n return triggerRequest(messages.value.concat(message as Message), options);\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 input = ref(initialInput);\n\n const handleSubmit = (\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 triggerRequest(\n !inputValue && options.allowEmptySubmit\n ? messages.value\n : messages.value.concat({\n id: generateId(),\n createdAt: new Date(),\n content: inputValue,\n role: 'user',\n }),\n options,\n );\n\n input.value = '';\n };\n\n return {\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 };\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 { readDataStream, generateId } from '@ai-sdk/ui-utils';\nimport type {\n AssistantStatus,\n CreateMessage,\n Message,\n UseAssistantOptions,\n} from '@ai-sdk/ui-utils';\nimport { computed, readonly, ref } from 'vue';\nimport type { ComputedRef, 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 for await (const { type, value } of readDataStream(\n response.body.getReader(),\n )) {\n switch (type) {\n case 'assistant_message': {\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 break;\n }\n case 'assistant_control_data': {\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 break;\n }\n\n case 'text': {\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 break;\n }\n\n case 'data_message': {\n setMessages(messages => [\n ...messages,\n {\n id: value.id ?? generateId(),\n role: 'data',\n content: '',\n data: value.data,\n },\n ]);\n break;\n }\n\n case 'error': {\n error.value = new Error(value);\n }\n\n default: {\n console.error('Unknown message type:', type);\n break;\n }\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\n/**\n * @deprecated Use `useAssistant` instead.\n */\nexport const experimental_useAssistant = useAssistant;\n"],"mappings":"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","names":["generateId","fetch","_a","data","options","swrv","ref","unref","uniqueId","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": "0.0.37",
3
+ "version": "0.0.38",
4
4
  "license": "Apache-2.0",
5
5
  "sideEffects": false,
6
6
  "main": "./dist/index.js",
@@ -0,0 +1,32 @@
1
+ <script setup lang="ts">
2
+ import { useChat } from './use-chat';
3
+
4
+ const { messages, append } = useChat({
5
+ body: {
6
+ body1: 'value1',
7
+ body2: 'value2',
8
+ },
9
+ headers: {
10
+ header1: 'value1',
11
+ header2: 'value2',
12
+ },
13
+ });
14
+ </script>
15
+
16
+ <template>
17
+ <div>
18
+ <div
19
+ v-for="(m, idx) in messages"
20
+ key="m.id"
21
+ :data-testid="`message-${idx}`"
22
+ >
23
+ {{ m.role === 'user' ? 'User: ' : 'AI: ' }}
24
+ {{ m.content }}
25
+ </div>
26
+
27
+ <button
28
+ data-testid="do-append"
29
+ @click="append({ role: 'user', content: 'custom metadata component' })"
30
+ />
31
+ </div>
32
+ </template>
@@ -13,7 +13,7 @@ const onFinishCalls: Array<{
13
13
  };
14
14
  }> = [];
15
15
 
16
- const { messages, append, data, error, isLoading } = useChat({
16
+ const { messages, append } = useChat({
17
17
  streamProtocol: 'text',
18
18
  onFinish: (message, options) => {
19
19
  onFinishCalls.push({ message, options });
@@ -23,9 +23,6 @@ const { messages, append, data, error, isLoading } = useChat({
23
23
 
24
24
  <template>
25
25
  <div>
26
- <div data-testid="loading">{{ isLoading?.toString() }}</div>
27
- <div data-testid="error">{{ error?.toString() }}</div>
28
- <div data-testid="data">{{ JSON.stringify(data) }}</div>
29
26
  <div
30
27
  v-for="(m, idx) in messages"
31
28
  key="m.id"
package/src/use-chat.ts CHANGED
@@ -83,8 +83,8 @@ export function useChat({
83
83
  onFinish,
84
84
  onError,
85
85
  credentials,
86
- headers,
87
- body,
86
+ headers: metadataHeaders,
87
+ body: metadataBody,
88
88
  generateId = generateIdFunc,
89
89
  fetch,
90
90
  keepLastMessageOnError = false,
@@ -126,6 +126,7 @@ export function useChat({
126
126
  const streamData = ref<undefined | unknown[]>(undefined);
127
127
 
128
128
  let abortController: AbortController | null = null;
129
+
129
130
  async function triggerRequest(
130
131
  messagesSnapshot: Message[],
131
132
  { options, data, headers, body }: ChatRequestOptions = {},
@@ -184,12 +185,12 @@ export function useChat({
184
185
  body: {
185
186
  messages: constructedMessagesPayload,
186
187
  data: chatRequest.data,
187
- ...unref(body), // Use unref to unwrap the ref value
188
+ ...unref(metadataBody), // Use unref to unwrap the ref value
188
189
  ...requestOptions.body,
189
190
  },
190
191
  streamProtocol,
191
192
  headers: {
192
- ...headers,
193
+ ...metadataHeaders,
193
194
  ...requestOptions.headers,
194
195
  },
195
196
  abortController: () => abortController,
@@ -9,6 +9,7 @@ import '@testing-library/jest-dom/vitest';
9
9
  import userEvent from '@testing-library/user-event';
10
10
  import { cleanup, findByText, render, screen } from '@testing-library/vue';
11
11
  import TestChatComponent from './TestChatComponent.vue';
12
+ import TestChatCustomMetadataComponent from './TestChatCustomMetadataComponent.vue';
12
13
  import TestChatFormComponent from './TestChatFormComponent.vue';
13
14
  import TestChatFormOptionsComponent from './TestChatFormOptionsComponent.vue';
14
15
  import TestChatReloadComponent from './TestChatReloadComponent.vue';
@@ -196,6 +197,7 @@ describe('text stream', () => {
196
197
 
197
198
  const onFinishCalls = screen.getByTestId('on-finish-calls');
198
199
  const onFinishCallsText = onFinishCalls.textContent ?? '';
200
+
199
201
  expect(JSON.parse(onFinishCallsText)).toStrictEqual([
200
202
  {
201
203
  message: {
@@ -220,6 +222,61 @@ describe('text stream', () => {
220
222
  );
221
223
  });
222
224
 
225
+ describe('custom metadata', () => {
226
+ beforeEach(() => {
227
+ render(TestChatCustomMetadataComponent);
228
+ });
229
+
230
+ afterEach(() => {
231
+ vi.restoreAllMocks();
232
+ cleanup();
233
+ });
234
+
235
+ it(
236
+ 'should should use custom headers',
237
+ withTestServer(
238
+ {
239
+ url: '/api/chat',
240
+ type: 'stream-values',
241
+ content: ['0:"Hello, World."\n'],
242
+ },
243
+ async ({ call }) => {
244
+ await userEvent.click(screen.getByTestId('do-append'));
245
+
246
+ await screen.findByTestId('message-1');
247
+
248
+ expect(call(0).getRequestHeaders()).toStrictEqual({
249
+ 'content-type': 'application/json',
250
+ header1: 'value1',
251
+ header2: 'value2',
252
+ });
253
+ },
254
+ ),
255
+ );
256
+
257
+ it(
258
+ 'should should use custom body',
259
+ withTestServer(
260
+ {
261
+ url: '/api/chat',
262
+ type: 'stream-values',
263
+ content: ['0:"Hello, World."\n'],
264
+ },
265
+ async ({ call }) => {
266
+ await userEvent.click(screen.getByTestId('do-append'));
267
+
268
+ await screen.findByTestId('message-1');
269
+
270
+ expect(await call(0).getRequestBodyJson()).toStrictEqual({
271
+ messages: [{ content: 'custom metadata component', role: 'user' }],
272
+ body1: 'value1',
273
+ body2: 'value2',
274
+ });
275
+ },
276
+ ),
277
+ );
278
+ });
279
+
223
280
  describe('form actions', () => {
224
281
  beforeEach(() => {
225
282
  render(TestChatFormComponent);