Skip to main content

ralph_workflow/agents/providers/
detection.rs

1//! Provider Detection
2//!
3//! Logic for detecting provider type from model flag strings.
4
5use super::types::OpenCodeProviderType;
6
7/// Strip a leading model-flag prefix and return the raw `provider/model` string.
8///
9/// Supports common `OpenCode` CLI forms:
10/// - `-m provider/model`
11/// - `--model provider/model`
12/// - `-m=provider/model`
13/// - `--model=provider/model`
14pub fn strip_model_flag_prefix(model_flag: &str) -> &str {
15    let s = model_flag.trim();
16
17    // Equals-style flags first.
18    if let Some(rest) = s.strip_prefix("-m=") {
19        return rest.trim();
20    }
21    if let Some(rest) = s.strip_prefix("--model=") {
22        return rest.trim();
23    }
24
25    // Space-style flags.
26    if s == "-m" {
27        return "";
28    }
29    if let Some(rest) = s.strip_prefix("-m ") {
30        return rest.trim();
31    }
32    if let Some(rest) = s.strip_prefix("-m\t") {
33        return rest.trim();
34    }
35    if s == "--model" {
36        return "";
37    }
38    if let Some(rest) = s.strip_prefix("--model ") {
39        return rest.trim();
40    }
41    if let Some(rest) = s.strip_prefix("--model\t") {
42        return rest.trim();
43    }
44
45    s
46}
47
48impl OpenCodeProviderType {
49    /// Detect provider type from a model flag string.
50    pub fn from_model_flag(model_flag: &str) -> Self {
51        let model = strip_model_flag_prefix(model_flag);
52        let prefix = model.split('/').next().unwrap_or("").to_lowercase();
53
54        match prefix.as_str() {
55            // OpenCode Gateway
56            "opencode" => Self::OpenCodeZen,
57
58            // Chinese AI Providers
59            "zai" | "zhipuai" => Self::ZaiDirect,
60            "zai-coding" | "zai-plan" => Self::ZaiCodingPlan,
61            "moonshot" | "kimi" => Self::Moonshot,
62            "minimax" => Self::MiniMax,
63
64            // Major Cloud Providers
65            "anthropic" => Self::Anthropic,
66            "openai" => Self::OpenAI,
67            "google" => Self::Google,
68            "google-vertex" | "vertex" => Self::GoogleVertex,
69            "amazon-bedrock" | "bedrock" => Self::AmazonBedrock,
70            "azure-openai" | "azure" => Self::AzureOpenAI,
71            "copilot" | "github-copilot" => Self::GithubCopilot,
72
73            // Fast Inference Providers
74            "groq" => Self::Groq,
75            "together" => Self::Together,
76            "fireworks" => Self::Fireworks,
77            "cerebras" => Self::Cerebras,
78            "sambanova" => Self::SambaNova,
79            "deep-infra" | "deepinfra" => Self::DeepInfra,
80
81            // Gateway / Aggregator Providers
82            "openrouter" => Self::OpenRouter,
83            "cloudflare" | "cf" => Self::Cloudflare,
84            "vercel" => Self::Vercel,
85            "helicone" => Self::Helicone,
86            "zenmux" => Self::ZenMux,
87
88            // Specialized Providers
89            "deepseek" => Self::DeepSeek,
90            "xai" | "grok" => Self::Xai,
91            "mistral" => Self::Mistral,
92            "cohere" => Self::Cohere,
93            "perplexity" => Self::Perplexity,
94            "ai21" => Self::AI21,
95            "venice-ai" | "venice" => Self::VeniceAI,
96
97            // Open-Source Model Providers
98            "huggingface" | "hf" => Self::HuggingFace,
99            "replicate" => Self::Replicate,
100
101            // Cloud Platform Providers
102            "baseten" => Self::Baseten,
103            "cortecs" => Self::Cortecs,
104            "scaleway" => Self::Scaleway,
105            "ovhcloud" | "ovh" => Self::OVHcloud,
106            "io-net" | "ionet" => Self::IONet,
107            "nebius" => Self::Nebius,
108
109            // Enterprise / Industry Providers
110            "sap-ai-core" | "sap" => Self::SapAICore,
111            "azure-cognitive-services" | "azure-cognitive" => Self::AzureCognitiveServices,
112
113            // Local / Self-Hosted Providers
114            "ollama" => Self::Ollama,
115            "lmstudio" => Self::LMStudio,
116            "ollama-cloud" => Self::OllamaCloud,
117            "llama.cpp" | "llamacpp" | "llama-cpp" => Self::LlamaCpp,
118
119            _ => Self::Custom,
120        }
121    }
122}