Skip to content

fix(genai-util): propagate workflow context to downstream spans and m…#6

Open
shuningc wants to merge 1 commit intomainfrom
copy-pr-208
Open

fix(genai-util): propagate workflow context to downstream spans and m…#6
shuningc wants to merge 1 commit intomainfrom
copy-pr-208

Conversation

@shuningc
Copy link
Owner

@shuningc shuningc commented Feb 11, 2026

…etrics

Add workflow context inheritance in TelemetryHandler and include gen_ai.workflow.name in downstream LLM/tool/embedding/retrieval metric attributes so nested operations consistently carry workflow identity.

Summary by CodeRabbit

Release Notes

  • New Features

    • Workflow information is now automatically included in OpenTelemetry metrics for GenAI operations, improving observability and traceability across workflow executions.
  • Tests

    • Added comprehensive tests validating workflow and agent context propagation across telemetry handlers.

…etrics

Add workflow context inheritance in TelemetryHandler and include gen_ai.workflow.name in downstream LLM/tool/embedding/retrieval metric attributes so nested operations consistently carry workflow identity.

Co-authored-by: Cursor <cursoragent@cursor.com>
@coderabbitai
Copy link

coderabbitai bot commented Feb 11, 2026

📝 Walkthrough

Walkthrough

The pull request introduces workflow context propagation throughout the OpenTelemetry GenAI utilities. A new workflow context stack in the TelemetryHandler manages workflow lifecycle, propagating workflow names into invocation attributes and metrics across LLM, embedding, retrieval, and tool call invocations.

Changes

Cohort / File(s) Summary
Workflow Context Stack Management
util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py
Adds _workflow_context_stack to track active workflows, manages context push/pop on workflow lifecycle methods (start_workflow, stop_workflow, fail_workflow). Introduces _get_current_span_attribute() static helper and _inherit_parent_context_attributes() method to propagate agent and workflow context from active span into invocations. Updates all invocation start methods to apply inherited workflow context when not explicitly provided.
Workflow Context in Metrics
util/opentelemetry-util-genai/src/opentelemetry/util/genai/emitters/metrics.py
Retrieves GEN_AI_WORKFLOW_NAME from invocation attributes and adds it to metric attributes across token, duration, and MCP-related metric emission paths in both on_end and on_error processing. New import for GEN_AI_WORKFLOW_NAME from attributes module.
Test Coverage for Context Propagation
util/opentelemetry-util-genai/tests/test_metrics.py
Adds imports for TelemetryHandler and Workflow types. Introduces test_cross_handler_parent_context_propagates_agent_and_workflow test validating workflow and agent context inheritance across handler instances, with assertions on span attributes and metric propagation. Adds handler cleanup in setUp method.

Sequence Diagram

sequenceDiagram
    participant Client as Client Code
    participant Handler as TelemetryHandler
    participant Stack as Workflow<br/>Context Stack
    participant Span as Active Span
    participant Metrics as Metrics Emitter

    Client->>Handler: start_workflow(workflow)
    activate Handler
    Handler->>Stack: push(workflow.name)
    deactivate Handler

    Client->>Handler: start_llm(invocation)
    activate Handler
    Handler->>Handler: _inherit_parent_context_attributes()
    Handler->>Span: get current span attributes
    Span-->>Handler: span attributes (including GEN_AI_WORKFLOW_NAME)
    Handler->>invocation: set GEN_AI_WORKFLOW_NAME from context
    deactivate Handler

    Client->>Handler: stop_llm(invocation)
    activate Handler
    Handler->>Metrics: emit_token_metrics(invocation)
    Metrics->>invocation: get GEN_AI_WORKFLOW_NAME
    invocation-->>Metrics: workflow_name
    Metrics->>Metrics: add workflow_name to metric attributes
    deactivate Handler

    Client->>Handler: stop_workflow(workflow)
    activate Handler
    Handler->>Stack: pop(workflow.name)
    deactivate Handler
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~30 minutes

Poem

🐰 A workflow context hops through the stack,
Each invocation remembers where it's at,
Metrics now track the path they've taken,
No workflow identity left forsaken,
Context flows forward, never to lack! 🌟

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 57.89% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: propagating workflow context to downstream spans and metrics, which is the core objective described in the PR.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch copy-pr-208

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@qodo-code-review
Copy link

Review Summary by Qodo

Propagate workflow context to downstream spans and metrics

