@ai-sdk/react 0.0.3 → 0.0.4

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.mjs CHANGED
@@ -1,10 +1,171 @@
1
+ // src/use-assistant.ts
2
+ import { isAbortError } from "@ai-sdk/provider-utils";
3
+ import {
4
+ generateId,
5
+ readDataStream
6
+ } from "@ai-sdk/ui-utils";
7
+ import { useCallback, useRef, useState } from "react";
8
+ function useAssistant({
9
+ api,
10
+ threadId: threadIdParam,
11
+ credentials,
12
+ headers,
13
+ body,
14
+ onError
15
+ }) {
16
+ const [messages, setMessages] = useState([]);
17
+ const [input, setInput] = useState("");
18
+ const [threadId, setThreadId] = useState(void 0);
19
+ const [status, setStatus] = useState("awaiting_message");
20
+ const [error, setError] = useState(void 0);
21
+ const handleInputChange = (event) => {
22
+ setInput(event.target.value);
23
+ };
24
+ const abortControllerRef = useRef(null);
25
+ const stop = useCallback(() => {
26
+ if (abortControllerRef.current) {
27
+ abortControllerRef.current.abort();
28
+ abortControllerRef.current = null;
29
+ }
30
+ }, []);
31
+ const append = async (message, requestOptions) => {
32
+ var _a;
33
+ setStatus("in_progress");
34
+ setMessages((messages2) => {
35
+ var _a2;
36
+ return [
37
+ ...messages2,
38
+ {
39
+ ...message,
40
+ id: (_a2 = message.id) != null ? _a2 : generateId()
41
+ }
42
+ ];
43
+ });
44
+ setInput("");
45
+ const abortController = new AbortController();
46
+ try {
47
+ abortControllerRef.current = abortController;
48
+ const result = await fetch(api, {
49
+ method: "POST",
50
+ credentials,
51
+ signal: abortController.signal,
52
+ headers: { "Content-Type": "application/json", ...headers },
53
+ body: JSON.stringify({
54
+ ...body,
55
+ // always use user-provided threadId when available:
56
+ threadId: (_a = threadIdParam != null ? threadIdParam : threadId) != null ? _a : null,
57
+ message: message.content,
58
+ // optional request data:
59
+ data: requestOptions == null ? void 0 : requestOptions.data
60
+ })
61
+ });
62
+ if (result.body == null) {
63
+ throw new Error("The response body is empty.");
64
+ }
65
+ for await (const { type, value } of readDataStream(
66
+ result.body.getReader()
67
+ )) {
68
+ switch (type) {
69
+ case "assistant_message": {
70
+ setMessages((messages2) => [
71
+ ...messages2,
72
+ {
73
+ id: value.id,
74
+ role: value.role,
75
+ content: value.content[0].text.value
76
+ }
77
+ ]);
78
+ break;
79
+ }
80
+ case "text": {
81
+ setMessages((messages2) => {
82
+ const lastMessage = messages2[messages2.length - 1];
83
+ return [
84
+ ...messages2.slice(0, messages2.length - 1),
85
+ {
86
+ id: lastMessage.id,
87
+ role: lastMessage.role,
88
+ content: lastMessage.content + value
89
+ }
90
+ ];
91
+ });
92
+ break;
93
+ }
94
+ case "data_message": {
95
+ setMessages((messages2) => {
96
+ var _a2;
97
+ return [
98
+ ...messages2,
99
+ {
100
+ id: (_a2 = value.id) != null ? _a2 : generateId(),
101
+ role: "data",
102
+ content: "",
103
+ data: value.data
104
+ }
105
+ ];
106
+ });
107
+ break;
108
+ }
109
+ case "assistant_control_data": {
110
+ setThreadId(value.threadId);
111
+ setMessages((messages2) => {
112
+ const lastMessage = messages2[messages2.length - 1];
113
+ lastMessage.id = value.messageId;
114
+ return [...messages2.slice(0, messages2.length - 1), lastMessage];
115
+ });
116
+ break;
117
+ }
118
+ case "error": {
119
+ setError(new Error(value));
120
+ break;
121
+ }
122
+ }
123
+ }
124
+ } catch (error2) {
125
+ if (isAbortError(error2) && abortController.signal.aborted) {
126
+ abortControllerRef.current = null;
127
+ return;
128
+ }
129
+ if (onError && error2 instanceof Error) {
130
+ onError(error2);
131
+ }
132
+ setError(error2);
133
+ } finally {
134
+ abortControllerRef.current = null;
135
+ setStatus("awaiting_message");
136
+ }
137
+ };
138
+ const submitMessage = async (event, requestOptions) => {
139
+ var _a;
140
+ (_a = event == null ? void 0 : event.preventDefault) == null ? void 0 : _a.call(event);
141
+ if (input === "") {
142
+ return;
143
+ }
144
+ append({ role: "user", content: input }, requestOptions);
145
+ };
146
+ return {
147
+ append,
148
+ messages,
149
+ setMessages,
150
+ threadId,
151
+ input,
152
+ setInput,
153
+ handleInputChange,
154
+ submitMessage,
155
+ status,
156
+ error,
157
+ stop
158
+ };
159
+ }
160
+ var experimental_useAssistant = useAssistant;
161
+
1
162
  // src/use-chat.ts
