1use super::config::{get_embedding_settings, is_embeddings_enabled};
6use super::huggingface::HuggingFaceProvider;
7use super::ollama::OllamaProvider;
8use super::provider::{BoxedProvider, EmbeddingProvider};
9use super::types::EmbeddingProviderType;
10
11#[derive(Debug, Clone)]
13pub struct ProviderDetection {
14 pub available: Vec<String>,
16 pub recommended: Option<String>,
18}
19
20pub async fn detect_available_providers() -> ProviderDetection {
22 let mut available = Vec::new();
23
24 let ollama = OllamaProvider::new();
26 if ollama.is_available().await {
27 available.push("ollama".to_string());
28 }
29
30 if let Some(hf) = HuggingFaceProvider::new() {
32 if hf.is_available().await {
33 available.push("huggingface".to_string());
34 }
35 }
36
37 let recommended = available.first().cloned();
41
42 ProviderDetection {
43 available,
44 recommended,
45 }
46}
47
48pub async fn create_embedding_provider() -> Option<BoxedProvider> {
56 if !is_embeddings_enabled() {
58 return None;
59 }
60
61 if let Ok(Some(settings)) = get_embedding_settings() {
63 if let Some(provider_type) = settings.provider {
64 return create_provider_by_type(provider_type).await;
65 }
66 }
67
68 let ollama = OllamaProvider::new();
70 if ollama.is_available().await {
71 return Some(BoxedProvider::new(ollama));
72 }
73
74 if let Some(hf) = HuggingFaceProvider::new() {
75 if hf.is_available().await {
76 return Some(BoxedProvider::new(hf));
77 }
78 }
79
80 None
81}
82
83async fn create_provider_by_type(provider_type: EmbeddingProviderType) -> Option<BoxedProvider> {
85 match provider_type {
86 EmbeddingProviderType::Ollama => {
87 let provider = OllamaProvider::new();
88 if provider.is_available().await {
89 Some(BoxedProvider::new(provider))
90 } else {
91 None
92 }
93 }
94 EmbeddingProviderType::Huggingface => {
95 HuggingFaceProvider::new().map(BoxedProvider::new)
96 }
97 EmbeddingProviderType::Transformers => {
98 None
101 }
102 EmbeddingProviderType::Model2vec => {
103 super::model2vec::Model2VecProvider::try_new().map(BoxedProvider::new)
106 }
107 }
108}
109
110pub fn create_ollama_provider(endpoint: Option<String>, model: Option<String>) -> BoxedProvider {
112 BoxedProvider::new(OllamaProvider::with_config(endpoint, model))
113}
114
115pub fn create_huggingface_provider(
117 endpoint: Option<String>,
118 model: Option<String>,
119 token: Option<String>,
120) -> Option<BoxedProvider> {
121 HuggingFaceProvider::with_config(endpoint, model, token)
122 .map(BoxedProvider::new)
123}