Merge 0b789e78bb into sapling-pr-archive-bolinfest

This commit is contained in:
Michael Bolin
2025-07-10 14:20:18 -07:00
committed by GitHub
12 changed files with 58 additions and 26 deletions

View File

@@ -10,7 +10,7 @@
"devDependencies": {
"@types/bun": "^1.2.11",
"@types/node": "^22.15.21",
"prettier": "^3.5.3",
"prettier": "^3.6.2",
"typescript": "^5.8.3",
},
},
@@ -60,7 +60,7 @@
"once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="],
"prettier": ["prettier@3.5.3", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw=="],
"prettier": ["prettier@3.6.2", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ=="],
"tunnel": ["tunnel@0.0.6", "", {}, "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg=="],

View File

@@ -15,7 +15,7 @@
"devDependencies": {
"@types/bun": "^1.2.11",
"@types/node": "^22.15.21",
"prettier": "^3.5.3",
"prettier": "^3.6.2",
"typescript": "^5.8.3"
}
}

View File

@@ -1,4 +1,4 @@
FROM node:22-slim
FROM node:24-slim
ARG TZ
ENV TZ="$TZ"

10
codex-rs/Cargo.lock generated
View File

@@ -601,7 +601,7 @@ dependencies = [
"clap",
"codex-core",
"serde",
"toml 0.9.0",
"toml 0.9.1",
]
[[package]]
@@ -638,7 +638,7 @@ dependencies = [
"time",
"tokio",
"tokio-util",
"toml 0.9.0",
"toml 0.9.1",
"tracing",
"tree-sitter",
"tree-sitter-bash",
@@ -749,7 +749,7 @@ dependencies = [
"serde",
"serde_json",
"tokio",
"toml 0.9.0",
"toml 0.9.1",
"tracing",
"tracing-subscriber",
]
@@ -4496,9 +4496,9 @@ dependencies = [
[[package]]
name = "toml"
version = "0.9.0"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f271e09bde39ab52250160a67e88577e0559ad77e9085de6e9051a2c4353f8f8"
checksum = "0207d6ed1852c2a124c1fbec61621acb8330d2bf969a5d0643131e9affd985a5"
dependencies = [
"indexmap 2.10.0",
"serde",

View File

@@ -206,6 +206,14 @@ To disable reasoning summaries, set `model_reasoning_summary` to `"none"` in you
model_reasoning_summary = "none" # disable reasoning summaries
```
## model_supports_reasoning_summaries
By default, `reasoning` is only set on requests to OpenAI models that are known to support them. To force `reasoning` to set on requests to the current model, you can force this behavior by setting the following in `config.toml`:
```toml
model_supports_reasoning_summaries = true
```
## sandbox_mode
Codex executes model-generated shell commands inside an OS-level sandbox.

View File

@@ -39,7 +39,7 @@ tokio = { version = "1", features = [
"signal",
] }
tokio-util = "0.7.14"
toml = "0.9.0"
toml = "0.9.1"
tracing = { version = "0.1.41", features = ["log"] }
tree-sitter = "0.25.3"
tree-sitter-bash = "0.25.0"

View File

@@ -23,6 +23,7 @@ use crate::client_common::ResponseEvent;
use crate::client_common::ResponseStream;
use crate::client_common::ResponsesApiRequest;
use crate::client_common::create_reasoning_param_for_request;
use crate::config::Config;
use crate::config_types::ReasoningEffort as ReasoningEffortConfig;
use crate::config_types::ReasoningSummary as ReasoningSummaryConfig;
use crate::error::CodexErr;
@@ -36,9 +37,11 @@ use crate::models::ResponseItem;
use crate::openai_tools::create_tools_json_for_responses_api;
use crate::protocol::TokenUsage;
use crate::util::backoff;
use std::sync::Arc;
#[derive(Clone)]
pub struct ModelClient {
config: Arc<Config>,
model: String,
client: reqwest::Client,
provider: ModelProviderInfo,
@@ -48,12 +51,14 @@ pub struct ModelClient {
impl ModelClient {
pub fn new(
model: impl ToString,
config: Arc<Config>,
provider: ModelProviderInfo,
effort: ReasoningEffortConfig,
summary: ReasoningSummaryConfig,
) -> Self {
let model = config.model.clone();
Self {
config,
model: model.to_string(),
client: reqwest::Client::new(),
provider,
@@ -108,7 +113,7 @@ impl ModelClient {
let full_instructions = prompt.get_full_instructions(&self.model);
let tools_json = create_tools_json_for_responses_api(prompt, &self.model)?;
let reasoning = create_reasoning_param_for_request(&self.model, self.effort, self.summary);
let reasoning = create_reasoning_param_for_request(&self.config, self.effort, self.summary);
let payload = ResponsesApiRequest {
model: &self.model,
instructions: &full_instructions,

View File

@@ -131,15 +131,16 @@ pub(crate) struct ResponsesApiRequest<'a> {
pub(crate) stream: bool,
}
use crate::config::Config;
pub(crate) fn create_reasoning_param_for_request(
model: &str,
config: &Config,
effort: ReasoningEffortConfig,
summary: ReasoningSummaryConfig,
) -> Option<Reasoning> {
let effort: Option<OpenAiReasoningEffort> = effort.into();
let effort = effort?;
if model_supports_reasoning_summaries(model) {
if model_supports_reasoning_summaries(config) {
let effort: Option<OpenAiReasoningEffort> = effort.into();
let effort = effort?;
Some(Reasoning {
effort,
summary: summary.into(),
@@ -149,19 +150,24 @@ pub(crate) fn create_reasoning_param_for_request(
}
}
pub fn model_supports_reasoning_summaries(model: &str) -> bool {
// Currently, we hardcode this rule to decide whether enable reasoning.
pub fn model_supports_reasoning_summaries(config: &Config) -> bool {
// Currently, we hardcode this rule to decide whether to enable reasoning.
// We expect reasoning to apply only to OpenAI models, but we do not want
// users to have to mess with their config to disable reasoning for models
// that do not support it, such as `gpt-4.1`.
//
// Though if a user is using Codex with non-OpenAI models that, say, happen
// to start with "o", then they can set `model_reasoning_effort = "none` in
// to start with "o", then they can set `model_reasoning_effort = "none"` in
// config.toml to disable reasoning.
//
// Ultimately, this should also be configurable in config.toml, but we
// need to have defaults that "just work." Perhaps we could have a
// "reasoning models pattern" as part of ModelProviderInfo?
// Converseley, if a user has a non-OpenAI provider that supports reasoning,
// they can set the top-level `model_supports_reasoning_summaries = true`
// config option to enable reasoning.
if config.model_supports_reasoning_summaries {
return true;
}
let model = &config.model;
model.starts_with("o") || model.starts_with("codex")
}

View File

@@ -586,7 +586,7 @@ async fn submission_loop(
}
let client = ModelClient::new(
model.clone(),
config.clone(),
provider.clone(),
model_reasoning_effort,
model_reasoning_summary,

View File

@@ -130,6 +130,10 @@ pub struct Config {
/// If not "none", the value to use for `reasoning.summary` when making a
/// request using the Responses API.
pub model_reasoning_summary: ReasoningSummary,
/// When set to `true`, overrides the default heuristic and forces
/// `model_supports_reasoning_summaries()` to return `true`.
pub model_supports_reasoning_summaries: bool,
}
impl Config {
@@ -308,6 +312,9 @@ pub struct ConfigToml {
pub model_reasoning_effort: Option<ReasoningEffort>,
pub model_reasoning_summary: Option<ReasoningSummary>,
/// Override to force-enable reasoning summaries for the configured model.
pub model_supports_reasoning_summaries: Option<bool>,
}
impl ConfigToml {
@@ -472,6 +479,10 @@ impl Config {
.model_reasoning_summary
.or(cfg.model_reasoning_summary)
.unwrap_or_default(),
model_supports_reasoning_summaries: cfg
.model_supports_reasoning_summaries
.unwrap_or(false),
};
Ok(config)
}
@@ -776,6 +787,7 @@ disable_response_storage = true
hide_agent_reasoning: false,
model_reasoning_effort: ReasoningEffort::High,
model_reasoning_summary: ReasoningSummary::Detailed,
model_supports_reasoning_summaries: false,
},
o3_profile_config
);
@@ -820,6 +832,7 @@ disable_response_storage = true
hide_agent_reasoning: false,
model_reasoning_effort: ReasoningEffort::default(),
model_reasoning_summary: ReasoningSummary::default(),
model_supports_reasoning_summaries: false,
};
assert_eq!(expected_gpt3_profile_config, gpt3_profile_config);

View File

@@ -139,7 +139,7 @@ impl EventProcessor {
("sandbox", summarize_sandbox_policy(&config.sandbox_policy)),
];
if config.model_provider.wire_api == WireApi::Responses
&& model_supports_reasoning_summaries(&config.model)
&& model_supports_reasoning_summaries(config)
{
entries.push((
"reasoning effort",

View File

@@ -159,7 +159,7 @@ impl HistoryCell {
("sandbox", summarize_sandbox_policy(&config.sandbox_policy)),
];
if config.model_provider.wire_api == WireApi::Responses
&& model_supports_reasoning_summaries(&config.model)
&& model_supports_reasoning_summaries(config)
{
entries.push((
"reasoning effort",