Created
February 26, 2026 22:02
-
-
Save khaliqgant/169be7410d2d06e2fcd320dcaa1da9c3 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * Two agents collaborate on a marketing plan for the Agent Relay SDK. | |
| * | |
| * Claude posts its pillars to #marketing, Codex receives them automatically | |
| * (the broker injects channel messages into subscribed agent PTYs) and | |
| * writes the final plan — no API key required. | |
| * | |
| * Run: | |
| * npm run build && npm run marketing-plan --workspace=packages/sdk | |
| */ | |
| import { randomBytes } from 'node:crypto'; | |
| import { AgentRelay } from '../relay.js'; | |
| import { RelaycastApi } from '../relaycast.js'; | |
| // Auto-provision a fresh isolated workspace — no signup or config needed. | |
| const { apiKey } = await RelaycastApi.createWorkspace(`marketing-plan-${randomBytes(4).toString('hex')}`); | |
| console.log(`\nWorkspace API key: ${apiKey}\nObserver: https://observer.relaycast.dev (paste key above)\n`); | |
| const relay = new AgentRelay({ env: { ...process.env, RELAY_API_KEY: apiKey } }); | |
| // Show when agents are thinking (PTY output chunks). | |
| relay.onWorkerOutput = ({ name }) => { | |
| process.stdout.write(`\r\x1b[2K[${name} is thinking...]`); | |
| }; | |
| // Show completed messages. | |
| relay.onMessageReceived = ({ from, text }) => { | |
| if (text.trim()) { | |
| process.stdout.write('\r\x1b[2K'); // clear the thinking line | |
| console.log(`[${from}]: ${text}`); | |
| } | |
| }; | |
| // Spawn both agents into the same channel. | |
| const [claude, codex] = await Promise.all([ | |
| relay.claude.spawn({ channels: ['marketing'] }), | |
| relay.codex.spawn({ channels: ['marketing'] }), | |
| ]); | |
| console.log('Agents online. Kicking off...\n'); | |
| const system = relay.human({ name: 'System' }); | |
| // Tell Claude to post to #marketing — the broker will inject it into Codex's PTY. | |
| await system.sendMessage({ | |
| to: claude.name, | |
| text: `Post 3 punchy messaging pillars for the Agent Relay SDK to the #marketing channel | |
| using relay_send. The SDK lets developers run Claude, Codex, and Gemini in parallel, | |
| with real-time inter-agent messaging and workflow orchestration.`, | |
| }); | |
| // Tell Codex to watch #marketing, build on Claude's pillars, and post the final plan. | |
| await system.sendMessage({ | |
| to: codex.name, | |
| text: `Watch the #marketing channel. When ${claude.name} posts its pillars, | |
| add your perspective on developer experience and multi-model flexibility, | |
| then post the complete "## Marketing Plan" to #marketing.`, | |
| }); | |
| // Wait for Codex to post the finished plan. | |
| await new Promise<void>((resolve) => { | |
| relay.onMessageReceived = ({ from, text }) => { | |
| if (text.trim()) { | |
| process.stdout.write('\r\x1b[2K'); | |
| console.log(`[${from}]: ${text}`); | |
| } | |
| if (from === codex.name && text.includes('## Marketing Plan')) { | |
| resolve(); | |
| } | |
| }; | |
| }); | |
| console.log('\nDone. Shutting down...'); | |
| await claude.release(); | |
| await codex.release(); | |
| await relay.shutdown(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment