opencrabs 0.3.25

The autonomous, self-improving AI agent. Single Rust binary. Every channel. Install with: cargo install opencrabs
Documentation
//! LLM Provider Abstraction Layer
//!
//! Provides a unified interface for interacting with different LLM providers.

pub mod error;
pub mod json_repair;
pub mod placeholder;
pub mod rate_limiter;
pub mod retry;
#[allow(clippy::module_inception)]
mod r#trait;
pub mod types;

// Re-exports
pub use error::{ProviderError, Result};
pub use placeholder::PlaceholderProvider;
pub use r#trait::{Provider, ProviderCapabilities, ProviderStream};
pub use types::*;

// Provider implementations
pub mod anthropic;
pub mod claude_cli;
pub mod codex_cli;
pub mod codex_oauth;
pub mod copilot;
pub mod custom_openai_compatible;
pub mod factory;
pub mod fallback;
pub mod gemini;
pub mod model_fetch;
pub(crate) mod nonstream_compat;
pub mod opencode_cli;
pub mod qwen;

pub use anthropic::AnthropicProvider;
pub use claude_cli::ClaudeCliProvider;
pub use codex_cli::CodexCliProvider;
pub use codex_oauth::CodexOAuthProvider;
pub use custom_openai_compatible::OpenAIProvider;
pub use factory::{create_provider, create_provider_by_name, create_provider_with_warning};
pub use fallback::{FallbackProvider, SwapEvent};
pub use gemini::GeminiProvider;
pub use opencode_cli::OpenCodeCliProvider;

/// Cross-platform binary lookup. Uses `where.exe` on Windows, `which` elsewhere.
/// Returns the resolved path if found on PATH, or None.
pub(crate) fn which_binary(name: &str) -> Option<String> {
    #[cfg(target_os = "windows")]
    let cmd = "where.exe";
    #[cfg(not(target_os = "windows"))]
    let cmd = "which";

    if let Ok(output) = std::process::Command::new(cmd).arg(name).output()
        && output.status.success()
    {
        // `where.exe` can return multiple lines — take the first
        let path = String::from_utf8_lossy(&output.stdout)
            .lines()
            .next()
            .unwrap_or("")
            .trim()
            .to_string();
        if !path.is_empty() {
            return Some(path);
        }
    }
    None
}