🐞 Bug fix ✨ Enhancement

Grey Divider

Walkthroughs

Description
• Propagate workflow context to downstream spans and metrics
  - Add workflow name inheritance in TelemetryHandler
  - Extract workflow name from parent span attributes
  - Include gen_ai.workflow.name in LLM/tool/embedding/retrieval metrics
• Implement parent context attribute extraction from active spans
  - Add _get_current_span_attribute() method for best-effort span attribute access
  - Add _inherit_parent_context_attributes() to propagate agent/workflow identity
• Manage workflow context stack lifecycle
  - Push workflow name on start_workflow()
  - Pop workflow name on stop_workflow() and fail_workflow()
• Add comprehensive test for cross-handler context propagation
Diagram
flowchart LR
  A["Workflow/Agent Start"] -->|Push context| B["Workflow Context Stack"]
  B -->|Inherit on nested ops| C["LLM/Tool/Embedding/Retrieval"]
  C -->|Extract from parent span| D["Parent Span Attributes"]
  D -->|Propagate to metrics| E["Metric Attributes"]
  F["Workflow/Agent Stop"] -->|Pop context| B
Loading

Grey Divider

File Changes

1. util/opentelemetry-util-genai/src/opentelemetry/util/genai/emitters/metrics.py ✨ Enhancement +50/-0

Include workflow name in metric attributes

• Import GEN_AI_WORKFLOW_NAME constant from attributes module
• Extract workflow name from invocation attributes in on_end() for LLM/tool/embedding operations
• Extract workflow name from invocation attributes in on_error() for LLM/tool/embedding operations
• Extract workflow name from retrieval attributes in _record_retrieval_metrics()
• Add workflow name to metric attributes when available

util/opentelemetry-util-genai/src/opentelemetry/util/genai/emitters/metrics.py


2. util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py ✨ Enhancement +110/-0

Implement workflow context propagation and inheritance

• Import GEN_AI_AGENT_ID, GEN_AI_AGENT_NAME, and GEN_AI_WORKFLOW_NAME constants
• Add _workflow_context_stack list to track active workflow names
• Implement _get_current_span_attribute() static method for safe span attribute extraction
• Implement _inherit_parent_context_attributes() method to propagate agent/workflow identity from
 parent spans
• Update start_llm(), start_embedding(), start_retrieval(), start_tool_call(), and start_agent() to
 inherit workflow context from stack and parent spans
• Push workflow name to stack in start_workflow()
• Pop workflow name from stack in stop_workflow() and fail_workflow() with error handling

util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py


3. util/opentelemetry-util-genai/tests/test_metrics.py 🧪 Tests +115/-1

Add cross-handler context propagation test

• Import TelemetryHandler class and Workflow type
• Add test_cross_handler_parent_context_propagates_agent_and_workflow() test
• Verify workflow name and agent identity propagate across handler instances
• Validate propagation in both span and metric attributes

util/opentelemetry-util-genai/tests/test_metrics.py


Grey Divider

Qodo Logo

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
util/opentelemetry-util-genai/tests/test_metrics.py (1)

59-64: ⚠️ Potential issue | 🟡 Minor

Duplicate cleanup block in setUp.

Lines 60-61 and Lines 63-64 are identical hasattr/delattr pairs. This is a copy-paste leftover.

🧹 Remove the duplicate
         # Reset handler singleton
         if hasattr(get_telemetry_handler, "_default_handler"):
             delattr(get_telemetry_handler, "_default_handler")
-        # Reset handler singleton
-        if hasattr(get_telemetry_handler, "_default_handler"):
-            delattr(get_telemetry_handler, "_default_handler")
🧹 Nitpick comments (6)
util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py (4)

262-263: Workflow context stack lacks a unique identifier — out-of-order completions can orphan entries.

The _agent_context_stack tracks (name, run_id) tuples and pops only when both match (Lines 965-967), making it resilient to out-of-order stop/fail. In contrast, _workflow_context_stack stores only the name string. If a nested workflow (B) is still active when an outer workflow (A) completes out of order, the pop check ([-1] == workflow.name) will silently skip the pop and leave A permanently on the stack.

Consider storing (name, run_id) tuples (mirroring the agent stack) and matching on both fields when popping.

