pub struct TokenBudget { /* private fields */ }Expand description
Keep turns up to threshold_pct of the model’s context window.
Budget math (fixed in Step 18.1): the fullness figure anchors on the
backend’s last-reported prompt size — which already includes the system
prompt and ALL prior turns — plus a chars/4 estimate of content added or
removed since that report. The previous implementation summed
input + output per turn across history, double-counting every prior turn
in every later reading (the B3 baseline measured 5.4× inflation by turn
20), which forced spurious pruning. Without any backend report the figure
falls back to summing per-turn content estimates (each turn counted once).
Configure via [memory] provider = "token_budget". The budget is a
construction-time value injected by the caller (Step 18.2, #247) with
this precedence:
- explicit
[memory] context_tokens(a deliberate user override), - capability-derived (
max_ok_inputelsesafe_contextfrom the caller’s probe cache — newt-core deliberately has no dependency on the probe types, mirroring thewith_summarizerinjection), DEFAULT_CONTEXT_TOKENSwhen neither exists (fresh model).
The value is fixed for the provider’s lifetime: budgets refresh per session; mid-session capability ratchets are tracked live by the agentic loop’s own pre-send guard, not by this provider.
Implementations§
Source§impl TokenBudget
impl TokenBudget
pub fn new(max_tokens: u32, threshold_pct: f32) -> Self
Sourcepub fn with_estimation(self, est: TokenEstimation) -> Self
pub fn with_estimation(self, est: TokenEstimation) -> Self
Builder: set the token-estimation heuristic from [context.estimation].
Sourcepub fn with_budget(self, tokens: u32) -> Self
pub fn with_budget(self, tokens: u32) -> Self
Inject a resolved token budget (builder form of the max_tokens
constructor argument, mirroring Summarizing::with_summarizer).
Same ≥512 clamp as TokenBudget::new.
Step 18.2 (#247): this replaces the deleted from_config() path,
whose silent 8,192 fallback ignored empirical capability data. The
caller resolves the budget (explicit config override → capability
cache → DEFAULT_CONTEXT_TOKENS) and injects the value here.
Trait Implementations§
Source§impl MemoryProvider for TokenBudget
impl MemoryProvider for TokenBudget
Source§fn build_messages(&self, system_prompt: &str, new_task: &str) -> Vec<MemMessage>
fn build_messages(&self, system_prompt: &str, new_task: &str) -> Vec<MemMessage>
Source§fn sync_turn<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 mut self,
user: &'life1 str,
assistant: &'life2 str,
metrics: &'life3 TurnMetrics,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
fn sync_turn<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 mut self,
user: &'life1 str,
assistant: &'life2 str,
metrics: &'life3 TurnMetrics,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
Source§fn reset(&mut self)
fn reset(&mut self)
Source§fn restore_turns(&mut self, turns: &[ConversationTurn])
fn restore_turns(&mut self, turns: &[ConversationTurn])
Source§fn usage(&self) -> Option<(String, usize, usize)>
fn usage(&self) -> Option<(String, usize, usize)>
/memory command).
Returns (label, current, max) — e.g. ("turns", 12, 20).Source§fn initialize<'life0, 'life1, 'async_trait>(
&'life0 mut self,
_ctx: &'life1 SessionContext,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn initialize<'life0, 'life1, 'async_trait>(
&'life0 mut self,
_ctx: &'life1 SessionContext,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn system_prompt_block(&self) -> Option<String>
fn system_prompt_block(&self) -> Option<String>
Source§fn prefetch<'life0, 'life1, 'async_trait>(
&'life0 self,
_query: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn prefetch<'life0, 'life1, 'async_trait>(
&'life0 self,
_query: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn take_compaction_record(&mut self) -> Option<String>
fn take_compaction_record(&mut self) -> Option<String>
user = the marked message, assistant = empty, token
columns NULL — it is not a backend-measured turn) so a later restore
can rehydrate the same working-set shape via Self::restore_turns.
Default: None — providers that never compress mint nothing.Source§fn on_pre_compress<'life0, 'life1, 'async_trait>(
&'life0 self,
_messages: &'life1 [MemMessage],
) -> Pin<Box<dyn Future<Output = String> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn on_pre_compress<'life0, 'life1, 'async_trait>(
&'life0 self,
_messages: &'life1 [MemMessage],
) -> Pin<Box<dyn Future<Output = String> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
messages; return it as a string
to include in the compression summary. Return empty string for nothing.Source§fn on_session_end<'life0, 'life1, 'async_trait>(
&'life0 mut self,
_messages: &'life1 [MemMessage],
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn on_session_end<'life0, 'life1, 'async_trait>(
&'life0 mut self,
_messages: &'life1 [MemMessage],
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn replace_note(&mut self, _old_substring: &str, _new_text: &str) -> Result<()>
fn replace_note(&mut self, _old_substring: &str, _new_text: &str) -> Result<()>
old_substring with
new_text (Step 19.3 — the save_note tool’s replace action).
Default: NotesUnsupported, same routing contract as add_note.Source§fn remove_note(&mut self, _substring: &str) -> Result<()>
fn remove_note(&mut self, _substring: &str) -> Result<()>
substring (Step 19.3 —
the save_note tool’s remove action).
Default: NotesUnsupported, same routing contract as add_note.Auto Trait Implementations§
impl Freeze for TokenBudget
impl RefUnwindSafe for TokenBudget
impl Send for TokenBudget
impl Sync for TokenBudget
impl Unpin for TokenBudget
impl UnsafeUnpin for TokenBudget
impl UnwindSafe for TokenBudget
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
impl<T> ErasedDestructor for Twhere
T: 'static,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more