inter-agent-core 0.2.0__py3-none-any.whl

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 (80) hide show
  1. inter_agent/__init__.py +0 -0
  2. inter_agent/core/__init__.py +1 -0
  3. inter_agent/core/adapter_control.py +350 -0
  4. inter_agent/core/auth.py +279 -0
  5. inter_agent/core/channels.py +131 -0
  6. inter_agent/core/client.py +345 -0
  7. inter_agent/core/config.py +325 -0
  8. inter_agent/core/errors.py +31 -0
  9. inter_agent/core/kick.py +111 -0
  10. inter_agent/core/list.py +127 -0
  11. inter_agent/core/publish.py +146 -0
  12. inter_agent/core/router.py +8 -0
  13. inter_agent/core/send.py +265 -0
  14. inter_agent/core/server.py +765 -0
  15. inter_agent/core/shared.py +182 -0
  16. inter_agent/core/shutdown.py +92 -0
  17. inter_agent/core/status.py +291 -0
  18. inter_agent/core/tls.py +141 -0
  19. inter_agent/core/transport.py +37 -0
  20. inter_agent/py.typed +0 -0
  21. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/asyncapi.yaml +225 -0
  22. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/error-codes.md +28 -0
  23. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/examples/auth_challenge.json +6 -0
  24. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/examples/auth_response.json +4 -0
  25. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/examples/broadcast.json +4 -0
  26. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/examples/bye.json +3 -0
  27. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/examples/channels.json +3 -0
  28. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/examples/channels_ok.json +9 -0
  29. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/examples/custom.unknown-pass-through.json +9 -0
  30. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/examples/error.auth-failed.json +5 -0
  31. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/examples/hello.agent-with-label.json +14 -0
  32. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/examples/hello.agent.json +13 -0
  33. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/examples/kick.json +4 -0
  34. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/examples/kick_ok.json +5 -0
  35. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/examples/list.json +3 -0
  36. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/examples/list_ok.json +10 -0
  37. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/examples/msg.custom.json +13 -0
  38. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/examples/msg.text.json +9 -0
  39. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/examples/ping.json +3 -0
  40. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/examples/pong.json +3 -0
  41. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/examples/publish.json +5 -0
  42. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/examples/send.direct.json +5 -0
  43. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/examples/shutdown.json +3 -0
  44. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/examples/shutdown_ok.json +3 -0
  45. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/examples/subscribe.json +4 -0
  46. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/examples/subscribe_ok.json +4 -0
  47. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/examples/unsubscribe.json +4 -0
  48. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/examples/unsubscribe_ok.json +4 -0
  49. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/examples/welcome.json +10 -0
  50. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/schemas/auth_challenge.json +13 -0
  51. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/schemas/auth_response.json +11 -0
  52. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/schemas/broadcast.json +18 -0
  53. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/schemas/bye.json +10 -0
  54. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/schemas/channels.json +10 -0
  55. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/schemas/channels_ok.json +26 -0
  56. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/schemas/custom.json +22 -0
  57. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/schemas/error.json +37 -0
  58. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/schemas/hello.json +59 -0
  59. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/schemas/kick.json +13 -0
  60. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/schemas/kick_ok.json +12 -0
  61. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/schemas/list.json +10 -0
  62. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/schemas/list_ok.json +24 -0
  63. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/schemas/msg.json +29 -0
  64. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/schemas/ping.json +10 -0
  65. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/schemas/pong.json +10 -0
  66. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/schemas/publish.json +23 -0
  67. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/schemas/send.json +22 -0
  68. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/schemas/shutdown.json +10 -0
  69. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/schemas/shutdown_ok.json +10 -0
  70. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/schemas/subscribe.json +15 -0
  71. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/schemas/subscribe_ok.json +11 -0
  72. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/schemas/unsubscribe.json +15 -0
  73. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/schemas/unsubscribe_ok.json +11 -0
  74. inter_agent_core-0.2.0.data/data/share/inter-agent/spec/schemas/welcome.json +36 -0
  75. inter_agent_core-0.2.0.dist-info/METADATA +85 -0
  76. inter_agent_core-0.2.0.dist-info/RECORD +80 -0
  77. inter_agent_core-0.2.0.dist-info/WHEEL +5 -0
  78. inter_agent_core-0.2.0.dist-info/entry_points.txt +10 -0
  79. inter_agent_core-0.2.0.dist-info/licenses/LICENSE.md +21 -0
  80. inter_agent_core-0.2.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,37 @@
