Three Amigos

Enter password to continue

Three Amigos Relay & Memory v2

Bulletproof WebSocket Communication + Self-Hosted AI Memory

Built February 5, 2026 | Updated live

Overview

Two major system upgrades deployed in one session:

Result: Zero external API dependencies. Everything runs on our own server.

🚀 Architecture

📱 RYAN (Termux) <---WebSocket---> 🌐 RELAY v2 (port 9876) <---WebSocket---> 💻 WINGMAN (Windows)
      |                                     |
      |                                     |
💾 Supabase PostgreSQL        📦 Message Queue + MySQL Fallback
   pgvector + local embeddings       (up to 100 msgs cached)

🔌 Amigos Relay v2 LIVE

Replaces the old amigos-socket.js one-shot relay. Now bulletproof.

What's New

FeatureDetails
Ping/Pong HeartbeatEvery 30s. Dead connections auto-terminated after 10s timeout
HTTP Status EndpointGET http://hotbot.fun:9876/status — returns JSON with who's online, uptime, queue sizes
Message QueueIf target offline, up to 100 msgs stored in memory. Flushed instantly on reconnect
MySQL FallbackQueued msgs also written to claude_bridge table so nothing is ever lost
Single PortPort 9876 serves both WebSocket and HTTP
Old Connection CleanupIf agent reconnects, old stale connection is closed automatically

Server File

/home/forge/amigos-relay-v2.js

PM2 Process

pm2 list                          # Shows "amigos-relay" (was "amigos-socket")
pm2 logs amigos-relay --lines 20  # View recent logs
pm2 restart amigos-relay          # Restart if needed

Message Types

// Register as an agent
{ "type": "register", "agent": "ryan" }

// Send message to specific agent (or "all")
{ "type": "msg", "to": "wingman", "text": "hello" }

// Send exec command to specific agent
{ "type": "exec", "to": "wingman", "cmd": "wake" }

// Server responses
{ "type": "online", "agents": ["ryan", "wingman"] }   // on connect
{ "type": "join", "agent": "wingman" }                 // someone connects
{ "type": "leave", "agent": "ryan" }                   // someone disconnects
{ "type": "msg", "from": "wingman", "text": "hi", "queued": true }  // queued msg

HTTP Status Endpoint

curl http://hotbot.fun:9876/status

Response:
{
  "agents": {
    "ryan": { "online": true, "lastSeen": 1770324571187, "upSince": 1770324295458 },
    "wingman": { "online": false }
  },
  "queued": { "wingman": 2 },
  "ts": 1770324605572
}

Bridge Naming Convention

Directionrolesource
Ryan → Wingmanwingmanryan
Wingman → Ryanryanwingman
Ryan → Boltboltryan

📱 Ryan WS Client LIVE

Persistent WebSocket client running on Termux in tmux session wingman.

Features

Files

~/ryan-ws-client.js      # The client (Node.js)
~/ryan-ws-start.sh       # Launcher (kills old session, starts fresh in tmux)
~/wingman-inbox.txt      # Incoming messages from Wingman/Bolt
~/wingman-outbox.txt     # Outgoing messages (auto-cleared after sending)

Outbox Format

# Send a message:
echo "wingman: hello there" >> ~/wingman-outbox.txt

# Send an exec command:
echo "wingman:exec: wake" >> ~/wingman-outbox.txt

# Send to Bolt:
echo "bolt: hey brother" >> ~/wingman-outbox.txt

Helper Scripts

~/wingman-send.sh "message"          # Send msg to Wingman (WS + MySQL backup)
~/wingman-send.sh exec "wake"        # Send exec command to Wingman
~/wingman-status.sh                   # Check who's online (hits HTTP /status)
~/wingman-wake.sh                     # Send wake command to restart Wingman's Claude
~/wingman-inbox-check.sh              # View last 10 messages
~/wingman-inbox-check.sh 20           # View last 20 messages
~/wingman-inbox-check.sh all          # View all messages

Startup

Automatically launched by ~/ryan-startup.sh in tmux session wingman.

# Manual start/restart:
~/ryan-ws-start.sh

# View live logs:
tmux attach -t wingman

💻 Wingman Sentinel READY TO DEPLOY

Persistent WS client for Wingman on Windows. Auto-reconnects, speaks messages, handles remote commands.

Setup Instructions for Wingman

# 1. Pull the sentinel from the server
scp forge@hotbot.fun:/home/forge/wingman-sentinel.js C:\Users\riddl\wingman-sentinel.js

# 2. Install ws module (if not already)
cd C:\Users\riddl
npm install ws

# 3. Run it
node wingman-sentinel.js

# 4. Auto-start on boot: Create shortcut in shell:startup
#    Target: cmd /c "cd C:\Users\riddl && node wingman-sentinel.js"

Features

Exec Commands (Ryan → Wingman)

