Skip to content

Anthropic prices no gateway-spelled model id, while the effort policy one file away normalizes them deliberately #940

Description

@sroussey

What

Two files in providers/anthropic disagree about what a Bedrock / Vertex model id is.

Anthropic_EffortPolicy.ts:18-28 strips the gateway prefix on purpose, and the docstring says why:

/** ... having them fall out of the parser as "not a Claude id at all". */
const GATEWAY_PREFIX = /^(?:[a-z0-9-]+\.)*anthropic\./i;

function isPreThinkingClaude(id: string): boolean {
  const parsed = parseAnthropicModelId(id.replace(GATEWAY_PREFIX, ""));
  ...

Anthropic_Pricing.ts:283 does not:

return resolveModelPricingFromTable(ANTHROPIC_PRICING, modelId, ["anthropic/"]);

["anthropic/"] is a slash-suffixed npm-style prefix. It does not match us.anthropic. / eu.anthropic. / anthropic..

Executed at 2d36880 (real modules, provider_config.model_name set):

id                                           effort.supported  effort.default   pricing
claude-sonnet-5                              6                 none             in=2 out=10 cached=0.2
us.anthropic.claude-sonnet-4-20250514-v1:0   6                 none             UNPRICED
anthropic.claude-3-5-sonnet-20241022-v2:0    0                 undefined        UNPRICED

Row 2 is the bug: the same model, on a gateway spelling the package explicitly supports for reasoning, resolves no rate card. Row 3 is correct for a different reason (pre-3.7, no dial) and is also unpriced, which it should not be — Claude 3.5 Sonnet has a published rate.

Why it matters

  • This is the safe direction — unpriced reports nothing rather than a wrong number — so it is lower severity than a fabricated rate. But it is silent: a host running Claude through Bedrock gets a cost estimate of "unknown" on every call with nothing saying why, while the reasoning dial works.
  • GATEWAY_PREFIX exists because this review asked for it (ModelEffortPolicy became a contract without its six regexes being revisited #859) and the fix argued the case explicitly: gateway spellings must "grade the same as native ids". Pricing is the other half of that same claim and was not updated with it.
  • assertPricedGapDoesNotGrow (pricingMatchesModality.ts:99-133), added this window, is exactly the assertion that would have caught it — KNOWN_UNPRICED.anthropic is [] — except no gateway-spelled id appears in PROVIDER_CASES (inferAdvertisesRegistered.test.ts:56-90), so the axis has nothing to fail on.

Proposed fix

  1. Strip the same prefix in getAnthropicModelPricing, from the same exported constant rather than a copy — the pattern Xai_Pricing.ts / Xai_EffortPolicy.ts adopted this window (export const XAI_IMAGE_MODEL, imported by pricing, "one matcher, so the two cannot drift"):

    // Anthropic_EffortPolicy.ts
    export const ANTHROPIC_GATEWAY_PREFIX = /^(?:[a-z0-9-]+\.)*anthropic\./i;
    
    // Anthropic_Pricing.ts
    export function getAnthropicModelPricing(modelId: string | undefined): ModelPricing | undefined {
      return resolveModelPricingFromTable(
        ANTHROPIC_PRICING,
        modelId?.replace(ANTHROPIC_GATEWAY_PREFIX, ""),
        ["anthropic/"]
      );
    }

    Note a gateway id also carries a -v1:0 suffix; KEY_SUFFIX_BOUNDARY admits - so claude-sonnet-4-20250514-v1:0 will walk back to claude-sonnet-4-* on its own, but confirm against the table rather than assuming.

  2. Add one gateway-spelled id to PROVIDER_CASES for anthropic, so assertPricedGapDoesNotGrow guards it thereafter. It fails today and passes after (1), which is the argument for adding it in the same commit.

Found during the 2026-09-14 review of providers/. Verified against origin/main @ 2d36880.

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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions