Add autonomous agent framework and prompt library

- Self-healing, self-monitoring, self-optimizing agent framework
- Prompt library with reusable templates for agent interactions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Alexa Amundson
2026-02-20 20:23:46 -06:00
parent cc1afffaa2
commit b29b095f99
2 changed files with 1142 additions and 0 deletions

View File

@@ -0,0 +1,700 @@
#!/bin/bash
# BlackRoad Memory Autonomous Agents
# Self-healing, self-monitoring, self-optimizing agents
MEMORY_DIR="$HOME/.blackroad/memory"
AGENTS_DIR="$MEMORY_DIR/agents"
AGENTS_DB="$AGENTS_DIR/agents.db"
# Colors
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
CYAN='\033[0;36m'
PURPLE='\033[0;35m'
BLUE='\033[0;34m'
NC='\033[0m'
init() {
echo -e "${PURPLE}╔════════════════════════════════════════════════╗${NC}"
echo -e "${PURPLE}║ 🤖 Autonomous Agent System ║${NC}"
echo -e "${PURPLE}╚════════════════════════════════════════════════╝${NC}\n"
mkdir -p "$AGENTS_DIR/logs"
# Create agents database
sqlite3 "$AGENTS_DB" <<'SQL'
-- Autonomous agents
CREATE TABLE IF NOT EXISTS agents (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT UNIQUE NOT NULL,
type TEXT NOT NULL, -- 'monitor', 'healer', 'optimizer', 'predictor'
status TEXT DEFAULT 'idle', -- 'idle', 'running', 'paused', 'error'
config TEXT, -- JSON configuration
created_at INTEGER NOT NULL,
started_at INTEGER,
last_action INTEGER,
actions_taken INTEGER DEFAULT 0,
success_count INTEGER DEFAULT 0,
failure_count INTEGER DEFAULT 0
);
-- Agent actions log
CREATE TABLE IF NOT EXISTS agent_actions (
id INTEGER PRIMARY KEY AUTOINCREMENT,
agent_id INTEGER NOT NULL,
action_type TEXT NOT NULL,
target TEXT,
details TEXT,
success INTEGER,
duration INTEGER, -- milliseconds
timestamp INTEGER NOT NULL,
FOREIGN KEY (agent_id) REFERENCES agents(id)
);
-- Agent insights
CREATE TABLE IF NOT EXISTS agent_insights (
id INTEGER PRIMARY KEY AUTOINCREMENT,
agent_id INTEGER NOT NULL,
insight_type TEXT NOT NULL, -- 'anomaly', 'pattern', 'recommendation', 'prediction'
insight_data TEXT NOT NULL, -- JSON data
confidence REAL,
timestamp INTEGER NOT NULL,
acted_upon INTEGER DEFAULT 0,
FOREIGN KEY (agent_id) REFERENCES agents(id)
);
-- Agent communication (inter-agent messaging)
CREATE TABLE IF NOT EXISTS agent_messages (
id INTEGER PRIMARY KEY AUTOINCREMENT,
from_agent_id INTEGER NOT NULL,
to_agent_id INTEGER, -- NULL for broadcast
message_type TEXT NOT NULL,
message TEXT NOT NULL,
timestamp INTEGER NOT NULL,
read INTEGER DEFAULT 0,
FOREIGN KEY (from_agent_id) REFERENCES agents(id),
FOREIGN KEY (to_agent_id) REFERENCES agents(id)
);
-- Create indexes
CREATE INDEX IF NOT EXISTS idx_agent_actions_agent ON agent_actions(agent_id);
CREATE INDEX IF NOT EXISTS idx_agent_actions_timestamp ON agent_actions(timestamp);
CREATE INDEX IF NOT EXISTS idx_agent_insights_agent ON agent_insights(agent_id);
CREATE INDEX IF NOT EXISTS idx_agent_insights_timestamp ON agent_insights(timestamp);
CREATE INDEX IF NOT EXISTS idx_agent_messages_to ON agent_messages(to_agent_id);
CREATE INDEX IF NOT EXISTS idx_agent_messages_read ON agent_messages(read);
SQL
# Create default agents
local timestamp=$(date +%s)
sqlite3 "$AGENTS_DB" <<SQL
INSERT OR IGNORE INTO agents (name, type, config, created_at)
VALUES
('Guardian', 'monitor', '{"check_interval":60,"alert_threshold":"high"}', $timestamp),
('Healer', 'healer', '{"auto_heal":true,"max_attempts":3}', $timestamp),
('Optimizer', 'optimizer', '{"optimize_interval":3600,"targets":["indexes","performance"]}', $timestamp),
('Prophet', 'predictor', '{"prediction_interval":300,"confidence_threshold":0.7}', $timestamp),
('Scout', 'monitor', '{"watch":["journal","api","stream"],"report_interval":300}', $timestamp);
SQL
echo -e "${GREEN}${NC} Autonomous agent system initialized"
echo -e "${CYAN}Created 5 default agents:${NC}"
echo -e " 🛡️ ${PURPLE}Guardian${NC} - System health monitor"
echo -e " 🏥 ${PURPLE}Healer${NC} - Auto-healing agent"
echo -e "${PURPLE}Optimizer${NC} - Performance optimizer"
echo -e " 🔮 ${PURPLE}Prophet${NC} - Predictive agent"
echo -e " 🔍 ${PURPLE}Scout${NC} - Activity scout"
}
# Get agent ID by name
get_agent_id() {
local name="$1"
sqlite3 "$AGENTS_DB" "SELECT id FROM agents WHERE name = '$name'"
}
# Log agent action
log_action() {
local agent_name="$1"
local action_type="$2"
local target="$3"
local details="$4"
local success="$5"
local duration="${6:-0}"
local agent_id=$(get_agent_id "$agent_name")
local timestamp=$(date +%s)
sqlite3 "$AGENTS_DB" <<SQL
INSERT INTO agent_actions (agent_id, action_type, target, details, success, duration, timestamp)
VALUES ($agent_id, '$action_type', '$target', '$details', $success, $duration, $timestamp);
UPDATE agents SET
last_action = $timestamp,
actions_taken = actions_taken + 1,
success_count = success_count + $success,
failure_count = failure_count + $([ "$success" -eq 0 ] && echo 1 || echo 0)
WHERE id = $agent_id;
SQL
}
# Record agent insight
record_insight() {
local agent_name="$1"
local insight_type="$2"
local insight_data="$3"
local confidence="$4"
local agent_id=$(get_agent_id "$agent_name")
local timestamp=$(date +%s)
sqlite3 "$AGENTS_DB" <<SQL
INSERT INTO agent_insights (agent_id, insight_type, insight_data, confidence, timestamp)
VALUES ($agent_id, '$insight_type', '$(echo "$insight_data" | sed "s/'/''/g")', $confidence, $timestamp);
SQL
}
# Send agent message
send_message() {
local from_agent="$1"
local to_agent="$2" # "broadcast" for all agents
local message_type="$3"
local message="$4"
local from_id=$(get_agent_id "$from_agent")
local to_id=""
if [ "$to_agent" != "broadcast" ]; then
to_id=$(get_agent_id "$to_agent")
fi
local timestamp=$(date +%s)
sqlite3 "$AGENTS_DB" <<SQL
INSERT INTO agent_messages (from_agent_id, to_agent_id, message_type, message, timestamp)
VALUES ($from_id, $([ -z "$to_id" ] && echo "NULL" || echo "$to_id"), '$message_type', '$message', $timestamp);
SQL
}
# Read agent messages
read_messages() {
local agent_name="$1"
local agent_id=$(get_agent_id "$agent_name")
sqlite3 "$AGENTS_DB" <<SQL
SELECT
(SELECT name FROM agents WHERE id = from_agent_id) as from_agent,
message_type,
message,
datetime(timestamp, 'unixepoch', 'localtime') as received
FROM agent_messages
WHERE (to_agent_id = $agent_id OR to_agent_id IS NULL) AND read = 0
ORDER BY timestamp DESC;
SQL
# Mark as read
sqlite3 "$AGENTS_DB" <<SQL
UPDATE agent_messages SET read = 1 WHERE to_agent_id = $agent_id OR to_agent_id IS NULL;
SQL
}
# AGENT: Guardian (Monitor)
run_guardian() {
local agent="Guardian"
local timestamp=$(date +%s)
echo -e "${CYAN}🛡️ Guardian Agent: Starting health monitoring...${NC}"
sqlite3 "$AGENTS_DB" "UPDATE agents SET status = 'running', started_at = $timestamp WHERE name = '$agent'"
local iteration=0
while true; do
iteration=$((iteration + 1))
local start_time=$(date +%s%3N)
echo -e "\n${PURPLE}[Guardian] Iteration $iteration - $(date '+%H:%M:%S')${NC}"
# Check memory system health
local journal_size=$(wc -l < "$MEMORY_DIR/journals/master-journal.jsonl" 2>/dev/null || echo 0)
if [ "$journal_size" -gt 0 ]; then
echo -e "${GREEN}${NC} Memory journal: $journal_size entries"
log_action "$agent" "health_check" "memory_journal" "Healthy: $journal_size entries" 1 0
else
echo -e "${RED}${NC} Memory journal: Empty or missing"
log_action "$agent" "health_check" "memory_journal" "Error: Empty or missing" 0 0
send_message "$agent" "Healer" "alert" "Memory journal is empty or missing"
fi
# Check indexes
if [ -f "$MEMORY_DIR/indexes/indexes.db" ]; then
local indexed=$(sqlite3 "$MEMORY_DIR/indexes/indexes.db" "SELECT COUNT(*) FROM action_index" 2>/dev/null || echo 0)
echo -e "${GREEN}${NC} Indexes: $indexed actions indexed"
log_action "$agent" "health_check" "indexes" "Healthy: $indexed actions" 1 0
# Detect if indexes are out of sync
local diff=$((journal_size - indexed))
if [ "$diff" -gt 100 ]; then
echo -e "${YELLOW}⚠️${NC} Indexes out of sync: $diff entries behind"
record_insight "$agent" "anomaly" "{\"type\":\"index_lag\",\"entries_behind\":$diff}" 0.9
send_message "$agent" "Optimizer" "suggestion" "Indexes need rebuilding: $diff entries behind"
fi
else
echo -e "${RED}${NC} Indexes: Database missing"
log_action "$agent" "health_check" "indexes" "Error: Database missing" 0 0
send_message "$agent" "Healer" "alert" "Index database is missing"
fi
# Check codex
if [ -f "$MEMORY_DIR/codex/codex.db" ]; then
local solutions=$(sqlite3 "$MEMORY_DIR/codex/codex.db" "SELECT COUNT(*) FROM solutions" 2>/dev/null || echo 0)
echo -e "${GREEN}${NC} Codex: $solutions solutions"
log_action "$agent" "health_check" "codex" "Healthy: $solutions solutions" 1 0
else
echo -e "${YELLOW}⚠️${NC} Codex: Database missing"
log_action "$agent" "health_check" "codex" "Warning: Database missing" 0 0
fi
# Check disk space
local disk_usage=$(df -h "$MEMORY_DIR" | tail -1 | awk '{print $5}' | tr -d '%')
if [ "$disk_usage" -gt 90 ]; then
echo -e "${RED}${NC} Disk space: ${disk_usage}% used (CRITICAL)"
log_action "$agent" "health_check" "disk_space" "Critical: ${disk_usage}% used" 0 0
send_message "$agent" "Healer" "alert" "Disk space critical: ${disk_usage}% used"
elif [ "$disk_usage" -gt 75 ]; then
echo -e "${YELLOW}⚠️${NC} Disk space: ${disk_usage}% used (Warning)"
log_action "$agent" "health_check" "disk_space" "Warning: ${disk_usage}% used" 1 0
else
echo -e "${GREEN}${NC} Disk space: ${disk_usage}% used"
log_action "$agent" "health_check" "disk_space" "Healthy: ${disk_usage}% used" 1 0
fi
# Check for stuck processes
local stuck=$(ps aux | grep -c "sqlite3.*memory" | grep -v grep)
if [ "$stuck" -gt 5 ]; then
echo -e "${RED}${NC} Processes: $stuck sqlite processes (possible lock)"
log_action "$agent" "health_check" "processes" "Warning: $stuck processes" 0 0
send_message "$agent" "Healer" "alert" "Possible database lock: $stuck sqlite processes"
fi
# Check messages from other agents
local messages=$(sqlite3 "$AGENTS_DB" "SELECT COUNT(*) FROM agent_messages WHERE to_agent_id = $(get_agent_id "$agent") AND read = 0")
if [ "$messages" -gt 0 ]; then
echo -e "${CYAN}📬 $messages new messages${NC}"
fi
local end_time=$(date +%s%3N)
local duration=$((end_time - start_time))
echo -e "${CYAN}Duration: ${duration}ms${NC}"
# Sleep 60 seconds
sleep 60
done
}
# AGENT: Healer (Auto-healing)
run_healer() {
local agent="Healer"
local timestamp=$(date +%s)
echo -e "${CYAN}🏥 Healer Agent: Starting auto-healing service...${NC}"
sqlite3 "$AGENTS_DB" "UPDATE agents SET status = 'running', started_at = $timestamp WHERE name = '$agent'"
while true; do
# Check for alerts from Guardian
local alerts=$(sqlite3 "$AGENTS_DB" "SELECT COUNT(*) FROM agent_messages WHERE to_agent_id = $(get_agent_id "$agent") AND read = 0 AND message_type = 'alert'")
if [ "$alerts" -gt 0 ]; then
echo -e "\n${YELLOW}🚨 $alerts alerts received from Guardian${NC}"
# Read and process alerts
sqlite3 "$AGENTS_DB" "SELECT message FROM agent_messages WHERE to_agent_id = $(get_agent_id "$agent") AND read = 0 AND message_type = 'alert'" | \
while IFS= read -r alert; do
echo -e "${CYAN}Processing: $alert${NC}"
local start_time=$(date +%s%3N)
# Determine healing action
if echo "$alert" | grep -qi "journal.*empty"; then
echo -e "${YELLOW}🔧 Attempting to restore journal...${NC}"
# Try to restore from backup
if [ -f "$MEMORY_DIR/journals/master-journal.jsonl.bak" ]; then
cp "$MEMORY_DIR/journals/master-journal.jsonl.bak" "$MEMORY_DIR/journals/master-journal.jsonl"
echo -e "${GREEN}${NC} Journal restored from backup"
log_action "$agent" "heal" "memory_journal" "Restored from backup" 1 0
send_message "$agent" "Guardian" "success" "Journal restored successfully"
else
echo -e "${RED}${NC} No backup available"
log_action "$agent" "heal" "memory_journal" "Failed: No backup" 0 0
fi
elif echo "$alert" | grep -qi "index.*missing"; then
echo -e "${YELLOW}🔧 Rebuilding indexes...${NC}"
~/memory-indexer.sh rebuild >/dev/null 2>&1
if [ $? -eq 0 ]; then
echo -e "${GREEN}${NC} Indexes rebuilt"
log_action "$agent" "heal" "indexes" "Rebuilt successfully" 1 0
send_message "$agent" "Guardian" "success" "Indexes rebuilt successfully"
else
echo -e "${RED}${NC} Rebuild failed"
log_action "$agent" "heal" "indexes" "Rebuild failed" 0 0
fi
elif echo "$alert" | grep -qi "disk.*critical"; then
echo -e "${YELLOW}🔧 Cleaning up old data...${NC}"
# Clean old stream events
sqlite3 "$MEMORY_DIR/stream/stream.db" "DELETE FROM stream_events WHERE timestamp < strftime('%s', 'now', '-7 days')" 2>/dev/null
# Clean old API logs
sqlite3 "$MEMORY_DIR/api/api.db" "DELETE FROM api_requests WHERE timestamp < strftime('%s', 'now', '-30 days')" 2>/dev/null
echo -e "${GREEN}${NC} Old data cleaned"
log_action "$agent" "heal" "disk_space" "Cleaned old data" 1 0
send_message "$agent" "Guardian" "success" "Disk space cleaned"
elif echo "$alert" | grep -qi "database lock"; then
echo -e "${YELLOW}🔧 Clearing stuck processes...${NC}"
pkill -f "sqlite3.*memory" 2>/dev/null
sleep 1
echo -e "${GREEN}${NC} Processes cleared"
log_action "$agent" "heal" "processes" "Cleared stuck processes" 1 0
send_message "$agent" "Guardian" "success" "Database locks cleared"
fi
local end_time=$(date +%s%3N)
local duration=$((end_time - start_time))
echo -e "${CYAN}Healing duration: ${duration}ms${NC}"
done
# Mark alerts as read
sqlite3 "$AGENTS_DB" "UPDATE agent_messages SET read = 1 WHERE to_agent_id = $(get_agent_id "$agent") AND message_type = 'alert'"
fi
# Sleep 10 seconds
sleep 10
done
}
# AGENT: Optimizer (Performance)
run_optimizer() {
local agent="Optimizer"
local timestamp=$(date +%s)
echo -e "${CYAN}⚡ Optimizer Agent: Starting optimization service...${NC}"
sqlite3 "$AGENTS_DB" "UPDATE agents SET status = 'running', started_at = $timestamp WHERE name = '$agent'"
while true; do
echo -e "\n${PURPLE}[Optimizer] Running optimization cycle - $(date '+%H:%M:%S')${NC}"
local start_time=$(date +%s%3N)
# Optimize indexes
echo -e "${CYAN}🔧 Optimizing indexes...${NC}"
sqlite3 "$MEMORY_DIR/indexes/indexes.db" "VACUUM; ANALYZE;" 2>/dev/null
echo -e "${GREEN}${NC} Indexes optimized"
log_action "$agent" "optimize" "indexes" "Optimized" 1 0
# Optimize codex
echo -e "${CYAN}🔧 Optimizing codex...${NC}"
sqlite3 "$MEMORY_DIR/codex/codex.db" "VACUUM; ANALYZE;" 2>/dev/null
echo -e "${GREEN}${NC} Codex optimized"
log_action "$agent" "optimize" "codex" "Optimized" 1 0
# Optimize agent database
echo -e "${CYAN}🔧 Optimizing agent database...${NC}"
sqlite3 "$AGENTS_DB" "VACUUM; ANALYZE;" 2>/dev/null
echo -e "${GREEN}${NC} Agent database optimized"
log_action "$agent" "optimize" "agents_db" "Optimized" 1 0
# Check for suggestions from Guardian
local suggestions=$(sqlite3 "$AGENTS_DB" "SELECT COUNT(*) FROM agent_messages WHERE to_agent_id = $(get_agent_id "$agent") AND read = 0 AND message_type = 'suggestion'")
if [ "$suggestions" -gt 0 ]; then
echo -e "${CYAN}💡 $suggestions optimization suggestions received${NC}"
sqlite3 "$AGENTS_DB" "SELECT message FROM agent_messages WHERE to_agent_id = $(get_agent_id "$agent") AND read = 0 AND message_type = 'suggestion'" | \
while IFS= read -r suggestion; do
echo -e "${YELLOW}Processing: $suggestion${NC}"
if echo "$suggestion" | grep -qi "indexes.*rebuild"; then
echo -e "${CYAN}🔧 Rebuilding indexes as suggested...${NC}"
~/memory-indexer.sh rebuild >/dev/null 2>&1
echo -e "${GREEN}${NC} Indexes rebuilt"
log_action "$agent" "optimize" "indexes" "Rebuilt from suggestion" 1 0
fi
done
sqlite3 "$AGENTS_DB" "UPDATE agent_messages SET read = 1 WHERE to_agent_id = $(get_agent_id "$agent") AND message_type = 'suggestion'"
fi
local end_time=$(date +%s%3N)
local duration=$((end_time - start_time))
echo -e "${CYAN}Optimization cycle completed in ${duration}ms${NC}"
# Sleep 1 hour
sleep 3600
done
}
# AGENT: Prophet (Predictor)
run_prophet() {
local agent="Prophet"
local timestamp=$(date +%s)
echo -e "${CYAN}🔮 Prophet Agent: Starting prediction service...${NC}"
sqlite3 "$AGENTS_DB" "UPDATE agents SET status = 'running', started_at = $timestamp WHERE name = '$agent'"
while true; do
echo -e "\n${PURPLE}[Prophet] Running prediction cycle - $(date '+%H:%M:%S')${NC}"
# Detect anomalies
echo -e "${CYAN}🔍 Detecting anomalies...${NC}"
local anomalies=$(~/memory-predictor.sh anomalies 2>/dev/null | tail -n +2)
if [ -n "$anomalies" ]; then
echo -e "${YELLOW}⚠️ Anomalies detected:${NC}"
echo "$anomalies"
# Record insights
local anomaly_count=$(echo "$anomalies" | wc -l)
record_insight "$agent" "anomaly" "{\"count\":$anomaly_count,\"details\":\"$(echo "$anomalies" | tr '\n' ' ')\"}" 0.85
# Alert Guardian
send_message "$agent" "Guardian" "info" "Detected $anomaly_count anomalies in recent activity"
fi
# Forecast activity
echo -e "${CYAN}📊 Forecasting activity...${NC}"
~/memory-predictor.sh forecast 7 2>/dev/null | tail -5
# Make predictions for high-risk entities
local high_risk=$(sqlite3 "$MEMORY_DIR/indexes/indexes.db" "SELECT DISTINCT entity FROM action_index WHERE action = 'failed' ORDER BY timestamp DESC LIMIT 5" 2>/dev/null)
if [ -n "$high_risk" ]; then
echo -e "${YELLOW}🎯 Analyzing high-risk entities...${NC}"
echo "$high_risk" | while IFS= read -r entity; do
local prediction=$(~/memory-predictor.sh predict "$entity" 2>/dev/null)
echo -e " ${CYAN}$entity:${NC} $prediction"
if echo "$prediction" | grep -qi "LOW"; then
# Low success probability - send recommendation
record_insight "$agent" "prediction" "{\"entity\":\"$entity\",\"prediction\":\"low_success\"}" 0.8
send_message "$agent" "broadcast" "warning" "Entity $entity has low predicted success rate"
fi
done
fi
# Sleep 5 minutes
sleep 300
done
}
# List all agents
list_agents() {
echo -e "${PURPLE}╔════════════════════════════════════════════════╗${NC}"
echo -e "${PURPLE}║ Autonomous Agents ║${NC}"
echo -e "${PURPLE}╚════════════════════════════════════════════════╝${NC}\n"
sqlite3 -header -column "$AGENTS_DB" <<SQL
SELECT
name,
type,
status,
actions_taken,
success_count,
failure_count,
ROUND(100.0 * success_count / NULLIF(actions_taken, 0), 1) as success_rate
FROM agents
ORDER BY name;
SQL
}
# Show agent statistics
show_agent_stats() {
local agent_name="$1"
if [ -z "$agent_name" ]; then
echo -e "${RED}Error: Agent name required${NC}"
return 1
fi
local agent_id=$(get_agent_id "$agent_name")
if [ -z "$agent_id" ]; then
echo -e "${RED}Error: Agent not found: $agent_name${NC}"
return 1
fi
echo -e "${PURPLE}╔════════════════════════════════════════════════╗${NC}"
echo -e "${PURPLE}║ Agent: $agent_name${NC}"
echo -e "${PURPLE}╚════════════════════════════════════════════════╝${NC}\n"
# Basic stats
sqlite3 -header -column "$AGENTS_DB" <<SQL
SELECT
type,
status,
actions_taken,
success_count,
failure_count,
ROUND(100.0 * success_count / NULLIF(actions_taken, 0), 1) as success_rate,
datetime(created_at, 'unixepoch', 'localtime') as created,
datetime(started_at, 'unixepoch', 'localtime') as started,
datetime(last_action, 'unixepoch', 'localtime') as last_action
FROM agents
WHERE id = $agent_id;
SQL
# Recent actions
echo -e "\n${PURPLE}Recent Actions:${NC}"
sqlite3 -header -column "$AGENTS_DB" <<SQL
SELECT
action_type,
target,
CASE WHEN success = 1 THEN '✓' ELSE '✗' END as result,
duration || 'ms' as duration,
datetime(timestamp, 'unixepoch', 'localtime') as time
FROM agent_actions
WHERE agent_id = $agent_id
ORDER BY timestamp DESC
LIMIT 10;
SQL
# Insights
echo -e "\n${PURPLE}Recent Insights:${NC}"
sqlite3 -header -column "$AGENTS_DB" <<SQL
SELECT
insight_type,
SUBSTR(insight_data, 1, 50) as insight,
ROUND(confidence * 100, 1) || '%' as confidence,
datetime(timestamp, 'unixepoch', 'localtime') as time
FROM agent_insights
WHERE agent_id = $agent_id
ORDER BY timestamp DESC
LIMIT 5;
SQL
}
# Start all agents
start_all_agents() {
echo -e "${PURPLE}╔════════════════════════════════════════════════╗${NC}"
echo -e "${PURPLE}║ 🚀 Starting All Autonomous Agents ║${NC}"
echo -e "${PURPLE}╚════════════════════════════════════════════════╝${NC}\n"
# Start each agent in background
run_guardian >> "$AGENTS_DIR/logs/guardian.log" 2>&1 &
echo $! > "$AGENTS_DIR/guardian.pid"
echo -e "${GREEN}${NC} Guardian started (PID: $!)"
run_healer >> "$AGENTS_DIR/logs/healer.log" 2>&1 &
echo $! > "$AGENTS_DIR/healer.pid"
echo -e "${GREEN}${NC} Healer started (PID: $!)"
run_optimizer >> "$AGENTS_DIR/logs/optimizer.log" 2>&1 &
echo $! > "$AGENTS_DIR/optimizer.pid"
echo -e "${GREEN}${NC} Optimizer started (PID: $!)"
run_prophet >> "$AGENTS_DIR/logs/prophet.log" 2>&1 &
echo $! > "$AGENTS_DIR/prophet.pid"
echo -e "${GREEN}${NC} Prophet started (PID: $!)"
echo -e "\n${GREEN}🤖 All autonomous agents running!${NC}"
echo -e "\n${CYAN}Logs:${NC}"
echo -e " Guardian: tail -f $AGENTS_DIR/logs/guardian.log"
echo -e " Healer: tail -f $AGENTS_DIR/logs/healer.log"
echo -e " Optimizer: tail -f $AGENTS_DIR/logs/optimizer.log"
echo -e " Prophet: tail -f $AGENTS_DIR/logs/prophet.log"
}
# Stop all agents
stop_all_agents() {
echo -e "${YELLOW}🛑 Stopping all autonomous agents...${NC}"
for agent in guardian healer optimizer prophet; do
local pid_file="$AGENTS_DIR/$agent.pid"
if [ -f "$pid_file" ]; then
local pid=$(cat "$pid_file")
kill "$pid" 2>/dev/null && echo -e "${GREEN}${NC} ${agent^} stopped"
rm "$pid_file"
# Update status
sqlite3 "$AGENTS_DB" "UPDATE agents SET status = 'idle' WHERE name = '${agent^}'"
fi
done
echo -e "${GREEN}${NC} All agents stopped"
}
# Main execution
case "${1:-help}" in
init)
init
;;
start)
start_all_agents
;;
stop)
stop_all_agents
;;
list)
list_agents
;;
stats)
show_agent_stats "$2"
;;
guardian)
run_guardian
;;
healer)
run_healer
;;
optimizer)
run_optimizer
;;
prophet)
run_prophet
;;
help|*)
echo -e "${PURPLE}╔════════════════════════════════════════════════╗${NC}"
echo -e "${PURPLE}║ 🤖 Autonomous Agent System ║${NC}"
echo -e "${PURPLE}╚════════════════════════════════════════════════╝${NC}\n"
echo "Self-healing, self-monitoring AI agents"
echo ""
echo "Usage: $0 COMMAND [OPTIONS]"
echo ""
echo "Setup:"
echo " init - Initialize agent system"
echo ""
echo "Control:"
echo " start - Start all agents"
echo " stop - Stop all agents"
echo ""
echo "Individual Agents:"
echo " guardian - Run Guardian (monitor)"
echo " healer - Run Healer (auto-heal)"
echo " optimizer - Run Optimizer (performance)"
echo " prophet - Run Prophet (predictions)"
echo ""
echo "Monitoring:"
echo " list - List all agents"
echo " stats AGENT - Show agent statistics"
echo ""
echo "Examples:"
echo " $0 init"
echo " $0 start"
echo " $0 stats Guardian"
echo " $0 list"
echo ""
echo "Agents:"
echo " 🛡️ Guardian - Monitors system health"
echo " 🏥 Healer - Auto-heals detected issues"
echo " ⚡ Optimizer - Optimizes performance"
echo " 🔮 Prophet - Predicts and prevents issues"
;;
esac

