Skip to main content

khive_pack_knowledge/
pack.rs

1//! `KnowledgePack` struct, factory, and `PackRuntime` impl.
2
3use async_trait::async_trait;
4use serde_json::Value;
5
6use khive_runtime::pack::PackRuntime;
7use khive_runtime::{KhiveRuntime, NamespaceToken, RuntimeError, VerbRegistry};
8use khive_types::{HandlerDef, Pack};
9
10use crate::knowledge::vamana;
11use crate::knowledge::KnowledgeHandlers;
12use crate::vocab::KNOWLEDGE_HANDLERS;
13
14/// Knowledge corpus pack — atoms, domains, TF-IDF search, fold, import, and KG concept verbs.
15pub struct KnowledgePack {
16    pub(crate) runtime: KhiveRuntime,
17    pub(crate) ann: vamana::SharedAnn,
18}
19
20impl Pack for KnowledgePack {
21    const NAME: &'static str = "knowledge";
22    const NOTE_KINDS: &'static [&'static str] = &[];
23    const ENTITY_KINDS: &'static [&'static str] = &[];
24    const HANDLERS: &'static [HandlerDef] = &KNOWLEDGE_HANDLERS;
25    const REQUIRES: &'static [&'static str] = &["kg"];
26}
27
28impl KnowledgePack {
29    /// Create a new pack bound to the given runtime, initializing a shared ANN index.
30    pub fn new(runtime: KhiveRuntime) -> Self {
31        Self {
32            runtime,
33            ann: vamana::new_shared(),
34        }
35    }
36}
37
38struct KnowledgePackFactory;
39
40impl khive_runtime::PackFactory for KnowledgePackFactory {
41    fn name(&self) -> &'static str {
42        "knowledge"
43    }
44
45    fn requires(&self) -> &'static [&'static str] {
46        &["kg"]
47    }
48
49    fn create(&self, runtime: KhiveRuntime) -> Box<dyn khive_runtime::PackRuntime> {
50        Box::new(KnowledgePack::new(runtime))
51    }
52}
53
54inventory::submit! { khive_runtime::PackRegistration(&KnowledgePackFactory) }
55
56#[async_trait]
57impl PackRuntime for KnowledgePack {
58    fn name(&self) -> &str {
59        <KnowledgePack as Pack>::NAME
60    }
61
62    fn note_kinds(&self) -> &'static [&'static str] {
63        <KnowledgePack as Pack>::NOTE_KINDS
64    }
65
66    fn entity_kinds(&self) -> &'static [&'static str] {
67        <KnowledgePack as Pack>::ENTITY_KINDS
68    }
69
70    fn handlers(&self) -> &'static [HandlerDef] {
71        &KNOWLEDGE_HANDLERS
72    }
73
74    fn requires(&self) -> &'static [&'static str] {
75        <KnowledgePack as Pack>::REQUIRES
76    }
77
78    async fn warm(&self) {
79        crate::knowledge::vamana::warm_known_snapshots(&self.runtime, &self.ann).await;
80        if !self.runtime.default_embedder_name().is_empty() {
81            let runtime = self.runtime.clone();
82            tokio::spawn(async move {
83                let _ = runtime.embed("__khive_knowledge_warm__").await;
84            });
85        }
86    }
87
88    async fn dispatch(
89        &self,
90        verb: &str,
91        params: Value,
92        _registry: &VerbRegistry,
93        token: &NamespaceToken,
94    ) -> Result<Value, RuntimeError> {
95        match verb {
96            "knowledge.upsert_atoms" => {
97                KnowledgeHandlers::upsert_atoms(&self.runtime, token, params).await
98            }
99            "knowledge.upsert_domains" => {
100                KnowledgeHandlers::upsert_domains(&self.runtime, token, params).await
101            }
102            "knowledge.get" => KnowledgeHandlers::get(&self.runtime, token, params).await,
103            "knowledge.list" => KnowledgeHandlers::list(&self.runtime, token, params).await,
104            "knowledge.delete_atoms" => {
105                KnowledgeHandlers::delete_atoms(&self.runtime, token, params).await
106            }
107            "knowledge.stats" => KnowledgeHandlers::stats(&self.runtime, token, params).await,
108            "knowledge.index" => {
109                KnowledgeHandlers::index(&self.runtime, token, params, &self.ann).await
110            }
111            "knowledge.fold" => KnowledgeHandlers::fold(&self.runtime, token, params).await,
112            "knowledge.search" => {
113                KnowledgeHandlers::search(&self.runtime, token, params, &self.ann).await
114            }
115            "knowledge.suggest" => {
116                KnowledgeHandlers::suggest(&self.runtime, token, params, &self.ann).await
117            }
118            "knowledge.compose" => KnowledgeHandlers::compose(&self.runtime, token, params).await,
119            "knowledge.edit" => KnowledgeHandlers::edit(&self.runtime, token, params).await,
120            "knowledge.import" => KnowledgeHandlers::import(&self.runtime, token, params).await,
121            "knowledge.challenge" => {
122                KnowledgeHandlers::challenge(&self.runtime, token, params).await
123            }
124            "knowledge.adjudicate" => {
125                KnowledgeHandlers::adjudicate(&self.runtime, token, params).await
126            }
127            "knowledge.learn" => self.handle_learn(token, params).await,
128            "knowledge.cite" => self.handle_cite(token, params).await,
129            "knowledge.topic" => self.handle_topic(token, params).await,
130            _ => Err(RuntimeError::InvalidInput(format!(
131                "knowledge pack does not handle verb {verb:?}"
132            ))),
133        }
134    }
135}