mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-24 05:41:40 +00:00
feat(cron): support name-based lookup for job operations
Cron mutation operations (run/pause/resume/remove) and 'hermes cron edit'
now accept a job name in addition to the hex ID, with case-insensitive
matching. Before this, 'hermes cron run my_job_name' died with
'Job with ID my_job_name not found' and forced the user to look up the
hex ID first.
The original PR matched by name but silently picked the first match when
two jobs shared a name. This version refuses to act on an ambiguous name
and surfaces every matching job (id, name, schedule, next_run_at) so the
caller can pick a specific ID.
- cron/jobs.py:
- get_job() stays ID-only (preserves existing call-site semantics for
web_server/api_server/curator/scheduler/test code that always passes
real IDs).
- resolve_job_ref() is the new name-or-ID resolver, used by pause/
resume/trigger/remove_job. Exact ID match wins over a name match
even if a different job's name happens to equal that ID. Ambiguous
name match raises AmbiguousJobReference with all candidate IDs.
- tools/cronjob_tools.py: dispatch site uses resolve_job_ref, surfaces
ambiguous matches as a structured error with the matching IDs.
- hermes_cli/cron.py: 'cron edit' uses resolve_job_ref so editing by
name works and ambiguous names are reported with IDs.
- tests/cron/test_jobs.py: new TestResolveJobRef covering ID match,
case-insensitive name match, ID-wins-over-name, ambiguous refusal,
and that pause/resume/trigger/remove all refuse on ambiguity.
Closes #2627
This commit is contained in:
parent
05d9f641c0
commit
6682f91b80
4 changed files with 176 additions and 16 deletions
|
|
@ -21,12 +21,14 @@ logger = logging.getLogger(__name__)
|
|||
sys.path.insert(0, str(Path(__file__).parent.parent))
|
||||
|
||||
from cron.jobs import (
|
||||
AmbiguousJobReference,
|
||||
create_job,
|
||||
get_job,
|
||||
list_jobs,
|
||||
parse_schedule,
|
||||
pause_job,
|
||||
remove_job,
|
||||
resolve_job_ref,
|
||||
resume_job,
|
||||
trigger_job,
|
||||
update_job,
|
||||
|
|
@ -393,12 +395,32 @@ def cronjob(
|
|||
if not job_id:
|
||||
return tool_error(f"job_id is required for action '{normalized}'", success=False)
|
||||
|
||||
job = get_job(job_id)
|
||||
if not job:
|
||||
try:
|
||||
job = resolve_job_ref(job_id)
|
||||
except AmbiguousJobReference as exc:
|
||||
return json.dumps(
|
||||
{"success": False, "error": f"Job with ID '{job_id}' not found. Use cronjob(action='list') to inspect jobs."},
|
||||
{
|
||||
"success": False,
|
||||
"error": str(exc),
|
||||
"matches": [
|
||||
{
|
||||
"id": m["id"],
|
||||
"name": m.get("name"),
|
||||
"schedule": m.get("schedule_display"),
|
||||
"next_run_at": m.get("next_run_at"),
|
||||
}
|
||||
for m in exc.matches
|
||||
],
|
||||
},
|
||||
indent=2,
|
||||
)
|
||||
if not job:
|
||||
return json.dumps(
|
||||
{"success": False, "error": f"Job with ID or name '{job_id}' not found. Use cronjob(action='list') to inspect jobs."},
|
||||
indent=2,
|
||||
)
|
||||
# Resolve to canonical ID (supports name-based lookup)
|
||||
job_id = job["id"]
|
||||
|
||||
if normalized == "remove":
|
||||
removed = remove_job(job_id)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue