forked from kent/consciousness
store: remove visit tracking infrastructure
Remove AgentVisit, TranscriptSegment, and all related visit tracking code. Provenance is what we've been using to track agent interaction with nodes. Also removes dead fields from Node (state_tag, created). -349 lines. Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
parent
7d49f29fde
commit
a1accc7cd4
8 changed files with 7 additions and 349 deletions
|
|
@ -30,14 +30,6 @@ impl Store {
|
|||
if rels_p.exists() {
|
||||
store.replay_relations(&rels_p)?;
|
||||
}
|
||||
let visits_p = visits_path();
|
||||
if visits_p.exists() {
|
||||
store.replay_visits(&visits_p)?;
|
||||
}
|
||||
let tp_p = transcript_progress_path();
|
||||
if tp_p.exists() {
|
||||
store.replay_transcript_progress(&tp_p)?;
|
||||
}
|
||||
|
||||
// Record log sizes after replay
|
||||
store.loaded_nodes_size = fs::metadata(&nodes_p).map(|m| m.len()).unwrap_or(0);
|
||||
|
|
@ -330,173 +322,6 @@ impl Store {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Append agent visit records to the visits log.
|
||||
pub fn append_visits(&mut self, visits: &[AgentVisit]) -> Result<()> {
|
||||
if visits.is_empty() { return Ok(()); }
|
||||
|
||||
let mut msg = message::Builder::new_default();
|
||||
{
|
||||
let log = msg.init_root::<memory_capnp::agent_visit_log::Builder>();
|
||||
let mut list = log.init_visits(visits.len() as u32);
|
||||
for (i, visit) in visits.iter().enumerate() {
|
||||
visit.to_capnp(list.reborrow().get(i as u32));
|
||||
}
|
||||
}
|
||||
let mut buf = Vec::new();
|
||||
serialize::write_message(&mut buf, &msg)
|
||||
.with_context(|| format!("serialize visits"))?;
|
||||
|
||||
let path = visits_path();
|
||||
let file = fs::OpenOptions::new()
|
||||
.create(true).append(true).open(&path)
|
||||
.with_context(|| format!("open {}", path.display()))?;
|
||||
use std::io::Write;
|
||||
(&file).write_all(&buf)
|
||||
.with_context(|| format!("write visits"))?;
|
||||
|
||||
// Update in-memory index
|
||||
for v in visits {
|
||||
self.visits
|
||||
.entry(v.node_key.clone())
|
||||
.or_default()
|
||||
.insert(v.agent.clone(), v.timestamp);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Replay visits log to rebuild in-memory index.
|
||||
fn replay_visits(&mut self, path: &Path) -> Result<()> {
|
||||
let file = fs::File::open(path)
|
||||
.with_context(|| format!("open {}", path.display()))?;
|
||||
let mut reader = BufReader::new(file);
|
||||
|
||||
while reader.stream_position()?
|
||||
< fs::metadata(path)?.len()
|
||||
{
|
||||
let msg = match serialize::read_message(&mut reader, Default::default()) {
|
||||
Ok(m) => m,
|
||||
Err(_) => break,
|
||||
};
|
||||
let log = msg.get_root::<memory_capnp::agent_visit_log::Reader>()
|
||||
.with_context(|| format!("read visit log"))?;
|
||||
|
||||
for visit in log.get_visits()? {
|
||||
let key = visit.get_node_key().ok()
|
||||
.and_then(|t| t.to_str().ok())
|
||||
.unwrap_or("")
|
||||
.to_string();
|
||||
let agent = visit.get_agent().ok()
|
||||
.and_then(|t| t.to_str().ok())
|
||||
.unwrap_or("")
|
||||
.to_string();
|
||||
let ts = visit.get_timestamp();
|
||||
|
||||
if !key.is_empty() && !agent.is_empty() {
|
||||
let entry = self.visits.entry(key).or_default();
|
||||
// Keep latest timestamp per agent
|
||||
let existing = entry.entry(agent).or_insert(0);
|
||||
if ts > *existing {
|
||||
*existing = ts;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Append transcript segment progress records.
|
||||
pub fn append_transcript_progress(&mut self, segments: &[TranscriptSegment]) -> Result<()> {
|
||||
if segments.is_empty() { return Ok(()); }
|
||||
|
||||
let mut msg = message::Builder::new_default();
|
||||
{
|
||||
let log = msg.init_root::<memory_capnp::transcript_progress_log::Builder>();
|
||||
let mut list = log.init_segments(segments.len() as u32);
|
||||
for (i, seg) in segments.iter().enumerate() {
|
||||
seg.to_capnp(list.reborrow().get(i as u32));
|
||||
}
|
||||
}
|
||||
let mut buf = Vec::new();
|
||||
serialize::write_message(&mut buf, &msg)
|
||||
.with_context(|| format!("serialize transcript progress"))?;
|
||||
|
||||
let path = transcript_progress_path();
|
||||
let file = fs::OpenOptions::new()
|
||||
.create(true).append(true).open(&path)
|
||||
.with_context(|| format!("open {}", path.display()))?;
|
||||
use std::io::Write;
|
||||
(&file).write_all(&buf)
|
||||
.with_context(|| format!("write transcript progress"))?;
|
||||
|
||||
// Update in-memory index
|
||||
for seg in segments {
|
||||
self.transcript_progress
|
||||
.entry((seg.transcript_id.clone(), seg.segment_index))
|
||||
.or_default()
|
||||
.insert(seg.agent.clone());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Replay transcript progress log to rebuild in-memory index.
|
||||
fn replay_transcript_progress(&mut self, path: &Path) -> Result<()> {
|
||||
let file = fs::File::open(path)
|
||||
.with_context(|| format!("open {}", path.display()))?;
|
||||
let mut reader = BufReader::new(file);
|
||||
|
||||
while reader.stream_position()?
|
||||
< fs::metadata(path)?.len()
|
||||
{
|
||||
let msg = match serialize::read_message(&mut reader, Default::default()) {
|
||||
Ok(m) => m,
|
||||
Err(_) => break,
|
||||
};
|
||||
let log = msg.get_root::<memory_capnp::transcript_progress_log::Reader>()
|
||||
.with_context(|| format!("read transcript progress"))?;
|
||||
|
||||
for seg in log.get_segments()? {
|
||||
let id = seg.get_transcript_id().ok()
|
||||
.and_then(|t| t.to_str().ok())
|
||||
.unwrap_or("")
|
||||
.to_string();
|
||||
let agent = seg.get_agent().ok()
|
||||
.and_then(|t| t.to_str().ok())
|
||||
.unwrap_or("")
|
||||
.to_string();
|
||||
let idx = seg.get_segment_index();
|
||||
|
||||
if !id.is_empty() && !agent.is_empty() {
|
||||
self.transcript_progress
|
||||
.entry((id, idx))
|
||||
.or_default()
|
||||
.insert(agent);
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Record visits for a batch of node keys from a successful agent run.
|
||||
pub fn record_agent_visits(&mut self, node_keys: &[String], agent: &str) -> Result<()> {
|
||||
let visits: Vec<AgentVisit> = node_keys.iter()
|
||||
.filter_map(|key| {
|
||||
let node = self.nodes.get(key)?;
|
||||
Some(new_visit(node.uuid, key, agent, "processed"))
|
||||
})
|
||||
.collect();
|
||||
self.append_visits(&visits)
|
||||
}
|
||||
|
||||
/// Get the last time an agent visited a node. Returns 0 if never visited.
|
||||
pub fn last_visited(&self, node_key: &str, agent: &str) -> i64 {
|
||||
self.visits.get(node_key)
|
||||
.and_then(|agents| agents.get(agent))
|
||||
.copied()
|
||||
.unwrap_or(0)
|
||||
}
|
||||
|
||||
/// Placeholder - indices will be updated on write with redb.
|
||||
pub fn save(&self) -> Result<()> {
|
||||
Ok(())
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue