Skip to content

Feat/cron session titles - #39363

Closed
anthonyarmijo wants to merge 2 commits into
NousResearch:mainfrom
anthonyarmijo:feat/cron-session-titles
Closed

Feat/cron session titles#39363
anthonyarmijo wants to merge 2 commits into
NousResearch:mainfrom
anthonyarmijo:feat/cron-session-titles

Conversation

@anthonyarmijo

Copy link
Copy Markdown

What does this PR do?

Cron sessions currently appear as cron_<id>_<timestamp> with no title in
hermes sessions list, making them indistinguishable from each other. When
you have 10+ cron jobs, there's no way to tell which session was which
without cross-referencing job IDs.

This sets the session title to the cron job's name after each run via
set_session_title(), so sessions are immediately identifiable.

Why finally block?

The call fires on both success and failure without
code duplication. It sits right before end_session() — same guard
(if _session_db:), same lifetime.

Why catch only ValueError?

set_session_title() raises ValueError
on title collision or invalid length. We log a warning and let the job
complete — a title collision shouldn't block cron execution. All other
exceptions propagate (the finally block's existing end_session /
close calls also catch broadly, so this is consistent).

Why no new schema field?

Job names already serve as descriptive
identifiers (they cap at 50 chars, well under the 100-char title limit).
No new config, no migration, no API changes.

Note on existing PRs

PRs #14813 and #23121 propose similar features with different approaches. This PR is the minimal implementation:

  • vs feat(cron): pass job name as session title for cron sessions #14813: That PR modifies hermes_state.py and run_agent.py to pass
    the title at session creation time, which required a follow-up fix for
    uniqueness collisions on repeated runs (lineage titles: #2, #3). This PR
    avoids that entirely by using the existing set_session_title() API in the
    finally block — the session already has a unique ID, so collisions are
    handled gracefully via ValueError.
  • vs feat: meaningful session titles for cron jobs and improved auto-title generation #23121: That PR bundles cron titles with a title_generator.py rewrite
    (two features, one PR), adds opinionated date suffixes (· 2026-05-10), and
    injects token-tracking imports. This PR is a single focused change — 9 lines
    in the scheduler, cron-only, no opinionated formatting.

Related Issue

N/A — small self-contained improvement.

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ New feature (non-breaking change that adds functionality)
  • 🔒 Security fix
  • 📝 Documentation update
  • ✅ Tests (adding or improving test coverage)
  • ♻️ Refactor (no behavior change)
  • 🎯 New skill (bundled or hub)

Changes Made

  • cron/scheduler.py — added set_session_title() call in finally block (line ~1940), after TERMINAL_CWD/ContextVar cleanup and before end_session(). Catches ValueError with logger.warning().

  • tests/cron/test_scheduler.py

    • Added set_session_title assertions to existing success-path test
    • Added test_run_job_sets_session_title_on_failure — agent raises →
      title still set
    • Added test_run_job_handles_session_title_valueerror — collision
      doesn't crash the job
    • Added test_run_job_skips_title_when_session_db_is_none — no
      SessionDB → no crash

How to Test

  1. Trigger any cron job:
    hermes cron run <job_id>
    
  2. Wait for it to complete, then check sessions:
    hermes sessions list
    
  3. Verify: the session shows the job name as its title instead of
  4. Edge case — job that fails:
    • Can simulate by creating a job whose prompt triggers an error
    • Session should still have the title set
  5. Edge case — _session_db is None:
    • Covered by unit test, not manual

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits
  • I searched for existing PRs — no duplicates
  • My PR contains only changes related to this feature
  • I've run tests: pytest tests/cron/495 passed
  • I've added tests for: success path, failure path, ValueError handling, None SessionDB
  • I've tested on: macOS 26.4.1

Documentation & Housekeeping

  • Documentation — N/A (no public API or config surface changed)
  • cli-config.yaml.example — N/A (no config keys added)
  • CONTRIBUTING.md / AGENTS.md — N/A (no architecture changes)
  • Cross-platform — N/A (pure Python + SQLite; no OS-specific code, no paths, no shell)
  • Tool descriptions/schemas — N/A (no tool behavior changed)

Screenshots / Logs

Before — all cron sessions show with no title:

Title    Preview                                  Last Active   ID
─        [cron job output...]                     7h ago        cron_acc2c0a0020d_20260604_070018
─        [cron job output...]                     6h ago        cron_a42178af4483_20260604_083028

After — the session title is the job's name:

Title                   Preview                                  Last Active   ID
Quick Weather Check     [cron job output...]                     1m ago        cron_a5cb6df35aaa_20260604_144633
─                       [cron job output...]                     6h ago        cron_a42178af4483_20260604_083028

The still-untitled session (cron_a421*) ran before the gateway was
restarted with the new code — all subsequent runs get titled automatically.

Cron sessions currently appear as 'cron_<id>_<timestamp>' with no
title in 'hermes sessions list', making them indistinguishable.

After a cron job completes (success or failure), set the session
title to the job's name via set_session_title().  This makes cron
sessions immediately identifiable in session listings.

The title is set in a try/except block so a title collision or DB
issue never blocks the cron job from completing.
Set session title to the job name after each cron run, so sessions
are identifiable in 'hermes sessions list' instead of showing the
raw 'cron_<id>_<timestamp>' ID.

Moved title-setting to the finally block so it fires on both success
and failure paths without code duplication. Catches ValueError
specifically (title collision) and logs a warning instead of silently
swallowing all exceptions.

Added three tests:
- set_session_title called on agent failure
- ValueError from set_session_title does not crash the job
- _session_db is None handled gracefully
@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 Jun 4, 2026
@teknium1

Copy link
Copy Markdown
Contributor

Thanks for the focused cron-session usability improvement. This is an automated hermes-sweeper review; current main already provides this behavior.

  • cron/scheduler.py:3336-3348 titles each completed cron session from the job name, adds a run-time uniqueness suffix, and isolates title-setting failures from cron completion.
  • tests/cron/test_scheduler.py:1090-1126 verifies the title is derived from the job rather than the injected [IMPORTANT] cron hint.
  • The implementation landed in ad0f6db151bf00f3d5b7303a45a961f735fbdb3a (feat(cron): title cron sessions from the job, not the [IMPORTANT] hint) and shipped in v2026.6.19.

@teknium1 teknium1 closed this Jul 14, 2026
@teknium1 teknium1 added the sweeper:implemented-on-main Sweeper: behavior already present on current main label 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 P3 Low — cosmetic, nice to have sweeper:implemented-on-main Sweeper: behavior already present on current main type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants