Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/core/all.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,8 @@ fn build_registered_controllers() -> Vec<RegisteredController> {
// Memory sources — user-configured data connectors registry
controllers
.extend(crate::openhuman::memory_sources::all_memory_sources_registered_controllers());
// Memory diff — snapshot-based change tracking for memory sources
controllers.extend(crate::openhuman::memory_diff::all_memory_diff_registered_controllers());
// Link shortener for long tracking URLs — saves LLM tokens
controllers
.extend(crate::openhuman::redirect_links::all_redirect_links_registered_controllers());
Expand Down Expand Up @@ -366,6 +368,7 @@ fn build_declared_controller_schemas() -> Vec<ControllerSchema> {
crate::openhuman::memory_sync::sync_status::all_memory_sync_status_controller_schemas(),
);
schemas.extend(crate::openhuman::memory_sources::all_memory_sources_controller_schemas());
schemas.extend(crate::openhuman::memory_diff::all_memory_diff_controller_schemas());
schemas.extend(crate::openhuman::redirect_links::all_redirect_links_controller_schemas());
schemas.extend(crate::openhuman::referral::all_referral_controller_schemas());
schemas.extend(crate::openhuman::billing::all_billing_controller_schemas());
Expand Down Expand Up @@ -478,6 +481,9 @@ pub fn namespace_description(namespace: &str) -> Option<&'static str> {
"memory_sources" => Some(
"User-configured data connectors (Composio, folders, GitHub repos, RSS, web pages) that feed memory.",
),
"memory_diff" => Some(
"Snapshot-based change tracking for memory sources — capture state, compute diffs, and surface changes to agents.",
),
"redirect_links" => Some(
"Shorten long tracking URLs to `openhuman://link/<id>` placeholders (SQLite-backed) to save tokens in prompts, with round-trip rewrite helpers.",
),
Expand Down
25 changes: 24 additions & 1 deletion src/core/event_bus/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,25 @@ pub enum DomainEvent {
queue_depth: usize,
},

// ── Memory Diff ─────────────────────────────────────────────────────
/// A snapshot of a memory source's chunk state was captured.
MemoryDiffSnapshotTaken {
snapshot_id: String,
source_id: String,
source_kind: String,
item_count: usize,
trigger: String,
},
/// A diff was computed between two snapshots.
MemoryDiffComputed {
source_id: String,
from_snapshot_id: Option<String>,
to_snapshot_id: String,
added: usize,
removed: usize,
modified: usize,
},

// ── Channels ────────────────────────────────────────────────────────
/// An inbound channel message from the transport layer, ready for processing.
///
Expand Down Expand Up @@ -1020,7 +1039,9 @@ impl DomainEvent {
| Self::MemorySyncStageChanged { .. }
| Self::MemoryIngestionStarted { .. }
| Self::MemoryIngestionCompleted { .. }
| Self::DocumentCanonicalized { .. } => "memory",
| Self::DocumentCanonicalized { .. }
| Self::MemoryDiffSnapshotTaken { .. }
| Self::MemoryDiffComputed { .. } => "memory",

Self::CacheRebuilt { .. } => "learning",

Expand Down Expand Up @@ -1152,6 +1173,8 @@ impl DomainEvent {
Self::MemoryIngestionStarted { .. } => "MemoryIngestionStarted",
Self::MemoryIngestionCompleted { .. } => "MemoryIngestionCompleted",
Self::DocumentCanonicalized { .. } => "DocumentCanonicalized",
Self::MemoryDiffSnapshotTaken { .. } => "MemoryDiffSnapshotTaken",
Self::MemoryDiffComputed { .. } => "MemoryDiffComputed",
Self::CacheRebuilt { .. } => "CacheRebuilt",
Self::ChannelInboundMessage { .. } => "ChannelInboundMessage",
Self::ChannelMessageReceived { .. } => "ChannelMessageReceived",
Expand Down
32 changes: 32 additions & 0 deletions src/openhuman/memory_diff/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//! Snapshot-based change tracking for memory sources.
//!
//! After each sync, this module captures what's in the chunk store for
//! that source, then diffs against previous snapshots to surface
//! additions, removals, and modifications — helping agents understand
//! how their world view has changed over time.
//!
//! Snapshots are built from already-ingested data in `mem_tree_chunks`
//! (not by re-calling source readers), making them free of API calls.
//!
//! Features:
//! - Per-source snapshots (auto after sync, or manual via RPC)
//! - Diff between any two snapshots
//! - Named checkpoints for cross-source "what changed since X" queries
//! - Agent tool for in-conversation diff queries

pub mod ops;
pub mod rpc;
pub mod schemas;
pub mod store;
pub mod tools;
pub mod types;

pub use schemas::{
all_controller_schemas as all_memory_diff_controller_schemas,
all_registered_controllers as all_memory_diff_registered_controllers,
};
pub use tools::MemoryDiffTool;
pub use types::{
ChangeKind, Checkpoint, CrossSourceDiff, DiffResult, DiffSummary, ItemChange, Snapshot,
SnapshotItem, SnapshotTrigger,
};
Loading
Loading