ai 6.0.117 → 6.0.119

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,24 @@
1
1
  # ai
2
2
 
3
+ ## 6.0.119
4
+
5
+ ### Patch Changes
6
+
7
+ - ab286f1: fix(ai): doStream should reflect transformed values
8
+ - d68b122: feat(ai): add missing usage attributes
9
+
10
+ ## 6.0.118
11
+
12
+ ### Patch Changes
13
+
14
+ - 64ac0fd: fix(security): validate redirect targets in download functions to prevent SSRF bypass
15
+
16
+ Both `downloadBlob` and `download` now validate the final URL after following HTTP redirects, preventing attackers from bypassing SSRF protections via open redirects to internal/private addresses.
17
+
18
+ - Updated dependencies [64ac0fd]
19
+ - @ai-sdk/provider-utils@4.0.20
20
+ - @ai-sdk/gateway@3.0.68
21
+
3
22
  ## 6.0.117
4
23
 
5
24
  ### Patch Changes
package/dist/index.js CHANGED
@@ -1230,7 +1230,7 @@ var import_provider_utils3 = require("@ai-sdk/provider-utils");
1230
1230
  var import_provider_utils4 = require("@ai-sdk/provider-utils");
1231
1231
 
1232
1232
  // src/version.ts
1233
- var VERSION = true ? "6.0.117" : "0.0.0-test";
1233
+ var VERSION = true ? "6.0.119" : "0.0.0-test";
1234
1234
 
1235
1235
  // src/util/download/download.ts
