pub struct NoteStore { /* private fields */ }Expand description
Persistent agent notes at ~/.newt/NOTES.md.
Notes are read once at session start and frozen into the system prompt
so the model’s prefix cache stays valid. Mid-session writes (via
/remember <fact>) update the file but NOT the system prompt block —
changes take effect next session.
Modelled on hermes-agent’s MemoryStore (MEMORY.md pattern).
Implementations§
Source§impl NoteStore
impl NoteStore
pub const DEFAULT_CHAR_LIMIT: usize = 2_200
pub fn new(path: impl Into<PathBuf>, char_limit: usize) -> Self
Sourcepub fn default_path() -> Self
pub fn default_path() -> Self
Create at the default location ~/.newt/NOTES.md.
pub fn is_empty(&self) -> bool
Sourcepub fn body_by_id(&self, id: &str) -> Option<&str>
pub fn body_by_id(&self, id: &str) -> Option<&str>
The verbatim body of the note addressed by id — the by-id read the
memory_fetch tool’s note:<id> resolver needs (progressive-disclosure
memory, Workstream A MVP, #319). id is the 1-based entry number the
memory index renders (the same numbering Self::numbered_listing and
the curator error already show, so the model fetches an id it was
shown). Returns None for a non-positive, non-numeric, or
out-of-range id — labelled absence, never an error.
Sourcepub fn index_entries(&self) -> Vec<(usize, &str)>
pub fn index_entries(&self) -> Vec<(usize, &str)>
(id, first-line title) for every note entry, in order — what the
budgeted memory index lists (titles/ids, never bodies). id is the
1-based entry number Self::body_by_id resolves; the title is the
entry’s first non-empty line, the human-readable hint the model uses to
decide whether to memory_fetch the body.
pub fn char_usage(&self) -> (usize, usize)
Sourcepub fn add(&mut self, fact: &str) -> Result<()>
pub fn add(&mut self, fact: &str) -> Result<()>
Add an entry. Over-budget adds fail with the full current entry list
(see Self::over_budget_error). Exact duplicates are a no-op.
Runs the write-time security scan (crate::notes_scan::scan_note)
before anything else can succeed — the scan precedes even the
duplicate no-op so malicious text never gets a silent Ok.
Sourcepub fn replace(&mut self, old_substr: &str, new_text: &str) -> Result<()>
pub fn replace(&mut self, old_substr: &str, new_text: &str) -> Result<()>
Replace the single entry containing old_substr with new_text.
Exactly one entry must match; the result must fit the char budget.
The replacement text goes through the same write-time security scan
as Self::add — replace is a write path, not a loophole.
Trait Implementations§
Source§impl MemoryProvider for NoteStore
impl MemoryProvider for NoteStore
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 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 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 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.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 reset(&mut self)
fn reset(&mut self)
Source§fn restore_turns(&mut self, _turns: &[ConversationTurn])
fn restore_turns(&mut self, _turns: &[ConversationTurn])
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,
Auto Trait Implementations§
impl Freeze for NoteStore
impl RefUnwindSafe for NoteStore
impl Send for NoteStore
impl Sync for NoteStore
impl Unpin for NoteStore
impl UnsafeUnpin for NoteStore
impl UnwindSafe for NoteStore
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