Fetch available models for a provider. Routing logic: 1. Known built-in types (`openai`, `anthropic`, `enowxlabs`, …) use their canonical endpoints. 2. Custom providers use `api_format` to decide the wire format: - `"anthropic"` → Anthropic `/models` endpoint on the gateway. - anything else → OpenAI `/models` endpoint on the gateway.
(provider: &Provider)
| 23 | /// - `"anthropic"` → Anthropic `/models` endpoint on the gateway. |
| 24 | /// - anything else → OpenAI `/models` endpoint on the gateway. |
| 25 | pub async fn list_models(provider: &Provider) -> AppResult<Vec<String>> { |
| 26 | match provider.provider_type.as_str() { |
| 27 | // Built-in types with known behaviour |
| 28 | "openai" | "ollama" | "gemini" => { |
| 29 | fetch_openai_models(&provider.base_url, provider.api_key.as_deref()).await |
| 30 | } |
| 31 | "anthropic" => { |
| 32 | fetch_anthropic_models("https://api.anthropic.com/v1", provider.api_key.as_deref(), true).await |
| 33 | } |
| 34 | "enowxlabs" => { |
| 35 | // enowxlabs gateway: strip /v1 for the models endpoint |
| 36 | let base = provider.base_url.trim_end_matches('/').trim_end_matches("/v1"); |
| 37 | fetch_anthropic_models(base, provider.api_key.as_deref(), false).await |
| 38 | } |
| 39 | // Custom / unknown provider types — decide by api_format |
| 40 | _ => { |
| 41 | if provider.uses_anthropic_format() { |
| 42 | fetch_anthropic_models( |
| 43 | provider.base_url.trim_end_matches('/'), |
| 44 | provider.api_key.as_deref(), |
| 45 | false, |
| 46 | ) |
| 47 | .await |
| 48 | } else { |
| 49 | fetch_openai_models(&provider.base_url, provider.api_key.as_deref()).await |
| 50 | } |
| 51 | } |
| 52 | } |
| 53 | } |
| 54 | |
| 55 | async fn fetch_openai_models(base_url: &str, api_key: Option<&str>) -> AppResult<Vec<String>> { |
| 56 | let url = format!("{}/models", base_url.trim_end_matches('/')); |
nothing calls this directly
no test coverage detected