1use ainl_memory::{AinlMemoryNode, GraphStore};
7use serde::{Deserialize, Serialize};
8
9pub trait MemoryProvider {
11 fn record_episode(&self, node: AinlMemoryNode) -> Result<(), String>;
13
14 fn get_recent_context(
16 &self,
17 agent_id: &str,
18 limit: usize,
19 ) -> Result<Vec<AinlMemoryNode>, String>;
20}
21
22#[derive(Serialize, Deserialize, Debug, Clone)]
24pub struct RuntimeConfig {
25 pub max_delegation_depth: u32,
27
28 pub enable_graph_memory: bool,
30}
31
32impl Default for RuntimeConfig {
33 fn default() -> Self {
34 Self {
35 max_delegation_depth: 10,
36 enable_graph_memory: true,
37 }
38 }
39}
40
41pub struct RuntimeContext<S: GraphStore> {
43 _config: RuntimeConfig,
44 memory: Option<S>,
45}
46
47impl<S: GraphStore> RuntimeContext<S> {
48 pub fn new(config: RuntimeConfig, memory: Option<S>) -> Self {
50 Self {
51 _config: config,
52 memory,
53 }
54 }
55
56 pub fn record_delegation(
58 &self,
59 agent_id: String,
60 delegated_to: String,
61 trace_id: String,
62 depth: u32,
63 ) -> Result<(), String> {
64 if let Some(store) = &self.memory {
65 let node = AinlMemoryNode::new_delegation_episode(
66 agent_id,
67 delegated_to,
68 trace_id,
69 depth,
70 );
71 store.write_node(&node)?;
72 }
73 Ok(())
74 }
75
76 pub fn record_tool_execution(
78 &self,
79 agent_id: String,
80 tool_name: String,
81 ) -> Result<(), String> {
82 if let Some(store) = &self.memory {
83 let node = AinlMemoryNode::new_tool_episode(agent_id, tool_name);
84 store.write_node(&node)?;
85 }
86 Ok(())
87 }
88}
89
90#[cfg(test)]
91mod tests {
92 use super::*;
93
94 #[test]
95 fn test_runtime_config_default() {
96 let config = RuntimeConfig::default();
97 assert_eq!(config.max_delegation_depth, 10);
98 assert!(config.enable_graph_memory);
99 }
100}