Back to Microsandbox

Agent client

docs/sdk/python/agent-client.mdx

0.6.910.9 KB
Original Source

Low-level raw CBOR transport for communicating with agentd through a sandbox relay.

Constants

NameValueDescription
FLAG_TERMINAL0b0000_0001Last frame for a correlation id
FLAG_SESSION_START0b0000_0010First frame of a streaming session
FLAG_SHUTDOWN0b0000_0100Shutdown frame

AgentClient

<span className="msb-recv">AgentClient.</span><span className="msb-hn">connect_sandbox()</span>

<Tooltip tip="Connecting an agent client by socket path is local-only; on microsandbox cloud the SDK uses the agent WebSocket route internally."><span className="msb-badge-local">Local-only <Icon icon="circle-info" size={11} /></span></Tooltip>

python
@classmethod
async def connect_sandbox(cls, name: str, *, timeout: float | None = None) -> AgentClient
<Accordion title="Example">
python
client = await AgentClient.connect_sandbox("dev", timeout=5.0)
</Accordion>

Connect to a running sandbox by name. Sandbox names are limited to 128 UTF-8 bytes.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>name</code><span className="msb-type">str</span></div> <div className="msb-param-desc">Sandbox name, up to 128 UTF-8 bytes.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>timeout</code><span className="msb-type">float | None</span></div> <div className="msb-param-desc">Connection timeout in seconds. <code>None</code> uses the default.</div> </div> </div> <p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><span className="msb-type">AgentClient</span></div> <div className="msb-param-desc">Connected client.</div> </div> </div>

<span className="msb-recv">AgentClient.</span><span className="msb-hn">connect()</span>

<Tooltip tip="Connecting an agent client by socket path is local-only; on microsandbox cloud the SDK uses the agent WebSocket route internally."><span className="msb-badge-local">Local-only <Icon icon="circle-info" size={11} /></span></Tooltip>

python
@classmethod
async def connect(cls, path: str, *, timeout: float | None = None) -> AgentClient
<Accordion title="Example">
python
path = AgentClient.socket_path("dev")
client = await AgentClient.connect(path)
</Accordion>

Connect to an agent relay socket by path. Use this when you already know the socket path, for example one returned by socket_path().

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>path</code><span className="msb-type">str</span></div> <div className="msb-param-desc">Path to the agentd relay socket.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>timeout</code><span className="msb-type">float | None</span></div> <div className="msb-param-desc">Connection timeout in seconds. <code>None</code> uses the default.</div> </div> </div> <p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><span className="msb-type">AgentClient</span></div> <div className="msb-param-desc">Connected client.</div> </div> </div>

<span className="msb-recv">AgentClient.</span><span className="msb-hn">socket_path()</span>

<Tooltip tip="Connecting an agent client by socket path is local-only; on microsandbox cloud the SDK uses the agent WebSocket route internally."><span className="msb-badge-local">Local-only <Icon icon="circle-info" size={11} /></span></Tooltip>

python
@staticmethod
def socket_path(name: str) -> str
<Accordion title="Example">
python
path = AgentClient.socket_path("dev")
</Accordion>

Resolve a sandbox's agentd relay socket path without connecting. Returns the same path connect_sandbox() would dial, so you can talk 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. Sandbox names are limited to 128 UTF-8 bytes.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>name</code><span className="msb-type">str</span></div> <div className="msb-param-desc">Sandbox name, up to 128 UTF-8 bytes.</div> </div> </div> <p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><span className="msb-type">str</span></div> <div className="msb-param-desc">Filesystem path to the relay socket.</div> </div> </div> <p className="msb-member-group">Instance methods</p>

<span className="msb-recv">client.</span><span className="msb-hn">request()</span>

python
async def request(self, flags: int, body: bytes) -> RawFrame
<Accordion title="Example">
python
frame = await client.request(0, body)
print(frame["id"], frame["flags"])
</Accordion>

