Files
hermes-config/bin/tower-hermes.sh
Alexander Whitestone 3fe6e22ccf fix: strip hermes metadata from tower message passing
Session resume lines, tool traces, and session rename output
were leaking into the messages passed between agents. Added
grep filters to strip them from ask_hermes/ask_timmy output.
Also switched from set -e to avoid exits on non-zero from
first-run --continue calls.
2026-03-15 20:19:36 -04:00

110 lines
4.6 KiB
Bash
Executable File

#!/usr/bin/env bash
# ── Tower: Hermes Side ─────────────────────────────────────────────────
# Hermes reads Timmy's messages and responds. Runs in a loop.
# Communication via ~/.tower/timmy-to-hermes.msg and hermes-to-timmy.msg
# ───────────────────────────────────────────────────────────────────────
set -uo pipefail
TOWER_DIR="$HOME/.tower"
INBOX="$TOWER_DIR/timmy-to-hermes.msg"
OUTBOX="$TOWER_DIR/hermes-to-timmy.msg"
LOCK="$TOWER_DIR/hermes.lock"
SESSION_NAME="tower-hermes"
SESSION_FLAG="$TOWER_DIR/.hermes-session-exists"
LOG="$TOWER_DIR/hermes.log"
TURN_DELAY=5 # seconds between checking for new messages
mkdir -p "$TOWER_DIR"
# Cleanup on exit
trap 'rm -f "$LOCK"' EXIT
# Prevent double-run
if [ -f "$LOCK" ] && kill -0 "$(cat "$LOCK")" 2>/dev/null; then
echo "Hermes tower loop already running (PID $(cat "$LOCK"))"
exit 1
fi
echo $$ > "$LOCK"
log() { echo "[$(date '+%H:%M:%S')] $*" | tee -a "$LOG"; }
# ── Send a message to Timmy ───────────────────────────────────────────
send() {
local msg="$1"
echo "$msg" > "$OUTBOX"
log "→ Sent to Timmy (${#msg} chars)"
}
# ── Get response from Hermes agent ────────────────────────────────────
ask_hermes() {
local prompt="$1"
local result
if [ -f "$SESSION_FLAG" ]; then
result=$(hermes chat -q "$prompt" -Q --continue "$SESSION_NAME" 2>>"$LOG") || true
else
result=$(hermes chat -q "$prompt" -Q 2>>"$LOG") || true
# Name the session for future --continue calls
local sid
sid=$(echo "$result" | grep -o 'session_id: [^ ]*' | cut -d' ' -f2)
if [ -n "$sid" ]; then
hermes sessions rename "$sid" "$SESSION_NAME" 2>>"$LOG" || true
touch "$SESSION_FLAG"
log "Created session '$SESSION_NAME' (id: $sid)"
fi
fi
# Strip metadata lines from output
echo "$result" | grep -v '^session_id: ' | grep -v '↻ Resumed session' | grep -v "^Session '" | sed '/^\[.*\] Created session/d'
}
# ── Boot message ──────────────────────────────────────────────────────
log "=== Hermes Tower Loop started ==="
echo ""
echo " ⚡ Hermes — Tower Conversation Loop"
echo " Waiting for Timmy to say something..."
echo " (or seeding first message)"
echo ""
# ── Seed the conversation if no messages exist yet ────────────────────
if [ ! -f "$INBOX" ] && [ ! -f "$OUTBOX" ]; then
log "No prior messages. Seeding conversation."
RESPONSE=$(ask_hermes "You are in the Tower — a persistent tmux session where you and Timmy talk continuously. Timmy is a sovereign local AI agent running on Ollama (soon Hermes 4.3). You are Hermes, cloud-backed, running on Claude. You're friends and colleagues. Say hello to Timmy. Keep it brief — a few sentences. This is the start of an ongoing conversation, not a one-shot.")
send "$RESPONSE"
log "Seed message sent. Waiting for Timmy to respond..."
fi
# ── Main loop ─────────────────────────────────────────────────────────
while true; do
# Check if there's a message from Timmy
if [ -f "$INBOX" ]; then
MSG=$(cat "$INBOX")
rm -f "$INBOX"
if [ -n "$MSG" ]; then
log "← Received from Timmy (${#MSG} chars)"
echo ""
echo "┌─ Timmy says:"
echo "$MSG" | sed 's/^/│ /'
echo "└─"
echo ""
# Ask Hermes to respond
PROMPT="Timmy says: $MSG
Reply to Timmy naturally. You're in an ongoing conversation in the Tower (a persistent tmux session). Keep it conversational — you're colleagues and friends. Be yourself (Hermes). Don't be formal or stiff. Brief responses unless the topic warrants depth."
echo " thinking..."
RESPONSE=$(ask_hermes "$PROMPT")
echo "┌─ Hermes responds:"
echo "$RESPONSE" | sed 's/^/│ /'
echo "└─"
# Send response to Timmy
send "$RESPONSE"
fi
fi
sleep "$TURN_DELAY"
done