ai 3.2.34 → 3.2.35

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
@@ -13,6 +13,157 @@ import {
13
13
  } from "@ai-sdk/ui-utils";
14
14
  import { generateId as generateIdImpl } from "@ai-sdk/provider-utils";
15
15
 
16
+ // core/telemetry/get-base-telemetry-attributes.ts
17
+ function getBaseTelemetryAttributes({
18
+ operationName,
19
+ model,
20
+ settings,
21
+ telemetry,
22
+ headers
23
+ }) {
24
+ var _a;
25
+ return {
26
+ "ai.model.provider": model.provider,
27
+ "ai.model.id": model.modelId,
28
+ // settings:
29
+ ...Object.entries(settings).reduce((attributes, [key, value]) => {
30
+ attributes[`ai.settings.${key}`] = value;
31
+ return attributes;
32
+ }, {}),
33
+ // special telemetry information
34
+ "operation.name": operationName,
35
+ "resource.name": telemetry == null ? void 0 : telemetry.functionId,
36
+ "ai.telemetry.functionId": telemetry == null ? void 0 : telemetry.functionId,
37
+ // add metadata as attributes:
38
+ ...Object.entries((_a = telemetry == null ? void 0 : telemetry.metadata) != null ? _a : {}).reduce(
39
+ (attributes, [key, value]) => {
40
+ attributes[`ai.telemetry.metadata.${key}`] = value;
41
+ return attributes;
42
+ },
43
+ {}
44
+ ),
45
+ // request headers
46
+ ...Object.entries(headers != null ? headers : {}).reduce((attributes, [key, value]) => {
47
+ if (value !== void 0) {
48
+ attributes[`ai.request.headers.${key}`] = value;
49
+ }
50
+ return attributes;
51
+ }, {})
52
+ };
53
+ }
54
+
55
+ // core/telemetry/get-tracer.ts
56
+ import { trace } from "@opentelemetry/api";
57
+
58
+ // core/telemetry/noop-tracer.ts
59
+ var noopTracer = {
60
+ startSpan() {
61
+ return noopSpan;
62
+ },
63
+ startActiveSpan(name, arg1, arg2, arg3) {
64
+ if (typeof arg1 === "function") {
65
+ return arg1(noopSpan);
66
+ }
67
+ if (typeof arg2 === "function") {
68
+ return arg2(noopSpan);
69
+ }
70
+ if (typeof arg3 === "function") {
71
+ return arg3(noopSpan);
72
+ }
73
+ }
74
+ };
75
+ var noopSpan = {
76
+ spanContext() {
77
+ return noopSpanContext;
78
+ },
79
+ setAttribute() {
80
+ return this;
81
+ },
82
+ setAttributes() {
83
+ return this;
84
+ },
85
+ addEvent() {
86
+ return this;
87
+ },
88
+ addLink() {
89
+ return this;
90
+ },
91
+ addLinks() {
92
+ return this;
93
+ },
94
+ setStatus() {
95
+ return this;
96
+ },
97
+ updateName() {
98
+ return this;
99
+ },
100
+ end() {
101
+ return this;
102
+ },
103
+ isRecording() {
104
+ return false;
105
+ },
106
+ recordException() {
107
+ return this;
108
+ }
109
+ };
110
+ var noopSpanContext = {
111
+ traceId: "",
112
+ spanId: "",
113
+ traceFlags: 0
114
+ };
115
+
116
+ // core/telemetry/get-tracer.ts
117
+ var testTracer = void 0;
118
+ function getTracer({ isEnabled }) {
119
+ if (!isEnabled) {
120
+ return noopTracer;
121
+ }
122
+ if (testTracer) {
123
+ return testTracer;
124
+ }
125
+ return trace.getTracer("ai");
126
+ }
127
+
128
+ // core/telemetry/record-span.ts
129
+ import { SpanStatusCode } from "@opentelemetry/api";
130
+ function recordSpan({
131
+ name,
132
+ tracer,
133
+ attributes,
134
+ fn,
135
+ endWhenDone = true
136
+ }) {
137
+ return tracer.startActiveSpan(name, { attributes }, async (span) => {
138
+ try {
139
+ const result = await fn(span);
140
+ if (endWhenDone) {
141
+ span.end();
142
+ }
143
+ return result;
144
+ } catch (error) {
145
+ try {
146
+ if (error instanceof Error) {
147
+ span.recordException({
148
+ name: error.name,
149
+ message: error.message,
150
+ stack: error.stack
151
+ });
152
+ span.setStatus({
153
+ code: SpanStatusCode.ERROR,
154
+ message: error.message
155
+ });
156
+ } else {
157
+ span.setStatus({ code: SpanStatusCode.ERROR });
158
+ }
159
+ } finally {
160
+ span.end();
161
+ }
162
+ throw error;
163
+ }
164
+ });
165
+ }
166
+
16
167
  // core/util/retry-with-exponential-backoff.ts
