config: honor same-path multi-config at runtime (key siblings by alias)

The web UI stores sibling configs for one model file (distinct config_id, e.g. a
smaller-context variant), and the front already routes by alias (_route_key:
"two configs of the same model with distinct aliases can be assigned to
different engines"). But engine startup keyed every text-model config by path
(_model_id -> path), so a second same-path entry OVERWROTE the first —
BOTH aliases then resolved to the last-registered config (verified: lisa and
lisa-32k both got n_ctx=32768, silently changing the primary too).

Fix: in main.py text-model registration, key the PRIMARY config by path (stays
path-addressable) and each SIBLING (same path, already seen) by its ALIAS, so
the two configs are distinct and each alias resolves to its own n_ctx. A sibling
without an alias is skipped (can't be addressed). The GGUF loader already reads
the file from cfg['path'], so an alias-keyed sibling still loads the right file.
Verified: lisa->178000, lisa-32k->32768, same underlying .gguf.
Co-Authored-By: 's avatarClaude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mw2KQiswmD69T45fTfjKwW
parent b72896e5
......@@ -910,10 +910,27 @@ def main():
if text_model_names:
print(f"\nText model(s): {text_model_names}")
_seen_text_paths = set()
for i, m in enumerate(text_models):
mid = _model_id(m)
if not mid:
path_id = _model_id(m)
if not path_id:
continue
_alias = m.get("alias") if isinstance(m, dict) else None
# Multi-config support: the per-model config is keyed by `mid`. A SECOND
# entry for the same file (a sibling config — e.g. a smaller-context
# variant) must be keyed by its ALIAS so it doesn't overwrite the primary
# config (keyed by path) — otherwise both resolve to the last-registered
# config. A sibling without an alias can't be addressed distinctly, so skip
# it rather than silently clobbering the primary.
if path_id in _seen_text_paths:
if not _alias:
print(f"[config] skipping duplicate text config for '{path_id}' "
f"(add an alias to address it as a separate config)")
continue
mid = _alias
else:
mid = path_id
_seen_text_paths.add(path_id)
cfg = _model_cfg(m, "text")
if i == 0:
# Only the first text model becomes the default
......@@ -927,8 +944,9 @@ def main():
multi_model_manager.model_backend_types[mid] = (
m.get("backend", "auto") if isinstance(m, dict) else "auto"
)
if isinstance(m, dict) and m.get("alias"):
multi_model_manager.set_model_alias(m["alias"], mid)
# Primary: alias -> path. Sibling: alias -> itself (its own config key).
if _alias:
multi_model_manager.set_model_alias(_alias, mid)
# Audio models
audio_models = models_config.get("audio_models", [])
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment