use llm_memory_graph::{
AgentNode, Config, ContextType, InheritsProperties, InstantiatesProperties, InvokesProperties,
MemoryGraph, Priority, PromptTemplate, ReferencesProperties, TransfersToProperties,
VariableSpec,
};
use std::collections::HashMap;
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("=== LLM-Memory-Graph: Edge Properties Example ===\n");
let config = Config::default();
let graph = MemoryGraph::open(config)?;
let session = graph.create_session()?;
println!("1. INSTANTIATES Edge: Linking Prompts to Templates");
println!(" Properties: template_version, variable_bindings, instantiation_time\n");
let template_vars = vec![
VariableSpec::new(
"topic".to_string(),
"String".to_string(),
true,
"The topic to explain".to_string(),
),
VariableSpec::new(
"audience".to_string(),
"String".to_string(),
true,
"Target audience level".to_string(),
),
];
let explanation_template = PromptTemplate::new(
"Explanation Template".to_string(),
"Explain {{topic}} for a {{audience}} audience.".to_string(),
template_vars,
)
.with_description("Template for generating explanations".to_string());
let template_node_id = explanation_template.node_id;
let template_version = explanation_template.version.to_string();
graph.create_template(explanation_template.clone())?;
let mut bindings = HashMap::new();
bindings.insert("topic".to_string(), "quantum computing".to_string());
bindings.insert("audience".to_string(), "beginner".to_string());
let prompt_text = explanation_template.instantiate(&bindings)?;
let prompt_id = graph.add_prompt(session.id, prompt_text.clone(), None)?;
use llm_memory_graph::types::Edge;
let instantiate_props = InstantiatesProperties::new(template_version.clone(), bindings.clone());
let edge = Edge::instantiates(prompt_id, template_node_id, instantiate_props);
println!(" Template: {}", explanation_template.name);
println!(" Version: {}", template_version);
println!(" Prompt: {}", prompt_text);
println!(" Bindings: {:?}", bindings);
graph.add_edge(edge.from, edge.to, edge.edge_type.clone())?;
let edges = graph.get_outgoing_edges(prompt_id)?;
let instantiate_edge = edges
.iter()
.find(|e| matches!(e.edge_type, llm_memory_graph::EdgeType::Instantiates))
.expect("INSTANTIATES edge should exist");
if let Some(props) = instantiate_edge.get_instantiates_properties() {
println!(" ✓ Retrieved properties:");
println!(" - Template version: {}", props.template_version);
println!(
" - Variable bindings: {} entries",
props.variable_bindings.len()
);
println!(" - Instantiation time: {}", props.instantiation_time);
}
println!();
println!("2. INHERITS Edge: Template Inheritance Hierarchy");
println!(" Properties: override_sections, version_diff, inheritance_depth\n");
let parent_template = PromptTemplate::new(
"Base Analysis Template".to_string(),
"Analyze the following: {{content}}".to_string(),
vec![VariableSpec::new(
"content".to_string(),
"String".to_string(),
true,
"Content to analyze".to_string(),
)],
);
let parent_id = parent_template.id;
let parent_node_id = parent_template.node_id;
graph.create_template(parent_template.clone())?;
let child_vars = vec![
VariableSpec::new(
"content".to_string(),
"String".to_string(),
true,
"Content to analyze".to_string(),
),
VariableSpec::new(
"focus_area".to_string(),
"String".to_string(),
true,
"Specific aspect to focus on".to_string(),
),
];
let child_template = PromptTemplate::from_parent(
parent_id,
"Focused Analysis Template".to_string(),
"Analyze the following, focusing on {{focus_area}}: {{content}}".to_string(),
child_vars,
);
let child_node_id = child_template.node_id;
graph.create_template_from_parent(child_template.clone(), parent_node_id)?;
let override_sections = vec!["focus_area".to_string()];
let version_diff = "Added focus_area variable to narrow analysis scope".to_string();
let inherits_props =
InheritsProperties::new(override_sections.clone(), version_diff.clone(), 1);
let inherits_edge = Edge::inherits(child_node_id, parent_node_id, inherits_props);
println!(" Parent: {}", parent_template.name);
println!(" Child: {}", child_template.name);
println!(" Inheritance depth: 1");
println!(" Override sections: {:?}", override_sections);
println!(" Version diff: {}", version_diff);
if let Some(props) = inherits_edge.get_inherits_properties() {
println!(" ✓ Properties confirmed:");
println!(
" - Override sections: {} sections",
props.override_sections.len()
);
println!(" - Version diff: {}", props.version_diff);
println!(" - Depth: {}", props.inheritance_depth);
}
println!();
println!("3. INVOKES Edge: Tool Invocation Tracking");
println!(" Properties: invocation_order, success, required\n");
let agent = AgentNode::new(
"Research Agent".to_string(),
"Information retrieval specialist".to_string(),
vec!["web_search".to_string(), "calculator".to_string()],
);
let agent_node_id = agent.node_id;
let invokes_props = InvokesProperties::new(
0, true, true, );
let invokes_edge = Edge::invokes(
prompt_id, agent_node_id, invokes_props,
);
println!(" Tool invocation order: 0 (first call)");
println!(" Success: true");
println!(" Required: true");
if let Some(props) = invokes_edge.get_invokes_properties() {
println!(" ✓ Properties confirmed:");
println!(" - Invocation order: {}", props.invocation_order);
println!(" - Success: {}", props.success);
println!(" - Required: {}", props.required);
}
println!();
println!("4. TRANSFERS_TO Edge: Agent-to-Agent Handoff");
println!(" Properties: handoff_reason, context_summary, priority\n");
let specialist_agent = AgentNode::new(
"Code Specialist".to_string(),
"Code analysis and optimization expert".to_string(),
vec!["code_analyzer".to_string(), "profiler".to_string()],
);
let specialist_node_id = specialist_agent.node_id;
let transfers_props = TransfersToProperties::new(
"User requested code analysis which requires specialist expertise".to_string(),
"User is asking about optimizing quantum circuit implementations in Python".to_string(),
Priority::High,
);
let transfers_edge = Edge::transfers_to(agent_node_id, specialist_node_id, transfers_props);
println!(" From: Research Agent");
println!(" To: Code Specialist");
println!(" Priority: High");
println!(" Reason: Requires specialist expertise");
if let Some(props) = transfers_edge.get_transfers_to_properties() {
println!(" ✓ Properties confirmed:");
println!(" - Priority: {:?}", props.priority);
println!(" - Handoff reason: {}", props.handoff_reason);
println!(" - Context: {} chars", props.context_summary.len());
}
println!();
println!("5. REFERENCES Edge: External Context References");
println!(" Properties: context_type, relevance_score, chunk_id\n");
let references_props = ReferencesProperties::new(
ContextType::WebPage,
0.95,
Some("chunk-arxiv-2024-quantum-section-3".to_string()),
);
let references_edge = Edge::references(
prompt_id,
template_node_id, references_props,
);
println!(" Context Type: WebPage");
println!(" Relevance: 0.95");
println!(" Chunk ID: chunk-arxiv-2024-quantum-section-3");
if let Some(props) = references_edge.get_references_properties() {
println!(" ✓ Properties confirmed:");
println!(" - Type: {:?}", props.context_type);
println!(" - Relevance: {:.2}", props.relevance_score);
println!(" - Has chunk ID: {}", props.chunk_id.is_some());
if let Some(chunk) = &props.chunk_id {
println!(" - Chunk: {}", chunk);
}
}
println!();
println!("6. Complex Workflow: Combining All Edge Types\n");
println!(" Workflow Steps:");
println!(" 1. User question instantiates explanation template (INSTANTIATES)");
println!(" 2. Research agent invokes web_search tool (INVOKES)");
println!(" 3. Agent references external research paper (REFERENCES)");
println!(" 4. Agent transfers to Code Specialist (TRANSFERS_TO)");
println!(" 5. Specialist uses focused analysis template that inherits from base (INHERITS)");
println!("\n Edge Types Demonstrated:");
println!(" ✓ INSTANTIATES - Template to prompt binding");
println!(" ✓ INHERITS - Template inheritance hierarchy");
println!(" ✓ INVOKES - Tool invocation tracking");
println!(" ✓ TRANSFERS_TO - Agent handoff coordination");
println!(" ✓ REFERENCES - External context linking");
println!("\n Priority Levels Available:");
println!(" - Low: Background tasks");
println!(" - Normal: Standard operations");
println!(" - High: Important requests");
println!(" - Critical: Urgent/time-sensitive");
println!("\n Context Types Available:");
println!(" - Document: Local files and documents");
println!(" - WebPage: Internet resources");
println!(" - Database: Structured data sources");
println!(" - VectorSearch: Embedding-based retrieval");
println!(" - Memory: Previous conversation context");
println!("\n=== Summary ===");
let stats = graph.stats()?;
println!("Total nodes: {}", stats.node_count);
println!("Total edges: {}", stats.edge_count);
println!("\n✓ All 5 edge types demonstrated successfully!");
println!("✓ All property structures are strongly-typed and validated");
println!("✓ Enterprise-grade implementation with full type safety");
Ok(())
}