1
+ from __future__ import annotations
2
+
3
+ import ipaddress
4
+ import ssl
5
+ from pathlib import Path
6
+
7
+ from inter_agent.core.config import EndpointResolution
8
+ from inter_agent.core.tls import build_client_ssl_context
9
+
10
+
11
+ def websocket_uri(host: str, port: int, tls: bool = False) -> str:
12
+ scheme = "wss" if tls else "ws"
13
+ try:
14
+ display_host = f"[{host}]" if ipaddress.ip_address(host).version == 6 else host
15
+ except ValueError:
16
+ display_host = host
17
+ return f"{scheme}://{display_host}:{port}"
18
+
19
+
20
+ def client_ssl_context(
21
+ tls: bool,
22
+ data_dir: Path | None = None,
23
+ tls_cert_path: Path | None = None,
24
+ ) -> ssl.SSLContext | None:
25
+ if not tls:
26
+ return None
27
+ if data_dir is None:
28
+ raise ValueError("TLS client connections require a data directory")
29
+ return build_client_ssl_context(data_dir, tls_cert_path)
30
+
31
+
32
+ def endpoint_uri(endpoint: EndpointResolution) -> str:
33
+ return websocket_uri(endpoint.host, endpoint.port, endpoint.tls)
34
+
35
+
36
+ def endpoint_ssl_context(endpoint: EndpointResolution) -> ssl.SSLContext | None:
37
+ return client_ssl_context(endpoint.tls, endpoint.data_dir, endpoint.tls_cert_path)
inter_agent/py.typed ADDED
File without changes
@@ -0,0 +1,225 @@
1
+ asyncapi: 2.6.0
2
+ id: urn:inter-agent:protocol
3
+ info:
4
+ title: inter-agent protocol
5
+ version: 0.1.0
6
+ description: >
7
+ Minimal universal-friendly protocol for an inter-agent bus. Clients connect
8
+ over WebSocket (`ws://` or `wss://`) and start with `hello`, complete an
9
+ HMAC-SHA-256 challenge-response using a shared secret, then receive
10
+ `welcome`. Loopback hosts default to plaintext `ws://` unless TLS is
11
+ explicitly enabled; non-loopback hosts default to TLS `wss://` unless TLS
12
+ is explicitly disabled. Handshake capabilities are JSON objects: clients
13
+ declare optional known or extension keys in `hello`, and the server
14
+ advertises supported baseline capabilities in `welcome`. Unknown client
15
+ capability keys may be ignored.
16
+ contact:
17
+ name: Arcane Machine
18
+ url: https://github.com/arcanemachine/inter-agent
19
+ email: arcanemachine@gmail.com
20
+ license:
21
+ name: MIT
22
+ url: https://opensource.org/license/mit
23
+ tags:
24
+ - name: agent-coordination
25
+ defaultContentType: application/json
26
+ servers:
27
+ default:
28
+ url: '{host}:{port}'
29
+ protocol: ws
30
+ description: >
31
+ The resolved local endpoint. Use wss with the same host and port when
32
+ TLS is enabled.
33
+ variables:
34
+ host:
35
+ default: 127.0.0.1
36
+ port:
37
+ default: '16837'
38
+ channels:
39
+ /:
40
+ publish:
41
+ operationId: clientToServer
42
+ message:
43
+ oneOf:
44
+ - $ref: '#/components/messages/Hello'
45
+ - $ref: '#/components/messages/AuthResponse'
46
+ - $ref: '#/components/messages/Send'
47
+ - $ref: '#/components/messages/Broadcast'
48
+ - $ref: '#/components/messages/Ping'
49
+ - $ref: '#/components/messages/Bye'
50
+ - $ref: '#/components/messages/List'
51
+ - $ref: '#/components/messages/Shutdown'
52
+ - $ref: '#/components/messages/Kick'
53
+ - $ref: '#/components/messages/Custom'
54
+ - $ref: '#/components/messages/Subscribe'
55
+ - $ref: '#/components/messages/Unsubscribe'
56
+ - $ref: '#/components/messages/Publish'
57
+ - $ref: '#/components/messages/Channels'
58
+ subscribe:
59
+ operationId: serverToClient
60
+ message:
61
+ oneOf:
62
+ - $ref: '#/components/messages/AuthChallenge'
63
+ - $ref: '#/components/messages/Welcome'
64
+ - $ref: '#/components/messages/Msg'
65
+ - $ref: '#/components/messages/Pong'
66
+ - $ref: '#/components/messages/Error'
67
+ - $ref: '#/components/messages/ListOk'
68
+ - $ref: '#/components/messages/ShutdownOk'
69
+ - $ref: '#/components/messages/KickOk'
70
+ - $ref: '#/components/messages/SubscribeOk'
71
+ - $ref: '#/components/messages/UnsubscribeOk'
72
+ - $ref: '#/components/messages/ChannelsOk'
73
+ components:
74
+ schemas:
75
+ Hello:
76
+ $ref: './schemas/hello.json'
77
+ AuthChallenge:
78
+ $ref: './schemas/auth_challenge.json'
79
+ AuthResponse:
80
+ $ref: './schemas/auth_response.json'
81
+ Welcome:
82
+ $ref: './schemas/welcome.json'
83
+ Send:
84
+ $ref: './schemas/send.json'
85
+ Broadcast:
86
+ $ref: './schemas/broadcast.json'
87
+ Ping:
88
+ $ref: './schemas/ping.json'
89
+ Pong:
90
+ $ref: './schemas/pong.json'
91
+ Bye:
92
+ $ref: './schemas/bye.json'
93
+ Msg:
94
+ $ref: './schemas/msg.json'
95
+ Error:
96
+ $ref: './schemas/error.json'
97
+ List:
98
+ $ref: './schemas/list.json'
99
+ ListOk:
100
+ $ref: './schemas/list_ok.json'
101
+ Shutdown:
102
+ $ref: './schemas/shutdown.json'
103
+ ShutdownOk:
104
+ $ref: './schemas/shutdown_ok.json'
105
+ Kick:
106
+ $ref: './schemas/kick.json'
107
+ KickOk:
108
+ $ref: './schemas/kick_ok.json'
109
+ Custom:
110
+ $ref: './schemas/custom.json'
111
+ Subscribe:
112
+ $ref: './schemas/subscribe.json'
113
+ SubscribeOk:
114
+ $ref: './schemas/subscribe_ok.json'
115
+ Unsubscribe:
116
+ $ref: './schemas/unsubscribe.json'
117
+ UnsubscribeOk:
118
+ $ref: './schemas/unsubscribe_ok.json'
119
+ Publish:
120
+ $ref: './schemas/publish.json'
121
+ Channels:
122
+ $ref: './schemas/channels.json'
123
+ ChannelsOk:
124
+ $ref: './schemas/channels_ok.json'
125
+ messages:
126
+ Hello:
127
+ messageId: inter-agent.hello
128
+ payload:
129
+ $ref: '#/components/schemas/Hello'
130
+ AuthChallenge:
131
+ messageId: inter-agent.auth-challenge
132
+ payload:
133
+ $ref: '#/components/schemas/AuthChallenge'
134
+ AuthResponse:
135
+ messageId: inter-agent.auth-response
136
+ payload:
137
+ $ref: '#/components/schemas/AuthResponse'
138
+ Welcome:
139
+ messageId: inter-agent.welcome
140
+ payload:
141
+ $ref: '#/components/schemas/Welcome'
142
+ Send:
143
+ messageId: inter-agent.send
144
+ payload:
145
+ $ref: '#/components/schemas/Send'
146
+ Broadcast:
147
+ messageId: inter-agent.broadcast
148
+ payload:
149
+ $ref: '#/components/schemas/Broadcast'
150
+ Ping:
151
+ messageId: inter-agent.ping
152
+ payload:
153
+ $ref: '#/components/schemas/Ping'
154
+ Pong:
155
+ messageId: inter-agent.pong
156
+ payload:
157
+ $ref: '#/components/schemas/Pong'
158
+ Bye:
159
+ messageId: inter-agent.bye
160
+ payload:
161
+ $ref: '#/components/schemas/Bye'
162
+ Msg:
163
+ messageId: inter-agent.msg
164
+ payload:
165
+ $ref: '#/components/schemas/Msg'
166
+ Error:
167
+ messageId: inter-agent.error
168
+ payload:
169
+ $ref: '#/components/schemas/Error'
170
+ List:
171
+ messageId: inter-agent.list
172
+ payload:
173
+ $ref: '#/components/schemas/List'
174
+ ListOk:
175
+ messageId: inter-agent.list-ok
176
+ payload:
177
+ $ref: '#/components/schemas/ListOk'
178
+ Shutdown:
179
+ messageId: inter-agent.shutdown
180
+ payload:
181
+ $ref: '#/components/schemas/Shutdown'
182
+ ShutdownOk:
183
+ messageId: inter-agent.shutdown-ok
184
+ payload:
185
+ $ref: '#/components/schemas/ShutdownOk'
186
+ Kick:
187
+ messageId: inter-agent.kick
188
+ payload:
189
+ $ref: '#/components/schemas/Kick'
190
+ KickOk:
191
+ messageId: inter-agent.kick-ok
192
+ payload:
193
+ $ref: '#/components/schemas/KickOk'
194
+ Custom:
195
+ messageId: inter-agent.custom
196
+ payload:
197
+ $ref: '#/components/schemas/Custom'
198
+ Subscribe:
199
+ messageId: inter-agent.subscribe
200
+ payload:
201
+ $ref: '#/components/schemas/Subscribe'
202
+ SubscribeOk:
203
+ messageId: inter-agent.subscribe-ok
204
+ payload:
205
+ $ref: '#/components/schemas/SubscribeOk'
206
+ Unsubscribe:
207
+ messageId: inter-agent.unsubscribe
208
+ payload:
209
+ $ref: '#/components/schemas/Unsubscribe'
210
+ UnsubscribeOk:
211
+ messageId: inter-agent.unsubscribe-ok
212
+ payload:
213
+ $ref: '#/components/schemas/UnsubscribeOk'
214
+ Publish:
215
+ messageId: inter-agent.publish
216
+ payload:
217
+ $ref: '#/components/schemas/Publish'
218
+ Channels:
219
+ messageId: inter-agent.channels
220
+ payload:
221
+ $ref: '#/components/schemas/Channels'
222
+ ChannelsOk:
223
+ messageId: inter-agent.channels-ok
224
+ payload:
225
+ $ref: '#/components/schemas/ChannelsOk'
@@ -0,0 +1,28 @@
1
+ # Error Codes
2
+
3
+ Protocol errors are returned as `{"op":"error","code":"...","message":"..."}`. The `code` field is stable for clients and adapters; `message` is human-readable context and may vary.
4
+
5
+ | Code | Trigger condition | Client expectation |
6
+ | --- | --- | --- |
7
+ | `PROTOCOL_ERROR` | The first frame is not `hello`, a frame is invalid JSON, a frame is not a JSON object, or authenticated `hello.capabilities` is missing or not an object. | Treat the connection as invalid and reconnect with a valid protocol frame. |
8
+ | `AUTH_FAILED` | Challenge-response auth is missing, malformed, or proves the client does not know the shared secret. | Do not retry until server and client secret configuration has been corrected; see the secret rotation procedure in `SECURITY.md`. |
9
+ | `TOO_MANY_CONNECTIONS` | A valid connection attempt would exceed the configured active connection limit. | Close unused sessions or increase the local connection limit. |
10
+ | `BAD_ROLE` | `hello.role` is missing or is not `agent` or `control`, or an agent-role session attempts a control-only operation such as `shutdown`. | Send a valid role or use a control-role connection for control-only operations. |
11
+ | `BAD_SESSION` | `hello.session_id` is missing, empty, or not a string. | Generate and send a string session ID. |
12
+ | `SESSION_TAKEN` | `hello.session_id` is already active on another connection. | Reconnect after the previous connection closes or generate a new session ID. |
13
+ | `BAD_NAME` | An agent `hello.name` is missing or fails routing-name validation. | Choose a lowercase routing name matching the documented name format. |
14
+ | `BAD_LABEL` | `hello.label` is present but is neither a string nor `null`. | Omit the label, send `null`, or send a string display label. |
15
+ | `NAME_TAKEN` | An agent routing name is already connected. | Choose a different routing name or disconnect the existing session. |
16
+ | `UNKNOWN_OP` | A post-handshake frame uses an unsupported `op`. | Use a supported core operation or an extension envelope. |
17
+ | `BAD_TEXT` | A `send`, `broadcast`, or `publish` operation has a non-string `text`. | Send message text as a string. |
18
+ | `BAD_FROM_NAME` | A message operation has a non-string `from_name`. | Omit `from_name` or send it as a string. |
19
+ | `BAD_CUSTOM_TYPE` | A `custom` operation has a missing, empty, non-string, or oversized `custom_type`. | Send a non-empty custom type within the configured byte limit. |
20
+ | `TEXT_TOO_LARGE` | A direct or broadcast message exceeds configured UTF-8 byte text limits (`INTER_AGENT_DIRECT_MAX` or `INTER_AGENT_BROADCAST_MAX`). | Shorten or split the message. |
21
+ | `CUSTOM_PAYLOAD_TOO_LARGE` | A `custom.payload` exceeds the configured JSON-encoded UTF-8 byte limit (`INTER_AGENT_CUSTOM_PAYLOAD_MAX`). | Shorten or split the custom payload. |
22
+ | `UNKNOWN_TARGET` | A direct `send` or targeted `custom` operation names no connected target. | Refresh session presence and retry with a connected routing name. |
23
+ | `AMBIGUOUS_TARGET` | A direct `send` or targeted `custom` operation uses a prefix that matches multiple connected targets. | Retry with a longer prefix or exact routing name. |
24
+ | `BAD_CHANNEL` | A channel operation has a missing, non-string, syntactically invalid, or oversized `channel` value. | Send a valid channel name matching the documented format and byte limit. |
25
+ | `CHANNEL_LIMIT_REACHED` | A subscription would exceed the per-session subscription limit (`INTER_AGENT_SUBSCRIPTIONS_MAX`) or creating a channel would exceed the server channel limit (`INTER_AGENT_CHANNELS_MAX`). | Leave unused channels or increase the configured limit. |
26
+ | `NOT_SUBSCRIBED` | An `unsubscribe` targets a channel the session is not subscribed to. | Subscribe before unsubscribing, or ignore if already unsubscribed. |
27
+ | `UNKNOWN_CHANNEL` | A `publish` targets a channel with no active subscribers. | Subscribe at least one session to the channel before publishing. |
28
+ | `KICKED` | A control-role caller removed this connection with `kick`. The error is sent immediately before the target WebSocket is closed. | Treat the error as terminal for this listener process: stop automatic reconnects. The routing name is free immediately and may register again through an explicit later connect or host/session reload/restart; there is no ban or blocklist. |
@@ -0,0 +1,6 @@
1
+ {
2
+ "op": "auth_challenge",
3
+ "method": "hmac-sha256",
4
+ "server_nonce": "server-nonce",
5
+ "server_proof": "server-proof-hex"
6
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "op": "auth_response",
3
+ "client_proof": "client-proof-hex"
4
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "op": "broadcast",
3
+ "text": "build is green"
4
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "op": "channels_ok",
3
+ "channels": [
4
+ {
5
+ "name": "build",
6
+ "subscribers": ["agent-a", "agent-b"]
7
+ }
8
+ ]
9
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "op": "custom",
3
+ "custom_type": "acme.sync.v1",
4
+ "to": "agent-b",
5
+ "payload": {
6
+ "action": "sync",
7
+ "id": 42
8
+ }
9
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "op": "error",
3
+ "code": "AUTH_FAILED",
4
+ "message": "invalid auth"
5
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "op": "hello",
3
+ "auth": {
4
+ "method": "hmac-sha256",
5
+ "client_nonce": "client-nonce"
6
+ },
7
+ "role": "agent",
8
+ "session_id": "sess-a",
9
+ "name": "agent-a",
10
+ "label": "Agent A",
11
+ "capabilities": {
12
+ "core": {"version": "0.1"}
13
+ }
14
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "op": "hello",
3
+ "auth": {
4
+ "method": "hmac-sha256",
5
+ "client_nonce": "client-nonce"
6
+ },
7
+ "role": "agent",
8
+ "session_id": "sess-a",
9
+ "name": "agent-a",
10
+ "capabilities": {
11
+ "core": {"version": "0.1"}
12
+ }
13
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "op": "kick",
3
+ "name": "agent-a"
4
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "op": "kick_ok",
3
+ "name": "agent-a",
4
+ "session_id": "sess-a"
5
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "op": "list_ok",
3
+ "sessions": [
4
+ {
5
+ "session_id": "sess-a",
6
+ "name": "agent-a",
7
+ "label": "Agent A"
8
+ }
9
+ ]
10
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "op": "msg",
3
+ "msg_id": "msg-b",
4
+ "from": "sess-a",
5
+ "from_name": "agent-a",
6
+ "to": "agent-b",
7
+ "custom_type": "acme.sync.v1",
8
+ "payload": {
9
+ "action": "sync",
10
+ "id": 42
11
+ },
12
+ "ts": "2026-01-01T00:00:00+00:00"
13
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "op": "msg",
3
+ "msg_id": "msg-a",
4
+ "from": "sess-a",
5
+ "from_name": "agent-a",
6
+ "to": "agent-b",
7
+ "text": "run tests",
8
+ "ts": "2026-01-01T00:00:00+00:00"
9
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "op": "publish",
3
+ "channel": "build",
4
+ "text": "hello"
5
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "op": "send",
3
+ "to": "agent-b",
4
+ "text": "run tests"
5
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "op": "subscribe",
3
+ "channel": "build"
4
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "op": "subscribe_ok",
3
+ "channel": "build"
4
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "op": "unsubscribe",
3
+ "channel": "build"
4
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "op": "unsubscribe_ok",
3
+ "channel": "build"
4
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "op": "welcome",
3
+ "session_id": "sess-a",
4
+ "assigned_name": "agent-a",
5
+ "capabilities": {
6
+ "core": {"version": "0.1"},
7
+ "channels": true,
8
+ "rate_limit": false
9
+ }
10
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "title": "AuthChallenge",
4
+ "type": "object",
5
+ "required": ["op", "method", "server_nonce", "server_proof"],
6
+ "properties": {
7
+ "op": { "const": "auth_challenge" },
8
+ "method": { "const": "hmac-sha256" },
9
+ "server_nonce": { "type": "string", "minLength": 1 },
10
+ "server_proof": { "type": "string", "minLength": 1 }
11
+ },
12
+ "additionalProperties": true
13
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "title": "AuthResponse",
4
+ "type": "object",
5
+ "required": ["op", "client_proof"],
6
+ "properties": {
7
+ "op": { "const": "auth_response" },
8
+ "client_proof": { "type": "string", "minLength": 1 }
9
+ },
10
+ "additionalProperties": true
11
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "title": "Broadcast",
4
+ "type": "object",
5
+ "required": ["op", "text"],
6
+ "properties": {
7
+ "op": { "const": "broadcast" },
8
+ "text": {
9
+ "type": "string",
10
+ "description": "Broadcast message text. The server accepts UTF-8 encoded text bytes up to INTER_AGENT_BROADCAST_MAX."
11
+ },
12
+ "from_name": {
13
+ "type": "string",
14
+ "description": "Optional display name for delivered messages; defaults to the sender routing name."
15
+ }
16
+ },
17
+ "additionalProperties": true
18
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "title": "Bye",
4
+ "type": "object",
5
+ "required": ["op"],
6
+ "properties": {
7
+ "op": { "const": "bye" }
8
+ },
9
+ "additionalProperties": true
10
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "title": "Channels",
4
+ "type": "object",
5
+ "required": ["op"],
6
+ "properties": {
7
+ "op": { "const": "channels" }
8
+ },
9
+ "additionalProperties": true
10
+ }
@@ -0,0 +1,26 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "title": "ChannelsOk",
4
+ "type": "object",
5
+ "required": ["op", "channels"],
6
+ "properties": {
7
+ "op": { "const": "channels_ok" },
8
+ "channels": {
9
+ "type": "array",
10
+ "description": "Active channels sorted by name. Each entry contains the channel name and a sorted list of subscriber routing names.",
11
+ "items": {
12
+ "type": "object",
13
+ "required": ["name", "subscribers"],
14
+ "properties": {
15
+ "name": { "type": "string", "description": "Channel name." },
16
+ "subscribers": {
17
+ "type": "array",
18
+ "items": { "type": "string" }
19
+ }
20
+ },
21
+ "additionalProperties": true
22
+ }
23
+ }
24
+ },
25
+ "additionalProperties": true
26
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "title": "Custom",
4
+ "type": "object",
5
+ "required": ["op", "custom_type", "payload"],
6
+ "properties": {
7
+ "op": { "const": "custom" },
8
+ "custom_type": {
9
+ "type": "string",
10
+ "minLength": 1,
11
+ "description": "Extension message type. The server applies the configured UTF-8 byte limit (INTER_AGENT_CUSTOM_TYPE_MAX)."
12
+ },
13
+ "to": {
14
+ "type": ["string", "null"],
15
+ "description": "Optional target routing name or unambiguous routing-name prefix. Exact names are resolved before prefixes."
16
+ },
17
+ "payload": {
18
+ "description": "Pass-through JSON payload. The server applies the configured JSON-encoded UTF-8 byte limit (INTER_AGENT_CUSTOM_PAYLOAD_MAX)."
19
+ }
20
+ },
21
+ "additionalProperties": true
22
+ }