- 人工智能
- AI Agent
- 自主智能体
- 桌面应用
- MCP Clients
【免费下载链接】Kun
Local-first AI agent workspace for coding, writing, design, research, and automation — one runtime for desktop GUI and TUI.
本文聚焦 Kun 开源仓库中「扩展面板与主 Agent 协调(Extension–Agent Panel Coordination)」这一设计主题:在 Kun 将扩展 UI 收敛为views.rightSidebar侧边栏面板、并把主对话保留为唯一 Agent 操作面的背景下,主 Kun Agent 与打开的扩展面板之间如何通过"扩展注册的认证工具 + workspace 作用域状态 + 有界项目变更事件"完成项目编辑、状态同步与竞态防护,而绝不共享渲染器内部状态或私有 IPC。读完本文,你将掌握活动项目指针的读写约定、乐观修订(optimistic revision)的冲突拒绝语义、按 workspace 隔离 Host/工具/事件的实现要点,以及只读轮询与破坏性取消的工具分类规则,并能以仓库内置的 Kun Video Editor 为参照实现自己的协调型扩展。
一、设计背景:从"聚合启动器"到"IDE 工具窗格"模型
Kun 在本次右侧边栏重设计之前,扩展 UI 通过一个聚合启动器(aggregate launcher)混排多种占位模型,扩展面板与主 Agent 之间缺乏清晰、可审计的协作通道。重设计的核心方向是把扩展 UI 收敛为类似 IDE 工具窗格的形态:扩展声明一个views.rightSidebar视图与自己的图标,Kun 在代码模式右侧垂直工具栏渲染该图标,点击后在与主对话相邻的独立标签页中打开隔离视图(详见 extension-right-sidebar-navigation 规格)。
在这个模型下,主 Agent 与面板的协作遵循一条明确边界——extension-agent-panel-coordination 规格 原文规定:
扩展面板与主 Kun Agent 必须通过扩展的已认证、schema 校验通过的工具表面以及workspace 作用域的扩展状态进行协调;Kun 不得将主渲染器 React 状态、会话对话 DOM、运行时凭据或私有 guest IPC 暴露为协调机制。
这意味着协调契约由三部分组成,缺一不可:
- 工具表面(Tool Surface):扩展注册的、声明了输入/输出 Schema 与副作用级别的工具;
- 工作区状态(Workspace State):存放在扩展 workspace 命名空间内的活动项目指针等状态;
- 有界事件(Bounded Events):项目变更后发布的可归属、有边界的 workspace 事件。
对照 proposal.md 中的拒绝项可以看到,设计团队曾评估过"向每次提示注入面板状态的 renderer context-provider API"方案,最终因会扩大稳定提示面、加剧缓存抖动和跨层授权而否决,改为显式工具调用,因为工具调用是可审计且修订安全的。
二、活动项目指针:显式、workspace 作用域、绝不猜测
协调的第一步是让主 Agent 知道"面板当前打开的是哪个项目"。规格要求:
支持 Agent–面板协调的扩展必须暴露一个用于解析活动面板资源的显式工具操作。该指针只能存储在扩展的 workspace 命名空间内,使用前必须校验,且必须返回显式的"空"或"过期"结果,而不是猜测。
2.1 指针的写入:面板打开项目时记录
当用户在面板中打开或创建项目,扩展需将该项目记录为"当前可信 workspace 的活动项目"。在参考实现 kun-video-editor 中,video-tools-project.ts的selectActiveProject通过context.storage.workspace.set(ACTIVE_PROJECT_KEY, ...)写入带schemaVersion: 1的指针记录,并同时通过ui.postMessage发布kun-video-editor.project-changed消息(见 video-tools-project.ts)。该消息携带projectId、activeProjectId、previousProjectId、revision、generation、sequenceId、selectionGeneration、reason、transition、source等字段,为后续面板刷新提供完整依据。
2.2 指针的读取:显式的空/过期结果
video-project工具的active操作是读取路径。源码展示了三种显式结果(video-tools-project.ts):
no-active-project:存储中没有任何指针记录时返回,绝不替用户随便挑一个项目;stale-active-project(已清除):指针记录存在但 schema 版本不符、projectId 非法,或项目已无法加载时,扩展会先删除无效指针再返回过期结果;active:校验通过后返回当前项目的投影(projection)与currentRevision。
这种"显式结果优先于猜测"的设计避免了 Agent 在指针失效时对不存在的项目盲目操作。
三、乐观修订:Agent 编辑的并发安全基础
3.1 expectedRevision:每次变更都声明预期修订
规格中的两个场景定义了修订语义:
- Agent 编辑面板的活动项目:Agent 解析活动项目并用**其预期修订(expected revision)**调用受权的变更工具,扩展通过面板使用的同一
ProjectService提交修订并发布有界项目变更事件; - Agent 尝试过期编辑:当 Agent 使用比面板当前项目修订更旧的修订调用变更时,工具必须以当前修订拒绝该变更,面板与 Agent 应能刷新而不做隐式合并。
在参考实现中,所有写型视频工具(如video-update-timeline、video-probe、video-transcribe)的输入 Schema 都要求projectId与expectedRevision(整数、最小值 0),参见 tool-contracts.ts。而 project-service.ts 的saveProjectWithReceipt会先assertExpectedRevision(current, expectedRevision),修订不符时抛出revision_conflict错误——绝不静默合并,而是把expectedRevision与currentRevision一并返回给调用方,让 Agent 重新读取后再决策。
3.2 修订与选择代际(generation)双重校验
除了项目修订,参考实现还维护selection.generation与eventGeneration(见 project-service.ts)。updateSelection同时校验expectedRevision与expectedGeneration,任一不符即抛出revision_conflict或 selection generation 冲突。这保证了 Agent 的操作不仅"修订新鲜",而且不会覆盖面板用户刚做出的选择变更。
3.3 变更的可追溯性:Mutation Receipt
saveProjectWithReceipt中的 "Receipt" 是每次提交返回的变更凭据(操作列表、逆操作、摘要、attribution 等),Agent 每次编辑后必须消费该凭据并刷新标识符(参考 agentProfiles.video-editor.instructions)。这为"可归属的 workspace 事件"提供了数据基础——事件中的source字段可区分agent来源与手动来源。
四、有界项目变更事件:面板如何观察 Agent 发起的变更
4.1 事件发布与刷新路径
规格要求:Agent 工具提交新修订后,显示该项目的打开面板必须收到有界项目变更事件并重新加载该修订,且不读取对话内容。
参考实现的消息通道是kun-video-editor.project-changed(主动画变更时同时发布active-project-changed)。Webview 侧在 controller-effects.ts 订阅该通道:收到事件后dispatch({ type: 'project-change', value: change }),若事件针对当前面板项目或属于活动项目变更,则调用loadProject(change.projectId)重新拉取权威状态。面板绝不会去读主对话的 DOM 或 React 状态。
4.2 迟到的响应不得覆盖新选择:加载代际(generation)
规格强调"活动项目变更具有权威性、可归属且竞态安全"。实现上,Webview 维护activeProjectResolutionGeneration与projectLoadGeneration等递增计数器:每次active-project-changed事件都会使代际 +1,旧代际的迟到异步响应到达时会被丢弃,无法把面板"闪回"到更早的项目选择。项目切换时还会释放旧媒体租约、清理或过滤旧项目的脚本、媒体、作业与产物(规格 "Project-scoped panel state never leaks across selections" 的要求)。
4.3 面板中的同步状态展示
参考实现用一个紧凑的 Agent-sync 面板替代了原先内嵌的第二个私有 Agent 对话界面(见 app-timeline-panels.tsx):展示当前活动项目名、r{currentRevision}修订徽标、最近一次同步的来源与修订,以及aria-live的同步状态提示。它向用户传达"主对话才是编辑入口"这一设计立场,而不是在面板内再造一个聊天室。
五、Workspace 所有权隔离:Host、工具与视图事件的三重隔离
5.1 工具注册按 workspace 作用域键控
规格要求:workspace 作用域的扩展 Host 及其注册的 Agent 工具只能被激活它们的 workspace 发现与调用;另一个 workspace 的激活失败或挂起不得复用第一个 workspace 的注册或存储。
在 Kun 运行时,工具注册以"规范化 workspace 归属"为键:ExtensionToolRegistry使用scopedRegistrationKey(canonicalToolId, principal.workspaceRoots)管理注册,同一规范工具 ID 在不同 workspace 作用域下可各自持有一份注册;发现与调用都要求调用方的 workspace 与注册归属匹配(registrationOwnsWorkspace、registrationForWorkspace),不匹配时直接拒绝,见 extension-tool-provider.ts。其测试用例discovers and invokes one independently registered handler per workspace覆盖了三个 workspace 场景,验证 workspace C 无法看到 A/B 的注册(见 extension-tool-provider.test.ts)。
5.2 视图事件按"扩展身份 + workspace 作用域"双重路由
ExtensionViewSessionService的publish逻辑先匹配extensionId,再用viewSessionMatchesWorkspace/viewSessionMatchesWorkspaceKey匹配 workspace 作用域(见 extension-view-session-service-core.ts)。两个 workspace 各开一个视频面板时,A 的 Host 发布项目变更,只有 A 的 View Session 能收到,B 完全不受影响。对应回归测试见 extension-view-session-service.test.ts,其中明确断言 workspace B 的会话事件列表为空。
5.3 激活失败必须 fail closed
规格特别强调:某 workspace 的 Host 无法激活时,另一个 workspace 遗留的陈旧工具注册必须从该 Agent 的工具目录中缺席,并在调用时被拒绝。这与"可发现且仅可调用于激活它的 workspace"的原则一致,防止后台 Agent 会话或直接运行时工具执行跨越 workspace 边界(design.md 决策 9 明确否决了"保留单一全局 Host、仅在渲染器层隐藏工具"的备选方案)。
六、只读轮询与破坏性取消分离:审批模型的边界
规格最后一条要求:只读的渲染状态查询必须是独立的、无副作用的工具操作,与渲染取消分开;取消必须保留显式的副作用元数据与审批行为。
参考实现的video-render-status工具声明sideEffects: 'read'、idempotent: true,而video-render-cancel声明sideEffects: 'destructive'、idempotent: false(见 tool-contracts.ts)。同理还有video-analysis-status(read)与video-analysis-cancel(destructive)、video-interchange-status(read)与video-interchange-cancel(destructive)等成对工具。
这样设计的直接收益是:Agent 反复轮询导出进度时不会触发破坏性审批弹窗,而一旦发起取消,系统仍按完整副作用审批流程处理。规格原文对此的表述是"轮询不应训练用户去批准破坏性权限"。在 Agent 指令中也有对应约束:导出时用只读的video-render-status轮询持久化作业,仅在用户明确要求取消时才调用video-render-cancel(见 contributions.json 中 agentProfiles 指令)。
七、参考实现全景:Kun Video Editor 如何落地协调契约
整个协调模型在仓库内置的 Kun Video Editor(kun-examples.kun-video-editor)中端到端落地,可当作第三方扩展的范本:
7.1 清单侧:声明视图、权限与 Agent Profile
- metadata.json 声明
views.rightSidebar的editor视图、storage.workspace、workspace.read/write、media.*、jobs.manage等最小权限集; - contributions.json 声明 26 个
video-*工具及其allowedTools、budget,并把主 Agent 编辑流程固化在agentProfiles.video-editor.instructions中——其要点正是本规格的落地:先video-project解析活动项目、按expectedRevision读取/变更、把修订冲突视为"刷新信号而非合并机会"、用只读状态工具轮询。
7.2 Host 侧:工具分发与事件发布
VideoEditorTools.register()遍历VIDEO_TOOL_DECLARATIONS逐个注册工具(video-tools.ts),invoke按工具 ID 分发给video-tools-*.ts中对应的实现;editor-request命令则是面板 Webview 走认证 RPC 调用的私有通道(见 extension.ts)。
7.3 Webview 侧:订阅有界事件、按代际加载
面板通过controller-effects.ts订阅project-changed/active-project-changed/selection-changed/derived-changed等通道完成增量刷新,配合代际计数防御竞态,并在AgentSyncPanel中呈现同步状态(见前述引用)。
7.4 事件的作用域校验与发布来源
Host 发布事件统一走context.ui.postMessage,最终由 Kun 运行时的 View Session 服务按扩展身份 + workspace 作用域路由(见第五节)。source: 'agent' | 'manual'归属字段让面板可以区分"Agent 改的"与"用户自己改的",这也是规格要求的"可归属(attributable)"语义。
八、给扩展作者的协调契约清单
对照规格与参考实现,编写一个支持 Agent–面板协调的views.rightSidebar扩展时,需要满足以下可验证条件:
- 协调通道只走工具 + workspace 状态 + 有界事件:不请求访问主渲染器 React 状态、对话 DOM、运行时凭据或私有 guest IPC;manifest 中不声明超出需要的权限(参考实现仅声明
storage.workspace与workspace.read/write等)。 - 提供显式的活动资源解析工具:无活动项目时返回
no-active-project之类显式结果,指针过期时返回stale-*结果并清理,绝不随意选一个项目代替用户决策。 - 所有写型工具强制
expectedRevision校验:冲突时返回当前修订并拒绝,明确提示"刷新而非合并";面板与 Agent 均从权威ProjectService读取。 - 变更后发布有界、可归属的项目事件:事件包含项目 ID、修订、代际与来源;打开的面板订阅事件并从权威状态刷新,而不是读取对话内容。
- 按 workspace 隔离 Host、工具与视图事件:注册、发现、调用、事件路由均以规范化 workspace 作用域为键,激活失败 fail closed。
- 把只读查询与破坏性操作拆成不同工具:轮询用
sideEffects: 'read'的工具,取消用sideEffects: 'destructive'的工具并保留审批。
九、验证与测试依据
本规格对应的实现与回归测试在仓库中均可复现:
- 工具作用域隔离:extension-tool-provider.test.ts(多 workspace 独立注册/调用);
- 视图事件隔离:extension-view-session-service.test.ts(按 workspace 路由消息、按 workspace 撤销会话);
- 修订冲突语义:project-service.test.ts 与 video-tools.test.ts;
- 面板事件订阅与竞态:webview-controller-projects.tsx 与 webview-controller.test.tsx;
- 整体迁移与验证:任务清单见 tasks.md,全部勾选完成,覆盖活动项目指针权威化、事件路由隔离、只读/破坏性工具拆分等条目。
这套"工具 + workspace 状态 + 有界事件"的协调模型,为 Kun 生态中的扩展同时提供了可审计性、并发安全与多工作区隔离:主 Agent 与扩展面板共享同一份 workspace 作用域的项目事实,却互不窥探对方的内部实现——这正是 IDE 工具窗格式扩展协作的正确打开方式。
- 人工智能
- AI Agent
- 自主智能体
- 桌面应用
- MCP Clients
【免费下载链接】Kun
Local-first AI agent workspace for coding, writing, design, research, and automation — one runtime for desktop GUI and TUI.
相关推荐
Kun PPT:基于 Kun 扩展 API v1 的人机协作演示文稿工作区实现解析
Kun PPT:基于 Kun 扩展 API v1 的人机协作演示文稿工作区实现解析 Kun 已经能够通过受管的 PPT Master 工作流生成原生 PPTX
人工智能AI Agent自主智能体桌面应用MCP ClientsGopeed项目浏览器扩展与桌面端协同工作机制解析
Gopeed项目浏览器扩展与桌面端协同工作机制解析 Gopeed作为一款优秀的下载管理工具,其浏览器扩展与桌面客户端的协同工作能力一直是开发者关注的重点。近期有
网络CLI后端Kun 扩展平台架构与边界:单 Agent Runtime 之上的安全扩展模型
Kun 扩展平台架构与边界:单 Agent Runtime 之上的安全扩展模型 本文以 docs/extensions/architecture.md http
人工智能AI Agent自主智能体桌面应用MCP Clients
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考