Skip to content
Merged
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ docker run -p 38440:38440 -v $(pwd)/config.yml:/config/config.yml moonbridge
| `/v1/models` | GET | 列出可用模型 |
| `/models` | GET | 同上 |
| `/api/v1/` | — | 管理 API(需启用持久化) |
| `/health` | GET | 健康检查 |

详细 API 文档见 [API.md](docs/api.md)。

Expand Down
5 changes: 5 additions & 0 deletions config.example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ extensions:
# binding: MOONBRIDGE_DB

# Persistence consumer: request metrics
# apply_patch 代理扩展:控制 Codex 文件编辑工具是否展开为结构化代理工具。
# 默认关闭,开启后 apply_patch 被拆分为 add_file/delete_file/update_file/replace_file/batch
# codex_tool_proxy:
# enabled: true

metrics:
enabled: true
config:
Expand Down
30 changes: 26 additions & 4 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,32 @@ data: {"response": {...}}

| 端点 | 方法 | 功能 |
|------|------|------|
| `/api/v1/config` | GET/PUT | 获取/更新运行时配置 |
| `/api/v1/codex/config` | GET | 生成 Codex TOML 配置 |
| `/api/v1/providers` | GET/POST/DELETE | 管理 Provider |
| `/api/v1/sessions/{id}` | GET | 获取会话用量统计 |
| `/api/v1/providers` | GET/POST/PUT/PATCH/DELETE | 管理 Provider CRUD |
| `/api/v1/providers/{key}/offers` | POST | 创建 Offer |
| `/api/v1/providers/{key}/offers/{model}` | PATCH/DELETE | 更新/删除 Offer |
| `/api/v1/providers/{key}/test` | POST | 测试 Provider 连通性 |
| `/api/v1/models` | GET | 列出模型定义 |
| `/api/v1/models/{slug}` | GET/PUT/DELETE | 管理单个模型定义 |
| `/api/v1/routes` | GET | 列出路由 |
| `/api/v1/routes/{alias}` | GET/PUT/DELETE | 管理单个路由 |
| `/api/v1/defaults` | GET/PUT | 管理默认配置(model/max_tokens/system_prompt) |
| `/api/v1/web-search` | GET/PUT | 管理全局 Web Search 设置 |
| `/api/v1/extensions` | GET | 列出扩展 |
| `/api/v1/extensions/{name}` | GET/PUT | 管理扩展设置 |
| `/api/v1/config/effective` | GET | 获取生效配置 |
| `/api/v1/config/export` | GET | 导出配置 YAML |
| `/api/v1/config/import` | POST | 导入配置 YAML |
| `/api/v1/config/validate` | POST | 校验配置 |
| `/api/v1/changes` | GET | 列出未提交的配置变更 |
| `/api/v1/changes/apply` | POST | 应用配置变更 |
| `/api/v1/changes/discard` | POST | 放弃配置变更 |
| `/api/v1/status` | GET | 系统状态 |
| `/api/v1/status/providers` | GET | Provider 运行状态 |
| `/api/v1/sessions` | GET | 列出活跃会话 |
| `/api/v1/stats` | GET | 用量统计 |
| `/api/v1/stats/summary` | GET | 用量统计摘要 |
| `/api/v1/logs` | GET | 日志查询 |
| `/api/v1/version` | GET | 版本信息 |

## 错误处理

Expand Down
109 changes: 62 additions & 47 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,46 @@ Moon Bridge 是一个 Go 语言编写的 HTTP 代理/协议转换服务器。对

## 四层架构

```
┌─────────────────────────────────────────────────┐
│ Service 层 │
│ server(路由/处理) adapter_dispatch(协议分发) │
│ provider(路由) stats(统计) trace(跟踪) │
│ proxy(Capture代理) api(管理 API) │
│ store(持久化) runtime(运行时) │
├─────────────────────────────────────────────────┤
│ Protocol 层 │
│ format(核心类型/注册表) anthropic(Anthropic 适配) │
│ openai(OpenAI 适配) google(GenAI 适配) │
│ chat(OpenAI Chat 适配) cache(缓存) │
├─────────────────────────────────────────────────┤
│ 基础组件(直接位于 internal/ 下) │
│ config(配置) logger(日志) openai_dto(共享 DTO) │
│ modelref(模型引用) session(会话) db(数据库) │
├─────────────────────────────────────────────────┤
│ Extension 层 │
│ deepseek_v4 visual websearch websearchinjected│
│ kimi_workaround metrics codex(Codex模型目录) │
│ plugin(插件注册/接口) db(持久化后端: SQLite/D1) │
└─────────────────────────────────────────────────┘
```mermaid
flowchart TB
subgraph Service["Service 层"]
s1["server(路由/处理)"]
s2["adapter_dispatch(协议分发)"]
s3["provider(路由)"]
s4["stats(统计)"]
s5["trace(跟踪)"]
s6["proxy(Capture代理)"]
s7["api(管理 API)"]
s8["store(持久化)"]
s9["runtime(运行时)"]
end
subgraph Protocol["Protocol 层"]
p1["format(核心类型/注册表)"]
p2["anthropic(Anthropic 适配)"]
p3["openai(OpenAI 适配)"]
p4["google(GenAI 适配)"]
p5["chat(OpenAI Chat 适配)"]
p6["cache(缓存)"]
end
subgraph Base["基础组件"]
b1["config(配置)"]
b2["logger(日志)"]
b3["openai_dto(共享 DTO)"]
b4["modelref(模型引用)"]
b5["session(会话)"]
b6["db(数据库)"]
end
subgraph Extension["Extension 层"]
e1["deepseek_v4"]
e2["visual"]
e3["websearch"]
e4["websearchinjected"]
e5["kimi_workaround"]
e6["metrics"]
e7["codex(模型目录)"]
e8["plugin(插件注册/接口)"]
e9["db(SQLite/D1)"]
end
```

### 基础组件(internal/ 顶层包)
Expand Down Expand Up @@ -58,7 +76,7 @@ Moon Bridge 是一个 Go 语言编写的 HTTP 代理/协议转换服务器。对

业务编排层,组合基础层和 Protocol 组件:

- `internal/service/server` — HTTP 服务器、路由(`/v1/responses`、`/v1/models`、`/health` 等)、认证
- `internal/service/server` — HTTP 服务器、路由(`/v1/responses`、`/v1/models` 等)、认证
- `internal/service/server/adapter_dispatch.go` — Adapter 分发路径(switch 协议类型 → 调用对应 Adapter)
- `internal/service/provider` — Provider 管理器(多 Provider 路由、配置热重载)
- `internal/service/proxy` — Capture 模式下的透明代理
Expand All @@ -68,7 +86,6 @@ Moon Bridge 是一个 Go 语言编写的 HTTP 代理/协议转换服务器。对
- `internal/service/trace` — 请求跟踪(捕获请求/响应的完整链路,持久化到 `data/trace/`)
- `internal/service/store` — 配置持久化存储(SQLite / D1)
- `internal/service/runtime` — 运行时上下文
- `internal/service/bridge` — 备用桥接层

### Extension 层

Expand All @@ -81,6 +98,8 @@ Moon Bridge 是一个 Go 语言编写的 HTTP 代理/协议转换服务器。对
- `internal/extension/metrics` — 请求指标采集与查询
- `internal/extension/plugin` — 三方插件注册管理(`PluginRegistry` + `CorePluginHooks`)
- `internal/extension/codex` — Codex 模型目录
- `internal/extension/codex_tool_proxy` — apply_patch 代理扩展
- `internal/extension/kimi_workaround` — Kimi 工具调用轮次限制
- `internal/extension/db` — 持久化 Provider(SQLite 本地 / Cloudflare D1 Worker)

## 三种运行模式
Expand All @@ -93,26 +112,22 @@ Moon Bridge 是一个 Go 语言编写的 HTTP 代理/协议转换服务器。对

## 请求生命周期数据流(Transform 模式)

```
客户端 (Codex CLI)
│ POST /v1/responses (OpenAI Responses 格式)
server.handleResponses()
│ 认证 / 日志 / 统计初始化 / 路由解析
adapter_dispatch.go (Adapter 分发)
│ preferred.Protocol 决定上游协议
├── ProtocolAnthropic → anthropic adapter
├── ProtocolGoogleGenAI → google adapter
├── ProtocolOpenAIChat → chat adapter
└── ProtocolOpenAIResponse → 直通(无协议转换)
├── 插件拦截 (PluginHooks)
│ MutateCoreRequest → [Adapter] → RememberContent → OnStreamEvent
客户端 ←── OpenAI Responses 响应
```mermaid
flowchart TD
A["客户端 (Codex CLI)"]
A -->|"POST /v1/responses<br/>(OpenAI Responses 格式)"| B["server.handleResponses()"]
B -->|"认证 / 日志 / 统计初始化 / 路由解析"| C["adapter_dispatch.go (Adapter 分发)"]
C -->|"preferred.Protocol 决定上游协议"| D{"协议分支"}
D -->|"ProtocolAnthropic"| E["anthropic adapter"]
D -->|"ProtocolGoogleGenAI"| F["google adapter"]
D -->|"ProtocolOpenAIChat"| G["chat adapter"]
D -->|"ProtocolOpenAIResponse"| H["直通(无协议转换)"]
E --> I["插件拦截 (PluginHooks)"]
F --> I
G --> I
H --> I
I --> J["MutateCoreRequest → [Adapter] → RememberContent → OnStreamEvent"]
J --> K["客户端<br/>← OpenAI Responses 响应"]
```

## 模型路由
Expand Down Expand Up @@ -141,9 +156,9 @@ adapter_dispatch.go (Adapter 分发)
```go

type ClientAdapter interface {
Protocol() string
ToCoreRequest(context.Context, []byte) (*CoreRequest, error)
FromCoreResponse(context.Context, *CoreResponse) ([]byte, error)
ClientProtocol() string
ToCoreRequest(context.Context, any) (*CoreRequest, error)
FromCoreResponse(context.Context, *CoreResponse) (any, error)
}

type ProviderAdapter interface {
Expand Down
101 changes: 60 additions & 41 deletions docs/development-conventions.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,47 +4,66 @@

### 目录布局

```
internal/
├── config/ # 配置加载/校验/Schema
├── logger/ # 结构化日志(slog 封装)
├── openai_dto/ # 共享 OpenAI DTO
├── modelref/ # 模型引用解析
├── session/ # 会话管理
├── db/ # 数据库抽象与注册表
├── format/ # Core 类型(CoreRequest/CoreResponse/Registry/Adapter 接口)
├── protocol/ # 协议转换层
│ ├── anthropic/ # Anthropic Messages Adapter
│ ├── cache/ # Prompt 缓存规划
│ ├── chat/ # OpenAI Chat Adapter
│ ├── format/ # (遗留层,功能已迁移到 internal/format)
│ ├── google/ # Google Gemini Adapter
│ └── openai/ # OpenAI Responses Adapter
├── service/ # 业务编排层
│ ├── api/ # 管理 REST API(路由在 router.go)
│ ├── app/ # 应用生命周期管理、Extension 目录
│ ├── bridge/ # (空目录,保留以备将来使用)
│ ├── e2e/ # 服务层 E2E 测试
│ ├── provider/ # Provider 管理器
│ ├── proxy/ # Capture 模式代理
│ ├── runtime/ # 运行时上下文
│ ├── server/ # HTTP 服务器 + 路由 + 认证 + Adapter 分发
│ │ ├── session/ # 会话管理
│ │ ├── trace/ # 请求跟踪写入
│ │ └── usage/ # 用量跟踪
│ ├── stats/ # 用量统计
│ └── trace/ # 请求跟踪记录
├── extension/ # 可插拔扩展
│ ├── codex/ # Codex 模型目录(catalog.go、default_instructions.go)
│ ├── db/ # 数据库 Provider(sqlite/、d1/)
│ ├── deepseek_v4/ # DeepSeek V4 推理优化
│ ├── kimi_workaround/ # Kimi 模型 tool call 轮次限制
│ ├── metrics/ # 用量指标采集与查询
│ ├── plugin/ # Plugin 接口 + 能力接口 + 注册表
│ ├── visual/ # 视觉模型分发(CoreProvider 模式)
│ ├── websearch/ # Web Search 编排器
│ └── websearchinjected/ # 注入式搜索插件
└── e2e/ # 端到端集成测试(协议转换)
```mermaid
flowchart TD
subgraph internal["internal/"]
direction TB
config["config/ — 配置加载/校验/Schema"]
logger["logger/ — 结构化日志(slog封装)"]
openai_dto["openai_dto/ — 共享 OpenAI DTO"]
modelref["modelref/ — 模型引用解析"]
session["session/ — 会话管理"]
db["db/ — 数据库抽象与注册表"]
fmt["format/ — Core类型/Registry/Adapter接口"]

subgraph protocol["protocol/ — 协议转换层"]
direction TB
pa["anthropic/ — Anthropic Messages Adapter"]
pc["cache/ — Prompt 缓存规划"]
pch["chat/ — OpenAI Chat Adapter"]
pf["format/ — (遗留层,功能已迁移到 internal/format)"]
pg["google/ — Google Gemini Adapter"]
po["openai/ — OpenAI Responses Adapter"]
end

subgraph service["service/ — 业务编排层"]
direction TB
sa["api/ — 管理 REST API"]
sapp["app/ — 应用生命周期管理、Extension 目录"]
se["e2e/ — 服务层 E2E 测试"]
sp["provider/ — Provider 管理器"]
spr["proxy/ — Capture 模式代理"]
srt["runtime/ — 运行时上下文"]
subgraph srv["server/ — HTTP服务器/路由/认证/Adapter分发"]
direction TB
ss["session/ — 会话管理"]
st["trace/ — 请求跟踪写入"]
su["usage/ — 用量跟踪"]
end
sst["stats/ — 用量统计"]
str["trace/ — 请求跟踪记录"]
end

subgraph extension["extension/ — 可插拔扩展"]
direction TB
ec["codex/ — Codex 模型目录"]
subgraph edb["db/ — 数据库 Provider"]
es["sqlite/"]
ed1["d1/"]
end
eds["deepseek_v4/ — DeepSeek V4 推理优化"]
ek["kimi_workaround/ — Kimi tool call 轮次限制"]
em["metrics/ — 用量指标采集与查询"]
ep["plugin/ — Plugin 接口+能力接口+注册表"]
ev["visual/ — 视觉模型分发(CoreProvider模式)"]
ew["websearch/ — Web Search 编排器"]
ewi["websearchinjected/ — 注入式搜索插件"]
ectp["codex_tool_proxy/ — apply_patch 代理扩展"]
ect["codextool/ — 工具类型定义与工具映射"]
end

e2e["e2e/ — 端到端集成测试(协议转换)"]
end
```

### 依赖方向
Expand Down
40 changes: 40 additions & 0 deletions docs/extensions-overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,46 @@ moonbridge -config config.yml -print-codex-config my-model

---


---

## codex_tool_proxy(apply_patch 代理扩展)

控制 Codex 的 `apply_patch` 自定义工具是否被展开为 5 个结构化代理工具(`add_file`、`delete_file`、`update_file`、`replace_file`、`batch`)发送给上游模型。

**位置**:`internal/extension/codex_tool_proxy/`

**文件清单**:

| 文件 | 用途 |
|------|------|
| `plugin.go` | Plugin 实现 + PatchProxyDecider |

**行为**:

- **默认关闭**(`DefaultEnabled: false`):`apply_patch` 以 raw grammar 形态原样透传给上游模型
- **开启后**:展开为 5 个独立的结构化工具,让上游模型以 JSON schema 方式调用

**实现的能力**:

```go
var (
_ plugin.Plugin = (*ProxyPlugin)(nil)
_ plugin.ConfigSpecProvider = (*ProxyPlugin)(nil)
_ plugin.PatchProxyDecider = (*ProxyPlugin)(nil)
)
```

**启用方式**:

```yaml
extensions:
codex_tool_proxy:
enabled: true
```

支持 route / model / provider 级别覆盖。

## visual(视觉扩展)


Expand Down
Loading