codex: address PR review feedback (#16969)

This commit is contained in:
Richard Lee
2026-04-07 21:53:17 -07:00
parent 43f381cae6
commit 3650918b95
4 changed files with 90 additions and 42 deletions

View File

@@ -1,9 +1,39 @@
use codex_backend_client::Client as BackendClient;
use codex_backend_client::RequestError;
use codex_backend_client::WorkspaceRole as BackendWorkspaceRole;
use codex_login::AuthManager;
use codex_login::CodexAuth;
use thiserror::Error;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum WorkspaceRole {
AccountOwner,
AccountAdmin,
StandardUser,
}
impl WorkspaceRole {
fn is_workspace_owner(self) -> bool {
matches!(self, Self::AccountOwner | Self::AccountAdmin)
}
}
impl From<BackendWorkspaceRole> for WorkspaceRole {
fn from(value: BackendWorkspaceRole) -> Self {
match value {
BackendWorkspaceRole::AccountOwner => Self::AccountOwner,
BackendWorkspaceRole::AccountAdmin => Self::AccountAdmin,
BackendWorkspaceRole::StandardUser => Self::StandardUser,
}
}
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct WorkspaceOwnership {
pub workspace_role: Option<WorkspaceRole>,
pub is_workspace_owner: Option<bool>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum AddCreditsNudgeEmailStatus {
Sent,
@@ -53,3 +83,39 @@ pub async fn send_add_credits_nudge_email_for_auth(
Err(err) => Err(err.into()),
}
}
pub async fn resolve_workspace_role_and_owner_for_auth(
chatgpt_base_url: &str,
auth: Option<&CodexAuth>,
) -> WorkspaceOwnership {
let token_is_workspace_owner = auth.and_then(CodexAuth::is_workspace_owner);
let Some(auth) = auth else {
return WorkspaceOwnership::default();
};
let workspace_role = fetch_current_workspace_role_for_auth(chatgpt_base_url, auth).await;
let is_workspace_owner = workspace_role
.map(WorkspaceRole::is_workspace_owner)
.or(token_is_workspace_owner);
WorkspaceOwnership {
workspace_role,
is_workspace_owner,
}
}
async fn fetch_current_workspace_role_for_auth(
chatgpt_base_url: &str,
auth: &CodexAuth,
) -> Option<WorkspaceRole> {
if !auth.is_chatgpt_auth() || auth.get_account_id().is_none() {
return None;
}
let client = BackendClient::from_auth(chatgpt_base_url.to_string(), auth).ok()?;
client
.get_current_workspace_role()
.await
.ok()
.flatten()
.map(WorkspaceRole::from)
}

View File

@@ -185,7 +185,6 @@ use codex_app_server_protocol::WorkspaceRole;
use codex_app_server_protocol::build_turns_from_rollout_items;
use codex_arg0::Arg0DispatchPaths;
use codex_backend_client::Client as BackendClient;
use codex_backend_client::WorkspaceRole as BackendWorkspaceRole;
use codex_chatgpt::connectors;
use codex_cloud_requirements::cloud_requirements_loader;
use codex_config::types::McpServerTransportConfig;
@@ -199,6 +198,7 @@ use codex_core::SteerInputError;
use codex_core::ThreadConfigSnapshot;
use codex_core::ThreadManager;
use codex_core::ThreadSortKey as CoreThreadSortKey;
use codex_core::WorkspaceRole as CoreWorkspaceRole;
use codex_core::config::Config;
use codex_core::config::ConfigOverrides;
use codex_core::config::NetworkProxyAuditMetadata;
@@ -485,49 +485,19 @@ async fn resolve_workspace_role_and_owner_for_auth(
chatgpt_base_url: &str,
auth: Option<&CodexAuth>,
) -> (Option<WorkspaceRole>, Option<bool>) {
let token_is_workspace_owner = auth.and_then(CodexAuth::is_workspace_owner);
let Some(auth) = auth else {
return (None, None);
};
let workspace_role = fetch_current_workspace_role_for_auth(chatgpt_base_url, auth).await;
let is_workspace_owner = workspace_role
.map(|role| {
matches!(
role,
WorkspaceRole::AccountOwner | WorkspaceRole::AccountAdmin
)
})
.or(token_is_workspace_owner);
(workspace_role, is_workspace_owner)
let ownership =
codex_core::resolve_workspace_role_and_owner_for_auth(chatgpt_base_url, auth).await;
(
ownership.workspace_role.map(workspace_role_to_v2),
ownership.is_workspace_owner,
)
}
async fn fetch_current_workspace_role_for_auth(
chatgpt_base_url: &str,
auth: &CodexAuth,
) -> Option<WorkspaceRole> {
if !auth.is_chatgpt_auth() || auth.get_account_id().is_none() {
return None;
}
let client = match BackendClient::from_auth(chatgpt_base_url.to_string(), auth) {
Ok(client) => client,
Err(err) => {
warn!("failed to construct backend client for workspace role fetch: {err}");
return None;
}
};
match client.get_current_workspace_role().await {
Ok(role) => role.map(|role| match role {
BackendWorkspaceRole::AccountOwner => WorkspaceRole::AccountOwner,
BackendWorkspaceRole::AccountAdmin => WorkspaceRole::AccountAdmin,
BackendWorkspaceRole::StandardUser => WorkspaceRole::StandardUser,
}),
Err(err) => {
warn!("failed to fetch current workspace role from backend: {err}");
None
}
fn workspace_role_to_v2(role: CoreWorkspaceRole) -> WorkspaceRole {
match role {
CoreWorkspaceRole::AccountOwner => WorkspaceRole::AccountOwner,
CoreWorkspaceRole::AccountAdmin => WorkspaceRole::AccountAdmin,
CoreWorkspaceRole::StandardUser => WorkspaceRole::StandardUser,
}
}

View File

@@ -1,7 +1,9 @@
use crate::config::Config;
use codex_account::AddCreditsNudgeEmailStatus;
use codex_account::SendAddCreditsNudgeEmailError;
use codex_account::WorkspaceOwnership;
use codex_login::AuthManager;
use codex_login::CodexAuth;
pub async fn send_add_credits_nudge_email(
config: &Config,
@@ -9,3 +11,10 @@ pub async fn send_add_credits_nudge_email(
) -> Result<AddCreditsNudgeEmailStatus, SendAddCreditsNudgeEmailError> {
codex_account::send_add_credits_nudge_email(config.chatgpt_base_url.clone(), auth_manager).await
}
pub async fn resolve_workspace_role_and_owner_for_auth(
chatgpt_base_url: &str,
auth: Option<&CodexAuth>,
) -> WorkspaceOwnership {
codex_account::resolve_workspace_role_and_owner_for_auth(chatgpt_base_url, auth).await
}

View File

@@ -110,10 +110,13 @@ mod stream_events_utils;
pub mod test_support;
mod unified_exec;
pub mod windows_sandbox;
pub use account::resolve_workspace_role_and_owner_for_auth;
pub use account::send_add_credits_nudge_email;
pub use client::X_RESPONSESAPI_INCLUDE_TIMING_METRICS_HEADER;
pub use codex_account::AddCreditsNudgeEmailStatus;
pub use codex_account::SendAddCreditsNudgeEmailError;
pub use codex_account::WorkspaceOwnership;
pub use codex_account::WorkspaceRole;
pub use codex_protocol::config_types::ModelProviderAuthInfo;
mod event_mapping;
pub mod review_format;