Skip to content

feat(cron): add context_from field for cron job output chaining#14190

Closed
MorAlekss wants to merge 3 commits into
NousResearch:mainfrom
MorAlekss:feat/cron-context-from
Closed

feat(cron): add context_from field for cron job output chaining#14190
MorAlekss wants to merge 3 commits into
NousResearch:mainfrom
MorAlekss:feat/cron-context-from

Conversation

@MorAlekss

@MorAlekss MorAlekss commented Apr 22, 2026

Copy link
Copy Markdown
Contributor

Closes #5439

Summary

Adds native cron job output chaining via context_from field. When set, the most recent output of the referenced job(s) is automatically injected into the prompt before each run, enabling job A to collect data and job B to process it without manual file wiring.

Files changed

  • cron/jobs.py — added context_from parameter to create_job(), with normalization to a list
  • cron/scheduler.py — output injection in _build_job_prompt()
  • tools/cronjob_tools.py — schema, validation, handler wiring
  • tests/cron/test_cron_context_from.py — 14 new tests

Implementation

Issue #5439 Option C proposed a new ~/.hermes/cron/shared/ directory with named files. Instead, the implementation reads from the existing ~/.hermes/cron/output/{job_id}/ store that save_job_output() already writes atomically.

This avoids introducing a new filesystem surface while delivering stronger guarantees:

  • Per-job isolation, no naming collisions between jobs
  • Atomic writes already in place (temp → fsync → os.replace())
  • Automatic latest semantics via mtime sorting
  • No new cleanup logic needed

Safety:

  • Path traversal guard: job IDs validated as 12-char hex strings
  • Truncation at 8K chars to prevent prompt bloat
  • Graceful degradation on OSError (covers PermissionError and FileNotFoundError)

Usage:

# Job A collects data
cronjob(action='create', prompt='Find top news', schedule='every 1h', name='news_finder')
# Returns job_id: abc123def456

# Job B processes it
cronjob(action='create', prompt='Summarize the news', schedule='every 2h',
        context_from=['abc123def456'])

Tests

# Scenario Result
1 context_from stored as list when passed as string
2 context_from stored when passed as list
3 None when not provided
4 Empty string normalized to None
5 Empty list normalized to None
6 Latest output injected into prompt
7 Most recent file selected by mtime
8 Silent skip when no output exists yet
9 Multiple jobs injected in order
10 Context appears before job prompt
11 Output truncated at 8K chars
12 FileNotFoundError handled gracefully
13 PermissionError handled gracefully
14 Path traversal attempt silently skipped

Tested on

macOS, Linux, Python 3.11, Hermes v0.11.0

@alt-glitch alt-glitch added type/feature New feature or request P3 Low — cosmetic, nice to have comp/cron Cron scheduler and job management labels Apr 22, 2026
@MorAlekss MorAlekss force-pushed the feat/cron-context-from branch 2 times, most recently from cd24980 to 51e2638 Compare April 24, 2026 23:09
@MorAlekss

Copy link
Copy Markdown
Contributor Author

Updated: silent skip instead of placeholder when referenced job has no output. Avoids spurious context in the LLM prompt.

@teknium1

Copy link
Copy Markdown
Contributor

Merged via #15606 (rebase-merge) with your 3 feature commits preserving your authorship in git log. One follow-up commit from me wired the missing update-path support (schema promised 'pass an empty array to clear' but the update branch didn't read the kwarg) — now add/change/clear all work end-to-end. Thanks for the solid groundwork on this one: Option B semantics, path-traversal guard, 8K truncation, graceful no-output behavior, and 15 tests were all sound as written.

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 P3 Low — cosmetic, nice to have type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature: Cron job output chaining — let one job's output feed into another

3 participants