免费获取学习方案
ARTICLE DETAIL

资讯详情

深耕编程基础知识与建站技术分享的一线实战洞察。

qwen-code 守护进程工作区运行时 Skills 管理:config/skills 与 runtime/skills 双目录机制解析

qwen-code 守护进程工作区运行时 Skills 管理:config/skills 与 runtime/skills 双目录机制解析 qwen-code 守护进程工作区运行时 Skills 管理config/skills 与 runtime/skills 双目录机制解析【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code导读本文围绕 docs/design/daemon-workspace-runtime-skills.md 这一设计文档深入讲解 qwen-code 守护进程daemon如何在不依赖聊天会话、不将内部快照缓存暴露为 API 状态的前提下实现 Skills技能管理的工作区感知workspace-aware。你将掌握config/skills守护进程本地持久清单与runtime/skills活跃工作区运行时目录的职责划分、runtimeEpoch与revision的新鲜度判定规则、workspace_skills_config_runtime能力通告机制以及 Web Shell 端在 Skills 管理页和新会话编排中的实际加载流程。文中所有结论均以当前仓库源码与测试用例为依据可直接对照验证。一、设计目标Skills 管理的工作区感知传统模式下Skills 目录的读取与刷新强绑定在某个 ACPAgent Client Protocol会话上下文中要么需要先建立一个聊天会话才能查询 Skills要么直接依赖 daemon 内部快照缓存导致客户端看到的目录状态与真实运行状态之间存在隐藏的耦合。该设计文档给出的目标非常明确Skills 管理做到工作区感知workspace-aware而不必先建立聊天会话不把 daemon 内部的快照缓存暴露成公开 API 状态——快照缓存只是实现细节公开协议上不新增任何 cache/source 状态。换句话说Skills 的配置事实与运行时事实被彻底分层配置层回答这个工作区装了哪些 Skill、启用了哪些运行时层回答当前活跃的 ACP 运行时实际加载了哪些 Skill。这两层各自独立可读、可验证且在运行时能力就绪后按明确的规则合并。二、所有权与数据分层config 与 runtime 两条目录设计文档将 Skills 状态明确划分为两个所有权边界层面数据来源读取代价对应 APIconfig/skillsdaemon 本地、持久化的 Skills 清单不启动、不查询 ACP纯本地读取GET /workspace/config/skillsruntime/skills选中的活跃工作区运行时返回的目录由运行时产生携带产生它的runtimeEpochGET /workspace/runtime/skillsconfig/skills是 daemon 本地的持久清单durable inventory例如.qwen/skills下的已安装 Skill 目录、skills.disabled/skills.enabled设置项等。读取它不会拉起 ACP 子进程。runtime/skills是选中的活跃工作区运行时返回的目录快照。它必须携带产生该目录时的运行时纪元runtimeEpoch用于判断目录是否仍然当前。运行时协调器的职责工作区运行时协调器Workspace Runtime Coordinator负责运行时的准备preparation与对账reconciliation。其 Skills 能力项对外报告三个字段——statenot_started/starting/ready/stale/error、revision、runtimeEpoch。变更路由规则这是工作区感知的核心用户级user-global变更走单数工作区路由/workspace/...提交后对所有可信的托管运行时做对账reconcile项目级project变更与开关toggle走限定工作区路由/workspaces/:workspace/...只对该运行时做对账。从源码看这一规则在 packages/cli/src/serve/routes/workspace-skills.ts 的reconcileSkills函数中实现它遍历运行时列表对每个运行时先调用invalidateWorkspaceSkillsStatus()使旧目录失效再对可信运行时调用协调器的reconcileSkillsConfiguration()。测试用例commits global config without using the legacy runtime refresh验证了用户级安装提交后invalidateSkillsConfigStatus会同时作用于两个工作区/workspace与/workspace-2见 packages/cli/src/serve/routes/workspace-skills.test.ts。三、新鲜度规则epoch 相等才能合并revision 只用于进程内排序设计文档对什么时候可以把运行时目录合并给消费者看给出了严格的判定条件这也是整套机制里最容易被误解的部分消费者只有在 Skills 能力状态为ready且能力自身与目录的runtimeEpoch都等于当前运行时的runtimeEpoch时才能合并运行时独有runtime-only的 Skills否则一律回退使用 config 清单。两个概念必须分清runtimeEpoch运行时纪元标识产生目录的运行时代次。ACP 子进程每次重启如信任策略变更、运行时重建都会产生新纪元。目录与能力的 epoch 与当前运行时 epoch 不一致即代表过时。revision修订号仅在单个 daemon 进程内为变更排序不持久化消费者也不得持久化它。它不能跨进程、跨 epoch 比较。在 packages/cli/src/serve/workspace-runtime-coordinator.ts 中可以看到协调器初始状态为{ state: not_started, revision: 0 }status()方法L155-L185在能力已有runtimeEpoch但运行时未存活、或 epoch 与当前快照不一致时会把该能力状态降级标记为stale同时保留其revision与旧runtimeEpoch供诊断。而在ensure()的准备流程中skillsReady的判定正是state ready且capabilities.skills.runtimeEpoch status.runtimeEpochL233-L239。设计文档还特别强调daemon 既有的快照缓存仍然是实现细节不新增任何公开的 cache/source 状态。这保证了 API 面的简洁性——客户端永远只需要关心 config 与 runtime 两个显式来源。四、能力通告与路由契约workspace_skills_config_runtime该特性的对外开关是能力标签workspace_skills_config_runtime。在 packages/cli/src/serve/capabilities.ts 的能力注册表中登记且属于条件性通告conditional能力只有当toggles.workspaceRuntimeAvailable true即每个活跃工作区都支持权威的运行时生命周期时才在/capabilities中宣告见 CONDITIONAL_SERVE_FEATURES。客户端必须先 pre-flight 该标签再决定是否调用拆分路由——这是 qwen-code serve 协议标签存在 行为开启的一贯约定。4.1 拆分后的路由面依据 docs/developers/qwen-serve-protocol.md 的协议描述拆分后的核心路由如下读取config 面纯本地、无需运行时存活GET /workspace/config/skills读取 daemon 本地全局配置所有者GET /workspaces/:workspace/config/skills读取指定注册工作区的配置不要求运行时存活或可信。响应为标准 Skills 状态形状不要求runtimeEpoch{ v: 1, workspaceCwd: /work/project, initialized: true, skills: [] }读取runtime 面不启动运行时GET /workspace/runtime/skills与GET /workspaces/:workspace/runtime/skills读取选中的可信运行时目录而不启动它。活跃目录携带产生它的运行时纪元{ v: 1, workspaceCwd: /work/project, initialized: true, runtimeEpoch: 4, skills: [] }写入config 面用户级POST /workspace/config/skills/install、DELETE /workspace/config/skills/:name?scopeglobal工作区级POST /workspaces/:workspace/config/skills/install、DELETE /workspaces/:workspace/config/skills/:name?scopeworkspace、POST /workspaces/:workspace/config/skills/:name/enable。4.2 激活语义deferred 与 reconcilingconfig 写入总是先提交持久状态、再调度运行时对账。响应中的activation字段语义如下deferred当前没有可更新的运行时对账被延后reconciling对账请求已排队正在协调器执行无操作no-op的开关保持门面已有的激活值不得谎称发生了运行时刷新。对应源码中reconcileSkills的返回逻辑workspace-skills.ts L65-L80只要任一可信运行时的协调器返回reconciling整体就是reconciling否则为deferred。测试reports a live qualified toggle as reconcilingworkspace-skills.test.ts L365-L375与commits global config without using the legacy runtime refresh断言activation为deferred分别覆盖了两种分支。4.3 结构化错误码从路由实现与测试中可归纳出以下关键错误码均以{error, code}结构返回错误码HTTP 状态触发场景skills_config_unavailable503config 枚举失败时删除/变更操作不给出确定性的 not-found而是报配置不可用skill_not_found404目标 Skill 不存在含ENOENT映射skill_not_managed409大小写不敏感删除存在歧义无法唯一确定目标global_scope_requires_singular_owner400在限定工作区路由上使用scopeglobalworkspace_scope_requires_qualified_workspace400在单数路由上使用scopeworkspaceuntrusted_workspace403对非可信工作区执行限定写操作workspace_runtime_not_supported501旧式注入桥不支持运行时协调invalid_skill_name/invalid_skill_names400名称超长256 字符上限、为空或非法invalid_enabled_flag400enabled缺失或非布尔值workspace_runtime_unavailable503变更期间工作区代次关闭workspace_generation_closed此外批量开关POST /workspace/skills/enable的单次上限为100 个名称且在去重前计数重复项无法绕过上限见 workspace-skills.ts L35 与测试validates Skill batch request shape before calling the serviceworkspace-skills.test.ts L759-L825。五、Web Shell 端行为从列表页到新会话编排5.1 Skills 管理页当能力标签workspace_skills_config_runtime被通告时Web Shell 的 Skills 页面packages/web-shell/client/components/plugins/PluginManagerPage.tsx采用以下流程先加载 config立即展示选中工作区的配置 Skills快、纯本地后台确保运行时再在后台调用ensureRuntime()确保选中运行时然后读取该运行时的目录多工作区选择器当注册了多个工作区时列表页展示工作区选择器详情页展示同一个但禁用的选择器防止在详情视图中切换上下文见 PluginManagerPage.tsx L95-L109无该特性时回退保持旧的主工作区primary workspace路由并且不为 Skills 而 ensure 运行时。5.2 新会话编排与延迟会话引导新会话 composer 与延迟会话引导deferred session bootstrap的拆分读取同样以workspace_skills_config_runtime为门槛二者逻辑一致先展示选中工作区的 config Skills立即可用在后台 ensure 该运行时运行时就绪后用当前 epoch 的运行时目录替换 config 目录。该流程在 packages/web-shell/client/App.tsx 的reloadLoadedSkills中落地forNewSession且支持拆分特性时先workspaceConfigSkills()填充loadedSkills随后ensureRuntime()loadReadyWorkspaceSkills()用运行时目录二次覆盖。每次异步返回前都会用请求序号loadedSkillsRequestRef做竞态检查丢弃过期结果。与之配套的测试在 packages/web-shell/client/daemon/session/DaemonSessionProvider.test.tsxuses the Skills runtime API for a new task when advertised断言了workspaceConfigSkills、ensureRuntime、runtimeStatus、workspaceRuntimeSkills各调用一次且不再调用旧的workspaceSkills/workspaceAcpStatus/workspaceAcpPreheat而skips all Skill preparation when prefetch is disabled则验证了关闭预取后无论是否通告拆分特性所有 Skills 相关调用都会被跳过。其他消费者不使用该特性——设计文档明确限定只有 Skills 管理页与新会话编排接入避免扩大行为面。六、兼容性策略新旧路由并存设计文档的兼容性要求有两层旧 Skills 路由保持同步刷新行为不变GET /workspace/skills、POST /workspace/skills/install、POST /workspace/skills/enable等旧路由能力标签workspace_skills继续工作老客户端不受影响。测试invalidates config status after qualified legacy mutationsworkspace-skills.test.ts L584-L611验证了四条旧式限定路由在变更后都会使 config 状态失效。新 config 路由禁用旧式刷新并委托恰好一次运行时对账新的 config 写入不再走旧的读目录→刷新运行时链路而是由协调器统一调度reconcileSkillsConfiguration()。协调器内部通过skillsRevision递增 修订号比对来去重if (revision ! this.skillsRevision) return;见 workspace-runtime-coordinator.ts L314-L316保证同一代次的变更只被处理一次。这种新路由委托、旧路由保留的渐进式迁移让支持多工作区的 daemon 与旧式主工作区客户端可以在同一部署中共存。七、源码级验证从测试用例看契约边界除上文引用的测试外以下测试进一步固化了设计文档中的契约值得读者对照阅读packages/cli/src/serve/routes/workspace-skills.test.tskeeps config reads daemon-local and runtime reads explicitGET /workspace/config/skills只调用getSkillsConfigStatus不调用运行时状态GET /workspace/runtime/skills恰好调用一次getWorkspaceSkillsRuntimeStatus——这正是config 纯本地、runtime 显式读取的直接验证。L220-L237does not report a missing Skill when config enumeration failsconfig 枚举失败时删除操作返回 503skills_config_unavailable且不触碰服务层。L239-L302大小写敏感/歧义删除config 清单中存在多个仅大小写不同的名称时删除返回 409skill_not_managed防止误删。L304-L337限定读取兼容非可信与替换中工作区GET /workspaces/:workspace/config/skills对非可信、以及正在替换transitioning的工作区仍可读且全局安装被拒绝。L377-L395旧式桥返回 501限定 config 写入在旧式注入桥无生命周期快照能力上返回workspace_runtime_not_supported。八、总结qwen-code 的守护进程工作区运行时 Skills 设计本质上是一次状态来源分层的工程实践config/skills 负责事实daemon 本地持久、随时可读、不依赖 ACPruntime/skills 负责运行真相由活跃运行时产生用runtimeEpoch标注代次协调器负责对账以revision在进程内排序变更、以stale状态表达代次失配将配置变更 → 运行时生效收敛为一次权威调度Web Shell 负责渐进呈现先给 config再在后台补 runtime保证 UI 永远有东西可看、且最终收敛到当前代次的真实目录。对于希望为多工作区 daemon 扩展管理面的开发者这套能力标签 条件通告 拆分路由 唯一对账入口的模式本身就是一个可复用的参考模板新增面向工作区的管理路由时优先考虑 config/runtime 分层与runtimeEpoch校验而不是把快照缓存直接暴露给客户端。【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表