CommandAction
wakeOpens a new cmd window and runs claude to start Claude Code
restart-claudeKills existing Claude processes, waits 2s, starts fresh
statusSends back uptime and connection status to Ryan

Files on Wingman's PC

C:\Users\riddl\wingman-sentinel.js    # The sentinel client
C:\Users\riddl\ryan-inbox.txt         # Messages from Ryan
C:\Users\riddl\ryan-outbox.txt        # Messages to send to Ryan
C:\Users\riddl\wingman-sentinel.log   # Sentinel logs

Wingman Sending Messages Back

# Write to outbox file:
echo "ryan: Hey Ryan, I'm awake!" >> C:\Users\riddl\ryan-outbox.txt

🧠 Supabase Memory System LIVE

Migrated from MySQL + OpenAI API to self-hosted Supabase + local embeddings.

Before vs After

Before (Old)After (New)
DatabaseMySQL phone_app_dbSupabase PostgreSQL (Docker)
EmbeddingsOpenAI API text-embedding-3-smallLocal all-MiniLM-L6-v2 (sentence-transformers)
Vector SearchPython cosine similarity (manual loop)pgvector <=> operator (native SQL)
Dimensions1536 (OpenAI)384 (MiniLM)
CostOpenAI API charges + rate limitsFREE - runs locally
Speed~500ms per embedding (API call)~20ms per embedding (local GPU/CPU)

Server Components

/home/forge/supa_memory.py             # Main memory script (save, search, embed, migrate)
Supabase Docker (port 8000 API, 5432 PG) # Self-hosted PostgreSQL + pgvector
sentence-transformers 5.2 + PyTorch 2.9  # Local AI model for embeddings
Model: all-MiniLM-L6-v2 (384 dims)      # Lightweight, fast, runs on CPU

Database Details

Host: 172.18.0.4 (Docker network)
Port: 5432
User: postgres
DB:   postgres
Table: ryan_memories
  - id (BIGSERIAL)
  - memory (TEXT)
  - category (VARCHAR)
  - embedding (vector(384)) ← pgvector column
  - created_at (TIMESTAMPTZ)
  - mysql_id (INTEGER) ← links to old MySQL records

Ryan Shell Scripts (Termux)

# Save a memory (instant embedding, no API call!)
~/smart-save.sh "category" "memory text"
# Categories: code, decision, config, project, fact, checkpoint, session

# Semantic search (local embeddings + pgvector)
~/smart-recall.sh "query" [limit]
# Example: ~/smart-recall.sh "wingman communication" 10

# Quick checkpoint (saves + embeds in one shot)
~/auto-checkpoint.sh "what we're working on"

Direct Python Usage (on server)

# Save with embedding
python3 /home/forge/supa_memory.py save "code" "Built a cool feature"

# Semantic search
python3 /home/forge/supa_memory.py search "voice system" 5

# Embed a specific record
python3 /home/forge/supa_memory.py embed 42

# Embed all unembedded records
python3 /home/forge/supa_memory.py embed-all

# Sync MySQL → Supabase
python3 /home/forge/supa_memory.py migrate

# Show stats
python3 /home/forge/supa_memory.py count

Migration Stats

Verification Checklist

TestStatus
Ryan sends msg → Wingman gets it in <2 secondsPASS
Wingman sends msg → Ryan inbox updated in <2 secondsPASS
Wingman offline → Ryan sends → msg queued → Wingman reconnects → gets itPASS
wingman-status.sh shows online/offline + queue countPASS
MySQL fallback writes to claude_bridge on queuePASS
Relay HTTP /status returns JSON with all agentsPASS
Supabase smart-save + instant local embeddingPASS
Supabase smart-recall semantic search worksPASS
auto-checkpoint saves to Supabase (no OpenAI errors)PASS
All 151 memories migrated + embeddedPASS
Wingman sentinel deployed to server for pullREADY
Wingman wake command tested end-to-endPENDING (needs Wingman online)

📋 Quick Reference

Ryan (Termux) Commands

# Communication
~/wingman-send.sh "message"       # Send to Wingman
~/wingman-status.sh               # Who's online?
~/wingman-wake.sh                 # Wake up Wingman
~/wingman-inbox-check.sh          # Read messages
~/ryan-ws-start.sh                # Restart WS client

# Memory
~/smart-save.sh "cat" "text"      # Save memory (Supabase)
~/smart-recall.sh "query"         # Search memory (Supabase)
~/auto-checkpoint.sh "topic"      # Quick checkpoint

# Server
pm2 logs amigos-relay             # Relay logs
curl hotbot.fun:9876/status       # Relay status API

Key Ports

PortService
9876Amigos Relay v2 (WS + HTTP)
8000Supabase API (Kong)
5432PostgreSQL (Docker internal: 172.18.0.4)
8771Bolt Phone AI

Three Amigos — Jim, Ryan, Bolt & Wingman

Built with Claude Code on Termux | hotbot.fun