@ai-sdk/react 2.0.0-canary.2 → 2.0.0-canary.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -37,7 +37,7 @@ __export(src_exports, {
37
37
  module.exports = __toCommonJS(src_exports);
38
38
 
39
39
  // src/use-chat.ts
40
- var import_ui_utils2 = require("@ai-sdk/ui-utils");
40
+ var import_ai2 = require("ai");
41
41
  var import_react2 = require("react");
42
42
  var import_swr = __toESM(require("swr"));
43
43
 
@@ -48,12 +48,12 @@ function throttle(fn, waitMs) {
48
48
  }
49
49
 
50
50
  // src/util/use-stable-value.ts
51
- var import_ui_utils = require("@ai-sdk/ui-utils");
51
+ var import_ai = require("ai");
52
52
  var import_react = require("react");
53
53
  function useStableValue(latestValue) {
54
54
  const [value, setValue] = (0, import_react.useState)(latestValue);
55
55
  (0, import_react.useEffect)(() => {
56
- if (!(0, import_ui_utils.isDeepEqualData)(latestValue, value)) {
56
+ if (!(0, import_ai.isDeepEqualData)(latestValue, value)) {
57
57
  setValue(latestValue);
58
58
  }
59
59
  }, [latestValue, value]);
@@ -66,28 +66,26 @@ function useChat({
66
66
  id,
67
67
  initialMessages,
68
68
  initialInput = "",
69
- sendExtraMessageFields,
70
69
  onToolCall,
71
70
  experimental_prepareRequestBody,
72
71
  maxSteps = 1,
73
- streamProtocol = "data",
74
- onResponse,
72
+ streamProtocol = "ui-message",
75
73
  onFinish,
76
74
  onError,
77
75
  credentials,
78
76
  headers,
79
77
  body,
80
- generateId = import_ui_utils2.generateId,
78
+ generateId = import_ai2.generateId,
81
79
  fetch: fetch2,
82
- keepLastMessageOnError = true,
83
- experimental_throttle: throttleWaitMs
80
+ experimental_throttle: throttleWaitMs,
81
+ messageMetadataSchema
84
82
  } = {}) {
85
83
  const [hookId] = (0, import_react2.useState)(generateId);
86
84
  const chatId = id != null ? id : hookId;
87
85
  const chatKey = typeof api === "string" ? [api, chatId] : chatId;
88
86
  const stableInitialMessages = useStableValue(initialMessages != null ? initialMessages : []);
89
87
  const processedInitialMessages = (0, import_react2.useMemo)(
90
- () => (0, import_ui_utils2.fillMessageParts)(stableInitialMessages),
88
+ () => stableInitialMessages,
91
89
  [stableInitialMessages]
92
90
  );
93
91
  const { data: messages, mutate } = (0, import_swr.default)(
@@ -99,11 +97,6 @@ function useChat({
99
97
  (0, import_react2.useEffect)(() => {
100
98
  messagesRef.current = messages || [];
101
99
  }, [messages]);
102
- const { data: streamData, mutate: mutateStreamData } = (0, import_swr.default)([chatKey, "streamData"], null);
103
- const streamDataRef = (0, import_react2.useRef)(streamData);
104
- (0, import_react2.useEffect)(() => {
105
- streamDataRef.current = streamData;
106
- }, [streamData]);
107
100
  const { data: status = "ready", mutate: mutateStatus } = (0, import_swr.default)([chatKey, "status"], null);
108
101
  const { data: error = void 0, mutate: setError } = (0, import_swr.default)([chatKey, "error"], null);
109
102
  const abortControllerRef = (0, import_react2.useRef)(null);
@@ -120,58 +113,29 @@ function useChat({
120
113
  };
121
114
  }, [credentials, headers, body]);
122
115
  const triggerRequest = (0, import_react2.useCallback)(
123
- async (chatRequest) => {
124
- var _a, _b;
116
+ async (chatRequest, requestType = "generate") => {
117
+ var _a;
125
118
  mutateStatus("submitted");
126
119
  setError(void 0);
127
- const chatMessages = (0, import_ui_utils2.fillMessageParts)(chatRequest.messages);
120
+ const chatMessages = chatRequest.messages;
128
121
  const messageCount = chatMessages.length;
129
- const maxStep = (0, import_ui_utils2.extractMaxToolInvocationStep)(
130
- (_a = chatMessages[chatMessages.length - 1]) == null ? void 0 : _a.toolInvocations
122
+ const maxStep = (0, import_ai2.extractMaxToolInvocationStep)(
123
+ (0, import_ai2.getToolInvocations)(chatMessages[chatMessages.length - 1])
131
124
  );
132
125
  try {
133
126
  const abortController = new AbortController();
134
127
  abortControllerRef.current = abortController;
135
128
  const throttledMutate = throttle(mutate, throttleWaitMs);
136
- const throttledMutateStreamData = throttle(
137
- mutateStreamData,
138
- throttleWaitMs
139
- );
140
- const previousMessages = messagesRef.current;
141
129
  throttledMutate(chatMessages, false);
142
- const constructedMessagesPayload = sendExtraMessageFields ? chatMessages : chatMessages.map(
143
- ({
144
- role,
145
- content,
146
- experimental_attachments,
147
- data,
148
- annotations,
149
- toolInvocations,
150
- parts
151
- }) => ({
152
- role,
153
- content,
154
- ...experimental_attachments !== void 0 && {
155
- experimental_attachments
156
- },
157
- ...data !== void 0 && { data },
158
- ...annotations !== void 0 && { annotations },
159
- ...toolInvocations !== void 0 && { toolInvocations },
160
- ...parts !== void 0 && { parts }
161
- })
162
- );
163
- const existingData = streamDataRef.current;
164
- await (0, import_ui_utils2.callChatApi)({
130
+ await (0, import_ai2.callChatApi)({
165
131
  api,
166
- body: (_b = experimental_prepareRequestBody == null ? void 0 : experimental_prepareRequestBody({
132
+ body: (_a = experimental_prepareRequestBody == null ? void 0 : experimental_prepareRequestBody({
167
133
  id: chatId,
168
134
  messages: chatMessages,
169
- requestData: chatRequest.data,
170
135
  requestBody: chatRequest.body
171
- })) != null ? _b : {
136
+ })) != null ? _a : {
172
137
  id: chatId,
173
- messages: constructedMessagesPayload,
174
- data: chatRequest.data,
138
+ messages: chatMessages,
175
139
  ...extraMetadataRef.current.body,
176
140
  ...chatRequest.body
177
141
  },
@@ -182,14 +146,9 @@ function useChat({
182
146
  ...chatRequest.headers
183
147
  },
184
148
  abortController: () => abortControllerRef.current,
185
- restoreMessagesOnFailure() {
186
- if (!keepLastMessageOnError) {
187
- throttledMutate(previousMessages, false);
188
- }
189
- },
190
- onResponse,
191
- onUpdate({ message, data, replaceLastMessage }) {
149
+ onUpdate({ message }) {
192
150
  mutateStatus("streaming");
151
+ const replaceLastMessage = message.id === chatMessages[chatMessages.length - 1].id;
193
152
  throttledMutate(
194
153
  [
195
154
  ...replaceLastMessage ? chatMessages.slice(0, chatMessages.length - 1) : chatMessages,
@@ -197,18 +156,14 @@ function useChat({
197
156
  ],
198
157
  false
199
158
  );
200
- if (data == null ? void 0 : data.length) {
201
- throttledMutateStreamData(
202
- [...existingData != null ? existingData : [], ...data],
203
- false
204
- );
205
- }
206
159
  },
207
160
  onToolCall,
208
161
  onFinish,
209
162
  generateId,
210
163
  fetch: fetch2,
211
- lastMessage: chatMessages[chatMessages.length - 1]
164
+ lastMessage: chatMessages[chatMessages.length - 1],
165
+ requestType,
166
+ messageMetadataSchema
212
167
  });
213
168
  abortControllerRef.current = null;
214
169
  mutateStatus("ready");
@@ -225,7 +180,7 @@ function useChat({
225
180
  mutateStatus("error");
226
181
  }
227
182
  const messages2 = messagesRef.current;
228
- if ((0, import_ui_utils2.shouldResubmitMessages)({
183
+ if ((0, import_ai2.shouldResubmitMessages)({
229
184
  originalMaxToolInvocationStep: maxStep,
230
185
  originalMessageCount: messageCount,
231
186
  maxSteps,
@@ -239,14 +194,10 @@ function useChat({
239
194
  mutateStatus,
240
195
  api,
241
196
  extraMetadataRef,
242
- onResponse,
243
197
  onFinish,
244
198
  onError,
245
199
  setError,
246
- mutateStreamData,
247
- streamDataRef,
248
200
  streamProtocol,
249
- sendExtraMessageFields,
250
201
  experimental_prepareRequestBody,
251
202
  onToolCall,
252
203
  maxSteps,
@@ -254,35 +205,27 @@ function useChat({
254
205
  abortControllerRef,
255
206
  generateId,
256
207
  fetch2,
257
- keepLastMessageOnError,
258
208
  throttleWaitMs,
259
- chatId
209
+ chatId,
210
+ messageMetadataSchema
260
211
  ]
261
212
  );
262
213
  const append = (0, import_react2.useCallback)(
263
- async (message, {
264
- data,
265
- headers: headers2,
266
- body: body2,
267
- experimental_attachments
268
- } = {}) => {
269
- var _a, _b;
270
- const attachmentsForRequest = await (0, import_ui_utils2.prepareAttachmentsForRequest)(
271
- experimental_attachments
272
- );
273
- const messages2 = messagesRef.current.concat({
274
- ...message,
275
- id: (_a = message.id) != null ? _a : generateId(),
276
- createdAt: (_b = message.createdAt) != null ? _b : /* @__PURE__ */ new Date(),
277
- experimental_attachments: attachmentsForRequest.length > 0 ? attachmentsForRequest : void 0,
278
- parts: (0, import_ui_utils2.getMessageParts)(message)
214
+ async (message, { headers: headers2, body: body2 } = {}) => {
215
+ var _a;
216
+ await triggerRequest({
217
+ messages: messagesRef.current.concat({
218
+ ...message,
219
+ id: (_a = message.id) != null ? _a : generateId()
220
+ }),
221
+ headers: headers2,
222
+ body: body2
279
223
  });
280
- return triggerRequest({ messages: messages2, headers: headers2, body: body2, data });
281
224
  },
282
225
  [triggerRequest, generateId]
283
226
  );
284
227
  const reload = (0, import_react2.useCallback)(
285
- async ({ data, headers: headers2, body: body2 } = {}) => {
228
+ async ({ headers: headers2, body: body2 } = {}) => {
286
229
  const messages2 = messagesRef.current;
287
230
  if (messages2.length === 0) {
288
231
  return null;
@@ -291,8 +234,7 @@ function useChat({
291
234
  return triggerRequest({
292
235
  messages: lastMessage.role === "assistant" ? messages2.slice(0, -1) : messages2,
293
236
  headers: headers2,
294
- body: body2,
295
- data
237
+ body: body2
296
238
  });
297
239
  },
298
240
  [triggerRequest]
@@ -303,33 +245,27 @@ function useChat({
303
245
  abortControllerRef.current = null;
304
246
  }
305
247
  }, []);
248
+ const experimental_resume = (0, import_react2.useCallback)(async () => {
249
+ const messages2 = messagesRef.current;
250
+ triggerRequest({ messages: messages2 }, "resume");
251
+ }, [triggerRequest]);
306
252
  const setMessages = (0, import_react2.useCallback)(
307
253
  (messages2) => {
308
254
  if (typeof messages2 === "function") {
309
255
  messages2 = messages2(messagesRef.current);
310
256
  }
311
- const messagesWithParts = (0, import_ui_utils2.fillMessageParts)(messages2);
312
- mutate(messagesWithParts, false);
313
- messagesRef.current = messagesWithParts;
257
+ mutate(messages2, false);
258
+ messagesRef.current = messages2;
314
259
  },
315
260
  [mutate]
316
261
  );
317
- const setData = (0, import_react2.useCallback)(
318
- (data) => {
319
- if (typeof data === "function") {
320
- data = data(streamDataRef.current);
321
- }
322
- mutateStreamData(data, false);
323
- streamDataRef.current = data;
324
- },
325
- [mutateStreamData]
326
- );
327
262
  const [input, setInput] = (0, import_react2.useState)(initialInput);
328
263
  const handleSubmit = (0, import_react2.useCallback)(
329
264
  async (event, options = {}, metadata) => {
330
265
  var _a;
331
266
  (_a = event == null ? void 0 : event.preventDefault) == null ? void 0 : _a.call(event);
332
- if (!input && !options.allowEmptySubmit)
267
+ const fileParts = Array.isArray(options == null ? void 0 : options.files) ? options.files : await (0, import_ai2.convertFileListToFileUIParts)(options == null ? void 0 : options.files);
268
+ if (!input && fileParts.length === 0)
333
269
  return;
334
270
  if (metadata) {
335
271
  extraMetadataRef.current = {
@@ -337,24 +273,16 @@ function useChat({
337
273
  ...metadata
338
274
  };
339
275
  }
340
- const attachmentsForRequest = await (0, import_ui_utils2.prepareAttachmentsForRequest)(
341
- options.experimental_attachments
342
- );
343
- const messages2 = messagesRef.current.concat({
344
- id: generateId(),
345
- createdAt: /* @__PURE__ */ new Date(),
346
- role: "user",
347
- content: input,
348
- experimental_attachments: attachmentsForRequest.length > 0 ? attachmentsForRequest : void 0,
349
- parts: [{ type: "text", text: input }]
350
- });
351
- const chatRequest = {
352
- messages: messages2,
276
+ triggerRequest({
277
+ messages: messagesRef.current.concat({
278
+ id: generateId(),
279
+ role: "user",
280
+ metadata: void 0,
281
+ parts: [...fileParts, { type: "text", text: input }]
282
+ }),
353
283
  headers: options.headers,
354
- body: options.body,
355
- data: options.data
356
- };
357
- triggerRequest(chatRequest);
284
+ body: options.body
285
+ });
358
286
  setInput("");
359
287
  },
360
288
  [input, generateId, triggerRequest]
@@ -365,7 +293,7 @@ function useChat({
365
293
  const addToolResult = (0, import_react2.useCallback)(
366
294
  ({ toolCallId, result }) => {
367
295
  const currentMessages = messagesRef.current;
368
- (0, import_ui_utils2.updateToolCallResult)({
296
+ (0, import_ai2.updateToolCallResult)({
369
297
  messages: currentMessages,
370
298
  toolCallId,
371
299
  toolResult: result
@@ -373,7 +301,12 @@ function useChat({
373
301
  mutate(
374
302
  [
375
303
  ...currentMessages.slice(0, currentMessages.length - 1),
376
- { ...currentMessages[currentMessages.length - 1] }
304
+ {
305
+ ...currentMessages[currentMessages.length - 1],
306
+ // @ts-ignore
307
+ // update the revisionId to trigger a re-render
308
+ revisionId: generateId()
309
+ }
377
310
  ],
378
311
  false
379
312
  );
@@ -381,34 +314,32 @@ function useChat({
381
314
  return;
382
315
  }
383
316
  const lastMessage = currentMessages[currentMessages.length - 1];
384
- if ((0, import_ui_utils2.isAssistantMessageWithCompletedToolCalls)(lastMessage)) {
317
+ if ((0, import_ai2.isAssistantMessageWithCompletedToolCalls)(lastMessage)) {
385
318
  triggerRequest({ messages: currentMessages });
386
319
  }
387
320
  },
388
- [mutate, status, triggerRequest]
321
+ [mutate, status, triggerRequest, generateId]
389
322
  );
390
323
  return {
391
324
  messages: messages != null ? messages : [],
392
325
  id: chatId,
393
326
  setMessages,
394
- data: streamData,
395
- setData,
396
327
  error,
397
328
  append,
398
329
  reload,
399
330
  stop,
331
+ experimental_resume,
400
332
  input,
401
333
  setInput,
402
334
  handleInputChange,
403
335
  handleSubmit,
404
- isLoading: status === "submitted" || status === "streaming",
405
336
  status,
406
337
  addToolResult
407
338
  };
408
339
  }
409
340
 
410
341
  // src/use-completion.ts
411
- var import_ui_utils3 = require("@ai-sdk/ui-utils");
342
+ var import_ai3 = require("ai");
412
343
  var import_react3 = require("react");
413
344
  var import_swr2 = __toESM(require("swr"));
414
345
  function useCompletion({
@@ -421,7 +352,6 @@ function useCompletion({
421
352
  body,
422
353
  streamProtocol = "data",
423
354
  fetch: fetch2,
424
- onResponse,
425
355
  onFinish,
426
356
  onError,
427
357
  experimental_throttle: throttleWaitMs
@@ -435,7 +365,6 @@ function useCompletion({
435
365
  [completionId, "loading"],
436
366
  null
437
367
  );
438
- const { data: streamData, mutate: mutateStreamData } = (0, import_swr2.default)([completionId, "streamData"], null);
439
368
  const [error, setError] = (0, import_react3.useState)(void 0);
440
369
  const completion = data;
441
370
  const [abortController, setAbortController] = (0, import_react3.useState)(null);
@@ -452,7 +381,7 @@ function useCompletion({
452
381
  };
453
382
  }, [credentials, headers, body]);
454
383
  const triggerRequest = (0, import_react3.useCallback)(
455
- async (prompt, options) => (0, import_ui_utils3.callCompletionApi)({
384
+ async (prompt, options) => (0, import_ai3.callCompletionApi)({
456
385
  api,
457
386
  prompt,
458
387
  credentials: extraMetadataRef.current.credentials,
@@ -468,14 +397,9 @@ function useCompletion({
468
397
  (completion2) => mutate(completion2, false),
469
398
  throttleWaitMs
470
399
  ),
471
- onData: throttle(
472
- (data2) => mutateStreamData([...streamData != null ? streamData : [], ...data2 != null ? data2 : []], false),
473
- throttleWaitMs
474
- ),
475
400
  setLoading: mutateLoading,
476
401
  setError,
477
402
  setAbortController,
478
- onResponse,
479
403
  onFinish,
480
404
  onError
481
405
  }),
@@ -485,14 +409,11 @@ function useCompletion({
485
409
  api,
486
410
  extraMetadataRef,
487
411
  setAbortController,
488
- onResponse,
489
412
  onFinish,
490
413
  onError,
491
414
  setError,
492
- streamData,
493
415
  streamProtocol,
494
416
  fetch2,
495
- mutateStreamData,
496
417
  throttleWaitMs
497
418
  ]
498
419
  );
@@ -539,14 +460,13 @@ function useCompletion({
539
460
  setInput,
540
461
  handleInputChange,
541
462
  handleSubmit,
542
- isLoading,
543
- data: streamData
463
+ isLoading
544
464
  };
545
465
  }
546
466
 
547
467
  // src/use-object.ts
548
468
  var import_provider_utils = require("@ai-sdk/provider-utils");
549
- var import_ui_utils4 = require("@ai-sdk/ui-utils");
469
+ var import_ai4 = require("ai");
550
470
  var import_react4 = require("react");
551
471
  var import_swr3 = __toESM(require("swr"));
552
472
  var getOriginalFetch = () => fetch;
@@ -613,22 +533,22 @@ function useObject({
613
533
  let latestObject = void 0;
614
534
  await response.body.pipeThrough(new TextDecoderStream()).pipeTo(
615
535
  new WritableStream({
616
- write(chunk) {
536
+ async write(chunk) {
617
537
  accumulatedText += chunk;
618
- const { value } = (0, import_ui_utils4.parsePartialJson)(accumulatedText);
538
+ const { value } = await (0, import_ai4.parsePartialJson)(accumulatedText);
619
539
  const currentObject = value;
620
- if (!(0, import_ui_utils4.isDeepEqualData)(latestObject, currentObject)) {
540
+ if (!(0, import_ai4.isDeepEqualData)(latestObject, currentObject)) {
621
541
  latestObject = currentObject;
622
542
  mutate(currentObject);
623
543
  }
624
544
  },
625
- close() {
545
+ async close() {
626
546
  setIsLoading(false);
627
547
  abortControllerRef.current = null;
628
548
  if (onFinish != null) {
629
- const validationResult = (0, import_provider_utils.safeValidateTypes)({
549
+ const validationResult = await (0, import_provider_utils.safeValidateTypes)({
630
550
  value: latestObject,
631
- schema: (0, import_ui_utils4.asSchema)(schema)
551
+ schema: (0, import_ai4.asSchema)(schema)
632
552
  });
633
553
  onFinish(
634
554
  validationResult.success ? { object: validationResult.value, error: void 0 } : { object: void 0, error: validationResult.error }