diff --git a/codex-rs/Cargo.lock b/codex-rs/Cargo.lock index 6694490a24..ea79776bdc 100644 --- a/codex-rs/Cargo.lock +++ b/codex-rs/Cargo.lock @@ -1906,7 +1906,6 @@ dependencies = [ "codex-app-server-protocol", "codex-apply-patch", "codex-async-utils", - "codex-backend-client", "codex-code-mode", "codex-config", "codex-connectors", diff --git a/codex-rs/app-server-protocol/src/protocol/v2.rs b/codex-rs/app-server-protocol/src/protocol/v2.rs index 566c1d4cc6..13c49dc030 100644 --- a/codex-rs/app-server-protocol/src/protocol/v2.rs +++ b/codex-rs/app-server-protocol/src/protocol/v2.rs @@ -48,8 +48,6 @@ use codex_protocol::openai_models::default_input_modalities; use codex_protocol::parse_command::ParsedCommand as CoreParsedCommand; use codex_protocol::plan_tool::PlanItemArg as CorePlanItemArg; use codex_protocol::plan_tool::StepStatus as CorePlanStepStatus; -use codex_protocol::protocol::AddCreditsNudgeCreditType as CoreAddCreditsNudgeCreditType; -use codex_protocol::protocol::AddCreditsNudgeEmailStatus as CoreAddCreditsNudgeEmailStatus; use codex_protocol::protocol::AgentStatus as CoreAgentStatus; use codex_protocol::protocol::AskForApproval as CoreAskForApproval; use codex_protocol::protocol::CodexErrorInfo as CoreCodexErrorInfo; @@ -1780,24 +1778,6 @@ pub enum AddCreditsNudgeCreditType { UsageLimit, } -impl From for CoreAddCreditsNudgeCreditType { - fn from(value: AddCreditsNudgeCreditType) -> Self { - match value { - AddCreditsNudgeCreditType::Credits => Self::Credits, - AddCreditsNudgeCreditType::UsageLimit => Self::UsageLimit, - } - } -} - -impl From for AddCreditsNudgeCreditType { - fn from(value: CoreAddCreditsNudgeCreditType) -> Self { - match value { - CoreAddCreditsNudgeCreditType::Credits => Self::Credits, - CoreAddCreditsNudgeCreditType::UsageLimit => Self::UsageLimit, - } - } -} - #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] @@ -1813,24 +1793,6 @@ pub enum AddCreditsNudgeEmailStatus { CooldownActive, } -impl From for AddCreditsNudgeEmailStatus { - fn from(value: CoreAddCreditsNudgeEmailStatus) -> Self { - match value { - CoreAddCreditsNudgeEmailStatus::Sent => Self::Sent, - CoreAddCreditsNudgeEmailStatus::CooldownActive => Self::CooldownActive, - } - } -} - -impl From for CoreAddCreditsNudgeEmailStatus { - fn from(value: AddCreditsNudgeEmailStatus) -> Self { - match value { - AddCreditsNudgeEmailStatus::Sent => Self::Sent, - AddCreditsNudgeEmailStatus::CooldownActive => Self::CooldownActive, - } - } -} - #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] diff --git a/codex-rs/app-server/src/codex_message_processor.rs b/codex-rs/app-server/src/codex_message_processor.rs index 1b4e8e372f..626ea95add 100644 --- a/codex-rs/app-server/src/codex_message_processor.rs +++ b/codex-rs/app-server/src/codex_message_processor.rs @@ -28,6 +28,8 @@ use codex_analytics::TurnSteerRequestError; use codex_app_server_protocol::Account; use codex_app_server_protocol::AccountLoginCompletedNotification; use codex_app_server_protocol::AccountUpdatedNotification; +use codex_app_server_protocol::AddCreditsNudgeCreditType; +use codex_app_server_protocol::AddCreditsNudgeEmailStatus; use codex_app_server_protocol::AppInfo; use codex_app_server_protocol::AppsListParams; use codex_app_server_protocol::AppsListResponse; @@ -199,6 +201,7 @@ use codex_app_server_protocol::WindowsSandboxSetupStartParams; use codex_app_server_protocol::WindowsSandboxSetupStartResponse; use codex_app_server_protocol::build_turns_from_rollout_items; use codex_arg0::Arg0DispatchPaths; +use codex_backend_client::AddCreditsNudgeCreditType as BackendAddCreditsNudgeCreditType; use codex_backend_client::Client as BackendClient; use codex_chatgpt::connectors; use codex_cloud_requirements::cloud_requirements_loader; @@ -290,7 +293,6 @@ use codex_protocol::error::CodexErr; use codex_protocol::error::Result as CodexResult; use codex_protocol::items::TurnItem; use codex_protocol::models::ResponseItem; -use codex_protocol::protocol::AddCreditsNudgeEmailStatus as CoreAddCreditsNudgeEmailStatus; use codex_protocol::protocol::AgentStatus; use codex_protocol::protocol::ConversationAudioParams; use codex_protocol::protocol::ConversationStartParams; @@ -1907,7 +1909,7 @@ impl CodexMessageProcessor { async fn send_add_credits_nudge_email_inner( &self, params: SendAddCreditsNudgeEmailParams, - ) -> Result { + ) -> Result { let Some(auth) = self.auth_manager.auth().await else { return Err(JSONRPCErrorError { code: INVALID_REQUEST_ERROR_CODE, @@ -1933,12 +1935,12 @@ impl CodexMessageProcessor { })?; match client - .send_add_credits_nudge_email(params.credit_type.into()) + .send_add_credits_nudge_email(Self::backend_credit_type(params.credit_type)) .await { - Ok(()) => Ok(CoreAddCreditsNudgeEmailStatus::Sent), + Ok(()) => Ok(AddCreditsNudgeEmailStatus::Sent), Err(err) if err.status().is_some_and(|status| status.as_u16() == 429) => { - Ok(CoreAddCreditsNudgeEmailStatus::CooldownActive) + Ok(AddCreditsNudgeEmailStatus::CooldownActive) } Err(err) => Err(JSONRPCErrorError { code: INTERNAL_ERROR_CODE, @@ -1948,6 +1950,13 @@ impl CodexMessageProcessor { } } + fn backend_credit_type(value: AddCreditsNudgeCreditType) -> BackendAddCreditsNudgeCreditType { + match value { + AddCreditsNudgeCreditType::Credits => BackendAddCreditsNudgeCreditType::Credits, + AddCreditsNudgeCreditType::UsageLimit => BackendAddCreditsNudgeCreditType::UsageLimit, + } + } + async fn fetch_account_rate_limits( &self, ) -> Result< diff --git a/codex-rs/app-server/tests/suite/v2/rate_limits.rs b/codex-rs/app-server/tests/suite/v2/rate_limits.rs index 2104d4ca81..b1a108dc7b 100644 --- a/codex-rs/app-server/tests/suite/v2/rate_limits.rs +++ b/codex-rs/app-server/tests/suite/v2/rate_limits.rs @@ -280,6 +280,48 @@ async fn send_add_credits_nudge_email_posts_expected_body() -> Result<()> { Ok(()) } +#[tokio::test] +async fn send_add_credits_nudge_email_maps_cooldown() -> Result<()> { + let codex_home = TempDir::new()?; + write_chatgpt_auth( + codex_home.path(), + ChatGptAuthFixture::new("chatgpt-token") + .account_id("account-123") + .plan_type("pro"), + AuthCredentialsStoreMode::File, + )?; + + let server = MockServer::start().await; + let server_url = server.uri(); + write_chatgpt_base_url(codex_home.path(), &server_url)?; + + Mock::given(method("POST")) + .and(path("/api/codex/accounts/send_add_credits_nudge_email")) + .respond_with(ResponseTemplate::new(429)) + .mount(&server) + .await; + + let mut mcp = McpProcess::new_with_env(codex_home.path(), &[("OPENAI_API_KEY", None)]).await?; + timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??; + + let request_id = mcp + .send_add_credits_nudge_email_request(SendAddCreditsNudgeEmailParams { + credit_type: AddCreditsNudgeCreditType::Credits, + }) + .await?; + + let response: JSONRPCResponse = timeout( + DEFAULT_READ_TIMEOUT, + mcp.read_stream_until_response_message(RequestId::Integer(request_id)), + ) + .await??; + let received: SendAddCreditsNudgeEmailResponse = to_response(response)?; + + assert_eq!(received.status, AddCreditsNudgeEmailStatus::CooldownActive); + + Ok(()) +} + async fn login_with_api_key(mcp: &mut McpProcess, api_key: &str) -> Result<()> { let request_id = mcp.send_login_account_api_key_request(api_key).await?; let response: JSONRPCResponse = timeout( diff --git a/codex-rs/backend-client/src/client.rs b/codex-rs/backend-client/src/client.rs index d7d6b7ffe2..e024974a0e 100644 --- a/codex-rs/backend-client/src/client.rs +++ b/codex-rs/backend-client/src/client.rs @@ -9,7 +9,6 @@ use codex_client::build_reqwest_client_with_custom_ca; use codex_login::CodexAuth; use codex_login::default_client::get_codex_user_agent; use codex_protocol::account::PlanType as AccountPlanType; -use codex_protocol::protocol::AddCreditsNudgeCreditType; use codex_protocol::protocol::CreditsSnapshot; use codex_protocol::protocol::RateLimitReachedType; use codex_protocol::protocol::RateLimitSnapshot; @@ -83,6 +82,13 @@ impl From for RequestError { } } +#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)] +#[serde(rename_all = "snake_case")] +pub enum AddCreditsNudgeCreditType { + Credits, + UsageLimit, +} + #[derive(Serialize)] struct SendAddCreditsNudgeEmailRequest { credit_type: AddCreditsNudgeCreditType, diff --git a/codex-rs/backend-client/src/lib.rs b/codex-rs/backend-client/src/lib.rs index 397c2a2cd4..300da81568 100644 --- a/codex-rs/backend-client/src/lib.rs +++ b/codex-rs/backend-client/src/lib.rs @@ -1,6 +1,7 @@ mod client; pub(crate) mod types; +pub use client::AddCreditsNudgeCreditType; pub use client::Client; pub use client::RequestError; pub use types::CodeTaskDetailsResponse; diff --git a/codex-rs/core/Cargo.toml b/codex-rs/core/Cargo.toml index 7d48c532bc..c91f07f705 100644 --- a/codex-rs/core/Cargo.toml +++ b/codex-rs/core/Cargo.toml @@ -30,7 +30,6 @@ codex-api = { workspace = true } codex-app-server-protocol = { workspace = true } codex-apply-patch = { workspace = true } codex-async-utils = { workspace = true } -codex-backend-client = { workspace = true } codex-code-mode = { workspace = true } codex-connectors = { workspace = true } codex-config = { workspace = true } diff --git a/codex-rs/core/src/codex.rs b/codex-rs/core/src/codex.rs index 3052d7b662..95e932b1dc 100644 --- a/codex-rs/core/src/codex.rs +++ b/codex-rs/core/src/codex.rs @@ -4702,16 +4702,6 @@ async fn submission_loop(sess: Arc, config: Arc, rx_sub: Receiv handlers::realtime_conversation_list_voices(&sess, sub.id.clone()).await; false } - Op::SendAddCreditsNudgeEmail { credit_type } => { - handlers::send_add_credits_nudge_email( - &sess, - &config, - sub.id.clone(), - credit_type, - ) - .await; - false - } Op::OverrideTurnContext { cwd, approval_policy, @@ -4941,13 +4931,8 @@ mod handlers { use crate::tasks::UserShellCommandMode; use crate::tasks::UserShellCommandTask; use crate::tasks::execute_user_shell_command; - use codex_backend_client::Client as BackendClient; use codex_mcp::collect_mcp_snapshot_from_manager; use codex_mcp::compute_auth_statuses; - use codex_protocol::protocol::AddCreditsNudgeCreditType; - use codex_protocol::protocol::AddCreditsNudgeEmailResponseEvent; - use codex_protocol::protocol::AddCreditsNudgeEmailResult; - use codex_protocol::protocol::AddCreditsNudgeEmailStatus; use codex_protocol::protocol::CodexErrorInfo; use codex_protocol::protocol::ErrorEvent; use codex_protocol::protocol::Event; @@ -4981,7 +4966,6 @@ mod handlers { use codex_protocol::user_input::UserInput; use codex_rmcp_client::ElicitationAction; use codex_rmcp_client::ElicitationResponse; - use reqwest::StatusCode; use serde_json::Value; use std::path::PathBuf; use std::sync::Arc; @@ -5009,51 +4993,6 @@ mod handlers { .await; } - pub async fn send_add_credits_nudge_email( - sess: &Arc, - config: &Arc, - sub_id: String, - credit_type: AddCreditsNudgeCreditType, - ) { - let result = match send_add_credits_nudge_email_inner(sess, config, credit_type).await { - Ok(status) => status.into(), - Err(message) => AddCreditsNudgeEmailResult::Failed { message }, - }; - sess.send_event_raw(Event { - id: sub_id, - msg: EventMsg::AddCreditsNudgeEmailResponse(AddCreditsNudgeEmailResponseEvent { - result, - }), - }) - .await; - } - - async fn send_add_credits_nudge_email_inner( - sess: &Arc, - config: &Arc, - credit_type: AddCreditsNudgeCreditType, - ) -> Result { - let Some(auth) = sess.services.auth_manager.auth().await else { - return Err( - "codex account authentication required to notify workspace owner".to_string(), - ); - }; - - if !auth.is_chatgpt_auth() { - return Err("chatgpt authentication required to notify workspace owner".to_string()); - } - - let client = BackendClient::from_auth(config.chatgpt_base_url.clone(), &auth) - .map_err(|err| format!("failed to construct backend client: {err}"))?; - match client.send_add_credits_nudge_email(credit_type).await { - Ok(()) => Ok(AddCreditsNudgeEmailStatus::Sent), - Err(err) if err.status() == Some(StatusCode::TOO_MANY_REQUESTS) => { - Ok(AddCreditsNudgeEmailStatus::CooldownActive) - } - Err(err) => Err(format!("failed to notify workspace owner: {err}")), - } - } - pub async fn override_turn_context( sess: &Session, sub_id: String, @@ -7531,7 +7470,6 @@ fn realtime_text_for_event(msg: &EventMsg) -> Option { | EventMsg::McpListToolsResponse(_) | EventMsg::ListSkillsResponse(_) | EventMsg::RealtimeConversationListVoicesResponse(_) - | EventMsg::AddCreditsNudgeEmailResponse(_) | EventMsg::SkillsUpdateAvailable | EventMsg::PlanUpdate(_) | EventMsg::TurnAborted(_) diff --git a/codex-rs/mcp-server/src/codex_tool_runner.rs b/codex-rs/mcp-server/src/codex_tool_runner.rs index ef20b992d1..eee2347202 100644 --- a/codex-rs/mcp-server/src/codex_tool_runner.rs +++ b/codex-rs/mcp-server/src/codex_tool_runner.rs @@ -393,7 +393,6 @@ async fn run_codex_tool_session_inner( | EventMsg::RealtimeConversationSdp(_) | EventMsg::RealtimeConversationRealtime(_) | EventMsg::RealtimeConversationClosed(_) - | EventMsg::AddCreditsNudgeEmailResponse(_) | EventMsg::DeprecationNotice(_) => { // For now, we do not do anything extra for these // events. Note that diff --git a/codex-rs/protocol/src/protocol.rs b/codex-rs/protocol/src/protocol.rs index f62cb7f27c..6091213852 100644 --- a/codex-rs/protocol/src/protocol.rs +++ b/codex-rs/protocol/src/protocol.rs @@ -400,12 +400,6 @@ pub enum Op { /// Request the list of voices supported by realtime conversation streams. RealtimeConversationListVoices, - /// Ask the workspace owner to add credits or raise the workspace usage - /// limit after the user confirms an actionable workspace member limit. - SendAddCreditsNudgeEmail { - credit_type: AddCreditsNudgeCreditType, - }, - /// Legacy user input. /// /// Prefer [`Op::UserTurn`] so the caller provides full turn context @@ -770,7 +764,6 @@ impl Op { Self::RealtimeConversationText(_) => "realtime_conversation_text", Self::RealtimeConversationClose => "realtime_conversation_close", Self::RealtimeConversationListVoices => "realtime_conversation_list_voices", - Self::SendAddCreditsNudgeEmail { .. } => "send_add_credits_nudge_email", Self::UserInput { .. } => "user_input", Self::UserTurn { .. } => "user_turn", Self::InterAgentCommunication { .. } => "inter_agent_communication", @@ -1559,8 +1552,6 @@ pub enum EventMsg { /// Notification that skill data may have been updated and clients may want to reload. SkillsUpdateAvailable, - AddCreditsNudgeEmailResponse(AddCreditsNudgeEmailResponseEvent), - PlanUpdate(UpdatePlanArgs), TurnAborted(TurnAbortedEvent), @@ -2189,45 +2180,6 @@ pub enum RateLimitReachedType { WorkspaceMemberUsageLimitReached, } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize, JsonSchema, TS)] -#[serde(rename_all = "snake_case")] -#[ts(rename_all = "snake_case")] -pub enum AddCreditsNudgeCreditType { - Credits, - UsageLimit, -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize, JsonSchema, TS)] -#[serde(rename_all = "snake_case")] -#[ts(rename_all = "snake_case")] -pub enum AddCreditsNudgeEmailStatus { - Sent, - CooldownActive, -} - -#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, JsonSchema, TS)] -#[serde(tag = "status", rename_all = "snake_case")] -#[ts(tag = "status")] -pub enum AddCreditsNudgeEmailResult { - Sent, - CooldownActive, - Failed { message: String }, -} - -impl From for AddCreditsNudgeEmailResult { - fn from(value: AddCreditsNudgeEmailStatus) -> Self { - match value { - AddCreditsNudgeEmailStatus::Sent => Self::Sent, - AddCreditsNudgeEmailStatus::CooldownActive => Self::CooldownActive, - } - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, JsonSchema, TS)] -pub struct AddCreditsNudgeEmailResponseEvent { - pub result: AddCreditsNudgeEmailResult, -} - #[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema, TS)] pub struct RateLimitWindow { /// Percentage (0-100) of the window that has been consumed. diff --git a/codex-rs/rollout/src/policy.rs b/codex-rs/rollout/src/policy.rs index 4223c8ad5c..4b50781e76 100644 --- a/codex-rs/rollout/src/policy.rs +++ b/codex-rs/rollout/src/policy.rs @@ -161,7 +161,6 @@ fn event_msg_persistence_mode(ev: &EventMsg) -> Option { | EventMsg::UndoStarted(_) | EventMsg::McpListToolsResponse(_) | EventMsg::RealtimeConversationListVoicesResponse(_) - | EventMsg::AddCreditsNudgeEmailResponse(_) | EventMsg::McpStartupUpdate(_) | EventMsg::McpStartupComplete(_) | EventMsg::ListSkillsResponse(_) diff --git a/codex-rs/tui/src/app.rs b/codex-rs/tui/src/app.rs index cfe288d4ee..6ffd64aeae 100644 --- a/codex-rs/tui/src/app.rs +++ b/codex-rs/tui/src/app.rs @@ -72,6 +72,8 @@ use crate::version::CODEX_CLI_VERSION; use codex_ansi_escape::ansi_escape_line; use codex_app_server_client::AppServerRequestHandle; use codex_app_server_client::TypedRequestError; +use codex_app_server_protocol::AddCreditsNudgeCreditType; +use codex_app_server_protocol::AddCreditsNudgeEmailStatus; use codex_app_server_protocol::ClientRequest; use codex_app_server_protocol::CodexErrorInfo as AppServerCodexErrorInfo; use codex_app_server_protocol::ConfigLayerSource; @@ -119,9 +121,6 @@ use codex_protocol::openai_models::ModelAvailabilityNux; use codex_protocol::openai_models::ModelPreset; use codex_protocol::openai_models::ModelUpgrade; use codex_protocol::openai_models::ReasoningEffort as ReasoningEffortConfig; -use codex_protocol::protocol::AddCreditsNudgeCreditType; -use codex_protocol::protocol::AddCreditsNudgeEmailResult; -use codex_protocol::protocol::AddCreditsNudgeEmailStatus; use codex_protocol::protocol::AskForApproval; use codex_protocol::protocol::FinalOutput; use codex_protocol::protocol::GetHistoryEntryResponseEvent; @@ -1956,11 +1955,7 @@ impl App { tokio::spawn(async move { let result = send_add_credits_nudge_email(request_handle, credit_type) .await - .map(AddCreditsNudgeEmailStatus::from) - .map(AddCreditsNudgeEmailResult::from) - .unwrap_or_else(|err| AddCreditsNudgeEmailResult::Failed { - message: err.to_string(), - }); + .map_err(|err| err.to_string()); app_event_tx.send(AppEvent::AddCreditsNudgeEmailFinished { result }); }); } @@ -6269,9 +6264,7 @@ async fn send_add_credits_nudge_email( let response: codex_app_server_protocol::SendAddCreditsNudgeEmailResponse = request_handle .request_typed(ClientRequest::SendAddCreditsNudgeEmail { request_id, - params: SendAddCreditsNudgeEmailParams { - credit_type: credit_type.into(), - }, + params: SendAddCreditsNudgeEmailParams { credit_type }, }) .await .wrap_err("account/sendAddCreditsNudgeEmail failed in TUI")?; diff --git a/codex-rs/tui/src/app_event.rs b/codex-rs/tui/src/app_event.rs index 4ec4cebec4..fe9f800898 100644 --- a/codex-rs/tui/src/app_event.rs +++ b/codex-rs/tui/src/app_event.rs @@ -10,6 +10,8 @@ use std::path::PathBuf; +use codex_app_server_protocol::AddCreditsNudgeCreditType; +use codex_app_server_protocol::AddCreditsNudgeEmailStatus; use codex_app_server_protocol::McpServerStatus; use codex_app_server_protocol::PluginInstallResponse; use codex_app_server_protocol::PluginListResponse; @@ -20,8 +22,6 @@ use codex_chatgpt::connectors::AppInfo; use codex_file_search::FileMatch; use codex_protocol::ThreadId; use codex_protocol::openai_models::ModelPreset; -use codex_protocol::protocol::AddCreditsNudgeCreditType; -use codex_protocol::protocol::AddCreditsNudgeEmailResult; use codex_protocol::protocol::GetHistoryEntryResponseEvent; use codex_protocol::protocol::Op; use codex_protocol::protocol::RateLimitSnapshot; @@ -180,7 +180,7 @@ pub(crate) enum AppEvent { /// Result of notifying the workspace owner. AddCreditsNudgeEmailFinished { - result: AddCreditsNudgeEmailResult, + result: Result, }, /// Result of prefetching connectors. diff --git a/codex-rs/tui/src/chatwidget.rs b/codex-rs/tui/src/chatwidget.rs index 4f4cf60d8b..cc1f1f06ea 100644 --- a/codex-rs/tui/src/chatwidget.rs +++ b/codex-rs/tui/src/chatwidget.rs @@ -78,6 +78,8 @@ use crate::terminal_title::clear_terminal_title; use crate::terminal_title::set_terminal_title; use crate::text_formatting::proper_join; use crate::version::CODEX_CLI_VERSION; +use codex_app_server_protocol::AddCreditsNudgeCreditType; +use codex_app_server_protocol::AddCreditsNudgeEmailStatus; use codex_app_server_protocol::AppSummary; use codex_app_server_protocol::CodexErrorInfo as AppServerCodexErrorInfo; use codex_app_server_protocol::CollabAgentState as AppServerCollabAgentState; @@ -134,8 +136,6 @@ use codex_protocol::models::local_image_label_text; use codex_protocol::parse_command::ParsedCommand; use codex_protocol::plan_tool::PlanItemArg as UpdatePlanItemArg; use codex_protocol::plan_tool::StepStatus as UpdatePlanItemStatus; -use codex_protocol::protocol::AddCreditsNudgeCreditType; -use codex_protocol::protocol::AddCreditsNudgeEmailResult; #[cfg(test)] use codex_protocol::protocol::AgentMessageDeltaEvent; #[cfg(test)] @@ -6677,9 +6677,6 @@ impl ChatWidget { self.set_token_info(ev.info); self.on_rate_limit_snapshot(ev.rate_limits); } - EventMsg::AddCreditsNudgeEmailResponse(ev) => { - self.finish_add_credits_nudge_email_request(ev.result); - } EventMsg::Warning(WarningEvent { message }) => self.on_warning(message), EventMsg::GuardianAssessment(ev) => self.on_guardian_assessment(ev), EventMsg::ModelReroute(_) => {} @@ -7554,29 +7551,31 @@ impl ChatWidget { pub(crate) fn finish_add_credits_nudge_email_request( &mut self, - result: AddCreditsNudgeEmailResult, + result: Result, ) { let credit_type = self .add_credits_nudge_email_in_flight .take() .unwrap_or(AddCreditsNudgeCreditType::Credits); let message = match (credit_type, result) { - (AddCreditsNudgeCreditType::Credits, AddCreditsNudgeEmailResult::Sent) => { + (AddCreditsNudgeCreditType::Credits, Ok(AddCreditsNudgeEmailStatus::Sent)) => { "Workspace owner notified." } - (AddCreditsNudgeCreditType::Credits, AddCreditsNudgeEmailResult::CooldownActive) => { - "Workspace owner was already notified recently." - } - (AddCreditsNudgeCreditType::Credits, AddCreditsNudgeEmailResult::Failed { .. }) => { + ( + AddCreditsNudgeCreditType::Credits, + Ok(AddCreditsNudgeEmailStatus::CooldownActive), + ) => "Workspace owner was already notified recently.", + (AddCreditsNudgeCreditType::Credits, Err(_)) => { "Could not notify your workspace owner. Please try again." } - (AddCreditsNudgeCreditType::UsageLimit, AddCreditsNudgeEmailResult::Sent) => { + (AddCreditsNudgeCreditType::UsageLimit, Ok(AddCreditsNudgeEmailStatus::Sent)) => { "Limit increase requested." } - (AddCreditsNudgeCreditType::UsageLimit, AddCreditsNudgeEmailResult::CooldownActive) => { - "A limit increase was already requested recently." - } - (AddCreditsNudgeCreditType::UsageLimit, AddCreditsNudgeEmailResult::Failed { .. }) => { + ( + AddCreditsNudgeCreditType::UsageLimit, + Ok(AddCreditsNudgeEmailStatus::CooldownActive), + ) => "A limit increase was already requested recently.", + (AddCreditsNudgeCreditType::UsageLimit, Err(_)) => { "Could not request a limit increase. Please try again." } }; diff --git a/codex-rs/tui/src/chatwidget/tests.rs b/codex-rs/tui/src/chatwidget/tests.rs index 5f8a7e3185..8adcfe6e8f 100644 --- a/codex-rs/tui/src/chatwidget/tests.rs +++ b/codex-rs/tui/src/chatwidget/tests.rs @@ -33,6 +33,8 @@ pub(super) use crate::test_support::test_path_buf; pub(super) use crate::test_support::test_path_display; pub(super) use crate::tui::FrameRequester; pub(super) use assert_matches::assert_matches; +pub(super) use codex_app_server_protocol::AddCreditsNudgeCreditType; +pub(super) use codex_app_server_protocol::AddCreditsNudgeEmailStatus; pub(super) use codex_app_server_protocol::AdditionalFileSystemPermissions as AppServerAdditionalFileSystemPermissions; pub(super) use codex_app_server_protocol::AdditionalNetworkPermissions as AppServerAdditionalNetworkPermissions; pub(super) use codex_app_server_protocol::AdditionalPermissionProfile as AppServerAdditionalPermissionProfile; @@ -129,8 +131,6 @@ pub(super) use codex_protocol::parse_command::ParsedCommand; pub(super) use codex_protocol::plan_tool::PlanItemArg; pub(super) use codex_protocol::plan_tool::StepStatus; pub(super) use codex_protocol::plan_tool::UpdatePlanArgs; -pub(super) use codex_protocol::protocol::AddCreditsNudgeCreditType; -pub(super) use codex_protocol::protocol::AddCreditsNudgeEmailResult; pub(super) use codex_protocol::protocol::AgentMessageDeltaEvent; pub(super) use codex_protocol::protocol::AgentMessageEvent; pub(super) use codex_protocol::protocol::AgentReasoningDeltaEvent; diff --git a/codex-rs/tui/src/chatwidget/tests/status_and_layout.rs b/codex-rs/tui/src/chatwidget/tests/status_and_layout.rs index 30b20a5a74..d43abd5cf5 100644 --- a/codex-rs/tui/src/chatwidget/tests/status_and_layout.rs +++ b/codex-rs/tui/src/chatwidget/tests/status_and_layout.rs @@ -615,17 +615,15 @@ async fn workspace_owner_nudge_default_no_dismisses_without_sending() { async fn workspace_owner_credits_nudge_completion_renders_feedback() { let cases = [ ( - AddCreditsNudgeEmailResult::Sent, + Ok(AddCreditsNudgeEmailStatus::Sent), "Workspace owner notified.", ), ( - AddCreditsNudgeEmailResult::CooldownActive, + Ok(AddCreditsNudgeEmailStatus::CooldownActive), "Workspace owner was already notified recently.", ), ( - AddCreditsNudgeEmailResult::Failed { - message: "request failed".to_string(), - }, + Err("request failed".to_string()), "Could not notify your workspace owner. Please try again.", ), ]; @@ -653,17 +651,15 @@ async fn workspace_owner_credits_nudge_completion_renders_feedback() { async fn workspace_owner_usage_limit_nudge_completion_renders_feedback() { let cases = [ ( - AddCreditsNudgeEmailResult::Sent, + Ok(AddCreditsNudgeEmailStatus::Sent), "Limit increase requested.", ), ( - AddCreditsNudgeEmailResult::CooldownActive, + Ok(AddCreditsNudgeEmailStatus::CooldownActive), "A limit increase was already requested recently.", ), ( - AddCreditsNudgeEmailResult::Failed { - message: "request failed".to_string(), - }, + Err("request failed".to_string()), "Could not request a limit increase. Please try again.", ), ];