ai 7.0.105 → 7.0.107

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 (34) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/dist/index.js +278 -88
  3. package/dist/index.js.map +1 -1
  4. package/dist/internal/index.d.ts +15 -3
  5. package/dist/internal/index.js +153 -46
  6. package/dist/internal/index.js.map +1 -1
  7. package/docs/03-ai-sdk-core/19-tool-search.mdx +4 -2
  8. package/docs/07-reference/01-ai-sdk-core/23-tool-search.mdx +3 -2
  9. package/package.json +11 -11
  10. package/src/batch/batch.ts +1 -0
  11. package/src/generate-object/generate-object.ts +1 -0
  12. package/src/generate-object/stream-object.ts +1 -0
  13. package/src/generate-speech/generate-speech.ts +44 -4
  14. package/src/generate-text/generate-text.ts +28 -15
  15. package/src/generate-text/invoke-tool-callbacks-from-stream.ts +68 -16
  16. package/src/generate-text/prune-messages.ts +13 -0
  17. package/src/generate-text/stream-language-model-call.ts +1 -0
  18. package/src/generate-text/stream-text.ts +29 -12
  19. package/src/generate-video/generate-video.ts +61 -10
  20. package/src/middleware/extract-json-middleware.ts +35 -9
  21. package/src/middleware/simulate-streaming-middleware.ts +7 -1
  22. package/src/middleware/wrap-provider.ts +2 -0
  23. package/src/prompt/convert-to-language-model-prompt.ts +4 -2
  24. package/src/prompt/create-tool-model-output.ts +20 -11
  25. package/src/test/mock-server-response.ts +19 -3
  26. package/src/text-stream/pipe-text-stream-to-response.ts +3 -5
  27. package/src/ui/http-chat-transport.ts +12 -2
  28. package/src/ui/last-assistant-message-is-complete-with-approval-responses.ts +1 -1
  29. package/src/ui/last-assistant-message-is-complete-with-tool-calls.ts +2 -1
  30. package/src/ui-message-stream/pipe-ui-message-stream-to-response.ts +1 -3
  31. package/src/ui-message-stream/read-ui-message-stream.ts +13 -4
  32. package/src/util/data-url.ts +13 -1
  33. package/src/util/download/download-function.ts +5 -2
  34. package/src/util/write-to-server-response.ts +7 -3
package/dist/index.js CHANGED
@@ -1211,7 +1211,7 @@ import {
1211
1211
  } from "@ai-sdk/provider-utils";
1212
1212
 
1213
1213
  // src/version.ts
1214
- var VERSION = true ? "7.0.105" : "0.0.0-test";
1214
+ var VERSION = true ? "7.0.107" : "0.0.0-test";
1215
1215
 
1216
1216
  // src/util/download/download.ts
