docs(schedule): add subsystem reference
This commit is contained in:
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write docs/persistence-catalog.md
|
||||
persistence-catalog.md: 535ccdac8dafaa99116f686d1c7772ca1ceda6e9
|
||||
persistence-catalog.zh.md: b0eb3b69e026b960f00a70de0942f502b36faf1e
|
||||
persistence-catalog.md: 2ca0bad217f37c5c35298ec04ce7f9c8a9b88d9f
|
||||
persistence-catalog.zh.md: 4f927eaae8a634acdda49688a417c57b4541e579
|
||||
@@ -519,6 +519,8 @@ Source: [`packages/sandbox/sandbox-policy/src/session-mode.ts:33`](../packages/s
|
||||
'schedule/change': ScheduleChange
|
||||
```
|
||||
|
||||
Types: [ScheduleChange](subsystems/schedule.md)
|
||||
|
||||
Source: [`packages/schedule/tool-schedule/src/types.ts:144`](../packages/schedule/tool-schedule/src/types.ts)
|
||||
|
||||
### `session/*`
|
||||
|
||||
@@ -521,6 +521,8 @@ export type SessionEvent<T extends SessionEventType = SessionEventType> = {
|
||||
'schedule/change': ScheduleChange
|
||||
```
|
||||
|
||||
类型:[ScheduleChange](subsystems/schedule.md)
|
||||
|
||||
来源:[`packages/schedule/tool-schedule/src/types.ts:144`](../packages/schedule/tool-schedule/src/types.ts)
|
||||
|
||||
### `session/*`
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write docs/subsystems/README.md
|
||||
README.md: 096fd7de4d2644dac664fac940b6487052115258
|
||||
README.zh.md: 6b6758db8f7118a09f6b0998231d3944f44f5052
|
||||
README.md: fea77566dd2cf07af04619203ef5a94dad6b2dc0
|
||||
README.zh.md: dfcd5a6360d375f710213b3cb944695f19f488d6
|
||||
@@ -12,6 +12,7 @@ One page per subsystem of the DeepSeek Harness: what it is, the data structures
|
||||
| [scope.md](scope.md) | scoped registration identity, dispatch carriers, and the owned `Scope` context |
|
||||
| [typert.md](typert.md) | Remote invocation descriptors, lookup/Context declarations, TypeRT registries, and the Host Gateway/Client API boundaries |
|
||||
| [goal.md](goal.md) | persisted goal identity, lifecycle snapshots, activation, change records, and round attribution |
|
||||
| [schedule.md](schedule.md) | Session-local reminder records, durable transitions, active views, and ordinary-conversation delivery |
|
||||
| [commands.md](commands.md) | the human-command registry service: definitions, adapter discovery, direct invocation, results, and parsing views |
|
||||
| [session.md](session.md) | the full `SessionEventMap` variant catalog, `TurnTrigger`/`TurnEndReason`, `deriveMessages()`, execution enclosure, and standalone events |
|
||||
| [persistence.md](persistence.md) | the durability seam: `SessionPersistence`, JSONL + SQLite backends, `session/flush`, crash recovery, `SessionHeader` |
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
| [scope.md](scope.md) | 作用域注册标识、dispatch 载体,以及拥有的 `Scope` 上下文 |
|
||||
| [typert.md](typert.md) | 远程调用描述符、lookup/Context 声明、TypeRT 注册表,以及 Host Gateway/Client API 边界 |
|
||||
| [goal.md](goal.md) | 持久 goal 标识、生命周期快照、激活、变更记录与 Round 归属 |
|
||||
| [schedule.md](schedule.md) | 仅限 Session 内的提醒记录、持久转换、活动视图与普通对话交付 |
|
||||
| [commands.md](commands.md) | 人类命令注册表服务:定义、适配器发现、直接调用、结果与解析视图 |
|
||||
| [session.md](session.md) | 完整的 `SessionEventMap` 变体目录、`TurnTrigger`/`TurnEndReason`、`deriveMessages()`、执行封闭与独立事件 |
|
||||
| [persistence.md](persistence.md) | 持久性 seam:`SessionPersistence`、JSONL + SQLite 后端、`session/flush`、崩溃恢复、`SessionHeader` |
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write docs/subsystems/schedule.md
|
||||
schedule.md: 4357434fade3b49d6a4704bf8c6b28591e7460c9
|
||||
schedule.zh.md: c8291e782068cbff32c9a130a06680506f383c42
|
||||
@@ -0,0 +1,100 @@
|
||||
# Session-local Schedule
|
||||
|
||||
English | [中文](schedule.zh.md)
|
||||
|
||||
Schedule owns durable reminders that return to the original live Session as ordinary later conversation turns. The [durable Schedule Agent Note](../../.agents/notes/implemented/feature/2026-08-05-durable-web-schedule.md) owns the persistence and lifecycle decisions, and [conversational delivery](../../.agents/notes/implemented/simplification/2026-08-09-conversational-schedule-delivery.md) owns the no-receipt boundary. This page records the durable and model-facing shapes from [`packages/schedule/tool-schedule/src/types.ts`](../../packages/schedule/tool-schedule/src/types.ts); the [package README](../../packages/schedule/tool-schedule/README.md) owns composition, tool behavior, and the exact reminder framing.
|
||||
|
||||
## Durable records
|
||||
|
||||
`ScheduleId` is a [branded id](core.md#branded-ids), unique and never reused within one Session. Version 1 initially supports a positive safe-integer `after_seconds` selector. Creation canonicalizes the selected target into a four-digit-year RFC 3339 UTC `scheduledAt`; the submitted delay remains in the record so list results explain the rule that produced it.
|
||||
|
||||
```ts type-equiv
|
||||
/** Durable one-shot reminder created from a positive delay. */
|
||||
interface AfterScheduleRecord {
|
||||
/** Session-local stable identity. */
|
||||
readonly id: ScheduleId
|
||||
/** Rule discriminator; v1 supports only delayed one-shot reminders. */
|
||||
readonly kind: 'after'
|
||||
/** Trimmed reminder content supplied at creation. */
|
||||
readonly prompt: string
|
||||
/** Positive safe-integer delay accepted at creation. */
|
||||
readonly afterSeconds: number
|
||||
/** Four-digit-year RFC 3339 UTC target. */
|
||||
readonly scheduledAt: string
|
||||
}
|
||||
```
|
||||
|
||||
```ts type-equiv
|
||||
/** The v1 durable reminder record union. */
|
||||
type ScheduleRecord = AfterScheduleRecord
|
||||
```
|
||||
|
||||
## Durable changes and replay
|
||||
|
||||
The version-1 `schedule/change` Session event is the only durable Schedule authority. Create stores the complete record. Delete and dispatch are terminal id-only transitions for one-shot reminders; dispatch means the follow-up was synchronously queued, not that a model answer succeeded or the user read it.
|
||||
|
||||
```ts type-equiv
|
||||
/** Creates one durable reminder record. */
|
||||
interface ScheduleCreateChange {
|
||||
readonly version: 1
|
||||
readonly operation: 'create'
|
||||
readonly schedule: ScheduleRecord
|
||||
}
|
||||
```
|
||||
|
||||
```ts type-equiv
|
||||
/** Deletes one currently active reminder. */
|
||||
interface ScheduleDeleteChange {
|
||||
readonly version: 1
|
||||
readonly operation: 'delete'
|
||||
readonly id: ScheduleId
|
||||
}
|
||||
```
|
||||
|
||||
```ts type-equiv
|
||||
/** Records that one active one-shot reminder entered the durable dispatch history. */
|
||||
interface ScheduleDispatchChange {
|
||||
readonly version: 1
|
||||
readonly operation: 'dispatch'
|
||||
readonly id: ScheduleId
|
||||
}
|
||||
```
|
||||
|
||||
```ts type-equiv
|
||||
/** Strict version-1 durable Schedule mutation union. */
|
||||
type ScheduleChange = ScheduleCreateChange | ScheduleDeleteChange | ScheduleDispatchChange
|
||||
```
|
||||
|
||||
The strict decoder and fold reject unknown versions, extra fields, reused ids, and delete or dispatch transitions against inactive records. A normal Session folds its complete event stream. A fork folds only events at or after `SessionHeader.seedLength`, so it retains history without adopting the parent Session's active reminders. The `schedule/change` declaration and source location are also indexed in the [persistence catalog](../persistence-catalog.md#schedulechange--log-only).
|
||||
|
||||
## Active views and management
|
||||
|
||||
Tool values combine the durable record with delivery state derived from the current wall clock. `session-local` means the original Session must be live: no external notification channel or cold-session scheduler exists.
|
||||
|
||||
```ts type-equiv
|
||||
/** Current delivery timing derived from the durable record and wall clock. */
|
||||
type ScheduleState = 'scheduled' | 'overdue'
|
||||
```
|
||||
|
||||
```ts type-equiv
|
||||
/** Fixed v1 delivery boundary: the original session must be live. */
|
||||
type ScheduleDeliveryMode = 'session-local'
|
||||
```
|
||||
|
||||
```ts type-equiv
|
||||
/** Complete model-facing view of one active after reminder. */
|
||||
interface ScheduleView extends AfterScheduleRecord {
|
||||
/** Whether the target remains in the future. */
|
||||
readonly state: ScheduleState
|
||||
/** Reminder delivery never leaves the owning session. */
|
||||
readonly deliveryMode: ScheduleDeliveryMode
|
||||
}
|
||||
```
|
||||
|
||||
The generated [tool catalog](../tool-catalog.md#deepseek-aidsh-tool-schedule) owns the argument and result schemas for `schedule_create`, `schedule_list`, and `schedule_delete`. Management calls serialize with due work in one Agent-scoped queue. Every read or decision first waits for the shared Session persistence barrier; create and an actual delete wait again after appending. A barrier failure reports `persistence_uncertain` instead of guessing whether an eager write committed. The other stable error codes are `invalid_prompt`, `invalid_selector`, `invalid_rule`, `time_out_of_range`, `corrupt_schedule_log`, and `internal_error`.
|
||||
|
||||
## Live delivery
|
||||
|
||||
The process-local owner derives its earliest timer from the durable fold and rereads the wall clock after every bounded wait. Cold Sessions do no work; reopening one reconstructs timers and makes a past target overdue. An overdue reminder waits for the Agent to become fully idle and claims the maintenance phase before it refolds state, queues `followup()`, and appends dispatch. It never calls `steer()` and never interrupts a current turn.
|
||||
|
||||
The admitted follow-up starts one normal later turn and appears only through the ordinary conversation transcript; Schedule has no independent durable Web receipt or browser renderer. If framing or synchronous queue admission fails, no dispatch is recorded and the reminder stays active. The narrow crash interval after admission but before durable dispatch can repeat the reminder after recovery, so the boundary is best-effort at-least-once rather than exactly-once delivery.
|
||||
@@ -0,0 +1,100 @@
|
||||
# 仅限 Session 内的 Schedule
|
||||
|
||||
[English](schedule.md) | 中文
|
||||
|
||||
Schedule 拥有持久提醒;这些提醒会作为普通的后续对话轮次返回原 live Session。[持久 Schedule Agent Note](../../.agents/notes/implemented/feature/2026-08-05-durable-web-schedule.md) 负责持久化与生命周期决策,[对话式交付](../../.agents/notes/implemented/simplification/2026-08-09-conversational-schedule-delivery.md) 负责无回执边界。本页记录 [`packages/schedule/tool-schedule/src/types.ts`](../../packages/schedule/tool-schedule/src/types.ts) 中的持久数据形状和面向模型的数据形状;[包 README](../../packages/schedule/tool-schedule/README.md) 负责组合、工具行为与确切的提醒 framing。
|
||||
|
||||
## 持久记录
|
||||
|
||||
`ScheduleId` 是[品牌化 id](core.md#branded-ids),在单个 Session 内唯一且绝不复用。版本 1 最初只支持正的安全整数 `after_seconds` 选择器。创建操作会将选定目标规范化为使用四位年份的 RFC 3339 UTC `scheduledAt`;记录仍保留提交的延时,以便 list 结果说明生成该目标所用的规则。
|
||||
|
||||
```ts type-equiv
|
||||
/** Durable one-shot reminder created from a positive delay. */
|
||||
interface AfterScheduleRecord {
|
||||
/** Session-local stable identity. */
|
||||
readonly id: ScheduleId
|
||||
/** Rule discriminator; v1 supports only delayed one-shot reminders. */
|
||||
readonly kind: 'after'
|
||||
/** Trimmed reminder content supplied at creation. */
|
||||
readonly prompt: string
|
||||
/** Positive safe-integer delay accepted at creation. */
|
||||
readonly afterSeconds: number
|
||||
/** Four-digit-year RFC 3339 UTC target. */
|
||||
readonly scheduledAt: string
|
||||
}
|
||||
```
|
||||
|
||||
```ts type-equiv
|
||||
/** The v1 durable reminder record union. */
|
||||
type ScheduleRecord = AfterScheduleRecord
|
||||
```
|
||||
|
||||
## 持久变更与回放
|
||||
|
||||
版本 1 的 `schedule/change` 会话事件是 Schedule 唯一的持久权威。create 保存完整记录。delete 与 dispatch 是一次性提醒的终结性、仅含 id 的转换;dispatch 表示 follow-up 已同步入队,而不表示模型答复成功或用户已读取答复。
|
||||
|
||||
```ts type-equiv
|
||||
/** Creates one durable reminder record. */
|
||||
interface ScheduleCreateChange {
|
||||
readonly version: 1
|
||||
readonly operation: 'create'
|
||||
readonly schedule: ScheduleRecord
|
||||
}
|
||||
```
|
||||
|
||||
```ts type-equiv
|
||||
/** Deletes one currently active reminder. */
|
||||
interface ScheduleDeleteChange {
|
||||
readonly version: 1
|
||||
readonly operation: 'delete'
|
||||
readonly id: ScheduleId
|
||||
}
|
||||
```
|
||||
|
||||
```ts type-equiv
|
||||
/** Records that one active one-shot reminder entered the durable dispatch history. */
|
||||
interface ScheduleDispatchChange {
|
||||
readonly version: 1
|
||||
readonly operation: 'dispatch'
|
||||
readonly id: ScheduleId
|
||||
}
|
||||
```
|
||||
|
||||
```ts type-equiv
|
||||
/** Strict version-1 durable Schedule mutation union. */
|
||||
type ScheduleChange = ScheduleCreateChange | ScheduleDeleteChange | ScheduleDispatchChange
|
||||
```
|
||||
|
||||
严格 decoder 与 fold 会拒绝未知版本、额外字段、重复使用的 id,以及针对非活动记录的 delete 或 dispatch 转换。普通 Session 折叠完整事件流。fork 只折叠 `SessionHeader.seedLength` 位置及其后的事件,因此保留历史,但不会接管父 Session 的活动提醒。`schedule/change` 声明和源码位置也编入[持久化目录](../persistence-catalog.md#schedulechange--log-only)。
|
||||
|
||||
## 活动视图与管理
|
||||
|
||||
工具值将持久记录与根据当前墙钟派生的交付状态组合起来。`session-local` 表示原 Session 必须处于 live 状态:不存在外部通知渠道或 cold Session scheduler。
|
||||
|
||||
```ts type-equiv
|
||||
/** Current delivery timing derived from the durable record and wall clock. */
|
||||
type ScheduleState = 'scheduled' | 'overdue'
|
||||
```
|
||||
|
||||
```ts type-equiv
|
||||
/** Fixed v1 delivery boundary: the original session must be live. */
|
||||
type ScheduleDeliveryMode = 'session-local'
|
||||
```
|
||||
|
||||
```ts type-equiv
|
||||
/** Complete model-facing view of one active after reminder. */
|
||||
interface ScheduleView extends AfterScheduleRecord {
|
||||
/** Whether the target remains in the future. */
|
||||
readonly state: ScheduleState
|
||||
/** Reminder delivery never leaves the owning session. */
|
||||
readonly deliveryMode: ScheduleDeliveryMode
|
||||
}
|
||||
```
|
||||
|
||||
生成的[工具目录](../tool-catalog.md#deepseek-aidsh-tool-schedule)负责 `schedule_create`、`schedule_list` 和 `schedule_delete` 的参数与结果 schema。一条 Agent-scoped 队列将管理调用与到期工作串行化。每次读取或判断都会先等待共享的 Session 持久化 barrier;create 与实际执行的 delete 在追加后还会再次等待。barrier 失败会报告 `persistence_uncertain`,而不是猜测 eager write 是否已提交。其他稳定错误代码是 `invalid_prompt`、`invalid_selector`、`invalid_rule`、`time_out_of_range`、`corrupt_schedule_log` 和 `internal_error`。
|
||||
|
||||
## Live 交付
|
||||
|
||||
进程内 owner 根据持久 fold 派生最早的 timer,并在每次有界等待后重新读取墙钟。cold Session 不执行任何工作;重新打开后会重建 timer,并使已经过去的目标进入 overdue 状态。overdue 提醒会先等待 Agent 完全 idle 并认领 maintenance phase,再重新折叠状态、将 `followup()` 排入队列并追加 dispatch。它绝不会调用 `steer()`,也绝不会中断当前轮次。
|
||||
|
||||
获得准入的 follow-up 会启动一个普通的后续轮次,且只通过普通对话 transcript(文本记录)出现;Schedule 不提供独立的持久 Web 回执或浏览器渲染器。如果 framing 构造或同步队列准入失败,则不会记录 dispatch,提醒仍保持活动。follow-up 获得准入后、持久 dispatch 前的狭窄崩溃窗口可能使提醒在恢复后重复,因此该边界提供的是尽力而为的至少一次交付,而非恰好一次交付。
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write packages/schedule/README.md
|
||||
README.md: edcd84b11444c596028cbd9ccae3926e4fbfdca8
|
||||
README.zh.md: 09e6cb5bdd1a726cfa6c964438df011035ba0a1e
|
||||
README.md: 7fffe6efb91e92a5664ee30ef9bf7c77581fe346
|
||||
README.zh.md: a819dcb0e57cae834813479713d598ef26ce4ed3
|
||||
@@ -9,3 +9,5 @@ The Schedule family owns reminders whose durable state lives in the original Ses
|
||||
| `tool-schedule/` | Versioned Schedule events and fold, model-facing create/list/delete tools, and a live root-Agent timer owner | — |
|
||||
|
||||
The package deliberately exposes no public Schedule service or mutable database. Tools and runtime append to the Session stream; due work enters the same conversation through the Agent's ordinary follow-up queue.
|
||||
|
||||
See [Session-local Schedule](../../docs/subsystems/schedule.md) for the durable record, transition, view, and delivery contracts.
|
||||
@@ -9,3 +9,5 @@ Schedule 家族负责管理提醒,其持久状态保存在原 Session 日志
|
||||
| `tool-schedule/` | 版本化 Schedule 事件与 fold、面向模型的创建/列出/删除工具,以及 live 根 Agent timer owner | 无 |
|
||||
|
||||
本包有意不公开 Schedule service 或可变数据库。工具与 runtime 向 Session stream 追加事件;到期工作通过 Agent 的普通 follow-up 队列进入同一对话。
|
||||
|
||||
有关持久记录、转换、视图与交付约定,请参阅[仅限 Session 内的 Schedule](../../docs/subsystems/schedule.md)。
|
||||
@@ -39,6 +39,7 @@ const LINK_MAP: Record<string, string> = {
|
||||
CallId: 'core.md',
|
||||
ContentBlock: 'core.md',
|
||||
MessageSource: 'core.md',
|
||||
ScheduleChange: 'schedule.md',
|
||||
StreamChunk: 'llm-streaming.md',
|
||||
TokenUsage: 'llm-streaming.md',
|
||||
TodoItem: 'session.md',
|
||||
|
||||
@@ -294,7 +294,7 @@ describe('docsPages locale routes', () => {
|
||||
const translated = rootPages.filter(page => page.contentLocale === 'zh-CN')
|
||||
const fallbacks = rootPages.filter(page => page.contentLocale === 'en-US')
|
||||
|
||||
expect(translated).toHaveLength(42)
|
||||
expect(translated).toHaveLength(43)
|
||||
expect(translated.every(page => page.source.endsWith('.zh.md'))).toBe(true)
|
||||
expect(fallbacks).toEqual([])
|
||||
})
|
||||
|
||||
@@ -221,6 +221,51 @@
|
||||
"symbol": "GoalChanged",
|
||||
"source": "packages/goal/goal/src/domain.ts"
|
||||
},
|
||||
{
|
||||
"doc": "docs/subsystems/schedule.md",
|
||||
"symbol": "AfterScheduleRecord",
|
||||
"source": "packages/schedule/tool-schedule/src/types.ts"
|
||||
},
|
||||
{
|
||||
"doc": "docs/subsystems/schedule.md",
|
||||
"symbol": "ScheduleRecord",
|
||||
"source": "packages/schedule/tool-schedule/src/types.ts"
|
||||
},
|
||||
{
|
||||
"doc": "docs/subsystems/schedule.md",
|
||||
"symbol": "ScheduleCreateChange",
|
||||
"source": "packages/schedule/tool-schedule/src/types.ts"
|
||||
},
|
||||
{
|
||||
"doc": "docs/subsystems/schedule.md",
|
||||
"symbol": "ScheduleDeleteChange",
|
||||
"source": "packages/schedule/tool-schedule/src/types.ts"
|
||||
},
|
||||
{
|
||||
"doc": "docs/subsystems/schedule.md",
|
||||
"symbol": "ScheduleDispatchChange",
|
||||
"source": "packages/schedule/tool-schedule/src/types.ts"
|
||||
},
|
||||
{
|
||||
"doc": "docs/subsystems/schedule.md",
|
||||
"symbol": "ScheduleChange",
|
||||
"source": "packages/schedule/tool-schedule/src/types.ts"
|
||||
},
|
||||
{
|
||||
"doc": "docs/subsystems/schedule.md",
|
||||
"symbol": "ScheduleState",
|
||||
"source": "packages/schedule/tool-schedule/src/types.ts"
|
||||
},
|
||||
{
|
||||
"doc": "docs/subsystems/schedule.md",
|
||||
"symbol": "ScheduleDeliveryMode",
|
||||
"source": "packages/schedule/tool-schedule/src/types.ts"
|
||||
},
|
||||
{
|
||||
"doc": "docs/subsystems/schedule.md",
|
||||
"symbol": "ScheduleView",
|
||||
"source": "packages/schedule/tool-schedule/src/types.ts"
|
||||
},
|
||||
{
|
||||
"doc": "docs/subsystems/commands.md",
|
||||
"symbol": "CommandInputDescriptor",
|
||||
|
||||
@@ -369,6 +369,7 @@ const reference = [
|
||||
}))),
|
||||
...pairedPages(([
|
||||
['goal.md', '目标', 'Goals', 14],
|
||||
['schedule.md', '定时提醒', 'Scheduled reminders', 15],
|
||||
['pty.md', 'PTY 会话', 'PTY sessions', 26],
|
||||
['commands.md', '命令', 'Human commands', 38],
|
||||
] as const).map(([file, rootLabel, enLabel, order]): PairedPage => ({
|
||||
|
||||
Reference in New Issue
Block a user