@ai-sdk/react 0.0.19 → 0.0.20

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/react@0.0.19 build /home/runner/work/ai/ai/packages/react
2
+ > @ai-sdk/react@0.0.20 build /home/runner/work/ai/ai/packages/react
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 24.58 KB
13
- CJS dist/index.js.map 49.89 KB
14
- CJS ⚡️ Build success in 47ms
15
- ESM dist/index.mjs 22.10 KB
16
- ESM dist/index.mjs.map 49.82 KB
17
- ESM ⚡️ Build success in 48ms
12
+ CJS dist/index.js 25.13 KB
13
+ CJS dist/index.js.map 50.67 KB
14
+ CJS ⚡️ Build success in 71ms
15
+ ESM dist/index.mjs 22.65 KB
16
+ ESM dist/index.mjs.map 50.59 KB
17
+ ESM ⚡️ Build success in 72ms
18
18
  DTS Build start
19
- DTS ⚡️ Build success in 5098ms
19
+ DTS ⚡️ Build success in 5305ms
20
20
  DTS dist/index.d.ts 10.40 KB
21
21
  DTS dist/index.d.mts 10.40 KB
@@ -1,4 +1,4 @@
1
1
 
2
- > @ai-sdk/react@0.0.19 clean /home/runner/work/ai/ai/packages/react
2
+ > @ai-sdk/react@0.0.20 clean /home/runner/work/ai/ai/packages/react
3
3
  > rm -rf dist
4
4
 
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # @ai-sdk/react
2
2
 
3
+ ## 0.0.20
4
+
5
+ ### Patch Changes
6
+
7
+ - 56bbc2a7: feat (ai/ui): set body and headers directly on options for handleSubmit and append
8
+ - Updated dependencies [56bbc2a7]
9
+ - @ai-sdk/ui-utils@0.0.12
10
+
3
11
  ## 0.0.19
4
12
 
5
13
  ### Patch Changes
package/dist/index.js CHANGED
@@ -216,7 +216,7 @@ var import_ui_utils2 = require("@ai-sdk/ui-utils");
216
216
  var import_react2 = require("react");
217
217
  var import_swr = __toESM(require("swr"));
218
218
  var getStreamedResponse = async (api, chatRequest, mutate, mutateStreamData, existingData, extraMetadataRef, messagesRef, abortControllerRef, generateId2, streamMode, onFinish, onResponse, onToolCall, sendExtraMessageFields, experimental_prepareRequestBody, fetch2) => {
219
- var _a, _b, _c, _d;
219
+ var _a;
220
220
  const previousMessages = messagesRef.current;
221
221
  mutate(chatRequest.messages, false);
222
222
  const constructedMessagesPayload = sendExtraMessageFields ? chatRequest.messages : chatRequest.messages.map(
@@ -245,15 +245,15 @@ var getStreamedResponse = async (api, chatRequest, mutate, mutateStreamData, exi
245
245
  );
246
246
  return await (0, import_ui_utils2.callChatApi)({
247
247
  api,
248
- body: (_c = experimental_prepareRequestBody == null ? void 0 : experimental_prepareRequestBody({
248
+ body: (_a = experimental_prepareRequestBody == null ? void 0 : experimental_prepareRequestBody({
249
249
  messages: chatRequest.messages,
250
250
  requestData: chatRequest.data,
251
- requestBody: (_a = chatRequest.options) == null ? void 0 : _a.body
252
- })) != null ? _c : {
251
+ requestBody: chatRequest.body
252
+ })) != null ? _a : {
253
253
  messages: constructedMessagesPayload,
254
254
  data: chatRequest.data,
255
255
  ...extraMetadataRef.current.body,
256
- ...(_b = chatRequest.options) == null ? void 0 : _b.body,
256
+ ...chatRequest.body,
257
257
  ...chatRequest.functions !== void 0 && {
258
258
  functions: chatRequest.functions
259
259
  },
@@ -271,7 +271,7 @@ var getStreamedResponse = async (api, chatRequest, mutate, mutateStreamData, exi
271
271
  credentials: extraMetadataRef.current.credentials,
272
272
  headers: {
273
273
  ...extraMetadataRef.current.headers,
274
- ...(_d = chatRequest.options) == null ? void 0 : _d.headers
274
+ ...chatRequest.headers
275
275
  },
276
276
  abortController: () => abortControllerRef.current,
277
277
  restoreMessagesOnFailure() {
@@ -434,14 +434,22 @@ function useChat({
434
434
  function_call,
435
435
  tools,
436
436
  tool_choice,
437
- data
437
+ data,
438
+ headers: headers2,
439
+ body: body2
438
440
  } = {}) => {
439
441
  if (!message.id) {
440
442
  message.id = generateId2();
441
443
  }
444
+ const requestOptions = {
445
+ headers: headers2 != null ? headers2 : options == null ? void 0 : options.headers,
446
+ body: body2 != null ? body2 : options == null ? void 0 : options.body
447
+ };
442
448
  const chatRequest = {
443
449
  messages: messagesRef.current.concat(message),
444
- options,
450
+ options: requestOptions,
451
+ headers: requestOptions.headers,
452
+ body: requestOptions.body,
445
453
  data,
446
454
  ...functions !== void 0 && { functions },
447
455
  ...function_call !== void 0 && { function_call },
@@ -502,7 +510,7 @@ function useChat({
502
510
  const [input, setInput] = (0, import_react2.useState)(initialInput);
503
511
  const handleSubmit = (0, import_react2.useCallback)(
504
512
  (event, options = {}, metadata) => {
505
- var _a;
513
+ var _a, _b, _c, _d, _e;
506
514
  if (metadata) {
507
515
  extraMetadataRef.current = {
508
516
  ...extraMetadataRef.current,
@@ -510,13 +518,19 @@ function useChat({
510
518
  };
511
519
  }
512
520
  (_a = event == null ? void 0 : event.preventDefault) == null ? void 0 : _a.call(event);
521
+ const requestOptions = {
522
+ headers: (_c = options.headers) != null ? _c : (_b = options.options) == null ? void 0 : _b.headers,
523
+ body: (_e = options.body) != null ? _e : (_d = options.options) == null ? void 0 : _d.body
524
+ };
513
525
  const chatRequest = {
514
526
  messages: input ? messagesRef.current.concat({
515
527
  id: generateId2(),
516
528
  role: "user",
517
529
  content: input
518
530
  }) : messagesRef.current,
519
- options: options.options,
531
+ options: requestOptions,
532
+ headers: requestOptions.headers,
533
+ body: requestOptions.body,
520
534
  data: options.data
521
535
  };
522
536
  triggerRequest(chatRequest);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/use-assistant.ts","../src/use-chat.ts","../src/use-completion.ts","../src/use-object.ts"],"sourcesContent":["export * from './use-assistant';\nexport * from './use-chat';\nexport * from './use-completion';\nexport * from './use-object';\n","import { isAbortError } from '@ai-sdk/provider-utils';\nimport {\n AssistantStatus,\n CreateMessage,\n Message,\n UseAssistantOptions,\n generateId,\n readDataStream,\n} from '@ai-sdk/ui-utils';\nimport { useCallback, useRef, useState } from 'react';\n\n// use function to allow for mocking in tests:\nconst getOriginalFetch = () => fetch;\n\nexport type UseAssistantHelpers = {\n /**\n * The current array of chat messages.\n */\n messages: Message[];\n\n /**\n * Update the message store with a new array of messages.\n */\n setMessages: React.Dispatch<React.SetStateAction<Message[]>>;\n\n /**\n * The current thread ID.\n */\n threadId: 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 /**\n * The current value of the input field.\n */\n input: 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 /**\nAbort the current request immediately, keep the generated tokens if any.\n */\n stop: () => void;\n\n /**\n * setState-powered method to update the input value.\n */\n setInput: React.Dispatch<React.SetStateAction<string>>;\n\n /**\n * Handler for the `onChange` event of the input field to control the input's value.\n */\n handleInputChange: (\n event:\n | React.ChangeEvent<HTMLInputElement>\n | React.ChangeEvent<HTMLTextAreaElement>,\n ) => void;\n\n /**\n * Form submission handler that automatically resets the input field and appends a user message.\n */\n submitMessage: (\n event?: React.FormEvent<HTMLFormElement>,\n requestOptions?: {\n data?: Record<string, string>;\n },\n ) => Promise<void>;\n\n /**\n * The current status of the assistant. This can be used to show a loading indicator.\n */\n status: AssistantStatus;\n\n /**\n * The error thrown during the assistant message processing, if any.\n */\n error: undefined | Error;\n};\n\nexport function useAssistant({\n api,\n threadId: threadIdParam,\n credentials,\n headers,\n body,\n onError,\n fetch,\n}: UseAssistantOptions): UseAssistantHelpers {\n const [messages, setMessages] = useState<Message[]>([]);\n const [input, setInput] = useState('');\n const [currentThreadId, setCurrentThreadId] = useState<string | undefined>(\n undefined,\n );\n const [status, setStatus] = useState<AssistantStatus>('awaiting_message');\n const [error, setError] = useState<undefined | Error>(undefined);\n\n const handleInputChange = (\n event:\n | React.ChangeEvent<HTMLInputElement>\n | React.ChangeEvent<HTMLTextAreaElement>,\n ) => {\n setInput(event.target.value);\n };\n\n // Abort controller to cancel the current API call.\n const abortControllerRef = useRef<AbortController | null>(null);\n\n const stop = useCallback(() => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n abortControllerRef.current = null;\n }\n }, []);\n\n const append = async (\n message: Message | CreateMessage,\n requestOptions?: {\n data?: Record<string, string>;\n },\n ) => {\n setStatus('in_progress');\n\n setMessages(messages => [\n ...messages,\n {\n ...message,\n id: message.id ?? generateId(),\n },\n ]);\n\n setInput('');\n\n const abortController = new AbortController();\n\n try {\n abortControllerRef.current = abortController;\n\n const actualFetch = fetch ?? getOriginalFetch();\n const response = await actualFetch(api, {\n method: 'POST',\n credentials,\n signal: abortController.signal,\n headers: { 'Content-Type': 'application/json', ...headers },\n body: JSON.stringify({\n ...body,\n // always use user-provided threadId when available:\n threadId: threadIdParam ?? currentThreadId ?? null,\n message: message.content,\n\n // optional request data:\n data: requestOptions?.data,\n }),\n });\n\n if (!response.ok) {\n throw new Error(\n (await response.text()) ?? 'Failed to fetch the assistant response.',\n );\n }\n\n if (response.body == null) {\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 setMessages(messages => [\n ...messages,\n {\n id: value.id,\n role: value.role,\n content: value.content[0].text.value,\n },\n ]);\n break;\n }\n\n case 'text': {\n // text delta - add to last message:\n setMessages(messages => {\n const lastMessage = messages[messages.length - 1];\n return [\n ...messages.slice(0, messages.length - 1),\n {\n id: lastMessage.id,\n role: lastMessage.role,\n content: lastMessage.content + value,\n },\n ];\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 'assistant_control_data': {\n setCurrentThreadId(value.threadId);\n\n // set id of last message:\n setMessages(messages => {\n const lastMessage = messages[messages.length - 1];\n lastMessage.id = value.messageId;\n return [...messages.slice(0, messages.length - 1), lastMessage];\n });\n\n break;\n }\n\n case 'error': {\n setError(new Error(value));\n break;\n }\n }\n }\n } catch (error) {\n // Ignore abort errors as they are expected when the user cancels the request:\n if (isAbortError(error) && abortController.signal.aborted) {\n abortControllerRef.current = null;\n return;\n }\n\n if (onError && error instanceof Error) {\n onError(error);\n }\n\n setError(error as Error);\n } finally {\n abortControllerRef.current = null;\n setStatus('awaiting_message');\n }\n };\n\n const submitMessage = async (\n event?: React.FormEvent<HTMLFormElement>,\n requestOptions?: {\n data?: Record<string, string>;\n },\n ) => {\n event?.preventDefault?.();\n\n if (input === '') {\n return;\n }\n\n append({ role: 'user', content: input }, requestOptions);\n };\n\n const setThreadId = (threadId: string | undefined) => {\n setCurrentThreadId(threadId);\n setMessages([]);\n };\n\n return {\n append,\n messages,\n setMessages,\n threadId: currentThreadId,\n setThreadId,\n input,\n setInput,\n handleInputChange,\n submitMessage,\n status,\n error,\n stop,\n };\n}\n\n/**\n@deprecated Use `useAssistant` instead.\n */\nexport const experimental_useAssistant = useAssistant;\n","import type {\n ChatRequest,\n ChatRequestOptions,\n CreateMessage,\n FetchFunction,\n IdGenerator,\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 { useCallback, useEffect, useId, useRef, useState } from 'react';\nimport useSWR, { KeyedMutator } from 'swr';\n\nexport type { CreateMessage, Message, UseChatOptions };\n\nexport type UseChatHelpers = {\n /** Current messages in the chat */\n messages: Message[];\n /** The error object of the API request */\n error: undefined | Error;\n /**\n * Append a user message to the chat list. This triggers the API call to fetch\n * the assistant's response.\n * @param message The message to append\n * @param options Additional options to pass to the API call\n */\n append: (\n message: Message | CreateMessage,\n chatRequestOptions?: ChatRequestOptions,\n ) => Promise<string | null | undefined>;\n /**\n * Reload the last AI chat response for the given chat history. If the last\n * message isn't from the assistant, it will request the API to generate a\n * new response.\n */\n reload: (\n chatRequestOptions?: ChatRequestOptions,\n ) => Promise<string | null | undefined>;\n /**\n * Abort the current request immediately, keep the generated tokens if any.\n */\n stop: () => void;\n /**\n * Update the `messages` state locally. This is useful when you want to\n * edit the messages on the client, and then trigger the `reload` method\n * manually to regenerate the AI response.\n */\n setMessages: (messages: Message[]) => void;\n /** The current value of the input */\n input: string;\n /** setState-powered method to update the input value */\n setInput: React.Dispatch<React.SetStateAction<string>>;\n /** An input/textarea-ready onChange handler to control the value of the input */\n handleInputChange: (\n e:\n | React.ChangeEvent<HTMLInputElement>\n | React.ChangeEvent<HTMLTextAreaElement>,\n ) => void;\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 metadata?: Object;\n /** Whether the API request is in progress */\n isLoading: boolean;\n /** Additional data added on the server via StreamData */\n data?: JSONValue[];\n};\n\nconst getStreamedResponse = async (\n api: string,\n chatRequest: ChatRequest,\n mutate: KeyedMutator<Message[]>,\n mutateStreamData: KeyedMutator<JSONValue[] | undefined>,\n existingData: JSONValue[] | undefined,\n extraMetadataRef: React.MutableRefObject<any>,\n messagesRef: React.MutableRefObject<Message[]>,\n abortControllerRef: React.MutableRefObject<AbortController | null>,\n generateId: IdGenerator,\n streamMode: 'stream-data' | 'text' | undefined,\n onFinish: ((message: Message) => void) | undefined,\n onResponse: ((response: Response) => void | Promise<void>) | undefined,\n onToolCall: UseChatOptions['onToolCall'] | undefined,\n sendExtraMessageFields: boolean | undefined,\n experimental_prepareRequestBody:\n | ((options: {\n messages: Message[];\n requestData?: JSONValue;\n requestBody?: object;\n }) => JSONValue)\n | undefined,\n fetch: FetchFunction | undefined,\n) => {\n // Do an optimistic update to the chat state to show the updated messages\n // immediately.\n const previousMessages = messagesRef.current;\n mutate(chatRequest.messages, false);\n\n const constructedMessagesPayload = sendExtraMessageFields\n ? chatRequest.messages\n : chatRequest.messages.map(\n ({\n role,\n content,\n name,\n data,\n annotations,\n toolInvocations,\n function_call,\n tool_calls,\n tool_call_id,\n }) => ({\n role,\n content,\n ...(name !== undefined && { name }),\n ...(data !== undefined && { data }),\n ...(annotations !== undefined && { annotations }),\n ...(toolInvocations !== undefined && { toolInvocations }),\n // outdated function/tool call handling (TODO deprecate):\n tool_call_id,\n ...(function_call !== undefined && { function_call }),\n ...(tool_calls !== undefined && { tool_calls }),\n }),\n );\n\n return await callChatApi({\n api,\n body: experimental_prepareRequestBody?.({\n messages: chatRequest.messages,\n requestData: chatRequest.data,\n requestBody: chatRequest.options?.body,\n }) ?? {\n messages: constructedMessagesPayload,\n data: chatRequest.data,\n ...extraMetadataRef.current.body,\n ...chatRequest.options?.body,\n ...(chatRequest.functions !== undefined && {\n functions: chatRequest.functions,\n }),\n ...(chatRequest.function_call !== undefined && {\n function_call: chatRequest.function_call,\n }),\n ...(chatRequest.tools !== undefined && {\n tools: chatRequest.tools,\n }),\n ...(chatRequest.tool_choice !== undefined && {\n tool_choice: chatRequest.tool_choice,\n }),\n },\n streamMode,\n credentials: extraMetadataRef.current.credentials,\n headers: {\n ...extraMetadataRef.current.headers,\n ...chatRequest.options?.headers,\n },\n abortController: () => abortControllerRef.current,\n restoreMessagesOnFailure() {\n mutate(previousMessages, false);\n },\n onResponse,\n onUpdate(merged, data) {\n mutate([...chatRequest.messages, ...merged], false);\n mutateStreamData([...(existingData || []), ...(data || [])], false);\n },\n onToolCall,\n onFinish,\n generateId,\n fetch,\n });\n};\n\nexport function useChat({\n api = '/api/chat',\n id,\n initialMessages,\n initialInput = '',\n sendExtraMessageFields,\n experimental_onFunctionCall,\n experimental_onToolCall,\n onToolCall,\n experimental_prepareRequestBody,\n experimental_maxAutomaticRoundtrips = 0,\n maxAutomaticRoundtrips = experimental_maxAutomaticRoundtrips,\n maxToolRoundtrips = maxAutomaticRoundtrips,\n streamMode,\n onResponse,\n onFinish,\n onError,\n credentials,\n headers,\n body,\n generateId = generateIdFunc,\n fetch,\n}: UseChatOptions & {\n key?: string;\n\n /**\n@deprecated Use `maxToolRoundtrips` instead.\n */\n experimental_maxAutomaticRoundtrips?: number;\n\n /**\n@deprecated Use `maxToolRoundtrips` instead.\n */\n maxAutomaticRoundtrips?: number;\n\n /**\n * Experimental (React only). When a function is provided, it will be used\n * to prepare the request body for the chat API. This can be useful for\n * customizing the request body based on the messages and data in the chat.\n *\n * @param messages The current messages in the chat.\n * @param requestData The data object passed in the chat request.\n * @param requestBody The request body object passed in the chat request.\n */\n experimental_prepareRequestBody?: (options: {\n messages: Message[];\n requestData?: JSONValue;\n requestBody?: object;\n }) => JSONValue;\n\n /**\nMaximal number of automatic roundtrips for tool calls.\n\nAn automatic tool call roundtrip is a call to the server with the \ntool call results when all tool calls in the last assistant \nmessage have results.\n\nA maximum number is required to prevent infinite loops in the\ncase of misconfigured tools.\n\nBy default, it's set to 0, which will disable the feature.\n */\n maxToolRoundtrips?: number;\n} = {}): UseChatHelpers & {\n /**\n * @deprecated Use `addToolResult` instead.\n */\n experimental_addToolResult: ({\n toolCallId,\n result,\n }: {\n toolCallId: string;\n result: any;\n }) => void;\n addToolResult: ({\n toolCallId,\n result,\n }: {\n toolCallId: string;\n result: any;\n }) => void;\n} {\n // Generate a unique id for the chat if not provided.\n const hookId = useId();\n const idKey = id ?? hookId;\n const chatKey = typeof api === 'string' ? [api, idKey] : idKey;\n\n // Store a empty array as the initial messages\n // (instead of using a default parameter value that gets re-created each time)\n // to avoid re-renders:\n const [initialMessagesFallback] = useState([]);\n\n // Store the chat state in SWR, using the chatId as the key to share states.\n const { data: messages, mutate } = useSWR<Message[]>(\n [chatKey, 'messages'],\n null,\n { fallbackData: initialMessages ?? initialMessagesFallback },\n );\n\n // We store loading state in another hook to sync loading states across hook invocations\n const { data: isLoading = false, mutate: mutateLoading } = useSWR<boolean>(\n [chatKey, 'loading'],\n null,\n );\n\n const { data: streamData, mutate: mutateStreamData } = useSWR<\n JSONValue[] | undefined\n >([chatKey, 'streamData'], null);\n\n const { data: error = undefined, mutate: setError } = useSWR<\n undefined | Error\n >([chatKey, 'error'], null);\n\n // Keep the latest messages in a ref.\n const messagesRef = useRef<Message[]>(messages || []);\n useEffect(() => {\n messagesRef.current = messages || [];\n }, [messages]);\n\n // Abort controller to cancel the current API call.\n const abortControllerRef = useRef<AbortController | null>(null);\n\n const extraMetadataRef = useRef({\n credentials,\n headers,\n body,\n });\n\n useEffect(() => {\n extraMetadataRef.current = {\n credentials,\n headers,\n body,\n };\n }, [credentials, headers, body]);\n\n const triggerRequest = useCallback(\n async (chatRequest: ChatRequest) => {\n const messageCount = messagesRef.current.length;\n\n try {\n mutateLoading(true);\n setError(undefined);\n\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n\n await processChatStream({\n getStreamedResponse: () =>\n getStreamedResponse(\n api,\n chatRequest,\n mutate,\n mutateStreamData,\n streamData!,\n extraMetadataRef,\n messagesRef,\n abortControllerRef,\n generateId,\n streamMode,\n onFinish,\n onResponse,\n onToolCall,\n sendExtraMessageFields,\n experimental_prepareRequestBody,\n fetch,\n ),\n experimental_onFunctionCall,\n experimental_onToolCall,\n updateChatRequest: chatRequestParam => {\n chatRequest = chatRequestParam;\n },\n getCurrentMessages: () => messagesRef.current,\n });\n\n abortControllerRef.current = null;\n } catch (err) {\n // Ignore abort errors as they are expected.\n if ((err as any).name === 'AbortError') {\n abortControllerRef.current = null;\n return null;\n }\n\n if (onError && err instanceof Error) {\n onError(err);\n }\n\n setError(err as Error);\n } finally {\n mutateLoading(false);\n }\n\n // auto-submit when all tool calls in the last assistant message have results:\n const messages = messagesRef.current;\n const lastMessage = messages[messages.length - 1];\n if (\n // ensure we actually have new messages (to prevent infinite loops in case of errors):\n messages.length > messageCount &&\n // ensure there is a last message:\n lastMessage != null &&\n // check if the feature is enabled:\n maxToolRoundtrips > 0 &&\n // check that roundtrip is possible:\n isAssistantMessageWithCompletedToolCalls(lastMessage) &&\n // limit the number of automatic roundtrips:\n countTrailingAssistantMessages(messages) <= maxToolRoundtrips\n ) {\n await triggerRequest({ messages });\n }\n },\n [\n mutate,\n mutateLoading,\n api,\n extraMetadataRef,\n onResponse,\n onFinish,\n onError,\n setError,\n mutateStreamData,\n streamData,\n streamMode,\n sendExtraMessageFields,\n experimental_onFunctionCall,\n experimental_onToolCall,\n experimental_prepareRequestBody,\n onToolCall,\n maxToolRoundtrips,\n messagesRef,\n abortControllerRef,\n generateId,\n fetch,\n ],\n );\n\n const append = useCallback(\n async (\n message: Message | CreateMessage,\n {\n options,\n functions,\n function_call,\n tools,\n tool_choice,\n data,\n }: ChatRequestOptions = {},\n ) => {\n if (!message.id) {\n message.id = generateId();\n }\n\n const chatRequest: ChatRequest = {\n messages: messagesRef.current.concat(message as Message),\n options,\n data,\n ...(functions !== undefined && { functions }),\n ...(function_call !== undefined && { function_call }),\n ...(tools !== undefined && { tools }),\n ...(tool_choice !== undefined && { tool_choice }),\n };\n\n return triggerRequest(chatRequest);\n },\n [triggerRequest, generateId],\n );\n\n const reload = useCallback(\n async ({\n options,\n functions,\n function_call,\n tools,\n tool_choice,\n }: ChatRequestOptions = {}) => {\n if (messagesRef.current.length === 0) return null;\n\n // Remove last assistant message and retry last user message.\n const lastMessage = messagesRef.current[messagesRef.current.length - 1];\n if (lastMessage.role === 'assistant') {\n const chatRequest: ChatRequest = {\n messages: messagesRef.current.slice(0, -1),\n options,\n ...(functions !== undefined && { functions }),\n ...(function_call !== undefined && { function_call }),\n ...(tools !== undefined && { tools }),\n ...(tool_choice !== undefined && { tool_choice }),\n };\n\n return triggerRequest(chatRequest);\n }\n\n const chatRequest: ChatRequest = {\n messages: messagesRef.current,\n options,\n ...(functions !== undefined && { functions }),\n ...(function_call !== undefined && { function_call }),\n ...(tools !== undefined && { tools }),\n ...(tool_choice !== undefined && { tool_choice }),\n };\n\n return triggerRequest(chatRequest);\n },\n [triggerRequest],\n );\n\n const stop = useCallback(() => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n abortControllerRef.current = null;\n }\n }, []);\n\n const setMessages = useCallback(\n (messages: Message[]) => {\n mutate(messages, false);\n messagesRef.current = messages;\n },\n [mutate],\n );\n\n // Input state and handlers.\n const [input, setInput] = useState(initialInput);\n\n const handleSubmit = useCallback(\n (\n event?: { preventDefault?: () => void },\n options: ChatRequestOptions = {},\n metadata?: Object,\n ) => {\n if (metadata) {\n extraMetadataRef.current = {\n ...extraMetadataRef.current,\n ...metadata,\n };\n }\n\n event?.preventDefault?.();\n\n const chatRequest: ChatRequest = {\n messages: input\n ? messagesRef.current.concat({\n id: generateId(),\n role: 'user',\n content: input,\n })\n : messagesRef.current,\n options: options.options,\n data: options.data,\n };\n\n triggerRequest(chatRequest);\n\n setInput('');\n },\n [input, generateId, triggerRequest],\n );\n\n const handleInputChange = (e: any) => {\n setInput(e.target.value);\n };\n\n const addToolResult = ({\n toolCallId,\n result,\n }: {\n toolCallId: string;\n result: any;\n }) => {\n const updatedMessages = messagesRef.current.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 ? { ...toolInvocation, result }\n : toolInvocation,\n ),\n }\n : message,\n );\n\n mutate(updatedMessages, false);\n\n // auto-submit when all tool calls in the last assistant message have results:\n const lastMessage = updatedMessages[updatedMessages.length - 1];\n if (isAssistantMessageWithCompletedToolCalls(lastMessage)) {\n triggerRequest({ messages: updatedMessages });\n }\n };\n\n return {\n messages: messages || [],\n error,\n append,\n reload,\n stop,\n setMessages,\n input,\n setInput,\n handleInputChange,\n handleSubmit,\n isLoading,\n data: streamData,\n addToolResult,\n experimental_addToolResult: 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 {\n JSONValue,\n RequestOptions,\n UseCompletionOptions,\n callCompletionApi,\n} from '@ai-sdk/ui-utils';\nimport { useCallback, useEffect, useId, useRef, useState } from 'react';\nimport useSWR from 'swr';\n\nexport type { UseCompletionOptions };\n\nexport type UseCompletionHelpers = {\n /** The current completion result */\n completion: string;\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 /** The error object of the API request */\n error: undefined | Error;\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: string;\n /** setState-powered method to update the input value */\n setInput: React.Dispatch<React.SetStateAction<string>>;\n /**\n * An input/textarea-ready onChange handler to control the value of the input\n * @example\n * ```jsx\n * <input onChange={handleInputChange} value={input} />\n * ```\n */\n handleInputChange: (\n event:\n | React.ChangeEvent<HTMLInputElement>\n | React.ChangeEvent<HTMLTextAreaElement>,\n ) => void;\n\n /**\n * Form submission handler to automatically reset input and append a user message\n * @example\n * ```jsx\n * <form onSubmit={handleSubmit}>\n * <input onChange={handleInputChange} value={input} />\n * </form>\n * ```\n */\n handleSubmit: (event?: { preventDefault?: () => void }) => void;\n\n /** Whether the API request is in progress */\n isLoading: boolean;\n /** Additional data added on the server via StreamData */\n data?: JSONValue[];\n};\n\nexport function useCompletion({\n api = '/api/completion',\n id,\n initialCompletion = '',\n initialInput = '',\n credentials,\n headers,\n body,\n streamMode,\n fetch,\n onResponse,\n onFinish,\n onError,\n}: UseCompletionOptions = {}): UseCompletionHelpers {\n // Generate an unique id for the completion if not provided.\n const hookId = useId();\n const completionId = id || hookId;\n\n // Store the completion state in SWR, using the completionId as the key to share states.\n const { data, mutate } = useSWR<string>([api, completionId], null, {\n fallbackData: initialCompletion,\n });\n\n const { data: isLoading = false, mutate: mutateLoading } = useSWR<boolean>(\n [completionId, 'loading'],\n null,\n );\n\n const { data: streamData, mutate: mutateStreamData } = useSWR<\n JSONValue[] | undefined\n >([completionId, 'streamData'], null);\n\n const [error, setError] = useState<undefined | Error>(undefined);\n const completion = data!;\n\n // Abort controller to cancel the current API call.\n const [abortController, setAbortController] =\n useState<AbortController | null>(null);\n\n const extraMetadataRef = useRef({\n credentials,\n headers,\n body,\n });\n useEffect(() => {\n extraMetadataRef.current = {\n credentials,\n headers,\n body,\n };\n }, [credentials, headers, body]);\n\n const triggerRequest = useCallback(\n async (prompt: string, options?: RequestOptions) =>\n callCompletionApi({\n api,\n prompt,\n credentials: extraMetadataRef.current.credentials,\n headers: { ...extraMetadataRef.current.headers, ...options?.headers },\n body: {\n ...extraMetadataRef.current.body,\n ...options?.body,\n },\n streamMode,\n fetch,\n setCompletion: completion => mutate(completion, false),\n setLoading: mutateLoading,\n setError,\n setAbortController,\n onResponse,\n onFinish,\n onError,\n onData: data => {\n mutateStreamData([...(streamData || []), ...(data || [])], false);\n },\n }),\n [\n mutate,\n mutateLoading,\n api,\n extraMetadataRef,\n setAbortController,\n onResponse,\n onFinish,\n onError,\n setError,\n streamData,\n streamMode,\n fetch,\n mutateStreamData,\n ],\n );\n\n const stop = useCallback(() => {\n if (abortController) {\n abortController.abort();\n setAbortController(null);\n }\n }, [abortController]);\n\n const setCompletion = useCallback(\n (completion: string) => {\n mutate(completion, false);\n },\n [mutate],\n );\n\n const complete = useCallback<UseCompletionHelpers['complete']>(\n async (prompt, options) => {\n return triggerRequest(prompt, options);\n },\n [triggerRequest],\n );\n\n const [input, setInput] = useState(initialInput);\n\n const handleSubmit = useCallback(\n (event?: { preventDefault?: () => void }) => {\n event?.preventDefault?.();\n return input ? complete(input) : undefined;\n },\n [input, complete],\n );\n\n const handleInputChange = (e: any) => {\n setInput(e.target.value);\n };\n\n return {\n completion,\n complete,\n error,\n setCompletion,\n stop,\n input,\n setInput,\n handleInputChange,\n handleSubmit,\n isLoading,\n data: streamData,\n };\n}\n","import { isAbortError } from '@ai-sdk/provider-utils';\nimport {\n DeepPartial,\n FetchFunction,\n isDeepEqualData,\n parsePartialJson,\n} from '@ai-sdk/ui-utils';\nimport { useCallback, useId, useRef, useState } from 'react';\nimport useSWR from 'swr';\nimport z from 'zod';\n\n// use function to allow for mocking in tests:\nconst getOriginalFetch = () => fetch;\n\nexport type Experimental_UseObjectOptions<RESULT> = {\n /**\n * The API endpoint. It should stream JSON that matches the schema as chunked text.\n */\n api: string;\n\n /**\n * A Zod schema that defines the shape of the complete object.\n */\n schema: z.Schema<RESULT>;\n\n /**\n * An unique identifier. If not provided, a random one will be\n * generated. When provided, the `useObject` hook with the same `id` will\n * have shared states across components.\n */\n id?: string;\n\n /**\n * An optional value for the initial object.\n */\n initialValue?: DeepPartial<RESULT>;\n\n /**\nCustom fetch implementation. You can use it as a middleware to intercept requests,\nor to provide a custom fetch implementation for e.g. testing.\n */\n fetch?: FetchFunction;\n\n /**\n * Callback function to be called when an error is encountered.\n */\n onError?: (error: Error) => void;\n};\n\nexport type Experimental_UseObjectHelpers<RESULT, INPUT> = {\n /**\n * @deprecated Use `submit` instead.\n */\n setInput: (input: INPUT) => void;\n\n /**\n * Calls the API with the provided input as JSON body.\n */\n submit: (input: INPUT) => void;\n\n /**\n * The current value for the generated object. Updated as the API streams JSON chunks.\n */\n object: DeepPartial<RESULT> | undefined;\n\n /**\n * The error object of the API request if any.\n */\n error: undefined | unknown;\n\n /**\n * Flag that indicates whether an API request is in progress.\n */\n isLoading: boolean;\n\n /**\n * Abort the current request immediately, keep the current partial object if any.\n */\n stop: () => void;\n};\n\nfunction useObject<RESULT, INPUT = any>({\n api,\n id,\n schema, // required, in the future we will use it for validation\n initialValue,\n fetch,\n onError,\n}: Experimental_UseObjectOptions<RESULT>): Experimental_UseObjectHelpers<\n RESULT,\n INPUT\n> {\n // Generate an unique id if not provided.\n const hookId = useId();\n const completionId = id ?? hookId;\n\n // Store the completion state in SWR, using the completionId as the key to share states.\n const { data, mutate } = useSWR<DeepPartial<RESULT>>(\n [api, completionId],\n null,\n { fallbackData: initialValue },\n );\n\n const [error, setError] = useState<undefined | unknown>(undefined);\n const [isLoading, setIsLoading] = useState(false);\n\n // Abort controller to cancel the current API call.\n const abortControllerRef = useRef<AbortController | null>(null);\n\n const stop = useCallback(() => {\n try {\n abortControllerRef.current?.abort();\n } catch (ignored) {\n } finally {\n setIsLoading(false);\n abortControllerRef.current = null;\n }\n }, []);\n\n const submit = async (input: INPUT) => {\n try {\n setIsLoading(true);\n setError(undefined);\n\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n\n const actualFetch = fetch ?? getOriginalFetch();\n const response = await actualFetch(api, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n signal: abortController.signal,\n body: JSON.stringify(input),\n });\n\n if (!response.ok) {\n throw new Error(\n (await response.text()) ?? 'Failed to fetch the response.',\n );\n }\n\n if (response.body == null) {\n throw new Error('The response body is empty.');\n }\n\n let accumulatedText = '';\n let latestObject: DeepPartial<RESULT> | undefined = undefined;\n\n await response.body.pipeThrough(new TextDecoderStream()).pipeTo(\n new WritableStream<string>({\n write(chunk) {\n accumulatedText += chunk;\n\n const currentObject = parsePartialJson(\n accumulatedText,\n ) as DeepPartial<RESULT>;\n\n if (!isDeepEqualData(latestObject, currentObject)) {\n latestObject = currentObject;\n\n mutate(currentObject);\n }\n },\n\n close() {\n setIsLoading(false);\n abortControllerRef.current = null;\n },\n }),\n );\n } catch (error) {\n if (isAbortError(error)) {\n return;\n }\n\n if (onError && error instanceof Error) {\n onError(error);\n }\n\n setError(error);\n }\n };\n\n return {\n setInput: submit, // Deprecated\n submit,\n object: data,\n error,\n isLoading,\n stop,\n };\n}\n\nexport const experimental_useObject = useObject;\n"],"mappings":"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","names":["fetch","messages","_a","error","import_ui_utils","import_react","generateId","fetch","generateIdFunc","useSWR","messages","chatRequest","import_ui_utils","import_react","import_swr","fetch","useSWR","completion","data","import_provider_utils","import_ui_utils","import_react","import_swr","getOriginalFetch","fetch","useSWR","error"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/use-assistant.ts","../src/use-chat.ts","../src/use-completion.ts","../src/use-object.ts"],"sourcesContent":["export * from './use-assistant';\nexport * from './use-chat';\nexport * from './use-completion';\nexport * from './use-object';\n","import { isAbortError } from '@ai-sdk/provider-utils';\nimport {\n AssistantStatus,\n CreateMessage,\n Message,\n UseAssistantOptions,\n generateId,\n readDataStream,\n} from '@ai-sdk/ui-utils';\nimport { useCallback, useRef, useState } from 'react';\n\n// use function to allow for mocking in tests:\nconst getOriginalFetch = () => fetch;\n\nexport type UseAssistantHelpers = {\n /**\n * The current array of chat messages.\n */\n messages: Message[];\n\n /**\n * Update the message store with a new array of messages.\n */\n setMessages: React.Dispatch<React.SetStateAction<Message[]>>;\n\n /**\n * The current thread ID.\n */\n threadId: 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 /**\n * The current value of the input field.\n */\n input: 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 /**\nAbort the current request immediately, keep the generated tokens if any.\n */\n stop: () => void;\n\n /**\n * setState-powered method to update the input value.\n */\n setInput: React.Dispatch<React.SetStateAction<string>>;\n\n /**\n * Handler for the `onChange` event of the input field to control the input's value.\n */\n handleInputChange: (\n event:\n | React.ChangeEvent<HTMLInputElement>\n | React.ChangeEvent<HTMLTextAreaElement>,\n ) => void;\n\n /**\n * Form submission handler that automatically resets the input field and appends a user message.\n */\n submitMessage: (\n event?: React.FormEvent<HTMLFormElement>,\n requestOptions?: {\n data?: Record<string, string>;\n },\n ) => Promise<void>;\n\n /**\n * The current status of the assistant. This can be used to show a loading indicator.\n */\n status: AssistantStatus;\n\n /**\n * The error thrown during the assistant message processing, if any.\n */\n error: undefined | Error;\n};\n\nexport function useAssistant({\n api,\n threadId: threadIdParam,\n credentials,\n headers,\n body,\n onError,\n fetch,\n}: UseAssistantOptions): UseAssistantHelpers {\n const [messages, setMessages] = useState<Message[]>([]);\n const [input, setInput] = useState('');\n const [currentThreadId, setCurrentThreadId] = useState<string | undefined>(\n undefined,\n );\n const [status, setStatus] = useState<AssistantStatus>('awaiting_message');\n const [error, setError] = useState<undefined | Error>(undefined);\n\n const handleInputChange = (\n event:\n | React.ChangeEvent<HTMLInputElement>\n | React.ChangeEvent<HTMLTextAreaElement>,\n ) => {\n setInput(event.target.value);\n };\n\n // Abort controller to cancel the current API call.\n const abortControllerRef = useRef<AbortController | null>(null);\n\n const stop = useCallback(() => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n abortControllerRef.current = null;\n }\n }, []);\n\n const append = async (\n message: Message | CreateMessage,\n requestOptions?: {\n data?: Record<string, string>;\n },\n ) => {\n setStatus('in_progress');\n\n setMessages(messages => [\n ...messages,\n {\n ...message,\n id: message.id ?? generateId(),\n },\n ]);\n\n setInput('');\n\n const abortController = new AbortController();\n\n try {\n abortControllerRef.current = abortController;\n\n const actualFetch = fetch ?? getOriginalFetch();\n const response = await actualFetch(api, {\n method: 'POST',\n credentials,\n signal: abortController.signal,\n headers: { 'Content-Type': 'application/json', ...headers },\n body: JSON.stringify({\n ...body,\n // always use user-provided threadId when available:\n threadId: threadIdParam ?? currentThreadId ?? null,\n message: message.content,\n\n // optional request data:\n data: requestOptions?.data,\n }),\n });\n\n if (!response.ok) {\n throw new Error(\n (await response.text()) ?? 'Failed to fetch the assistant response.',\n );\n }\n\n if (response.body == null) {\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 setMessages(messages => [\n ...messages,\n {\n id: value.id,\n role: value.role,\n content: value.content[0].text.value,\n },\n ]);\n break;\n }\n\n case 'text': {\n // text delta - add to last message:\n setMessages(messages => {\n const lastMessage = messages[messages.length - 1];\n return [\n ...messages.slice(0, messages.length - 1),\n {\n id: lastMessage.id,\n role: lastMessage.role,\n content: lastMessage.content + value,\n },\n ];\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 'assistant_control_data': {\n setCurrentThreadId(value.threadId);\n\n // set id of last message:\n setMessages(messages => {\n const lastMessage = messages[messages.length - 1];\n lastMessage.id = value.messageId;\n return [...messages.slice(0, messages.length - 1), lastMessage];\n });\n\n break;\n }\n\n case 'error': {\n setError(new Error(value));\n break;\n }\n }\n }\n } catch (error) {\n // Ignore abort errors as they are expected when the user cancels the request:\n if (isAbortError(error) && abortController.signal.aborted) {\n abortControllerRef.current = null;\n return;\n }\n\n if (onError && error instanceof Error) {\n onError(error);\n }\n\n setError(error as Error);\n } finally {\n abortControllerRef.current = null;\n setStatus('awaiting_message');\n }\n };\n\n const submitMessage = async (\n event?: React.FormEvent<HTMLFormElement>,\n requestOptions?: {\n data?: Record<string, string>;\n },\n ) => {\n event?.preventDefault?.();\n\n if (input === '') {\n return;\n }\n\n append({ role: 'user', content: input }, requestOptions);\n };\n\n const setThreadId = (threadId: string | undefined) => {\n setCurrentThreadId(threadId);\n setMessages([]);\n };\n\n return {\n append,\n messages,\n setMessages,\n threadId: currentThreadId,\n setThreadId,\n input,\n setInput,\n handleInputChange,\n submitMessage,\n status,\n error,\n stop,\n };\n}\n\n/**\n@deprecated Use `useAssistant` instead.\n */\nexport const experimental_useAssistant = useAssistant;\n","import type {\n ChatRequest,\n ChatRequestOptions,\n CreateMessage,\n FetchFunction,\n IdGenerator,\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 { useCallback, useEffect, useId, useRef, useState } from 'react';\nimport useSWR, { KeyedMutator } from 'swr';\n\nexport type { CreateMessage, Message, UseChatOptions };\n\nexport type UseChatHelpers = {\n /** Current messages in the chat */\n messages: Message[];\n /** The error object of the API request */\n error: undefined | Error;\n /**\n * Append a user message to the chat list. This triggers the API call to fetch\n * the assistant's response.\n * @param message The message to append\n * @param options Additional options to pass to the API call\n */\n append: (\n message: Message | CreateMessage,\n chatRequestOptions?: ChatRequestOptions,\n ) => Promise<string | null | undefined>;\n /**\n * Reload the last AI chat response for the given chat history. If the last\n * message isn't from the assistant, it will request the API to generate a\n * new response.\n */\n reload: (\n chatRequestOptions?: ChatRequestOptions,\n ) => Promise<string | null | undefined>;\n /**\n * Abort the current request immediately, keep the generated tokens if any.\n */\n stop: () => void;\n /**\n * Update the `messages` state locally. This is useful when you want to\n * edit the messages on the client, and then trigger the `reload` method\n * manually to regenerate the AI response.\n */\n setMessages: (messages: Message[]) => void;\n /** The current value of the input */\n input: string;\n /** setState-powered method to update the input value */\n setInput: React.Dispatch<React.SetStateAction<string>>;\n /** An input/textarea-ready onChange handler to control the value of the input */\n handleInputChange: (\n e:\n | React.ChangeEvent<HTMLInputElement>\n | React.ChangeEvent<HTMLTextAreaElement>,\n ) => void;\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 metadata?: Object;\n /** Whether the API request is in progress */\n isLoading: boolean;\n /** Additional data added on the server via StreamData */\n data?: JSONValue[];\n};\n\nconst getStreamedResponse = async (\n api: string,\n chatRequest: ChatRequest,\n mutate: KeyedMutator<Message[]>,\n mutateStreamData: KeyedMutator<JSONValue[] | undefined>,\n existingData: JSONValue[] | undefined,\n extraMetadataRef: React.MutableRefObject<any>,\n messagesRef: React.MutableRefObject<Message[]>,\n abortControllerRef: React.MutableRefObject<AbortController | null>,\n generateId: IdGenerator,\n streamMode: 'stream-data' | 'text' | undefined,\n onFinish: ((message: Message) => void) | undefined,\n onResponse: ((response: Response) => void | Promise<void>) | undefined,\n onToolCall: UseChatOptions['onToolCall'] | undefined,\n sendExtraMessageFields: boolean | undefined,\n experimental_prepareRequestBody:\n | ((options: {\n messages: Message[];\n requestData?: JSONValue;\n requestBody?: object;\n }) => JSONValue)\n | undefined,\n fetch: FetchFunction | undefined,\n) => {\n // Do an optimistic update to the chat state to show the updated messages\n // immediately.\n const previousMessages = messagesRef.current;\n mutate(chatRequest.messages, false);\n\n const constructedMessagesPayload = sendExtraMessageFields\n ? chatRequest.messages\n : chatRequest.messages.map(\n ({\n role,\n content,\n name,\n data,\n annotations,\n toolInvocations,\n function_call,\n tool_calls,\n tool_call_id,\n }) => ({\n role,\n content,\n ...(name !== undefined && { name }),\n ...(data !== undefined && { data }),\n ...(annotations !== undefined && { annotations }),\n ...(toolInvocations !== undefined && { toolInvocations }),\n // outdated function/tool call handling (TODO deprecate):\n tool_call_id,\n ...(function_call !== undefined && { function_call }),\n ...(tool_calls !== undefined && { tool_calls }),\n }),\n );\n\n return await callChatApi({\n api,\n body: experimental_prepareRequestBody?.({\n messages: chatRequest.messages,\n requestData: chatRequest.data,\n requestBody: chatRequest.body,\n }) ?? {\n messages: constructedMessagesPayload,\n data: chatRequest.data,\n ...extraMetadataRef.current.body,\n ...chatRequest.body,\n ...(chatRequest.functions !== undefined && {\n functions: chatRequest.functions,\n }),\n ...(chatRequest.function_call !== undefined && {\n function_call: chatRequest.function_call,\n }),\n ...(chatRequest.tools !== undefined && {\n tools: chatRequest.tools,\n }),\n ...(chatRequest.tool_choice !== undefined && {\n tool_choice: chatRequest.tool_choice,\n }),\n },\n streamMode,\n credentials: extraMetadataRef.current.credentials,\n headers: {\n ...extraMetadataRef.current.headers,\n ...chatRequest.headers,\n },\n abortController: () => abortControllerRef.current,\n restoreMessagesOnFailure() {\n mutate(previousMessages, false);\n },\n onResponse,\n onUpdate(merged, data) {\n mutate([...chatRequest.messages, ...merged], false);\n mutateStreamData([...(existingData || []), ...(data || [])], false);\n },\n onToolCall,\n onFinish,\n generateId,\n fetch,\n });\n};\n\nexport function useChat({\n api = '/api/chat',\n id,\n initialMessages,\n initialInput = '',\n sendExtraMessageFields,\n experimental_onFunctionCall,\n experimental_onToolCall,\n onToolCall,\n experimental_prepareRequestBody,\n experimental_maxAutomaticRoundtrips = 0,\n maxAutomaticRoundtrips = experimental_maxAutomaticRoundtrips,\n maxToolRoundtrips = maxAutomaticRoundtrips,\n streamMode,\n onResponse,\n onFinish,\n onError,\n credentials,\n headers,\n body,\n generateId = generateIdFunc,\n fetch,\n}: UseChatOptions & {\n key?: string;\n\n /**\n@deprecated Use `maxToolRoundtrips` instead.\n */\n experimental_maxAutomaticRoundtrips?: number;\n\n /**\n@deprecated Use `maxToolRoundtrips` instead.\n */\n maxAutomaticRoundtrips?: number;\n\n /**\n * Experimental (React only). When a function is provided, it will be used\n * to prepare the request body for the chat API. This can be useful for\n * customizing the request body based on the messages and data in the chat.\n *\n * @param messages The current messages in the chat.\n * @param requestData The data object passed in the chat request.\n * @param requestBody The request body object passed in the chat request.\n */\n experimental_prepareRequestBody?: (options: {\n messages: Message[];\n requestData?: JSONValue;\n requestBody?: object;\n }) => JSONValue;\n\n /**\nMaximal number of automatic roundtrips for tool calls.\n\nAn automatic tool call roundtrip is a call to the server with the \ntool call results when all tool calls in the last assistant \nmessage have results.\n\nA maximum number is required to prevent infinite loops in the\ncase of misconfigured tools.\n\nBy default, it's set to 0, which will disable the feature.\n */\n maxToolRoundtrips?: number;\n} = {}): UseChatHelpers & {\n /**\n * @deprecated Use `addToolResult` instead.\n */\n experimental_addToolResult: ({\n toolCallId,\n result,\n }: {\n toolCallId: string;\n result: any;\n }) => void;\n addToolResult: ({\n toolCallId,\n result,\n }: {\n toolCallId: string;\n result: any;\n }) => void;\n} {\n // Generate a unique id for the chat if not provided.\n const hookId = useId();\n const idKey = id ?? hookId;\n const chatKey = typeof api === 'string' ? [api, idKey] : idKey;\n\n // Store a empty array as the initial messages\n // (instead of using a default parameter value that gets re-created each time)\n // to avoid re-renders:\n const [initialMessagesFallback] = useState([]);\n\n // Store the chat state in SWR, using the chatId as the key to share states.\n const { data: messages, mutate } = useSWR<Message[]>(\n [chatKey, 'messages'],\n null,\n { fallbackData: initialMessages ?? initialMessagesFallback },\n );\n\n // We store loading state in another hook to sync loading states across hook invocations\n const { data: isLoading = false, mutate: mutateLoading } = useSWR<boolean>(\n [chatKey, 'loading'],\n null,\n );\n\n const { data: streamData, mutate: mutateStreamData } = useSWR<\n JSONValue[] | undefined\n >([chatKey, 'streamData'], null);\n\n const { data: error = undefined, mutate: setError } = useSWR<\n undefined | Error\n >([chatKey, 'error'], null);\n\n // Keep the latest messages in a ref.\n const messagesRef = useRef<Message[]>(messages || []);\n useEffect(() => {\n messagesRef.current = messages || [];\n }, [messages]);\n\n // Abort controller to cancel the current API call.\n const abortControllerRef = useRef<AbortController | null>(null);\n\n const extraMetadataRef = useRef({\n credentials,\n headers,\n body,\n });\n\n useEffect(() => {\n extraMetadataRef.current = {\n credentials,\n headers,\n body,\n };\n }, [credentials, headers, body]);\n\n const triggerRequest = useCallback(\n async (chatRequest: ChatRequest) => {\n const messageCount = messagesRef.current.length;\n\n try {\n mutateLoading(true);\n setError(undefined);\n\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n\n await processChatStream({\n getStreamedResponse: () =>\n getStreamedResponse(\n api,\n chatRequest,\n mutate,\n mutateStreamData,\n streamData!,\n extraMetadataRef,\n messagesRef,\n abortControllerRef,\n generateId,\n streamMode,\n onFinish,\n onResponse,\n onToolCall,\n sendExtraMessageFields,\n experimental_prepareRequestBody,\n fetch,\n ),\n experimental_onFunctionCall,\n experimental_onToolCall,\n updateChatRequest: chatRequestParam => {\n chatRequest = chatRequestParam;\n },\n getCurrentMessages: () => messagesRef.current,\n });\n\n abortControllerRef.current = null;\n } catch (err) {\n // Ignore abort errors as they are expected.\n if ((err as any).name === 'AbortError') {\n abortControllerRef.current = null;\n return null;\n }\n\n if (onError && err instanceof Error) {\n onError(err);\n }\n\n setError(err as Error);\n } finally {\n mutateLoading(false);\n }\n\n // auto-submit when all tool calls in the last assistant message have results:\n const messages = messagesRef.current;\n const lastMessage = messages[messages.length - 1];\n if (\n // ensure we actually have new messages (to prevent infinite loops in case of errors):\n messages.length > messageCount &&\n // ensure there is a last message:\n lastMessage != null &&\n // check if the feature is enabled:\n maxToolRoundtrips > 0 &&\n // check that roundtrip is possible:\n isAssistantMessageWithCompletedToolCalls(lastMessage) &&\n // limit the number of automatic roundtrips:\n countTrailingAssistantMessages(messages) <= maxToolRoundtrips\n ) {\n await triggerRequest({ messages });\n }\n },\n [\n mutate,\n mutateLoading,\n api,\n extraMetadataRef,\n onResponse,\n onFinish,\n onError,\n setError,\n mutateStreamData,\n streamData,\n streamMode,\n sendExtraMessageFields,\n experimental_onFunctionCall,\n experimental_onToolCall,\n experimental_prepareRequestBody,\n onToolCall,\n maxToolRoundtrips,\n messagesRef,\n abortControllerRef,\n generateId,\n fetch,\n ],\n );\n\n const append = useCallback(\n async (\n message: Message | CreateMessage,\n {\n options,\n functions,\n function_call,\n tools,\n tool_choice,\n data,\n headers,\n body,\n }: ChatRequestOptions = {},\n ) => {\n if (!message.id) {\n message.id = generateId();\n }\n\n const requestOptions = {\n headers: headers ?? options?.headers,\n body: body ?? options?.body,\n };\n\n const chatRequest: ChatRequest = {\n messages: messagesRef.current.concat(message as Message),\n options: requestOptions,\n headers: requestOptions.headers,\n body: requestOptions.body,\n data,\n ...(functions !== undefined && { functions }),\n ...(function_call !== undefined && { function_call }),\n ...(tools !== undefined && { tools }),\n ...(tool_choice !== undefined && { tool_choice }),\n };\n\n return triggerRequest(chatRequest);\n },\n [triggerRequest, generateId],\n );\n\n const reload = useCallback(\n async ({\n options,\n functions,\n function_call,\n tools,\n tool_choice,\n }: ChatRequestOptions = {}) => {\n if (messagesRef.current.length === 0) return null;\n\n // Remove last assistant message and retry last user message.\n const lastMessage = messagesRef.current[messagesRef.current.length - 1];\n if (lastMessage.role === 'assistant') {\n const chatRequest: ChatRequest = {\n messages: messagesRef.current.slice(0, -1),\n options,\n ...(functions !== undefined && { functions }),\n ...(function_call !== undefined && { function_call }),\n ...(tools !== undefined && { tools }),\n ...(tool_choice !== undefined && { tool_choice }),\n };\n\n return triggerRequest(chatRequest);\n }\n\n const chatRequest: ChatRequest = {\n messages: messagesRef.current,\n options,\n ...(functions !== undefined && { functions }),\n ...(function_call !== undefined && { function_call }),\n ...(tools !== undefined && { tools }),\n ...(tool_choice !== undefined && { tool_choice }),\n };\n\n return triggerRequest(chatRequest);\n },\n [triggerRequest],\n );\n\n const stop = useCallback(() => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n abortControllerRef.current = null;\n }\n }, []);\n\n const setMessages = useCallback(\n (messages: Message[]) => {\n mutate(messages, false);\n messagesRef.current = messages;\n },\n [mutate],\n );\n\n // Input state and handlers.\n const [input, setInput] = useState(initialInput);\n\n const handleSubmit = useCallback(\n (\n event?: { preventDefault?: () => void },\n options: ChatRequestOptions = {},\n metadata?: Object,\n ) => {\n if (metadata) {\n extraMetadataRef.current = {\n ...extraMetadataRef.current,\n ...metadata,\n };\n }\n\n event?.preventDefault?.();\n\n const requestOptions = {\n headers: options.headers ?? options.options?.headers,\n body: options.body ?? options.options?.body,\n };\n\n const chatRequest: ChatRequest = {\n messages: input\n ? messagesRef.current.concat({\n id: generateId(),\n role: 'user',\n content: input,\n })\n : messagesRef.current,\n options: requestOptions,\n headers: requestOptions.headers,\n body: requestOptions.body,\n data: options.data,\n };\n\n triggerRequest(chatRequest);\n\n setInput('');\n },\n [input, generateId, triggerRequest],\n );\n\n const handleInputChange = (e: any) => {\n setInput(e.target.value);\n };\n\n const addToolResult = ({\n toolCallId,\n result,\n }: {\n toolCallId: string;\n result: any;\n }) => {\n const updatedMessages = messagesRef.current.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 ? { ...toolInvocation, result }\n : toolInvocation,\n ),\n }\n : message,\n );\n\n mutate(updatedMessages, false);\n\n // auto-submit when all tool calls in the last assistant message have results:\n const lastMessage = updatedMessages[updatedMessages.length - 1];\n if (isAssistantMessageWithCompletedToolCalls(lastMessage)) {\n triggerRequest({ messages: updatedMessages });\n }\n };\n\n return {\n messages: messages || [],\n error,\n append,\n reload,\n stop,\n setMessages,\n input,\n setInput,\n handleInputChange,\n handleSubmit,\n isLoading,\n data: streamData,\n addToolResult,\n experimental_addToolResult: 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 {\n JSONValue,\n RequestOptions,\n UseCompletionOptions,\n callCompletionApi,\n} from '@ai-sdk/ui-utils';\nimport { useCallback, useEffect, useId, useRef, useState } from 'react';\nimport useSWR from 'swr';\n\nexport type { UseCompletionOptions };\n\nexport type UseCompletionHelpers = {\n /** The current completion result */\n completion: string;\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 /** The error object of the API request */\n error: undefined | Error;\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: string;\n /** setState-powered method to update the input value */\n setInput: React.Dispatch<React.SetStateAction<string>>;\n /**\n * An input/textarea-ready onChange handler to control the value of the input\n * @example\n * ```jsx\n * <input onChange={handleInputChange} value={input} />\n * ```\n */\n handleInputChange: (\n event:\n | React.ChangeEvent<HTMLInputElement>\n | React.ChangeEvent<HTMLTextAreaElement>,\n ) => void;\n\n /**\n * Form submission handler to automatically reset input and append a user message\n * @example\n * ```jsx\n * <form onSubmit={handleSubmit}>\n * <input onChange={handleInputChange} value={input} />\n * </form>\n * ```\n */\n handleSubmit: (event?: { preventDefault?: () => void }) => void;\n\n /** Whether the API request is in progress */\n isLoading: boolean;\n /** Additional data added on the server via StreamData */\n data?: JSONValue[];\n};\n\nexport function useCompletion({\n api = '/api/completion',\n id,\n initialCompletion = '',\n initialInput = '',\n credentials,\n headers,\n body,\n streamMode,\n fetch,\n onResponse,\n onFinish,\n onError,\n}: UseCompletionOptions = {}): UseCompletionHelpers {\n // Generate an unique id for the completion if not provided.\n const hookId = useId();\n const completionId = id || hookId;\n\n // Store the completion state in SWR, using the completionId as the key to share states.\n const { data, mutate } = useSWR<string>([api, completionId], null, {\n fallbackData: initialCompletion,\n });\n\n const { data: isLoading = false, mutate: mutateLoading } = useSWR<boolean>(\n [completionId, 'loading'],\n null,\n );\n\n const { data: streamData, mutate: mutateStreamData } = useSWR<\n JSONValue[] | undefined\n >([completionId, 'streamData'], null);\n\n const [error, setError] = useState<undefined | Error>(undefined);\n const completion = data!;\n\n // Abort controller to cancel the current API call.\n const [abortController, setAbortController] =\n useState<AbortController | null>(null);\n\n const extraMetadataRef = useRef({\n credentials,\n headers,\n body,\n });\n useEffect(() => {\n extraMetadataRef.current = {\n credentials,\n headers,\n body,\n };\n }, [credentials, headers, body]);\n\n const triggerRequest = useCallback(\n async (prompt: string, options?: RequestOptions) =>\n callCompletionApi({\n api,\n prompt,\n credentials: extraMetadataRef.current.credentials,\n headers: { ...extraMetadataRef.current.headers, ...options?.headers },\n body: {\n ...extraMetadataRef.current.body,\n ...options?.body,\n },\n streamMode,\n fetch,\n setCompletion: completion => mutate(completion, false),\n setLoading: mutateLoading,\n setError,\n setAbortController,\n onResponse,\n onFinish,\n onError,\n onData: data => {\n mutateStreamData([...(streamData || []), ...(data || [])], false);\n },\n }),\n [\n mutate,\n mutateLoading,\n api,\n extraMetadataRef,\n setAbortController,\n onResponse,\n onFinish,\n onError,\n setError,\n streamData,\n streamMode,\n fetch,\n mutateStreamData,\n ],\n );\n\n const stop = useCallback(() => {\n if (abortController) {\n abortController.abort();\n setAbortController(null);\n }\n }, [abortController]);\n\n const setCompletion = useCallback(\n (completion: string) => {\n mutate(completion, false);\n },\n [mutate],\n );\n\n const complete = useCallback<UseCompletionHelpers['complete']>(\n async (prompt, options) => {\n return triggerRequest(prompt, options);\n },\n [triggerRequest],\n );\n\n const [input, setInput] = useState(initialInput);\n\n const handleSubmit = useCallback(\n (event?: { preventDefault?: () => void }) => {\n event?.preventDefault?.();\n return input ? complete(input) : undefined;\n },\n [input, complete],\n );\n\n const handleInputChange = (e: any) => {\n setInput(e.target.value);\n };\n\n return {\n completion,\n complete,\n error,\n setCompletion,\n stop,\n input,\n setInput,\n handleInputChange,\n handleSubmit,\n isLoading,\n data: streamData,\n };\n}\n","import { isAbortError } from '@ai-sdk/provider-utils';\nimport {\n DeepPartial,\n FetchFunction,\n isDeepEqualData,\n parsePartialJson,\n} from '@ai-sdk/ui-utils';\nimport { useCallback, useId, useRef, useState } from 'react';\nimport useSWR from 'swr';\nimport z from 'zod';\n\n// use function to allow for mocking in tests:\nconst getOriginalFetch = () => fetch;\n\nexport type Experimental_UseObjectOptions<RESULT> = {\n /**\n * The API endpoint. It should stream JSON that matches the schema as chunked text.\n */\n api: string;\n\n /**\n * A Zod schema that defines the shape of the complete object.\n */\n schema: z.Schema<RESULT>;\n\n /**\n * An unique identifier. If not provided, a random one will be\n * generated. When provided, the `useObject` hook with the same `id` will\n * have shared states across components.\n */\n id?: string;\n\n /**\n * An optional value for the initial object.\n */\n initialValue?: DeepPartial<RESULT>;\n\n /**\nCustom fetch implementation. You can use it as a middleware to intercept requests,\nor to provide a custom fetch implementation for e.g. testing.\n */\n fetch?: FetchFunction;\n\n /**\n * Callback function to be called when an error is encountered.\n */\n onError?: (error: Error) => void;\n};\n\nexport type Experimental_UseObjectHelpers<RESULT, INPUT> = {\n /**\n * @deprecated Use `submit` instead.\n */\n setInput: (input: INPUT) => void;\n\n /**\n * Calls the API with the provided input as JSON body.\n */\n submit: (input: INPUT) => void;\n\n /**\n * The current value for the generated object. Updated as the API streams JSON chunks.\n */\n object: DeepPartial<RESULT> | undefined;\n\n /**\n * The error object of the API request if any.\n */\n error: undefined | unknown;\n\n /**\n * Flag that indicates whether an API request is in progress.\n */\n isLoading: boolean;\n\n /**\n * Abort the current request immediately, keep the current partial object if any.\n */\n stop: () => void;\n};\n\nfunction useObject<RESULT, INPUT = any>({\n api,\n id,\n schema, // required, in the future we will use it for validation\n initialValue,\n fetch,\n onError,\n}: Experimental_UseObjectOptions<RESULT>): Experimental_UseObjectHelpers<\n RESULT,\n INPUT\n> {\n // Generate an unique id if not provided.\n const hookId = useId();\n const completionId = id ?? hookId;\n\n // Store the completion state in SWR, using the completionId as the key to share states.\n const { data, mutate } = useSWR<DeepPartial<RESULT>>(\n [api, completionId],\n null,\n { fallbackData: initialValue },\n );\n\n const [error, setError] = useState<undefined | unknown>(undefined);\n const [isLoading, setIsLoading] = useState(false);\n\n // Abort controller to cancel the current API call.\n const abortControllerRef = useRef<AbortController | null>(null);\n\n const stop = useCallback(() => {\n try {\n abortControllerRef.current?.abort();\n } catch (ignored) {\n } finally {\n setIsLoading(false);\n abortControllerRef.current = null;\n }\n }, []);\n\n const submit = async (input: INPUT) => {\n try {\n setIsLoading(true);\n setError(undefined);\n\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n\n const actualFetch = fetch ?? getOriginalFetch();\n const response = await actualFetch(api, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n signal: abortController.signal,\n body: JSON.stringify(input),\n });\n\n if (!response.ok) {\n throw new Error(\n (await response.text()) ?? 'Failed to fetch the response.',\n );\n }\n\n if (response.body == null) {\n throw new Error('The response body is empty.');\n }\n\n let accumulatedText = '';\n let latestObject: DeepPartial<RESULT> | undefined = undefined;\n\n await response.body.pipeThrough(new TextDecoderStream()).pipeTo(\n new WritableStream<string>({\n write(chunk) {\n accumulatedText += chunk;\n\n const currentObject = parsePartialJson(\n accumulatedText,\n ) as DeepPartial<RESULT>;\n\n if (!isDeepEqualData(latestObject, currentObject)) {\n latestObject = currentObject;\n\n mutate(currentObject);\n }\n },\n\n close() {\n setIsLoading(false);\n abortControllerRef.current = null;\n },\n }),\n );\n } catch (error) {\n if (isAbortError(error)) {\n return;\n }\n\n if (onError && error instanceof Error) {\n onError(error);\n }\n\n setError(error);\n }\n };\n\n return {\n setInput: submit, // Deprecated\n submit,\n object: data,\n error,\n isLoading,\n stop,\n };\n}\n\nexport const experimental_useObject = useObject;\n"],"mappings":"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","names":["fetch","messages","_a","error","import_ui_utils","import_react","generateId","fetch","generateIdFunc","useSWR","messages","headers","body","chatRequest","import_ui_utils","import_react","import_swr","fetch","useSWR","completion","data","import_provider_utils","import_ui_utils","import_react","import_swr","getOriginalFetch","fetch","useSWR","error"]}
package/dist/index.mjs CHANGED
@@ -183,7 +183,7 @@ import {
183
183
  import { useCallback as useCallback2, useEffect, useId, useRef as useRef2, useState as useState2 } from "react";
184
184
  import useSWR from "swr";
185
185
  var getStreamedResponse = async (api, chatRequest, mutate, mutateStreamData, existingData, extraMetadataRef, messagesRef, abortControllerRef, generateId2, streamMode, onFinish, onResponse, onToolCall, sendExtraMessageFields, experimental_prepareRequestBody, fetch2) => {
186
- var _a, _b, _c, _d;
186
+ var _a;
187
187
  const previousMessages = messagesRef.current;
188
188
  mutate(chatRequest.messages, false);
189
189
  const constructedMessagesPayload = sendExtraMessageFields ? chatRequest.messages : chatRequest.messages.map(
@@ -212,15 +212,15 @@ var getStreamedResponse = async (api, chatRequest, mutate, mutateStreamData, exi
212
212
  );
213
213
  return await callChatApi({
214
214
  api,
215
- body: (_c = experimental_prepareRequestBody == null ? void 0 : experimental_prepareRequestBody({
215
+ body: (_a = experimental_prepareRequestBody == null ? void 0 : experimental_prepareRequestBody({
216
216
  messages: chatRequest.messages,
217
217
  requestData: chatRequest.data,
218
- requestBody: (_a = chatRequest.options) == null ? void 0 : _a.body
219
- })) != null ? _c : {
218
+ requestBody: chatRequest.body
219
+ })) != null ? _a : {
220
220
  messages: constructedMessagesPayload,
221
221
  data: chatRequest.data,
222
222
  ...extraMetadataRef.current.body,
223
- ...(_b = chatRequest.options) == null ? void 0 : _b.body,
223
+ ...chatRequest.body,
224
224
  ...chatRequest.functions !== void 0 && {
225
225
  functions: chatRequest.functions
226
226
  },
@@ -238,7 +238,7 @@ var getStreamedResponse = async (api, chatRequest, mutate, mutateStreamData, exi
238
238
  credentials: extraMetadataRef.current.credentials,
239
239
  headers: {
240
240
  ...extraMetadataRef.current.headers,
241
- ...(_d = chatRequest.options) == null ? void 0 : _d.headers
241
+ ...chatRequest.headers
242
242
  },
243
243
  abortController: () => abortControllerRef.current,
244
244
  restoreMessagesOnFailure() {
@@ -401,14 +401,22 @@ function useChat({
401
401
  function_call,
402
402
  tools,
403
403
  tool_choice,
404
- data
404
+ data,
405
+ headers: headers2,
406
+ body: body2
405
407
  } = {}) => {
406
408
  if (!message.id) {
407
409
  message.id = generateId2();
408
410
  }
411
+ const requestOptions = {
412
+ headers: headers2 != null ? headers2 : options == null ? void 0 : options.headers,
413
+ body: body2 != null ? body2 : options == null ? void 0 : options.body
414
+ };
409
415
  const chatRequest = {
410
416
  messages: messagesRef.current.concat(message),
411
- options,
417
+ options: requestOptions,
418
+ headers: requestOptions.headers,
419
+ body: requestOptions.body,
412
420
  data,
413
421
  ...functions !== void 0 && { functions },
414
422
  ...function_call !== void 0 && { function_call },
@@ -469,7 +477,7 @@ function useChat({
469
477
  const [input, setInput] = useState2(initialInput);
470
478
  const handleSubmit = useCallback2(
471
479
  (event, options = {}, metadata) => {
472
- var _a;
480
+ var _a, _b, _c, _d, _e;
473
481
  if (metadata) {
474
482
  extraMetadataRef.current = {
475
483
  ...extraMetadataRef.current,
@@ -477,13 +485,19 @@ function useChat({
477
485
  };
478
486
  }
479
487
  (_a = event == null ? void 0 : event.preventDefault) == null ? void 0 : _a.call(event);
488
+ const requestOptions = {
489
+ headers: (_c = options.headers) != null ? _c : (_b = options.options) == null ? void 0 : _b.headers,
490
+ body: (_e = options.body) != null ? _e : (_d = options.options) == null ? void 0 : _d.body
491
+ };
480
492
  const chatRequest = {
481
493
  messages: input ? messagesRef.current.concat({
482
494
  id: generateId2(),
483
495
  role: "user",
484
496
  content: input
485
497
  }) : messagesRef.current,
486
- options: options.options,
498
+ options: requestOptions,
499
+ headers: requestOptions.headers,
500
+ body: requestOptions.body,
487
501
  data: options.data
488
502
  };
489
503
  triggerRequest(chatRequest);
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/use-assistant.ts","../src/use-chat.ts","../src/use-completion.ts","../src/use-object.ts"],"sourcesContent":["import { isAbortError } from '@ai-sdk/provider-utils';\nimport {\n AssistantStatus,\n CreateMessage,\n Message,\n UseAssistantOptions,\n generateId,\n readDataStream,\n} from '@ai-sdk/ui-utils';\nimport { useCallback, useRef, useState } from 'react';\n\n// use function to allow for mocking in tests:\nconst getOriginalFetch = () => fetch;\n\nexport type UseAssistantHelpers = {\n /**\n * The current array of chat messages.\n */\n messages: Message[];\n\n /**\n * Update the message store with a new array of messages.\n */\n setMessages: React.Dispatch<React.SetStateAction<Message[]>>;\n\n /**\n * The current thread ID.\n */\n threadId: 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 /**\n * The current value of the input field.\n */\n input: 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 /**\nAbort the current request immediately, keep the generated tokens if any.\n */\n stop: () => void;\n\n /**\n * setState-powered method to update the input value.\n */\n setInput: React.Dispatch<React.SetStateAction<string>>;\n\n /**\n * Handler for the `onChange` event of the input field to control the input's value.\n */\n handleInputChange: (\n event:\n | React.ChangeEvent<HTMLInputElement>\n | React.ChangeEvent<HTMLTextAreaElement>,\n ) => void;\n\n /**\n * Form submission handler that automatically resets the input field and appends a user message.\n */\n submitMessage: (\n event?: React.FormEvent<HTMLFormElement>,\n requestOptions?: {\n data?: Record<string, string>;\n },\n ) => Promise<void>;\n\n /**\n * The current status of the assistant. This can be used to show a loading indicator.\n */\n status: AssistantStatus;\n\n /**\n * The error thrown during the assistant message processing, if any.\n */\n error: undefined | Error;\n};\n\nexport function useAssistant({\n api,\n threadId: threadIdParam,\n credentials,\n headers,\n body,\n onError,\n fetch,\n}: UseAssistantOptions): UseAssistantHelpers {\n const [messages, setMessages] = useState<Message[]>([]);\n const [input, setInput] = useState('');\n const [currentThreadId, setCurrentThreadId] = useState<string | undefined>(\n undefined,\n );\n const [status, setStatus] = useState<AssistantStatus>('awaiting_message');\n const [error, setError] = useState<undefined | Error>(undefined);\n\n const handleInputChange = (\n event:\n | React.ChangeEvent<HTMLInputElement>\n | React.ChangeEvent<HTMLTextAreaElement>,\n ) => {\n setInput(event.target.value);\n };\n\n // Abort controller to cancel the current API call.\n const abortControllerRef = useRef<AbortController | null>(null);\n\n const stop = useCallback(() => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n abortControllerRef.current = null;\n }\n }, []);\n\n const append = async (\n message: Message | CreateMessage,\n requestOptions?: {\n data?: Record<string, string>;\n },\n ) => {\n setStatus('in_progress');\n\n setMessages(messages => [\n ...messages,\n {\n ...message,\n id: message.id ?? generateId(),\n },\n ]);\n\n setInput('');\n\n const abortController = new AbortController();\n\n try {\n abortControllerRef.current = abortController;\n\n const actualFetch = fetch ?? getOriginalFetch();\n const response = await actualFetch(api, {\n method: 'POST',\n credentials,\n signal: abortController.signal,\n headers: { 'Content-Type': 'application/json', ...headers },\n body: JSON.stringify({\n ...body,\n // always use user-provided threadId when available:\n threadId: threadIdParam ?? currentThreadId ?? null,\n message: message.content,\n\n // optional request data:\n data: requestOptions?.data,\n }),\n });\n\n if (!response.ok) {\n throw new Error(\n (await response.text()) ?? 'Failed to fetch the assistant response.',\n );\n }\n\n if (response.body == null) {\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 setMessages(messages => [\n ...messages,\n {\n id: value.id,\n role: value.role,\n content: value.content[0].text.value,\n },\n ]);\n break;\n }\n\n case 'text': {\n // text delta - add to last message:\n setMessages(messages => {\n const lastMessage = messages[messages.length - 1];\n return [\n ...messages.slice(0, messages.length - 1),\n {\n id: lastMessage.id,\n role: lastMessage.role,\n content: lastMessage.content + value,\n },\n ];\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 'assistant_control_data': {\n setCurrentThreadId(value.threadId);\n\n // set id of last message:\n setMessages(messages => {\n const lastMessage = messages[messages.length - 1];\n lastMessage.id = value.messageId;\n return [...messages.slice(0, messages.length - 1), lastMessage];\n });\n\n break;\n }\n\n case 'error': {\n setError(new Error(value));\n break;\n }\n }\n }\n } catch (error) {\n // Ignore abort errors as they are expected when the user cancels the request:\n if (isAbortError(error) && abortController.signal.aborted) {\n abortControllerRef.current = null;\n return;\n }\n\n if (onError && error instanceof Error) {\n onError(error);\n }\n\n setError(error as Error);\n } finally {\n abortControllerRef.current = null;\n setStatus('awaiting_message');\n }\n };\n\n const submitMessage = async (\n event?: React.FormEvent<HTMLFormElement>,\n requestOptions?: {\n data?: Record<string, string>;\n },\n ) => {\n event?.preventDefault?.();\n\n if (input === '') {\n return;\n }\n\n append({ role: 'user', content: input }, requestOptions);\n };\n\n const setThreadId = (threadId: string | undefined) => {\n setCurrentThreadId(threadId);\n setMessages([]);\n };\n\n return {\n append,\n messages,\n setMessages,\n threadId: currentThreadId,\n setThreadId,\n input,\n setInput,\n handleInputChange,\n submitMessage,\n status,\n error,\n stop,\n };\n}\n\n/**\n@deprecated Use `useAssistant` instead.\n */\nexport const experimental_useAssistant = useAssistant;\n","import type {\n ChatRequest,\n ChatRequestOptions,\n CreateMessage,\n FetchFunction,\n IdGenerator,\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 { useCallback, useEffect, useId, useRef, useState } from 'react';\nimport useSWR, { KeyedMutator } from 'swr';\n\nexport type { CreateMessage, Message, UseChatOptions };\n\nexport type UseChatHelpers = {\n /** Current messages in the chat */\n messages: Message[];\n /** The error object of the API request */\n error: undefined | Error;\n /**\n * Append a user message to the chat list. This triggers the API call to fetch\n * the assistant's response.\n * @param message The message to append\n * @param options Additional options to pass to the API call\n */\n append: (\n message: Message | CreateMessage,\n chatRequestOptions?: ChatRequestOptions,\n ) => Promise<string | null | undefined>;\n /**\n * Reload the last AI chat response for the given chat history. If the last\n * message isn't from the assistant, it will request the API to generate a\n * new response.\n */\n reload: (\n chatRequestOptions?: ChatRequestOptions,\n ) => Promise<string | null | undefined>;\n /**\n * Abort the current request immediately, keep the generated tokens if any.\n */\n stop: () => void;\n /**\n * Update the `messages` state locally. This is useful when you want to\n * edit the messages on the client, and then trigger the `reload` method\n * manually to regenerate the AI response.\n */\n setMessages: (messages: Message[]) => void;\n /** The current value of the input */\n input: string;\n /** setState-powered method to update the input value */\n setInput: React.Dispatch<React.SetStateAction<string>>;\n /** An input/textarea-ready onChange handler to control the value of the input */\n handleInputChange: (\n e:\n | React.ChangeEvent<HTMLInputElement>\n | React.ChangeEvent<HTMLTextAreaElement>,\n ) => void;\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 metadata?: Object;\n /** Whether the API request is in progress */\n isLoading: boolean;\n /** Additional data added on the server via StreamData */\n data?: JSONValue[];\n};\n\nconst getStreamedResponse = async (\n api: string,\n chatRequest: ChatRequest,\n mutate: KeyedMutator<Message[]>,\n mutateStreamData: KeyedMutator<JSONValue[] | undefined>,\n existingData: JSONValue[] | undefined,\n extraMetadataRef: React.MutableRefObject<any>,\n messagesRef: React.MutableRefObject<Message[]>,\n abortControllerRef: React.MutableRefObject<AbortController | null>,\n generateId: IdGenerator,\n streamMode: 'stream-data' | 'text' | undefined,\n onFinish: ((message: Message) => void) | undefined,\n onResponse: ((response: Response) => void | Promise<void>) | undefined,\n onToolCall: UseChatOptions['onToolCall'] | undefined,\n sendExtraMessageFields: boolean | undefined,\n experimental_prepareRequestBody:\n | ((options: {\n messages: Message[];\n requestData?: JSONValue;\n requestBody?: object;\n }) => JSONValue)\n | undefined,\n fetch: FetchFunction | undefined,\n) => {\n // Do an optimistic update to the chat state to show the updated messages\n // immediately.\n const previousMessages = messagesRef.current;\n mutate(chatRequest.messages, false);\n\n const constructedMessagesPayload = sendExtraMessageFields\n ? chatRequest.messages\n : chatRequest.messages.map(\n ({\n role,\n content,\n name,\n data,\n annotations,\n toolInvocations,\n function_call,\n tool_calls,\n tool_call_id,\n }) => ({\n role,\n content,\n ...(name !== undefined && { name }),\n ...(data !== undefined && { data }),\n ...(annotations !== undefined && { annotations }),\n ...(toolInvocations !== undefined && { toolInvocations }),\n // outdated function/tool call handling (TODO deprecate):\n tool_call_id,\n ...(function_call !== undefined && { function_call }),\n ...(tool_calls !== undefined && { tool_calls }),\n }),\n );\n\n return await callChatApi({\n api,\n body: experimental_prepareRequestBody?.({\n messages: chatRequest.messages,\n requestData: chatRequest.data,\n requestBody: chatRequest.options?.body,\n }) ?? {\n messages: constructedMessagesPayload,\n data: chatRequest.data,\n ...extraMetadataRef.current.body,\n ...chatRequest.options?.body,\n ...(chatRequest.functions !== undefined && {\n functions: chatRequest.functions,\n }),\n ...(chatRequest.function_call !== undefined && {\n function_call: chatRequest.function_call,\n }),\n ...(chatRequest.tools !== undefined && {\n tools: chatRequest.tools,\n }),\n ...(chatRequest.tool_choice !== undefined && {\n tool_choice: chatRequest.tool_choice,\n }),\n },\n streamMode,\n credentials: extraMetadataRef.current.credentials,\n headers: {\n ...extraMetadataRef.current.headers,\n ...chatRequest.options?.headers,\n },\n abortController: () => abortControllerRef.current,\n restoreMessagesOnFailure() {\n mutate(previousMessages, false);\n },\n onResponse,\n onUpdate(merged, data) {\n mutate([...chatRequest.messages, ...merged], false);\n mutateStreamData([...(existingData || []), ...(data || [])], false);\n },\n onToolCall,\n onFinish,\n generateId,\n fetch,\n });\n};\n\nexport function useChat({\n api = '/api/chat',\n id,\n initialMessages,\n initialInput = '',\n sendExtraMessageFields,\n experimental_onFunctionCall,\n experimental_onToolCall,\n onToolCall,\n experimental_prepareRequestBody,\n experimental_maxAutomaticRoundtrips = 0,\n maxAutomaticRoundtrips = experimental_maxAutomaticRoundtrips,\n maxToolRoundtrips = maxAutomaticRoundtrips,\n streamMode,\n onResponse,\n onFinish,\n onError,\n credentials,\n headers,\n body,\n generateId = generateIdFunc,\n fetch,\n}: UseChatOptions & {\n key?: string;\n\n /**\n@deprecated Use `maxToolRoundtrips` instead.\n */\n experimental_maxAutomaticRoundtrips?: number;\n\n /**\n@deprecated Use `maxToolRoundtrips` instead.\n */\n maxAutomaticRoundtrips?: number;\n\n /**\n * Experimental (React only). When a function is provided, it will be used\n * to prepare the request body for the chat API. This can be useful for\n * customizing the request body based on the messages and data in the chat.\n *\n * @param messages The current messages in the chat.\n * @param requestData The data object passed in the chat request.\n * @param requestBody The request body object passed in the chat request.\n */\n experimental_prepareRequestBody?: (options: {\n messages: Message[];\n requestData?: JSONValue;\n requestBody?: object;\n }) => JSONValue;\n\n /**\nMaximal number of automatic roundtrips for tool calls.\n\nAn automatic tool call roundtrip is a call to the server with the \ntool call results when all tool calls in the last assistant \nmessage have results.\n\nA maximum number is required to prevent infinite loops in the\ncase of misconfigured tools.\n\nBy default, it's set to 0, which will disable the feature.\n */\n maxToolRoundtrips?: number;\n} = {}): UseChatHelpers & {\n /**\n * @deprecated Use `addToolResult` instead.\n */\n experimental_addToolResult: ({\n toolCallId,\n result,\n }: {\n toolCallId: string;\n result: any;\n }) => void;\n addToolResult: ({\n toolCallId,\n result,\n }: {\n toolCallId: string;\n result: any;\n }) => void;\n} {\n // Generate a unique id for the chat if not provided.\n const hookId = useId();\n const idKey = id ?? hookId;\n const chatKey = typeof api === 'string' ? [api, idKey] : idKey;\n\n // Store a empty array as the initial messages\n // (instead of using a default parameter value that gets re-created each time)\n // to avoid re-renders:\n const [initialMessagesFallback] = useState([]);\n\n // Store the chat state in SWR, using the chatId as the key to share states.\n const { data: messages, mutate } = useSWR<Message[]>(\n [chatKey, 'messages'],\n null,\n { fallbackData: initialMessages ?? initialMessagesFallback },\n );\n\n // We store loading state in another hook to sync loading states across hook invocations\n const { data: isLoading = false, mutate: mutateLoading } = useSWR<boolean>(\n [chatKey, 'loading'],\n null,\n );\n\n const { data: streamData, mutate: mutateStreamData } = useSWR<\n JSONValue[] | undefined\n >([chatKey, 'streamData'], null);\n\n const { data: error = undefined, mutate: setError } = useSWR<\n undefined | Error\n >([chatKey, 'error'], null);\n\n // Keep the latest messages in a ref.\n const messagesRef = useRef<Message[]>(messages || []);\n useEffect(() => {\n messagesRef.current = messages || [];\n }, [messages]);\n\n // Abort controller to cancel the current API call.\n const abortControllerRef = useRef<AbortController | null>(null);\n\n const extraMetadataRef = useRef({\n credentials,\n headers,\n body,\n });\n\n useEffect(() => {\n extraMetadataRef.current = {\n credentials,\n headers,\n body,\n };\n }, [credentials, headers, body]);\n\n const triggerRequest = useCallback(\n async (chatRequest: ChatRequest) => {\n const messageCount = messagesRef.current.length;\n\n try {\n mutateLoading(true);\n setError(undefined);\n\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n\n await processChatStream({\n getStreamedResponse: () =>\n getStreamedResponse(\n api,\n chatRequest,\n mutate,\n mutateStreamData,\n streamData!,\n extraMetadataRef,\n messagesRef,\n abortControllerRef,\n generateId,\n streamMode,\n onFinish,\n onResponse,\n onToolCall,\n sendExtraMessageFields,\n experimental_prepareRequestBody,\n fetch,\n ),\n experimental_onFunctionCall,\n experimental_onToolCall,\n updateChatRequest: chatRequestParam => {\n chatRequest = chatRequestParam;\n },\n getCurrentMessages: () => messagesRef.current,\n });\n\n abortControllerRef.current = null;\n } catch (err) {\n // Ignore abort errors as they are expected.\n if ((err as any).name === 'AbortError') {\n abortControllerRef.current = null;\n return null;\n }\n\n if (onError && err instanceof Error) {\n onError(err);\n }\n\n setError(err as Error);\n } finally {\n mutateLoading(false);\n }\n\n // auto-submit when all tool calls in the last assistant message have results:\n const messages = messagesRef.current;\n const lastMessage = messages[messages.length - 1];\n if (\n // ensure we actually have new messages (to prevent infinite loops in case of errors):\n messages.length > messageCount &&\n // ensure there is a last message:\n lastMessage != null &&\n // check if the feature is enabled:\n maxToolRoundtrips > 0 &&\n // check that roundtrip is possible:\n isAssistantMessageWithCompletedToolCalls(lastMessage) &&\n // limit the number of automatic roundtrips:\n countTrailingAssistantMessages(messages) <= maxToolRoundtrips\n ) {\n await triggerRequest({ messages });\n }\n },\n [\n mutate,\n mutateLoading,\n api,\n extraMetadataRef,\n onResponse,\n onFinish,\n onError,\n setError,\n mutateStreamData,\n streamData,\n streamMode,\n sendExtraMessageFields,\n experimental_onFunctionCall,\n experimental_onToolCall,\n experimental_prepareRequestBody,\n onToolCall,\n maxToolRoundtrips,\n messagesRef,\n abortControllerRef,\n generateId,\n fetch,\n ],\n );\n\n const append = useCallback(\n async (\n message: Message | CreateMessage,\n {\n options,\n functions,\n function_call,\n tools,\n tool_choice,\n data,\n }: ChatRequestOptions = {},\n ) => {\n if (!message.id) {\n message.id = generateId();\n }\n\n const chatRequest: ChatRequest = {\n messages: messagesRef.current.concat(message as Message),\n options,\n data,\n ...(functions !== undefined && { functions }),\n ...(function_call !== undefined && { function_call }),\n ...(tools !== undefined && { tools }),\n ...(tool_choice !== undefined && { tool_choice }),\n };\n\n return triggerRequest(chatRequest);\n },\n [triggerRequest, generateId],\n );\n\n const reload = useCallback(\n async ({\n options,\n functions,\n function_call,\n tools,\n tool_choice,\n }: ChatRequestOptions = {}) => {\n if (messagesRef.current.length === 0) return null;\n\n // Remove last assistant message and retry last user message.\n const lastMessage = messagesRef.current[messagesRef.current.length - 1];\n if (lastMessage.role === 'assistant') {\n const chatRequest: ChatRequest = {\n messages: messagesRef.current.slice(0, -1),\n options,\n ...(functions !== undefined && { functions }),\n ...(function_call !== undefined && { function_call }),\n ...(tools !== undefined && { tools }),\n ...(tool_choice !== undefined && { tool_choice }),\n };\n\n return triggerRequest(chatRequest);\n }\n\n const chatRequest: ChatRequest = {\n messages: messagesRef.current,\n options,\n ...(functions !== undefined && { functions }),\n ...(function_call !== undefined && { function_call }),\n ...(tools !== undefined && { tools }),\n ...(tool_choice !== undefined && { tool_choice }),\n };\n\n return triggerRequest(chatRequest);\n },\n [triggerRequest],\n );\n\n const stop = useCallback(() => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n abortControllerRef.current = null;\n }\n }, []);\n\n const setMessages = useCallback(\n (messages: Message[]) => {\n mutate(messages, false);\n messagesRef.current = messages;\n },\n [mutate],\n );\n\n // Input state and handlers.\n const [input, setInput] = useState(initialInput);\n\n const handleSubmit = useCallback(\n (\n event?: { preventDefault?: () => void },\n options: ChatRequestOptions = {},\n metadata?: Object,\n ) => {\n if (metadata) {\n extraMetadataRef.current = {\n ...extraMetadataRef.current,\n ...metadata,\n };\n }\n\n event?.preventDefault?.();\n\n const chatRequest: ChatRequest = {\n messages: input\n ? messagesRef.current.concat({\n id: generateId(),\n role: 'user',\n content: input,\n })\n : messagesRef.current,\n options: options.options,\n data: options.data,\n };\n\n triggerRequest(chatRequest);\n\n setInput('');\n },\n [input, generateId, triggerRequest],\n );\n\n const handleInputChange = (e: any) => {\n setInput(e.target.value);\n };\n\n const addToolResult = ({\n toolCallId,\n result,\n }: {\n toolCallId: string;\n result: any;\n }) => {\n const updatedMessages = messagesRef.current.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 ? { ...toolInvocation, result }\n : toolInvocation,\n ),\n }\n : message,\n );\n\n mutate(updatedMessages, false);\n\n // auto-submit when all tool calls in the last assistant message have results:\n const lastMessage = updatedMessages[updatedMessages.length - 1];\n if (isAssistantMessageWithCompletedToolCalls(lastMessage)) {\n triggerRequest({ messages: updatedMessages });\n }\n };\n\n return {\n messages: messages || [],\n error,\n append,\n reload,\n stop,\n setMessages,\n input,\n setInput,\n handleInputChange,\n handleSubmit,\n isLoading,\n data: streamData,\n addToolResult,\n experimental_addToolResult: 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 {\n JSONValue,\n RequestOptions,\n UseCompletionOptions,\n callCompletionApi,\n} from '@ai-sdk/ui-utils';\nimport { useCallback, useEffect, useId, useRef, useState } from 'react';\nimport useSWR from 'swr';\n\nexport type { UseCompletionOptions };\n\nexport type UseCompletionHelpers = {\n /** The current completion result */\n completion: string;\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 /** The error object of the API request */\n error: undefined | Error;\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: string;\n /** setState-powered method to update the input value */\n setInput: React.Dispatch<React.SetStateAction<string>>;\n /**\n * An input/textarea-ready onChange handler to control the value of the input\n * @example\n * ```jsx\n * <input onChange={handleInputChange} value={input} />\n * ```\n */\n handleInputChange: (\n event:\n | React.ChangeEvent<HTMLInputElement>\n | React.ChangeEvent<HTMLTextAreaElement>,\n ) => void;\n\n /**\n * Form submission handler to automatically reset input and append a user message\n * @example\n * ```jsx\n * <form onSubmit={handleSubmit}>\n * <input onChange={handleInputChange} value={input} />\n * </form>\n * ```\n */\n handleSubmit: (event?: { preventDefault?: () => void }) => void;\n\n /** Whether the API request is in progress */\n isLoading: boolean;\n /** Additional data added on the server via StreamData */\n data?: JSONValue[];\n};\n\nexport function useCompletion({\n api = '/api/completion',\n id,\n initialCompletion = '',\n initialInput = '',\n credentials,\n headers,\n body,\n streamMode,\n fetch,\n onResponse,\n onFinish,\n onError,\n}: UseCompletionOptions = {}): UseCompletionHelpers {\n // Generate an unique id for the completion if not provided.\n const hookId = useId();\n const completionId = id || hookId;\n\n // Store the completion state in SWR, using the completionId as the key to share states.\n const { data, mutate } = useSWR<string>([api, completionId], null, {\n fallbackData: initialCompletion,\n });\n\n const { data: isLoading = false, mutate: mutateLoading } = useSWR<boolean>(\n [completionId, 'loading'],\n null,\n );\n\n const { data: streamData, mutate: mutateStreamData } = useSWR<\n JSONValue[] | undefined\n >([completionId, 'streamData'], null);\n\n const [error, setError] = useState<undefined | Error>(undefined);\n const completion = data!;\n\n // Abort controller to cancel the current API call.\n const [abortController, setAbortController] =\n useState<AbortController | null>(null);\n\n const extraMetadataRef = useRef({\n credentials,\n headers,\n body,\n });\n useEffect(() => {\n extraMetadataRef.current = {\n credentials,\n headers,\n body,\n };\n }, [credentials, headers, body]);\n\n const triggerRequest = useCallback(\n async (prompt: string, options?: RequestOptions) =>\n callCompletionApi({\n api,\n prompt,\n credentials: extraMetadataRef.current.credentials,\n headers: { ...extraMetadataRef.current.headers, ...options?.headers },\n body: {\n ...extraMetadataRef.current.body,\n ...options?.body,\n },\n streamMode,\n fetch,\n setCompletion: completion => mutate(completion, false),\n setLoading: mutateLoading,\n setError,\n setAbortController,\n onResponse,\n onFinish,\n onError,\n onData: data => {\n mutateStreamData([...(streamData || []), ...(data || [])], false);\n },\n }),\n [\n mutate,\n mutateLoading,\n api,\n extraMetadataRef,\n setAbortController,\n onResponse,\n onFinish,\n onError,\n setError,\n streamData,\n streamMode,\n fetch,\n mutateStreamData,\n ],\n );\n\n const stop = useCallback(() => {\n if (abortController) {\n abortController.abort();\n setAbortController(null);\n }\n }, [abortController]);\n\n const setCompletion = useCallback(\n (completion: string) => {\n mutate(completion, false);\n },\n [mutate],\n );\n\n const complete = useCallback<UseCompletionHelpers['complete']>(\n async (prompt, options) => {\n return triggerRequest(prompt, options);\n },\n [triggerRequest],\n );\n\n const [input, setInput] = useState(initialInput);\n\n const handleSubmit = useCallback(\n (event?: { preventDefault?: () => void }) => {\n event?.preventDefault?.();\n return input ? complete(input) : undefined;\n },\n [input, complete],\n );\n\n const handleInputChange = (e: any) => {\n setInput(e.target.value);\n };\n\n return {\n completion,\n complete,\n error,\n setCompletion,\n stop,\n input,\n setInput,\n handleInputChange,\n handleSubmit,\n isLoading,\n data: streamData,\n };\n}\n","import { isAbortError } from '@ai-sdk/provider-utils';\nimport {\n DeepPartial,\n FetchFunction,\n isDeepEqualData,\n parsePartialJson,\n} from '@ai-sdk/ui-utils';\nimport { useCallback, useId, useRef, useState } from 'react';\nimport useSWR from 'swr';\nimport z from 'zod';\n\n// use function to allow for mocking in tests:\nconst getOriginalFetch = () => fetch;\n\nexport type Experimental_UseObjectOptions<RESULT> = {\n /**\n * The API endpoint. It should stream JSON that matches the schema as chunked text.\n */\n api: string;\n\n /**\n * A Zod schema that defines the shape of the complete object.\n */\n schema: z.Schema<RESULT>;\n\n /**\n * An unique identifier. If not provided, a random one will be\n * generated. When provided, the `useObject` hook with the same `id` will\n * have shared states across components.\n */\n id?: string;\n\n /**\n * An optional value for the initial object.\n */\n initialValue?: DeepPartial<RESULT>;\n\n /**\nCustom fetch implementation. You can use it as a middleware to intercept requests,\nor to provide a custom fetch implementation for e.g. testing.\n */\n fetch?: FetchFunction;\n\n /**\n * Callback function to be called when an error is encountered.\n */\n onError?: (error: Error) => void;\n};\n\nexport type Experimental_UseObjectHelpers<RESULT, INPUT> = {\n /**\n * @deprecated Use `submit` instead.\n */\n setInput: (input: INPUT) => void;\n\n /**\n * Calls the API with the provided input as JSON body.\n */\n submit: (input: INPUT) => void;\n\n /**\n * The current value for the generated object. Updated as the API streams JSON chunks.\n */\n object: DeepPartial<RESULT> | undefined;\n\n /**\n * The error object of the API request if any.\n */\n error: undefined | unknown;\n\n /**\n * Flag that indicates whether an API request is in progress.\n */\n isLoading: boolean;\n\n /**\n * Abort the current request immediately, keep the current partial object if any.\n */\n stop: () => void;\n};\n\nfunction useObject<RESULT, INPUT = any>({\n api,\n id,\n schema, // required, in the future we will use it for validation\n initialValue,\n fetch,\n onError,\n}: Experimental_UseObjectOptions<RESULT>): Experimental_UseObjectHelpers<\n RESULT,\n INPUT\n> {\n // Generate an unique id if not provided.\n const hookId = useId();\n const completionId = id ?? hookId;\n\n // Store the completion state in SWR, using the completionId as the key to share states.\n const { data, mutate } = useSWR<DeepPartial<RESULT>>(\n [api, completionId],\n null,\n { fallbackData: initialValue },\n );\n\n const [error, setError] = useState<undefined | unknown>(undefined);\n const [isLoading, setIsLoading] = useState(false);\n\n // Abort controller to cancel the current API call.\n const abortControllerRef = useRef<AbortController | null>(null);\n\n const stop = useCallback(() => {\n try {\n abortControllerRef.current?.abort();\n } catch (ignored) {\n } finally {\n setIsLoading(false);\n abortControllerRef.current = null;\n }\n }, []);\n\n const submit = async (input: INPUT) => {\n try {\n setIsLoading(true);\n setError(undefined);\n\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n\n const actualFetch = fetch ?? getOriginalFetch();\n const response = await actualFetch(api, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n signal: abortController.signal,\n body: JSON.stringify(input),\n });\n\n if (!response.ok) {\n throw new Error(\n (await response.text()) ?? 'Failed to fetch the response.',\n );\n }\n\n if (response.body == null) {\n throw new Error('The response body is empty.');\n }\n\n let accumulatedText = '';\n let latestObject: DeepPartial<RESULT> | undefined = undefined;\n\n await response.body.pipeThrough(new TextDecoderStream()).pipeTo(\n new WritableStream<string>({\n write(chunk) {\n accumulatedText += chunk;\n\n const currentObject = parsePartialJson(\n accumulatedText,\n ) as DeepPartial<RESULT>;\n\n if (!isDeepEqualData(latestObject, currentObject)) {\n latestObject = currentObject;\n\n mutate(currentObject);\n }\n },\n\n close() {\n setIsLoading(false);\n abortControllerRef.current = null;\n },\n }),\n );\n } catch (error) {\n if (isAbortError(error)) {\n return;\n }\n\n if (onError && error instanceof Error) {\n onError(error);\n }\n\n setError(error);\n }\n };\n\n return {\n setInput: submit, // Deprecated\n submit,\n object: data,\n error,\n isLoading,\n stop,\n };\n}\n\nexport const experimental_useObject = useObject;\n"],"mappings":"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","names":["fetch","messages","_a","error","useCallback","useRef","useState","generateId","fetch","messages","chatRequest","useCallback","useEffect","useId","useRef","useState","useSWR","fetch","completion","data","isAbortError","useCallback","useId","useRef","useState","useSWR","getOriginalFetch","fetch","error"]}
1
+ {"version":3,"sources":["../src/use-assistant.ts","../src/use-chat.ts","../src/use-completion.ts","../src/use-object.ts"],"sourcesContent":["import { isAbortError } from '@ai-sdk/provider-utils';\nimport {\n AssistantStatus,\n CreateMessage,\n Message,\n UseAssistantOptions,\n generateId,\n readDataStream,\n} from '@ai-sdk/ui-utils';\nimport { useCallback, useRef, useState } from 'react';\n\n// use function to allow for mocking in tests:\nconst getOriginalFetch = () => fetch;\n\nexport type UseAssistantHelpers = {\n /**\n * The current array of chat messages.\n */\n messages: Message[];\n\n /**\n * Update the message store with a new array of messages.\n */\n setMessages: React.Dispatch<React.SetStateAction<Message[]>>;\n\n /**\n * The current thread ID.\n */\n threadId: 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 /**\n * The current value of the input field.\n */\n input: 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 /**\nAbort the current request immediately, keep the generated tokens if any.\n */\n stop: () => void;\n\n /**\n * setState-powered method to update the input value.\n */\n setInput: React.Dispatch<React.SetStateAction<string>>;\n\n /**\n * Handler for the `onChange` event of the input field to control the input's value.\n */\n handleInputChange: (\n event:\n | React.ChangeEvent<HTMLInputElement>\n | React.ChangeEvent<HTMLTextAreaElement>,\n ) => void;\n\n /**\n * Form submission handler that automatically resets the input field and appends a user message.\n */\n submitMessage: (\n event?: React.FormEvent<HTMLFormElement>,\n requestOptions?: {\n data?: Record<string, string>;\n },\n ) => Promise<void>;\n\n /**\n * The current status of the assistant. This can be used to show a loading indicator.\n */\n status: AssistantStatus;\n\n /**\n * The error thrown during the assistant message processing, if any.\n */\n error: undefined | Error;\n};\n\nexport function useAssistant({\n api,\n threadId: threadIdParam,\n credentials,\n headers,\n body,\n onError,\n fetch,\n}: UseAssistantOptions): UseAssistantHelpers {\n const [messages, setMessages] = useState<Message[]>([]);\n const [input, setInput] = useState('');\n const [currentThreadId, setCurrentThreadId] = useState<string | undefined>(\n undefined,\n );\n const [status, setStatus] = useState<AssistantStatus>('awaiting_message');\n const [error, setError] = useState<undefined | Error>(undefined);\n\n const handleInputChange = (\n event:\n | React.ChangeEvent<HTMLInputElement>\n | React.ChangeEvent<HTMLTextAreaElement>,\n ) => {\n setInput(event.target.value);\n };\n\n // Abort controller to cancel the current API call.\n const abortControllerRef = useRef<AbortController | null>(null);\n\n const stop = useCallback(() => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n abortControllerRef.current = null;\n }\n }, []);\n\n const append = async (\n message: Message | CreateMessage,\n requestOptions?: {\n data?: Record<string, string>;\n },\n ) => {\n setStatus('in_progress');\n\n setMessages(messages => [\n ...messages,\n {\n ...message,\n id: message.id ?? generateId(),\n },\n ]);\n\n setInput('');\n\n const abortController = new AbortController();\n\n try {\n abortControllerRef.current = abortController;\n\n const actualFetch = fetch ?? getOriginalFetch();\n const response = await actualFetch(api, {\n method: 'POST',\n credentials,\n signal: abortController.signal,\n headers: { 'Content-Type': 'application/json', ...headers },\n body: JSON.stringify({\n ...body,\n // always use user-provided threadId when available:\n threadId: threadIdParam ?? currentThreadId ?? null,\n message: message.content,\n\n // optional request data:\n data: requestOptions?.data,\n }),\n });\n\n if (!response.ok) {\n throw new Error(\n (await response.text()) ?? 'Failed to fetch the assistant response.',\n );\n }\n\n if (response.body == null) {\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 setMessages(messages => [\n ...messages,\n {\n id: value.id,\n role: value.role,\n content: value.content[0].text.value,\n },\n ]);\n break;\n }\n\n case 'text': {\n // text delta - add to last message:\n setMessages(messages => {\n const lastMessage = messages[messages.length - 1];\n return [\n ...messages.slice(0, messages.length - 1),\n {\n id: lastMessage.id,\n role: lastMessage.role,\n content: lastMessage.content + value,\n },\n ];\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 'assistant_control_data': {\n setCurrentThreadId(value.threadId);\n\n // set id of last message:\n setMessages(messages => {\n const lastMessage = messages[messages.length - 1];\n lastMessage.id = value.messageId;\n return [...messages.slice(0, messages.length - 1), lastMessage];\n });\n\n break;\n }\n\n case 'error': {\n setError(new Error(value));\n break;\n }\n }\n }\n } catch (error) {\n // Ignore abort errors as they are expected when the user cancels the request:\n if (isAbortError(error) && abortController.signal.aborted) {\n abortControllerRef.current = null;\n return;\n }\n\n if (onError && error instanceof Error) {\n onError(error);\n }\n\n setError(error as Error);\n } finally {\n abortControllerRef.current = null;\n setStatus('awaiting_message');\n }\n };\n\n const submitMessage = async (\n event?: React.FormEvent<HTMLFormElement>,\n requestOptions?: {\n data?: Record<string, string>;\n },\n ) => {\n event?.preventDefault?.();\n\n if (input === '') {\n return;\n }\n\n append({ role: 'user', content: input }, requestOptions);\n };\n\n const setThreadId = (threadId: string | undefined) => {\n setCurrentThreadId(threadId);\n setMessages([]);\n };\n\n return {\n append,\n messages,\n setMessages,\n threadId: currentThreadId,\n setThreadId,\n input,\n setInput,\n handleInputChange,\n submitMessage,\n status,\n error,\n stop,\n };\n}\n\n/**\n@deprecated Use `useAssistant` instead.\n */\nexport const experimental_useAssistant = useAssistant;\n","import type {\n ChatRequest,\n ChatRequestOptions,\n CreateMessage,\n FetchFunction,\n IdGenerator,\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 { useCallback, useEffect, useId, useRef, useState } from 'react';\nimport useSWR, { KeyedMutator } from 'swr';\n\nexport type { CreateMessage, Message, UseChatOptions };\n\nexport type UseChatHelpers = {\n /** Current messages in the chat */\n messages: Message[];\n /** The error object of the API request */\n error: undefined | Error;\n /**\n * Append a user message to the chat list. This triggers the API call to fetch\n * the assistant's response.\n * @param message The message to append\n * @param options Additional options to pass to the API call\n */\n append: (\n message: Message | CreateMessage,\n chatRequestOptions?: ChatRequestOptions,\n ) => Promise<string | null | undefined>;\n /**\n * Reload the last AI chat response for the given chat history. If the last\n * message isn't from the assistant, it will request the API to generate a\n * new response.\n */\n reload: (\n chatRequestOptions?: ChatRequestOptions,\n ) => Promise<string | null | undefined>;\n /**\n * Abort the current request immediately, keep the generated tokens if any.\n */\n stop: () => void;\n /**\n * Update the `messages` state locally. This is useful when you want to\n * edit the messages on the client, and then trigger the `reload` method\n * manually to regenerate the AI response.\n */\n setMessages: (messages: Message[]) => void;\n /** The current value of the input */\n input: string;\n /** setState-powered method to update the input value */\n setInput: React.Dispatch<React.SetStateAction<string>>;\n /** An input/textarea-ready onChange handler to control the value of the input */\n handleInputChange: (\n e:\n | React.ChangeEvent<HTMLInputElement>\n | React.ChangeEvent<HTMLTextAreaElement>,\n ) => void;\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 metadata?: Object;\n /** Whether the API request is in progress */\n isLoading: boolean;\n /** Additional data added on the server via StreamData */\n data?: JSONValue[];\n};\n\nconst getStreamedResponse = async (\n api: string,\n chatRequest: ChatRequest,\n mutate: KeyedMutator<Message[]>,\n mutateStreamData: KeyedMutator<JSONValue[] | undefined>,\n existingData: JSONValue[] | undefined,\n extraMetadataRef: React.MutableRefObject<any>,\n messagesRef: React.MutableRefObject<Message[]>,\n abortControllerRef: React.MutableRefObject<AbortController | null>,\n generateId: IdGenerator,\n streamMode: 'stream-data' | 'text' | undefined,\n onFinish: ((message: Message) => void) | undefined,\n onResponse: ((response: Response) => void | Promise<void>) | undefined,\n onToolCall: UseChatOptions['onToolCall'] | undefined,\n sendExtraMessageFields: boolean | undefined,\n experimental_prepareRequestBody:\n | ((options: {\n messages: Message[];\n requestData?: JSONValue;\n requestBody?: object;\n }) => JSONValue)\n | undefined,\n fetch: FetchFunction | undefined,\n) => {\n // Do an optimistic update to the chat state to show the updated messages\n // immediately.\n const previousMessages = messagesRef.current;\n mutate(chatRequest.messages, false);\n\n const constructedMessagesPayload = sendExtraMessageFields\n ? chatRequest.messages\n : chatRequest.messages.map(\n ({\n role,\n content,\n name,\n data,\n annotations,\n toolInvocations,\n function_call,\n tool_calls,\n tool_call_id,\n }) => ({\n role,\n content,\n ...(name !== undefined && { name }),\n ...(data !== undefined && { data }),\n ...(annotations !== undefined && { annotations }),\n ...(toolInvocations !== undefined && { toolInvocations }),\n // outdated function/tool call handling (TODO deprecate):\n tool_call_id,\n ...(function_call !== undefined && { function_call }),\n ...(tool_calls !== undefined && { tool_calls }),\n }),\n );\n\n return await callChatApi({\n api,\n body: experimental_prepareRequestBody?.({\n messages: chatRequest.messages,\n requestData: chatRequest.data,\n requestBody: chatRequest.body,\n }) ?? {\n messages: constructedMessagesPayload,\n data: chatRequest.data,\n ...extraMetadataRef.current.body,\n ...chatRequest.body,\n ...(chatRequest.functions !== undefined && {\n functions: chatRequest.functions,\n }),\n ...(chatRequest.function_call !== undefined && {\n function_call: chatRequest.function_call,\n }),\n ...(chatRequest.tools !== undefined && {\n tools: chatRequest.tools,\n }),\n ...(chatRequest.tool_choice !== undefined && {\n tool_choice: chatRequest.tool_choice,\n }),\n },\n streamMode,\n credentials: extraMetadataRef.current.credentials,\n headers: {\n ...extraMetadataRef.current.headers,\n ...chatRequest.headers,\n },\n abortController: () => abortControllerRef.current,\n restoreMessagesOnFailure() {\n mutate(previousMessages, false);\n },\n onResponse,\n onUpdate(merged, data) {\n mutate([...chatRequest.messages, ...merged], false);\n mutateStreamData([...(existingData || []), ...(data || [])], false);\n },\n onToolCall,\n onFinish,\n generateId,\n fetch,\n });\n};\n\nexport function useChat({\n api = '/api/chat',\n id,\n initialMessages,\n initialInput = '',\n sendExtraMessageFields,\n experimental_onFunctionCall,\n experimental_onToolCall,\n onToolCall,\n experimental_prepareRequestBody,\n experimental_maxAutomaticRoundtrips = 0,\n maxAutomaticRoundtrips = experimental_maxAutomaticRoundtrips,\n maxToolRoundtrips = maxAutomaticRoundtrips,\n streamMode,\n onResponse,\n onFinish,\n onError,\n credentials,\n headers,\n body,\n generateId = generateIdFunc,\n fetch,\n}: UseChatOptions & {\n key?: string;\n\n /**\n@deprecated Use `maxToolRoundtrips` instead.\n */\n experimental_maxAutomaticRoundtrips?: number;\n\n /**\n@deprecated Use `maxToolRoundtrips` instead.\n */\n maxAutomaticRoundtrips?: number;\n\n /**\n * Experimental (React only). When a function is provided, it will be used\n * to prepare the request body for the chat API. This can be useful for\n * customizing the request body based on the messages and data in the chat.\n *\n * @param messages The current messages in the chat.\n * @param requestData The data object passed in the chat request.\n * @param requestBody The request body object passed in the chat request.\n */\n experimental_prepareRequestBody?: (options: {\n messages: Message[];\n requestData?: JSONValue;\n requestBody?: object;\n }) => JSONValue;\n\n /**\nMaximal number of automatic roundtrips for tool calls.\n\nAn automatic tool call roundtrip is a call to the server with the \ntool call results when all tool calls in the last assistant \nmessage have results.\n\nA maximum number is required to prevent infinite loops in the\ncase of misconfigured tools.\n\nBy default, it's set to 0, which will disable the feature.\n */\n maxToolRoundtrips?: number;\n} = {}): UseChatHelpers & {\n /**\n * @deprecated Use `addToolResult` instead.\n */\n experimental_addToolResult: ({\n toolCallId,\n result,\n }: {\n toolCallId: string;\n result: any;\n }) => void;\n addToolResult: ({\n toolCallId,\n result,\n }: {\n toolCallId: string;\n result: any;\n }) => void;\n} {\n // Generate a unique id for the chat if not provided.\n const hookId = useId();\n const idKey = id ?? hookId;\n const chatKey = typeof api === 'string' ? [api, idKey] : idKey;\n\n // Store a empty array as the initial messages\n // (instead of using a default parameter value that gets re-created each time)\n // to avoid re-renders:\n const [initialMessagesFallback] = useState([]);\n\n // Store the chat state in SWR, using the chatId as the key to share states.\n const { data: messages, mutate } = useSWR<Message[]>(\n [chatKey, 'messages'],\n null,\n { fallbackData: initialMessages ?? initialMessagesFallback },\n );\n\n // We store loading state in another hook to sync loading states across hook invocations\n const { data: isLoading = false, mutate: mutateLoading } = useSWR<boolean>(\n [chatKey, 'loading'],\n null,\n );\n\n const { data: streamData, mutate: mutateStreamData } = useSWR<\n JSONValue[] | undefined\n >([chatKey, 'streamData'], null);\n\n const { data: error = undefined, mutate: setError } = useSWR<\n undefined | Error\n >([chatKey, 'error'], null);\n\n // Keep the latest messages in a ref.\n const messagesRef = useRef<Message[]>(messages || []);\n useEffect(() => {\n messagesRef.current = messages || [];\n }, [messages]);\n\n // Abort controller to cancel the current API call.\n const abortControllerRef = useRef<AbortController | null>(null);\n\n const extraMetadataRef = useRef({\n credentials,\n headers,\n body,\n });\n\n useEffect(() => {\n extraMetadataRef.current = {\n credentials,\n headers,\n body,\n };\n }, [credentials, headers, body]);\n\n const triggerRequest = useCallback(\n async (chatRequest: ChatRequest) => {\n const messageCount = messagesRef.current.length;\n\n try {\n mutateLoading(true);\n setError(undefined);\n\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n\n await processChatStream({\n getStreamedResponse: () =>\n getStreamedResponse(\n api,\n chatRequest,\n mutate,\n mutateStreamData,\n streamData!,\n extraMetadataRef,\n messagesRef,\n abortControllerRef,\n generateId,\n streamMode,\n onFinish,\n onResponse,\n onToolCall,\n sendExtraMessageFields,\n experimental_prepareRequestBody,\n fetch,\n ),\n experimental_onFunctionCall,\n experimental_onToolCall,\n updateChatRequest: chatRequestParam => {\n chatRequest = chatRequestParam;\n },\n getCurrentMessages: () => messagesRef.current,\n });\n\n abortControllerRef.current = null;\n } catch (err) {\n // Ignore abort errors as they are expected.\n if ((err as any).name === 'AbortError') {\n abortControllerRef.current = null;\n return null;\n }\n\n if (onError && err instanceof Error) {\n onError(err);\n }\n\n setError(err as Error);\n } finally {\n mutateLoading(false);\n }\n\n // auto-submit when all tool calls in the last assistant message have results:\n const messages = messagesRef.current;\n const lastMessage = messages[messages.length - 1];\n if (\n // ensure we actually have new messages (to prevent infinite loops in case of errors):\n messages.length > messageCount &&\n // ensure there is a last message:\n lastMessage != null &&\n // check if the feature is enabled:\n maxToolRoundtrips > 0 &&\n // check that roundtrip is possible:\n isAssistantMessageWithCompletedToolCalls(lastMessage) &&\n // limit the number of automatic roundtrips:\n countTrailingAssistantMessages(messages) <= maxToolRoundtrips\n ) {\n await triggerRequest({ messages });\n }\n },\n [\n mutate,\n mutateLoading,\n api,\n extraMetadataRef,\n onResponse,\n onFinish,\n onError,\n setError,\n mutateStreamData,\n streamData,\n streamMode,\n sendExtraMessageFields,\n experimental_onFunctionCall,\n experimental_onToolCall,\n experimental_prepareRequestBody,\n onToolCall,\n maxToolRoundtrips,\n messagesRef,\n abortControllerRef,\n generateId,\n fetch,\n ],\n );\n\n const append = useCallback(\n async (\n message: Message | CreateMessage,\n {\n options,\n functions,\n function_call,\n tools,\n tool_choice,\n data,\n headers,\n body,\n }: ChatRequestOptions = {},\n ) => {\n if (!message.id) {\n message.id = generateId();\n }\n\n const requestOptions = {\n headers: headers ?? options?.headers,\n body: body ?? options?.body,\n };\n\n const chatRequest: ChatRequest = {\n messages: messagesRef.current.concat(message as Message),\n options: requestOptions,\n headers: requestOptions.headers,\n body: requestOptions.body,\n data,\n ...(functions !== undefined && { functions }),\n ...(function_call !== undefined && { function_call }),\n ...(tools !== undefined && { tools }),\n ...(tool_choice !== undefined && { tool_choice }),\n };\n\n return triggerRequest(chatRequest);\n },\n [triggerRequest, generateId],\n );\n\n const reload = useCallback(\n async ({\n options,\n functions,\n function_call,\n tools,\n tool_choice,\n }: ChatRequestOptions = {}) => {\n if (messagesRef.current.length === 0) return null;\n\n // Remove last assistant message and retry last user message.\n const lastMessage = messagesRef.current[messagesRef.current.length - 1];\n if (lastMessage.role === 'assistant') {\n const chatRequest: ChatRequest = {\n messages: messagesRef.current.slice(0, -1),\n options,\n ...(functions !== undefined && { functions }),\n ...(function_call !== undefined && { function_call }),\n ...(tools !== undefined && { tools }),\n ...(tool_choice !== undefined && { tool_choice }),\n };\n\n return triggerRequest(chatRequest);\n }\n\n const chatRequest: ChatRequest = {\n messages: messagesRef.current,\n options,\n ...(functions !== undefined && { functions }),\n ...(function_call !== undefined && { function_call }),\n ...(tools !== undefined && { tools }),\n ...(tool_choice !== undefined && { tool_choice }),\n };\n\n return triggerRequest(chatRequest);\n },\n [triggerRequest],\n );\n\n const stop = useCallback(() => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n abortControllerRef.current = null;\n }\n }, []);\n\n const setMessages = useCallback(\n (messages: Message[]) => {\n mutate(messages, false);\n messagesRef.current = messages;\n },\n [mutate],\n );\n\n // Input state and handlers.\n const [input, setInput] = useState(initialInput);\n\n const handleSubmit = useCallback(\n (\n event?: { preventDefault?: () => void },\n options: ChatRequestOptions = {},\n metadata?: Object,\n ) => {\n if (metadata) {\n extraMetadataRef.current = {\n ...extraMetadataRef.current,\n ...metadata,\n };\n }\n\n event?.preventDefault?.();\n\n const requestOptions = {\n headers: options.headers ?? options.options?.headers,\n body: options.body ?? options.options?.body,\n };\n\n const chatRequest: ChatRequest = {\n messages: input\n ? messagesRef.current.concat({\n id: generateId(),\n role: 'user',\n content: input,\n })\n : messagesRef.current,\n options: requestOptions,\n headers: requestOptions.headers,\n body: requestOptions.body,\n data: options.data,\n };\n\n triggerRequest(chatRequest);\n\n setInput('');\n },\n [input, generateId, triggerRequest],\n );\n\n const handleInputChange = (e: any) => {\n setInput(e.target.value);\n };\n\n const addToolResult = ({\n toolCallId,\n result,\n }: {\n toolCallId: string;\n result: any;\n }) => {\n const updatedMessages = messagesRef.current.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 ? { ...toolInvocation, result }\n : toolInvocation,\n ),\n }\n : message,\n );\n\n mutate(updatedMessages, false);\n\n // auto-submit when all tool calls in the last assistant message have results:\n const lastMessage = updatedMessages[updatedMessages.length - 1];\n if (isAssistantMessageWithCompletedToolCalls(lastMessage)) {\n triggerRequest({ messages: updatedMessages });\n }\n };\n\n return {\n messages: messages || [],\n error,\n append,\n reload,\n stop,\n setMessages,\n input,\n setInput,\n handleInputChange,\n handleSubmit,\n isLoading,\n data: streamData,\n addToolResult,\n experimental_addToolResult: 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 {\n JSONValue,\n RequestOptions,\n UseCompletionOptions,\n callCompletionApi,\n} from '@ai-sdk/ui-utils';\nimport { useCallback, useEffect, useId, useRef, useState } from 'react';\nimport useSWR from 'swr';\n\nexport type { UseCompletionOptions };\n\nexport type UseCompletionHelpers = {\n /** The current completion result */\n completion: string;\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 /** The error object of the API request */\n error: undefined | Error;\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: string;\n /** setState-powered method to update the input value */\n setInput: React.Dispatch<React.SetStateAction<string>>;\n /**\n * An input/textarea-ready onChange handler to control the value of the input\n * @example\n * ```jsx\n * <input onChange={handleInputChange} value={input} />\n * ```\n */\n handleInputChange: (\n event:\n | React.ChangeEvent<HTMLInputElement>\n | React.ChangeEvent<HTMLTextAreaElement>,\n ) => void;\n\n /**\n * Form submission handler to automatically reset input and append a user message\n * @example\n * ```jsx\n * <form onSubmit={handleSubmit}>\n * <input onChange={handleInputChange} value={input} />\n * </form>\n * ```\n */\n handleSubmit: (event?: { preventDefault?: () => void }) => void;\n\n /** Whether the API request is in progress */\n isLoading: boolean;\n /** Additional data added on the server via StreamData */\n data?: JSONValue[];\n};\n\nexport function useCompletion({\n api = '/api/completion',\n id,\n initialCompletion = '',\n initialInput = '',\n credentials,\n headers,\n body,\n streamMode,\n fetch,\n onResponse,\n onFinish,\n onError,\n}: UseCompletionOptions = {}): UseCompletionHelpers {\n // Generate an unique id for the completion if not provided.\n const hookId = useId();\n const completionId = id || hookId;\n\n // Store the completion state in SWR, using the completionId as the key to share states.\n const { data, mutate } = useSWR<string>([api, completionId], null, {\n fallbackData: initialCompletion,\n });\n\n const { data: isLoading = false, mutate: mutateLoading } = useSWR<boolean>(\n [completionId, 'loading'],\n null,\n );\n\n const { data: streamData, mutate: mutateStreamData } = useSWR<\n JSONValue[] | undefined\n >([completionId, 'streamData'], null);\n\n const [error, setError] = useState<undefined | Error>(undefined);\n const completion = data!;\n\n // Abort controller to cancel the current API call.\n const [abortController, setAbortController] =\n useState<AbortController | null>(null);\n\n const extraMetadataRef = useRef({\n credentials,\n headers,\n body,\n });\n useEffect(() => {\n extraMetadataRef.current = {\n credentials,\n headers,\n body,\n };\n }, [credentials, headers, body]);\n\n const triggerRequest = useCallback(\n async (prompt: string, options?: RequestOptions) =>\n callCompletionApi({\n api,\n prompt,\n credentials: extraMetadataRef.current.credentials,\n headers: { ...extraMetadataRef.current.headers, ...options?.headers },\n body: {\n ...extraMetadataRef.current.body,\n ...options?.body,\n },\n streamMode,\n fetch,\n setCompletion: completion => mutate(completion, false),\n setLoading: mutateLoading,\n setError,\n setAbortController,\n onResponse,\n onFinish,\n onError,\n onData: data => {\n mutateStreamData([...(streamData || []), ...(data || [])], false);\n },\n }),\n [\n mutate,\n mutateLoading,\n api,\n extraMetadataRef,\n setAbortController,\n onResponse,\n onFinish,\n onError,\n setError,\n streamData,\n streamMode,\n fetch,\n mutateStreamData,\n ],\n );\n\n const stop = useCallback(() => {\n if (abortController) {\n abortController.abort();\n setAbortController(null);\n }\n }, [abortController]);\n\n const setCompletion = useCallback(\n (completion: string) => {\n mutate(completion, false);\n },\n [mutate],\n );\n\n const complete = useCallback<UseCompletionHelpers['complete']>(\n async (prompt, options) => {\n return triggerRequest(prompt, options);\n },\n [triggerRequest],\n );\n\n const [input, setInput] = useState(initialInput);\n\n const handleSubmit = useCallback(\n (event?: { preventDefault?: () => void }) => {\n event?.preventDefault?.();\n return input ? complete(input) : undefined;\n },\n [input, complete],\n );\n\n const handleInputChange = (e: any) => {\n setInput(e.target.value);\n };\n\n return {\n completion,\n complete,\n error,\n setCompletion,\n stop,\n input,\n setInput,\n handleInputChange,\n handleSubmit,\n isLoading,\n data: streamData,\n };\n}\n","import { isAbortError } from '@ai-sdk/provider-utils';\nimport {\n DeepPartial,\n FetchFunction,\n isDeepEqualData,\n parsePartialJson,\n} from '@ai-sdk/ui-utils';\nimport { useCallback, useId, useRef, useState } from 'react';\nimport useSWR from 'swr';\nimport z from 'zod';\n\n// use function to allow for mocking in tests:\nconst getOriginalFetch = () => fetch;\n\nexport type Experimental_UseObjectOptions<RESULT> = {\n /**\n * The API endpoint. It should stream JSON that matches the schema as chunked text.\n */\n api: string;\n\n /**\n * A Zod schema that defines the shape of the complete object.\n */\n schema: z.Schema<RESULT>;\n\n /**\n * An unique identifier. If not provided, a random one will be\n * generated. When provided, the `useObject` hook with the same `id` will\n * have shared states across components.\n */\n id?: string;\n\n /**\n * An optional value for the initial object.\n */\n initialValue?: DeepPartial<RESULT>;\n\n /**\nCustom fetch implementation. You can use it as a middleware to intercept requests,\nor to provide a custom fetch implementation for e.g. testing.\n */\n fetch?: FetchFunction;\n\n /**\n * Callback function to be called when an error is encountered.\n */\n onError?: (error: Error) => void;\n};\n\nexport type Experimental_UseObjectHelpers<RESULT, INPUT> = {\n /**\n * @deprecated Use `submit` instead.\n */\n setInput: (input: INPUT) => void;\n\n /**\n * Calls the API with the provided input as JSON body.\n */\n submit: (input: INPUT) => void;\n\n /**\n * The current value for the generated object. Updated as the API streams JSON chunks.\n */\n object: DeepPartial<RESULT> | undefined;\n\n /**\n * The error object of the API request if any.\n */\n error: undefined | unknown;\n\n /**\n * Flag that indicates whether an API request is in progress.\n */\n isLoading: boolean;\n\n /**\n * Abort the current request immediately, keep the current partial object if any.\n */\n stop: () => void;\n};\n\nfunction useObject<RESULT, INPUT = any>({\n api,\n id,\n schema, // required, in the future we will use it for validation\n initialValue,\n fetch,\n onError,\n}: Experimental_UseObjectOptions<RESULT>): Experimental_UseObjectHelpers<\n RESULT,\n INPUT\n> {\n // Generate an unique id if not provided.\n const hookId = useId();\n const completionId = id ?? hookId;\n\n // Store the completion state in SWR, using the completionId as the key to share states.\n const { data, mutate } = useSWR<DeepPartial<RESULT>>(\n [api, completionId],\n null,\n { fallbackData: initialValue },\n );\n\n const [error, setError] = useState<undefined | unknown>(undefined);\n const [isLoading, setIsLoading] = useState(false);\n\n // Abort controller to cancel the current API call.\n const abortControllerRef = useRef<AbortController | null>(null);\n\n const stop = useCallback(() => {\n try {\n abortControllerRef.current?.abort();\n } catch (ignored) {\n } finally {\n setIsLoading(false);\n abortControllerRef.current = null;\n }\n }, []);\n\n const submit = async (input: INPUT) => {\n try {\n setIsLoading(true);\n setError(undefined);\n\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n\n const actualFetch = fetch ?? getOriginalFetch();\n const response = await actualFetch(api, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n signal: abortController.signal,\n body: JSON.stringify(input),\n });\n\n if (!response.ok) {\n throw new Error(\n (await response.text()) ?? 'Failed to fetch the response.',\n );\n }\n\n if (response.body == null) {\n throw new Error('The response body is empty.');\n }\n\n let accumulatedText = '';\n let latestObject: DeepPartial<RESULT> | undefined = undefined;\n\n await response.body.pipeThrough(new TextDecoderStream()).pipeTo(\n new WritableStream<string>({\n write(chunk) {\n accumulatedText += chunk;\n\n const currentObject = parsePartialJson(\n accumulatedText,\n ) as DeepPartial<RESULT>;\n\n if (!isDeepEqualData(latestObject, currentObject)) {\n latestObject = currentObject;\n\n mutate(currentObject);\n }\n },\n\n close() {\n setIsLoading(false);\n abortControllerRef.current = null;\n },\n }),\n );\n } catch (error) {\n if (isAbortError(error)) {\n return;\n }\n\n if (onError && error instanceof Error) {\n onError(error);\n }\n\n setError(error);\n }\n };\n\n return {\n setInput: submit, // Deprecated\n submit,\n object: data,\n error,\n isLoading,\n stop,\n };\n}\n\nexport const experimental_useObject = useObject;\n"],"mappings":"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","names":["fetch","messages","_a","error","useCallback","useRef","useState","generateId","fetch","messages","headers","body","chatRequest","useCallback","useEffect","useId","useRef","useState","useSWR","fetch","completion","data","isAbortError","useCallback","useId","useRef","useState","useSWR","getOriginalFetch","fetch","error"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/react",
3
- "version": "0.0.19",
3
+ "version": "0.0.20",
4
4
  "license": "Apache-2.0",
5
5
  "sideEffects": false,
6
6
  "main": "./dist/index.js",
@@ -16,7 +16,7 @@
16
16
  },
17
17
  "dependencies": {
18
18
  "@ai-sdk/provider-utils": "1.0.2",
19
- "@ai-sdk/ui-utils": "0.0.11",
19
+ "@ai-sdk/ui-utils": "0.0.12",
20
20
  "swr": "2.2.0"
21
21
  },
22
22
  "devDependencies": {
package/src/use-chat.ts CHANGED
@@ -134,12 +134,12 @@ const getStreamedResponse = async (
134
134
  body: experimental_prepareRequestBody?.({
135
135
  messages: chatRequest.messages,
136
136
  requestData: chatRequest.data,
137
- requestBody: chatRequest.options?.body,
137
+ requestBody: chatRequest.body,
138
138
  }) ?? {
139
139
  messages: constructedMessagesPayload,
140
140
  data: chatRequest.data,
141
141
  ...extraMetadataRef.current.body,
142
- ...chatRequest.options?.body,
142
+ ...chatRequest.body,
143
143
  ...(chatRequest.functions !== undefined && {
144
144
  functions: chatRequest.functions,
145
145
  }),
@@ -157,7 +157,7 @@ const getStreamedResponse = async (
157
157
  credentials: extraMetadataRef.current.credentials,
158
158
  headers: {
159
159
  ...extraMetadataRef.current.headers,
160
- ...chatRequest.options?.headers,
160
+ ...chatRequest.headers,
161
161
  },
162
162
  abortController: () => abortControllerRef.current,
163
163
  restoreMessagesOnFailure() {
@@ -420,15 +420,24 @@ By default, it's set to 0, which will disable the feature.
420
420
  tools,
421
421
  tool_choice,
422
422
  data,
423
+ headers,
424
+ body,
423
425
  }: ChatRequestOptions = {},
424
426
  ) => {
425
427
  if (!message.id) {
426
428
  message.id = generateId();
427
429
  }
428
430
 
431
+ const requestOptions = {
432
+ headers: headers ?? options?.headers,
433
+ body: body ?? options?.body,
434
+ };
435
+
429
436
  const chatRequest: ChatRequest = {
430
437
  messages: messagesRef.current.concat(message as Message),
431
- options,
438
+ options: requestOptions,
439
+ headers: requestOptions.headers,
440
+ body: requestOptions.body,
432
441
  data,
433
442
  ...(functions !== undefined && { functions }),
434
443
  ...(function_call !== undefined && { function_call }),
@@ -513,6 +522,11 @@ By default, it's set to 0, which will disable the feature.
513
522
 
514
523
  event?.preventDefault?.();
515
524
 
525
+ const requestOptions = {
526
+ headers: options.headers ?? options.options?.headers,
527
+ body: options.body ?? options.options?.body,
528
+ };
529
+
516
530
  const chatRequest: ChatRequest = {
517
531
  messages: input
518
532
  ? messagesRef.current.concat({
@@ -521,7 +535,9 @@ By default, it's set to 0, which will disable the feature.
521
535
  content: input,
522
536
  })
523
537
  : messagesRef.current,
524
- options: options.options,
538
+ options: requestOptions,
539
+ headers: requestOptions.headers,
540
+ body: requestOptions.body,
525
541
  data: options.data,
526
542
  };
527
543
 
@@ -227,12 +227,12 @@ describe('form actions', () => {
227
227
  </div>
228
228
  ))}
229
229
 
230
- <form onSubmit={handleSubmit} className="fixed bottom-0 p-2 w-full">
230
+ <form onSubmit={handleSubmit} className="fixed bottom-0 w-full p-2">
231
231
  <input
232
232
  value={input}
233
233
  placeholder="Send message..."
234
234
  onChange={handleInputChange}
235
- className="bg-zinc-100 w-full p-2"
235
+ className="w-full p-2 bg-zinc-100"
236
236
  disabled={isLoading}
237
237
  data-testid="do-input"
238
238
  />
@@ -311,9 +311,7 @@ describe('prepareRequestBody', () => {
311
311
  { role: 'user', content: 'hi' },
312
312
  {
313
313
  data: { 'test-data-key': 'test-data-value' },
314
- options: {
315
- body: { 'request-body-key': 'request-body-value' },
316
- },
314
+ body: { 'request-body-key': 'request-body-value' },
317
315
  },
318
316
  );
319
317
  }}