mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-06-27 11:22:03 +00:00
feat(cron): warn when gateway not running on cron create/list (#51696)
The cron ticker only runs inside the gateway (_start_cron_ticker); there is no standalone cron daemon. When the gateway isn't running, next_run_at passes but jobs never fire and last_run_at stays null — and manual 'hermes cron run' (which bypasses the ticker) appears to work, masking the real cause. This is the most common cron support report (#51038). cron list already warned; extend the same warning to cron create (the moment the user is most likely to hit this) via a shared helper, and add a pointer to 'hermes cron status'. Silent when a gateway is running, so the gateway /cron path is unaffected.
This commit is contained in:
parent
c39b2b50ee
commit
78e122ae1a
2 changed files with 83 additions and 6 deletions
|
|
@ -57,6 +57,30 @@ def _cron_api(**kwargs):
|
|||
return json.loads(cronjob_tool(**kwargs))
|
||||
|
||||
|
||||
def _warn_if_gateway_not_running() -> None:
|
||||
"""Warn that scheduled jobs won't fire unless the gateway is running.
|
||||
|
||||
The cron ticker only runs inside the gateway (``_start_cron_ticker`` in
|
||||
gateway/run.py); there is no standalone cron daemon. Without a running
|
||||
gateway, ``next_run_at`` passes but jobs never fire and ``last_run_at``
|
||||
stays null — the most common cron support report (#51038). Surfacing this
|
||||
at create/list time, when the user is right there, prevents it.
|
||||
"""
|
||||
try:
|
||||
from hermes_cli.gateway import find_gateway_pids
|
||||
|
||||
if find_gateway_pids():
|
||||
return
|
||||
except Exception:
|
||||
# If we can't determine gateway state, stay quiet rather than nag.
|
||||
return
|
||||
|
||||
print(color(" ⚠ Gateway is not running — jobs won't fire automatically.", Colors.YELLOW))
|
||||
print(color(" Start it with: hermes gateway install", Colors.DIM))
|
||||
print(color(" sudo hermes gateway install --system # Linux servers", Colors.DIM))
|
||||
print(color(" Check status: hermes cron status", Colors.DIM))
|
||||
|
||||
|
||||
def cron_list(show_all: bool = False):
|
||||
"""List all scheduled jobs."""
|
||||
from cron.jobs import list_jobs
|
||||
|
|
@ -137,12 +161,7 @@ def cron_list(show_all: bool = False):
|
|||
|
||||
print()
|
||||
|
||||
from hermes_cli.gateway import find_gateway_pids
|
||||
if not find_gateway_pids():
|
||||
print(color(" ⚠ Gateway is not running — jobs won't fire automatically.", Colors.YELLOW))
|
||||
print(color(" Start it with: hermes gateway install", Colors.DIM))
|
||||
print(color(" sudo hermes gateway install --system # Linux servers", Colors.DIM))
|
||||
print()
|
||||
_warn_if_gateway_not_running()
|
||||
|
||||
|
||||
def cron_tick():
|
||||
|
|
@ -276,6 +295,7 @@ def cron_create(args):
|
|||
if job_data.get("workdir"):
|
||||
print(f" Workdir: {job_data['workdir']}")
|
||||
print(f" Next run: {result['next_run_at']}")
|
||||
_warn_if_gateway_not_running()
|
||||
return 0
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -121,3 +121,60 @@ class TestCronCommandLifecycle:
|
|||
|
||||
out = capsys.readouterr().out
|
||||
assert "Repeat: ∞" in out
|
||||
|
||||
|
||||
class TestGatewayNotRunningWarning:
|
||||
"""`cron create` / `cron list` must warn when the gateway (and thus the
|
||||
cron ticker) isn't running, since jobs only fire inside the gateway.
|
||||
Regression guard for #51038 — the most common cron 'jobs never fired'
|
||||
report was simply a gateway that was never started.
|
||||
"""
|
||||
|
||||
def test_create_warns_when_gateway_absent(self, tmp_cron_dir, capsys, monkeypatch):
|
||||
monkeypatch.setattr("hermes_cli.gateway.find_gateway_pids", lambda: [])
|
||||
cron_command(
|
||||
Namespace(
|
||||
cron_command="create",
|
||||
schedule="0 11 * * *",
|
||||
prompt="Daily report",
|
||||
name="Daily 1130",
|
||||
deliver=None,
|
||||
repeat=None,
|
||||
skill=None,
|
||||
skills=None,
|
||||
script=None,
|
||||
workdir=None,
|
||||
no_agent=False,
|
||||
)
|
||||
)
|
||||
out = capsys.readouterr().out
|
||||
assert "Created job" in out
|
||||
assert "Gateway is not running" in out
|
||||
|
||||
def test_create_silent_when_gateway_running(self, tmp_cron_dir, capsys, monkeypatch):
|
||||
monkeypatch.setattr("hermes_cli.gateway.find_gateway_pids", lambda: [4242])
|
||||
cron_command(
|
||||
Namespace(
|
||||
cron_command="create",
|
||||
schedule="0 11 * * *",
|
||||
prompt="Daily report",
|
||||
name="Daily 1130",
|
||||
deliver=None,
|
||||
repeat=None,
|
||||
skill=None,
|
||||
skills=None,
|
||||
script=None,
|
||||
workdir=None,
|
||||
no_agent=False,
|
||||
)
|
||||
)
|
||||
out = capsys.readouterr().out
|
||||
assert "Created job" in out
|
||||
assert "Gateway is not running" not in out
|
||||
|
||||
def test_list_warns_when_gateway_absent(self, tmp_cron_dir, capsys, monkeypatch):
|
||||
create_job(prompt="Daily report", schedule="0 11 * * *")
|
||||
monkeypatch.setattr("hermes_cli.gateway.find_gateway_pids", lambda: [])
|
||||
cron_command(Namespace(cron_command="list", all=True))
|
||||
out = capsys.readouterr().out
|
||||
assert "Gateway is not running" in out
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue