Skip to content
Merged
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
22 changes: 19 additions & 3 deletions .env.schema
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,26 @@
# ---

# ── LLM Access ───────────────────────────────────────────────────────────────
# Set at least one. Multiple can coexist — switch models at runtime.

# API key for the LLM provider (Anthropic, OpenAI, or a proxy)
# @required @type=string
# @docs(https://docs.anthropic.com/en/api/getting-started)
# Anthropic API key (Claude models)
# @type=string(startsWith=sk-ant-)
# @docs(https://console.anthropic.com/settings/keys)
ANTHROPIC_API_KEY=

# OpenAI API key (GPT, o-series models)
# @type=string(startsWith=sk-)
# @docs(https://platform.openai.com/api-keys)
OPENAI_API_KEY=

# Google Gemini API key
# @type=string
# @docs(https://aistudio.google.com/apikey)
GEMINI_API_KEY=

# OpenCode Zen API key (multi-provider router)
# @type=string
# @docs(https://opencode.ai)
OPENCODE_ZEN_API_KEY=

# ── GitHub ───────────────────────────────────────────────────────────────────
Expand Down
18 changes: 13 additions & 5 deletions CONFIGURATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,14 @@ Baudbot uses [Varlock](https://varlock.dev) to validate environment variables at

### LLM Access

| Variable | Description | How to get it |
|----------|-------------|---------------|
| `OPENCODE_ZEN_API_KEY` | API key for the LLM provider | Your LLM provider dashboard (e.g. Anthropic, OpenAI, or a proxy like OpenCode Zen) |
Set at least one. Multiple can coexist — switch models at runtime via `/model`.

| Variable | Provider | How to get it |
|----------|----------|---------------|
| `ANTHROPIC_API_KEY` | Anthropic (Claude) | [console.anthropic.com/settings/keys](https://console.anthropic.com/settings/keys) |
| `OPENAI_API_KEY` | OpenAI (GPT, o-series) | [platform.openai.com/api-keys](https://platform.openai.com/api-keys) |
| `GEMINI_API_KEY` | Google Gemini | [aistudio.google.com/apikey](https://aistudio.google.com/apikey) |
| `OPENCODE_ZEN_API_KEY` | OpenCode Zen (multi-provider router) | [opencode.ai](https://opencode.ai) |

### GitHub

Expand Down Expand Up @@ -90,8 +95,11 @@ Set during `setup.sh` via env vars (or edit `~/.gitconfig` after):
## Example `.env` File

```bash
# LLM
OPENCODE_ZEN_API_KEY=sk-...
# LLM (set at least one)
ANTHROPIC_API_KEY=sk-ant-...
# OPENAI_API_KEY=sk-...
# GEMINI_API_KEY=...
# OPENCODE_ZEN_API_KEY=...

# GitHub
GITHUB_TOKEN=ghp_...
Expand Down
4 changes: 2 additions & 2 deletions bin/ci/setup-arch.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ sudo -u baudbot_admin bash -c 'cd ~/baudbot && git init -q && git config user.em

echo "=== Running install.sh ==="
# Simulate interactive input: admin user, required secrets, skip optionals, decline launch
printf 'baudbot_admin\nsk-test-key\nghp_testtoken\nxoxb-test\nxapp-test\nU01TEST\n\n\n\n\n\nn\n' \
printf 'baudbot_admin\nsk-ant-testkey\n\n\n\nghp_testtoken\nxoxb-test\nxapp-test\nU01TEST\n\n\n\n\n\nn\n' \
| bash /home/baudbot_admin/baudbot/install.sh

echo "=== Verifying install ==="
Expand All @@ -32,7 +32,7 @@ test "$(stat -c '%U' /home/baudbot_agent/.config/.env)" = "baudbot_agent"
test -f /home/baudbot_agent/runtime/start.sh
test -d /home/baudbot_agent/.pi/agent/extensions
# Required secrets written
grep -q "OPENCODE_ZEN_API_KEY=sk-test-key" /home/baudbot_agent/.config/.env
grep -q "ANTHROPIC_API_KEY=sk-ant-testkey" /home/baudbot_agent/.config/.env
grep -q "SLACK_BOT_TOKEN=xoxb-test" /home/baudbot_agent/.config/.env
grep -q "BAUDBOT_SOURCE_DIR=" /home/baudbot_agent/.config/.env
echo " ✓ install.sh verification passed"
Expand Down
4 changes: 2 additions & 2 deletions bin/ci/setup-ubuntu.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ sudo -u baudbot_admin bash -c 'cd ~/baudbot && git init -q && git config user.em

echo "=== Running install.sh ==="
# Simulate interactive input: admin user, required secrets, skip optionals, decline launch
printf 'baudbot_admin\nsk-test-key\nghp_testtoken\nxoxb-test\nxapp-test\nU01TEST\n\n\n\n\n\nn\n' \
printf 'baudbot_admin\nsk-ant-testkey\n\n\n\nghp_testtoken\nxoxb-test\nxapp-test\nU01TEST\n\n\n\n\n\nn\n' \
| bash /home/baudbot_admin/baudbot/install.sh

echo "=== Verifying install ==="
Expand All @@ -43,7 +43,7 @@ test "$(stat -c '%U' /home/baudbot_agent/.config/.env)" = "baudbot_agent"
test -f /home/baudbot_agent/runtime/start.sh
test -d /home/baudbot_agent/.pi/agent/extensions
# Required secrets written
grep -q "OPENCODE_ZEN_API_KEY=sk-test-key" /home/baudbot_agent/.config/.env
grep -q "ANTHROPIC_API_KEY=sk-ant-testkey" /home/baudbot_agent/.config/.env
grep -q "SLACK_BOT_TOKEN=xoxb-test" /home/baudbot_agent/.config/.env
grep -q "BAUDBOT_SOURCE_DIR=" /home/baudbot_agent/.config/.env
echo " ✓ install.sh verification passed"
Expand Down
46 changes: 42 additions & 4 deletions install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -237,10 +237,38 @@ prompt_secret() {
echo -e "${BOLD}Required${RESET} ${DIM}(agent won't start without these)${RESET}"
echo ""

echo -e "${BOLD}LLM provider${RESET} ${DIM}(set at least one)${RESET}"
echo ""

prompt_secret "ANTHROPIC_API_KEY" \
"Anthropic API key" \
"https://console.anthropic.com/settings/keys" \
"" \
"sk-ant-"

prompt_secret "OPENAI_API_KEY" \
"OpenAI API key" \
"https://platform.openai.com/api-keys" \
"" \
"sk-"

prompt_secret "GEMINI_API_KEY" \
"Google Gemini API key" \
"https://aistudio.google.com/apikey"

prompt_secret "OPENCODE_ZEN_API_KEY" \
"LLM API key (Anthropic/OpenAI)" \
"https://docs.anthropic.com/en/api/getting-started" \
"required"
"OpenCode Zen API key (multi-provider router)" \
"https://opencode.ai"

HAS_LLM_KEY=false
for k in ANTHROPIC_API_KEY OPENAI_API_KEY GEMINI_API_KEY OPENCODE_ZEN_API_KEY; do
if [ -n "${ENV_VARS[$k]:-}" ]; then HAS_LLM_KEY=true; break; fi
done
if [ "$HAS_LLM_KEY" = false ]; then
warn "No LLM key set — agent needs at least one to work"
fi

echo ""

prompt_secret "GITHUB_TOKEN" \
"GitHub personal access token" \
Expand Down Expand Up @@ -321,6 +349,9 @@ ENV_CONTENT="# Baudbot agent configuration

# Write in a sensible order
ordered_keys=(
ANTHROPIC_API_KEY
OPENAI_API_KEY
GEMINI_API_KEY
OPENCODE_ZEN_API_KEY
GITHUB_TOKEN
SLACK_BOT_TOKEN
Expand Down Expand Up @@ -358,7 +389,14 @@ header "Launch"

# Check if we have the minimum required secrets
MISSING=""
for key in OPENCODE_ZEN_API_KEY GITHUB_TOKEN SLACK_BOT_TOKEN SLACK_APP_TOKEN SLACK_ALLOWED_USERS; do
HAS_LLM=false
for k in ANTHROPIC_API_KEY OPENAI_API_KEY GEMINI_API_KEY OPENCODE_ZEN_API_KEY; do
if [ -n "${ENV_VARS[$k]:-}" ]; then HAS_LLM=true; break; fi
done
if [ "$HAS_LLM" = false ]; then
MISSING+=" - LLM key (ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY, or OPENCODE_ZEN_API_KEY)\n"
fi
for key in GITHUB_TOKEN SLACK_BOT_TOKEN SLACK_APP_TOKEN SLACK_ALLOWED_USERS; do
if [ -z "${ENV_VARS[$key]:-}" ]; then
MISSING+=" - $key\n"
fi
Expand Down
2 changes: 0 additions & 2 deletions pi/settings.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
{
"lastChangelogVersion": "0.52.12",
"defaultProvider": "opencode-zen",
"defaultModel": "claude-opus-4-6",
"skills": [
"~/.pi/agent/skills"
],
Expand Down
34 changes: 33 additions & 1 deletion pi/skills/control-agent/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,17 @@ If dev-agent reports repeated failures (e.g. CI failing after 3+ fix attempts, o

## Spawning a Dev Agent

Pick the model based on which API key is available (check env vars in this order):

**Coding / orchestration (top-tier):**

| API key | Model |
|---------|-------|
| `ANTHROPIC_API_KEY` | `anthropic/claude-opus-4-6` |
| `OPENAI_API_KEY` | `openai/gpt-5.2-codex` |
| `GEMINI_API_KEY` | `google/gemini-3-pro-preview` |
| `OPENCODE_ZEN_API_KEY` | `opencode-zen/claude-opus-4-6` |

Full procedure for spinning up a task-scoped dev agent:

```bash
Expand All @@ -170,7 +181,7 @@ tmux new-session -d -s $SESSION_NAME \
"cd ~/workspace/worktrees/$BRANCH && \
export PATH=\$HOME/.varlock/bin:\$HOME/opt/node-v22.14.0-linux-x64/bin:\$PATH && \
export PI_SESSION_NAME=$SESSION_NAME && \
exec varlock run --path ~/.config/ -- pi --session-control --skill ~/.pi/agent/skills/dev-agent"
exec varlock run --path ~/.config/ -- pi --session-control --skill ~/.pi/agent/skills/dev-agent --model <MODEL_FROM_TABLE_ABOVE>"
```

**Important notes:**
Expand Down Expand Up @@ -331,6 +342,27 @@ The script:

**Note**: Dev agents are NOT started at startup. They are spawned on-demand when tasks arrive.

### Spawning sentry-agent

The sentry-agent triages Sentry alerts and investigates critical issues via the Sentry API. It runs on a cheap model to save tokens.

**Triage (cheap):**

| API key | Model |
|---------|-------|
| `ANTHROPIC_API_KEY` | `anthropic/claude-haiku-4-5` |
| `OPENAI_API_KEY` | `openai/gpt-5-mini` |
| `GEMINI_API_KEY` | `google/gemini-3-flash-preview` |
| `OPENCODE_ZEN_API_KEY` | `opencode-zen/claude-haiku-4-5` |

```bash
tmux new-session -d -s sentry-agent "export PATH=\$HOME/.varlock/bin:\$HOME/opt/node-v22.14.0-linux-x64/bin:\$PATH && export PI_SESSION_NAME=sentry-agent && varlock run --path ~/.config/ -- pi --session-control --skill ~/.pi/agent/skills/sentry-agent --model <MODEL_FROM_TABLE_ABOVE>"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: The SKILL.md file contains conflicting instructions for spawning sentry-agent, with an outdated section hardcoding a model that will fail if its specific API key is not set.
Severity: HIGH

Suggested Fix

Remove the old "## Sentry Agent" section from pi/skills/control-agent/SKILL.md entirely. Retain only the updated "### Spawning sentry-agent" section that includes the model selection table and uses the <MODEL_FROM_TABLE_ABOVE> placeholder.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.

Location: pi/skills/control-agent/SKILL.md#L359

Potential issue: The documentation file `pi/skills/control-agent/SKILL.md` contains two
conflicting sets of instructions for spawning the `sentry-agent`. An older section
includes a command that hardcodes the model to `opencode-zen/claude-haiku-4-5`. A newer
section, introduced by this pull request, provides instructions for dynamic model
selection based on available API keys. If an operator follows the older, hardcoded
instructions and the `OPENCODE_ZEN_API_KEY` is not configured, the `sentry-agent` will
fail to start, even if other provider keys are available. This creates documentation
duplication and a risk of incorrect deployment.

Did we get this right? 👍 / 👎 to inform future reviews.

```

**Model note**: `github-copilot/*` models reject Personal Access Tokens and will fail in non-interactive sessions.

The sentry-agent operates in **on-demand mode** — it does NOT poll. Sentry alerts arrive via the Slack bridge in real-time and are forwarded by you. The sentry-agent uses `sentry_monitor get <issue_id>` to investigate when asked.

### Starting the Slack Bridge

The Slack bridge (Socket Mode) receives real-time Slack events and forwards them to this session via port 7890.
Expand Down
16 changes: 15 additions & 1 deletion start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,20 @@ umask 077
# Set session name (read by auto-name.ts extension)
export PI_SESSION_NAME="control-agent"

# Pick model based on available API keys (first match wins)
if [ -n "${ANTHROPIC_API_KEY:-}" ]; then
MODEL="anthropic/claude-opus-4-6"
elif [ -n "${OPENAI_API_KEY:-}" ]; then
MODEL="openai/gpt-5.2-codex"
elif [ -n "${GEMINI_API_KEY:-}" ]; then
MODEL="google/gemini-3-pro-preview"
elif [ -n "${OPENCODE_ZEN_API_KEY:-}" ]; then
MODEL="opencode-zen/claude-opus-4-6"
else
echo "❌ No LLM API key found — set ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY, or OPENCODE_ZEN_API_KEY"
exit 1
fi

# Start control-agent
# --session-control: enables inter-session communication (handled by control.ts extension)
pi --session-control --skill ~/.pi/agent/skills/control-agent "/skill:control-agent"
pi --session-control --model "$MODEL" --skill ~/.pi/agent/skills/control-agent "/skill:control-agent"