Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,16 @@ Runtime 接口,不经过对外能力门面。只有某个具体 DTO 同时出
| 对外能力门面 | 暴露真实消费者需要的窄用例、只读状态、事件和类型化错误 | 暴露内部 manager、插件 Host ABI、任意服务查找或产品 UI。 |
| Host Adapter | 把门面映射为某宿主的 MCP、Skill、Plugin、Hook、SDK 或 Server 调用 | 声称突破宿主未提供的生命周期、状态或替换能力。 |

当前外部 Subagent 输入切片落实了上述边界:`contracts/product-domains` 只定义来源无关的 Subagent contribution、
provenance、兼容状态、摘要和冲突契约;OpenCode adapter 独立维护本生态来源与字段语义;生命周期协调器隔离 provider
失败并发布不可变候选;现有 AgentRegistry/Task owner 再解析模型、工具、权限上限和同名路由。产品主体不读取
OpenCode 类型,也不通过统一 agent JSON 理解未来 Codex/Claude Code。

fresh external invocation 在 admission 前绑定逻辑名到 runtime generation,并把 generation lease 传入前台或后台
调度请求。来源更新或撤下只改变后续 admission,不修改已接受调用的 prompt/model/tool 绑定;安全策略收紧仍由现有
owner 按原规则优先执行。当前外部 Subagent 不支持 session follow-up,结果与管理 surface 必须明确标为 single-run,
不能用持久化 session 绕过重新审批或 generation 解析。

对外能力门面不等于 Agent Runtime SDK 的全部接口。SDK 可以包含构建与运行 Agent 所需的底层能力;宿主 adapter
只消费当前场景需要的最小子集。外部产品只需要调用一个 BitFun workflow 时,不应被迫嵌入完整 Agent Runtime。

Expand Down
37 changes: 28 additions & 9 deletions docs/architecture/extensions/external-ai-work-sources-design.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ SDK 或 Server 输出到外部宿主,以及内部 Provider Slot、状态、事

本文同时记录当前可用纵向切片与目标架构。当前 BitFun 已具备通用外部来源目录和生命周期协调器,并通过
OpenCode Prompt Command 适配器接入本地用户全局/项目来源;Desktop 可查看、刷新、抑制和处理跨来源冲突,
CLI/TUI 可列出并执行 prompt-only Command。第二条纵向切片已让受支持的单文件 OpenCode `.js` standalone Tool 经静态
预览、来源/能力确认和同名冲突选择后进入现有 Tool Runtime;Desktop 与 CLI/TUI 使用同一决策状态。完整
TypeScript/Bun、包依赖、package plugin、Codex/Claude Code 适配器和 Subagent 仍属于后续阶段,不能因来源被识别
就宣称已经可用。
交互式 TUI(ChatMode)可列出并执行 prompt-only Command。第二条纵向切片已让受支持的单文件 OpenCode `.js` standalone Tool 经静态
预览、来源/能力确认和同名冲突选择后进入现有 Tool Runtime;Desktop 与交互式 TUI(ChatMode)使用同一决策状态。第三条纵向
切片已把 OpenCode 全局/项目 Subagent 的安全子集通过独立 provider 契约接入现有 Subagent owner:首次启用与
同名冲突使用非阻塞决策,fresh 调用固定不可变 generation,更新和撤下不会静默切换到同名实现。完整
TypeScript/Bun、包依赖、package plugin、Codex/Claude Code 适配器、primary agent 替换和外部 Subagent 续接仍属于
后续阶段,不能因来源被识别就宣称已经可用。

## 1. 产品判断与竞品启示

Expand Down Expand Up @@ -56,7 +58,7 @@ TypeScript/Bun、包依赖、package plugin、Codex/Claude Code 适配器和 Sub

### 3.1 首次发现

发现始终在后台进行。Desktop、CLI/TUI 和未来 Web 入口消费同一只读来源状态,但按宿主展示:
发现始终在后台进行。Desktop、交互式 TUI(ChatMode)和未来 Web 入口消费同一只读来源状态,但按宿主展示:

