pub struct SessionBuilder<Link, Responder: JrResponder<Link> = NullResponder, BlockState: SessionBlockState = NonBlocking>{ /* private fields */ }Expand description
Session builder for a new session request. Allows you to add MCP servers or set other details for this session.
The BlockState type parameter tracks whether blocking methods are available:
NonBlocking(default): Onlyon_session_startis availableBlocking(after callingblock_task):run_untilandstart_sessionbecome available
Implementations§
Source§impl<Link, Responder, BlockState> SessionBuilder<Link, Responder, BlockState>
impl<Link, Responder, BlockState> SessionBuilder<Link, Responder, BlockState>
Sourcepub fn with_mcp_server<R>(
self,
mcp_server: McpServer<Link, R>,
) -> Result<SessionBuilder<Link, ChainResponder<Responder, R>, BlockState>, Error>where
R: JrResponder<Link>,
pub fn with_mcp_server<R>(
self,
mcp_server: McpServer<Link, R>,
) -> Result<SessionBuilder<Link, ChainResponder<Responder, R>, BlockState>, Error>where
R: JrResponder<Link>,
Add the MCP servers from the given registry to this session.
Sourcepub fn on_session_start<F, Fut>(self, op: F) -> Result<(), Error>
pub fn on_session_start<F, Fut>(self, op: F) -> Result<(), Error>
Spawn a task that runs the provided closure once the session starts.
Unlike start_session, this method returns immediately
without blocking the current task. The session handshake and closure execution
happen in a spawned background task.
The closure receives an ActiveSession<'static, _> and should return
Result<(), Error>. If the closure returns an error, it will propagate
to the connection’s error handling.
§Example
cx.build_session_cwd()?
.with_mcp_server(mcp)?
.on_session_start(async |mut session| {
// Do something with the session
session.send_prompt("Hello")?;
let response = session.read_to_string().await?;
Ok(())
})?;
// Returns immediately, session runs in background§Ordering
This callback blocks the dispatch loop until the session starts and your
callback completes. See the ordering module for details.
Sourcepub fn on_proxy_session_start<F, Fut>(
self,
request_cx: JrRequestCx<NewSessionResponse>,
op: F,
) -> Result<(), Error>
pub fn on_proxy_session_start<F, Fut>( self, request_cx: JrRequestCx<NewSessionResponse>, op: F, ) -> Result<(), Error>
Spawn a proxy session and run a closure with the session ID.
A proxy session starts the session with the agent and then automatically proxies all session updates (prompts, tool calls, etc.) from the agent back to the client. You don’t need to handle any messages yourself - the proxy takes care of forwarding everything. This is useful when you want to inject and/or filter prompts coming from the client but otherwise not be involved in the session.
Unlike start_session_proxy, this method returns
immediately without blocking the current task. The session handshake, client
response, and proxy setup all happen in a spawned background task.
The closure receives the SessionId once the session is established, allowing
you to perform any custom work with that ID (e.g., tracking, logging).
§Example
ProxyToConductor::builder()
.on_receive_request_from(ClientPeer, async |request: NewSessionRequest, request_cx, cx| {
let mcp = McpServer::<ProxyToConductor, _>::builder("tools").build();
cx.build_session_from(request)
.with_mcp_server(mcp)?
.on_proxy_session_start(request_cx, async |session_id| {
// Session started
Ok(())
})
}, sacp::on_receive_request!())
.serve(transport)
.await?;§Ordering
This callback blocks the dispatch loop until the session starts and your
callback completes. See the ordering module for details.
Source§impl<Link, Responder> SessionBuilder<Link, Responder, NonBlocking>
impl<Link, Responder> SessionBuilder<Link, Responder, NonBlocking>
Sourcepub fn block_task(self) -> SessionBuilder<Link, Responder, Blocking>
pub fn block_task(self) -> SessionBuilder<Link, Responder, Blocking>
Mark this session builder as being able to block the current task.
After calling this, you can use run_until or
start_session which block the current task.
This should not be used from inside a message handler like
JrConnectionBuilder::on_receive_request or JrMessageHandler
implementations.
Source§impl<Link, Responder> SessionBuilder<Link, Responder, Blocking>
impl<Link, Responder> SessionBuilder<Link, Responder, Blocking>
Sourcepub async fn run_until<R>(
self,
op: impl for<'responder> AsyncFnOnce(ActiveSession<'responder, Link>) -> Result<R, Error>,
) -> Result<R, Error>
pub async fn run_until<R>( self, op: impl for<'responder> AsyncFnOnce(ActiveSession<'responder, Link>) -> Result<R, Error>, ) -> Result<R, Error>
Run this session synchronously. The current task will be blocked
and op will be executed with the active session information.
This is useful when you have MCP servers that are borrowed from your local
stack frame.
The ActiveSession passed to op has a non-'static lifetime, which
prevents calling ActiveSession::proxy_remaining_messages (since the
responders would terminate when op returns).
Requires calling block_task first.
Sourcepub async fn start_session(self) -> Result<ActiveSession<'static, Link>, Error>where
Responder: 'static,
pub async fn start_session(self) -> Result<ActiveSession<'static, Link>, Error>where
Responder: 'static,
Send the request to create the session and return a handle.
This is an alternative to Self::run_until that avoids rightward
drift but at the cost of requiring MCP servers that are Send and
don’t access data from the surrounding scope.
Returns an ActiveSession<'static, _> because responders are spawned
into background tasks that live for the connection lifetime.
Requires calling block_task first.
Sourcepub async fn start_session_proxy(
self,
request_cx: JrRequestCx<NewSessionResponse>,
) -> Result<SessionId, Error>where
Link: HasPeer<ClientPeer>,
Responder: 'static,
pub async fn start_session_proxy(
self,
request_cx: JrRequestCx<NewSessionResponse>,
) -> Result<SessionId, Error>where
Link: HasPeer<ClientPeer>,
Responder: 'static,
Start a proxy session that forwards all messages between client and agent.
A proxy session starts the session with the agent and then automatically proxies all session updates (prompts, tool calls, etc.) from the agent back to the client. You don’t need to handle any messages yourself - the proxy takes care of forwarding everything. This is useful when you want to inject and/or filter prompts coming from the client but otherwise not be involved in the session.
This is a convenience method that combines start_session,
responding to the client, and ActiveSession::proxy_remaining_messages.
For more control (e.g., to send some messages before proxying), use
start_session instead and call
proxy_remaining_messages manually.
Requires calling block_task first.