pub struct Session {
pub meta: SessionMeta,
pub path: PathBuf,
}Fields§
§meta: SessionMeta§path: PathBufImplementations§
Source§impl Session
impl Session
Sourcepub fn default_dir() -> Result<PathBuf>
pub fn default_dir() -> Result<PathBuf>
Where transcripts live: ~/.mecha/sessions, or $MECHA_SESSION_DIR.
pub fn create(dir: &Path, meta: SessionMeta) -> Result<Self>
pub fn new_id() -> String
pub fn append(&self, record: &Record) -> Result<()>
pub fn append_messages(&self, messages: &[Message]) -> Result<()>
Sourcepub fn record_run(&self, before: &[Message], after: &[Message]) -> Result<()>
pub fn record_run(&self, before: &[Message], after: &[Message]) -> Result<()>
Record what a run did to the conversation, given the messages it started from.
before must be what the file already holds — every front-end has
appended the opening user message (and, resumed, the loaded history)
before the run starts. When the run only appended, the new tail is
appended here too. When it rewrote what was already recorded —
compaction, eviction, thinning, all of which edit earlier messages in
place — a Record::Rewrite carries the whole current list instead,
because slicing a rewritten transcript records a lie: the old head
stays in the file, the rebuilt one (summary included) never lands.
Comparison, not a flag from the loop: any mutation the loop grows later is caught by construction, and the clone this costs is one more beside the one the loop already pays per request.
Sourcepub fn load(path: &Path) -> Result<(SessionMeta, Conversation)>
pub fn load(path: &Path) -> Result<(SessionMeta, Conversation)>
Read a transcript back, taint included.
Unparseable lines are skipped rather than failing the load — a truncated final line is the normal result of a killed process.
Sourcepub fn taint_timeline(path: &Path) -> Result<TaintTimeline>
pub fn taint_timeline(path: &Path) -> Result<TaintTimeline>
The taint checkpoints of a transcript, positioned against its messages.
Every front-end appends a Record::Taint checkpoint after the
messages of the run it describes, so the checkpoint that covers a
message is the first one written after it — and by then the taint of
everything earlier in that run, hostile fetches included, has merged
in. That ordering is what makes TaintTimeline::covering safe to
gate on: it can over-taint a message (a fetch later in the same run
counts against it), never under-taint one.
Sourcepub fn run_configs(path: &Path) -> Result<Vec<RunConfig>>
pub fn run_configs(path: &Path) -> Result<Vec<RunConfig>>
Every run configuration in a transcript, in the order the runs happened.
A replay driver needs this per run rather than per session: resuming under different flags is a normal thing to do, and the turns before and after are not comparable. An empty result means a transcript written before this was recorded — which cannot be replayed faithfully, because the system prompt and tool list that shaped it are gone.
Sourcepub fn peek_meta(path: &Path) -> Option<SessionMeta>
pub fn peek_meta(path: &Path) -> Option<SessionMeta>
The header alone, without parsing the rest of the file.
Listing goes through this rather than Session::load so mecha sessions stays O(number of sessions) instead of O(total transcript
bytes) — with reflect-on-close recording every interaction, the full
parse re-read the whole store to print one line per file. The header
is the first record create writes; a file whose first record is
anything else is not a session this process wrote, and is skipped
exactly as load’s no-header error skipped it.