saya-cli 0.2.0

Database-aware AI agent for the terminal: full-screen TUI, schema discovery, and bounded read-only SQL over PostgreSQL, MySQL, DuckDB, and Snowflake.
Documentation
use saya_agent::{
    AnthropicProvider, ChatProvider, GeminiProvider, OllamaProvider, OpenAiCompatibleProvider,
    ProviderError, ProviderSettings,
};
use saya_config::{AiProvider, ResolvedAi, SecretResolver};

pub(crate) fn build(
    config: &ResolvedAi,
    resolver: &dyn SecretResolver,
) -> Result<Box<dyn ChatProvider>, ProviderError> {
    let settings = ProviderSettings::new(config.model.clone(), config.base_url.clone())
        .with_temperature(config.temperature);
    match config.provider {
        AiProvider::Ollama => Ok(Box::new(OllamaProvider::new(settings)?)),
        AiProvider::Openai | AiProvider::OpenaiCompatible => {
            let key = config
                .api_key
                .as_ref()
                .map(|reference| resolver.resolve(reference))
                .transpose()
                .map_err(|_| ProviderError::Configuration("API key unavailable".into()))?;
            Ok(Box::new(OpenAiCompatibleProvider::new(
                settings,
                key.as_ref().map(|value| value.expose()),
            )?))
        }
        AiProvider::Anthropic => {
            let key = config
                .api_key
                .as_ref()
                .map(|reference| resolver.resolve(reference))
                .transpose()
                .map_err(|_| ProviderError::Configuration("API key unavailable".into()))?;
            Ok(Box::new(AnthropicProvider::new(
                settings,
                key.as_ref().map(|value| value.expose()),
            )?))
        }
        AiProvider::Gemini => {
            let key = config
                .api_key
                .as_ref()
                .map(|reference| resolver.resolve(reference))
                .transpose()
                .map_err(|_| ProviderError::Configuration("API key unavailable".into()))?;
            Ok(Box::new(GeminiProvider::new(
                settings,
                key.as_ref().map(|value| value.expose()),
            )?))
        }
    }
}