ai 2.2.26 → 2.2.28

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.
@@ -4,9 +4,6 @@
4
4
  import { useCallback, useEffect, useId, useRef, useState } from "react";
5
5
  import useSWR from "swr";
6
6
 
7
- // shared/utils.ts
8
- import { customAlphabet } from "nanoid/non-secure";
9
-
10
7
  // shared/stream-parts.ts
11
8
  var textStreamPart = {
12
9
  code: "0",
@@ -53,7 +50,7 @@ var errorStreamPart = {
53
50
  return { type: "error", value };
54
51
  }
55
52
  };
56
- var assistantMessage = {
53
+ var assistantMessageStreamPart = {
57
54
  code: "4",
58
55
  name: "assistant_message",
59
56
  parse: (value) => {
@@ -70,7 +67,7 @@ var assistantMessage = {
70
67
  };
71
68
  }
72
69
  };
73
- var assistantControlData = {
70
+ var assistantControlDataStreamPart = {
74
71
  code: "5",
75
72
  name: "assistant_control_data",
76
73
  parse: (value) => {
@@ -88,29 +85,47 @@ var assistantControlData = {
88
85
  };
89
86
  }
90
87
  };
88
+ var dataMessageStreamPart = {
89
+ code: "6",
90
+ name: "data_message",
91
+ parse: (value) => {
92
+ if (value == null || typeof value !== "object" || !("role" in value) || !("data" in value) || typeof value.role !== "string" || value.role !== "data") {
93
+ throw new Error(
94
+ '"data_message" parts expect an object with a "role" and "data" property.'
95
+ );
96
+ }
97
+ return {
98
+ type: "data_message",
99
+ value
100
+ };
101
+ }
102
+ };
91
103
  var streamParts = [
92
104
  textStreamPart,
93
105
  functionCallStreamPart,
94
106
  dataStreamPart,
95
107
  errorStreamPart,
96
- assistantMessage,
97
- assistantControlData
108
+ assistantMessageStreamPart,
109
+ assistantControlDataStreamPart,
110
+ dataMessageStreamPart
98
111
  ];
99
112
  var streamPartsByCode = {
100
113
  [textStreamPart.code]: textStreamPart,
101
114
  [functionCallStreamPart.code]: functionCallStreamPart,
102
115
  [dataStreamPart.code]: dataStreamPart,
103
116
  [errorStreamPart.code]: errorStreamPart,
104
- [assistantMessage.code]: assistantMessage,
105
- [assistantControlData.code]: assistantControlData
117
+ [assistantMessageStreamPart.code]: assistantMessageStreamPart,
118
+ [assistantControlDataStreamPart.code]: assistantControlDataStreamPart,
119
+ [dataMessageStreamPart.code]: dataMessageStreamPart
106
120
  };
107
121
  var StreamStringPrefixes = {
108
122
  [textStreamPart.name]: textStreamPart.code,
109
123
  [functionCallStreamPart.name]: functionCallStreamPart.code,
110
124
  [dataStreamPart.name]: dataStreamPart.code,
111
125
  [errorStreamPart.name]: errorStreamPart.code,
112
- [assistantMessage.name]: assistantMessage.code,
113
- [assistantControlData.name]: assistantControlData.code
126
+ [assistantMessageStreamPart.name]: assistantMessageStreamPart.code,
127
+ [assistantControlDataStreamPart.name]: assistantControlDataStreamPart.code,
128
+ [dataMessageStreamPart.name]: dataMessageStreamPart.code
114
129
  };
115
130
  var validCodes = streamParts.map((part) => part.code);
116
131
  var parseStreamPart = (line) => {
@@ -128,7 +143,51 @@ var parseStreamPart = (line) => {
128
143
  return streamPartsByCode[code].parse(jsonValue);
129
144
  };
130
145
 
146
+ // shared/read-data-stream.ts
147
+ var NEWLINE = "\n".charCodeAt(0);
148
+ function concatChunks(chunks, totalLength) {
149
+ const concatenatedChunks = new Uint8Array(totalLength);
150
+ let offset = 0;
151
+ for (const chunk of chunks) {
152
+ concatenatedChunks.set(chunk, offset);
153
+ offset += chunk.length;
154
+ }
155
+ chunks.length = 0;
156
+ return concatenatedChunks;
157
+ }
158
+ async function* readDataStream(reader, {
159
+ isAborted
160
+ } = {}) {
161
+ const decoder = new TextDecoder();
162
+ const chunks = [];
163
+ let totalLength = 0;
164
+ while (true) {
165
+ const { value } = await reader.read();
166
+ if (value) {
167
+ chunks.push(value);
168
+ totalLength += value.length;
169
+ if (value[value.length - 1] !== NEWLINE) {
170
+ continue;
171
+ }
172
+ }
173
+ if (chunks.length === 0) {
174
+ break;
175
+ }
176
+ const concatenatedChunks = concatChunks(chunks, totalLength);
177
+ totalLength = 0;
178
+ const streamParts2 = decoder.decode(concatenatedChunks, { stream: true }).split("\n").filter((line) => line !== "").map(parseStreamPart);
179
+ for (const streamPart of streamParts2) {
180
+ yield streamPart;
181
+ }
182
+ if (isAborted == null ? void 0 : isAborted()) {
183
+ reader.cancel();
184
+ break;
185
+ }
186
+ }
187
+ }
188
+
131
189
  // shared/utils.ts
190
+ import { customAlphabet } from "nanoid/non-secure";
132
191
  var nanoid = customAlphabet(
133
192
  "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
134
193
  7
@@ -159,80 +218,47 @@ async function parseComplexResponse({
159
218
  getCurrentDate = () => /* @__PURE__ */ new Date()
160
219
  }) {
161
220
  const createdAt = getCurrentDate();
162
- const decode = createChunkDecoder(true);
163
221
  const prefixMap = {
164
222
  data: []
165
223
  };
166
- const NEWLINE = "\n".charCodeAt(0);
167
- const chunks = [];
168
- let totalLength = 0;
169
- while (true) {
170
- const { value } = await reader.read();
171
- if (value) {
172
- chunks.push(value);
173
- totalLength += value.length;
174
- if (value[value.length - 1] !== NEWLINE) {
175
- continue;
176
- }
177
- }
178
- if (chunks.length === 0) {
179
- break;
180
- }
181
- let concatenatedChunks = new Uint8Array(totalLength);
182
- let offset = 0;
183
- for (const chunk of chunks) {
184
- concatenatedChunks.set(chunk, offset);
185
- offset += chunk.length;
186
- }
187
- chunks.length = 0;
188
- totalLength = 0;
189
- const lines = decode(concatenatedChunks);
190
- if (typeof lines === "string") {
191
- throw new Error(
192
- "Invalid response format. Complex mode was set but the response is a string. This should never happen."
193
- );
194
- }
195
- for (const { type, value: value2 } of lines) {
196
- if (type === "text") {
197
- if (prefixMap["text"]) {
198
- prefixMap["text"] = {
199
- ...prefixMap["text"],
200
- content: (prefixMap["text"].content || "") + value2
201
- };
202
- } else {
203
- prefixMap["text"] = {
204
- id: generateId(),
205
- role: "assistant",
206
- content: value2,
207
- createdAt
208
- };
209
- }
210
- }
211
- let functionCallMessage = null;
212
- if (type === "function_call") {
213
- prefixMap["function_call"] = {
224
+ for await (const { type, value } of readDataStream(reader, {
225
+ isAborted: () => (abortControllerRef == null ? void 0 : abortControllerRef.current) === null
226
+ })) {
227
+ if (type === "text") {
228
+ if (prefixMap["text"]) {
229
+ prefixMap["text"] = {
230
+ ...prefixMap["text"],
231
+ content: (prefixMap["text"].content || "") + value
232
+ };
233
+ } else {
234
+ prefixMap["text"] = {
214
235
  id: generateId(),
215
236
  role: "assistant",
216
- content: "",
217
- function_call: value2.function_call,
218
- name: value2.function_call.name,
237
+ content: value,
219
238
  createdAt
220
239
  };
221
- functionCallMessage = prefixMap["function_call"];
222
- }
223
- if (type === "data") {
224
- prefixMap["data"].push(...value2);
225
- }
226
- const responseMessage = prefixMap["text"];
227
- const merged = [functionCallMessage, responseMessage].filter(
228
- Boolean
229
- );
230
- update(merged, [...prefixMap["data"]]);
231
- if ((abortControllerRef == null ? void 0 : abortControllerRef.current) === null) {
232
- reader.cancel();
233
- break;
234
240
  }
235
241
  }
242
+ let functionCallMessage = null;
243
+ if (type === "function_call") {
244
+ prefixMap["function_call"] = {
245
+ id: generateId(),
246
+ role: "assistant",
247
+ content: "",
248
+ function_call: value.function_call,
249
+ name: value.function_call.name,
250
+ createdAt
251
+ };
252
+ functionCallMessage = prefixMap["function_call"];
253
+ }
254
+ if (type === "data") {
255
+ prefixMap["data"].push(...value);
256
+ }
257
+ const responseMessage = prefixMap["text"];
258
+ const merged = [functionCallMessage, responseMessage].filter(
259
+ Boolean
260
+ );
261
+ update(merged, [...prefixMap["data"]]);
236
262
  }
237
263
  onFinish == null ? void 0 : onFinish(prefixMap);
238
264
  return {
@@ -243,8 +269,8 @@ async function parseComplexResponse({
243
269
  };
244
270
  }
245
271
 
246
- // shared/call-api.ts
247
- async function callApi({
272
+ // shared/call-chat-api.ts
273
+ async function callChatApi({
248
274
  api,
249
275
  messages,
250
276
  body,
@@ -439,7 +465,7 @@ var getStreamedResponse = async (api, chatRequest, mutate, mutateStreamData, exi
439
465
  }
440
466
  return responseMessage;
441
467
  }
442
- return await callApi({
468
+ return await callChatApi({
443
469
  api,
444
470
  messages: constructedMessagesPayload,
445
471
  body: {
@@ -490,16 +516,20 @@ function useChat({
490
516
  generateId = nanoid
491
517
  } = {}) {
492
518
  const hookId = useId();
493
- const chatId = id || hookId;
519
+ const idKey = id != null ? id : hookId;
520
+ const chatKey = typeof api === "string" ? [api, idKey] : idKey;
494
521
  const [initialMessagesFallback] = useState([]);
495
- const { data: messages, mutate } = useSWR([api, chatId], null, {
496
- fallbackData: initialMessages != null ? initialMessages : initialMessagesFallback
497
- });
522
+ const { data: messages, mutate } = useSWR(
523
+ [chatKey, "messages"],
524
+ null,
525
+ { fallbackData: initialMessages != null ? initialMessages : initialMessagesFallback }
526
+ );
498
527
  const { data: isLoading = false, mutate: mutateLoading } = useSWR(
499
- [chatId, "loading"],
528
+ [chatKey, "loading"],
500
529
  null
501
530
  );
502
- const { data: streamData, mutate: mutateStreamData } = useSWR([chatId, "streamData"], null);
531
+ const { data: streamData, mutate: mutateStreamData } = useSWR([chatKey, "streamData"], null);
532
+ const { data: error = void 0, mutate: setError } = useSWR([chatKey, "error"], null);
503
533
  const messagesRef = useRef(messages || []);
504
534
  useEffect(() => {
505
535
  messagesRef.current = messages || [];
@@ -517,7 +547,6 @@ function useChat({
517
547
  body
518
548
  };
519
549
  }, [credentials, headers, body]);
520
- const [error, setError] = useState();
521
550
  const triggerRequest = useCallback(
522
551
  async (chatRequest) => {
523
552
  try {
@@ -573,8 +602,8 @@ function useChat({
573
602
  streamData,
574
603
  sendExtraMessageFields,
575
604
  experimental_onFunctionCall,
576
- messagesRef.current,
577
- abortControllerRef.current,
605
+ messagesRef,
606
+ abortControllerRef,
578
607
  generateId
579
608
  ]
580
609
  );
@@ -678,24 +707,110 @@ function useChat({
678
707
  import { useCallback as useCallback2, useEffect as useEffect2, useId as useId2, useRef as useRef2, useState as useState2 } from "react";
679
708
  import useSWR2 from "swr";
680
709
 
681
- // shared/process-message-stream.ts
682
- async function processMessageStream(reader, processMessage) {
683
- const decoder = new TextDecoder();
684
- let buffer = "";
685
- while (true) {
686
- const { done, value } = await reader.read();
687
- if (done) {
688
- if (buffer.length > 0) {
689
- processMessage(buffer);
710
+ // shared/call-completion-api.ts
711
+ async function callCompletionApi({
712
+ api,
713
+ prompt,
714
+ credentials,
715
+ headers,
716
+ body,
717
+ setCompletion,
718
+ setLoading,
719
+ setError,
720
+ setAbortController,
721
+ onResponse,
722
+ onFinish,
723
+ onError,
724
+ onData
725
+ }) {
726
+ try {
727
+ setLoading(true);
728
+ setError(void 0);
729
+ const abortController = new AbortController();
730
+ setAbortController(abortController);
731
+ setCompletion("");
732
+ const res = await fetch(api, {
733
+ method: "POST",
734
+ body: JSON.stringify({
735
+ prompt,
736
+ ...body
737
+ }),
738
+ credentials,
739
+ headers: {
740
+ "Content-Type": "application/json",
741
+ ...headers
742
+ },
743
+ signal: abortController.signal
744
+ }).catch((err) => {
745
+ throw err;
746
+ });
747
+ if (onResponse) {
748
+ try {
749
+ await onResponse(res);
750
+ } catch (err) {
751
+ throw err;
690
752
  }
691
- break;
692
753
  }
693
- buffer += decoder.decode(value, { stream: true });
694
- let endIndex;
695
- while ((endIndex = buffer.indexOf("\n")) !== -1) {
696
- processMessage(buffer.substring(0, endIndex).trim());
697
- buffer = buffer.substring(endIndex + 1);
754
+ if (!res.ok) {
755
+ throw new Error(
756
+ await res.text() || "Failed to fetch the chat response."
757
+ );
758
+ }
759
+ if (!res.body) {
760
+ throw new Error("The response body is empty.");
698
761
  }
762
+ let result = "";
763
+ const reader = res.body.getReader();
764
+ const isComplexMode = res.headers.get(COMPLEX_HEADER) === "true";
765
+ if (isComplexMode) {
766
+ for await (const { type, value } of readDataStream(reader, {
767
+ isAborted: () => abortController === null
768
+ })) {
769
+ switch (type) {
770
+ case "text": {
771
+ result += value;
772
+ setCompletion(result);
773
+ break;
774
+ }
775
+ case "data": {
776
+ onData == null ? void 0 : onData(value);
777
+ break;
778
+ }
779
+ }
780
+ }
781
+ } else {
782
+ const decoder = createChunkDecoder();
783
+ while (true) {
784
+ const { done, value } = await reader.read();
785
+ if (done) {
786
+ break;
787
+ }
788
+ result += decoder(value);
789
+ setCompletion(result);
790
+ if (abortController === null) {
791
+ reader.cancel();
792
+ break;
793
+ }
794
+ }
795
+ }
796
+ if (onFinish) {
797
+ onFinish(prompt, result);
798
+ }
799
+ setAbortController(null);
800
+ return result;
801
+ } catch (err) {
802
+ if (err.name === "AbortError") {
803
+ setAbortController(null);
804
+ return null;
805
+ }
806
+ if (err instanceof Error) {
807
+ if (onError) {
808
+ onError(err);
809
+ }
810
+ }
811
+ setError(err);
812
+ } finally {
813
+ setLoading(false);
699
814
  }
700
815
  }
701
816
 
@@ -721,6 +836,7 @@ function useCompletion({
721
836
  [completionId, "loading"],
722
837
  null
723
838
  );
839
+ const { data: streamData, mutate: mutateStreamData } = useSWR2([completionId, "streamData"], null);
724
840
  const [error, setError] = useState2(void 0);
725
841
  const completion = data;
726
842
  const [abortController, setAbortController] = useState2(null);
@@ -737,90 +853,26 @@ function useCompletion({
737
853
  };
738
854
  }, [credentials, headers, body]);
739
855
  const triggerRequest = useCallback2(
740
- async (prompt, options) => {
741
- try {
742
- mutateLoading(true);
743
- setError(void 0);
744
- const abortController2 = new AbortController();
745
- setAbortController(abortController2);
746
- mutate("", false);
747
- const res = await fetch(api, {
748
- method: "POST",
749
- body: JSON.stringify({
750
- prompt,
751
- ...extraMetadataRef.current.body,
752
- ...options == null ? void 0 : options.body
753
- }),
754
- credentials: extraMetadataRef.current.credentials,
755
- headers: {
756
- ...extraMetadataRef.current.headers,
757
- ...options == null ? void 0 : options.headers
758
- },
759
- signal: abortController2.signal
760
- }).catch((err) => {
761
- throw err;
762
- });
763
- if (onResponse) {
764
- try {
765
- await onResponse(res);
766
- } catch (err) {
767
- throw err;
768
- }
769
- }
770
- if (!res.ok) {
771
- throw new Error(
772
- await res.text() || "Failed to fetch the chat response."
773
- );
774
- }
775
- if (!res.body) {
776
- throw new Error("The response body is empty.");
777
- }
778
- let result = "";
779
- const reader = res.body.getReader();
780
- const isComplexMode = res.headers.get(COMPLEX_HEADER) === "true";
781
- if (isComplexMode) {
782
- await processMessageStream(reader, (message) => {
783
- const { type, value } = parseStreamPart(message);
784
- if (type === "text") {
785
- result += value;
786
- mutate(result, false);
787
- }
788
- });
789
- } else {
790
- const decoder = createChunkDecoder();
791
- while (true) {
792
- const { done, value } = await reader.read();
793
- if (done) {
794
- break;
795
- }
796
- result += decoder(value);
797
- mutate(result, false);
798
- if (abortController2 === null) {
799
- reader.cancel();
800
- break;
801
- }
802
- }
803
- }
804
- if (onFinish) {
805
- onFinish(prompt, result);
806
- }
807
- setAbortController(null);
808
- return result;
809
- } catch (err) {
810
- if (err.name === "AbortError") {
811
- setAbortController(null);
812
- return null;
813
- }
814
- if (err instanceof Error) {
815
- if (onError) {
816
- onError(err);
817
- }
818
- }
819
- setError(err);
820
- } finally {
821
- mutateLoading(false);
856
+ async (prompt, options) => callCompletionApi({
857
+ api,
858
+ prompt,
859
+ credentials: extraMetadataRef.current.credentials,
860
+ headers: { ...extraMetadataRef.current.headers, ...options == null ? void 0 : options.headers },
861
+ body: {
862
+ ...extraMetadataRef.current.body,
863
+ ...options == null ? void 0 : options.body
864
+ },
865
+ setCompletion: (completion2) => mutate(completion2, false),
866
+ setLoading: mutateLoading,
867
+ setError,
868
+ setAbortController,
869
+ onResponse,
870
+ onFinish,
871
+ onError,
872
+ onData: (data2) => {
873
+ mutateStreamData([...streamData || [], ...data2 || []], false);
822
874
  }
823
- },
875
+ }),
824
876
  [
825
877
  mutate,
826
878
  mutateLoading,
@@ -830,7 +882,9 @@ function useCompletion({
830
882
  onResponse,
831
883
  onFinish,
832
884
  onError,
833
- setError
885
+ setError,
886
+ streamData,
887
+ mutateStreamData
834
888
  ]
835
889
  );
836
890
  const stop = useCallback2(() => {
@@ -874,7 +928,8 @@ function useCompletion({
874
928
  setInput,
875
929
  handleInputChange,
876
930
  handleSubmit,
877
- isLoading
931
+ isLoading,
932
+ data: streamData
878
933
  };
879
934
  }
880
935
 
@@ -882,7 +937,10 @@ function useCompletion({
882
937
  import { useState as useState3 } from "react";
883
938
  function experimental_useAssistant({
884
939
  api,
885
- threadId: threadIdParam
940
+ threadId: threadIdParam,
941
+ credentials,
942
+ headers,
943
+ body
886
944
  }) {
887
945
  const [messages, setMessages] = useState3([]);
888
946
  const [input, setInput] = useState3("");
@@ -906,8 +964,10 @@ function experimental_useAssistant({
906
964
  setInput("");
907
965
  const result = await fetch(api, {
908
966
  method: "POST",
909
- headers: { "Content-Type": "application/json" },
967
+ credentials,
968
+ headers: { "Content-Type": "application/json", ...headers },
910
969
  body: JSON.stringify({
970
+ ...body,
911
971
  // always use user-provided threadId when available:
912
972
  threadId: (_b = threadIdParam != null ? threadIdParam : threadId) != null ? _b : null,
913
973
  message: input,
@@ -918,9 +978,10 @@ function experimental_useAssistant({
918
978
  if (result.body == null) {
919
979
  throw new Error("The response body is empty.");
920
980
  }
921
- await processMessageStream(result.body.getReader(), (message) => {
922
- try {
923
- const { type, value } = parseStreamPart(message);
981
+ try {
982
+ for await (const { type, value } of readDataStream(
983
+ result.body.getReader()
984
+ )) {
924
985
  switch (type) {
925
986
  case "assistant_message": {
926
987
  setMessages((messages2) => [
@@ -933,6 +994,21 @@ function experimental_useAssistant({
933
994
  ]);
934
995
  break;
935
996
  }
997
+ case "data_message": {
998
+ setMessages((messages2) => {
999
+ var _a2;
1000
+ return [
1001
+ ...messages2,
1002
+ {
1003
+ id: (_a2 = value.id) != null ? _a2 : "",
1004
+ role: "data",
1005
+ content: "",
1006
+ data: value.data
1007
+ }
1008
+ ];
1009
+ });
1010
+ break;
1011
+ }
936
1012
  case "assistant_control_data": {
937
1013
  setThreadId(value.threadId);
938
1014
  setMessages((messages2) => {
@@ -947,10 +1023,10 @@ function experimental_useAssistant({
947
1023
  break;
948
1024
  }
949
1025
  }
950
- } catch (error2) {
951
- setError(error2);
952
1026
  }
953
- });
1027
+ } catch (error2) {
1028
+ setError(error2);
1029
+ }
954
1030
  setStatus("awaiting_message");
955
1031
  };
956
1032
  return {
@@ -968,3 +1044,4 @@ export {
968
1044
  useChat,
969
1045
  useCompletion
970
1046
  };
1047
+ //# sourceMappingURL=index.mjs.map