OpenBitFun Agent SDK 产品与宿主架构设计

September 4, 2026 · View on GitHub

本文定义 OpenBitFun Agent SDK 的公开产品心智、与 GUI/TUI/Headless CLI/ACP/Server 的关系、内部 SDK Host 边界,以及对外发布前必须满足的能力和兼容性门槛。智能体内核和 Rust crate 归属继续由 agent-runtime-services-design.md 定义;产品级接口边界由 product-architecture.md 定义;CLI/TUI 体验由 cli-product-line-design.md 定义;扩展能力导入和宿主适配由 capability-runtime-integration-design.md 定义;多个第一方界面与 SDK/CLI 并存时的 Runtime 部署、共享和进程隔离由 agent-runtime-deployment-design.md 定义。

本文只记录长期产品心智、架构边界和发布门槛。当前代码中的 agent-runtime::sdk 是供 OpenBitFun 内部入口和受控 Rust 嵌入使用的低层 Rust Runtime SDK; interfaces/sdk-hostapps/sdk-host 是本地协议和独立 Host 进程的实现候选;sdk/typescript 是仓库内私有的 TypeScript 垂直切片,用于验证 managed Host、Query、显式 Session、取消、终态和错误语义。其 internal wire 类型与 runtime validator 均由 Rust Host 协议生成,不构成公开 API。该切片对 Query 事件、终态聚合、JSON-RPC pending request 和载体写队列分别设置条目与字节预算;Windows Host 通过 services-core 的 kill-on-close Job Object owner 持有后代进程, Unix managed client 通过独立进程组回收 Host 树。Python binding、平台原生 Host 包、安装与签名链路尚未交付,握手仍返回 not_delivered,因此不能据此宣称公开或 Preview SDK 已交付。

1. 最终决策

OpenBitFun 不选择“复制 Claude”“复制 OpenCode”或“复制 Codex”中的任一条单一路线,而是按不同问题采用各自已经验证的做法:

问题采用的成熟做法OpenBitFun 决策
用户如何运行 AgentClaude Agent SDK 的 Agent、Session、消息流、Tool、MCP、Permission、Hook 心智公开 API 使用行业常见 Agent 概念,不暴露内部端口、协议和 Product Assembly
如何让多个产品入口共享能力OpenCode 的 Server/Core 多客户端模式,Codex App Server 的 rich-client 边界所有入口调用同一 Agent Runtime API;入口是同级 adapter,不相互依赖
SDK 如何保持简洁Codex SDK 的精选 Thread/Turn 用例,而不是全量管理 API公开 SDK 只提供 Agent 应用所需的高层用例,不直接镜像内部或 Server 全部路由
本地 Runtime 如何交付Claude/Copilot SDK 管理匹配原生 runtime,Codex App Server 的握手与 schema 纪律SDK 默认管理匹配的本地 openbitfun-sdk-host;用户不需要安装 CLI
多语言如何一致Copilot SDK 的单协议、多语言包、协议版本范围和 codegen drift checkPython/TypeScript 是同一 SDK 的语言绑定,共用一个 Host 协议和一致性套件
外部开发者如何定制界面Vercel AI SDK UI 的状态/transport 分离与 AI Elements 的 copy-source 组件Preview 提供最小参考应用;有真实复用后再抽取可选组件层,不形成第二套“UI SDK”

一句话定义:

OpenBitFun Agent SDK 是同一 OpenBitFun Agent Runtime 面向应用开发者的公开开发接口;它不是新的 Runtime, 不是 CLI/Server 的别名,也不是 GUI/TUI 的底层依赖。

最终只向普通用户和外部开发者呈现三种产品选择:

flowchart LR
  Need{"你要做什么?"}
  Need -->|"人工交互"| Product["OpenBitFun GUI / TUI"]
  Need -->|"shell、一次性任务、普通 CI"| CLI["openbitfun exec"]
  Need -->|"应用、服务、IDE、复杂自动化"| SDK["OpenBitFun Agent SDK"]

ACP、Server、SDK Host、跨进程协议(wire protocol)和 Rust Runtime SDK 是互操作或内部工程边界, 不应成为首次使用时的产品选项。

2. 竞品复核与客观取舍

本节按 2026-07-24 的官方文档和公开代码核对。OpenCode 代码基线为 2ea4bb793e, Codex 代码基线为 f61b51ddd9。 滚动版本的新能力不自动进入 OpenBitFun 稳定承诺;发布前必须固定对比版本和 fixture。

2.1 产品与生态对比

维度Claude Agent SDKOpenCode SDK / ServerCodex SDK / App ServerCopilot SDK对 OpenBitFun 的启发
公开心智query()、Session、消息流、Tool/MCP/Hook/Permissiontype-safe Server client、资源和路由精选 Thread/Turn SDK;rich client 使用 App ServerSession、Message、Tool,多个语言绑定Agent SDK 应是高层应用 API,不是内部资源目录
Runtime 交付Python/TS 包携带原生 Claude Code binarySDK 可启动 PATH 中的 Server,也可连接已有 ServerTS SDK 包装 CLI JSONL;App Server 提供更完整协议SDK 通过 JSON-RPC 管理 CLI server;部分语言包携带 CLI安装 SDK 后应得到匹配 Host,但 CLI 与 SDK Host 不能混为一个产品
能力深度内置 Tool、MCP、Hook、权限、Subagent、Skill、Plugin、Session、用量Project/Session/File/TUI/MCP/Provider 等广泛 Server APISDK 精简;App Server 有审批、动态工具、事件、配置和稳定/实验分层Session、工具、Hook、权限、事件等经协议开放GA 能力下限参考 Claude,协议纪律参考 Codex/Copilot
生态发展官方 Python/TS SDK 和完整能力文档;生态围绕 Claude Code 配置与插件开源 Core/Server、Provider/Plugin 生态及 TUI/Web/Desktop/IDE 多客户端开源 Runtime/App Server 快速演进;TS SDK 走 CLI JSONL,Python SDK 绑定匹配 Runtime/App Server六种语言包、统一协议和各语言 registry首版聚焦 Python/TS,但合同从第一天按可增加语言设计;不把某一语言实现当规范
多客户端/UISDK 示例为主,官方不提供通用 UI SDKTUI/Web/Desktop/IDE 共享 Server;SDK 可控制 TUIApp、CLI、SDK 分层;App Server 面向 rich client面向各语言应用,无统一组件层OpenBitFun 第一方界面直接用 Runtime API,外部 UI 经开发者后端使用 SDK
多语言Python/TypeScript,部分能力存在语言时差官方主要 JS/TS,OpenAPI 可生成其他客户端TS 与 Python 当前底层形态不同TS/Python/Go/.NET/Java/Rust,共用协议版本不能让 Python/TS 各写一套 transport 和行为
可定制程度callback、Tool、Hook、MCP、Agent/Skill/Plugin 配置Server 全资源控制和插件生态,最开放精选 SDK 较克制,App Server 更底层多语言自定义 Tool/Hook公开 API 保持精选;高级资源管理通过明确 capability 增量开放
发布渠道npm、PyPI,包内携带 binarynpm SDK;Server 由 OpenCode 安装提供npm SDK、PyPI SDK/Runtime、Codex CLInpm、PyPI、NuGet、Go module、Maven、crates.io语言包走原生 registry;Host 版本必须与 SDK 可验证匹配

