use std::collections::{BTreeMap, BTreeSet};
use std::path::PathBuf;
use serde::{Deserialize, Serialize};
use thiserror::Error;
use crate::Config;
use crate::auth::{AuthConstraints, AuthMetadataDefaults};
use crate::provider::Provider;
use crate::provider_matrix::{
AnthropicAuthMethod, AnthropicBackendKind, GoogleAuthMethod, GoogleBackendKind,
OpenAiAuthMethod, OpenAiBackendKind, SelfHostedAuthMethod, SelfHostedBackendKind,
};
const AZURE_OPENAI_API_KEY_ENV: &str = "AZURE_OPENAI_API_KEY";
const AZURE_OPENAI_ENDPOINT_ENV: &str = "AZURE_OPENAI_ENDPOINT";
const AZURE_OPENAI_IMAGE_GENERATION_DEPLOYMENT_ENV: &str =
"AZURE_OPENAI_IMAGE_GENERATION_DEPLOYMENT";
const AZURE_OPENAI_IMAGE_DEPLOYMENT_ENV: &str = "AZURE_OPENAI_IMAGE_DEPLOYMENT";
const AZURE_OPENAI_IMAGE_GENERATION_API_VERSION_ENV: &str =
"AZURE_OPENAI_IMAGE_GENERATION_API_VERSION";
#[derive(Debug, Clone, PartialEq, Eq)]
struct EnvDefaultSpec {
backend_kind: &'static str,
auth_method: &'static str,
env_var: &'static str,
fallback: Vec<String>,
base_url: Option<String>,
options: serde_json::Value,
}
#[derive(Debug, Clone, PartialEq, Eq, Error, Serialize, Deserialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub enum IdentityError {
#[error("identity slug is empty")]
Empty,
#[error(
"identity slug contains invalid character {0:?}; must be ASCII alphanumeric or one of '-', '_', '.'"
)]
InvalidChar(char),
}
fn is_false(value: &bool) -> bool {
!*value
}
fn validate_slug(raw: &str) -> Result<(), IdentityError> {
if raw.is_empty() {
return Err(IdentityError::Empty);
}
for ch in raw.chars() {
if !(ch.is_ascii_alphanumeric() || ch == '-' || ch == '_' || ch == '.') {
return Err(IdentityError::InvalidChar(ch));
}
}
Ok(())
}
macro_rules! slug_newtype {
($name:ident, $doc:literal) => {
#[doc = $doc]
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[serde(try_from = "String", into = "String")]
pub struct $name(String);
impl $name {
pub fn parse(raw: impl Into<String>) -> Result<Self, IdentityError> {
let raw = raw.into();
validate_slug(&raw)?;
Ok(Self(raw))
}
#[allow(dead_code)]
pub(crate) fn from_known_valid(raw: &'static str) -> Self {
debug_assert!(
validate_slug(raw).is_ok(),
"from_known_valid called with invalid slug literal: {raw:?}",
);
Self(raw.to_string())
}
pub fn as_str(&self) -> &str {
&self.0
}
}
impl TryFrom<String> for $name {
type Error = IdentityError;
fn try_from(s: String) -> Result<Self, Self::Error> {
Self::parse(s)
}
}
impl From<$name> for String {
fn from(v: $name) -> String {
v.0
}
}
impl std::fmt::Display for $name {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(&self.0)
}
}
};
}
slug_newtype!(RealmId, "Opaque slug identifying a realm.");
slug_newtype!(
BindingId,
"Opaque slug identifying a binding inside a realm."
);
slug_newtype!(
ProfileId,
"Opaque slug identifying an auth profile override on a connection."
);
pub const ENV_DEFAULT_REALM_SLUG: &str = "env_default";
impl RealmId {
#[must_use]
pub fn is_env_default(&self) -> bool {
self.as_str() == ENV_DEFAULT_REALM_SLUG
}
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[serde(rename_all = "snake_case")]
pub enum BindingOrigin {
#[default]
Configured,
SyntheticEnvDefault,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct AuthBindingRef {
pub realm: RealmId,
pub binding: BindingId,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub profile: Option<ProfileId>,
#[serde(default, skip_serializing_if = "BindingOrigin::is_configured")]
pub origin: BindingOrigin,
}
impl BindingOrigin {
pub fn is_configured(&self) -> bool {
matches!(self, BindingOrigin::Configured)
}
}
impl AuthBindingRef {
pub fn is_env_default(&self) -> bool {
matches!(self.origin, BindingOrigin::SyntheticEnvDefault)
}
}
pub fn mob_realm_id(mob_id: &str) -> Result<RealmId, IdentityError> {
RealmId::parse(format!("mob.{mob_id}"))
}
#[derive(Debug, Clone, PartialEq, Eq, Error)]
pub enum MemberCommsNameError {
#[error(
"mob member comms name must have exactly three '/'-separated components (mob_id/role/member)"
)]
WrongComponentCount,
#[error(
"mob member comms name component {component:?} is invalid; \
each must start with an ASCII letter or '_' and contain only ASCII alphanumerics, '-', or '_'"
)]
InvalidComponent { component: String },
}
fn validate_member_comms_name_component(component: &str) -> Result<(), MemberCommsNameError> {
let mut chars = component.chars();
let Some(first) = chars.next() else {
return Err(MemberCommsNameError::InvalidComponent {
component: component.to_string(),
});
};
if !first.is_ascii_alphabetic() && first != '_' {
return Err(MemberCommsNameError::InvalidComponent {
component: component.to_string(),
});
}
if !chars.all(|c| c.is_ascii_alphanumeric() || c == '-' || c == '_') {
return Err(MemberCommsNameError::InvalidComponent {
component: component.to_string(),
});
}
Ok(())
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct MemberCommsName {
mob_id: String,
role: String,
member: String,
}
impl MemberCommsName {
pub fn new(
mob_id: impl Into<String>,
role: impl Into<String>,
member: impl Into<String>,
) -> Result<Self, MemberCommsNameError> {
let mob_id = mob_id.into();
let role = role.into();
let member = member.into();
validate_member_comms_name_component(&mob_id)?;
validate_member_comms_name_component(&role)?;
validate_member_comms_name_component(&member)?;
Ok(Self {
mob_id,
role,
member,
})
}
pub fn mob_id(&self) -> &str {
&self.mob_id
}
pub fn role(&self) -> &str {
&self.role
}
pub fn member(&self) -> &str {
&self.member
}
pub fn to_member_binding(&self) -> MobMemberBinding {
MobMemberBinding {
mob_id: self.mob_id.clone(),
role: self.role.clone(),
member: self.member.clone(),
}
}
}
impl std::fmt::Display for MemberCommsName {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}/{}/{}", self.mob_id, self.role, self.member)
}
}
impl std::str::FromStr for MemberCommsName {
type Err = MemberCommsNameError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut parts = s.split('/');
match (parts.next(), parts.next(), parts.next(), parts.next()) {
(Some(mob_id), Some(role), Some(member), None) => Self::new(mob_id, role, member),
_ => Err(MemberCommsNameError::WrongComponentCount),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum PeerRole {
Member(String),
External,
}
impl PeerRole {
pub fn as_label(&self) -> &str {
match self {
PeerRole::Member(role) => role.as_str(),
PeerRole::External => "external",
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[serde(rename_all = "snake_case")]
pub struct MobMemberBinding {
pub mob_id: String,
pub role: String,
pub member: String,
}
impl MobMemberBinding {
pub fn comms_name(&self) -> Result<MemberCommsName, MemberCommsNameError> {
MemberCommsName::new(self.mob_id.clone(), self.role.clone(), self.member.clone())
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct BackendProfile {
pub id: String,
pub provider: Provider,
pub backend_kind: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub base_url: Option<String>,
#[serde(default, skip_serializing_if = "serde_json::Value::is_null")]
pub options: serde_json::Value,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct AuthProfile {
pub id: String,
pub provider: Provider,
pub auth_method: String,
pub source: CredentialSourceSpec,
#[serde(default)]
pub constraints: AuthConstraints,
#[serde(default)]
pub metadata_defaults: AuthMetadataDefaults,
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[serde(transparent)]
pub struct ExternalResolverId(String);
impl ExternalResolverId {
pub fn new(id: impl Into<String>) -> Self {
Self(id.into())
}
pub fn as_str(&self) -> &str {
&self.0
}
}
impl std::fmt::Display for ExternalResolverId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(&self.0)
}
}
impl From<String> for ExternalResolverId {
fn from(value: String) -> Self {
Self(value)
}
}
impl From<&str> for ExternalResolverId {
fn from(value: &str) -> Self {
Self(value.to_string())
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[serde(tag = "kind", rename_all = "snake_case")]
pub enum CredentialSourceSpec {
InlineSecret {
secret: String,
},
ManagedStore,
Env {
env: String,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
fallback: Vec<String>,
},
ExternalResolver {
handle: ExternalResolverId,
},
PlatformDefault,
Command {
program: PathBuf,
#[serde(default)]
args: Vec<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
cwd: Option<PathBuf>,
#[serde(default)]
env: BTreeMap<String, String>,
#[serde(default = "default_command_timeout_ms")]
timeout_ms: u64,
#[serde(default, skip_serializing_if = "Option::is_none")]
refresh_interval_ms: Option<u64>,
},
FileDescriptor {
fd: i32,
#[serde(default, skip_serializing_if = "Option::is_none")]
scope_override: Option<String>,
},
}
impl CredentialSourceSpec {
pub const ALL_KIND_LABELS: &'static [&'static str] = &[
"inline_secret",
"managed_store",
"env",
"external_resolver",
"platform_default",
"command",
"file_descriptor",
];
pub const fn kind_label(&self) -> &'static str {
match self {
Self::InlineSecret { .. } => "inline_secret",
Self::ManagedStore => "managed_store",
Self::Env { .. } => "env",
Self::ExternalResolver { .. } => "external_resolver",
Self::PlatformDefault => "platform_default",
Self::Command { .. } => "command",
Self::FileDescriptor { .. } => "file_descriptor",
}
}
}
fn default_command_timeout_ms() -> u64 {
30_000
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct BindingPolicy {
#[serde(default)]
pub allow_auth_override: bool,
#[serde(default)]
pub require_metadata_account: bool,
#[serde(default)]
pub require_metadata_workspace: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct ProviderBinding {
pub id: String,
pub backend_profile: String,
pub auth_profile: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub default_model: Option<String>,
#[serde(default)]
pub policy: BindingPolicy,
#[serde(default, skip_serializing_if = "is_false")]
pub provider_default: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct RealmConnectionSet {
pub realm_id: RealmId,
pub backends: BTreeMap<String, BackendProfile>,
pub auth_profiles: BTreeMap<String, AuthProfile>,
pub bindings: BTreeMap<String, ProviderBinding>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub default_binding: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ResolvedConnectionTarget {
pub realm: RealmConnectionSet,
pub auth_binding: AuthBindingRef,
pub binding: ProviderBinding,
pub backend: BackendProfile,
pub auth_profile: AuthProfile,
}
#[derive(Debug, Clone, Error, PartialEq, Eq)]
pub enum ConnectionTargetError {
#[error("connection target did not name a realm and no configured default realm was available")]
MissingRealm,
#[error("realm '{0}' not found in config.realm")]
UnknownRealm(String),
#[error("realm '{realm}' has no default binding")]
MissingDefaultBinding { realm: String },
#[error("invalid realm id '{realm}': {source}")]
InvalidRealmId {
realm: String,
source: IdentityError,
},
#[error("invalid binding id '{binding}': {source}")]
InvalidBindingId {
binding: String,
source: IdentityError,
},
#[error("realm '{realm}' config invalid: {source}")]
RealmConfigInvalid {
realm: String,
source: ProviderBindingError,
},
#[error("binding '{realm}:{binding}' is invalid: {source}")]
BindingInvalid {
realm: String,
binding: String,
source: ProviderBindingError,
},
#[error(
"binding '{realm}:{binding}' resolves backend={backend:?} auth={auth:?}, expected provider {expected:?}"
)]
ProviderMismatch {
realm: String,
binding: String,
expected: Provider,
backend: Provider,
auth: Provider,
},
}
pub fn resolve_realm_binding_target_for_provider(
config: &Config,
provider: Provider,
explicit_realm: Option<&RealmId>,
explicit_binding: Option<&BindingId>,
explicit_profile: Option<&ProfileId>,
preferred_realm: Option<&RealmId>,
allow_env_default: bool,
) -> Result<ResolvedConnectionTarget, ConnectionTargetError> {
let mut candidates: Vec<&str> = Vec::new();
if let Some(realm) = explicit_realm {
candidates.push(realm.as_str());
} else {
if let Some(realm) = preferred_realm {
candidates.push(realm.as_str());
}
if !candidates.contains(&"default") {
candidates.push("default");
}
}
let mut missing_default: Option<String> = None;
for realm_id in candidates {
let Some(section) = config.realm.get(realm_id) else {
if explicit_realm.is_some() {
return Err(ConnectionTargetError::UnknownRealm(realm_id.to_string()));
}
continue;
};
let realm = RealmConnectionSet::from_config(realm_id, section).map_err(|source| {
ConnectionTargetError::RealmConfigInvalid {
realm: realm_id.to_string(),
source,
}
})?;
let binding_id = match explicit_binding {
Some(binding) => binding.clone(),
None => {
let Some(default_binding) = realm.default_binding.as_deref() else {
missing_default = Some(realm_id.to_string());
if explicit_realm.is_some() {
return Err(ConnectionTargetError::MissingDefaultBinding {
realm: realm_id.to_string(),
});
}
continue;
};
BindingId::parse(default_binding).map_err(|source| {
ConnectionTargetError::InvalidBindingId {
binding: default_binding.to_string(),
source,
}
})?
}
};
return materialize_connection_target(
realm,
provider,
binding_id,
explicit_profile.cloned(),
BindingOrigin::Configured,
);
}
if allow_env_default && explicit_realm.is_none() && explicit_binding.is_none() {
let realm = RealmConnectionSet::synthesize_env_default(provider);
let binding = BindingId::parse("default").map_err(|source| {
ConnectionTargetError::InvalidBindingId {
binding: "default".to_string(),
source,
}
})?;
return materialize_connection_target(
realm,
provider,
binding,
explicit_profile.cloned(),
BindingOrigin::SyntheticEnvDefault,
);
}
if let Some(realm) = missing_default {
return Err(ConnectionTargetError::MissingDefaultBinding { realm });
}
Err(ConnectionTargetError::MissingRealm)
}
pub fn resolve_auth_binding_or_default_for_provider(
config: &Config,
provider: Provider,
auth_binding: Option<&AuthBindingRef>,
preferred_realm: Option<&RealmId>,
allow_env_default: bool,
) -> Result<ResolvedConnectionTarget, ConnectionTargetError> {
if let Some(auth_binding) = auth_binding {
let realm_id = auth_binding.realm.as_str();
if auth_binding.is_env_default() {
return Err(ConnectionTargetError::UnknownRealm(realm_id.to_string()));
}
let section = config
.realm
.get(realm_id)
.ok_or_else(|| ConnectionTargetError::UnknownRealm(realm_id.to_string()))?;
let realm = RealmConnectionSet::from_config(realm_id, section).map_err(|source| {
ConnectionTargetError::RealmConfigInvalid {
realm: realm_id.to_string(),
source,
}
})?;
return materialize_connection_target(
realm,
provider,
auth_binding.binding.clone(),
auth_binding.profile.clone(),
BindingOrigin::Configured,
);
}
resolve_realm_binding_target_for_provider(
config,
provider,
None,
None,
None,
preferred_realm,
allow_env_default,
)
}
fn selected_binding_id_for_provider(
realm: &RealmConnectionSet,
provider: Provider,
) -> Result<Option<BindingId>, ConnectionTargetError> {
let mut provider_bindings = Vec::new();
let mut provider_default_binding: Option<&str> = None;
for (binding_id, binding) in &realm.bindings {
let backend = realm
.backends
.get(&binding.backend_profile)
.ok_or_else(|| ConnectionTargetError::BindingInvalid {
realm: realm.realm_id.to_string(),
binding: binding_id.clone(),
source: ProviderBindingError::UnknownBackend(binding.backend_profile.clone()),
})?;
let auth = realm
.auth_profiles
.get(&binding.auth_profile)
.ok_or_else(|| ConnectionTargetError::BindingInvalid {
realm: realm.realm_id.to_string(),
binding: binding_id.clone(),
source: ProviderBindingError::UnknownAuth(binding.auth_profile.clone()),
})?;
if backend.provider == provider && auth.provider == provider {
provider_bindings.push(binding_id.as_str());
if binding.provider_default && provider_default_binding.is_none() {
provider_default_binding = Some(binding_id.as_str());
}
}
}
if let Some(default_binding) = realm.default_binding.as_deref()
&& provider_bindings.contains(&default_binding)
{
return BindingId::parse(default_binding.to_string())
.map(Some)
.map_err(|source| ConnectionTargetError::InvalidBindingId {
binding: default_binding.to_string(),
source,
});
}
if let Some(provider_default_binding) = provider_default_binding {
return BindingId::parse(provider_default_binding.to_string())
.map(Some)
.map_err(|source| ConnectionTargetError::InvalidBindingId {
binding: provider_default_binding.to_string(),
source,
});
}
match provider_bindings.as_slice() {
[binding_id] => BindingId::parse((*binding_id).to_string())
.map(Some)
.map_err(|source| ConnectionTargetError::InvalidBindingId {
binding: (*binding_id).to_string(),
source,
}),
_ => Ok(None),
}
}
fn push_candidate_realm_ids<'a>(
ids: &mut Vec<&'a str>,
seen: &mut BTreeSet<&'a str>,
id: Option<&'a str>,
) {
if let Some(id) = id
&& seen.insert(id)
{
ids.push(id);
}
}
pub fn resolve_auth_binding_candidates_for_provider(
config: &Config,
provider: Provider,
auth_binding: Option<&AuthBindingRef>,
preferred_realm: Option<&RealmId>,
allow_env_default: bool,
) -> Result<Vec<ResolvedConnectionTarget>, ConnectionTargetError> {
if auth_binding.is_some() {
return resolve_auth_binding_or_default_for_provider(
config,
provider,
auth_binding,
preferred_realm,
allow_env_default,
)
.map(|target| vec![target]);
}
let mut realm_ids = Vec::new();
let mut seen = BTreeSet::new();
push_candidate_realm_ids(
&mut realm_ids,
&mut seen,
preferred_realm.map(RealmId::as_str),
);
push_candidate_realm_ids(&mut realm_ids, &mut seen, Some("default"));
for realm_id in config.realm.keys() {
push_candidate_realm_ids(&mut realm_ids, &mut seen, Some(realm_id.as_str()));
}
let mut candidates = Vec::new();
let mut missing_default: Option<String> = None;
for realm_id in realm_ids {
let Some(section) = config.realm.get(realm_id) else {
if preferred_realm.is_some_and(|preferred| preferred.as_str() == realm_id) {
missing_default.get_or_insert_with(|| realm_id.to_string());
}
continue;
};
let realm = RealmConnectionSet::from_config(realm_id, section).map_err(|source| {
ConnectionTargetError::RealmConfigInvalid {
realm: realm_id.to_string(),
source,
}
})?;
if let Some(binding_id) = selected_binding_id_for_provider(&realm, provider)? {
candidates.push(materialize_connection_target(
realm,
provider,
binding_id,
None,
BindingOrigin::Configured,
)?);
}
}
if allow_env_default {
let realm = RealmConnectionSet::synthesize_env_default(provider);
let binding = BindingId::parse("default").map_err(|source| {
ConnectionTargetError::InvalidBindingId {
binding: "default".to_string(),
source,
}
})?;
candidates.push(materialize_connection_target(
realm,
provider,
binding,
None,
BindingOrigin::SyntheticEnvDefault,
)?);
}
if !candidates.is_empty() {
return Ok(candidates);
}
if let Some(realm) = missing_default {
return Err(ConnectionTargetError::MissingDefaultBinding { realm });
}
Err(ConnectionTargetError::MissingRealm)
}
fn materialize_connection_target(
realm: RealmConnectionSet,
provider: Provider,
binding: BindingId,
profile: Option<ProfileId>,
origin: BindingOrigin,
) -> Result<ResolvedConnectionTarget, ConnectionTargetError> {
let auth_binding = AuthBindingRef {
realm: realm.realm_id.clone(),
binding,
profile,
origin,
};
let (binding, backend, auth_profile) =
realm.lookup_auth_binding(&auth_binding).map_err(|source| {
ConnectionTargetError::BindingInvalid {
realm: auth_binding.realm.to_string(),
binding: auth_binding.binding.to_string(),
source,
}
})?;
if backend.provider != provider || auth_profile.provider != provider {
return Err(ConnectionTargetError::ProviderMismatch {
realm: auth_binding.realm.to_string(),
binding: auth_binding.binding.to_string(),
expected: provider,
backend: backend.provider,
auth: auth_profile.provider,
});
}
let binding = binding.clone();
let backend = backend.clone();
let auth_profile = auth_profile.clone();
Ok(ResolvedConnectionTarget {
realm,
auth_binding,
binding,
backend,
auth_profile,
})
}
impl RealmConnectionSet {
pub fn from_config(
realm_id: &str,
section: &RealmConfigSection,
) -> Result<Self, ProviderBindingError> {
let realm_id =
RealmId::parse(realm_id).map_err(|source| ProviderBindingError::InvalidRealmId {
realm: realm_id.to_string(),
source,
})?;
let mut backends: BTreeMap<String, BackendProfile> = BTreeMap::new();
for (id, cfg) in §ion.backend {
let provider = Provider::parse_strict(&cfg.provider)
.ok_or_else(|| ProviderBindingError::UnknownProviderName(cfg.provider.clone()))?;
let backend = BackendProfile {
id: id.clone(),
provider,
backend_kind: cfg.backend_kind.clone(),
base_url: cfg.base_url.clone(),
options: cfg.options.clone(),
};
backends.insert(id.clone(), backend);
}
let mut auth_profiles: BTreeMap<String, AuthProfile> = BTreeMap::new();
for (id, cfg) in §ion.auth {
let provider = Provider::parse_strict(&cfg.provider)
.ok_or_else(|| ProviderBindingError::UnknownProviderName(cfg.provider.clone()))?;
let profile = AuthProfile {
id: id.clone(),
provider,
auth_method: cfg.auth_method.clone(),
source: cfg.source.clone(),
constraints: cfg.constraints.clone(),
metadata_defaults: cfg.metadata_defaults.clone(),
};
auth_profiles.insert(id.clone(), profile);
}
let mut bindings: BTreeMap<String, ProviderBinding> = BTreeMap::new();
for (id, cfg) in §ion.binding {
let backend = backends
.get(&cfg.backend_profile)
.ok_or_else(|| ProviderBindingError::UnknownBackend(cfg.backend_profile.clone()))?;
let auth = auth_profiles
.get(&cfg.auth_profile)
.ok_or_else(|| ProviderBindingError::UnknownAuth(cfg.auth_profile.clone()))?;
if backend.provider != auth.provider {
return Err(ProviderBindingError::ProviderMismatch {
binding: id.clone(),
backend: backend.provider,
auth: auth.provider,
});
}
let binding = ProviderBinding {
id: id.clone(),
backend_profile: cfg.backend_profile.clone(),
auth_profile: cfg.auth_profile.clone(),
default_model: cfg.default_model.clone(),
policy: cfg.policy.clone(),
provider_default: cfg.provider_default,
};
bindings.insert(id.clone(), binding);
}
Ok(Self {
realm_id,
backends,
auth_profiles,
bindings,
default_binding: section.default_binding.clone(),
})
}
pub fn synthesize_env_default(provider: Provider) -> Self {
Self::synthesize_env_default_from_lookup(provider, |key| std::env::var(key).ok())
}
pub fn synthesize_env_default_from_lookup<F>(provider: Provider, env_lookup: F) -> Self
where
F: Fn(&str) -> Option<String>,
{
let spec = env_default_spec(provider, env_lookup);
Self::synthesize_default_from_spec(provider, spec)
}
fn synthesize_default_from_spec(provider: Provider, spec: EnvDefaultSpec) -> Self {
let backend = BackendProfile {
id: "default".to_string(),
provider,
backend_kind: spec.backend_kind.to_string(),
base_url: spec.base_url,
options: spec.options,
};
let source = CredentialSourceSpec::Env {
env: spec.env_var.to_string(),
fallback: spec.fallback,
};
let auth = AuthProfile {
id: "default".to_string(),
provider,
auth_method: spec.auth_method.to_string(),
source,
constraints: AuthConstraints::default(),
metadata_defaults: AuthMetadataDefaults::default(),
};
let binding = ProviderBinding {
id: "default".to_string(),
backend_profile: "default".to_string(),
auth_profile: "default".to_string(),
default_model: None,
policy: BindingPolicy::default(),
provider_default: true,
};
let mut backends = BTreeMap::new();
backends.insert("default".to_string(), backend);
let mut auth_profiles = BTreeMap::new();
auth_profiles.insert("default".to_string(), auth);
let mut bindings = BTreeMap::new();
bindings.insert("default".to_string(), binding);
Self {
realm_id: RealmId::from_known_valid(ENV_DEFAULT_REALM_SLUG),
backends,
auth_profiles,
bindings,
default_binding: Some("default".to_string()),
}
}
pub fn lookup_binding(
&self,
id: &str,
) -> Result<(&ProviderBinding, &BackendProfile, &AuthProfile), ProviderBindingError> {
let binding = self
.bindings
.get(id)
.ok_or_else(|| ProviderBindingError::UnknownBinding(id.to_string()))?;
let backend = self
.backends
.get(&binding.backend_profile)
.ok_or_else(|| ProviderBindingError::UnknownBackend(binding.backend_profile.clone()))?;
let auth = self
.auth_profiles
.get(&binding.auth_profile)
.ok_or_else(|| ProviderBindingError::UnknownAuth(binding.auth_profile.clone()))?;
Ok((binding, backend, auth))
}
pub fn lookup_auth_binding(
&self,
auth_binding: &AuthBindingRef,
) -> Result<(&ProviderBinding, &BackendProfile, &AuthProfile), ProviderBindingError> {
let binding = self
.bindings
.get(auth_binding.binding.as_str())
.ok_or_else(|| {
ProviderBindingError::UnknownBinding(auth_binding.binding.to_string())
})?;
let backend = self
.backends
.get(&binding.backend_profile)
.ok_or_else(|| ProviderBindingError::UnknownBackend(binding.backend_profile.clone()))?;
let auth_profile_id = auth_binding
.profile
.as_ref()
.map(ProfileId::as_str)
.unwrap_or(binding.auth_profile.as_str());
let auth = self
.auth_profiles
.get(auth_profile_id)
.ok_or_else(|| ProviderBindingError::UnknownAuth(auth_profile_id.to_string()))?;
Ok((binding, backend, auth))
}
}
#[derive(Debug, Clone, Error, Serialize, Deserialize, PartialEq, Eq)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[serde(tag = "kind", rename_all = "snake_case")]
pub enum ProviderBindingError {
#[error("unknown binding: {0}")]
UnknownBinding(String),
#[error("unknown backend: {0}")]
UnknownBackend(String),
#[error("unknown auth: {0}")]
UnknownAuth(String),
#[error("provider mismatch on binding {binding}: backend={backend:?} auth={auth:?}")]
ProviderMismatch {
binding: String,
backend: Provider,
auth: Provider,
},
#[error("unknown provider name: {0}")]
UnknownProviderName(String),
#[error("invalid realm id '{realm}': {source}")]
InvalidRealmId {
realm: String,
source: IdentityError,
},
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct RealmConfigSection {
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub backend: BTreeMap<String, BackendProfileConfig>,
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub auth: BTreeMap<String, AuthProfileConfig>,
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub binding: BTreeMap<String, ProviderBindingConfig>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub default_binding: Option<String>,
}
impl RealmConfigSection {
pub fn from_inline_api_keys(entries: &[(&str, &str)]) -> Self {
let mut backend = BTreeMap::new();
let mut auth = BTreeMap::new();
let mut binding = BTreeMap::new();
let mut default_binding: Option<String> = None;
for (idx, (provider, secret)) in entries.iter().enumerate() {
let id = format!("default_{provider}");
let (backend_kind, auth_method) = match *provider {
"anthropic" => (
AnthropicBackendKind::AnthropicApi.as_str(),
AnthropicAuthMethod::ApiKey.as_str(),
),
"openai" => (
OpenAiBackendKind::OpenAiApi.as_str(),
OpenAiAuthMethod::ApiKey.as_str(),
),
"gemini" | "google" => (
GoogleBackendKind::GoogleGenAi.as_str(),
GoogleAuthMethod::ApiKey.as_str(),
),
other => (other, "api_key"),
};
backend.insert(
id.clone(),
BackendProfileConfig {
provider: provider.to_string(),
backend_kind: backend_kind.to_string(),
base_url: None,
options: serde_json::Value::Null,
},
);
auth.insert(
id.clone(),
AuthProfileConfig {
provider: provider.to_string(),
auth_method: auth_method.to_string(),
source: CredentialSourceSpec::InlineSecret {
secret: (*secret).to_string(),
},
constraints: AuthConstraints::default(),
metadata_defaults: AuthMetadataDefaults::default(),
},
);
binding.insert(
id.clone(),
ProviderBindingConfig {
backend_profile: id.clone(),
auth_profile: id.clone(),
default_model: None,
policy: BindingPolicy::default(),
provider_default: true,
},
);
if idx == 0 {
default_binding = Some(id);
}
}
Self {
backend,
auth,
binding,
default_binding,
}
}
}
fn env_default_spec<F>(provider: Provider, env_lookup: F) -> EnvDefaultSpec
where
F: Fn(&str) -> Option<String>,
{
match provider {
Provider::Anthropic => EnvDefaultSpec {
backend_kind: AnthropicBackendKind::AnthropicApi.as_str(),
auth_method: AnthropicAuthMethod::ApiKey.as_str(),
env_var: "ANTHROPIC_API_KEY",
fallback: vec![],
base_url: None,
options: serde_json::Value::Null,
},
Provider::OpenAI => openai_env_default_spec(env_lookup),
Provider::Gemini => EnvDefaultSpec {
backend_kind: GoogleBackendKind::GoogleGenAi.as_str(),
auth_method: GoogleAuthMethod::ApiKey.as_str(),
env_var: "GEMINI_API_KEY",
fallback: vec!["GOOGLE_API_KEY".to_string()],
base_url: None,
options: serde_json::Value::Null,
},
Provider::SelfHosted => EnvDefaultSpec {
backend_kind: SelfHostedBackendKind::SelfHosted.as_str(),
auth_method: SelfHostedAuthMethod::ApiKey.as_str(),
env_var: "RKAT_SELF_HOSTED_API_KEY",
fallback: vec![],
base_url: None,
options: serde_json::Value::Null,
},
Provider::Other => EnvDefaultSpec {
backend_kind: "other_api",
auth_method: "api_key",
env_var: "RKAT_OTHER_API_KEY",
fallback: vec![],
base_url: None,
options: serde_json::Value::Null,
},
}
}
fn openai_env_default_spec<F>(env_lookup: F) -> EnvDefaultSpec
where
F: Fn(&str) -> Option<String>,
{
let public_openai_key = env_value_with_rkat(&env_lookup, "OPENAI_API_KEY");
let azure_key = env_value_with_rkat(&env_lookup, AZURE_OPENAI_API_KEY_ENV);
let azure_endpoint = env_value_with_rkat(&env_lookup, AZURE_OPENAI_ENDPOINT_ENV);
let azure_explicit = direct_env_value(&env_lookup, &format!("RKAT_{AZURE_OPENAI_API_KEY_ENV}"))
.is_some()
|| direct_env_value(&env_lookup, &format!("RKAT_{AZURE_OPENAI_ENDPOINT_ENV}")).is_some();
if azure_key.is_some()
&& let Some(endpoint) = azure_endpoint
&& (azure_explicit || public_openai_key.is_none())
{
let mut options = serde_json::Map::new();
if let Some(deployment) =
env_value_with_rkat(&env_lookup, AZURE_OPENAI_IMAGE_GENERATION_DEPLOYMENT_ENV)
.or_else(|| env_value_with_rkat(&env_lookup, AZURE_OPENAI_IMAGE_DEPLOYMENT_ENV))
{
options.insert(
"image_generation_deployment".to_string(),
serde_json::Value::String(deployment),
);
}
if let Some(api_version) =
env_value_with_rkat(&env_lookup, AZURE_OPENAI_IMAGE_GENERATION_API_VERSION_ENV)
{
options.insert(
"image_generation_api_version".to_string(),
serde_json::Value::String(api_version),
);
}
return EnvDefaultSpec {
backend_kind: OpenAiBackendKind::AzureOpenAi.as_str(),
auth_method: OpenAiAuthMethod::AzureApiKey.as_str(),
env_var: AZURE_OPENAI_API_KEY_ENV,
fallback: vec![],
base_url: Some(endpoint),
options: if options.is_empty() {
serde_json::Value::Null
} else {
serde_json::Value::Object(options)
},
};
}
EnvDefaultSpec {
backend_kind: OpenAiBackendKind::OpenAiApi.as_str(),
auth_method: OpenAiAuthMethod::ApiKey.as_str(),
env_var: "OPENAI_API_KEY",
fallback: vec![],
base_url: None,
options: serde_json::Value::Null,
}
}
fn env_value_with_rkat<F>(env_lookup: &F, candidate: &str) -> Option<String>
where
F: Fn(&str) -> Option<String>,
{
let rkat_override = if candidate.starts_with("RKAT_") {
None
} else {
direct_env_value(env_lookup, &format!("RKAT_{candidate}"))
};
rkat_override.or_else(|| direct_env_value(env_lookup, candidate))
}
fn direct_env_value<F>(env_lookup: &F, key: &str) -> Option<String>
where
F: Fn(&str) -> Option<String>,
{
env_lookup(key)
.map(|value| value.trim().to_string())
.filter(|value| !value.is_empty())
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct BackendProfileConfig {
pub provider: String,
pub backend_kind: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub base_url: Option<String>,
#[serde(default, skip_serializing_if = "serde_json::Value::is_null")]
pub options: serde_json::Value,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct AuthProfileConfig {
pub provider: String,
pub auth_method: String,
pub source: CredentialSourceSpec,
#[serde(default)]
pub constraints: AuthConstraints,
#[serde(default)]
pub metadata_defaults: AuthMetadataDefaults,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct ProviderBindingConfig {
pub backend_profile: String,
pub auth_profile: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub default_model: Option<String>,
#[serde(default)]
pub policy: BindingPolicy,
#[serde(default, skip_serializing_if = "is_false")]
pub provider_default: bool,
}
#[cfg(test)]
#[allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)]
mod tests {
use super::*;
use std::str::FromStr;
#[test]
fn member_comms_name_round_trips_through_display_and_from_str() {
let name = MemberCommsName::new("team", "reviewer", "alice").unwrap();
assert_eq!(name.to_string(), "team/reviewer/alice");
let parsed = MemberCommsName::from_str("team/reviewer/alice").unwrap();
assert_eq!(parsed, name);
assert_eq!(parsed.mob_id(), "team");
assert_eq!(parsed.role(), "reviewer");
assert_eq!(parsed.member(), "alice");
}
#[test]
fn member_comms_name_from_str_is_fail_closed() {
assert!(matches!(
MemberCommsName::from_str("team/reviewer"),
Err(MemberCommsNameError::WrongComponentCount)
));
assert!(matches!(
MemberCommsName::from_str("team/reviewer/alice/extra"),
Err(MemberCommsNameError::WrongComponentCount)
));
assert!(matches!(
MemberCommsName::from_str("team//alice"),
Err(MemberCommsNameError::InvalidComponent { .. })
));
assert!(MemberCommsName::from_str("1team/reviewer/alice").is_err());
assert!(MemberCommsName::from_str("te.am/reviewer/alice").is_err());
assert!(MemberCommsName::from_str("_team/reviewer/alice").is_ok());
}
#[test]
fn member_comms_name_components_are_always_valid_realm_slugs() {
let name = MemberCommsName::new("team", "reviewer", "alice").unwrap();
assert!(mob_realm_id(name.mob_id()).is_ok());
assert_eq!(mob_realm_id("team").unwrap().as_str(), "mob.team");
}
#[test]
fn mob_member_binding_round_trips_to_comms_name() {
let binding = MobMemberBinding {
mob_id: "team".to_string(),
role: "reviewer".to_string(),
member: "alice".to_string(),
};
assert_eq!(
binding.comms_name().unwrap().to_string(),
"team/reviewer/alice"
);
}
#[test]
fn peer_role_external_label_is_typed_not_magic_string() {
assert_eq!(PeerRole::External.as_label(), "external");
assert_eq!(
PeerRole::Member("reviewer".to_string()).as_label(),
"reviewer"
);
}
fn config_with_realms(toml_input: &str) -> Config {
Config {
realm: toml::from_str(toml_input).unwrap(),
..Default::default()
}
}
fn openai_target_config() -> Config {
config_with_realms(
r#"
[prod]
default_binding = "primary"
[prod.backend.openai_default]
provider = "openai"
backend_kind = "openai_api"
[prod.auth.openai_oauth]
provider = "openai"
auth_method = "chatgpt_oauth"
source = { kind = "platform_default" }
[prod.binding.primary]
backend_profile = "openai_default"
auth_profile = "openai_oauth"
[prod.binding.secondary]
backend_profile = "openai_default"
auth_profile = "openai_oauth"
"#,
)
}
fn lookup_from_pairs(
pairs: &'static [(&'static str, &'static str)],
) -> impl Fn(&str) -> Option<String> {
move |key| {
pairs
.iter()
.find_map(|(candidate, value)| (*candidate == key).then(|| (*value).to_string()))
}
}
#[test]
fn auth_binding_is_purely_structural() {
let c = AuthBindingRef {
realm: RealmId::parse("dev").unwrap(),
binding: BindingId::parse("default_openai").unwrap(),
profile: None,
origin: BindingOrigin::Configured,
};
assert_eq!(c.realm.as_str(), "dev");
assert_eq!(c.binding.as_str(), "default_openai");
assert!(c.profile.is_none());
assert!(!c.is_env_default());
}
#[test]
fn auth_binding_serde_roundtrip_with_profile() {
let c = AuthBindingRef {
realm: RealmId::parse("prod").unwrap(),
binding: BindingId::parse("gpt5").unwrap(),
profile: Some(ProfileId::parse("override").unwrap()),
origin: BindingOrigin::Configured,
};
let s = serde_json::to_string(&c).unwrap();
assert!(s.contains("\"realm\":\"prod\""));
assert!(s.contains("\"binding\":\"gpt5\""));
assert!(s.contains("\"profile\":\"override\""));
assert!(!s.contains("origin"));
let back: AuthBindingRef = serde_json::from_str(&s).unwrap();
assert_eq!(back, c);
}
#[test]
fn auth_binding_origin_is_typed_not_slug() {
let synthetic = AuthBindingRef {
realm: RealmId::parse("env_default").unwrap(),
binding: BindingId::parse("default").unwrap(),
profile: None,
origin: BindingOrigin::SyntheticEnvDefault,
};
assert!(synthetic.is_env_default());
let configured = AuthBindingRef {
realm: RealmId::parse("env_default").unwrap(),
binding: BindingId::parse("default").unwrap(),
profile: None,
origin: BindingOrigin::Configured,
};
assert!(!configured.is_env_default());
let s = serde_json::to_string(&synthetic).unwrap();
assert!(s.contains("\"origin\":\"synthetic_env_default\""));
let back: AuthBindingRef = serde_json::from_str(&s).unwrap();
assert_eq!(back, synthetic);
let legacy = r#"{"realm":"env_default","binding":"default"}"#;
let back: AuthBindingRef = serde_json::from_str(legacy).unwrap();
assert_eq!(back.origin, BindingOrigin::Configured);
assert!(!back.is_env_default());
}
#[test]
fn auth_binding_profile_overrides_binding_auth_profile() {
let toml = r#"
realm_id = "prod"
default_binding = "primary"
[backend.openai_default]
provider = "openai"
backend_kind = "openai_api"
base_url = "https://api.openai.com/v1"
[auth.default_profile]
provider = "openai"
auth_method = "api_key"
source = { kind = "env", env = "OPENAI_API_KEY" }
[auth.override_profile]
provider = "openai"
auth_method = "api_key"
source = { kind = "env", env = "OVERRIDE_OPENAI_API_KEY" }
[binding.primary]
backend_profile = "openai_default"
auth_profile = "default_profile"
"#;
let section: RealmConfigSection = toml::from_str(toml).unwrap();
let realm = RealmConnectionSet::from_config("prod", §ion).unwrap();
let auth_binding = AuthBindingRef {
realm: RealmId::parse("prod").unwrap(),
binding: BindingId::parse("primary").unwrap(),
profile: Some(ProfileId::parse("override_profile").unwrap()),
origin: BindingOrigin::Configured,
};
let (_binding, _backend, auth) = realm.lookup_auth_binding(&auth_binding).unwrap();
assert_eq!(auth.id, "override_profile");
}
#[test]
fn identity_slugs_reject_invalid_characters() {
assert!(RealmId::parse("").is_err());
assert!(BindingId::parse("bad space").is_err());
assert!(ProfileId::parse("bad:colon").is_err());
assert!(RealmId::parse("dev").is_ok());
assert!(BindingId::parse("openai_default.v1").is_ok());
}
#[test]
fn credential_source_spec_serde() {
for src in [
CredentialSourceSpec::InlineSecret {
secret: "sk-x".into(),
},
CredentialSourceSpec::ManagedStore,
CredentialSourceSpec::Env {
env: "OPENAI_API_KEY".into(),
fallback: Vec::new(),
},
CredentialSourceSpec::ExternalResolver {
handle: "desktop".into(),
},
CredentialSourceSpec::PlatformDefault,
] {
let s = serde_json::to_string(&src).unwrap();
let back: CredentialSourceSpec = serde_json::from_str(&s).unwrap();
assert_eq!(back, src);
}
}
#[test]
fn credential_source_spec_rejects_unknown_kind() {
let bad = r#"{"kind":"nonexistent","foo":"bar"}"#;
let err = serde_json::from_str::<CredentialSourceSpec>(bad).unwrap_err();
assert!(
err.to_string().contains("nonexistent") || err.to_string().contains("unknown variant"),
"serde error should mention unknown variant: {err}",
);
}
#[test]
fn env_default_openai_uses_public_openai_without_azure_envelope() {
let realm = RealmConnectionSet::synthesize_env_default_from_lookup(
Provider::OpenAI,
lookup_from_pairs(&[]),
);
let backend = realm.backends.get("default").unwrap();
let auth = realm.auth_profiles.get("default").unwrap();
assert_eq!(backend.backend_kind, "openai_api");
assert_eq!(backend.base_url, None);
assert_eq!(auth.auth_method, "api_key");
assert_eq!(
auth.source,
CredentialSourceSpec::Env {
env: "OPENAI_API_KEY".to_string(),
fallback: Vec::new(),
}
);
}
#[test]
fn env_default_openai_uses_azure_when_key_and_endpoint_are_present() {
let realm = RealmConnectionSet::synthesize_env_default_from_lookup(
Provider::OpenAI,
lookup_from_pairs(&[
("AZURE_OPENAI_API_KEY", "azure-key"),
("AZURE_OPENAI_ENDPOINT", "https://example.openai.azure.com/"),
(
"AZURE_OPENAI_IMAGE_GENERATION_DEPLOYMENT",
"image-deployment-a",
),
("AZURE_OPENAI_IMAGE_GENERATION_API_VERSION", "preview"),
]),
);
let backend = realm.backends.get("default").unwrap();
let auth = realm.auth_profiles.get("default").unwrap();
assert_eq!(backend.backend_kind, "azure_openai");
assert_eq!(
backend.base_url.as_deref(),
Some("https://example.openai.azure.com/")
);
assert_eq!(
backend.options["image_generation_deployment"],
"image-deployment-a"
);
assert_eq!(backend.options["image_generation_api_version"], "preview");
assert_eq!(auth.auth_method, "azure_api_key");
assert_eq!(
auth.source,
CredentialSourceSpec::Env {
env: "AZURE_OPENAI_API_KEY".to_string(),
fallback: Vec::new(),
}
);
}
#[test]
fn env_default_openai_keeps_public_key_when_plain_azure_and_public_keys_are_both_set() {
let realm = RealmConnectionSet::synthesize_env_default_from_lookup(
Provider::OpenAI,
lookup_from_pairs(&[
("OPENAI_API_KEY", "public-key"),
("AZURE_OPENAI_API_KEY", "azure-key"),
("AZURE_OPENAI_ENDPOINT", "https://example.openai.azure.com"),
]),
);
let backend = realm.backends.get("default").unwrap();
assert_eq!(backend.backend_kind, "openai_api");
assert_eq!(backend.base_url, None);
}
#[test]
fn env_default_openai_rkat_azure_envelope_overrides_public_openai_key() {
let realm = RealmConnectionSet::synthesize_env_default_from_lookup(
Provider::OpenAI,
lookup_from_pairs(&[
("OPENAI_API_KEY", "public-key"),
("RKAT_AZURE_OPENAI_API_KEY", "azure-key"),
(
"RKAT_AZURE_OPENAI_ENDPOINT",
"https://example.openai.azure.com",
),
]),
);
let backend = realm.backends.get("default").unwrap();
let auth = realm.auth_profiles.get("default").unwrap();
assert_eq!(backend.backend_kind, "azure_openai");
assert_eq!(
backend.base_url.as_deref(),
Some("https://example.openai.azure.com")
);
assert_eq!(auth.auth_method, "azure_api_key");
}
#[test]
fn from_config_empty_section_yields_empty_set() {
let section = RealmConfigSection::default();
let set = RealmConnectionSet::from_config("dev", §ion).expect("empty section is valid");
assert_eq!(set.realm_id.as_str(), "dev");
assert!(set.backends.is_empty());
assert!(set.auth_profiles.is_empty());
assert!(set.bindings.is_empty());
assert_eq!(set.default_binding, None);
}
#[test]
fn lookup_binding_returns_unknown_binding() {
let set = RealmConnectionSet::from_config("dev", &RealmConfigSection::default())
.expect("empty section valid");
let err = set
.lookup_binding("missing")
.expect_err("empty set has no bindings");
assert_eq!(err, ProviderBindingError::UnknownBinding("missing".into()));
}
#[test]
fn connection_target_uses_configured_realm_default_binding() {
let config = openai_target_config();
let preferred_realm = RealmId::parse("prod").unwrap();
let target = resolve_realm_binding_target_for_provider(
&config,
Provider::OpenAI,
None,
None,
None,
Some(&preferred_realm),
false,
)
.unwrap();
assert_eq!(target.auth_binding.realm.as_str(), "prod");
assert_eq!(target.auth_binding.binding.as_str(), "primary");
assert_eq!(target.binding.id, "primary");
}
#[test]
fn connection_target_explicit_binding_wins_with_preferred_realm() {
let config = openai_target_config();
let preferred_realm = RealmId::parse("prod").unwrap();
let binding = BindingId::parse("secondary").unwrap();
let target = resolve_realm_binding_target_for_provider(
&config,
Provider::OpenAI,
None,
Some(&binding),
None,
Some(&preferred_realm),
false,
)
.unwrap();
assert_eq!(target.auth_binding.realm.as_str(), "prod");
assert_eq!(target.auth_binding.binding.as_str(), "secondary");
assert_eq!(target.binding.id, "secondary");
}
#[test]
fn connection_target_rejects_provider_mismatch() {
let config = openai_target_config();
let preferred_realm = RealmId::parse("prod").unwrap();
let err = resolve_realm_binding_target_for_provider(
&config,
Provider::Anthropic,
None,
None,
None,
Some(&preferred_realm),
false,
)
.unwrap_err();
assert!(matches!(
err,
ConnectionTargetError::ProviderMismatch {
expected: Provider::Anthropic,
backend: Provider::OpenAI,
auth: Provider::OpenAI,
..
}
));
}
#[test]
fn auth_binding_candidates_prefer_provider_binding_in_preferred_realm() {
let config = config_with_realms(
r#"
[dev]
default_binding = "openai_oauth"
[dev.backend.openai_chatgpt]
provider = "openai"
backend_kind = "openai_chatgpt"
[dev.auth.openai_oauth]
provider = "openai"
auth_method = "chatgpt_oauth"
source = { kind = "managed_store" }
[dev.binding.openai_oauth]
backend_profile = "openai_chatgpt"
auth_profile = "openai_oauth"
default_model = "test-openai-default"
"#,
);
let preferred_realm = RealmId::parse("dev").unwrap();
let candidates = resolve_auth_binding_candidates_for_provider(
&config,
Provider::OpenAI,
None,
Some(&preferred_realm),
true,
)
.expect("candidates resolve");
assert_eq!(candidates[0].auth_binding.realm.as_str(), "dev");
assert_eq!(candidates[0].auth_binding.binding.as_str(), "openai_oauth");
assert!(!candidates[0].auth_binding.is_env_default());
}
#[test]
fn auth_binding_candidates_scan_configured_realms_before_env_default() {
let config = config_with_realms(
r#"
[dev]
[dev.backend.openai_chatgpt]
provider = "openai"
backend_kind = "openai_chatgpt"
[dev.auth.openai_oauth]
provider = "openai"
auth_method = "chatgpt_oauth"
source = { kind = "managed_store" }
[dev.binding.openai_oauth]
backend_profile = "openai_chatgpt"
auth_profile = "openai_oauth"
"#,
);
let preferred_realm = RealmId::parse("missing").unwrap();
let candidates = resolve_auth_binding_candidates_for_provider(
&config,
Provider::OpenAI,
None,
Some(&preferred_realm),
true,
)
.expect("candidates resolve");
assert_eq!(candidates[0].auth_binding.realm.as_str(), "dev");
assert_eq!(candidates[0].auth_binding.binding.as_str(), "openai_oauth");
assert!(!candidates[0].auth_binding.is_env_default());
let synthetic = candidates.last().unwrap();
assert_eq!(synthetic.auth_binding.realm.as_str(), "env_default");
assert_eq!(
synthetic.auth_binding.origin,
BindingOrigin::SyntheticEnvDefault
);
assert!(synthetic.auth_binding.is_env_default());
}
#[test]
fn from_inline_api_keys_marks_each_provider_default() {
let section = RealmConfigSection::from_inline_api_keys(&[
("anthropic", "sk-ant"),
("openai", "sk-oai"),
]);
assert!(section.binding["default_anthropic"].provider_default);
assert!(section.binding["default_openai"].provider_default);
assert_eq!(
section.default_binding.as_deref(),
Some("default_anthropic")
);
}
#[test]
fn selected_binding_prefers_typed_provider_default_marker() {
let config = config_with_realms(
r#"
[dev]
[dev.backend.openai_default]
provider = "openai"
backend_kind = "openai_api"
[dev.auth.openai_api]
provider = "openai"
auth_method = "api_key"
source = { kind = "env", env = "OPENAI_API_KEY" }
[dev.binding.alpha]
backend_profile = "openai_default"
auth_profile = "openai_api"
[dev.binding.beta]
backend_profile = "openai_default"
auth_profile = "openai_api"
provider_default = true
"#,
);
let preferred_realm = RealmId::parse("dev").unwrap();
let candidates = resolve_auth_binding_candidates_for_provider(
&config,
Provider::OpenAI,
None,
Some(&preferred_realm),
false,
)
.expect("candidates resolve");
assert_eq!(candidates[0].auth_binding.realm.as_str(), "dev");
assert_eq!(candidates[0].auth_binding.binding.as_str(), "beta");
}
#[test]
fn realm_config_section_serde_empty() {
let section = RealmConfigSection::default();
let s = serde_json::to_string(§ion).unwrap();
assert_eq!(s, "{}");
}
#[test]
fn realm_config_section_serde_populated() {
let toml_input = r#"
default_binding = "default_openai"
[backend.openai_default]
provider = "openai"
backend_kind = "openai_api"
base_url = "https://api.openai.com"
[auth.openai_api_key]
provider = "openai"
auth_method = "api_key"
source = { kind = "env", env = "OPENAI_API_KEY" }
[binding.default_openai]
backend_profile = "openai_default"
auth_profile = "openai_api_key"
default_model = "test-openai-other"
"#;
let section: RealmConfigSection = toml::from_str(toml_input).unwrap();
assert_eq!(section.backend.len(), 1);
assert_eq!(section.auth.len(), 1);
assert_eq!(section.binding.len(), 1);
assert_eq!(section.default_binding.as_deref(), Some("default_openai"));
assert_eq!(
section.backend["openai_default"].base_url.as_deref(),
Some("https://api.openai.com"),
);
}
}