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