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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,9 @@ examples/claude_sdk_docker/reviewer.yaml
examples/claude_sdk_docker/implementer.yaml
examples/claude_sdk_docker/.agent_ids.txt
!examples/claude_sdk_docker/example_agent.yaml
examples/coding_agents/.agent_ids.txt
examples/coding_agents/planner.yaml
examples/coding_agents/reviewer.yaml

# Parlant local data (sessions, cache, databases)
parlant-data/
Expand Down
4 changes: 4 additions & 0 deletions examples/coding_agents/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
# Copy to .env and fill in values before running docker compose up.

# ── Platform URLs ─────────────────────────────────────────────────────────
# MUST match the platform you registered the agents against — i.e. the
# BAND_REST_URL used when running create_agents.py (default: app.band.ai).
# A mismatch, or an unreachable/misspelled host, crashes both containers at
# startup with: httpx.ConnectError: [Errno -2] Name or service not known.
BAND_REST_URL=https://app.band.ai
BAND_WS_URL=wss://app.band.ai/api/v1/socket/websocket

Expand Down
63 changes: 45 additions & 18 deletions examples/coding_agents/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,15 @@ Shared workspace volumes:

## Repo Initialization

On startup, each container reads `repo` config from `agent_config.yaml`:
1. Clone repo to `repo.path` if missing
2. Skip clone when repo already exists
3. Optionally generate context files when `repo.index: true`
The `repo` block in `agent_config.yaml` is **optional**. With no `repo` block
(the default written by `create_agents.py`), the agents boot, connect to Band,
and coordinate over chat — no repository is cloned and no GitHub/SSH access is
needed. This is the fastest way to see the two agents talk.

When you add a `repo` block, each container on startup:
1. Clones the repo to `repo.path` if missing
2. Skips the clone when the repo already exists
3. Optionally generates context files when `repo.index: true`

