fix(agents): gate tool-span I/O behind DATAPIZZA_TRACE_CLIENT_IO - #141
Open
antoniociccia wants to merge 1 commit into
Open
fix(agents): gate tool-span I/O behind DATAPIZZA_TRACE_CLIENT_IO#141antoniociccia wants to merge 1 commit into
antoniociccia wants to merge 1 commit into
Conversation
Tool spans exported tool arguments and results unconditionally, so sensitive data handled by tools (file contents, DB rows, PII) leaked to trace exporters by default. Client I/O is already gated behind DATAPIZZA_TRACE_CLIENT_IO in core/clients/client.py; tool spans were simply not covered. Gate the two set_attribute calls in _execute_tool and _a_execute_tool behind the same flag (default off). The console log_panel output is intentionally left unchanged. Adds sync+async regression tests and documents the flag's tool coverage.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
When an agent runs a tool, AgentRunner._execute_tool / _a_execute_tool attach the tool arguments and result to the tracing span unconditionally. Span attributes are the export surface of tracing: once the SDK's OTLP instrumentor is enabled (DATAPIZZA_OTLP_ENDPOINT), every span - tool spans included - is shipped to a remote collector via BatchSpanProcessor, carrying those attributes. So sensitive data a tool handles (file contents, DB rows, PII) is exported off-box.
Client I/O is already protected: core/clients/client.py gates input/output/memory span attributes behind DATAPIZZA_TRACE_CLIENT_IO (default false), and it's documented. Tool spans were simply not covered by the same gate.
Fix
Gate the two set_attribute("tool_arguments" / "tool_result", …) calls in both the sync and async tool executors behind the same existing DATAPIZZA_TRACE_CLIENT_IO flag (default off), via a small _trace_tool_io_enabled() helper. No new dependency, no public API change. The span attributes are pure observability - no code path reads them back (get_token_usage only reads type=="generation" spans), so control flow and the returned FunctionCallResultBlock are unchanged.
Scope / follow-up
The console log_panel output is intentionally left unchanged (different sink, developer UX). In containerized deployments stdout is often shipped to a persistent aggregator, so gating the console channel could be a sensible follow-up - kept out of this PR to stay minimal. Reusing the client flag also means enabling client-I/O tracing re-enables tool-I/O tracing; a separate DATAPIZZA_TRACE_TOOL_IO flag is an easy alternative if maintainers prefer.
Tests
Adds test_tool_span_privacy.py (9 tests, sync + async): default omits tool I/O from spans; =true/=TRUE includes it; non-true values (1) don't enable it; falsy results never set tool_result; and invariants that the return value and console output are preserved. Full agents+tracing suite: 93 passing.