Handoff-style /model switch command and per-turn thinking level (#64)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Yaowei Zheng
2026-07-26 16:31:51 +08:00
committed by GitHub
parent 816a823b75
commit 1e23452f48
58 changed files with 1064 additions and 336 deletions
@@ -1,14 +1,22 @@
/**
* Pure logic for the conversation-time thinking-level picker (chat draft view).
* Pure logic for the conversation-time thinking-level pickers (chat draft + active session).
*
* The picker is backed by the **Agent settings** (`system_config.model.thinking_level`):
* it shows the selected Agent's current level and writes a picked level straight through
* to the Agent config, so the session created on first send — which reads systemConfig
* fresh — runs with it, and it becomes the Agent's new default (switch-becomes-default).
* Per review: the menu lists the levels with short names only (no descriptions, no
* "default" row) under a title bar naming the control — and it does **not** offer "none"
* Two variants share these levels and labels, and both list only concrete levels — there is
* no "follow config" row anywhere:
* - Draft view: backed by the **Agent settings** (`system_config.model.thinking_level`) —
* shows the selected Agent's current level and writes a picked level straight through to
* the Agent config, so the session created on first send runs with it and it becomes the
* Agent's new default (switch-becomes-default).
* - Active session: the level is a **per-turn override**. The picker's displayed value
* initializes to the Agent config's level and auto-follows it while the user hasn't
* picked (internally the "" state remains as "untouched": tasks then omit the level, so
* the server/core fallback applies and config edits keep taking effect); an explicit pick
* sticks for the session and rides on every subsequent task as `thinkingLevel`, never
* writing through to the Agent config.
* Per review: the menus list the levels with short names only (no descriptions, no
* "default" row) under a title bar naming the control — and they do **not** offer "none"
* (many models cannot disable thinking): "none" stays a valid stored/wire value, so a
* legacy config or session that carries it still displays via the label table below.
* legacy config or trace that carries it still displays via the label table below.
*/
/** All five stored/wire levels, for display lookup (mirrors core's ThinkingLevelName). */