Skip to content

Commit 5880109

Browse files
GWealecopybara-github
authored andcommitted
fix: Set empty JSON string as placeholder for redacted content in traces
When content capture is disabled, trace attributes for tool arguments, tool responses, LLM requests, LLM responses, and agent data are now set to the string '{}' instead of an empty dictionary Close #4094 Co-authored-by: George Weale <gweale@google.com> PiperOrigin-RevId: 855304806
1 parent 458d24e commit 5880109

File tree

2 files changed

+71
-54
lines changed

2 files changed

+71
-54
lines changed

src/google/adk/telemetry/tracing.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ def trace_tool_call(
149149
_safe_json_serialize(args),
150150
)
151151
else:
152-
span.set_attribute('gcp.vertex.agent.tool_call_args', {})
152+
span.set_attribute('gcp.vertex.agent.tool_call_args', '{}')
153153

154154
# Tracing tool response
155155
tool_call_id = '<not specified>'
@@ -179,7 +179,7 @@ def trace_tool_call(
179179
_safe_json_serialize(tool_response),
180180
)
181181
else:
182-
span.set_attribute('gcp.vertex.agent.tool_response', {})
182+
span.set_attribute('gcp.vertex.agent.tool_response', '{}')
183183

184184

185185
def trace_merged_tool_calls(
@@ -219,7 +219,7 @@ def trace_merged_tool_calls(
219219
function_response_event_json,
220220
)
221221
else:
222-
span.set_attribute('gcp.vertex.agent.tool_response', {})
222+
span.set_attribute('gcp.vertex.agent.tool_response', '{}')
223223
# Setting empty llm request and response (as UI expect these) while not
224224
# applicable for tool_response.
225225
span.set_attribute('gcp.vertex.agent.llm_request', '{}')
@@ -265,7 +265,7 @@ def trace_call_llm(
265265
_safe_json_serialize(_build_llm_request_for_trace(llm_request)),
266266
)
267267
else:
268-
span.set_attribute('gcp.vertex.agent.llm_request', {})
268+
span.set_attribute('gcp.vertex.agent.llm_request', '{}')
269269
# Consider removing once GenAI SDK provides a way to record this info.
270270
if llm_request.config:
271271
if llm_request.config.top_p:
@@ -290,7 +290,7 @@ def trace_call_llm(
290290
llm_response_json,
291291
)
292292
else:
293-
span.set_attribute('gcp.vertex.agent.llm_response', {})
293+
span.set_attribute('gcp.vertex.agent.llm_response', '{}')
294294

295295
if llm_response.usage_metadata is not None:
296296
span.set_attribute(
@@ -346,7 +346,7 @@ def trace_send_data(
346346
]),
347347
)
348348
else:
349-
span.set_attribute('gcp.vertex.agent.data', {})
349+
span.set_attribute('gcp.vertex.agent.data', '{}')
350350

351351

352352
def _build_llm_request_for_trace(llm_request: LlmRequest) -> dict[str, Any]:

tests/unittests/telemetry/test_spans.py

