# Gamechat – Voice-Based Agent Orchestrator Built in Rust

> Source: <https://github.com/zdql/gamechat>
> Published: 2026-05-26 13:26:06+00:00

Voice-driven supervisor for [Claude Code](https://github.com/anthropics/claude-code) and [Codex](https://github.com/openai/codex). You talk to a low-latency Realtime model in your terminal; whenever you ask for real work, it dispatches a job to a background coding agent and narrates the result when it lands.

```
🎤 ──▶ OpenAI Realtime (gpt-realtime-2) ──▶ 🔈
                │
                │  tool: delegate_to_orchestrator(slug, intent, …)
                │  tool: sub_agent_progress(slug)
                ▼
        OrchestratorJobManager
                │  one worker task per slug, ordered within a slug,
                │  concurrent across slugs
                ▼
        ┌───────┴────────┐
   `claude -p`        `codex exec`
   (Claude Code)      (Codex CLI)
```

There is exactly **one realtime voice loop** and an **async worker pool** for background agent jobs. Those are the two halves of the binary.

A single `tokio::select!`

loop that owns:

- a microphone stream (
`cpal`

, mono, resampled to 24 kHz) - a websocket to the OpenAI Realtime API
- a playback buffer (
`cpal`

again, jittered) - a channel of job-completion events from the worker pool

On startup it sends a `session.update`

that registers two tools — `delegate_to_orchestrator`

and `sub_agent_progress`

— and tells the model to use stable snake_case **slugs** for each background task. Reusing a slug continues the same orchestrator conversation; new slugs spawn parallel work. Run `gamechat --print-realtime-config`

to inspect the exact JSON.

`OrchestratorJobManager`

runs in its own task. Behind it:

**One worker per slug.** All sends for`refactor_docs`

go through the same`OrchestratorSession`

, in order. Different slugs run concurrently in independent sessions.**A** Workers stream snippets into a slug-keyed buffer;`ProgressStore`

.`sub_agent_progress`

queries it with built-in rate limiting (~5 s) so the model can't poll itself into a loop.**A** with two backends:`Provider`

/`Session`

trait— spawns`claude`

`claude -p`

per send. First send uses`--name <slug>`

; subsequent sends use`--resume <session_id>`

. Claude Code's server-side prompt cache does the heavy lifting; we don't maintain our own.— spawns`codex`

`codex exec`

per send and tails its output back through the same`SendResult`

shape.

Adding a third backend means implementing `Provider`

and wiring one match arm in `main.rs`

. The voice loop doesn't know which agent is on the other end.

```
curl -fsSL https://raw.githubusercontent.com/zdql/gamechat/main/install.sh | sh
```

Pulls the latest prebuilt binary for your platform from [GitHub Releases](https://github.com/zdql/gamechat/releases) and drops it in `~/.local/bin/gamechat`

. Supported platforms: `darwin-arm64`

, `darwin-x86_64`

, `linux-x86_64`

, `linux-arm64`

.

The installer also prompts (hidden input) for your `OPENAI_API_KEY`

and stores it at `~/.config/gamechat/env`

(mode 0600). `gamechat`

reads that file automatically from any working directory, so `gamechat --realtime`

just works after install. Skip the prompt with `GAMECHAT_NO_PROMPT=1`

.

If `~/.local/bin`

isn't on your `PATH`

, the installer prints the line to add to your shell profile.

**Pin a version or change install location:**

```
GAMECHAT_VERSION=v0.1.0 INSTALL_DIR=/usr/local/bin \
  sh -c "$(curl -fsSL https://raw.githubusercontent.com/zdql/gamechat/main/install.sh)"
git clone https://github.com/zdql/gamechat.git && cd gamechat
cargo install --path .
```

Requires Rust 1.87+. Linux additionally needs `libasound2-dev`

(and `pkg-config`

) for `cpal`

.

— required. The Realtime API runs on OpenAI regardless of which background agent you use.`OPENAI_API_KEY`

**A coding agent on your**`$PATH`

:[Claude Code](https://github.com/anthropics/claude-code)(`claude`

) — default backend.[Codex CLI](https://github.com/openai/codex)(`codex`

) — pass`--provider codex`

.

- Microphone + speakers.

`gamechat`

looks for env vars in three places, in order: the process environment, then a `.env`

file in the current directory or any parent, then `$XDG_CONFIG_HOME/gamechat/env`

(defaults to `~/.config/gamechat/env`

). The installer writes that last file; per-project `.env`

s override it. First match wins per variable.

```
# Live voice session — talks to Claude Code by default. Ctrl-C to stop.
gamechat --realtime

# Use Codex instead.
gamechat --realtime --provider codex --codex-model gpt-5-codex

# One-shot delegation (no audio) — useful for scripting / smoke tests.
gamechat --once "summarize the last 5 commits" --slug summarize_commits

# Dump the session.update JSON without connecting.
gamechat --print-realtime-config
```

| Flag | Default | Description |
|---|---|---|
`--realtime` |
— | Live voice loop (mic + speakers). |
`--once <msg>` |
— | Single delegation; prints the `VoiceUpdate` JSON. |
`--provider <claude|codex>` |
`claude` |
Background coding agent. |
`--model <id>` |
`gpt-realtime-2` |
Realtime voice model. |
`--slug <slug>` |
`default` |
Background task slug (used with `--once` ). |
`--claude-bin` / `--claude-model` |
autodetect | Override the `claude` binary or its model. |
`--codex-bin` / `--codex-model` |
autodetect | Override the `codex` binary or its model. |

```
gamechat/
├── src/
│   ├── main.rs              # CLI, dotenv, provider wiring
│   ├── types.rs             # DelegateToOrchestratorArgs, VoiceUpdate
│   ├── voice_loop/
│   │   ├── mod.rs           # The select! loop
│   │   ├── session.rs       # session.update JSON + tool defs
│   │   └── audio.rs         # cpal input/output, resampling
│   └── orchestrator/
│       ├── interface.rs     # Provider / Session traits, public types
│       ├── jobs.rs          # OrchestratorJobManager + per-slug workers
│       ├── progress.rs      # ProgressStore + rate-limited snapshots
│       ├── bridge.rs        # Realtime tool calls ↔ job events
│       ├── shared.rs        # Logging / stream helpers
│       ├── claude/          # `claude -p` backend
│       └── openai/          # `codex exec` backend
├── install.sh               # curl|sh installer
└── .github/workflows/release.yml  # cross-platform release builds
```

MIT.
