Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

[bot] Bedrock ConverseStream drops tool use and non-text content blocks in streaming spans

未关闭
#85 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

评估

难度
4/5
预计耗时
3-5 天
新手友好度
64/100
Issue 类型
缺陷
描述清晰度
描述清楚
活跃度
冷清
技术栈
aws, java

调研方向

从 braintrust-sdk/instrumentation/aws_bedrock_2_30_0/src/main/java/dev/braintrust/instrumentation/awsbedrock/v2_30_0/BraintrustBedrockInterceptor.java 中的 TeeingSubscriber.onNext、parseDeltaText 和 buildConverseJson 开始。将流式事件处理与 braintrust-sdk/src/main/java/dev/braintrust/instrumentation/InstrumentationSemConv.java 中的 normalizeBedrockMessage() 进行比较,并查看现有的 Bedrock 测试。当流式 tool-use 内容、标识符、名称和输入都在 span 输出中得到表示,并在 BraintrustAWSBedrockTest.java 中有覆盖时,即表示完成。

由索引模型根据 Issue 内容生成。

描述

Summary

The Bedrock ConverseStream instrumentation in TeeingSubscriber only accumulates delta.text from contentBlockDelta events. When the model returns tool use content blocks during streaming (a documented and supported Bedrock feature), the tool call data is silently dropped from the span output.

Non-streaming Converse calls handle tool use correctly — normalizeBedrockMessage() in InstrumentationSemConv already recognizes toolUse, toolResult, and image content block types and adds appropriate type annotations. The gap is exclusively in the streaming path.

What is missing

1. TeeingSubscriber only parses text deltas (lines 273–289)
case "contentBlockDelta" -> {
    String t = parseDeltaText(payload);   // only looks for delta.text
    if (t != null) {
        text.append(t);
        // ...
    }
}

parseDeltaText() (lines 322–339) searches exclusively for delta.text. Bedrock ConverseStream sends delta.toolUse for tool use blocks (containing incremental input JSON), which is silently ignored.

2. contentBlockStart events are not handled

The TeeingSubscriber switch (lines 273–289) has no case for contentBlockStart. This event carries toolUse.toolUseId and toolUse.name — metadata needed to reconstruct the tool call. Without it, even if tool use deltas were captured, the tool name and ID would be lost.

3. buildConverseJson always produces a single text block (lines 385–410)
gen.writeArrayFieldStart("content");
gen.writeStartObject();
gen.writeStringField("text", text);   // always one text block
gen.writeEndObject();
gen.writeEndArray();

The synthetic response JSON always contains exactly one {"text": "..."} content block, regardless of what the model actually returned. When the model requests a tool call, the span output will show empty text instead of the tool invocation.

Impact

When a streaming Bedrock call triggers tool use (common in agentic workflows):

  • The span's output_json contains [{"role":"assistant","content":[{"text":"","type":"text"}]}] — as if the model returned nothing
  • The stopReason is captured as "tool_use", contradicting the empty output
  • Tool call names, IDs, and argument JSON are permanently lost from the trace
  • Non-streaming Converse calls with tool use are correctly captured

Braintrust docs status

Upstream sources

Local files inspected

  • braintrust-sdk/instrumentation/aws_bedrock_2_30_0/src/main/java/dev/braintrust/instrumentation/awsbedrock/v2_30_0/BraintrustBedrockInterceptor.java — lines 273–289 (TeeingSubscriber.onNext: only contentBlockDelta→text, messageStop, metadata handled; no contentBlockStart), lines 322–339 (parseDeltaText: only delta.text), lines 385–410 (buildConverseJson: hardcoded single text block)
  • braintrust-sdk/src/main/java/dev/braintrust/instrumentation/InstrumentationSemConv.java — lines 400–434 (normalizeBedrockMessage: non-streaming path correctly handles toolUse, toolResult, image content block types)
  • braintrust-sdk/instrumentation/aws_bedrock_2_30_0/src/test/java/dev/braintrust/instrumentation/awsbedrock/v2_30_0/BraintrustAWSBedrockTest.java — no streaming test exercises tool use responses
主要语言
Java
星标
21
派生
5
平均合并
2 天 34 分钟
30 天内合并 PR
6

环境准备

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

从这里开始

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

braintrustdata/braintrust-sdk-java 的其他 Issue

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

相似的 Issue

更多 Java Issue

把新 issue 发到你的邮箱

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