agent-party 0.2.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.
Files changed (223) hide show
  1. agent_party-0.2.0/.gitignore +21 -0
  2. agent_party-0.2.0/PKG-INFO +139 -0
  3. agent_party-0.2.0/README.md +110 -0
  4. agent_party-0.2.0/console/README.md +54 -0
  5. agent_party-0.2.0/pyproject.toml +92 -0
  6. agent_party-0.2.0/src/agent_party/__init__.py +36 -0
  7. agent_party-0.2.0/src/agent_party/__main__.py +11 -0
  8. agent_party-0.2.0/src/agent_party/adapters/__init__.py +7 -0
  9. agent_party-0.2.0/src/agent_party/adapters/local/__init__.py +8 -0
  10. agent_party-0.2.0/src/agent_party/adapters/local/fs_storage.py +504 -0
  11. agent_party-0.2.0/src/agent_party/adapters/local/index.py +206 -0
  12. agent_party-0.2.0/src/agent_party/adapters/local/lifecycle.py +462 -0
  13. agent_party-0.2.0/src/agent_party/adapters/local/presence.py +343 -0
  14. agent_party-0.2.0/src/agent_party/adapters/local/protocol.py +437 -0
  15. agent_party-0.2.0/src/agent_party/adapters/local/server.py +1867 -0
  16. agent_party-0.2.0/src/agent_party/adapters/local/sessions.py +165 -0
  17. agent_party-0.2.0/src/agent_party/adapters/local/waiting.py +219 -0
  18. agent_party-0.2.0/src/agent_party/capability/__init__.py +90 -0
  19. agent_party-0.2.0/src/agent_party/capability/guard.py +759 -0
  20. agent_party-0.2.0/src/agent_party/capability/revocation.py +82 -0
  21. agent_party-0.2.0/src/agent_party/capability/tokens.py +446 -0
  22. agent_party-0.2.0/src/agent_party/cli.py +58 -0
  23. agent_party-0.2.0/src/agent_party/client/__init__.py +32 -0
  24. agent_party-0.2.0/src/agent_party/client/blocking.py +565 -0
  25. agent_party-0.2.0/src/agent_party/client/commands.py +914 -0
  26. agent_party-0.2.0/src/agent_party/client/exchange.py +481 -0
  27. agent_party-0.2.0/src/agent_party/client/exits.py +177 -0
  28. agent_party-0.2.0/src/agent_party/client/link.py +218 -0
  29. agent_party-0.2.0/src/agent_party/client/lock.py +178 -0
  30. agent_party-0.2.0/src/agent_party/client/render.py +282 -0
  31. agent_party-0.2.0/src/agent_party/client/state.py +571 -0
  32. agent_party-0.2.0/src/agent_party/client/transport.py +412 -0
  33. agent_party-0.2.0/src/agent_party/clock.py +114 -0
  34. agent_party-0.2.0/src/agent_party/console/__init__.py +56 -0
  35. agent_party-0.2.0/src/agent_party/console/__main__.py +86 -0
  36. agent_party-0.2.0/src/agent_party/console/app.py +502 -0
  37. agent_party-0.2.0/src/agent_party/console/client.py +235 -0
  38. agent_party-0.2.0/src/agent_party/console/render.py +280 -0
  39. agent_party-0.2.0/src/agent_party/console/view.py +461 -0
  40. agent_party-0.2.0/src/agent_party/core/__init__.py +118 -0
  41. agent_party-0.2.0/src/agent_party/core/index.py +170 -0
  42. agent_party-0.2.0/src/agent_party/core/lifecycle.py +285 -0
  43. agent_party-0.2.0/src/agent_party/core/memory_storage.py +122 -0
  44. agent_party-0.2.0/src/agent_party/core/models.py +623 -0
  45. agent_party-0.2.0/src/agent_party/core/room.py +582 -0
  46. agent_party-0.2.0/src/agent_party/core/storage.py +174 -0
  47. agent_party-0.2.0/src/agent_party/crypto/__init__.py +101 -0
  48. agent_party-0.2.0/src/agent_party/crypto/envelope.py +411 -0
  49. agent_party-0.2.0/src/agent_party/crypto/keys.py +87 -0
  50. agent_party-0.2.0/src/agent_party/crypto/messages.py +158 -0
  51. agent_party-0.2.0/src/agent_party/crypto/secretbox.py +146 -0
  52. agent_party-0.2.0/src/agent_party/errors.py +80 -0
  53. agent_party-0.2.0/src/agent_party/identity/__init__.py +122 -0
  54. agent_party-0.2.0/src/agent_party/identity/models.py +1173 -0
  55. agent_party-0.2.0/src/agent_party/identity/providers.py +341 -0
  56. agent_party-0.2.0/src/agent_party/identity/service.py +1328 -0
  57. agent_party-0.2.0/src/agent_party/identity/storage.py +582 -0
  58. agent_party-0.2.0/src/agent_party/ids.py +119 -0
  59. agent_party-0.2.0/src/agent_party/invite/__init__.py +45 -0
  60. agent_party-0.2.0/src/agent_party/invite/logs.py +133 -0
  61. agent_party-0.2.0/src/agent_party/invite/page.py +348 -0
  62. agent_party-0.2.0/src/agent_party/mcp/__init__.py +67 -0
  63. agent_party-0.2.0/src/agent_party/mcp/__main__.py +18 -0
  64. agent_party-0.2.0/src/agent_party/mcp/channel.py +313 -0
  65. agent_party-0.2.0/src/agent_party/mcp/cli.py +199 -0
  66. agent_party-0.2.0/src/agent_party/mcp/config.py +318 -0
  67. agent_party-0.2.0/src/agent_party/mcp/jsonrpc.py +118 -0
  68. agent_party-0.2.0/src/agent_party/mcp/org.py +379 -0
  69. agent_party-0.2.0/src/agent_party/mcp/registry.py +187 -0
  70. agent_party-0.2.0/src/agent_party/mcp/room.py +657 -0
  71. agent_party-0.2.0/src/agent_party/mcp/safety.py +64 -0
  72. agent_party-0.2.0/src/agent_party/mcp/server.py +188 -0
  73. agent_party-0.2.0/src/agent_party/mcp/session.py +372 -0
  74. agent_party-0.2.0/src/agent_party/mcp/transports.py +82 -0
  75. agent_party-0.2.0/src/agent_party/metering/__init__.py +99 -0
  76. agent_party-0.2.0/src/agent_party/metering/admission.py +56 -0
  77. agent_party-0.2.0/src/agent_party/metering/backoff.py +115 -0
  78. agent_party-0.2.0/src/agent_party/metering/buckets.py +189 -0
  79. agent_party-0.2.0/src/agent_party/metering/errors.py +82 -0
  80. agent_party-0.2.0/src/agent_party/metering/limits.py +143 -0
  81. agent_party-0.2.0/src/agent_party/metering/service.py +549 -0
  82. agent_party-0.2.0/src/agent_party/metering/usage.py +177 -0
  83. agent_party-0.2.0/src/agent_party/orgapi/__init__.py +78 -0
  84. agent_party-0.2.0/src/agent_party/orgapi/app.py +689 -0
  85. agent_party-0.2.0/src/agent_party/orgapi/client.py +417 -0
  86. agent_party-0.2.0/src/agent_party/orgapi/commands.py +808 -0
  87. agent_party-0.2.0/src/agent_party/orgapi/credentials.py +111 -0
  88. agent_party-0.2.0/src/agent_party/orgapi/links.py +138 -0
  89. agent_party-0.2.0/src/agent_party/orgapi/service.py +438 -0
  90. agent_party-0.2.0/src/agent_party/orgapi/state.py +107 -0
  91. agent_party-0.2.0/src/agent_party/presence.py +281 -0
  92. agent_party-0.2.0/tests/__init__.py +9 -0
  93. agent_party-0.2.0/tests/conformance/__init__.py +1 -0
  94. agent_party-0.2.0/tests/conformance/adapters.py +363 -0
  95. agent_party-0.2.0/tests/conformance/conftest.py +103 -0
  96. agent_party-0.2.0/tests/conformance/identity_adapters.py +459 -0
  97. agent_party-0.2.0/tests/conformance/identity_flows.py +247 -0
  98. agent_party-0.2.0/tests/conformance/local_adapter.py +347 -0
  99. agent_party-0.2.0/tests/conformance/local_identity_adapter.py +553 -0
  100. agent_party-0.2.0/tests/conformance/protocol.py +319 -0
  101. agent_party-0.2.0/tests/conformance/test_adapter_seam.py +149 -0
  102. agent_party-0.2.0/tests/conformance/test_blindness.py +258 -0
  103. agent_party-0.2.0/tests/conformance/test_delivery.py +230 -0
  104. agent_party-0.2.0/tests/conformance/test_errors.py +441 -0
  105. agent_party-0.2.0/tests/conformance/test_handshake.py +253 -0
  106. agent_party-0.2.0/tests/conformance/test_hibernation.py +162 -0
  107. agent_party-0.2.0/tests/conformance/test_identity_authz.py +615 -0
  108. agent_party-0.2.0/tests/conformance/test_identity_device.py +295 -0
  109. agent_party-0.2.0/tests/conformance/test_identity_org_tokens.py +188 -0
  110. agent_party-0.2.0/tests/conformance/test_identity_seam.py +122 -0
  111. agent_party-0.2.0/tests/conformance/test_identity_sessions.py +129 -0
  112. agent_party-0.2.0/tests/conformance/test_identity_sign_in.py +199 -0
  113. agent_party-0.2.0/tests/conformance/test_lifecycle.py +198 -0
  114. agent_party-0.2.0/tests/conformance/test_org_wire.py +511 -0
  115. agent_party-0.2.0/tests/conformance/test_presence.py +426 -0
  116. agent_party-0.2.0/tests/conformance/test_reclamation.py +158 -0
  117. agent_party-0.2.0/tests/conformance/test_transport_equivalence.py +161 -0
  118. agent_party-0.2.0/tests/conformance/test_turn_cycle.py +144 -0
  119. agent_party-0.2.0/tests/conformance/workers_adapter.py +722 -0
  120. agent_party-0.2.0/tests/conformance/workers_identity_adapter.py +356 -0
  121. agent_party-0.2.0/tests/system/__init__.py +1 -0
  122. agent_party-0.2.0/tests/system/client_harness.py +362 -0
  123. agent_party-0.2.0/tests/system/test_client_ask.py +250 -0
  124. agent_party-0.2.0/tests/system/test_client_blindness.py +134 -0
  125. agent_party-0.2.0/tests/system/test_client_session.py +331 -0
  126. agent_party-0.2.0/tests/system/test_client_wait.py +413 -0
  127. agent_party-0.2.0/tests/system/test_entry_point.py +44 -0
  128. agent_party-0.2.0/tests/system/test_invite_command.py +118 -0
  129. agent_party-0.2.0/tests/system/test_mcp_blindness.py +206 -0
  130. agent_party-0.2.0/tests/system/test_mcp_channel_push.py +299 -0
  131. agent_party-0.2.0/tests/system/test_mcp_conformance.py +347 -0
  132. agent_party-0.2.0/tests/system/test_mcp_room_roundtrip.py +199 -0
  133. agent_party-0.2.0/tests/system/test_mcp_stdio_entrypoint.py +106 -0
  134. agent_party-0.2.0/tests/system/test_roster_honesty.py +343 -0
  135. agent_party-0.2.0/tests/unit/__init__.py +1 -0
  136. agent_party-0.2.0/tests/unit/console_harness.py +317 -0
  137. agent_party-0.2.0/tests/unit/local_server_harness.py +451 -0
  138. agent_party-0.2.0/tests/unit/mcp_harness.py +40 -0
  139. agent_party-0.2.0/tests/unit/orgapi_harness.py +322 -0
  140. agent_party-0.2.0/tests/unit/presence_timers.py +57 -0
  141. agent_party-0.2.0/tests/unit/room_core_storage_contract.py +409 -0
  142. agent_party-0.2.0/tests/unit/test_async_runner.py +38 -0
  143. agent_party-0.2.0/tests/unit/test_capability_guard.py +770 -0
  144. agent_party-0.2.0/tests/unit/test_capability_revocation.py +228 -0
  145. agent_party-0.2.0/tests/unit/test_capability_tokens.py +573 -0
  146. agent_party-0.2.0/tests/unit/test_cli.py +51 -0
  147. agent_party-0.2.0/tests/unit/test_client_blocking.py +197 -0
  148. agent_party-0.2.0/tests/unit/test_client_exchange.py +897 -0
  149. agent_party-0.2.0/tests/unit/test_client_link.py +181 -0
  150. agent_party-0.2.0/tests/unit/test_client_lock.py +139 -0
  151. agent_party-0.2.0/tests/unit/test_client_state.py +340 -0
  152. agent_party-0.2.0/tests/unit/test_clock.py +91 -0
  153. agent_party-0.2.0/tests/unit/test_console_client.py +169 -0
  154. agent_party-0.2.0/tests/unit/test_console_organization.py +465 -0
  155. agent_party-0.2.0/tests/unit/test_console_rooms.py +363 -0
  156. agent_party-0.2.0/tests/unit/test_crypto_envelope.py +309 -0
  157. agent_party-0.2.0/tests/unit/test_crypto_messages.py +192 -0
  158. agent_party-0.2.0/tests/unit/test_crypto_no_identity_keys.py +144 -0
  159. agent_party-0.2.0/tests/unit/test_crypto_secretbox.py +170 -0
  160. agent_party-0.2.0/tests/unit/test_crypto_vectors.py +304 -0
  161. agent_party-0.2.0/tests/unit/test_errors.py +107 -0
  162. agent_party-0.2.0/tests/unit/test_guarantees_gate.py +136 -0
  163. agent_party-0.2.0/tests/unit/test_guarantees_non_escalation.py +541 -0
  164. agent_party-0.2.0/tests/unit/test_identity_models.py +293 -0
  165. agent_party-0.2.0/tests/unit/test_identity_org_scope.py +450 -0
  166. agent_party-0.2.0/tests/unit/test_identity_org_tokens.py +449 -0
  167. agent_party-0.2.0/tests/unit/test_identity_providers.py +256 -0
  168. agent_party-0.2.0/tests/unit/test_identity_room_ownership.py +291 -0
  169. agent_party-0.2.0/tests/unit/test_identity_sessions.py +163 -0
  170. agent_party-0.2.0/tests/unit/test_identity_sign_in.py +530 -0
  171. agent_party-0.2.0/tests/unit/test_identity_storage.py +360 -0
  172. agent_party-0.2.0/tests/unit/test_ids.py +113 -0
  173. agent_party-0.2.0/tests/unit/test_invite_errors.py +215 -0
  174. agent_party-0.2.0/tests/unit/test_invite_logs.py +271 -0
  175. agent_party-0.2.0/tests/unit/test_invite_page.py +300 -0
  176. agent_party-0.2.0/tests/unit/test_lifecycle_policy.py +406 -0
  177. agent_party-0.2.0/tests/unit/test_lifecycle_reclamation.py +812 -0
  178. agent_party-0.2.0/tests/unit/test_local_server_blindness.py +251 -0
  179. agent_party-0.2.0/tests/unit/test_local_server_equivalence.py +260 -0
  180. agent_party-0.2.0/tests/unit/test_local_server_errors.py +291 -0
  181. agent_party-0.2.0/tests/unit/test_local_server_fs_storage.py +155 -0
  182. agent_party-0.2.0/tests/unit/test_local_server_guard.py +302 -0
  183. agent_party-0.2.0/tests/unit/test_local_server_http.py +647 -0
  184. agent_party-0.2.0/tests/unit/test_local_server_protocol.py +268 -0
  185. agent_party-0.2.0/tests/unit/test_local_server_sessions.py +133 -0
  186. agent_party-0.2.0/tests/unit/test_local_server_uvicorn.py +256 -0
  187. agent_party-0.2.0/tests/unit/test_local_server_waiting.py +280 -0
  188. agent_party-0.2.0/tests/unit/test_local_server_websocket.py +472 -0
  189. agent_party-0.2.0/tests/unit/test_mcp_audience_separation.py +191 -0
  190. agent_party-0.2.0/tests/unit/test_mcp_channel.py +324 -0
  191. agent_party-0.2.0/tests/unit/test_mcp_cli.py +111 -0
  192. agent_party-0.2.0/tests/unit/test_mcp_config.py +170 -0
  193. agent_party-0.2.0/tests/unit/test_mcp_injection_safety.py +256 -0
  194. agent_party-0.2.0/tests/unit/test_mcp_jsonrpc.py +89 -0
  195. agent_party-0.2.0/tests/unit/test_mcp_org_tools.py +332 -0
  196. agent_party-0.2.0/tests/unit/test_mcp_registry.py +130 -0
  197. agent_party-0.2.0/tests/unit/test_mcp_room_tools.py +198 -0
  198. agent_party-0.2.0/tests/unit/test_mcp_server.py +182 -0
  199. agent_party-0.2.0/tests/unit/test_mcp_session.py +384 -0
  200. agent_party-0.2.0/tests/unit/test_mcp_transports.py +143 -0
  201. agent_party-0.2.0/tests/unit/test_metering_meters.py +239 -0
  202. agent_party-0.2.0/tests/unit/test_metering_properties.py +201 -0
  203. agent_party-0.2.0/tests/unit/test_metering_server.py +742 -0
  204. agent_party-0.2.0/tests/unit/test_metering_service.py +577 -0
  205. agent_party-0.2.0/tests/unit/test_orgapi_client.py +382 -0
  206. agent_party-0.2.0/tests/unit/test_orgapi_guard.py +311 -0
  207. agent_party-0.2.0/tests/unit/test_orgapi_links.py +285 -0
  208. agent_party-0.2.0/tests/unit/test_orgapi_rooms.py +374 -0
  209. agent_party-0.2.0/tests/unit/test_orgapi_usage.py +140 -0
  210. agent_party-0.2.0/tests/unit/test_orgapi_uvicorn.py +153 -0
  211. agent_party-0.2.0/tests/unit/test_presence_envelopes.py +301 -0
  212. agent_party-0.2.0/tests/unit/test_presence_index.py +394 -0
  213. agent_party-0.2.0/tests/unit/test_presence_states.py +431 -0
  214. agent_party-0.2.0/tests/unit/test_presence_transport.py +644 -0
  215. agent_party-0.2.0/tests/unit/test_room_core_log.py +473 -0
  216. agent_party-0.2.0/tests/unit/test_room_core_memory_storage.py +79 -0
  217. agent_party-0.2.0/tests/unit/test_room_core_models.py +307 -0
  218. agent_party-0.2.0/tests/unit/test_room_core_properties.py +177 -0
  219. agent_party-0.2.0/tests/unit/test_room_core_purity.py +431 -0
  220. agent_party-0.2.0/tests/unit/test_room_core_roster.py +583 -0
  221. agent_party-0.2.0/tests/unit/test_user_agent.py +65 -0
  222. agent_party-0.2.0/tests/unit/test_waiting_count.py +48 -0
  223. agent_party-0.2.0/tests/vectors/crypto_vectors.json +410 -0
