Files
hack/tools/scripts/llm-key-hunter/results/_cache/content/binrogithub_1-3-cloud-adoption-skills.json
OpenCode 68a9071cf1 feat: reconcile local master with origin (exa/hot-platform hunters, leaks ledger, latest results)
Local branch had diverged from origin/master (sibling commits on the same base). Rewrote local history linearly on top of origin/master, folding in all local content: exa/hot-platform discovery hunters, leaks ledger, nightly sweep orchestrator, updated .gitignore and skill docs, plus the latest hunt output and vault state. Remote-only files (vault keys, channel scripts) were restored rather than dropped, so the resulting tree is a full union of both sides.
2026-08-07 12:53:47 +08:00

1 line
76 KiB
JSON

{"repo": "binrogithub/1-3-cloud-adoption-skills", "files": {"AI-Assist-Migration/AI-Coding/ClaudeCode-LiteLLM-MaaS/SKILL.md": {"dfd489984a277403e3ffedcfee1fb136579dabf3": {"t": 1785746585.1679766, "n": 21031, "h": "51fae0154980bc30", "c": "---\nname: claude-code-litellm-maas\ndescription: Configure Claude Code with LiteLLM proxy for Huawei Cloud MaaS models. Covers Node.js/Claude Code installation, venv setup, config generation with Claude model-name aliases, environment variable configuration, startup script, and model switching.\nlicense: MIT\ncompatibility: claude-code\nmetadata:\n audience: infrastructure-engineers\n workflow: claude-code-litellm-maas\n---\n\n# Claude Code + LiteLLM Proxy for Huawei Cloud MaaS\n\nSet up **Claude Code** to use **LiteLLM proxy** as a gateway to Huawei Cloud ModelArts MaaS models. Claude Code sends requests to LiteLLM (localhost:4000), which forwards them to MaaS using the `custom_openai` provider.\n\n**Key technique:** Claude Code validates model names at startup. We register Claude-recognized model names (e.g. `claude-3-5-haiku-coding`) as aliases in LiteLLM's `config.yaml`, mapping them to actual MaaS models (e.g. `deepseek-v4-flash`). Claude Code thinks it's using Claude models; LiteLLM transparently routes to MaaS.\n\n```\nClaude Code → LiteLLM (localhost:4000) → Huawei Cloud MaaS → DeepSeek/GLM models\n```\n\n## Rules\n\n1. **ALWAYS use a Python 3.12 venv** — Python 3.14+ breaks `orjson` which `litellm[proxy]` depends on. Use `uv` to manage the venv if the system Python is too new.\n2. **NEVER hardcode `MAAS_API_KEY` in config.yaml** — use `os.environ/MAAS_API_KEY` so the key stays in env vars only.\n3. **NEVER expose `MAAS_API_KEY` in logs** — LiteLLM logs may contain request details. Keep the key out of shell history by sourcing env scripts instead of passing it inline.\n4. **ALWAYS `unset ANTHROPIC_API_KEY`** — if this env var is set, Claude Code attempts official Anthropic authentication and ignores `ANTHROPIC_AUTH_TOKEN`. This is the #1 cause of \"Claude Code still tries to login to Anthropic\".\n5. **ALWAYS kill existing LiteLLM on port 4000 before starting** — stale processes cause \"address already in use\" errors.\n6. **Use `setsid` + `disown` to daemonize LiteLLM** — `nohup` alone may die when the parent shell exits. `setsid` creates a new session group so the proxy survives.\n7. **ALWAYS register Claude model-name aliases in config.yaml** — Claude Code expects specific model name patterns (`claude-3-5-haiku-*`, `claude-3-5-sonnet-*`, `claude-3-opus-*`). Without these aliases mapped in LiteLLM, Claude Code will fail at startup or when switching model tiers.\n8. **`ANTHROPIC_MODEL` must match a `model_name` in config.yaml** — this is the model Claude Code uses for main responses. If it doesn't match a LiteLLM entry, requests will fail.\n9. **Health check via `/v1/models` with auth header** — the `/health` endpoint returns 500 on some LiteLLM versions even when the proxy is fully functional. `/v1/models` with `Authorization: Bearer <master_key>` is the reliable check.\n\n## Prerequisites\n\n| Requirement | Details |\n|-------------|---------|\n| Node.js 20+ | Required by Claude Code. Install via nodesource setup script if missing. |\n| npm | Comes with Node.js. Used to install `@anthropic-ai/claude-code`. |\n| Python 3.12+ | 3.14+ is NOT supported (orjson build fails). Install via `uv` if needed. |\n| `uv` (recommended) or `pip` | For venv + package management. `uv` handles Python version downloads automatically. |\n| `MAAS_API_KEY` | Huawei Cloud ModelArts API key (create in MaaS console → API Key Management). |\n| `lsof` | For port checking in the startup script. Usually pre-installed on Linux. |\n| `curl` | For health checks and API testing. Pre-installed on most systems. |\n\n**Pre-condition:** An ECS instance on Huawei Cloud with EIP (public IP) for accessing MaaS endpoints. Ubuntu 24.04 used as reference OS.\n\n**Minimum resources:** 512 MB RAM, 200 MB disk (for venv + litellm packages).\n\n## Available MaaS Models (July 2026)\n\n> **Note:** DeepSeek-V3.1-Terminus was fully retired on 2026-07-24. DeepSeek-V4-Flash replaces it as the recommended cost-effective model. Source: [DeepSeek API changelog](https://api-docs.deepseek.com/updates).\n\n| Model | MaaS model ID | Context | Max Output | Deep Thinking | Cost Tier |\n|-------|---------------|---------|------------|---------------|-----------|\n| DeepSeek-V4-Flash | `deepseek-v4-flash` | 1M | 128K | Configurable | $$ |\n| DeepSeek-V4-Pro | `deepseek-v4-pro` | 1M | 128K | Configurable | $$$$ |\n| DeepSeek-V3.2 | `deepseek-v3.2` | 160K | 32K | Configurable | $ |\n| DeepSeek-V3 | `DeepSeek-V3` | 128K | 64K | No | $ |\n| DeepSeek-R1 | `deepseek-r1-250528` | 128K | 32K | Always active | $$$$ |\n| GLM-5.2 | `glm-5.2` | 198K | 128K | Configurable | $$$ |\n| GLM-5.1 | `glm-5.1` | 198K | 128K | Configurable | $$$$ |\n| GLM-5 | `glm-5` | 198K | 64K | Configurable | $$$$ |\n\n## Model Name Aliases\n\nClaude Code sends model names it recognizes. We map these to MaaS models in LiteLLM:\n\n| Claude Code sees (`model_name`) | LiteLLM routes to (`litellm_params.model`) | Env var | Use case |\n|----------------------------------|---------------------------------------------|--------|----------|\n| `claude-3-5-haiku-coding` | `custom_openai/deepseek-v4-flash` | `ANTHROPIC_MODEL` | Default main model |\n| `claude-3-5-haiku-20241022` | `custom_openai/deepseek-v3.2` | `ANTHROPIC_SMALL_FAST_MODEL`, `ANTHROPIC_DEFAULT_HAIKU_MODEL`, `CLAUDE_CODE_SUBAGENT_MODEL` | Background/fast tasks |\n| `claude-3-5-sonnet-20241022` | `custom_openai/deepseek-v4-pro` | `ANTHROPIC_DEFAULT_SONNET_MODEL` | Heavy coding |\n| `claude-3-opus-20240229` | `custom_openai/deepseek-v4-pro` | `ANTHROPIC_DEFAULT_OPUS_MODEL` | Opus tier |\n\nAdditionally, all 8 MaaS models are registered with their real names for direct access via `/model` switching.\n\n## Workflow\n\n### Step 1: CHECK PREREQUISITES\n\nVerify Node.js, Python, and check if Claude Code is already installed:\n\n```bash\nnode --version # Need 20+ (for Claude Code)\npython3 --version # Need 3.12+ (NOT 3.14+)\nwhich claude 2>/dev/null # Check if Claude Code is already installed\nwhich uv || which pip3 # At least one package manager\n```\n\nIf system Python is 3.14+, install `uv` to manage a 3.12 venv:\n\n```bash\ncurl -LsSf https://astral.sh/uv/install.sh | sh\n# uv is now at ~/.local/bin/uv\n```\n\n### Step 2: INSTALL CLAUDE CODE\n\nSkip this step if `claude --version` already returns a version number.\n\n#### 2a. Install Node.js 20 (if missing or too old)\n\n```bash\ncurl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -\nsudo apt-get install -y nodejs\nnode --version # Verify: v20.x.x\n```\n\n#### 2b. Install Claude Code\n\n```bash\nnpm install -g @anthropic-ai/claude-code\nclaude --version # Verify installation\n```\n\n### Step 3: CREATE VENV & INSTALL LITELLM\n\n```bash\n# With uv (recommended — auto-downloads Python 3.12 if needed):\n~/.local/bin/uv venv ~/litellm-env --python 3.12\n~/.local/bin/uv pip install 'litellm[proxy]' --python ~/litellm-env/bin/python\n\n# Or with system Python 3.12:\npython3.12 -m venv ~/litellm-env\nsource ~/litellm-env/bin/activate\npip install 'litellm[proxy]'\n```\n\nVerify:\n\n```bash\nsource ~/litellm-env/bin/activate\npython -c \"import litellm; print('litellm OK')\"\nwhich litellm # Should point to ~/litellm-env/bin/litellm\n```\n\n### Step 4: CREATE CONFIG DIRECTORY & FILES\n\n```bash\nmkdir -p ~/litellm\n```\n\n#### 4a. `~/litellm/config.yaml`\n\nCreate the LiteLLM proxy config with Claude model-name aliases + all MaaS models:\n\n```yaml\n# ============================================================\n# LiteLLM Proxy Config - Claude Code + MaaS (Huawei ModelArts)\n# ============================================================\n# Claude Code sends model names it recognizes (claude-3-5-haiku-*,\n# claude-3-5-sonnet-*, claude-3-opus-*). We map these to actual\n# MaaS models. All 8 MaaS models are also available directly.\n#\n# Available models (July 2026):\n# Deep Thinking configurable: glm-5.2, glm-5.1, glm-5,\n# deepseek-v4-pro, deepseek-v4-flash, deepseek-v3.2\n# Deep Thinking always active: deepseek-r1-250528\n# Without Deep Thinking: DeepSeek-V3\n#\n# Retired: deepseek-v3.1-terminus (fully retired 2026-07-24)\n#\n# Cost order (cheap -> expensive):\n# v3.2 < V3 < v4-flash < glm-5.2 < glm-5.1 < glm-5 < v4-pro < r1\n\nmodel_list:\n # ===============================================================\n # Claude model-name aliases (what Claude Code expects to see)\n # ===============================================================\n\n # Default main model: Claude Code thinks it's Haiku, uses V4-Flash\n - model_name: claude-3-5-haiku-coding\n litellm_params:\n model: custom_openai/deepseek-v4-flash\n api_base: https://api-ap-southeast-1.modelarts-maas.com/openai/v1\n api_key: os.environ/MAAS_API_KEY\n\n # Fast/background model: Claude Code thinks Haiku, uses V3.2\n - model_name: claude-3-5-haiku-20241022\n litellm_params:\n model: custom_openai/deepseek-v3.2\n api_base: https://api-ap-southeast-1.modelarts-maas.com/openai/v1\n api_key: os.environ/MAAS_API_KEY\n\n # Sonnet tier: Claude Code thinks Sonnet, uses V4-Pro\n - model_name: claude-3-5-sonnet-20241022\n litellm_params:\n model: custom_openai/deepseek-v4-pro\n api_base: https://api-ap-southeast-1.modelarts-maas.com/openai/v1\n api_key: os.environ/MAAS_API_KEY\n\n # Opus tier: Claude Code thinks Opus, uses V4-Pro\n - model_name: claude-3-opus-20240229\n litellm_params:\n model: custom_openai/deepseek-v4-pro\n api_base: https://api-ap-southeast-1.modelarts-maas.com/openai/v1\n api_key: os.environ/MAAS_API_KEY\n\n # ===============================================================\n # Direct MaaS model access (switch with /model <name>)\n # ===============================================================\n\n - model_name: deepseek-v4-flash\n litellm_params:\n model: custom_openai/deepseek-v4-flash\n api_base: https://api-ap-southeast-1.modelarts-maas.com/openai/v1\n api_key: os.environ/MAAS_API_KEY\n\n - model_name: deepseek-v4-pro\n litellm_params:\n model: custom_openai/deepseek-v4-pro\n api_base: https://api-ap-southeast-1.modelarts-maas.com/openai/v1\n api_key: os.environ/MAAS_API_KEY\n\n - model_name: deepseek-v3.2\n litellm_params:\n model: custom_openai/deepseek-v3.2\n api_base: https://api-ap-southeast-1.modelarts-maas.com/openai/v1\n api_key: os.environ/MAAS_API_KEY\n\n - model_name: deepseek-v3\n litellm_params:\n model: custom_openai/DeepSeek-V3\n api_base: https://api-ap-southeast-1.modelarts-maas.com/openai/v1\n api_key: os.environ/MAAS_API_KEY\n\n - model_name: deepseek-r1\n litellm_params:\n model: custom_openai/deepseek-r1-250528\n api_base: https://api-ap-southeast-1.modelarts-maas.com/openai/v1\n api_key: os.environ/MAAS_API_KEY\n\n - model_name: glm-5.2\n litellm_params:\n model: custom_openai/glm-5.2\n api_base: https://api-ap-southeast-1.modelarts-maas.com/openai/v1\n api_key: os.environ/MAAS_API_KEY\n\n - model_name: glm-5.1\n litellm_params:\n model: custom_openai/glm-5.1\n api_base: https://api-ap-southeast-1.modelarts-maas.com/openai/v1\n api_key: os.environ/MAAS_API_KEY\n\n - model_name: glm-5\n litellm_params:\n model: custom_openai/glm-5\n api_base: https://api-ap-southeast-1.modelarts-maas.com/openai/v1\n api_key: os.environ/MAAS_API_KEY\n\nlitellm_settings:\n drop_params: true # auto drop params MaaS doesn't support\n\ngeneral_settings:\n master_key: sk-123456\n```\n\n#### 4b. `~/litellm/init_litellm_env.sh`\n\nExports the MaaS API key. **Replace the placeholder with your actual key.**\n\n```bash\n#!/bin/bash\n# Source before starting LiteLLM:\n# source ~/litellm/init_litellm_env.sh && litellm --config ~/litellm/config.yaml --port 4000\nexport MAAS_API_KEY=\"<YOUR_MAAS_API_KEY>\"\n```\n\n```bash\nchmod +x ~/litellm/init_litellm_env.sh\n```\n\n#### 4c. `~/litellm/init_claude_env.sh`\n\nSets environment variables so Claude Code talks to the local LiteLLM proxy instead of Anthropic's servers:\n\n```bash\n#!/bin/bash\n# Source before starting Claude Code:\n# source ~/litellm/init_claude_env.sh && claude\n\n# ── LiteLLM master key (must match master_key in config.yaml) ──\nexport LITELLM_MASTER_KEY=\"sk-123456\"\n\n# ── Huawei Cloud MaaS API key ──\nsource ~/litellm/init_litellm_env.sh\n\n# ── Claude Code → LiteLLM proxy ──\nexport ANTHROPIC_BASE_URL=\"http://127.0.0.1:4000\"\nexport ANTHROPIC_AUTH_TOKEN=\"$LITELLM_MASTER_KEY\"\n\n# ── Model mapping (all names must exist in config.yaml) ──\nexport ANTHROPIC_MODEL=\"claude-3-5-haiku-coding\" # → deepseek-v4-flash\nexport ANTHROPIC_SMALL_FAST_MODEL=\"claude-3-5-haiku-20241022\" # → deepseek-v3.2\nexport ANTHROPIC_DEFAULT_HAIKU_MODEL=\"claude-3-5-haiku-20241022\" # → deepseek-v3.2\nexport ANTHROPIC_DEFAULT_SONNET_MODEL=\"claude-3-5-sonnet-20241022\" # → deepseek-v4-pro\nexport ANTHROPIC_DEFAULT_OPUS_MODEL=\"claude-3-opus-20240229\" # → deepseek-v4-pro\nexport CLAUDE_CODE_SUBAGENT_MODEL=\"claude-3-5-haiku-20241022\" # → deepseek-v3.2\n\n# ── CRITICAL: unset official Anthropic auth ──\n# Without this, Claude Code tries to login to Anthropic and ignores ANTHROPIC_AUTH_TOKEN\nunset ANTHROPIC_API_KEY\n\n# ── API timeout (ms) ──\nexport API_TIMEOUT_MS=600000\n\n# ── Disable non-essential traffic (optional, reduces noise) ──\nexport CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1\n```\n\n```bash\nchmod +x ~/litellm/init_claude_env.sh\n```\n\n### Step 5: CREATE STARTUP SCRIPT\n\nCreate `~/start_claude.sh` — kills any stale proxy, starts LiteLLM, waits for it to be ready, then launches Claude Code:\n\n```bash\n#!/bin/bash\nset -euo pipefail\n\nLITELLM_DIR=\"$HOME/litellm\"\nLITELLM_ENV=\"$HOME/litellm-env\"\nLITELLM_PORT=4000\n\nRED='\\033[0;31m'\nGREEN='\\033[0;32m'\nYELLOW='\\033[1;33m'\nNC='\\033[0m'\ninfo() { echo -e \"${GREEN}[INFO]${NC} $*\"; }\nwarn() { echo -e \"${YELLOW}[WARN]${NC} $*\"; }\nerror() { echo -e \"${RED}[ERROR]${NC} $*\"; exit 1; }\n\n# 1. Kill existing LiteLLM on port 4000\nPID=$(lsof -ti :$LITELLM_PORT 2>/dev/null || true)\nif [[ -n \"$PID\" ]]; then\n warn \"Killing LiteLLM on port $LITELLM_PORT (PID: $PID)...\"\n kill -9 $PID 2>/dev/null || true\n sleep 1\n PID2=$(lsof -ti :$LITELLM_PORT 2>/dev/null || true)\n [[ -n \"$PID2\" ]] && error \"Cannot free port $LITELLM_PORT\"\n info \"Port freed\"\nelse\n info \"Port $LITELLM_PORT free\"\nfi\n\n# 2. Activate venv and source env vars\nsource \"$LITELLM_ENV/bin/activate\"\nsource \"$LITELLM_DIR/init_litellm_env.sh\"\n\n# 3. Start LiteLLM proxy\ninfo \"Starting LiteLLM proxy on port $LITELLM_PORT...\"\nsetsid litellm --config \"$LITELLM_DIR/config.yaml\" --port $LITELLM_PORT \\\n > \"$LITELLM_DIR/proxy.log\" 2>&1 &\ndisown\ninfo \"LiteLLM started (daemon)\"\n\n# 4. Wait for health check\ninfo \"Waiting for proxy...\"\nfor i in $(seq 1 30); do\n if curl -sf -H \"Authorization: Bearer sk-123456\" \\\n \"http://127.0.0.1:$LITELLM_PORT/v1/models\" >/dev/null 2>&1; then\n echo\n info \"Proxy ready at http://127.0.0.1:$LITELLM_PORT\"\n break\n fi\n sleep 1\n printf \".\"\ndone\n\nif ! curl -sf -H \"Authorization: Bearer sk-123456\" \\\n \"http://127.0.0.1:$LITELLM_PORT/v1/models\" >/dev/null 2>&1; then\n echo\n error \"Proxy did not respond in 30s. Check: tail -20 $LITELLM_DIR/proxy.log\"\nfi\n\n# 5. Source Claude env and launch\nsource \"$LITELLM_DIR/init_claude_env.sh\"\ninfo \"Launching Claude Code...\"\ninfo \"\"\ninfo \"Model aliases:\"\ninfo \" claude-3-5-haiku-coding -> deepseek-v4-flash (default)\"\ninfo \" claude-3-5-haiku-20241022 -> deepseek-v3.2 (fast/bg)\"\ninfo \" claude-3-5-sonnet-20241022 -> deepseek-v4-pro (sonnet)\"\ninfo \" claude-3-opus-20240229 -> deepseek-v4-pro (opus)\"\ninfo \"\"\ninfo \"Switch models with: /model <name>\"\ninfo \" e.g. /model deepseek-v4-pro, /model glm-5.2, /model deepseek-r1\"\ninfo \"\"\nclaude\n```\n\n```bash\nchmod +x ~/start_claude.sh\n```\n\n### Step 6: VERIFY\n\nStart the proxy manually and confirm it works:\n\n```bash\nsource ~/litellm-env/bin/activate\nsource ~/litellm/init_litellm_env.sh\nsetsid litellm --config ~/litellm/config.yaml --port 4000 > ~/litellm/proxy.log 2>&1 &\ndisown\n\n# Wait ~10s for startup, then check:\ncurl -s -H \"Authorization: Bearer sk-123456\" http://127.0.0.1:4000/v1/models | python3 -m json.tool\n```\n\nExpected output: a JSON list with 12 model IDs including `claude-3-5-haiku-coding`, `claude-3-5-haiku-20241022`, `claude-3-5-sonnet-20241022`, `claude-3-opus-20240229`, and all 8 MaaS model names.\n\nTest an API call:\n\n```bash\ncurl http://localhost:4000/v1/chat/completions \\\n -H \"Authorization: Bearer sk-123456\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\"model\": \"claude-3-5-haiku-coding\", \"messages\": [{\"role\": \"user\", \"content\": \"Hello\"}]}'\n```\n\nVerify Claude Code:\n\n```bash\nclaude --version\n```\n\n## Generated Files\n\n```\n~/litellm/\n config.yaml # LiteLLM proxy config (4 Claude aliases + 8 MaaS models)\n init_litellm_env.sh # Exports MAAS_API_KEY\n init_claude_env.sh # Sets ANTHROPIC_* env vars for Claude Code\n proxy.log # LiteLLM proxy log (created at runtime)\n\n~/litellm-env/ # Python 3.12 venv with litellm[proxy]\n\n~/start_claude.sh # One-command startup: kill stale -> start proxy -> launch claude\n```\n\n## Daily Usage\n\n```bash\n# Start everything (proxy + Claude Code):\n~/start_claude.sh\n\n# Or manually (two terminals):\n# Terminal 1 - start proxy:\nsource ~/litellm-env/bin/activate\nsource ~/litellm/init_litellm_env.sh\nlitellm --config ~/litellm/config.yaml --port 4000\n\n# Terminal 2 - start Claude Code:\ncd ~/yourproject\nsource ~/litellm/init_claude_env.sh\nclaude\n```\n\n### Switching models in Claude Code\n\nInside a Claude Code conversation, use the `/model` command:\n\n```bash\n/model deepseek-v4-pro # Switch to V4-Pro directly\n/model deepseek-v4-flash # Switch to V4-Flash directly\n/model deepseek-v3.2 # Switch to V3.2 (economical)\n/model glm-5.2 # Switch to GLM-5.2\n/model deepseek-r1 # Switch to DeepSeek-R1 (deep reasoning)\n/model claude-3-5-sonnet-20241022 # Switch to Sonnet alias (-> V4-Pro)\n```\n\nAfter switching, subsequent conversation will use the new model.\n\n## Troubleshooting\n\n| Problem | Solution |\n|---------|----------|\n| `orjson` build fails | System Python is 3.14+. Use `uv venv --python 3.12` to get a compatible venv. |\n| Claude Code still tries to login to Anthropic | `ANTHROPIC_API_KEY` is set. Run `unset ANTHROPIC_API_KEY` and ensure `ANTHROPIC_AUTH_TOKEN` is set correctly. |\n| API call timeout | Network connectivity issue. Increase `API_TIMEOUT_MS` (e.g. `export API_TIMEOUT_MS=600000`). |\n| Authenticate fail | `master_key` in `config.yaml` doesn't match `ANTHROPIC_AUTH_TOKEN` in `init_claude_env.sh`. Make them consistent. |\n| Proxy dies when shell closes | Use `setsid` + `disown` instead of `nohup` alone. |\n| `/health` returns 500 | Known LiteLLM quirk. Use `/v1/models` with auth header for health checks. |\n| \"address already in use\" | Kill stale process: `kill $(lsof -ti :4000)` |\n| `MAAS_API_KEY` not set | Source `init_litellm_env.sh` before starting the proxy. |\n| Model not found | The `model_name` in the error must exist in `config.yaml`. Check spelling and that LiteLLM is running with the correct config file. |\n| `pip install` failure | Python env conflict. Use venv: `python3.12 -m venv ~/litellm-env && source ~/litellm-env/bin/activate` |\n\n```bash\n# View proxy log:\ntail -f ~/litellm/proxy.log\n\n# Check proxy health:\ncurl -s -H \"Authorization: Bearer sk-123456\" http://127.0.0.1:4000/v1/models\n\n# List available models:\ncurl -s -H \"Authorization: Bearer sk-123456\" http://127.0.0.1:4000/v1/models | python3 -m json.tool\n\n# Kill proxy:\nkill $(lsof -ti :4000)\n\n# Full restart:\n~/start_claude.sh\n```\n\n## FAQ\n\n**Q: Why do we need Claude model-name aliases?**\nA: Claude Code validates model names at startup and when switching model tiers (haiku/sonnet/opus). By registering aliases like `claude-3-5-haiku-coding` in LiteLLM's `config.yaml`, Claude Code accepts the model name while LiteLLM transparently routes the request to the actual MaaS model.\n\n**Q: Can I use MaaS model names directly without aliases?**\nA: Yes, for the `/model` switch command (e.g. `/model deepseek-v4-pro`). However, the default model in `ANTHROPIC_MODEL` should use a Claude-recognized name to avoid startup issues. The env vars `ANTHROPIC_DEFAULT_HAIKU_MODEL`, `ANTHROPIC_DEFAULT_SONNET_MODEL`, and `ANTHROPIC_DEFAULT_OPUS_MODEL` must also point to names that exist in `config.yaml`.\n\n**Q: What happened to DeepSeek-V3.1-Terminus?**\nA: It was fully retired on 2026-07-24. DeepSeek-V4-Flash replaces it as the recommended cost-effective model. The DeepSeek API changelog states: \"deepseek-chat & deepseek-reasoner will be fully retired and inaccessible after Jul 24th, 2026.\"\n\n**Q: Why is `unset ANTHROPIC_API_KEY` critical?**\nA: If `ANTHROPIC_API_KEY` is set in the environment (e.g. from a previous Anthropic setup), Claude Code will attempt to authenticate with Anthropic's servers and ignore `ANTHROPIC_AUTH_TOKEN`. Unsetting it forces Claude Code to use the auth token against the proxy.\n\n**Q: What is `drop_params: true`?**\nA: MaaS doesn't support all OpenAI/Anthropic parameters. `drop_params: true` tells LiteLLM to automatically drop unsupported parameters instead of returning an error.\n"}, "f45629e1d1dedc798a0a057f979c7317878df2b1": {"t": 1785765991.363858, "n": 21031, "h": "51fae0154980bc30", "c": "---\nname: claude-code-litellm-maas\ndescription: Configure Claude Code with LiteLLM proxy for Huawei Cloud MaaS models. Covers Node.js/Claude Code installation, venv setup, config generation with Claude model-name aliases, environment variable configuration, startup script, and model switching.\nlicense: MIT\ncompatibility: claude-code\nmetadata:\n audience: infrastructure-engineers\n workflow: claude-code-litellm-maas\n---\n\n# Claude Code + LiteLLM Proxy for Huawei Cloud MaaS\n\nSet up **Claude Code** to use **LiteLLM proxy** as a gateway to Huawei Cloud ModelArts MaaS models. Claude Code sends requests to LiteLLM (localhost:4000), which forwards them to MaaS using the `custom_openai` provider.\n\n**Key technique:** Claude Code validates model names at startup. We register Claude-recognized model names (e.g. `claude-3-5-haiku-coding`) as aliases in LiteLLM's `config.yaml`, mapping them to actual MaaS models (e.g. `deepseek-v4-flash`). Claude Code thinks it's using Claude models; LiteLLM transparently routes to MaaS.\n\n```\nClaude Code → LiteLLM (localhost:4000) → Huawei Cloud MaaS → DeepSeek/GLM models\n```\n\n## Rules\n\n1. **ALWAYS use a Python 3.12 venv** — Python 3.14+ breaks `orjson` which `litellm[proxy]` depends on. Use `uv` to manage the venv if the system Python is too new.\n2. **NEVER hardcode `MAAS_API_KEY` in config.yaml** — use `os.environ/MAAS_API_KEY` so the key stays in env vars only.\n3. **NEVER expose `MAAS_API_KEY` in logs** — LiteLLM logs may contain request details. Keep the key out of shell history by sourcing env scripts instead of passing it inline.\n4. **ALWAYS `unset ANTHROPIC_API_KEY`** — if this env var is set, Claude Code attempts official Anthropic authentication and ignores `ANTHROPIC_AUTH_TOKEN`. This is the #1 cause of \"Claude Code still tries to login to Anthropic\".\n5. **ALWAYS kill existing LiteLLM on port 4000 before starting** — stale processes cause \"address already in use\" errors.\n6. **Use `setsid` + `disown` to daemonize LiteLLM** — `nohup` alone may die when the parent shell exits. `setsid` creates a new session group so the proxy survives.\n7. **ALWAYS register Claude model-name aliases in config.yaml** — Claude Code expects specific model name patterns (`claude-3-5-haiku-*`, `claude-3-5-sonnet-*`, `claude-3-opus-*`). Without these aliases mapped in LiteLLM, Claude Code will fail at startup or when switching model tiers.\n8. **`ANTHROPIC_MODEL` must match a `model_name` in config.yaml** — this is the model Claude Code uses for main responses. If it doesn't match a LiteLLM entry, requests will fail.\n9. **Health check via `/v1/models` with auth header** — the `/health` endpoint returns 500 on some LiteLLM versions even when the proxy is fully functional. `/v1/models` with `Authorization: Bearer <master_key>` is the reliable check.\n\n## Prerequisites\n\n| Requirement | Details |\n|-------------|---------|\n| Node.js 20+ | Required by Claude Code. Install via nodesource setup script if missing. |\n| npm | Comes with Node.js. Used to install `@anthropic-ai/claude-code`. |\n| Python 3.12+ | 3.14+ is NOT supported (orjson build fails). Install via `uv` if needed. |\n| `uv` (recommended) or `pip` | For venv + package management. `uv` handles Python version downloads automatically. |\n| `MAAS_API_KEY` | Huawei Cloud ModelArts API key (create in MaaS console → API Key Management). |\n| `lsof` | For port checking in the startup script. Usually pre-installed on Linux. |\n| `curl` | For health checks and API testing. Pre-installed on most systems. |\n\n**Pre-condition:** An ECS instance on Huawei Cloud with EIP (public IP) for accessing MaaS endpoints. Ubuntu 24.04 used as reference OS.\n\n**Minimum resources:** 512 MB RAM, 200 MB disk (for venv + litellm packages).\n\n## Available MaaS Models (July 2026)\n\n> **Note:** DeepSeek-V3.1-Terminus was fully retired on 2026-07-24. DeepSeek-V4-Flash replaces it as the recommended cost-effective model. Source: [DeepSeek API changelog](https://api-docs.deepseek.com/updates).\n\n| Model | MaaS model ID | Context | Max Output | Deep Thinking | Cost Tier |\n|-------|---------------|---------|------------|---------------|-----------|\n| DeepSeek-V4-Flash | `deepseek-v4-flash` | 1M | 128K | Configurable | $$ |\n| DeepSeek-V4-Pro | `deepseek-v4-pro` | 1M | 128K | Configurable | $$$$ |\n| DeepSeek-V3.2 | `deepseek-v3.2` | 160K | 32K | Configurable | $ |\n| DeepSeek-V3 | `DeepSeek-V3` | 128K | 64K | No | $ |\n| DeepSeek-R1 | `deepseek-r1-250528` | 128K | 32K | Always active | $$$$ |\n| GLM-5.2 | `glm-5.2` | 198K | 128K | Configurable | $$$ |\n| GLM-5.1 | `glm-5.1` | 198K | 128K | Configurable | $$$$ |\n| GLM-5 | `glm-5` | 198K | 64K | Configurable | $$$$ |\n\n## Model Name Aliases\n\nClaude Code sends model names it recognizes. We map these to MaaS models in LiteLLM:\n\n| Claude Code sees (`model_name`) | LiteLLM routes to (`litellm_params.model`) | Env var | Use case |\n|----------------------------------|---------------------------------------------|--------|----------|\n| `claude-3-5-haiku-coding` | `custom_openai/deepseek-v4-flash` | `ANTHROPIC_MODEL` | Default main model |\n| `claude-3-5-haiku-20241022` | `custom_openai/deepseek-v3.2` | `ANTHROPIC_SMALL_FAST_MODEL`, `ANTHROPIC_DEFAULT_HAIKU_MODEL`, `CLAUDE_CODE_SUBAGENT_MODEL` | Background/fast tasks |\n| `claude-3-5-sonnet-20241022` | `custom_openai/deepseek-v4-pro` | `ANTHROPIC_DEFAULT_SONNET_MODEL` | Heavy coding |\n| `claude-3-opus-20240229` | `custom_openai/deepseek-v4-pro` | `ANTHROPIC_DEFAULT_OPUS_MODEL` | Opus tier |\n\nAdditionally, all 8 MaaS models are registered with their real names for direct access via `/model` switching.\n\n## Workflow\n\n### Step 1: CHECK PREREQUISITES\n\nVerify Node.js, Python, and check if Claude Code is already installed:\n\n```bash\nnode --version # Need 20+ (for Claude Code)\npython3 --version # Need 3.12+ (NOT 3.14+)\nwhich claude 2>/dev/null # Check if Claude Code is already installed\nwhich uv || which pip3 # At least one package manager\n```\n\nIf system Python is 3.14+, install `uv` to manage a 3.12 venv:\n\n```bash\ncurl -LsSf https://astral.sh/uv/install.sh | sh\n# uv is now at ~/.local/bin/uv\n```\n\n### Step 2: INSTALL CLAUDE CODE\n\nSkip this step if `claude --version` already returns a version number.\n\n#### 2a. Install Node.js 20 (if missing or too old)\n\n```bash\ncurl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -\nsudo apt-get install -y nodejs\nnode --version # Verify: v20.x.x\n```\n\n#### 2b. Install Claude Code\n\n```bash\nnpm install -g @anthropic-ai/claude-code\nclaude --version # Verify installation\n```\n\n### Step 3: CREATE VENV & INSTALL LITELLM\n\n```bash\n# With uv (recommended — auto-downloads Python 3.12 if needed):\n~/.local/bin/uv venv ~/litellm-env --python 3.12\n~/.local/bin/uv pip install 'litellm[proxy]' --python ~/litellm-env/bin/python\n\n# Or with system Python 3.12:\npython3.12 -m venv ~/litellm-env\nsource ~/litellm-env/bin/activate\npip install 'litellm[proxy]'\n```\n\nVerify:\n\n```bash\nsource ~/litellm-env/bin/activate\npython -c \"import litellm; print('litellm OK')\"\nwhich litellm # Should point to ~/litellm-env/bin/litellm\n```\n\n### Step 4: CREATE CONFIG DIRECTORY & FILES\n\n```bash\nmkdir -p ~/litellm\n```\n\n#### 4a. `~/litellm/config.yaml`\n\nCreate the LiteLLM proxy config with Claude model-name aliases + all MaaS models:\n\n```yaml\n# ============================================================\n# LiteLLM Proxy Config - Claude Code + MaaS (Huawei ModelArts)\n# ============================================================\n# Claude Code sends model names it recognizes (claude-3-5-haiku-*,\n# claude-3-5-sonnet-*, claude-3-opus-*). We map these to actual\n# MaaS models. All 8 MaaS models are also available directly.\n#\n# Available models (July 2026):\n# Deep Thinking configurable: glm-5.2, glm-5.1, glm-5,\n# deepseek-v4-pro, deepseek-v4-flash, deepseek-v3.2\n# Deep Thinking always active: deepseek-r1-250528\n# Without Deep Thinking: DeepSeek-V3\n#\n# Retired: deepseek-v3.1-terminus (fully retired 2026-07-24)\n#\n# Cost order (cheap -> expensive):\n# v3.2 < V3 < v4-flash < glm-5.2 < glm-5.1 < glm-5 < v4-pro < r1\n\nmodel_list:\n # ===============================================================\n # Claude model-name aliases (what Claude Code expects to see)\n # ===============================================================\n\n # Default main model: Claude Code thinks it's Haiku, uses V4-Flash\n - model_name: claude-3-5-haiku-coding\n litellm_params:\n model: custom_openai/deepseek-v4-flash\n api_base: https://api-ap-southeast-1.modelarts-maas.com/openai/v1\n api_key: os.environ/MAAS_API_KEY\n\n # Fast/background model: Claude Code thinks Haiku, uses V3.2\n - model_name: claude-3-5-haiku-20241022\n litellm_params:\n model: custom_openai/deepseek-v3.2\n api_base: https://api-ap-southeast-1.modelarts-maas.com/openai/v1\n api_key: os.environ/MAAS_API_KEY\n\n # Sonnet tier: Claude Code thinks Sonnet, uses V4-Pro\n - model_name: claude-3-5-sonnet-20241022\n litellm_params:\n model: custom_openai/deepseek-v4-pro\n api_base: https://api-ap-southeast-1.modelarts-maas.com/openai/v1\n api_key: os.environ/MAAS_API_KEY\n\n # Opus tier: Claude Code thinks Opus, uses V4-Pro\n - model_name: claude-3-opus-20240229\n litellm_params:\n model: custom_openai/deepseek-v4-pro\n api_base: https://api-ap-southeast-1.modelarts-maas.com/openai/v1\n api_key: os.environ/MAAS_API_KEY\n\n # ===============================================================\n # Direct MaaS model access (switch with /model <name>)\n # ===============================================================\n\n - model_name: deepseek-v4-flash\n litellm_params:\n model: custom_openai/deepseek-v4-flash\n api_base: https://api-ap-southeast-1.modelarts-maas.com/openai/v1\n api_key: os.environ/MAAS_API_KEY\n\n - model_name: deepseek-v4-pro\n litellm_params:\n model: custom_openai/deepseek-v4-pro\n api_base: https://api-ap-southeast-1.modelarts-maas.com/openai/v1\n api_key: os.environ/MAAS_API_KEY\n\n - model_name: deepseek-v3.2\n litellm_params:\n model: custom_openai/deepseek-v3.2\n api_base: https://api-ap-southeast-1.modelarts-maas.com/openai/v1\n api_key: os.environ/MAAS_API_KEY\n\n - model_name: deepseek-v3\n litellm_params:\n model: custom_openai/DeepSeek-V3\n api_base: https://api-ap-southeast-1.modelarts-maas.com/openai/v1\n api_key: os.environ/MAAS_API_KEY\n\n - model_name: deepseek-r1\n litellm_params:\n model: custom_openai/deepseek-r1-250528\n api_base: https://api-ap-southeast-1.modelarts-maas.com/openai/v1\n api_key: os.environ/MAAS_API_KEY\n\n - model_name: glm-5.2\n litellm_params:\n model: custom_openai/glm-5.2\n api_base: https://api-ap-southeast-1.modelarts-maas.com/openai/v1\n api_key: os.environ/MAAS_API_KEY\n\n - model_name: glm-5.1\n litellm_params:\n model: custom_openai/glm-5.1\n api_base: https://api-ap-southeast-1.modelarts-maas.com/openai/v1\n api_key: os.environ/MAAS_API_KEY\n\n - model_name: glm-5\n litellm_params:\n model: custom_openai/glm-5\n api_base: https://api-ap-southeast-1.modelarts-maas.com/openai/v1\n api_key: os.environ/MAAS_API_KEY\n\nlitellm_settings:\n drop_params: true # auto drop params MaaS doesn't support\n\ngeneral_settings:\n master_key: sk-123456\n```\n\n#### 4b. `~/litellm/init_litellm_env.sh`\n\nExports the MaaS API key. **Replace the placeholder with your actual key.**\n\n```bash\n#!/bin/bash\n# Source before starting LiteLLM:\n# source ~/litellm/init_litellm_env.sh && litellm --config ~/litellm/config.yaml --port 4000\nexport MAAS_API_KEY=\"<YOUR_MAAS_API_KEY>\"\n```\n\n```bash\nchmod +x ~/litellm/init_litellm_env.sh\n```\n\n#### 4c. `~/litellm/init_claude_env.sh`\n\nSets environment variables so Claude Code talks to the local LiteLLM proxy instead of Anthropic's servers:\n\n```bash\n#!/bin/bash\n# Source before starting Claude Code:\n# source ~/litellm/init_claude_env.sh && claude\n\n# ── LiteLLM master key (must match master_key in config.yaml) ──\nexport LITELLM_MASTER_KEY=\"sk-123456\"\n\n# ── Huawei Cloud MaaS API key ──\nsource ~/litellm/init_litellm_env.sh\n\n# ── Claude Code → LiteLLM proxy ──\nexport ANTHROPIC_BASE_URL=\"http://127.0.0.1:4000\"\nexport ANTHROPIC_AUTH_TOKEN=\"$LITELLM_MASTER_KEY\"\n\n# ── Model mapping (all names must exist in config.yaml) ──\nexport ANTHROPIC_MODEL=\"claude-3-5-haiku-coding\" # → deepseek-v4-flash\nexport ANTHROPIC_SMALL_FAST_MODEL=\"claude-3-5-haiku-20241022\" # → deepseek-v3.2\nexport ANTHROPIC_DEFAULT_HAIKU_MODEL=\"claude-3-5-haiku-20241022\" # → deepseek-v3.2\nexport ANTHROPIC_DEFAULT_SONNET_MODEL=\"claude-3-5-sonnet-20241022\" # → deepseek-v4-pro\nexport ANTHROPIC_DEFAULT_OPUS_MODEL=\"claude-3-opus-20240229\" # → deepseek-v4-pro\nexport CLAUDE_CODE_SUBAGENT_MODEL=\"claude-3-5-haiku-20241022\" # → deepseek-v3.2\n\n# ── CRITICAL: unset official Anthropic auth ──\n# Without this, Claude Code tries to login to Anthropic and ignores ANTHROPIC_AUTH_TOKEN\nunset ANTHROPIC_API_KEY\n\n# ── API timeout (ms) ──\nexport API_TIMEOUT_MS=600000\n\n# ── Disable non-essential traffic (optional, reduces noise) ──\nexport CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1\n```\n\n```bash\nchmod +x ~/litellm/init_claude_env.sh\n```\n\n### Step 5: CREATE STARTUP SCRIPT\n\nCreate `~/start_claude.sh` — kills any stale proxy, starts LiteLLM, waits for it to be ready, then launches Claude Code:\n\n```bash\n#!/bin/bash\nset -euo pipefail\n\nLITELLM_DIR=\"$HOME/litellm\"\nLITELLM_ENV=\"$HOME/litellm-env\"\nLITELLM_PORT=4000\n\nRED='\\033[0;31m'\nGREEN='\\033[0;32m'\nYELLOW='\\033[1;33m'\nNC='\\033[0m'\ninfo() { echo -e \"${GREEN}[INFO]${NC} $*\"; }\nwarn() { echo -e \"${YELLOW}[WARN]${NC} $*\"; }\nerror() { echo -e \"${RED}[ERROR]${NC} $*\"; exit 1; }\n\n# 1. Kill existing LiteLLM on port 4000\nPID=$(lsof -ti :$LITELLM_PORT 2>/dev/null || true)\nif [[ -n \"$PID\" ]]; then\n warn \"Killing LiteLLM on port $LITELLM_PORT (PID: $PID)...\"\n kill -9 $PID 2>/dev/null || true\n sleep 1\n PID2=$(lsof -ti :$LITELLM_PORT 2>/dev/null || true)\n [[ -n \"$PID2\" ]] && error \"Cannot free port $LITELLM_PORT\"\n info \"Port freed\"\nelse\n info \"Port $LITELLM_PORT free\"\nfi\n\n# 2. Activate venv and source env vars\nsource \"$LITELLM_ENV/bin/activate\"\nsource \"$LITELLM_DIR/init_litellm_env.sh\"\n\n# 3. Start LiteLLM proxy\ninfo \"Starting LiteLLM proxy on port $LITELLM_PORT...\"\nsetsid litellm --config \"$LITELLM_DIR/config.yaml\" --port $LITELLM_PORT \\\n > \"$LITELLM_DIR/proxy.log\" 2>&1 &\ndisown\ninfo \"LiteLLM started (daemon)\"\n\n# 4. Wait for health check\ninfo \"Waiting for proxy...\"\nfor i in $(seq 1 30); do\n if curl -sf -H \"Authorization: Bearer sk-123456\" \\\n \"http://127.0.0.1:$LITELLM_PORT/v1/models\" >/dev/null 2>&1; then\n echo\n info \"Proxy ready at http://127.0.0.1:$LITELLM_PORT\"\n break\n fi\n sleep 1\n printf \".\"\ndone\n\nif ! curl -sf -H \"Authorization: Bearer sk-123456\" \\\n \"http://127.0.0.1:$LITELLM_PORT/v1/models\" >/dev/null 2>&1; then\n echo\n error \"Proxy did not respond in 30s. Check: tail -20 $LITELLM_DIR/proxy.log\"\nfi\n\n# 5. Source Claude env and launch\nsource \"$LITELLM_DIR/init_claude_env.sh\"\ninfo \"Launching Claude Code...\"\ninfo \"\"\ninfo \"Model aliases:\"\ninfo \" claude-3-5-haiku-coding -> deepseek-v4-flash (default)\"\ninfo \" claude-3-5-haiku-20241022 -> deepseek-v3.2 (fast/bg)\"\ninfo \" claude-3-5-sonnet-20241022 -> deepseek-v4-pro (sonnet)\"\ninfo \" claude-3-opus-20240229 -> deepseek-v4-pro (opus)\"\ninfo \"\"\ninfo \"Switch models with: /model <name>\"\ninfo \" e.g. /model deepseek-v4-pro, /model glm-5.2, /model deepseek-r1\"\ninfo \"\"\nclaude\n```\n\n```bash\nchmod +x ~/start_claude.sh\n```\n\n### Step 6: VERIFY\n\nStart the proxy manually and confirm it works:\n\n```bash\nsource ~/litellm-env/bin/activate\nsource ~/litellm/init_litellm_env.sh\nsetsid litellm --config ~/litellm/config.yaml --port 4000 > ~/litellm/proxy.log 2>&1 &\ndisown\n\n# Wait ~10s for startup, then check:\ncurl -s -H \"Authorization: Bearer sk-123456\" http://127.0.0.1:4000/v1/models | python3 -m json.tool\n```\n\nExpected output: a JSON list with 12 model IDs including `claude-3-5-haiku-coding`, `claude-3-5-haiku-20241022`, `claude-3-5-sonnet-20241022`, `claude-3-opus-20240229`, and all 8 MaaS model names.\n\nTest an API call:\n\n```bash\ncurl http://localhost:4000/v1/chat/completions \\\n -H \"Authorization: Bearer sk-123456\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\"model\": \"claude-3-5-haiku-coding\", \"messages\": [{\"role\": \"user\", \"content\": \"Hello\"}]}'\n```\n\nVerify Claude Code:\n\n```bash\nclaude --version\n```\n\n## Generated Files\n\n```\n~/litellm/\n config.yaml # LiteLLM proxy config (4 Claude aliases + 8 MaaS models)\n init_litellm_env.sh # Exports MAAS_API_KEY\n init_claude_env.sh # Sets ANTHROPIC_* env vars for Claude Code\n proxy.log # LiteLLM proxy log (created at runtime)\n\n~/litellm-env/ # Python 3.12 venv with litellm[proxy]\n\n~/start_claude.sh # One-command startup: kill stale -> start proxy -> launch claude\n```\n\n## Daily Usage\n\n```bash\n# Start everything (proxy + Claude Code):\n~/start_claude.sh\n\n# Or manually (two terminals):\n# Terminal 1 - start proxy:\nsource ~/litellm-env/bin/activate\nsource ~/litellm/init_litellm_env.sh\nlitellm --config ~/litellm/config.yaml --port 4000\n\n# Terminal 2 - start Claude Code:\ncd ~/yourproject\nsource ~/litellm/init_claude_env.sh\nclaude\n```\n\n### Switching models in Claude Code\n\nInside a Claude Code conversation, use the `/model` command:\n\n```bash\n/model deepseek-v4-pro # Switch to V4-Pro directly\n/model deepseek-v4-flash # Switch to V4-Flash directly\n/model deepseek-v3.2 # Switch to V3.2 (economical)\n/model glm-5.2 # Switch to GLM-5.2\n/model deepseek-r1 # Switch to DeepSeek-R1 (deep reasoning)\n/model claude-3-5-sonnet-20241022 # Switch to Sonnet alias (-> V4-Pro)\n```\n\nAfter switching, subsequent conversation will use the new model.\n\n## Troubleshooting\n\n| Problem | Solution |\n|---------|----------|\n| `orjson` build fails | System Python is 3.14+. Use `uv venv --python 3.12` to get a compatible venv. |\n| Claude Code still tries to login to Anthropic | `ANTHROPIC_API_KEY` is set. Run `unset ANTHROPIC_API_KEY` and ensure `ANTHROPIC_AUTH_TOKEN` is set correctly. |\n| API call timeout | Network connectivity issue. Increase `API_TIMEOUT_MS` (e.g. `export API_TIMEOUT_MS=600000`). |\n| Authenticate fail | `master_key` in `config.yaml` doesn't match `ANTHROPIC_AUTH_TOKEN` in `init_claude_env.sh`. Make them consistent. |\n| Proxy dies when shell closes | Use `setsid` + `disown` instead of `nohup` alone. |\n| `/health` returns 500 | Known LiteLLM quirk. Use `/v1/models` with auth header for health checks. |\n| \"address already in use\" | Kill stale process: `kill $(lsof -ti :4000)` |\n| `MAAS_API_KEY` not set | Source `init_litellm_env.sh` before starting the proxy. |\n| Model not found | The `model_name` in the error must exist in `config.yaml`. Check spelling and that LiteLLM is running with the correct config file. |\n| `pip install` failure | Python env conflict. Use venv: `python3.12 -m venv ~/litellm-env && source ~/litellm-env/bin/activate` |\n\n```bash\n# View proxy log:\ntail -f ~/litellm/proxy.log\n\n# Check proxy health:\ncurl -s -H \"Authorization: Bearer sk-123456\" http://127.0.0.1:4000/v1/models\n\n# List available models:\ncurl -s -H \"Authorization: Bearer sk-123456\" http://127.0.0.1:4000/v1/models | python3 -m json.tool\n\n# Kill proxy:\nkill $(lsof -ti :4000)\n\n# Full restart:\n~/start_claude.sh\n```\n\n## FAQ\n\n**Q: Why do we need Claude model-name aliases?**\nA: Claude Code validates model names at startup and when switching model tiers (haiku/sonnet/opus). By registering aliases like `claude-3-5-haiku-coding` in LiteLLM's `config.yaml`, Claude Code accepts the model name while LiteLLM transparently routes the request to the actual MaaS model.\n\n**Q: Can I use MaaS model names directly without aliases?**\nA: Yes, for the `/model` switch command (e.g. `/model deepseek-v4-pro`). However, the default model in `ANTHROPIC_MODEL` should use a Claude-recognized name to avoid startup issues. The env vars `ANTHROPIC_DEFAULT_HAIKU_MODEL`, `ANTHROPIC_DEFAULT_SONNET_MODEL`, and `ANTHROPIC_DEFAULT_OPUS_MODEL` must also point to names that exist in `config.yaml`.\n\n**Q: What happened to DeepSeek-V3.1-Terminus?**\nA: It was fully retired on 2026-07-24. DeepSeek-V4-Flash replaces it as the recommended cost-effective model. The DeepSeek API changelog states: \"deepseek-chat & deepseek-reasoner will be fully retired and inaccessible after Jul 24th, 2026.\"\n\n**Q: Why is `unset ANTHROPIC_API_KEY` critical?**\nA: If `ANTHROPIC_API_KEY` is set in the environment (e.g. from a previous Anthropic setup), Claude Code will attempt to authenticate with Anthropic's servers and ignore `ANTHROPIC_AUTH_TOKEN`. Unsetting it forces Claude Code to use the auth token against the proxy.\n\n**Q: What is `drop_params: true`?**\nA: MaaS doesn't support all OpenAI/Anthropic parameters. `drop_params: true` tells LiteLLM to automatically drop unsupported parameters instead of returning an error.\n"}}, "AI/AI-Coding/Enterprise-MaaS-Foundation/LiteLLM-Huawei-MaaS-Proxy/assets/config/litellm_config.yaml.example": {"dfd489984a277403e3ffedcfee1fb136579dabf3": {"t": 1785746847.7533195, "n": 8432, "h": "b03a650805faf26f", "c": "# ─────────────────────────────────────────────────────────────────────────────\n# LiteLLM Config Example (Single-Key Reference)\n#\n# This is a REFERENCE example showing single-key configuration.\n# The actual config is GENERATED by scripts/generate_config.sh which creates\n# N deployments per model (one for each HUAWEI_MAAS_API_KEY_N).\n#\n# Do NOT edit this file directly. Instead:\n# 1. Run scripts/init_env.sh to set up .env with your MaaS API keys\n# 2. Run scripts/generate_config.sh to generate the actual config\n#\n# Generated config will use: os.environ/HUAWEI_MAAS_API_KEY_0, _1, _2, etc.\n#\n# The generator also emits, to match the production deployment:\n# • rolling_budget_hook.proxy_handler_instance — three-tier rolling-window\n# budget (BUDGET_TIER_* env; effectively unlimited until those are set).\n# • search_tools (exa-search) + the websearch_interception callback —\n# ONLY when EXA_API_KEY is set (shown commented below).\n# • proxy_batch_write_at: 1 — near-real-time spend so the budget hook is timely.\n#\n# The optional BR fintech DLP guardrails are NOT generated (they require the\n# external risk-control module to be mounted first) — see the commented\n# \"guardrails:\" reference block near the end and references/operations.md.\n# ─────────────────────────────────────────────────────────────────────────────\n\nmodel_list:\n\n # ───────── OpenRouter Vision Models (image requests auto-routed here) ─────────\n\n - model_name: vision-openrouter\n litellm_params:\n model: openrouter/openai/gpt-4o\n api_key: os.environ/OpenRouter_API_KEY\n api_base: https://openrouter.ai/api/v1\n tpm: 800000\n rpm: 100\n model_info:\n supports_vision: true\n max_tokens: 16384\n max_input_tokens: 128000\n max_output_tokens: 16384\n input_cost_per_token: 0.0000025\n output_cost_per_token: 0.00001\n\n - model_name: vision-openrouter\n litellm_params:\n model: openrouter/anthropic/claude-opus-4\n api_key: os.environ/OpenRouter_API_KEY\n api_base: https://openrouter.ai/api/v1\n tpm: 400000\n rpm: 50\n model_info:\n supports_vision: true\n max_tokens: 32000\n max_input_tokens: 200000\n max_output_tokens: 32000\n input_cost_per_token: 0.000015\n output_cost_per_token: 0.000075\n\n # ───────── Huawei MaaS Models (1 deployment(s) per model, 7 total) ───────────\n\n - model_name: glm-5.1\n litellm_params:\n model: openai/glm-5.1\n api_base: os.environ/HUAWEI_MAAS_API_BASE\n api_key: os.environ/HUAWEI_MAAS_API_KEY_0\n tpm: 500000\n rpm: 30\n model_info:\n max_tokens: 198000\n max_input_tokens: 192000\n max_output_tokens: 128000\n input_cost_per_token: 0.000001078\n output_cost_per_token: 0.000003774\n\n - model_name: claude-opus-4-6\n litellm_params:\n model: openai/glm-5.1\n api_base: os.environ/HUAWEI_MAAS_API_BASE\n api_key: os.environ/HUAWEI_MAAS_API_KEY_0\n tpm: 500000\n rpm: 30\n model_info:\n max_tokens: 198000\n max_input_tokens: 192000\n max_output_tokens: 128000\n input_cost_per_token: 0.000001078\n output_cost_per_token: 0.000003774\n\n - model_name: claude-glm1\n litellm_params:\n model: openai/glm-5.1\n api_base: os.environ/HUAWEI_MAAS_API_BASE\n api_key: os.environ/HUAWEI_MAAS_API_KEY_0\n tpm: 500000\n rpm: 30\n model_info:\n max_tokens: 198000\n max_input_tokens: 192000\n max_output_tokens: 128000\n input_cost_per_token: 0.000001078\n output_cost_per_token: 0.000003774\n\n - model_name: glm-5\n litellm_params:\n model: openai/glm-5\n api_base: os.environ/HUAWEI_MAAS_API_BASE\n api_key: os.environ/HUAWEI_MAAS_API_KEY_0\n tpm: 500000\n rpm: 30\n model_info:\n max_tokens: 198000\n max_input_tokens: 192000\n max_output_tokens: 64000\n input_cost_per_token: 0.000000809\n output_cost_per_token: 0.000002965\n\n - model_name: deepseek-v4-pro\n litellm_params:\n model: openai/deepseek-v4-pro\n api_base: os.environ/HUAWEI_MAAS_API_BASE\n api_key: os.environ/HUAWEI_MAAS_API_KEY_0\n tpm: 30000\n rpm: 3\n model_info:\n max_tokens: 1000000\n max_input_tokens: 1000000\n max_output_tokens: 128000\n input_cost_per_token: 0.000001617\n output_cost_per_token: 0.000003235\n\n - model_name: deepseek-v4-flash\n litellm_params:\n model: openai/deepseek-v4-flash\n api_base: os.environ/HUAWEI_MAAS_API_BASE\n api_key: os.environ/HUAWEI_MAAS_API_KEY_0\n tpm: 30000\n rpm: 3\n model_info:\n max_tokens: 1000000\n max_input_tokens: 1000000\n max_output_tokens: 128000\n input_cost_per_token: 0.000000135\n output_cost_per_token: 0.00000027\n\n - model_name: deepseek-v3.2\n litellm_params:\n model: openai/deepseek-v3.2\n api_base: os.environ/HUAWEI_MAAS_API_BASE\n api_key: os.environ/HUAWEI_MAAS_API_KEY_0\n tpm: 500000\n rpm: 700\n model_info:\n max_tokens: 160000\n max_input_tokens: 128000\n max_output_tokens: 32000\n input_cost_per_token: 0.00000027\n output_cost_per_token: 0.000000404\n\n# ── Optional: Exa search tool (emitted by the generator only when EXA_API_KEY set) ──\n# search_tools:\n# - search_tool_name: exa-search\n# litellm_params:\n# search_provider: exa_ai\n# api_key: os.environ/EXA_API_KEY\n\nlitellm_settings:\n num_retries: 3 # retry call 3 times within same deployment\n request_timeout: 600 # raise TimeoutError if full request takes longer than 600s (default)\n stream_timeout: 60 # raise TimeoutError if first token takes longer than 60s (TTFT only)\n drop_params: True\n set_verbose: False\n callbacks:\n - \"prometheus\"\n - custom_callbacks.my_prometheus_logger\n - rolling_budget_hook.proxy_handler_instance\n # Added by the generator only when EXA_API_KEY is set:\n # - \"websearch_interception\"\n ui_theme_config:\n logo_url: \"https://upload.wikimedia.org/wikipedia/en/thumb/0/04/Huawei_Standard_logo.svg/3840px-Huawei_Standard_logo.svg.png\"\n favicon_url: \"https://upload.wikimedia.org/wikipedia/en/thumb/0/04/Huawei_Standard_logo.svg/3840px-Huawei_Standard_logo.svg.png\"\n # Added by the generator only when EXA_API_KEY is set:\n # websearch_interception_params:\n # enabled_providers: [\"openai\"]\n # search_tool_name: \"exa-search\"\n\n# ── Optional: BR fintech DLP guardrails (external risk-control project) ──────────\n# Reference of the production layering. NOT enabled by default: the\n# br_dlp_guardrail module + presidio service must be mounted/running first\n# (see docker-compose.yml commented mounts and references/operations.md).\n# All guardrails use default_on: false → they fire only when a request carries\n# `guardrails: [...]`, so the core stack is unaffected if you leave this out.\n#\n# guardrails:\n# - guardrail_name: secrets-filter # L1: built-in content filter (API keys/JWT/private keys)\n# litellm_params:\n# guardrail: litellm_content_filter\n# mode: pre_call\n# default_on: false\n# patterns:\n# - {pattern_type: prebuilt, pattern_name: generic_api_key, action: BLOCK}\n# - {pattern_type: prebuilt, pattern_name: github_token, action: BLOCK}\n# - guardrail_name: br-dlp-input # L2: Brazilian entity DLP (input)\n# litellm_params:\n# guardrail: br_dlp_guardrail.BrazilDLPGuardrail\n# mode: pre_call\n# default_on: false\n# - guardrail_name: br-pii-presidio # L2: Presidio + pt NLP (PERSON/LOCATION)\n# litellm_params:\n# guardrail: presidio\n# mode: pre_call\n# default_on: false\n# presidio_language: pt\n# pii_entities_config: {PERSON: MASK, LOCATION: MASK}\n# presidio_score_thresholds: {PERSON: 0.80, LOCATION: 0.80}\n# - guardrail_name: br-dlp-output # must register LAST (appends privacy banner)\n# litellm_params:\n# guardrail: br_dlp_guardrail.BrazilDLPGuardrail\n# mode: post_call\n# default_on: false\n\nrouter_settings:\n routing_strategy: simple-shuffle\n num_retries: 3\n cooldown_time: 30 # seconds to cool down a failed deployment\n allowed_fails: 3 # failures before cooldown kicks in\n\ngeneral_settings:\n database_connection_pool_limit: 10\n database_connection_timeout: 60\n # Flush spend logs quickly so the rolling-budget hook sees near-real-time spend\n # (default is 10s). Hour/day-scale production windows tolerate raising this back.\n proxy_batch_write_at: 1\n"}, "8c5233f7d93916d582471d3070069e5f6a72dd62": {"t": 1785765990.2974656, "n": 8432, "h": "b03a650805faf26f", "c": "# ─────────────────────────────────────────────────────────────────────────────\n# LiteLLM Config Example (Single-Key Reference)\n#\n# This is a REFERENCE example showing single-key configuration.\n# The actual config is GENERATED by scripts/generate_config.sh which creates\n# N deployments per model (one for each HUAWEI_MAAS_API_KEY_N).\n#\n# Do NOT edit this file directly. Instead:\n# 1. Run scripts/init_env.sh to set up .env with your MaaS API keys\n# 2. Run scripts/generate_config.sh to generate the actual config\n#\n# Generated config will use: os.environ/HUAWEI_MAAS_API_KEY_0, _1, _2, etc.\n#\n# The generator also emits, to match the production deployment:\n# • rolling_budget_hook.proxy_handler_instance — three-tier rolling-window\n# budget (BUDGET_TIER_* env; effectively unlimited until those are set).\n# • search_tools (exa-search) + the websearch_interception callback —\n# ONLY when EXA_API_KEY is set (shown commented below).\n# • proxy_batch_write_at: 1 — near-real-time spend so the budget hook is timely.\n#\n# The optional BR fintech DLP guardrails are NOT generated (they require the\n# external risk-control module to be mounted first) — see the commented\n# \"guardrails:\" reference block near the end and references/operations.md.\n# ─────────────────────────────────────────────────────────────────────────────\n\nmodel_list:\n\n # ───────── OpenRouter Vision Models (image requests auto-routed here) ─────────\n\n - model_name: vision-openrouter\n litellm_params:\n model: openrouter/openai/gpt-4o\n api_key: os.environ/OpenRouter_API_KEY\n api_base: https://openrouter.ai/api/v1\n tpm: 800000\n rpm: 100\n model_info:\n supports_vision: true\n max_tokens: 16384\n max_input_tokens: 128000\n max_output_tokens: 16384\n input_cost_per_token: 0.0000025\n output_cost_per_token: 0.00001\n\n - model_name: vision-openrouter\n litellm_params:\n model: openrouter/anthropic/claude-opus-4\n api_key: os.environ/OpenRouter_API_KEY\n api_base: https://openrouter.ai/api/v1\n tpm: 400000\n rpm: 50\n model_info:\n supports_vision: true\n max_tokens: 32000\n max_input_tokens: 200000\n max_output_tokens: 32000\n input_cost_per_token: 0.000015\n output_cost_per_token: 0.000075\n\n # ───────── Huawei MaaS Models (1 deployment(s) per model, 7 total) ───────────\n\n - model_name: glm-5.1\n litellm_params:\n model: openai/glm-5.1\n api_base: os.environ/HUAWEI_MAAS_API_BASE\n api_key: os.environ/HUAWEI_MAAS_API_KEY_0\n tpm: 500000\n rpm: 30\n model_info:\n max_tokens: 198000\n max_input_tokens: 192000\n max_output_tokens: 128000\n input_cost_per_token: 0.000001078\n output_cost_per_token: 0.000003774\n\n - model_name: claude-opus-4-6\n litellm_params:\n model: openai/glm-5.1\n api_base: os.environ/HUAWEI_MAAS_API_BASE\n api_key: os.environ/HUAWEI_MAAS_API_KEY_0\n tpm: 500000\n rpm: 30\n model_info:\n max_tokens: 198000\n max_input_tokens: 192000\n max_output_tokens: 128000\n input_cost_per_token: 0.000001078\n output_cost_per_token: 0.000003774\n\n - model_name: claude-glm1\n litellm_params:\n model: openai/glm-5.1\n api_base: os.environ/HUAWEI_MAAS_API_BASE\n api_key: os.environ/HUAWEI_MAAS_API_KEY_0\n tpm: 500000\n rpm: 30\n model_info:\n max_tokens: 198000\n max_input_tokens: 192000\n max_output_tokens: 128000\n input_cost_per_token: 0.000001078\n output_cost_per_token: 0.000003774\n\n - model_name: glm-5\n litellm_params:\n model: openai/glm-5\n api_base: os.environ/HUAWEI_MAAS_API_BASE\n api_key: os.environ/HUAWEI_MAAS_API_KEY_0\n tpm: 500000\n rpm: 30\n model_info:\n max_tokens: 198000\n max_input_tokens: 192000\n max_output_tokens: 64000\n input_cost_per_token: 0.000000809\n output_cost_per_token: 0.000002965\n\n - model_name: deepseek-v4-pro\n litellm_params:\n model: openai/deepseek-v4-pro\n api_base: os.environ/HUAWEI_MAAS_API_BASE\n api_key: os.environ/HUAWEI_MAAS_API_KEY_0\n tpm: 30000\n rpm: 3\n model_info:\n max_tokens: 1000000\n max_input_tokens: 1000000\n max_output_tokens: 128000\n input_cost_per_token: 0.000001617\n output_cost_per_token: 0.000003235\n\n - model_name: deepseek-v4-flash\n litellm_params:\n model: openai/deepseek-v4-flash\n api_base: os.environ/HUAWEI_MAAS_API_BASE\n api_key: os.environ/HUAWEI_MAAS_API_KEY_0\n tpm: 30000\n rpm: 3\n model_info:\n max_tokens: 1000000\n max_input_tokens: 1000000\n max_output_tokens: 128000\n input_cost_per_token: 0.000000135\n output_cost_per_token: 0.00000027\n\n - model_name: deepseek-v3.2\n litellm_params:\n model: openai/deepseek-v3.2\n api_base: os.environ/HUAWEI_MAAS_API_BASE\n api_key: os.environ/HUAWEI_MAAS_API_KEY_0\n tpm: 500000\n rpm: 700\n model_info:\n max_tokens: 160000\n max_input_tokens: 128000\n max_output_tokens: 32000\n input_cost_per_token: 0.00000027\n output_cost_per_token: 0.000000404\n\n# ── Optional: Exa search tool (emitted by the generator only when EXA_API_KEY set) ──\n# search_tools:\n# - search_tool_name: exa-search\n# litellm_params:\n# search_provider: exa_ai\n# api_key: os.environ/EXA_API_KEY\n\nlitellm_settings:\n num_retries: 3 # retry call 3 times within same deployment\n request_timeout: 600 # raise TimeoutError if full request takes longer than 600s (default)\n stream_timeout: 60 # raise TimeoutError if first token takes longer than 60s (TTFT only)\n drop_params: True\n set_verbose: False\n callbacks:\n - \"prometheus\"\n - custom_callbacks.my_prometheus_logger\n - rolling_budget_hook.proxy_handler_instance\n # Added by the generator only when EXA_API_KEY is set:\n # - \"websearch_interception\"\n ui_theme_config:\n logo_url: \"https://upload.wikimedia.org/wikipedia/en/thumb/0/04/Huawei_Standard_logo.svg/3840px-Huawei_Standard_logo.svg.png\"\n favicon_url: \"https://upload.wikimedia.org/wikipedia/en/thumb/0/04/Huawei_Standard_logo.svg/3840px-Huawei_Standard_logo.svg.png\"\n # Added by the generator only when EXA_API_KEY is set:\n # websearch_interception_params:\n # enabled_providers: [\"openai\"]\n # search_tool_name: \"exa-search\"\n\n# ── Optional: BR fintech DLP guardrails (external risk-control project) ──────────\n# Reference of the production layering. NOT enabled by default: the\n# br_dlp_guardrail module + presidio service must be mounted/running first\n# (see docker-compose.yml commented mounts and references/operations.md).\n# All guardrails use default_on: false → they fire only when a request carries\n# `guardrails: [...]`, so the core stack is unaffected if you leave this out.\n#\n# guardrails:\n# - guardrail_name: secrets-filter # L1: built-in content filter (API keys/JWT/private keys)\n# litellm_params:\n# guardrail: litellm_content_filter\n# mode: pre_call\n# default_on: false\n# patterns:\n# - {pattern_type: prebuilt, pattern_name: generic_api_key, action: BLOCK}\n# - {pattern_type: prebuilt, pattern_name: github_token, action: BLOCK}\n# - guardrail_name: br-dlp-input # L2: Brazilian entity DLP (input)\n# litellm_params:\n# guardrail: br_dlp_guardrail.BrazilDLPGuardrail\n# mode: pre_call\n# default_on: false\n# - guardrail_name: br-pii-presidio # L2: Presidio + pt NLP (PERSON/LOCATION)\n# litellm_params:\n# guardrail: presidio\n# mode: pre_call\n# default_on: false\n# presidio_language: pt\n# pii_entities_config: {PERSON: MASK, LOCATION: MASK}\n# presidio_score_thresholds: {PERSON: 0.80, LOCATION: 0.80}\n# - guardrail_name: br-dlp-output # must register LAST (appends privacy banner)\n# litellm_params:\n# guardrail: br_dlp_guardrail.BrazilDLPGuardrail\n# mode: post_call\n# default_on: false\n\nrouter_settings:\n routing_strategy: simple-shuffle\n num_retries: 3\n cooldown_time: 30 # seconds to cool down a failed deployment\n allowed_fails: 3 # failures before cooldown kicks in\n\ngeneral_settings:\n database_connection_pool_limit: 10\n database_connection_timeout: 60\n # Flush spend logs quickly so the rolling-budget hook sees near-real-time spend\n # (default is 10s). Hour/day-scale production windows tolerate raising this back.\n proxy_batch_write_at: 1\n"}, "52cdd6365603db5ea7e8ef3cadd754e48b6f312d": {"t": 1785765991.8214955, "n": 5382, "h": "e38522ec517d89ab", "c": "# ─────────────────────────────────────────────────────────────────────────────\n# LiteLLM Config Example (Single-Key Reference)\n#\n# This is a REFERENCE example showing single-key configuration.\n# The actual config is GENERATED by scripts/generate_config.sh which creates\n# N deployments per model (one for each HUAWEI_MAAS_API_KEY_N).\n#\n# Do NOT edit this file directly. Instead:\n# 1. Run scripts/init_env.sh to set up .env with your MaaS API keys\n# 2. Run scripts/generate_config.sh to generate the actual config\n#\n# Generated config will use: os.environ/HUAWEI_MAAS_API_KEY_0, _1, _2, etc.\n# ─────────────────────────────────────────────────────────────────────────────\n\nmodel_list:\n\n # ───────── OpenRouter Vision Models (image requests auto-routed here) ─────────\n\n - model_name: vision-openrouter\n litellm_params:\n model: openrouter/openai/gpt-4o\n api_key: os.environ/OpenRouter_API_KEY\n api_base: https://openrouter.ai/api/v1\n tpm: 800000\n rpm: 100\n model_info:\n supports_vision: true\n max_tokens: 16384\n max_input_tokens: 128000\n max_output_tokens: 16384\n input_cost_per_token: 0.0000025\n output_cost_per_token: 0.00001\n\n - model_name: vision-openrouter\n litellm_params:\n model: openrouter/anthropic/claude-opus-4\n api_key: os.environ/OpenRouter_API_KEY\n api_base: https://openrouter.ai/api/v1\n tpm: 400000\n rpm: 50\n model_info:\n supports_vision: true\n max_tokens: 32000\n max_input_tokens: 200000\n max_output_tokens: 32000\n input_cost_per_token: 0.000015\n output_cost_per_token: 0.000075\n\n # ───────── Huawei MaaS Models ───────────\n\n - model_name: glm-5.1\n litellm_params:\n model: openai/glm-5.1\n api_base: os.environ/HUAWEI_MAAS_API_BASE\n api_key: os.environ/HUAWEI_MAAS_API_KEY\n tpm: 500000\n rpm: 30\n model_info:\n max_tokens: 198000\n max_input_tokens: 192000\n max_output_tokens: 128000\n input_cost_per_token: 0.000001078\n output_cost_per_token: 0.000003774\n\n - model_name: claude-opus-4-6\n litellm_params:\n model: openai/glm-5.1\n api_base: os.environ/HUAWEI_MAAS_API_BASE\n api_key: os.environ/HUAWEI_MAAS_API_KEY\n tpm: 500000\n rpm: 30\n model_info:\n max_tokens: 198000\n max_input_tokens: 192000\n max_output_tokens: 128000\n input_cost_per_token: 0.000001078\n output_cost_per_token: 0.000003774\n\n - model_name: claude-glm1\n litellm_params:\n model: openai/glm-5.1\n api_base: os.environ/HUAWEI_MAAS_API_BASE\n api_key: os.environ/HUAWEI_MAAS_API_KEY\n tpm: 500000\n rpm: 30\n model_info:\n max_tokens: 198000\n max_input_tokens: 192000\n max_output_tokens: 128000\n input_cost_per_token: 0.000001078\n output_cost_per_token: 0.000003774\n\n - model_name: glm-5\n litellm_params:\n model: openai/glm-5\n api_base: os.environ/HUAWEI_MAAS_API_BASE\n api_key: os.environ/HUAWEI_MAAS_API_KEY\n tpm: 500000\n rpm: 30\n model_info:\n max_tokens: 198000\n max_input_tokens: 192000\n max_output_tokens: 64000\n input_cost_per_token: 0.000000809\n output_cost_per_token: 0.000002965\n\n - model_name: deepseek-v4-pro\n litellm_params:\n model: openai/deepseek-v4-pro\n api_base: os.environ/HUAWEI_MAAS_API_BASE\n api_key: os.environ/HUAWEI_MAAS_API_KEY\n tpm: 30000\n rpm: 3\n model_info:\n max_tokens: 1000000\n max_input_tokens: 1000000\n max_output_tokens: 128000\n input_cost_per_token: 0.000001617\n output_cost_per_token: 0.000003235\n\n - model_name: deepseek-v4-flash\n litellm_params:\n model: openai/deepseek-v4-flash\n api_base: os.environ/HUAWEI_MAAS_API_BASE\n api_key: os.environ/HUAWEI_MAAS_API_KEY\n tpm: 30000\n rpm: 3 \n model_info:\n max_tokens: 1000000\n max_input_tokens: 1000000\n max_output_tokens: 128000\n input_cost_per_token: 0.000000135\n output_cost_per_token: 0.00000027\n\n - model_name: deepseek-v3.2\n litellm_params:\n model: openai/deepseek-v3.2\n api_base: os.environ/HUAWEI_MAAS_API_BASE\n api_key: os.environ/HUAWEI_MAAS_API_KEY\n tpm: 500000\n rpm: 700\n model_info:\n max_tokens: 160000\n max_input_tokens: 128000\n max_output_tokens: 32000\n input_cost_per_token: 0.00000027\n output_cost_per_token: 0.000000404\n\n\nlitellm_settings:\n num_retries: 3 # retry call 3 times within same deployment\n request_timeout: 600 # raise TimeoutError if full request takes longer than 600s (default)\n stream_timeout: 60 # raise TimeoutError if first token takes longer than 60s (TTFT only)\n drop_params: True\n set_verbose: False\n callbacks:\n - \"prometheus\"\n - custom_callbacks.my_prometheus_logger\n ui_theme_config:\n logo_url: \"https://upload.wikimedia.org/wikipedia/en/thumb/0/04/Huawei_Standard_logo.svg/3840px-Huawei_Standard_logo.svg.png\"\n favicon_url: \"https://upload.wikimedia.org/wikipedia/en/thumb/0/04/Huawei_Standard_logo.svg/3840px-Huawei_Standard_logo.svg.png\"\n\nrouter_settings:\n routing_strategy: simple-shuffle\n num_retries: 3 # retry across deployments\n cooldown_time: 30 # seconds to cool down a failed deployment\n allowed_fails: 3 # failures before cooldown kicks in\n\ngeneral_settings:\n database_connection_pool_limit: 10\n database_connection_timeout: 60\n"}, "db4315c0ce9637176568443c1d2a3ae34bb189af": {"t": 1786068507.1803997, "n": 8432, "h": "b03a650805faf26f", "c": "# ─────────────────────────────────────────────────────────────────────────────\n# LiteLLM Config Example (Single-Key Reference)\n#\n# This is a REFERENCE example showing single-key configuration.\n# The actual config is GENERATED by scripts/generate_config.sh which creates\n# N deployments per model (one for each HUAWEI_MAAS_API_KEY_N).\n#\n# Do NOT edit this file directly. Instead:\n# 1. Run scripts/init_env.sh to set up .env with your MaaS API keys\n# 2. Run scripts/generate_config.sh to generate the actual config\n#\n# Generated config will use: os.environ/HUAWEI_MAAS_API_KEY_0, _1, _2, etc.\n#\n# The generator also emits, to match the production deployment:\n# • rolling_budget_hook.proxy_handler_instance — three-tier rolling-window\n# budget (BUDGET_TIER_* env; effectively unlimited until those are set).\n# • search_tools (exa-search) + the websearch_interception callback —\n# ONLY when EXA_API_KEY is set (shown commented below).\n# • proxy_batch_write_at: 1 — near-real-time spend so the budget hook is timely.\n#\n# The optional BR fintech DLP guardrails are NOT generated (they require the\n# external risk-control module to be mounted first) — see the commented\n# \"guardrails:\" reference block near the end and references/operations.md.\n# ─────────────────────────────────────────────────────────────────────────────\n\nmodel_list:\n\n # ───────── OpenRouter Vision Models (image requests auto-routed here) ─────────\n\n - model_name: vision-openrouter\n litellm_params:\n model: openrouter/openai/gpt-4o\n api_key: os.environ/OpenRouter_API_KEY\n api_base: https://openrouter.ai/api/v1\n tpm: 800000\n rpm: 100\n model_info:\n supports_vision: true\n max_tokens: 16384\n max_input_tokens: 128000\n max_output_tokens: 16384\n input_cost_per_token: 0.0000025\n output_cost_per_token: 0.00001\n\n - model_name: vision-openrouter\n litellm_params:\n model: openrouter/anthropic/claude-opus-4\n api_key: os.environ/OpenRouter_API_KEY\n api_base: https://openrouter.ai/api/v1\n tpm: 400000\n rpm: 50\n model_info:\n supports_vision: true\n max_tokens: 32000\n max_input_tokens: 200000\n max_output_tokens: 32000\n input_cost_per_token: 0.000015\n output_cost_per_token: 0.000075\n\n # ───────── Huawei MaaS Models (1 deployment(s) per model, 7 total) ───────────\n\n - model_name: glm-5.1\n litellm_params:\n model: openai/glm-5.1\n api_base: os.environ/HUAWEI_MAAS_API_BASE\n api_key: os.environ/HUAWEI_MAAS_API_KEY_0\n tpm: 500000\n rpm: 30\n model_info:\n max_tokens: 198000\n max_input_tokens: 192000\n max_output_tokens: 128000\n input_cost_per_token: 0.000001078\n output_cost_per_token: 0.000003774\n\n - model_name: claude-opus-4-6\n litellm_params:\n model: openai/glm-5.1\n api_base: os.environ/HUAWEI_MAAS_API_BASE\n api_key: os.environ/HUAWEI_MAAS_API_KEY_0\n tpm: 500000\n rpm: 30\n model_info:\n max_tokens: 198000\n max_input_tokens: 192000\n max_output_tokens: 128000\n input_cost_per_token: 0.000001078\n output_cost_per_token: 0.000003774\n\n - model_name: claude-glm1\n litellm_params:\n model: openai/glm-5.1\n api_base: os.environ/HUAWEI_MAAS_API_BASE\n api_key: os.environ/HUAWEI_MAAS_API_KEY_0\n tpm: 500000\n rpm: 30\n model_info:\n max_tokens: 198000\n max_input_tokens: 192000\n max_output_tokens: 128000\n input_cost_per_token: 0.000001078\n output_cost_per_token: 0.000003774\n\n - model_name: glm-5\n litellm_params:\n model: openai/glm-5\n api_base: os.environ/HUAWEI_MAAS_API_BASE\n api_key: os.environ/HUAWEI_MAAS_API_KEY_0\n tpm: 500000\n rpm: 30\n model_info:\n max_tokens: 198000\n max_input_tokens: 192000\n max_output_tokens: 64000\n input_cost_per_token: 0.000000809\n output_cost_per_token: 0.000002965\n\n - model_name: deepseek-v4-pro\n litellm_params:\n model: openai/deepseek-v4-pro\n api_base: os.environ/HUAWEI_MAAS_API_BASE\n api_key: os.environ/HUAWEI_MAAS_API_KEY_0\n tpm: 30000\n rpm: 3\n model_info:\n max_tokens: 1000000\n max_input_tokens: 1000000\n max_output_tokens: 128000\n input_cost_per_token: 0.000001617\n output_cost_per_token: 0.000003235\n\n - model_name: deepseek-v4-flash\n litellm_params:\n model: openai/deepseek-v4-flash\n api_base: os.environ/HUAWEI_MAAS_API_BASE\n api_key: os.environ/HUAWEI_MAAS_API_KEY_0\n tpm: 30000\n rpm: 3\n model_info:\n max_tokens: 1000000\n max_input_tokens: 1000000\n max_output_tokens: 128000\n input_cost_per_token: 0.000000135\n output_cost_per_token: 0.00000027\n\n - model_name: deepseek-v3.2\n litellm_params:\n model: openai/deepseek-v3.2\n api_base: os.environ/HUAWEI_MAAS_API_BASE\n api_key: os.environ/HUAWEI_MAAS_API_KEY_0\n tpm: 500000\n rpm: 700\n model_info:\n max_tokens: 160000\n max_input_tokens: 128000\n max_output_tokens: 32000\n input_cost_per_token: 0.00000027\n output_cost_per_token: 0.000000404\n\n# ── Optional: Exa search tool (emitted by the generator only when EXA_API_KEY set) ──\n# search_tools:\n# - search_tool_name: exa-search\n# litellm_params:\n# search_provider: exa_ai\n# api_key: os.environ/EXA_API_KEY\n\nlitellm_settings:\n num_retries: 3 # retry call 3 times within same deployment\n request_timeout: 600 # raise TimeoutError if full request takes longer than 600s (default)\n stream_timeout: 60 # raise TimeoutError if first token takes longer than 60s (TTFT only)\n drop_params: True\n set_verbose: False\n callbacks:\n - \"prometheus\"\n - custom_callbacks.my_prometheus_logger\n - rolling_budget_hook.proxy_handler_instance\n # Added by the generator only when EXA_API_KEY is set:\n # - \"websearch_interception\"\n ui_theme_config:\n logo_url: \"https://upload.wikimedia.org/wikipedia/en/thumb/0/04/Huawei_Standard_logo.svg/3840px-Huawei_Standard_logo.svg.png\"\n favicon_url: \"https://upload.wikimedia.org/wikipedia/en/thumb/0/04/Huawei_Standard_logo.svg/3840px-Huawei_Standard_logo.svg.png\"\n # Added by the generator only when EXA_API_KEY is set:\n # websearch_interception_params:\n # enabled_providers: [\"openai\"]\n # search_tool_name: \"exa-search\"\n\n# ── Optional: BR fintech DLP guardrails (external risk-control project) ──────────\n# Reference of the production layering. NOT enabled by default: the\n# br_dlp_guardrail module + presidio service must be mounted/running first\n# (see docker-compose.yml commented mounts and references/operations.md).\n# All guardrails use default_on: false → they fire only when a request carries\n# `guardrails: [...]`, so the core stack is unaffected if you leave this out.\n#\n# guardrails:\n# - guardrail_name: secrets-filter # L1: built-in content filter (API keys/JWT/private keys)\n# litellm_params:\n# guardrail: litellm_content_filter\n# mode: pre_call\n# default_on: false\n# patterns:\n# - {pattern_type: prebuilt, pattern_name: generic_api_key, action: BLOCK}\n# - {pattern_type: prebuilt, pattern_name: github_token, action: BLOCK}\n# - guardrail_name: br-dlp-input # L2: Brazilian entity DLP (input)\n# litellm_params:\n# guardrail: br_dlp_guardrail.BrazilDLPGuardrail\n# mode: pre_call\n# default_on: false\n# - guardrail_name: br-pii-presidio # L2: Presidio + pt NLP (PERSON/LOCATION)\n# litellm_params:\n# guardrail: presidio\n# mode: pre_call\n# default_on: false\n# presidio_language: pt\n# pii_entities_config: {PERSON: MASK, LOCATION: MASK}\n# presidio_score_thresholds: {PERSON: 0.80, LOCATION: 0.80}\n# - guardrail_name: br-dlp-output # must register LAST (appends privacy banner)\n# litellm_params:\n# guardrail: br_dlp_guardrail.BrazilDLPGuardrail\n# mode: post_call\n# default_on: false\n\nrouter_settings:\n routing_strategy: simple-shuffle\n num_retries: 3\n cooldown_time: 30 # seconds to cool down a failed deployment\n allowed_fails: 3 # failures before cooldown kicks in\n\ngeneral_settings:\n database_connection_pool_limit: 10\n database_connection_timeout: 60\n # Flush spend logs quickly so the rolling-budget hook sees near-real-time spend\n # (default is 10s). Hour/day-scale production windows tolerate raising this back.\n proxy_batch_write_at: 1\n"}}}}