From 4bdc7ae11249487f0b47254c35bd7fcae32e4d44 Mon Sep 17 00:00:00 2001 From: Kent Overstreet Date: Thu, 2 Apr 2026 02:29:48 -0400 Subject: [PATCH] Journal budget: count from structured data, not string matching Count journal tokens directly from Vec instead of scanning message text for prefix strings. Type system, not string typing. Co-Authored-By: Proof of Concept --- src/agent/runner.rs | 32 +++++++++++--------------------- 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/src/agent/runner.rs b/src/agent/runner.rs index fd027ea..7308504 100644 --- a/src/agent/runner.rs +++ b/src/agent/runner.rs @@ -186,7 +186,9 @@ impl Agent { let count = |s: &str| self.tokenizer.encode_with_special_tokens(s).len(); let mut id_tokens: usize = 0; - let mut jnl_tokens: usize = 0; + let jnl_tokens: usize = self.context.journal.iter() + .map(|e| count(&e.content)) + .sum(); let mut conv_tokens: usize = 0; let mut in_conversation = false; @@ -198,26 +200,13 @@ impl Agent { continue; } - match msg.role { - Role::System => id_tokens += tokens, - Role::User => { - let text = msg.content_text(); - if text.starts_with("[Earlier in this conversation") { - jnl_tokens += tokens; - } else if text.starts_with("Your context was just rebuilt") { - jnl_tokens += tokens; - } else if jnl_tokens == 0 && conv_tokens == 0 { - // Personality context — part of identity - id_tokens += tokens; - } else { - in_conversation = true; - conv_tokens += tokens; - } - } - _ => { - in_conversation = true; - conv_tokens += tokens; - } + if in_conversation { + conv_tokens += tokens; + } else if msg.role == Role::System || (!in_conversation && conv_tokens == 0) { + id_tokens += tokens; + } else { + in_conversation = true; + conv_tokens += tokens; } } @@ -851,6 +840,7 @@ impl Agent { } self.context.journal = entries; + dbg_log!("[journal] context.journal now has {} entries", self.context.journal.len()); } /// Re-render the context message in self.messages from live ContextState.