2.2 各产品最值得采用和不应照搬的部分

产品采用不照搬
Claude行业已形成的 Agent SDK 能力心智、第一次调用体验、语言内 callback包名、类名、字段名、Hook ABI 和 Claude 专属配置;不承诺 import-compatible
OpenCode一个 Core/Server 服务多个客户端、managed/client-only 两种连接方式、OpenAPI/codegen 思路全量 Server route 直接成为公开 SDK;不让浏览器或第三方拿到无界本机管理接口
Codex精选 SDK、Thread/Turn/Event 分层、初始化/能力协商、稳定/实验 schemaTypeScript 与 Python 使用不同底层 transport;不让公开 SDK退化成 CLI JSONL parser
Copilot单一 JSON-RPC 合同、多语言 conformance、协议版本范围、CLI/SDK feature matrix不让 CLI app 成为 OpenBitFun CLI 的隐藏 SDK server;不接受不同语言安装体验长期分裂
Vercel AI SDK/AI ElementsUI state/transport 分离、组件可组合、copy-source 定制不把 React 组件、框架 Hook 或浏览器 transport 塞进 Agent SDK 核心包

2.3 OpenBitFun 的能力基线

“至少与 Claude Agent SDK 等价”是 GA 的能力下限之一,但不是架构只能以 Claude 为中心。OpenBitFun 使用三组相互独立的门槛:

  1. Agent 能力门槛:固定一个 Claude Agent SDK 稳定版本,核心稳定能力不得静默缺失。
  2. 协议与多客户端门槛:采用 Codex/Copilot 式初始化、能力协商、schema、稳定/实验和跨语言一致性检查。
  3. 定制化门槛:参考 OpenCode 和 Vercel,允许应用与界面定制,但不把内部 Server API 或第一方 UI 固化成 SDK ABI。
flowchart LR
  Claude["Claude Agent SDK\nAgent 能力与开发者心智"] --> Capability["Agent 能力门槛"]
  Codex["Codex App Server\n协议与 rich-client 边界"] --> Protocol["协议与多客户端门槛"]
  Copilot["Copilot SDK\n多语言与发布一致性"] --> Protocol
  OpenCode["OpenCode Server / SDK\n单内核与多客户端"] --> Customization["定制化门槛"]
  Vercel["Vercel AI SDK / Elements\nUI 状态与 transport 分离"] --> Customization

  Capability --> OpenBitFun["一个 OpenBitFun Agent SDK"]
  Protocol --> OpenBitFun
  Customization --> OpenBitFun

这张图表达的是决策证据来源,而不是把多个竞品 API 拼成一个超集。能力、协议和界面定制分别取证, 最终仍统一为一套 OpenBitFun 语义和一个公开 SDK。

对标状态只使用以下三个词:

状态含义
原生(native)OpenBitFun 现有 owner 直接提供同类公开语义
映射(translated)达到同一用户目标,但生命周期或命名按 OpenBitFun 语义表达;差异可查询
增强(additive)OpenBitFun 特有能力;不能用来替代行业基础能力

3. 公开名词与产品边界

3.1 用户需要理解的名词

名词含义不等于
Agent模型、指令、工具、权限上限和可选 Subagent 的组合具体 Provider、页面或进程
Session可连续工作并按能力持久化、恢复或分支的上下文SDK 连接或单次命令
TurnSession 中一次执行的只读身份与事实;一个 Turn 可包含多个 Model RoundSDK 中另一个可操作运行句柄
Query一次 Turn 的唯一实时控制句柄,承载消息流、取消、交互和最终状态第二种 Session、另一套 Agent Loop 或只读 Turn 事实
Message / Event输入、输出、增量、工具/权限请求和生命周期通知内部事件总线 payload
ResultTurn 的最终状态、输出、结构化结果、用量和错误摘要stdout 文本本身
Tool内置工具、SDK 函数 Tool 或 MCP Tool绕过权限和审计的任意函数
Permission副作用前的 allow/deny/ask 决策SDK 调用方扩大 Host 策略上限的开关
Hook在明确生命周期点执行的检查、变换或观察 callback通用事件总线或工作流编排 DSL
MCP Server通过 MCP 提供工具/资源的外部服务第二个 Tool Runtime
Subagent由当前 Agent 委派且受父级权限、预算和取消约束的执行独立产品 Runtime
Skill / Plugin可复用说明、资源和经策略启用的扩展包自动受信任的任意代码

公开文档不要求用户理解 SDK Host、SDK Host protocol、RuntimeServicesDeliveryProfile、 Rust port/provider、Product Assembly、Tauri adapter 或能力版本。这些词只出现在贡献者文档和高级诊断中。

3.2 只有一个公开 SDK

flowchart TB
  Client["AgentClient"]
  Ephemeral["Managed Session"]
  Session["Explicit Session"]
  Query["Query · live handle"]
  Turn["Turn · read-only"]
  Stream["Message / Event"]
  Result["Result"]
  Callback["Callbacks"]

  Client --> Ephemeral
  Client --> Session
  Ephemeral --> Query
  Session --> Query
  Query --> Turn
  Query --> Stream
  Query --> Result
  Stream --> Callback
  Callback -->|"恢复同一待处理操作"| Query

client.query() 是常用入口,使用由 SDK 管理的临时 Session;需要恢复、多轮或并发控制时,调用方显式创建 Sessionclient.query()session.startTurn() 都返回同一种 Query,而 Turn 只作为 Query 和事件中可读取的 身份与已提交事实。两条路径进入同一个 Runtime 生命周期,不形成第二套 Session 或 Agent loop。

层次使用者状态与职责
Agent Runtime APIOpenBitFun 各产品 adapter唯一 Agent loop 与应用用例边界;不是语言包
Rust Runtime SDKOpenBitFun 内部入口、受控 Rust 嵌入当前 preview;不等于公开产品
OpenBitFun Agent SDKPython/TypeScript 应用开发者一个公开产品、多个语言绑定;尚未交付

Python SDK、TypeScript SDK、managed Host 和连接预启动 Host 不是四种 SDK。前两者是同一 API 的语言绑定,后两者是 SDK 内部 transport 模式。

4. 产品视图:一个 Runtime,多种入口

4.1 产品入口

flowchart TB
  GUI["GUI / TUI"] --> UIA["UI adapter"]
  CLI["openbitfun exec"] --> CLIA["CLI adapter"]
  SDK["Agent SDK"] --> SDKA["SDK Host"]
  ACP["ACP"] --> ACPA["ACP adapter"]
  Server["Server / Remote"] --> RemoteA["Server / Remote adapter"]
  UIA --> API["Runtime API"]
  CLIA --> API
  SDKA --> API
  ACPA --> API["Runtime API"]
  RemoteA --> API
  API --> Coordinator["ConversationCoordinator"]
  Coordinator --> Runtime["Agent Runtime owners"]

  Composition["first-party composition roots"] -. "inject once" .-> Ownership["CoreRuntimeOwnership"]
  Ownership -. "local attach / mutation gate" .-> Coordinator

4.2 互操作入口

上图中的 ACP、Server/Remote 和 SDK Host 都是同级 adapter;虚线只表示第一方进程装配 ownership,不表示某个入口依赖另一个入口。

上图固定四条架构结论:

  • GUI/TUI/CLI 同样使用 Query、MCP、Permission 和 Hook,但它们直接经过各自 adapter 调用共享 Runtime API, 不依赖 Python/TypeScript SDK,也不依赖 SDK Host。
  • SDK Host 是跨进程/跨语言 adapter,不拥有 Session、Tool、MCP、Permission、Hook 或 Event 状态。
  • 各入口共享业务事实和 owner,不共享 renderer、命令行参数、wire protocol 或平台生命周期。
  • 增加 SDK 不得让 CLI、GUI/TUI 或 Server 的底层依赖变深;它只增加一个同级入口。

该图表达逻辑依赖,不要求所有入口位于同一进程。目标部署中,GUI/TUI/本机 Remote 可以连接第一方 Shared Agent Runtime; 一次性 Headless CLI 继续 Embedded;公开 SDK 默认连接私有 SDK Host。Shared Agent Runtime process 和 SDK Host 都是 Rust 产品进程, 与运行第三方 JS/TS 的 Node/Bun Plugin Host 不同;三者不能共享名称或业务归属。

当前代码已经交付显式启用的 Shared TUI 最小切片,包含本机 IPC、身份、握手、Session/Turn、当前 Session 的 name/Agent mode/model、Permission/UserInput、 ownership 和生命周期治理;Model、Skill、Subagent 和 MCP 管理暂由 Shared CLI adapter 的本地 compatibility provider 保留,不属于 v17 或公开 SDK 合同。GUI、Headless CLI、ACP、SDK Host、Server/Remote 仍没有 Shared consumer。该图中的多入口逻辑复用是 当前事实,除 Shared TUI 外的跨进程 Shared deployment 仍是目标架构。

4.3 各形态能做什么

形态最适合共享能力形态特有职责
GUI日常交互、审批、设置、诊断和可视化Session、Tool/MCP、Permission、Hook 结果、用量与事件React/Tauri/Web 渲染、窗口和平台生命周期
TUI终端内持续交互与 GUI 相同的业务事实和控制动作终端渲染、键位和终端恢复
Headless CLIshell、一次性任务、普通 CI、简单脚本Query、结构化输出、取消、非交互权限策略flags、stdin/stdout/stderr、退出码、JSON/JSONL
Agent SDK应用、服务、IDE、复杂自动化和语言内扩展CLI 的 Agent 能力,加类型明确的对象、并发 Session 和 callbackPython/TypeScript API、Host 生命周期、函数 Tool/Permission/Hook callback
ACP编辑器与 Agent 的标准互操作ACP 稳定规范能表达的 Session/Tool/Permission/Event 子集ACP 协议、兼容映射和降级
Server/Remote远程控制、多设备和服务化接入Host capability 与远程策略允许的共享用例认证、网络、执行域、断线恢复和远程策略

5. 运行视图:SDK 如何进入同一 Runtime

5.1 依赖和进程关系

flowchart LR
  App["Developer application"] --> SDK["OpenBitFun Agent SDK"]
  SDK -->|"manage + authenticated local channel"| Host["openbitfun-sdk-host"]
  Host --> SDKAdapter["SDK Host protocol adapter"]
  SDKAdapter --> API["Agent Runtime API"]
  API --> Runtime["Single Agent Runtime and owners"]

本图只放大 SDK 特有的跨进程路径;GUI/TUI、CLI、ACP 和 Server 的同级 adapter 关系以第 4 节产品视图为准, 不在这里再次折叠或定义。

依赖约束:

组件必须禁止
openbitfun CLI依赖共享 Runtime/Application 能力依赖 SDK Host app、SDK protocol 或公开语言包
GUI/TUI依赖共享应用用例和各自平台 adapter经公开 SDK 绕行 Runtime;共享 renderer/protocol
openbitfun-sdk-host独立组装入口,选择 SDK profile依赖 CLI crate;成为第二个 Server 或 Runtime
SDK Host adapter协议、能力协商、连接/Query 资源清理责任和 DTO 转换stdin/stdout 入口、Agent 业务状态、Tool/MCP 注册表
Python/TypeScript SDK管理或连接匹配 Host,提供一致公开 API要求用户安装 openbitfun CLI;暴露内部 wire DTO
CoreRuntimeOwnership第一方 Rust 入口选择 Embedded/Shared,并把本机 workspace lease 注入 Coordinator进入公开 SDK/wire;成为 Session 单写或 Server 路由 owner

通讯能力按“协议机械层、载体、产品协议”三层拆分:

层次共享 owner保留在使用方的职责
协议无关机械层adapters/transport 的 Rust 有界 JSON,以及同目录 TypeScript MessageTransport、有界 WebSocketMessageTransport、JSON-RPC request correlation不拥有业务 method、DTO、认证、Session/Query 生命周期或恢复策略;单一消费者的 length-prefix framing 留在 private IPC owner
载体stdio、Named Pipe/UDS、WebSocket adapter 实现统一的消息收发与背压边界各 Host 继续拥有 endpoint、具体 framing、Origin/认证、重连和方向性限额策略
产品协议SDK Host、private Runtime IPC 和 App Server 分别拥有自己的 wire 与行为合同不因复用 JSON-RPC/消息机械能力而合并业务协议、controller/lease 或 Runtime owner

因此“复用通讯层”不等于建立万能 wire:stdio、IPC 和 WebSocket 共享有界编解码、消息收发、request correlation 等机械能力,但 SDK Host、Shared TUI IPC 与 Web App Server 仍是同级 adapter。任何载体超限、背压失败或无法确认的 请求结果都由对应产品 adapter 投影成自己的错误与清理语义;通用通讯层不能替它们决定自动重试或生命周期。

5.2 一次 Query 的运行时序

sequenceDiagram
  participant App
  participant SDK
  participant Host
  participant API
  participant Runtime

  App->>SDK: query()
  SDK->>Host: initialize
  SDK->>Host: create / resume Session
  Host->>API: start Turn
  API->>Runtime: run Turn
  Runtime-->>API: events / requests
  API-->>Host: events / requests
  Host-->>SDK: messages
  SDK-->>App: messages
  App-->>SDK: callback response
  SDK-->>Host: callback response
  Host->>API: callback response
  API->>Runtime: resume operation
  Runtime-->>API: result
  API-->>Host: Turn completed
  Host-->>SDK: Result
  SDK-->>App: Result

SDK 连接、Query、Session 和 callback invocation 分别记录由谁负责清理资源;这只是资源回收责任,不是另一套业务状态。 重复调用 Query.cancel() 不会产生额外取消动作,Runtime 已结算的最终状态以 Result 为准。Query.close() 在 Query 活跃时执行取消、 有界等待结算并释放 stream/callback 注册;最终状态后只释放资源。各语言的 dispose/context-manager 语法映射到同一 close()

client.query() 创建的临时 Session 由 Query 持有,Query 结算并关闭后随之释放;显式 Session 由调用方持有, 其 Query 关闭不会关闭 Session。Session.close() 停止新 Turn,取消并结算其活动 Query,再释放该 Session 的资源; 它不关闭共享的 AgentClient/Host connection,也不等于删除或归档持久化 Session。只有 AgentClient.close() 才关闭连接并按 同一规则清理其活动 Session/Query。client.query()session.startTurn() 是异步启动方法;Turn 被 Runtime 接受前的 启动失败直接返回 Operation Error,不产生 Query。接受后,Runtime 能确认的完成、失败和取消都返回同一个 Result。 如果连接丢失或清理超时导致 Runtime 的最终状态无法确认,则返回“结果是否生效未知” (outcome_certainty=unknown)的 Operation Error,不伪造 Result。已取消或已结束 Turn 的迟到 callback 必须被拒绝。

5.3 Host 流与 callback 不变量

主题必须保持的不变量
身份connection、Session、Query、Turn、operation 和 callback invocation 使用不同的稳定身份;transport request id 不能代替 operation id
顺序每个 Query 的 Message/Event 使用严格递增序号;不承诺不同 Query 之间的全局顺序
最终状态屏障Runtime 已结算时,Result 恰好产生一次并成为最后一项;无法确认结算时以 Operation Error 结束本地流且不伪造 Result,两者之后都不得再发送事件或 callback
流量控制读写队列同时受条目数和字节数约束;队列溢出、写入超时或连接丢失会触发 Query/connection 取消、结算和明确错误,禁止静默丢事件
重连与重放首个本地协议不自动重放旧 Query;断连后恢复 Session 并读取已知 Turn 结果,请求身份只用于去重、审计和恢复关联,不承诺通用 operation 查询 API
连接清理活动 Query 在断连时取消,并在有限时间内等待结算后再释放资源;首个稳定 API 不支持 detach
清理超时返回 cleanup_incompleteoutcome_certainty=unknown;保留操作终止记录以拒绝迟到响应,并将 Session 和连接标记为不可复用。managed Host 由进程监督模块终止并回收;重新连接后先核对已知 Turn 事实
Callback 不变量规则
调用身份每次请求携带唯一 callback invocation id、Query、Turn、operation 和期限;invocation 必须属于当前 operation,且只接受一次响应
迟到与重复重复、过期或已取消响应返回稳定错误,不能再次提交 Runtime 状态
Permission / Before Hookhandler 异常、超时、取消或连接丢失时拒绝执行;不能扩大产品、组织或 Host 的策略上限
After Hookhandler 失败时保留真实 Tool 结果和副作用事实,只增加诊断;绝不重放 Tool
函数 Toolhandler 失败形成明确的 Tool failure;只有归属模块明确证明安全时才允许重试,不能重放整个 Turn
UserInput单次响应受 schema、大小和 deadline 约束;超时、异常或断连不提供默认答案,以类型化 input_unavailable 结束当前交互并按 Runtime 策略结算 Turn
Query 取消取消向所有待处理 callback 传播;callback 清理完成或 deadline 到达后再发布 Query 最终状态

每一种 callback kind 单独参与 capability negotiation;不能因为 Permission callback 可用,就推断 UserInput、Tool 或 Hook callback 也可用。

6. 公开 Agent SDK 形态

6.1 一个客户端,两种使用深度

公开 API 以一个 AgentClient 为权威入口:

await using client = await AgentClient.start({ cwd });

// 常见的一次 Query;返回可迭代、可取消、可关闭的句柄。
await using query = await client.query({
  prompt: "Find and fix the failing test",
  allowedTools: ["Read", "Edit", "ExecCommand"],
});
for await (const message of query) {
  // Message / Event / Result
}
const quickResult = await query.result(); // cached terminal Result from the stream

// 需要多轮、恢复或并发控制时使用显式 Session。
await using session = await client.sessions.create({ agent: "agentic" });
await using review = await session.startTurn({ prompt: "Review the resulting diff" });
for await (const event of review) {
  // observe, approve/deny, answer, cancel or steer when supported
}
const result = await review.result(); // same terminal Result emitted by the stream

Python 提供同一对象关系和生命周期。字段遵循各语言惯例,但能力、默认值、错误码、事件顺序和资源关闭语义必须一致。 自然消费到 Result 会释放 Runtime 中该 Query 占用的资源,result() 返回同一个缓存最终状态;调用方仍使用语言的 dispose/context-manager 语法关闭本地句柄,提前离开流则按 close() 的取消与结算语义处理。 示例固定的是对象关系和职责,不提前固定 package path、所有方法签名或字段;任何签名进入 preview 前都需通过双语言 fixture。

为降低第一次使用成本,可以在 preview 后评估顶层 query() 便捷函数;它只能是创建短生命周期 client 并调用 client.query() 的薄封装,不能拥有第二套配置、Session 或错误语义。正式签名前需由 Python/TypeScript 两个真实消费者验证。

6.2 核心能力门槛

能力类别公开目标单一 owner / 约束
Query 与异步流类型明确的 Message/Event/Result、cancel/close/result、交互控制和唯一最终状态Agent Runtime / Event 模块;唯一实时运行句柄
Session 与 TurnSession create/resume/fork/close;按 id 读取已知 Turn 的只读身份与已提交事实Session 模块;close 不等于 delete/archive,也不构成通用 operation 查询 API
执行上下文cwd/workspace、agent/model、预算/deadline、配置来源Product policy;凭据不进入普通 wire/log
内置 Tool与 GUI/TUI/CLI 相同 catalog、权限和审计Tool 归属模块
自定义函数 ToolPython/TS callback、schema、deadline、取消和大小限制作为 Tool provider 注册;不创建 SDK Tool Runtime
MCP配置、ready/pending/failed 状态、目录版本既有 MCP 生命周期模块;不创建 SDK 专用连接池
Permissionallow/deny/ask callback 和明确的恢复状态Permission 归属模块保留最终上限;超时后拒绝执行
Hook稳定生命周期 callback、确定顺序、阻止/变换/观察唯一 Hook Coordinator;不创建 SDK HookBus
UserInput类型明确的 question/answer callback、schema、大小、期限、取消和 unavailable 最终状态Agent Runtime 交互模块;不提供默认答案,不与 Permission 混用
Subagent定义、委派、父子事件、权限和预算收紧Runtime/Subagent 模块;父子取消可验证
Skill/Plugin/来源显式选择可信来源并报告实际状态External Source control;不输出生态原始对象
Structured outputJSON Schema、验证失败与重试事实与 CLI/Runtime 使用同一结果合同
Usage/Tracetoken、cost、cache、duration、调用关联Event/usage 模块;低基数和默认脱敏

Goal、Deep Review、Harness、Remote execution 和 Mini App 可以作为 additive 能力出现,但不能替代上表的基础能力, 也不能迫使第一次使用 SDK 的用户先学习 OpenBitFun 特有概念。

6.3 Capability 而不是猜测

SDK 在初始化后获得稳定 capability 集合。未交付能力必须明确为 unavailable/experimental,不得根据 Runtime 中存在同名 trait、空 port、内部事件或 CLI flag 推断可用。调用不支持能力返回类型化 capability_unavailable,不能静默切换为本机、 另一种权限模式或另一套 transport。

7. 外部应用与可定制界面

Agent SDK 不等于 UI SDK。外部开发者需要基础界面时,采用以下拓扑:

flowchart LR
  Browser["Browser UI\ncustom or reference components"]
  Backend["Developer backend / BFF\nauth · tenancy · policy · secrets"]
  SDK["OpenBitFun Agent SDK"]
  Host["Managed SDK Host"]
  Runtime["OpenBitFun Agent Runtime"]

  Browser <-->|"application-specific HTTPS / stream"| Backend
  Backend --> SDK --> Host --> Runtime

安全和职责边界:

  • BFF 指面向该界面的开发者后端(Backend for Frontend),不是 OpenBitFun 新增的公共服务。
  • 浏览器不直接启动或连接本机 SDK Host,不持有 Provider/MCP/OpenBitFun Host 凭据。
  • 开发者后端负责用户认证、租户隔离、速率限制,并把公开 SDK 事件转换为自己的前端协议。
  • OpenBitFun SDK 负责 Agent 能力;它不负责 React 状态、路由、主题、组件或业务认证。
  • 第一方 src/web-ui 不作为 npm SDK 发布;它包含 Desktop/Server 产品假设和内部命令,直接复用会固化私有 ABI。

