1pub mod handlers;
2
3use async_trait::async_trait;
4use serde_json::Value;
5
6use khive_runtime::pack::PackRuntime;
7use khive_runtime::{KhiveRuntime, RuntimeError, VerbRegistry};
8use khive_types::{Pack, VerbDef};
9
10pub struct MemoryPack {
11 runtime: KhiveRuntime,
12}
13
14impl Pack for MemoryPack {
15 const NAME: &'static str = "memory";
16 const NOTE_KINDS: &'static [&'static str] = &["memory"];
17 const ENTITY_KINDS: &'static [&'static str] = &[];
18 const VERBS: &'static [VerbDef] = &MEMORY_VERBS;
19 const REQUIRES: &'static [&'static str] = &["kg"];
20}
21
22static MEMORY_VERBS: [VerbDef; 2] = [
23 VerbDef {
24 name: "remember",
25 description: "Create a memory note with salience and decay",
26 },
27 VerbDef {
28 name: "recall",
29 description: "Recall memory notes with decay-aware hybrid ranking",
30 },
31];
32
33impl MemoryPack {
34 pub fn new(runtime: KhiveRuntime) -> Self {
35 Self { runtime }
36 }
37}
38
39#[async_trait]
40impl PackRuntime for MemoryPack {
41 fn name(&self) -> &str {
42 <MemoryPack as Pack>::NAME
43 }
44
45 fn note_kinds(&self) -> &'static [&'static str] {
46 <MemoryPack as Pack>::NOTE_KINDS
47 }
48
49 fn entity_kinds(&self) -> &'static [&'static str] {
50 <MemoryPack as Pack>::ENTITY_KINDS
51 }
52
53 fn verbs(&self) -> &'static [VerbDef] {
54 &MEMORY_VERBS
55 }
56
57 fn requires(&self) -> &'static [&'static str] {
58 <MemoryPack as Pack>::REQUIRES
59 }
60
61 async fn dispatch(
62 &self,
63 verb: &str,
64 params: Value,
65 registry: &VerbRegistry,
66 ) -> Result<Value, RuntimeError> {
67 match verb {
68 "remember" => self.handle_remember(params).await,
69 "recall" => self.handle_recall(params, registry).await,
70 _ => Err(RuntimeError::InvalidInput(format!(
71 "memory pack does not handle verb {verb:?}"
72 ))),
73 }
74 }
75}