nodus-agent
Full AI agent execution lifecycle for Nodus AI systems.
Provides the plan → approve → execute pipeline with HMAC-signed capability tokens, duplicate-submission guardrails, and a pluggable planner backend. No required external dependencies — all integrations (LLM client, memory, events, approvals) are injected at construction time.
Status: v0.1.0 — prepared, not yet published.
Install
pip install nodus-agent
What it provides
| Component | Purpose |
|---|---|
AgentRun / InMemoryAgentRunStore |
Run state machine: PENDING_APPROVAL → APPROVED → EXECUTING → COMPLETED/FAILED |
mint_token / validate_token |
HMAC-SHA256 capability tokens scoped to a run and user |
LocalPlanner |
Heuristic planner — zero deps, matches tool names from objective text |
LLMPlanner |
LLM-backed planner — accepts any client with a .chat() method |
AgentExecutor |
Orchestrates submit → approve → execute; all integrations optional |
DuplicateSubmissionGuard |
Blocks concurrent identical submissions per user |
check_risk_policy |
Raises GuardrailViolation if plan risk exceeds allowed level |
Quick start
from nodus_agent import AgentExecutor, LocalPlanner, AgentStatus
executor = AgentExecutor()
run = executor.submit("Summarise last week's sales data", user_id="u1")
# run.status == AgentStatus.PENDING_APPROVAL
executor.approve(run.id)
result = executor.execute(run.id)
# result == {"steps_completed": N, "outputs": [...]}
# run.status == AgentStatus.COMPLETED
Auto-approve for automated pipelines
run = executor.submit("Routine cleanup", "u1", auto_approve=True)
executor.execute(run.id)
With a tool registry
from nodus_agent import AgentExecutor
def my_tool(args):
return {"result": "done"}
class SimpleRegistry:
def list(self, **_): return [{"name": "my.tool", "description": "does a thing"}]
def get(self, name): return type("T", (), {"handler": my_tool, "deprecated": False})()
executor = AgentExecutor(tool_registry=SimpleRegistry())
Capability tokens
from nodus_agent import mint_token, validate_token
token = mint_token(
run_id="run-abc",
user_id="u1",
granted_tools=["memory.read", "memory.write"],
allowed_capabilities=["memory.read", "memory.write"],
ttl_hours=1,
)
result = validate_token(token.to_dict(), run_id="run-abc", user_id="u1")
# {"ok": True, "granted_tools": [...], "allowed_capabilities": [...]}
Tokens are HMAC-SHA256 signed over the payload. Tampering with any field
causes validate_token to return {"ok": False, "error": "signature mismatch"}.
LLM-backed planning
from nodus_agent import AgentExecutor, LLMPlanner
# Any object with a .chat(messages, max_tokens) method
class MyLLMClient:
def chat(self, messages, max_tokens=1024):
# call OpenAI / Anthropic / local model
return '{"steps": [{"tool": "memory.read", "args": {}}]}'
executor = AgentExecutor(planner=LLMPlanner(MyLLMClient()))
LLMPlanner falls back to LocalPlanner if the LLM call fails.
Guardrails
from nodus_agent import (
DuplicateSubmissionGuard, GuardrailViolation, check_risk_policy,
)
guard = DuplicateSubmissionGuard(window_seconds=300)
guard.check(user_id, objective) # raises GuardrailViolation if duplicate
guard.register(user_id, objective, run_id)
guard.release(user_id, objective) # call when run completes
check_risk_policy(plan, allowed_risk_levels=("low", "medium"))
# raises GuardrailViolation if plan["risk"] not in allowed_risk_levels
Run state machine
PENDING_APPROVAL → APPROVED → EXECUTING → COMPLETED
↘ FAILED
run.is_terminal # True for COMPLETED and FAILED
run.approved_at # datetime | None
run.completed_at # datetime | None
run.result # output dict | None
Design
- No required dependencies. All five modules are pure stdlib. Integrations (LLM client, memory store, event bus, approvals, A2A coordinator) are passed as optional constructor arguments.
- Pluggable planner. Any object implementing
plan(objective, tools, context) → dictsatisfiesPlannerBackend. - Thread-safe.
InMemoryAgentRunStoreandDuplicateSubmissionGuardusethreading.Lock.
Development
pip install -e ".[dev]"
pytest tests/ -q
License
MIT — see LICENSE.
Metadata
Release files for nodus-agent 0.1.0
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_agent-0.1.0.tar.gz | 15.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| nodus_agent-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 29.4 kB
Release files / nodus_agent-0.1.0.tar.gz
| Download URL | nodus_agent-0.1.0.tar.gz |
|---|---|
| Size | 15.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
dc25a223919f05ff45a1bea091106bd4e1f51f3288502623d42f0a519b0d1890
|
|
BLAKE2b-256 checksum How to use checksums |
175c32789c65bfab2bee4c83458e24c4d80b3a34debb8bc30ed1044fa96d14c2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.9
|
Release files / nodus_agent-0.1.0-py3-none-any.whl
| Download URL | nodus_agent-0.1.0-py3-none-any.whl |
|---|---|
| Size | 14.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d8595979a9b556edf3a0510cb4d9d664aa3711c1db8a1eaa1fdec25372f75cdc
|
|
BLAKE2b-256 checksum How to use checksums |
2c6e8293bb4e0e730115ddc611717f5d0633f1432a33fc441f04061fd938a791
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.9
|