Skip to content

fix(cron): tell the agent scheduling is a handoff - #2219

Merged
bobleer merged 1 commit into
mainfrom
bob/bitfun-agent-wait-issue-1c9f2f
Aug 11, 2026
Merged

fix(cron): tell the agent scheduling is a handoff#2219
bobleer merged 1 commit into
mainfrom
bob/bitfun-agent-wait-issue-1c9f2f

Conversation

@bobleer

@bobleer bobleer commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

Problem

Asked to pace itself with a scheduled job instead of a wait loop, the agent created one — cron_4d437971, every 30 minutes, bound to the current session — and then kept working for another half hour before stopping on its own.

Nothing was broken. Cron add returns:

Created scheduled job 'BitFun 推广轮次 30min' (cron_4d437971) for session '…' in workspace '…'.

and nothing more. That reads as an ordinary success, and no tool can end a turn — only the model choosing to stop ends one. So the agent, still holding the loop it had just handed to the scheduler, went on driving that loop itself.

That is worse than untidy. A scheduled run is submitted as a queued dialog turn at DialogQueuePriority::Low (service.rs), so it is never run in parallel with the turn already in flight — a round that outlives the interval simply delays the trigger it is racing. The round in question took 32m11s against a 30-minute interval, which turns "every 30 minutes" into back-to-back rounds.

Changes

  • Say it in the add result — but only when the job genuinely takes over this turn's cadence: it repeats (every / cron, not a one-shot at) and it targets the current session. A single reminder, or a job scheduled for some other session, says nothing about the rest of this turn and must not cut real work short.
  • Say it in the tool description too, so the model knows before it commits to a plan rather than after — including that a run firing into a busy session is queued, so the interval wants to be comfortably longer than one round takes.
  • Drop the claim that Cron "ends the turn and re-invokes you", added alongside the browser.wait fix in fix(control-hub): make browser.wait actually wait #2212. It does not, and a model that believed it would hold the turn open waiting for an end that never comes. Reworded to say plainly that creating the job does not end the turn and the agent must end it itself; the mode-availability note added in fix(agents): give every ControlHub mode the Cron tool #2215 is preserved.

Testing

cargo test -p bitfun-core --lib — 1949 passed, 0 failed.

Four new tests cover the guidance appearing for a repeating every schedule and for a cron expression, and not appearing for a one-shot at job, for a job targeting a different session, or when the caller has no session identity to compare against.

cargo fmt --check and cargo clippy are unchanged from the base — 9 pre-existing fmt diffs and 11 pre-existing MutexGuard held across await findings, none in the files this PR touches.

Not changed

The workspace-level scheduled-jobs panel filters to targetKind: 'workspace', so the session-scoped jobs the Cron tool creates never appear there — it reports "此工作区还没有定时任务" while a job bound to that workspace exists. Real, but a separate concern from this one, and left for its own PR.

Asked to pace itself with a cron job, the agent created one and then kept
working for another half hour before stopping on its own. Nothing was
broken: `Cron add` returns "Created scheduled job ..." and nothing more, so
the call reads as an ordinary success, and no tool can end a turn — only
the model stopping ends it. With the loop it just handed to the scheduler
still in its head, it drives that loop itself.

That is worse than untidy. A scheduled run is submitted as a queued dialog
turn at low priority, so it is never run in parallel with the turn already
in flight; a round that outlives the interval simply delays the trigger it
is racing. The round in question took 32m against a 30m interval, which
turns "every 30 minutes" into back-to-back rounds.

- Say it in the `add` result, but only when the job actually takes over
  this turn's cadence: it repeats, and it targets this session. A one-shot
  reminder, or a job scheduled for some other session, must not cut the
  current turn short.
- Say it in the tool description too, so the model knows before it commits
  to a plan rather than after — including that a run firing into a busy
  session is queued, so the interval wants to be longer than a round.
- Drop the claim, added with the browser.wait fix, that Cron "ends the turn
  and re-invokes you". It does not, and a model that believed it would keep
  the turn open waiting for an end that never comes.
@bobleer
bobleer merged commit 23571fd into main Aug 11, 2026
7 checks passed
@bobleer
bobleer deleted the bob/bitfun-agent-wait-issue-1c9f2f branch August 11, 2026 09:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant