feat(telemetry): Expand load_skill telemetry
Extend the `execute_tool load_skill` span by adding new skill-related attributes. Adds new experimental attributes, and new namespace for them. PiperOrigin-RevId: 964033870
This commit is contained in:
committed by
Copybara-Service
parent
2e878ed412
commit
bddbb3dd8c
@@ -0,0 +1,35 @@
|
||||
# Copyright 2026 Google LLC
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""ADK-owned span attribute names.
|
||||
|
||||
These attributes are defined by ADK itself; they are not part of any
|
||||
OpenTelemetry semantic convention (neither the stable one in
|
||||
``_stable_semconv`` nor the experimental one in ``_experimental_semconv``).
|
||||
|
||||
Everything named ``adk.experimental.*`` is emitted only when experimental
|
||||
telemetry is enabled and carries no compatibility guarantee: an attribute may be
|
||||
renamed, restructured, or removed in any release.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
ADK_EXPERIMENTAL_SKILL_NAME = 'adk.experimental.skill.name'
|
||||
ADK_EXPERIMENTAL_SKILL_SOURCE_TYPE = 'adk.experimental.skill.source.type'
|
||||
ADK_EXPERIMENTAL_SKILL_CACHE_HIT = 'adk.experimental.skill.cache_hit'
|
||||
ADK_EXPERIMENTAL_SKILL_DESCRIPTION = 'adk.experimental.skill.description'
|
||||
ADK_EXPERIMENTAL_SKILL_ADDITIONAL_TOOLS = (
|
||||
'adk.experimental.skill.additional_tools'
|
||||
)
|
||||
ADK_EXPERIMENTAL_SKILL_SOURCE_URI = 'adk.experimental.skill.source.uri'
|
||||
@@ -16,6 +16,7 @@ from __future__ import annotations
|
||||
|
||||
import contextlib
|
||||
import dataclasses
|
||||
import enum
|
||||
import logging
|
||||
import sys
|
||||
import time
|
||||
@@ -26,6 +27,7 @@ from typing import TYPE_CHECKING
|
||||
from opentelemetry import trace
|
||||
import opentelemetry.context as context_api
|
||||
|
||||
from . import _adk_attributes
|
||||
from . import _metrics
|
||||
from . import tracing
|
||||
from ._schema_version import resolve_schema_version
|
||||
@@ -38,12 +40,16 @@ if TYPE_CHECKING:
|
||||
from ..events import event as event_lib
|
||||
from ..models.llm_request import LlmRequest
|
||||
from ..models.llm_response import LlmResponse
|
||||
from ..skills.models import Skill
|
||||
from ..tools.base_tool import BaseTool
|
||||
from ..workflow._base_node import BaseNode
|
||||
|
||||
logger = logging.getLogger("google_adk." + __name__)
|
||||
|
||||
_INVOKE_AGENT_TELEMETRY_KEY = context_api.create_key("invoke_agent_telemetry")
|
||||
_TOOL_EXECUTION_TELEMETRY_KEY = context_api.create_key(
|
||||
"tool_execution_telemetry"
|
||||
)
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
@@ -85,6 +91,37 @@ def record_invocation(
|
||||
yield
|
||||
|
||||
|
||||
class SkillTelemetrySpanType(enum.Enum):
|
||||
"""Skill telemetry type."""
|
||||
|
||||
SKILL_LOAD = enum.auto()
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class SkillTelemetry:
|
||||
"""Skill related telemetry.
|
||||
|
||||
Added to the enclosing tool execution via :func:`record_skill_telemetry`,
|
||||
which is what turns it into attributes on the skill related spans.
|
||||
|
||||
Attributes:
|
||||
span_type: The type of skill telemetry being recorded.
|
||||
skill_name: The name of the skill.
|
||||
skill: The loaded skill, or None if the load did not produce one (unknown
|
||||
skill name, registry failure). Nothing is recorded in that case; the
|
||||
failure itself is already reported as the span's ``error.type``.
|
||||
cache_hit: Whether the skill came from the per-invocation fetch cache
|
||||
instead of the registry. Only meaningful for registry-sourced skills.
|
||||
additional_tools: The list of additional tools reported by the skill.
|
||||
"""
|
||||
|
||||
span_type: SkillTelemetrySpanType
|
||||
skill_name: str | None = None
|
||||
skill: Skill | None = None
|
||||
cache_hit: bool = False
|
||||
additional_tools: list[str] = dataclasses.field(default_factory=list)
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class TelemetryContext:
|
||||
"""Stores all telemetry related state."""
|
||||
@@ -93,6 +130,7 @@ class TelemetryContext:
|
||||
function_response_event: event_lib.Event | None = None
|
||||
error_type: str | None = None
|
||||
span: tracing.GenerateContentSpan | trace.Span | None = None
|
||||
skill_telemetry: SkillTelemetry | None = None
|
||||
_llm_responses: list[LlmResponse] = dataclasses.field(default_factory=list)
|
||||
_inference_call_count: int = 0
|
||||
_tool_call_count: int = 0
|
||||
@@ -167,6 +205,109 @@ def _accumulate_invoke_agent_inference_call() -> None:
|
||||
span_tel_ctx.increment_inference_calls()
|
||||
|
||||
|
||||
def _active_tool_execution_tel_ctx() -> TelemetryContext | None:
|
||||
"""Returns the TelemetryContext of the active execute_tool span."""
|
||||
value = context_api.get_value(_TOOL_EXECUTION_TELEMETRY_KEY)
|
||||
return value if isinstance(value, TelemetryContext) else None
|
||||
|
||||
|
||||
def record_skill_telemetry(
|
||||
telemetry_type: SkillTelemetrySpanType,
|
||||
) -> SkillTelemetry:
|
||||
"""Attaches skill telemetry to the enclosing tool execution.
|
||||
|
||||
The attributes are written by :func:`record_tool_execution`, which owns the
|
||||
``execute_tool`` span, once the tool call completes. Callers therefore never
|
||||
depend on a span being open: outside a tool execution this is a no-op rather
|
||||
than an attribute silently landing on whatever span happens to be current.
|
||||
|
||||
A tool execution references a single skill, so a second call within the same
|
||||
tool execution replaces the first.
|
||||
|
||||
Args:
|
||||
telemetry_type: The type of skill telemetry being recorded.
|
||||
|
||||
Returns:
|
||||
skill_telemetry: Skill telemetry reference to record against the active tool
|
||||
call.
|
||||
"""
|
||||
tel_ctx = _active_tool_execution_tel_ctx()
|
||||
if tel_ctx is None:
|
||||
logger.debug(
|
||||
"No tool execution is being recorded, skill telemetry will not be"
|
||||
" attached to current span."
|
||||
)
|
||||
return SkillTelemetry(span_type=telemetry_type)
|
||||
if tel_ctx.skill_telemetry is not None:
|
||||
logger.warning(
|
||||
"Tool execution already has attached skill telemetry, overwriting."
|
||||
)
|
||||
tel_ctx.skill_telemetry = SkillTelemetry(span_type=telemetry_type)
|
||||
return tel_ctx.skill_telemetry
|
||||
|
||||
|
||||
def record_skill_cache_hit() -> None:
|
||||
"""Records a skill cache hit against the enclosing tool execution."""
|
||||
tel_ctx = _active_tool_execution_tel_ctx()
|
||||
if tel_ctx is None:
|
||||
logger.debug(
|
||||
"Skipping skill cache hit: no tool execution is being recorded."
|
||||
)
|
||||
return
|
||||
if tel_ctx.skill_telemetry is None:
|
||||
logger.warning(
|
||||
"Tool execution has no attached skill telemetry, skipping cache hit."
|
||||
)
|
||||
return
|
||||
tel_ctx.skill_telemetry.cache_hit = True
|
||||
|
||||
|
||||
def _trace_skill_load(
|
||||
span: trace.Span,
|
||||
skill_telemetry: SkillTelemetry | None,
|
||||
invocation_context: InvocationContext,
|
||||
) -> None:
|
||||
"""Stamps the skill load attributes onto the ``execute_tool`` span."""
|
||||
if skill_telemetry is None:
|
||||
return
|
||||
|
||||
telemetry_config = tracing._telemetry_config_from_invocation_context(
|
||||
invocation_context
|
||||
)
|
||||
if not telemetry_config.should_emit_experimental_telemetry:
|
||||
return
|
||||
|
||||
if skill_telemetry.skill_name is not None:
|
||||
span.set_attribute(
|
||||
_adk_attributes.ADK_EXPERIMENTAL_SKILL_NAME, skill_telemetry.skill_name
|
||||
)
|
||||
|
||||
skill = skill_telemetry.skill
|
||||
if skill is None:
|
||||
return
|
||||
|
||||
span.set_attribute(
|
||||
_adk_attributes.ADK_EXPERIMENTAL_SKILL_DESCRIPTION, skill.description
|
||||
)
|
||||
|
||||
if skill._uri is not None:
|
||||
span.set_attribute(
|
||||
_adk_attributes.ADK_EXPERIMENTAL_SKILL_SOURCE_URI, skill._uri
|
||||
)
|
||||
|
||||
if skill._uri.startswith(("http", "https")):
|
||||
# Only meaningful if skill is from registry.
|
||||
span.set_attribute(
|
||||
_adk_attributes.ADK_EXPERIMENTAL_SKILL_CACHE_HIT,
|
||||
skill_telemetry.cache_hit,
|
||||
)
|
||||
|
||||
span.set_attribute(
|
||||
_adk_attributes.ADK_EXPERIMENTAL_SKILL_ADDITIONAL_TOOLS,
|
||||
skill_telemetry.additional_tools,
|
||||
)
|
||||
|
||||
|
||||
@contextlib.asynccontextmanager
|
||||
async def record_agent_invocation(
|
||||
ctx: InvocationContext, agent: BaseAgent
|
||||
@@ -216,12 +357,19 @@ async def record_tool_execution(
|
||||
with tracing.tracer.start_as_current_span(span_name) as s:
|
||||
span = s
|
||||
tel_ctx = TelemetryContext(otel_context=context_api.get_current())
|
||||
# Published so the running tool can report telemetry back to this span
|
||||
# (see `record_skill_telemetry`) without reaching for the ambient span
|
||||
# itself.
|
||||
token = context_api.attach(
|
||||
context_api.set_value(_TOOL_EXECUTION_TELEMETRY_KEY, tel_ctx)
|
||||
)
|
||||
try:
|
||||
yield tel_ctx
|
||||
except Exception as e:
|
||||
caught_error = e
|
||||
raise
|
||||
finally:
|
||||
context_api.detach(token)
|
||||
detected_error_type = tel_ctx.error_type
|
||||
response_event = (
|
||||
tel_ctx.function_response_event if caught_error is None else None
|
||||
@@ -234,6 +382,12 @@ async def record_tool_execution(
|
||||
invocation_context=invocation_context,
|
||||
error_type=tel_ctx.error_type,
|
||||
)
|
||||
if (
|
||||
tel_ctx.skill_telemetry is not None
|
||||
and tel_ctx.skill_telemetry.span_type
|
||||
== SkillTelemetrySpanType.SKILL_LOAD
|
||||
):
|
||||
_trace_skill_load(span, tel_ctx.skill_telemetry, invocation_context)
|
||||
finally:
|
||||
_accumulate_invoke_agent_tool_call()
|
||||
try:
|
||||
|
||||
@@ -40,6 +40,7 @@ from ..code_executors.code_execution_utils import CodeExecutionInput
|
||||
from ..skills import models
|
||||
from ..skills import prompt
|
||||
from ..skills import SkillRegistry
|
||||
from ..telemetry import _instrumentation
|
||||
from ..utils import instructions_utils
|
||||
from .base_tool import BaseTool
|
||||
from .base_toolset import BaseToolset
|
||||
@@ -249,13 +250,18 @@ class LoadSkillTool(BaseTool):
|
||||
async def run_async(
|
||||
self, *, args: dict[str, Any], tool_context: ToolContext
|
||||
) -> Any:
|
||||
skill_name = args.get("skill_name")
|
||||
skill_name: str | None = args.get("skill_name")
|
||||
if not skill_name:
|
||||
return {
|
||||
"error": "Argument 'skill_name' is required.",
|
||||
"error_code": "INVALID_ARGUMENTS",
|
||||
}
|
||||
|
||||
skill_telemetry = _instrumentation.record_skill_telemetry(
|
||||
_instrumentation.SkillTelemetrySpanType.SKILL_LOAD
|
||||
)
|
||||
skill_telemetry.skill_name = skill_name
|
||||
|
||||
try:
|
||||
skill = await self._toolset._get_or_fetch_skill(
|
||||
skill_name, tool_context.invocation_id
|
||||
@@ -272,6 +278,11 @@ class LoadSkillTool(BaseTool):
|
||||
"error_code": "SKILL_NOT_FOUND",
|
||||
}
|
||||
|
||||
skill_telemetry.skill = skill
|
||||
skill_telemetry.additional_tools = skill.frontmatter.metadata.get(
|
||||
"adk_additional_tools", []
|
||||
)
|
||||
|
||||
# Record skill activation in agent state for tool resolution.
|
||||
agent_name = tool_context.agent_name
|
||||
state_key = f"_adk_activated_skill_{agent_name}"
|
||||
@@ -1349,6 +1360,8 @@ class SkillToolset(BaseToolset):
|
||||
turn_cache = self._fetched_skill_cache[invocation_id]
|
||||
if skill_name in turn_cache:
|
||||
cached = turn_cache[skill_name]
|
||||
_instrumentation.record_skill_cache_hit()
|
||||
|
||||
if isinstance(cached, asyncio.Future):
|
||||
return await cached
|
||||
return cached
|
||||
|
||||
@@ -21,6 +21,7 @@ the configuration to drive it under.
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from dataclasses import field
|
||||
from typing import Literal
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
@@ -31,8 +32,10 @@ import pytest
|
||||
from typing_extensions import assert_never
|
||||
|
||||
from ._digests import TelemetryDigest
|
||||
from ._scenarios import ADK_EXPERIMENTAL_TELEMETRY
|
||||
from ._scenarios import ADK_TELEMETRY_SCHEMA_VERSION_OPT_IN
|
||||
from ._scenarios import build_mcp_test_runner
|
||||
from ._scenarios import build_skill_test_runner
|
||||
from ._scenarios import build_test_runner
|
||||
from ._scenarios import CAPTURE_CONTENT
|
||||
from ._scenarios import FakeMcpSession
|
||||
@@ -41,6 +44,7 @@ from ._scenarios import OTEL_OPT_IN
|
||||
from ._scenarios import run_agent_scenario
|
||||
from ._scenarios import run_node_scenario
|
||||
from ._scenarios import Scenario
|
||||
from ._scenarios import SkillType
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from google.adk.events.event import Event
|
||||
@@ -67,6 +71,8 @@ class FunctionalTestCase:
|
||||
# When true, the tool raises instead of returning, and the scenario is
|
||||
# expected to propagate it (tool-failure telemetry path).
|
||||
tool_fails: bool = False
|
||||
experimental_telemetry: bool = False
|
||||
loaded_skills: list[SkillType] = field(default_factory=list)
|
||||
|
||||
@property
|
||||
def expects_failure(self) -> bool:
|
||||
@@ -99,6 +105,9 @@ class FunctionalTestCase:
|
||||
ADK_TELEMETRY_SCHEMA_VERSION_OPT_IN, str(self.schema_version)
|
||||
)
|
||||
monkeypatch.setenv("ADK_CAPTURE_MESSAGE_CONTENT_IN_SPANS", "false")
|
||||
monkeypatch.setenv(
|
||||
ADK_EXPERIMENTAL_TELEMETRY, str(self.experimental_telemetry).lower()
|
||||
)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -163,5 +172,8 @@ async def _run_scenario(
|
||||
build_mcp_test_runner(monkeypatch, FakeMcpSession())
|
||||
)
|
||||
return []
|
||||
elif case.scenario == "skill":
|
||||
await run_agent_scenario(build_skill_test_runner(skills=case.loaded_skills))
|
||||
return []
|
||||
else:
|
||||
assert_never(case.scenario)
|
||||
|
||||
@@ -24,17 +24,22 @@ from __future__ import annotations
|
||||
from contextlib import aclosing
|
||||
from typing import Literal
|
||||
from typing import NamedTuple
|
||||
from typing import Sequence
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from google.adk.agents.llm_agent import Agent
|
||||
from google.adk.models.llm_response import LlmResponse
|
||||
from google.adk.runners import InMemoryRunner
|
||||
from google.adk.skills.models import Frontmatter
|
||||
from google.adk.skills.models import Skill
|
||||
from google.adk.skills.skill_registry import SkillRegistry
|
||||
from google.adk.telemetry import _metrics
|
||||
from google.adk.telemetry import node_tracing
|
||||
from google.adk.telemetry import tracing
|
||||
from google.adk.tools.function_tool import FunctionTool
|
||||
from google.adk.tools.mcp_tool.mcp_session_manager import StdioConnectionParams
|
||||
from google.adk.tools.mcp_tool.mcp_toolset import McpToolset
|
||||
from google.adk.tools.skill_toolset import SkillToolset
|
||||
from google.adk.workflow._base_node import START
|
||||
from google.adk.workflow._workflow import Workflow
|
||||
from google.genai.types import Content
|
||||
@@ -71,6 +76,7 @@ OTEL_OPT_IN = "OTEL_SEMCONV_STABILITY_OPT_IN"
|
||||
CAPTURE_CONTENT = "OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT"
|
||||
EXPERIMENTAL_OPT_IN = "gen_ai_latest_experimental"
|
||||
ADK_TELEMETRY_SCHEMA_VERSION_OPT_IN = "ADK_TELEMETRY_SCHEMA_VERSION_OPT_IN"
|
||||
ADK_EXPERIMENTAL_TELEMETRY = "ADK_EXPERIMENTAL_TELEMETRY"
|
||||
|
||||
# Stable semconv event names.
|
||||
GEN_AI_SYSTEM_MESSAGE_EVENT = "gen_ai.system.message"
|
||||
@@ -81,7 +87,10 @@ GEN_AI_CHOICE_EVENT = "gen_ai.choice"
|
||||
GEN_AI_COMPLETION_DETAILS_EVENT = "gen_ai.client.inference.operation.details"
|
||||
|
||||
# Which end-to-end scenario a test case drives.
|
||||
Scenario = Literal["agent", "node", "mcp"]
|
||||
Scenario = Literal["agent", "node", "mcp", "skill"]
|
||||
|
||||
# The type of skill being used in a test case.
|
||||
SkillType = Literal["local", "registry", "nonexistent"]
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Telemetry plumbing.
|
||||
@@ -494,3 +503,95 @@ def build_mcp_test_runner(
|
||||
tools=[toolset],
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Skill telemetry scenario.
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
REGISTRY_SKILL_NAME = "registry-skill"
|
||||
LOCAL_SKILL_NAME = "local-skill"
|
||||
NONEXISTENT_SKILL_NAME = "nonexistent-skill"
|
||||
SKILL_DESCRIPTION = "A sample skill."
|
||||
|
||||
|
||||
def _make_skill(
|
||||
*,
|
||||
name: str = LOCAL_SKILL_NAME,
|
||||
source: str = "static",
|
||||
additional_tools: Sequence[str] | None = None,
|
||||
) -> Skill:
|
||||
additional_tools = additional_tools or []
|
||||
|
||||
skill = Skill(
|
||||
frontmatter=Frontmatter(
|
||||
name=name,
|
||||
description=SKILL_DESCRIPTION,
|
||||
metadata={"adk_additional_tools": additional_tools},
|
||||
),
|
||||
instructions="skill instructions",
|
||||
)
|
||||
if source == "registry":
|
||||
skill._uri = f"https://fake-registry.com/skill/{name}"
|
||||
else:
|
||||
skill._uri = f"file://{name}"
|
||||
return skill
|
||||
|
||||
|
||||
class _FakeSkillRegistry(SkillRegistry):
|
||||
"""Registry serving one in-memory skill, with no network of its own."""
|
||||
|
||||
def __init__(self, skill: Skill) -> None:
|
||||
self._skill = skill
|
||||
|
||||
@override
|
||||
async def get_skill(self, *, name: str) -> Skill:
|
||||
# A fresh copy per fetch: the toolset stamps `source` on what it gets back.
|
||||
if name == self._skill.frontmatter.name:
|
||||
return self._skill.model_copy(deep=True)
|
||||
else:
|
||||
raise KeyError(f"Skill {name} not found")
|
||||
|
||||
@override
|
||||
async def search_skills(self, *, query: str) -> list[Frontmatter]:
|
||||
return []
|
||||
|
||||
|
||||
def build_skill_test_runner(
|
||||
*, skills: Sequence[SkillType] | None = None
|
||||
) -> TestInMemoryRunner:
|
||||
"""Builds a runner whose model calls ``load_skill`` then answers."""
|
||||
skills = skills or []
|
||||
|
||||
part_map: dict[SkillType, Part] = {
|
||||
"local": Part.from_function_call(
|
||||
name="load_skill", args={"skill_name": LOCAL_SKILL_NAME}
|
||||
),
|
||||
"registry": Part.from_function_call(
|
||||
name="load_skill", args={"skill_name": REGISTRY_SKILL_NAME}
|
||||
),
|
||||
"nonexistent": Part.from_function_call(
|
||||
name="load_skill", args={"skill_name": NONEXISTENT_SKILL_NAME}
|
||||
),
|
||||
}
|
||||
|
||||
mock_model = MockModel.create(
|
||||
responses=[
|
||||
*(part_map[skill] for skill in skills),
|
||||
Part.from_text(text=FINAL_TEXT),
|
||||
]
|
||||
)
|
||||
registry = _FakeSkillRegistry(
|
||||
_make_skill(name=REGISTRY_SKILL_NAME, source="registry"),
|
||||
)
|
||||
toolset = SkillToolset(
|
||||
[_make_skill(additional_tools=["foo", "bar"])], registry=registry
|
||||
)
|
||||
test_agent = Agent(
|
||||
name=AGENT_NAME,
|
||||
description=AGENT_DESCRIPTION,
|
||||
instruction=BASE_INSTRUCTION,
|
||||
model=mock_model,
|
||||
tools=[toolset],
|
||||
)
|
||||
return TestInMemoryRunner(node=test_agent)
|
||||
|
||||
@@ -0,0 +1,245 @@
|
||||
{
|
||||
"root_span": {
|
||||
"name": "invoke_workflow some_root_agent",
|
||||
"attributes": {
|
||||
"gen_ai.operation.name": "invoke_workflow",
|
||||
"gen_ai.conversation.id": "PRESENT",
|
||||
"gen_ai.workflow.name": "some_root_agent"
|
||||
},
|
||||
"status": "UNSET",
|
||||
"children": [
|
||||
{
|
||||
"name": "invoke_agent some_root_agent",
|
||||
"attributes": {
|
||||
"gen_ai.operation.name": "invoke_agent",
|
||||
"gen_ai.agent.description": "A sample root agent.",
|
||||
"gen_ai.agent.name": "some_root_agent",
|
||||
"gen_ai.conversation.id": "PRESENT"
|
||||
},
|
||||
"status": "UNSET",
|
||||
"children": [
|
||||
{
|
||||
"name": "call_llm",
|
||||
"attributes": {
|
||||
"gen_ai.system": "gcp.vertex.agent",
|
||||
"gen_ai.request.model": "mock",
|
||||
"gcp.vertex.agent.invocation_id": "PRESENT",
|
||||
"gcp.vertex.agent.session_id": "PRESENT",
|
||||
"gcp.vertex.agent.event_id": "PRESENT",
|
||||
"gcp.vertex.agent.llm_request": "{}",
|
||||
"gcp.vertex.agent.llm_response": "{}"
|
||||
},
|
||||
"status": "UNSET",
|
||||
"children": [
|
||||
{
|
||||
"name": "generate_content mock",
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini",
|
||||
"gen_ai.operation.name": "generate_content",
|
||||
"gen_ai.request.model": "mock",
|
||||
"gen_ai.agent.name": "some_root_agent",
|
||||
"gen_ai.conversation.id": "PRESENT",
|
||||
"gcp.vertex.agent.event_id": "PRESENT",
|
||||
"gcp.vertex.agent.invocation_id": "PRESENT"
|
||||
},
|
||||
"status": "UNSET",
|
||||
"children": [
|
||||
{
|
||||
"name": "execute_tool load_skill",
|
||||
"attributes": {
|
||||
"gen_ai.operation.name": "execute_tool",
|
||||
"gen_ai.tool.description": "Loads the SKILL.md instructions for a given skill.",
|
||||
"gen_ai.tool.name": "load_skill",
|
||||
"gen_ai.tool.type": "LoadSkillTool",
|
||||
"gen_ai.agent.name": "some_root_agent",
|
||||
"error.type": "REGISTRY_ERROR",
|
||||
"gcp.vertex.agent.llm_request": "{}",
|
||||
"gcp.vertex.agent.llm_response": "{}",
|
||||
"gcp.vertex.agent.tool_call_args": "{}",
|
||||
"gen_ai.tool.call.id": "PRESENT",
|
||||
"gcp.vertex.agent.event_id": "PRESENT",
|
||||
"gcp.vertex.agent.tool_response": "{}",
|
||||
"adk.experimental.skill.name": "nonexistent-skill"
|
||||
},
|
||||
"status": "ERROR",
|
||||
"children": [],
|
||||
"logs": []
|
||||
}
|
||||
],
|
||||
"logs": [
|
||||
{
|
||||
"event_name": "gen_ai.choice",
|
||||
"body": {
|
||||
"content": "<elided>",
|
||||
"index": 0
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
},
|
||||
{
|
||||
"event_name": "gen_ai.system.message",
|
||||
"body": {
|
||||
"content": "<elided>"
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
},
|
||||
{
|
||||
"event_name": "gen_ai.user.message",
|
||||
"body": {
|
||||
"content": "<elided>"
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"logs": []
|
||||
},
|
||||
{
|
||||
"name": "call_llm",
|
||||
"attributes": {
|
||||
"gen_ai.system": "gcp.vertex.agent",
|
||||
"gen_ai.request.model": "mock",
|
||||
"gcp.vertex.agent.invocation_id": "PRESENT",
|
||||
"gcp.vertex.agent.session_id": "PRESENT",
|
||||
"gcp.vertex.agent.event_id": "PRESENT",
|
||||
"gcp.vertex.agent.llm_request": "{}",
|
||||
"gcp.vertex.agent.llm_response": "{}"
|
||||
},
|
||||
"status": "UNSET",
|
||||
"children": [
|
||||
{
|
||||
"name": "generate_content mock",
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini",
|
||||
"gen_ai.operation.name": "generate_content",
|
||||
"gen_ai.request.model": "mock",
|
||||
"gen_ai.agent.name": "some_root_agent",
|
||||
"gen_ai.conversation.id": "PRESENT",
|
||||
"gcp.vertex.agent.event_id": "PRESENT",
|
||||
"gcp.vertex.agent.invocation_id": "PRESENT"
|
||||
},
|
||||
"status": "UNSET",
|
||||
"children": [],
|
||||
"logs": [
|
||||
{
|
||||
"event_name": "gen_ai.choice",
|
||||
"body": {
|
||||
"content": "<elided>",
|
||||
"index": 0
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
},
|
||||
{
|
||||
"event_name": "gen_ai.system.message",
|
||||
"body": {
|
||||
"content": "<elided>"
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
},
|
||||
{
|
||||
"event_name": "gen_ai.user.message",
|
||||
"body": {
|
||||
"content": "<elided>"
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
},
|
||||
{
|
||||
"event_name": "gen_ai.user.message",
|
||||
"body": {
|
||||
"content": "<elided>"
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
},
|
||||
{
|
||||
"event_name": "gen_ai.user.message",
|
||||
"body": {
|
||||
"content": "<elided>"
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"logs": []
|
||||
}
|
||||
],
|
||||
"logs": []
|
||||
}
|
||||
],
|
||||
"logs": []
|
||||
},
|
||||
"metric_points": {
|
||||
"gen_ai.client.operation.duration": [
|
||||
{
|
||||
"attributes": {
|
||||
"gen_ai.agent.name": "some_root_agent",
|
||||
"gen_ai.operation.name": "generate_content",
|
||||
"gen_ai.provider.name": "gemini",
|
||||
"gen_ai.request.model": "mock",
|
||||
"gen_ai.response.model": "mock"
|
||||
},
|
||||
"value": "PRESENT"
|
||||
}
|
||||
],
|
||||
"gen_ai.execute_tool.duration": [
|
||||
{
|
||||
"attributes": {
|
||||
"gen_ai.agent.name": "some_root_agent",
|
||||
"gen_ai.tool.name": "load_skill",
|
||||
"gen_ai.tool.type": "LoadSkillTool",
|
||||
"error.type": "REGISTRY_ERROR"
|
||||
},
|
||||
"value": "PRESENT"
|
||||
}
|
||||
],
|
||||
"gen_ai.invoke_agent.duration": [
|
||||
{
|
||||
"attributes": {
|
||||
"gen_ai.agent.name": "some_root_agent"
|
||||
},
|
||||
"value": "PRESENT"
|
||||
}
|
||||
],
|
||||
"gen_ai.invoke_agent.inference_calls": [
|
||||
{
|
||||
"attributes": {
|
||||
"gen_ai.agent.name": "some_root_agent"
|
||||
},
|
||||
"value": 2
|
||||
}
|
||||
],
|
||||
"gen_ai.invoke_agent.tool_calls": [
|
||||
{
|
||||
"attributes": {
|
||||
"gen_ai.agent.name": "some_root_agent"
|
||||
},
|
||||
"value": 1
|
||||
}
|
||||
],
|
||||
"gen_ai.invoke_workflow.duration": [
|
||||
{
|
||||
"attributes": {
|
||||
"gen_ai.operation.name": "invoke_workflow",
|
||||
"gen_ai.workflow.name": "some_root_agent"
|
||||
},
|
||||
"value": "PRESENT"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
+368
@@ -0,0 +1,368 @@
|
||||
{
|
||||
"root_span": {
|
||||
"name": "invoke_workflow some_root_agent",
|
||||
"attributes": {
|
||||
"gen_ai.operation.name": "invoke_workflow",
|
||||
"gen_ai.conversation.id": "PRESENT",
|
||||
"gen_ai.workflow.name": "some_root_agent"
|
||||
},
|
||||
"status": "UNSET",
|
||||
"children": [
|
||||
{
|
||||
"name": "invoke_agent some_root_agent",
|
||||
"attributes": {
|
||||
"gen_ai.operation.name": "invoke_agent",
|
||||
"gen_ai.agent.description": "A sample root agent.",
|
||||
"gen_ai.agent.name": "some_root_agent",
|
||||
"gen_ai.conversation.id": "PRESENT"
|
||||
},
|
||||
"status": "UNSET",
|
||||
"children": [
|
||||
{
|
||||
"name": "call_llm",
|
||||
"attributes": {
|
||||
"gen_ai.system": "gcp.vertex.agent",
|
||||
"gen_ai.request.model": "mock",
|
||||
"gcp.vertex.agent.invocation_id": "PRESENT",
|
||||
"gcp.vertex.agent.session_id": "PRESENT",
|
||||
"gcp.vertex.agent.event_id": "PRESENT",
|
||||
"gcp.vertex.agent.llm_request": "{}",
|
||||
"gcp.vertex.agent.llm_response": "{}"
|
||||
},
|
||||
"status": "UNSET",
|
||||
"children": [
|
||||
{
|
||||
"name": "generate_content mock",
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini",
|
||||
"gen_ai.operation.name": "generate_content",
|
||||
"gen_ai.request.model": "mock",
|
||||
"gen_ai.agent.name": "some_root_agent",
|
||||
"gen_ai.conversation.id": "PRESENT",
|
||||
"gcp.vertex.agent.event_id": "PRESENT",
|
||||
"gcp.vertex.agent.invocation_id": "PRESENT"
|
||||
},
|
||||
"status": "UNSET",
|
||||
"children": [
|
||||
{
|
||||
"name": "execute_tool load_skill",
|
||||
"attributes": {
|
||||
"gen_ai.operation.name": "execute_tool",
|
||||
"gen_ai.tool.description": "Loads the SKILL.md instructions for a given skill.",
|
||||
"gen_ai.tool.name": "load_skill",
|
||||
"gen_ai.tool.type": "LoadSkillTool",
|
||||
"gen_ai.agent.name": "some_root_agent",
|
||||
"gcp.vertex.agent.llm_request": "{}",
|
||||
"gcp.vertex.agent.llm_response": "{}",
|
||||
"gcp.vertex.agent.tool_call_args": "{}",
|
||||
"gen_ai.tool.call.id": "PRESENT",
|
||||
"gcp.vertex.agent.event_id": "PRESENT",
|
||||
"gcp.vertex.agent.tool_response": "{}",
|
||||
"adk.experimental.skill.name": "registry-skill",
|
||||
"adk.experimental.skill.description": "A sample skill.",
|
||||
"adk.experimental.skill.source.uri": "https://fake-registry.com/skill/registry-skill",
|
||||
"adk.experimental.skill.cache_hit": false,
|
||||
"adk.experimental.skill.additional_tools": []
|
||||
},
|
||||
"status": "UNSET",
|
||||
"children": [],
|
||||
"logs": []
|
||||
}
|
||||
],
|
||||
"logs": [
|
||||
{
|
||||
"event_name": "gen_ai.choice",
|
||||
"body": {
|
||||
"content": "<elided>",
|
||||
"index": 0
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
},
|
||||
{
|
||||
"event_name": "gen_ai.system.message",
|
||||
"body": {
|
||||
"content": "<elided>"
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
},
|
||||
{
|
||||
"event_name": "gen_ai.user.message",
|
||||
"body": {
|
||||
"content": "<elided>"
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"logs": []
|
||||
},
|
||||
{
|
||||
"name": "call_llm",
|
||||
"attributes": {
|
||||
"gen_ai.system": "gcp.vertex.agent",
|
||||
"gen_ai.request.model": "mock",
|
||||
"gcp.vertex.agent.invocation_id": "PRESENT",
|
||||
"gcp.vertex.agent.session_id": "PRESENT",
|
||||
"gcp.vertex.agent.event_id": "PRESENT",
|
||||
"gcp.vertex.agent.llm_request": "{}",
|
||||
"gcp.vertex.agent.llm_response": "{}"
|
||||
},
|
||||
"status": "UNSET",
|
||||
"children": [
|
||||
{
|
||||
"name": "generate_content mock",
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini",
|
||||
"gen_ai.operation.name": "generate_content",
|
||||
"gen_ai.request.model": "mock",
|
||||
"gen_ai.agent.name": "some_root_agent",
|
||||
"gen_ai.conversation.id": "PRESENT",
|
||||
"gcp.vertex.agent.event_id": "PRESENT",
|
||||
"gcp.vertex.agent.invocation_id": "PRESENT"
|
||||
},
|
||||
"status": "UNSET",
|
||||
"children": [
|
||||
{
|
||||
"name": "execute_tool load_skill",
|
||||
"attributes": {
|
||||
"gen_ai.operation.name": "execute_tool",
|
||||
"gen_ai.tool.description": "Loads the SKILL.md instructions for a given skill.",
|
||||
"gen_ai.tool.name": "load_skill",
|
||||
"gen_ai.tool.type": "LoadSkillTool",
|
||||
"gen_ai.agent.name": "some_root_agent",
|
||||
"gcp.vertex.agent.llm_request": "{}",
|
||||
"gcp.vertex.agent.llm_response": "{}",
|
||||
"gcp.vertex.agent.tool_call_args": "{}",
|
||||
"gen_ai.tool.call.id": "PRESENT",
|
||||
"gcp.vertex.agent.event_id": "PRESENT",
|
||||
"gcp.vertex.agent.tool_response": "{}",
|
||||
"adk.experimental.skill.name": "registry-skill",
|
||||
"adk.experimental.skill.description": "A sample skill.",
|
||||
"adk.experimental.skill.source.uri": "https://fake-registry.com/skill/registry-skill",
|
||||
"adk.experimental.skill.cache_hit": true,
|
||||
"adk.experimental.skill.additional_tools": []
|
||||
},
|
||||
"status": "UNSET",
|
||||
"children": [],
|
||||
"logs": []
|
||||
}
|
||||
],
|
||||
"logs": [
|
||||
{
|
||||
"event_name": "gen_ai.choice",
|
||||
"body": {
|
||||
"content": "<elided>",
|
||||
"index": 0
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
},
|
||||
{
|
||||
"event_name": "gen_ai.system.message",
|
||||
"body": {
|
||||
"content": "<elided>"
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
},
|
||||
{
|
||||
"event_name": "gen_ai.user.message",
|
||||
"body": {
|
||||
"content": "<elided>"
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
},
|
||||
{
|
||||
"event_name": "gen_ai.user.message",
|
||||
"body": {
|
||||
"content": "<elided>"
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
},
|
||||
{
|
||||
"event_name": "gen_ai.user.message",
|
||||
"body": {
|
||||
"content": "<elided>"
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"logs": []
|
||||
},
|
||||
{
|
||||
"name": "call_llm",
|
||||
"attributes": {
|
||||
"gen_ai.system": "gcp.vertex.agent",
|
||||
"gen_ai.request.model": "mock",
|
||||
"gcp.vertex.agent.invocation_id": "PRESENT",
|
||||
"gcp.vertex.agent.session_id": "PRESENT",
|
||||
"gcp.vertex.agent.event_id": "PRESENT",
|
||||
"gcp.vertex.agent.llm_request": "{}",
|
||||
"gcp.vertex.agent.llm_response": "{}"
|
||||
},
|
||||
"status": "UNSET",
|
||||
"children": [
|
||||
{
|
||||
"name": "generate_content mock",
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini",
|
||||
"gen_ai.operation.name": "generate_content",
|
||||
"gen_ai.request.model": "mock",
|
||||
"gen_ai.agent.name": "some_root_agent",
|
||||
"gen_ai.conversation.id": "PRESENT",
|
||||
"gcp.vertex.agent.event_id": "PRESENT",
|
||||
"gcp.vertex.agent.invocation_id": "PRESENT"
|
||||
},
|
||||
"status": "UNSET",
|
||||
"children": [],
|
||||
"logs": [
|
||||
{
|
||||
"event_name": "gen_ai.choice",
|
||||
"body": {
|
||||
"content": "<elided>",
|
||||
"index": 0
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
},
|
||||
{
|
||||
"event_name": "gen_ai.system.message",
|
||||
"body": {
|
||||
"content": "<elided>"
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
},
|
||||
{
|
||||
"event_name": "gen_ai.user.message",
|
||||
"body": {
|
||||
"content": "<elided>"
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
},
|
||||
{
|
||||
"event_name": "gen_ai.user.message",
|
||||
"body": {
|
||||
"content": "<elided>"
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
},
|
||||
{
|
||||
"event_name": "gen_ai.user.message",
|
||||
"body": {
|
||||
"content": "<elided>"
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
},
|
||||
{
|
||||
"event_name": "gen_ai.user.message",
|
||||
"body": {
|
||||
"content": "<elided>"
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
},
|
||||
{
|
||||
"event_name": "gen_ai.user.message",
|
||||
"body": {
|
||||
"content": "<elided>"
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"logs": []
|
||||
}
|
||||
],
|
||||
"logs": []
|
||||
}
|
||||
],
|
||||
"logs": []
|
||||
},
|
||||
"metric_points": {
|
||||
"gen_ai.client.operation.duration": [
|
||||
{
|
||||
"attributes": {
|
||||
"gen_ai.agent.name": "some_root_agent",
|
||||
"gen_ai.operation.name": "generate_content",
|
||||
"gen_ai.provider.name": "gemini",
|
||||
"gen_ai.request.model": "mock",
|
||||
"gen_ai.response.model": "mock"
|
||||
},
|
||||
"value": "PRESENT"
|
||||
}
|
||||
],
|
||||
"gen_ai.execute_tool.duration": [
|
||||
{
|
||||
"attributes": {
|
||||
"gen_ai.agent.name": "some_root_agent",
|
||||
"gen_ai.tool.name": "load_skill",
|
||||
"gen_ai.tool.type": "LoadSkillTool"
|
||||
},
|
||||
"value": "PRESENT"
|
||||
}
|
||||
],
|
||||
"gen_ai.invoke_agent.duration": [
|
||||
{
|
||||
"attributes": {
|
||||
"gen_ai.agent.name": "some_root_agent"
|
||||
},
|
||||
"value": "PRESENT"
|
||||
}
|
||||
],
|
||||
"gen_ai.invoke_agent.inference_calls": [
|
||||
{
|
||||
"attributes": {
|
||||
"gen_ai.agent.name": "some_root_agent"
|
||||
},
|
||||
"value": 3
|
||||
}
|
||||
],
|
||||
"gen_ai.invoke_agent.tool_calls": [
|
||||
{
|
||||
"attributes": {
|
||||
"gen_ai.agent.name": "some_root_agent"
|
||||
},
|
||||
"value": 2
|
||||
}
|
||||
],
|
||||
"gen_ai.invoke_workflow.duration": [
|
||||
{
|
||||
"attributes": {
|
||||
"gen_ai.operation.name": "invoke_workflow",
|
||||
"gen_ai.workflow.name": "some_root_agent"
|
||||
},
|
||||
"value": "PRESENT"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
+345
@@ -0,0 +1,345 @@
|
||||
{
|
||||
"root_span": {
|
||||
"name": "invocation",
|
||||
"attributes": {},
|
||||
"status": "UNSET",
|
||||
"children": [
|
||||
{
|
||||
"name": "invoke_agent some_root_agent",
|
||||
"attributes": {
|
||||
"gen_ai.operation.name": "invoke_agent",
|
||||
"gen_ai.agent.description": "A sample root agent.",
|
||||
"gen_ai.agent.name": "some_root_agent",
|
||||
"gen_ai.conversation.id": "PRESENT"
|
||||
},
|
||||
"status": "UNSET",
|
||||
"children": [
|
||||
{
|
||||
"name": "call_llm",
|
||||
"attributes": {
|
||||
"gen_ai.system": "gcp.vertex.agent",
|
||||
"gen_ai.request.model": "mock",
|
||||
"gcp.vertex.agent.invocation_id": "PRESENT",
|
||||
"gcp.vertex.agent.session_id": "PRESENT",
|
||||
"gcp.vertex.agent.event_id": "PRESENT",
|
||||
"gcp.vertex.agent.llm_request": "{}",
|
||||
"gcp.vertex.agent.llm_response": "{}"
|
||||
},
|
||||
"status": "UNSET",
|
||||
"children": [
|
||||
{
|
||||
"name": "generate_content mock",
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini",
|
||||
"gen_ai.operation.name": "generate_content",
|
||||
"gen_ai.request.model": "mock",
|
||||
"gen_ai.agent.name": "some_root_agent",
|
||||
"gen_ai.conversation.id": "PRESENT",
|
||||
"gcp.vertex.agent.event_id": "PRESENT",
|
||||
"gcp.vertex.agent.invocation_id": "PRESENT"
|
||||
},
|
||||
"status": "UNSET",
|
||||
"children": [
|
||||
{
|
||||
"name": "execute_tool load_skill",
|
||||
"attributes": {
|
||||
"gen_ai.operation.name": "execute_tool",
|
||||
"gen_ai.tool.description": "Loads the SKILL.md instructions for a given skill.",
|
||||
"gen_ai.tool.name": "load_skill",
|
||||
"gen_ai.tool.type": "LoadSkillTool",
|
||||
"gen_ai.agent.name": "some_root_agent",
|
||||
"gcp.vertex.agent.llm_request": "{}",
|
||||
"gcp.vertex.agent.llm_response": "{}",
|
||||
"gcp.vertex.agent.tool_call_args": "{}",
|
||||
"gen_ai.tool.call.id": "PRESENT",
|
||||
"gcp.vertex.agent.event_id": "PRESENT",
|
||||
"gcp.vertex.agent.tool_response": "{}"
|
||||
},
|
||||
"status": "UNSET",
|
||||
"children": [],
|
||||
"logs": []
|
||||
}
|
||||
],
|
||||
"logs": [
|
||||
{
|
||||
"event_name": "gen_ai.choice",
|
||||
"body": {
|
||||
"content": "<elided>",
|
||||
"index": 0
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
},
|
||||
{
|
||||
"event_name": "gen_ai.system.message",
|
||||
"body": {
|
||||
"content": "<elided>"
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
},
|
||||
{
|
||||
"event_name": "gen_ai.user.message",
|
||||
"body": {
|
||||
"content": "<elided>"
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"logs": []
|
||||
},
|
||||
{
|
||||
"name": "call_llm",
|
||||
"attributes": {
|
||||
"gen_ai.system": "gcp.vertex.agent",
|
||||
"gen_ai.request.model": "mock",
|
||||
"gcp.vertex.agent.invocation_id": "PRESENT",
|
||||
"gcp.vertex.agent.session_id": "PRESENT",
|
||||
"gcp.vertex.agent.event_id": "PRESENT",
|
||||
"gcp.vertex.agent.llm_request": "{}",
|
||||
"gcp.vertex.agent.llm_response": "{}"
|
||||
},
|
||||
"status": "UNSET",
|
||||
"children": [
|
||||
{
|
||||
"name": "generate_content mock",
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini",
|
||||
"gen_ai.operation.name": "generate_content",
|
||||
"gen_ai.request.model": "mock",
|
||||
"gen_ai.agent.name": "some_root_agent",
|
||||
"gen_ai.conversation.id": "PRESENT",
|
||||
"gcp.vertex.agent.event_id": "PRESENT",
|
||||
"gcp.vertex.agent.invocation_id": "PRESENT"
|
||||
},
|
||||
"status": "UNSET",
|
||||
"children": [
|
||||
{
|
||||
"name": "execute_tool load_skill",
|
||||
"attributes": {
|
||||
"gen_ai.operation.name": "execute_tool",
|
||||
"gen_ai.tool.description": "Loads the SKILL.md instructions for a given skill.",
|
||||
"gen_ai.tool.name": "load_skill",
|
||||
"gen_ai.tool.type": "LoadSkillTool",
|
||||
"gen_ai.agent.name": "some_root_agent",
|
||||
"gcp.vertex.agent.llm_request": "{}",
|
||||
"gcp.vertex.agent.llm_response": "{}",
|
||||
"gcp.vertex.agent.tool_call_args": "{}",
|
||||
"gen_ai.tool.call.id": "PRESENT",
|
||||
"gcp.vertex.agent.event_id": "PRESENT",
|
||||
"gcp.vertex.agent.tool_response": "{}"
|
||||
},
|
||||
"status": "UNSET",
|
||||
"children": [],
|
||||
"logs": []
|
||||
}
|
||||
],
|
||||
"logs": [
|
||||
{
|
||||
"event_name": "gen_ai.choice",
|
||||
"body": {
|
||||
"content": "<elided>",
|
||||
"index": 0
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
},
|
||||
{
|
||||
"event_name": "gen_ai.system.message",
|
||||
"body": {
|
||||
"content": "<elided>"
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
},
|
||||
{
|
||||
"event_name": "gen_ai.user.message",
|
||||
"body": {
|
||||
"content": "<elided>"
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
},
|
||||
{
|
||||
"event_name": "gen_ai.user.message",
|
||||
"body": {
|
||||
"content": "<elided>"
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
},
|
||||
{
|
||||
"event_name": "gen_ai.user.message",
|
||||
"body": {
|
||||
"content": "<elided>"
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"logs": []
|
||||
},
|
||||
{
|
||||
"name": "call_llm",
|
||||
"attributes": {
|
||||
"gen_ai.system": "gcp.vertex.agent",
|
||||
"gen_ai.request.model": "mock",
|
||||
"gcp.vertex.agent.invocation_id": "PRESENT",
|
||||
"gcp.vertex.agent.session_id": "PRESENT",
|
||||
"gcp.vertex.agent.event_id": "PRESENT",
|
||||
"gcp.vertex.agent.llm_request": "{}",
|
||||
"gcp.vertex.agent.llm_response": "{}"
|
||||
},
|
||||
"status": "UNSET",
|
||||
"children": [
|
||||
{
|
||||
"name": "generate_content mock",
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini",
|
||||
"gen_ai.operation.name": "generate_content",
|
||||
"gen_ai.request.model": "mock",
|
||||
"gen_ai.agent.name": "some_root_agent",
|
||||
"gen_ai.conversation.id": "PRESENT",
|
||||
"gcp.vertex.agent.event_id": "PRESENT",
|
||||
"gcp.vertex.agent.invocation_id": "PRESENT"
|
||||
},
|
||||
"status": "UNSET",
|
||||
"children": [],
|
||||
"logs": [
|
||||
{
|
||||
"event_name": "gen_ai.choice",
|
||||
"body": {
|
||||
"content": "<elided>",
|
||||
"index": 0
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
},
|
||||
{
|
||||
"event_name": "gen_ai.system.message",
|
||||
"body": {
|
||||
"content": "<elided>"
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
},
|
||||
{
|
||||
"event_name": "gen_ai.user.message",
|
||||
"body": {
|
||||
"content": "<elided>"
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
},
|
||||
{
|
||||
"event_name": "gen_ai.user.message",
|
||||
"body": {
|
||||
"content": "<elided>"
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
},
|
||||
{
|
||||
"event_name": "gen_ai.user.message",
|
||||
"body": {
|
||||
"content": "<elided>"
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
},
|
||||
{
|
||||
"event_name": "gen_ai.user.message",
|
||||
"body": {
|
||||
"content": "<elided>"
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
},
|
||||
{
|
||||
"event_name": "gen_ai.user.message",
|
||||
"body": {
|
||||
"content": "<elided>"
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"logs": []
|
||||
}
|
||||
],
|
||||
"logs": []
|
||||
}
|
||||
],
|
||||
"logs": []
|
||||
},
|
||||
"metric_points": {
|
||||
"gen_ai.client.operation.duration": [
|
||||
{
|
||||
"attributes": {
|
||||
"gen_ai.agent.name": "some_root_agent",
|
||||
"gen_ai.operation.name": "generate_content",
|
||||
"gen_ai.provider.name": "gemini",
|
||||
"gen_ai.request.model": "mock",
|
||||
"gen_ai.response.model": "mock"
|
||||
},
|
||||
"value": "PRESENT"
|
||||
}
|
||||
],
|
||||
"gen_ai.execute_tool.duration": [
|
||||
{
|
||||
"attributes": {
|
||||
"gen_ai.agent.name": "some_root_agent",
|
||||
"gen_ai.tool.name": "load_skill",
|
||||
"gen_ai.tool.type": "LoadSkillTool"
|
||||
},
|
||||
"value": "PRESENT"
|
||||
}
|
||||
],
|
||||
"gen_ai.invoke_agent.duration": [
|
||||
{
|
||||
"attributes": {
|
||||
"gen_ai.agent.name": "some_root_agent"
|
||||
},
|
||||
"value": "PRESENT"
|
||||
}
|
||||
],
|
||||
"gen_ai.invoke_agent.inference_calls": [
|
||||
{
|
||||
"attributes": {
|
||||
"gen_ai.agent.name": "some_root_agent"
|
||||
},
|
||||
"value": 3
|
||||
}
|
||||
],
|
||||
"gen_ai.invoke_agent.tool_calls": [
|
||||
{
|
||||
"attributes": {
|
||||
"gen_ai.agent.name": "some_root_agent"
|
||||
},
|
||||
"value": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,236 @@
|
||||
{
|
||||
"root_span": {
|
||||
"name": "invocation",
|
||||
"attributes": {},
|
||||
"status": "UNSET",
|
||||
"children": [
|
||||
{
|
||||
"name": "invoke_agent some_root_agent",
|
||||
"attributes": {
|
||||
"gen_ai.operation.name": "invoke_agent",
|
||||
"gen_ai.agent.description": "A sample root agent.",
|
||||
"gen_ai.agent.name": "some_root_agent",
|
||||
"gen_ai.conversation.id": "PRESENT"
|
||||
},
|
||||
"status": "UNSET",
|
||||
"children": [
|
||||
{
|
||||
"name": "call_llm",
|
||||
"attributes": {
|
||||
"gen_ai.system": "gcp.vertex.agent",
|
||||
"gen_ai.request.model": "mock",
|
||||
"gcp.vertex.agent.invocation_id": "PRESENT",
|
||||
"gcp.vertex.agent.session_id": "PRESENT",
|
||||
"gcp.vertex.agent.event_id": "PRESENT",
|
||||
"gcp.vertex.agent.llm_request": "{}",
|
||||
"gcp.vertex.agent.llm_response": "{}"
|
||||
},
|
||||
"status": "UNSET",
|
||||
"children": [
|
||||
{
|
||||
"name": "generate_content mock",
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini",
|
||||
"gen_ai.operation.name": "generate_content",
|
||||
"gen_ai.request.model": "mock",
|
||||
"gen_ai.agent.name": "some_root_agent",
|
||||
"gen_ai.conversation.id": "PRESENT",
|
||||
"gcp.vertex.agent.event_id": "PRESENT",
|
||||
"gcp.vertex.agent.invocation_id": "PRESENT"
|
||||
},
|
||||
"status": "UNSET",
|
||||
"children": [
|
||||
{
|
||||
"name": "execute_tool load_skill",
|
||||
"attributes": {
|
||||
"gen_ai.operation.name": "execute_tool",
|
||||
"gen_ai.tool.description": "Loads the SKILL.md instructions for a given skill.",
|
||||
"gen_ai.tool.name": "load_skill",
|
||||
"gen_ai.tool.type": "LoadSkillTool",
|
||||
"gen_ai.agent.name": "some_root_agent",
|
||||
"gcp.vertex.agent.llm_request": "{}",
|
||||
"gcp.vertex.agent.llm_response": "{}",
|
||||
"gcp.vertex.agent.tool_call_args": "{}",
|
||||
"gen_ai.tool.call.id": "PRESENT",
|
||||
"gcp.vertex.agent.event_id": "PRESENT",
|
||||
"gcp.vertex.agent.tool_response": "{}",
|
||||
"adk.experimental.skill.name": "local-skill",
|
||||
"adk.experimental.skill.description": "A sample skill.",
|
||||
"adk.experimental.skill.source.uri": "file://local-skill",
|
||||
"adk.experimental.skill.additional_tools": [
|
||||
"foo",
|
||||
"bar"
|
||||
]
|
||||
},
|
||||
"status": "UNSET",
|
||||
"children": [],
|
||||
"logs": []
|
||||
}
|
||||
],
|
||||
"logs": [
|
||||
{
|
||||
"event_name": "gen_ai.choice",
|
||||
"body": {
|
||||
"content": "<elided>",
|
||||
"index": 0
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
},
|
||||
{
|
||||
"event_name": "gen_ai.system.message",
|
||||
"body": {
|
||||
"content": "<elided>"
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
},
|
||||
{
|
||||
"event_name": "gen_ai.user.message",
|
||||
"body": {
|
||||
"content": "<elided>"
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"logs": []
|
||||
},
|
||||
{
|
||||
"name": "call_llm",
|
||||
"attributes": {
|
||||
"gen_ai.system": "gcp.vertex.agent",
|
||||
"gen_ai.request.model": "mock",
|
||||
"gcp.vertex.agent.invocation_id": "PRESENT",
|
||||
"gcp.vertex.agent.session_id": "PRESENT",
|
||||
"gcp.vertex.agent.event_id": "PRESENT",
|
||||
"gcp.vertex.agent.llm_request": "{}",
|
||||
"gcp.vertex.agent.llm_response": "{}"
|
||||
},
|
||||
"status": "UNSET",
|
||||
"children": [
|
||||
{
|
||||
"name": "generate_content mock",
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini",
|
||||
"gen_ai.operation.name": "generate_content",
|
||||
"gen_ai.request.model": "mock",
|
||||
"gen_ai.agent.name": "some_root_agent",
|
||||
"gen_ai.conversation.id": "PRESENT",
|
||||
"gcp.vertex.agent.event_id": "PRESENT",
|
||||
"gcp.vertex.agent.invocation_id": "PRESENT"
|
||||
},
|
||||
"status": "UNSET",
|
||||
"children": [],
|
||||
"logs": [
|
||||
{
|
||||
"event_name": "gen_ai.choice",
|
||||
"body": {
|
||||
"content": "<elided>",
|
||||
"index": 0
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
},
|
||||
{
|
||||
"event_name": "gen_ai.system.message",
|
||||
"body": {
|
||||
"content": "<elided>"
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
},
|
||||
{
|
||||
"event_name": "gen_ai.user.message",
|
||||
"body": {
|
||||
"content": "<elided>"
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
},
|
||||
{
|
||||
"event_name": "gen_ai.user.message",
|
||||
"body": {
|
||||
"content": "<elided>"
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
},
|
||||
{
|
||||
"event_name": "gen_ai.user.message",
|
||||
"body": {
|
||||
"content": "<elided>"
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"logs": []
|
||||
}
|
||||
],
|
||||
"logs": []
|
||||
}
|
||||
],
|
||||
"logs": []
|
||||
},
|
||||
"metric_points": {
|
||||
"gen_ai.client.operation.duration": [
|
||||
{
|
||||
"attributes": {
|
||||
"gen_ai.agent.name": "some_root_agent",
|
||||
"gen_ai.operation.name": "generate_content",
|
||||
"gen_ai.provider.name": "gemini",
|
||||
"gen_ai.request.model": "mock",
|
||||
"gen_ai.response.model": "mock"
|
||||
},
|
||||
"value": "PRESENT"
|
||||
}
|
||||
],
|
||||
"gen_ai.execute_tool.duration": [
|
||||
{
|
||||
"attributes": {
|
||||
"gen_ai.agent.name": "some_root_agent",
|
||||
"gen_ai.tool.name": "load_skill",
|
||||
"gen_ai.tool.type": "LoadSkillTool"
|
||||
},
|
||||
"value": "PRESENT"
|
||||
}
|
||||
],
|
||||
"gen_ai.invoke_agent.duration": [
|
||||
{
|
||||
"attributes": {
|
||||
"gen_ai.agent.name": "some_root_agent"
|
||||
},
|
||||
"value": "PRESENT"
|
||||
}
|
||||
],
|
||||
"gen_ai.invoke_agent.inference_calls": [
|
||||
{
|
||||
"attributes": {
|
||||
"gen_ai.agent.name": "some_root_agent"
|
||||
},
|
||||
"value": 2
|
||||
}
|
||||
],
|
||||
"gen_ai.invoke_agent.tool_calls": [
|
||||
{
|
||||
"attributes": {
|
||||
"gen_ai.agent.name": "some_root_agent"
|
||||
},
|
||||
"value": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,249 @@
|
||||
{
|
||||
"root_span": {
|
||||
"name": "invoke_workflow some_root_agent",
|
||||
"attributes": {
|
||||
"gen_ai.operation.name": "invoke_workflow",
|
||||
"gen_ai.conversation.id": "PRESENT",
|
||||
"gen_ai.workflow.name": "some_root_agent"
|
||||
},
|
||||
"status": "UNSET",
|
||||
"children": [
|
||||
{
|
||||
"name": "invoke_agent some_root_agent",
|
||||
"attributes": {
|
||||
"gen_ai.operation.name": "invoke_agent",
|
||||
"gen_ai.agent.description": "A sample root agent.",
|
||||
"gen_ai.agent.name": "some_root_agent",
|
||||
"gen_ai.conversation.id": "PRESENT"
|
||||
},
|
||||
"status": "UNSET",
|
||||
"children": [
|
||||
{
|
||||
"name": "call_llm",
|
||||
"attributes": {
|
||||
"gen_ai.system": "gcp.vertex.agent",
|
||||
"gen_ai.request.model": "mock",
|
||||
"gcp.vertex.agent.invocation_id": "PRESENT",
|
||||
"gcp.vertex.agent.session_id": "PRESENT",
|
||||
"gcp.vertex.agent.event_id": "PRESENT",
|
||||
"gcp.vertex.agent.llm_request": "{}",
|
||||
"gcp.vertex.agent.llm_response": "{}"
|
||||
},
|
||||
"status": "UNSET",
|
||||
"children": [
|
||||
{
|
||||
"name": "generate_content mock",
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini",
|
||||
"gen_ai.operation.name": "generate_content",
|
||||
"gen_ai.request.model": "mock",
|
||||
"gen_ai.agent.name": "some_root_agent",
|
||||
"gen_ai.conversation.id": "PRESENT",
|
||||
"gcp.vertex.agent.event_id": "PRESENT",
|
||||
"gcp.vertex.agent.invocation_id": "PRESENT"
|
||||
},
|
||||
"status": "UNSET",
|
||||
"children": [
|
||||
{
|
||||
"name": "execute_tool load_skill",
|
||||
"attributes": {
|
||||
"gen_ai.operation.name": "execute_tool",
|
||||
"gen_ai.tool.description": "Loads the SKILL.md instructions for a given skill.",
|
||||
"gen_ai.tool.name": "load_skill",
|
||||
"gen_ai.tool.type": "LoadSkillTool",
|
||||
"gen_ai.agent.name": "some_root_agent",
|
||||
"gcp.vertex.agent.llm_request": "{}",
|
||||
"gcp.vertex.agent.llm_response": "{}",
|
||||
"gcp.vertex.agent.tool_call_args": "{}",
|
||||
"gen_ai.tool.call.id": "PRESENT",
|
||||
"gcp.vertex.agent.event_id": "PRESENT",
|
||||
"gcp.vertex.agent.tool_response": "{}",
|
||||
"adk.experimental.skill.name": "local-skill",
|
||||
"adk.experimental.skill.description": "A sample skill.",
|
||||
"adk.experimental.skill.source.uri": "file://local-skill",
|
||||
"adk.experimental.skill.additional_tools": [
|
||||
"foo",
|
||||
"bar"
|
||||
]
|
||||
},
|
||||
"status": "UNSET",
|
||||
"children": [],
|
||||
"logs": []
|
||||
}
|
||||
],
|
||||
"logs": [
|
||||
{
|
||||
"event_name": "gen_ai.choice",
|
||||
"body": {
|
||||
"content": "<elided>",
|
||||
"index": 0
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
},
|
||||
{
|
||||
"event_name": "gen_ai.system.message",
|
||||
"body": {
|
||||
"content": "<elided>"
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
},
|
||||
{
|
||||
"event_name": "gen_ai.user.message",
|
||||
"body": {
|
||||
"content": "<elided>"
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"logs": []
|
||||
},
|
||||
{
|
||||
"name": "call_llm",
|
||||
"attributes": {
|
||||
"gen_ai.system": "gcp.vertex.agent",
|
||||
"gen_ai.request.model": "mock",
|
||||
"gcp.vertex.agent.invocation_id": "PRESENT",
|
||||
"gcp.vertex.agent.session_id": "PRESENT",
|
||||
"gcp.vertex.agent.event_id": "PRESENT",
|
||||
"gcp.vertex.agent.llm_request": "{}",
|
||||
"gcp.vertex.agent.llm_response": "{}"
|
||||
},
|
||||
"status": "UNSET",
|
||||
"children": [
|
||||
{
|
||||
"name": "generate_content mock",
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini",
|
||||
"gen_ai.operation.name": "generate_content",
|
||||
"gen_ai.request.model": "mock",
|
||||
"gen_ai.agent.name": "some_root_agent",
|
||||
"gen_ai.conversation.id": "PRESENT",
|
||||
"gcp.vertex.agent.event_id": "PRESENT",
|
||||
"gcp.vertex.agent.invocation_id": "PRESENT"
|
||||
},
|
||||
"status": "UNSET",
|
||||
"children": [],
|
||||
"logs": [
|
||||
{
|
||||
"event_name": "gen_ai.choice",
|
||||
"body": {
|
||||
"content": "<elided>",
|
||||
"index": 0
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
},
|
||||
{
|
||||
"event_name": "gen_ai.system.message",
|
||||
"body": {
|
||||
"content": "<elided>"
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
},
|
||||
{
|
||||
"event_name": "gen_ai.user.message",
|
||||
"body": {
|
||||
"content": "<elided>"
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
},
|
||||
{
|
||||
"event_name": "gen_ai.user.message",
|
||||
"body": {
|
||||
"content": "<elided>"
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
},
|
||||
{
|
||||
"event_name": "gen_ai.user.message",
|
||||
"body": {
|
||||
"content": "<elided>"
|
||||
},
|
||||
"attributes": {
|
||||
"gen_ai.system": "gemini"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"logs": []
|
||||
}
|
||||
],
|
||||
"logs": []
|
||||
}
|
||||
],
|
||||
"logs": []
|
||||
},
|
||||
"metric_points": {
|
||||
"gen_ai.client.operation.duration": [
|
||||
{
|
||||
"attributes": {
|
||||
"gen_ai.agent.name": "some_root_agent",
|
||||
"gen_ai.operation.name": "generate_content",
|
||||
"gen_ai.provider.name": "gemini",
|
||||
"gen_ai.request.model": "mock",
|
||||
"gen_ai.response.model": "mock"
|
||||
},
|
||||
"value": "PRESENT"
|
||||
}
|
||||
],
|
||||
"gen_ai.execute_tool.duration": [
|
||||
{
|
||||
"attributes": {
|
||||
"gen_ai.agent.name": "some_root_agent",
|
||||
"gen_ai.tool.name": "load_skill",
|
||||
"gen_ai.tool.type": "LoadSkillTool"
|
||||
},
|
||||
"value": "PRESENT"
|
||||
}
|
||||
],
|
||||
"gen_ai.invoke_agent.duration": [
|
||||
{
|
||||
"attributes": {
|
||||
"gen_ai.agent.name": "some_root_agent"
|
||||
},
|
||||
"value": "PRESENT"
|
||||
}
|
||||
],
|
||||
"gen_ai.invoke_agent.inference_calls": [
|
||||
{
|
||||
"attributes": {
|
||||
"gen_ai.agent.name": "some_root_agent"
|
||||
},
|
||||
"value": 2
|
||||
}
|
||||
],
|
||||
"gen_ai.invoke_agent.tool_calls": [
|
||||
{
|
||||
"attributes": {
|
||||
"gen_ai.agent.name": "some_root_agent"
|
||||
},
|
||||
"value": 1
|
||||
}
|
||||
],
|
||||
"gen_ai.invoke_workflow.duration": [
|
||||
{
|
||||
"attributes": {
|
||||
"gen_ai.operation.name": "invoke_workflow",
|
||||
"gen_ai.workflow.name": "some_root_agent"
|
||||
},
|
||||
"value": "PRESENT"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -128,6 +128,52 @@ ALL_CASES: list[FunctionalTestCase] = semconv_matrix("agent") + [
|
||||
schema_version=2,
|
||||
tool_fails=True,
|
||||
),
|
||||
# Skill telemetry scenarios.
|
||||
FunctionalTestCase(
|
||||
test_id="skill-telemetry-schema-v1",
|
||||
scenario="skill",
|
||||
semconv_opt_in=None,
|
||||
experimental_telemetry=True,
|
||||
capture_content="false",
|
||||
schema_version=1,
|
||||
loaded_skills=["local"],
|
||||
),
|
||||
FunctionalTestCase(
|
||||
test_id="skill-telemetry-schema-v2",
|
||||
scenario="skill",
|
||||
semconv_opt_in=None,
|
||||
experimental_telemetry=True,
|
||||
capture_content="false",
|
||||
schema_version=2,
|
||||
loaded_skills=["local"],
|
||||
),
|
||||
FunctionalTestCase(
|
||||
test_id="skill-registry-cache-hit-schema-v2",
|
||||
scenario="skill",
|
||||
semconv_opt_in=None,
|
||||
experimental_telemetry=True,
|
||||
capture_content="false",
|
||||
schema_version=2,
|
||||
loaded_skills=["registry", "registry"],
|
||||
),
|
||||
FunctionalTestCase(
|
||||
test_id="invalid-skill-schema-v2",
|
||||
scenario="skill",
|
||||
semconv_opt_in=None,
|
||||
experimental_telemetry=True,
|
||||
capture_content="false",
|
||||
schema_version=2,
|
||||
loaded_skills=["nonexistent"],
|
||||
),
|
||||
FunctionalTestCase(
|
||||
test_id="skill-telemetry-disabled-schema-v1",
|
||||
scenario="skill",
|
||||
semconv_opt_in=None,
|
||||
experimental_telemetry=False,
|
||||
capture_content="false",
|
||||
schema_version=1,
|
||||
loaded_skills=["local", "registry"],
|
||||
),
|
||||
]
|
||||
|
||||
# The MCP integration case: an agent whose only tool source is a (fake) MCP
|
||||
|
||||
@@ -126,6 +126,39 @@ async def test_record_tool_execution_forwards_detected_error_type():
|
||||
assert mock_record.call_args.kwargs["error_type"] == "MCP_TOOL_ERROR"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_record_skill_load_reaches_the_enclosing_tool_execution():
|
||||
"""A skill load is reported to the tool execution that wraps it."""
|
||||
tool = mock.MagicMock()
|
||||
tool.name = "load_skill"
|
||||
agent = mock.MagicMock()
|
||||
agent.name = "sample_agent"
|
||||
|
||||
async with _instrumentation.record_tool_execution(
|
||||
tool=tool,
|
||||
agent=agent,
|
||||
function_args={},
|
||||
invocation_context=mock.MagicMock(),
|
||||
) as tel_ctx:
|
||||
skill_telemetry = _instrumentation.record_skill_telemetry(
|
||||
_instrumentation.SkillTelemetrySpanType.SKILL_LOAD
|
||||
)
|
||||
skill_telemetry.skill_name = "sample_skill"
|
||||
skill_telemetry.skill = mock.MagicMock()
|
||||
skill_telemetry.cache_hit = True
|
||||
|
||||
assert tel_ctx.skill_telemetry is skill_telemetry
|
||||
|
||||
|
||||
def test_record_skill_load_outside_tool_execution_is_a_noop():
|
||||
"""Callers never depend on a tool execution (and thus a span) being open."""
|
||||
_instrumentation.record_skill_telemetry(
|
||||
_instrumentation.SkillTelemetrySpanType.SKILL_LOAD,
|
||||
)
|
||||
|
||||
assert _instrumentation._active_tool_execution_tel_ctx() is None
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# The consolidated span + metric context managers.
|
||||
#
|
||||
|
||||
Reference in New Issue
Block a user