# Providers

Providers 把不同模型服务统一成 Beaver 内部的 `chat(messages, tools, model, ...)` 协议，屏蔽 OpenAI/LiteLLM/Anthropic/Codex/Custom 的差异。

## 大模块流程

配置目标provider_name/model/api_base/key
->
ProviderBundlemain/auxiliary/embedding
->
Provider.chat统一入参
->
协议转换system/tool/reasoning/usage
->
LLMResponsecontent/tool_calls/finish_reason

## 小模块拆分

### base models

`LLMProvider` 定义 chat 协议；`LLMResponse` 统一模型输出；`ToolCallRequest` 统一工具调用 id/name/arguments。

AgentLoop 只消费 LLMResponse，不关心具体 SDK。
Tool call arguments 被规范化为字符串或 dict 后交给 ToolExecutor。
usage 被映射回 session usage。

### factory / runtime / registry

根据配置创建 provider runtime，并组织 main provider、auxiliary provider 和 embedding runtime。Router、Planner、Validator 和 Skill 选择通常使用 auxiliary provider；主回答使用 main provider。

resolve provider target。
创建 runtime，带 api key/base/header/timeout/model。
创建 ProviderBundle，供一次 Task attempt 复用。

### LiteLLM / OpenAI-like

主要走 OpenAI 风格 messages + tools。它最接近 Beaver 内部协议，转换成本最低。

接收 ContextBuilder messages。
附加 tools、max_tokens、temperature、thinking_enabled。
解析 content、tool_calls、usage、finish_reason。

### Anthropic 与 Codex

这两类 provider 对 system prompt 有特殊要求，会把第一条 system message 提取到独立字段，剩余 messages 作为对话输入。Codex 还会使用 prompt cache key。

扫描 messages，提取第一条 system。
其余 system 或非 system message 按 provider 能接受的格式转换。
调用 provider SDK，并把响应转回 LLMResponse。

Prompt 相关：provider 本身不创造业务 prompt，但会改变 system message 的传输位置，详见 Prompt Atlas。

### fallback chain

当主 provider 失败时，fallback chain 可以尝试备用目标。上层仍看到统一的 LLMResponse。

主 provider 调用失败。
记录异常并尝试 fallback target。
成功则返回 fallback response；全部失败则 finish_reason/error。