17
168
  import { APICallError, RetryError } from "@ai-sdk/provider";
18
169
  import { getErrorMessage, isAbortError } from "@ai-sdk/provider-utils";
@@ -81,18 +232,69 @@ async function embed({
81
232
  value,
82
233
  maxRetries,
83
234
  abortSignal,
84
- headers
235
+ headers,
236
+ experimental_telemetry: telemetry
85
237
  }) {
86
238
  var _a;
87
- const retry = retryWithExponentialBackoff({ maxRetries });
88
- const modelResponse = await retry(
89
- () => model.doEmbed({ values: [value], abortSignal, headers })
90
- );
91
- return new DefaultEmbedResult({
92
- value,
93
- embedding: modelResponse.embeddings[0],
94
- usage: (_a = modelResponse.usage) != null ? _a : { tokens: NaN },
95
- rawResponse: modelResponse.rawResponse
239
+ const baseTelemetryAttributes = getBaseTelemetryAttributes({
240
+ operationName: "ai.embed",
241
+ model,
242
+ telemetry,
243
+ headers,
244
+ settings: { maxRetries }
245
+ });
246
+ const tracer = getTracer({ isEnabled: (_a = telemetry == null ? void 0 : telemetry.isEnabled) != null ? _a : false });
247
+ return recordSpan({
248
+ name: "ai.embed",
249
+ attributes: {
250
+ ...baseTelemetryAttributes,
251
+ // specific settings that only make sense on the outer level:
252
+ "ai.value": JSON.stringify(value)
253
+ },
254
+ tracer,
255
+ fn: async (span) => {
256
+ const retry = retryWithExponentialBackoff({ maxRetries });
257
+ const { embedding, usage, rawResponse } = await retry(
258
+ () => (
259
+ // nested spans to align with the embedMany telemetry data:
260
+ recordSpan({
261
+ name: "ai.embed.doEmbed",
262
+ attributes: {
263
+ ...baseTelemetryAttributes,
264
+ // specific settings that only make sense on the outer level:
265
+ "ai.values": [JSON.stringify(value)]
266
+ },
267
+ tracer,
268
+ fn: async (doEmbedSpan) => {
269
+ var _a2;
270
+ const modelResponse = await model.doEmbed({
271
+ values: [value],
272
+ abortSignal,
273
+ headers
274
+ });
275
+ const embedding2 = modelResponse.embeddings[0];
276
+ const usage2 = (_a2 = modelResponse.usage) != null ? _a2 : { tokens: NaN };
277
+ doEmbedSpan.setAttributes({
278
+ "ai.embeddings": modelResponse.embeddings.map(
279
+ (embedding3) => JSON.stringify(embedding3)
280
+ ),
281
+ "ai.usage.tokens": usage2.tokens
282
+ });
283
+ return {
284
+ embedding: embedding2,
285
+ usage: usage2,
286
+ rawResponse: modelResponse.rawResponse
287
+ };
288
+ }
289
+ })
290
+ )
291
+ );
292
+ span.setAttributes({
293
+ "ai.embedding": JSON.stringify(embedding),
294
+ "ai.usage.tokens": usage.tokens
295
+ });
296
+ return new DefaultEmbedResult({ value, embedding, usage, rawResponse });
297
+ }
96
298
  });
97
299
  }
98
300
  var DefaultEmbedResult = class {
@@ -520,157 +722,6 @@ function prepareCallSettings({
520
722
  };
521
723
  }
522
724
 
523
- // core/telemetry/get-base-telemetry-attributes.ts
524
- function getBaseTelemetryAttributes({
525
- operationName,
526
- model,
527
- settings,
528
- telemetry,
529
- headers
530
- }) {
531
- var _a;
532
- return {
533
- "ai.model.provider": model.provider,
534
- "ai.model.id": model.modelId,
535
- // settings:
536
- ...Object.entries(settings).reduce((attributes, [key, value]) => {
537
- attributes[`ai.settings.${key}`] = value;
538
- return attributes;
539
- }, {}),
540
- // special telemetry information
541
- "operation.name": operationName,
542
- "resource.name": telemetry == null ? void 0 : telemetry.functionId,
543
- "ai.telemetry.functionId": telemetry == null ? void 0 : telemetry.functionId,
544
- // add metadata as attributes:
545
- ...Object.entries((_a = telemetry == null ? void 0 : telemetry.metadata) != null ? _a : {}).reduce(
546
- (attributes, [key, value]) => {
547
- attributes[`ai.telemetry.metadata.${key}`] = value;
548
- return attributes;
549
- },
550
- {}
551
- ),
552
- // request headers
553
- ...Object.entries(headers != null ? headers : {}).reduce((attributes, [key, value]) => {
554
- if (value !== void 0) {
555
- attributes[`ai.request.headers.${key}`] = value;
556
- }
557
- return attributes;
558
- }, {})
559
- };
560
- }
561
-
562
- // core/telemetry/get-tracer.ts
563
- import { trace } from "@opentelemetry/api";
564
-
565
- // core/telemetry/noop-tracer.ts
566
- var noopTracer = {
567
- startSpan() {
568
- return noopSpan;
569
- },
570
- startActiveSpan(name, arg1, arg2, arg3) {
571
- if (typeof arg1 === "function") {
572
- return arg1(noopSpan);
573
- }
574
- if (typeof arg2 === "function") {
575
- return arg2(noopSpan);
576
- }
577
- if (typeof arg3 === "function") {
578
- return arg3(noopSpan);
579
- }
580
- }
581
- };
582
- var noopSpan = {
583
- spanContext() {
584
- return noopSpanContext;
585
- },
586
- setAttribute() {
587
- return this;
588
- },
589
- setAttributes() {
590
- return this;
591
- },
592
- addEvent() {
593
- return this;
594
- },
595
- addLink() {
596
- return this;
597
- },
598
- addLinks() {
599
- return this;
600
- },
601
- setStatus() {
602
- return this;
603
- },
604
- updateName() {
605
- return this;
606
- },
607
- end() {
608
- return this;
609
- },
610
- isRecording() {
611
- return false;
612
- },
613
- recordException() {
614
- return this;
615
- }
616
- };
617
- var noopSpanContext = {
618
- traceId: "",
619
- spanId: "",
620
- traceFlags: 0
621
- };
622
-
623
- // core/telemetry/get-tracer.ts
624
- var testTracer = void 0;
625
- function getTracer({ isEnabled }) {
626
- if (!isEnabled) {
627
- return noopTracer;
628
- }
629
- if (testTracer) {
630
- return testTracer;
631
- }
632
- return trace.getTracer("ai");
633
- }
634
-
635
- // core/telemetry/record-span.ts
636
- import { SpanStatusCode } from "@opentelemetry/api";
637
- function recordSpan({
638
- name,
639
- tracer,
640
- attributes,
641
- fn,
642
- endWhenDone = true
643
- }) {
644
- return tracer.startActiveSpan(name, { attributes }, async (span) => {
645
- try {
646
- const result = await fn(span);
647
- if (endWhenDone) {
648
- span.end();
649
- }
650
- return result;
651
- } catch (error) {
652
- try {
653
- if (error instanceof Error) {
654
- span.recordException({
655
- name: error.name,
656
- message: error.message,
657
- stack: error.stack
658
- });
659
- span.setStatus({
660
- code: SpanStatusCode.ERROR,
661
- message: error.message
662
- });
663
- } else {
664
- span.setStatus({ code: SpanStatusCode.ERROR });
665
- }
666
- } finally {
667
- span.end();
668
- }
669
- throw error;
670
- }
671
- });
672
- }
673
-
674
725
  // core/types/token-usage.ts
675
726
  function calculateCompletionTokenUsage(usage) {
676
727
  return {
@@ -680,12 +731,6 @@ function calculateCompletionTokenUsage(usage) {
680
731
  };
681
732
  }
682
733
 
683
- // core/util/convert-zod-to-json-schema.ts
684
- import zodToJsonSchema from "zod-to-json-schema";
685
- function convertZodToJSONSchema(zodSchema) {
686
- return zodToJsonSchema(zodSchema);
687
- }
688
-
689
734
  // core/util/prepare-response-headers.ts
690
735
  function prepareResponseHeaders(init, { contentType }) {
691
736
  var _a;
@@ -696,6 +741,41 @@ function prepareResponseHeaders(init, { contentType }) {
696
741
  return headers;
697
742
  }
698
743
 
744
+ // core/util/schema.ts
745
+ import { validatorSymbol } from "@ai-sdk/provider-utils";
746
+ import zodToJsonSchema from "zod-to-json-schema";
747
+ var schemaSymbol = Symbol("vercel.ai.schema");
748
+ function jsonSchema(jsonSchema2, {
749
+ validate
750
+ } = {}) {
751
+ return {
752
+ [schemaSymbol]: true,
753
+ _type: void 0,
754
+ // should never be used directly
755
+ [validatorSymbol]: true,
756
+ jsonSchema: jsonSchema2,
757
+ validate
758
+ };
759
+ }
760
+ function isSchema(value) {
761
+ return typeof value === "object" && value !== null && schemaSymbol in value && value[schemaSymbol] === true && "jsonSchema" in value && "validate" in value;
762
+ }
763
+ function asSchema(schema) {
764
+ return isSchema(schema) ? schema : zodSchema(schema);
765
+ }
766
+ function zodSchema(zodSchema2) {
767
+ return jsonSchema(
768
+ // we assume that zodToJsonSchema will return a valid JSONSchema7:
769
+ zodToJsonSchema(zodSchema2),
770
+ {
771
+ validate: (value) => {
772
+ const result = zodSchema2.safeParse(value);
773
+ return result.success ? { success: true, value: result.data } : { success: false, error: result.error };
774
+ }
775
+ }
776
+ );
777
+ }
778
+
699
779
  // core/generate-object/inject-json-schema-into-system.ts
700
780
  var DEFAULT_SCHEMA_PREFIX = "JSON schema:";
701
781
  var DEFAULT_SCHEMA_SUFFIX = "You MUST answer with a JSON object that matches the JSON schema above.";
@@ -718,7 +798,7 @@ function injectJsonSchemaIntoSystem({
718
798
  // core/generate-object/generate-object.ts
719
799
  async function generateObject({
720
800
  model,
721
- schema,
801
+ schema: inputSchema,
722
802
  mode,
723
803
  system,
724
804
  prompt,
@@ -737,7 +817,7 @@ async function generateObject({
737
817
  headers,
738
818
  settings: { ...settings, maxRetries }
739
819
  });
740
- const jsonSchema = convertZodToJSONSchema(schema);
820
+ const schema = asSchema(inputSchema);
741
821
  const tracer = getTracer({ isEnabled: (_a = telemetry == null ? void 0 : telemetry.isEnabled) != null ? _a : false });
742
822
  return recordSpan({
743
823
  name: "ai.generateObject",
@@ -745,7 +825,7 @@ async function generateObject({
745
825
  ...baseTelemetryAttributes,
746
826
  // specific settings that only make sense on the outer level:
747
827
  "ai.prompt": JSON.stringify({ system, prompt, messages }),
748
- "ai.settings.jsonSchema": JSON.stringify(jsonSchema),
828
+ "ai.settings.jsonSchema": JSON.stringify(schema.jsonSchema),
749
829
  "ai.settings.mode": mode
750
830
  },
751
831
  tracer,
@@ -764,7 +844,10 @@ async function generateObject({
764
844
  switch (mode) {
765
845
  case "json": {
766
846
  const validatedPrompt = getValidatedPrompt({
767
- system: injectJsonSchemaIntoSystem({ system, schema: jsonSchema }),
847
+ system: injectJsonSchemaIntoSystem({
848
+ system,
849
+ schema: schema.jsonSchema
850
+ }),
768
851
  prompt,
769
852
  messages
770
853
  });
@@ -836,7 +919,7 @@ async function generateObject({
836
919
  type: "function",
837
920
  name: "json",
838
921
  description: "Respond with a JSON object.",
839
- parameters: jsonSchema
922
+ parameters: schema.jsonSchema
840
923
  }
841
924
  },
842
925
  ...prepareCallSettings(settings),
@@ -985,7 +1068,7 @@ var DelayedPromise = class {
985
1068
  // core/generate-object/stream-object.ts
986
1069
  async function streamObject({
987
1070
  model,
988
- schema,
1071
+ schema: inputSchema,
989
1072
  mode,
990
1073
  system,
991
1074
  prompt,
@@ -997,7 +1080,7 @@ async function streamObject({
997
1080
  ...settings
998
1081
  }) {
999
1082
  const retry = retryWithExponentialBackoff({ maxRetries });
1000
- const jsonSchema = convertZodToJSONSchema(schema);
1083
+ const schema = asSchema(inputSchema);
1001
1084
  if (mode === "auto" || mode == null) {
1002
1085
  mode = model.defaultObjectGenerationMode;
1003
1086
  }
@@ -1006,7 +1089,10 @@ async function streamObject({
1006
1089
  switch (mode) {
1007
1090
  case "json": {
1008
1091
  const validatedPrompt = getValidatedPrompt({
1009
- system: injectJsonSchemaIntoSystem({ system, schema: jsonSchema }),
1092
+ system: injectJsonSchemaIntoSystem({
1093
+ system,
1094
+ schema: schema.jsonSchema
1095
+ }),
1010
1096
  prompt,
1011
1097
  messages
1012
1098
  });
@@ -1046,7 +1132,7 @@ async function streamObject({
1046
1132
  type: "function",
1047
1133
  name: "json",
1048
1134
  description: "Respond with a JSON object.",
1049
- parameters: jsonSchema
1135
+ parameters: schema.jsonSchema
1050
1136
  }
1051
1137
  },
1052
1138
  ...prepareCallSettings(settings),
@@ -1291,7 +1377,7 @@ function prepareToolsAndToolChoice({
1291
1377
  type: "function",
1292
1378
  name,
1293
1379
  description: tool2.description,
1294
- parameters: convertZodToJSONSchema(tool2.parameters)
1380
+ parameters: asSchema(tool2.parameters).jsonSchema
1295
1381
  })),
1296
1382
  toolChoice: toolChoice == null ? { type: "auto" } : typeof toolChoice === "string" ? { type: toolChoice } : { type: "tool", toolName: toolChoice.toolName }
1297
1383
  };
@@ -1320,7 +1406,7 @@ function parseToolCall({
1320
1406
  }
1321
1407
  const parseResult = safeParseJSON2({
1322
1408
  text: toolCall.args,
1323
- schema: tool2.parameters
1409
+ schema: asSchema(tool2.parameters)
1324
1410
  });
1325
1411
  if (parseResult.success === false) {
1326
1412
  throw new InvalidToolArgumentsError({
@@ -3623,6 +3709,7 @@ export {
3623
3709
  generateId2 as generateId,
3624
3710
  generateObject,
3625
3711
  generateText,
3712
+ jsonSchema,
3626
3713
  nanoid,
3627
3714
  parseComplexResponse,
3628
3715
  parseStreamPart,