Core Namespaces
Agentix core owns three reserved Socket.IO namespaces:
Plugin-specific protocols use their own namespace, conventionally
/<package-name>. See Plugins and Side Channels for the
extension model.
Systems
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
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.