hypersteeldb 0.3.0

A database that compiles questions instead of guessing answers: typed vocabulary discovered from your documents, queries type-checked before they run, roaring-bitmap set algebra over reified hyperedges, and Dempster-Shafer evidence with an explicit conflict guard.
Documentation
//! The provider abstraction: any chat model with tool-use, behind one async trait. Bedrock (Claude)
//! and Paddock (local Qwen) both implement it; the agent loop is provider-agnostic.

use crate::agent::types::{Msg, ToolSpec, Turn};
use async_trait::async_trait;

#[async_trait]
pub trait LlmProvider: Send + Sync {
    /// One turn: given the system prompt, conversation, and available tools, return the model's reply
    /// (assistant text and/or tool calls).
    async fn chat(&self, system: &str, msgs: &[Msg], tools: &[ToolSpec]) -> Result<Turn, String>;
    fn name(&self) -> &str;

    /// One turn whose output is **constrained to a JSON schema** by the decoder, rather than requested by a
    /// tool definition and hoped for.
    ///
    /// This exists because tool calling is a capability many small models simply lack: asked to call a tool,
    /// `qwen2.5:0.5b` returns `tool_calls: null` every time and answers in prose, so a caller that needs
    /// structured output has nothing to work with. Constraining the sampler to a grammar needs no such
    /// capability — the model can only emit tokens the schema permits.
    ///
    /// Returns `Ok(None)` when this provider cannot constrain decoding, so a caller can fall back rather than
    /// treating it as an error. The default is `Ok(None)`, which keeps every existing provider unaffected.
    async fn chat_json(
        &self,
        system: &str,
        msgs: &[Msg],
        schema: &serde_json::Value,
        name: &str,
    ) -> Result<Option<serde_json::Value>, String> {
        let _ = (system, msgs, schema, name);
        Ok(None)
    }

    /// Whether this provider produces trustworthy natural-language *synthesis* of tool results. Large
    /// models (Bedrock, big OpenAI-compatible) do; small on-device tool-callers (Needle, the native
    /// 1.7B) do NOT — for those the agent renders a deterministic template from the program result
    /// instead of trusting the model to phrase the numbers. Default `true`.
    fn synthesizes(&self) -> bool {
        true
    }
}