Skip to main content

Session

Struct Session 

Source
pub struct Session {
    pub id: String,
    pub title: Option<String>,
    pub created_at: DateTime<Utc>,
    pub updated_at: DateTime<Utc>,
    pub metadata: SessionMetadata,
    pub agent: String,
    pub messages: Vec<Message>,
    pub tool_uses: Vec<ToolUse>,
    pub usage: Usage,
    pub max_steps: Option<usize>,
    pub bus: Option<Arc<AgentBus>>,
}
Expand description

A conversation session.

See the session module docs for a usage overview.

Fields§

§id: String

UUID identifying this session on disk.

§title: Option<String>

Optional human-readable title. Auto-generated from the first user message when absent; see Session::generate_title.

§created_at: DateTime<Utc>

When the session was first created.

§updated_at: DateTime<Utc>

When the session was last modified.

§metadata: SessionMetadata

Durable session configuration.

Serialized before Self::messages so cheap workspace-match prefiltering (see [crate::session::header::SessionHeader]) can avoid lexing past the transcript.

§agent: String

Name of the agent persona that owns this session.

§messages: Vec<Message>

Ordered conversation transcript.

§tool_uses: Vec<ToolUse>

Per-tool-call audit records.

§usage: Usage

Aggregate token usage across all completions in this session.

§max_steps: Option<usize>

Maximum agentic loop steps. None falls back to DEFAULT_MAX_STEPS.

§bus: Option<Arc<AgentBus>>

Optional bus for publishing agent thinking/reasoning.

Implementations§

Source§

impl Session

Source

pub async fn new() -> Result<Self>

Create a new empty session rooted at the current working directory.

§Errors

Returns an error if the current working directory cannot be resolved.

§Examples
use codetether_agent::session::Session;

let session = Session::new().await.unwrap();
assert!(!session.id.is_empty());
assert_eq!(session.agent, "build");
assert!(session.messages.is_empty());
Source

pub fn with_bus(self, bus: Arc<AgentBus>) -> Self

Attach an agent bus for publishing agent thinking/reasoning events.

Source

pub fn apply_config( &mut self, config: &Config, registry: Option<&ProviderRegistry>, )

Seed session metadata from a loaded crate::config::Config.

Currently copies crate::config::Config::rlm into SessionMetadata::rlm so RLM compaction and tool-output routing honour user-configured thresholds, iteration limits, and model selectors.

Also attempts to resolve [RlmConfig::subcall_model] against the given provider registry. When resolution succeeds the resolved provider is cached on SessionMetadata (not serialised) so every AutoProcessContext built from this session can cheaply reference it. On failure the subcall provider is left as None and the resolution failure is logged.

Idempotent: re-applying the same config is a no-op.

§Examples
use codetether_agent::config::Config;
use codetether_agent::session::Session;

let cfg = Config::default();
let mut session = Session::new().await.unwrap();
session.apply_config(&cfg, None);
assert_eq!(session.metadata.rlm.mode, cfg.rlm.mode);
Source

pub fn resolve_subcall_provider(&mut self, registry: &ProviderRegistry)

Attempt to resolve [RlmConfig::subcall_model] against the given provider registry, storing the result on metadata.

Called by session helpers right before building an AutoProcessContext if subcall_provider is still None but subcall_model is configured. This deferred resolution avoids requiring the registry at session creation time.

§Errors

Does not return errors — resolution failure is logged.

Source

pub fn set_agent_name(&mut self, agent_name: impl Into<String>)

Set the agent persona owning this session. Also updates the provenance record so audit logs reflect the new agent.

Source

pub fn attach_worker_task_provenance(&mut self, worker_id: &str, task_id: &str)

Tag the session as having been dispatched by a specific A2A worker for a specific task.

Source

pub fn attach_claim_provenance(&mut self, claim: &ClaimProvenance)

Attach a claim-provenance record to the session’s execution provenance.

Source

pub fn add_message(&mut self, message: Message)

Append a message to the transcript and bump updated_at.

Source§

impl Session

Source

pub async fn load(id: &str) -> Result<Self>

Load an existing session by its UUID.

§Errors

Returns an error if the session file does not exist or the JSON is malformed.

Source

pub async fn last_for_directory(workspace: Option<&Path>) -> Result<Self>

Load the most recent session, optionally scoped to a workspace directory.

When workspace is Some, only considers sessions created in that directory. When None, returns the most recent session globally.

§Errors

Returns an error if no sessions exist (or, with workspace set, none match the requested directory).

Source

pub async fn last_for_directory_tail( workspace: Option<&Path>, window: usize, ) -> Result<TailLoad>

Like Self::last_for_directory but keeps only the last window messages and tool uses in memory, returning a TailLoad with the number of entries that were dropped. Use this when resuming very large sessions where the full transcript would exhaust memory.

Implementation: the entire scan runs on a single blocking thread. For each candidate (newest-mtime first) we do a cheap [SessionHeader] parse to compare metadata.directory; only the matching file pays for a full tail parse.

Source

pub async fn last() -> Result<Self>

Load the most recent session globally (unscoped).

Kept for legacy compatibility; prefer Session::last_for_directory.

Source

pub async fn save(&self) -> Result<()>

Persist the session to disk as JSON. Creates the sessions directory on demand.

Performance:

  • Serialization runs on the blocking thread pool so a large session doesn’t stall the async reactor during serde_json formatting.
  • Writes compact JSON (no pretty-printing): ~30% less CPU to serialize, ~30–40% smaller on disk, and correspondingly faster to load and mmap-scan on resume. Session files are machine-owned — humans never hand-edit them — so indentation is pure overhead.
  • Write is atomic (tmp + rename) so a crash mid-save leaves the previous session intact, and the mmap prefilter in [file_contains_finder] cannot observe a torn buffer.
Source

pub async fn delete(id: &str) -> Result<()>

Delete a session file by ID. No-op if the file does not exist.

Source§

impl Session

Source

pub async fn prompt(&mut self, message: &str) -> Result<SessionResult>

Execute a prompt and return the final text answer (non-streaming).

This loads the provider registry from Vault on every call, which is fine for one-shot CLI use but expensive for the TUI — the TUI uses Session::prompt_with_events with a shared registry instead.

§Errors

Returns an error if no providers are configured, the model cannot be resolved, or the agentic loop exhausts its retry budgets.

Source

pub async fn prompt_with_events( &mut self, message: &str, event_tx: Sender<SessionEvent>, registry: Arc<ProviderRegistry>, ) -> Result<SessionResult>

Process a user message with real-time event streaming for UI updates.

Accepts a pre-loaded ProviderRegistry to avoid re-fetching secrets from Vault on every message.

Source

pub async fn prompt_with_events_and_images( &mut self, message: &str, images: Vec<ImageAttachment>, event_tx: Sender<SessionEvent>, registry: Arc<ProviderRegistry>, ) -> Result<SessionResult>

Execute a prompt with optional image attachments and stream events.

Images must be base64-encoded data URLs.

Source§

impl Session

Source

pub async fn load_tail(id: &str, window: usize) -> Result<TailLoad>

Load a session by UUID, keeping only the last window messages and tool uses. Use window = 0 to drop all messages (cheap directory scan).

§Errors

Returns an error if the file cannot be opened or the JSON is malformed.

Source

pub async fn load_tail_from_path( path: PathBuf, window: usize, ) -> Result<TailLoad>

Load a session from an explicit path with a bounded message window.

Source§

impl Session

Source

pub async fn generate_title(&mut self) -> Result<()>

Generate a title from the first user message if one is not already set.

Source

pub async fn regenerate_title(&mut self) -> Result<()>

Regenerate the title from the first user message, even if already set.

Source

pub fn set_title(&mut self, title: impl Into<String>)

Set a custom title for the session.

Source

pub fn clear_title(&mut self)

Clear the title, allowing it to be regenerated on the next call to Session::generate_title.

Source

pub async fn on_context_change(&mut self, regenerate_title: bool) -> Result<()>

React to a context change (directory change, model change, etc.). Bumps updated_at and optionally regenerates the title.

Trait Implementations§

Source§

impl Clone for Session

Source§

fn clone(&self) -> Session

Returns a duplicate of the value. Read more
1.0.0 · Source§

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

Performs copy-assignment from source. Read more
Source§

impl Debug for Session

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'de> Deserialize<'de> for Session

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl Serialize for Session

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. 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<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> DynClone for T
where T: Clone,

Source§

fn __clone_box(&self, _: Private) -> *mut ()

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

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

Source§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
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> IntoRequest<T> for T

Source§

fn into_request(self) -> Request<T>

Wrap the input message T in a tonic::Request
Source§

impl<L> LayerExt<L> for L

Source§

fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>
where L: Layer<S>,

Applies the layer to a service and wraps it in Layered.
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: 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: 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> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> Serialize for T
where T: Serialize + ?Sized,

Source§

fn erased_serialize(&self, serializer: &mut dyn Serializer) -> Result<(), Error>

Source§

fn do_erased_serialize( &self, serializer: &mut dyn Serializer, ) -> Result<(), ErrorImpl>

Source§

impl<T> ServiceExt for T

Source§

fn map_response_body<F>(self, f: F) -> MapResponseBody<Self, F>
where Self: Sized,

Apply a transformation to the response body. Read more
Source§

fn trace_for_http(self) -> Trace<Self, SharedClassifier<ServerErrorsAsFailures>>
where Self: Sized,

High level tracing that classifies responses using HTTP status codes. Read more
Source§

fn trace_for_grpc(self) -> Trace<Self, SharedClassifier<GrpcErrorsAsFailures>>
where Self: Sized,

High level tracing that classifies responses using gRPC headers. Read more
Source§

fn follow_redirects(self) -> FollowRedirect<Self>
where Self: Sized,

Follow redirect resposes using the Standard policy. Read more
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<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

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

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<T> ErasedDestructor for T
where T: 'static,