Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 36 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,55 +1,58 @@
<img src="./readme-banner.png" alt="Agent Relay" height="392">
<img src="./readme-banner.png" alt="Agent Relay">

**Website:** [agentrelay.com](https://agentrelay.com) · **Docs:** [agentrelay.com/docs](https://agentrelay.com/docs)

<a href="https://www.npmjs.com/package/@agent-relay/sdk"><img alt="npm" src="https://img.shields.io/npm/v/@agent-relay/sdk"></a>
<a href="https://github.com/AgentWorkforce/relay/actions/workflows/test.yml"><img alt="Tests" src="https://img.shields.io/github/actions/workflow/status/AgentWorkforce/relay/test.yml?branch=main&label=tests"></a>
<a href="./LICENSE"><img alt="License" src="https://img.shields.io/badge/license-Apache--2.0-blue.svg"></a>

</div>
# Use Claude to orchestrate a team of Codex agents.

## Multi Agent Orchestration
Don't limit yourself to one model or one harness. Use the best tools for the job.

Enable your Claude Code, Codex, OpenCode agent spawn agent teams that can communicate and collaborate. Not subagents, but real agents who
could spawn their own subagents. This allows for powerful AI cross-collaboration so you can get the best harnesses + models working
together.
![Three agents debating a plan in real time](./scripts/demos/three-way-debate.gif)

## Benefits Over Subagents
A planner drafts a plan. An adversarial critic tears it apart. A reviewer arbitrates. Three live agents, three terminals, talking to each other on a shared channel until they agree. You watched it happen — you didn't drive it.

1. The agent orchestrating has full insight what the spawned agents are doing. It can read the logs and steer mid turn if needed
2. Enables advanced swarm techniques as each agent can communicate with each other and coordinate to form agent teams for different types: review/fix loops, adversarial/debate pairs, fan-out -> pipeline -> gather, or lead + workers to name a few
3. Diversity of thought and implementation. Codex implement, Claude review, Gemini do the final verification leads to better results as different models + harnesses excel in different things.
4. Review happens as a conversation between the live reviewer and the live implementer, not as a report handed back to the parent after each one finishes.
5. Audit trail exists outside the agent and outside the parent. With the [Agent Relay Observer](https://agentrelay.com/observer) you get full auditability into every single DM and group message sent by the agents.
## What you can build with it today

## Get Started
- **Claude orchestrates, Codex implements.** Spawn a Claude lead that hands work to Codex workers, reads their progress live, and steers mid-task when one goes off the rails.
- **Adversarial review loops.** Run an implementer alongside one or two critics. They iterate until the critic ratifies — no human in the loop.
- **Walk-away autonomy.** Kick off a multi-step job, close the laptop. Agents keep talking, finishing, and verifying each other's work.

1. Install the agent-relay cli
## Get started

```
curl -fsSL https://raw.githubusercontent.com/AgentWorkforce/relay/main/install.sh | bash
1. Install the agent-relay CLI:

```
```bash
curl -fsSL https://raw.githubusercontent.com/AgentWorkforce/relay/main/install.sh | bash
```

2. Install the skill
2. Install the orchestration skill:

```
npx skills add https://github.com/agentworkforce/skills --skill orchestrating-agent-relay
```
```bash
npx skills add https://github.com/agentworkforce/skills --skill orchestrating-agent-relay
```

3. Tell your agent to use it
3. Tell your agent to use it:

```
use the orchestrating-agent-relay skill to spawn a claude and codex agent and [YOUR_TASK]
```
```
use the orchestrating-agent-relay skill to spawn a claude and codex agent and [YOUR_TASK]
```
Comment on lines +39 to +41
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add a language tag to the fenced block to satisfy markdownlint.

This block triggers MD040 because the fence has no language identifier.

Suggested fix
-   ```
+   ```text
    use the orchestrating-agent-relay skill to spawn a claude and codex agent and [YOUR_TASK]
    ```
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
```
use the orchestrating-agent-relay skill to spawn a claude and codex agent and [YOUR_TASK]
```
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 39-39: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.md` around lines 39 - 41, Add a language tag to the fenced code block
containing "use the orchestrating-agent-relay skill to spawn a claude and codex
agent and [YOUR_TASK]" to satisfy markdownlint MD040; change the opening fence
from ``` to ```text so the block becomes a labeled text code block.


For single, well-scoped, one-shot tasks, subagents still win. Agent relay's advantages compound when work is multi-step, multi-role, long-running or needs independent verification.
## Why not subagents?

## SDK
Subagents are the right tool when work is a single well-scoped one-shot. Agent Relay's advantages compound when work is multi-step, multi-role, long-running, or needs independent verification.

Use the Agent Relay SDK to spawn and control agents programmatically.
- **Mix models and harnesses.** Codex implements, Claude reviews, Gemini verifies — each model used for what it's best at, not whatever the parent harness happens to be.
- **Live steering.** The orchestrator reads logs and DMs as workers run and can redirect mid-turn instead of waiting for a final report.
- **Review as a conversation.** The reviewer and implementer talk while the code is being written, not after the fact.
- **Swarm patterns out of the box.** Review/fix loops, adversarial debate pairs, fan-out → pipeline → gather, lead + workers.
- **Audit trail outside the agent.** Every DM and channel message shows up in the [Agent Relay Observer](https://agentrelay.com/observer) — full visibility without trusting the parent agent's self-report.

### Install
## SDK

Spawn and control agents programmatically.

**TypeScript / Node.js**

Expand Down Expand Up @@ -102,24 +105,15 @@ await AgentRelay.waitForAny([x, o], 5 * 60 * 1000);
await relay.shutdown();
```

Want more than a toy example? Start with:
More:

- [Introduction](https://agentrelay.com/docs/introduction)
- [TypeScript SDK README](https://agentrelay.com/docs/typescript-sdk)
- [Python SDK README](https://agentrelay.com/docs/python-sdk)

### What you can build

- Multi-agent coding flows with shared channels and worker handoffs
- Agent inboxes for status updates, blockers, and review loops
- Tooling that lets existing agents communicate without rewriting their runtime
- Local or remote coordination patterns where multiple agents need shared context

Then use Agent Relay to bring agents into a shared workspace and route work between them.

## Supported agents and runtimes

Agent Relay is designed for terminal-native agents and SDK-driven workflows. This repo currently includes first-class support for:
First-class support for terminal-native agents:

- Claude Code
- Codex CLI
Expand All @@ -128,17 +122,15 @@ Agent Relay is designed for terminal-native agents and SDK-driven workflows. Thi

The broader SDK and workflow surface also includes additional integrations in the codebase. See the package docs for details.

### Development

If you want to work on the repo itself:
## Development

```bash
npm install
npm run build
npm test
```

Useful references:
References:

- [CHANGELOG.md](./CHANGELOG.md)
- [GitHub Issues](https://github.com/AgentWorkforce/relay/issues)
Expand Down
Binary file modified readme-banner.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added scripts/demos/three-way-debate.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added scripts/demos/three-way-debate.mp4
Binary file not shown.
82 changes: 82 additions & 0 deletions scripts/demos/three-way-debate.tape
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# Three-Way Plan Debate — VHS recording
#
# Records a side-by-side demo of three named agents (planner, reviewer,
# adversarial) debating a plan in real time, communicating via the
# workspace's general channel.
#
# Strategy (third iteration — the first two failed because VHS keystrokes
# were racing Claude's boot and Opus xhigh thinking was too slow):
# - Use --model sonnet for fast responses
# - Use --task to deliver each agent's role via the broker's controlled
# inject mechanism — the broker waits for Claude to be ready before
# injecting, so the brief never gets dropped
# - No VHS Type into Claude's prompt at all; all input goes to bash shells
# - PlaybackSpeed 2.5x compresses the GIF
#
# Layout: planner left, reviewer top-right, adversarial bottom-right.
#
# Prereqs:
# - `agent-relay` on PATH, `claude` authenticated, tmux 3.x, vhs >= 0.11
#
# Run from repo root:
# vhs scripts/demos/three-way-debate.tape

Output scripts/demos/three-way-debate.gif
Output scripts/demos/three-way-debate.mp4

Set Shell "bash"
Set FontSize 13
Set Width 1920
Set Height 1080
Set Padding 18
Set Theme "Catppuccin Mocha"
Set TypingSpeed 25ms
Set PlaybackSpeed 2.5

# ---------- Hidden setup ----------
Hide

Type "tmux kill-session -t debate 2>/dev/null; agent-relay down 2>/dev/null; true" Enter
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Avoid using a globally generic tmux session name for destructive operations.

Line 39 and Line 81 tear down debate, while Lines 46-48, 53, 57, 61-62 assume that same static name. This can kill a user’s unrelated tmux session if they already have one named debate.

Suggested hardening diff
+Type "SESSION=relay-three-way-debate-${USER:-user}-$$" Enter
-Type "tmux kill-session -t debate 2>/dev/null; agent-relay down 2>/dev/null; true" Enter
+Type "tmux kill-session -t \"$SESSION\" 2>/dev/null; agent-relay down 2>/dev/null; true" Enter

-Type "tmux new-session -d -s debate -x 240 -y 60" Enter
-Type "tmux split-window -h -p 45 -t debate" Enter
-Type "tmux split-window -v -t debate:0.1" Enter
+Type "tmux new-session -d -s \"$SESSION\" -x 240 -y 60" Enter
+Type "tmux split-window -h -p 45 -t \"$SESSION\"" Enter
+Type "tmux split-window -v -t \"$SESSION\":0.1" Enter

-Type `tmux send-keys -t debate:0.1 "agent-relay new reviewer claude --attach --mode passthrough --ephemeral --model sonnet --task 'Watch the general channel using mcp__relaycast__message_inbox_check every 20 seconds. When planner and adversarial deadlock, post a synthesis to general via mcp__relaycast__message_post and say REVIEWER ratified.'" Enter` Enter
+Type `tmux send-keys -t "$SESSION":0.1 "agent-relay new reviewer claude --attach --mode passthrough --ephemeral --model sonnet --task 'Watch the general channel using mcp__relaycast__message_inbox_check every 20 seconds. When planner and adversarial deadlock, post a synthesis to general via mcp__relaycast__message_post and say REVIEWER ratified.'" Enter` Enter

-Type `tmux send-keys -t debate:0.2 "agent-relay new adversarial claude --attach --mode passthrough --ephemeral --model sonnet --task 'Watch the general channel via mcp__relaycast__message_inbox_check every 15 seconds. When planner posts a plan, find 3 biggest flaws and post critique via mcp__relaycast__message_post. Iterate. Say ADVERSARIAL satisfied when convinced.'" Enter` Enter
+Type `tmux send-keys -t "$SESSION":0.2 "agent-relay new adversarial claude --attach --mode passthrough --ephemeral --model sonnet --task 'Watch the general channel via mcp__relaycast__message_inbox_check every 15 seconds. When planner posts a plan, find 3 biggest flaws and post critique via mcp__relaycast__message_post. Iterate. Say ADVERSARIAL satisfied when convinced.'" Enter` Enter

-Type "tmux select-pane -t debate:0.0" Enter
-Type "tmux attach -t debate" Enter
+Type "tmux select-pane -t \"$SESSION\":0.0" Enter
+Type "tmux attach -t \"$SESSION\"" Enter

-Type "tmux kill-session -t debate; agent-relay down" Enter
+Type "tmux kill-session -t \"$SESSION\"; agent-relay down" Enter

Also applies to: 46-48, 53-53, 57-57, 61-62, 81-81

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/demos/three-way-debate.tape` at line 39, Replace the hardcoded tmux
session name "debate" with a generated per-run variable (e.g., DEBATE_SESSION)
and use that variable in every place the script references the session (replace
occurrences of "debate" in commands like tmux kill-session -t debate and any
tmux new-session/attach calls), generating the value once at script start (use a
safe unique suffix like $$ or a timestamp/mktemp-style id) and persisting it for
teardown; also ensure teardown checks that the session exists before killing
(tmux has-session -t "$DEBATE_SESSION") so you don't accidentally kill an
unrelated user session and update any related agent-relay calls to reference the
same variable.

Sleep 2s

Type "agent-relay up --no-spawn >/tmp/agent-relay-vhs.log 2>&1 &" Enter
Sleep 5s

# Build the 3-pane layout
Type "tmux new-session -d -s debate -x 240 -y 60" Enter
Type "tmux split-window -h -p 45 -t debate" Enter
Type "tmux split-window -v -t debate:0.1" Enter

# Spawn reviewer (top-right, pane 0.1) with its task — broker injects when Claude is ready.
# IMPORTANT: must use the verbose `new` verb (not `-n` shorthand) so --task and --model
# are parsed by agent-relay instead of being passed through to claude as unknown options.
Type `tmux send-keys -t debate:0.1 "agent-relay new reviewer claude --attach --mode passthrough --ephemeral --model sonnet --task 'Watch the general channel using mcp__relaycast__message_inbox_check every 20 seconds. When planner and adversarial deadlock, post a synthesis to general via mcp__relaycast__message_post and say REVIEWER ratified.'" Enter` Enter
Sleep 1s

# Spawn adversarial (bottom-right, pane 0.2) with its task
Type `tmux send-keys -t debate:0.2 "agent-relay new adversarial claude --attach --mode passthrough --ephemeral --model sonnet --task 'Watch the general channel via mcp__relaycast__message_inbox_check every 15 seconds. When planner posts a plan, find 3 biggest flaws and post critique via mcp__relaycast__message_post. Iterate. Say ADVERSARIAL satisfied when convinced.'" Enter` Enter
Sleep 1s

# Focus planner pane and attach VHS to tmux
Type "tmux select-pane -t debate:0.0" Enter
Type "tmux attach -t debate" Enter
Sleep 2s

# Give reviewer and adversarial time to boot and start polling
Sleep 18s

# ---------- Recording starts ----------
Show

# Spawn planner with its task — the typed command IS the visible kickoff
Type `agent-relay new planner claude --attach --mode passthrough --ephemeral --model sonnet --task "You are the planner. Two other agents are listening on the general channel: adversarial (critic) and reviewer (arbitrator). Draft a plan to migrate our auth service from session cookies to OAuth2, zero downtime, 50k DAU. Post the plan to general via mcp__relaycast__message_post. Iterate with adversarial until they ratify."`
Sleep 600ms
Enter

# Show debate: ~100s real -> ~40s in the GIF at 2.5x playback
Sleep 100s

# ---------- Cleanup ----------
Hide
Type "tmux kill-session -t debate; agent-relay down" Enter
Sleep 1s
Loading