wrapAISDK copies AI SDK v7 file bytes one key per byte instead of turning them into attachments

未关闭
#2,750 0 条评论 0 个 reaction 已指派 1 人 在 GitHub 查看

维护者通常 1 天内回复

@AbhiPrasad 已经在做这个了。

开始于 2026年11月6日。

  • #2751 来自 @pmartinsdev —— 已关闭,未合并
  • #2752 来自 @AbhiPrasad —— 未关闭

评估

这个 Issue 还没有评估数据。

描述

typescript

What happens

With ai 7.0.145 and braintrust 3.32.0, file parts reach the doStream model span as { type: 'file', mediaType, data: { type: 'data', data: Uint8Array } }, the AI SDK 7 shape (SharedV4FileData). processContentPart passes part.data, the wrapper object, to convertDataToAttachment, which only handles a string, Uint8Array, Buffer or Blob, so no attachment is made. deepCopyEvent then runs JSON.stringify and JSON.parse on the raw Uint8Array, which becomes an object with one key per byte.

https://github.com/braintrustdata/braintrust-sdk-javascript/blob/braintrust%403.32.0/js/src/instrumentation/plugins/ai-sdk-plugin.ts#L1297-L1301

The same code is in 3.43.0 and on main as of e0b7107dc7.

Impact

1 MB of image bytes becomes 1,000,000 keys and about 120 MB of heap on every model call. We call Claude through Vertex, which takes no image URLs, so the AI SDK downloads every image in the conversation and each call carries all of them. A chat with 25 MB of images pushed the heap to about 3.1 GB, and our 4 GB serverless instances were killed for memory.

On a single 38-image call (24.5 MB of images), the heap peaked at 2,651 MB with wrapAISDK and at 117 MB without it, and deepCopyEvent alone allocated 5.4 GB.

Reproduction

processContentPart leaves this shape untouched, so the model span event is copied like this.

import { deepCopyEvent } from 'braintrust';

const copy = deepCopyEvent({
  input: [{ type: 'file', mediaType: 'image/png', data: { type: 'data', data: new Uint8Array(1_000_000) } }],
});
// copy.input[0].data.data is a plain object with 1,000,000 keys, about 11 MB of JSON

Workaround we use

A one-line change in processContentPart, applied with pnpm patch to every build in dist, fixes it for us.

       const fileAttachment = convertDataToAttachment(
-        part.data,
+        part.data.type === "data" ? part.data.data : part.data,
         part.mimeType || part.mediaType,
         part.name || part.filename
       );

With it, the same 38-image call peaked at 130 MB of heap with tracing on. A complete fix could also handle { type: 'url' } and the other SharedV4FileData variants in convertDataToAttachment.

Environment

  • braintrust 3.32.0, also seen at runtime on 3.42.0 and in the source of 3.43.0
  • ai 7.0.145 with @ai-sdk/google-vertex 5.0.117 (Anthropic on Vertex)
  • Node 22
主要语言
TypeScript
星标
29
派生
22
平均合并
1 天 25 分钟
30 天内合并 PR
80

环境准备

  • 提供 Dockerfile 或 Docker Compose 文件
  • 没有 Pull Request 模板
  • 没有贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

braintrustdata/braintrust-sdk-javascript 的其他 Issue

查看 braintrustdata/braintrust-sdk-javascript 的全部 Issue

相似的 Issue

更多 TypeScript Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。