Add Agent Mail documentation and bash-agent integration

- Added Agent Mail section to QUICKSTART.md with benefits and setup
- Integrated Agent Mail into bash-agent example with reservation/notification
- Added multi-agent usage instructions to bash-agent README
- Closed bd-eimz (QUICKSTART), bd-fkdw (bash-agent), bd-sc57 (production)
- Completed bd-nl8z documentation epic

Amp-Thread-ID: https://ampcode.com/threads/T-5b0d67ff-5eb2-41b3-bc9b-7f33719e0c85
Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
Steve Yegge
2025-11-08 01:10:20 -08:00
parent 687c23cf71
commit c3856bb140
4 changed files with 173 additions and 6 deletions

View File

@@ -10,6 +10,7 @@ A bash script demonstrating how an AI agent can use bd to manage tasks autonomou
- Random issue creation to simulate real agent behavior
- Dependency linking with `discovered-from`
- Statistics display
- **Optional Agent Mail integration** for multi-agent coordination
## Prerequisites
@@ -20,6 +21,8 @@ A bash script demonstrating how an AI agent can use bd to manage tasks autonomou
## Usage
### Basic (Single Agent)
```bash
# Make executable
chmod +x agent.sh
@@ -31,6 +34,29 @@ chmod +x agent.sh
./agent.sh 20
```
### Multi-Agent Mode (with Agent Mail)
```bash
# Terminal 1: Start Agent Mail server
cd ~/src/mcp_agent_mail
source .venv/bin/activate
python -m mcp_agent_mail.cli serve-http
# Terminal 2: Run first agent
export BEADS_AGENT_MAIL_URL=http://127.0.0.1:8765
export BEADS_AGENT_NAME=bash-agent-1
export BEADS_PROJECT_ID=my-project
./agent.sh 10
# Terminal 3: Run second agent (simultaneously)
export BEADS_AGENT_MAIL_URL=http://127.0.0.1:8765
export BEADS_AGENT_NAME=bash-agent-2
export BEADS_PROJECT_ID=my-project
./agent.sh 10
```
Agents will coordinate via Agent Mail to prevent claiming the same issues.
## What It Does
The agent runs in a loop:

View File

@@ -4,10 +4,15 @@
#
# This demonstrates the full lifecycle of an agent managing tasks:
# - Find ready work
# - Claim and execute
# - Claim and execute (with optional Agent Mail reservation)
# - Discover new issues
# - Link discoveries
# - Complete and move on
#
# Optional Agent Mail integration:
# export BEADS_AGENT_MAIL_URL=http://127.0.0.1:8765
# export BEADS_AGENT_NAME=bash-agent-1
# export BEADS_PROJECT_ID=my-project
set -euo pipefail
@@ -34,6 +39,88 @@ log_error() {
echo -e "${RED}${NC} $1"
}
# Agent Mail integration (optional, graceful degradation)
AGENT_MAIL_ENABLED=false
AGENT_MAIL_URL="${BEADS_AGENT_MAIL_URL:-}"
AGENT_NAME="${BEADS_AGENT_NAME:-bash-agent-$$}"
PROJECT_ID="${BEADS_PROJECT_ID:-default}"
# Check Agent Mail health
check_agent_mail() {
if [[ -z "$AGENT_MAIL_URL" ]]; then
return 1
fi
if ! command -v curl &> /dev/null; then
log_warning "curl not available, Agent Mail disabled"
return 1
fi
if curl -s -f "$AGENT_MAIL_URL/health" > /dev/null 2>&1; then
return 0
fi
return 1
}
# Reserve an issue (prevents other agents from claiming)
reserve_issue() {
local issue_id="$1"
if ! $AGENT_MAIL_ENABLED; then
return 0 # Skip if disabled
fi
local response=$(curl -s -X POST "$AGENT_MAIL_URL/api/reserve" \
-H "Content-Type: application/json" \
-d "{\"file_path\": \"$issue_id\", \"agent_name\": \"$AGENT_NAME\", \"project_id\": \"$PROJECT_ID\", \"ttl_seconds\": 300}" \
2>/dev/null || echo "")
if [[ -z "$response" ]] || echo "$response" | grep -q "error"; then
log_warning "Failed to reserve $issue_id (may be claimed by another agent)"
return 1
fi
return 0
}
# Release an issue reservation
release_issue() {
local issue_id="$1"
if ! $AGENT_MAIL_ENABLED; then
return 0 # Skip if disabled
fi
curl -s -X POST "$AGENT_MAIL_URL/api/release" \
-H "Content-Type: application/json" \
-d "{\"file_path\": \"$issue_id\", \"agent_name\": \"$AGENT_NAME\", \"project_id\": \"$PROJECT_ID\"}" \
> /dev/null 2>&1 || true
}
# Send notification to other agents
notify() {
local event_type="$1"
local issue_id="$2"
local message="$3"
if ! $AGENT_MAIL_ENABLED; then
return 0 # Skip if disabled
fi
curl -s -X POST "$AGENT_MAIL_URL/api/notify" \
-H "Content-Type: application/json" \
-d "{\"event_type\": \"$event_type\", \"from_agent\": \"$AGENT_NAME\", \"project_id\": \"$PROJECT_ID\", \"payload\": {\"issue_id\": \"$issue_id\", \"message\": \"$message\"}}" \
> /dev/null 2>&1 || true
}
# Initialize Agent Mail
if check_agent_mail; then
AGENT_MAIL_ENABLED=true
log_success "Agent Mail enabled (agent: $AGENT_NAME)"
else
log_info "Agent Mail disabled (Beads-only mode)"
fi
# Check if bd is installed
if ! command -v bd &> /dev/null; then
log_error "bd is not installed"
@@ -63,9 +150,21 @@ get_field() {
# Claim a task
claim_task() {
local issue_id="$1"
# Try to reserve first (Agent Mail)
if ! reserve_issue "$issue_id"; then
log_error "Could not reserve $issue_id - skipping"
return 1
fi
log_info "Claiming task: $issue_id"
bd update "$issue_id" --status in_progress --json > /dev/null
# Notify other agents
notify "status_changed" "$issue_id" "Claimed by $AGENT_NAME"
log_success "Task claimed"
return 0
}
# Simulate doing work (in real agent, this would call LLM/execute code)
@@ -113,6 +212,11 @@ complete_task() {
log_info "Completing task: $issue_id"
bd close "$issue_id" --reason "$reason" --json > /dev/null
# Notify completion and release reservation
notify "issue_completed" "$issue_id" "$reason"
release_issue "$issue_id"
log_success "Task completed: $issue_id"
}
@@ -155,8 +259,11 @@ run_agent() {
issue_id=$(get_field "$ready_work" "id")
# Claim it
claim_task "$issue_id"
# Claim it (may fail if another agent reserved it)
if ! claim_task "$issue_id"; then
log_warning "Skipping already-claimed task, trying next iteration"
continue
fi
# Do the work
if do_work "$ready_work"; then