ai 2.2.26 → 2.2.27

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.
@@ -149,21 +149,22 @@ function createChunkDecoder(complex) {
149
149
  }
150
150
  var COMPLEX_HEADER = "X-Experimental-Stream-Data";
151
151
 
152
- // shared/parse-complex-response.ts
153
- async function parseComplexResponse({
154
- reader,
155
- abortControllerRef,
156
- update,
157
- onFinish,
158
- generateId = nanoid,
159
- getCurrentDate = () => /* @__PURE__ */ new Date()
160
- }) {
161
- const createdAt = getCurrentDate();
162
- const decode = createChunkDecoder(true);
163
- const prefixMap = {
164
- data: []
165
- };
166
- const NEWLINE = "\n".charCodeAt(0);
152
+ // shared/read-data-stream.ts
153
+ var NEWLINE = "\n".charCodeAt(0);
154
+ function concatChunks(chunks, totalLength) {
155
+ const concatenatedChunks = new Uint8Array(totalLength);
156
+ let offset = 0;
157
+ for (const chunk of chunks) {
158
+ concatenatedChunks.set(chunk, offset);
159
+ offset += chunk.length;
160
+ }
161
+ chunks.length = 0;
162
+ return concatenatedChunks;
163
+ }
164
+ async function* readDataStream(reader, {
165
+ isAborted
166
+ } = {}) {
167
+ const decoder = new TextDecoder();
167
168
  const chunks = [];
168
169
  let totalLength = 0;
169
170
  while (true) {
@@ -178,61 +179,70 @@ async function parseComplexResponse({
178
179
  if (chunks.length === 0) {
179
180
  break;
180
181
  }
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;
182
+ const concatenatedChunks = concatChunks(chunks, totalLength);
188
183
  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
- );
184
+ const streamParts2 = decoder.decode(concatenatedChunks, { stream: true }).split("\n").filter((line) => line !== "").map(parseStreamPart);
185
+ for (const streamPart of streamParts2) {
186
+ yield streamPart;
194
187
  }
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"] = {
188
+ if (isAborted == null ? void 0 : isAborted()) {
189
+ reader.cancel();
190
+ break;
191
+ }
192
+ }
193
+ }
194
+
195
+ // shared/parse-complex-response.ts
196
+ async function parseComplexResponse({
197
+ reader,
198
+ abortControllerRef,
199
+ update,
200
+ onFinish,
201
+ generateId = nanoid,
202
+ getCurrentDate = () => /* @__PURE__ */ new Date()
203
+ }) {
204
+ const createdAt = getCurrentDate();
205
+ const prefixMap = {
206
+ data: []
207
+ };
208
+ for await (const { type, value } of readDataStream(reader, {
209
+ isAborted: () => (abortControllerRef == null ? void 0 : abortControllerRef.current) === null
210
+ })) {
211
+ if (type === "text") {
212
+ if (prefixMap["text"]) {
213
+ prefixMap["text"] = {
214
+ ...prefixMap["text"],
215
+ content: (prefixMap["text"].content || "") + value
216
+ };
217
+ } else {
218
+ prefixMap["text"] = {
214
219
  id: generateId(),
215
220
  role: "assistant",
216
- content: "",
217
- function_call: value2.function_call,
218
- name: value2.function_call.name,
221
+ content: value,
219
222
  createdAt
220
223
  };
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
224
  }
235
225
  }
226
+ let functionCallMessage = null;
227
+ if (type === "function_call") {
228
+ prefixMap["function_call"] = {
229
+ id: generateId(),
230
+ role: "assistant",
231
+ content: "",
232
+ function_call: value.function_call,
233
+ name: value.function_call.name,
234
+ createdAt
235
+ };
236
+ functionCallMessage = prefixMap["function_call"];
237
+ }
238
+ if (type === "data") {
239
+ prefixMap["data"].push(...value);
240
+ }
241
+ const responseMessage = prefixMap["text"];
242
+ const merged = [functionCallMessage, responseMessage].filter(
243
+ Boolean
244
+ );
245
+ update(merged, [...prefixMap["data"]]);
236
246
  }
237
247
  onFinish == null ? void 0 : onFinish(prefixMap);
238
248
  return {
@@ -677,29 +687,6 @@ function useChat({
677
687
  // react/use-completion.ts
678
688
  import { useCallback as useCallback2, useEffect as useEffect2, useId as useId2, useRef as useRef2, useState as useState2 } from "react";
679
689
  import useSWR2 from "swr";
680
-
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);
690
- }
691
- break;
692
- }
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);
698
- }
699
- }
700
- }
701
-
702
- // react/use-completion.ts
703
690
  function useCompletion({
704
691
  api = "/api/completion",
705
692
  id,
@@ -721,6 +708,7 @@ function useCompletion({
721
708
  [completionId, "loading"],
722
709
  null
723
710
  );
711
+ const { data: streamData, mutate: mutateStreamData } = useSWR2([completionId, "streamData"], null);
724
712
  const [error, setError] = useState2(void 0);
725
713
  const completion = data;
726
714
  const [abortController, setAbortController] = useState2(null);
@@ -779,13 +767,24 @@ function useCompletion({
779
767
  const reader = res.body.getReader();
780
768
  const isComplexMode = res.headers.get(COMPLEX_HEADER) === "true";
781
769
  if (isComplexMode) {
782
- await processMessageStream(reader, (message) => {
783
- const { type, value } = parseStreamPart(message);
784
- if (type === "text") {
785
- result += value;
786
- mutate(result, false);
770
+ for await (const { type, value } of readDataStream(reader, {
771
+ isAborted: () => abortController2 === null
772
+ })) {
773
+ switch (type) {
774
+ case "text": {
775
+ result += value;
776
+ mutate(result, false);
777
+ break;
778
+ }
779
+ case "data": {
780
+ mutateStreamData(
781
+ [...streamData || [], ...value || []],
782
+ false
783
+ );
784
+ break;
785
+ }
787
786
  }
788
- });
787
+ }
789
788
  } else {
790
789
  const decoder = createChunkDecoder();
791
790
  while (true) {
@@ -874,7 +873,8 @@ function useCompletion({
874
873
  setInput,
875
874
  handleInputChange,
876
875
  handleSubmit,
877
- isLoading
876
+ isLoading,
877
+ data: streamData
878
878
  };
879
879
  }
880
880
 
@@ -882,7 +882,10 @@ function useCompletion({
882
882
  import { useState as useState3 } from "react";
883
883
  function experimental_useAssistant({
884
884
  api,
885
- threadId: threadIdParam
885
+ threadId: threadIdParam,
886
+ credentials,
887
+ headers,
888
+ body
886
889
  }) {
887
890
  const [messages, setMessages] = useState3([]);
888
891
  const [input, setInput] = useState3("");
@@ -906,8 +909,10 @@ function experimental_useAssistant({
906
909
  setInput("");
907
910
  const result = await fetch(api, {
908
911
  method: "POST",
909
- headers: { "Content-Type": "application/json" },
912
+ credentials,
913
+ headers: { "Content-Type": "application/json", ...headers },
910
914
  body: JSON.stringify({
915
+ ...body,
911
916
  // always use user-provided threadId when available:
912
917
  threadId: (_b = threadIdParam != null ? threadIdParam : threadId) != null ? _b : null,
913
918
  message: input,
@@ -918,9 +923,10 @@ function experimental_useAssistant({
918
923
  if (result.body == null) {
919
924
  throw new Error("The response body is empty.");
920
925
  }
921
- await processMessageStream(result.body.getReader(), (message) => {
922
- try {
923
- const { type, value } = parseStreamPart(message);
926
+ try {
927
+ for await (const { type, value } of readDataStream(
928
+ result.body.getReader()
929
+ )) {
924
930
  switch (type) {
925
931
  case "assistant_message": {
926
932
  setMessages((messages2) => [
@@ -947,10 +953,10 @@ function experimental_useAssistant({
947
953
  break;
948
954
  }
949
955
  }
950
- } catch (error2) {
951
- setError(error2);
952
956
  }
953
- });
957
+ } catch (error2) {
958
+ setError(error2);
959
+ }
954
960
  setStatus("awaiting_message");
955
961
  };
956
962
  return {
@@ -279,6 +279,8 @@ type UseCompletionHelpers = {
279
279
  handleSubmit: (e: any) => void;
280
280
  /** Whether the API request is in progress */
281
281
  isLoading: Accessor<boolean>;
282
+ /** Additional data added on the server via StreamData */
283
+ data: Accessor<JSONValue[] | undefined>;
282
284
  };
283
285
  declare function useCompletion({ api, id, initialCompletion, initialInput, credentials, headers, body, onResponse, onFinish, onError, }?: UseCompletionOptions): UseCompletionHelpers;
284
286
 
@@ -30,9 +30,6 @@ var import_solid_js = require("solid-js");
30
30
  var import_solid_swr_store = require("solid-swr-store");
31
31
  var import_swr_store = require("swr-store");
32
32
 
33
- // shared/utils.ts
34
- var import_non_secure = require("nanoid/non-secure");
35
-
36
33
  // shared/stream-parts.ts
37
34
  var textStreamPart = {
38
35
  code: "0",
@@ -154,7 +151,51 @@ var parseStreamPart = (line) => {
154
151
  return streamPartsByCode[code].parse(jsonValue);
155
152
  };
156
153
 
154
+ // shared/read-data-stream.ts
155
+ var NEWLINE = "\n".charCodeAt(0);
156
+ function concatChunks(chunks, totalLength) {
157
+ const concatenatedChunks = new Uint8Array(totalLength);
158
+ let offset = 0;
159
+ for (const chunk of chunks) {
160
+ concatenatedChunks.set(chunk, offset);
161
+ offset += chunk.length;
162
+ }
163
+ chunks.length = 0;
164
+ return concatenatedChunks;
165
+ }
166
+ async function* readDataStream(reader, {
167
+ isAborted
168
+ } = {}) {
169
+ const decoder = new TextDecoder();
170
+ const chunks = [];
171
+ let totalLength = 0;
172
+ while (true) {
173
+ const { value } = await reader.read();
174
+ if (value) {
175
+ chunks.push(value);
176
+ totalLength += value.length;
177
+ if (value[value.length - 1] !== NEWLINE) {
178
+ continue;
179
+ }
180
+ }
181
+ if (chunks.length === 0) {
182
+ break;
183
+ }
184
+ const concatenatedChunks = concatChunks(chunks, totalLength);
185
+ totalLength = 0;
186
+ const streamParts2 = decoder.decode(concatenatedChunks, { stream: true }).split("\n").filter((line) => line !== "").map(parseStreamPart);
187
+ for (const streamPart of streamParts2) {
188
+ yield streamPart;
189
+ }
190
+ if (isAborted == null ? void 0 : isAborted()) {
191
+ reader.cancel();
192
+ break;
193
+ }
194
+ }
195
+ }
196
+
157
197
  // shared/utils.ts
198
+ var import_non_secure = require("nanoid/non-secure");
158
199
  var nanoid = (0, import_non_secure.customAlphabet)(
159
200
  "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
160
201
  7
@@ -185,80 +226,47 @@ async function parseComplexResponse({
185
226
  getCurrentDate = () => /* @__PURE__ */ new Date()
186
227
  }) {
187
228
  const createdAt = getCurrentDate();
188
- const decode = createChunkDecoder(true);
189
229
  const prefixMap = {
190
230
  data: []
191
231
  };
192
- const NEWLINE = "\n".charCodeAt(0);
193
- const chunks = [];
194
- let totalLength = 0;
195
- while (true) {
196
- const { value } = await reader.read();
197
- if (value) {
198
- chunks.push(value);
199
- totalLength += value.length;
200
- if (value[value.length - 1] !== NEWLINE) {
201
- continue;
202
- }
203
- }
204
- if (chunks.length === 0) {
205
- break;
206
- }
207
- let concatenatedChunks = new Uint8Array(totalLength);
208
- let offset = 0;
209
- for (const chunk of chunks) {
210
- concatenatedChunks.set(chunk, offset);
211
- offset += chunk.length;
212
- }
213
- chunks.length = 0;
214
- totalLength = 0;
215
- const lines = decode(concatenatedChunks);
216
- if (typeof lines === "string") {
217
- throw new Error(
218
- "Invalid response format. Complex mode was set but the response is a string. This should never happen."
219
- );
220
- }
221
- for (const { type, value: value2 } of lines) {
222
- if (type === "text") {
223
- if (prefixMap["text"]) {
224
- prefixMap["text"] = {
225
- ...prefixMap["text"],
226
- content: (prefixMap["text"].content || "") + value2
227
- };
228
- } else {
229
- prefixMap["text"] = {
230
- id: generateId(),
231
- role: "assistant",
232
- content: value2,
233
- createdAt
234
- };
235
- }
236
- }
237
- let functionCallMessage = null;
238
- if (type === "function_call") {
239
- prefixMap["function_call"] = {
232
+ for await (const { type, value } of readDataStream(reader, {
233
+ isAborted: () => (abortControllerRef == null ? void 0 : abortControllerRef.current) === null
234
+ })) {
235
+ if (type === "text") {
236
+ if (prefixMap["text"]) {
237
+ prefixMap["text"] = {
238
+ ...prefixMap["text"],
239
+ content: (prefixMap["text"].content || "") + value
240
+ };
241
+ } else {
242
+ prefixMap["text"] = {
240
243
  id: generateId(),
241
244
  role: "assistant",
242
- content: "",
243
- function_call: value2.function_call,
244
- name: value2.function_call.name,
245
+ content: value,
245
246
  createdAt
246
247
  };
247
- functionCallMessage = prefixMap["function_call"];
248
- }
249
- if (type === "data") {
250
- prefixMap["data"].push(...value2);
251
- }
252
- const responseMessage = prefixMap["text"];
253
- const merged = [functionCallMessage, responseMessage].filter(
254
- Boolean
255
- );
256
- update(merged, [...prefixMap["data"]]);
257
- if ((abortControllerRef == null ? void 0 : abortControllerRef.current) === null) {
258
- reader.cancel();
259
- break;
260
248
  }
261
249
  }
250
+ let functionCallMessage = null;
251
+ if (type === "function_call") {
252
+ prefixMap["function_call"] = {
253
+ id: generateId(),
254
+ role: "assistant",
255
+ content: "",
256
+ function_call: value.function_call,
257
+ name: value.function_call.name,
258
+ createdAt
259
+ };
260
+ functionCallMessage = prefixMap["function_call"];
261
+ }
262
+ if (type === "data") {
263
+ prefixMap["data"].push(...value);
264
+ }
265
+ const responseMessage = prefixMap["text"];
266
+ const merged = [functionCallMessage, responseMessage].filter(
267
+ Boolean
268
+ );
269
+ update(merged, [...prefixMap["data"]]);
262
270
  }
263
271
  onFinish == null ? void 0 : onFinish(prefixMap);
264
272
  return {
@@ -597,8 +605,8 @@ function useChat({
597
605
 
598
606
  // solid/use-completion.ts
599
607
  var import_solid_js2 = require("solid-js");
600
- var import_swr_store2 = require("swr-store");
601
608
  var import_solid_swr_store2 = require("solid-swr-store");
609
+ var import_swr_store2 = require("swr-store");
602
610
  var uniqueId2 = 0;
603
611
  var store2 = {};
604
612
  var completionApiStore = (0, import_swr_store2.createSWRStore)({
@@ -633,9 +641,13 @@ function useCompletion({
633
641
  };
634
642
  const completion = data;
635
643
  const [error, setError] = (0, import_solid_js2.createSignal)(void 0);
644
+ const [streamData, setStreamData] = (0, import_solid_js2.createSignal)(
645
+ void 0
646
+ );
636
647
  const [isLoading, setIsLoading] = (0, import_solid_js2.createSignal)(false);
637
648
  let abortController = null;
638
649
  async function triggerRequest(prompt, options) {
650
+ var _a;
639
651
  try {
640
652
  setError(void 0);
641
653
  setIsLoading(true);
@@ -674,17 +686,37 @@ function useCompletion({
674
686
  }
675
687
  let result = "";
676
688
  const reader = res.body.getReader();
677
- const decoder = createChunkDecoder();
678
- while (true) {
679
- const { done, value } = await reader.read();
680
- if (done) {
681
- break;
689
+ const isComplexMode = res.headers.get(COMPLEX_HEADER) === "true";
690
+ if (isComplexMode) {
691
+ const existingData = (_a = streamData()) != null ? _a : [];
692
+ for await (const { type, value } of readDataStream(reader, {
693
+ isAborted: () => abortController === null
694
+ })) {
695
+ switch (type) {
696
+ case "text": {
697
+ result += value;
698
+ mutate(result);
699
+ break;
700
+ }
701
+ case "data": {
702
+ setStreamData([...existingData, ...value != null ? value : []]);
703
+ break;
704
+ }
705
+ }
682
706
  }
683
- result += decoder(value);
684
- mutate(result);
685
- if (abortController === null) {
686
- reader.cancel();
687
- break;
707
+ } else {
708
+ const decoder = createChunkDecoder();
709
+ while (true) {
710
+ const { done, value } = await reader.read();
711
+ if (done) {
712
+ break;
713
+ }
714
+ result += decoder(value);
715
+ mutate(result);
716
+ if (abortController === null) {
717
+ reader.cancel();
718
+ break;
719
+ }
688
720
  }
689
721
  }
690
722
  if (onFinish) {
@@ -734,7 +766,8 @@ function useCompletion({
734
766
  input,
735
767
  setInput,
736
768
  handleSubmit,
737
- isLoading
769
+ isLoading,
770
+ data: streamData
738
771
  };
739
772
  }
740
773
  // Annotate the CommonJS export names for ESM import in node: