Skip to main content

SubAgentSession

Struct SubAgentSession 

Source
pub struct SubAgentSession<State: Send + Sync, Ctx: Send + Sync = ()> { /* private fields */ }
Expand description

A persistent, reusable conversation with a single SubAgent.

Where SubAgentTool runs a fresh, stateless child run per tool call, a SubAgentSession keeps the same underlying SubAgent (and therefore the same AgentHarness) alive across multiple turns and retains the full conversation transcript between them. This is post-completion reuse: the child run finishes normally, the orchestrator inspects/awaits human input, then calls the same sub-agent again — distinct from steering, which interrupts a still-running agent.

§Human-in-the-loop reuse flow

  1. send the first input (e.g. a user question). The session appends it to the retained transcript, runs the sub-agent over the full transcript, and folds the resulting assistant (and any tool) messages back in.
  2. Inspect the returned [AgentRun] and obtain human input out-of-band.
  3. Wrap that human input as a Message::user and send it again. Because the prior turn’s messages are still in the transcript, the sub-agent answers with full context — without being killed and restarted.

Each send after the first emits AgentEvent::SubAgentReused (alongside the usual SubAgentStarted/SubAgentCompleted bracket) so reuse is observable in the event stream.

Implementations§

Source§

impl<State: Send + Sync, Ctx: Send + Sync> SubAgentSession<State, Ctx>

Source

pub fn new(subagent: Arc<SubAgent<State, Ctx>>) -> Self

Creates a session that reuses subagent across turns.

The child runs at depth 1 by default (caller parent_depth = 0); use Self::with_parent_depth to express deeper nesting.

Source

pub fn from_subagent(subagent: SubAgent<State, Ctx>) -> Self

Creates a session from an owned SubAgent, wrapping it in an Arc.

Source

pub fn with_events(self, events: EventSink) -> Self

Routes the reuse lifecycle and the child run’s own events onto events so an external observer (or testkit recorder) sees every send. Returns self for chaining.

Source

pub fn with_parent_depth(self, parent_depth: usize) -> Self

Sets the caller depth the child runs at; the child run is created at parent_depth + 1. Returns self for chaining.

Source

pub fn subagent(&self) -> &Arc<SubAgent<State, Ctx>>

Returns the reused sub-agent. The same Arc is shared across every send, so this is how callers confirm the harness was never rebuilt.

Source

pub fn transcript(&self) -> &[Message]

Returns the accumulated conversation transcript carried across sends.

Source

pub fn turns(&self) -> usize

Returns the number of completed sends (turns).

Source

pub fn reset(&mut self)

Clears the retained transcript and turn counter, so the next Self::send starts a fresh conversation (re-seeding the fixed system prompt). The underlying SubAgent/harness is left untouched and still reused.

Source

pub async fn send( &mut self, state: &State, ctx_data: Ctx, input: Vec<Message>, ) -> Result<AgentRun>

Runs the reused sub-agent for one turn over the FULL accumulated transcript, then folds the produced assistant/tool messages back into the transcript so the next send continues with full context.

input (typically a single Message::user carrying human input) is appended to the retained transcript before the run. On the first send the sub-agent’s fixed SubAgent::with_system_prompt is prepended once. The same underlying harness is reused on every call — nothing is reconstructed.

§Errors

Returns TinyAgentsError::SubAgentDepth if the child depth would exceed the configured max_depth, or any error surfaced by the child agent loop.

Auto Trait Implementations§

§

impl<State, Ctx = ()> !RefUnwindSafe for SubAgentSession<State, Ctx>

§

impl<State, Ctx = ()> !UnwindSafe for SubAgentSession<State, Ctx>

§

impl<State, Ctx> Freeze for SubAgentSession<State, Ctx>

§

impl<State, Ctx> Send for SubAgentSession<State, Ctx>

§

impl<State, Ctx> Sync for SubAgentSession<State, Ctx>

§

impl<State, Ctx> Unpin for SubAgentSession<State, Ctx>

§

impl<State, Ctx> UnsafeUnpin for SubAgentSession<State, Ctx>

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, 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 = 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.