MemoryGraph

Struct MemoryGraph 

Source
pub struct MemoryGraph { /* private fields */ }
Expand description

Main interface for interacting with the memory graph

MemoryGraph provides a thread-safe, high-level API for managing conversation sessions, prompts, responses, and their relationships in a graph structure.

§Examples

use llm_memory_graph::{MemoryGraph, Config};

let config = Config::new("./data/my_graph.db");
let graph = MemoryGraph::open(config)?;

let session = graph.create_session()?;
let prompt_id = graph.add_prompt(session.id, "What is Rust?".to_string(), None)?;

Implementations§

Source§

impl MemoryGraph

Source

pub fn open(config: Config) -> Result<Self>

Open or create a memory graph with the given configuration

This will create the database directory if it doesn’t exist and initialize all necessary storage trees.

§Errors

Returns an error if:

  • The database path is invalid or inaccessible
  • Storage initialization fails
  • Existing data is corrupted
§Examples
use llm_memory_graph::{MemoryGraph, Config};

let config = Config::new("./data/graph.db");
let graph = MemoryGraph::open(config)?;
Source

pub fn create_session(&self) -> Result<ConversationSession>

Create a new conversation session

Sessions are used to group related prompts and responses together. Each session has a unique ID and can store custom metadata.

§Errors

Returns an error if the session cannot be persisted to storage.

§Examples
let session = graph.create_session()?;
println!("Created session: {}", session.id);
Source

pub fn create_session_with_metadata( &self, metadata: HashMap<String, String>, ) -> Result<ConversationSession>

Create a session with custom metadata

§Errors

Returns an error if the session cannot be persisted to storage.

§Examples
let mut metadata = HashMap::new();
metadata.insert("user_id".to_string(), "123".to_string());
let session = graph.create_session_with_metadata(metadata)?;
Source

pub fn get_session(&self, session_id: SessionId) -> Result<ConversationSession>

Get a session by ID

This will first check the in-memory cache, then fall back to storage.

§Errors

Returns an error if:

  • The session doesn’t exist
  • Storage retrieval fails
§Examples
let session = graph.get_session(created_session.id)?;
Source

pub fn add_prompt( &self, session_id: SessionId, content: String, metadata: Option<PromptMetadata>, ) -> Result<NodeId>

Add a prompt to a session

This creates a new prompt node and automatically creates edges linking it to the session and to the previous prompt if one exists.

§Errors

Returns an error if:

  • The session doesn’t exist
  • Storage operations fail
§Examples
let prompt_id = graph.add_prompt(
    session.id,
    "Explain quantum entanglement".to_string(),
    None,
)?;
Source

pub fn add_response( &self, prompt_id: NodeId, content: String, usage: TokenUsage, metadata: Option<ResponseMetadata>, ) -> Result<NodeId>

Add a response to a prompt

This creates a response node and a RespondsTo edge linking it to the prompt.

§Errors

Returns an error if:

  • The prompt doesn’t exist
  • Storage operations fail
§Examples
let usage = TokenUsage::new(10, 20);
let response_id = graph.add_response(
    prompt_id,
    "Quantum entanglement is...".to_string(),
    usage,
    None,
)?;
Source

pub fn add_tool_invocation(&self, tool: ToolInvocation) -> Result<NodeId>

Add a tool invocation node to the graph

This creates a tool invocation record and automatically creates an INVOKES edge from the response to the tool invocation.

§Arguments
  • tool - The tool invocation to add
§Returns

The node ID of the created tool invocation

§Example
let params = serde_json::json!({"operation": "add", "a": 2, "b": 3});
let tool = ToolInvocation::new(response_id, "calculator".to_string(), params);
let tool_id = graph.add_tool_invocation(tool)?;
Source

pub fn update_tool_invocation( &self, tool_id: NodeId, success: bool, result_or_error: String, duration_ms: u64, ) -> Result<()>

Update an existing tool invocation with results

This method updates a tool invocation’s status, result, and duration after execution.

§Arguments
  • tool_id - The ID of the tool invocation to update
  • success - Whether the tool execution was successful
  • result_or_error - Either the result (if successful) or error message (if failed)
  • duration_ms - Execution duration in milliseconds
§Example
// Mark tool invocation as successful
let result = serde_json::json!({"result": 5});
graph.update_tool_invocation(tool_id, true, serde_json::to_string(&result)?, 150)?;
Source

pub fn get_response_tools( &self, response_id: NodeId, ) -> Result<Vec<ToolInvocation>>

Get all tool invocations for a specific response

§Arguments
  • response_id - The response node ID
§Returns

A vector of tool invocation nodes

§Example
let tools = graph.get_response_tools(response_id)?;
println!("Response invoked {} tools", tools.len());
Source

pub fn add_agent(&self, agent: AgentNode) -> Result<NodeId>

Create and register an agent in the graph

§Errors

Returns an error if storage fails

§Examples
let agent = AgentNode::new(
    "Researcher".to_string(),
    "research".to_string(),
    vec!["web_search".to_string(), "summarize".to_string()],
);
let agent_id = graph.add_agent(agent)?;
Source

pub fn update_agent(&self, agent: AgentNode) -> Result<()>

Update an existing agent’s data

§Errors

Returns an error if:

  • The agent doesn’t exist
  • Storage update fails
§Examples
let node = graph.get_node(node_id)?;
if let llm_memory_graph::types::Node::Agent(mut agent) = node {
    agent.update_metrics(true, 250, 150);
    graph.update_agent(agent)?;
}
Source

pub fn assign_agent_to_prompt( &self, prompt_id: NodeId, agent_node_id: NodeId, ) -> Result<()>

