ai 7.0.0-beta.2 → 7.0.0-beta.4

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,23 @@
1
1
  # ai
2
2
 
3
+ ## 7.0.0-beta.4
4
+
5
+ ### Patch Changes
6
+
7
+ - 5ceed7d: fix(ai): doStream should reflect transformed values
8
+
9
+ ## 7.0.0-beta.3
10
+
11
+ ### Patch Changes
12
+
13
+ - 531251e: fix(security): validate redirect targets in download functions to prevent SSRF bypass
14
+
15
+ 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.
16
+
17
+ - Updated dependencies [531251e]
18
+ - @ai-sdk/provider-utils@5.0.0-beta.1
19
+ - @ai-sdk/gateway@4.0.0-beta.2
20
+
3
21
  ## 7.0.0-beta.2
4
22
 
5
23
  ### Patch Changes
package/dist/index.js CHANGED
@@ -1370,7 +1370,7 @@ var import_provider_utils3 = require("@ai-sdk/provider-utils");
1370
1370
  var import_provider_utils4 = require("@ai-sdk/provider-utils");
1371
1371
 
1372
1372
  // src/version.ts
1373
- var VERSION = true ? "7.0.0-beta.2" : "0.0.0-test";
1373
+ var VERSION = true ? "7.0.0-beta.4" : "0.0.0-test";
1374
1374
 
1375
1375
  // src/util/download/download.ts
1376
1376
  var download = async ({
@@ -1390,6 +1390,9 @@ var download = async ({
1390
1390
  ),
1391
1391
  signal: abortSignal
1392
1392
  });
1393
+ if (response.redirected) {
1394
+ (0, import_provider_utils3.validateDownloadUrl)(response.url);
1395
+ }
1393
1396
  if (!response.ok) {
1394
1397
  throw new import_provider_utils3.DownloadError({
1395
1398
  url: urlText,
@@ -7597,24 +7600,12 @@ var DefaultStreamTextResult = class {
7597
7600
  telemetry,
7598
7601
  attributes: {
7599
7602
  "ai.response.finishReason": stepFinishReason,
7600
- "ai.response.text": {
7601
- output: () => activeText
7602
- },
7603
- "ai.response.reasoning": {
7604
- output: () => {
7605
- const reasoningParts = recordedContent.filter(
7606
- (c) => c.type === "reasoning"
7607
- );
7608
- return reasoningParts.length > 0 ? reasoningParts.map((r) => r.text).join("\n") : void 0;
7609
- }
7610
- },
7611
7603
  "ai.response.toolCalls": {
7612
7604
  output: () => stepToolCallsJson
7613
7605
  },
7614
7606
  "ai.response.id": stepResponse.id,
7615
7607
  "ai.response.model": stepResponse.modelId,
7616
7608
  "ai.response.timestamp": stepResponse.timestamp.toISOString(),
7617
- "ai.response.providerMetadata": JSON.stringify(stepProviderMetadata),
7618
7609
  "ai.usage.inputTokens": stepUsage.inputTokens,
7619
7610
  "ai.usage.outputTokens": stepUsage.outputTokens,
7620
7611
  "ai.usage.totalTokens": stepUsage.totalTokens,
@@ -7632,8 +7623,6 @@ var DefaultStreamTextResult = class {
7632
7623
  })
7633
7624
  );
7634
7625
  } catch (error) {
7635
- } finally {
7636
- doStreamSpan.end();
7637
7626
  }
7638
7627
  controller.enqueue({
7639
7628
  type: "finish-step",
@@ -7651,6 +7640,28 @@ var DefaultStreamTextResult = class {
7651
7640
  stepUsage
7652
7641
  );
7653
7642
  await stepFinish.promise;
7643
+ const processedStep = recordedSteps[recordedSteps.length - 1];
7644
+ try {
7645
+ doStreamSpan.setAttributes(
7646
+ await selectTelemetryAttributes({
7647
+ telemetry,
7648
+ attributes: {
7649
+ "ai.response.text": {
7650
+ output: () => processedStep.text
7651
+ },
7652
+ "ai.response.reasoning": {
7653
+ output: () => processedStep.reasoningText
7654
+ },
7655
+ "ai.response.providerMetadata": JSON.stringify(
7656
+ processedStep.providerMetadata
7657
+ )
7658
+ }
7659
+ })
7660
+ );
7661
+ } catch (error) {
7662
+ } finally {
7663
+ doStreamSpan.end();
7664
+ }
7654
7665
  const clientToolCalls = stepToolCalls.filter(
7655
7666
  (toolCall) => toolCall.providerExecuted !== true
7656
7667
  );