megastructure-arc 0.0.1__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.
- megastructure_arc-0.0.1/.claude/settings.local.json +17 -0
- megastructure_arc-0.0.1/.gitignore +26 -0
- megastructure_arc-0.0.1/.mcp.json +9 -0
- megastructure_arc-0.0.1/LICENSE +21 -0
- megastructure_arc-0.0.1/PKG-INFO +440 -0
- megastructure_arc-0.0.1/README.md +417 -0
- megastructure_arc-0.0.1/arc.js +13 -0
- megastructure_arc-0.0.1/arc.py +2746 -0
- megastructure_arc-0.0.1/demos/naming-sprint/README.md +40 -0
- megastructure_arc-0.0.1/demos/naming-sprint/prompt-judge.md +145 -0
- megastructure_arc-0.0.1/demos/naming-sprint/prompt-namer.md +108 -0
- megastructure_arc-0.0.1/demos/naming-sprint/prompt-scout.md +131 -0
- megastructure_arc-0.0.1/demos/naming-sprint/run.sh +39 -0
- megastructure_arc-0.0.1/docs/PROTOCOL.md +1289 -0
- megastructure_arc-0.0.1/package.json +17 -0
- megastructure_arc-0.0.1/pyproject.toml +34 -0
- megastructure_arc-0.0.1/src/megastructure_arc/__init__.py +7 -0
- megastructure_arc-0.0.1/tests/test_file_relay.py +177 -0
- megastructure_arc-0.0.1/tests/test_smoke_agent.py +137 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"Bash(python -c \"import py_compile; py_compile.compile\\('arc.py', doraise=True\\); print\\('OK'\\)\")",
|
|
5
|
+
"Bash(python3 -c \"import py_compile; py_compile.compile\\('arc.py', doraise=True\\); print\\('OK'\\)\")",
|
|
6
|
+
"Bash(py -3 -c \"import py_compile; py_compile.compile\\('arc.py', doraise=True\\); print\\('OK'\\)\")",
|
|
7
|
+
"Bash(py -3 -m pytest tests/ -x -q)",
|
|
8
|
+
"Bash(py -3 -m unittest discover -s tests -v)",
|
|
9
|
+
"Bash(python -m pytest tests/ -x -q)",
|
|
10
|
+
"Bash(python3 -c \"import arc; print\\('import ok'\\)\")",
|
|
11
|
+
"Bash(py -3 -c \"import arc; print\\('import ok'\\)\")",
|
|
12
|
+
"Bash(py -3 -c ':*)",
|
|
13
|
+
"Bash(python arc.py stop)",
|
|
14
|
+
"Bash(python arc.py ensure)"
|
|
15
|
+
]
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
__pycache__/
|
|
2
|
+
*.py[cod]
|
|
3
|
+
*$py.class
|
|
4
|
+
*.egg-info/
|
|
5
|
+
dist/
|
|
6
|
+
build/
|
|
7
|
+
.eggs/
|
|
8
|
+
*.egg
|
|
9
|
+
*.sqlite3
|
|
10
|
+
*.sqlite3-shm
|
|
11
|
+
*.sqlite3-wal
|
|
12
|
+
*.db
|
|
13
|
+
.venv/
|
|
14
|
+
venv/
|
|
15
|
+
env/
|
|
16
|
+
.env
|
|
17
|
+
.forge.pid
|
|
18
|
+
.fuse_hidden*
|
|
19
|
+
.pytest_cache/
|
|
20
|
+
.mypy_cache/
|
|
21
|
+
.ruff_cache/
|
|
22
|
+
*.swp
|
|
23
|
+
*.swo
|
|
24
|
+
*~
|
|
25
|
+
.DS_Store
|
|
26
|
+
Thumbs.db
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Megastructure Corp
|
|
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.
|
|
@@ -0,0 +1,440 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: megastructure-arc
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: Agent Relay & Coordination — local-first multi-agent coordination hub from Megastructure
|
|
5
|
+
Project-URL: Homepage, https://megastructure.ai/arc
|
|
6
|
+
Project-URL: Repository, https://github.com/megastructurecorp/ARC
|
|
7
|
+
Project-URL: Issues, https://github.com/megastructurecorp/ARC/issues
|
|
8
|
+
Author-email: Rod Humble <rod.humble@gmail.com>
|
|
9
|
+
License: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: agents,coordination,megastructure,multi-agent,relay
|
|
12
|
+
Classifier: Development Status :: 2 - Pre-Alpha
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
|
|
24
|
+
# Arc
|
|
25
|
+
|
|
26
|
+
Local-first agent coordination over HTTP and SQLite, with a file-relay mode for sandboxed agents that cannot reach host localhost or safely use SQLite on the shared mount.
|
|
27
|
+
|
|
28
|
+
This repo ships one canonical implementation: [`arc.py`](./arc.py).
|
|
29
|
+
|
|
30
|
+
## What It Supports
|
|
31
|
+
|
|
32
|
+
`arc.py` provides:
|
|
33
|
+
|
|
34
|
+
- a local HTTP coordination hub with optional network access for cross-machine collaboration
|
|
35
|
+
- SQLite-backed persistence
|
|
36
|
+
- sessions, channels, messages, claims, locks, tasks, inbox, and thread views
|
|
37
|
+
- agent capability discovery and filtering
|
|
38
|
+
- structured task request/result flow with automatic task lifecycle
|
|
39
|
+
- SSE (Server-Sent Events) streaming for real-time message push
|
|
40
|
+
- an MCP server for native AI agent tool integration
|
|
41
|
+
- agent-to-agent RPC (synchronous request/response)
|
|
42
|
+
- one-call `quickstart()` client for fast agent onboarding
|
|
43
|
+
- an HTML dashboard at `GET /`
|
|
44
|
+
- a host-side relay for constrained sandboxes
|
|
45
|
+
- a deterministic smoke runner for validating mixed HTTP and relay agents
|
|
46
|
+
|
|
47
|
+
## Starting & Stopping
|
|
48
|
+
|
|
49
|
+
Start the hub (idempotent — safe to run multiple times):
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
python arc.py ensure
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
The hub runs in the background on `http://127.0.0.1:6969`. Open that URL in a browser to see the live dashboard.
|
|
56
|
+
|
|
57
|
+
The relay for sandboxed agents starts automatically alongside the hub — no extra commands needed.
|
|
58
|
+
|
|
59
|
+
Stop the hub (and relay):
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
python arc.py stop
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Stop the hub and delete all data (sessions, messages, claims, locks, tasks):
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
python arc.py reset
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
All commands accept `--host`, `--port`, `--storage`, and `--spool-dir` flags if you're not using the defaults.
|
|
72
|
+
|
|
73
|
+
## Talking To The Hub Without curl
|
|
74
|
+
|
|
75
|
+
Arc ships a small CLI built on the new `ArcClient` class so you never need to hand-roll HTTP requests:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
python arc.py post --agent me "hello from the cli"
|
|
79
|
+
python arc.py post --agent me --to teammate "private ping"
|
|
80
|
+
python arc.py poll --agent me --timeout 30
|
|
81
|
+
python arc.py whoami --agent me
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
`poll` defaults to `exclude_self=true` (you will not see your own messages echoed back) and uses long-poll. `post --agent me` implicitly registers the session with `replace=true`, which will evict any bot already running under that `agent_id` — use a distinct id when interleaving with a live agent.
|
|
85
|
+
|
|
86
|
+
For programmatic use:
|
|
87
|
+
|
|
88
|
+
```python
|
|
89
|
+
import arc
|
|
90
|
+
client = arc.ArcClient("my-agent")
|
|
91
|
+
client.register(display_name="My Agent")
|
|
92
|
+
client.post("general", "hello")
|
|
93
|
+
for msg in client.poll(timeout=30):
|
|
94
|
+
...
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Sandboxed agents that cannot reach `127.0.0.1` use the same class with a different constructor — everything else is identical:
|
|
98
|
+
|
|
99
|
+
```python
|
|
100
|
+
import arc
|
|
101
|
+
client = arc.ArcClient.over_relay("sandboxed-agent", spool_dir=".arc-relay")
|
|
102
|
+
client.register()
|
|
103
|
+
client.post("general", "hello from the sandbox")
|
|
104
|
+
for msg in client.poll(timeout=30): # still exclude_self by default, still tracks since_id
|
|
105
|
+
...
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
The host must already be running `python arc.py ensure`; the relay thread starts automatically as part of the hub. Hub-level errors (400, 404, 409) round-trip through the relay as `arc.ArcError` with the original error text intact.
|
|
109
|
+
|
|
110
|
+
## Using Arc On Windows
|
|
111
|
+
|
|
112
|
+
On fresh Windows 11 installs, `python` is often aliased to the Microsoft Store shim and will not run the script. Use the official launcher instead:
|
|
113
|
+
|
|
114
|
+
```powershell
|
|
115
|
+
py -3 arc.py ensure
|
|
116
|
+
py -3 arc.py post --agent me "hello"
|
|
117
|
+
py -3 arc.py poll --agent me --timeout 30
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
`curl` on Windows 10/11 is a real PowerShell alias that mangles UTF-8 in `-d` payloads. Two reliable workarounds:
|
|
121
|
+
|
|
122
|
+
1. Use PowerShell's native `Invoke-RestMethod`:
|
|
123
|
+
```powershell
|
|
124
|
+
Invoke-RestMethod -Method Post -Uri http://127.0.0.1:6969/v1/messages `
|
|
125
|
+
-ContentType 'application/json' `
|
|
126
|
+
-Body '{"from_agent":"me","channel":"general","body":"hi"}'
|
|
127
|
+
```
|
|
128
|
+
2. Or write the JSON to a file and use `curl --data-binary`:
|
|
129
|
+
```powershell
|
|
130
|
+
Set-Content -Path msg.json -Value '{"from_agent":"me","channel":"general","body":"hi"}' -Encoding utf8
|
|
131
|
+
curl.exe --data-binary "@msg.json" -H "Content-Type: application/json" http://127.0.0.1:6969/v1/messages
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Better yet, skip curl and use the built-in CLI: `py -3 arc.py post --agent me "hi"` handles quoting and encoding correctly on every shell.
|
|
135
|
+
|
|
136
|
+
## Network Mode
|
|
137
|
+
|
|
138
|
+
Arc can accept connections from other machines on your local network. This lets agents on different computers collaborate through the same hub.
|
|
139
|
+
|
|
140
|
+
Start with remote access enabled:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
python arc.py serve --host 0.0.0.0 --allow-remote
|
|
144
|
+
# or with ensure:
|
|
145
|
+
python arc.py ensure --allow-remote
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Toggle remote access at runtime from the dashboard (`/network on` or `/network off`) or via the API:
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
curl -X POST http://192.168.1.100:6969/v1/network -H "Content-Type: application/json" -d '{"allow_remote": true}'
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Remote agents connect using the hub machine's LAN IP instead of `127.0.0.1`.
|
|
155
|
+
|
|
156
|
+
## Agent Capability Discovery
|
|
157
|
+
|
|
158
|
+
Agents can declare capabilities when registering, and other agents can search for peers by capability:
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
# Register with capabilities
|
|
162
|
+
curl -X POST http://127.0.0.1:6969/v1/sessions -H "Content-Type: application/json" \
|
|
163
|
+
-d '{"agent_id": "reviewer", "capabilities": ["code_review", "testing"]}'
|
|
164
|
+
|
|
165
|
+
# Find agents that can do code review
|
|
166
|
+
curl "http://127.0.0.1:6969/v1/agents?capability=code_review"
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
This enables self-organizing workflows where agents find the right peer for a task without hardcoded IDs.
|
|
170
|
+
|
|
171
|
+
## Structured Task Request/Result
|
|
172
|
+
|
|
173
|
+
Two new message kinds provide a first-class request/response pattern for agent-to-agent work:
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
# Agent A posts a task request (auto-creates a task entry)
|
|
177
|
+
curl -X POST http://127.0.0.1:6969/v1/messages -H "Content-Type: application/json" \
|
|
178
|
+
-d '{"from_agent": "alice", "channel": "general", "kind": "task_request", "body": "Please review auth.py"}'
|
|
179
|
+
# Returns message with id: 42, task auto-created with task_id: 42
|
|
180
|
+
|
|
181
|
+
# Agent B posts the result (auto-completes the linked task)
|
|
182
|
+
curl -X POST http://127.0.0.1:6969/v1/messages -H "Content-Type: application/json" \
|
|
183
|
+
-d '{"from_agent": "bob", "channel": "general", "kind": "task_result", "reply_to": 42, "body": "Looks good, approved"}'
|
|
184
|
+
# Task 42 auto-completes
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Additional recognized message kinds: `status_update`, `code_review` (no special handling, but validated so agents can use them as conventions).
|
|
188
|
+
|
|
189
|
+
## SSE Streaming
|
|
190
|
+
|
|
191
|
+
Real-time push alternative to polling. The hub keeps the connection open and sends new messages as server-sent events:
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
# Stream all messages visible to an agent
|
|
195
|
+
curl -N "http://127.0.0.1:6969/v1/stream?agent_id=myagent"
|
|
196
|
+
|
|
197
|
+
# Stream specific channels, starting from a known point
|
|
198
|
+
curl -N "http://127.0.0.1:6969/v1/stream?agent_id=myagent&channels=general,dev&since_id=100"
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Stays within Arc's zero-dependency philosophy (SSE is plain HTTP). The agent's session is automatically kept alive while streaming. Long-poll remains available as a fallback.
|
|
202
|
+
|
|
203
|
+
## MCP Server
|
|
204
|
+
|
|
205
|
+
Arc can run as an [MCP (Model Context Protocol)](https://modelcontextprotocol.io) server, giving AI agents native tool access without curl or HTTP knowledge:
|
|
206
|
+
|
|
207
|
+
```bash
|
|
208
|
+
python arc.py mcp --agent my-agent --base-url http://127.0.0.1:6969
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
This exposes six tools over stdio (JSON-RPC 2.0):
|
|
212
|
+
|
|
213
|
+
| Tool | Description |
|
|
214
|
+
|------|-------------|
|
|
215
|
+
| `arc_post_message` | Post a message to a channel |
|
|
216
|
+
| `arc_poll_messages` | Poll for new messages |
|
|
217
|
+
| `arc_dm` | Send a direct message |
|
|
218
|
+
| `arc_list_agents` | List live agents |
|
|
219
|
+
| `arc_create_channel` | Create a channel |
|
|
220
|
+
| `arc_rpc_call` | Send a task_request and wait for the result |
|
|
221
|
+
|
|
222
|
+
### Setting Up MCP in Claude Code
|
|
223
|
+
|
|
224
|
+
Create `.mcp.json` in the Arc project directory:
|
|
225
|
+
|
|
226
|
+
```json
|
|
227
|
+
{
|
|
228
|
+
"mcpServers": {
|
|
229
|
+
"arc": {
|
|
230
|
+
"command": "python",
|
|
231
|
+
"args": ["arc.py", "mcp", "--agent", "my-agent", "--base-url", "http://127.0.0.1:6969"],
|
|
232
|
+
"cwd": "/path/to/arc"
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
Restart your Claude Code session in the Arc directory. The `arc_*` tools will be available natively.
|
|
239
|
+
|
|
240
|
+
For remote agents, change `--base-url` to the hub machine's LAN address (e.g. `http://192.168.1.100:6969`).
|
|
241
|
+
|
|
242
|
+
## Quickstart (Programmatic)
|
|
243
|
+
|
|
244
|
+
One-call client setup for agents that want to get connected fast:
|
|
245
|
+
|
|
246
|
+
```python
|
|
247
|
+
import arc
|
|
248
|
+
client = arc.ArcClient.quickstart("my-agent", "http://192.168.1.100:6969",
|
|
249
|
+
capabilities=["coding", "review"])
|
|
250
|
+
client.post("general", "ready to work")
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
This creates the client, registers the session (with `replace=True`), and returns a ready-to-use instance.
|
|
254
|
+
|
|
255
|
+
## Agent-to-Agent RPC
|
|
256
|
+
|
|
257
|
+
Synchronous request/response between agents using the task_request/task_result lifecycle:
|
|
258
|
+
|
|
259
|
+
```python
|
|
260
|
+
import arc
|
|
261
|
+
client = arc.ArcClient.quickstart("alice")
|
|
262
|
+
|
|
263
|
+
# Blocks until bob posts a task_result, or times out
|
|
264
|
+
result = client.call("bob", "Please review auth.py", timeout=30)
|
|
265
|
+
print(result["body"]) # bob's response
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
Under the hood this posts a `task_request` directed at the target agent and polls for a matching `task_result`.
|
|
269
|
+
|
|
270
|
+
## Choose The Right Mode
|
|
271
|
+
|
|
272
|
+
### Mode 1: Single Hub
|
|
273
|
+
|
|
274
|
+
Use this when all agents can reach the same local HTTP server.
|
|
275
|
+
|
|
276
|
+
Start the hub:
|
|
277
|
+
|
|
278
|
+
```bash
|
|
279
|
+
python arc.py ensure
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
Default URL:
|
|
283
|
+
|
|
284
|
+
```text
|
|
285
|
+
http://127.0.0.1:6969
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
### Mode 2: Shared-Filesystem Multi-Hub
|
|
289
|
+
|
|
290
|
+
Use this when agents cannot reach each other's localhost, but each environment can:
|
|
291
|
+
|
|
292
|
+
- run its own local process
|
|
293
|
+
- use the same SQLite file
|
|
294
|
+
- rely on the shared filesystem to support SQLite WAL and locking correctly
|
|
295
|
+
|
|
296
|
+
Example:
|
|
297
|
+
|
|
298
|
+
```bash
|
|
299
|
+
# Sandbox A
|
|
300
|
+
python arc.py --port 6969 --storage /shared/arc.sqlite3
|
|
301
|
+
|
|
302
|
+
# Sandbox B
|
|
303
|
+
python arc.py --port 9876 --storage /shared/arc.sqlite3
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
Each sandbox talks only to its own local hub. All hubs share the same coordination state through the same SQLite file.
|
|
307
|
+
|
|
308
|
+
### Mode 3: Sandbox Relay
|
|
309
|
+
|
|
310
|
+
Use this when the sandbox can write ordinary files into the shared workspace, but cannot:
|
|
311
|
+
|
|
312
|
+
- reach the host machine's `127.0.0.1`
|
|
313
|
+
- safely use SQLite directly on the shared mount
|
|
314
|
+
|
|
315
|
+
In this mode:
|
|
316
|
+
|
|
317
|
+
1. the host runs Arc (the relay starts automatically as a background thread)
|
|
318
|
+
2. the sandbox writes request files into the relay spool directory
|
|
319
|
+
3. the relay forwards those requests to the HTTP hub
|
|
320
|
+
4. the relay writes response files back for the sandbox to read
|
|
321
|
+
|
|
322
|
+
Start the host side:
|
|
323
|
+
|
|
324
|
+
```bash
|
|
325
|
+
python arc.py ensure
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
The relay is built in and starts automatically. To use a custom spool directory:
|
|
329
|
+
|
|
330
|
+
```bash
|
|
331
|
+
python arc.py ensure --spool-dir .arc-relay
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
The relay is intentionally append-only:
|
|
335
|
+
|
|
336
|
+
- requests land under `requests/<agent>/`
|
|
337
|
+
- responses land under `responses/<agent>/`
|
|
338
|
+
- processed requests are renamed to `.work`
|
|
339
|
+
|
|
340
|
+
## Agent Instructions
|
|
341
|
+
|
|
342
|
+
### Instructions For Normal Agents
|
|
343
|
+
|
|
344
|
+
Use this when the agent can call the local hub directly:
|
|
345
|
+
|
|
346
|
+
> Arc is available in `arc.py`.
|
|
347
|
+
> First ensure the hub is running with `python arc.py ensure`.
|
|
348
|
+
> Then use `http://127.0.0.1:6969`.
|
|
349
|
+
> Register your session, poll for messages, claim work, post artifacts, and release claims when done.
|
|
350
|
+
|
|
351
|
+
### Instructions For Isolated Agents Sharing SQLite
|
|
352
|
+
|
|
353
|
+
Use this when each sandbox can safely run its own local hub against the same shared database:
|
|
354
|
+
|
|
355
|
+
> Arc is available in `arc.py`.
|
|
356
|
+
> Start your own local hub pointing at the shared database file:
|
|
357
|
+
> `python arc.py --port <your_port> --storage /shared/arc.sqlite3`
|
|
358
|
+
> Then talk only to your own local hub URL inside that sandbox.
|
|
359
|
+
> Do not try to call another sandbox's localhost.
|
|
360
|
+
|
|
361
|
+
### Instructions For Constrained Sandboxed Agents
|
|
362
|
+
|
|
363
|
+
Use this when the agent's sandbox cannot reach the host machine's `localhost` or use SQLite on the shared mount.
|
|
364
|
+
|
|
365
|
+
**WARNING: DO NOT start your own hub process!**
|
|
366
|
+
If an agent runs `python arc.py ensure` inside an isolated sandbox, it will succeed, but they will be talking to an isolated hub and no other agents will see their messages. The host is ALREADY running the real hub.
|
|
367
|
+
|
|
368
|
+
Provide the agent with this exact prompt:
|
|
369
|
+
|
|
370
|
+
> You are operating in a constrained sandbox. You cannot communicate via HTTP or direct SQLite, and you MUST NOT start your own Arc server process. Doing so will isolate you.
|
|
371
|
+
> Instead, interact with the hub exclusively using the file-based relay transport via the `FileRelayClient` class in `arc.py`.
|
|
372
|
+
> The shared relay spool directory is located at `.arc-relay`.
|
|
373
|
+
>
|
|
374
|
+
> Example Python usage:
|
|
375
|
+
> ```python
|
|
376
|
+
> import arc
|
|
377
|
+
> client = arc.FileRelayClient(agent_id="my-agent-name", spool_dir=".arc-relay")
|
|
378
|
+
> client.call("POST", "/v1/sessions", {"agent_id": "my-agent-name", "replace": True})
|
|
379
|
+
> client.call("POST", "/v1/messages", {"channel": "general", "kind": "chat", "body": "hello"})
|
|
380
|
+
> ```
|
|
381
|
+
|
|
382
|
+
### Instructions You Should Not Give To Constrained Sandboxes
|
|
383
|
+
|
|
384
|
+
Do **not** tell a constrained sandboxed agent to:
|
|
385
|
+
|
|
386
|
+
- run `python arc.py ensure` (it will create a silent, isolated "party of one")
|
|
387
|
+
- bootstrap by calling host localhost unless you know it can
|
|
388
|
+
- depend on direct SQLite access unless you know the mount supports it
|
|
389
|
+
- follow the normal single-hub bootstrap blindly
|
|
390
|
+
|
|
391
|
+
For that environment, the right transport is relay mode.
|
|
392
|
+
|
|
393
|
+
## Smoke Validation
|
|
394
|
+
|
|
395
|
+
Arc includes a deterministic smoke runner inside the same file.
|
|
396
|
+
|
|
397
|
+
Example mixed validation:
|
|
398
|
+
|
|
399
|
+
```bash
|
|
400
|
+
python arc.py ensure
|
|
401
|
+
|
|
402
|
+
python arc.py smoke-agent --role smoke-a --transport http
|
|
403
|
+
python arc.py smoke-agent --role smoke-b --transport relay --relay-dir .arc-relay
|
|
404
|
+
python arc.py smoke-agent --role smoke-c --transport http
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
This validates that:
|
|
408
|
+
|
|
409
|
+
- direct HTTP agents can see relay-originated work
|
|
410
|
+
- relay agents can claim and post artifacts
|
|
411
|
+
- the constrained sandbox path does not require direct localhost access
|
|
412
|
+
|
|
413
|
+
## Common Commands
|
|
414
|
+
|
|
415
|
+
```bash
|
|
416
|
+
python arc.py ensure # start hub (idempotent)
|
|
417
|
+
python arc.py stop # stop the running hub
|
|
418
|
+
python arc.py reset # stop hub + delete database
|
|
419
|
+
python arc.py --port 6969 # run hub + relay in foreground
|
|
420
|
+
python arc.py smoke-agent --role smoke-b --transport relay --relay-dir .arc-relay
|
|
421
|
+
curl http://127.0.0.1:6969/v1/hub-info
|
|
422
|
+
curl http://127.0.0.1:6969/v1/threads
|
|
423
|
+
curl "http://127.0.0.1:6969/v1/messages?thread_id=demo-thread"
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
## Protocol Reference
|
|
427
|
+
|
|
428
|
+
The wire contract is documented in [`docs/PROTOCOL.md`](./docs/PROTOCOL.md).
|
|
429
|
+
|
|
430
|
+
## Tests
|
|
431
|
+
|
|
432
|
+
```bash
|
|
433
|
+
python -m unittest discover -s tests -v
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
The restored test coverage includes relay transport and mixed HTTP/relay smoke scenarios.
|
|
437
|
+
|
|
438
|
+
## License
|
|
439
|
+
|
|
440
|
+
MIT
|