Lines changed: 65 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
from google.adk.telemetry.tracing import trace_agent_invocation
2828
from google.adk.telemetry.tracing import trace_call_llm
2929
from google.adk.telemetry.tracing import trace_merged_tool_calls
30+
from google.adk.telemetry.tracing import trace_send_data
3031
from google.adk.telemetry.tracing import trace_tool_call
3132
from google.adk.tools.base_tool import BaseTool
3233
from google.genai import types
@@ -447,7 +448,7 @@ def test_trace_merged_tool_calls_sets_correct_attributes(
447448
async def test_call_llm_disabling_request_response_content(
448449
monkeypatch, mock_span_fixture
449450
):
450-
"""Test trace_call_llm doesn't set request and response attributes if env is set to false"""
451+
"""Test trace_call_llm sets placeholders when capture is disabled."""
451452
# Arrange
452453
monkeypatch.setenv(ADK_CAPTURE_MESSAGE_CONTENT_IN_SPANS, 'false')
453454
monkeypatch.setattr(
@@ -474,23 +475,19 @@ async def test_call_llm_disabling_request_response_content(
474475
trace_call_llm(invocation_context, 'test_event_id', llm_request, llm_response)
475476

476477
# Assert
477-
assert not any(
478-
arg_name == 'gcp.vertex.agent.llm_request' and arg_value != {}
479-
for arg_name, arg_value in (
480-
call_obj.args
481-
for call_obj in mock_span_fixture.set_attribute.call_args_list
482-
)
483-
), "Attribute 'gcp.vertex.agent.llm_request' was incorrectly set on the span."
484-
485-
assert not any(
486-
arg_name == 'gcp.vertex.agent.llm_response' and arg_value != {}
487-
for arg_name, arg_value in (
488-
call_obj.args
489-
for call_obj in mock_span_fixture.set_attribute.call_args_list
490-
)
491-
), (
492-
"Attribute 'gcp.vertex.agent.llm_response' was incorrectly set on the"
493-
' span.'
478+
assert (
479+
'gcp.vertex.agent.llm_request',
480+
'{}',
481+
) in (
482+
call_obj.args
483+
for call_obj in mock_span_fixture.set_attribute.call_args_list
484+
)
485+
assert (
486+
'gcp.vertex.agent.llm_response',
487+
'{}',
488+
) in (
489+
call_obj.args
490+
for call_obj in mock_span_fixture.set_attribute.call_args_list
494491
)
495492

496493

@@ -500,7 +497,7 @@ def test_trace_tool_call_disabling_request_response_content(
500497
mock_tool_fixture,
501498
mock_event_fixture,
502499
):
503-
"""Test trace_tool_call doesn't set request and response attributes if env is set to false"""
500+
"""Test trace_tool_call sets placeholders when capture is disabled."""
504501
# Arrange
505502
monkeypatch.setenv(ADK_CAPTURE_MESSAGE_CONTENT_IN_SPANS, 'false')
506503
monkeypatch.setattr(
@@ -537,26 +534,19 @@ def test_trace_tool_call_disabling_request_response_content(
537534
)
538535

539536
# Assert
540-
assert not any(
541-
arg_name == 'gcp.vertex.agent.tool_call_args' and arg_value != {}
542-
for arg_name, arg_value in (
543-
call_obj.args
544-
for call_obj in mock_span_fixture.set_attribute.call_args_list
545-
)
546-
), (
547-
"Attribute 'gcp.vertex.agent.tool_call_args' was incorrectly set on the"
548-
' span.'
537+
assert (
538+
'gcp.vertex.agent.tool_call_args',
539+
'{}',
540+
) in (
541+
call_obj.args
542+
for call_obj in mock_span_fixture.set_attribute.call_args_list
549543
)
550-
551-
assert not any(
552-
arg_name == 'gcp.vertex.agent.tool_response' and arg_value != {}
553-
for arg_name, arg_value in (
554-
call_obj.args
555-
for call_obj in mock_span_fixture.set_attribute.call_args_list
556-
)
557-
), (
558-
"Attribute 'gcp.vertex.agent.tool_response' was incorrectly set on the"
559-
' span.'
544+
assert (
545+
'gcp.vertex.agent.tool_response',
546+
'{}',
547+
) in (
548+
call_obj.args
549+
for call_obj in mock_span_fixture.set_attribute.call_args_list
560550
)
561551

562552

@@ -565,7 +555,7 @@ def test_trace_merged_tool_disabling_request_response_content(
565555
mock_span_fixture,
566556
mock_event_fixture,
567557
):
568-
"""Test trace_merged_tool doesn't set request and response attributes if env is set to false"""
558+
"""Test trace_merged_tool_calls sets placeholders when capture is disabled."""
569559
# Arrange
570560
monkeypatch.setenv(ADK_CAPTURE_MESSAGE_CONTENT_IN_SPANS, 'false')
571561
monkeypatch.setattr(
@@ -585,13 +575,40 @@ def test_trace_merged_tool_disabling_request_response_content(
585575
)
586576

587577
# Assert
588-
assert not any(
589-
arg_name == 'gcp.vertex.agent.tool_response' and arg_value != {}
590-
for arg_name, arg_value in (
591-
call_obj.args
592-
for call_obj in mock_span_fixture.set_attribute.call_args_list
593-
)
594-
), (
595-
"Attribute 'gcp.vertex.agent.tool_response' was incorrectly set on the"
596-
' span.'
578+
assert (
579+
'gcp.vertex.agent.tool_response',
580+
'{}',
581+
) in (
582+
call_obj.args
583+
for call_obj in mock_span_fixture.set_attribute.call_args_list
584+
)
585+
586+
587+
@pytest.mark.asyncio
588+
async def test_trace_send_data_disabling_request_response_content(
589+
monkeypatch, mock_span_fixture
590+
):
591+
"""Test trace_send_data sets placeholders when capture is disabled."""
592+
monkeypatch.setenv(ADK_CAPTURE_MESSAGE_CONTENT_IN_SPANS, 'false')
593+
monkeypatch.setattr(
594+
'opentelemetry.trace.get_current_span', lambda: mock_span_fixture
595+
)
596+
597+
agent = LlmAgent(name='test_agent')
598+
invocation_context = await _create_invocation_context(agent)
599+
600+
trace_send_data(
601+
invocation_context=invocation_context,
602+
event_id='test_event_id',
603+
data=[
604+
types.Content(
605+
role='user',
606+
parts=[types.Part(text='hi')],
607+
)
608+
],
609+
)
610+
611+
assert ('gcp.vertex.agent.data', '{}') in (
612+
call_obj.args
613+
for call_obj in mock_span_fixture.set_attribute.call_args_list
597614
)

0 commit comments

Comments
 (0)