mirror of
https://github.com/openswarm-ai/openswarm.git
synced 2026-09-09 03:07:45 +02:00
[eric] models: Fable 5 back on both lanes (1-token probe 200, drill turn completed), Fable 5.1 API-key only (the pinned router's CLI version is refused on the sub lane), gpt-5.4 off the ChatGPT lane (OpenAI refuses it), Sonnet 5 at its $2/$10 rate
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
e188b704f8
commit
96cb953a27
@@ -20,6 +20,10 @@ MODEL_TIERS: dict[str, tuple[int, int, int]] = {
|
||||
"anthropic/claude-opus-4": (5, 2, 5),
|
||||
"claude-sonnet-5": (5, 4, 3),
|
||||
"anthropic/claude-sonnet-5": (5, 4, 3),
|
||||
"claude-fable-5-1": (5, 2, 5),
|
||||
"anthropic/claude-fable-5-1": (5, 2, 5),
|
||||
"claude-fable-5": (5, 2, 5),
|
||||
"anthropic/claude-fable-5": (5, 2, 5),
|
||||
"claude-sonnet-4-6": (4, 4, 3),
|
||||
"claude-sonnet-4.6": (4, 4, 3),
|
||||
"anthropic/claude-sonnet-4.6": (4, 4, 3),
|
||||
|
||||
@@ -39,6 +39,12 @@ BUILTIN_MODELS: dict[str, list[dict[str, Any]]] = {
|
||||
# Opus 5 (added 2026-07-26): drop-in Opus 4.8 successor, same $5/$25, 1M ctx, 128k out. Thinking is ON by default; explicit thinking:disabled is only valid at effort<=high, which is all this app ever sends (run_options_helpers caps at "high"), so the off toggle stays safe.
|
||||
{"value": "opus-5", "label": "Claude Opus 5", "context_window": 1_000_000,
|
||||
"model_id": "claude-opus-5", "router_model_id": "cc/claude-opus-5", "api": "anthropic", "reasoning": True},
|
||||
# Fable 5.1 (current, $10/$50, 1M ctx, 128k out, adaptive thinking always on) is API-KEY ONLY here: the pinned
|
||||
# 9router 0.3.60 presents itself to Anthropic as "claude-cli/2.1.63" and the subscription endpoint answers
|
||||
# "Claude Code 2.1.63 does not support this model; version 2.1.251 or newer is required" (probed 2026-09-06).
|
||||
# Fable 5 (legacy, same price, retire not before 2027-06-09) serves on the subscription lane: 1-token probe 200.
|
||||
{"value": "fable-5", "label": "Claude Fable 5", "context_window": 1_000_000,
|
||||
"model_id": "claude-fable-5", "router_model_id": "cc/claude-fable-5", "api": "anthropic", "reasoning": True},
|
||||
# Opus 4.8 (released 2026-05-28): previous Opus flagship. Adaptive thinking (not extended), effort param defaults to high. 1M ctx, 128k max output, $5/$25. Verified live on the cc sub route (this app runs on it) and the API.
|
||||
{"value": "opus-4-8", "label": "Claude Opus 4.8", "context_window": 1_000_000,
|
||||
"model_id": "claude-opus-4-8", "router_model_id": "cc/claude-opus-4-8", "api": "anthropic", "reasoning": True},
|
||||
@@ -52,11 +58,14 @@ BUILTIN_MODELS: dict[str, list[dict[str, Any]]] = {
|
||||
"model_id": "claude-sonnet-4-6", "router_model_id": "cc/claude-sonnet-4-6", "api": "anthropic", "reasoning": True},
|
||||
{"value": "opus", "label": "Claude Opus 4.6", "context_window": 1_000_000,
|
||||
"model_id": "claude-opus-4-6", "router_model_id": "cc/claude-opus-4-6", "api": "anthropic", "reasoning": True},
|
||||
# Retirement "not sooner than October 15, 2026", the soonest in this catalog (model page, read 2026-09-06); no model here is retired today.
|
||||
{"value": "haiku", "label": "Claude Haiku 4.5", "context_window": 200_000,
|
||||
"model_id": "claude-haiku-4-5", "router_model_id": "cc/claude-haiku-4-5-20251001", "api": "anthropic", "reasoning": True},
|
||||
# cc/ pins the user's Claude sub regardless of connection_mode.
|
||||
{"value": "opus-5-cc", "label": "Claude Opus 5", "context_window": 1_000_000,
|
||||
"model_id": "claude-opus-5", "router_model_id": "cc/claude-opus-5", "api": "anthropic", "reasoning": True, "route": "cc"},
|
||||
{"value": "fable-5-cc", "label": "Claude Fable 5", "context_window": 1_000_000,
|
||||
"model_id": "claude-fable-5", "router_model_id": "cc/claude-fable-5", "api": "anthropic", "reasoning": True, "route": "cc"},
|
||||
{"value": "opus-4-8-cc", "label": "Claude Opus 4.8", "context_window": 1_000_000,
|
||||
"model_id": "claude-opus-4-8", "router_model_id": "cc/claude-opus-4-8", "api": "anthropic", "reasoning": True, "route": "cc"},
|
||||
{"value": "opus-4-7-cc", "label": "Claude Opus 4.7", "context_window": 1_000_000,
|
||||
@@ -73,6 +82,10 @@ BUILTIN_MODELS: dict[str, list[dict[str, Any]]] = {
|
||||
# Fable 5 re-added 2026-07-02 after the ban lifted (Eric confirmed access is back); pull both rows again if it errors live.
|
||||
{"value": "opus-5-api", "label": "Claude Opus 5 (API key)", "context_window": 1_000_000,
|
||||
"model_id": "claude-opus-5", "router_model_id": "claude-opus-5", "api": "anthropic", "reasoning": True, "route": "api"},
|
||||
{"value": "fable-5-1-api", "label": "Claude Fable 5.1 (API key)", "context_window": 1_000_000,
|
||||
"model_id": "claude-fable-5-1", "router_model_id": "claude-fable-5-1", "api": "anthropic", "reasoning": True, "route": "api"},
|
||||
{"value": "fable-5-api", "label": "Claude Fable 5 (API key)", "context_window": 1_000_000,
|
||||
"model_id": "claude-fable-5", "router_model_id": "claude-fable-5", "api": "anthropic", "reasoning": True, "route": "api"},
|
||||
{"value": "opus-4-8-api", "label": "Claude Opus 4.8 (API key)", "context_window": 1_000_000,
|
||||
"model_id": "claude-opus-4-8", "router_model_id": "claude-opus-4-8", "api": "anthropic", "reasoning": True, "route": "api"},
|
||||
{"value": "opus-4-7-api", "label": "Claude Opus 4.7 (API key)", "context_window": 1_000_000,
|
||||
@@ -111,9 +124,7 @@ BUILTIN_MODELS: dict[str, list[dict[str, Any]]] = {
|
||||
{"value": "gpt-5.5", "label": "GPT-5.5",
|
||||
"context_window": 1_000_000, "router_model_id": "cx/gpt-5.5",
|
||||
"api": "codex", "subscription_only": True, "reasoning": True},
|
||||
{"value": "gpt-5.4", "label": "GPT-5.4",
|
||||
"context_window": 1_000_000, "router_model_id": "cx/gpt-5.4",
|
||||
"api": "codex", "subscription_only": True, "reasoning": True},
|
||||
# gpt-5.4 has no ChatGPT-lane row: OpenAI refuses it there ("not supported when using Codex with a ChatGPT account", 400, drilled 2026-09-06); the API-key row below stays, unverified on this box.
|
||||
{"value": "gpt-5.4-mini", "label": "GPT-5.4 Mini",
|
||||
"context_window": 400_000, "router_model_id": "cx/gpt-5.4-mini",
|
||||
"api": "codex", "subscription_only": True, "reasoning": True},
|
||||
@@ -409,7 +420,10 @@ def get_context_window(provider: str, model: str, settings: AppSettings | None =
|
||||
COST_PER_1M_TOKENS: dict[tuple[str, str], tuple[float, float]] = {
|
||||
# (provider, model): (input_cost_per_1M, output_cost_per_1M) NOTE: real cost numbers come from 9Router's usage stats. These entries are kept so the table matches BUILTIN_MODELS and can be used by any future native-loop path. Subscription-routed models are zero-cost to the user, but API rates are recorded here for reference where they exist. Anthropic (direct API rates).
|
||||
("Anthropic", "sonnet"): (3.0, 15.0),
|
||||
("Anthropic", "sonnet-5"): (3.0, 15.0),
|
||||
("Anthropic", "sonnet-5"): (2.0, 10.0),
|
||||
# Fable 5 (legacy, retire not before 2027-06-09) and Fable 5.1, both $10 / $50 (platform.claude.com model pages, read 2026-09-06).
|
||||
("Anthropic", "fable-5"): (10.0, 50.0),
|
||||
("Anthropic", "fable-5-1"): (10.0, 50.0),
|
||||
("Anthropic", "opus"): (5.0, 25.0),
|
||||
("Anthropic", "opus-4-7"): (5.0, 25.0),
|
||||
("Anthropic", "opus-4-8"): (5.0, 25.0),
|
||||
|
||||
@@ -672,16 +672,18 @@ def test_banned_models_not_offered():
|
||||
selectable and simply did not work, and Opus covers the same ground.)"""
|
||||
from backend.apps.agents.providers.registry import BUILTIN_MODELS
|
||||
all_values = {m["value"] for models in BUILTIN_MODELS.values() for m in models}
|
||||
for dead in ("gemini-3.1-pro", "gemini-3.1-pro-api", "gemini-3-flash", "gemini-3-flash-api",
|
||||
"fable-5-cc", "fable-5-api"):
|
||||
# Fable 5 left this list 2026-09-06: a 1-token probe on cc/claude-fable-5 through the pinned router answered 200
|
||||
# with a real completion and a drill turn on the sub lane completed. gpt-5.4 (cx) joined it the same day: OpenAI
|
||||
# answers "The 'gpt-5.4' model is not supported when using Codex with a ChatGPT account" (400, deterministic).
|
||||
for dead in ("gemini-3.1-pro", "gemini-3.1-pro-api", "gemini-3-flash", "gemini-3-flash-api", "gpt-5.4"):
|
||||
assert dead not in all_values, f"{dead} is back in the picker"
|
||||
assert "gpt-5.5-api" in all_values
|
||||
assert "gpt-5.5" in all_values # cx lane restored 2026-07-26 (live-probed)
|
||||
# No '3.1 pro' label survives in any provider group either.
|
||||
all_labels = " | ".join(m["label"].lower() for models in BUILTIN_MODELS.values() for m in models)
|
||||
assert "3.1 pro" not in all_labels
|
||||
assert "fable" not in all_labels
|
||||
assert "gemini 3 flash" not in all_labels
|
||||
assert "gpt-5.4" not in {m["value"] for m in BUILTIN_MODELS["OpenAI"] if m.get("api") == "codex"}
|
||||
|
||||
|
||||
# =========================================================================== Group E, 9Router-streamed 401 detection =========================================================================== 9Router sometimes returns upstream auth failures AS the assistant's reply text, not as an exception. We detect the pattern in the stream handler to substitute a friendly bubble.
|
||||
@@ -1189,9 +1191,10 @@ async def test_aux_returns_sonnet_when_preferred_tier_set():
|
||||
|
||||
def test_get_api_type_openai():
|
||||
from backend.apps.agents.providers.registry import get_api_type
|
||||
# gpt-5.4 maps to codex (the OpenAI-via-Codex-subscription api family)
|
||||
api = get_api_type("gpt-5.4")
|
||||
# gpt-5.5 maps to codex (the OpenAI-via-Codex-subscription api family); gpt-5.4 left that lane 2026-09-06.
|
||||
api = get_api_type("gpt-5.5")
|
||||
assert api in ("openai", "codex"), f"unexpected: {api}"
|
||||
assert get_api_type("gpt-5.4-api") == "openai"
|
||||
|
||||
|
||||
def test_find_builtin_model_returns_none_for_unknown():
|
||||
|
||||
Reference in New Issue
Block a user