feat: implement web UI for provider and model configuration

- Added 'provider_configs' and 'model_configs' tables to database.
- Refactored ProviderManager to support thread-safe dynamic updates and database overrides.
- Implemented 'Models' tab in dashboard to manage model visibility, mapping, and pricing.
- Added provider configuration modal to 'Providers' tab.
- Integrated database overrides into chat completion logic (enabled state, mapping, and cost).
This commit is contained in:
2026-02-26 18:13:04 -05:00
parent c5fb2357ff
commit 3165aa1859
14 changed files with 707 additions and 103 deletions

View File

@@ -1,20 +1,12 @@
use anyhow::Result;
use axum::{Router, routing::get};
use std::net::SocketAddr;
use std::sync::Arc;
use tracing::{info, error};
use llm_proxy::{
config::AppConfig,
state::AppState,
providers::{
ProviderManager,
openai::OpenAIProvider,
gemini::GeminiProvider,
deepseek::DeepSeekProvider,
grok::GrokProvider,
ollama::OllamaProvider,
},
providers::ProviderManager,
database,
server,
dashboard,
@@ -40,60 +32,13 @@ async fn main() -> Result<()> {
info!("Database initialized at {:?}", config.database.path);
// Initialize provider manager with configured providers
let mut provider_manager = ProviderManager::new();
let provider_manager = ProviderManager::new();
// Initialize OpenAI
if config.providers.openai.enabled {
match OpenAIProvider::new(&config.providers.openai, &config) {
Ok(p) => {
provider_manager.add_provider(Arc::new(p));
info!("OpenAI provider initialized");
}
Err(e) => error!("Failed to initialize OpenAI provider: {}", e),
}
}
// Initialize Gemini
if config.providers.gemini.enabled {
match GeminiProvider::new(&config.providers.gemini, &config) {
Ok(p) => {
provider_manager.add_provider(Arc::new(p));
info!("Gemini provider initialized");
}
Err(e) => error!("Failed to initialize Gemini provider: {}", e),
}
}
// Initialize DeepSeek
if config.providers.deepseek.enabled {
match DeepSeekProvider::new(&config.providers.deepseek, &config) {
Ok(p) => {
provider_manager.add_provider(Arc::new(p));
info!("DeepSeek provider initialized");
}
Err(e) => error!("Failed to initialize DeepSeek provider: {}", e),
}
}
// Initialize Grok
if config.providers.grok.enabled {
match GrokProvider::new(&config.providers.grok, &config) {
Ok(p) => {
provider_manager.add_provider(Arc::new(p));
info!("Grok provider initialized");
}
Err(e) => error!("Failed to initialize Grok provider: {}", e),
}
}
// Initialize Ollama
if config.providers.ollama.enabled {
match OllamaProvider::new(&config.providers.ollama, &config) {
Ok(p) => {
provider_manager.add_provider(Arc::new(p));
info!("Ollama provider initialized at {}", config.providers.ollama.base_url);
}
Err(e) => error!("Failed to initialize Ollama provider: {}", e),
// Initialize all supported providers (they handle their own enabled check)
let supported_providers = vec!["openai", "gemini", "deepseek", "grok", "ollama"];
for name in supported_providers {
if let Err(e) = provider_manager.initialize_provider(name, &config, &db_pool).await {
error!("Failed to initialize provider {}: {}", name, e);
}
}