mirror of
https://github.com/hanzoai/dev.git
synced 2026-10-25 03:32:32 +00:00
feat(models): update default agent model routing
This commit is contained in:
@@ -19,8 +19,8 @@
|
||||
- Stress tests now cover heavy agent churn plus concurrent Auto Review + Esc/typing responsiveness.
|
||||
|
||||
- **New/updated models and agents**
|
||||
- Auto Drive CLI model support includes `gpt-5.3-codex` (planning/problem-solving) and `gpt-5.3-codex-spark` (fast coding/fix loops), with `medium | high | xhigh` reasoning controls.
|
||||
- Frontline and alias-aware agent model handling now includes `code-gpt-5.3-codex` and `code-gpt-5.3-codex-spark`, with compatibility alias upgrades for `gpt-5.1-codex`, `gpt-5.1-codex-mini`, `gpt-5.2-codex`, etc.
|
||||
- Auto Drive CLI model support defaults to `gpt-5.5` (planning/problem-solving) and `gpt-5.4-mini` (fast coding/fix loops), with `medium | high | xhigh` reasoning controls.
|
||||
- Frontline and alias-aware agent model handling now includes `code-gpt-5.5`, `code-gpt-5.4`, `claude-opus-4.8`, and `claude-sonnet-4.6`, with compatibility aliases for older model names where supported.
|
||||
- Auto Drive decision schema and coordinator payloads now enforce bounded history while preserving goal and recent context.
|
||||
|
||||
See commit `60727b068` and related Auto Drive hardening commits in git history for details.
|
||||
|
||||
@@ -66,8 +66,8 @@ const MAX_QUEUED_CONVERSATION_UPDATES: usize = 24;
|
||||
const DEBUG_JSON_MAX_CHARS: usize = 1200;
|
||||
const CLI_PROMPT_MIN_CHARS: usize = 4;
|
||||
const CLI_PROMPT_MAX_CHARS: usize = 600;
|
||||
const AUTO_DRIVE_CLI_MODEL_PRIMARY: &str = "gpt-5.3-codex";
|
||||
const AUTO_DRIVE_CLI_MODEL_SPARK: &str = "gpt-5.3-codex-spark";
|
||||
const AUTO_DRIVE_CLI_MODEL_PRIMARY: &str = "gpt-5.5";
|
||||
const AUTO_DRIVE_CLI_MODEL_FAST: &str = "gpt-5.4-mini";
|
||||
const AUTO_DRIVE_PRIMARY_ROUTING_DESCRIPTION: &str =
|
||||
"Hard planning and complex problem solving";
|
||||
const AUTO_DRIVE_SPARK_ROUTING_DESCRIPTION: &str =
|
||||
@@ -160,7 +160,7 @@ fn default_auto_drive_cli_routing_entries() -> Vec<AutoDriveCliRoutingEntry> {
|
||||
description: AUTO_DRIVE_PRIMARY_ROUTING_DESCRIPTION.to_string(),
|
||||
},
|
||||
AutoDriveCliRoutingEntry {
|
||||
model: AUTO_DRIVE_CLI_MODEL_SPARK.to_string(),
|
||||
model: AUTO_DRIVE_CLI_MODEL_FAST.to_string(),
|
||||
reasoning_levels: vec![ReasoningEffort::High],
|
||||
description: AUTO_DRIVE_SPARK_ROUTING_DESCRIPTION.to_string(),
|
||||
},
|
||||
@@ -168,24 +168,10 @@ fn default_auto_drive_cli_routing_entries() -> Vec<AutoDriveCliRoutingEntry> {
|
||||
}
|
||||
|
||||
fn auto_drive_cli_routing_entries_for_auth(
|
||||
auth_mode: Option<code_app_server_protocol::AuthMode>,
|
||||
supports_pro_only_models: bool,
|
||||
_auth_mode: Option<code_app_server_protocol::AuthMode>,
|
||||
_supports_pro_only_models: bool,
|
||||
) -> Vec<AutoDriveCliRoutingEntry> {
|
||||
let mut entries = vec![AutoDriveCliRoutingEntry {
|
||||
model: AUTO_DRIVE_CLI_MODEL_PRIMARY.to_string(),
|
||||
reasoning_levels: vec![ReasoningEffort::High, ReasoningEffort::XHigh],
|
||||
description: AUTO_DRIVE_PRIMARY_ROUTING_DESCRIPTION.to_string(),
|
||||
}];
|
||||
if auth_mode.is_some_and(code_app_server_protocol::AuthMode::is_chatgpt)
|
||||
&& supports_pro_only_models
|
||||
{
|
||||
entries.push(AutoDriveCliRoutingEntry {
|
||||
model: AUTO_DRIVE_CLI_MODEL_SPARK.to_string(),
|
||||
reasoning_levels: vec![ReasoningEffort::High],
|
||||
description: AUTO_DRIVE_SPARK_ROUTING_DESCRIPTION.to_string(),
|
||||
});
|
||||
}
|
||||
entries
|
||||
default_auto_drive_cli_routing_entries()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -268,9 +254,6 @@ fn resolve_auto_drive_cli_routing_entries(
|
||||
available_models: &[String],
|
||||
) -> Vec<AutoDriveCliRoutingEntry> {
|
||||
let mut entries = normalize_auto_drive_cli_routing_entries(&settings.model_routing_entries);
|
||||
if !auth_mode.is_some_and(|mode| mode.is_chatgpt()) || !supports_pro_only_models {
|
||||
entries.retain(|entry| !entry.model.eq_ignore_ascii_case(AUTO_DRIVE_CLI_MODEL_SPARK));
|
||||
}
|
||||
entries.retain(|entry| {
|
||||
available_models
|
||||
.iter()
|
||||
@@ -1183,7 +1166,7 @@ mod tests {
|
||||
"status_title": "Fixing tests",
|
||||
"status_sent_to_user": "Running clear failing-test loops.",
|
||||
"cli_milestone_instruction": "Take the failing test from red to green and report the passing evidence.",
|
||||
"cli_model": "gpt-5.3-codex-spark",
|
||||
"cli_model": "gpt-5.4-mini",
|
||||
"cli_reasoning_effort": "high"
|
||||
}"#;
|
||||
|
||||
@@ -1197,18 +1180,18 @@ mod tests {
|
||||
.expect("routing-enabled decision should parse");
|
||||
|
||||
let cli = decision.cli.expect("cli action expected");
|
||||
assert_eq!(cli.model_override.as_deref(), Some("gpt-5.3-codex-spark"));
|
||||
assert_eq!(cli.model_override.as_deref(), Some("gpt-5.4-mini"));
|
||||
assert_eq!(cli.reasoning_effort_override, Some(ReasoningEffort::High));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_decision_rejects_spark_when_not_allowed() {
|
||||
fn parse_decision_rejects_fast_model_when_not_allowed() {
|
||||
let raw = r#"{
|
||||
"finish_status": "continue",
|
||||
"status_title": "Fixing tests",
|
||||
"status_sent_to_user": "Running clear failing-test loops.",
|
||||
"cli_milestone_instruction": "Take the failing test from red to green and report the passing evidence.",
|
||||
"cli_model": "gpt-5.3-codex-spark",
|
||||
"cli_model": "gpt-5.4-mini",
|
||||
"cli_reasoning_effort": "high"
|
||||
}"#;
|
||||
|
||||
@@ -1223,7 +1206,7 @@ mod tests {
|
||||
}],
|
||||
},
|
||||
)
|
||||
.expect_err("non-pro routing should reject spark");
|
||||
.expect_err("routing should reject unavailable fast model");
|
||||
|
||||
assert!(err.to_string().contains("unsupported cli_model"));
|
||||
assert!(err.to_string().contains(AUTO_DRIVE_CLI_MODEL_PRIMARY));
|
||||
@@ -1236,7 +1219,7 @@ mod tests {
|
||||
"status_title": "Fixing tests",
|
||||
"status_sent_to_user": "Running clear failing-test loops.",
|
||||
"cli_milestone_instruction": "Take the failing test from red to green and report the passing evidence.",
|
||||
"cli_model": "gpt-5.3-codex",
|
||||
"cli_model": "gpt-5.5",
|
||||
"cli_reasoning_effort": "xhigh"
|
||||
}"#;
|
||||
|
||||
@@ -1259,25 +1242,25 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn auto_drive_cli_models_gates_spark_by_auth() {
|
||||
fn auto_drive_cli_models_include_primary_and_fast_for_auth_modes() {
|
||||
let pro_models = auto_drive_cli_models_for_auth(Some(AuthMode::Chatgpt), true);
|
||||
assert!(pro_models.contains(&AUTO_DRIVE_CLI_MODEL_PRIMARY.to_string()));
|
||||
assert!(pro_models.contains(&AUTO_DRIVE_CLI_MODEL_SPARK.to_string()));
|
||||
assert!(pro_models.contains(&AUTO_DRIVE_CLI_MODEL_FAST.to_string()));
|
||||
|
||||
let non_pro_models = auto_drive_cli_models_for_auth(Some(AuthMode::Chatgpt), false);
|
||||
assert!(non_pro_models.contains(&AUTO_DRIVE_CLI_MODEL_PRIMARY.to_string()));
|
||||
assert!(!non_pro_models.contains(&AUTO_DRIVE_CLI_MODEL_SPARK.to_string()));
|
||||
assert!(non_pro_models.contains(&AUTO_DRIVE_CLI_MODEL_FAST.to_string()));
|
||||
|
||||
let api_key_models = auto_drive_cli_models_for_auth(Some(AuthMode::ApiKey), false);
|
||||
assert!(api_key_models.contains(&AUTO_DRIVE_CLI_MODEL_PRIMARY.to_string()));
|
||||
assert!(!api_key_models.contains(&AUTO_DRIVE_CLI_MODEL_SPARK.to_string()));
|
||||
assert!(api_key_models.contains(&AUTO_DRIVE_CLI_MODEL_FAST.to_string()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn resolve_cli_routing_entries_falls_back_when_enabled_entries_missing() {
|
||||
let mut settings = AutoDriveSettings::default();
|
||||
settings.model_routing_entries = vec![AutoDriveModelRoutingEntry {
|
||||
model: "gpt-5.3-codex".to_string(),
|
||||
model: "gpt-5.5".to_string(),
|
||||
enabled: false,
|
||||
reasoning_levels: vec![ReasoningEffort::High],
|
||||
description: "disabled".to_string(),
|
||||
@@ -1285,7 +1268,7 @@ mod tests {
|
||||
|
||||
let available_models = vec![
|
||||
AUTO_DRIVE_CLI_MODEL_PRIMARY.to_string(),
|
||||
AUTO_DRIVE_CLI_MODEL_SPARK.to_string(),
|
||||
AUTO_DRIVE_CLI_MODEL_FAST.to_string(),
|
||||
];
|
||||
|
||||
let entries = resolve_auto_drive_cli_routing_entries(
|
||||
@@ -1296,7 +1279,7 @@ mod tests {
|
||||
);
|
||||
|
||||
assert!(entries.iter().any(|entry| entry.model == AUTO_DRIVE_CLI_MODEL_PRIMARY));
|
||||
assert!(entries.iter().any(|entry| entry.model == AUTO_DRIVE_CLI_MODEL_SPARK));
|
||||
assert!(entries.iter().any(|entry| entry.model == AUTO_DRIVE_CLI_MODEL_FAST));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -75,7 +75,7 @@ static PRESETS: Lazy<Vec<ModelPreset>> = Lazy::new(|| {
|
||||
},
|
||||
],
|
||||
supported_text_verbosity: ALL_TEXT_VERBOSITY,
|
||||
is_default: false,
|
||||
is_default: true,
|
||||
upgrade: None,
|
||||
pro_only: false,
|
||||
show_in_picker: true,
|
||||
@@ -226,14 +226,14 @@ static PRESETS: Lazy<Vec<ModelPreset>> = Lazy::new(|| {
|
||||
},
|
||||
],
|
||||
supported_text_verbosity: &[TextVerbosityConfig::Medium],
|
||||
is_default: true,
|
||||
is_default: false,
|
||||
upgrade: Some(ModelUpgrade {
|
||||
id: "gpt-5.3-codex".to_string(),
|
||||
reasoning_effort_mapping: None,
|
||||
migration_config_key: HIDE_GPT_5_2_CODEX_MIGRATION_PROMPT_CONFIG.to_string(),
|
||||
}),
|
||||
pro_only: false,
|
||||
show_in_picker: true,
|
||||
show_in_picker: false,
|
||||
},
|
||||
ModelPreset {
|
||||
id: "gpt-5.2".to_string(),
|
||||
@@ -577,7 +577,7 @@ pub fn model_preset_available_for_auth(
|
||||
|
||||
match auth_mode {
|
||||
Some(AuthMode::ApiKey) => {
|
||||
preset.id != "gpt-5.2-codex" && preset.id != "gpt-5.3-codex"
|
||||
preset.id != "gpt-5.2-codex" && preset.id != "gpt-5.3-codex-spark"
|
||||
}
|
||||
_ => true,
|
||||
}
|
||||
@@ -668,13 +668,13 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gpt_5_codex_hidden_for_api_key_auth() {
|
||||
fn deprecated_and_chatgpt_only_codex_models_hidden_for_api_key_auth() {
|
||||
let presets = builtin_model_presets(Some(AuthMode::ApiKey), false);
|
||||
assert!(presets.iter().all(|preset| {
|
||||
preset.id != "gpt-5.2-codex"
|
||||
&& preset.id != "gpt-5.3-codex"
|
||||
&& preset.id != "gpt-5.3-codex-spark"
|
||||
}));
|
||||
assert!(presets.iter().any(|preset| preset.id == "gpt-5.3-codex"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -60,7 +60,7 @@ agent {
|
||||
"task": "Implement JWT middleware (RS256) with key rotation and unit/integration tests. Preserve existing OAuth flows. Provide README usage snippet.",
|
||||
"context": "Service: services/api (Rust Axum). Secrets via env. CI: `cargo test --all`.",
|
||||
"files": ["services/api", "services/api/src", "services/api/Cargo.toml"],
|
||||
"models": ["code-gpt-5.4","claude-sonnet-4.5","gemini-3.5-flash"],
|
||||
"models": ["code-gpt-5.5","claude-sonnet-4.6","gemini-3.5-flash"],
|
||||
"output": "Middleware + passing tests + README snippet",
|
||||
"write": true // Allow changes - will launch every agent in a separate worktree
|
||||
}
|
||||
|
||||
@@ -40,14 +40,13 @@ const MODELS_MANIFEST: &str = include_str!("../../../codex-rs/models-manager/mod
|
||||
/// CLI-name lookups.
|
||||
pub const DEFAULT_AGENT_NAMES: &[&str] = &[
|
||||
// Frontline for moderate/challenging tasks
|
||||
"code-gpt-5.5",
|
||||
"code-gpt-5.4",
|
||||
"code-gpt-5.4-mini",
|
||||
"code-gpt-5.3-codex",
|
||||
"code-gpt-5.3-codex-spark",
|
||||
"claude-opus-4.8",
|
||||
"gemini-3.1-pro",
|
||||
// Straightforward / cost-aware
|
||||
"claude-sonnet-4.5",
|
||||
"claude-sonnet-4.6",
|
||||
"gemini-3.5-flash",
|
||||
"github-copilot",
|
||||
// Mixed/general and alternates
|
||||
@@ -148,7 +147,7 @@ const AGENT_MODEL_SPECS: &[AgentModelSpec] = &[
|
||||
write_args: CODE_GPT5_CODEX_WRITE,
|
||||
model_args: &["--model", "gpt-5.3-codex"],
|
||||
description: "Primary coding agent for implementation and multi-file edits; strong speed and reliability.",
|
||||
enabled_by_default: true,
|
||||
enabled_by_default: false,
|
||||
aliases: &[
|
||||
"code-gpt-5.2-codex",
|
||||
"code-gpt-5.1-codex-max",
|
||||
@@ -159,9 +158,6 @@ const AGENT_MODEL_SPECS: &[AgentModelSpec] = &[
|
||||
"gpt-5.1-codex-max",
|
||||
"gpt-5.1-codex",
|
||||
"gpt-5-codex",
|
||||
"coder",
|
||||
"code",
|
||||
"codex",
|
||||
],
|
||||
gating_env: None,
|
||||
is_frontline: true,
|
||||
@@ -175,7 +171,7 @@ const AGENT_MODEL_SPECS: &[AgentModelSpec] = &[
|
||||
write_args: CODE_GPT5_CODEX_WRITE,
|
||||
model_args: &["--model", "gpt-5.3-codex-spark"],
|
||||
description: "Fast codex variant tuned for responsive coding loops and smaller edits.",
|
||||
enabled_by_default: true,
|
||||
enabled_by_default: false,
|
||||
aliases: &["gpt-5.3-codex-spark", "code-gpt-5.3-spark", "codex-spark"],
|
||||
gating_env: None,
|
||||
is_frontline: false,
|
||||
@@ -202,7 +198,7 @@ const AGENT_MODEL_SPECS: &[AgentModelSpec] = &[
|
||||
pro_only: false,
|
||||
},
|
||||
AgentModelSpec {
|
||||
slug: "claude-sonnet-4.5",
|
||||
slug: "claude-sonnet-4.6",
|
||||
family: "claude",
|
||||
cli: "claude",
|
||||
read_only_args: CLAUDE_SONNET_READ_ONLY,
|
||||
@@ -210,7 +206,7 @@ const AGENT_MODEL_SPECS: &[AgentModelSpec] = &[
|
||||
model_args: &["--model", "sonnet"],
|
||||
description: "Balanced Claude model for implementation and debugging; a solid default when you want Claude.",
|
||||
enabled_by_default: true,
|
||||
aliases: &["claude", "claude-sonnet"],
|
||||
aliases: &["claude", "claude-sonnet", "claude-sonnet-4.5"],
|
||||
gating_env: None,
|
||||
is_frontline: false,
|
||||
pro_only: false,
|
||||
@@ -369,7 +365,7 @@ fn dynamic_code_agent_spec(model: ManifestModel) -> Option<AgentModelSpec> {
|
||||
let model_slug = leak_str(model.slug);
|
||||
let description = leak_str(model.description);
|
||||
let _display_name = leak_str(model.display_name);
|
||||
let aliases = leak_str_slice(vec![model_slug]);
|
||||
let aliases = dynamic_code_agent_aliases(model_slug);
|
||||
let model_args = leak_str_slice(vec!["--model", model_slug]);
|
||||
let pro_only = matches!(track, CodeAgentTrack::CodexSpark);
|
||||
let is_frontline = !matches!(track, CodeAgentTrack::Mini | CodeAgentTrack::CodexSpark);
|
||||
@@ -390,6 +386,14 @@ fn dynamic_code_agent_spec(model: ManifestModel) -> Option<AgentModelSpec> {
|
||||
})
|
||||
}
|
||||
|
||||
fn dynamic_code_agent_aliases(model_slug: &'static str) -> &'static [&'static str] {
|
||||
if model_slug.eq_ignore_ascii_case("gpt-5.5") {
|
||||
return leak_str_slice(vec![model_slug, "coder", "code", "codex"]);
|
||||
}
|
||||
|
||||
leak_str_slice(vec![model_slug])
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
enum CodeAgentTrack {
|
||||
Base,
|
||||
@@ -546,7 +550,7 @@ fn model_guide_intro(active_agents: &[String]) -> String {
|
||||
.collect();
|
||||
|
||||
if present_frontline.is_empty() {
|
||||
present_frontline.push("code-gpt-5.4".to_string());
|
||||
present_frontline.push("code-gpt-5.5".to_string());
|
||||
}
|
||||
let frontline_str = present_frontline.join(", ");
|
||||
|
||||
@@ -720,6 +724,11 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn gpt_codex_aliases_resolve() {
|
||||
for alias in ["coder", "code", "codex"] {
|
||||
let spec = agent_model_spec(alias).expect("generic codex alias resolves");
|
||||
assert_eq!(spec.slug, "code-gpt-5.5");
|
||||
}
|
||||
|
||||
let codex = agent_model_spec("gpt-5.1-codex").expect("alias for codex present");
|
||||
assert_eq!(codex.slug, "code-gpt-5.3-codex");
|
||||
|
||||
@@ -762,6 +771,11 @@ mod tests {
|
||||
assert_eq!(opus.slug, "claude-opus-4.8");
|
||||
assert_eq!(opus.model_args, &["--model", "opus"]);
|
||||
|
||||
let sonnet =
|
||||
agent_model_spec("claude-sonnet-4.5").expect("legacy sonnet alias resolves");
|
||||
assert_eq!(sonnet.slug, "claude-sonnet-4.6");
|
||||
assert_eq!(sonnet.model_args, &["--model", "sonnet"]);
|
||||
|
||||
let gemini = agent_model_spec("gemini").expect("gemini alias resolves");
|
||||
assert_eq!(gemini.slug, "gemini-3.5-flash");
|
||||
assert_eq!(gemini.cli, "agy");
|
||||
@@ -781,12 +795,30 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn spark_agent_model_requires_pro_chatgpt_auth() {
|
||||
fn spark_agent_model_remains_explicit_pro_only() {
|
||||
let spark = agent_model_spec("gpt-5.3-codex-spark").expect("spark spec present");
|
||||
assert!(!spark.is_enabled());
|
||||
assert!(agent_model_available_for_auth(
|
||||
spark,
|
||||
Some(AuthMode::Chatgpt),
|
||||
true
|
||||
));
|
||||
assert!(!agent_model_available_for_auth(
|
||||
spark,
|
||||
Some(AuthMode::Chatgpt),
|
||||
false
|
||||
));
|
||||
assert!(!agent_model_available_for_auth(
|
||||
spark,
|
||||
Some(AuthMode::ApiKey),
|
||||
false
|
||||
));
|
||||
|
||||
let pro_specs = enabled_agent_model_specs_for_auth(Some(AuthMode::Chatgpt), true);
|
||||
assert!(
|
||||
pro_specs
|
||||
.iter()
|
||||
.any(|spec| spec.slug == "code-gpt-5.3-codex-spark")
|
||||
.all(|spec| spec.slug != "code-gpt-5.3-codex-spark")
|
||||
);
|
||||
|
||||
let non_pro_specs = enabled_agent_model_specs_for_auth(Some(AuthMode::Chatgpt), false);
|
||||
@@ -844,5 +876,10 @@ mod tests {
|
||||
.iter()
|
||||
.all(|spec| spec.slug != "code-gpt-5.2")
|
||||
);
|
||||
assert!(
|
||||
enabled_agent_model_specs()
|
||||
.iter()
|
||||
.all(|spec| spec.slug != "code-gpt-5.3-codex")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2439,7 +2439,7 @@ pub fn create_agent_tool(allowed_models: &[String]) -> OpenAiTool {
|
||||
},
|
||||
}),
|
||||
description: Some(
|
||||
"Optional array of model names (e.g., ['code-gpt-5.4','claude-sonnet-4.5','code-gpt-5.3-codex-spark','gemini-3.5-flash'])".to_string(),
|
||||
"Optional array of model names (e.g., ['code-gpt-5.5','claude-sonnet-4.6','code-gpt-5.4-mini','gemini-3.5-flash'])".to_string(),
|
||||
),
|
||||
},
|
||||
);
|
||||
@@ -2997,7 +2997,7 @@ mod tests {
|
||||
}
|
||||
|
||||
let cfg = AgentConfig {
|
||||
name: "claude-sonnet-4.5".to_string(),
|
||||
name: "claude-sonnet-4.6".to_string(),
|
||||
command: "claude".to_string(),
|
||||
args: Vec::new(),
|
||||
read_only: true,
|
||||
@@ -3011,7 +3011,7 @@ mod tests {
|
||||
|
||||
let output = execute_model_with_permissions(
|
||||
"agent-test",
|
||||
"claude-sonnet-4.5",
|
||||
"claude-sonnet-4.6",
|
||||
"ok",
|
||||
true,
|
||||
None,
|
||||
|
||||
+20
-10
@@ -142,9 +142,9 @@ pub use crate::config_constraint::ConstraintResult;
|
||||
pub(crate) use defaults::merge_with_default_agents;
|
||||
pub(crate) use validation::upgrade_legacy_model_slugs;
|
||||
|
||||
pub(crate) const OPENAI_DEFAULT_MODEL: &str = "gpt-5.4";
|
||||
const OPENAI_DEFAULT_REVIEW_MODEL: &str = "gpt-5.4";
|
||||
pub const GPT_5_CODEX_MEDIUM_MODEL: &str = "gpt-5.4";
|
||||
pub(crate) const OPENAI_DEFAULT_MODEL: &str = "gpt-5.5";
|
||||
const OPENAI_DEFAULT_REVIEW_MODEL: &str = "gpt-5.5";
|
||||
pub const GPT_5_CODEX_MEDIUM_MODEL: &str = "gpt-5.5";
|
||||
pub(crate) const DEFAULT_SUBAGENT_MAX_DEPTH: i32 = 1;
|
||||
|
||||
/// Maximum number of bytes of the documentation that will be embedded. Larger
|
||||
@@ -229,7 +229,7 @@ pub struct Config {
|
||||
/// Whether planning should inherit the chat model instead of using a dedicated override.
|
||||
pub planning_use_chat_model: bool,
|
||||
|
||||
/// Model used specifically for review sessions. Defaults to "gpt-5.4".
|
||||
/// Model used specifically for review sessions. Defaults to "gpt-5.5".
|
||||
pub review_model: String,
|
||||
|
||||
/// Reasoning effort used when running review sessions.
|
||||
@@ -1398,7 +1398,7 @@ impl Config {
|
||||
|| agent.name.eq_ignore_ascii_case("cloud")
|
||||
{
|
||||
tracing::warn!(
|
||||
"legacy agent name '{}' detected; update config to use model slugs (e.g., code-gpt-5.3-codex)",
|
||||
"legacy agent name '{}' detected; update config to use model slugs (e.g., code-gpt-5.5)",
|
||||
agent.name
|
||||
);
|
||||
}
|
||||
@@ -2820,7 +2820,7 @@ model_verbosity = "high"
|
||||
assert_eq!(config.auto_drive.model_routing_entries.len(), 2);
|
||||
assert_eq!(
|
||||
config.auto_drive.model_routing_entries[0].model,
|
||||
"gpt-5.3-codex"
|
||||
"gpt-5.5"
|
||||
);
|
||||
assert_eq!(
|
||||
config.auto_drive.model_routing_entries[0].reasoning_levels,
|
||||
@@ -2828,7 +2828,7 @@ model_verbosity = "high"
|
||||
);
|
||||
assert_eq!(
|
||||
config.auto_drive.model_routing_entries[1].model,
|
||||
"gpt-5.3-codex-spark"
|
||||
"gpt-5.4-mini"
|
||||
);
|
||||
assert_eq!(
|
||||
config.auto_drive.model_routing_entries[1].reasoning_levels,
|
||||
@@ -2892,13 +2892,13 @@ model_verbosity = "high"
|
||||
auto_drive.model_routing_enabled = true;
|
||||
auto_drive.model_routing_entries = vec![
|
||||
AutoDriveModelRoutingEntry {
|
||||
model: "gpt-5.3-codex".to_string(),
|
||||
model: "gpt-5.5".to_string(),
|
||||
enabled: false,
|
||||
reasoning_levels: vec![ReasoningEffort::High],
|
||||
description: String::new(),
|
||||
},
|
||||
AutoDriveModelRoutingEntry {
|
||||
model: "gpt-5.3-codex-spark".to_string(),
|
||||
model: "gpt-5.4-mini".to_string(),
|
||||
enabled: false,
|
||||
reasoning_levels: vec![ReasoningEffort::High],
|
||||
description: String::new(),
|
||||
@@ -3066,11 +3066,20 @@ model_verbosity = "high"
|
||||
review_model: Some("gemini-3-flash".to_string()),
|
||||
..Default::default()
|
||||
};
|
||||
cfg.profiles.insert(
|
||||
"claude".to_string(),
|
||||
ConfigProfile {
|
||||
model: Some("claude-sonnet-4.5".to_string()),
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
|
||||
upgrade_legacy_model_slugs(&mut cfg);
|
||||
|
||||
assert_eq!(cfg.model.as_deref(), Some("claude-opus-4.8"));
|
||||
assert_eq!(cfg.review_model.as_deref(), Some("gemini-3.5-flash"));
|
||||
let profile = cfg.profiles.get("claude").expect("profile exists");
|
||||
assert_eq!(profile.model.as_deref(), Some("claude-sonnet-4.6"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -3157,9 +3166,10 @@ model_verbosity = "high"
|
||||
.map(|agent| agent.name.to_ascii_lowercase())
|
||||
.collect();
|
||||
|
||||
assert!(enabled_names.contains("code-gpt-5.5"));
|
||||
assert!(enabled_names.contains("code-gpt-5.3-codex"));
|
||||
assert!(enabled_names.contains("code-gpt-5.4"));
|
||||
assert!(enabled_names.contains("claude-sonnet-4.5"));
|
||||
assert!(enabled_names.contains("claude-sonnet-4.6"));
|
||||
assert!(enabled_names.contains("gemini-3.1-pro"));
|
||||
assert!(enabled_names.contains("gemini-3.5-flash"));
|
||||
assert!(enabled_names.contains("qwen-3-coder"));
|
||||
|
||||
@@ -201,6 +201,10 @@ fn upgrade_legacy_model_slug(slug: &str) -> Option<String> {
|
||||
return Some("claude-opus-4.8".to_string());
|
||||
}
|
||||
|
||||
if slug.eq_ignore_ascii_case("claude-sonnet-4.5") {
|
||||
return Some("claude-sonnet-4.6".to_string());
|
||||
}
|
||||
|
||||
// Upgrade Gemini Pro aliases to the current Gemini CLI preset.
|
||||
if matches!(
|
||||
slug.to_ascii_lowercase().as_str(),
|
||||
|
||||
@@ -956,13 +956,13 @@ fn default_auto_drive_model_routing_reasoning_levels() -> Vec<ReasoningEffort> {
|
||||
pub fn default_auto_drive_model_routing_entries() -> Vec<AutoDriveModelRoutingEntry> {
|
||||
vec![
|
||||
AutoDriveModelRoutingEntry {
|
||||
model: "gpt-5.3-codex".to_string(),
|
||||
model: "gpt-5.5".to_string(),
|
||||
enabled: true,
|
||||
reasoning_levels: vec![ReasoningEffort::High, ReasoningEffort::XHigh],
|
||||
description: "Hard planning and complex problem solving".to_string(),
|
||||
},
|
||||
AutoDriveModelRoutingEntry {
|
||||
model: "gpt-5.3-codex-spark".to_string(),
|
||||
model: "gpt-5.4-mini".to_string(),
|
||||
enabled: true,
|
||||
reasoning_levels: vec![ReasoningEffort::High],
|
||||
description: "Fast implementation loops and failing-test iteration".to_string(),
|
||||
|
||||
@@ -295,8 +295,8 @@ mod tests {
|
||||
}
|
||||
|
||||
let defaults = get_default_models();
|
||||
assert!(defaults.iter().any(|v| v == "code-gpt-5.5"));
|
||||
assert!(defaults.iter().any(|v| v == "code-gpt-5.4"));
|
||||
assert!(defaults.iter().any(|v| v == "code-gpt-5.3-codex"));
|
||||
assert!(!defaults.iter().any(|v| v == "qwen-3-coder"));
|
||||
assert!(!defaults.iter().any(|v| v == "gemini-3-flash"));
|
||||
assert!(!defaults.iter().any(|v| v == "claude-sonnet-4.5"));
|
||||
@@ -334,7 +334,7 @@ mod tests {
|
||||
}
|
||||
|
||||
let defaults = get_default_models();
|
||||
assert!(defaults.iter().any(|v| v == "claude-sonnet-4.5"));
|
||||
assert!(defaults.iter().any(|v| v == "claude-sonnet-4.6"));
|
||||
|
||||
restore_var("PATH", orig_path);
|
||||
restore_var("HOME", orig_home);
|
||||
@@ -375,8 +375,8 @@ mod tests {
|
||||
let plan_prompt = result.unwrap();
|
||||
assert!(plan_prompt.contains("final, comprehensive plan"));
|
||||
// Default agents list should include non-Codex providers when no [[agents]] configured
|
||||
assert!(plan_prompt.contains("code-gpt-5.5"));
|
||||
assert!(plan_prompt.contains("code-gpt-5.4"));
|
||||
assert!(plan_prompt.contains("code-gpt-5.3-codex"));
|
||||
assert!(!plan_prompt.contains("cloud-gpt-5.1-codex-max"));
|
||||
|
||||
// Test /solve command
|
||||
|
||||
@@ -236,7 +236,7 @@ impl AutoDriveSettingsView {
|
||||
}
|
||||
|
||||
fn default_routing_model() -> String {
|
||||
"gpt-5.3-codex".to_string()
|
||||
"gpt-5.5".to_string()
|
||||
}
|
||||
|
||||
fn normalize_routing_model(model: &str) -> Option<String> {
|
||||
@@ -1278,7 +1278,7 @@ mod tests {
|
||||
let (tx, _rx) = channel();
|
||||
AutoDriveSettingsView::new(
|
||||
AppEventSender::new(tx),
|
||||
"gpt-5.3-codex".to_string(),
|
||||
"gpt-5.5".to_string(),
|
||||
ReasoningEffort::High,
|
||||
false,
|
||||
true,
|
||||
@@ -1287,7 +1287,7 @@ mod tests {
|
||||
true,
|
||||
model_routing_enabled,
|
||||
entries,
|
||||
vec!["gpt-5.3-codex".to_string(), "gpt-5.3-codex-spark".to_string()],
|
||||
vec!["gpt-5.5".to_string(), "gpt-5.4-mini".to_string()],
|
||||
AutoContinueMode::Manual,
|
||||
)
|
||||
}
|
||||
@@ -1297,7 +1297,7 @@ mod tests {
|
||||
let mut view = build_view(
|
||||
true,
|
||||
vec![AutoDriveModelRoutingEntry {
|
||||
model: "gpt-5.3-codex".to_string(),
|
||||
model: "gpt-5.5".to_string(),
|
||||
enabled: true,
|
||||
reasoning_levels: vec![ReasoningEffort::High],
|
||||
description: String::new(),
|
||||
@@ -1318,7 +1318,7 @@ mod tests {
|
||||
let mut view = build_view(
|
||||
true,
|
||||
vec![AutoDriveModelRoutingEntry {
|
||||
model: "gpt-5.3-codex".to_string(),
|
||||
model: "gpt-5.5".to_string(),
|
||||
enabled: true,
|
||||
reasoning_levels: vec![ReasoningEffort::High],
|
||||
description: String::new(),
|
||||
@@ -1349,7 +1349,7 @@ mod tests {
|
||||
let mut view = build_view(
|
||||
false,
|
||||
vec![AutoDriveModelRoutingEntry {
|
||||
model: "gpt-5.3-codex".to_string(),
|
||||
model: "gpt-5.5".to_string(),
|
||||
enabled: false,
|
||||
reasoning_levels: vec![ReasoningEffort::High],
|
||||
description: String::new(),
|
||||
@@ -1373,7 +1373,7 @@ mod tests {
|
||||
let mut view = build_view(
|
||||
true,
|
||||
vec![AutoDriveModelRoutingEntry {
|
||||
model: "gpt-5.3-codex".to_string(),
|
||||
model: "gpt-5.5".to_string(),
|
||||
enabled: true,
|
||||
reasoning_levels: vec![ReasoningEffort::High],
|
||||
description: String::new(),
|
||||
@@ -1409,7 +1409,7 @@ mod tests {
|
||||
let mut view = build_view(
|
||||
true,
|
||||
vec![AutoDriveModelRoutingEntry {
|
||||
model: "gpt-5.3-codex".to_string(),
|
||||
model: "gpt-5.5".to_string(),
|
||||
enabled: true,
|
||||
reasoning_levels: vec![ReasoningEffort::High],
|
||||
description: String::new(),
|
||||
|
||||
@@ -35154,7 +35154,7 @@ use code_core::protocol::OrderMeta;
|
||||
write: false,
|
||||
write_requested: Some(false),
|
||||
models: Some(vec![
|
||||
"claude-sonnet-4.5".to_string(),
|
||||
"claude-sonnet-4.6".to_string(),
|
||||
"gemini-3.1-pro".to_string(),
|
||||
]),
|
||||
}];
|
||||
@@ -35169,7 +35169,7 @@ use code_core::protocol::OrderMeta;
|
||||
assert!(message.contains("Run diagnostics"));
|
||||
assert!(message.contains("Please run agent.create"));
|
||||
assert!(message.contains("write: false"));
|
||||
assert!(message.contains("Models: [claude-sonnet-4.5, gemini-3.1-pro]"));
|
||||
assert!(message.contains("Models: [claude-sonnet-4.6, gemini-3.1-pro]"));
|
||||
assert!(message.contains("Draft alternative fix"));
|
||||
assert!(message.contains("Focus on parser module"));
|
||||
assert!(message.contains("agent.wait"));
|
||||
|
||||
@@ -42,11 +42,10 @@ pub(crate) fn migration_copy_for_key(key: &str) -> ModelMigrationCopy {
|
||||
can_opt_out: true,
|
||||
},
|
||||
code_common::model_presets::HIDE_GPT_5_2_CODEX_MIGRATION_PROMPT_CONFIG => ModelMigrationCopy {
|
||||
heading: "Upgrade available: GPT-5.2 Codex",
|
||||
heading: "Upgrade available: GPT-5.3 Codex",
|
||||
content: &[
|
||||
"OpenAI's latest frontier agentic coding model is here: gpt-5.2-codex.",
|
||||
"GPT-5.2 Codex has been superseded by gpt-5.3-codex.",
|
||||
"Switch now for better coding results; you can keep your current model if you prefer.",
|
||||
"Learn more: https://openai.com/index/introducing-gpt-5-2-codex/",
|
||||
],
|
||||
can_opt_out: true,
|
||||
},
|
||||
|
||||
@@ -45,6 +45,9 @@ pub(crate) fn merge_remote_models(
|
||||
if remote_slugs.contains(&preset.model.to_ascii_lowercase()) {
|
||||
continue;
|
||||
}
|
||||
if should_skip_chatgpt_account_catalog_fallback(&preset, auth_mode) {
|
||||
continue;
|
||||
}
|
||||
preset.is_default = false;
|
||||
remote_presets.push(preset);
|
||||
}
|
||||
@@ -60,6 +63,20 @@ pub(crate) fn merge_remote_models(
|
||||
remote_presets
|
||||
}
|
||||
|
||||
fn should_skip_chatgpt_account_catalog_fallback(
|
||||
preset: &ModelPreset,
|
||||
auth_mode: Option<AuthMode>,
|
||||
) -> bool {
|
||||
if !auth_mode.is_some_and(AuthMode::is_chatgpt) {
|
||||
return false;
|
||||
}
|
||||
|
||||
matches!(
|
||||
preset.model.to_ascii_lowercase().as_str(),
|
||||
"gpt-5.2" | "gpt-5.2-codex" | "gpt-5.3-codex" | "gpt-5.3-codex-spark"
|
||||
)
|
||||
}
|
||||
|
||||
fn model_info_to_preset(info: ModelInfo) -> ModelPreset {
|
||||
let pro_only = info.slug.eq_ignore_ascii_case("gpt-5.3-codex-spark");
|
||||
let show_in_picker = info.visibility == ModelVisibility::List
|
||||
@@ -102,6 +119,69 @@ fn model_info_to_preset(info: ModelInfo) -> ModelPreset {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
fn remote_model(slug: &str, priority: i32) -> ModelInfo {
|
||||
serde_json::from_value(serde_json::json!({
|
||||
"slug": slug,
|
||||
"display_name": slug,
|
||||
"description": format!("{slug} desc"),
|
||||
"default_reasoning_level": "medium",
|
||||
"supported_reasoning_levels": [
|
||||
{"effort": "low", "description": "low"},
|
||||
{"effort": "medium", "description": "medium"}
|
||||
],
|
||||
"shell_type": "shell_command",
|
||||
"visibility": "list",
|
||||
"supported_in_api": true,
|
||||
"priority": priority,
|
||||
"upgrade": null,
|
||||
"base_instructions": "",
|
||||
"supports_reasoning_summaries": false,
|
||||
"support_verbosity": false,
|
||||
"default_verbosity": null,
|
||||
"apply_patch_tool_type": null,
|
||||
"truncation_policy": {"mode": "bytes", "limit": 10000},
|
||||
"supports_parallel_tool_calls": false,
|
||||
"context_window": null,
|
||||
"experimental_supported_tools": []
|
||||
}))
|
||||
.expect("valid model")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn chatgpt_remote_catalog_does_not_resurrect_sunset_local_models() {
|
||||
let merged = merge_remote_models(
|
||||
vec![remote_model("gpt-5.5", 0), remote_model("gpt-5.4", 1)],
|
||||
code_common::model_presets::builtin_model_presets(Some(AuthMode::ChatGPT), true),
|
||||
Some(AuthMode::ChatGPT),
|
||||
true,
|
||||
);
|
||||
|
||||
let ids: Vec<&str> = merged.iter().map(|preset| preset.id.as_str()).collect();
|
||||
assert!(ids.contains(&"gpt-5.5"));
|
||||
assert!(ids.contains(&"gpt-5.4"));
|
||||
assert!(!ids.contains(&"gpt-5.2"));
|
||||
assert!(!ids.contains(&"gpt-5.2-codex"));
|
||||
assert!(!ids.contains(&"gpt-5.3-codex"));
|
||||
assert!(!ids.contains(&"gpt-5.3-codex-spark"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn api_key_presets_keep_gpt_5_3_codex_available() {
|
||||
let merged = merge_remote_models(
|
||||
vec![remote_model("gpt-5.5", 0)],
|
||||
code_common::model_presets::builtin_model_presets(Some(AuthMode::ApiKey), false),
|
||||
Some(AuthMode::ApiKey),
|
||||
false,
|
||||
);
|
||||
|
||||
assert!(merged.iter().any(|preset| preset.id == "gpt-5.3-codex"));
|
||||
}
|
||||
}
|
||||
|
||||
fn map_reasoning_effort(effort: RemoteReasoningEffort) -> ProtocolReasoningEffort {
|
||||
match effort {
|
||||
RemoteReasoningEffort::None => ProtocolReasoningEffort::Minimal,
|
||||
|
||||
+2
-2
@@ -5,7 +5,7 @@ Every Code can launch external CLI “agents” and orchestrate them in multi-ag
|
||||
## Agent configuration (`[[agents]]` in `config.toml`)
|
||||
```toml
|
||||
[[agents]]
|
||||
name = "code-gpt-5.3-codex" # slug or alias shown in pickers
|
||||
name = "code-gpt-5.5" # slug or alias shown in pickers
|
||||
command = "coder" # executable; defaults to name
|
||||
args = ["--foo", "bar"] # base argv
|
||||
args_read_only = ["-s", "read-only", "-a", "never", "exec", "--skip-git-repo-check"]
|
||||
@@ -19,7 +19,7 @@ instructions = "Preamble added to this agent’s prompt"
|
||||
Field recap: `name` (slug/alias), `command` (absolute paths ok), `args*` (RO/RW lists override base), `env`, `read_only`, `enabled`, optional `description` and `instructions`.
|
||||
|
||||
### Built-in defaults
|
||||
If no `[[agents]]` are configured, Code advertises built-ins (gated by env `CODE_ENABLE_CLOUD_AGENT_MODEL` for cloud variants): `code-gpt-5.4`, `code-gpt-5.4-mini`, `code-gpt-5.3-codex`, `code-gpt-5.3-codex-spark`, `claude-opus-4.8`, `gemini-3.1-pro`, `claude-sonnet-4.5`, `gemini-3.5-flash`, `claude-haiku-4.5`, `qwen-3-coder`, `cloud-gpt-5.1-codex-max`. Built-ins strip any user `--model/-m` flags to avoid conflicts and inject their own.
|
||||
If no `[[agents]]` are configured, Code advertises built-ins (gated by env `CODE_ENABLE_CLOUD_AGENT_MODEL` for cloud variants): `code-gpt-5.5`, `code-gpt-5.4`, `code-gpt-5.4-mini`, `claude-opus-4.8`, `gemini-3.1-pro`, `claude-sonnet-4.6`, `gemini-3.5-flash`, `claude-haiku-4.5`, `qwen-3-coder`, `cloud-gpt-5.1-codex-max`. Built-ins strip any user `--model/-m` flags to avoid conflicts and inject their own.
|
||||
|
||||
Tip: `gemini` resolves to `gemini-3.5-flash` through Antigravity CLI. Use `gemini-3.1-pro` when you want the higher-capacity Gemini CLI option.
|
||||
|
||||
|
||||
+2
-2
@@ -198,7 +198,7 @@ approval_policy = "never"
|
||||
|
||||
Use `[[agents]]` blocks to register additional CLI programs that Code can launch as peers. Each block maps a short `name` (referenced elsewhere in the config) to the command to execute, optional default flags, and environment variables.
|
||||
|
||||
> **Note:** Built-in model slugs (for example `code-gpt-5.4`, `claude-sonnet-4.5`) automatically inject the correct `--model` or `-m` flag. To avoid conflicting arguments, Code strips any `--model`/`-m` flags you place in `args`, `args_read_only`, or `args_write` before launching the agent. If you need a new model variant, add a slug in `code-rs/core/src/agent_defaults.rs` (or set an environment variable consumed by the CLI) rather than pinning the flag here.
|
||||
> **Note:** Built-in model slugs (for example `code-gpt-5.5`, `claude-sonnet-4.6`) automatically inject the correct `--model` or `-m` flag. To avoid conflicting arguments, Code strips any `--model`/`-m` flags you place in `args`, `args_read_only`, or `args_write` before launching the agent. If you need a new model variant, add a slug in `code-rs/core/src/agent_defaults.rs` (or set an environment variable consumed by the CLI) rather than pinning the flag here.
|
||||
|
||||
```toml
|
||||
[[agents]]
|
||||
@@ -449,7 +449,7 @@ tool_timeout_sec = 30
|
||||
|
||||
Sub-agents are orchestrated helper workflows you can trigger with slash commands (for example `/plan`, `/solve`, `/code`). Each entry under `[[subagents.commands]]` defines the slash command name, whether spawned agents run in read-only mode, which `agents` to launch, and extra guidance for both the orchestrator (Code) and the individual agents.
|
||||
|
||||
By default (when no `[[agents]]` are configured) Code advertises these model slugs for multi-agent runs: `code-gpt-5.4`, `code-gpt-5.4-mini`, `code-gpt-5.3-codex`, `code-gpt-5.3-codex-spark`, `claude-opus-4.8`, `gemini-3.1-pro`, `claude-sonnet-4.5`, `gemini-3.5-flash`, `claude-haiku-4.5`, and `qwen-3-coder`. The cloud counterpart, `cloud-gpt-5.1-codex-max`, only appears when `CODE_ENABLE_CLOUD_AGENT_MODEL=1` is set. (`gemini` resolves to the Antigravity-backed `gemini-3.5-flash`.) You can override the list by defining `[[agents]]` entries or by specifying `agents = [ … ]` on a given `[[subagents.commands]]` entry.
|
||||
By default (when no `[[agents]]` are configured) Code advertises these model slugs for multi-agent runs: `code-gpt-5.5`, `code-gpt-5.4`, `code-gpt-5.4-mini`, `claude-opus-4.8`, `gemini-3.1-pro`, `claude-sonnet-4.6`, `gemini-3.5-flash`, `claude-haiku-4.5`, and `qwen-3-coder`. The cloud counterpart, `cloud-gpt-5.1-codex-max`, only appears when `CODE_ENABLE_CLOUD_AGENT_MODEL=1` is set. (`gemini` resolves to the Antigravity-backed `gemini-3.5-flash`.) You can override the list by defining `[[agents]]` entries or by specifying `agents = [ … ]` on a given `[[subagents.commands]]` entry.
|
||||
|
||||
```toml
|
||||
[[subagents.commands]]
|
||||
|
||||
@@ -119,10 +119,10 @@ Implementation Notes
|
||||
- Prompt formatting for `/plan`, `/solve`, and `/code` lives in
|
||||
`code-rs/core/src/slash_commands.rs`.
|
||||
When no `[[agents]]` are configured, the orchestrator advertises the
|
||||
following model slugs to the LLM for multi-agent runs: `code-gpt-5.4`,
|
||||
`code-gpt-5.4-mini`, `code-gpt-5.3-codex`, `code-gpt-5.3-codex-spark`,
|
||||
following model slugs to the LLM for multi-agent runs: `code-gpt-5.5`,
|
||||
`code-gpt-5.4`, `code-gpt-5.4-mini`,
|
||||
`claude-opus-4.8`, `gemini-3.1-pro`,
|
||||
`claude-sonnet-4.5`, `gemini-3.5-flash`,
|
||||
`claude-sonnet-4.6`, `gemini-3.5-flash`,
|
||||
`claude-haiku-4.5`, and `qwen-3-coder` (with
|
||||
`cloud-gpt-5.1-codex-max` gated by `CODE_ENABLE_CLOUD_AGENT_MODEL`). (`gemini`
|
||||
resolves to `gemini-3.5-flash`.) You can replace or pin this set via
|
||||
|
||||
Reference in New Issue
Block a user