run:
Why Function Objects
sandbox is a live handle returned by the provider — call
sandbox.remote(fn, ...) on it directly. Passing the function object keeps
the host and sandbox API aligned:
- Your editor sees kwargs and return types from the local signature.
- Refactors stay visible to Python tooling instead of hiding in RPC strings.
- Agents, tools, and scorers all use the same call path.
RemoteCallable.validate:
Payload Shape
This call:sandbox.remote() generates a fresh call_id per call. The
runtime uses it to correlate call:result / call:error responses and
to support cancellation.
The return value comes back as its own pickle blob. Because a sandbox may
run less-trusted code, the host does not decode it with plain
pickle.loads: it uses a restricted allowlist loader that admits only
reviewed value types and refuses anything else with
agentix.RestrictedUnpickleError. Returning a workload’s own custom class
raises that error unless the class is explicitly allowed (see
agentix.runtime.shared.safepickle); return plain data or the framework’s
own result types and it just works.
Remote calls use Socket.IO events on the /rpc namespace. The sandbox
may use the internal HTTP /call fast path for short calls, but accepted
long-running calls and replayed results still complete over /rpc.
Example
app.py
Typing
sandbox.remote(fn, ...) returns the unwrapped result of fn — type
R — whether fn is sync or async. remote is itself a coroutine you
await, so an async def target does not surface as Awaitable[R] on
the host:
fn’s real signature, so argument and return types are
checked against the local definition.
Side Channels
Trace, log, and plugin traffic share the same Socket.IO connection but ride their own namespaces, separate fromsandbox.remote():
| Namespace | Direction | Purpose |
|---|---|---|
/rpc | host ↔ sandbox | sandbox.remote() |
/trace | sandbox → host | span lifecycle (auto-registered) |
/log | sandbox → host | stdlib logging records + captured stdout/stderr (auto-registered) |
/<plugin> | both | plugin-defined events via agentix.sio |
Errors and Cancellation
Agentix keeps errors in-band. A failed call emitscall:error with a
structured payload; the client raises RemoteCallError (or its subclass
CallCancelled when error.cancelled=True — a terminal server-side state,
distinct from local task cancellation). RemoteCallError’s
message includes the sandbox-side traceback when one is available, and
exc.error.traceback holds it on the exception for programmatic access.
When the sandbox disconnects or the caller’s task is cancelled before a
result arrives, the sandbox emits cancel for the in-flight call_id.
Per-call timeouts are caller-owned — wrap await sandbox.remote(...) in
asyncio.wait_for(...) when you need a deadline.