Core Namespaces
Agentix core owns three reserved Socket.IO namespaces:| Namespace | System | Public API |
|---|---|---|
/rpc | RPC | RuntimeClient.remote(fn, *args, **kwargs) |
/log | logging | standard logging records plus captured stdout/stderr (agentix.sandbox.stdout / agentix.sandbox.stderr) forwarded sandbox -> host; also written to a durable $AGENTIX_LOG_DIR/sandbox-<id>.log |
/trace | tracing | agentix.trace.trace(...), agentix.trace.span(...), trace.Processor |
/<package-name>. See Plugins and Side Channels for the
extension model.
Systems
| System | Responsibility |
|---|---|
agentix.runtime.shared | Wire models, msgpack codec, framing, RemoteCallable, CallId |
agentix.runtime.client | RuntimeClient.remote(fn, ...) and host-side namespace handlers |
agentix.runtime.server | FastAPI and Socket.IO server, worker process management, namespace forwarding |
agentix.provider | Host-side sandbox lifecycle protocol and backend plugin lookup |
agentix.cli | agentix build |
agentix.sio | Sandbox-side namespace API bridged over the worker pipe |
Remote Target
The caller passes a normal imported function:call:result. Because a sandbox may run less-trusted code,
the host decodes those blobs through a restricted allowlist loader
(agentix.runtime.shared.safepickle) rather than plain pickle.loads,
refusing any non-allowlisted global with agentix.RestrictedUnpickleError.
Call Flow
Transports
| Path | Carries | Wire |
|---|---|---|
GET /health | health probe | HTTP JSON |
POST /call | internal short-call fast path | HTTP msgpack |
Socket.IO /rpc | c.remote() RPC | call / call:result / call:error / cancel |
Socket.IO /trace, /log, /<plugin> | side channels | plugin-defined events (msgpack payloads) |
| worker private pipe | runtime ↔ worker | length-prefixed msgpack frames |
Bundle Layout
agentix build [path] installs one Python project into the runtime venv
with uv (uv owns Python; Nix owns system binaries — there is no pip):
pyproject.toml.
The runtime tree is the uv venv plus a symlinkJoin of the Nix
closures (interpreter, uv, and any system deps):
default.nix, the build adds a Nix builder stage
and links binaries into /nix/runtime/bin.
Worker Model
The runtime server owns one worker subprocess. The worker handles remote function invocation and keeps the runtime server isolated from user code. For each call, the worker:- resolves the
RemoteCallableimport path - unpickles
(args, kwargs) - calls the callable (awaiting when the return value is awaitable)
- pickles the return value
agentix.sio bridge. Plugin
namespaces register inside the worker and forward events through
sio_emit / sio_open / sio_inbound frames on the worker pipe.
The runtime server does not implement plugin business logic. It accepts
namespace connections, dynamically registers generic forwarders, and relays
events between host-side AsyncClientNamespace handlers and worker-side
Namespace handlers.
The worker uses the same /nix/runtime environment as the runtime
server, so anything installed into the bundle can be imported on demand.
SandboxProvider Boundary
ASandboxProvider is a host-side plugin that stages a bundle and starts
the sandbox. provider.create(...) returns a live Sandbox handle; call
await sandbox.remote(fn, ...) directly. The runtime protocol is the same
regardless of where the sandbox is running.
RuntimeClient(runtime_url) still exists as the underlying transport for
advanced, direct use against a known runtime_url (for example, an
in-process server). The sandbox path uses sandbox.remote rather than a
nested RuntimeClient.