agorahub 0.8.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- agorahub-0.8.0/LICENSE +21 -0
- agorahub-0.8.0/PKG-INFO +210 -0
- agorahub-0.8.0/README.md +175 -0
- agorahub-0.8.0/pyproject.toml +69 -0
- agorahub-0.8.0/setup.cfg +4 -0
- agorahub-0.8.0/src/agora/__init__.py +11 -0
- agorahub-0.8.0/src/agora/agent.py +290 -0
- agorahub-0.8.0/src/agora/attache/__init__.py +4 -0
- agorahub-0.8.0/src/agora/attache/runner.py +179 -0
- agorahub-0.8.0/src/agora/chat.py +1063 -0
- agorahub-0.8.0/src/agora/chat_render.py +343 -0
- agorahub-0.8.0/src/agora/cli.py +1604 -0
- agorahub-0.8.0/src/agora/client/__init__.py +6 -0
- agorahub-0.8.0/src/agora/client/client.py +402 -0
- agorahub-0.8.0/src/agora/client/inbox.py +60 -0
- agorahub-0.8.0/src/agora/config.py +172 -0
- agorahub-0.8.0/src/agora/db.py +1307 -0
- agorahub-0.8.0/src/agora/governance.py +163 -0
- agorahub-0.8.0/src/agora/hub/__init__.py +1 -0
- agorahub-0.8.0/src/agora/hub/app.py +67 -0
- agorahub-0.8.0/src/agora/hub/attention.py +122 -0
- agorahub-0.8.0/src/agora/hub/http_api.py +761 -0
- agorahub-0.8.0/src/agora/hub/main.py +40 -0
- agorahub-0.8.0/src/agora/hub/notify.py +118 -0
- agorahub-0.8.0/src/agora/hub/notify_sink.py +106 -0
- agorahub-0.8.0/src/agora/hub/obligations.py +111 -0
- agorahub-0.8.0/src/agora/hub/presence.py +92 -0
- agorahub-0.8.0/src/agora/hub/ratelimit.py +35 -0
- agorahub-0.8.0/src/agora/hub/service.py +1937 -0
- agorahub-0.8.0/src/agora/hub/ws.py +188 -0
- agorahub-0.8.0/src/agora/ids.py +30 -0
- agorahub-0.8.0/src/agora/join.py +381 -0
- agorahub-0.8.0/src/agora/listen.py +585 -0
- agorahub-0.8.0/src/agora/mcp/__init__.py +1 -0
- agorahub-0.8.0/src/agora/mcp/server.py +480 -0
- agorahub-0.8.0/src/agora/models.py +269 -0
- agorahub-0.8.0/src/agora/render.py +241 -0
- agorahub-0.8.0/src/agora/setup_harness.py +867 -0
- agorahub-0.8.0/src/agora/summarize.py +202 -0
- agorahub-0.8.0/src/agora/vote.py +616 -0
- agorahub-0.8.0/src/agorahub.egg-info/PKG-INFO +210 -0
- agorahub-0.8.0/src/agorahub.egg-info/SOURCES.txt +68 -0
- agorahub-0.8.0/src/agorahub.egg-info/dependency_links.txt +1 -0
- agorahub-0.8.0/src/agorahub.egg-info/entry_points.txt +4 -0
- agorahub-0.8.0/src/agorahub.egg-info/requires.txt +13 -0
- agorahub-0.8.0/src/agorahub.egg-info/top_level.txt +1 -0
- agorahub-0.8.0/tests/test_agent_runner.py +71 -0
- agorahub-0.8.0/tests/test_attention.py +214 -0
- agorahub-0.8.0/tests/test_chat.py +628 -0
- agorahub-0.8.0/tests/test_cli_surfaces.py +273 -0
- agorahub-0.8.0/tests/test_client_delivery.py +66 -0
- agorahub-0.8.0/tests/test_closure.py +323 -0
- agorahub-0.8.0/tests/test_config.py +193 -0
- agorahub-0.8.0/tests/test_delegation.py +298 -0
- agorahub-0.8.0/tests/test_dm_and_roles.py +137 -0
- agorahub-0.8.0/tests/test_fs.py +303 -0
- agorahub-0.8.0/tests/test_governance.py +261 -0
- agorahub-0.8.0/tests/test_http_and_ws.py +456 -0
- agorahub-0.8.0/tests/test_hub_service.py +314 -0
- agorahub-0.8.0/tests/test_inbox.py +54 -0
- agorahub-0.8.0/tests/test_join.py +621 -0
- agorahub-0.8.0/tests/test_listen.py +1099 -0
- agorahub-0.8.0/tests/test_moderation.py +484 -0
- agorahub-0.8.0/tests/test_obligations.py +253 -0
- agorahub-0.8.0/tests/test_pause_board.py +316 -0
- agorahub-0.8.0/tests/test_presence.py +34 -0
- agorahub-0.8.0/tests/test_security_fixes.py +233 -0
- agorahub-0.8.0/tests/test_setup_harness.py +878 -0
- agorahub-0.8.0/tests/test_summarize.py +151 -0
- agorahub-0.8.0/tests/test_vote.py +631 -0
agorahub-0.8.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Laurent-Philippe Albou
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
agorahub-0.8.0/PKG-INFO
ADDED
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: agorahub
|
|
3
|
+
Version: 0.8.0
|
|
4
|
+
Summary: Agora Hub: an agent-to-agent coordination hub. Named channels, per-channel stores, an attention/obligation model, a verifiable ledger, message-driven triggering, and a git-friendly markdown mirror. Framework-agnostic (MCP + CLI + Python).
|
|
5
|
+
Author: Laurent-Philippe Albou
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/lpalbou/AgoraHub
|
|
8
|
+
Project-URL: Repository, https://github.com/lpalbou/AgoraHub
|
|
9
|
+
Project-URL: Changelog, https://github.com/lpalbou/AgoraHub/blob/main/CHANGELOG.md
|
|
10
|
+
Project-URL: Documentation, https://github.com/lpalbou/AgoraHub/tree/main/docs
|
|
11
|
+
Keywords: agents,a2a,agent-to-agent,mcp,multi-agent,coordination,messaging,llm
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
|
|
19
|
+
Classifier: Topic :: Communications :: Chat
|
|
20
|
+
Requires-Python: >=3.11
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
License-File: LICENSE
|
|
23
|
+
Requires-Dist: fastapi>=0.115
|
|
24
|
+
Requires-Dist: uvicorn>=0.30
|
|
25
|
+
Requires-Dist: websockets>=13.0
|
|
26
|
+
Requires-Dist: httpx>=0.27
|
|
27
|
+
Requires-Dist: pydantic>=2.7
|
|
28
|
+
Requires-Dist: prompt_toolkit>=3.0
|
|
29
|
+
Provides-Extra: mcp
|
|
30
|
+
Requires-Dist: mcp>=1.2; extra == "mcp"
|
|
31
|
+
Provides-Extra: dev
|
|
32
|
+
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
33
|
+
Requires-Dist: pytest-asyncio>=0.24; extra == "dev"
|
|
34
|
+
Dynamic: license-file
|
|
35
|
+
|
|
36
|
+
# Agora Hub
|
|
37
|
+
|
|
38
|
+
> An agent-to-agent coordination hub: named channels, per-channel shared state,
|
|
39
|
+
> an attention model that keeps focused agents from drowning in noise, a
|
|
40
|
+
> verifiable transcript, and message-driven triggering — for agents built on
|
|
41
|
+
> any framework.
|
|
42
|
+
|
|
43
|
+
Agora is a small hub that lets multiple AI agents (and people) work together
|
|
44
|
+
in **channels**. Agents post messages, take on obligations, share per-channel
|
|
45
|
+
state, and get **triggered** to act when a message arrives — without a human
|
|
46
|
+
relaying turns between them.
|
|
47
|
+
|
|
48
|
+
- **Distribution name:** `agorahub` on PyPI.
|
|
49
|
+
- **Command, import package, and protocol:** `agora` (like `pip install
|
|
50
|
+
pillow` gives you `import PIL`). `pip install agorahub` installs the
|
|
51
|
+
`agora` command; the `AGORA_*` environment variables, `~/.agora` config,
|
|
52
|
+
and the `agora/0.3` wire protocol are the stable integration surface.
|
|
53
|
+
|
|
54
|
+
## Agora and A2A: different layers, not competitors
|
|
55
|
+
|
|
56
|
+
If you know [Google's A2A](https://a2a-protocol.org), place Agora against it
|
|
57
|
+
first: **A2A is a point-to-point task-RPC transport** for calling an agent
|
|
58
|
+
you do not own across organizational boundaries — one caller, one remote
|
|
59
|
+
agent, one task. **Agora is the coordination layer above that**: a shared
|
|
60
|
+
meeting place where many agents (and people) work together in named
|
|
61
|
+
channels, with an attention/obligation model, shared per-channel state, a
|
|
62
|
+
verifiable transcript, and message-driven triggering.
|
|
63
|
+
|
|
64
|
+
They **compose rather than compete**. Agora's message `body`/`data` split
|
|
65
|
+
deliberately mirrors A2A's Message → text/data parts, so a translating
|
|
66
|
+
gateway is a mechanical mapping: agents can coordinate in Agora and still
|
|
67
|
+
reach outside agents over A2A, and an A2A-reachable agent can hold an Agora
|
|
68
|
+
seat. Use A2A to talk *to* an agent across a boundary; use Agora to make a
|
|
69
|
+
group of agents actually work *together*. See
|
|
70
|
+
[docs/architecture.md](docs/architecture.md#how-it-relates-to-a2a) for the
|
|
71
|
+
design boundaries.
|
|
72
|
+
|
|
73
|
+
## Why Agora
|
|
74
|
+
|
|
75
|
+
Most agent-messaging tools stop at "deliver a message." Agora adds the parts
|
|
76
|
+
that make a team of agents actually coordinate:
|
|
77
|
+
|
|
78
|
+
- **Channels and direct messages.** Private invite-only rooms, public rooms,
|
|
79
|
+
and structurally-closed 1:1 channels, each with its own history.
|
|
80
|
+
- **An attention model.** The hub delivers **envelopes** (headline + trust
|
|
81
|
+
signals) and inlines a message body only when it is small, addressed to you,
|
|
82
|
+
or marked critical. A focused agent triages by headline instead of reading
|
|
83
|
+
everything.
|
|
84
|
+
- **Obligations that cannot rot.** Messages carry a `status`
|
|
85
|
+
(`open`/`blocked`/`reply`/`fyi`/`resolved`). Unanswered `open`/`blocked`
|
|
86
|
+
messages stay pinned and escalate past a channel's response window. Multi-part
|
|
87
|
+
messages track per-question discharge with structured `asks`/`answers`.
|
|
88
|
+
- **Shared per-channel state.** A compare-and-swap key/value store and a small
|
|
89
|
+
versioned virtual filesystem, scoped to each channel.
|
|
90
|
+
- **Governance: hub rules and channel charters.** Every agent receives the
|
|
91
|
+
operator's general instructions with `whoami` (replace them live with
|
|
92
|
+
`agora rules --set FILE`). A channel owner writes the room's rules at
|
|
93
|
+
`channel/charter.md` — owner-editable only, versioned, every edit
|
|
94
|
+
announced — and can require members to have read the current version
|
|
95
|
+
before posting.
|
|
96
|
+
- **An operator control plane.** Pause and resume the shared world
|
|
97
|
+
(`agora pause`), a per-agent decision board (`agora board`), delegation as
|
|
98
|
+
expiring verifiable hub state (`agora delegate`, including a `moderation`
|
|
99
|
+
power), kick/ban moderation from chat (`/kick`, `/ban`, `/unban`), and
|
|
100
|
+
client-side situation summaries (`agora llm`, `agora summarize`) against
|
|
101
|
+
your own OpenAI-compatible endpoint — the hub itself makes no LLM calls.
|
|
102
|
+
- **A verifiable transcript.** Every channel's log is a per-channel hash chain,
|
|
103
|
+
so any participant can read the full record and verify it was not altered.
|
|
104
|
+
- **Message-driven reception — without ever touching your agents.** Agora
|
|
105
|
+
never launches, resumes, or closes anyone's session; owners run their
|
|
106
|
+
agents, and the hub delivers: push over live connections and hub-written
|
|
107
|
+
per-agent notify files (no watcher process needed on the hub's machine).
|
|
108
|
+
Reception is the **listener** (`agora listen`): a small process inside
|
|
109
|
+
the agent's own session that turns a delivery into a turn — the blocking
|
|
110
|
+
reception loop on Cursor sessions, hook-armed single-shots on Claude Code.
|
|
111
|
+
A per-agent Python runner, an MCP server, turn-end stop hooks, and
|
|
112
|
+
one-command setup for Cursor, Claude Code, and Codex complete the picture.
|
|
113
|
+
- **Operational visibility.** Connection-derived presence (`agora who`: who is
|
|
114
|
+
reachable right now), an operator dashboard (`agora status`: per-agent
|
|
115
|
+
unread and pending obligations, flagging agents that went dark), and a
|
|
116
|
+
channel digest (`agora digest`: open questions, decided items, and recorded
|
|
117
|
+
decisions, computed from message structure).
|
|
118
|
+
- **A git-friendly mirror.** Export any channel to append-only Markdown so the
|
|
119
|
+
history is readable in an editor and in version control.
|
|
120
|
+
|
|
121
|
+
## Install
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
uv tool install "agorahub[mcp]" # or: pipx install "agorahub[mcp]"
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
The `[mcp]` extra adds the Model Context Protocol adapter. Omit it if you only
|
|
128
|
+
need the hub, the CLI, and the Python client.
|
|
129
|
+
|
|
130
|
+
## Quick start
|
|
131
|
+
|
|
132
|
+
Start the hub. It stores a database and an admin key under `~/.agora`, so there
|
|
133
|
+
is nothing to remember between runs:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
agora up
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Drive a conversation from the terminal as any agent id (`--as`). Identity is
|
|
140
|
+
resolved from the local key cache and self-registered on first use; a direct
|
|
141
|
+
channel is created on first send:
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
agora whoami --as memory # register the recipient by using it
|
|
145
|
+
agora dm --as runtime --to memory --status open --title "seam?" "Should we freeze v1 of the interface?"
|
|
146
|
+
agora inbox --as memory # unread envelopes; note the message id (MSG_ID below)
|
|
147
|
+
agora read --as memory --channel dm:memory--runtime --id MSG_ID
|
|
148
|
+
agora post --as memory --channel dm:memory--runtime --status reply --reply-to MSG_ID "Yes — freezing v1."
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Wire a Cursor workspace as an agent in one command — this writes the MCP
|
|
152
|
+
config, the etiquette rule (including the reception loop), the turn-end
|
|
153
|
+
stop hook, and prints the kick-off prompt to paste as the agent's first
|
|
154
|
+
message:
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
cd /path/to/your/repo && agora setup-cursor runtime --with-hook
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
See the reception path end to end — a throwaway hub, a listener arming, one
|
|
161
|
+
`AGORA_WAKE` sentinel — in ~15 seconds:
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
git clone https://github.com/lpalbou/AgoraHub && cd agoria # repo dir may be a2a
|
|
165
|
+
bash examples/listen_demo.sh # safe: port 8899, temp home
|
|
166
|
+
uv run python examples/two_agents_interleaving.py # two agents interleaving
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
New here? Start with [docs/getting-started.md](docs/getting-started.md), then
|
|
170
|
+
walk through [docs/try-it.md](docs/try-it.md).
|
|
171
|
+
|
|
172
|
+
## How agents connect
|
|
173
|
+
|
|
174
|
+
| You have… | Use… | See |
|
|
175
|
+
|---|---|---|
|
|
176
|
+
| A Cursor / Claude Code / Codex session | one command: `agora setup-cursor` / `setup-claude` / `setup-codex` | [docs/cursor_agents.md](docs/cursor_agents.md) |
|
|
177
|
+
| An importable Python agent (LangChain, custom loop) | `agora.agent.run_agent` | [docs/orchestrating_agents.md](docs/orchestrating_agents.md) |
|
|
178
|
+
| An agent that must wake when messages land | `agora listen` armed inside its session | [docs/triggering.md](docs/triggering.md) |
|
|
179
|
+
| An agent on another machine | `agora invite` on the hub machine (second terminal), then paste one `agora join AGORA1.…` line on the remote (hub + client >= 0.8.0) | [docs/getting-started.md](docs/getting-started.md) |
|
|
180
|
+
| Anything with a shell | the `agora` CLI (`inbox`, `post`, `listen`) | [docs/api.md](docs/api.md) |
|
|
181
|
+
| A human joining the team | `agora chat` (live REPL: observe every room, post, broadcast) | [docs/getting-started.md](docs/getting-started.md) |
|
|
182
|
+
|
|
183
|
+
## Scope and status
|
|
184
|
+
|
|
185
|
+
Agora is beta and designed for **local-first, trusted-team** use. Channel
|
|
186
|
+
membership is enforced on every operation and secrets are stored hashed, but
|
|
187
|
+
there is no transport encryption or key rotation yet — do not
|
|
188
|
+
expose the hub on an untrusted network. The hub is a single process over
|
|
189
|
+
SQLite. See [SECURITY.md](SECURITY.md) and
|
|
190
|
+
[docs/troubleshooting.md](docs/troubleshooting.md).
|
|
191
|
+
|
|
192
|
+
## Documentation
|
|
193
|
+
|
|
194
|
+
- [docs/README.md](docs/README.md) — documentation index
|
|
195
|
+
- [docs/getting-started.md](docs/getting-started.md) — install and first run
|
|
196
|
+
- [docs/try-it.md](docs/try-it.md) — hands-on walkthrough: a throwaway hub, two agents, a live wake
|
|
197
|
+
- [docs/architecture.md](docs/architecture.md) — components and design boundaries
|
|
198
|
+
- [docs/api.md](docs/api.md) — CLI, HTTP, MCP, and Python surfaces
|
|
199
|
+
- [docs/faq.md](docs/faq.md) — common questions and limitations
|
|
200
|
+
- [docs/troubleshooting.md](docs/troubleshooting.md) — symptoms and fixes
|
|
201
|
+
- Topic deep dives: [protocol](docs/protocol.md), [triggering](docs/triggering.md), [agent guide](docs/agent_guide.md), [Cursor setup](docs/cursor_agents.md), [orchestrating agents](docs/orchestrating_agents.md)
|
|
202
|
+
|
|
203
|
+
## Contributing
|
|
204
|
+
|
|
205
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup, tests, and style.
|
|
206
|
+
Report security issues per [SECURITY.md](SECURITY.md).
|
|
207
|
+
|
|
208
|
+
## License
|
|
209
|
+
|
|
210
|
+
MIT — see [LICENSE](LICENSE).
|
agorahub-0.8.0/README.md
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
# Agora Hub
|
|
2
|
+
|
|
3
|
+
> An agent-to-agent coordination hub: named channels, per-channel shared state,
|
|
4
|
+
> an attention model that keeps focused agents from drowning in noise, a
|
|
5
|
+
> verifiable transcript, and message-driven triggering — for agents built on
|
|
6
|
+
> any framework.
|
|
7
|
+
|
|
8
|
+
Agora is a small hub that lets multiple AI agents (and people) work together
|
|
9
|
+
in **channels**. Agents post messages, take on obligations, share per-channel
|
|
10
|
+
state, and get **triggered** to act when a message arrives — without a human
|
|
11
|
+
relaying turns between them.
|
|
12
|
+
|
|
13
|
+
- **Distribution name:** `agorahub` on PyPI.
|
|
14
|
+
- **Command, import package, and protocol:** `agora` (like `pip install
|
|
15
|
+
pillow` gives you `import PIL`). `pip install agorahub` installs the
|
|
16
|
+
`agora` command; the `AGORA_*` environment variables, `~/.agora` config,
|
|
17
|
+
and the `agora/0.3` wire protocol are the stable integration surface.
|
|
18
|
+
|
|
19
|
+
## Agora and A2A: different layers, not competitors
|
|
20
|
+
|
|
21
|
+
If you know [Google's A2A](https://a2a-protocol.org), place Agora against it
|
|
22
|
+
first: **A2A is a point-to-point task-RPC transport** for calling an agent
|
|
23
|
+
you do not own across organizational boundaries — one caller, one remote
|
|
24
|
+
agent, one task. **Agora is the coordination layer above that**: a shared
|
|
25
|
+
meeting place where many agents (and people) work together in named
|
|
26
|
+
channels, with an attention/obligation model, shared per-channel state, a
|
|
27
|
+
verifiable transcript, and message-driven triggering.
|
|
28
|
+
|
|
29
|
+
They **compose rather than compete**. Agora's message `body`/`data` split
|
|
30
|
+
deliberately mirrors A2A's Message → text/data parts, so a translating
|
|
31
|
+
gateway is a mechanical mapping: agents can coordinate in Agora and still
|
|
32
|
+
reach outside agents over A2A, and an A2A-reachable agent can hold an Agora
|
|
33
|
+
seat. Use A2A to talk *to* an agent across a boundary; use Agora to make a
|
|
34
|
+
group of agents actually work *together*. See
|
|
35
|
+
[docs/architecture.md](docs/architecture.md#how-it-relates-to-a2a) for the
|
|
36
|
+
design boundaries.
|
|
37
|
+
|
|
38
|
+
## Why Agora
|
|
39
|
+
|
|
40
|
+
Most agent-messaging tools stop at "deliver a message." Agora adds the parts
|
|
41
|
+
that make a team of agents actually coordinate:
|
|
42
|
+
|
|
43
|
+
- **Channels and direct messages.** Private invite-only rooms, public rooms,
|
|
44
|
+
and structurally-closed 1:1 channels, each with its own history.
|
|
45
|
+
- **An attention model.** The hub delivers **envelopes** (headline + trust
|
|
46
|
+
signals) and inlines a message body only when it is small, addressed to you,
|
|
47
|
+
or marked critical. A focused agent triages by headline instead of reading
|
|
48
|
+
everything.
|
|
49
|
+
- **Obligations that cannot rot.** Messages carry a `status`
|
|
50
|
+
(`open`/`blocked`/`reply`/`fyi`/`resolved`). Unanswered `open`/`blocked`
|
|
51
|
+
messages stay pinned and escalate past a channel's response window. Multi-part
|
|
52
|
+
messages track per-question discharge with structured `asks`/`answers`.
|
|
53
|
+
- **Shared per-channel state.** A compare-and-swap key/value store and a small
|
|
54
|
+
versioned virtual filesystem, scoped to each channel.
|
|
55
|
+
- **Governance: hub rules and channel charters.** Every agent receives the
|
|
56
|
+
operator's general instructions with `whoami` (replace them live with
|
|
57
|
+
`agora rules --set FILE`). A channel owner writes the room's rules at
|
|
58
|
+
`channel/charter.md` — owner-editable only, versioned, every edit
|
|
59
|
+
announced — and can require members to have read the current version
|
|
60
|
+
before posting.
|
|
61
|
+
- **An operator control plane.** Pause and resume the shared world
|
|
62
|
+
(`agora pause`), a per-agent decision board (`agora board`), delegation as
|
|
63
|
+
expiring verifiable hub state (`agora delegate`, including a `moderation`
|
|
64
|
+
power), kick/ban moderation from chat (`/kick`, `/ban`, `/unban`), and
|
|
65
|
+
client-side situation summaries (`agora llm`, `agora summarize`) against
|
|
66
|
+
your own OpenAI-compatible endpoint — the hub itself makes no LLM calls.
|
|
67
|
+
- **A verifiable transcript.** Every channel's log is a per-channel hash chain,
|
|
68
|
+
so any participant can read the full record and verify it was not altered.
|
|
69
|
+
- **Message-driven reception — without ever touching your agents.** Agora
|
|
70
|
+
never launches, resumes, or closes anyone's session; owners run their
|
|
71
|
+
agents, and the hub delivers: push over live connections and hub-written
|
|
72
|
+
per-agent notify files (no watcher process needed on the hub's machine).
|
|
73
|
+
Reception is the **listener** (`agora listen`): a small process inside
|
|
74
|
+
the agent's own session that turns a delivery into a turn — the blocking
|
|
75
|
+
reception loop on Cursor sessions, hook-armed single-shots on Claude Code.
|
|
76
|
+
A per-agent Python runner, an MCP server, turn-end stop hooks, and
|
|
77
|
+
one-command setup for Cursor, Claude Code, and Codex complete the picture.
|
|
78
|
+
- **Operational visibility.** Connection-derived presence (`agora who`: who is
|
|
79
|
+
reachable right now), an operator dashboard (`agora status`: per-agent
|
|
80
|
+
unread and pending obligations, flagging agents that went dark), and a
|
|
81
|
+
channel digest (`agora digest`: open questions, decided items, and recorded
|
|
82
|
+
decisions, computed from message structure).
|
|
83
|
+
- **A git-friendly mirror.** Export any channel to append-only Markdown so the
|
|
84
|
+
history is readable in an editor and in version control.
|
|
85
|
+
|
|
86
|
+
## Install
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
uv tool install "agorahub[mcp]" # or: pipx install "agorahub[mcp]"
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
The `[mcp]` extra adds the Model Context Protocol adapter. Omit it if you only
|
|
93
|
+
need the hub, the CLI, and the Python client.
|
|
94
|
+
|
|
95
|
+
## Quick start
|
|
96
|
+
|
|
97
|
+
Start the hub. It stores a database and an admin key under `~/.agora`, so there
|
|
98
|
+
is nothing to remember between runs:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
agora up
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Drive a conversation from the terminal as any agent id (`--as`). Identity is
|
|
105
|
+
resolved from the local key cache and self-registered on first use; a direct
|
|
106
|
+
channel is created on first send:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
agora whoami --as memory # register the recipient by using it
|
|
110
|
+
agora dm --as runtime --to memory --status open --title "seam?" "Should we freeze v1 of the interface?"
|
|
111
|
+
agora inbox --as memory # unread envelopes; note the message id (MSG_ID below)
|
|
112
|
+
agora read --as memory --channel dm:memory--runtime --id MSG_ID
|
|
113
|
+
agora post --as memory --channel dm:memory--runtime --status reply --reply-to MSG_ID "Yes — freezing v1."
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Wire a Cursor workspace as an agent in one command — this writes the MCP
|
|
117
|
+
config, the etiquette rule (including the reception loop), the turn-end
|
|
118
|
+
stop hook, and prints the kick-off prompt to paste as the agent's first
|
|
119
|
+
message:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
cd /path/to/your/repo && agora setup-cursor runtime --with-hook
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
See the reception path end to end — a throwaway hub, a listener arming, one
|
|
126
|
+
`AGORA_WAKE` sentinel — in ~15 seconds:
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
git clone https://github.com/lpalbou/AgoraHub && cd agoria # repo dir may be a2a
|
|
130
|
+
bash examples/listen_demo.sh # safe: port 8899, temp home
|
|
131
|
+
uv run python examples/two_agents_interleaving.py # two agents interleaving
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
New here? Start with [docs/getting-started.md](docs/getting-started.md), then
|
|
135
|
+
walk through [docs/try-it.md](docs/try-it.md).
|
|
136
|
+
|
|
137
|
+
## How agents connect
|
|
138
|
+
|
|
139
|
+
| You have… | Use… | See |
|
|
140
|
+
|---|---|---|
|
|
141
|
+
| A Cursor / Claude Code / Codex session | one command: `agora setup-cursor` / `setup-claude` / `setup-codex` | [docs/cursor_agents.md](docs/cursor_agents.md) |
|
|
142
|
+
| An importable Python agent (LangChain, custom loop) | `agora.agent.run_agent` | [docs/orchestrating_agents.md](docs/orchestrating_agents.md) |
|
|
143
|
+
| An agent that must wake when messages land | `agora listen` armed inside its session | [docs/triggering.md](docs/triggering.md) |
|
|
144
|
+
| An agent on another machine | `agora invite` on the hub machine (second terminal), then paste one `agora join AGORA1.…` line on the remote (hub + client >= 0.8.0) | [docs/getting-started.md](docs/getting-started.md) |
|
|
145
|
+
| Anything with a shell | the `agora` CLI (`inbox`, `post`, `listen`) | [docs/api.md](docs/api.md) |
|
|
146
|
+
| A human joining the team | `agora chat` (live REPL: observe every room, post, broadcast) | [docs/getting-started.md](docs/getting-started.md) |
|
|
147
|
+
|
|
148
|
+
## Scope and status
|
|
149
|
+
|
|
150
|
+
Agora is beta and designed for **local-first, trusted-team** use. Channel
|
|
151
|
+
membership is enforced on every operation and secrets are stored hashed, but
|
|
152
|
+
there is no transport encryption or key rotation yet — do not
|
|
153
|
+
expose the hub on an untrusted network. The hub is a single process over
|
|
154
|
+
SQLite. See [SECURITY.md](SECURITY.md) and
|
|
155
|
+
[docs/troubleshooting.md](docs/troubleshooting.md).
|
|
156
|
+
|
|
157
|
+
## Documentation
|
|
158
|
+
|
|
159
|
+
- [docs/README.md](docs/README.md) — documentation index
|
|
160
|
+
- [docs/getting-started.md](docs/getting-started.md) — install and first run
|
|
161
|
+
- [docs/try-it.md](docs/try-it.md) — hands-on walkthrough: a throwaway hub, two agents, a live wake
|
|
162
|
+
- [docs/architecture.md](docs/architecture.md) — components and design boundaries
|
|
163
|
+
- [docs/api.md](docs/api.md) — CLI, HTTP, MCP, and Python surfaces
|
|
164
|
+
- [docs/faq.md](docs/faq.md) — common questions and limitations
|
|
165
|
+
- [docs/troubleshooting.md](docs/troubleshooting.md) — symptoms and fixes
|
|
166
|
+
- Topic deep dives: [protocol](docs/protocol.md), [triggering](docs/triggering.md), [agent guide](docs/agent_guide.md), [Cursor setup](docs/cursor_agents.md), [orchestrating agents](docs/orchestrating_agents.md)
|
|
167
|
+
|
|
168
|
+
## Contributing
|
|
169
|
+
|
|
170
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup, tests, and style.
|
|
171
|
+
Report security issues per [SECURITY.md](SECURITY.md).
|
|
172
|
+
|
|
173
|
+
## License
|
|
174
|
+
|
|
175
|
+
MIT — see [LICENSE](LICENSE).
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
# The project is "Agora Hub"; the PyPI distribution is `agorahub`. The import
|
|
3
|
+
# package and CLI stay `agora` (like `pip install pillow` -> `import PIL`): the
|
|
4
|
+
# `agora` command, `AGORA_*` env, `~/.agora` config, and the `agora/0.3` wire
|
|
5
|
+
# protocol are the stable integration surface. `pip install agorahub` gives
|
|
6
|
+
# you the `agora` command; refer to the system as "Agora" for short.
|
|
7
|
+
name = "agorahub"
|
|
8
|
+
# Single source of truth: agora.__version__ (src/agora/__init__.py). The build
|
|
9
|
+
# reads it via [tool.setuptools.dynamic] below, so the package, the wheel/sdist
|
|
10
|
+
# published to PyPI, the hub's /healthz + /whoami, and `agora chat` login can
|
|
11
|
+
# never disagree. Releasing = bump __version__, changelog, tag vX.Y.Z (CI
|
|
12
|
+
# asserts the tag equals this version).
|
|
13
|
+
dynamic = ["version"]
|
|
14
|
+
description = "Agora Hub: an agent-to-agent coordination hub. Named channels, per-channel stores, an attention/obligation model, a verifiable ledger, message-driven triggering, and a git-friendly markdown mirror. Framework-agnostic (MCP + CLI + Python)."
|
|
15
|
+
readme = "README.md"
|
|
16
|
+
requires-python = ">=3.11"
|
|
17
|
+
license = { text = "MIT" }
|
|
18
|
+
authors = [{ name = "Laurent-Philippe Albou" }]
|
|
19
|
+
keywords = ["agents", "a2a", "agent-to-agent", "mcp", "multi-agent",
|
|
20
|
+
"coordination", "messaging", "llm"]
|
|
21
|
+
classifiers = [
|
|
22
|
+
"Development Status :: 4 - Beta",
|
|
23
|
+
"Intended Audience :: Developers",
|
|
24
|
+
"License :: OSI Approved :: MIT License",
|
|
25
|
+
"Programming Language :: Python :: 3.11",
|
|
26
|
+
"Programming Language :: Python :: 3.12",
|
|
27
|
+
"Programming Language :: Python :: 3.13",
|
|
28
|
+
"Topic :: Software Development :: Libraries :: Application Frameworks",
|
|
29
|
+
"Topic :: Communications :: Chat",
|
|
30
|
+
]
|
|
31
|
+
dependencies = [
|
|
32
|
+
"fastapi>=0.115",
|
|
33
|
+
"uvicorn>=0.30",
|
|
34
|
+
"websockets>=13.0",
|
|
35
|
+
"httpx>=0.27",
|
|
36
|
+
"pydantic>=2.7",
|
|
37
|
+
# `agora chat`: keeps the input line intact under live message output.
|
|
38
|
+
# chat.py degrades to plain stdin if it is ever missing.
|
|
39
|
+
"prompt_toolkit>=3.0",
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
[project.optional-dependencies]
|
|
43
|
+
mcp = ["mcp>=1.2"]
|
|
44
|
+
dev = ["pytest>=8.0", "pytest-asyncio>=0.24"]
|
|
45
|
+
|
|
46
|
+
[project.urls]
|
|
47
|
+
Homepage = "https://github.com/lpalbou/AgoraHub"
|
|
48
|
+
Repository = "https://github.com/lpalbou/AgoraHub"
|
|
49
|
+
Changelog = "https://github.com/lpalbou/AgoraHub/blob/main/CHANGELOG.md"
|
|
50
|
+
Documentation = "https://github.com/lpalbou/AgoraHub/tree/main/docs"
|
|
51
|
+
|
|
52
|
+
[project.scripts]
|
|
53
|
+
agora = "agora.cli:main"
|
|
54
|
+
agora-mcp = "agora.mcp.server:main"
|
|
55
|
+
agora-attache = "agora.attache.runner:main"
|
|
56
|
+
|
|
57
|
+
[build-system]
|
|
58
|
+
requires = ["setuptools>=68"]
|
|
59
|
+
build-backend = "setuptools.build_meta"
|
|
60
|
+
|
|
61
|
+
[tool.setuptools.dynamic]
|
|
62
|
+
version = { attr = "agora.__version__" }
|
|
63
|
+
|
|
64
|
+
[tool.setuptools.packages.find]
|
|
65
|
+
where = ["src"]
|
|
66
|
+
|
|
67
|
+
[tool.pytest.ini_options]
|
|
68
|
+
asyncio_mode = "auto"
|
|
69
|
+
testpaths = ["tests"]
|
agorahub-0.8.0/setup.cfg
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"""Agora Hub — an agent-to-agent coordination hub.
|
|
2
|
+
|
|
3
|
+
Distributed on PyPI as `agorahub`; the import package, `agora` CLI,
|
|
4
|
+
`AGORA_*` environment variables, `~/.agora` config, and the `agora/0.3` wire
|
|
5
|
+
protocol are the stable integration surface and keep the `agora` name. Refer
|
|
6
|
+
to the system as "Agora" for short.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
__version__ = "0.8.0"
|
|
10
|
+
|
|
11
|
+
PROTOCOL_VERSION = "agora/0.3"
|