claude-code-router-config 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +27 -0
- package/LICENSE +30 -0
- package/README.md +148 -0
- package/config/config.json +67 -0
- package/config/intent-router.js +108 -0
- package/docs/FULL_DOCUMENTATION.md +489 -0
- package/docs/FULL_DOCUMENTATION_EN.md +505 -0
- package/docs/README_EN.md +146 -0
- package/docs/SETUP_PROMPT.md +299 -0
- package/docs/SETUP_PROMPT_EN.md +317 -0
- package/install.js +160 -0
- package/install.sh +73 -0
- package/package.json +59 -0
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
# Claude Code Router - Kurulum Prompt'u
|
|
2
|
+
|
|
3
|
+
Bu prompt'u başka bir makinede Claude Code Router kurmak için kullanabilirsin.
|
|
4
|
+
Kopyala ve Claude Code'a yapıştır.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## KURULUM PROMPT'U
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
Sen bir DevOps + LLM altyapı uzmanısın.
|
|
12
|
+
|
|
13
|
+
Görev: Claude Code Router'ı kur ve intent-based routing ile yapılandır.
|
|
14
|
+
|
|
15
|
+
Gereksinimler:
|
|
16
|
+
- pnpm kullan (npm değil)
|
|
17
|
+
- Model versiyonlarını sabitlemek yerine en güncel/önerilen modelleri kullan
|
|
18
|
+
- macOS/Linux ortamı
|
|
19
|
+
|
|
20
|
+
Kurulacak Provider'lar:
|
|
21
|
+
1. OpenAI (gpt-4o, o1) - Coding, debugging
|
|
22
|
+
2. Anthropic Claude - Deep reasoning, analysis
|
|
23
|
+
3. Google Gemini - Hızlı cevaplar, uzun context
|
|
24
|
+
4. Alibaba Qwen (DashScope) - Ucuz, basit işler
|
|
25
|
+
5. Zhipu GLM (Z.ai) - Çok dilli, çeviri
|
|
26
|
+
6. OpenRouter - Fallback
|
|
27
|
+
|
|
28
|
+
Intent-Based Routing Kuralları:
|
|
29
|
+
- Kod yazma/debug → OpenAI (gpt-4o)
|
|
30
|
+
- Mimari/analiz/neden → Anthropic Claude
|
|
31
|
+
- Hızlı/özet/tldr → Gemini Flash
|
|
32
|
+
- Basit/liste/yardım → Qwen (ucuz)
|
|
33
|
+
- Çeviri/çok dilli → GLM
|
|
34
|
+
- Karmaşık algoritma → OpenAI (o1)
|
|
35
|
+
- Eşleşme yok → OpenAI (fallback)
|
|
36
|
+
|
|
37
|
+
Yapılacaklar:
|
|
38
|
+
1. pnpm ile @musistudio/claude-code-router kur
|
|
39
|
+
2. ~/.claude-code-router/config.json oluştur (tüm provider'lar)
|
|
40
|
+
3. ~/.claude-code-router/intent-router.js oluştur (routing logic)
|
|
41
|
+
4. ~/.zshrc için gerekli env var'ları göster
|
|
42
|
+
|
|
43
|
+
API Endpoint'leri:
|
|
44
|
+
- OpenAI: https://api.openai.com/v1/chat/completions
|
|
45
|
+
- Anthropic: https://api.anthropic.com/v1/messages (transformer: Anthropic)
|
|
46
|
+
- Gemini: https://generativelanguage.googleapis.com/v1beta/openai/chat/completions (transformer: gemini)
|
|
47
|
+
- Qwen: https://dashscope-intl.aliyuncs.com/compatible-mode/v1/chat/completions
|
|
48
|
+
- GLM: https://api.z.ai/api/paas/v4/chat/completions
|
|
49
|
+
- OpenRouter: https://openrouter.ai/api/v1/chat/completions (transformer: openrouter)
|
|
50
|
+
|
|
51
|
+
Router Ayarları:
|
|
52
|
+
- default: openai,gpt-4o
|
|
53
|
+
- background: qwen,qwen-turbo
|
|
54
|
+
- think: anthropic,claude-sonnet-4-latest
|
|
55
|
+
- longContext: gemini,gemini-2.5-flash
|
|
56
|
+
- longContextThreshold: 60000
|
|
57
|
+
|
|
58
|
+
Çıktı:
|
|
59
|
+
1. Kurulum komutları
|
|
60
|
+
2. config.json içeriği
|
|
61
|
+
3. intent-router.js içeriği
|
|
62
|
+
4. .zshrc eklemeleri
|
|
63
|
+
5. Başlatma ve test komutları
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## HIZLI KURULUM (Manuel)
|
|
69
|
+
|
|
70
|
+
Eğer prompt kullanmak istemiyorsan, aşağıdaki adımları manuel uygula:
|
|
71
|
+
|
|
72
|
+
### 1. Kurulum
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
pnpm add -g @musistudio/claude-code-router
|
|
76
|
+
mkdir -p ~/.claude-code-router
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### 2. config.json
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
cat > ~/.claude-code-router/config.json << 'EOF'
|
|
83
|
+
{
|
|
84
|
+
"LOG": true,
|
|
85
|
+
"LOG_LEVEL": "info",
|
|
86
|
+
"API_TIMEOUT_MS": 300000,
|
|
87
|
+
"CUSTOM_ROUTER_PATH": "$HOME/.claude-code-router/intent-router.js",
|
|
88
|
+
|
|
89
|
+
"Providers": [
|
|
90
|
+
{
|
|
91
|
+
"name": "openai",
|
|
92
|
+
"api_base_url": "https://api.openai.com/v1/chat/completions",
|
|
93
|
+
"api_key": "$OPENAI_API_KEY",
|
|
94
|
+
"models": ["gpt-4o", "gpt-4-turbo", "gpt-4o-mini", "o1", "o1-mini"],
|
|
95
|
+
"transformer": { "use": [] }
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
"name": "anthropic",
|
|
99
|
+
"api_base_url": "https://api.anthropic.com/v1/messages",
|
|
100
|
+
"api_key": "$ANTHROPIC_API_KEY",
|
|
101
|
+
"models": ["claude-sonnet-4-latest", "claude-3-5-sonnet-latest"],
|
|
102
|
+
"transformer": { "use": ["Anthropic"] }
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"name": "gemini",
|
|
106
|
+
"api_base_url": "https://generativelanguage.googleapis.com/v1beta/openai/chat/completions",
|
|
107
|
+
"api_key": "$GEMINI_API_KEY",
|
|
108
|
+
"models": ["gemini-2.5-flash", "gemini-2.5-pro", "gemini-2.0-flash"],
|
|
109
|
+
"transformer": { "use": ["gemini"] }
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"name": "qwen",
|
|
113
|
+
"api_base_url": "https://dashscope-intl.aliyuncs.com/compatible-mode/v1/chat/completions",
|
|
114
|
+
"api_key": "$QWEN_API_KEY",
|
|
115
|
+
"models": ["qwen-plus", "qwen-max", "qwen3-coder-plus", "qwen-turbo"],
|
|
116
|
+
"transformer": { "use": [] }
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
"name": "glm",
|
|
120
|
+
"api_base_url": "https://api.z.ai/api/paas/v4/chat/completions",
|
|
121
|
+
"api_key": "$GLM_API_KEY",
|
|
122
|
+
"models": ["glm-4.6", "glm-4.5", "glm-4-plus"],
|
|
123
|
+
"transformer": { "use": [] }
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
"name": "openrouter",
|
|
127
|
+
"api_base_url": "https://openrouter.ai/api/v1/chat/completions",
|
|
128
|
+
"api_key": "$OPENROUTER_API_KEY",
|
|
129
|
+
"models": [
|
|
130
|
+
"anthropic/claude-sonnet-4",
|
|
131
|
+
"deepseek/deepseek-chat",
|
|
132
|
+
"google/gemini-2.5-flash",
|
|
133
|
+
"meta-llama/llama-3.3-70b-instruct"
|
|
134
|
+
],
|
|
135
|
+
"transformer": { "use": ["openrouter"] }
|
|
136
|
+
}
|
|
137
|
+
],
|
|
138
|
+
|
|
139
|
+
"Router": {
|
|
140
|
+
"default": "openai,gpt-4o",
|
|
141
|
+
"background": "qwen,qwen-turbo",
|
|
142
|
+
"think": "anthropic,claude-sonnet-4-latest",
|
|
143
|
+
"longContext": "gemini,gemini-2.5-flash",
|
|
144
|
+
"longContextThreshold": 60000
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
EOF
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### 3. intent-router.js
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
cat > ~/.claude-code-router/intent-router.js << 'EOF'
|
|
154
|
+
const INTENTS = {
|
|
155
|
+
CODING: {
|
|
156
|
+
patterns: [
|
|
157
|
+
/\b(implement|refactor|debug|fix|write|code|function|class|method|bug|error|compile|syntax)\b/i,
|
|
158
|
+
/\b(typescript|javascript|python|rust|go|java|react|vue|angular|swift|kotlin)\b/i,
|
|
159
|
+
/\b(api|endpoint|database|query|migration|schema|test|unit test)\b/i,
|
|
160
|
+
/\b(codex|o1|reasoning)\b/i
|
|
161
|
+
],
|
|
162
|
+
route: "openai,gpt-4o"
|
|
163
|
+
},
|
|
164
|
+
REASONING: {
|
|
165
|
+
patterns: [
|
|
166
|
+
/\b(architect|design|analyze|plan|strategy|structure|system|trade-?off)\b/i,
|
|
167
|
+
/\b(why|explain|reason|understand|compare|evaluate|consider|review)\b/i,
|
|
168
|
+
/\b(decision|approach|best practice|pattern|principle|philosophy)\b/i
|
|
169
|
+
],
|
|
170
|
+
route: "anthropic,claude-sonnet-4-latest"
|
|
171
|
+
},
|
|
172
|
+
FAST: {
|
|
173
|
+
patterns: [
|
|
174
|
+
/\b(fast|quick|brief|short|summary|tldr|overview|hızlı)\b/i,
|
|
175
|
+
/\b(scan|check|verify|validate)\b/i
|
|
176
|
+
],
|
|
177
|
+
route: "gemini,gemini-2.5-flash"
|
|
178
|
+
},
|
|
179
|
+
SIMPLE: {
|
|
180
|
+
patterns: [
|
|
181
|
+
/\b(list|show|what is|simple|basic|help|how to|format)\b/i,
|
|
182
|
+
/\b(rename|move|delete|create file|mkdir|copy)\b/i,
|
|
183
|
+
/\b(ucuz|basit|kolay)\b/i
|
|
184
|
+
],
|
|
185
|
+
route: "qwen,qwen-plus"
|
|
186
|
+
},
|
|
187
|
+
MULTILINGUAL: {
|
|
188
|
+
patterns: [
|
|
189
|
+
/\b(translate|çevir|tercüme|chinese|türkçe|multilingual)\b/i,
|
|
190
|
+
/[\u4e00-\u9fff]/,
|
|
191
|
+
/[\u0600-\u06FF]/,
|
|
192
|
+
],
|
|
193
|
+
route: "glm,glm-4.6"
|
|
194
|
+
},
|
|
195
|
+
HEAVY_REASONING: {
|
|
196
|
+
patterns: [
|
|
197
|
+
/\b(complex algorithm|optimization|performance critical|system design)\b/i,
|
|
198
|
+
/\b(prove|mathematical|theorem|formal verification)\b/i
|
|
199
|
+
],
|
|
200
|
+
route: "openai,o1"
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
function extractContent(req) {
|
|
205
|
+
const messages = req.body?.messages || [];
|
|
206
|
+
return messages
|
|
207
|
+
.filter(m => m.role === "user" || m.role === "system")
|
|
208
|
+
.map(m => typeof m.content === "string" ? m.content : JSON.stringify(m.content))
|
|
209
|
+
.join(" ")
|
|
210
|
+
.slice(0, 3000);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
function detectIntent(content) {
|
|
214
|
+
const scores = {};
|
|
215
|
+
for (const [intent, config] of Object.entries(INTENTS)) {
|
|
216
|
+
scores[intent] = config.patterns.reduce((score, pattern) => {
|
|
217
|
+
const matches = (content.match(pattern) || []).length;
|
|
218
|
+
return score + matches;
|
|
219
|
+
}, 0);
|
|
220
|
+
}
|
|
221
|
+
const sorted = Object.entries(scores)
|
|
222
|
+
.filter(([_, score]) => score > 0)
|
|
223
|
+
.sort((a, b) => b[1] - a[1]);
|
|
224
|
+
return sorted.length > 0 ? sorted[0][0] : null;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
module.exports = async function router(req, config) {
|
|
228
|
+
const content = extractContent(req);
|
|
229
|
+
const intent = detectIntent(content);
|
|
230
|
+
if (intent && INTENTS[intent]) {
|
|
231
|
+
const route = INTENTS[intent].route;
|
|
232
|
+
console.log(`[Router] ${intent} → ${route}`);
|
|
233
|
+
return route;
|
|
234
|
+
}
|
|
235
|
+
console.log("[Router] No match → openai,gpt-4o");
|
|
236
|
+
return null;
|
|
237
|
+
};
|
|
238
|
+
EOF
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### 4. .zshrc Eklemeleri
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
cat >> ~/.zshrc << 'EOF'
|
|
245
|
+
|
|
246
|
+
# ═══════════════════════════════════════════════════
|
|
247
|
+
# Claude Code Router - API Keys
|
|
248
|
+
# ═══════════════════════════════════════════════════
|
|
249
|
+
export OPENAI_API_KEY="sk-..."
|
|
250
|
+
export ANTHROPIC_API_KEY="sk-ant-..."
|
|
251
|
+
export GEMINI_API_KEY="AIza..."
|
|
252
|
+
export QWEN_API_KEY="sk-..."
|
|
253
|
+
export GLM_API_KEY="..."
|
|
254
|
+
export OPENROUTER_API_KEY="sk-or-..."
|
|
255
|
+
|
|
256
|
+
# Router Connection
|
|
257
|
+
export ANTHROPIC_BASE_URL="http://127.0.0.1:3456"
|
|
258
|
+
export NO_PROXY="127.0.0.1"
|
|
259
|
+
EOF
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### 5. Başlat
|
|
263
|
+
|
|
264
|
+
```bash
|
|
265
|
+
source ~/.zshrc
|
|
266
|
+
ccr code
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
---
|
|
270
|
+
|
|
271
|
+
## TEK SATIRLIK KURULUM
|
|
272
|
+
|
|
273
|
+
Tüm dosyaları tek seferde oluşturmak için:
|
|
274
|
+
|
|
275
|
+
```bash
|
|
276
|
+
# 1. Kur
|
|
277
|
+
pnpm add -g @musistudio/claude-code-router && mkdir -p ~/.claude-code-router
|
|
278
|
+
|
|
279
|
+
# 2. Config'leri indir (bu repo'dan)
|
|
280
|
+
curl -sL https://raw.githubusercontent.com/YOUR_REPO/main/config.json > ~/.claude-code-router/config.json
|
|
281
|
+
curl -sL https://raw.githubusercontent.com/YOUR_REPO/main/intent-router.js > ~/.claude-code-router/intent-router.js
|
|
282
|
+
|
|
283
|
+
# 3. API key'leri .zshrc'ye ekle (manuel)
|
|
284
|
+
# 4. Başlat
|
|
285
|
+
source ~/.zshrc && ccr code
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
## API KEY ALMA LİNKLERİ
|
|
291
|
+
|
|
292
|
+
| Provider | Link |
|
|
293
|
+
|----------|------|
|
|
294
|
+
| OpenAI | https://platform.openai.com/api-keys |
|
|
295
|
+
| Anthropic | https://console.anthropic.com/settings/keys |
|
|
296
|
+
| Gemini | https://aistudio.google.com/apikey |
|
|
297
|
+
| Qwen | https://dashscope.console.aliyun.com/apiKey |
|
|
298
|
+
| GLM | https://open.bigmodel.cn/usercenter/apikeys |
|
|
299
|
+
| OpenRouter | https://openrouter.ai/keys |
|
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
# Claude Code Router - Setup Prompt for Other Machines
|
|
2
|
+
|
|
3
|
+
Use this prompt to set up Claude Code Router on another machine. Copy and paste into Claude Code.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## SETUP PROMPT
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
You are a DevOps + LLM infrastructure engineer.
|
|
11
|
+
|
|
12
|
+
Task: Install and configure Claude Code Router with intent-based routing.
|
|
13
|
+
|
|
14
|
+
Requirements:
|
|
15
|
+
- Use pnpm (not npm)
|
|
16
|
+
- Don't hardcode model versions, use the latest/recommended models per provider
|
|
17
|
+
- macOS/Linux environment
|
|
18
|
+
|
|
19
|
+
Providers to setup:
|
|
20
|
+
1. OpenAI (gpt-4o, o1) - Coding, debugging
|
|
21
|
+
2. Anthropic Claude - Deep reasoning, analysis
|
|
22
|
+
3. Google Gemini - Fast responses, long context
|
|
23
|
+
4. Alibaba Qwen (DashScope) - Cheap, simple tasks
|
|
24
|
+
5. Zhipu GLM (Z.ai) - Multilingual, translation
|
|
25
|
+
6. OpenRouter - Fallback
|
|
26
|
+
7. GitHub Copilot - Coding assistance
|
|
27
|
+
|
|
28
|
+
Intent-Based Routing Rules:
|
|
29
|
+
- Code writing/debug → OpenAI (gpt-4o)
|
|
30
|
+
- Architecture/analysis/why → Anthropic Claude
|
|
31
|
+
- Fast/summary/tldr → Gemini Flash
|
|
32
|
+
- Simple/list/help → Qwen (cheap)
|
|
33
|
+
- Translation/multilingual → GLM
|
|
34
|
+
- Complex algorithm → OpenAI (o1)
|
|
35
|
+
- Coding help/suggestions → GitHub Copilot
|
|
36
|
+
- No match → OpenAI (fallback)
|
|
37
|
+
|
|
38
|
+
Tasks:
|
|
39
|
+
1. Install @musistudio/claude-code-router with pnpm
|
|
40
|
+
2. Create ~/.claude-code-router/config.json (all providers)
|
|
41
|
+
3. Create ~/.claude-code-router/intent-router.js (routing logic)
|
|
42
|
+
4. Show required .zshrc additions
|
|
43
|
+
|
|
44
|
+
API Endpoints:
|
|
45
|
+
- OpenAI: https://api.openai.com/v1/chat/completions
|
|
46
|
+
- Anthropic: https://api.anthropic.com/v1/messages (transformer: Anthropic)
|
|
47
|
+
- Gemini: https://generativelanguage.googleapis.com/v1beta/openai/chat/completions (transformer: gemini)
|
|
48
|
+
- Qwen: https://dashscope-intl.aliyuncs.com/compatible-mode/v1/chat/completions
|
|
49
|
+
- GLM: https://api.z.ai/api/paas/v4/chat/completions
|
|
50
|
+
- OpenRouter: https://openrouter.ai/api/v1/chat/completions (transformer: openrouter)
|
|
51
|
+
- GitHub Copilot: Custom implementation for GitHub API
|
|
52
|
+
|
|
53
|
+
Router Settings:
|
|
54
|
+
- default: openai,gpt-4o
|
|
55
|
+
- background: qwen,qwen-turbo
|
|
56
|
+
- think: anthropic,claude-sonnet-4-latest
|
|
57
|
+
- longContext: gemini,gemini-2.5-flash
|
|
58
|
+
- longContextThreshold: 60000
|
|
59
|
+
|
|
60
|
+
Output:
|
|
61
|
+
1. Installation commands
|
|
62
|
+
2. config.json content
|
|
63
|
+
3. intent-router.js content
|
|
64
|
+
4. .zshrc additions
|
|
65
|
+
5. Startup and test commands
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## QUICK SETUP (Manual)
|
|
71
|
+
|
|
72
|
+
If you prefer manual setup:
|
|
73
|
+
|
|
74
|
+
### 1. Install
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
pnpm add -g @musistudio/claude-code-router
|
|
78
|
+
mkdir -p ~/.claude-code-router
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### 2. config.json
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
cat > ~/.claude-code-router/config.json << 'EOF'
|
|
85
|
+
{
|
|
86
|
+
"LOG": true,
|
|
87
|
+
"LOG_LEVEL": "info",
|
|
88
|
+
"API_TIMEOUT_MS": 300000,
|
|
89
|
+
"CUSTOM_ROUTER_PATH": "$HOME/.claude-code-router/intent-router.js",
|
|
90
|
+
|
|
91
|
+
"Providers": [
|
|
92
|
+
{
|
|
93
|
+
"name": "openai",
|
|
94
|
+
"api_base_url": "https://api.openai.com/v1/chat/completions",
|
|
95
|
+
"api_key": "$OPENAI_API_KEY",
|
|
96
|
+
"models": ["gpt-4o", "gpt-4-turbo", "gpt-4o-mini", "o1", "o1-mini"],
|
|
97
|
+
"transformer": { "use": [] }
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"name": "anthropic",
|
|
101
|
+
"api_base_url": "https://api.anthropic.com/v1/messages",
|
|
102
|
+
"api_key": "$ANTHROPIC_API_KEY",
|
|
103
|
+
"models": ["claude-sonnet-4-latest", "claude-3-5-sonnet-latest"],
|
|
104
|
+
"transformer": { "use": ["Anthropic"] }
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"name": "gemini",
|
|
108
|
+
"api_base_url": "https://generativelanguage.googleapis.com/v1beta/openai/chat/completions",
|
|
109
|
+
"api_key": "$GEMINI_API_KEY",
|
|
110
|
+
"models": ["gemini-2.5-flash", "gemini-2.5-pro", "gemini-2.0-flash"],
|
|
111
|
+
"transformer": { "use": ["gemini"] }
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"name": "qwen",
|
|
115
|
+
"api_base_url": "https://dashscope-intl.aliyuncs.com/compatible-mode/v1/chat/completions",
|
|
116
|
+
"api_key": "$QWEN_API_KEY",
|
|
117
|
+
"models": ["qwen-plus", "qwen-max", "qwen3-coder-plus", "qwen-turbo"],
|
|
118
|
+
"transformer": { "use": [] }
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
"name": "glm",
|
|
122
|
+
"api_base_url": "https://api.z.ai/api/paas/v4/chat/completions",
|
|
123
|
+
"api_key": "$GLM_API_KEY",
|
|
124
|
+
"models": ["glm-4.6", "glm-4.5", "glm-4-plus"],
|
|
125
|
+
"transformer": { "use": [] }
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
"name": "openrouter",
|
|
129
|
+
"api_base_url": "https://openrouter.ai/api/v1/chat/completions",
|
|
130
|
+
"api_key": "$OPENROUTER_API_KEY",
|
|
131
|
+
"models": [
|
|
132
|
+
"anthropic/claude-sonnet-4",
|
|
133
|
+
"deepseek/deepseek-chat",
|
|
134
|
+
"google/gemini-2.5-flash",
|
|
135
|
+
"meta-llama/llama-3.3-70b-instruct"
|
|
136
|
+
],
|
|
137
|
+
"transformer": { "use": ["openrouter"] }
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
"name": "copilot",
|
|
141
|
+
"api_base_url": "https://api.githubcopilot.com/chat/completions",
|
|
142
|
+
"api_key": "$GITHUB_COPIOT_API_KEY",
|
|
143
|
+
"models": ["copilot"],
|
|
144
|
+
"transformer": { "use": [] }
|
|
145
|
+
}
|
|
146
|
+
],
|
|
147
|
+
|
|
148
|
+
"Router": {
|
|
149
|
+
"default": "openai,gpt-4o",
|
|
150
|
+
"background": "qwen,qwen-turbo",
|
|
151
|
+
"think": "anthropic,claude-sonnet-4-latest",
|
|
152
|
+
"longContext": "gemini,gemini-2.5-flash",
|
|
153
|
+
"longContextThreshold": 60000
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
EOF
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### 3. intent-router.js
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
cat > ~/.claude-code-router/intent-router.js << 'EOF'
|
|
163
|
+
const INTENTS = {
|
|
164
|
+
CODING: {
|
|
165
|
+
patterns: [
|
|
166
|
+
/\b(implement|refactor|debug|fix|write|code|function|class|method|bug|error|compile|syntax)\b/i,
|
|
167
|
+
/\b(typescript|javascript|python|rust|go|java|react|vue|angular|swift|kotlin)\b/i,
|
|
168
|
+
/\b(api|endpoint|database|query|migration|schema|test|unit test)\b/i,
|
|
169
|
+
/\b(codex|o1|reasoning)\b/i
|
|
170
|
+
],
|
|
171
|
+
route: "openai,gpt-4o"
|
|
172
|
+
},
|
|
173
|
+
CODING_ASSIST: {
|
|
174
|
+
patterns: [
|
|
175
|
+
/\b(help me code|suggest improvement|better way to|how to improve)\b/i,
|
|
176
|
+
/\b(refactor this|optimize this|clean up this code)\b/i
|
|
177
|
+
],
|
|
178
|
+
route: "copilot,copilot"
|
|
179
|
+
},
|
|
180
|
+
REASONING: {
|
|
181
|
+
patterns: [
|
|
182
|
+
/\b(architect|design|analyze|plan|strategy|structure|system|trade-?off)\b/i,
|
|
183
|
+
/\b(why|explain|reason|understand|compare|evaluate|consider|review)\b/i,
|
|
184
|
+
/\b(decision|approach|best practice|pattern|principle|philosophy)\b/i
|
|
185
|
+
],
|
|
186
|
+
route: "anthropic,claude-sonnet-4-latest"
|
|
187
|
+
},
|
|
188
|
+
FAST: {
|
|
189
|
+
patterns: [
|
|
190
|
+
/\b(fast|quick|brief|short|summary|tldr|overview)\b/i,
|
|
191
|
+
/\b(scan|check|verify|validate)\b/i
|
|
192
|
+
],
|
|
193
|
+
route: "gemini,gemini-2.5-flash"
|
|
194
|
+
},
|
|
195
|
+
SIMPLE: {
|
|
196
|
+
patterns: [
|
|
197
|
+
/\b(list|show|what is|simple|basic|help|how to|format)\b/i,
|
|
198
|
+
/\b(rename|move|delete|create file|mkdir|copy)\b/i
|
|
199
|
+
],
|
|
200
|
+
route: "qwen,qwen-plus"
|
|
201
|
+
},
|
|
202
|
+
MULTILINGUAL: {
|
|
203
|
+
patterns: [
|
|
204
|
+
/\b(translate|multilingual|chinese|japanese|spanish|french|german)\b/i,
|
|
205
|
+
/[\u4e00-\u9fff]/, // Chinese characters
|
|
206
|
+
/[\u0600-\u06FF]/, // Arabic
|
|
207
|
+
/[\u0400-\u04FF]/, // Cyrillic
|
|
208
|
+
],
|
|
209
|
+
route: "glm,glm-4.6"
|
|
210
|
+
},
|
|
211
|
+
HEAVY_REASONING: {
|
|
212
|
+
patterns: [
|
|
213
|
+
/\b(complex algorithm|optimization|performance critical|system design)\b/i,
|
|
214
|
+
/\b(prove|mathematical|theorem|formal verification)\b/i
|
|
215
|
+
],
|
|
216
|
+
route: "openai,o1"
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
function extractContent(req) {
|
|
221
|
+
const messages = req.body?.messages || [];
|
|
222
|
+
return messages
|
|
223
|
+
.filter(m => m.role === "user" || m.role === "system")
|
|
224
|
+
.map(m => typeof m.content === "string" ? m.content : JSON.stringify(m.content))
|
|
225
|
+
.join(" ")
|
|
226
|
+
.slice(0, 3000);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function detectIntent(content) {
|
|
230
|
+
const scores = {};
|
|
231
|
+
for (const [intent, config] of Object.entries(INTENTS)) {
|
|
232
|
+
scores[intent] = config.patterns.reduce((score, pattern) => {
|
|
233
|
+
const matches = (content.match(pattern) || []).length;
|
|
234
|
+
return score + matches;
|
|
235
|
+
}, 0);
|
|
236
|
+
}
|
|
237
|
+
const sorted = Object.entries(scores)
|
|
238
|
+
.filter(([_, score]) => score > 0)
|
|
239
|
+
.sort((a, b) => b[1] - a[1]);
|
|
240
|
+
return sorted.length > 0 ? sorted[0][0] : null;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
module.exports = async function router(req, config) {
|
|
244
|
+
const content = extractContent(req);
|
|
245
|
+
const intent = detectIntent(content);
|
|
246
|
+
if (intent && INTENTS[intent]) {
|
|
247
|
+
const route = INTENTS[intent].route;
|
|
248
|
+
console.log(`[Router] ${intent} → ${route}`);
|
|
249
|
+
return route;
|
|
250
|
+
}
|
|
251
|
+
console.log("[Router] No match → openai,gpt-4o");
|
|
252
|
+
return null;
|
|
253
|
+
};
|
|
254
|
+
EOF
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### 4. .zshrc Additions
|
|
258
|
+
|
|
259
|
+
```bash
|
|
260
|
+
cat >> ~/.zshrc << 'EOF'
|
|
261
|
+
|
|
262
|
+
# ═══════════════════════════════════════════════════
|
|
263
|
+
# Claude Code Router - API Keys
|
|
264
|
+
# ═══════════════════════════════════════════════════
|
|
265
|
+
export OPENAI_API_KEY="sk-..."
|
|
266
|
+
export ANTHROPIC_API_KEY="sk-ant-..."
|
|
267
|
+
export GEMINI_API_KEY="AIza..."
|
|
268
|
+
export QWEN_API_KEY="sk-..."
|
|
269
|
+
export GLM_API_KEY="..."
|
|
270
|
+
export OPENROUTER_API_KEY="sk-or-..."
|
|
271
|
+
export GITHUB_COPIOT_API_KEY="ghu_..."
|
|
272
|
+
|
|
273
|
+
# Router Connection
|
|
274
|
+
export ANTHROPIC_BASE_URL="http://127.0.0.1:3456"
|
|
275
|
+
export NO_PROXY="127.0.0.1"
|
|
276
|
+
EOF
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### 5. Start
|
|
280
|
+
|
|
281
|
+
```bash
|
|
282
|
+
source ~/.zshrc
|
|
283
|
+
ccr code
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
---
|
|
287
|
+
|
|
288
|
+
## ONE-LINE INSTALLATION
|
|
289
|
+
|
|
290
|
+
To create all files at once:
|
|
291
|
+
|
|
292
|
+
```bash
|
|
293
|
+
# 1. Install
|
|
294
|
+
pnpm add -g @musistudio/claude-code-router && mkdir -p ~/.claude-code-router
|
|
295
|
+
|
|
296
|
+
# 2. Download configs (from this repo)
|
|
297
|
+
curl -sL https://raw.githubusercontent.com/YOUR_REPO/main/config/config.json > ~/.claude-code-router/config.json
|
|
298
|
+
curl -sL https://raw.githubusercontent.com/YOUR_REPO/main/config/intent-router.js > ~/.claude-code-router/intent-router.js
|
|
299
|
+
|
|
300
|
+
# 3. Add API keys to .zshrc (manual)
|
|
301
|
+
# 4. Start
|
|
302
|
+
source ~/.zshrc && ccr code
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
---
|
|
306
|
+
|
|
307
|
+
## API KEY SETUP LINKS
|
|
308
|
+
|
|
309
|
+
| Provider | Link | Notes |
|
|
310
|
+
|----------|------|-------|
|
|
311
|
+
| OpenAI | https://platform.openai.com/api-keys | gpt-4o, o1 |
|
|
312
|
+
| Anthropic | https://console.anthropic.com/settings/keys | Claude |
|
|
313
|
+
| Gemini | https://aistudio.google.com/apikey | Google AI |
|
|
314
|
+
| Qwen | https://dashscope.console.aliyun.com/apiKey | Alibaba |
|
|
315
|
+
| GLM | https://open.bigmodel.cn/usercenter/apikeys | Zhipu AI |
|
|
316
|
+
| OpenRouter | https://openrouter.ai/keys | Multiple |
|
|
317
|
+
| GitHub Copilot | https://github.com/settings/tokens | `copilot` scope |
|