cliai 0.2.0

A small Rust library for invoking AI tools through CLI backends like Ollama and GitHub Copilot CLI.
Documentation
//! `cliai` is a small Rust library for invoking AI tools through local CLI backends.
//!
//! It exposes a minimal trait-based interface so applications can work with
//! different AI backends without coupling to a provider SDK or HTTP client.
//!
//! # Included backends
//!
//! - [`Ollama`] for local models via the `ollama` CLI
//! - [`Copilot`] for GitHub Copilot CLI via the `copilot` binary
//!
//! # Design
//!
//! This crate shells out to installed executables. That keeps the dependency
//! surface small, but it also means:
//!
//! - the backend binary must be installed and available on `PATH`, unless
//!   overridden with `with_bin()`
//! - prompts are passed to external processes
//! - runtime behavior depends on the installed CLI tool
//!
//! # Example
//!
//! ```no_run
//! use cliai::{AiBackend, GenerateRequest, Ollama};
//!
//! fn main() -> Result<(), Box<dyn std::error::Error>> {
//!     let ai = Ollama::new("llama3.2");
//!     let response = ai.generate(
//!         &GenerateRequest::new("Write a haiku about Rust.")
//!             .with_instructions("Be concise."),
//!     )?;
//!
//!     println!("{}", response.text);
//!     Ok(())
//! }
//! ```

pub mod backend;
mod error;
pub mod request;
pub mod response;
#[cfg(test)]
mod tests;

pub use backend::{Copilot, Ollama};
pub use error::AiError;
pub use request::GenerateRequest;
pub use response::GenerateResponse;

/// Common interface implemented by supported AI backends.
///
/// Backends are expected to invoke an external CLI tool and return the generated
/// text as a [`GenerateResponse`].
pub trait AiBackend: Send + Sync {
    /// Returns the backend name.
    fn name(&self) -> &'static str;

    /// Generates text from the given request.
    ///
    /// Returns an [`AiError`] if the process cannot be started, exits with a
    /// non-zero status, or produces invalid UTF-8 output.
    fn generate(&self, request: &GenerateRequest) -> Result<GenerateResponse, AiError>;
}