Skip to content

perf: avoid full response model_dump in usage cost path#1886

Merged
alexmojaki merged 8 commits into
pydantic:mainfrom
imp-joshi:fix/1844-avoid-full-model-dump-cost-calculation
Apr 29, 2026
Merged

perf: avoid full response model_dump in usage cost path#1886
alexmojaki merged 8 commits into
pydantic:mainfrom
imp-joshi:fix/1844-avoid-full-model-dump-cost-calculation

Conversation

@imp-joshi
Copy link
Copy Markdown
Contributor

Closes #1844

get_usage_attributes() calls response.model_dump() on the full response before passing it to genai_prices.extract_usage(). For embedding responses this serializes all the embedding vectors even though extract_usage only reads two top-level fields (model and usage for OpenAI/Anthropic, modelVersion and usageMetadata for Google GenAI).

What changed

The cost path now calls model_dump(include=...) with just those four fields. Falls back to plain model_dump() if include= is not supported (TypeError), keeping compatibility with custom response wrappers.

Tests

  • test_model_dump_prefers_include_for_cost — confirms include= is passed on the primary path
  • test_model_dump_include_fallback_to_plain_dump — confirms the TypeError fallback still computes cost
  • Cost path assertions are conditional on GENAI_PRICES_AVAILABLE so environments where the pricing backend cannot import (e.g. pydantic 2.4 matrix) do not produce false failures

- Use model_dump(include=...) to pass only pricing fields

- Fall back to plain model_dump() when include is unsupported

- Add focused tests for include path and fallback path
- Run include/fallback assertions only when pricing backend is available
- Prevent false failures on pydantic 2.4 job
Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

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

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 2 additional findings.

Open in Devin Review

@alexmojaki
Copy link
Copy Markdown
Collaborator

The complication not mentioned in the issue is that this should only apply to embeddings responses so that it doesn't get in the way of pydantic/genai-prices#290 in the future.

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 28, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

- use model_dump(include={'model', 'usage'}) only for openai embeddings

- keep plain model_dump() for chat, responses, and non-openai providers

- align tests with scoped behavior and keep ci-matrix-safe assertions
@imp-joshi imp-joshi force-pushed the fix/1844-avoid-full-model-dump-cost-calculation branch from 4d8ccde to d66bae2 Compare April 28, 2026 14:55
@imp-joshi
Copy link
Copy Markdown
Contributor Author

imp-joshi commented Apr 28, 2026

The latest CI failure looks unrelated to this PR. The changed usage tests passed, and the failure is a timeout in the docs/loguru runnable example. (see line:258)
The exact same ci test on python 3.12 ran successully in its ealier commit d66bae2

Comment thread logfire/_internal/integrations/llm_providers/usage.py Outdated
Comment thread logfire/_internal/integrations/llm_providers/usage.py Outdated
imp-joshi and others added 4 commits April 29, 2026 09:39
- remove defensive TypeError fallback for include model_dump

- keep scoped include path for openai embeddings only

- drop fallback-only test and keep scoped behavior coverage
@alexmojaki
Copy link
Copy Markdown
Collaborator

thanks!

Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 1 new potential issue.

View 2 additional findings in Devin Review.

Open in Devin Review

Comment thread tests/otel_integrations/test_llm_usage_attributes.py
@alexmojaki alexmojaki enabled auto-merge (squash) April 29, 2026 10:11
@alexmojaki alexmojaki merged commit fe970e0 into pydantic:main Apr 29, 2026
19 checks passed
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.

Avoid full response model_dump() for cost calculation in GenAI usage tracking

2 participants