Send one raw frame and wait for one response frame.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>flags</code><span className="msb-type">int</span></div> <div className="msb-param-desc">Frame flag byte, e.g. a combination of <code>FLAG_*</code> constants.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>body</code><span className="msb-type">bytes</span></div> <div className="msb-param-desc">CBOR-encoded protocol message body.</div> </div> </div> <p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><a className="msb-type" href="#rawframe">RawFrame</a></div> <div className="msb-param-desc">The response frame.</div> </div> </div>

<span className="msb-recv">client.</span><span className="msb-hn">stream()</span>

python
async def stream(self, flags: int, body: bytes) -> AgentStream
<Accordion title="Example">
python
from microsandbox import FLAG_SESSION_START, FLAG_TERMINAL

stream = await client.stream(FLAG_SESSION_START, body)
async for frame in stream:
    if frame["flags"] & FLAG_TERMINAL:
        break
</Accordion>

Open a raw streaming session. The returned AgentStream carries the protocol correlation id and is also an async iterator of raw frames.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>flags</code><span className="msb-type">int</span></div> <div className="msb-param-desc">Frame flag byte; pass <code>FLAG_SESSION_START</code> to open a session.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>body</code><span className="msb-type">bytes</span></div> <div className="msb-param-desc">CBOR-encoded protocol message body.</div> </div> </div> <p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><a className="msb-type" href="#agentstream">AgentStream</a></div> <div className="msb-param-desc">Open streaming session.</div> </div> </div>

<span className="msb-recv">client.</span><span className="msb-hn">send()</span>

python
async def send(self, id: int, flags: int, body: bytes) -> None
<Accordion title="Example">
python
stream = await client.stream(FLAG_SESSION_START, body)
await client.send(stream.id, 0, follow_up_body)
</Accordion>

Send a follow-up frame on an existing correlation id. Use the id from the AgentStream returned by stream().

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>id</code><span className="msb-type">int</span></div> <div className="msb-param-desc">Correlation id of an open session, from <code>stream.id</code>.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>flags</code><span className="msb-type">int</span></div> <div className="msb-param-desc">Frame flag byte.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>body</code><span className="msb-type">bytes</span></div> <div className="msb-param-desc">CBOR-encoded protocol message body.</div> </div> </div>

<span className="msb-recv">client.</span><span className="msb-hn">ready_bytes()</span>

python
def ready_bytes(self) -> bytes
<Accordion title="Example">
python
ready = client.ready_bytes()
</Accordion>

Return the cached handshake core.ready frame body as CBOR bytes.

<p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><span className="msb-type">bytes</span></div> <div className="msb-param-desc">CBOR-encoded <code>core.ready</code> frame body.</div> </div> </div>

<span className="msb-recv">client.</span><span className="msb-hn">close()</span>

python
async def close(self) -> None
<Accordion title="Example">
python
await client.close()
</Accordion>

Close the client. Calling it more than once is safe.

AgentStream

<p className="msb-backref">Returned by <a href="#client-stream">stream()</a></p>

An async iterator of raw agent frames.

<span className="msb-recv">stream.</span><span className="msb-hn">id</span>

int

Protocol correlation id; pass to send() for follow-up frames

<span className="msb-recv">stream.</span><span className="msb-hn">next()</span>

python
next()

Read the next frame; returns None at EOF

<p className="msb-label">Returns</p>

Awaitable[RawFrame \| None]

<span className="msb-recv">stream.</span><span className="msb-hn">close()</span>

python
close()

Release the stream handle early; safe to call more than once

<p className="msb-label">Returns</p>

Awaitable[None]

<Accordion title="Example">
python
from microsandbox import FLAG_SESSION_START, FLAG_TERMINAL

async with await client.stream(FLAG_SESSION_START, body) as stream:
    async for frame in stream:
        if frame["flags"] & FLAG_TERMINAL:
            break
</Accordion>

Types

RawFrame

<p className="msb-backref">Returned by <a href="#client-request">request()</a> · yielded by <a href="#agentstream">AgentStream</a></p>

A raw protocol frame with a CBOR-encoded body.

python
class RawFrame(TypedDict):
    id: int
    flags: int
    body: bytes
FieldTypeDescription
idintProtocol correlation id
flagsintFrame flag byte (combination of FLAG_* constants)
bodybytesCBOR-encoded protocol message body