hermes - ✅(Solved) Fix bug: MiniMax M2.7 / minimax-cn provider cost always 0 — missing billing route and pricing entry in usage_pricing.py [2 pull requests, 1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
NousResearch/hermes-agent#16825Fetched 2026-04-29 06:38:50
View on GitHub
Comments
1
Participants
2
Timeline
9
Reactions
0
Author
Participants
Timeline (top)
labeled ×4cross-referenced ×3commented ×1referenced ×1

When using MiniMax-M2.7 via the minimax-cn provider (base URL https://api.minimaxi.com/anthropic), all sessions are recorded in state.db with estimated_cost_usd = 0.0 and cost_status = 'unknown'. The /usage command in both CLI and gateway also reports $0.0000. Users who run Hermes against MiniMax's own API endpoint have no visibility into cost at all.


Root Cause

Two separate gaps in agent/usage_pricing.py:

Fix Action

Fixed

PR fix notes

PR #16828: fix: add minimax-cn billing route to resolve cost_status='unknown' (#16825)

Description (problem / solution / changelog)

Problem

Closes #16825

When using MiniMax-M2.7 via the minimax-cn provider (https://api.minimaxi.com/anthropic), all sessions are stored in state.db with cost_status='unknown' and estimated_cost_usd=0.0. The /usage command shows $0.0000 for every session.

Root cause: resolve_billing_route() had no branch for minimax-cn, so it fell through to the final catch-all and returned billing_mode='unknown'. This caused estimate_usage_cost() to return CostResult(amount_usd=None, status='unknown').

Fix

Add an explicit minimax-cn branch in resolve_billing_route() that returns billing_mode='official_docs_snapshot', and add per-token pricing entries for all MiniMax models in _OFFICIAL_DOCS_PRICING.

MiniMax's API offers both a subscription Token Plan (requests/5hrs quota) and pay-as-you-go per-token pricing. We always apply the official pay-as-you-go rates so users can see the token-equivalent cost of their usage regardless of which plan they are on. This lets subscription users understand the savings they receive compared to pay-as-you-go.

Pricing sourced from: https://platform.minimax.io/docs/guides/pricing-paygo

ModelInputOutputCache ReadCache Write
MiniMax-M2.7$0.30/M$1.20/M$0.06/M$0.375/M
MiniMax-M2.7-highspeed$0.60/M$2.40/M$0.06/M$0.375/M
MiniMax-M2.5$0.30/M$1.20/M$0.03/M$0.375/M
MiniMax-M2.5-highspeed$0.60/M$2.40/M$0.03/M$0.375/M

Detection works both by provider="minimax-cn" and by base_url host match on minimaxi.com.

Changes

  • agent/usage_pricing.py — add minimax-cn route in resolve_billing_route() with billing_mode='official_docs_snapshot', and 4 pricing entries in _OFFICIAL_DOCS_PRICING
  • tests/agent/test_usage_pricing.py — add 4 regression tests:
    • test_minimax_cn_route_resolves_to_official_docs_snapshot
    • test_minimax_cn_cost_result_is_estimated_with_official_rates
    • test_minimax_cn_detected_by_base_url_host
    • test_minimax_cn_pricing_entry_uses_official_paygo_rates

Verification

13 passed in 4.96s

All existing tests pass; 4 new regression tests added and passing.

Changed files

  • agent/usage_pricing.py (modified, +57/-0)
  • tests/agent/test_usage_pricing.py (modified, +68/-0)

PR #16854: fix(usage_pricing): add minimax-cn billing route and regression tests

Description (problem / solution / changelog)

Problem

When using MiniMax-M2.7 via the minimax-cn provider, all sessions are recorded in state.db with estimated_cost_usd = 0.0 and cost_status = 'unknown'. The /usage command in both CLI and gateway also reports $0.0000.

Root Cause

resolve_billing_route() in agent/usage_pricing.py had no branch for minimax-cn, causing it to fall through to the catch-all with billing_mode="unknown".

Solution

  • Add a minimax-cn route in resolve_billing_route() that returns billing_mode="subscription_included" (MiniMax uses a request-quota subscription plan).
  • Add regression tests in tests/agent/test_usage_pricing.py.

Changes

  • agent/usage_pricing.py: add minimax-cn billing route
  • tests/agent/test_usage_pricing.py: add regression tests for minimax-cn route and cost estimation

Fixes #16825

Changed files

  • agent/usage_pricing.py (modified, +2/-0)
  • tests/agent/test_usage_pricing.py (modified, +18/-0)

Code Example

# agent/usage_pricing.py  (current)
def resolve_billing_route(model_name, provider=None, base_url=None):
    ...
    if provider_name == "openrouter" or base_url_host_matches(base_url or "", "openrouter.ai"):
        return BillingRoute(..., billing_mode="official_models_api")
    if provider_name == "anthropic":
        return BillingRoute(..., billing_mode="official_docs_snapshot")
    if provider_name == "openai":
        return BillingRoute(..., billing_mode="official_docs_snapshot")
    ...
    # ← minimax-cn falls through to the final catch-all:
    return BillingRoute(provider=provider_name or "unknown", ..., billing_mode="unknown")

---

estimate_usage_cost("MiniMax-M2.7", usage, provider="minimax-cn",
                    base_url="https://api.minimaxi.com/anthropic")
resolve_billing_route(...)  →  billing_mode="unknown"
get_pricing_entry(...)
fetch_endpoint_model_metadata(base_url)  →  no pricing field
_lookup_official_docs_pricing(route)None  (no entry)
  → entry is None
CostResult(amount_usd=None, status="unknown", source="none")

---

from agent.usage_pricing import resolve_billing_route, get_pricing_entry, estimate_usage_cost, CanonicalUsage

route = resolve_billing_route("MiniMax-M2.7", provider="minimax-cn",
                              base_url="https://api.minimaxi.com/anthropic")
print(route)
# BillingRoute(provider='minimax-cn', model='MiniMax-M2.7',
#              base_url='https://api.minimaxi.com/anthropic', billing_mode='unknown')

entry = get_pricing_entry("MiniMax-M2.7", provider="minimax-cn",
                          base_url="https://api.minimaxi.com/anthropic")
print(entry)
# None

result = estimate_usage_cost("MiniMax-M2.7",
                             CanonicalUsage(input_tokens=10000, output_tokens=500,
                                           cache_read_tokens=5000),
                             provider="minimax-cn",
                             base_url="https://api.minimaxi.com/anthropic")
print(result)
# CostResult(amount_usd=None, status='unknown', source='none', label='n/a', ...)

---

cost_status:         'unknown'   (100% of sessions)
cost_source:         'none'      (100% of sessions)
estimated_cost_usd:  0.0         (100% of sessions)
actual_cost_usd:     None        (100% of sessions)

---

# Add before the final catch-all return:
if provider_name == "minimax-cn" or base_url_host_matches(base_url or "", "minimaxi.com"):
    return BillingRoute(
        provider="minimax-cn",
        model=model,
        base_url=base_url or "",
        billing_mode="subscription_included",  # MiniMax uses a request-quota subscription plan
    )

---

(
    "minimax-cn",
    "minimax-m2.7",
): PricingEntry(
    input_cost_per_million=Decimal("0.30"),
    output_cost_per_million=Decimal("1.20"),
    source="official_docs_snapshot",
    source_url="https://openrouter.ai/minimax/minimax-m2.7",
    pricing_version="minimax-pricing-2026-04",
),

---

def test_minimax_cn_route_resolves_to_subscription_included():
    route = resolve_billing_route("MiniMax-M2.7", provider="minimax-cn",
                                  base_url="https://api.minimaxi.com/anthropic")
    assert route.provider == "minimax-cn"
    assert route.billing_mode == "subscription_included"

def test_minimax_cn_cost_result_is_included_not_unknown():
    result = estimate_usage_cost("MiniMax-M2.7",
                                 CanonicalUsage(input_tokens=10000, output_tokens=500),
                                 provider="minimax-cn",
                                 base_url="https://api.minimaxi.com/anthropic")
    assert result.status == "included"
    assert result.amount_usd == Decimal("0")
RAW_BUFFERClick to expand / collapse

Summary

When using MiniMax-M2.7 via the minimax-cn provider (base URL https://api.minimaxi.com/anthropic), all sessions are recorded in state.db with estimated_cost_usd = 0.0 and cost_status = 'unknown'. The /usage command in both CLI and gateway also reports $0.0000. Users who run Hermes against MiniMax's own API endpoint have no visibility into cost at all.


Root Cause

Two separate gaps in agent/usage_pricing.py:

1. resolve_billing_route() — no route for minimax-cn

# agent/usage_pricing.py  (current)
def resolve_billing_route(model_name, provider=None, base_url=None):
    ...
    if provider_name == "openrouter" or base_url_host_matches(base_url or "", "openrouter.ai"):
        return BillingRoute(..., billing_mode="official_models_api")
    if provider_name == "anthropic":
        return BillingRoute(..., billing_mode="official_docs_snapshot")
    if provider_name == "openai":
        return BillingRoute(..., billing_mode="official_docs_snapshot")
    ...
    # ← minimax-cn falls through to the final catch-all:
    return BillingRoute(provider=provider_name or "unknown", ..., billing_mode="unknown")

minimax-cn hits the final return with billing_mode="unknown".

2. _OFFICIAL_DOCS_PRICING — no entry for ("minimax-cn", "minimax-m2.7")

get_pricing_entry() tries fetch_endpoint_model_metadata("https://api.minimaxi.com/anthropic", ...) but the MiniMax Anthropic-compatible endpoint returns no pricing in its /models response, so the lookup returns None.

Observed call chain

estimate_usage_cost("MiniMax-M2.7", usage, provider="minimax-cn",
                    base_url="https://api.minimaxi.com/anthropic")
  → resolve_billing_route(...)  →  billing_mode="unknown"
  → get_pricing_entry(...)
      → fetch_endpoint_model_metadata(base_url)  →  no pricing field
      → _lookup_official_docs_pricing(route)      →  None  (no entry)
  → entry is None
  → CostResult(amount_usd=None, status="unknown", source="none")

Verified with a Python repro

from agent.usage_pricing import resolve_billing_route, get_pricing_entry, estimate_usage_cost, CanonicalUsage

route = resolve_billing_route("MiniMax-M2.7", provider="minimax-cn",
                              base_url="https://api.minimaxi.com/anthropic")
print(route)
# BillingRoute(provider='minimax-cn', model='MiniMax-M2.7',
#              base_url='https://api.minimaxi.com/anthropic', billing_mode='unknown')

entry = get_pricing_entry("MiniMax-M2.7", provider="minimax-cn",
                          base_url="https://api.minimaxi.com/anthropic")
print(entry)
# None

result = estimate_usage_cost("MiniMax-M2.7",
                             CanonicalUsage(input_tokens=10000, output_tokens=500,
                                           cache_read_tokens=5000),
                             provider="minimax-cn",
                             base_url="https://api.minimaxi.com/anthropic")
print(result)
# CostResult(amount_usd=None, status='unknown', source='none', label='n/a', ...)

Database evidence

197 sessions accumulated over 5 days, all via minimax-cn:

cost_status:         'unknown'   (100% of sessions)
cost_source:         'none'      (100% of sessions)
estimated_cost_usd:  0.0         (100% of sessions)
actual_cost_usd:     None        (100% of sessions)

Published Pricing (MiniMax M2.7)

SourceInput $/1MOutput $/1M
OpenRouter (minimax/minimax-m2.7)$0.30$1.20
MiniMax Platform (platform.minimax.io)subscription-based (request quota per plan)

OpenRouter source: https://openrouter.ai/minimax/minimax-m2.7

Note: MiniMax's own API (api.minimaxi.com) uses a subscription token-plan model (requests/5hrs quota per tier), so cost tracking for direct minimax-cn access is arguably best expressed as billing_mode="subscription_included" (same pattern as openai-codex) — which would at least surface a meaningful "included" status instead of "unknown".


Recommended Fix

Two changes in agent/usage_pricing.py:

Fix 1 — Add minimax-cn route in resolve_billing_route()

# Add before the final catch-all return:
if provider_name == "minimax-cn" or base_url_host_matches(base_url or "", "minimaxi.com"):
    return BillingRoute(
        provider="minimax-cn",
        model=model,
        base_url=base_url or "",
        billing_mode="subscription_included",  # MiniMax uses a request-quota subscription plan
    )

This makes /usage report "included" rather than "unknown", which is truthful for subscription users.

Fix 2 — Optionally add pay-per-token pricing for OpenRouter route of MiniMax M2.7

For users accessing MiniMax M2.7 via OpenRouter (provider="openrouter"), pricing is already fetched dynamically from the OpenRouter models API — no static entry needed for that path.

If direct pay-per-token MiniMax billing should be supported in future, a static entry would look like:

(
    "minimax-cn",
    "minimax-m2.7",
): PricingEntry(
    input_cost_per_million=Decimal("0.30"),
    output_cost_per_million=Decimal("1.20"),
    source="official_docs_snapshot",
    source_url="https://openrouter.ai/minimax/minimax-m2.7",
    pricing_version="minimax-pricing-2026-04",
),

Fix 3 — Add regression tests in tests/agent/test_usage_pricing.py

def test_minimax_cn_route_resolves_to_subscription_included():
    route = resolve_billing_route("MiniMax-M2.7", provider="minimax-cn",
                                  base_url="https://api.minimaxi.com/anthropic")
    assert route.provider == "minimax-cn"
    assert route.billing_mode == "subscription_included"

def test_minimax_cn_cost_result_is_included_not_unknown():
    result = estimate_usage_cost("MiniMax-M2.7",
                                 CanonicalUsage(input_tokens=10000, output_tokens=500),
                                 provider="minimax-cn",
                                 base_url="https://api.minimaxi.com/anthropic")
    assert result.status == "included"
    assert result.amount_usd == Decimal("0")

Files Affected

  • agent/usage_pricing.pyresolve_billing_route() (and optionally _OFFICIAL_DOCS_PRICING)
  • tests/agent/test_usage_pricing.py — regression tests for minimax-cn route

extent analysis

TL;DR

To fix the issue with MiniMax-M2.7 usage cost estimation, update the resolve_billing_route function in agent/usage_pricing.py to include a route for minimax-cn with billing_mode="subscription_included".

Guidance

  1. Update resolve_billing_route: Add a condition to check for minimax-cn provider or minimaxi.com base URL and return a BillingRoute with billing_mode="subscription_included".
  2. Optionally add pay-per-token pricing: If direct pay-per-token MiniMax billing is desired, add a static entry to _OFFICIAL_DOCS_PRICING with the pricing details.
  3. Add regression tests: Create tests in tests/agent/test_usage_pricing.py to verify the minimax-cn route resolves to subscription_included and the cost result is included instead of unknown.

Example

# agent/usage_pricing.py
def resolve_billing_route(model_name, provider=None, base_url=None):
    ...
    if provider_name == "minimax-cn" or base_url_host_matches(base_url or "", "minimaxi.com"):
        return BillingRoute(
            provider="minimax-cn",
            model=model,
            base_url=base_url or "",
            billing_mode="subscription_included",
        )
    ...

Notes

The provided fix assumes that the minimax-cn provider uses a subscription-based model, and the cost should be reported as included instead of unknown. If the pricing model changes, the fix may need to be updated accordingly.

Recommendation

Apply the workaround by updating the resolve_billing_route function to include the minimax-cn route with billing_mode="subscription_included", as this will provide a more accurate representation of the cost for MiniMax-M2.7 usage.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING