添加提供方¶
提供方集成的评判标准是每个 T3 特性在其上是否诚实可靠,而不是一次回合是否成功运行。本页列出了新驱动所需做出的决策和提供的证据。提供方约束 和 能力系统 解释了这些规则存在的原因。
选择集成形态¶
- ACP 代理 以 ACP Registry 条目形式起步,这些条目遵循 ACP 规范,无需按代理单独处理。只有当代理需要规范未涵盖的行为时,它才会获得专用驱动,并且此时它只是 共享 ACP 适配器 之上的一个小变体,例如 Grok 和 Antigravity。切勿向通用注册表适配器添加 agent-id 检查。
- 其他协议 获得一个原生适配器,实现
ProviderAdapterV2,例如 Codex、Claude、Cursor、OpenCode、Pi 和 Muse。
提供方特定的行为保留在适配器和驱动中。编排层和客户端读取的是能力,而不是驱动种类。
只报告提供方的真实行为¶
- 能力。 将
OrchestrationV2ProviderCapabilities中的每个标志都设置为提供方真实具备的行为。关闭其不具备的 fork、rollback、steering 或 subagent 支持;编排层随后会回退,例如对 fork 使用可移植上下文交接。某个能力标志保持开启但在运行时失败,这就是一个 bug。 - 权限模式。 仅通过提供方展示信息中的
supportedRuntimeModes提供提供方原生强制执行的模式(Grok 和 Pi 是示例)。不要通过在 T3 中批准审批来模仿缺失的模式:T3 的检查比代理自身的强制执行更弱。服务器会将未被提供的已存储模式作为 Supervised 运行(RuntimePolicy.ts)。 - 审批和问题选项。 原样传递提供方自己的选项 ID。每个请求都需要一种提供方认可的拒绝方式。
- 交互模式。 隐藏计划切换开关(
showInteractionModeToggle: false),除非提供方的计划输出会成为 T3 的建议计划卡片。
进程、账户和设置边界¶
- 实例。 会话状态、目录和凭据属于提供方实例,而不属于驱动。移除实例未配置的环境凭据,以免两个实例在静默状态下共享账户或计费。
- 状态检查。 后台状态和模型刷新不得打开可能启动 MCP 服务器、运行钩子(hooks)或发起登录的会话。将较重的探测保留在显式刷新之后。
- T3 MCP 工具。 注入线程的 MCP 服务器,以便代理可以使用 T3 的工具,并确保当该服务器不可达时回合仍然能继续。
- 更新。 只能通过可证明拥有该二进制的安装程序来运行更新;否则保持手动更新。参见
providerMaintenanceRunner.ts。
测试¶
用回放夹具证明适配器行为:将提供方的记录通过真实编排器、适配器和投影进行回放。参见 测试策略。
- 使用
apps/server/scripts中的录制脚本(record-*-replay-fixture.ts)从真实提供方录制记录。新协议通常需要自己的录制器。 - 覆盖
testkit/fixtures下提供方支持的共享场景:simple、multi_turn、queued_turn、turn_interrupt、message_steering、provider_thread_resume以及tool_call_*审批用例。为共享夹具无法触及的行为添加提供方特定夹具。 - 单元测试用于纯逻辑以及真实提供方无法按需产生的失败。用手写帧驱动适配器的测试其实是对协议的一种猜测;实时测试经常会发现这些猜测遗漏的地方。
- 欢迎针对真实二进制文件的门控实时测试,但它不能替代回放,因为 CI 会跳过它。
多个提供方都踩过的陷阱¶
这些陷阱中每一个都曾破坏过不止一个适配器。为你的提供方可能产生的每种情况准备一个回放夹具,就可以捕获这些问题。
- 在提供方公布设置之前就应用设置。 代理通常会在会话打开之后、在后续更新中、或者仅在模型运行时才列出配置选项(例如仅对支持 effort 的模型才存在的 effort 选项)。代理在此之前可以接受写入却不做任何更改。在写入之前要等待选项被公布,并且将实时会话未提供的已存储选项视为“已跳过”,而不是失败。
- “默认”是一个哨兵值,而不是模型。 默认模型选择必须在指定模型运行后将会话切换回来,包括在恢复的会话中也是如此。切勿将哨兵值发送给提供方。
- 在回合开始前发送停止。 在提供方注册提示词之前到达的取消操作可能会被忽略,回合会继续运行至完成,或者可能留下一个提供方从未保存的会话。找到提供方自己的回合开始信号,并测试在发送后立即按下 Stop 的情况。
- 提供方自行启动的工作。 后台命令、子代理、工作流和目标可能在 T3 的回合结束后才完成或开始一个新回合。通过
ProviderContinuationRequests提供延续机制,以便父级被唤醒,并上报hasPendingBackgroundWork,使得会话不会被释放为空闲。如果丢弃它或终止会话,就会丢失结果。 - 子代理比启动它们的运行更长寿。 子代理可能在父级回合结束后才上报,或者在之后的运行中恢复。必须按子代理来路由其更新,而不是按当前正在活动的运行来路由。
- 失败或停止的回合不应留下任何未完成事项。 要结清回合的工具调用、子代理以及待处理的审批和问题。每个终止路径都需要自己的回放:完成、Stop、提供方失败和进程退出。
- 使用限制不是通用失败。 将配额和速率限制错误归类为
usage_limit,并在提供方提供重置时间时附带该时间,这样线程会显示 Limited 并可以恢复。 - 路径和环境。 测试符号链接的工作区,例如 macOS 的
/tmp;如果代理比较规范路径,那么在那里每个回合都会失败。丢弃实例未配置的继承凭据。将未知的登录状态报告为 unknown,而不是已登录。
驱动接入位置¶
一个提供程序位于其自己的 packages/provider-<name> 包中,以 Pi 作为参考。尚未迁移的驱动仍位于 provider/Drivers 中。
- 包导出。
./settings保存实例设置模式,使用 contracts 中的makeProviderSettingsSchema构建。./client导出ProviderClientDefinition(标签、设置模式、纯数据图标、徽章),并且必须保持浏览器和 React Native 安全可用。./server导出ProviderDriver及其适配器驱动。./testing暴露内部内容,供服务器的回放测试工具包驱动;需要编排器的测试工具包保留在服务器中。设置位于providerInstances中;新提供程序默认关闭。 - 包边界。 服务器代码仅导入
@t3tools/provider-core/server/*、contracts 和 shared。它通过ProviderHost(路径、设置、后台需求、附件、存储的凭据)访问服务器,绝不通过apps/server。测试使用@t3tools/provider-testing。 - 服务器注册: 驱动在
builtInDrivers.ts中的条目。驱动携带其适配器驱动。还有其在 状态顺序 中的位置、model-manifest.json中的兼容性策略(更新updatedAt;参见 模型清单),以及 contracts 中的默认模型。 - 客户端注册: Web 和移动端提供程序注册表中的客户端定义,以及设置搜索词。客户端绘制包图标;不要添加按驱动区分的图标分支。
- 文档: 以产品口吻编写的
docs/user/providers-<name>.md指南、安装 表中的一行,以及任何改变 权限模式 页面的提供程序差异。
本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 t3/t3code