New `/purge` command lets the agent surgically remove or rewrite
conversation history via a purge_context tool call. The engine
validates and applies the operations, cascading tool-result removal
to the paired tool-use call.
The whale-route fallback in the picker constructor used show_custom_model_row
as the gate for selecting the 'auto' vs custom row, but a known DeepSeek model
(e.g. v4-pro) paired with ReasoningEffort::Auto would not match any whale route
yet still have show_custom_model_row=false — silently landing on the auto row
and replacing the explicit model with 'auto' on apply.
Key the fallback on whether the initial model is actually 'auto' instead.
When a whale-route fallback selects the custom row, ensure show_custom_model_row
is set to true so the row is visible in the picker UI.
Also:
- Add regression test: known-model + Auto effort must not fall to auto row.
- Clean up picker_auto_model_forces_auto_effort_on_apply: remove manual
mutations of selected_model_idx / selected_effort_idx which whale-route
mode never reads.
- Rename Porpoise → Beluga per #2016, which excludes porpoises from the
user-facing whale pool.
Adds native xiaomi-mimo provider configuration, auth/env aliases, model registry entries, TUI request handling, tests, and docs. Keeps credentials in existing provider-scoped config/env/keyring paths and uses placeholders only in docs.
Resolve the prompt-layer conflict by keeping the core tool taxonomy block while routing base prompt composition through the override accessor. Tighten the override API so duplicate registrations return the rejected string, and make locale preamble/closer overrides symmetric across supported bookend locales.
Route user cells in the transcript cache through the existing user-message renderer.
The live chat view renders through lines_with_copy_metadata(), which previously
bypassed the user-message highlight path. As a result, submitted user prompts did
not show the intended full-row background in the main transcript.
Add a regression test for the transcript cache path.
The second feature-flag gate in tool_setup.rs was calling
with_shell_tools() again when allow_shell was already true, causing
duplicate tool registration. Remove the redundant gate since
with_agent_tools() already handles the allow_shell check.
Also add task_shell_wait to MODES.md alongside task_shell_start.
task_shell_start delegates to ExecShellTool, providing the same shell
execution capability as exec_shell. Previously, task_shell_start was
registered unconditionally in with_runtime_task_tools while exec_shell
was gated behind allow_shell, creating an inconsistent security gate.
This caused the model to try exec_shell first, fail, then fall back to
task_shell_start — wasting tokens and bypassing the intended security
boundary.
Split TaskShellStartTool and TaskShellWaitTool out of
with_runtime_task_tools into a new with_runtime_task_shell_tools method,
and gate both behind the allow_shell check in with_agent_tools.
Closes#2303