Assign an agent to handle a prompt

Creates a HandledBy edge from the prompt to the agent.

§Errors

Returns an error if storage fails

§Examples
graph.assign_agent_to_prompt(prompt_id, agent_node_id)?;
Source

pub fn transfer_to_agent( &self, response_id: NodeId, agent_node_id: NodeId, ) -> Result<()>

Create a transfer from a response to an agent

Creates a TransfersTo edge indicating agent handoff.

§Errors

Returns an error if storage fails

§Examples
graph.transfer_to_agent(response_id, agent_node_id)?;
Source

pub fn get_prompt_agent(&self, prompt_id: NodeId) -> Result<AgentNode>

Get the agent assigned to handle a prompt

§Errors

Returns an error if:

  • No agent is assigned
  • Storage retrieval fails
§Examples
let agent = graph.get_prompt_agent(prompt_id)?;
println!("Handled by: {}", agent.name);
Source

pub fn get_agent_handoffs(&self, response_id: NodeId) -> Result<Vec<AgentNode>>

Get all agents a response was transferred to

§Errors

Returns an error if storage retrieval fails

§Examples
let agents = graph.get_agent_handoffs(response_id)?;
for agent in agents {
    println!("Transferred to: {}", agent.name);
}
Source

pub fn get_node(&self, node_id: NodeId) -> Result<Node>

Get a node by its ID

§Errors

Returns an error if:

  • The node doesn’t exist
  • Storage retrieval fails
§Examples
let node = graph.get_node(prompt_id)?;
Source

pub fn add_edge( &self, from: NodeId, to: NodeId, edge_type: EdgeType, ) -> Result<()>

Add a custom edge between two nodes

§Errors

Returns an error if storage operations fail.

§Examples
graph.add_edge(prompt1, prompt2, EdgeType::Follows)?;
Source

pub fn get_outgoing_edges(&self, node_id: NodeId) -> Result<Vec<Edge>>

Get all edges originating from a node

§Errors

Returns an error if storage retrieval fails.

§Examples
let edges = graph.get_outgoing_edges(prompt_id)?;
Source

pub fn get_incoming_edges(&self, node_id: NodeId) -> Result<Vec<Edge>>

Get all edges pointing to a node

§Errors

Returns an error if storage retrieval fails.

§Examples
let edges = graph.get_incoming_edges(prompt_id)?;
Source

pub fn get_session_nodes(&self, session_id: SessionId) -> Result<Vec<Node>>

Get all nodes in a session

§Errors

Returns an error if storage retrieval fails.

§Examples
let nodes = graph.get_session_nodes(session.id)?;
Source

pub fn flush(&self) -> Result<()>

Flush all pending writes to disk

§Errors

Returns an error if the flush operation fails.

§Examples
graph.flush()?;
Source

pub fn stats(&self) -> Result<StorageStats>

Get storage statistics

Returns information about node count, edge count, storage size, etc.

§Errors

Returns an error if statistics cannot be retrieved.

§Examples
let stats = graph.stats()?;
println!("Nodes: {}, Edges: {}", stats.node_count, stats.edge_count);
Source

pub fn create_template(&self, template: PromptTemplate) -> Result<TemplateId>

Create and store a new prompt template

Templates are versioned prompt structures that can be instantiated with variables.

§Errors

Returns an error if storage fails.

§Examples
let variables = vec![
    VariableSpec::new(
        "user_input".to_string(),
        "String".to_string(),
        true,
        "User's question".to_string(),
    ),
];
let template = PromptTemplate::new(
    "Question Answering".to_string(),
    "Answer this question: {{user_input}}".to_string(),
    variables,
);
let template_id = graph.create_template(template)?;
Source

pub fn get_template(&self, _template_id: TemplateId) -> Result<PromptTemplate>

Get a template by its ID

§Errors

Returns an error if:

  • The template doesn’t exist
  • Storage retrieval fails
§Examples
let template = graph.get_template(template_id)?;
Source

pub fn get_template_by_node_id(&self, node_id: NodeId) -> Result<PromptTemplate>

Get a template by its node ID

§Errors

Returns an error if:

  • The node doesn’t exist or is not a template
  • Storage retrieval fails
§Examples
let template = graph.get_template_by_node_id(node_id)?;
Source

pub fn update_template(&self, template: PromptTemplate) -> Result<()>

Update an existing template

This will store the updated template data. Note that the template’s version should be bumped appropriately before calling this method.

§Errors

Returns an error if storage update fails.

§Examples
let mut template = graph.get_template_by_node_id(node_id)?;
template.record_usage();
template.bump_version(VersionLevel::Patch);
graph.update_template(template)?;

Link a prompt to the template it was instantiated from

Creates an Instantiates edge from the prompt to the template.

§Errors

Returns an error if storage fails.

§Examples
let mut values = HashMap::new();
values.insert("name".to_string(), "World".to_string());
let prompt_text = template.instantiate(&values)?;
let prompt_id = graph.add_prompt(session.id, prompt_text, None)?;
graph.link_prompt_to_template(prompt_id, template_node_id)?;
Source

pub fn create_template_from_parent( &self, template: PromptTemplate, parent_node_id: NodeId, ) -> Result<TemplateId>

Create a new template that inherits from a parent template

This creates the new template and automatically establishes an Inherits edge.

§Errors

Returns an error if storage fails.

§Examples
let child = PromptTemplate::from_parent(
    parent_id,
    "Child Template".to_string(),
    "Extended: {{x}} with {{y}}".to_string(),
    vec![],
);
let child_id = graph.create_template_from_parent(child, parent_node_id)?;

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more