Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions src/google/adk/telemetry/_instrumentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@ def record_llm_response(
def _record_agent_metrics(
agent_name: str,
elapsed_s: float,
user_content: object,
events: object,
caught_error: Exception | None,
) -> None:
Expand All @@ -116,8 +115,6 @@ def _record_agent_metrics(
elapsed_s,
caught_error,
)
_metrics.record_agent_request_size(agent_name, user_content)
_metrics.record_agent_response_size(agent_name, events)
_metrics.record_agent_workflow_steps(agent_name, events)
except Exception: # pylint: disable=broad-exception-caught
logger.exception("Failed to record agent metrics for agent %s", agent_name)
Expand Down Expand Up @@ -145,7 +142,6 @@ async def record_agent_invocation(
_record_agent_metrics(
agent.name,
_metrics.get_elapsed_s(span, start_time),
getattr(ctx, "user_content", None),
getattr(getattr(ctx, "session", None), "events", []),
caught_error,
)
Expand Down
79 changes: 0 additions & 79 deletions src/google/adk/telemetry/_metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
from google.adk import version
from google.adk.telemetry import tracing
from google.adk.telemetry._token_usage import TokenUsage
from google.genai import types
from opentelemetry import metrics
from opentelemetry.semconv._incubating.attributes import gen_ai_attributes
from opentelemetry.semconv._incubating.metrics import gen_ai_metrics
Expand Down Expand Up @@ -92,48 +91,6 @@
81.92,
],
)
_agent_request_size = meter.create_histogram(
"gen_ai.agent.request.size",
unit="By",
description="Size of agent requests.",
explicit_bucket_boundaries_advisory=[
1,
4,
16,
64,
256,
1024,
4096,
16384,
65536,
262144,
1048576,
4194304,
16777216,
67108864,
],
)
_agent_response_size = meter.create_histogram(
"gen_ai.agent.response.size",
unit="By",
description="Size of agent responses.",
explicit_bucket_boundaries_advisory=[
1,
4,
16,
64,
256,
1024,
4096,
16384,
65536,
262144,
1048576,
4194304,
16777216,
67108864,
],
)
_agent_workflow_steps = meter.create_histogram(
"gen_ai.agent.workflow.steps",
unit="1",
Expand Down Expand Up @@ -191,28 +148,6 @@ def record_workflow_invocation_duration(
_workflow_invocation_duration.record(elapsed_s, attributes=attrs)


def record_agent_request_size(
agent_name: str, user_content: types.Content | None
):
"""Records the size of the agent request."""
size = _get_content_size(user_content)
attrs = {gen_ai_attributes.GEN_AI_AGENT_NAME: agent_name}
_agent_request_size.record(size, attributes=attrs)


def record_agent_response_size(agent_name: str, events: list[Event]):
"""Records the size of the agent response by extracting content from events."""
response_content: types.Content | None = None
for event in reversed(events):
if event.author == agent_name and event.content:
response_content = event.content
break

size = _get_content_size(response_content)
attrs = {gen_ai_attributes.GEN_AI_AGENT_NAME: agent_name}
_agent_response_size.record(size, attributes=attrs)


def record_agent_workflow_steps(agent_name: str, events: list[Event]):
"""Records the number of steps in the agent workflow by counting the number of events."""
attrs = {gen_ai_attributes.GEN_AI_AGENT_NAME: agent_name}
Expand Down Expand Up @@ -318,20 +253,6 @@ def record_client_token_usage(
_client_token_usage.record(output_token_count, attributes=output_attrs)


def _get_content_size(
content: types.Content | None,
) -> int:
if not content or not content.parts:
return 0
size = 0
for part in content.parts:
if part.text is not None:
size += len(part.text.encode("utf-8"))
if part.inline_data and part.inline_data.data:
size += len(part.inline_data.data)
return size


def _get_provider_name() -> str:
return tracing._guess_gemini_system_name()

Expand Down
24 changes: 0 additions & 24 deletions tests/unittests/telemetry/functional_node_test_cases.py
Original file line number Diff line number Diff line change
Expand Up @@ -2597,18 +2597,6 @@
value=NON_DETERMINISTIC,
),
}),
"gen_ai.agent.request.size": frozenset({
MetricPoint(
attributes={"gen_ai.agent.name": AGENT_NAME},
value=len(USER_PROMPT),
),
}),
"gen_ai.agent.response.size": frozenset({
MetricPoint(
attributes={"gen_ai.agent.name": AGENT_NAME},
value=len(FINAL_TEXT),
),
}),
"gen_ai.agent.workflow.steps": frozenset({
MetricPoint(attributes={"gen_ai.agent.name": AGENT_NAME}, value=3),
}),
Expand Down Expand Up @@ -2653,18 +2641,6 @@
value=NON_DETERMINISTIC,
),
}),
"gen_ai.agent.request.size": frozenset({
MetricPoint(
attributes={"gen_ai.agent.name": AGENT_NAME},
value=len(USER_PROMPT),
),
}),
"gen_ai.agent.response.size": frozenset({
MetricPoint(
attributes={"gen_ai.agent.name": AGENT_NAME},
value=len(FINAL_TEXT),
),
}),
"gen_ai.agent.workflow.steps": frozenset({
MetricPoint(attributes={"gen_ai.agent.name": AGENT_NAME}, value=3),
}),
Expand Down
24 changes: 0 additions & 24 deletions tests/unittests/telemetry/functional_test_cases.py
Original file line number Diff line number Diff line change
Expand Up @@ -2291,18 +2291,6 @@
value=NON_DETERMINISTIC,
),
}),
"gen_ai.agent.request.size": frozenset({
MetricPoint(
attributes={"gen_ai.agent.name": AGENT_NAME},
value=len(USER_PROMPT),
),
}),
"gen_ai.agent.response.size": frozenset({
MetricPoint(
attributes={"gen_ai.agent.name": AGENT_NAME},
value=len(FINAL_TEXT),
),
}),
"gen_ai.agent.workflow.steps": frozenset({
MetricPoint(attributes={"gen_ai.agent.name": AGENT_NAME}, value=3),
}),
Expand Down Expand Up @@ -2338,18 +2326,6 @@
value=NON_DETERMINISTIC,
),
}),
"gen_ai.agent.request.size": frozenset({
MetricPoint(
attributes={"gen_ai.agent.name": AGENT_NAME},
value=len(USER_PROMPT),
),
}),
"gen_ai.agent.response.size": frozenset({
MetricPoint(
attributes={"gen_ai.agent.name": AGENT_NAME},
value=len(FINAL_TEXT),
),
}),
"gen_ai.agent.workflow.steps": frozenset({
MetricPoint(attributes={"gen_ai.agent.name": AGENT_NAME}, value=3),
}),
Expand Down
10 changes: 0 additions & 10 deletions tests/unittests/telemetry/functional_test_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -314,16 +314,6 @@ class HistogramSpec(NamedTuple):
attr="_tool_execution_duration",
metric_name="gen_ai.execute_tool.duration",
),
HistogramSpec(
module=_metrics,
attr="_agent_request_size",
metric_name="gen_ai.agent.request.size",
),
HistogramSpec(
module=_metrics,
attr="_agent_response_size",
metric_name="gen_ai.agent.response.size",
),
HistogramSpec(
module=_metrics,
attr="_agent_workflow_steps",
Expand Down
15 changes: 7 additions & 8 deletions tests/unittests/telemetry/test_instrumentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,16 +86,16 @@ def test_get_elapsed_s_span_non_int_end():

@pytest.mark.asyncio
async def test_record_agent_invocation_tolerates_minimal_context():
"""Tolerates context-likes that lack user_content or session.
"""Tolerates context-likes that lack session.

Test doubles, partial migrations, and external embedders can pass an
InvocationContext-like object without `user_content` or with a `session`
that has no `events` attribute. The telemetry path must not raise
AttributeError on the metrics call in those cases.
InvocationContext-like object with a `session` that has no `events`
attribute. The telemetry path must not raise AttributeError on the
metrics call in those cases.
"""
agent = mock.MagicMock()
agent.name = "test_agent"
# Bare object without `user_content` and without `session`.
# Bare object without `session`.
bare_ctx = object()

with (
Expand All @@ -112,7 +112,6 @@ async def test_record_agent_invocation_tolerates_minimal_context():

mock_record.assert_called_once()
call_args = mock_record.call_args
# positional: (agent_name, elapsed_s, user_content, events, caught_error)
# positional: (agent_name, elapsed_s, events, caught_error)
assert call_args.args[0] == "test_agent"
assert call_args.args[2] is None # user_content default
assert call_args.args[3] == [] # events default
assert call_args.args[2] == [] # events default
Loading
Loading