Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/dallay/corvus/llms.txt

Use this file to discover all available pages before exploring further.

Example: Ollama Provider

A complete example of integrating Ollama (local LLM server) with Corvus. Source: examples/custom_provider.rs

Full Implementation

//! Example: Implementing a custom Provider for Corvus
//!
//! This shows how to add a new LLM backend in ~30 lines of code.

use anyhow::Result;
use async_trait::async_trait;

/// Minimal Provider trait (mirrors src/providers/traits.rs)
#[async_trait]
pub trait Provider: Send + Sync {
    async fn chat(&self, message: &str, model: &str, temperature: f64) -> Result<String>;
}

/// Example: Ollama local provider
pub struct OllamaProvider {
    base_url: String,
    client: reqwest::Client,
}

impl OllamaProvider {
    pub fn new(base_url: Option<&str>) -> Self {
        Self {
            base_url: base_url.unwrap_or("http://localhost:11434").to_string(),
            client: reqwest::Client::new(),
        }
    }
}

#[async_trait]
impl Provider for OllamaProvider {
    async fn chat(&self, message: &str, model: &str, temperature: f64) -> Result<String> {
        let url = format!("{}/api/generate", self.base_url);

        let body = serde_json::json!({
            "model": model,
            "prompt": message,
            "temperature": temperature,
            "stream": false,
        });

        let resp = self
            .client
            .post(&url)
            .json(&body)
            .send()
            .await?
            .json::<serde_json::Value>()
            .await?;

        resp["response"]
            .as_str()
            .map(|s| s.to_string())
            .ok_or_else(|| anyhow::anyhow!("No response field in Ollama reply"))
    }
}

Setup Ollama

1. Install Ollama

# macOS/Linux
curl -fsSL https://ollama.com/install.sh | sh

# Or download from https://ollama.com

2. Pull a Model

ollama pull llama3.2
ollama pull mistral

3. Start Ollama Server

ollama serve
Server runs on http://localhost:11434

Integration Steps

1. Add to Corvus

Copy implementation to src/providers/ollama.rs (already exists in Corvus)

2. Register Provider

Already registered in src/providers/mod.rs:54:
"ollama" => Ok(Box::new(ollama::OllamaProvider::new(None))),

3. Configure

# ~/.corvus/config.toml
default_provider = "ollama"
default_model = "llama3.2"
default_temperature = 0.7

4. Use

corvus agent -m "Hello, Ollama!"

API Format

Request

{
  "model": "llama3.2",
  "prompt": "Hello, Ollama!",
  "temperature": 0.7,
  "stream": false
}

Response

{
  "model": "llama3.2",
  "response": "Hello! How can I assist you today?",
  "done": true
}

Advanced Features

Streaming Support

impl Provider for OllamaProvider {
    fn supports_streaming(&self) -> bool {
        true
    }
    
    fn stream_chat_with_system(
        &self,
        system_prompt: Option<&str>,
        message: &str,
        model: &str,
        temperature: f64,
        _options: StreamOptions,
    ) -> BoxStream<'static, StreamResult<StreamChunk>> {
        // Set stream: true in request
        // Parse SSE events
        // Yield StreamChunk per token
    }
}

Model List

impl OllamaProvider {
    pub async fn list_models(&self) -> Result<Vec<String>> {
        let url = format!("{}/api/tags", self.base_url);
        let resp = self.client
            .get(&url)
            .send()
            .await?
            .json::<serde_json::Value>()
            .await?;
        
        let models = resp["models"]
            .as_array()
            .ok_or_else(|| anyhow::anyhow!("No models array"))?
            .iter()
            .filter_map(|m| m["name"].as_str())
            .map(|s| s.to_string())
            .collect();
        
        Ok(models)
    }
}

Build docs developers (and LLMs) love