Skip to content

fix(models): GPT-5.6 (Sol/Terra/Luna) + refresh OpenRouter's catalogue against the live API - #773

Merged
ericleepi314 merged 3 commits into
mainfrom
fix/openrouter-openai-models
Jul 31, 2026
Merged

fix(models): GPT-5.6 (Sol/Terra/Luna) + refresh OpenRouter's catalogue against the live API#773
ericleepi314 merged 3 commits into
mainfrom
fix/openrouter-openai-models

Conversation

@ericleepi314

Copy link
Copy Markdown
Collaborator

Summary

Refreshes OpenRouter's curated catalogue against the live API and adds OpenAI's current frontier generation, GPT-5.6.

GPT-5.6 (Sol / Terra / Luna). Three durable capability tiers on one generation rather than a size ladder: Sol is the flagship, Terra balances capability against cost, Luna is the cheap high-volume tier, and gpt-5.6 is OpenAI's alias for Sol. Offered by the direct provider and by OpenRouter, which also carries a -pro variant of each tier.

Ids came from OpenAI's own API docs rather than stripping OpenRouter's openai/ prefix — the direct API takes the bare id, and that equivalence needed confirming rather than assuming.

Model configs are the non-obvious half. Adding ids to a provider list isn't enough: without a ModelConfig these resolved through get_model_config's prefix fallback to the 272K catch-all, firing auto-compact roughly three quarters of a 1.05M window early.

Placement there is load-bearing. The fallback matches on key.rsplit("-", 1)[0], so the bare gpt-5.6 alias has base gpt and would become the catch-all for every unknown gpt id if it preceded gpt-5.5, handing them a 1.05M window. Over-estimating overflows the context; under-estimating only compacts early. So the catch-all stays on the 272K entry and the alias is registered after it, while the tier keys (base gpt-5.6) go first — which is what lets an unlisted variant like gpt-5.6-sol-pro inherit the right window. Exact lookups are unaffected by position.

OpenRouter's list had gone stale, and two entries were dead. The OpenAI section still led with gpt-5 / gpt-4o / o1, and openai/o1-mini had been delisted upstream entirely — a row the picker offers that fails at request time, the same "offers something you cannot select" shape as the picker bug in #772.

Validating the rest against https://openrouter.ai/api/v1/models caught five more dead ids: anthropic/claude-3.5-sonnet, anthropic/claude-3.5-haiku, google/gemini-2.0-flash, meta-llama/llama-3.1-405b-instruct, deepseek/deepseek-v3.2-speciale, x-ai/grok-2. All replaced with live successors. Every one of the 46 ids in the catalogue now resolves, including the default model.

Batch (:batch), image, audio and embedding variants stay out — none serves an interactive agent turn, and free-text ids are accepted regardless of this list.

Two duplicate lists removed. PROVIDER_INFO["openrouter"] was duplicated verbatim in OpenRouterProvider._curated_models(), and PROVIDER_INFO["openai"] in OpenAIProvider.get_available_models(). Each pair feeds different surfaces — the registry drives login and the /model picker, the copies drive discovery — so editing one shows up as a model one surface offers and the other drops. Both now read the registry. The subscription branch keeps its own list, since a ChatGPT plan serves a smaller set.

Deliberately unchanged

  • default_model stays gpt-5.4. The default is a cost-sensible tier, not the frontier — Anthropic likewise defaults to claude-sonnet-4-6 while listing claude-fable-5 first. Moving it would silently change cost and behaviour for everyone without an explicit --model.
  • SUBSCRIPTION_MODELS untouched. Which models the ChatGPT-subscription backend serves is a wire fact sourced from Codex CLI's cache. Guessing there breaks subscription sessions rather than showing a stale row.

Test Coverage

New tests/providers/test_openrouter_catalog.py (107 tests): the single-sourcing of both lists, ids vendor-qualified for OpenRouter and bare for the direct API, no :batch variants, the flagship-first tier ordering, the 1.05M windows, and the catch-all invariant.

Mutation-verified — each fix reverted and the intended test confirmed to fail:

Mutation Test that catches it
Move the gpt-5.6 alias above gpt-5.5 test_an_unknown_gpt_id_still_gets_the_conservative_catch_all
Restore either duplicate list test_provider_reads_the_registry_rather_than_a_second_copy
Order Luna ahead of Sol test_the_5_6_tiers_are_ordered_flagship_first
Re-add the delisted openai/o1-mini test_openai_section_leads_with_the_current_frontier

The tests deliberately do not hit the network: CI would otherwise fail whenever a vendor retires a model, which is a fact about the world rather than a defect in the diff. The file documents the revalidation command instead.

Test plan

  • Python suite: 9373 passed, 3 skipped, 0 failed
  • Every curated OpenRouter id verified resolvable against the live API
  • gpt-5.6, -sol, -terra, -luna resolve to 1.05M; gpt-5.6-sol-pro inherits it; an unknown gpt id still gets 272K

🤖 Generated with Claude Code

The OpenAI section still led with gpt-5 / gpt-4o / o1 while OpenRouter had
moved on to the gpt-5.6 generation, and openai/o1-mini had been delisted
upstream entirely — so the /model picker offered a row that fails at
request time, the same "offers something you cannot select" shape as the
picker bug in #772.

Validating the rest against https://openrouter.ai/api/v1/models caught
five more dead ids: anthropic/claude-3.5-sonnet, anthropic/claude-3.5-haiku,
google/gemini-2.0-flash, meta-llama/llama-3.1-405b-instruct,
deepseek/deepseek-v3.2-speciale and x-ai/grok-2. All are replaced with live
successors; every id in the catalogue now resolves.

Batch (:batch), image, audio and embedding variants stay out — none of them
serves an interactive agent turn, and free-text ids are accepted regardless
of this list.

The list was also duplicated verbatim between PROVIDER_INFO["openrouter"]
and OpenRouterProvider._curated_models(). Two lists for one set drift the
moment someone edits one, and the halves feed different surfaces — the
registry drives login and the picker, the other drives discovery's
curation — so the provider now reads the registry.
Sol, Terra and Luna are durable capability tiers on one generation rather
than a size ladder: Sol is the flagship, Terra balances capability against
cost, Luna is the cheap high-volume tier, and gpt-5.6 is OpenAI's alias for
Sol. Offered by the direct provider and by OpenRouter, which also carries a
-pro variant of each tier.

Each gets a real ModelConfig (1.05M context / 128K output). Without one they
resolved through get_model_config's prefix fallback to the 272K catch-all,
firing auto-compact about three quarters of a window early.

Placement is load-bearing. The fallback matches on key.rsplit("-", 1)[0], so
the bare gpt-5.6 alias has base "gpt" and would become the catch-all for
EVERY unknown gpt id if it preceded gpt-5.5 — handing them a 1.05M window.
Over-estimating overflows the context; under-estimating only compacts early,
so the catch-all stays on the 272K entry and the alias is registered after
it. The tier keys (base "gpt-5.6") go first, which is what lets an unlisted
variant like gpt-5.6-sol-pro inherit the right window.

default_model stays gpt-5.4 — the default is a cost-sensible tier, not the
frontier, matching Anthropic defaulting to sonnet-4-6 while listing fable-5
first. SUBSCRIPTION_MODELS is untouched: which models the ChatGPT backend
serves is a wire fact to observe, not assume.

OpenAIProvider.get_available_models kept a second verbatim copy of the
registry list, the same drift hazard as OpenRouter's; it now reads the
registry, leaving the subscription branch its own set.
@ericleepi314
ericleepi314 merged commit b51a606 into main Jul 31, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant