systemprompt_models/bridge/
profile.rs1use serde::{Deserialize, Serialize};
16
17use crate::profile::{ApiSurface, ProviderRegistry};
18
19#[derive(Debug, Clone, Serialize, Deserialize)]
20pub struct BridgeProfileResponse {
21 pub inference_gateway_base_url: String,
22 pub auth_scheme: String,
23 #[serde(default)]
24 pub models: Vec<String>,
25 #[serde(default)]
26 pub organization_uuid: Option<String>,
27 #[serde(default)]
28 pub providers: Vec<ProviderHealth>,
29}
30
31#[derive(Debug, Clone, Serialize, Deserialize)]
34pub struct ProviderHealth {
35 pub name: String,
36 pub surface: ApiSurface,
37 pub configured: bool,
38 #[serde(default)]
39 pub models: Vec<String>,
40 #[serde(default, skip_serializing_if = "Option::is_none")]
41 pub config_issue: Option<String>,
42}
43
44pub fn provider_health(
45 registry: &ProviderRegistry,
46 secret_present: impl Fn(&str) -> bool,
47) -> Vec<ProviderHealth> {
48 registry
49 .advertised_providers()
50 .map(|entry| {
51 let secret = entry.api_key_secret.as_str();
52 let configured = secret_present(secret);
53 ProviderHealth {
54 name: entry.name.as_str().to_owned(),
55 surface: entry.surface,
56 configured,
57 models: entry
58 .models
59 .iter()
60 .flat_map(|m| {
61 std::iter::once(m.id.as_str().to_owned())
62 .chain(m.aliases.iter().map(|a| a.as_str().to_owned()))
63 })
64 .collect(),
65 config_issue: (!configured)
66 .then(|| format!("API key secret '{secret}' is not configured")),
67 }
68 })
69 .collect()
70}
71
72#[must_use]
73pub fn build(
74 inference_gateway_base_url: String,
75 auth_scheme: String,
76 organization_uuid: Option<String>,
77 registry: &ProviderRegistry,
78 secret_present: impl Fn(&str) -> bool,
79) -> BridgeProfileResponse {
80 BridgeProfileResponse {
81 inference_gateway_base_url,
82 auth_scheme,
83 models: registry.advertised_model_ids(&[ApiSurface::Anthropic]),
84 organization_uuid,
85 providers: provider_health(registry, secret_present),
86 }
87}