use crate::llm::types::{LLMError, LLMRequest, LLMResponse, ProviderCapabilities, ProviderStatus};
use futures::future::BoxFuture;
use std::path::PathBuf;
use std::sync::Arc;
pub trait LLMProvider: Send + Sync {
fn execute_request(
&self,
request: LLMRequest,
session_dir: Option<PathBuf>,
) -> BoxFuture<'_, Result<LLMResponse, LLMError>>;
fn get_capabilities(&self) -> BoxFuture<'_, Result<ProviderCapabilities, LLMError>>;
fn get_status(&self) -> BoxFuture<'_, Result<ProviderStatus, LLMError>>;
fn health_check(&self) -> BoxFuture<'_, Result<(), LLMError>>;
fn provider_name(&self) -> &'static str;
fn list_models(&self) -> BoxFuture<'_, Result<Vec<String>, LLMError>>;
fn estimate_tokens(&self, text: &str) -> u64;
fn shutdown(&self) -> BoxFuture<'_, Result<(), LLMError>> {
Box::pin(async { Ok(()) })
}
}
pub struct LLMProviderFactory;
impl LLMProviderFactory {
pub async fn create_provider(
config: crate::llm::types::ProviderConfig,
workspace_root: PathBuf,
) -> Result<Arc<dyn LLMProvider>, LLMError> {
match config.provider_type {
crate::llm::types::ProviderType::ClaudeCode => Ok(Arc::new(
crate::llm::claude_provider::ClaudeProvider::new(config, workspace_root).await?,
)),
crate::llm::types::ProviderType::OpenAICodex => Ok(Arc::new(
crate::llm::openai_provider::OpenAIProvider::new(config, workspace_root).await?,
)),
crate::llm::types::ProviderType::Anthropic => {
Err(LLMError::ProviderUnavailable(
"Anthropic provider not yet implemented".to_string(),
))
}
crate::llm::types::ProviderType::LocalModel => {
Err(LLMError::ProviderUnavailable(
"Local model provider not yet implemented".to_string(),
))
}
crate::llm::types::ProviderType::Custom(name) => Err(LLMError::ProviderUnavailable(
format!("Custom provider '{}' not implemented", name),
)),
}
}
}