From 3e4d608fbf68dfe8dd6804a19d4e05d76e1d66c1 Mon Sep 17 00:00:00 2001 From: Tony Balascio Date: Thu, 13 Aug 2026 20:48:36 +0000 Subject: [PATCH] Delete directory 'hermes-automation' --- hermes-automation/README.md | 55 ------------- hermes-automation/examples/.gitkeep | 0 hermes-automation/gates/.gitkeep | 0 .../gates/email-triage-wakegate.md | 79 ------------------- hermes-automation/notes/.gitkeep | 0 .../notes/daily-brief-implementation.md | 42 ---------- hermes-automation/scripts/.gitkeep | 0 .../scripts/daily-brief-collector.sh | 70 ---------------- 8 files changed, 246 deletions(-) delete mode 100644 hermes-automation/README.md delete mode 100644 hermes-automation/examples/.gitkeep delete mode 100644 hermes-automation/gates/.gitkeep delete mode 100644 hermes-automation/gates/email-triage-wakegate.md delete mode 100644 hermes-automation/notes/.gitkeep delete mode 100644 hermes-automation/notes/daily-brief-implementation.md delete mode 100644 hermes-automation/scripts/.gitkeep delete mode 100644 hermes-automation/scripts/daily-brief-collector.sh diff --git a/hermes-automation/README.md b/hermes-automation/README.md deleted file mode 100644 index d4ddbd2..0000000 --- a/hermes-automation/README.md +++ /dev/null @@ -1,55 +0,0 @@ -# Hermes Automation Patterns - -Production patterns for efficient, low-cost always-on Hermes agents tied to Tony's workflows. - -## Source: Tonbi Hermes Agent Masterclass (Cron & Automation, June 19 2026) - -This directory captures techniques from the **cyrilXBT / Tonbi Hermes Agent Masterclass** series, specifically the **Cron & Automation** session published June 19, 2026. The session covers how to build persistent, cost-effective autonomous agents using Hermes' built-in scheduler, gates, and delivery controls. - -**Link:** [YouTube — Hermes Agent Masterclass (Cron & Automation)](https://www.youtube.com/watch?v=grMNnzCv2gY) - -### Key Techniques - -| Technique | Description | Cost Impact | -|-----------|-------------|-------------| -| **wakeAgent Gates** | Condition-based triggers that only invoke the LLM when specific criteria are met (instead of running every tick). Prevents unnecessary API calls on irrelevant cycles. | High savings | -| **no-agent Polling** | `no_agent=True` flag on cron scripts — runs a shell script directly without any LLM context. Output is delivered verbatim only when there's change or data. Zero token cost per tick when nothing happens. | Max savings | -| **context-from Chaining** | Pipe output of one cron job as context into another via `context_from`. Enables multi-stage pipelines (e.g., collector → summarizer → delivery) where each stage only fires on upstream data. | Tiered cost | -| **Silent Delivery** | Cron jobs that produce empty stdout on no-change ticks deliver nothing. The user only sees messages when there's actionable output. Reduces noise and delivery friction. | Free (no token) | - -### Goals - -1. **Email Triage** — Automated inbox scanning, priority routing, and draft response generation with approval gates. -2. **Skills Hub Monitoring** — Track skill usage, freshness, and curator activity across all active skills. -3. **Compliance Monitoring** — Periodic scans of regulatory changes and gap detection against SOP/KB artifacts. -4. **Opportunity Scanning** — Scheduled market/tech landscape scans with mechanical filtering and artifact persistence. -5. **Daily Briefs** — High-signal daily summaries from multiple sources, delivered at configured times via Telegram or email. - ---- - -## Directory Layout - -``` -hermes-automation/ -├── README.md # This file — overview and masterclass summary -├── gates/ # wakeAgent-style gate designs (condition-based triggers) -│ ├── email-triage-wakegate.md # Example: email triage poller gate -│ └── .gitkeep -├── scripts/ # Shell/Python scripts for no-agent polling jobs -│ └── .gitkeep -├── examples/ # Full worked examples combining gates + scripts + delivery -│ └── .gitkeep -└── notes/ # Implementation notes, gotchas, config snippets - └── .gitkeep -``` - ---- - -## Getting Started - -Browse the `gates/` directory for condition-based trigger patterns. When adapting a pattern: - -1. Start with a **no-agent script** (cheapest) — just shell/Python collecting and filtering data -2. Add a **wakeAgent gate** when conditional LLM reasoning is needed -3. Chain via **context-from** to split complex pipelines into lean stages -4. Use **silent delivery** on every poller — never deliver "nothing changed" ticks diff --git a/hermes-automation/examples/.gitkeep b/hermes-automation/examples/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/hermes-automation/gates/.gitkeep b/hermes-automation/gates/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/hermes-automation/gates/email-triage-wakegate.md b/hermes-automation/gates/email-triage-wakegate.md deleted file mode 100644 index d001a49..0000000 --- a/hermes-automation/gates/email-triage-wakegate.md +++ /dev/null @@ -1,79 +0,0 @@ -# Email Triage — wakeAgent Gate Pattern - -A condition-based poller that checks for new actionable email, fires the LLM only when there's unprocessed high-priority mail, and stays silent (zero cost) on empty ticks. - -## Design - -``` -┌─────────────────────────────────────────────────────────────┐ -│ cron: every 15m │ -│ no_agent=true │ -│ script: check-unread-email.sh │ -├─────────────────────────────────────────────────────────────┤ -│ Script output (stdout): │ -│ • "" (empty) → no agent, no delivery ── $0.00 │ -│ • "3 unread priority" → gate opens → agent processes │ -└─────────────────────────────────────────────────────────────┘ -``` - -## Implementation - -### 1. Script (`scripts/check-unread-email.sh`) - -```bash -#!/usr/bin/env bash -# Silent poller: outputs nothing unless there are actionable unread emails -# Called by cron with no_agent=true — zero token cost on empty ticks -# -# Gate logic: -# stdout empty = no new email → silent delivery (nothing sent) -# stdout non-empty = has mail → cron passes it to agent context - -source ~/.hermes/profiles/leonard/.env - -COUNT=$(himalaya envelope list -f INBOX -a 2>/dev/null | grep -c "UNSEEN" || echo 0) - -if [ "$COUNT" -eq 0 ]; then - exit 0 # silent — no output, no delivery -fi - -# Gate opened: output structured context for the agent to process -echo "UNREAD_EMAIL=$COUNT" -echo "TIMESTAMP=$(date -Iseconds)" -echo "---" -himalaya envelope list -f INBOX -a 2>/dev/null | head -20 -``` - -### 2. Cron Job (Hermes cron) - -```bash -hermes cron create \ - -s "email-monitor" \ - --schedule "every 15m" \ - --script ~/.hermes/profiles/leonard/scripts/check-unread-email.sh \ - --no-agent \ - "If the script reports unread emails, summarize the top 3 most important ones with sender, subject, and a one-line action recommendation. Flag anything urgent or time-sensitive. If nothing actionable, deliver nothing." -``` - -### 3. Wake Gate Principle - -The gate stays **closed** (no agent invoked) 95%+ of ticks. The script: -- Uses no LLM resources (pure shell) -- Outputs nothing on empty scans → **silent delivery** (free) -- Only when email is found does the agent context fire - -## Key Configuration - -| Setting | Value | Reason | -|---------|-------|--------| -| `schedule` | `every 15m` | Fast enough for triage, sparse enough to stay cheap | -| `no_agent` | `true` | Script-only polling — zero token cost per tick | -| `deliver` | `origin` | Returns to the same chat where created | -| Script exit | `0` with empty stdout | Silent — no notification sent | - -## Variants - -- **Compliance monitor**: Same pattern, replace email check with regulatory RSS/API poll -- **Opportunity scanner**: Script scrapes X/HN, gates on fresh high-signal mentions -- **System health**: Script checks disk/GPU/memory thresholds, gates only on warnings -- **Skills curator**: Script checks skill freshness, gates on skills approaching staleness \ No newline at end of file diff --git a/hermes-automation/notes/.gitkeep b/hermes-automation/notes/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/hermes-automation/notes/daily-brief-implementation.md b/hermes-automation/notes/daily-brief-implementation.md deleted file mode 100644 index 61a2600..0000000 --- a/hermes-automation/notes/daily-brief-implementation.md +++ /dev/null @@ -1,42 +0,0 @@ -# Daily Brief — Implementation Notes - -## Architecture: context-from Chaining - -The daily brief uses a **no-agent script → agent curation** pipeline: - -``` -┌──────────────────────────────┐ -│ cron: 0 15 * * * │ -│ script: collector.sh │ ← no-agent, free public APIs -├──────────────────────────────┤ -│ Script stdout → agent │ ← injected as prompt context -│ context │ -├──────────────────────────────┤ -│ Agent: curates → formats │ ← lightweight LLM pass only -│ → delivers to Telegram │ -└──────────────────────────────┘ -``` - -## Cost Breakdown - -| Stage | Token Cost | Frequency | -|-------|-----------|-----------| -| Script fetch (shell) | $0 | 1x per tick | -| Agent curation | Full model | 1x per tick | -| **Total vs old approach** | **~90% cheaper** | Old: agent had to web search + X search (both failing) | - -## Sources (Free, No API Key) - -| Source | Endpoint | Reliability | -|--------|----------|-------------| -| Weather | `wttr.in/Placerville,CA` | 99.9% | -| Hacker News | Firebase API (v0) | 99.9% | -| GitHub Trending | `api.github.com/search/repositories` | 99% (unauthed rate limit: 60/hr — fine for daily) | - -## Previous State (Before June 20) - -The old prompt instructed the agent to use web_search and x_search tools to gather data. Both were failing silently — Firecrawl was unconfigured and xAI credits were exhausted. The brief was returning `[SILENT]` every run (zero useful output for weeks). - -## Key Insight - -The **script + context_from** pattern from the masterclass turned a dead cron job into a working one in <5 minutes, with zero ongoing API costs. The script does the heavy lifting (API calls, parsing), and the agent only does the lightweight curation pass. \ No newline at end of file diff --git a/hermes-automation/scripts/.gitkeep b/hermes-automation/scripts/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/hermes-automation/scripts/daily-brief-collector.sh b/hermes-automation/scripts/daily-brief-collector.sh deleted file mode 100644 index 51a83e0..0000000 --- a/hermes-automation/scripts/daily-brief-collector.sh +++ /dev/null @@ -1,70 +0,0 @@ -#!/usr/bin/env bash -# daily-brief-collector.sh -# No-agent data collector: fetches free public data for the daily brief. -# Injected as cron context via the script= parameter. -# Zero API keys needed — all sources are free/public. -# -# Pattern: no-agent polling script → context injection → agent curates - -set -euo pipefail - -echo "# Daily Brief Data — $(date -I 2>/dev/null || date +%Y-%m-%d)" -echo "" - -# --- 1. Weather --- -echo "## 🌤 Weather — Placerville, CA" -if WEATHER=$(curl -sf "wttr.in/Placerville,CA?format=%C+%t+%w+%h&u" 2>/dev/null); then - echo "Current: $WEATHER" -else - echo "Weather: (unavailable)" -fi -echo "" - -# --- 2. Hacker News Top Stories --- -echo "## 📰 Hacker News — Top Stories" -TOP_IDS=$(curl -sf "https://hacker-news.firebaseio.com/v0/topstories.json" 2>/dev/null | python3 -c " -import sys, json -ids = json.load(sys.stdin)[:8] -for i in ids: - print(i) -" 2>/dev/null) - -if [ -n "$TOP_IDS" ]; then - echo "$TOP_IDS" | while read -r ID; do - ITEM=$(curl -sf "https://hacker-news.firebaseio.com/v0/item/$ID.json" 2>/dev/null) - [ -n "$ITEM" ] && echo "$ITEM" | python3 -c " -import sys, json -d = json.load(sys.stdin) -title = d.get('title', '?') -url = d.get('url', 'https://news.ycombinator.com/item?id=' + str(d.get('id', ''))) -score = d.get('score', 0) -print(f\"- [{title}]({url}) (⬆{score})\") -" 2>/dev/null || true - done -else - echo "HN: (unavailable)" -fi -echo "" - -# --- 3. GitHub Trending (24h) --- -echo "## 💻 GitHub — Trending Repos (24h)" -YESTERDAY=$(date -d '2 days ago' +%Y-%m-%d 2>/dev/null || date -v-2d +%Y-%m-%d 2>/dev/null || echo "2026-06-18") -curl -sf "https://api.github.com/search/repositories?q=created:>$YESTERDAY&sort=stars&order=desc&per_page=5" 2>/dev/null | python3 -c " -import sys, json -data = json.load(sys.stdin) -items = data.get('items', []) -if not items: - print('No repos found in last 24h') -else: - for r in items: - name = r['full_name'] - desc = (r['description'] or 'No description')[:100] - stars = r['stargazers_count'] - url = r['html_url'] - lang = r.get('language') or '?' - print(f\"- [{name}]({url}) — {desc} ({lang}, ⭐{stars})\") -" 2>/dev/null || echo "GitHub: (unavailable)" -echo "" - -echo "---" -echo "Use the data above to generate a concise daily brief (max 8 bullets). Format all links as clickable Telegram markdown. No intro or closing text." \ No newline at end of file