Skip to content

feat(cli): add scheduled wakeup and cancel tools - #14094

Merged
iscekic merged 1 commit into
mainfrom
kwf/agent-scheduled-wakeup-tool-c6b8
Sep 14, 2026
Merged

iscekic merged 1 commit into
mainfrom
kwf/agent-scheduled-wakeup-tool-c6b8

Conversation

@iscekic

@iscekic iscekic commented Sep 13, 2026 •

Copy link
Copy Markdown
Collaborator

Changelog for users

  • The agent can schedule a future wakeup for its own session, and the session resumes at that time with the prompt it set.
  • The agent can list the wakeups pending for its session and cancel one by id.
  • Scheduled wakeups survive the process: they are stored and re-armed when the project is opened again, and overdue wakeups fire on start.
  • A delay under 10 seconds is raised to 10 seconds, and a time beyond 7 days is pulled back to 7 days; an absolute when fires as given and a past time is rejected.
  • A session holds at most 10 pending wakeups.
  • A wakeup that fires while the session is paused is logged as unresumable instead of disappearing silently.
  • On wake, the model receives its scheduled prompt marked [scheduled wakeup], with a note that no user is present.

Changelog for maintainers

  • packages/opencode/src/kilocode/wakeup/resume.ts:37 — accepted: resume reads the session's paused flag and logs error-level wakeup could not resume session with the id, session, directory, and reason=session is paused instead of letting the prompt path drop the wake; a missing session or directory takes the same error log. The wake turn is a synthetic text part that begins [scheduled wakeup], carries the scheduled prompt and a no-user note with the wake id and due time, and an idle session resumes through the session prompt path.
  • packages/opencode/src/kilocode/wakeup/index.ts:81 — accepted: a fire deletes its persisted file and marks the id as firing before resuming, so adopt cannot re-fire a turn that is already running; bootstrap calls adopt(directory), which fires overdue wakeups immediately and arms timers for the rest.
  • packages/opencode/src/kilocode/wakeup/index.ts:105 — accepted: the cap counts only parseable files and runs the count and write as one semaphore-guarded section, so corrupt files cannot hold slots and parallel schedules cannot pass the cap; two wakeups due at the same instant both fire.
  • packages/opencode/src/kilocode/wakeup/index.ts:124 — accepted: list merges the in-memory map with the persisted wakeup/sessionID/id store, so it sees wakeups saved before a restart; each record carries sessionID and directory, so the guarantee reaches a running process and the next CLI start in that directory, not a separate daemon.
  • packages/opencode/src/kilocode/tool/cancel-wakeup.ts:79 — accepted: cancel takes the caller's session id and reports an id owned by another session as not found; both tools ship to CLI and VS Code clients, and a changeset marks the CLI release as minor.
  • packages/opencode/src/kilocode/wakeup/schema.ts:8 — accepted: only delay is raised to the 10-second minimum; an absolute when is honored as given, and the comment and changelog now say so. Exactly one of when/delay; an explicit offset is absolute, otherwise the host timezone applies; a past time is rejected and a time past 7 days is pulled back.
  • packages/opencode/src/kilocode/tool/cancel-wakeup.txt:4 — accepted: the description now says list shows the reason, or the scheduled prompt when no reason was given.
  • packages/opencode/src/kilocode/wakeup/resume.ts:53 — accepted: an inPlace flag keeps the deadlock-avoiding in-place branch only on the overdue-adopt path, so a timer fire re-resolves the instance through provide; a fire while the model is running forks a detached prompt instead of blocking the timer. Check the resume path first, then the clamp math; the resume integration test needs a promise-facade guard allowlist entry because a static layer dependency between the wakeup node and the session prompt node is impossible; an orphaned ghostty-web patch with no patchedDependencies entry was removed.

E2E proof — log excerpts

Collected 2026-09-13. These live CLI captures replace the earlier schedule/list/cancel, clamp, cap, and validation transcript claims.

[e1] Live CLI: schedule a wakeup ~3 minutes out, restart the CLI in the same project directory, then `cancel_wakeup action=list` and cancel by id -> pass :: process 1 scheduled `wku_09cacc211001V9gVYKRWCAzcT8` due 2026-09-13T21:32:22.679Z (in 3m); a fresh process listed it with reason CHECK_DEPLOY and cancelled it; a third listed none and storage held 0 wakeup files, with 0 synthetic wake parts.
[e2] Live CLI: schedule a wakeup with a `when` about 5 seconds out -> pass :: it fired at roughly 5 seconds rather than being clamped to the 10-second minimum.
[e3] Live CLI: schedule a wakeup, abort the session before it is due, and let the due time pass -> pass :: the session gained no wake turn and the CLI log showed `wakeup could not resume session` naming the id, session, and directory with `reason=session is paused`.

Limitation: process 1 scheduled at 2026-09-13T21:29:22Z and the listing process started at 2026-09-13T21:29:34Z, so e1's restart/list/cancel was observed across CLI starts in the same directory; e3 depends on the abort leaving the session paused.

Owner request

Surface: the agent tools in this repo (packages/opencode/src/tool/ for core tools, packages/opencode/src/kilocode/tool/ for Kilo-specific ones, registered through packages/opencode/src/tool/registry.ts; each tool ships a .ts and a .txt description).

Add a scheduled wakeup tool and its cancel counterpart.

What it must do.

  • The model calls the wakeup tool with a point in time in the future and a reason or prompt to resume with. The harness wakes the model at that time and continues the session from that prompt.
  • A second tool cancels a scheduled wakeup, by its id, and can list what is pending so the model can see what it scheduled.
  • A wakeup survives the process: if the session is idle or the harness restarted, the wake still fires. Say in the PR body how far that guarantee reaches (a running daemon, the next CLI start, or a persisted queue the host drains) and pick the mechanism that already exists in this repo rather than adding a new daemon.

Design decisions the workflow makes, and must state in the PR body.

  • The time argument: accept an absolute time and/or a delay, and define the timezone behaviour and the clamps. There must be a minimum delay and a maximum horizon, and a cap on how many wakeups one session can hold.
  • Where the schedule is stored, and how it is keyed to the session so a wake resumes the right conversation.
  • What the model sees on wake: the prompt it scheduled, plus enough context to know a wakeup fired rather than a user message.
  • Whether an idle session is kept alive or restarted, and what happens if the session ended or its working directory is gone. A wake that cannot resume must fail loudly in a log, never silently disappear.
  • Concurrency: two wakeups due at the same moment, and a wake that fires while the model is already running.

Follow the repo's own conventions.

  • Read several existing tools in both tool directories first, especially one with persisted state and one that talks to the host process (background-process.ts is a good reference), and copy their shape: schema, description file, registration, permission handling, error messages.
  • The tool description (.txt) must tell the model when to use it and when not to, in the same voice as the existing descriptions.

Proof.

  • Unit tests next to the existing tool tests (packages/opencode/test/tool/, packages/opencode/test/kilocode/tool/): schedule, list, cancel, a past time rejected, the horizon and count clamps, a duplicate cancel, and persistence across a restart of whatever holds the schedule.
  • An end-to-end run of the real CLI that schedules a wakeup a short interval ahead, shows the session waking with the scheduled prompt, and shows a cancelled wakeup not firing. Capture the transcript in the PR body.

@kilo-code-bot

kilo-code-bot Bot commented Sep 13, 2026 •

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Files Reviewed (2 files)
  • packages/opencode/src/kilocode/wakeup/index.ts
  • packages/opencode/test/kilocode/wakeup/wakeup.test.ts
Previous Review Summaries (2 snapshots, latest commit ad942f9)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit ad942f9)

Status: 1 Issue Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 0
SUGGESTION 1
Issue Details (click to expand)

SUGGESTION

File Line Issue
packages/opencode/src/kilocode/wakeup/index.ts 97 The ensuring cleanup also runs on the early-return path, so it can clear an in-flight fire's guard (latent).

All eight findings from the previous review (paused-session drop, adopt/fire duplicate, cap accounting and atomicity, storage-backed list, session-scoped cancel, MIN_DELAY_MS wording, cancel-wakeup.txt wording, unreachable provide fallback) are resolved on the changed lines: resume now reads the paused flag and logs, fireNow claims the wake via firing + pre-resume persistence removal, schedule counts parseable entries under a semaphore, list merges the persisted store, cancel takes the caller session, and the inPlace flag scopes the in-place resume to the overdue-adopt path.

Files Reviewed (11 files)
  • packages/opencode/src/kilocode/session/control.ts
  • packages/opencode/src/kilocode/tool/cancel-wakeup.ts
  • packages/opencode/src/kilocode/tool/cancel-wakeup.txt
  • packages/opencode/src/kilocode/wakeup/index.ts - 1 issue
  • packages/opencode/src/kilocode/wakeup/resume.ts
  • packages/opencode/src/kilocode/wakeup/schema.ts
  • packages/opencode/src/session/prompt.ts
  • packages/opencode/test/kilocode/tool/cancel-wakeup.test.ts
  • packages/opencode/test/kilocode/wakeup/wakeup-resume.test.ts
  • packages/opencode/test/kilocode/wakeup/wakeup.test.ts
  • script/check-opencode-promise-facades.ts

