Skip to content

fix(cron): add seconds support and honor sub-minute schedules - #44751

Open
bitflicker64 wants to merge 3 commits into
NousResearch:mainfrom
bitflicker64:fix/cron-add-seconds-support
Open

fix(cron): add seconds support and honor sub-minute schedules#44751
bitflicker64 wants to merge 3 commits into
NousResearch:mainfrom
bitflicker64:fix/cron-add-seconds-support

Conversation

@bitflicker64

@bitflicker64 bitflicker64 commented Jun 12, 2026

Copy link
Copy Markdown

Summary

Fixes #44749. Relative schedules like "in 10 seconds" were broken in two places:

  1. LLM fabricates absolute timestamps. The system prompt only injects the date (for caching), so models invent something like 12:35 for "now + 10s" and the job never fires.
  2. parse_duration rejected seconds. Even a correct "10s" schedule raised ValueError.

This PR adds seconds support and makes the built-in ticker actually honor those schedules.

Changes

cron/jobs.py

  • parse_duration accepts s / sec / secs / second / seconds
  • Allows decimal values (1.5s, 0.5m)
  • Returns float minutes so sub-minute precision is preserved
  • seconds_until_next_job / compute_ticker_wait_seconds for adaptive sleep

cron/scheduler_provider.py

  • Built-in ticker still defaults to a 60s cadence when nothing is due soon
  • When a job is due sooner, wait shortens to that job's next_run_at
  • Rechecks every second so a job created mid-cycle (e.g. "remind me in 10s") still fires on time

tools/cronjob_tools.py

  • Schema examples include 10s / 30s
  • Explicit warning: do not invent ISO timestamps for relative times; use duration format instead

Docs

  • website/docs/user-guide/features/cron.md documents seconds formats and adaptive wake

Review follow-up

Earlier feedback correctly pointed out that advertising 10s while the ticker slept a fixed 60s could not honor the promised resolution. This update keeps the seconds parser and adds the trigger path plus an end-to-end test that a 2s one-shot fires in under ~6s with interval=60.

Test plan

  • parse_duration("30s") == 0.5
  • parse_duration("90seconds") == 1.5
  • parse_schedule("every 30s") / "30s" / "1.5m"
  • TestTickerWait (no jobs, near-term shortens wait, overdue near-zero, paused/disabled ignored)
  • test_inprocess_provider_honors_subminute_schedule (e2e dispatch path)
  • Existing scheduler-provider suite green (61 tests)
.venv/bin/python -m pytest tests/cron/test_scheduler_provider.py \
  tests/cron/test_jobs.py::TestTickerWait \
  tests/cron/test_jobs.py::TestParseDuration \
  tests/cron/test_jobs.py::TestParseSchedule -q

@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/cron Cron scheduler and job management labels Jun 12, 2026

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for addressing the missing relative-duration path. Current main still rejects 10s in cron/jobs.py:465, so the premise is valid.

Problems

  • The default trigger cannot honor the new advertised timing. InProcessCronScheduler.start() calls cron_tick() and then stop_event.wait(interval) with interval=60 by default (cron/scheduler_provider.py:166-194). Therefore 10s and 30s schedules can wait until the next 60-second tick.
  • The added parser tests do not exercise that dispatch path, so they do not verify the requested timing guarantee.

Suggested changes

  • Align the accepted schedule resolution with the built-in trigger, or add a trigger mechanism and an end-to-end timing test that can honor sub-minute jobs.
  • Update website/docs/user-guide/features/cron.md:526-540 if seconds become a supported user-facing format.

Automated hermes-sweeper review.

Comment thread tools/cronjob_tools.py
…rom absolute timestamps

- Add seconds (s/sec/secs/second/seconds) to parse_duration regex
- Allow decimal values in durations (e.g. '1.5s', '0.5m')
- Change return type from int to float for sub-minute precision
- Update CRONJOB_SCHEMA to warn LLM against constructing ISO timestamps
- Add test cases for seconds and decimal duration values

Fixes NousResearch#44749
- Fix interval display to use original input string instead of computed float minutes
- Update parse_schedule docstring: minutes type int -> float
- Add integration tests: parse_schedule('every 30s'), parse_schedule('30s'), parse_schedule('1.5m')
- Fix docstring example: 0.1667 -> 10/60
- Restructure CRONJOB_SCHEMA to clearly separate ISO timestamps from relative-time warning
- Note: hermes_cli/kanban.py and plugins/google_meet/meet_bot.py have their own _parse_duration functions and are unaffected
Review on NousResearch#44751 noted that advertising 10s/30s was misleading while the
built-in provider slept a fixed 60s. Shorten wait to the next job's
next_run_at (capped at the default interval), recheck every second so
jobs created mid-cycle still fire on time, document seconds formats,
and add unit + e2e coverage for the dispatch path.
@bitflicker64
bitflicker64 force-pushed the fix/cron-add-seconds-support branch from e9320b8 to eff9621 Compare July 14, 2026 13:11
@bitflicker64 bitflicker64 changed the title fix(cron): add seconds support to parse_duration and guide LLM away from absolute timestamps fix(cron): add seconds support and honor sub-minute schedules Jul 14, 2026
@teknium1 teknium1 added sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/cron Cron scheduler and job management P2 Medium — degraded but workaround exists sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: cron relative timestamps fail for sub-minute schedules (e.g. 'in 10 seconds')

3 participants