Operations Guide¶
This document covers deployment, configuration, monitoring, security, and day-to-day operation of Agents Discussion.
Table of Contents¶
- Deployment
- Local Installation
- Docker Deployment
- Reverse Proxy Setup
- Configuration
- Environment Variables
- Model Selection
- Prompt Templates
- Authentication
- GitHub Models
- GitHub Copilot
- Runtime Management
- Starting the Web Server
- CLI Execution
- Run Lifecycle
- Tool Operations
- Approval Gating
- Tool Configuration
- Adding Custom Tools
- Monitoring
- Audit Logs
- Health Checks
- Troubleshooting
- Backup & Recovery
- Security Hardening
- Maintenance
Deployment¶
Local Installation¶
# 1. Clone and enter directory
cd /path/to/agents-discussion
# 2. Create virtual environment
python -m venv .venv
source .venv/bin/activate
# 3. Install in editable mode
pip install -e .
# 4. Copy and edit configuration
cp .env.example .env
# Edit .env with your tokens and preferences
# 5. Verify installation
agents-discuss --help
agents-discuss-web --help
Docker Deployment¶
# 1. Build and start
cp .env.example .env # edit as needed
docker compose up --build
# 2. Access the web UI
# http://localhost:8000 (or WEB_HOST:WEB_PORT from .env)
Docker Compose Services:
| Service | Description | Volume |
|---|---|---|
web |
FastAPI server | /data for run persistence |
Persistent Data:
The volume /data inside the container stores:
- Completed run JSON files
- audit.jsonl tool invocation log
- Custom prompt templates (if mounted)
Reverse Proxy Setup¶
For production deployment behind a reverse proxy:
Nginx Example:
server {
listen 443 ssl http2;
server_name diagnosis.example.com;
ssl_certificate /etc/ssl/certs/example.com.crt;
ssl_certificate_key /etc/ssl/private/example.com.key;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_read_timeout 86400; # SSE connections are long-lived
}
}
Important: SSE connections require proxy_read_timeout to be high (default in Nginx is 60s, which kills streams).
Configuration¶
Environment Variables¶
All configuration is via environment variables or .env file. See .env.example for the full list.
Required¶
| Variable | Default | Description |
|---|---|---|
GITHUB_TOKEN |
— | PAT for GitHub Models (if not using Copilot) |
DIAGNOSTIC_MODEL |
copilot/gpt-4o |
Model for diagnosis agent |
SKEPTIC_MODEL |
copilot/claude-sonnet-4.6 |
Model for skeptic agent |
MODERATOR_MODEL |
copilot/claude-sonnet-4.6 |
Model for moderator |
Optional — Architecture¶
| Variable | Default | Description |
|---|---|---|
MAX_ROUNDS |
4 | Maximum debate rounds (1–10) |
CONFIDENCE_THRESHOLD |
0.8 | Threshold for moderator to close |
COMPRESS_HISTORY |
true |
Enable history compression after round 2 |
SUMMARY_MODEL |
"" |
Model for history summaries (empty = moderator_model) |
EARLY_OUT_ENABLED |
true |
Allow diagnostic agent to signal early closure |
EARLY_OUT_THRESHOLD |
0.9 | Confidence threshold for early-out |
Optional — Tools¶
| Variable | Default | Description |
|---|---|---|
TOOLS_ENABLED |
true |
Enable ReAct tools |
MAX_TOOL_CALLS_PER_AGENT |
8 | Calls per agent per round |
ENABLED_TOOLS |
"" |
Comma-separated limit (empty = all) |
TOOL_APPROVAL_REQUIRED |
true |
Require approval for sensitive tools |
APPROVAL_REQUIRED_TOOLS |
run_ssh_command,run_local_command,run_kubectl,run_db_explain |
Which tools need approval |
run_local_command does not invoke a shell. It accepts only a fixed allowlist
of read-only diagnostic executables. SSH host keys must already exist in the
service user's known_hosts; unknown hosts are rejected.
Optional — Web security¶
| Variable | Default | Description |
|---|---|---|
WEB_HOST |
127.0.0.1 |
Listen address; keep loopback unless protected by a reverse proxy |
WEB_PORT |
8000 |
Listen port |
WEB_USERNAME |
"" |
HTTP Basic username; configure together with WEB_PASSWORD |
WEB_PASSWORD |
"" |
HTTP Basic password; configure together with WEB_USERNAME |
MAX_UPLOAD_BYTES |
10485760 |
Maximum bytes accepted per uploaded file |
ALLOWED_PROJECT_ROOTS |
current directory | Comma-separated roots readable by the web project-context collector |
The bundled Compose file publishes port 8000 on 127.0.0.1 only. Configure
authentication and TLS at the application or reverse-proxy layer before
making it reachable from another host.
Optional — Observability Endpoints¶
| Variable | Default | Description |
|---|---|---|
PROMETHEUS_URL |
— | Prometheus server for query_prometheus |
LOKI_URL |
— | Loki server for query_loki |
ELASTICSEARCH_URL |
— | Elasticsearch for query_elasticsearch |
DATABASE_URL |
— | Database for run_db_explain |
Optional — SSH¶
| Variable | Default | Description |
|---|---|---|
SSH_DEFAULT_USER |
"" |
Default SSH username |
SSH_KEY_PATH |
"" |
Default SSH private key |
SSH_CONNECT_TIMEOUT |
15 | Connection timeout in seconds |
Model Selection¶
Models are specified with optional provider prefix:
# GitHub Models (uses GITHUB_TOKEN)
DIAGNOSTIC_MODEL=openai/gpt-4o
SKEPTIC_MODEL=openai/gpt-4.1
MODERATOR_MODEL=openai/gpt-4o-mini
# GitHub Copilot (uses COPILOT_TOKEN, supports Claude/Gemini)
DIAGNOSTIC_MODEL=copilot/gpt-4o
SKEPTIC_MODEL=copilot/claude-sonnet-4.6
MODERATOR_MODEL=copilot/claude-sonnet-4.6
Prompt Templates¶
Built-in templates:
- default — General diagnosis
- performance — Degradation and latency
- errors — 5xx errors and exceptions
- data — Data inconsistencies and corruption
- security — Security incidents
Override or add templates:
mkdir -p ~/.local/share/agents-discussion/prompts
cat > ~/.local/share/agents-discussion/prompts/custom.en.yaml << 'EOF'
name: custom
language: en
version: 1
description: Custom incident template
diagnostic_system: |
You are a senior SRE diagnosing incidents...
skeptic_system: |
You are a skeptical peer reviewer...
moderator_system: |
You are a tech lead reviewing the debate...
EOF
Authentication¶
GitHub Models¶
- Generate a PAT at https://github.com/settings/tokens
- Ensure it has access to GitHub Models
- Set
GITHUB_TOKEN=ghp_...in.env
GitHub Copilot¶
- Run the auth helper once:
agents-discuss-copilot-auth
This initiates the OAuth device flow and stores the token in ~/.config/agents-discussion/copilot_token.
- Alternatively, copy the token directly to
.env:
COPILOT_TOKEN=ghu_xxxxxxxxxxxxxxxxxxxx
Session tokens (TTL ~25 minutes) are managed automatically by auth_copilot.py.
Runtime Management¶
Starting the Web Server¶
# Default: 127.0.0.1:8000
agents-discuss-web
# Custom host/port
WEB_HOST=0.0.0.0 WEB_PORT=8080 agents-discuss-web
CLI Execution¶
# Basic usage
agents-discuss "The /orders endpoint is slow"
# With context files
agents-discuss "Diagnose the issue" \
--base-context architecture.md \
--file incident.log
# With project context
agents-discuss "Debug slowness" \
--project ./backend \
--include "src/**/*.py" \
--include "config/**/*.yaml"
# With custom thresholds
agents-discuss "Quick diagnosis" \
--early-out-threshold 0.85 \
--no-compress-history
Run Lifecycle¶
| State | Description | Transitions |
|---|---|---|
running |
Debate in progress | → completed, cancelled, error, interrupted |
completed |
Moderator closed successfully | Final report available |
cancelled |
Operator stopped manually | Partial results preserved |
error |
Exception during execution | Error message in final event |
interrupted |
Server crashed during run | Marked on next startup |
Resuming a Run¶
From the web UI or API:
POST /api/runs/{run_id}/resume
Content-Type: multipart/form-data
new_evidence=Additional logs from 2024-01-15
Tool Operations¶
Approval Gating¶
Sensitive tools block until an operator approves. The approval UI shows:
- Tool name and arguments
- Agent that requested it
- Approve / Reject buttons
Timeout: APPROVAL_TIMEOUT_SECONDS (default 300s). If no response, the tool is rejected and the agent continues without it.
Tool Configuration¶
To disable all tools:
TOOLS_ENABLED=false
To allow only specific tools:
ENABLED_TOOLS=http_get,query_prometheus,git_recent_changes
Adding Custom Tools¶
- Create the tool function in
tools.py:
from langchain_core.tools import tool
@tool
def my_custom_check(
endpoint: str,
timeout: int = 10,
) -> str:
"""Run a custom health check on an internal service.
Args:
endpoint: Service URL to check.
timeout: Request timeout in seconds.
"""
import httpx
r = httpx.get(endpoint, timeout=timeout)
return f"Status: {r.status_code}\n{r.text[:2000]}"
- Register it in
get_tools():
def get_tools():
return [
run_ssh_command,
http_get,
# ... existing tools
my_custom_check,
]
- Optionally add to
APPROVAL_REQUIRED_TOOLSif it has side effects.
Monitoring¶
Audit Logs¶
Every tool invocation is logged to DATA_DIR/audit.jsonl:
{
"timestamp": "2024-06-11T14:32:01Z",
"run_id": "abc123",
"agent": "diagnostic_agent",
"tool": "run_ssh_command",
"args": {"host": "prod-01", "command": "df -h"},
"result": "Filesystem Size Used Avail Use%...",
"error": false,
"approval": "approved"
}
Retention: Rotate audit.jsonl with standard logrotate:
# /etc/logrotate.d/agents-discussion
/home/user/.local/share/agents-discussion/runs/audit.jsonl {
daily
rotate 30
compress
delaycompress
missingok
}
Health Checks¶
The web server exposes a basic health endpoint implicitly via FastAPI. For monitoring, check:
GET /api/runs— Returns200if server is responsive- SSE endpoint
/api/runs/{id}/events— Stream connectivity
Log Levels¶
Set LOG_LEVEL environment variable:
LOG_LEVEL=DEBUG agents-discuss-web # Verbose model and tool logging
LOG_LEVEL=WARNING agents-discuss-web # Only warnings and errors
Troubleshooting¶
Common Issues¶
| Symptom | Cause | Fix |
|---|---|---|
ModuleNotFoundError: langchain_core |
Virtualenv not activated | source .venv/bin/activate |
No JSON object found in moderator response |
Moderator model returned malformed JSON | Check model compatibility; fallback path handles this |
| Tool approval timeout | Operator didn't respond | Reduce APPROVAL_TIMEOUT_SECONDS or disable approval |
| SSE stream disconnects | Nginx proxy_read_timeout too low | Set proxy_read_timeout 86400; |
| History compression fails | Summary model unavailable | Set SUMMARY_MODEL to a known working model |
| "name 'history' is not defined" | _last_round_messages bug after graph changes |
Update to latest version where _last_round_messages counts forward |
Diagnostic Steps¶
- Check
.envconfiguration:
cat .env | grep -v "^#" | grep -v "^$"
- Verify token:
# GitHub Models
curl -H "Authorization: Bearer $GITHUB_TOKEN" \
https://models.github.ai/v1/models
# GitHub Copilot
agents-discuss-copilot-auth --verify
- Test with minimal CLI run:
agents-discuss "Test topic" --no-redact-context
- Check audit log for tool failures:
tail -20 ~/.local/share/agents-discussion/runs/audit.jsonl | jq .
Backup & Recovery¶
What to Back Up¶
| Path | Contents | Backup Frequency |
|---|---|---|
DATA_DIR/*.json |
Completed run records | Daily |
DATA_DIR/audit.jsonl |
Tool audit trail | Daily |
~/.local/share/agents-discussion/prompts/ |
Custom templates | After changes |
~/.config/agents-discussion/copilot_token |
Copilot OAuth token | After generation |
Restoration¶
# Restore runs
tar -xzf agents-discussion-backup-20240611.tar.gz -C ~/.local/share/
# Restart web server
agents-discuss-web
Security Hardening¶
Network¶
- Bind web server to
127.0.0.1unless behind a reverse proxy. - Use TLS 1.3 termination at the reverse proxy.
- Restrict SSH keys used by
run_ssh_commandto read-only operations.
Secrets¶
- Never commit
.envfiles to version control (.gitignoreenforced). - Redact secrets from context before sending to models (
--no-redact-contextoverride available). - Rotate
GITHUB_TOKENandCOPILOT_TOKENquarterly.
Tool Safety¶
- Always require approval for destructive tools (
run_local_command,run_ssh_command). - Use read-only database URLs for
run_db_explain. - Run with
ENABLED_TOOLSlimited to the minimum necessary set.
Container Security¶
# Dockerfile best practices
USER appuser # Don't run as root
EXPOSE 8000
# No secrets in image layers
Maintenance¶
Regular Tasks¶
| Frequency | Task | Command |
|---|---|---|
| Weekly | Rotate audit log | logrotate |
| Monthly | Clean old interrupted runs | find DATA_DIR -name "*.json" -mtime +30 -delete |
| Quarterly | Update model versions | Edit .env, test, restart |
| Quarterly | Review custom templates | Check PROMPTS_DIR for drift |
| On demand | Re-index orphaned runs | Restart web server (triggers _mark_orphans()) |
Upgrading¶
# Pull latest code
git pull origin main
# Reinstall dependencies
pip install -e .
# Restart services
pkill -f "agents-discuss-web"
agents-discuss-web
Capacity Planning¶
| Resource | Baseline | Scaling Trigger |
|---|---|---|
| Disk | 1 GB / 1000 runs | Clean old runs |
| Memory | 150 MB per concurrent run | Increase comment_timeout to reduce concurrent |
| LLM tokens | ~50K tokens / round | Enable compression, lower MAX_ROUNDS |
| Network | Minimal (SSE streams) | Nginx worker processes |