This commit is contained in:
musistudio
2025-08-03 08:18:08 +08:00
commit b8e0e99e5c
12 changed files with 244 additions and 0 deletions

49
.github/workflows/daily-build.yml vendored Normal file
View 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
View File

@@ -0,0 +1,2 @@
providers.json
.env

17
README.md Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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"]
}
}

View 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
}
]
]
}
}

View 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
View 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);