fix(server): advertise registry.default when model.default_alias is foreign

GET /v1/api/models blanked default_alias whenever model.default_alias named
an alias absent from the server's live registry — e.g. when a standalone
turnstone-server shares a ConfigStore with a console whose model.default_alias
points at a console-only / DB alias (or the underlying model id rather than
the alias). The interactive dashboard then showed a bare "Default model"
placeholder even though a new workstream launches on a concrete model.

Mirror session_factory's _effective_default_alias / _effective_routing: fall
back to registry.default (which already incorporates a *valid* model.default_alias
override) when the configured alias is unset or foreign, blanking only if
registry.default is itself unresolvable. The endpoint now reports the model
creation actually uses.
This commit is contained in:
Patrick Buckley
2026-05-29 13:05:58 -07:00
parent 3e5633f440
commit 8e32aa09d4
2 changed files with 35 additions and 6 deletions
+25 -3
View File
@@ -5,8 +5,10 @@ composer + the channel gateway. The dashboard's Options panel renders
each one as a "Default — alias (model)" placeholder, so the resolution
chain has to stay honest:
* ``default_alias`` ← ``model.default_alias``, falling back to the
registry default; blanked when it points at a disabled/removed alias.
* ``default_alias`` ← ``model.default_alias`` when it names an enabled
alias, otherwise ``registry.default`` (mirrors session_factory's
``_effective_default_alias`` — the model a new workstream actually launches
on). Only blanked when even ``registry.default`` is unresolvable.
* ``channel_default_alias`` ← ``channels.default_model_alias``.
* ``judge_default_alias`` ← ``judge.model``, but *only* when it names an
enabled alias. An unset / whitespace / unknown / disabled value stays
@@ -151,10 +153,30 @@ def test_model_default_falls_back_to_registry_default() -> None:
assert body["judge_default_alias"] == ""
def test_model_default_blanked_when_pointing_at_unknown_alias() -> None:
def test_model_default_foreign_alias_falls_back_to_registry_default() -> None:
"""``model.default_alias`` naming an alias absent from THIS server's
registry (e.g. a console-only alias leaking through a shared ConfigStore)
falls back to ``registry.default`` — the model creation actually uses —
rather than being blanked. Blanking made the dashboard show a bare
"Default model" placeholder even though a workstream would launch on a
concrete model."""
body = _get_models(
_make_client(
aliases={"primary": "vendor/primary"},
registry_default="primary",
settings={"model.default_alias": "ghost"},
)
)
assert body["default_alias"] == "primary"
def test_model_default_blanks_only_when_registry_default_also_unresolvable() -> None:
"""The defensive blank still applies when neither the configured alias
nor ``registry.default`` resolves to an enabled alias."""
body = _get_models(
_make_client(
aliases={"primary": "vendor/primary"},
registry_default="",
settings={"model.default_alias": "ghost"},
)
)
+10 -3
View File
@@ -1170,10 +1170,17 @@ async def list_available_models(request: Request) -> JSONResponse:
default_alias = cs.get("model.default_alias") or ""
channel_default_alias = cs.get("channels.default_model_alias") or ""
judge_default_alias = (cs.get("judge.model") or "").strip()
if not default_alias:
default_alias = registry.default
# Clear defaults that point to unknown/disabled aliases.
# Mirror session_factory's ``_effective_default_alias`` (and
# ``_effective_routing``): a ``model.default_alias`` that's unset — or
# names an alias absent from THIS server's registry — falls back to
# ``registry.default``, which is the model a new workstream actually
# launches on. Reporting "" here made the dashboard show a bare
# "Default model" placeholder even though creation has a concrete default
# (e.g. when the shared ConfigStore points at a console-only alias).
enabled_aliases = set(registry.list_aliases())
if default_alias not in enabled_aliases:
default_alias = registry.default
# Defensive: only blank if even registry.default is unknown/disabled.
if default_alias and default_alias not in enabled_aliases:
default_alias = ""
if channel_default_alias and channel_default_alias not in enabled_aliases: