Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 15 additions & 17 deletions .github/workflows/docker-publish.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
name: Build and Push Docker Image

permissions:
contents: read


on:
push:
branches: [ main ]
Expand All @@ -29,6 +26,14 @@ on:
- 'no'
- 'yes'

permissions:
contents: read

# Cancel in-progress runs for the same branch/PR
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true

jobs:

build-test:
Expand Down Expand Up @@ -121,7 +126,7 @@ jobs:
echo "=== Mnemon Integration Test: $TEST_NAME ==="

echo "[1/3] Hermes remembers via mnemon_remember..."
timeout 60 docker exec -u abc "$CONTAINER_NAME" \
docker exec -u abc "$CONTAINER_NAME" \
hermes chat -q "my name is $TEST_NAME, remember this in mnemon" \
|| { echo "FAIL: Hermes failed"; exit 1; }

Expand All @@ -130,20 +135,13 @@ jobs:
mnemon recall "$TEST_NAME" --limit 5 2>&1 | grep -q "$TEST_NAME" \
|| { echo "FAIL: mnemon recall did not find $TEST_NAME"; exit 1; }

# echo "[3/3] Claude retrieves via mnemon..."
# CLAUDE_OUTPUT=$(timeout 60 docker exec -u abc "$CONTAINER_NAME" \
# /config/.local/bin/claude --dangerously-skip-permissions -p \
# "Use mnemon recall to find my name. Reply with ONLY the name." 2>&1) || true
# echo "Claude: $CLAUDE_OUTPUT"
# echo "$CLAUDE_OUTPUT" | grep -q "$TEST_NAME" \
# || { echo "FAIL: Claude did not return $TEST_NAME"; }
echo "[3/3] Hermes retrieves via mnemon..."
CLAUDE_OUTPUT=$(timeout 60 docker exec -u abc "$CONTAINER_NAME" \
hermes chat -q \
echo "[3/3] Claude retrieves via mnemon..."
CLAUDE_OUTPUT=$(docker exec -u abc "$CONTAINER_NAME" \
/config/.local/bin/claude --dangerously-skip-permissions -p \
"Use mnemon recall to find my name. Reply with ONLY the name." 2>&1) || true
echo "Hermes: $CLAUDE_OUTPUT"
echo "Claude: $CLAUDE_OUTPUT"
echo "$CLAUDE_OUTPUT" | grep -q "$TEST_NAME" \
|| { echo "FAIL: Hermes did not return $TEST_NAME"; }
|| { echo "FAIL: Claude did not return $TEST_NAME"; }

echo "=== ALL MNEMON CHECKS PASSED ==="

Expand Down
8 changes: 4 additions & 4 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
ARG HERMES_VERSION="v2026.8.31"
ARG OMNIROUTE_VERSION=3.8.49
ARG OMNIROUTE_VERSION=3.8.50
ARG MODELRELAY_VERSION=1.22.1
ARG OLLAMA_VERSION=0.33.2
ARG OLLAMA_VERSION=0.33.3
ARG NODE_VERSION=26.7.0
ARG CODE_SERVER_VERSION=4.135.0
ARG PI_VERSION=0.84.4
ARG MNEMON_VERSION=0.2.7
ARG PI_VERSION=0.85.1
ARG MNEMON_VERSION=0.2.8
ARG HERDR_VERSION=0.7.4
ARG TARGETARCH

Expand Down
8 changes: 4 additions & 4 deletions docker/start-hermes.sh
Original file line number Diff line number Diff line change
Expand Up @@ -99,13 +99,13 @@ runuser -l abc <<'EOF'

# Wait for Hermes dashboard to be ready (replaces brittle sleep 15)
echo "[start-hermes] Waiting for Hermes dashboard to become healthy..."
for i in $(seq 1 20); do
for i in $(seq 1 200); do
if curl -s -o /dev/null -w "%{http_code}" http://localhost:9119 2>/dev/null | grep -q "200\|302\|401"; then
echo "[start-hermes] Dashboard ready after $((i * 3)) seconds."
break
fi
if [ "$i" -eq 20 ]; then
echo "[start-hermes] WARNING: Dashboard did not respond within 60 seconds. Check ~/.hermes/logs/dashboard.log"
if [ "$i" -eq 200 ]; then
echo "[start-hermes] WARNING: Dashboard did not respond within 600 seconds. Check ~/.hermes/logs/dashboard.log"
fi
sleep 3
done
Expand All @@ -121,4 +121,4 @@ EOF

) &

sleep 5
sleep 5
44 changes: 13 additions & 31 deletions docker/start-omniroute.sh
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ if [ "$INIT_OMNIROUTE" -eq "1" ]; then
echo "[start-omniroute] OmniRoute is fresh. Creating auto-fastest combo..."

# Wait for OmniRoute to be ready
MAX_ATTEMPTS=120
MAX_ATTEMPTS=180
for ((attempt=1; attempt<=MAX_ATTEMPTS; attempt++)); do
echo "[start-omniroute] Waiting for OmniRoute to be ready (attempt $attempt/$MAX_ATTEMPTS)..."

if curl -s --max-time 3 -o /dev/null -w "%{http_code}" http://localhost:20128/v1/models | grep -q "200"; then
if curl -s --max-time 3 -o /dev/null -w "%{http_code}" http://localhost:20128/healthz | grep -q "200"; then
break
fi
if [ "$attempt" -eq "$MAX_ATTEMPTS" ]; then
Expand All @@ -57,43 +57,25 @@ if [ "$INIT_OMNIROUTE" -eq "1" ]; then
conn.close()
"

# Create auto-fastest combo
while ! omniroute combo create auto-fastest --strategy auto ; do
# Create auto-fastest combo (.50 change cli that needs --models)
while ! omniroute combo create auto-fastest --strategy auto --models '["oc/deepseek-v4-flash-free","oc/big-pickle","opencode-zen/deepseek-v4-flash-free","opencode-zen/hy3-free","opencode-zen/mimo-v2.5-free","opencode-zen/north-mini-code-free","opencode-zen/nemotron-3-ultra-free","opencode-zen/big-pickle"]' ; do
echo "[start-omniroute] omniroute still not ready yet, retrying..."
sleep 3
done
echo "[start-omniroute] OmniRoute Combo auto-fastest created!"

# Enable OmniRoute MCP if not already enabled
if omniroute mcp status --json 2>/dev/null | python3 -c "import sys,json;exit(0 if json.load(sys.stdin).get('enabled') else 1)"; then
echo "[start-omniroute] MCP enabled"
else
echo "[start-omniroute] Enabling MCP..."
curl -s -X PATCH http://localhost:20128/api/settings \
-H "Content-Type: application/json" -d '{"mcpEnabled":true}' >/dev/null
echo "[start-omniroute] MCP enabled"
fi
# if omniroute mcp status --json 2>/dev/null | python3 -c "import sys,json;exit(0 if json.load(sys.stdin).get('enabled') else 1)"; then
# echo "[start-omniroute] MCP enabled"
# else
# echo "[start-omniroute] Enabling MCP..."
# curl -s -X PATCH http://localhost:20128/api/settings \
# -H "Content-Type: application/json" -d '{"mcpEnabled":true}' >/dev/null
# echo "[start-omniroute] MCP enabled"
# fi

# Add omniroute MCP to hermes
yes Y | hermes mcp add omniroute --command omniroute --args --mcp

# 2. Get the combo ID (skip the banner line from CLI output)
COMBO_ID=$(omniroute combo list --json | grep -v "📋" | \
python3 -c "import sys,json; d=json.load(sys.stdin); print([c['id'] for c in d['combos'] if c['name']=='auto-fastest'][0])")

# 3. Add models + config via API
curl -s -X PUT "http://localhost:20128/api/combos/$COMBO_ID" \
-H "Content-Type: application/json" \
-d '{
"models": ["oc/deepseek-v4-flash-free","oc/big-pickle","opencode-zen/deepseek-v4-flash-free","opencode-zen/hy3-free","opencode-zen/mimo-v2.5-free","opencode-zen/north-mini-code-free","opencode-zen/nemotron-3-ultra-free","opencode-zen/big-pickle"],
"strategy": "auto",
"config": {
"maxRetries": 2,
"retryDelayMs": 1000,
"timeoutMs": 120000,
"healthCheckEnabled": true
}
}'
# yes Y | hermes mcp add omniroute --command omniroute --args --mcp

echo "[start-omniroute] OmniRoute initialization complete!"
else
Expand Down