The control plane for AI agents working in real products.
Relay is a website where you can watch your AI agent work in real time from any browser: your phone, another laptop, anywhere. You run one terminal command on your machine to start it. From that point, every action your agent takes streams live to the website. You can pause the agent, redirect it with a new instruction, or stop it, all from the browser and the command reaches the agent on your machine instantly via PowerSync.
Quickstart · Screens · How It Works · Workspace · Architecture Notes
- Watch actions, screenshots, reasoning, drift alerts, and operator controls in one session view.
- Intervene live with pause, resume, redirect, and stop instead of restarting the agent loop.
- Replay a run step-by-step with timeline scrubbing and screenshot recovery.
- Hand a session to another operator with share context and resume instructions.
- Plug external JavaScript or Python agents into Relay through a local HTTP bridge.
Representative screens from the current routes in this repo.
| Route | Purpose |
|---|---|
/ |
Landing page and product overview |
/live |
Live operator feed with actions, screenshots, reasoning, and controls |
/timeline |
Session replay scrubber for historical inspection |
/handoff |
Share token generation plus resume-with-context flow |
/connect |
Bridge onboarding for existing agents |
/demo |
Offline queue demonstration |
/mock-form, /mock-email, /mock-scrape |
Demo targets for browser workflows |
Relay has two operating modes:
- Local-first bridge mode for development and sidecar-style integrations.
- PowerSync-backed sync mode for shared browser and machine state.
flowchart LR
A[Agent runtime<br/>Relay SDK or external agent] -->|actions, reasoning, screenshots| B[(Machine SQLite)]
C[Relay web app<br/>apps/web] -->|pause, redirect, stop| D[(Browser SQLite)]
D <--> |PowerSync| E[(Neon + sync rules)]
E <--> |PowerSync| B
C -->|live feed, replay, handoff| D
The judge-facing loop is the same one the product depends on:
- The browser writes a control command.
- PowerSync propagates it to the machine.
- The local runtime executes it and marks it as handled.
- Relay reflects the new state back to operators in real time.
-
Local-first principles: Relay writes session state to local SQLite first on both the machine and the browser, keeps a local-only bridge mode available when remote sync is unavailable, demonstrates offline queueing in
/demo, and supports optional local drift checks through Ollama. -
PowerSync: PowerSync keeps browser-local and machine-local SQLite state synchronized, propagates operator control commands across devices, and supports the upload/download path that turns local-first writes into shared session state.
-
TanStack:
apps/webis built on TanStack Start and TanStack Router, and uses TanStack-powered routing plus server functions to drive the live feed, timeline replay, handoff, connect, and demo flows. -
Neon: Neon is part of the backend architecture through the schema and migration layer in
packages/db, the durable event model, and the PowerSync upload path that persists actions, reasoning, control commands, and session history.
- Install Node
22+andpnpm 10+. - Install dependencies:
pnpm install- Copy the example env file:
cp .env.example .env- Start the web app:
pnpm dev- In a second terminal, start a Relay session:
pnpm --filter @relay/relay-sdk relay-watch --task "Demo: monitor booking flow"- Open
http://localhost:3000/live.
For a local demo with seeded Relay state, use:
pnpm demo:reset
pnpm demo:devUse the built-in Playwright-backed runtime when you want Relay to drive a real page:
pnpm real-browser --task "Search the site and inspect the main navigation" --screenshot-url https://example.comFor a visible local browser instead of headless mode:
pnpm real-browser-visible --task "Search the site and inspect the main navigation" --screenshot-url https://example.comMock workflows are available for local demos:
pnpm real-browser --workflow mock-form --task "Fill the mock lead intake form" --screenshot-url http://localhost:3000/mock-form
pnpm real-browser --workflow mock-email --task "Draft and send the mock operations email" --screenshot-url http://localhost:3000/mock-email
pnpm real-browser --workflow mock-scrape --task "Scrape visible titles, prices, and stock data from the Books to Scrape poetry catalogue" --screenshot-url https://books.toscrape.com/Relay also works as a sidecar control plane for agents that already exist outside this repo.
Start bridge mode:
pnpm --filter @relay/relay-sdk relay-watch \
--task "My real agent task" \
--name "My External Agent" \
--agent-id my-external-agent \
--user-id demo_user \
--bridge true \
--bridge-port 8787Then point your agent at the local bridge:
curl -X POST http://127.0.0.1:8787/action \
-H "Content-Type: application/json" \
-d '{
"type": "click",
"title": "Clicked checkout",
"detail": "Clicked the checkout button on cart page",
"reasoning": "Proceeding to payment step"
}'Poll controls from the UI:
curl "http://127.0.0.1:8787/control?consumeRedirect=true"Example agents live in:
examples/external-agent-js/agent.mjsexamples/external-agent-python/agent.py
The /connect route generates launch commands, helper snippets, and a cURL smoke test directly in the app.
relay/
apps/
web/ # TanStack Start web app and operator UI
packages/
shared/ # Shared contracts and types
relay-sdk/ # Local runtime, bridge API, browser agent, drift checks
db/ # Migrations and PowerSync / Neon database helpers
docs/
ARCHITECTURE.md # System behavior and demo narrative
Copy .env.example to .env and fill in the pieces you need for your mode:
| Variable | Purpose |
|---|---|
GEMINI_API_KEY, GEMINI_MODEL |
Default sample-agent model setup |
GROQ_API_KEY, GROQ_MODEL |
Optional Groq-based sample-agent setup |
POWERSYNC_URL, POWERSYNC_DEV_TOKEN |
PowerSync-backed sync and token issuance |
VITE_POWERSYNC_URL, VITE_POWERSYNC_DEV_TOKEN |
Browser-side sync configuration |
DATABASE_URL, DATABASE_URL_UNPOOLED |
Neon migrations and PowerSync uploads |
RELAY_SESSION_TOKEN |
Default user/session identity for local runs |
RELAY_DATA_DIR |
Override the local Relay SQLite data directory |
VITE_RELAY_USE_LOCAL_BRIDGE |
Force local bridge mode in the browser |
OLLAMA_MODEL |
Local drift scoring model |
If sync credentials are missing, Relay can still run in local-first mode for development.
pnpm typecheck
pnpm --filter @relay/relay-sdk verify-control-loop
pnpm preflight

