feat(schedule): add fixed-rate reminders

This commit is contained in:
pku-xht
2026-08-06 20:37:08 +08:00
committed by Tianyi Cui
parent 1e6e92fb0a
commit ceb0bbd66d
19 changed files with 2173 additions and 528 deletions

View File

@@ -1,19 +1,23 @@
# Session-local Schedule
# Durable Web Schedule
English | [中文](README.zh.md)
This overlay opts one `dsh web` process into Schedule reminders without changing the shipped default Web composition:
This overlay opts one `dsh web` process into durable Schedule reminders without changing the shipped default Web composition:
```sh
dsh web --patch examples/web-schedule/cordis.yml
```
The current overlay supports one-shot reminders created with a positive whole-number `after_seconds` or an absolute `at` target. The model manages them through `schedule_create`, `schedule_list`, and `schedule_delete`; every result identifies delivery as `session-local`.
The current overlay supports one-shot reminders created with a positive whole-number `after_seconds` or an absolute `at` target, plus fixed-rate `every_seconds` reminders at intervals of at least 300 seconds. The model manages them through `schedule_create`, `schedule_list`, and `schedule_delete`; every result identifies the delivery mode as `session-local`.
The browser attaches its IANA zone to each prompt. Time-context tells the model to interpret otherwise-unqualified dates and times in that request's browser zone. This assumption belongs to natural-language interpretation only: `schedule_create.at` must be either a strict RFC 3339 date-time with `Z` or a numeric offset, or `{ date, time, time_zone }` with an explicit `UTC` or IANA Area/Location zone. Schedule does not retain or infer a Session default zone. Daylight-saving gaps are rejected, overlaps choose the first instant, and successful records keep only the resulting UTC target.
An `at` target is either a strict RFC 3339 date-time with `Z` or a numeric offset, or a local `{ date, time, time_zone? }` value. The overlay loads time-context so the model sees the current date, local time, Session zone, and request-zone relationship before calling the tool. A local value may omit `time_zone` only when the current browser zone agrees with the immutable zone captured when that Session was created.
The original Session log owns each reminder. A live root Agent waits until it is fully idle, then queues a normal follow-up turn in that conversation. It never steers current work and adds no separate receipt or reminder card. Closing the process or leaving the Session cold stops its in-memory timer without deleting the record; reopening that same Session restores the wait and delivers an overdue reminder. Reading cold history never activates it, and a fork does not inherit its parent's reminders.
The browser samples its zone for each create or prompt operation. Resuming the Session from another zone does not overwrite the original default: an omitted local zone then returns `timezone_confirmation_required`, and the model asks which zone to use before retrying explicitly. Older headerless Sessions behave the same way with an unavailable default. Daylight-saving gaps are rejected and overlaps choose the first instant; successful records keep only the resulting UTC target.
Create and actual delete operations acknowledge success only after Session persistence confirms their event prefix. Schedule does not provide browser, operating-system, email, SMS, or other external notification. A durable dispatch records that the follow-up was queued; it does not acknowledge model success or user receipt.
The original Session log owns each reminder. A live root Agent waits, retries after it becomes idle, and records a durable dispatch receipt in the Web conversation. Closing the process or leaving the Session cold stops its in-memory timer without deleting the record; reopening that same Session restores the wait and delivers an overdue reminder. Merely reading cold history never activates it, and a fork does not inherit its parent's reminders.
Fixed-rate and cron rules are not supported by this version.
Fixed-rate reminders remain anchored to their first target. A late wake or restart skips the missed backlog and presents only each record's latest due occurrence, then advances to its first future target. All overdue fixed-rate records share one model follow-up when the 300-second recurring gate opens, while each keeps its own durable dispatch, next target, and Web receipt. One-shot reminders bypass that gate.
Create and actual delete operations acknowledge success only after Session persistence confirms their event prefix. A reminder receipt likewise appears only after its dispatch is durable. Schedule does not provide browser, operating-system, email, SMS, or other external notification, and the best-effort model follow-up is not a delivery acknowledgement.
Cron rules are not accepted by this layer.