Skip to main content

ActiveSession

Struct ActiveSession 

Source
pub struct ActiveSession<'runner, Link>
where Link: HasPeer<Agent>,
{ /* private fields */ }
Expand description

Stable protocol v1 active session that lets you send prompts and receive updates.

The session owns a stream of SessionMessages: the requests and notifications the agent sends for this session, and the responses to prompts sent with send_prompt or send_prompt_blocks.

This handle covers prompting and reading the stream only. It has no helpers for session/cancel, session/set_mode, session/set_config_option, session/close or session/fork. Send those messages through connection with session_id, for example session.connection().send_notification_to(Agent, CancelNotification::new(session.session_id().clone())).

The 'runner lifetime represents the span during which session support runners (such as MCP servers) are active. When created via SessionBuilder::start_session, this is 'static because the runners are spawned into background tasks. When created via SessionBuilder::run_until, this is tied to the closure scope, preventing Self::proxy_remaining_messages from being called (since the runners would stop when the closure returns).

Implementations§

Source§

impl<Link> ActiveSession<'_, Link>
where Link: HasPeer<Agent>,

Source

pub fn session_id(&self) -> &SessionId

Access the session ID.

Source

pub fn connection(&self) -> &ConnectionTo<Link>

Access the underlying connection context used to communicate with the agent.

Source

pub fn send_prompt(&mut self, prompt: impl ToString) -> Result<(), Error>

Send a text prompt to the agent.

Read the agent’s output with read_update or read_to_string. The session/prompt response, or the error the agent answered with, arrives on the same stream as SessionMessage::PromptResponse.

Source

pub fn send_prompt_blocks( &mut self, prompt: Vec<ContentBlock>, ) -> Result<(), Error>

Send a prompt made of arbitrary content blocks to the agent.

Content other than text and resource links needs the matching promptCapabilities entry from the agent’s initialize response. Like send_prompt, the response arrives on the update stream as SessionMessage::PromptResponse.

Source

pub async fn read_update(&mut self) -> Result<SessionMessage, Error>

Read the next item on the session’s update stream: a message the agent sent for this session, or the response to a prompt.

Source

pub async fn read_to_string(&mut self) -> Result<String, Error>

Read updates until the next prompt response and return the text of the agent’s message chunks.

Ignores non-text updates. Requests from the agent that reach the session, such as session/request_permission, are answered with a method not found error (-32601). Use read_update instead to answer them yourself. If the agent answers the prompt with an error, this returns that error.

Source§

impl<Link> ActiveSession<'static, Link>
where Link: HasPeer<Agent>,

Source

pub fn proxy_remaining_messages(self) -> Result<(), Error>
where Link: HasPeer<Client>,

Proxy all remaining messages for this session between client and agent.

Use this when you want to inject MCP servers into a session but don’t need to actively interact with it after setup. The session messages will be proxied between client and agent automatically.

This consumes the ActiveSession since you’re giving up active control.

This method is only available on ActiveSession<'static, _> (from SessionBuilder::start_session) because it requires the session’s runners to outlive the method call.

§Message Ordering Guarantees

This method ensures proper handoff from active session mode to proxy mode without losing or reordering messages:

  1. Stop the session handler - Deactivate the handler that routes messages to update_rx. After this, no new messages will be queued.
  2. Close the channel - Drop update_tx so we can detect when the channel is fully drained.
  3. Drain queued messages - Forward any messages that were already queued in update_rx to the client, preserving order.
  4. Install proxy handler - Now that all queued messages are forwarded, install the proxy handler to handle future messages.
  5. Remove the session handler - Drop its registration.

This sequence prevents the race condition where messages could be delivered out of order or lost during the transition. Messages that arrive between steps 1 and 4 wait for the proxy handler. The deactivated handler stays registered until the proxy handler is installed, so a request in that window waits too instead of being rejected.

Trait Implementations§

Source§

impl<'runner, Link> Debug for ActiveSession<'runner, Link>
where Link: HasPeer<Agent> + Debug,

Source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'runner, Link> !RefUnwindSafe for ActiveSession<'runner, Link>

§

impl<'runner, Link> !UnwindSafe for ActiveSession<'runner, Link>

§

impl<'runner, Link> Freeze for ActiveSession<'runner, Link>

§

impl<'runner, Link> Send for ActiveSession<'runner, Link>

§

impl<'runner, Link> Sync for ActiveSession<'runner, Link>

§

impl<'runner, Link> Unpin for ActiveSession<'runner, Link>

§

impl<'runner, Link> UnsafeUnpin for ActiveSession<'runner, Link>

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> IntoMaybeUndefined<T> for T

Source§

fn into_maybe_undefined(self) -> MaybeUndefined<T>

Converts this value into a three-state builder argument.
Source§

impl<T> IntoOption<T> for T

Source§

fn into_option(self) -> Option<T>

Converts this value into an optional builder argument.
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, !>

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