cli: add memory_history, remove dump-json/edges/lookups
- Add memory_history MCP tool for version history - Convert cmd_history to use memory_rpc - Add raw parameter to memory_render for editing - Remove unused: dump-json, list-edges, lookup-bump, lookups - Fix render_node path in defs.rs/subconscious.rs Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
parent
3e0c6b039f
commit
ad59596335
8 changed files with 188 additions and 132 deletions
|
|
@ -116,6 +116,7 @@ async fn dispatch(
|
|||
"memory_link_set" => link_set(&args).await,
|
||||
"memory_link_add" => link_add(agent, &args).await,
|
||||
"memory_delete" => delete(&args).await,
|
||||
"memory_history" => history(&args).await,
|
||||
"memory_weight_set" => weight_set(&args).await,
|
||||
"memory_rename" => rename(&args).await,
|
||||
"memory_supersede" => supersede(agent, &args).await,
|
||||
|
|
@ -131,7 +132,7 @@ async fn dispatch(
|
|||
|
||||
// ── Definitions ────────────────────────────────────────────────
|
||||
|
||||
pub fn memory_tools() -> [super::Tool; 13] {
|
||||
pub fn memory_tools() -> [super::Tool; 14] {
|
||||
use super::Tool;
|
||||
[
|
||||
Tool { name: "memory_render", description: "Read a memory node's content and links.",
|
||||
|
|
@ -155,6 +156,9 @@ pub fn memory_tools() -> [super::Tool; 13] {
|
|||
Tool { name: "memory_delete", description: "Delete a memory node.",
|
||||
parameters_json: r#"{"type":"object","properties":{"key":{"type":"string","description":"Node key"}},"required":["key"]}"#,
|
||||
handler: Arc::new(|a, v| Box::pin(async move { dispatch("memory_delete", &a, v).await })) },
|
||||
Tool { name: "memory_history", description: "Show version history for a node.",
|
||||
parameters_json: r#"{"type":"object","properties":{"key":{"type":"string","description":"Node key"},"full":{"type":"boolean","description":"Show full content for each version"}},"required":["key"]}"#,
|
||||
handler: Arc::new(|a, v| Box::pin(async move { dispatch("memory_history", &a, v).await })) },
|
||||
Tool { name: "memory_weight_set", description: "Set a node's weight directly (0.01 to 1.0).",
|
||||
parameters_json: r#"{"type":"object","properties":{"key":{"type":"string"},"weight":{"type":"number","description":"0.01 to 1.0"}},"required":["key","weight"]}"#,
|
||||
handler: Arc::new(|a, v| Box::pin(async move { dispatch("memory_weight_set", &a, v).await })) },
|
||||
|
|
@ -330,6 +334,61 @@ async fn delete(args: &serde_json::Value) -> Result<String> {
|
|||
Ok(format!("deleted {}", resolved))
|
||||
}
|
||||
|
||||
async fn history(args: &serde_json::Value) -> Result<String> {
|
||||
let key = get_str(args, "key")?;
|
||||
let full = args.get("full").and_then(|v| v.as_bool()).unwrap_or(false);
|
||||
|
||||
let arc = cached_store().await?;
|
||||
let store = arc.lock().await;
|
||||
let key = store.resolve_key(key).unwrap_or_else(|_| key.to_string());
|
||||
drop(store);
|
||||
|
||||
let path = crate::store::nodes_path();
|
||||
if !path.exists() {
|
||||
anyhow::bail!("No node log found");
|
||||
}
|
||||
|
||||
use std::io::BufReader;
|
||||
let file = std::fs::File::open(&path)
|
||||
.map_err(|e| anyhow::anyhow!("open {}: {}", path.display(), e))?;
|
||||
let mut reader = BufReader::new(file);
|
||||
|
||||
let mut versions: Vec<crate::store::Node> = Vec::new();
|
||||
while let Ok(msg) = capnp::serialize::read_message(&mut reader, capnp::message::ReaderOptions::new()) {
|
||||
let log = msg.get_root::<crate::memory_capnp::node_log::Reader>()
|
||||
.map_err(|e| anyhow::anyhow!("read log: {}", e))?;
|
||||
for node_reader in log.get_nodes()
|
||||
.map_err(|e| anyhow::anyhow!("get nodes: {}", e))? {
|
||||
let node = crate::store::Node::from_capnp_migrate(node_reader)
|
||||
.map_err(|e| anyhow::anyhow!("{}", e))?;
|
||||
if node.key == key {
|
||||
versions.push(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if versions.is_empty() {
|
||||
anyhow::bail!("No history found for '{}'", key);
|
||||
}
|
||||
|
||||
let mut out = format!("{} versions of '{}':\n\n", versions.len(), key);
|
||||
for node in &versions {
|
||||
let ts = crate::store::format_datetime(node.timestamp);
|
||||
let deleted = if node.deleted { " DELETED" } else { "" };
|
||||
if full {
|
||||
out.push_str(&format!("=== v{} {} {}{} w={:.3} {}b ===\n",
|
||||
node.version, ts, node.provenance, deleted, node.weight, node.content.len()));
|
||||
out.push_str(&node.content);
|
||||
out.push('\n');
|
||||
} else {
|
||||
let preview = crate::util::first_n_chars(&node.content, 120).replace('\n', "\\n");
|
||||
out.push_str(&format!("v{:<3} {} {:24} w={:.3} {}b{}\n {}\n",
|
||||
node.version, ts, node.provenance, node.weight, node.content.len(), deleted, preview));
|
||||
}
|
||||
}
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
async fn weight_set(args: &serde_json::Value) -> Result<String> {
|
||||
let arc = cached_store().await?;
|
||||
let mut store = arc.lock().await;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue