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:
File diff suppressed because one or more lines are too long
@@ -172,6 +172,40 @@ After upgrading bd, use `bd migrate` to check for and migrate old database files
|
|||||||
|
|
||||||
**AI agents:** Use `--inspect` to analyze migration safety before running. The system verifies required config keys and data integrity invariants.
|
**AI agents:** Use `--inspect` to analyze migration safety before running. The system verifies required config keys and data integrity invariants.
|
||||||
|
|
||||||
|
## Advanced: Agent Mail (Optional)
|
||||||
|
|
||||||
|
For **multi-agent workflows** (2+ AI agents working concurrently), Agent Mail provides real-time coordination:
|
||||||
|
|
||||||
|
**Benefits:**
|
||||||
|
- 20-50x latency reduction (<100ms vs 2-5s git sync)
|
||||||
|
- Collision prevention via file reservations
|
||||||
|
- Agents can't accidentally claim same issue
|
||||||
|
|
||||||
|
**Quick setup:**
|
||||||
|
```bash
|
||||||
|
# Install and start server (one-time)
|
||||||
|
git clone https://github.com/Dicklesworthstone/mcp_agent_mail.git
|
||||||
|
cd mcp_agent_mail && python3 -m venv .venv && source .venv/bin/activate
|
||||||
|
pip install -e .
|
||||||
|
python -m mcp_agent_mail.cli serve-http
|
||||||
|
|
||||||
|
# Configure each agent (environment variables)
|
||||||
|
export BEADS_AGENT_MAIL_URL=http://127.0.0.1:8765
|
||||||
|
export BEADS_AGENT_NAME=assistant-alpha # Unique per agent
|
||||||
|
export BEADS_PROJECT_ID=my-project
|
||||||
|
|
||||||
|
# Use bd normally - Agent Mail auto-activates
|
||||||
|
bd ready
|
||||||
|
bd update bd-42 --status in_progress # Reserves instantly
|
||||||
|
```
|
||||||
|
|
||||||
|
**When to use:**
|
||||||
|
- ✅ Multiple agents working simultaneously
|
||||||
|
- ✅ High collision risk (frequent status updates)
|
||||||
|
- ❌ Single agent workflows (unnecessary overhead)
|
||||||
|
|
||||||
|
See [AGENT_MAIL.md](AGENT_MAIL.md) for complete guide.
|
||||||
|
|
||||||
## Next Steps
|
## Next Steps
|
||||||
|
|
||||||
- Add labels: `./bd create "Task" -l "backend,urgent"`
|
- Add labels: `./bd create "Task" -l "backend,urgent"`
|
||||||
|
|||||||
@@ -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
|
- Random issue creation to simulate real agent behavior
|
||||||
- Dependency linking with `discovered-from`
|
- Dependency linking with `discovered-from`
|
||||||
- Statistics display
|
- Statistics display
|
||||||
|
- **Optional Agent Mail integration** for multi-agent coordination
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
@@ -20,6 +21,8 @@ A bash script demonstrating how an AI agent can use bd to manage tasks autonomou
|
|||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
|
### Basic (Single Agent)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Make executable
|
# Make executable
|
||||||
chmod +x agent.sh
|
chmod +x agent.sh
|
||||||
@@ -31,6 +34,29 @@ chmod +x agent.sh
|
|||||||
./agent.sh 20
|
./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
|
## What It Does
|
||||||
|
|
||||||
The agent runs in a loop:
|
The agent runs in a loop:
|
||||||
|
|||||||
@@ -4,10 +4,15 @@
|
|||||||
#
|
#
|
||||||
# This demonstrates the full lifecycle of an agent managing tasks:
|
# This demonstrates the full lifecycle of an agent managing tasks:
|
||||||
# - Find ready work
|
# - Find ready work
|
||||||
# - Claim and execute
|
# - Claim and execute (with optional Agent Mail reservation)
|
||||||
# - Discover new issues
|
# - Discover new issues
|
||||||
# - Link discoveries
|
# - Link discoveries
|
||||||
# - Complete and move on
|
# - 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
|
set -euo pipefail
|
||||||
|
|
||||||
@@ -34,6 +39,88 @@ log_error() {
|
|||||||
echo -e "${RED}✗${NC} $1"
|
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
|
# Check if bd is installed
|
||||||
if ! command -v bd &> /dev/null; then
|
if ! command -v bd &> /dev/null; then
|
||||||
log_error "bd is not installed"
|
log_error "bd is not installed"
|
||||||
@@ -63,9 +150,21 @@ get_field() {
|
|||||||
# Claim a task
|
# Claim a task
|
||||||
claim_task() {
|
claim_task() {
|
||||||
local issue_id="$1"
|
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"
|
log_info "Claiming task: $issue_id"
|
||||||
bd update "$issue_id" --status in_progress --json > /dev/null
|
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"
|
log_success "Task claimed"
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
# Simulate doing work (in real agent, this would call LLM/execute code)
|
# Simulate doing work (in real agent, this would call LLM/execute code)
|
||||||
@@ -113,6 +212,11 @@ complete_task() {
|
|||||||
|
|
||||||
log_info "Completing task: $issue_id"
|
log_info "Completing task: $issue_id"
|
||||||
bd close "$issue_id" --reason "$reason" --json > /dev/null
|
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"
|
log_success "Task completed: $issue_id"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,8 +259,11 @@ run_agent() {
|
|||||||
|
|
||||||
issue_id=$(get_field "$ready_work" "id")
|
issue_id=$(get_field "$ready_work" "id")
|
||||||
|
|
||||||
# Claim it
|
# Claim it (may fail if another agent reserved it)
|
||||||
claim_task "$issue_id"
|
if ! claim_task "$issue_id"; then
|
||||||
|
log_warning "Skipping already-claimed task, trying next iteration"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
# Do the work
|
# Do the work
|
||||||
if do_work "$ready_work"; then
|
if do_work "$ready_work"; then
|
||||||
|
|||||||
Reference in New Issue
Block a user