mirror of
https://github.com/openai/codex.git
synced 2026-02-02 15:03:38 +00:00
Compare commits
1 Commits
bazelversi
...
search
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
47bf6b9667 |
@@ -1050,6 +1050,7 @@ impl CodexMessageProcessor {
|
||||
effort,
|
||||
summary,
|
||||
final_output_json_schema: None,
|
||||
disabled_tools: None,
|
||||
})
|
||||
.await;
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ use crate::model_family::ModelFamily;
|
||||
use crate::model_provider_info::ModelProviderInfo;
|
||||
use crate::model_provider_info::WireApi;
|
||||
use crate::openai_model_info::get_model_info;
|
||||
use crate::openai_tools::create_allowed_tools_json_for_responses_api;
|
||||
use crate::openai_tools::create_tools_json_for_responses_api;
|
||||
use crate::protocol::RateLimitSnapshot;
|
||||
use crate::protocol::RateLimitWindow;
|
||||
@@ -54,6 +55,7 @@ use codex_otel::otel_event_manager::OtelEventManager;
|
||||
use codex_protocol::config_types::ReasoningEffort as ReasoningEffortConfig;
|
||||
use codex_protocol::config_types::ReasoningSummary as ReasoningSummaryConfig;
|
||||
use codex_protocol::models::ResponseItem;
|
||||
use std::collections::HashSet;
|
||||
use std::sync::Arc;
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
@@ -233,13 +235,39 @@ impl ModelClient {
|
||||
//
|
||||
// For Azure, we send `store: true` and preserve reasoning item IDs.
|
||||
let azure_workaround = self.provider.is_azure_responses_endpoint();
|
||||
let tool_choice = if let Some(disabled) = &prompt.disabled_tools {
|
||||
if disabled.is_empty() {
|
||||
serde_json::json!("auto")
|
||||
} else {
|
||||
let allowed = create_allowed_tools_json_for_responses_api(&prompt.tools, disabled);
|
||||
let total_unique = prompt
|
||||
.tools
|
||||
.iter()
|
||||
.map(super::client_common::tools::ToolSpec::name)
|
||||
.collect::<HashSet<_>>()
|
||||
.len();
|
||||
if allowed.is_empty() {
|
||||
serde_json::json!("none")
|
||||
} else if allowed.len() == total_unique {
|
||||
serde_json::json!("auto")
|
||||
} else {
|
||||
serde_json::json!({
|
||||
"type": "allowed_tools",
|
||||
"mode": "auto",
|
||||
"tools": allowed,
|
||||
})
|
||||
}
|
||||
}
|
||||
} else {
|
||||
serde_json::json!("auto")
|
||||
};
|
||||
|
||||
let payload = ResponsesApiRequest {
|
||||
model: &self.config.model,
|
||||
instructions: &full_instructions,
|
||||
input: &input_with_instructions,
|
||||
tools: &tools_json,
|
||||
tool_choice: "auto",
|
||||
tool_choice,
|
||||
parallel_tool_calls: prompt.parallel_tool_calls,
|
||||
reasoning,
|
||||
store: azure_workaround,
|
||||
|
||||
@@ -41,6 +41,9 @@ pub struct Prompt {
|
||||
|
||||
/// Optional the output schema for the model's response.
|
||||
pub output_schema: Option<Value>,
|
||||
|
||||
/// Optional list of tool names to disable for this prompt.
|
||||
pub disabled_tools: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
impl Prompt {
|
||||
@@ -268,7 +271,7 @@ pub(crate) struct ResponsesApiRequest<'a> {
|
||||
// separate enum for serialization.
|
||||
pub(crate) input: &'a Vec<ResponseItem>,
|
||||
pub(crate) tools: &'a [serde_json::Value],
|
||||
pub(crate) tool_choice: &'static str,
|
||||
pub(crate) tool_choice: Value,
|
||||
pub(crate) parallel_tool_calls: bool,
|
||||
pub(crate) reasoning: Option<Reasoning>,
|
||||
pub(crate) store: bool,
|
||||
@@ -457,7 +460,7 @@ mod tests {
|
||||
instructions: "i",
|
||||
input: &input,
|
||||
tools: &tools,
|
||||
tool_choice: "auto",
|
||||
tool_choice: serde_json::json!("auto"),
|
||||
parallel_tool_calls: true,
|
||||
reasoning: None,
|
||||
store: false,
|
||||
@@ -498,7 +501,7 @@ mod tests {
|
||||
instructions: "i",
|
||||
input: &input,
|
||||
tools: &tools,
|
||||
tool_choice: "auto",
|
||||
tool_choice: serde_json::json!("auto"),
|
||||
parallel_tool_calls: true,
|
||||
reasoning: None,
|
||||
store: false,
|
||||
@@ -534,7 +537,7 @@ mod tests {
|
||||
instructions: "i",
|
||||
input: &input,
|
||||
tools: &tools,
|
||||
tool_choice: "auto",
|
||||
tool_choice: serde_json::json!("auto"),
|
||||
parallel_tool_calls: true,
|
||||
reasoning: None,
|
||||
store: false,
|
||||
|
||||
@@ -265,6 +265,7 @@ pub(crate) struct TurnContext {
|
||||
pub(crate) tools_config: ToolsConfig,
|
||||
pub(crate) is_review_mode: bool,
|
||||
pub(crate) final_output_json_schema: Option<Value>,
|
||||
pub(crate) disabled_tools: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
impl TurnContext {
|
||||
@@ -488,6 +489,7 @@ impl Session {
|
||||
cwd,
|
||||
is_review_mode: false,
|
||||
final_output_json_schema: None,
|
||||
disabled_tools: None,
|
||||
};
|
||||
let services = SessionServices {
|
||||
mcp_connection_manager,
|
||||
@@ -1171,6 +1173,7 @@ async fn submission_loop(
|
||||
model,
|
||||
effort,
|
||||
summary,
|
||||
disabled_tools,
|
||||
} => {
|
||||
// Recalculate the persistent turn context with provided overrides.
|
||||
let prev = Arc::clone(&turn_context);
|
||||
@@ -1219,6 +1222,9 @@ async fn submission_loop(
|
||||
.clone()
|
||||
.unwrap_or(prev.sandbox_policy.clone());
|
||||
let new_cwd = cwd.clone().unwrap_or_else(|| prev.cwd.clone());
|
||||
let new_disabled_tools = disabled_tools
|
||||
.clone()
|
||||
.or_else(|| prev.disabled_tools.clone());
|
||||
|
||||
let tools_config = ToolsConfig::new(&ToolsConfigParams {
|
||||
model_family: &effective_family,
|
||||
@@ -1236,6 +1242,7 @@ async fn submission_loop(
|
||||
cwd: new_cwd.clone(),
|
||||
is_review_mode: false,
|
||||
final_output_json_schema: None,
|
||||
disabled_tools: new_disabled_tools,
|
||||
};
|
||||
|
||||
// Install the new persistent context for subsequent tasks/turns.
|
||||
@@ -1274,6 +1281,7 @@ async fn submission_loop(
|
||||
effort,
|
||||
summary,
|
||||
final_output_json_schema,
|
||||
disabled_tools,
|
||||
} => {
|
||||
turn_context
|
||||
.client
|
||||
@@ -1314,6 +1322,9 @@ async fn submission_loop(
|
||||
summary,
|
||||
sess.conversation_id,
|
||||
);
|
||||
let effective_disabled_tools = disabled_tools
|
||||
.clone()
|
||||
.or_else(|| turn_context.disabled_tools.clone());
|
||||
|
||||
let fresh_turn_context = TurnContext {
|
||||
client,
|
||||
@@ -1329,6 +1340,7 @@ async fn submission_loop(
|
||||
cwd,
|
||||
is_review_mode: false,
|
||||
final_output_json_schema,
|
||||
disabled_tools: effective_disabled_tools.clone(),
|
||||
};
|
||||
|
||||
// if the environment context has changed, record it in the conversation history
|
||||
@@ -1608,6 +1620,7 @@ async fn spawn_review_thread(
|
||||
cwd: parent_turn_context.cwd.clone(),
|
||||
is_review_mode: true,
|
||||
final_output_json_schema: None,
|
||||
disabled_tools: parent_turn_context.disabled_tools.clone(),
|
||||
};
|
||||
|
||||
// Seed the child task with the review prompt as the initial user message.
|
||||
@@ -1980,6 +1993,7 @@ async fn run_turn(
|
||||
parallel_tool_calls,
|
||||
base_instructions_override: turn_context.base_instructions.clone(),
|
||||
output_schema: turn_context.final_output_json_schema.clone(),
|
||||
disabled_tools: turn_context.disabled_tools.clone(),
|
||||
};
|
||||
|
||||
let mut retries = 0;
|
||||
@@ -2787,6 +2801,7 @@ mod tests {
|
||||
tools_config,
|
||||
is_review_mode: false,
|
||||
final_output_json_schema: None,
|
||||
disabled_tools: None,
|
||||
};
|
||||
let services = SessionServices {
|
||||
mcp_connection_manager: McpConnectionManager::default(),
|
||||
@@ -2855,6 +2870,7 @@ mod tests {
|
||||
tools_config,
|
||||
is_review_mode: false,
|
||||
final_output_json_schema: None,
|
||||
disabled_tools: None,
|
||||
});
|
||||
let services = SessionServices {
|
||||
mcp_connection_manager: McpConnectionManager::default(),
|
||||
|
||||
@@ -92,6 +92,7 @@ async fn run_compact_task_inner(
|
||||
loop {
|
||||
let prompt = Prompt {
|
||||
input: turn_input.clone(),
|
||||
disabled_tools: turn_context.disabled_tools.clone(),
|
||||
..Default::default()
|
||||
};
|
||||
let attempt_result =
|
||||
|
||||
@@ -145,6 +145,22 @@ impl ToolRouter {
|
||||
let payload_outputs_custom = matches!(payload, ToolPayload::Custom { .. });
|
||||
let failure_call_id = call_id.clone();
|
||||
|
||||
if turn
|
||||
.disabled_tools
|
||||
.as_ref()
|
||||
.map(|tools| tools.iter().any(|name| name == &tool_name))
|
||||
.unwrap_or(false)
|
||||
{
|
||||
let err = FunctionCallError::RespondToModel(format!(
|
||||
"tool {tool_name} is disabled for this turn"
|
||||
));
|
||||
return Ok(Self::failure_response(
|
||||
failure_call_id,
|
||||
payload_outputs_custom,
|
||||
err,
|
||||
));
|
||||
}
|
||||
|
||||
let invocation = ToolInvocation {
|
||||
session,
|
||||
turn,
|
||||
|
||||
@@ -14,6 +14,7 @@ use serde_json::Value as JsonValue;
|
||||
use serde_json::json;
|
||||
use std::collections::BTreeMap;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::HashSet;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum ConfigShellToolType {
|
||||
@@ -532,6 +533,40 @@ pub fn create_tools_json_for_responses_api(
|
||||
|
||||
Ok(tools_json)
|
||||
}
|
||||
|
||||
pub fn create_allowed_tools_json_for_responses_api(
|
||||
tools: &[ToolSpec],
|
||||
disabled_names: &[String],
|
||||
) -> Vec<serde_json::Value> {
|
||||
let disabled_set: HashSet<&str> = disabled_names
|
||||
.iter()
|
||||
.map(std::string::String::as_str)
|
||||
.collect();
|
||||
let mut seen = HashSet::new();
|
||||
let mut allowed = Vec::new();
|
||||
|
||||
for spec in tools {
|
||||
let name = spec.name();
|
||||
if disabled_set.contains(name) || !seen.insert(name) {
|
||||
continue;
|
||||
}
|
||||
let value = match spec {
|
||||
ToolSpec::Function(tool) => json!({
|
||||
"type": "function",
|
||||
"name": tool.name,
|
||||
}),
|
||||
ToolSpec::Freeform(tool) => json!({
|
||||
"type": "custom",
|
||||
"name": tool.name,
|
||||
}),
|
||||
ToolSpec::LocalShell {} => json!({ "type": "local_shell" }),
|
||||
ToolSpec::WebSearch {} => json!({ "type": "web_search" }),
|
||||
};
|
||||
allowed.push(value);
|
||||
}
|
||||
|
||||
allowed
|
||||
}
|
||||
/// Returns JSON values that are compatible with Function Calling in the
|
||||
/// Chat Completions API:
|
||||
/// https://platform.openai.com/docs/guides/function-calling?api-mode=chat
|
||||
@@ -1093,6 +1128,33 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn create_allowed_tools_excludes_disabled_entries() {
|
||||
let shell = super::create_shell_tool();
|
||||
let web_search = ToolSpec::WebSearch {};
|
||||
let view_image = super::create_view_image_tool();
|
||||
|
||||
let specs = vec![shell, web_search, view_image];
|
||||
|
||||
let allowed = super::create_allowed_tools_json_for_responses_api(
|
||||
&specs,
|
||||
&[String::from("web_search")],
|
||||
);
|
||||
|
||||
assert_eq!(allowed.len(), 2);
|
||||
assert!(allowed.iter().any(|tool| {
|
||||
tool.get("type") == Some(&serde_json::Value::String("function".into()))
|
||||
&& tool.get("name") == Some(&serde_json::Value::String("shell".into()))
|
||||
}));
|
||||
assert!(allowed.iter().any(|tool| {
|
||||
tool.get("type") == Some(&serde_json::Value::String("function".into()))
|
||||
&& tool.get("name") == Some(&serde_json::Value::String("view_image".into()))
|
||||
}));
|
||||
assert!(allowed.iter().all(|tool| {
|
||||
tool.get("name") != Some(&serde_json::Value::String("web_search".into()))
|
||||
}));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_build_specs_mcp_tools_sorted_by_name() {
|
||||
let model_family = find_family_for_model("o3").expect("o3 should be a valid model family");
|
||||
|
||||
@@ -124,6 +124,7 @@ async fn compact_resume_and_fork_preserve_model_history_view() {
|
||||
.unwrap_or_default()
|
||||
.to_string();
|
||||
let tool_calls = json!(requests[0]["tools"].as_array());
|
||||
let tool_choice_request_1 = requests[0]["tool_choice"].clone();
|
||||
let prompt_cache_key = requests[0]["prompt_cache_key"]
|
||||
.as_str()
|
||||
.unwrap_or_default()
|
||||
@@ -132,6 +133,10 @@ async fn compact_resume_and_fork_preserve_model_history_view() {
|
||||
.as_str()
|
||||
.unwrap_or_default()
|
||||
.to_string();
|
||||
let tool_choice_compact_1 = requests[1]["tool_choice"].clone();
|
||||
let tool_choice_after_compact = requests[2]["tool_choice"].clone();
|
||||
let tool_choice_after_resume = requests[3]["tool_choice"].clone();
|
||||
let tool_choice_after_fork = requests[4]["tool_choice"].clone();
|
||||
let expected_model = OPENAI_DEFAULT_MODEL;
|
||||
let user_turn_1 = json!(
|
||||
{
|
||||
@@ -170,7 +175,7 @@ async fn compact_resume_and_fork_preserve_model_history_view() {
|
||||
}
|
||||
],
|
||||
"tools": tool_calls,
|
||||
"tool_choice": "auto",
|
||||
"tool_choice": tool_choice_request_1,
|
||||
"parallel_tool_calls": false,
|
||||
"reasoning": {
|
||||
"summary": "auto"
|
||||
@@ -239,7 +244,7 @@ async fn compact_resume_and_fork_preserve_model_history_view() {
|
||||
}
|
||||
],
|
||||
"tools": [],
|
||||
"tool_choice": "auto",
|
||||
"tool_choice": tool_choice_compact_1,
|
||||
"parallel_tool_calls": false,
|
||||
"reasoning": {
|
||||
"summary": "auto"
|
||||
@@ -304,7 +309,7 @@ SUMMARY_ONLY_CONTEXT"
|
||||
}
|
||||
],
|
||||
"tools": tool_calls,
|
||||
"tool_choice": "auto",
|
||||
"tool_choice": tool_choice_after_compact,
|
||||
"parallel_tool_calls": false,
|
||||
"reasoning": {
|
||||
"summary": "auto"
|
||||
@@ -389,7 +394,7 @@ SUMMARY_ONLY_CONTEXT"
|
||||
}
|
||||
],
|
||||
"tools": tool_calls,
|
||||
"tool_choice": "auto",
|
||||
"tool_choice": tool_choice_after_resume,
|
||||
"parallel_tool_calls": false,
|
||||
"reasoning": {
|
||||
"summary": "auto"
|
||||
@@ -474,7 +479,7 @@ SUMMARY_ONLY_CONTEXT"
|
||||
}
|
||||
],
|
||||
"tools": tool_calls,
|
||||
"tool_choice": "auto",
|
||||
"tool_choice": tool_choice_after_fork,
|
||||
"parallel_tool_calls": false,
|
||||
"reasoning": {
|
||||
"summary": "auto"
|
||||
|
||||
@@ -159,6 +159,7 @@ async fn submit_turn(test: &TestCodex, prompt: &str) -> Result<()> {
|
||||
model: session_model,
|
||||
effort: None,
|
||||
summary: ReasoningSummary::Auto,
|
||||
disabled_tools: None,
|
||||
})
|
||||
.await?;
|
||||
|
||||
|
||||
@@ -84,6 +84,7 @@ async fn codex_returns_json_result(model: String) -> anyhow::Result<()> {
|
||||
model,
|
||||
effort: None,
|
||||
summary: ReasoningSummary::Auto,
|
||||
disabled_tools: None,
|
||||
})
|
||||
.await?;
|
||||
|
||||
|
||||
@@ -76,6 +76,7 @@ async fn list_dir_tool_returns_entries() -> anyhow::Result<()> {
|
||||
model: session_model,
|
||||
effort: None,
|
||||
summary: ReasoningSummary::Auto,
|
||||
disabled_tools: None,
|
||||
})
|
||||
.await?;
|
||||
|
||||
@@ -181,6 +182,7 @@ async fn list_dir_tool_depth_one_omits_children() -> anyhow::Result<()> {
|
||||
model: session_model,
|
||||
effort: None,
|
||||
summary: ReasoningSummary::Auto,
|
||||
disabled_tools: None,
|
||||
})
|
||||
.await?;
|
||||
|
||||
@@ -293,6 +295,7 @@ async fn list_dir_tool_depth_two_includes_children_only() -> anyhow::Result<()>
|
||||
model: session_model,
|
||||
effort: None,
|
||||
summary: ReasoningSummary::Auto,
|
||||
disabled_tools: None,
|
||||
})
|
||||
.await?;
|
||||
|
||||
@@ -408,6 +411,7 @@ async fn list_dir_tool_depth_three_includes_grandchildren() -> anyhow::Result<()
|
||||
model: session_model,
|
||||
effort: None,
|
||||
summary: ReasoningSummary::Auto,
|
||||
disabled_tools: None,
|
||||
})
|
||||
.await?;
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ async fn override_turn_context_does_not_persist_when_config_exists() {
|
||||
model: Some("o3".to_string()),
|
||||
effort: Some(Some(ReasoningEffort::High)),
|
||||
summary: None,
|
||||
disabled_tools: None,
|
||||
})
|
||||
.await
|
||||
.expect("submit override");
|
||||
@@ -78,6 +79,7 @@ async fn override_turn_context_does_not_create_config_file() {
|
||||
model: Some("o3".to_string()),
|
||||
effort: Some(Some(ReasoningEffort::Medium)),
|
||||
summary: None,
|
||||
disabled_tools: None,
|
||||
})
|
||||
.await
|
||||
.expect("submit override");
|
||||
|
||||
@@ -443,6 +443,7 @@ async fn overrides_turn_context_but_keeps_cached_prefix_and_key_constant() {
|
||||
model: Some("o3".to_string()),
|
||||
effort: Some(Some(ReasoningEffort::High)),
|
||||
summary: Some(ReasoningSummary::Detailed),
|
||||
disabled_tools: None,
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
@@ -577,6 +578,7 @@ async fn per_turn_overrides_keep_cached_prefix_and_key_constant() {
|
||||
effort: Some(ReasoningEffort::High),
|
||||
summary: ReasoningSummary::Detailed,
|
||||
final_output_json_schema: None,
|
||||
disabled_tools: None,
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
@@ -688,6 +690,7 @@ async fn send_user_turn_with_no_changes_does_not_send_environment_context() {
|
||||
effort: default_effort,
|
||||
summary: default_summary,
|
||||
final_output_json_schema: None,
|
||||
disabled_tools: None,
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
@@ -705,6 +708,7 @@ async fn send_user_turn_with_no_changes_does_not_send_environment_context() {
|
||||
effort: default_effort,
|
||||
summary: default_summary,
|
||||
final_output_json_schema: None,
|
||||
disabled_tools: None,
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
@@ -802,6 +806,7 @@ async fn send_user_turn_with_changes_sends_environment_context() {
|
||||
effort: default_effort,
|
||||
summary: default_summary,
|
||||
final_output_json_schema: None,
|
||||
disabled_tools: None,
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
@@ -819,6 +824,7 @@ async fn send_user_turn_with_changes_sends_environment_context() {
|
||||
effort: Some(ReasoningEffort::High),
|
||||
summary: ReasoningSummary::Detailed,
|
||||
final_output_json_schema: None,
|
||||
disabled_tools: None,
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
@@ -74,6 +74,7 @@ async fn read_file_tool_returns_requested_lines() -> anyhow::Result<()> {
|
||||
model: session_model,
|
||||
effort: None,
|
||||
summary: ReasoningSummary::Auto,
|
||||
disabled_tools: None,
|
||||
})
|
||||
.await?;
|
||||
|
||||
|
||||
@@ -110,6 +110,7 @@ async fn stdio_server_round_trip() -> anyhow::Result<()> {
|
||||
model: session_model,
|
||||
effort: None,
|
||||
summary: ReasoningSummary::Auto,
|
||||
disabled_tools: None,
|
||||
})
|
||||
.await?;
|
||||
|
||||
@@ -259,6 +260,7 @@ async fn streamable_http_tool_call_round_trip() -> anyhow::Result<()> {
|
||||
model: session_model,
|
||||
effort: None,
|
||||
summary: ReasoningSummary::Auto,
|
||||
disabled_tools: None,
|
||||
})
|
||||
.await?;
|
||||
|
||||
@@ -440,6 +442,7 @@ async fn streamable_http_with_oauth_round_trip() -> anyhow::Result<()> {
|
||||
model: session_model,
|
||||
effort: None,
|
||||
summary: ReasoningSummary::Auto,
|
||||
disabled_tools: None,
|
||||
})
|
||||
.await?;
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ async fn submit_turn(test: &TestCodex, prompt: &str, sandbox_policy: SandboxPoli
|
||||
model: session_model,
|
||||
effort: None,
|
||||
summary: ReasoningSummary::Auto,
|
||||
disabled_tools: None,
|
||||
})
|
||||
.await?;
|
||||
|
||||
|
||||
@@ -84,6 +84,7 @@ async fn shell_tool_executes_command_and_streams_output() -> anyhow::Result<()>
|
||||
model: session_model,
|
||||
effort: None,
|
||||
summary: ReasoningSummary::Auto,
|
||||
disabled_tools: None,
|
||||
})
|
||||
.await?;
|
||||
|
||||
@@ -153,6 +154,7 @@ async fn update_plan_tool_emits_plan_update_event() -> anyhow::Result<()> {
|
||||
model: session_model,
|
||||
effort: None,
|
||||
summary: ReasoningSummary::Auto,
|
||||
disabled_tools: None,
|
||||
})
|
||||
.await?;
|
||||
|
||||
@@ -236,6 +238,7 @@ async fn update_plan_tool_rejects_malformed_payload() -> anyhow::Result<()> {
|
||||
model: session_model,
|
||||
effort: None,
|
||||
summary: ReasoningSummary::Auto,
|
||||
disabled_tools: None,
|
||||
})
|
||||
.await?;
|
||||
|
||||
@@ -334,6 +337,7 @@ async fn apply_patch_tool_executes_and_emits_patch_events() -> anyhow::Result<()
|
||||
model: session_model,
|
||||
effort: None,
|
||||
summary: ReasoningSummary::Auto,
|
||||
disabled_tools: None,
|
||||
})
|
||||
.await?;
|
||||
|
||||
@@ -435,6 +439,7 @@ async fn apply_patch_reports_parse_diagnostics() -> anyhow::Result<()> {
|
||||
model: session_model,
|
||||
effort: None,
|
||||
summary: ReasoningSummary::Auto,
|
||||
disabled_tools: None,
|
||||
})
|
||||
.await?;
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ async fn run_turn(test: &TestCodex, prompt: &str) -> anyhow::Result<()> {
|
||||
model: session_model,
|
||||
effort: None,
|
||||
summary: ReasoningSummary::Auto,
|
||||
disabled_tools: None,
|
||||
})
|
||||
.await?;
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@ async fn submit_turn(
|
||||
model: session_model,
|
||||
effort: None,
|
||||
summary: ReasoningSummary::Auto,
|
||||
disabled_tools: None,
|
||||
})
|
||||
.await?;
|
||||
|
||||
|
||||
@@ -128,6 +128,7 @@ async fn unified_exec_reuses_session_via_stdin() -> Result<()> {
|
||||
model: session_model,
|
||||
effort: None,
|
||||
summary: ReasoningSummary::Auto,
|
||||
disabled_tools: None,
|
||||
})
|
||||
.await?;
|
||||
|
||||
@@ -264,6 +265,7 @@ PY
|
||||
model: session_model,
|
||||
effort: None,
|
||||
summary: ReasoningSummary::Auto,
|
||||
disabled_tools: None,
|
||||
})
|
||||
.await?;
|
||||
|
||||
@@ -370,6 +372,7 @@ async fn unified_exec_timeout_and_followup_poll() -> Result<()> {
|
||||
model: session_model,
|
||||
effort: None,
|
||||
summary: ReasoningSummary::Auto,
|
||||
disabled_tools: None,
|
||||
})
|
||||
.await?;
|
||||
|
||||
|
||||
@@ -100,6 +100,7 @@ async fn view_image_tool_attaches_local_image() -> anyhow::Result<()> {
|
||||
model: session_model,
|
||||
effort: None,
|
||||
summary: ReasoningSummary::Auto,
|
||||
disabled_tools: None,
|
||||
})
|
||||
.await?;
|
||||
|
||||
@@ -199,6 +200,7 @@ async fn view_image_tool_errors_when_path_is_directory() -> anyhow::Result<()> {
|
||||
model: session_model,
|
||||
effort: None,
|
||||
summary: ReasoningSummary::Auto,
|
||||
disabled_tools: None,
|
||||
})
|
||||
.await?;
|
||||
|
||||
@@ -264,6 +266,7 @@ async fn view_image_tool_errors_when_file_missing() -> anyhow::Result<()> {
|
||||
model: session_model,
|
||||
effort: None,
|
||||
summary: ReasoningSummary::Auto,
|
||||
disabled_tools: None,
|
||||
})
|
||||
.await?;
|
||||
|
||||
|
||||
@@ -348,6 +348,7 @@ pub async fn run_main(cli: Cli, codex_linux_sandbox_exe: Option<PathBuf>) -> any
|
||||
effort: default_effort,
|
||||
summary: default_summary,
|
||||
final_output_json_schema: output_schema,
|
||||
disabled_tools: None,
|
||||
})
|
||||
.await?;
|
||||
info!("Sent prompt with event ID: {initial_prompt_task_id}");
|
||||
|
||||
@@ -90,6 +90,9 @@ pub enum Op {
|
||||
summary: ReasoningSummaryConfig,
|
||||
// The JSON schema to use for the final assistant message
|
||||
final_output_json_schema: Option<Value>,
|
||||
/// Optional list of tool names to disable for this turn.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
disabled_tools: Option<Vec<String>>,
|
||||
},
|
||||
|
||||
/// Override parts of the persistent turn context for subsequent turns.
|
||||
@@ -125,6 +128,9 @@ pub enum Op {
|
||||
/// Updated reasoning summary preference (honored only for reasoning-capable models).
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
summary: Option<ReasoningSummaryConfig>,
|
||||
/// Updated default disabled tool list for subsequent turns.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
disabled_tools: Option<Vec<String>>,
|
||||
},
|
||||
|
||||
/// Approve a command execution
|
||||
|
||||
@@ -1751,6 +1751,7 @@ impl ChatWidget {
|
||||
model: Some(model_for_action.clone()),
|
||||
effort: Some(effort_for_action),
|
||||
summary: None,
|
||||
disabled_tools: None,
|
||||
}));
|
||||
tx.send(AppEvent::UpdateModel(model_for_action.clone()));
|
||||
tx.send(AppEvent::UpdateReasoningEffort(effort_for_action));
|
||||
@@ -1807,6 +1808,7 @@ impl ChatWidget {
|
||||
model: None,
|
||||
effort: None,
|
||||
summary: None,
|
||||
disabled_tools: None,
|
||||
}));
|
||||
tx.send(AppEvent::UpdateAskForApprovalPolicy(approval));
|
||||
tx.send(AppEvent::UpdateSandboxPolicy(sandbox.clone()));
|
||||
|
||||
Reference in New Issue
Block a user