1217
1217
  var download = async ({
@@ -1258,9 +1258,9 @@ var download = async ({
1258
1258
  };
1259
1259
 
1260
1260
  // src/util/download/download-function.ts
1261
- var createDefaultDownloadFunction = (download2 = download) => (requestedDownloads) => Promise.all(
1261
+ var createDefaultDownloadFunction = (download2 = download, abortSignal) => (requestedDownloads) => Promise.all(
1262
1262
  requestedDownloads.map(
1263
- async (requestedDownload) => requestedDownload.isUrlSupportedByModel ? null : await download2(requestedDownload)
1263
+ async (requestedDownload) => requestedDownload.isUrlSupportedByModel ? null : await download2({ ...requestedDownload, abortSignal })
1264
1264
  )
1265
1265
  );
1266
1266
 
@@ -1409,14 +1409,15 @@ function convertToLanguageModelV4FilePart(content) {
1409
1409
  async function convertToLanguageModelPrompt({
1410
1410
  prompt,
1411
1411
  supportedUrls,
1412
- download: download2 = createDefaultDownloadFunction(),
1412
+ download: download2,
1413
+ abortSignal,
1413
1414
  // `provider` is only needed here to convert legacy tool output types via `mapToolResultOutput`.
1414
1415
  // TODO: remove in v8 when "file-id" and "image-file-id" types are removed
1415
1416
  provider
1416
1417
  }) {
1417
1418
  const downloadedAssets = await downloadAssets(
1418
1419
  prompt.messages,
1419
- download2,
1420
+ download2 != null ? download2 : createDefaultDownloadFunction(void 0, abortSignal),
1420
1421
  supportedUrls
1421
1422
  );
1422
1423
  const approvalIdToToolCallId = /* @__PURE__ */ new Map();
@@ -2040,9 +2041,6 @@ function getMediaTypeFromUrl(url, fallbackMediaType = "application/octet-stream"
2040
2041
 
2041
2042
  // src/prompt/create-tool-model-output.ts
2042
2043
  import { getErrorMessage as getErrorMessage3 } from "@ai-sdk/provider";
2043
- import {
2044
- parseJSON
2045
- } from "@ai-sdk/provider-utils";
2046
2044
  async function createToolModelOutput({
2047
2045
  toolCallId,
2048
2046
  input,
@@ -2053,19 +2051,19 @@ async function createToolModelOutput({
2053
2051
  if (errorMode === "text") {
2054
2052
  return { type: "error-text", value: getErrorMessage3(output) };
2055
2053
  } else if (errorMode === "json") {
2056
- return { type: "error-json", value: await toJSONValue(output) };
2054
+ return { type: "error-json", value: toJSONValue(output) };
2057
2055
  }
2058
2056
  if (tool3 == null ? void 0 : tool3.toModelOutput) {
2059
2057
  return await tool3.toModelOutput({ toolCallId, input, output });
2060
2058
  }
2061
- return typeof output === "string" ? { type: "text", value: output } : { type: "json", value: await toJSONValue(output) };
2059
+ return typeof output === "string" ? { type: "text", value: output } : { type: "json", value: toJSONValue(output) };
2062
2060
  }
2063
- async function toJSONValue(value) {
2061
+ function toJSONValue(value) {
2064
2062
  if (value === void 0) {
2065
2063
  return null;
2066
2064
  }
2067
2065
  const serialized = JSON.stringify(value);
2068
- return serialized === void 0 ? null : await parseJSON({ text: serialized });
2066
+ return serialized === void 0 ? null : JSON.parse(serialized);
2069
2067
  }
2070
2068
 
2071
2069
  // src/prompt/prepare-language-model-call-options.ts
@@ -6099,6 +6097,7 @@ async function generateText({
6099
6097
  },
6100
6098
  supportedUrls: await stepModel.supportedUrls,
6101
6099
  download: download2,
6100
+ abortSignal: mergedAbortSignal,
6102
6101
  provider: stepModel.provider.split(".")[0]
6103
6102
  });
6104
6103
  const stepProviderOptions = mergeObjects(
@@ -6266,22 +6265,29 @@ async function generateText({
6266
6265
  if (tool3 == null) {
6267
6266
  continue;
6268
6267
  }
6269
- if (tool3.onInputStart != null) {
6270
- await tool3.onInputStart({
6271
- toolCallId: toolCall.toolCallId,
6272
- messages: stepMessages,
6273
- abortSignal: mergedAbortSignal,
6274
- context: runtimeContext
6275
- });
6276
- }
6277
- if ((tool3 == null ? void 0 : tool3.onInputAvailable) != null) {
6278
- await tool3.onInputAvailable({
6279
- input: toolCall.input,
6280
- toolCallId: toolCall.toolCallId,
6281
- messages: stepMessages,
6282
- abortSignal: mergedAbortSignal,
6283
- context: runtimeContext
6268
+ if (tool3.onInputStart != null || tool3.onInputAvailable != null) {
6269
+ const context = await validateToolContext({
6270
+ toolName: toolCall.toolName,
6271
+ context: getOwn(toolsContext, toolCall.toolName),
6272
+ contextSchema: tool3.contextSchema
6284
6273
  });
6274
+ if (tool3.onInputStart != null) {
6275
+ await tool3.onInputStart({
6276
+ toolCallId: toolCall.toolCallId,
6277
+ messages: stepMessages,
6278
+ abortSignal: mergedAbortSignal,
6279
+ context
6280
+ });
6281
+ }
6282
+ if (tool3.onInputAvailable != null) {
6283
+ await tool3.onInputAvailable({
6284
+ input: toolCall.input,
6285
+ toolCallId: toolCall.toolCallId,
6286
+ messages: stepMessages,
6287
+ abortSignal: mergedAbortSignal,
6288
+ context
6289
+ });
6290
+ }
6285
6291
  }
6286
6292
  const toolApprovalStatus = await resolveToolApproval({
6287
6293
  tools: stepExecutionTools,
@@ -6784,10 +6790,13 @@ function writeToServerResponse({
6784
6790
  stream
6785
6791
  }) {
6786
6792
  const statusCode = status != null ? status : 200;
6793
+ if (headers != null) {
6794
+ response.setHeaders(headers);
6795
+ }
6787
6796
  if (statusText !== void 0) {
6788
- response.writeHead(statusCode, statusText, headers);
6797
+ response.writeHead(statusCode, statusText);
6789
6798
  } else {
6790
- response.writeHead(statusCode, headers);
6799
+ response.writeHead(statusCode);
6791
6800
  }
6792
6801
  const reader = stream.getReader();
6793
6802
  const read = async () => {
@@ -6827,11 +6836,9 @@ function pipeTextStreamToResponse({
6827
6836
  response,
6828
6837
  status,
6829
6838
  statusText,
6830
- headers: Object.fromEntries(
6831
- prepareHeaders(headers, {
6832
- "content-type": "text/plain; charset=utf-8"
6833
- }).entries()
6834
- ),
6839
+ headers: prepareHeaders(headers, {
6840
+ "content-type": "text/plain; charset=utf-8"
6841
+ }),
6835
6842
  stream: stream.pipeThrough(new TextEncoderStream())
6836
6843
  });
6837
6844
  }
@@ -6917,9 +6924,7 @@ function pipeUIMessageStreamToResponse({
6917
6924
  response,
6918
6925
  status,
6919
6926
  statusText,
6920
- headers: Object.fromEntries(
6921
- prepareHeaders(headers, UI_MESSAGE_STREAM_HEADERS).entries()
6922
- ),
6927
+ headers: prepareHeaders(headers, UI_MESSAGE_STREAM_HEADERS),
6923
6928
  stream: sseStream.pipeThrough(new TextEncoderStream())
6924
6929
  });
6925
6930
  }
@@ -8797,33 +8802,60 @@ function invokeToolCallbacksFromStream({
8797
8802
  tools,
8798
8803
  stepInputMessages,
8799
8804
  abortSignal,
8800
- runtimeContext
8805
+ toolsContext
8801
8806
  }) {
8802
8807
  if (tools == null) return stream;
8803
- const ongoingToolCallToolNames = createIdMap();
8808
+ let ongoingToolCalls = createIdMap();
8809
+ const getValidatedContext = ({
8810
+ toolCallId,
8811
+ toolName
8812
+ }) => {
8813
+ const ongoingToolCall = ongoingToolCalls[toolCallId];
8814
+ if ((ongoingToolCall == null ? void 0 : ongoingToolCall.validatedContext) != null) {
8815
+ return ongoingToolCall.validatedContext;
8816
+ }
8817
+ const tool3 = getOwn(tools, toolName);
8818
+ const validatedContext = validateToolContext({
8819
+ toolName,
8820
+ context: getOwn(toolsContext, toolName),
8821
+ contextSchema: tool3 == null ? void 0 : tool3.contextSchema
8822
+ });
8823
+ if (ongoingToolCall != null) {
8824
+ ongoingToolCall.validatedContext = validatedContext;
8825
+ }
8826
+ return validatedContext;
8827
+ };
8804
8828
  return stream.pipeThrough(
8805
8829
  new TransformStream({
8806
8830
  async transform(chunk, controller) {
8831
+ var _a25, _b25;
8807
8832
  controller.enqueue(chunk);
8808
8833
  if (isStreamRetryAttemptBoundaryPart(chunk)) {
8834
+ ongoingToolCalls = createIdMap();
8809
8835
  return;
8810
8836
  }
8811
8837
  switch (chunk.type) {
8812
8838
  case "tool-input-start": {
8813
- ongoingToolCallToolNames[chunk.id] = chunk.toolName;
8839
+ ongoingToolCalls[chunk.id] = {
8840
+ toolName: chunk.toolName,
8841
+ validatedContext: void 0
8842
+ };
8814
8843
  const tool3 = getOwn(tools, chunk.toolName);
8815
8844
  if ((tool3 == null ? void 0 : tool3.onInputStart) != null) {
8816
8845
  await tool3.onInputStart({
8817
8846
  toolCallId: chunk.id,
8818
8847
  messages: stepInputMessages,
8819
8848
  abortSignal,
8820
- context: runtimeContext
8849
+ context: await getValidatedContext({
8850
+ toolCallId: chunk.id,
8851
+ toolName: chunk.toolName
8852
+ })
8821
8853
  });
8822
8854
  }
8823
8855
  break;
8824
8856
  }
8825
8857
  case "tool-input-delta": {
8826
- const toolName = ongoingToolCallToolNames[chunk.id];
8858
+ const toolName = (_a25 = ongoingToolCalls[chunk.id]) == null ? void 0 : _a25.toolName;
8827
8859
  const tool3 = getOwn(tools, toolName);
8828
8860
  if ((tool3 == null ? void 0 : tool3.onInputDelta) != null) {
8829
8861
  await tool3.onInputDelta({
@@ -8831,23 +8863,32 @@ function invokeToolCallbacksFromStream({
8831
8863
  toolCallId: chunk.id,
8832
8864
  messages: stepInputMessages,
8833
8865
  abortSignal,
8834
- context: runtimeContext
8866
+ context: await getValidatedContext({
8867
+ toolCallId: chunk.id,
8868
+ toolName
8869
+ })
8835
8870
  });
8836
8871
  }
8837
8872
  break;
8838
8873
  }
8839
8874
  case "tool-call": {
8840
- const toolName = ongoingToolCallToolNames[chunk.toolCallId];
8875
+ const toolName = (_b25 = ongoingToolCalls[chunk.toolCallId]) == null ? void 0 : _b25.toolName;
8841
8876
  const tool3 = getOwn(tools, toolName);
8842
- delete ongoingToolCallToolNames[chunk.toolCallId];
8843
- if ((tool3 == null ? void 0 : tool3.onInputAvailable) != null) {
8877
+ if (!chunk.invalid && (tool3 == null ? void 0 : tool3.onInputAvailable) != null) {
8878
+ const validatedContext = getValidatedContext({
8879
+ toolCallId: chunk.toolCallId,
8880
+ toolName
8881
+ });
8882
+ delete ongoingToolCalls[chunk.toolCallId];
8844
8883
  await tool3.onInputAvailable({
8845
8884
  input: chunk.input,
8846
8885
  toolCallId: chunk.toolCallId,
8847
8886
  messages: stepInputMessages,
8848
8887
  abortSignal,
8849
- context: runtimeContext
8888
+ context: await validatedContext
8850
8889
  });
8890
+ } else {
8891
+ delete ongoingToolCalls[chunk.toolCallId];
8851
8892
  }
8852
8893
  }
8853
8894
  }
@@ -8990,6 +9031,7 @@ async function streamLanguageModelCall({
8990
9031
  },
8991
9032
  supportedUrls: await resolvedModel.supportedUrls,
8992
9033
  download: download2,
9034
+ abortSignal,
8993
9035
  provider: resolvedModel.provider.split(".")[0]
8994
9036
  });
8995
9037
  const stepTools = await prepareTools({
@@ -9680,13 +9722,15 @@ function createOutputTransformStream(output) {
9680
9722
  let text2 = "";
9681
9723
  let textChunk = "";
9682
9724
  let textProviderMetadata = void 0;
9683
- let lastPublishedValue = "";
9684
- function resetAttemptState() {
9725
+ let lastPublishedValue = void 0;
9726
+ let hasPublishedValue = false;
9727
+ function resetOutputState() {
9685
9728
  firstTextChunkId = void 0;
9686
9729
  text2 = "";
9687
9730
  textChunk = "";
9688
9731
  textProviderMetadata = void 0;
9689
- lastPublishedValue = "";
9732
+ lastPublishedValue = void 0;
9733
+ hasPublishedValue = false;
9690
9734
  }
9691
9735
  function enqueueChunk({
9692
9736
  controller,
@@ -9716,10 +9760,13 @@ function createOutputTransformStream(output) {
9716
9760
  async transform(chunk, controller) {
9717
9761
  var _a25;
9718
9762
  if (isStreamRetryBoundaryPart(chunk)) {
9719
- resetAttemptState();
9763
+ resetOutputState();
9720
9764
  controller.enqueue(chunk);
9721
9765
  return;
9722
9766
  }
9767
+ if (chunk.type === "start-step") {
9768
+ resetOutputState();
9769
+ }
9723
9770
  if (chunk.type === "finish-step" && textChunk.length > 0) {
9724
9771
  publishTextChunk({ controller });
9725
9772
  }
@@ -9769,9 +9816,10 @@ function createOutputTransformStream(output) {
9769
9816
  const result = await output.parsePartialOutput({ text: text2 });
9770
9817
  if (result !== void 0) {
9771
9818
  const currentValue = typeof result.partial === "string" ? result.partial : JSON.stringify(result.partial);
9772
- if (currentValue !== lastPublishedValue) {
9819
+ if (!hasPublishedValue || currentValue !== lastPublishedValue) {
9773
9820
  publishTextChunk({ controller, partialOutput: result.partial });
9774
9821
  lastPublishedValue = currentValue;
9822
+ hasPublishedValue = true;
9775
9823
  }
9776
9824
  }
9777
9825
  }
@@ -9934,6 +9982,8 @@ var DefaultStreamTextResult = class {
9934
9982
  const initialResponseMessages = [];
9935
9983
  let stepMessagesForNextStep;
9936
9984
  let currentStepMessages = [];
9985
+ let isAborted = false;
9986
+ let currentStepModel = model;
9937
9987
  const createPartIdReserver = () => {
9938
9988
  const usedIds = /* @__PURE__ */ new Set();
9939
9989
  return (id) => {
@@ -10100,8 +10150,8 @@ var DefaultStreamTextResult = class {
10100
10150
  const currentStepResult = new DefaultStepResult({
10101
10151
  callId,
10102
10152
  stepNumber: recordedSteps.length,
10103
- provider: model.provider,
10104
- modelId: model.modelId,
10153
+ provider: currentStepModel.provider,
10154
+ modelId: currentStepModel.modelId,
10105
10155
  runtimeContext,
10106
10156
  toolsContext,
10107
10157
  content: recordedContent,
@@ -10126,8 +10176,8 @@ var DefaultStreamTextResult = class {
10126
10176
  });
10127
10177
  logWarnings({
10128
10178
  warnings: recordedWarnings,
10129
- provider: model.provider,
10130
- model: model.modelId
10179
+ provider: currentStepModel.provider,
10180
+ model: currentStepModel.modelId
10131
10181
  });
10132
10182
  recordedSteps.push(currentStepResult);
10133
10183
  stepMessagesForNextStep = [
@@ -10157,6 +10207,9 @@ var DefaultStreamTextResult = class {
10157
10207
  self._rawFinishReason.resolve(recordedRawFinishReason);
10158
10208
  self._totalUsage.resolve(totalUsage);
10159
10209
  self._steps.resolve(recordedSteps);
10210
+ if (isAborted) {
10211
+ return;
10212
+ }
10160
10213
  const finalStep = recordedSteps[recordedSteps.length - 1];
10161
10214
  const content = recordedSteps.flatMap((step) => step.content);
10162
10215
  const files = recordedSteps.flatMap((step) => step.files);
@@ -10243,7 +10296,9 @@ var DefaultStreamTextResult = class {
10243
10296
  controller.enqueue({ type: "start" });
10244
10297
  },
10245
10298
  async pull(controller) {
10299
+ var _a25;
10246
10300
  async function abort() {
10301
+ isAborted = true;
10247
10302
  await notify({
10248
10303
  event: {
10249
10304
  callId,
@@ -10276,6 +10331,7 @@ var DefaultStreamTextResult = class {
10276
10331
  if (isAbortError(error) && (abortSignal == null ? void 0 : abortSignal.aborted)) {
10277
10332
  await abort();
10278
10333
  } else {
10334
+ await ((_a25 = telemetryDispatcher.onError) == null ? void 0 : _a25.call(telemetryDispatcher, { callId, error }));
10279
10335
  controller.error(error);
10280
10336
  }
10281
10337
  }
@@ -10616,6 +10672,7 @@ var DefaultStreamTextResult = class {
10616
10672
  const stepModel = resolveLanguageModel(
10617
10673
  (_e = prepareStepResult == null ? void 0 : prepareStepResult.model) != null ? _e : model
10618
10674
  );
10675
+ currentStepModel = stepModel;
10619
10676
  const stepActiveTools = filterActiveTools({
10620
10677
  tools,
10621
10678
  activeTools: (_f = prepareStepResult == null ? void 0 : prepareStepResult.activeTools) != null ? _f : activeTools
@@ -10866,7 +10923,7 @@ var DefaultStreamTextResult = class {
10866
10923
  tools: stepExecutionTools,
10867
10924
  stepInputMessages: stepMessages,
10868
10925
  abortSignal,
10869
- runtimeContext
10926
+ toolsContext
10870
10927
  });
10871
10928
  const runInTracingChannelSpanInStep = telemetryDispatcher.runInTracingChannelSpan == null ? void 0 : (options) => runInStepTracingChannelContext(
10872
10929
  () => telemetryDispatcher.runInTracingChannelSpan(options)
@@ -10928,7 +10985,7 @@ var DefaultStreamTextResult = class {
10928
10985
  const createStepResponse = () => ({
10929
10986
  id: generateId5(),
10930
10987
  timestamp: /* @__PURE__ */ new Date(),
10931
- modelId: model.modelId
10988
+ modelId: stepModel.modelId
10932
10989
  });
10933
10990
  let stepResponse = createStepResponse();
10934
10991
  const textPartIds = /* @__PURE__ */ new Map();
@@ -11399,7 +11456,7 @@ var DefaultStreamTextResult = class {
11399
11456
  this.teeStream().pipeThrough(
11400
11457
  new TransformStream({
11401
11458
  transform({ partialOutput }, controller) {
11402
- if (partialOutput != null) {
11459
+ if (partialOutput !== void 0) {
11403
11460
  controller.enqueue(partialOutput);
11404
11461
  }
11405
11462
  }
@@ -11889,9 +11946,15 @@ function readUIMessageStream({
11889
11946
  var _a25;
11890
11947
  let controller;
11891
11948
  let hasErrored = false;
11949
+ let isCancelled = false;
11950
+ const abortController = new AbortController();
11892
11951
  const outputStream = new ReadableStream({
11893
11952
  start(controllerParam) {
11894
11953
  controller = controllerParam;
11954
+ },
11955
+ cancel() {
11956
+ isCancelled = true;
11957
+ abortController.abort();
11895
11958
  }
11896
11959
  });
11897
11960
  const state = createStreamingUIMessageState({
@@ -11912,15 +11975,18 @@ function readUIMessageStream({
11912
11975
  return job({
11913
11976
  state,
11914
11977
  write: () => {
11915
- controller == null ? void 0 : controller.enqueue(createUIMessageSnapshot(state.message));
11978
+ if (!isCancelled) {
11979
+ controller == null ? void 0 : controller.enqueue(createUIMessageSnapshot(state.message));
11980
+ }
11916
11981
  }
11917
11982
  });
11918
11983
  },
11919
11984
  onError: handleError
11920
11985
  }),
11921
- onError: handleError
11986
+ onError: handleError,
11987
+ abortSignal: abortController.signal
11922
11988
  }).finally(() => {
11923
- if (!hasErrored) {
11989
+ if (!hasErrored && !isCancelled) {
11924
11990
  controller == null ? void 0 : controller.close();
11925
11991
  }
11926
11992
  });
@@ -13322,6 +13388,7 @@ async function startBatch({
13322
13388
  prompt: standardizedPrompt,
13323
13389
  supportedUrls,
13324
13390
  download: void 0,
13391
+ abortSignal: operationAbortSignal,
13325
13392
  provider: batchApi.provider.split(".")[0]
13326
13393
  }),
13327
13394
  tools: preparedTools,
@@ -15127,6 +15194,7 @@ async function generateObject(options) {
15127
15194
  prompt: standardizedPrompt,
15128
15195
  supportedUrls: await model.supportedUrls,
15129
15196
  download: download2,
15197
+ abortSignal,
15130
15198
  provider: model.provider.split(".")[0]
15131
15199
  });
15132
15200
  await notify({
@@ -15305,8 +15373,13 @@ function createDownload(options) {
15305
15373
  // src/util/data-url.ts
15306
15374
  var { atob: atob2 } = globalThis;
15307
15375
  function getTextFromDataUrl(dataUrl) {
15376
+ var _a25;
15308
15377
  const [header, base64Content] = dataUrl.split(",");
15309
15378
  const mediaType = header.split(";")[0].split(":")[1];
15379
+ const charsetMatch = /(?:^|;)\s*charset\s*=\s*(?:"([^"]+)"|([^;\s]+))/i.exec(
15380
+ header
15381
+ );
15382
+ const charset = (_a25 = charsetMatch == null ? void 0 : charsetMatch[1]) != null ? _a25 : charsetMatch == null ? void 0 : charsetMatch[2];
15310
15383
  if (mediaType == null || base64Content == null) {
15311
15384
  throw new InvalidArgumentError({
15312
15385
  parameter: "dataUrl",
@@ -15315,7 +15388,13 @@ function getTextFromDataUrl(dataUrl) {
15315
15388
  });
15316
15389
  }
15317
15390
  try {
15318
- return atob2(base64Content);
15391
+ const byteString = atob2(base64Content);
15392
+ if (charset == null) {
15393
+ return byteString;
15394
+ }
15395
+ return new TextDecoder(charset).decode(
15396
+ Uint8Array.from(byteString, (byte) => byte.codePointAt(0))
15397
+ );
15319
15398
  } catch (e) {
15320
15399
  throw new InvalidArgumentError({
15321
15400
  parameter: "dataUrl",
@@ -15575,6 +15654,7 @@ var DefaultStreamObjectResult = class {
15575
15654
  prompt: standardizedPrompt,
15576
15655
  supportedUrls: await model.supportedUrls,
15577
15656
  download: download2,
15657
+ abortSignal,
15578
15658
  provider: model.provider.split(".")[0]
15579
15659
  }),
15580
15660
  providerOptions,
@@ -15983,7 +16063,7 @@ async function generateSpeech({
15983
16063
  abortSignal,
15984
16064
  headers
15985
16065
  }) {
15986
- var _a25;
16066
+ var _a25, _b25;
15987
16067
  const resolvedModel = resolveSpeechModel(model);
15988
16068
  if (!resolvedModel) {
15989
16069
  throw new Error("Model could not be resolved");
@@ -16017,19 +16097,41 @@ async function generateSpeech({
16017
16097
  provider: resolvedModel.provider,
16018
16098
  model: resolvedModel.modelId
16019
16099
  });
16100
+ const detectedMediaType = detectMediaType4({
16101
+ data: result.audio,
16102
+ topLevelType: "audio"
16103
+ });
16020
16104
  return new DefaultSpeechResult({
16021
16105
  audio: new DefaultGeneratedAudioFile({
16022
16106
  data: result.audio,
16023
- mediaType: (_a25 = detectMediaType4({
16024
- data: result.audio,
16025
- topLevelType: "audio"
16026
- })) != null ? _a25 : "audio/mp3"
16107
+ mediaType: (_b25 = (_a25 = detectedMediaType != null ? detectedMediaType : getResponseAudioMediaType(result.response.headers)) != null ? _a25 : getOutputFormatMediaType(outputFormat)) != null ? _b25 : "audio/mp3"
16027
16108
  }),
16028
16109
  warnings: result.warnings,
16029
16110
  responses: [result.response],
16030
16111
  providerMetadata: result.providerMetadata
16031
16112
  });
16032
16113
  }
16114
+ function getResponseAudioMediaType(headers) {
16115
+ var _a25;
16116
+ const mediaType = (_a25 = Object.entries(headers != null ? headers : {}).find(
16117
+ ([name25]) => name25.toLowerCase() === "content-type"
16118
+ )) == null ? void 0 : _a25[1];
16119
+ if (mediaType == null) {
16120
+ return void 0;
16121
+ }
16122
+ const normalizedMediaType = mediaType.split(";", 1)[0].trim().toLowerCase();
16123
+ if (normalizedMediaType.length === 0) {
16124
+ return void 0;
16125
+ }
16126
+ return normalizedMediaType.startsWith("audio/") ? normalizedMediaType : void 0;
16127
+ }
16128
+ function getOutputFormatMediaType(outputFormat) {
16129
+ if (outputFormat == null) {
16130
+ return void 0;
16131
+ }
16132
+ const normalizedOutputFormat = outputFormat.trim().toLowerCase();
16133
+ return normalizedOutputFormat === "pcm" || normalizedOutputFormat === "audio/pcm" ? "audio/pcm" : void 0;
16134
+ }
16033
16135
  var DefaultSpeechResult = class {
16034
16136
  constructor(options) {
16035
16137
  var _a25;
@@ -16099,11 +16201,13 @@ function pruneMessages({
16099
16201
  }
16100
16202
  }
16101
16203
  }
16204
+ const approvalIdToToolCallId = /* @__PURE__ */ new Map();
16102
16205
  const approvalIdToToolName = /* @__PURE__ */ new Map();
16103
16206
  for (const message of messages) {
16104
16207
  if ((message.role === "assistant" || message.role === "tool") && typeof message.content !== "string") {
16105
16208
  for (const part of message.content) {
16106
16209
  if (part.type === "tool-approval-request") {
16210
+ approvalIdToToolCallId.set(part.approvalId, part.toolCallId);
16107
16211
  const toolName = toolCallIdToToolName.get(part.toolCallId);
16108
16212
  if (toolName != null) {
16109
16213
  approvalIdToToolName.set(part.approvalId, toolName);
@@ -16112,6 +16216,12 @@ function pruneMessages({
16112
16216
  }
16113
16217
  }
16114
16218
  }
16219
+ for (const approvalId of keptApprovalIds) {
16220
+ const toolCallId = approvalIdToToolCallId.get(approvalId);
16221
+ if (toolCallId != null) {
16222
+ keptToolCallIds.add(toolCallId);
16223
+ }
16224
+ }
16115
16225
  messages = messages.map((message, messageIndex) => {
16116
16226
  if (message.role !== "assistant" && message.role !== "tool" || typeof message.content === "string" || keepLastMessagesCount && messageIndex >= messages.length - keepLastMessagesCount) {
16117
16227
  return message;
@@ -16329,7 +16439,7 @@ async function experimental_generateVideo({
16329
16439
  headers != null ? headers : {},
16330
16440
  `ai/${VERSION}`
16331
16441
  );
16332
- const { retry } = prepareRetries({
16442
+ const { maxRetries, retry } = prepareRetries({
16333
16443
  maxRetries: maxRetriesArg,
16334
16444
  abortSignal
16335
16445
  });
@@ -16389,6 +16499,7 @@ async function experimental_generateVideo({
16389
16499
  callOptions,
16390
16500
  poll,
16391
16501
  webhook,
16502
+ maxRetries,
16392
16503
  retry
16393
16504
  });
16394
16505
  }
@@ -16477,6 +16588,7 @@ async function executeStartStatusFlow({
16477
16588
  callOptions,
16478
16589
  poll: pollConfig,
16479
16590
  webhook: webhookFactory,
16591
+ maxRetries,
16480
16592
  retry
16481
16593
  }) {
16482
16594
  var _a25, _b25, _c, _d;
@@ -16518,6 +16630,9 @@ async function executeStartStatusFlow({
16518
16630
  const timeoutMs = (_c = pollConfig == null ? void 0 : pollConfig.timeoutMs) != null ? _c : 6e5;
16519
16631
  const delay = (_d = pollConfig == null ? void 0 : pollConfig.delay) != null ? _d : defaultDelay;
16520
16632
  const startTime = Date.now();
16633
+ const pollingTimeoutError = new Error(
16634
+ `Video generation timed out after ${timeoutMs}ms.`
16635
+ );
16521
16636
  if (webhookReceived != null) {
16522
16637
  await waitForWebhook({
16523
16638
  received: webhookReceived,
@@ -16530,22 +16645,65 @@ async function executeStartStatusFlow({
16530
16645
  if (webhookReceived == null) {
16531
16646
  const elapsedMs = Date.now() - startTime;
16532
16647
  if (elapsedMs >= timeoutMs) {
16533
- throw new Error(`Video generation timed out after ${timeoutMs}ms.`);
16648
+ throw pollingTimeoutError;
16534
16649
  }
16535
16650
  await delay(Math.min(intervalMs, timeoutMs - elapsedMs), {
16536
16651
  abortSignal: callOptions.abortSignal
16537
16652
  });
16538
16653
  if (Date.now() - startTime >= timeoutMs) {
16539
- throw new Error(`Video generation timed out after ${timeoutMs}ms.`);
16654
+ throw pollingTimeoutError;
16655
+ }
16656
+ }
16657
+ let statusResult;
16658
+ if (webhookReceived != null) {
16659
+ statusResult = await retry(
16660
+ () => model.doStatus({
16661
+ operation: startResult.operation,
16662
+ abortSignal: callOptions.abortSignal,
16663
+ headers: callOptions.headers
16664
+ })
16665
+ );
16666
+ } else {
16667
+ const statusTimeoutController = new AbortController();
16668
+ const statusAbortSignal = mergeAbortSignals(
16669
+ callOptions.abortSignal,
16670
+ statusTimeoutController.signal
16671
+ );
16672
+ const statusTimeoutId = setTimeout(
16673
+ () => statusTimeoutController.abort(pollingTimeoutError),
16674
+ timeoutMs - (Date.now() - startTime)
16675
+ );
16676
+ const statusTimeoutPromise = new Promise((_, reject) => {
16677
+ statusTimeoutController.signal.addEventListener(
16678
+ "abort",
16679
+ () => reject(pollingTimeoutError),
16680
+ { once: true }
16681
+ );
16682
+ });
16683
+ const { retry: statusRetry } = prepareRetries({
16684
+ maxRetries,
16685
+ abortSignal: statusAbortSignal
16686
+ });
16687
+ try {
16688
+ statusResult = await Promise.race([
16689
+ statusRetry(
16690
+ () => model.doStatus({
16691
+ operation: startResult.operation,
16692
+ abortSignal: statusAbortSignal,
16693
+ headers: callOptions.headers
16694
+ })
16695
+ ),
16696
+ statusTimeoutPromise
16697
+ ]);
16698
+ } catch (error) {
16699
+ if (statusTimeoutController.signal.aborted) {
16700
+ throw pollingTimeoutError;
16701
+ }
16702
+ throw error;
16703
+ } finally {
16704
+ clearTimeout(statusTimeoutId);
16540
16705
  }
16541
16706
  }
16542
- const statusResult = await retry(
16543
- () => model.doStatus({
16544
- operation: startResult.operation,
16545
- abortSignal: callOptions.abortSignal,
16546
- headers: callOptions.headers
16547
- })
16548
- );
16549
16707
  if (statusResult.status === "error") {
16550
16708
  throw new Error(statusResult.error);
16551
16709
  }
@@ -16895,6 +17053,23 @@ function defaultTransform(text2) {
16895
17053
  function stripMarkdownCodeFenceSuffix(text2) {
16896
17054
  return text2.replace(/\n?```\s*$/, "").trimEnd();
16897
17055
  }
17056
+ function getPotentialSuffixStart(text2) {
17057
+ let index = text2.length;
17058
+ while (index > 0 && /\s/.test(text2[index - 1])) {
17059
+ index--;
17060
+ }
17061
+ let backtickCount = 0;
17062
+ while (index > 0 && backtickCount < 3 && text2[index - 1] === "`") {
17063
+ index--;
17064
+ backtickCount++;
17065
+ }
17066
+ if (backtickCount > 0) {
17067
+ while (index > 0 && /\s/.test(text2[index - 1])) {
17068
+ index--;
17069
+ }
17070
+ }
17071
+ return index;
17072
+ }
16898
17073
  function extractJsonMiddleware(options) {
16899
17074
  var _a25;
16900
17075
  const transform = (_a25 = options == null ? void 0 : options.transform) != null ? _a25 : defaultTransform;
@@ -16919,7 +17094,6 @@ function extractJsonMiddleware(options) {
16919
17094
  wrapStream: async ({ doStream }) => {
16920
17095
  const { stream, ...rest } = await doStream();
16921
17096
  const textBlocks = createIdMap();
16922
- const SUFFIX_BUFFER_SIZE = 12;
16923
17097
  return {
16924
17098
  stream: stream.pipeThrough(
16925
17099
  new TransformStream({
@@ -16968,9 +17142,15 @@ function extractJsonMiddleware(options) {
16968
17142
  controller.enqueue(block.startEvent);
16969
17143
  }
16970
17144
  }
16971
- if (block.phase === "streaming" && block.buffer.length > SUFFIX_BUFFER_SIZE) {
16972
- const toStream = block.buffer.slice(0, -SUFFIX_BUFFER_SIZE);
16973
- block.buffer = block.buffer.slice(-SUFFIX_BUFFER_SIZE);
17145
+ if (block.phase === "streaming") {
17146
+ const potentialSuffixStart = getPotentialSuffixStart(
17147
+ block.buffer
17148
+ );
17149
+ const toStream = block.buffer.slice(0, potentialSuffixStart);
17150
+ block.buffer = block.buffer.slice(potentialSuffixStart);
17151
+ if (toStream.length === 0) {
17152
+ return;
17153
+ }
16974
17154
  controller.enqueue({
16975
17155
  type: "text-delta",
16976
17156
  id: chunk.id,
@@ -17211,7 +17391,11 @@ function simulateStreamingMiddleware() {
17211
17391
  switch (part.type) {
17212
17392
  case "text": {
17213
17393
  if (part.text.length > 0) {
17214
- controller.enqueue({ type: "text-start", id: String(id) });
17394
+ controller.enqueue({
17395
+ type: "text-start",
17396
+ id: String(id),
17397
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
17398
+ });
17215
17399
  controller.enqueue({
17216
17400
  type: "text-delta",
17217
17401
  id: String(id),
@@ -17490,7 +17674,9 @@ function wrapProvider({
17490
17674
  },
17491
17675
  transcriptionModel: providerV4.transcriptionModel,
17492
17676
  speechModel: providerV4.speechModel,
17493
- rerankingModel: providerV4.rerankingModel
17677
+ rerankingModel: providerV4.rerankingModel,
17678
+ ...providerV4.files != null ? { files: providerV4.files } : {},
17679
+ ...providerV4.skills != null ? { skills: providerV4.skills } : {}
17494
17680
  };
17495
17681
  }
17496
17682
 
@@ -21471,6 +21657,10 @@ import {
21471
21657
  resolve as resolve2
21472
21658
  } from "@ai-sdk/provider-utils";
21473
21659
  import { EmptyResponseBodyError as EmptyResponseBodyError3 } from "@ai-sdk/provider";
21660
+ function appendPathToUrl(url, path) {
21661
+ const queryOrFragmentStart = url.search(/[?#]/);
21662
+ return queryOrFragmentStart === -1 ? `${url}${path}` : `${url.slice(0, queryOrFragmentStart)}${path}${url.slice(queryOrFragmentStart)}`;
21663
+ }
21474
21664
  var HttpChatTransport = class {
21475
21665
  constructor({
21476
21666
  api = "/api/chat",
@@ -21527,7 +21717,7 @@ var HttpChatTransport = class {
21527
21717
  const response = await fetch2(api, {
21528
21718
  method: "POST",
21529
21719
  headers: {
21530
- "Content-Type": "application/json",
21720
+ "content-type": "application/json",
21531
21721
  ...headers
21532
21722
  },
21533
21723
  body: JSON.stringify(body),
@@ -21565,7 +21755,7 @@ var HttpChatTransport = class {
21565
21755
  credentials: resolvedCredentials,
21566
21756
  requestMetadata: options.metadata
21567
21757
  }));
21568
- const api = (_b25 = preparedRequest == null ? void 0 : preparedRequest.api) != null ? _b25 : `${this.api}/${options.chatId}/stream`;
21758
+ const api = (_b25 = preparedRequest == null ? void 0 : preparedRequest.api) != null ? _b25 : appendPathToUrl(this.api, `/${options.chatId}/stream`);
21569
21759
  const headers = (preparedRequest == null ? void 0 : preparedRequest.headers) !== void 0 ? normalizeHeaders(preparedRequest.headers) : baseHeaders;
21570
21760
  const credentials = (_c = preparedRequest == null ? void 0 : preparedRequest.credentials) != null ? _c : resolvedCredentials;
21571
21761
  const fetch2 = (_d = this.fetch) != null ? _d : globalThis.fetch;
@@ -22151,7 +22341,7 @@ function lastAssistantMessageIsCompleteWithApprovalResponses({
22151
22341
  // has at least one tool approval response
22152
22342
  lastStepToolInvocations.filter((part) => part.state === "approval-responded").length > 0 && // all tool approvals must have a response
22153
22343
  lastStepToolInvocations.every(
22154
- (part) => part.state === "output-available" || part.state === "output-error" || part.state === "output-denied" || part.state === "approval-responded"
22344
+ (part) => part.state === "output-available" && part.preliminary !== true || part.state === "output-error" || part.state === "output-denied" || part.state === "approval-responded"
22155
22345
  )
22156
22346
  );
22157
22347
  }
@@ -22172,7 +22362,7 @@ function lastAssistantMessageIsCompleteWithToolCalls({
22172
22362
  }, -1);
22173
22363
  const lastStepToolInvocations = message.parts.slice(lastStepStartIndex + 1).filter(isToolUIPart).filter((part) => !part.providerExecuted);
22174
22364
  return lastStepToolInvocations.length > 0 && lastStepToolInvocations.every(
22175
- (part) => part.state === "output-available" || part.state === "output-error"
22365
+ (part) => part.state === "output-available" && part.preliminary !== true || part.state === "output-error"
22176
22366
  );
22177
22367
  }
22178
22368