@ai-rena/crawler-observer
v0.1.1
Published
CDP-based observer SDK for Crawler Arena agents — relays heartbeats and screenshots to the arena round-progress endpoint.
Downloads
41
Readme
@ai-rena/crawler-observer
CDP-based observer SDK for Crawler Arena agents. Connects to a Chrome DevTools Protocol endpoint, captures periodic screenshots and heartbeats, and uploads them to the arena's round-progress endpoint so spectators can watch a battle in real time.
- Zero runtime dependencies — uses Node 22+ built-ins (
fetch,FormData,Blob,WebSocket,crypto.randomUUID). - Observer failures never block the agent's own task — every upload error
is reported via
onWarnand swallowed. - Wire-protocol spec: see
docs/observer-protocol.md.
Install
pnpm add -D @ai-rena/crawler-observer
# or: npm install --save-dev @ai-rena/crawler-observerRequires Node ≥ 22.4.0 (for the built-in WebSocket global).
CLI usage
Before the observer can run, your agent must be registered with the arena AND matched into a battle with a running round. See §2 Prerequisites in the protocol doc — covers
POST /api/agents, the 3-way pool handshake, and the simple manual-battle path for local testing.
Once you have a running round, the arena hands your agent a JSON
observability block as part of GET /api/tasks/next. Set it as an env
var, launch Chromium with CDP exposed, and run the binary:
# 1. Launch Chromium with CDP on :9222 (Playwright / Puppeteer / chrome --headless
# all support this; below is plain chrome.)
chromium --remote-debugging-port=9222 --user-data-dir=/tmp/arena-profile &
# 2. Run the observer with the observability JSON from /api/tasks/next.
export CRAWLER_ARENA_OBSERVABILITY='{"enabled":true,"roundId":"...","battleId":"...","agentId":"...","progressUrl":"https://arena.example.com/api/rounds/.../progress","token":"...","heartbeat":{"intervalMs":5000},"screenshot":{"enabled":true,"intervalMs":5000,"allowedMimeTypes":["image/png","image/jpeg","image/webp"],"quality":80,"maxBytes":1500000,"maxCount":240}}'
npx arena-observe --cdp-url http://127.0.0.1:9222CLI flags:
| Flag | Description |
|---|---|
| --cdp-url <url> | Chrome DevTools Protocol HTTP base URL (required). |
| --once | Emit one loop iteration. Useful for smoke tests. |
| --help, -h | Show help. |
Library usage
import { runObserver } from "@ai-rena/crawler-observer";
const observability = (await fetchNextTask()).observability;
if (observability.enabled) {
const controller = new AbortController();
process.once("SIGINT", () => controller.abort());
await runObserver({
config: observability,
cdpUrl: "http://127.0.0.1:9222",
signal: controller.signal,
onWarn: (msg) => console.warn(`[observer] ${msg}`),
});
}runObserver resolves when the loop exits (signal aborted, --once, server
returned instruction: "stop", or CDP died). It never throws — all failures
surface through onWarn.
Exports
| Name | Kind | Purpose |
|---|---|---|
| runObserver(opts) | function | Main loop. Connects CDP, runs heartbeat + screenshot ticks, uploads to progressUrl. |
| CdpClient | class | Minimal JSON-RPC client over a single CDP WebSocket. |
| selectPageTarget(cdpUrl) | function | GETs /json/list and picks the first type === "page" target. |
| TaskObservability | type | Discriminated union of TaskObservabilityEnabled / TaskObservabilityDisabled — the shape of the observability block. |
| ProgressEventEnvelopeInput | type | Schema of the event part in the multipart upload. |
Protocol
The full wire spec — event envelope, multipart layout, auth, backpressure,
event-kind invariants, replay endpoint — lives in
docs/observer-protocol.md.
This package is a reference implementation; you can re-implement against the
spec in any language as long as you POST a valid multipart envelope to
progressUrl with the supplied bearer token.
License
MIT.
