-
Notifications
You must be signed in to change notification settings - Fork 3.1k
feat(serve): scope extensions to workspace runtimes #11086
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from all commits
Commits
Show all changes
56 commits
Select commit
Hold shift + click to select a range
f931162
feat(serve): scope extensions to workspace runtimes
f65c0e8
test(serve): cover extension runtime capabilities
9493fa6
Merge remote-tracking branch 'origin/main' into codex/daemon-workspac…
fbec518
fix(serve): address round-1 review findings on Extension runtime read…
qwen-code-ci-bot e77c512
Merge branch 'main' into codex/daemon-workspace-runtime-extensions-main
wenshao d431d17
Merge branch 'main' into codex/daemon-workspace-runtime-extensions-main
qwen-code-dev-bot e9c084c
test(cli): wait out the serve bootstrap window in the capabilities en…
qwen-code-dev-bot 9fed1f0
Merge branch 'main' into codex/daemon-workspace-runtime-extensions-main
qwen-code-dev-bot 0e3dbea
fix(serve): address extension runtime review findings
ac63bb4
Merge remote-tracking branch 'origin/main' into codex/daemon-workspac…
26ed5a5
fix(web-shell): keep split Extension runtime loaders off untrusted wo…
9ae66ef
Merge remote-tracking branch 'origin/main' into codex/daemon-workspac…
qwen-code-ci-bot c7030d9
fix(serve): address round-4 extension runtime review findings (#11086)
qwen-code-ci-bot 403b254
Merge remote-tracking branch 'origin/main' into codex/daemon-workspac…
qwen-code-ci-bot dedac49
fix(web-shell): annotate composer action merge as AtMentionWorkspaceA…
qwen-code-ci-bot f1a4858
fix(serve): address round-5 extension runtime review findings (#11086)
qwen-code-ci-bot aae6c06
fix(web-shell): cancel MessageList scroll-settle timer on unmount (#1…
qwen-code-ci-bot 93a7ae7
fix(web-shell): surface extension runtime readiness errors
e96a0ed
fix(serve): close extension readiness gaps
882a153
fix(web-shell): merge main, keeping upstream locate scroll timer
qwen-code-dev-bot 69604a9
fix(serve): address round-6 extension runtime findings and merge main…
qwen-code-ci-bot b97231b
Merge remote-tracking branch 'origin/main' into codex/daemon-workspac…
qwen-code-ci-bot ca96071
fix(web-shell): address round-7 extension runtime findings (#11086)
qwen-code-ci-bot 80d2ab8
test(web-shell): repair render indicator in split-session rerender te…
qwen-code-ci-bot 1937afd
chore(web-shell): merge main into #11086, keep strengthened split-rer…
qwen-code-dev-bot 6296997
fix(serve): address extension reconciliation and notice review
8fd4108
Merge remote-tracking branch 'origin/main' into codex/daemon-workspac…
29ea351
fix(serve): preserve cold-runtime extension install success
75f6b12
Merge branch 'main' into codex/daemon-workspace-runtime-extensions-main
qwen-code-dev-bot 35bf4f6
Merge branch 'main' into codex/daemon-workspace-runtime-extensions-main
qwen-code-dev-bot c031c91
fix(serve): Preserve extension reconciliation and operation lifecycle…
c80017e
Merge origin/main into codex/daemon-workspace-runtime-extensions-main
abb6fef
fix(extensions): Allow slow reconciliation and show unknown activation
641804c
fix(extensions): detect reused store generations and harden recovery …
0774d33
Merge branch 'main' into codex/daemon-workspace-runtime-extensions-main
qwen-code-dev-bot c246135
Merge remote-tracking branch 'origin/main' into codex/daemon-workspac…
qwen-code-ci-bot faefc6c
fix(extensions): hash receipts, scope update supersession, flag drain…
qwen-code-ci-bot 26aafd9
fix(extensions): track recovered store identity during reconciliation
4e35093
Merge remote-tracking branch 'origin/main' into codex/daemon-workspac…
5fc7d91
fix(extensions): normalize source-addressed update operations
44983f7
Merge branch 'main' into codex/daemon-workspace-runtime-extensions-main
ytahdn 8c027e5
fix(extensions): address round-15 extension runtime review findings (…
qwen-code-ci-bot 878b891
Merge branch 'main' into codex/daemon-workspace-runtime-extensions-main
qwen-code-dev-bot 4913ac9
Merge branch 'main' into codex/daemon-workspace-runtime-extensions-main
qwen-code-dev-bot 167621f
Merge remote-tracking branch 'origin/main' into codex/daemon-workspac…
qwen-code-dev-bot 357979f
fix(cli): close review-round reconciliation and interaction gaps (#11…
qwen-code-dev-bot 22da331
Merge branch 'main' into codex/daemon-workspace-runtime-extensions-main
qwen-code-dev-bot 3e48daa
fix(cli): keep a late install sweep from cancelling newer parked oper…
qwen-code-dev-bot 8285097
Merge branch 'main' into codex/daemon-workspace-runtime-extensions-main
wenshao 8e4e3c8
fix(cli): re-check extension readiness in-queue and order the install…
qwen-code-dev-bot 4c1733f
Merge branch 'main' into codex/daemon-workspace-runtime-extensions-main
qwen-code-dev-bot 0d75dee
Merge remote-tracking branch 'origin/main' into pr-11086-takeover
wenshao ef6b267
test(serve): pin extension interaction re-entry and fix activationSou…
wenshao b231153
fix(cli): close extension-generation certification gaps on ensure and…
qwen-code-dev-bot e756254
Merge branch 'main' into codex/daemon-workspace-runtime-extensions-main
qwen-code-dev-bot bd6077c
Merge branch 'main' into codex/daemon-workspace-runtime-extensions-main
qwen-code-dev-bot File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,137 @@ | ||
| # Daemon Workspace Runtime Extensions | ||
|
|
||
| [English](daemon-workspace-runtime-extensions.md) | [简体中文](daemon-workspace-runtime-extensions.zh-CN.md) | ||
|
|
||
| ## Goal | ||
|
|
||
| Move Extension management onto workspace-owned runtimes without requiring a | ||
| chat session. Keep the existing Extension Store as the durable global owner and | ||
| use the selected runtime only for the live catalog and reconciliation. | ||
|
|
||
| ## Ownership | ||
|
|
||
| - `GET /extensions` remains the daemon-local global artifact catalog. | ||
| - `GET /workspaces/:workspace/extensions` remains the durable activation | ||
| projection for one workspace. | ||
| - `GET /workspaces/:workspace/runtime/extensions` returns the selected live | ||
| runtime catalog and its runtime epoch. | ||
| - `WorkspaceRuntimeCoordinator` owns desired/applied Extension generation, | ||
| capability readiness, runtime refresh, and stale-result rejection. | ||
| - Global mutations invalidate every managed runtime. Workspace activation and | ||
| resource-state mutations invalidate only the selected runtime. | ||
|
|
||
| The coordinator is the only writable owner of runtime Extension readiness. | ||
| The route controller continues to own operation history and durable mutation | ||
| sequencing, but reports committed generations to each affected coordinator. | ||
|
|
||
| ## Reconciliation | ||
|
|
||
| An Extension commit is successful once the Extension Store commit succeeds. | ||
| For each affected trusted live runtime, the coordinator refreshes the bootstrap | ||
| configuration, discovery configuration, and active sessions, then reads the | ||
| live Extension catalog. It marks the capability ready only when the response | ||
| comes from the current runtime epoch and the applied generation equals the | ||
| latest desired generation. Cold runtimes remain deferred and converge on the | ||
| next `ensureRuntime()`. | ||
|
|
||
| Only ensure starts a cold runtime; queued reconciliation rechecks liveness and | ||
| never preheats. Applied generation is certified in a particular runtime epoch. | ||
| A narrow Skill refresh cannot carry that certification across an epoch change. | ||
| An obsolete generation returns `superseded`, not a refresh failure. Deferred | ||
| drain work preserves its narrow/full scope; full work takes precedence when | ||
| both are pending. A repeated failure re-arms the retry cooldown. | ||
|
|
||
| The physical refresh has the same five-minute budget as MCP controls because | ||
| it includes MCP discovery. The shorter ensure observation deadline does not | ||
| cancel that refresh; a later successful result can still certify readiness. | ||
| Hard timeouts retain the bridge's channel-retirement policy. | ||
|
|
||
| Observing a new generation invalidates retained Skill snapshots even while the | ||
| runtime is cold. Projection generation equality alone is not readiness: use | ||
| the current epoch and the coordinator capability state. Restore of a lower | ||
| store generation is supported by the poller's fresh authoritative read: it | ||
| invalidates applied certification and advances the coordinator revision. A | ||
| read overtaken by another observed mutation cannot lower the generation; | ||
| operation receipts alone never lower it. A recovery and recommit between two | ||
| reads reuses the generation number for different content, which the number | ||
| alone cannot show; the poller records the store's content hash, and a changed | ||
| hash at the desired generation clears applied certification and re-drives | ||
| reconciliation. The hash covers the entire store snapshot, including Skill | ||
| overrides and artifact metadata, not just the legacy enablement projection. | ||
| Recovery persists a fresh `recoveryId` (optional for existing V2 stores), so | ||
| recommits with identical artifact metadata still have a distinct identity. | ||
| Changing that recovery identity invalidates certification even when subsequent | ||
| commits advance the generation; a narrow Skill refresh cannot certify the | ||
| recovered artifacts without a full apply first. | ||
| An unknown prior hash or unreadable receipt identity requires reapplication; | ||
| reads overtaken by another observation cannot replace its identity, even at | ||
| the same generation. | ||
|
|
||
| Extension invalidation also invalidates the selected runtime's Skills and MCP | ||
| capabilities because both catalogs include Extension contributions. A late | ||
| refresh or catalog response from a replaced runtime cannot advance readiness. | ||
|
|
||
| ## API and SDK | ||
|
|
||
| Runtime status adds an `extensions` capability with `state`, `revision`, | ||
| `runtimeEpoch`, `desiredGeneration`, and `appliedGeneration`. Extension runtime | ||
| catalog responses add `runtimeEpoch`. | ||
|
|
||
| `WorkspaceDaemonClient` exposes the runtime catalog. Global install, update, | ||
| uninstall, update-check, and default activation remain on `DaemonClient`; | ||
| workspace activation, Extension Skill state, projection reads, and runtime | ||
| catalog reads remain on `WorkspaceDaemonClient`. | ||
|
|
||
| Source installs use the V2 global route. Archive uploads remain on the legacy | ||
| workspace route until a V2 archive endpoint exists, so they retain the legacy | ||
| default-activation behavior. | ||
|
|
||
| Interactive installs and updates share the existing operation interaction | ||
| endpoint under `/workspace/extensions/operations`. Their preparation deadline | ||
| cancels pending input. Prepared resources remain owned by the route until its | ||
| `finally` disposal, including when the deadline prevents commit. | ||
|
|
||
| ## Web Shell | ||
|
|
||
| When the daemon advertises `workspace_extensions_config_runtime`, the | ||
| Extensions page: | ||
|
|
||
| 1. loads the global catalog and selected workspace projection without starting | ||
| ACP; | ||
| 2. calls the shared parameterless runtime ensure; | ||
| 3. merges live details and `isActive` when the durable catalog generation and | ||
| coordinator are available, the runtime catalog is initialized, and capability | ||
| and catalog epochs match the coordinator epoch. Readiness and matching | ||
| desired/applied generations on the capability and activation projection | ||
| determine whether to re-read the catalog and projection, not whether to | ||
| retain matching-epoch live rows; | ||
| 4. shows the workspace selector on the list page and the disabled selector in | ||
| detail view. | ||
|
|
||
| Older daemons keep the existing primary-workspace flow. | ||
|
|
||
| When both the workspace activation projection and live activation state are | ||
| unavailable, list and detail badges show unknown, not the global default. | ||
|
|
||
| When the daemon also advertises `workspace_extension_mentions`, the composer | ||
| uses the selected workspace runtime for both the `+` and `@` Extension menus. | ||
| Without that feature, it keeps the legacy primary-workspace loader. | ||
|
|
||
| Notice attribution and the in-flight lock are distinct: an unknown or absent | ||
| Extension name falls back to the global notice surface without releasing the | ||
| active operation's lock. | ||
|
|
||
| ## Verification | ||
|
|
||
| Cover cold/queued-cold runtimes, superseded generations, runtime replacement, | ||
| same-epoch narrow refresh, drain replay, repeated failure cooldown, retained | ||
| Skills invalidation, expired interactive preparation, and recovered notices. | ||
| Run the existing local-install integration test without starting an ACP child. | ||
|
|
||
| ## Downstream consumers | ||
|
|
||
| - runtime status and workspace management routes; | ||
| - Extension V2 operation reconciliation and external-generation polling; | ||
| - Skills and MCP capability invalidation; | ||
| - TypeScript daemon SDK; | ||
| - Web Shell Plugin manager and Extensions manager. | ||
103 changes: 103 additions & 0 deletions
103
docs/design/daemon-workspace-runtime-extensions.zh-CN.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,103 @@ | ||
| # Daemon 工作区运行时拓展 | ||
|
|
||
| [English](daemon-workspace-runtime-extensions.md) | [简体中文](daemon-workspace-runtime-extensions.zh-CN.md) | ||
|
|
||
| ## 目标 | ||
|
|
||
| 将拓展管理迁移到工作区所属运行时,无需创建聊天 session。现有 Extension Store | ||
| 继续作为全局持久化所有者,仅实时目录和协调刷新使用选定运行时。 | ||
|
|
||
| ## 所有权 | ||
|
|
||
| - `GET /extensions` 是 daemon 本地的全局制品目录。 | ||
| - `GET /workspaces/:workspace/extensions` 是一个工作区的持久化激活投影。 | ||
| - `GET /workspaces/:workspace/runtime/extensions` 返回选定运行时的实时目录和 epoch。 | ||
| - `WorkspaceRuntimeCoordinator` 拥有期望/已应用 generation、能力就绪态、运行时刷新及过期结果拒绝。 | ||
| - 全局变更使所有受管理运行时失效;工作区激活和资源状态变更只使选定运行时失效。 | ||
|
|
||
| 协调器是拓展运行时就绪态的唯一可写所有者。路由控制器仍拥有操作历史和持久化变更 | ||
| 排序,并将已提交 generation 通知受影响协调器。 | ||
|
|
||
| ## 协调刷新 | ||
|
|
||
| Extension Store 提交成功即表示拓展变更成功。对受影响且可信的活动运行时,协调器 | ||
| 刷新 bootstrap 配置、发现配置及活动 session,然后读取实时目录。只有响应来自当前 | ||
| epoch,且已应用 generation 等于最新期望 generation,能力才标记为 ready。 | ||
| 冷运行时保持 deferred,等下次 `ensureRuntime()` 再生效。 | ||
|
|
||
| 只有 ensure 启动冷运行时;排队后的协调刷新重新检查存活状态,不执行 preheat。 | ||
| 已应用 generation 的认证属于特定 epoch,窄范围 Skill 刷新不能跨 epoch 继承认证。 | ||
| 过时 generation 返回 `superseded`,不算刷新失败。drain 延后任务保留窄/完整范围, | ||
| 两者同时待处理时完整刷新优先。冷却结束后再次失败会重新开始冷却。 | ||
|
|
||
| 实际刷新包含 MCP 发现,因此采用与 MCP 控制相同的五分钟预算。较短的 ensure | ||
| 观察截止时间不会取消刷新;稍后成功的结果仍可认证就绪态。 | ||
| 硬超时保留 bridge 现有的通道退役策略。 | ||
|
|
||
| 观察到新 generation 时,即使运行时是冷的,也使保留的 Skill 快照失效。 | ||
| 投影 generation 相等不独立代表就绪,还需当前 epoch 和协调器能力状态。 | ||
| 轮询器的新鲜权威读取支持存储恢复到较低 generation:清除已应用认证并推进协调器 revision。 | ||
| 读取期间若观察到其他变更,则该读取不能降低 generation;仅操作回执始终不能降低 generation。 | ||
| 若恢复与重新提交发生在两次读取之间,generation 编号会被不同内容复用,仅凭编号无法发现; | ||
| 轮询器记录存储内容哈希,相同 generation 上哈希变化即清除已应用认证并重新驱动协调。 | ||
| 哈希覆盖完整存储快照,包括 Skill 开关和安装产物元数据,而不只是旧版启用规则投影。 | ||
| 恢复时持久化新的 `recoveryId`(兼容缺少此字段的现有 V2 存储),使产物元数据完全相同的 | ||
| 重新提交仍具有不同身份。恢复身份变化时,即使后续提交推进了 generation,也清除认证; | ||
| 恢复的产物必须先完整应用,不能由窄范围 Skill 刷新直接认证。 | ||
| 此前哈希未知或回执身份读取失败时需要重新应用;读取期间若已有更新的观察, | ||
| 即使 generation 相同,也不能用迟到的读取替换内容身份。 | ||
|
|
||
| 拓展应用还会使选定运行时的 Skills 和 MCP 能力失效,因为两个目录均包含拓展贡献。 | ||
| 来自已替换运行时的迟到刷新或目录响应不能推进就绪态。 | ||
|
|
||
| ## API 与 SDK | ||
|
|
||
| 运行时状态增加 `extensions` 能力,包含 `state`、`revision`、`runtimeEpoch`、 | ||
| `desiredGeneration`、`appliedGeneration`。实时拓展目录响应增加 `runtimeEpoch`。 | ||
|
|
||
| `WorkspaceDaemonClient` 提供实时目录。全局安装、更新、卸载、更新检查、默认激活 | ||
| 保留在 `DaemonClient`;工作区激活、拓展 Skill 状态、投影和实时目录读取保留在 | ||
| `WorkspaceDaemonClient`。 | ||
|
|
||
| 来源安装使用 V2 全局路由。V2 归档端点存在之前,归档上传仍走旧工作区路由,保留旧的 | ||
| 默认激活行为。 | ||
|
|
||
| 交互安装和更新共用 `/workspace/extensions/operations` 下现有的交互应答端点。 | ||
| 准备阶段截止时间取消待输入交互。已准备资源由路由持有,直到其 `finally` 释放, | ||
| 包括截止时间阻止提交的情况。 | ||
|
|
||
| ## Web Shell | ||
|
|
||
| daemon 声明 `workspace_extensions_config_runtime` 时,拓展页面: | ||
|
|
||
| 1. 读取全局目录和选定工作区投影,不启动 ACP; | ||
| 2. 调用共享的无参数运行时 ensure; | ||
| 3. 当持久目录 generation 与协调器可用、实时目录已初始化、能力和目录 epoch 均匹配 | ||
| 协调器 epoch 时,合并实时详情及 `isActive`。能力就绪及能力/投影的期望与已应用 | ||
| generation 相等决定是否重新读取目录和投影,不决定是否保留 epoch 匹配的实时行; | ||
| 4. 列表页显示工作区选择器,详情页显示禁用的选择器。 | ||
|
|
||
| 旧 daemon 保留现有主工作区流程。 | ||
|
|
||
| 工作区激活投影和实时激活状态都不可用时,列表及详情徽标显示状态未知, | ||
| 不使用全局默认值代替。 | ||
|
|
||
| daemon 同时声明 `workspace_extension_mentions` 时,输入区 `+` 和 `@` 拓展菜单 | ||
| 使用选定工作区运行时;否则保留旧主工作区加载器。 | ||
|
|
||
| 提示归属和进行中操作锁互相独立:未知或缺失的拓展名称回退到全局提示区域,但不释放 | ||
| 活动操作的锁。 | ||
|
|
||
| ## 验证 | ||
|
|
||
| 覆盖冷/排队后变冷运行时、过时 generation、运行时替换、同 epoch 窄刷新、drain | ||
| 回放、连续失败冷却、保留 Skills 失效、交互准备超时及恢复操作提示。 | ||
| 执行现有本地安装集成测试,确认不启动 ACP child。 | ||
|
|
||
| ## 下游消费者 | ||
|
|
||
| - 运行时状态和工作区管理路由; | ||
| - 拓展 V2 操作协调及外部 generation 轮询; | ||
| - Skills 与 MCP 能力失效; | ||
| - TypeScript daemon SDK; | ||
| - Web Shell Plugin 管理器和拓展管理器。 |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.