<div align="center">
  <img src="docs/logo.png" width="120" alt="Protoflux logo" />

  <h1>Protoflux</h1>

  <p>基于 Rust 构建的企业级 AI 网关 — 协议翻译、凭证管理、运维可观测性，一个二进制文件搞定。</p>

  <p>
    <a href="README.md">English</a> · <a href="README.zh-CN.md">简体中文</a>
  </p>

  <p>
    <a href="docs/configuration.zh-CN.md">配置文档</a> ·
    <a href="docs/scripting.zh-CN.md">脚本指南</a> ·
    <a href="docs/console-api.zh-CN.md">Console API</a> ·
    <a href="docs/mcp.zh-CN.md">MCP Gateway</a> ·
    <a href="docs/deployment.zh-CN.md">部署指南</a>
  </p>
</div>

---

## ✨ 特性

| 特性 | 说明 |
|------|------|
| 🔐 **用户级访问控制** | 每个用户独立 API Key + 分组模型 ACL，支持匿名用户 |
| 🔄 **凭证轮换与故障转移** | 多上游密钥自动轮转，失败自动切换 |
| 📊 **运维可观测性** | 请求日志、持久化统计、实时 SSE 日志流、Web Console |
| 📈 **Prometheus 指标** | `/metrics` 端点（Bearer 认证），请求计数器、延迟直方图、熔断器状态 |
| 🔭 **OpenTelemetry 追踪** | OTLP gRPC 导出（feature-gated），W3C Trace Context 传播，42 个 `#[instrument]` span |
| 📋 **审计日志** | 配置变更审计追踪（谁/做了什么/什么时候）存入 SQLite/PostgreSQL，fire-and-forget 写入 |
| 🌐 **协议翻译** | OpenAI ↔ Anthropic ↔ Gemini ↔ AWS Bedrock ↔ DashScope ↔ Passthrough，透明桥接 |
| 📝 **脚本转换** | 请求/响应自定义处理，支持 JavaScript 脚本（[脚本指南](docs/scripting.zh-CN.md)） |
| 🚀 **部署友好** | TOML 配置 + 环境变量、Docker 就绪、单二进制文件（单实例零外部依赖；多实例可选 PostgreSQL/Redis） |
| 🛡️ **安全加固** | bcrypt 密码哈希、IP 防爆破、API Key 脱敏、安全响应头、每 IP 限速 |
| ⚡ **高性能** | Rust + Tokio 异步运行时，无 GC 停顿 |
| ⚖️ **模型级负载均衡** | 加权轮询、粘性会话、故障降级、429 限流故障转移，跨上游智能分发 |
| 🗄️ **分布式状态** | Redis 支持的会话、限流、日志广播、IP 封禁，适用于多实例部署 |
| ☸️ **Kubernetes 就绪** | 存活/就绪探针、优雅关闭与 pre-stop drain、可配置超时 |
| 🛠️ **MCP Gateway** | 内置 MCP (Model Context Protocol) 代理，聚合外部工具服务器，支持 ACL、上下文预算和 BM25 工具搜索 |

## 🌍 支持的协议

| 协议 | 执行器 | 状态 |
|------|--------|------|
| OpenAI Chat Completions | `openai` | ✅ 生产可用 |
| OpenAI Completions | `openai_completions` | ✅ 生产可用 |
| OpenAI Response | `openai_response` | ✅ 生产可用 |
| OpenAI Images | `openai_images` | ✅ 生产可用 |
| OpenAI Embeddings | `openai_embeddings` | ✅ 生产可用 |
| OpenAI Audio | `openai_audio` | ✅ 生产可用 |
| Anthropic Messages | `anthropic` | ✅ 生产可用 |
| Gemini Generative Language | `google` | ✅ 生产可用 |
| AWS Bedrock Converse | `aws_converse` | ✅ 生产可用 |
| AWS Bedrock InvokeModel | `aws_invoke` | ✅ 生产可用 |
| Alibaba DashScope | `dashscope` | ✅ 生产可用 |
| Passthrough (透传代理) | `passthrough` | ✅ 生产可用 |

超出范围的 endpoint 返回 `501 Not Implemented`，不返回占位数据。

> [!NOTE]
> Protoflux 仅使用 API Key 认证，**不支持 OAuth**。OpenAI、Anthropic 等订阅服务通常禁止将账户用于 API 用途，违反厂商协议。

## 🚀 快速开始

### 前置条件

