Skip to main content

ConversationManager

Struct ConversationManager 

Source
pub struct ConversationManager { /* private fields */ }
Expand description

Manages conversation persistence for a project

Implementations§

Source§

impl ConversationManager

Source

pub fn new(project_dir: impl AsRef<Path>) -> Result<Self>

Create a new conversation manager for a project directory

§Errors

Creating .mermaid/conversations under project_dir — a read-only or unwritable project. It is created here, so the later load and list paths can treat an unreadable directory as “no conversations” rather than a failure.

Source

pub fn append_session_events( &self, snapshot: &ConversationHistory, events: &[SessionEvent], ) -> Result<()>

Append session events for snapshot to its .jsonl log, creating the log (with a backfill from the snapshot) on first touch. Called by the persistence chain BEFORE the snapshot rewrite, so the history lands before the file it explains is overwritten.

§Errors

An id that would escape the conversations dir, and the append I/O itself. The caller treats a failure as a warning: the snapshot save must still run, and the log self-heals on the next save.

Source

pub fn event_log_path(&self, id: &str) -> PathBuf

Where a session’s event log lives. The compaction bookkeeping row records this instead of a per-compaction archive file: the dropped messages are the log’s earlier message events.

Source

pub fn read_session_events(&self, id: &str) -> Result<Option<Vec<SessionEvent>>>

Read a session’s log as EVENTS rather than folding it into a conversation — for readers that want the history in the order it happened instead of the state it produced.

The daemon’s subscribe_task catch-up is that reader: a mid-run attach replays these onto the RunEvent wire so a subscriber joining at minute nine learns what the first nine produced. Ok(None) when there is no readable log; a torn tail yields the prefix, exactly as a fold does.

§Errors

An id that would escape the conversations dir, and read I/O on the log file. A log that is absent, over the cap, or newer-format is Ok(None), not an error.

Source

pub fn fold_conversation_from_log( &self, id: &str, ) -> Result<Option<ConversationHistory>>

Rebuild a conversation from its event log — the recovery source when the snapshot is missing or will not parse. Ok(None) when there is no (foldable) log.

§Errors

An id that would escape the conversations dir, and read I/O on the log file. A log that is absent, capped, newer-format, or headerless is Ok(None), not an error.

Source

pub fn save_conversation( &self, conversation: &ConversationHistory, ) -> Result<()>

Save a conversation to disk

§Errors

An id that would escape the conversations dir, serializing the conversation, and the atomic 0600 write. Two cases that look like failures are Ok: a message-less conversation is deliberately not persisted, and a concurrent writer detected through the (mtime, len) baseline diverts this copy to a .conflict sibling and warns instead of overwriting. The .meta sidecar is best-effort and never fails the save.

Source

pub fn load_conversation(&self, id: &str) -> Result<ConversationHistory>

Load a specific conversation by ID

§Errors

An id that would escape the conversations dir, a file that is missing, unreadable, or past the size cap, JSON that does not parse, and a parsed id that would itself traverse — checked separately, because that field is on-disk state that drives later saves.

Source

pub fn load_last_conversation(&self) -> Result<Option<ConversationHistory>>

Load the most recent valid conversation.

Iterates files newest-first by mtime and returns the first that reads, parses, and has a valid id — skipping (with a warning) any unreadable, unparseable, or traversing-id file. Mirrors list_conversations’s tolerance so one corrupt/partial file (e.g. a crash mid-write) can’t make --continue hard-fail; it falls back to the next-newest valid conversation.

§Errors

In practice none: an unreadable conversations dir and every unreadable, oversized, unparseable, or traversing-id file are skipped with a warning, and running out of candidates is Ok(None). The Result is kept for callers that already handle one and so this can grow a real failure later.

Source

pub fn list_conversations(&self) -> Result<Vec<ConversationHistory>>

List all conversations in the project

§Errors

In practice none, and deliberately: an unreadable directory yields an empty list, and any file that will not read or parse is skipped, so one corrupt transcript cannot empty the picker.

Source

pub fn list_conversation_metas(&self) -> Result<Vec<ConversationMeta>>

Fast session list: read each <id>.meta sidecar; for a session that lacks a (valid) one — older, or written by a pre-sidecar build — fall back to fully parsing its <id>.json. Message-less sessions are skipped. Newest-first. Cheaper than Self::list_conversations for display-only paths.

§Errors

In practice none, matching Self::list_conversations: an unreadable directory yields an empty list, and a sidecar that will not read or parse falls through to parsing its <id>.json, which is itself skipped if that fails too.

Source

pub fn delete_conversation(&self, id: &str) -> Result<()>

Delete a conversation (and its metadata sidecar).

§Errors

An id that would escape the conversations dir, and removing the <id>.json itself. An id with no file is Ok, and the .meta sidecar and the session scratch dir are cleaned up best-effort — neither can fail the delete.

Source

pub fn conversations_dir(&self) -> &Path

Get the conversations directory path

Trait Implementations§

Source§

impl Clone for ConversationManager

Source§

fn clone(&self) -> ConversationManager

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Send + Sync>

Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more