Skip to main content

cron-worker

Use when the user wants to create, configure, or migrate a dedicated cron-worker Hermes profile for scheduled/background tasks. Covers profile creation with symlink-based identity sharing (SOUL.md, memory), skill external_dirs configuration, model downgrade for cost savings, cron job migration, three heartbeat patterns (cron, signal/hook, change-detection), and artifact logging discipline. Triggers on: 创建cron-worker, 定时任务agent, 迁移cron job, cron profile, background agent profile, scheduled task worker, 后台任务profile, 分离定时任务. DO NOT use for one-off cron job creation or general Hermes config/debugging questions — use hermes-agent or hermes-setup instead.

跳到安装

来源信息

仓库
Loveacup/jz-skills
最近来源活动
2026年6月11日 22:23
检测到的 SKILL.md 语言
英语
星标
1
分支
1

安装方式

默认使用会先检查来源的 Prompt;你也可以切换为直接命令,或下载本地副本。

检查来源文件

决定是否安装前,请先阅读 SKILL.md,以及 SkillsMP 当前展示的配套文件。

文件资源管理器
6 个文件

正在显示 SKILL.md

SKILL.md
来源说明 · 只读预览
name
cron-worker
description
Use when the user wants to create, configure, or migrate a dedicated cron-worker Hermes profile for scheduled/background tasks. Covers profile creation with symlink-based identity sharing (SOUL.md, memory), skill external_dirs configuration, model downgrade for cost savings, cron job migration, three heartbeat patterns (cron, signal/hook, change-detection), and artifact logging discipline. Triggers on: 创建cron-worker, 定时任务agent, 迁移cron job, cron profile, background agent profile, scheduled task worker, 后台任务profile, 分离定时任务. DO NOT use for one-off cron job creation or general Hermes config/debugging questions — use hermes-agent or hermes-setup instead.
version
1.0.0
author
Hermes Agent + Alex
license
MIT
platforms
["macos","linux"]
metadata
{"hermes":{"tags":["hermes","cron","profile","worker","scheduled-tasks","background","cost-optimization"],"related_skills":["hermes-agent","hermes-setup","calendar-manager"]}}
# Cron-Worker Profile Create a dedicated Hermes profile for scheduled/background tasks — isolated sessions, cheaper model, shared identity with the default assistant. ## 🚨 Red Flags: DO NOT SKIP THIS SKILL | Excuse your brain will make | Why it's wrong | |------------------------------|----------------| | "I'll just create the profile and figure it out" | Symlink + external_dirs order matters. Wrong order = broken identity sync. Follow Step 2 exactly. | | "The cron job works fine on default, why move it" | Agent-mode cron jobs on default burn expensive models (v4-pro) for routine work. Moving to cron-worker with v4-flash cuts cost 60%+. | | "I don't need change-detection, cron is enough" | Blindly running every tick costs LLM tokens on 95% of ticks where nothing changed. A hash pre-check pays for itself within days. | | "I'll add the artifact log later" | Silent failures are indistinguishable from healthy idle. Without per-run logging, you're debugging by intuition. | ## 🔀 Decision Tree ``` User wants to set up cron/background task isolation? ├── Haven't audited existing cron jobs yet → Step 0: Audit first ├── New cron-worker profile → Step 1: Create profile ├── Existing profile, want to migrate jobs → Step 3: Migrate cron jobs ├── Already have cron-worker, want to add trigger pattern → Step 4: Heartbeat patterns ├── Cron job failed silently, want observability → Step 5: Artifact logging ├── Want to interact with cron-worker directly (DM the bot) → Step 2g: Optional gateway └── Just exploring the concept → Read the Obsidian doc first ``` ## Step 0: Audit Existing Cron Jobs **Before creating a worker profile, audit what's already running.** List all jobs and classify each one: ```bash hermes cron list ``` For each job, ask: - **Is it still needed?** → If no → `cronjob(action="remove", job_id="...")` - **Is it agent-mode or script-mode?** → Agent-mode = candidate for model downgrade - **Does it deliver to Telegram?** → May want to switch to `local` delivery - **Is it redundant?** (e.g., sync scripts superseded by Supermemory) > [!tip] 💡 本会话经验:从 4 个 cron job 开始,删掉 3 个(季度归档、memory sync、MCP 同步),只保留 1 个(每日日记),再设计 worker。先瘦身再建架构。 --- ## Step 1: Create the Cron-Worker Profile ```bash hermes profile create cron-worker --clone ``` This clones the current default profile (personality, skills, config, memory). ## Step 2: Set Up Identity Sharing (Symlink + External Dirs) **Order matters.** Do symlinks first, then external_dirs. ### 2a. SOUL.md — Symlink to Default ```bash rm ~/.hermes/profiles/cron-worker/SOUL.md ln -sf ~/.hermes/SOUL.md ~/.hermes/profiles/cron-worker/SOUL.md ``` Hermes explicitly supports SOUL.md symlinks (`utils.py:62-82`, GitHub #16743). Modifications write through to the original file. ### 2b. Memory — Symlink to Default ```bash rm -rf ~/.hermes/profiles/cron-worker/memories ln -sf ~/.hermes/memories ~/.hermes/profiles/cron-worker/memories ``` This syncs both MEMORY.md and USER.md. Corrections/preferences learned in default propagate to cron-worker. ### 2c. Skills — External Dirs (Prefer Over Symlink) Add to `~/.hermes/profiles/cron-worker/config.yaml`: ```yaml skills: external_dirs: - ~/.hermes/skills ``` `agent/skill_utils.py:241` — first-class feature. `os.walk(followlinks=True)` ensures symlinked skill dirs are followed. Cleaner than symlinking the entire skills/ directory — the curator won't accidentally touch externally-referenced skills, and cron-worker can still add its own. ### 2d. Long-Term Memory — Auto-Match Main Agent Cron-worker must share long-term memory with the default profile. Hermes supports two providers — auto-detect which one is active and mirror it. **Detection:** ```bash hermes memory status | awk '/^ Provider:/ {print $2}' ``` | Output | Provider | Action | |--------|----------|--------| | `provider: supermemory` | Supermemory | Copy config + ensure API key | | `provider: hindsight` | Hindsight | Copy config + use same `bank_id` | | `provider: ""` | None (built-in only) | Skip — built-in MEMORY.md already symlinked | #### If Supermemory ```bash # Copy config (same container_tag = same pool) cp ~/.hermes/supermemory.json ~/.hermes/profiles/cron-worker/supermemory.json # Ensure API key (if cron-worker has independent .env) grep -q SUPERMEMORY_API_KEY ~/.hermes/profiles/cron-worker/.env 2>/dev/null || \ grep SUPERMEMORY_API_KEY ~/.hermes/.env >> ~/.hermes/profiles/cron-worker/.env ``` Verify `container_tag` is `"hermes"` in the copied JSON. #### If Hindsight ```bash # Copy config cp ~/.hermes/hindsight/config.json ~/.hermes/profiles/cron-worker/hindsight/config.json # IMPORTANT: Change bank_id_template → bank_id to share the same bank # Edit ~/.hermes/profiles/cron-worker/hindsight/config.json: # Remove "bank_id_template": "hermes-{profile}" # Add "bank_id": "hermes" ``` Without this edit, `bank_id_template` auto-generates `"hermes-cron-worker"` — a separate bank, defeating the purpose. Explicit `bank_id: "hermes"` forces the same bank as default. Then enable: ```bash hermes --profile cron-worker config set memory.provider hindsight ``` **⚠️ Only one external provider is active at a time.** If you switch the main agent from Hindsight to Supermemory later, re-run this section for cron-worker. ### 2e. Model Selection > [!important] **MUST use `clarify()` here.** Ask the user which model to use for cron-worker. Do NOT assume v4-flash — the user may have specific cost/latency/quality preferences. **Clarify prompt template:** ``` question: "cron-worker 用什么模型?推荐 v4-flash(便宜 60%+,定时任务够用),也可以保持 v4-pro 或指定其他。" choices: - "deepseek-v4-flash(推荐,便宜量足)" - "deepseek-v4-pro(和主频道一样)" - "其他模型(我指定)" ``` **After user picks:** ```bash hermes --profile cron-worker config set model.default <chosen-model> ``` > [!tip] **Default recommendation:** `deepseek-v4-flash`. Routine cron tasks don't need reasoning — v4-flash is 60%+ cheaper than v4-pro. For script-mode jobs (`no_agent=true`), model is irrelevant, but still worth setting for agent-mode jobs. ### 2f. Verify ```bash hermes --profile cron-worker config show | grep -E "model|external" ls -la ~/.hermes/profiles/cron-worker/SOUL.md # should show symlink ``` ### 2g. Gateway Decision — Choose Communication Channel > [!important] **MUST use `clarify()` here.** After completing Steps 2a–2f, ask the user whether to add a gateway. Do NOT assume — the resource impact is meaningful, and a wrong choice wastes either a bot token or the ability to DM. **Clarify prompt template:** ``` question: "给 cron-worker 加独立 gateway 吗?加了可以 DM bot 交互、webhook 触发;不加更轻量,cron job 走 scheduler 投递。" choices: - "加 gateway,我去 @BotFather 创建新 bot" - "加 gateway,我已有 token 直接配" - "不加 gateway,cron-only 就够了" ``` **Full instructions → `references/gateway-decision.md`** — covers Path A (get token, write .env, install, verify, harmless errors, resource impact) and Path B (delivery mechanism, `deliver` target matrix, code examples, recommendation table). **Quick summary:** | Path | What you get | What you need | |------|-------------|---------------| | A: Add gateway | DM the bot, webhook triggers, direct Telegram interaction | Separate bot token, ~104MB RSS | | B: Skip gateway | Lighter, cron jobs deliver via scheduler (`deliver="origin"`) | Nothing extra | **Default recommendation:** start without gateway (Path B). Add anytime with `hermes --profile cron-worker gateway install`. --- ## Step 3: Migrate Existing Cron Jobs Use `cronjob(action="update", job_id="...", profile="cron-worker")` to reassign jobs. ```python cronjob(action="update", job_id="1ca6e7d692fa", profile="cron-worker") ``` Then verify: ```bash hermes cron list # should show profile: cron-worker ``` **⚠️ Delivery mechanism:** The default gateway's cron scheduler handles delivery for ALL cron jobs, regardless of which profile they run under. `deliver="origin"` routes output through the scheduler back to your Telegram — cron-worker does NOT need its own gateway for cron job delivery. Cron jobs are transient processes that fire on each tick; the gateway only matters if you want to DM the bot interactively (see Step 2g). --- ## Step 4: Three Heartbeat Patterns Reference: Knowlee *Heartbeat Patterns (2026)*. ### 4a. Cron Heartbeat — Time-Driven Standard Hermes cron. Best for fixed-cadence tasks where work is identical each cycle. ```python cronjob( action="create", name="daily-digest", schedule="0 23 * * *", prompt="Generate today's diary...", profile="cron-worker", model={"model": "deepseek-v4-flash", "provider": "deepseek"}, ) ``` ### 4b. Signal Heartbeat — Event-Driven (Hook) Use Hermes webhooks as the signal channel. External system POSTs → webhook endpoint → cron-worker handles. ```bash # Create webhook endpoint hermes --profile cron-worker webhook subscribe github-push ``` Then configure the external system (GitHub, CI, monitoring) to POST to the webhook URL. ### 4c. Change-Detection Heartbeat — State-Diff-Driven **Highest cost-saving leverage.** Run frequently, but only invoke the LLM when state changed. ```python cronjob( action="create", name="pipeline-monitor", schedule="*/15 * * * *", script="monitor-hash.py", # ← script runs first, output auto-prepended as "## Script Output" prompt="State changed. Analyze and alert if needed.", profile="cron-worker", model={"model": "deepseek-v4-flash", "provider": "deepseek"}, ) ``` The `script` runs first — its stdout is auto-prepended to the prompt as `## Script Output` by the scheduler. To skip the agent run when no change detected, the script's **last non-empty line** must be the JSON `{"wakeAgent": false}`. Any other output triggers the agent. See `scripts/change-detection.py` for a complete template with hash persistence. --- ## Step 5: Artifact Logging Every cron run must produce an artifact, even when the answer is "nothing to do." Without this, silent failures are indistinguishable from healthy idle. ### Minimum Viable Log Add this line to the END of every agent-mode cron prompt: ``` After completing (or determining no action is needed), append ONE line to ~/Obsidian/AlexCai/50-Self/01_日记/cron-artifact-log.md: - `[CRON] [YYYY-MM-DD HH:MM] [job_name] [OK|FAIL|SKIP] [key_metric] [action_taken]` ``` Example output: ```markdown - `[CRON] [2026-05-30 23:02] 每日日记草稿 OK 1 entry written` - `[CRON] [2026-05-31 06:00] pipeline-monitor SKIP no_change` - `[CRON] [2026-05-31 06:15] pipeline-monitor FAIL API timeout` ``` --- ## Pitfalls | Pitfall | Fix | |---------|-----| | Symlink replaced by profile update | `hermes profile create` writes fresh files. Re-apply symlinks after any profile recreation. | | external_dirs path uses `~` but not expanded | `agent/skill_utils.py:305` calls `os.path.expanduser()` — `~` is safe. | | Cron job still runs on default after update | Verify with `hermes cron list` — check the `profile` column. | | Gateway: when to add vs skip | Without gateway, cron jobs still deliver via scheduler (`deliver="origin"`). Add a gateway (Step 2g) only if you want to DM the bot interactively. Gateway requires a **separate Telegram bot token** — one gateway = one bot. Adds ~104MB RSS per gateway process. | | Gateway: api_server port 8460 conflict | Expected and harmless — default gateway already owns 8460. Telegram polling works without api_server. Ignore the error. | | Gateway: wrong bot token after profile clone | `hermes profile create --clone` copies default's TELEGRAM_BOT_TOKEN into cron-worker's .env. After cloning, always `grep -n TELEGRAM_BOT_TOKEN` and replace with the correct bot token. | | Change-detection script doesn't skip idle ticks | Script's last non-empty stdout line must be `{"wakeAgent": false}` JSON. Any other output wakes the agent. Empty stdout ALSO wakes the agent — do not rely on silence. | | `no_agent` script timeout blamed on the model | `no_agent=true` runs the script directly; null model/provider and empty prompt means GPT was never called. Diagnose child processes, cron output artifacts, and orphan PPID=1 processes first. See `references/no-agent-script-timeout-diagnosis.md`. | | Cron script uses `kill 0` in traps | When the scheduler runs scripts inside the gateway process group, `kill 0` can SIGTERM the gateway and trigger repeated "down" notifications. Use child-only cleanup such as `pkill -TERM -P $$ 2>/dev/null || true`; verify gateway PID and SIGTERM log count before/after a direct smoke run. | | `no_agent=true` script prints idle output | Non-empty stdout is delivered to the user every tick. In quiet mode, redirect noisy helper stdout to `/dev/null` and verify `stdout_len=0`; stderr may be kept for diagnostics, but successful idle runs should be stdout-silent. | | Cron script path passed as absolute path | `cronjob(action="create", script=...)` requires a path relative to `~/.hermes/scripts/` (e.g. `openwrt_watchdog.py`), not `/Users/.../.hermes/scripts/openwrt_watchdog.py` or `~/.hermes/scripts/...`. Place the script under `~/.hermes/scripts/` and pass only the filename/subpath. | | Profile-scoped cron script placed only in default scripts dir | When `cronjob(..., profile="cron-worker", script="foo.py")` is used, the scheduler resolves `foo.py` under `~/.hermes/profiles/cron-worker/scripts/`, not the default profile's `~/.hermes/scripts/`. Copy/install the script into the target profile's `scripts/` directory and run it once from that path before declaring the job healthy. | | Forgot to pin model on cron job | Always set `model` explicitly in `cronjob()` calls. Default model may be rate-limited or wrong tier. | | Hermes upgrade breaks symlinks | `hermes update` may refresh profile files. After any upgrade, re-run Step 2a-2b to re-apply SOUL.md + memory symlinks. | --- ## ✅ Verification Checklist (RUN AFTER SETUP)
在 GitHub 查看
这个 SKILL.md 很大,SkillsMP 这里只预览前一段内容。 在 GitHub 查看