Skip to content

Cost is always $0 when routing through the vercel gateway provider #42

Description

@mostlydev

Summary

Any model routed through the vercel provider reports cost_usd = 0. claw audit shows COST_USD 0.0000 for every agent and model, and reported_cost_usd is absent from response telemetry.

Confirmed on cllama v0.9.0.

Cause

internal/cost/pricing.go keys the rate table by provider:

return &Pricing{rates: map[string]map[string]Rate{
    "anthropic":  {...},
    "openai":     {...},
    "openrouter": {...},
    "google":     {...},

There is no vercel entry, and Lookup returns early on an unknown provider:

func (p *Pricing) Lookup(provider, model string) (Rate, bool) {
    models, ok := p.rates[provider]
    if !ok {
        return Rate{}, false
    }

vercel is a first-class provider in internal/provider/provider.go (https://ai-gateway.vercel.sh/v1, keyed by AI_GATEWAY_API_KEY), so it is reachable but unpriceable.

There is a second layer to this. Gateway model ids carry their own sub-provider prefix, so a configured model looks like vercel/openai/gpt-5.6-luna and the model string reaching Lookup is openai/gpt-5.6-luna. Even with a vercel table added, keys like gpt-5.6-luna would not match unless the sub-provider prefix is stripped or the table is keyed by the full gateway id.

The existing prefix-match fallback does not help, because it only runs after the provider lookup has already succeeded.

Impact

Telemetry is the visible part, but internal/proxy/budget.go enforces spend on the same value:

if normalized.LimitUSD != nil && summary.ReportedCostUSD >= *normalized.LimitUSD {

A limit_usd budget on a gateway-routed service can therefore never trip — it silently does not enforce. unknown_cost_requests is tracked in the decision log, so the information needed to detect this already exists.

Suggested fix

Resolve pricing against the effective downstream provider and model rather than the routing provider: for gateway providers, split the sub-provider prefix off the model id and look the rate up under that provider's table. That reuses the existing per-provider rates instead of duplicating a table per gateway.

Failing that, at minimum surface the condition — a startup warning when a configured model resolves to no rate, and/or refuse to accept a limit_usd budget for a service whose model has no known rate, so an unenforceable budget fails loudly instead of silently.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions