fix(cron): record no_agent runs as sessions, keep them out of the sidebar - #62247
Open
fangl12 wants to merge 1 commit into
Open
fix(cron): record no_agent runs as sessions, keep them out of the sidebar#62247fangl12 wants to merge 1 commit into
fangl12 wants to merge 1 commit into
Conversation
…ebar
no_agent (script-mode) cron jobs short-circuit run_job() before any
SessionDB work, so they never produce the cron_{job_id}_{ts} session row
that the run-history endpoint (GET /api/cron/jobs/{id}/runs) is built
from. Manually triggering such a job gives zero feedback in the Desktop
GUI: no running indicator, no run record, no output.
Fix (cron/scheduler.py): in the no_agent branch of run_job(), create the
run session before executing the script (source='cron', matching the
agent path's shape) so the runs endpoint's is_active check reflects an
in-flight run. After execution, persist the outcome doc as an assistant
message, title the session, and end_session. Covers all four exit paths:
success, script failure, empty-stdout silent run, and wakeAgent=false
silent run. Recording is best-effort — a broken state store degrades to
the old no-record behaviour and never blocks the script run. The
no_agent cost contract is preserved: run_agent/AIAgent are still never
imported on this path.
This alone introduces a second bug: opening a cron run from the Cron
panel's run-history list navigates to /session/<cron_id>, which sets
. The desktop sidebar's sessionsToKeep() helper
unconditionally re-adds the 'active' session id on every refresh to
survive an in-flight-first-turn race — with no source check, so a cron
session (source='cron', normally excluded from the recents list) gets
permanently pinned into the main sidebar the moment its run history is
viewed once.
Fix (apps/desktop): sessionsToKeep() takes an optional excludedSources
list; the active row is only kept if its source isn't in that list. The
two recents-list call sites (refreshSessions, loadMoreSessionsForProfile)
pass SIDEBAR_EXCLUDED_SOURCES so a viewed cron/subagent/tool/messaging
session can no longer leak into the main chat list.
Tests: tests/cron/test_cron_no_agent.py — 22 passed (4 new, covering
success/failure/silent run-session recording + broken-store fallback).
apps/desktop: tsc --noEmit and eslint clean on the changed file.
Contributor
|
Thanks for tracing both the missing no-agent run row and the sidebar interaction. The premise holds on current main: Problems
Suggested changes
Automated hermes-sweeper review. |
7 tasks
This was referenced Aug 3, 2026
This was referenced Aug 8, 2026
Open
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
no_agent: true(script-mode) cron jobs short-circuitrun_job()before anySessionDBwork, so they never produce thecron_{job_id}_{timestamp}session row that the run-history endpoint (GET /api/cron/jobs/{id}/runs) is built from. Manually triggering such a job gives zero feedback in the Desktop GUI: no running indicator, no run record, no output.This overlaps with #44080 / #42433 / #53692 — same root cause, but this PR also fixes a second bug that those left open: recording the run session introduces a sidebar leak.
Fix 1 —
cron/scheduler.pyIn the
no_agentbranch ofrun_job(): create the run session (cron_{job_id}_{ts},source='cron', matching the agent path's shape) before executing the script, so the runs endpoint'sis_activecheck reflects an in-flight run. After execution, persist the outcome doc as an assistant message, title the session, andend_session. Covers all four exit paths: success, script failure, empty-stdout silent run, andwakeAgent=falsesilent run.no_agentcost contract is preserved:run_agent/AIAgentare still never imported on this path (test_run_job_no_agent_never_invokes_aiagentstill passes).Fix 2 —
apps/desktop/src/app/session/hooks/use-session-list-actions.tsRecording the run session (Fix 1) surfaces a second, previously-latent bug: opening a cron run from the Cron panel's run-history list navigates to
/session/<cron_id>, which sets$selectedStoredSessionId. The desktop sidebar'ssessionsToKeep()helper unconditionally re-adds the "active" session id on every refresh (to survive an in-flight-first-turn race) — with no source check. So a cron session (source='cron', normally excluded from the recents list viaSIDEBAR_EXCLUDED_SOURCES) gets permanently pinned into the main sidebar the moment its run history is viewed once, and stays there across refreshes indefinitely.Fix:
sessionsToKeep()takes an optionalexcludedSourceslist; the active row is only kept if its source isn't in that list. The two recents-list call sites (refreshSessions,loadMoreSessionsForProfile) passSIDEBAR_EXCLUDED_SOURCESso a viewed cron/subagent/tool/messaging session can no longer leak into the main chat list.Testing
Related issues
Fixes #44080. Related: #42433, #53692 (same root cause, this PR additionally fixes the
sidebar-leak regression those introduce once the run session exists).