use crate::schema::{ModelSchema, ModelSource, ProprietaryAuth, ProprietaryWire};
use crate::InferenceError;
pub(crate) fn is_direct(row: &ModelSchema) -> bool {
row.provider.eq_ignore_ascii_case("typesafe")
&& matches!(&row.source, ModelSource::Proprietary { provider, .. }
if provider.eq_ignore_ascii_case("typesafe"))
}
pub(crate) fn key_name(row: &ModelSchema) -> Result<&str, InferenceError> {
match &row.source {
ModelSource::Proprietary {
auth: ProprietaryAuth::ApiKeyEnv { env_var },
protocol,
..
} if is_direct(row)
&& protocol.wire == ProprietaryWire::SystemOne
&& !env_var.trim().is_empty() =>
{
Ok(env_var)
}
_ => Err(InferenceError::InferenceFailed(format!(
"{}: TypeSafe direct requires System One wire and an api_key_env naming a stored key",
row.id
))),
}
}
pub(crate) fn stored_key(row: &ModelSchema) -> Result<String, InferenceError> {
let name = key_name(row)?;
let value = car_secrets::resolve_stored_provider_key(name)
.map(|value| value.trim().to_owned())
.filter(|value| !value.is_empty())
.ok_or_else(|| InferenceError::ProviderKeyMissing {
provider: "typesafe".into(),
model: row.id.clone(),
env_vars: vec![name.into()],
message: format!("TypeSafe direct needs stored key {name}; run `car keys set {name}`"),
})?;
Ok(value)
}
pub(crate) fn audit_reason(row: &ModelSchema, reason: &str) -> String {
if !is_direct(row) {
return reason.into();
}
serde_json::json!({"provider":"typesafe","provider_row":row.id,
"key_id":key_name(row).ok(),"route":reason})
.to_string()
}