mirror of
https://github.com/openai/codex.git
synced 2026-05-02 02:17:22 +00:00
make model optional in config (#7769)
- Make Config.model optional and centralize default-selection logic in ModelsManager, including a default_model helper (with codex-auto-balanced when available) so sessions now carry an explicit chosen model separate from the base config. - Resolve `model` once in `core` and `tui` from config. Then store the state of it on other structs. - Move refreshing models to be before resolving the default model
This commit is contained in:
@@ -39,8 +39,8 @@ fn test_auth_manager(config: &Config) -> AuthManager {
|
||||
)
|
||||
}
|
||||
|
||||
fn test_model_family(config: &Config) -> ModelFamily {
|
||||
ModelsManager::construct_model_family_offline(config.model.as_str(), config)
|
||||
fn test_model_family(model_slug: &str, config: &Config) -> ModelFamily {
|
||||
ModelsManager::construct_model_family_offline(model_slug, config)
|
||||
}
|
||||
|
||||
fn render_lines(lines: &[Line<'static>]) -> Vec<String> {
|
||||
@@ -88,7 +88,7 @@ fn reset_at_from(captured_at: &chrono::DateTime<chrono::Local>, seconds: i64) ->
|
||||
fn status_snapshot_includes_reasoning_details() {
|
||||
let temp_home = TempDir::new().expect("temp home");
|
||||
let mut config = test_config(&temp_home);
|
||||
config.model = "gpt-5.1-codex-max".to_string();
|
||||
config.model = Some("gpt-5.1-codex-max".to_string());
|
||||
config.model_provider_id = "openai".to_string();
|
||||
config.model_reasoning_effort = Some(ReasoningEffort::High);
|
||||
config.model_reasoning_summary = ReasoningSummary::Detailed;
|
||||
@@ -130,7 +130,8 @@ fn status_snapshot_includes_reasoning_details() {
|
||||
};
|
||||
let rate_display = rate_limit_snapshot_display(&snapshot, captured_at);
|
||||
|
||||
let model_family = test_model_family(&config);
|
||||
let model_slug = ModelsManager::get_model_offline(config.model.as_deref());
|
||||
let model_family = test_model_family(&model_slug, &config);
|
||||
|
||||
let composite = new_status_output(
|
||||
&config,
|
||||
@@ -142,6 +143,7 @@ fn status_snapshot_includes_reasoning_details() {
|
||||
Some(&rate_display),
|
||||
None,
|
||||
captured_at,
|
||||
&model_slug,
|
||||
);
|
||||
let mut rendered_lines = render_lines(&composite.display_lines(80));
|
||||
if cfg!(windows) {
|
||||
@@ -157,7 +159,7 @@ fn status_snapshot_includes_reasoning_details() {
|
||||
fn status_snapshot_includes_monthly_limit() {
|
||||
let temp_home = TempDir::new().expect("temp home");
|
||||
let mut config = test_config(&temp_home);
|
||||
config.model = "gpt-5.1-codex-max".to_string();
|
||||
config.model = Some("gpt-5.1-codex-max".to_string());
|
||||
config.model_provider_id = "openai".to_string();
|
||||
config.cwd = PathBuf::from("/workspace/tests");
|
||||
|
||||
@@ -186,7 +188,8 @@ fn status_snapshot_includes_monthly_limit() {
|
||||
};
|
||||
let rate_display = rate_limit_snapshot_display(&snapshot, captured_at);
|
||||
|
||||
let model_family = test_model_family(&config);
|
||||
let model_slug = ModelsManager::get_model_offline(config.model.as_deref());
|
||||
let model_family = test_model_family(&model_slug, &config);
|
||||
let composite = new_status_output(
|
||||
&config,
|
||||
&auth_manager,
|
||||
@@ -197,6 +200,7 @@ fn status_snapshot_includes_monthly_limit() {
|
||||
Some(&rate_display),
|
||||
None,
|
||||
captured_at,
|
||||
&model_slug,
|
||||
);
|
||||
let mut rendered_lines = render_lines(&composite.display_lines(80));
|
||||
if cfg!(windows) {
|
||||
@@ -229,7 +233,8 @@ fn status_snapshot_shows_unlimited_credits() {
|
||||
plan_type: None,
|
||||
};
|
||||
let rate_display = rate_limit_snapshot_display(&snapshot, captured_at);
|
||||
let model_family = test_model_family(&config);
|
||||
let model_slug = ModelsManager::get_model_offline(config.model.as_deref());
|
||||
let model_family = test_model_family(&model_slug, &config);
|
||||
let composite = new_status_output(
|
||||
&config,
|
||||
&auth_manager,
|
||||
@@ -240,6 +245,7 @@ fn status_snapshot_shows_unlimited_credits() {
|
||||
Some(&rate_display),
|
||||
None,
|
||||
captured_at,
|
||||
&model_slug,
|
||||
);
|
||||
let rendered = render_lines(&composite.display_lines(120));
|
||||
assert!(
|
||||
@@ -271,7 +277,8 @@ fn status_snapshot_shows_positive_credits() {
|
||||
plan_type: None,
|
||||
};
|
||||
let rate_display = rate_limit_snapshot_display(&snapshot, captured_at);
|
||||
let model_family = test_model_family(&config);
|
||||
let model_slug = ModelsManager::get_model_offline(config.model.as_deref());
|
||||
let model_family = test_model_family(&model_slug, &config);
|
||||
let composite = new_status_output(
|
||||
&config,
|
||||
&auth_manager,
|
||||
@@ -282,6 +289,7 @@ fn status_snapshot_shows_positive_credits() {
|
||||
Some(&rate_display),
|
||||
None,
|
||||
captured_at,
|
||||
&model_slug,
|
||||
);
|
||||
let rendered = render_lines(&composite.display_lines(120));
|
||||
assert!(
|
||||
@@ -313,7 +321,8 @@ fn status_snapshot_hides_zero_credits() {
|
||||
plan_type: None,
|
||||
};
|
||||
let rate_display = rate_limit_snapshot_display(&snapshot, captured_at);
|
||||
let model_family = test_model_family(&config);
|
||||
let model_slug = ModelsManager::get_model_offline(config.model.as_deref());
|
||||
let model_family = test_model_family(&model_slug, &config);
|
||||
let composite = new_status_output(
|
||||
&config,
|
||||
&auth_manager,
|
||||
@@ -324,6 +333,7 @@ fn status_snapshot_hides_zero_credits() {
|
||||
Some(&rate_display),
|
||||
None,
|
||||
captured_at,
|
||||
&model_slug,
|
||||
);
|
||||
let rendered = render_lines(&composite.display_lines(120));
|
||||
assert!(
|
||||
@@ -353,7 +363,8 @@ fn status_snapshot_hides_when_has_no_credits_flag() {
|
||||
plan_type: None,
|
||||
};
|
||||
let rate_display = rate_limit_snapshot_display(&snapshot, captured_at);
|
||||
let model_family = test_model_family(&config);
|
||||
let model_slug = ModelsManager::get_model_offline(config.model.as_deref());
|
||||
let model_family = test_model_family(&model_slug, &config);
|
||||
let composite = new_status_output(
|
||||
&config,
|
||||
&auth_manager,
|
||||
@@ -364,6 +375,7 @@ fn status_snapshot_hides_when_has_no_credits_flag() {
|
||||
Some(&rate_display),
|
||||
None,
|
||||
captured_at,
|
||||
&model_slug,
|
||||
);
|
||||
let rendered = render_lines(&composite.display_lines(120));
|
||||
assert!(
|
||||
@@ -376,7 +388,7 @@ fn status_snapshot_hides_when_has_no_credits_flag() {
|
||||
fn status_card_token_usage_excludes_cached_tokens() {
|
||||
let temp_home = TempDir::new().expect("temp home");
|
||||
let mut config = test_config(&temp_home);
|
||||
config.model = "gpt-5.1-codex-max".to_string();
|
||||
config.model = Some("gpt-5.1-codex-max".to_string());
|
||||
config.cwd = PathBuf::from("/workspace/tests");
|
||||
|
||||
let auth_manager = test_auth_manager(&config);
|
||||
@@ -393,7 +405,8 @@ fn status_card_token_usage_excludes_cached_tokens() {
|
||||
.single()
|
||||
.expect("timestamp");
|
||||
|
||||
let model_family = test_model_family(&config);
|
||||
let model_slug = ModelsManager::get_model_offline(config.model.as_deref());
|
||||
let model_family = test_model_family(&model_slug, &config);
|
||||
let composite = new_status_output(
|
||||
&config,
|
||||
&auth_manager,
|
||||
@@ -404,6 +417,7 @@ fn status_card_token_usage_excludes_cached_tokens() {
|
||||
None,
|
||||
None,
|
||||
now,
|
||||
&model_slug,
|
||||
);
|
||||
let rendered = render_lines(&composite.display_lines(120));
|
||||
|
||||
@@ -417,7 +431,7 @@ fn status_card_token_usage_excludes_cached_tokens() {
|
||||
fn status_snapshot_truncates_in_narrow_terminal() {
|
||||
let temp_home = TempDir::new().expect("temp home");
|
||||
let mut config = test_config(&temp_home);
|
||||
config.model = "gpt-5.1-codex-max".to_string();
|
||||
config.model = Some("gpt-5.1-codex-max".to_string());
|
||||
config.model_provider_id = "openai".to_string();
|
||||
config.model_reasoning_effort = Some(ReasoningEffort::High);
|
||||
config.model_reasoning_summary = ReasoningSummary::Detailed;
|
||||
@@ -448,7 +462,8 @@ fn status_snapshot_truncates_in_narrow_terminal() {
|
||||
};
|
||||
let rate_display = rate_limit_snapshot_display(&snapshot, captured_at);
|
||||
|
||||
let model_family = test_model_family(&config);
|
||||
let model_slug = ModelsManager::get_model_offline(config.model.as_deref());
|
||||
let model_family = test_model_family(&model_slug, &config);
|
||||
let composite = new_status_output(
|
||||
&config,
|
||||
&auth_manager,
|
||||
@@ -459,6 +474,7 @@ fn status_snapshot_truncates_in_narrow_terminal() {
|
||||
Some(&rate_display),
|
||||
None,
|
||||
captured_at,
|
||||
&model_slug,
|
||||
);
|
||||
let mut rendered_lines = render_lines(&composite.display_lines(70));
|
||||
if cfg!(windows) {
|
||||
@@ -475,7 +491,7 @@ fn status_snapshot_truncates_in_narrow_terminal() {
|
||||
fn status_snapshot_shows_missing_limits_message() {
|
||||
let temp_home = TempDir::new().expect("temp home");
|
||||
let mut config = test_config(&temp_home);
|
||||
config.model = "gpt-5.1-codex-max".to_string();
|
||||
config.model = Some("gpt-5.1-codex-max".to_string());
|
||||
config.cwd = PathBuf::from("/workspace/tests");
|
||||
|
||||
let auth_manager = test_auth_manager(&config);
|
||||
@@ -492,7 +508,8 @@ fn status_snapshot_shows_missing_limits_message() {
|
||||
.single()
|
||||
.expect("timestamp");
|
||||
|
||||
let model_family = test_model_family(&config);
|
||||
let model_slug = ModelsManager::get_model_offline(config.model.as_deref());
|
||||
let model_family = test_model_family(&model_slug, &config);
|
||||
let composite = new_status_output(
|
||||
&config,
|
||||
&auth_manager,
|
||||
@@ -503,6 +520,7 @@ fn status_snapshot_shows_missing_limits_message() {
|
||||
None,
|
||||
None,
|
||||
now,
|
||||
&model_slug,
|
||||
);
|
||||
let mut rendered_lines = render_lines(&composite.display_lines(80));
|
||||
if cfg!(windows) {
|
||||
@@ -518,7 +536,7 @@ fn status_snapshot_shows_missing_limits_message() {
|
||||
fn status_snapshot_includes_credits_and_limits() {
|
||||
let temp_home = TempDir::new().expect("temp home");
|
||||
let mut config = test_config(&temp_home);
|
||||
config.model = "gpt-5.1-codex".to_string();
|
||||
config.model = Some("gpt-5.1-codex".to_string());
|
||||
config.cwd = PathBuf::from("/workspace/tests");
|
||||
|
||||
let auth_manager = test_auth_manager(&config);
|
||||
@@ -554,7 +572,8 @@ fn status_snapshot_includes_credits_and_limits() {
|
||||
};
|
||||
let rate_display = rate_limit_snapshot_display(&snapshot, captured_at);
|
||||
|
||||
let model_family = test_model_family(&config);
|
||||
let model_slug = ModelsManager::get_model_offline(config.model.as_deref());
|
||||
let model_family = test_model_family(&model_slug, &config);
|
||||
let composite = new_status_output(
|
||||
&config,
|
||||
&auth_manager,
|
||||
@@ -565,6 +584,7 @@ fn status_snapshot_includes_credits_and_limits() {
|
||||
Some(&rate_display),
|
||||
None,
|
||||
captured_at,
|
||||
&model_slug,
|
||||
);
|
||||
let mut rendered_lines = render_lines(&composite.display_lines(80));
|
||||
if cfg!(windows) {
|
||||
@@ -580,7 +600,7 @@ fn status_snapshot_includes_credits_and_limits() {
|
||||
fn status_snapshot_shows_empty_limits_message() {
|
||||
let temp_home = TempDir::new().expect("temp home");
|
||||
let mut config = test_config(&temp_home);
|
||||
config.model = "gpt-5.1-codex-max".to_string();
|
||||
config.model = Some("gpt-5.1-codex-max".to_string());
|
||||
config.cwd = PathBuf::from("/workspace/tests");
|
||||
|
||||
let auth_manager = test_auth_manager(&config);
|
||||
@@ -604,7 +624,8 @@ fn status_snapshot_shows_empty_limits_message() {
|
||||
.expect("timestamp");
|
||||
let rate_display = rate_limit_snapshot_display(&snapshot, captured_at);
|
||||
|
||||
let model_family = test_model_family(&config);
|
||||
let model_slug = ModelsManager::get_model_offline(config.model.as_deref());
|
||||
let model_family = test_model_family(&model_slug, &config);
|
||||
let composite = new_status_output(
|
||||
&config,
|
||||
&auth_manager,
|
||||
@@ -615,6 +636,7 @@ fn status_snapshot_shows_empty_limits_message() {
|
||||
Some(&rate_display),
|
||||
None,
|
||||
captured_at,
|
||||
&model_slug,
|
||||
);
|
||||
let mut rendered_lines = render_lines(&composite.display_lines(80));
|
||||
if cfg!(windows) {
|
||||
@@ -630,7 +652,7 @@ fn status_snapshot_shows_empty_limits_message() {
|
||||
fn status_snapshot_shows_stale_limits_message() {
|
||||
let temp_home = TempDir::new().expect("temp home");
|
||||
let mut config = test_config(&temp_home);
|
||||
config.model = "gpt-5.1-codex-max".to_string();
|
||||
config.model = Some("gpt-5.1-codex-max".to_string());
|
||||
config.cwd = PathBuf::from("/workspace/tests");
|
||||
|
||||
let auth_manager = test_auth_manager(&config);
|
||||
@@ -663,7 +685,8 @@ fn status_snapshot_shows_stale_limits_message() {
|
||||
let rate_display = rate_limit_snapshot_display(&snapshot, captured_at);
|
||||
let now = captured_at + ChronoDuration::minutes(20);
|
||||
|
||||
let model_family = test_model_family(&config);
|
||||
let model_slug = ModelsManager::get_model_offline(config.model.as_deref());
|
||||
let model_family = test_model_family(&model_slug, &config);
|
||||
let composite = new_status_output(
|
||||
&config,
|
||||
&auth_manager,
|
||||
@@ -674,6 +697,7 @@ fn status_snapshot_shows_stale_limits_message() {
|
||||
Some(&rate_display),
|
||||
None,
|
||||
now,
|
||||
&model_slug,
|
||||
);
|
||||
let mut rendered_lines = render_lines(&composite.display_lines(80));
|
||||
if cfg!(windows) {
|
||||
@@ -689,7 +713,7 @@ fn status_snapshot_shows_stale_limits_message() {
|
||||
fn status_snapshot_cached_limits_hide_credits_without_flag() {
|
||||
let temp_home = TempDir::new().expect("temp home");
|
||||
let mut config = test_config(&temp_home);
|
||||
config.model = "gpt-5.1-codex".to_string();
|
||||
config.model = Some("gpt-5.1-codex".to_string());
|
||||
config.cwd = PathBuf::from("/workspace/tests");
|
||||
|
||||
let auth_manager = test_auth_manager(&config);
|
||||
@@ -726,7 +750,8 @@ fn status_snapshot_cached_limits_hide_credits_without_flag() {
|
||||
let rate_display = rate_limit_snapshot_display(&snapshot, captured_at);
|
||||
let now = captured_at + ChronoDuration::minutes(20);
|
||||
|
||||
let model_family = test_model_family(&config);
|
||||
let model_slug = ModelsManager::get_model_offline(config.model.as_deref());
|
||||
let model_family = test_model_family(&model_slug, &config);
|
||||
let composite = new_status_output(
|
||||
&config,
|
||||
&auth_manager,
|
||||
@@ -737,6 +762,7 @@ fn status_snapshot_cached_limits_hide_credits_without_flag() {
|
||||
Some(&rate_display),
|
||||
None,
|
||||
now,
|
||||
&model_slug,
|
||||
);
|
||||
let mut rendered_lines = render_lines(&composite.display_lines(80));
|
||||
if cfg!(windows) {
|
||||
@@ -775,7 +801,8 @@ fn status_context_window_uses_last_usage() {
|
||||
.single()
|
||||
.expect("timestamp");
|
||||
|
||||
let model_family = test_model_family(&config);
|
||||
let model_slug = ModelsManager::get_model_offline(config.model.as_deref());
|
||||
let model_family = test_model_family(&model_slug, &config);
|
||||
let composite = new_status_output(
|
||||
&config,
|
||||
&auth_manager,
|
||||
@@ -786,6 +813,7 @@ fn status_context_window_uses_last_usage() {
|
||||
None,
|
||||
None,
|
||||
now,
|
||||
&model_slug,
|
||||
);
|
||||
let rendered_lines = render_lines(&composite.display_lines(80));
|
||||
let context_line = rendered_lines
|
||||
|
||||
Reference in New Issue
Block a user