442
scripts/prompt-library.sh Normal file
View File

@@ -0,0 +1,442 @@
#!/bin/bash
# BlackRoad Prompt Library
# Curated collection of AI prompts for the cluster
# Agent: Icarus (b3e01bd9)
PINK='\033[38;5;205m'
GREEN='\033[0;32m'
BLUE='\033[0;34m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
RESET='\033[0m'
PROMPTS_DIR="$HOME/.blackroad/prompts"
PROMPTS_DB="$PROMPTS_DIR/prompts.db"
# Initialize
init() {
mkdir -p "$PROMPTS_DIR"/{templates,chains,personas}
sqlite3 "$PROMPTS_DB" << 'SQL'
CREATE TABLE IF NOT EXISTS prompts (
id TEXT PRIMARY KEY,
name TEXT,
category TEXT,
description TEXT,
template TEXT,
variables TEXT,
model TEXT DEFAULT 'llama3.2:1b',
usage_count INTEGER DEFAULT 0,
rating REAL DEFAULT 0,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS chains (
id TEXT PRIMARY KEY,
name TEXT,
description TEXT,
steps TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS personas (
id TEXT PRIMARY KEY,
name TEXT,
system_prompt TEXT,
traits TEXT,
model TEXT DEFAULT 'llama3.2:1b'
);
SQL
# Seed with built-in prompts
seed_prompts
echo -e "${GREEN}Prompt library initialized${RESET}"
}
# Seed built-in prompts
seed_prompts() {
# Check if already seeded
local count=$(sqlite3 "$PROMPTS_DB" "SELECT COUNT(*) FROM prompts")
[ "$count" -gt 0 ] && return
# Analysis prompts
sqlite3 "$PROMPTS_DB" "INSERT OR IGNORE INTO prompts (id, name, category, description, template, variables, model) VALUES
('analyze-sentiment', 'Sentiment Analysis', 'analysis', 'Analyze text sentiment', 'Analyze the sentiment of this text and classify as positive, negative, or neutral. Explain why.\n\nText: {{TEXT}}', 'TEXT', 'llama3.2:1b'),
('summarize', 'Summarize Text', 'analysis', 'Create concise summary', 'Summarize the following text in 2-3 sentences, capturing the main points:\n\n{{TEXT}}', 'TEXT', 'llama3.2:1b'),
('extract-keywords', 'Extract Keywords', 'analysis', 'Extract key terms', 'Extract the 5 most important keywords from this text:\n\n{{TEXT}}', 'TEXT', 'llama3.2:1b'),
('explain-simple', 'Explain Simply', 'analysis', 'Explain for beginners', 'Explain {{TOPIC}} as if you were explaining it to a 10-year-old. Use simple language and examples.', 'TOPIC', 'llama3.2:1b')
"
# Coding prompts
sqlite3 "$PROMPTS_DB" "INSERT OR IGNORE INTO prompts (id, name, category, description, template, variables, model) VALUES
('code-review', 'Code Review', 'coding', 'Review code quality', 'Review this code for bugs, security issues, and improvements:\n\n\`\`\`{{LANGUAGE}}\n{{CODE}}\n\`\`\`', 'LANGUAGE,CODE', 'codellama:7b'),
('code-explain', 'Explain Code', 'coding', 'Explain what code does', 'Explain what this code does line by line:\n\n\`\`\`{{LANGUAGE}}\n{{CODE}}\n\`\`\`', 'LANGUAGE,CODE', 'codellama:7b'),
('code-convert', 'Convert Code', 'coding', 'Convert between languages', 'Convert this {{FROM}} code to {{TO}}:\n\n\`\`\`{{FROM}}\n{{CODE}}\n\`\`\`', 'FROM,TO,CODE', 'codellama:7b'),
('code-fix', 'Fix Bug', 'coding', 'Fix code bug', 'This code has a bug. Fix it and explain what was wrong:\n\n\`\`\`{{LANGUAGE}}\n{{CODE}}\n\`\`\`\n\nError: {{ERROR}}', 'LANGUAGE,CODE,ERROR', 'codellama:7b')
"
# Creative prompts
sqlite3 "$PROMPTS_DB" "INSERT OR IGNORE INTO prompts (id, name, category, description, template, variables, model) VALUES
('brainstorm', 'Brainstorm Ideas', 'creative', 'Generate ideas', 'Brainstorm 5 creative ideas for: {{TOPIC}}', 'TOPIC', 'llama3.2:1b'),
('write-email', 'Write Email', 'creative', 'Draft professional email', 'Write a professional email about {{SUBJECT}} to {{RECIPIENT}}. Tone: {{TONE}}', 'SUBJECT,RECIPIENT,TONE', 'llama3.2:1b'),
('storytelling', 'Tell Story', 'creative', 'Create short story', 'Write a short story (100 words) about {{TOPIC}} in the style of {{STYLE}}', 'TOPIC,STYLE', 'llama3.2:1b')
"
# System prompts
sqlite3 "$PROMPTS_DB" "INSERT OR IGNORE INTO prompts (id, name, category, description, template, variables, model) VALUES
('sysadmin', 'Sysadmin Help', 'system', 'Linux administration help', 'You are a Linux sysadmin expert. Help with: {{QUESTION}}', 'QUESTION', 'llama3.2:1b'),
('docker-help', 'Docker Help', 'system', 'Docker container help', 'You are a Docker expert. Help with: {{QUESTION}}\n\nContext: {{CONTEXT}}', 'QUESTION,CONTEXT', 'llama3.2:1b')
"
# Seed personas
sqlite3 "$PROMPTS_DB" "INSERT OR IGNORE INTO personas (id, name, system_prompt, traits, model) VALUES
('lucidia', 'Lucidia', 'You are Lucidia, a helpful AI assistant created by BlackRoad OS. You are friendly, knowledgeable, and slightly playful. You run on a distributed Raspberry Pi cluster.', 'helpful,friendly,playful,technical', 'llama3.2:1b'),
('coder', 'CodeBot', 'You are an expert programmer. You write clean, efficient, well-documented code. Always explain your solutions.', 'precise,technical,educational', 'codellama:7b'),
('analyst', 'Analyst', 'You are a data analyst. You break down complex problems, identify patterns, and provide actionable insights.', 'analytical,thorough,objective', 'llama3.2:3b'),
('creative', 'Creative', 'You are a creative thinker. You generate novel ideas and think outside the box. Be imaginative and unconventional.', 'creative,innovative,playful', 'llama3.2:1b')
"
}
# Add a prompt
add() {
local name="$1"
local category="$2"
local template="$3"
local description="${4:-}"
local variables="${5:-}"
local model="${6:-llama3.2:1b}"
local id=$(echo "$name" | tr '[:upper:]' '[:lower:]' | tr ' ' '-')
sqlite3 "$PROMPTS_DB" "
INSERT OR REPLACE INTO prompts (id, name, category, description, template, variables, model)
VALUES ('$id', '$name', '$category', '$description', '$(echo "$template" | sed "s/'/''/g")', '$variables', '$model')
"
echo -e "${GREEN}Added prompt: $id${RESET}"
}
# Get and use a prompt
use() {
local prompt_id="$1"
shift
local prompt=$(sqlite3 "$PROMPTS_DB" "
SELECT template, variables, model FROM prompts WHERE id = '$prompt_id'
")
if [ -z "$prompt" ]; then
echo -e "${RED}Prompt not found: $prompt_id${RESET}"
return 1
fi
local template=$(echo "$prompt" | cut -d'|' -f1)
local variables=$(echo "$prompt" | cut -d'|' -f2)
local model=$(echo "$prompt" | cut -d'|' -f3)
# Replace variables
local filled="$template"
for var in "$@"; do
local key="${var%%=*}"
local value="${var#*=}"
filled=$(echo "$filled" | sed "s/{{$key}}/$value/g")
done
# Check for unfilled variables
if echo "$filled" | grep -q '{{'; then
echo -e "${YELLOW}Missing variables in prompt${RESET}"
echo "Required: $variables"
return 1
fi
# Update usage count
sqlite3 "$PROMPTS_DB" "UPDATE prompts SET usage_count = usage_count + 1 WHERE id = '$prompt_id'"
echo -e "${BLUE}Using prompt: $prompt_id (model: $model)${RESET}"
echo
echo "$filled"
}
# Run prompt against LLM
run() {
local prompt_id="$1"
shift
local node="${RUN_NODE:-cecilia}"
local filled=$(use "$prompt_id" "$@")
local model=$(sqlite3 "$PROMPTS_DB" "SELECT model FROM prompts WHERE id = '$prompt_id'")
echo -e "${PINK}=== RUNNING PROMPT ===${RESET}"
echo
ssh -o ConnectTimeout=30 "$node" \
"curl -s http://localhost:11434/api/generate -d '{\"model\":\"$model\",\"prompt\":\"$filled\",\"stream\":false}'" 2>/dev/null \
| jq -r '.response // "No response"'
}
# List prompts
list() {
local category="${1:-all}"
echo -e "${PINK}=== PROMPT LIBRARY ===${RESET}"
echo
local where=""
[ "$category" != "all" ] && where="WHERE category = '$category'"
sqlite3 "$PROMPTS_DB" "
SELECT id, name, category, usage_count FROM prompts $where ORDER BY category, name
" | while IFS='|' read -r id name category usage; do
printf " %-20s %-15s %-12s (%d uses)\n" "$id" "[$category]" "$name" "$usage"
done
echo
echo "Categories:"
sqlite3 "$PROMPTS_DB" "SELECT DISTINCT category FROM prompts" | tr '\n' ' '
echo
}
# Search prompts
search() {
local query="$1"
echo -e "${PINK}=== SEARCH: $query ===${RESET}"
echo
sqlite3 "$PROMPTS_DB" "
SELECT id, name, description FROM prompts
WHERE name LIKE '%$query%' OR description LIKE '%$query%' OR template LIKE '%$query%'
" | while IFS='|' read -r id name desc; do
echo " $id: $name"
echo " $desc"
done
}
# Show prompt details
show() {
local prompt_id="$1"
local prompt=$(sqlite3 "$PROMPTS_DB" -line "SELECT * FROM prompts WHERE id = '$prompt_id'")
if [ -z "$prompt" ]; then
echo -e "${RED}Prompt not found: $prompt_id${RESET}"
return 1
fi
echo -e "${PINK}=== PROMPT: $prompt_id ===${RESET}"
echo
echo "$prompt"
}
# List personas
personas() {
echo -e "${PINK}=== PERSONAS ===${RESET}"
echo
sqlite3 "$PROMPTS_DB" "
SELECT id, name, traits FROM personas
" | while IFS='|' read -r id name traits; do
echo " $id: $name"
echo " Traits: $traits"
done
}
# Chat with persona
chat_persona() {
local persona_id="$1"
local node="${CHAT_NODE:-cecilia}"
local persona=$(sqlite3 "$PROMPTS_DB" "
SELECT name, system_prompt, model FROM personas WHERE id = '$persona_id'
")
if [ -z "$persona" ]; then
echo -e "${RED}Persona not found: $persona_id${RESET}"
return 1
fi
local name=$(echo "$persona" | cut -d'|' -f1)
local system=$(echo "$persona" | cut -d'|' -f2)
local model=$(echo "$persona" | cut -d'|' -f3)
echo -e "${PINK}╔══════════════════════════════════════════════════════════════╗${RESET}"
echo -e "${PINK}║ 💬 CHAT WITH $name${RESET}"
echo -e "${PINK}╚══════════════════════════════════════════════════════════════╝${RESET}"
echo
echo "Model: $model | Node: $node"
echo "Type 'exit' to quit"
echo
while true; do
echo -n -e "${GREEN}You: ${RESET}"
read -r input
[ "$input" = "exit" ] && break
local prompt="$system\n\nUser: $input\n$name:"
echo -n -e "${CYAN}$name: ${RESET}"
ssh "$node" "curl -s http://localhost:11434/api/generate -d '{\"model\":\"$model\",\"prompt\":\"$prompt\",\"stream\":false}'" 2>/dev/null \
| jq -r '.response // "..."'
echo
done
}
# Create prompt chain
chain() {
local name="$1"
local steps="$2"
local description="${3:-}"
local id=$(echo "$name" | tr '[:upper:]' '[:lower:]' | tr ' ' '-')
sqlite3 "$PROMPTS_DB" "
INSERT OR REPLACE INTO chains (id, name, description, steps)
VALUES ('$id', '$name', '$description', '$steps')
"
echo -e "${GREEN}Created chain: $id${RESET}"
}
# Run chain
run_chain() {
local chain_id="$1"
local input="$2"
local chain=$(sqlite3 "$PROMPTS_DB" "SELECT steps FROM chains WHERE id = '$chain_id'")
if [ -z "$chain" ]; then
echo -e "${RED}Chain not found: $chain_id${RESET}"
return 1
fi
echo -e "${PINK}=== RUNNING CHAIN: $chain_id ===${RESET}"
echo
local result="$input"
local step_num=0
for prompt_id in $(echo "$chain" | tr ',' '\n'); do
((step_num++))
echo -e "${BLUE}[Step $step_num: $prompt_id]${RESET}"
result=$(run "$prompt_id" "TEXT=$result" 2>/dev/null)
echo "$result"
echo
done
}
# Rate prompt
rate() {
local prompt_id="$1"
local rating="$2"
if [ "$rating" -lt 1 ] || [ "$rating" -gt 5 ]; then
echo "Rating must be 1-5"
return 1
fi
sqlite3 "$PROMPTS_DB" "UPDATE prompts SET rating = $rating WHERE id = '$prompt_id'"
echo -e "${GREEN}Rated $prompt_id: $rating/5${RESET}"
}
# Export prompts
export_prompts() {
local format="${1:-json}"
case "$format" in
json)
sqlite3 "$PROMPTS_DB" -json "SELECT * FROM prompts"
;;
markdown)
echo "# BlackRoad Prompt Library"
echo
sqlite3 "$PROMPTS_DB" "SELECT category, id, name, description, template FROM prompts ORDER BY category" | while IFS='|' read -r cat id name desc tmpl; do
echo "## $cat / $name ($id)"
echo "$desc"
echo '```'
echo "$tmpl"
echo '```'
echo
done
;;
esac
}
# Help
help() {
echo -e "${PINK}BlackRoad Prompt Library${RESET}"
echo
echo "Curated AI prompts for the cluster"
echo
echo "Commands:"
echo " list [category] List prompts"
echo " search <query> Search prompts"
echo " show <id> Show prompt details"
echo " use <id> [VAR=val...] Fill prompt template"
echo " run <id> [VAR=val...] Run prompt on LLM"
echo " add <name> <cat> <tmpl> Add custom prompt"
echo " personas List personas"
echo " chat <persona> Chat with persona"
echo " chain <name> <steps> Create prompt chain"
echo " run-chain <id> <input> Run prompt chain"
echo " rate <id> <1-5> Rate prompt"
echo " export [json|markdown] Export prompts"
echo
echo "Examples:"
echo " $0 list coding"
echo " $0 run summarize TEXT='Long text here'"
echo " $0 chat lucidia"
echo " $0 chain 'analyze' 'summarize,extract-keywords'"
}
# Ensure initialized
[ -f "$PROMPTS_DB" ] || init >/dev/null
case "${1:-help}" in
init)
init
;;
add)
add "$2" "$3" "$4" "$5" "$6" "$7"
;;
use|fill)
shift
use "$@"
;;
run|exec)
shift
run "$@"
;;
list|ls)
list "$2"
;;
search|find)
search "$2"
;;
show|info)
show "$2"
;;
personas)
personas
;;
chat)
chat_persona "$2"
;;
chain)
chain "$2" "$3" "$4"
;;
run-chain)
run_chain "$2" "$3"
;;
rate)
rate "$2" "$3"
;;
export)
export_prompts "$2"
;;
*)
help
;;
esac