hermes-agent/website/docs/guides
Teknium 3db6b9cc87
feat(cron): add no_agent mode for script-only cron jobs (watchdog pattern) (#19709)
* feat(cron): add no_agent mode for script-only cron jobs (watchdog pattern)

Adds a no_agent=True option to the cronjob system. When enabled, the
scheduler runs the attached script on schedule and delivers its stdout
directly to the job's target — no LLM, no agent loop, no token spend.
This is the classic bash-watchdog pattern (memory alert every 5 min,
disk alert every 15 min, CI ping) reimplemented as a first-class Hermes
primitive instead of a systemd timer + curl + bot token triplet living
outside the system.

## What

  hermes cron create "every 5m" \
    --no-agent \
    --script memory-watchdog.sh \
    --deliver telegram \
    --name memory-watchdog

Agent tool:

  cronjob(action='create',
          schedule='every 5m',
          script='memory-watchdog.sh',
          no_agent=True,
          deliver='telegram')

Semantics:
- Script stdout (trimmed) → delivered verbatim as the message
- Empty stdout          → silent tick (no delivery; watchdog pattern)
- wakeAgent=false gate  → silent tick (same gate LLM jobs use)
- Non-zero exit/timeout → delivered as an error alert
                          (broken watchdogs shouldn't fail silently)
- No LLM ever invoked; no tokens spent; no provider fallback applied

## Implementation

cron/jobs.py
  * create_job gains no_agent: bool = False
  * prompt becomes Optional (no_agent jobs don't need one)
  * Validation: no_agent=True requires a script at create time
  * Field roundtrips via load_jobs / save_jobs / update_job

cron/scheduler.py
  * run_job: new short-circuit branch at the top that runs the script,
    wraps its output into the (success, doc, final_response, error)
    tuple downstream delivery already expects, and returns before any
    AIAgent import or construction
  * _run_job_script: picks interpreter by extension — .sh/.bash run
    under /bin/bash, anything else under sys.executable (Python).
    Shell support unlocks the bash-watchdog pattern without wrapping
    scripts in Python. Extension is explicit; we deliberately do NOT
    trust the file's own shebang. Path-containment guard (scripts dir)
    unchanged.

tools/cronjob_tools.py
  * Schema: new no_agent boolean property with clear trigger guidance
  * cronjob() accepts no_agent and validates mode-specific shape:
    - no_agent=True requires script; prompt/skills optional
    - no_agent=False keeps the existing 'prompt or skill required' rule
  * update path rejects flipping no_agent=True on a job without a script
  * _format_job surfaces no_agent in list output
  * Handler lambda forwards no_agent from tool args

hermes_cli/main.py, hermes_cli/cron.py
  * 'hermes cron create --no-agent' and edit's --no-agent / --agent
    pair for toggling at CLI parity with the agent tool
  * Existing --script help text updated to describe both modes
  * List / create / edit output now shows 'Mode: no-agent (...)' when set

## Tests

tests/cron/test_cron_no_agent.py — 18 tests covering:
  * create_job: no_agent shape, validation, field persistence
  * update_job: flag roundtrip across reload
  * cronjob tool: schema validation, update toggling, mode-specific
    requirements, prompt-relaxation rule
  * run_job short-circuit:
    - success path delivers stdout verbatim
    - empty stdout → SILENT_MARKER (no delivery downstream)
    - wakeAgent=false gate → silent
    - script failure → error alert
    - run_job does NOT import AIAgent (verified via mock)
  * _run_job_script:
    - .sh executes via bash (no shebang required)
    - .bash executes via bash
    - .py still runs via sys.executable (regression)
    - path-traversal still blocked (security regression)

All 18 new tests pass. 341/342 pre-existing cron tests still pass; the
one failure (test_script_empty_output_noted) was already broken on main
and is unrelated to this change.

## Docs

website/docs/guides/cron-script-only.md — new dedicated guide covering
the watchdog pattern, interpreter rules, delivery mapping, worked
examples (memory / disk alerts), and the comparison table vs hermes send,
regular LLM cron jobs, and OS-level cron.

website/docs/user-guide/features/cron.md — new 'No-agent mode' section
in the cron feature reference, cross-linked to the guide.

website/docs/guides/automate-with-cron.md — new tip box pointing users
to no-agent mode when they don't need LLM reasoning.

## Compatibility

- Existing jobs: unchanged. no_agent defaults to False, existing code
  paths untouched until the flag is set.
- Schema additive only; older jobs.json without the field load fine
  via .get() with False default.
- New CLI flags are opt-in and don't alter existing flag behavior.

* fix(cron): lazy-import AIAgent + SessionDB so no_agent ticks pay zero

The unconditional `from run_agent import AIAgent` + SessionDB() init at
the top of run_job() meant every no_agent tick still paid the full agent
module load cost (~300ms + transitive imports + DB open) even though it
never touched any of that machinery.

Move both to live under the default (LLM) path, after the no_agent
short-circuit has returned. Now a no_agent tick's sys.modules stays
clean — verified end-to-end:

    assert 'run_agent' not in sys.modules  # before
    run_job(no_agent_job)
    assert 'run_agent' not in sys.modules  # after

The existing mock-based unit test (test_run_job_no_agent_never_invokes_aiagent)
kept passing because patch() replaces the class AFTER import; the leak
was only visible via real subprocess-style verification. End-to-end
demo confirmed: agent calls cronjob(no_agent=True) → script runs →
stdout delivered → no LLM machinery loaded.

* docs(cron): tighten no_agent tool schema — defaults, silent semantics, pick rule

Previous description buried the important bits in one long sentence.
Agents could plausibly miss three things an LLM-facing schema should
make unmissable:

1. What the default is — now first sentence + JSON Schema `default: false`
2. What 'silent run' actually means for the user — now spelled out:
   'nothing is sent to the user and they won't see anything happened'
3. When to pick True vs False — now a concrete decision rule with
   examples on both sides (watchdogs/metrics/pollers → True;
   summarize/draft/pick/rephrase → False)

Also adds explicit 'prompt and skills are ignored when True' since the
agent could otherwise still pass them out of habit.

No behavior change — schema text only.
2026-05-04 12:31:01 -07:00
..
_category_.json docs: add Guides & Tutorials section, restructure sidebar 2026-03-08 19:37:34 -07:00
automate-with-cron.md feat(cron): add no_agent mode for script-only cron jobs (watchdog pattern) (#19709) 2026-05-04 12:31:01 -07:00
automation-templates.md docs: automation templates gallery + comparison post (#9821) 2026-04-14 12:30:50 -07:00
aws-bedrock.md feat: native AWS Bedrock provider via Converse API 2026-04-15 16:17:17 -07:00
azure-foundry.md fix(providers): honor key_env/api_key_env on Azure Anthropic + accept alias in normalizer (#16935) 2026-04-28 02:12:08 -07:00
build-a-hermes-plugin.md docs: two-week gap sweep — platforms, CLI, config, TUI, hooks, providers (#17727) 2026-04-29 20:32:37 -07:00
cron-script-only.md feat(cron): add no_agent mode for script-only cron jobs (watchdog pattern) (#19709) 2026-05-04 12:31:01 -07:00
cron-troubleshooting.md docs: add QQBot to all 14 docs pages (full platform parity) 2026-04-14 00:11:49 -07:00
daily-briefing-bot.md docs(cron): clarify default model/provider setup for scheduled jobs 2026-04-23 02:04:45 -07:00
delegation-patterns.md docs(delegate_task): clarify that it is synchronous and not durable (#17022) 2026-04-28 06:45:15 -07:00
github-pr-review-agent.md fix(docs): unbreak docs-site-checks — ascii-guard diagram + MDX <1% (#12984) 2026-04-20 04:29:02 -07:00
local-llm-on-mac.md docs: document streaming timeout auto-detection for local LLMs (#6990) 2026-04-09 23:28:25 -07:00
migrate-from-openclaw.md feat(claw-migrate): harden OpenClaw import with plan-first apply, redaction, and pre-migration backup (#16911) 2026-04-28 01:50:23 -07:00
minimax-oauth.md docs: document MiniMax OAuth login flow 2026-04-29 09:53:42 -07:00
python-library.md docs: guides section overhaul — fix existing + add 3 new tutorials (#5735) 2026-04-06 22:02:47 -07:00
team-telegram-assistant.md docs: guides section overhaul — fix existing + add 3 new tutorials (#5735) 2026-04-06 22:02:47 -07:00
tips.md docs: fix 40+ discrepancies between documentation and codebase (#5818) 2026-04-07 10:17:44 -07:00
use-mcp-with-hermes.md docs: guides section overhaul — fix existing + add 3 new tutorials (#5735) 2026-04-06 22:02:47 -07:00
use-soul-with-hermes.md docs: guides section overhaul — fix existing + add 3 new tutorials (#5735) 2026-04-06 22:02:47 -07:00
use-voice-mode-with-hermes.md feat(voice): add cli beep toggle 2026-04-21 00:29:29 -07:00
webhook-github-pr-review.md docs: add PR review guides, rework quickstart, slim down installation 2026-04-19 05:30:50 -07:00
work-with-skills.md docs(skills): document URL install across features, reference, guide, and hermes-agent skill (#16355) 2026-04-26 21:27:59 -07:00