Skip to content

Conversation

@divagr18
Copy link
Contributor

@divagr18 divagr18 commented Nov 29, 2025

Summary

This PR introduces a lightweight, opt-in mechanism for users to define model pricing (per million tokens) and automatically calculate cost estimates within Agno session metrics.
Currently, Agno tracks token usage but not the associated costs. Since pricing varies frequently by provider and date, this PR avoids hardcoding price tables. Instead, it provides a PricingConfig registry where users can define their own rates.
The new method works perfectly with both string model IDs and Agno Model objects.

Type of change

  • Bug fix
  • New feature
  • Breaking change
  • Improvement
  • Model update
  • Other:

Checklist

  • Code complies with style guidelines
  • Ran format/validation scripts (./scripts/format.sh and ./scripts/validate.sh)
  • Self-review completed
  • Documentation updated (comments, docstrings)
  • Examples and guides: Relevant cookbook examples have been included or updated (if applicable)
  • Tested in clean environment
  • Tests added/updated (if applicable)

Additional Notes

Key Changes:

  • New Utility (agno/utils/pricing.py): Added PricingConfig, a singleton registry to store model pricing, currency, and calculate costs.
  • Updated Metrics (agno/models/metrics.py):
    • Added fields: input_cost, output_cost, cache_read_cost, cache_write_cost, total_cost, and currency.
    • Updated __add__ to correctly sum costs when aggregating metrics.
    • Updated to_dict to format costs as decimal strings (e.g., "0.000025") to prevent scientific notation (e.g., 2.5e-05) in logs.
  • Model Integration (agno/models/base.py): Hooked calculate_cost() into the message population logic for both standard and streaming responses.

Features & DX Improvements:

  • Flexible Configuration: The PricingConfig.set_price() method works perfectly with both string IDs and Model objects.
    • Example: set_price(model="gpt-5.1", ...) works.
    • Example: set_price(model=my_gemini_instance, ...) also works (automatically extracts .id).
  • Granular Pricing: Supports input, output, cache read, and cache write tokens.
  • Currency Support: Users can define the currency symbol/code (default: "USD").
  • Zero Breaking Changes: If pricing is not set, cost fields remain None and are excluded from the metrics dictionary, ensuring no clutter for users who don't need this feature.

@divagr18 divagr18 requested a review from a team as a code owner November 29, 2025 20:37
@adiberk
Copy link
Contributor

adiberk commented Dec 2, 2025

Pretty awesome idea. Have you seen tokencost lib? Maybe it is something ee can use and users can instead add any overrides and or unsupported model coverage?

@divagr18
Copy link
Contributor Author

divagr18 commented Dec 2, 2025

Pretty awesome idea. Have you seen tokencost lib? Maybe it is something ee can use and users can instead add any overrides and or unsupported model coverage?

Thanks! Yep, I’ve seen tokencost, it’s super handy. For this PR though, I wanted to keep Agno fully flexible and provider-agnostic. Pricing changes fast, varies by region, and sometimes depends on custom enterprise deals, so letting users set their own rates keeps things accurate and avoids relying on a static table.

That said, I’d love to add an optional integration layer later. The registry is designed so something like tokencost → PricingConfig would be a clean plug-in, while Agno itself stays lightweight and dependency-free.

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