Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,42 @@
- **GitHub Actions Integration**: Trigger Claude Code tasks in your GitHub workflows.
- **Plugin System**: Extend functionality with custom transformers.

## ✨ Anthropic Passthrough Support

The router now supports two backend formats:
- **OpenAI Format**: Converts Anthropic requests to OpenAI-compatible format (default)
- **Anthropic Format**: Directly passes through original Anthropic requests (new feature)

### Configuration

Use `anthropicPassthrough` transformer to enable Anthropic passthrough mode:

```json
{
"Providers": [
{
"name": "openai",
"api_base_url": "https://api.openai.com/v1",
"api_key": "your-openai-api-key",
"models": ["gpt-4o", "gpt-4o-mini"]
},
{
"name": "anthropic-official",
"api_base_url": "https://api.anthropic.com",
"api_key": "your-anthropic-api-key",
"models": ["claude-3-5-sonnet-20241022", "claude-3-5-haiku-20241022"],
"transformer": {
"use": ["anthropicPassthrough"]
}
}
]
}
```

**API URL Configuration:**
- **Basic URL (recommended)**: `"https://api.anthropic.com"` → auto-adds `/v1/messages`
- **Full URL**: `"https://api.example.com/v1/messages"` → uses as-is

## 🚀 Getting Started

### 1. Installation
Expand Down Expand Up @@ -233,6 +269,7 @@ Transformers allow you to modify the request and response payloads to ensure com

**Available Built-in Transformers:**

- `anthropicpassthrough`: Enables direct passthrough to Anthropic API without format conversion.
- `deepseek`: Adapts requests/responses for DeepSeek API.
- `gemini`: Adapts requests/responses for Gemini API.
- `openrouter`: Adapts requests/responses for OpenRouter API.
Expand Down
38 changes: 38 additions & 0 deletions README_zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,43 @@
- **动态模型切换**: 在 Claude Code 中使用 `/model` 命令动态切换模型。
- **GitHub Actions 集成**: 在您的 GitHub 工作流程中触发 Claude Code 任务。
- **插件系统**: 使用自定义转换器扩展功能。
- **Anthropic 直通**: 支持原始 Anthropic API 格式的直接透传,提供完整的流式体验。

## ✨ Anthropic 直通支持

路由器现在支持两种后端格式:
- **OpenAI 格式**: 将 Anthropic 请求转换为 OpenAI 兼容格式(默认)
- **Anthropic 格式**: 直接透传原始 Anthropic 请求到后端(新功能)

### 配置方法

使用 `anthropicPassthrough` transformer 来启用 Anthropic 直通模式:

```json
{
"Providers": [
{
"name": "openai",
"api_base_url": "https://api.openai.com/v1",
"api_key": "your-openai-api-key",
"models": ["gpt-4o", "gpt-4o-mini"]
},
{
"name": "anthropic-official",
"api_base_url": "https://api.anthropic.com",
"api_key": "your-anthropic-api-key",
"models": ["claude-3-5-sonnet-20241022", "claude-3-5-haiku-20241022"],
"transformer": {
"use": ["anthropicPassthrough"]
}
}
]
}
```

**API URL 配置:**
- **基础 URL(推荐)**: `"https://api.anthropic.com"` → 自动添加 `/v1/messages`
- **完整 URL**: `"https://api.example.com/v1/messages"` → 直接使用

## 🚀 快速入门

Expand Down Expand Up @@ -228,6 +265,7 @@ Transformers 允许您修改请求和响应负载,以确保与不同提供商

**可用的内置 Transformer:**

- `anthropicpassthrough`: 启用 Anthropic API 直通模式,不进行格式转换。
- `deepseek`: 适配 DeepSeek API 的请求/响应。
- `gemini`: 适配 Gemini API 的请求/响应。
- `openrouter`: 适配 OpenRouter API 的请求/响应。
Expand Down
4 changes: 4 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,8 @@ export const DEFAULT_CONFIG = {
OPENAI_API_KEY: "",
OPENAI_BASE_URL: "",
OPENAI_MODEL: "",
Providers: [],
Router: {
default: ""
}
};
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ async function run(options: RunOptions = {}) {
server.addHook("preHandler", async (req, reply) =>
router(req, reply, config)
);

server.start();
}

Expand Down
1 change: 1 addition & 0 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ export const readConfigFile = async () => {
const APIKEY = await question("Enter Provider API KEY: ");
const baseUrl = await question("Enter Provider URL: ");
const model = await question("Enter MODEL Name: ");

const config = Object.assign({}, DEFAULT_CONFIG, {
Providers: [
{
Expand Down
2 changes: 2 additions & 0 deletions src/utils/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ const getUseModel = async (req: any, tokenCount: number, config: any) => {
return config.Router!.default;
};


export const router = async (req: any, _res: any, config: any) => {
const { messages, system = [], tools }: MessageCreateParamsBase = req.body;
try {
Expand All @@ -118,6 +119,7 @@ export const router = async (req: any, _res: any, config: any) => {
if (!model) {
model = await getUseModel(req, tokenCount, config);
}

req.body.model = model;
} catch (error: any) {
log("Error in router middleware:", error.message);
Expand Down