greentic-flow-builder 0.4.0

Greentic Flow Builder — orchestrator that powers Adaptive Card design via the adaptive-card-mcp toolkit
Documentation
//! Thin wrapper around `adaptive_card_core::knowledge::KnowledgeBase`.
//!
//! Loads the embedded knowledge base at startup. The wrapper exists so the
//! rest of `greentic-flow-builder` does not need to know whether the KB came
//! from the embedded data or an external `--knowledge-base <DIR>` argument.

use adaptive_card_core::knowledge::{KnowledgeBase, KnowledgeEntry, SuggestResult};
use std::path::Path;

pub struct Knowledge {
    inner: &'static KnowledgeBase,
}

impl Knowledge {
    /// Load the compile-time embedded knowledge base.
    #[must_use]
    pub fn embedded() -> Self {
        Self {
            inner: KnowledgeBase::embedded(),
        }
    }

    /// Load a knowledge base from an external directory (dev iteration).
    /// Leaks the box so the returned `Knowledge` borrows for `'static`.
    pub fn from_dir(path: &Path) -> anyhow::Result<Self> {
        let kb = KnowledgeBase::from_dir(path)?;
        let leaked: &'static KnowledgeBase = Box::leak(Box::new(kb));
        Ok(Self { inner: leaked })
    }

    #[must_use]
    pub fn entry_count(&self) -> usize {
        self.inner.all().len()
    }

    #[must_use]
    pub fn all(&self) -> &'static [KnowledgeEntry] {
        self.inner.all()
    }

    #[must_use]
    pub fn by_id(&self, id: &str) -> Option<&'static KnowledgeEntry> {
        self.inner.by_id(id)
    }

    #[must_use]
    pub fn suggest(&self, query: &str, limit: usize) -> Vec<SuggestResult> {
        self.inner.suggest(query, limit)
    }

    /// Borrow the underlying core KB (used by `prompt_builder`).
    #[must_use]
    pub fn as_core(&self) -> &'static KnowledgeBase {
        self.inner
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn embedded_loads() {
        let kb = Knowledge::embedded();
        let _count = kb.entry_count();
    }

    #[test]
    fn suggest_on_empty_query_returns_empty() {
        let kb = Knowledge::embedded();
        let results = kb.suggest("", 5);
        assert!(results.is_empty());
    }
}