nodus-extension
Status: v0.1.0 — published on PyPI.
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 — published on PyPI. 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.
Metadata
Release files for nodus-extension 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| nodus_extension-0.1.1.tar.gz | 28.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| nodus_extension-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 47.5 kB
Release files / nodus_extension-0.1.1.tar.gz
| Download URL | nodus_extension-0.1.1.tar.gz |
|---|---|
| Size | 28.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
346760275a05455aefd4928f3b40e98a373f63ec7b1261ca24b40c9c4470873d
|
|
BLAKE2b-256 checksum How to use checksums |
43a7697ac24cf8cf09c15cdf7d606cf3b43c3576f7e7a6d991cadceaba93987d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.9
|
Release files / nodus_extension-0.1.1-py3-none-any.whl
| Download URL | nodus_extension-0.1.1-py3-none-any.whl |
|---|---|
| Size | 19.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
8e026c09592d29ec3b94638aa65ddd478adc690f2814fc3781f3ec4b960f34b5
|
|
BLAKE2b-256 checksum How to use checksums |
cdcba09b007500bacea6fc2410628a2f8a705ee1ec1df7cb4388a48c71d6649b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.9
|