Files
codex/codex-rs/core/src/auth_env_telemetry.rs
Michael Bolin aa2403e2eb core: remove cross-crate re-exports from lib.rs (#16512)
## Why

`codex-core` was re-exporting APIs owned by sibling `codex-*` crates,
which made downstream crates depend on `codex-core` as a proxy module
instead of the actual owner crate.

Removing those forwards makes crate boundaries explicit and lets leaf
crates drop unnecessary `codex-core` dependencies. In this PR, this
reduces the dependency on `codex-core` to `codex-login` in the following
files:

```
codex-rs/backend-client/Cargo.toml
codex-rs/mcp-server/tests/common/Cargo.toml
```

## What

- Remove `codex-rs/core/src/lib.rs` re-exports for symbols owned by
`codex-login`, `codex-mcp`, `codex-rollout`, `codex-analytics`,
`codex-protocol`, `codex-shell-command`, `codex-sandboxing`,
`codex-tools`, and `codex-utils-path`.
- Delete the `default_client` forwarding shim in `codex-rs/core`.
- Update in-crate and downstream callsites to import directly from the
owning `codex-*` crate.
- Add direct Cargo dependencies where callsites now target the owner
crate, and remove `codex-core` from `codex-rs/backend-client`.
2026-04-01 23:06:24 -07:00

89 lines
3.2 KiB
Rust

use codex_otel::AuthEnvTelemetryMetadata;
use crate::model_provider_info::ModelProviderInfo;
use codex_login::CODEX_API_KEY_ENV_VAR;
use codex_login::OPENAI_API_KEY_ENV_VAR;
use codex_login::REFRESH_TOKEN_URL_OVERRIDE_ENV_VAR;
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub(crate) struct AuthEnvTelemetry {
pub(crate) openai_api_key_env_present: bool,
pub(crate) codex_api_key_env_present: bool,
pub(crate) codex_api_key_env_enabled: bool,
pub(crate) provider_env_key_name: Option<String>,
pub(crate) provider_env_key_present: Option<bool>,
pub(crate) refresh_token_url_override_present: bool,
}
impl AuthEnvTelemetry {
pub(crate) fn to_otel_metadata(&self) -> AuthEnvTelemetryMetadata {
AuthEnvTelemetryMetadata {
openai_api_key_env_present: self.openai_api_key_env_present,
codex_api_key_env_present: self.codex_api_key_env_present,
codex_api_key_env_enabled: self.codex_api_key_env_enabled,
provider_env_key_name: self.provider_env_key_name.clone(),
provider_env_key_present: self.provider_env_key_present,
refresh_token_url_override_present: self.refresh_token_url_override_present,
}
}
}
pub(crate) fn collect_auth_env_telemetry(
provider: &ModelProviderInfo,
codex_api_key_env_enabled: bool,
) -> AuthEnvTelemetry {
AuthEnvTelemetry {
openai_api_key_env_present: env_var_present(OPENAI_API_KEY_ENV_VAR),
codex_api_key_env_present: env_var_present(CODEX_API_KEY_ENV_VAR),
codex_api_key_env_enabled,
// Custom provider `env_key` is arbitrary config text, so emit only a safe bucket.
provider_env_key_name: provider.env_key.as_ref().map(|_| "configured".to_string()),
provider_env_key_present: provider.env_key.as_deref().map(env_var_present),
refresh_token_url_override_present: env_var_present(REFRESH_TOKEN_URL_OVERRIDE_ENV_VAR),
}
}
fn env_var_present(name: &str) -> bool {
match std::env::var(name) {
Ok(value) => !value.trim().is_empty(),
Err(std::env::VarError::NotUnicode(_)) => true,
Err(std::env::VarError::NotPresent) => false,
}
}
#[cfg(test)]
mod tests {
use super::*;
use pretty_assertions::assert_eq;
#[test]
fn collect_auth_env_telemetry_buckets_provider_env_key_name() {
let provider = ModelProviderInfo {
name: "Custom".to_string(),
base_url: None,
env_key: Some("sk-should-not-leak".to_string()),
env_key_instructions: None,
experimental_bearer_token: None,
auth: None,
wire_api: crate::model_provider_info::WireApi::Responses,
query_params: None,
http_headers: None,
env_http_headers: None,
request_max_retries: None,
stream_max_retries: None,
stream_idle_timeout_ms: None,
websocket_connect_timeout_ms: None,
requires_openai_auth: false,
supports_websockets: false,
};
let telemetry =
collect_auth_env_telemetry(&provider, /*codex_api_key_env_enabled*/ false);
assert_eq!(
telemetry.provider_env_key_name,
Some("configured".to_string())
);
}
}