Skip to content

fix(tracing): name streamed task spans after the run's own workflow - #4167

Merged
seratch merged 1 commit into
openai:mainfrom
LeSingh1:fix/streamed-task-span-workflow-name
Aug 4, 2026
Merged

fix(tracing): name streamed task spans after the run's own workflow#4167
seratch merged 1 commit into
openai:mainfrom
LeSingh1:fix/streamed-task-span-workflow-name

Conversation

@LeSingh1

@LeSingh1 LeSingh1 commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Summary

A task span represents one top-level Runner invocation. The non-streaming path names it from the workflow name resolved for that run; the streaming path named it from streamed_result.trace or get_current_trace().

Those two agree only when the run creates its own trace. Inside an existing trace create_trace_for_run returns None, so streamed_result.trace is None and the streamed run fell back to the enclosing trace's name. An orchestration trace that fans out several streamed sub-runs therefore gets task spans all labelled with the orchestrator's workflow name — indistinguishable from each other and from the outer trace — while the same code run non-streamed labels them correctly. RunConfig(workflow_name=...) is effectively ignored for streamed runs nested in a trace.

This passes the already-resolved workflow name into start_streaming and uses it, which also drops a current_trace guard the non-streaming path never had (that variable existed only to supply the name, and its None branch is unreachable — create_trace_for_run returns None only when get_current_trace() is truthy).

start_streaming lives in agents.run_internal and is not a public export, so the new keyword-only argument is not a public API change. No persisted schema or wire format is affected; only exported telemetry changes, and it changes toward the documented semantics and toward the non-streamed path.

Present in released v0.19.2.

Test plan

  • New tests/test_agent_tracing.py::test_wrapped_run_task_span_uses_run_workflow_name runs the same agent non-streamed and streamed inside one outer trace and asserts both task spans use the run's own workflow name. It fails on main with At index 1 diff: 'outer_workflow' != 'inner_workflow' and passes with this change.
  • uv run pytest tests/test_agent_tracing.py tests/tracing → 72 passed.
  • bash .agents/skills/code-change-verification/scripts/run.sh → all commands passed.

Issue number

N/A — found while auditing tracing parity between the streamed and non-streamed runners.

Checks

  • I've added new tests, if relevant
  • I've run .agents/skills/code-change-verification/scripts/run.sh
  • I've confirmed all verification steps pass
  • If using Codex, I've run /review before submitting this PR

A task span represents one top-level Runner invocation, and the
non-streaming path names it from the workflow name resolved for that run.
The streaming path instead named it from `streamed_result.trace or
get_current_trace()`. Those two agree only when the run creates its own
trace: inside an existing trace `create_trace_for_run` returns `None`, so
`streamed_result.trace` is `None` and the streamed run fell back to the
enclosing trace's name.

The result is that an orchestration trace that fans out several streamed
sub-runs gets task spans all labelled with the orchestrator's workflow name,
so they cannot be told apart, while the same code run non-streamed labels
them correctly. `RunConfig(workflow_name=...)` is silently ignored for
streamed runs nested in a trace.

Pass the already-resolved workflow name into `start_streaming` and use it,
which also drops the `current_trace` guard the non-streaming path never had.
@seratch seratch added this to the 0.19.x milestone Aug 4, 2026
@seratch
seratch merged commit 72e7c6e into openai:main Aug 4, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants