mirror of
https://github.com/tiennm99/claude-code-router-provider-registry.git
synced 2026-04-17 13:20:58 +00:00
init
This commit is contained in:
49
.github/workflows/daily-build.yml
vendored
Normal file
49
.github/workflows/daily-build.yml
vendored
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
name: Daily Build and Upload to Cloudflare R2
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
# Runs at 2 AM UTC every day
|
||||||
|
- cron: '0 2 * * *'
|
||||||
|
workflow_dispatch: # Allows manual triggering
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-and-upload:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: '22'
|
||||||
|
cache: 'npm'
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: npm ci
|
||||||
|
|
||||||
|
- name: Build providers.json
|
||||||
|
run: npm run build
|
||||||
|
|
||||||
|
- name: Verify providers.json exists
|
||||||
|
run: |
|
||||||
|
if [ ! -f providers.json ]; then
|
||||||
|
echo "providers.json file not found!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "providers.json file size: $(wc -c < providers.json) bytes"
|
||||||
|
|
||||||
|
- name: Upload to Cloudflare R2
|
||||||
|
uses: cloudflare/wrangler-action@v3
|
||||||
|
with:
|
||||||
|
apiToken: $\{{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||||
|
accountId: $\{{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||||
|
command: r2 object put providers.json --file providers.json --bucket $\{{ secrets.R2_BUCKET_NAME }}
|
||||||
|
|
||||||
|
- name: Upload Success Notification
|
||||||
|
if: success()
|
||||||
|
run: echo "Successfully uploaded providers.json to Cloudflare R2"
|
||||||
|
|
||||||
|
- name: Upload Failure Notification
|
||||||
|
if: failure()
|
||||||
|
run: echo "Failed to upload providers.json to Cloudflare R2"
|
||||||
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
providers.json
|
||||||
|
.env
|
||||||
17
README.md
Normal file
17
README.md
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# Claude Code Router Provider Registry
|
||||||
|
|
||||||
|
This repository contains provider configurations for the Claude Code Router.
|
||||||
|
|
||||||
|
## Submitting a New Provider
|
||||||
|
|
||||||
|
To add a new provider to the registry:
|
||||||
|
|
||||||
|
1. Create a new JSON file in the `providers` directory with your provider's configuration. The file should include:
|
||||||
|
- `name`: The provider's name
|
||||||
|
- `api_base_url`: The base URL for the provider's API
|
||||||
|
- `api_key`: The API key (keep empty)
|
||||||
|
- `models`: An array of supported model names
|
||||||
|
- `transformer`: Configuration for request/response transformation
|
||||||
|
2. Commit your changes with a descriptive message
|
||||||
|
3. Push your changes to your fork
|
||||||
|
4. Open a pull request to the main repository with a clear title and description
|
||||||
16
package.json
Normal file
16
package.json
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"name": "claude-code-router-provider-registry",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "Provider registry for Claude Code Router",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"build": "node scripts/build.js"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"fs": "0.0.1-security",
|
||||||
|
"path": "0.12.7"
|
||||||
|
}
|
||||||
|
}
|
||||||
19
providers/dashscope.json
Normal file
19
providers/dashscope.json
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"name": "dashscope",
|
||||||
|
"api_base_url": "https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions",
|
||||||
|
"api_key": "",
|
||||||
|
"models": ["qwen3-coder-plus"],
|
||||||
|
"transformer": {
|
||||||
|
"use": [
|
||||||
|
[
|
||||||
|
"maxtoken",
|
||||||
|
{
|
||||||
|
"max_tokens": 65536
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"qwen3-coder-plus": {
|
||||||
|
"use": ["enhancetool"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
12
providers/deepseek.json
Normal file
12
providers/deepseek.json
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"name": "deepseek",
|
||||||
|
"api_base_url": "https://api.deepseek.com/chat/completions",
|
||||||
|
"api_key": "",
|
||||||
|
"models": ["deepseek-chat", "deepseek-reasoner"],
|
||||||
|
"transformer": {
|
||||||
|
"use": ["deepseek"],
|
||||||
|
"deepseek-chat": {
|
||||||
|
"use": ["tooluse"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
9
providers/gemini.json
Normal file
9
providers/gemini.json
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"name": "gemini",
|
||||||
|
"api_base_url": "https://generativelanguage.googleapis.com/v1beta/models/",
|
||||||
|
"api_key": "",
|
||||||
|
"models": ["gemini-2.5-flash", "gemini-2.5-pro"],
|
||||||
|
"transformer": {
|
||||||
|
"use": ["gemini"]
|
||||||
|
}
|
||||||
|
}
|
||||||
26
providers/modelscope.json
Normal file
26
providers/modelscope.json
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"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",
|
||||||
|
"ZhipuAI/GLM-4.5"
|
||||||
|
],
|
||||||
|
"transformer": {
|
||||||
|
"use": [
|
||||||
|
[
|
||||||
|
"maxtoken",
|
||||||
|
{
|
||||||
|
"max_tokens": 65536
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"Qwen/Qwen3-Coder-480B-A35B-Instruct": {
|
||||||
|
"use": ["enhancetool"]
|
||||||
|
},
|
||||||
|
"Qwen/Qwen3-235B-A22B-Thinking-2507": {
|
||||||
|
"use": ["reasoning"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
14
providers/openrouter.json
Normal file
14
providers/openrouter.json
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"name": "openrouter",
|
||||||
|
"api_base_url": "https://openrouter.ai/api/v1/chat/completions",
|
||||||
|
"api_key": "",
|
||||||
|
"models": [
|
||||||
|
"google/gemini-2.5-pro-preview",
|
||||||
|
"anthropic/claude-sonnet-4",
|
||||||
|
"anthropic/claude-3.5-sonnet",
|
||||||
|
"anthropic/claude-3.7-sonnet:thinking"
|
||||||
|
],
|
||||||
|
"transformer": {
|
||||||
|
"use": ["openrouter"]
|
||||||
|
}
|
||||||
|
}
|
||||||
16
providers/siliconflow.json
Normal file
16
providers/siliconflow.json
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"name": "siliconflow",
|
||||||
|
"api_base_url": "https://api.siliconflow.cn/v1/chat/completions",
|
||||||
|
"api_key": "sk-xxx",
|
||||||
|
"models": ["moonshotai/Kimi-K2-Instruct"],
|
||||||
|
"transformer": {
|
||||||
|
"use": [
|
||||||
|
[
|
||||||
|
"maxtoken",
|
||||||
|
{
|
||||||
|
"max_tokens": 16384
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
9
providers/volcengine.json
Normal file
9
providers/volcengine.json
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"name": "volcengine",
|
||||||
|
"api_base_url": "https://ark.cn-beijing.volces.com/api/v3/chat/completions",
|
||||||
|
"api_key": "sk-xxx",
|
||||||
|
"models": ["deepseek-v3-250324", "deepseek-r1-250528"],
|
||||||
|
"transformer": {
|
||||||
|
"use": ["deepseek"]
|
||||||
|
}
|
||||||
|
}
|
||||||
55
scripts/build.js
Normal file
55
scripts/build.js
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 合并目录中的所有JSON文件到一个大的JSON文件中
|
||||||
|
* @param {string} inputDir 包含JSON文件的目录路径
|
||||||
|
* @param {string} outputFile 输出的合并后JSON文件路径
|
||||||
|
*/
|
||||||
|
async function mergeJsonFiles(inputDir, outputFile) {
|
||||||
|
try {
|
||||||
|
// 1. 读取目录中的所有文件
|
||||||
|
const files = await fs.promises.readdir(inputDir);
|
||||||
|
|
||||||
|
// 2. 过滤出JSON文件
|
||||||
|
const jsonFiles = files.filter(file => file.endsWith('.json'));
|
||||||
|
|
||||||
|
if (jsonFiles.length === 0) {
|
||||||
|
console.log('目录中没有找到JSON文件');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 读取并解析所有JSON文件
|
||||||
|
const jsonArray = [];
|
||||||
|
|
||||||
|
for (const file of jsonFiles) {
|
||||||
|
const filePath = path.join(inputDir, file);
|
||||||
|
const fileContent = await fs.promises.readFile(filePath, 'utf8');
|
||||||
|
|
||||||
|
try {
|
||||||
|
const jsonData = JSON.parse(fileContent);
|
||||||
|
jsonArray.push(jsonData);
|
||||||
|
console.log(`成功加载: ${file}`);
|
||||||
|
} catch (err) {
|
||||||
|
console.error(`解析失败 ${file}: ${err.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 将合并后的数组写入输出文件
|
||||||
|
await fs.promises.writeFile(
|
||||||
|
outputFile,
|
||||||
|
JSON.stringify(jsonArray, null, 2), // 使用2空格缩进美化输出
|
||||||
|
'utf8'
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log(`成功合并 ${jsonArray.length} 个JSON文件到 ${outputFile}`);
|
||||||
|
} catch (err) {
|
||||||
|
console.error('处理过程中出错:', err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用示例
|
||||||
|
const inputDirectory = './providers'; // 替换为你的JSON文件目录
|
||||||
|
const outputFile = './providers.json'; // 替换为你想输出的文件路径
|
||||||
|
|
||||||
|
mergeJsonFiles(inputDirectory, outputFile);
|
||||||
Reference in New Issue
Block a user