ai 7.0.106 → 7.0.108

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 (37) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/dist/index.d.ts +2 -0
  3. package/dist/index.js +390 -95
  4. package/dist/index.js.map +1 -1
  5. package/dist/internal/index.d.ts +16 -2
  6. package/dist/internal/index.js +323 -53
  7. package/dist/internal/index.js.map +1 -1
  8. package/docs/00-introduction/index.mdx +1 -1
  9. package/docs/02-getting-started/03-nextjs-pages-router.mdx +1 -1
  10. package/docs/02-getting-started/05-nuxt.mdx +1 -1
  11. package/docs/03-ai-sdk-core/16-mcp-tools.mdx +31 -0
  12. package/docs/03-ai-sdk-core/19-tool-search.mdx +4 -2
  13. package/docs/04-ai-sdk-ui/02-chatbot.mdx +26 -11
  14. package/docs/04-ai-sdk-ui/05-completion.mdx +1 -1
  15. package/docs/07-reference/01-ai-sdk-core/01-generate-text.mdx +7 -0
  16. package/docs/07-reference/01-ai-sdk-core/02-stream-text.mdx +7 -0
  17. package/docs/07-reference/01-ai-sdk-core/23-tool-search.mdx +3 -2
  18. package/docs/07-reference/02-ai-sdk-ui/01-use-chat.mdx +1 -1
  19. package/package.json +11 -11
  20. package/src/generate-speech/generate-speech.ts +44 -4
  21. package/src/generate-text/generate-text.ts +29 -16
  22. package/src/generate-text/invoke-tool-callbacks-from-stream.ts +68 -16
  23. package/src/generate-text/parse-tool-call.ts +64 -12
  24. package/src/generate-text/stream-language-model-call.ts +32 -21
  25. package/src/generate-text/stream-text.ts +1 -1
  26. package/src/generate-text/tool-call-repair-function.ts +2 -0
  27. package/src/generate-video/generate-video.ts +61 -10
  28. package/src/middleware/wrap-provider.ts +2 -0
  29. package/src/model/as-language-model-v4.ts +166 -6
  30. package/src/test/mock-server-response.ts +19 -3
  31. package/src/text-stream/pipe-text-stream-to-response.ts +3 -5
  32. package/src/ui/http-chat-transport.ts +12 -2
  33. package/src/ui/last-assistant-message-is-complete-with-approval-responses.ts +1 -1
  34. package/src/ui/last-assistant-message-is-complete-with-tool-calls.ts +2 -1
  35. package/src/ui-message-stream/pipe-ui-message-stream-to-response.ts +1 -3
  36. package/src/util/data-url.ts +13 -1
  37. package/src/util/write-to-server-response.ts +7 -3
package/dist/index.js CHANGED
@@ -774,6 +774,9 @@ function asImageModelV4(model) {
774
774
  });
775
775
  }
776
776
 
777
+ // src/model/as-language-model-v4.ts
778
+ import { convertUint8ArrayToBase64 } from "@ai-sdk/provider-utils";
779
+
777
780
  // src/model/as-language-model-v3.ts
