ai 7.0.102 → 7.0.103

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.
Files changed (35) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/index.d.ts +57 -3
  3. package/dist/index.js +427 -50
  4. package/dist/index.js.map +1 -1
  5. package/dist/internal/index.js +2 -1
  6. package/dist/internal/index.js.map +1 -1
  7. package/dist/test/index.d.ts +16 -2
  8. package/dist/test/index.js +17 -0
  9. package/dist/test/index.js.map +1 -1
  10. package/docs/03-ai-sdk-core/18-code-mode.mdx +39 -0
  11. package/docs/03-ai-sdk-core/32-evaluation.mdx +110 -0
  12. package/docs/03-ai-sdk-core/42-batch.mdx +1 -2
  13. package/docs/04-ai-sdk-ui/03-chatbot-message-persistence.mdx +35 -0
  14. package/docs/06-advanced/11-secure-url-fetching.mdx +8 -2
  15. package/docs/07-reference/01-ai-sdk-core/14-evaluate.mdx +54 -0
  16. package/docs/07-reference/01-ai-sdk-core/32-validate-ui-messages.mdx +12 -0
  17. package/docs/07-reference/01-ai-sdk-core/33-safe-validate-ui-messages.mdx +12 -0
  18. package/docs/07-reference/02-ai-sdk-ui/31-convert-to-model-messages.mdx +12 -0
  19. package/docs/07-reference/05-ai-sdk-errors/ai-evaluation-unsupported-question-type-error.mdx +31 -0
  20. package/package.json +12 -12
  21. package/src/error/index.ts +1 -0
  22. package/src/evaluate/evaluate.ts +112 -0
  23. package/src/evaluate/evaluation-result.ts +39 -0
  24. package/src/evaluate/index.ts +7 -0
  25. package/src/evaluate/validate-evaluation.ts +298 -0
  26. package/src/generate-text/generate-text.ts +16 -12
  27. package/src/generate-text/stream-text.ts +6 -1
  28. package/src/generate-text/tool-caller-configuration.ts +58 -4
  29. package/src/index.ts +1 -0
  30. package/src/test/evaluation-mock-model-v4.ts +27 -0
  31. package/src/ui/convert-to-model-messages.ts +3 -0
  32. package/src/ui/process-ui-message-stream.ts +4 -0
  33. package/src/ui/ui-messages.ts +5 -1
  34. package/src/ui/validate-ui-messages.ts +3 -0
  35. package/src/ui/warn-if-ui-message-has-deprecated-raw-input.ts +36 -0
