Multi-agent coordination SDK for NoLag - handoff, blackboard, inbox, tools, approval, observe patterns
Project description
nolag-agents
Multi-agent coordination SDK for Python, built on the nolag real-time SDK.
Six coordination patterns out of the box: Handoff, Blackboard, Inbox, Tools, Approve, and Observe. Plus built-in load balancing for worker pools.
Install
pip install nolag-agents
Requires Python 3.10+ and nolag>=2.1.0 (installed automatically).
Quick Start
Orchestrator
from nolag_agents import NoLagAgents, NoLagAgentsOptions, AgentPresenceData
from nolag_agents.patterns import Handoff
agents = NoLagAgents(ORCHESTRATOR_TOKEN, NoLagAgentsOptions(
app_name="my-agents",
presence=AgentPresenceData(name="orchestrator", role="orchestrator", capabilities=["dispatch"]),
))
await agents.connect()
room = await agents.room("default-workflow")
handoff = Handoff(room)
result = await handoff.dispatch("summarize",
{"url": "https://example.com/article"},
wait_for_result=True, timeout=30000,
)
print("Result:", result.payload)
Worker
from nolag_agents import NoLagAgents, NoLagAgentsOptions, AgentPresenceData
from nolag_agents.patterns import Handoff
agents = NoLagAgents(WORKER_TOKEN, NoLagAgentsOptions(
app_name="my-agents",
presence=AgentPresenceData(name="summarizer", role="worker", capabilities=["summarize"]),
))
await agents.connect()
room = await agents.room("default-workflow")
handoff = Handoff(room)
def handle_task(task, respond):
summary = do_summarize(task.payload["url"])
await respond("success", {"summary": summary})
handoff.on_task(["summarize"], handle_task)
Patterns
Handoff
Dispatch tasks to agents by capability. Workers register capabilities via presence, and the orchestrator routes work to capable agents.
from nolag_agents.patterns import Handoff
handoff = Handoff(room)
# Dispatch (orchestrator)
result = await handoff.dispatch("translate", {"text": "hello"}, wait_for_result=True)
# Receive (worker)
handoff.on_task(["translate"], handler)
# Find agents with a capability
agents = handoff.get_capable_agents("translate")
Blackboard
Shared key-value state visible to all agents in a room. Uses retained messages so state is available immediately on join.
from nolag_agents.patterns import Blackboard
blackboard = Blackboard(room, agents.agent_id)
await blackboard.set("status", "processing")
value = blackboard.get("status") # "processing"
# Watch for changes
blackboard.on_change("status", lambda envelope: print(envelope.value))
# Get all state
all_state = blackboard.get_all()
Inbox
Per-agent direct messaging. Messages are filtered by recipient agent ID.
from nolag_agents.patterns import Inbox
inbox = Inbox(room, agents.agent_id)
# Send a direct message
await inbox.send("other-agent-id", {"action": "ping"})
# Receive messages (via room event listener)
room.on("inbox", lambda msg: print(msg))
Tools
Remote tool invocation over pub/sub with correlated request/response.
from nolag_agents.patterns import Tools
tools = Tools(room, agents.agent_id)
# Register a tool handler
tools.register("lookup", lambda args: {"result": db.find(args["id"])})
# Call a remote tool
response = await tools.call("lookup", {"id": "abc123"}, timeout=5000)
print(response.result)
Approve
Human-in-the-loop approval gates. Agents request approval before taking actions.
from nolag_agents.patterns import Approve
approve = Approve(room, agents.agent_id)
# Request approval (agent side)
response = await approve.request(
action="delete_record",
context={"record_id": "123"},
timeout=60000,
)
if response.decision == "approved":
delete_record("123")
# Respond to requests (human/dashboard side)
approve.on_request(lambda req: approve.respond(req.request_id, "approved"))
Observe
Structured observability events. Agents emit events, dashboards and monitors subscribe.
from nolag_agents.patterns import Observe
observe = Observe(room, agents.agent_id)
# Emit an event
await observe.emit("task_started", {"task_id": "abc"}, severity="info")
# Listen for events
observe.on("task_started", lambda event: print(event.payload))
Load Balancing
Distribute tasks across a pool of workers. When enabled, NoLag routes each message to only one subscriber in the group.
agents = NoLagAgents(WORKER_TOKEN, NoLagAgentsOptions(
app_name="my-agents",
presence=AgentPresenceData(name="worker-1", role="worker", capabilities=["process"]),
load_balance=True,
load_balance_group="workers",
))
Lobby Presence
Observe agent presence across multiple rooms at once. Useful for dashboards and orchestrator discovery.
agents = NoLagAgents(TOKEN, NoLagAgentsOptions(
app_name="my-agents",
lobby="agent-dashboard",
presence=AgentPresenceData(name="monitor", role="observer"),
))
await agents.connect()
room = await agents.room("default-workflow")
connected = room.get_connected_agents()
capabilities = room.get_available_capabilities()
Configuration
NoLagAgentsOptions fields:
| Field | Type | Default | Description |
|---|---|---|---|
app_name |
str |
"agents" |
NoLag app slug |
agent_id |
str |
auto-generated | Unique agent identifier |
debug |
bool |
False |
Enable debug logging |
rooms |
list[str] |
["default-workflow"] |
Rooms to join on connect |
lobby |
str |
None |
Lobby slug for cross-room presence |
presence |
AgentPresenceData |
None |
Agent presence metadata |
client_options |
dict |
None |
Passed to the underlying nolag client |
load_balance |
bool |
False |
Enable load balancing |
load_balance_group |
str |
None |
Load balance group name |
load_balance_topics |
list[str] |
None |
Topics to load balance |
Testing
# Unit tests
pytest tests/
# Integration tests (requires NOLAG_ACCESS_TOKEN)
NOLAG_ACCESS_TOKEN=<token> pytest integration_test.py -v
License
MIT
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 nolag_agents-0.2.1.tar.gz.
File metadata
- Download URL: nolag_agents-0.2.1.tar.gz
- Upload date:
- Size: 19.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c15869827f5823a5e96daee0c7142c6ae03719be4fdb775b8d249c128e89fc58
|
|
| MD5 |
85f4e188a7b921f08fc3c8c0d1b9cfe6
|
|
| BLAKE2b-256 |
53dd7d91ee55d634152bd98508dd6601d15b346085510eb3c7701127713f5c44
|
File details
Details for the file nolag_agents-0.2.1-py3-none-any.whl.
File metadata
- Download URL: nolag_agents-0.2.1-py3-none-any.whl
- Upload date:
- Size: 20.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
381aadc10a02c37ae61a2c35c855bb1c7ac0028ed84c859e7ded6ed92e2ce5e7
|
|
| MD5 |
ece5d4548a1ed203e79e9127f933d256
|
|
| BLAKE2b-256 |
094ea24229278865636b9f47fb181667b041892770ff261fb9855cdd81785178
|