fix(cli): -Q stdout carries only the final response — no tool diffs, spinner lines, or reasoning

Widens the cherry-picked reasoning-callback fix to the whole leak class
(#93220):

- quiet branch also neutralizes tool_progress_callback,
  tool_start_callback, tool_complete_callback (inline diff rendering via
  render_edit_diff_with_delta was gated by NEITHER quiet_mode nor
  tool_progress_mode) and syncs agent.tool_progress_mode='off'.
- _should_emit_quiet_tool_messages() returns False under
  suppress_status_output: with callbacks neutralized, the quiet-mode
  KawaiiSpinner fallback printed '[tool]'/'[done]' lines into captured
  stdout. Also covers oneshot.py and background-review forks, which set
  the same flag and expect strict silence.

E2E (isolated HERMES_HOME, live model, write_file turn): base leaks
'┊ review diff' + full SVG source into stdout; head emits exactly the
final response. Regression tests pin the quiet-branch statements and the
gate (sabotage-verified).

Co-authored-by: liuhao1024 <liuhao1024@users.noreply.github.com>
This commit is contained in:
Teknium
2026-08-23 16:40:08 -07:00
parent 8e2e3202da
commit 637716755c
3 changed files with 127 additions and 0 deletions
+14
View File
@@ -21380,6 +21380,20 @@ def main(
cli.agent.stream_delta_callback = None
cli.agent.tool_gen_callback = None
cli.agent.reasoning_callback = None
# Inline-diff and progress callbacks print directly to
# stdout and are gated by NEITHER quiet_mode nor
# tool_progress_mode: _on_tool_complete renders full
# file diffs via render_edit_diff_with_delta, and
# _on_tool_progress prints MoA reference blocks before
# its mode check. Neutralize them too so -Q stdout
# carries only the final response (#93220).
cli.agent.tool_progress_callback = None
cli.agent.tool_start_callback = None
cli.agent.tool_complete_callback = None
# Belt-and-braces for the executor's direct prints
# (they check agent.tool_progress_mode, initialized
# from display.tool_progress at construction).
cli.agent.tool_progress_mode = "off"
try:
result = cli.agent.run_conversation(
user_message=effective_query,