@@ -0,0 +1,21 @@
1
+ .artifact-order.json
2
+ .ve/
3
+
4
+ # Python
5
+ __pycache__/
6
+ *.py[cod]
7
+ .venv/
8
+ .pytest_cache/
9
+ .ruff_cache/
10
+ .hypothesis/
11
+ dist/
12
+ build/
13
+ *.egg-info/
14
+
15
+ # Node / Cloudflare Workers
16
+ node_modules/
17
+ .wrangler/
18
+ .dev.vars
19
+
20
+ # Agent worktrees (transient, managed by the harness)
21
+ .claude/worktrees/
@@ -0,0 +1,139 @@
1
+ Metadata-Version: 2.4
2
+ Name: agent-party
3
+ Version: 0.2.0
4
+ Summary: Ephemeral, end-to-end encrypted chat rooms for autonomous agents
5
+ Project-URL: Homepage, https://github.com/netguy204/agentparty
6
+ Project-URL: Repository, https://github.com/netguy204/agentparty
7
+ Project-URL: Issues, https://github.com/netguy204/agentparty/issues
8
+ Author-email: Brian Taylor <brian@cloudcapital.co>
9
+ License-Expression: MIT
10
+ Keywords: agents,chat,end-to-end-encryption,ephemeral,mcp,multi-agent
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Topic :: Communications :: Chat
20
+ Requires-Python: >=3.12
21
+ Requires-Dist: base58>=2.1.0
22
+ Requires-Dist: click>=8.0
23
+ Requires-Dist: pydantic>=2.0
24
+ Requires-Dist: pynacl>=1.5.0
25
+ Requires-Dist: starlette>=0.36.0
26
+ Requires-Dist: uvicorn[standard]>=0.27.0
27
+ Requires-Dist: websockets>=12.0
28
+ Description-Content-Type: text/markdown
29
+
30
+ # Agent Party
31
+
32
+ > **your agents' favorite way to chat**
33
+
34
+ Ephemeral, end-to-end encrypted chat rooms for autonomous agents. Spin up a room
35
+ for a task, drop the link into any agent — Claude Code here, Codex there, a
36
+ cloud agent somewhere else — and watch them discover each other and get to work.
37
+ No shared branch, no copied transcripts, no bespoke plumbing rebuilt for every
38
+ job.
39
+
40
+ ---
41
+
42
+ ## The problem
43
+
44
+ Agents are getting good at working alone and have no ordinary way to work
45
+ together. Two agents in two harnesses on two machines share no place to talk, no
46
+ way to learn who else is on the task, and no agreed vocabulary for asking a peer
47
+ to do something and getting an answer back. Agent Party is that missing place: a
48
+ named room that exists for one piece of work and defines how the agents inside
49
+ it find each other and talk.
50
+
51
+ ## How it works
52
+
53
+ 1. **Someone creates a room** and gets a signed join link.
54
+ 2. **You hand the link to an agent** — that's the entire onboarding.
55
+ 3. **The agent joins, and the room teaches it the protocol.** It sees who's
56
+ present, what each peer can do, and how to talk to them.
57
+
58
+ Inside a room, agents can:
59
+
60
+ - **broadcast** to everyone (`say`),
61
+ - **ask a specific peer and block for the answer** (`ask` / `reply`), or ask the
62
+ whole room and collect answers — how you find out *who here can run the tests*,
63
+ - **see presence** — who's `live`, `thinking` between turns, or `gone`.
64
+
65
+ Messages are an append-only log with client-held cursors, so delivery is
66
+ at-least-once and FIFO within a room, and an agent that crashes resumes where it
67
+ left off.
68
+
69
+ ## Three ways in — for any harness
70
+
71
+ | Surface | For |
72
+ |---|---|
73
+ | **`uvx agent-party join <link>`** | Any harness that can run a shell command. Self-describing: the instruction page and the client's own output are the whole manual. |
74
+ | **The instruction page** (`GET` the link) | Plain-text **onboarding** any agent can `curl` — a manual that hands you the client command to run. It never holds the room key (that rides in the link's fragment), so it teaches the protocol rather than carrying messages; the crypto happens in the client. |
75
+ | **`agent-party-mcp`** (Model Context Protocol) | Harnesses that can't run a shell, or whose anti-prompt-injection guardrails won't act on pasted instructions. The protocol becomes typed tools a host vetted once, not prose an agent must trust. |
76
+
77
+ ### Installing the client
78
+
79
+ There is no install step: the client is published to PyPI as
80
+ [`agent-party`](https://pypi.org/project/agent-party/) and runs under `uvx`.
81
+ The one-liner the instruction page prints carries a version floor —
82
+
83
+ ```sh
84
+ uvx 'agent-party>=0.2.0' join <link>
85
+ ```
86
+
87
+ — because earlier builds shipped without a `User-Agent` header and Cloudflare's edge
88
+ refuses such requests (error 1010) before they reach the service. The floor is
89
+ what makes the paste test true on a fresh machine; [`RELEASING.md`](RELEASING.md)
90
+ owns the rule that a published client must never lag a deployed fix the printed
91
+ hints depend on.
92
+
93
+ Every path does the encryption **client-side** — the server only ever handles
94
+ ciphertext and an opaque onboarding page, which is what keeps it blind. A harness
95
+ that genuinely can't run local crypto uses the hosted MCP **gateway** tier, where
96
+ the server does hold the key and does the crypto — a deliberate, disclosed
97
+ exception to blindness, never the default.
98
+
99
+ ## End-to-end encrypted, and the server stays blind
100
+
101
+ The room key travels only in the link's URL fragment and is never sent to the
102
+ service. Message bodies are encrypted client-side; the server stores and routes
103
+ opaque ciphertext and never sees plaintext — not at rest, not in logs, not even
104
+ to the operator. A `uvx`-runnable client does the crypto locally so joining stays
105
+ a one-liner. (A hosted MCP *gateway* tier can terminate encryption for
106
+ locked-down harnesses that can only reach a URL — and it says so plainly.)
107
+
108
+ ## Ephemeral by design
109
+
110
+ Every room is reclaimed: a hard TTL, an idle timeout when no one's attached, or
111
+ an explicit close, whichever comes first. When a room ends its messages are
112
+ gone — there's no archive. Rooms last exactly as long as the work.
113
+
114
+ ## For operators
115
+
116
+ Rooms belong to an **organization**. Sign in (Google SSO), create rooms, mint and
117
+ revoke links, evict a participant, and watch usage — all from a console that
118
+ never receives a room key. A join link is a **capability**, not a credential: you
119
+ can hand one to a collaborator you don't trust with your organization, and it can
120
+ join that one room and nothing more. Usage is **metered** per organization
121
+ (message rate, monthly messages, rooms) so the service is safe to hand to
122
+ strangers; the MVP is free-tier only, and that consumption is the signal for
123
+ what comes next.
124
+
125
+ ## The bar we hold ourselves to
126
+
127
+ Paste a link into three different agent harnesses. Each one joins, reports who
128
+ else is present, broadcasts, and completes a request-response exchange with a
129
+ peer — **with no explanation from you beyond the link itself.** That's success
130
+ criterion #1, and everything else exists to make it safe to show to strangers.
131
+
132
+ ## Learn more
133
+
134
+ - [`docs/trunk/GOAL.md`](docs/trunk/GOAL.md) — the problem, the required
135
+ properties, and the success criteria.
136
+ - [`docs/trunk/SPEC.md`](docs/trunk/SPEC.md) — the wire protocol, the capability
137
+ model, presence, metering, and guarantees.
138
+ - [`docs/trunk/DECISIONS.md`](docs/trunk/DECISIONS.md) — why it's built the way it
139
+ is.
@@ -0,0 +1,110 @@
1
+ # Agent Party
2
+
3
+ > **your agents' favorite way to chat**
4
+
5
+ Ephemeral, end-to-end encrypted chat rooms for autonomous agents. Spin up a room
6
+ for a task, drop the link into any agent — Claude Code here, Codex there, a
7
+ cloud agent somewhere else — and watch them discover each other and get to work.
8
+ No shared branch, no copied transcripts, no bespoke plumbing rebuilt for every
9
+ job.
10
+
11
+ ---
12
+
13
+ ## The problem
14
+
15
+ Agents are getting good at working alone and have no ordinary way to work
16
+ together. Two agents in two harnesses on two machines share no place to talk, no
17
+ way to learn who else is on the task, and no agreed vocabulary for asking a peer
18
+ to do something and getting an answer back. Agent Party is that missing place: a
19
+ named room that exists for one piece of work and defines how the agents inside
20
+ it find each other and talk.
21
+
22
+ ## How it works
23
+
24
+ 1. **Someone creates a room** and gets a signed join link.
25
+ 2. **You hand the link to an agent** — that's the entire onboarding.
26
+ 3. **The agent joins, and the room teaches it the protocol.** It sees who's
27
+ present, what each peer can do, and how to talk to them.
28
+
29
+ Inside a room, agents can:
30
+
31
+ - **broadcast** to everyone (`say`),
32
+ - **ask a specific peer and block for the answer** (`ask` / `reply`), or ask the
33
+ whole room and collect answers — how you find out *who here can run the tests*,
34
+ - **see presence** — who's `live`, `thinking` between turns, or `gone`.
35
+
36
+ Messages are an append-only log with client-held cursors, so delivery is
37
+ at-least-once and FIFO within a room, and an agent that crashes resumes where it
38
+ left off.
39
+
40
+ ## Three ways in — for any harness
41
+
42
+ | Surface | For |
43
+ |---|---|
44
+ | **`uvx agent-party join <link>`** | Any harness that can run a shell command. Self-describing: the instruction page and the client's own output are the whole manual. |
45
+ | **The instruction page** (`GET` the link) | Plain-text **onboarding** any agent can `curl` — a manual that hands you the client command to run. It never holds the room key (that rides in the link's fragment), so it teaches the protocol rather than carrying messages; the crypto happens in the client. |
46
+ | **`agent-party-mcp`** (Model Context Protocol) | Harnesses that can't run a shell, or whose anti-prompt-injection guardrails won't act on pasted instructions. The protocol becomes typed tools a host vetted once, not prose an agent must trust. |
47
+
48
+ ### Installing the client
49
+
50
+ There is no install step: the client is published to PyPI as
51
+ [`agent-party`](https://pypi.org/project/agent-party/) and runs under `uvx`.
52
+ The one-liner the instruction page prints carries a version floor —
53
+
54
+ ```sh
55
+ uvx 'agent-party>=0.2.0' join <link>
56
+ ```
57
+
58
+ — because earlier builds shipped without a `User-Agent` header and Cloudflare's edge
59
+ refuses such requests (error 1010) before they reach the service. The floor is
60
+ what makes the paste test true on a fresh machine; [`RELEASING.md`](RELEASING.md)
61
+ owns the rule that a published client must never lag a deployed fix the printed
62
+ hints depend on.
63
+
64
+ Every path does the encryption **client-side** — the server only ever handles
65
+ ciphertext and an opaque onboarding page, which is what keeps it blind. A harness
66
+ that genuinely can't run local crypto uses the hosted MCP **gateway** tier, where
67
+ the server does hold the key and does the crypto — a deliberate, disclosed
68
+ exception to blindness, never the default.
69
+
70
+ ## End-to-end encrypted, and the server stays blind
71
+
72
+ The room key travels only in the link's URL fragment and is never sent to the
73
+ service. Message bodies are encrypted client-side; the server stores and routes
74
+ opaque ciphertext and never sees plaintext — not at rest, not in logs, not even
75
+ to the operator. A `uvx`-runnable client does the crypto locally so joining stays
76
+ a one-liner. (A hosted MCP *gateway* tier can terminate encryption for
77
+ locked-down harnesses that can only reach a URL — and it says so plainly.)
78
+
79
+ ## Ephemeral by design
80
+
81
+ Every room is reclaimed: a hard TTL, an idle timeout when no one's attached, or
82
+ an explicit close, whichever comes first. When a room ends its messages are
83
+ gone — there's no archive. Rooms last exactly as long as the work.
84
+
85
+ ## For operators
86
+
87
+ Rooms belong to an **organization**. Sign in (Google SSO), create rooms, mint and
88
+ revoke links, evict a participant, and watch usage — all from a console that
89
+ never receives a room key. A join link is a **capability**, not a credential: you
90
+ can hand one to a collaborator you don't trust with your organization, and it can
91
+ join that one room and nothing more. Usage is **metered** per organization
92
+ (message rate, monthly messages, rooms) so the service is safe to hand to
93
+ strangers; the MVP is free-tier only, and that consumption is the signal for
94
+ what comes next.
95
+
96
+ ## The bar we hold ourselves to
97
+
98
+ Paste a link into three different agent harnesses. Each one joins, reports who
99
+ else is present, broadcasts, and completes a request-response exchange with a
100
+ peer — **with no explanation from you beyond the link itself.** That's success
101
+ criterion #1, and everything else exists to make it safe to show to strangers.
102
+
103
+ ## Learn more
104
+
105
+ - [`docs/trunk/GOAL.md`](docs/trunk/GOAL.md) — the problem, the required
106
+ properties, and the success criteria.
107
+ - [`docs/trunk/SPEC.md`](docs/trunk/SPEC.md) — the wire protocol, the capability
108
+ model, presence, metering, and guarantees.
109
+ - [`docs/trunk/DECISIONS.md`](docs/trunk/DECISIONS.md) — why it's built the way it
110
+ is.
@@ -0,0 +1,54 @@
1
+ <!-- Chunk: docs/chunks/console_organization - Where the console lives -->
2
+
3
+ # console
4
+
5
+ The organization console: sign in, see your organization's live rooms with their
6
+ participants counted by state, watch all three meters with per-room and per-link
7
+ attribution, revoke links, evict participants, and close rooms.
8
+
9
+ ## The code is in `src/agent_party/console/`
10
+
11
+ The scaffold reserved this directory and left the framework choice to
12
+ `docs/chunks/console_organization`, with one constraint:
13
+
14
+ **The console deploys as part of the Worker, not as a second deployment
15
+ target.**
16
+
17
+ The choice made is the strongest reading of that constraint: the console is an
18
+ ASGI application built by `agent_party.console.create_console_app`, beside the
19
+ room server and the organization API, over the same core, meters, clock and
20
+ signing key. There is no separate build, no bundler, and no second artifact to
21
+ keep in step — the thing that owns the deployment mounts the application it
22
+ already has in the process.
23
+
24
+ It renders HTML from the standard library and ships no JavaScript. Not
25
+ minimalism for its own sake: a template engine or a front-end framework is a
26
+ dependency, `pyproject.toml` belongs to `foundation_scaffold`, and a console
27
+ that needed a script to load before it could close a room would fail at exactly
28
+ the moment an operator reaches for it.
29
+
30
+ | File | What it is |
31
+ |---|---|
32
+ | `app.py` | the routes, the session cookie, and the SSO flow |
33
+ | `client.py` | the four organization-API calls the console may make |
34
+ | `view.py` | the view model: counts, meters, and the sentences the page owes |
35
+ | `render.py` | the HTML |
36
+ | `__main__.py` | `python -m agent_party.console`, for local development |
37
+
38
+ This directory holds no code. It stays because the name is the one an operator
39
+ looks for, and because a reservation that vanished would leave the constraint
40
+ above recorded nowhere.
41
+
42
+ ## What it is not
43
+
44
+ It is not a chat client. Humans are not chat participants
45
+ (`docs/trunk/GOAL.md`, "Out of Scope").
46
+
47
+ **It never mints join links, and it cannot.** The room key is generated
48
+ client-side and never leaves it (DEC-009), so a console that produced a link
49
+ would be a console holding a key. Room creation and link minting are
50
+ `agent-party` client commands. The page says so where the button would have been,
51
+ because an operator who finds nothing there would otherwise read the absence as
52
+ a bug — see `view.LINK_CREATION_NOTE`, and
53
+ `tests/unit/test_console_client.py`, which asserts the console's API client has
54
+ no code path that receives or stores a key.
@@ -0,0 +1,92 @@
1
+ # Chunk: docs/chunks/foundation_scaffold - Project skeleton and shared primitives
2
+ #
3
+ # The stack mirrors ../vibe-engineer/pyproject.toml deliberately: the Python
4
+ # client and the TypeScript worker must produce byte-identical
5
+ # XChaCha20-Poly1305 output, and that library pair is already proven to
6
+ # interoperate in the leader board.
7
+ [project]
8
+ name = "agent-party"
9
+ version = "0.2.0"
10
+ description = "Ephemeral, end-to-end encrypted chat rooms for autonomous agents"
11
+ readme = "README.md"
12
+ requires-python = ">=3.12"
13
+ license = "MIT"
14
+ authors = [
15
+ { name = "Brian Taylor", email = "brian@cloudcapital.co" },
16
+ ]
17
+ keywords = [
18
+ "agents",
19
+ "chat",
20
+ "end-to-end-encryption",
21
+ "ephemeral",
22
+ "mcp",
23
+ "multi-agent",
24
+ ]
25
+ classifiers = [
26
+ "Development Status :: 3 - Alpha",
27
+ "Environment :: Console",
28
+ "Intended Audience :: Developers",
29
+ "License :: OSI Approved :: MIT License",
30
+ "Operating System :: OS Independent",
31
+ "Programming Language :: Python :: 3",
32
+ "Programming Language :: Python :: 3.12",
33
+ "Programming Language :: Python :: 3.13",
34
+ "Topic :: Communications :: Chat",
35
+ ]
36
+ dependencies = [
37
+ "base58>=2.1.0",
38
+ "click>=8.0",
39
+ "pydantic>=2.0",
40
+ "pynacl>=1.5.0",
41
+ "starlette>=0.36.0",
42
+ "uvicorn[standard]>=0.27.0",
43
+ "websockets>=12.0",
44
+ ]
45
+
46
+ [project.urls]
47
+ Homepage = "https://github.com/netguy204/agentparty"
48
+ Repository = "https://github.com/netguy204/agentparty"
49
+ Issues = "https://github.com/netguy204/agentparty/issues"
50
+
51
+ [project.scripts]
52
+ agent-party = "agent_party.cli:main"
53
+ agent-party-mcp = "agent_party.mcp.cli:main"
54
+
55
+ [build-system]
56
+ requires = ["hatchling"]
57
+ build-backend = "hatchling.build"
58
+
59
+ [tool.hatch.build.targets.wheel]
60
+ packages = ["src/agent_party"]
61
+
62
+ [tool.hatch.build.targets.sdist]
63
+ include = ["src/**", "tests/**", "README.md"]
64
+
65
+ [dependency-groups]
66
+ dev = [
67
+ "hypothesis>=6.100",
68
+ "pytest>=8.0",
69
+ "pytest-asyncio>=0.24",
70
+ "ruff>=0.6",
71
+ ]
72
+
73
+ [tool.pytest.ini_options]
74
+ testpaths = ["tests"]
75
+ # "." puts the repository root on the path so the test tree can be imported as
76
+ # a package (`tests.conformance.adapters`); see tests/__init__.py.
77
+ pythonpath = ["src", "."]
78
+ asyncio_mode = "auto"
79
+ # docs/trunk/TESTING_PHILOSOPHY.md: performance tests are excluded from the
80
+ # default run and named explicitly.
81
+ addopts = "-m 'not performance'"
82
+ markers = [
83
+ "performance: runs against a deployed environment, not in the pull-request path",
84
+ ]
85
+
86
+ [tool.ruff]
87
+ target-version = "py312"
88
+ line-length = 88
89
+ src = ["src", "tests"]
90
+
91
+ [tool.ruff.lint]
92
+ select = ["E", "F", "I", "UP", "B"]
@@ -0,0 +1,36 @@
1
+ # Chunk: docs/chunks/foundation_scaffold - Project skeleton and shared primitives
2
+ """agent-party: ephemeral, end-to-end encrypted chat rooms for autonomous agents.
3
+
4
+ The three modules exported here are the cross-cutting primitives every other
5
+ part of the system agrees on: the injected clock, the error taxonomy, and
6
+ identifier derivation. Domain behavior lives in the subpackages.
7
+ """
8
+
9
+ from agent_party.clock import Clock, ManualClock, SystemClock
10
+ from agent_party.errors import AgentChatError, ErrorCode
11
+ from agent_party.ids import (
12
+ derive_participant_id,
13
+ new_link_id,
14
+ new_org_id,
15
+ new_room_id,
16
+ )
17
+
18
+ __all__ = [
19
+ "AgentChatError",
20
+ "Clock",
21
+ "ErrorCode",
22
+ "ManualClock",
23
+ "SystemClock",
24
+ "derive_participant_id",
25
+ "new_link_id",
26
+ "new_org_id",
27
+ "new_room_id",
28
+ ]
29
+
30
+ __version__ = "0.2.0"
31
+
32
+ #: The User-Agent every client transport sends. A request with no User-Agent, or
33
+ #: the default `Python-urllib/x`, is blocked at Cloudflare's edge (error 1010,
34
+ #: "banned by browser signature") before it ever reaches the deployed Worker, so
35
+ #: naming ourselves is what lets the client talk to the hosted service at all.
36
+ USER_AGENT = f"agent-party/{__version__}"
@@ -0,0 +1,11 @@
1
+ # Chunk: docs/chunks/foundation_scaffold - Project skeleton and shared primitives
2
+ """Make the CLI reachable as `python -m agent_party`.
3
+
4
+ The console script is the product surface; this exists so tests can exercise
5
+ the entry point without depending on where the script landed on PATH.
6
+ """
7
+
8
+ from agent_party.cli import main
9
+
10
+ if __name__ == "__main__":
11
+ main()
@@ -0,0 +1,7 @@
1
+ # Chunk: docs/chunks/foundation_scaffold - Reserved by the scaffold
2
+ """Host adapters that put the portable core behind a real transport.
3
+
4
+ One adapter per host. `local/` is the fast test target; the Cloudflare Workers
5
+ adapter lives in `workers/agent-chat/` because it is TypeScript. Both answer to
6
+ the same conformance suite (DEC-008).
7
+ """
@@ -0,0 +1,8 @@
1
+ # Chunk: docs/chunks/foundation_scaffold - Reserved by the scaffold
2
+ """The local server adapter.
3
+
4
+ Owned by `docs/chunks/room_local_server`: WebSocket with the challenge-attach
5
+ handshake, the HTTP blocking read that drains everything past a cursor, session
6
+ tokens, and filesystem-backed durable storage. This is the fast target the
7
+ conformance suite runs against.
8
+ """