This commit is contained in:
Ahmed Ibrahim
2025-12-15 20:36:23 -08:00
parent 6bf3d3eccf
commit baf075e49f
4 changed files with 30 additions and 90 deletions

View File

@@ -83,8 +83,6 @@ use crate::context_manager::ContextManager;
use crate::environment_context::EnvironmentContext;
use crate::error::CodexErr;
use crate::error::Result as CodexResult;
use crate::error::error_event_with_update_nudge;
use crate::error::stream_error_event_with_update_nudge;
#[cfg(test)]
use crate::exec::StreamOutput;
use crate::exec_policy::ExecPolicyUpdateError;
@@ -98,7 +96,6 @@ use crate::protocol::ApplyPatchApprovalRequestEvent;
use crate::protocol::AskForApproval;
use crate::protocol::BackgroundEventEvent;
use crate::protocol::DeprecationNoticeEvent;
use crate::protocol::ErrorEvent;
use crate::protocol::Event;
use crate::protocol::EventMsg;
use crate::protocol::ExecApprovalRequestEvent;
@@ -248,19 +245,11 @@ impl Codex {
let exec_policy = Arc::new(RwLock::new(exec_policy));
let config = Arc::new(config);
let mut remote_models_error: Option<EventMsg> = None;
let is_up_to_date = compute_is_up_to_date(&config);
if config.features.enabled(Feature::RemoteModels)
&& let Err(err) = models_manager.refresh_available_models(&config).await
{
error!("failed to refresh available models: {err:?}");
if !is_up_to_date {
remote_models_error = Some(EventMsg::Error(ErrorEvent {
message: "failed to refresh available models.".to_string(),
codex_error_info: None,
}));
}
}
let model = models_manager.get_model(&config.model, &config).await;
let session_configuration = SessionConfiguration {
@@ -278,7 +267,6 @@ impl Codex {
original_config_do_not_use: Arc::clone(&config),
exec_policy,
session_source,
is_up_to_date,
};
// Generate a unique ID for the lifetime of this Codex session.
@@ -309,14 +297,6 @@ impl Codex {
rx_event,
};
if let Some(remote_models_error) = remote_models_error {
let event = Event {
id: INITIAL_SUBMIT_ID.to_string(),
msg: remote_models_error,
};
session.send_event_raw(event).await;
}
Ok(CodexSpawnOk {
codex,
conversation_id,
@@ -452,8 +432,6 @@ pub(crate) struct SessionConfiguration {
original_config_do_not_use: Arc<Config>,
/// Source of the session (cli, vscode, exec, mcp, ...)
session_source: SessionSource,
/// Whether the CLI is up to date with the latest known version at session start.
is_up_to_date: bool,
}
impl SessionConfiguration {
@@ -784,11 +762,6 @@ impl Session {
state.get_total_token_usage()
}
pub(crate) async fn is_up_to_date(&self) -> bool {
let state = self.state.lock().await;
state.session_configuration.is_up_to_date
}
async fn record_initial_history(&self, conversation_history: InitialHistory) {
let turn_context = self.new_turn(SessionSettingsUpdate::default()).await;
match conversation_history {
@@ -953,25 +926,7 @@ impl Session {
}
}
pub(crate) async fn send_event_raw(&self, mut event: Event) {
if matches!(&event.msg, EventMsg::Error(_) | EventMsg::StreamError(_)) {
let is_up_to_date = self.is_up_to_date().await;
event.msg = match event.msg {
EventMsg::Error(error_event) => EventMsg::Error(error_event_with_update_nudge(
error_event.message,
error_event.codex_error_info,
is_up_to_date,
)),
EventMsg::StreamError(error_event) => {
EventMsg::StreamError(stream_error_event_with_update_nudge(
error_event.message,
error_event.codex_error_info,
is_up_to_date,
))
}
other => other,
};
}
pub(crate) async fn send_event_raw(&self, event: Event) {
// Persist the event into rollout (recorder filters as needed)
let rollout_items = vec![RolloutItem::EventMsg(event.msg.clone())];
self.persist_rollout_items(&rollout_items).await;
@@ -2832,7 +2787,6 @@ mod tests {
original_config_do_not_use: Arc::clone(&config),
exec_policy: Arc::new(RwLock::new(ExecPolicy::empty())),
session_source: SessionSource::Exec,
is_up_to_date: true,
};
let mut state = SessionState::new(session_configuration);
@@ -2905,7 +2859,6 @@ mod tests {
original_config_do_not_use: Arc::clone(&config),
exec_policy: Arc::new(RwLock::new(ExecPolicy::empty())),
session_source: SessionSource::Exec,
is_up_to_date: true,
};
let mut state = SessionState::new(session_configuration);
@@ -3110,7 +3063,6 @@ mod tests {
original_config_do_not_use: Arc::clone(&config),
exec_policy: Arc::new(RwLock::new(ExecPolicy::empty())),
session_source: SessionSource::Exec,
is_up_to_date: true,
};
let per_turn_config = Session::build_per_turn_config(&session_configuration);
let model_family = ModelsManager::construct_model_family_offline(
@@ -3202,7 +3154,6 @@ mod tests {
original_config_do_not_use: Arc::clone(&config),
exec_policy: Arc::new(RwLock::new(ExecPolicy::empty())),
session_source: SessionSource::Exec,
is_up_to_date: true,
};
let per_turn_config = Session::build_per_turn_config(&session_configuration);
let model_family = ModelsManager::construct_model_family_offline(

View File

@@ -3,7 +3,6 @@ use crate::token_data::KnownPlan;
use crate::token_data::PlanType;
use crate::truncate::TruncationPolicy;
use crate::truncate::truncate_text;
use crate::update_action::update_available_nudge;
use chrono::DateTime;
use chrono::Datelike;
use chrono::Local;
@@ -13,7 +12,6 @@ use codex_protocol::ConversationId;
use codex_protocol::protocol::CodexErrorInfo;
use codex_protocol::protocol::ErrorEvent;
use codex_protocol::protocol::RateLimitSnapshot;
use codex_protocol::protocol::StreamErrorEvent;
use reqwest::StatusCode;
use serde_json;
use std::io;
@@ -26,43 +24,6 @@ pub type Result<T> = std::result::Result<T, CodexErr>;
/// Limit UI error messages to a reasonable size while keeping useful context.
const ERROR_MESSAGE_UI_MAX_BYTES: usize = 2 * 1024; // 4 KiB
pub(crate) fn error_event_with_update_nudge(
message: String,
codex_error_info: Option<CodexErrorInfo>,
is_up_to_date: bool,
) -> ErrorEvent {
let message = maybe_append_update_nudge(message, is_up_to_date);
ErrorEvent {
message,
codex_error_info,
}
}
pub(crate) fn stream_error_event_with_update_nudge(
message: String,
codex_error_info: Option<CodexErrorInfo>,
is_up_to_date: bool,
) -> StreamErrorEvent {
StreamErrorEvent {
message: maybe_append_update_nudge(message, is_up_to_date),
codex_error_info,
}
}
fn maybe_append_update_nudge(message: String, is_up_to_date: bool) -> String {
// skip if version is 0.0.0
let is_dev = env!("CARGO_PKG_VERSION") == "0.0.0";
if is_up_to_date || is_dev {
return message;
}
let nudge = update_available_nudge();
if message.is_empty() {
nudge
} else {
format!("{message}\n{nudge}")
}
}
#[derive(Error, Debug)]
pub enum SandboxErr {
/// Error from sandbox execution

View File

@@ -48,7 +48,8 @@ pub fn get_update_action() -> Option<UpdateAction> {
None
}
pub(crate) fn update_available_nudge() -> String {
/// Returns the standard update-available message for clients to display.
pub fn update_available_nudge() -> String {
match get_update_action() {
Some(action) => {
let command = action.command_str();

View File

@@ -676,7 +676,33 @@ impl ChatWidget {
self.model_family.clone()
}
fn maybe_append_update_nudge(&self, message: String) -> String {
if !self.should_show_update_nudge() {
return message;
}
let nudge = crate::update_action::update_available_nudge();
if message.is_empty() {
nudge
} else {
format!("{message}\n{nudge}")
}
}
#[cfg(not(debug_assertions))]
fn should_show_update_nudge(&self) -> bool {
if env!("CARGO_PKG_VERSION") == "0.0.0" {
return false;
}
crate::updates::get_upgrade_version(&self.config).is_some()
}
#[cfg(debug_assertions)]
fn should_show_update_nudge(&self) -> bool {
false
}
fn on_error(&mut self, message: String) {
let message = self.maybe_append_update_nudge(message);
self.finalize_turn();
self.add_to_history(history_cell::new_error_event(message));
self.request_redraw();
@@ -955,6 +981,7 @@ impl ChatWidget {
}
fn on_stream_error(&mut self, message: String) {
let message = self.maybe_append_update_nudge(message);
if self.retry_status_header.is_none() {
self.retry_status_header = Some(self.current_status_header.clone());
}