fix(desktop): let explicit model switches escape broken config providers (salvage #42971) - #46796
Merged
Merged
Conversation
…ers (#42241) When a desktop/dashboard session had no agent built yet and the user explicitly picked a provider in the model picker, config.set('model', ...) would first try to initialize the agent from the (possibly broken) config default provider — failing before the user's explicit switch could take effect, trapping them on a misconfigured default. config.set now pre-parses the model flags: if an explicit --provider is present and no agent exists yet, it skips the default-provider agent build and routes straight through _apply_model_switch with the explicit provider. _apply_model_switch gained a parsed_flags passthrough (avoids double-parsing) and only falls back to resolve_runtime_provider(requested=None) when no explicit provider was given. The desktop hook now sends config.set instead of slash.exec for active-session model changes, so errors from the selected provider surface to the user instead of being swallowed. Co-authored-by: rodboev <rod.boev@gmail.com>
Contributor
🔎 Lint report:
|
| Rule | Count |
|---|---|
unresolved-attribute |
3 |
unsupported-operator |
1 |
First entries
tests/test_tui_gateway_server.py:3051: [unresolved-attribute] unresolved-attribute: Attribute `append` is not defined on `int` in union `int | list[Unknown]`
run_agent.py:2920: [unresolved-attribute] unresolved-attribute: Object of type `Self@get_credits_spent_micros` has no attribute `_credits_session_start_micros`
tests/test_tui_gateway_server.py:3046: [unsupported-operator] unsupported-operator: Operator `+` is not supported between objects of type `int | list[Unknown]` and `Literal[1]`
tests/run_agent/test_credits_notices_toggle.py:76: [unresolved-attribute] unresolved-attribute: Unresolved attribute `_credits_session_start_micros` on type `AIAgent`
✅ Fixed issues (1):
| Rule | Count |
|---|---|
invalid-assignment |
1 |
First entries
tests/run_agent/test_credits_notices_toggle.py:76: [invalid-assignment] invalid-assignment: Object of type `None` is not assignable to attribute `_credits_session_start_micros` of type `int`
Unchanged: 5758 pre-existing issues carried over.
Diagnostics are surfaced as warnings — this check never fails the build.
Collaborator
|
Related: #42971 (original by @rodboev — this is the salvage onto current main), #42241 (the issue it fixes), and #46288 (sibling desktop model-switch fix via a different mechanism — routing picker switches through config.set to avoid the slash worker). This salvage is the active/authoritative version of the #42971 fix; tracking lineage only. |
rdnot
added a commit
to rdnot/hermes-agent-medical-research
that referenced
this pull request
Jun 15, 2026
…kfile-fix.yml) Upstream advanced from 5bfed0f (Jun 15) to 3e7e9b2 (Jun 16). Major upstream changes since last merge: - feat(skills): add optional payments skills (Stripe Link, MPP, Projects) NousResearch#31343 - feat(delegation): async background subagents via delegate_task(background=true) NousResearch#40946 - fix(desktop): read HERMES_HOME from Windows registry when env is stale NousResearch#46772 - fix(desktop): let explicit model switches escape broken config providers NousResearch#46796 - fix(dump): report effective terminal backend in hermes debug - fix(inventory): deduplicate models between user-defined and aggregator providers - fix(doctor): recognize nvidia as vendor-slug-accepting provider - fix(discord): cap slash commands at Discord's 100-command limit - fix(teams): package Microsoft Teams SDK as an installable extra NousResearch#46764 - fix(dashboard): scope chat sidebar model card to selected profile NousResearch#46665 - fix(deps): declare websockets as core dep + relax dev setuptools pin NousResearch#46744 - fix(desktop): pin @assistant-ui/store so the cluster shares one tap - fix(install): make npm install -g packages reachable on PATH - feat(honcho-setup): replace deployment-shape prompt with gateway-gated identity tree - refactor(honcho): canonicalize identity-mapping on pinUserPeer, migrate legacy key - mattermost: preserve thread-local delivery hygiene - ci: rip out nix ci for now - ...plus desktop Electron changes, web UI updates, website docs, honcho docs Fork customizations preserved (all 22 verified intact): - run_agent.py: max_iterations: int = 200 - agent/conversation_loop.py: _force_final_threshold, _build_tools_summary, _current_turn_tool_calls, _pending_tool_summary, tool_summary flow - agent/turn_finalizer.py: 'tool_summary' key in result dict - tools/web_tools.py: tiered fetcher (curl_cffi→scrapling→httpx), MAX_OUTPUT_SIZE=10000, _get_extract_backend, max_result_size_chars=500_000, LLM-summarization disabled, NCBI/PubMed/PMC hardening - tools/budget_config.py: 400_000 / 500_000 - gateway/run.py: HERMES_MAX_ITERATIONS, "200" - hermes_cli/config.py: max_turns: 200 - cli.py: result.get('tool_summary') display - gateway/config.py: Platform.LINE = "line" - gateway/authz_mixin.py: Platform.LINE: "LINE_ALLOWED_GROUPS" - plugins/platforms/line/adapter.py: reply_only_mention, build_source Conflict resolution: - .github/workflows/nix-lockfile-fix.yml: removed by upstream. Was fork-only (disabled with if:false, requires APP_ID/APP_PRIVATE_KEY secrets the fork does not have). Upstream deletion is correct. Backup branch: backup-main-pre-merge-20260616-063126
alanbratu
pushed a commit
to alanbratu/hermes-agent
that referenced
this pull request
Jun 17, 2026
…ers (NousResearch#42241) (NousResearch#46796) When a desktop/dashboard session had no agent built yet and the user explicitly picked a provider in the model picker, config.set('model', ...) would first try to initialize the agent from the (possibly broken) config default provider — failing before the user's explicit switch could take effect, trapping them on a misconfigured default. config.set now pre-parses the model flags: if an explicit --provider is present and no agent exists yet, it skips the default-provider agent build and routes straight through _apply_model_switch with the explicit provider. _apply_model_switch gained a parsed_flags passthrough (avoids double-parsing) and only falls back to resolve_runtime_provider(requested=None) when no explicit provider was given. The desktop hook now sends config.set instead of slash.exec for active-session model changes, so errors from the selected provider surface to the user instead of being swallowed. Co-authored-by: rodboev <rod.boev@gmail.com>
zmlgit
pushed a commit
to zmlgit/hermes-agent
that referenced
this pull request
Jun 17, 2026
…ers (NousResearch#42241) (NousResearch#46796) When a desktop/dashboard session had no agent built yet and the user explicitly picked a provider in the model picker, config.set('model', ...) would first try to initialize the agent from the (possibly broken) config default provider — failing before the user's explicit switch could take effect, trapping them on a misconfigured default. config.set now pre-parses the model flags: if an explicit --provider is present and no agent exists yet, it skips the default-provider agent build and routes straight through _apply_model_switch with the explicit provider. _apply_model_switch gained a parsed_flags passthrough (avoids double-parsing) and only falls back to resolve_runtime_provider(requested=None) when no explicit provider was given. The desktop hook now sends config.set instead of slash.exec for active-session model changes, so errors from the selected provider surface to the user instead of being swallowed. Co-authored-by: rodboev <rod.boev@gmail.com>
al3xar
pushed a commit
to al3xar/hermes-agent
that referenced
this pull request
Jun 17, 2026
…ers (NousResearch#42241) (NousResearch#46796) When a desktop/dashboard session had no agent built yet and the user explicitly picked a provider in the model picker, config.set('model', ...) would first try to initialize the agent from the (possibly broken) config default provider — failing before the user's explicit switch could take effect, trapping them on a misconfigured default. config.set now pre-parses the model flags: if an explicit --provider is present and no agent exists yet, it skips the default-provider agent build and routes straight through _apply_model_switch with the explicit provider. _apply_model_switch gained a parsed_flags passthrough (avoids double-parsing) and only falls back to resolve_runtime_provider(requested=None) when no explicit provider was given. The desktop hook now sends config.set instead of slash.exec for active-session model changes, so errors from the selected provider surface to the user instead of being swallowed. Co-authored-by: rodboev <rod.boev@gmail.com>
T02200059
pushed a commit
to T02200059/hermes-agent
that referenced
this pull request
Jun 18, 2026
…ers (NousResearch#42241) (NousResearch#46796) When a desktop/dashboard session had no agent built yet and the user explicitly picked a provider in the model picker, config.set('model', ...) would first try to initialize the agent from the (possibly broken) config default provider — failing before the user's explicit switch could take effect, trapping them on a misconfigured default. config.set now pre-parses the model flags: if an explicit --provider is present and no agent exists yet, it skips the default-provider agent build and routes straight through _apply_model_switch with the explicit provider. _apply_model_switch gained a parsed_flags passthrough (avoids double-parsing) and only falls back to resolve_runtime_provider(requested=None) when no explicit provider was given. The desktop hook now sends config.set instead of slash.exec for active-session model changes, so errors from the selected provider surface to the user instead of being swallowed. Co-authored-by: rodboev <rod.boev@gmail.com>
waefrebeorn
pushed a commit
to waefrebeorn/slermes
that referenced
this pull request
Jul 2, 2026
…ers (NousResearch#42241) (NousResearch#46796) When a desktop/dashboard session had no agent built yet and the user explicitly picked a provider in the model picker, config.set('model', ...) would first try to initialize the agent from the (possibly broken) config default provider — failing before the user's explicit switch could take effect, trapping them on a misconfigured default. config.set now pre-parses the model flags: if an explicit --provider is present and no agent exists yet, it skips the default-provider agent build and routes straight through _apply_model_switch with the explicit provider. _apply_model_switch gained a parsed_flags passthrough (avoids double-parsing) and only falls back to resolve_runtime_provider(requested=None) when no explicit provider was given. The desktop hook now sends config.set instead of slash.exec for active-session model changes, so errors from the selected provider surface to the user instead of being swallowed. Co-authored-by: rodboev <rod.boev@gmail.com>
Methodician
added a commit
to Methodician/hermes-agent
that referenced
this pull request
Jul 4, 2026
…ers (NousResearch#42241) (NousResearch#46796) When a desktop/dashboard session had no agent built yet and the user explicitly picked a provider in the model picker, config.set('model', ...) would first try to initialize the agent from the (possibly broken) config default provider — failing before the user's explicit switch could take effect, trapping them on a misconfigured default. config.set now pre-parses the model flags: if an explicit --provider is present and no agent exists yet, it skips the default-provider agent build and routes straight through _apply_model_switch with the explicit provider. _apply_model_switch gained a parsed_flags passthrough (avoids double-parsing) and only falls back to resolve_runtime_provider(requested=None) when no explicit provider was given. The desktop hook now sends config.set instead of slash.exec for active-session model changes, so errors from the selected provider surface to the user instead of being swallowed. Co-authored-by: rodboev <rod.boev@gmail.com>
habarmc1223-sudo
pushed a commit
to habarmc1223-sudo/hermes-agent-fluxmem
that referenced
this pull request
Jul 8, 2026
…ers (NousResearch#42241) (NousResearch#46796) When a desktop/dashboard session had no agent built yet and the user explicitly picked a provider in the model picker, config.set('model', ...) would first try to initialize the agent from the (possibly broken) config default provider — failing before the user's explicit switch could take effect, trapping them on a misconfigured default. config.set now pre-parses the model flags: if an explicit --provider is present and no agent exists yet, it skips the default-provider agent build and routes straight through _apply_model_switch with the explicit provider. _apply_model_switch gained a parsed_flags passthrough (avoids double-parsing) and only falls back to resolve_runtime_provider(requested=None) when no explicit provider was given. The desktop hook now sends config.set instead of slash.exec for active-session model changes, so errors from the selected provider surface to the user instead of being swallowed. Co-authored-by: rodboev <rod.boev@gmail.com>
santhreal
pushed a commit
to santhreal/hermes-agent
that referenced
this pull request
Jul 13, 2026
…ers (NousResearch#42241) (NousResearch#46796) When a desktop/dashboard session had no agent built yet and the user explicitly picked a provider in the model picker, config.set('model', ...) would first try to initialize the agent from the (possibly broken) config default provider — failing before the user's explicit switch could take effect, trapping them on a misconfigured default. config.set now pre-parses the model flags: if an explicit --provider is present and no agent exists yet, it skips the default-provider agent build and routes straight through _apply_model_switch with the explicit provider. _apply_model_switch gained a parsed_flags passthrough (avoids double-parsing) and only falls back to resolve_runtime_provider(requested=None) when no explicit provider was given. The desktop hook now sends config.set instead of slash.exec for active-session model changes, so errors from the selected provider surface to the user instead of being swallowed. Co-authored-by: rodboev <rod.boev@gmail.com>
Gravezzz
pushed a commit
to Gravezzz/hermes-agent
that referenced
this pull request
Jul 21, 2026
…ers (NousResearch#42241) (NousResearch#46796) When a desktop/dashboard session had no agent built yet and the user explicitly picked a provider in the model picker, config.set('model', ...) would first try to initialize the agent from the (possibly broken) config default provider — failing before the user's explicit switch could take effect, trapping them on a misconfigured default. config.set now pre-parses the model flags: if an explicit --provider is present and no agent exists yet, it skips the default-provider agent build and routes straight through _apply_model_switch with the explicit provider. _apply_model_switch gained a parsed_flags passthrough (avoids double-parsing) and only falls back to resolve_runtime_provider(requested=None) when no explicit provider was given. The desktop hook now sends config.set instead of slash.exec for active-session model changes, so errors from the selected provider surface to the user instead of being swallowed. Co-authored-by: rodboev <rod.boev@gmail.com>
leewenjie
pushed a commit
to leewenjie/hermes-agent
that referenced
this pull request
Aug 7, 2026
…ers (NousResearch#42241) (NousResearch#46796) When a desktop/dashboard session had no agent built yet and the user explicitly picked a provider in the model picker, config.set('model', ...) would first try to initialize the agent from the (possibly broken) config default provider — failing before the user's explicit switch could take effect, trapping them on a misconfigured default. config.set now pre-parses the model flags: if an explicit --provider is present and no agent exists yet, it skips the default-provider agent build and routes straight through _apply_model_switch with the explicit provider. _apply_model_switch gained a parsed_flags passthrough (avoids double-parsing) and only falls back to resolve_runtime_provider(requested=None) when no explicit provider was given. The desktop hook now sends config.set instead of slash.exec for active-session model changes, so errors from the selected provider surface to the user instead of being swallowed. Co-authored-by: rodboev <rod.boev@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Salvage of #42971 (@rodboev) onto current
main. Fixes #42241.When a desktop/dashboard session had no agent built yet and the user explicitly picked a provider in the model picker,
config.set('model', …)would first try to initialize the agent from the (possibly broken) config default provider — failing before the user's explicit switch could take effect. The user got trapped on a misconfigured default with no way to switch out via the UI.Confirmed still present on
main:tui_gateway/server.py_apply_model_switch()else-branch unconditionally callsresolve_runtime_provider(requested=None), and theconfig.setmodel handler does_start_agent_buildwheneversession.get("agent") is Noneregardless of an explicit provider.What changed
config.setpre-parses the model flags. If an explicit--provideris present and no agent exists yet, it skips the default-provider agent build and routes straight through_apply_model_switchwith the explicit provider._apply_model_switchgained aparsed_flagspassthrough (avoids double-parsing) and only falls back toresolve_runtime_provider(requested=None)when no explicit provider was given; otherwise it uses the explicit provider directly.use-model-controls.ts) sendsconfig.setinstead ofslash.execfor active-session changes, so errors from the selected provider surface to the user instead of being swallowed.How this was salvaged
The original PR was 4 commits (core fix + i18n test alignment + a refactor that removed 26 lockfile lines + a follow-up that re-added them — net lockfile change zero). I applied the net diff of the 4 real files via 3-way merge onto current
main. One conflict in_apply_model_switch's signature —mainadded apin_session_overrideparam since the PR was authored; kept both that and the newparsed_flagsparam. Dropped the no-op lockfile churn entirely.Test plan
py_compileonserver.py→ OKpytest tests/test_tui_gateway_server.py -k model→ 20 passed (incl. the 2 new tests + the env-leak guard)Credit