Generated files:
- `/workspace/context/structure.md`
Expand Down Expand Up @@ -62,28 +67,30 @@ When using HTTPS URLs, configure git credentials on host (`credential helper`, P
## Prerequisites

- Docker and Docker Compose v2
- Anthropic API key for planner
- OpenAI API key for reviewer
- Band agent credentials (`agent_id` + `api_key`)
- Anthropic API key for the planner
- OpenAI API key for the reviewer
- A Band **user** API key (`band_u_...`) to register the two agents

## Setup

1. Configure environment:
1. Add your LLM API keys:

```bash
cp .env.example .env
# edit .env: set ANTHROPIC_API_KEY and OPENAI_API_KEY
```

2. Configure agents and repo:
2. Register the agents and generate `agent_config.yaml`:

```bash
cp agent_config.yaml.example agent_config.yaml
BAND_API_KEY=band_u_... python create_agents.py

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Since this script is now the required setup path, can we add PEP 723 metadata and document uv run create_agents.py? Plain python currently depends on the SDK already being installed.

```

Fill in:
- `planner.agent_id`, `planner.api_key`
- `reviewer.agent_id`, `reviewer.api_key`
- `planner.repo` and `reviewer.repo` (same URL/path/branch)
This registers a Planner and a Reviewer and writes the combined
`agent_config.yaml` that compose reads. No repo is wired by default (chat-only).
To point the agents at a shared repo, set `REPO_URL` (and optionally
`REPO_BRANCH`, `REPO_INDEX`) when running the script — see
`agent_config.yaml.example` for the block it produces.

3. Build and run:

Expand All @@ -100,6 +107,12 @@ docker compose logs -f planner
docker compose logs -f reviewer
```

5. (Optional) Send a test message that makes the planner ping the reviewer:

```bash
python test_communication.py
```

## Configuration

### `.env`
Expand All @@ -118,14 +131,17 @@ docker compose logs -f reviewer

### `agent_config.yaml`

Use `repo` under both planner and reviewer:
Generated by `create_agents.py` — you don't normally edit it by hand. It's a
single combined file keyed by agent. The `repo` block is optional; omit it (the
default) for a chat-only stack. To add a repo later, drop an identical `repo`
block under **both** agents:

```yaml
planner:
agent_id: "..."
api_key: "..."
role: planner
repo:
repo: # optional
url: "git@github.com:org/repo.git"
path: "/workspace/repo"
branch: "main"
Expand All @@ -134,7 +150,8 @@ planner:
reviewer:
agent_id: "..."
api_key: "..."
repo:
role: reviewer
repo: # keep identical to planner.repo
url: "git@github.com:org/repo.git"
path: "/workspace/repo"
branch: "main"
Expand All @@ -143,7 +160,17 @@ reviewer:

## Troubleshooting

- `Config file not found`: create `agent_config.yaml` from the example.
- **`Config file is empty` / `IsADirectoryError` on `agent_config.yaml`**: a
stale empty `agent_config.yaml` **directory** exists (Docker auto-creates the
bind-mount source when the file is missing). Run `docker compose down`, then
`rm -rf agent_config.yaml && python create_agents.py` to regenerate the file
before `docker compose up`.
- `Config file not found`: run `create_agents.py` to generate `agent_config.yaml`.
- **`httpx.ConnectError: [Errno -2] Name or service not known` (crash loop)**:
`BAND_REST_URL`/`BAND_WS_URL` in `.env` point at an unreachable/misspelled
host, or at a *different* platform than the one you registered the agents on.
They must match the `BAND_REST_URL` used with `create_agents.py` (default
`https://app.band.ai`). Fix `.env`, then `docker compose up -d --force-recreate`.
- `Invalid repo configuration`: verify `repo.url` and absolute `repo.path`.
- `Host not found in known_hosts`: add host key (`ssh-keyscan -H <host> >> ~/.ssh/known_hosts`).
- `Authentication failed` on clone: verify SSH keys or HTTPS token/credential helper.
Expand Down
47 changes: 26 additions & 21 deletions examples/coding_agents/agent_config.yaml.example
Original file line number Diff line number Diff line change
@@ -1,30 +1,35 @@
# Agent credentials for all agents in this example.
# Copy to agent_config.yaml and fill in values from the Band platform.
# Template for agent_config.yaml (the combined, keyed credentials file that
# docker-compose.yml consumes).
#
# You normally do NOT copy this by hand — `create_agents.py` registers both
# agents and writes agent_config.yaml for you. Use this file only as a reference
# for the format, or to add a `repo:` block after the fact.
#
# NEVER commit real credentials to version control.
#
# Keys must match:
# - AGENT_KEY env var for the Claude SDK planner (default: "planner")
# - REVIEWER_AGENT_KEY in .env (default: "reviewer")
# Keys must match the runner AGENT_KEY:
# planner -> AGENT_KEY=planner (compose service "planner")
# reviewer -> REVIEWER_AGENT_KEY=reviewer (compose service "reviewer")

planner:
agent_id: "" # Agent UUID from Band platform
agent_id: "" # Agent UUID from Band
api_key: "" # Agent-specific Band API key
role: planner
repo:
# Supports either SSH or HTTPS:
# git@github.com:org/repo.git
# https://github.com/org/repo.git
url: "git@github.com:org/repo.git"
path: "/workspace/repo"
branch: "main" # Optional
index: true # Optional: generate /workspace/context/*.md
# Optional — omit entirely for a chat-only stack (no GitHub/SSH). Add an
# identical block under reviewer so both containers target the same repo.
# repo:
# # SSH (git@github.com:org/repo.git) or HTTPS (https://github.com/org/repo.git)
# url: "git@github.com:org/repo.git"
# path: "/workspace/repo"
# branch: "main" # Optional
# index: true # Optional: generate /workspace/context/*.md

reviewer:
agent_id: "" # Agent UUID from Band platform
agent_id: "" # Agent UUID from Band
api_key: "" # Agent-specific Band API key
repo:
# Keep this in sync with planner.repo so both containers target the same repo.
url: "git@github.com:org/repo.git"
path: "/workspace/repo"
branch: "main" # Optional
index: true # Optional: enabled by default in this example
role: reviewer
# repo:
# url: "git@github.com:org/repo.git"
# path: "/workspace/repo"
# branch: "main"
# index: true
Loading