♻️ Suggested change
-        # Active workflow name stack for implicit propagation to nested operations
-        self._workflow_context_stack: list[str] = []
+        # Active workflow name stack for implicit propagation to nested operations
+        self._workflow_context_stack: list[tuple[str, str]] = []  # (name, run_id)

Then adjust push (Line 731):

-            self._workflow_context_stack.append(workflow.name)
+            self._workflow_context_stack.append((workflow.name, str(workflow.run_id)))

Pop sites (Lines 873-878, 897-902) become:

-                and self._workflow_context_stack[-1] == workflow.name
+                and self._workflow_context_stack[-1] == (workflow.name, str(workflow.run_id))

Read sites extract [0] for the name:

-                self._workflow_context_stack[-1]
+                self._workflow_context_stack[-1][0]

350-367: Accessing _attributes is fragile — document the SDK coupling.

_attributes is a private attribute of ReadableSpan in the OTel SDK. The public attributes property exists on ReadableSpan (SDK), but not on the base Span interface (API). The fallback chain (attributes_attributes) is reasonable defensive coding, but a brief inline comment noting the SDK coupling would help future maintainers.

Also, get_current_span() returns INVALID_SPAN (not None) when no span is active. The is None guard on Line 357 will never be True for the default implementation. This is harmless because INVALID_SPAN has no attributes/_attributes, so execution falls through correctly — but it could be slightly more precise.

Minor precision improvement
         try:
             current_span = _trace_mod.get_current_span()
         except Exception:
             return None
-        if current_span is None:
+        if current_span is None or not current_span.is_recording():
             return None

369-419: Dual propagation paths (stack + parent span) may conflict or double-apply.

start_llm (and siblings) first checks _workflow_context_stack (Lines 412-418), then calls _inherit_parent_context_attributes (Line 419), which also tries to set GEN_AI_WORKFLOW_NAME from the parent span (Lines 383-393). When the active span already carries the workflow name (set by start_workflowon_start), both paths would agree. However, if the stack and parent span disagree (e.g., stale stack entry), the stack wins because the in invocation.attributes guard in _inherit_parent_context_attributes sees it's already set.

This is probably intentional (stack = authoritative source, parent span = fallback for cross-handler scenarios), but it's worth a brief comment explaining the precedence. Also, in _inherit_parent_context_attributes, the workflow check uses in invocation.attributes while the agent checks use not invocation.agent_name — the inconsistency is minor but could confuse readers.


412-419: Repeated workflow-context injection block — consider extracting a helper.

The same 7-line pattern (check attributes → check stack → assign) is duplicated verbatim in start_llm, start_embedding, start_retrieval, start_tool_call, and start_agent. A small private helper would reduce duplication and make future changes (e.g., adding run_id to the stack) a single-point edit.

♻️ Proposed helper
def _apply_workflow_context(self, invocation: GenAI) -> None:
    """Set workflow name from context stack if not already present."""
    if (
        GEN_AI_WORKFLOW_NAME not in invocation.attributes
        and self._workflow_context_stack
    ):
        invocation.attributes[GEN_AI_WORKFLOW_NAME] = (
            self._workflow_context_stack[-1]
        )

Then each start_* call becomes:

self._apply_workflow_context(invocation)
self._inherit_parent_context_attributes(invocation)

Also applies to: 538-545, 612-619, 682-689, 913-920

util/opentelemetry-util-genai/src/opentelemetry/util/genai/emitters/metrics.py (2)

105-111: Consider extracting the repeated workflow-name extraction into a helper.

The same block:

workflow_name = (
    invocation.attributes.get(GEN_AI_WORKFLOW_NAME)
    if invocation.attributes
    else None
)
if workflow_name:
    metric_attrs[GEN_AI_WORKFLOW_NAME] = workflow_name

appears 8 times across on_end, on_error, and _record_retrieval_metrics. Combined with the similarly repeated agent_name/agent_id extraction, there's an opportunity to consolidate all context-attribute propagation into a single helper that enriches metric_attrs from invocation attributes in one pass.

♻️ Proposed helper
def _enrich_metric_attrs_with_context(
    metric_attrs: dict[str, Any], invocation: Any
) -> None:
    """Copy agent and workflow context from invocation into metric attributes."""
    if getattr(invocation, "agent_name", None):
        metric_attrs[GenAI.GEN_AI_AGENT_NAME] = invocation.agent_name
    if getattr(invocation, "agent_id", None):
        metric_attrs[GenAI.GEN_AI_AGENT_ID] = invocation.agent_id
    attrs = getattr(invocation, "attributes", None)
    if attrs:
        wf = attrs.get(GEN_AI_WORKFLOW_NAME)
        if wf:
            metric_attrs[GEN_AI_WORKFLOW_NAME] = wf

