Skip to content

feat(cron): pass job name as session title for cron sessions - #14813

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

feat(cron): pass job name as session title for cron sessions#14813
waldmanz wants to merge 2 commits into
NousResearch:mainfrom
waldmanz:feat/cron-session-titles

Conversation

@waldmanz

Copy link
Copy Markdown

Problem

Cron job sessions previously had no title in the SQLite session store, causing the web UI and sessions list to display truncated system prompt text as session titles:

[SYSTEM: You are running as a scheduled cron job. DELIVERY: Your...
[SILENT]讨论
llm-wiki与AI效率

This happens because cron sessions bypass the gateway/CLI — they call agent.run_conversation() directly, so the maybe_auto_title() hook is never triggered. The web UI falls back to the first message content (session.preview) when title is NULL.

Solution

Pass the cron job's human-readable name through to SessionDB.create_session() so each cron session gets a meaningful title immediately: wiki-auto-ingest, Hermes Tips, AI docs vault updater, etc.

Changes

File Change
hermes_state.py Add optional title parameter to create_session()
run_agent.py Accept session_title in AIAgent.init and forward it
cron/scheduler.py Pass session_title=job_name when constructing the agent

Testing

  • All 277 existing tests pass (cron, hermes_state, title_generator)
  • Backward compatible — all new parameters default to None
  • No migration needed — the title column already exists in the schema (v3 migration)

Cron job sessions previously had no title in the SQLite session store,
causing the web UI to display truncated system prompt text as session
titles (e.g., '[SYSTEM: You are running as a scheduled cron job...]').

Pass the job's human-readable name through to SessionDB.create_session()
so cron sessions display meaningful titles like 'wiki-auto-ingest',
'Hermes Tips', etc. in the sessions list, dashboard, and session search.

Changes:
- hermes_state.py: Add optional 'title' parameter to create_session()
- run_agent.py: Accept 'session_title' in AIAgent.__init__ and forward it
- cron/scheduler.py: Pass session_title=job_name when constructing AIAgent

All parameters are optional with defaults that preserve existing behavior.
No migration needed — the title column already exists in the schema.
@alt-glitch alt-glitch added type/feature New feature or request P3 Low — cosmetic, nice to have comp/cron Cron scheduler and job management comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint labels Apr 23, 2026
@waldmanz

Copy link
Copy Markdown
Author

Thanks — I pushed a follow-up fix for the session-title behavior.

What changed

  • Preserve cron session titles across repeated runs
  • Sanitize titles on create_session()
    • This now uses the same title-cleaning rules as set_session_title()
    • Prevents raw whitespace/control-character titles from being inserted directly
  • Preserve title in the late recovery path
    • If startup session creation is skipped/fails and run_agent later falls back to ensure_session(), the requested session title is still retained

Why this follow-up was needed
The initial version passed title=job_name into create_session(), but sessions.title is uniquely indexed.
That meant the first run of a recurring cron job worked, while later runs with the same job name could hit INSERT OR IGNORE, skip row creation, and then get recreated later without a title via ensure_session().

This follow-up fixes that by allocating a unique sanitized title before insert, and by threading the title through the ensure_session() recovery path too.

Tests added

  • create_session with duplicate title gets numbered variant
  • create_session sanitizes title input
  • ensure_session preserves requested title
  • run_agent flush path passes session_title into ensure_session

Validation

  • Focused new regression tests pass
  • Existing hermes_state title/ensure_session tests still pass
  • Related run_agent tests still pass

Pushed in:

  • a45a727 fix(cron): preserve unique session titles across repeated runs

@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 cron-session naming gap. Current main already titles sessions in the scheduler finalizer, but the repeated-run edge case remains.

Problems

  • cron/scheduler.py:3297 formats the suffix only through minutes. Two same-name runs completing in one minute generate the same title; hermes_state.py:2743-2745 raises ValueError, and cron/scheduler.py:3299-3300 logs and suppresses it, leaving the later session untitled.
  • The PR targets an older persistence shape. Current session creation is centralized by hermes_state.py:1610-1668 and invoked by run_agent.py:598-607, so the creation-time plumbing needs adaptation rather than a direct cherry-pick.

Suggested changes

  • Keep the current finalizer path and allocate a numbered fallback with SessionDB.get_next_title_in_lineage() (hermes_state.py:2852-2885) before set_session_title().
  • Add a fixed-clock regression covering two same-name runs in one minute and assert both sessions retain distinct titles.

This is an automated hermes-sweeper review.

Comment thread hermes_state.py
@@ -643,6 +648,48 @@ def sanitize_title(title: Optional[str]) -> Optional[str]:

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.

Current main already has SessionDB.get_next_title_in_lineage() for numbered title allocation. Please rebase the duplicate-title behavior onto that existing API and the scheduler finalizer, rather than adding a second allocator in the session-creation path.

@teknium1 teknium1 added sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-broad Sweeper blast radius: broad — a core path most sessions hit labels Jul 12, 2026
@teknium1

Copy link
Copy Markdown
Contributor

Thanks for the contribution — this was the earliest PR (April 23) to target meaningful cron session titles, and the need was real.

Closing as superseded by main's design plus PR #66058: main now titles cron sessions in the scheduler's finally block after the run (deliberate — a create-time title would be overwritten by the agent's own INSERT bookkeeping, and loses the timestamp suffix that keeps repeated runs unique against the title index). #66058 hardened that path with collision dedup and a non-blank guarantee. The job-name-as-title outcome you wanted is what ships today; the mechanism just moved to the other end of the run.

@teknium1 teknium1 closed this Jul 17, 2026
@teknium1 teknium1 added the area/sessions Session lifecycle, resume, persistence, history label Jul 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/sessions Session lifecycle, resume, persistence, history comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/cron Cron scheduler and job management P3 Low — cosmetic, nice to have sweeper:blast-broad Sweeper blast radius: broad — a core path most sessions hit sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants