feat(moa): make /moa one-shot only; route preset switching through the model picker - #53548
Conversation
…e model picker /moa no longer does a sticky model switch. It now always runs a single prompt through the default MoA preset and restores the prior model afterward; the whole argument is the prompt (no preset-name matching). To switch to a MoA preset for the session, select it from the model picker, where presets already surface under a virtual Mixture of Agents provider on every model-selection surface. Also fixes #53444: the TUI one-shot only set session[model_override], which the already-built cached agent ignored, so MoA silently never ran and the turn used the original model. The TUI now does a real in-place agent.switch_model() via _apply_model_switch() when a live agent exists (with a proper restore after the turn), and falls back to a model_override for lazy/unbuilt sessions. Removes the redundant sticky-switch branch from the CLI, gateway, and TUI /moa handlers; updates the command description, usage string, and docs.
🔎 Lint report:
|
| 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`
✅ Fixed issues (2):
| Rule | Count |
|---|---|
unresolved-attribute |
2 |
First entries
tests/run_agent/test_credits_notices_toggle.py:76: [unresolved-attribute] unresolved-attribute: Unresolved attribute `_credits_session_start_micros` on type `AIAgent`
run_agent.py:3002: [unresolved-attribute] unresolved-attribute: Object of type `Self@get_credits_spent_micros` has no attribute `_credits_session_start_micros`
Unchanged: 6031 pre-existing issues carried over.
Diagnostics are surfaced as warnings — this check never fails the build.
tonydwb
left a comment
There was a problem hiding this comment.
Code Review Summary
Verdict: Approved
Clean simplification of /moa to one-shot-only behavior. The removal of preset switching via /moa (now routed through the model picker) is well-motivated and the diff is well-scoped across 9 files.
Looks Good
- Clear separation: /moa is sugar for one-shot, model picker handles session switching
- Restoring previous model via
_pending_moa_restore_modelis correct - Unused imports (
exact_moa_preset_name,resolve_moa_preset) properly removed - Related PR #53526 adds MoA presets to the model picker, supporting this design
- Related PR #53523 fixes MoA one-shot restore on failed turns
No security, correctness, or testing concerns.
Reviewed by Hermes Agent
Related (MoA cluster): this changes the |
Summary
/moais now one-shot-only sugar: it runs a single prompt through the default MoA preset and restores your model afterward. Switching to a MoA preset for the rest of a session is done through the model picker, where presets already surface as selectable models under a virtualMixture of Agentsprovider on every model-selection surface (CLI/gateway/model,hermes model, TUI, desktop, dashboard).Also fixes #53444: the TUI
/moaone-shot only setsession["model_override"], which the already-built cached agent ignored — so MoA silently never ran and the turn used the original model.Changes
cli.py,gateway/run.py,tui_gateway/server.py: removed the redundant sticky preset-switch branch from each/moahandler. The whole argument is now treated as the one-shot prompt (no preset-name matching). Bare/moaprints usage.tui_gateway/server.py(feat: Rethink MoA architecture — virtual provider is overkill, subagent delegation is simpler and more robust #53444): when a live agent exists, the one-shot now does a real in-placeagent.switch_model()via_apply_model_switch()and restores the prior model after the turn (also through the switch path, so the live client is actually swapped back). Lazy/unbuilt sessions fall back to settingmodel_overridefor the first build.hermes_cli/commands.py,hermes_cli/moa_config.py: updated the/moacommand description andmoa_usage()to the one-shot-only contract.website/docs/...: rewrote the slash-command section ofmixture-of-agents.mdand thehermes moareference to point at the model picker for sticky preset selection.tests/cli/test_moa_command.py,tests/tui_gateway/test_goal_command.py).The MoA virtual-provider machinery (
moa_loop.py, theinventory.pyprovider row,model_switch.pyresolution, theencode/decode_moa_turntext-marker fallback) is intentionally kept — that is the model-picker route, and it composes through the standard model-selection path as designed.Validation
tests/cli/test_moa_command.py+tests/tui_gateway/test_goal_command.py+tests/hermes_cli/test_moa_config.pytests/hermes_cli/test_commands.py(registry, covers CommandDef change)/moa/moa <preset>/moa <prompt>/moa <preset>Mixture of Agentsprovider)Closes #53444.
Infographic