Typed, versioned, sandboxed extension framework for Nodus agents
Project description
nodus-extension
Typed, versioned, sandboxed extension framework for Nodus agents.
Allows platform operators to let third-party developers extend a Nodus application with typed, versioned, sandboxed plugins — registering agent tools without access to host runtime internals.
Quick start — host operator
from nodus import NodusRuntime
from nodus_extension import ExtensionRegistry, attach_to_runtime
registry = ExtensionRegistry()
registry.load("/path/to/my-extension")
runtime = NodusRuntime(timeout_ms=None)
attach_to_runtime(runtime, registry)
# Scripts can now load and invoke extensions
result = runtime.run_source('''
import "nodus-extension"
let result = ext_invoke("myapp.my-extension", "myapp.greet", "{\"name\": \"Alice\"}")
print(result)
''')
Quick start — extension developer
Create a directory with nodus-extension.json and extension.py:
{
"name": "myapp.greet-extension",
"version": "1.0.0",
"description": "Greets people",
"abi_version": "1",
"capabilities": ["tool.invoke"],
"surfaces": {
"tools": [{"name": "myapp.greet", "description": "Greet by name"}]
}
}
from nodus_extension.worker import register_tool, run_loop
register_tool("myapp.greet", lambda args: f"Hello, {args['name']}!")
run_loop()
Capabilities
| Capability | Grants |
|---|---|
filesystem.read |
read_file, list_dir, exists |
filesystem.write |
write_file, append_file, mkdir |
network.outbound |
std:http outbound calls |
subprocess.run |
std:subprocess |
tool.invoke |
invoke tools in host registry |
memory.read |
read from host memory store |
memory.write |
write to host memory store |
Status
v0.1.0 — PREPARED, NOT RELEASED. v0.1 ships subprocess sandbox (insecure-dev tier). OCI container and VM tiers are v0.2+.
Install
pip install nodus-extension
Requires nodus-lang>=4.0.0 and pydantic>=2.0.
ExtensionRegistry
from nodus_extension import ExtensionRegistry
registry = ExtensionRegistry()
registry.load("/path/to/my-extension") # reads nodus-extension.json
registry.load("/path/to/another-ext")
ext = registry.get("myapp.my-extension") # ExtensionHost | None
all_exts = registry.list_all() # list[ExtensionHost]
registry.unload("myapp.my-extension")
ExtensionHost
host = registry.get("myapp.my-extension")
host.name # "myapp.my-extension"
host.manifest # ExtensionManifest
host.gate # CapabilityGate
result = host.invoke("myapp.greet", '{"name": "Alice"}')
# result is the JSON-decoded return value from the extension
invoke takes args as a JSON string — not a dict. The extension runs in
a subprocess; the args are serialized over NDJSON IPC.
Capabilities
from nodus_extension import Capability, CapabilityGate
gate = CapabilityGate({"tool.invoke", "memory.read"})
gate.has(Capability.TOOL_INVOKE) # True
gate.require(Capability.NETWORK_OUTBOUND) # raises CapabilityError
Provenance
from nodus_extension import Provenance, Origin, TrustClass, OwnerClass
prov = Provenance(
origin=Origin.LOCAL,
trust_class=TrustClass.DEV,
owner_class=OwnerClass.PERSONAL,
)
Error types
| Error | When raised |
|---|---|
ManifestError |
Invalid or missing nodus-extension.json |
CapabilityError |
Extension attempts an undeclared capability |
SandboxError |
Subprocess failed to start or exited unexpectedly |
AbiError |
abi_version mismatch |
RegistryError |
Duplicate or unknown extension name |
InvokeError |
Extension returned an error response |
TimeoutError |
Invocation exceeded per-invoke timeout |
Development
pip install -e ".[dev]"
PYTHONPATH=src pytest tests/ -q
Known limitations (v0.1)
- Subprocess sandbox only. OCI container and VM isolation tiers are v0.2+.
ext_invokeargs are a JSON string, not a Nodus map.- Extensions must declare
"tool.invoke"capability to register tools.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file nodus_extension-0.1.0.tar.gz.
File metadata
- Download URL: nodus_extension-0.1.0.tar.gz
- Upload date:
- Size: 27.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b7ead05ab2e5f5d86cbc07225b9072792d9a5972213094d80a600cda99f4dd89
|
|
| MD5 |
6825260c045b323972d1d9a2f4973d91
|
|
| BLAKE2b-256 |
ccb670dff38389f42da548239fdce51cda0a2401f32cb9aca2aeb14dad23fe10
|
File details
Details for the file nodus_extension-0.1.0-py3-none-any.whl.
File metadata
- Download URL: nodus_extension-0.1.0-py3-none-any.whl
- Upload date:
- Size: 19.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9c2e3cc7af14822015e60a5e409be69029fe4d9fcfda8d0ff2fc21e80f93542c
|
|
| MD5 |
e4d1270c46fb0b58bc42cd515bdef08f
|
|
| BLAKE2b-256 |
f04eb4811e9be1c635def614e400e59331b4959c85b3bdf30d89bb10ba7e33ee
|