Skip to content

Anthropic integration: streamed tool_use input is appended to gen_ai.response.text and tool_calls are not recorded #8050

Open

Description

@pcbeingused333

How do you use Sentry?

Sentry Saas (sentry.io)

Version

2.72.0 (also on master @ 0f7acd5)

Steps to Reproduce

With AnthropicIntegration enabled and send_default_pii=True, stream a response that contains a tool call:

import anthropic, sentry_sdk
from sentry_sdk.integrations.anthropic import AnthropicIntegration

sentry_sdk.init(dsn=..., traces_sample_rate=1.0, send_default_pii=True,
                integrations=[AnthropicIntegration(include_prompts=True)])

client = anthropic.Anthropic()
with sentry_sdk.start_transaction(name="t"):
    stream = client.messages.create(
        model="claude-sonnet-5-5", max_tokens=256, stream=True,
        tools=[{"name": "get_weather", "description": "Weather for a city",
                "input_schema": {"type": "object", "properties": {"city": {"type": "string"}}}}],
        messages=[{"role": "user", "content": "Weather in Paris?"}],
    )
    for _ in stream:
        pass

The response streams a text block ("Checking the weather.") and a tool_use block whose input arrives as input_json_delta events.

Expected Result

The AI client span records the same output as the non-streamed call with the same response:

  • gen_ai.response.text: Checking the weather.
  • gen_ai.response.tool_calls: [{"id": "toolu_1", "input": {"city": "Paris"}, "name": "get_weather", "type": "tool_use"}]

Actual Result

For the streamed call:

  • gen_ai.response.text: Checking the weather.{"city": "Paris"} (the tool input JSON is appended to the answer)
  • gen_ai.response.tool_calls: not set

_collect_ai_data appends both text_delta.text and input_json_delta.partial_json to the same content_blocks list (L339-341), and _set_streaming_output_data joins that list into a single text block (L977-1007). The block structure (which deltas belong to the text block and which to the tool_use block) is lost, so tool calls are never recorded for streams and the text attribute is corrupted.

This was reproduced with the real anthropic 1.15.0 client against a local endpoint that replays a Messages API event stream, comparing the non-streamed and streamed spans.

A possible fix: track blocks by content_block_start / index, keep text and tool_use input separate (parsing the accumulated JSON at content_block_stop), and set tool_calls the way the non-streamed path does. The OpenAI integration's streaming handlers have a related gap: they only collect delta.content, so streamed tool calls are missing there too (without corrupting the text).

Found with an automated check of streaming paths in tracing integrations and confirmed with the reproduction described above; this report was drafted with Claude Code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions