Skip to content

feat(moa): make /moa one-shot only; route preset switching through the model picker - #53548

Merged
teknium1 merged 1 commit into
mainfrom
feat/moa-one-shot-only
Jun 27, 2026
Merged

feat(moa): make /moa one-shot only; route preset switching through the model picker#53548
teknium1 merged 1 commit into
mainfrom
feat/moa-one-shot-only

Conversation

@teknium1

Copy link
Copy Markdown
Contributor

Summary

/moa is 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 virtual Mixture of Agents provider on every model-selection surface (CLI/gateway /model, hermes model, TUI, desktop, dashboard).

Also fixes #53444: the TUI /moa 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.

Changes

  • cli.py, gateway/run.py, tui_gateway/server.py: removed the redundant sticky preset-switch branch from each /moa handler. The whole argument is now treated as the one-shot prompt (no preset-name matching). Bare /moa prints 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-place agent.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 setting model_override for the first build.
  • hermes_cli/commands.py, hermes_cli/moa_config.py: updated the /moa command description and moa_usage() to the one-shot-only contract.
  • website/docs/...: rewrote the slash-command section of mixture-of-agents.md and the hermes moa reference to point at the model picker for sticky preset selection.
  • Tests updated to the new contract (tests/cli/test_moa_command.py, tests/tui_gateway/test_goal_command.py).

The MoA virtual-provider machinery (moa_loop.py, the inventory.py provider row, model_switch.py resolution, the encode/decode_moa_turn text-marker fallback) is intentionally kept — that is the model-picker route, and it composes through the standard model-selection path as designed.

Validation

Suite Result
tests/cli/test_moa_command.py + tests/tui_gateway/test_goal_command.py + tests/hermes_cli/test_moa_config.py 32/32 passed
tests/hermes_cli/test_commands.py (registry, covers CommandDef change) 161/161 passed
CLI one-shot path E2E (real imports, isolated HERMES_HOME) passed
Behavior Before After
bare /moa switched session to default preset prints usage (no switch)
/moa <preset> switched session to that preset one-shot prompt through default preset
/moa <prompt> one-shot, but TUI silently ran old model (#53444) one-shot, real in-place switch + restore
switch to a preset for the session /moa <preset> model picker (Mixture of Agents provider)

Closes #53444.

Infographic

moa-one-shot-only

…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.
@github-actions

Copy link
Copy Markdown
Contributor

🔎 Lint report: feat/moa-one-shot-only vs origin/main

ruff

Total: 0 on HEAD, 0 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 0 pre-existing issues carried over.

ty (type checker)

Total: 11481 on HEAD, 11483 on base (✅ -2)

🆕 New 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`

✅ 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 tonydwb left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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_model is 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

@teknium1
teknium1 merged commit 50f6855 into main Jun 27, 2026
30 checks passed
@teknium1
teknium1 deleted the feat/moa-one-shot-only branch June 27, 2026 10:09
@alt-glitch alt-glitch added type/feature New feature or request comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/cli CLI entry point, hermes_cli/, setup wizard comp/gateway Gateway runner, session dispatch, delivery comp/tui Terminal UI (ui-tui/ + tui_gateway/) P3 Low — cosmetic, nice to have labels Jun 27, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

This was generated by AI during triage.

Related (MoA cluster): this changes the /moa contract to one-shot-only and routes sticky preset switching through the model picker (virtual provider #46081), AND fixes the #53444 live-agent no-op. #53502 also fixes that same #53444 no-op (TUI live switch), and #53526 adds MoA presets to the gateway model picker. These overlap — not duplicates. A maintainer should decide whether this broad contract change supersedes the narrower #53502/#53526.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/cli CLI entry point, hermes_cli/, setup wizard comp/gateway Gateway runner, session dispatch, delivery comp/tui Terminal UI (ui-tui/ + tui_gateway/) P3 Low — cosmetic, nice to have type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: Rethink MoA architecture — virtual provider is overkill, subagent delegation is simpler and more robust

3 participants