```text
已发现 OpenCode 工作内容
Expand All @@ -74,6 +76,8 @@ TypeScript/Bun、包依赖、package plugin、Codex/Claude Code 适配器和 Sub
读取凭据或主动联网;提示可以稍后处理。
- 当前阶段范围外的 TypeScript、依赖型 Tool 和 package plugin 只进入“已发现,静态预览”清单,不进入模型可调用
集合;受支持 JS Tool 也必须在明确启用前保持同一状态。
- 外部 Subagent 即使只是声明文件,也会把 prompt、模型和工具集合带入一次独立 agent 调用,因此按当前行为与能力
包络确认;列表和 IPC 只显示描述、来源、模型、工具和诊断摘要,不传输 prompt 正文。
- 全局来源首次在当前执行域识别时提示一次;项目来源按工作区提示。相同全局来源不能在每个项目重复轰炸用户。
- “撤销已应用内容”对持续兼容来源表示在用户选择的当前项目或当前执行域内抑制对应来源/资产并重新计算下一
来源或产品默认;后续 watcher 更新不得绕过该偏好重新应用。该操作不写回外部文件,也不同于显式导入的字段级撤销。
Expand All @@ -84,7 +88,7 @@ TypeScript/Bun、包依赖、package plugin、Codex/Claude Code 适配器和 Sub

| 信息 | 产品要求 |
|---|---|
| 来源 | 产品、规范化位置、用户全局/项目/工作区作用域、实际执行域;敏感路径默认缩略显示。 |
| 来源 | 产品、规范化位置、用户全局/项目/工作区作用域、实际执行域;Agent 普通视图只接收 `<workspace>/…`、`~/.config/…` 或 `<remote>/…` 等安全标签,不传绝对用户路径。 |
| 内容 | 配置、Rules、Agents、Skills、Commands、MCP、插件、工具等类别与数量。 |
| 状态 | 已发现、已应用、可用、需确认、更新中、沿用上一版本、部分受限、暂时过期、已移除/已停用或不可用。 |
| 变化 | 最近成功读取时间、候选摘要、已应用摘要、权限或能力变化。 |
Expand Down Expand Up @@ -130,6 +134,14 @@ TypeScript/Bun、包依赖、package plugin、Codex/Claude Code 适配器和 Sub
| L2 受归属模块保护的外部能力 | 可执行 Skill/Command、远程 Reference、MCP、LSP、Formatter、Provider 连接 | 发现后进入“需确认”;由真实归属模块展示命令、网络、凭据和作用域后启用。 |
| L3 任意第三方代码 | JS/TS Tool、服务插件、Hook、TUI target、动态 import | 发现但不 import;首次按来源/target 启用时说明执行用户、工作目录和直接文件/网络/进程的粗粒度执行包络,不能承诺 import 前已知全部动态贡献。 |

OpenCode Subagent 属于 L2:adapter 只读取声明,不执行外部代码;激活仍需确认实际模型、工具、执行域和来源谱系。
仅 description 等 catalog 文案变化不扩大包络,不重复询问;prompt 行为、provenance、模型或工具变化必须重新确认。
生态 adapter 只提交类型化的模型请求,不能把 `provider/model` 等来源语法交给通用 owner 解析。Subagent owner 在审批
前将请求物化为唯一、已启用的具体模型,并形成“配置 ID + 运行配置指纹”的不可变绑定;`inherit`、`primary`、`fast`、
`auto`、`default` 等字符串在此绑定中都是普通配置 ID,不能再次经过模型选择器解释。无法唯一确定时保持不可用。provider、
模型名、endpoint 或其他影响运行身份的配置在同一 ID 下变化,也会重建未来 generation 并产生新的审批决策;generation
lease 保留旧绑定事实,执行入口若发现当前配置与旧指纹不一致则安全失败,不能静默改用新配置或父会话模型。

确认结果分成两层:来源级加载偏好按“来源限定身份 + target + 执行域 + 更新策略”保存,并明确作用于当前项目
还是当前执行域内所有已通过来源校验的项目;项目/工作区实例只作为“有效来源图 + 粗粒度执行包络 + 已知贡献
摘要”的重新求值上下文,不形成第二个确认键。选择全局作用域后,跨项目本身不重复询问;只有新实例使执行包络、
Expand Down Expand Up @@ -160,6 +172,8 @@ TypeScript/Bun、包依赖、package plugin、Codex/Claude Code 适配器和 Sub
```

在途调用固定使用发起时的激活代次。新调用只在切换完成后使用新代次;旧代次的迟到响应和贡献引用在退出后失效。
Subagent 通过随调度请求传递的 generation lease 实现这一点;路由撤下后有 lease 的精确运行定义保留到调用结束,
无 route 且无 lease 的旧定义立即回收。该机制不允许新调用使用已删除或已撤销的来源。

文件观察事件不是业务事实。协调器先按来源聚合连续 create/rename/write/remove 事件,并在可配置的文件稳定窗口后
重新扫描完整来源图;编辑器的原子保存不能被误判成删除后重装。用户显式停用、组织策略收紧或安全撤销不等待
Expand Down Expand Up @@ -217,6 +231,7 @@ flowchart LR
| 文件观察服务 | 提供可订阅、去抖的文件变化事实 | 解释生态路径、决定优先级、提交业务状态。 |
| 本地 JSON 存储服务 | 提供跨进程锁、锁内读改写和严格同卷原子替换等通用文件能力;替换失败时保留旧文件 | 定义外部来源偏好 schema、冲突策略或生态语义。 |
| 共享生命周期协调器 | 调用已注册 provider、生成不可变候选、按 provider 原子替换、保留隔离诊断,并请求能力 owner 切换 | 按生态 ID 分支业务行为、解析生态文件、直接提交配置、工具、权限或界面状态。 |
| 产品展示投影 | 按作用域、工作区或用户目录关系统一生成安全来源位置,清理可见诊断文本中的已知绝对路径,并按 `Source / Command / Tool / Subagent` 资源类型路由诊断 | 让 GUI/TUI 解析 provider 诊断码前缀、识别 `.opencode`、`.claude` 等私有目录结构,或接收原始用户/工作区路径。 |
| 冲突解析 | 对独立 provider 或产品本地能力的同名候选建立版本敏感指纹;未选择时不激活,选择后只在指纹不变时复用 | 用 adapter 优先级静默覆盖另一生态或本地能力,或把选择写回外部文件。 |
| 激活策略与各能力 owner | 根据风险、用户选择、组织上限和执行域决定自动应用、等待确认或限制 | 修改生态加载顺序或把策略拒绝伪装成解析失败。 |
| Runtime Configuration Service | 应用兼容配置视图,执行显式导入、冲突预览、原子写入和撤销 | 读取凭据值或加载插件代码。 |
Expand Down Expand Up @@ -278,8 +293,8 @@ Command;明确缺失且未被标记失败的 Command 是稳定删除。产品
4. 含 `!shell`、`@file`、`{env:...}`、`{file:...}`、`agent`、`model`、`variant` 或 `subtask` 等未接通语义的命令标记为“部分受限”,不做
静默忽略后的部分执行。
5. Desktop 提供统一来源状态、刷新、按执行域抑制/恢复和冲突候选选择;首次 provider 扫描完成前显示中性检查状态,
不把暂时空目录误报为最终空结果;已经选择且指纹未变化的冲突退出待处理区。CLI/TUI 使用同一目录列出和执行
Command;跨 provider 候选以来源限定别名供 CLI 用户直接选择,同次选择也解析本地同名冲突。发现或确认不阻塞
不把暂时空目录误报为最终空结果;已经选择且指纹未变化的冲突退出待处理区。交互式 TUI(ChatMode)使用同一目录列出和执行
Command;跨 provider 候选以来源限定别名供 TUI 用户直接选择,同次选择也解析本地同名冲突。发现或确认不阻塞
普通聊天输入;发现未完成时未限定 slash 别名不猜测冲突结果,显式 `/builtin:<name>` 仍可立即执行。执行域全局偏好
使用独立偏好文件、跨进程锁和严格原子替换,并在查询、刷新和执行前重新读取,使并行 Desktop/CLI 进程不会继续使用
另一进程已停用的来源或丢失并发选择。Desktop IPC 仅返回设置页所需摘要,不携带 Prompt Command 模板正文。
Expand All @@ -295,7 +310,7 @@ Command;明确缺失且未被标记失败的 Command 是稳定删除。产品
3. 内置、MCP 与外部同名 Tool 使用包含候选身份和内容版本的指纹;选择前保留已有本地实现,不按注册顺序静默覆盖。
候选集合由已识别定义而非成功加载结果计算;候选更新、暂不可用或删除后重新选择,已选外部实现失效时保持
unavailable,不静默回退同名本地实现。其他无关 Tool 和生态不受影响。
4. Desktop 提供完整审核卡、主动停用/重新审核和冲突候选;CLI/TUI 状态栏只做非阻塞提示,`/external-tools`
4. Desktop 提供完整审核卡、主动停用/重新审核和冲突候选;交互式 TUI(ChatMode)状态栏只做非阻塞提示,`/external-tools`
以编号映射稳定 key 完成启用、保持停用、冲突选择和刷新。普通聊天输入和无关会话不等待用户处理。
5. 每个 target 使用一个持久 Node worker,支持 load/invoke、`AbortSignal` 取消、500 ms 宽限后的 target 级硬终止、
30 秒请求期限和 dispose;产品配置的更短外层期限丢弃调用 future 时也会终止 worker,并在终止完成前保持 target
Expand Down Expand Up @@ -324,6 +339,10 @@ Command;明确缺失且未被标记失败的 Command 是稳定删除。产品
- 持续来源撤销后不会被下一次 watcher 更新重新应用;当前项目与整个执行域的抑制范围可验证。
- 同名外部候选和产品本地能力在用户选择前均不会被静默覆盖;选择在候选内容版本和参与集合不变时不重复询问,
任一候选更新、删除或参与集合变化后重新进入待选择,即使变化后只剩一个实现也不静默切换。
- 冲突谱系对 0/1/N 个当前参与者都生成当前指纹;自动更新谱系或将旧选择改为“需重选”时,与用户选择一样原子推进
`preference_revision`。跨进程旧 revision 的操作必须返回 stale,不得重新写入旧授权或旧候选。
- GUI/TUI 的外部 Agent 冲突选择在同一上下文中展示将被原子批准的模型、工具、执行域、安全来源、兼容影响和恢复动作;
同工作区决策串行化,成功后读取权威快照,不以较旧整表覆盖无关的 Command/Tool 新状态。
- 冲突偏好按执行域与命令族只保留当前指纹,并以去重候选身份标记曾发生冲突;连续内容更新不会按历史指纹线性膨胀。
- 显式导入的字段级预览、冲突、撤销和凭据脱敏可验证。
- 当前只支持静态预览的资产不会被产品文案误报为已应用或可执行;支持子集与完整 OpenCode 兼容不会混写。
Expand Down
Loading
Loading