HARNESS 调研 · 应用设计

已创建的应用,
在新标签页直接打开

界面自由编写,业务数据独立保存,模型与程序能力通过明确的运行合同调用。

应用运行与管理体系已实现 / 38 个框架、产品或协议条目 / 42 个来源入口

按使用样例实施: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 或安装路径放在启动按钮上。管理入口负责隐藏、重命名显示名称、卸载和查看错误;隐藏不删除应用数据。

OpenProgram · 交互示意
▤ 文件
+ 新建聊天
◎ 浏览器
›_ 终端

上方仅演示“从新标签页打开已存在应用”,不调用模型、不安装软件。四个内置项目作为背景展示;两个应用按钮和返回按钮可以操作。

同一应用在同一项目默认复用已打开标签页;不同项目可以分别打开,数据范围明确分开。新标签页没有活动项目时,先使用应用已绑定的项目;应用要求项目而尚未绑定时,首次打开才选择。应用不能跟随任意另一个聊天标签页的 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.pyPython 安装需要明确 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 的自动适配仍属于后续扩展。

应用架构与责任划分

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 标识。应用展示偏好如隐藏与排序属于用户偏好,不写入发行包。

对象责任与最少字段
ApplicationDefinitionapp ID、来源引用、版本/UI 资源、运行类型、操作 schema、能力需求、数据 schema。
Installation引用已有来源记录;选中版本、启用状态、验证结果和权限决策。不是复制源码目录就算安装完成。
AppInstanceowner + app ID + project scope;业务数据位置及活动运行。一个窗口不是一个数据库。
Viewtab ID、instance ID、UI route、正在显示的运行;可以销毁并重建。
OperationRunrun 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;本次核查的本地版本见独立交付记录。

  1. DeepSeek Harnesshttps://github.com/deepseek-ai/deepseek-harness
  2. dsh-worktablehttps://github.com/Aisland-SJL/dsh-worktable
  3. Pihttps://github.com/earendil-works/pi/blob/main/packages/coding-agent/docs/extensions.md
  4. OpenCodehttps://opencode.ai/docs/plugins/
  5. Codex App Serverhttps://learn.chatgpt.com/docs/app-server
  6. Claude Codehttps://code.claude.com/docs/en/plugins-reference
  7. Hermeshttps://hermes-agent.nousresearch.com/docs/developer-guide/plugins/
  8. Hermes 桌面插件 SDKhttps://hermes-agent.nousresearch.com/docs/developer-guide/desktop-plugin-sdk
  9. Hermes 仪表盘扩展https://hermes-agent.nousresearch.com/docs/user-guide/features/extending-the-dashboard
  10. OpenClawhttps://docs.openclaw.ai/tools/plugin
  11. OpenClaw 组件面板https://docs.openclaw.ai/platforms/mac/canvas
  12. Gemini CLIhttps://geminicli.com/docs/extensions/
  13. goosehttps://block.github.io/goose/index.html
  14. OpenHandshttps://docs.openhands.dev/sdk
  15. DeerFlowhttps://github.com/bytedance/deer-flow
  16. Aiderhttps://aider.chat/docs/
  17. mini-SWE-agenthttps://github.com/SWE-agent/mini-swe-agent
  18. Mistral Vibehttps://github.com/mistralai/mistral-vibe
  19. Clinehttps://docs.cline.bot/mcp/mcp-overview
  20. Roo Codehttps://roocodeinc.github.io/Roo-Code/features/mcp/using-mcp-in-roo/
  21. Continuehttps://docs.continue.dev/customize/deep-dives/mcp
  22. Cursorhttps://cursor.com/docs
  23. Windsurf / Devin Desktophttps://docs.devin.ai/desktop/cascade/mcp
  24. Claude Agent SDKhttps://code.claude.com/docs/en/agent-sdk/overview
  25. LangGraphhttps://docs.langchain.com/oss/python/langgraph/overview
  26. Deep Agentshttps://docs.langchain.com/oss/python/deepagents/overview
  27. Google ADKhttps://adk.dev/
  28. Microsoft Agent Frameworkhttps://learn.microsoft.com/en-us/agent-framework/overview/
  29. Agno / AgentOShttps://docs.agno.com/agent-os/introduction
  30. CrewAIhttps://docs.crewai.com/en/concepts/flows
  31. PydanticAIhttps://pydantic.dev/docs/ai/integrations/ui/overview/
  32. Mastrahttps://mastra.ai/docs
  33. NeMo Agent Toolkithttps://github.com/NVIDIA/NeMo-Agent-Toolkit
  34. smolagentshttps://github.com/huggingface/smolagents
  35. Difyhttps://github.com/langgenius/dify-plugin-daemon
  36. Open WebUIhttps://docs.openwebui.com/features/extensibility/plugin/
  37. Chainlithttps://docs.chainlit.io/api-reference/elements/custom
  38. Chainlit 自定义 React 前端https://docs.chainlit.io/deploy/react/overview
  39. OpenAI Plugins(原 Apps SDK 路径)https://developers.openai.com/plugins/build/chatgpt-ui
  40. MCP Appshttps://modelcontextprotocol.io/extensions/apps/overview
  41. AG-UIhttps://docs.ag-ui.com/introduction
  42. A2UIhttps://a2ui.org/