1236
1236
  var download = async ({
@@ -1250,6 +1250,9 @@ var download = async ({
1250
1250
  ),
1251
1251
  signal: abortSignal
1252
1252
  });
1253
+ if (response.redirected) {
1254
+ (0, import_provider_utils3.validateDownloadUrl)(response.url);
1255
+ }
1253
1256
  if (!response.ok) {
1254
1257
  throw new import_provider_utils3.DownloadError({
1255
1258
  url: urlText,
@@ -4203,7 +4206,7 @@ async function generateText({
4203
4206
  }),
4204
4207
  tracer,
4205
4208
  fn: async (span) => {
4206
- var _a21, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
4209
+ var _a21, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t;
4207
4210
  const initialMessages = initialPrompt.messages;
4208
4211
  const responseMessages = [];
4209
4212
  const { approvedToolApprovals, deniedToolApprovals } = collectToolApprovals({ messages: initialMessages });
@@ -4420,6 +4423,7 @@ async function generateText({
4420
4423
  headers: (_g2 = result.response) == null ? void 0 : _g2.headers,
4421
4424
  body: (_h2 = result.response) == null ? void 0 : _h2.body
4422
4425
  };
4426
+ const usage = asLanguageModelUsage(result.usage);
4423
4427
  span2.setAttributes(
4424
4428
  await selectTelemetryAttributes({
4425
4429
  telemetry,
@@ -4443,9 +4447,16 @@ async function generateText({
4443
4447
  "ai.response.providerMetadata": JSON.stringify(
4444
4448
  result.providerMetadata
4445
4449
  ),
4446
- // TODO rename telemetry attributes to inputTokens and outputTokens
4447
- "ai.usage.promptTokens": result.usage.inputTokens.total,
4448
- "ai.usage.completionTokens": result.usage.outputTokens.total,
4450
+ "ai.usage.inputTokens": result.usage.inputTokens.total,
4451
+ "ai.usage.inputTokenDetails.noCacheTokens": result.usage.inputTokens.noCache,
4452
+ "ai.usage.inputTokenDetails.cacheReadTokens": result.usage.inputTokens.cacheRead,
4453
+ "ai.usage.inputTokenDetails.cacheWriteTokens": result.usage.inputTokens.cacheWrite,
4454
+ "ai.usage.outputTokens": result.usage.outputTokens.total,
4455
+ "ai.usage.outputTokenDetails.textTokens": result.usage.outputTokens.text,
4456
+ "ai.usage.outputTokenDetails.reasoningTokens": result.usage.outputTokens.reasoning,
4457
+ "ai.usage.totalTokens": usage.totalTokens,
4458
+ "ai.usage.reasoningTokens": result.usage.outputTokens.reasoning,
4459
+ "ai.usage.cachedInputTokens": result.usage.inputTokens.cacheRead,
4449
4460
  // standardized gen-ai llm span attributes:
4450
4461
  "gen_ai.response.finish_reasons": [
4451
4462
  result.finishReason.unified
@@ -4646,10 +4657,7 @@ async function generateText({
4646
4657
  },
4647
4658
  "ai.response.providerMetadata": JSON.stringify(
4648
4659
  currentModelResponse.providerMetadata
4649
- ),
4650
- // TODO rename telemetry attributes to inputTokens and outputTokens
4651
- "ai.usage.promptTokens": currentModelResponse.usage.inputTokens.total,
4652
- "ai.usage.completionTokens": currentModelResponse.usage.outputTokens.total
4660
+ )
4653
4661
  }
4654
4662
  })
4655
4663
  );
@@ -4666,6 +4674,23 @@ async function generateText({
4666
4674
  cachedInputTokens: void 0
4667
4675
  }
4668
4676
  );
4677
+ span.setAttributes(
4678
+ await selectTelemetryAttributes({
4679
+ telemetry,
4680
+ attributes: {
4681
+ "ai.usage.inputTokens": totalUsage.inputTokens,
4682
+ "ai.usage.inputTokenDetails.noCacheTokens": (_n = totalUsage.inputTokenDetails) == null ? void 0 : _n.noCacheTokens,
4683
+ "ai.usage.inputTokenDetails.cacheReadTokens": (_o = totalUsage.inputTokenDetails) == null ? void 0 : _o.cacheReadTokens,
4684
+ "ai.usage.inputTokenDetails.cacheWriteTokens": (_p = totalUsage.inputTokenDetails) == null ? void 0 : _p.cacheWriteTokens,
4685
+ "ai.usage.outputTokens": totalUsage.outputTokens,
4686
+ "ai.usage.outputTokenDetails.textTokens": (_q = totalUsage.outputTokenDetails) == null ? void 0 : _q.textTokens,
4687
+ "ai.usage.outputTokenDetails.reasoningTokens": (_r = totalUsage.outputTokenDetails) == null ? void 0 : _r.reasoningTokens,
4688
+ "ai.usage.totalTokens": totalUsage.totalTokens,
4689
+ "ai.usage.reasoningTokens": (_s = totalUsage.outputTokenDetails) == null ? void 0 : _s.reasoningTokens,
4690
+ "ai.usage.cachedInputTokens": (_t = totalUsage.inputTokenDetails) == null ? void 0 : _t.cacheReadTokens
4691
+ }
4692
+ })
4693
+ );
4669
4694
  await notify({
4670
4695
  event: {
4671
4696
  stepNumber: lastStep.stepNumber,
@@ -6764,6 +6789,7 @@ var DefaultStreamTextResult = class {
6764
6789
  }
6765
6790
  },
6766
6791
  async flush(controller) {
6792
+ var _a21, _b, _c, _d, _e, _f, _g;
6767
6793
  try {
6768
6794
  if (recordedSteps.length === 0) {
6769
6795
  const error = (abortSignal == null ? void 0 : abortSignal.aborted) ? abortSignal.reason : new NoOutputGeneratedError({
@@ -6827,18 +6853,23 @@ var DefaultStreamTextResult = class {
6827
6853
  },
6828
6854
  "ai.response.toolCalls": {
6829
6855
  output: () => {
6830
- var _a21;
6831
- return ((_a21 = finalStep.toolCalls) == null ? void 0 : _a21.length) ? JSON.stringify(finalStep.toolCalls) : void 0;
6856
+ var _a22;
6857
+ return ((_a22 = finalStep.toolCalls) == null ? void 0 : _a22.length) ? JSON.stringify(finalStep.toolCalls) : void 0;
6832
6858
  }
6833
6859
  },
6834
6860
  "ai.response.providerMetadata": JSON.stringify(
6835
6861
  finalStep.providerMetadata
6836
6862
  ),
6837
6863
  "ai.usage.inputTokens": totalUsage.inputTokens,
6864
+ "ai.usage.inputTokenDetails.noCacheTokens": (_a21 = totalUsage.inputTokenDetails) == null ? void 0 : _a21.noCacheTokens,
6865
+ "ai.usage.inputTokenDetails.cacheReadTokens": (_b = totalUsage.inputTokenDetails) == null ? void 0 : _b.cacheReadTokens,
6866
+ "ai.usage.inputTokenDetails.cacheWriteTokens": (_c = totalUsage.inputTokenDetails) == null ? void 0 : _c.cacheWriteTokens,
6838
6867
  "ai.usage.outputTokens": totalUsage.outputTokens,
6868
+ "ai.usage.outputTokenDetails.textTokens": (_d = totalUsage.outputTokenDetails) == null ? void 0 : _d.textTokens,
6869
+ "ai.usage.outputTokenDetails.reasoningTokens": (_e = totalUsage.outputTokenDetails) == null ? void 0 : _e.reasoningTokens,
6839
6870
  "ai.usage.totalTokens": totalUsage.totalTokens,
6840
- "ai.usage.reasoningTokens": totalUsage.reasoningTokens,
6841
- "ai.usage.cachedInputTokens": totalUsage.cachedInputTokens
6871
+ "ai.usage.reasoningTokens": (_f = totalUsage.outputTokenDetails) == null ? void 0 : _f.reasoningTokens,
6872
+ "ai.usage.cachedInputTokens": (_g = totalUsage.inputTokenDetails) == null ? void 0 : _g.cacheReadTokens
6842
6873
  }
6843
6874
  })
6844
6875
  );
@@ -7450,6 +7481,7 @@ var DefaultStreamTextResult = class {
7450
7481
  },
7451
7482
  // invoke onFinish callback and resolve toolResults promise when the stream is about to close:
7452
7483
  async flush(controller) {
7484
+ var _a22, _b2, _c2, _d2, _e2, _f2, _g2;
7453
7485
  const stepToolCallsJson = stepToolCalls.length > 0 ? JSON.stringify(stepToolCalls) : void 0;
7454
7486
  try {
7455
7487
  doStreamSpan.setAttributes(
@@ -7457,29 +7489,22 @@ var DefaultStreamTextResult = class {
7457
7489
  telemetry,
7458
7490
  attributes: {
7459
7491
  "ai.response.finishReason": stepFinishReason,
7460
- "ai.response.text": {
7461
- output: () => activeText
7462
- },
7463
- "ai.response.reasoning": {
7464
- output: () => {
7465
- const reasoningParts = recordedContent.filter(
7466
- (c) => c.type === "reasoning"
7467
- );
7468
- return reasoningParts.length > 0 ? reasoningParts.map((r) => r.text).join("\n") : void 0;
7469
- }
7470
- },
7471
7492
  "ai.response.toolCalls": {
7472
7493
  output: () => stepToolCallsJson
7473
7494
  },
7474
7495
  "ai.response.id": stepResponse.id,
7475
7496
  "ai.response.model": stepResponse.modelId,
7476
7497
  "ai.response.timestamp": stepResponse.timestamp.toISOString(),
7477
- "ai.response.providerMetadata": JSON.stringify(stepProviderMetadata),
7478
7498
  "ai.usage.inputTokens": stepUsage.inputTokens,
7499
+ "ai.usage.inputTokenDetails.noCacheTokens": (_a22 = stepUsage.inputTokenDetails) == null ? void 0 : _a22.noCacheTokens,
7500
+ "ai.usage.inputTokenDetails.cacheReadTokens": (_b2 = stepUsage.inputTokenDetails) == null ? void 0 : _b2.cacheReadTokens,
7501
+ "ai.usage.inputTokenDetails.cacheWriteTokens": (_c2 = stepUsage.inputTokenDetails) == null ? void 0 : _c2.cacheWriteTokens,
7479
7502
  "ai.usage.outputTokens": stepUsage.outputTokens,
7503
+ "ai.usage.outputTokenDetails.textTokens": (_d2 = stepUsage.outputTokenDetails) == null ? void 0 : _d2.textTokens,
7504
+ "ai.usage.outputTokenDetails.reasoningTokens": (_e2 = stepUsage.outputTokenDetails) == null ? void 0 : _e2.reasoningTokens,
7480
7505
  "ai.usage.totalTokens": stepUsage.totalTokens,
7481
- "ai.usage.reasoningTokens": stepUsage.reasoningTokens,
7482
- "ai.usage.cachedInputTokens": stepUsage.cachedInputTokens,
7506
+ "ai.usage.reasoningTokens": (_f2 = stepUsage.outputTokenDetails) == null ? void 0 : _f2.reasoningTokens,
7507
+ "ai.usage.cachedInputTokens": (_g2 = stepUsage.inputTokenDetails) == null ? void 0 : _g2.cacheReadTokens,
7483
7508
  // standardized gen-ai llm span attributes:
7484
7509
  "gen_ai.response.finish_reasons": [
7485
7510
  stepFinishReason
@@ -7492,8 +7517,6 @@ var DefaultStreamTextResult = class {
7492
7517
  })
7493
7518
  );
7494
7519
  } catch (error) {
7495
- } finally {
7496
- doStreamSpan.end();
7497
7520
  }
7498
7521
  controller.enqueue({
7499
7522
  type: "finish-step",
@@ -7511,6 +7534,28 @@ var DefaultStreamTextResult = class {
7511
7534
  stepUsage
7512
7535
  );
7513
7536
  await stepFinish.promise;
7537
+ const processedStep = recordedSteps[recordedSteps.length - 1];
7538
+ try {
7539
+ doStreamSpan.setAttributes(
7540
+ await selectTelemetryAttributes({
7541
+ telemetry,
7542
+ attributes: {
7543
+ "ai.response.text": {
7544
+ output: () => processedStep.text
7545
+ },
7546
+ "ai.response.reasoning": {
7547
+ output: () => processedStep.reasoningText
7548
+ },
7549
+ "ai.response.providerMetadata": JSON.stringify(
7550
+ processedStep.providerMetadata
7551
+ )
7552
+ }
7553
+ })
7554
+ );
7555
+ } catch (error) {
7556
+ } finally {
7557
+ doStreamSpan.end();
7558
+ }
7514
7559
  const clientToolCalls = stepToolCalls.filter(
7515
7560
  (toolCall) => toolCall.providerExecuted !== true
7516
7561
  );