WIP: ContextEntry/ContextSection data structures for incremental token counting

New types — not yet wired to callers:

- ContextEntry: wraps ConversationEntry with cached token count and
  timestamp
- ContextSection: named group of entries with cached token total.
  Private entries/tokens, read via entries()/tokens().
  Mutation via push(entry), set(index, entry), del(index).
- ContextState: system/identity/journal/conversation sections + working_stack
- ConversationEntry::System variant for system prompt entries

Token counting happens once at push time. Sections maintain their
totals incrementally via push/set/del. No more recomputing from
scratch on every budget check.

Does not compile — callers need updating.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
Kent Overstreet 2026-04-07 20:15:31 -04:00
parent 776ac527f1
commit 62996e27d7
10 changed files with 450 additions and 403 deletions

View file

@ -518,12 +518,12 @@ impl Subconscious {
pub async fn trigger(&mut self, agent: &Arc<tokio::sync::Mutex<Agent>>) {
let (conversation_bytes, memory_keys) = {
let ag = agent.lock().await;
let bytes = ag.context.entries.iter()
.filter(|e| !e.is_log() && !e.is_memory())
.map(|e| e.message().content_text().len() as u64)
let bytes = ag.context.conversation.entries().iter()
.filter(|ce| !ce.entry.is_log() && !ce.entry.is_memory())
.map(|ce| ce.entry.message().content_text().len() as u64)
.sum::<u64>();
let keys: Vec<String> = ag.context.entries.iter().filter_map(|e| {
if let ConversationEntry::Memory { key, .. } = e {
let keys: Vec<String> = ag.context.conversation.entries().iter().filter_map(|ce| {
if let ConversationEntry::Memory { key, .. } = &ce.entry {
Some(key.clone())
} else { None }
}).collect();
@ -550,7 +550,7 @@ impl Subconscious {
let mut forked = conscious.fork(auto.tools.clone());
forked.provenance = format!("agent:{}", auto.name);
let fork_point = forked.context.entries.len();
let fork_point = forked.context.conversation.len();
let shared_forked = Arc::new(tokio::sync::Mutex::new(forked));
self.agents[idx].forked_agent = Some(shared_forked.clone());