已创建的应用,
在新标签页直接打开
界面自由编写,业务数据独立保存,模型与程序能力通过明确的运行合同调用。
按使用样例实施:Program、Package 与 Application
本节规定管理体系调整。Program 是可调用能力的总称,Tools 与 Workflows 保留现有定义。Package 是包含这些能力的安装单位,三个 harness 属于 Package。Application 是用户可打开的软件,拥有自己的界面、版本、数据和运行生命周期。Package 不作为新的执行类型;Application 不再记录在 Program 来源目录中。
| 用户样例 | 入口与操作 | 可观察结果及失败处理 | 实现与验收 |
|---|---|---|---|
| U1 查看已有能力 | Abilities → Programs,展开 Tools、Workflows、Packages | 三个 harness 显示在 Packages;选择包显示来源、默认调用入口与调用结构。gui_agent 等调用名不变,软件应用不进入能力扫描。 | 来源发现、explorer、调用图和页面分类统一;API 测试检查新分类及旧路径兼容。 |
| U2 安装、升级和卸载程序包 | 包详情查看管理命令;使用现有 programs install、install --upgrade、uninstall CLI | 新安装使用 programs/packages。已有安装按原路径继续识别,记录标明 package;不重新下载、不移动外部源码、不修改开发符号链接目标。桌面只读依赖限制保留,页面明确由拥有环境的 CLI 管理。 | 安装目录辅助函数、保护路径、来源记录、registry、CLI 与刷新脚本兼容新旧目录;安装/撤销与未知目录不导入测试。 |
| U3 安装一个软件应用 | 侧栏 Applications → 输入本地应用目录 → 安装 | 显示声明、来源、版本及启用状态。Python 后端须在安装表单明确勾选信任本地代码;重复 ID、坏入口或依赖准备失败返回错误,不覆盖旧版本。 | 独立管理页复用 owner API;新注册文件 applications/catalog.json。浏览器从安装表单验证目录、失败和成功。 |
| U4 从菜单打开软件 | 新标签页点击应用按钮;管理页也可点击 Open | 打开应用自己的标签;同实例复用。项目应用按当前项目或项目选择器绑定。普通 Program/Package 不自动产生启动按钮。 | 复用现有应用打开路径与项目选择;浏览器验证管理页和菜单指向同一实例。 |
| U5 管理已安装软件 | Applications → 启停、显示/隐藏、更新、卸载 | 禁用阻止新打开与操作;隐藏仅移除菜单按钮;更新需明确使用原来源重新安装并保持既有 schema 保护。卸载撤销注册,保留用户数据;再次安装恢复原实例。错误保留在对应操作处。 | 复用 PATCH、install replace 与 DELETE API;页面刷新及跨页重新打开读取最新目录。验证保存的数据和运行版本不受分类迁移影响。 |
| U6 更新已有 OpenProgram | 启动或首次读取新应用目录 | 将旧 program-sources.json 中 kind=application 的软件记录迁入独立文件,包括禁用、隐藏、来源和卸载记录;先写入新文件成功再移除旧记录。冲突拒绝覆盖并保留原始记录,可重复执行。程序包来源继续存在于 Program 目录。 | 真实 API 触发迁移,验证幂等、写入失败、冲突及数据/实例身份保留。相同锁序串行化迁移与目录更新。 |
| U7 使用命令行或 Agent 调用 | apps list/install/run/status/cancel/uninstall;原 programs apps 命令兼容 | 新文档以顶层 apps 表达软件管理;现有工具、Workflow 和 harness 调用不变。旧自动化命令继续可用。 | CLI parser/dispatch 与 help 验证,沿用 owner-authenticated application client。 |
管理入口与目录
Abilities / Programs Applications /applications
Tools 已安装的软件及安装表单
Workflows 来源、版本、启停、更新、卸载
Packages Open → 同一应用实例标签
gui_harness
research_harness 新标签页
wiki_agent_harness 已启用且未隐藏的软件按钮
新程序包安装目录为 openprogram/programs/packages/。原 programs/applications/ 仅作为旧安装位置兼容读取,界面统一显示 Packages;不把旧源码搬入软件数据目录。Program 来源仍由 program-sources.json 管理。软件注册使用 applications/catalog.json;已有 versions、environments、实例 SQLite、运行记录和数据目录保持原位置。源目录分类改变不赋予任何未登记目录执行权限。
实施顺序与范围
作为一项完整的分类迁移实施:先固定 U1/U6 的公开入口失败测试,再修改来源与独立目录;随后完成 U2/U7 的目录和 CLI 兼容、U3–U5 的管理页面与菜单接入,最后验证端到端使用样例。所有共享目录消费者、沙箱保护、发行打包、产品文档和契约测试一起更新。独立规范审查通过后进行质量审查,再执行完整测试清单并更新默认 App。
本次不增加插件市场、不改三个 harness 的算法、不自动把任意代码识别成软件,不新增其他语言 runner,也不增加独立部署。程序包的安装仍使用已有 CLI 环境约束;应用安装页面不能借程序包接口修改桌面宿主依赖。
实现状态:U1–U7 已实现并验收。分类、独立目录迁移、管理页、菜单启动与顶层 CLI 已通过独立规范审查、质量审查和完整检查。默认 App 已验证三个 harness 位于 Packages、管理页与菜单复用阅读器实例、原笔记与项目文件分析结果保留、菜单隐藏及恢复。实际迁移核对三个应用记录、三个实例与两个数据文件保持一致,十四条 Program 来源保留;重复历史登记按同一路径识别,仍拒绝不同安装位置的冲突。安装、更新、禁用、卸载后重新安装及失败处理由公开 API、CLI 和真实浏览器测试覆盖。模型成功与失败使用受控集成测试验证,不表示真实模型服务可用性;独立部署与 MCP Apps 适配仍未实现。
Application 软件与 Program 能力分别管理
OpenProgram 的应用包含自己的界面、业务逻辑、数据和依赖;框架负责应用注册、打开、运行上下文与公共能力。创建完成并验证的应用,以名称和图标出现在新标签页。用户点一下就打开应用,不需要重新描述需求,也不需要回到生成它的对话。
默认界面采用标准 Web 技术:HTML、CSS、JavaScript,以及编译后的 React、Vue 等。应用可以自行设计页面、编辑器、图表和交互,不必由 OpenProgram 的几个固定组件拼装。Python 后端处理业务和模型任务。HTML 是界面的实现技术,不能据此判断程序是否完整;后端、状态、运行合同和部署依赖才决定软件能力。
应用默认在 OpenProgram 中运行。架构允许同一应用以后用最小 runtime 单独部署,不要求打开整个桌面客户端;这仍属于依赖 OpenProgram runtime 的软件。完全去掉 OpenProgram 依赖,需要应用提供替代模型、存储和运行实现,不能承诺自动导出任何应用为独立程序。
这项设计的具体价值是:应用按钮与 Agent 使用同一业务操作,模型调用归入已有执行记录,业务数据不依赖聊天窗口,升级不会改变正在运行的任务代码。它是产品合同的组合,不能声称上述单项机制市场独有。Hermes 的 UI 扩展、MCP Apps 的可移植界面和 AgentOS 的运行服务都已有直接参考。[8] Hermes 桌面插件 SDK [40] MCP Apps [29] Agno / AgentOS
用户看到什么
新标签页保留 Files、New chat、Browser、Terminal,已启用且注册完成的应用追加在同一区域。应用自己的功能在打开后展示,不把模型、端口、runtime 或安装路径放在启动按钮上。管理入口负责隐藏、重命名显示名称、卸载和查看错误;隐藏不删除应用数据。
上方仅演示“从新标签页打开已存在应用”,不调用模型、不安装软件。四个内置项目作为背景展示;两个应用按钮和返回按钮可以操作。
同一应用在同一项目默认复用已打开标签页;不同项目可以分别打开,数据范围明确分开。新标签页没有活动项目时,先使用应用已绑定的项目;应用要求项目而尚未绑定时,首次打开才选择。应用不能跟随任意另一个聊天标签页的 cwd 静默改变数据目录。
“一句话创建”的入口仍是已有对话:Agent 编写应用包和依赖说明,完成构建与行为验证,然后在该创建任务授权范围内注册应用。注册成功才出现菜单按钮。创建失败保留源码和错误供修复,不把尚不能打开的半成品显示为可用应用;后续修改生成候选版本,验证后再替换。
第一次打开可能显示准备依赖或启动中;失败时留在同一个应用页显示失败原因和重试入口。普通页面关闭仅关闭视图。用户已发起的后台任务继续运行;重新打开读取同一任务状态。服务进程退出与业务任务中断分开报告。
调研范围与判断方法
本报告覆盖下表列出的主要公开 Agent harness、编码工具、嵌入式框架、应用平台及界面协议。分类按本问题中的作用划分,不是市场份额排名。协议不是 harness;纳入它们是为了回答界面如何集成,而不是把不同层次混称为同类产品。
DSH 发行包、worktable 和 OpenProgram 进行了相关代码路径核查;其他项目以当前官方文档、公开示例或仓库说明为证据。未安装并端到端验证所有产品。表中的“未核实”表示来源不足,不等于产品绝对不支持。Cursor、Windsurf 的内部实现未知。AutoGen、Semantic Kernel 在 Microsoft Agent Framework 的沿革中讨论,未伪装成三套已经逐项核查的当前实现。
“所有市面框架”没有封闭名录。未穷尽商业产品、社区分支及私有 harness;例如 Qwen Code、Strands 的相关页面本次未成功获取,Trae、Kimi CLI、各类云端软件生成服务也不在已核查矩阵内。这些缺口限制了市场唯一性结论,不影响下方已经明确的应用运行需求。
对每个项目分别问:扩展交付什么?谁加载和执行?谁渲染 UI?业务状态存在哪里?能否离开宿主?“会写软件”“能执行代码”“有 UI”“支持安装应用”分别判断,不互相替代。
公开机制比较
| 项目 / 证据 | 类别 | 扩展或运行机制 | 界面能力 | 宿主依赖 / 来源 |
|---|---|---|---|---|
| DeepSeek Harness已读本地发行包代码 | 宿主扩展 | Cordis 生命周期、服务注入;动态插件包含 host/client 两部分。 | 宿主 React 插槽;动态前端调用已注册的后端处理函数。 | 插件依赖 DSH 服务与加载器;不自动成为独立软件。 [1] DeepSeek Harness |
| dsh-worktable已读插件源码 | 宿主扩展 | 安装包同时提供后端路由与前端工作台。 | 项目入口、分屏;生成产物按 widget-result.json 装入 iframe。 | 工作台依赖 DSH;生成页面是否独立取决于页面自己的依赖。 [2] dsh-worktable |
| Pi官方文档 | 宿主扩展 | TypeScript 扩展:工具、事件、命令与上下文。 | ctx.ui 自定义终端组件、消息渲染和覆盖面板。 | 扩展运行依赖 Pi;终端组件并非 HTML。 [3] Pi |
| OpenCode官方文档 | 宿主扩展 | JS/TS 插件事件钩子、自定义工具、SDK client。 | 已查文档列出 TUI 通知等接口;不能据此认定支持任意业务页面插件。 | 插件依赖 OpenCode;应用程序产物的独立性另论。 [4] OpenCode |
| Codex App Server官方文档 | Agent 服务 | 双向 JSON-RPC,线程、轮次、事件与审批。 | 客户端自己实现界面;该接口不是应用安装清单。 | 可构建独立客户端,但 Agent 能力仍依赖 Codex 服务。 [5] Codex App Server |
| Claude Code官方文档 | 宿主扩展 | 插件打包 skills、agents、hooks、MCP、LSP 等。 | 公开插件合同主要扩展 Agent;未据此确认任意 React 页面注册。 | 插件依赖 Claude Code;不能把插件包视为桌面应用。 [6] Claude Code |
| Hermes官方文档 | 宿主扩展 | Python register(ctx) 与多种能力注册。 | 另有 Desktop SDK、Dashboard 扩展,不只有终端插件。 | 本地宿主扩展;兼容其他插件格式只代表明确支持的子集。 [7] Hermes |
| OpenClaw官方文档 | 宿主扩展 | Gateway 插件提供工具、服务、通道与运行能力。 | 交互 Dashboard 与 macOS widget panel 的合同不同。 | 插件依赖 Gateway;面板显示 HTML 不等于全部运行能力。 [10] OpenClaw |
| Gemini CLI官方文档 | 宿主扩展 | 扩展打包 prompts、MCP、命令等 Agent 配置与能力。 | CLI 扩展机制;不是任意应用页面的安装合同。 | 扩展使用 Gemini CLI 的加载与运行环境。 [12] Gemini CLI |
| goose官方文档 | 宿主扩展 | MCP 扩展、recipes、CLI/API。 | Desktop 明确支持 MCP Apps 交互界面。 | MCP 服务可分离部署;UI 需要兼容宿主。 [13] goose |
| OpenHands官方文档 | Agent 服务 | Python/REST SDK、工具、会话与远程 Agent Server。 | 可用 SDK 构建自己的开发者体验。 | 可嵌入应用;不等于通用应用菜单或任意宿主 UI 扩展。 [14] OpenHands |
| DeerFlow官方仓库说明 | Agent 服务 | Gateway、长任务 Agent、skills、文件和执行环境。 | 完整 Web 客户端;只读静态演示与带后端运行模式明确不同。 | 完整功能需要其运行后端;演示页面不能证明服务独立性。 [15] DeerFlow |
| Aider官方文档 | 编码工具 | 以代码修改、测试和 Git 工作流为主。 | 命令行产品;本次未核实通用应用 UI 插件合同。 | 写出的源码可按自身依赖部署;与 Aider 扩展是两回事。 [16] Aider |
| mini-SWE-agent官方仓库说明 | 编码工具 | 简化 Agent 循环、独立 shell action、线性历史。 | CLI 与轨迹查看器。 | 能生成程序;所查合同不负责安装程序为宿主应用。 [17] mini-SWE-agent |
| Mistral Vibe官方仓库说明 | 编码工具 | CLI 编码 Agent,程序模式及流式输出。 | 终端;本次未核实业务页面插件合同。 | 可被程序调用;输出格式不承担 UI 渲染合同。 [18] Mistral Vibe |
| Cline官方文档 | 编码工具 | MCP 扩展外部工具与服务。 | 所查页面证明工具集成,不证明任意 UI 扩展。 | MCP 服务器可以独立运行;宿主负责工具调用。 [19] Cline |
| Roo Code官方文档 | 编码工具 | 项目/全局 MCP,stdio、HTTP 等连接。 | 编辑器内的 Agent 交互。 | MCP 服务与编辑器扩展是不同部署对象。 [20] Roo Code |
| Continue官方文档 | 编码工具 | 配置 MCP 工具到 Agent。 | 编辑器/Agent 集成;本次未核实任意业务页面注册。 | 工具服务可跨宿主;Continue 配置仍依赖 Continue。 [21] Continue |
| Cursor官方概览;内部未知 | 闭源产品 | 公开文档提供 Agent、Rules、MCP 等入口。 | 产品界面可见;内部插件运行机制本次未核实。 | 不依据公开功能列表推断内部架构或任意应用宿主合同。 [22] Cursor |
| Windsurf / Devin Desktop官方文档;内部未知 | 闭源产品 | 公开 Cascade MCP 集成。 | 编辑器内交互;内部机制未核实。 | MCP 能力不等于业务应用页面的可移植性。 [23] Windsurf / Devin Desktop |
| Claude Agent SDK官方文档 | 嵌入式框架 | 把 Claude Agent 能力嵌入 Python/TypeScript 程序。 | 应用自行提供 UI。 | 可脱离 Claude Code 的交互界面;仍有 SDK/runtime 依赖。 [24] Claude Agent SDK |
| LangGraph官方文档 | 嵌入式框架 | 状态图、持久化、恢复与人工介入。 | 图/事件不规定最终业务 UI。 | 可作为独立程序的库;持久化要实际配置。 [25] LangGraph |
| Deep Agents官方文档 | 嵌入式框架 | 在 LangGraph 上组合工具、文件、上下文与子 Agent。 | Agent harness 与最终应用界面分离。 | 可嵌入应用,依赖其库和运行配置。 [26] Deep Agents |
| Google ADK官方文档 | 嵌入式框架 | Agent 开发、编排、工具与部署体系。 | 开发工具与业务应用 UI 应分别评估。 | 用于构建/部署 Agent;不是桌面应用注册协议。 [27] Google ADK |
| Microsoft Agent Framework官方文档 | 嵌入式框架 | Agent 与 workflow 开发;延续 AutoGen、Semantic Kernel 的相关能力。 | 应用自行集成界面与渠道。 | SDK/服务依赖,不要求使用某个桌面宿主页面。 [28] Microsoft Agent Framework |
| Agno / AgentOS官方文档 | Agent 服务 | FastAPI 运行 agents、teams、workflows;数据库状态与接口。 | Control Plane 用于管理;可有自己的产品前端。 | 应用可独立部署服务;仍需 AgentOS 与存储配置。 [29] Agno / AgentOS |
| CrewAI官方文档 | 嵌入式框架 | Flows 表达业务流程与状态。 | 流程运行不限定业务前端。 | 应用依赖库及其部署环境;不是页面插件格式。 [30] CrewAI |
| PydanticAI官方文档 | 嵌入式框架 | 类型化 Agent 与 UI 事件流集成。 | UI Event Streams 为前端消费事件提供适配。 | 前端与 Agent 运行可分离;不是完整应用安装协议。 [31] PydanticAI |
| Mastra官方文档 | 嵌入式框架 | TypeScript agents、workflows、服务与存储。 | 支持 Next.js、React/Vite 等应用集成;Studio 用于开发管理。 | 业务应用可自己部署,依赖 Mastra 服务/库。 [32] Mastra |
| NeMo Agent Toolkit官方仓库说明 | 嵌入式框架 | 函数、模型、workflow 配置与多框架集成。 | 所查入口以运行/优化 Agent 工作流为主。 | 部署工具链;不据此认定通用桌面应用插件支持。 [33] NeMo Agent Toolkit |
| smolagents官方仓库说明 | 嵌入式框架 | CodeAgent 执行代码并调用工具,可分享 Agent。 | 应用 UI 另行实现或集成。 | 可写普通 Python 程序;不是宿主页面扩展协议。 [34] smolagents |
| Dify官方仓库说明 | 应用平台 | Plugin Daemon 管理 local/debug/serverless 插件运行。 | 插件运行与 Dify 应用展示分开;不能把后端插件当任意 UI。 | 本地子进程或远程运行仍依赖 Dify 插件调用协议。 [35] Dify |
| Open WebUI官方文档 | 应用平台 | Python Tools/Functions 扩展推理与平台行为。 | Action 可增加聊天按钮;还有事件驱动的交互扩展。 | 平台扩展依赖 Open WebUI,不是自动独立发布的软件。 [36] Open WebUI |
| Chainlit官方文档 | 应用平台 | Python 应用配合自定义元素及回调。 | CustomElement 使用 React;也可开发自有前端。 | 元素依赖 Chainlit 上下文;完整应用可以作为服务部署。 [37] Chainlit |
| OpenAI Plugins(原 Apps SDK 路径)官方文档 | 界面协议 | MCP 工具提供 UI 资源,标准 bridge 加宿主特定扩展。 | iframe Web UI;当前官方文档以 MCP Apps 为基础。 | 可跨兼容宿主;window.openai 特定能力不能自动跨宿主。 [39] OpenAI Plugins(原 Apps SDK 路径) |
| MCP Apps官方文档 | 界面协议 | 工具与 ui:// 资源关联;JSON-RPC / postMessage。 | 沙箱 Web UI,可选择前端框架。 | 兼容的是 UI/工具交互;不负责本地安装、业务数据库与后台任务。 [40] MCP Apps |
| AG-UI官方文档 | 界面协议 | Agent 与 UI 的事件通信。 | 不规定 HTML、原生组件或页面框架。 | 解决流式交互,不是应用包、权限系统或部署器。 [41] AG-UI |
| A2UI官方文档 | 界面协议 | 生成结构化 UI 描述,由受信组件目录渲染。 | 限制在可用组件与 renderer 合同内。 | 可跨平台渲染;不等于运行任意生成前端代码。 [42] A2UI |
“官方仓库说明”仅代表阅读公开说明,不表示审计过整个仓库。没有实测证据的兼容能力不计为验收通过。
哪些机制直接影响我们的选择
DSH:宿主插件和生成页面是两条不同路径
安装的 worktable 插件通过宿主服务和 UI 插槽工作,自己的分屏布局由 React 实现;它不是一个可以直接双击运行的独立软件。其“生成窗口”则根据产物清单读取 HTML、URL 或文件,把内容放入窗口。页面如果只使用自身资源,可以单独托管;一旦依赖 DSH 路由、会话或插件服务,离开 DSH 就缺少这些实现。[2] dsh-worktable
另一个机制是 DSH 动态 Cordis 插件:已读发行包中,host 部分注册处理函数,client 部分由宿主提供运行环境并调用后端。它可以有真实逻辑,不只是静态展示;但受支持 API、加载生命周期及动态代码格式约束,不是“任意代码都能在任意窗口运行”。其 Node vm 使用也不能当作操作系统级安全隔离。[1] DeepSeek Harness
Hermes 与 Pi:宿主扩展可以提供复杂交互,但依赖明确
Hermes Desktop SDK 有 pane、page、sidebar、status bar、palette 等贡献点;本地插件直接在宿主环境加载,与隔离 HTML 预览是不同执行路径。Dashboard 也支持页面与 slot。可采用其明确的贡献点和生命周期概念,但不应让普通生成应用拿到宿主全部内部对象。Pi 的自定义 UI 是终端组件,说明“插件界面都是 HTML”本身也不成立。[8] Hermes 桌面插件 SDK [9] Hermes 仪表盘扩展 [3] Pi
OpenClaw:展示面板与交互应用不可混为一谈
当前 macOS widget panel 文档明确说明该面板只负责渲染;宿主集成操作在 Control UI 和 session dashboard 使用,A2UI 也属于 dashboard。不能只看同一个 canvas 名称,就把旧文档或其他界面的能力迁移到面板上。[11] OpenClaw 组件面板
MCP Apps、AG-UI、A2UI 分别解决不同问题
MCP Apps 提供可移植的 Web 资源与宿主通信合同;AG-UI 描述 Agent 和用户界面之间的事件;A2UI 让宿主根据组件目录渲染声明式数据。完整自由布局的应用适合 Web UI,常见表单适合可选声明式渲染,流式任务需要事件协议。三者均不自动提供应用安装、数据迁移和后台服务生命周期。[40] MCP Apps [41] AG-UI [42] A2UI
运行框架:独立部署不等于不依赖框架
LangGraph 的状态持久化、AgentOS 的运行 API、OpenHands 的 SDK/Agent Server 都支持将 Agent 能力用于自己的产品。应用可以独立部署,同时依赖某个运行库或服务。OpenProgram 应沿用这一依赖表达,不把“离开桌面客户端”与“删除全部 OpenProgram 依赖”混为一谈。[25] LangGraph [29] Agno / AgentOS [14] OpenHands
OpenProgram 当前实现与边界
应用运行能力复用既有 Program 来源管理、模型 Runtime、执行记录和标签页基础。本文沿用 Programs 代码结构;更广泛的比较见 框架比较。独立审查、完整验收与本地 App 的交付状态集中列在文末。
| 当前实现 | 源码 | 边界 |
|---|---|---|
| 新标签页保留四个内置入口,并读取已安装应用;点击后按实例复用应用标签。 | apps/web/components/center-tabs/new-tab-page.tsx | 项目应用支持选择项目和复用已保存绑定;隐藏与停用分开管理。 |
| 独立应用界面通过 sandbox iframe 和 MessagePort 调用实例接口。 | apps/web/components/center-tabs/application-tab-pane.tsx | 应用自行编写 HTML/CSS/JavaScript,不依赖宿主 React 组件;页面不能直接调用 owner API。 |
| 应用注册写入独立 applications/catalog.json,固定内容版本保存在应用版本目录;旧 Program 来源记录首次读取时迁移。 | openprogram/programs/_applications/catalog.py | Python 安装需要明确 trust;最终快照再次检查授权;不把进程隔离当作恶意代码沙箱。 |
| Python 操作由独立进程执行,生命周期使用既有执行记录、Attempt 和 Driver。 | openprogram/programs/_applications/service.py | 并发取消共用一次清理;保留进程树归属,主进程退出后仍可终止子进程。 |
| 模型调用绑定已有 Runtime 和 SessionNodeWriter。 | openprogram/programs/_applications/runner.py | 应用定义的模型名传入 Runtime;模型凭据不交给页面。普通 Python 调用栈不支持恢复。 |
| 实例保存业务状态、运行结果、提问及递增事件。 | openprogram/programs/_applications/state.py | 重开页面恢复数据;worker 重启标记中断。自动数据迁移、附件 API 和菜单排序未实现。 |
应用和宿主插件分开管理:既有插件可扩展宿主行为,应用通过自己的页面和实例接口运行。现有插件 loader 不提供本文的应用隔离保证;插件贡献 Application 的自动适配仍属于后续扩展。
应用架构与责任划分
名称、图标、打开、关闭视图
来源、版本、UI、操作、数据范围
自己的组件和业务交互
校验身份、操作、授权和任务
普通代码、llm()、agent()
业务数据、事件、结果与恢复
Application 是一种 Program 包,扩展已有来源注册。Plugin 是扩展宿主行为的安装单元,可以提供工具或主题;插件贡献 Application 定义的自动适配保留为扩展。不是每个插件都出现在新标签页,也不是每个 Application 都要改动宿主 UI。一个包只保留一份应用定义;后续插件适配应引用同一份定义。
普通应用只能在自己的标签页内渲染。全局工具栏、聊天编辑器、主题和系统级服务属于另一类受信宿主扩展,沿用插件权限。对应用暴露少量稳定的 API,不公开 React store、全局 session manager 或框架内部模块。应用可选用外观组件包,但标准 HTML 和独立前端构建同样有效。
第一阶段支持静态 Web 应用和带 Python 业务操作的 Web 应用。浏览器可执行的 JavaScript、Canvas、WebGL、WASM 可以用于页面;系统 GUI、GPU 驱动、任意二进制、任意语言服务不是浏览器天然能力。后续如需 Node/其他语言后端,增加明确的 runtime adapter 和依赖合同,不宣称首版支持任何程序。
包保留自己的依赖文件、测试和发布边界。发布 UI 使用构建产物,不在每次点击时运行开发服务器、安装 latest 依赖或让 Agent 再生成代码。应用没有后台操作时完全不启动 Python 进程;有操作时按需启动对应 runner。runner 是应用执行容器的逻辑角色,进程隔离与安全沙箱必须分别实现、分别标注。
最小应用合同
首版以应用清单引用 Python entrypoint 和已构建静态目录;以下字段对应当前 application.json;公开命令和 SDK 见产品文档。操作名只在 UI/进程通信边界寻址,Python 内部仍用普通函数 import 和调用,不新增第二套 Workflow 字符串调度系统。
{
"id": "local.paper-reader",
"title": "论文阅读器",
"version": "1.0.0",
"ui": { "root": "web/dist", "entry": "index.html" },
"backend": { "kind": "python", "entry": "paper_reader.app:operations" },
"scope": "project",
"capabilities": ["model.invoke", "storage.app", "files.project.read"],
"dataSchema": 1,
"operations": { "summarize": { "agent": true, "input": { "type": "object" }, "output": { "type": "string" } } }
}
静态应用省略 backend,capabilities 可为空。id 是包内稳定身份,不使用标题、绝对路径或生成它的 chat ID。安装记录关联 owner、来源、内容摘要和已选版本;应用实例由 app ID、owner 和显式 project scope 标识。应用展示偏好如隐藏与排序属于用户偏好,不写入发行包。
| 对象 | 责任与最少字段 |
|---|---|
| ApplicationDefinition | app ID、来源引用、版本/UI 资源、运行类型、操作 schema、能力需求、数据 schema。 |
| Installation | 引用已有来源记录;选中版本、启用状态、验证结果和权限决策。不是复制源码目录就算安装完成。 |
| AppInstance | owner + app ID + project scope;业务数据位置及活动运行。一个窗口不是一个数据库。 |
| View | tab ID、instance ID、UI route、正在显示的运行;可以销毁并重建。 |
| OperationRun | run ID、instance ID、操作版本、输入、身份、幂等键、状态、事件序号、结果引用。与已有执行记录关联,不复制完整 DAG。 |
跨进程操作提供输入/输出 schema。客户端不能自行指定任意 import path、源码路径或 owner;服务器根据安装记录解析。后端可信身份来自已认证连接,不相信 JSON 中的 appId 就是权限凭证。运行事件包含递增序号,客户端断线后按游标补读;结果与错误都写入持久记录。
业务状态采用按应用实例划分的 SQLite 数据库;附件 API 保留为后续扩展。数据置于当前 profile 状态目录下,由宿主使用内部生成的实例键定位。默认 profile 对应 ~/.openprogram;不在源码版本目录保存用户数据。项目路径变化只更新项目绑定,不改变实例身份。已有 Runtime 数据库保存执行事实,应用状态仅引用 run ID;不另建平行的 Agent 会话数据库。localStorage 只缓存可丢弃的视图偏好。
Python runner 使用固定版本的应用依赖环境;应用依赖不得直接安装进主 worker 环境。宿主通过已选安装记录启动允许的入口,不接受来自浏览器的任意启动命令。每次业务操作启动一个 runner,操作结束后清理所属进程树;关闭视图不取消操作。再次打开页面读取持久状态,不需要常驻应用服务。
模型与业务操作如何结合
首版论文阅读器示例接受论文文本,支持“生成摘要”和“保存批注”。保存由确定性代码完成;摘要操作进入 OpenProgram Runtime,再调用已有 llm()。PDF 导入需要应用另外实现。模型只承担需要推理的步骤,不要求每次按钮点击都先经过一次聊天。
用户按“生成摘要”和 Agent 调用该应用的 summarize 操作,都经过同一输入校验、权限和实现。是否向 Agent 暴露某项操作由应用明确声明,不能把所有内部数据库方法自动注册为工具。Agent 调用也必须绑定应用实例,不能因聊天切换而改用另一个项目的数据。
Runtime 由 runner 创建,使用应用清单指定的模型名或宿主默认配置,并绑定应用运行记录。上下文只包含操作输入与应用明确提供的数据,不随活动聊天切换。当前对话的显式导入保留为后续能力;模型配置在 Runtime 创建时解析。运行中的操作固定其应用内容版本。
前端得到任务进度和结果,不得到 provider 密钥。模型调用使用已有 Runtime 的记录与错误处理。context.ask() 产生 question 事件,用户回答绑定 run ID 与 request ID;回答只能用于该次运行当前仍在等待的问题。应用提问不引入第二套 ExecutionStatus。
数据修改应先由普通代码校验模型输出,再事务性提交。模型返回的自然语言“已保存”不是保存成功证据。对于不可幂等的外部副作用,重试必须查询已有操作记录或交给用户处理,不能因为网络超时就自动再执行一遍。
打开、后台执行、恢复与升级
打开路径
新标签页读取已验证 Application 定义 → 用户选择应用 → 解析应用实例与绑定项目 → 复用或创建应用标签 → 加载固定版本资源 → 建立能力连接 → 获取业务状态与活动运行。注册/列出应用只读 manifest,不导入应用业务代码,不发起模型请求。
任务路径
提交操作时持久化输入、幂等键和 accepted 事件,随后由既有 Attempt 管理 running。需要输入时保存 question,完成时进入 completed / failed / cancelled。关闭视图不产生 cancelled。停止任务终止所属进程树,完成清理后才返回 cancelled;迟到结果不能覆盖终态。并发修改同一业务对象使用数据库事务或版本检查,不能以前端按钮禁用代替后端并发控制。
重启路径
重新打开页面恢复视图和状态;worker 重启后,未完成运行按既有 owner-loss 规则标记 interrupted 或完成已请求的取消。保留输入、已保存进度和结果,并清楚显示中断。首版不自动续跑 Python 操作;应用可以读取已保存业务状态后显式提交新操作。
升级路径
构建候选版本 → 静态/schema 校验 → 依赖准备 → 启动与行为验证 → 数据兼容检查 → 原子切换安装记录。正在运行的操作固定旧版本,新启动操作使用新版本。旧视图和新后端必须版本一致;不允许更新静态文件时悄悄切换已加载页面的操作合同。
首版拒绝 dataSchema 或 scope 不兼容的替换,不自动执行迁移。后续迁移需要备份、验证和明确恢复流程。卸载停止相关运行并隐藏应用,保留来源、schema、scope、代码快照与业务数据;重新安装仍受同一兼容检查约束。业务数据删除 API 未提供。
隔离与可移植性
浏览器隔离是应用自由编写界面的前提。首版普通应用使用 sandbox iframe 与受限 CSP;不能复用当前无 sandbox 的同源插件页作为隔离保证。选择 opaque origin 时通过经校验的 MessageChannel/窗口握手通信;若后续使用独立 origin,也必须隔离宿主 cookie、storage 与管理 API。CORS 本身不是鉴权,iframe 本身也不是默认安全。
应用资源按安装内容摘要提供,只允许访问已发布静态目录。宿主仅向自己创建的 iframe 交付 MessagePort,并按绑定实例校验操作;不接受页面自行指定的 owner、任意 URL 或其他实例运行。前端默认不能直接访问全部 /api/*。需要联网、项目文件或设备权限时声明具体能力,服务端在每次操作重新检查,停用或卸载后撤销连接。
Python 独立进程可以隔离依赖和崩溃,但不能阻止代码直接读取宿主文件或联网。首版后端应用只支持明确获准的本地代码,不把 manifest 的能力列表宣传为恶意 Python 的安全沙箱。接纳不受信远程代码之前,必须实现平台级文件/网络限制或容器沙箱,并验证子进程、包安装脚本和继承环境。高信任宿主插件继续单独标识。
| 运行方式 | 依赖 | 设计承诺 |
|---|---|---|
| 纯静态应用 | 标准浏览器和自身资源。 | 无宿主 API 时可独立托管;数据迁移仍由应用负责。 |
| OpenProgram 内应用 | UI + 应用后端 + OpenProgram Runtime。 | 当前实现;菜单入口、模型操作、数据和任务归属一致。 |
| 独立部署,同一 runtime | 应用包 + 最小 runtime + 配置/存储。 | 架构保留边界;在实施适配与验收前不宣称可用。 |
| MCP Apps 跨宿主 | MCP server + 兼容宿主及其能力。 | 共享 UI/工具合同;OpenProgram 特定后台运行 API 不自动可移植。 |
| 完全无 OpenProgram 依赖 | 应用自己提供模型、任务、存储等替代实现。 | 不自动保证;必须单独构建和测试。 |
采用、调整与暂不采用
| 选择 | 依据 | 具体处理 |
|---|---|---|
| 采用:标准 Web 应用界面 | [40] MCP Apps [39] OpenAI Plugins(原 Apps SDK 路径) | 自由前端构建;主题组件可选。用稳定接口连接宿主。 |
| 采用:明确贡献与生命周期 | [8] Hermes 桌面插件 SDK [1] DeepSeek Harness | 应用贡献限制在自己的页面;宿主全局 UI 插槽留给受信插件。 |
| 采用:状态与页面分开 | [25] LangGraph [29] Agno / AgentOS | 业务状态和运行记录持久化;不以 localStorage 或聊天历史作唯一数据库。 |
| 调整:MCP Apps 集成 | [40] MCP Apps | 保留标准 bridge 适配,先实现本地应用合同;标准工具调用不足的持久任务以明确宿主扩展暴露,不能谎称标准保证。 |
| 调整:UI 事件流 | [41] AG-UI | 复用既有事件语义,需要跨框架接入时做 AG-UI adapter,避免重建内部任务系统。 |
| 可选:声明式 UI | [42] A2UI | 适合确认单和普通表单;不规定所有应用只能使用内置组件。 |
| 暂不采用:任意动态代码直接进入宿主 | 宿主稳定性与普通应用隔离要求。 | 代码先成为可审查、可构建的应用版本,再注册运行;不把 eval 作为默认发布机制。 |
| 暂不采用:完整市场、任意语言 runner、原生 GUI 嵌入 | 不影响已经明确的首版使用路径。 | 先证明安装—打开—操作—恢复的合同;不把发布平台做成首版依赖。 |
实施分解与验收
此节是已批准的实施范围。阶段 1–4 已通过独立审查、完整检查与默认 App 验收;阶段 5 保持未实现。每一步必须从公开入口验证,不能仅凭注册器单测宣称用户可以使用应用。现有 Programs 与插件兼容测试应随相关改动一起运行。
| 阶段 / 主要位置 | 交付行为 | 必要验收 |
|---|---|---|
| 1. 应用定义与来源 programs/_programs.py、plugins manifest/loader、应用目录 API | 一份定义、一份来源身份、验证与启用状态;元数据发现不执行代码。 | 重复 ID、无效入口、缺失来源、停用后残留;未安装应用不出现在菜单。 |
| 2. 菜单与页面 new-tab-page.tsx、center-tabs state、app-shell.tsx、应用页面组件 | 点击固定入口打开静态应用,复用标签并绑定实例;隔离页面资源。 | 从四入口页面增加两个应用;键盘打开、刷新恢复、两个项目互不串数据;iframe 无法访问宿主状态。 |
| 3. 业务操作与 Runtime server 应用路由、Program 执行适配与事件 | Python 操作进入已有模型/Workflow 运行合同;取消、提问、结果持久化。 | UI 与 Agent 调用相同操作;模型配置生效、凭据不出前端、重复提交不重复写入。 |
| 4. 完整生命周期 来源版本、应用状态存储与 runner 管理 | 依赖准备、后台任务、重启中断处理、版本固定、数据迁移与卸载。 | 关闭页后任务继续;worker 中断可解释;升级期间旧任务不换代码;迁移失败不损坏旧数据。 |
| 5. 兼容与独立部署 独立 adapter,按需求增加 | MCP Apps、最小 runtime 服务部署;之后再考虑非 Python runner。 | 相同 UI/操作在明确支持的第二种宿主或部署目标实际运行;不以截图代替。 |
阶段 1–4 合起来才是可称为“完整应用支持”的第一版。阶段 2 单独完成只能称为静态应用入口。第一版使用三种验收应用:不调用模型的本地计算器、保存批注并生成摘要的论文阅读器、可显示进度并处理重启中断的批量文件分析。验收数据必须包括再次打开、重启、重复点击和模型失败。
性能目标以可测条件规定:列出新标签页不启动任何应用业务进程;已有应用重复点击不产生第二个同 scope 实例;打开应用不触发生成代码或模型请求;大产物按引用读取而非塞入每条事件。具体延迟和资源预算在首个完整样例中测量,当前没有基准数据,不给出未经测量的毫秒或周数承诺。
实现状态与证据限制
阶段 1–4 已实现:应用注册与固定版本、新标签页入口、独立 UI 与能力 bridge、Python 操作、实例数据和执行记录。独立规范审查、质量审查和完整检查通过;默认 App 已验证菜单启动计算器、笔记保存后重新打开、Python 文件分析以及重启后恢复应用标签与结果。模型成功与失败、取消、重复提交和运行中断由集成测试验证,未将真实模型服务可用性视为离线测试保证。独立部署与 MCP Apps 适配保持未实现。
操作状态使用现有 ExecutionStore;模型记录使用既有 SessionNodeWriter,保存到应用运行目录。UI 通过 MessagePort 使用实例限定的接口;opaque-origin 页面以单版本资源凭据加载相对模块,凭据只允许读取 UI 资源。Python 每个内容版本使用独立环境,依赖宿主框架;首版用 context.ask() 表达应用提问,worker 停止后报告 interrupted,不恢复 Python 调用栈。JSON 状态上限为 4 MiB,事件上限为 1 MiB;附件管理、自动 schema 迁移、对话上下文选择与菜单手动排序仍未实现。产品接口见 应用文档。
DSH 细节基于已安装的 0.1.5-rc.1 发行包,worktable 源码版本为 0.3.3。二者未做完整兼容性验收;GitHub 当前默认分支也可能继续变化。其动态插件加载机制与 worktable 的产物页面机制分别引用,不用一个版本的演示代表另一个版本的能力。
来源索引
框架事实使用项目官方文档、官方仓库或本地公开发行包。链接支持其附近的具体描述,不代表对该项目所有实现的背书。OpenProgram 文件链接指向 main;本次核查的本地版本见独立交付记录。
- DeepSeek Harnesshttps://github.com/deepseek-ai/deepseek-harness
- dsh-worktablehttps://github.com/Aisland-SJL/dsh-worktable
- Pihttps://github.com/earendil-works/pi/blob/main/packages/coding-agent/docs/extensions.md
- OpenCodehttps://opencode.ai/docs/plugins/
- Codex App Serverhttps://learn.chatgpt.com/docs/app-server
- Claude Codehttps://code.claude.com/docs/en/plugins-reference
- Hermeshttps://hermes-agent.nousresearch.com/docs/developer-guide/plugins/
- Hermes 桌面插件 SDKhttps://hermes-agent.nousresearch.com/docs/developer-guide/desktop-plugin-sdk
- Hermes 仪表盘扩展https://hermes-agent.nousresearch.com/docs/user-guide/features/extending-the-dashboard
- OpenClawhttps://docs.openclaw.ai/tools/plugin
- OpenClaw 组件面板https://docs.openclaw.ai/platforms/mac/canvas
- Gemini CLIhttps://geminicli.com/docs/extensions/
- goosehttps://block.github.io/goose/index.html
- OpenHandshttps://docs.openhands.dev/sdk
- DeerFlowhttps://github.com/bytedance/deer-flow
- Aiderhttps://aider.chat/docs/
- mini-SWE-agenthttps://github.com/SWE-agent/mini-swe-agent
- Mistral Vibehttps://github.com/mistralai/mistral-vibe
- Clinehttps://docs.cline.bot/mcp/mcp-overview
- Roo Codehttps://roocodeinc.github.io/Roo-Code/features/mcp/using-mcp-in-roo/
- Continuehttps://docs.continue.dev/customize/deep-dives/mcp
- Cursorhttps://cursor.com/docs
- Windsurf / Devin Desktophttps://docs.devin.ai/desktop/cascade/mcp
- Claude Agent SDKhttps://code.claude.com/docs/en/agent-sdk/overview
- LangGraphhttps://docs.langchain.com/oss/python/langgraph/overview
- Deep Agentshttps://docs.langchain.com/oss/python/deepagents/overview
- Google ADKhttps://adk.dev/
- Microsoft Agent Frameworkhttps://learn.microsoft.com/en-us/agent-framework/overview/
- Agno / AgentOShttps://docs.agno.com/agent-os/introduction
- CrewAIhttps://docs.crewai.com/en/concepts/flows
- PydanticAIhttps://pydantic.dev/docs/ai/integrations/ui/overview/
- Mastrahttps://mastra.ai/docs
- NeMo Agent Toolkithttps://github.com/NVIDIA/NeMo-Agent-Toolkit
- smolagentshttps://github.com/huggingface/smolagents
- Difyhttps://github.com/langgenius/dify-plugin-daemon
- Open WebUIhttps://docs.openwebui.com/features/extensibility/plugin/
- Chainlithttps://docs.chainlit.io/api-reference/elements/custom
- Chainlit 自定义 React 前端https://docs.chainlit.io/deploy/react/overview
- OpenAI Plugins(原 Apps SDK 路径)https://developers.openai.com/plugins/build/chatgpt-ui
- MCP Appshttps://modelcontextprotocol.io/extensions/apps/overview
- AG-UIhttps://docs.ag-ui.com/introduction
- A2UIhttps://a2ui.org/