Skip to content

Commit 9559968

Browse files
google-genai-botcopybara-github
authored andcommitted
refactor: remove input.type and output.type attributes from adk metrics
They were added prematurely, and currently output.type diverges from what's in semconv (https://opentelemetry.io/docs/specs/semconv/registry/attributes/gen-ai/), so this change removes them from our metrics, at least for the time being. PiperOrigin-RevId: 910587563
1 parent f8b4c59 commit 9559968

5 files changed

Lines changed: 18 additions & 199 deletions

File tree

src/google/adk/flows/llm_flows/functions.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -593,7 +593,7 @@ async def _run_with_trace():
593593
return function_response_event
594594

595595
async with _instrumentation.record_tool_execution(
596-
tool, agent, invocation_context, function_args
596+
tool, agent, function_args
597597
) as tel_ctx:
598598
tel_ctx.function_response_event = await _run_with_trace()
599599
return tel_ctx.function_response_event
@@ -828,7 +828,7 @@ async def _run_with_trace():
828828
return function_response_event
829829

830830
async with _instrumentation.record_tool_execution(
831-
tool, agent, invocation_context, function_args
831+
tool, agent, function_args
832832
) as tel_ctx:
833833
tel_ctx.function_response_event = await _run_with_trace()
834834
return tel_ctx.function_response_event

src/google/adk/telemetry/_instrumentation.py

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
import contextlib
1818
import dataclasses
1919
import logging
20-
import sys
2120
import time
2221
from typing import Any
2322
from typing import AsyncIterator
@@ -94,8 +93,6 @@ async def record_agent_invocation(
9493
_metrics.record_agent_invocation_duration(
9594
agent.name,
9695
elapsed_ms,
97-
ctx.user_content,
98-
ctx.session.events,
9996
caught_error,
10097
)
10198
_metrics.record_agent_request_size(agent.name, ctx.user_content)
@@ -111,14 +108,12 @@ async def record_agent_invocation(
111108
async def record_tool_execution(
112109
tool: BaseTool,
113110
agent: BaseAgent,
114-
invocation_context: InvocationContext,
115111
function_args: dict[str, Any],
116112
) -> AsyncIterator[TelemetryContext]:
117113
"""Unified context manager for consolidated tool execution telemetry."""
118114
start_time = time.monotonic()
119115
caught_error: Exception | None = None
120116
span: trace.Span | None = None
121-
tel_ctx: TelemetryContext | None = None
122117
span_name = f"execute_tool {tool.name}"
123118
try:
124119
with tracing.tracer.start_as_current_span(span_name) as s:
@@ -140,22 +135,11 @@ async def record_tool_execution(
140135
error=caught_error,
141136
)
142137
finally:
143-
elapsed_ms = _get_elapsed_ms(span, start_time)
144-
result_event = (
145-
tel_ctx.function_response_event if tel_ctx is not None else None
146-
)
147-
output_content = (
148-
result_event.content
149-
if isinstance(result_event, event_lib.Event)
150-
else None
151-
)
152138
try:
153139
_metrics.record_tool_execution_duration(
154140
tool_name=tool.name,
155141
agent_name=agent.name,
156-
elapsed_ms=elapsed_ms,
157-
input_content=invocation_context.user_content,
158-
output_content=output_content,
142+
elapsed_ms=_get_elapsed_ms(span, start_time),
159143
error=caught_error,
160144
)
161145
except Exception: # pylint: disable=broad-exception-caught

src/google/adk/telemetry/_metrics.py

Lines changed: 11 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727

2828
# TODO(b/477553411): add these attributes to Otel semconv.
2929
GEN_AI_AGENT_VERSION = "gen_ai.agent.version"
30-
GEN_AI_INPUT_TYPE = "gen_ai.input.type"
3130
GEN_AI_TOOL_VERSION = "gen_ai.tool.version"
3231

3332
# Initialize meter
@@ -65,60 +64,37 @@
6564
)
6665

6766

68-
def record_agent_request_size(
69-
agent_name: str, user_content: types.Content | None
70-
):
71-
"""Records the size of the agent request."""
72-
size = _get_content_size(user_content)
73-
attrs = {
74-
gen_ai_attributes.GEN_AI_AGENT_NAME: agent_name,
75-
GEN_AI_INPUT_TYPE: _get_modality_from_content(user_content),
76-
}
77-
_agent_request_size.record(size, attributes=attrs)
78-
79-
8067
def record_agent_invocation_duration(
8168
agent_name: str,
8269
elapsed_ms: float,
83-
user_content: types.Content | None,
84-
events: list[Event],
8570
error: Exception | None = None,
8671
):
8772
"""Records the duration of the agent invocation."""
88-
response_content: types.Content | None = None
89-
for event in reversed(events):
90-
if event.author == agent_name and event.content:
91-
response_content = event.content
92-
break
93-
94-
attrs = {
95-
gen_ai_attributes.GEN_AI_AGENT_NAME: agent_name,
96-
GEN_AI_INPUT_TYPE: _get_modality_from_content(user_content),
97-
gen_ai_attributes.GEN_AI_OUTPUT_TYPE: _get_modality_from_content(
98-
response_content
99-
),
100-
}
73+
attrs = {gen_ai_attributes.GEN_AI_AGENT_NAME: agent_name}
10174
if error is not None:
10275
attrs[error_attributes.ERROR_TYPE] = type(error).__name__
10376
_agent_invocation_duration.record(elapsed_ms, attributes=attrs)
10477

10578

79+
def record_agent_request_size(
80+
agent_name: str, user_content: types.Content | None
81+
):
82+
"""Records the size of the agent request."""
83+
size = _get_content_size(user_content)
84+
attrs = {gen_ai_attributes.GEN_AI_AGENT_NAME: agent_name}
85+
_agent_request_size.record(size, attributes=attrs)
86+
87+
10688
def record_agent_response_size(agent_name: str, events: list[Event]):
10789
"""Records the size of the agent response by extracting content from events."""
10890
response_content: types.Content | None = None
10991
for event in reversed(events):
110-
# Need to look for author matching agent_name and having content
11192
if event.author == agent_name and event.content:
11293
response_content = event.content
11394
break
11495

11596
size = _get_content_size(response_content)
116-
attrs = {
117-
gen_ai_attributes.GEN_AI_AGENT_NAME: agent_name,
118-
gen_ai_attributes.GEN_AI_OUTPUT_TYPE: _get_modality_from_content(
119-
response_content
120-
),
121-
}
97+
attrs = {gen_ai_attributes.GEN_AI_AGENT_NAME: agent_name}
12298
_agent_response_size.record(size, attributes=attrs)
12399

124100

@@ -134,52 +110,18 @@ def record_tool_execution_duration(
134110
tool_name: str,
135111
agent_name: str,
136112
elapsed_ms: float,
137-
input_content: types.Content | None,
138-
output_content: types.Content | None,
139113
error: Exception | None = None,
140114
):
141115
"""Records the duration of the tool execution."""
142116
attrs = {
143117
gen_ai_attributes.GEN_AI_AGENT_NAME: agent_name,
144118
gen_ai_attributes.GEN_AI_TOOL_NAME: tool_name,
145-
GEN_AI_INPUT_TYPE: _get_modality_from_content(input_content),
146119
}
147120
if error is not None:
148121
attrs[error_attributes.ERROR_TYPE] = type(error).__name__
149-
else:
150-
attrs[gen_ai_attributes.GEN_AI_OUTPUT_TYPE] = _get_modality_from_content(
151-
output_content
152-
)
153122
_tool_execution_duration.record(elapsed_ms, attributes=attrs)
154123

155124

156-
# Helper functions copied from metrics_plugin.py
157-
158-
159-
def _get_modality_from_content(
160-
content: types.Content | None,
161-
) -> str:
162-
if content is None or not content.parts:
163-
return "unknown"
164-
modalities = set()
165-
for part in content.parts:
166-
if part.text is not None:
167-
modalities.add("text")
168-
inline_data = part.inline_data
169-
if inline_data and inline_data.mime_type:
170-
mime = inline_data.mime_type
171-
if "/" in mime:
172-
modalities.add(mime.split("/")[0])
173-
file_data = part.file_data
174-
if file_data and file_data.mime_type:
175-
mime = file_data.mime_type
176-
if "/" in mime:
177-
modalities.add(mime.split("/")[0])
178-
if not modalities:
179-
return "text"
180-
return ",".join(sorted(modalities))
181-
182-
183125
def _get_content_size(
184126
content: types.Content | None,
185127
) -> int:

tests/unittests/telemetry/test_functional.py

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -316,8 +316,6 @@ async def generate_random_number():
316316
MetricPoint(
317317
attributes={
318318
"gen_ai.agent.name": "complex_agent",
319-
"gen_ai.input.type": "text",
320-
"gen_ai.output.type": "text",
321319
},
322320
value=None,
323321
)
@@ -334,17 +332,13 @@ async def generate_random_number():
334332
attributes={
335333
"gen_ai.agent.name": "complex_agent",
336334
"gen_ai.tool.name": "generate_random_number",
337-
"gen_ai.input.type": "text",
338-
"gen_ai.output.type": "text",
339335
},
340336
value=None,
341337
),
342338
MetricPoint(
343339
attributes={
344340
"gen_ai.agent.name": "complex_agent",
345341
"gen_ai.tool.name": "get_current_time",
346-
"gen_ai.input.type": "text",
347-
"gen_ai.output.type": "text",
348342
},
349343
value=None,
350344
),
@@ -401,7 +395,6 @@ async def failing_tool():
401395
attributes={
402396
"gen_ai.agent.name": "error_agent",
403397
"gen_ai.tool.name": "failing_tool",
404-
"gen_ai.input.type": "text",
405398
"error.type": "ValueError",
406399
},
407400
value=None,
@@ -410,8 +403,6 @@ async def failing_tool():
410403
attributes={
411404
"gen_ai.agent.name": "error_agent",
412405
"gen_ai.tool.name": "get_current_time",
413-
"gen_ai.input.type": "text",
414-
"gen_ai.output.type": "text",
415406
},
416407
value=None,
417408
),

0 commit comments

Comments
 (0)