Keep owner nudge flow out of core

This commit is contained in:
Richard Lee
2026-04-15 15:19:08 -07:00
parent c079914656
commit 3dc09e8193
16 changed files with 94 additions and 200 deletions
-1
View File
@@ -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",
@@ -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<AddCreditsNudgeCreditType> for CoreAddCreditsNudgeCreditType {
fn from(value: AddCreditsNudgeCreditType) -> Self {
match value {
AddCreditsNudgeCreditType::Credits => Self::Credits,
AddCreditsNudgeCreditType::UsageLimit => Self::UsageLimit,
}
}
}
impl From<CoreAddCreditsNudgeCreditType> 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<CoreAddCreditsNudgeEmailStatus> for AddCreditsNudgeEmailStatus {
fn from(value: CoreAddCreditsNudgeEmailStatus) -> Self {
match value {
CoreAddCreditsNudgeEmailStatus::Sent => Self::Sent,
CoreAddCreditsNudgeEmailStatus::CooldownActive => Self::CooldownActive,
}
}
}
impl From<AddCreditsNudgeEmailStatus> 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/")]
@@ -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<CoreAddCreditsNudgeEmailStatus, JSONRPCErrorError> {
) -> Result<AddCreditsNudgeEmailStatus, JSONRPCErrorError> {
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<
@@ -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(
+7 -1
View File
@@ -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<anyhow::Error> 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,
+1
View File
@@ -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;
-1
View File
@@ -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 }
-62
View File
@@ -4702,16 +4702,6 @@ async fn submission_loop(sess: Arc<Session>, config: Arc<Config>, 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<Session>,
config: &Arc<Config>,
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<Session>,
config: &Arc<Config>,
credit_type: AddCreditsNudgeCreditType,
) -> Result<AddCreditsNudgeEmailStatus, String> {
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<String> {
| EventMsg::McpListToolsResponse(_)
| EventMsg::ListSkillsResponse(_)
| EventMsg::RealtimeConversationListVoicesResponse(_)
| EventMsg::AddCreditsNudgeEmailResponse(_)
| EventMsg::SkillsUpdateAvailable
| EventMsg::PlanUpdate(_)
| EventMsg::TurnAborted(_)
@@ -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
-48
View File
@@ -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<AddCreditsNudgeEmailStatus> 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.
-1
View File
@@ -161,7 +161,6 @@ fn event_msg_persistence_mode(ev: &EventMsg) -> Option<EventPersistenceMode> {
| EventMsg::UndoStarted(_)
| EventMsg::McpListToolsResponse(_)
| EventMsg::RealtimeConversationListVoicesResponse(_)
| EventMsg::AddCreditsNudgeEmailResponse(_)
| EventMsg::McpStartupUpdate(_)
| EventMsg::McpStartupComplete(_)
| EventMsg::ListSkillsResponse(_)
+4 -11
View File
@@ -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")?;
+3 -3
View File
@@ -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<AddCreditsNudgeEmailStatus, String>,
},
/// Result of prefetching connectors.
+15 -16
View File
@@ -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<AddCreditsNudgeEmailStatus, String>,
) {
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."
}
};
+2 -2
View File
@@ -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;
@@ -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.",
),
];