ai 3.1.37 → 3.2.1

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
@@ -588,7 +588,7 @@ async function generateObject({
588
588
  const generateResult = await retry(
589
589
  () => model.doGenerate({
590
590
  mode: { type: "object-grammar", schema: jsonSchema },
591
- ...settings,
591
+ ...prepareCallSettings(settings),
592
592
  inputFormat: validatedPrompt.type,
593
593
  prompt: convertToLanguageModelPrompt(validatedPrompt),
594
594
  abortSignal
@@ -622,7 +622,7 @@ async function generateObject({
622
622
  parameters: jsonSchema
623
623
  }
624
624
  },
625
- ...settings,
625
+ ...prepareCallSettings(settings),
626
626
  inputFormat: validatedPrompt.type,
627
627
  prompt: convertToLanguageModelPrompt(validatedPrompt),
628
628
  abortSignal
@@ -673,6 +673,13 @@ var GenerateObjectResult = class {
673
673
  };
674
674
  var experimental_generateObject = generateObject;
675
675
 
676
+ // core/generate-object/stream-object.ts
677
+ import { safeValidateTypes } from "@ai-sdk/provider-utils";
678
+ import {
679
+ isDeepEqualData,
680
+ parsePartialJson
681
+ } from "@ai-sdk/ui-utils";
682
+
676
683
  // core/util/async-iterable-stream.ts
677
684
  function createAsyncIterableStream(source, transformer) {
678
685
  const transformedStream = source.pipeThrough(
@@ -690,381 +697,17 @@ function createAsyncIterableStream(source, transformer) {
690
697
  return transformedStream;
691
698
  }
692
699
 
693
- // core/util/is-deep-equal-data.ts
694
- function isDeepEqualData(obj1, obj2) {
695
- if (obj1 === obj2)
696
- return true;
697
- if (obj1 == null || obj2 == null)
698
- return false;
699
- if (typeof obj1 !== "object" && typeof obj2 !== "object")
700
- return obj1 === obj2;
701
- if (obj1.constructor !== obj2.constructor)
702
- return false;
703
- if (obj1 instanceof Date && obj2 instanceof Date) {
704
- return obj1.getTime() === obj2.getTime();
705
- }
706
- if (Array.isArray(obj1)) {
707
- if (obj1.length !== obj2.length)
708
- return false;
709
- for (let i = 0; i < obj1.length; i++) {
710
- if (!isDeepEqualData(obj1[i], obj2[i]))
711
- return false;
712
- }
713
- return true;
714
- }
715
- const keys1 = Object.keys(obj1);
716
- const keys2 = Object.keys(obj2);
717
- if (keys1.length !== keys2.length)
718
- return false;
719
- for (const key of keys1) {
720
- if (!keys2.includes(key))
721
- return false;
722
- if (!isDeepEqualData(obj1[key], obj2[key]))
723
- return false;
724
- }
725
- return true;
726
- }
727
-
728
- // core/util/parse-partial-json.ts
729
- import SecureJSON from "secure-json-parse";
730
-
731
- // core/util/fix-json.ts
732
- function fixJson(input) {
733
- const stack = ["ROOT"];
734
- let lastValidIndex = -1;
735
- let literalStart = null;
736
- function processValueStart(char, i, swapState) {
737
- {
738
- switch (char) {
739
- case '"': {
740
- lastValidIndex = i;
741
- stack.pop();
742
- stack.push(swapState);
743
- stack.push("INSIDE_STRING");
744
- break;
745
- }
746
- case "f":
747
- case "t":
748
- case "n": {
749
- lastValidIndex = i;
750
- literalStart = i;
751
- stack.pop();
752
- stack.push(swapState);
753
- stack.push("INSIDE_LITERAL");
754
- break;
755
- }
756
- case "-": {
757
- stack.pop();
758
- stack.push(swapState);
759
- stack.push("INSIDE_NUMBER");
760
- break;
761
- }
762
- case "0":
763
- case "1":
764
- case "2":
765
- case "3":
766
- case "4":
767
- case "5":
768
- case "6":
769
- case "7":
770
- case "8":
771
- case "9": {
772
- lastValidIndex = i;
773
- stack.pop();
774
- stack.push(swapState);
775
- stack.push("INSIDE_NUMBER");
776
- break;
777
- }
778
- case "{": {
779
- lastValidIndex = i;
780
- stack.pop();
781
- stack.push(swapState);
782
- stack.push("INSIDE_OBJECT_START");
783
- break;
784
- }
785
- case "[": {
786
- lastValidIndex = i;
787
- stack.pop();
788
- stack.push(swapState);
789
- stack.push("INSIDE_ARRAY_START");
790
- break;
791
- }
792
- }
793
- }
794
- }
795
- function processAfterObjectValue(char, i) {
796
- switch (char) {
797
- case ",": {
798
- stack.pop();
799
- stack.push("INSIDE_OBJECT_AFTER_COMMA");
800
- break;
801
- }
802
- case "}": {
803
- lastValidIndex = i;
804
- stack.pop();
805
- break;
806
- }
807
- }
808
- }
809
- function processAfterArrayValue(char, i) {
810
- switch (char) {
811
- case ",": {
812
- stack.pop();
813
- stack.push("INSIDE_ARRAY_AFTER_COMMA");
814
- break;
815
- }
816
- case "]": {
817
- lastValidIndex = i;
818
- stack.pop();
819
- break;
820
- }
821
- }
822
- }
823
- for (let i = 0; i < input.length; i++) {
824
- const char = input[i];
825
- const currentState = stack[stack.length - 1];
826
- switch (currentState) {
827
- case "ROOT":
828
- processValueStart(char, i, "FINISH");
829
- break;
830
- case "INSIDE_OBJECT_START": {
831
- switch (char) {
832
- case '"': {
833
- stack.pop();
834
- stack.push("INSIDE_OBJECT_KEY");
835
- break;
836
- }
837
- case "}": {
838
- lastValidIndex = i;
839
- stack.pop();
840
- break;
841
- }
842
- }
843
- break;
844
- }
845
- case "INSIDE_OBJECT_AFTER_COMMA": {
846
- switch (char) {
847
- case '"': {
848
- stack.pop();
849
- stack.push("INSIDE_OBJECT_KEY");
850
- break;
851
- }
852
- }
853
- break;
854
- }
855
- case "INSIDE_OBJECT_KEY": {
856
- switch (char) {
857
- case '"': {
858
- stack.pop();
859
- stack.push("INSIDE_OBJECT_AFTER_KEY");
860
- break;
861
- }
862
- }
863
- break;
864
- }
865
- case "INSIDE_OBJECT_AFTER_KEY": {
866
- switch (char) {
867
- case ":": {
868
- stack.pop();
869
- stack.push("INSIDE_OBJECT_BEFORE_VALUE");
870
- break;
871
- }
872
- }
873
- break;
874
- }
875
- case "INSIDE_OBJECT_BEFORE_VALUE": {
876
- processValueStart(char, i, "INSIDE_OBJECT_AFTER_VALUE");
877
- break;
878
- }
879
- case "INSIDE_OBJECT_AFTER_VALUE": {
880
- processAfterObjectValue(char, i);
881
- break;
882
- }
883
- case "INSIDE_STRING": {
884
- switch (char) {
885
- case '"': {
886
- stack.pop();
887
- lastValidIndex = i;
888
- break;
889
- }
890
- case "\\": {
891
- stack.push("INSIDE_STRING_ESCAPE");
892
- break;
893
- }
894
- default: {
895
- lastValidIndex = i;
896
- }
897
- }
898
- break;
899
- }
900
- case "INSIDE_ARRAY_START": {
901
- switch (char) {
902
- case "]": {
903
- lastValidIndex = i;
904
- stack.pop();
905
- break;
906
- }
907
- default: {
908
- lastValidIndex = i;
909
- processValueStart(char, i, "INSIDE_ARRAY_AFTER_VALUE");
910
- break;
911
- }
912
- }
913
- break;
914
- }
915
- case "INSIDE_ARRAY_AFTER_VALUE": {
916
- switch (char) {
917
- case ",": {
918
- stack.pop();
919
- stack.push("INSIDE_ARRAY_AFTER_COMMA");
920
- break;
921
- }
922
- case "]": {
923
- lastValidIndex = i;
924
- stack.pop();
925
- break;
926
- }
927
- default: {
928
- lastValidIndex = i;
929
- break;
930
- }
931
- }
932
- break;
933
- }
934
- case "INSIDE_ARRAY_AFTER_COMMA": {
935
- processValueStart(char, i, "INSIDE_ARRAY_AFTER_VALUE");
936
- break;
937
- }
938
- case "INSIDE_STRING_ESCAPE": {
939
- stack.pop();
940
- lastValidIndex = i;
941
- break;
942
- }
943
- case "INSIDE_NUMBER": {
944
- switch (char) {
945
- case "0":
946
- case "1":
947
- case "2":
948
- case "3":
949
- case "4":
950
- case "5":
951
- case "6":
952
- case "7":
953
- case "8":
954
- case "9": {
955
- lastValidIndex = i;
956
- break;
957
- }
958
- case "e":
959
- case "E":
960
- case "-":
961
- case ".": {
962
- break;
963
- }
964
- case ",": {
965
- stack.pop();
966
- if (stack[stack.length - 1] === "INSIDE_ARRAY_AFTER_VALUE") {
967
- processAfterArrayValue(char, i);
968
- }
969
- if (stack[stack.length - 1] === "INSIDE_OBJECT_AFTER_VALUE") {
970
- processAfterObjectValue(char, i);
971
- }
972
- break;
973
- }
974
- case "}": {
975
- stack.pop();
976
- if (stack[stack.length - 1] === "INSIDE_OBJECT_AFTER_VALUE") {
977
- processAfterObjectValue(char, i);
978
- }
979
- break;
980
- }
981
- case "]": {
982
- stack.pop();
983
- if (stack[stack.length - 1] === "INSIDE_ARRAY_AFTER_VALUE") {
984
- processAfterArrayValue(char, i);
985
- }
986
- break;
987
- }
988
- default: {
989
- stack.pop();
990
- break;
991
- }
992
- }
993
- break;
994
- }
995
- case "INSIDE_LITERAL": {
996
- const partialLiteral = input.substring(literalStart, i + 1);
997
- if (!"false".startsWith(partialLiteral) && !"true".startsWith(partialLiteral) && !"null".startsWith(partialLiteral)) {
998
- stack.pop();
999
- if (stack[stack.length - 1] === "INSIDE_OBJECT_AFTER_VALUE") {
1000
- processAfterObjectValue(char, i);
1001
- } else if (stack[stack.length - 1] === "INSIDE_ARRAY_AFTER_VALUE") {
1002
- processAfterArrayValue(char, i);
1003
- }
1004
- } else {
1005
- lastValidIndex = i;
1006
- }
1007
- break;
1008
- }
1009
- }
1010
- }
1011
- let result = input.slice(0, lastValidIndex + 1);
1012
- for (let i = stack.length - 1; i >= 0; i--) {
1013
- const state = stack[i];
1014
- switch (state) {
1015
- case "INSIDE_STRING": {
1016
- result += '"';
1017
- break;
1018
- }
1019
- case "INSIDE_OBJECT_KEY":
1020
- case "INSIDE_OBJECT_AFTER_KEY":
1021
- case "INSIDE_OBJECT_AFTER_COMMA":
1022
- case "INSIDE_OBJECT_START":
1023
- case "INSIDE_OBJECT_BEFORE_VALUE":
1024
- case "INSIDE_OBJECT_AFTER_VALUE": {
1025
- result += "}";
1026
- break;
1027
- }
1028
- case "INSIDE_ARRAY_START":
1029
- case "INSIDE_ARRAY_AFTER_COMMA":
1030
- case "INSIDE_ARRAY_AFTER_VALUE": {
1031
- result += "]";
1032
- break;
1033
- }
1034
- case "INSIDE_LITERAL": {
1035
- const partialLiteral = input.substring(literalStart, input.length);
1036
- if ("true".startsWith(partialLiteral)) {
1037
- result += "true".slice(partialLiteral.length);
1038
- } else if ("false".startsWith(partialLiteral)) {
1039
- result += "false".slice(partialLiteral.length);
1040
- } else if ("null".startsWith(partialLiteral)) {
1041
- result += "null".slice(partialLiteral.length);
1042
- }
1043
- }
1044
- }
1045
- }
1046
- return result;
1047
- }
1048
-
1049
- // core/util/parse-partial-json.ts
1050
- function parsePartialJson(jsonText) {
1051
- if (jsonText == null) {
1052
- return void 0;
1053
- }
1054
- try {
1055
- return SecureJSON.parse(jsonText);
1056
- } catch (ignored) {
1057
- try {
1058
- const fixedJsonText = fixJson(jsonText);
1059
- return SecureJSON.parse(fixedJsonText);
1060
- } catch (ignored2) {
1061
- }
700
+ // core/util/prepare-response-headers.ts
701
+ function prepareResponseHeaders(init, { contentType }) {
702
+ var _a;
703
+ const headers = new Headers((_a = init == null ? void 0 : init.headers) != null ? _a : {});
704
+ if (!headers.has("Content-Type")) {
705
+ headers.set("Content-Type", contentType);
1062
706
  }
1063
- return void 0;
707
+ return headers;
1064
708
  }
1065
709
 
1066
710
  // core/generate-object/stream-object.ts
1067
- import { safeValidateTypes } from "@ai-sdk/provider-utils";
1068
711
  async function streamObject({
1069
712
  model,
1070
713
  schema,
@@ -1121,7 +764,7 @@ async function streamObject({
1121
764
  });
1122
765
  callOptions = {
1123
766
  mode: { type: "object-grammar", schema: jsonSchema },
1124
- ...settings,
767
+ ...prepareCallSettings(settings),
1125
768
  inputFormat: validatedPrompt.type,
1126
769
  prompt: convertToLanguageModelPrompt(validatedPrompt),
1127
770
  abortSignal
@@ -1157,7 +800,7 @@ async function streamObject({
1157
800
  parameters: jsonSchema
1158
801
  }
1159
802
  },
1160
- ...settings,
803
+ ...prepareCallSettings(settings),
1161
804
  inputFormat: validatedPrompt.type,
1162
805
  prompt: convertToLanguageModelPrompt(validatedPrompt),
1163
806
  abortSignal
@@ -1218,23 +861,39 @@ var StreamObjectResult = class {
1218
861
  let object;
1219
862
  let error;
1220
863
  let accumulatedText = "";
864
+ let delta = "";
1221
865
  let latestObject = void 0;
1222
866
  this.originalStream = stream.pipeThrough(
1223
867
  new TransformStream({
1224
868
  async transform(chunk, controller) {
1225
869
  if (typeof chunk === "string") {
1226
870
  accumulatedText += chunk;
871
+ delta += chunk;
1227
872
  const currentObject = parsePartialJson(
1228
873
  accumulatedText
1229
874
  );
1230
875
  if (!isDeepEqualData(latestObject, currentObject)) {
1231
876
  latestObject = currentObject;
1232
- controller.enqueue({ type: "object", object: currentObject });
877
+ controller.enqueue({
878
+ type: "object",
879
+ object: currentObject
880
+ });
881
+ controller.enqueue({
882
+ type: "text-delta",
883
+ textDelta: delta
884
+ });
885
+ delta = "";
1233
886
  }
1234
887
  return;
1235
888
  }
1236
889
  switch (chunk.type) {
1237
890
  case "finish": {
891
+ if (delta !== "") {
892
+ controller.enqueue({
893
+ type: "text-delta",
894
+ textDelta: delta
895
+ });
896
+ }
1238
897
  usage = calculateTokenUsage(chunk.usage);
1239
898
  controller.enqueue({ ...chunk, usage });
1240
899
  resolveUsage(usage);
@@ -1278,6 +937,12 @@ var StreamObjectResult = class {
1278
937
  })
1279
938
  );
1280
939
  }
940
+ /**
941
+ Stream of partial objects. It gets more complete as the stream progresses.
942
+
943
+ Note that the partial object is not validated.
944
+ If you want to be certain that the actual content matches your schema, you need to implement your own validation for partial results.
945
+ */
1281
946
  get partialObjectStream() {
1282
947
  return createAsyncIterableStream(this.originalStream, {
1283
948
  transform(chunk, controller) {
@@ -1285,6 +950,32 @@ var StreamObjectResult = class {
1285
950
  case "object":
1286
951
  controller.enqueue(chunk.object);
1287
952
  break;
953
+ case "text-delta":
954
+ case "finish":
955
+ break;
956
+ case "error":
957
+ controller.error(chunk.error);
958
+ break;
959
+ default: {
960
+ const _exhaustiveCheck = chunk;
961
+ throw new Error(`Unsupported chunk type: ${_exhaustiveCheck}`);
962
+ }
963
+ }
964
+ }
965
+ });
966
+ }
967
+ /**
968
+ Text stream of the JSON representation of the generated object. It contains text chunks.
969
+ When the stream is finished, the object is valid JSON that can be parsed.
970
+ */
971
+ get textStream() {
972
+ return createAsyncIterableStream(this.originalStream, {
973
+ transform(chunk, controller) {
974
+ switch (chunk.type) {
975
+ case "text-delta":
976
+ controller.enqueue(chunk.textDelta);
977
+ break;
978
+ case "object":
1288
979
  case "finish":
1289
980
  break;
1290
981
  case "error":
@@ -1298,6 +989,9 @@ var StreamObjectResult = class {
1298
989
  }
1299
990
  });
1300
991
  }
992
+ /**
993
+ Stream of different types of events, including partial objects, errors, and finish events.
994
+ */
1301
995
  get fullStream() {
1302
996
  return createAsyncIterableStream(this.originalStream, {
1303
997
  transform(chunk, controller) {
@@ -1305,6 +999,53 @@ var StreamObjectResult = class {
1305
999
  }
1306
1000
  });
1307
1001
  }
1002
+ /**
1003
+ Writes text delta output to a Node.js response-like object.
1004
+ It sets a `Content-Type` header to `text/plain; charset=utf-8` and
1005
+ writes each text delta as a separate chunk.
1006
+
1007
+ @param response A Node.js response-like object (ServerResponse).
1008
+ @param init Optional headers and status code.
1009
+ */
1010
+ pipeTextStreamToResponse(response, init) {
1011
+ var _a;
1012
+ response.writeHead((_a = init == null ? void 0 : init.status) != null ? _a : 200, {
1013
+ "Content-Type": "text/plain; charset=utf-8",
1014
+ ...init == null ? void 0 : init.headers
1015
+ });
1016
+ const reader = this.textStream.pipeThrough(new TextEncoderStream()).getReader();
1017
+ const read = async () => {
1018
+ try {
1019
+ while (true) {
1020
+ const { done, value } = await reader.read();
1021
+ if (done)
1022
+ break;
1023
+ response.write(value);
1024
+ }
1025
+ } catch (error) {
1026
+ throw error;
1027
+ } finally {
1028
+ response.end();
1029
+ }
1030
+ };
1031
+ read();
1032
+ }
1033
+ /**
1034
+ Creates a simple text stream response.
1035
+ Each text delta is encoded as UTF-8 and sent as a separate chunk.
1036
+ Non-text-delta events are ignored.
1037
+
1038
+ @param init Optional headers and status code.
1039
+ */
1040
+ toTextStreamResponse(init) {
1041
+ var _a;
1042
+ return new Response(this.textStream.pipeThrough(new TextEncoderStream()), {
1043
+ status: (_a = init == null ? void 0 : init.status) != null ? _a : 200,
1044
+ headers: prepareResponseHeaders(init, {
1045
+ contentType: "text/plain; charset=utf-8"
1046
+ })
1047
+ });
1048
+ }
1308
1049
  };
1309
1050
  var experimental_streamObject = streamObject;
1310
1051
 
@@ -1509,16 +1250,6 @@ function toResponseMessages({
1509
1250
  }
1510
1251
  var experimental_generateText = generateText;
1511
1252
 
1512
- // core/util/prepare-response-headers.ts
1513
- function prepareResponseHeaders(init, { contentType }) {
1514
- var _a;
1515
- const headers = new Headers((_a = init == null ? void 0 : init.headers) != null ? _a : {});
1516
- if (!headers.has("Content-Type")) {
1517
- headers.set("Content-Type", contentType);
1518
- }
1519
- return headers;
1520
- }
1521
-
1522
1253
  // core/generate-text/run-tools-transformation.ts
1523
1254
  import { NoSuchToolError as NoSuchToolError2 } from "@ai-sdk/provider";
1524
1255
  import { generateId } from "@ai-sdk/ui-utils";