Journal budget: count from structured data, not string matching

Count journal tokens directly from Vec<JournalEntry> instead of
scanning message text for prefix strings. Type system, not string
typing.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
Kent Overstreet 2026-04-02 02:29:48 -04:00
parent 5526a26d4c
commit 4bdc7ae112

View file

@ -186,7 +186,9 @@ impl Agent {
let count = |s: &str| self.tokenizer.encode_with_special_tokens(s).len(); let count = |s: &str| self.tokenizer.encode_with_special_tokens(s).len();
let mut id_tokens: usize = 0; 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 conv_tokens: usize = 0;
let mut in_conversation = false; let mut in_conversation = false;
@ -198,26 +200,13 @@ impl Agent {
continue; continue;
} }
match msg.role { if in_conversation {
Role::System => id_tokens += tokens, conv_tokens += tokens;
Role::User => { } else if msg.role == Role::System || (!in_conversation && conv_tokens == 0) {
let text = msg.content_text(); id_tokens += tokens;
if text.starts_with("[Earlier in this conversation") { } else {
jnl_tokens += tokens; in_conversation = true;
} else if text.starts_with("Your context was just rebuilt") { conv_tokens += tokens;
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;
}
} }
} }
@ -851,6 +840,7 @@ impl Agent {
} }
self.context.journal = entries; 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. /// Re-render the context message in self.messages from live ContextState.