areev 0.0.0

Rust SDK for the Areev knowledge database — gRPC and HTTP transports
Documentation
use serde::{Deserialize, Serialize};

/// Grain types supported by Areev.
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum GrainType {
    Belief,
    Event,
    State,
    Workflow,
    Action,
    Observation,
    Goal,
    Reasoning,
    Consensus,
    Consent,
}

impl std::fmt::Display for GrainType {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        let s = match self {
            Self::Belief => "belief",
            Self::Event => "event",
            Self::State => "state",
            Self::Workflow => "workflow",
            Self::Action => "action",
            Self::Observation => "observation",
            Self::Goal => "goal",
            Self::Reasoning => "reasoning",
            Self::Consensus => "consensus",
            Self::Consent => "consent",
        };
        f.write_str(s)
    }
}

/// Options for the add operation (import intelligence).
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct AddOptions {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub extract_event_date: Option<bool>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub auto_relate: Option<bool>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub extract_memories: Option<bool>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub sync: Option<bool>,
}

/// Request to add a grain.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AddRequest {
    pub grain_type: GrainType,
    pub fields: serde_json::Value,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub options: Option<AddOptions>,
}

/// Response from adding a grain.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AddResponse {
    pub hash: String,
}

/// Request to recall (query) grains.
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct RecallRequest {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub query: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub subject: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub relation: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub object: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub namespace: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub user_id: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub grain_type: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub limit: Option<u32>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub temporal_expr: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub tags: Option<Vec<String>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub deduplicate: Option<bool>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub rerank: Option<bool>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub query_expansion: Option<bool>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub explanation: Option<bool>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub min_score: Option<f64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub diversity: Option<f64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub recency_weight: Option<f64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub entity: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub multi_hop: Option<u32>,
    /// Additional fields not covered above (passed through as-is).
    #[serde(flatten)]
    pub extra: serde_json::Map<String, serde_json::Value>,
}

/// A single search result.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SearchHit {
    pub hash: String,
    pub grain_type: String,
    pub score: f64,
    pub fields: serde_json::Value,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub source_namespace: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub explanation: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub relative_time: Option<String>,
}

/// Response from a recall query.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RecallResponse {
    pub count: u32,
    pub results: Vec<SearchHit>,
}

/// Request to forget (delete) a grain.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ForgetRequest {
    pub hash: String,
}

/// Request to supersede a grain.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SupersedeRequest {
    pub old_hash: String,
    pub grain_type: GrainType,
    pub fields: serde_json::Value,
}

/// Response from superseding a grain.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SupersedeResponse {
    pub new_hash: String,
}

/// Request to remember natural language text.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RememberRequest {
    /// Natural language text to remember (1-32768 bytes).
    pub text: String,
    /// Sync mode: extract beliefs inline via LLM (default: false = async via Axtion).
    #[serde(skip_serializing_if = "Option::is_none")]
    pub sync: Option<bool>,
    /// Keep the source Observation after extraction (default: false = forget source).
    #[serde(skip_serializing_if = "Option::is_none")]
    pub keep_source: Option<bool>,
    /// Namespace for the observation and extracted beliefs.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub namespace: Option<String>,
    /// User ID (mandatory per compliance).
    #[serde(skip_serializing_if = "Option::is_none")]
    pub user_id: Option<String>,
    /// Tags for the observation and extracted beliefs.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub tags: Option<Vec<String>>,
    /// Source attribution (e.g., "conversation", "note", "document").
    #[serde(skip_serializing_if = "Option::is_none")]
    pub source_type: Option<String>,
    /// Explicit timestamp in milliseconds since epoch.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub created_at: Option<i64>,
    /// Confidence for LLM-extracted beliefs (default 0.9).
    #[serde(skip_serializing_if = "Option::is_none")]
    pub confidence: Option<f64>,
    /// Extract temporal references from content and auto-populate valid_from.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub extract_event_date: Option<bool>,
    /// Auto-detect updates/extends relationships with existing grains.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub auto_relate: Option<bool>,
}

/// Response from remembering natural language text.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RememberResponse {
    /// Content-address hash of the source Observation grain.
    pub source_hash: String,
    /// Whether sync or async extraction was used.
    pub mode: String,
    /// Number of beliefs extracted.
    pub extracted_count: u32,
    /// Whether the source Observation was forgotten after extraction.
    pub source_forgotten: bool,
    /// Hashes of beliefs extracted in sync mode. Empty for async.
    #[serde(default)]
    pub extracted_hashes: Vec<String>,
    /// Warnings from the extraction pipeline.
    #[serde(default)]
    pub warnings: Vec<String>,
    /// Extraction marker status (for async mode).
    #[serde(skip_serializing_if = "Option::is_none")]
    pub marker_status: Option<String>,
}

/// Response from getting a grain by hash.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GetResponse {
    pub hash: String,
    pub grain_type: String,
    pub fields: serde_json::Value,
}

/// Health check response.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HealthResponse {
    pub status: String,
    pub version: String,
}

/// Database statistics.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct StatsResponse {
    pub total_grains: u64,
    pub disk_space_bytes: u64,
    pub store_size: String,
    #[serde(default)]
    pub type_counts: std::collections::HashMap<String, u64>,
}