Each call site then becomes a single line:

_enrich_metric_attrs_with_context(metric_attrs, llm_invocation)

Also applies to: 143-149, 181-187, 228-234, 260-266, 299-305, 408-414


127-160: Missing return after ToolCall branch in on_endEmbeddingInvocation and RetrievalInvocation blocks always execute for tool calls.

Line 127 uses if isinstance(obj, ToolCall) but does not return at the end of the block (Line 159). Since ToolCall is not an EmbeddingInvocation or RetrievalInvocation, the subsequent if checks on Lines 161 and 196 evaluate to False and are harmless — so there's no runtime bug. However, this differs from the LLMInvocation branch which does return on Line 126. The inconsistency could cause issues if type hierarchies change.

This is pre-existing code (not introduced in this PR), so flagging it only as a minor observation.

@qodo-code-review
Copy link

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (2) 📎 Requirement gaps (0)

Grey Divider


Action required

1. Workflow stack not context-safe 🐞 Bug ⛯ Reliability
Description
TelemetryHandler stores workflow identity in a mutable instance stack that is shared by all callers
of the singleton handler, which can mis-attribute workflow name in concurrent/overlapping workflows
(threads/async tasks) and pollute downstream span/metric attributes.
Code

util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py[R262-263]

+        # Active workflow name stack for implicit propagation to nested operations
+        self._workflow_context_stack: list[str] = []
Evidence
The handler is commonly used as a singleton, and workflow context is tracked via a shared list
(_workflow_context_stack). Downstream invocations read the top of this stack to set
gen_ai.workflow.name, so interleaving start/stop across concurrent executions can cause the wrong
workflow name to be applied to unrelated invocations.

util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py[260-264]
util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py[412-418]
util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py[1225-1243]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`TelemetryHandler` tracks workflow identity in a mutable list on the handler instance. Because `get_telemetry_handler()` returns a singleton, that stack becomes shared mutable state across concurrent requests/tasks, which can cause `gen_ai.workflow.name` to be applied to the wrong nested spans/metrics.

### Issue Context
The PR already adds `_inherit_parent_context_attributes()` which can derive workflow/agent identity from the current active span. Prefer context-local propagation over a shared stack.

### Fix Focus Areas
- util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py[260-264]
- util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py[722-732]
- util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py[851-905]
- util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py[395-420]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Exceptions swallowed in context inheritance 📘 Rule violation ⛯ Reliability
Description
New context-inheritance code catches broad Exception and silently returns None/pass, which can
hide real failures during telemetry context propagation and make production debugging difficult.
This conflicts with the requirement to avoid swallowed exceptions without logging or actionable
context.
Code

util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py[R353-367]

+        try:
+            current_span = _trace_mod.get_current_span()
+        except Exception:
+            return None
+        if current_span is None:
+            return None
+        attributes = getattr(current_span, "attributes", None)
+        if attributes is None:
+            attributes = getattr(current_span, "_attributes", None)
+        if not attributes:
+            return None
+        try:
+            return attributes.get(key)
+        except Exception:
+            return None
Evidence
PR Compliance ID 3 requires robust error handling and explicitly calls out swallowed exceptions
without logging as a failure case. The newly added logic in TelemetryHandler introduces multiple
broad except Exception blocks that return None/pass without logging.

Rule 3: Generic: Robust Error Handling and Edge Case Management
util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py[350-367]
util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py[873-880]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
New context inheritance code introduces broad `except Exception` blocks that silently return `None`/`pass`, making failures in span attribute extraction or stack maintenance hard to detect and debug.

## Issue Context
Compliance requires robust error handling and avoiding swallowed exceptions without logging/actionable context.

## Fix Focus Areas
- util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py[350-367]
- util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py[873-904]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Duplicated workflow_name extraction logic 📘 Rule violation ⛯ Reliability
Description
The same multi-line workflow_name extraction block is repeated across multiple metric-recording
paths, increasing maintenance burden and risk of inconsistencies. This violates the DRY/SOLID
maintainability requirement.
Code

util/opentelemetry-util-genai/src/opentelemetry/util/genai/emitters/metrics.py[R105-111]

