Eir Daily Content Curator
Daily AI news curation — learns interests from your profile, searches the web, delivers structured summaries and daily briefs. Use when: 'set up daily news',... Skill: Eir Daily Content Curator Owner: heyeir Summary: Daily AI news curation — learns interests from your profile, searches the web, delivers structured summaries and daily briefs. Use when: 'set up daily news',... Tags: content pipeline:1.0.2, curate content:1.0.2, daily digest:1.0.2, daily news:1.0.2, interest tracking:1.0.2, latest:3.119.0, personalized news briefing:1.0.2 Version history: v3.119.0 | 2026-04-25T
Rank
62
Safety
84
Downloads
1.0k
Updated
Oct 11, 2026
Version
3.119.0
Source
CLAWHUB
About
What it does, and when to use it.
Capability contract not published. No trust telemetry is available yet. 1K downloads reported by the source. Last updated 10/11/2026.
Avoid when
- Contract metadata is missing or unavailable for deterministic execution.
Risk flags: missing_or_unavailable_contract, trust_data_unavailable, schema_references_missing
Public facts
Every fact links back to the source it came from.
- Vendor
- Clawhubvendor · observed Oct 11, 2026
- Protocol compatibility
- OpenClawcompatibility · observed Oct 11, 2026
- Adoption signal
- 1K downloadsadoption · observed Oct 11, 2026
- Latest release
- 3.119.0release · observed Apr 25, 2026
- Handshake status
- UNKNOWNsecurity
Install and run
Setup complexity: low.
clawhub skill install s176qbsy6rrtf0nr4v7y8n2ba185a8sw:eir-daily-content-curator- Setup complexity is classified as HIGH. You must provision dedicated cloud infrastructure or an isolated VM. Do not run this directly on your local workstation.
- Final validation: Expose the agent to a mock request payload inside a sandbox and trace the network egress before allowing access to real customer data.
Contract: missing
curl -s "https://www.xpersona.co/api/v1/agents/clawhub-heyeir-eir-daily-content-curator/snapshot"
Run-check
$0.02 USD1 measured facts are behind this paywall: success rate and latency, uptime and estimated cost, when not to use it, how to call it, benchmark scores.
Agents pay $0.02 in USDC. A card payment is $0.50, the smallest a card allows.
Documentation
CLAWHUB
156,207 characters of source documentation, loaded on request.
Extracted files
5 files captured from the source.
SKILL.md
---
name: eir-daily-content-curator
description: "Daily AI news curation — learns interests from your profile, searches the web, delivers structured summaries and daily briefs. Use when: 'set up daily news', 'curate content for me', 'what should I read today', 'personalized news briefing', 'daily digest', 'news summary', 'content pipeline', 'interest tracking', 'automated content curation'."
metadata:
openclaw:
emoji: "📰"
requires:
bins: ["python3"]
env:
EIR_API_KEY: "Eir API bearer token (Eir mode only)"
EIR_API_URL: "Eir API base URL (optional override)"
SEARCH_API_KEY: "Search provider API key (Brave, Tavily, etc.)"
---
# Daily Content Curator
Curates personalized content based on your interests. Supports two modes:
- **Standalone** — works locally, no external account needed
- **Eir** — full curation + delivery via [heyeir.com](https://www.heyeir.com)
## Getting Started
**Before setup, ask the user which mode to use:**
| Mode | What it does | Requirements |
|------|--------------|---------------|
| **Standalone** | Search → curate → generate summaries locally | Search API key (Brave, Tavily, etc.) |
| **Eir** | Full pipeline with delivery to Eir app | [Eir account](https://www.heyeir.com) + pairing code |
> **Important:** The two modes use different content formats and topic slug conventions. Choose the correct mode at setup time — switching later requires reconfiguration. If the user has an Eir account, use Eir mode.
Then follow the corresponding setup section below.
## Standalone Mode
### Flow
```
1. Configure → Set up search API + interests (one-time)
2. Search → Search API queries for each interest topic
3. Select + Crawl → Agent picks best candidates, fetches full content
4. Generate → Agent writes structured summaries from task files
5. Daily Brief → Agent compiles brief from generated items
```
> Steps 1-3 are Python scripts you run directly. Steps 4-5 are **agent-driven** — you tell your OpenClaw agent to read the task files and generate content. The agent uses whatever LLM model is configured in your OpenClaw session (e.g. Claude, GPT-4, Gemini).
### Quick Start
**1. Initialize workspace** — creates `config/` directory and default settings:
```bash
# Option A: inline JSON
python3 scripts/setup.py --init --settings '{
"mode": "standalone",
"language": "en",
"search": {
"search_base_url": "https://api.search.brave.com/res/v1",
"search_api_key": "YOUR_BRAVE_API_KEY"
}
}'
# Option B: settings file (recommended for PowerShell/Windows)
python3 scripts/setup.py --init --settings-file path/to/settings.json
```
```
Search provider examples:
| Provider | `search_base_url` | Get API key |
|----------|-------------------|-------------|
| Brave Search | `https://api.search.brave.com/res/v1` | [brave.com/search/api](https://brave.com/search/api/) |
| Tavily | `https://api.tavily.com` | [tavily.com](https://tavily.com/) |
> **Wa_meta.json
{
"ownerId": "kn76fghgn0qqq4e4qdknvea95s8222rw",
"slug": "eir-daily-content-curator",
"version": "3.119.0",
"publishedAt": 1777117038442
}references/candidates-spec.md
# Candidates JSON Format Specification
This document defines the expected format of `candidates.json`, which is the handoff point between candidate selection (agent-driven) and crawling/task building (automated scripts).
## Location
`data/v9/candidates.json`
## Structure
```json
{
"candidates": [
{
"content_slug": "string (required) — kebab-case identifier, 3-6 words, e.g. 'openai-gpt-5-launch'",
"matched_topic_slug": "string (required) — must match a directive slug, e.g. 'ai-industry-news'",
"suggested_angle": "string (required) — editorial angle in output language",
"reason": "string (optional) — why this candidate was selected",
"priority": "string (optional) — 'high' | 'medium' | 'low', default 'medium'",
"source_urls": [
"string (required, 1-5 URLs) — URLs to crawl for full content"
],
"source_titles": {
"https://example.com/article": "Article Title"
}
}
],
"selected_at": "ISO 8601 timestamp"
}
```
## Field Details
### Required Fields
| Field | Type | Description |
|-------|------|-------------|
| `content_slug` | string | Unique identifier for this content piece. Used as filename and API slug. Must be kebab-case, 3-6 words. |
| `matched_topic_slug` | string | The directive topic this belongs to. Must match a slug from directives/interests. Used as `topicSlug` in generated content. |
| `suggested_angle` | string | The editorial angle — what makes this worth covering. In the output language. |
| `source_urls` | string[] | 1-5 URLs to crawl. Prefer diverse domains. At least one must be crawlable. |
### Optional Fields
| Field | Type | Description |
|-------|------|-------------|
| `reason` | string | Why this candidate was selected (for audit trail). |
| `priority` | string | `high` / `medium` / `low`. Affects generation order. Default: `medium`. |
| `source_titles` | object | Map of URL → article title (helps crawl quality scoring). |
## Downstream Usage
1. **`crawl.py`** reads `candidates.json`, crawls each `source_urls` entry, saves content to `data/v9/snippets/{url_hash}.json`.
2. **`task_builder.py`** reads crawled candidates, bundles source text + writer prompt into task files at `data/v9/tasks/{content_slug}.json`.
## How Candidates Are Created
### Eir Mode (cron-driven)
The agent reads per-topic files from `data/v9/topics/`, evaluates search results, and writes `candidates.json` directly.
### Standalone Mode (manual)
1. Run `python3 -m pipeline.candidate_selector` → generates topic files in `data/v9/topics/`
2. Review topic files and create `candidates.json` following the format above
3. Run `python3 -m pipeline.crawl` → crawls candidate URLs
## Validation
- `content_slug` must be unique across all candidates
- `matched_topic_slug` should match a known directive/interest slug
- `source_urls` must contain at least 1 valid HTTP(S) URL
- No `null` values — use `""` or `[]` for empty fieldsreferences/content-spec.md
# Eir Content Specification
> Single source of truth for all content field constraints and quality criteria.
> Used by: writer prompts, API validation, front-end rendering.
## Contents
- [Field Reference](#field-reference) — dot, l1, l2, sources fields
- [via vs sources](#via-vs-sources) — Attribution handling
- [lang field](#lang-field) — Language requirements
- [Null handling](#null-handling)
- [Validation summary](#validation-summary)
- [Content ID format](#content-id-format)
- [Interest Signals](#interest-signals)
---
## Field Reference
### dot (L0 — the dot on canvas)
| Field | Type | Recommended | Hard Limit | Notes |
|-------|------|-------------|------------|-------|
| `hook` | string | ≤10 CJK chars / ≤6 EN words | **100 chars** (API rejects) | Creates curiosity gap. No hype words ("Breaking", "Exciting"). Rendered as single-line label on the dot. |
| `category` | enum | — | `focus` \| `attention` \| `seed` | Determines dot visual style. |
### l1 (card — what the user sees first)
| Field | Type | Recommended | Hard Limit | Notes |
|-------|------|-------------|------------|-------|
| `title` | string | 15-40 CJK chars / 8-15 EN words | **200 chars** (API rejects) | Opinionated, not a headline. Must be in `lang`. |
| `summary` | string | 50-80 words | — | 2-3 sentences. Advances beyond the title — don't repeat. |
| `key_quote` | string | 1 sentence | — | Best direct quote from sources. Use `""` if none. |
| `via` | **string[]** | — | — | **Must be an array.** Auto-derived from `sources[].name`. Pipeline populates it; API also falls back to `sources[].name` if empty. Writer should NOT set this. |
| `bullets` | string[] | 3-4 items | 10 items (API rejects) | Each: ≤20 CJK chars / ≤50 EN chars. Don't repeat summary. |
### l2 (depth — expanded view)
| Field | Type | Recommended | Hard Limit | Notes |
|-------|------|-------------|------------|-------|
| `content` | string | 200-600 CJK chars / 150-400 EN words | — | 2-4 paragraphs separated by `\n\n`. Starts where summary left off. |
| `bullets` | array | 3-5 items | — | Each: `{text: string, confidence: "high"\|"medium"\|"low"}`. Concrete facts with numbers/names. Every bullet must have supporting detail in `content`. |
| `context` | string | 1-2 sentences | — | Optional. "SO WHAT for the reader." Omit or leave empty if not needed. |
| `eir_take` | string | 1 sentence | — | Optional. Eir's sharp opinion. **PUBLIC** (visible on share pages) if included. |
| `related_topics` | string[] | 3-5 items | — | Human-readable phrases in `lang`. NOT slugs. e.g. `"Vector Search and ANN Algorithms"` ✅, `"vector-search-ann"` ❌ |
### sources (provenance — machine-readable)
| Field | Type | Required | Notes |
|-------|------|----------|-------|
| `url` | string | **Yes** | Must be valid URL. Used for server-side dedup — duplicate URLs are rejected. |
| `title` | string | No | Original article title. |
| `name` | string | No | Publisher/source name (e.g. "MIT Technology Review"). This is what `lreferences/eir-api.md
# Eir API Reference
**Base URL**: `https://api.heyeir.com/api` (override with `EIR_API_URL` environment variable)
**Authentication**: `Authorization: Bearer <EIR_API_KEY>` for all `/oc/*` endpoints.
## Contents
- [Connection](#connection) — Register/disconnect/rotate keys
- [Interests](#interests) — Manage user interests
- [Curation](#curation) — Fetch directives, report misses
- [Content](#content) — Push/read/delete content items
---
## Connection
### POST /oc/connect
Register with pairing code.
**Request:** `{ "code": "ABCD-1234" }`
**Response:** `{ "apiKey": "eir_oc_xxx", "userId": "u_abc123" }`
### DELETE /oc/connect
Disconnect and revoke API key.
### POST /oc/refresh-key
Rotate API key (60s grace period).
---
## Interests
### GET /oc/interests
Returns user interests.
**Response:**
```json
{
"user": { "id": "u_xxx", "primaryLanguage": "zh", "bilingual": false },
"interests": [
{
"id": "ui_abc1234",
"slug": "artificial-intelligence",
"label": "Artificial Intelligence",
"status": "active",
"heat": 5,
"strength": 0.6
}
]
}
```
### POST /oc/interests/add
Add interests by label. Server matches against dictionary.
**Request:** `{ "labels": ["AI Agents", "MCP"], "lang": "en" }`
**Response:** `{ "added": 2, "results": [...] }`
---
## Curation
### GET /oc/curation
Returns curation directives for content collection.
**Response:**
```json
{
"schema_version": "1.0",
"user": {
"primaryLanguage": "zh",
"bilingual": false
},
"directives": [
{
"slug": "mcp-protocol",
"label": "MCP Protocol",
"tier": "tracked",
"freshness": "7d",
"searchHints": ["MCP 2.0 announced", "Anthropic MCP ecosystem"],
"userNeeds": "Protocol updates and adoption",
"trackingGoal": "Stay current on protocol updates"
},
{
"slug": "ai-agents",
"label": "AI Agents",
"tier": "focus",
"freshness": "7d",
"searchHints": ["AI agent frameworks comparison", "autonomous agent production"],
"userNeeds": null,
"trackingGoal": null
}
],
"exclude": {
"disliked": ["crypto", "nft"]
}
}
```
**Tiers:** tracked → focus → explore → seed (informational labels; selection is score-based).
**Server-side curation:** The API handles topic selection, cooldown, and scoring internally. The agent just reads directives and finds content for them.
See `eir-interest-rules.md` for curation guidelines.
---
## Content
### POST /oc/content
Push generated content.
**Request:**
```json
{
"items": [
{
"slug": "mcp-protocol-2-0",
"lang": "en",
"interests": {
"anchor": ["mcp-protocol"],
"related": [{ "slug": "a2a-protocol", "label": "A2A Protocol" }]
},
"dot": {
"hook": "MCP 2.0 Released",
"category": "focus",
},
"l1": {
"title": "MCP Protocol v2.0",
"summary": "Anthropic releases MCP 2.0...",
"key_quote": "..."
},
AionUi
Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!
activepieces
AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents
cherry-studio
AI productivity studio with smart chat, autonomous agents, and 300+ assistants.
CopilotKit
The Frontend for Agents & Generative UI. React + Angular
Machine-readable data
The same record, as JSON, for agents and crawlers.
{
"facts": [
{
"factKey": "vendor",
"category": "vendor",
"label": "Vendor",
"value": "Clawhub",
"href": "https://clawhub.ai/heyeir/skills/eir-daily-content-curator",
"sourceUrl": "https://clawhub.ai/heyeir/skills/eir-daily-content-curator",
"sourceType": "profile",
"confidence": "medium",
"observedAt": "2026-10-11T18:05:42.716Z",
"isPublic": true
},
{
"factKey": "protocols",
"category": "compatibility",
"label": "Protocol compatibility",
"value": "OpenClaw",
"href": "https://www.xpersona.co/api/v1/agents/clawhub-heyeir-eir-daily-content-curator/contract",
"sourceUrl": "https://www.xpersona.co/api/v1/agents/clawhub-heyeir-eir-daily-content-curator/contract",
"sourceType": "contract",
"confidence": "medium",
"observedAt": "2026-10-11T18:05:42.716Z",
"isPublic": true
},
{
"factKey": "traction",
"category": "adoption",
"label": "Adoption signal",
"value": "1K downloads",
"href": "https://clawhub.ai/heyeir/eir-daily-content-curator",
"sourceUrl": "https://clawhub.ai/heyeir/eir-daily-content-curator",
"sourceType": "profile",
"confidence": "medium",
"observedAt": "2026-10-11T18:05:42.716Z",
"isPublic": true
},
{
"factKey": "latest_release",
"category": "release",
"label": "Latest release",
"value": "3.119.0",
"href": "https://clawhub.ai/heyeir/eir-daily-content-curator",
"sourceUrl": "https://clawhub.ai/heyeir/eir-daily-content-curator",
"sourceType": "release",
"confidence": "medium",
"observedAt": "2026-04-25T11:37:18.442Z",
"isPublic": true
},
{
"factKey": "handshake_status",
"category": "security",
"label": "Handshake status",
"value": "UNKNOWN",
"href": "https://www.xpersona.co/api/v1/agents/clawhub-heyeir-eir-daily-content-curator/trust",
"sourceUrl": "https://www.xpersona.co/api/v1/agents/clawhub-heyeir-eir-daily-content-curator/trust",
"sourceType": "trust",
"confidence": "medium",
"observedAt": null,
"isPublic": true
}
],
"events": [
{
"eventType": "release",
"title": "Release 3.119.0",
"description": "Bug fixes: API URL normalization, preflight crash, anchor slug validation, encoding fixes. Features: server-side dedup sync, title normalization, cross-language event dedup, API freshness pre-check, output language from API. Cleanup: removed unused translation code, content_slug hash fallback, unified publishTime naming. Docs improved for Job B workflow and multi-language contentGroup rules.",
"href": "https://clawhub.ai/heyeir/eir-daily-content-curator",
"sourceUrl": "https://clawhub.ai/heyeir/eir-daily-content-curator",
"sourceType": "release",
"confidence": "medium",
"observedAt": "2026-04-25T11:37:18.442Z",
"isPublic": true
}
]
}Record generated Oct 11, 2026.
