Split context_state_summary: ContextBudget for compaction, UI-only for display
context_state_summary() was used for both compaction decisions (just needs token counts) and debug screen display (needs full tree with labels). Split into: - Agent::context_budget() -> ContextBudget: cheap token counting by category, used by compact(), restore_from_log(), mind event loop - ContextBudget::format(): replaces sections_budget_string() which fragily pattern-matched on section name strings - context_state_summary(): now UI-only, formatting code stays here Also extracted entry_sections() as shared helper with include_memories param — false for context_state_summary (memories have own section), true for conversation_sections_from() (subconscious screen shows all). Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
parent
9e49398689
commit
cf1c64f936
4 changed files with 130 additions and 86 deletions
|
|
@ -336,33 +336,29 @@ impl ContextState {
|
|||
}
|
||||
}
|
||||
|
||||
/// Total tokens used across all context sections.
|
||||
pub fn sections_used(sections: &[ContextSection]) -> usize {
|
||||
sections.iter().map(|s| s.tokens).sum()
|
||||
/// Token budget per context category — cheap to compute, no formatting.
|
||||
pub struct ContextBudget {
|
||||
pub system: usize,
|
||||
pub identity: usize,
|
||||
pub journal: usize,
|
||||
pub memory: usize,
|
||||
pub conversation: usize,
|
||||
}
|
||||
|
||||
/// Budget status string derived from context sections.
|
||||
pub fn sections_budget_string(sections: &[ContextSection]) -> String {
|
||||
let window = context_window();
|
||||
if window == 0 { return String::new(); }
|
||||
let used: usize = sections.iter().map(|s| s.tokens).sum();
|
||||
let free = window.saturating_sub(used);
|
||||
let pct = |n: usize| if n == 0 { 0 } else { ((n * 100) / window).max(1) };
|
||||
let parts: Vec<String> = sections.iter()
|
||||
.map(|s| {
|
||||
// Short label from section name
|
||||
let label = match s.name.as_str() {
|
||||
n if n.starts_with("System") => "sys",
|
||||
n if n.starts_with("Personality") => "id",
|
||||
n if n.starts_with("Journal") => "jnl",
|
||||
n if n.starts_with("Working") => "stack",
|
||||
n if n.starts_with("Memory") => "mem",
|
||||
n if n.starts_with("Conversation") => "conv",
|
||||
_ => return String::new(),
|
||||
};
|
||||
format!("{}:{}%", label, pct(s.tokens))
|
||||
})
|
||||
.filter(|s| !s.is_empty())
|
||||
.collect();
|
||||
format!("{} free:{}%", parts.join(" "), pct(free))
|
||||
impl ContextBudget {
|
||||
pub fn total(&self) -> usize {
|
||||
self.system + self.identity + self.journal + self.memory + self.conversation
|
||||
}
|
||||
|
||||
pub fn format(&self) -> String {
|
||||
let window = context_window();
|
||||
if window == 0 { return String::new(); }
|
||||
let used = self.total();
|
||||
let free = window.saturating_sub(used);
|
||||
let pct = |n: usize| if n == 0 { 0 } else { ((n * 100) / window).max(1) };
|
||||
format!("sys:{}% id:{}% jnl:{}% mem:{}% conv:{}% free:{}%",
|
||||
pct(self.system), pct(self.identity), pct(self.journal),
|
||||
pct(self.memory), pct(self.conversation), pct(free))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue