该技能是 bro 的 provider 注册表(providers)的契约参考,用于配置和调试 bro 的 provider 注册表。其机制在配置和 @broject/providers 绑定中实现,provider 一律通过配置声明,从不硬编码。
一、provider 是什么 provider 是 bro.config.json 中 providers 下的一个命名条目,形式为 { type, …connection }。消费者按名称选用,名称本身不带语义;type(provider 类型)决定连接形式和该条目能够服务的面。
示例配置包含三类条目:
- api 类:一个 API 主机,多个模型,每个模型声明其 wire,如 baseUrl 为 https://api.orcarouter.ai,apiKeyCommand 为 secret-tool 查找命令,models 中映射模型 id 到 systemone、openai-compat 或 null(推断)。
- acp 类:command 为 kilo --acp,指定 model。
- cli 类:command 为带 {promptFile} 的 shell 模板,指定 model。
二、类型与服务面
- api:call(判定)按模型 wire,systemone 为强类型、openai-compat 为散文;不用于 spawn(集群)。
- acp:在 jev 家族模型上为强类型,否则为散文;支持 spawn。
- cli:散文,解析 stdout;支持 spawn(loop.agent 模板契约)。
api 条目是主机 + 认证 + models 白名单,形如 { "<model-id>": "systemone" | "openai-compat" | { "wire": … } | null }。null 或缺省时推断 wire:jev 家族 id 为 systemone,其余为 openai-compat。model 固定默认模型;judge.model 或每次调用覆盖必须指定白名单内的 id,否则为配置错误并列出白名单。
cli.command 是 shell 模板:{promptFile} 展开为存放提示词文件的带引号路径(缺省时作为最后一个参数附加);{model} 展开为解析出的有效模型(带引号)。进程运行后退出,stdout 即答案。模板无法消费的模型覆盖(如在没有 {model} 的命令上使用 --model/profile/judge.model)会明确报错,而不是重新贴标签:来源永不声称 worker 未运行的模型。
acp 条目的 call 等级由所服务的模型决定:typesafe/jev-(或裸 jev-)为强类型传输;其他为散文,并在 decidedBy 中标记 provider:<name>:prose。
cli 条目可选的 models 是 shell 模板,每行输出一个模型 id,即目录服务面,例如 "models": "opencode models"。缺省表示无可枚举目录;固定的模型仍会渲染。
三、bro providers models [name…]:模型目录 将每个 provider 的模型列表渲染为 <name>/<model-id>,即各宿主选择器共用的统一 provider/model 词汇(claude 的 /bro:models 命令正是包装此调用)。各类型来源:
- api:models 白名单的键(配置声明,离线)。
- acp:session/new 的 model configOptions,通过协议实时枚举,与 agent 自身模型选择器提供的列表相同。
- cli:models 模板的 stdout 行,并去重追加固定的模型(固定模型总会渲染,provider 不会静默为空)。
指定的 provider 会明确报错(providers.<name> is not configured);某个 provider 失败会警告,不影响其余 provider。
四、消费者接线
- Judge:judge.provider: '<name>' + judge.model: '<allowed-id>'(+ judge.fallback: '<name>')。解析出的模型的 wire 决定适配器:systemone → 强类型判定,openai-compat → 散文。散文级答案从不计为校准的强类型判定,decidedBy 会说明是哪种。旧的 judge.{baseUrl,model,apiKeyEnv} / judge.llm 会合成匿名单模型 api 条目并给出弃用警告。
- Fleet:agents.<backend>.provider: '<name>' 或 fleet.profiles.<p>.provider,provider 提供后端 spawn 中运行的内容;来源通过 BRO_AGENT_PROVIDER / BRO_AGENT_MODEL 进入注册表条目和 bro fleet 输出。
五、不可妥协的规则
- 无默认、无硬编码。缺省 providers 表示 provider 行为关闭,从不静默使用某供应商。消费者引用不存在的条目会在使用时出错(providers.<name> is not configured),绝不回退。
- 密钥通过环境变量名或查找命令传递。apiKeyEnv 指定变量名(大写下划线);apiKeyCommand 指定密钥库查找(secret-tool lookup …、pass show …、op read …),其 stdout 为密钥。密钥值从不落入配置或错误输出;内联夹带密钥的命令会被拒绝。
- 已退役的类型会使配置失败。type: "systemone" 或 "openai-compat" 作为 provider 类型是硬错误,并指明迁移方式:将条目改为 type: "api" + models 映射。
- 服务面错误即配置错误。要求 api 条目 spawn,或让非 call 类型执行判定,会在解析时失败并指明 kind + surface。
- bro doctor 报告注册表:条目(名称、类型、默认/服务模型)、未设置的 apiKeyEnv 变量、悬空/服务面不匹配的消费者引用,以警告行呈现,不影响退出码。
六、策略 新供应商是一个注册表条目,而不是新连接器——类型仅为连接形式差异而存在(并集封闭为三种);HTTP 主机内的协议差异是 models 映射条目,而非类型。
在改动 provider 配置前先用 bro doctor 诊断——其中的警告行正是 spawn/decide 会遇到的失败,提前说明。