Skip to content

feat(runtime): unified Automation replaces session-internal CronJob (#643 by @hqhq1025, adopted with review fixes) - #656

Merged
jackwener merged 1 commit into
mainfrom
adopt/643-unified-automation
Jul 8, 2026
Merged

feat(runtime): unified Automation replaces session-internal CronJob (#643 by @hqhq1025, adopted with review fixes)#656
jackwener merged 1 commit into
mainfrom
adopt/643-unified-automation

Conversation

@jackwener

Copy link
Copy Markdown
Member

Adoption of #643 — the unified Automation primitive by @hqhq1025 — with the four review fixes applied, per the maintainer review on that PR.

Design pivot accepted

The unified Automation is a genuine superset of the #639 WakeupScheduler where it matters: durable automations.json persistence (fail-loud, shared-store-safe), cross-restart and cross-session cron (fires into a fresh session after the creator is archived), first-class once/interval/cron kinds, and a stronger cron parser. The author's test discipline is excellent (~2400 lines, behavioral, incl. a mutation-verify suite).

Review fixes applied on top (they reverted #639 decisions)

  • F1 — busy-session defer window restored to ~45min (was a fixed 5s×24 ≈ 120s then silent drop); a transient busy window can no longer terminally expire a once automation. (automation-scheduler.ts)
  • F2waiting_for_user is back in the heartbeat idle set — the wakeup's home scenario per feat(runtime): session-internal CronJob scheduling (#545 + review fixes) #639; the test that pinned the opposite is re-pinned. (automation-can-fire.ts)
  • F3 — thundering-herd jitter ported (recurring ±10% capped 15min, one-shot up-to-90s-early on :00/:30 round marks, computed on the actual fire timestamp; non-negative for recurring so a cron can't double-fire). (automation-state.ts, injectable random)
  • F5AutomationResultPreview cards replace the deleted CronJob preview instead of raw-JSON fallback; contract test drives the real tool output through the real renderer. (tool-activity.tsx)
  • LOW — terminal history cap 5→50; list output exposes deferred-fire counts.
  • Found during verification — the PR's always-on 5s scheduler tick kept the Node event loop alive, hanging the CLI test suite (and any CLI exit path skipping close()); the tick timer is now unref()ed in runtime-bootstrap.

Verification

Supersedes #643; the model-facing tool renames CronCreate/CronDelete/CronList → a single Automation tool (breaking for prompts/skills referencing old names — flagged in the PR body for release notes).

…643 by @hqhq1025) — adopted with review fixes F1-F3+F5

Adopts PR #643 (unified Automation: heartbeat + cron, single tool) onto
current main as a squash, preserving main's ToolCardBody dispatch and the
#647 tool-activity refactors, with the maintainer's review fixes:

- F1 (HIGH, automation-scheduler.ts): the busy-session defer budget is a
  ~45min wall-clock window (DEFER_WINDOW_MS, equivalent to the old
  wakeup-scheduler's 5s→5min exponential backoff), replacing the ~120s
  24-retry cap. A transient busy window no longer terminally expires a
  `once` automation — skipFire only runs when the window is exhausted.
- F2 (HIGH, automation-can-fire.ts): 'waiting_for_user' joins
  HEARTBEAT_IDLE_STATUSES (#639 decision — the wakeup's home scenario is
  starting a turn in place of the user); the desktop canfire test now pins
  the new set instead of the opposite.
- F3 (MEDIUM, automation-state.ts): computeJitter ported verbatim from the
  old wakeup-scheduler and wired into computeNextFire — recurring
  (interval/cron) re-schedules get up to 10% delay jitter capped at 15min,
  one-shot fires landing on :00/:30 get up to 90s early jitter, computed on
  the actual fire timestamp. Mirrored the old jitter unit tests and added
  wiring coverage; AutomationManagerDeps gains an injectable `random`.
- F5 (MEDIUM, packages/ui/tool-activity.tsx): AutomationResultPreview card
  (created/deleted/listed, localized) replaces the deleted
  CronJobResultPreview inside the shared ToolCardBody dispatch, plus a new
  desktop contract test binding the runtime tool's real output strings to
  the rendered card.
- LOW: MAX_TERMINAL_KEPT 5 → 50 (old wakeup history cap) and the
  model-facing list now surfaces deferred fire attempts (deferredFireCount),
  mirroring the old CronList fire_attempts.
- Fix: the CLI scheduler tick timer is unref()ed — the PR's always-on 5s
  tick kept the Node event loop alive, hanging any bootstrap consumer that
  exits without close() (this hung the CLI test suite indefinitely). Also
  allow-listed the PR's CLI persistence warnings in check-console.

Original feature authored by @hqhq1025 in #643.
@jackwener
jackwener merged commit 6a41cb5 into main Jul 8, 2026
3 checks passed
@Astro-Han
Astro-Han deleted the adopt/643-unified-automation branch July 14, 2026 05:05
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