Skip to main content

Typed, versioned, sandboxed extension loading: manifest validation, hook lifecycle, sandbox runners

Project description

nodus-extensions

Typed, versioned, sandboxed extension loading for Nodus AI systems.

Provides ABI versioning constants, a hook lifecycle runner, subprocess and OCI sandbox runners, disk-discovery extension registry, and a provenance inventory. No required external dependencies — pure stdlib.

Note on naming: This package (nodus-extensions, plural) is distinct from nodus-extension (singular). nodus-extension is the nodus-lang companion that provides .nd script bindings (import "nodus-extension"). This package is a standalone Tier 4 library for building extension-hosting platforms in Python.

Status: v0.1.0 — prepared, not yet published.


Install

pip install nodus-extensions

What it provides

Component Purpose
ExtensionManifest Typed extension declaration (name, version, ABI, surfaces)
ExtensionRegistry Disk-discovery registry: discover(), load(), get(), list_all()
HookRunner Phase hook lifecycle: register, unregister, run
SubprocessSandboxRunner Insecure-dev tier: runs extensions as child processes
OciSandboxRunner Container-grade tier: runs extensions via Docker
make_runner(tier) Factory for the appropriate sandbox runner
ExtensionProvenance / ProvenanceInventory Source, trust class, load time tracking

ExtensionManifest

from nodus_extensions import (
    ExtensionManifest, SandboxTier,
    MANIFEST_ABI_V1, AGENT_TOOL_REGISTRATION_ABI_V1ALPHA1,
    SURFACE_AGENT_TOOL, OWNER_EXTERNAL_THIRD_PARTY,
)

manifest = ExtensionManifest(
    name="myapp.greet-extension",
    version="1.0.0",
    description="Greets users",
    abi_version=MANIFEST_ABI_V1,
    sandbox_tier=SandboxTier.INSECURE_DEV,
    surfaces=[SURFACE_AGENT_TOOL],
    capabilities=["tool.invoke"],
)

ABI version constants

Constant Value Surface
MANIFEST_ABI_V1 "v1" Manifest schema
NODE_REGISTRATION_ABI_V1ALPHA1 "v1alpha1" Dynamic nodes
WEBHOOK_REGISTRATION_ABI_V1ALPHA1 "v1alpha1" Webhooks
FLOW_REGISTRATION_ABI_V1ALPHA1 "v1alpha1" Flows
AGENT_TOOL_REGISTRATION_ABI_V1ALPHA1 "v1alpha1" Agent tools
PLANNER_BACKEND_REGISTRATION_ABI_V1ALPHA1 "v1alpha1" Planner backends

ExtensionRegistry

from nodus_extensions import ExtensionRegistry

registry = ExtensionRegistry()
registry.discover("/path/to/extensions/")   # scans for nodus-extension.json files
registry.load("/path/to/specific-ext/")     # load one extension dir

ext = registry.get("myapp.greet-extension")  # ExtensionManifest | None
all_exts = registry.list_all()               # list[ExtensionManifest]
registry.unload("myapp.greet-extension")

HookRunner

from nodus_extensions import (
    HookRunner,
    PHASE_INIT, PHASE_BEFORE_AGENT_START,
    PHASE_BEFORE_MODEL_RESOLVE, PHASE_AFTER_AGENT_END, PHASE_SHUTDOWN,
)

runner = HookRunner()

def my_init_hook(params: dict) -> None:
    print("Initialising:", params)

runner.register(PHASE_INIT, "my-hook", my_init_hook)
await runner.run(PHASE_INIT, {"context": "startup"})
runner.unregister(PHASE_INIT, "my-hook")

Hooks are async-aware — sync hooks are called directly; async hooks are awaited. All hooks for a phase run in registration order.


Sandbox runners

from nodus_extensions import SubprocessSandboxRunner, OciSandboxRunner, make_runner, SandboxTier

# Subprocess (insecure-dev — same OS user as host)
runner = SubprocessSandboxRunner()
result = runner.run("python3 extension.py", input_data={"tool": "greet", "args": {}})
# result.ok, result.stdout, result.stderr, result.returncode, result.output

# OCI container (Docker required)
runner = OciSandboxRunner(image="myapp/greet-extension:1.0")
result = runner.run("python3 extension.py", input_data={...})

# Factory
runner = make_runner(SandboxTier.INSECURE_DEV)
runner = make_runner(SandboxTier.CONTAINER)

Provenance

from nodus_extensions import ExtensionProvenance, ProvenanceInventory, derive_trust_class

inventory = ProvenanceInventory()
prov = ExtensionProvenance(
    name="myapp.greet-extension",
    source="local",
    owner_class="personal",
    trust_class=derive_trust_class("personal"),
)
inventory.record(prov)

all_prov = inventory.list_all()
entry = inventory.get("myapp.greet-extension")

Design

  • No required dependencies. Pure stdlib (asyncio, threading, subprocess, importlib, pathlib, json, logging).
  • Thread-safe. ExtensionRegistry and ProvenanceInventory use threading.Lock.
  • Sandbox tiers are explicit. SandboxTier.INSECURE_DEV (subprocess) and SandboxTier.CONTAINER (OCI) are named constants, not flags.

Development

pip install -e ".[dev]"
pytest tests/ -q

License

MIT — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nodus_extensions-0.1.0.tar.gz (15.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

nodus_extensions-0.1.0-py3-none-any.whl (13.5 kB view details)

Uploaded Python 3

File details

Details for the file nodus_extensions-0.1.0.tar.gz.

File metadata

  • Download URL: nodus_extensions-0.1.0.tar.gz
  • Upload date:
  • Size: 15.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.9

File hashes

Hashes for nodus_extensions-0.1.0.tar.gz
Algorithm Hash digest
SHA256 86bfe6ce1ff97a2dffa168ca86ec5138fe654a05ccfb00eda74914c3557615ff
MD5 e7265054d5a60a91b5faec71b14619cb
BLAKE2b-256 bbf34f65d4034ca34aa6f6990a85e2b43327e80eeaa015a080a99bec17bf63ba

See more details on using hashes here.

File details

Details for the file nodus_extensions-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for nodus_extensions-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ce0f0b3d3551cc6c8d1d487c8cffa843f22ece341dfd423c74566f75e6e3dd24
MD5 588e9fc993c0a5d3cace7cc5605a6298
BLAKE2b-256 c307050044f4285a873649999db5bc5e53b3c813c78d66bf829b1e5f2f0fe1d3

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page