ai 5.0.239 → 5.0.241

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -727,7 +727,7 @@ import {
727
727
  } from "@ai-sdk/provider-utils";
728
728
 
729
729
  // src/version.ts
730
- var VERSION = true ? "5.0.239" : "0.0.0-test";
730
+ var VERSION = true ? "5.0.241" : "0.0.0-test";
731
731
 
732
732
  // src/util/download/download.ts
733
733
  var download = async ({
@@ -1931,6 +1931,11 @@ var DefaultGeneratedFileWithType = class extends DefaultGeneratedFile {
1931
1931
  }
1932
1932
  };
1933
1933
 
1934
+ // src/generate-text/is-tool-execution-allowed-finish-reason.ts
1935
+ function isToolExecutionAllowedFinishReason(finishReason) {
1936
+ return finishReason === "stop" || finishReason === "tool-calls";
1937
+ }
1938
+
1934
1939
  // src/generate-text/parse-tool-call.ts
1935
1940
  import {
1936
1941
  asSchema as asSchema2,
@@ -2498,7 +2503,9 @@ async function generateText({
2498
2503
  clientToolCalls = stepToolCalls.filter(
2499
2504
  (toolCall) => !toolCall.providerExecuted
2500
2505
  );
2501
- if (stepToolSet != null) {
2506
+ if (stepToolSet != null && isToolExecutionAllowedFinishReason(
2507
+ currentModelResponse.finishReason
2508
+ )) {
2502
2509
  clientToolOutputs.push(
2503
2510
  ...await executeTools({
2504
2511
  toolCalls: clientToolCalls.filter(
@@ -4271,32 +4278,33 @@ function createResolvablePromise() {
4271
4278
 
4272
4279
  // src/util/create-stitchable-stream.ts
4273
4280
  function createStitchableStream() {
4274
- let innerStreamReaders = [];
4281
+ let innerStreams = [];
4275
4282
  let controller = null;
4276
4283
  let isClosed = false;
4277
4284
  let waitForNewStream = createResolvablePromise();
4278
4285
  const terminate = () => {
4279
4286
  isClosed = true;
4280
4287
  waitForNewStream.resolve();
4281
- innerStreamReaders.forEach((reader) => reader.cancel());
4282
- innerStreamReaders = [];
4288
+ innerStreams.forEach(({ reader }) => reader.cancel());
4289
+ innerStreams = [];
4283
4290
  controller == null ? void 0 : controller.close();
4284
4291
  };
4285
4292
  const processPull = async () => {
4286
- if (isClosed && innerStreamReaders.length === 0) {
4293
+ var _a16, _b;
4294
+ if (isClosed && innerStreams.length === 0) {
4287
4295
  controller == null ? void 0 : controller.close();
4288
4296
  return;
4289
4297
  }
4290
- if (innerStreamReaders.length === 0) {
4298
+ if (innerStreams.length === 0) {
4291
4299
  waitForNewStream = createResolvablePromise();
4292
4300
  await waitForNewStream.promise;
4293
4301
  return processPull();
4294
4302
  }
4295
4303
  try {
4296
- const { value, done } = await innerStreamReaders[0].read();
4304
+ const { value, done } = await innerStreams[0].reader.read();
4297
4305
  if (done) {
4298
- innerStreamReaders.shift();
4299
- if (innerStreamReaders.length > 0) {
4306
+ innerStreams.shift();
4307
+ if (innerStreams.length > 0) {
4300
4308
  await processPull();
4301
4309
  } else if (isClosed) {
4302
4310
  controller == null ? void 0 : controller.close();
@@ -4305,8 +4313,9 @@ function createStitchableStream() {
4305
4313
  controller == null ? void 0 : controller.enqueue(value);
4306
4314
  }
4307
4315
  } catch (error) {
4316
+ (_b = (_a16 = innerStreams[0]).onError) == null ? void 0 : _b.call(_a16, error);
4308
4317
  controller == null ? void 0 : controller.error(error);
4309
- innerStreamReaders.shift();
4318
+ innerStreams.shift();
4310
4319
  terminate();
4311
4320
  }
4312
4321
  };
@@ -4317,18 +4326,21 @@ function createStitchableStream() {
4317
4326
  },
4318
4327
  pull: processPull,
4319
4328
  async cancel() {
4320
- for (const reader of innerStreamReaders) {
4329
+ for (const { reader } of innerStreams) {
4321
4330
  await reader.cancel();
4322
4331
  }
4323
- innerStreamReaders = [];
4332
+ innerStreams = [];
4324
4333
  isClosed = true;
4325
4334
  }
4326
4335
  }),
4327
- addStream: (innerStream) => {
4336
+ addStream: (innerStream, callbacks) => {
4328
4337
  if (isClosed) {
4329
4338
  throw new Error("Cannot add inner stream: outer stream is closed");
4330
4339
  }
4331
- innerStreamReaders.push(innerStream.getReader());
4340
+ innerStreams.push({
4341
+ reader: innerStream.getReader(),
4342
+ ...callbacks
4343
+ });
4332
4344
  waitForNewStream.resolve();
4333
4345
  },
4334
4346
  /**
@@ -4338,7 +4350,7 @@ function createStitchableStream() {
4338
4350
  close: () => {
4339
4351
  isClosed = true;
4340
4352
  waitForNewStream.resolve();
4341
- if (innerStreamReaders.length === 0) {
4353
+ if (innerStreams.length === 0) {
4342
4354
  controller == null ? void 0 : controller.close();
4343
4355
  }
4344
4356
  },
@@ -4404,6 +4416,7 @@ function runToolsTransformation({
4404
4416
  }
4405
4417
  }
4406
4418
  const outstandingToolResults = /* @__PURE__ */ new Set();
4419
+ const pendingToolCalls = [];
4407
4420
  const toolInputs = /* @__PURE__ */ new Map();
4408
4421
  let canClose = false;
4409
4422
  let finishChunk = void 0;
@@ -4415,6 +4428,82 @@ function runToolsTransformation({
4415
4428
  closeToolResultsStream();
4416
4429
  }
4417
4430
  }
4431
+ function executePendingToolCall(toolCall) {
4432
+ const tool2 = tools[toolCall.toolName];
4433
+ const toolExecutionId = generateId();
4434
+ outstandingToolResults.add(toolExecutionId);
4435
+ recordSpan({
4436
+ name: "ai.toolCall",
4437
+ attributes: selectTelemetryAttributes({
4438
+ telemetry,
4439
+ attributes: {
4440
+ ...assembleOperationName({
4441
+ operationId: "ai.toolCall",
4442
+ telemetry
4443
+ }),
4444
+ "ai.toolCall.name": toolCall.toolName,
4445
+ "ai.toolCall.id": toolCall.toolCallId,
4446
+ "ai.toolCall.args": {
4447
+ output: () => JSON.stringify(toolCall.input)
4448
+ }
4449
+ }
4450
+ }),
4451
+ tracer,
4452
+ fn: async (span) => {
4453
+ let output;
4454
+ try {
4455
+ const stream = executeTool2({
4456
+ execute: tool2.execute.bind(tool2),
4457
+ input: toolCall.input,
4458
+ options: {
4459
+ toolCallId: toolCall.toolCallId,
4460
+ messages,
4461
+ abortSignal,
4462
+ experimental_context
4463
+ }
4464
+ });
4465
+ for await (const part of stream) {
4466
+ enqueueToolResult({
4467
+ ...toolCall,
4468
+ type: "tool-result",
4469
+ output: part.output,
4470
+ ...part.type === "preliminary" && {
4471
+ preliminary: true
4472
+ }
4473
+ });
4474
+ if (part.type === "final") {
4475
+ output = part.output;
4476
+ }
4477
+ }
4478
+ } catch (error) {
4479
+ recordErrorOnSpan(span, error);
4480
+ enqueueToolResult({
4481
+ ...toolCall,
4482
+ type: "tool-error",
4483
+ error
4484
+ });
4485
+ outstandingToolResults.delete(toolExecutionId);
4486
+ attemptClose();
4487
+ return;
4488
+ }
4489
+ outstandingToolResults.delete(toolExecutionId);
4490
+ attemptClose();
4491
+ try {
4492
+ span.setAttributes(
4493
+ selectTelemetryAttributes({
4494
+ telemetry,
4495
+ attributes: {
4496
+ "ai.toolCall.result": {
4497
+ output: () => JSON.stringify(output)
4498
+ }
4499
+ }
4500
+ })
4501
+ );
4502
+ } catch (ignored) {
4503
+ }
4504
+ }
4505
+ });
4506
+ }
4418
4507
  const forwardStream = new TransformStream({
4419
4508
  async transform(chunk, controller) {
4420
4509
  const chunkType = chunk.type;
@@ -4453,6 +4542,13 @@ function runToolsTransformation({
4453
4542
  usage: chunk.usage,
4454
4543
  providerMetadata: chunk.providerMetadata
4455
4544
  };
4545
+ if (isToolExecutionAllowedFinishReason(chunk.finishReason)) {
4546
+ for (const toolCall of pendingToolCalls.splice(0)) {
4547
+ executePendingToolCall(toolCall);
4548
+ }
4549
+ } else {
4550
+ pendingToolCalls.length = 0;
4551
+ }
4456
4552
  break;
4457
4553
  }
4458
4554
  case "tool-call": {
@@ -4488,79 +4584,7 @@ function runToolsTransformation({
4488
4584
  });
4489
4585
  }
4490
4586
  if (tool2.execute != null && toolCall.providerExecuted !== true) {
4491
- const toolExecutionId = generateId();
4492
- outstandingToolResults.add(toolExecutionId);
4493
- recordSpan({
4494
- name: "ai.toolCall",
4495
- attributes: selectTelemetryAttributes({
4496
- telemetry,
4497
- attributes: {
4498
- ...assembleOperationName({
4499
- operationId: "ai.toolCall",
4500
- telemetry
4501
- }),
4502
- "ai.toolCall.name": toolCall.toolName,
4503
- "ai.toolCall.id": toolCall.toolCallId,
4504
- "ai.toolCall.args": {
4505
- output: () => JSON.stringify(toolCall.input)
4506
- }
4507
- }
4508
- }),
4509
- tracer,
4510
- fn: async (span) => {
4511
- let output;
4512
- try {
4513
- const stream = executeTool2({
4514
- execute: tool2.execute.bind(tool2),
4515
- input: toolCall.input,
4516
- options: {
4517
- toolCallId: toolCall.toolCallId,
4518
- messages,
4519
- abortSignal,
4520
- experimental_context
4521
- }
4522
- });
4523
- for await (const part of stream) {
4524
- enqueueToolResult({
4525
- ...toolCall,
4526
- type: "tool-result",
4527
- output: part.output,
4528
- ...part.type === "preliminary" && {
4529
- preliminary: true
4530
- }
4531
- });
4532
- if (part.type === "final") {
4533
- output = part.output;
4534
- }
4535
- }
4536
- } catch (error) {
4537
- recordErrorOnSpan(span, error);
4538
- enqueueToolResult({
4539
- ...toolCall,
4540
- type: "tool-error",
4541
- error
4542
- });
4543
- outstandingToolResults.delete(toolExecutionId);
4544
- attemptClose();
4545
- return;
4546
- }
4547
- outstandingToolResults.delete(toolExecutionId);
4548
- attemptClose();
4549
- try {
4550
- span.setAttributes(
4551
- selectTelemetryAttributes({
4552
- telemetry,
4553
- attributes: {
4554
- "ai.toolCall.result": {
4555
- output: () => JSON.stringify(output)
4556
- }
4557
- }
4558
- })
4559
- );
4560
- } catch (ignored) {
4561
- }
4562
- }
4563
- });
4587
+ pendingToolCalls.push({ ...toolCall });
4564
4588
  }
4565
4589
  } catch (error) {
4566
4590
  enqueueToolResult({ type: "error", error });
@@ -5985,7 +6009,7 @@ function convertToModelMessages(messages, options) {
5985
6009
  messages = messages.map((message) => ({
5986
6010
  ...message,
5987
6011
  parts: message.parts.filter(
5988
- (part) => !isToolOrDynamicToolUIPart(part) || part.state !== "input-streaming" && part.state !== "input-available"
6012
+ (part) => !isToolOrDynamicToolUIPart(part) || part.state !== "input-streaming" && part.state !== "input-available" && (part.state !== "output-available" || part.preliminary !== true)
5989
6013
  )
5990
6014
  }));
5991
6015
  }
@@ -7574,6 +7598,12 @@ function simulateReadableStream({
7574
7598
 
7575
7599
  // src/generate-object/stream-object.ts
7576
7600
  var originalGenerateId4 = createIdGenerator4({ prefix: "aiobj", size: 24 });
7601
+ async function markPromiseAsHandled(promise) {
7602
+ try {
7603
+ await promise;
7604
+ } catch (e) {
7605
+ }
7606
+ }
7577
7607
  function streamObject(options) {
7578
7608
  const {
7579
7609
  model,
@@ -7810,6 +7840,7 @@ var DefaultStreamObjectResult = class {
7810
7840
  let providerMetadata;
7811
7841
  let object2;
7812
7842
  let error;
7843
+ let terminalError;
7813
7844
  let accumulatedText = "";
7814
7845
  let textDelta = "";
7815
7846
  let fullResponse = {
@@ -7880,11 +7911,22 @@ var DefaultStreamObjectResult = class {
7880
7911
  };
7881
7912
  break;
7882
7913
  }
7914
+ case "error": {
7915
+ if (terminalError === void 0) {
7916
+ const wrappedError = wrapGatewayError(chunk.error);
7917
+ terminalError = { error: wrappedError };
7918
+ error = wrappedError;
7919
+ finishReason = "error";
7920
+ self.rejectResultPromises(wrappedError);
7921
+ }
7922
+ controller.enqueue(chunk);
7923
+ break;
7924
+ }
7883
7925
  case "finish": {
7884
7926
  if (textDelta !== "") {
7885
7927
  controller.enqueue({ type: "text-delta", textDelta });
7886
7928
  }
7887
- finishReason = chunk.finishReason;
7929
+ finishReason = terminalError === void 0 ? chunk.finishReason : "error";
7888
7930
  usage = chunk.usage;
7889
7931
  providerMetadata = chunk.providerMetadata;
7890
7932
  controller.enqueue({
@@ -7893,6 +7935,9 @@ var DefaultStreamObjectResult = class {
7893
7935
  response: fullResponse
7894
7936
  });
7895
7937
  logWarnings(warnings != null ? warnings : []);
7938
+ if (terminalError !== void 0) {
7939
+ break;
7940
+ }
7896
7941
  self._usage.resolve(usage);
7897
7942
  self._providerMetadata.resolve(providerMetadata);
7898
7943
  self._warnings.resolve(warnings);
@@ -7995,9 +8040,16 @@ var DefaultStreamObjectResult = class {
7995
8040
  }
7996
8041
  })
7997
8042
  );
7998
- stitchableStream.addStream(transformedStream);
8043
+ stitchableStream.addStream(transformedStream, {
8044
+ onError(error2) {
8045
+ const wrappedError = wrapGatewayError(error2);
8046
+ self.rejectResultPromises(wrappedError);
8047
+ void onError({ error: wrappedError });
8048
+ }
8049
+ });
7999
8050
  }
8000
8051
  }).catch((error) => {
8052
+ self.rejectResultPromises(error);
8001
8053
  stitchableStream.addStream(
8002
8054
  new ReadableStream({
8003
8055
  start(controller) {
@@ -8011,6 +8063,24 @@ var DefaultStreamObjectResult = class {
8011
8063
  });
8012
8064
  this.outputStrategy = outputStrategy;
8013
8065
  }
8066
+ rejectResultPromises(error) {
8067
+ this.rejectResultPromise({ delayedPromise: this._object, error });
8068
+ this.rejectResultPromise({ delayedPromise: this._usage, error });
8069
+ this.rejectResultPromise({ delayedPromise: this._providerMetadata, error });
8070
+ this.rejectResultPromise({ delayedPromise: this._warnings, error });
8071
+ this.rejectResultPromise({ delayedPromise: this._request, error });
8072
+ this.rejectResultPromise({ delayedPromise: this._response, error });
8073
+ this.rejectResultPromise({ delayedPromise: this._finishReason, error });
8074
+ }
8075
+ rejectResultPromise({
8076
+ delayedPromise,
8077
+ error
8078
+ }) {
8079
+ if (delayedPromise.isPending()) {
8080
+ delayedPromise.reject(error);
8081
+ markPromiseAsHandled(delayedPromise.promise);
8082
+ }
8083
+ }
8014
8084
  get object() {
8015
8085
  return this._object.promise;
8016
8086
  }