Merge pull request #1343 from NousResearch/hermes/hermes-5d160594
feat: compress cron management into one tool
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
---
|
||||
sidebar_position: 11
|
||||
title: "Cron Internals"
|
||||
description: "How Hermes stores, schedules, locks, and delivers cron jobs"
|
||||
description: "How Hermes stores, schedules, edits, pauses, skill-loads, and delivers cron jobs"
|
||||
---
|
||||
|
||||
# Cron Internals
|
||||
@@ -10,7 +10,9 @@ Hermes cron support is implemented primarily in:
|
||||
|
||||
- `cron/jobs.py`
|
||||
- `cron/scheduler.py`
|
||||
- `tools/cronjob_tools.py`
|
||||
- `gateway/run.py`
|
||||
- `hermes_cli/cron.py`
|
||||
|
||||
## Scheduling model
|
||||
|
||||
@@ -21,9 +23,30 @@ Hermes supports:
|
||||
- cron expressions
|
||||
- explicit timestamps
|
||||
|
||||
The model-facing surface is a single `cronjob` tool with action-style operations:
|
||||
|
||||
- `create`
|
||||
- `list`
|
||||
- `update`
|
||||
- `pause`
|
||||
- `resume`
|
||||
- `run`
|
||||
- `remove`
|
||||
|
||||
## Job storage
|
||||
|
||||
Cron jobs are stored in Hermes-managed local state with atomic save/update semantics.
|
||||
Cron jobs are stored in Hermes-managed local state (`~/.hermes/cron/jobs.json`) with atomic write semantics.
|
||||
|
||||
Each job can carry:
|
||||
|
||||
- prompt
|
||||
- schedule metadata
|
||||
- repeat counters
|
||||
- delivery target
|
||||
- lifecycle state (`scheduled`, `paused`, `completed`, etc.)
|
||||
- zero, one, or multiple attached skills
|
||||
|
||||
Backward compatibility is preserved for older jobs that only stored a legacy single `skill` field or none of the newer lifecycle fields.
|
||||
|
||||
## Runtime behavior
|
||||
|
||||
@@ -32,11 +55,22 @@ The scheduler:
|
||||
- loads jobs
|
||||
- computes due work
|
||||
- executes jobs in fresh agent sessions
|
||||
- optionally injects one or more skills before the prompt
|
||||
- handles repeat counters
|
||||
- updates next-run metadata
|
||||
- updates next-run metadata and state
|
||||
|
||||
In gateway mode, cron ticking is integrated into the long-running gateway loop.
|
||||
|
||||
## Skill-backed jobs
|
||||
|
||||
A cron job may attach multiple skills. At runtime, Hermes loads those skills in order and then appends the job prompt as the task instruction.
|
||||
|
||||
This gives scheduled jobs reusable guidance without requiring the user to paste full skill bodies into the cron prompt.
|
||||
|
||||
## Recursion guard
|
||||
|
||||
Cron-run sessions disable the `cronjob` toolset. This prevents a scheduled job from recursively creating or mutating more cron jobs and accidentally exploding token usage or scheduler load.
|
||||
|
||||
## Delivery model
|
||||
|
||||
Cron jobs can deliver to:
|
||||
@@ -48,7 +82,7 @@ Cron jobs can deliver to:
|
||||
|
||||
## Locking
|
||||
|
||||
Hermes uses lock-based protections so concurrent cron ticks or overlapping scheduler processes do not corrupt job state.
|
||||
Hermes uses lock-based protections so overlapping scheduler ticks do not execute the same due-job batch twice.
|
||||
|
||||
## Related docs
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ and open source LLMs. Summarize the top 3 stories in a concise briefing
|
||||
with links. Use a friendly, professional tone. Deliver to telegram.
|
||||
```
|
||||
|
||||
Hermes will create the cron job for you using the `schedule_cronjob` tool.
|
||||
Hermes will create the cron job for you using the unified `cronjob` tool.
|
||||
|
||||
### Option B: CLI Slash Command
|
||||
|
||||
@@ -232,7 +232,7 @@ Or ask conversationally:
|
||||
Remove my morning briefing cron job.
|
||||
```
|
||||
|
||||
Hermes will use `list_cronjobs` to find it and `remove_cronjob` to delete it.
|
||||
Hermes will use `cronjob(action="list")` to find it and `cronjob(action="remove")` to delete it.
|
||||
|
||||
### Check Gateway Status
|
||||
|
||||
|
||||
@@ -181,12 +181,18 @@ hermes status [--all] [--deep]
|
||||
## `hermes cron`
|
||||
|
||||
```bash
|
||||
hermes cron <list|status|tick>
|
||||
hermes cron <list|create|edit|pause|resume|run|remove|status|tick>
|
||||
```
|
||||
|
||||
| Subcommand | Description |
|
||||
|------------|-------------|
|
||||
| `list` | Show scheduled jobs. |
|
||||
| `create` / `add` | Create a scheduled job from a prompt, optionally attaching one or more skills via repeated `--skill`. |
|
||||
| `edit` | Update a job's schedule, prompt, name, delivery, repeat count, or attached skills. Supports `--clear-skills`, `--add-skill`, and `--remove-skill`. |
|
||||
| `pause` | Pause a job without deleting it. |
|
||||
| `resume` | Resume a paused job and compute its next future run. |
|
||||
| `run` | Trigger a job on the next scheduler tick. |
|
||||
| `remove` | Delete a scheduled job. |
|
||||
| `status` | Check whether the cron scheduler is running. |
|
||||
| `tick` | Run due jobs once and exit. |
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ Type `/` in the CLI to open the autocomplete menu. Built-in commands are case-in
|
||||
| `/tools` | List available tools |
|
||||
| `/toolsets` | List available toolsets |
|
||||
| `/skills` | Search, install, inspect, or manage skills from online registries |
|
||||
| `/cron` | Manage scheduled tasks (list, add, remove) |
|
||||
| `/cron` | Manage scheduled tasks (list, add/create, edit, pause, resume, run, remove) |
|
||||
| `/reload-mcp` | Reload MCP servers from config.yaml |
|
||||
|
||||
### Info
|
||||
|
||||
@@ -40,9 +40,7 @@ This page documents the built-in Hermes tool registry as it exists in code. Avai
|
||||
|
||||
| Tool | Description | Requires environment |
|
||||
|------|-------------|----------------------|
|
||||
| `list_cronjobs` | List all scheduled cronjobs with their IDs, schedules, and status. Use this to: - See what jobs are currently scheduled - Find job IDs for removal with remove_cronjob - Check job status and next run times Returns job_id, name, schedule, re… | — |
|
||||
| `remove_cronjob` | Remove a scheduled cronjob by its ID. Use list_cronjobs first to find the job_id of the job you want to remove. Jobs that have completed their repeat count are auto-removed, but you can use this to cancel a job before it completes. | — |
|
||||
| `schedule_cronjob` | Schedule an automated task to run the agent on a schedule. ⚠️ CRITICAL: The cronjob runs in a FRESH SESSION with NO CONTEXT from this conversation. The prompt must be COMPLETELY SELF-CONTAINED with ALL necessary information including: - Fu… | — |
|
||||
| `cronjob` | Unified scheduled-task manager. Use `action="create"`, `"list"`, `"update"`, `"pause"`, `"resume"`, `"run"`, or `"remove"` to manage jobs. Supports skill-backed jobs with one or more attached skills, and `skills=[]` on update clears attached skills. Cron runs happen in fresh sessions with no current-chat context. | — |
|
||||
|
||||
## `delegation` toolset
|
||||
|
||||
|
||||
@@ -13,19 +13,19 @@ Toolsets are named bundles of tools that you can enable with `hermes chat --tool
|
||||
| `browser` | core | `browser_back`, `browser_click`, `browser_close`, `browser_get_images`, `browser_navigate`, `browser_press`, `browser_scroll`, `browser_snapshot`, `browser_type`, `browser_vision`, `web_search` |
|
||||
| `clarify` | core | `clarify` |
|
||||
| `code_execution` | core | `execute_code` |
|
||||
| `cronjob` | core | `list_cronjobs`, `remove_cronjob`, `schedule_cronjob` |
|
||||
| `cronjob` | core | `cronjob` |
|
||||
| `debugging` | composite | `patch`, `process`, `read_file`, `search_files`, `terminal`, `web_extract`, `web_search`, `write_file` |
|
||||
| `delegation` | core | `delegate_task` |
|
||||
| `file` | core | `patch`, `read_file`, `search_files`, `write_file` |
|
||||
| `hermes-cli` | platform | `browser_back`, `browser_click`, `browser_close`, `browser_get_images`, `browser_navigate`, `browser_press`, `browser_scroll`, `browser_snapshot`, `browser_type`, `browser_vision`, `clarify`, `delegate_task`, `execute_code`, `ha_call_service`, `ha_get_state`, `ha_list_entities`, `ha_list_services`, `honcho_conclude`, `honcho_context`, `honcho_profile`, `honcho_search`, `image_generate`, `list_cronjobs`, `memory`, `mixture_of_agents`, `patch`, `process`, `read_file`, `remove_cronjob`, `schedule_cronjob`, `search_files`, `send_message`, `session_search`, `skill_manage`, `skill_view`, `skills_list`, `terminal`, `text_to_speech`, `todo`, `vision_analyze`, `web_extract`, `web_search`, `write_file` |
|
||||
| `hermes-discord` | platform | `browser_back`, `browser_click`, `browser_close`, `browser_get_images`, `browser_navigate`, `browser_press`, `browser_scroll`, `browser_snapshot`, `browser_type`, `browser_vision`, `clarify`, `delegate_task`, `execute_code`, `ha_call_service`, `ha_get_state`, `ha_list_entities`, `ha_list_services`, `honcho_conclude`, `honcho_context`, `honcho_profile`, `honcho_search`, `image_generate`, `list_cronjobs`, `memory`, `mixture_of_agents`, `patch`, `process`, `read_file`, `remove_cronjob`, `schedule_cronjob`, `search_files`, `send_message`, `session_search`, `skill_manage`, `skill_view`, `skills_list`, `terminal`, `text_to_speech`, `todo`, `vision_analyze`, `web_extract`, `web_search`, `write_file` |
|
||||
| `hermes-email` | platform | `browser_back`, `browser_click`, `browser_close`, `browser_get_images`, `browser_navigate`, `browser_press`, `browser_scroll`, `browser_snapshot`, `browser_type`, `browser_vision`, `clarify`, `delegate_task`, `execute_code`, `ha_call_service`, `ha_get_state`, `ha_list_entities`, `ha_list_services`, `honcho_conclude`, `honcho_context`, `honcho_profile`, `honcho_search`, `image_generate`, `list_cronjobs`, `memory`, `mixture_of_agents`, `patch`, `process`, `read_file`, `remove_cronjob`, `schedule_cronjob`, `search_files`, `send_message`, `session_search`, `skill_manage`, `skill_view`, `skills_list`, `terminal`, `text_to_speech`, `todo`, `vision_analyze`, `web_extract`, `web_search`, `write_file` |
|
||||
| `hermes-gateway` | platform | `browser_back`, `browser_click`, `browser_close`, `browser_get_images`, `browser_navigate`, `browser_press`, `browser_scroll`, `browser_snapshot`, `browser_type`, `browser_vision`, `clarify`, `delegate_task`, `execute_code`, `ha_call_service`, `ha_get_state`, `ha_list_entities`, `ha_list_services`, `honcho_conclude`, `honcho_context`, `honcho_profile`, `honcho_search`, `image_generate`, `list_cronjobs`, `memory`, `mixture_of_agents`, `patch`, `process`, `read_file`, `remove_cronjob`, `schedule_cronjob`, `search_files`, `send_message`, `session_search`, `skill_manage`, `skill_view`, `skills_list`, `terminal`, `text_to_speech`, `todo`, `vision_analyze`, `web_extract`, `web_search`, `write_file` |
|
||||
| `hermes-homeassistant` | platform | `browser_back`, `browser_click`, `browser_close`, `browser_get_images`, `browser_navigate`, `browser_press`, `browser_scroll`, `browser_snapshot`, `browser_type`, `browser_vision`, `clarify`, `delegate_task`, `execute_code`, `ha_call_service`, `ha_get_state`, `ha_list_entities`, `ha_list_services`, `honcho_conclude`, `honcho_context`, `honcho_profile`, `honcho_search`, `image_generate`, `list_cronjobs`, `memory`, `mixture_of_agents`, `patch`, `process`, `read_file`, `remove_cronjob`, `schedule_cronjob`, `search_files`, `send_message`, `session_search`, `skill_manage`, `skill_view`, `skills_list`, `terminal`, `text_to_speech`, `todo`, `vision_analyze`, `web_extract`, `web_search`, `write_file` |
|
||||
| `hermes-signal` | platform | `browser_back`, `browser_click`, `browser_close`, `browser_get_images`, `browser_navigate`, `browser_press`, `browser_scroll`, `browser_snapshot`, `browser_type`, `browser_vision`, `clarify`, `delegate_task`, `execute_code`, `ha_call_service`, `ha_get_state`, `ha_list_entities`, `ha_list_services`, `honcho_conclude`, `honcho_context`, `honcho_profile`, `honcho_search`, `image_generate`, `list_cronjobs`, `memory`, `mixture_of_agents`, `patch`, `process`, `read_file`, `remove_cronjob`, `schedule_cronjob`, `search_files`, `send_message`, `session_search`, `skill_manage`, `skill_view`, `skills_list`, `terminal`, `text_to_speech`, `todo`, `vision_analyze`, `web_extract`, `web_search`, `write_file` |
|
||||
| `hermes-slack` | platform | `browser_back`, `browser_click`, `browser_close`, `browser_get_images`, `browser_navigate`, `browser_press`, `browser_scroll`, `browser_snapshot`, `browser_type`, `browser_vision`, `clarify`, `delegate_task`, `execute_code`, `ha_call_service`, `ha_get_state`, `ha_list_entities`, `ha_list_services`, `honcho_conclude`, `honcho_context`, `honcho_profile`, `honcho_search`, `image_generate`, `list_cronjobs`, `memory`, `mixture_of_agents`, `patch`, `process`, `read_file`, `remove_cronjob`, `schedule_cronjob`, `search_files`, `send_message`, `session_search`, `skill_manage`, `skill_view`, `skills_list`, `terminal`, `text_to_speech`, `todo`, `vision_analyze`, `web_extract`, `web_search`, `write_file` |
|
||||
| `hermes-telegram` | platform | `browser_back`, `browser_click`, `browser_close`, `browser_get_images`, `browser_navigate`, `browser_press`, `browser_scroll`, `browser_snapshot`, `browser_type`, `browser_vision`, `clarify`, `delegate_task`, `execute_code`, `ha_call_service`, `ha_get_state`, `ha_list_entities`, `ha_list_services`, `honcho_conclude`, `honcho_context`, `honcho_profile`, `honcho_search`, `image_generate`, `list_cronjobs`, `memory`, `mixture_of_agents`, `patch`, `process`, `read_file`, `remove_cronjob`, `schedule_cronjob`, `search_files`, `send_message`, `session_search`, `skill_manage`, `skill_view`, `skills_list`, `terminal`, `text_to_speech`, `todo`, `vision_analyze`, `web_extract`, `web_search`, `write_file` |
|
||||
| `hermes-whatsapp` | platform | `browser_back`, `browser_click`, `browser_close`, `browser_get_images`, `browser_navigate`, `browser_press`, `browser_scroll`, `browser_snapshot`, `browser_type`, `browser_vision`, `clarify`, `delegate_task`, `execute_code`, `ha_call_service`, `ha_get_state`, `ha_list_entities`, `ha_list_services`, `honcho_conclude`, `honcho_context`, `honcho_profile`, `honcho_search`, `image_generate`, `list_cronjobs`, `memory`, `mixture_of_agents`, `patch`, `process`, `read_file`, `remove_cronjob`, `schedule_cronjob`, `search_files`, `send_message`, `session_search`, `skill_manage`, `skill_view`, `skills_list`, `terminal`, `text_to_speech`, `todo`, `vision_analyze`, `web_extract`, `web_search`, `write_file` |
|
||||
| `hermes-cli` | platform | `browser_back`, `browser_click`, `browser_close`, `browser_get_images`, `browser_navigate`, `browser_press`, `browser_scroll`, `browser_snapshot`, `browser_type`, `browser_vision`, `clarify`, `delegate_task`, `execute_code`, `ha_call_service`, `ha_get_state`, `ha_list_entities`, `ha_list_services`, `honcho_conclude`, `honcho_context`, `honcho_profile`, `honcho_search`, `image_generate`, `cronjob`, `memory`, `mixture_of_agents`, `patch`, `process`, `read_file`, `search_files`, `send_message`, `session_search`, `skill_manage`, `skill_view`, `skills_list`, `terminal`, `text_to_speech`, `todo`, `vision_analyze`, `web_extract`, `web_search`, `write_file` |
|
||||
| `hermes-discord` | platform | `browser_back`, `browser_click`, `browser_close`, `browser_get_images`, `browser_navigate`, `browser_press`, `browser_scroll`, `browser_snapshot`, `browser_type`, `browser_vision`, `clarify`, `delegate_task`, `execute_code`, `ha_call_service`, `ha_get_state`, `ha_list_entities`, `ha_list_services`, `honcho_conclude`, `honcho_context`, `honcho_profile`, `honcho_search`, `image_generate`, `cronjob`, `memory`, `mixture_of_agents`, `patch`, `process`, `read_file`, `search_files`, `send_message`, `session_search`, `skill_manage`, `skill_view`, `skills_list`, `terminal`, `text_to_speech`, `todo`, `vision_analyze`, `web_extract`, `web_search`, `write_file` |
|
||||
| `hermes-email` | platform | `browser_back`, `browser_click`, `browser_close`, `browser_get_images`, `browser_navigate`, `browser_press`, `browser_scroll`, `browser_snapshot`, `browser_type`, `browser_vision`, `clarify`, `delegate_task`, `execute_code`, `ha_call_service`, `ha_get_state`, `ha_list_entities`, `ha_list_services`, `honcho_conclude`, `honcho_context`, `honcho_profile`, `honcho_search`, `image_generate`, `cronjob`, `memory`, `mixture_of_agents`, `patch`, `process`, `read_file`, `search_files`, `send_message`, `session_search`, `skill_manage`, `skill_view`, `skills_list`, `terminal`, `text_to_speech`, `todo`, `vision_analyze`, `web_extract`, `web_search`, `write_file` |
|
||||
| `hermes-gateway` | platform | `browser_back`, `browser_click`, `browser_close`, `browser_get_images`, `browser_navigate`, `browser_press`, `browser_scroll`, `browser_snapshot`, `browser_type`, `browser_vision`, `clarify`, `delegate_task`, `execute_code`, `ha_call_service`, `ha_get_state`, `ha_list_entities`, `ha_list_services`, `honcho_conclude`, `honcho_context`, `honcho_profile`, `honcho_search`, `image_generate`, `cronjob`, `memory`, `mixture_of_agents`, `patch`, `process`, `read_file`, `search_files`, `send_message`, `session_search`, `skill_manage`, `skill_view`, `skills_list`, `terminal`, `text_to_speech`, `todo`, `vision_analyze`, `web_extract`, `web_search`, `write_file` |
|
||||
| `hermes-homeassistant` | platform | `browser_back`, `browser_click`, `browser_close`, `browser_get_images`, `browser_navigate`, `browser_press`, `browser_scroll`, `browser_snapshot`, `browser_type`, `browser_vision`, `clarify`, `delegate_task`, `execute_code`, `ha_call_service`, `ha_get_state`, `ha_list_entities`, `ha_list_services`, `honcho_conclude`, `honcho_context`, `honcho_profile`, `honcho_search`, `image_generate`, `cronjob`, `memory`, `mixture_of_agents`, `patch`, `process`, `read_file`, `search_files`, `send_message`, `session_search`, `skill_manage`, `skill_view`, `skills_list`, `terminal`, `text_to_speech`, `todo`, `vision_analyze`, `web_extract`, `web_search`, `write_file` |
|
||||
| `hermes-signal` | platform | `browser_back`, `browser_click`, `browser_close`, `browser_get_images`, `browser_navigate`, `browser_press`, `browser_scroll`, `browser_snapshot`, `browser_type`, `browser_vision`, `clarify`, `delegate_task`, `execute_code`, `ha_call_service`, `ha_get_state`, `ha_list_entities`, `ha_list_services`, `honcho_conclude`, `honcho_context`, `honcho_profile`, `honcho_search`, `image_generate`, `cronjob`, `memory`, `mixture_of_agents`, `patch`, `process`, `read_file`, `search_files`, `send_message`, `session_search`, `skill_manage`, `skill_view`, `skills_list`, `terminal`, `text_to_speech`, `todo`, `vision_analyze`, `web_extract`, `web_search`, `write_file` |
|
||||
| `hermes-slack` | platform | `browser_back`, `browser_click`, `browser_close`, `browser_get_images`, `browser_navigate`, `browser_press`, `browser_scroll`, `browser_snapshot`, `browser_type`, `browser_vision`, `clarify`, `delegate_task`, `execute_code`, `ha_call_service`, `ha_get_state`, `ha_list_entities`, `ha_list_services`, `honcho_conclude`, `honcho_context`, `honcho_profile`, `honcho_search`, `image_generate`, `cronjob`, `memory`, `mixture_of_agents`, `patch`, `process`, `read_file`, `search_files`, `send_message`, `session_search`, `skill_manage`, `skill_view`, `skills_list`, `terminal`, `text_to_speech`, `todo`, `vision_analyze`, `web_extract`, `web_search`, `write_file` |
|
||||
| `hermes-telegram` | platform | `browser_back`, `browser_click`, `browser_close`, `browser_get_images`, `browser_navigate`, `browser_press`, `browser_scroll`, `browser_snapshot`, `browser_type`, `browser_vision`, `clarify`, `delegate_task`, `execute_code`, `ha_call_service`, `ha_get_state`, `ha_list_entities`, `ha_list_services`, `honcho_conclude`, `honcho_context`, `honcho_profile`, `honcho_search`, `image_generate`, `cronjob`, `memory`, `mixture_of_agents`, `patch`, `process`, `read_file`, `search_files`, `send_message`, `session_search`, `skill_manage`, `skill_view`, `skills_list`, `terminal`, `text_to_speech`, `todo`, `vision_analyze`, `web_extract`, `web_search`, `write_file` |
|
||||
| `hermes-whatsapp` | platform | `browser_back`, `browser_click`, `browser_close`, `browser_get_images`, `browser_navigate`, `browser_press`, `browser_scroll`, `browser_snapshot`, `browser_type`, `browser_vision`, `clarify`, `delegate_task`, `execute_code`, `ha_call_service`, `ha_get_state`, `ha_list_entities`, `ha_list_services`, `honcho_conclude`, `honcho_context`, `honcho_profile`, `honcho_search`, `image_generate`, `cronjob`, `memory`, `mixture_of_agents`, `patch`, `process`, `read_file`, `search_files`, `send_message`, `session_search`, `skill_manage`, `skill_view`, `skills_list`, `terminal`, `text_to_speech`, `todo`, `vision_analyze`, `web_extract`, `web_search`, `write_file` |
|
||||
| `homeassistant` | core | `ha_call_service`, `ha_get_state`, `ha_list_entities`, `ha_list_services` |
|
||||
| `honcho` | core | `honcho_conclude`, `honcho_context`, `honcho_profile`, `honcho_search` |
|
||||
| `image_gen` | core | `image_generate` |
|
||||
|
||||
@@ -1,68 +1,183 @@
|
||||
---
|
||||
sidebar_position: 5
|
||||
title: "Scheduled Tasks (Cron)"
|
||||
description: "Schedule automated tasks with natural language — cron jobs, delivery options, and the gateway scheduler"
|
||||
description: "Schedule automated tasks with natural language, manage them with one cron tool, and attach one or more skills"
|
||||
---
|
||||
|
||||
# Scheduled Tasks (Cron)
|
||||
|
||||
Schedule tasks to run automatically with natural language or cron expressions. The agent can self-schedule using the `schedule_cronjob` tool from any platform.
|
||||
Schedule tasks to run automatically with natural language or cron expressions. Hermes exposes cron management through a single `cronjob` tool with action-style operations instead of separate schedule/list/remove tools.
|
||||
|
||||
## Creating Scheduled Tasks
|
||||
## What cron can do now
|
||||
|
||||
### In the CLI
|
||||
Cron jobs can:
|
||||
|
||||
Use the `/cron` slash command:
|
||||
- schedule one-shot or recurring tasks
|
||||
- pause, resume, edit, trigger, and remove jobs
|
||||
- attach zero, one, or multiple skills to a job
|
||||
- deliver results back to the origin chat, local files, or configured platform targets
|
||||
- run in fresh agent sessions with the normal static tool list
|
||||
|
||||
```
|
||||
:::warning
|
||||
Cron-run sessions cannot recursively create more cron jobs. Hermes disables cron management tools inside cron executions to prevent runaway scheduling loops.
|
||||
:::
|
||||
|
||||
## Creating scheduled tasks
|
||||
|
||||
### In chat with `/cron`
|
||||
|
||||
```bash
|
||||
/cron add 30m "Remind me to check the build"
|
||||
/cron add "every 2h" "Check server status"
|
||||
/cron add "0 9 * * *" "Morning briefing"
|
||||
/cron list
|
||||
/cron remove <job_id>
|
||||
/cron add "every 1h" "Summarize new feed items" --skill blogwatcher
|
||||
/cron add "every 1h" "Use both skills and combine the result" --skill blogwatcher --skill find-nearby
|
||||
```
|
||||
|
||||
### Through Natural Conversation
|
||||
|
||||
Simply ask the agent on any platform:
|
||||
### From the standalone CLI
|
||||
|
||||
```bash
|
||||
hermes cron create "every 2h" "Check server status"
|
||||
hermes cron create "every 1h" "Summarize new feed items" --skill blogwatcher
|
||||
hermes cron create "every 1h" "Use both skills and combine the result" \
|
||||
--skill blogwatcher \
|
||||
--skill find-nearby \
|
||||
--name "Skill combo"
|
||||
```
|
||||
|
||||
### Through natural conversation
|
||||
|
||||
Ask Hermes normally:
|
||||
|
||||
```text
|
||||
Every morning at 9am, check Hacker News for AI news and send me a summary on Telegram.
|
||||
```
|
||||
|
||||
The agent will use the `schedule_cronjob` tool to set it up.
|
||||
Hermes will use the unified `cronjob` tool internally.
|
||||
|
||||
## How It Works
|
||||
## Skill-backed cron jobs
|
||||
|
||||
**Cron execution is handled by the gateway daemon.** The gateway ticks the scheduler every 60 seconds, running any due jobs in isolated agent sessions:
|
||||
A cron job can load one or more skills before it runs the prompt.
|
||||
|
||||
### Single skill
|
||||
|
||||
```python
|
||||
cronjob(
|
||||
action="create",
|
||||
skill="blogwatcher",
|
||||
prompt="Check the configured feeds and summarize anything new.",
|
||||
schedule="0 9 * * *",
|
||||
name="Morning feeds",
|
||||
)
|
||||
```
|
||||
|
||||
### Multiple skills
|
||||
|
||||
Skills are loaded in order. The prompt becomes the task instruction layered on top of those skills.
|
||||
|
||||
```python
|
||||
cronjob(
|
||||
action="create",
|
||||
skills=["blogwatcher", "find-nearby"],
|
||||
prompt="Look for new local events and interesting nearby places, then combine them into one short brief.",
|
||||
schedule="every 6h",
|
||||
name="Local brief",
|
||||
)
|
||||
```
|
||||
|
||||
This is useful when you want a scheduled agent to inherit reusable workflows without stuffing the full skill text into the cron prompt itself.
|
||||
|
||||
## Editing jobs
|
||||
|
||||
You do not need to delete and recreate jobs just to change them.
|
||||
|
||||
### Chat
|
||||
|
||||
```bash
|
||||
/cron edit <job_id> --schedule "every 4h"
|
||||
/cron edit <job_id> --prompt "Use the revised task"
|
||||
/cron edit <job_id> --skill blogwatcher --skill find-nearby
|
||||
/cron edit <job_id> --remove-skill blogwatcher
|
||||
/cron edit <job_id> --clear-skills
|
||||
```
|
||||
|
||||
### Standalone CLI
|
||||
|
||||
```bash
|
||||
hermes cron edit <job_id> --schedule "every 4h"
|
||||
hermes cron edit <job_id> --prompt "Use the revised task"
|
||||
hermes cron edit <job_id> --skill blogwatcher --skill find-nearby
|
||||
hermes cron edit <job_id> --add-skill find-nearby
|
||||
hermes cron edit <job_id> --remove-skill blogwatcher
|
||||
hermes cron edit <job_id> --clear-skills
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
- repeated `--skill` replaces the job's attached skill list
|
||||
- `--add-skill` appends to the existing list without replacing it
|
||||
- `--remove-skill` removes specific attached skills
|
||||
- `--clear-skills` removes all attached skills
|
||||
|
||||
## Lifecycle actions
|
||||
|
||||
Cron jobs now have a fuller lifecycle than just create/remove.
|
||||
|
||||
### Chat
|
||||
|
||||
```bash
|
||||
/cron list
|
||||
/cron pause <job_id>
|
||||
/cron resume <job_id>
|
||||
/cron run <job_id>
|
||||
/cron remove <job_id>
|
||||
```
|
||||
|
||||
### Standalone CLI
|
||||
|
||||
```bash
|
||||
hermes cron list
|
||||
hermes cron pause <job_id>
|
||||
hermes cron resume <job_id>
|
||||
hermes cron run <job_id>
|
||||
hermes cron remove <job_id>
|
||||
hermes cron status
|
||||
hermes cron tick
|
||||
```
|
||||
|
||||
What they do:
|
||||
|
||||
- `pause` — keep the job but stop scheduling it
|
||||
- `resume` — re-enable the job and compute the next future run
|
||||
- `run` — trigger the job on the next scheduler tick
|
||||
- `remove` — delete it entirely
|
||||
|
||||
## How it works
|
||||
|
||||
**Cron execution is handled by the gateway daemon.** The gateway ticks the scheduler every 60 seconds, running any due jobs in isolated agent sessions.
|
||||
|
||||
```bash
|
||||
hermes gateway install # Install as system service (recommended)
|
||||
hermes gateway # Or run in foreground
|
||||
|
||||
hermes cron list # View scheduled jobs
|
||||
hermes cron status # Check if gateway is running
|
||||
hermes cron list
|
||||
hermes cron status
|
||||
```
|
||||
|
||||
### The Gateway Scheduler
|
||||
### Gateway scheduler behavior
|
||||
|
||||
The scheduler runs as a background thread inside the gateway process. On each tick (every 60 seconds):
|
||||
On each tick Hermes:
|
||||
|
||||
1. It loads all jobs from `~/.hermes/cron/jobs.json`
|
||||
2. Checks each enabled job's `next_run_at` against the current time
|
||||
3. For each due job, spawns a fresh `AIAgent` session with the job's prompt
|
||||
4. The agent runs to completion with full tool access
|
||||
5. The final response is delivered to the configured target
|
||||
6. The job's run count is incremented and next run time computed
|
||||
7. Jobs that hit their repeat limit are auto-removed
|
||||
1. loads jobs from `~/.hermes/cron/jobs.json`
|
||||
2. checks `next_run_at` against the current time
|
||||
3. starts a fresh `AIAgent` session for each due job
|
||||
4. optionally injects one or more attached skills into that fresh session
|
||||
5. runs the prompt to completion
|
||||
6. delivers the final response
|
||||
7. updates run metadata and the next scheduled time
|
||||
|
||||
A **file-based lock** (`~/.hermes/cron/.tick.lock`) prevents duplicate execution if multiple processes overlap (e.g., gateway + manual tick).
|
||||
A file lock at `~/.hermes/cron/.tick.lock` prevents overlapping scheduler ticks from double-running the same job batch.
|
||||
|
||||
:::info
|
||||
Even if no messaging platforms are configured, the gateway stays running for cron. A file lock prevents duplicate execution if multiple processes overlap.
|
||||
:::
|
||||
|
||||
## Delivery Options
|
||||
## Delivery options
|
||||
|
||||
When scheduling jobs, you specify where the output goes:
|
||||
|
||||
@@ -70,48 +185,36 @@ When scheduling jobs, you specify where the output goes:
|
||||
|--------|-------------|---------|
|
||||
| `"origin"` | Back to where the job was created | Default on messaging platforms |
|
||||
| `"local"` | Save to local files only (`~/.hermes/cron/output/`) | Default on CLI |
|
||||
| `"telegram"` | Telegram home channel | Uses `TELEGRAM_HOME_CHANNEL` env var |
|
||||
| `"discord"` | Discord home channel | Uses `DISCORD_HOME_CHANNEL` env var |
|
||||
| `"telegram:123456"` | Specific Telegram chat by ID | For directing output to a specific chat |
|
||||
| `"discord:987654"` | Specific Discord channel by ID | For directing output to a specific channel |
|
||||
| `"telegram"` | Telegram home channel | Uses `TELEGRAM_HOME_CHANNEL` |
|
||||
| `"discord"` | Discord home channel | Uses `DISCORD_HOME_CHANNEL` |
|
||||
| `"telegram:123456"` | Specific Telegram chat by ID | Direct delivery |
|
||||
| `"discord:987654"` | Specific Discord channel by ID | Direct delivery |
|
||||
|
||||
**How `"origin"` works:** When a job is created from a messaging platform, Hermes records the source platform and chat ID. When the job runs and deliver is `"origin"`, the output is sent back to that exact platform and chat. If origin info isn't available (e.g., job created from CLI), delivery falls back to local.
|
||||
The agent's final response is automatically delivered. You do not need to call `send_message` in the cron prompt.
|
||||
|
||||
**How platform names work:** When you specify a bare platform name like `"telegram"`, Hermes first checks if the job's origin matches that platform and uses the origin chat ID. Otherwise, it falls back to the platform's home channel configured via environment variable (e.g., `TELEGRAM_HOME_CHANNEL`).
|
||||
## Schedule formats
|
||||
|
||||
The agent's final response is automatically delivered — you do **not** need to include `send_message` in the cron prompt for that same destination. If a cron run calls `send_message` to the exact target the scheduler will already deliver to, Hermes skips that duplicate send and tells the model to put the user-facing content in the final response instead. Use `send_message` only for additional or different targets.
|
||||
|
||||
The agent knows your connected platforms and home channels — it'll choose sensible defaults.
|
||||
### Relative delays (one-shot)
|
||||
|
||||
## Schedule Formats
|
||||
|
||||
### Relative Delays (One-Shot)
|
||||
|
||||
Run once after a delay:
|
||||
|
||||
```
|
||||
```text
|
||||
30m → Run once in 30 minutes
|
||||
2h → Run once in 2 hours
|
||||
1d → Run once in 1 day
|
||||
```
|
||||
|
||||
Supported units: `m`/`min`/`minutes`, `h`/`hr`/`hours`, `d`/`day`/`days`.
|
||||
### Intervals (recurring)
|
||||
|
||||
### Intervals (Recurring)
|
||||
|
||||
Run repeatedly at fixed intervals:
|
||||
|
||||
```
|
||||
```text
|
||||
every 30m → Every 30 minutes
|
||||
every 2h → Every 2 hours
|
||||
every 1d → Every day
|
||||
```
|
||||
|
||||
### Cron Expressions
|
||||
### Cron expressions
|
||||
|
||||
Standard 5-field cron syntax for precise scheduling:
|
||||
|
||||
```
|
||||
```text
|
||||
0 9 * * * → Daily at 9:00 AM
|
||||
0 9 * * 1-5 → Weekdays at 9:00 AM
|
||||
0 */6 * * * → Every 6 hours
|
||||
@@ -119,155 +222,63 @@ Standard 5-field cron syntax for precise scheduling:
|
||||
0 0 * * 0 → Every Sunday at midnight
|
||||
```
|
||||
|
||||
#### Cron Expression Cheat Sheet
|
||||
### ISO timestamps
|
||||
|
||||
```
|
||||
┌───── minute (0-59)
|
||||
│ ┌───── hour (0-23)
|
||||
│ │ ┌───── day of month (1-31)
|
||||
│ │ │ ┌───── month (1-12)
|
||||
│ │ │ │ ┌───── day of week (0-7, 0 and 7 = Sunday)
|
||||
│ │ │ │ │
|
||||
* * * * *
|
||||
|
||||
Special characters:
|
||||
* Any value
|
||||
, List separator (1,3,5)
|
||||
- Range (1-5)
|
||||
/ Step values (*/15 = every 15)
|
||||
```
|
||||
|
||||
:::note
|
||||
Cron expressions require the `croniter` Python package. Install with `pip install croniter` if not already available.
|
||||
:::
|
||||
|
||||
### ISO Timestamps
|
||||
|
||||
Run once at a specific date/time:
|
||||
|
||||
```
|
||||
```text
|
||||
2026-03-15T09:00:00 → One-time at March 15, 2026 9:00 AM
|
||||
```
|
||||
|
||||
## Repeat Behavior
|
||||
## Repeat behavior
|
||||
|
||||
The `repeat` parameter controls how many times a job runs:
|
||||
|
||||
| Schedule Type | Default Repeat | Behavior |
|
||||
| Schedule type | Default repeat | Behavior |
|
||||
|--------------|----------------|----------|
|
||||
| One-shot (`30m`, timestamp) | 1 (run once) | Runs once, then auto-deleted |
|
||||
| Interval (`every 2h`) | Forever (`null`) | Runs indefinitely until removed |
|
||||
| Cron expression | Forever (`null`) | Runs indefinitely until removed |
|
||||
| One-shot (`30m`, timestamp) | 1 | Runs once |
|
||||
| Interval (`every 2h`) | forever | Runs until removed |
|
||||
| Cron expression | forever | Runs until removed |
|
||||
|
||||
You can override the default:
|
||||
You can override it:
|
||||
|
||||
```python
|
||||
schedule_cronjob(
|
||||
cronjob(
|
||||
action="create",
|
||||
prompt="...",
|
||||
schedule="every 2h",
|
||||
repeat=5 # Run exactly 5 times, then auto-delete
|
||||
repeat=5,
|
||||
)
|
||||
```
|
||||
|
||||
When a job hits its repeat limit, it is automatically removed from the job list.
|
||||
## Managing jobs programmatically
|
||||
|
||||
## Real-World Examples
|
||||
|
||||
### Daily Standup Report
|
||||
|
||||
```
|
||||
Schedule a daily standup report: Every weekday at 9am, check the GitHub
|
||||
repository at github.com/myorg/myproject for:
|
||||
1. Pull requests opened/merged in the last 24 hours
|
||||
2. Issues created or closed
|
||||
3. Any CI/CD failures on the main branch
|
||||
Format as a brief standup-style summary. Deliver to telegram.
|
||||
```
|
||||
|
||||
The agent creates:
|
||||
```python
|
||||
schedule_cronjob(
|
||||
prompt="Check github.com/myorg/myproject for PRs, issues, and CI status from the last 24 hours. Format as a standup report.",
|
||||
schedule="0 9 * * 1-5",
|
||||
name="Daily Standup Report",
|
||||
deliver="telegram"
|
||||
)
|
||||
```
|
||||
|
||||
### Weekly Backup Verification
|
||||
|
||||
```
|
||||
Every Sunday at 2am, verify that backups exist in /data/backups/ for
|
||||
each day of the past week. Check file sizes are > 1MB. Report any
|
||||
gaps or suspiciously small files.
|
||||
```
|
||||
|
||||
### Monitoring Alerts
|
||||
|
||||
```
|
||||
Every 15 minutes, curl https://api.myservice.com/health and verify
|
||||
it returns HTTP 200 with {"status": "ok"}. If it fails, include the
|
||||
error details and response code. Deliver to telegram:123456789.
|
||||
```
|
||||
The agent-facing API is one tool:
|
||||
|
||||
```python
|
||||
schedule_cronjob(
|
||||
prompt="Run 'curl -s -o /dev/null -w \"%{http_code}\" https://api.myservice.com/health' and verify it returns 200. Also fetch the full response with 'curl -s https://api.myservice.com/health' and check for {\"status\": \"ok\"}. Report the result.",
|
||||
schedule="every 15m",
|
||||
name="API Health Check",
|
||||
deliver="telegram:123456789"
|
||||
)
|
||||
cronjob(action="create", ...)
|
||||
cronjob(action="list")
|
||||
cronjob(action="update", job_id="...")
|
||||
cronjob(action="pause", job_id="...")
|
||||
cronjob(action="resume", job_id="...")
|
||||
cronjob(action="run", job_id="...")
|
||||
cronjob(action="remove", job_id="...")
|
||||
```
|
||||
|
||||
### Periodic Disk Usage Check
|
||||
For `update`, pass `skills=[]` to remove all attached skills.
|
||||
|
||||
```python
|
||||
schedule_cronjob(
|
||||
prompt="Check disk usage with 'df -h' and report any partitions above 80% usage. Also check Docker disk usage with 'docker system df' if Docker is installed.",
|
||||
schedule="0 8 * * *",
|
||||
name="Disk Usage Report",
|
||||
deliver="origin"
|
||||
)
|
||||
```
|
||||
## Job storage
|
||||
|
||||
## Managing Jobs
|
||||
Jobs are stored in `~/.hermes/cron/jobs.json`. Output from job runs is saved to `~/.hermes/cron/output/{job_id}/{timestamp}.md`.
|
||||
|
||||
```bash
|
||||
# CLI commands
|
||||
hermes cron list # View all scheduled jobs
|
||||
hermes cron status # Check if the scheduler is running
|
||||
The storage uses atomic file writes so interrupted writes do not leave a partially written job file behind.
|
||||
|
||||
# Slash commands (inside chat)
|
||||
/cron list
|
||||
/cron remove <job_id>
|
||||
```
|
||||
|
||||
The agent can also manage jobs conversationally:
|
||||
- `list_cronjobs` — Shows all jobs with IDs, schedules, repeat status, and next run times
|
||||
- `remove_cronjob` — Removes a job by ID (use `list_cronjobs` to find the ID)
|
||||
|
||||
## Job Storage
|
||||
|
||||
Jobs are stored as JSON in `~/.hermes/cron/jobs.json`. Output from job runs is saved to `~/.hermes/cron/output/{job_id}/{timestamp}.md`.
|
||||
|
||||
The storage uses atomic file writes (temp file + rename) to prevent corruption from concurrent access.
|
||||
|
||||
## Self-Contained Prompts
|
||||
## Self-contained prompts still matter
|
||||
|
||||
:::warning Important
|
||||
Cron job prompts run in a **completely fresh agent session** with zero memory of any prior conversation. The prompt must contain **everything** the agent needs:
|
||||
|
||||
- Full context and background
|
||||
- Specific file paths, URLs, server addresses
|
||||
- Clear instructions and success criteria
|
||||
- Any credentials or configuration details
|
||||
Cron jobs run in a completely fresh agent session. The prompt must contain everything the agent needs that is not already provided by attached skills.
|
||||
:::
|
||||
|
||||
**BAD:** `"Check on that server issue"`
|
||||
|
||||
**GOOD:** `"SSH into server 192.168.1.100 as user 'deploy', check if nginx is running with 'systemctl status nginx', and verify https://example.com returns HTTP 200."`
|
||||
:::
|
||||
|
||||
## Security
|
||||
|
||||
:::warning
|
||||
Scheduled task prompts are scanned for instruction-override patterns (prompt injection). Jobs matching threat patterns like credential exfiltration, SSH backdoor attempts, or prompt injection are blocked at creation time. Content with invisible Unicode characters (zero-width spaces, directional overrides) is also rejected.
|
||||
:::
|
||||
Scheduled task prompts are scanned for prompt-injection and credential-exfiltration patterns at creation and update time. Prompts containing invisible Unicode tricks, SSH backdoor attempts, or obvious secret-exfiltration payloads are blocked.
|
||||
|
||||
@@ -22,7 +22,7 @@ High-level categories:
|
||||
| **Media** | `vision_analyze`, `image_generate`, `text_to_speech` | Multimodal analysis and generation. |
|
||||
| **Agent orchestration** | `todo`, `clarify`, `execute_code`, `delegate_task` | Planning, clarification, code execution, and subagent delegation. |
|
||||
| **Memory & recall** | `memory`, `session_search`, `honcho_*` | Persistent memory, session search, and Honcho cross-session context. |
|
||||
| **Automation & delivery** | `schedule_cronjob`, `send_message` | Scheduled tasks and outbound messaging delivery. |
|
||||
| **Automation & delivery** | `cronjob`, `send_message` | Scheduled tasks with create/list/update/pause/resume/run/remove actions, plus outbound messaging delivery. |
|
||||
| **Integrations** | `ha_*`, MCP server tools, `rl_*` | Home Assistant, MCP, RL training, and other integrations. |
|
||||
|
||||
For the authoritative code-derived registry, see [Built-in Tools Reference](/docs/reference/tools-reference) and [Toolsets Reference](/docs/reference/toolsets-reference).
|
||||
|
||||
Reference in New Issue
Block a user