Skip to content

test: cover cache-aware effective cost; fix Anthropic cache-read field name - #47

Open
giladsamuels-cognition wants to merge 2 commits into
mainfrom
devin/1790797658-effective-cost-tests
Open

giladsamuels-cognition wants to merge 2 commits into
mainfrom
devin/1790797658-effective-cost-tests

Conversation

@giladsamuels-cognition

@giladsamuels-cognition giladsamuels-cognition commented Sep 30, 2026 •

Copy link
Copy Markdown

Summary

Adds unit tests for TrackAPIPricingMixin.get_effective_cost and its Anthropic/OpenAI variants using non-zero cached tokens, and fixes the bug the tests caught. Closes code-scan finding sfind-ba28615afd004752ba3b8515683639d9.

Production change (Anthropic path only): the code read cache-read tokens from a field that doesn't exist, so the 0 default applied and cache-read cost was always dropped from effective_cost. anthropic.types.Usage has cache_read_input_tokens, cache_creation_input_tokens, input_tokens, output_tokens and no cache_input_tokens. Both cache fields are Optional[int], so a null value now falls back to 0.

- cache_read_tokens = getattr(usage, "cache_input_tokens", 0)
- cache_write_tokens = getattr(usage, "cache_creation_input_tokens", 0)
+ cache_read_tokens = getattr(usage, "cache_read_input_tokens", 0) or 0
+ cache_write_tokens = getattr(usage, "cache_creation_input_tokens", 0) or 0

The create_mock_anthropic_response helper in tests/llm/test_response_api.py also set the old field name. It now sets the real one, otherwise the MagicMock would return a mock for the missing attribute.

New tests in tests/llm/test_tracking.py build usage objects with the real SDK types (anthropic.types.Usage, openai CompletionUsage / ResponseUsage) and fixed prices (input_cost=2e-6, output_cost=1e-5). They assert exact costs:

  • Anthropic: 100 new input + 50 output + 1000 cache-read (0.1x) + 200 cache-write (1.25x) → 1.4e-3. Also checks that cache reads are billed at the discount, and that missing or null (None) cache fields fall back to 0.
  • OpenAI chat completion (prompt_tokens_details present): 1000 prompt tokens, 600 of them cached (0.5x), + 100 output → 2.4e-3. Also covers prompt_tokens_details=None.
  • OpenAI Responses API (input_tokens_details branch): same numbers → 2.4e-3.
  • Fallbacks: usage is None or missing → 0.0; unsupported provider (openrouter, unknown, None) → 0.0; litellm delegates to completion_cost (patched).
  • End-to-end through TrackAPIPricingMixin.__call__: stats["effective_cost"], usage_cached_tokens and n_api_calls add up across calls. The tracker cost still bills all prompt tokens at the full price.

Without the field-name fix, the Anthropic cache-read tests fail. With it, uv run pytest tests/llm passes and black --check src/ is clean.

Devin-Org: engineering

Link to Devin session: https://app.devin.ai/sessions/190c921121af47b2956a84e336f23eef
Open in Devin Desktop: https://app.devin.ai/desktop/session/190c921121af47b2956a84e336f23eef?variant=devin
Requested by: @giladsamuels-cognition


Devin Review

…ut_tokens

Co-Authored-By: Gilad Samuels <gilad.samuels@cognition.ai>
@devin-ai-integration

Copy link
Copy Markdown

I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".

  • Disable automatic comment, CI, and merge conflict monitoring

devin-ai-integration[bot]

This comment was marked as resolved.

Co-Authored-By: Gilad Samuels <gilad.samuels@cognition.ai>
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.

1 participant