ai 6.0.285 → 6.0.287

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/CHANGELOG.md CHANGED
@@ -1,5 +1,30 @@
1
1
  # ai
2
2
 
3
+ ## 6.0.287
4
+
5
+ ### Patch Changes
6
+
7
+ - 9af6cfa: fix(ai): preserve provider metadata when converting failed tool calls
8
+ - Updated dependencies [5f2d078]
9
+ - Updated dependencies [1096a27]
10
+ - Updated dependencies [2a82d35]
11
+ - Updated dependencies [82e18b0]
12
+ - Updated dependencies [eea6869]
13
+ - @ai-sdk/gateway@3.0.197
14
+ - @ai-sdk/provider-utils@4.0.52
15
+
16
+ ## 6.0.286
17
+
18
+ ### Patch Changes
19
+
20
+ - 8a9722e: fix(ai): preserve provider metadata when simulating text streams
21
+ - 6a0f2d9: fix(ai): report the prepareStep model in streamed step results
22
+ - db02971: fix(ai): prevent unhandled rejections when UI message stream reading stops early
23
+ - 4d91999: fix(ai): preserve tool calls required by retained pending approvals
24
+ - b2ad994: fix(ai): cancel prompt attachment downloads when model calls are aborted or time out
25
+ - 9c85bd4: fix(ai): stream null and empty string JSON partial outputs
26
+ - becaa32: fix(ai): stream structured output from the final tool-loop step
27
+
3
28
  ## 6.0.285
4
29
 
5
30
  ### Patch Changes