Fix these issues in Kilo Cloud

Previous review (commit e9d14e4)

Status: 8 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 2
SUGGESTION 6
Issue Details (click to expand)

WARNING

File Line Issue
packages/opencode/src/kilocode/wakeup/resume.ts 37 A wake that fires while the session is paused is silently consumed with no error log.
packages/opencode/src/kilocode/wakeup/index.ts 81 Duplicate fire when adopt races an in-flight fireNow (persistence removed after fire.run).

SUGGESTION

File Line Issue
packages/opencode/src/kilocode/wakeup/index.ts 105 Cap counts persisted files, so corrupt files permanently consume slots; check is not atomic.
packages/opencode/src/kilocode/wakeup/index.ts 124 list reads only the in-memory map while cancel falls back to storage.
packages/opencode/src/kilocode/tool/cancel-wakeup.ts 79 cancel is not scoped to the caller's session, unlike list.
packages/opencode/src/kilocode/wakeup/schema.ts 8 MIN_DELAY_MS comment/changelog overstate the minimum, which only applies to delay.
packages/opencode/src/kilocode/tool/cancel-wakeup.txt 4 Says the list shows the prompt, but it renders reason ?? prompt.
packages/opencode/src/kilocode/wakeup/resume.ts 53 The provide fallback is unreachable, so a reloaded instance is never re-resolved.
Files Reviewed (20 files)
  • .changeset/scheduled-wakeup.md
  • packages/opencode/src/effect/app-runtime.ts
  • packages/opencode/src/kilocode/bootstrap.ts
  • packages/opencode/src/kilocode/tool/cancel-wakeup.ts
  • packages/opencode/src/kilocode/tool/cancel-wakeup.txt
  • packages/opencode/src/kilocode/tool/registry.ts
  • packages/opencode/src/kilocode/tool/schedule-wakeup.ts
  • packages/opencode/src/kilocode/tool/schedule-wakeup.txt
  • packages/opencode/src/kilocode/wakeup/index.ts
  • packages/opencode/src/kilocode/wakeup/resume.ts
  • packages/opencode/src/kilocode/wakeup/schema.ts
  • packages/opencode/src/tool/registry.ts
  • packages/opencode/test/kilocode/tool-registry-indexing.test.ts
  • packages/opencode/test/kilocode/tool/cancel-wakeup.test.ts
  • packages/opencode/test/kilocode/tool/schedule-wakeup.test.ts
  • packages/opencode/test/kilocode/wakeup/wakeup-resume.test.ts
  • packages/opencode/test/kilocode/wakeup/wakeup.test.ts
  • packages/opencode/test/tool/registry.test.ts
  • patches/ghostty-web@0.3.0.patch
  • script/check-opencode-promise-facades.ts

Fix these issues in Kilo Cloud


Reviewed by deepseek-v4.1-flash · Input: 0 · Output: 0 · Cached: 0

Review guidance: REVIEW.md from base branch main

@iscekic
iscekic marked this pull request as draft September 13, 2026 18:29
iscekic added a commit that referenced this pull request Sep 13, 2026
@iscekic
iscekic force-pushed the kwf/agent-scheduled-wakeup-tool-c6b8 branch from e9d14e4 to ad942f9 Compare September 13, 2026 21:38
@iscekic
iscekic marked this pull request as ready for review September 13, 2026 21:48
@iscekic
iscekic marked this pull request as draft September 13, 2026 21:52
@iscekic
iscekic force-pushed the kwf/agent-scheduled-wakeup-tool-c6b8 branch from ad942f9 to 8438f8d Compare September 13, 2026 22:28
@iscekic
iscekic marked this pull request as ready for review September 13, 2026 22:39
@iscekic
iscekic requested a review from lambertjosh September 13, 2026 22:46
@iscekic iscekic added the human-ready PR is ready for a human review. label Sep 13, 2026
@iscekic iscekic self-assigned this Sep 13, 2026
@iscekic
iscekic merged commit b7070e5 into main Sep 14, 2026
33 checks passed
@iscekic
iscekic deleted the kwf/agent-scheduled-wakeup-tool-c6b8 branch September 14, 2026 13:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

human-ready PR is ready for a human review.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants