This commit is contained in:
Ahmed Ibrahim
2026-01-05 10:50:38 -08:00
parent 5c79085dae
commit 0239053ad9
4 changed files with 99 additions and 73 deletions

View File

@@ -183,7 +183,7 @@ impl App {
let mut config = config;
let pending_model_migration_notice =
crate::model_migration::take_pending_model_migration_notice(&mut config);
crate::model_migration::maybe_show_pending_model_migration_notice(&config);
let conversation_manager = Arc::new(ConversationManager::new(
auth_manager.clone(),
@@ -199,29 +199,52 @@ impl App {
)
.await?;
let mut edits = ConfigEditsBuilder::new(&config.codex_home)
.record_model_migration_seen(notice.from_model.as_str(), notice.to_model.as_str());
if matches!(
outcome,
crate::model_migration::ModelMigrationOutcome::Accepted
) {
config.model = Some(notice.to_model.clone());
edits = edits.set_model(config.model.as_deref(), config.model_reasoning_effort);
}
match outcome {
crate::model_migration::ModelMigrationOutcome::Accepted => {
config.model = Some(notice.to_model.clone());
config
.notices
.model_migrations
.insert(notice.from_model.clone(), notice.to_model.clone());
if let Err(err) = edits.apply().await {
tracing::error!(
error = %err,
"failed to persist model migration prompt outcome"
);
}
let edits = ConfigEditsBuilder::new(&config.codex_home)
.record_model_migration_seen(
notice.from_model.as_str(),
notice.to_model.as_str(),
)
.set_model(config.model.as_deref(), config.model_reasoning_effort);
if let Err(err) = edits.apply().await {
tracing::error!(
error = %err,
"failed to persist model migration prompt outcome"
);
}
}
crate::model_migration::ModelMigrationOutcome::Rejected => {
config
.notices
.model_migrations
.insert(notice.from_model.clone(), notice.to_model.clone());
if matches!(outcome, crate::model_migration::ModelMigrationOutcome::Exit) {
return Ok(AppExitInfo {
token_usage: TokenUsage::default(),
conversation_id: None,
update_action: None,
});
let edits = ConfigEditsBuilder::new(&config.codex_home)
.record_model_migration_seen(
notice.from_model.as_str(),
notice.to_model.as_str(),
);
if let Err(err) = edits.apply().await {
tracing::error!(
error = %err,
"failed to persist model migration prompt outcome"
);
}
}
crate::model_migration::ModelMigrationOutcome::Exit => {
return Ok(AppExitInfo {
token_usage: TokenUsage::default(),
conversation_id: None,
update_action: None,
});
}
}
}

View File

@@ -26,12 +26,9 @@ pub(crate) use prompt_ui::ModelMigrationOutcome;
pub(crate) use prompt_ui::ModelMigrationScreen;
pub(crate) use prompt_ui::migration_copy_for_models;
/// Read and clear the one-shot migration notice file, returning the notice if it should be shown.
///
/// If the notice is returned, this also updates `config.notices.model_migrations` to prevent
/// re-scheduling within the current process.
pub(crate) fn take_pending_model_migration_notice(
config: &mut Config,
/// Read the pending migration notice file, returning the notice if it should be shown.
pub(crate) fn maybe_show_pending_model_migration_notice(
config: &Config,
) -> Option<PendingModelMigrationNotice> {
let notice_path = pending_model_migration_notice_path(config);
let contents = match std::fs::read_to_string(&notice_path) {
@@ -55,6 +52,7 @@ pub(crate) fn take_pending_model_migration_notice(
notice_path = %notice_path.display(),
"failed to parse pending model migration notice"
);
let _ = std::fs::remove_file(&notice_path);
return None;
}
};
@@ -78,14 +76,6 @@ pub(crate) fn take_pending_model_migration_notice(
return None;
}
// Best-effort: clear the one-shot file so it doesn't appear again.
let _ = std::fs::remove_file(&notice_path);
config
.notices
.model_migrations
.insert(notice.from_model.clone(), notice.to_model.clone());
Some(notice)
}

View File

@@ -224,7 +224,7 @@ impl App {
let mut config = config;
let pending_model_migration_notice =
crate::model_migration::take_pending_model_migration_notice(&mut config);
crate::model_migration::maybe_show_pending_model_migration_notice(&config);
let conversation_manager = Arc::new(ConversationManager::new(
auth_manager.clone(),
@@ -240,30 +240,53 @@ impl App {
)
.await?;
let mut edits = ConfigEditsBuilder::new(&config.codex_home)
.record_model_migration_seen(notice.from_model.as_str(), notice.to_model.as_str());
if matches!(
outcome,
crate::model_migration::ModelMigrationOutcome::Accepted
) {
config.model = Some(notice.to_model.clone());
edits = edits.set_model(config.model.as_deref(), config.model_reasoning_effort);
}
match outcome {
crate::model_migration::ModelMigrationOutcome::Accepted => {
config.model = Some(notice.to_model.clone());
config
.notices
.model_migrations
.insert(notice.from_model.clone(), notice.to_model.clone());
if let Err(err) = edits.apply().await {
tracing::error!(
error = %err,
"failed to persist model migration prompt outcome"
);
}
let edits = ConfigEditsBuilder::new(&config.codex_home)
.record_model_migration_seen(
notice.from_model.as_str(),
notice.to_model.as_str(),
)
.set_model(config.model.as_deref(), config.model_reasoning_effort);
if let Err(err) = edits.apply().await {
tracing::error!(
error = %err,
"failed to persist model migration prompt outcome"
);
}
}
crate::model_migration::ModelMigrationOutcome::Rejected => {
config
.notices
.model_migrations
.insert(notice.from_model.clone(), notice.to_model.clone());
if matches!(outcome, crate::model_migration::ModelMigrationOutcome::Exit) {
return Ok(AppExitInfo {
token_usage: TokenUsage::default(),
conversation_id: None,
update_action: None,
session_lines: Vec::new(),
});
let edits = ConfigEditsBuilder::new(&config.codex_home)
.record_model_migration_seen(
notice.from_model.as_str(),
notice.to_model.as_str(),
);
if let Err(err) = edits.apply().await {
tracing::error!(
error = %err,
"failed to persist model migration prompt outcome"
);
}
}
crate::model_migration::ModelMigrationOutcome::Exit => {
return Ok(AppExitInfo {
token_usage: TokenUsage::default(),
conversation_id: None,
update_action: None,
session_lines: Vec::new(),
});
}
}
}

View File

@@ -26,12 +26,9 @@ pub(crate) use prompt_ui::ModelMigrationOutcome;
pub(crate) use prompt_ui::ModelMigrationScreen;
pub(crate) use prompt_ui::migration_copy_for_models;
/// Read and clear the one-shot migration notice file, returning the notice if it should be shown.
///
/// If the notice is returned, this also updates `config.notices.model_migrations` to prevent
/// re-scheduling within the current process.
pub(crate) fn take_pending_model_migration_notice(
config: &mut Config,
/// Read the pending migration notice file, returning the notice if it should be shown.
pub(crate) fn maybe_show_pending_model_migration_notice(
config: &Config,
) -> Option<PendingModelMigrationNotice> {
let notice_path = pending_model_migration_notice_path(config);
let contents = match std::fs::read_to_string(&notice_path) {
@@ -55,6 +52,7 @@ pub(crate) fn take_pending_model_migration_notice(
notice_path = %notice_path.display(),
"failed to parse pending model migration notice"
);
let _ = std::fs::remove_file(&notice_path);
return None;
}
};
@@ -78,14 +76,6 @@ pub(crate) fn take_pending_model_migration_notice(
return None;
}
// Best-effort: clear the one-shot file so it doesn't appear again.
let _ = std::fs::remove_file(&notice_path);
config
.notices
.model_migrations
.insert(notice.from_model.clone(), notice.to_model.clone());
Some(notice)
}