package/dist/index.js CHANGED
@@ -1334,7 +1334,7 @@ function detectMediaType({
1334
1334
  var import_provider_utils3 = require("@ai-sdk/provider-utils");
1335
1335
 
1336
1336
  // src/version.ts
1337
- var VERSION = true ? "6.0.285" : "0.0.0-test";
1337
+ var VERSION = true ? "6.0.287" : "0.0.0-test";
1338
1338
 
1339
1339
  // src/util/download/download.ts
1340
1340
  var download = async ({
@@ -1381,9 +1381,9 @@ var download = async ({
1381
1381
  };
1382
1382
 
1383
1383
  // src/util/download/download-function.ts
1384
- var createDefaultDownloadFunction = (download2 = download) => (requestedDownloads) => Promise.all(
1384
+ var createDefaultDownloadFunction = (download2 = download, abortSignal) => (requestedDownloads) => Promise.all(
1385
1385
  requestedDownloads.map(
1386
- async (requestedDownload) => requestedDownload.isUrlSupportedByModel ? null : download2(requestedDownload)
1386
+ async (requestedDownload) => requestedDownload.isUrlSupportedByModel ? null : await download2({ ...requestedDownload, abortSignal })
1387
1387
  )
1388
1388
  );
1389
1389
 
@@ -1519,11 +1519,12 @@ function convertDataContentToUint8Array(content) {
1519
1519
  async function convertToLanguageModelPrompt({
1520
1520
  prompt,
1521
1521
  supportedUrls,
1522
- download: download2 = createDefaultDownloadFunction()
1522
+ download: download2,
1523
+ abortSignal
1523
1524
  }) {
1524
1525
  const downloadedAssets = await downloadAssets(
1525
1526
  prompt.messages,
1526
- download2,
1527
+ download2 != null ? download2 : createDefaultDownloadFunction(void 0, abortSignal),
1527
1528
  supportedUrls
1528
1529
  );
1529
1530
  const approvalIdToToolCallId = /* @__PURE__ */ new Map();
@@ -4815,7 +4816,8 @@ async function generateText({
4815
4816
  messages: (_c = prepareStepResult == null ? void 0 : prepareStepResult.messages) != null ? _c : stepInputMessages
4816
4817
  },
4817
4818
  supportedUrls: await stepModel.supportedUrls,
4818
- download: download2
4819
+ download: download2,
4820
+ abortSignal: mergedAbortSignal
4819
4821
  });
4820
4822
  experimental_context = (_d = prepareStepResult == null ? void 0 : prepareStepResult.experimental_context) != null ? _d : experimental_context;
4821
4823
  const stepActiveTools = (_e = prepareStepResult == null ? void 0 : prepareStepResult.activeTools) != null ? _e : activeTools;
@@ -7294,7 +7296,15 @@ function createOutputTransformStream(output) {
7294
7296
  let text2 = "";
7295
7297
  let textChunk = "";
7296
7298
  let textProviderMetadata = void 0;
7297
- let lastPublishedValue = "";
7299
+ let lastPublishedValue = void 0;
7300
+ let hasPublishedValue = false;
7301
+ function resetOutputState() {
7302
+ firstTextChunkId = void 0;
7303
+ text2 = "";
7304
+ textChunk = "";
7305
+ textProviderMetadata = void 0;
7306
+ lastPublishedValue = "";
7307
+ }
7298
7308
  function publishTextChunk({
7299
7309
  controller,
7300
7310
  partialOutput = void 0
@@ -7313,6 +7323,9 @@ function createOutputTransformStream(output) {
7313
7323
  return new TransformStream({
7314
7324
  async transform(chunk, controller) {
7315
7325
  var _a23;
7326
+ if (chunk.type === "start-step") {
7327
+ resetOutputState();
7328
+ }
7316
7329
  if (chunk.type === "finish-step" && textChunk.length > 0) {
7317
7330
  publishTextChunk({ controller });
7318
7331
  }
@@ -7347,9 +7360,10 @@ function createOutputTransformStream(output) {
7347
7360
  const result = await output.parsePartialOutput({ text: text2 });
7348
7361
  if (result !== void 0) {
7349
7362
  const currentValue = typeof result.partial === "string" ? result.partial : JSON.stringify(result.partial);
7350
- if (currentValue !== lastPublishedValue) {
7363
+ if (!hasPublishedValue || currentValue !== lastPublishedValue) {
7351
7364
  publishTextChunk({ controller, partialOutput: result.partial });
7352
7365
  lastPublishedValue = currentValue;
7366
+ hasPublishedValue = true;
7353
7367
  }
7354
7368
  }
7355
7369
  }
@@ -7420,6 +7434,7 @@ var DefaultStreamTextResult = class {
7420
7434
  const recordedSteps = [];
7421
7435
  let recordedNoOutputError;
7422
7436
  let currentStepToolSet = tools;
7437
+ let currentStepModel = model;
7423
7438
  const createPartIdReserver = () => {
7424
7439
  const usedIds = /* @__PURE__ */ new Set();
7425
7440
  return (id) => {
@@ -7576,7 +7591,10 @@ var DefaultStreamTextResult = class {
7576
7591
  });
7577
7592
  const currentStepResult = new DefaultStepResult({
7578
7593
  stepNumber: recordedSteps.length,
7579
- model: modelInfo,
7594
+ model: {
7595
+ provider: currentStepModel.provider,
7596
+ modelId: currentStepModel.modelId
7597
+ },
7580
7598
  ...callbackTelemetryProps,
7581
7599
  experimental_context,
7582
7600
  content: recordedContent,
@@ -7597,8 +7615,8 @@ var DefaultStreamTextResult = class {
7597
7615
  });
7598
7616
  logWarnings({
7599
7617
  warnings: recordedWarnings,
7600
- provider: modelInfo.provider,
7601
- model: modelInfo.modelId
7618
+ provider: currentStepModel.provider,
7619
+ model: currentStepModel.modelId
7602
7620
  });
7603
7621
  recordedSteps.push(currentStepResult);
7604
7622
  recordedResponseMessages.push(...stepMessages);
@@ -8037,6 +8055,7 @@ var DefaultStreamTextResult = class {
8037
8055
  const stepModel = resolveLanguageModel(
8038
8056
  (_a23 = prepareStepResult == null ? void 0 : prepareStepResult.model) != null ? _a23 : model
8039
8057
  );
8058
+ currentStepModel = stepModel;
8040
8059
  const stepModelInfo = {
8041
8060
  provider: stepModel.provider,
8042
8061
  modelId: stepModel.modelId
@@ -8047,7 +8066,8 @@ var DefaultStreamTextResult = class {
8047
8066
  messages: (_c = prepareStepResult == null ? void 0 : prepareStepResult.messages) != null ? _c : stepInputMessages
8048
8067
  },
8049
8068
  supportedUrls: await stepModel.supportedUrls,
8050
- download: download2
8069
+ download: download2,
8070
+ abortSignal
8051
8071
  });
8052
8072
  const stepActiveTools = (_d = prepareStepResult == null ? void 0 : prepareStepResult.activeTools) != null ? _d : activeTools;
8053
8073
  const stepToolSet = filterActiveTools({
@@ -8196,7 +8216,7 @@ var DefaultStreamTextResult = class {
8196
8216
  let stepResponse = {
8197
8217
  id: generateId2(),
8198
8218
  timestamp: /* @__PURE__ */ new Date(),
8199
- modelId: modelInfo.modelId
8219
+ modelId: stepModelInfo.modelId
8200
8220
  };
8201
8221
  let activeText = "";
8202
8222
  const textPartIds = /* @__PURE__ */ new Map();
@@ -8718,7 +8738,7 @@ var DefaultStreamTextResult = class {
8718
8738
  this.teeStream().pipeThrough(
8719
8739
  new TransformStream({
8720
8740
  transform({ partialOutput }, controller) {
8721
- if (partialOutput != null) {
8741
+ if (partialOutput !== void 0) {
8722
8742
  controller.enqueue(partialOutput);
8723
8743
  }
8724
8744
  }
@@ -9410,9 +9430,15 @@ function readUIMessageStream({
9410
9430
  var _a23;
9411
9431
  let controller;
9412
9432
  let hasErrored = false;
9433
+ let isCancelled = false;
9434
+ const abortController = new AbortController();
9413
9435
  const outputStream = new ReadableStream({
9414
9436
  start(controllerParam) {
9415
9437
  controller = controllerParam;
9438
+ },
9439
+ cancel() {
9440
+ isCancelled = true;
9441
+ abortController.abort();
9416
9442
  }
9417
9443
  });
9418
9444
  const state = createStreamingUIMessageState({
@@ -9433,15 +9459,18 @@ function readUIMessageStream({
9433
9459
  return job({
9434
9460
  state,
9435
9461
  write: () => {
9436
- controller == null ? void 0 : controller.enqueue(createUIMessageSnapshot(state.message));
9462
+ if (!isCancelled) {
9463
+ controller == null ? void 0 : controller.enqueue(createUIMessageSnapshot(state.message));
9464
+ }
9437
9465
  }
9438
9466
  });
9439
9467
  },
9440
9468
  onError: handleError
9441
9469
  }),
9442
- onError: handleError
9470
+ onError: handleError,
9471
+ abortSignal: abortController.signal
9443
9472
  }).finally(() => {
9444
- if (!hasErrored) {
9473
+ if (!hasErrored && !isCancelled) {
9445
9474
  controller == null ? void 0 : controller.close();
9446
9475
  }
9447
9476
  });
@@ -9514,7 +9543,7 @@ async function convertToModelMessages(messages, options) {
9514
9543
  if (message.parts != null) {
9515
9544
  let block = [];
9516
9545
  async function processBlock() {
9517
- var _a23, _b, _c, _d, _e, _f, _g, _h;
9546
+ var _a23, _b, _c, _d, _e, _f, _g, _h, _i;
9518
9547
  if (block.length === 0) {
9519
9548
  return;
9520
9549
  }
@@ -9543,13 +9572,14 @@ async function convertToModelMessages(messages, options) {
9543
9572
  } else if (isToolUIPart(part)) {
9544
9573
  const toolName = getToolName(part);
9545
9574
  if (part.state !== "input-streaming") {
9575
+ const callProviderMetadata = (_a23 = part.callProviderMetadata) != null ? _a23 : part.state === "output-error" ? part.resultProviderMetadata : void 0;
9546
9576
  content.push({
9547
9577
  type: "tool-call",
9548
9578
  toolCallId: part.toolCallId,
9549
9579
  toolName,
9550
- input: part.state === "output-error" ? (_a23 = part.input) != null ? _a23 : "rawInput" in part ? part.rawInput : void 0 : part.input,
9580
+ input: part.state === "output-error" ? (_b = part.input) != null ? _b : "rawInput" in part ? part.rawInput : void 0 : part.input,
9551
9581
  providerExecuted: part.providerExecuted,
9552
- ...part.callProviderMetadata != null ? { providerOptions: part.callProviderMetadata } : {}
9582
+ ...callProviderMetadata != null ? { providerOptions: callProviderMetadata } : {}
9553
9583
  });
9554
9584
  if (part.approval != null) {
9555
9585
  content.push({
@@ -9560,7 +9590,7 @@ async function convertToModelMessages(messages, options) {
9560
9590
  });
9561
9591
  }
9562
9592
  if (part.providerExecuted === true && part.state !== "approval-responded" && (part.state === "output-available" || part.state === "output-error")) {
9563
- const resultProviderMetadata = (_b = part.resultProviderMetadata) != null ? _b : part.callProviderMetadata;
9593
+ const resultProviderMetadata = (_c = part.resultProviderMetadata) != null ? _c : part.callProviderMetadata;
9564
9594
  content.push({
9565
9595
  type: "tool-result",
9566
9596
  toolCallId: part.toolCallId,
@@ -9569,7 +9599,7 @@ async function convertToModelMessages(messages, options) {
9569
9599
  toolCallId: part.toolCallId,
9570
9600
  input: part.input,
9571
9601
  output: part.state === "output-error" ? part.errorText : part.output,
9572
- tool: (_c = options == null ? void 0 : options.tools) == null ? void 0 : _c[toolName],
9602
+ tool: (_d = options == null ? void 0 : options.tools) == null ? void 0 : _d[toolName],
9573
9603
  errorMode: part.state === "output-error" ? "json" : "none"
9574
9604
  }),
9575
9605
  ...resultProviderMetadata != null ? { providerOptions: resultProviderMetadata } : {}
@@ -9577,7 +9607,7 @@ async function convertToModelMessages(messages, options) {
9577
9607
  }
9578
9608
  }
9579
9609
  } else if (isDataUIPart(part)) {
9580
- const dataPart = (_d = options == null ? void 0 : options.convertDataPart) == null ? void 0 : _d.call(
9610
+ const dataPart = (_e = options == null ? void 0 : options.convertDataPart) == null ? void 0 : _e.call(
9581
9611
  options,
9582
9612
  part
9583
9613
  );
@@ -9605,7 +9635,7 @@ async function convertToModelMessages(messages, options) {
9605
9635
  {
9606
9636
  const content2 = [];
9607
9637
  for (const toolPart of toolParts) {
9608
- if (((_e = toolPart.approval) == null ? void 0 : _e.approved) != null) {
9638
+ if (((_f = toolPart.approval) == null ? void 0 : _f.approved) != null) {
9609
9639
  content2.push({
9610
9640
  type: "tool-approval-response",
9611
9641
  approvalId: toolPart.approval.id,
@@ -9625,7 +9655,7 @@ async function convertToModelMessages(messages, options) {
9625
9655
  toolName: getToolName(toolPart),
9626
9656
  output: {
9627
9657
  type: "error-text",
9628
- value: (_g = (_f = toolPart.approval) == null ? void 0 : _f.reason) != null ? _g : "Tool call execution denied."
9658
+ value: (_h = (_g = toolPart.approval) == null ? void 0 : _g.reason) != null ? _h : "Tool call execution denied."
9629
9659
  },
9630
9660
  ...toolPart.callProviderMetadata != null ? { providerOptions: toolPart.callProviderMetadata } : {}
9631
9661
  });
@@ -9642,7 +9672,7 @@ async function convertToModelMessages(messages, options) {
9642
9672
  toolCallId: toolPart.toolCallId,
9643
9673
  input: toolPart.input,
9644
9674
  output: toolPart.state === "output-error" ? toolPart.errorText : toolPart.output,
9645
- tool: (_h = options == null ? void 0 : options.tools) == null ? void 0 : _h[toolName],
9675
+ tool: (_i = options == null ? void 0 : options.tools) == null ? void 0 : _i[toolName],
9646
9676
  errorMode: toolPart.state === "output-error" ? "text" : "none"
9647
9677
  }),
9648
9678
  ...toolPart.callProviderMetadata != null ? { providerOptions: toolPart.callProviderMetadata } : {}
@@ -11460,7 +11490,8 @@ async function generateObject(options) {
11460
11490
  const promptMessages = await convertToLanguageModelPrompt({
11461
11491
  prompt: standardizedPrompt,
11462
11492
  supportedUrls: await model.supportedUrls,
11463
- download: download2
11493
+ download: download2,
11494
+ abortSignal
11464
11495
  });
11465
11496
  const generateResult = await retry(
11466
11497
  () => recordSpan({
@@ -11949,7 +11980,8 @@ var DefaultStreamObjectResult = class {
11949
11980
  prompt: await convertToLanguageModelPrompt({
11950
11981
  prompt: standardizedPrompt,
11951
11982
  supportedUrls: await model.supportedUrls,
11952
- download: download2
11983
+ download: download2,
11984
+ abortSignal
11953
11985
  }),
11954
11986
  providerOptions,
11955
11987
  abortSignal,
@@ -12509,11 +12541,13 @@ function pruneMessages({
12509
12541
  }
12510
12542
  }
12511
12543
  }
12544
+ const approvalIdToToolCallId = /* @__PURE__ */ new Map();
12512
12545
  const approvalIdToToolName = /* @__PURE__ */ new Map();
12513
12546
  for (const message of messages) {
12514
12547
  if ((message.role === "assistant" || message.role === "tool") && typeof message.content !== "string") {
12515
12548
  for (const part of message.content) {
12516
12549
  if (part.type === "tool-approval-request") {
12550
+ approvalIdToToolCallId.set(part.approvalId, part.toolCallId);
12517
12551
  const toolName = toolCallIdToToolName.get(part.toolCallId);
12518
12552
  if (toolName != null) {
12519
12553
  approvalIdToToolName.set(part.approvalId, toolName);
@@ -12522,6 +12556,12 @@ function pruneMessages({
12522
12556
  }
12523
12557
  }
12524
12558
  }
12559
+ for (const approvalId of keptApprovalIds) {
12560
+ const toolCallId = approvalIdToToolCallId.get(approvalId);
12561
+ if (toolCallId != null) {
12562
+ keptToolCallIds.add(toolCallId);
12563
+ }
12564
+ }
12525
12565
  messages = messages.map((message, messageIndex) => {
12526
12566
  if (message.role !== "assistant" && message.role !== "tool" || typeof message.content === "string" || keepLastMessagesCount && messageIndex >= messages.length - keepLastMessagesCount) {
12527
12567
  return message;
@@ -13253,7 +13293,11 @@ function simulateStreamingMiddleware() {
13253
13293
  switch (part.type) {
13254
13294
  case "text": {
13255
13295
  if (part.text.length > 0) {
13256
- controller.enqueue({ type: "text-start", id: String(id) });
13296
+ controller.enqueue({
13297
+ type: "text-start",
13298
+ id: String(id),
13299
+ ...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
13300
+ });
13257
13301
  controller.enqueue({
13258
13302
  type: "text-delta",
13259
13303
  id: String(id),