mirror of
https://github.com/openai/codex.git
synced 2026-10-18 17:18:52 +00:00
Allow Guardian Decisions to fall back to OPENAI_API_KEY (#51133)
## What changed Use `OPENAI_API_KEY` for the Guardian Decisions sampler when `CODEX_GUARDIAN_DECISIONS_API_KEY` is absent, the provider is `openai`, and no custom base URL is configured. Preserve dedicated-key precedence, including empty values, and do not fall back for other providers or custom base URLs. ## Testing Add a credential-selection test covering fallback, dedicated-key precedence, empty dedicated keys, and provider and base URL restrictions. GitOrigin-RevId: a2a62c28789597f013544b51e142b21f9e214080
This commit is contained in:
@@ -23,16 +23,20 @@ pub(super) fn decisions_sampler(
|
||||
use super::decisions::DecisionsSampler;
|
||||
use super::decisions::URL;
|
||||
use codex_http_client::ClientRouteClass;
|
||||
let result = std::env::var("CODEX_GUARDIAN_DECISIONS_API_KEY")
|
||||
.map_err(|_| DecisionsError::Credentials)
|
||||
.and_then(|key| {
|
||||
let client = input
|
||||
.config
|
||||
.http_client_factory()
|
||||
.build_client_without_request_logging(URL, ClientRouteClass::Api)
|
||||
.map_err(|_| DecisionsError::ClientSetup)?;
|
||||
DecisionsSampler::new(client, key, URL.to_owned())
|
||||
});
|
||||
let result = decisions_api_key(
|
||||
&input.config.model_provider_id,
|
||||
input.config.model_provider.base_url.as_deref(),
|
||||
|name| std::env::var(name),
|
||||
)
|
||||
.map_err(|_| DecisionsError::Credentials)
|
||||
.and_then(|key| {
|
||||
let client = input
|
||||
.config
|
||||
.http_client_factory()
|
||||
.build_client_without_request_logging(URL, ClientRouteClass::Api)
|
||||
.map_err(|_| DecisionsError::ClientSetup)?;
|
||||
DecisionsSampler::new(client, key, URL.to_owned())
|
||||
});
|
||||
match result {
|
||||
Ok(sampler) => Some(sampler),
|
||||
Err(error) => {
|
||||
@@ -48,6 +52,19 @@ pub(super) fn decisions_sampler(
|
||||
}
|
||||
}
|
||||
|
||||
fn decisions_api_key(
|
||||
provider_id: &str,
|
||||
base_url: Option<&str>,
|
||||
read_env: impl Fn(&str) -> Result<String, std::env::VarError>,
|
||||
) -> Result<String, std::env::VarError> {
|
||||
read_env("CODEX_GUARDIAN_DECISIONS_API_KEY").or_else(|error| match error {
|
||||
std::env::VarError::NotPresent if provider_id == "openai" && base_url.is_none() => {
|
||||
read_env("OPENAI_API_KEY")
|
||||
}
|
||||
std::env::VarError::NotPresent | std::env::VarError::NotUnicode(_) => Err(error),
|
||||
})
|
||||
}
|
||||
|
||||
pub(super) async fn sampler_config(
|
||||
input: &ThreadStartInput<'_, Config>,
|
||||
auth_manager: Arc<AuthManager>,
|
||||
@@ -100,3 +117,7 @@ pub(super) async fn sampler_config(
|
||||
metrics: input.extension_metrics.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "startup_tests.rs"]
|
||||
mod tests;
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
//! Credential selection honors dedicated keys and restricts ambient-key fallback.
|
||||
|
||||
use super::decisions_api_key;
|
||||
use pretty_assertions::assert_eq;
|
||||
use std::env::VarError;
|
||||
|
||||
#[test]
|
||||
fn decisions_key_fallback_preserves_precedence_and_provider_boundary() {
|
||||
for (provider, base_url, dedicated, expected) in [
|
||||
("openai", None, None, Some("standard")),
|
||||
("openai", None, Some("dedicated"), Some("dedicated")),
|
||||
("openai", None, Some(""), Some("")),
|
||||
("custom", None, None, None),
|
||||
("openai", Some("https://gateway.example/v1"), None, None),
|
||||
("custom", None, Some("dedicated"), Some("dedicated")),
|
||||
] {
|
||||
let result = decisions_api_key(provider, base_url, |name| match name {
|
||||
"CODEX_GUARDIAN_DECISIONS_API_KEY" => {
|
||||
dedicated.map(str::to_owned).ok_or(VarError::NotPresent)
|
||||
}
|
||||
"OPENAI_API_KEY" => {
|
||||
assert_eq!((provider, base_url, dedicated), ("openai", None, None));
|
||||
Ok("standard".into())
|
||||
}
|
||||
_ => panic!("unexpected environment variable: {name}"),
|
||||
});
|
||||
assert_eq!(
|
||||
result,
|
||||
expected.map(str::to_owned).ok_or(VarError::NotPresent)
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user