feat: to #2767, support verbose and compact mode swither with ctrl-o#2770
feat: to #2767, support verbose and compact mode swither with ctrl-o#2770chiga0 wants to merge 1 commit intoQwenLM:mainfrom
Conversation
tanzhenxin
left a comment
There was a problem hiding this comment.
Code Review
Hey @chiga0 — thanks for the effort on this, the compact/verbose toggle is an interesting idea!
However, we have some concerns that need to be addressed before this can move forward.
Default behavior change is too disruptive
The biggest issue: this PR changes the default display behavior. Currently, thinking blocks (gemini_thought, gemini_thought_content) are always visible. After this PR, they're hidden by default (verboseMode: false). This is a significant UX regression for existing users who rely on seeing the model's reasoning. We can't accept a change that silently alters the default experience like this.
If you'd like to continue with this feature, the default should be verboseMode: true (preserving current behavior), with compact mode as an opt-in.
Critical issues
-
useCallbackdependency regression —AppContainer.tsx- The dependency
settings.merged.general?.debugKeystrokeLoggingwas replaced withsettings(the full object). Sincesettingscreates a new reference on every render, this defeatsuseCallbackmemoization entirely and causeshandleGlobalKeypressto be recreated every render. Please keep the original granular dependency and accesssetValueseparately.
- The dependency
-
Compact mode hides actively-executing shell output —
ToolMessage.tsx- In compact mode,
effectiveDisplayRendereris unconditionally set to{ type: 'none' }, which hides the liveansioutput of running shell commands. Users would be typing into a shell blind — they can see the input prompt but not the command output. At minimum,ansi-type displays should be exempted when a tool is actively executing.
- In compact mode,
Suggestions
-
Asymmetric frozen snapshot behavior — Frozen snapshot is only created when toggling TO verbose mode during streaming, not when toggling to compact. Switching to compact mid-stream causes tool outputs to disappear abruptly.
-
Copyright header — New file
VerboseModeContext.tsxsays "Copyright 2025 Google LLC". New files should reflect the Qwen Code project. -
Missing translations — Non-English locales (except Chinese) use the untranslated English string "verbose".
Please address the default behavior change and the critical issues. Happy to re-review once updated!
TLDR
Adds a compact/verbose mode toggle (Ctrl+O) to Qwen Code. In compact mode (default), tool result output and model thinking-chain are hidden, keeping the
terminal clean during long agentic runs. Pressing Ctrl+O switches to verbose mode, revealing full tool output and thoughts. The setting persists across
sessions via
~/.qwen/settings.json, and averboselabel appears in the footer when active.Screenshots / Video Demo
Compact mode (default) — tool calls show name + status only, no output noise:
✓ ReadFile src/index.ts
✓ Edit src/index.ts
✓ Bash npm run build
Verbose mode (Ctrl+O) — full tool output visible,
verboseindicator in footer:✓ ReadFile src/index.ts
1 import React from 'react';
...
✓ Bash npm run build
▎ build
▎ tsc --project tsconfig.json
▎ Done in 2.3s
Dive Deeper
Architecture: Rendering-layer filtering via React Context. No changes to the data model or streaming pipeline —
VerboseModeContextdistributesverboseModeandfrozenSnapshotstate fromAppContainerto:HistoryItemDisplay— gatesgemini_thought/gemini_thought_contentrenders behindverboseModeToolMessage— computeseffectiveDisplayRenderer: passes through in verbose mode, returns{ type: 'none' }in compact mode (interactive shellprompt is unaffected)
MainContent— usesfrozenSnapshotto freeze the pending items viewport while streaming, preventing layout jitter when toggling mid-stream;auto-unfreezes when streaming completes
Footer— showsverboselabel (localised) when verbose mode is activeKey design decisions:
verboseMode: false) — matches the target UX of a clean terminal by defaultpendingHistoryItemsuseMemo was moved earlier inAppContainer(beforehandleGlobalKeypress) to avoid stale closure / TDZ issues when referenced inthe Ctrl+O handler
refreshStatic()is called on toggle to remount Ink's<Static>component, applying the mode change retroactively to already-rendered historyIdentityFileapproach for SSH key (non-breaking, no changes to auth)Localization:
verbosekey added toen,zh,de,ja,ru,ptlocale files.Reviewer Test Plan
npm run build— should pass with zero TypeScript errorsnpm test— all 238 test files should passlist all files in src). Tool result output should be hidden; only tool name +status icon shown.
verboselabel should appear in the footer. Re-run a prompt — full tool output should now be visible.verboselabel disappears, tool output hidden.~/.qwen/settings.jsonfor"ui": { "verboseMode": true }.auto-unfreeze.
<think>blocks should be hidden. In verbose mode, they shouldappear.
Ctrl+Ffocus) still works normally in compact mode — the shell input prompt must not be gated byverbose mode.
Testing Matrix
Validated on macOS (Apple Silicon) via
npm run.Linked issues / bugs
Closes #2767