Skip to content

Commit 63b8ed2

Browse files
starfolkai[bot]starfolkbotclaude
authored
fix(anthropic): drop redundant bt_safe_deep_copy passes in tracing (#583)
## Summary - `SpanImpl.log_internal` already runs `bt_safe_deep_copy` on every logged event (see `logger.py:4699`), so the eager copies in `_normalize_anthropic_input`, `_get_input_from_kwargs`, and `_redact_server_tool_output` were duplicating work on every span open/log. - Removed the three `bt_safe_deep_copy` calls and dropped the now-unused import. The remaining walks (`_normalize_anthropic_data`, `_process_input_attachments`, inlined redaction) already build fresh dicts/lists and never mutate user data, so behavior is preserved. - Mirrors what `google_genai/tracing.py` does today and matches the `sdk-integrations` skill guidance: "Do not over-serialize. Braintrust serializes at send/log time." ## Test plan - [x] `pytest src/braintrust/integrations/anthropic/test_anthropic.py` on anthropic==0.116.0 (matrix `latest`) — 48 passed - [x] `pytest src/braintrust/integrations/anthropic/test_anthropic.py` on anthropic==0.48.0 — 39 passed, 9 legitimately skipped for features unavailable on that version - No cassettes re-recorded, no new mocks/fakes added — used the existing VCR-backed tests 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- sfk:created-approved-by --> Created by abhijeet <!-- sfk:slack-thread --> [Slack thread](https://starfolkai.slack.com/archives/C0AQDETAVT3/p1784236089663339?thread_ts=1784236089.663339&cid=C0AQDETAVT3) Co-authored-by: Starfolk <noreply@starfolk.ai> Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
1 parent cb8323f commit 63b8ed2

1 file changed

Lines changed: 11 additions & 18 deletions

File tree

  • py/src/braintrust/integrations/anthropic

‎py/src/braintrust/integrations/anthropic/tracing.py‎

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import warnings
44
from typing import Any
55

6-
from braintrust.bt_json import bt_safe_deep_copy
76
from braintrust.integrations.anthropic._utils import Wrapper, _try_to_dict, extract_anthropic_usage
87
from braintrust.integrations.utils import _materialize_attachment
98
from braintrust.logger import log_exc_info_to_span
@@ -904,7 +903,7 @@ def _normalize_anthropic_data(value: Any) -> Any:
904903

905904

906905
def _normalize_anthropic_input(value: Any) -> Any:
907-
return _process_input_attachments(_normalize_anthropic_data(bt_safe_deep_copy(value)))
906+
return _process_input_attachments(_normalize_anthropic_data(value))
908907

909908

910909
def _managed_agents_model_name(value: Any) -> str | None:
@@ -1280,10 +1279,9 @@ def _process_input_attachments(value):
12801279

12811280

12821281
def _get_input_from_kwargs(kwargs):
1283-
msgs = bt_safe_deep_copy(list(kwargs.get("messages", [])))
1284-
msgs = _process_input_attachments(msgs)
1282+
msgs = _process_input_attachments(list(kwargs.get("messages", [])))
12851283

1286-
system = bt_safe_deep_copy(kwargs.get("system", None))
1284+
system = kwargs.get("system", None)
12871285
if system:
12881286
msgs.append({"role": "system", "content": _process_input_attachments(system)})
12891287

@@ -1343,19 +1341,14 @@ def _tool_span_input(call_item: dict[str, Any] | None) -> Any:
13431341

13441342

13451343
def _redact_server_tool_output(value: Any) -> Any:
1346-
value = bt_safe_deep_copy(value)
1347-
1348-
def _redact(inner: Any) -> Any:
1349-
if isinstance(inner, list):
1350-
return [_redact(item) for item in inner]
1351-
if isinstance(inner, dict):
1352-
return {
1353-
key: ("<redacted>" if key in _SERVER_TOOL_SPAN_REDACTED_KEYS else _redact(item))
1354-
for key, item in inner.items()
1355-
}
1356-
return inner
1357-
1358-
return _redact(value)
1344+
if isinstance(value, list):
1345+
return [_redact_server_tool_output(item) for item in value]
1346+
if isinstance(value, dict):
1347+
return {
1348+
key: ("<redacted>" if key in _SERVER_TOOL_SPAN_REDACTED_KEYS else _redact_server_tool_output(item))
1349+
for key, item in value.items()
1350+
}
1351+
return value
13591352

13601353

13611354
def _tool_span_output(result_item: dict[str, Any] | None) -> Any:

0 commit comments

Comments
 (0)