Repro (post v0.15.0 reinstall on devbox)
# Worker env (verified via /proc/PID/environ):
HERMES_HOME=~/.hermes/profiles/polynomial-explorer
DEVAGENTIC_BASE_URL=http://devbox:6071/v1
DEVAGENTIC_API_KEY=<set>
# Symptom:
hermes # picks provider=openrouter automatically
# Logs: "model switched ... via auto" → openrouter
/model devagentic-local/mistral-large
# Response: "model not found, similar: mistralai/mistral-large"
Earlier session 20260524_023743_715053 had provider=devagentic-local correctly with the same env — regression introduced by the reinstall.
Root cause (read from hermes_cli/models.py)
detect_provider_for_model(model_name, current_provider) walks:
- Step 0 — bare provider name (
/model nous → switch to nous). N/A for mistral-large.
- Step 1 — direct match in static
_PROVIDER_MODELS[pid] catalog. devagentic-local is NOT in _PROVIDER_MODELS because its model catalog is fetched dynamically from /v1/models via DevagenticLocalProfile.fetch_models() — it lives in fallback_models = ("devagentic/coder", "devagentic/researcher", "devagentic/orchestrator") plus whatever the live fetch returns. Bare mistral-large is not in the fallback list.
- Step 2 — OpenRouter catalog.
mistralai/mistral-large IS there → returns ("openrouter", "mistralai/mistral-large").
So when current_provider != "devagentic-local", the auto-detect cannot see mistral-large belongs to a devagentic-local-fetched catalog and routes to OpenRouter.
Why session 20260524_023743_715053 worked
That session was already on current_provider="devagentic-local" when the bare model lookup ran. The check at line ~1842 (if _model_in_provider_catalog(name_lower, current_keys): return None) short-circuits — model belongs to current provider's catalog, don't switch. After the reinstall, current_provider reset to the default (openrouter) and the short-circuit no longer fires.
Why /model devagentic-local/mistral-large ALSO fails
The explicit provider/model syntax routes through parse_model_input (line 1663) → validates the model name against the catalog hermes has for devagentic-local. Hermes' cached catalog for devagentic-local probably only has fallback_models until fetch_models() repopulates it on next session boot. If fetch_models() hits the /v1/models 401 issue (fixed in TechDevGroup/devagentic#216 / PR NousResearch#216) and silently returns None, the cache stays at fallback_models and mistral-large is "not found".
So this regression compounds with NousResearch#216 (/v1/models auth fix) — even after NousResearch#216 ships, hermes still needs to actually CALL fetch_models() at session boot AND cache its result for detect_provider_for_model to see the live catalog.
Suggested fixes (pick one or layer)
Option A — env-aware priority bump (cheapest)
When DEVAGENTIC_BASE_URL + DEVAGENTIC_API_KEY are both set, detect_provider_for_model consults devagentic-local's fetched catalog BEFORE the OpenRouter slug-match fallback. One conditional branch insertion before Step 2. Risk: a network call per auto-detect attempt unless cached.
Option B — populate static catalog from fetched models on boot (cleanest)
On hermes session init, when devagentic-local is configured, call fetch_models() once and merge result into _PROVIDER_MODELS["devagentic-local"]. Subsequent detect_static_provider_for_model calls find mistral-large via Step 1, returns ("devagentic-local", "mistral-large"). Existing current_provider short-circuit becomes irrelevant.
Option C — surface a default_provider env var (hammer)
Add HERMES_DEFAULT_PROVIDER=devagentic-local that sets current_provider at session boot. Worker env makes the provider explicit instead of relying on auto-detect. Operators get reproducible behavior; auto-detect only matters for /model X invocations mid-session.
OPENROUTER_BASE_URL leak check
Verified — none of the auto-detect code reads OPENROUTER_BASE_URL. The OpenRouter routing in Step 2 is from the static slug catalog, not from an env var. Not the cause.
Operator workaround until fix
# Force current_provider before auto-detect runs:
hermes --provider devagentic-local --model devagentic/coder
# Then /model mistral-large works (resolves via Step 0 short-circuit).
OR set the model explicitly via fallback list in plugins/model-providers/devagentic-local/__init__.py to include mistral-large (one-line edit, persists across sessions).
Severity / priority
Not urgent per orchestrator — fusion stack itself is healthy, polynomial-explorer can wait. File for proper fix when bandwidth allows; workaround unblocks the worker immediately.
Related
- TechDevGroup/devagentic#216 (
/v1/models bearer-only fix) — must be deployed on devbox before any fetch_models() approach works
- TechDevGroup/devagentic#218 (silo-v2 rename) — once deployed + migration run,
/v1/models returns the new role catalog including the renamed mistral-large (was silo-mistral)
- hermes-agent#66 (G6 deploy gap) — same container-rebuild gate
Repro (post v0.15.0 reinstall on devbox)
Earlier session
20260524_023743_715053hadprovider=devagentic-localcorrectly with the same env — regression introduced by the reinstall.Root cause (read from
hermes_cli/models.py)detect_provider_for_model(model_name, current_provider)walks:/model nous→ switch to nous). N/A formistral-large._PROVIDER_MODELS[pid]catalog. devagentic-local is NOT in_PROVIDER_MODELSbecause its model catalog is fetched dynamically from/v1/modelsviaDevagenticLocalProfile.fetch_models()— it lives infallback_models = ("devagentic/coder", "devagentic/researcher", "devagentic/orchestrator")plus whatever the live fetch returns. Baremistral-largeis not in the fallback list.mistralai/mistral-largeIS there → returns("openrouter", "mistralai/mistral-large").So when
current_provider != "devagentic-local", the auto-detect cannot seemistral-largebelongs to a devagentic-local-fetched catalog and routes to OpenRouter.Why session
20260524_023743_715053workedThat session was already on
current_provider="devagentic-local"when the bare model lookup ran. The check at line ~1842 (if _model_in_provider_catalog(name_lower, current_keys): return None) short-circuits — model belongs to current provider's catalog, don't switch. After the reinstall,current_providerreset to the default (openrouter) and the short-circuit no longer fires.Why
/model devagentic-local/mistral-largeALSO failsThe explicit
provider/modelsyntax routes throughparse_model_input(line 1663) → validates the model name against the catalog hermes has fordevagentic-local. Hermes' cached catalog for devagentic-local probably only hasfallback_modelsuntilfetch_models()repopulates it on next session boot. Iffetch_models()hits the/v1/models401 issue (fixed in TechDevGroup/devagentic#216 / PR NousResearch#216) and silently returns None, the cache stays at fallback_models andmistral-largeis "not found".So this regression compounds with NousResearch#216 (
/v1/modelsauth fix) — even after NousResearch#216 ships, hermes still needs to actually CALL fetch_models() at session boot AND cache its result fordetect_provider_for_modelto see the live catalog.Suggested fixes (pick one or layer)
Option A — env-aware priority bump (cheapest)
When
DEVAGENTIC_BASE_URL+DEVAGENTIC_API_KEYare both set,detect_provider_for_modelconsultsdevagentic-local's fetched catalog BEFORE the OpenRouter slug-match fallback. One conditional branch insertion before Step 2. Risk: a network call per auto-detect attempt unless cached.Option B — populate static catalog from fetched models on boot (cleanest)
On hermes session init, when devagentic-local is configured, call
fetch_models()once and merge result into_PROVIDER_MODELS["devagentic-local"]. Subsequentdetect_static_provider_for_modelcalls findmistral-largevia Step 1, returns("devagentic-local", "mistral-large"). Existingcurrent_providershort-circuit becomes irrelevant.Option C — surface a
default_providerenv var (hammer)Add
HERMES_DEFAULT_PROVIDER=devagentic-localthat setscurrent_providerat session boot. Worker env makes the provider explicit instead of relying on auto-detect. Operators get reproducible behavior; auto-detect only matters for/model Xinvocations mid-session.OPENROUTER_BASE_URL leak check
Verified — none of the auto-detect code reads
OPENROUTER_BASE_URL. The OpenRouter routing in Step 2 is from the static slug catalog, not from an env var. Not the cause.Operator workaround until fix
OR set the model explicitly via fallback list in
plugins/model-providers/devagentic-local/__init__.pyto includemistral-large(one-line edit, persists across sessions).Severity / priority
Not urgent per orchestrator — fusion stack itself is healthy, polynomial-explorer can wait. File for proper fix when bandwidth allows; workaround unblocks the worker immediately.
Related
/v1/modelsbearer-only fix) — must be deployed on devbox before any fetch_models() approach works/v1/modelsreturns the new role catalog including the renamedmistral-large(wassilo-mistral)