Skip to content

Model ref parsing misroutes gateway/URL provider IDs via substring match #2

Description

@grave0x

Problem

Provider selection uses substring matching on the whole model reference. provider_for_model (crates/llm/src/lib.rs:358-391) routes on model.contains("anthropic"), model.contains("claude"), model.contains("openai"), etc. And the session handler strips only a provider/model prefix (crates/server/src/handler/session.rs:270model.split('/').nth(1)).

A gateway-connected model reference like http://127.0.0.1:8787/v1#claude-sonnet-4-5 or http://gateway:port/model/claude-x contains "claude" → routed to Anthropic's real API with the gateway's key. url#model refs aren't parsed at all.

This mirrors upstream anomalyco/opencode#40071 ("fix(provider): parse URL-based provider IDs", closes #39926): parseModel only expected providerID/modelID and broke when the provider ID is itself a URL (gateway/.well-known models). Prompts work because IDs are sent separately, but combined command strings must be parsed server-side — exactly what crates/server/src/handler/session.rs does.

Impact

  • A model configured via OTHER_API_BASE_URL/gateway can be silently sent to the wrong endpoint.
  • Keys can leak to the wrong provider; responses come back malformed or fail auth.

Spec / Acceptance criteria

  1. Implement a parse_model_ref(ref: &str) -> (provider, model) that handles, in order:
    • provider/model (e.g. anthropic/claude-sonnet-4)
    • url#model (e.g. http://host:port/v1#claude-x)
    • url/model gateway forms
    • bare model name (resolve via existing heuristics)
  2. In provider_for_model, match the parsed provider ID exactly (including "other"/extra providers by base URL) before any substring fallback. Never route a URL-bearing ref by substring.
  3. Session handler uses the parsed provider+model (drop the ad-hoc split('/').nth(1)).
  4. Tests: http://127.0.0.1:8787/v1#claude-sonnet-4-5 → routes to the local gateway provider, not Anthropic; deepseek/deepseek-chat → DeepSeek.

Reference: upstream anomalyco/opencode#40071 (closes #39926); our code: crates/llm/src/lib.rs:263-306, 358-391, crates/server/src/handler/session.rs:262-270.

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

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions