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