ai 4.0.18 → 4.0.19

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
@@ -1744,6 +1744,13 @@ function calculateLanguageModelUsage({
1744
1744
  totalTokens: promptTokens + completionTokens
1745
1745
  };
1746
1746
  }
1747
+ function addLanguageModelUsage(usage1, usage2) {
1748
+ return {
1749
+ promptTokens: usage1.promptTokens + usage2.promptTokens,
1750
+ completionTokens: usage1.completionTokens + usage2.completionTokens,
1751
+ totalTokens: usage1.totalTokens + usage2.totalTokens
1752
+ };
1753
+ }
1747
1754
 
1748
1755
  // core/generate-object/inject-json-instruction.ts
1749
1756
  var DEFAULT_SCHEMA_PREFIX = "JSON schema:";
@@ -3582,7 +3589,7 @@ async function generateText({
3582
3589
  const responseMessages = [];
3583
3590
  let text2 = "";
3584
3591
  const steps = [];
3585
- const usage = {
3592
+ let usage = {
3586
3593
  completionTokens: 0,
3587
3594
  promptTokens: 0,
3588
3595
  totalTokens: 0
@@ -3709,9 +3716,7 @@ async function generateText({
3709
3716
  const currentUsage = calculateLanguageModelUsage(
3710
3717
  currentModelResponse.usage
3711
3718
  );
3712
- usage.completionTokens += currentUsage.completionTokens;
3713
- usage.promptTokens += currentUsage.promptTokens;
3714
- usage.totalTokens += currentUsage.totalTokens;
3719
+ usage = addLanguageModelUsage(usage, currentUsage);
3715
3720
  let nextStepType = "done";
3716
3721
  if (++stepCount < maxSteps) {
3717
3722
  if (continueSteps && currentModelResponse.finishReason === "length" && // only use continue when there are no tool calls:
@@ -4369,10 +4374,168 @@ var DefaultStreamTextResult = class {
4369
4374
  message: "maxSteps must be at least 1"
4370
4375
  });
4371
4376
  }
4377
+ let recordedStepText = "";
4378
+ let recordedContinuationText = "";
4379
+ let recordedFullText = "";
4380
+ let recordedRequest = void 0;
4381
+ const recordedResponse = {
4382
+ id: generateId3(),
4383
+ timestamp: currentDate(),
4384
+ modelId: model.modelId,
4385
+ messages: []
4386
+ };
4387
+ let recordedToolCalls = [];
4388
+ let recordedToolResults = [];
4389
+ let recordedFinishReason = void 0;
4390
+ let recordedUsage = void 0;
4391
+ let recordedProviderMetadata = void 0;
4392
+ let stepType = "initial";
4393
+ const recordedSteps = [];
4394
+ let rootSpan;
4395
+ const eventProcessor = new TransformStream({
4396
+ async transform(chunk, controller) {
4397
+ controller.enqueue(chunk);
4398
+ if (chunk.type === "text-delta" || chunk.type === "tool-call" || chunk.type === "tool-result" || chunk.type === "tool-call-streaming-start" || chunk.type === "tool-call-delta") {
4399
+ await (onChunk == null ? void 0 : onChunk({ chunk }));
4400
+ }
4401
+ if (chunk.type === "text-delta") {
4402
+ recordedStepText += chunk.textDelta;
4403
+ recordedContinuationText += chunk.textDelta;
4404
+ recordedFullText += chunk.textDelta;
4405
+ }
4406
+ if (chunk.type === "tool-call") {
4407
+ recordedToolCalls.push(chunk);
4408
+ }
4409
+ if (chunk.type === "tool-result") {
4410
+ recordedToolResults.push(chunk);
4411
+ }
4412
+ if (chunk.type === "step-finish") {
4413
+ const stepMessages = toResponseMessages({
4414
+ text: recordedContinuationText,
4415
+ tools: tools != null ? tools : {},
4416
+ toolCalls: recordedToolCalls,
4417
+ toolResults: recordedToolResults
4418
+ });
4419
+ const currentStep = recordedSteps.length;
4420
+ let nextStepType = "done";
4421
+ if (currentStep + 1 < maxSteps) {
4422
+ if (continueSteps && chunk.finishReason === "length" && // only use continue when there are no tool calls:
4423
+ recordedToolCalls.length === 0) {
4424
+ nextStepType = "continue";
4425
+ } else if (
4426
+ // there are tool calls:
4427
+ recordedToolCalls.length > 0 && // all current tool calls have results:
4428
+ recordedToolResults.length === recordedToolCalls.length
4429
+ ) {
4430
+ nextStepType = "tool-result";
4431
+ }
4432
+ }
4433
+ const currentStepResult = {
4434
+ stepType,
4435
+ text: recordedStepText,
4436
+ toolCalls: recordedToolCalls,
4437
+ toolResults: recordedToolResults,
4438
+ finishReason: chunk.finishReason,
4439
+ usage: chunk.usage,
4440
+ warnings: chunk.warnings,
4441
+ logprobs: chunk.logprobs,
4442
+ request: chunk.request,
4443
+ response: {
4444
+ ...chunk.response,
4445
+ messages: [...recordedResponse.messages, ...stepMessages]
4446
+ },
4447
+ experimental_providerMetadata: chunk.experimental_providerMetadata,
4448
+ isContinued: chunk.isContinued
4449
+ };
4450
+ await (onStepFinish == null ? void 0 : onStepFinish(currentStepResult));
4451
+ recordedSteps.push(currentStepResult);
4452
+ recordedToolCalls = [];
4453
+ recordedToolResults = [];
4454
+ recordedStepText = "";
4455
+ recordedRequest = chunk.request;
4456
+ if (nextStepType !== "done") {
4457
+ stepType = nextStepType;
4458
+ }
4459
+ if (nextStepType !== "continue") {
4460
+ recordedResponse.messages.push(...stepMessages);
4461
+ recordedContinuationText = "";
4462
+ }
4463
+ }
4464
+ if (chunk.type === "finish") {
4465
+ recordedResponse.id = chunk.response.id;
4466
+ recordedResponse.timestamp = chunk.response.timestamp;
4467
+ recordedResponse.modelId = chunk.response.modelId;
4468
+ recordedResponse.headers = chunk.response.headers;
4469
+ recordedUsage = chunk.usage;
4470
+ recordedFinishReason = chunk.finishReason;
4471
+ recordedProviderMetadata = chunk.experimental_providerMetadata;
4472
+ }
4473
+ },
4474
+ async flush(controller) {
4475
+ var _a13;
4476
+ try {
4477
+ const lastStep = recordedSteps[recordedSteps.length - 1];
4478
+ if (lastStep) {
4479
+ self.warningsPromise.resolve(lastStep.warnings);
4480
+ self.requestPromise.resolve(lastStep.request);
4481
+ self.responsePromise.resolve(lastStep.response);
4482
+ self.toolCallsPromise.resolve(lastStep.toolCalls);
4483
+ self.toolResultsPromise.resolve(lastStep.toolResults);
4484
+ self.providerMetadataPromise.resolve(
4485
+ lastStep.experimental_providerMetadata
4486
+ );
4487
+ }
4488
+ const finishReason = recordedFinishReason != null ? recordedFinishReason : "unknown";
4489
+ const usage = recordedUsage != null ? recordedUsage : {
4490
+ completionTokens: NaN,
4491
+ promptTokens: NaN,
4492
+ totalTokens: NaN
4493
+ };
4494
+ self.finishReasonPromise.resolve(finishReason);
4495
+ self.usagePromise.resolve(usage);
4496
+ self.textPromise.resolve(recordedFullText);
4497
+ self.stepsPromise.resolve(recordedSteps);
4498
+ await (onFinish == null ? void 0 : onFinish({
4499
+ finishReason,
4500
+ logprobs: void 0,
4501
+ usage,
4502
+ text: recordedFullText,
4503
+ toolCalls: lastStep.toolCalls,
4504
+ toolResults: lastStep.toolResults,
4505
+ request: (_a13 = lastStep.request) != null ? _a13 : {},
4506
+ response: lastStep.response,
4507
+ warnings: lastStep.warnings,
4508
+ experimental_providerMetadata: lastStep.experimental_providerMetadata,
4509
+ steps: recordedSteps
4510
+ }));
4511
+ rootSpan.setAttributes(
4512
+ selectTelemetryAttributes({
4513
+ telemetry,
4514
+ attributes: {
4515
+ "ai.response.finishReason": finishReason,
4516
+ "ai.response.text": { output: () => recordedFullText },
4517
+ "ai.response.toolCalls": {
4518
+ output: () => {
4519
+ var _a14;
4520
+ return ((_a14 = lastStep.toolCalls) == null ? void 0 : _a14.length) ? JSON.stringify(lastStep.toolCalls) : void 0;
4521
+ }
4522
+ },
4523
+ "ai.usage.promptTokens": usage.promptTokens,
4524
+ "ai.usage.completionTokens": usage.completionTokens
4525
+ }
4526
+ })
4527
+ );
4528
+ } catch (error) {
4529
+ controller.error(error);
4530
+ } finally {
4531
+ rootSpan.end();
4532
+ }
4533
+ }
4534
+ });
4372
4535
  const stitchableStream = createStitchableStream();
4373
4536
  this.addStream = stitchableStream.addStream;
4374
4537
  this.closeStream = stitchableStream.close;
4375
- this.baseStream = transform ? stitchableStream.stream.pipeThrough(transform) : stitchableStream.stream;
4538
+ this.baseStream = (transform ? stitchableStream.stream.pipeThrough(transform) : stitchableStream.stream).pipeThrough(eventProcessor);
4376
4539
  const { maxRetries, retry } = prepareRetries({
4377
4540
  maxRetries: maxRetriesArg
4378
4541
  });
@@ -4404,13 +4567,13 @@ var DefaultStreamTextResult = class {
4404
4567
  }),
4405
4568
  tracer,
4406
4569
  endWhenDone: false,
4407
- fn: async (rootSpan) => {
4408
- const stepResults = [];
4570
+ fn: async (rootSpanArg) => {
4571
+ rootSpan = rootSpanArg;
4409
4572
  async function streamStep({
4410
4573
  currentStep,
4411
4574
  responseMessages,
4412
4575
  usage,
4413
- stepType,
4576
+ stepType: stepType2,
4414
4577
  previousStepText,
4415
4578
  hasLeadingWhitespace
4416
4579
  }) {
@@ -4516,7 +4679,7 @@ var DefaultStreamTextResult = class {
4516
4679
  let stepProviderMetadata;
4517
4680
  let stepFirstChunk = true;
4518
4681
  let stepText = "";
4519
- let fullStepText = stepType === "continue" ? previousStepText : "";
4682
+ let fullStepText = stepType2 === "continue" ? previousStepText : "";
4520
4683
  let stepLogProbs;
4521
4684
  let stepResponse = {
4522
4685
  id: generateId3(),
@@ -4536,7 +4699,6 @@ var DefaultStreamTextResult = class {
4536
4699
  fullStepText += chunk.textDelta;
4537
4700
  chunkTextPublished = true;
4538
4701
  hasWhitespaceSuffix = chunk.textDelta.trimEnd() !== chunk.textDelta;
4539
- await (onChunk == null ? void 0 : onChunk({ chunk }));
4540
4702
  }
4541
4703
  self.addStream(
4542
4704
  transformedStream.pipeThrough(
@@ -4585,13 +4747,11 @@ var DefaultStreamTextResult = class {
4585
4747
  case "tool-call": {
4586
4748
  controller.enqueue(chunk);
4587
4749
  stepToolCalls.push(chunk);
4588
- await (onChunk == null ? void 0 : onChunk({ chunk }));
4589
4750
  break;
4590
4751
  }
4591
4752
  case "tool-result": {
4592
4753
  controller.enqueue(chunk);
4593
4754
  stepToolResults.push(chunk);
4594
- await (onChunk == null ? void 0 : onChunk({ chunk }));
4595
4755
  break;
4596
4756
  }
4597
4757
  case "response-metadata": {
@@ -4618,7 +4778,6 @@ var DefaultStreamTextResult = class {
4618
4778
  case "tool-call-streaming-start":
4619
4779
  case "tool-call-delta": {
4620
4780
  controller.enqueue(chunk);
4621
- await (onChunk == null ? void 0 : onChunk({ chunk }));
4622
4781
  break;
4623
4782
  }
4624
4783
  case "error": {
@@ -4649,7 +4808,7 @@ var DefaultStreamTextResult = class {
4649
4808
  }
4650
4809
  }
4651
4810
  if (continueSteps && chunkBuffer.length > 0 && (nextStepType !== "continue" || // when the next step is a regular step, publish the buffer
4652
- stepType === "continue" && !chunkTextPublished)) {
4811
+ stepType2 === "continue" && !chunkTextPublished)) {
4653
4812
  await publishTextChunk({
4654
4813
  controller,
4655
4814
  chunk: {
@@ -4693,69 +4852,16 @@ var DefaultStreamTextResult = class {
4693
4852
  usage: stepUsage,
4694
4853
  experimental_providerMetadata: stepProviderMetadata,
4695
4854
  logprobs: stepLogProbs,
4696
- response: {
4697
- ...stepResponse
4698
- },
4699
- isContinued: nextStepType === "continue"
4700
- });
4701
- if (stepType === "continue") {
4702
- const lastMessage = responseMessages[responseMessages.length - 1];
4703
- if (typeof lastMessage.content === "string") {
4704
- lastMessage.content += stepText;
4705
- } else {
4706
- lastMessage.content.push({
4707
- text: stepText,
4708
- type: "text"
4709
- });
4710
- }
4711
- } else {
4712
- responseMessages.push(
4713
- ...toResponseMessages({
4714
- text: stepText,
4715
- tools: tools != null ? tools : {},
4716
- toolCalls: stepToolCalls,
4717
- toolResults: stepToolResults
4718
- })
4719
- );
4720
- }
4721
- const currentStepResult = {
4722
- stepType,
4723
- text: stepText,
4724
- toolCalls: stepToolCalls,
4725
- toolResults: stepToolResults,
4726
- finishReason: stepFinishReason,
4727
- usage: stepUsage,
4728
- warnings,
4729
- logprobs: stepLogProbs,
4730
4855
  request: stepRequest,
4731
4856
  response: {
4732
4857
  ...stepResponse,
4733
- headers: rawResponse == null ? void 0 : rawResponse.headers,
4734
- // deep clone msgs to avoid mutating past messages in multi-step:
4735
- messages: JSON.parse(JSON.stringify(responseMessages))
4858
+ headers: rawResponse == null ? void 0 : rawResponse.headers
4736
4859
  },
4737
- experimental_providerMetadata: stepProviderMetadata,
4860
+ warnings,
4738
4861
  isContinued: nextStepType === "continue"
4739
- };
4740
- stepResults.push(currentStepResult);
4741
- await (onStepFinish == null ? void 0 : onStepFinish(currentStepResult));
4742
- const combinedUsage = {
4743
- promptTokens: usage.promptTokens + stepUsage.promptTokens,
4744
- completionTokens: usage.completionTokens + stepUsage.completionTokens,
4745
- totalTokens: usage.totalTokens + stepUsage.totalTokens
4746
- };
4747
- if (nextStepType !== "done") {
4748
- await streamStep({
4749
- currentStep: currentStep + 1,
4750
- responseMessages,
4751
- usage: combinedUsage,
4752
- stepType: nextStepType,
4753
- previousStepText: fullStepText,
4754
- hasLeadingWhitespace: hasWhitespaceSuffix
4755
- });
4756
- return;
4757
- }
4758
- try {
4862
+ });
4863
+ const combinedUsage = addLanguageModelUsage(usage, stepUsage);
4864
+ if (nextStepType === "done") {
4759
4865
  controller.enqueue({
4760
4866
  type: "finish",
4761
4867
  finishReason: stepFinishReason,
@@ -4763,63 +4869,40 @@ var DefaultStreamTextResult = class {
4763
4869
  experimental_providerMetadata: stepProviderMetadata,
4764
4870
  logprobs: stepLogProbs,
4765
4871
  response: {
4766
- ...stepResponse
4872
+ ...stepResponse,
4873
+ headers: rawResponse == null ? void 0 : rawResponse.headers
4767
4874
  }
4768
4875
  });
4769
4876
  self.closeStream();
4770
- rootSpan.setAttributes(
4771
- selectTelemetryAttributes({
4772
- telemetry,
4773
- attributes: {
4774
- "ai.response.finishReason": stepFinishReason,
4775
- "ai.response.text": { output: () => fullStepText },
4776
- "ai.response.toolCalls": {
4777
- output: () => stepToolCallsJson
4778
- },
4779
- "ai.usage.promptTokens": combinedUsage.promptTokens,
4780
- "ai.usage.completionTokens": combinedUsage.completionTokens
4781
- }
4782
- })
4783
- );
4784
- self.usagePromise.resolve(combinedUsage);
4785
- self.finishReasonPromise.resolve(stepFinishReason);
4786
- self.textPromise.resolve(fullStepText);
4787
- self.toolCallsPromise.resolve(stepToolCalls);
4788
- self.providerMetadataPromise.resolve(stepProviderMetadata);
4789
- self.toolResultsPromise.resolve(stepToolResults);
4790
- self.requestPromise.resolve(stepRequest);
4791
- self.responsePromise.resolve({
4792
- ...stepResponse,
4793
- headers: rawResponse == null ? void 0 : rawResponse.headers,
4794
- messages: responseMessages
4795
- });
4796
- self.stepsPromise.resolve(stepResults);
4797
- self.warningsPromise.resolve(warnings != null ? warnings : []);
4798
- await (onFinish == null ? void 0 : onFinish({
4799
- finishReason: stepFinishReason,
4800
- logprobs: stepLogProbs,
4877
+ } else {
4878
+ if (stepType2 === "continue") {
4879
+ const lastMessage = responseMessages[responseMessages.length - 1];
4880
+ if (typeof lastMessage.content === "string") {
4881
+ lastMessage.content += stepText;
4882
+ } else {
4883
+ lastMessage.content.push({
4884
+ text: stepText,
4885
+ type: "text"
4886
+ });
4887
+ }
4888
+ } else {
4889
+ responseMessages.push(
4890
+ ...toResponseMessages({
4891
+ text: stepText,
4892
+ tools: tools != null ? tools : {},
4893
+ toolCalls: stepToolCalls,
4894
+ toolResults: stepToolResults
4895
+ })
4896
+ );
4897
+ }
4898
+ await streamStep({
4899
+ currentStep: currentStep + 1,
4900
+ responseMessages,
4801
4901
  usage: combinedUsage,
4802
- text: fullStepText,
4803
- toolCalls: stepToolCalls,
4804
- // The tool results are inferred as a never[] type, because they are
4805
- // optional and the execute method with an inferred result type is
4806
- // optional as well. Therefore we need to cast the toolResults to any.
4807
- // The type exposed to the users will be correctly inferred.
4808
- toolResults: stepToolResults,
4809
- request: stepRequest,
4810
- response: {
4811
- ...stepResponse,
4812
- headers: rawResponse == null ? void 0 : rawResponse.headers,
4813
- messages: responseMessages
4814
- },
4815
- warnings,
4816
- experimental_providerMetadata: stepProviderMetadata,
4817
- steps: stepResults
4818
- }));
4819
- } catch (error) {
4820
- controller.error(error);
4821
- } finally {
4822
- rootSpan.end();
4902
+ stepType: nextStepType,
4903
+ previousStepText: fullStepText,
4904
+ hasLeadingWhitespace: hasWhitespaceSuffix
4905
+ });
4823
4906
  }
4824
4907
  }
4825
4908
  })