Compare commits

...

2 Commits

Author SHA1 Message Date
teknium1
d270fe52b3 fix(pricing): correct host-match patterns + add tests (#15268)
The original PR's host-match pattern used 'nousresearch' (without
.com), but utils.base_url_host_matches does suffix-based host
matching and requires the full domain — so the base_url-inference
path never triggered and only the explicit provider='nous' /
provider='xai' branches worked.

Three changes:
- Fix the nous host pattern: 'nousresearch' → 'nousresearch.com'.
- Add the symmetric xai host pattern ('x.ai') so x.ai base URLs
  route correctly without an explicit provider name.  Mirrors how
  the openrouter branch already works.
- Five new tests in tests/agent/test_usage_pricing.py that lock
  in the routing contract for both providers AND both inference
  paths (explicit provider + base_url-only).

Also adds GumbyEnder to AUTHOR_MAP so the salvage attribution
check passes.
2026-05-25 14:56:34 -07:00
GumbyEnder
579fa6a1f7 feat(pricing): add provider routing for nous and xai
Route 'nous' and 'xai' providers to official_models_api billing mode
so cost estimation can attempt model metadata lookups at the endpoint
instead of falling through to 'unknown'.

This enables per-token cost tracking for Nous Research models
(qwen3.6-plus, etc.) and xAI models (grok-4-1-fast, etc.)
2026-05-25 14:54:14 -07:00
3 changed files with 64 additions and 0 deletions

View File

@@ -548,6 +548,10 @@ def resolve_billing_route(
return BillingRoute(provider="openai", model=model.split("/")[-1], base_url=base_url or "", billing_mode="official_docs_snapshot")
if provider_name in {"minimax", "minimax-cn"}:
return BillingRoute(provider=provider_name, model=model.split("/")[-1], base_url=base_url or "", billing_mode="official_docs_snapshot")
if provider_name == "nous" or base_url_host_matches(base_url or "", "nousresearch.com"):
return BillingRoute(provider="nous", model=(model.split("/")[-1] if model else model), base_url=base_url or "", billing_mode="official_models_api")
if provider_name == "xai" or base_url_host_matches(base_url or "", "x.ai"):
return BillingRoute(provider="xai", model=(model.split("/")[-1] if model else model), base_url=base_url or "", billing_mode="official_models_api")
if provider_name in {"custom", "local"} or (base and "localhost" in base):
return BillingRoute(provider=provider_name or "custom", model=model, base_url=base_url or "", billing_mode="unknown")
return BillingRoute(provider=provider_name or "unknown", model=model.split("/")[-1] if model else "", base_url=base_url or "", billing_mode="unknown")

View File

@@ -242,6 +242,7 @@ AUTHOR_MAP = {
"harryykyle1@gmail.com": "hharry11",
"wysie@users.noreply.github.com": "wysie",
"ronhi@buildabear1.localdomain": "RonHillDev", # PR #29523 salvage (machine-local commit email)
"48990701+GumbyEnder@users.noreply.github.com": "GumbyEnder", # PR #15268 salvage
"jkausel@gmail.com": "jkausel-ai",
"e.silacandmr@gmail.com": "Es1la",
"51599529+stephen0110@users.noreply.github.com": "stephen0110",

View File

@@ -5,6 +5,7 @@ from agent.usage_pricing import (
estimate_usage_cost,
get_pricing_entry,
normalize_usage,
resolve_billing_route,
)
@@ -224,3 +225,61 @@ def test_deepseek_v4_pro_estimate_usage_cost():
assert result.amount_usd is not None
# 1M input × $1.74/M + 500K output × $3.48/M = $1.74 + $1.74 = $3.48
assert float(result.amount_usd) == 3.48
def test_resolve_billing_route_routes_nous_to_official_models_api():
"""nous provider should route to its /models endpoint (#15268).
Pre-fix the route fell through to ``provider="unknown"`` and the
dashboard / CLI usage summary / session ledger showed \\$0.00 for
real Nous token consumption. Post-fix the route lands on
``billing_mode="official_models_api"`` and downstream pricing
resolution hits ``https://inference-api.nousresearch.com/v1/models``
which returns real per-token pricing in the standard
``{prompt, completion, ...}`` shape.
"""
route = resolve_billing_route(
"qwen3.6-plus",
provider="nous",
base_url="https://inference-api.nousresearch.com/v1",
)
assert route.provider == "nous"
assert route.model == "qwen3.6-plus"
assert route.billing_mode == "official_models_api"
def test_resolve_billing_route_routes_xai_to_official_models_api():
"""xai provider symmetric with nous — routes to /models for pricing."""
route = resolve_billing_route(
"grok-4-fast-reasoning",
provider="xai",
base_url="https://api.x.ai/v1",
)
assert route.provider == "xai"
assert route.model == "grok-4-fast-reasoning"
assert route.billing_mode == "official_models_api"
def test_resolve_billing_route_infers_nous_from_base_url_host():
"""Even without an explicit provider, a nousresearch.com base URL
should land on the nous route — guards against custom_providers
entries that point at Nous but forget the provider name."""
route = resolve_billing_route(
"qwen3.6-plus",
provider="",
base_url="https://inference-api.nousresearch.com/v1",
)
assert route.provider == "nous"
assert route.billing_mode == "official_models_api"
def test_resolve_billing_route_infers_xai_from_base_url_host():
"""Symmetric with nous — a x.ai base URL routes to the xai branch
even when the caller omits the provider name."""
route = resolve_billing_route(
"grok-4-fast-reasoning",
provider="",
base_url="https://api.x.ai/v1",
)
assert route.provider == "xai"
assert route.billing_mode == "official_models_api"