From 41c29fa8326818acdc4dab617995ec50ecd42199 Mon Sep 17 00:00:00 2001 From: Chinesezjc Date: Thu, 24 Sep 2026 21:03:26 +0800 Subject: [PATCH 1/9] feat(schedule): ship the Schedule switch as an optional bundle The shipped Web composition carries `time-context`, `schedule`, and `ui-schedule` disabled. This adds `@deepseek-ai/dsh-experimental-schedule-bundle`, whose patch sets `disabled: false` on those three rows and inserts none, and names it in `OPTIONAL_BUNDLES` with a runtime dependency of `apps/cli`, so every installation ships it switched off and the Web Plugins page offers it in the Official group. The two Web suites and the built-Web Schedule Remote scenario enable the rows through that bundle instead of a scenario-local fixture. --- ...-schedule-opt-in-optional-bundle.i18n.yaml | 19 ++++ ...6-09-24-schedule-opt-in-optional-bundle.md | 32 +++++++ ...9-24-schedule-opt-in-optional-bundle.zh.md | 32 +++++++ ...web-default-schedule-composition.i18n.yaml | 22 ----- ...-09-24-web-default-schedule-composition.md | 39 -------- ...-24-web-default-schedule-composition.zh.md | 39 -------- apps/cli/package.json | 1 + .../web/tests/fixtures/schedule.patch.yml | 2 - .../web/tests/schedule-timing.expected.e2e.ts | 3 +- .../time-context-every-step.patch.yml | 7 +- apps/web/tests/schedule-after.e2e.ts | 7 +- docs/config-catalog.md | 1 + docs/config-catalog.zh.md | 1 + docs/module-graph.md | 2 + docs/module-graph.zh.md | 2 + docs/subsystems/schedule.i18n.yaml | 8 +- docs/subsystems/schedule.md | 4 +- docs/subsystems/schedule.zh.md | 4 +- docs/user/guide/schedule.i18n.yaml | 4 +- docs/user/guide/schedule.md | 2 +- docs/user/guide/schedule.zh.md | 2 +- packages/boot/app-boot/src/profile.ts | 1 + packages/bundle/web-app/README.i18n.yaml | 4 +- packages/bundle/web-app/README.md | 2 +- packages/bundle/web-app/README.zh.md | 2 +- packages/client/ui-schedule/README.i18n.yaml | 4 +- packages/client/ui-schedule/README.md | 2 +- packages/client/ui-schedule/README.zh.md | 2 +- packages/context/README.i18n.yaml | 4 +- packages/context/README.md | 2 +- packages/context/README.zh.md | 2 +- .../context/time-context/README.i18n.yaml | 4 +- packages/context/time-context/README.md | 2 +- packages/context/time-context/README.zh.md | 2 +- packages/experimental/README.i18n.yaml | 8 +- packages/experimental/README.md | 3 +- packages/experimental/README.zh.md | 3 +- .../schedule-bundle/README.i18n.yaml | 46 +++++++++ .../experimental/schedule-bundle/README.md | 94 +++++++++++++++++++ .../experimental/schedule-bundle/README.zh.md | 94 +++++++++++++++++++ .../schedule-bundle/cordis.patch.yml | 12 +++ .../experimental/schedule-bundle/icon.svg | 11 +++ .../schedule-bundle/locale/en.json | 6 ++ .../schedule-bundle/locale/zh.json | 6 ++ .../experimental/schedule-bundle/package.json | 48 ++++++++++ .../experimental/schedule-bundle/src/index.ts | 2 + .../schedule-bundle/tests/patch.spec.ts | 56 +++++++++++ .../schedule-bundle/tsconfig.json | 15 +++ .../schedule-bundle/tsdown.config.ts | 3 + packages/schedule/schedule/README.i18n.yaml | 4 +- packages/schedule/schedule/README.md | 2 +- packages/schedule/schedule/README.zh.md | 2 +- pnpm-lock.yaml | 15 +++ scripts/release/families.spec.ts | 1 + tsconfig.base.json | 1 + 55 files changed, 550 insertions(+), 148 deletions(-) create mode 100644 .agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.i18n.yaml create mode 100644 .agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.md create mode 100644 .agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.zh.md delete mode 100644 .agents/notes/implemented/architecture/2026-09-24-web-default-schedule-composition.i18n.yaml delete mode 100644 .agents/notes/implemented/architecture/2026-09-24-web-default-schedule-composition.md delete mode 100644 .agents/notes/implemented/architecture/2026-09-24-web-default-schedule-composition.zh.md delete mode 100644 apps/cli/tests/profiles/web/tests/fixtures/schedule.patch.yml create mode 100644 packages/experimental/schedule-bundle/README.i18n.yaml create mode 100644 packages/experimental/schedule-bundle/README.md create mode 100644 packages/experimental/schedule-bundle/README.zh.md create mode 100644 packages/experimental/schedule-bundle/cordis.patch.yml create mode 100644 packages/experimental/schedule-bundle/icon.svg create mode 100644 packages/experimental/schedule-bundle/locale/en.json create mode 100644 packages/experimental/schedule-bundle/locale/zh.json create mode 100644 packages/experimental/schedule-bundle/package.json create mode 100644 packages/experimental/schedule-bundle/src/index.ts create mode 100644 packages/experimental/schedule-bundle/tests/patch.spec.ts create mode 100644 packages/experimental/schedule-bundle/tsconfig.json create mode 100644 packages/experimental/schedule-bundle/tsdown.config.ts diff --git a/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.i18n.yaml new file mode 100644 index 0000000000..901bf1470d --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.i18n.yaml @@ -0,0 +1,19 @@ +# Bilingual-pair consistency record for 2026-09-24-schedule-opt-in-optional-bundle.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.md +/agent-note-schedule-as-an-opt-in-optional-bundle: + en: 8c2381fd778a9888 + zh: 8877255cb980eea1 +/agent-note-schedule-as-an-opt-in-optional-bundle/problem: + en: 26d8e4f92b6cf3c5 + zh: 48dcb89bbb4a7169 +/agent-note-schedule-as-an-opt-in-optional-bundle/decision: + en: 5edbd3d4f9007745 + zh: e12eb39513bed213 +/agent-note-schedule-as-an-opt-in-optional-bundle/alternatives-considered: + en: d12affa9097a1a50 + zh: 4190d195c6a6eb8d +/agent-note-schedule-as-an-opt-in-optional-bundle/consequences: + en: 00d9287c82256837 + zh: eb85623524e59b60 diff --git a/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.md b/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.md new file mode 100644 index 0000000000..b0c4eba715 --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.md @@ -0,0 +1,32 @@ +# Agent Note: Schedule as an opt-in optional bundle + +Status: implemented + +English | [中文](2026-09-24-schedule-opt-in-optional-bundle.zh.md) + +## Problem + +The shipped Web composition mounted `time-context`, `schedule`, and `ui-schedule`, so every Web session carried four Schedule tool schemas and one durable clock message per eligible step whether or not the deployment wanted reminders. The rows had no switch on the product surface: a deployment that wanted them off edited its own profile patch layer, and the `--patch apps/cli/config/examples/schedule/cordis.yml` overlay could only switch them on from a launch flag. + +## Decision + +`packages/bundle/web-app/cordis.patch.yml` inserts `time-context`, `schedule`, and `ui-schedule` with `disabled: true`, so the shipped Web composition mounts none of the three. The rows stay in the composition because an id-targeted patch overrides an existing row: a profile patch or a bundle sets a row's `disabled` to `false` without inserting it again. + +`@deepseek-ai/dsh-experimental-schedule-bundle` (`packages/experimental/schedule-bundle/`) carries three id-targeted patches in its `cordis.patch.yml`, one per row, each setting `disabled: false`; it inserts no row. `OPTIONAL_BUNDLES` in `packages/boot/app-boot/src/profile.ts` names the package, and `apps/cli` declares it as a runtime dependency, so every installation ships it switched off. The [experimental-as-optional-bundles decision](2026-09-21-experimental-capabilities-as-optional-bundles.md) owns the `OPTIONAL_BUNDLES` conventions and the localized `icon` and `meta.title` / `meta.description` metadata the Web Plugins page renders in its Official group. + +Enabling the bundle turns on `time-context` (a per-step clock reading with the sampled instant, the browser zone attached to the open request, and the elapsed time since the preceding model-visible message), `schedule` (durable reminders plus `schedule_create`, `schedule_list`, `schedule_update`, and `schedule_delete` on live root Agents), and `ui-schedule` (the Session reminder catalog and the Automation tasks page). The [Schedule subsystem](../../../../docs/subsystems/schedule.md) owns the durable records, delivery, and management operations; the [Web bundle](../../../../packages/bundle/web-app/README.md) owns the composition that carries the disabled rows. Disabling the bundle restores the shipped composition, and the Host stops scheduling while the `schedule` row stays disabled; stored task records remain in the Schedule domain. + +## Alternatives considered + +**Ship Schedule on by default.** Every Web session then pays four tool schemas in each request header and one durable user message per eligible step, and a conversation that never creates a reminder pays both costs. The arrangement also left the capability without an off switch on the product surface. + +**Keep a `--patch` overlay file.** An overlay is a launch-time argument rather than a product-surface switch, so a person using the shipped Web profile cannot reach it. It cannot re-insert the rows either: `applyEntryPatches` appends an `insert` list without de-duplicating ids, so an overlay that inserts `time-context` and `schedule` mounts each Host plugin a second time. + +**Extract the three rows out of the Web composition into the bundle.** The bundle would insert the rows instead of overriding them, so any profile that also inserts a row would mount the same Host plugin twice for the same reason. The disabled rows are what an override-style switch targets. + +## Consequences + +- A default `dsh web` session carries no Schedule tool schemas, no Session reminder catalog, no Automation tasks page, and no per-step clock reading. An installation that wants them enables the optional bundle from the Plugins page or lists the package in a profile's `dsh.profile.bundles`. +- An enabled installation adds four tool schemas to every live root Agent and one durable clock message per eligible step; the reading is model-visible and durable, so it replays, compacts, and appears in exported Session logs like any other user message. +- The bundle changes nothing in a composition that does not carry the three Web rows, and its package declares no plugin dependency, so enabling it cannot mount a Host service twice. +- The switch is configuration-only: `src/index.ts` is an empty module, the patch carries the runtime content, and the package owns no mutable runtime state, so it publishes no invariant companion. diff --git a/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.zh.md b/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.zh.md new file mode 100644 index 0000000000..871bd7b52e --- /dev/null +++ b/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.zh.md @@ -0,0 +1,32 @@ +# Agent Note: Schedule 作为按需开启的可选 bundle + +Status: implemented + +[English](2026-09-24-schedule-opt-in-optional-bundle.md) | 中文 + +## Problem + +发布的 Web 组合挂载了 `time-context`、`schedule` 与 `ui-schedule`,因此每个 Web 会话都会带上四个 Schedule 工具 schema,并在每个符合条件的步骤追加一条持久时钟消息,无论该部署是否需要提醒。产品界面上没有开关:想要关闭它们的部署只能改自己的 profile patch 层,而 `--patch apps/cli/config/examples/schedule/cordis.yml` overlay 只能通过启动参数打开它们。 + +## Decision + +`packages/bundle/web-app/cordis.patch.yml` 以 `disabled: true` 插入 `time-context`、`schedule` 与 `ui-schedule`,因此随发行版交付的 Web 组合不挂载其中任何一行。这三行仍留在组合中,因为按 id 定位的 patch 覆盖的是已存在的行:profile patch 或 bundle 把某行的 `disabled` 设为 `false`,无需再次插入它。 + +`@deepseek-ai/dsh-experimental-schedule-bundle`(`packages/experimental/schedule-bundle/`)在其 `cordis.patch.yml` 中携带三个按 id 定位的 patch,每行一个,各自把 `disabled` 设为 `false`;它不插入任何行。`packages/boot/app-boot/src/profile.ts` 的 `OPTIONAL_BUNDLES` 列出该包,`apps/cli` 将其声明为运行时依赖,因此每次安装都随包携带且默认关闭。[实验性能力作为可选 bundle 的决策](2026-09-21-experimental-capabilities-as-optional-bundles.zh.md)负责 `OPTIONAL_BUNDLES` 的约定,以及 Web 插件管理页在 Official 分组中渲染的本地化 `icon` 与 `meta.title` / `meta.description` 元数据。 + +启用该 bundle 会打开 `time-context`(每个步骤的时钟读数,包含采样瞬时、附加到当前开放请求的浏览器时区,以及自前一条模型可见消息以来的经过时长)、`schedule`(持久提醒,以及每个活跃根 Agent 上的 `schedule_create`、`schedule_list`、`schedule_update` 与 `schedule_delete`),以及 `ui-schedule`(Session 提醒目录与自动化任务页面)。持久记录、投递与管理操作由 [Schedule 子系统](../../../../docs/subsystems/schedule.zh.md)负责;承载这些禁用行的组合由 [Web bundle](../../../../packages/bundle/web-app/README.zh.md)负责。禁用该 bundle 会恢复随发行版交付的组合,`schedule` 行保持禁用期间 Host 不再调度;已存储的任务记录保留在 Schedule domain 中。 + +## Alternatives considered + +**默认发布 Schedule。** 那样每个 Web 会话都要在每个请求头中带上四个工具 schema,并在每个符合条件的步骤追加一条持久 user 消息,从不创建提醒的对话也要承担这两项成本。这种安排还让该能力在产品界面上没有关闭开关。 + +**保留一个 `--patch` overlay 文件。** overlay 是启动时的参数,而不是产品界面上的开关,因此使用随发行版 `web` profile 的人无法触及它。它也无法重新插入这些行:`applyEntryPatches` 追加 `insert` 列表时不对 id 去重,插入 `time-context` 与 `schedule` 的 overlay 会把每个 Host 插件挂载两次。 + +**把这三行从 Web 组合中抽出、移入 bundle。** 这样 bundle 会插入这些行而不是覆盖它们,任何同样插入某行的 profile 都会因同样的原因把同一个 Host 插件挂载两次。按需开关针对的正是这些禁用行。 + +## Consequences + +- 默认的 `dsh web` 会话不带 Schedule 工具 schema、Session 提醒目录、自动化任务页面与逐步时钟读数。需要它们的安装可从插件管理页启用该可选 bundle,或把该包列进 profile 的 `dsh.profile.bundles`。 +- 启用后的安装会给每个活跃根 Agent 增加四个工具 schema,并在每个符合条件的步骤追加一条持久时钟消息;该读数对模型可见且持久,因此它与其他 user 消息一样参与回放、压缩,并出现在导出的 Session 日志中。 +- 在不携带这三行 Web 行的组合中,该 bundle 不改变任何东西;其包不声明插件依赖,因此启用它不会重复挂载同一个 Host 服务。 +- 该开关只涉及配置:`src/index.ts` 是空模块,运行时内容由 patch 承载,包本身不拥有可变的运行时状态,因此不发布不变量伴随模块。 diff --git a/.agents/notes/implemented/architecture/2026-09-24-web-default-schedule-composition.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-24-web-default-schedule-composition.i18n.yaml deleted file mode 100644 index fec9a85467..0000000000 --- a/.agents/notes/implemented/architecture/2026-09-24-web-default-schedule-composition.i18n.yaml +++ /dev/null @@ -1,22 +0,0 @@ -# Bilingual-pair consistency record for 2026-09-24-web-default-schedule-composition.md (docs/i18n/README.md): per heading -# section, a hash of its English and Chinese blocks outside code blocks and generated regions. -# After editing either side, bring the other along and re-record with: -# pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-24-web-default-schedule-composition.md -/agent-note-schedule-in-the-shipped-web-composition: - en: 39229d7ab6ed433b - zh: 54287471d371a11c -/agent-note-schedule-in-the-shipped-web-composition/problem: - en: 2871fd5ed881c007 - zh: d03c78d402d186da -/agent-note-schedule-in-the-shipped-web-composition/decision: - en: bb19ad12b2ab0ffc - zh: 971f33e95474a36c -/agent-note-schedule-in-the-shipped-web-composition/recorded-sessions: - en: 5539a42052f4ddb7 - zh: 98cc190ae63b4549 -/agent-note-schedule-in-the-shipped-web-composition/alternatives-considered: - en: ca032a407c2ee8cb - zh: 748a4fcf2485a3da -/agent-note-schedule-in-the-shipped-web-composition/consequences: - en: 4f23bda8fda37987 - zh: 9f7c4a3538bd2979 diff --git a/.agents/notes/implemented/architecture/2026-09-24-web-default-schedule-composition.md b/.agents/notes/implemented/architecture/2026-09-24-web-default-schedule-composition.md deleted file mode 100644 index 91f533950a..0000000000 --- a/.agents/notes/implemented/architecture/2026-09-24-web-default-schedule-composition.md +++ /dev/null @@ -1,39 +0,0 @@ -# Agent Note: Schedule in the shipped Web composition - -Status: implemented - -English | [中文](2026-09-24-web-default-schedule-composition.zh.md) - -## Problem - -The Automation tasks page, the Session reminder catalog, and the `schedule_*` tools reached a Web deployment only through `--patch apps/cli/config/examples/schedule/cordis.yml`. `packages/bundle/web-app/cordis.patch.yml` carried the `ui-schedule` client row with `disabled: true`, and the Host rows `time-context` and `schedule` existed in that overlay alone. A person running the shipped `web` profile therefore saw no Automation tasks entry and no reminder tools, while every consumer that wanted them repeated the same three rows: the repository preview image kept its own overlay list, and two Web suites hard-coded the overlay path. - -## Decision - -`packages/bundle/web-app/cordis.patch.yml` inserts `time-context` and `schedule` in its Host row list and leaves `ui-schedule` enabled; `packages/bundle/web-app/package.json` declares both packages, which `verify-cordis-config` requires for a bare row name in a bundle patch. The `web` profile consequently ships the Automation tasks page, the Session-header reminder clock, the idle Session row's clock mark and hover list, the right-Sidebar task tab, and `schedule_create`, `schedule_list`, `schedule_update`, and `schedule_delete` on every live root Agent. - -`apps/cli/config/examples/schedule/cordis.yml` is deleted. `applyEntryPatches` appends an `insert` list without de-duplicating ids, so keeping the overlay would mount `time-context` and `schedule` a second time; the two Web suites and the preview packer that named the overlay compose the shipped profile alone. - -`time-context` ships with Schedule because a reminder request states a wall-clock target. The plugin appends one durable user message per eligible step carrying the sampled instant, the browser zone attached to the open request, and the elapsed time since the preceding model-visible message. The sampling instant is what lets the model turn a request such as "tomorrow at nine" into an offset-bearing `at` value; the [Schedule subsystem](../../../../docs/subsystems/schedule.md) owns that interpretation boundary and the explicit-zone requirement it feeds. - -The Host service, its storage domain, and the client half are unchanged. This decision moves which composition mounts them, and the [Host-owned scheduled messages decision](2026-09-16-host-schedule-storage.md) continues to own task storage, activation, dispatch, and delivery records. - -## Recorded sessions - -A Web scenario that drives a live step now logs one time-context reading per step, so its committed Session fixture and header sidecars were refreshed. A reading's sampled instant, browser zone, and elapsed duration are volatile, and `normalizeWebSessionVolatiles` in `apps/web/tests/scaffold.ts` replaces them with `{{timeContextTimestamp}}`, `{{clientTimeZone}}`, and `{{elapsed}}`. The turn and step numbers and the preceding-event baseline stay readable, so a fixture still shows what the model received. Refresh writes the current writer generation (`session.v4.jsonl`) beside the retained predecessors, which remain committed replay baselines. - -## Alternatives considered - -**Keep the overlay and change nothing.** The shipped surface would keep contradicting the product documentation that describes the Automation tasks entry, and each consumer would keep its own copy of the three rows. The overlay also cannot satisfy the request that the default `dsh web` process exposes the page without a flag. - -**Ship the Schedule rows without `time-context`.** The model would then have no sampling instant of its own, so an unqualified date or time in a reminder request would depend on a separate clock source; the overlay paired the two rows for that reason. - -**Reach for a separate optional bundle.** `OPTIONAL_BUNDLES` exists for bundles a person switches on from the plugin manager, which is the same opt-in shape as the overlay; the decision here is that a default Web surface owns the page and the tools. - -## Consequences - -- Every Web session's request header carries four additional tool schemas, and every eligible step appends one durable user message. A conversation that never creates a reminder pays that token cost. -- The clock reading is model-visible and durable, so it replays, compacts, and appears in exported Session logs like any other user message. -- A deployment that wants the previous behavior disables the `time-context`, `schedule`, and `ui-schedule` rows in its own profile patch layer; the capability itself is untouched. -- The `cordis_inspect_query` `listTools` answer for a full preset table now passes the base composition's 12,500-token inline budget, so the spill policy retains that answer's head and tail with a spill path instead of the complete JSON. -- The repository preview image and both Web suites drop their overlay arguments, so one composition change reaches every surface at once. diff --git a/.agents/notes/implemented/architecture/2026-09-24-web-default-schedule-composition.zh.md b/.agents/notes/implemented/architecture/2026-09-24-web-default-schedule-composition.zh.md deleted file mode 100644 index af561fe63e..0000000000 --- a/.agents/notes/implemented/architecture/2026-09-24-web-default-schedule-composition.zh.md +++ /dev/null @@ -1,39 +0,0 @@ -# Agent Note: 默认 Web 组合中的 Schedule - -Status: implemented - -[English](2026-09-24-web-default-schedule-composition.md) | 中文 - -## Problem - -自动化任务页面、Session 提醒目录以及 `schedule_*` 工具此前只能通过 `--patch apps/cli/config/examples/schedule/cordis.yml` 进入某个 Web 部署:`packages/bundle/web-app/cordis.patch.yml` 里的 `ui-schedule` 客户端行带 `disabled: true`,而宿主行 `time-context` 与 `schedule` 只存在于那个 overlay 中。因此运行发布版 `web` profile 的人既看不到自动化任务入口,也拿不到提醒工具;同时每个需要它们的消费者都要重复同样的三行:仓库预览镜像自行维护了一份 overlay 列表,两个 Web 测试套件各自硬编码了 overlay 路径。 - -## Decision - -`packages/bundle/web-app/cordis.patch.yml` 在其宿主行列表中插入 `time-context` 与 `schedule`,并让 `ui-schedule` 保持启用;`packages/bundle/web-app/package.json` 声明这两个包,这是 `verify-cordis-config` 对 bundle patch 中裸包名的要求。因此 `web` profile 会交付自动化任务页面、Session 页头的提醒时钟、空闲 Session 行的时钟标记与悬停列表、右侧栏任务页签,并在每个 live 根 Agent 上注册 `schedule_create`、`schedule_list`、`schedule_update` 与 `schedule_delete`。 - -`apps/cli/config/examples/schedule/cordis.yml` 已删除。`applyEntryPatches` 追加 `insert` 列表时不对 id 去重,保留该 overlay 会把 `time-context` 与 `schedule` 挂载两次;原本引用它的两个 Web 测试套件与预览打包器现在只组合发布版 profile。 - -`time-context` 随 Schedule 一起发布,因为提醒请求本身给出的是墙上时钟目标。该插件在每个符合条件的步骤追加一条持久 user 消息,包含采样瞬时、附加到当前开放请求的浏览器时区,以及自前一条模型可见消息以来的经过时长。正是采样瞬时让模型能把「明天九点」这类请求落成带偏移量的 `at` 值;该解释边界及其要求的显式时区由 [Schedule 子系统](../../../../docs/subsystems/schedule.zh.md)负责。 - -宿主服务、其存储 domain 与客户端半边都没有改动。本决策改变的是由哪个组合挂载它们,任务存储、激活、投递与投递记录仍由[宿主定时消息决策](2026-09-16-host-schedule-storage.zh.md)负责。 - -## Recorded sessions - -驱动 live 步骤的 Web 场景现在每步记录一条 time-context 读数,因此其已提交的 Session 夹具与页头 sidecar 都已重刷。一条读数中的采样瞬时、浏览器时区与经过时长是易变值,`apps/web/tests/scaffold.ts` 的 `normalizeWebSessionVolatiles` 会把它们替换为 `{{timeContextTimestamp}}`、`{{clientTimeZone}}` 和 `{{elapsed}}`。turn 与 step 序号以及"前一条事件"的基线保持可读,因此夹具仍能显示模型收到的内容。重刷会在已保留的上一代旁写入当前 writer 代次(`session.v4.jsonl`),旧代次继续作为已提交的回放基线保留。 - -## Alternatives considered - -**保留 overlay,不做任何改动。** 发布版界面会继续与描述该自动化任务入口的产品文档相矛盾,而每个消费者都要各自保留那三行的副本。overlay 也无法满足「默认 `dsh web` 进程不带 flag 就暴露该页面」这一要求。 - -**只发布 Schedule 两行,不带 `time-context`。** 模型将没有自己的采样瞬时,于是提醒请求中未明确限定时区的日期或时间要依赖另一个时钟来源;overlay 当初正是为此把两行配对。 - -**另建一个可选 bundle。** `OPTIONAL_BUNDLES` 面向的是用户在插件管理器里主动开启的 bundle,与 overlay 是同一种 opt-in 形态;本决策要的是默认 Web 界面自己拥有该页面与这些工具。 - -## Consequences - -- 每个 Web 会话的请求头多出四个工具 schema,且每个符合条件的步骤追加一条持久 user 消息。从不创建提醒的对话也要承担这份 token 成本。 -- 时钟读数对模型可见且持久,因此它与其他 user 消息一样参与回放、压缩,并出现在导出的 Session 日志中。 -- 想要恢复旧行为的部署,可在自己的 profile patch 层禁用 `time-context`、`schedule` 与 `ui-schedule` 三行;能力本身没有改动。 -- 完整预设表的 `cordis_inspect_query` `listTools` 答案现在超过基础组合 12,500 token 的内联预算,因此 spill 策略改为保留该答案的首尾并给出 spill 路径,而不是完整 JSON。 -- 仓库预览镜像与两个 Web 测试套件都不再传 overlay 参数,一处组合改动即同时作用于所有界面。 diff --git a/apps/cli/package.json b/apps/cli/package.json index 33eac62c0b..7e9fb3286b 100644 --- a/apps/cli/package.json +++ b/apps/cli/package.json @@ -38,6 +38,7 @@ "@deepseek-ai/dsh-compaction-basic": "workspace:*", "@deepseek-ai/dsh-compaction-tool-result-pruner": "workspace:*", "@deepseek-ai/dsh-cordis-client-runner": "workspace:*", + "@deepseek-ai/dsh-experimental-schedule-bundle": "workspace:*", "@deepseek-ai/dsh-experimental-agent-team-profile": "workspace:*", "@deepseek-ai/dsh-fs-local": "workspace:*", "@deepseek-ai/dsh-goal": "workspace:*", diff --git a/apps/cli/tests/profiles/web/tests/fixtures/schedule.patch.yml b/apps/cli/tests/profiles/web/tests/fixtures/schedule.patch.yml deleted file mode 100644 index fd53f05e15..0000000000 --- a/apps/cli/tests/profiles/web/tests/fixtures/schedule.patch.yml +++ /dev/null @@ -1,2 +0,0 @@ -- id: schedule - disabled: false diff --git a/apps/cli/tests/profiles/web/tests/schedule-timing.expected.e2e.ts b/apps/cli/tests/profiles/web/tests/schedule-timing.expected.e2e.ts index 0cf380636f..a6846024da 100644 --- a/apps/cli/tests/profiles/web/tests/schedule-timing.expected.e2e.ts +++ b/apps/cli/tests/profiles/web/tests/schedule-timing.expected.e2e.ts @@ -8,7 +8,8 @@ import type { DailyScheduleRecord, ScheduleCatalogEntry } from '@deepseek-ai/dsh import { expect, it } from 'vitest' import { withDefaultWeb, webGet, webRequest } from './default-web-process.ts' -const patches = [fileURLToPath(new URL('./fixtures/schedule.patch.yml', import.meta.url))] +/** The optional Schedule bundle is the switch this built-Web scenario turns on. */ +const patches = [fileURLToPath(new URL('../../../../../../packages/experimental/schedule-bundle/cordis.patch.yml', import.meta.url))] const id = 'retained-remote-task' as DailyScheduleRecord['id'] const sessionId = 'unloaded-owner' as ScheduleCatalogEntry['sessionId'] diff --git a/apps/web/tests/fixtures/time-context-every-step.patch.yml b/apps/web/tests/fixtures/time-context-every-step.patch.yml index dcff9f2b61..7a1937d44d 100644 --- a/apps/web/tests/fixtures/time-context-every-step.patch.yml +++ b/apps/web/tests/fixtures/time-context-every-step.patch.yml @@ -1,9 +1,6 @@ # Browser-zone assertions need a fresh reading after the non-browser preparation turn. +# The Schedule rows stay disabled in the shipped composition; the scenario enables them +# with the shipped `@deepseek-ai/dsh-experimental-schedule-bundle` patch. - id: time-context - disabled: false config: refreshIntervalMs: 0 -- id: schedule - disabled: false -- id: ui-schedule - disabled: false diff --git a/apps/web/tests/schedule-after.e2e.ts b/apps/web/tests/schedule-after.e2e.ts index 84cd580b8b..c0f131f3d3 100644 --- a/apps/web/tests/schedule-after.e2e.ts +++ b/apps/web/tests/schedule-after.e2e.ts @@ -44,6 +44,9 @@ declare module '@deepseek-ai/dsh-llm' { } const MODE = webSnapshotMode() +/** The optional Schedule bundle is the switch these scenarios turn on. */ +const SCHEDULE_BUNDLE = fileURLToPath(new URL('../../../packages/experimental/schedule-bundle/cordis.patch.yml', import.meta.url)) +const TIME_CONTEXT_EVERY_STEP = fileURLToPath(new URL('./fixtures/time-context-every-step.patch.yml', import.meta.url)) const SNAPSHOT_DIR = fileURLToPath(new URL('./expected/schedule-after', import.meta.url)) const AFTER_EXPECTED = join(SNAPSHOT_DIR, 'conversation.expected.md') const AT_EXPECTED = join(SNAPSHOT_DIR, 'at-conversation.expected.md') @@ -272,7 +275,7 @@ describe.skipIf(MODE === 'record')('web e2e: conversational reminders', () => { beforeAll(async () => { scaffold = await launchWebScaffold({ - extraOverlayPath: fileURLToPath(new URL('./fixtures/time-context-every-step.patch.yml', import.meta.url)), + extraOverlayPath: [SCHEDULE_BUNDLE, TIME_CONTEXT_EVERY_STEP], }) scaffold.ctx.effect( () => scaffold.ctx.llm.registerAdapter([AFTER_PROVIDER], afterAdapter), @@ -710,7 +713,7 @@ describe.skipIf(MODE === 'record')('web e2e: active Schedule catalog', () => { beforeAll(async () => { const fixture = await readFile(CATALOG_FIXTURE, 'utf8') scaffold = await launchWebScaffold({ - extraOverlayPath: fileURLToPath(new URL('./fixtures/time-context-every-step.patch.yml', import.meta.url)), + extraOverlayPath: [SCHEDULE_BUNDLE, TIME_CONTEXT_EVERY_STEP], }) await seedSession(scaffold, fixture, CATALOG_SESSION_ID, 'standard') const records = foldScheduleEvents(fixture.trim().split('\n').slice(1).map(line => JSON.parse(line) as SessionEvent)).active diff --git a/docs/config-catalog.md b/docs/config-catalog.md index 7978a4afaf..da7af50cea 100644 --- a/docs/config-catalog.md +++ b/docs/config-catalog.md @@ -4424,6 +4424,7 @@ Imported as libraries by other packages; a `cordis.yml` cannot load them. | `@deepseek-ai/dsh-deque` | — | [`packages/util/deque/src/index.ts`](../packages/util/deque/src/index.ts) | | `@deepseek-ai/dsh-experimental-agent-team-profile` | — | [`packages/experimental/agent-team-profile/src/index.ts`](../packages/experimental/agent-team-profile/src/index.ts) | | `@deepseek-ai/dsh-experimental-browser-use-runtime` | — | [`packages/experimental/browser-use-runtime/src/index.ts`](../packages/experimental/browser-use-runtime/src/index.ts) | +| `@deepseek-ai/dsh-experimental-schedule-bundle` | — | [`packages/experimental/schedule-bundle/src/index.ts`](../packages/experimental/schedule-bundle/src/index.ts) | | `@deepseek-ai/dsh-experimental-voice-input-bundle` | — | [`packages/experimental/voice-input-bundle/src/index.ts`](../packages/experimental/voice-input-bundle/src/index.ts) | | `@deepseek-ai/dsh-experimental-webworker-packer` | — | [`packages/experimental/webworker-packer/src/index.ts`](../packages/experimental/webworker-packer/src/index.ts) | | `@deepseek-ai/dsh-experimental-webworker-runtime` | — | [`packages/experimental/webworker-runtime/src/index.ts`](../packages/experimental/webworker-runtime/src/index.ts) | diff --git a/docs/config-catalog.zh.md b/docs/config-catalog.zh.md index 12383e538d..41b92912b4 100644 --- a/docs/config-catalog.zh.md +++ b/docs/config-catalog.zh.md @@ -4426,6 +4426,7 @@ export interface Config { | `@deepseek-ai/dsh-deque` | — | [`packages/util/deque/src/index.ts`](../packages/util/deque/src/index.ts) | | `@deepseek-ai/dsh-experimental-agent-team-profile` | — | [`packages/experimental/agent-team-profile/src/index.ts`](../packages/experimental/agent-team-profile/src/index.ts) | | `@deepseek-ai/dsh-experimental-browser-use-runtime` | — | [`packages/experimental/browser-use-runtime/src/index.ts`](../packages/experimental/browser-use-runtime/src/index.ts) | +| `@deepseek-ai/dsh-experimental-schedule-bundle` | — | [`packages/experimental/schedule-bundle/src/index.ts`](../packages/experimental/schedule-bundle/src/index.ts) | | `@deepseek-ai/dsh-experimental-voice-input-bundle` | — | [`packages/experimental/voice-input-bundle/src/index.ts`](../packages/experimental/voice-input-bundle/src/index.ts) | | `@deepseek-ai/dsh-experimental-webworker-packer` | — | [`packages/experimental/webworker-packer/src/index.ts`](../packages/experimental/webworker-packer/src/index.ts) | | `@deepseek-ai/dsh-experimental-webworker-runtime` | — | [`packages/experimental/webworker-runtime/src/index.ts`](../packages/experimental/webworker-runtime/src/index.ts) | diff --git a/docs/module-graph.md b/docs/module-graph.md index b005413ba3..95370f261d 100644 --- a/docs/module-graph.md +++ b/docs/module-graph.md @@ -258,6 +258,7 @@ flowchart TD pkg_experimental_computer_use_cua_driver_native["experimental-computer-use-cua-driver-native"] pkg_experimental_inspector["experimental-inspector"] pkg_experimental_ptc_runtime_python["experimental-ptc-runtime-python"] + pkg_experimental_schedule_bundle["experimental-schedule-bundle"] pkg_experimental_speech_to_text["experimental-speech-to-text"] pkg_experimental_speech_to_text_sensevoice["experimental-speech-to-text-sensevoice"] pkg_experimental_tool_agent_team["experimental-tool-agent-team"] @@ -1452,6 +1453,7 @@ flowchart TD | [`client-web`](../packages/client/web) | `client` | — | | [`office-to-pdf`](../packages/document/office-to-pdf) | `document` | — | | [`experimental-agent-team-profile`](../packages/experimental/agent-team-profile) | `experimental` | — | +| [`experimental-schedule-bundle`](../packages/experimental/schedule-bundle) | `experimental` | — | | [`experimental-voice-input-bundle`](../packages/experimental/voice-input-bundle) | `experimental` | — | | [`experimental-webworker-packer`](../packages/experimental/webworker-packer) | `experimental` | — | | [`client-ui-cordis`](../packages/extensions/ui-cordis) | `extensions` | — | diff --git a/docs/module-graph.zh.md b/docs/module-graph.zh.md index fe41849447..fa7306530d 100644 --- a/docs/module-graph.zh.md +++ b/docs/module-graph.zh.md @@ -260,6 +260,7 @@ flowchart TD pkg_experimental_computer_use_cua_driver_native["experimental-computer-use-cua-driver-native"] pkg_experimental_inspector["experimental-inspector"] pkg_experimental_ptc_runtime_python["experimental-ptc-runtime-python"] + pkg_experimental_schedule_bundle["experimental-schedule-bundle"] pkg_experimental_speech_to_text["experimental-speech-to-text"] pkg_experimental_speech_to_text_sensevoice["experimental-speech-to-text-sensevoice"] pkg_experimental_tool_agent_team["experimental-tool-agent-team"] @@ -1454,6 +1455,7 @@ flowchart TD | [`client-web`](../packages/client/web) | `client` | — | | [`office-to-pdf`](../packages/document/office-to-pdf) | `document` | — | | [`experimental-agent-team-profile`](../packages/experimental/agent-team-profile) | `experimental` | — | +| [`experimental-schedule-bundle`](../packages/experimental/schedule-bundle) | `experimental` | — | | [`experimental-voice-input-bundle`](../packages/experimental/voice-input-bundle) | `experimental` | — | | [`experimental-webworker-packer`](../packages/experimental/webworker-packer) | `experimental` | — | | [`client-ui-cordis`](../packages/extensions/ui-cordis) | `extensions` | — | diff --git a/docs/subsystems/schedule.i18n.yaml b/docs/subsystems/schedule.i18n.yaml index d6d12d5a95..13c6d192fe 100644 --- a/docs/subsystems/schedule.i18n.yaml +++ b/docs/subsystems/schedule.i18n.yaml @@ -9,8 +9,8 @@ en: 41cd197b5c74bfa3 zh: 18ed11259036d726 /host-wide-schedule/absolute-time-input: - en: e730fda52ba2854f - zh: 01a6c682e327a133 + en: 0876a14a60ba2160 + zh: e7d4bd9099c14fb2 /host-wide-schedule/daily-wall-clock-input: en: 2d249edc3dfccb8a zh: 33fecda132b03b84 @@ -27,8 +27,8 @@ en: 0656173de50ee132 zh: 54176540371d0f28 /host-wide-schedule/web-catalog: - en: 39f24636dd788034 - zh: ba3ff541fee5854a + en: 60c88b08abde9bb0 + zh: 0a3644cfa86d014d /host-wide-schedule/timing-edits: en: ce5d2095a3ad2e82 zh: 167b3715f8eaffc1 diff --git a/docs/subsystems/schedule.md b/docs/subsystems/schedule.md index 0784c0b92a..571084d0ae 100644 --- a/docs/subsystems/schedule.md +++ b/docs/subsystems/schedule.md @@ -116,7 +116,7 @@ interface LocalAtInput { type AtInput = string | LocalAtInput ``` -The shipped Web bundle mounts time-context, which samples the browser's IANA zone for every prompt. Time-context tells the model to interpret otherwise-unqualified natural-language dates and times in that request-local zone when the open turn has one unambiguous browser zone; mixed or missing browser-zone records tell the model to ask. That guidance is not a durable Session default: the model must still pass an offset in the string form or `time_zone` in the local form, and Schedule never reads browser, Session, process, or model context. +The shipped Web composition carries the `time-context` row disabled; the optional experimental bundle `@deepseek-ai/dsh-experimental-schedule-bundle`, enabled from the Plugins page, mounts time-context, which samples the browser's IANA zone for every prompt. Time-context tells the model to interpret otherwise-unqualified natural-language dates and times in that request-local zone when the open turn has one unambiguous browser zone; mixed or missing browser-zone records tell the model to ask. That guidance is not a durable Session default: the model must still pass an offset in the string form or `time_zone` in the local form, and Schedule never reads browser, Session, process, or model context. Schedule rejects invalid offsets and zones, offset-free strings, non-future targets, and local times inside daylight-saving gaps. A daylight-saving overlap chooses its first, earlier instant. Successful creation stores only canonical UTC `scheduledAt`, so replay never depends on ambient time-zone state. @@ -339,7 +339,7 @@ type ScheduleCatalogEntry = ScheduleRecord & { The Remote `schedule.list({ sessionId })`, model `schedule_list`, and Session-header catalog return only active tasks. A model view's derived timing `state` remains distinct from stored lifecycle `status`. Deletion uses `schedule.delete({ sessionId, id })` with the entry's original binding; a mismatched binding returns not found. Model tools supply the current Agent's Session, whereas the global user interface supplies the selected task's binding. The binding check alone does not establish caller authorization. The payload-free `schedule/changed` event invalidates client lists; reconnecting clients fetch current state again. -The Web bundle mounts `ui-schedule` with the Host capability. The [client package](../../packages/client/ui-schedule/README.md) owns the catalog, empty state, and deletion controls. The page separately filters all, active, and inactive tasks, retains inactive details and an original-Session control in the detail tab strip, and requires explicit confirmed deletion. Rules and Delivery records separate task settings from lazily paged saved receipts. Neither a receipt nor inactive status confirms model execution. +The shipped Web composition carries the `ui-schedule` row disabled; the optional experimental bundle `@deepseek-ai/dsh-experimental-schedule-bundle`, enabled from the Plugins page, mounts `ui-schedule` with the Host capability. The [client package](../../packages/client/ui-schedule/README.md) owns the catalog, empty state, and deletion controls. The page separately filters all, active, and inactive tasks, retains inactive details and an original-Session control in the detail tab strip, and requires explicit confirmed deletion. Rules and Delivery records separate task settings from lazily paged saved receipts. Neither a receipt nor inactive status confirms model execution. ## Timing edits diff --git a/docs/subsystems/schedule.zh.md b/docs/subsystems/schedule.zh.md index d1a726fa97..bd210a11a2 100644 --- a/docs/subsystems/schedule.zh.md +++ b/docs/subsystems/schedule.zh.md @@ -116,7 +116,7 @@ interface LocalAtInput { type AtInput = string | LocalAtInput ``` -发布的 Web bundle 会挂载 time-context,它为每条提示词采样浏览器的 IANA 时区。当 open turn 只有一个无歧义的浏览器时区时,Time-context 会告诉模型按该请求本地时区解释未明确限定时区的自然语言日期和时间;浏览器时区记录混合或缺失时,则告诉模型询问用户。该指引不是持久 Session 默认值:模型仍必须在字符串形式中传入偏移量,或在本地形式中传入 `time_zone`;Schedule 绝不会读取浏览器、Session、进程或模型上下文。 +随发行版交付的 Web 组合把 `time-context` 行保持禁用;在插件管理页启用可选实验性 bundle `@deepseek-ai/dsh-experimental-schedule-bundle` 会挂载 time-context,它为每条提示词采样浏览器的 IANA 时区。当 open turn 只有一个无歧义的浏览器时区时,Time-context 会告诉模型按该请求本地时区解释未明确限定时区的自然语言日期和时间;浏览器时区记录混合或缺失时,则告诉模型询问用户。该指引不是持久 Session 默认值:模型仍必须在字符串形式中传入偏移量,或在本地形式中传入 `time_zone`;Schedule 绝不会读取浏览器、Session、进程或模型上下文。 Schedule 会拒绝无效偏移量与时区、不带偏移量的字符串、非未来目标,以及落在夏令时缺口内的本地时间。遇到夏令时重叠时,会选择第一次出现的较早时点。创建成功后只存储规范化后的 UTC `scheduledAt`,因此回放绝不依赖环境时区状态。 @@ -339,7 +339,7 @@ type ScheduleCatalogEntry = ScheduleRecord & { Remote 方法 `schedule.list({ sessionId })`、模型 `schedule_list` 和 Session 页头目录仅返回活动任务。模型视图派生的时间 `state` 与存储的生命周期 `status` 仍是不同概念。删除通过 `schedule.delete({ sessionId, id })` 使用条目的原始绑定;绑定不匹配时返回未找到。模型工具传入当前 Agent 的 Session,全局用户界面则传入所选任务的绑定。仅校验绑定并不构成调用者鉴权。无 payload 的 `schedule/changed` 事件通知客户端刷新列表;重新连接后,客户端再次获取当前状态。 -Web bundle 将 `ui-schedule` 与宿主能力一起挂载。[客户端包](../../packages/client/ui-schedule/README.zh.md) 负责目录、空状态与删除控件。页面单独筛选全部、活动和未运行任务,保留未运行任务详情及详情页签条内的原 Session 入口,并要求显式确认删除。“规则”和“发送记录”将任务设置与按需分页加载的已保存回执分开。回执与未运行状态均不确认模型执行。 +随发行版交付的 Web 组合把 `ui-schedule` 行保持禁用;在插件管理页启用可选实验性 bundle `@deepseek-ai/dsh-experimental-schedule-bundle` 会将它与宿主能力一起挂载。[客户端包](../../packages/client/ui-schedule/README.zh.md) 负责目录、空状态与删除控件。页面单独筛选全部、活动和未运行任务,保留未运行任务详情及详情页签条内的原 Session 入口,并要求显式确认删除。“规则”和“发送记录”将任务设置与按需分页加载的已保存回执分开。回执与未运行状态均不确认模型执行。 ## 修改时间 diff --git a/docs/user/guide/schedule.i18n.yaml b/docs/user/guide/schedule.i18n.yaml index a6033b0b82..1bf88dec7c 100644 --- a/docs/user/guide/schedule.i18n.yaml +++ b/docs/user/guide/schedule.i18n.yaml @@ -12,8 +12,8 @@ en: b3b2a6e0ce02bdee zh: 2ddb168de79fd19c /schedule-reminders/create-reminders: - en: 70ae56895847c453 - zh: 19b38057c7462123 + en: c76ee99f59529942 + zh: be1d75c226231dd7 /schedule-reminders/inspect-and-delete-tasks: en: a44fc1aabc2ab957 zh: 31f444d4c7fd5c7a diff --git a/docs/user/guide/schedule.md b/docs/user/guide/schedule.md index b0058b0cba..abb86b7f8e 100644 --- a/docs/user/guide/schedule.md +++ b/docs/user/guide/schedule.md @@ -17,7 +17,7 @@ Create reminders in a conversation, then inspect active and inactive tasks and e ## Create reminders -The shipped Web profile mounts Schedule with the clock context that gives the model the current time and the browser's zone. Configure a model provider before asking it to create reminders. +The shipped Web profile carries the `time-context`, `schedule`, and `ui-schedule` rows disabled. Open Plugins and enable `Scheduling and time context` in the Official group; the optional experimental bundle `@deepseek-ai/dsh-experimental-schedule-bundle` then mounts Schedule with the clock context that gives the model the current time and the browser's zone. Configure a model provider before asking it to create reminders. Ask the model to create, list, edit, or delete reminders. It uses `schedule_create`, `schedule_list`, `schedule_update`, and `schedule_delete` (update changes one reminder in place and keeps its id and saved delivery records); the Automation tasks page's New action opens a New Session for a creation instead, with the request already written in its composer. Supported choices are a one-time delay in positive whole seconds, an absolute date and time, a fixed interval of at least one minute, a daily local time with an IANA time zone, a weekly local time with an IANA time zone and ISO weekdays from Monday 1 through Sunday 7, or a five-field cron expression with an explicit IANA time zone, stored in canonical form. diff --git a/docs/user/guide/schedule.zh.md b/docs/user/guide/schedule.zh.md index 60829d82ae..bd10a06fe5 100644 --- a/docs/user/guide/schedule.zh.md +++ b/docs/user/guide/schedule.zh.md @@ -17,7 +17,7 @@ ## 创建提醒 -发布的 Web profile 会挂载 Schedule 及其时钟上下文,后者把当前时间和浏览器时区交给模型。在请求模型创建提醒前,先配置模型 provider。 +发布的 Web profile 把 `time-context`、`schedule` 与 `ui-schedule` 三行保持禁用。打开插件管理页,在 Official 分组中启用“定时与时间上下文”;可选实验性 bundle `@deepseek-ai/dsh-experimental-schedule-bundle` 随即挂载 Schedule 及其时钟上下文,后者把当前时间和浏览器时区交给模型。在请求模型创建提醒前,先配置模型 provider。 向模型提出创建、列出、修改或删除提醒的请求。模型使用 `schedule_create`、`schedule_list`、`schedule_update` 和 `schedule_delete`(更新原地修改一条提醒,保留其 id 与已保存的投递记录);「自动化任务」页面的「新建」操作则为创建打开一个新会话,其 composer 已写好该请求。支持正整数秒的一次性延迟、绝对日期时间、至少一分钟的固定间隔、带 IANA 时区的每日本地时间、带 IANA 时区和 ISO 星期(周一 1 至周日 7)的每周本地时间,以及带显式 IANA 时区的五字段 cron 表达式(表达式以规范化形式保存)。 diff --git a/packages/boot/app-boot/src/profile.ts b/packages/boot/app-boot/src/profile.ts index da580c762e..e17e125a75 100644 --- a/packages/boot/app-boot/src/profile.ts +++ b/packages/boot/app-boot/src/profile.ts @@ -214,6 +214,7 @@ export const OPTIONAL_BUNDLES: readonly string[] = [ '@deepseek-ai/dsh-experimental-agent-team-profile', '@deepseek-ai/dsh-experimental-voice-input-bundle', '@deepseek-ai/dsh-experimental-auto-review', + '@deepseek-ai/dsh-experimental-schedule-bundle', ] const PROFILE_PATCH_TEMPLATE = `# Your patch layer for this dsh profile, applied after every bundle layer: diff --git a/packages/bundle/web-app/README.i18n.yaml b/packages/bundle/web-app/README.i18n.yaml index c958afc209..eddc2d76d7 100644 --- a/packages/bundle/web-app/README.i18n.yaml +++ b/packages/bundle/web-app/README.i18n.yaml @@ -21,8 +21,8 @@ en: b7ab01cfe9fed40f zh: 23703ab7727c3ab5 /deepseek-ai-dsh-web-app/use-this-package/configuration: - en: 4f18797d9de48038 - zh: 62387505417e4813 + en: cea7ecccb2a03b79 + zh: 0af72c22e46045d3 /deepseek-ai-dsh-web-app/use-this-package/lan-access-and-trusted-hosts: en: 2522c806db384ddc zh: 7e96f11194af9f9f diff --git a/packages/bundle/web-app/README.md b/packages/bundle/web-app/README.md index a798b7f506..4f5b8f6e7c 100644 --- a/packages/bundle/web-app/README.md +++ b/packages/bundle/web-app/README.md @@ -51,7 +51,7 @@ Most users never set these; the command-line flags feed the four settings below | `surfaceContext` | `true` | Give the agent GUI-orientation context and expose `DSH_WEB_URL` to its shell commands | | `trustedHosts` | `[]` | Extra hosts allowed to reach the GUI from the network | -The generated [configuration catalog](../../../docs/config-catalog.md#deepseek-aidsh-web-app) is the exhaustive source for every accepted field and its JSDoc. The shipped composition disables `schedule`, `ui-schedule`, and `time-context` by default. +The generated [configuration catalog](../../../docs/config-catalog.md#deepseek-aidsh-web-app) is the exhaustive source for every accepted field and its JSDoc. The shipped composition disables `schedule`, `ui-schedule`, and `time-context` by default, and the optional experimental bundle `@deepseek-ai/dsh-experimental-schedule-bundle` switches those three rows on from the Plugins page. ### LAN access and trusted hosts diff --git a/packages/bundle/web-app/README.zh.md b/packages/bundle/web-app/README.zh.md index 9ea8e7e868..97010b39e5 100644 --- a/packages/bundle/web-app/README.zh.md +++ b/packages/bundle/web-app/README.zh.md @@ -51,7 +51,7 @@ dsh --profile web --no-open --port 8080 | `surfaceContext` | `true` | 给 agent 提供 GUI 定位上下文,并把 `DSH_WEB_URL` 暴露给其 shell 命令 | | `trustedHosts` | `[]` | 允许从网络访问 GUI 的额外主机 | -生成的[配置目录](../../../docs/config-catalog.zh.md#deepseek-aidsh-web-app)是每个受支持字段及其 JSDoc 的穷尽式真源。 随发行版交付的组合默认禁用 `schedule`、`ui-schedule` 和 `time-context`。 +生成的[配置目录](../../../docs/config-catalog.zh.md#deepseek-aidsh-web-app)是每个受支持字段及其 JSDoc 的穷尽式真源。 随发行版交付的组合默认禁用 `schedule`、`ui-schedule` 和 `time-context`,可选实验性 bundle `@deepseek-ai/dsh-experimental-schedule-bundle` 可在插件管理页把这三行打开。 ### LAN 访问与可信主机 diff --git a/packages/client/ui-schedule/README.i18n.yaml b/packages/client/ui-schedule/README.i18n.yaml index 9797b69beb..ec785c3dda 100644 --- a/packages/client/ui-schedule/README.i18n.yaml +++ b/packages/client/ui-schedule/README.i18n.yaml @@ -15,8 +15,8 @@ en: d152484eb41ac6b4 zh: 405b30feaf48c087 /deepseek-ai-dsh-client-ui-schedule/use-this-package: - en: 3594ab6704cbd7b9 - zh: 99a965f43187501b + en: bf8096e6e576ac07 + zh: 1936c0a75dc5cd4b /deepseek-ai-dsh-client-ui-schedule/use-this-package/time-zone-data-source: en: 6bd6882dbbbefcb0 zh: 03aa15f1a65d13dc diff --git a/packages/client/ui-schedule/README.md b/packages/client/ui-schedule/README.md index 577e9e4ccc..54b0b172b5 100644 --- a/packages/client/ui-schedule/README.md +++ b/packages/client/ui-schedule/README.md @@ -25,7 +25,7 @@ Manage active and inactive tasks from the Automation tasks page and the right Si ## Use this package -The shipped Web bundle mounts `ui-schedule` with the Host Schedule service and the clock context that supplies the model's current time. The Automation tasks sidebar entry opens a global page without selecting or activating a Session. The page header's New action starts a new Session, where the reminder is created by asking the model; the page itself has no creation form. Its task list supports text search and one All, Enabled, and Inactive status filter row; search matches the stored task name, the instruction, and the internal Session id, not a resolved Session title, and the empty state keeps the heading's New action beside the notice. Selecting an active or inactive task opens a second detail level with Rules and Delivery records tabs. Every list row shows the task's stored title with its status, frequency, and next run and never the original Session name; the detail's name control shows the stored title. Rules contains the complete reminder, status, next target for active tasks, original recurrence rule, and task id. Daily rule labels show the saved local time and exact stored IANA zone, preserving nonzero seconds and milliseconds rather than substituting the browser's zone. The Linked session entry in the detail tab strip names the linked Session by its catalog title, falling back to the Session id when no title is available. It opens an available, unarchived Session after metadata loads; pending Session or Workspace metadata, an archived Session, missing Session membership, or a Workspace query error keeps it disabled with an explanation. The click rechecks availability; browsing does not unarchive the Session. Only this action requests Session activation. Deletion is available from the More task actions menu in the detail's top strip, separate from navigation. +The shipped Web composition carries the `ui-schedule` row disabled; enable the optional experimental bundle `@deepseek-ai/dsh-experimental-schedule-bundle` from the Plugins page (Official group), or list it in a profile's `dsh.profile.bundles`, to mount `ui-schedule` with the Host Schedule service and the clock context that supplies the model's current time. The Automation tasks sidebar entry opens a global page without selecting or activating a Session. The page header's New action starts a new Session, where the reminder is created by asking the model; the page itself has no creation form. Its task list supports text search and one All, Enabled, and Inactive status filter row; search matches the stored task name, the instruction, and the internal Session id, not a resolved Session title, and the empty state keeps the heading's New action beside the notice. Selecting an active or inactive task opens a second detail level with Rules and Delivery records tabs. Every list row shows the task's stored title with its status, frequency, and next run and never the original Session name; the detail's name control shows the stored title. Rules contains the complete reminder, status, next target for active tasks, original recurrence rule, and task id. Daily rule labels show the saved local time and exact stored IANA zone, preserving nonzero seconds and milliseconds rather than substituting the browser's zone. The Linked session entry in the detail tab strip names the linked Session by its catalog title, falling back to the Session id when no title is available. It opens an available, unarchived Session after metadata loads; pending Session or Workspace metadata, an archived Session, missing Session membership, or a Workspace query error keeps it disabled with an explanation. The click rechecks availability; browsing does not unarchive the Session. Only this action requests Session activation. Deletion is available from the More task actions menu in the detail's top strip, separate from navigation. Selecting a task from the list opens Rules; refreshing that task preserves the selected tab. Rules edits an active task's name, instruction, and run time; the edits stay in a local draft until saved, and inactive tasks remain read-only. Unmodified Left/Right arrows cycle the tabs, Home/End select the first/last tab, and keyboard focus follows the selection. The tabs do not consume these keys with Alt, Ctrl, Meta, or Shift. The linked-Session control in the detail tab strip stays available on the Rules tab, and confirmed deletion is available from either view. diff --git a/packages/client/ui-schedule/README.zh.md b/packages/client/ui-schedule/README.zh.md index 743d8a5525..4a4fab6b96 100644 --- a/packages/client/ui-schedule/README.zh.md +++ b/packages/client/ui-schedule/README.zh.md @@ -25,7 +25,7 @@ kind: "package-reference" ## 使用本包 -发布的 Web bundle 将 `ui-schedule` 与 Host Schedule 服务、以及为模型提供当前时间的时钟上下文一起挂载。侧栏的自动化任务入口打开全局页面,不选择或激活会话。页面页头的“新建”操作会打开一个新会话,提醒由模型在该会话中创建;页面本身没有创建表单。列表支持文本搜索和一行“全部/已开启/未运行”状态筛选;搜索匹配任务已存储的名称、指令和内部会话 id,不匹配解析出的会话标题,空状态在提示旁保留页头的“新建”操作。选择活动或未运行任务后,进入含“规则”和“任务运行记录”页签的第二层详情。每条列表行显示任务已存储的标题及其状态、频率和下次运行,不显示原会话名称;详情中的名称输入框显示任务已存储的标题。“规则”显示完整提醒、状态、活动任务的下一目标时间、原始重复规则和任务 id。每天的规则标签显示已保存的本地时间与精确的存储 IANA 时区,保留非零秒与毫秒,而不替换为浏览器时区。详情页签条内的“关联会话”入口按会话标题显示,取不到标题时回退显示会话 id。元数据加载后,它可打开可用且未归档的会话;会话或 Workspace 元数据尚未就绪、会话已归档、会话不在列表中或 Workspace 查询失败时,入口保持禁用并显示原因。点击时会重新检查可用性;浏览不会取消会话归档。仅此操作请求激活会话。删除位于详情顶部条带的“更多任务操作”菜单。 +随发行版交付的 Web 组合把 `ui-schedule` 行保持禁用;在插件管理页(Official 分组)启用可选实验性 bundle `@deepseek-ai/dsh-experimental-schedule-bundle`,或把它列进 profile 的 `dsh.profile.bundles`,即可将 `ui-schedule` 与 Host Schedule 服务、以及为模型提供当前时间的时钟上下文一起挂载。侧栏的自动化任务入口打开全局页面,不选择或激活会话。页面页头的“新建”操作会打开一个新会话,提醒由模型在该会话中创建;页面本身没有创建表单。列表支持文本搜索和一行“全部/已开启/未运行”状态筛选;搜索匹配任务已存储的名称、指令和内部会话 id,不匹配解析出的会话标题,空状态在提示旁保留页头的“新建”操作。选择活动或未运行任务后,进入含“规则”和“任务运行记录”页签的第二层详情。每条列表行显示任务已存储的标题及其状态、频率和下次运行,不显示原会话名称;详情中的名称输入框显示任务已存储的标题。“规则”显示完整提醒、状态、活动任务的下一目标时间、原始重复规则和任务 id。每天的规则标签显示已保存的本地时间与精确的存储 IANA 时区,保留非零秒与毫秒,而不替换为浏览器时区。详情页签条内的“关联会话”入口按会话标题显示,取不到标题时回退显示会话 id。元数据加载后,它可打开可用且未归档的会话;会话或 Workspace 元数据尚未就绪、会话已归档、会话不在列表中或 Workspace 查询失败时,入口保持禁用并显示原因。点击时会重新检查可用性;浏览不会取消会话归档。仅此操作请求激活会话。删除位于详情顶部条带的“更多任务操作”菜单。 从列表选择任务时默认打开“规则”;刷新同一任务会保留当前页签。活动任务的“规则”修改名称、指令和运行时间;这些修改保留在本地草稿中直到保存,未运行任务保持只读。不带修饰键的左右方向键循环切换页签,Home/End 选择第一个/最后一个页签,键盘焦点随选择移动。页签不会拦截这些键与 Alt、Ctrl、Meta 或 Shift 的组合。共用的会话入口位于详情页签条内,在“规则”页签可见;确认删除操作在两种页签下都可用。 diff --git a/packages/context/README.i18n.yaml b/packages/context/README.i18n.yaml index cbf433cd29..0aa51cfac3 100644 --- a/packages/context/README.i18n.yaml +++ b/packages/context/README.i18n.yaml @@ -9,8 +9,8 @@ en: 05a169f23a64b7e4 zh: cf57e471b7f13509 /context-request-context-plugins/summary: - en: 4a48e859cbeca00f - zh: 312b8621ba74a3ec + en: c301d0f01494ac06 + zh: 00e51efcde0d1267 /context-request-context-plugins/table-of-contents: en: 1eb35b015a6c423f zh: a8a3dceee2c9e943 diff --git a/packages/context/README.md b/packages/context/README.md index 6e6d38a5f8..3ddd0c5105 100644 --- a/packages/context/README.md +++ b/packages/context/README.md @@ -9,7 +9,7 @@ English | [中文](README.zh.md) ## Summary -The context group provides plugins that add model-visible context to each request without defining any tool: workspace instruction files become guidance, `@file` mentions offer path completion, other sessions can be referenced as bounded snapshots, and the model can see the current time and the agent's tmux location. Only `agent-instructions` (`dsh-base`) and `time-context` (`dsh-web-app`) ship by default; the rest are opt-in. Context is durable: injected instructions and references enter session history as user-role messages, so they persist, replay, and compact like other conversation content. This page maps the group; each package README owns the per-package contract. +The context group provides plugins that add model-visible context to each request without defining any tool: workspace instruction files become guidance, `@file` mentions offer path completion, other sessions can be referenced as bounded snapshots, and the model can see the current time and the agent's tmux location. Only `agent-instructions` (`dsh-base`) ships mounted by default; the rest are opt-in. Context is durable: injected instructions and references enter session history as user-role messages, so they persist, replay, and compact like other conversation content. This page maps the group; each package README owns the per-package contract. ## Table of Contents diff --git a/packages/context/README.zh.md b/packages/context/README.zh.md index 2392f1c644..98b4133036 100644 --- a/packages/context/README.zh.md +++ b/packages/context/README.zh.md @@ -9,7 +9,7 @@ kind: "package-group" ## 概述 -context 组提供不定义任何工具、为每次请求添加模型可见上下文的插件:工作区指令文件成为指引,`@file` 提及提供路径补全,其他会话可以作为有界快照被引用,模型还能看到当前时间与 agent(智能体)的 tmux 位置。默认只包含 `agent-instructions`(`dsh-base`)与 `time-context`(`dsh-web-app`);其余全部需主动启用。上下文是持久的:注入的指令与引用以用户角色消息的形式进入会话历史,因此与其他对话内容一样持久保留、可回放、可压缩。本页概述本组;包级约定由各包 README 负责。 +context 组提供不定义任何工具、为每次请求添加模型可见上下文的插件:工作区指令文件成为指引,`@file` 提及提供路径补全,其他会话可以作为有界快照被引用,模型还能看到当前时间与 agent(智能体)的 tmux 位置。默认只挂载 `agent-instructions`(`dsh-base`);其余全部需主动启用。上下文是持久的:注入的指令与引用以用户角色消息的形式进入会话历史,因此与其他对话内容一样持久保留、可回放、可压缩。本页概述本组;包级约定由各包 README 负责。 ## 目录 diff --git a/packages/context/time-context/README.i18n.yaml b/packages/context/time-context/README.i18n.yaml index 770857eb2c..526a79b8d9 100644 --- a/packages/context/time-context/README.i18n.yaml +++ b/packages/context/time-context/README.i18n.yaml @@ -9,8 +9,8 @@ en: ec051915b3d81cda zh: 3a0ef832e3a5e419 /deepseek-ai-dsh-time-context/summary: - en: e4e308b9fd3fcd56 - zh: 9fb4d40ebe621d6a + en: 8160d6d20a8bc98c + zh: b7010a1edf57079b /deepseek-ai-dsh-time-context/table-of-contents: en: d152484eb41ac6b4 zh: 09388d293f9be9cb diff --git a/packages/context/time-context/README.md b/packages/context/time-context/README.md index 7bfb2b1606..01af143af1 100644 --- a/packages/context/time-context/README.md +++ b/packages/context/time-context/README.md @@ -9,7 +9,7 @@ English | [中文](README.zh.md) ## Summary -`dsh-time-context` gives the model a clock: on eligible steps it appends a durable, source-attributed reading with the current time, the browser zone attached to the open request, and the elapsed time since the preceding model-visible message. It helps the model interpret otherwise-unqualified dates and times in the user's browser zone, and tells it to ask when current-turn browser zones are mixed or missing. The shipped Web bundle mounts it with Schedule. Readings default to a 10-minute minimum interval; `refreshIntervalMs: 0` injects at every eligible step. +`dsh-time-context` gives the model a clock: on eligible steps it appends a durable, source-attributed reading with the current time, the browser zone attached to the open request, and the elapsed time since the preceding model-visible message. It helps the model interpret otherwise-unqualified dates and times in the user's browser zone, and tells it to ask when current-turn browser zones are mixed or missing. The shipped Web composition carries its row disabled; the optional `@deepseek-ai/dsh-experimental-schedule-bundle` mounts it with Schedule from the Plugins page. Readings default to a 10-minute minimum interval; `refreshIntervalMs: 0` injects at every eligible step. ## Table of Contents diff --git a/packages/context/time-context/README.zh.md b/packages/context/time-context/README.zh.md index 84b18bc96b..95afe6acb0 100644 --- a/packages/context/time-context/README.zh.md +++ b/packages/context/time-context/README.zh.md @@ -9,7 +9,7 @@ kind: "package-reference" ## 概述 -`dsh-time-context` 给模型一只时钟:在符合条件的步骤上,它追加一条持久、带来源的读数,包含当前时间、附加到当前开放请求的浏览器时区,以及自前一条模型可见消息以来的经过时长。它帮助模型按用户的浏览器时区解释未明确限定时区的日期与时间;时区来源混杂或缺失时,它告诉模型去询问。发布的 Web bundle 会随 Schedule 一起挂载它。读数默认采用 10 分钟的最小间隔;`refreshIntervalMs: 0` 会在每个符合条件的步骤注入。 +`dsh-time-context` 给模型一只时钟:在符合条件的步骤上,它追加一条持久、带来源的读数,包含当前时间、附加到当前开放请求的浏览器时区,以及自前一条模型可见消息以来的经过时长。它帮助模型按用户的浏览器时区解释未明确限定时区的日期与时间;时区来源混杂或缺失时,它告诉模型去询问。随发行版交付的 Web 组合把该行保持禁用;可选的 `@deepseek-ai/dsh-experimental-schedule-bundle` 在插件管理页会随 Schedule 一起挂载它。读数默认采用 10 分钟的最小间隔;`refreshIntervalMs: 0` 会在每个符合条件的步骤注入。 ## 目录 diff --git a/packages/experimental/README.i18n.yaml b/packages/experimental/README.i18n.yaml index c3c5329e44..a979c5d99b 100644 --- a/packages/experimental/README.i18n.yaml +++ b/packages/experimental/README.i18n.yaml @@ -9,14 +9,14 @@ en: 18bc48bb66b3e516 zh: 51f2340a5c921f36 /packages-experimental/summary: - en: 9341a408afcd5dfa - zh: 07541055b5f41ff8 + en: 882aada84ecc5413 + zh: daedbca3726e6ac2 /packages-experimental/table-of-contents: en: 1eb35b015a6c423f zh: a8a3dceee2c9e943 /packages-experimental/packages: - en: ad10945dac9dbb51 - zh: 245b454406ce99f8 + en: 74635f0629fe1e84 + zh: 6119c5bbc6b807ac /packages-experimental/related-documentation: en: 31282a28dd828c81 zh: ebb1d3cacdc1bd6d diff --git a/packages/experimental/README.md b/packages/experimental/README.md index a49181f7de..32411baad8 100644 --- a/packages/experimental/README.md +++ b/packages/experimental/README.md @@ -9,7 +9,7 @@ English | [中文](README.zh.md) ## Summary -The experimental group contains prototype capabilities whose contracts can change and carry no support promise. All current packages publish under their `@deepseek-ai/dsh-experimental-*` names, including the opt-in Agent Teams composition, Auto review, Cua Driver providers, browser-use backends, cross-realm Inspector, CPython PTC backend, and browser-worker preview libraries. Released products outside this group must not depend on experimental packages. The dsh installation ships the Agent Teams, voice input, and Auto review packages as optional bundles switched on from the Web sidebar's Plugins page ([decision](../../.agents/notes/implemented/architecture/2026-09-21-experimental-capabilities-as-optional-bundles.md)); the other packages are libraries or explicit compositions. +The experimental group contains prototype capabilities whose contracts can change and carry no support promise. All current packages publish under their `@deepseek-ai/dsh-experimental-*` names, including the opt-in Agent Teams composition, Auto review, Cua Driver providers, browser-use backends, cross-realm Inspector, CPython PTC backend, and browser-worker preview libraries. Released products outside this group must not depend on experimental packages. The dsh installation ships the Agent Teams, voice input, Auto review, and Schedule packages as optional bundles switched on from the Web sidebar's Plugins page ([decision](../../.agents/notes/implemented/architecture/2026-09-21-experimental-capabilities-as-optional-bundles.md)); the other packages are libraries or explicit compositions. ## Table of Contents @@ -33,6 +33,7 @@ The experimental group contains prototype capabilities whose contracts can chang | [`agent-team`](agent-team/README.md) | Named teammates with durable messages and a shared task board | `ctx.agentTeams` | | [`client-ui-agent-team`](client-ui-agent-team/README.md) | Team roster, task board, and teammate navigation for Web | — | | [`auto-review`](auto-review/README.md) | Explicit Web layer for same-model review before each native or PTC inner tool call | — | +| [`schedule-bundle`](schedule-bundle/README.md) | Opt-in Schedule and time-context switch over the shipped Web composition | — | | [`ptc-runtime-python`](ptc-runtime-python/README.md) | CPython subprocess backend for the PTC execution seam | `ctx.ptcRuntime` | | [`computer-use-cua-driver-mcp`](computer-use-cua-driver-mcp/README.md) | Use an installed Cua Driver through MCP | `ctx.computerUse` | | [`computer-use-cua-driver-native`](computer-use-cua-driver-native/README.md) | Embed the Cua Driver native npm runtime | `ctx.computerUse` | diff --git a/packages/experimental/README.zh.md b/packages/experimental/README.zh.md index 68b905673f..85c609b043 100644 --- a/packages/experimental/README.zh.md +++ b/packages/experimental/README.zh.md @@ -9,7 +9,7 @@ kind: "package-group" ## 概述 -实验组包含约定可能变更且不提供支持承诺的原型能力。所有当前包都以 `@deepseek-ai/dsh-experimental-*` 名称发布,包括显式启用的 Agent Teams 组合、Auto review、Cua Driver 提供方、浏览器操作后端、跨 realm Inspector、CPython PTC 后端与浏览器 worker 预览库。组外已发布产品不得依赖实验性包。dsh 安装将 Agent Teams、语音输入与 Auto review 包作为可选 bundle 一起发布,可从 Web 侧边栏“插件”页启用([决策](../../.agents/notes/implemented/architecture/2026-09-21-experimental-capabilities-as-optional-bundles.zh.md));其余包是库或显式组合。 +实验组包含约定可能变更且不提供支持承诺的原型能力。所有当前包都以 `@deepseek-ai/dsh-experimental-*` 名称发布,包括显式启用的 Agent Teams 组合、Auto review、Cua Driver 提供方、浏览器操作后端、跨 realm Inspector、CPython PTC 后端与浏览器 worker 预览库。组外已发布产品不得依赖实验性包。dsh 安装将 Agent Teams、语音输入、Auto review 与定时包作为可选 bundle 一起发布,可从 Web 侧边栏“插件”页启用([决策](../../.agents/notes/implemented/architecture/2026-09-21-experimental-capabilities-as-optional-bundles.zh.md));其余包是库或显式组合。 ## 目录 @@ -33,6 +33,7 @@ kind: "package-group" | [`agent-team`](agent-team/README.zh.md) | 具名 teammate,成员之间持久消息与共享任务板 | `ctx.agentTeams` | | [`client-ui-agent-team`](client-ui-agent-team/README.zh.md) | Web Team roster、任务板与 teammate 导航 | — | | [`auto-review`](auto-review/README.zh.md) | 显式 Web 层,在每个原生或 PTC inner 工具调用前使用同一模型审查 | — | +| [`schedule-bundle`](schedule-bundle/README.zh.md) | 在出厂 Web 组合上按需开启定时与时间上下文的开关 | — | | [`ptc-runtime-python`](ptc-runtime-python/README.zh.md) | PTC 执行 seam 的 CPython 子进程后端 | `ctx.ptcRuntime` | | [`computer-use-cua-driver-mcp`](computer-use-cua-driver-mcp/README.zh.md) | 通过 MCP 使用已安装的 Cua Driver | `ctx.computerUse` | | [`computer-use-cua-driver-native`](computer-use-cua-driver-native/README.zh.md) | 嵌入 Cua Driver 原生 npm 运行时 | `ctx.computerUse` | diff --git a/packages/experimental/schedule-bundle/README.i18n.yaml b/packages/experimental/schedule-bundle/README.i18n.yaml new file mode 100644 index 0000000000..a07b7aa5b1 --- /dev/null +++ b/packages/experimental/schedule-bundle/README.i18n.yaml @@ -0,0 +1,46 @@ +# Bilingual-pair consistency record for README.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write packages/experimental/schedule-bundle/README.md +/: + en: 7504834d27adc717 + zh: 464587026083c661 +/deepseek-ai-dsh-experimental-schedule-bundle: + en: d7b8b6126df4e3c4 + zh: 546d528efd4edbde +/deepseek-ai-dsh-experimental-schedule-bundle/summary: + en: 832752e963df6177 + zh: 30d1d292230a17c1 +/deepseek-ai-dsh-experimental-schedule-bundle/table-of-contents: + en: d152484eb41ac6b4 + zh: 364c80ee00a374ff +/deepseek-ai-dsh-experimental-schedule-bundle/use-this-package: + en: ffaa4b18e10a1df9 + zh: b675fd8195ebb057 +/deepseek-ai-dsh-experimental-schedule-bundle/understand-the-implementation: + en: 9bb32d6e6930f0c2 + zh: d81683d7bb1f6903 +/deepseek-ai-dsh-experimental-schedule-bundle/further-exploration: + en: 99a29dddf9805540 + zh: 13a6df3ee31abfc1 +/deepseek-ai-dsh-experimental-schedule-bundle/model-experience: + en: 215e7ba838619b7b + zh: a311da3843709f90 +/deepseek-ai-dsh-experimental-schedule-bundle/model-experience/reminder-tools-and-clock-readings: + en: c7fec3a37d945018 + zh: 164346dc63d188dd +/deepseek-ai-dsh-experimental-schedule-bundle/model-experience/reminder-tools-and-clock-readings/what-the-model-sees: + en: fb1906621d02c594 + zh: 394dc933ed63b349 +/deepseek-ai-dsh-experimental-schedule-bundle/model-experience/reminder-tools-and-clock-readings/token-effect: + en: 7c44bfc062010b7b + zh: 15f431db31ad53eb +/deepseek-ai-dsh-experimental-schedule-bundle/model-experience/reminder-tools-and-clock-readings/kv-cache-effect: + en: 0b01d8c40b422f5b + zh: 57fede4db59a62b8 +/deepseek-ai-dsh-experimental-schedule-bundle/known-limitations-and-deferred-work: + en: d733f4e0f983de86 + zh: 7ffb3d3fe7f77a7b +/deepseek-ai-dsh-experimental-schedule-bundle/known-limitations-and-deferred-work/dev-note: + en: 0225ba087c5266f3 + zh: 4e706f1b2b984e63 diff --git a/packages/experimental/schedule-bundle/README.md b/packages/experimental/schedule-bundle/README.md new file mode 100644 index 0000000000..10f254bc11 --- /dev/null +++ b/packages/experimental/schedule-bundle/README.md @@ -0,0 +1,94 @@ +--- +description: "Enable the shipped Schedule services, reminder catalog, and Automation tasks page from the plugin manager." +kind: "package-bundle" +--- + +# @deepseek-ai/dsh-experimental-schedule-bundle + +English | [中文](README.zh.md) + +## Summary + +This optional bundle switches on the three Schedule rows that `@deepseek-ai/dsh-web-app` inserts with `disabled: true`: `time-context`, `schedule`, and `ui-schedule`. Its patch appends no row and declares no plugin dependency, so enabling it cannot mount a Host service twice. Shipped profiles leave it switched off. + +## Table of Contents + +- [Use this package](#use-this-package) +- [Understand the implementation](#understand-the-implementation) +- [Further Exploration](#further-exploration) +- [Model Experience](#model-experience) +- [Known Limitations and Deferred Work](#known-limitations-and-deferred-work) +- [Dev Note](#dev-note) + +----- + + +## Use this package + +Open Plugins in the Web sidebar and enable Scheduling and time context, marked by a clock icon. A live root Agent then receives `schedule_create`, `schedule_list`, `schedule_update`, and `schedule_delete`, the Session header shows its reminder catalog, the right sidebar shows the Automation tasks page, and each eligible step appends one clock reading with the current time, the browser zone attached to the open request, and the elapsed time since the preceding model-visible message. Disabling the bundle restores the shipped composition; stored tasks remain on disk. + +----- + + +## Understand the implementation + +
+Maintainer details — click to expand + +`cordis.patch.yml` carries three id-targeted patches, each setting `disabled: false` on a row the Web bundle already inserts. `OPTIONAL_BUNDLES` in `packages/boot/app-boot/src/profile.ts` names this package and `apps/cli` depends on it, so every installation ships it switched off and the plugin manager offers it in the Official group. Selecting it appends the bundle to the profile's `dsh.profile.bundles` list, and the profile launcher applies the bundle layers after the Web layer. No runtime invariant companion is published, because this configuration-only package owns no mutable runtime state. + +| File | Role | +|---|---| +| [`cordis.patch.yml`](cordis.patch.yml) | Three `disabled: false` patches over the shipped Web rows | +| [`locale/en.json`](locale/en.json), [`locale/zh.json`](locale/zh.json) | Plugin-manager title and description | +| [`icon.svg`](icon.svg) | Plugin-manager icon | +| [`src/index.ts`](src/index.ts) | Empty module entry; the patch is the runtime content | + +
+ +----- + + +## Further Exploration + +- [Schedule subsystem](../../../docs/subsystems/schedule.md) — durable tasks, occurrence resolution, and delivery. +- [Schedule service](../../schedule/schedule/README.md) — Host task storage, activation, and the record format. +- [Web bundle](../../bundle/web-app/README.md) — the composition that carries these rows. + +----- + + +## Model Experience + +### Reminder tools and clock readings + +#### What the model sees + +A live root Agent gains `schedule_create`, `schedule_list`, `schedule_update`, and `schedule_delete`. `time-context` appends one durable user message per eligible step carrying the sampled instant, the browser zone attached to the open request, and the elapsed time since the preceding model-visible message. + +#### Token effect + +Selecting the bundle adds four Schedule tool schemas to every live root Agent request and one durable clock reading per eligible step; a conversation that never creates a reminder pays both. + +#### KV Cache effect + +The tool schemas change the request prefix once when the bundle mounts; each appended reading is new visible content after that prefix, so existing entries are not invalidated. + +## Known Limitations and Deferred Work + + + +- The switch targets rows `@deepseek-ai/dsh-web-app` inserts. A profile without that bundle carries no such rows, so this bundle changes nothing there. +- Selecting the bundle adds the four Schedule tool schemas to every live root Agent and one clock reading per eligible step. A conversation that never creates a reminder still pays both costs. + +----- + + +### Dev Note + +
+Maintainer details — click to expand + +None. + +
diff --git a/packages/experimental/schedule-bundle/README.zh.md b/packages/experimental/schedule-bundle/README.zh.md new file mode 100644 index 0000000000..747137bc57 --- /dev/null +++ b/packages/experimental/schedule-bundle/README.zh.md @@ -0,0 +1,94 @@ +--- +description: "从插件管理页启用出厂的定时服务、提醒目录与自动化任务页面。" +kind: "package-bundle" +--- + +# @deepseek-ai/dsh-experimental-schedule-bundle + +[English](README.md) | 中文 + +## 概述 + +此可选 Bundle 打开 `@deepseek-ai/dsh-web-app` 以 `disabled: true` 插入的三个定时条目:`time-context`、`schedule` 与 `ui-schedule`。它的补丁不追加条目,也不声明插件依赖,因此启用它不会重复挂载同一个 Host 服务。随包配置默认禁用。 + +## 目录 + +- [使用此包](#use-this-package) +- [理解实现](#understand-the-implementation) +- [进一步探索](#further-exploration) +- [模型体验](#model-experience) +- [已知限制与后续工作](#known-limitations-and-deferred-work) +- [开发备注](#dev-note) + +----- + + +## 使用此包 + +打开 Web 侧栏的插件管理页并启用带时钟图标的“定时与时间上下文”。此后,活跃的根智能体获得 `schedule_create`、`schedule_list`、`schedule_update` 与 `schedule_delete`,会话头部显示提醒目录,右侧栏显示自动化任务页面,每个符合条件的步骤追加一条时钟读数,包含当前时间、打开请求所带的浏览器时区,以及距上一条模型可见消息的经过时间。禁用此 Bundle 会恢复随包组合;已存储的任务保留在磁盘上。 + +----- + + +## 理解实现 + +
+维护者信息 — 点击展开 + +`cordis.patch.yml` 包含三个按 id 定位的补丁,各自把 Web Bundle 已插入条目的 `disabled` 设为 `false`。`packages/boot/app-boot/src/profile.ts` 的 `OPTIONAL_BUNDLES` 列出此包,`apps/cli` 依赖它,因此每次安装都随包携带且默认禁用,插件管理页在 Official 分组中提供它。选中后会把该 Bundle 追加到 profile 的 `dsh.profile.bundles` 列表,profile 启动器在 Web 层之后应用各 Bundle 层。此纯配置包不拥有可变的运行时状态,因此不发布不变量伴随模块。 + +| 文件 | 作用 | +|---|---| +| [`cordis.patch.yml`](cordis.patch.yml) | 针对出厂 Web 条目的三个 `disabled: false` 补丁 | +| [`locale/en.json`](locale/en.json)、[`locale/zh.json`](locale/zh.json) | 插件管理页的标题与描述 | +| [`icon.svg`](icon.svg) | 插件管理页图标 | +| [`src/index.ts`](src/index.ts) | 空的模块入口;补丁即运行时内容 | + +
+ +----- + + +## 进一步探索 + +- [定时子系统](../../../docs/subsystems/schedule.zh.md) — 持久任务、发生时刻解析与投递。 +- [定时服务](../../schedule/schedule/README.zh.md) — Host 任务存储、激活与记录格式。 +- [Web Bundle](../../bundle/web-app/README.zh.md) — 携带这些条目的组合。 + +----- + + +## 模型体验 + +### 提醒工具与时钟读数 + +#### 模型看到的内容 + +活跃的根智能体获得 `schedule_create`、`schedule_list`、`schedule_update` 与 `schedule_delete`。`time-context` 在每个符合条件的步骤追加一条持久用户消息,携带采样时刻、打开请求所带的浏览器时区,以及距上一条模型可见消息的经过时间。 + +#### Token 影响 + +启用该 bundle 会给每个活跃根 Agent 请求增加四个定时工具的 schema,并为每个符合条件的步骤增加一条持久时钟读数;即使对话从不创建提醒也会承担这两项开销。 + +#### KV 缓存影响 + +四个工具的 schema 在 bundle 挂载时改变一次请求前缀;每条追加的读数都是该前缀之后的新可见内容,因此不会使已有条目失效。 + +## 已知限制与后续工作 + + + +- 此开关针对 `@deepseek-ai/dsh-web-app` 插入的条目。没有该 Bundle 的 profile 不含这些条目,此 Bundle 在那里不产生变化。 +- 选中此 Bundle 会给每个活跃根智能体增加四个定时工具的 schema,并为每个符合条件的步骤增加一条时钟读数。即使对话从不创建提醒,也会承担这两项开销。 + +----- + + +### 开发备注 + +
+维护者信息 — 点击展开 + +无。 + +
diff --git a/packages/experimental/schedule-bundle/cordis.patch.yml b/packages/experimental/schedule-bundle/cordis.patch.yml new file mode 100644 index 0000000000..3ae14343f2 --- /dev/null +++ b/packages/experimental/schedule-bundle/cordis.patch.yml @@ -0,0 +1,12 @@ +# Experimental Schedule switch over the shipped Web composition. `dsh-web-app` +# inserts the three rows with `disabled: true`; this layer flips them on and +# appends nothing, so enabling it cannot mount a Host service twice. + +- id: time-context + disabled: false + +- id: schedule + disabled: false + +- id: ui-schedule + disabled: false diff --git a/packages/experimental/schedule-bundle/icon.svg b/packages/experimental/schedule-bundle/icon.svg new file mode 100644 index 0000000000..4299a86395 --- /dev/null +++ b/packages/experimental/schedule-bundle/icon.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/packages/experimental/schedule-bundle/locale/en.json b/packages/experimental/schedule-bundle/locale/en.json new file mode 100644 index 0000000000..f748924183 --- /dev/null +++ b/packages/experimental/schedule-bundle/locale/en.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "Scheduling and time context", + "description": "Enable durable reminders, the Automation tasks page, and per-step clock context." + } +} diff --git a/packages/experimental/schedule-bundle/locale/zh.json b/packages/experimental/schedule-bundle/locale/zh.json new file mode 100644 index 0000000000..47abb9b169 --- /dev/null +++ b/packages/experimental/schedule-bundle/locale/zh.json @@ -0,0 +1,6 @@ +{ + "meta": { + "title": "定时与时间上下文", + "description": "启用持久提醒、自动化任务页面与逐步时钟上下文。" + } +} diff --git a/packages/experimental/schedule-bundle/package.json b/packages/experimental/schedule-bundle/package.json new file mode 100644 index 0000000000..ba15cc8922 --- /dev/null +++ b/packages/experimental/schedule-bundle/package.json @@ -0,0 +1,48 @@ +{ + "name": "@deepseek-ai/dsh-experimental-schedule-bundle", + "description": "Optional bundle that switches the shipped Schedule, time-context, and reminder-catalog rows on", + "version": "0.1.7-rc.1", + "icon": "./icon.svg", + "publishConfig": { + "access": "public" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/deepseek-ai/deepseek-harness.git", + "directory": "packages/experimental/schedule-bundle" + }, + "type": "module", + "main": "lib/index.js", + "types": "lib/types/index.d.ts", + "exports": { + ".": { + "types": "./lib/types/index.d.ts", + "default": "./lib/index.js" + }, + "./src/*": "./src/*", + "./package.json": "./package.json", + "./cordis.patch.yml": "./cordis.patch.yml", + "./locale/*.json": "./locale/*.json" + }, + "files": [ + "icon.svg", + "locale/*.json", + "lib/index.js", + "cordis.patch.yml", + "lib/types/**/*.d.ts" + ], + "license": "MIT", + "peerDependencies": { + "@deepseek-ai/cordis": "workspace:~" + }, + "devDependencies": { + "@deepseek-ai/cordis": "workspace:~", + "@deepseek-ai/cordis-plugin-include": "workspace:~", + "js-yaml": "^4.2.0" + }, + "dsh": { + "bundle": { + "patch": "./cordis.patch.yml" + } + } +} diff --git a/packages/experimental/schedule-bundle/src/index.ts b/packages/experimental/schedule-bundle/src/index.ts new file mode 100644 index 0000000000..bebbdde0ec --- /dev/null +++ b/packages/experimental/schedule-bundle/src/index.ts @@ -0,0 +1,2 @@ +/** Experimental Schedule composition switch; the patched rows live in cordis.patch.yml. */ +export {} diff --git a/packages/experimental/schedule-bundle/tests/patch.spec.ts b/packages/experimental/schedule-bundle/tests/patch.spec.ts new file mode 100644 index 0000000000..0e61e1c91d --- /dev/null +++ b/packages/experimental/schedule-bundle/tests/patch.spec.ts @@ -0,0 +1,56 @@ +/** The experimental Schedule switch must flip exactly the three rows the Web bundle inserts. */ + +import { readFileSync } from 'node:fs' +import { resolve } from 'node:path' +import { fileURLToPath } from 'node:url' +import { describe, expect, it } from 'vitest' +import * as yaml from 'js-yaml' +import { entryListSchema } from '@deepseek-ai/cordis-plugin-include' + +const root = fileURLToPath(new URL('..', import.meta.url)) + +interface Manifest { + name?: string + icon?: string + private?: boolean + publishConfig?: { access?: string } + exports?: Record + dependencies?: Record + dsh?: { bundle?: { patch?: string } } +} + +interface Patch { + id?: string + name?: string + disabled?: boolean + insert?: unknown[] +} + +describe('experimental Schedule bundle', () => { + const manifest = JSON.parse(readFileSync(resolve(root, 'package.json'), 'utf8')) as Manifest + + it('publishes as an experimental bundle with plugin-manager display metadata', () => { + expect(manifest.name).toBe('@deepseek-ai/dsh-experimental-schedule-bundle') + expect(manifest.private).toBeUndefined() + expect(manifest.publishConfig?.access).toBe('public') + expect(manifest.icon).toBe('./icon.svg') + expect(manifest.dsh?.bundle?.patch).toBe('./cordis.patch.yml') + expect(manifest.exports?.['./locale/*.json']).toBe('./locale/*.json') + expect(manifest.exports?.['./cordis.patch.yml']).toBe('./cordis.patch.yml') + // The patch only overrides rows another layer inserts, so it depends on no plugin package. + expect(manifest.dependencies).toBeUndefined() + }) + + it('flips the three shipped rows on and appends none', () => { + const parsed = yaml.load(readFileSync(resolve(root, './cordis.patch.yml'), 'utf8'), { schema: entryListSchema }) + expect(parsed).toEqual([ + { id: 'time-context', disabled: false }, + { id: 'schedule', disabled: false }, + { id: 'ui-schedule', disabled: false }, + ]) + for (const patch of parsed as Patch[]) { + expect(patch.insert).toBeUndefined() + expect(patch.name).toBeUndefined() + } + }) +}) diff --git a/packages/experimental/schedule-bundle/tsconfig.json b/packages/experimental/schedule-bundle/tsconfig.json new file mode 100644 index 0000000000..f1a449634c --- /dev/null +++ b/packages/experimental/schedule-bundle/tsconfig.json @@ -0,0 +1,15 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "rootDir": "src", + "outDir": "lib/types" + }, + "include": [ + "src" + ], + "references": [ + { + "path": "../../../vendor/cordis" + } + ] +} diff --git a/packages/experimental/schedule-bundle/tsdown.config.ts b/packages/experimental/schedule-bundle/tsdown.config.ts new file mode 100644 index 0000000000..be29690579 --- /dev/null +++ b/packages/experimental/schedule-bundle/tsdown.config.ts @@ -0,0 +1,3 @@ +import { defineConfig } from 'tsdown' + +export default defineConfig({ entry: ['lib/types/index.js'], outDir: 'lib', format: ['esm'], platform: 'node', target: 'es2024', fixedExtension: false, dts: false, clean: false }) diff --git a/packages/schedule/schedule/README.i18n.yaml b/packages/schedule/schedule/README.i18n.yaml index 86176d8c0e..80bd55f6f7 100644 --- a/packages/schedule/schedule/README.i18n.yaml +++ b/packages/schedule/schedule/README.i18n.yaml @@ -15,8 +15,8 @@ en: 23386452a66b2fbd zh: 4a8d91b2f313fead /deepseek-ai-dsh-schedule/use-this-package: - en: 401d9737620b86d9 - zh: 0ebbc36e2fe157f3 + en: db292f4e03cef41b + zh: 064cb553698d548c /deepseek-ai-dsh-schedule/understand-the-implementation: en: 676b7c508f37a1b7 zh: c5e8520b3350f0b0 diff --git a/packages/schedule/schedule/README.md b/packages/schedule/schedule/README.md index cc39506ee6..b932e52e13 100644 --- a/packages/schedule/schedule/README.md +++ b/packages/schedule/schedule/README.md @@ -23,7 +23,7 @@ Schedule delivers one-shot, fixed-rate, daily, weekly, and cron wall-clock remin ## Use this package -The shipped Web bundle mounts the service alongside storage-domain and the Session controller. Its `Config` states `deliveryHistoryDays` (default 30) and `deliveryHistoryRecords` (default 200). Storage backend routing belongs to storage-domain; Session model and preset restoration belong to the Session controller. Schedule cannot be mounted alone in a headless or SDK-only composition: delivery requires the Host Web Session controller and a Session persistence backend, because a delivery commits only after the Session acknowledges `session/flush`. +The shipped Web composition carries the `schedule` row disabled; enable the optional experimental bundle `@deepseek-ai/dsh-experimental-schedule-bundle` from the Plugins page (Official group), or list it in a profile's `dsh.profile.bundles`, to mount the service alongside storage-domain and the Session controller. Its `Config` states `deliveryHistoryDays` (default 30) and `deliveryHistoryRecords` (default 200). Storage backend routing belongs to storage-domain; Session model and preset restoration belong to the Session controller. Schedule cannot be mounted alone in a headless or SDK-only composition: delivery requires the Host Web Session controller and a Session persistence backend, because a delivery commits only after the Session acknowledges `session/flush`. The Agent receives `schedule_create`, `schedule_list`, `schedule_delete`, and `schedule_update`. Update replaces the name, instruction, or timing of one reminder in place and keeps its id and saved records; it is not offered for the relative `after` delay. Creation requires a non-empty prompt, a title, and exactly one of six selectors: diff --git a/packages/schedule/schedule/README.zh.md b/packages/schedule/schedule/README.zh.md index 93f67b6cab..6b4e70c9c1 100644 --- a/packages/schedule/schedule/README.zh.md +++ b/packages/schedule/schedule/README.zh.md @@ -23,7 +23,7 @@ Schedule 将一次性、固定周期、按每日、按每周以及 cron 本地 ## 使用此包 -发布的 Web bundle 将此服务与 storage-domain、Session controller 一起挂载。其 `Config` 声明 `deliveryHistoryDays`(默认 30)与 `deliveryHistoryRecords`(默认 200)。存储后端路由由 storage-domain 管理;会话模型与 preset 恢复由 Session controller 管理。Schedule 无法在 headless 或仅 SDK 的组合中单独挂载:投递需要 Host 的 Web Session controller 和 Session 持久化后端,因为只有在 Session 确认 `session/flush` 之后一次投递才会提交。 +随发行版交付的 Web 组合把 `schedule` 行保持禁用;在插件管理页(Official 分组)启用可选实验性 bundle `@deepseek-ai/dsh-experimental-schedule-bundle`,或把它列进 profile 的 `dsh.profile.bundles`,即可将此服务与 storage-domain、Session controller 一起挂载。其 `Config` 声明 `deliveryHistoryDays`(默认 30)与 `deliveryHistoryRecords`(默认 200)。存储后端路由由 storage-domain 管理;会话模型与 preset 恢复由 Session controller 管理。Schedule 无法在 headless 或仅 SDK 的组合中单独挂载:投递需要 Host 的 Web Session controller 和 Session 持久化后端,因为只有在 Session 确认 `session/flush` 之后一次投递才会提交。 Agent 获得 `schedule_create`、`schedule_list`、`schedule_delete` 和 `schedule_update`。更新原地替换一条提醒的名称、指令或时间,保留其 id 与已保存记录;相对的 `after` 延迟不支持更新。创建时需要非空提示文本、标题,且必须只提供以下六个选择器之一: diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 36dc0506d3..49642d4755 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -247,6 +247,9 @@ importers: '@deepseek-ai/dsh-experimental-auto-review': specifier: workspace:* version: link:../../packages/experimental/auto-review + '@deepseek-ai/dsh-experimental-schedule-bundle': + specifier: workspace:* + version: link:../../packages/experimental/schedule-bundle '@deepseek-ai/dsh-experimental-voice-input-bundle': specifier: workspace:* version: link:../../packages/experimental/voice-input-bundle @@ -7769,6 +7772,18 @@ importers: specifier: workspace:* version: link:../../util/values + packages/experimental/schedule-bundle: + devDependencies: + '@deepseek-ai/cordis': + specifier: workspace:~ + version: link:../../../vendor/cordis + '@deepseek-ai/cordis-plugin-include': + specifier: workspace:~ + version: link:../../../vendor/include + js-yaml: + specifier: ^4.2.0 + version: 4.3.1 + packages/experimental/speech-to-text: dependencies: '@deepseek-ai/dsh-brand': diff --git a/scripts/release/families.spec.ts b/scripts/release/families.spec.ts index a54d7c3fb2..003c97074d 100644 --- a/scripts/release/families.spec.ts +++ b/scripts/release/families.spec.ts @@ -62,6 +62,7 @@ describe('release families', () => { '@deepseek-ai/dsh-experimental-computer-use-cua-driver-native', '@deepseek-ai/dsh-experimental-inspector', '@deepseek-ai/dsh-experimental-ptc-runtime-python', + '@deepseek-ai/dsh-experimental-schedule-bundle', '@deepseek-ai/dsh-experimental-speech-to-text-sensevoice', '@deepseek-ai/dsh-experimental-speech-to-text', '@deepseek-ai/dsh-experimental-tool-agent-team', diff --git a/tsconfig.base.json b/tsconfig.base.json index e2b7da61e8..f303dfc77a 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -319,6 +319,7 @@ "@deepseek-ai/dsh-experimental-inspector": ["./packages/experimental/inspector/src"], "@deepseek-ai/dsh-experimental-inspector/client": ["./packages/experimental/inspector/src/client/index.ts"], "@deepseek-ai/dsh-experimental-ptc-runtime-python": ["./packages/experimental/ptc-runtime-python/src"], + "@deepseek-ai/dsh-experimental-schedule-bundle": ["./packages/experimental/schedule-bundle/src/index.ts"], "@deepseek-ai/dsh-util-crypto": ["./packages/util/crypto/src"], "@deepseek-ai/dsh-util-values": ["./packages/util/values/src"], "@deepseek-ai/dsh-util-code-language": ["./packages/util/code-language/src"], From d0f62c36facdbc4e7fc70336193c16819f88481d Mon Sep 17 00:00:00 2001 From: Chinesezjc Date: Thu, 24 Sep 2026 21:05:54 +0800 Subject: [PATCH 2/9] build(schedule-bundle): add the bundle to the host program references --- tsconfig.host.json | 1 + 1 file changed, 1 insertion(+) diff --git a/tsconfig.host.json b/tsconfig.host.json index bbdbf3cac5..f73460ef8c 100644 --- a/tsconfig.host.json +++ b/tsconfig.host.json @@ -357,6 +357,7 @@ { "path": "./packages/terminal/tool-terminal" }, { "path": "./packages/ptc-runtime/ptc-runtime" }, { "path": "./packages/experimental/ptc-runtime-python" }, + { "path": "./packages/experimental/schedule-bundle" }, { "path": "./packages/ptc-runtime/ptc-runtime-node" }, { "path": "./packages/llm/llm-deepseek" }, { "path": "./packages/llm/llm-deepseek-api-key" }, From 3ce7b1142546cc46a44c1c5b2edd6b73168ec250 Mon Sep 17 00:00:00 2001 From: Chinesezjc Date: Thu, 24 Sep 2026 21:32:28 +0800 Subject: [PATCH 3/9] fix(schedule-bundle): satisfy the omitted-companion README rule and refresh the plugin goldens --- apps/web/tests/expected/plugin-config/official.expected.md | 6 +++++- .../tests/expected/plugin-manager/live-enabled.expected.md | 6 +++++- apps/web/tests/expected/plugin-manager/manager.expected.md | 6 +++++- packages/experimental/schedule-bundle/README.i18n.yaml | 2 +- packages/experimental/schedule-bundle/README.md | 2 +- 5 files changed, 17 insertions(+), 5 deletions(-) diff --git a/apps/web/tests/expected/plugin-config/official.expected.md b/apps/web/tests/expected/plugin-config/official.expected.md index d408f284f3..247d6ac308 100644 --- a/apps/web/tests/expected/plugin-config/official.expected.md +++ b/apps/web/tests/expected/plugin-config/official.expected.md @@ -3,7 +3,7 @@ - button "刷新" - button "添加插件" - heading "官方" [level=3] -- text: "7" +- text: "8" - list: - listitem: - button "查看 智能体团队": 智能体团队 @@ -13,6 +13,10 @@ - button "查看 自动授权审查": 自动授权审查 - text: 实验性 提供自动审查权限模式,由模型在每次工具调用前判断是否授权。 - switch "启用 自动授权审查" + - listitem: + - button "查看 定时与时间上下文": 定时与时间上下文 + - text: 实验性 启用持久提醒、自动化任务页面与逐步时钟上下文。 + - switch "启用 定时与时间上下文" - listitem: - button "查看 语音输入": 语音输入 - text: 实验性 在本机使用 SenseVoice 转写录音;首次使用需安装依赖 diff --git a/apps/web/tests/expected/plugin-manager/live-enabled.expected.md b/apps/web/tests/expected/plugin-manager/live-enabled.expected.md index 2f7b9bc832..4bd8ed064e 100644 --- a/apps/web/tests/expected/plugin-manager/live-enabled.expected.md +++ b/apps/web/tests/expected/plugin-manager/live-enabled.expected.md @@ -3,7 +3,7 @@ - button "刷新" - button "添加插件" - heading "官方" [level=3] -- text: "7" +- text: "8" - list: - listitem: - button "查看 智能体团队": 智能体团队 @@ -13,6 +13,10 @@ - button "查看 自动授权审查": 自动授权审查 - text: 实验性 提供自动审查权限模式,由模型在每次工具调用前判断是否授权。 - switch "启用 自动授权审查" + - listitem: + - button "查看 定时与时间上下文": 定时与时间上下文 + - text: 实验性 启用持久提醒、自动化任务页面与逐步时钟上下文。 + - switch "启用 定时与时间上下文" - listitem: - button "查看 语音输入": 语音输入 - text: 实验性 在本机使用 SenseVoice 转写录音;首次使用需安装依赖 diff --git a/apps/web/tests/expected/plugin-manager/manager.expected.md b/apps/web/tests/expected/plugin-manager/manager.expected.md index 61c517953b..b188be8787 100644 --- a/apps/web/tests/expected/plugin-manager/manager.expected.md +++ b/apps/web/tests/expected/plugin-manager/manager.expected.md @@ -3,7 +3,7 @@ - button "刷新" - button "添加插件" - heading "官方" [level=3] -- text: "7" +- text: "8" - list: - listitem: - button "查看 智能体团队": 智能体团队 @@ -13,6 +13,10 @@ - button "查看 自动授权审查": 自动授权审查 - text: 实验性 提供自动审查权限模式,由模型在每次工具调用前判断是否授权。 - switch "启用 自动授权审查" + - listitem: + - button "查看 定时与时间上下文": 定时与时间上下文 + - text: 实验性 启用持久提醒、自动化任务页面与逐步时钟上下文。 + - switch "启用 定时与时间上下文" - listitem: - button "查看 语音输入": 语音输入 - text: 实验性 在本机使用 SenseVoice 转写录音;首次使用需安装依赖 diff --git a/packages/experimental/schedule-bundle/README.i18n.yaml b/packages/experimental/schedule-bundle/README.i18n.yaml index a07b7aa5b1..98d86454bc 100644 --- a/packages/experimental/schedule-bundle/README.i18n.yaml +++ b/packages/experimental/schedule-bundle/README.i18n.yaml @@ -18,7 +18,7 @@ en: ffaa4b18e10a1df9 zh: b675fd8195ebb057 /deepseek-ai-dsh-experimental-schedule-bundle/understand-the-implementation: - en: 9bb32d6e6930f0c2 + en: 90beaeda691bd0a7 zh: d81683d7bb1f6903 /deepseek-ai-dsh-experimental-schedule-bundle/further-exploration: en: 99a29dddf9805540 diff --git a/packages/experimental/schedule-bundle/README.md b/packages/experimental/schedule-bundle/README.md index 10f254bc11..6e3abd4eea 100644 --- a/packages/experimental/schedule-bundle/README.md +++ b/packages/experimental/schedule-bundle/README.md @@ -35,7 +35,7 @@ Open Plugins in the Web sidebar and enable Scheduling and time context, marked b
Maintainer details — click to expand -`cordis.patch.yml` carries three id-targeted patches, each setting `disabled: false` on a row the Web bundle already inserts. `OPTIONAL_BUNDLES` in `packages/boot/app-boot/src/profile.ts` names this package and `apps/cli` depends on it, so every installation ships it switched off and the plugin manager offers it in the Official group. Selecting it appends the bundle to the profile's `dsh.profile.bundles` list, and the profile launcher applies the bundle layers after the Web layer. No runtime invariant companion is published, because this configuration-only package owns no mutable runtime state. +`cordis.patch.yml` carries three id-targeted patches, each setting `disabled: false` on a row the Web bundle already inserts. `OPTIONAL_BUNDLES` in `packages/boot/app-boot/src/profile.ts` names this package and `apps/cli` depends on it, so every installation ships it switched off and the plugin manager offers it in the Official group. Selecting it appends the bundle to the profile's `dsh.profile.bundles` list, and the profile launcher applies the bundle layers after the Web layer. No runtime invariant companion is published because this configuration-only package owns no mutable runtime state. | File | Role | |---|---| From 1145adee07216bdb5d8487046f4d732569f7b3d0 Mon Sep 17 00:00:00 2001 From: Chinesezjc Date: Fri, 25 Sep 2026 15:00:26 +0800 Subject: [PATCH 4/9] docs(schedule-bundle): correct the notes, README limits, and composed patch spec Archive the reversed 2026-09-24-web-default-schedule-composition triplet and name the four bundles in the optional-bundles note. Rewrite the opt-in note's Problem to the state at the branch base and state why the bundle switches time-context on with schedule. Record the missing-row warnings, the bundle list order, and the bundle detail page's empty state in the bundle README. Pin the composed Schedule rows in scripts/optional-bundles.spec.ts and move the cli dependency entry into order. --- ...web-default-schedule-composition.i18n.yaml | 6 +++ ...-09-24-web-default-schedule-composition.md | 40 +++++++++++++++++++ ...-24-web-default-schedule-composition.zh.md | 40 +++++++++++++++++++ .agents/notes/archived/manifest.json | 3 ++ ...capabilities-as-optional-bundles.i18n.yaml | 8 ++-- ...mental-capabilities-as-optional-bundles.md | 4 +- ...tal-capabilities-as-optional-bundles.zh.md | 4 +- ...-schedule-opt-in-optional-bundle.i18n.yaml | 12 +++--- ...6-09-24-schedule-opt-in-optional-bundle.md | 6 +-- ...9-24-schedule-opt-in-optional-bundle.zh.md | 6 +-- apps/cli/package.json | 2 +- .../schedule-bundle/README.i18n.yaml | 8 ++-- .../experimental/schedule-bundle/README.md | 6 +-- .../experimental/schedule-bundle/README.zh.md | 6 +-- scripts/optional-bundles.spec.ts | 23 ++++++++++- 15 files changed, 142 insertions(+), 32 deletions(-) create mode 100644 .agents/notes/archived/architecture/2026-09-24-web-default-schedule-composition.i18n.yaml create mode 100644 .agents/notes/archived/architecture/2026-09-24-web-default-schedule-composition.md create mode 100644 .agents/notes/archived/architecture/2026-09-24-web-default-schedule-composition.zh.md diff --git a/.agents/notes/archived/architecture/2026-09-24-web-default-schedule-composition.i18n.yaml b/.agents/notes/archived/architecture/2026-09-24-web-default-schedule-composition.i18n.yaml new file mode 100644 index 0000000000..b5321c036f --- /dev/null +++ b/.agents/notes/archived/architecture/2026-09-24-web-default-schedule-composition.i18n.yaml @@ -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 +2026-09-24-web-default-schedule-composition.md: 3f27bb09ebc00d42c32563e17a1de82c8e525be1 +2026-09-24-web-default-schedule-composition.zh.md: 9e0e1fb77ce89b579e1bc8b0d4d0a1b9f4e9fea5 diff --git a/.agents/notes/archived/architecture/2026-09-24-web-default-schedule-composition.md b/.agents/notes/archived/architecture/2026-09-24-web-default-schedule-composition.md new file mode 100644 index 0000000000..3f27bb09eb --- /dev/null +++ b/.agents/notes/archived/architecture/2026-09-24-web-default-schedule-composition.md @@ -0,0 +1,40 @@ +# Agent Note: Schedule in the shipped Web composition + +Status: implemented +Archived: 2026-09-25 + +English | [中文](2026-09-24-web-default-schedule-composition.zh.md) + +## Problem + +The Automation tasks page, the Session reminder catalog, and the `schedule_*` tools reached a Web deployment only through `--patch apps/cli/config/examples/schedule/cordis.yml`. `packages/bundle/web-app/cordis.patch.yml` carried the `ui-schedule` client row with `disabled: true`, and the Host rows `time-context` and `schedule` existed in that overlay alone. A person running the shipped `web` profile therefore saw no Automation tasks entry and no reminder tools, while every consumer that wanted them repeated the same three rows: the repository preview image kept its own overlay list, and two Web suites hard-coded the overlay path. + +## Decision + +`packages/bundle/web-app/cordis.patch.yml` inserts `time-context` and `schedule` in its Host row list and leaves `ui-schedule` enabled; `packages/bundle/web-app/package.json` declares both packages, which `verify-cordis-config` requires for a bare row name in a bundle patch. The `web` profile consequently ships the Automation tasks page, the Session-header reminder clock, the idle Session row's clock mark and hover list, the right-Sidebar task tab, and `schedule_create`, `schedule_list`, `schedule_update`, and `schedule_delete` on every live root Agent. + +`apps/cli/config/examples/schedule/cordis.yml` is deleted. `applyEntryPatches` appends an `insert` list without de-duplicating ids, so keeping the overlay would mount `time-context` and `schedule` a second time; the two Web suites and the preview packer that named the overlay compose the shipped profile alone. + +`time-context` ships with Schedule because a reminder request states a wall-clock target. The plugin appends one durable user message per eligible step carrying the sampled instant, the browser zone attached to the open request, and the elapsed time since the preceding model-visible message. The sampling instant is what lets the model turn a request such as "tomorrow at nine" into an offset-bearing `at` value; the [Schedule subsystem](../../../../docs/subsystems/schedule.md) owns that interpretation boundary and the explicit-zone requirement it feeds. + +The Host service, its storage domain, and the client half are unchanged. This decision moves which composition mounts them, and the [Host-owned scheduled messages decision](2026-09-16-host-schedule-storage.md) continues to own task storage, activation, dispatch, and delivery records. + +## Recorded sessions + +A Web scenario that drives a live step now logs one time-context reading per step, so its committed Session fixture and header sidecars were refreshed. A reading's sampled instant, browser zone, and elapsed duration are volatile, and `normalizeWebSessionVolatiles` in `apps/web/tests/scaffold.ts` replaces them with `{{timeContextTimestamp}}`, `{{clientTimeZone}}`, and `{{elapsed}}`. The turn and step numbers and the preceding-event baseline stay readable, so a fixture still shows what the model received. Refresh writes the current writer generation (`session.v4.jsonl`) beside the retained predecessors, which remain committed replay baselines. + +## Alternatives considered + +**Keep the overlay and change nothing.** The shipped surface would keep contradicting the product documentation that describes the Automation tasks entry, and each consumer would keep its own copy of the three rows. The overlay also cannot satisfy the request that the default `dsh web` process exposes the page without a flag. + +**Ship the Schedule rows without `time-context`.** The model would then have no sampling instant of its own, so an unqualified date or time in a reminder request would depend on a separate clock source; the overlay paired the two rows for that reason. + +**Reach for a separate optional bundle.** `OPTIONAL_BUNDLES` exists for bundles a person switches on from the plugin manager, which is the same opt-in shape as the overlay; the decision here is that a default Web surface owns the page and the tools. + +## Consequences + +- Every Web session's request header carries four additional tool schemas, and every eligible step appends one durable user message. A conversation that never creates a reminder pays that token cost. +- The clock reading is model-visible and durable, so it replays, compacts, and appears in exported Session logs like any other user message. +- A deployment that wants the previous behavior disables the `time-context`, `schedule`, and `ui-schedule` rows in its own profile patch layer; the capability itself is untouched. +- The `cordis_inspect_query` `listTools` answer for a full preset table now passes the base composition's 12,500-token inline budget, so the spill policy retains that answer's head and tail with a spill path instead of the complete JSON. +- The repository preview image and both Web suites drop their overlay arguments, so one composition change reaches every surface at once. diff --git a/.agents/notes/archived/architecture/2026-09-24-web-default-schedule-composition.zh.md b/.agents/notes/archived/architecture/2026-09-24-web-default-schedule-composition.zh.md new file mode 100644 index 0000000000..9e0e1fb77c --- /dev/null +++ b/.agents/notes/archived/architecture/2026-09-24-web-default-schedule-composition.zh.md @@ -0,0 +1,40 @@ +# Agent Note: 默认 Web 组合中的 Schedule + +Status: implemented +Archived: 2026-09-25 + +[English](2026-09-24-web-default-schedule-composition.md) | 中文 + +## Problem + +自动化任务页面、Session 提醒目录以及 `schedule_*` 工具此前只能通过 `--patch apps/cli/config/examples/schedule/cordis.yml` 进入某个 Web 部署:`packages/bundle/web-app/cordis.patch.yml` 里的 `ui-schedule` 客户端行带 `disabled: true`,而宿主行 `time-context` 与 `schedule` 只存在于那个 overlay 中。因此运行发布版 `web` profile 的人既看不到自动化任务入口,也拿不到提醒工具;同时每个需要它们的消费者都要重复同样的三行:仓库预览镜像自行维护了一份 overlay 列表,两个 Web 测试套件各自硬编码了 overlay 路径。 + +## Decision + +`packages/bundle/web-app/cordis.patch.yml` 在其宿主行列表中插入 `time-context` 与 `schedule`,并让 `ui-schedule` 保持启用;`packages/bundle/web-app/package.json` 声明这两个包,这是 `verify-cordis-config` 对 bundle patch 中裸包名的要求。因此 `web` profile 会交付自动化任务页面、Session 页头的提醒时钟、空闲 Session 行的时钟标记与悬停列表、右侧栏任务页签,并在每个 live 根 Agent 上注册 `schedule_create`、`schedule_list`、`schedule_update` 与 `schedule_delete`。 + +`apps/cli/config/examples/schedule/cordis.yml` 已删除。`applyEntryPatches` 追加 `insert` 列表时不对 id 去重,保留该 overlay 会把 `time-context` 与 `schedule` 挂载两次;原本引用它的两个 Web 测试套件与预览打包器现在只组合发布版 profile。 + +`time-context` 随 Schedule 一起发布,因为提醒请求本身给出的是墙上时钟目标。该插件在每个符合条件的步骤追加一条持久 user 消息,包含采样瞬时、附加到当前开放请求的浏览器时区,以及自前一条模型可见消息以来的经过时长。正是采样瞬时让模型能把「明天九点」这类请求落成带偏移量的 `at` 值;该解释边界及其要求的显式时区由 [Schedule 子系统](../../../../docs/subsystems/schedule.zh.md)负责。 + +宿主服务、其存储 domain 与客户端半边都没有改动。本决策改变的是由哪个组合挂载它们,任务存储、激活、投递与投递记录仍由[宿主定时消息决策](2026-09-16-host-schedule-storage.zh.md)负责。 + +## Recorded sessions + +驱动 live 步骤的 Web 场景现在每步记录一条 time-context 读数,因此其已提交的 Session 夹具与页头 sidecar 都已重刷。一条读数中的采样瞬时、浏览器时区与经过时长是易变值,`apps/web/tests/scaffold.ts` 的 `normalizeWebSessionVolatiles` 会把它们替换为 `{{timeContextTimestamp}}`、`{{clientTimeZone}}` 和 `{{elapsed}}`。turn 与 step 序号以及"前一条事件"的基线保持可读,因此夹具仍能显示模型收到的内容。重刷会在已保留的上一代旁写入当前 writer 代次(`session.v4.jsonl`),旧代次继续作为已提交的回放基线保留。 + +## Alternatives considered + +**保留 overlay,不做任何改动。** 发布版界面会继续与描述该自动化任务入口的产品文档相矛盾,而每个消费者都要各自保留那三行的副本。overlay 也无法满足「默认 `dsh web` 进程不带 flag 就暴露该页面」这一要求。 + +**只发布 Schedule 两行,不带 `time-context`。** 模型将没有自己的采样瞬时,于是提醒请求中未明确限定时区的日期或时间要依赖另一个时钟来源;overlay 当初正是为此把两行配对。 + +**另建一个可选 bundle。** `OPTIONAL_BUNDLES` 面向的是用户在插件管理器里主动开启的 bundle,与 overlay 是同一种 opt-in 形态;本决策要的是默认 Web 界面自己拥有该页面与这些工具。 + +## Consequences + +- 每个 Web 会话的请求头多出四个工具 schema,且每个符合条件的步骤追加一条持久 user 消息。从不创建提醒的对话也要承担这份 token 成本。 +- 时钟读数对模型可见且持久,因此它与其他 user 消息一样参与回放、压缩,并出现在导出的 Session 日志中。 +- 想要恢复旧行为的部署,可在自己的 profile patch 层禁用 `time-context`、`schedule` 与 `ui-schedule` 三行;能力本身没有改动。 +- 完整预设表的 `cordis_inspect_query` `listTools` 答案现在超过基础组合 12,500 token 的内联预算,因此 spill 策略改为保留该答案的首尾并给出 spill 路径,而不是完整 JSON。 +- 仓库预览镜像与两个 Web 测试套件都不再传 overlay 参数,一处组合改动即同时作用于所有界面。 diff --git a/.agents/notes/archived/manifest.json b/.agents/notes/archived/manifest.json index 5ed6850038..b4e085deb2 100644 --- a/.agents/notes/archived/manifest.json +++ b/.agents/notes/archived/manifest.json @@ -376,6 +376,9 @@ "architecture/2026-09-11-wasm-preview-font-and-image-budgets.i18n.yaml": "sha256:af027c7dae53a181e4d73fd2309f69e9ae3c48df0d3b1dfc53cae274aa60d69e", "architecture/2026-09-11-wasm-preview-font-and-image-budgets.md": "sha256:44dd52839cdb67644c0dbcbc4beb6f36802628c4a8d17a0aad11db1f9be649ed", "architecture/2026-09-11-wasm-preview-font-and-image-budgets.zh.md": "sha256:8285432ee1676be8b79a05953c4b6ac4a7ca5d8e701173b3a2b533608b584d0a", + "architecture/2026-09-24-web-default-schedule-composition.i18n.yaml": "sha256:8c3d5c614924d0e81f361a299427ac697aefc6189c41eb3f4151f5c42e371ca0", + "architecture/2026-09-24-web-default-schedule-composition.md": "sha256:3a139593ade13f95cbb67094c1eec66cb0a2c14bcc154512799803b2a7d22ab4", + "architecture/2026-09-24-web-default-schedule-composition.zh.md": "sha256:59908f7987058742d1226dc8a801d03c265c84d51172249ba51716b91f084f0c", "bug-fix/2026-07-19-windows-atomic-write-dacl-preservation.i18n.yaml": "sha256:8be5b0afd8820c593e2ec254d35fb8c384267814104f6234bb9af824c5f974ba", "bug-fix/2026-07-19-windows-atomic-write-dacl-preservation.md": "sha256:861e6130e893489271478def5f54f212a106a1580b744e6e40f56356f73c7e10", "bug-fix/2026-07-19-windows-atomic-write-dacl-preservation.zh.md": "sha256:3549257e06f074591de580ebfaa71284c7c384fb0ffb1963c30258d7a7c26db7", diff --git a/.agents/notes/implemented/architecture/2026-09-21-experimental-capabilities-as-optional-bundles.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-21-experimental-capabilities-as-optional-bundles.i18n.yaml index e8573b2e72..87aa04a960 100644 --- a/.agents/notes/implemented/architecture/2026-09-21-experimental-capabilities-as-optional-bundles.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-21-experimental-capabilities-as-optional-bundles.i18n.yaml @@ -9,11 +9,11 @@ en: 2ba6c43b20a3d347 zh: 5647179ddaa38ad9 /agent-note-ship-experimental-capabilities-as-optional-bundles/decision: - en: 1c5a43b3ce2d3056 - zh: b59f549a12cf67d1 + en: fdd54ede661f7a83 + zh: a41ed1a872bb8ba3 /agent-note-ship-experimental-capabilities-as-optional-bundles/alternatives-considered: en: a65d84004e48b3ef zh: 17221f08e7a8a89b /agent-note-ship-experimental-capabilities-as-optional-bundles/consequences: - en: d52ed0a248131a37 - zh: 779b8d415281c5da + en: 71482af50ad31d54 + zh: 12d4849104842f0d diff --git a/.agents/notes/implemented/architecture/2026-09-21-experimental-capabilities-as-optional-bundles.md b/.agents/notes/implemented/architecture/2026-09-21-experimental-capabilities-as-optional-bundles.md index a2a83645c9..48d3fee0bb 100644 --- a/.agents/notes/implemented/architecture/2026-09-21-experimental-capabilities-as-optional-bundles.md +++ b/.agents/notes/implemented/architecture/2026-09-21-experimental-capabilities-as-optional-bundles.md @@ -10,7 +10,7 @@ The Web plugin page offered two optional bundles, Agent Teams and voice input. A ## Decision -`OPTIONAL_BUNDLES` lists Agent Teams, voice input, and Auto review. Every optional bundle declares `icon` and exports `./locale/*.json` with `meta.title` and `meta.description`, so the Official group renders a localized title, description, and image; `verify-default-product-isolation` rejects an optional bundle without them. The Inspector's `cordis.patch.yml` names the package instead of a built-artifact path, so the same file is the bundle patch and the `--patch` overlay for a built Web launch. +`OPTIONAL_BUNDLES` lists Agent Teams, voice input, Auto review, and the Schedule bundle. Every optional bundle declares `icon` and exports `./locale/*.json` with `meta.title` and `meta.description`, so the Official group renders a localized title, description, and image; `verify-default-product-isolation` rejects an optional bundle without them. The Inspector's `cordis.patch.yml` names the package instead of a built-artifact path, so the same file is the bundle patch and the `--patch` overlay for a built Web launch. An optional bundle is a runtime dependency of the installation, so its dependency graph is downloaded by every `dsh` install. The list therefore admits only packages whose graph is already in the installation's closure; Auto review adds nothing. The Inspector stays available through explicit installation and does not appear in the default plugin list. The browser-use and computer-use providers stay explicit compositions: Playwright MCP, Chrome DevTools MCP, and the native Cua Driver runtime binaries add about 85 MB and 21 packages to every install whether or not the bundle is enabled, and a shipped Cua Driver MCP switch would offer a capability whose executable the installation does not carry. Those provider packages keep locale display metadata for their component rows. Two more packages stay out for other reasons: `ptc-runtime-python` replaces the PTC runtime, and `workflow-ptc` rejects a non-TypeScript runtime at load while the Web presets carry `workflow-ptc` rows a bundle patch cannot reach; `browser-use-stagehand-native` requires a native model name and API key at schema validation with no configuration form on the page. @@ -22,4 +22,4 @@ An optional bundle is a runtime dependency of the installation, so its dependenc ## Consequences -The Official group grows from two to three entries, each tagged experimental by its experimental name. The runtime dependency closure of the installation is unchanged. A browser-use or computer-use provider still needs its Service Definition and the provider in a profile patch or composition. +The Official group grows from two to four entries, each tagged experimental by its experimental name. The runtime dependency closure of the installation is unchanged. A browser-use or computer-use provider still needs its Service Definition and the provider in a profile patch or composition. diff --git a/.agents/notes/implemented/architecture/2026-09-21-experimental-capabilities-as-optional-bundles.zh.md b/.agents/notes/implemented/architecture/2026-09-21-experimental-capabilities-as-optional-bundles.zh.md index 62e248e5ae..37df0d630a 100644 --- a/.agents/notes/implemented/architecture/2026-09-21-experimental-capabilities-as-optional-bundles.zh.md +++ b/.agents/notes/implemented/architecture/2026-09-21-experimental-capabilities-as-optional-bundles.zh.md @@ -10,7 +10,7 @@ Web 插件页只提供两个可选 bundle:Agent Teams 与语音输入。Auto r ## 决策 -`OPTIONAL_BUNDLES` 列出 Agent Teams、语音输入与 Auto review。每个可选 bundle 都声明 `icon` 并导出带 `meta.title` 与 `meta.description` 的 `./locale/*.json`,官方分组因此能渲染本地化标题、描述和图片;`verify-default-product-isolation` 会拒绝缺少这些声明的可选 bundle。Inspector 的 `cordis.patch.yml` 直接写包名而非构建产物路径,所以同一文件既是 bundle patch,也是已构建 Web 启动的 `--patch` overlay。 +`OPTIONAL_BUNDLES` 列出 Agent Teams、语音输入、Auto review 与 Schedule bundle。每个可选 bundle 都声明 `icon` 并导出带 `meta.title` 与 `meta.description` 的 `./locale/*.json`,官方分组因此能渲染本地化标题、描述和图片;`verify-default-product-isolation` 会拒绝缺少这些声明的可选 bundle。Inspector 的 `cordis.patch.yml` 直接写包名而非构建产物路径,所以同一文件既是 bundle patch,也是已构建 Web 启动的 `--patch` overlay。 可选 bundle 是安装的运行时依赖,其依赖图会随每次 `dsh` 安装一起下载。因此名单只接纳依赖图已在安装闭包内的包;Auto review 不增加任何依赖。Inspector 保留显式安装方式,不在默认插件列表中显示。浏览器操作与电脑操作提供方仍保持显式组合:Playwright MCP、Chrome DevTools MCP 与原生 Cua Driver 运行时二进制会让每次安装多出约 85 MB、21 个包,无论 bundle 是否启用;而随附的 Cua Driver MCP 开关会提供一个安装本身并不携带其可执行文件的能力。这些提供方包保留 locale 显示元数据,供组件行使用。另有两个包因其他原因不纳入:`ptc-runtime-python` 会替换 PTC 运行时,而 `workflow-ptc` 在加载时拒绝非 TypeScript 运行时,且 Web preset 内含 bundle patch 无法触及的 `workflow-ptc` 行;`browser-use-stagehand-native` 在 schema 校验时就要求原生模型名称与 API 密钥,而插件页没有对应的配置表单。 @@ -22,4 +22,4 @@ Web 插件页只提供两个可选 bundle:Agent Teams 与语音输入。Auto r ## 后果 -官方分组从两项增至三项,每项都因实验包名而带实验性标签。安装的运行时依赖闭包保持不变。浏览器操作或电脑操作提供方仍需在 profile patch 或组合中同时挂载其 Service Definition 与提供方。 +官方分组从两项增至四项,每项都因实验包名而带实验性标签。安装的运行时依赖闭包保持不变。浏览器操作或电脑操作提供方仍需在 profile patch 或组合中同时挂载其 Service Definition 与提供方。 diff --git a/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.i18n.yaml index 901bf1470d..a95cf939f3 100644 --- a/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.i18n.yaml @@ -6,14 +6,14 @@ en: 8c2381fd778a9888 zh: 8877255cb980eea1 /agent-note-schedule-as-an-opt-in-optional-bundle/problem: - en: 26d8e4f92b6cf3c5 - zh: 48dcb89bbb4a7169 + en: 2409ea3a006ea5d9 + zh: dbcda58a4c6b5b9f /agent-note-schedule-as-an-opt-in-optional-bundle/decision: - en: 5edbd3d4f9007745 - zh: e12eb39513bed213 + en: 360867ff77c6b727 + zh: 4eb4b47439c21d5d /agent-note-schedule-as-an-opt-in-optional-bundle/alternatives-considered: en: d12affa9097a1a50 zh: 4190d195c6a6eb8d /agent-note-schedule-as-an-opt-in-optional-bundle/consequences: - en: 00d9287c82256837 - zh: eb85623524e59b60 + en: 8ea1d9aaf25f1702 + zh: 32e721347ea55475 diff --git a/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.md b/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.md index b0c4eba715..4ea60cb9cd 100644 --- a/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.md +++ b/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.md @@ -6,7 +6,7 @@ English | [中文](2026-09-24-schedule-opt-in-optional-bundle.zh.md) ## Problem -The shipped Web composition mounted `time-context`, `schedule`, and `ui-schedule`, so every Web session carried four Schedule tool schemas and one durable clock message per eligible step whether or not the deployment wanted reminders. The rows had no switch on the product surface: a deployment that wanted them off edited its own profile patch layer, and the `--patch apps/cli/config/examples/schedule/cordis.yml` overlay could only switch them on from a launch flag. +`packages/bundle/web-app/cordis.patch.yml` inserts `time-context`, `schedule`, and `ui-schedule` with `disabled: true`, so the shipped Web composition exposes no Schedule surface: no `schedule_*` tools, no Session reminder catalog, no Automation tasks page, and no per-step clock reading. The rows have no switch on the product surface; a deployment that wants them edits a profile patch layer or passes a `--patch` overlay, and both are configuration files a person using the shipped Web profile cannot reach. ## Decision @@ -14,7 +14,7 @@ The shipped Web composition mounted `time-context`, `schedule`, and `ui-schedule `@deepseek-ai/dsh-experimental-schedule-bundle` (`packages/experimental/schedule-bundle/`) carries three id-targeted patches in its `cordis.patch.yml`, one per row, each setting `disabled: false`; it inserts no row. `OPTIONAL_BUNDLES` in `packages/boot/app-boot/src/profile.ts` names the package, and `apps/cli` declares it as a runtime dependency, so every installation ships it switched off. The [experimental-as-optional-bundles decision](2026-09-21-experimental-capabilities-as-optional-bundles.md) owns the `OPTIONAL_BUNDLES` conventions and the localized `icon` and `meta.title` / `meta.description` metadata the Web Plugins page renders in its Official group. -Enabling the bundle turns on `time-context` (a per-step clock reading with the sampled instant, the browser zone attached to the open request, and the elapsed time since the preceding model-visible message), `schedule` (durable reminders plus `schedule_create`, `schedule_list`, `schedule_update`, and `schedule_delete` on live root Agents), and `ui-schedule` (the Session reminder catalog and the Automation tasks page). The [Schedule subsystem](../../../../docs/subsystems/schedule.md) owns the durable records, delivery, and management operations; the [Web bundle](../../../../packages/bundle/web-app/README.md) owns the composition that carries the disabled rows. Disabling the bundle restores the shipped composition, and the Host stops scheduling while the `schedule` row stays disabled; stored task records remain in the Schedule domain. +Enabling the bundle turns on `time-context` (a per-step clock reading with the sampled instant, the browser zone attached to the open request, and the elapsed time since the preceding model-visible message), `schedule` (durable reminders plus `schedule_create`, `schedule_list`, `schedule_update`, and `schedule_delete` on live root Agents), and `ui-schedule` (the Session reminder catalog and the Automation tasks page). The bundle switches `time-context` on with `schedule` because a reminder request states a wall-clock target: the sampled instant is what lets the model turn a request such as "tomorrow at nine" into an offset-bearing `at` value. The [Schedule subsystem](../../../../docs/subsystems/schedule.md) owns the durable records, delivery, and management operations; the [Web bundle](../../../../packages/bundle/web-app/README.md) owns the composition that carries the disabled rows. Disabling the bundle restores the shipped composition, and the Host stops scheduling while the `schedule` row stays disabled; stored task records remain in the Schedule domain. ## Alternatives considered @@ -28,5 +28,5 @@ Enabling the bundle turns on `time-context` (a per-step clock reading with the s - A default `dsh web` session carries no Schedule tool schemas, no Session reminder catalog, no Automation tasks page, and no per-step clock reading. An installation that wants them enables the optional bundle from the Plugins page or lists the package in a profile's `dsh.profile.bundles`. - An enabled installation adds four tool schemas to every live root Agent and one durable clock message per eligible step; the reading is model-visible and durable, so it replays, compacts, and appears in exported Session logs like any other user message. -- The bundle changes nothing in a composition that does not carry the three Web rows, and its package declares no plugin dependency, so enabling it cannot mount a Host service twice. +- A composition that does not carry the three Web rows reports one `patch: entry not found` warning per patch and mounts nothing from this bundle, and its package declares no plugin dependency, so enabling it cannot mount a Host service twice. - The switch is configuration-only: `src/index.ts` is an empty module, the patch carries the runtime content, and the package owns no mutable runtime state, so it publishes no invariant companion. diff --git a/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.zh.md b/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.zh.md index 871bd7b52e..ed63f8e9c9 100644 --- a/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.zh.md +++ b/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.zh.md @@ -6,7 +6,7 @@ Status: implemented ## Problem -发布的 Web 组合挂载了 `time-context`、`schedule` 与 `ui-schedule`,因此每个 Web 会话都会带上四个 Schedule 工具 schema,并在每个符合条件的步骤追加一条持久时钟消息,无论该部署是否需要提醒。产品界面上没有开关:想要关闭它们的部署只能改自己的 profile patch 层,而 `--patch apps/cli/config/examples/schedule/cordis.yml` overlay 只能通过启动参数打开它们。 +`packages/bundle/web-app/cordis.patch.yml` 以 `disabled: true` 插入 `time-context`、`schedule` 与 `ui-schedule`,因此随发行版交付的 Web 组合不提供任何定时能力:没有 `schedule_*` 工具、没有 Session 提醒目录、没有自动化任务页面,也没有逐步时钟读数。这些条目在产品界面上没有开关;想要它们的部署要改 profile patch 层或传 `--patch` overlay,而两者都是使用随发行版 Web profile 的人无法触及的配置文件。 ## Decision @@ -14,7 +14,7 @@ Status: implemented `@deepseek-ai/dsh-experimental-schedule-bundle`(`packages/experimental/schedule-bundle/`)在其 `cordis.patch.yml` 中携带三个按 id 定位的 patch,每行一个,各自把 `disabled` 设为 `false`;它不插入任何行。`packages/boot/app-boot/src/profile.ts` 的 `OPTIONAL_BUNDLES` 列出该包,`apps/cli` 将其声明为运行时依赖,因此每次安装都随包携带且默认关闭。[实验性能力作为可选 bundle 的决策](2026-09-21-experimental-capabilities-as-optional-bundles.zh.md)负责 `OPTIONAL_BUNDLES` 的约定,以及 Web 插件管理页在 Official 分组中渲染的本地化 `icon` 与 `meta.title` / `meta.description` 元数据。 -启用该 bundle 会打开 `time-context`(每个步骤的时钟读数,包含采样瞬时、附加到当前开放请求的浏览器时区,以及自前一条模型可见消息以来的经过时长)、`schedule`(持久提醒,以及每个活跃根 Agent 上的 `schedule_create`、`schedule_list`、`schedule_update` 与 `schedule_delete`),以及 `ui-schedule`(Session 提醒目录与自动化任务页面)。持久记录、投递与管理操作由 [Schedule 子系统](../../../../docs/subsystems/schedule.zh.md)负责;承载这些禁用行的组合由 [Web bundle](../../../../packages/bundle/web-app/README.zh.md)负责。禁用该 bundle 会恢复随发行版交付的组合,`schedule` 行保持禁用期间 Host 不再调度;已存储的任务记录保留在 Schedule domain 中。 +启用该 bundle 会打开 `time-context`(每个步骤的时钟读数,包含采样瞬时、附加到当前开放请求的浏览器时区,以及自前一条模型可见消息以来的经过时长)、`schedule`(持久提醒,以及每个活跃根 Agent 上的 `schedule_create`、`schedule_list`、`schedule_update` 与 `schedule_delete`),以及 `ui-schedule`(Session 提醒目录与自动化任务页面)。该 bundle 把 `time-context` 与 `schedule` 一起打开,因为提醒请求给出的是挂钟时间目标:采样瞬时正是让模型把“明天九点”这类请求转换成带偏移量的 `at` 值的依据。持久记录、投递与管理操作由 [Schedule 子系统](../../../../docs/subsystems/schedule.zh.md)负责;承载这些禁用行的组合由 [Web bundle](../../../../packages/bundle/web-app/README.zh.md)负责。禁用该 bundle 会恢复随发行版交付的组合,`schedule` 行保持禁用期间 Host 不再调度;已存储的任务记录保留在 Schedule domain 中。 ## Alternatives considered @@ -28,5 +28,5 @@ Status: implemented - 默认的 `dsh web` 会话不带 Schedule 工具 schema、Session 提醒目录、自动化任务页面与逐步时钟读数。需要它们的安装可从插件管理页启用该可选 bundle,或把该包列进 profile 的 `dsh.profile.bundles`。 - 启用后的安装会给每个活跃根 Agent 增加四个工具 schema,并在每个符合条件的步骤追加一条持久时钟消息;该读数对模型可见且持久,因此它与其他 user 消息一样参与回放、压缩,并出现在导出的 Session 日志中。 -- 在不携带这三行 Web 行的组合中,该 bundle 不改变任何东西;其包不声明插件依赖,因此启用它不会重复挂载同一个 Host 服务。 +- 在不携带这三行 Web 行的组合中,该 bundle 的每个补丁都会报告一条 `patch: entry not found` 警告且不挂载任何东西;其包不声明插件依赖,因此启用它不会重复挂载同一个 Host 服务。 - 该开关只涉及配置:`src/index.ts` 是空模块,运行时内容由 patch 承载,包本身不拥有可变的运行时状态,因此不发布不变量伴随模块。 diff --git a/apps/cli/package.json b/apps/cli/package.json index 7e9fb3286b..3c84cff81a 100644 --- a/apps/cli/package.json +++ b/apps/cli/package.json @@ -38,8 +38,8 @@ "@deepseek-ai/dsh-compaction-basic": "workspace:*", "@deepseek-ai/dsh-compaction-tool-result-pruner": "workspace:*", "@deepseek-ai/dsh-cordis-client-runner": "workspace:*", - "@deepseek-ai/dsh-experimental-schedule-bundle": "workspace:*", "@deepseek-ai/dsh-experimental-agent-team-profile": "workspace:*", + "@deepseek-ai/dsh-experimental-schedule-bundle": "workspace:*", "@deepseek-ai/dsh-fs-local": "workspace:*", "@deepseek-ai/dsh-goal": "workspace:*", "@deepseek-ai/dsh-goal-round-driver": "workspace:*", diff --git a/packages/experimental/schedule-bundle/README.i18n.yaml b/packages/experimental/schedule-bundle/README.i18n.yaml index 98d86454bc..efbd18b82e 100644 --- a/packages/experimental/schedule-bundle/README.i18n.yaml +++ b/packages/experimental/schedule-bundle/README.i18n.yaml @@ -18,8 +18,8 @@ en: ffaa4b18e10a1df9 zh: b675fd8195ebb057 /deepseek-ai-dsh-experimental-schedule-bundle/understand-the-implementation: - en: 90beaeda691bd0a7 - zh: d81683d7bb1f6903 + en: 744024d71c8fca24 + zh: 22f939f9484e1ad7 /deepseek-ai-dsh-experimental-schedule-bundle/further-exploration: en: 99a29dddf9805540 zh: 13a6df3ee31abfc1 @@ -39,8 +39,8 @@ en: 0b01d8c40b422f5b zh: 57fede4db59a62b8 /deepseek-ai-dsh-experimental-schedule-bundle/known-limitations-and-deferred-work: - en: d733f4e0f983de86 - zh: 7ffb3d3fe7f77a7b + en: 6f2812ce847b2654 + zh: ac8ef109662f67c0 /deepseek-ai-dsh-experimental-schedule-bundle/known-limitations-and-deferred-work/dev-note: en: 0225ba087c5266f3 zh: 4e706f1b2b984e63 diff --git a/packages/experimental/schedule-bundle/README.md b/packages/experimental/schedule-bundle/README.md index 6e3abd4eea..7b8feb04ee 100644 --- a/packages/experimental/schedule-bundle/README.md +++ b/packages/experimental/schedule-bundle/README.md @@ -35,7 +35,7 @@ Open Plugins in the Web sidebar and enable Scheduling and time context, marked b
Maintainer details — click to expand -`cordis.patch.yml` carries three id-targeted patches, each setting `disabled: false` on a row the Web bundle already inserts. `OPTIONAL_BUNDLES` in `packages/boot/app-boot/src/profile.ts` names this package and `apps/cli` depends on it, so every installation ships it switched off and the plugin manager offers it in the Official group. Selecting it appends the bundle to the profile's `dsh.profile.bundles` list, and the profile launcher applies the bundle layers after the Web layer. No runtime invariant companion is published because this configuration-only package owns no mutable runtime state. +`cordis.patch.yml` carries three id-targeted patches, each setting `disabled: false` on a row the Web bundle already inserts. `OPTIONAL_BUNDLES` in `packages/boot/app-boot/src/profile.ts` names this package and `apps/cli` depends on it, so every installation ships it switched off and the plugin manager offers it in the Official group. Selecting it appends the bundle to the tail of the profile's `dsh.profile.bundles` list; bundle layers apply in list order, so the patches reach the rows only because that list places `@deepseek-ai/dsh-web-app` before this package. No runtime invariant companion is published because this configuration-only package owns no mutable runtime state. | File | Role | |---|---| @@ -78,8 +78,8 @@ The tool schemas change the request prefix once when the bundle mounts; each app -- The switch targets rows `@deepseek-ai/dsh-web-app` inserts. A profile without that bundle carries no such rows, so this bundle changes nothing there. -- Selecting the bundle adds the four Schedule tool schemas to every live root Agent and one clock reading per eligible step. A conversation that never creates a reminder still pays both costs. +- The switch targets rows `@deepseek-ai/dsh-web-app` inserts. In a profile without that bundle the three patches match no row: the loader reports one `patch: entry not found` warning per row and skips it, while the Plugins page still shows the switch as on. +- The bundle's detail page has no per-row switches. The Host reports the three overridden ids under `overrides`, and the Web client renders only the rows a bundle inserts, so opening this card shows "This plugin pack contains no components." The switches for the three rows are on the Official-group list row. ----- diff --git a/packages/experimental/schedule-bundle/README.zh.md b/packages/experimental/schedule-bundle/README.zh.md index 747137bc57..4201c46ad5 100644 --- a/packages/experimental/schedule-bundle/README.zh.md +++ b/packages/experimental/schedule-bundle/README.zh.md @@ -35,7 +35,7 @@ kind: "package-bundle"
维护者信息 — 点击展开 -`cordis.patch.yml` 包含三个按 id 定位的补丁,各自把 Web Bundle 已插入条目的 `disabled` 设为 `false`。`packages/boot/app-boot/src/profile.ts` 的 `OPTIONAL_BUNDLES` 列出此包,`apps/cli` 依赖它,因此每次安装都随包携带且默认禁用,插件管理页在 Official 分组中提供它。选中后会把该 Bundle 追加到 profile 的 `dsh.profile.bundles` 列表,profile 启动器在 Web 层之后应用各 Bundle 层。此纯配置包不拥有可变的运行时状态,因此不发布不变量伴随模块。 +`cordis.patch.yml` 包含三个按 id 定位的补丁,各自把 Web Bundle 已插入条目的 `disabled` 设为 `false`。`packages/boot/app-boot/src/profile.ts` 的 `OPTIONAL_BUNDLES` 列出此包,`apps/cli` 依赖它,因此每次安装都随包携带且默认禁用,插件管理页在 Official 分组中提供它。选中后会把该 Bundle 追加到 profile 的 `dsh.profile.bundles` 列表末尾;Bundle 层按列表顺序应用,因此这些补丁能命中条目,只是因为该列表把 `@deepseek-ai/dsh-web-app` 排在此包之前。此纯配置包不拥有可变的运行时状态,因此不发布不变量伴随模块。 | 文件 | 作用 | |---|---| @@ -78,8 +78,8 @@ kind: "package-bundle" -- 此开关针对 `@deepseek-ai/dsh-web-app` 插入的条目。没有该 Bundle 的 profile 不含这些条目,此 Bundle 在那里不产生变化。 -- 选中此 Bundle 会给每个活跃根智能体增加四个定时工具的 schema,并为每个符合条件的步骤增加一条时钟读数。即使对话从不创建提醒,也会承担这两项开销。 +- 此开关针对 `@deepseek-ai/dsh-web-app` 插入的条目。在没有该 Bundle 的 profile 中,三个补丁匹配不到任何条目:加载器为每个条目报告一条 `patch: entry not found` 警告并跳过它,而插件管理页仍把该开关显示为已启用。 +- 该 Bundle 的详情页没有逐条目开关。Host 把被覆盖的三个 id 报告在 `overrides` 下,而 Web 客户端只渲染 Bundle 插入的条目,因此打开这张卡片会显示“这个插件包不包含任何组件。”。三个条目的开关在 Official 分组列表行上。 ----- diff --git a/scripts/optional-bundles.spec.ts b/scripts/optional-bundles.spec.ts index 71671e5b71..9218b4ed98 100644 --- a/scripts/optional-bundles.spec.ts +++ b/scripts/optional-bundles.spec.ts @@ -41,13 +41,34 @@ describe('optional bundles', () => { it.each(OPTIONAL_BUNDLES)('%s composes over the Web profile without a skipped patch', (name) => { const { patches } = bundle(name) const warnings: string[] = [] - const ids = new Set(composeEntries([...shipped, patches], message => warnings.push(message)).map(entry => entry.id)) + const composed = composeEntries([...shipped, patches], message => warnings.push(message)) + const ids = new Set(composed.map(entry => entry.id)) expect(warnings).toEqual([]) // Inserted rows carry stable ids at the profile root, so a later profile patch can configure or disable them. for (const row of patches.flatMap(patch => patch.insert ?? [])) { expect(typeof row.id).toBe('string') expect(ids.has(row.id)).toBe(true) } + // An id-targeted patch reaches a row another layer inserted: the composed row keeps that row's package + // name, appears once, and carries the patched values. + for (const patch of patches) { + if (patch.insert !== undefined || typeof patch.id !== 'string') continue + const matches = composed.filter(entry => entry.id === patch.id) + expect(matches).toHaveLength(1) + expect(matches[0]).toMatchObject({ ...patch }) + expect(typeof matches[0]?.name).toBe('string') + } + }) + + it('composes the Schedule bundle over the three shipped Web rows', () => { + const { patches } = bundle('@deepseek-ai/dsh-experimental-schedule-bundle') + const composed = composeEntries([...shipped, patches]) + expect(composed.filter(entry => entry.id === 'time-context' || entry.id === 'schedule' || entry.id === 'ui-schedule')) + .toMatchObject([ + { id: 'time-context', name: '@deepseek-ai/dsh-time-context', disabled: false }, + { id: 'schedule', name: '@deepseek-ai/dsh-schedule', disabled: false }, + { id: 'ui-schedule', name: '@deepseek-ai/dsh-client-ui-schedule', disabled: false }, + ]) }) it.each(OPTIONAL_BUNDLES)('%s resolves a title, description, and icon in both shipped languages', (name) => { From 1065f0afd17ca2ad8cc215aeed8d5436a0fcedf9 Mon Sep 17 00:00:00 2001 From: Chinesezjc Date: Fri, 25 Sep 2026 15:12:14 +0800 Subject: [PATCH 5/9] fix(schedule-bundle): correct review findings on row semantics and the archived note Cross-link the archived decision the opt-in note supersedes, state the Loader's one entry per id and last-declaration-wins behavior in the overlay and extraction alternatives, scope the missing-row warning to profiles that mount no Plugins page, and move the switch-on-but-ineffective case to the list-order paragraph. Assert one top-level composed row per id and correct the stale assembled-remote comment. --- ...perimental-capabilities-as-optional-bundles.i18n.yaml | 4 ++-- ...9-21-experimental-capabilities-as-optional-bundles.md | 2 +- ...1-experimental-capabilities-as-optional-bundles.zh.md | 2 +- .../2026-09-24-schedule-opt-in-optional-bundle.i18n.yaml | 8 ++++---- .../2026-09-24-schedule-opt-in-optional-bundle.md | 6 ++++-- .../2026-09-24-schedule-opt-in-optional-bundle.zh.md | 6 ++++-- apps/web/tests/assembled-remote.ts | 5 +++-- packages/experimental/schedule-bundle/README.i18n.yaml | 8 ++++---- packages/experimental/schedule-bundle/README.md | 6 +++--- packages/experimental/schedule-bundle/README.zh.md | 6 +++--- scripts/optional-bundles.spec.ts | 9 ++++++--- 11 files changed, 35 insertions(+), 27 deletions(-) diff --git a/.agents/notes/implemented/architecture/2026-09-21-experimental-capabilities-as-optional-bundles.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-21-experimental-capabilities-as-optional-bundles.i18n.yaml index 87aa04a960..521567dd7e 100644 --- a/.agents/notes/implemented/architecture/2026-09-21-experimental-capabilities-as-optional-bundles.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-21-experimental-capabilities-as-optional-bundles.i18n.yaml @@ -15,5 +15,5 @@ en: a65d84004e48b3ef zh: 17221f08e7a8a89b /agent-note-ship-experimental-capabilities-as-optional-bundles/consequences: - en: 71482af50ad31d54 - zh: 12d4849104842f0d + en: e7fb2a93a89ba9b6 + zh: 37ed9f0a3ca44583 diff --git a/.agents/notes/implemented/architecture/2026-09-21-experimental-capabilities-as-optional-bundles.md b/.agents/notes/implemented/architecture/2026-09-21-experimental-capabilities-as-optional-bundles.md index 48d3fee0bb..b7139f6d9a 100644 --- a/.agents/notes/implemented/architecture/2026-09-21-experimental-capabilities-as-optional-bundles.md +++ b/.agents/notes/implemented/architecture/2026-09-21-experimental-capabilities-as-optional-bundles.md @@ -22,4 +22,4 @@ An optional bundle is a runtime dependency of the installation, so its dependenc ## Consequences -The Official group grows from two to four entries, each tagged experimental by its experimental name. The runtime dependency closure of the installation is unchanged. A browser-use or computer-use provider still needs its Service Definition and the provider in a profile patch or composition. +The Official group carries four optional-bundle entries, each tagged experimental by its experimental name. The runtime dependency closure of the installation is unchanged. A browser-use or computer-use provider still needs its Service Definition and the provider in a profile patch or composition. diff --git a/.agents/notes/implemented/architecture/2026-09-21-experimental-capabilities-as-optional-bundles.zh.md b/.agents/notes/implemented/architecture/2026-09-21-experimental-capabilities-as-optional-bundles.zh.md index 37df0d630a..af4048bc5e 100644 --- a/.agents/notes/implemented/architecture/2026-09-21-experimental-capabilities-as-optional-bundles.zh.md +++ b/.agents/notes/implemented/architecture/2026-09-21-experimental-capabilities-as-optional-bundles.zh.md @@ -22,4 +22,4 @@ Web 插件页只提供两个可选 bundle:Agent Teams 与语音输入。Auto r ## 后果 -官方分组从两项增至四项,每项都因实验包名而带实验性标签。安装的运行时依赖闭包保持不变。浏览器操作或电脑操作提供方仍需在 profile patch 或组合中同时挂载其 Service Definition 与提供方。 +官方分组包含四个可选 bundle 条目,每项都因实验包名而带实验性标签。安装的运行时依赖闭包保持不变。浏览器操作或电脑操作提供方仍需在 profile patch 或组合中同时挂载其 Service Definition 与提供方。 diff --git a/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.i18n.yaml index a95cf939f3..4cc0c9b59b 100644 --- a/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.i18n.yaml @@ -3,8 +3,8 @@ # After editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.md /agent-note-schedule-as-an-opt-in-optional-bundle: - en: 8c2381fd778a9888 - zh: 8877255cb980eea1 + en: d234bf064c5990f1 + zh: c54b941429b4658c /agent-note-schedule-as-an-opt-in-optional-bundle/problem: en: 2409ea3a006ea5d9 zh: dbcda58a4c6b5b9f @@ -12,8 +12,8 @@ en: 360867ff77c6b727 zh: 4eb4b47439c21d5d /agent-note-schedule-as-an-opt-in-optional-bundle/alternatives-considered: - en: d12affa9097a1a50 - zh: 4190d195c6a6eb8d + en: cef562365cc8ab3a + zh: 2d43ba5839b97474 /agent-note-schedule-as-an-opt-in-optional-bundle/consequences: en: 8ea1d9aaf25f1702 zh: 32e721347ea55475 diff --git a/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.md b/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.md index 4ea60cb9cd..c06bd25549 100644 --- a/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.md +++ b/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.md @@ -4,6 +4,8 @@ Status: implemented English | [中文](2026-09-24-schedule-opt-in-optional-bundle.zh.md) +> Supersedes [Schedule in the shipped Web composition](../../archived/architecture/2026-09-24-web-default-schedule-composition.md): the three rows now ship disabled, and switching them on is this bundle's job. + ## Problem `packages/bundle/web-app/cordis.patch.yml` inserts `time-context`, `schedule`, and `ui-schedule` with `disabled: true`, so the shipped Web composition exposes no Schedule surface: no `schedule_*` tools, no Session reminder catalog, no Automation tasks page, and no per-step clock reading. The rows have no switch on the product surface; a deployment that wants them edits a profile patch layer or passes a `--patch` overlay, and both are configuration files a person using the shipped Web profile cannot reach. @@ -20,9 +22,9 @@ Enabling the bundle turns on `time-context` (a per-step clock reading with the s **Ship Schedule on by default.** Every Web session then pays four tool schemas in each request header and one durable user message per eligible step, and a conversation that never creates a reminder pays both costs. The arrangement also left the capability without an off switch on the product surface. -**Keep a `--patch` overlay file.** An overlay is a launch-time argument rather than a product-surface switch, so a person using the shipped Web profile cannot reach it. It cannot re-insert the rows either: `applyEntryPatches` appends an `insert` list without de-duplicating ids, so an overlay that inserts `time-context` and `schedule` mounts each Host plugin a second time. +**Keep a `--patch` overlay file.** An overlay is a launch-time argument rather than a product-surface switch, so a person using the shipped Web profile cannot reach it. It also cannot set fields on the shipped rows: `applyEntryPatches` appends an `insert` list without de-duplicating ids, and the Loader keeps one entry per id with the last declaration winning, so an overlay that re-declares `time-context` and `schedule` replaces the Web bundle's rows instead of overriding them. -**Extract the three rows out of the Web composition into the bundle.** The bundle would insert the rows instead of overriding them, so any profile that also inserts a row would mount the same Host plugin twice for the same reason. The disabled rows are what an override-style switch targets. +**Extract the three rows out of the Web composition into the bundle.** The bundle would insert the rows instead of overriding them, so a profile that also declares one of those ids would have two declarations for it, of which the Loader keeps only the last. The disabled rows are what an override-style switch targets. ## Consequences diff --git a/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.zh.md b/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.zh.md index ed63f8e9c9..4a92067a46 100644 --- a/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.zh.md +++ b/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.zh.md @@ -4,6 +4,8 @@ Status: implemented [English](2026-09-24-schedule-opt-in-optional-bundle.md) | 中文 +> 取代[默认 Web 组合中的 Schedule](../../archived/architecture/2026-09-24-web-default-schedule-composition.md):这三行现在默认禁用,打开它们是此 bundle 的职责。 + ## Problem `packages/bundle/web-app/cordis.patch.yml` 以 `disabled: true` 插入 `time-context`、`schedule` 与 `ui-schedule`,因此随发行版交付的 Web 组合不提供任何定时能力:没有 `schedule_*` 工具、没有 Session 提醒目录、没有自动化任务页面,也没有逐步时钟读数。这些条目在产品界面上没有开关;想要它们的部署要改 profile patch 层或传 `--patch` overlay,而两者都是使用随发行版 Web profile 的人无法触及的配置文件。 @@ -20,9 +22,9 @@ Status: implemented **默认发布 Schedule。** 那样每个 Web 会话都要在每个请求头中带上四个工具 schema,并在每个符合条件的步骤追加一条持久 user 消息,从不创建提醒的对话也要承担这两项成本。这种安排还让该能力在产品界面上没有关闭开关。 -**保留一个 `--patch` overlay 文件。** overlay 是启动时的参数,而不是产品界面上的开关,因此使用随发行版 `web` profile 的人无法触及它。它也无法重新插入这些行:`applyEntryPatches` 追加 `insert` 列表时不对 id 去重,插入 `time-context` 与 `schedule` 的 overlay 会把每个 Host 插件挂载两次。 +**保留一个 `--patch` overlay 文件。** overlay 是启动时的参数,而不是产品界面上的开关,因此使用随发行版 `web` profile 的人无法触及它。它也无法给出厂条目设值:`applyEntryPatches` 追加 `insert` 列表时不对 id 去重,而 Loader 每个 id 只保留一个条目、最后一个声明生效,因此重新声明 `time-context` 与 `schedule` 的 overlay 会替换 Web Bundle 的条目,而不是覆盖它们。 -**把这三行从 Web 组合中抽出、移入 bundle。** 这样 bundle 会插入这些行而不是覆盖它们,任何同样插入某行的 profile 都会因同样的原因把同一个 Host 插件挂载两次。按需开关针对的正是这些禁用行。 +**把这三行从 Web 组合中抽出、移入 bundle。** 这样 bundle 会插入这些行而不是覆盖它们;某个 profile 若也声明了这些 id,同一个 id 就会有两份声明,而 Loader 只保留最后一份。按需开关针对的正是这些禁用行。 ## Consequences diff --git a/apps/web/tests/assembled-remote.ts b/apps/web/tests/assembled-remote.ts index 7569106fc6..192feb1142 100644 --- a/apps/web/tests/assembled-remote.ts +++ b/apps/web/tests/assembled-remote.ts @@ -223,8 +223,9 @@ export function createAssembledRemote(options: AssembledRemoteOptions = {}): Ass return ok(undefined) }) mock.unary('session/list', () => ok({ items: structuredClone(sessions) })) - // The shipped Web composition mounts the Schedule client, whose catalog and - // per-Session list read empty here: these scenarios drive no reminder. + // The shipped bundle layers this graph composes carry the `ui-schedule` row + // disabled, so the Schedule client does not mount and no case here reads the + // catalog or the per-Session list; both stay declared empty. mock.unary('schedule/catalog', () => ok([])) mock.unary('schedule/list', () => ok([])) mock.unary('session/projections', (request: unknown) => { diff --git a/packages/experimental/schedule-bundle/README.i18n.yaml b/packages/experimental/schedule-bundle/README.i18n.yaml index efbd18b82e..c05ec3e55b 100644 --- a/packages/experimental/schedule-bundle/README.i18n.yaml +++ b/packages/experimental/schedule-bundle/README.i18n.yaml @@ -18,8 +18,8 @@ en: ffaa4b18e10a1df9 zh: b675fd8195ebb057 /deepseek-ai-dsh-experimental-schedule-bundle/understand-the-implementation: - en: 744024d71c8fca24 - zh: 22f939f9484e1ad7 + en: b17882af7c7eaf2c + zh: bfc71d0152557af5 /deepseek-ai-dsh-experimental-schedule-bundle/further-exploration: en: 99a29dddf9805540 zh: 13a6df3ee31abfc1 @@ -39,8 +39,8 @@ en: 0b01d8c40b422f5b zh: 57fede4db59a62b8 /deepseek-ai-dsh-experimental-schedule-bundle/known-limitations-and-deferred-work: - en: 6f2812ce847b2654 - zh: ac8ef109662f67c0 + en: a4a2674fb3c5a101 + zh: cb4c54ba37730708 /deepseek-ai-dsh-experimental-schedule-bundle/known-limitations-and-deferred-work/dev-note: en: 0225ba087c5266f3 zh: 4e706f1b2b984e63 diff --git a/packages/experimental/schedule-bundle/README.md b/packages/experimental/schedule-bundle/README.md index 7b8feb04ee..02c0e1740f 100644 --- a/packages/experimental/schedule-bundle/README.md +++ b/packages/experimental/schedule-bundle/README.md @@ -35,7 +35,7 @@ Open Plugins in the Web sidebar and enable Scheduling and time context, marked b
Maintainer details — click to expand -`cordis.patch.yml` carries three id-targeted patches, each setting `disabled: false` on a row the Web bundle already inserts. `OPTIONAL_BUNDLES` in `packages/boot/app-boot/src/profile.ts` names this package and `apps/cli` depends on it, so every installation ships it switched off and the plugin manager offers it in the Official group. Selecting it appends the bundle to the tail of the profile's `dsh.profile.bundles` list; bundle layers apply in list order, so the patches reach the rows only because that list places `@deepseek-ai/dsh-web-app` before this package. No runtime invariant companion is published because this configuration-only package owns no mutable runtime state. +`cordis.patch.yml` carries three id-targeted patches, each setting `disabled: false` on a row the Web bundle already inserts. `OPTIONAL_BUNDLES` in `packages/boot/app-boot/src/profile.ts` names this package and `apps/cli` depends on it, so every installation ships it switched off and the plugin manager offers it in the Official group. Selecting it appends the bundle to the tail of the profile's `dsh.profile.bundles` list; bundle layers apply in list order, so the patches reach the rows only because that list places `@deepseek-ai/dsh-web-app` before this package. A hand-ordered list with this package first leaves the rows disabled while the Plugins page still shows the switch as on. No runtime invariant companion is published because this configuration-only package owns no mutable runtime state. | File | Role | |---|---| @@ -78,8 +78,8 @@ The tool schemas change the request prefix once when the bundle mounts; each app -- The switch targets rows `@deepseek-ai/dsh-web-app` inserts. In a profile without that bundle the three patches match no row: the loader reports one `patch: entry not found` warning per row and skips it, while the Plugins page still shows the switch as on. -- The bundle's detail page has no per-row switches. The Host reports the three overridden ids under `overrides`, and the Web client renders only the rows a bundle inserts, so opening this card shows "This plugin pack contains no components." The switches for the three rows are on the Official-group list row. +- The switch targets rows `@deepseek-ai/dsh-web-app` inserts. In a profile without that bundle the three patches match no row: the loader reports one `patch: entry not found` warning per row and mounts nothing from this bundle; such a profile mounts no Plugins page either. +- The bundle's detail page has no per-row switches. The Host reports the three overridden ids under `overrides`, and the Web client renders only the rows a bundle inserts, so opening this card shows "This plugin pack contains no components." The switch for the three rows is on the Official-group list row. ----- diff --git a/packages/experimental/schedule-bundle/README.zh.md b/packages/experimental/schedule-bundle/README.zh.md index 4201c46ad5..f28a2466ce 100644 --- a/packages/experimental/schedule-bundle/README.zh.md +++ b/packages/experimental/schedule-bundle/README.zh.md @@ -35,7 +35,7 @@ kind: "package-bundle"
维护者信息 — 点击展开 -`cordis.patch.yml` 包含三个按 id 定位的补丁,各自把 Web Bundle 已插入条目的 `disabled` 设为 `false`。`packages/boot/app-boot/src/profile.ts` 的 `OPTIONAL_BUNDLES` 列出此包,`apps/cli` 依赖它,因此每次安装都随包携带且默认禁用,插件管理页在 Official 分组中提供它。选中后会把该 Bundle 追加到 profile 的 `dsh.profile.bundles` 列表末尾;Bundle 层按列表顺序应用,因此这些补丁能命中条目,只是因为该列表把 `@deepseek-ai/dsh-web-app` 排在此包之前。此纯配置包不拥有可变的运行时状态,因此不发布不变量伴随模块。 +`cordis.patch.yml` 包含三个按 id 定位的补丁,各自把 Web Bundle 已插入条目的 `disabled` 设为 `false`。`packages/boot/app-boot/src/profile.ts` 的 `OPTIONAL_BUNDLES` 列出此包,`apps/cli` 依赖它,因此每次安装都随包携带且默认禁用,插件管理页在 Official 分组中提供它。选中后会把该 Bundle 追加到 profile 的 `dsh.profile.bundles` 列表末尾;Bundle 层按列表顺序应用,因此这些补丁能命中条目,只是因为该列表把 `@deepseek-ai/dsh-web-app` 排在此包之前。手写顺序把此包排在最前时,这些条目保持禁用,而插件管理页仍把该开关显示为已启用。此纯配置包不拥有可变的运行时状态,因此不发布不变量伴随模块。 | 文件 | 作用 | |---|---| @@ -78,8 +78,8 @@ kind: "package-bundle" -- 此开关针对 `@deepseek-ai/dsh-web-app` 插入的条目。在没有该 Bundle 的 profile 中,三个补丁匹配不到任何条目:加载器为每个条目报告一条 `patch: entry not found` 警告并跳过它,而插件管理页仍把该开关显示为已启用。 -- 该 Bundle 的详情页没有逐条目开关。Host 把被覆盖的三个 id 报告在 `overrides` 下,而 Web 客户端只渲染 Bundle 插入的条目,因此打开这张卡片会显示“这个插件包不包含任何组件。”。三个条目的开关在 Official 分组列表行上。 +- 此开关针对 `@deepseek-ai/dsh-web-app` 插入的条目。在没有该 Bundle 的 profile 中,三个补丁匹配不到任何条目:加载器为每个条目报告一条 `patch: entry not found` 警告,且不从该 Bundle 挂载任何东西;这样的 profile 也不挂载插件管理页。 +- 该 Bundle 的详情页没有逐条目开关。Host 把被覆盖的三个 id 报告在 `overrides` 下,而 Web 客户端只渲染 Bundle 插入的条目,因此打开这张卡片会显示“这个插件包不包含任何组件。”。控制这三个条目的开关在 Official 分组列表行上。 ----- diff --git a/scripts/optional-bundles.spec.ts b/scripts/optional-bundles.spec.ts index 9218b4ed98..aa7c1b9dd4 100644 --- a/scripts/optional-bundles.spec.ts +++ b/scripts/optional-bundles.spec.ts @@ -49,13 +49,16 @@ describe('optional bundles', () => { expect(typeof row.id).toBe('string') expect(ids.has(row.id)).toBe(true) } - // An id-targeted patch reaches a row another layer inserted: the composed row keeps that row's package - // name, appears once, and carries the patched values. + // One top-level row per id: a duplicate declaration leaves the Loader with the last one, silently + // replacing the layer that declared the id first. + const topLevelIds = composed.flatMap(entry => typeof entry.id === 'string' ? [entry.id] : []) + expect(topLevelIds).toHaveLength(new Set(topLevelIds).size) + // An id-targeted patch reaches a row another layer inserted: the id resolves to exactly one top-level + // row that keeps its declared package name. for (const patch of patches) { if (patch.insert !== undefined || typeof patch.id !== 'string') continue const matches = composed.filter(entry => entry.id === patch.id) expect(matches).toHaveLength(1) - expect(matches[0]).toMatchObject({ ...patch }) expect(typeof matches[0]?.name).toBe('string') } }) From 7b3bc172dedcde2f9a66b39f8d4e2d4ad16d86c0 Mon Sep 17 00:00:00 2001 From: Chinesezjc Date: Fri, 25 Sep 2026 15:18:31 +0800 Subject: [PATCH 6/9] docs(schedule-bundle): scope the overlay limitation and pin the overridden row name The overlay alternative now says only its insert form fails to override a shipped row, since an id-targeted --patch overlay does set one. The composed assertion compares the overridden row's package name with the shipped layer's name instead of asserting a string. --- .../2026-09-24-schedule-opt-in-optional-bundle.i18n.yaml | 4 ++-- .../2026-09-24-schedule-opt-in-optional-bundle.md | 2 +- .../2026-09-24-schedule-opt-in-optional-bundle.zh.md | 2 +- scripts/optional-bundles.spec.ts | 5 +++-- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.i18n.yaml index 4cc0c9b59b..614307e4b2 100644 --- a/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.i18n.yaml @@ -12,8 +12,8 @@ en: 360867ff77c6b727 zh: 4eb4b47439c21d5d /agent-note-schedule-as-an-opt-in-optional-bundle/alternatives-considered: - en: cef562365cc8ab3a - zh: 2d43ba5839b97474 + en: 1782c8ecdbe6bf87 + zh: dd6997d067257562 /agent-note-schedule-as-an-opt-in-optional-bundle/consequences: en: 8ea1d9aaf25f1702 zh: 32e721347ea55475 diff --git a/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.md b/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.md index c06bd25549..09bca841cf 100644 --- a/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.md +++ b/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.md @@ -22,7 +22,7 @@ Enabling the bundle turns on `time-context` (a per-step clock reading with the s **Ship Schedule on by default.** Every Web session then pays four tool schemas in each request header and one durable user message per eligible step, and a conversation that never creates a reminder pays both costs. The arrangement also left the capability without an off switch on the product surface. -**Keep a `--patch` overlay file.** An overlay is a launch-time argument rather than a product-surface switch, so a person using the shipped Web profile cannot reach it. It also cannot set fields on the shipped rows: `applyEntryPatches` appends an `insert` list without de-duplicating ids, and the Loader keeps one entry per id with the last declaration winning, so an overlay that re-declares `time-context` and `schedule` replaces the Web bundle's rows instead of overriding them. +**Keep a `--patch` overlay file.** An overlay is a launch-time argument rather than a product-surface switch, so a person using the shipped Web profile cannot reach it. Re-declaring the rows through its `insert` list does not override them: `applyEntryPatches` appends that list without de-duplicating ids, and the Loader collapses the composed list to one entry per id with the last declaration winning, so the overlay replaces the Web bundle's rows instead of setting fields on them. **Extract the three rows out of the Web composition into the bundle.** The bundle would insert the rows instead of overriding them, so a profile that also declares one of those ids would have two declarations for it, of which the Loader keeps only the last. The disabled rows are what an override-style switch targets. diff --git a/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.zh.md b/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.zh.md index 4a92067a46..ed22c1ab08 100644 --- a/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.zh.md +++ b/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.zh.md @@ -22,7 +22,7 @@ Status: implemented **默认发布 Schedule。** 那样每个 Web 会话都要在每个请求头中带上四个工具 schema,并在每个符合条件的步骤追加一条持久 user 消息,从不创建提醒的对话也要承担这两项成本。这种安排还让该能力在产品界面上没有关闭开关。 -**保留一个 `--patch` overlay 文件。** overlay 是启动时的参数,而不是产品界面上的开关,因此使用随发行版 `web` profile 的人无法触及它。它也无法给出厂条目设值:`applyEntryPatches` 追加 `insert` 列表时不对 id 去重,而 Loader 每个 id 只保留一个条目、最后一个声明生效,因此重新声明 `time-context` 与 `schedule` 的 overlay 会替换 Web Bundle 的条目,而不是覆盖它们。 +**保留一个 `--patch` overlay 文件。** overlay 是启动时的参数,而不是产品界面上的开关,因此使用随发行版 `web` profile 的人无法触及它。通过它的 `insert` 列表重新声明这些条目并不能覆盖它们:`applyEntryPatches` 追加该列表时不对 id 去重,而 Loader 会把组合出的列表按 id 收敛为一个条目、最后一个声明生效,因此该 overlay 会替换 Web Bundle 的条目,而不是给它们设值。 **把这三行从 Web 组合中抽出、移入 bundle。** 这样 bundle 会插入这些行而不是覆盖它们;某个 profile 若也声明了这些 id,同一个 id 就会有两份声明,而 Loader 只保留最后一份。按需开关针对的正是这些禁用行。 diff --git a/scripts/optional-bundles.spec.ts b/scripts/optional-bundles.spec.ts index aa7c1b9dd4..3158b7a0fb 100644 --- a/scripts/optional-bundles.spec.ts +++ b/scripts/optional-bundles.spec.ts @@ -54,12 +54,13 @@ describe('optional bundles', () => { const topLevelIds = composed.flatMap(entry => typeof entry.id === 'string' ? [entry.id] : []) expect(topLevelIds).toHaveLength(new Set(topLevelIds).size) // An id-targeted patch reaches a row another layer inserted: the id resolves to exactly one top-level - // row that keeps its declared package name. + // row, and the override keeps the package the shipped layer declared on it. + const shippedComposed = composeEntries([...shipped]) for (const patch of patches) { if (patch.insert !== undefined || typeof patch.id !== 'string') continue const matches = composed.filter(entry => entry.id === patch.id) expect(matches).toHaveLength(1) - expect(typeof matches[0]?.name).toBe('string') + expect(matches[0]?.name).toBe(shippedComposed.find(entry => entry.id === patch.id)?.name) } }) From e3a36cfe8024fc28f3ca1378c99798f55de2ad8c Mon Sep 17 00:00:00 2001 From: Chinesezjc Date: Fri, 25 Sep 2026 15:29:39 +0800 Subject: [PATCH 7/9] docs(schedule-bundle): keep the host-storage note current and trim the restated decision The 2026-09-16 host-schedule-storage note now names the optional experimental bundle as what mounts Schedule, since the Web composition carries the row disabled. The opt-in note's Decision drops the sentence the Problem already owns, and the assembled-remote mock states why its Schedule answers stay declared. --- .../architecture/2026-09-16-host-schedule-storage.i18n.yaml | 4 ++-- .../architecture/2026-09-16-host-schedule-storage.md | 2 +- .../architecture/2026-09-16-host-schedule-storage.zh.md | 2 +- .../2026-09-24-schedule-opt-in-optional-bundle.i18n.yaml | 4 ++-- .../2026-09-24-schedule-opt-in-optional-bundle.md | 2 +- .../2026-09-24-schedule-opt-in-optional-bundle.zh.md | 2 +- apps/web/tests/assembled-remote.ts | 3 ++- 7 files changed, 10 insertions(+), 9 deletions(-) diff --git a/.agents/notes/implemented/architecture/2026-09-16-host-schedule-storage.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-16-host-schedule-storage.i18n.yaml index 159fee0bf9..8bc4eaeaa5 100644 --- a/.agents/notes/implemented/architecture/2026-09-16-host-schedule-storage.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-16-host-schedule-storage.i18n.yaml @@ -15,5 +15,5 @@ en: 21d7ec9a9ff3cbf2 zh: 93d03b8b3012aa7e /agent-note-host-owned-scheduled-messages/consequences: - en: 0358aab730e4bf56 - zh: 61e89e0374891f8a + en: a48f13f89a1944b1 + zh: f8fa677122ce2e12 diff --git a/.agents/notes/implemented/architecture/2026-09-16-host-schedule-storage.md b/.agents/notes/implemented/architecture/2026-09-16-host-schedule-storage.md index 79a4f72071..3d90e8ad7e 100644 --- a/.agents/notes/implemented/architecture/2026-09-16-host-schedule-storage.md +++ b/.agents/notes/implemented/architecture/2026-09-16-host-schedule-storage.md @@ -58,7 +58,7 @@ Session inbox persistence and the task put occur in separate persistence systems **Keep the mock's hourly choice out of the stored vocabulary.** The approved mock lists 每小时整点 beside the daily, weekly and one-shot choices. Hourly and fixed-rate intervals are the same elapsed-time rule, so the card maps that menu slot onto the existing interval kind instead of adding a persisted kind. A dedicated hourly kind would need a new durable variant, its decoder, its target resolution, and its tool schema, all to express what an interval already expresses. -Task discovery and timers do not depend on loaded Sessions. The after, absolute-time, and fixed-rate selectors retain their semantics alongside Daily, Weekly, and Cron; reading existing saved tasks does not rewrite them. The Host must have its ordinary Session persistence and recovery services available, and the Web bundle mounts Schedule in its host row list. Explicit deletion stops future delivery and removes the task from `list` and `catalog` without deleting conversation messages; the removed row takes its saved receipts with it. History is pruned to the configured window and record cap when an acknowledgment is appended, loaded into Host memory, and rewritten with the task on each acknowledgment. Pagination limits the returned record count; the plugin configuration (`deliveryHistoryDays`, default 30, and `deliveryHistoryRecords`, default 200) limits storage growth. Earlier overwritten receipts and deliveries whose task write failed cannot be reconstructed. Pause and execution-history operations remain unsupported. +Task discovery and timers do not depend on loaded Sessions. The after, absolute-time, and fixed-rate selectors retain their semantics alongside Daily, Weekly, and Cron; reading existing saved tasks does not rewrite them. The Host must have its ordinary Session persistence and recovery services available, and enabling the optional experimental bundle `@deepseek-ai/dsh-experimental-schedule-bundle` mounts Schedule; the Web composition carries its row disabled. Explicit deletion stops future delivery and removes the task from `list` and `catalog` without deleting conversation messages; the removed row takes its saved receipts with it. History is pruned to the configured window and record cap when an acknowledgment is appended, loaded into Host memory, and rewritten with the task on each acknowledgment. Pagination limits the returned record count; the plugin configuration (`deliveryHistoryDays`, default 30, and `deliveryHistoryRecords`, default 200) limits storage growth. Earlier overwritten receipts and deliveries whose task write failed cannot be reconstructed. Pause and execution-history operations remain unsupported. Required coverage includes startup from stored tasks, missing-status normalization, cold Session restoration, latest-only catch-up, inactive-task retention without repeat dispatch, real message receipts, deletion across restart, removal of a deleted task's saved deliveries, queue/persistence failures, and disposal. Wall-clock obligations include gaps and skipped dates, earlier-only overlaps, fractional seconds, UTC-range edges, committed-target and alias preservation, and post-restoration clock rollback. Weekly adds weekday normalization and validation, next-target selection across a gap and an overlap, and stored set preservation. Historical decoders must reject Daily, Weekly, and Cron while Host storage accepts them. Client coverage includes every recurring kind, exact rule time, zone, and weekday set, All/Enabled/Inactive status filters, retained inactive details and original-Session navigation, authoritative refresh after confirmed deletion and notification, empty lists, reconnect, and late responses. Presentation coverage includes the page's New action starting a Session, the transcript card's narrowing of persisted result JSON including an incomplete or replayed result, the header clock's direct open for exactly one task and its count label, the idle-only row mark with the hover-card two-task limit and omission line. History coverage includes legacy byte preservation, append and restart, immutable sent instructions, strict latest-receipt consistency, stable cursor pagination, binding checks, failed persistence, and late page replies during refresh or task changes. Cross-store crash duplication remains an explicit limitation rather than a completion claim. diff --git a/.agents/notes/implemented/architecture/2026-09-16-host-schedule-storage.zh.md b/.agents/notes/implemented/architecture/2026-09-16-host-schedule-storage.zh.md index 393a773fa0..f7b9a8f889 100644 --- a/.agents/notes/implemented/architecture/2026-09-16-host-schedule-storage.zh.md +++ b/.agents/notes/implemented/architecture/2026-09-16-host-schedule-storage.zh.md @@ -58,7 +58,7 @@ Session 收件箱持久化和任务 put 发生在两个持久化系统中。收 **不把 mock 的「每小时整点」引入持久词表。** 设计稿把它与每天、每周、仅一次并列。每小时整点与固定间隔在语义上是同一种按经过时间计量的规则,因此详情里的该项直接映射到既有的间隔类型,而不是新增一个持久种类。若真要新增,需要新的持久变体、解码器、目标解析与工具 schema,而它表达的能力现有间隔已经覆盖。 -任务发现和 timer 不依赖已加载的 Session。延迟、绝对时间和固定速率选择器在与 Daily、Weekly、Cron 并存时保留自身语义;读取已有任务不会重写它们。Host 必须提供普通 Session 持久化和恢复服务,Web bundle 在其宿主行列表中挂载 Schedule。显式删除会阻止后续投递,并将任务从 `list` 和 `catalog` 中移除,不删除对话消息;被移除的行会带走其已保存回执。历史在追加确认时按配置的窗口与条数上限裁剪,随后加载到 Host 内存,并在每次确认时随任务一起重写。分页限制返回记录数量,不限制存储增长或指令字节数。此前被覆盖的回执,以及任务写入失败的投递记录,无法重建。暂停和执行历史操作仍不受支持。 +任务发现和 timer 不依赖已加载的 Session。延迟、绝对时间和固定速率选择器在与 Daily、Weekly、Cron 并存时保留自身语义;读取已有任务不会重写它们。Host 必须提供普通 Session 持久化和恢复服务,而挂载 Schedule 需要启用可选实验 bundle `@deepseek-ai/dsh-experimental-schedule-bundle`;Web 组合以禁用状态携带其条目。显式删除会阻止后续投递,并将任务从 `list` 和 `catalog` 中移除,不删除对话消息;被移除的行会带走其已保存回执。历史在追加确认时按配置的窗口与条数上限裁剪,随后加载到 Host 内存,并在每次确认时随任务一起重写。分页限制返回记录数量,不限制存储增长或指令字节数。此前被覆盖的回执,以及任务写入失败的投递记录,无法重建。暂停和执行历史操作仍不受支持。 必要覆盖范围包括从已存储任务启动、缺失状态规范化、冷 Session 恢复、仅补发最新发生时点、保留未运行任务且不重复投递、真实消息回执、重启后的删除结果、删除会移除已保存发送记录、排队或持久化失败,以及销毁。钟表规则的验证要求包括缺口和跳过的日期、仅选择较早时点的重叠、小数秒、UTC 范围边缘、已提交目标和别名保留,以及恢复后的时钟回拨。Weekly 另需覆盖星期集合的规范化与校验、跨缺口与重叠的下一目标选择,以及已存集合的保留。历史解码器必须拒绝 Daily、Weekly 与 Cron,而宿主存储接受它们。客户端覆盖范围包括每种重复规则、精确规则时间、时区和星期集合、全部/已开启/未运行状态筛选、保留未运行任务详情和原 Session 导航、确认删除和通知后的权威刷新、空列表、重新连接和晚到响应。呈现覆盖范围包括页面“新建”操作打开新会话、transcript 卡片从不完整或回放的结果 JSON 中收窄任务、页头时钟在恰好一个任务时直接打开并给出数量标签、仅空闲行标记及其悬浮卡片两个任务上限与遗漏行。历史覆盖范围包括旧文件字节保留、追加与重启、不可变的发送指令、最近回执一致性严格校验、稳定游标分页、绑定校验、持久化失败,以及刷新或切换任务期间晚到的分页响应。跨存储崩溃导致的重复投递仍是明确限制,不能被表述为完成保证。 diff --git a/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.i18n.yaml b/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.i18n.yaml index 614307e4b2..ae54aff2a9 100644 --- a/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.i18n.yaml +++ b/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.i18n.yaml @@ -9,8 +9,8 @@ en: 2409ea3a006ea5d9 zh: dbcda58a4c6b5b9f /agent-note-schedule-as-an-opt-in-optional-bundle/decision: - en: 360867ff77c6b727 - zh: 4eb4b47439c21d5d + en: 5aa944749a231645 + zh: c14651be6367ee13 /agent-note-schedule-as-an-opt-in-optional-bundle/alternatives-considered: en: 1782c8ecdbe6bf87 zh: dd6997d067257562 diff --git a/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.md b/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.md index 09bca841cf..bd4b47d25a 100644 --- a/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.md +++ b/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.md @@ -12,7 +12,7 @@ English | [中文](2026-09-24-schedule-opt-in-optional-bundle.zh.md) ## Decision -`packages/bundle/web-app/cordis.patch.yml` inserts `time-context`, `schedule`, and `ui-schedule` with `disabled: true`, so the shipped Web composition mounts none of the three. The rows stay in the composition because an id-targeted patch overrides an existing row: a profile patch or a bundle sets a row's `disabled` to `false` without inserting it again. +The rows stay in the composition because an id-targeted patch overrides an existing row: a profile patch or a bundle sets a row's `disabled` to `false` without inserting it again. `@deepseek-ai/dsh-experimental-schedule-bundle` (`packages/experimental/schedule-bundle/`) carries three id-targeted patches in its `cordis.patch.yml`, one per row, each setting `disabled: false`; it inserts no row. `OPTIONAL_BUNDLES` in `packages/boot/app-boot/src/profile.ts` names the package, and `apps/cli` declares it as a runtime dependency, so every installation ships it switched off. The [experimental-as-optional-bundles decision](2026-09-21-experimental-capabilities-as-optional-bundles.md) owns the `OPTIONAL_BUNDLES` conventions and the localized `icon` and `meta.title` / `meta.description` metadata the Web Plugins page renders in its Official group. diff --git a/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.zh.md b/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.zh.md index ed22c1ab08..eaa59aa17d 100644 --- a/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.zh.md +++ b/.agents/notes/implemented/architecture/2026-09-24-schedule-opt-in-optional-bundle.zh.md @@ -12,7 +12,7 @@ Status: implemented ## Decision -`packages/bundle/web-app/cordis.patch.yml` 以 `disabled: true` 插入 `time-context`、`schedule` 与 `ui-schedule`,因此随发行版交付的 Web 组合不挂载其中任何一行。这三行仍留在组合中,因为按 id 定位的 patch 覆盖的是已存在的行:profile patch 或 bundle 把某行的 `disabled` 设为 `false`,无需再次插入它。 +这三行仍留在组合中,因为按 id 定位的 patch 覆盖的是已存在的行:profile patch 或 bundle 把某行的 `disabled` 设为 `false`,无需再次插入它。 `@deepseek-ai/dsh-experimental-schedule-bundle`(`packages/experimental/schedule-bundle/`)在其 `cordis.patch.yml` 中携带三个按 id 定位的 patch,每行一个,各自把 `disabled` 设为 `false`;它不插入任何行。`packages/boot/app-boot/src/profile.ts` 的 `OPTIONAL_BUNDLES` 列出该包,`apps/cli` 将其声明为运行时依赖,因此每次安装都随包携带且默认关闭。[实验性能力作为可选 bundle 的决策](2026-09-21-experimental-capabilities-as-optional-bundles.zh.md)负责 `OPTIONAL_BUNDLES` 的约定,以及 Web 插件管理页在 Official 分组中渲染的本地化 `icon` 与 `meta.title` / `meta.description` 元数据。 diff --git a/apps/web/tests/assembled-remote.ts b/apps/web/tests/assembled-remote.ts index 192feb1142..e8d0141ba1 100644 --- a/apps/web/tests/assembled-remote.ts +++ b/apps/web/tests/assembled-remote.ts @@ -225,7 +225,8 @@ export function createAssembledRemote(options: AssembledRemoteOptions = {}): Ass mock.unary('session/list', () => ok({ items: structuredClone(sessions) })) // The shipped bundle layers this graph composes carry the `ui-schedule` row // disabled, so the Schedule client does not mount and no case here reads the - // catalog or the per-Session list; both stay declared empty. + // catalog or the per-Session list. Both stay declared so an enabled + // composition reads empty lists instead of a missing-rule failure. mock.unary('schedule/catalog', () => ok([])) mock.unary('schedule/list', () => ok([])) mock.unary('session/projections', (request: unknown) => { From acf3efeb038d0257b0c3d9fb2fc542c41440bdd1 Mon Sep 17 00:00:00 2001 From: Chinesezjc Date: Fri, 25 Sep 2026 15:32:29 +0800 Subject: [PATCH 8/9] build(schedule-bundle): match the workspace version after the master merge-forward The 0.1.7-rc.2 release bumped the root and every dsh-family manifest; the new experimental bundle carries the same version so check-workspace-constraints passes. --- packages/experimental/schedule-bundle/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/experimental/schedule-bundle/package.json b/packages/experimental/schedule-bundle/package.json index ba15cc8922..d64d82eb8f 100644 --- a/packages/experimental/schedule-bundle/package.json +++ b/packages/experimental/schedule-bundle/package.json @@ -1,7 +1,7 @@ { "name": "@deepseek-ai/dsh-experimental-schedule-bundle", "description": "Optional bundle that switches the shipped Schedule, time-context, and reminder-catalog rows on", - "version": "0.1.7-rc.1", + "version": "0.1.7-rc.2", "icon": "./icon.svg", "publishConfig": { "access": "public" From 657b8dac061c4be9c2d0d23f459c86ee5661104a Mon Sep 17 00:00:00 2001 From: Chinesezjc Date: Fri, 25 Sep 2026 15:48:37 +0800 Subject: [PATCH 9/9] docs(schedule-bundle): place the Automation tasks page on the sidebar entry The bundle README said the right sidebar shows the Automation tasks page. The ui-schedule client registers that page as a `main` panel with a sidebar entry and keeps the right Sidebar for the single-task detail tab. --- packages/experimental/schedule-bundle/README.i18n.yaml | 4 ++-- packages/experimental/schedule-bundle/README.md | 2 +- packages/experimental/schedule-bundle/README.zh.md | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/experimental/schedule-bundle/README.i18n.yaml b/packages/experimental/schedule-bundle/README.i18n.yaml index c05ec3e55b..bf7fe80742 100644 --- a/packages/experimental/schedule-bundle/README.i18n.yaml +++ b/packages/experimental/schedule-bundle/README.i18n.yaml @@ -15,8 +15,8 @@ en: d152484eb41ac6b4 zh: 364c80ee00a374ff /deepseek-ai-dsh-experimental-schedule-bundle/use-this-package: - en: ffaa4b18e10a1df9 - zh: b675fd8195ebb057 + en: d84cae0d3f3869c6 + zh: c19c74c0671f3127 /deepseek-ai-dsh-experimental-schedule-bundle/understand-the-implementation: en: b17882af7c7eaf2c zh: bfc71d0152557af5 diff --git a/packages/experimental/schedule-bundle/README.md b/packages/experimental/schedule-bundle/README.md index 02c0e1740f..b65f8586a1 100644 --- a/packages/experimental/schedule-bundle/README.md +++ b/packages/experimental/schedule-bundle/README.md @@ -25,7 +25,7 @@ This optional bundle switches on the three Schedule rows that `@deepseek-ai/dsh- ## Use this package -Open Plugins in the Web sidebar and enable Scheduling and time context, marked by a clock icon. A live root Agent then receives `schedule_create`, `schedule_list`, `schedule_update`, and `schedule_delete`, the Session header shows its reminder catalog, the right sidebar shows the Automation tasks page, and each eligible step appends one clock reading with the current time, the browser zone attached to the open request, and the elapsed time since the preceding model-visible message. Disabling the bundle restores the shipped composition; stored tasks remain on disk. +Open Plugins in the Web sidebar and enable Scheduling and time context, marked by a clock icon. A live root Agent then receives `schedule_create`, `schedule_list`, `schedule_update`, and `schedule_delete`, the Session header shows its reminder catalog, the sidebar's Automation tasks entry opens the task-management page and the right Sidebar holds the selected task's detail, and each eligible step appends one clock reading with the current time, the browser zone attached to the open request, and the elapsed time since the preceding model-visible message. Disabling the bundle restores the shipped composition; stored tasks remain on disk. ----- diff --git a/packages/experimental/schedule-bundle/README.zh.md b/packages/experimental/schedule-bundle/README.zh.md index f28a2466ce..0224507932 100644 --- a/packages/experimental/schedule-bundle/README.zh.md +++ b/packages/experimental/schedule-bundle/README.zh.md @@ -25,7 +25,7 @@ kind: "package-bundle" ## 使用此包 -打开 Web 侧栏的插件管理页并启用带时钟图标的“定时与时间上下文”。此后,活跃的根智能体获得 `schedule_create`、`schedule_list`、`schedule_update` 与 `schedule_delete`,会话头部显示提醒目录,右侧栏显示自动化任务页面,每个符合条件的步骤追加一条时钟读数,包含当前时间、打开请求所带的浏览器时区,以及距上一条模型可见消息的经过时间。禁用此 Bundle 会恢复随包组合;已存储的任务保留在磁盘上。 +打开 Web 侧栏的插件管理页并启用带时钟图标的“定时与时间上下文”。此后,活跃的根智能体获得 `schedule_create`、`schedule_list`、`schedule_update` 与 `schedule_delete`,会话头部显示提醒目录,侧栏的自动化任务入口打开任务管理页面、右侧栏承载所选任务的详情,每个符合条件的步骤追加一条时钟读数,包含当前时间、打开请求所带的浏览器时区,以及距上一条模型可见消息的经过时间。禁用此 Bundle 会恢复随包组合;已存储的任务保留在磁盘上。 -----