areev 0.0.0

Rust SDK for the Areev knowledge database — gRPC and HTTP transports
Documentation
use std::env;

use crate::error::Result;
use crate::http::HttpClient;
use crate::types::*;

const DEFAULT_URL: &str = "https://app.areev.ai";
const DEFAULT_MEMORY: &str = "default";

/// High-level Areev client with minimal boilerplate.
///
/// # Examples
///
/// ```no_run
/// # #[tokio::main]
/// # async fn main() -> areev_client::Result<()> {
/// use areev_client::Areev;
///
/// let areev = Areev::from_env();
/// areev.remember("John likes coffee").await?;
/// let results = areev.recall("what does John like?").await?;
/// # Ok(())
/// # }
/// ```
pub struct Areev {
    inner: HttpClient,
}

impl Areev {
    /// Create a client from environment variables.
    ///
    /// | Variable | Default | Description |
    /// |----------|---------|-------------|
    /// | `AREEV_API_KEY` | — | API key (`X-API-Key` header) |
    /// | `AREEV_URL` | `https://app.areev.ai` | Server endpoint |
    /// | `AREEV_MEMORY_ID` | `default` | Memory database ID |
    pub fn from_env() -> Self {
        let api_key = env::var("AREEV_API_KEY").ok();
        let url = env::var("AREEV_URL").unwrap_or_else(|_| DEFAULT_URL.to_string());
        let memory_id = env::var("AREEV_MEMORY_ID").unwrap_or_else(|_| DEFAULT_MEMORY.to_string());
        Self {
            inner: HttpClient::new(&url, &memory_id, api_key.as_deref()),
        }
    }

    /// Create a client from explicit values.
    pub fn new(api_key: Option<&str>, url: Option<&str>, memory_id: Option<&str>) -> Self {
        Self {
            inner: HttpClient::new(
                url.unwrap_or(DEFAULT_URL),
                memory_id.unwrap_or(DEFAULT_MEMORY),
                api_key,
            ),
        }
    }

    // -- Primary methods --------------------------------------------------

    /// Store a natural-language memory. Extracts beliefs synchronously.
    pub async fn remember(&self, text: &str) -> Result<RememberResponse> {
        let req = RememberRequest {
            text: text.to_string(),
            sync: Some(true),
            keep_source: None,
            namespace: None,
            user_id: None,
            tags: None,
            source_type: None,
            created_at: None,
            confidence: None,
            extract_event_date: None,
            auto_relate: None,
        };
        self.inner.remember(&req).await
    }

    /// Search memories. Returns matching grains.
    pub async fn recall(&self, query: &str) -> Result<RecallResponse> {
        let req = RecallRequest {
            query: Some(query.to_string()),
            limit: Some(10),
            ..Default::default()
        };
        self.inner.recall(&req).await
    }

    /// Delete a memory by hash.
    pub async fn forget(&self, hash: &str) -> Result<()> {
        self.inner.forget(hash).await
    }

    // -- Low-level methods ------------------------------------------------

    /// Add a typed grain.
    pub async fn add(&self, req: &AddRequest) -> Result<AddResponse> {
        self.inner.add(req).await
    }

    /// Get a grain by hash.
    pub async fn get(&self, hash: &str) -> Result<GetResponse> {
        self.inner.get(hash).await
    }

    /// Supersede (update) a grain.
    pub async fn supersede(&self, req: &SupersedeRequest) -> Result<SupersedeResponse> {
        self.inner.supersede(req).await
    }

    /// Health check.
    pub async fn health(&self) -> Result<HealthResponse> {
        self.inner.health().await
    }

    /// Database statistics.
    pub async fn stats(&self) -> Result<StatsResponse> {
        self.inner.stats().await
    }

    /// Flush write buffer.
    pub async fn flush(&self) -> Result<()> {
        self.inner.flush().await
    }
}