pub struct Responder<T: JsonRpcResponse = Value, P: Protocol = Raw> { /* private fields */ }Expand description
The context to respond to an incoming request.
This context is provided to request handlers and serves a dual role:
- Respond to the request - Use
respondorrespond_with_resultto send the response - Send other messages - Use the
ConnectionToparameter passed to your handler, which providessend_request,send_notification, andspawn
§Example
connection.on_receive_request(async |req: ProcessRequest, responder, cx| {
// Send a notification while processing
cx.send_notification(StatusUpdate {
message: "processing".into(),
})?;
// Do some work...
let result = process(&req.data)?;
// Respond to the request
responder.respond(ProcessResponse { result })
}, agent_client_protocol::on_receive_request!())§Event Loop Considerations
Like all handlers, request handlers run on the event loop. Use
spawn for expensive operations to avoid blocking
the connection.
See the Event Loop and Concurrency section for more details.
§Drop behavior
A request must be answered. If a responder for a request is dropped without a response having been sent through it, the SDK answers the request itself with an error, so the peer is never left waiting:
-32800(Error::request_cancelled) if the peer had cancelled the request with$/cancel_request;- otherwise
-32603(Error::internal_error), with data naming the method whose responder was dropped.
No automatic response is sent when:
- a response was already sent through the responder (any of the
respond*methods), or the responder was handed to something that answers through it (such asSentRequest::forward_response_to) — only dropping the responder itself without responding triggers the fallback; - the responder was moved into another owner (another task, a wrapped
responder from
castorwrap_params, a retriedDispatch); that owner’s eventual drop is what counts; - the connection is shutting down or has terminated.
When a handler drops the responder and then returns an error, that error is the response instead of the generic fallback.
The automatic error is an ordinary error response: for example, a dropped
initialize responder fails initialization just as an explicit error
would.
§Protocol version
P is the Protocol marker and selects the type id
returns. Typed handlers on Client.v1(), Agent.v1() and
Proxy.v1() receive V1 responders and those on the v2 builders
receive V2 responders. The version-neutral raw dispatch layer
(HandleDispatchFrom, MatchDispatch)
uses the default, Raw. raw_id returns the wire ID
whatever the marker; into_protocol and
into_raw convert between markers.
Implementations§
Source§impl<P: Protocol> Responder<Value, P>
impl<P: Protocol> Responder<Value, P>
Sourcepub fn cast<T: JsonRpcResponse>(self) -> Responder<T, P>
pub fn cast<T: JsonRpcResponse>(self) -> Responder<T, P>
Cast this request context to a different response type.
The provided type T will be serialized to JSON before sending.
Source§impl<T: JsonRpcResponse, P: Protocol> Responder<T, P>
impl<T: JsonRpcResponse, P: Protocol> Responder<T, P>
Sourcepub fn id(&self) -> &P::RequestId
pub fn id(&self) -> &P::RequestId
ID of the incoming request, as this responder’s protocol version types it.
On a V2 responder this is never null: the SDK
rejects v2 requests with a null ID before dispatch.
Sourcepub fn raw_id(&self) -> &RawJsonRpcId
pub fn raw_id(&self) -> &RawJsonRpcId
ID of the incoming request exactly as it appeared on the wire.
This is the same ID as id, in the version-neutral form
used by routers, forwarders and tracing.
Sourcepub fn cancellation(&self) -> RequestCancellation
pub fn cancellation(&self) -> RequestCancellation
Returns the cancellation marker for this request.
The marker is set when the peer sends $/cancel_request for this
request’s JSON-RPC ID. Cancellation is cooperative: handlers should use
the marker to stop long-running work and then respond. Unless the
method defines a successful response for cancellation (for example a
permission request’s cancelled outcome), that response is
Error::request_cancelled (-32800) rather than partial data.
Dropping the responder of a cancelled request sends that error
automatically.
Sourcepub fn erase_to_json(self) -> Responder<Value, P>
pub fn erase_to_json(self) -> Responder<Value, P>
Convert to a Responder that expects a JSON value
and which checks (dynamically) that the JSON value it receives
can be converted to T.
Sourcepub fn wrap_method(self, method: String) -> Responder<T, P>
pub fn wrap_method(self, method: String) -> Responder<T, P>
Return a new Responder with a different method name.
Sourcepub fn wrap_params<U: JsonRpcResponse>(
self,
wrap_fn: impl FnOnce(&str, Result<U, Error>) -> Result<T, Error> + Send + 'static,
) -> Responder<U, P>
pub fn wrap_params<U: JsonRpcResponse>( self, wrap_fn: impl FnOnce(&str, Result<U, Error>) -> Result<T, Error> + Send + 'static, ) -> Responder<U, P>
Return a new Responder that expects a response of type U.
wrap_fn will be invoked with the method name and the result to transform
type U into type T before sending.
Sourcepub fn respond_with_result(
self,
response: Result<T, Error>,
) -> Result<(), Error>
pub fn respond_with_result( self, response: Result<T, Error>, ) -> Result<(), Error>
Respond to the JSON-RPC request with either a value (Ok) or an error (Err).
Sourcepub fn respond(self, response: T) -> Result<(), Error>
pub fn respond(self, response: T) -> Result<(), Error>
Respond to the JSON-RPC request with a value.
Sourcepub fn respond_with_internal_error(
self,
message: impl ToString,
) -> Result<(), Error>
pub fn respond_with_internal_error( self, message: impl ToString, ) -> Result<(), Error>
Respond to the JSON-RPC request with an internal error containing a message.
Source§impl<T: JsonRpcResponse> Responder<T, Raw>
impl<T: JsonRpcResponse> Responder<T, Raw>
Sourcepub fn into_protocol<Q: Protocol>(self) -> Result<Responder<T, Q>, Error>
pub fn into_protocol<Q: Protocol>(self) -> Result<Responder<T, Q>, Error>
Convert this version-neutral responder to protocol Q’s responder,
for example to pass a responder from a HandleDispatchFrom or
MatchDispatch handler to a v2 session
helper.
Only the request ID’s type changes. It fails only when Q does not
allow the ID: protocol v2 rejects null with the Invalid Request
error (-32600) that a v2 connection sends for a null request ID.
That cannot happen for a request received on a v2 connection, which
rejects such requests before dispatch. On failure the responder is
dropped, which answers the request with an error.
let responder: agent_client_protocol::v1::Responder<schema::PromptResponse> =
responder.into_protocol::<V1>()?;
let id: &schema::RequestId = responder.id();