jeouly3-bot

provider-manager

Manage AI provider API keys and models. Auto-discover models, track quota exhaustion across agents, and auto-switch on failure. Use when: adding API key, checking model availability, viewing exhausted models, syncing configs, or when a model returns 403/billing/quota errors. Triggers on: "add API key", "new account key", "model used up", "switch model", "check models", "reset models", "quota exhausted", "billing error", "403 error", "insufficient balance", "模型额度", "key用完了", "换模型", "添加key", "额度用完", "余额不足".

jeouly3-bot 4 Updated 2mo ago
GitHub

Install

npx skillscat add jeouly3-bot/openclaw-provider-manager

Install via the SkillsCat registry.

SKILL.md

Provider Manager — Agent Decision Tree

This document is your operating manual. Follow the decision trees below to manage API keys, models, and quota for your user. All commands use {baseDir} to refer to the directory where this skill is installed.

Communication principle: When you need to ask the user a question or report a result, use whatever communication channel is available to you (chat UI, messaging app, webhook, etc.). This skill does not prescribe any specific channel — you decide based on your own capabilities.


1. Installation

How to install this skill

# Clone into your skills directory
git clone https://github.com/jeouly3-bot/openclaw-provider-manager.git {skillsDir}/openclaw-provider-manager

# Install dependencies
cd {skillsDir}/openclaw-provider-manager && npm install

Verify installation

node {baseDir}/scripts/registry.js --help

If this prints the help text, installation is successful.


2. First Run — Auto-Configuration

When this skill is loaded for the first time, follow this sequence:

START
  │
  ├─ Run: node {baseDir}/scripts/health-check.js
  │
  ├─ IF exit code = 0 AND status = "healthy"
  │    └─ Registry exists and has available models. Ready to use.
  │
  ├─ IF exit code = 0 AND status = "no-registry"
  │    ├─ No registry found. First-time setup needed.
  │    ├─ ASK USER: "I need an API key to get started. Which provider are you using?"
  │    ├─ Offer choices: bailian, deepseek, zhipu, kimi, openai, siliconflow, custom
  │    ├─ ASK USER: "Please provide your API key for {provider}."
  │    ├─ Run: node {baseDir}/scripts/registry.js add-key \
  │    │        --provider {provider} --key {user_key} --label "{agent_name}"
  │    ├─ IF success:
  │    │    └─ Tell user: "Added key and discovered N models. Ready to use."
  │    └─ IF failure:
  │         └─ Tell user the error message. Ask them to verify the key.
  │
  ├─ IF exit code = 0 AND status = "warning"
  │    ├─ Some models are exhausted but others remain.
  │    ├─ Tell user: "{summary}" (from health-check output)
  │    └─ ASK USER: "Would you like to add a new key or reset exhausted models with a new account?"
  │
  └─ IF exit code = 0 AND status = "critical"
       ├─ ALL text models exhausted. Cannot make API calls.
       ├─ Tell user: "All text models are exhausted. I need a new API key to continue."
       ├─ ASK USER: "Please provide a new API key. Is this from a new account (fresh quota)?"
       ├─ IF new account:
       │    ├─ Run: node {baseDir}/scripts/registry.js reset --provider {provider}
       │    └─ Run: node {baseDir}/scripts/registry.js add-key \
       │           --provider {provider} --key {new_key} --label "{agent_name}"
       └─ IF same account, different key:
            └─ Run: node {baseDir}/scripts/registry.js add-key \
                   --provider {provider} --key {new_key} --label "{agent_name}"

3. When a Model Returns 403 / Billing Error / Quota Exhausted

When you receive ANY of these errors from an API call:

  • HTTP 403
  • "billing error"
  • "insufficient balance"
  • "insufficient quota"
  • "quota exhausted"
  • "rate limit" (persistent, not transient)
  • "API key has run out of credits"

Follow this sequence:

ERROR DETECTED: {provider}/{model} returned {error}
  │
  ├─ Step 1: Mark the model as exhausted
  │    Run: node {baseDir}/scripts/registry.js mark-exhausted \
  │         --provider {provider} --model {model} --by {your_agent_name}
  │
  ├─ Step 2: Get the next available model
  │    Run: node {baseDir}/scripts/registry.js next-model \
  │         --provider {provider} --type text
  │    ├─ IF success (returns JSON with model field):
  │    │    ├─ Parse the output JSON: { "model": "new-model-id", "type": "text" }
  │    │    ├─ Step 3: Sync configuration
  │    │    │    Run: node {baseDir}/scripts/sync-config.js \
  │    │    │         --format gateway --config {config_path} \
  │    │    │         --provider {provider}
  │    │    └─ Step 4: Retry the original API call with the new model.
  │    │         Tell user: "Model {old_model} exhausted. Switched to {new_model}."
  │    │
  │    └─ IF failure (no available models):
  │         ├─ ALL models for this provider are exhausted.
  │         ├─ Tell user: "All models for {provider} are exhausted. I need a new API key."
  │         ├─ ASK USER: "Please provide a new key. Is this a new account?"
  │         ├─ IF new account:
  │         │    ├─ Run: node {baseDir}/scripts/registry.js reset --provider {provider}
  │         │    └─ Run: node {baseDir}/scripts/registry.js add-key \
  │         │           --provider {provider} --key {new_key} --label "{agent_name}"
  │         └─ IF same account:
  │              └─ Run: node {baseDir}/scripts/registry.js add-key \
  │                     --provider {provider} --key {new_key} --label "{agent_name}"
  │
  └─ After adding new key, retry the original API call.

