hippocampus: move MemoryNode + store ops to where they belong
MemoryNode moved from agent/memory.rs to hippocampus/memory.rs — it's a view over hippocampus data, not agent-specific. Store operations (set_weight, set_link_strength, add_link) moved into store/ops.rs. CLI code (cli/graph.rs, cli/node.rs) and agent tools both call the same store methods now. render_node() delegates to MemoryNode::from_store().render() — 3 lines instead of 40. Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
parent
4b97bb2f2e
commit
10932cb67e
10 changed files with 108 additions and 191 deletions
|
|
@ -7,9 +7,9 @@
|
|||
use anyhow::{Context, Result};
|
||||
use serde_json::json;
|
||||
|
||||
use crate::agent::memory::MemoryNode;
|
||||
use crate::hippocampus::memory::MemoryNode;
|
||||
use crate::agent::types::ToolDef;
|
||||
use crate::store::{self, Store};
|
||||
use crate::store::Store;
|
||||
|
||||
pub fn definitions() -> Vec<ToolDef> {
|
||||
vec![
|
||||
|
|
@ -246,70 +246,18 @@ fn link_set(source: &str, target: &str, strength: f32) -> Result<String> {
|
|||
let mut store = Store::load().map_err(|e| anyhow::anyhow!("{}", e))?;
|
||||
let source = store.resolve_key(source).map_err(|e| anyhow::anyhow!("{}", e))?;
|
||||
let target = store.resolve_key(target).map_err(|e| anyhow::anyhow!("{}", e))?;
|
||||
let strength = strength.clamp(0.01, 1.0);
|
||||
|
||||
let mut found = false;
|
||||
let mut first = true;
|
||||
for rel in &mut store.relations {
|
||||
if rel.deleted { continue; }
|
||||
if (rel.source_key == source && rel.target_key == target)
|
||||
|| (rel.source_key == target && rel.target_key == source)
|
||||
{
|
||||
if first {
|
||||
let old = rel.strength;
|
||||
rel.strength = strength;
|
||||
first = false;
|
||||
found = true;
|
||||
if (old - strength).abs() < 0.001 {
|
||||
return Ok(format!("{} ↔ {} already at {:.2}", source, target, strength));
|
||||
}
|
||||
} else {
|
||||
rel.deleted = true; // deduplicate
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
anyhow::bail!("no link found between {} and {}", source, target);
|
||||
}
|
||||
|
||||
let old = store.set_link_strength(&source, &target, strength)
|
||||
.map_err(|e| anyhow::anyhow!("{}", e))?;
|
||||
store.save().map_err(|e| anyhow::anyhow!("{}", e))?;
|
||||
Ok(format!("set {} ↔ {} strength to {:.2}", source, target, strength))
|
||||
Ok(format!("set {} ↔ {} strength {:.2} → {:.2}", source, target, old, strength))
|
||||
}
|
||||
|
||||
fn link_add(source: &str, target: &str, prov: &str) -> Result<String> {
|
||||
let mut store = Store::load().map_err(|e| anyhow::anyhow!("{}", e))?;
|
||||
let source = store.resolve_key(source).map_err(|e| anyhow::anyhow!("{}", e))?;
|
||||
let target = store.resolve_key(target).map_err(|e| anyhow::anyhow!("{}", e))?;
|
||||
|
||||
// Check for existing link
|
||||
let exists = store.relations.iter().any(|r|
|
||||
!r.deleted &&
|
||||
((r.source_key == source && r.target_key == target) ||
|
||||
(r.source_key == target && r.target_key == source)));
|
||||
if exists {
|
||||
return Ok(format!("link already exists: {} ↔ {}", source, target));
|
||||
}
|
||||
|
||||
let source_uuid = store.nodes.get(&source)
|
||||
.map(|n| n.uuid)
|
||||
.ok_or_else(|| anyhow::anyhow!("source not found: {}", source))?;
|
||||
let target_uuid = store.nodes.get(&target)
|
||||
.map(|n| n.uuid)
|
||||
.ok_or_else(|| anyhow::anyhow!("target not found: {}", target))?;
|
||||
|
||||
// Compute initial strength from Jaccard similarity
|
||||
let graph = store.build_graph();
|
||||
let jaccard = graph.jaccard(&source, &target);
|
||||
let strength = (jaccard * 3.0).clamp(0.1, 1.0) as f32;
|
||||
|
||||
let mut rel = store::new_relation(
|
||||
source_uuid, target_uuid,
|
||||
store::RelationType::Link, strength,
|
||||
&source, &target,
|
||||
);
|
||||
rel.provenance = prov.to_string();
|
||||
store.add_relation(rel).map_err(|e| anyhow::anyhow!("{}", e))?;
|
||||
let strength = store.add_link(&source, &target, prov)
|
||||
.map_err(|e| anyhow::anyhow!("{}", e))?;
|
||||
store.save().map_err(|e| anyhow::anyhow!("{}", e))?;
|
||||
Ok(format!("linked {} → {} (strength={:.2})", source, target, strength))
|
||||
}
|
||||
|
|
@ -317,14 +265,10 @@ fn link_add(source: &str, target: &str, prov: &str) -> Result<String> {
|
|||
fn weight_set(key: &str, weight: f32) -> Result<String> {
|
||||
let mut store = Store::load().map_err(|e| anyhow::anyhow!("{}", e))?;
|
||||
let resolved = store.resolve_key(key).map_err(|e| anyhow::anyhow!("{}", e))?;
|
||||
let weight = weight.clamp(0.01, 1.0);
|
||||
|
||||
let node = store.nodes.get_mut(&resolved)
|
||||
.ok_or_else(|| anyhow::anyhow!("node not found: {}", resolved))?;
|
||||
let old = node.weight;
|
||||
node.weight = weight;
|
||||
let (old, new) = store.set_weight(&resolved, weight)
|
||||
.map_err(|e| anyhow::anyhow!("{}", e))?;
|
||||
store.save().map_err(|e| anyhow::anyhow!("{}", e))?;
|
||||
Ok(format!("weight {} {:.2} → {:.2}", resolved, old, weight))
|
||||
Ok(format!("weight {} {:.2} → {:.2}", resolved, old, new))
|
||||
}
|
||||
|
||||
fn supersede(args: &serde_json::Value, prov: &str) -> Result<String> {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue