open-telemetry / open-telemetry/opentelemetry-python-genai
openai-agents: run context does not propagate to spans owned by the model SDK instrumentation
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 39
- Forks
- 63
- Avg merge
- 1d 15h
- Merged PRs (30d)
- 175
Description
Describe your environment
OS: Amazon Linux 2023
Python version: Python 3.14.7
Package version: opentelemetry-instrumentation-genai-openai-agents 1.2b0.dev0, opentelemetry-instrumentation-genai-openai 1.2b0.dev0, opentelemetry-util-genai 1.2b0.dev0 (reproduces on main @ c6b63bd)
GenAI library (e.g. anthropic, openai) and version: openai-agents 0.22.2, openai 3.13.0
What happened?
A trace of an agents run is produced by two independent instrumentation
packages. opentelemetry-instrumentation-genai-openai-agents owns
invoke_workflow, invoke_agent and execute_tool; the chat span is owned by
whichever model SDK instrumentation is installed —
opentelemetry-instrumentation-genai-openai on the default path, or
...-anthropic and friends when the run is routed through LiteLLM, any-llm, or
a caller-supplied Model.
There is no channel between them. Anything the agents instrumentation learns
from the framework stops at the spans it owns, and the model SDK
instrumentation, which only sees an HTTP call to a provider, cannot learn it.
OTel's Span API is write-only, so it cannot read the value off its parent span
either.
gen_ai.conversation.id is the case where this bites today. The agents library
carries a chat-thread identifier on Trace.group_id, set through
RunConfig(group_id=...) or trace(..., group_id=...), and semconv defines the
attribute as conditionally required on inference, invoke_agent and
invoke_workflow. The agents instrumentation receives the Trace in
on_trace_start and ignores group_id, so no span carries the attribute today
— but only the invoke_workflow and invoke_agent halves are a local
oversight. The chat span is unreachable by construction, and that is the part
that needs a decision.
Steps to Reproduce
import asyncio
from agents import Agent, Runner
from agents.run import RunConfig
from opentelemetry.instrumentation.genai.openai import OpenAIInstrumentor
from opentelemetry.instrumentation.genai.openai_agents import (
OpenAIAgentsInstrumentor,
)
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import SimpleSpanProcessor
from opentelemetry.sdk.trace.export.in_memory_span_exporter import (
InMemorySpanExporter,
)
exporter = InMemorySpanExporter()
provider = TracerProvider()
provider.add_span_processor(SimpleSpanProcessor(exporter))
OpenAIInstrumentor().instrument(tracer_provider=provider)
OpenAIAgentsInstrumentor().instrument(tracer_provider=provider)
agent = Agent(name="triage", instructions="Answer briefly.", model="gpt-4o-mini")
asyncio.run(
Runner.run(
agent,
"What colour is the sky?",
run_config=RunConfig(
workflow_name="probe-workflow", group_id="chat-thread-1"
),
)
)
for span in exporter.get_finished_spans():
print(span.name, span.attributes.get("gen_ai.conversation.id"))
Expected Result
chat gpt-4o-mini chat-thread-1
invoke_agent triage chat-thread-1
invoke_workflow probe-workflow chat-thread-1
Actual Result
chat gpt-4o-mini None
invoke_agent triage None
invoke_workflow probe-workflow None
Additional context
LangChain hit the same symptom in #474 (issue #475), but not the same problem:
LangChain is a single package that owns its whole tree and merges a run's config
metadata into every descendant, so each callback resolves the id from its own
metadata. Here the value has to cross a package boundary. The agents library
offers nothing to cross it with — group_id lives only on the Trace, and none
of the 14 types in agents.tracing.span_data exposes it.
Would you like to implement a fix?
Yes
Tip
React with 👍 to help prioritize this issue. Please use comments to provide useful context, avoiding +1 or me too, to help us triage it. Learn more here.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the agents instrumentation's on_trace_start handling of Trace and the agents.tracing.span_data types, then inspect how the OpenAI and other model SDK instrumentations create chat spans. Determine a supported way to carry group_id across the package boundary, and verify that the expected conversation ID appears on invoke_workflow, invoke_agent, and chat spans without breaking alternate model paths.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- observability-sre
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100