+            workflow_name = (
+                llm_invocation.attributes.get(GEN_AI_WORKFLOW_NAME)
+                if llm_invocation.attributes
+                else None
+            )
+            if workflow_name:
+                metric_attrs[GEN_AI_WORKFLOW_NAME] = workflow_name
Evidence
PR Compliance ID 24 requires avoiding unnecessary duplication and keeping abstractions maintainable.
The PR adds identical workflow_name = (...) blocks in multiple places
(LLM/tool/embedding/retrieval and error paths) instead of factoring into a helper.

AGENTS.md
util/opentelemetry-util-genai/src/opentelemetry/util/genai/emitters/metrics.py[105-111]
util/opentelemetry-util-genai/src/opentelemetry/util/genai/emitters/metrics.py[143-149]
util/opentelemetry-util-genai/src/opentelemetry/util/genai/emitters/metrics.py[181-187]
util/opentelemetry-util-genai/src/opentelemetry/util/genai/emitters/metrics.py[408-414]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`workflow_name` extraction and assignment is duplicated across multiple metric emission branches, creating avoidable repetition.

## Issue Context
The same pattern appears for LLM, tool, embedding, retrieval, and error metric paths.

## Fix Focus Areas
- util/opentelemetry-util-genai/src/opentelemetry/util/genai/emitters/metrics.py[105-111]
- util/opentelemetry-util-genai/src/opentelemetry/util/genai/emitters/metrics.py[143-149]
- util/opentelemetry-util-genai/src/opentelemetry/util/genai/emitters/metrics.py[181-187]
- util/opentelemetry-util-genai/src/opentelemetry/util/genai/emitters/metrics.py[408-414]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


4. Wrong precedence vs parent span 🐞 Bug ✓ Correctness
Description
Downstream invocations set workflow name from _workflow_context_stack before inheriting from the
active parent span, so if the stack is stale (e.g., due to overlap/concurrency), the correct
parent-span workflow name will not override the incorrect stack value.
Code

util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py[R412-420]

+        if (
+            GEN_AI_WORKFLOW_NAME not in invocation.attributes
+            and self._workflow_context_stack
+        ):
+            invocation.attributes[GEN_AI_WORKFLOW_NAME] = (
+                self._workflow_context_stack[-1]
+            )
+        self._inherit_parent_context_attributes(invocation)
        # Start invocation span; tracer context propagation handles parent/child links
Evidence
In start_llm (and similarly in other start_* methods), the workflow attribute is assigned from the
stack first. _inherit_parent_context_attributes() only sets workflow name when the key is not
already present, so a wrong stack-derived value blocks the parent-span-derived value.

util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py[383-394]
util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py[412-420]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
Current propagation order sets `gen_ai.workflow.name` from `_workflow_context_stack` before inheriting from the active parent span. Because `_inherit_parent_context_attributes()` only fills missing keys, a wrong stack value cannot be corrected by the parent span.

### Issue Context
The PR’s intent is to propagate workflow identity via active parent span context for cross-handler cases; that should be the primary source of truth.

### Fix Focus Areas
- util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py[395-420]
- util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py[525-552]
- util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py[599-626]
- util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py[671-695]
- util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py[908-935]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

Comment on lines +262 to +263
# Active workflow name stack for implicit propagation to nested operations
self._workflow_context_stack: list[str] = []

Choose a reason for hiding this comment

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

Action required

1. Workflow stack not context-safe 🐞 Bug ⛯ Reliability

TelemetryHandler stores workflow identity in a mutable instance stack that is shared by all callers
of the singleton handler, which can mis-attribute workflow name in concurrent/overlapping workflows
(threads/async tasks) and pollute downstream span/metric attributes.
Agent Prompt
### Issue description
`TelemetryHandler` tracks workflow identity in a mutable list on the handler instance. Because `get_telemetry_handler()` returns a singleton, that stack becomes shared mutable state across concurrent requests/tasks, which can cause `gen_ai.workflow.name` to be applied to the wrong nested spans/metrics.

### Issue Context
The PR already adds `_inherit_parent_context_attributes()` which can derive workflow/agent identity from the current active span. Prefer context-local propagation over a shared stack.

### Fix Focus Areas
- util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py[260-264]
- util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py[722-732]
- util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py[851-905]
- util/opentelemetry-util-genai/src/opentelemetry/util/genai/handler.py[395-420]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants