Skip to main content

Session

Struct Session 

Source
pub struct Session<'a> { /* private fields */ }
Expand description

The durable state of an agent session: the scoped tool catalogue, the resource-awareness map, and the conversation transcript — everything that persists across turns. A once-mode / per-event run is a session of exactly one turn (run_loop); a warm continue-session runs many turns over the same transcript, each new event appended via Session::deliver before another Session::run_turn.

Implementations§

Source§

impl<'a> Session<'a>

Source

pub fn prepare( servers: &'a [McpClient], input: &LoopInput, self_handler: &mut dyn SelfHandler, ) -> Result<Session<'a>, LoopAbort>

Assemble a session: the tool catalogue (MCP tools + self-tools, plus resource.read when resources exist), the resource awareness note, and the opening transcript (system prompt + seed + the instruction as the first user turn). Resources are split deliberately: listing them makes the model aware of what exists, while reading one is an explicit tool call, so a large resource enters the context only when actually wanted.

Source

pub fn refresh_tools( &mut self, self_handler: &mut dyn SelfHandler, ) -> Result<(), LoopAbort>

Rebuild the MCP side of the tool catalogue from the servers’ CURRENT tools/list. Called at a turn boundary after an inbound notifications/tools/list_changed, so a long-lived continue-session tracks a server whose tool set changed instead of holding a stale catalogue for its whole life. Self-tools and resource.read are re-merged and the transcript is untouched, so a refresh costs no context.

Source

pub fn tools_len(&self) -> usize

The current catalogue size (observability for the live refresh).

Source

pub fn tool_class(&self, name: &str) -> ToolClass

Classify a catalogue tool by its seam: a name routed to an MCP server is ToolClass::Mcp, dispatched back to that server; every other catalogue entry is agentd’s own ToolClass::SelfControl surface — the self-tools plus resource.read. The routing map IS the MCP-tool set, and the two classes are assembled by different code paths ([build_catalogue] versus the SelfHandler merge), which makes this an authoritative and testable boundary between “tools from a registered server” and “agentd’s own orchestration primitives”.

Callers must pass a name drawn from Session::tools: a name absent from the catalogue classifies as SelfControl, since it is by definition not a routed server tool, so classifying an arbitrary string is meaningless.

Source

pub fn tool_permitted(&self, name: &str) -> bool

Whether this session’s GRANT admits name. Every grant must admit it; an ungranted session — one with no parent narrowing — admits everything. The catalogue is already filtered, so this is a second gate at dispatch time, for the model that names a tool anyway: a hallucinated name, or one remembered from a transcript written when the catalogue was wider.

Source

pub fn deliver(&mut self, content: &str)

Append the next event as a new user turn — the delivery point for a warm continue-session. The transcript, which is the model’s memory of the session, carries forward, so the next turn continues the conversation rather than starting over.

Source

pub fn set_model(&mut self, model: &str)

Adopt a new model for subsequent turns. The transcript is UNTOUCHED — only the model dialed for the NEXT turn changes, and a turn already in flight runs to completion on the model it started with. The model is what each request’s model field carries.

Source

pub fn model(&self) -> &str

The current model dialed for the next turn. Used to decide whether a pending swap actually changes the model: an endpoint repoint that leaves the model alone needs no turn restart, since the output would match.

Source

pub fn transcript_len(&self) -> usize

The number of transcript messages so far — a cheap pre-turn marker for the restart-turn policy: snapshot this before a turn, then truncate_transcript back to it to discard the swapped turn’s appended messages and re-run from the same pre-turn state.

Source

pub fn truncate_transcript(&mut self, len: usize)

Truncate the transcript back to len for a restart-turn: drop every message a discarded turn appended, restoring the exact pre-turn transcript so the turn can be re-run on the new model. A no-op when len is already at or past the current length — this never grows the transcript, so a stale marker cannot resurrect dropped messages.

Source

pub fn run_turn( &mut self, intel: &IntelClient, self_handler: &mut dyn SelfHandler, log: &Logger, budget: &mut Budget, cancel: Option<&Arc<AtomicBool>>, ) -> Result<(Outcome, Usage), LoopAbort>

Run one turn: the ReAct loop over the persistent transcript until a terminal status, bounded by budget. cancel is polled at each turn boundary. Every assistant/tool message (including the final answer) is appended to the transcript, so a subsequent turn continues the same conversation.

Returns the turn’s Outcome together with the turn’s token Usage — the sum of every model call in this turn. The control layer rolls this DELTA up to the supervisor as crate::subagent::protocol::AgentMsg::Usage, which is what makes hierarchical token accounting (agentd_tokens_total) add up. The loop itself never touches the control channel: the up handle stays in control.rs, so the loop stays runnable in-process and in a child alike.

Auto Trait Implementations§

§

impl<'a> !RefUnwindSafe for Session<'a>

§

impl<'a> !UnwindSafe for Session<'a>

§

impl<'a> Freeze for Session<'a>

§

impl<'a> Send for Session<'a>

§

impl<'a> Sync for Session<'a>

§

impl<'a> Unpin for Session<'a>

§

impl<'a> UnsafeUnpin for Session<'a>

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> 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, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

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