slash command for enabling search for the session

This commit is contained in:
easong-openai
2025-09-08 15:07:44 -07:00
parent 3f40fbc0a8
commit c56b871369
7 changed files with 72 additions and 1 deletions
+5 -1
View File
@@ -1054,6 +1054,7 @@ async fn submission_loop(
model,
effort,
summary,
include_web_search_request,
} => {
// Recalculate the persistent turn context with provided overrides.
let prev = Arc::clone(&turn_context);
@@ -1097,13 +1098,16 @@ async fn submission_loop(
.unwrap_or(prev.sandbox_policy.clone());
let new_cwd = cwd.clone().unwrap_or_else(|| prev.cwd.clone());
let effective_web_search =
include_web_search_request.unwrap_or(prev.tools_config.web_search_request);
let tools_config = ToolsConfig::new(&ToolsConfigParams {
model_family: &effective_family,
approval_policy: new_approval_policy,
sandbox_policy: new_sandbox_policy.clone(),
include_plan_tool: config.include_plan_tool,
include_apply_patch_tool: config.include_apply_patch_tool,
include_web_search_request: config.tools_web_search_request,
include_web_search_request: effective_web_search,
use_streamable_shell_tool: config.use_experimental_streamable_shell_tool,
include_view_image_tool: config.include_view_image_tool,
});
@@ -393,6 +393,7 @@ async fn overrides_turn_context_but_keeps_cached_prefix_and_key_constant() {
model: Some("o3".to_string()),
effort: Some(ReasoningEffort::High),
summary: Some(ReasoningSummary::Detailed),
include_web_search_request: None,
})
.await
.unwrap();
+6
View File
@@ -116,6 +116,12 @@ pub enum Op {
/// Updated reasoning summary preference (honored only for reasoning-capable models).
#[serde(skip_serializing_if = "Option::is_none")]
summary: Option<ReasoningSummaryConfig>,
/// Toggle availability of the `web_search` tool in subsequent turns.
/// When `Some(true)`, include the web search tool; when `Some(false)`,
/// exclude it. When `None`, preserve the previous session state.
#[serde(skip_serializing_if = "Option::is_none")]
include_web_search_request: Option<bool>,
},
/// Approve a command execution
+3
View File
@@ -308,6 +308,9 @@ impl App {
AppEvent::UpdateSandboxPolicy(policy) => {
self.chat_widget.set_sandbox_policy(policy);
}
AppEvent::UpdateWebSearchRequest(enabled) => {
self.chat_widget.set_web_search_enabled(enabled);
}
}
Ok(true)
}
+3
View File
@@ -57,6 +57,9 @@ pub(crate) enum AppEvent {
/// Update the current sandbox policy in the running app and widget.
UpdateSandboxPolicy(SandboxPolicy),
/// Update whether the web_search tool is available for this session.
UpdateWebSearchRequest(bool),
/// Forwarded conversation history snapshot from the current conversation.
ConversationHistory(ConversationHistoryResponseEvent),
}
+51
View File
@@ -832,6 +832,9 @@ impl ChatWidget {
SlashCommand::Approvals => {
self.open_approvals_popup();
}
SlashCommand::Search => {
self.open_search_popup();
}
SlashCommand::Quit => {
self.app_event_tx.send(AppEvent::ExitRequest);
}
@@ -1174,6 +1177,7 @@ impl ChatWidget {
model: Some(model_slug.clone()),
effort: Some(effort),
summary: None,
include_web_search_request: None,
}));
tx.send(AppEvent::UpdateModel(model_slug.clone()));
tx.send(AppEvent::UpdateReasoningEffort(effort));
@@ -1222,6 +1226,7 @@ impl ChatWidget {
model: None,
effort: None,
summary: None,
include_web_search_request: None,
}));
tx.send(AppEvent::UpdateAskForApprovalPolicy(approval));
tx.send(AppEvent::UpdateSandboxPolicy(sandbox.clone()));
@@ -1242,6 +1247,47 @@ impl ChatWidget {
);
}
pub(crate) fn open_search_popup(&mut self) {
let cur = self.config.tools_web_search_request;
let mut items: Vec<SelectionItem> = Vec::new();
for (name, enabled, desc) in [
("Search Disabled", false, None),
(
"Search Enabled for Session",
true,
Some("Makes the web_search tool available to the model".to_string()),
),
] {
let is_current = cur == enabled;
let actions: Vec<SelectionAction> = vec![Box::new(move |tx| {
tx.send(AppEvent::CodexOp(Op::OverrideTurnContext {
cwd: None,
approval_policy: None,
sandbox_policy: None,
model: None,
effort: None,
summary: None,
include_web_search_request: Some(enabled),
}));
tx.send(AppEvent::UpdateWebSearchRequest(enabled));
})];
items.push(SelectionItem {
name: name.to_string(),
description: desc.clone(),
is_current,
actions,
});
}
self.bottom_pane.show_selection_view(
"Select Web Search".to_string(),
Some("Toggle web search tool availability for this session".to_string()),
Some("Press Enter to confirm or Esc to go back".to_string()),
items,
);
}
/// Set the approval policy in the widget's config copy.
pub(crate) fn set_approval_policy(&mut self, policy: AskForApproval) {
self.config.approval_policy = policy;
@@ -1262,6 +1308,11 @@ impl ChatWidget {
self.config.model = model;
}
/// Set web search tool availability in the widget's config copy.
pub(crate) fn set_web_search_enabled(&mut self, enabled: bool) {
self.config.tools_web_search_request = enabled;
}
pub(crate) fn add_mcp_output(&mut self) {
if self.config.mcp_servers.is_empty() {
self.add_to_history(history_cell::empty_mcp_output());
+3
View File
@@ -14,6 +14,7 @@ pub enum SlashCommand {
// more frequently used commands should be listed first.
Model,
Approvals,
Search,
New,
Init,
Compact,
@@ -40,6 +41,7 @@ impl SlashCommand {
SlashCommand::Status => "show current session configuration and token usage",
SlashCommand::Model => "choose what model and reasoning effort to use",
SlashCommand::Approvals => "choose what Codex can do without approval",
SlashCommand::Search => "enable or disable web search for this session",
SlashCommand::Mcp => "list configured MCP tools",
SlashCommand::Logout => "log out of Codex",
#[cfg(debug_assertions)]
@@ -61,6 +63,7 @@ impl SlashCommand {
| SlashCommand::Compact
| SlashCommand::Model
| SlashCommand::Approvals
| SlashCommand::Search
| SlashCommand::Logout => false,
SlashCommand::Diff
| SlashCommand::Mention