Important notes on exhaustion

  • Exhausted models are permanently marked until a reset is performed.
  • reset should ONLY be used when the user provides keys from a new account with fresh quota.
  • Adding a new key from the same account does NOT reset exhaustion — the models remain exhausted because the quota is shared across keys on the same account.

4. Health Check (Proactive Monitoring)

Run the health check periodically or when you suspect quota issues:

node {baseDir}/scripts/health-check.js [--registry <path>]

The output is JSON:

{
  "status": "healthy|warning|critical|no-registry",
  "summary": "human-readable summary",
  "total_models": 190,
  "available": 118,
  "exhausted": 72,
  "by_type": {
    "text": { "total": 95, "available": 55, "exhausted": 40 }
  },
  "recently_exhausted": [
    { "model": "qwen3.5-plus", "exhausted_at": "...", "by": "小艺" }
  ],
  "action_required": "description of what needs to happen, or null"
}

Status thresholds

Status Condition Action
healthy < 25% text models exhausted No action needed
warning 25% – 99% text models exhausted Inform user, suggest adding a new key
critical 100% text models exhausted Must get new key before any API calls
no-registry Registry file not found Run first-time setup (Section 2)

Decision tree for health check results

HEALTH CHECK RESULT
  │
  ├─ healthy → No action. Continue normally.
  │
  ├─ warning → Tell user: "{summary}. Consider adding a new API key."
  │
  ├─ critical → Tell user: "All text models exhausted. Provide a new key to continue."
  │              Follow the key-addition flow in Section 3.
  │
  └─ no-registry → Follow first-run setup in Section 2.

5. Adding a New API Key (User-Initiated)

When a user says they want to add a key (unprompted by an error):

USER WANTS TO ADD A KEY
  │
  ├─ ASK USER: "Which provider? (bailian / deepseek / zhipu / kimi / openai / siliconflow / custom)"
  ├─ ASK USER: "Please provide the API key."
  ├─ IF custom: ASK USER: "What is the base URL? (e.g., https://your-api.com/v1)"
  │
  ├─ Run: node {baseDir}/scripts/registry.js add-key \
  │        --provider {provider} --key {key} --label "{agent_name}" \
  │        [--base-url {url}]
  │
  ├─ IF success:
  │    └─ Tell user: "Key added. Discovered N models."
  └─ IF failure:
       └─ Tell user the error. Common issues:
            - Key already registered
            - Network error reaching provider API
            - Invalid key format

6. Checking Status (User-Initiated)

When a user asks about model availability or status:

# Full status
node {baseDir}/scripts/registry.js status

# Status for one provider
node {baseDir}/scripts/registry.js status --provider bailian

# Health summary (JSON)
node {baseDir}/scripts/health-check.js

Present the results in a readable format to the user.


7. Resetting Exhausted Models

Only reset when the user confirms they have a new account with fresh quota:

node {baseDir}/scripts/registry.js reset --provider {provider}

Never reset automatically. Always confirm with the user first.


8. Supported Providers

ID Name Base URL
bailian 阿里云百炼 (DashScope) https://dashscope.aliyuncs.com/compatible-mode/v1
deepseek DeepSeek https://api.deepseek.com/v1
zhipu 智谱AI (Zhipu) https://open.bigmodel.cn/api/paas/v4
kimi Kimi / 月之暗面 https://api.moonshot.cn/v1
openai OpenAI https://api.openai.com/v1
siliconflow SiliconFlow https://api.siliconflow.cn/v1
custom Custom User-specified --base-url

All providers use the OpenAI-compatible API standard (GET /v1/models).


9. Multi-Agent Shared Registry

Multiple agents can share one registry file. Set the path via:

  • Environment variable: PROVIDER_REGISTRY_PATH=/shared/.provider-registry.json
  • CLI flag: --registry /shared/.provider-registry.json

When one agent marks a model exhausted, all other agents see it on their next read. File-locking ensures safe concurrent writes.


10. Blacklist Management

Some models have no free quota. Manage the blacklist:

# Add to blacklist
node {baseDir}/scripts/registry.js blacklist-add --model "model-name"

# Remove from blacklist
node {baseDir}/scripts/registry.js blacklist-remove --model "model-name"

Blacklisted models are excluded from discovery and will never be selected by next-model.