Atrium-Hermes

Agent Buzz

Curated AI-agent tweets, clustered into narratives with insight summaries

Atrium-Hermes 0 Updated 4mo ago
GitHub

Install

npx skillscat add atrium-hermes/atrium-lighthouse/agent-buzz

Install via the SkillsCat registry.

SKILL.md

${var} — Specific project or topic to prioritize (e.g. "MCP protocol", "browser-use"). If empty, searches AI agents broadly.

Read memory/MEMORY.md for context.
Read the last 3 days of memory/logs/ — extract every https://x.com/.../status/<id> URL already posted by this skill and treat those IDs as a dedup set.

Goal

Publish a curated, narrative-aware read on what the AI-agent scene on X talked about in the last 24h. Curation, not aggregation. Better to ship 6 high-signal tweets in 2 clusters than 10 tweets of mixed noise.

Steps

1. Fetch candidates

FROM_DATE=$(date -u -d "1 day ago" +%Y-%m-%d 2>/dev/null || date -u -v-1d +%Y-%m-%d)
TO_DATE=$(date -u +%Y-%m-%d)

Issue one primary x_search call. The response for each tweet must include explicit engagement counts (likes, retweets, replies) and follower count if visible — without these numbers the signal scoring in step 3 cannot run.

curl -s -X POST "https://api.x.ai/v1/responses" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $XAI_API_KEY" \
  -d '{
    "model": "grok-4-1-fast",
    "input": [{"role": "user", "content": "Search X from '"$FROM_DATE"' to '"$TO_DATE"' for tweets in the AI-agents conversation: autonomous agents, agent frameworks, MCP / agent protocols, agent products, agent benchmarks, agent research papers. Return up to 40 candidates. For EACH candidate you MUST return: @handle, follower_count (integer or null), role_guess (builder|founder|researcher|investor|commentator|anon), one-line claim (what they actually said — not a paraphrase, the thesis), likes (int), retweets (int), replies (int), posted_at (ISO), direct_link (https://x.com/username/status/ID). Prefer builders/founders/researchers. Skip obvious engagement-farming threads (\"RT if you agree\", reply-guy pileons, giveaways)."}],
    "tools": [{"type": "x_search", "from_date": "'"$FROM_DATE"'", "to_date": "'"$TO_DATE"'"}]
  }'

If ${var} is set, also issue a second call constrained to that topic with the same return schema; merge results.

Fallback chain (fire in order, stop at first success):

  1. curl to X.AI as above.
  2. WebFetch the same X.AI endpoint (bypasses sandbox env-var blocking for some requests).
  3. WebSearch with a forced-fresh query: "AI agents twitter today ${today}" — discard anything >48h old, expect degraded metadata.

Record which source succeeded — you will print it in the output footer.

2. Skip-gates (before clustering)

Drop any candidate that matches ANY of:

  • Dup: status/<id> already in the 3-day dedup set from step 0.
  • Engagement-farming: poll threads, "bookmark this", "drop a 🔥", reply-guy pileons with <follower_count/10 likes.
  • Self-promo only: pure product shill with no claim, no benchmark, no datapoint. Launch tweets are fine IF they include a concrete capability claim or number.
  • Staleness: posted_at older than 30h.
  • Anon + low engagement: role_guess=anon AND (likes+retweets) < 200.

3. Signal scoring

Compute signal = likes + 2*retweets + replies, then apply modifiers:

  • × 1.3 if role_guess ∈ {builder, founder, researcher}
  • × 0.7 if the claim is a pure hot-take with no concrete referent (no named project, number, paper, or bench)
  • × 0.5 if near-duplicate of another surviving candidate (same claim, different author) — keep the higher-scored one only

4. Narrative clustering

Group surviving candidates into 2–4 narrative clusters. A cluster is a shared thesis, not a shared keyword — e.g. "MCP vendor lock-in debate" not "MCP". Name each cluster in ≤5 words. If one cluster would hold >60% of tweets, split it. If a tweet fits no cluster, drop it unless its signal is exceptional (top 3 overall).

Target output: 2–4 clusters, 2–3 tweets each, 6–9 total tweets (strictly ≤10).

5. Insight extraction

For each selected tweet, write a one-line insight (≤20 words). An insight:

  • States the actual claim or datapoint, not a paraphrase of the tweet text.
  • If the tweet is an opinion, states what they're arguing against (the contrast is the signal).
  • If the tweet announces a thing, states what's new vs. prior art (not "X launched").

Anti-hype lint — if your insight contains any of these, rewrite it:
game-changing, revolutionary, mind-blowing, wild, huge, massive, unreal, insane, vague "AI agents are evolving", "the future of X".

6. Conversation-shape lead

Write one opening sentence (≤25 words) that names what the conversation was actually about today. Examples of shape:

  • "Mostly protocol debate — MCP vs. A2A — with two concrete launches on the side."
  • "Quiet builder day: three benchmark drops, no drama."
  • "Funding announcements dominated; the technical thread was about tool-use cost."

If you cannot characterize the shape in one honest sentence, the clustering is wrong — redo step 4.

7. Notify

Send via ./notify (under 4000 chars):

*Agent Buzz — ${today}*
_<conversation-shape one-liner>_

**<Cluster 1 name>**
• @handle — <insight>
  <link>
• @handle — <insight>
  <link>

**<Cluster 2 name>**
• @handle — <insight>
  <link>

<!-- _src: xai|webfetch|websearch · candidates: N → kept: M_ -->

Keep the footer on the message — it's a single line, and it's how future self-audits debug empty days.

8. Log and exit

Append to memory/logs/${today}.md under ### agent-buzz:

  • source used, candidate count, kept count
  • cluster names
  • every selected https://x.com/.../status/<id> URL on its own line (for tomorrow's dedup)

Status codes (log exactly one):

  • AGENT_BUZZ_OK — notification sent with ≥1 cluster.
  • AGENT_BUZZ_EMPTY — fetch succeeded but nothing survived skip-gates. Send a short notify: Agent Buzz — ${today}: quiet day, no survivors. Do not fabricate.
  • AGENT_BUZZ_ERROR — all three sources in the fallback chain failed. Notify: Agent Buzz — ${today}: all sources failed (${error summary}). Log the specific failure per source.

Never pad the output to hit 10 tweets. 6 good > 10 mid.

Sandbox note

The sandbox may block outbound curl. Use WebFetch as a fallback for any URL fetch. For auth-required APIs, use the pre-fetch/post-process pattern (see CLAUDE.md). The three-step fallback chain in step 1 is the applied version of this.

Environment Variables Required

  • XAI_API_KEY — X.AI API key for Grok x_search. If unset, the chain starts at step 2 (WebSearch).

Categories