package/dist/index.js CHANGED
@@ -40,6 +40,7 @@ import {
40
40
  AISDKError as AISDKError25,
41
41
  APICallError,
42
42
  EmptyResponseBodyError,
43
+ Experimental_EvaluationUnsupportedQuestionTypeError,
43
44
  InvalidPromptError,
44
45
  InvalidResponseDataError,
45
46
  JSONParseError,
@@ -1178,7 +1179,7 @@ import {
1178
1179
  } from "@ai-sdk/provider-utils";
1179
1180
 
1180
1181
  // src/version.ts
1181
- var VERSION = true ? "7.0.102" : "0.0.0-test";
1182
+ var VERSION = true ? "7.0.103" : "0.0.0-test";
1182
1183
 
1183
1184
  // src/util/download/download.ts
1184
1185
  var download = async ({
@@ -5248,11 +5249,16 @@ function prepareToolsForToolCallers({
5248
5249
  }) {
5249
5250
  var _a25, _b25;
5250
5251
  if (tools == null || toolCallers == null) {
5251
- return { executionTools: tools, modelTools: tools };
5252
+ return {
5253
+ executionTools: tools,
5254
+ modelTools: tools,
5255
+ toolCallerMessages: []
5256
+ };
5252
5257
  }
5253
5258
  const executionTools = { ...tools };
5254
5259
  const modelTools = { ...tools };
5255
5260
  const localToolsByCaller = /* @__PURE__ */ new Map();
5261
+ const toolCallerMessages = [];
5256
5262
  for (const [toolName, callerNames] of Object.entries(toolCallers)) {
5257
5263
  const tool2 = executionTools[toolName];
5258
5264
  if (tool2 == null) {
@@ -5296,13 +5302,44 @@ function prepareToolsForToolCallers({
5296
5302
  if ((caller == null ? void 0 : caller.type) !== "local") {
5297
5303
  continue;
5298
5304
  }
5299
- const boundCaller = caller.bind((_b25 = localToolsByCaller.get(callerName)) != null ? _b25 : {});
5305
+ const callerTools = (_b25 = localToolsByCaller.get(callerName)) != null ? _b25 : {};
5306
+ const boundCaller = caller.bind(callerTools);
5300
5307
  executionTools[callerName] = boundCaller;
5301
5308
  if (Object.prototype.hasOwnProperty.call(modelTools, callerName)) {
5302
- modelTools[callerName] = boundCaller;
5309
+ if (caller.prepareModelMessage == null) {
5310
+ modelTools[callerName] = boundCaller;
5311
+ } else {
5312
+ const content = caller.prepareModelMessage(callerTools);
5313
+ if (content != null) {
5314
+ toolCallerMessages.push({ role: "user", content });
5315
+ }
5316
+ }
5303
5317
  }
5304
5318
  }
5305
- return { executionTools, modelTools };
5319
+ return { executionTools, modelTools, toolCallerMessages };
5320
+ }
5321
+ function appendToolCallerMessages({
5322
+ messages,
5323
+ toolCallerMessages
5324
+ }) {
5325
+ var _a25;
5326
+ if (toolCallerMessages.length === 0) {
5327
+ return messages;
5328
+ }
5329
+ const latestUserText = (_a25 = messages.findLast(
5330
+ (message) => message.role === "user" && typeof message.content === "string"
5331
+ )) == null ? void 0 : _a25.content;
5332
+ const existingUserText = new Set(
5333
+ latestUserText == null ? [] : [latestUserText]
5334
+ );
5335
+ const additions = toolCallerMessages.filter((message) => {
5336
+ if (typeof message.content !== "string" || existingUserText.has(message.content)) {
5337
+ return false;
5338
+ }
5339
+ existingUserText.add(message.content);
5340
+ return true;
5341
+ });
5342
+ return additions.length === 0 ? messages : [...messages, ...additions];
5306
5343
  }
5307
5344
 
5308
5345
  // src/generate-text/tool-approval-signature.ts
@@ -5825,7 +5862,7 @@ async function generateText({
5825
5862
  type: "step",
5826
5863
  event: { callId, stepNumber },
5827
5864
  execute: async () => {
5828
- var _a27, _b26, _c2, _d2, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q;
5865
+ var _a27, _b26, _c2, _d2, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
5829
5866
  const accumulatedResponseMessages = [
5830
5867
  ...initialResponseMessages,
5831
5868
  ...steps.flatMap((step) => step.response.messages)
@@ -5849,29 +5886,21 @@ async function generateText({
5849
5886
  (_b26 = prepareStepResult == null ? void 0 : prepareStepResult.model) != null ? _b26 : model
5850
5887
  );
5851
5888
  const stepInstructions = (_d2 = (_c2 = prepareStepResult == null ? void 0 : prepareStepResult.instructions) != null ? _c2 : prepareStepResult == null ? void 0 : prepareStepResult.system) != null ? _d2 : instructionsForNextStep;
5852
- const promptMessages = await convertToLanguageModelPrompt({
5853
- prompt: {
5854
- instructions: stepInstructions,
5855
- messages: (_e = prepareStepResult == null ? void 0 : prepareStepResult.messages) != null ? _e : stepInputMessages
5856
- },
5857
- supportedUrls: await stepModel.supportedUrls,
5858
- download: download2,
5859
- provider: stepModel.provider.split(".")[0]
5860
- });
5861
- runtimeContext = (_f = prepareStepResult == null ? void 0 : prepareStepResult.runtimeContext) != null ? _f : runtimeContext;
5862
- toolsContext = (_g = prepareStepResult == null ? void 0 : prepareStepResult.toolsContext) != null ? _g : toolsContext;
5889
+ runtimeContext = (_e = prepareStepResult == null ? void 0 : prepareStepResult.runtimeContext) != null ? _e : runtimeContext;
5890
+ toolsContext = (_f = prepareStepResult == null ? void 0 : prepareStepResult.toolsContext) != null ? _f : toolsContext;
5863
5891
  const stepActiveTools = filterActiveTools({
5864
5892
  tools,
5865
- activeTools: (_h = prepareStepResult == null ? void 0 : prepareStepResult.activeTools) != null ? _h : activeTools
5893
+ activeTools: (_g = prepareStepResult == null ? void 0 : prepareStepResult.activeTools) != null ? _g : activeTools
5866
5894
  });
5867
5895
  const {
5868
5896
  executionTools: stepExecutionTools,
5869
- modelTools: stepModelTools
5897
+ modelTools: stepModelTools,
5898
+ toolCallerMessages
5870
5899
  } = prepareToolsForToolCallers({
5871
5900
  tools: stepActiveTools,
5872
5901
  toolCallers: resolvedToolCallers
5873
5902
  });
5874
- const stepToolOrder = (_i = prepareStepResult == null ? void 0 : prepareStepResult.toolOrder) != null ? _i : toolOrder;
5903
+ const stepToolOrder = (_h = prepareStepResult == null ? void 0 : prepareStepResult.toolOrder) != null ? _h : toolOrder;
5875
5904
  const stepTools = await prepareTools({
5876
5905
  tools: stepModelTools,
5877
5906
  toolOrder: stepToolOrder,
@@ -5880,9 +5909,21 @@ async function generateText({
5880
5909
  experimental_sandbox: stepSandbox
5881
5910
  });
5882
5911
  const stepToolChoice = prepareToolChoice({
5883
- toolChoice: (_j = prepareStepResult == null ? void 0 : prepareStepResult.toolChoice) != null ? _j : toolChoice
5912
+ toolChoice: (_i = prepareStepResult == null ? void 0 : prepareStepResult.toolChoice) != null ? _i : toolChoice
5913
+ });
5914
+ const stepMessages = appendToolCallerMessages({
5915
+ messages: (_j = prepareStepResult == null ? void 0 : prepareStepResult.messages) != null ? _j : stepInputMessages,
5916
+ toolCallerMessages
5917
+ });
5918
+ const promptMessages = await convertToLanguageModelPrompt({
5919
+ prompt: {
5920
+ instructions: stepInstructions,
5921
+ messages: stepMessages
5922
+ },
5923
+ supportedUrls: await stepModel.supportedUrls,
5924
+ download: download2,
5925
+ provider: stepModel.provider.split(".")[0]
5884
5926
  });
5885
- const stepMessages = (_k = prepareStepResult == null ? void 0 : prepareStepResult.messages) != null ? _k : stepInputMessages;
5886
5927
  const stepProviderOptions = mergeObjects(
5887
5928
  providerOptions,
5888
5929
  prepareStepResult == null ? void 0 : prepareStepResult.providerOptions
@@ -5900,8 +5941,8 @@ async function generateText({
5900
5941
  instructions: stepInstructions,
5901
5942
  messages: stepMessages,
5902
5943
  tools,
5903
- toolChoice: (_l = prepareStepResult == null ? void 0 : prepareStepResult.toolChoice) != null ? _l : toolChoice,
5904
- activeTools: (_m = prepareStepResult == null ? void 0 : prepareStepResult.activeTools) != null ? _m : activeTools,
5944
+ toolChoice: (_k = prepareStepResult == null ? void 0 : prepareStepResult.toolChoice) != null ? _k : toolChoice,
5945
+ activeTools: (_l = prepareStepResult == null ? void 0 : prepareStepResult.activeTools) != null ? _l : activeTools,
5905
5946
  toolOrder: stepToolOrder,
5906
5947
  steps: [...steps],
5907
5948
  providerOptions: stepProviderOptions,
@@ -5937,7 +5978,7 @@ async function generateText({
5937
5978
  telemetryDispatcher.onLanguageModelCallStart
5938
5979
  ]
5939
5980
  });
5940
- const executeLanguageModelCallInTelemetryContext = (_n = telemetryDispatcher.executeLanguageModelCall) != null ? _n : (async ({ execute }) => await execute());
5981
+ const executeLanguageModelCallInTelemetryContext = (_m = telemetryDispatcher.executeLanguageModelCall) != null ? _m : (async ({ execute }) => await execute());
5941
5982
  currentModelResponse = await retry(async () => {
5942
5983
  var _a28, _b27, _c3, _d3, _e2, _f2, _g2, _h2;
5943
5984
  const result = await executeLanguageModelCallInTelemetryContext(
@@ -6246,7 +6287,7 @@ async function generateText({
6246
6287
  });
6247
6288
  const stepRequest = {
6248
6289
  ...currentModelResponse.request,
6249
- body: include.requestBody ? (_o = currentModelResponse.request) == null ? void 0 : _o.body : void 0,
6290
+ body: include.requestBody ? (_n = currentModelResponse.request) == null ? void 0 : _n.body : void 0,
6250
6291
  messages: include.requestMessages ? cloneModelMessages(stepMessages) : void 0
6251
6292
  };
6252
6293
  const stepResponse = {
@@ -6254,7 +6295,7 @@ async function generateText({
6254
6295
  // deep clone msgs to avoid mutating step results in multi-step:
6255
6296
  messages: cloneModelMessages(stepResponseMessages),
6256
6297
  // Conditionally include response body:
6257
- body: include.responseBody ? (_p = currentModelResponse.response) == null ? void 0 : _p.body : void 0
6298
+ body: include.responseBody ? (_o = currentModelResponse.response) == null ? void 0 : _o.body : void 0
6258
6299
  };
6259
6300
  const currentStepResult = new DefaultStepResult({
6260
6301
  callId,
@@ -6274,7 +6315,7 @@ async function generateText({
6274
6315
  toolsContext
6275
6316
  });
6276
6317
  logWarnings({
6277
- warnings: (_q = currentModelResponse.warnings) != null ? _q : [],
6318
+ warnings: (_p = currentModelResponse.warnings) != null ? _p : [],
6278
6319
  provider: stepModel.provider,
6279
6320
  model: stepModel.modelId
6280
6321
  });
@@ -6970,6 +7011,25 @@ function getToolName(part) {
6970
7011
  }
6971
7012
  var getToolOrDynamicToolName = getToolName;
6972
7013
 
7014
+ // src/ui/warn-if-ui-message-has-deprecated-raw-input.ts
7015
+ var rawInputDeprecationWarning = {
7016
+ type: "deprecated",
7017
+ setting: "rawInput in output-error UI message parts",
7018
+ message: 'Use the "input" field instead. The "rawInput" field will be removed in the next major version.'
7019
+ };
7020
+ function warnIfUIMessageHasDeprecatedRawInput(messages) {
7021
+ const hasDeprecatedRawInput = messages.some(
7022
+ (message) => message.parts.some(
7023
+ (part) => part != null && typeof part === "object" && "type" in part && typeof part.type === "string" && (part.type === "dynamic-tool" || part.type.startsWith("tool-")) && "state" in part && part.state === "output-error" && Object.prototype.hasOwnProperty.call(part, "rawInput") && "rawInput" in part && part.rawInput !== void 0
7024
+ )
7025
+ );
7026
+ if (hasDeprecatedRawInput) {
7027
+ logWarnings({
7028
+ warnings: [rawInputDeprecationWarning]
7029
+ });
7030
+ }
7031
+ }
7032
+
6973
7033
  // src/ui/process-ui-message-stream.ts
6974
7034
  function createStreamingUIMessageState({
6975
7035
  lastMessage,
@@ -7423,6 +7483,7 @@ function processUIMessageStream({
7423
7483
  providerMetadata: chunk.providerMetadata,
7424
7484
  toolMetadata: chunk.toolMetadata
7425
7485
  });
7486
+ warnIfUIMessageHasDeprecatedRawInput([state.message]);
7426
7487
  }
7427
7488
  write();
7428
7489
  break;
@@ -10380,7 +10441,8 @@ var DefaultStreamTextResult = class {
10380
10441
  });
10381
10442
  const {
10382
10443
  executionTools: stepExecutionTools,
10383
- modelTools: stepModelTools
10444
+ modelTools: stepModelTools,
10445
+ toolCallerMessages
10384
10446
  } = prepareToolsForToolCallers({
10385
10447
  tools: stepActiveTools,
10386
10448
  toolCallers: resolvedToolCallers
@@ -10396,7 +10458,10 @@ var DefaultStreamTextResult = class {
10396
10458
  const stepToolChoice = prepareToolChoice({
10397
10459
  toolChoice: (_h = prepareStepResult == null ? void 0 : prepareStepResult.toolChoice) != null ? _h : toolChoice
10398
10460
  });
10399
- const stepMessages = (_i = prepareStepResult == null ? void 0 : prepareStepResult.messages) != null ? _i : stepInputMessages;
10461
+ const stepMessages = appendToolCallerMessages({
10462
+ messages: (_i = prepareStepResult == null ? void 0 : prepareStepResult.messages) != null ? _i : stepInputMessages,
10463
+ toolCallerMessages
10464
+ });
10400
10465
  currentStepMessages = stepMessages;
10401
10466
  const stepInstructions = (_k = (_j = prepareStepResult == null ? void 0 : prepareStepResult.instructions) != null ? _j : prepareStepResult == null ? void 0 : prepareStepResult.system) != null ? _k : instructionsForNextStep;
10402
10467
  instructionsForNextStep = stepInstructions;
@@ -11684,6 +11749,7 @@ import {
11684
11749
  } from "@ai-sdk/provider-utils";
11685
11750
  async function convertToModelMessages(messages, options) {
11686
11751
  const modelMessages = [];
11752
+ warnIfUIMessageHasDeprecatedRawInput(messages);
11687
11753
  if (options == null ? void 0 : options.ignoreIncompleteToolCalls) {
11688
11754
  messages = messages.map((message) => ({
11689
11755
  ...message,
@@ -12357,6 +12423,7 @@ async function safeValidateUIMessagesInternal({
12357
12423
  value: messages,
12358
12424
  schema: uiMessagesSchema
12359
12425
  });
12426
+ warnIfUIMessageHasDeprecatedRawInput(validatedMessages);
12360
12427
  if (metadataSchema) {
12361
12428
  for (const [msgIdx, message] of validatedMessages.entries()) {
12362
12429
  await validateTypes4({
@@ -13989,10 +14056,318 @@ var DefaultEmbedManyResult = class {
13989
14056
  }
13990
14057
  };
13991
14058
 
14059
+ // src/evaluate/evaluate.ts
14060
+ import {
14061
+ Experimental_EvaluationUnsupportedQuestionTypeError as EvaluationUnsupportedQuestionTypeError
14062
+ } from "@ai-sdk/provider";
14063
+ import {
14064
+ withUserAgentSuffix as withUserAgentSuffix8
14065
+ } from "@ai-sdk/provider-utils";
14066
+
14067
+ // src/evaluate/validate-evaluation.ts
14068
+ import {
14069
+ InvalidResponseDataError as InvalidResponseDataError3
14070
+ } from "@ai-sdk/provider";
14071
+ var tolerance = 1e-6;
14072
+ function isRecord(value) {
14073
+ if (value == null || typeof value !== "object" || Array.isArray(value))
14074
+ return false;
14075
+ const prototype = Object.getPrototypeOf(value);
14076
+ return prototype === Object.prototype || prototype === null;
14077
+ }
14078
+ function isJSON(value, ancestors = /* @__PURE__ */ new Set()) {
14079
+ if (value === null || typeof value === "string" || typeof value === "boolean")
14080
+ return true;
14081
+ if (typeof value === "number") return Number.isFinite(value);
14082
+ if (typeof value !== "object" || !Array.isArray(value) && !isRecord(value))
14083
+ return false;
14084
+ if (ancestors.has(value)) return false;
14085
+ ancestors.add(value);
14086
+ const valid = Object.getOwnPropertySymbols(value).length === 0 && (Array.isArray(value) ? Array.from(value).every((item) => isJSON(item, ancestors)) : Object.values(value).every((item) => isJSON(item, ancestors)));
14087
+ ancestors.delete(value);
14088
+ return valid;
14089
+ }
14090
+ function isInput(value) {
14091
+ return (typeof value === "string" || Array.isArray(value) || isRecord(value)) && isJSON(value);
14092
+ }
14093
+ function invalidInput(parameter, value, message) {
14094
+ throw new InvalidArgumentError({ parameter, value, message });
14095
+ }
14096
+ function validateEvaluationInput({
14097
+ state,
14098
+ questions
14099
+ }) {
14100
+ if (!isInput(state)) {
14101
+ invalidInput(
14102
+ "state",
14103
+ state,
14104
+ "must be a JSON-compatible string, object, or array"
14105
+ );
14106
+ }
14107
+ if (!isRecord(questions) || Object.keys(questions).length === 0) {
14108
+ invalidInput("questions", questions, "must be a nonempty question map");
14109
+ }
14110
+ for (const [id, question] of Object.entries(questions)) {
14111
+ const parameter = `questions.${id}`;
14112
+ if (!isRecord(question) || !isInput(question.instructions)) {
14113
+ invalidInput(
14114
+ parameter,
14115
+ question,
14116
+ "instructions must be a JSON-compatible string, object, or array"
14117
+ );
14118
+ }
14119
+ const criteria = question.criteria;
14120
+ switch (question.type) {
14121
+ case "choice":
14122
+ if (!isRecord(criteria) || Object.keys(criteria).length === 0) {
14123
+ invalidInput(
14124
+ parameter,
14125
+ question,
14126
+ "choice criteria must be a nonempty option map"
14127
+ );
14128
+ }
14129
+ break;
14130
+ case "score":
14131
+ if (!Array.isArray(criteria) || criteria.length < 2) {
14132
+ invalidInput(
14133
+ parameter,
14134
+ question,
14135
+ "score criteria must contain at least two ordered levels"
14136
+ );
14137
+ }
14138
+ break;
14139
+ case "boolean":
14140
+ if (criteria === void 0) continue;
14141
+ if (!isRecord(criteria) || Object.keys(criteria).some((key) => key !== "true" && key !== "false")) {
14142
+ invalidInput(
14143
+ parameter,
14144
+ question,
14145
+ "boolean criteria may only describe true and false"
14146
+ );
14147
+ }
14148
+ break;
14149
+ default:
14150
+ invalidInput(
14151
+ parameter,
14152
+ question,
14153
+ "question type must be choice, score, or boolean"
14154
+ );
14155
+ }
14156
+ if (!isJSON(criteria) || Object.values(criteria).some((value) => value !== null && !isInput(value))) {
14157
+ invalidInput(
14158
+ parameter,
14159
+ question,
14160
+ "criteria descriptions must be JSON-compatible strings, objects, arrays, or null"
14161
+ );
14162
+ }
14163
+ }
14164
+ }
14165
+ function invalidAnswer(answers, message) {
14166
+ throw new InvalidResponseDataError3({ data: answers, message });
14167
+ }
14168
+ function isProbability(value) {
14169
+ return typeof value === "number" && Number.isFinite(value) && value >= 0 && value <= 1;
14170
+ }
14171
+ function hasExactKeys(value, keys) {
14172
+ return Object.keys(value).length === keys.length && keys.every((key) => Object.hasOwn(value, key));
14173
+ }
14174
+ function validateDistribution(value, keys, answers, id, roundingError) {
14175
+ if (!isRecord(value) || !hasExactKeys(value, keys) || !Object.values(value).every(isProbability)) {
14176
+ invalidAnswer(
14177
+ answers,
14178
+ `Question "${id}" must have a complete distribution of finite probabilities in [0, 1].`
14179
+ );
14180
+ }
14181
+ const sum = Object.values(value).reduce(
14182
+ (total, probability) => total + probability,
14183
+ 0
14184
+ );
14185
+ if (Math.abs(sum - 1) > tolerance + keys.length * roundingError) {
14186
+ invalidAnswer(
14187
+ answers,
14188
+ `Question "${id}" probabilities must sum to 1 within the declared rounding precision.`
14189
+ );
14190
+ }
14191
+ }
14192
+ function validateEvaluationAnswers({
14193
+ questions,
14194
+ answers,
14195
+ rounding
14196
+ }) {
14197
+ function roundingError(decimals) {
14198
+ if (decimals === void 0) return 0;
14199
+ if (!Number.isInteger(decimals) || decimals < 0 || decimals > 15) {
14200
+ invalidAnswer(
14201
+ answers,
14202
+ "Evaluation rounding decimals must be integers between 0 and 15."
14203
+ );
14204
+ }
14205
+ return 0.5 * 10 ** -decimals;
14206
+ }
14207
+ const probabilityError = roundingError(rounding == null ? void 0 : rounding.probabilityDecimals);
14208
+ const scoreError = roundingError(rounding == null ? void 0 : rounding.scoreDecimals);
14209
+ if (!isRecord(answers) || !hasExactKeys(answers, Object.keys(questions))) {
14210
+ invalidAnswer(
14211
+ answers,
14212
+ "Evaluation must return exactly one answer for every question."
14213
+ );
14214
+ }
14215
+ for (const [id, question] of Object.entries(questions)) {
14216
+ const answer = answers[id];
14217
+ if (!isRecord(answer) || answer.type !== question.type) {
14218
+ invalidAnswer(
14219
+ answers,
14220
+ `Question "${id}" returned an answer with the wrong type.`
14221
+ );
14222
+ }
14223
+ switch (question.type) {
14224
+ case "choice": {
14225
+ if (typeof answer.choice !== "string" || !Object.hasOwn(question.criteria, answer.choice)) {
14226
+ invalidAnswer(
14227
+ answers,
14228
+ `Question "${id}" selected an unknown option.`
14229
+ );
14230
+ }
14231
+ if (answer.probabilities !== void 0) {
14232
+ validateDistribution(
14233
+ answer.probabilities,
14234
+ Object.keys(question.criteria),
14235
+ answers,
14236
+ id,
14237
+ probabilityError
14238
+ );
14239
+ const selected = answer.probabilities[answer.choice];
14240
+ if (Object.values(answer.probabilities).some(
14241
+ (probability) => probability > selected + tolerance
14242
+ )) {
14243
+ invalidAnswer(
14244
+ answers,
14245
+ `Question "${id}" did not select a highest-probability option.`
14246
+ );
14247
+ }
14248
+ }
14249
+ break;
14250
+ }
14251
+ case "score": {
14252
+ if (typeof answer.score !== "number" || !Number.isFinite(answer.score) || answer.score < 0 || answer.score > question.criteria.length - 1) {
14253
+ invalidAnswer(
14254
+ answers,
14255
+ `Question "${id}" score must be in [0, ${question.criteria.length - 1}].`
14256
+ );
14257
+ }
14258
+ if (answer.probabilities !== void 0) {
14259
+ const keys = question.criteria.map((_, index) => String(index));
14260
+ validateDistribution(
14261
+ answer.probabilities,
14262
+ keys,
14263
+ answers,
14264
+ id,
14265
+ probabilityError
14266
+ );
14267
+ const mean = Object.entries(answer.probabilities).reduce(
14268
+ (total, [index, probability]) => total + Number(index) * probability,
14269
+ 0
14270
+ );
14271
+ const meanRoundingError = keys.reduce(
14272
+ (total, index) => total + Number(index) * probabilityError,
14273
+ 0
14274
+ );
14275
+ if (Math.abs(mean - answer.score) > tolerance + meanRoundingError + scoreError) {
14276
+ invalidAnswer(
14277
+ answers,
14278
+ `Question "${id}" score must equal the probability-weighted mean within the declared rounding precision.`
14279
+ );
14280
+ }
14281
+ }
14282
+ break;
14283
+ }
14284
+ case "boolean":
14285
+ if (!isProbability(answer.probability)) {
14286
+ invalidAnswer(
14287
+ answers,
14288
+ `Question "${id}" must return P(true) as a finite probability in [0, 1].`
14289
+ );
14290
+ }
14291
+ break;
14292
+ }
14293
+ }
14294
+ }
14295
+
14296
+ // src/evaluate/evaluate.ts
14297
+ async function evaluate({
14298
+ model,
14299
+ state,
14300
+ questions,
14301
+ maxRetries,
14302
+ abortSignal,
14303
+ headers,
14304
+ providerOptions = {}
14305
+ }) {
14306
+ var _a25, _b25, _c, _d, _e, _f;
14307
+ if (model.specificationVersion !== "v4") {
14308
+ throw new UnsupportedModelVersionError({
14309
+ version: model.specificationVersion,
14310
+ provider: model.provider,
14311
+ modelId: model.modelId
14312
+ });
14313
+ }
14314
+ validateEvaluationInput({ state, questions });
14315
+ for (const [questionId, question] of Object.entries(questions)) {
14316
+ if (!model.supportedQuestionTypes.includes(question.type)) {
14317
+ throw new EvaluationUnsupportedQuestionTypeError({
14318
+ questionId,
14319
+ questionType: question.type,
14320
+ provider: model.provider,
14321
+ modelId: model.modelId
14322
+ });
14323
+ }
14324
+ }
14325
+ const { retry } = prepareRetries({ maxRetries, abortSignal });
14326
+ const result = await retry(() => {
14327
+ abortSignal == null ? void 0 : abortSignal.throwIfAborted();
14328
+ return model.doEvaluate({
14329
+ state,
14330
+ questions,
14331
+ abortSignal,
14332
+ headers: withUserAgentSuffix8(headers != null ? headers : {}, `ai/${VERSION}`),
14333
+ providerOptions
14334
+ });
14335
+ });
14336
+ abortSignal == null ? void 0 : abortSignal.throwIfAborted();
14337
+ validateEvaluationAnswers({
14338
+ questions,
14339
+ answers: result.answers,
14340
+ rounding: result.rounding
14341
+ });
14342
+ logWarnings({
14343
+ warnings: result.warnings,
14344
+ provider: model.provider,
14345
+ model: model.modelId
14346
+ });
14347
+ const inputTokens = (_a25 = result.usage) == null ? void 0 : _a25.inputTokens;
14348
+ const outputTokens = (_b25 = result.usage) == null ? void 0 : _b25.outputTokens;
14349
+ return {
14350
+ answers: result.answers,
14351
+ usage: {
14352
+ inputTokens,
14353
+ outputTokens,
14354
+ totalTokens: inputTokens != null && outputTokens != null ? inputTokens + outputTokens : void 0
14355
+ },
14356
+ warnings: result.warnings,
14357
+ rounding: result.rounding,
14358
+ providerMetadata: result.providerMetadata,
14359
+ response: {
14360
+ ...result.response,
14361
+ timestamp: (_d = (_c = result.response) == null ? void 0 : _c.timestamp) != null ? _d : /* @__PURE__ */ new Date(),
14362
+ modelId: (_f = (_e = result.response) == null ? void 0 : _e.modelId) != null ? _f : model.modelId
14363
+ }
14364
+ };
14365
+ }
14366
+
13992
14367
  // src/generate-object/generate-object.ts
13993
14368
  import {
13994
14369
  createIdGenerator as createIdGenerator6,
13995
- withUserAgentSuffix as withUserAgentSuffix8
14370
+ withUserAgentSuffix as withUserAgentSuffix9
13996
14371
  } from "@ai-sdk/provider-utils";
13997
14372
 
13998
14373
  // src/generate-text/extract-reasoning-content.ts
@@ -14524,7 +14899,7 @@ async function generateObject(options) {
14524
14899
  enumValues
14525
14900
  });
14526
14901
  const callSettings = prepareLanguageModelCallOptions(settings);
14527
- const headersWithUserAgent = withUserAgentSuffix8(
14902
+ const headersWithUserAgent = withUserAgentSuffix9(
14528
14903
  headers != null ? headers : {},
14529
14904
  `ai/${VERSION}`
14530
14905
  );
@@ -15388,7 +15763,7 @@ var DefaultStreamObjectResult = class {
15388
15763
  // src/generate-speech/generate-speech.ts
15389
15764
  import {
15390
15765
  detectMediaType as detectMediaType4,
15391
- withUserAgentSuffix as withUserAgentSuffix9
15766
+ withUserAgentSuffix as withUserAgentSuffix10
15392
15767
  } from "@ai-sdk/provider-utils";
15393
15768
 
15394
15769
  // src/generate-speech/generated-audio-file.ts
@@ -15435,7 +15810,7 @@ async function generateSpeech({
15435
15810
  if (!resolvedModel) {
15436
15811
  throw new Error("Model could not be resolved");
15437
15812
  }
15438
- const headersWithUserAgent = withUserAgentSuffix9(
15813
+ const headersWithUserAgent = withUserAgentSuffix10(
15439
15814
  headers != null ? headers : {},
15440
15815
  `ai/${VERSION}`
15441
15816
  );
@@ -15745,7 +16120,7 @@ import {
15745
16120
  convertBase64ToUint8Array as convertBase64ToUint8Array5,
15746
16121
  delay as defaultDelay,
15747
16122
  generateId,
15748
- withUserAgentSuffix as withUserAgentSuffix10,
16123
+ withUserAgentSuffix as withUserAgentSuffix11,
15749
16124
  detectMediaType as detectMediaType5
15750
16125
  } from "@ai-sdk/provider-utils";
15751
16126
  var defaultDownload = createDownload();
@@ -15772,7 +16147,7 @@ async function experimental_generateVideo({
15772
16147
  }) {
15773
16148
  var _a25;
15774
16149
  const model = resolveVideoModel(modelArg);
15775
- const headersWithUserAgent = withUserAgentSuffix10(
16150
+ const headersWithUserAgent = withUserAgentSuffix11(
15776
16151
  headers != null ? headers : {},
15777
16152
  `ai/${VERSION}`
15778
16153
  );
@@ -16179,7 +16554,7 @@ async function invokeModelMaxVideosPerCall(model) {
16179
16554
  // src/generate-video/start-video.ts
16180
16555
  import {
16181
16556
  generateId as generateId2,
16182
- withUserAgentSuffix as withUserAgentSuffix11
16557
+ withUserAgentSuffix as withUserAgentSuffix12
16183
16558
  } from "@ai-sdk/provider-utils";
16184
16559
  async function experimental_startVideo({
16185
16560
  model: modelArg,
@@ -16245,7 +16620,7 @@ async function experimental_startVideo({
16245
16620
  generateAudio,
16246
16621
  providerOptions: providerOptions != null ? providerOptions : {},
16247
16622
  headers: {
16248
- ...withUserAgentSuffix11(headers != null ? headers : {}, `ai/${VERSION}`),
16623
+ ...withUserAgentSuffix12(headers != null ? headers : {}, `ai/${VERSION}`),
16249
16624
  ...callerIdempotencyKey ? {} : { "idempotency-key": `aisdk_vid_${generateId2()}` }
16250
16625
  },
16251
16626
  abortSignal,
@@ -16261,7 +16636,7 @@ async function experimental_startVideo({
16261
16636
  }
16262
16637
 
16263
16638
  // src/generate-video/get-video-status.ts
16264
- import { withUserAgentSuffix as withUserAgentSuffix12 } from "@ai-sdk/provider-utils";
16639
+ import { withUserAgentSuffix as withUserAgentSuffix13 } from "@ai-sdk/provider-utils";
16265
16640
  async function experimental_getVideoStatus(modelArg, {
16266
16641
  operation,
16267
16642
  headers,
@@ -16281,7 +16656,7 @@ async function experimental_getVideoStatus(modelArg, {
16281
16656
  return retry(
16282
16657
  () => model.doStatus({
16283
16658
  operation,
16284
- headers: withUserAgentSuffix12(headers != null ? headers : {}, `ai/${VERSION}`),
16659
+ headers: withUserAgentSuffix13(headers != null ? headers : {}, `ai/${VERSION}`),
16285
16660
  abortSignal
16286
16661
  })
16287
16662
  );
@@ -19890,7 +20265,7 @@ var DefaultProviderRegistry = class {
19890
20265
 
19891
20266
  // src/rerank/rerank.ts
19892
20267
  import {
19893
- InvalidResponseDataError as InvalidResponseDataError3
20268
+ InvalidResponseDataError as InvalidResponseDataError4
19894
20269
  } from "@ai-sdk/provider";
19895
20270
  import {
19896
20271
  createIdGenerator as createIdGenerator8
@@ -20136,7 +20511,7 @@ function validateRankingIndices({
20136
20511
  }) {
20137
20512
  for (const { index } of ranking) {
20138
20513
  if (!Number.isInteger(index) || index < 0 || index >= documents.length) {
20139
- throw new InvalidResponseDataError3({
20514
+ throw new InvalidResponseDataError4({
20140
20515
  data: ranking,
20141
20516
  message: `Invalid ranking index ${index}. Expected an integer between 0 and ${documents.length - 1}.`
20142
20517
  });
@@ -20158,7 +20533,7 @@ var DefaultRerankResult = class {
20158
20533
  // src/transcribe/transcribe.ts
20159
20534
  import {
20160
20535
  detectMediaType as detectMediaType6,
20161
- withUserAgentSuffix as withUserAgentSuffix13
20536
+ withUserAgentSuffix as withUserAgentSuffix14
20162
20537
  } from "@ai-sdk/provider-utils";
20163
20538
  var defaultDownload2 = createDownload();
20164
20539
  async function transcribe({
@@ -20178,7 +20553,7 @@ async function transcribe({
20178
20553
  maxRetries: maxRetriesArg,
20179
20554
  abortSignal
20180
20555
  });
20181
- const headersWithUserAgent = withUserAgentSuffix13(
20556
+ const headersWithUserAgent = withUserAgentSuffix14(
20182
20557
  headers != null ? headers : {},
20183
20558
  `ai/${VERSION}`
20184
20559
  );
@@ -20235,7 +20610,7 @@ import {
20235
20610
  } from "@ai-sdk/provider";
20236
20611
  import {
20237
20612
  DelayedPromise as DelayedPromise3,
20238
- withUserAgentSuffix as withUserAgentSuffix14
20613
+ withUserAgentSuffix as withUserAgentSuffix15
20239
20614
  } from "@ai-sdk/provider-utils";
20240
20615
  function streamTranscribe({
20241
20616
  model,
@@ -20259,7 +20634,7 @@ function streamTranscribe({
20259
20634
  message: `The ${resolvedModel.provider} model "${resolvedModel.modelId}" does not support streaming transcription.` + (typeof model === "string" ? " String model IDs resolve through the global provider (AI Gateway by default). If that provider does not support streaming transcription, pass a provider model instance instead (e.g. openai.transcription('gpt-realtime-whisper')) or upgrade @ai-sdk/gateway to a version with streaming transcription support." : "")
20260
20635
  });
20261
20636
  }
20262
- const headersWithUserAgent = withUserAgentSuffix14(
20637
+ const headersWithUserAgent = withUserAgentSuffix15(
20263
20638
  headers != null ? headers : {},
20264
20639
  `ai/${VERSION}`
20265
20640
  );
@@ -20444,7 +20819,7 @@ var experimental_transcribe = transcribe;
20444
20819
  // src/translate/stream-translate.ts
20445
20820
  import {
20446
20821
  DelayedPromise as DelayedPromise4,
20447
- withUserAgentSuffix as withUserAgentSuffix15
20822
+ withUserAgentSuffix as withUserAgentSuffix16
20448
20823
  } from "@ai-sdk/provider-utils";
20449
20824
  function streamTranslate({
20450
20825
  model,
@@ -20461,7 +20836,7 @@ function streamTranslate({
20461
20836
  }) {
20462
20837
  const resolvedModel = resolveSpeechTranslationModel(model);
20463
20838
  const doStream = resolvedModel.doStream.bind(resolvedModel);
20464
- const headersWithUserAgent = withUserAgentSuffix15(
20839
+ const headersWithUserAgent = withUserAgentSuffix16(
20465
20840
  headers != null ? headers : {},
20466
20841
  `ai/${VERSION}`
20467
20842
  );
@@ -20658,7 +21033,7 @@ function streamTranslate({
20658
21033
  // src/ui/call-completion-api.ts
20659
21034
  import {
20660
21035
  parseJsonEventStream,
20661
- withUserAgentSuffix as withUserAgentSuffix16,
21036
+ withUserAgentSuffix as withUserAgentSuffix17,
20662
21037
  getRuntimeEnvironmentUserAgent as getRuntimeEnvironmentUserAgent2
20663
21038
  } from "@ai-sdk/provider-utils";
20664
21039
  import { EmptyResponseBodyError as EmptyResponseBodyError2 } from "@ai-sdk/provider";
@@ -20727,7 +21102,7 @@ async function callCompletionApi({
20727
21102
  ...body
20728
21103
  }),
20729
21104
  credentials,
20730
- headers: withUserAgentSuffix16(
21105
+ headers: withUserAgentSuffix17(
20731
21106
  {
20732
21107
  "Content-Type": "application/json",
20733
21108
  ...headers
@@ -21726,6 +22101,7 @@ export {
21726
22101
  EmptyResponseBodyError,
21727
22102
  AbstractRealtimeSession as Experimental_AbstractRealtimeSession,
21728
22103
  ToolLoopAgent as Experimental_Agent,
22104
+ Experimental_EvaluationUnsupportedQuestionTypeError,
21729
22105
  HttpChatTransport,
21730
22106
  InvalidArgumentError,
21731
22107
  InvalidDataContentError,
@@ -21799,6 +22175,7 @@ export {
21799
22175
  experimental_createProviderRegistry,
21800
22176
  decodeRealtimeAudio as experimental_decodeRealtimeAudio,
21801
22177
  encodeRealtimeAudio as experimental_encodeRealtimeAudio,
22178
+ evaluate as experimental_evaluate,
21802
22179
  filterActiveTools as experimental_filterActiveTools,
21803
22180
  experimental_generateSpeech,
21804
22181
  experimental_generateVideo,