{
  "_note": "Example config for pi-fallback-chains. Copy to ~/.pi/agent/pi-fallback-chains.json and edit. Keys are globs over 'provider/modelId' ('*' spans '/'). The three target styles shown below are interchangeable.",

  "enabled": true,
  "terminalFallback": true,

  "chains": {
    "cline-pass/*": [
      "cline-pass-gmail/*",
      { "model": "neuralwatt/kimi-k3-flex", "thinking_level": "max" },
      "neuralwatt/glm-5.3-flash-flex",
      "opencode-go/*",
      "openrouterTim/openrouter/fusion:xxs"
    ],

    "cline-pass-gmail/*": [
      "cline-pass/*",
      "neuralwatt/kimi-k3-flex:max",
      "opencode-go/glm-5.3-flash"
    ],

    "cline-pass/cline-pass/glm-5.3-flash": {
      "thinking_level": "high",
      "targets": [
        "cline-pass-gmail/cline-pass/glm-5.3-flash",
        { "model": "neuralwatt/glm-5.3-flash-flex", "thinking_level": "max" },
        "opencode-go/glm-5.3-flash"
      ]
    },

    "neuralwatt/*": [
      { "model": "neuralwatt/kimi-k3-flex", "thinking_level": "max" },
      "neuralwatt/glm-5.3-flash-flex",
      "openrouterTim/openrouter/fusion:xxs"
    ],

    "opencode-go/*": ["openrouterTim/openrouter/fusion:xxs"],

    "openrouter/*": [
      "neuralwatt/deepseek-v4-pro",
      "opencode-go/deepseek-v4-flash",
      "openrouterTim/openrouter/fusion:xxs"
    ],

    "openai-codex/*": [
      "neuralwatt/kimi-k3-flex:max",
      "openrouterTim/openrouter/fusion:xxs"
    ],

    "databricks-anthropic/*": [
      "databricks-anthropic/databricks-claude-opus-4-8",
      "openrouterTim/openrouter/fusion:xxs"
    ],

    "muse/*": [
      "openrouter/meta/muse-spark-1.3-contributor",
      "neuralwatt/deepseek-v4-flash-flex:max",
      "openrouterTim/openrouter/fusion:xxs"
    ]
  },

  "defaultChain": ["openrouterTim/openrouter/fusion:xxs"],

  "maxFailoversPerRequest": 4,
  "settleDelayMs": 0,
  "retryMode": "replay",
  "retryInstruction": "Continue from where you left off.",
  "compactBeforeRetry": true,
  "requireNoToolCalls": false,
  "notify": true,
  "restoreOnShutdown": true,

  "retryableStatusCodes": [
    408, 409, 425, 429, 500, 501, 502, 503, 504,
    520, 521, 522, 523, 524, 525, 526, 527, 529
  ],
  "nonRetryableStatusCodes": [400, 401, 403, 405, 422],

  "retryablePatterns": [
    "timeout",
    "rate ?limit",
    "too many requests",
    "overloaded",
    "\\binternal (?:backend |server )?error\\b",
    "unavailable",
    "quota",
    "insufficient_quota",
    "usage limit",
    "econnreset",
    "socket hang up",
    "fetch failed",
    "connection reset",
    "no such model",
    "model not found",
    "is not available"
  ],

  "nonRetryablePatterns": [
    "invalid api key",
    "authentication",
    "unauthorized",
    "forbidden",
    "context_length_exceeded",
    "context window",
    "maximum context length",
    "prompt is too long",
    "aborted"
  ],

  "providerCapPatterns": [
    "inference_cap",
    "quota",
    "usage limit",
    "rate ?limit",
    "too many requests",
    "billing",
    "capacity",
    "exceeded your"
  ]
}