- Rust 1.80+（`rustup default stable`）
- 你的 LLM API Key

### 1. 复制配置

```bash
cp server.example.toml server.toml
# 编辑 server.toml 设置基础设施配置（server, logging, cors 等）
# 业务配置（用户、上游、模型）启动后通过 Console 管理
```

### 2. 校验配置

```bash
cargo run -- --config server.toml config-validate
```

### 3. 启动服务

```bash
cargo run -- --config server.toml serve
```

### 4. 健康检查

```bash
cargo run -- health-check --url http://localhost:7890
```

> 💡 配置文件支持 `${ENV_VAR}` 环境变量展开。裸 `$VAR` 不会被展开，避免与 bcrypt 哈希冲突。

### 🐳 Docker 快速启动

Protoflux 支持两种存储模式。**SQLite** 适用于单实例部署（默认），**PostgreSQL** 适用于多实例容器部署，支持共享状态。

#### SQLite 模式（单实例）

配置和统计数据存储在本地 SQLite 数据库中。业务配置持久化在数据库内。适合开发、单节点部署或无需多实例协调的场景。

```bash
docker pull ghcr.io/taichulab/protoflux:latest

docker run -d \
  --name protoflux \
  -p 7890:7890 \
  -v $(pwd)/server.toml:/etc/protoflux/server.toml:ro \
  -v protoflux-data:/var/lib/protoflux \
  ghcr.io/taichulab/protoflux:latest
```

> SQLite 模式需要挂载数据卷（`/var/lib/protoflux`）以持久化统计和配置数据库，避免重启丢失。通过 Web Console（`http://localhost:7890/console`）配置端点和查看统计信息。

#### PostgreSQL 模式（多实例）

配置、统计和业务数据存储在 PostgreSQL 中。多个网关实例可共享同一数据库，实现水平扩展和通过 Console 集中管理配置。

```bash
# 启动 PostgreSQL
docker run -d \
  --name protoflux-pg \
  -e POSTGRES_USER=protoflux \
  -e POSTGRES_PASSWORD=changeme \
  -e POSTGRES_DB=protoflux \
  -p 5432:5432 \
  postgres:17-alpine

# 启动 Protoflux（连接 PG）
docker run -d \
  --name protoflux \
  -p 7890:7890 \
  -e POSTGRES_URL="postgresql://protoflux:changeme@host.docker.internal:5432/protoflux" \
  -v $(pwd)/server.toml:/etc/protoflux/server.toml:ro \
  ghcr.io/taichulab/protoflux:latest
```

配合配置 TOML：

```toml
[server]
storage_mode = "postgresql"
postgres_url = "${POSTGRES_URL}"
```

> PostgreSQL 自动通过 refinery 迁移创建统计表。业务配置（用户、上游、模型）通过 Console 管理并持久化到数据库。SQLite 和 PostgreSQL 两种模式都支持通过 Console 配置端点信息和查看统计数据。

## 🛠️ 开发者指南

### 构建

```bash
# Debug 构建（编译快）
cargo build

# Release 构建（优化二进制，启用 LTO）
cargo build --release

# 构建指定 crate
cargo build -p protoflux-core
cargo build -p protoflux-server
```

### 测试

测试默认使用内联 `#[cfg(test)]` 块。大型或集成测试提取到 `crates/<crate>/tests/` 目录。

```bash
# 运行全量测试
cargo test --workspace

# 运行指定 crate 的测试
cargo test -p protoflux-core
cargo test -p protoflux-server

# 运行单个测试
cargo test -p protoflux-core resolved_route_user_agent
```

### 代码质量

```bash
# 格式检查
cargo fmt --all --check

# 配置校验（提交前必跑）
cargo run -- --config server.example.toml config-validate
```

### 架构速览

Protoflux 是一个 Cargo workspace，包含五个 crate：

| Crate | 职责 |
|-------|------|
| `protoflux-core` | 领域模型、配置解析、路由解析、鉴权、协议翻译器、上游执行器 |
| `protoflux-server` | Axum HTTP 服务、中间件（鉴权/客户端鉴权/限流/访问日志/统计）、Console API、插件运行时 |
| `protoflux-plugin` | 插件 SPI trait 定义 — 自定义鉴权、路由、中间件、UI overlay 的扩展接口 |
| `protoflux-license` | License 验证、内存上限策略、license API（商业版） |
| `protoflux-bin` | 二进制入口 — CLI 解析、配置加载、通过 `AppBuilder` 驱动的启动生命周期 |

**请求链路**：客户端 → 鉴权中间件 → 路由解析 → 请求变换 → 协议翻译 → 上游执行器 → 响应变换 → 协议翻译 → 客户端

关键设计：
- **协议翻译**：客户端和上游可以使用不同协议（如 Anthropic → OpenAI），翻译器双向转换 payload。
- **凭证轮换**：每个上游可配置多个 API Key，网关自动轮转并在失败时重试。
- **脚本引擎**：请求/响应体可通过 JavaScript 脚本自定义处理，支持灵活的路由和 payload 操控。
- **插件 SPI**：通过 [`protoflux-plugin`](docs/plugin-development.zh-CN.md) crate 扩展网关功能，支持自定义鉴权、路由、中间件、Console UI 等。

### Console 前端

Web Console 是一个 TypeScript 单页应用，位于 `console/` 目录，使用 [React](https://react.dev/) + TailwindCSS + DaisyUI。通过 Vite 构建，编译产物通过 `rust-embed` 嵌入到二进制文件中。

```bash
# Console 与网关同一端口
# http://localhost:7890/console
```

### 环境变量

| 变量 | 说明 |
|------|------|
| `LOG` | 日志级别过滤（如 `info`、`debug`、`warn`） |
| `RUST_LOG` | 备用日志过滤（tracing-subscriber） |
| `RUST_BACKTRACE` | 设为 `1` 时 panic 输出完整调用栈 |

配置文件支持 `${ENV_VAR}` 语法，可在运行时注入密钥而无需修改 TOML 文件。

### 贡献流程

1. 从 `main` 创建功能分支
2. 测试写在内联 `#[cfg(test)]` 或 `crates/<crate>/tests/` 集成测试目录
3. 提交前运行 `cargo fmt --all --check && cargo test --workspace`
4. 校验配置：`cargo run -- --config server.example.toml config-validate`

## 📖 文档

- [Architecture](docs/architecture.md) · [架构文档](docs/architecture.zh-CN.md)
- [Configuration](docs/configuration.md) · [配置文档](docs/configuration.zh-CN.md)
- [Plugin Development](docs/plugin-development.md) · [插件开发指南](docs/plugin-development.zh-CN.md)
- [Deployment](docs/deployment.md) · [部署文档](docs/deployment.zh-CN.md)
- [Console API](docs/console-api.md) · [Console API 文档](docs/console-api.zh-CN.md)
- [MCP Gateway](docs/mcp.md) · [MCP 网关](docs/mcp.zh-CN.md)
- [Testing](docs/testing.md) · [测试文档](docs/testing.zh-CN.md)
- [ADR](docs/adr/) · Architecture Decision Records

> **文档语言约定**：
> - **顶层文档与用户手册** — 以**中文为主版本**，英文等其他语言为翻译版。内容以中文版为准，翻译版须与中文版保持一致；新增或修改文档先写中文、再做翻译，禁止出现翻译版独有而中文版缺失的内容。
> - **ADR**（`docs/adr/`） — **仅中文**，不翻译英文。
> - **Tasks**（`docs/tasks/`） — **仅中文**。记录业务相关的任务节点（迁移脚本、发版清单等），作为历史快照保留。这些文件仅反映编写时的状态，**不得**作为架构或业务参考——当前设计请以权威文档（`architecture.zh-CN.md`、`configuration.zh-CN.md` 等）为准。

## 📁 仓库结构

```text
protoflux/
├── crates/
│   ├── protoflux-core/        # 领域模型、配置、路由、鉴权、翻译器、执行器、管线、脚本
│   ├── protoflux-server/     # Axum 服务、middleware、console API、统计、存储、插件运行时
│   ├── protoflux-plugin/      # 插件 SPI trait 定义和上下文类型
│   ├── protoflux-license/     # License verification, memory cap, license API
│   └── protoflux-bin/         # 二进制入口（CLI、配置加载、AppBuilder）
├── e2e/                       # 端到端集成测试
├── docs/                      # 长文档
│   ├── adr/                   # 架构决策记录（仅中文）
│   └── tasks/                 # 业务任务节点——历史快照（仅中文）
├── console/                   # Web Console UI (TypeScript + React + Vite)
├── server.example.toml        # 基础设施配置示例
└── server.docker.toml         # Docker 部署配置（环境变量）
```

## 📄 许可证

[AGPL-3.0-or-later](https://spdx.org/licenses/AGPL-3.0-or-later.html)
