Skip to content

fix: store OpenAI agent Generation span attributes under correct SpanAttributeKey constants#24290

Merged
joshuawong-db merged 6 commits into
mlflow:masterfrom
RudraDudhat2509:fix/openai-agent-generation-span-token-usage
Jul 14, 2026
Merged

fix: store OpenAI agent Generation span attributes under correct SpanAttributeKey constants#24290
joshuawong-db merged 6 commits into
mlflow:masterfrom
RudraDudhat2509:fix/openai-agent-generation-span-token-usage

Conversation

@RudraDudhat2509

@RudraDudhat2509 RudraDudhat2509 commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Related Issues/PRs

Closes #24059

What changes are proposed in this pull request?

MlflowOpenAgentTracingProcessor._parse_span_data() wrote token usage for GENERATION spans under the plain key "usage". However, aggregate_usage_from_spans() and calculate_span_cost() both read SpanAttributeKey.CHAT_USAGE ("mlflow.chat.tokenUsage"). The key mismatch silently dropped all token counts from trace.info.token_usage. Streaming calls were hit hardest since the Agents SDK is the only source of usage data for those spans.

Two fixes in this PR:

  1. Added _parse_generation_usage() helper that maps the Agents SDK usage dict to TokenUsageKey-keyed values and sets the result under SpanAttributeKey.CHAT_USAGE inside _parse_span_data(). Matches the existing pattern in mlflow/groq/_groq_autolog.py and mlflow/anthropic/autolog.py.

  2. _parse_span_data() now sets SpanAttributeKey.MODEL (not plain "model") for GENERATION spans, so calculate_span_cost() can read the model name and compute cost correctly.

No API changes are needed.

How is this PR tested?

  • Existing unit/integration tests
  • New unit/integration tests
  • Manual tests

test_generation_span_attributes_stored_under_span_attribute_keys: mocks a GenerationSpanData, calls _parse_span_data(), asserts attributes contain both SpanAttributeKey.MODEL and SpanAttributeKey.CHAT_USAGE with correct values, and that neither plain "model" nor "usage" keys exist.

test_parse_generation_usage: parametrized over full dict, partial dict, nested input_tokens_details with both cache keys, partial cache details (only one key present), None, and empty dict.

test_calculate_span_cost_uses_generation_span_model_attribute: verifies cost calculation reads the model from SpanAttributeKey.MODEL and not the plain "model" key.

image

Does this PR require documentation update?

  • No.
  • Yes. I've updated:
    • Examples
    • API references
    • Instructions

Does this PR require updating the MLflow Skills repository?

  • No.
  • Yes. Please link the corresponding PR or explain how you plan to update it.

Release Notes

Is this a user-facing change?

  • No.
  • Yes. Give a description of this change to be included in the release notes for MLflow users.

Token usage from OpenAI Agents SDK GENERATION spans (including streamed runs) now correctly rolls up into trace.info.token_usage and is used by calculate_span_cost(). Cached token counts (read and creation) are now captured from the nested input_tokens_details field. Model name is now stored under the correct attribute key so span cost is no longer silently skipped.

What component(s), interfaces, languages, and integrations does this PR affect?

Components

  • area/tracking: Tracking Service, tracking client APIs, autologging
  • area/models: MLmodel format, model serialization/deserialization, flavors
  • area/model-registry: Model Registry service, APIs, and the fluent client calls for Model Registry
  • area/scoring: MLflow Model server, model deployment tools, Spark UDFs
  • area/evaluation: MLflow model evaluation features, evaluation metrics, and evaluation workflows
  • area/gateway: MLflow AI Gateway client APIs, server, and third-party integrations
  • area/prompts: MLflow prompt engineering features, prompt templates, and prompt management
  • area/tracing: MLflow Tracing features, tracing APIs, and LLM tracing functionality
  • area/projects: MLproject format, project running backends
  • area/uiux: Front-end, user experience, plotting, JavaScript, JavaScript dev server
  • area/build: Build and test infrastructure for MLflow
  • area/docs: MLflow documentation pages

How should the PR be classified in the release notes? Choose one:

  • rn/none - No description will be included. The PR will be mentioned only by the PR number in the "Small Bugfixes and Documentation Updates" section
  • rn/breaking-change - The PR will be mentioned in the "Breaking Changes" section
  • rn/feature - A new user-facing feature worth mentioning in the release notes
  • rn/bug-fix - A user-facing bug fix worth mentioning in the release notes
  • rn/documentation - A user-facing documentation change worth mentioning in the release notes

Is this PR a critical bugfix or security fix that should go into the next patch release?

What is a minor/patch release?
  • Minor release: a release that increments the second part of the version number (e.g., 1.2.0 -> 1.3.0).
    Minor releases are expected to contain larger changes, such as new features and improvements. Non-critical bug fixes and doc updates can be included as well. By default, your PR should target the next minor release.
  • Patch release: a release that increments the third part of the version number (e.g., 1.2.0 -> 1.2.1).
    Patch releases are typically only performed when there has been a major regression or bug in the latest release. For the sake of stability, your PR should not be included in a patch release unless it is a critical fix, or if the risk level of your PR is exceedingly low.
  • This PR is critical and needs to be in the next patch release
  • This PR can wait for the next minor release

Copilot AI review requested due to automatic review settings July 6, 2026 07:14
@github-actions github-actions Bot added the community Community/external contribution label Jul 6, 2026
@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor
Install mlflow from this PR

Install mlflow from this PR

# mlflow
pip install git+https://github.com/mlflow/mlflow.git@refs/pull/24290/merge
# mlflow-skinny
pip install git+https://github.com/mlflow/mlflow.git@refs/pull/24290/merge#subdirectory=libs/skinny

For Databricks, use the following command:

%sh curl -LsSf https://raw.githubusercontent.com/mlflow/mlflow/HEAD/dev/install-skinny.sh | sh -s pull/24290/merge

PR author's recent activity

In the last 14 days, @RudraDudhat2509 opened 15 PRs across 4 repos:

Repository Open Closed Merged Total
RudraDudhat2509/brok 0 0 7 7
RudraDudhat2509/mimic-eval 1 0 5 6
mlflow/mlflow 1 0 0 1
langfuse/langfuse-python 1 0 0 1

@github-actions github-actions Bot added size/M area/tracing MLflow Tracing and its integrations rn/bug-fix Mention under Bug Fixes in Changelogs. labels Jul 6, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a data-correctness issue in MLflow’s OpenAI Agents SDK tracing integration where token usage recorded on GENERATION spans was stored under the wrong attribute key, preventing trace-level token aggregation (and related downstream consumers) from seeing those tokens.

Changes:

  • Update _parse_span_data() for GENERATION spans to store usage under SpanAttributeKey.CHAT_USAGE instead of a plain "usage" attribute.
  • Add _parse_generation_usage() helper to normalize usage dicts into MLflow’s TokenUsageKey schema.
  • Add unit tests covering both the span attribute behavior and the usage parsing helper.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
mlflow/openai/_agent_tracer.py Writes Generation span usage under SpanAttributeKey.CHAT_USAGE via a new parsing helper.
tests/openai/test_openai_agent_autolog.py Adds tests ensuring usage is stored under CHAT_USAGE and validating _parse_generation_usage().

Comment thread mlflow/openai/_agent_tracer.py
Comment thread mlflow/openai/_agent_tracer.py Outdated
Co-authored-by: Copilot Autofix powered by AI <[email protected]>
Signed-off-by: Rudra Dudhat <[email protected]>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

@RudraDudhat2509

Copy link
Copy Markdown
Contributor Author

opened #24393 to address copilot comments

@PattaraS

Copy link
Copy Markdown
Collaborator

Following @joshuawong-db's note on #24393 (closed into this PR): could you also fold in the model-key fix here? The GENERATION span sets a plain "model" key, but calculate_span_cost() reads SpanAttributeKey.MODEL ("mlflow.llm.model"), so cost stays None for these traces even with the token-usage fix. Setting SpanAttributeKey.MODEL alongside the current change (plus a small test asserting cost/model resolves) would let this PR close both. The token-usage part already looks good.

…MODEL

Using a plain string key "model" instead of SpanAttributeKey.MODEL
("mlflow.llm.model") caused calculate_span_cost() to silently skip
cost calculation for Generation spans because the attribute was never
found via get_attribute().

Signed-off-by: Rudra Dudhat <[email protected]>
@RudraDudhat2509

Copy link
Copy Markdown
Contributor Author

hey @PattaraS ! pushed the changes, also updated the test file, lmk if anything else is required from my end, thx

Merged model-key and token-usage assertions into one test
(test_generation_span_attributes_stored_under_span_attribute_keys)
to verify both fixes together; mocked cost calculation in
test_calculate_span_cost_uses_generation_span_model_attribute to
avoid coupling to LiteLLM pricing data.

Signed-off-by: Rudra Dudhat <[email protected]>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

@joshuawong-db

Copy link
Copy Markdown
Collaborator

/review-v2

@github-actions

github-actions Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Documentation preview for d06cc26 is available at:

More info
  • Ignore this comment if this PR does not change the documentation.
  • The preview is updated when a new commit is pushed to this PR.
  • This comment was created by this workflow run.
  • The documentation was built by this workflow run.

@joshuawong-db joshuawong-db left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thank you, in general this looks good, pending one comment on cached tokens nesting. Could you also update the PR description? It references tests that do not exist in the code.

Comment thread tests/openai/test_openai_agent_autolog.py
Comment thread mlflow/openai/_agent_tracer.py
@RudraDudhat2509 RudraDudhat2509 changed the title fix: store OpenAI agent Generation span token usage under SpanAttributeKey.CHAT_USAGE fix: store OpenAI agent Generation span attributes under correct SpanAttributeKey constants Jul 13, 2026

@joshuawong-db joshuawong-db left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM, thanks for the contribution @RudraDudhat2509

@joshuawong-db
joshuawong-db added this pull request to the merge queue Jul 14, 2026
Merged via the queue into mlflow:master with commit 43c1455 Jul 14, 2026
79 of 83 checks passed
@RudraDudhat2509

Copy link
Copy Markdown
Contributor Author

Appreciate the quick review thx!

@RudraDudhat2509
RudraDudhat2509 deleted the fix/openai-agent-generation-span-token-usage branch July 14, 2026 11:47
Copilot AI pushed a commit that referenced this pull request Jul 16, 2026
…AttributeKey constants (#24290)

Signed-off-by: Rudra Dudhat <[email protected]>
Co-authored-by: Copilot Autofix powered by AI <[email protected]>
Co-authored-by: mprahl <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/tracing MLflow Tracing and its integrations community Community/external contribution rn/bug-fix Mention under Bug Fixes in Changelogs. size/M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] OpenAI Autolog Generation spans store token usage under the wrong attribute key, so it's excluded from trace-level token aggregation

4 participants