3 Commits

Author SHA1 Message Date
Teknium 79aeb22886 refactor(cli): unify duplicated model-switch staging and last-assistant-text blocks
cli_model_switch_mixin: the identical snapshot->stage->agent.switch_model->rollback
block in _apply_model_switch_result and _confirm_and_apply_cli_model_switch (2x47
lines) -> _stage_and_swap_model(result, old_model) -> bool. cli_loops_mixin: the
identical reversed-history assistant-text extraction in the loop-tick and goal
post-turn hooks -> _last_assistant_response_text(). Four _StubCLI test doubles bind
the new helper to the real implementation.
2026-09-02 16:17:31 -07:00
Turgut Kural 9a8af40192 fix(cli): run /model expensive-confirm off the main thread (#79401)
The command path (/model <name> --provider <p>) called
_confirm_expensive_model_switch() inline. That modal blocks its calling
thread on a response queue (see _prompt_text_input_modal); on the
prompt_toolkit main thread the TUI event loop freezes, the modal never
renders, and the switch silently cancels after the 120s timeout — the
user sees a frozen terminal and 'Model switch cancelled.' without ever
seeing the warning. The picker path already dispatched confirm+apply on
a worker thread; the command path now mirrors that contract.

Extract the inline confirm+apply block into
_confirm_and_apply_cli_model_switch() (preserving --once restore and
persist semantics) and dispatch it on a daemon thread when a TUI app is
present, keeping the synchronous path for non-interactive/test use.

Tests: new test_model_switch_confirm_thread.py pins (a) confirm runs off
the main thread when _app is present, and (b) the no-app path stays
synchronous. Existing _StubCLI helpers forward to the extracted method.
2026-08-14 01:31:21 -07:00
deusyu 3f84b7a163 feat: add /model --once one-turn model override (#29914)
Adds --once to /model across CLI, TUI, and gateway: switch model for the
next turn only, restoring the previous model in a finally block so
success, exception, and interrupt all revert. Parsing extends
parse_model_flags_detailed(); resolve_persist_behavior() treats --once
as a persistence opt-out; --global + --once is rejected.

Salvaged from PR #29923 (image-generation lane split to #59815 per
review; conflict resolution against current main by the maintainers).
2026-07-18 14:01:56 -07:00