Skip to content

Commit 5e51452

Browse files
committed
fix: close PR224 semantic convention gaps
1 parent 9ca80c0 commit 5e51452

15 files changed

Lines changed: 61 additions & 21 deletions

File tree

instrumentation-loongsuite/loongsuite-instrumentation-agentscope/src/opentelemetry/instrumentation/agentscope/_v2_middleware.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,7 @@ async def on_acting(
259259
handler.start_react_step(react_invocation, context=get_current())
260260
invocation = ExecuteToolInvocation(
261261
tool_name=getattr(tool_call, "name", "unknown_tool"),
262+
tool_type="function",
262263
tool_call_id=getattr(tool_call, "id", None),
263264
tool_call_arguments=_loads_json(getattr(tool_call, "input", None)),
264265
provider="agentscope",

instrumentation-loongsuite/loongsuite-instrumentation-agentscope/tests/test_v2_instrumentation.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ async def tool_handler(**kwargs):
240240
span_exporter.get_finished_spans(), "execute_tool"
241241
)[0]
242242
assert tool_span.attributes["gen_ai.tool.name"] == "lookup_weather"
243+
assert tool_span.attributes["gen_ai.tool.type"] == "function"
243244

244245

245246
async def test_v2_tool_result_content_capture(
@@ -333,6 +334,9 @@ async def tool_handler(**kwargs):
333334
"calculate_total",
334335
"write_summary",
335336
}
337+
assert {span.attributes["gen_ai.tool.type"] for span in tool_spans} == {
338+
"function"
339+
}
336340
react_span_ids = {span.context.span_id for span in react_spans}
337341
assert {span.parent.span_id for span in tool_spans} == react_span_ids
338342

instrumentation-loongsuite/loongsuite-instrumentation-google-adk/src/opentelemetry/instrumentation/google_adk/internal/_plugin.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,12 @@
6060
)
6161

6262

63+
def _non_empty_string(value: Any) -> Optional[str]:
64+
if isinstance(value, str) and value.strip():
65+
return value
66+
return None
67+
68+
6369
class GoogleAdkObservabilityPlugin(BasePlugin):
6470
"""
6571
OpenTelemetry ADK Observability Plugin.
@@ -119,7 +125,6 @@ async def before_run_callback(
119125
invocation = InvokeAgentInvocation(
120126
provider="google_adk",
121127
agent_name=invocation_context.app_name,
122-
agent_id=invocation_context.app_name,
123128
)
124129

125130
# Set conversation_id if available
@@ -276,12 +281,12 @@ async def before_agent_callback(
276281
invocation = InvokeAgentInvocation(
277282
provider="google_adk",
278283
agent_name=agent.name,
279-
agent_id=agent.name,
280284
)
281285

282286
# Set agent attributes
283-
if hasattr(agent, "id") and agent.id:
284-
invocation.agent_id = agent.id
287+
agent_id = _non_empty_string(getattr(agent, "id", None))
288+
if agent_id:
289+
invocation.agent_id = agent_id
285290

286291
if hasattr(agent, "description") and agent.description:
287292
invocation.agent_description = agent.description

instrumentation-loongsuite/loongsuite-instrumentation-google-adk/tests/test_plugin_integration.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,38 @@ async def test_agent_span_attributes_semantic_conventions(self):
412412
"gen_ai.agent.description" in attributes
413413
or "agent.description" in attributes
414414
), "Should have agent description attribute"
415+
assert "gen_ai.agent.id" not in attributes
416+
417+
@pytest.mark.asyncio
418+
async def test_agent_span_uses_explicit_agent_id(self):
419+
"""Test that Agent spans use real agent.id when ADK exposes one."""
420+
self.instrumentor.instrument(
421+
tracer_provider=self.tracer_provider,
422+
meter_provider=self.meter_provider,
423+
)
424+
425+
plugin = self.instrumentor._plugin
426+
427+
mock_agent = Mock()
428+
mock_agent.name = "weather_agent"
429+
mock_agent.id = "agent_123"
430+
mock_agent.description = "Agent for weather queries"
431+
mock_agent.sub_agents = []
432+
433+
mock_callback_context = create_mock_callback_context(
434+
"session_789", "user_999"
435+
)
436+
437+
await plugin.before_agent_callback(
438+
agent=mock_agent, callback_context=mock_callback_context
439+
)
440+
await plugin.after_agent_callback(
441+
agent=mock_agent, callback_context=mock_callback_context
442+
)
443+
444+
spans = self.span_exporter.get_finished_spans()
445+
assert len(spans) == 1
446+
assert spans[0].attributes["gen_ai.agent.id"] == "agent_123"
415447

416448
@pytest.mark.asyncio
417449
async def test_tool_span_attributes_semantic_conventions(self):
@@ -534,6 +566,7 @@ async def test_runner_span_attributes(self):
534566
assert attributes.get("gen_ai.span.kind") == "AGENT"
535567
# Note: runner.app_name is namespaced with google_adk prefix
536568
assert attributes.get("google_adk.runner.app_name") == "test_app"
569+
assert "gen_ai.agent.id" not in attributes
537570

538571
@pytest.mark.asyncio
539572
async def test_runner_span_finishes_on_root_final_event(self):

instrumentation-loongsuite/loongsuite-instrumentation-hermes-agent/src/opentelemetry/instrumentation/hermes_agent/helpers.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -580,7 +580,6 @@ def create_agent_invocation(
580580
invocation = InvokeAgentInvocation(
581581
provider=_HERMES_AGENT_SYSTEM,
582582
agent_name="Hermes",
583-
agent_id="Hermes",
584583
conversation_id=getattr(instance, "session_id", None),
585584
request_model=getattr(instance, "model", None),
586585
input_messages=[

instrumentation-loongsuite/loongsuite-instrumentation-langchain/src/opentelemetry/instrumentation/langchain/internal/_tracer.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -451,7 +451,6 @@ def _start_agent(self, run: Run) -> None:
451451
invocation = InvokeAgentInvocation(
452452
provider="langchain",
453453
agent_name=agent_name,
454-
agent_id=agent_name or None,
455454
input_messages=input_messages,
456455
)
457456
self._handler.start_invoke_agent(invocation, context=parent_ctx)

instrumentation-loongsuite/loongsuite-instrumentation-minisweagent/src/opentelemetry/instrumentation/minisweagent/internal/agent_wrappers.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,6 @@ def __call__(
115115
inv = InvokeAgentInvocation(
116116
provider="minisweagent",
117117
agent_name=agent_name,
118-
agent_id=agent_name,
119118
)
120119
inv.request_model = _request_model_from_agent(instance)
121120
inv.attributes.setdefault("gen_ai.framework", "minisweagent")

instrumentation-loongsuite/loongsuite-instrumentation-qwen-agent/src/opentelemetry/instrumentation/qwen_agent/utils.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -613,7 +613,6 @@ def _create_agent_invocation(
613613
invocation = InvokeAgentInvocation(
614614
provider=provider_name,
615615
agent_name=agent_name,
616-
agent_id=agent_name,
617616
agent_description=agent_description,
618617
request_model=request_model,
619618
input_messages=input_messages,

instrumentation-loongsuite/loongsuite-instrumentation-vita/src/opentelemetry/instrumentation/vita/patch.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,6 @@ def wrap_generate_next_message(
300300
invocation = InvokeAgentInvocation(
301301
provider="vitabench",
302302
agent_name=agent_name,
303-
agent_id=agent_name,
304303
request_model=model,
305304
)
306305

instrumentation-loongsuite/loongsuite-instrumentation-widesearch/src/opentelemetry/instrumentation/widesearch/utils.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,6 @@ def _create_agent_invocation(
8888
invocation = InvokeAgentInvocation(
8989
provider="widesearch",
9090
agent_name=agent_name,
91-
agent_id=agent_name,
9291
agent_description=instructions[:200] if instructions else "",
9392
request_model=request_model,
9493
input_messages=[

0 commit comments

Comments
 (0)