Files
Selig 4c966a3ad2 Initial commit: OpenClaw Skill Collection
6 custom skills (assign-task, dispatch-webhook, daily-briefing,
task-capture, qmd-brain, tts-voice) with technical documentation.
Compatible with Claude Code, OpenClaw, Codex CLI, and OpenCode.
2026-03-13 10:58:30 +08:00

59 lines
6.4 KiB
JSON
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"title": "Model failover",
"content": "OpenClaw handles failures in two stages:\n\n1. **Auth profile rotation** within the current provider.\n2. **Model fallback** to the next model in `agents.defaults.model.fallbacks`.\n\nThis doc explains the runtime rules and the data that backs them.\n\n## Auth storage (keys + OAuth)\n\nOpenClaw uses **auth profiles** for both API keys and OAuth tokens.\n\n* Secrets live in `~/.openclaw/agents/<agentId>/agent/auth-profiles.json` (legacy: `~/.openclaw/agent/auth-profiles.json`).\n* Config `auth.profiles` / `auth.order` are **metadata + routing only** (no secrets).\n* Legacy import-only OAuth file: `~/.openclaw/credentials/oauth.json` (imported into `auth-profiles.json` on first use).\n\nMore detail: [/concepts/oauth](/concepts/oauth)\n\n* `type: \"api_key\"` → `{ provider, key }`\n* `type: \"oauth\"` → `{ provider, access, refresh, expires, email? }` (+ `projectId`/`enterpriseUrl` for some providers)\n\nOAuth logins create distinct profiles so multiple accounts can coexist.\n\n* Default: `provider:default` when no email is available.\n* OAuth with email: `provider:<email>` (for example `google-antigravity:user@gmail.com`).\n\nProfiles live in `~/.openclaw/agents/<agentId>/agent/auth-profiles.json` under `profiles`.\n\nWhen a provider has multiple profiles, OpenClaw chooses an order like this:\n\n1. **Explicit config**: `auth.order[provider]` (if set).\n2. **Configured profiles**: `auth.profiles` filtered by provider.\n3. **Stored profiles**: entries in `auth-profiles.json` for the provider.\n\nIf no explicit order is configured, OpenClaw uses a roundrobin order:\n\n* **Primary key:** profile type (**OAuth before API keys**).\n* **Secondary key:** `usageStats.lastUsed` (oldest first, within each type).\n* **Cooldown/disabled profiles** are moved to the end, ordered by soonest expiry.\n\n### Session stickiness (cache-friendly)\n\nOpenClaw **pins the chosen auth profile per session** to keep provider caches warm.\nIt does **not** rotate on every request. The pinned profile is reused until:\n\n* the session is reset (`/new` / `/reset`)\n* a compaction completes (compaction count increments)\n* the profile is in cooldown/disabled\n\nManual selection via `/model …@<profileId>` sets a **user override** for that session\nand is not autorotated until a new session starts.\n\nAutopinned profiles (selected by the session router) are treated as a **preference**:\nthey are tried first, but OpenClaw may rotate to another profile on rate limits/timeouts.\nUserpinned profiles stay locked to that profile; if it fails and model fallbacks\nare configured, OpenClaw moves to the next model instead of switching profiles.\n\n### Why OAuth can “look lost”\n\nIf you have both an OAuth profile and an API key profile for the same provider, roundrobin can switch between them across messages unless pinned. To force a single profile:\n\n* Pin with `auth.order[provider] = [\"provider:profileId\"]`, or\n* Use a per-session override via `/model …` with a profile override (when supported by your UI/chat surface).\n\nWhen a profile fails due to auth/ratelimit errors (or a timeout that looks\nlike rate limiting), OpenClaw marks it in cooldown and moves to the next profile.\nFormat/invalidrequest errors (for example Cloud Code Assist tool call ID\nvalidation failures) are treated as failoverworthy and use the same cooldowns.\n\nCooldowns use exponential backoff:\n\n* 1 minute\n* 5 minutes\n* 25 minutes\n* 1 hour (cap)\n\nState is stored in `auth-profiles.json` under `usageStats`:\n\nBilling/credit failures (for example “insufficient credits” / “credit balance too low”) are treated as failoverworthy, but theyre usually not transient. Instead of a short cooldown, OpenClaw marks the profile as **disabled** (with a longer backoff) and rotates to the next profile/provider.\n\nState is stored in `auth-profiles.json`:\n\n* Billing backoff starts at **5 hours**, doubles per billing failure, and caps at **24 hours**.\n* Backoff counters reset if the profile hasnt failed for **24 hours** (configurable).\n\nIf all profiles for a provider fail, OpenClaw moves to the next model in\n`agents.defaults.model.fallbacks`. This applies to auth failures, rate limits, and\ntimeouts that exhausted profile rotation (other errors do not advance fallback).\n\nWhen a run starts with a model override (hooks or CLI), fallbacks still end at\n`agents.defaults.model.primary` after trying any configured fallbacks.\n\nSee [Gateway configuration](/gateway/configuration) for:\n\n* `auth.profiles` / `auth.order`\n* `auth.cooldowns.billingBackoffHours` / `auth.cooldowns.billingBackoffHoursByProvider`\n* `auth.cooldowns.billingMaxHours` / `auth.cooldowns.failureWindowHours`\n* `agents.defaults.model.primary` / `agents.defaults.model.fallbacks`\n* `agents.defaults.imageModel` routing\n\nSee [Models](/concepts/models) for the broader model selection and fallback overview.",
"code_samples": [
{
"code": "## Billing disables\n\nBilling/credit failures (for example “insufficient credits” / “credit balance too low”) are treated as failoverworthy, but theyre usually not transient. Instead of a short cooldown, OpenClaw marks the profile as **disabled** (with a longer backoff) and rotates to the next profile/provider.\n\nState is stored in `auth-profiles.json`:",
"language": "unknown"
}
],
"headings": [
{
"level": "h2",
"text": "Auth storage (keys + OAuth)",
"id": "auth-storage-(keys-+-oauth)"
},
{
"level": "h2",
"text": "Profile IDs",
"id": "profile-ids"
},
{
"level": "h2",
"text": "Rotation order",
"id": "rotation-order"
},
{
"level": "h3",
"text": "Session stickiness (cache-friendly)",
"id": "session-stickiness-(cache-friendly)"
},
{
"level": "h3",
"text": "Why OAuth can “look lost”",
"id": "why-oauth-can-“look-lost”"
},
{
"level": "h2",
"text": "Cooldowns",
"id": "cooldowns"
},
{
"level": "h2",
"text": "Billing disables",
"id": "billing-disables"
},
{
"level": "h2",
"text": "Model fallback",
"id": "model-fallback"
},
{
"level": "h2",
"text": "Related config",
"id": "related-config"
}
],
"url": "llms-txt#model-failover",
"links": []
}