fix(pricing): price Venice models from live metadata - #49932
Conversation
teknium1
left a comment
There was a problem hiding this comment.
Thanks for tracing direct Venice calls through the pricing and Langfuse paths. Current main still lacks the Venice route: agent/usage_pricing.py:675 classifies direct api.venice.ai custom calls as unknown, while models.dev currently has a venice/kimi-k2-7-code pricing entry.
Problems
- The added
cost_details["total"]calculations atplugins/observability/langfuse/__init__.py:594and proposed line 1014 sum token buckets only. Canonical pricing also addsPricingEntry.request_costatagent/usage_pricing.py:966-967, so the transmitted total can be lower than Hermes' canonical estimate.
Suggested changes
- Populate
totalfrom canonicalestimate_usage_cost(...).amount_usdin both paths, while retaining the bucket breakdown. - Add request-cost coverage for both Langfuse usage paths.
This is an automated hermes-sweeper review.
| @@ -590,6 +590,8 @@ def _usage_and_cost(response: Any, *, provider: str, api_mode: str, model: str, | |||
| cost_details["cache_read_input_tokens"] = float(Decimal(canonical.cache_read_tokens) * entry.cache_read_cost_per_million / _ONE_M) | |||
| if entry.cache_write_cost_per_million is not None and canonical.cache_write_tokens: | |||
| cost_details["cache_creation_input_tokens"] = float(Decimal(canonical.cache_write_tokens) * entry.cache_write_cost_per_million / _ONE_M) | |||
| if cost_details: | |||
| cost_details["total"] = float(sum(Decimal(str(v)) for v in cost_details.values())) | |||
There was a problem hiding this comment.
estimate_usage_cost() also includes PricingEntry.request_cost (agent/usage_pricing.py:966-967), but this token-bucket sum does not. Please use the already-computed canonical cost.amount_usd for total (and apply the same fix to the sanitized-usage path) so Langfuse totals cannot understate request-priced routes.
|
Thanks for identifying that Langfuse needs an explicit I reproduced the generic failure on current Because that contract fix is cross-provider and independent of this PR's Venice pricing work, and this head branch does not allow maintainer edits, I am preparing a narrowly scoped current-main PR that changes only the Langfuse plugin and its tests. It will use the canonical estimate in both active paths, include cache + request-cost regression coverage, and explicitly credit/cross-link this PR and @rdguidry. The Venice route and pricing scope remain entirely here. |
7af999e to
cb34a17
Compare
Summary
api.venice.aicustom-provider calls as Venice billing routes.model_spec.pricing.{input,output,cache_input}.usdvalues fromGET /modelsand convert USD-per-million-token rates into Hermes' per-token metadata format.Why
Hermes profiles can configure Venice through the generic
customprovider withhttps://api.venice.ai/api/v1. Current routing classifies that as an unknown custom endpoint, and Venice publishes pricing in nested objects that the generic parser cannot consume. As a result, direct Venice usage is unpriced in Langfuse; some nested payloads can also trigger parser exceptions.The earlier version of this PR included a generic Langfuse
costDetails.totalchange. That cross-provider work is intentionally removed here because #64797 now owns that concern. This revision is limited to Venice routing, metadata parsing, credential scoping, and regression coverage.User impact
Direct Venice calls can use the provider's live model prices for token-cost accounting, including cache-read pricing. Custom non-Venice endpoints receive no inferred Venice or OpenAI credential.
Validation
uv run --extra dev --frozen pytest -q tests/agent/test_usage_pricing.py tests/hermes_cli/test_api_key_providers.py tests/plugins/test_langfuse_plugin.py— 272 passeduv run --extra dev --frozen ruff check agent/model_metadata.py agent/usage_pricing.py plugins/observability/langfuse/__init__.py tests/agent/test_usage_pricing.py tests/hermes_cli/test_api_key_providers.py tests/plugins/test_langfuse_plugin.pygit diff --check