Agent-to-Agent coordination: registry, delegation, dead letter, and watchdog
Project description
nodus-a2a
Agent-to-Agent coordination primitives for Nodus AI systems.
nodus-a2a provides the coordination layer between agents: capability-based
routing, load-aware delegation, dead-letter recovery, and stuck-run detection.
No external dependencies — stdlib only.
Status: v0.1.0 — prepared, not yet published.
Install
pip install nodus-a2a
What it provides
| Component | Purpose |
|---|---|
AgentRegistry |
Thread-safe registry of agents with capability declarations and load |
AgentCoordinator |
Decides LOCAL vs DELEGATE execution; selects the best available agent |
DelegationRequest / DelegationResult |
Typed delegation envelopes |
DeadLetterService |
Records failed delegations; supports replay and drain |
StuckRunWatchdog |
Tracks in-flight runs; fires a callback when timeout elapses |
Quick start
from nodus_a2a import (
AgentRegistry, AgentCapabilitySet, AgentHealthStatus,
AgentCoordinator, DelegationRequest, ExecutionMode,
)
registry = AgentRegistry()
registry.register(AgentCapabilitySet(
agent_id="memory-agent",
capabilities=["memory.read", "memory.write"],
load=0.2,
health_status=AgentHealthStatus.HEALTHY,
))
registry.register(AgentCapabilitySet(
agent_id="flow-agent",
capabilities=["flow.run"],
load=0.5,
health_status=AgentHealthStatus.HEALTHY,
))
coordinator = AgentCoordinator(registry, local_agent_id="memory-agent")
req = DelegationRequest(
operation={"type": "flow.run", "flow": "my-flow"},
required_capabilities=["flow.run"],
requesting_agent_id="memory-agent",
)
mode = coordinator.decide_mode(req) # ExecutionMode.DELEGATE
target = coordinator.select_agent(req) # flow-agent (lowest load with capability)
AgentRegistry
registry = AgentRegistry()
registry.register(agent)
registry.update_load("agent-id", 0.7) # returns False if unknown
registry.deregister("agent-id")
registry.get("agent-id") # AgentCapabilitySet | None
registry.find_capable(["cap.a", "cap.b"]) # sorted by load, UNAVAILABLE excluded
len(registry)
AgentCoordinator
coordinator = AgentCoordinator(registry, local_agent_id="my-agent")
mode = coordinator.decide_mode(request) # ExecutionMode.LOCAL or DELEGATE
agent = coordinator.select_agent(request) # AgentCapabilitySet | None (lowest load)
DeadLetterService
dlq = DeadLetterService(on_record=my_alert_fn)
dlq.record(request, result)
dlq.list() # all entries
dlq.list(replayed=True)
dlq.mark_replayed(req_id) # True if found
dlq.drain() # removes all; returns count
StuckRunWatchdog
watchdog = StuckRunWatchdog(
timeout_seconds=300,
on_stuck=lambda run_id: logger.warning("stuck: %s", run_id),
)
watchdog.track("run-abc")
watchdog.complete("run-abc")
stuck = watchdog.check_once() # list of stuck IDs; fires on_stuck for each
len(watchdog)
Health statuses
| Status | Eligible for delegation? |
|---|---|
HEALTHY |
Yes |
DEGRADED |
Yes (deprioritised by load sort) |
UNAVAILABLE |
No — excluded from find_capable |
Design
- No external dependencies. Five modules; stdlib only (
threading,dataclasses,datetime,uuid,logging). - Thread-safe.
AgentRegistryandDeadLetterServiceusethreading.Lock. - No nodus-lang dependency. Coordinates agents; does not execute Nodus scripts.
See docs/design.md for design decisions.
Development
pip install -e ".[dev]"
pytest tests/ -q
License
MIT — see LICENSE.
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_a2a-0.1.0.tar.gz.
File metadata
- Download URL: nodus_a2a-0.1.0.tar.gz
- Upload date:
- Size: 10.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eb4501a01933ef9e9491e3d9b3eae99729fb1c6253cd5c3062bad1f2b3462d7c
|
|
| MD5 |
497aff12f7bb72e56450a3d97c00dd0a
|
|
| BLAKE2b-256 |
49224419011f02747cc587902597736295462c9668ccbbf15f02a43bd395bb2f
|
File details
Details for the file nodus_a2a-0.1.0-py3-none-any.whl.
File metadata
- Download URL: nodus_a2a-0.1.0-py3-none-any.whl
- Upload date:
- Size: 9.8 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 |
a2a15538820b427bae123a2146845b1bb6ba05692ab0261feda9b06fa412aaff
|
|
| MD5 |
f96dcae1263d3b2d914fa8de4a0366c9
|
|
| BLAKE2b-256 |
4672c5079c012bb826a3bd12ef23001aa7f6df09c9bb518f097b6dbf9d08682a
|