Event-driven Agent-to-Agent protocol - agents are plain functions, coordination is messages, there is no orchestrator
Architecture • How It Works • Why Cosmonapse • Quick Start • Docs
Cosmonapse is an event-driven Agent-to-Agent (A2A) protocol with a Python SDK, a TypeScript SDK, and a developer CLI (cosmo
). It models multi-agent systems on a nervous system instead of a supervisor: agents are pure functions that emit and react to messages on a shared bus, so you grow a system by adding nodes - not by editing a central orchestrator.
PyPI · Envelope Spec · SDK Design · Roadmap · Contributing · Changelog
import asyncio
from cosmonapse import Axon, Dendrite, MemoryRegistryStore, connect_synapse
async def main():
synapse = await connect_synapse("cosmo://127.0.0.1:7070")
try:
async def answerer(input, context):
return {"answer": input["q"]}
worker = Dendrite(synapse=synapse, namespace="demo")
worker.attach_axon(Axon(neuron_id="answerer", neuron_fn=answerer))
orch = Dendrite(synapse=synapse, registry_store=MemoryRegistryStore(),
namespace="demo")
@orch.on_agent_output
async def done(sig):
await orch.emit_final(trace_id=sig.trace_id, parent_id=sig.id,
result=sig.payload["output"])
async with orch, worker:
await orch.dispatch_task(neuron="answerer", input={"q": "hi"})
await asyncio.sleep(0.5)
finally:
await synapse.close()
asyncio.run(main())
Cosmonapse maps a multi-agent system onto a neural metaphor. Every layer is a small, replaceable part - there is no central class that has to know about every agent.
| Abstraction | Plays the role of | What it does |
|---|---|---|
| Neuron | ||
| The agent | A pure function (input, context) -> output . No base class, no inheritance, no framework lock-in. |
|
| Axon | ||
| The output path | Wraps a Neuron and turns its return value into a protocol-valid Signal. | |
| Dendrite | ||
| The connection point | Attaches Axons to the bus, dispatches work, and reacts to results. Any Dendrite can be a worker, an orchestrator, or both. | |
| Synapse | ||
| The bus | Transports Signals between Dendrites - in-memory, a local dev TCP broker, NATS, or Kafka. | |
| Signal | ||
| The message | The typed envelope every agent emits and reacts to (TASK , RESULT , CLARIFICATION , PERMISSION , …). |
|
| Engram | ||
| Shared memory | Durable store so granted permissions and answered questions are recalled instead of re-asked. |
The key property: coordination happens by passing Signals, not by reporting up to a master orchestrator. Add a fourth agent and you stand up another Dendrite and point it at the Synapse - you do not edit a god object.
The transport is pluggable because Cosmonapse is a protocol, not a runtime. The same agent code runs across every transport - you change a connection string, not your logic.
| Transport | Best for | Connect |
|---|---|---|
| In-memory | Unit tests and single-process apps | connect_synapse("memory://") |
| TCP broker | Local multi-process development | connect_synapse("cosmo://127.0.0.1:7070") |
| NATS | Production, low-latency fan-out | pip install "cosmonapse[nats]" |
| Kafka | Production, durable high-throughput streams | pip install "cosmonapse[kafka]" |
dispatch_task emit_final
│ ▲
▼ │
┌─────────┐ TASK ┌──────────┐ RESULT ┌─────────┐
│ Dendrite│ ──────────▶ │ Axon │ ──────────▶ │ Dendrite│
│ (orch) │ Synapse │ (Neuron) │ Synapse │ (orch) │
└─────────┘ └──────────┘ └─────────┘
│
│ may and ask instead of returning
▼
CLARIFICATION / PERMISSION ──▶ answered by a peer
or a central Cortex,
recalled via Engram
- A Dendrite dispatches a
TASK
Signal naming a Neuron and an input. - The Synapse routes it to whichever Dendrite has an Axon for that Neuron.
- The Axon runs the Neuron and emits the output back as a
RESULT
Signal. - Any Dendrite subscribed to that result reacts - including emitting the final answer.
- A Neuron can and
askinstead of returning: a
__clarification__
or__permission__
marker becomes aCLARIFICATION
/PERMISSION
Signal that another Dendrite answers. Human-in-the-loop is just a Signal type, not a bolt-on. - Paired with
Engram, once a question is answered or a permission granted, it is remembered - so agents stop re-asking the same approvals. See§7.5.design/ENVELOPE_SPEC.md
A single orchestrator works in the demo. It breaks down when one supervisor has to know every agent, every step, and every branch - it becomes a thousand-line bottleneck every change routes through.
Cosmonapse removes the orchestrator and makes responsibilities explicit:
-
Agents are pure functions, not subclasses - nothing to inherit, easy to test in isolation
-
Coordination is message-passing on a shared bus, so the system grows sideways instead of onto one chokepoint
-
Human-in-the-loop is a first-class Signal type, not custom plumbing
-
Shared memory (Engram) means granted permissions and answers are recalled, not re-requested
-
The transport is pluggable - the same code runs in-memory for tests and on NATS or Kafka in production
-
Define agents as plain Python (or TypeScript) functions and attach them with a single Axon
-
Dispatch and react to work from any node - no central orchestrator class required
-
Run the same code across in-memory, local TCP, NATS, and Kafka transports
-
an agent to request a clarification or permission and have a peer answer it
-
Persist grants and answers in Engram so they are recalled instead of re-asked
-
Drive everything from the
cosmo
CLI - Explore runnable end-to-end examplescovering Neurons, providers, Engram, parallel builds, and the orchestrator API
Choose the shortest path that matches how you want to use Cosmonapse.
| Surface | Best for | Start |
|---|---|---|
| Python SDK | Building and running agents | pip install cosmonapse |
| TypeScript SDK | Node / browser agents | npm install @cosmonapse/sdk |
| CLI | Terminal-first workflows | one build; pip install cosmonapse or npm i -g @cosmonapse/sdk |
pip install cosmonapse
This installs both import cosmonapse
and the cosmo
command. Optional extras: [nats]
, [kafka]
, and [postgres]
. To work against a local checkout instead:
pip install -e cosmonapse-core/packages/python-sdk
See packages/python-sdk/README.md for full SDK and CLI documentation.
npm install @cosmonapse/sdk
The cosmo
CLI has a single implementation, shipped in the Python package -
there is exactly one CLI build, so pip and npm users always run identical
tooling. The npm package includes a cosmo
launcher that installs and runs it for you:
npm install -g @cosmonapse/sdk
cosmo --help
On first run the launcher looks for a Python that already has cosmonapse
installed and delegates to it (python -m cosmo
). If none is found, it
bootstraps automatically: it creates a private environment under
~/.cosmonapse/cli-venv
and pip-installs cosmonapse
pinned to the npm
package's version, so the two stay in lockstep. The only requirement is a
Python 3.11+ interpreter on PATH ($COSMO_PYTHON
overrides discovery). If
you already pip install cosmonapse
, its own cosmo
entry point is the same code and the launcher simply defers to it.
To work against a local checkout of the SDK:
cd packages/ts-sdk
npm install
npm run build # builds dist/index.{js,cjs,d.ts}
See packages/ts-sdk/README.md for full SDK documentation.
| Path | Purpose |
|---|---|
packages/python-sdk/ |
|
The cosmonapse SDK and bundled cosmo CLI |
|
packages/ts-sdk/ |
|
TypeScript SDK (+ cosmo launcher for npm installs) |
|
packages/prism-ui/ |
|
| Prism UI | |
examples/ |
|
| Runnable end-to-end examples | |
design/SDK_DESIGN.md |
|
| Design rationale | |
design/ENVELOPE_SPEC.md |
|
| Signal envelope / wire-format spec | |
design/ENGRAM_DESIGN.md |
|
| Engram (shared memory) design | |
design/ROADMAP.md |
|
| Roadmap and milestones | |
design/DECISIONS.md |
|
| Architecture decision log |
Python SDK README- install, quick start, API, CLITypeScript SDK README- install, quick start, API, CLISDK_DESIGN.md- design rationaleENVELOPE_SPEC.md- the Signal wire formatENGRAM_DESIGN.md- shared memory designCONTRIBUTING.md- how to set up and contributeCHANGELOG.md- release notes
Apache 2.0 © 2026 Aqib Khan