#!/usr/bin/env bash # ============================================================ # CCMR (Claude Code Model Router) 配置自动生成脚本 # # 功能说明: # 读取 CCMR_* 环境变量,生成 CCMR 网关所需的 .env 和 models.yaml # 支持两种配置方式,优先级:文件 > Docker/HF Spaces 环境变量 # # 方式1 - 配置文件(推荐): # 创建 /root/.env.d/ccmr.env,填入以下变量即可 # 修改后立即生效,无需重启容器(由 ccmr-wrapper.sh 监控热加载) # # 方式2 - Docker/HF Spaces 环境变量: # 在 docker run -e 或 HF Spaces Secrets 中设置 CCMR_* 变量 # # 运行原理: # 1. 检测 /root/.env.d/ccmr.env 是否存在,存在则 source 加载 # 2. 读取当前 Shell 中所有 CCMR_* 环境变量(来自文件或 Docker) # 3. 将 CCMR_DEEPSEEK_API_KEY -> DEEPSEEK_API_KEY 映射写入 .env # 4. 如果 /root/.ccmr/models.yaml 不存在,生成默认模型配置 # # ============================================================ # 所有支持的环境变量(共 10 个 API Key + 3 个系统设置) # ============================================================ # # 系统设置: # CCMR_ENABLED - 是否启用 CCMR (true/false, 默认 false) # CCMR_PORT - 网关监听端口 (默认 8080) # CCMR_CONFIG_DIR - 配置存放目录 (默认 ~/.ccmr) # # API Key 列表(按平台分组): # # 1) DeepSeek(https://platform.deepseek.com/) # CCMR_DEEPSEEK_API_KEY=sk-xxx # 支持模型: deepseek-v4-pro, deepseek-v4-flash # 可用别名: deepseek, deepseek-pro, deepseek-flash, ds-flash # # 2) 通义千问 / Qwen(https://dashscope.console.aliyun.com/) # CCMR_QWEN_API_KEY=sk-xxx # 支持模型: qwen3.5-plus, qwen3.5-flash, qwen3-max # 可用别名: qwen, qwen-plus, qwen-flash, qw-turbo, qwen-max # # 3) Kimi / Moonshot(https://platform.kimi.ai/) # CCMR_KIMI_API_KEY=sk-xxx # 支持模型: kimi-k2.6 # 可用别名: kimi, moonshot # # 4) 智谱 GLM(https://open.bigmodel.cn/) # CCMR_GLM_API_KEY=xxx # 支持模型: glm-5.1, glm-5.1-flash # 可用别名: glm, glm4, glm-flash # # 5) MiniMax CN(https://platform.minimaxi.com/) # CCMR_MINIMAX_API_KEY=xxx # 支持模型: minimax-m2.7 # 可用别名: minimax, mmax # # 6) MiniMax Global(https://platform.minimax.io/) # CCMR_MINIMAX_GLOBAL_API_KEY=xxx # 支持模型: minimax-global-m2.7 # 可用别名: minimax-global, mmax-global # # 7) MiMo Token Plan SGP 集群(https://platform.xiaomimimo.com/) # CCMR_MIMO_API_KEY=tp-xxx # 支持模型: mimo-v2.5-pro - SGP 集群 (Singapore) # 可用别名: mimo, mimo-pro # # 8) MiMo Token Plan CN 集群 # CCMR_MIMO_TOKEN_CN_API_KEY=tp-xxx # 支持模型: mimo-v2.5-pro - CN 集群 # # 9) MiMo Token Plan AMS 集群 # CCMR_MIMO_TOKEN_AMS_API_KEY=tp-xxx # 支持模型: mimo-v2.5-pro - AMS 集群 (Amsterdam) # # 10) MiMo 按量付费(https://platform.xiaomimimo.com/) # CCMR_MIMO_PAYG_API_KEY=sk-xxx # 支持模型: mimo-v2.5-pro - Pay-as-you-go # # ============================================================ set -euo pipefail # ============================================================ # 从文件加载 CCMR 环境变量 # ============================================================ CCMR_CONFIG_FILE="${CCMR_CONFIG_FILE:-/root/.env.d/ccmr.env}" if [[ -f "$CCMR_CONFIG_FILE" ]]; then echo "[CCMR-SETUP] Loading configuration from: $CCMR_CONFIG_FILE" # shellcheck source=/dev/null source "$CCMR_CONFIG_FILE" else echo "[CCMR-SETUP] No config file at $CCMR_CONFIG_FILE, using env vars only" echo "[CCMR-SETUP] To use file-based config, create: $CCMR_CONFIG_FILE" fi CCMR_CONFIG_DIR="${CCMR_CONFIG_DIR:-$HOME/.ccmr}" mkdir -p "$CCMR_CONFIG_DIR" echo "[CCMR-SETUP] Generating configuration in: $CCMR_CONFIG_DIR" # ============================================================ # 生成 .env 文件 # ============================================================ ENV_FILE="$CCMR_CONFIG_DIR/.env" # API Key 映射表: CCMR_xxx -> .env 中的键名 declare -A API_KEY_MAP=( ["CCMR_DEEPSEEK_API_KEY"]="DEEPSEEK_API_KEY" ["CCMR_QWEN_API_KEY"]="QWEN_API_KEY" ["CCMR_KIMI_API_KEY"]="KIMI_API_KEY" ["CCMR_GLM_API_KEY"]="GLM_API_KEY" ["CCMR_MINIMAX_API_KEY"]="MINIMAX_API_KEY" ["CCMR_MINIMAX_GLOBAL_API_KEY"]="MINIMAX_GLOBAL_API_KEY" ["CCMR_MIMO_API_KEY"]="MIMO_API_KEY" ["CCMR_MIMO_TOKEN_CN_API_KEY"]="MIMO_TOKEN_CN_API_KEY" ["CCMR_MIMO_TOKEN_AMS_API_KEY"]="MIMO_TOKEN_AMS_API_KEY" ["CCMR_MIMO_PAYG_API_KEY"]="MIMO_PAYG_API_KEY" ) # 创建 .env 文件 { echo "# ============================================================" echo "# Claude Code Model Router - 自动生成的配置" echo "# ============================================================" echo "" has_any_key=false for ccmr_var in "${!API_KEY_MAP[@]}"; do env_key="${API_KEY_MAP[$ccmr_var]}" env_value="${!ccmr_var:-}" if [[ -n "$env_value" ]]; then echo "${env_key}=${env_value}" has_any_key=true fi done if [[ "$has_any_key" == "false" ]]; then echo "# 未检测到 API Key 环境变量" echo "# 请设置环境变量后重新运行,例如:" echo "# CCMR_DEEPSEEK_API_KEY=sk-xxx" echo "# 支持的 Key 列表:" for ccmr_var in "${!API_KEY_MAP[@]}"; do env_key="${API_KEY_MAP[$ccmr_var]}" echo "# ${ccmr_var}=xxx -> ${env_key}=xxx" done fi } > "$ENV_FILE" echo "[CCMR-SETUP] ✓ .env written with $([ "$has_any_key" == "true" ] && echo "$(grep -c '=' "$ENV_FILE") key(s) configured" || echo "no API keys (template mode)")" # ============================================================ # 生成 models.yaml 配置文件 # ============================================================ MODELS_FILE="$CCMR_CONFIG_DIR/models.yaml" if [[ ! -f "$MODELS_FILE" ]]; then echo "[CCMR-SETUP] Creating default models.yaml..." cat > "$MODELS_FILE" << 'YAMLEOF' # ============================================================ # Claude Code Model Router - 模型配置 # ============================================================ providers: deepseek: base_url: "https://api.deepseek.com" api_key_env: "DEEPSEEK_API_KEY" variants: deepseek-v4-pro: model: "deepseek-chat" context_window: 65536 max_tokens: 8192 aliases: - deepseek - deepseek-pro deepseek-v4-flash: model: "deepseek-chat" context_window: 65536 max_tokens: 8192 aliases: - deepseek-flash - ds-flash qwen: base_url: "https://dashscope.aliyuncs.com/compatible-mode/v1" api_key_env: "QWEN_API_KEY" variants: qwen3.5-plus: model: "qwen-plus" context_window: 131072 max_tokens: 8192 aliases: - qwen - qwen-plus qwen3.5-flash: model: "qwen-turbo" context_window: 131072 max_tokens: 8192 aliases: - qwen-flash - qw-turbo qwen3-max: model: "qwen-max" context_window: 32768 max_tokens: 8192 aliases: - qwen-max kimi: base_url: "https://api.moonshot.cn/v1" api_key_env: "KIMI_API_KEY" variants: kimi-k2.6: model: "moonshot-v1-8k" context_window: 8192 max_tokens: 4096 aliases: - kimi - moonshot glm: base_url: "https://open.bigmodel.cn/api/paas/v4" api_key_env: "GLM_API_KEY" variants: glm-5.1: model: "glm-4" context_window: 131072 max_tokens: 4096 aliases: - glm - glm4 glm-5.1-flash: model: "glm-4-flash" context_window: 131072 max_tokens: 4096 aliases: - glm-flash minimax: base_url: "https://api.minimax.chat/v1" api_key_env: "MINIMAX_API_KEY" variants: minimax-m2.7: model: "minimax-m2.7" context_window: 131072 max_tokens: 8192 aliases: - minimax - mmax minimax_global: base_url: "https://api.minimax.io/v1" api_key_env: "MINIMAX_GLOBAL_API_KEY" variants: minimax-global-m2.7: model: "minimax-m2.7" context_window: 131072 max_tokens: 8192 aliases: - minimax-global - mmax-global mimo: base_url: "https://api.miMo.com/v1" api_key_env: "MIMO_API_KEY" variants: mimo-v2.5-pro: model: "mimo-v2.5-pro" context_window: 131072 max_tokens: 8192 aliases: - mimo - mimo-pro YAMLEOF echo "[CCMR-SETUP] ✓ models.yaml created" else echo "[CCMR-SETUP] → models.yaml already exists, skipping" fi # ============================================================ # 完成 # ============================================================ echo "[CCMR-SETUP] Config directory: $CCMR_CONFIG_DIR" echo "[CCMR-SETUP] Files:" ls -la "$CCMR_CONFIG_DIR/" echo "[CCMR-SETUP] Setup complete!"