ai 5.0.212 → 5.0.213

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,16 @@
1
1
  # ai
2
2
 
3
+ ## 5.0.213
4
+
5
+ ### Patch Changes
6
+
7
+ - 97e9b70: Allow validating assistant UI messages with empty parts so persisted errored responses remain loadable.
8
+ - 59e34d9: Prevent pending tool executions from enqueueing results after a model stream error closes the result stream.
9
+ - Updated dependencies [c6e1d1a]
10
+ - Updated dependencies [7480df1]
11
+ - @ai-sdk/provider-utils@3.0.29
12
+ - @ai-sdk/gateway@2.0.112
13
+
3
14
  ## 5.0.212
4
15
 
5
16
  ### Patch Changes
package/dist/index.js CHANGED
@@ -778,7 +778,7 @@ function detectMediaType({
778
778
  var import_provider_utils2 = require("@ai-sdk/provider-utils");
779
779
 
780
780
  // src/version.ts
781
- var VERSION = true ? "5.0.212" : "0.0.0-test";
781
+ var VERSION = true ? "5.0.213" : "0.0.0-test";
782
782
 
783
783
  // src/util/download/download.ts
784
784
  var download = async ({
@@ -4310,11 +4310,35 @@ function runToolsTransformation({
4310
4310
  experimental_context
4311
4311
  }) {
4312
4312
  let toolResultsStreamController = null;
4313
+ let toolResultsStreamClosed = false;
4313
4314
  const toolResultsStream = new ReadableStream({
4314
4315
  start(controller) {
4315
4316
  toolResultsStreamController = controller;
4317
+ },
4318
+ cancel() {
4319
+ toolResultsStreamClosed = true;
4316
4320
  }
4317
4321
  });
4322
+ function enqueueToolResult(chunk) {
4323
+ if (toolResultsStreamClosed) {
4324
+ return;
4325
+ }
4326
+ try {
4327
+ toolResultsStreamController.enqueue(chunk);
4328
+ } catch (e) {
4329
+ toolResultsStreamClosed = true;
4330
+ }
4331
+ }
4332
+ function closeToolResultsStream() {
4333
+ if (toolResultsStreamClosed) {
4334
+ return;
4335
+ }
4336
+ toolResultsStreamClosed = true;
4337
+ try {
4338
+ toolResultsStreamController.close();
4339
+ } catch (e) {
4340
+ }
4341
+ }
4318
4342
  const outstandingToolResults = /* @__PURE__ */ new Set();
4319
4343
  const toolInputs = /* @__PURE__ */ new Map();
4320
4344
  let canClose = false;
@@ -4322,9 +4346,9 @@ function runToolsTransformation({
4322
4346
  function attemptClose() {
4323
4347
  if (canClose && outstandingToolResults.size === 0) {
4324
4348
  if (finishChunk != null) {
4325
- toolResultsStreamController.enqueue(finishChunk);
4349
+ enqueueToolResult(finishChunk);
4326
4350
  }
4327
- toolResultsStreamController.close();
4351
+ closeToolResultsStream();
4328
4352
  }
4329
4353
  }
4330
4354
  const forwardStream = new TransformStream({
@@ -4378,7 +4402,7 @@ function runToolsTransformation({
4378
4402
  });
4379
4403
  controller.enqueue(toolCall);
4380
4404
  if (toolCall.invalid) {
4381
- toolResultsStreamController.enqueue({
4405
+ enqueueToolResult({
4382
4406
  type: "tool-error",
4383
4407
  toolCallId: toolCall.toolCallId,
4384
4408
  toolName: toolCall.toolName,
@@ -4433,7 +4457,7 @@ function runToolsTransformation({
4433
4457
  }
4434
4458
  });
4435
4459
  for await (const part of stream) {
4436
- toolResultsStreamController.enqueue({
4460
+ enqueueToolResult({
4437
4461
  ...toolCall,
4438
4462
  type: "tool-result",
4439
4463
  output: part.output,
@@ -4447,7 +4471,7 @@ function runToolsTransformation({
4447
4471
  }
4448
4472
  } catch (error) {
4449
4473
  recordErrorOnSpan(span, error);
4450
- toolResultsStreamController.enqueue({
4474
+ enqueueToolResult({
4451
4475
  ...toolCall,
4452
4476
  type: "tool-error",
4453
4477
  error
@@ -4475,14 +4499,14 @@ function runToolsTransformation({
4475
4499
  });
4476
4500
  }
4477
4501
  } catch (error) {
4478
- toolResultsStreamController.enqueue({ type: "error", error });
4502
+ enqueueToolResult({ type: "error", error });
4479
4503
  }
4480
4504
  break;
4481
4505
  }
4482
4506
  case "tool-result": {
4483
4507
  const toolName = chunk.toolName;
4484
4508
  if (chunk.isError) {
4485
- toolResultsStreamController.enqueue({
4509
+ enqueueToolResult({
4486
4510
  type: "tool-error",
4487
4511
  toolCallId: chunk.toolCallId,
4488
4512
  toolName,
@@ -9810,7 +9834,19 @@ var uiMessagesSchema = (0, import_provider_utils32.lazyValidator)(
9810
9834
  })
9811
9835
  })
9812
9836
  ])
9813
- ).nonempty("Message must contain at least one part")
9837
+ )
9838
+ }).superRefine((message, context) => {
9839
+ if (message.role !== "assistant" && message.parts.length === 0) {
9840
+ context.addIssue({
9841
+ origin: "array",
9842
+ code: "too_small",
9843
+ minimum: 1,
9844
+ inclusive: true,
9845
+ input: message.parts,
9846
+ path: ["parts"],
9847
+ message: "Message must contain at least one part"
9848
+ });
9849
+ }
9814
9850
  })
9815
9851
  ).nonempty("Messages array must not be empty")
9816
9852
  )