2
163
  import {
3
164
  callChatApi,
4
165
  generateId as generateIdFunc,
5
166
  processChatStream
6
167
  } from "@ai-sdk/ui-utils";
7
- import { useCallback, useEffect, useId, useRef, useState } from "react";
168
+ import { useCallback as useCallback2, useEffect, useId, useRef as useRef2, useState as useState2 } from "react";
8
169
  import useSWR from "swr";
9
170
  var getStreamedResponse = async (api, chatRequest, mutate, mutateStreamData, existingData, extraMetadataRef, messagesRef, abortControllerRef, generateId2, streamMode, onFinish, onResponse, onToolCall, sendExtraMessageFields) => {
10
171
  var _a, _b;
@@ -98,7 +259,7 @@ function useChat({
98
259
  const hookId = useId();
99
260
  const idKey = id != null ? id : hookId;
100
261
  const chatKey = typeof api === "string" ? [api, idKey] : idKey;
101
- const [initialMessagesFallback] = useState([]);
262
+ const [initialMessagesFallback] = useState2([]);
102
263
  const { data: messages, mutate } = useSWR(
103
264
  [chatKey, "messages"],
104
265
  null,
@@ -110,12 +271,12 @@ function useChat({
110
271
  );
111
272
  const { data: streamData, mutate: mutateStreamData } = useSWR([chatKey, "streamData"], null);
112
273
  const { data: error = void 0, mutate: setError } = useSWR([chatKey, "error"], null);
113
- const messagesRef = useRef(messages || []);
274
+ const messagesRef = useRef2(messages || []);
114
275
  useEffect(() => {
115
276
  messagesRef.current = messages || [];
116
277
  }, [messages]);
117
- const abortControllerRef = useRef(null);
118
- const extraMetadataRef = useRef({
278
+ const abortControllerRef = useRef2(null);
279
+ const extraMetadataRef = useRef2({
119
280
  credentials,
120
281
  headers,
121
282
  body
@@ -127,7 +288,7 @@ function useChat({
127
288
  body
128
289
  };
129
290
  }, [credentials, headers, body]);
130
- const triggerRequest = useCallback(
291
+ const triggerRequest = useCallback2(
131
292
  async (chatRequest) => {
132
293
  try {
133
294
  mutateLoading(true);
@@ -205,7 +366,7 @@ function useChat({
205
366
  generateId2
206
367
  ]
207
368
  );
208
- const append = useCallback(
369
+ const append = useCallback2(
209
370
  async (message, {
210
371
  options,
211
372
  functions,
@@ -230,7 +391,7 @@ function useChat({
230
391
  },
231
392
  [triggerRequest, generateId2]
232
393
  );
233
- const reload = useCallback(
394
+ const reload = useCallback2(
234
395
  async ({
235
396
  options,
236
397
  functions,
@@ -264,21 +425,21 @@ function useChat({
264
425
  },
265
426
  [triggerRequest]
266
427
  );
267
- const stop = useCallback(() => {
428
+ const stop = useCallback2(() => {
268
429
  if (abortControllerRef.current) {
269
430
  abortControllerRef.current.abort();
270
431
  abortControllerRef.current = null;
271
432
  }
272
433
  }, []);
273
- const setMessages = useCallback(
434
+ const setMessages = useCallback2(
274
435
  (messages2) => {
275
436
  mutate(messages2, false);
276
437
  messagesRef.current = messages2;
277
438
  },
278
439
  [mutate]
279
440
  );
280
- const [input, setInput] = useState(initialInput);
281
- const handleSubmit = useCallback(
441
+ const [input, setInput] = useState2(initialInput);
442
+ const handleSubmit = useCallback2(
282
443
  (e, options = {}, metadata) => {
283
444
  if (metadata) {
284
445
  extraMetadataRef.current = {
@@ -361,7 +522,7 @@ function countTrailingAssistantMessages(messages) {
361
522
  import {
362
523
  callCompletionApi
363
524
  } from "@ai-sdk/ui-utils";
364
- import { useCallback as useCallback2, useEffect as useEffect2, useId as useId2, useRef as useRef2, useState as useState2 } from "react";
525
+ import { useCallback as useCallback3, useEffect as useEffect2, useId as useId2, useRef as useRef3, useState as useState3 } from "react";
365
526
  import useSWR2 from "swr";
366
527
  function useCompletion({
367
528
  api = "/api/completion",
@@ -386,10 +547,10 @@ function useCompletion({
386
547
  null
387
548
  );
388
549
  const { data: streamData, mutate: mutateStreamData } = useSWR2([completionId, "streamData"], null);
389
- const [error, setError] = useState2(void 0);
550
+ const [error, setError] = useState3(void 0);
390
551
  const completion = data;
391
- const [abortController, setAbortController] = useState2(null);
392
- const extraMetadataRef = useRef2({
552
+ const [abortController, setAbortController] = useState3(null);
553
+ const extraMetadataRef = useRef3({
393
554
  credentials,
394
555
  headers,
395
556
  body
@@ -401,7 +562,7 @@ function useCompletion({
401
562
  body
402
563
  };
403
564
  }, [credentials, headers, body]);
404
- const triggerRequest = useCallback2(
565
+ const triggerRequest = useCallback3(
405
566
  async (prompt, options) => callCompletionApi({
406
567
  api,
407
568
  prompt,
@@ -438,26 +599,26 @@ function useCompletion({
438
599
  mutateStreamData
439
600
  ]
440
601
  );
441
- const stop = useCallback2(() => {
602
+ const stop = useCallback3(() => {
442
603
  if (abortController) {
443
604
  abortController.abort();
444
605
  setAbortController(null);
445
606
  }
446
607
  }, [abortController]);
447
- const setCompletion = useCallback2(
608
+ const setCompletion = useCallback3(
448
609
  (completion2) => {
449
610
  mutate(completion2, false);
450
611
  },
451
612
  [mutate]
452
613
  );
453
- const complete = useCallback2(
614
+ const complete = useCallback3(
454
615
  async (prompt, options) => {
455
616
  return triggerRequest(prompt, options);
456
617
  },
457
618
  [triggerRequest]
458
619
  );
459
- const [input, setInput] = useState2(initialInput);
460
- const handleSubmit = useCallback2(
620
+ const [input, setInput] = useState3(initialInput);
621
+ const handleSubmit = useCallback3(
461
622
  (e) => {
462
623
  e.preventDefault();
463
624
  if (!input)
@@ -484,168 +645,74 @@ function useCompletion({
484
645
  };
485
646
  }
486
647
 
487
- // src/use-assistant.ts
488
- import { isAbortError } from "@ai-sdk/provider-utils";
648
+ // src/use-object.ts
489
649
  import {
490
- generateId,
491
- readDataStream
650
+ isDeepEqualData,
651
+ parsePartialJson
492
652
  } from "@ai-sdk/ui-utils";
493
- import { useCallback as useCallback3, useRef as useRef3, useState as useState3 } from "react";
494
- function useAssistant({
653
+ import { useId as useId3, useState as useState4 } from "react";
654
+ import useSWR3 from "swr";
655
+ function useObject({
495
656
  api,
496
- threadId: threadIdParam,
497
- credentials,
498
- headers,
499
- body,
500
- onError
657
+ id,
658
+ schema,
659
+ // required, in the future we will use it for validation
660
+ initialValue
501
661
  }) {
502
- const [messages, setMessages] = useState3([]);
503
- const [input, setInput] = useState3("");
504
- const [threadId, setThreadId] = useState3(void 0);
505
- const [status, setStatus] = useState3("awaiting_message");
506
- const [error, setError] = useState3(void 0);
507
- const handleInputChange = (event) => {
508
- setInput(event.target.value);
509
- };
510
- const abortControllerRef = useRef3(null);
511
- const stop = useCallback3(() => {
512
- if (abortControllerRef.current) {
513
- abortControllerRef.current.abort();
514
- abortControllerRef.current = null;
515
- }
516
- }, []);
517
- const append = async (message, requestOptions) => {
518
- var _a;
519
- setStatus("in_progress");
520
- setMessages((messages2) => {
521
- var _a2;
522
- return [
523
- ...messages2,
524
- {
525
- ...message,
526
- id: (_a2 = message.id) != null ? _a2 : generateId()
662
+ const hookId = useId3();
663
+ const completionId = id != null ? id : hookId;
664
+ const { data, mutate } = useSWR3(
665
+ [api, completionId],
666
+ null,
667
+ { fallbackData: initialValue }
668
+ );
669
+ const [error, setError] = useState4(void 0);
670
+ return {
671
+ async setInput(input) {
672
+ var _a;
673
+ try {
674
+ const response = await fetch(api, {
675
+ method: "POST",
676
+ headers: { "Content-Type": "application/json" },
677
+ body: JSON.stringify(input)
678
+ });
679
+ if (!response.ok) {
680
+ throw new Error(
681
+ (_a = await response.text()) != null ? _a : "Failed to fetch the response."
682
+ );
527
683
  }
528
- ];
529
- });
530
- setInput("");
531
- const abortController = new AbortController();
532
- try {
533
- abortControllerRef.current = abortController;
534
- const result = await fetch(api, {
535
- method: "POST",
536
- credentials,
537
- signal: abortController.signal,
538
- headers: { "Content-Type": "application/json", ...headers },
539
- body: JSON.stringify({
540
- ...body,
541
- // always use user-provided threadId when available:
542
- threadId: (_a = threadIdParam != null ? threadIdParam : threadId) != null ? _a : null,
543
- message: message.content,
544
- // optional request data:
545
- data: requestOptions == null ? void 0 : requestOptions.data
546
- })
547
- });
548
- if (result.body == null) {
549
- throw new Error("The response body is empty.");
550
- }
551
- for await (const { type, value } of readDataStream(
552
- result.body.getReader()
553
- )) {
554
- switch (type) {
555
- case "assistant_message": {
556
- setMessages((messages2) => [
557
- ...messages2,
558
- {
559
- id: value.id,
560
- role: value.role,
561
- content: value.content[0].text.value
562
- }
563
- ]);
564
- break;
565
- }
566
- case "text": {
567
- setMessages((messages2) => {
568
- const lastMessage = messages2[messages2.length - 1];
569
- return [
570
- ...messages2.slice(0, messages2.length - 1),
571
- {
572
- id: lastMessage.id,
573
- role: lastMessage.role,
574
- content: lastMessage.content + value
575
- }
576
- ];
577
- });
578
- break;
579
- }
580
- case "data_message": {
581
- setMessages((messages2) => {
582
- var _a2;
583
- return [
584
- ...messages2,
585
- {
586
- id: (_a2 = value.id) != null ? _a2 : generateId(),
587
- role: "data",
588
- content: "",
589
- data: value.data
590
- }
591
- ];
592
- });
593
- break;
594
- }
595
- case "assistant_control_data": {
596
- setThreadId(value.threadId);
597
- setMessages((messages2) => {
598
- const lastMessage = messages2[messages2.length - 1];
599
- lastMessage.id = value.messageId;
600
- return [...messages2.slice(0, messages2.length - 1), lastMessage];
601
- });
602
- break;
603
- }
604
- case "error": {
605
- setError(new Error(value));
606
- break;
607
- }
684
+ if (response.body == null) {
685
+ throw new Error("The response body is empty.");
608
686
  }
687
+ let accumulatedText = "";
688
+ let latestObject = void 0;
689
+ response.body.pipeThrough(new TextDecoderStream()).pipeTo(
690
+ new WritableStream({
691
+ write(chunk) {
692
+ accumulatedText += chunk;
693
+ const currentObject = parsePartialJson(
694
+ accumulatedText
695
+ );
696
+ if (!isDeepEqualData(latestObject, currentObject)) {
697
+ latestObject = currentObject;
698
+ mutate(currentObject);
699
+ }
700
+ }
701
+ })
702
+ );
703
+ setError(void 0);
704
+ } catch (error2) {
705
+ setError(error2);
609
706
  }
610
- } catch (error2) {
611
- if (isAbortError(error2) && abortController.signal.aborted) {
612
- abortControllerRef.current = null;
613
- return;
614
- }
615
- if (onError && error2 instanceof Error) {
616
- onError(error2);
617
- }
618
- setError(error2);
619
- } finally {
620
- abortControllerRef.current = null;
621
- setStatus("awaiting_message");
622
- }
623
- };
624
- const submitMessage = async (event, requestOptions) => {
625
- var _a;
626
- (_a = event == null ? void 0 : event.preventDefault) == null ? void 0 : _a.call(event);
627
- if (input === "") {
628
- return;
629
- }
630
- append({ role: "user", content: input }, requestOptions);
631
- };
632
- return {
633
- append,
634
- messages,
635
- setMessages,
636
- threadId,
637
- input,
638
- setInput,
639
- handleInputChange,
640
- submitMessage,
641
- status,
642
- error,
643
- stop
707
+ },
708
+ object: data,
709
+ error
644
710
  };
645
711
  }
646
- var experimental_useAssistant = useAssistant;
712
+ var experimental_useObject = useObject;
647
713
  export {
648
714
  experimental_useAssistant,
715
+ experimental_useObject,
649
716
  useAssistant,
650
717
  useChat,
651
718
  useCompletion