From ace269f2b6ecae2c228aba0b7d6a193a7302b25b Mon Sep 17 00:00:00 2001 From: Michael Bolin Date: Fri, 30 May 2025 23:06:30 -0700 Subject: [PATCH] feat: add hide_agent_reasoning config option --- codex-rs/core/src/config.rs | 14 ++++++++++++++ codex-rs/exec/src/event_processor.rs | 21 ++++++++++++++------- codex-rs/exec/src/lib.rs | 3 ++- codex-rs/tui/src/chatwidget.rs | 8 +++++--- 4 files changed, 35 insertions(+), 11 deletions(-) diff --git a/codex-rs/core/src/config.rs b/codex-rs/core/src/config.rs index b6871da153..d948ddb916 100644 --- a/codex-rs/core/src/config.rs +++ b/codex-rs/core/src/config.rs @@ -42,6 +42,11 @@ pub struct Config { pub shell_environment_policy: ShellEnvironmentPolicy, + /// When `true`, `AgentReasoning` events emitted by the backend will be + /// suppressed from the frontend output. This can reduce visual noise when + /// users are only interested in the final agent responses. + pub hide_agent_reasoning: bool, + /// Disable server-side response storage (sends the full conversation /// context with every request). Currently necessary for OpenAI customers /// who have opted into Zero Data Retention (ZDR). @@ -272,6 +277,10 @@ pub struct ConfigToml { /// Collection of settings that are specific to the TUI. pub tui: Option, + + /// When set to `true`, `AgentReasoning` events will be hidden from the + /// UI/output. Defaults to `false`. + pub hide_agent_reasoning: Option, } fn deserialize_sandbox_permissions<'de, D>( @@ -433,6 +442,8 @@ impl Config { file_opener: cfg.file_opener.unwrap_or(UriBasedFileOpener::VsCode), tui: cfg.tui.unwrap_or_default(), codex_linux_sandbox_exe, + + hide_agent_reasoning: cfg.hide_agent_reasoning.unwrap_or(false), }; Ok(config) } @@ -774,6 +785,7 @@ disable_response_storage = true file_opener: UriBasedFileOpener::VsCode, tui: Tui::default(), codex_linux_sandbox_exe: None, + hide_agent_reasoning: false, }, o3_profile_config ); @@ -813,6 +825,7 @@ disable_response_storage = true file_opener: UriBasedFileOpener::VsCode, tui: Tui::default(), codex_linux_sandbox_exe: None, + hide_agent_reasoning: false, }; assert_eq!(expected_gpt3_profile_config, gpt3_profile_config); @@ -867,6 +880,7 @@ disable_response_storage = true file_opener: UriBasedFileOpener::VsCode, tui: Tui::default(), codex_linux_sandbox_exe: None, + hide_agent_reasoning: false, }; assert_eq!(expected_zdr_profile_config, zdr_profile_config); diff --git a/codex-rs/exec/src/event_processor.rs b/codex-rs/exec/src/event_processor.rs index 57a6cbc9ac..89ad7d7cde 100644 --- a/codex-rs/exec/src/event_processor.rs +++ b/codex-rs/exec/src/event_processor.rs @@ -43,10 +43,13 @@ pub(crate) struct EventProcessor { red: Style, green: Style, cyan: Style, + + /// Whether to include `AgentReasoning` events in the output. + show_agent_reasoning: bool, } impl EventProcessor { - pub(crate) fn create_with_ansi(with_ansi: bool) -> Self { + pub(crate) fn create_with_ansi(with_ansi: bool, show_agent_reasoning: bool) -> Self { let call_id_to_command = HashMap::new(); let call_id_to_patch = HashMap::new(); let call_id_to_tool_call = HashMap::new(); @@ -63,6 +66,7 @@ impl EventProcessor { green: Style::new().green(), cyan: Style::new().cyan(), call_id_to_tool_call, + show_agent_reasoning, } } else { Self { @@ -76,6 +80,7 @@ impl EventProcessor { green: Style::new(), cyan: Style::new(), call_id_to_tool_call, + show_agent_reasoning, } } } @@ -411,12 +416,14 @@ impl EventProcessor { // Should we exit? } EventMsg::AgentReasoning(agent_reasoning_event) => { - ts_println!( - self, - "{}\n{}", - "thinking".style(self.italic).style(self.magenta), - agent_reasoning_event.text - ); + if self.show_agent_reasoning { + ts_println!( + self, + "{}\n{}", + "thinking".style(self.italic).style(self.magenta), + agent_reasoning_event.text + ); + } } EventMsg::SessionConfigured(session_configured_event) => { let SessionConfiguredEvent { diff --git a/codex-rs/exec/src/lib.rs b/codex-rs/exec/src/lib.rs index e203c2f161..925e25d670 100644 --- a/codex-rs/exec/src/lib.rs +++ b/codex-rs/exec/src/lib.rs @@ -112,7 +112,8 @@ pub async fn run_main(cli: Cli, codex_linux_sandbox_exe: Option) -> any }; let config = Config::load_with_cli_overrides(cli_kv_overrides, overrides)?; - let mut event_processor = EventProcessor::create_with_ansi(stdout_with_ansi); + let mut event_processor = + EventProcessor::create_with_ansi(stdout_with_ansi, !config.hide_agent_reasoning); // Print the effective configuration and prompt so users can see what Codex // is using. event_processor.print_config_summary(&config, &prompt); diff --git a/codex-rs/tui/src/chatwidget.rs b/codex-rs/tui/src/chatwidget.rs index 4819be3809..63f3bc727a 100644 --- a/codex-rs/tui/src/chatwidget.rs +++ b/codex-rs/tui/src/chatwidget.rs @@ -239,9 +239,11 @@ impl ChatWidget<'_> { self.request_redraw(); } EventMsg::AgentReasoning(AgentReasoningEvent { text }) => { - self.conversation_history - .add_agent_reasoning(&self.config, text); - self.request_redraw(); + if !self.config.hide_agent_reasoning { + self.conversation_history + .add_agent_reasoning(&self.config, text); + self.request_redraw(); + } } EventMsg::TaskStarted => { self.bottom_pane.set_task_running(true);