SDK Preview 提供最小参考应用,证明浏览器认证后端、流式 Query、取消,以及无法继续时显示 action_required; Beta 再扩展 Permission callback、审批提交和断线/Host 崩溃恢复。参考应用是示例而不是稳定 UI ABI。 只有出现至少两个仓库外 UI 消费者后,才允许从重复需求中抽取独立、可选的 UI 工具层:

产物交付时机作用约束
Reference app(Preview)SDK Preview展示后端接 SDK、前端流式事件、取消和待处理动作的只读提示示例,不构成稳定 ABI;不伪造尚未交付的审批 callback
Reference app(Beta)SDK Beta增加 Permission callback、审批提交和断线/Host 崩溃恢复继续只消费公开 SDK,不访问 Host protocol
Headless UI controller两个真实消费者出现重复状态逻辑后Session/Turn/Message/Tool/Permission 的框架无关状态归约只消费公开 SDK 事件;不访问 Host protocol
Copy-source components两个真实消费者出现重复组件需求后对话、Tool、Permission、Plan、Usage 等可复制组件独立包/registry;允许深度改造,不与 SDK 版本强绑定

这仍然是一个 Agent SDK 加一个可选 UI 工具层,不是“本地 SDK、远程 SDK、UI SDK”三套产品。

不同应用形态只改变 SDK 放置位置,不改变公开能力:

外部应用推荐连接说明
浏览器 Web 应用Browser → developer backend → SDK认证、密钥、策略和 callback 留在后端
Electron/本地桌面或开发者工具trusted main/backend process → SDKSDK 在受信本机管理 Host;renderer 只通过受限 IPC 访问 main process,不直接接 Host
多租户服务server-side worker/backend process → SDK浏览器 service worker 不接 SDK;调用方另行负责租户隔离和 OS/容器沙箱,SDK Host 本身不是沙箱

8. Tool、MCP、Permission 与 Hook 的单一执行链

flowchart LR
  Input["Model input"] --> Initial["Tool owner\nresolve identity + initial shape"]
  Initial --> Before["Hook Coordinator\nBeforeTool"]
  Before --> Validate["Tool owner\nrevalidate schema + final arguments"]
  Validate --> Permission["Permission owner\nproduct + organization + user"]
  Permission --> Execute["Tool owner\nexecute selected provider"]
  Execute --> Fact["Immutable execution fact + audit"]
  Fact --> After["Hook Coordinator\nAfterTool / Failure"]
  After --> Projection["Model / UI projection"]

  Catalog["Tool provider catalog"] --> Initial
  Builtin["Built-in Tool"] -. "register" .-> Catalog
  SDKTool["SDK function Tool"] -. "register" .-> Catalog
  MCP["MCP lifecycle"] -. "provider" .-> Catalog
  GUI["GUI / TUI decision"] -.-> Permission
  CLI["CLI policy"] -.-> Permission
  SDK["SDK callback"] -.-> Permission
  Handlers["Typed Hook handlers\nSDK callbacks + ecosystem adapters"] -.-> Before
  Handlers -.-> After

约束:

  • GUI/TUI 决策、CLI flag 和 SDK callback 都只是输入;Permission owner 保留最终决定权。
  • MCP 配置可来自产品设置、项目文件、CLI 或 SDK,但连接、认证、健康、重连和回收只有一个 lifecycle owner。
  • SDK Hook 与 OpenCode/Claude/Codex adapter 共享 Hook Coordinator;adapter 只解释来源语义。
  • Before Hook 修改参数后必须重新校验 schema 与权限;After Hook 不能覆盖真实副作用、成功/失败或审计事实。
  • Safe Mode、Host capability 或 execution domain 不允许时,所有入口统一拒绝执行;SDK 不回退本机。

9. Headless CLI 与 Agent SDK

CLI 和 SDK 共享能力事实,但不是上下层关系:

需求openbitfun execAgent SDK
一次性命令、shell 管道首选可用,但增加语言和 Host 生命周期
普通 CI首选:稳定退出码、JSON/JSONL、进程级期限只有需要类型明确的 callback、并发 Session 或应用内状态时选择
text/json/JSONL原生输出类型明确的对象 / async iterator
多轮 SessionID/flag 恢复,适合脚本Session object 与长连接更自然
权限flag/配置;非交互时拒绝需要确认的操作类型明确的 callback,加同一策略上限
自定义函数 Tool不把 shell callback 固定为稳定 ABIPython/TS function callback
Hook配置来源和可选事件显示类型明确的 callback
并发多进程,由调用方管理一个受控 client/Host 上并发多个 Session
资源关闭进程最终状态和退出显式 close/dispose、断连和 callback 清理

因此:

  • CLI 不默认依赖 SDK Host,也不通过 SDK package 运行。
  • CLI、ACP、Desktop 与 SDK Host 只共享 Core ownership 和 Runtime 行为 owner;共享这些内部 owner 不构成产品依赖,也不新增第二种 SDK。
  • 一次性 openbitfun exec 默认使用 Embedded Runtime;只有恢复或控制 Shared Agent Runtime 中的共享 Session 时,才使用第一方 client adapter attach,且不经过 SDK Host。
  • SDK 不解析 CLI stream-json 作为正式双向协议。
  • 普通脚本/CI 不需要为了“架构统一”改写成 SDK;复杂生产自动化才选择 SDK。
  • 两者使用共同的行为样例验证相同配置、权限和 Tool 结果,但 flags、事件格式和传输方式可以不同。

10. 合同、版本与发布视图

10.1 一套业务含义,多种输出格式

flowchart LR
  Runtime["Runtime domain contracts"] --> HostSchema["SDK Host schema\nstable + experimental"]
  Runtime --> SessionCreate["AgentSessionCreateResult\nshared session-create facts"]
  SessionCreate --> HostSchema
  SessionCreate --> CLIProjection
  SessionCreate --> UIProjection
  HostSchema --> TSClient["generated internal TS wire client"]
  HostSchema --> PyClient["generated internal Python wire client"]
  TSClient --> TSApi["curated TypeScript public API"]
  PyClient --> PyApi["curated Python public API"]
  Runtime --> CLIProjection["CLI JSON / JSONL"]
  Runtime --> UIProjection["GUI / TUI views"]

  Fixtures["shared semantic fixtures"] --> Runtime
  Fixtures --> TSApi
  Fixtures --> PyApi
  Fixtures --> CLIProjection

会话创建是这条规则的当前实例:AgentSessionCreateResult 由 Session owner 生成并携带规范化的 workspace 与 execution-target 事实;Desktop 的 CreateSessionResponse 只是该类型的宿主命名,SDK Host 的 SessionCreateResult 则保留 agentlifetime 等协议字段并从同一结果转换。adapter 可以改变 wire 形状, 但不能重新计算或持有第二份 Session 创建事实。

生成的 wire 类型保持 SDK 内部;公开 API 必须经过人工策划,不能把协议 DTO 原样暴露给用户。

10.2 防止持续迭代造成不一致

机制作用
单一 Runtime 归属业务事实只实现一次;可替换 Provider 仍通过同一归属接口接入,入口只转换输出格式并转发 callback
单一 Host schemaPython/TS 不各自手写 wire 类型和错误
Schema drift CI代码生成结果有差异即失败,禁止忘记更新某个绑定
Capability negotiation新旧 Host/SDK 明确知道哪些能力可用;不按版本号猜测
Stable / experimental 分层实验能力需显式 opt-in;稳定 API 不依赖实验字段
Semantic conformance suite同一 Session/Turn/Tool/Permission/UserInput fixture 跨 Runtime、CLI、TS、Python 验证业务事实
Compatibility matrix每个 SDK 版本声明 Host protocol 范围和 Runtime capability 下限
Release gate语言包、Host binary、schema、文档和 fixture 同一发布流水线验证

版本分为三层:

  1. SDK API version:Python/TypeScript 的公开方法和类型,遵循各自包的 semver。
  2. SDK Host protocol version range:wire schema、方法、事件、错误与 capability。
  3. Runtime capability version:Tool/MCP/Permission/Hook/UserInput 等业务语义版本。
flowchart LR
  TSRelease["npm package\nSDK API semver"] --> SDK["TypeScript binding"]
  PyRelease["PyPI package\nSDK API semver"] --> SDK2["Python binding"]
  SDK --> Range["Supported Host protocol range"]
  SDK2 --> Range
  Host["Matched openbitfun-sdk-host\nprotocol version"] --> Negotiate{"initialize + negotiate"}
  Range --> Negotiate
  Runtime["Runtime capability set"] --> Negotiate
  Negotiate -->|"range overlaps"| Ready["Typed capabilities\nenabled per feature"]
  Negotiate -->|"no overlap"| Reject["Version or capability error\nreject"]

语言包版本、Host 协议版本和 Runtime 能力版本不能互相替代。握手先验证协议范围,再报告实际 capability; 版本兼容但能力缺失时仍必须返回明确不可用,不能根据 SDK 包版本推断 Runtime 已支持。

SDK 安装后必须能定位匹配 Host。TypeScript 可使用平台可选包,Python 可使用平台 wheel;具体打包方案可按仓库和签名体系调整, 但用户不应先安装或升级 openbitfun CLI。连接预启动 Host 是高级模式,需双向认证、端点 owner/ACL 校验和 capability negotiation。

10.3 发布渠道

产物推荐渠道公开与兼容承诺
TypeScript Agent SDKnpm公开 curated API;只有 GA stable namespace 承诺长期兼容,Preview/Beta 与 experimental 按阶段策略演进
Python Agent SDKPyPI公开 curated API;只有 GA stable namespace 承诺长期兼容,Preview/Beta 与 experimental 按阶段策略演进
openbitfun-sdk-host随 SDK 平台包/wheel 或受签名下载器提供不是用户 API;协议是版本化兼容边界
JSON/TypeScript schema构建产物和协议测试 fixturewire 合同,不等于公开语言 API
Reference UI / components独立示例仓库或可选 registry示例或组件级版本,不绑定 SDK 主包

11. 错误、日志、指标与安全

公开 SDK 与 SDK Host 共享稳定错误信封,至少包含 codestageretryablemessageoperation_idcausation_id、不透明 correlation_idoutcome_certainty、最小可见身份和可选 recovery action。 调用方不得解析 message 驱动控制流。transport request id 只负责协议配对,不能代替跨重连保留的请求身份;后者只用于去重、审计和 恢复关联的 operation identity。

outcome_certainty 是封闭事实:

含义调用方动作
not_started权威 owner 保证操作未被接受且没有副作用只有 retryable=true 时才可用同一 operation identity 安全重试
committedowner 已记录权威最终状态;错误携带结果引用或 resume_session / read_turn recovery action读取已知 Turn/结果事实,不重新执行
unknown连接/进程故障后无法证明是否已产生副作用可能重复产生副作用的操作禁止自动重试;恢复 Session 读取已知 Turn,仍未知时人工对账

retryable=true 只表示协议和 owner 能证明使用同一 operation identity 重试安全;它不是“建议再试一次”。 写入、发送、删除、外部 Tool 或结果未知的 callback 默认不可重放。

类型用途约束
Error当前操作失败和恢复稳定 code;区分 validation/auth/permission/quota/version/timeout/cancel/process/internal
DiagnosticSession/Tool/MCP/Hook/Host 的持续降级状态生命周期明确;恢复后撤销
Log本地开发和运维英文结构化;默认不记录 prompt、参数、结果、环境变量和凭据
Metric/Trace成功率、时延、队列、成本和因果链低基数标签;身份、路径和内容不进 metric label
Audit权限、Hook 变换、Tool 副作用和管理动作不可被 SDK callback 或插件覆盖

上述所有 Error、Diagnostic、Log、Trace 和 Audit surface 共用一套数据分类规则;应用主动请求的 Message/Result 属于业务 payload,不因此自动进入可观测数据:

数据类别统一规则允许的替代信息
凭据、token、header、环境变量秘密永不进入错误、诊断、日志、trace、audit 或 metric仅记录稳定的缺失/拒绝错误码
prompt、Tool 参数、模型/Tool 结果默认不进入任何可观测 surface;显式调试也必须按策略授权、限时和脱敏schema 名、大小、内容摘要或受控 artifact 引用
本机路径、用户/Session/插件身份最小化并按可见范围脱敏;不得成为 metric label不透明 ID、路径类别或受控 hash
correlation/operation/causation identity必须不透明、不可由内容推导,不包含路径或用户输入稳定随机标识
Audit 事实记录决策、owner、稳定 ID、摘要和时间,不保存原始敏感 payload内容摘要和受访问控制的 artifact ref

日志、trace 和 audit 必须有明确访问边界、保留期与删除策略;含 secret/path/prompt 的跨语言 fixture 是发布门禁, 不能只验证 Rust 侧协议实现的序列化结果。

安全边界:

  • SDK Host/CLI/Node/Python 进程治理用于取消和回收,不等于操作系统安全沙箱。
  • 本地 Host 默认只接受父 SDK 的受控通道;预启动 Host 在业务 payload 前完成双向认证。
  • callback 只能返回候选结果,不能直接修改 Runtime 权威状态或扩大组织/产品策略。
  • 远程 SDK 后续必须复用 Server/Remote 的认证、execution domain、凭据 owner 和断线策略;不能把本地 Host 协议直接暴露到网络。

12. 所有权视图:SDK、扩展与外部界面的边界

flowchart LR
  SDK["Agent SDK boundary\nHost protocol · language bindings"]
  Extension["Ecosystem adapter boundary\nOpenCode / Claude / Codex mapping"]
  ExternalApp["External application boundary\nbackend / BFF · UI · tenancy"]
  API["Shared Agent Runtime API"]
  Hook["Single Hook Coordinator"]
  Owners["Single Tool / MCP / Permission owners"]

  ExternalApp --> SDK
  SDK --> API
  Extension --> Hook
  API --> Hook
  API --> Owners
边界负责不负责
Agent SDK公开对象、语言绑定、Host 生命周期、协议转换和 callback 传输生态配置解析、第一方 UI、Runtime 业务状态
生态 adapter来源发现、宿主语义映射、兼容诊断和 fixture公开 SDK transport、通用 Hook 调度、Runtime owner
外部应用/BFF认证、租户、应用策略、界面状态和自定义交互直连本机 Host、复制 Agent loop、保存 OpenBitFun 凭据
Agent Runtime API跨入口共享的 Query/Session/Turn 应用用例语言包、renderer、生态私有 payload
Tool/MCP/Permission/Hook owner最终业务事实、顺序、权限、审计和生命周期为某一 SDK 或生态复制专用实现
UserInput interaction owner问题身份、可见范围、回答提交、取消和最终状态把输入 callback 当作 Permission 或提供默认答案

外部 Hook adapter 负责来源与语义映射,SDK 负责语言 callback 通信;二者最终汇入同一个 Hook Coordinator。 任何跨边界能力都必须先确定唯一归属模块、稳定事实和失败语义,不得通过复制类型、私有注册表、平行 HookBus, 或按 ecosystem ID 在 Core 分支来规避边界。

13. 成熟度与发布门槛

阶段可以宣称不可宣称
InternalHost/protocol 候选可供仓库内验证可安装 Agent SDK、跨语言兼容
PreviewPython/TS 可安装,核心 Query/Session/取消/错误有真实样例Claude 核心能力等价、生产稳定
BetaTool/MCP/Permission/Hook/UserInput callback 和升级/崩溃恢复完整流程长期兼容或全部 additive 能力
GA固定能力矩阵、协议/语言一致性、全平台生命周期和外部消费者通过对未来竞品滚动版本自动等价

GA 必须同时满足:

  • 固定版本的 Claude Agent SDK 稳定核心能力无静默缺口;每项标记 native/translated/additive。
  • TypeScript 和 Python 至少各有一个仓库外真实消费者,并通过同一 conformance suite。
  • SDK/Host 安装、升级、版本不匹配、崩溃、取消和完整进程树回收通过 Windows/macOS/Linux 验证。
  • Session resume/fork、structured output、usage、Tool/MCP/Permission/Hook/UserInput callback 有端到端样例。
  • CLI 与 SDK 共同 fixture 证明业务事实一致,但 CLI 仍不依赖 SDK Host。
  • schema drift、stable/experimental、capability negotiation、错误码和兼容矩阵进入发布门禁。
  • API 参考、快速开始、迁移说明、安全模型和外部 UI 参考架构完整。

14. 明确非目标

  • 不提供 Claude Agent SDK 的 import-compatible 或 source-compatible 替换包。
  • 不发布多个互不兼容的“本地 SDK”“远程 SDK”“UI SDK”。
  • 不让 CLI、GUI/TUI、ACP 或 Server 依赖公开 Python/TypeScript SDK 或 SDK Host。
  • 不把 stream-json、ACP 或 HTTP Server 全量路由冒充正式 Agent SDK。
  • 不发布 OpenBitFun 第一方 React UI 作为稳定 SDK ABI。
  • 不把 OpenCode/Claude/Codex 原始插件对象、Hook payload 或配置类型带入 Runtime 公共合同。
  • 不在没有真实消费者、owner 和失败语义时建立通用工作流、HookBus、远程 SDK transport 或公共 Capability SDK。

15. 参考基线