778
781
  function asLanguageModelV3(model) {
779
782
  if (model.specificationVersion === "v3") {
@@ -861,11 +864,131 @@ function asLanguageModelV4(model) {
861
864
  const v3Model = model.specificationVersion === "v2" ? asLanguageModelV3(model) : model;
862
865
  return new Proxy(v3Model, {
863
866
  get(target, prop) {
864
- if (prop === "specificationVersion") return "v4";
865
- return target[prop];
867
+ switch (prop) {
868
+ case "specificationVersion":
869
+ return "v4";
870
+ case "doGenerate":
871
+ return async (options) => {
872
+ const result = await target.doGenerate({
873
+ ...options,
874
+ prompt: convertV4PromptToV3(options.prompt)
875
+ });
876
+ return {
877
+ ...result,
878
+ content: result.content.map(convertV3ContentToV4)
879
+ };
880
+ };
881
+ case "doStream":
882
+ return async (options) => {
883
+ const result = await target.doStream({
884
+ ...options,
885
+ prompt: convertV4PromptToV3(options.prompt)
886
+ });
887
+ return {
888
+ ...result,
889
+ stream: convertV3StreamToV4(result.stream)
890
+ };
891
+ };
892
+ default:
893
+ return target[prop];
894
+ }
895
+ }
896
+ });
897
+ }
898
+ function convertV4PromptToV3(prompt) {
899
+ return prompt.map((message) => {
900
+ if (message.role === "system") {
901
+ return message;
866
902
  }
903
+ return {
904
+ ...message,
905
+ content: message.content.map((part) => {
906
+ switch (part.type) {
907
+ case "file":
908
+ return {
909
+ ...part,
910
+ data: convertV4FileDataToV3(part.data)
911
+ };
912
+ case "tool-result":
913
+ return {
914
+ ...part,
915
+ output: convertV4ToolResultOutputToV3(part.output)
916
+ };
917
+ default:
918
+ return part;
919
+ }
920
+ })
921
+ };
867
922
  });
868
923
  }
924
+ function convertV4FileDataToV3(data) {
925
+ switch (data.type) {
926
+ case "data":
927
+ return data.data;
928
+ case "url":
929
+ return data.url;
930
+ case "reference":
931
+ case "text":
932
+ return data;
933
+ }
934
+ }
935
+ function convertV4ToolResultOutputToV3(output) {
936
+ if (output.type !== "content") {
937
+ return output;
938
+ }
939
+ return {
940
+ ...output,
941
+ value: output.value.map((part) => {
942
+ if (part.type !== "file") {
943
+ return part;
944
+ }
945
+ switch (part.data.type) {
946
+ case "data":
947
+ return {
948
+ type: "file-data",
949
+ data: typeof part.data.data === "string" ? part.data.data : convertUint8ArrayToBase64(part.data.data),
950
+ mediaType: part.mediaType,
951
+ filename: part.filename,
952
+ providerOptions: part.providerOptions
953
+ };
954
+ case "url":
955
+ return {
956
+ type: "file-url",
957
+ url: part.data.url.toString(),
958
+ providerOptions: part.providerOptions
959
+ };
960
+ case "reference":
961
+ return {
962
+ type: "file-id",
963
+ fileId: part.data.reference,
964
+ providerOptions: part.providerOptions
965
+ };
966
+ case "text":
967
+ return part;
968
+ }
969
+ })
970
+ };
971
+ }
972
+ function convertV3ContentToV4(content) {
973
+ return content.type === "file" ? {
974
+ ...content,
975
+ data: { type: "data", data: content.data }
976
+ } : content;
977
+ }
978
+ function convertV3StreamToV4(stream) {
979
+ return stream.pipeThrough(
980
+ new TransformStream({
981
+ transform(chunk, controller) {
982
+ controller.enqueue(
983
+ chunk.type === "file" ? {
984
+ ...chunk,
985
+ data: { type: "data", data: chunk.data }
986
+ } : chunk
987
+ );
988
+ }
989
+ })
990
+ );
991
+ }
869
992
 
870
993
  // src/model/as-reranking-model-v4.ts
871
994
  function asRerankingModelV4(model) {
@@ -1211,7 +1334,7 @@ import {
1211
1334
  } from "@ai-sdk/provider-utils";
1212
1335
 
1213
1336
  // src/version.ts
1214
- var VERSION = true ? "7.0.106" : "0.0.0-test";
1337
+ var VERSION = true ? "7.0.108" : "0.0.0-test";
1215
1338
 
1216
1339
  // src/util/download/download.ts
1217
1340
  var download = async ({
@@ -3010,7 +3133,7 @@ function collectToolApprovals({
3010
3133
  // src/generate-text/generated-file.ts
3011
3134
  import {
3012
3135
  convertBase64ToUint8Array,
3013
- convertUint8ArrayToBase64
3136
+ convertUint8ArrayToBase64 as convertUint8ArrayToBase642
3014
3137
  } from "@ai-sdk/provider-utils";
3015
3138
  var DefaultGeneratedFile = class {
3016
3139
  constructor({
@@ -3027,7 +3150,7 @@ var DefaultGeneratedFile = class {
3027
3150
  // lazy conversion with caching to avoid unnecessary conversion overhead:
3028
3151
  get base64() {
3029
3152
  if (this.base64Data == null) {
3030
- this.base64Data = convertUint8ArrayToBase64(this.uint8ArrayData);
3153
+ this.base64Data = convertUint8ArrayToBase642(this.uint8ArrayData);
3031
3154
  }
3032
3155
  return this.base64Data;
3033
3156
  }
@@ -4439,7 +4562,8 @@ async function parseToolCall({
4439
4562
  repairToolCall,
4440
4563
  refineToolInput,
4441
4564
  messages,
4442
- instructions
4565
+ instructions,
4566
+ abortSignal
4443
4567
  }) {
4444
4568
  try {
4445
4569
  if (tools == null) {
@@ -4462,20 +4586,26 @@ async function parseToolCall({
4462
4586
  }
4463
4587
  let repairedToolCall = null;
4464
4588
  try {
4465
- repairedToolCall = await repairToolCall({
4466
- toolCall,
4467
- tools,
4468
- inputSchema: async ({ toolName }) => {
4469
- var _a25;
4470
- const inputSchema = (_a25 = getOwn(tools, toolName)) == null ? void 0 : _a25.inputSchema;
4471
- return await asSchema3(inputSchema).jsonSchema;
4472
- },
4473
- instructions,
4474
- system: instructions,
4475
- messages,
4476
- error
4589
+ abortSignal == null ? void 0 : abortSignal.throwIfAborted();
4590
+ repairedToolCall = await waitForPromiseWithAbortSignal({
4591
+ promise: repairToolCall({
4592
+ toolCall,
4593
+ tools,
4594
+ inputSchema: async ({ toolName }) => {
4595
+ var _a25;
4596
+ const inputSchema = (_a25 = getOwn(tools, toolName)) == null ? void 0 : _a25.inputSchema;
4597
+ return await asSchema3(inputSchema).jsonSchema;
4598
+ },
4599
+ instructions,
4600
+ system: instructions,
4601
+ messages,
4602
+ error,
4603
+ abortSignal
4604
+ }),
4605
+ abortSignal
4477
4606
  });
4478
4607
  } catch (repairError) {
4608
+ abortSignal == null ? void 0 : abortSignal.throwIfAborted();
4479
4609
  throw new ToolCallRepairError({
4480
4610
  cause: repairError,
4481
4611
  originalError: error
@@ -4484,12 +4614,15 @@ async function parseToolCall({
4484
4614
  if (repairedToolCall == null) {
4485
4615
  throw error;
4486
4616
  }
4487
- return await refineParsedToolCallInput({
4617
+ const parsedRepairedToolCall = await refineParsedToolCallInput({
4488
4618
  toolCall: await doParseToolCall({ toolCall: repairedToolCall, tools }),
4489
4619
  refineToolInput
4490
4620
  });
4621
+ abortSignal == null ? void 0 : abortSignal.throwIfAborted();
4622
+ return parsedRepairedToolCall;
4491
4623
  }
4492
4624
  } catch (error) {
4625
+ abortSignal == null ? void 0 : abortSignal.throwIfAborted();
4493
4626
  const parsedInput = await safeParseJSON3({ text: toolCall.input });
4494
4627
  const input = parsedInput.success ? parsedInput.value : toolCall.input;
4495
4628
  const tool3 = getOwn(tools, toolCall.toolName);
@@ -4508,6 +4641,34 @@ async function parseToolCall({
4508
4641
  };
4509
4642
  }
4510
4643
  }
4644
+ async function waitForPromiseWithAbortSignal({
4645
+ promise,
4646
+ abortSignal
4647
+ }) {
4648
+ if (abortSignal == null) {
4649
+ return await promise;
4650
+ }
4651
+ return await new Promise((resolve3, reject) => {
4652
+ const cleanup = () => {
4653
+ abortSignal.removeEventListener("abort", onAbort);
4654
+ };
4655
+ const onAbort = () => {
4656
+ cleanup();
4657
+ reject(abortSignal.reason);
4658
+ };
4659
+ Promise.resolve(promise).then((value) => {
4660
+ cleanup();
4661
+ resolve3(value);
4662
+ }).catch((error) => {
4663
+ cleanup();
4664
+ reject(error);
4665
+ });
4666
+ abortSignal.addEventListener("abort", onAbort, { once: true });
4667
+ if (abortSignal.aborted) {
4668
+ onAbort();
4669
+ }
4670
+ });
4671
+ }
4511
4672
  async function refineParsedToolCallInput({
4512
4673
  toolCall,
4513
4674
  refineToolInput
@@ -5514,7 +5675,7 @@ function sortToolResultContentByToolCallOrder({
5514
5675
  import { convertBase64ToUint8Array as convertBase64ToUint8Array2 } from "@ai-sdk/provider-utils";
5515
5676
 
5516
5677
  // src/util/canonical-hash.ts
5517
- import { convertUint8ArrayToBase64 as convertUint8ArrayToBase642 } from "@ai-sdk/provider-utils";
5678
+ import { convertUint8ArrayToBase64 as convertUint8ArrayToBase643 } from "@ai-sdk/provider-utils";
5518
5679
  var encoder = new TextEncoder();
5519
5680
  function canonicalJSON(value) {
5520
5681
  if (value === null || value === void 0) {
@@ -5533,7 +5694,7 @@ function canonicalJSON(value) {
5533
5694
  return `{${entries.join(",")}}`;
5534
5695
  }
5535
5696
  function toBase64url(bytes) {
5536
- return convertUint8ArrayToBase642(bytes).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
5697
+ return convertUint8ArrayToBase643(bytes).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
5537
5698
  }
5538
5699
  async function hashCanonical(value) {
5539
5700
  const digest = await crypto.subtle.digest(
@@ -6191,11 +6352,12 @@ async function generateText({
6191
6352
  ).map(
6192
6353
  (toolCall) => parseToolCall({
6193
6354
  toolCall,
6194
- tools: stepExecutionTools,
6355
+ tools: stepModelTools,
6195
6356
  repairToolCall,
6196
6357
  refineToolInput,
6197
6358
  instructions: stepInstructions,
6198
- messages: stepMessages
6359
+ messages: stepMessages,
6360
+ abortSignal: mergedAbortSignal
6199
6361
  })
6200
6362
  )
6201
6363
  );
@@ -6265,22 +6427,29 @@ async function generateText({
6265
6427
  if (tool3 == null) {
6266
6428
  continue;
6267
6429
  }
6268
- if (tool3.onInputStart != null) {
6269
- await tool3.onInputStart({
6270
- toolCallId: toolCall.toolCallId,
6271
- messages: stepMessages,
6272
- abortSignal: mergedAbortSignal,
6273
- context: runtimeContext
6274
- });
6275
- }
6276
- if ((tool3 == null ? void 0 : tool3.onInputAvailable) != null) {
6277
- await tool3.onInputAvailable({
6278
- input: toolCall.input,
6279
- toolCallId: toolCall.toolCallId,
6280
- messages: stepMessages,
6281
- abortSignal: mergedAbortSignal,
6282
- context: runtimeContext
6430
+ if (tool3.onInputStart != null || tool3.onInputAvailable != null) {
6431
+ const context = await validateToolContext({
6432
+ toolName: toolCall.toolName,
6433
+ context: getOwn(toolsContext, toolCall.toolName),
6434
+ contextSchema: tool3.contextSchema
6283
6435
  });
6436
+ if (tool3.onInputStart != null) {
6437
+ await tool3.onInputStart({
6438
+ toolCallId: toolCall.toolCallId,
6439
+ messages: stepMessages,
6440
+ abortSignal: mergedAbortSignal,
6441
+ context
6442
+ });
6443
+ }
6444
+ if (tool3.onInputAvailable != null) {
6445
+ await tool3.onInputAvailable({
6446
+ input: toolCall.input,
6447
+ toolCallId: toolCall.toolCallId,
6448
+ messages: stepMessages,
6449
+ abortSignal: mergedAbortSignal,
6450
+ context
6451
+ });
6452
+ }
6284
6453
  }
6285
6454
  const toolApprovalStatus = await resolveToolApproval({
6286
6455
  tools: stepExecutionTools,
@@ -6783,10 +6952,13 @@ function writeToServerResponse({
6783
6952
  stream
6784
6953
  }) {
6785
6954
  const statusCode = status != null ? status : 200;
6955
+ if (headers != null) {
6956
+ response.setHeaders(headers);
6957
+ }
6786
6958
  if (statusText !== void 0) {
6787
- response.writeHead(statusCode, statusText, headers);
6959
+ response.writeHead(statusCode, statusText);
6788
6960
  } else {
6789
- response.writeHead(statusCode, headers);
6961
+ response.writeHead(statusCode);
6790
6962
  }
6791
6963
  const reader = stream.getReader();
6792
6964
  const read = async () => {
@@ -6826,11 +6998,9 @@ function pipeTextStreamToResponse({
6826
6998
  response,
6827
6999
  status,
6828
7000
  statusText,
6829
- headers: Object.fromEntries(
6830
- prepareHeaders(headers, {
6831
- "content-type": "text/plain; charset=utf-8"
6832
- }).entries()
6833
- ),
7001
+ headers: prepareHeaders(headers, {
7002
+ "content-type": "text/plain; charset=utf-8"
7003
+ }),
6834
7004
  stream: stream.pipeThrough(new TextEncoderStream())
6835
7005
  });
6836
7006
  }
@@ -6916,9 +7086,7 @@ function pipeUIMessageStreamToResponse({
6916
7086
  response,
6917
7087
  status,
6918
7088
  statusText,
6919
- headers: Object.fromEntries(
6920
- prepareHeaders(headers, UI_MESSAGE_STREAM_HEADERS).entries()
6921
- ),
7089
+ headers: prepareHeaders(headers, UI_MESSAGE_STREAM_HEADERS),
6922
7090
  stream: sseStream.pipeThrough(new TextEncoderStream())
6923
7091
  });
6924
7092
  }
@@ -8796,33 +8964,60 @@ function invokeToolCallbacksFromStream({
8796
8964
  tools,
8797
8965
  stepInputMessages,
8798
8966
  abortSignal,
8799
- runtimeContext
8967
+ toolsContext
8800
8968
  }) {
8801
8969
  if (tools == null) return stream;
8802
- const ongoingToolCallToolNames = createIdMap();
8970
+ let ongoingToolCalls = createIdMap();
8971
+ const getValidatedContext = ({
8972
+ toolCallId,
8973
+ toolName
8974
+ }) => {
8975
+ const ongoingToolCall = ongoingToolCalls[toolCallId];
8976
+ if ((ongoingToolCall == null ? void 0 : ongoingToolCall.validatedContext) != null) {
8977
+ return ongoingToolCall.validatedContext;
8978
+ }
8979
+ const tool3 = getOwn(tools, toolName);
8980
+ const validatedContext = validateToolContext({
8981
+ toolName,
8982
+ context: getOwn(toolsContext, toolName),
8983
+ contextSchema: tool3 == null ? void 0 : tool3.contextSchema
8984
+ });
8985
+ if (ongoingToolCall != null) {
8986
+ ongoingToolCall.validatedContext = validatedContext;
8987
+ }
8988
+ return validatedContext;
8989
+ };
8803
8990
  return stream.pipeThrough(
8804
8991
  new TransformStream({
8805
8992
  async transform(chunk, controller) {
8993
+ var _a25, _b25;
8806
8994
  controller.enqueue(chunk);
8807
8995
  if (isStreamRetryAttemptBoundaryPart(chunk)) {
8996
+ ongoingToolCalls = createIdMap();
8808
8997
  return;
8809
8998
  }
8810
8999
  switch (chunk.type) {
8811
9000
  case "tool-input-start": {
8812
- ongoingToolCallToolNames[chunk.id] = chunk.toolName;
9001
+ ongoingToolCalls[chunk.id] = {
9002
+ toolName: chunk.toolName,
9003
+ validatedContext: void 0
9004
+ };
8813
9005
  const tool3 = getOwn(tools, chunk.toolName);
8814
9006
  if ((tool3 == null ? void 0 : tool3.onInputStart) != null) {
8815
9007
  await tool3.onInputStart({
8816
9008
  toolCallId: chunk.id,
8817
9009
  messages: stepInputMessages,
8818
9010
  abortSignal,
8819
- context: runtimeContext
9011
+ context: await getValidatedContext({
9012
+ toolCallId: chunk.id,
9013
+ toolName: chunk.toolName
9014
+ })
8820
9015
  });
8821
9016
  }
8822
9017
  break;
8823
9018
  }
8824
9019
  case "tool-input-delta": {
8825
- const toolName = ongoingToolCallToolNames[chunk.id];
9020
+ const toolName = (_a25 = ongoingToolCalls[chunk.id]) == null ? void 0 : _a25.toolName;
8826
9021
  const tool3 = getOwn(tools, toolName);
8827
9022
  if ((tool3 == null ? void 0 : tool3.onInputDelta) != null) {
8828
9023
  await tool3.onInputDelta({
@@ -8830,23 +9025,32 @@ function invokeToolCallbacksFromStream({
8830
9025
  toolCallId: chunk.id,
8831
9026
  messages: stepInputMessages,
8832
9027
  abortSignal,
8833
- context: runtimeContext
9028
+ context: await getValidatedContext({
9029
+ toolCallId: chunk.id,
9030
+ toolName
9031
+ })
8834
9032
  });
8835
9033
  }
8836
9034
  break;
8837
9035
  }
8838
9036
  case "tool-call": {
8839
- const toolName = ongoingToolCallToolNames[chunk.toolCallId];
9037
+ const toolName = (_b25 = ongoingToolCalls[chunk.toolCallId]) == null ? void 0 : _b25.toolName;
8840
9038
  const tool3 = getOwn(tools, toolName);
8841
- delete ongoingToolCallToolNames[chunk.toolCallId];
8842
9039
  if (!chunk.invalid && (tool3 == null ? void 0 : tool3.onInputAvailable) != null) {
9040
+ const validatedContext = getValidatedContext({
9041
+ toolCallId: chunk.toolCallId,
9042
+ toolName
9043
+ });
9044
+ delete ongoingToolCalls[chunk.toolCallId];
8843
9045
  await tool3.onInputAvailable({
8844
9046
  input: chunk.input,
8845
9047
  toolCallId: chunk.toolCallId,
8846
9048
  messages: stepInputMessages,
8847
9049
  abortSignal,
8848
- context: runtimeContext
9050
+ context: await validatedContext
8849
9051
  });
9052
+ } else {
9053
+ delete ongoingToolCalls[chunk.toolCallId];
8850
9054
  }
8851
9055
  }
8852
9056
  }
@@ -9047,6 +9251,7 @@ async function streamLanguageModelCall({
9047
9251
  messages: standardizedPrompt.messages,
9048
9252
  repairToolCall,
9049
9253
  refineToolInput,
9254
+ abortSignal,
9050
9255
  callId: effectiveCallId,
9051
9256
  provider: resolvedModel.provider,
9052
9257
  modelId: resolvedModel.modelId,
@@ -9069,6 +9274,7 @@ function createLanguageModelV4StreamPartToLanguageModelStreamPartTransform({
9069
9274
  messages,
9070
9275
  repairToolCall,
9071
9276
  refineToolInput,
9277
+ abortSignal,
9072
9278
  callId,
9073
9279
  provider,
9074
9280
  modelId,
@@ -9256,27 +9462,28 @@ function createLanguageModelV4StreamPartToLanguageModelStreamPartTransform({
9256
9462
  },
9257
9463
  callbacks: onLanguageModelCallEnd
9258
9464
  });
9465
+ const enforcedToolChoice = toolChoice.type === "required" || toolChoice.type === "tool" ? toolChoice : void 0;
9466
+ const toolChoiceViolationError = enforcedToolChoice != null && ![...toolCallsByToolCallId.values()].some(
9467
+ (toolCall) => enforcedToolChoice.type === "required" || toolCall.toolName === enforcedToolChoice.toolName
9468
+ ) ? new ToolChoiceViolationError({
9469
+ toolChoice: enforcedToolChoice,
9470
+ finishReason: chunk.finishReason.unified,
9471
+ provider,
9472
+ modelId,
9473
+ content: rawModelCallContent
9474
+ }) : void 0;
9259
9475
  controller.enqueue({
9260
9476
  type: "model-call-end",
9261
- finishReason: chunk.finishReason.unified,
9477
+ finishReason: toolChoiceViolationError == null ? chunk.finishReason.unified : "error",
9262
9478
  rawFinishReason: chunk.finishReason.raw,
9263
9479
  usage,
9264
9480
  providerMetadata: chunk.providerMetadata,
9265
9481
  performance
9266
9482
  });
9267
- const enforcedToolChoice = toolChoice.type === "required" || toolChoice.type === "tool" ? toolChoice : void 0;
9268
- if (enforcedToolChoice != null && ![...toolCallsByToolCallId.values()].some(
9269
- (toolCall) => enforcedToolChoice.type === "required" || toolCall.toolName === enforcedToolChoice.toolName
9270
- )) {
9483
+ if (toolChoiceViolationError != null) {
9271
9484
  controller.enqueue({
9272
9485
  type: "error",
9273
- error: new ToolChoiceViolationError({
9274
- toolChoice: enforcedToolChoice,
9275
- finishReason: chunk.finishReason.unified,
9276
- provider,
9277
- modelId,
9278
- content: rawModelCallContent
9279
- })
9486
+ error: toolChoiceViolationError
9280
9487
  });
9281
9488
  break;
9282
9489
  }
@@ -9291,7 +9498,8 @@ function createLanguageModelV4StreamPartToLanguageModelStreamPartTransform({
9291
9498
  repairToolCall,
9292
9499
  refineToolInput,
9293
9500
  instructions,
9294
- messages
9501
+ messages,
9502
+ abortSignal
9295
9503
  });
9296
9504
  toolCallsByToolCallId.set(toolCall.toolCallId, toolCall);
9297
9505
  controller.enqueue(toolCall);
@@ -10881,7 +11089,7 @@ var DefaultStreamTextResult = class {
10881
11089
  tools: stepExecutionTools,
10882
11090
  stepInputMessages: stepMessages,
10883
11091
  abortSignal,
10884
- runtimeContext
11092
+ toolsContext
10885
11093
  });
10886
11094
  const runInTracingChannelSpanInStep = telemetryDispatcher.runInTracingChannelSpan == null ? void 0 : (options) => runInStepTracingChannelContext(
10887
11095
  () => telemetryDispatcher.runInTracingChannelSpan(options)
@@ -12893,16 +13101,16 @@ import {
12893
13101
  // src/prompt/data-content.ts
12894
13102
  import {
12895
13103
  convertBase64ToUint8Array as convertBase64ToUint8Array3,
12896
- convertUint8ArrayToBase64 as convertUint8ArrayToBase643
13104
+ convertUint8ArrayToBase64 as convertUint8ArrayToBase644
12897
13105
  } from "@ai-sdk/provider-utils";
12898
13106
  function convertDataContentToBase64String(content) {
12899
13107
  if (typeof content === "string") {
12900
13108
  return content;
12901
13109
  }
12902
13110
  if (content instanceof ArrayBuffer) {
12903
- return convertUint8ArrayToBase643(new Uint8Array(content));
13111
+ return convertUint8ArrayToBase644(new Uint8Array(content));
12904
13112
  }
12905
- return convertUint8ArrayToBase643(content);
13113
+ return convertUint8ArrayToBase644(content);
12906
13114
  }
12907
13115
  function convertDataContentToUint8Array(content) {
12908
13116
  if (content instanceof Uint8Array) {
@@ -15331,8 +15539,13 @@ function createDownload(options) {
15331
15539
  // src/util/data-url.ts
15332
15540
  var { atob: atob2 } = globalThis;
15333
15541
  function getTextFromDataUrl(dataUrl) {
15542
+ var _a25;
15334
15543
  const [header, base64Content] = dataUrl.split(",");
15335
15544
  const mediaType = header.split(";")[0].split(":")[1];
15545
+ const charsetMatch = /(?:^|;)\s*charset\s*=\s*(?:"([^"]+)"|([^;\s]+))/i.exec(
15546
+ header
15547
+ );
15548
+ const charset = (_a25 = charsetMatch == null ? void 0 : charsetMatch[1]) != null ? _a25 : charsetMatch == null ? void 0 : charsetMatch[2];
15336
15549
  if (mediaType == null || base64Content == null) {
15337
15550
  throw new InvalidArgumentError({
15338
15551
  parameter: "dataUrl",
@@ -15341,7 +15554,13 @@ function getTextFromDataUrl(dataUrl) {
15341
15554
  });
15342
15555
  }
15343
15556
  try {
15344
- return atob2(base64Content);
15557
+ const byteString = atob2(base64Content);
15558
+ if (charset == null) {
15559
+ return byteString;
15560
+ }
15561
+ return new TextDecoder(charset).decode(
15562
+ Uint8Array.from(byteString, (byte) => byte.codePointAt(0))
15563
+ );
15345
15564
  } catch (e) {
15346
15565
  throw new InvalidArgumentError({
15347
15566
  parameter: "dataUrl",
@@ -16010,7 +16229,7 @@ async function generateSpeech({
16010
16229
  abortSignal,
16011
16230
  headers
16012
16231
  }) {
16013
- var _a25;
16232
+ var _a25, _b25;
16014
16233
  const resolvedModel = resolveSpeechModel(model);
16015
16234
  if (!resolvedModel) {
16016
16235
  throw new Error("Model could not be resolved");
@@ -16044,19 +16263,41 @@ async function generateSpeech({
16044
16263
  provider: resolvedModel.provider,
16045
16264
  model: resolvedModel.modelId
16046
16265
  });
16266
+ const detectedMediaType = detectMediaType4({
16267
+ data: result.audio,
16268
+ topLevelType: "audio"
16269
+ });
16047
16270
  return new DefaultSpeechResult({
16048
16271
  audio: new DefaultGeneratedAudioFile({
16049
16272
  data: result.audio,
16050
- mediaType: (_a25 = detectMediaType4({
16051
- data: result.audio,
16052
- topLevelType: "audio"
16053
- })) != null ? _a25 : "audio/mp3"
16273
+ mediaType: (_b25 = (_a25 = detectedMediaType != null ? detectedMediaType : getResponseAudioMediaType(result.response.headers)) != null ? _a25 : getOutputFormatMediaType(outputFormat)) != null ? _b25 : "audio/mp3"
16054
16274
  }),
16055
16275
  warnings: result.warnings,
16056
16276
  responses: [result.response],
16057
16277
  providerMetadata: result.providerMetadata
16058
16278
  });
16059
16279
  }
16280
+ function getResponseAudioMediaType(headers) {
16281
+ var _a25;
16282
+ const mediaType = (_a25 = Object.entries(headers != null ? headers : {}).find(
16283
+ ([name25]) => name25.toLowerCase() === "content-type"
16284
+ )) == null ? void 0 : _a25[1];
16285
+ if (mediaType == null) {
16286
+ return void 0;
16287
+ }
16288
+ const normalizedMediaType = mediaType.split(";", 1)[0].trim().toLowerCase();
16289
+ if (normalizedMediaType.length === 0) {
16290
+ return void 0;
16291
+ }
16292
+ return normalizedMediaType.startsWith("audio/") ? normalizedMediaType : void 0;
16293
+ }
16294
+ function getOutputFormatMediaType(outputFormat) {
16295
+ if (outputFormat == null) {
16296
+ return void 0;
16297
+ }
16298
+ const normalizedOutputFormat = outputFormat.trim().toLowerCase();
16299
+ return normalizedOutputFormat === "pcm" || normalizedOutputFormat === "audio/pcm" ? "audio/pcm" : void 0;
16300
+ }
16060
16301
  var DefaultSpeechResult = class {
16061
16302
  constructor(options) {
16062
16303
  var _a25;
@@ -16364,7 +16605,7 @@ async function experimental_generateVideo({
16364
16605
  headers != null ? headers : {},
16365
16606
  `ai/${VERSION}`
16366
16607
  );
16367
- const { retry } = prepareRetries({
16608
+ const { maxRetries, retry } = prepareRetries({
16368
16609
  maxRetries: maxRetriesArg,
16369
16610
  abortSignal
16370
16611
  });
@@ -16424,6 +16665,7 @@ async function experimental_generateVideo({
16424
16665
  callOptions,
16425
16666
  poll,
16426
16667
  webhook,
16668
+ maxRetries,
16427
16669
  retry
16428
16670
  });
16429
16671
  }
@@ -16512,6 +16754,7 @@ async function executeStartStatusFlow({
16512
16754
  callOptions,
16513
16755
  poll: pollConfig,
16514
16756
  webhook: webhookFactory,
16757
+ maxRetries,
16515
16758
  retry
16516
16759
  }) {
16517
16760
  var _a25, _b25, _c, _d;
@@ -16553,6 +16796,9 @@ async function executeStartStatusFlow({
16553
16796
  const timeoutMs = (_c = pollConfig == null ? void 0 : pollConfig.timeoutMs) != null ? _c : 6e5;
16554
16797
  const delay = (_d = pollConfig == null ? void 0 : pollConfig.delay) != null ? _d : defaultDelay;
16555
16798
  const startTime = Date.now();
16799
+ const pollingTimeoutError = new Error(
16800
+ `Video generation timed out after ${timeoutMs}ms.`
16801
+ );
16556
16802
  if (webhookReceived != null) {
16557
16803
  await waitForWebhook({
16558
16804
  received: webhookReceived,
@@ -16565,22 +16811,65 @@ async function executeStartStatusFlow({
16565
16811
  if (webhookReceived == null) {
16566
16812
  const elapsedMs = Date.now() - startTime;
16567
16813
  if (elapsedMs >= timeoutMs) {
16568
- throw new Error(`Video generation timed out after ${timeoutMs}ms.`);
16814
+ throw pollingTimeoutError;
16569
16815
  }
16570
16816
  await delay(Math.min(intervalMs, timeoutMs - elapsedMs), {
16571
16817
  abortSignal: callOptions.abortSignal
16572
16818
  });
16573
16819
  if (Date.now() - startTime >= timeoutMs) {
16574
- throw new Error(`Video generation timed out after ${timeoutMs}ms.`);
16820
+ throw pollingTimeoutError;
16821
+ }
16822
+ }
16823
+ let statusResult;
16824
+ if (webhookReceived != null) {
16825
+ statusResult = await retry(
16826
+ () => model.doStatus({
16827
+ operation: startResult.operation,
16828
+ abortSignal: callOptions.abortSignal,
16829
+ headers: callOptions.headers
16830
+ })
16831
+ );
16832
+ } else {
16833
+ const statusTimeoutController = new AbortController();
16834
+ const statusAbortSignal = mergeAbortSignals(
16835
+ callOptions.abortSignal,
16836
+ statusTimeoutController.signal
16837
+ );
16838
+ const statusTimeoutId = setTimeout(
16839
+ () => statusTimeoutController.abort(pollingTimeoutError),
16840
+ timeoutMs - (Date.now() - startTime)
16841
+ );
16842
+ const statusTimeoutPromise = new Promise((_, reject) => {
16843
+ statusTimeoutController.signal.addEventListener(
16844
+ "abort",
16845
+ () => reject(pollingTimeoutError),
16846
+ { once: true }
16847
+ );
16848
+ });
16849
+ const { retry: statusRetry } = prepareRetries({
16850
+ maxRetries,
16851
+ abortSignal: statusAbortSignal
16852
+ });
16853
+ try {
16854
+ statusResult = await Promise.race([
16855
+ statusRetry(
16856
+ () => model.doStatus({
16857
+ operation: startResult.operation,
16858
+ abortSignal: statusAbortSignal,
16859
+ headers: callOptions.headers
16860
+ })
16861
+ ),
16862
+ statusTimeoutPromise
16863
+ ]);
16864
+ } catch (error) {
16865
+ if (statusTimeoutController.signal.aborted) {
16866
+ throw pollingTimeoutError;
16867
+ }
16868
+ throw error;
16869
+ } finally {
16870
+ clearTimeout(statusTimeoutId);
16575
16871
  }
16576
16872
  }
16577
- const statusResult = await retry(
16578
- () => model.doStatus({
16579
- operation: startResult.operation,
16580
- abortSignal: callOptions.abortSignal,
16581
- headers: callOptions.headers
16582
- })
16583
- );
16584
16873
  if (statusResult.status === "error") {
16585
16874
  throw new Error(statusResult.error);
16586
16875
  }
@@ -17551,7 +17840,9 @@ function wrapProvider({
17551
17840
  },
17552
17841
  transcriptionModel: providerV4.transcriptionModel,
17553
17842
  speechModel: providerV4.speechModel,
17554
- rerankingModel: providerV4.rerankingModel
17843
+ rerankingModel: providerV4.rerankingModel,
17844
+ ...providerV4.files != null ? { files: providerV4.files } : {},
17845
+ ...providerV4.skills != null ? { skills: providerV4.skills } : {}
17555
17846
  };
17556
17847
  }
17557
17848
 
@@ -21532,6 +21823,10 @@ import {
21532
21823
  resolve as resolve2
21533
21824
  } from "@ai-sdk/provider-utils";
21534
21825
  import { EmptyResponseBodyError as EmptyResponseBodyError3 } from "@ai-sdk/provider";
21826
+ function appendPathToUrl(url, path) {
21827
+ const queryOrFragmentStart = url.search(/[?#]/);
21828
+ return queryOrFragmentStart === -1 ? `${url}${path}` : `${url.slice(0, queryOrFragmentStart)}${path}${url.slice(queryOrFragmentStart)}`;
21829
+ }
21535
21830
  var HttpChatTransport = class {
21536
21831
  constructor({
21537
21832
  api = "/api/chat",
@@ -21588,7 +21883,7 @@ var HttpChatTransport = class {
21588
21883
  const response = await fetch2(api, {
21589
21884
  method: "POST",
21590
21885
  headers: {
21591
- "Content-Type": "application/json",
21886
+ "content-type": "application/json",
21592
21887
  ...headers
21593
21888
  },
21594
21889
  body: JSON.stringify(body),
@@ -21626,7 +21921,7 @@ var HttpChatTransport = class {
21626
21921
  credentials: resolvedCredentials,
21627
21922
  requestMetadata: options.metadata
21628
21923
  }));
21629
- const api = (_b25 = preparedRequest == null ? void 0 : preparedRequest.api) != null ? _b25 : `${this.api}/${options.chatId}/stream`;
21924
+ const api = (_b25 = preparedRequest == null ? void 0 : preparedRequest.api) != null ? _b25 : appendPathToUrl(this.api, `/${options.chatId}/stream`);
21630
21925
  const headers = (preparedRequest == null ? void 0 : preparedRequest.headers) !== void 0 ? normalizeHeaders(preparedRequest.headers) : baseHeaders;
21631
21926
  const credentials = (_c = preparedRequest == null ? void 0 : preparedRequest.credentials) != null ? _c : resolvedCredentials;
21632
21927
  const fetch2 = (_d = this.fetch) != null ? _d : globalThis.fetch;
@@ -22212,7 +22507,7 @@ function lastAssistantMessageIsCompleteWithApprovalResponses({
22212
22507
  // has at least one tool approval response
22213
22508
  lastStepToolInvocations.filter((part) => part.state === "approval-responded").length > 0 && // all tool approvals must have a response
22214
22509
  lastStepToolInvocations.every(
22215
- (part) => part.state === "output-available" || part.state === "output-error" || part.state === "output-denied" || part.state === "approval-responded"
22510
+ (part) => part.state === "output-available" && part.preliminary !== true || part.state === "output-error" || part.state === "output-denied" || part.state === "approval-responded"
22216
22511
  )
22217
22512
  );
22218
22513
  }
@@ -22233,7 +22528,7 @@ function lastAssistantMessageIsCompleteWithToolCalls({
22233
22528
  }, -1);
22234
22529
  const lastStepToolInvocations = message.parts.slice(lastStepStartIndex + 1).filter(isToolUIPart).filter((part) => !part.providerExecuted);
22235
22530
  return lastStepToolInvocations.length > 0 && lastStepToolInvocations.every(
22236
- (part) => part.state === "output-available" || part.state === "output-error"
22531
+ (part) => part.state === "output-available" && part.preliminary !== true || part.state === "output-error"
22237
22532
  );
22238
22533
  }
22239
22534