Lightweight async multi-agent framework for Python
Project description
aioagent
Lightweight async multi-agent framework for Python.
Build multi-agent systems using pure asyncio — no external infrastructure, no XMPP servers, no heavy dependencies.
Why aioagent?
| SPADE | aioagent | |
|---|---|---|
| Infrastructure | XMPP server (Prosody) | None |
| Deploy | Complex | Single process |
| Distributed agents | Yes | No (in-process) |
| Dependencies | slixmpp, aioxmpp | stdlib only |
| Best for | Distributed systems | Simulations, pipelines, prototypes |
Installation
pip install aioagent
Quick start
import asyncio
from aioagent import AgentMessage, BaseAgent, CyclicBehaviour, MessageBus
class PingBehaviour(CyclicBehaviour):
async def run(self):
await self.send(AgentMessage(to="pong", body="ping"))
reply = await self.receive(timeout=2.0)
if reply:
print(f"Got: {reply.body}")
self.kill()
class PongBehaviour(CyclicBehaviour):
async def run(self):
msg = await self.receive(timeout=2.0)
if msg:
await self.send(msg.make_reply(body="pong"))
self.kill()
class PingAgent(BaseAgent):
async def setup(self):
self.add_behaviour(PingBehaviour())
class PongAgent(BaseAgent):
async def setup(self):
self.add_behaviour(PongBehaviour())
async def main():
bus = MessageBus()
async with PongAgent("pong", bus=bus), PingAgent("ping", bus=bus):
await asyncio.sleep(1)
asyncio.run(main())
Core concepts
Agents
Subclass BaseAgent and override setup() to register behaviours:
class MyAgent(BaseAgent):
async def setup(self):
self.add_behaviour(MyBehaviour())
Agents support async with for automatic start/stop.
Behaviours
| Class | Description |
|---|---|
OneShotBehaviour |
Runs run() once and stops |
CyclicBehaviour |
Runs run() in a loop until killed |
PeriodicBehaviour |
Runs run() every N seconds |
FSMBehaviour |
Finite-state machine with transitions |
Each behaviour has on_start() and on_end() lifecycle hooks.
FSMBehaviour
Model complex protocols as state machines:
from aioagent import FSMBehaviour
class NegotiationFSM(FSMBehaviour):
async def setup_fsm(self):
self.add_state("PROPOSE", self.propose, initial=True)
self.add_state("EVALUATE", self.evaluate)
self.add_state("DONE", self.finish, final=True)
self.add_transition("PROPOSE", "EVALUATE")
self.add_transition("EVALUATE", "PROPOSE")
self.add_transition("EVALUATE", "DONE")
async def propose(self):
# ... send proposal ...
self.set_next_state("EVALUATE")
async def evaluate(self):
# ... check reply ...
self.set_next_state("DONE")
async def finish(self):
pass
Messages
msg = AgentMessage(
to="recipient",
body="hello",
performative="INFORM", # FIPA-style (optional)
metadata={"protocol": "cnp", "priority": 1},
thread="conversation-1",
)
reply = msg.make_reply(body="acknowledged")
Interaction patterns
Convenience functions for common FIPA performatives:
from aioagent import request, agree, refuse, inform
msg = request("worker", body="compute fibonacci(10)")
await self.send(msg)
reply = await self.receive(timeout=5.0)
# reply with: agree(msg, body="ok") or refuse(msg, body="busy")
Templates
Filter incoming messages by sender, performative, or metadata:
from aioagent import MessageTemplate
template = MessageTemplate(sender="agent_a", performative="REQUEST")
agent.add_behaviour(handler, template=template)
MessageBus
The bus routes messages between agents via per-agent asyncio.Queue instances:
bus = MessageBus()
agent_a = BaseAgent("a", bus=bus)
agent_b = BaseAgent("b", bus=bus)
# Broadcast to all agents
msg = AgentMessage(to="", sender="coordinator", body="start")
await bus.broadcast(msg, exclude="coordinator")
Custom exceptions
All framework errors inherit from AioagentError:
from aioagent import AgentNotFoundError, AgentAlreadyRegisteredError, BehaviourNotBoundError
Examples
See the examples/ directory:
- ping_pong.py — Basic message exchange
- fsm_negotiation.py — Price negotiation with FSM
- broadcast.py — Coordinator notifies all workers
- pipeline.py — Data processing pipeline
- request_reply.py — Request/reply with agree/refuse
Development
git clone https://github.com/mariotrerotola/aioagent.git
cd aioagent
pip install -e ".[dev]"
pytest
pytest --cov=aioagent # with coverage
mypy src/aioagent/ # type checking
ruff check src/ tests/ # linting
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 aioagent-0.1.0.tar.gz.
File metadata
- Download URL: aioagent-0.1.0.tar.gz
- Upload date:
- Size: 20.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cba46922fa40b1e66ab88507f5d439b0a7140b1818afc98a1c1fdc3fe12ffb64
|
|
| MD5 |
133f3ec87b6b5ecaae097139761e9e92
|
|
| BLAKE2b-256 |
f9069d4825629fcc935b911454b24ba2345a717ba778fba6fa4fc55af8a6659d
|
Provenance
The following attestation bundles were made for aioagent-0.1.0.tar.gz:
Publisher:
publish.yml on mariotrerotola/aioagent
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
aioagent-0.1.0.tar.gz -
Subject digest:
cba46922fa40b1e66ab88507f5d439b0a7140b1818afc98a1c1fdc3fe12ffb64 - Sigstore transparency entry: 1017970898
- Sigstore integration time:
-
Permalink:
mariotrerotola/aioagent@37cb04804f7348f2d42a18f487b794751d855896 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/mariotrerotola
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@37cb04804f7348f2d42a18f487b794751d855896 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file aioagent-0.1.0-py3-none-any.whl.
File metadata
- Download URL: aioagent-0.1.0-py3-none-any.whl
- Upload date:
- Size: 13.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
da64ffbc78c7d8e00c9a7196e7fb5461129afb064171a8f4a43cf8a6872911c6
|
|
| MD5 |
ea4741997c66664eb7e68c64bd7a9fce
|
|
| BLAKE2b-256 |
5d4d6e9128457a8fa61b33f5db9b9e81145bf7175a2faf114de39f628f324c50
|
Provenance
The following attestation bundles were made for aioagent-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on mariotrerotola/aioagent
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
aioagent-0.1.0-py3-none-any.whl -
Subject digest:
da64ffbc78c7d8e00c9a7196e7fb5461129afb064171a8f4a43cf8a6872911c6 - Sigstore transparency entry: 1017970926
- Sigstore integration time:
-
Permalink:
mariotrerotola/aioagent@37cb04804f7348f2d42a18f487b794751d855896 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/mariotrerotola
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@37cb04804f7348f2d42a18f487b794751d855896 -
Trigger Event:
workflow_dispatch
-
Statement type: