This commit is contained in:
Ahmed Ibrahim
2025-12-22 15:25:00 -08:00
parent a010965005
commit 9cc4748524
5 changed files with 80 additions and 66 deletions

View File

@@ -631,36 +631,6 @@ impl ConfigEditsBuilder {
self
}
pub fn set_pending_model_migration_notice(mut self, from_model: &str, to_model: &str) -> Self {
self.edits.push(ConfigEdit::SetPath {
segments: vec![
Notice::TABLE_KEY.to_string(),
"pending_model_migration".to_string(),
"from_model".to_string(),
],
value: value(from_model.to_string()),
});
self.edits.push(ConfigEdit::SetPath {
segments: vec![
Notice::TABLE_KEY.to_string(),
"pending_model_migration".to_string(),
"to_model".to_string(),
],
value: value(to_model.to_string()),
});
self
}
pub fn clear_pending_model_migration_notice(mut self) -> Self {
self.edits.push(ConfigEdit::ClearPath {
segments: vec![
Notice::TABLE_KEY.to_string(),
"pending_model_migration".to_string(),
],
});
self
}
pub fn set_windows_wsl_setup_acknowledged(mut self, acknowledged: bool) -> Self {
self.edits
.push(ConfigEdit::SetWindowsWslSetupAcknowledged(acknowledged));

View File

@@ -514,12 +514,6 @@ const fn default_true() -> bool {
/// Settings for notices we display to users via the tui and app-server clients
/// (primarily the Codex IDE extension). NOTE: these are different from
/// notifications - notices are warnings, NUX screens, acknowledgements, etc.
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct PendingModelMigrationNotice {
pub from_model: String,
pub to_model: String,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default)]
pub struct Notice {
/// Tracks whether the user has acknowledged the full access warning prompt.
@@ -536,8 +530,6 @@ pub struct Notice {
/// Tracks acknowledged model migrations as old->new model slug mappings.
#[serde(default)]
pub model_migrations: BTreeMap<String, String>,
/// Persisted "show on next run" model migration notice.
pub pending_model_migration: Option<PendingModelMigrationNotice>,
}
impl Notice {

View File

@@ -217,9 +217,20 @@ impl App {
}
async fn maybe_emit_pending_model_migration_notice(&mut self, used_model: &str) {
let Some(pending) = self.config.notices.pending_model_migration.take() else {
return;
};
let pending =
match crate::model_migration_notice::read_pending_model_migration_notice(&self.config)
.await
{
Ok(Some(pending)) => pending,
Ok(None) => return,
Err(err) => {
tracing::error!(
error = %err,
"failed to read pending model migration notice"
);
return;
}
};
let should_show = pending.from_model == used_model;
if should_show {
@@ -237,20 +248,31 @@ impl App {
.insert(pending.from_model.clone(), pending.to_model.clone());
}
let mut edits = ConfigEditsBuilder::new(&self.config.codex_home);
if should_show {
edits = edits.record_model_migration_seen(
pending.from_model.as_str(),
pending.to_model.as_str(),
);
if let Err(err) = ConfigEditsBuilder::new(&self.config.codex_home)
.record_model_migration_seen(pending.from_model.as_str(), pending.to_model.as_str())
.apply()
.await
{
tracing::error!(
error = %err,
"failed to persist model migration notice acknowledgement"
);
self.chat_widget.add_error_message(format!(
"Failed to persist model migration notice acknowledgement: {err}"
));
}
}
if let Err(err) = edits.clear_pending_model_migration_notice().apply().await {
if let Err(err) =
crate::model_migration_notice::clear_pending_model_migration_notice(&self.config).await
{
tracing::error!(
error = %err,
"failed to clear pending model migration notice"
"failed to clear pending model migration notice file"
);
self.chat_widget.add_error_message(format!(
"Failed to persist model migration notice state: {err}"
"Failed to clear pending model migration notice: {err}"
));
}
}
@@ -285,10 +307,12 @@ impl App {
return;
}
if let Err(err) = ConfigEditsBuilder::new(&config.codex_home)
.set_pending_model_migration_notice(used_model.as_str(), target_model.as_str())
.apply()
.await
if let Err(err) = crate::model_migration_notice::write_pending_model_migration_notice(
&config,
used_model.as_str(),
target_model.as_str(),
)
.await
{
tracing::error!(
error = %err,

View File

@@ -57,6 +57,7 @@ pub mod live_wrap;
mod markdown;
mod markdown_render;
mod markdown_stream;
pub mod model_migration_notice;
// Model migration prompt UI is no longer used in production; keep it for snapshot tests.
#[cfg(test)]
mod model_migration;

View File

@@ -283,8 +283,20 @@ impl App {
}
async fn maybe_emit_pending_model_migration_notice(&mut self, used_model: &str) {
let Some(pending) = self.config.notices.pending_model_migration.take() else {
return;
let pending = match codex_tui::model_migration_notice::read_pending_model_migration_notice(
&self.config,
)
.await
{
Ok(Some(pending)) => pending,
Ok(None) => return,
Err(err) => {
tracing::error!(
error = %err,
"failed to read pending model migration notice"
);
return;
}
};
let should_show = pending.from_model == used_model;
@@ -303,20 +315,32 @@ impl App {
.insert(pending.from_model.clone(), pending.to_model.clone());
}
let mut edits = ConfigEditsBuilder::new(&self.config.codex_home);
if should_show {
edits = edits.record_model_migration_seen(
pending.from_model.as_str(),
pending.to_model.as_str(),
);
if let Err(err) = ConfigEditsBuilder::new(&self.config.codex_home)
.record_model_migration_seen(pending.from_model.as_str(), pending.to_model.as_str())
.apply()
.await
{
tracing::error!(
error = %err,
"failed to persist model migration notice acknowledgement"
);
self.chat_widget.add_error_message(format!(
"Failed to persist model migration notice acknowledgement: {err}"
));
}
}
if let Err(err) = edits.clear_pending_model_migration_notice().apply().await {
if let Err(err) =
codex_tui::model_migration_notice::clear_pending_model_migration_notice(&self.config)
.await
{
tracing::error!(
error = %err,
"failed to clear pending model migration notice"
"failed to clear pending model migration notice file"
);
self.chat_widget.add_error_message(format!(
"Failed to persist model migration notice state: {err}"
"Failed to clear pending model migration notice: {err}"
));
}
}
@@ -351,9 +375,12 @@ impl App {
return;
}
if let Err(err) = ConfigEditsBuilder::new(&config.codex_home)
.set_pending_model_migration_notice(used_model.as_str(), target_model.as_str())
.apply()
if let Err(err) =
codex_tui::model_migration_notice::write_pending_model_migration_notice(
&config,
used_model.as_str(),
target_model.as_str(),
)
.await
{
tracing::error!(