ai 7.0.93 → 7.0.94

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.js CHANGED
@@ -7,7 +7,7 @@ var __export = (target, all) => {
7
7
  // src/index.ts
8
8
  import {
9
9
  createGateway,
10
- gateway as gateway2
10
+ gateway as gateway3
11
11
  } from "@ai-sdk/gateway";
12
12
  import {
13
13
  asSchema as asSchema8,
@@ -1178,7 +1178,7 @@ import {
1178
1178
  } from "@ai-sdk/provider-utils";
1179
1179
 
1180
1180
  // src/version.ts
1181
- var VERSION = true ? "7.0.93" : "0.0.0-test";
1181
+ var VERSION = true ? "7.0.94" : "0.0.0-test";
1182
1182
 
1183
1183
  // src/util/download/download.ts
1184
1184
  var download = async ({
@@ -2813,13 +2813,14 @@ var retryWithExponentialBackoffRespectingRetryHeaders = ({
2813
2813
  maxRetries = 2,
2814
2814
  initialDelayInMs = 2e3,
2815
2815
  backoffFactor = 2,
2816
- abortSignal
2816
+ abortSignal,
2817
+ additionalRetryableError
2817
2818
  } = {}) => retryWithExponentialBackoff({
2818
2819
  maxRetries,
2819
2820
  initialDelayInMs,
2820
2821
  backoffFactor,
2821
2822
  abortSignal,
2822
- shouldRetry: (error) => error instanceof Error && (APICallError2.isInstance(error) && error.isRetryable === true || GatewayError.isInstance(error) && error.isRetryable === true),
2823
+ shouldRetry: async (error) => error instanceof Error && (APICallError2.isInstance(error) && error.isRetryable === true || GatewayError.isInstance(error) && error.isRetryable === true) || additionalRetryableError != null && await additionalRetryableError(error),
2823
2824
  getDelayInMs: ({ error, exponentialBackoffDelay }) => getRetryDelayInMs({
2824
2825
  error,
2825
2826
  exponentialBackoffDelay
@@ -2831,6 +2832,7 @@ var retryWithExponentialBackoffRespectingRetryHeaders = ({
2831
2832
  function prepareRetries({
2832
2833
  maxRetries,
2833
2834
  abortSignal,
2835
+ additionalRetryableError,
2834
2836
  parameter = "maxRetries",
2835
2837
  defaultMaxRetries = 2
2836
2838
  }) {
@@ -2855,7 +2857,8 @@ function prepareRetries({
2855
2857
  maxRetries: maxRetriesResult,
2856
2858
  retry: retryWithExponentialBackoffRespectingRetryHeaders({
2857
2859
  maxRetries: maxRetriesResult,
2858
- abortSignal
2860
+ abortSignal,
2861
+ additionalRetryableError
2859
2862
  })
2860
2863
  };
2861
2864
  }
@@ -8792,6 +8795,7 @@ async function streamLanguageModelCall({
8792
8795
  callId: effectiveCallId,
8793
8796
  provider: resolvedModel.provider,
8794
8797
  modelId: resolvedModel.modelId,
8798
+ toolChoice: stepToolChoice,
8795
8799
  generateId: generateId4,
8796
8800
  now: now2,
8797
8801
  callStartTimestampMs,
@@ -8813,6 +8817,7 @@ function createLanguageModelV4StreamPartToLanguageModelStreamPartTransform({
8813
8817
  callId,
8814
8818
  provider,
8815
8819
  modelId,
8820
+ toolChoice,
8816
8821
  generateId: generateId4,
8817
8822
  now: now2,
8818
8823
  callStartTimestampMs,
@@ -8820,8 +8825,11 @@ function createLanguageModelV4StreamPartToLanguageModelStreamPartTransform({
8820
8825
  }) {
8821
8826
  const toolCallsByToolCallId = /* @__PURE__ */ new Map();
8822
8827
  const modelCallContent = [];
8828
+ const rawModelCallContent = [];
8823
8829
  const textPartIndexes = /* @__PURE__ */ new Map();
8824
8830
  const reasoningPartIndexes = /* @__PURE__ */ new Map();
8831
+ const rawTextPartIndexes = /* @__PURE__ */ new Map();
8832
+ const rawReasoningPartIndexes = /* @__PURE__ */ new Map();
8825
8833
  let responseId = generateId4();
8826
8834
  let responseModelId = modelId;
8827
8835
  let timeToFirstOutputMs;
@@ -8851,7 +8859,9 @@ function createLanguageModelV4StreamPartToLanguageModelStreamPartTransform({
8851
8859
  case "text-start":
8852
8860
  upsertTextContentPart({
8853
8861
  content: modelCallContent,
8862
+ rawContent: rawModelCallContent,
8854
8863
  partIndexes: textPartIndexes,
8864
+ rawPartIndexes: rawTextPartIndexes,
8855
8865
  id: chunk.id,
8856
8866
  type: "text",
8857
8867
  providerMetadata: chunk.providerMetadata
@@ -8861,7 +8871,9 @@ function createLanguageModelV4StreamPartToLanguageModelStreamPartTransform({
8861
8871
  case "text-delta":
8862
8872
  upsertTextContentPart({
8863
8873
  content: modelCallContent,
8874
+ rawContent: rawModelCallContent,
8864
8875
  partIndexes: textPartIndexes,
8876
+ rawPartIndexes: rawTextPartIndexes,
8865
8877
  id: chunk.id,
8866
8878
  type: "text",
8867
8879
  textDelta: chunk.delta,
@@ -8877,18 +8889,23 @@ function createLanguageModelV4StreamPartToLanguageModelStreamPartTransform({
8877
8889
  case "text-end":
8878
8890
  upsertTextContentPart({
8879
8891
  content: modelCallContent,
8892
+ rawContent: rawModelCallContent,
8880
8893
  partIndexes: textPartIndexes,
8894
+ rawPartIndexes: rawTextPartIndexes,
8881
8895
  id: chunk.id,
8882
8896
  type: "text",
8883
8897
  providerMetadata: chunk.providerMetadata
8884
8898
  });
8885
8899
  textPartIndexes.delete(chunk.id);
8900
+ rawTextPartIndexes.delete(chunk.id);
8886
8901
  controller.enqueue(chunk);
8887
8902
  break;
8888
8903
  case "reasoning-start":
8889
8904
  upsertTextContentPart({
8890
8905
  content: modelCallContent,
8906
+ rawContent: rawModelCallContent,
8891
8907
  partIndexes: reasoningPartIndexes,
8908
+ rawPartIndexes: rawReasoningPartIndexes,
8892
8909
  id: chunk.id,
8893
8910
  type: "reasoning",
8894
8911
  providerMetadata: chunk.providerMetadata
@@ -8898,7 +8915,9 @@ function createLanguageModelV4StreamPartToLanguageModelStreamPartTransform({
8898
8915
  case "reasoning-delta":
8899
8916
  upsertTextContentPart({
8900
8917
  content: modelCallContent,
8918
+ rawContent: rawModelCallContent,
8901
8919
  partIndexes: reasoningPartIndexes,
8920
+ rawPartIndexes: rawReasoningPartIndexes,
8902
8921
  id: chunk.id,
8903
8922
  type: "reasoning",
8904
8923
  textDelta: chunk.delta,
@@ -8914,12 +8933,15 @@ function createLanguageModelV4StreamPartToLanguageModelStreamPartTransform({
8914
8933
  case "reasoning-end":
8915
8934
  upsertTextContentPart({
8916
8935
  content: modelCallContent,
8936
+ rawContent: rawModelCallContent,
8917
8937
  partIndexes: reasoningPartIndexes,
8938
+ rawPartIndexes: rawReasoningPartIndexes,
8918
8939
  id: chunk.id,
8919
8940
  type: "reasoning",
8920
8941
  providerMetadata: chunk.providerMetadata
8921
8942
  });
8922
8943
  reasoningPartIndexes.delete(chunk.id);
8944
+ rawReasoningPartIndexes.delete(chunk.id);
8923
8945
  controller.enqueue(chunk);
8924
8946
  break;
8925
8947
  case "file":
@@ -8933,6 +8955,7 @@ function createLanguageModelV4StreamPartToLanguageModelStreamPartTransform({
8933
8955
  file,
8934
8956
  ...chunk.providerMetadata != null ? { providerMetadata: chunk.providerMetadata } : {}
8935
8957
  });
8958
+ rawModelCallContent.push(chunk);
8936
8959
  controller.enqueue({
8937
8960
  type: chunk.type,
8938
8961
  file,
@@ -8986,9 +9009,26 @@ function createLanguageModelV4StreamPartToLanguageModelStreamPartTransform({
8986
9009
  providerMetadata: chunk.providerMetadata,
8987
9010
  performance
8988
9011
  });
9012
+ const enforcedToolChoice = toolChoice.type === "required" || toolChoice.type === "tool" ? toolChoice : void 0;
9013
+ if (enforcedToolChoice != null && ![...toolCallsByToolCallId.values()].some(
9014
+ (toolCall) => enforcedToolChoice.type === "required" || toolCall.toolName === enforcedToolChoice.toolName
9015
+ )) {
9016
+ controller.enqueue({
9017
+ type: "error",
9018
+ error: new ToolChoiceViolationError({
9019
+ toolChoice: enforcedToolChoice,
9020
+ finishReason: chunk.finishReason.unified,
9021
+ provider,
9022
+ modelId,
9023
+ content: rawModelCallContent
9024
+ })
9025
+ });
9026
+ break;
9027
+ }
8989
9028
  break;
8990
9029
  }
8991
9030
  case "tool-call": {
9031
+ rawModelCallContent.push(chunk);
8992
9032
  try {
8993
9033
  const toolCall = await parseToolCall({
8994
9034
  toolCall: chunk,
@@ -9022,6 +9062,7 @@ function createLanguageModelV4StreamPartToLanguageModelStreamPartTransform({
9022
9062
  break;
9023
9063
  }
9024
9064
  case "tool-approval-request": {
9065
+ rawModelCallContent.push(chunk);
9025
9066
  const toolCall = toolCallsByToolCallId.get(chunk.toolCallId);
9026
9067
  if (toolCall == null) {
9027
9068
  controller.enqueue({
@@ -9043,6 +9084,7 @@ function createLanguageModelV4StreamPartToLanguageModelStreamPartTransform({
9043
9084
  break;
9044
9085
  }
9045
9086
  case "tool-result": {
9087
+ rawModelCallContent.push(chunk);
9046
9088
  const toolName = chunk.toolName;
9047
9089
  const toolCall = toolCallsByToolCallId.get(chunk.toolCallId);
9048
9090
  const toolResultPart = chunk.isError ? {
@@ -9101,6 +9143,7 @@ function createLanguageModelV4StreamPartToLanguageModelStreamPartTransform({
9101
9143
  default:
9102
9144
  if (chunk.type === "custom" || chunk.type === "source") {
9103
9145
  modelCallContent.push(chunk);
9146
+ rawModelCallContent.push(chunk);
9104
9147
  }
9105
9148
  controller.enqueue(chunk);
9106
9149
  break;
@@ -9128,7 +9171,9 @@ function calculateNearestRankPercentile(sortedValues, percentile) {
9128
9171
  }
9129
9172
  function upsertTextContentPart({
9130
9173
  content,
9174
+ rawContent,
9131
9175
  partIndexes,
9176
+ rawPartIndexes,
9132
9177
  id,
9133
9178
  type,
9134
9179
  textDelta,
@@ -9143,12 +9188,24 @@ function upsertTextContentPart({
9143
9188
  }) - 1;
9144
9189
  partIndexes.set(id, partIndex);
9145
9190
  }
9191
+ let rawPartIndex = rawPartIndexes.get(id);
9192
+ if (rawPartIndex == null) {
9193
+ rawPartIndex = rawContent.push({
9194
+ type,
9195
+ text: "",
9196
+ ...providerMetadata != null ? { providerMetadata } : {}
9197
+ }) - 1;
9198
+ rawPartIndexes.set(id, rawPartIndex);
9199
+ }
9146
9200
  const part = content[partIndex];
9201
+ const rawPart = rawContent[rawPartIndex];
9147
9202
  if (textDelta != null) {
9148
9203
  part.text += textDelta;
9204
+ rawPart.text += textDelta;
9149
9205
  }
9150
9206
  if (providerMetadata != null) {
9151
9207
  part.providerMetadata = providerMetadata;
9208
+ rawPart.providerMetadata = providerMetadata;
9152
9209
  }
9153
9210
  }
9154
9211
 
@@ -10492,14 +10549,15 @@ var DefaultStreamTextResult = class {
10492
10549
  callbacks: onChunk
10493
10550
  });
10494
10551
  const error = wrapGatewayError(value.error);
10552
+ const isToolChoiceViolation = ToolChoiceViolationError.isInstance(error);
10495
10553
  let onErrorResult;
10496
10554
  try {
10497
10555
  onErrorResult = await onError({ error });
10498
10556
  } catch (e) {
10499
10557
  }
10500
10558
  const callbackRequestedRetry = canRetryStreamViaOnError && typeof onErrorResult === "object" && onErrorResult != null && "retry" in onErrorResult && onErrorResult.retry === true;
10501
- const automaticRetry = automaticStreamRetryCount < streamRetries;
10502
- const callbackRetry = !automaticRetry && callbackRequestedRetry && callbackStreamRetryCount < 1;
10559
+ const automaticRetry = !isToolChoiceViolation && automaticStreamRetryCount < streamRetries;
10560
+ const callbackRetry = !isToolChoiceViolation && !automaticRetry && callbackRequestedRetry && callbackStreamRetryCount < 1;
10503
10561
  if (!automaticRetry && !callbackRetry) {
10504
10562
  flushBufferedAttemptParts();
10505
10563
  errorsHandledForStreamRetry.add(value.error);
@@ -12522,14 +12580,40 @@ async function pipeAgentUIStreamToResponse({
12522
12580
  import {
12523
12581
  UnsupportedFunctionalityError as UnsupportedFunctionalityError3
12524
12582
  } from "@ai-sdk/provider";
12583
+ import { gateway as gateway2 } from "@ai-sdk/gateway";
12525
12584
  import { withUserAgentSuffix as withUserAgentSuffix4 } from "@ai-sdk/provider-utils";
12526
- async function startTextBatch({
12527
- model: modelArg,
12585
+
12586
+ // src/util/is-deep-equal-data.ts
12587
+ function isDeepEqualData(obj1, obj2) {
12588
+ if (obj1 === obj2) return true;
12589
+ if (obj1 == null || obj2 == null) return false;
12590
+ if (typeof obj1 !== "object" && typeof obj2 !== "object")
12591
+ return obj1 === obj2;
12592
+ if (obj1.constructor !== obj2.constructor) return false;
12593
+ if (obj1 instanceof Date && obj2 instanceof Date) {
12594
+ return obj1.getTime() === obj2.getTime();
12595
+ }
12596
+ if (Array.isArray(obj1)) {
12597
+ if (obj1.length !== obj2.length) return false;
12598
+ for (let i = 0; i < obj1.length; i++) {
12599
+ if (!isDeepEqualData(obj1[i], obj2[i])) return false;
12600
+ }
12601
+ return true;
12602
+ }
12603
+ const keys1 = Object.keys(obj1);
12604
+ const keys2 = Object.keys(obj2);
12605
+ if (keys1.length !== keys2.length) return false;
12606
+ for (const key of keys1) {
12607
+ if (!keys2.includes(key)) return false;
12608
+ if (!isDeepEqualData(obj1[key], obj2[key])) return false;
12609
+ }
12610
+ return true;
12611
+ }
12612
+
12613
+ // src/batch/batch.ts
12614
+ async function startBatch({
12615
+ provider,
12528
12616
  requests,
12529
- tools,
12530
- toolChoice,
12531
- toolOrder,
12532
- toolsContext,
12533
12617
  providerOptions,
12534
12618
  webhookUrl,
12535
12619
  abortSignal,
@@ -12537,37 +12621,49 @@ async function startTextBatch({
12537
12621
  timeout
12538
12622
  }) {
12539
12623
  validateRequests(requests);
12540
- const model = resolveBatchLanguageModel(modelArg);
12624
+ const batchApi = resolveBatchApi(provider);
12541
12625
  const operationAbortSignal = mergeAbortSignals(
12542
12626
  abortSignal,
12543
12627
  getTotalTimeoutMs(timeout)
12544
12628
  );
12545
- const supportedUrls = await model.supportedUrls;
12546
- const preparedTools = await prepareTools({
12547
- tools,
12548
- toolOrder,
12549
- toolsContext
12550
- });
12551
- const preparedToolChoice = prepareToolChoice({ toolChoice });
12629
+ const supportedUrls = await batchApi.supportedUrls;
12552
12630
  operationAbortSignal == null ? void 0 : operationAbortSignal.throwIfAborted();
12553
12631
  const normalizedRequests = [];
12632
+ const toolsByName = /* @__PURE__ */ new Map();
12554
12633
  for (const request of requests) {
12555
- const standardizedPrompt = await standardizePrompt(request);
12556
- normalizedRequests.push({
12557
- id: request.id,
12558
- options: {
12559
- ...prepareLanguageModelCallOptions(request),
12560
- prompt: await convertToLanguageModelPrompt({
12561
- prompt: standardizedPrompt,
12562
- supportedUrls,
12563
- download: void 0,
12564
- provider: model.provider.split(".")[0]
12565
- }),
12566
- tools: preparedTools,
12567
- toolChoice: preparedToolChoice,
12568
- providerOptions: request.providerOptions
12634
+ switch (request.type) {
12635
+ case "text": {
12636
+ const standardizedPrompt = await standardizePrompt(request);
12637
+ const preparedTools = await prepareTools({
12638
+ tools: request.tools,
12639
+ toolOrder: request.toolOrder,
12640
+ toolsContext: request.toolsContext
12641
+ });
12642
+ validateCompatibleTools({
12643
+ requestId: request.id,
12644
+ tools: preparedTools,
12645
+ toolsByName
12646
+ });
12647
+ normalizedRequests.push({
12648
+ id: request.id,
12649
+ type: request.type,
12650
+ modelId: request.model,
12651
+ options: {
12652
+ ...prepareLanguageModelCallOptions(request),
12653
+ prompt: await convertToLanguageModelPrompt({
12654
+ prompt: standardizedPrompt,
12655
+ supportedUrls,
12656
+ download: void 0,
12657
+ provider: batchApi.provider.split(".")[0]
12658
+ }),
12659
+ tools: preparedTools,
12660
+ toolChoice: prepareToolChoice({ toolChoice: request.toolChoice }),
12661
+ providerOptions: request.providerOptions
12662
+ }
12663
+ });
12664
+ break;
12569
12665
  }
12570
- });
12666
+ }
12571
12667
  operationAbortSignal == null ? void 0 : operationAbortSignal.throwIfAborted();
12572
12668
  }
12573
12669
  const headersWithUserAgent = withUserAgentSuffix4(
@@ -12575,7 +12671,7 @@ async function startTextBatch({
12575
12671
  `ai/${VERSION}`
12576
12672
  );
12577
12673
  try {
12578
- const result = await model.experimental_doStartBatch({
12674
+ const result = await batchApi.doStartBatch({
12579
12675
  requests: normalizedRequests,
12580
12676
  providerOptions,
12581
12677
  abortSignal: operationAbortSignal,
@@ -12583,17 +12679,20 @@ async function startTextBatch({
12583
12679
  ...webhookUrl != null && { webhookUrl }
12584
12680
  });
12585
12681
  const { batchId, warnings, ...status } = result;
12586
- logWarnings({
12587
- warnings: warnings.map(({ warning }) => warning),
12588
- provider: model.provider,
12589
- model: model.modelId
12590
- });
12682
+ const modelByRequestId = new Map(
12683
+ normalizedRequests.map((request) => [request.id, request.modelId])
12684
+ );
12685
+ for (const { requestId, warning } of warnings) {
12686
+ logWarnings({
12687
+ warnings: [warning],
12688
+ provider: batchApi.provider,
12689
+ model: requestId == null ? void 0 : modelByRequestId.get(requestId)
12690
+ });
12691
+ }
12591
12692
  return {
12592
- version: 1,
12593
- type: "text",
12693
+ version: 2,
12594
12694
  id: batchId,
12595
- provider: model.provider,
12596
- modelId: model.modelId,
12695
+ provider: batchApi.provider,
12597
12696
  ...status,
12598
12697
  warnings
12599
12698
  };
@@ -12601,8 +12700,25 @@ async function startTextBatch({
12601
12700
  throw wrapGatewayError(error);
12602
12701
  }
12603
12702
  }
12703
+ function validateCompatibleTools({
12704
+ requestId,
12705
+ tools,
12706
+ toolsByName
12707
+ }) {
12708
+ for (const tool2 of tools != null ? tools : []) {
12709
+ const previousTool = toolsByName.get(tool2.name);
12710
+ if (previousTool != null && !isDeepEqualData(previousTool, tool2)) {
12711
+ throw new InvalidArgumentError({
12712
+ parameter: "requests",
12713
+ value: requestId,
12714
+ message: `tool "${tool2.name}" must have the same definition in every batch request`
12715
+ });
12716
+ }
12717
+ toolsByName.set(tool2.name, tool2);
12718
+ }
12719
+ }
12604
12720
  async function getBatchStatus({
12605
- model: modelArg,
12721
+ provider,
12606
12722
  batch,
12607
12723
  providerOptions,
12608
12724
  maxRetries,
@@ -12610,8 +12726,8 @@ async function getBatchStatus({
12610
12726
  headers,
12611
12727
  timeout
12612
12728
  }) {
12613
- const model = resolveBatchLanguageModel(modelArg);
12614
- validateBatchReference({ model, batch });
12729
+ const batchApi = resolveBatchApi(provider);
12730
+ validateBatchReference({ batchApi, batch });
12615
12731
  const operationAbortSignal = mergeAbortSignals(
12616
12732
  abortSignal,
12617
12733
  getTotalTimeoutMs(timeout)
@@ -12622,7 +12738,7 @@ async function getBatchStatus({
12622
12738
  });
12623
12739
  try {
12624
12740
  const status = await retry(
12625
- () => model.experimental_doGetBatchStatus({
12741
+ () => batchApi.doGetBatchStatus({
12626
12742
  batchId: batch.id,
12627
12743
  providerOptions,
12628
12744
  abortSignal: operationAbortSignal,
@@ -12635,7 +12751,7 @@ async function getBatchStatus({
12635
12751
  }
12636
12752
  }
12637
12753
  function getBatchResults({
12638
- model: modelArg,
12754
+ provider,
12639
12755
  batch,
12640
12756
  tools,
12641
12757
  providerOptions,
@@ -12644,8 +12760,8 @@ function getBatchResults({
12644
12760
  headers,
12645
12761
  timeout
12646
12762
  }) {
12647
- const model = resolveBatchLanguageModel(modelArg);
12648
- validateBatchReference({ model, batch });
12763
+ const batchApi = resolveBatchApi(provider);
12764
+ validateBatchReference({ batchApi, batch });
12649
12765
  const streamAbortController = new AbortController();
12650
12766
  const operationAbortSignal = mergeAbortSignals(
12651
12767
  abortSignal,
@@ -12670,7 +12786,7 @@ function getBatchResults({
12670
12786
  void (async () => {
12671
12787
  try {
12672
12788
  const stream = await retry(
12673
- () => model.experimental_doGetBatchResults({
12789
+ () => batchApi.doGetBatchResults({
12674
12790
  batchId: batch.id,
12675
12791
  providerOptions,
12676
12792
  abortSignal: operationAbortSignal,
@@ -12687,19 +12803,26 @@ function getBatchResults({
12687
12803
  })();
12688
12804
  return asAsyncIterableStream(transform.readable);
12689
12805
  }
12690
- function resolveBatchLanguageModel(modelArg) {
12691
- const model = resolveLanguageModel(modelArg);
12692
- if (!isBatchLanguageModel(model)) {
12806
+ function resolveBatchApi(provider) {
12807
+ var _a25;
12808
+ provider != null ? provider : provider = asProviderV4((_a25 = globalThis.AI_SDK_DEFAULT_PROVIDER) != null ? _a25 : gateway2);
12809
+ if (isBatchApi(provider)) {
12810
+ return provider;
12811
+ }
12812
+ if (!hasBatchFactory(provider)) {
12693
12813
  throw new UnsupportedFunctionalityError3({
12694
12814
  functionality: "batch processing",
12695
- message: `The ${model.provider} model "${model.modelId}" does not support batch processing.`
12815
+ message: "The provider does not support batch processing. Make sure it exposes an experimental_batch() method."
12696
12816
  });
12697
12817
  }
12698
- return model;
12818
+ return provider.experimental_batch();
12699
12819
  }
12700
- function isBatchLanguageModel(model) {
12701
- const candidate = model;
12702
- return typeof candidate.experimental_doStartBatch === "function" && typeof candidate.experimental_doGetBatchStatus === "function" && typeof candidate.experimental_doGetBatchResults === "function";
12820
+ function hasBatchFactory(provider) {
12821
+ return typeof provider.experimental_batch === "function";
12822
+ }
12823
+ function isBatchApi(provider) {
12824
+ const candidate = provider;
12825
+ return typeof candidate.doStartBatch === "function" && typeof candidate.doGetBatchStatus === "function" && typeof candidate.doGetBatchResults === "function";
12703
12826
  }
12704
12827
  function validateRequests(requests) {
12705
12828
  if (requests.length === 0) {
@@ -12729,21 +12852,21 @@ function validateRequests(requests) {
12729
12852
  }
12730
12853
  }
12731
12854
  function validateBatchReference({
12732
- model,
12855
+ batchApi,
12733
12856
  batch
12734
12857
  }) {
12735
- if (batch.version !== 1 || batch.type !== "text") {
12858
+ if (batch.version !== 2) {
12736
12859
  throw new InvalidArgumentError({
12737
12860
  parameter: "batch",
12738
12861
  value: batch,
12739
- message: "batch must be a supported text batch reference"
12862
+ message: "batch must be a supported batch reference"
12740
12863
  });
12741
12864
  }
12742
- if (batch.provider !== model.provider || batch.modelId !== model.modelId) {
12865
+ if (batch.provider !== batchApi.provider) {
12743
12866
  throw new InvalidArgumentError({
12744
- parameter: "model",
12745
- value: model,
12746
- message: `model ${model.provider}:${model.modelId} is not compatible with batch ${batch.provider}:${batch.modelId}`
12867
+ parameter: "provider",
12868
+ value: batchApi,
12869
+ message: `provider ${batchApi.provider} is not compatible with batch provider ${batch.provider}`
12747
12870
  });
12748
12871
  }
12749
12872
  }
@@ -12751,14 +12874,32 @@ async function convertBatchItemResult({
12751
12874
  item,
12752
12875
  tools
12753
12876
  }) {
12754
- if (item.status !== "succeeded") {
12755
- return item;
12877
+ switch (item.type) {
12878
+ case "text":
12879
+ switch (item.status) {
12880
+ case "succeeded":
12881
+ return {
12882
+ id: item.id,
12883
+ status: item.status,
12884
+ ...await convertGenerateResult({ result: item.result, tools })
12885
+ };
12886
+ case "failed":
12887
+ return {
12888
+ id: item.id,
12889
+ status: item.status,
12890
+ error: item.error,
12891
+ providerMetadata: item.providerMetadata
12892
+ };
12893
+ case "cancelled":
12894
+ case "expired":
12895
+ return {
12896
+ id: item.id,
12897
+ status: item.status,
12898
+ error: item.error,
12899
+ providerMetadata: item.providerMetadata
12900
+ };
12901
+ }
12756
12902
  }
12757
- return {
12758
- id: item.id,
12759
- status: "succeeded",
12760
- ...await convertGenerateResult({ result: item.result, tools })
12761
- };
12762
12903
  }
12763
12904
  async function convertGenerateResult({
12764
12905
  result,
@@ -13355,6 +13496,12 @@ var gatewayCostMetadataKeys = [
13355
13496
  "outputInferenceCost",
13356
13497
  "surchargeCost"
13357
13498
  ];
13499
+ var RetryableNoImageResultError = class extends Error {
13500
+ constructor() {
13501
+ super("No image generated.");
13502
+ this.name = "RetryableNoImageResultError";
13503
+ }
13504
+ };
13358
13505
  async function generateImage({
13359
13506
  model: modelArg,
13360
13507
  prompt: promptArg,
@@ -13376,7 +13523,8 @@ async function generateImage({
13376
13523
  );
13377
13524
  const { retry } = prepareRetries({
13378
13525
  maxRetries: maxRetriesArg,
13379
- abortSignal
13526
+ abortSignal,
13527
+ additionalRetryableError: (error) => error instanceof RetryableNoImageResultError
13380
13528
  });
13381
13529
  const maxImagesPerCallWithDefault = (_a25 = maxImagesPerCall != null ? maxImagesPerCall : await invokeModelMaxImagesPerCall(model)) != null ? _a25 : 1;
13382
13530
  const callCount = Math.ceil(n / maxImagesPerCallWithDefault);
@@ -13387,25 +13535,41 @@ async function generateImage({
13387
13535
  const remainder = n % maxImagesPerCallWithDefault;
13388
13536
  return remainder === 0 ? maxImagesPerCallWithDefault : remainder;
13389
13537
  });
13390
- const results = await Promise.all(
13391
- callImageCounts.map(
13392
- async (callImageCount) => await retry(() => {
13393
- const { prompt, files, mask } = normalizePrompt(promptArg);
13394
- return model.doGenerate({
13395
- prompt,
13396
- files,
13397
- mask,
13398
- n: callImageCount,
13399
- abortSignal,
13400
- headers: headersWithUserAgent,
13401
- size,
13402
- aspectRatio,
13403
- seed,
13404
- providerOptions: providerOptions != null ? providerOptions : {}
13538
+ const resultGroups = await Promise.all(
13539
+ callImageCounts.map(async (callImageCount) => {
13540
+ const callResults = [];
13541
+ try {
13542
+ await retry(async () => {
13543
+ const { prompt, files, mask } = normalizePrompt(promptArg);
13544
+ const result = await model.doGenerate({
13545
+ prompt,
13546
+ files,
13547
+ mask,
13548
+ n: callImageCount,
13549
+ abortSignal,
13550
+ headers: headersWithUserAgent,
13551
+ size,
13552
+ aspectRatio,
13553
+ seed,
13554
+ providerOptions: providerOptions != null ? providerOptions : {}
13555
+ });
13556
+ callResults.push(result);
13557
+ if (result.images.length === 0 && result.isRetryable !== false) {
13558
+ throw new RetryableNoImageResultError();
13559
+ }
13560
+ return result;
13405
13561
  });
13406
- })
13407
- )
13562
+ return callResults;
13563
+ } catch (error) {
13564
+ const noImageResultError = error instanceof RetryableNoImageResultError ? error : RetryError.isInstance(error) && error.lastError instanceof RetryableNoImageResultError ? error.lastError : void 0;
13565
+ if (noImageResultError != null) {
13566
+ return callResults;
13567
+ }
13568
+ throw error;
13569
+ }
13570
+ })
13408
13571
  );
13572
+ const results = resultGroups.flat();
13409
13573
  const images = [];
13410
13574
  const calls = [];
13411
13575
  const warnings = [];
@@ -14362,33 +14526,6 @@ function getTextFromDataUrl(dataUrl) {
14362
14526
  }
14363
14527
  }
14364
14528
 
14365
- // src/util/is-deep-equal-data.ts
14366
- function isDeepEqualData(obj1, obj2) {
14367
- if (obj1 === obj2) return true;
14368
- if (obj1 == null || obj2 == null) return false;
14369
- if (typeof obj1 !== "object" && typeof obj2 !== "object")
14370
- return obj1 === obj2;
14371
- if (obj1.constructor !== obj2.constructor) return false;
14372
- if (obj1 instanceof Date && obj2 instanceof Date) {
14373
- return obj1.getTime() === obj2.getTime();
14374
- }
14375
- if (Array.isArray(obj1)) {
14376
- if (obj1.length !== obj2.length) return false;
14377
- for (let i = 0; i < obj1.length; i++) {
14378
- if (!isDeepEqualData(obj1[i], obj2[i])) return false;
14379
- }
14380
- return true;
14381
- }
14382
- const keys1 = Object.keys(obj1);
14383
- const keys2 = Object.keys(obj2);
14384
- if (keys1.length !== keys2.length) return false;
14385
- for (const key of keys1) {
14386
- if (!keys2.includes(key)) return false;
14387
- if (!isDeepEqualData(obj1[key], obj2[key])) return false;
14388
- }
14389
- return true;
14390
- }
14391
-
14392
14529
  // src/util/serial-job-executor.ts
14393
14530
  var SerialJobExecutor = class {
14394
14531
  constructor() {
@@ -19639,7 +19776,7 @@ export {
19639
19776
  getRealtimeToolDefinitions as experimental_getRealtimeToolDefinitions,
19640
19777
  experimental_getVideoStatus,
19641
19778
  resampleAudio as experimental_resampleAudio,
19642
- startTextBatch as experimental_startTextBatch,
19779
+ startBatch as experimental_startBatch,
19643
19780
  experimental_startVideo,
19644
19781
  streamLanguageModelCall as experimental_streamLanguageModelCall,
19645
19782
  streamTranscribe as experimental_streamTranscribe,
@@ -19649,7 +19786,7 @@ export {
19649
19786
  extractJsonMiddleware,
19650
19787
  extractReasoningMiddleware,
19651
19788
  fingerprintTools,
19652
- gateway2 as gateway,
19789
+ gateway3 as gateway,
19653
19790
  generateId3 as generateId,
19654
19791
  generateImage,
19655
19792
  generateObject,