diff --git a/docs/providers.md b/docs/providers.md index cd90b46..3e0d258 100644 --- a/docs/providers.md +++ b/docs/providers.md @@ -90,7 +90,7 @@ Runs Claude-style coding sessions against OpenAI's Codex using your ChatGPT/Code | `gpt-5.4-mini` | Fast/lower-cost model for lighter coding tasks and subagents | | `gpt-5.3-codex-spark` | Research preview for ChatGPT Pro users | | `gpt-5.3-codex` | Deprecated for ChatGPT sign-in; retained for explicit selection | -| `gpt-5.2-codex` | Deprecated for ChatGPT sign-in; retained for explicit selection | +| `gpt-5.2-codex` | Legacy Codex/API-key compatibility model | | `gpt-5.1-codex` | Legacy Codex model | | `gpt-5.1-codex-mini` | Legacy mini model | | `gpt-5.1-codex-max` | Legacy max model | diff --git a/src-rust/crates/api/src/lib.rs b/src-rust/crates/api/src/lib.rs index 0fea2b1..f2c6f73 100644 --- a/src-rust/crates/api/src/lib.rs +++ b/src-rust/crates/api/src/lib.rs @@ -674,7 +674,7 @@ pub mod client { .header("anthropic-version", &self.config.api_version) .header("content-type", "application/json"); if self.config.use_bearer_auth { - req = req.header("Authorization", format!("Bearer {}", &self.config.api_key)); + req = req.header("Authorization", format!("Bearer {}", self.config.api_key)); } else { req = req.header("x-api-key", &self.config.api_key); } @@ -727,7 +727,7 @@ pub mod client { .header("accept", "text/event-stream"); if use_oauth { - req = req.header("Authorization", format!("Bearer {}", &self.config.api_key)); + req = req.header("Authorization", format!("Bearer {}", self.config.api_key)); } else { // Compute CCH billing hash and attach on the API-key path // only — this is the codepath the official client uses diff --git a/src-rust/crates/api/src/model_registry.rs b/src-rust/crates/api/src/model_registry.rs index 388184e..22be960 100644 --- a/src-rust/crates/api/src/model_registry.rs +++ b/src-rust/crates/api/src/model_registry.rs @@ -970,6 +970,11 @@ fn flagship_patterns_for(provider_id: &str) -> &'static [&'static str] { "claude-sonnet-3", ], "openai" => &[ + "gpt-5.6-sol", + "gpt-5.6-terra", + "gpt-5.6-luna", + "gpt-5.6", + "gpt-5.5", "gpt-5.2-pro", "gpt-5.2", "gpt-5.1", @@ -1196,6 +1201,7 @@ mod tests { let best = reg .best_model_for_provider("codex") .expect("codex best model must fall back to CODEX_MODELS default"); + assert_eq!(best, claurst_core::codex_oauth::DEFAULT_CODEX_MODEL); assert!( claurst_core::codex_oauth::CODEX_MODELS .iter() @@ -1205,6 +1211,7 @@ mod tests { let small = reg .best_small_model_for_provider("codex") .expect("codex small model must fall back to a mini/default id"); + assert_eq!(small, "gpt-5.6-luna"); assert!( claurst_core::codex_oauth::CODEX_MODELS .iter() diff --git a/src-rust/crates/tui/src/app.rs b/src-rust/crates/tui/src/app.rs index 9136efc..3a47437 100644 --- a/src-rust/crates/tui/src/app.rs +++ b/src-rust/crates/tui/src/app.rs @@ -275,6 +275,7 @@ pub(crate) mod test_env { old_anthropic_config_dir: Option, old_anthropic_api_key: Option, old_oauth_client_id: Option, + old_claude_bin: Option, old_user: Option, old_username: Option, _lock: MutexGuard<'static, ()>, @@ -293,6 +294,8 @@ pub(crate) mod test_env { old_anthropic_config_dir: std::env::var("ANTHROPIC_CONFIG_DIR").ok(), old_anthropic_api_key: std::env::var("ANTHROPIC_API_KEY").ok(), old_oauth_client_id: std::env::var(claurst_core::oauth::CLIENT_ID_ENV).ok(), + old_claude_bin: std::env::var(claurst_api::providers::claude_cli::CLAUDE_BIN_ENV) + .ok(), old_user: std::env::var("USER").ok(), old_username: std::env::var("USERNAME").ok(), _lock: lock, @@ -302,6 +305,7 @@ pub(crate) mod test_env { std::env::remove_var("ANTHROPIC_CONFIG_DIR"); std::env::remove_var("ANTHROPIC_API_KEY"); std::env::remove_var(claurst_core::oauth::CLIENT_ID_ENV); + std::env::remove_var(claurst_api::providers::claude_cli::CLAUDE_BIN_ENV); match user { Some(value) => std::env::set_var("USER", value), None => std::env::remove_var("USER"), @@ -335,6 +339,12 @@ pub(crate) mod test_env { Some(value) => std::env::set_var(claurst_core::oauth::CLIENT_ID_ENV, value), None => std::env::remove_var(claurst_core::oauth::CLIENT_ID_ENV), } + match &self.old_claude_bin { + Some(value) => { + std::env::set_var(claurst_api::providers::claude_cli::CLAUDE_BIN_ENV, value) + } + None => std::env::remove_var(claurst_api::providers::claude_cli::CLAUDE_BIN_ENV), + } match &self.old_user { Some(value) => std::env::set_var("USER", value), None => std::env::remove_var("USER"), @@ -7941,18 +7951,23 @@ role = "Research" } #[test] - fn provider_picker_prioritizes_import_when_claude_credentials_exist() { + fn provider_picker_marks_claude_cli_local_when_binary_exists() { let temp = tempfile::tempdir().expect("tempdir"); let home = temp.path().join("home"); let coven_home = temp.path().join("coven"); - std::fs::create_dir_all(home.join(".claude")).expect("claude dir"); + let claude_bin = temp.path().join(if cfg!(windows) { + "claude.cmd" + } else { + "claude" + }); + std::fs::create_dir_all(&home).expect("home"); std::fs::create_dir_all(&coven_home).expect("coven home"); - std::fs::write( - home.join(".claude").join(".credentials.json"), - r#"{"claudeAiOauth":{"accessToken":"sk-ant-oat01-test"}}"#, - ) - .expect("credentials"); + std::fs::write(&claude_bin, "").expect("claude binary"); let _guard = EnvGuard::set(&home, &coven_home); + std::env::set_var( + claurst_api::providers::claude_cli::CLAUDE_BIN_ENV, + &claude_bin, + ); let items = provider_picker_items();