Conversation scheduling #
An explicit scheduling request can invoke the native Think createSchedule action. It creates an enabled task in the current conversation through the same parent task service used by /tasks. The result includes the saved ID, normalized schedule, actual native nextRunAt, status and /tasks/<id> URL. The existing task list and editor display and edit that record directly.
The action accepts a bounded name, execution instructions, and either a one-off future instant with an explicit offset and whole seconds or numeric five-field cron with timezone: "UTC". Canonical task validation remains in the Worker. The model cannot select an owner or another conversation. “Every Monday morning” requires a conversation clarification for an exact time and timezone; “every Monday at 09:00 UTC” maps to 0 9 * * 1. Local wall-clock recurrence and DST are not supported. Each native turn receives the current authoritative UTC time alongside the complete custom instructions, relevant memories and existing tool guidance. Execution instructions describe the work to perform; mentions of scheduling in existing tasks or research are not authorization to create more tasks.
Think's native action ledger uses the tool call ID. A deterministic task UUID derived from the conversation and that native call ID also protects the separate parent write: an accepted write whose reply was lost replays the same task, including its current edits. Conflicting creation input and deleted identities fail. Once Think settles a successful result, its native ledger replays that saved result; the task UI remains authoritative for subsequent edits. No extra action ledger, schedule store or transcript is introduced.
Cancellation and clear-generation checks surround pre-dispatch hashing and parent acquisition. The parent checks the still-active conversation, including after the task store's asynchronous hash. Stop or clear cannot roll back a mutation already accepted by the service. Conversation deletion removes its tasks using the existing lifecycle and native schedule cleanup. If native scheduling is unavailable, the saved result explicitly has status: "unavailable", schedulingError: "schedule_unavailable" and no next run; it never claims to be armed. Existing native reconciliation can repair it.
Run pnpm build:release followed by pnpm test:schedule-action. The test uses the real native Think/Agents Worker and WebSocket transport with a test-only MockLanguageModelV3, then opens and edits the action-created task in the packaged Kumo UI. It checks one-off normalization, unsupported/ambiguous timing rejection, action output and safe activity, lost acceptance replies across restart and edits, successful native ledger replay, tombstones, unavailable bindings, Stop/clear during parent acquisition, and deletion before mutation. Prompt assertions verify the clarification/current-time policy and retained instructions; they do not certify live model interpretation of natural language. The conversation UI is implemented separately in FLA-28; this gate drives the native chat transport directly. No live provider or Cloudflare-account execution is claimed.