Skip to content

Genai utils | Add AgentInvocation type#4274

Open
etserend wants to merge 15 commits intoopen-telemetry:mainfrom
etserend:genai-utils/agent-invocation
Open

Genai utils | Add AgentInvocation type#4274
etserend wants to merge 15 commits intoopen-telemetry:mainfrom
etserend:genai-utils/agent-invocation

Conversation

@etserend
Copy link

Description

This PR adds the AgentInvocation type extending _BaseAgent for agent invocation (invoke_agent) spans. It provides TelemetryHandler lifecycle methods and an agent() context manager — aligned with the GenAI agent span semantic conventions.

Builds on the _BaseAgent base class and AgentCreation type added in #4217. Agent metrics and events to come in follow-up PRs.

Type of change

Please delete options that are not relevant.

  • New feature (non-breaking change which adds functionality)

How Has This Been Tested?

  • Basic unit tests for starting and stopping agent invocation spans
  • Unit tests for agent invocation with all attributes (request + response)
  • Unit tests for context manager happy path and error path
  • Unit tests for AgentInvocation dataclass defaults and messages

Does This PR Require a Core Repo Change?

  • No.

Checklist:

See contributing.md for styleguide, changelog guidelines, and more.

  • Followed the style guidelines of this project
  • Changelogs have been updated
  • Unit tests have been added
  • Documentation has been updated

@etserend etserend force-pushed the genai-utils/agent-invocation branch from 1b5cd9f to 08e2b07 Compare February 27, 2026 17:45
@etserend etserend changed the title Genai utils/agent invocation Genai utils/Add AgentInvocation type Mar 2, 2026
@etserend etserend changed the title Genai utils/Add AgentInvocation type Genai utils | Add AgentInvocation type Mar 2, 2026
@etserend
Copy link
Author

etserend commented Mar 2, 2026

Sample trace from demo app

Trace: ad3749665a3bffcef592d6bacc2a2924

invoke_agent Poetry Agent (1.323s, Client)
├── gen_ai.agent.name: Poetry Agent
├── gen_ai.input.messages: [{"role":"user","parts":[{"content":"What is O...
├── gen_ai.operation.name: invoke_agent
├── gen_ai.output.messages: [{"role":"assistant","parts":[{"content":"Ope...
├── gen_ai.provider.name: openai
├── gen_ai.request.model: gpt-4o-mini
├── gen_ai.response.finish_reasons:
├── gen_ai.response.id: chatcmpl-DHtaXlNpLabc2yKX3TfQ0dlJT5rj9
├── gen_ai.response.model: gpt-4o-mini-2024-07-18
├── gen_ai.usage.input_tokens: 15
├── gen_ai.usage.output_tokens: 36
├── server.address: api.openai.com
├── server.port: 443
│
├── chat gpt-4o-mini (1.323s, Client)
│   ├── gen_ai.input.messages: [{"role":"user","parts":[{"content":"What is O...
│   ├── gen_ai.operation.name: chat
│   ├── gen_ai.output.messages: [{"role":"assistant","parts":[{"content":"Ope...
│   ├── gen_ai.provider.name: openai
│   ├── gen_ai.request.model: gpt-4o-mini
│   ├── gen_ai.response.finish_reasons:
│   ├── gen_ai.response.id: chatcmpl-DHtaXlNpLabc2yKX3TfQ0dlJT5rj9
│   ├── gen_ai.response.model: gpt-4o-mini-2024-07-18
│   ├── gen_ai.usage.input_tokens: 15
│   ├── gen_ai.usage.output_tokens: 36
│   ├── server.address: api.openai.com
│   │
│   └── chat gpt-4o-mini (1.322s, Client)
│       ├── gen_ai.openai.response.service_tier: default
│       ├── gen_ai.operation.name: chat
│       ├── gen_ai.request.model: gpt-4o-mini
│       ├── gen_ai.response.finish_reasons:
│       ├── gen_ai.response.id: chatcmpl-DHtaXlNpLabc2yKX3TfQ0dlJT5rj9
│       ├── gen_ai.response.model: gpt-4o-mini-2024-07-18
│       ├── gen_ai.system: openai
│       ├── gen_ai.usage.input_tokens: 15
│       ├── gen_ai.usage.output_tokens: 36
│       └── server.address: api.openai.com

@etserend etserend marked this pull request as ready for review March 2, 2026 22:23
@etserend etserend requested a review from a team as a code owner March 2, 2026 22:23
@tammy-baylis-swi tammy-baylis-swi moved this to Ready for review in Python PR digest Mar 3, 2026
@etserend etserend force-pushed the genai-utils/agent-invocation branch from e0ee125 to 25411ca Compare March 6, 2026 16:28
Copy link
Contributor

@eternalcuriouslearner eternalcuriouslearner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall LGTM!! I left few questions to understand:

  1. If we need to improve overall robustness of error handling.
  2. early capture of few sem conv.

I used this doc for reviewing if sem conv are captured correctly or not. Additionally does it make sense to make this pr specific for agent invocation and removing agent creation specific code.

Copy link
Contributor

@wrisa wrisa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Though would need refactoring in handler.py in case other PRs are merged first.

Copy link
Contributor

@eternalcuriouslearner eternalcuriouslearner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: Do we have GEN_AI_AGENT_VERSION, GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS, GEN_AI_TOOL_DEFINITIONS and GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS in opentelemetry.semconv._incubating.attributes?

@etserend
Copy link
Author

question: Do we have GEN_AI_AGENT_VERSION, GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS, GEN_AI_TOOL_DEFINITIONS and GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS in opentelemetry.semconv._incubating.attributes?

Yes @eternalcuriouslearner , all four constants in semconv package and referenced them via the GenAI. alias.

@etserend
Copy link
Author

Verified the AgentInvocation type and TelemetryHandler.agent() context manager end-to-end using the Vertex AI SDK with VertexAIInstrumentor auto-instrumentation.

Demo PR: #4340

Steps exercised:

  • invoke_agent span wrapping a generate_content LLM call
  • Auto-instrumented chat span appears as child of invoke_agent (same trace)
  • Token usage populated from response metadata
Trace (e71e16deb2ecd162e3f4fc67c240818b)
└── invoke_agent Currency Exchange Agent (4.16s, Client)
    ├── gen_ai.operation.name: invoke_agent
    ├── gen_ai.agent.name: Currency Exchange Agent
    ├── gen_ai.agent.description: Currency exchange agent demo
    ├── gen_ai.provider.name: gcp_vertex_ai
    ├── gen_ai.request.model: gemini-2.5-flash
    ├── gen_ai.response.finish_reasons: ["stop"]
    ├── gen_ai.usage.input_tokens: 12
    ├── gen_ai.usage.output_tokens: 87
    ├── server.address: us-central1-aiplatform.googleapis.com
    │
    └── chat gemini-2.5-flash (4.12s, Client)
        ├── gen_ai.operation.name: chat
        ├── gen_ai.system: vertex_ai
        ├── gen_ai.request.model: gemini-2.5-flash
        ├── gen_ai.response.model: gemini-2.5-flash
        ├── gen_ai.response.finish_reasons: ["stop"]
        ├── gen_ai.usage.input_tokens: 12
        ├── gen_ai.usage.output_tokens: 87
        ├── server.address: us-central1-aiplatform.googleapis.com
        └── server.port: 443

@keith-decker
Copy link
Contributor

@etserend Note: based on the discussion in SIG today, we should not be introducing new start_, stop_ and fail_* methods.

see #4219 for the discussion and examples.

@keith-decker keith-decker self-requested a review March 19, 2026 16:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Ready for review

Development

Successfully merging this pull request may close these issues.

7 participants