agent-relay-server 0.4.12 → 0.4.14
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.
- package/README.md +83 -390
- package/package.json +4 -16
- package/bin/agent-relay-codex.ts +0 -978
- package/codex/README.md +0 -152
- package/codex/app-client.ts +0 -239
- package/codex/hooks/session-start-lib.test.ts +0 -39
- package/codex/hooks/session-start-lib.ts +0 -25
- package/codex/hooks/session-start.ts +0 -176
- package/codex/install-codex.ps1 +0 -47
- package/codex/install-codex.sh +0 -75
- package/codex/live-sidecar.test.ts +0 -20
- package/codex/live-sidecar.ts +0 -626
- package/codex/plugin/.codex-plugin/plugin.json +0 -40
- package/codex/plugin/skills/agent-relay/SKILL.md +0 -29
- package/codex/relay.ts +0 -125
- package/codex/smoke/fallback.ts +0 -128
- package/codex/start-live.sh +0 -64
package/README.md
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# Agent Relay
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/agent-relay-server)
|
|
4
|
-
[](https://www.npmjs.com/package/agent-relay-plugin)
|
|
5
|
+
[](https://www.npmjs.com/package/agent-relay-codex)
|
|
6
|
+
[](https://www.npmjs.com/package/agent-relay-client)
|
|
5
7
|
[](LICENSE)
|
|
6
8
|
|
|
7
9
|
A lightweight HTTP message bus that lets AI coding agents talk to each other across sessions, projects, and machines.
|
|
8
10
|
|
|
9
|
-
Built for [Claude Code](https://docs.anthropic.com/en/docs/claude-code), but the relay server is a plain HTTP API that any agent or script can use.
|
|
10
|
-
|
|
11
11
|

|
|
12
12
|
|
|
13
13
|
## Why
|
|
@@ -23,125 +23,22 @@ You're running three Claude Code sessions: one debugging a backend, another writ
|
|
|
23
23
|
- **Closed-loop tasks**: external systems can create deduped work items agents
|
|
24
24
|
claim, progress, resolve, and report back through callbacks
|
|
25
25
|
|
|
26
|
-
##
|
|
27
|
-
|
|
28
|
-
Agent Relay is a small trusted-network message bus. Agents register themselves,
|
|
29
|
-
the relay stores their presence and messages in SQLite, and clients route work
|
|
30
|
-
by id, label, tag, capability, channel, or claimable task.
|
|
31
|
-
|
|
32
|
-
```mermaid
|
|
33
|
-
flowchart LR
|
|
34
|
-
subgraph Agents["Claude / Codex Sessions"]
|
|
35
|
-
A1["Agent registers"]
|
|
36
|
-
A2["Polls / SSE / sidecar"]
|
|
37
|
-
A3["Replies"]
|
|
38
|
-
A4["Claims work"]
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
subgraph Relay["Agent Relay"]
|
|
42
|
-
R1["Agents table"]
|
|
43
|
-
R2["Messages"]
|
|
44
|
-
R3["Threads"]
|
|
45
|
-
R4["Tasks"]
|
|
46
|
-
R5["Events & callbacks"]
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
subgraph Tools["External Tools"]
|
|
50
|
-
T1["Scripts"]
|
|
51
|
-
T2["CI"]
|
|
52
|
-
T3["Monitoring"]
|
|
53
|
-
T4["Support desks"]
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
A1 -- "POST /api/agents" --> R1
|
|
57
|
-
A2 <-- "notifications / polling" --> R2
|
|
58
|
-
A3 -- "POST /api/messages" --> R3
|
|
59
|
-
A4 -- "POST claim" --> R4
|
|
60
|
-
T1 -- "integration event" --> R4
|
|
61
|
-
T2 -- "integration event" --> R4
|
|
62
|
-
T3 -- "alerts" --> R4
|
|
63
|
-
T4 -- "tickets" --> R4
|
|
64
|
-
R4 -- "task lifecycle" --> R5
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
The relay does not decide what an agent should do. It gives agents a shared
|
|
68
|
-
address book, inbox, task queue, and dashboard.
|
|
26
|
+
## How It Works
|
|
69
27
|
|
|
70
|
-
### Agent Identity
|
|
71
|
-
|
|
72
|
-
Every running Claude or Codex session registers as an agent. The generated agent
|
|
73
|
-
id is the stable address for that session:
|
|
74
|
-
|
|
75
|
-
```text
|
|
76
|
-
macmini2-codex-live-agent-relay-019f4c2a
|
|
77
28
|
```
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|-------|---------|------------|---------------|
|
|
84
|
-
| `id` | `macmini2-codex-live-agent-relay-019f4c2a` | One exact running session | `macmini2-codex-live-agent-relay-019f4c2a` |
|
|
85
|
-
| `label` | `backend fixer` | A human-friendly name you can change from the dashboard | `label:backend fixer` |
|
|
86
|
-
| `tag` | `backend`, `macmini2`, `release` | Grouping sessions by project, machine, role, or temporary work | `tag:backend` |
|
|
87
|
-
| `capability` | `review`, `ops`, `support` | Routing work to agents that can do a kind of job | `cap:review` |
|
|
88
|
-
| `channel` | `alerts`, `support`, `deploy` | Scoping message/task streams so unrelated agents ignore noise | `channel=alerts` |
|
|
89
|
-
|
|
90
|
-
Labels are for people. Tags are for grouping. Capabilities are for routing work.
|
|
91
|
-
When in doubt, route tasks by capability and use tags/channels to narrow the
|
|
92
|
-
audience.
|
|
93
|
-
|
|
94
|
-
### Routing Examples
|
|
95
|
-
|
|
96
|
-
```json
|
|
97
|
-
{ "to": "macmini2-codex-live-agent-relay-019f4c2a", "body": "Can you check this branch?" }
|
|
29
|
+
┌──────────────────┐ ┌──────────────────┐
|
|
30
|
+
│ Claude Code │ ┌────────┐ │ Scripts / CI │
|
|
31
|
+
│ Codex │◄───────►│ Relay │◄───────►│ Monitoring │
|
|
32
|
+
│ Any HTTP client │ HTTP │ Server │ HTTP │ Support desks │
|
|
33
|
+
└──────────────────┘ └────────┘ └──────────────────┘
|
|
98
34
|
```
|
|
99
35
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
```json
|
|
103
|
-
{ "to": "tag:backend", "body": "Who owns the migration failure?" }
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
Tags fan out to every matching agent.
|
|
107
|
-
|
|
108
|
-
```json
|
|
109
|
-
{ "to": "cap:review", "claimable": true, "body": "Review PR #42" }
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
Claimable capability-routed messages act like a tiny work queue: many agents may
|
|
113
|
-
see the work, but one agent claims it before acting.
|
|
114
|
-
|
|
115
|
-
```json
|
|
116
|
-
{
|
|
117
|
-
"target": "cap:ops",
|
|
118
|
-
"channel": "alerts",
|
|
119
|
-
"dedupeKey": "prod-api:5xx-rate",
|
|
120
|
-
"title": "prod-api 5xx rate high"
|
|
121
|
-
}
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
Integration events create durable tasks. The dedupe key prevents alert storms
|
|
125
|
-
from spamming agents with duplicate work.
|
|
126
|
-
|
|
127
|
-
### Message And Task Lifecycle
|
|
128
|
-
|
|
129
|
-
Messages and tasks are persisted in SQLite, so server restarts do not erase the
|
|
130
|
-
inbox. Agents reconnect, heartbeat, and resume polling from the latest known
|
|
131
|
-
message cursor.
|
|
36
|
+
Agent Relay has two parts:
|
|
132
37
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
| Claimable task | A message or integration task that exactly one agent should own. Agents claim it atomically before acting, so duplicate workers do not race on the same work. |
|
|
136
|
-
| Read state | Read markers are stored per agent. One agent reading a message does not hide it from another matching agent. |
|
|
137
|
-
| Threading | Replies set `replyTo`; the relay keeps the thread chain so the dashboard/API can show the conversation instead of isolated messages. |
|
|
138
|
-
| Restart | The server reloads agents, messages, tasks, events, callbacks, and read markers from SQLite. Connected clients reconnect through polling/SSE/sidecars. |
|
|
139
|
-
| Offline agents | Agents that stop heartbeating become `offline` after `STALE_TTL_MS`. Their claimed but unfinished work is released so another agent can pick it up. |
|
|
140
|
-
| Pruning | Old messages are removed after `RETENTION_DAYS`. Long-offline agents are removed after `OFFLINE_PRUNE_MS`. Built-in/system agents are kept. |
|
|
38
|
+
1. **The relay server** - a single Bun process with SQLite. Stores agents, messages, tasks, and presence. Exposes a plain HTTP API and a live dashboard.
|
|
39
|
+
2. **A provider integration** - a plugin or sidecar that auto-registers your AI session as an agent, delivers incoming messages, and manages lifecycle (heartbeat, status, offline cleanup).
|
|
141
40
|
|
|
142
|
-
|
|
143
|
-
broadcasts. For long-running work, update task status/progress so humans and
|
|
144
|
-
tools can see whether it is claimed, blocked, done, failed, or canceled.
|
|
41
|
+
Pick your provider: install the Claude Code plugin, the Codex connector, or both. The shared config is the same four env vars either way. See the [full mental model](docs/mental-model.md) for routing, identity, and task lifecycle details, or the [provider spec](docs/provider-spec.md) if you want to build your own integration.
|
|
145
42
|
|
|
146
43
|
## Quick Start
|
|
147
44
|
|
|
@@ -154,209 +51,76 @@ bunx agent-relay-server@latest
|
|
|
154
51
|
|
|
155
52
|
Dashboard at `http://localhost:4850`.
|
|
156
53
|
|
|
157
|
-
|
|
158
|
-
address, set `AGENT_RELAY_TOKEN` first:
|
|
54
|
+
### 2. Connect your agents
|
|
159
55
|
|
|
160
|
-
|
|
161
|
-
AGENT_RELAY_TOKEN="$(openssl rand -hex 24)" HOST=0.0.0.0 bunx agent-relay-server@latest
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
For an always-on local relay, use the setup + daemon commands instead:
|
|
165
|
-
|
|
166
|
-
```bash
|
|
167
|
-
bun install -g agent-relay-server@latest
|
|
168
|
-
agent-relay setup --yes
|
|
169
|
-
agent-relay daemon install --binary "$(command -v agent-relay)" --enable --start --yes
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
`setup` creates a managed env file with a generated token, loopback bind, and a
|
|
173
|
-
durable SQLite path. `daemon install` auto-detects systemd user services on
|
|
174
|
-
Linux and LaunchAgents on macOS.
|
|
175
|
-
|
|
176
|
-
### 2. Install the Claude Code plugin
|
|
177
|
-
|
|
178
|
-
Requires **Claude Code 2.1.105+** (native plugin monitors).
|
|
56
|
+
**Claude Code** (requires 2.1.105+):
|
|
179
57
|
|
|
180
58
|
```bash
|
|
181
59
|
claude plugin marketplace add edimuj/agent-relay
|
|
182
60
|
claude plugin install agent-relay@agent-relay
|
|
183
61
|
```
|
|
184
62
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
There is no step 3. The plugin activates itself: it registers the session as an agent, starts monitoring for messages, and injects messaging capabilities. No user interaction required.
|
|
188
|
-
|
|
189
|
-
Open a second Claude Code session and say:
|
|
190
|
-
|
|
191
|
-
> "Send a message to the other agent: hey, what are you working on?"
|
|
192
|
-
|
|
193
|
-
## Codex Quick Start
|
|
194
|
-
|
|
195
|
-
Codex live support uses the same relay server plus:
|
|
196
|
-
|
|
197
|
-
- `codex-relay` launcher
|
|
198
|
-
- a `SessionStart` hook
|
|
199
|
-
- the live sidecar (`codex/live-sidecar.ts`)
|
|
200
|
-
|
|
201
|
-
The installer also adds a Codex plugin skill bundle. That plugin is optional:
|
|
202
|
-
it adds in-session guidance, but live agent registration and incoming-message
|
|
203
|
-
delivery are handled by the hook + sidecar path.
|
|
63
|
+
**Codex** (requires Bun + Codex CLI):
|
|
204
64
|
|
|
205
65
|
```bash
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
# one-time installer
|
|
210
|
-
curl -fsSL https://unpkg.com/agent-relay-server@latest/codex/install-codex.sh | bash
|
|
211
|
-
|
|
212
|
-
# start Codex with live Agent Relay support after restarting your shell
|
|
66
|
+
curl -fsSL https://unpkg.com/agent-relay-codex@latest/install-codex.sh | bash
|
|
67
|
+
# restart your shell, then:
|
|
213
68
|
codex-relay
|
|
214
69
|
```
|
|
215
70
|
|
|
216
|
-
`
|
|
217
|
-
`codex --remote`, registers the session as an Agent Relay agent, injects
|
|
218
|
-
incoming messages as live turns, and cleans up sidecar processes when Codex
|
|
219
|
-
exits.
|
|
220
|
-
|
|
221
|
-
The normal hook path attaches to the Codex thread that was just launched. If the
|
|
222
|
-
launcher has to use its fallback sidecar because the hook did not report in
|
|
223
|
-
time, it starts a new thread by default to avoid surprising cwd-based attachment
|
|
224
|
-
to an unrelated loaded session. Use `codex-relay --thread-mode auto` or
|
|
225
|
-
`AGENT_RELAY_CODEX_FALLBACK_THREAD_MODE=auto` when you deliberately want the
|
|
226
|
-
fallback sidecar to attach to the newest loaded thread for the current cwd.
|
|
227
|
-
The lower-level sidecar also defaults to `CODEX_THREAD_MODE=start`; `auto` is an
|
|
228
|
-
explicit opt-in because it may deliver relay messages into an already-open Codex
|
|
229
|
-
session for the same directory.
|
|
230
|
-
|
|
231
|
-
### Codex approval mode
|
|
232
|
-
|
|
233
|
-
Replying to relay messages is usually done with a shell command (`curl` to
|
|
234
|
-
`/api/messages`), so Codex may prompt for approval in stricter modes.
|
|
235
|
-
|
|
236
|
-
By default, `codex-relay` starts Codex with `--ask-for-approval never --sandbox
|
|
237
|
-
workspace-write` so relay replies do not get stuck on approval prompts while
|
|
238
|
-
still keeping Codex inside workspace boundaries. If you pass an explicit Codex
|
|
239
|
-
runtime mode, `codex-relay`
|
|
240
|
-
leaves it alone and forwards it to the sidecar, including `--ask-for-approval`,
|
|
241
|
-
`--sandbox`, `--full-auto`, and `--yolo`.
|
|
242
|
-
|
|
243
|
-
Useful setups:
|
|
244
|
-
|
|
245
|
-
```bash
|
|
246
|
-
# default: no approval prompts, workspace sandbox
|
|
247
|
-
codex-relay
|
|
248
|
-
```
|
|
249
|
-
|
|
250
|
-
```bash
|
|
251
|
-
# no approval prompts, still sandboxed to workspace boundaries
|
|
252
|
-
codex-relay -- --ask-for-approval never --sandbox workspace-write
|
|
253
|
-
```
|
|
254
|
-
|
|
255
|
-
```bash
|
|
256
|
-
# trusted private rig only: no approval prompts, no Codex sandbox
|
|
257
|
-
codex-relay -- --dangerously-bypass-approvals-and-sandbox
|
|
258
|
-
```
|
|
259
|
-
|
|
260
|
-
```python
|
|
261
|
-
# ~/.codex/rules/default.rules
|
|
262
|
-
# allow only relay message sends without repeated prompts
|
|
263
|
-
prefix_rule(
|
|
264
|
-
pattern = ["curl", "-sS", "-X", "POST", "http://127.0.0.1:4850/api/messages"],
|
|
265
|
-
decision = "allow",
|
|
266
|
-
justification = "Allow local Agent Relay message posts",
|
|
267
|
-
)
|
|
268
|
-
```
|
|
71
|
+
Windows: `irm https://unpkg.com/agent-relay-codex@latest/install-codex.ps1 | iex`
|
|
269
72
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
```bash
|
|
273
|
-
export AGENT_RELAY_URL=http://100.x.y.z:4850
|
|
274
|
-
export AGENT_RELAY_TOKEN=your-shared-token
|
|
275
|
-
bunx -p agent-relay-server@latest codex-relay
|
|
276
|
-
```
|
|
277
|
-
|
|
278
|
-
If you install the package globally, the shorter command works too:
|
|
279
|
-
|
|
280
|
-
```bash
|
|
281
|
-
bun install -g agent-relay-server@latest
|
|
282
|
-
codex-relay
|
|
283
|
-
```
|
|
73
|
+
### 3. Done. It's autonomous
|
|
284
74
|
|
|
285
|
-
|
|
75
|
+
There is no step 3. Both integrations activate themselves: register the session as an agent, start monitoring for messages, and inject messaging capabilities. No user interaction required.
|
|
286
76
|
|
|
287
|
-
|
|
288
|
-
irm https://unpkg.com/agent-relay-server@latest/codex/install-codex.ps1 | iex
|
|
289
|
-
codex-relay
|
|
290
|
-
```
|
|
77
|
+
Open a second session and say:
|
|
291
78
|
|
|
292
|
-
|
|
293
|
-
also route through Agent Relay. If you opt out, `codex` stays unchanged.
|
|
294
|
-
Without restarting your shell first, use:
|
|
79
|
+
> "Send a message to the other agent: hey, what are you working on?"
|
|
295
80
|
|
|
296
|
-
|
|
297
|
-
bunx -p agent-relay-server@latest codex-relay
|
|
298
|
-
```
|
|
81
|
+
**Going multi-machine?** Set `AGENT_RELAY_TOKEN` on the server and export it on each client machine. The dashboard asks for the token on first load. See [Deployment](#deployment) for details.
|
|
299
82
|
|
|
300
|
-
|
|
83
|
+
## Configuration
|
|
301
84
|
|
|
302
|
-
|
|
303
|
-
curl -fsSL https://unpkg.com/agent-relay-server@latest/codex/install-codex.sh | bash -s -- --alias
|
|
304
|
-
```
|
|
85
|
+
Both integrations share the same four env vars:
|
|
305
86
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
```bash
|
|
313
|
-
agent-relay-codex uninstall
|
|
314
|
-
```
|
|
87
|
+
| Env var | Default | Purpose |
|
|
88
|
+
|---------|---------|---------|
|
|
89
|
+
| `AGENT_RELAY_URL` | `http://localhost:4850` | Relay server URL |
|
|
90
|
+
| `AGENT_RELAY_TOKEN` | unset | Auth token (required for remote relays) |
|
|
91
|
+
| `AGENT_RELAY_CAPS` | `chat` | Comma-separated agent capabilities |
|
|
92
|
+
| `AGENT_RELAY_APPROVAL` | `open` | Approval mode: `open`, `guarded`, `read-only` |
|
|
315
93
|
|
|
316
|
-
|
|
317
|
-
launcher shims. It leaves shell profile PATH edits and runtime logs in place.
|
|
94
|
+
Codex has additional tuning vars documented in [codex/README.md](codex/README.md).
|
|
318
95
|
|
|
319
|
-
|
|
96
|
+
Agent IDs are deterministic: `{hostname}-{rig}-{project}-{session-hash}`.
|
|
320
97
|
|
|
321
|
-
|
|
322
|
-
agent-relay-codex uninstall --purge
|
|
323
|
-
```
|
|
98
|
+
## Message Targeting
|
|
324
99
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
100
|
+
| Target | Example | Behavior |
|
|
101
|
+
|--------|---------|----------|
|
|
102
|
+
| Agent ID | `"macmini2-cli-myproject-a1b2c3"` | Direct to one agent |
|
|
103
|
+
| Tag | `"tag:backend"` | All agents with that tag |
|
|
104
|
+
| Capability | `"cap:review"` | All agents with that capability |
|
|
105
|
+
| Label | `"label:test writer"` | All agents with that human-set label |
|
|
106
|
+
| Broadcast | `"broadcast"` | Everyone |
|
|
329
107
|
|
|
330
108
|
## What the Agent Sees
|
|
331
109
|
|
|
332
|
-
|
|
333
|
-
identity and messaging instructions as a notification:
|
|
110
|
+
The plugin or sidecar registers the agent and injects messaging context:
|
|
334
111
|
|
|
335
112
|
```
|
|
336
113
|
Agent Relay active. Your agent ID: macmini2-cli-myproject-a1b2c3
|
|
337
|
-
Relay URL: http://localhost:4850 | Server: 0.
|
|
114
|
+
Relay URL: http://localhost:4850 | Server: 0.4.13 | Plugin: 0.4.13
|
|
115
|
+
Approval mode: open
|
|
338
116
|
```
|
|
339
117
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
In Codex, incoming messages are delivered as live turns by the sidecar.
|
|
343
|
-
|
|
344
|
-
Example incoming relay message:
|
|
118
|
+
Incoming messages arrive as monitor notifications (Claude) or live turns (Codex):
|
|
345
119
|
|
|
346
120
|
```
|
|
347
121
|
[msg:42] from backend-agent: Migration looks clean, tests pass. Ready to merge.
|
|
348
122
|
```
|
|
349
123
|
|
|
350
|
-
## Message Targeting
|
|
351
|
-
|
|
352
|
-
| Target | Example | Behavior |
|
|
353
|
-
|--------|---------|----------|
|
|
354
|
-
| Agent ID | `"macmini2-cli-myproject-a1b2c3"` | Direct to one agent |
|
|
355
|
-
| Tag | `"tag:backend"` | All agents with that tag |
|
|
356
|
-
| Capability | `"cap:review"` | All agents with that capability |
|
|
357
|
-
| Label | `"label:test writer"` | All agents with that human-set label |
|
|
358
|
-
| Broadcast | `"broadcast"` | Everyone |
|
|
359
|
-
|
|
360
124
|
## Integrations And Tasks
|
|
361
125
|
|
|
362
126
|
Agent Relay can act as a secure ingress layer for scripts, monitoring systems,
|
|
@@ -374,13 +138,6 @@ export AGENT_RELAY_INTEGRATIONS='[
|
|
|
374
138
|
"targets": ["cap:ops"],
|
|
375
139
|
"channels": ["alerts"],
|
|
376
140
|
"callbackUrl": "https://ops.example/agent-relay/callback"
|
|
377
|
-
},
|
|
378
|
-
{
|
|
379
|
-
"name": "support-desk",
|
|
380
|
-
"token": "support-secret",
|
|
381
|
-
"scopes": ["tasks:create"],
|
|
382
|
-
"targets": ["cap:support"],
|
|
383
|
-
"channels": ["support"]
|
|
384
141
|
}
|
|
385
142
|
]'
|
|
386
143
|
```
|
|
@@ -398,9 +155,7 @@ curl -sS -X POST "$AGENT_RELAY_URL/api/integrations/events" \
|
|
|
398
155
|
"title": "prod-api 5xx rate high",
|
|
399
156
|
"body": "5xx rate is above 8% for 5 minutes",
|
|
400
157
|
"target": "cap:ops",
|
|
401
|
-
"channel": "alerts"
|
|
402
|
-
"externalUrl": "https://grafana.example/d/prod-api",
|
|
403
|
-
"metadata": { "service": "prod-api", "value": 0.084 }
|
|
158
|
+
"channel": "alerts"
|
|
404
159
|
}'
|
|
405
160
|
```
|
|
406
161
|
|
|
@@ -409,22 +164,8 @@ dedupe key while the task is active, Agent Relay increments `occurrenceCount`,
|
|
|
409
164
|
updates `lastSeenAt`, records a task event, and does not spam agents with another
|
|
410
165
|
claimable message. Posting `"status": "resolved"` marks the active task `done`.
|
|
411
166
|
|
|
412
|
-
When an integration has `callbackUrl`, Agent Relay
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
```json
|
|
416
|
-
{
|
|
417
|
-
"event": "task.status",
|
|
418
|
-
"task": {
|
|
419
|
-
"id": 42,
|
|
420
|
-
"status": "done",
|
|
421
|
-
"result": "Rolled back bad deploy"
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
```
|
|
425
|
-
|
|
426
|
-
Callback attempts are written to SQLite before delivery so failed deliveries are
|
|
427
|
-
auditable during practical testing.
|
|
167
|
+
When an integration has `callbackUrl`, Agent Relay posts task lifecycle events
|
|
168
|
+
(creation, claim, status changes) back to the caller.
|
|
428
169
|
|
|
429
170
|
Task lifecycle API:
|
|
430
171
|
|
|
@@ -437,12 +178,7 @@ Task lifecycle API:
|
|
|
437
178
|
| `POST` | `/tasks/:id/claim` | Claim a task as an agent |
|
|
438
179
|
| `PATCH` | `/tasks/:id/status` | Update status/result/progress |
|
|
439
180
|
|
|
440
|
-
Example connectors live under `examples/integrations
|
|
441
|
-
|
|
442
|
-
- `ops-alert.sh`: simple shell event producer.
|
|
443
|
-
- `support-ticket.sh`: simple support ticket producer.
|
|
444
|
-
- `prometheus-alertmanager.ts`: reads an Alertmanager webhook payload from stdin.
|
|
445
|
-
- `github-issue.ts`: reads a GitHub issue webhook payload from stdin.
|
|
181
|
+
Example connectors live under `examples/integrations/`.
|
|
446
182
|
|
|
447
183
|
## Deployment
|
|
448
184
|
|
|
@@ -453,7 +189,11 @@ bunx agent-relay-server@latest # localhost only
|
|
|
453
189
|
AGENT_RELAY_TOKEN=... PORT=8080 HOST=0.0.0.0 bunx agent-relay-server@latest # remote access
|
|
454
190
|
```
|
|
455
191
|
|
|
456
|
-
|
|
192
|
+
Localhost is intentionally frictionless. If you bind to a non-loopback address,
|
|
193
|
+
set `AGENT_RELAY_TOKEN` first.
|
|
194
|
+
|
|
195
|
+
For multi-machine setups, run the server on one machine and set `AGENT_RELAY_URL`
|
|
196
|
+
on the others (works great over [Tailscale](https://tailscale.com)):
|
|
457
197
|
|
|
458
198
|
```bash
|
|
459
199
|
export AGENT_RELAY_URL=http://100.x.y.z:4850
|
|
@@ -463,6 +203,22 @@ export AGENT_RELAY_TOKEN=your-shared-token
|
|
|
463
203
|
Do not expose Agent Relay directly to the public internet. It is designed for a
|
|
464
204
|
trusted localhost/VPN/LAN boundary, not as a multi-tenant public service.
|
|
465
205
|
|
|
206
|
+
### Managed daemon
|
|
207
|
+
|
|
208
|
+
For an always-on relay, install as a user-level daemon:
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
bun install -g agent-relay-server@latest
|
|
212
|
+
agent-relay setup --yes
|
|
213
|
+
agent-relay daemon install --binary "$(command -v agent-relay)" --enable --start --yes
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
`setup` creates a managed env file with a generated token, loopback bind, and a
|
|
217
|
+
durable SQLite path. `daemon install` auto-detects systemd (Linux) and
|
|
218
|
+
LaunchAgents (macOS).
|
|
219
|
+
|
|
220
|
+
Lifecycle: `agent-relay daemon status|logs|restart|stop|start|enable|disable|uninstall`
|
|
221
|
+
|
|
466
222
|
### Server environment variables
|
|
467
223
|
|
|
468
224
|
| Variable | Default | Purpose |
|
|
@@ -480,78 +236,13 @@ trusted localhost/VPN/LAN boundary, not as a multi-tenant public service.
|
|
|
480
236
|
| `AGENT_RELAY_INTEGRATIONS` | `[]` | JSON integration token/scopes/target/callback config |
|
|
481
237
|
| `AGENT_RELAY_INTEGRATION_RATE_LIMIT_PER_MINUTE` | `120` | Per-integration event ingress limit |
|
|
482
238
|
|
|
483
|
-
### Plugin environment variables
|
|
484
|
-
|
|
485
|
-
| Variable | Default | Purpose |
|
|
486
|
-
|----------|---------|---------|
|
|
487
|
-
| `AGENT_RELAY_URL` | `http://localhost:4850` | Relay server URL |
|
|
488
|
-
| `AGENT_RELAY_TOKEN` | unset | Token sent by Codex/dashboard/API clients |
|
|
489
|
-
| `AGENT_RELAY_CAPS` | `chat` | Comma-separated agent capabilities |
|
|
490
|
-
|
|
491
|
-
Agent IDs are deterministic: `{hostname}-{rig}-{project}-{pid-hash}`.
|
|
492
|
-
|
|
493
|
-
### Managed daemon
|
|
494
|
-
|
|
495
|
-
Agent Relay can install itself as a user-level daemon and load on computer
|
|
496
|
-
restart. The installer chooses the safest supported backend:
|
|
497
|
-
|
|
498
|
-
- Linux with `systemctl`: systemd user service by default.
|
|
499
|
-
- macOS: launchd LaunchAgent.
|
|
500
|
-
- Unsupported environments: prints a manual command instead of guessing.
|
|
501
|
-
|
|
502
|
-
Recommended first-time setup:
|
|
503
|
-
|
|
504
|
-
```bash
|
|
505
|
-
# inspect what will be written
|
|
506
|
-
agent-relay setup --dry-run
|
|
507
|
-
|
|
508
|
-
# write the env file with a generated AGENT_RELAY_TOKEN
|
|
509
|
-
agent-relay setup --yes
|
|
510
|
-
|
|
511
|
-
# install, enable at login/boot, and start now
|
|
512
|
-
agent-relay daemon install --binary "$(command -v agent-relay)" --enable --start --yes
|
|
513
|
-
```
|
|
514
|
-
|
|
515
|
-
Lifecycle commands:
|
|
516
|
-
|
|
517
|
-
```bash
|
|
518
|
-
agent-relay daemon status
|
|
519
|
-
agent-relay daemon logs
|
|
520
|
-
agent-relay daemon restart
|
|
521
|
-
agent-relay daemon stop
|
|
522
|
-
agent-relay daemon start
|
|
523
|
-
agent-relay daemon disable
|
|
524
|
-
agent-relay daemon enable
|
|
525
|
-
agent-relay daemon uninstall
|
|
526
|
-
```
|
|
527
|
-
|
|
528
|
-
Useful options:
|
|
529
|
-
|
|
530
|
-
```bash
|
|
531
|
-
# preview service files/commands without changing the machine
|
|
532
|
-
agent-relay daemon install --dry-run --enable --start
|
|
533
|
-
|
|
534
|
-
# remote/VPN bind; setup will still generate a token
|
|
535
|
-
agent-relay setup --host 0.0.0.0 --yes
|
|
536
|
-
agent-relay daemon install --binary "$(command -v agent-relay)" --enable --start --yes
|
|
537
|
-
|
|
538
|
-
# use a known stable binary/script path in the service file
|
|
539
|
-
agent-relay daemon install --binary ~/.bun/bin/agent-relay --enable --start
|
|
540
|
-
```
|
|
541
|
-
|
|
542
|
-
Daemon install/uninstall refuses to overwrite or remove service files that do
|
|
543
|
-
not contain Agent Relay's managed marker unless `--force` is passed.
|
|
544
|
-
|
|
545
239
|
### Version compatibility
|
|
546
240
|
|
|
547
241
|
The plugin checks the server version on startup and warns if they diverge. Both packages share version numbers. Update them together:
|
|
548
242
|
|
|
549
243
|
```bash
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
# update plugin
|
|
554
|
-
claude plugin update agent-relay@agent-relay
|
|
244
|
+
systemctl --user restart agent-relay # server pulls latest on restart
|
|
245
|
+
claude plugin update agent-relay@agent-relay # Claude plugin
|
|
555
246
|
```
|
|
556
247
|
|
|
557
248
|
## API Reference
|
|
@@ -565,9 +256,6 @@ curl -H "Authorization: Bearer $AGENT_RELAY_TOKEN" http://localhost:4850/api/sta
|
|
|
565
256
|
curl -H "X-Agent-Relay-Token: $AGENT_RELAY_TOKEN" http://localhost:4850/api/stats
|
|
566
257
|
```
|
|
567
258
|
|
|
568
|
-
The dashboard asks for the token on first 401 and stores it in browser
|
|
569
|
-
`localStorage` for that origin.
|
|
570
|
-
|
|
571
259
|
### Agents
|
|
572
260
|
|
|
573
261
|
| Method | Path | Purpose |
|
|
@@ -635,19 +323,24 @@ public/
|
|
|
635
323
|
├── index.html # Dashboard markup
|
|
636
324
|
└── dashboard.js # Dashboard Alpine model and behavior
|
|
637
325
|
|
|
638
|
-
claude/ # Claude Code plugin
|
|
326
|
+
claude/ # Claude Code plugin (npm: agent-relay-plugin)
|
|
639
327
|
├── .claude-plugin/plugin.json
|
|
640
328
|
├── monitors/monitors.json # Auto-start inbox monitor
|
|
641
329
|
└── hooks/
|
|
642
330
|
├── relay-monitor.sh # Register, inject context, poll
|
|
331
|
+
├── approval-gate.sh # PreToolUse/PermissionDenied enforcement
|
|
643
332
|
├── set-status.sh # Turn hooks: busy/idle status updates
|
|
644
333
|
├── session-end.sh # Mark agent offline
|
|
645
334
|
└── poll-inbox.sh # Inbox poll loop
|
|
646
335
|
|
|
647
|
-
codex/ # Codex integration
|
|
648
|
-
├──
|
|
649
|
-
├──
|
|
650
|
-
|
|
336
|
+
codex/ # Codex integration (npm: agent-relay-codex)
|
|
337
|
+
├── bin/agent-relay-codex.ts # Launcher CLI (install/start/doctor)
|
|
338
|
+
├── live-sidecar.ts # App-server <-> relay bridge
|
|
339
|
+
├── hooks/session-start.ts # Starts one sidecar per launched thread
|
|
340
|
+
└── plugin/ # Codex plugin bundle
|
|
341
|
+
|
|
342
|
+
client/ # TypeScript client (npm: agent-relay-client)
|
|
343
|
+
└── index.ts # RelayClient class + types
|
|
651
344
|
```
|
|
652
345
|
|
|
653
346
|
## Development
|
package/package.json
CHANGED
|
@@ -1,22 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-relay-server",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.14",
|
|
4
4
|
"description": "Lightweight HTTP message relay for inter-agent communication across machines",
|
|
5
5
|
"module": "src/index.ts",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"bin": {
|
|
8
|
-
"agent-relay": "src/index.ts"
|
|
9
|
-
"agent-relay-codex": "bin/agent-relay-codex.ts",
|
|
10
|
-
"codex-relay": "bin/agent-relay-codex.ts"
|
|
8
|
+
"agent-relay": "src/index.ts"
|
|
11
9
|
},
|
|
12
10
|
"files": [
|
|
13
|
-
"bin/**/*.ts",
|
|
14
11
|
"src/**/*.ts",
|
|
15
12
|
"!src/**/*.test.ts",
|
|
16
|
-
"codex/**/*.ts",
|
|
17
|
-
"codex/**/*.sh",
|
|
18
|
-
"codex/**/*.ps1",
|
|
19
|
-
"codex/plugin/**",
|
|
20
13
|
"examples/**",
|
|
21
14
|
"public/**",
|
|
22
15
|
"README.md",
|
|
@@ -26,13 +19,8 @@
|
|
|
26
19
|
"scripts": {
|
|
27
20
|
"start": "bun run src/index.ts",
|
|
28
21
|
"dev": "bun --watch run src/index.ts",
|
|
29
|
-
"test": "bun test",
|
|
30
|
-
"typecheck": "tsc --noEmit"
|
|
31
|
-
"codex:live": "bun run codex/live-sidecar.ts",
|
|
32
|
-
"codex:live:start": "bash codex/start-live.sh",
|
|
33
|
-
"codex:install": "bun run bin/agent-relay-codex.ts install",
|
|
34
|
-
"codex:doctor": "bun run bin/agent-relay-codex.ts doctor",
|
|
35
|
-
"codex:smoke:fallback": "bun run codex/smoke/fallback.ts"
|
|
22
|
+
"test": "bun test src/",
|
|
23
|
+
"typecheck": "tsc --noEmit"
|
|
36
24
|
},
|
|
37
25
|
"keywords": [
|
|
38
26
|
"agent-relay",
|