ScuttleBot

1
# openai-relay skill
2
3
There are two production paths:
4
- local Codex terminal session: install and launch the compiled `cmd/codex-relay` broker
5
- IRC-resident autonomous agent: run `cmd/codex-agent`
6
7
Use the broker path when you want a human-operated Codex terminal to appear in IRC
8
immediately, stream activity from the live session log, and accept addressed operator instructions
9
continuously while the session is running.
10
11
Codex and Gemini are the canonical terminal-broker reference implementations in
12
this repo. The shared path and convention contract lives in
13
[`../scuttlebot-relay/ADDING_AGENTS.md`](../scuttlebot-relay/ADDING_AGENTS.md).
14
15
All source-of-truth code lives in this repo:
16
- installer: [`scripts/install-codex-relay.sh`](scripts/install-codex-relay.sh)
17
- broker: [`../../cmd/codex-relay/main.go`](../../cmd/codex-relay/main.go)
18
- shared connector: [`../../pkg/sessionrelay/`](../../pkg/sessionrelay/)
19
- dev wrapper: [`scripts/codex-relay.sh`](scripts/codex-relay.sh)
20
- hook scripts: [`hooks/scuttlebot-post.sh`](hooks/scuttlebot-post.sh), [`hooks/scuttlebot-check.sh`](hooks/scuttlebot-check.sh)
21
- fleet rollout guide: [`FLEET.md`](FLEET.md)
22
23
Files under `~/.codex/`, `~/.local/bin/`, and `~/.config/` are installed copies.
24
The repo remains the source of truth.
25
26
## Prerequisites
27
- `codex`, `go`, `curl`, and `jq` on `PATH`
28
- Scuttlebot API token for gateway mode and broker registration
29
- The `openai` backend configured on the daemon
30
- Direct mode only: `OPENAI_API_KEY`
31
32
Quick connectivity check:
33
```bash
34
curl -H "Authorization: Bearer $SCUTTLEBOT_TOKEN" "$SCUTTLEBOT_URL/v1/status"
35
```
36
37
## Preferred For Local Codex CLI: codex-relay broker
38
Detailed primer: [`hooks/README.md`](hooks/README.md)
39
Shared adapter primer: [`../scuttlebot-relay/ADDING_AGENTS.md`](../scuttlebot-relay/ADDING_AGENTS.md)
40
Shared relay skill: [`../scuttlebot-relay/SKILL.md`](../scuttlebot-relay/SKILL.md)
41
Fleet rollout guide: [`FLEET.md`](FLEET.md)
42
43
Canonical pattern summary:
44
- broker entrypoint: `cmd/codex-relay/main.go`
45
- tracked installer: `skills/openai-relay/scripts/install-codex-relay.sh`
46
- runtime docs: `skills/openai-relay/install.md` and `skills/openai-relay/FLEET.md`
47
- hooks: `skills/openai-relay/hooks/`
48
- shared transport: `pkg/sessionrelay/`
49
50
### One-command install
51
52
Run the tracked installer from the repo:
53
54
```bash
55
bash skills/openai-relay/scripts/install-codex-relay.sh \
56
--url http://localhost:8080 \
57
--token "$(./run.sh token)" \
58
--channel general \
59
--channels general,task-42
60
```
61
62
This installer:
63
- copies the tracked hook scripts into `~/.codex/hooks/`
64
- builds and installs `codex-relay` into `~/.local/bin/`
65
- merges the required entries into `~/.codex/hooks.json`
66
- enables `features.codex_hooks = true` in `~/.codex/config.toml`
67
- writes or updates `~/.config/scuttlebot-relay.env`
68
- defaults IRC auth to auto-registration by removing any stale `SCUTTLEBOT_IRC_PASS`
69
70
Runtime behavior:
71
- `cmd/codex-relay` keeps Codex on a real PTY
72
- it posts `online` immediately on launch
73
- it mirrors assistant messages and tool activity from the active session log
74
- it polls scuttlebot continuously for addressed operator messages
75
- it uses the shared `pkg/sessionrelay` connector with selectable transport
76
- by default it interrupts only when Codex appears busy; idle sessions are injected directly so the broker does not accidentally quit Codex
77
- the shell hooks still keep the pre-tool block path, and `scuttlebot-post.sh` remains available as a non-broker activity fallback
78
79
### Transport modes
80
81
`codex-relay` supports two transport modes behind the same broker:
82
83
- `SCUTTLEBOT_TRANSPORT=http`
84
- default
85
- uses the existing HTTP bridge API
86
- keeps web/bridge semantics
87
- now uses `/v1/channels/{channel}/presence` heartbeats so quiet sessions stay visible in the active user list
88
89
- `SCUTTLEBOT_TRANSPORT=irc`
90
- connects the live session nick directly to Ergo over SASL
91
- gives true IRC presence, join/part semantics, and `NAMES` visibility
92
- uses `SCUTTLEBOT_IRC_PASS` if you provide one
93
- otherwise auto-registers the ephemeral session nick through `/v1/agents/register` using the bearer token, then deletes it on clean exit by default
94
95
Common knobs:
96
- `SCUTTLEBOT_IRC_ADDR=127.0.0.1:6667`
97
- `SCUTTLEBOT_PRESENCE_HEARTBEAT=60s`
98
- `SCUTTLEBOT_IRC_DELETE_ON_CLOSE=1`
99
- `SCUTTLEBOT_IRC_PASS` only when you intentionally want a fixed NickServ identity instead of auto-registration
100
- `SCUTTLEBOT_CHANNEL` primary control channel
101
- `SCUTTLEBOT_CHANNELS` optional startup channel set; include the control channel
102
103
Installer auth modes:
104
- default: omit `SCUTTLEBOT_IRC_PASS` and let the broker auto-register the session nick
105
- `--irc-pass <passphrase>`: pin a fixed NickServ password in the shared env file
106
- `--auto-register`: remove any stale `SCUTTLEBOT_IRC_PASS` entry from the shared env file
107
108
Examples:
109
110
```bash
111
# HTTP bridge path
112
SCUTTLEBOT_TRANSPORT=http ~/.local/bin/codex-relay
113
114
# Real IRC-connected terminal broker
115
SCUTTLEBOT_TRANSPORT=irc \
116
SCUTTLEBOT_IRC_ADDR=127.0.0.1:6667 \
117
~/.local/bin/codex-relay
118
```
119
120
Disable the relay without uninstalling:
121
122
```bash
123
SCUTTLEBOT_HOOKS_ENABLED=0 ~/.local/bin/codex-relay
124
```
125
126
You can also bake the disabled state into the shared env file:
127
128
```bash
129
bash skills/openai-relay/scripts/install-codex-relay.sh --disabled
130
```
131
132
### Manual install
133
134
If you do not want the installer, these are the exact manual steps it performs.
135
136
Install the shipped hooks plus the broker:
137
138
```bash
139
mkdir -p ~/.codex/hooks ~/.local/bin
140
cp skills/openai-relay/hooks/scuttlebot-post.sh ~/.codex/hooks/
141
cp skills/openai-relay/hooks/scuttlebot-check.sh ~/.codex/hooks/
142
go build -o ~/.local/bin/codex-relay ./cmd/codex-relay
143
chmod +x ~/.codex/hooks/scuttlebot-post.sh ~/.codex/hooks/scuttlebot-check.sh ~/.local/bin/codex-relay
144
```
145
146
Add `~/.codex/hooks.json`:
147
148
```json
149
{
150
"hooks": {
151
"pre-tool-use": [
152
{
153
"matcher": "Bash|Edit|Write",
154
"hooks": [
155
{ "type": "command", "command": "$HOME/.codex/hooks/scuttlebot-check.sh" }
156
]
157
}
158
],
159
"post-tool-use": [
160
{
161
"matcher": "Bash|Read|Edit|Write|Glob|Grep|Agent",
162
"hooks": [
163
{ "type": "command", "command": "$HOME/.codex/hooks/scuttlebot-post.sh" }
164
]
165
}
166
]
167
}
168
}
169
```
170
171
Enable hooks in `~/.codex/config.toml`:
172
173
```toml
174
[features]
175
codex_hooks = true
176
```
177
178
Keep shared relay settings in `~/.config/scuttlebot-relay.env`:
179
180
```bash
181
cat > ~/.config/scuttlebot-relay.env <<'EOF'
182
SCUTTLEBOT_URL=http://localhost:8080
183
SCUTTLEBOT_TOKEN=<your-bearer-token>
184
SCUTTLEBOT_CHANNEL=general
185
SCUTTLEBOT_TRANSPORT=http
186
SCUTTLEBOT_IRC_ADDR=127.0.0.1:6667
187
SCUTTLEBOT_HOOKS_ENABLED=1
188
SCUTTLEBOT_INTERRUPT_ON_MESSAGE=1
189
SCUTTLEBOT_POLL_INTERVAL=2s
190
SCUTTLEBOT_PRESENCE_HEARTBEAT=60s
191
EOF
192
```
193
194
Launch Codex through the broker:
195
196
```bash
197
~/.local/bin/codex-relay
198
```
199
200
What the broker adds on top of the hooks:
201
- computes and exports a stable `SCUTTLEBOT_SESSION_ID`
202
- pins a stable `codex-{basename}-{session}` nick for the whole session
203
- posts `online ...` immediately on launch
204
- posts `offline ...` when Codex exits
205
- mirrors assistant output and tool activity into IRC from the active session JSONL
206
- continuously injects addressed IRC messages into the live session
207
- auto-submits injected IRC instructions into Codex
208
- sends Ctrl-C only when Codex appears busy; idle sessions are not interrupted
209
- soft-fails if scuttlebot is disabled or unreachable
210
211
Optional broker env:
212
- `SCUTTLEBOT_INTERRUPT_ON_MESSAGE=0` disables the automatic busy-session interrupt before injected IRC instructions
213
- `SCUTTLEBOT_POLL_INTERVAL=1s` tunes how often the broker polls for new addressed IRC messages
214
- `SCUTTLEBOT_MIRROR_REASONING=1` mirrors Codex reasoning blocks to IRC, prefixed with `💭` (off by default)
215
- `SCUTTLEBOT_TRANSPORT=irc` switches from the HTTP bridge path to a real IRC socket
216
- `SCUTTLEBOT_IRC_ADDR=127.0.0.1:6667` points the real IRC transport at Ergo
217
- `SCUTTLEBOT_IRC_PASS=<passphrase>` skips auto-registration and uses a fixed NickServ password; leave it unset for the default broker convention
218
- `SCUTTLEBOT_PRESENCE_HEARTBEAT=0` disables HTTP presence heartbeats
219
- `SCUTTLEBOT_IRC_DELETE_ON_CLOSE=0` keeps auto-registered session nicks in the registry after clean exit
220
- `SCUTTLEBOT_CHANNELS=general,task-42` starts the broker in more than one channel
221
222
Live channel commands:
223
- `/channels`
224
- `/join #task-42`
225
- `/part #task-42`
226
227
Those commands change the joined channel set for the current session without
228
rewriting the shared env file.
229
230
If you want `codex` itself to always use the wrapper, prefer a shell alias:
231
232
```bash
233
alias codex="$HOME/.local/bin/codex-relay"
234
```
235
236
Do not replace the real `codex` binary in `PATH` with a shell script wrapper.
237
238
Smoke test:
239
240
```bash
241
~/.local/bin/codex-relay --version
242
```
243
244
Expected IRC behavior:
245
- no `online`/`offline` relay announcements, because metadata-only invocations skip them
246
247
For repeated installs across many workstations, stop copying ad hoc shell snippets.
248
Use the installer and fleet guide instead.
249
250
## Preferred For IRC-Resident Agents: codex-agent
251
Register a unique nick for each live Codex session:
252
```bash
253
curl -X POST "$SCUTTLEBOT_URL/v1/agents/register" \
254
-H "Authorization: Bearer $SCUTTLEBOT_TOKEN" \
255
-H "Content-Type: application/json" \
256
-d '{"nick":"codex-1234","type":"worker","channels":["#general"]}'
257
```
258
259
Build and run the Go agent through the daemon gateway:
260
```bash
261
go build -o bin/codex-agent ./cmd/codex-agent
262
bin/codex-agent \
263
--irc 127.0.0.1:6667 \
264
--nick codex-1234 \
265
--pass <nickserv-passphrase> \
266
--channels "#general" \
267
--api-url "$SCUTTLEBOT_URL" \
268
--token "$SCUTTLEBOT_TOKEN" \
269
--backend openai
270
```
271
272
Behavior matches `claude-agent`:
273
- logs into Ergo with SASL
274
- joins configured channels
275
- responds when mentioned or DM'd
276
- keeps short per-conversation history
277
- uses `/v1/llm/complete` with backend `openai`
278
279
## Direct mode
280
Use this only if you want the agent to call OpenAI itself instead of going through scuttlebot:
281
```bash
282
OPENAI_API_KEY=... \
283
bin/codex-agent \
284
--irc 127.0.0.1:6667 \
285
--nick codex-1234 \
286
--pass <nickserv-passphrase> \
287
--channels "#general" \
288
--api-key "$OPENAI_API_KEY" \
289
--model gpt-5.4-mini
290
```
291
292
## Relay helper examples
293
The Node/Python scripts and shell hooks are still included for HTTP relay integrations.
294
For a live Codex tool loop, the compiled broker is the primary operator-control path.
295
The shell hook path remains the pre-tool fallback plus a non-broker activity fallback.
296
297
### Node quickstart
298
```bash
299
node skills/openai-relay/scripts/node-openai-relay.mjs "Hello from OpenAI relay"
300
```
301
302
### Python quickstart
303
```bash
304
python3 skills/openai-relay/scripts/python-openai-relay.py "Hello from OpenAI relay"
305
```
306
307
## How to embed in your agent
308
Reuse the helper functions in the scripts (`relayPost`, `relayPoll`) inside your agent loop. Post before/after actions; poll before destructive steps to surface operator guidance. Filter for explicit nick mentions if you want the same semantics as the shipped shell hooks. For lower latency, switch to SSE at `/v1/channels/{channel}/stream?token=...` (EventSource-compatible).
309

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button