journal_tail: return typed Vec<JournalEntry>, remove Store::load from agent
- journal_tail returns Vec<JournalEntry> with key, content, created_at - load_startup_journal uses typed API, no more direct Store access - CLI does formatting, hippocampus returns data Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
parent
419bb222b5
commit
063cf031d3
4 changed files with 62 additions and 47 deletions
|
|
@ -497,42 +497,33 @@ impl Agent {
|
|||
}
|
||||
|
||||
async fn load_startup_journal(&self) {
|
||||
use crate::agent::tools::memory::journal_tail;
|
||||
|
||||
let oldest_msg_ts = {
|
||||
let ctx = self.context.lock().await;
|
||||
ctx.conversation_log.as_ref().and_then(|log| log.oldest_timestamp())
|
||||
};
|
||||
|
||||
let store = match crate::store::Store::load() {
|
||||
Ok(s) => s,
|
||||
// Get recent journal entries (newest first)
|
||||
let journal_entries = match journal_tail(None, Some(100), Some(0), None).await {
|
||||
Ok(e) => e,
|
||||
Err(_) => return,
|
||||
};
|
||||
|
||||
let mut journal_nodes: Vec<_> = store.nodes.values()
|
||||
.filter(|n| n.node_type == crate::store::NodeType::EpisodicSession)
|
||||
// Filter to entries before the conversation started
|
||||
let cutoff_ts = oldest_msg_ts.map(|t| t.timestamp());
|
||||
let filtered: Vec<_> = journal_entries.into_iter()
|
||||
.filter(|e| cutoff_ts.map(|ts| e.created_at < ts).unwrap_or(true))
|
||||
.collect();
|
||||
journal_nodes.sort_by_key(|n| n.created_at);
|
||||
|
||||
let cutoff_idx = if let Some(cutoff) = oldest_msg_ts {
|
||||
let cutoff_ts = cutoff.timestamp();
|
||||
let mut idx = journal_nodes.len();
|
||||
for (i, node) in journal_nodes.iter().enumerate() {
|
||||
if node.created_at >= cutoff_ts {
|
||||
idx = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
idx
|
||||
} else {
|
||||
journal_nodes.len()
|
||||
};
|
||||
|
||||
let journal_budget = context::context_window() * 15 / 100;
|
||||
let mut entries = Vec::new();
|
||||
let mut total_tokens = 0;
|
||||
|
||||
for node in journal_nodes[..cutoff_idx].iter().rev() {
|
||||
let ts = chrono::DateTime::from_timestamp(node.created_at, 0);
|
||||
let ast = AstNode::memory(&node.key, &node.content)
|
||||
// Take entries within budget (they're newest-first, so reverse for display)
|
||||
for entry in filtered.iter() {
|
||||
let ts = chrono::DateTime::from_timestamp(entry.created_at, 0);
|
||||
let ast = AstNode::memory(&entry.key, &entry.content)
|
||||
.with_timestamp(ts.unwrap_or_else(chrono::Utc::now));
|
||||
let tok = ast.tokens();
|
||||
if total_tokens + tok > journal_budget && !entries.is_empty() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue