mirror of
https://github.com/musistudio/claude-code-router.git
synced 2026-01-29 22:02:05 +00:00
init doc
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -6,3 +6,7 @@ dist
|
||||
.DS_Store
|
||||
.vscode
|
||||
tsconfig.tsbuildinfo
|
||||
|
||||
# Documentation build output
|
||||
docs/build
|
||||
docs/.docusaurus
|
||||
|
||||
29
docs/.gitignore
vendored
Normal file
29
docs/.gitignore
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
# Docusaurus build output
|
||||
build/
|
||||
dist/
|
||||
|
||||
# Docusaurus generated files
|
||||
.docusaurus/
|
||||
|
||||
# Node modules
|
||||
node_modules/
|
||||
|
||||
# Environment variables
|
||||
.env
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# IDE
|
||||
.vscode/
|
||||
.idea/
|
||||
|
||||
# OS
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Logs
|
||||
*.log
|
||||
|
||||
# Misc
|
||||
*.swp
|
||||
*.swo
|
||||
104
docs/README.md
Normal file
104
docs/README.md
Normal file
@@ -0,0 +1,104 @@
|
||||
# Claude Code Router Documentation
|
||||
|
||||
This directory contains the documentation website built with [Docusaurus](https://docusaurus.io/).
|
||||
|
||||
## Development
|
||||
|
||||
### Install Dependencies
|
||||
|
||||
```bash
|
||||
cd docs
|
||||
pnpm install
|
||||
```
|
||||
|
||||
### Start Development Server
|
||||
|
||||
```bash
|
||||
# From docs directory
|
||||
pnpm start
|
||||
|
||||
# Or from root directory
|
||||
pnpm dev:docs
|
||||
```
|
||||
|
||||
Open [http://localhost:3000](http://localhost:3000) to view the documentation.
|
||||
|
||||
## Build
|
||||
|
||||
```bash
|
||||
# From docs directory
|
||||
pnpm build
|
||||
|
||||
# Or from root directory
|
||||
pnpm build:docs
|
||||
```
|
||||
|
||||
The built files will be in the `build/` directory.
|
||||
|
||||
## Serve Built Files
|
||||
|
||||
```bash
|
||||
# From docs directory
|
||||
pnpm serve
|
||||
|
||||
# Or from root directory
|
||||
pnpm serve:docs
|
||||
```
|
||||
|
||||
## Structure
|
||||
|
||||
```
|
||||
docs/
|
||||
├── docs/ # Markdown documentation files
|
||||
│ ├── intro.md # Introduction page
|
||||
│ ├── installation.md
|
||||
│ ├── config/ # Configuration docs
|
||||
│ ├── advanced/ # Advanced topics
|
||||
│ └── cli/ # CLI reference
|
||||
├── src/ # React components and pages
|
||||
│ ├── components/ # Custom React components
|
||||
│ ├── pages/ # Additional pages
|
||||
│ ├── css/ # Custom CSS
|
||||
│ └── theme/ # Docusaurus theme customization
|
||||
├── static/ # Static assets (images, etc.)
|
||||
├── i18n/ # Internationalization files
|
||||
├── docusaurus.config.ts # Docusaurus configuration
|
||||
└── sidebars.ts # Documentation sidebar structure
|
||||
```
|
||||
|
||||
## Adding Documentation
|
||||
|
||||
### Adding New Docs
|
||||
|
||||
Create a new Markdown file in the `docs/` directory and add it to `sidebars.ts`.
|
||||
|
||||
### Adding New Pages
|
||||
|
||||
Add React components to `src/pages/`.
|
||||
|
||||
### Customizing Styles
|
||||
|
||||
Edit `src/css/custom.css`.
|
||||
|
||||
## Internationalization
|
||||
|
||||
Documentation supports both English and Chinese.
|
||||
|
||||
- English: `docs/` and `src/`
|
||||
- Chinese: `i18n/zh/docusaurus-plugin-content-docs/current/`
|
||||
|
||||
To add Chinese translations:
|
||||
|
||||
1. Create corresponding files in `i18n/zh/docusaurus-plugin-content-docs/current/`
|
||||
2. Translate the content
|
||||
|
||||
## Deployment
|
||||
|
||||
The documentation can be deployed to:
|
||||
|
||||
- GitHub Pages
|
||||
- Netlify
|
||||
- Vercel
|
||||
- Any static hosting service
|
||||
|
||||
See [Docusaurus deployment docs](https://docusaurus.io/docs/deployment) for details.
|
||||
108
docs/docs/cli/commands/model.md
Normal file
108
docs/docs/cli/commands/model.md
Normal file
@@ -0,0 +1,108 @@
|
||||
---
|
||||
sidebar_position: 2
|
||||
---
|
||||
|
||||
# ccr model
|
||||
|
||||
Interactive model selection and configuration.
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
ccr model [command]
|
||||
```
|
||||
|
||||
## Commands
|
||||
|
||||
### Select Model
|
||||
|
||||
Interactively select a model:
|
||||
|
||||
```bash
|
||||
ccr model
|
||||
```
|
||||
|
||||
This will display an interactive menu with available providers and models.
|
||||
|
||||
### Set Default Model
|
||||
|
||||
Set the default model directly:
|
||||
|
||||
```bash
|
||||
ccr model set <provider>,<model>
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
ccr model set deepseek,deepseek-chat
|
||||
```
|
||||
|
||||
### List Models
|
||||
|
||||
List all configured models:
|
||||
|
||||
```bash
|
||||
ccr model list
|
||||
```
|
||||
|
||||
### Add Model
|
||||
|
||||
Add a new model to configuration:
|
||||
|
||||
```bash
|
||||
ccr model add <provider>,<model>
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
ccr model add groq,llama-3.3-70b-versatile
|
||||
```
|
||||
|
||||
### Remove Model
|
||||
|
||||
Remove a model from configuration:
|
||||
|
||||
```bash
|
||||
ccr model remove <provider>,<model>
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Interactive selection
|
||||
|
||||
```bash
|
||||
$ ccr model
|
||||
|
||||
? Select a provider: deepseek
|
||||
? Select a model: deepseek-chat
|
||||
|
||||
Default model set to: deepseek,deepseek-chat
|
||||
```
|
||||
|
||||
### Direct configuration
|
||||
|
||||
```bash
|
||||
ccr model set deepseek,deepseek-chat
|
||||
```
|
||||
|
||||
### View current configuration
|
||||
|
||||
```bash
|
||||
ccr model list
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```
|
||||
Configured Models:
|
||||
deepseek,deepseek-chat (default)
|
||||
groq,llama-3.3-70b-versatile
|
||||
gemini,gemini-1.5-pro
|
||||
```
|
||||
|
||||
## Related Commands
|
||||
|
||||
- [ccr start](/docs/cli/start) - Start the server
|
||||
- [ccr config](/docs/cli/other-commands#ccr-config) - Edit configuration
|
||||
178
docs/docs/cli/commands/other.md
Normal file
178
docs/docs/cli/commands/other.md
Normal file
@@ -0,0 +1,178 @@
|
||||
---
|
||||
sidebar_position: 4
|
||||
---
|
||||
|
||||
# Other Commands
|
||||
|
||||
Additional CLI commands for managing Claude Code Router.
|
||||
|
||||
## ccr stop
|
||||
|
||||
Stop the running server.
|
||||
|
||||
```bash
|
||||
ccr stop
|
||||
```
|
||||
|
||||
## ccr restart
|
||||
|
||||
Restart the server.
|
||||
|
||||
```bash
|
||||
ccr restart
|
||||
```
|
||||
|
||||
## ccr code
|
||||
|
||||
Execute a claude command through the router.
|
||||
|
||||
```bash
|
||||
ccr code [args...]
|
||||
```
|
||||
|
||||
## ccr activate
|
||||
|
||||
Output shell environment variables for integration.
|
||||
|
||||
```bash
|
||||
ccr activate
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```bash
|
||||
export ANTHROPIC_API_URL="http://localhost:8080/v1"
|
||||
export ANTHROPIC_API_KEY="sk-xxxxx"
|
||||
```
|
||||
|
||||
To use in your shell:
|
||||
|
||||
```bash
|
||||
eval "$(ccr activate)"
|
||||
```
|
||||
|
||||
## ccr ui
|
||||
|
||||
Open the Web UI in your browser.
|
||||
|
||||
```bash
|
||||
ccr ui
|
||||
```
|
||||
|
||||
## ccr statusline
|
||||
|
||||
Integrated statusline (reads JSON from stdin).
|
||||
|
||||
```bash
|
||||
echo '{"status":"running"}' | ccr statusline
|
||||
```
|
||||
|
||||
## ccr config
|
||||
|
||||
Configuration management commands.
|
||||
|
||||
### Edit Configuration
|
||||
|
||||
```bash
|
||||
ccr config edit
|
||||
```
|
||||
|
||||
Opens the configuration file in your default editor.
|
||||
|
||||
### Validate Configuration
|
||||
|
||||
```bash
|
||||
ccr config validate
|
||||
```
|
||||
|
||||
Validates the current configuration file.
|
||||
|
||||
### Show Configuration
|
||||
|
||||
```bash
|
||||
ccr config show
|
||||
```
|
||||
|
||||
Displays the current configuration (with sensitive values masked).
|
||||
|
||||
## ccr preset
|
||||
|
||||
Preset management commands.
|
||||
|
||||
### List Presets
|
||||
|
||||
```bash
|
||||
ccr preset list
|
||||
```
|
||||
|
||||
### Apply Preset
|
||||
|
||||
```bash
|
||||
ccr preset apply <name>
|
||||
```
|
||||
|
||||
### Save Preset
|
||||
|
||||
```bash
|
||||
ccr preset save <name>
|
||||
```
|
||||
|
||||
## ccr log
|
||||
|
||||
View server logs.
|
||||
|
||||
```bash
|
||||
ccr log [options]
|
||||
```
|
||||
|
||||
Options:
|
||||
- `-f, --follow`: Follow log output (like `tail -f`)
|
||||
- `-n <lines>`: Number of lines to show
|
||||
|
||||
## Global Options
|
||||
|
||||
These options can be used with any command:
|
||||
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `-h, --help` | Show help |
|
||||
| `-v, --version` | Show version number |
|
||||
| `--config <path>` | Path to configuration file |
|
||||
| `--verbose` | Enable verbose output |
|
||||
|
||||
## Examples
|
||||
|
||||
### Stop the server
|
||||
|
||||
```bash
|
||||
ccr stop
|
||||
```
|
||||
|
||||
### Restart with custom config
|
||||
|
||||
```bash
|
||||
ccr restart --config /path/to/config.json
|
||||
```
|
||||
|
||||
### View and set environment variables
|
||||
|
||||
```bash
|
||||
eval "$(ccr activate)"
|
||||
```
|
||||
|
||||
### Open Web UI
|
||||
|
||||
```bash
|
||||
ccr ui
|
||||
```
|
||||
|
||||
### Follow logs
|
||||
|
||||
```bash
|
||||
ccr log -f
|
||||
```
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [Getting Started](/docs/intro) - Introduction to Claude Code Router
|
||||
- [Configuration](/docs/config/basic) - Configuration guide
|
||||
81
docs/docs/cli/commands/start.md
Normal file
81
docs/docs/cli/commands/start.md
Normal file
@@ -0,0 +1,81 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
# ccr start
|
||||
|
||||
Start the Claude Code Router server.
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
ccr start [options]
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
| Option | Alias | Description |
|
||||
|--------|-------|-------------|
|
||||
| `--port <number>` | `-p` | Port to listen on (default: 8080) |
|
||||
| `--config <path>` | `-c` | Path to configuration file |
|
||||
| `--daemon` | `-d` | Run as daemon (background process) |
|
||||
| `--log-level <level>` | `-l` | Log level (fatal/error/warn/info/debug/trace) |
|
||||
|
||||
## Examples
|
||||
|
||||
### Start with default settings
|
||||
|
||||
```bash
|
||||
ccr start
|
||||
```
|
||||
|
||||
### Start on custom port
|
||||
|
||||
```bash
|
||||
ccr start --port 3000
|
||||
```
|
||||
|
||||
### Start with custom config
|
||||
|
||||
```bash
|
||||
ccr start --config /path/to/config.json
|
||||
```
|
||||
|
||||
### Start as daemon
|
||||
|
||||
```bash
|
||||
ccr start --daemon
|
||||
```
|
||||
|
||||
### Start with debug logging
|
||||
|
||||
```bash
|
||||
ccr start --log-level debug
|
||||
```
|
||||
|
||||
## Environment Variables
|
||||
|
||||
You can also configure the server using environment variables:
|
||||
|
||||
| Variable | Description |
|
||||
|----------|-------------|
|
||||
| `PORT` | Port to listen on |
|
||||
| `CONFIG_PATH` | Path to configuration file |
|
||||
| `LOG_LEVEL` | Logging level |
|
||||
| `CUSTOM_ROUTER_PATH` | Path to custom router function |
|
||||
| `HOST` | Host to bind to (default: 0.0.0.0) |
|
||||
|
||||
## Output
|
||||
|
||||
When started successfully, you'll see:
|
||||
|
||||
```
|
||||
Claude Code Router is running on http://localhost:8080
|
||||
API endpoint: http://localhost:8080/v1
|
||||
```
|
||||
|
||||
## Related Commands
|
||||
|
||||
- [ccr stop](/docs/cli/other-commands#ccr-stop) - Stop the server
|
||||
- [ccr restart](/docs/cli/other-commands#ccr-restart) - Restart the server
|
||||
- [ccr status](/docs/cli/other-commands#ccr-status) - Check server status
|
||||
62
docs/docs/cli/commands/status.md
Normal file
62
docs/docs/cli/commands/status.md
Normal file
@@ -0,0 +1,62 @@
|
||||
---
|
||||
sidebar_position: 3
|
||||
---
|
||||
|
||||
# ccr status
|
||||
|
||||
Show the current status of the Claude Code Router server.
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
ccr status
|
||||
```
|
||||
|
||||
## Output
|
||||
|
||||
### Running Server
|
||||
|
||||
When the server is running:
|
||||
|
||||
```
|
||||
Claude Code Router Status: Running
|
||||
Version: 2.0.0
|
||||
PID: 12345
|
||||
Port: 8080
|
||||
Uptime: 2h 34m
|
||||
Configuration: /home/user/.claude-code-router/config.json
|
||||
```
|
||||
|
||||
### Stopped Server
|
||||
|
||||
When the server is not running:
|
||||
|
||||
```
|
||||
Claude Code Router Status: Stopped
|
||||
```
|
||||
|
||||
## Exit Codes
|
||||
|
||||
| Code | Description |
|
||||
|------|-------------|
|
||||
| 0 | Server is running |
|
||||
| 1 | Server is stopped |
|
||||
| 2 | Error checking status |
|
||||
|
||||
## Examples
|
||||
|
||||
```bash
|
||||
$ ccr status
|
||||
|
||||
Claude Code Router Status: Running
|
||||
Version: 2.0.0
|
||||
PID: 12345
|
||||
Port: 8080
|
||||
Uptime: 2h 34m
|
||||
```
|
||||
|
||||
## Related Commands
|
||||
|
||||
- [ccr start](/docs/cli/start) - Start the server
|
||||
- [ccr stop](/docs/cli/other-commands#ccr-stop) - Stop the server
|
||||
- [ccr restart](/docs/cli/other-commands#ccr-restart) - Restart the server
|
||||
208
docs/docs/cli/config/basic.md
Normal file
208
docs/docs/cli/config/basic.md
Normal file
@@ -0,0 +1,208 @@
|
||||
# CLI 基础配置
|
||||
|
||||
CLI 使用与 Server 相同的配置文件:`~/.claude-code-router/config.json`
|
||||
|
||||
## 配置文件位置
|
||||
|
||||
```bash
|
||||
~/.claude-code-router/config.json
|
||||
```
|
||||
|
||||
## 快速配置
|
||||
|
||||
使用交互式命令配置:
|
||||
|
||||
```bash
|
||||
ccr model
|
||||
```
|
||||
|
||||
这将引导你完成:
|
||||
1. 选择 LLM 提供商
|
||||
2. 配置 API Key
|
||||
3. 选择模型
|
||||
4. 设置路由规则
|
||||
|
||||
## 手动配置
|
||||
|
||||
### 编辑配置文件
|
||||
|
||||
```bash
|
||||
# 打开配置文件
|
||||
nano ~/.claude-code-router/config.json
|
||||
```
|
||||
|
||||
### 最小配置示例
|
||||
|
||||
```json5
|
||||
{
|
||||
// API 密钥(可选,用于保护服务)
|
||||
"APIKEY": "your-api-key-here",
|
||||
|
||||
// LLM 提供商
|
||||
"Providers": [
|
||||
{
|
||||
"name": "openai",
|
||||
"baseUrl": "https://api.openai.com/v1",
|
||||
"apiKey": "$OPENAI_API_KEY",
|
||||
"models": ["gpt-4", "gpt-3.5-turbo"]
|
||||
}
|
||||
],
|
||||
|
||||
// 默认路由
|
||||
"Router": {
|
||||
"default": "openai,gpt-4"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 环境变量
|
||||
|
||||
配置支持环境变量插值:
|
||||
|
||||
```json5
|
||||
{
|
||||
"Providers": [
|
||||
{
|
||||
"apiKey": "$OPENAI_API_KEY" // 从环境变量读取
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
在 `.bashrc` 或 `.zshrc` 中设置:
|
||||
|
||||
```bash
|
||||
export OPENAI_API_KEY="sk-..."
|
||||
export ANTHROPIC_API_KEY="sk-ant-..."
|
||||
```
|
||||
|
||||
## 常用配置项
|
||||
|
||||
### HOST 和 PORT
|
||||
|
||||
```json5
|
||||
{
|
||||
"HOST": "127.0.0.1", // 监听地址
|
||||
"PORT": 3456 // 监听端口
|
||||
}
|
||||
```
|
||||
|
||||
### 日志配置
|
||||
|
||||
```json5
|
||||
{
|
||||
"LOG": true, // 启用日志
|
||||
"LOG_LEVEL": "info" // 日志级别
|
||||
}
|
||||
```
|
||||
|
||||
### 路由配置
|
||||
|
||||
```json5
|
||||
{
|
||||
"Router": {
|
||||
"default": "openai,gpt-4",
|
||||
"background": "openai,gpt-3.5-turbo",
|
||||
"think": "openai,gpt-4",
|
||||
"longContext": "anthropic,claude-3-opus"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 配置验证
|
||||
|
||||
配置文件会自动验证。常见错误:
|
||||
|
||||
- **缺少 Providers**:必须至少配置一个提供商
|
||||
- **API Key 缺失**:如果配置了 Providers,必须提供 API Key
|
||||
- **模型不存在**:确保模型在提供商的 models 列表中
|
||||
|
||||
## 配置备份
|
||||
|
||||
每次更新配置时会自动备份:
|
||||
|
||||
```
|
||||
~/.claude-code-router/config.backup.{timestamp}.json
|
||||
```
|
||||
|
||||
## 重新加载配置
|
||||
|
||||
修改配置后需要重启服务:
|
||||
|
||||
```bash
|
||||
ccr restart
|
||||
```
|
||||
|
||||
## 查看当前配置
|
||||
|
||||
```bash
|
||||
# 通过 API 查看
|
||||
curl http://localhost:3456/api/config
|
||||
|
||||
# 或查看配置文件
|
||||
cat ~/.claude-code-router/config.json
|
||||
```
|
||||
|
||||
## 示例配置
|
||||
|
||||
### OpenAI
|
||||
|
||||
```json5
|
||||
{
|
||||
"Providers": [
|
||||
{
|
||||
"name": "openai",
|
||||
"baseUrl": "https://api.openai.com/v1",
|
||||
"apiKey": "$OPENAI_API_KEY",
|
||||
"models": ["gpt-4", "gpt-3.5-turbo"]
|
||||
}
|
||||
],
|
||||
"Router": {
|
||||
"default": "openai,gpt-4"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Anthropic
|
||||
|
||||
```json5
|
||||
{
|
||||
"Providers": [
|
||||
{
|
||||
"name": "anthropic",
|
||||
"baseUrl": "https://api.anthropic.com/v1",
|
||||
"apiKey": "$ANTHROPIC_API_KEY",
|
||||
"models": ["claude-3-5-sonnet-20241022", "claude-3-opus-20240229"]
|
||||
}
|
||||
],
|
||||
"Router": {
|
||||
"default": "anthropic,claude-3-5-sonnet-20241022"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 多提供商
|
||||
|
||||
```json5
|
||||
{
|
||||
"Providers": [
|
||||
{
|
||||
"name": "openai",
|
||||
"baseUrl": "https://api.openai.com/v1",
|
||||
"apiKey": "$OPENAI_API_KEY",
|
||||
"models": ["gpt-4", "gpt-3.5-turbo"]
|
||||
},
|
||||
{
|
||||
"name": "anthropic",
|
||||
"baseUrl": "https://api.anthropic.com/v1",
|
||||
"apiKey": "$ANTHROPIC_API_KEY",
|
||||
"models": ["claude-3-5-sonnet-20241022", "claude-3-opus-20240229"]
|
||||
}
|
||||
],
|
||||
"Router": {
|
||||
"default": "openai,gpt-4",
|
||||
"think": "anthropic,claude-3-5-sonnet-20241022",
|
||||
"background": "openai,gpt-3.5-turbo"
|
||||
}
|
||||
}
|
||||
```
|
||||
213
docs/docs/cli/config/project-level.md
Normal file
213
docs/docs/cli/config/project-level.md
Normal file
@@ -0,0 +1,213 @@
|
||||
# 项目级配置
|
||||
|
||||
除了全局配置,`ccr` 还支持为特定项目设置不同的路由规则。
|
||||
|
||||
## 项目配置文件
|
||||
|
||||
项目配置文件位于:
|
||||
|
||||
```
|
||||
~/.claude/projects/<project-id>/claude-code-router.json
|
||||
```
|
||||
|
||||
其中 `<project-id>` 是 Claude Code 项目的唯一标识符。
|
||||
|
||||
## 项目配置结构
|
||||
|
||||
```json5
|
||||
{
|
||||
"Router": {
|
||||
"default": "openai,gpt-4",
|
||||
"background": "openai,gpt-3.5-turbo"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 查找项目 ID
|
||||
|
||||
### 方法一:使用 CLI
|
||||
|
||||
```bash
|
||||
# 在项目目录中运行
|
||||
ccr status
|
||||
```
|
||||
|
||||
输出会显示当前项目 ID:
|
||||
|
||||
```
|
||||
Project: my-project (abc123def456)
|
||||
```
|
||||
|
||||
### 方法二:查看 Claude Code 配置
|
||||
|
||||
```bash
|
||||
cat ~/.claude.json
|
||||
```
|
||||
|
||||
找到你的项目 ID:
|
||||
|
||||
```json
|
||||
{
|
||||
"projects": {
|
||||
"abc123def456": {
|
||||
"path": "/path/to/your/project",
|
||||
"name": "my-project"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 创建项目配置
|
||||
|
||||
### 手动创建
|
||||
|
||||
```bash
|
||||
# 创建项目配置目录
|
||||
mkdir -p ~/.claude/projects/abc123def456
|
||||
|
||||
# 创建配置文件
|
||||
cat > ~/.claude/projects/abc123def456/claude-code-router.json << 'EOF'
|
||||
{
|
||||
"Router": {
|
||||
"default": "anthropic,claude-3-5-sonnet-20241022",
|
||||
"background": "openai,gpt-3.5-turbo"
|
||||
}
|
||||
}
|
||||
EOF
|
||||
```
|
||||
|
||||
### 使用 ccr model 命令
|
||||
|
||||
```bash
|
||||
# 在项目目录中运行
|
||||
cd /path/to/your/project
|
||||
ccr model --project
|
||||
```
|
||||
|
||||
## 配置优先级
|
||||
|
||||
路由配置的优先级(从高到低):
|
||||
|
||||
1. **自定义路由函数** (`CUSTOM_ROUTER_PATH`)
|
||||
2. **项目级配置** (`~/.claude/projects/<id>/claude-code-router.json`)
|
||||
3. **全局配置** (`~/.claude-code-router/config.json`)
|
||||
4. **内置路由规则**
|
||||
|
||||
## 使用场景
|
||||
|
||||
### 场景一:不同项目使用不同模型
|
||||
|
||||
```json5
|
||||
// Web 项目使用 GPT-4
|
||||
~/.claude/projects/web-project-id/claude-code-router.json:
|
||||
{
|
||||
"Router": {
|
||||
"default": "openai,gpt-4"
|
||||
}
|
||||
}
|
||||
|
||||
// AI 项目使用 Claude
|
||||
~/.claude/projects/ai-project-id/claude-code-router.json:
|
||||
{
|
||||
"Router": {
|
||||
"default": "anthropic,claude-3-5-sonnet-20241022"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 场景二:测试项目使用低成本模型
|
||||
|
||||
```json5
|
||||
~/.claude/projects/test-project-id/claude-code-router.json:
|
||||
{
|
||||
"Router": {
|
||||
"default": "openai,gpt-3.5-turbo",
|
||||
"background": "openai,gpt-3.5-turbo"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 场景三:长上下文项目
|
||||
|
||||
```json5
|
||||
~/.claude/projects/long-context-project-id/claude-code-router.json:
|
||||
{
|
||||
"Router": {
|
||||
"default": "anthropic,claude-3-opus-20240229",
|
||||
"longContext": "anthropic,claude-3-opus-20240229"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 验证项目配置
|
||||
|
||||
```bash
|
||||
# 查看当前项目使用的路由
|
||||
ccr status
|
||||
|
||||
# 查看日志确认路由决策
|
||||
tail -f ~/.claude-code-router/claude-code-router.log
|
||||
```
|
||||
|
||||
## 删除项目配置
|
||||
|
||||
```bash
|
||||
rm ~/.claude/projects/<project-id>/claude-code-router.json
|
||||
```
|
||||
|
||||
删除后会回退到全局配置。
|
||||
|
||||
## 完整示例
|
||||
|
||||
假设你有两个项目:
|
||||
|
||||
### 全局配置(`~/.claude-code-router/config.json`)
|
||||
|
||||
```json5
|
||||
{
|
||||
"Providers": [
|
||||
{
|
||||
"name": "openai",
|
||||
"baseUrl": "https://api.openai.com/v1",
|
||||
"apiKey": "$OPENAI_API_KEY",
|
||||
"models": ["gpt-4", "gpt-3.5-turbo"]
|
||||
},
|
||||
{
|
||||
"name": "anthropic",
|
||||
"baseUrl": "https://api.anthropic.com/v1",
|
||||
"apiKey": "$ANTHROPIC_API_KEY",
|
||||
"models": ["claude-3-5-sonnet-20241022"]
|
||||
}
|
||||
],
|
||||
"Router": {
|
||||
"default": "openai,gpt-4",
|
||||
"background": "openai,gpt-3.5-turbo"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Web 项目配置
|
||||
|
||||
```json5
|
||||
{
|
||||
"Router": {
|
||||
"default": "openai,gpt-4"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### AI 项目配置
|
||||
|
||||
```json5
|
||||
{
|
||||
"Router": {
|
||||
"default": "anthropic,claude-3-5-sonnet-20241022",
|
||||
"think": "anthropic,claude-3-5-sonnet-20241022"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
这样:
|
||||
- Web 项目使用 GPT-4
|
||||
- AI 项目使用 Claude
|
||||
- 所有项目的后台任务使用 GPT-3.5-turbo(继承全局配置)
|
||||
45
docs/docs/cli/installation.md
Normal file
45
docs/docs/cli/installation.md
Normal file
@@ -0,0 +1,45 @@
|
||||
---
|
||||
sidebar_position: 2
|
||||
---
|
||||
|
||||
# Installation
|
||||
|
||||
Install Claude Code Router globally using your preferred package manager.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- **Node.js**: >= 18.0.0
|
||||
- **pnpm**: >= 8.0.0 (if using pnpm)
|
||||
- An API key from your preferred LLM provider
|
||||
|
||||
## Install via npm
|
||||
|
||||
```bash
|
||||
npm install -g @musistudio/claude-code-router-cli
|
||||
```
|
||||
|
||||
## Install via pnpm
|
||||
|
||||
```bash
|
||||
pnpm add -g @musistudio/claude-code-router-cli
|
||||
```
|
||||
|
||||
## Install via Yarn
|
||||
|
||||
```bash
|
||||
yarn global add @musistudio/claude-code-router-cli
|
||||
```
|
||||
|
||||
## Verify Installation
|
||||
|
||||
After installation, verify that `ccr` is available:
|
||||
|
||||
```bash
|
||||
ccr --version
|
||||
```
|
||||
|
||||
You should see the version number displayed.
|
||||
|
||||
## Next Steps
|
||||
|
||||
Once installed, proceed to [Quick Start](/docs/quick-start) to configure and start using the router.
|
||||
83
docs/docs/cli/intro.md
Normal file
83
docs/docs/cli/intro.md
Normal file
@@ -0,0 +1,83 @@
|
||||
# CLI 简介
|
||||
|
||||
Claude Code Router CLI (`ccr`) 是一个命令行工具,用于管理和控制 Claude Code Router 服务。
|
||||
|
||||
## 功能概述
|
||||
|
||||
`ccr` 提供以下功能:
|
||||
|
||||
- **服务管理**:启动、停止、重启服务
|
||||
- **配置管理**:交互式配置模型选择
|
||||
- **状态查看**:查看服务运行状态
|
||||
- **代码执行**:直接执行 `claude` 命令
|
||||
- **环境集成**:输出环境变量用于 shell 集成
|
||||
- **Web UI**:打开 Web 管理界面
|
||||
- **状态栏**:集成到编辑器状态栏
|
||||
|
||||
## 安装
|
||||
|
||||
```bash
|
||||
npm install -g @musistudio/claude-code-router-cli
|
||||
```
|
||||
|
||||
或使用项目别名:
|
||||
|
||||
```bash
|
||||
npm install -g claude-code-router
|
||||
```
|
||||
|
||||
## 基本使用
|
||||
|
||||
### 启动服务
|
||||
|
||||
```bash
|
||||
ccr start
|
||||
```
|
||||
|
||||
### 查看状态
|
||||
|
||||
```bash
|
||||
ccr status
|
||||
```
|
||||
|
||||
### 停止服务
|
||||
|
||||
```bash
|
||||
ccr stop
|
||||
```
|
||||
|
||||
### 查看模型
|
||||
|
||||
```bash
|
||||
ccr model
|
||||
```
|
||||
|
||||
## 与 Claude Code 集成
|
||||
|
||||
`ccr` 可以与 Claude Code 无缝集成,将请求路由到你选择的 LLM 提供商。
|
||||
|
||||
### 方式一:设置 API 地址
|
||||
|
||||
```bash
|
||||
export ANTHROPIC_BASE_URL="http://localhost:3456/v1"
|
||||
export ANTHROPIC_API_KEY="your-api-key"
|
||||
```
|
||||
|
||||
### 方式二:使用 activate 命令
|
||||
|
||||
```bash
|
||||
eval "$(ccr activate)"
|
||||
```
|
||||
|
||||
## 配置文件
|
||||
|
||||
`ccr` 使用与 Server 相同的配置文件:`~/.claude-code-router/config.json`
|
||||
|
||||
配置一次,CLI 和 Server 都会使用。
|
||||
|
||||
## 下一步
|
||||
|
||||
- [安装指南](/docs/cli/installation) - 详细安装说明
|
||||
- [快速开始](/docs/cli/quick-start) - 5 分钟上手
|
||||
- [命令参考](/docs/category/cli-commands) - 完整命令列表
|
||||
- [配置说明](/docs/category/cli-config) - 配置文件详解
|
||||
81
docs/docs/cli/quick-start.md
Normal file
81
docs/docs/cli/quick-start.md
Normal file
@@ -0,0 +1,81 @@
|
||||
---
|
||||
sidebar_position: 3
|
||||
---
|
||||
|
||||
# Quick Start
|
||||
|
||||
Get up and running with Claude Code Router in 5 minutes.
|
||||
|
||||
## 1. Start the Router
|
||||
|
||||
```bash
|
||||
ccr start
|
||||
```
|
||||
|
||||
The router will start on `http://localhost:8080` by default.
|
||||
|
||||
## 2. Configure Environment Variables
|
||||
|
||||
Set the following environment variables in your shell:
|
||||
|
||||
```bash
|
||||
export ANTHROPIC_API_URL="http://localhost:8080/v1"
|
||||
export ANTHROPIC_API_KEY="your-provider-api-key"
|
||||
```
|
||||
|
||||
Or use the `ccr activate` command to get the environment variables:
|
||||
|
||||
```bash
|
||||
eval "$(ccr activate)"
|
||||
```
|
||||
|
||||
## 3. Use Claude Code
|
||||
|
||||
Now you can use Claude Code normally:
|
||||
|
||||
```bash
|
||||
claude code
|
||||
```
|
||||
|
||||
Your requests will be routed through Claude Code Router to your configured provider.
|
||||
|
||||
## 4. Configure Providers (Optional)
|
||||
|
||||
To configure multiple providers or custom routing, use:
|
||||
|
||||
```bash
|
||||
ccr model
|
||||
```
|
||||
|
||||
This will open an interactive menu to select and configure models.
|
||||
|
||||
Or edit the configuration file directly:
|
||||
|
||||
```bash
|
||||
# Open config in your default editor
|
||||
ccr config edit
|
||||
```
|
||||
|
||||
Example configuration (`~/.claude-code-router/config.json`):
|
||||
|
||||
```json
|
||||
{
|
||||
"Providers": [
|
||||
{
|
||||
"NAME": "deepseek",
|
||||
"HOST": "https://api.deepseek.com",
|
||||
"APIKEY": "your-deepseek-api-key",
|
||||
"MODELS": ["deepseek-chat", "deepseek-coder"]
|
||||
}
|
||||
],
|
||||
"Router": {
|
||||
"default": "deepseek,deepseek-chat"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## What's Next?
|
||||
|
||||
- [Basic Configuration](/docs/config/basic) - Learn about configuration options
|
||||
- [Routing](/docs/config/routing) - Configure smart routing rules
|
||||
- [CLI Commands](/docs/cli/start) - Explore all CLI commands
|
||||
40
docs/docs/server/advanced/agents.md
Normal file
40
docs/docs/server/advanced/agents.md
Normal file
@@ -0,0 +1,40 @@
|
||||
---
|
||||
sidebar_position: 2
|
||||
---
|
||||
|
||||
# Agents
|
||||
|
||||
Extend functionality with the agent system.
|
||||
|
||||
## What are Agents?
|
||||
|
||||
Agents are pluggable feature modules that can:
|
||||
- Detect whether to handle a request
|
||||
- Modify requests
|
||||
- Provide custom tools
|
||||
|
||||
## Built-in Agents
|
||||
|
||||
### Image Agent
|
||||
|
||||
Handles image-related tasks by detecting image URLs or file paths in requests.
|
||||
|
||||
## Agent Configuration
|
||||
|
||||
Agents are configured in the server configuration and automatically loaded.
|
||||
|
||||
## Agent Tool Call Flow
|
||||
|
||||
1. Detect and mark agents in `preHandler` hook
|
||||
2. Add agent tools to the request
|
||||
3. Intercept tool call events in `onSend` hook
|
||||
4. Execute agent tool and initiate new LLM request
|
||||
5. Stream results back
|
||||
|
||||
## Creating Custom Agents
|
||||
|
||||
Coming soon! Custom agent support is under development.
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [Presets](/docs/advanced/presets) - Use predefined configurations
|
||||
126
docs/docs/server/advanced/custom-router.md
Normal file
126
docs/docs/server/advanced/custom-router.md
Normal file
@@ -0,0 +1,126 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
# Custom Router
|
||||
|
||||
Write your own routing logic in JavaScript.
|
||||
|
||||
## Creating a Custom Router
|
||||
|
||||
Create a JavaScript file that exports a routing function:
|
||||
|
||||
```javascript
|
||||
// custom-router.js
|
||||
module.exports = function(config, context) {
|
||||
const { scenario, projectId, tokenCount, request } = context;
|
||||
|
||||
// Your custom logic here
|
||||
if (scenario === 'background') {
|
||||
return 'groq,llama-3.3-70b-versatile';
|
||||
}
|
||||
|
||||
if (tokenCount > 100000) {
|
||||
return 'gemini,gemini-1.5-pro';
|
||||
}
|
||||
|
||||
// Check request content
|
||||
if (request && request.system && request.system.includes('code')) {
|
||||
return 'deepseek,deepseek-coder';
|
||||
}
|
||||
|
||||
// Default
|
||||
return 'deepseek,deepseek-chat';
|
||||
};
|
||||
```
|
||||
|
||||
## Context Object
|
||||
|
||||
The router function receives a context object with:
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `scenario` | string | Detected scenario (background, think, webSearch, image, etc.) |
|
||||
| `projectId` | string | Project ID from Claude Code |
|
||||
| `tokenCount` | number | Estimated token count of the request |
|
||||
| `request` | object | Full request object |
|
||||
|
||||
## Configuration
|
||||
|
||||
Set the environment variable to use your custom router:
|
||||
|
||||
```bash
|
||||
export CUSTOM_ROUTER_PATH="/path/to/custom-router.js"
|
||||
```
|
||||
|
||||
Or set it in your shell configuration:
|
||||
|
||||
```bash
|
||||
# ~/.bashrc or ~/.zshrc
|
||||
export CUSTOM_ROUTER_PATH="/path/to/custom-router.js"
|
||||
```
|
||||
|
||||
## Return Format
|
||||
|
||||
The router function should return a string in the format:
|
||||
|
||||
```
|
||||
{provider-name},{model-name}
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
deepseek,deepseek-chat
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
If your router function throws an error or returns an invalid format, the router will fall back to the default routing configuration.
|
||||
|
||||
## Example: Time-Based Routing
|
||||
|
||||
```javascript
|
||||
module.exports = function(config, context) {
|
||||
const hour = new Date().getHours();
|
||||
|
||||
// Use faster models during work hours
|
||||
if (hour >= 9 && hour <= 18) {
|
||||
return 'groq,llama-3.3-70b-versatile';
|
||||
}
|
||||
|
||||
// Use more capable models outside work hours
|
||||
return 'deepseek,deepseek-chat';
|
||||
};
|
||||
```
|
||||
|
||||
## Example: Cost Optimization
|
||||
|
||||
```javascript
|
||||
module.exports = function(config, context) {
|
||||
const { tokenCount } = context;
|
||||
|
||||
// Use cheaper models for large requests
|
||||
if (tokenCount > 50000) {
|
||||
return 'groq,llama-3.3-70b-versatile';
|
||||
}
|
||||
|
||||
// Use default for smaller requests
|
||||
return 'deepseek,deepseek-chat';
|
||||
};
|
||||
```
|
||||
|
||||
## Testing Your Router
|
||||
|
||||
Test your custom router by checking the logs:
|
||||
|
||||
```bash
|
||||
tail -f ~/.claude-code-router/claude-code-router.log
|
||||
```
|
||||
|
||||
Look for routing decisions to see which model is being selected.
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [Agents](/docs/advanced/agents) - Extend functionality with agents
|
||||
- [Presets](/docs/advanced/presets) - Use predefined configurations
|
||||
64
docs/docs/server/advanced/presets.md
Normal file
64
docs/docs/server/advanced/presets.md
Normal file
@@ -0,0 +1,64 @@
|
||||
---
|
||||
sidebar_position: 3
|
||||
---
|
||||
|
||||
# Presets
|
||||
|
||||
Use predefined configurations for quick setup.
|
||||
|
||||
## What are Presets?
|
||||
|
||||
Presets are pre-configured settings that include provider configurations, routing rules, and transformers optimized for specific use cases.
|
||||
|
||||
## Available Presets
|
||||
|
||||
### Development
|
||||
|
||||
Optimized for software development tasks:
|
||||
- Fast response times
|
||||
- Good for code generation
|
||||
- Cost-effective
|
||||
|
||||
### Research
|
||||
|
||||
Optimized for research and analysis:
|
||||
- Long context support
|
||||
- High-quality responses
|
||||
- More capable models
|
||||
|
||||
### Balanced
|
||||
|
||||
A balance between speed and quality:
|
||||
- Good general-purpose performance
|
||||
- Reasonable costs
|
||||
- Wide model support
|
||||
|
||||
## Using Presets
|
||||
|
||||
Use the CLI to apply a preset:
|
||||
|
||||
```bash
|
||||
ccr preset apply development
|
||||
```
|
||||
|
||||
List available presets:
|
||||
|
||||
```bash
|
||||
ccr preset list
|
||||
```
|
||||
|
||||
## Creating Custom Presets
|
||||
|
||||
You can create custom presets by saving your configuration and reloading it later:
|
||||
|
||||
```bash
|
||||
# Save current configuration as a preset
|
||||
ccr preset save my-preset
|
||||
|
||||
# Load a saved preset
|
||||
ccr preset apply my-preset
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [CLI Reference](/docs/cli/start) - Complete CLI command reference
|
||||
220
docs/docs/server/api/config-api.md
Normal file
220
docs/docs/server/api/config-api.md
Normal file
@@ -0,0 +1,220 @@
|
||||
# 配置 API
|
||||
|
||||
## GET /api/config
|
||||
|
||||
获取当前服务器配置。
|
||||
|
||||
### 请求示例
|
||||
|
||||
```bash
|
||||
curl http://localhost:3456/api/config \
|
||||
-H "x-api-key: your-api-key"
|
||||
```
|
||||
|
||||
### 响应示例
|
||||
|
||||
```json
|
||||
{
|
||||
"HOST": "0.0.0.0",
|
||||
"PORT": 3456,
|
||||
"APIKEY": "sk-xxxxx",
|
||||
"Providers": [
|
||||
{
|
||||
"name": "openai",
|
||||
"baseUrl": "https://api.openai.com/v1",
|
||||
"apiKey": "sk-...",
|
||||
"models": ["gpt-4", "gpt-3.5-turbo"]
|
||||
}
|
||||
],
|
||||
"Router": {
|
||||
"default": "openai,gpt-4"
|
||||
},
|
||||
"transformers": [
|
||||
"anthropic"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## POST /api/config
|
||||
|
||||
更新服务器配置。更新后会自动备份旧配置。
|
||||
|
||||
### 请求示例
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:3456/api/config \
|
||||
-H "x-api-key: your-api-key" \
|
||||
-H "content-type: application/json" \
|
||||
-d '{
|
||||
"HOST": "0.0.0.0",
|
||||
"PORT": 3456,
|
||||
"Providers": [
|
||||
{
|
||||
"name": "openai",
|
||||
"baseUrl": "https://api.openai.com/v1",
|
||||
"apiKey": "$OPENAI_API_KEY",
|
||||
"models": ["gpt-4"]
|
||||
}
|
||||
],
|
||||
"Router": {
|
||||
"default": "openai,gpt-4"
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
### 配置对象结构
|
||||
|
||||
#### 基础配置
|
||||
|
||||
| 字段 | 类型 | 必需 | 说明 |
|
||||
|------|------|------|------|
|
||||
| `HOST` | string | 否 | 监听地址(默认 127.0.0.1) |
|
||||
| `PORT` | integer | 否 | 监听端口(默认 3456) |
|
||||
| `APIKEY` | string | 否 | API 密钥 |
|
||||
| `LOG` | boolean | 否 | 是否启用日志(默认 true) |
|
||||
| `LOG_LEVEL` | string | 否 | 日志级别(debug/info/warn/error) |
|
||||
|
||||
#### Providers 配置
|
||||
|
||||
```json
|
||||
{
|
||||
"Providers": [
|
||||
{
|
||||
"name": "provider-name",
|
||||
"baseUrl": "https://api.example.com/v1",
|
||||
"apiKey": "your-api-key",
|
||||
"models": ["model-1", "model-2"]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
| 字段 | 类型 | 必需 | 说明 |
|
||||
|------|------|------|------|
|
||||
| `name` | string | 是 | 提供商名称 |
|
||||
| `baseUrl` | string | 是 | API 基础 URL |
|
||||
| `apiKey` | string | 是 | API 密钥 |
|
||||
| `models` | array | 是 | 支持的模型列表 |
|
||||
|
||||
#### Router 配置
|
||||
|
||||
```json
|
||||
{
|
||||
"Router": {
|
||||
"default": "provider,model",
|
||||
"longContextThreshold": 100000,
|
||||
"routes": {
|
||||
"background": "lightweight-model",
|
||||
"think": "powerful-model",
|
||||
"longContext": "long-context-model",
|
||||
"webSearch": "search-model",
|
||||
"image": "vision-model"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Transformers 配置
|
||||
|
||||
```json
|
||||
{
|
||||
"transformers": [
|
||||
{
|
||||
"name": "anthropic",
|
||||
"provider": "provider-name",
|
||||
"models": ["model-1"],
|
||||
"options": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 响应示例
|
||||
|
||||
成功:
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "Config saved successfully"
|
||||
}
|
||||
```
|
||||
|
||||
### 配置备份
|
||||
|
||||
每次更新配置时,旧配置会自动备份到:
|
||||
|
||||
```
|
||||
~/.claude-code-router/config.backup.{timestamp}.json
|
||||
```
|
||||
|
||||
保留最近 3 个备份。
|
||||
|
||||
## GET /api/transformers
|
||||
|
||||
获取服务器加载的所有转换器列表。
|
||||
|
||||
### 请求示例
|
||||
|
||||
```bash
|
||||
curl http://localhost:3456/api/transformers \
|
||||
-H "x-api-key: your-api-key"
|
||||
```
|
||||
|
||||
### 响应示例
|
||||
|
||||
```json
|
||||
{
|
||||
"transformers": [
|
||||
{
|
||||
"name": "anthropic",
|
||||
"endpoint": null
|
||||
},
|
||||
{
|
||||
"name": "openai",
|
||||
"endpoint": null
|
||||
},
|
||||
{
|
||||
"name": "gemini",
|
||||
"endpoint": "https://generativelanguage.googleapis.com"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 转换器列表
|
||||
|
||||
内置转换器:
|
||||
|
||||
- `anthropic` - Anthropic Claude 格式
|
||||
- `openai` - OpenAI 格式
|
||||
- `deepseek` - DeepSeek 格式
|
||||
- `gemini` - Google Gemini 格式
|
||||
- `openrouter` - OpenRouter 格式
|
||||
- `groq` - Groq 格式
|
||||
- `maxtoken` - 调整 max_tokens 参数
|
||||
- `tooluse` - 工具使用转换
|
||||
- `reasoning` - 推理模式转换
|
||||
- `enhancetool` - 增强工具功能
|
||||
|
||||
## 环境变量插值
|
||||
|
||||
配置支持环境变量插值:
|
||||
|
||||
```json
|
||||
{
|
||||
"Providers": [
|
||||
{
|
||||
"apiKey": "$OPENAI_API_KEY"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
或使用 `${VAR_NAME}` 格式:
|
||||
|
||||
```json
|
||||
{
|
||||
"baseUrl": "${API_BASE_URL}"
|
||||
}
|
||||
```
|
||||
190
docs/docs/server/api/logs-api.md
Normal file
190
docs/docs/server/api/logs-api.md
Normal file
@@ -0,0 +1,190 @@
|
||||
# 日志 API
|
||||
|
||||
## GET /api/logs/files
|
||||
|
||||
获取所有可用的日志文件列表。
|
||||
|
||||
### 请求示例
|
||||
|
||||
```bash
|
||||
curl http://localhost:3456/api/logs/files \
|
||||
-H "x-api-key: your-api-key"
|
||||
```
|
||||
|
||||
### 响应示例
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"name": "ccr-20241226143022.log",
|
||||
"path": "/home/user/.claude-code-router/logs/ccr-20241226143022.log",
|
||||
"size": 1024000,
|
||||
"lastModified": "2024-12-26T14:30:22.000Z"
|
||||
},
|
||||
{
|
||||
"name": "ccr-20241226143021.log",
|
||||
"path": "/home/user/.claude-code-router/logs/ccr-20241226143021.log",
|
||||
"size": 980000,
|
||||
"lastModified": "2024-12-26T14:30:21.000Z"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### 字段说明
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `name` | string | 文件名 |
|
||||
| `path` | string | 完整文件路径 |
|
||||
| `size` | integer | 文件大小(字节) |
|
||||
| `lastModified` | string | 最后修改时间(ISO 8601) |
|
||||
|
||||
文件按修改时间倒序排列。
|
||||
|
||||
## GET /api/logs
|
||||
|
||||
获取指定日志文件的内容。
|
||||
|
||||
### 查询参数
|
||||
|
||||
| 参数 | 类型 | 必需 | 说明 |
|
||||
|------|------|------|------|
|
||||
| `file` | string | 否 | 日志文件路径(默认使用 app.log) |
|
||||
|
||||
### 请求示例(获取默认日志)
|
||||
|
||||
```bash
|
||||
curl "http://localhost:3456/api/logs" \
|
||||
-H "x-api-key: your-api-key"
|
||||
```
|
||||
|
||||
### 请求示例(获取指定文件)
|
||||
|
||||
```bash
|
||||
curl "http://localhost:3456/api/logs?file=/home/user/.claude-code-router/logs/ccr-20241226143022.log" \
|
||||
-H "x-api-key: your-api-key"
|
||||
```
|
||||
|
||||
### 响应示例
|
||||
|
||||
```json
|
||||
[
|
||||
"{\"level\":30,\"time\":1703550622000,\"pid\":12345,\"hostname\":\"server\",\"msg\":\"Incoming request\",\"req\":{\"id\":1,\"method\":\"POST\",\"url\":\"/v1/messages\",\"remoteAddress\":\"127.0.0.1\"}}",
|
||||
"{\"level\":30,\"time\":1703550622500,\"pid\":12345,\"hostname\":\"server\",\"msg\":\"Request completed\",\"res\":{\"statusCode\":200,\"responseTime\":500}}",
|
||||
"..."
|
||||
]
|
||||
```
|
||||
|
||||
返回的是日志行数组,每行是一个 JSON 字符串。
|
||||
|
||||
### 日志格式
|
||||
|
||||
日志使用 Pino 格式:
|
||||
|
||||
```json
|
||||
{
|
||||
"level": 30,
|
||||
"time": 1703550622000,
|
||||
"pid": 12345,
|
||||
"hostname": "server",
|
||||
"msg": "Incoming request",
|
||||
"req": {
|
||||
"id": 1,
|
||||
"method": "POST",
|
||||
"url": "/v1/messages",
|
||||
"remoteAddress": "127.0.0.1"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 日志级别
|
||||
|
||||
| 级别 | 值 | 说明 |
|
||||
|------|------|------|
|
||||
| `trace` | 10 | 最详细的日志 |
|
||||
| `debug` | 20 | 调试信息 |
|
||||
| `info` | 30 | 一般信息 |
|
||||
| `warn` | 40 | 警告信息 |
|
||||
| `error` | 50 | 错误信息 |
|
||||
| `fatal` | 60 | 致命错误 |
|
||||
|
||||
## DELETE /api/logs
|
||||
|
||||
清除指定日志文件的内容。
|
||||
|
||||
### 查询参数
|
||||
|
||||
| 参数 | 类型 | 必需 | 说明 |
|
||||
|------|------|------|------|
|
||||
| `file` | string | 否 | 日志文件路径(默认使用 app.log) |
|
||||
|
||||
### 请求示例(清除默认日志)
|
||||
|
||||
```bash
|
||||
curl -X DELETE "http://localhost:3456/api/logs" \
|
||||
-H "x-api-key: your-api-key"
|
||||
```
|
||||
|
||||
### 请求示例(清除指定文件)
|
||||
|
||||
```bash
|
||||
curl -X DELETE "http://localhost:3456/api/logs?file=/home/user/.claude-code-router/logs/ccr-20241226143022.log" \
|
||||
-H "x-api-key: your-api-key"
|
||||
```
|
||||
|
||||
### 响应示例
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "Logs cleared successfully"
|
||||
}
|
||||
```
|
||||
|
||||
## 日志位置
|
||||
|
||||
### 服务器日志
|
||||
|
||||
位置:`~/.claude-code-router/logs/`
|
||||
|
||||
文件命名:`ccr-{YYYYMMDD}{HH}{MM}{SS}.log`
|
||||
|
||||
内容:HTTP 请求、API 调用、服务器事件
|
||||
|
||||
### 应用日志
|
||||
|
||||
位置:`~/.claude-code-router/claude-code-router.log`
|
||||
|
||||
内容:路由决策、业务逻辑事件
|
||||
|
||||
## 日志轮转
|
||||
|
||||
服务器日志使用 rotating-file-stream 自动轮转:
|
||||
|
||||
- **maxFiles**: 3 - 保留最近 3 个日志文件
|
||||
- **interval**: 1d - 每天轮转
|
||||
- **maxSize**: 50M - 单个文件最大 50MB
|
||||
|
||||
## 日志分析
|
||||
|
||||
### 使用 jq 分析日志
|
||||
|
||||
```bash
|
||||
# 查看所有错误日志
|
||||
curl "http://localhost:3456/api/logs" \
|
||||
-H "x-api-key: your-api-key" | \
|
||||
jq -r '.[] | fromjson | select(.level >= 40)'
|
||||
|
||||
# 统计请求次数
|
||||
curl "http://localhost:3456/api/logs" \
|
||||
-H "x-api-key: your-api-key" | \
|
||||
jq -r '.[] | fromjson | .req.method' | \
|
||||
sort | uniq -c
|
||||
```
|
||||
|
||||
### 实时监控日志
|
||||
|
||||
```bash
|
||||
# 通过 API 实时获取最新日志
|
||||
watch -n 5 'curl -s "http://localhost:3456/api/logs" -H "x-api-key: your-api-key" | jq -r ".[-10:]"'
|
||||
```
|
||||
220
docs/docs/server/api/messages-api.md
Normal file
220
docs/docs/server/api/messages-api.md
Normal file
@@ -0,0 +1,220 @@
|
||||
# 消息 API
|
||||
|
||||
## POST /v1/messages
|
||||
|
||||
发送消息到 LLM,兼容 Anthropic Claude API 格式。
|
||||
|
||||
### 请求格式
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:3456/v1/messages \
|
||||
-H "x-api-key: your-api-key" \
|
||||
-H "content-type: application/json" \
|
||||
-d '{
|
||||
"model": "claude-3-5-sonnet-20241022",
|
||||
"max_tokens": 1024,
|
||||
"messages": [
|
||||
{
|
||||
"role": "user",
|
||||
"content": "Hello, Claude!"
|
||||
}
|
||||
]
|
||||
}'
|
||||
```
|
||||
|
||||
### 请求参数
|
||||
|
||||
| 参数 | 类型 | 必需 | 说明 |
|
||||
|------|------|------|------|
|
||||
| `model` | string | 是 | 模型名称(会被路由到实际提供商) |
|
||||
| `messages` | array | 是 | 消息数组 |
|
||||
| `max_tokens` | integer | 是 | 最大生成 Token 数 |
|
||||
| `system` | string | 否 | 系统提示词 |
|
||||
| `tools` | array | 否 | 可用工具列表 |
|
||||
| `stream` | boolean | 否 | 是否使用流式响应(默认 false) |
|
||||
| `temperature` | number | 否 | 温度参数(0-1) |
|
||||
|
||||
### 消息对象格式
|
||||
|
||||
```json
|
||||
{
|
||||
"role": "user|assistant",
|
||||
"content": "string | array"
|
||||
}
|
||||
```
|
||||
|
||||
### 响应格式(非流式)
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "msg_xxx",
|
||||
"type": "message",
|
||||
"role": "assistant",
|
||||
"content": [
|
||||
{
|
||||
"type": "text",
|
||||
"text": "Hello! How can I help you today?"
|
||||
}
|
||||
],
|
||||
"model": "claude-3-5-sonnet-20241022",
|
||||
"stop_reason": "end_turn",
|
||||
"usage": {
|
||||
"input_tokens": 10,
|
||||
"output_tokens": 20
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 流式响应
|
||||
|
||||
设置 `stream: true` 启用流式响应:
|
||||
|
||||
```json
|
||||
{
|
||||
"model": "claude-3-5-sonnet-20241022",
|
||||
"max_tokens": 1024,
|
||||
"messages": [...],
|
||||
"stream": true
|
||||
}
|
||||
```
|
||||
|
||||
流式响应事件类型:
|
||||
|
||||
- `message_start` - 消息开始
|
||||
- `content_block_start` - 内容块开始
|
||||
- `content_block_delta` - 内容增量
|
||||
- `content_block_stop` - 内容块结束
|
||||
- `message_delta` - 消息元数据(usage)
|
||||
- `message_stop` - 消息结束
|
||||
|
||||
### 工具使用
|
||||
|
||||
支持函数调用(Tool Use):
|
||||
|
||||
```json
|
||||
{
|
||||
"model": "claude-3-5-sonnet-20241022",
|
||||
"max_tokens": 1024,
|
||||
"messages": [
|
||||
{
|
||||
"role": "user",
|
||||
"content": "What's the weather like?"
|
||||
}
|
||||
],
|
||||
"tools": [
|
||||
{
|
||||
"name": "get_weather",
|
||||
"description": "Get the current weather",
|
||||
"input_schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"location": {
|
||||
"type": "string",
|
||||
"description": "City name"
|
||||
}
|
||||
},
|
||||
"required": ["location"]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 多模态支持
|
||||
|
||||
支持图片输入:
|
||||
|
||||
```json
|
||||
{
|
||||
"role": "user",
|
||||
"content": [
|
||||
{
|
||||
"type": "image",
|
||||
"source": {
|
||||
"type": "base64",
|
||||
"media_type": "image/png",
|
||||
"data": "iVBORw0KGgo..."
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"text": "Describe this image"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## POST /v1/messages/count_tokens
|
||||
|
||||
计算消息的 Token 数量。
|
||||
|
||||
### 请求格式
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:3456/v1/messages/count_tokens \
|
||||
-H "x-api-key: your-api-key" \
|
||||
-H "content-type: application/json" \
|
||||
-d '{
|
||||
"model": "claude-3-5-sonnet-20241022",
|
||||
"messages": [
|
||||
{
|
||||
"role": "user",
|
||||
"content": "Hello!"
|
||||
}
|
||||
],
|
||||
"tools": [],
|
||||
"system": "You are a helpful assistant."
|
||||
}'
|
||||
```
|
||||
|
||||
### 请求参数
|
||||
|
||||
| 参数 | 类型 | 必需 | 说明 |
|
||||
|------|------|------|------|
|
||||
| `model` | string | 是 | 模型名称 |
|
||||
| `messages` | array | 是 | 消息数组 |
|
||||
| `tools` | array | 否 | 工具列表 |
|
||||
| `system` | string | 否 | 系统提示词 |
|
||||
|
||||
### 响应格式
|
||||
|
||||
```json
|
||||
{
|
||||
"input_tokens": 42
|
||||
}
|
||||
```
|
||||
|
||||
## 错误响应
|
||||
|
||||
### 400 Bad Request
|
||||
|
||||
```json
|
||||
{
|
||||
"error": {
|
||||
"type": "invalid_request_error",
|
||||
"message": "messages is required"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 401 Unauthorized
|
||||
|
||||
```json
|
||||
{
|
||||
"error": {
|
||||
"type": "authentication_error",
|
||||
"message": "Invalid API key"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 500 Internal Server Error
|
||||
|
||||
```json
|
||||
{
|
||||
"error": {
|
||||
"type": "api_error",
|
||||
"message": "Failed to connect to provider"
|
||||
}
|
||||
}
|
||||
```
|
||||
129
docs/docs/server/api/overview.md
Normal file
129
docs/docs/server/api/overview.md
Normal file
@@ -0,0 +1,129 @@
|
||||
# API 概览
|
||||
|
||||
Claude Code Router Server 提供了完整的 HTTP API,支持:
|
||||
|
||||
- **消息 API**:兼容 Anthropic Claude API 的消息接口
|
||||
- **配置 API**:读取和更新服务器配置
|
||||
- **日志 API**:查看和管理服务日志
|
||||
- **工具 API**:计算 Token 数量
|
||||
|
||||
## 基础信息
|
||||
|
||||
**Base URL**: `http://localhost:3456`
|
||||
|
||||
**认证方式**: API Key(通过 `x-api-key` 请求头)
|
||||
|
||||
```bash
|
||||
curl -H "x-api-key: your-api-key" http://localhost:3456/api/config
|
||||
```
|
||||
|
||||
## API 端点列表
|
||||
|
||||
### 消息相关
|
||||
|
||||
| 端点 | 方法 | 描述 |
|
||||
|------|------|------|
|
||||
| `/v1/messages` | POST | 发送消息(兼容 Anthropic API) |
|
||||
| `/v1/messages/count_tokens` | POST | 计算消息的 Token 数量 |
|
||||
|
||||
### 配置管理
|
||||
|
||||
| 端点 | 方法 | 描述 |
|
||||
|------|------|------|
|
||||
| `/api/config` | GET | 获取当前配置 |
|
||||
| `/api/config` | POST | 更新配置 |
|
||||
| `/api/transformers` | GET | 获取可用的转换器列表 |
|
||||
|
||||
### 日志管理
|
||||
|
||||
| 端点 | 方法 | 描述 |
|
||||
|------|------|------|
|
||||
| `/api/logs/files` | GET | 获取日志文件列表 |
|
||||
| `/api/logs` | GET | 获取日志内容 |
|
||||
| `/api/logs` | DELETE | 清除日志 |
|
||||
|
||||
### 服务管理
|
||||
|
||||
| 端点 | 方法 | 描述 |
|
||||
|------|------|------|
|
||||
| `/api/restart` | POST | 重启服务 |
|
||||
| `/ui` | GET | Web 管理界面 |
|
||||
| `/ui/` | GET | Web 管理界面(重定向) |
|
||||
|
||||
## 错误响应
|
||||
|
||||
所有 API 在发生错误时返回统一的错误格式:
|
||||
|
||||
```json
|
||||
{
|
||||
"error": {
|
||||
"type": "invalid_request_error",
|
||||
"message": "错误描述"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
常见 HTTP 状态码:
|
||||
|
||||
- `200` - 成功
|
||||
- `400` - 请求参数错误
|
||||
- `401` - 未授权(API Key 无效)
|
||||
- `404` - 资源不存在
|
||||
- `500` - 服务器内部错误
|
||||
|
||||
## 认证
|
||||
|
||||
### API Key 认证
|
||||
|
||||
在请求头中添加 API Key:
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:3456/v1/messages \
|
||||
-H "x-api-key: your-api-key" \
|
||||
-H "content-type: application/json" \
|
||||
-d '...'
|
||||
```
|
||||
|
||||
### 无认证模式
|
||||
|
||||
当没有配置 Providers 时,服务器会监听在 `0.0.0.0` 且无需认证:
|
||||
|
||||
```json5
|
||||
{
|
||||
"Providers": []
|
||||
}
|
||||
```
|
||||
|
||||
## 流式响应
|
||||
|
||||
消息 API 支持流式响应(Server-Sent Events):
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:3456/v1/messages \
|
||||
-H "x-api-key: your-api-key" \
|
||||
-H "content-type: application/json" \
|
||||
-d '{"stream": true, ...}'
|
||||
```
|
||||
|
||||
流式响应格式:
|
||||
|
||||
```
|
||||
event: message_start
|
||||
data: {"type":"message_start","message":{...}}
|
||||
|
||||
event: content_block_delta
|
||||
data: {"type":"content_block_delta","delta":{"type":"text_delta","text":"Hello"}}
|
||||
|
||||
event: message_stop
|
||||
data: {"type":"message_stop"}
|
||||
```
|
||||
|
||||
## 速率限制
|
||||
|
||||
服务器本身不实现速率限制,建议通过反向代理(如 Nginx)配置。
|
||||
|
||||
## 版本管理
|
||||
|
||||
当前 API 版本:`v1`
|
||||
|
||||
所有 `/v1/*` 端点保持向后兼容。
|
||||
146
docs/docs/server/config/basic.md
Normal file
146
docs/docs/server/config/basic.md
Normal file
@@ -0,0 +1,146 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
# Basic Configuration
|
||||
|
||||
Learn how to configure Claude Code Router to suit your needs.
|
||||
|
||||
## Configuration File Location
|
||||
|
||||
The configuration file is located at:
|
||||
|
||||
```
|
||||
~/.claude-code-router/config.json
|
||||
```
|
||||
|
||||
## Configuration Structure
|
||||
|
||||
### Providers
|
||||
|
||||
Configure LLM providers to route requests to:
|
||||
|
||||
```json
|
||||
{
|
||||
"Providers": [
|
||||
{
|
||||
"NAME": "deepseek",
|
||||
"HOST": "https://api.deepseek.com",
|
||||
"APIKEY": "your-api-key",
|
||||
"MODELS": ["deepseek-chat", "deepseek-coder"]
|
||||
},
|
||||
{
|
||||
"NAME": "groq",
|
||||
"HOST": "https://api.groq.com/openai/v1",
|
||||
"APIKEY": "your-groq-api-key",
|
||||
"MODELS": ["llama-3.3-70b-versatile"]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Router
|
||||
|
||||
Configure which model to use by default:
|
||||
|
||||
```json
|
||||
{
|
||||
"Router": {
|
||||
"default": "deepseek,deepseek-chat"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Format: `{provider-name},{model-name}`
|
||||
|
||||
### Transformers
|
||||
|
||||
Apply transformations to requests/responses:
|
||||
|
||||
```json
|
||||
{
|
||||
"transformers": [
|
||||
{
|
||||
"name": "anthropic",
|
||||
"providers": ["deepseek", "groq"]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
Use environment variables in your configuration:
|
||||
|
||||
```json
|
||||
{
|
||||
"Providers": [
|
||||
{
|
||||
"NAME": "deepseek",
|
||||
"HOST": "https://api.deepseek.com",
|
||||
"APIKEY": "$DEEPSEEK_API_KEY"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Both `$VAR_NAME` and `${VAR_NAME}` syntax are supported.
|
||||
|
||||
## Complete Example
|
||||
|
||||
```json
|
||||
{
|
||||
"port": 8080,
|
||||
"Providers": [
|
||||
{
|
||||
"NAME": "deepseek",
|
||||
"HOST": "https://api.deepseek.com",
|
||||
"APIKEY": "$DEEPSEEK_API_KEY",
|
||||
"MODELS": ["deepseek-chat", "deepseek-coder"],
|
||||
"transformers": ["anthropic"]
|
||||
},
|
||||
{
|
||||
"NAME": "groq",
|
||||
"HOST": "https://api.groq.com/openai/v1",
|
||||
"APIKEY": "$GROQ_API_KEY",
|
||||
"MODELS": ["llama-3.3-70b-versatile"],
|
||||
"transformers": ["anthropic"]
|
||||
}
|
||||
],
|
||||
"Router": {
|
||||
"default": "deepseek,deepseek-chat",
|
||||
"longContextThreshold": 100000,
|
||||
"background": "groq,llama-3.3-70b-versatile"
|
||||
},
|
||||
"transformers": [
|
||||
{
|
||||
"name": "anthropic",
|
||||
"providers": ["deepseek", "groq"]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Editing Configuration
|
||||
|
||||
Use the CLI to edit the configuration:
|
||||
|
||||
```bash
|
||||
ccr config edit
|
||||
```
|
||||
|
||||
This will open the configuration file in your default editor.
|
||||
|
||||
## Reloading Configuration
|
||||
|
||||
After editing the configuration, restart the router:
|
||||
|
||||
```bash
|
||||
ccr restart
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [Providers Configuration](/docs/config/providers) - Detailed provider configuration
|
||||
- [Routing Configuration](/docs/config/routing) - Configure routing rules
|
||||
- [Transformers](/docs/config/transformers) - Apply transformations
|
||||
86
docs/docs/server/config/providers.md
Normal file
86
docs/docs/server/config/providers.md
Normal file
@@ -0,0 +1,86 @@
|
||||
---
|
||||
sidebar_position: 2
|
||||
---
|
||||
|
||||
# Providers Configuration
|
||||
|
||||
Detailed guide for configuring LLM providers.
|
||||
|
||||
## Supported Providers
|
||||
|
||||
### DeepSeek
|
||||
|
||||
```json
|
||||
{
|
||||
"NAME": "deepseek",
|
||||
"HOST": "https://api.deepseek.com",
|
||||
"APIKEY": "your-api-key",
|
||||
"MODELS": ["deepseek-chat", "deepseek-coder"],
|
||||
"transformers": ["anthropic"]
|
||||
}
|
||||
```
|
||||
|
||||
### Groq
|
||||
|
||||
```json
|
||||
{
|
||||
"NAME": "groq",
|
||||
"HOST": "https://api.groq.com/openai/v1",
|
||||
"APIKEY": "your-api-key",
|
||||
"MODELS": ["llama-3.3-70b-versatile"],
|
||||
"transformers": ["anthropic"]
|
||||
}
|
||||
```
|
||||
|
||||
### Gemini
|
||||
|
||||
```json
|
||||
{
|
||||
"NAME": "gemini",
|
||||
"HOST": "https://generativelanguage.googleapis.com/v1beta",
|
||||
"APIKEY": "your-api-key",
|
||||
"MODELS": ["gemini-1.5-pro"],
|
||||
"transformers": ["anthropic"]
|
||||
}
|
||||
```
|
||||
|
||||
### OpenRouter
|
||||
|
||||
```json
|
||||
{
|
||||
"NAME": "openrouter",
|
||||
"HOST": "https://openrouter.ai/api/v1",
|
||||
"APIKEY": "your-api-key",
|
||||
"MODELS": ["anthropic/claude-3.5-sonnet"],
|
||||
"transformers": ["anthropic"]
|
||||
}
|
||||
```
|
||||
|
||||
## Provider Configuration Options
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
|-------|------|----------|-------------|
|
||||
| `NAME` | string | Yes | Unique provider identifier |
|
||||
| `HOST` | string | Yes | API base URL |
|
||||
| `APIKEY` | string | Yes | API authentication key |
|
||||
| `MODELS` | string[] | No | List of available models |
|
||||
| `transformers` | string[] | No | List of transformers to apply |
|
||||
|
||||
## Model Selection
|
||||
|
||||
When selecting a model in routing, use the format:
|
||||
|
||||
```
|
||||
{provider-name},{model-name}
|
||||
```
|
||||
|
||||
For example:
|
||||
|
||||
```
|
||||
deepseek,deepseek-chat
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [Routing Configuration](/docs/config/routing) - Configure how requests are routed
|
||||
- [Transformers](/docs/config/transformers) - Apply transformations to requests
|
||||
148
docs/docs/server/config/routing.md
Normal file
148
docs/docs/server/config/routing.md
Normal file
@@ -0,0 +1,148 @@
|
||||
---
|
||||
sidebar_position: 3
|
||||
---
|
||||
|
||||
# Routing Configuration
|
||||
|
||||
Configure how requests are routed to different models.
|
||||
|
||||
## Default Routing
|
||||
|
||||
Set the default model for all requests:
|
||||
|
||||
```json
|
||||
{
|
||||
"Router": {
|
||||
"default": "deepseek,deepseek-chat"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Built-in Scenarios
|
||||
|
||||
### Background Tasks
|
||||
|
||||
Route background tasks to a lightweight model:
|
||||
|
||||
```json
|
||||
{
|
||||
"Router": {
|
||||
"background": "groq,llama-3.3-70b-versatile"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Thinking Mode (Plan Mode)
|
||||
|
||||
Route thinking-intensive tasks to a more capable model:
|
||||
|
||||
```json
|
||||
{
|
||||
"Router": {
|
||||
"think": "deepseek,deepseek-chat"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Long Context
|
||||
|
||||
Route requests with long context:
|
||||
|
||||
```json
|
||||
{
|
||||
"Router": {
|
||||
"longContextThreshold": 100000,
|
||||
"longContext": "gemini,gemini-1.5-pro"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Web Search
|
||||
|
||||
Route web search tasks:
|
||||
|
||||
```json
|
||||
{
|
||||
"Router": {
|
||||
"webSearch": "deepseek,deepseek-chat"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Image Tasks
|
||||
|
||||
Route image-related tasks:
|
||||
|
||||
```json
|
||||
{
|
||||
"Router": {
|
||||
"image": "gemini,gemini-1.5-pro"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Project-Level Routing
|
||||
|
||||
Configure routing per project in `~/.claude/projects/<project-id>/claude-code-router.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"Router": {
|
||||
"default": "groq,llama-3.3-70b-versatile"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Project-level configuration takes precedence over global configuration.
|
||||
|
||||
## Custom Router
|
||||
|
||||
Create a custom JavaScript router function:
|
||||
|
||||
1. Create a router file (e.g., `custom-router.js`):
|
||||
|
||||
```javascript
|
||||
module.exports = function(config, context) {
|
||||
// Analyze the request context
|
||||
const { scenario, projectId, tokenCount } = context;
|
||||
|
||||
// Custom routing logic
|
||||
if (scenario === 'background') {
|
||||
return 'groq,llama-3.3-70b-versatile';
|
||||
}
|
||||
|
||||
if (tokenCount > 100000) {
|
||||
return 'gemini,gemini-1.5-pro';
|
||||
}
|
||||
|
||||
// Default
|
||||
return 'deepseek,deepseek-chat';
|
||||
};
|
||||
```
|
||||
|
||||
2. Set the `CUSTOM_ROUTER_PATH` environment variable:
|
||||
|
||||
```bash
|
||||
export CUSTOM_ROUTER_PATH="/path/to/custom-router.js"
|
||||
```
|
||||
|
||||
## Token Counting
|
||||
|
||||
The router uses `tiktoken` (cl100k_base) to estimate request token count. This is used for:
|
||||
|
||||
- Determining if a request exceeds `longContextThreshold`
|
||||
- Custom routing logic based on token count
|
||||
|
||||
## Subagent Routing
|
||||
|
||||
Specify models for subagents using special tags:
|
||||
|
||||
```
|
||||
<CCR-SUBAGENT-MODEL>provider,model</CCR-SUBAGENT-MODEL>
|
||||
Please help me analyze this code...
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [Transformers](/docs/config/transformers) - Apply transformations to requests
|
||||
- [Custom Router](/docs/advanced/custom-router) - Advanced custom routing
|
||||
176
docs/docs/server/config/transformers.md
Normal file
176
docs/docs/server/config/transformers.md
Normal file
@@ -0,0 +1,176 @@
|
||||
---
|
||||
sidebar_position: 4
|
||||
---
|
||||
|
||||
# Transformers
|
||||
|
||||
Transformers adapt API differences between providers.
|
||||
|
||||
## Built-in Transformers
|
||||
|
||||
### anthropic
|
||||
|
||||
Transforms requests to be compatible with Anthropic-style APIs:
|
||||
|
||||
```json
|
||||
{
|
||||
"transformers": [
|
||||
{
|
||||
"name": "anthropic",
|
||||
"providers": ["deepseek", "groq"]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### deepseek
|
||||
|
||||
Specialized transformer for DeepSeek API:
|
||||
|
||||
```json
|
||||
{
|
||||
"transformers": [
|
||||
{
|
||||
"name": "deepseek",
|
||||
"providers": ["deepseek"]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### gemini
|
||||
|
||||
Transformer for Google Gemini API:
|
||||
|
||||
```json
|
||||
{
|
||||
"transformers": [
|
||||
{
|
||||
"name": "gemini",
|
||||
"providers": ["gemini"]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### groq
|
||||
|
||||
Transformer for Groq API:
|
||||
|
||||
```json
|
||||
{
|
||||
"transformers": [
|
||||
{
|
||||
"name": "groq",
|
||||
"providers": ["groq"]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### openrouter
|
||||
|
||||
Transformer for OpenRouter API:
|
||||
|
||||
```json
|
||||
{
|
||||
"transformers": [
|
||||
{
|
||||
"name": "openrouter",
|
||||
"providers": ["openrouter"]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Applying Transformers
|
||||
|
||||
### Global Application
|
||||
|
||||
Apply to all requests for a provider:
|
||||
|
||||
```json
|
||||
{
|
||||
"Providers": [
|
||||
{
|
||||
"NAME": "deepseek",
|
||||
"HOST": "https://api.deepseek.com",
|
||||
"APIKEY": "your-api-key",
|
||||
"transformers": ["anthropic"]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Model-Specific Application
|
||||
|
||||
Apply to specific models:
|
||||
|
||||
```json
|
||||
{
|
||||
"transformers": [
|
||||
{
|
||||
"name": "maxtoken",
|
||||
"options": {
|
||||
"max_tokens": 8192
|
||||
},
|
||||
"models": ["deepseek,deepseek-chat"]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Passing Options
|
||||
|
||||
Some transformers accept options:
|
||||
|
||||
```json
|
||||
{
|
||||
"transformers": [
|
||||
{
|
||||
"name": "maxtoken",
|
||||
"options": {
|
||||
"max_tokens": 8192
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Custom Transformers
|
||||
|
||||
Create custom transformer plugins:
|
||||
|
||||
1. Create a transformer file:
|
||||
|
||||
```javascript
|
||||
module.exports = {
|
||||
name: 'my-transformer',
|
||||
transformRequest: async (req, config) => {
|
||||
// Modify request
|
||||
return req;
|
||||
},
|
||||
transformResponse: async (res, config) => {
|
||||
// Modify response
|
||||
return res;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
2. Load in configuration:
|
||||
|
||||
```json
|
||||
{
|
||||
"transformers": [
|
||||
{
|
||||
"name": "my-transformer",
|
||||
"path": "/path/to/transformer.js"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [Advanced Topics](/docs/advanced/custom-router) - Advanced routing customization
|
||||
- [Agents](/docs/advanced/agents) - Extending with agents
|
||||
182
docs/docs/server/deployment.md
Normal file
182
docs/docs/server/deployment.md
Normal file
@@ -0,0 +1,182 @@
|
||||
# Server 部署
|
||||
|
||||
Claude Code Router Server 支持多种部署方式,从本地开发到生产环境。
|
||||
|
||||
## Docker 部署(推荐)
|
||||
|
||||
### 使用 Docker Hub 镜像
|
||||
|
||||
```bash
|
||||
docker run -d \
|
||||
--name claude-code-router \
|
||||
-p 3456:3456 \
|
||||
-v ~/.claude-code-router:/app/.claude-code-router \
|
||||
musistudio/claude-code-router:latest
|
||||
```
|
||||
|
||||
### 使用 Docker Compose
|
||||
|
||||
创建 `docker-compose.yml`:
|
||||
|
||||
```yaml
|
||||
version: '3.8'
|
||||
services:
|
||||
claude-code-router:
|
||||
image: musistudio/claude-code-router:latest
|
||||
container_name: claude-code-router
|
||||
ports:
|
||||
- "3456:3456"
|
||||
volumes:
|
||||
- ./config:/app/.claude-code-router
|
||||
environment:
|
||||
- LOG_LEVEL=info
|
||||
- HOST=0.0.0.0
|
||||
- PORT=3456
|
||||
restart: unless-stopped
|
||||
```
|
||||
|
||||
启动服务:
|
||||
|
||||
```bash
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
### 自定义构建
|
||||
|
||||
从源码构建 Docker 镜像:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/musistudio/claude-code-router.git
|
||||
cd claude-code-router
|
||||
docker build -t claude-code-router:latest .
|
||||
```
|
||||
|
||||
## 配置文件挂载
|
||||
|
||||
将配置文件挂载到容器中:
|
||||
|
||||
```bash
|
||||
docker run -d \
|
||||
--name claude-code-router \
|
||||
-p 3456:3456 \
|
||||
-v $(pwd)/config.json:/app/.claude-code-router/config.json \
|
||||
musistudio/claude-code-router:latest
|
||||
```
|
||||
|
||||
配置文件示例:
|
||||
|
||||
```json5
|
||||
{
|
||||
// 服务器配置
|
||||
"HOST": "0.0.0.0",
|
||||
"PORT": 3456,
|
||||
"APIKEY": "your-api-key-here",
|
||||
|
||||
// 日志配置
|
||||
"LOG": true,
|
||||
"LOG_LEVEL": "info",
|
||||
|
||||
// LLM 提供商配置
|
||||
"Providers": [
|
||||
{
|
||||
"name": "openai",
|
||||
"baseUrl": "https://api.openai.com/v1",
|
||||
"apiKey": "$OPENAI_API_KEY",
|
||||
"models": ["gpt-4", "gpt-3.5-turbo"]
|
||||
}
|
||||
],
|
||||
|
||||
// 路由配置
|
||||
"Router": {
|
||||
"default": "openai,gpt-4"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 环境变量
|
||||
|
||||
支持通过环境变量覆盖配置:
|
||||
|
||||
| 变量名 | 说明 | 默认值 |
|
||||
|--------|------|--------|
|
||||
| `HOST` | 监听地址 | `127.0.0.1` |
|
||||
| `PORT` | 监听端口 | `3456` |
|
||||
| `APIKEY` | API 密钥 | - |
|
||||
| `LOG_LEVEL` | 日志级别 | `debug` |
|
||||
| `LOG` | 是否启用日志 | `true` |
|
||||
|
||||
## 生产环境建议
|
||||
|
||||
### 1. 使用反向代理
|
||||
|
||||
使用 Nginx 作为反向代理:
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name your-domain.com;
|
||||
|
||||
location / {
|
||||
proxy_pass http://localhost:3456;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection 'upgrade';
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_cache_bypass $http_upgrade;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 配置 HTTPS
|
||||
|
||||
使用 Let's Encrypt 获取免费证书:
|
||||
|
||||
```bash
|
||||
sudo certbot --nginx -d your-domain.com
|
||||
```
|
||||
|
||||
### 3. 日志管理
|
||||
|
||||
配置日志轮转和持久化:
|
||||
|
||||
```yaml
|
||||
version: '3.8'
|
||||
services:
|
||||
claude-code-router:
|
||||
image: musistudio/claude-code-router:latest
|
||||
volumes:
|
||||
- ./logs:/app/.claude-code-router/logs
|
||||
environment:
|
||||
- LOG_LEVEL=warn
|
||||
```
|
||||
|
||||
### 4. 健康检查
|
||||
|
||||
配置 Docker 健康检查:
|
||||
|
||||
```yaml
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:3456/api/config"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
```
|
||||
|
||||
## 访问 Web UI
|
||||
|
||||
部署完成后,访问 Web UI:
|
||||
|
||||
```
|
||||
http://localhost:3456/ui/
|
||||
```
|
||||
|
||||
通过 Web UI 可以:
|
||||
- 查看和管理配置
|
||||
- 监控日志
|
||||
- 查看服务状态
|
||||
|
||||
## 二次开发
|
||||
|
||||
如果需要基于 CCR Server 进行二次开发,请查看 [API 参考](/docs/category/api)。
|
||||
77
docs/docs/server/intro.md
Normal file
77
docs/docs/server/intro.md
Normal file
@@ -0,0 +1,77 @@
|
||||
# Server 简介
|
||||
|
||||
Claude Code Router Server 是一个核心服务组件,负责将 Claude Code 的 API 请求路由到不同的 LLM 提供商。它提供了完整的 HTTP API,支持:
|
||||
|
||||
- **API 请求路由**:将 Anthropic 格式的请求转换为各种提供商的 API 格式
|
||||
- **认证与授权**:支持 API Key 认证
|
||||
- **配置管理**:动态配置提供商、路由规则和转换器
|
||||
- **Web UI**:内置管理界面
|
||||
- **日志系统**:完整的请求日志记录
|
||||
|
||||
## 架构概述
|
||||
|
||||
```
|
||||
┌─────────────┐ ┌──────────────────┐ ┌──────────────┐
|
||||
│ Claude Code │────▶│ CCR Server │────▶│ LLM Provider │
|
||||
│ Client │ │ (Router + │ │ (OpenAI/ │
|
||||
└─────────────┘ │ Transformer) │ │ Gemini/etc)│
|
||||
└──────────────────┘ └──────────────┘
|
||||
│
|
||||
├─ Web UI
|
||||
├─ Config API
|
||||
└─ Logs API
|
||||
```
|
||||
|
||||
## 核心功能
|
||||
|
||||
### 1. 请求路由
|
||||
- 基于 Token 数量的智能路由
|
||||
- 项目级路由配置
|
||||
- 自定义路由函数
|
||||
- 场景化路由(background、think、longContext 等)
|
||||
|
||||
### 2. 请求转换
|
||||
- 支持多种 LLM 提供商的 API 格式转换
|
||||
- 内置转换器:Anthropic、DeepSeek、Gemini、OpenRouter、Groq 等
|
||||
- 可扩展的转换器系统
|
||||
|
||||
### 3. Agent 系统
|
||||
- 插件式的 Agent 架构
|
||||
- 内置图片处理 Agent
|
||||
- 自定义 Agent 支持
|
||||
|
||||
### 4. 配置管理
|
||||
- JSON5 格式配置文件
|
||||
- 环境变量插值
|
||||
- 配置热更新(需重启服务)
|
||||
|
||||
## 使用场景
|
||||
|
||||
### 场景一:个人本地服务
|
||||
在本地运行服务,供个人 Claude Code 使用:
|
||||
|
||||
```bash
|
||||
ccr start
|
||||
```
|
||||
|
||||
### 场景二:团队共享服务
|
||||
使用 Docker 部署,为团队成员提供共享服务:
|
||||
|
||||
```bash
|
||||
docker run -d -p 3456:3456 musistudio/claude-code-router
|
||||
```
|
||||
|
||||
### 场景三:二次开发
|
||||
基于暴露的 API 构建自定义应用:
|
||||
|
||||
```bash
|
||||
GET /api/config
|
||||
POST /v1/messages
|
||||
GET /api/logs
|
||||
```
|
||||
|
||||
## 下一步
|
||||
|
||||
- [Docker 部署指南](/docs/server/deployment) - 学习如何部署服务
|
||||
- [API 参考](/docs/category/api) - 查看完整的 API 文档
|
||||
- [配置说明](/docs/category/server-config) - 了解服务器配置选项
|
||||
123
docs/docusaurus.config.ts
Normal file
123
docs/docusaurus.config.ts
Normal file
@@ -0,0 +1,123 @@
|
||||
import type { Config } from '@docusaurus/types';
|
||||
import type * as Preset from '@docusaurus/preset-classic';
|
||||
import { themes as prismThemes } from 'prism-react-renderer';
|
||||
|
||||
const config: Config = {
|
||||
title: 'Claude Code Router',
|
||||
tagline: 'Use Claude Code without an Anthropics account and route it to another LLM provider',
|
||||
favicon: 'img/favicon.ico',
|
||||
|
||||
url: 'https://claude-code-router.js.org',
|
||||
baseUrl: '/',
|
||||
|
||||
organizationName: 'musistudio',
|
||||
projectName: 'claude-code-router',
|
||||
|
||||
onBrokenLinks: 'warn',
|
||||
onBrokenMarkdownLinks: 'warn',
|
||||
onBrokenAnchors: 'warn',
|
||||
|
||||
i18n: {
|
||||
defaultLocale: 'en',
|
||||
locales: ['en', 'zh-CN'],
|
||||
},
|
||||
|
||||
presets: [
|
||||
[
|
||||
'classic',
|
||||
{
|
||||
docs: {
|
||||
sidebarPath: './sidebars.ts',
|
||||
editUrl:
|
||||
'https://github.com/musistudio/claude-code-router/tree/main/docs',
|
||||
},
|
||||
blog: {
|
||||
showReadingTime: true,
|
||||
editUrl:
|
||||
'https://github.com/musistudio/claude-code-router/tree/main/docs',
|
||||
},
|
||||
theme: {
|
||||
customCss: './src/css/custom.css',
|
||||
},
|
||||
} satisfies Preset.Options,
|
||||
],
|
||||
],
|
||||
|
||||
themeConfig: {
|
||||
// Disable dark mode
|
||||
colorMode: {
|
||||
defaultMode: 'light',
|
||||
disableSwitch: true,
|
||||
respectPrefersColorScheme: false,
|
||||
},
|
||||
|
||||
image: 'img/docusaurus-social-card.jpg',
|
||||
navbar: {
|
||||
title: 'Claude Code Router',
|
||||
logo: {
|
||||
alt: 'Claude Code Router Logo',
|
||||
src: 'img/ccr.svg',
|
||||
width: 32,
|
||||
height: 32,
|
||||
},
|
||||
items: [
|
||||
{
|
||||
type: 'docSidebar',
|
||||
sidebarId: 'tutorialSidebar',
|
||||
position: 'left',
|
||||
label: 'Documentation',
|
||||
},
|
||||
{ to: '/blog', label: 'Blog', position: 'left' },
|
||||
{
|
||||
type: 'localeDropdown',
|
||||
position: 'right',
|
||||
},
|
||||
{
|
||||
href: 'https://github.com/musistudio/claude-code-router',
|
||||
label: 'GitHub',
|
||||
position: 'right',
|
||||
},
|
||||
],
|
||||
},
|
||||
footer: {
|
||||
style: 'light',
|
||||
links: [
|
||||
{
|
||||
title: 'Docs',
|
||||
items: [
|
||||
{
|
||||
label: 'Tutorial',
|
||||
to: '/docs/intro',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Community',
|
||||
items: [
|
||||
{
|
||||
label: 'GitHub',
|
||||
href: 'https://github.com/musistudio/claude-code-router',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'More',
|
||||
items: [
|
||||
{
|
||||
label: 'Blog',
|
||||
to: '/blog',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
copyright: `Copyright © ${new Date().getFullYear()} Claude Code Router. Built with Docusaurus.`,
|
||||
},
|
||||
prism: {
|
||||
theme: prismThemes.github,
|
||||
darkTheme: prismThemes.dracula,
|
||||
additionalLanguages: ['bash', 'typescript', 'javascript', 'json'],
|
||||
},
|
||||
} satisfies Preset.ThemeConfig,
|
||||
};
|
||||
|
||||
export default config;
|
||||
329
docs/i18n/zh-CN/code.json
Normal file
329
docs/i18n/zh-CN/code.json
Normal file
@@ -0,0 +1,329 @@
|
||||
{
|
||||
"theme.ErrorPageContent.title": {
|
||||
"message": "页面已崩溃。",
|
||||
"description": "The title of the fallback page when the page crashed"
|
||||
},
|
||||
"theme.BackToTopButton.buttonAriaLabel": {
|
||||
"message": "回到顶部",
|
||||
"description": "The ARIA label for the back to top button"
|
||||
},
|
||||
"theme.blog.archive.title": {
|
||||
"message": "历史博文",
|
||||
"description": "The page & hero title of the blog archive page"
|
||||
},
|
||||
"theme.blog.archive.description": {
|
||||
"message": "历史博文",
|
||||
"description": "The page & hero description of the blog archive page"
|
||||
},
|
||||
"theme.blog.paginator.navAriaLabel": {
|
||||
"message": "博文列表分页导航",
|
||||
"description": "The ARIA label for the blog pagination"
|
||||
},
|
||||
"theme.blog.paginator.newerEntries": {
|
||||
"message": "较新的博文",
|
||||
"description": "The label used to navigate to the newer blog posts page (previous page)"
|
||||
},
|
||||
"theme.blog.paginator.olderEntries": {
|
||||
"message": "较旧的博文",
|
||||
"description": "The label used to navigate to the older blog posts page (next page)"
|
||||
},
|
||||
"theme.blog.post.paginator.navAriaLabel": {
|
||||
"message": "博文分页导航",
|
||||
"description": "The ARIA label for the blog posts pagination"
|
||||
},
|
||||
"theme.blog.post.paginator.newerPost": {
|
||||
"message": "较新一篇",
|
||||
"description": "The blog post button label to navigate to the newer/previous post"
|
||||
},
|
||||
"theme.blog.post.paginator.olderPost": {
|
||||
"message": "较旧一篇",
|
||||
"description": "The blog post button label to navigate to the older/next post"
|
||||
},
|
||||
"theme.tags.tagsPageLink": {
|
||||
"message": "查看所有标签",
|
||||
"description": "The label of the link targeting the tag list page"
|
||||
},
|
||||
"theme.colorToggle.ariaLabel.mode.system": {
|
||||
"message": "system mode",
|
||||
"description": "The name for the system color mode"
|
||||
},
|
||||
"theme.colorToggle.ariaLabel.mode.light": {
|
||||
"message": "浅色模式",
|
||||
"description": "The name for the light color mode"
|
||||
},
|
||||
"theme.colorToggle.ariaLabel.mode.dark": {
|
||||
"message": "暗黑模式",
|
||||
"description": "The name for the dark color mode"
|
||||
},
|
||||
"theme.colorToggle.ariaLabel": {
|
||||
"message": "切换浅色/暗黑模式(当前为{mode})",
|
||||
"description": "The ARIA label for the color mode toggle"
|
||||
},
|
||||
"theme.docs.breadcrumbs.navAriaLabel": {
|
||||
"message": "页面路径",
|
||||
"description": "The ARIA label for the breadcrumbs"
|
||||
},
|
||||
"theme.docs.DocCard.categoryDescription.plurals": {
|
||||
"message": "{count} 个项目",
|
||||
"description": "The default description for a category card in the generated index about how many items this category includes"
|
||||
},
|
||||
"theme.docs.paginator.navAriaLabel": {
|
||||
"message": "文件选项卡",
|
||||
"description": "The ARIA label for the docs pagination"
|
||||
},
|
||||
"theme.docs.paginator.previous": {
|
||||
"message": "上一页",
|
||||
"description": "The label used to navigate to the previous doc"
|
||||
},
|
||||
"theme.docs.paginator.next": {
|
||||
"message": "下一页",
|
||||
"description": "The label used to navigate to the next doc"
|
||||
},
|
||||
"theme.docs.tagDocListPageTitle.nDocsTagged": {
|
||||
"message": "{count} 篇文档带有标签",
|
||||
"description": "Pluralized label for \"{count} docs tagged\". Use as much plural forms (separated by \"|\") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)"
|
||||
},
|
||||
"theme.docs.tagDocListPageTitle": {
|
||||
"message": "{nDocsTagged}「{tagName}」",
|
||||
"description": "The title of the page for a docs tag"
|
||||
},
|
||||
"theme.docs.versionBadge.label": {
|
||||
"message": "版本:{versionLabel}"
|
||||
},
|
||||
"theme.docs.versions.unreleasedVersionLabel": {
|
||||
"message": "此为 {siteTitle} {versionLabel} 版尚未发行的文档。",
|
||||
"description": "The label used to tell the user that he's browsing an unreleased doc version"
|
||||
},
|
||||
"theme.docs.versions.unmaintainedVersionLabel": {
|
||||
"message": "此为 {siteTitle} {versionLabel} 版的文档,现已不再积极维护。",
|
||||
"description": "The label used to tell the user that he's browsing an unmaintained doc version"
|
||||
},
|
||||
"theme.docs.versions.latestVersionSuggestionLabel": {
|
||||
"message": "最新的文档请参阅 {latestVersionLink} ({versionLabel})。",
|
||||
"description": "The label used to tell the user to check the latest version"
|
||||
},
|
||||
"theme.docs.versions.latestVersionLinkLabel": {
|
||||
"message": "最新版本",
|
||||
"description": "The label used for the latest version suggestion link label"
|
||||
},
|
||||
"theme.common.headingLinkTitle": {
|
||||
"message": "{heading}的直接链接",
|
||||
"description": "Title for link to heading"
|
||||
},
|
||||
"theme.common.editThisPage": {
|
||||
"message": "编辑此页",
|
||||
"description": "The link label to edit the current page"
|
||||
},
|
||||
"theme.lastUpdated.atDate": {
|
||||
"message": "于 {date} ",
|
||||
"description": "The words used to describe on which date a page has been last updated"
|
||||
},
|
||||
"theme.lastUpdated.byUser": {
|
||||
"message": "由 {user} ",
|
||||
"description": "The words used to describe by who the page has been last updated"
|
||||
},
|
||||
"theme.lastUpdated.lastUpdatedAtBy": {
|
||||
"message": "最后{byUser}{atDate}更新",
|
||||
"description": "The sentence used to display when a page has been last updated, and by who"
|
||||
},
|
||||
"theme.NotFound.title": {
|
||||
"message": "找不到页面",
|
||||
"description": "The title of the 404 page"
|
||||
},
|
||||
"theme.navbar.mobileVersionsDropdown.label": {
|
||||
"message": "选择版本",
|
||||
"description": "The label for the navbar versions dropdown on mobile view"
|
||||
},
|
||||
"theme.tags.tagsListLabel": {
|
||||
"message": "标签:",
|
||||
"description": "The label alongside a tag list"
|
||||
},
|
||||
"theme.AnnouncementBar.closeButtonAriaLabel": {
|
||||
"message": "关闭",
|
||||
"description": "The ARIA label for close button of announcement bar"
|
||||
},
|
||||
"theme.admonition.caution": {
|
||||
"message": "警告",
|
||||
"description": "The default label used for the Caution admonition (:::caution)"
|
||||
},
|
||||
"theme.admonition.danger": {
|
||||
"message": "危险",
|
||||
"description": "The default label used for the Danger admonition (:::danger)"
|
||||
},
|
||||
"theme.admonition.info": {
|
||||
"message": "信息",
|
||||
"description": "The default label used for the Info admonition (:::info)"
|
||||
},
|
||||
"theme.admonition.note": {
|
||||
"message": "备注",
|
||||
"description": "The default label used for the Note admonition (:::note)"
|
||||
},
|
||||
"theme.admonition.tip": {
|
||||
"message": "提示",
|
||||
"description": "The default label used for the Tip admonition (:::tip)"
|
||||
},
|
||||
"theme.admonition.warning": {
|
||||
"message": "注意",
|
||||
"description": "The default label used for the Warning admonition (:::warning)"
|
||||
},
|
||||
"theme.blog.sidebar.navAriaLabel": {
|
||||
"message": "最近博文导航",
|
||||
"description": "The ARIA label for recent posts in the blog sidebar"
|
||||
},
|
||||
"theme.DocSidebarItem.expandCategoryAriaLabel": {
|
||||
"message": "展开侧边栏分类 '{label}'",
|
||||
"description": "The ARIA label to expand the sidebar category"
|
||||
},
|
||||
"theme.DocSidebarItem.collapseCategoryAriaLabel": {
|
||||
"message": "折叠侧边栏分类 '{label}'",
|
||||
"description": "The ARIA label to collapse the sidebar category"
|
||||
},
|
||||
"theme.IconExternalLink.ariaLabel": {
|
||||
"message": "(opens in new tab)",
|
||||
"description": "The ARIA label for the external link icon"
|
||||
},
|
||||
"theme.NavBar.navAriaLabel": {
|
||||
"message": "主导航",
|
||||
"description": "The ARIA label for the main navigation"
|
||||
},
|
||||
"theme.NotFound.p1": {
|
||||
"message": "我们找不到您要找的页面。",
|
||||
"description": "The first paragraph of the 404 page"
|
||||
},
|
||||
"theme.NotFound.p2": {
|
||||
"message": "请联系原始链接来源网站的所有者,并告知他们链接已损坏。",
|
||||
"description": "The 2nd paragraph of the 404 page"
|
||||
},
|
||||
"theme.navbar.mobileLanguageDropdown.label": {
|
||||
"message": "选择语言",
|
||||
"description": "The label for the mobile language switcher dropdown"
|
||||
},
|
||||
"theme.TOCCollapsible.toggleButtonLabel": {
|
||||
"message": "本页总览",
|
||||
"description": "The label used by the button on the collapsible TOC component"
|
||||
},
|
||||
"theme.blog.post.readMore": {
|
||||
"message": "阅读更多",
|
||||
"description": "The label used in blog post item excerpts to link to full blog posts"
|
||||
},
|
||||
"theme.blog.post.readMoreLabel": {
|
||||
"message": "阅读 {title} 的全文",
|
||||
"description": "The ARIA label for the link to full blog posts from excerpts"
|
||||
},
|
||||
"theme.CodeBlock.copy": {
|
||||
"message": "复制",
|
||||
"description": "The copy button label on code blocks"
|
||||
},
|
||||
"theme.CodeBlock.copied": {
|
||||
"message": "复制成功",
|
||||
"description": "The copied button label on code blocks"
|
||||
},
|
||||
"theme.CodeBlock.copyButtonAriaLabel": {
|
||||
"message": "复制代码到剪贴板",
|
||||
"description": "The ARIA label for copy code blocks button"
|
||||
},
|
||||
"theme.CodeBlock.wordWrapToggle": {
|
||||
"message": "切换自动换行",
|
||||
"description": "The title attribute for toggle word wrapping button of code block lines"
|
||||
},
|
||||
"theme.blog.post.readingTime.plurals": {
|
||||
"message": "阅读需 {readingTime} 分钟",
|
||||
"description": "Pluralized label for \"{readingTime} min read\". Use as much plural forms (separated by \"|\") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)"
|
||||
},
|
||||
"theme.docs.breadcrumbs.home": {
|
||||
"message": "主页面",
|
||||
"description": "The ARIA label for the home page in the breadcrumbs"
|
||||
},
|
||||
"theme.docs.sidebar.navAriaLabel": {
|
||||
"message": "文档侧边栏",
|
||||
"description": "The ARIA label for the sidebar navigation"
|
||||
},
|
||||
"theme.docs.sidebar.collapseButtonTitle": {
|
||||
"message": "收起侧边栏",
|
||||
"description": "The title attribute for collapse button of doc sidebar"
|
||||
},
|
||||
"theme.docs.sidebar.collapseButtonAriaLabel": {
|
||||
"message": "收起侧边栏",
|
||||
"description": "The title attribute for collapse button of doc sidebar"
|
||||
},
|
||||
"theme.docs.sidebar.closeSidebarButtonAriaLabel": {
|
||||
"message": "关闭导航栏",
|
||||
"description": "The ARIA label for close button of mobile sidebar"
|
||||
},
|
||||
"theme.navbar.mobileDropdown.collapseButton.expandAriaLabel": {
|
||||
"message": "Expand the dropdown",
|
||||
"description": "The ARIA label of the button to expand the mobile dropdown navbar item"
|
||||
},
|
||||
"theme.navbar.mobileDropdown.collapseButton.collapseAriaLabel": {
|
||||
"message": "Collapse the dropdown",
|
||||
"description": "The ARIA label of the button to collapse the mobile dropdown navbar item"
|
||||
},
|
||||
"theme.docs.sidebar.toggleSidebarButtonAriaLabel": {
|
||||
"message": "切换导航栏",
|
||||
"description": "The ARIA label for hamburger menu button of mobile navigation"
|
||||
},
|
||||
"theme.docs.sidebar.expandButtonTitle": {
|
||||
"message": "展开侧边栏",
|
||||
"description": "The ARIA label and title attribute for expand button of doc sidebar"
|
||||
},
|
||||
"theme.docs.sidebar.expandButtonAriaLabel": {
|
||||
"message": "展开侧边栏",
|
||||
"description": "The ARIA label and title attribute for expand button of doc sidebar"
|
||||
},
|
||||
"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": {
|
||||
"message": "← 回到主菜单",
|
||||
"description": "The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)"
|
||||
},
|
||||
"theme.blog.post.plurals": {
|
||||
"message": "{count} 篇博文",
|
||||
"description": "Pluralized label for \"{count} posts\". Use as much plural forms (separated by \"|\") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)"
|
||||
},
|
||||
"theme.blog.tagTitle": {
|
||||
"message": "{nPosts} 含有标签「{tagName}」",
|
||||
"description": "The title of the page for a blog tag"
|
||||
},
|
||||
"theme.blog.author.pageTitle": {
|
||||
"message": "{authorName} - {nPosts}",
|
||||
"description": "The title of the page for a blog author"
|
||||
},
|
||||
"theme.blog.authorsList.pageTitle": {
|
||||
"message": "作者",
|
||||
"description": "The title of the authors page"
|
||||
},
|
||||
"theme.blog.authorsList.viewAll": {
|
||||
"message": "查看所有作者",
|
||||
"description": "The label of the link targeting the blog authors page"
|
||||
},
|
||||
"theme.blog.author.noPosts": {
|
||||
"message": "该作者尚未撰写任何文章。",
|
||||
"description": "The text for authors with 0 blog post"
|
||||
},
|
||||
"theme.contentVisibility.unlistedBanner.title": {
|
||||
"message": "未列出页",
|
||||
"description": "The unlisted content banner title"
|
||||
},
|
||||
"theme.contentVisibility.unlistedBanner.message": {
|
||||
"message": "此页面未列出。搜索引擎不会对其索引,只有拥有直接链接的用户才能访问。",
|
||||
"description": "The unlisted content banner message"
|
||||
},
|
||||
"theme.contentVisibility.draftBanner.title": {
|
||||
"message": "草稿页",
|
||||
"description": "The draft content banner title"
|
||||
},
|
||||
"theme.contentVisibility.draftBanner.message": {
|
||||
"message": "此页面是草稿,仅在开发环境中可见,不会包含在正式版本中。",
|
||||
"description": "The draft content banner message"
|
||||
},
|
||||
"theme.ErrorPageContent.tryAgain": {
|
||||
"message": "重试",
|
||||
"description": "The label of the button to try again rendering when the React error boundary captures an error"
|
||||
},
|
||||
"theme.common.skipToMainContent": {
|
||||
"message": "跳到主要内容",
|
||||
"description": "The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation"
|
||||
},
|
||||
"theme.tags.tagsPageTitle": {
|
||||
"message": "标签",
|
||||
"description": "The title of the tag list page"
|
||||
}
|
||||
}
|
||||
14
docs/i18n/zh-CN/docusaurus-plugin-content-blog/options.json
Normal file
14
docs/i18n/zh-CN/docusaurus-plugin-content-blog/options.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"title": {
|
||||
"message": "Blog",
|
||||
"description": "The title for the blog used in SEO"
|
||||
},
|
||||
"description": {
|
||||
"message": "Blog",
|
||||
"description": "The description for the blog used in SEO"
|
||||
},
|
||||
"sidebar.title": {
|
||||
"message": "Recent posts",
|
||||
"description": "The label for the left sidebar"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
---
|
||||
id: advanced/agents
|
||||
title: Agent 系统
|
||||
sidebar_position: 2
|
||||
---
|
||||
|
||||
# Agent 系统
|
||||
|
||||
使用 Agent 系统扩展功能。
|
||||
|
||||
## 什么是 Agent?
|
||||
|
||||
Agent 是可插拔的功能模块,可以:
|
||||
- 检测是否应处理请求
|
||||
- 修改请求
|
||||
- 提供自定义工具
|
||||
|
||||
## 内置 Agent
|
||||
|
||||
### Image Agent
|
||||
|
||||
通过检测请求中的图像 URL 或文件路径来处理图像相关任务。
|
||||
|
||||
当检测到图像相关内容时,Image Agent 会:
|
||||
1. 标记请求需要图像处理
|
||||
2. 添加图像分析工具到请求中
|
||||
3. 拦截工具调用事件
|
||||
4. 执行图像分析并返回结果
|
||||
|
||||
## Agent 配置
|
||||
|
||||
Agent 在服务器配置中配置并自动加载。
|
||||
|
||||
### 启用 Image Agent
|
||||
|
||||
Image Agent 内置于服务器中,无需额外配置。当请求包含图像内容时自动激活。
|
||||
|
||||
### 强制使用 Image Agent
|
||||
|
||||
如果您的模型不支持工具调用,可以在配置中设置 `config.forceUseImageAgent` 为 `true`:
|
||||
|
||||
```json
|
||||
{
|
||||
"Router": {
|
||||
"image": "gemini,gemini-2.5-pro"
|
||||
},
|
||||
"forceUseImageAgent": true
|
||||
}
|
||||
```
|
||||
|
||||
## Agent 工具调用流程
|
||||
|
||||
1. **检测阶段**:在 `preHandler` 钩子中检测并标记 agents
|
||||
2. **准备阶段**:将 agent 工具添加到请求中
|
||||
3. **拦截阶段**:在 `onSend` 钩子中拦截工具调用事件
|
||||
4. **执行阶段**:执行 agent 工具并发起新的 LLM 请求
|
||||
5. **返回阶段**:将结果流式返回
|
||||
|
||||
## Agent 类型定义
|
||||
|
||||
```typescript
|
||||
interface IAgent {
|
||||
name: string;
|
||||
shouldHandle: (req: any, config: any) => boolean;
|
||||
reqHandler: (req: any, config: any) => void;
|
||||
tools: Map<string, ITool>;
|
||||
}
|
||||
|
||||
interface ITool {
|
||||
name: string;
|
||||
description: string;
|
||||
input_schema: object;
|
||||
handler: (args: any, context: any) => Promise<any>;
|
||||
}
|
||||
```
|
||||
|
||||
## 创建自定义 Agent
|
||||
|
||||
自定义 Agent 支持正在开发中!
|
||||
|
||||
## 使用示例
|
||||
|
||||
### 图像分析请求
|
||||
|
||||
当您发送包含图像的请求时:
|
||||
|
||||
```
|
||||
请分析这张图片:/path/to/image.png
|
||||
```
|
||||
|
||||
Image Agent 将:
|
||||
1. 检测到图像路径
|
||||
2. 添加图像分析工具
|
||||
3. 调用配置的图像处理模型
|
||||
4. 返回分析结果
|
||||
|
||||
### 路由到支持图像的模型
|
||||
|
||||
在配置中指定用于图像任务的模型:
|
||||
|
||||
```json
|
||||
{
|
||||
"Router": {
|
||||
"image": "gemini,gemini-2.5-pro"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 下一步
|
||||
|
||||
- [预设](/zh/docs/advanced/presets) - 使用预定义配置
|
||||
- [自定义路由器](/zh/docs/advanced/custom-router) - 编写自定义路由逻辑
|
||||
@@ -0,0 +1,149 @@
|
||||
---
|
||||
id: advanced/custom-router
|
||||
title: 自定义路由器
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
# 自定义路由器
|
||||
|
||||
使用 JavaScript 编写自己的路由逻辑。
|
||||
|
||||
## 创建自定义路由器
|
||||
|
||||
创建一个导出路由函数的 JavaScript 文件:
|
||||
|
||||
```javascript
|
||||
// custom-router.js
|
||||
module.exports = async function(req, config) {
|
||||
// 获取用户消息
|
||||
const userMessage = req.body.messages.find(m => m.role === 'user')?.content;
|
||||
|
||||
// 自定义逻辑
|
||||
if (userMessage && userMessage.includes('解释代码')) {
|
||||
return 'openrouter,anthropic/claude-3.5-sonnet';
|
||||
}
|
||||
|
||||
// 返回 null 以使用默认路由
|
||||
return null;
|
||||
};
|
||||
```
|
||||
|
||||
## 参数说明
|
||||
|
||||
路由函数接收以下参数:
|
||||
|
||||
| 参数 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `req` | object | 来自 Claude Code 的请求对象,包含请求体 |
|
||||
| `config` | object | 应用程序的配置对象 |
|
||||
|
||||
## 配置
|
||||
|
||||
在 `config.json` 中设置 `CUSTOM_ROUTER_PATH` 以使用您的自定义路由器:
|
||||
|
||||
```json
|
||||
{
|
||||
"CUSTOM_ROUTER_PATH": "/path/to/custom-router.js"
|
||||
}
|
||||
```
|
||||
|
||||
## 返回格式
|
||||
|
||||
路由函数应返回以下格式的字符串:
|
||||
|
||||
```
|
||||
{provider-name},{model-name}
|
||||
```
|
||||
|
||||
示例:
|
||||
|
||||
```
|
||||
deepseek,deepseek-chat
|
||||
```
|
||||
|
||||
如果返回 `null`,则回退到默认路由配置。
|
||||
|
||||
## 错误处理
|
||||
|
||||
如果路由函数抛出错误或返回无效格式,路由器将回退到默认路由配置。
|
||||
|
||||
## 示例:基于时间的路由
|
||||
|
||||
```javascript
|
||||
module.exports = async function(req, config) {
|
||||
const hour = new Date().getHours();
|
||||
|
||||
// 工作时间使用更快的模型
|
||||
if (hour >= 9 && hour <= 18) {
|
||||
return 'groq,llama-3.3-70b-versatile';
|
||||
}
|
||||
|
||||
// 非工作时间使用更强大的模型
|
||||
return 'deepseek,deepseek-chat';
|
||||
};
|
||||
```
|
||||
|
||||
## 示例:成本优化
|
||||
|
||||
```javascript
|
||||
module.exports = async function(req, config) {
|
||||
const userMessage = req.body.messages.find(m => m.role === 'user')?.content;
|
||||
|
||||
// 简单任务使用较便宜的模型
|
||||
if (userMessage && userMessage.length < 100) {
|
||||
return 'groq,llama-3.3-70b-versatile';
|
||||
}
|
||||
|
||||
// 复杂任务使用默认模型
|
||||
return null;
|
||||
};
|
||||
```
|
||||
|
||||
## 示例:任务类型路由
|
||||
|
||||
```javascript
|
||||
module.exports = async function(req, config) {
|
||||
const userMessage = req.body.messages.find(m => m.role === 'user')?.content;
|
||||
|
||||
if (!userMessage) return null;
|
||||
|
||||
// 代码相关任务
|
||||
if (userMessage.includes('代码') || userMessage.includes('code')) {
|
||||
return 'deepseek,deepseek-coder';
|
||||
}
|
||||
|
||||
// 解释任务
|
||||
if (userMessage.includes('解释') || userMessage.includes('explain')) {
|
||||
return 'openrouter,anthropic/claude-3.5-sonnet';
|
||||
}
|
||||
|
||||
// 默认
|
||||
return null;
|
||||
};
|
||||
```
|
||||
|
||||
## 测试您的路由器
|
||||
|
||||
通过检查日志来测试您的自定义路由器:
|
||||
|
||||
```bash
|
||||
tail -f ~/.claude-code-router/claude-code-router.log
|
||||
```
|
||||
|
||||
查找路由决策以查看正在选择哪个模型。
|
||||
|
||||
## 子代理路由
|
||||
|
||||
对于子代理内的路由,您必须在子代理提示词的**开头**包含 `<CCR-SUBAGENT-MODEL>provider,model</CCR-SUBAGENT-MODEL>` 来指定特定的提供商和模型。
|
||||
|
||||
**示例:**
|
||||
|
||||
```
|
||||
<CCR-SUBAGENT-MODEL>openrouter,anthropic/claude-3.5-sonnet</CCR-SUBAGENT-MODEL>
|
||||
请帮我分析这段代码是否存在潜在的优化空间...
|
||||
```
|
||||
|
||||
## 下一步
|
||||
|
||||
- [Agent](/zh/docs/advanced/agents) - 使用 Agent 扩展功能
|
||||
- [预设](/zh/docs/advanced/presets) - 使用预定义配置
|
||||
@@ -0,0 +1,174 @@
|
||||
---
|
||||
id: advanced/presets
|
||||
title: 预设配置
|
||||
sidebar_position: 3
|
||||
---
|
||||
|
||||
# 预设配置
|
||||
|
||||
使用预定义配置进行快速设置。
|
||||
|
||||
## 什么是预设?
|
||||
|
||||
预设是预配置的设置,包括针对特定用例优化的提供商配置、路由规则和转换器。
|
||||
|
||||
## 可用预设
|
||||
|
||||
### Development(开发)
|
||||
|
||||
针对软件开发任务优化:
|
||||
- 快速响应时间
|
||||
- 适合代码生成
|
||||
- 成本效益高
|
||||
|
||||
配置特点:
|
||||
- 使用轻量级模型处理后台任务
|
||||
- 为代码任务选择专用模型
|
||||
- 优化的超时设置
|
||||
|
||||
### Research(研究)
|
||||
|
||||
针对研究和分析优化:
|
||||
- 支持长上下文
|
||||
- 高质量响应
|
||||
- 更强大的模型
|
||||
|
||||
配置特点:
|
||||
- 使用具有大上下文窗口的模型
|
||||
- 为分析任务选择高级模型
|
||||
- 较长的超时时间
|
||||
|
||||
### Balanced(平衡)
|
||||
|
||||
在速度和质量之间取得平衡:
|
||||
- 良好的通用性能
|
||||
- 合理的成本
|
||||
- 广泛的模型支持
|
||||
|
||||
配置特点:
|
||||
- 混合使用快速和高质量的模型
|
||||
- 适合大多数日常任务
|
||||
- 平衡的成本效益
|
||||
|
||||
## 使用预设
|
||||
|
||||
使用 CLI 应用预设:
|
||||
|
||||
```bash
|
||||
ccr preset apply development
|
||||
```
|
||||
|
||||
列出可用预设:
|
||||
|
||||
```bash
|
||||
ccr preset list
|
||||
```
|
||||
|
||||
## 创建自定义预设
|
||||
|
||||
您可以通过保存配置并稍后重新加载来创建自定义预设:
|
||||
|
||||
```bash
|
||||
# 将当前配置保存为预设
|
||||
ccr preset save my-preset
|
||||
|
||||
# 加载已保存的预设
|
||||
ccr preset apply my-preset
|
||||
```
|
||||
|
||||
## 预设管理
|
||||
|
||||
### 列出所有预设
|
||||
|
||||
```bash
|
||||
ccr preset list
|
||||
```
|
||||
|
||||
输出示例:
|
||||
|
||||
```
|
||||
可用预设:
|
||||
development - 开发优化配置
|
||||
research - 研究优化配置
|
||||
balanced - 平衡配置
|
||||
my-preset - 自定义预设
|
||||
```
|
||||
|
||||
### 应用预设
|
||||
|
||||
```bash
|
||||
ccr preset apply <预设名称>
|
||||
```
|
||||
|
||||
应用预设后,服务器将自动重启以加载新配置。
|
||||
|
||||
### 删除预设
|
||||
|
||||
```bash
|
||||
ccr preset delete <预设名称>
|
||||
```
|
||||
|
||||
## 预设文件位置
|
||||
|
||||
预设保存在:
|
||||
|
||||
```
|
||||
~/.claude-code-router/presets/
|
||||
```
|
||||
|
||||
每个预设都是一个 JSON 文件,包含完整的配置。
|
||||
|
||||
## 预设文件示例
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "development",
|
||||
"description": "针对软件开发优化的配置",
|
||||
"Providers": [
|
||||
{
|
||||
"name": "deepseek",
|
||||
"api_base_url": "https://api.deepseek.com/chat/completions",
|
||||
"api_key": "$DEEPSEEK_API_KEY",
|
||||
"models": ["deepseek-chat", "deepseek-coder"]
|
||||
},
|
||||
{
|
||||
"name": "groq",
|
||||
"api_base_url": "https://api.groq.com/openai/v1/chat/completions",
|
||||
"api_key": "$GROQ_API_KEY",
|
||||
"models": ["llama-3.3-70b-versatile"]
|
||||
}
|
||||
],
|
||||
"Router": {
|
||||
"default": "deepseek,deepseek-chat",
|
||||
"background": "groq,llama-3.3-70b-versatile",
|
||||
"think": "deepseek,deepseek-chat"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 导出和导入预设
|
||||
|
||||
### 导出当前配置
|
||||
|
||||
```bash
|
||||
ccr config show > my-config.json
|
||||
```
|
||||
|
||||
### 导入配置
|
||||
|
||||
```bash
|
||||
ccr config edit
|
||||
# 然后粘贴导入的配置
|
||||
```
|
||||
|
||||
## 最佳实践
|
||||
|
||||
1. **为不同项目创建预设**:为不同的工作流程创建专门的预设
|
||||
2. **版本控制**:将常用预设保存在版本控制中
|
||||
3. **文档化**:为自定义预设添加描述
|
||||
4. **测试**:在应用预设后验证配置
|
||||
|
||||
## 下一步
|
||||
|
||||
- [CLI 参考](/zh/docs/cli/start) - 完整的 CLI 命令参考
|
||||
- [配置](/zh/docs/config/basic) - 详细配置指南
|
||||
128
docs/i18n/zh-CN/docusaurus-plugin-content-docs/cli/model.md
Normal file
128
docs/i18n/zh-CN/docusaurus-plugin-content-docs/cli/model.md
Normal file
@@ -0,0 +1,128 @@
|
||||
---
|
||||
id: cli/model
|
||||
title: ccr model
|
||||
sidebar_position: 2
|
||||
---
|
||||
|
||||
# ccr model
|
||||
|
||||
交互式模型选择和配置。
|
||||
|
||||
## 用法
|
||||
|
||||
```bash
|
||||
ccr model [命令]
|
||||
```
|
||||
|
||||
## 命令
|
||||
|
||||
### 选择模型
|
||||
|
||||
交互式选择模型:
|
||||
|
||||
```bash
|
||||
ccr model
|
||||
```
|
||||
|
||||
这将显示一个包含可用提供商和模型的交互式菜单。
|
||||
|
||||
### 设置默认模型
|
||||
|
||||
直接设置默认模型:
|
||||
|
||||
```bash
|
||||
ccr model set <provider>,<model>
|
||||
```
|
||||
|
||||
示例:
|
||||
|
||||
```bash
|
||||
ccr model set deepseek,deepseek-chat
|
||||
```
|
||||
|
||||
### 列出模型
|
||||
|
||||
列出所有配置的模型:
|
||||
|
||||
```bash
|
||||
ccr model list
|
||||
```
|
||||
|
||||
### 添加模型
|
||||
|
||||
添加新模型到配置:
|
||||
|
||||
```bash
|
||||
ccr model add <provider>,<model>
|
||||
```
|
||||
|
||||
示例:
|
||||
|
||||
```bash
|
||||
ccr model add groq,llama-3.3-70b-versatile
|
||||
```
|
||||
|
||||
### 删除模型
|
||||
|
||||
从配置中删除模型:
|
||||
|
||||
```bash
|
||||
ccr model remove <provider>,<model>
|
||||
```
|
||||
|
||||
## 示例
|
||||
|
||||
### 交互式选择
|
||||
|
||||
```bash
|
||||
$ ccr model
|
||||
|
||||
? 选择一个提供商: deepseek
|
||||
? 选择一个模型: deepseek-chat
|
||||
|
||||
默认模型设置为: deepseek,deepseek-chat
|
||||
```
|
||||
|
||||
### 直接配置
|
||||
|
||||
```bash
|
||||
ccr model set deepseek,deepseek-chat
|
||||
```
|
||||
|
||||
### 查看当前配置
|
||||
|
||||
```bash
|
||||
ccr model list
|
||||
```
|
||||
|
||||
输出:
|
||||
|
||||
```
|
||||
已配置的模型:
|
||||
deepseek,deepseek-chat (默认)
|
||||
groq,llama-3.3-70b-versatile
|
||||
gemini,gemini-2.5-pro
|
||||
```
|
||||
|
||||
## 交互式功能
|
||||
|
||||
`ccr model` 命令提供以下功能:
|
||||
|
||||
1. **查看当前配置**:查看所有已配置的模型和路由器设置
|
||||
2. **切换模型**:快速更改每个路由器类型使用的模型
|
||||
3. **添加新模型**:向现有提供商添加模型
|
||||
4. **创建新提供商**:设置完整的提供商配置,包括:
|
||||
- 提供商名称和 API 端点
|
||||
- API 密钥
|
||||
- 可用模型
|
||||
- 转换器配置,支持:
|
||||
- 多个转换器(openrouter、deepseek、gemini 等)
|
||||
- 转换器选项(例如,带自定义限制的 maxtoken)
|
||||
- 提供商特定路由(例如,OpenRouter 提供商偏好)
|
||||
|
||||
CLI 工具会验证所有输入并提供有用的提示来引导您完成配置过程,使管理复杂设置变得容易,无需手动编辑 JSON 文件。
|
||||
|
||||
## 相关命令
|
||||
|
||||
- [ccr start](/zh/docs/cli/start) - 启动服务器
|
||||
- [ccr config](/zh/docs/cli/other-commands#ccr-config) - 编辑配置
|
||||
@@ -0,0 +1,203 @@
|
||||
---
|
||||
id: cli/other-commands
|
||||
title: 其他命令
|
||||
sidebar_position: 4
|
||||
---
|
||||
|
||||
# 其他命令
|
||||
|
||||
管理 Claude Code Router 的其他 CLI 命令。
|
||||
|
||||
## ccr stop
|
||||
|
||||
停止运行中的服务器。
|
||||
|
||||
```bash
|
||||
ccr stop
|
||||
```
|
||||
|
||||
## ccr restart
|
||||
|
||||
重启服务器。
|
||||
|
||||
```bash
|
||||
ccr restart
|
||||
```
|
||||
|
||||
## ccr code
|
||||
|
||||
通过路由器执行 claude 命令。
|
||||
|
||||
```bash
|
||||
ccr code [参数...]
|
||||
```
|
||||
|
||||
## ccr activate
|
||||
|
||||
输出 shell 环境变量以供集成使用。
|
||||
|
||||
```bash
|
||||
ccr activate
|
||||
```
|
||||
|
||||
输出:
|
||||
|
||||
```bash
|
||||
export ANTHROPIC_API_URL="http://localhost:3456/v1"
|
||||
export ANTHROPIC_API_KEY="sk-xxxxx"
|
||||
```
|
||||
|
||||
在 shell 中使用:
|
||||
|
||||
```bash
|
||||
eval "$(ccr activate)"
|
||||
```
|
||||
|
||||
`activate` 命令设置以下环境变量:
|
||||
|
||||
- `ANTHROPIC_AUTH_TOKEN`: 来自配置的 API 密钥
|
||||
- `ANTHROPIC_BASE_URL`: 本地路由器端点(默认:`http://127.0.0.1:3456`)
|
||||
- `NO_PROXY`: 设置为 `127.0.0.1` 以防止代理干扰
|
||||
- `DISABLE_TELEMETRY`: 禁用遥测
|
||||
- `DISABLE_COST_WARNINGS`: 禁用成本警告
|
||||
- `API_TIMEOUT_MS`: 来自配置的 API 超时时间
|
||||
|
||||
## ccr ui
|
||||
|
||||
在浏览器中打开 Web UI。
|
||||
|
||||
```bash
|
||||
ccr ui
|
||||
```
|
||||
|
||||
## ccr statusline
|
||||
|
||||
集成状态栏(从 stdin 读取 JSON)。
|
||||
|
||||
```bash
|
||||
echo '{"status":"running"}' | ccr statusline
|
||||
```
|
||||
|
||||
## ccr config
|
||||
|
||||
配置管理命令。
|
||||
|
||||
### 编辑配置
|
||||
|
||||
```bash
|
||||
ccr config edit
|
||||
```
|
||||
|
||||
在默认编辑器中打开配置文件。
|
||||
|
||||
### 验证配置
|
||||
|
||||
```bash
|
||||
ccr config validate
|
||||
```
|
||||
|
||||
验证当前配置文件。
|
||||
|
||||
### 显示配置
|
||||
|
||||
```bash
|
||||
ccr config show
|
||||
```
|
||||
|
||||
显示当前配置(敏感值已隐藏)。
|
||||
|
||||
## ccr preset
|
||||
|
||||
预设管理命令。
|
||||
|
||||
### 列出预设
|
||||
|
||||
```bash
|
||||
ccr preset list
|
||||
```
|
||||
|
||||
### 应用预设
|
||||
|
||||
```bash
|
||||
ccr preset apply <名称>
|
||||
```
|
||||
|
||||
### 保存预设
|
||||
|
||||
```bash
|
||||
ccr preset save <名称>
|
||||
```
|
||||
|
||||
保存当前配置为预设。
|
||||
|
||||
## ccr log
|
||||
|
||||
查看服务器日志。
|
||||
|
||||
```bash
|
||||
ccr log [选项]
|
||||
```
|
||||
|
||||
选项:
|
||||
- `-f, --follow`: 跟踪日志输出(类似 `tail -f`)
|
||||
- `-n <行数>`: 显示的行数
|
||||
|
||||
## 全局选项
|
||||
|
||||
这些选项可用于任何命令:
|
||||
|
||||
| 选项 | 说明 |
|
||||
|------|------|
|
||||
| `-h, --help` | 显示帮助 |
|
||||
| `-v, --version` | 显示版本号 |
|
||||
| `--config <路径>` | 配置文件路径 |
|
||||
| `--verbose` | 启用详细输出 |
|
||||
|
||||
## 示例
|
||||
|
||||
### 停止服务器
|
||||
|
||||
```bash
|
||||
ccr stop
|
||||
```
|
||||
|
||||
### 使用自定义配置重启
|
||||
|
||||
```bash
|
||||
ccr restart --config /path/to/config.json
|
||||
```
|
||||
|
||||
### 查看并设置环境变量
|
||||
|
||||
```bash
|
||||
eval "$(ccr activate)"
|
||||
```
|
||||
|
||||
### 打开 Web UI
|
||||
|
||||
```bash
|
||||
ccr ui
|
||||
```
|
||||
|
||||
### 跟踪日志
|
||||
|
||||
```bash
|
||||
ccr log -f
|
||||
```
|
||||
|
||||
### 列出可用预设
|
||||
|
||||
```bash
|
||||
ccr preset list
|
||||
```
|
||||
|
||||
### 应用预设
|
||||
|
||||
```bash
|
||||
ccr preset apply development
|
||||
```
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [入门](/zh/docs/intro) - Claude Code Router 简介
|
||||
- [配置](/zh/docs/config/basic) - 配置指南
|
||||
83
docs/i18n/zh-CN/docusaurus-plugin-content-docs/cli/start.md
Normal file
83
docs/i18n/zh-CN/docusaurus-plugin-content-docs/cli/start.md
Normal file
@@ -0,0 +1,83 @@
|
||||
---
|
||||
id: cli/start
|
||||
title: ccr start
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
# ccr start
|
||||
|
||||
启动 Claude Code Router 服务器。
|
||||
|
||||
## 用法
|
||||
|
||||
```bash
|
||||
ccr start [选项]
|
||||
```
|
||||
|
||||
## 选项
|
||||
|
||||
| 选项 | 别名 | 说明 |
|
||||
|------|------|------|
|
||||
| `--port <number>` | `-p` | 监听端口号(默认:3456) |
|
||||
| `--config <path>` | `-c` | 配置文件路径 |
|
||||
| `--daemon` | `-d` | 作为守护进程运行(后台进程) |
|
||||
| `--log-level <level>` | `-l` | 日志级别(fatal/error/warn/info/debug/trace) |
|
||||
|
||||
## 示例
|
||||
|
||||
### 使用默认设置启动
|
||||
|
||||
```bash
|
||||
ccr start
|
||||
```
|
||||
|
||||
### 在自定义端口启动
|
||||
|
||||
```bash
|
||||
ccr start --port 3000
|
||||
```
|
||||
|
||||
### 使用自定义配置启动
|
||||
|
||||
```bash
|
||||
ccr start --config /path/to/config.json
|
||||
```
|
||||
|
||||
### 作为守护进程启动
|
||||
|
||||
```bash
|
||||
ccr start --daemon
|
||||
```
|
||||
|
||||
### 启用调试日志
|
||||
|
||||
```bash
|
||||
ccr start --log-level debug
|
||||
```
|
||||
|
||||
## 环境变量
|
||||
|
||||
您也可以使用环境变量配置服务器:
|
||||
|
||||
| 变量 | 说明 |
|
||||
|------|------|
|
||||
| `PORT` | 监听端口号 |
|
||||
| `CONFIG_PATH` | 配置文件路径 |
|
||||
| `LOG_LEVEL` | 日志级别 |
|
||||
| `CUSTOM_ROUTER_PATH` | 自定义路由器函数路径 |
|
||||
| `HOST` | 绑定主机地址(默认:0.0.0.0) |
|
||||
|
||||
## 输出
|
||||
|
||||
启动成功后,您将看到:
|
||||
|
||||
```
|
||||
Claude Code Router is running on http://localhost:3456
|
||||
API endpoint: http://localhost:3456/v1
|
||||
```
|
||||
|
||||
## 相关命令
|
||||
|
||||
- [ccr stop](/zh/docs/cli/other-commands#ccr-stop) - 停止服务器
|
||||
- [ccr restart](/zh/docs/cli/other-commands#ccr-restart) - 重启服务器
|
||||
- [ccr status](/zh/docs/cli/other-commands#ccr-status) - 检查服务器状态
|
||||
64
docs/i18n/zh-CN/docusaurus-plugin-content-docs/cli/status.md
Normal file
64
docs/i18n/zh-CN/docusaurus-plugin-content-docs/cli/status.md
Normal file
@@ -0,0 +1,64 @@
|
||||
---
|
||||
id: cli/status
|
||||
title: ccr status
|
||||
sidebar_position: 3
|
||||
---
|
||||
|
||||
# ccr status
|
||||
|
||||
显示 Claude Code Router 服务器的当前状态。
|
||||
|
||||
## 用法
|
||||
|
||||
```bash
|
||||
ccr status
|
||||
```
|
||||
|
||||
## 输出
|
||||
|
||||
### 运行中的服务器
|
||||
|
||||
当服务器正在运行时:
|
||||
|
||||
```
|
||||
Claude Code Router 状态: 运行中
|
||||
版本: 2.0.0
|
||||
PID: 12345
|
||||
端口: 3456
|
||||
运行时间: 2小时34分钟
|
||||
配置: /home/user/.claude-code-router/config.json
|
||||
```
|
||||
|
||||
### 已停止的服务器
|
||||
|
||||
当服务器未运行时:
|
||||
|
||||
```
|
||||
Claude Code Router 状态: 已停止
|
||||
```
|
||||
|
||||
## 退出代码
|
||||
|
||||
| 代码 | 说明 |
|
||||
|------|------|
|
||||
| 0 | 服务器正在运行 |
|
||||
| 1 | 服务器已停止 |
|
||||
| 2 | 检查状态时出错 |
|
||||
|
||||
## 示例
|
||||
|
||||
```bash
|
||||
$ ccr status
|
||||
|
||||
Claude Code Router 状态: 运行中
|
||||
版本: 2.0.0
|
||||
PID: 12345
|
||||
端口: 3456
|
||||
运行时间: 2小时34分钟
|
||||
```
|
||||
|
||||
## 相关命令
|
||||
|
||||
- [ccr start](/zh/docs/cli/start) - 启动服务器
|
||||
- [ccr stop](/zh/docs/cli/other-commands#ccr-stop) - 停止服务器
|
||||
- [ccr restart](/zh/docs/cli/other-commands#ccr-restart) - 重启服务器
|
||||
161
docs/i18n/zh-CN/docusaurus-plugin-content-docs/config/basic.md
Normal file
161
docs/i18n/zh-CN/docusaurus-plugin-content-docs/config/basic.md
Normal file
@@ -0,0 +1,161 @@
|
||||
---
|
||||
id: config/basic
|
||||
title: 基础配置
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
# 基础配置
|
||||
|
||||
学习如何配置 Claude Code Router 以满足您的需求。
|
||||
|
||||
## 配置文件位置
|
||||
|
||||
配置文件位于:
|
||||
|
||||
```
|
||||
~/.claude-code-router/config.json
|
||||
```
|
||||
|
||||
## 配置结构
|
||||
|
||||
### Providers(提供商)
|
||||
|
||||
配置 LLM 提供商以将请求路由到:
|
||||
|
||||
```json
|
||||
{
|
||||
"Providers": [
|
||||
{
|
||||
"name": "deepseek",
|
||||
"api_base_url": "https://api.deepseek.com/chat/completions",
|
||||
"api_key": "your-api-key",
|
||||
"models": ["deepseek-chat", "deepseek-coder"]
|
||||
},
|
||||
{
|
||||
"name": "groq",
|
||||
"api_base_url": "https://api.groq.com/openai/v1/chat/completions",
|
||||
"api_key": "your-groq-api-key",
|
||||
"models": ["llama-3.3-70b-versatile"]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Router(路由器)
|
||||
|
||||
配置默认使用的模型:
|
||||
|
||||
```json
|
||||
{
|
||||
"Router": {
|
||||
"default": "deepseek,deepseek-chat"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
格式:`{provider-name},{model-name}`
|
||||
|
||||
### Transformers(转换器)
|
||||
|
||||
对请求/响应应用转换:
|
||||
|
||||
```json
|
||||
{
|
||||
"transformers": [
|
||||
{
|
||||
"path": "/path/to/custom-transformer.js",
|
||||
"options": {
|
||||
"key": "value"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 环境变量
|
||||
|
||||
在配置中使用环境变量:
|
||||
|
||||
```json
|
||||
{
|
||||
"Providers": [
|
||||
{
|
||||
"name": "deepseek",
|
||||
"api_base_url": "https://api.deepseek.com/chat/completions",
|
||||
"api_key": "$DEEPSEEK_API_KEY"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
同时支持 `$VAR_NAME` 和 `${VAR_NAME}` 语法。
|
||||
|
||||
## 完整示例
|
||||
|
||||
```json
|
||||
{
|
||||
"PORT": 8080,
|
||||
"APIKEY": "your-secret-key",
|
||||
"PROXY_URL": "http://127.0.0.1:7890",
|
||||
"LOG": true,
|
||||
"LOG_LEVEL": "debug",
|
||||
"API_TIMEOUT_MS": 600000,
|
||||
"Providers": [
|
||||
{
|
||||
"name": "deepseek",
|
||||
"api_base_url": "https://api.deepseek.com/chat/completions",
|
||||
"api_key": "$DEEPSEEK_API_KEY",
|
||||
"models": ["deepseek-chat", "deepseek-coder"],
|
||||
"transformer": {
|
||||
"use": ["deepseek"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "groq",
|
||||
"api_base_url": "https://api.groq.com/openai/v1/chat/completions",
|
||||
"api_key": "$GROQ_API_KEY",
|
||||
"models": ["llama-3.3-70b-versatile"]
|
||||
}
|
||||
],
|
||||
"Router": {
|
||||
"default": "deepseek,deepseek-chat",
|
||||
"longContextThreshold": 100000,
|
||||
"background": "groq,llama-3.3-70b-versatile"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 编辑配置
|
||||
|
||||
使用 CLI 编辑配置:
|
||||
|
||||
```bash
|
||||
ccr config edit
|
||||
```
|
||||
|
||||
这将在您的默认编辑器中打开配置文件。
|
||||
|
||||
## 重新加载配置
|
||||
|
||||
编辑配置后,重启路由器:
|
||||
|
||||
```bash
|
||||
ccr restart
|
||||
```
|
||||
|
||||
## 配置选项说明
|
||||
|
||||
- **PORT**: 服务器端口号(默认:3456)
|
||||
- **APIKEY**: API 密钥,用于身份验证
|
||||
- **HOST**: 服务器监听地址(默认:127.0.0.1,如果配置了 Providers 且没有设置 APIKEY,则强制为 127.0.0.1)
|
||||
- **PROXY_URL**: 代理服务器地址
|
||||
- **LOG**: 是否启用日志(默认:true)
|
||||
- **LOG_LEVEL**: 日志级别(fatal/error/warn/info/debug/trace)
|
||||
- **API_TIMEOUT_MS**: API 请求超时时间(毫秒)
|
||||
- **NON_INTERACTIVE_MODE**: 非交互模式(用于 CI/CD 环境)
|
||||
|
||||
## 下一步
|
||||
|
||||
- [提供商配置](/zh/docs/config/providers) - 详细的提供商配置
|
||||
- [路由配置](/zh/docs/config/routing) - 配置路由规则
|
||||
- [转换器](/zh/docs/config/transformers) - 应用转换
|
||||
@@ -0,0 +1,213 @@
|
||||
---
|
||||
id: config/providers
|
||||
title: 提供商配置
|
||||
sidebar_position: 2
|
||||
---
|
||||
|
||||
# 提供商配置
|
||||
|
||||
配置 LLM 提供商的详细指南。
|
||||
|
||||
## 支持的提供商
|
||||
|
||||
### DeepSeek
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "deepseek",
|
||||
"api_base_url": "https://api.deepseek.com/chat/completions",
|
||||
"api_key": "your-api-key",
|
||||
"models": ["deepseek-chat", "deepseek-coder", "deepseek-reasoner"],
|
||||
"transformer": {
|
||||
"use": ["deepseek"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Groq
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "groq",
|
||||
"api_base_url": "https://api.groq.com/openai/v1/chat/completions",
|
||||
"api_key": "your-api-key",
|
||||
"models": ["llama-3.3-70b-versatile"]
|
||||
}
|
||||
```
|
||||
|
||||
### Gemini
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "gemini",
|
||||
"api_base_url": "https://generativelanguage.googleapis.com/v1beta/models/",
|
||||
"api_key": "your-api-key",
|
||||
"models": ["gemini-2.5-flash", "gemini-2.5-pro"],
|
||||
"transformer": {
|
||||
"use": ["gemini"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### OpenRouter
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "openrouter",
|
||||
"api_base_url": "https://openrouter.ai/api/v1/chat/completions",
|
||||
"api_key": "your-api-key",
|
||||
"models": [
|
||||
"anthropic/claude-3.5-sonnet",
|
||||
"google/gemini-2.5-pro-preview"
|
||||
],
|
||||
"transformer": {
|
||||
"use": ["openrouter"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Ollama(本地模型)
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "ollama",
|
||||
"api_base_url": "http://localhost:11434/v1/chat/completions",
|
||||
"api_key": "ollama",
|
||||
"models": ["qwen2.5-coder:latest"]
|
||||
}
|
||||
```
|
||||
|
||||
### 火山引擎
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "volcengine",
|
||||
"api_base_url": "https://ark.cn-beijing.volces.com/api/v3/chat/completions",
|
||||
"api_key": "your-api-key",
|
||||
"models": ["deepseek-v3-250324", "deepseek-r1-250528"],
|
||||
"transformer": {
|
||||
"use": ["deepseek"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### ModelScope
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "modelscope",
|
||||
"api_base_url": "https://api-inference.modelscope.cn/v1/chat/completions",
|
||||
"api_key": "",
|
||||
"models": [
|
||||
"Qwen/Qwen3-Coder-480B-A35B-Instruct",
|
||||
"Qwen/Qwen3-235B-A22B-Thinking-2507"
|
||||
],
|
||||
"transformer": {
|
||||
"use": [
|
||||
["maxtoken", { "max_tokens": 65536 }],
|
||||
"enhancetool"
|
||||
],
|
||||
"Qwen/Qwen3-235B-A22B-Thinking-2507": {
|
||||
"use": ["reasoning"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### DashScope(阿里云)
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "dashscope",
|
||||
"api_base_url": "https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions",
|
||||
"api_key": "your-api-key",
|
||||
"models": ["qwen3-coder-plus"],
|
||||
"transformer": {
|
||||
"use": [
|
||||
["maxtoken", { "max_tokens": 65536 }],
|
||||
"enhancetool"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 提供商配置选项
|
||||
|
||||
| 字段 | 类型 | 必填 | 说明 |
|
||||
|------|------|------|------|
|
||||
| `name` | string | 是 | 提供商的唯一标识符 |
|
||||
| `api_base_url` | string | 是 | API 基础 URL |
|
||||
| `api_key` | string | 是 | API 认证密钥 |
|
||||
| `models` | string[] | 否 | 可用模型列表 |
|
||||
| `transformer` | object | 否 | 应用的转换器配置 |
|
||||
|
||||
## 模型选择
|
||||
|
||||
在路由中选择模型时,使用以下格式:
|
||||
|
||||
```
|
||||
{provider-name},{model-name}
|
||||
```
|
||||
|
||||
例如:
|
||||
|
||||
```
|
||||
deepseek,deepseek-chat
|
||||
```
|
||||
|
||||
## 使用环境变量
|
||||
|
||||
您可以在配置中使用环境变量来保护 API 密钥:
|
||||
|
||||
```json
|
||||
{
|
||||
"Providers": [
|
||||
{
|
||||
"name": "deepseek",
|
||||
"api_base_url": "https://api.deepseek.com/chat/completions",
|
||||
"api_key": "$DEEPSEEK_API_KEY",
|
||||
"models": ["deepseek-chat"]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
支持 `$VAR_NAME` 和 `${VAR_NAME}` 两种语法。
|
||||
|
||||
## 转换器配置
|
||||
|
||||
转换器用于适配不同提供商的 API 差异。您可以在提供商级别或模型级别配置转换器:
|
||||
|
||||
### 提供商级别转换器
|
||||
|
||||
应用于提供商的所有模型:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "openrouter",
|
||||
"transformer": {
|
||||
"use": ["openrouter"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 模型级别转换器
|
||||
|
||||
应用于特定模型:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "deepseek",
|
||||
"transformer": {
|
||||
"use": ["deepseek"],
|
||||
"deepseek-chat": {
|
||||
"use": ["tooluse"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 下一步
|
||||
|
||||
- [路由配置](/zh/docs/config/routing) - 配置请求如何路由
|
||||
- [转换器](/zh/docs/config/transformers) - 对请求应用转换
|
||||
165
docs/i18n/zh-CN/docusaurus-plugin-content-docs/config/routing.md
Normal file
165
docs/i18n/zh-CN/docusaurus-plugin-content-docs/config/routing.md
Normal file
@@ -0,0 +1,165 @@
|
||||
---
|
||||
id: config/routing
|
||||
title: 路由配置
|
||||
sidebar_position: 3
|
||||
---
|
||||
|
||||
# 路由配置
|
||||
|
||||
配置如何将请求路由到不同的模型。
|
||||
|
||||
## 默认路由
|
||||
|
||||
为所有请求设置默认模型:
|
||||
|
||||
```json
|
||||
{
|
||||
"Router": {
|
||||
"default": "deepseek,deepseek-chat"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 内置场景
|
||||
|
||||
### 后台任务
|
||||
|
||||
将后台任务路由到轻量级模型:
|
||||
|
||||
```json
|
||||
{
|
||||
"Router": {
|
||||
"background": "groq,llama-3.3-70b-versatile"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 思考模式(计划模式)
|
||||
|
||||
将思考密集型任务路由到更强大的模型:
|
||||
|
||||
```json
|
||||
{
|
||||
"Router": {
|
||||
"think": "deepseek,deepseek-reasoner"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 长上下文
|
||||
|
||||
路由长上下文请求:
|
||||
|
||||
```json
|
||||
{
|
||||
"Router": {
|
||||
"longContextThreshold": 100000,
|
||||
"longContext": "gemini,gemini-2.5-pro"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 网络搜索
|
||||
|
||||
路由网络搜索任务:
|
||||
|
||||
```json
|
||||
{
|
||||
"Router": {
|
||||
"webSearch": "gemini,gemini-2.5-flash"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 图像任务
|
||||
|
||||
路由图像相关任务:
|
||||
|
||||
```json
|
||||
{
|
||||
"Router": {
|
||||
"image": "gemini,gemini-2.5-pro"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 项目级路由
|
||||
|
||||
在 `~/.claude/projects/<project-id>/claude-code-router.json` 中为每个项目配置路由:
|
||||
|
||||
```json
|
||||
{
|
||||
"Router": {
|
||||
"default": "groq,llama-3.3-70b-versatile"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
项目级配置优先于全局配置。
|
||||
|
||||
## 自定义路由器
|
||||
|
||||
创建自定义 JavaScript 路由器函数:
|
||||
|
||||
1. 创建路由器文件(例如 `custom-router.js`):
|
||||
|
||||
```javascript
|
||||
module.exports = async function(req, config) {
|
||||
// 分析请求上下文
|
||||
const userMessage = req.body.messages.find(m => m.role === 'user')?.content;
|
||||
|
||||
// 自定义路由逻辑
|
||||
if (userMessage && userMessage.includes('解释代码')) {
|
||||
return 'openrouter,anthropic/claude-3.5-sonnet';
|
||||
}
|
||||
|
||||
// 返回 null 以使用默认路由
|
||||
return null;
|
||||
};
|
||||
```
|
||||
|
||||
2. 在 `config.json` 中设置 `CUSTOM_ROUTER_PATH`:
|
||||
|
||||
```json
|
||||
{
|
||||
"CUSTOM_ROUTER_PATH": "/path/to/custom-router.js"
|
||||
}
|
||||
```
|
||||
|
||||
## Token 计数
|
||||
|
||||
路由器使用 `tiktoken` (cl100k_base) 来估算请求 token 数量。这用于:
|
||||
|
||||
- 确定请求是否超过 `longContextThreshold`
|
||||
- 基于 token 数量的自定义路由逻辑
|
||||
|
||||
## 子代理路由
|
||||
|
||||
使用特殊标签为子代理指定模型:
|
||||
|
||||
```
|
||||
<CCR-SUBAGENT-MODEL>provider,model</CCR-SUBAGENT-MODEL>
|
||||
请帮我分析这段代码...
|
||||
```
|
||||
|
||||
## 动态模型切换
|
||||
|
||||
在 Claude Code 中使用 `/model` 命令动态切换模型:
|
||||
|
||||
```
|
||||
/model provider_name,model_name
|
||||
```
|
||||
|
||||
示例:`/model openrouter,anthropic/claude-3.5-sonnet`
|
||||
|
||||
## 路由优先级
|
||||
|
||||
1. 项目级配置
|
||||
2. 自定义路由器
|
||||
3. 内置场景路由
|
||||
4. 默认路由
|
||||
|
||||
## 下一步
|
||||
|
||||
- [转换器](/zh/docs/config/transformers) - 对请求应用转换
|
||||
- [自定义路由器](/zh/docs/advanced/custom-router) - 高级自定义路由
|
||||
@@ -0,0 +1,283 @@
|
||||
---
|
||||
id: config/transformers
|
||||
title: 转换器
|
||||
sidebar_position: 4
|
||||
---
|
||||
|
||||
# 转换器
|
||||
|
||||
转换器用于适配不同提供商之间的 API 差异。
|
||||
|
||||
## 内置转换器
|
||||
|
||||
### anthropic
|
||||
|
||||
将请求转换为兼容 Anthropic 风格的 API:
|
||||
|
||||
```json
|
||||
{
|
||||
"transformer": {
|
||||
"use": ["anthropic"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
如果只使用这一个转换器,它将直接透传请求和响应(您可以用来接入其他支持 Anthropic 端点的服务商)。
|
||||
|
||||
### deepseek
|
||||
|
||||
专门用于 DeepSeek API 的转换器:
|
||||
|
||||
```json
|
||||
{
|
||||
"transformer": {
|
||||
"use": ["deepseek"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### gemini
|
||||
|
||||
用于 Google Gemini API 的转换器:
|
||||
|
||||
```json
|
||||
{
|
||||
"transformer": {
|
||||
"use": ["gemini"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### groq
|
||||
|
||||
用于 Groq API 的转换器:
|
||||
|
||||
```json
|
||||
{
|
||||
"transformer": {
|
||||
"use": ["groq"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### openrouter
|
||||
|
||||
用于 OpenRouter API 的转换器:
|
||||
|
||||
```json
|
||||
{
|
||||
"transformer": {
|
||||
"use": ["openrouter"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
OpenRouter 转换器还支持 `provider` 路由参数,以指定 OpenRouter 应使用哪些底层提供商:
|
||||
|
||||
```json
|
||||
{
|
||||
"transformer": {
|
||||
"use": ["openrouter"],
|
||||
"moonshotai/kimi-k2": {
|
||||
"use": [
|
||||
["openrouter", {
|
||||
"provider": {
|
||||
"only": ["moonshotai/fp8"]
|
||||
}
|
||||
}]
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### maxtoken
|
||||
|
||||
设置特定的 `max_tokens` 值:
|
||||
|
||||
```json
|
||||
{
|
||||
"transformer": {
|
||||
"use": [
|
||||
["maxtoken", { "max_tokens": 65536 }]
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### tooluse
|
||||
|
||||
通过 `tool_choice` 参数优化某些模型的工具使用:
|
||||
|
||||
```json
|
||||
{
|
||||
"transformer": {
|
||||
"use": ["tooluse"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### reasoning
|
||||
|
||||
用于处理 `reasoning_content` 字段:
|
||||
|
||||
```json
|
||||
{
|
||||
"transformer": {
|
||||
"use": ["reasoning"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### sampling
|
||||
|
||||
用于处理采样信息字段,如 `temperature`、`top_p`、`top_k` 和 `repetition_penalty`:
|
||||
|
||||
```json
|
||||
{
|
||||
"transformer": {
|
||||
"use": ["sampling"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### enhancetool
|
||||
|
||||
对 LLM 返回的工具调用参数增加一层容错处理(注意:这会导致不再流式返回工具调用信息):
|
||||
|
||||
```json
|
||||
{
|
||||
"transformer": {
|
||||
"use": ["enhancetool"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### cleancache
|
||||
|
||||
清除请求中的 `cache_control` 字段:
|
||||
|
||||
```json
|
||||
{
|
||||
"transformer": {
|
||||
"use": ["cleancache"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### vertex-gemini
|
||||
|
||||
处理使用 Vertex 鉴权的 Gemini API:
|
||||
|
||||
```json
|
||||
{
|
||||
"transformer": {
|
||||
"use": ["vertex-gemini"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 应用转换器
|
||||
|
||||
### 全局应用
|
||||
|
||||
应用于提供商的所有请求:
|
||||
|
||||
```json
|
||||
{
|
||||
"Providers": [
|
||||
{
|
||||
"name": "deepseek",
|
||||
"api_base_url": "https://api.deepseek.com/chat/completions",
|
||||
"api_key": "your-api-key",
|
||||
"transformer": {
|
||||
"use": ["deepseek"]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 模型特定应用
|
||||
|
||||
应用于特定模型:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "deepseek",
|
||||
"transformer": {
|
||||
"use": ["deepseek"],
|
||||
"deepseek-chat": {
|
||||
"use": ["tooluse"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 传递选项
|
||||
|
||||
某些转换器接受选项:
|
||||
|
||||
```json
|
||||
{
|
||||
"transformer": {
|
||||
"use": [
|
||||
["maxtoken", { "max_tokens": 8192 }]
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 自定义转换器
|
||||
|
||||
创建自定义转换器插件:
|
||||
|
||||
1. 创建转换器文件:
|
||||
|
||||
```javascript
|
||||
module.exports = {
|
||||
name: 'my-transformer',
|
||||
transformRequest: async (req, config) => {
|
||||
// 修改请求
|
||||
return req;
|
||||
},
|
||||
transformResponse: async (res, config) => {
|
||||
// 修改响应
|
||||
return res;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
2. 在配置中加载:
|
||||
|
||||
```json
|
||||
{
|
||||
"transformers": [
|
||||
{
|
||||
"path": "/path/to/transformer.js",
|
||||
"options": {
|
||||
"key": "value"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 实验性转换器
|
||||
|
||||
### gemini-cli(实验性)
|
||||
|
||||
通过 Gemini CLI 对 Gemini 的非官方支持。
|
||||
|
||||
### qwen-cli(实验性)
|
||||
|
||||
通过 Qwen CLI 对 qwen3-coder-plus 的非官方支持。
|
||||
|
||||
### rovo-cli(实验性)
|
||||
|
||||
通过 Atlassian Rovo Dev CLI 对 GPT-5 的非官方支持。
|
||||
|
||||
## 下一步
|
||||
|
||||
- [高级主题](/zh/docs/advanced/custom-router) - 高级路由自定义
|
||||
- [Agent](/zh/docs/advanced/agents) - 使用 Agent 扩展功能
|
||||
54
docs/i18n/zh-CN/docusaurus-plugin-content-docs/current.json
Normal file
54
docs/i18n/zh-CN/docusaurus-plugin-content-docs/current.json
Normal file
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"version.label": {
|
||||
"message": "Next",
|
||||
"description": "The label for version current"
|
||||
},
|
||||
"sidebar.tutorialSidebar.category.Getting Started": {
|
||||
"message": "Getting Started",
|
||||
"description": "The label for category 'Getting Started' in sidebar 'tutorialSidebar'"
|
||||
},
|
||||
"sidebar.tutorialSidebar.category.Getting Started.link.generated-index.title": {
|
||||
"message": "Getting Started",
|
||||
"description": "The generated-index page title for category 'Getting Started' in sidebar 'tutorialSidebar'"
|
||||
},
|
||||
"sidebar.tutorialSidebar.category.Getting Started.link.generated-index.description": {
|
||||
"message": "Learn the basics of Claude Code Router",
|
||||
"description": "The generated-index page description for category 'Getting Started' in sidebar 'tutorialSidebar'"
|
||||
},
|
||||
"sidebar.tutorialSidebar.category.Configuration": {
|
||||
"message": "Configuration",
|
||||
"description": "The label for category 'Configuration' in sidebar 'tutorialSidebar'"
|
||||
},
|
||||
"sidebar.tutorialSidebar.category.Configuration.link.generated-index.title": {
|
||||
"message": "Configuration",
|
||||
"description": "The generated-index page title for category 'Configuration' in sidebar 'tutorialSidebar'"
|
||||
},
|
||||
"sidebar.tutorialSidebar.category.Configuration.link.generated-index.description": {
|
||||
"message": "Configure Claude Code Router to suit your needs",
|
||||
"description": "The generated-index page description for category 'Configuration' in sidebar 'tutorialSidebar'"
|
||||
},
|
||||
"sidebar.tutorialSidebar.category.Advanced": {
|
||||
"message": "Advanced",
|
||||
"description": "The label for category 'Advanced' in sidebar 'tutorialSidebar'"
|
||||
},
|
||||
"sidebar.tutorialSidebar.category.Advanced.link.generated-index.title": {
|
||||
"message": "Advanced Topics",
|
||||
"description": "The generated-index page title for category 'Advanced' in sidebar 'tutorialSidebar'"
|
||||
},
|
||||
"sidebar.tutorialSidebar.category.Advanced.link.generated-index.description": {
|
||||
"message": "Advanced features and customization",
|
||||
"description": "The generated-index page description for category 'Advanced' in sidebar 'tutorialSidebar'"
|
||||
},
|
||||
"sidebar.tutorialSidebar.category.CLI Reference": {
|
||||
"message": "CLI Reference",
|
||||
"description": "The label for category 'CLI Reference' in sidebar 'tutorialSidebar'"
|
||||
},
|
||||
"sidebar.tutorialSidebar.category.CLI Reference.link.generated-index.title": {
|
||||
"message": "CLI Commands",
|
||||
"description": "The generated-index page title for category 'CLI Reference' in sidebar 'tutorialSidebar'"
|
||||
},
|
||||
"sidebar.tutorialSidebar.category.CLI Reference.link.generated-index.description": {
|
||||
"message": "Complete reference for all CLI commands",
|
||||
"description": "The generated-index page description for category 'CLI Reference' in sidebar 'tutorialSidebar'"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
---
|
||||
id: installation
|
||||
title: 安装
|
||||
sidebar_position: 2
|
||||
---
|
||||
|
||||
# 安装
|
||||
|
||||
使用您喜欢的包管理器全局安装 Claude Code Router。
|
||||
|
||||
## 前置要求
|
||||
|
||||
- **Node.js**: >= 18.0.0
|
||||
- **pnpm**: >= 8.0.0(如果使用 pnpm)
|
||||
- 来自您偏好的 LLM 提供商的 API 密钥
|
||||
|
||||
## 通过 npm 安装
|
||||
|
||||
```bash
|
||||
npm install -g @musistudio/claude-code-router-cli
|
||||
```
|
||||
|
||||
## 通过 pnpm 安装
|
||||
|
||||
```bash
|
||||
pnpm add -g @musistudio/claude-code-router-cli
|
||||
```
|
||||
|
||||
## 通过 Yarn 安装
|
||||
|
||||
```bash
|
||||
yarn global add @musistudio/claude-code-router-cli
|
||||
```
|
||||
|
||||
## 验证安装
|
||||
|
||||
安装完成后,验证 `ccr` 命令是否可用:
|
||||
|
||||
```bash
|
||||
ccr --version
|
||||
```
|
||||
|
||||
您应该看到版本号显示。
|
||||
|
||||
## 下一步
|
||||
|
||||
安装完成后,前往 [快速开始](/zh/docs/quick-start) 了解如何配置和使用路由器。
|
||||
71
docs/i18n/zh-CN/docusaurus-plugin-content-docs/intro.md
Normal file
71
docs/i18n/zh-CN/docusaurus-plugin-content-docs/intro.md
Normal file
@@ -0,0 +1,71 @@
|
||||
---
|
||||
id: intro
|
||||
title: 欢迎使用 Claude Code Router
|
||||
sidebar_position: 1
|
||||
slug: /
|
||||
---
|
||||
|
||||
# 欢迎使用 Claude Code Router
|
||||
|
||||
[](https://www.npmjs.com/package/@musistudio/claude-code-router-cli)
|
||||

|
||||

|
||||
|
||||
**Claude Code Router** 是一个强大的工具,允许你在没有 Anthropic 账户的情况下使用 [Claude Code](https://claude.ai/code),并将请求路由到其他 LLM 提供商。
|
||||
|
||||
## 特性
|
||||
|
||||
- **多提供商支持**: 路由到 DeepSeek、Gemini、Groq、OpenRouter 等
|
||||
- **智能路由**: 内置不同任务类型的场景(后台、思考、网络搜索、图像)
|
||||
- **项目级配置**: 每个项目自定义路由
|
||||
- **自定义路由函数**: 编写 JavaScript 定义自己的路由逻辑
|
||||
- **转换器系统**: 无缝适配不同提供商之间的 API 差异
|
||||
- **代理系统**: 可扩展的插件架构,实现自定义功能
|
||||
- **Web UI**: 内置管理界面,方便配置
|
||||
- **CLI 集成**: 与现有的 Claude Code 工作流无缝集成
|
||||
|
||||
## 快速开始
|
||||
|
||||
### 安装
|
||||
|
||||
```bash
|
||||
npm install -g @musistudio/claude-code-router-cli
|
||||
# 或
|
||||
pnpm add -g @musistudio/claude-code-router-cli
|
||||
# 或
|
||||
yarn global add @musistudio/claude-code-router-cli
|
||||
```
|
||||
|
||||
### 基本使用
|
||||
|
||||
```bash
|
||||
# 启动路由器服务器
|
||||
ccr start
|
||||
|
||||
# 配置 Claude Code 使用路由器
|
||||
export ANTHROPIC_API_URL="http://localhost:8080/v1"
|
||||
export ANTHROPIC_API_KEY="your-api-key"
|
||||
|
||||
# 现在可以正常使用 Claude Code!
|
||||
claude code
|
||||
```
|
||||
|
||||
## 下一步
|
||||
|
||||
- [安装指南](/docs/installation) - 详细安装说明
|
||||
- [快速开始](/docs/quick-start) - 5 分钟入门
|
||||
- [配置](/docs/config/basic) - 了解如何配置路由器
|
||||
- [CLI 参考](/docs/cli/start) - 完整的 CLI 命令参考
|
||||
|
||||
## 架构
|
||||
|
||||
Claude Code Router 由四个主要组件组成:
|
||||
|
||||
- **CLI** (`@musistudio/claude-code-router-cli`): 提供 `ccr` 命令的命令行工具
|
||||
- **Server** (`@musistudio/claude-code-router-server`): 处理 API 路由和转换的核心服务器
|
||||
- **Shared** (`@musistudio/claude-code-router-shared`): 共享常量和工具
|
||||
- **UI** (`@musistudio/claude-code-router-ui`): Web 管理界面(React + Vite)
|
||||
|
||||
## 许可证
|
||||
|
||||
MIT © [musistudio](https://github.com/musistudio)
|
||||
@@ -0,0 +1,83 @@
|
||||
---
|
||||
id: quick-start
|
||||
title: 快速开始
|
||||
sidebar_position: 3
|
||||
---
|
||||
|
||||
# 快速开始
|
||||
|
||||
5 分钟内启动并运行 Claude Code Router。
|
||||
|
||||
## 1. 启动路由器
|
||||
|
||||
```bash
|
||||
ccr start
|
||||
```
|
||||
|
||||
路由器默认将在 `http://localhost:8080` 上启动。
|
||||
|
||||
## 2. 配置环境变量
|
||||
|
||||
在您的 shell 中设置以下环境变量:
|
||||
|
||||
```bash
|
||||
export ANTHROPIC_API_URL="http://localhost:8080/v1"
|
||||
export ANTHROPIC_API_KEY="your-provider-api-key"
|
||||
```
|
||||
|
||||
或者使用 `ccr activate` 命令获取环境变量:
|
||||
|
||||
```bash
|
||||
eval "$(ccr activate)"
|
||||
```
|
||||
|
||||
## 3. 使用 Claude Code
|
||||
|
||||
现在您可以正常使用 Claude Code:
|
||||
|
||||
```bash
|
||||
claude code
|
||||
```
|
||||
|
||||
您的请求将通过 Claude Code Router 路由到您配置的提供商。
|
||||
|
||||
## 4. 配置提供商(可选)
|
||||
|
||||
要配置多个提供商或自定义路由,使用:
|
||||
|
||||
```bash
|
||||
ccr model
|
||||
```
|
||||
|
||||
这将打开一个交互式菜单来选择和配置模型。
|
||||
|
||||
或者直接编辑配置文件:
|
||||
|
||||
```bash
|
||||
# 在默认编辑器中打开配置
|
||||
ccr config edit
|
||||
```
|
||||
|
||||
配置文件示例 (`~/.claude-code-router/config.json`):
|
||||
|
||||
```json
|
||||
{
|
||||
"Providers": [
|
||||
{
|
||||
"name": "deepseek",
|
||||
"api_base_url": "https://api.deepseek.com/chat/completions",
|
||||
"api_key": "your-deepseek-api-key",
|
||||
"models": ["deepseek-chat", "deepseek-coder"]
|
||||
}
|
||||
],
|
||||
"Router": {
|
||||
"default": "deepseek,deepseek-chat"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 下一步
|
||||
|
||||
- [基础配置](/zh/docs/config/basic) - 了解配置选项
|
||||
- [路由配置](/zh/docs/config/routing) - 配置智能路由规则
|
||||
- [CLI 命令](/zh/docs/cli/start) - 探索所有 CLI 命令
|
||||
50
docs/i18n/zh-CN/docusaurus-theme-classic/footer.json
Normal file
50
docs/i18n/zh-CN/docusaurus-theme-classic/footer.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"link.title.Documentation": {
|
||||
"message": "文档",
|
||||
"description": "The title of the footer links column with title=Documentation in the footer"
|
||||
},
|
||||
"link.title.Community": {
|
||||
"message": "社区",
|
||||
"description": "The title of the footer links column with title=Community in the footer"
|
||||
},
|
||||
"link.title.Resources": {
|
||||
"message": "资源",
|
||||
"description": "The title of the footer links column with title=Resources in the footer"
|
||||
},
|
||||
"link.item.label.Introduction": {
|
||||
"message": "简介",
|
||||
"description": "The label of footer link with label=Introduction linking to /docs/intro"
|
||||
},
|
||||
"link.item.label.Installation": {
|
||||
"message": "安装",
|
||||
"description": "The label of footer link with label=Installation linking to /docs/cli/installation"
|
||||
},
|
||||
"link.item.label.Quick Start": {
|
||||
"message": "快速开始",
|
||||
"description": "The label of footer link with label=Quick Start linking to /docs/cli/quick-start"
|
||||
},
|
||||
"link.item.label.GitHub": {
|
||||
"message": "GitHub",
|
||||
"description": "The label of footer link with label=GitHub linking to https://github.com/musistudio/claude-code-router"
|
||||
},
|
||||
"link.item.label.Issues": {
|
||||
"message": "问题反馈",
|
||||
"description": "The label of footer link with label=Issues linking to https://github.com/musistudio/claude-code-router/issues"
|
||||
},
|
||||
"link.item.label.Releases": {
|
||||
"message": "发布版本",
|
||||
"description": "The label of footer link with label=Releases linking to https://github.com/musistudio/claude-code-router/releases"
|
||||
},
|
||||
"link.item.label.Blog": {
|
||||
"message": "博客",
|
||||
"description": "The label of footer link with label=Blog linking to /blog"
|
||||
},
|
||||
"link.item.label.NPM Package": {
|
||||
"message": "NPM 包",
|
||||
"description": "The label of footer link with label=NPM Package linking to https://www.npmjs.com/package/@musistudio/claude-code-router-cli"
|
||||
},
|
||||
"copyright": {
|
||||
"message": "Copyright © 2025 Claude Code Router. 保留所有权利。",
|
||||
"description": "The footer copyright"
|
||||
}
|
||||
}
|
||||
22
docs/i18n/zh-CN/docusaurus-theme-classic/navbar.json
Normal file
22
docs/i18n/zh-CN/docusaurus-theme-classic/navbar.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"title": {
|
||||
"message": "Claude Code Router",
|
||||
"description": "The title in the navbar"
|
||||
},
|
||||
"logo.alt": {
|
||||
"message": "Claude Code Router Logo",
|
||||
"description": "The alt text of navbar logo"
|
||||
},
|
||||
"item.label.Documentation": {
|
||||
"message": "Documentation",
|
||||
"description": "Navbar item with label Documentation"
|
||||
},
|
||||
"item.label.Blog": {
|
||||
"message": "Blog",
|
||||
"description": "Navbar item with label Blog"
|
||||
},
|
||||
"item.label.GitHub": {
|
||||
"message": "GitHub",
|
||||
"description": "Navbar item with label GitHub"
|
||||
}
|
||||
}
|
||||
45
docs/package.json
Normal file
45
docs/package.json
Normal file
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"name": "claude-code-router-docs",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"docusaurus": "docusaurus",
|
||||
"start": "docusaurus start",
|
||||
"build": "docusaurus build",
|
||||
"swizzle": "docusaurus swizzle",
|
||||
"deploy": "docusaurus deploy",
|
||||
"clear": "docusaurus clear",
|
||||
"serve": "docusaurus serve",
|
||||
"write-translations": "docusaurus write-translations",
|
||||
"write-heading-ids": "docusaurus write-heading-ids"
|
||||
},
|
||||
"dependencies": {
|
||||
"@docusaurus/core": "^3.9.2",
|
||||
"@docusaurus/preset-classic": "^3.9.2",
|
||||
"@mdx-js/react": "^3.0.0",
|
||||
"prism-react-renderer": "^2.4.1",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@docusaurus/module-type-aliases": "^3.9.2",
|
||||
"@docusaurus/types": "^3.9.2",
|
||||
"autoprefixer": "^10.4.21",
|
||||
"tailwindcss": "3"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.5%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0"
|
||||
}
|
||||
}
|
||||
6
docs/postcss.config.js
Normal file
6
docs/postcss.config.js
Normal file
@@ -0,0 +1,6 @@
|
||||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
}
|
||||
114
docs/sidebars.ts
Normal file
114
docs/sidebars.ts
Normal file
@@ -0,0 +1,114 @@
|
||||
import type { SidebarsConfig } from '@docusaurus/plugin-content-docs';
|
||||
|
||||
const sidebars: SidebarsConfig = {
|
||||
tutorialSidebar: [
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Server',
|
||||
link: {
|
||||
type: 'generated-index',
|
||||
title: 'Claude Code Router Server',
|
||||
description: '部署和管理 Claude Code Router 服务',
|
||||
slug: 'category/server',
|
||||
},
|
||||
items: [
|
||||
'server/intro',
|
||||
'server/deployment',
|
||||
{
|
||||
type: 'category',
|
||||
label: 'API Reference',
|
||||
link: {
|
||||
type: 'generated-index',
|
||||
title: 'API Reference',
|
||||
description: '服务器 API 接口文档',
|
||||
slug: 'category/api',
|
||||
},
|
||||
items: [
|
||||
'server/api/overview',
|
||||
'server/api/messages-api',
|
||||
'server/api/config-api',
|
||||
'server/api/logs-api',
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Configuration',
|
||||
link: {
|
||||
type: 'generated-index',
|
||||
title: 'Server Configuration',
|
||||
description: '服务器配置说明',
|
||||
slug: 'category/server-config',
|
||||
},
|
||||
items: [
|
||||
'server/config/basic',
|
||||
'server/config/providers',
|
||||
'server/config/routing',
|
||||
'server/config/transformers',
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Advanced',
|
||||
link: {
|
||||
type: 'generated-index',
|
||||
title: 'Advanced Topics',
|
||||
description: '高级功能和自定义',
|
||||
slug: 'category/server-advanced',
|
||||
},
|
||||
items: [
|
||||
'server/advanced/custom-router',
|
||||
'server/advanced/agents',
|
||||
'server/advanced/presets',
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: 'CLI',
|
||||
link: {
|
||||
type: 'generated-index',
|
||||
title: 'Claude Code Router CLI',
|
||||
description: '命令行工具使用指南',
|
||||
slug: 'category/cli',
|
||||
},
|
||||
items: [
|
||||
'cli/intro',
|
||||
'cli/installation',
|
||||
'cli/quick-start',
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Commands',
|
||||
link: {
|
||||
type: 'generated-index',
|
||||
title: 'CLI Commands',
|
||||
description: '完整的命令参考',
|
||||
slug: 'category/cli-commands',
|
||||
},
|
||||
items: [
|
||||
'cli/commands/start',
|
||||
'cli/commands/model',
|
||||
'cli/commands/status',
|
||||
'cli/commands/other',
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Configuration',
|
||||
link: {
|
||||
type: 'generated-index',
|
||||
title: 'CLI Configuration',
|
||||
description: 'CLI 配置说明',
|
||||
slug: 'category/cli-config',
|
||||
},
|
||||
items: [
|
||||
'cli/config/basic',
|
||||
'cli/config/project-level',
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default sidebars;
|
||||
59
docs/src/components/HomepageFeatures.module.css
Normal file
59
docs/src/components/HomepageFeatures.module.css
Normal file
@@ -0,0 +1,59 @@
|
||||
.features {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 2rem 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.featureSvg {
|
||||
height: 160px;
|
||||
width: 160px;
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.feature:hover .featureSvg {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.feature {
|
||||
padding: 1.5rem;
|
||||
border-radius: 12px;
|
||||
background: var(--ifm-background-surface-color);
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||||
height: 100%;
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.feature::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 3px;
|
||||
background: linear-gradient(90deg, var(--ifm-color-primary), var(--ifm-color-primary-dark));
|
||||
transform: scaleX(0);
|
||||
transform-origin: left;
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.feature:hover::before {
|
||||
transform: scaleX(1);
|
||||
}
|
||||
|
||||
.feature:hover {
|
||||
box-shadow: 0 12px 24px rgba(0, 0, 0, 0.12);
|
||||
transform: translateY(-4px);
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.feature,
|
||||
.featureSvg,
|
||||
.feature:hover,
|
||||
.feature:hover .featureSvg {
|
||||
transition: none;
|
||||
transform: none;
|
||||
}
|
||||
}
|
||||
71
docs/src/components/HomepageFeatures.tsx
Normal file
71
docs/src/components/HomepageFeatures.tsx
Normal file
@@ -0,0 +1,71 @@
|
||||
import Heading from '@theme/Heading';
|
||||
import styles from './HomepageFeatures.module.css';
|
||||
|
||||
type FeatureItem = {
|
||||
title: string;
|
||||
Svg: React.ComponentType<React.ComponentProps<'svg'>>;
|
||||
description: JSX.Element;
|
||||
};
|
||||
|
||||
const FeatureList: FeatureItem[] = [
|
||||
{
|
||||
title: 'Easy to Use',
|
||||
Svg: require('@site/static/img/undraw_docusaurus_mountain.svg').default,
|
||||
description: (
|
||||
<>
|
||||
Install and configure Claude Code Router in minutes with our simple CLI.
|
||||
Start routing your Claude Code requests to any LLM provider instantly.
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: 'Flexible Routing',
|
||||
Svg: require('@site/static/img/undraw_docusaurus_tree.svg').default,
|
||||
description: (
|
||||
<>
|
||||
Configure custom routing logic based on project, context length, or task type.
|
||||
Built-in scenarios for background tasks, thinking mode, web search, and more.
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: 'Provider Agnostic',
|
||||
Svg: require('@site/static/img/undraw_docusaurus_react.svg').default,
|
||||
description: (
|
||||
<>
|
||||
Support for multiple LLM providers including DeepSeek, Gemini, Groq, and OpenRouter.
|
||||
Easy to extend with custom transformers for new providers.
|
||||
</>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
function Feature({title, Svg, description}: FeatureItem) {
|
||||
return (
|
||||
<div className={styles.feature}>
|
||||
<div className="text--center">
|
||||
<Svg className={styles.featureSvg} role="img" />
|
||||
</div>
|
||||
<div className="text--center padding-horiz--md">
|
||||
<Heading as="h3">{title}</Heading>
|
||||
<p>{description}</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function HomepageFeatures(): JSX.Element {
|
||||
return (
|
||||
<section className={styles.features}>
|
||||
<div className="container">
|
||||
<div className="row">
|
||||
{FeatureList.map((props, idx) => (
|
||||
<div key={idx} className="col col--4">
|
||||
<Feature {...props} />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
253
docs/src/css/custom.css
Normal file
253
docs/src/css/custom.css
Normal file
@@ -0,0 +1,253 @@
|
||||
/**
|
||||
* Any CSS included here will be global. The classic template
|
||||
* bundles Infima by default. Infima is a CSS framework designed to
|
||||
* work well for content-centric websites.
|
||||
*/
|
||||
|
||||
/* Tailwind CSS directives */
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
/* You can override the default Infima variables here. */
|
||||
:root {
|
||||
--ifm-color-primary: #CC7C5E;
|
||||
--ifm-color-primary-dark: #BC5C3E;
|
||||
--ifm-color-primary-darker: #964630;
|
||||
--ifm-color-primary-darkest: #7A3B2C;
|
||||
--ifm-color-primary-light: #F28B68;
|
||||
--ifm-color-primary-lighter: #F7AC92;
|
||||
--ifm-color-primary-lightest: #FEF6F3;
|
||||
--ifm-code-font-size: 95%;
|
||||
--docusaurus-highlighted-code-line-bg: rgba(204, 124, 94, 0.1);
|
||||
|
||||
/* Custom animations */
|
||||
--animation-duration-slow: 0.6s;
|
||||
--animation-duration-normal: 0.3s;
|
||||
--animation-duration-fast: 0.15s;
|
||||
}
|
||||
|
||||
/* Custom styles */
|
||||
.hero {
|
||||
padding: 4rem 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.hero__title {
|
||||
font-size: 3rem;
|
||||
font-weight: 700;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.hero__subtitle {
|
||||
font-size: 1.5rem;
|
||||
color: var(--ifm-color-emphasis-600);
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.features {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 2rem;
|
||||
margin-top: 3rem;
|
||||
}
|
||||
|
||||
.feature {
|
||||
padding: 1.5rem;
|
||||
border-radius: 8px;
|
||||
background: var(--ifm-background-surface-color);
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.feature__title {
|
||||
font-size: 1.25rem;
|
||||
font-weight: 600;
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
.feature__text {
|
||||
color: var(--ifm-color-emphasis-600);
|
||||
}
|
||||
|
||||
/* Smooth scroll behavior */
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
/* Custom scrollbar for webkit browsers */
|
||||
::-webkit-scrollbar {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: var(--ifm-background-surface-color);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: var(--ifm-color-primary);
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: var(--ifm-color-primary-dark);
|
||||
}
|
||||
|
||||
/* Enhanced animations */
|
||||
@keyframes fadeInUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(20px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slideInLeft {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateX(-30px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes scaleIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: scale(0.9);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
.animate-fade-in-up {
|
||||
animation: fadeInUp var(--animation-duration-slow) ease-out forwards;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.animate-fade-in {
|
||||
animation: fadeIn var(--animation-duration-slow) ease-out forwards;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.animate-slide-in-left {
|
||||
animation: slideInLeft var(--animation-duration-slow) ease-out forwards;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.animate-scale-in {
|
||||
animation: scaleIn var(--animation-duration-slow) ease-out forwards;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
/* Hover effects for cards */
|
||||
.hover-lift {
|
||||
transition: transform var(--animation-duration-normal) ease,
|
||||
box-shadow var(--animation-duration-normal) ease;
|
||||
}
|
||||
|
||||
.hover-lift:hover {
|
||||
transform: translateY(-4px);
|
||||
box-shadow: 0 12px 24px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
/* Gradient text */
|
||||
.gradient-text {
|
||||
background: linear-gradient(135deg, var(--ifm-color-primary) 0%, var(--ifm-color-primary-dark) 100%);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
}
|
||||
|
||||
/* Glass morphism effect */
|
||||
.glass {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
backdrop-filter: blur(10px);
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
/* Focus styles for accessibility */
|
||||
:focus-visible {
|
||||
outline: 2px solid var(--ifm-color-primary);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
/* Button hover effects */
|
||||
button,
|
||||
a {
|
||||
transition: all var(--animation-duration-fast) ease;
|
||||
}
|
||||
|
||||
/* Prevent navbar items from wrapping */
|
||||
.navbar__item,
|
||||
.navbar__link {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* Ensure navbar links with icons stay on same line */
|
||||
.navbar__link {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
.dropdown > .navbar__link:after{
|
||||
top: 4px;
|
||||
}
|
||||
|
||||
/* Prevent footer links from wrapping */
|
||||
.footer__link-item {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.25rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* Responsive improvements */
|
||||
@media (max-width: 996px) {
|
||||
.features {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.features {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.hero__title {
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
/* Reduce animation on mobile for better performance */
|
||||
.animate-fade-in-up,
|
||||
.animate-fade-in,
|
||||
.animate-slide-in-left,
|
||||
.animate-scale-in {
|
||||
animation-duration: 0.3s;
|
||||
}
|
||||
}
|
||||
|
||||
/* Print styles */
|
||||
@media print {
|
||||
.hero,
|
||||
.features {
|
||||
page-break-inside: avoid;
|
||||
}
|
||||
}
|
||||
674
docs/src/pages/index.tsx
Normal file
674
docs/src/pages/index.tsx
Normal file
@@ -0,0 +1,674 @@
|
||||
import Link from '@docusaurus/Link';
|
||||
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
|
||||
import Layout from '@theme/Layout';
|
||||
import Heading from '@theme/Heading';
|
||||
|
||||
function HomepageHeader() {
|
||||
const {siteConfig, i18n} = useDocusaurusContext();
|
||||
const currentLocale = i18n.currentLocale;
|
||||
|
||||
const content = {
|
||||
en: {
|
||||
title: 'Route Claude Code',
|
||||
highlight: 'to Any LLM',
|
||||
subtitle: 'Use Claude Code without an Anthropic account. Connect to DeepSeek, Gemini, Groq, and more.',
|
||||
getStarted: 'Get Started',
|
||||
github: 'View on GitHub',
|
||||
},
|
||||
'zh-CN': {
|
||||
title: '将 Claude Code',
|
||||
highlight: '路由到任何 LLM',
|
||||
subtitle: '无需 Anthropic 账户即可使用 Claude Code。支持连接 DeepSeek、Gemini、Groq 等提供商。',
|
||||
getStarted: '开始使用',
|
||||
github: '查看 GitHub',
|
||||
}
|
||||
};
|
||||
|
||||
const t = content[currentLocale as keyof typeof content] || content.en;
|
||||
|
||||
return (
|
||||
<header className="relative min-h-[90vh] flex items-center justify-center overflow-hidden bg-gradient-to-b from-gray-50 to-white">
|
||||
{/* Background Elements */}
|
||||
<div
|
||||
className="absolute inset-0"
|
||||
style={{
|
||||
backgroundImage: `
|
||||
linear-gradient(rgba(204, 124, 94, 0.03) 1px, transparent 1px),
|
||||
linear-gradient(90deg, rgba(204, 124, 94, 0.03) 1px, transparent 1px)
|
||||
`,
|
||||
backgroundSize: '50px 50px'
|
||||
}}
|
||||
></div>
|
||||
|
||||
{/* Hero Content */}
|
||||
<div className="relative z-10 container mx-auto px-4 py-20">
|
||||
<div className="max-w-4xl mx-auto text-center">
|
||||
{/* Badge */}
|
||||
<div className="animate-fade-in-up inline-flex items-center gap-2 px-4 py-2 bg-primary text-white rounded-full text-sm font-semibold mb-8">
|
||||
<span className="animate-pulse">●</span>
|
||||
<span>{currentLocale === 'zh-CN' ? '开源免费' : 'Open Source'}</span>
|
||||
</div>
|
||||
|
||||
{/* Title */}
|
||||
<Heading
|
||||
as="h1"
|
||||
className="text-5xl sm:text-6xl md:text-7xl lg:text-8xl font-extrabold mb-6 leading-tight animate-fade-in-up"
|
||||
style={{ animationDelay: '0.1s' }}
|
||||
>
|
||||
<span className="text-gray-900">{t.title}</span>
|
||||
<br />
|
||||
<span className="text-transparent bg-clip-text bg-gradient-to-r from-primary to-primary/70">
|
||||
{t.highlight}
|
||||
</span>
|
||||
</Heading>
|
||||
|
||||
{/* Subtitle */}
|
||||
<p
|
||||
className="text-lg sm:text-xl md:text-2xl text-gray-600 mb-10 leading-relaxed max-w-3xl mx-auto animate-fade-in-up"
|
||||
style={{ animationDelay: '0.2s' }}
|
||||
>
|
||||
{t.subtitle}
|
||||
</p>
|
||||
|
||||
{/* CTA Buttons */}
|
||||
<div
|
||||
className="flex flex-col sm:flex-row gap-4 justify-center items-center mb-12 animate-fade-in-up"
|
||||
style={{ animationDelay: '0.3s' }}
|
||||
>
|
||||
<Link
|
||||
className="px-6 sm:px-8 py-3 sm:py-4 bg-primary text-white hover:text-white rounded-lg text-base sm:text-lg font-semibold transition-all duration-300 shadow-lg hover:shadow-xl hover:scale-105"
|
||||
to={currentLocale === 'zh-CN' ? '/zh-CN/docs/intro' : '/docs/intro'}
|
||||
>
|
||||
{t.getStarted}
|
||||
</Link>
|
||||
<Link
|
||||
className="px-6 sm:px-8 py-3 sm:py-4 bg-white hover:bg-gray-50 text-gray-900 border border-gray-300 rounded-lg text-base sm:text-lg font-semibold transition-all duration-300 hover:border-primary hover:scale-105"
|
||||
to="https://github.com/musistudio/claude-code-router"
|
||||
>
|
||||
{t.github}
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
{/* Install Command */}
|
||||
<div
|
||||
className="animate-fade-in-up max-w-3xl mx-auto mt-16"
|
||||
style={{ animationDelay: '0.4s' }}
|
||||
>
|
||||
<div
|
||||
className="rounded-xl overflow-hidden"
|
||||
style={{
|
||||
background: 'linear-gradient(145deg, #1e1e1e 0%, #0d0d0d 100%)',
|
||||
boxShadow: '0 25px 50px -12px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(255, 255, 255, 0.1)',
|
||||
}}
|
||||
>
|
||||
{/* Terminal Header */}
|
||||
<div
|
||||
className="px-5 py-3 flex items-center justify-between"
|
||||
style={{
|
||||
background: 'linear-gradient(180deg, #2a2a2a 0%, #1f1f1f 100%)',
|
||||
borderBottom: '1px solid rgba(255, 255, 255, 0.1)',
|
||||
}}
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="flex gap-2">
|
||||
<div className="w-3 h-3 rounded-full bg-red-500 hover:bg-red-400 transition-colors"></div>
|
||||
<div className="w-3 h-3 rounded-full bg-yellow-500 hover:bg-yellow-400 transition-colors"></div>
|
||||
<div className="w-3 h-3 rounded-full bg-green-500 hover:bg-green-400 transition-colors"></div>
|
||||
</div>
|
||||
<span className="ml-4 text-xs text-gray-400 font-mono flex items-center gap-2">
|
||||
<svg className="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fillRule="evenodd" d="M2 5a2 2 0 012-2h12a2 2 0 012 2v10a2 2 0 01-2 2H4a2 2 0 01-2-2V5zm3.293 1.293a1 1 0 011.414 0l3 3a1 1 0 010 1.414l-3 3a1 1 0 01-1.414-1.414L7.586 10 5.293 7.707a1 1 0 010-1.414zM11 12a1 1 0 100 2h3a1 1 0 100-2h-3z" clipRule="evenodd" />
|
||||
</svg>
|
||||
terminal
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Copy Button */}
|
||||
<button
|
||||
onClick={() => navigator.clipboard.writeText('npm install -g @musistudio/claude-code-router-cli')}
|
||||
className="flex items-center gap-2 px-3 py-1.5 rounded-lg text-xs font-mono transition-all duration-200 hover:bg-white/10"
|
||||
style={{ color: '#9ca3af' }}
|
||||
title="Copy to clipboard"
|
||||
>
|
||||
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" />
|
||||
</svg>
|
||||
<span>Copy</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Terminal Body */}
|
||||
<div className="p-8" style={{ background: '#0d0d0d' }}>
|
||||
<div className="font-mono text-base md:text-lg leading-relaxed text-left">
|
||||
{/* Prompt */}
|
||||
<div className="flex items-start gap-3">
|
||||
<span style={{ color: '#22c55e', fontWeight: '600' }}>$</span>
|
||||
<span className="flex-1">
|
||||
<span style={{ color: '#60a5fa' }}>npm</span>
|
||||
<span style={{ color: '#f97583', marginLeft: '0.5rem' }}>install</span>
|
||||
<span style={{ color: '#fbbf24', marginLeft: '0.5rem' }}>-g</span>
|
||||
<span style={{ color: '#e5e7eb', marginLeft: '0.5rem' }}>
|
||||
@musistudio/claude-code-router-cli
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Scroll Indicator */}
|
||||
<div className="absolute bottom-8 left-1/2 -translate-x-1/2 animate-bounce">
|
||||
<svg className="w-6 h-6 text-primary" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 14l-7 7m0 0l-7-7m7 7V3" />
|
||||
</svg>
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
}
|
||||
|
||||
function FeatureSection() {
|
||||
const {i18n} = useDocusaurusContext();
|
||||
const currentLocale = i18n.currentLocale;
|
||||
|
||||
const content = {
|
||||
en: {
|
||||
title: 'Why Claude Code Router?',
|
||||
features: [
|
||||
{
|
||||
emoji: '⚡',
|
||||
title: 'Lightning Fast',
|
||||
description: 'Get started in minutes with just one command. No complicated configuration required.'
|
||||
},
|
||||
{
|
||||
emoji: '🎯',
|
||||
title: 'Smart Routing',
|
||||
description: 'Automatically route requests to the best model based on context length, task type, and custom rules.'
|
||||
},
|
||||
{
|
||||
emoji: '🔌',
|
||||
title: 'Multi-Provider',
|
||||
description: 'Support for DeepSeek, Gemini, Groq, OpenRouter, and more. Easy to extend with custom transformers.'
|
||||
},
|
||||
{
|
||||
emoji: '💰',
|
||||
title: 'Cost Effective',
|
||||
description: 'Use more affordable models for routine tasks while reserving Claude for complex scenarios.'
|
||||
},
|
||||
{
|
||||
emoji: '🛠️',
|
||||
title: 'Agent System',
|
||||
description: 'Extendable agent architecture for custom tools and workflows. Built-in support for image tasks.'
|
||||
},
|
||||
{
|
||||
emoji: '🔧',
|
||||
title: 'Highly Customizable',
|
||||
description: 'Configure routing per project, set up transformers, and fine-tune every aspect of your workflow.'
|
||||
}
|
||||
]
|
||||
},
|
||||
'zh-CN': {
|
||||
title: '为什么选择 Claude Code Router?',
|
||||
features: [
|
||||
{
|
||||
emoji: '⚡',
|
||||
title: '快速上手',
|
||||
description: '只需一条命令即可开始使用,无需复杂配置。'
|
||||
},
|
||||
{
|
||||
emoji: '🎯',
|
||||
title: '智能路由',
|
||||
description: '基于上下文长度、任务类型和自定义规则,自动将请求路由到最佳模型。'
|
||||
},
|
||||
{
|
||||
emoji: '🔌',
|
||||
title: '多提供商支持',
|
||||
description: '支持 DeepSeek、Gemini、Groq、OpenRouter 等多个提供商,易于扩展。'
|
||||
},
|
||||
{
|
||||
emoji: '💰',
|
||||
title: '节省成本',
|
||||
description: '常规任务使用更经济的模型,复杂场景再使用 Claude。'
|
||||
},
|
||||
{
|
||||
emoji: '🛠️',
|
||||
title: 'Agent 系统',
|
||||
description: '可扩展的 agent 架构,支持自定义工具和工作流。内置图像任务支持。'
|
||||
},
|
||||
{
|
||||
emoji: '🔧',
|
||||
title: '高度可定制',
|
||||
description: '按项目配置路由、设置转换器,微调工作流的每个细节。'
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
const t = content[currentLocale as keyof typeof content] || content.en;
|
||||
|
||||
return (
|
||||
<section className="py-16 sm:py-24 bg-white">
|
||||
<div className="container mx-auto px-4">
|
||||
<div className="text-center mb-12 sm:mb-16">
|
||||
<Heading as="h2" className="text-3xl sm:text-4xl md:text-5xl font-bold text-gray-900 mb-4">
|
||||
{t.title}
|
||||
</Heading>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 sm:gap-8 max-w-7xl mx-auto">
|
||||
{t.features.map((feature, idx) => (
|
||||
<div
|
||||
key={idx}
|
||||
className="group p-6 sm:p-8 bg-white rounded-2xl border border-gray-200 hover:border-primary transition-all duration-300 hover:shadow-2xl hover:-translate-y-2"
|
||||
style={{ animationDelay: `${idx * 0.1}s` }}
|
||||
>
|
||||
<div className="text-4xl sm:text-5xl mb-4">{feature.emoji}</div>
|
||||
<Heading as="h3" className="text-lg sm:text-xl font-bold text-gray-900 mb-3">
|
||||
{feature.title}
|
||||
</Heading>
|
||||
<p className="text-gray-600 leading-relaxed text-sm sm:text-base">
|
||||
{feature.description}
|
||||
</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
function CodeDemo() {
|
||||
const {i18n} = useDocusaurusContext();
|
||||
const currentLocale = i18n.currentLocale;
|
||||
|
||||
const content = {
|
||||
en: {
|
||||
title: 'Simple Configuration',
|
||||
subtitle: 'Configure your providers and routing logic with a single JSON file.'
|
||||
},
|
||||
'zh-CN': {
|
||||
title: '简单配置',
|
||||
subtitle: '使用单个 JSON 文件配置提供商和路由逻辑。'
|
||||
}
|
||||
};
|
||||
|
||||
const t = content[currentLocale as keyof typeof content] || content.en;
|
||||
|
||||
return (
|
||||
<section className="py-16 sm:py-24 bg-gray-50">
|
||||
<div className="container mx-auto px-4">
|
||||
<div className="text-center mb-12 sm:mb-16">
|
||||
<Heading as="h2" className="text-3xl sm:text-4xl md:text-5xl font-bold text-gray-900 mb-4">
|
||||
{t.title}
|
||||
</Heading>
|
||||
<p className="text-lg sm:text-xl text-gray-600 max-w-2xl mx-auto">
|
||||
{t.subtitle}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="max-w-4xl mx-auto">
|
||||
<div
|
||||
className="rounded-2xl overflow-hidden shadow-2xl"
|
||||
style={{
|
||||
background: '#1a1a1a',
|
||||
border: '2px solid #374151'
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className="px-6 py-4 flex items-center gap-2"
|
||||
style={{ background: '#2d2d2d', borderBottom: '1px solid #374151' }}
|
||||
>
|
||||
<div className="w-3 h-3 rounded-full bg-red-500"></div>
|
||||
<div className="w-3 h-3 rounded-full bg-yellow-500"></div>
|
||||
<div className="w-3 h-3 rounded-full bg-green-500"></div>
|
||||
<span className="ml-4 text-sm text-gray-300 font-mono">config.json</span>
|
||||
</div>
|
||||
<pre className="p-8 overflow-x-auto text-sm md:text-base" style={{ background: '#1a1a1a' }}>
|
||||
<code className="font-mono" style={{ lineHeight: '1.6' }}>
|
||||
<span style={{ color: '#f97583' }}>{'{'}</span>
|
||||
<span style={{ color: '#e5e7eb' }}>
|
||||
{'\n '}
|
||||
<span style={{ color: '#79c0ff' }}>"Providers"</span>
|
||||
<span style={{ color: '#f97583' }}>: </span>
|
||||
<span style={{ color: '#f97583' }}>[</span>
|
||||
{'\n '}
|
||||
<span style={{ color: '#f97583' }}>{'{'}</span>
|
||||
{'\n '}
|
||||
<span style={{ color: '#79c0ff' }}>"NAME"</span>
|
||||
<span style={{ color: '#f97583' }}>: </span>
|
||||
<span style={{ color: '#a5d6ff' }}>"deepseek"</span>
|
||||
<span style={{ color: '#f97583' }}>,</span>
|
||||
{'\n '}
|
||||
<span style={{ color: '#79c0ff' }}>"HOST"</span>
|
||||
<span style={{ color: '#f97583' }}>: </span>
|
||||
<span style={{ color: '#a5d6ff' }}>"https://api.deepseek.com"</span>
|
||||
<span style={{ color: '#f97583' }}>,</span>
|
||||
{'\n '}
|
||||
<span style={{ color: '#79c0ff' }}>"APIKEY"</span>
|
||||
<span style={{ color: '#f97583' }}>: </span>
|
||||
<span style={{ color: '#a5d6ff' }}>"your-api-key"</span>
|
||||
<span style={{ color: '#f97583' }}>,</span>
|
||||
{'\n '}
|
||||
<span style={{ color: '#79c0ff' }}>"MODELS"</span>
|
||||
<span style={{ color: '#f97583' }}>: </span>
|
||||
<span style={{ color: '#f97583' }}>[</span>
|
||||
<span style={{ color: '#a5d6ff' }}>"deepseek-chat"</span>
|
||||
<span style={{ color: '#f97583' }}>, </span>
|
||||
<span style={{ color: '#a5d6ff' }}>"deepseek-coder"</span>
|
||||
<span style={{ color: '#f97583' }}>]</span>
|
||||
{'\n '}
|
||||
<span style={{ color: '#f97583' }}>{'}'}</span>
|
||||
<span style={{ color: '#f97583' }}>,</span>
|
||||
{'\n '}
|
||||
<span style={{ color: '#f97583' }}>{'{'}</span>
|
||||
{'\n '}
|
||||
<span style={{ color: '#79c0ff' }}>"NAME"</span>
|
||||
<span style={{ color: '#f97583' }}>: </span>
|
||||
<span style={{ color: '#a5d6ff' }}>"groq"</span>
|
||||
<span style={{ color: '#f97583' }}>,</span>
|
||||
{'\n '}
|
||||
<span style={{ color: '#79c0ff' }}>"HOST"</span>
|
||||
<span style={{ color: '#f97583' }}>: </span>
|
||||
<span style={{ color: '#a5d6ff' }}>"https://api.groq.com/openai/v1"</span>
|
||||
<span style={{ color: '#f97583' }}>,</span>
|
||||
{'\n '}
|
||||
<span style={{ color: '#79c0ff' }}>"APIKEY"</span>
|
||||
<span style={{ color: '#f97583' }}>: </span>
|
||||
<span style={{ color: '#a5d6ff' }}>"your-groq-key"</span>
|
||||
<span style={{ color: '#f97583' }}>,</span>
|
||||
{'\n '}
|
||||
<span style={{ color: '#79c0ff' }}>"MODELS"</span>
|
||||
<span style={{ color: '#f97583' }}>: </span>
|
||||
<span style={{ color: '#f97583' }}>[</span>
|
||||
<span style={{ color: '#a5d6ff' }}>"llama-3.3-70b-versatile"</span>
|
||||
<span style={{ color: '#f97583' }}>]</span>
|
||||
{'\n '}
|
||||
<span style={{ color: '#f97583' }}>{'}'}</span>
|
||||
{'\n '}
|
||||
<span style={{ color: '#f97583' }}>]</span>
|
||||
<span style={{ color: '#f97583' }}>,</span>
|
||||
{'\n '}
|
||||
<span style={{ color: '#79c0ff' }}>"Router"</span>
|
||||
<span style={{ color: '#f97583' }}>: </span>
|
||||
<span style={{ color: '#f97583' }}>{'{'}</span>
|
||||
{'\n '}
|
||||
<span style={{ color: '#79c0ff' }}>"default"</span>
|
||||
<span style={{ color: '#f97583' }}>: </span>
|
||||
<span style={{ color: '#a5d6ff' }}>"deepseek,deepseek-chat"</span>
|
||||
<span style={{ color: '#f97583' }}>,</span>
|
||||
{'\n '}
|
||||
<span style={{ color: '#79c0ff' }}>"background"</span>
|
||||
<span style={{ color: '#f97583' }}>: </span>
|
||||
<span style={{ color: '#a5d6ff' }}>"groq,llama-3.3-70b-versatile"</span>
|
||||
{'\n '}
|
||||
<span style={{ color: '#f97583' }}>{'}'}</span>
|
||||
{'\n'}
|
||||
<span style={{ color: '#f97583' }}>{'}'}</span>
|
||||
</span>
|
||||
</code>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
function UseCases() {
|
||||
const {i18n} = useDocusaurusContext();
|
||||
const currentLocale = i18n.currentLocale;
|
||||
|
||||
const content = {
|
||||
en: {
|
||||
title: 'Perfect For',
|
||||
subtitle: 'See how Claude Code Router fits your workflow',
|
||||
cases: [
|
||||
{
|
||||
icon: '💰',
|
||||
title: 'Cost-Conscious Developers',
|
||||
description: 'Reduce API costs by 10x while maintaining quality for most tasks'
|
||||
},
|
||||
{
|
||||
icon: '🔒',
|
||||
title: 'Privacy-Focused Teams',
|
||||
description: 'Keep code local with self-hosted models while using Claude when needed'
|
||||
},
|
||||
{
|
||||
icon: '🔄',
|
||||
title: 'Multi-Model Workflows',
|
||||
description: 'Use different models for different tasks without switching tools'
|
||||
},
|
||||
{
|
||||
icon: '⚡',
|
||||
title: 'Claude Code Power Users',
|
||||
description: 'Extend Claude Code with custom providers and routing strategies'
|
||||
}
|
||||
]
|
||||
},
|
||||
'zh-CN': {
|
||||
title: '适用场景',
|
||||
subtitle: '看看 Claude Code Router 如何融入您的工作流程',
|
||||
cases: [
|
||||
{
|
||||
icon: '💰',
|
||||
title: '注重成本的开发者',
|
||||
description: '在大多数任务上保持质量的同时,将 API 成本降低 10 倍'
|
||||
},
|
||||
{
|
||||
icon: '🔒',
|
||||
title: '注重隐私的团队',
|
||||
description: '使用自托管模型保持代码本地化,需要时再使用 Claude'
|
||||
},
|
||||
{
|
||||
icon: '🔄',
|
||||
title: '多模型工作流',
|
||||
description: '为不同任务使用不同模型,无需切换工具'
|
||||
},
|
||||
{
|
||||
icon: '⚡',
|
||||
title: 'Claude Code 高级用户',
|
||||
description: '使用自定义提供商和路由策略扩展 Claude Code'
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
const t = content[currentLocale as keyof typeof content] || content.en;
|
||||
|
||||
return (
|
||||
<section className="py-16 sm:py-24 bg-gradient-to-b from-white to-gray-50">
|
||||
<div className="container mx-auto px-4">
|
||||
<div className="text-center mb-12 sm:mb-16">
|
||||
<Heading as="h2" className="text-3xl sm:text-4xl md:text-5xl font-bold text-gray-900 mb-4">
|
||||
{t.title}
|
||||
</Heading>
|
||||
<p className="text-lg sm:text-xl text-gray-600 max-w-2xl mx-auto">
|
||||
{t.subtitle}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6 sm:gap-8 max-w-5xl mx-auto">
|
||||
{t.cases.map((useCase, idx) => (
|
||||
<div
|
||||
key={idx}
|
||||
className="group relative p-6 sm:p-8 bg-white rounded-2xl border-2 border-gray-100 hover:border-primary transition-all duration-300 hover:shadow-2xl hover:-translate-y-1 overflow-hidden"
|
||||
style={{ animationDelay: `${idx * 0.1}s` }}
|
||||
>
|
||||
{/* Background decoration */}
|
||||
<div
|
||||
className="absolute top-0 right-0 w-32 h-32 rounded-full opacity-5 group-hover:opacity-10 transition-opacity"
|
||||
style={{
|
||||
background: 'linear-gradient(135deg, #CC7C5E 0%, transparent 70%)',
|
||||
transform: 'translate(30%, -30%)'
|
||||
}}
|
||||
></div>
|
||||
|
||||
{/* Number badge */}
|
||||
<div className="absolute top-4 sm:top-6 right-4 sm:right-6 w-8 h-8 sm:w-10 sm:h-10 flex items-center justify-center rounded-full text-base sm:text-lg font-bold transition-all duration-300 group-hover:scale-110"
|
||||
style={{
|
||||
background: 'linear-gradient(135deg, #CC7C5E 0%, #BC5C3E 100%)',
|
||||
color: 'white',
|
||||
boxShadow: '0 4px 12px rgba(204, 124, 94, 0.3)'
|
||||
}}
|
||||
>
|
||||
{idx + 1}
|
||||
</div>
|
||||
|
||||
{/* Icon */}
|
||||
<div className="text-4xl sm:text-5xl mb-4 group-hover:scale-110 transition-transform duration-300">
|
||||
{useCase.icon}
|
||||
</div>
|
||||
|
||||
{/* Content */}
|
||||
<div>
|
||||
<Heading as="h3" className="text-lg sm:text-xl font-bold text-gray-900 mb-3 group-hover:text-primary transition-colors">
|
||||
{useCase.title}
|
||||
</Heading>
|
||||
<p className="text-gray-600 leading-relaxed text-sm sm:text-base">
|
||||
{useCase.description}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Hover accent line */}
|
||||
<div
|
||||
className="absolute bottom-0 left-0 h-1 bg-gradient-to-r from-primary to-primary/70 transition-all duration-300 group-hover:w-full"
|
||||
style={{ width: '0%' }}
|
||||
></div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
function CTASection() {
|
||||
const {i18n} = useDocusaurusContext();
|
||||
const currentLocale = i18n.currentLocale;
|
||||
|
||||
const content = {
|
||||
en: {
|
||||
title: 'Ready to Get Started?',
|
||||
subtitle: 'Join thousands of developers using Claude Code Router to build better software.',
|
||||
getStarted: 'Get Started',
|
||||
docs: 'Read the Docs',
|
||||
github: 'Star on GitHub',
|
||||
community: 'Join Community'
|
||||
},
|
||||
'zh-CN': {
|
||||
title: '准备开始了吗?',
|
||||
subtitle: '加入数千名使用 Claude Code Router 的开发者,构建更好的软件。',
|
||||
getStarted: '开始使用',
|
||||
docs: '阅读文档',
|
||||
github: '在 GitHub 上点赞',
|
||||
community: '加入社区'
|
||||
}
|
||||
};
|
||||
|
||||
const t = content[currentLocale as keyof typeof content] || content.en;
|
||||
|
||||
return (
|
||||
<section className="relative py-20 sm:py-32 overflow-hidden">
|
||||
{/* Animated background */}
|
||||
<div className="absolute inset-0">
|
||||
<div className="absolute inset-0 bg-gradient-to-br from-primary via-primary/90 to-primary/80"></div>
|
||||
{/* Pattern overlay */}
|
||||
<div
|
||||
className="absolute inset-0 opacity-10"
|
||||
style={{
|
||||
backgroundImage: `
|
||||
radial-gradient(circle at 25% 25%, white 1%, transparent 1%),
|
||||
radial-gradient(circle at 75% 75%, white 1%, transparent 1%)
|
||||
`,
|
||||
backgroundSize: '40px 40px'
|
||||
}}
|
||||
></div>
|
||||
{/* Floating orbs */}
|
||||
<div className="absolute top-20 left-10 w-64 h-64 bg-white/10 rounded-full blur-3xl animate-pulse"></div>
|
||||
<div className="absolute bottom-20 right-10 w-96 h-96 bg-white/5 rounded-full blur-3xl animate-pulse" style={{ animationDelay: '1s' }}></div>
|
||||
</div>
|
||||
|
||||
<div className="relative container mx-auto px-4">
|
||||
<div className="max-w-4xl mx-auto text-center">
|
||||
{/* Main title */}
|
||||
<Heading as="h2" className="text-4xl sm:text-5xl md:text-6xl font-bold text-white mb-6 leading-tight">
|
||||
{t.title}
|
||||
</Heading>
|
||||
|
||||
{/* Subtitle */}
|
||||
<p className="text-lg sm:text-xl md:text-2xl text-white/95 mb-10 sm:mb-12 max-w-3xl mx-auto leading-relaxed">
|
||||
{t.subtitle}
|
||||
</p>
|
||||
|
||||
{/* Primary CTA buttons */}
|
||||
<div className="flex flex-col sm:flex-row gap-4 justify-center mb-8 sm:mb-12">
|
||||
<Link
|
||||
className="group px-8 sm:px-10 py-4 sm:py-5 bg-white text-primary hover:bg-gray-50 rounded-xl text-base sm:text-lg font-bold transition-all duration-300 shadow-2xl hover:shadow-white/20 hover:scale-105 flex items-center justify-center gap-2"
|
||||
to={currentLocale === 'zh-CN' ? '/zh-CN/docs/intro' : '/docs/intro'}
|
||||
>
|
||||
{t.getStarted}
|
||||
<svg className="w-5 h-5 group-hover:translate-x-1 transition-transform" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 7l5 5m0 0l-5 5m5-5H6" />
|
||||
</svg>
|
||||
</Link>
|
||||
<Link
|
||||
className="px-8 sm:px-10 py-4 sm:py-5 bg-white/10 backdrop-blur-sm text-white border-2 border-white/30 hover:bg-primary hover:border-primary hover:text-white rounded-xl text-base sm:text-lg font-bold transition-all duration-300 hover:scale-105 flex items-center justify-center gap-2"
|
||||
to={currentLocale === 'zh-CN' ? '/zh-CN/docs' : '/docs'}
|
||||
>
|
||||
{t.docs}
|
||||
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253" />
|
||||
</svg>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
{/* Secondary links */}
|
||||
<div className="flex flex-col sm:flex-row gap-6 justify-center items-center text-white/80">
|
||||
<a
|
||||
href="https://github.com/musistudio/claude-code-router"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="flex items-center gap-2 hover:text-white transition-colors group"
|
||||
>
|
||||
<svg className="w-5 h-5 group-hover:scale-110 transition-transform" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path fillRule="evenodd" d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z" clipRule="evenodd" />
|
||||
</svg>
|
||||
<span className="text-sm font-medium">{t.github}</span>
|
||||
</a>
|
||||
|
||||
<div className="hidden sm:block w-px h-4 bg-white/30"></div>
|
||||
|
||||
<Link
|
||||
to={currentLocale === 'zh-CN' ? '/zh-CN/docs' : '/docs'}
|
||||
className="flex items-center gap-2 hover:text-white transition-colors group"
|
||||
>
|
||||
<svg className="w-5 h-5 group-hover:scale-110 transition-transform" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z" />
|
||||
</svg>
|
||||
<span className="text-sm font-medium">{t.community}</span>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
export default function Home(): JSX.Element {
|
||||
const {siteConfig} = useDocusaurusContext();
|
||||
return (
|
||||
<Layout
|
||||
title={`${siteConfig.title}`}
|
||||
description="Use Claude Code without an Anthropics account and route it to another LLM provider">
|
||||
<HomepageHeader />
|
||||
<main>
|
||||
<FeatureSection />
|
||||
<CodeDemo />
|
||||
<UseCases />
|
||||
<CTASection />
|
||||
</main>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
4
docs/static/img/ccr.svg
vendored
Normal file
4
docs/static/img/ccr.svg
vendored
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 726 KiB |
1
docs/static/img/docusaurus-social-card.jpg
vendored
Normal file
1
docs/static/img/docusaurus-social-card.jpg
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[Placeholder for social card image]
|
||||
1
docs/static/img/favicon.ico
vendored
Normal file
1
docs/static/img/favicon.ico
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[Placeholder for favicon]
|
||||
4
docs/static/img/logo.svg
vendored
Normal file
4
docs/static/img/logo.svg
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg width="100" height="100" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="100" height="100" rx="10" fill="#2e8555"/>
|
||||
<text x="50" y="65" text-anchor="middle" font-family="sans-serif" font-size="40" font-weight="bold" fill="white">CCR</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 279 B |
6
docs/static/img/undraw_docusaurus_mountain.svg
vendored
Normal file
6
docs/static/img/undraw_docusaurus_mountain.svg
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg width="500" height="500" viewBox="0 0 500 500" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="500" height="500" fill="#f8f9fa"/>
|
||||
<path d="M250 100 L400 350 L100 350 Z" fill="#2e8555" opacity="0.8"/>
|
||||
<circle cx="250" cy="150" r="30" fill="#25c2a0"/>
|
||||
<text x="250" y="400" text-anchor="middle" font-family="sans-serif" font-size="24" fill="#333">Easy to Use</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 385 B |
7
docs/static/img/undraw_docusaurus_react.svg
vendored
Normal file
7
docs/static/img/undraw_docusaurus_react.svg
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<svg width="500" height="500" viewBox="0 0 500 500" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="500" height="500" fill="#f8f9fa"/>
|
||||
<circle cx="200" cy="200" r="60" fill="#2e8555" opacity="0.6"/>
|
||||
<circle cx="300" cy="200" r="60" fill="#25c2a0" opacity="0.6"/>
|
||||
<circle cx="250" cy="300" r="60" fill="#21af90" opacity="0.6"/>
|
||||
<text x="250" y="420" text-anchor="middle" font-family="sans-serif" font-size="24" fill="#333">Provider Agnostic</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 465 B |
7
docs/static/img/undraw_docusaurus_tree.svg
vendored
Normal file
7
docs/static/img/undraw_docusaurus_tree.svg
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<svg width="500" height="500" viewBox="0 0 500 500" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="500" height="500" fill="#f8f9fa"/>
|
||||
<circle cx="250" cy="120" r="80" fill="#2e8555" opacity="0.6"/>
|
||||
<rect x="230" y="180" width="40" height="200" fill="#8B4513"/>
|
||||
<path d="M250 280 L350 350 L150 350 Z" fill="#2e8555" opacity="0.8"/>
|
||||
<text x="250" y="420" text-anchor="middle" font-family="sans-serif" font-size="24" fill="#333">Flexible Routing</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 469 B |
46
docs/tailwind.config.js
Normal file
46
docs/tailwind.config.js
Normal file
@@ -0,0 +1,46 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
content: [
|
||||
'./src/**/*.{js,jsx,ts,tsx}',
|
||||
],
|
||||
darkMode: 'class',
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
primary: {
|
||||
DEFAULT: '#CC7C5E',
|
||||
50: '#FEF6F3',
|
||||
100: '#FDE8E0',
|
||||
200: '#FBD2C1',
|
||||
300: '#F7AC92',
|
||||
400: '#F28B68',
|
||||
500: '#CC7C5E',
|
||||
600: '#BC5C3E',
|
||||
700: '#964630',
|
||||
800: '#7A3B2C',
|
||||
900: '#643528',
|
||||
},
|
||||
},
|
||||
animation: {
|
||||
'fade-in-up': 'fadeInUp 0.6s ease-out',
|
||||
'fade-in': 'fadeIn 0.6s ease-out',
|
||||
'slide-in': 'slideIn 0.6s ease-out',
|
||||
},
|
||||
keyframes: {
|
||||
fadeInUp: {
|
||||
'0%': { opacity: '0', transform: 'translateY(20px)' },
|
||||
'100%': { opacity: '1', transform: 'translateY(0)' },
|
||||
},
|
||||
fadeIn: {
|
||||
'0%': { opacity: '0' },
|
||||
'100%': { opacity: '1' },
|
||||
},
|
||||
slideIn: {
|
||||
'0%': { transform: 'translateX(-100%)' },
|
||||
'100%': { transform: 'translateX(0)' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [],
|
||||
}
|
||||
22
docs/tsconfig.json
Normal file
22
docs/tsconfig.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"extends": "../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"jsx": "react",
|
||||
"jsxFactory": "React.createElement",
|
||||
"jsxFragmentFactory": "React.Fragment",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "Bundler",
|
||||
"target": "ES2020",
|
||||
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"noEmit": true
|
||||
},
|
||||
"include": ["src", "docs"],
|
||||
"exclude": ["node_modules", "build"]
|
||||
}
|
||||
@@ -8,12 +8,15 @@
|
||||
"build:cli": "pnpm --filter @CCR/cli build",
|
||||
"build:server": "pnpm --filter @CCR/server build",
|
||||
"build:ui": "pnpm --filter @CCR/ui build",
|
||||
"build:docs": "pnpm --filter claude-code-router-docs build",
|
||||
"release": "pnpm build && bash scripts/release.sh all",
|
||||
"release:npm": "bash scripts/release.sh npm",
|
||||
"release:docker": "bash scripts/release.sh docker",
|
||||
"dev:cli": "pnpm --filter @CCR/cli dev",
|
||||
"dev:server": "pnpm --filter @CCR/server dev",
|
||||
"dev:ui": "pnpm --filter @CCR/ui dev"
|
||||
"dev:ui": "pnpm --filter @CCR/ui dev",
|
||||
"dev:docs": "pnpm --filter claude-code-router-docs start",
|
||||
"serve:docs": "pnpm --filter claude-code-router-docs serve"
|
||||
},
|
||||
"bin": {
|
||||
"ccr": "dist/cli.js"
|
||||
|
||||
10366
pnpm-lock.yaml
generated
10366
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -1,2 +1,3 @@
|
||||
packages:
|
||||
- 'packages/*'
|
||||
- 'docs'
|
||||
|
||||
Reference in New Issue
Block a user