AgentClient is the low-level transport for talking to agentd through a running sandbox’s relay socket. For most applications, use Sandbox, exec, and fs instead. Reach for AgentClient when you are building a protocol-level integration or an SDK layer. AgentBridge wraps the same connection in concrete, FFI-shaped types for the Node, Python, and Go bindings.The client has two tiers that share one socket and one background reader task:
Typed methods encode and decode microsandbox protocol messages for you.
Raw methods move framed CBOR bytes without decoding the message body.
The raw body is the full CBOR-encoded protocol Message body (v, t, and p), not just the inner payload. The typed and raw methods reach the connection through Deref to the underlying client; everything below is callable directly on the value connect_sandbox returns.
use microsandbox::agent;let client = agent::connect_sandbox("dev").await?;
Resolve a sandbox name to its agent relay socket path and connect, using the default ten-second handshake timeout. The socket lives under the SDK’s configured runtime directory at a short, name-derived path. Sandbox names are limited to 128 UTF-8 bytes.
use microsandbox::agent::AgentClient;let path = AgentClient::socket_path("dev")?;let client = AgentClient::connect(&path).await?;
Connect to an arbitrary agent relay socket by path, using the default ten-second handshake timeout. The connection performs the relay handshake, validates the cached core.ready frame, and starts one background reader task.
Connect to an arbitrary agent relay socket by path with an explicit handshake deadline. The deadline bounds both handshake reads, so an accepted connection that stalls before writing the handshake bytes cannot block this call indefinitely.
Parameters
sock_pathimpl AsRef<Path>
Path to the agent relay socket.
deadlineInstant
Tokio instant by which the handshake must complete.
Resolve a sandbox name to its agent socket path and connect with an explicit handshake timeout. Equivalent to the module-level agent::connect_sandbox_with_timeout.
use microsandbox::agent::AgentClient;let path = AgentClient::socket_path("dev")?;println!("{}", path.display());
Resolve a sandbox’s relay socket path without connecting. Returns the same path connect_sandbox would dial: the hashed path under the runtime directory when it fits the platform’s Unix-socket length limit, and the legacy name-derived path otherwise. Useful for talking to agentd over a raw byte transport (for example a transparent relay that splices bytes to and from the socket) instead of this frame client. The sandbox need not be running.
use microsandbox::{agent::AgentClient, protocol::message::MessageType};AgentClient::ensure_version_compat_for(MessageType::FsRequest, 2)?;
Check a message type against an explicit negotiated generation. The single place the rule lives, exposed for callers that hold the negotiated generation but not a live client. Returns AgentClientError::UnsupportedOperation if the type was introduced after the given generation.
Send one typed protocol message and wait for one response frame with the same correlation id. Flags are derived from the message type. Use this for one-shot RPCs such as filesystem stat or list requests. Fails fast with AgentClientError::UnsupportedOperation if the connected sandbox is too old for the message type.
Open a typed streaming session. The returned id is the protocol correlation id. Use it with send() for follow-up messages such as stdin, resize, signal, or file data chunks. The receiver yields messages until a terminal frame is delivered or the connection closes.
let frame = client.request_raw(flags, body).await?;println!("id={} flags={}", frame.id, frame.flags);
Allocate a correlation id, send one raw frame with (flags, body), and wait for one raw response frame with the matching id. CBOR encoding and decoding are left to the caller.
Open a raw streaming session. The receiver yields raw frames for the returned correlation id until a frame with the terminal flag arrives or the receiver is dropped. Use send_raw() with the returned id to send follow-up frames.
Return the cached handshake core.ready frame body as CBOR bytes. Useful for bindings that want to deserialize the ready payload with their own CBOR tooling. For typed access, use ready().
The negotiated protocol generation for this connection: the lower of what this client speaks and what the sandbox advertised at handshake. This is the capability gate that drives supports() and the typed send path, and it is distinct from protocol(), which selects the wire codec.
The runtime’s self-reported package version, taken from its core.ready frame. Empty when the runtime predates this field (an older agent), in which case fall back to the generation for diagnostics.
use microsandbox::protocol::message::MessageType;if client.supports(MessageType::FsRequest) { // safe to issue filesystem RPCs}
Whether the connected sandbox is new enough to handle the given message type. The single source of truth for feature gating: callers that cannot gate by sending (for example the SSH/SFTP layer) consult this instead of inspecting the protocol generation directly.
use microsandbox::protocol::message::MessageType;client.ensure_version_compat(MessageType::TcpConnect)?;
Reject a message type the connected sandbox is too old to handle, against this connection’s negotiated generation. Fails before any bytes are sent, so only that one operation fails and the session continues. The typed request(), stream(), and send() methods call this internally.
Close the client by consuming it. Drops the writer and aborts the reader task; any in-flight requests resolve with AgentClientError::Closed. Dropping the client has the same effect.
Bytes-in/bytes-out wrapper around AgentClient, with concrete, monomorphic types suitable for crossing FFI boundaries. The Node, Python, and Go bindings build on it. No generics, no consuming-self methods, no callbacks across FFI: each method takes &self and is idempotent where the underlying operation allows. CBOR (de)serialization happens entirely in the caller’s language; the bridge only moves bytes. One instance owns one Unix-socket connection; multiple concurrent streams are supported, each identified by an opaque StreamHandle.
Open a streaming session. Returns the protocol correlation id (for follow-up sends via send()) and an opaque stream handle (for stream_next() and stream_close()).
let (id, handle) = bridge.stream_open(flags, body).await?;while let Some(frame) = bridge.stream_next(handle).await? { // decode frame.body with your own CBOR tooling}
Pull the next frame from a stream. Returns None when the stream has ended (the terminal frame was already delivered, or the stream was closed or dropped).
Client for communicating with agentd through a running sandbox’s relay. A newtype over the underlying microsandbox_agent_client::AgentClient; the typed and raw transport methods reach the inner client through Deref. See the static and instance method sections above.
Opaque handle identifying an open stream on an AgentBridge. Foreign-language wrappers reference streams by this u64 instead of owning a tokio receiver.
A framed protocol message at the byte level. id is the protocol correlation id, flags is the frame flag byte, and body is the CBOR-encoded protocol message body. Re-exported from microsandbox::protocol::codec.