pub struct SessionWriter { /* private fields */ }Expand description
Writer for appending messages to a JSONL session file.
Opens (or creates) a .jsonl file in append mode and writes one
JSON object per line. A companion .meta.json file tracks session
metadata and is updated on finish().
Implementations§
Source§impl SessionWriter
impl SessionWriter
Sourcepub fn create(
workspace: &Path,
goal: &str,
model: &str,
provider: &str,
) -> Result<Self>
pub fn create( workspace: &Path, goal: &str, model: &str, provider: &str, ) -> Result<Self>
Create a new session in the given workspace directory.
The session directory is <workspace>/.recursive/sessions/<workspace-slug>/<session-id>/.
The .jsonl file and .meta.json are placed inside that directory.
Equivalent to create_with_tools(workspace, goal, model, provider, &[]);
no tool_registry_hash is stamped in the meta. Prefer
create_with_tools whenever the caller has a ToolRegistry,
so that recursive resume (g151) can detect tool drift.
Sourcepub fn create_with_tools(
workspace: &Path,
goal: &str,
model: &str,
provider: &str,
tool_specs: &[ToolSpec],
preset: Option<&str>,
) -> Result<Self>
pub fn create_with_tools( workspace: &Path, goal: &str, model: &str, provider: &str, tool_specs: &[ToolSpec], preset: Option<&str>, ) -> Result<Self>
Create a new session, stamping a BLAKE3 hash of tool_specs
into .meta.json as tool_registry_hash. The hash is what
recursive resume validates against the current registry —
if they differ, resume aborts (g151).
Pass &[] for tool_specs if the caller has no registry
(e.g. tests, ad-hoc tools), in which case the hash is None
and resume will warn but not abort.
preset is the resolved provider preset id (e.g. “deepseek”)
from the active Config. Pass None for pre-preset-config
callers or when the user did not opt in; the field is
Option<String> and skip_serializing_if = "Option::is_none"
keeps the on-disk format clean.
Sourcepub fn open_existing(session_dir: &Path) -> Result<Self>
pub fn open_existing(session_dir: &Path) -> Result<Self>
Re-open an existing session directory for appending.
Reads the existing .meta.json to recover message_count,
created_at, goal, model, and provider. The
tool_registry_hash is not re-validated here — the
caller (typically the Cmd::Resume handler) must have done
that already.
Acquires SessionLock::acquire(session_dir) so a second
resume on the same session is refused while this writer is
alive.
Continues the msg_NNN sequence from where the existing
transcript left off (so the first append() after
open_existing does not collide with prior messages).
Sourcepub fn append(
&mut self,
msg: &Message,
parent_uuid_override: Option<&str>,
usage: Option<&UsageMeta>,
) -> Result<String>
pub fn append( &mut self, msg: &Message, parent_uuid_override: Option<&str>, usage: Option<&UsageMeta>, ) -> Result<String>
Append a message to the JSONL file.
Returns the UUID assigned to this message entry. Bumps
SessionMeta.updated_at on every assistant or user
message (skipping per-tool-result writes is an
optimisation — a turn with N tool calls would otherwise
rewrite the meta file 2N times). The “most-recent” shortcut
in recursive resume (g151) relies on updated_at being
live for crashed sessions.
parent_uuid_override — if Some, this UUID is used as parent_uuid
for the new entry instead of self.last_uuid. Use this for subagent
messages that branch off a specific parent agent message (g155).
usage — token usage to attach to this entry (non-None for assistant
messages, g156).
Sourcepub fn append_with_audit(
&mut self,
msg: &Message,
audit: Option<AuditMeta>,
parent_uuid_override: Option<&str>,
usage: Option<&UsageMeta>,
) -> Result<String>
pub fn append_with_audit( &mut self, msg: &Message, audit: Option<AuditMeta>, parent_uuid_override: Option<&str>, usage: Option<&UsageMeta>, ) -> Result<String>
Append a message with optional audit metadata (Goal 153).
audit should only be Some for Role::Tool messages.
Sourcepub fn write_compact_boundary(
&mut self,
turn: u32,
compacted_count: usize,
summary_uuid: Option<&str>,
) -> Result<()>
pub fn write_compact_boundary( &mut self, turn: u32, compacted_count: usize, summary_uuid: Option<&str>, ) -> Result<()>
Write a compact_boundary system entry directly to the JSONL (g157).
Called by SessionPersistenceSink when it receives a
AgentEvent::CompactionBoundary event. The entry is written outside
the normal append flow so it does not increment message_count or
advance the UUID chain.
Sourcepub fn finish(&mut self, status: &str) -> Result<()>
pub fn finish(&mut self, status: &str) -> Result<()>
Finalise the session: flush the writer and update the meta file with the final message count, status, prompts, and cumulative cost.
Sourcepub fn set_name(&mut self, name: impl Into<String>)
pub fn set_name(&mut self, name: impl Into<String>)
Set an optional human-readable display name for this session.
The name is persisted to .meta.json on the next finish() call.
Sourcepub fn session_id(&self) -> &str
pub fn session_id(&self) -> &str
Return the session ID.
Sourcepub fn session_dir(&self) -> &Path
pub fn session_dir(&self) -> &Path
Return the session directory path.
Sourcepub fn message_count(&self) -> u64
pub fn message_count(&self) -> u64
Return the number of messages written so far.
Auto Trait Implementations§
impl Freeze for SessionWriter
impl RefUnwindSafe for SessionWriter
impl Send for SessionWriter
impl Sync for SessionWriter
impl Unpin for SessionWriter
impl UnsafeUnpin for SessionWriter
impl UnwindSafe for SessionWriter
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<A, B, T> HttpServerConnExec<A, B> for Twhere
B: Body,
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