# Resilience Guide (ಕನ್ನಡ) 🌐 **Languages:** 🇺🇸 [English](../../../../architecture/RESILIENCE_GUIDE.md) · 🇪🇹 [am](../../../am/docs/architecture/RESILIENCE_GUIDE.md) · 🇸🇦 [ar](../../../ar/docs/architecture/RESILIENCE_GUIDE.md) · 🇦🇿 [az](../../../az/docs/architecture/RESILIENCE_GUIDE.md) · 🇧🇬 [bg](../../../bg/docs/architecture/RESILIENCE_GUIDE.md) · 🇧🇩 [bn](../../../bn/docs/architecture/RESILIENCE_GUIDE.md) · 🇧🇦 [bs](../../../bs/docs/architecture/RESILIENCE_GUIDE.md) · 🇨🇿 [cs](../../../cs/docs/architecture/RESILIENCE_GUIDE.md) · 🇩🇰 [da](../../../da/docs/architecture/RESILIENCE_GUIDE.md) · 🇩🇪 [de](../../../de/docs/architecture/RESILIENCE_GUIDE.md) · 🇬🇷 [el](../../../el/docs/architecture/RESILIENCE_GUIDE.md) · 🇪🇸 [es](../../../es/docs/architecture/RESILIENCE_GUIDE.md) · 🇪🇪 [et](../../../et/docs/architecture/RESILIENCE_GUIDE.md) · 🇮🇷 [fa](../../../fa/docs/architecture/RESILIENCE_GUIDE.md) · 🇫🇮 [fi](../../../fi/docs/architecture/RESILIENCE_GUIDE.md) · 🇫🇷 [fr](../../../fr/docs/architecture/RESILIENCE_GUIDE.md) · 🇮🇪 [ga](../../../ga/docs/architecture/RESILIENCE_GUIDE.md) · 🇮🇳 [gu](../../../gu/docs/architecture/RESILIENCE_GUIDE.md) · 🇳🇬 [ha](../../../ha/docs/architecture/RESILIENCE_GUIDE.md) · 🇮🇱 [he](../../../he/docs/architecture/RESILIENCE_GUIDE.md) · 🇮🇳 [hi](../../../hi/docs/architecture/RESILIENCE_GUIDE.md) · 🇭🇷 [hr](../../../hr/docs/architecture/RESILIENCE_GUIDE.md) · 🇭🇺 [hu](../../../hu/docs/architecture/RESILIENCE_GUIDE.md) · 🇦🇲 [hy](../../../hy/docs/architecture/RESILIENCE_GUIDE.md) · 🇮🇩 [id](../../../id/docs/architecture/RESILIENCE_GUIDE.md) · 🇳🇬 [ig](../../../ig/docs/architecture/RESILIENCE_GUIDE.md) · 🇮🇹 [it](../../../it/docs/architecture/RESILIENCE_GUIDE.md) · 🇯🇵 [ja](../../../ja/docs/architecture/RESILIENCE_GUIDE.md) · 🇬🇪 [ka](../../../ka/docs/architecture/RESILIENCE_GUIDE.md) · 🇰🇭 [km](../../../km/docs/architecture/RESILIENCE_GUIDE.md) · 🇰🇷 [ko](../../../ko/docs/architecture/RESILIENCE_GUIDE.md) · 🇱🇹 [lt](../../../lt/docs/architecture/RESILIENCE_GUIDE.md) · 🇱🇻 [lv](../../../lv/docs/architecture/RESILIENCE_GUIDE.md) · 🇮🇳 [ml](../../../ml/docs/architecture/RESILIENCE_GUIDE.md) · 🇮🇳 [mr](../../../mr/docs/architecture/RESILIENCE_GUIDE.md) · 🇲🇾 [ms](../../../ms/docs/architecture/RESILIENCE_GUIDE.md) · 🇲🇹 [mt](../../../mt/docs/architecture/RESILIENCE_GUIDE.md) · 🇲🇲 [my](../../../my/docs/architecture/RESILIENCE_GUIDE.md) · 🇳🇵 [ne](../../../ne/docs/architecture/RESILIENCE_GUIDE.md) · 🇳🇱 [nl](../../../nl/docs/architecture/RESILIENCE_GUIDE.md) · 🇳🇴 [no](../../../no/docs/architecture/RESILIENCE_GUIDE.md) · 🇮🇳 [or](../../../or/docs/architecture/RESILIENCE_GUIDE.md) · 🇮🇳 [pa](../../../pa/docs/architecture/RESILIENCE_GUIDE.md) · 🇵🇭 [phi](../../../phi/docs/architecture/RESILIENCE_GUIDE.md) · 🇵🇱 [pl](../../../pl/docs/architecture/RESILIENCE_GUIDE.md) · 🇵🇹 [pt](../../../pt/docs/architecture/RESILIENCE_GUIDE.md) · 🇧🇷 [pt-BR](../../../pt-BR/docs/architecture/RESILIENCE_GUIDE.md) · 🇷🇴 [ro](../../../ro/docs/architecture/RESILIENCE_GUIDE.md) · 🇷🇺 [ru](../../../ru/docs/architecture/RESILIENCE_GUIDE.md) · 🇱🇰 [si](../../../si/docs/architecture/RESILIENCE_GUIDE.md) · 🇸🇰 [sk](../../../sk/docs/architecture/RESILIENCE_GUIDE.md) · 🇸🇮 [sl](../../../sl/docs/architecture/RESILIENCE_GUIDE.md) · 🇷🇸 [sr](../../../sr/docs/architecture/RESILIENCE_GUIDE.md) · 🇸🇪 [sv](../../../sv/docs/architecture/RESILIENCE_GUIDE.md) · 🇰🇪 [sw](../../../sw/docs/architecture/RESILIENCE_GUIDE.md) · 🇮🇳 [ta](../../../ta/docs/architecture/RESILIENCE_GUIDE.md) · 🇮🇳 [te](../../../te/docs/architecture/RESILIENCE_GUIDE.md) · 🇹🇭 [th](../../../th/docs/architecture/RESILIENCE_GUIDE.md) · 🇹🇷 [tr](../../../tr/docs/architecture/RESILIENCE_GUIDE.md) · 🇺🇦 [uk-UA](../../../uk-UA/docs/architecture/RESILIENCE_GUIDE.md) · 🇵🇰 [ur](../../../ur/docs/architecture/RESILIENCE_GUIDE.md) · 🇺🇿 [uz](../../../uz/docs/architecture/RESILIENCE_GUIDE.md) · 🇻🇳 [vi](../../../vi/docs/architecture/RESILIENCE_GUIDE.md) · 🇳🇬 [yo](../../../yo/docs/architecture/RESILIENCE_GUIDE.md) · 🇨🇳 [zh-CN](../../../zh-CN/docs/architecture/RESILIENCE_GUIDE.md) · 🇹🇼 [zh-TW](../../../zh-TW/docs/architecture/RESILIENCE_GUIDE.md) --- OmniRoute ಗೆ ವಿಭಿನ್ನವಾದ ಆದರೆ ಪರಸ್ಪರ ಸಂಬಂಧಿಸಿದ ಮೂರು ರೆಸಿಲಿಯನ್ಸ್ ಕ್ರಮಗಳಿವೆ. ಪ್ರತಿಯೊಂದಕ್ಕೂ ಬೇರೆ ವ್ಯಾಪ್ತಿ ಮತ್ತು ಉದ್ದೇಶವಿದೆ. ರೂಟಿಂಗ್ ವರ್ತನೆಯನ್ನು ಡೀಬಗ್ ಮಾಡುವಾಗ ಇವುಗಳನ್ನು ಪ್ರತ್ಯೇಕವಾಗಿಟ್ಟುಕೊಳ್ಳಿ. ![3-ಪದರದ ರೆಸಿಲಿಯನ್ಸ್ ಮಾದರಿ](../diagrams/exported/resilience-3layers.svg) > ಮೂಲ: [diagrams/resilience-3layers.mmd](../diagrams/resilience-3layers.mmd) ## 1. ಪ್ರೊವೈಡರ್ ಸರ್ಕ್ಯೂಟ್ ಬ್ರೇಕರ್ **ವ್ಯಾಪ್ತಿ:** ಇಡೀ ಪ್ರೊವೈಡರ್ (ಉದಾ., `glm`, `openai`, `anthropic`). **ಉದ್ದೇಶ:** ಅಪ್ಸ್ಟ್ರೀಮ್/ಸೇವಾ ಮಟ್ಟದಲ್ಲಿ ಪದೇ ಪದೇ ವಿಫಲವಾಗುತ್ತಿರುವ ಪ್ರೊವೈಡರ್ಗೆ ಟ್ರಾಫಿಕ್ ಕಳುಹಿಸುವುದನ್ನು ನಿಲ್ಲಿಸುವುದು. **ಅನುಷ್ಠಾನ:** - ಪ್ರಧಾನ ಕ್ಲಾಸ್: `src/shared/utils/circuitBreaker.ts` - ವೈರಿಂಗ್: `src/sse/handlers/chatHelpers.ts`, `src/sse/handlers/chat.ts` - ಸ್ಥಿತಿ API: `GET /api/monitoring/health` - ರಿಸೆಟ್ API: `POST /api/resilience/reset` - ರ್ಯಾಪರ್ಗಳು: `open-sse/services/accountFallback.ts` - DB ಟೇಬಲ್: `domain_circuit_breakers` **ಸ್ಥಿತಿಗಳು:** - `CLOSED` — ಸಾಮಾನ್ಯ ಟ್ರಾಫಿಕ್ ಅನುಮತಿಸಲಾಗಿದೆ - `DEGRADED` — ಟ್ರಾಫಿಕ್ ಇನ್ನೂ ಅನುಮತಿಸಲಾಗಿದೆ, ಆದರೆ ಹೆಚ್ಚುತ್ತಿರುವ ಪ್ರೊವೈಡರ್ ವಿಫಲತೆಗಳನ್ನು ಟ್ರ್ಯಾಕ್ ಮಾಡಲಾಗುತ್ತಿದೆ; ಸಾಕಷ್ಟು ಯಶಸ್ಸುಗಳಾದಾಗ, ಮಾನ್ಯ ಸಂಪರ್ಕ ಪರೀಕ್ಷೆಯಾದಾಗ, ಅಥವಾ ಕೊನೆಯ ವಿಫಲತೆಯ ಪ್ರಕಾರದ ಅತ್ಯುದ್ದನೆಯ `OPEN` ಹೋಲ್ಡ್ ಅವಧಿಯ ನಂತರ (ಅದರ `cooldownByKind` ಮೌಲ್ಯ, ಇಲ್ಲದಿದ್ದರೆ `resetTimeout`, × `maxBackoffMultiplier`, ಕನಿಷ್ಠ ಒಂದು ಕೂಲ್ಡೌನ್) ಹೊಸ ವಿಫಲತೆಯಾಗದಿದ್ದರೆ `CLOSED` ಗೆ ಹಿಂತಿರುಗುತ್ತದೆ - `OPEN` — ಪ್ರೊವೈಡರ್ ತಾತ್ಕಾಲಿಕವಾಗಿ ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ; ಕಾಂಬೊ ರೂಟಿಂಗ್ ಅದನ್ನು ಬಿಟ್ಟುಬಿಡುತ್ತದೆ - `HALF_OPEN` — ರಿಸೆಟ್ ಟೈಮ್ಔಟ್ ಮುಗಿದಿದೆ; ಪ್ರೋಬ್ ವಿನಂತಿಯನ್ನು ಅನುಮತಿಸಲಾಗಿದೆ **ಕಾನ್ಫಿಗರ್ ಮಾಡಬಹುದಾದ ಡೀಫಾಲ್ಟ್ಗಳು (`open-sse/config/constants.ts`, ಡ್ಯಾಶ್ಬೋರ್ಡ್ → ಸೆಟ್ಟಿಂಗ್ಗಳು → ರೆಸಿಲಿಯನ್ಸ್ ನಲ್ಲಿ ಅನಾವರಣಗೊಂಡಿವೆ):** | ವರ್ಗ | ಡಿಗ್ರೇಡ್ ಆಗುವುದು | ಓಪನ್ ಆಗುವುದು | ರಿಸೆಟ್ ಟೈಮ್ಔಟ್ | | ------- | ---------------- | ------------ | -------------- | | OAuth | 5 ವಿಫಲತೆಗಳು | 8 ವಿಫಲತೆಗಳು | 60s | | API-key | 7 ವಿಫಲತೆಗಳು | 12 ವಿಫಲತೆಗಳು | 30s | | Local | ಲೆಕ್ಕಹಾಕಲಾಗಿದೆ | 2 ವಿಫಲತೆಗಳು | 15s | `degradationThreshold` ಪ್ರೊವೈಡರ್ ಯಾವಾಗ `DEGRADED` ಗೆ ಪ್ರವೇಶಿಸುತ್ತದೆ ಎಂಬುದನ್ನು ನಿಯಂತ್ರಿಸುತ್ತದೆ; `failureThreshold` ಅದು ಯಾವಾಗ ಓಪನ್ ಆಗುತ್ತದೆ ಮತ್ತು ಬಿಟ್ಟುಬಿಡಲಾಗುತ್ತದೆ ಎಂಬುದನ್ನು ನಿಯಂತ್ರಿಸುತ್ತದೆ. ಸ್ಥಳೀಯ ಪ್ರೊವೈಡರ್ ಪ್ರೊಫೈಲ್ಗಳನ್ನು ಇನ್ನೂ ರೆಸಿಲಿಯನ್ಸ್ ಸೆಟ್ಟಿಂಗ್ಗಳ ಪುಟದಲ್ಲಿ ಅನಾವರಣಗೊಳಿಸಲಾಗಿಲ್ಲ. **ಟ್ರಿಪ್ ಕೋಡ್ಗಳು:** ಕೇವಲ ಪ್ರೊವೈಡರ್-ಮಟ್ಟದ ಸ್ಥಿತಿಗಳು `[408, 500, 502, 503, 504]`. ಖಾತೆ-ಮಟ್ಟದ ದೋಷಗಳಿಗೆ ಟ್ರಿಪ್ ಮಾಡಬೇಡಿ (ಹೆಚ್ಚಿನ 401/403/429 — ಅವು ಕೂಲ್ಡೌನ್ ಅಥವಾ ಲಾಕ್ಔಟ್ಗೆ ಸೇರಿದವು). **ಲೇಜಿ ರಿಕವರಿ:** `OPEN` ಅವಧಿ ಮುಗಿದಾಗ, `getStatus()`, `canExecute()`, `getRetryAfterMs()` ಸ್ಥಿತಿಯನ್ನು `HALF_OPEN` ಗೆ ರಿಫ್ರೆಶ್ ಮಾಡುತ್ತವೆ. ಅದೇ ಓದುವಿಕೆಗಳು (ಮತ್ತು ಮುಂದಿನ ವಿಫಲತೆ) ಹಳೆಯಾದ `DEGRADED` ಅನ್ನು ಮತ್ತೆ `CLOSED` ಗೆ ಕ್ಷಯಿಸುತ್ತವೆ. ಬ್ಯಾಕ್ಗ್ರೌಂಡ್ ಟೈಮರ್ ಅಗತ್ಯವಿಲ್ಲ. --- ### ಆಪ್ಟ್-ಇನ್ ಜಾಗತಿಕ ಪ್ರೊವೈಡರ್ ಕೂಲ್ಡೌನ್ (ವಿಂಡೋ ಗೇಟ್) ನಾಲ್ಕನೆಯ, **ಆಪ್ಟ್-ಇನ್** ಪದರ (`PROVIDER_COOLDOWN_ENABLED`, ಡೀಫಾಲ್ಟ್ **ಆಫ್**) `open-sse/services/providerCooldownTracker.ts` ನಲ್ಲಿ ವಿಫಲವಾಗುತ್ತಿರುವ ಪ್ರೊವೈಡರ್ಗಳ ಕ್ರಾಸ್-ರಿಕ್ವೆಸ್ಟ್ ಮೆಮೊರಿಯನ್ನು ಇರಿಸುತ್ತದೆ; ಕಾಂಬೊ ಟಾರ್ಗೆಟ್ ರೆಸಲ್ಯೂಶನ್ ಇದನ್ನು ಸಂಪರ್ಕಿಸುತ್ತದೆ, ಆದ್ದರಿಂದ ಸತತ ಕಾಂಬೊ ವಿನಂತಿಗಳು ಈಗಷ್ಟೇ ವಿಫಲವಾದ ಪ್ರೊವೈಡರ್ ಅನ್ನು ಮತ್ತೆ ಹಾದುಹೋಗುವುದನ್ನು ನಿಲ್ಲಿಸುತ್ತವೆ. ಪ್ರೊವೈಡರ್-ಮಟ್ಟದ ಎಂಟ್ರಿಗಳು `PROVIDER_PROFILES` ವಿಂಡೋ ಗೇಟ್ ಅನ್ನು ಗೌರವಿಸುತ್ತವೆ: | ಪ್ರೊಫೈಲ್ | ಟ್ರಿಪ್ ಆಗುವುದು (`providerFailureThreshold`) | ಅವಧಿಯೊಳಗೆ (`providerFailureWindowMs`) | ಕೂಲ್ ಆಗುವ ಅವಧಿ (`providerCooldownMs`) | | -------- | ------------------------------------------: | ------------------------------------: | ------------------------------------: | | OAuth | `10` | `15min` | `5min` | | API key | `15` | `30min` | `10min` | ಮಿತಿಗಿಂತ ಕೆಳಗೆ ಪ್ರೊವೈಡರ್ ಕೂಲಿಂಗ್ನಲ್ಲಿ **ಇಲ್ಲ** ಎಂದು ಪರಿಗಣಿಸಲಾಗುತ್ತದೆ; ಯಶಸ್ಸು ವಿಂಡೋವನ್ನು ತೆರವುಗೊಳಿಸುತ್ತದೆ. ಸಂಪರ್ಕ-ಮಟ್ಟದ ಎಂಟ್ರಿಗಳು (`provider:connectionId`) ಬದಲಾಗಿ ಘಾತಾಂಕೀಯ `minRetryCooldownMs → maxRetryCooldownMs` ಬ್ಯಾಕ್ಆಫ್ ಅನ್ನು ಇರಿಸುತ್ತವೆ. ಓವರ್ರೈಡ್ಗಳು: `OMNIROUTE_PROVIDER_BREAKER_{OAUTH,API_KEY}_{FAILURE_THRESHOLD,FAILURE_WINDOW_MS,COOLDOWN_MS}`. ರಿಗ್ರೆಶನ್ ಗಾರ್ಡ್: `tests/unit/provider-cooldown-window-gate.test.ts`. ## 2. ಸಂಪರ್ಕ ಕೂಲ್ಡೌನ್ **ವ್ಯಾಪ್ತಿ:** ಏಕೈಕ ಪ್ರೊವೈಡರ್ ಸಂಪರ್ಕ/ಖಾತೆ/ಕೀ. **ಉದ್ದೇಶ:** ಅದೇ ಪ್ರೊವೈಡರ್ಗಾಗಿ ಇತರ ಸಂಪರ್ಕಗಳು ಸೇವೆ ನೀಡುತ್ತಿರುವಾಗ ಒಂದು ಕೆಟ್ಟ ಕೀಯನ್ನು ಬಿಟ್ಟುಬಿಡುವುದು. **ಅನುಷ್ಠಾನ:** - ಲಭ್ಯವಿಲ್ಲದಂತೆ ಗುರುತಿಸುವುದು: `src/sse/services/auth.ts::markAccountUnavailable()` - ಆಯ್ಕೆ: ಅದೇ ಫೈಲ್ನಲ್ಲಿ `getProviderCredentials*` - ಕೂಲ್ಡೌನ್ ಲೆಕ್ಕಾಚಾರ: `open-sse/services/accountFallback.ts::checkFallbackError()` - ಸೆಟ್ಟಿಂಗ್ಗಳು: `src/lib/resilience/settings.ts` **ಪ್ರತಿ ಸಂಪರ್ಕಕ್ಕೆ ಕ್ಷೇತ್ರಗಳು:** - `rateLimitedUntil` — ಕೂಲ್ಡೌನ್ ಮುಗಿಯುವವರೆಗಿನ ಟೈಮ್ಸ್ಟ್ಯಾಂಪ್ - `testStatus: "unavailable"` - `lastError`, `lastErrorType`, `errorCode` - `backoffLevel` — ಘಾತಾಂಕೀಯ ಬ್ಯಾಕ್ಆಫ್ ಕೌಂಟರ್ **ಡಿಫಾಲ್ಟ್ ಕೂಲ್ಡೌನ್ಗಳು:** - OAuth ಬೇಸ್: 5s - API-ಕೀ ಬೇಸ್: 3s - API-ಕೀ 429: ಅಪ್ಸ್ಟ್ರೀಮ್ `Retry-After`/reset ಹೆಡರ್ಗಳು/ಪಾರ್ಸ್ ಮಾಡಬಹುದಾದ reset ಪಠ್ಯವನ್ನು ಆದ್ಯತೆ ನೀಡುತ್ತದೆ - ಬ್ಯಾಕ್ಆಫ್: `baseCooldownMs * 2 ** failureIndex` **ಆಂಟಿ-ಥಂಡರಿಂಗ್-ಹರ್ಡ್ ರಕ್ಷಣೆ:** ಏಕಕಾಲಿಕ ವೈಫಲ್ಯಗಳು ಕೂಲ್ಡೌನ್ ಅನ್ನು ಅತಿಯಾಗಿ ವಿಸ್ತರಿಸುವುದನ್ನು ಅಥವಾ `backoffLevel` ಅನ್ನು ಎರಡು ಬಾರಿ ಹೆಚ್ಚಿಸುವುದನ್ನು ತಡೆಯುತ್ತದೆ. **ಹೊಂದಾಣಿಕೆ-ಮಿತಿ (concurrency-limit) 429 ಗಳು ಬ್ಯಾಕ್ಆಫ್ ಮೆಟ್ಟಿಲನ್ನು ಏರುವುದಿಲ್ಲ.** ಹೊಂದಾಣಿಕೆ ಮಿತಿಯನ್ನು ವರದಿ ಮಾಡುವ ಬಾಡಿ ಹೊಂದಿರುವ `429` ("too many concurrent requests", "concurrency limit", "parallel request limit", GLM `并发数过高`) ಎಂದರೆ ಖಾತೆ ಆರೋಗ್ಯವಾಗಿದೆ ಆದರೆ ಬಿಜಿಯಾಗಿದೆ. `checkFallbackError()` ಕಾರಣ `concurrency_limited` ಅನ್ನು ಹಿಂದಿರುಗಿಸುತ್ತದೆ: ಈಗಲೇ ಮುಂದಿನ ಸಂಪರ್ಕಕ್ಕೆ ಫೈಲ್ಓವರ್ ಮಾಡಿ, ಈ ಸಂಪರ್ಕವನ್ನು ಸ್ಥಿರ `CONCURRENCY_LIMIT_COOLDOWN_MS` (1s) ಅಥವಾ ಅಪ್ಸ್ಟ್ರೀಮ್ retry ಸುಳಿವಿನವರೆಗೆ ಕೂಲ್ ಮಾಡಿ, `backoffLevel` ಅನ್ನು ಬದಲಾಯಿಸದೆ ಇರಿಸಿ, ಮತ್ತು `skipProviderBreaker` ಅನ್ನು ಸೆಟ್ ಮಾಡಿ. ಸ್ಪಷ್ಟ quota ಬಾಡಿ ಇನ್ನೂ ಗೆಲುತ್ತದೆ, ಆದ್ದರಿಂದ quota ಪ್ಯಾಟರ್ನ್ಗೂ ಹೊಂದಿಕೆಯಾಗುವ ಬಾಡಿ quota ತೀರ್ಪಾಗಿಯೇ ಉಳಿಯುತ್ತದೆ. ಪತ್ತೆ: `src/shared/utils/classify429.ts` ನಲ್ಲಿ `looksLikeConcurrencyLimit()`; ತೀರ್ಪು: `open-sse/services/accountFallback/concurrencyLimit429.ts`. `classify429()` (ಬ್ರೇಕರ್ನ `FailureKind`) ಬದಲಾಗಿಲ್ಲ ಮತ್ತು ಈ ಬಾಡಿಗಳಿಗೆ ಇನ್ನೂ `rate_limit` ಅನ್ನೇ ಓದುತ್ತದೆ. **ಸ್ಟ್ರೀಮ್ ಕಂಟೆಂಟ್ ನಿಲುಗಡೆಗಳು ಖಾತೆಯನ್ನು ಕೂಲ್ ಮಾಡುವುದಿಲ್ಲ.** ಕಂಟೆಂಟ್-ಸ್ಟಾಲ್ ವಾಚ್ಡಾಗ್ (`open-sse/utils/streamHandler.ts`) ಸಮಯದೊಳಗೆ ಯಾವುದೇ ಮಾಡೆಲ್ ಔಟ್ಪುಟ್ ಕಳುಹಿಸದ ಸ್ಟ್ರೀಮ್ ಬಗ್ಗೆ ಹಾರೈಸಿದಾಗ, `markAccountUnavailable()` ದೋಷವನ್ನು ಸಂಪರ್ಕದಲ್ಲಿ ದಾಖಲಿಸುತ್ತದೆ ಆದರೆ ಯಾವುದೇ ಕೂಲ್ಡೌನ್ ಸೆಟ್ ಮಾಡುವುದಿಲ್ಲ: ನಿಲುಗಡೆ ಆ ವಿನಂತಿಗೆ ಸೇರಿದ್ದು, ಹೆಚ್ಚಾಗಿ ಇನ್ನೂ ಔಟ್ಪುಟ್ ಇಲ್ಲದ ಉದ್ದನೆಯ reasoning ಟರ್ನ್. ಆಪರೇಟರ್ಗಳು `resilienceSettings.streamStallCooldown.enabled` ಮೂಲಕ ಮತ್ತೆ ಆಪ್ಟ್-ಇನ್ ಮಾಡಬಹುದು (ಡಿಫಾಲ್ಟ್ `false`). **Reasoning ಫ್ರೇಮ್ಗಳು ಕಂಟೆಂಟ್-ಸ್ಟಾಲ್ ಬಜೆಟ್ ಅನ್ನು ಮರುಪ್ರಾರಂಭಿಸುತ್ತವೆ.** reasoning ಮಾಡೆಲ್ ತನ್ನ ಮೊದಲ ಗೋಚರ ಟೋಕನ್ಗೆ ಮೊದಲು ನಿಮಿಷಗಳ ಕಾಲ ಯೋಚಿಸಬಹುದು: Claude `thinking_delta` ಫ್ರೇಮ್ಗಳನ್ನು ಸ್ಟ್ರೀಮ್ ಮಾಡುತ್ತದೆ ಅವುಗಳ thinking ಪಠ್ಯ ಖಾಲಿ ಇರಬಹುದು, ಮತ್ತು Responses API ಒಂದನೆಯ ಹಿಂದೆ ಇನ್ನೊಂದು reasoning ಐಟಂ ಅನ್ನು ಸ್ಟ್ರೀಮ್ ಮಾಡುತ್ತದೆ. `isReasoningProgressFrame()` (`open-sse/utils/streamReadiness.ts`) ಈ ಫ್ರೇಮ್ಗಳನ್ನು ಗುರುತಿಸುತ್ತದೆ, ಮತ್ತು ವಾಚ್ಡಾಗ್ ಪ್ರತಿಯೊಂದರ ಮೇಲೂ ತನ್ನ ಬಜೆಟ್ ಅನ್ನು ಮರುಪ್ರಾರಂಭಿಸುತ್ತದೆ, ಟರ್ನ್ ಅನ್ನು ರದ್ದು ಮಾಡುವ ಬದಲು. ಅವು ಇನ್ನೂ ಮಾಡೆಲ್ ಔಟ್ಪುಟ್ ಅಲ್ಲ, ಆದ್ದರಿಂದ ಕೇವಲ reasoning ನೊಂದಿಗೆ ಮುಗಿಯುವ ಟರ್ನ್ ಇನ್ನೂ ಖಾಲಿ ಎಂದು ವರದಿಯಾಗುತ್ತದೆ, ಮತ್ತು reasoning ನಿಲ್ಲಿಸಿ ಕೇವಲ ಹಾರ್ಟ್ಬೀಟ್ಗಳನ್ನು ಕಳುಹಿಸುವ ಟರ್ನ್ ಇನ್ನೂ ವಾಚ್ಡಾಗ್ ಅನ್ನು ತrips ಮಾಡುತ್ತದೆ. ಖಾಲಿಯಲ್ಲದ ಸಹಿಯೊಂದಿಗೆ Kiro ಯ ಬೈನರಿ `reasoningContentEvent` ಫ್ರೇಮ್ಗಳು ಈ reasoning ಚಟುವಟಿಕೆಯನ್ನು executor ಮೂಲಕ ಖಾಲಿ `reasoning_content` ಡೆಲ್ಟಾವಾಗಿ ಉಳಿಸುತ್ತವೆ. ಸಹಿಯನ್ನು ಫಾರ್ವರ್ಡ್ ಮಾಡಲಾಗುವುದಿಲ್ಲ. ಮೆಟಾಡೇಟಾ, ಅಪೂರ್ಣ ಫ್ರೇಮ್ಗಳು ಮತ್ತು ಖಾಲಿ ಸಹಿಗಳು ಕಂಟೆಂಟ್ ಬಜೆಟ್ ಅನ್ನು ಮರುಪ್ರಾರಂಭಿಸುವುದಿಲ್ಲ; ಸ್ವತಂತ್ರ ಸಕ್ರಿಯ-ಸ್ಟ್ರೀಮ್ ಟೈಮ್ಔಟ್ ಮತ್ತು ಕ್ಲೈಂಟ್ ರದ್ದತಿ ಇನ್ನೂ ಅನ್ವಯಿಸುತ್ತವೆ (`open-sse/executors/kiro/reasoning.ts`). **ಅಂತಿಮ ಸ್ಥಿತಿಗಳು (ಕೂಲ್ಡೌನ್ಗಳು ಅಲ್ಲ):** - `banned` — ನಿಷೇಧಿತ-ಕೀವರ್ಡ್ / ಖಾತೆ-ನಿಷೇಧ ಪತ್ತೆಯಿಂದ ಸೆಟ್ ಆಗುತ್ತದೆ (ನೋಡಿ [BAN_DETECTION](../security/BAN_DETECTION.md)), ಮತ್ತು ಸತತ ಮೂರು ಅಪ್ಸ್ಟ್ರೀಮ್ ಪ್ರತಿ-ವಿನಂತಿ ನಿರಾಕರಣೆಗಳಿಂದ (`request_rejected`, ಉದಾ. Anthropic OAuth 403 "Request not allowed" — `open-sse/services/requestRejectedStreak.ts`); ಒಂದೇ ನಿರಾಕರಣೆ ಸಂಪರ್ಕವನ್ನು ಕೂಲ್ ಡೌನ್ ಮಾಡುತ್ತದೆ ಮಾತ್ರ - `expired` (ಸೀಮಿತ ಮರುಪ್ರಯತ್ನಗಳ ನಂತರ ಅಂತಿಮ ಸ್ಥಿತಿಗೆ ಪರಿವರ್ತನೆ — `EXPIRED_RETRY_MAX = 3` ಘಾತಾಂಕೀಯ ಬ್ಯಾಕ್ಆಫ್ನೊಂದಿಗೆ — ಆದ್ದರಿಂದ ತಾತ್ಕಾಲಿಕ OAuth ದೋಷಗಳು ಖಾತೆ ಶಾಶ್ವತವಾಗಿ ನಿಷ್ಕ್ರಿಯಗೊಳ್ಳುವ ಮೊದಲು ಸ್ವಯಂ-ಗುಣಮುಖವಾಗಬಹುದು) - `credits_exhausted` ಇವು ಕ್ರೆಡೆನ್ಷಿಯಲ್ಗಳು ಬದಲಾಗುವವರೆಗೆ ಅಥವಾ ಆಪರೇಟರ್ ಅವುಗಳನ್ನು ರೀಸೆಟ್ ಮಾಡುವವರೆಗೆ ಉಳಿಯುತ್ತವೆ. ಅಂತಿಮ ಸ್ಥಿತಿಗಳನ್ನು ತಾತ್ಕಾಲಿಕ ಕೂಲ್ಡೌನ್ ಸ್ಥಿತಿಯೊಂದಿಗೆ ಬದಲಾಯಿಸಬೇಡಿ. **ಸೋಜಿಗ (lazy) ಚೇತರಿಕೆ:** `rateLimitedUntil` ಕಳೆದ ನಂತರ, ಸಂಪರ್ಕ ಮತ್ತೆ ಅರ್ಹವಾಗುತ್ತದೆ. ಯಶಸ್ವಿ ಬಳಕೆಯ ಮೇಲೆ, `clearAccountError()` ಎಲ್ಲಾ ದೋಷ ಕ್ಷೇತ್ರಗಳನ್ನು ತೆರವುಗೊಳಿಸುತ್ತದೆ. ### Claude OAuth ಬಳಕೆಯ ಗೋಡೆ: ಕಡಿಮೆ-ಆದ್ಯತೆಯ ಲೇನ್ + ಸೆಷನ್-ಮಿತಿ ರೀಸೆಟ್ **ವ್ಯಾಪ್ತಿ:** ಒಂದು Claude ಸಬ್ಸ್ಕ್ರಿಪ್ಷನ್ (OAuth) ಸಂಪರ್ಕ. ಎರಡೂ ವೈಶಿಷ್ಟ್ಯಗಳು **ಪ್ರತಿ ಸಂಪರ್ಕಕ್ಕೆ ಆಪ್ಟ್-ಇನ್** (ಸಂಪರ್ಕ ಎಡಿಟ್ ಮಾಡಿ → Claude ವಿಭಾಗ → `providerSpecificData` ನಲ್ಲಿ `lowPriorityMode` / `autoLimitReset`, ಎರಡೂ ಡಿಫಾಲ್ಟ್ ಆಫ್) ಮತ್ತು Claude Code ನ `/low-priority` ಮತ್ತು `/limit-reset` ಕಮಾಂಡ್ಗಳನ್ನು ಪ್ರತಿಬಿಂಬಿಸುತ್ತವೆ (Claude Code 2.1.263 ರಿಂದ ಸೆರೆಹಿಡಿದ ವೈರ್ ಕಾಂಟ್ರಾಕ್ಟ್). **ಅನುಷ್ಠಾನ:** - ಸ್ಟೇಟ್ ಮಷೀನ್ + ರೆಸ್ಪಾನ್ಸ್ ವರ್ಗೀಕರಣ: `open-sse/services/claudeLowPriority.ts` - ರೀಸೆಟ್ ಸ್ಥಿತಿ/ಕ್ಲೇಮ್ ಕ್ಲೈಂಟ್: `open-sse/services/claudeLimitReset.ts` - Executor ಹುಕ್ (ಹೆಡರ್ ಇಂಜೆಕ್ಷನ್ + ಅದೇ-ಖಾತೆ ಮರುಪ್ರಯತ್ನ): `open-sse/executors/base.ts::execute()` - ಆಪ್ಟ್-ಇನ್ ಪರ್ಸಿಸ್ಟೆನ್ಸ್: `src/lib/providers/requestDefaults.ts::normalizeProviderSpecificData()` **ಟ್ರಿಗರ್:** 5-ಗಂಟೆಯ ಬಳಕೆಯ ಗೋಡೆ — ಹೆಡರ್ಗಳಲ್ಲಿ `anthropic-ratelimit-unified-status: rejected` ಮತ್ತು, ಖಾತೆ ಅರ್ಹವಾಗಿದ್ದಾಗ, `anthropic-ratelimit-unified-slow-offer: treatment` ಹೊಂದಿರುವ `429`. ಆ ಮೊದಲ ಗೋಡೆಯ 429 ಗೆ ಮೊದಲು ಏನೂ ಕಳುಹಿಸಲಾಗುವುದಿಲ್ಲ; ಯುನಿಫೈಡ್ ಹೆಡರ್ಗಳಿಲ್ಲದ ಬರ್ಸ್ಟ್ 429 ಸಾಮಾನ್ಯ ಕೂಲ್ಡೌನ್ ಮಾರ್ಗದ ಮೂಲಕ ಹೋಗುತ್ತದೆ. **ಕಡಿಮೆ-ಆದ್ಯತೆಯ ಲೇನ್** (`lowPriorityMode`): - 429 wall ಮೇಲೆ ಎಕ್ಸಿಕ್ಯೂಟರ್ ಆಫರ್ ಅನ್ನು ಸ್ವೀಕರಿಸಿ ತಕ್ಷಣವೇ **ಅದೇ** ಖಾತೆಯನ್ನು `anthropic-usage-limit: slow` ನೊಂದಿಗೆ ಮರುಪ್ರಯತ್ನಿಸುತ್ತದೆ; ಘೋಷಿತ `anthropic-ratelimit-unified-reset` (+60s grace) ತನಕ ಲೇನ್ ಸಕ್ರಿಯವಾಗಿರುತ್ತದೆ ಮತ್ತು ಆ ವಿಂಡೋನ内的 ಪ್ರತಿಯೊಂದು ವಿನಂತಿಯೂ ಆ ಹೆಡರ್ ಅನ್ನು ಹೊಂದಿರುತ್ತದೆ. ಇಂಟರ್ಸೆಪ್ಟ್ ಮಾಡಲಾದ 429 ಎಂದಿಗೂ `handleChatCore` ಅನ್ನು ತಲುಪುವುದಿಲ್ಲ, ಆದ್ದರಿಂದ ಸಂಪರ್ಕವನ್ನು ಕೂಲ್ಡೌನ್ನಲ್ಲಿ ಇರಿಸಲಾಗುವುದಿಲ್ಲ ಮತ್ತು ಅದನ್ನು ತಿರುಗಿಸಲಾಗುವುದಿಲ್ಲ. - ನಂತರದ ಪ್ರತಿಕ್ರಿಯೆಗಳ ಮೇಲೆ `anthropic-ratelimit-unified-slow-status`: `active` / `not_needed` ಲೇನ್ ಅನ್ನು ಮುಂದುವರೆಸುತ್ತವೆ; `slot_busy` (429) ಅಥವಾ `529` ಸರ್ವರ್ನ `anthropic-ratelimit-unified-slow-retry-after` (ಡೀಫಾಲ್ಟ್ 20s, clamp 5–600s, ±30% jitter) ಕಾಯುತ್ತದೆ ಮತ್ತು ಮರುಪ್ರಯತ್ನಿಸುತ್ತದೆ, ಇದು `anthropic-ratelimit-unified-slow-max-wait` (ಡೀಫಾಲ್ಟ್ 20 ನಿಮಿಷ, clamp 1 ನಿಮಿಷ–6 ಗಂಟೆ) ಮೂಲಕ ನಿರ್ಬಂಧಿತವಾಗಿದೆ — ಅದನ್ನು ಮೀರಿದರೆ ಲೇನ್ ಕೊನೆಯಾಗುತ್ತದೆ ಮತ್ತು 10-ನಿಮಿಷದ cool-off ಮರು-ಸ್ವೀಕಾರವನ್ನು ನಿರ್ಬಂಧಿಸುತ್ತದೆ. ಈ ಕಾಯುವಿಕೆಯನ್ನು ಹೆಚ್ಚುವರಿಯಾಗಿ ವಿನಂತಿಯ ಸ್ವಂತ upstream-start timeout (`resolveFetchStartTimeout`, ಡೀಫಾಲ್ಟ್ ಆಗಿ 10 ನಿಮಿಷ)ದ ಉಳಿದ ಭಾಗದಿಂದ 5 s margin ಕಡಿಮೆ ಮಾಡಿ ಕ್ಯಾಪ್ ಮಾಡಲಾಗುತ್ತದೆ: ಆ ಕ್ಯಾಪ್ ಇಲ್ಲದಿದ್ದರೆ 20-ನಿಮಿಷದ ಡೀಫಾಲ್ಟ್ max-wait ವಿನಂತಿಗಿಂತ ಹೆಚ್ಚು ಕಾಲ ಬಾಳುತ್ತಿತ್ತು ಮತ್ತು sleep ಅನ್ನು ಕಾಯುವಿಕೆಯ ಮಧ್ಯದಲ್ಲೇ abort ಮಾಡಲಾಗುತ್ತಿತ್ತು, ಇದು ಸುಗಮ `max_wait` ಅಂತ್ಯ + cool-off ಬದಲಾಗಿ `TimeoutError` ಅನ್ನು ಹೊರಹಾಕುತ್ತಿತ್ತು. - `weekly_limit` / `budget_exhausted` / `off` / `ineligible`, 5h-window rollover, ಅಥವಾ `ineligible` + `anthropic-ratelimit-unified-overage-in-use: true` (ಇದು ಯಾವುದೇ ಸ್ಥಿತಿಯಲ್ಲಿಯೂ ಅದನ್ನು `extra_usage` ಆಗಿ ಮುಗಿಸುತ್ತದೆ, ಏಕೆಂದರೆ ಈಗ ಪಾವತಿಸಿದ overage wall ಅನ್ನು ಒಳಗೊಂಡಿದೆ) ಲೇನ್ ಅನ್ನು ಮುಗಿಸುತ್ತವೆ; ನಂತರ ಪ್ರತಿಕ್ರಿಯೆಯು ಸಾಮಾನ್ಯ ಕೂಲ್ಡೌನ್ ಮಾರ್ಗಕ್ಕೆ ಹರಿಯುತ್ತದೆ. `budget_exhausted` ಅನ್ನು ಘೋಷಿತ budget reset (≤ 8 ದಿನಗಳು) ತನಕ ನೆನಪಿಡಲಾಗುತ್ತದೆ. - wall ಪರಿಶೀಲನೆಯು ಎಕ್ಸಿಕ್ಯೂಟರ್ನ ಸ್ವಂತ 400-ಚಾಲಿತ intra-attempt ಮರುಪ್ರಯತ್ನಗಳ (context editing, thinking/effort clamps, param auto-learn) ನಂತರ ಚಲಾಯಿಸಲಾಗುತ್ತದೆ, ಆದ್ದರಿಂದ ಆ ಮರುಪ್ರಯತ್ನಗಳಲ್ಲಿ ಒಂದರಲ್ಲಿ ಮಾತ್ರ ಕಂಡುಬರುವ wall 429 ಸಹ ಕೂಲ್ಡೌನ್ ಮಾರ್ಗವನ್ನು ತಲುಪುವ ಬದಲು ಇಂಟರ್ಸೆಪ್ಟ್ ಆಗುತ್ತದೆ. - ಸ್ಥಿತಿಯು ಪ್ರತಿ ಸಂಪರ್ಕಕ್ಕೆ in-memory ಆಗಿದೆ (ಮರುಪ್ರಾರಂಭವು ಮರು-ಸ್ವೀಕಾರಕ್ಕೆ ಒಂದು ಹೆಚ್ಚುವರಿ wall 429 ಬೆಲೆಯನ್ನು ಒಳಗೊಂಡಿರುತ್ತದೆ). **Session-limit reset** (`autoLimitReset`, ಎರಡೂ ಆನ್ ಆಗಿದ್ದಾಗ ಲೇನ್ಗಿಂತ ಮೊದಲು ಪ್ರಯತ್ನಿಸಲಾಗುತ್ತದೆ): - `GET https://api.anthropic.com/api/oauth/usage?at_wall=1&skip_spend=1` → `juniper_tide` ಬ್ಲಾಕ್; `arm: "reset"` ಮತ್ತು `available: true` ಆಗಿರುವಾಗ, `{ "program": "juniper_tide" }` ಸಹಿತ `POST https://api.anthropic.com/api/organizations/{orgUUID}/reset_rate_limits` (organization UUID `providerSpecificData.organizationUUID` ನಿಂದ, bootstrap fallback). - `result: reset|not_limited` → ವಿನಂತಿಯನ್ನು ಪೂರ್ಣ ವೇಗದಲ್ಲಿ ಮರುಪ್ರಯತ್ನಿಸಲಾಗುತ್ತದೆ (slow ಹೆಡರ್ ಇಲ್ಲ). `already_used` / `not_offered` `next_available_at` ಅನ್ನು memoise ಮಾಡುತ್ತವೆ (ಡೀಫಾಲ್ಟ್ ಒಂದು ವಾರ); ಯಾವುದೇ ವೈಫಲ್ಯವು 15 ನಿಮಿಷಗಳ ಕಾಲ back off ಆಗುತ್ತದೆ. reset ವಾರಕ್ಕೊಮ್ಮೆ ಮತ್ತು ಅದು ಇನ್ನೂ ವಾರದ ಮಿತಿಗೆ ಲೆಕ್ಕವಾಗುತ್ತದೆ. Regression guards: `tests/unit/claude-low-priority-mode.test.ts`, `tests/unit/claude-limit-reset.test.ts`, `tests/unit/claude-low-priority-executor.test.ts`. ### Session affinity (#7274) **ವ್ಯಾಪ್ತಿ:** ಒಂದು ಕ್ಲೈಂಟ್ ಸೆಷನ್ (`X-Session-Id` / `x-codex-session-id` / `x-omniroute-session` ಹೆಡರ್) ಒಂದು ಸಂಪರ್ಕಕ್ಕೆ ಪಿನ್ ಮಾಡಲಾಗಿದೆ, **ಯಾವುದೇ** ಪ್ರೊವೈಡರ್ಗೆ. **ಉದ್ದೇಶ:** ಬಹು-ಟರ್ನ್ ಏಜೆಂಟ್ (Claude Code, aider, ಕಸ್ಟಮ್ ಏಜೆಂಟ್ಗಳು) ಅನ್ನು ವಿನಂತಿಗಳಾದ್ಯಂತ ಒಂದೇ ಖಾತೆಯಲ್ಲಿಡುವುದು, ಕ್ರಾಸ್-ಖಾತೆ context ನಷ್ಟವನ್ನು ಕಡಿಮೆ ಮಾಡುವುದು ಮತ್ತು ಪ್ರತಿ-ಖಾತೆ session ಸ್ಥಿತಿಯನ್ನು ಹೊಂದಿರುವ ಪ್ರೊವೈಡರ್ಗಳಲ್ಲಿ ಪುನರಾವರ್ತಿತ cold-start 429ಗಳನ್ನು ಕಡಿಮೆ ಮಾಡುವುದು. **ಅನುಷ್ಠಾನ:** - TTL ರೆಸಲ್ಯೂಶನ್: `src/sse/services/sessionAffinityPin.ts::resolveSessionAffinityTtlMs()` - ಪಿನ್ ಆಯ್ಕೆ/ರಚನೆ: `src/sse/services/sessionAffinityPin.ts::selectSessionAffinityConnection()` - ಹೆಡರ್ ಹೊರತೆಗೆಯುವಿಕೆ (ಜೆನರಿಕ್, ಯಾವುದೇ ಪ್ರೊವೈಡರ್): `src/sse/services/auth.ts::extractSessionAffinityKey()` - persisted ಪಿನ್ ಟೇಬಲ್: `sessionAccountAffinity` (`src/lib/db/sessionAccountAffinity.ts`) - ಸೆಟ್ಟಿಂಗ್: `sessionAffinityTtlMs` (ms ನಲ್ಲಿ ಜಾಗತಿಕ TTL, `0` ನಿಷ್ಕ್ರಿಯಗೊಳಿಸುತ್ತದೆ) — `src/lib/db/settings.ts`. ಮೈಗ್ರೇಶನ್ `124_generic_session_affinity_ttl.sql` ಮೂಲಕ Codex-only `codexSessionAffinityTtlMs` ನಿಂದ ಮರುಹೆಸರಿಸಲಾಗಿದೆ, ಇದು ಹಿಂದೆ ಕಾನ್ಫಿಗರ್ ಮಾಡಲಾದ ಯಾವುದೇ Codex TTL ಅನ್ನು ಹೊಸ ಡೀಫಾಲ್ಟ್ ಆಗಿ ವಹಿಸುತ್ತದೆ. #7274 ಕ್ಕಿಂತ ಮೊದಲು, `resolveSessionAffinityTtlMs()` `codex` ಹೊರತು ಪ್ರತಿಯೊಂದು ಪ್ರೊವೈಡರ್ಗೂ `0` ಗೆ hard-bail ಆಗುತ್ತಿತ್ತು, ಆದ್ದರಿಂದ ಪಿನ್ನಿಂಗ್ ಮೆಕ್ಯಾನಿಸಮ್ ಮತ್ತು ಹೆಡರ್ ಹೊರತೆಗೆಯುವಿಕೆ ಈಗಾಗಲೇ ಪ್ರೊವೈಡರ್-ಅಜ್ಞಾತವಾಗಿದ್ದರೂ, TTL ಸೆಟ್ಟಿಂಗ್ (ಮತ್ತು session ಹೆಡರ್ಗಳು) ಬೇರೆ ಎಲ್ಲಿಯೂ ಯಾವುದೇ ಪರಿಣಾಮವನ್ನು ಬೀರುತ್ತಿರಲಿಲ್ಲ. ಈ ಫಿಕ್ಸ್ ಆ early-return ಅನ್ನು ತೆಗೆದುಹಾಕಿತು; ಈಗ TTL ಜಾಗತಿಕವಾಗಿ `0` ಕ್ಕಿಂತ ಮೇಲೆ ಹೊಂದಿಸಿದ ನಂತರ ಪ್ರತಿಯೊಂದು ಪ್ರೊವೈಡರ್ಗೂ ಏಕರೂಪದಲ್ಲಿ ಅನ್ವಯಿಸುತ್ತದೆ. ಮೂರು session-affinity ಹೆಡರ್ಗಳನ್ನು ಎಂದಿಗೂ upstream ಗೆ ಫಾರ್ವರ್ಡ್ ಮಾಡಲಾಗುವುದಿಲ್ಲ — ಎಕ್ಸಿಕ್ಯೂಟರ್ಗಳು ಕ್ಲೈಂಟ್ ಹೆಡರ್ಗಳನ್ನು ಹಾಗೇ ರವಾನಿಸುವ ಬದಲು ತಮ್ಮ ಸ್ವಂತ upstream ಹೆಡರ್ಗಳನ್ನು ಹೊಸದಾಗಿ ನಿರ್ಮಿಸುತ್ತಾರೆ, ಆದ್ದರಿಂದ ಇದು ಆಂತರಿಕ correlation id ಆಗಿ ಮಾತ್ರ ಉಳಿಯುತ್ತದೆ. ### Exclusive managed session connection leases **ವ್ಯಾಪ್ತಿ:** ಒಂದು ಸಕ್ರಿಯ managed HTTP ಕ್ಲೈಂಟ್/ಸೆಷನ್ ಒಂದು ಅರ್ಹ OmniRoute ಸಂಪರ್ಕವನ್ನು ಹೊಂದಿರುತ್ತದೆ. **ಉದ್ದೇಶ:** ವಿನಂತಿಗಳಾದ್ಯಂತ ಕಠಿಣ routing ಬೇಲಿ ಬೇಕಾಗುವ ಕ್ಲೈಂಟ್ಗಳಿಗೆ ದೀರ್ಘಕಾಲದ ಎಕ್ಸ್ಕ್ಲೂಸಿವ್ ಸಂಪರ್ಕ ಮಾಲೀಕತ್ವವನ್ನು ಒದಗಿಸುವುದು. ಇದು session affinity ಯಿಂದ ಭಿನ್ನವಾಗಿದೆ, ಅದು ಮೃದುವಾದ continuity ಆದ್ಯತೆ: ಎಕ್ಸ್ಕ್ಲೂಸಿವ್ ಲೀಸ್ lifecycle ಸ್ಥಿತಿಯನ್ನು SQLite ನಲ್ಲಿ persist ಮಾಡುತ್ತದೆ, ಜಾಗತಿಕ active-owner ಮತ್ತು active-connection ಏಕತೆಯನ್ನು ಜಾರಿಗೊಳಿಸುತ್ತದೆ, ಮತ್ತು ಪ್ರೊವೈಡರ್ dispatch ಗೆ ಮೊದಲು stale generation ಅನ್ನು ತಿರಸ್ಕರಿಸುತ್ತದೆ. ಈ ವೈಶಿಷ್ಟ್ಯವು ಪ್ರತಿ API key ಗೆ opt-in ಆಗಿದೆ. managed key `lease:exclusive` scope ಮತ್ತು ಸ್ಪಷ್ಟ ಖಾಲಿಯಲ್ಲದ `allowedConnections` ಪಟ್ಟಿಯನ್ನು ಹೊಂದಿರಬೇಕು. ಯಾವುದೇ HTTP ಕ್ಲೈಂಟ್ lifecycle endpoint ಅನ್ನು ಬಳಸಬಹುದು; ಯಾವುದೇ ಕ್ಲೈಂಟ್ ಹೆಸರು, user-agent, ಪ್ರೊವೈಡರ್, OAuth ವಿಧಾನ, ಅಥವಾ ಮಾದರಿ ಅಗತ್ಯವಿಲ್ಲ. ಲೀಸ್ ಸಂಪರ್ಕವನ್ನು ಹೊಂದಿದೆ, ಮಾದರಿಯನ್ನು ಅಲ್ಲ, ಆದ್ದರಿಂದ ಸಂಪರ್ಕವು ಸಾಮಾನ್ಯವಾಗಿ ಅರ್ಹವಾಗಿರುವವರೆಗೆ ಮಾದರಿ ಬದಲಾವಣೆಯು ಬಂಧನವನ್ನು ಉಳಿಸಿಕೊಳ್ಳುತ್ತದೆ. ಸಾಮಾನ್ಯ ಮಾದರಿ, ಕೋಟಾ, ಆರೋಗ್ಯ, ಕೂಲ್ಡೌನ್, ಮತ್ತು allowlist ನಿಯಮಗಳು ಅಧಿಕಾರದಲ್ಲಿರುತ್ತವೆ ಮತ್ತು ಅದೇ generation ಅನ್ನು ಬೇರೆ ಮುಕ್ತ ಅರ್ಹ ಸಂಪರ್ಕಕ್ಕೆ ಸ್ಥಳಾಂತರಿಸಬಹುದು. ಜೀವನಚಕ್ರವು `POST /api/v1/session-leases` ಆಗಿದ್ದು, `acquire`, `renew`, ಮತ್ತು `release` ಎಂಬ JSON ಕ್ರಿಯೆಗಳನ್ನು ಒಳಗೊಂಡಿರುತ್ತದೆ. ನಿರ್ವಹಿತ ಇನ್ಫರೆನ್ಸ್ ವಿನಂತಿಗಳು ಅಸ್ಪಷ್ಟವಾದ `X-OmniRoute-Lease-Owner` ಮೌಲ್ಯವನ್ನು ಮತ್ತು ನಿಖರವಾದ `X-OmniRoute-Lease-Generation` ಅನ್ನು ಸಲ್ಲಿಸುತ್ತವೆ. ಮಾಲೀಕತ್ವವು `vlo_` ನ ನಂತರ 43 base64url ಅಕ್ಷರಗಳನ್ನು ಬಳಸುತ್ತದೆ; ಅದರ SHA-256 ಹ್ಯಾಶ್ ಅನ್ನು ಮಾತ್ರ ಸಂಗ್ರಹಿಸಲಾಗುತ್ತದೆ. ಪ್ರತಿಯೊಂದು ಅಂತಿಮ ಡಿಸ್ಪ್ಯಾಚ್ ಫೆನ್ಸ್ ಸಹ ದೃಢೀಕೃತ API ಕೀ ID ಮತ್ತು ಸಕ್ರಿಯ ಸಂಪರ್ಕ ID ಅನ್ನು ಬಂಧಿಸುತ್ತದೆ. ಲೀಸ್ ನಿಯಂತ್ರಣ ಹೆಡರ್ಗಳನ್ನು ಲಾಗ್ಗಳಿಂದ, ಉಳಿಸಿಕೊಂಡ ವಿನಂತಿ ಸ್ನ್ಯಾಪ್ಶಾಟ್ಗಳಿಂದ, ಮತ್ತು ಅಪ್ಸ್ಟ್ರೀಮ್ ಎಕ್ಸಿಕ್ಯೂಟರ್ ಹೆಡರ್ಗಳಿಂದ ತೆಗೆದುಹಾಕಲಾಗುತ್ತದೆ. ಸಾಮಾನ್ಯ ರೂಟಿಂಗ್ ಅರ್ಹ ನಿರ್ವಹಿತ ಅಭ್ಯರ್ಥಿಗಳನ್ನು ಹೊಂದಿದ್ದರೂ, ಪ್ರತಿಯೊಂದು ಉಚಿತ ಅಭ್ಯರ್ಥಿಯು ಬಾಹ್ಯ ಸಕ್ರಿಯ ಲೀಸ್ನಿಂದ ಆಕ್ರಮಿತವಾಗಿದ್ದರೆ, OmniRoute HTTP `429`, ಲೀಸ್-ಸಾಮರ್ಥ್ಯ-ಲಭ್ಯವಿಲ್ಲದ ಕೋಡ್, ಸಾಮರ್ಥ್ಯಕ್ಕಾಗಿ-ಕಾಯುತ್ತಿರುವ ಸ್ಥಿತಿ, ಮತ್ತು ಸಂಬಂಧಿತ ಅತ್ಯಂತ ಬೇಗನೆಯ ಮುಗಿಯುವ ಅವಧಿಯಿಂದ ಪಡೆದ ಸೀಮಿತ `Retry-After` ಅನ್ನು ಹಿಂದಿರುಗಿಸುತ್ತದೆ. ಸಾಮಾನ್ಯ ಖಾಲಿ ಅರ್ಹತೆಯು ಲೀಸ್ ಸಂಘರ್ಷವಲ್ಲ ಮತ್ತು ಅದರ ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ ರೂಟಿಂಗ್ ದೋಷ ಸಿಮ್ಯಾಂಟಿಕ್ಸ್ ಅನ್ನು ಹಾಗೆಯೇ ಇರಿಸಿಕೊಳ್ಳುತ್ತದೆ. ಸಂಬಂಧಿತ ಕಾರ್ಯವಿಧಾನಗಳು ಪ್ರತ್ಯೇಕವಾಗಿರುತ್ತವೆ: - OAuth ಸೆಷನ್ ಆಕ್ಯುಪೆನ್ಸಿಯು OAuth ಖಾತೆಗಳಿಗಾಗಿ ಪ್ರಕ್ರಿಯೆ-ಸ್ಥಳೀಯ ಮೃದು ವಿತರಣೆಯಾಗಿದೆ. - ಖಾತೆ ಸೆಮಾಫೋರ್ಗಳು ವಿನಂತಿ-ಸಮಾಂತರತೆಯ ಪರವಾನಗಿಗಳನ್ನು ನೀಡುತ್ತವೆ ಮತ್ತು ವಿನಂತಿ ಪೂರ್ಣಗೊಂಡಾಗ ಕೊನೆಗೊಳ್ಳುತ್ತವೆ. - ಎಕ್ಸ್ಕ್ಲೂಸಿವ್ ನಿರ್ವಹಿತ ಸೆಷನ್ ಲೀಸ್ಗಳು ಜನರೇಷನ್ ಫೆನ್ಸ್ನೊಂದಿಗೆ ಬಾಳಿಕೆ ಬರುವ ಜೀವನಚಕ್ರ ಮಾಲೀಕತ್ವವಾಗಿವೆ. --- ## 3. ಮಾದರಿ ಲಾಕ್ಔಟ್ **ವ್ಯಾಪ್ತಿ:** ಪ್ರೊವೈಡರ್ + ಕನೆಕ್ಷನ್ + ಮಾದರಿ ತ್ರಯ. **ಸ್ಥಿತಿ ಆಧಾರಿತ ಕೀಲಿ ವ್ಯಾಪ್ತಿ:** ವಿಫಲವಾದ ಸ್ಥಿತಿಯು ಲಾಕ್ಔಟ್ ಯಾವ ಕೀಲಿಗೆ ಬರೆಯುತ್ತದೆ ಎಂಬುದನ್ನು ನಿರ್ಧರಿಸುತ್ತದೆ (`open-sse/services/accountFallback/exactModelLock.ts` ನಲ್ಲಿರುವ `resolveLockoutScope()`): - `429` / `403` / `402` — ಕೋಟಾ ಅಥವಾ ಎಂಟೈಟಲ್ಮೆಂಟ್ ಸಂಕೇತ — **ಕೋಟಾ ಕುಟುಂಬ**ವನ್ನು ಲಾಕ್ ಮಾಡಿ: codex ಗಾಗಿ ಇಡೀ `codex` / `spark` ವ್ಯಾಪ್ತಿ (ಕನೆಕ್ಷನ್ನ ಪ್ರತಿಯೊಂದು `gpt-5*` ಮಾದರಿ), ಇತರ ಪ್ರೊವೈಡರ್ಗಳಿಗೆ `getQuotaScopedModelForProvider()`. - `404` ಕೇವಲ ಮಾದರಿಯನ್ನು ಮಾತ್ರ ಲಾಕ್ ಮಾಡುತ್ತದೆ (`getModelLockKey()` `not_found` ಅನ್ನು ಕಿರಿದಾಗಿಸುತ್ತದೆ). - ಬೇರೆ ಯಾವುದೇ ಸ್ಥಿತಿ — `5xx` ಸಾರಿಗೆ/ಸರ್ವರ್ ವೈಫಲ್ಯಗಳು ಮತ್ತು ಗುಣಮಟ್ಟ ಮೌಲ್ಯೀಕರಣದಿಂದ OmniRoute ಸ್ವತಃ ಸಂಶ್ಲೇಷಿಸಿದ `502` — ಕೇವಲ **ನಿಖರ** ಪ್ರೊವೈಡರ್/ಕನೆಕ್ಷನ್/ಮಾದರಿ ಟಪಲ್ ಅನ್ನು ಮಾತ್ರ ಲಾಕ್ ಮಾಡುತ್ತದೆ. ಒಂದು ಮಾದರಿಯ ಕೆಟ್ಟ ಸ್ಟ್ರೀಮ್ ಅಕೌಂಟ್ನ ಕೋಟಾ ಬಗ್ಗೆ ಪುರಾವೆಯಾಗುವುದಿಲ್ಲ; ಈ ನಿಯಮಕ್ಕೆ ಮೊದಲು `codex/gpt-5.6-luna` ನಲ್ಲಿ ಒಂದು ಖಾಲಿ ಪ್ರತಿಕ್ರಿಯೆಯು ಆ ಕನೆಕ್ಷನ್ನ ಎಲ್ಲಾ `gpt-5*` ಮಾದರಿಗಳನ್ನು 2–30 ನಿಮಿಷಗಳವರೆಗೆ (ಹಂತಹಂತವಾಗಿ ಹೆಚ್ಚುತ್ತಾ) ರೂಟಿಂಗ್ನಿಂದ ತೆಗೆದುಹಾಕುತ್ತಿತ್ತು, ಅದರ ಕೋಟಾ ಮುಟ್ಟದೆಯೇ ಇದ್ದರೂ. - ಕರೆಗಾರನ ಸ್ಪಷ್ಟ `scope` ಆಯ್ಕೆ ಯಾವಾಗಲೂ ಜಯಿಸುತ್ತದೆ (Antigravity `"exact"` ಅನ್ನು ರವಾನಿಸುತ್ತದೆ). **ಉದ್ದೇಶ:** ಒಂದೇ ಮಾದರಿ ಲಭ್ಯವಿಲ್ಲದಿರುವಾಗ ಅಥವಾ ಕೋಟಾ-ಸೀಮಿತವಾಗಿರುವಾಗ ಇಡೀ ಕನೆಕ್ಷನ್ ಅನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸುವುದನ್ನು ತಪ್ಪಿಸುವುದು. **ಉದಾಹರಣೆಗಳು:** - 429 ಹಿಂದಿರುಗಿಸುವ ಮಾದರಿ-ವಾರು ಕೋಟಾ ಪ್ರೊವೈಡರ್ಗಳು - ಒಂದು ಕಾಣೆಯಾದ ಮಾದರಿಗೆ 404 ಹಿಂದಿರುಗಿಸುವ ಸ್ಥಳೀಯ ಪ್ರೊವೈಡರ್ಗಳು - ಪ್ರೊವೈಡರ್-ನಿರ್ದಿಷ್ಟ ಮೋಡ್/ಮಾದರಿ ಅನುಮತಿ ವೈಫಲ್ಯಗಳು (ಉದಾ., Grok ಮೋಡ್ಗಳು) **ಅನುಷ್ಠಾನ:** `open-sse/services/accountFallback.ts` — `lockModel()`, `clearModelLock()`, `getAllModelLockouts()`. ### ಮಾದರಿ ಕೂಲ್ಡೌನ್ ಡ್ಯಾಶ್ಬೋರ್ಡ್ (v3.8.0) UI: ಸೆಟ್ಟಿಂಗ್ಗಳು → ಮಾದರಿ ಕೂಲ್ಡೌನ್ಗಳು (`src/app/(dashboard)/dashboard/settings/components/ModelCooldownsCard.tsx`) ಸಕ್ರಿಯ ಲಾಕ್ಔಟ್ಗಳನ್ನು ಇವುಗಳೊಂದಿಗೆ ಪಟ್ಟಿ ಮಾಡುತ್ತದೆ: ಪ್ರೊವೈಡರ್, ಕನೆಕ್ಷನ್, ಮಾದರಿ, ಕಾರಣ, expiresAt. ಆಪರೇಟರ್ಗಳು ಕಾರ್ಡ್ನಿಂದ ಮಾದರಿಯನ್ನು ಹಸ್ತಚಾಲಿತವಾಗಿ ಮರು-ಸಕ್ರಿಯಗೊಳಿಸಬಹುದು. **REST API:** - `GET /api/resilience/model-cooldowns` — ಸಕ್ರಿಯ ಲಾಕ್ಔಟ್ಗಳನ್ನು ಪಟ್ಟಿ ಮಾಡಿ - `DELETE /api/resilience/model-cooldowns` — ಹಸ್ತಚಾಲಿತ ಮರು-ಸಕ್ರಿಯಗೊಳಿಸುವಿಕೆ. ಬಾಡಿ: `{provider, connection, model}`. ದೃಢೀಕರಣ: management. ### ಕೂಲ್ಡೌನ್ ಮ್ಯಾನೇಜರ್ UI: ಮಾನಿಟರಿಂಗ್ → ಕೂಲ್ಡೌನ್ ಮ್ಯಾನೇಜರ್ (`src/app/(dashboard)/dashboard/resilience/cooldowns/`). ಪ್ರತಿ ಪ್ರೊವೈಡರ್ ಪುಟವನ್ನು ತೆರೆಯುವ ಬದಲು, ತಾತ್ಕಾಲಿಕ ಕಾರಣದಿಂದ ರೂಟಿಂಗ್ನಿಂದ ಹೊರಗಿರುವ ಪ್ರತಿಯೊಂದು ಕನೆಕ್ಷನ್ಗಾಗಿ ಒಂದೇ ಪುಟ. ಇದು ಕನೆಕ್ಷನ್ ಕೂಲ್ಡೌನ್ಗಳು, ಮಾದರಿ ಲಾಕ್ಔಟ್ಗಳು ಮತ್ತು ಟರ್ಮಿನಲ್ ಸ್ಥಿತಿಗಳನ್ನು ಪಟ್ಟಿ ಮಾಡುತ್ತದೆ, ಅವುಗಳನ್ನು ಪ್ರತಿ ಕನೆಕ್ಷನ್ಗೆ, ಆಯ್ದ ಒಂದು ಗುಂಪಿಗೆ, ಅಥವಾ ಪ್ರೊವೈಡರ್ನ ಎಲ್ಲಾ ಕನೆಕ್ಷನ್ಗಳಿಗೆ ತೆರವುಗೊಳಿಸುತ್ತದೆ, ಮತ್ತು ಅತ್ಯಂತ ಹೆಚ್ಚು ಟ್ಯೂನ್ ಮಾಡಲಾದ ಕೂಲ್ಡೌನ್ ನಿಯಮಗಳನ್ನು ಸಂಪಾದಿಸುತ್ತದೆ: `streamStallCooldown.enabled` ಮತ್ತು OAuth / API-ಕೀ `connectionCooldown` ಮೂಲ ಕೂಲ್ಡೌನ್ ಹಾಗೂ ಗರಿಷ್ಠ ಬ್ಯಾಕ್ಆಫ್ ಹಂತಗಳು (`PATCH /api/resilience` ಮೂಲಕ ಉಳಿಸಲಾಗುತ್ತದೆ). ಟರ್ಮಿನಲ್ ಸ್ಥಿತಿಗಳನ್ನು (`banned`, `expired`, `credits_exhausted`) ಪಟ್ಟಿ ಮಾಡಲಾಗುತ್ತದೆ ಆದರೆ ಇಲ್ಲಿ ಎಂದಿಗೂ ತೆರವುಗೊಳಿಸಲಾಗುವುದಿಲ್ಲ. **REST API** (`src/lib/resilience/cooldownManager.ts`, ದೃಢೀಕರಣ: management): - `GET /api/resilience/cooldowns[?provider=]` — ಸ್ಥಿತಿ, ಉಳಿದ ಕೂಲ್ಡೌನ್, ಬ್ಯಾಕ್ಆಫ್ ಮಟ್ಟ, ಕೊನೆಯ ದೋಷ ಪ್ರಕಾರ ಮತ್ತು ಮಾದರಿ ಲಾಕ್ಔಟ್ಗಳೊಂದಿಗೆ ಕನೆಕ್ಷನ್ಗಳು (ರುಜುವಾತುಗಳಿಲ್ಲ) - `POST /api/resilience/cooldowns` — ಬಾಡಿ `{connectionIds: string[]}` ಅಥವಾ `{all: true, provider?}`; `{cleared, unchanged, skippedTerminal, lockoutsCleared}` ಅನ್ನು ಹಿಂದಿರುಗಿಸುತ್ತದೆ ### ಲಾಕ್ಔಟ್ ಸೆಟ್ಟಿಂಗ್ಗಳ UI + ಯಶಸ್ಸು-ಕ್ಷಯ ಚೇತರಿಕೆ (v3.8.23) ಮಾದರಿ ಲಾಕ್ಔಟ್ ಯಾವಾಗಲೂ-ಆನ್ ಆಗಿರುವ ಹಾರ್ಡ್ಕೋಡ್ ಮಾಡಿದ ನಡವಳಿಕೆಯಿಂದ, ತನ್ನ ಸ್ವಂತ ಸೆಟ್ಟಿಂಗ್ಗಳ ಕಾರ್ಡ್ ಮತ್ತು ಸ್ವಯಂ-ಗುಣಮುಖ ಚೇತರಿಕೆ ಮಾರ್ಗದೊಂದಿಗೆ, ಸಂಪೂರ್ಣವಾಗಿ ಕಾನ್ಫಿಗರ್ ಮಾಡಬಹುದಾದ ಆಪ್ಟ್-ಇನ್ ವೈಶಿಷ್ಟ್ಯಕ್ಕೆ ಬದಲಾಗಿದೆ. **ಸೆಟ್ಟಿಂಗ್ಗಳ ಕಾರ್ಡ್:** ಸೆಟ್ಟಿಂಗ್ಗಳು → ಮಾದರಿ ಲಾಕ್ಔಟ್ (`src/app/(dashboard)/dashboard/settings/components/ModelLockoutCard.tsx`). ಇದು ಮೇಲಿನ ಓದಲು-ಮಾತ್ರದ `ModelCooldownsCard` ನಿಂದ **ಭಿನ್ನವಾಗಿದೆ** (ಅದು ಕೇವಲ ಸಕ್ರಿಯ ಲಾಕ್ಔಟ್ಗಳನ್ನು _ಪಟ್ಟಿ_ ಮಾಡುತ್ತದೆ) — ಹೊಸ ಕಾರ್ಡ್ _ನಿಯತಾಂಕಗಳನ್ನು ಕಾನ್ಫಿಗರ್ ಮಾಡುತ್ತದೆ_. ಡೀಫಾಲ್ಟ್ಗಳು `DEFAULT_MODEL_LOCKOUT_SETTINGS` ನಲ್ಲಿ ಇವೆ (`src/lib/resilience/modelLockoutSettings.ts`): | ಸೆಟ್ಟಿಂಗ್ | ಡೀಫಾಲ್ಟ್ | ಅರ್ಥ | | ----------------------- | -------------------------------- | ------------------------------------------------------------------ | | `enabled` | `false` | ಮಾಸ್ಟರ್ ಟಾಗಲ್ — ಮಾದರಿ ಲಾಕ್ಔಟ್ **ಡೀಫಾಲ್ಟ್ ಆಗಿ ಆಫ್ ಆಗಿದೆ**. | | `errorCodes` | `[403, 404, 429, 502, 503, 504]` | ಮಾದರಿ-ವ್ಯಾಪ್ತಿಯ ವೈಫಲ್ಯವಾಗಿ ಪರಿಗಣಿಸಲಾಗುವ ಅಪ್ಸ್ಟ್ರೀಮ್ ಸ್ಥಿತಿಗಳು. | | `baseCooldownMs` | `120_000` (120 ಸೆ) | ಮೊದಲ ವೈಫಲ್ಯಕ್ಕೆ ಆರಂಭಿಕ ಲಾಕ್ಔಟ್ ಅವಧಿ. | | `maxCooldownMs` | `1_800_000` (30 ನಿಮಿಷ) | ಹೆಚ್ಚಿಸಿದ ಕೂಲ್ಡೌನ್ನ ಮೇಲಿನ ಮಿತಿ. | | `maxBackoffSteps` | `10` | ಗರಿಷ್ಠ ಘಾತಾಂಕೀಯ-ಬ್ಯಾಕ್ಆಫ್ ಹೆಚ್ಚಳದ ಹಂತಗಳು. | | `useExponentialBackoff` | `true` | ಪುನರಾವರ್ತಿತ ವೈಫಲ್ಯಗಳು ಕೂಲ್ಡೌನ್ ಅನ್ನು ಘಾತಾಂಕೀಯವಾಗಿ ಹೆಚ್ಚಿಸುತ್ತವೆಯೇ. | ಸೆಟ್ಟಿಂಗ್ಗಳು ಸಾಮಾನ್ಯ ಸೆಟ್ಟಿಂಗ್ಗಳ ಸ್ಟೋರ್ ಮೂಲಕ ಶೇಖರಿಸಲ್ಪಡುತ್ತವೆ ಮತ್ತು ರೆಸಿಲಿಯೆನ್ಸ್ ಸೆಟ್ಟಿಂಗ್ಗಳ ಸ್ಕೀಮಾ ಮೂಲಕ ಮಾನ್ಯಗೊಳಿಸಲ್ಪಡುತ್ತವೆ; ಕಾರ್ಡ್ `baseCooldownMs`/`maxCooldownMs` (`maxCooldownMs ≥ baseCooldownMs` ಆಗುವಂತೆ) ಮತ್ತು `maxBackoffSteps` ಅನ್ನು ಕ್ಲಾಂಪ್ ಮಾಡುತ್ತದೆ. **ಯಶಸ್ಸು-ಕ್ಷಯ ಚೇತರಿಕೆ:** ಚೇತರಿಕೆಯು **ಕೇವಲ** ಟೈಮರ್ ಮುಗಿಯುವಿಕೆಯಲ್ಲ. ಆರೋಗ್ಯಕರ ಪ್ರತಿಕ್ರಿಯೆಯು ಮಾದರಿಯ ವೈಫಲ್ಯ ಸಂಖ್ಯೆಯನ್ನು ಮತ್ತೆ ಕೆಳಗಿಳಿಸುತ್ತದೆ, ಆದ್ದರಿಂದ ಮಧ್ಯ-ವಿಂಡೋದಲ್ಲಿ ಚೇತರಿಸಿಕೊಂಡ ಮಾದರಿಯು ಅದರ ಟೈಮರ್ ಮುಗಿಯುವ ಮೊದಲೇ ಹೆಚ್ಚಳವನ್ನು ನಿಲ್ಲಿಸುತ್ತದೆ (ಮತ್ತು ತೆರವಾಗುತ್ತದೆ). ಯಶಸ್ವಿ ಕಾಂಬೊ ಗುರಿಯ ಮೇಲೆ, `open-sse/services/combo.ts` `decayModelFailureCount()` ಅನ್ನು ಕರೆಯುತ್ತದೆ (`open-sse/services/accountFallback.ts`), ಇದು ಸಂಗ್ರಹಿಸಲಾದ `failureCount` ಅನ್ನು **ಅರ್ಧ** ಮಾಡುತ್ತದೆ (`Math.floor(failureCount / 2)`); ಅದು `0` ಅನ್ನು ತಲುಪಿದಾಗ ಲಾಕ್ಔಟ್ ಎಂಟ್ರಿಯನ್ನು ಸಂಪೂರ್ಣವಾಗಿ ಅಳಿಸಲಾಗುತ್ತದೆ. ಅದರ ಪ್ರತಿರೂಪ `recordModelLockoutFailure()` ಹೆಚ್ಚಳದ ವಿಂಡೋವೊಳಗಿನ ವೈಫಲ್ಯಗಳಲ್ಲಿ ಸಂಖ್ಯೆಯನ್ನು ಹೆಚ್ಚಿಸುತ್ತದೆ (ಮತ್ತು ಕೂಲ್ಡೌನ್ ಅನ್ನು ಹೆಚ್ಚಿಸುತ್ತದೆ). ಈ ಯಶಸ್ಸು-ಕ್ಷಯವು ಸರಳ ಟೈಮರ್ ಮುಗಿಯುವಿಕೆಗೆ ಹೆಚ್ಚುವರಿಯಾಗಿದೆ — ಎರಡು ಮಾರ್ಗಗಳಲ್ಲಿ ಯಾವುದಾದರೂ ಮಾದರಿಯನ್ನು ಮರು-ಸಕ್ರಿಯಗೊಳಿಸಬಹುದು. **ಸ್ಥಿತಿ:** ಲಾಕ್ಔಟ್ಗಳನ್ನು **ಇನ್-ಮೆಮೊರಿ**ಯಲ್ಲಿ ಹಿಡಿಸಲಾಗುತ್ತದೆ (`provider:connectionId:model` ಕೀಲಿಯಿಂದ ಪ್ರತಿ-ಪ್ರಕ್ರಿಯೆಯ `Map` ಗಳಲ್ಲಿ `ModelLockoutEntry` ಆಗಿ, ನಿಖರ-ವ್ಯಾಪ್ತಿಯ ಲಾಕ್ಗಳು `provider:connectionId:exact:model` ಕೀಲಿಯಿಂದ), DB ಗೆ ಶೇಖರಿಸಲಾಗುವುದಿಲ್ಲ — ಅವು ಮರುಪ್ರಾರಂಭದಲ್ಲಿ ಕಳೆದುಹೋಗುತ್ತವೆ. _ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು_ ಶೇಖರಿಸಲಾಗುತ್ತದೆ; ಸಕ್ರಿಯ ಲಾಕ್ಔಟ್ _ಸ್ಥಿತಿ_ ಕ್ಷಣಿಕವಾಗಿದೆ. --- ## 4. ಕೋಟಾ-ಶೇರ್ ಸಮವರ್ತಿ ನಿಯಂತ್ರಣ (v3.8.36) ಚಂದಾದಾರಿಕೆ ಖಾತೆಗಳು (GLM, MiniMax ಇತ್ಯಾದಿ) ಸಾಮಾನ್ಯವಾಗಿ ಕೇವಲ ~1–3 ಸಮವರ್ತಿ ವಿನಂತಿಗಳನ್ನು ಮಾತ್ರ ಸ್ವೀಕರಿಸುತ್ತವೆ; ಅದನ್ನು ಮೀರಿದರೆ 429 ಗಳು ಮತ್ತು ಕೂಲ್ಡೌನ್ಗಳು ಉಂಟಾಗುತ್ತವೆ. ಇದು **ಕೋಟಾ-ಶೇರ್** (`qtSd/…`) ಕಾಂಬೋಗಳಲ್ಲಿ ವಿಶೇಷವಾಗಿ ತೀವ್ರವಾಗಿದೆ, ಇಲ್ಲಿ ಹಲವಾರು API ಕೀಗಳು ಒಂದೇ ಅಪ್ಸ್ಟ್ರೀಮ್ ಖಾತೆಯನ್ನು ಹಂಚಿಕೊಳ್ಳುತ್ತವೆ. ಹಂಚಿಕೊಂಡ ಖಾತೆಯು ಪ್ರವಾಹಕ್ಕೆ ಒಳಗಾಗದಂತೆ ಮೂರು ಪದರಗಳು ತಡೆಯುತ್ತವೆ. ### ಪ್ರತಿ-ಸಂಪರ್ಕ ಸಮವರ್ತಿ ಮಿತಿ (`max_concurrent`) ಪ್ರತಿ ಪ್ರೊವೈಡರ್ ಸಂಪರ್ಕವು `max_concurrent` ಮಿತಿಯನ್ನು ಘೋಷಿಸಬಹುದು (`provider_connections.max_concurrent`, ಸಂಪರ್ಕ ಮೋಡಲ್ / API / DB ಯಲ್ಲಿ ಹೊಂದಿಸಬಹುದು). ಯಾವುದೇ ಮಿತಿ ಬೇಡವಿದ್ದರೆ ಅದನ್ನು ಖಾಲಿ ಬಿಡಿ. ಇದು ಕೆಳಗಿನ ಸರಣೀಕರಣ ಪದರವನ್ನು ಚಲಾಯಿಸುವ ಏಕೈಕ ನಾಬ್ ಆಗಿದೆ — ಅದನ್ನು ಖಾತೆಯ ನಿಜವಾದ ಸಮವರ್ತಿತೆಗೆ ಹೊಂದಿಸಿ (ಉದಾ. GLM ~1, MiniMax ~2). ### ಪ್ರತಿ-ಮಾದರಿ ಸಮವರ್ತಿ ಮಿತಿಗಳು (`modelConcurrency`) ಒಂದು ಸಂಪರ್ಕವು ಹೆಚ್ಚುವರಿಯಾಗಿ ತನ್ನ `rateLimitOverrides` ಮ್ಯಾಪ್ನಲ್ಲಿ ನಿಖರವಾದ ಪ್ರತಿ-ಮಾದರಿ ಸಮವರ್ತಿ ಮಿತಿಗಳನ್ನು ಘೋಷಿಸಬಹುದು: ```json { "rateLimitOverrides": { "maxConcurrent": 4, "modelConcurrency": { "glm-5": 1, "glm-4.7": 3 } } } ``` ಇದನ್ನು ಸಂಪರ್ಕ ಮೋಡಲ್ನಲ್ಲಿ ಹೊಂದಿಸಿ (**ದರ ಮಿತಿ ಅತಿಕ್ರಮಣಗಳು → ಪ್ರತಿ-ಮಾದರಿ ಸಮವರ್ತಿ ಮಿತಿಗಳು**, ಪ್ರತಿ ಸಾಲಿಗೆ ಒಂದು `model=cap`) ಅಥವಾ ಅದೇ JSON ಆಕಾರದೊಂದಿಗೆ `PATCH /api/providers/[id]` ಮೂಲಕ. ಮುಖ್ಯ ನಿಯಮಗಳು: - **ಸಂಪರ್ಕ-ವ್ಯಾಪಿ vs ಮಾದರಿ-ನಿರ್ದಿಷ್ಟ:** `maxConcurrent` ಹಂಚಿಕೊಂಡ ಸಂಪರ್ಕ-ವ್ಯಾಪಿ ಮಿತಿಯಾಗಿ ಉಳಿಯುತ್ತದೆ. ಎರಡೂ ಅನ್ವಯಿಸಿದಾಗ, ಎರಡೂ ಗೇಟ್ಗಳನ್ನು ಒಂದೇ ಸಂಯುಕ್ತ ಗೇಟ್ನಲ್ಲಿ ಅವಿಭಾಜ್ಯವಾಗಿ ಪಡೆಯಲಾಗುತ್ತದೆ (`global → provider → account → model`); ಪರಿಣಾಮಕಾರಿ ನಡವಳಿಕೆಯು ಹೆಚ್ಚು ಕಟ್ಟುನಿಟ್ಟಾದ ಅನ್ವಯವಾಗುವ ಮಿತಿಯಾಗಿರುತ್ತದೆ. - **ನಿಖರ ಮಾದರಿ-ಕೀ ಹೊಂದಾಣಿಕೆ:** ಕೀ ಎಂಬುದು ರೌಟಿಂಗ್ ನಿರ್ಣಯದ ನಂತರ ಎಕ್ಸಿಕ್ಯೂಟರ್ಗೆ ರವಾನಿಸಲಾದ ಮಾದರಿ ಸ್ಟ್ರಿಂಗ್ ಆಗಿದೆ — ಸಾಮಾನ್ಯವಾಗಿ ಬರೇ ಅಪ್ಸ್ಟ್ರೀಮ್ ಮಾದರಿ id (`glm-5`), ಕ್ಲಯಂಟ್-ಸೈಡ್ `provider/model` ಅಲಿಯಾಸ್ ಅಲ್ಲ (`zai/glm-5` ಎಂಬುದು `glm-5` ಗೆ ಹೊಂದಿಕೆಯಾಗುವುದಿಲ್ಲ). ಮೌಲ್ಯಗಳು ಧನಾತ್ಮಕ ಪೂರ್ಣಾಂಕ ಸಮವರ್ತಿ-ವಿನಂತಿ ಮಿತಿಗಳು. - **ಸ್ಥಳೀಯ ಕ್ಯೂಯಿಂಗ್, ಡಿಸ್ಕವರಿ ಇಲ್ಲ:** ಹೆಚ್ಚುವರಿ ವಿನಂತಿಗಳು ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ ಕ್ಯೂ/ಟೈಮ್ಔಟ್ ಅರ್ಥನೀತಿಯೊಂದಿಗೆ ಸ್ಥಳೀಯವಾಗಿ ಕ್ಯೂ ಆಗುತ್ತವೆ (ಟೈಪ್ ಮಾಡಲಾದ `SEMAPHORE_TIMEOUT` / `SEMAPHORE_QUEUE_FULL` ಪ್ರವೇಶ ದೋಷಗಳು). OmniRoute ಅಪ್ಸ್ಟ್ರೀಮ್ ನೀತಿಯನ್ನು ಕಂಡುಹಿಡಿಯುವುದಿಲ್ಲ ಅಥವಾ ಊಹಿಸುವುದಿಲ್ಲ — ಇದು ಆಪರೇಟರ್ ಕಾನ್ಫಿಗರ್ ಮಾಡಿದ ನಿಖರ ಮಿತಿಗಳನ್ನು ಜಾರಿಗೊಳಿಸುತ್ತದೆ. ತುಂಬಿಹೋಗಿದ ಮಾದರಿ ಗೇಟ್ ಪ್ರೊವೈಡರ್ ಅನ್ನು ಎಂದಿಗೂ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸುವುದಿಲ್ಲ ಮತ್ತು ಶಾಶ್ವತ ಮಾದರಿ ಲಾಕ್ಔಟ್ ಅನ್ನು ಎಂದಿಗೂ ರಚಿಸುವುದಿಲ್ಲ; ಅಪ್ಸ್ಟ್ರೀಮ್ 429/ಕೂಲ್ಡೌನ್/ಫಾಲ್ಬ್ಯಾಕ್ ನಡವಳಿಕೆಯು ದೋಷ ಬ್ಯಾಕ್ಸ್ಟಾಪ್ ಆಗಿ ಉಳಿಯುತ್ತದೆ. - **ಪ್ರತಿ-ಸಂಪರ್ಕ, ಪ್ರತಿ-ಪ್ರಕ್ರಿಯೆ ವ್ಯಾಪ್ತಿ:** ಮಿತಿಗಳು ಪ್ರತಿ ಡೇಟಾಬೇಸ್ ಸಂಪರ್ಕಕ್ಕೆ ಸಂಬಂಧಿಸಿದವು ಮತ್ತು ಮೆಮೊರಿಯಲ್ಲಿ ಇರಿಸಲಾಗುತ್ತವೆ, ಆದ್ದರಿಂದ ಒಂದೇ ಅಪ್ಸ್ಟ್ರೀಮ್ API ಕೀಯನ್ನು ಮರುಬಳಸುವ ಎರಡು ಸಂಪರ್ಕಗಳು ಪರಸ್ಪರ ಸಂಯೋಜಿಸುವುದಿಲ್ಲ. - **ಕಾನ್ಫಿಗರ್ ಮಾಡದಿದ್ದರೆ ಬದಲಾವಣೆಯಿಲ್ಲ:** ಮ್ಯಾಪ್ ಅನ್ನು ಬಿಟ್ಟುಬಿಡುವುದು (ಅಥವಾ ಡ್ಯಾಶ್ಬೋರ್ಡ್ ಫೀಲ್ಡ್ ಅನ್ನು ಖಾಲಿ ಬಿಡುವುದು) ಯಾವುದೇ ಮಾದರಿ ಗೇಟ್ ಅನ್ನು ಸೇರಿಸುವುದಿಲ್ಲ. ಯಾವುದೇ ಸಾರ್ವತ್ರಿಕ ಪ್ರೊವೈಡರ್ ಮಿತಿಯನ್ನು ಘೋಷಿಸದ ಉದಾಹರಣೆ ಕಾನ್ಫಿಗರೇಶನ್: ```text glm-5=1 glm-4.7=3 ``` ### ಕೋಟಾ-ಶೇರ್ ವಿನಂತಿ ಸರಣೀಕರಣ ಕೋಟಾ-ಶೇರ್ ಡಿಸ್ಪ್ಯಾಚ್ ಧನಾತ್ಮಕ `max_concurrent` ಅನ್ನು ಘೋಷಿಸುವ ಸಂಪರ್ಕವನ್ನು ಗುರಿಯಾಗಿಸಿದಾಗ, ಆ **ಖಾತೆ**ಗೆ ಹೋಗುವ ಸಮವರ್ತಿ ವಿನಂತಿಗಳನ್ನು ಪ್ರತಿ-ಸಂಪರ್ಕ ಸೆಮಾಫೋರ್ ಮೂಲಕ (ಕೀ `qsconn:`) ಸರಣೀಕರಿಸಲಾಗುತ್ತದೆ: ಹೆಚ್ಚುವರಿ ವಿನಂತಿಗಳು ಖಾತೆಯನ್ನು ಪ್ರವಾಹದಿಂದ ತುಂಬಿಸುವ ಬದಲು **ಕ್ಯೂನಲ್ಲಿ ಕಾಯುತ್ತವೆ**. ಇದು **ಫೇಲ್-ಓಪನ್** — ತುಂಬಿದ ಕ್ಯೂ ಅಥವಾ ಟೈಮ್ಔಟ್ ಆದರೆ, ಡಿಸ್ಪ್ಯಾಚ್ ಮಾಡಬಹುದಾದ ವಿನಂತಿಯನ್ನು ಎಂದಿಗೂ ತಿರಸ್ಕರಿಸದೆ ಸ್ಲಾಟ್ ಇಲ್ಲದೆಯೇ ಮುಂದುವರೆಯುತ್ತದೆ. **ಸೆಟ್ಟಿಂಗ್ಗಳು → ಸ್ಥಿತಿಸ್ಥಾಪಕತೆ → ಕೋಟಾ-ಶೇರ್ ಪ್ರತಿ-ಸಂಪರ್ಕ ಸಮವರ್ತಿ** ಯಲ್ಲಿ ಟಾಗಲ್ ಮಾಡಿ (`resilienceSettings.quotaShareConcurrencyLimit.enabled`, ಪೂರ್ವನಿಯೋಜಿತ ಆನ್). `max_concurrent` ಮಿತಿ ಇಲ್ಲದಿದ್ದರೆ ನಡವಳಿಕೆಯು ಬದಲಾಗುವುದಿಲ್ಲ. > ಕೋಟಾ-ಶೇರ್ ರೌಟಿಂಗ್ ಗೇಟ್ (`selectQuotaShareTarget`, DRR + P2C) ಸ್ವತಃ > ಫೇಲ್-ಓಪನ್ ಆಗಿದೆ ಮತ್ತು ಮಿತಿ ತಲುಪಿದ ಸಂಪರ್ಕವನ್ನು ಕೇವಲ _ಆದ್ಯತೆ ಇಳಿಕೆ_ > ಮಾಡುತ್ತದೆ — ಏಕ-ಸಂಪರ್ಕ ಪೂಲ್ನೊಂದಿಗೆ ಅದು ಕಠಿಣ ಮಿತಿ ಹೇರಲು ಸಾಧ್ಯವಿಲ್ಲ, > ಆದ್ದರಿಂದ ಪ್ರವಾಹವನ್ನು ನಿಜವಾಗಿಯೂ ನಿಯಂತ್ರಿಸುವುದು ಈ ಸೆಮಾಫೋರ್. ### ಕಾಂಬೋ ಕೂಲ್ಡೌನ್-ಅರಿವುಳ್ಳ ಮರುಪ್ರಯತ್ನ ಪ್ರತಿ ಕಾಂಬೋ ತಂತ್ರಕ್ಕಾಗಿ (ಸಕ್ರಿಯಗೊಳಿಸಿದಾಗ), ಸ್ವಲ್ಪಕಾಲದ ಕ್ಷಣಿಕ ಕೂಲ್ಡೌನ್ಗಾಗಿ 429 ಅನ್ನು ಸ್ಥಿರಗೊಳಿಸುವ ವಿನಂತಿಯು, 429 ಅನ್ನು ಹಿಂದಿರುಗಿಸುವ ಬದಲು ಅದು ಮುಗಿಯುವವರೆಗೆ ಕಾಯುತ್ತದೆ ಮತ್ತು ಮರು-ಡಿಸ್ಪ್ಯಾಚ್ ಮಾಡುತ್ತದೆ — ಇದು ಬಹು-ಮಾದರಿ ಕಾಂಬೋಗಳಲ್ಲಿ Gemini-ವರ್ಗದ TPM/RPM ವಿಂಡೋಗಳನ್ನು (~60s retry-after) ಒಳಗೊಂಡಿದೆ, ಉದಾ. 2-ಮಾದರಿ ಕಾಂಬೋದ ಎರಡೂ ಗುರಿಗಳು ಪ್ರತಿ-ಮಾದರಿ ದರ ಮಿತಿಯನ್ನು ತಲುಪಿದಾಗ. **ಸೆಟ್ಟಿಂಗ್ಗಳು → ಸ್ಥಿತಿಸ್ಥಾಪಕತೆ** ಯಲ್ಲಿರುವ `comboCooldownWait` (`enabled`, `maxWaitMs`, `maxAttempts`, `budgetMs`) ಮೂಲಕ ಮಿತಿಗೊಳಿಸಲಾಗಿದೆ. ಇದು `quota_exhausted` (ಮಧ್ಯರಾತ್ರಿಯವರೆಗೆ ಲಾಕ್ ಆಗಿದೆ) ಅಥವಾ auth/not-found ಕಾರಣಗಳಿಗಾಗಿ ಎಂದಿಗೂ ಕಾಯುವುದಿಲ್ಲ. ಅದೇ ಗೇಟ್ ಪ್ರಿ-ಡಿಸ್ಪ್ಯಾಚ್ ಸಂದರ್ಭವನ್ನು (#16319) ಒಳಗೊಂಡಿದೆ: ಕಾಂಬೋದ ಪ್ರತಿ ಗುರಿಯೂ, ಅದರ ಮಾದರಿ ಸ್ವಲ್ಪಕಾಲದ ಕ್ಷಣಿಕ ಲಾಕ್ಔಟ್ನಲ್ಲಿ ಇರುವ ಕಾರಣದಿಂದ ಯಾವುದೇ ಪ್ರಯತ್ನ ಮಾಡುವ ಮೊದಲೇ ಬಿಟ್ಟುಬಿಡಲಾದಾಗ, ಶೂನ್ಯ-ಪ್ರಯತ್ನ ಮಾರ್ಗವು ಸುಳಿವುರಹಿತ `503 ALL_TARGETS_SKIPPED` ಎಂದು ಉತ್ತರಿಸುವ ಬದಲು ಅದೇ ಮಿತಿಗಳಡಿಯಲ್ಲಿ ಲಾಕ್ ಮುಗಿಯುವವರೆಗೆ ಕಾಯುತ್ತದೆ ಮತ್ತು ಮರು-ಡಿಸ್ಪ್ಯಾಚ್ ಮಾಡುತ್ತದೆ. ಯಾವುದೇ ಕಾಯುವಿಕೆಗೆ ಅನುಮತಿ ಇಲ್ಲದಿದ್ದಾಗ (ಮಿತಿ, ಪ್ರಯತ್ನ ಅಥವಾ ಬಜೆಟ್ ಮುಗಿದಿದ್ದಾಗ, ಅಥವಾ ಫೀಚರ್ ಆಫ್ ಆಗಿದ್ದಾಗ), ಅಂತಿಮ ಪ್ರತಿಕ್ರಿಯೆಯು `429 rate_limit_error` ಗೆ ಅಪ್ಗ್ರೇಡ್ ಆಗುತ್ತದೆ ಮತ್ತು ಅತ್ಯಂತ ಬೇಗ ಮುಗಿಯುವ ಕ್ಷಣಿಕ ಲಾಕ್ ಮುಕ್ತಾಯದಿಂದ `retry_after` / `reset_at` ಅನ್ನು ಹೊತ್ತುಕೊಂಡು ಹೋಗುತ್ತದೆ; ಕೋಟಾ, auth ಮತ್ತು not-found ಲಾಕ್ಗಳು ಸುಳಿವುರಹಿತ 503 ಅನ್ನು ಹಾಗೆಯೇ ಇರಿಸಿಕೊಳ್ಳುತ್ತವೆ. ```text #16319 · comboCooldownWait · pre-dispatch (attempts = 0) all targets skipped + transient model lockout: enabled ∧ 0 < waitMs ≤ maxWaitMs ∧ attempt < maxAttempts ∧ budgetLeftMs ≥ waitMs → wait → re-dispatch wait = false → HTTP 429 rate_limit_error retry_after / reset_at ← earliest transient lock expiry quota_exhausted / auth_error / not_found / not_found_local: no transient hint → HTTP 503 ALL_TARGETS_SKIPPED ``` --- ## 5. ರಿಕ್ವೆಸ್ಟ್ ಕ್ಯೂ ಅಡ್ಮಿಷನ್ ಕಂಟ್ರೋಲ್ (v3.8.49 · issue #6593) **ವ್ಯಾಪ್ತಿ**: ಪ್ರತಿ-ಪ್ರೊವೈಡರ್+ಕನೆಕ್ಷನ್ ಸ್ಥಳೀಯ ರೇಟ್-ಲಿಮಿಟ್ ಕ್ಯೂ (`open-sse/services/rateLimitManager.ts`, Bottleneck ಮೂಲಕ ಬೆಂಬಲಿತ), ಮೇಲಿನ ಮೂರು ಕ್ರಮಗಳಿಗಿಂತ ಒಂದು ಪದರ ಕೆಳಗಿನದ್ದು. **`maxWaitMs` ಕ್ಯೂ ಕಾಯುವಿಕೆಯನ್ನು ಮಿತಿಗೊಳಿಸುತ್ತದೆ; `executionMaxWaitMs` ಎಕ್ಸಿಕ್ಯೂಶನ್ ಅನ್ನು ಮಿತಿಗೊಳಿಸುತ್ತದೆ.** ಈ ಎರಡನ್ನು ಉದ್ದೇಶಪೂರ್ವಕವಾಗಿ ಪ್ರತ್ಯೇಕಿಸಲಾಗಿದೆ, ಮತ್ತು ಯಾವುದೂ ಇನ್ನೊಂದಕ್ಕೆ ಪೂರೈಕೆ ನೀಡುವುದಿಲ್ಲ. `resilienceSettings.requestQueue.maxWaitMs` ಎಂದರೆ **ಕ್ಯೂ-ಕಾಯುವಿಕೆ ಬಜೆಟ್**: ಇದು ಪ್ರೊವೈಡರ್ ಸ್ಲಾಟ್ಗಾಗಿ ಕಾಯುವುದನ್ನು ಮತ್ತು ನಂತರ QUEUED ಸ್ಥಿತಿಯಲ್ಲಿ ಕುಳಿತಿರುವುದನ್ನು ಒಳಗೊಂಡಿರುತ್ತದೆ, ಮತ್ತು ಜಾಬ್ QUEUED ಸ್ಥಿತಿಯನ್ನು ಬಿಟ್ಟು ಎಕ್ಸಿಕ್ಯೂಟ್ ಆಗಲಾರಂಭಿಸಿದ ಕ್ಷಣವೇ ಅದರ ಟೈಮರ್ ತೆರವುಗೊಳ್ಳುತ್ತದೆ (`rateLimitManager.ts`, `wrappedFn`). ಇದನ್ನು ಮೀರಿದ ರಿಕ್ವೆಸ್ಟ್ ಎಂದಿಗೂ ಅಪ್ಸ್ಟ್ರೀಮ್ ತಲುಪುವುದಿಲ್ಲ. ಡೀಫಾಲ್ಟ್ 30000ms, ಇದನ್ನು `src/lib/resilience/settings.ts` ನಲ್ಲಿ `DEFAULT_REQUEST_QUEUE_MAX_WAIT_MS` ಪೂರೈಸುತ್ತದೆ ಮತ್ತು `tests/unit/ratelimit-admission-control-6593.test.ts` ಪಿನ್ ಮಾಡುತ್ತದೆ — ಆದ್ದರಿಂದ ಇದನ್ನು ಬದಲಾಯಿಸಿದರೆ ಆ ಟೆಸ್ಟ್ ಕೆಂಪಾಗುತ್ತದೆ, ಈ ಪ್ಯಾರಾಗ್ರಾಫ್ ಮೌನವಾಗಿ ಹಳೆಯದಾಗಿ ಉಳಿಯುವುದಿಲ್ಲ. `resilienceSettings.requestQueue.executionMaxWaitMs` ಅನ್ನು Bottleneck ಜಾಬ್ `expiration` ಆಗಿ ಸ್ವೀಕರಿಸುತ್ತದೆ, ಇದರ ಟೈಮರ್ ಡಿಸ್ಪ್ಯಾಚ್ ನಂತರ ಮಾತ್ರ ಪ್ರಾರಂಭವಾಗುತ್ತದೆ. ತಮ್ಮದೇ ಆದ ಅಪ್ಸ್ಟ್ರೀಮ್ ಟೈಮ್ಔಟ್ ಇಲ್ಲದ ಎಕ್ಸಿಕ್ಯೂಟರ್ಗಳಿಗೆ ಇದು ಬ್ಯಾಕ್ಸ್ಟಾಪ್ ಆಗಿದೆ, ಮತ್ತು ಎಕ್ಸಿಕ್ಯೂಟರ್ನ ಸ್ವಂತ fetch-start ಟೈಮ್ಔಟ್ ಇದಕ್ಕಿಂತ ಉದ್ದವಾಗಿದ್ದಾಗ ಅದರ ಮಟ್ಟಕ್ಕೆ ಏರಿಸಲಾಗುತ್ತದೆ, ಆದ್ದರಿಂದ ಇದು ಆರೋಗ್ಯಕರ ಇನ್-ಫ್ಲೈಟ್ ರೆಸ್ಪಾನ್ಸ್ ಅನ್ನು ಕತ್ತರಿಸುವುದಿಲ್ಲ. ಡೀಫಾಲ್ಟ್ 600000ms (10 ನಿಮಿಷ). ಕ್ಯೂ ಬಜೆಟ್ ಅನ್ನು `expiration` ಗೆ ಪೂರೈಸುವುದೇ ಹಿಂದೆ ನಾನ್-ಇಂಕ್ರಿಮೆಂಟಲ್ ಗೇಟ್ವೇಗಳನ್ನು ಮಿಡ್-ಫ್ಲೈಟ್ನಲ್ಲಿ ಕೊಲ್ಲುತ್ತಿದ್ದದ್ದು — ಅವು ಮೊದಲ ಬೈಟ್ಗಳಿಗೆ ಮೊದಲು ನಿಮಿಷಗಳ ಕಾಲ ಕಾನೂನುಬದ್ಧವಾಗಿ ರನ್ ಆಗುತ್ತವೆ — ಮತ್ತು ಅದಕ್ಕಾಗಿಯೇ expiration ಅನ್ನು `code: "RATE_LIMIT_EXECUTION_TIMEOUT"` (HTTP 504) ಆಗಿ ಮೇಲ್ಮೈಗೆ ತರಲಾಗುತ್ತದೆ, ಆದರೆ ಕ್ಯೂ ಬಜೆಟ್ ಕ್ಯೂ-ಟೈಮ್ಔಟ್ ಕೋಡ್ ಅನ್ನು ಹೊಂದಿರುತ್ತದೆ. ಎರಡನ್ನೂ `RATE_LIMIT_MAX_WAIT_MS` / `RATE_LIMIT_EXECUTION_MAX_WAIT_MS` (env) ಅಥವಾ ಡ್ಯಾಶ್ಬೋರ್ಡ್ (**Settings → Resilience**) ಮೂಲಕ ಓವರ್ರೈಡ್ ಮಾಡಬಹುದು. ಎರಡನ್ನೂ ನಾರ್ಮಲೈಜ್ ಮಾಡಿದಾಗ 1ms–24h ಗೆ ಕ್ಲಾಂಪ್ ಮಾಡಲಾಗುತ್ತದೆ. **ಎರಡಕ್ಕೂ ಆದ್ಯತೆ:** env var ಕೇವಲ _ಡೀಫಾಲ್ಟ್_ ಅನ್ನು ಪೂರೈಸುತ್ತದೆ. `resilienceSettings.requestQueue` ನಲ್ಲಿ ಪರ್ಸಿಸ್ಟ್ ಮಾಡಲಾದ ಮೌಲ್ಯ (ಡ್ಯಾಶ್ಬೋರ್ಡ್ / API patch, `key_value` ನಲ್ಲಿ ಸಂಗ್ರಹ) ಅದನ್ನು ಗೆಲ್ಲುತ್ತದೆ, ಮತ್ತು ಪ್ರತಿ-ಕನೆಕ್ಷನ್ `rateLimitOverrides.maxWaitMs` / `.executionMaxWaitMs` ಅದನ್ನೂ ಗೆಲ್ಲುತ್ತದೆ. ಆದ್ದರಿಂದ ಈಗಾಗಲೇ ಪರ್ಸಿಸ್ಟ್ ಮಾಡಲಾದ ಮೌಲ್ಯವಿರುವ ಡಿಪ್ಲಾಯ್ಮೆಂಟ್ನಲ್ಲಿ env var ಹೊಂದಿಸಿದರೆ ಏನೂ ಬದಲಾಗುವುದಿಲ್ಲ — ಬದಲಿಗೆ ಪರ್ಸಿಸ್ಟ್ ಮಾಡಲಾದ ಸೆಟ್ಟಿಂಗ್ ಅನ್ನು ತೆರವುಗೊಳಿಸಿ ಅಥವಾ ಅಪ್ಡೇಟ್ ಮಾಡಿ. ಕ್ಯೂ ನಿವಾಸ ಅವಧಿಯನ್ನು `maxWaitMs` ಮಿತಿಗೊಳಿಸುತ್ತದೆ; ಕೆಳಗಿನ `maxQueueDepth` ಒಮ್ಮೆ ಎಷ್ಟು ಕಾಲರ್ಗಳು ಕ್ಯೂನಲ್ಲಿರಬಹುದು ಎಂಬುದನ್ನು ಮಿತಿಗೊಳಿಸುತ್ತದೆ. **ಬಾಡಿ-ಸೂಚಿತ ರಿಟ್ರೈಗಳು: ಪೇಸಿಂಗ್ vs ಲಾಕ್ಔಟ್.** 429 ಬಾಡಿ ತನ್ನದೇ ಕಾಯುವಿಕೆಯನ್ನು ಹೆಸರಿಸಬಹುದು (Gemini `RetryInfo.retryDelay`, "retry after Ns" ಪಠ್ಯ), ಇದನ್ನು `updateFromResponseBody` ಓದುತ್ತದೆ. ಕನೆಕ್ಷನ್ನ `maxWaitMs` ಗೆ ಹೊಂದುವ ಕಾಯುವಿಕೆ ಪೇಸಿಂಗ್ ಆಗಿದೆ: ಲಿಮಿಟರ್ ಆ ಅವಧಿಗೆ ತನ್ನ ರಿಸರ್ವಾಯರ್ ಅನ್ನು ಖಾಲಿ ಮಾಡುತ್ತದೆ ಮತ್ತು ಅದು ಮತ್ತೆ ತುಂಬಿದಾಗ ಕ್ಯೂನಲ್ಲಿರುವ ಕಾಲ್ಗಳು ಡಿಸ್ಪ್ಯಾಚ್ ಆಗುತ್ತವೆ. `maxWaitMs` ಗಿಂತ ಉದ್ದವಾದ ಕಾಯುವಿಕೆಯನ್ನು ಕ್ಯೂ ಕುಳಿತು ಕಾಯಲು ಸಾಧ್ಯವಿಲ್ಲ — Gemini ಖಾಲಿಯಾದ ದೈನಂದಿನ ಕೋಟಾಕ್ಕೆ `retryDelay: "86399s"` ನೊಂದಿಗೆ ಉತ್ತರಿಸುತ್ತದೆ. ಮರುನಿರ್ಮಿತ 429 ರ ಮೇಲಿನ ರಿಲೇ ಆಗಿರುವ `Retry-After` (#16528) ಈಗಾಗಲೇ ಫಾಲ್ಬ್ಯಾಕ್ ಎಂಜಿನ್ ಆ ವಿಂಡೋಗೆ ಮಾಡೆಲ್ ಅನ್ನು ಲಾಕ್ ಮಾಡುವಂತೆ ಮಾಡುತ್ತದೆ, ಆದರೆ ಅದಕ್ಕಾಗಿ ಲಿಮಿಟರ್ ಅನ್ನೂ ಪಾಜ್ ಮಾಡುವುದು ಕೀಯನ್ನು ಮುಂಚಿತವಾಗಿ ತಲುಪುವ ಯಾವುದೇ ಕಾಲ್ ಅನ್ನು (ಉದಾಹರಣೆಗೆ ರೆಸಿಲಿಯನ್ಸ್ ರಿಸೆಟ್ ನಂತರ) ಇಡೀ `maxWaitMs` ಅವಧಿಗೆ ನಿಲ್ಲಿಸುತ್ತದೆ. ಅಂಥ ಕಾಯುವಿಕೆ ಟೈಪ್ಡ್ Google `RetryInfo` ವಿವರದಿಂದ (`google_rpc_retry_info` ಪ್ರೊವೆನೆನ್ಸ್) ಬಂದಾಗ ಮತ್ತು ಕೀಯ ಲಿಮಿಟರ್ ಈಗಾಗಲೇ ಮಾಡೆಲ್ಗೆ ಸ್ಕೋಪ್ ಆಗಿದ್ದಾಗ (`getLimiterKey` ನೋಡಿ), 429 ಬದಲಿಗೆ ಆ ಕನೆಕ್ಷನ್ನಲ್ಲಿ ಮಾಡೆಲ್ ಲಾಕ್ಔಟ್ ಆಗುತ್ತದೆ (`open-sse/services/rateLimitManager/bodyRetryPause.ts` ನಲ್ಲಿರುವ `lockModelForLongBodyRetry`, 24h ಗೆ ಕ್ಯಾಪ್), ಮತ್ತು ಲಿಮಿಟರ್ ಅನ್ನು ಪಾಜ್ ಮಾಡದೆ ಬಿಡಲಾಗುತ್ತದೆ. ಅಕೌಂಟ್ ಸಿಲೆಕ್ಷನ್ ಆ ಲಾಕ್ ಮೂಲಕ `isModelLocked()` ನಿಂದ ಸ್ಕಿಪ್ ಆಗುತ್ತದೆ, ಮತ್ತು ಕನೆಕ್ಷನ್ಗೆ ಪಿನ್ ಆದ ಟಾರ್ಗೆಟ್ಗಳಿಗಾಗಿ ಕಾಂಬೊ ಪ್ರಿ-ಡಿಸ್ಪ್ಯಾಚ್ ಗೇಟ್ ಕೂಡ ಹಾಗೆಯೇ ಸ್ಕಿಪ್ ಆಗುತ್ತದೆ. antigravity ನಲ್ಲಿ, ಅದರ ಲಿಮಿಟರ್ ಪ್ರತಿ ಕೋಟಾ ಕುಟುಂಬಕ್ಕೆ ಇರುವುದರಿಂದ, ಲಾಕ್ ನಿಖರವಾದ ಮಾಡೆಲ್ ಮೇಲಿರುತ್ತದೆ — ಅದರ ಇತರ ಕೋಟಾ ಲಾಕ್ಗಳಂತೆಯೇ. ಅಲಿಯಾಸ್ ಅದನ್ನು ಆ ಮಾಡೆಲ್ಗೆ ರಿಸಾಲ್ವ್ ಮಾಡಿದಾಗ ಕ್ಲಯಂಟ್ ಕೇಳಿದ ಹೆಸರನ್ನೂ ಲಾಕ್ ಮಾಡಲಾಗುತ್ತದೆ, ಏಕೆಂದರೆ ಆ ಚೆಕ್ಗಳು ರಿಕ್ವೆಸ್ಟ್ ಮಾಡಲಾದ ಹೆಸರನ್ನು ಬಳಸುತ್ತವೆ; ಅದನ್ನು ನಿಖರವಾಗಿ ಲಾಕ್ ಮಾಡಲಾಗುತ್ತದೆ (`lockExactModel`), ಆದ್ದರಿಂದ antigravity ಕೋಟಾ ಕುಟುಂಬವನ್ನೋ ಅಥವಾ codex ಸ್ಕೋಪ್ ಅನ್ನೋ ದಾಟುವ ಅಲಿಯಾಸ್ ಎಂದಿಗೂ ತನ್ನದನ್ನೇ ಲಾಕ್ ಮಾಡುವುದಿಲ್ಲ. ಪ್ರೋಸ್ ಹಿಂಟ್, ಟೈಪ್ ಮಾಡದ `retryDelay`, ಅಥವಾ ಇಡೀ ಕನೆಕ್ಷನ್ನಿಂದ ಹಂಚಿಕೊಂಡ ಲಿಮಿಟರ್ ಪಾಜ್ ಅನ್ನು ಉಳಿಸುತ್ತದೆ. 429 ಪಾತ್ ಈಗಷ್ಟೇ ಮರುನಿರ್ಮಿಸಿದ ಲಿಮಿಟರ್ ಪಾಜ್ ಆದಾಗ, ಉಳಿದ ಕ್ಯೂ ಸಮಯವು ಪಾಜ್ ಮುಗಿಯುವ ಮೊದಲೇ ಮುಗಿಯುವ ಕಾಲರ್ ಅನ್ನು ಕೂಡಲೇ ಕ್ಯೂ-ಟೈಮ್ಔಟ್ ಕೋಡ್ನೊಂದಿಗೆ (`checkLimiterPause`) ತಿರಸ್ಕರಿಸಲಾಗುತ್ತದೆ — ಆ ಸಮಯವನ್ನು ಕಾಯುವ ಬದಲು; ದಾಖಲಾದ ಅಂತ್ಯವನ್ನು ಲಿಮಿಟರ್ ನಿರ್ಮಾಣಕ್ಕೆ ಮೊದಲು ಆಂಕರ್ ಮಾಡಲಾಗುತ್ತದೆ, ಅಲ್ಲಿ Bottleneck ತನ್ನ ರಿಫ್ರೆಶ್ ಕ್ಲಾಕ್ ಅನ್ನು ಪ್ರಾರಂಭಿಸುತ್ತದೆ, ಮತ್ತು ರಿಸರ್ವಾಯರ್ಗೆ ನಂತರದ ಯಾವುದೇ ಬದಲಾವಣೆ ಅದನ್ನು ಮರೆತುಬಿಡುತ್ತದೆ. `tests/unit/rate-limit-long-body-retry-lockout.test.ts` ಮತ್ತು `tests/unit/rate-limit-body-retry-pause.test.ts` ಮೂಲಕ ಕವರ್ ಆಗಿದೆ. **`maxQueueDepth` — ಆಪ್ಟ್-ಇನ್ ಅಡ್ಮಿಷನ್ ಕ್ಯಾಪ್ (ಹೊಸದು).** `resilienceSettings.requestQueue.maxQueueDepth` ಒಂದು ಪ್ರೊವೈಡರ್+ಕನೆಕ್ಷನ್ಗೆ ಒಮ್ಮೆ ಎಷ್ಟು ರಿಕ್ವೆಸ್ಟ್ಗಳು ಕ್ಯೂನಲ್ಲಿ ಕುಳಿತಿರಬಹುದು (ಇನ್ನೂ ಡಿಸ್ಪ್ಯಾಚ್ ಆಗಿಲ್ಲದಿರುವವು) ಎಂಬುದನ್ನು ಮಿತಿಗೊಳಿಸುತ್ತದೆ. ಕ್ಯೂ ಈಗಾಗಲೇ `maxQueueDepth` ರಿಕ್ವೆಸ್ಟ್ಗಳನ್ನು ಹೊಂದಿದ್ದಾಗ, ಹೊಸ ರಿಕ್ವೆಸ್ಟ್ `limiter.schedule()` ಅನ್ನು ತಲುಪುವ **ಮೊದಲೇ** ಟೈಪ್ಡ್ `code: "RATE_LIMIT_QUEUE_FULL"` ಎರರ್ನೊಂದಿಗೆ ಫಾಸ್ಟ್-ರಿಜೆಕ್ಟ್ ಆಗುತ್ತದೆ — ಆದ್ದರಿಂದ ತಿರಸ್ಕಾರವು ಅಗ್ಗದಾಗಿದ್ದು, ಆ ರಿಕ್ವೆಸ್ಟ್ಗಾಗಿ ಯಾವುದೇ ಡೌನ್ಸ್ಟ್ರೀಮ್ ಪ್ರಾಂಪ್ಟ್-ಕಂಪ್ರೆಶನ್ / ಟ್ರಾನ್ಸ್ಲೇಶನ್ ಕೆಲಸಕ್ಕಿಂತ ಮೊದಲು ನಡೆಯುತ್ತದೆ. ಡೀಫಾಲ್ಟ್ `0` = ಡಿಸೇಬಲ್ಡ್, ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ ಅನ್ಬೌಂಡಡ್-ಕ್ಯೂ ಬಿಹೇವಿಯರ್ ಅನ್ನು ಉಳಿಸುತ್ತದೆ; 0–100000 ಗೆ ಬೌಂಡ್ ಮಾಡಲಾಗಿದೆ. `RATE_LIMIT_MAX_QUEUE_DEPTH` (env) ಅಥವಾ `resilienceSettings.requestQueue.maxQueueDepth` (ಡ್ಯಾಶ್ಬೋರ್ಡ್/API patch) ಮೂಲಕ ಓವರ್ರೈಡ್ ಮಾಡಬಹುದು. ಅಡ್ಮಿಷನ್ ಚೆಕ್ ಸ್ವತಃ ಒಂದು ಪ್ಯೂರ್ ಫಂಕ್ಷನ್ ಆಗಿದೆ (`open-sse/services/rateLimitManager/admission.ts::checkQueueAdmission`), ಆದ್ದರಿಂದ ನಿಜವಾದ Bottleneck ಲಿಮಿಟರ್ ಇಲ್ಲದೆಯೂ ಅದನ್ನು ಯುನಿಟ್-ಟೆಸ್ಟ್ ಮಾಡಬಹುದು. > #6593 ಅನ್ನು ತೆರೆದ RFC, `bypassCompressionOnRateLimit` > ಫ್ಲ್ಯಾಗ್ ಅನ್ನೂ ಪ್ರಸ್ತಾಪಿಸಿತ್ತು. ಈ repo ಯ `open-sse/services/compression/` ಪೈಪ್ಲೈನ್ > ಹೊರಹೋಗುವ LLM ವಿನಂತಿಯ ಮೇಲಿನ ಪ್ರಾಂಪ್ಟ್/ಕಾಂಟೆಕ್ಸ್ಟ್ ಸಂಕುಚನವಾಗಿದೆ (`chatCore.ts`, > `resolveCompressionSettings`/`selectCompressionStrategy` ಬ್ಲಾಕ್ನ ಆಸುಪಾಸಿನಲ್ಲಿ), > ಸಂಶ್ಲೇಷಿತ 429 ಬಾಡಿಗಳ ಮೇಲಿನ HTTP ಪ್ರತಿಕ್ರಿಯೆ ಸಂಕುಚನವಲ್ಲ — ನೇರವಾದ bypass ಫ್ಲ್ಯಾಗ್ಗೆ > ಹೊಂದುವ ಯಾವುದೇ ಕೋಡ್ ಪಥವಿಲ್ಲ. ಆ ಪ್ರಾಂಪ್ಟ್-ಸಂಕುಚನ ಹಂತವು ಪ್ರಸ್ತುತ ವಿನಂತಿ ಪೈಪ್ಲೈನ್ನಲ್ಲಿ > `withRateLimit()` ಗಿಂತ _ಮೊದಲು_ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ, ಆದ್ದರಿಂದ ಕ್ಯೂ-ತುಂಬಿದೆ ಎಂಬ ನಿರಾಕರಣೆಯ > ಸಂದರ್ಭದಲ್ಲಿ ಅದನ್ನು ಬಿಟ್ಟುಬಿಡಲು ಕ್ರಮವನ್ನು ಬದಲಿಸುವುದು ಈ ಸಮಸ್ಯೆಯ ವ್ಯಾಪ್ತಿಗಿಂತ ಪ್ರತ್ಯೇಕವಾದ, > ದೊಡ್ಡ ಬದಲಾವಣೆಯಾಗಿದೆ; ಇದನ್ನು ಇಲ್ಲಿ ಉದ್ದೇಶಪೂರ್ವಕವಾಗಿ **ಅನುಷ್ಠಾನಗೊಳಿಸಲಾಗಿಲ್ಲ** ಮತ್ತು CPU > ಉಳಿತಾಯದ ಲಾಭವು ಕ್ರಮ ಬದಲಾವಣೆಯ ಅಪಾಯಕ್ಕೆ ತಕ್ಕದ್ದಾಗಿದ್ದರೆ, ಅದನ್ನು ಅನುಸರಣಾ ಕಾರ್ಯವಾಗಿ ಬಿಡಲಾಗಿದೆ. ### ದರ-ಮಿತಿ ಸ್ವಯಂ-ಸಕ್ರಿಯಗೊಳಿಸುವ ಸುರಕ್ಷತಾ ವ್ಯವಸ್ಥೆ ಮತ್ತು ಸಂಪರ್ಕ ರಕ್ಷಣೆ (`rateLimitProtection`) **ಸ್ವಯಂ-ಸಕ್ರಿಯಗೊಳಿಸುವ ಸುರಕ್ಷತಾ ವ್ಯವಸ್ಥೆ** (`resilienceSettings.requestQueue.autoEnableApiKeyProviders`, ಡೀಫಾಲ್ಟ್ `true`): ಡೀಫಾಲ್ಟ್ ಆಗಿ, OmniRoute ಎಲ್ಲಾ ಸಕ್ರಿಯ API-key ಪೂರೈಕೆದಾರರ ಸಂಪರ್ಕಗಳಿಗೆ (`getProviderCategory(provider) === "apikey"`) ದರ-ಮಿತಿ ಕ್ಯೂ ರಕ್ಷಣೆಯನ್ನು ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಸಕ್ರಿಯಗೊಳಿಸುತ್ತದೆ. ಇದು ದರಕ್ಕೆ ಸೂಕ್ಷ್ಮವಾಗಿರುವ ಅಪ್ಸ್ಟ್ರೀಮ್ API ಕೀಗಳಿಗೆ ಬರುವ ವಿನಂತಿಗಳು ಅಪ್ಸ್ಟ್ರೀಮ್ 429 ದೋಷಗಳಾಗಿ ಏಕಾಏಕಿ ಹೆಚ್ಚಾಗುವ ಬದಲು Bottleneck ಮೂಲಕ ಕ್ಯೂಗೆ ಸೇರಿಸಲ್ಪಟ್ಟು ನಿಯಂತ್ರಿಸಲ್ಪಡುವುದನ್ನು ಖಚಿತಪಡಿಸುತ್ತದೆ. `RATE_LIMIT_AUTO_ENABLE` ಪರಿಸರ ಚರದ ಮೂಲಕ ಈ ಸುರಕ್ಷತಾ ವ್ಯವಸ್ಥೆಯನ್ನು ಅತಿಕ್ರಮಿಸಬಹುದು (`false`/`0`/`off` ನಿಷ್ಕ್ರಿಯಗೊಳಿಸುತ್ತದೆ, `true`/`1`/`on` ಬಲವಂತವಾಗಿ ಸಕ್ರಿಯಗೊಳಿಸುತ್ತದೆ); ಇದು ಉಳಿಸಲಾದ ಡ್ಯಾಶ್ಬೋರ್ಡ್ ಸೆಟ್ಟಿಂಗ್ಗಿಂತ (**Settings → Resilience** / `PATCH /api/resilience`) ಆದ್ಯತೆ ಪಡೆಯುತ್ತದೆ. **ಪ್ರತಿ-ಸಂಪರ್ಕದ `rateLimitProtection` ನ ಅರ್ಥವ್ಯಾಪ್ತಿ:** ಪೂರೈಕೆದಾರರ ಸಂಪರ್ಕಗಳಲ್ಲಿನ `rateLimitProtection` ಬೂಲಿಯನ್ ಕ್ಷೇತ್ರದ ಮೂಲಕ ಪ್ರತಿ-ಸಂಪರ್ಕದ ದರ-ಮಿತಿ ರಕ್ಷಣೆಯನ್ನು ಟ್ರ್ಯಾಕ್ ಮಾಡಲಾಗುತ್ತದೆ (SQLite ನಲ್ಲಿ `rate_limit_protection` ಆಗಿ ಉಳಿಸಲಾಗುತ್ತದೆ): - **ಸ್ಪಷ್ಟವಾಗಿ ಆನ್ (`rateLimitProtection === true`)**: ಪೂರೈಕೆದಾರರ ವರ್ಗ ಅಥವಾ ಸ್ವಯಂ-ಸಕ್ರಿಯಗೊಳಿಸುವ ಸುರಕ್ಷತಾ ವ್ಯವಸ್ಥೆ ಆನ್ ಆಗಿದೆಯೇ ಎಂಬುದನ್ನು ಲೆಕ್ಕಿಸದೆ, ಈ ಸಂಪರ್ಕಕ್ಕೆ ದರ-ಮಿತಿ ರಕ್ಷಣೆಯನ್ನು ಸ್ಪಷ್ಟವಾಗಿ ಸಕ್ರಿಯಗೊಳಿಸಲಾಗುತ್ತದೆ. - **ಸ್ಪಷ್ಟವಾಗಿ ಆಫ್ (`rateLimitProtection === false`)**: ಸ್ಪಷ್ಟ ರಕ್ಷಣೆಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸುತ್ತದೆ, ಆದರೆ ಸಕ್ರಿಯ API-key ಸಂಪರ್ಕವನ್ನು ಜಾಗತಿಕ ಸ್ವಯಂ-ಸಕ್ರಿಯಗೊಳಿಸುವ ಸುರಕ್ಷತಾ ವ್ಯವಸ್ಥೆಯಿಂದ **ಹೊರಗಿಡುವುದಿಲ್ಲ**. `reconcileEnabledConnections` (`open-sse/services/rateLimitManager.ts`) ನಲ್ಲಿ `false` ಮತ್ತು `undefined` ಸಮಾನವಾಗಿವೆ: `rateLimitProtection === true` ಅನ್ನು ಮಾತ್ರ ಸ್ಪಷ್ಟ ಅತಿಕ್ರಮಣವೆಂದು ಪರಿಗಣಿಸಲಾಗುತ್ತದೆ. `rateLimitProtection` `false` ಆಗಿದ್ದರೆ (ಅಥವಾ ಹೊಂದಿಸದಿದ್ದರೆ), ಸಕ್ರಿಯ API-key ಸಂಪರ್ಕವು ಇನ್ನೂ ಸ್ವಯಂ-ಸಕ್ರಿಯಗೊಳಿಸುವ ಷರತ್ತಿಗೆ ಹೊಂದಿಕೆಯಾಗುತ್ತದೆ ಮತ್ತು ದರ-ಮಿತಿ ರಕ್ಷಣೆಯ ಅಡಿಯಲ್ಲೇ ಉಳಿಯುತ್ತದೆ. - **ಪ್ರತಿ-ಸಂಪರ್ಕದ ಹೊರಗುಳಿಯುವಿಕೆ ಇಲ್ಲ**: ಇತರ ಸಂಪರ್ಕಗಳಿಗೆ ಸ್ವಯಂ-ಸಕ್ರಿಯಗೊಳಿಸುವಿಕೆಯನ್ನು ಚಾಲ್ತಿಯಲ್ಲಿಟ್ಟುಕೊಂಡೇ, "ಈ ಒಂದು ಸಕ್ರಿಯ API-key ಸಂಪರ್ಕವು ದರ-ಮಿತಿ ಕ್ಯೂ ರಕ್ಷಣೆಯಿಲ್ಲದೆ ಕಾರ್ಯನಿರ್ವಹಿಸಬೇಕು" ಎಂದು ಆಪರೇಟರ್ ಪ್ರಸ್ತುತ ಸೂಚಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ. API-key ಸಂಪರ್ಕಗಳನ್ನು ದರ-ಮಿತಿ ಕ್ಯೂಗಳಿಲ್ಲದೆ ಸಂಪೂರ್ಣವಾಗಿ ಚಲಾಯಿಸಲು, ಸುರಕ್ಷತಾ ವ್ಯವಸ್ಥೆಯನ್ನು ಜಾಗತಿಕವಾಗಿ ಆಫ್ ಮಾಡಬೇಕು (`RATE_LIMIT_AUTO_ENABLE=false` ಅಥವಾ `resilienceSettings.requestQueue.autoEnableApiKeyProviders = false`). **ಬೆಂಬಲಿತ ಬರವಣಿಗೆ ಪಥಗಳು:** - **`POST /api/rate-limits`**: ಸಂಪರ್ಕಕ್ಕಾಗಿ `rateLimitProtection` ಅನ್ನು ಟಾಗಲ್ ಮಾಡಲು ಬೆಂಬಲಿತ ನಿರ್ವಹಣಾ ಬರವಣಿಗೆ ಪಥ (`{ connectionId: string, enabled: boolean }`). ಇದನ್ನು `enabled: true` ಜೊತೆಗೆ ಕರೆ ಮಾಡುವುದರಿಂದ ಸ್ಪಷ್ಟ ರಕ್ಷಣೆ ಆನ್ ಆಗುತ್ತದೆ; `enabled: false` ಜೊತೆಗೆ ಕರೆ ಮಾಡುವುದರಿಂದ ಸ್ಪಷ್ಟ ರಕ್ಷಣೆ ತೆಗೆದುಹಾಕಲ್ಪಡುತ್ತದೆ (ಆದರೂ ಸ್ವಯಂ-ಸಕ್ರಿಯಗೊಳಿಸುವಿಕೆ ಆನ್ ಆಗಿದ್ದರೆ, ಸಕ್ರಿಯ API-key ಸಂಪರ್ಕಗಳು ಜಾಗತಿಕ ಸುರಕ್ಷತಾ ವ್ಯವಸ್ಥೆಯ ಅಡಿಯಲ್ಲೇ ಉಳಿಯುತ್ತವೆ). - **`PUT /api/providers/[id]`**: ಉದ್ದೇಶಪೂರ್ವಕವಾಗಿ `rateLimitProtection` ಅನ್ನು ಸ್ವೀಕರಿಸುವುದಿಲ್ಲ ಅಥವಾ ಬದಲಿಸುವುದಿಲ್ಲ (#11278). `PUT /api/providers/[id]` ಮೂಲಕ ಪೂರೈಕೆದಾರರ ಸಂಪರ್ಕದ ಮೆಟಾಡೇಟಾವನ್ನು ನವೀಕರಿಸುವುದರಿಂದ ಉಳಿಸಲಾದ ದರ-ಮಿತಿ ರಕ್ಷಣೆಯ ಸ್ಥಿತಿ ಎಂದಿಗೂ ಬದಲಾಗುವುದಿಲ್ಲ. --- ## 6. ನಿಧಾನ-ಸ್ಟ್ರೀಮ್ ಥ್ರೂಪುಟ್ ವಾಚ್ಡಾಗ್ (#9709) ಐಚ್ಛಿಕ `resilienceSettings.streamRecovery.throughputWatchdog` ರಕ್ಷಣಾ ವ್ಯವಸ್ಥೆಯು, ಇನ್ನೂ ಚಂಕ್ಗಳನ್ನು ಕಳುಹಿಸುತ್ತಿದ್ದರೂ ಸಹ, ಕಾನ್ಫಿಗರ್ ಮಾಡಿದ ಉಪಯುಕ್ತ-ಔಟ್ಪುಟ್ ದರಕ್ಕಿಂತ ಕಡಿಮೆ ಅಸಿಸ್ಟೆಂಟ್ ಔಟ್ಪುಟ್ ಅನ್ನು ಉತ್ಪಾದಿಸುತ್ತಿರುವ ಅಪ್ಸ್ಟ್ರೀಮ್ ಅನ್ನು ಪತ್ತೆಹಚ್ಚುತ್ತದೆ. ಇದು ಉದ್ದೇಶಪೂರ್ವಕವಾಗಿ ಐಡಲ್ ಟೈಮ್ಔಟ್ನಿಂದ ಭಿನ್ನವಾಗಿದೆ: ಹಾರ್ಟ್ಬೀಟ್ಗಳು ಮತ್ತು ಮೆಟಾಡೇಟಾ ಯಾವುದೇ ಟೈಮರ್ ಅನ್ನು ಮರುಹೊಂದಿಸುವುದಿಲ್ಲ ಮತ್ತು ಪ್ರಗತಿಯಾಗಿ ಪರಿಗಣಿಸಲ್ಪಡುವುದಿಲ್ಲ. ಇದು ಹಾರ್ಡ್ ಅಟೆಂಪ್ಟ್ ಡೆಡ್ಲೈನ್ (#9153) ನಿಂದಲೂ ಭಿನ್ನವಾಗಿದೆ, ಅದು ಔಟ್ಪುಟ್ ಗುಣಮಟ್ಟವನ್ನು ಲೆಕ್ಕಿಸದೆ ಸಂಪೂರ್ಣ ಸುರಕ್ಷತಾ ಮಿತಿಯಾಗಿ ಉಳಿಯುತ್ತದೆ. ವಾಚ್ಡಾಗ್ ಅಬಾರ್ಟ್ ಮಾಡಲು ಸಾಧ್ಯವಾಗುವ ಮೊದಲು ವಾರ್ಮ್-ಅಪ್ ಅವಧಿಯನ್ನು ಮತ್ತು ಅದನ್ನು ಅನುಸರಿಸಿ ಸಂಪೂರ್ಣ ರೋಲಿಂಗ್ ವಿಂಡೋವನ್ನು ಅಗತ್ಯವಾಗಿ ಹೊಂದಿರುತ್ತದೆ. ಇದು Chat Completions ಮತ್ತು Responses API ಔಟ್ಪುಟ್ ಈವೆಂಟ್ಗಳಿಂದ ಟೆಕ್ಸ್ಟ್ ಡೆಲ್ಟಾಗಳನ್ನು ಎಣಿಸುತ್ತದೆ (ಸಂಪ್ರದಾಯವಾದಿ UTF-8 ಬೈಟ್ ಪ್ರಾಕ್ಸಿ), usage-only ಮತ್ತು ಖಾಲಿ ಈವೆಂಟ್ಗಳನ್ನು ನಿರ್ಲಕ್ಷಿಸುತ್ತದೆ, ಮತ್ತು ಟೂಲ್-ಕಾಲ್ ಅಥವಾ ರೀಸನಿಂಗ್ ಈವೆಂಟ್ಗಳು ಪ್ರಗತಿಯಲ್ಲಿರುವಾಗ ತೀರ್ಪನ್ನು ಮುಂದೂಡುತ್ತದೆ. ಇದು ಪೂರ್ವನಿಯೋಜಿತವಾಗಿ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲ್ಪಟ್ಟಿದೆ ಮತ್ತು `STREAM_THROUGHPUT_WATCHDOG_ENABLED=true` ಮೂಲಕ ಸಕ್ರಿಯಗೊಳಿಸಬಹುದು; ವಿಂಡೋ, ವಾರ್ಮ್-ಅಪ್, ಕನಿಷ್ಠ ದರ ಮತ್ತು ಕನಿಷ್ಠ ಅಳೆಯಬಹುದಾದ ಔಟ್ಪುಟ್ ಅನ್ನು ಸಾಮಾನ್ಯ resilience-settings ನಾರ್ಮಲೈಸೇಶನ್ ಲೇಯರ್ ಮೂಲಕ ಮಿತಿಗೊಳಿಸಲಾಗಿದೆ. ಸಕ್ರಿಯಗೊಳಿಸಿದಾಗ, ವಾಚ್ಡಾಗ್ ಅಬಾರ್ಟ್ ಅನ್ನು ಕೇವಲ ಸಕ್ರಿಯ ಅಪ್ಸ್ಟ್ರೀಮ್ ಅಟೆಂಪ್ಟ್ಗೆ ಮಾತ್ರ ಅನ್ವಯಿಸಲಾಗುತ್ತದೆ. ಯಾವುದೇ ಕ್ಲಯಂಟ್-ಗೋಚರ ಬೈಟ್ಗಳಿಗೆ ಮೊದಲು, ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ same-account early-recovery path ಅಟೆಂಪ್ಟ್ ಅನ್ನು ಮತ್ತೆ ತೆರೆಯಬಹುದು. ಕಮಿಟ್ ನಂತರ, ಸ್ಟ್ರೀಮ್ ಅನ್ನು ಎಂದಿಗೂ ಅಂಧವಾಗಿ ಮರುಪ್ಲೇ ಮಾಡಲಾಗುವುದಿಲ್ಲ; ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ ಸುರಕ್ಷಿತ mid-stream continuation contract ಮಾತ್ರ ಸಫಿಕ್ಸ್ ಅನ್ನು ಜೋಡಿಸಬಹುದು. ಫೈನಲೈಸೇಶನ್ single-shot ಆಗಿ ಉಳಿಯುತ್ತದೆ, ಆದ್ದರಿಂದ ಬಳಸಿಕೆ ಲೆಕ್ಕಪತ್ರ ಮತ್ತು semaphore ಬಿಡುಗಡೆ ನಕಲಾಗುವುದಿಲ್ಲ. --- ## 7. ಅಪ್ಸ್ಟ್ರೀಮ್ ಸ್ಥಿತಿ ಮರುಹೇಳಿಕೆ (ತಪ್ಪಾಗಿ ಹೇಳಲಾದ ಕೋಟಾ ದೋಷಗಳು) **ವ್ಯಾಪ್ತಿ:** ತಾತ್ಕಾಲಿಕ ಕೋಟಾ ಕೊರತೆಯನ್ನು ತಪ್ಪಾದ HTTP ಸ್ಥಿತಿಯೊಂದಿಗೆ ವರದಿ ಮಾಡುವ ಒಂದು ಅಪ್ಸ್ಟ್ರೀಮ್ ಗೇಟ್ವೇ. **ಉದ್ದೇಶ:** ವರ್ಗೀಕರಣಕ್ಕೆ ಮೊದಲು ದಾರಿತಪ್ಪಿಸುವ ಸ್ಥಿತಿಯನ್ನು ಸರಿಪಡಿಸುವುದು, ಇದರಿಂದ ಡೌನ್ಸ್ಟ್ರೀಮ್ ಬಳಸುವವರು (ಫಾಲ್ಬ್ಯಾಕ್ ಎಂಜಿನ್, ಕಾಂಬೊ ಸಂಗ್ರಹಣೆ, ಕ್ಲೈಂಟ್-ಎದುರಿನ ಪ್ರತಿಕ್ರಿಯೆ) ವೈಫಲ್ಯದ ನಿಜವಾದ ಮರುಪ್ರಯತ್ನ-ಯೋಗ್ಯ ಸ್ವಭಾವವನ್ನು ನೋಡುತ್ತಾರೆ. ಕೆಲವು ಗೇಟ್ವೇಗಳು ಮರುಪ್ರಯತ್ನ-ಯೋಗ್ಯವಲ್ಲದ HTTP ಸ್ಥಿತಿಯೊಂದಿಗೆ ತಾತ್ಕಾಲಿಕ ಕೋಟಾ ಕೊರತೆಯನ್ನು ಸೂಚಿಸುತ್ತವೆ. `agentrouter.org` ಪ್ರಮಾಣಿತ `429` ಬದಲಿಗೆ ಚೈನೀಸ್ ಬಾಡಿಯೊಂದಿಗೆ (`用户额度不足` / `额度不足`) `403` (ಕೆಲವೊಮ್ಮೆ `400`) ಹಿಂದಿರುಗಿಸುತ್ತದೆ. Claude Code ನಂತಹ ಕ್ಲೈಂಟ್ಗಳು `403` ಅನ್ನು ಶಾಶ್ವತವೆಂದು ಪರಿಗಣಿಸಿ ಸೆಷನ್ ಅನ್ನು ರದ್ದುಗೊಳಿಸುತ್ತವೆ, ಮತ್ತು ಸರಿಪಡಿಸದಿದ್ದರೆ ಫಾಲ್ಬ್ಯಾಕ್ ಎಂಜಿನ್ ಅದನ್ನು ಕೋಟಾ ಘಟನೆಯ ಬದಲಿಗೆ `AUTH_ERROR` ಎಂದು ವರ್ಗೀಕರಿಸುತ್ತದೆ. **ಅನುಷ್ಠಾನ:** - ರಿಜಿಸ್ಟ್ರಿ + ಹೊಂದಾಣಿಕೆಕಾರ: `open-sse/config/upstreamStatusRestatement.ts` — ಪ್ರತಿ-ಪ್ರೊವೈಡರ್ ನಿಯಮಗಳ ಪಟ್ಟಿ (`{id, fromStatuses, toStatus, textMarkers, excludeMarkers, defaultRetryAfterMs}`), `applyStatusRestatement()` ಮೂಲಕ ಹೊಂದಾಣಿಕೆಯಾಗುತ್ತದೆ. - ಕರೆ ಸ್ಥಳ: `open-sse/handlers/chatCore.ts` ನಲ್ಲಿನ `providerFailure:` ಬ್ಲಾಕ್ (ಸುಮಾರು ಸಾಲು 3654), `parseUpstreamError()` ದೋಷ HTTP ಸ್ಥಿತಿಯುಳ್ಳ ಅಪ್ಸ್ಟ್ರೀಮ್ ಪ್ರತಿಕ್ರಿಯೆಯನ್ನು (`!providerResponse.ok`) ಪಾರ್ಸ್ ಮಾಡಿದ ಒಡನೆ, ಮತ್ತು ಯಾವುದೇ ವರ್ಗೀಕರಣ ನಡೆಯುವ ಮೊದಲು, ಇದರಿಂದ ಪ್ರತಿ ಡೌನ್ಸ್ಟ್ರೀಮ್ ಬಳಸುವವರು ಸರಿಪಡಿಸಿದ ಸ್ಥಿತಿಯನ್ನು ನೋಡುತ್ತಾರೆ. `200` SSE ಸ್ಟ್ರೀಮ್ನ ಒಳಗೆ ಬಿಂಬಿತವಾದ ದೋಷಗಳು ಪ್ರತ್ಯೇಕ, ನಂತರದ ಸ್ಟ್ರೀಮ್-ಪಾರ್ಸಿಂಗ್ ಮಾರ್ಗವನ್ನು ಅನುಸರಿಸುತ್ತವೆ ಮತ್ತು ಇಂದು ಈ ಹುಕ್ನಿಂದ ಒಳಗೊಂಡಿಲ್ಲ — ತಿಳಿದಿರುವ ಮಿತಿ, agentrouter ನ ತಪ್ಪು-ಸ್ಥಿತಿಗೆ ಇನ್ನೂ ಅಗತ್ಯವಿಲ್ಲ (ಅದು ದೋಷ HTTP ಸ್ಥಿತಿಯಾಗಿ ಹೊರಬರುತ್ತದೆ). - ಮರುಪ್ರಯತ್ನ ಅರ್ಹತೆ: `429` `RETRY_AFTER_ELIGIBLE_STATUSES` ನಲ್ಲಿದೆ (`open-sse/services/combo/unavailableRetryGate.ts`), ಆದ್ದರಿಂದ ಮರುಹೇಳಿದ ದೋಷವು ಸತ್ತ `403` ಆಗಿ ಹೊರಬರದೇ ನಿಜವಾದ ಮರುಪ್ರಯತ್ನ ಕಿಟಕಿಯನ್ನು ಹೊಂದಿರುತ್ತದೆ. - ಸಿಂಥೆಟಿಕ್ `60s` `defaultRetryAfterMs` (`upstreamStatusRestatement.ts`) ಎನ್ನುವುದು ಮರುಹೇಳಿದ ಪ್ರತಿಕ್ರಿಯೆ **ಕ್ಲೈಂಟ್**ಗೆ ಹೇಳುವುದಷ್ಟೇ; ಅದು ಸ್ವತಃ ಸಂಪರ್ಕದ ಆಂತರಿಕ ಕೂಲ್ಡೌನ್/ಲಾಕ್ಔಟ್ ಅವಧಿಯಲ್ಲ — ಅದನ್ನು ಮರುಹೇಳಿದ ದೋಷವನ್ನು ನಿಜವಾಗಿ ನಿಭಾಯಿಸುವ ಯಾವ ಯಂತ್ರಾಂಶವೋ ಅದು ಪ್ರತ್ಯೇಕವಾಗಿ ನಿಯಂತ್ರಿಸುತ್ತದೆ (Connection Cooldown ನ ಏರುತ್ತಿರುವ ಬ್ಯಾಕ್ಆಫ್, §2, API-ಕೀ ಪ್ರೊವೈಡರ್ಗಳಿಗೆ ಬೇಸ್ `3s`; ಅಥವಾ Model Lockout, §3, agentrouter ನಂತಹ ಪ್ರತಿ-ಮಾದರಿ-ಕೋಟಾ ಪ್ರೊವೈಡರ್ಗಳಿಗೆ). ಕ್ಲೈಂಟ್ಗೆ ಅದು ಪ್ರಕಟಿಸುವ 60s ಕಿಟಕಿಗಿಂತ ಮೊದಲು ರೂಟರ್ ಆಂತರಿಕವಾಗಿ ಮರುಪ್ರಯತ್ನಿಸಲು ಅರ್ಹವಾಗಬಹುದು — ಉದ್ದೇಶಪೂರ್ವಕ ಹೆಡ್ರೂಮ್, ಬಗ್ ಅಲ್ಲ. ಶಾಶ್ವತ ದೋಷಗಳನ್ನು (agentrouter ನ `无权访问模型` — ಈ ಮಾದರಿಗೆ ಪ್ರವೇಶವಿಲ್ಲ) ಎಂದಿಗೂ ಮರುಹೇಳಲಾಗುವುದಿಲ್ಲ: `textMarkers` ಹೊಳೆದರೂ `excludeMarkers` ನಿಯಮವನ್ನು ವಿಟೋ ಮಾಡುತ್ತದೆ, ಆದ್ದರಿಂದ ದೋಷವು ತನ್ನ ಮೂಲ ಸ್ಥಿತಿಯನ್ನು ಇರಿಸಿಕೊಳ್ಳುತ್ತದೆ ಮತ್ತು ಏನೂ ಅದನ್ನು ಶಾಶ್ವತವಾಗಿ ಮರುಪ್ರಯತ್ನಿಸುವುದಿಲ್ಲ. ಹೊಂದಾಣಿಕೆಯಾದ ಪ್ರೊವೈಡರ್ ವರ್ಗೀಕರಣ ನಿಯಮವನ್ನು (`open-sse/config/providerErrorRules.ts` ನಲ್ಲಿನ `agentrouter-model-access-denied`: `reason: "auth_error"`, `scope: "model"`, `6h` ಘೋಷಿತ ಬೇಸ್ ಕೂಲ್ಡೌನ್) `checkFallbackError` (`open-sse/services/accountFallback.ts`) ಸಾಮಾನ್ಯ apikey-ವರ್ಗದ `FORBIDDEN` ಎರ್ಲಿ-ರಿಟರ್ನ್ಗೆ _ಮೊದಲು_ ಸಂಪರ್ಕಿಸುತ್ತದೆ, `honorsRuleLockScope(provider)` ಮೇಲೆ ಗೇಟ್ ಮಾಡಲಾಗಿದೆ (#10334 — ಪ್ರಸ್ತುತ `providerErrorRules.ts` ನಲ್ಲಿನ `HONORS_RULE_LOCK_SCOPE_PROVIDERS` ಅನುಮತಿ-ಪಟ್ಟಿಯ ಮೂಲಕ agentrouter-ಏಕಸ್ವಾಮ್ಯ). ನಿಯಮದ ಘೋಷಿತ 6h ಕೂಲ್ಡೌನ್ `fallbackResult.baseCooldownMs` ಆಗಿ ಹರಿದುಹೋಗುತ್ತದೆ, ಆದರೆ ಅದು ಇನ್ನೂ ಹಿಂದೆ-ಇದ್ದ ಪ್ರತಿ-ಮಾದರಿ-ಕೋಟಾ ಲಾಕ್ಔಟ್ ಮಾರ್ಗವನ್ನೇ ತುಂಬಿಸುತ್ತದೆ (`lockModelIfPerModelQuota()` / `recordModelLockoutFailure()`, ಕೂಲ್ಡೌನ್ ಮೂಲವನ್ನು ಹೊರತುಪಡಿಸಿ #10334 ರಿಂದ ಬದಲಾಗಿಲ್ಲ): ಇತರ ಎಲ್ಲಾ ಮಾದರಿ ಲಾಕ್ಔಟ್ಗಳಂತೆ ಅದು ಆಪರೇಟರ್ನ `mlSettings.maxCooldownMs` ಗೆ (ಡೀಫಾಲ್ಟ್ `1_800_000ms` / 30min) ಕುಗ್ಗಿಸಲ್ಪಡುತ್ತದೆ, ಮತ್ತು _ಕಾಯ್ದಿರಿಸಿದ ಲಾಕ್ಔಟ್ ಕಾರಣ_ ಹಿಂದೆ-ಇದ್ದ ಹಾರ್ಡ್ಕೋಡ್ ಮಾಡಿದ `"forbidden"` ಆಗಿಯೇ ಉಳಿಯುತ್ತದೆ, ನಿಯಮದ `"auth_error"` ಅಲ್ಲ — ಕೂಲ್ಡೌನ್ ಅವಧಿಯನ್ನು ಮಾತ್ರ ಎಂಡ್-ಟು-ಎಂಡ್ ಗೌರವಿಸಲಾಗುತ್ತದೆ, ಕಾರಣ ಸ್ಟ್ರಿಂಗ್ ಅಲ್ಲ. ಸಂಪರ್ಕವೇ ಸಕ್ರಿಯವಾಗಿ ಉಳಿಯುತ್ತದೆ; ಅದೇ ಸಂಪರ್ಕದ ಸಹೋದರ ಮಾದರಿಗಳಿಗೆ ಪರಿಣಾಮವಾಗುವುದಿಲ್ಲ. ಮರುಹೇಳಿದ ಕೋಟಾ ದೋಷಗಳು (`额度不足`) ಪ್ರೊಡಕ್ಷನ್ನಲ್ಲಿ ಪ್ರೊವೈಡರ್ ನಿಯಮವನ್ನು ತಲುಪುತ್ತವೆ (`agentrouter-user-quota-exhausted`: `reason: "quota_exhausted"`, `scope: "connection"`, ತನ್ನದೇ ಘೋಷಿತ ಕೂಲ್ಡೌನ್ ಇಲ್ಲ — ಪರ್ಸಿಸ್ಟೆನ್ಸ್ ಲೇಯರ್ನ ಸ್ಕೇಲ್ಡ್ ಬ್ಯಾಕ್ಆಫ್ ಡೀಫಾಲ್ಟ್ ಅನ್ವಯಿಸುತ್ತದೆ). #10334 ರಿಂದ, `ProviderErrorRuleMatch` ನ ಮೇಲಿನ `scope` ಎಂಡ್-ಟು-ಎಂಡ್ ಬಳಸಲ್ಪಡುತ್ತದೆ, ಆದರೆ `HONORS_RULE_LOCK_SCOPE_PROVIDERS` ಅನುಮತಿ-ಪಟ್ಟಿಯಲ್ಲಿರುವ ಪ್ರೊವೈಡರ್ಗಳಿಗೆ **ಮಾತ್ರ** (`providerErrorRules.ts` — ಇಂದು ಕೇವಲ `"agentrouter"`, `honorsRuleLockScope()` ಮೂಲಕ ಗೇಟ್ ಮಾಡಲಾಗಿದೆ). ಪ್ರತಿಯೊಂದು ಇತರ ಪ್ರೊವೈಡರ್ಗೆ `scope` ಮಾಹಿತಿ-ಮಾತ್ರವಾಗಿಯೇ ಉಳಿಯುತ್ತದೆ, #10334 ರ ಮೊದಲಿನಂತೆಯೇ. `checkFallbackError` ಹೊಂದಾಣಿಕೆಯಾದ ನಿಯಮದ scope ಅನ್ನು `fallbackResult.ruleScope` ಆಗಿ ಹೊರತರುತ್ತದೆ; `isAgentrouterConnectionQuotaScope()` (`src/sse/services/auth.ts`) ಒಂದು `ruleScope` ಅನ್ನು ಸಂಪರ್ಕ-ವ್ಯಾಪ್ತಿಯ, ಸ್ವಯಂ-ಚೇತರಿಸಿಕೊಳ್ಳುವ ಸಂಕೇತವಾಗಿ ಗೌರವಿಸಲು ನಿಜವಾಗಿಯೂ ಸುರಕ್ಷಿತವೆಂದು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳುವ ಹಂಚಿಕೆ ಗಾರ್ಡ್ ಆಗಿದೆ (scope `"connection"`, ಕಾರಣ `quota_exhausted`, ಎಂದಿಗೂ `permanent` ಅಲ್ಲ, ಎಂದಿಗೂ `creditsExhausted` ಅಲ್ಲ — scope `"connection"` ಅನ್ನು ಶಾಶ್ವತ ಖಾತೆ ಸ್ಥಿತಿಯೊಂದಿಗೆ ಜೋಡಿಸುವ ಭವಿಷ್ಯದ ನಿಯಮದ ವಿರುದ್ಧದ ರಕ್ಷಣೆ). ಎರಡು ಬಳಸುವವರು ಅದನ್ನು ಕರೆಯುತ್ತಾರೆ: - **ಸ್ಥಿರತೆ** (`markAccountUnavailable()`, `src/sse/services/auth.ts`): ಪಾಸ್ಥ್ರೂ-ಪ್ರೊವೈಡರ್ನ **ಪ್ರತಿ-ಮಾದರಿ** ಲಾಕ್ಔಟ್ ಶಾಖೆಗೆ ಹೋಗುವ ಬದಲು (agentrouter ಎಂಬುದು `passthroughModels: true` → `hasPerModelQuota()` `true` ಅನ್ನು ಹಿಂದಿರುಗಿಸುತ್ತದೆ), ಇದು **ತಾತ್ಕಾಲಿಕ ಸಂಪರ್ಕ ಕೂಲ್ಡೌನ್** ಅನ್ನು ಅನ್ವಯಿಸುತ್ತದೆ — `testStatus: "unavailable"` + `rateLimitedUntil`, ಎಂದಿಗೂ ಅಂತಿಮ ಸ್ಥಿತಿಯನ್ನು (`credits_exhausted`/`banned`/`expired`) ಅನ್ವಯಿಸುವುದಿಲ್ಲ — ಆದ್ದರಿಂದ ಕೂಲ್ಡೌನ್ ಅವಧಿ ಮುಗಿದ ಬಳಿಕ, ಕೈಯಾರೆ ಕ್ರೆಡೆನ್ಶಿಯಲ್ ಮರುಹೊಂದಿಸುವ ಅಗತ್ಯವಿಲ್ಲದೆ ಸಂಪರ್ಕವು ಸ್ವತಃ ಚೇತರಿಸಿಕೊಳ್ಳುತ್ತದೆ. `disableCooling: true` ಹೊಂದಿರುವ ಸಂಪರ್ಕಗಳಿಗೆ ಇದನ್ನು ಬಿಟ್ಟುಬಿಡಲಾಗುತ್ತದೆ (#2997): ಬದಲಿಗೆ ಆ ಆಯ್ಕೆಯಿಂದ ಹೊರಗುಳಿಯುವಿಕೆಯು ಪ್ರತಿ-ಮಾದರಿ ಲಾಕ್ಔಟ್ಗೆ ಹೋಗುತ್ತದೆ (ದಾಖಲೀಕರಿಸಲಾದ ರಾಜಿ — ಶಾಖೆಯ ಮೇಲಿರುವ ಕೋಡ್ ಕಾಮೆಂಟ್ ನೋಡಿ). - **ಅದೇ-ವಿನಂತಿಯ ಕಾಂಬೊ ರೂಟಿಂಗ್** (`applyComboTargetExhaustion()`, `open-sse/services/combo/targetExhaustion.ts`): ಅದೇ ಗಾರ್ಡ್ ಸಂಪರ್ಕವನ್ನು `${provider}:${connectionId}` ಕೀಲಿಯಿಂದ ಗುರುತಿಸಲಾದ, ಮೆಮೊರಿಯಲ್ಲಿರುವ `exhaustedConnections` ಸೆಟ್ನಲ್ಲಿ ಗುರುತಿಸುತ್ತದೆ. ಇದು ಉಳಿದಿರುವ ಅದೇ-ವಿನಂತಿಯ ಗುರಿಯನ್ನು, ಆ ಗುರಿಯ ಸ್ವಂತ ಆಬ್ಜೆಕ್ಟ್ನಲ್ಲಿ _ಅದೇ ನಿಖರವಾದ `connectionId` ಅನ್ನು ಈಗಾಗಲೇ ಹೊಂದಿದ್ದರೆ ಮಾತ್ರ_ ಬಿಟ್ಟುಬಿಡುತ್ತದೆ (`getExhaustedTargetSkipReason()`, `open-sse/services/combo/comboPredicates.ts`, `if (provider && connectionId)` ಎಂಬುದು `exhaustedConnections` ಲುಕ್ಅಪ್ಗಿಂತ ಮೊದಲು) — ಸಹೋದರ ಗುರಿಗಳು ತಮ್ಮದೇ ಪಿನ್ ಮಾಡಿದ `connectionId` ಅನ್ನು ಹೊಂದಿರದ ಮತ್ತು ಪ್ರತಿಯೊಂದು ಡಿಸ್ಪ್ಯಾಚ್ಗೆ ಒಂದನ್ನು ಪ್ರತಿಕ್ರಿಯೆಯ `X-OmniRoute-Selected-Connection-Id` ಹೆಡರ್ನಿಂದ ಮಾತ್ರ ಪರಿಹರಿಸುವ ಸರಳ ಮಾದರಿ-ಪಟ್ಟಿ ಕಾಂಬೊ ಎಂದಿಗೂ ಆ ಕೀ ಹೊಂದಾಣಿಕೆಯನ್ನು ತಲುಪುವುದಿಲ್ಲ. ಆ ಸಾಮಾನ್ಯ ಸಂದರ್ಭದಲ್ಲಿ, ಉಳಿದಿರುವ ಲೆಗ್ ಇದೀಗ ಖಾಲಿಯಾದ ಖಾತೆಯನ್ನು ಮರುಬಳಸದಂತೆ ಮಾಡುವ ನಿಜವಾದ ರಕ್ಷಣೆ ಈ ಸೆಟ್ ಅಲ್ಲ — ಅದು ಮೇಲಿನ ಸ್ಥಿರತೆ ಪದರ (ಸಂಪರ್ಕದ `rateLimitedUntil` ಈಗ ಭವಿಷ್ಯದಲ್ಲಿದೆ) ಮತ್ತು ಇದೇ ಗಾರ್ಡ್ ವೈಫಲ್ಯಕ್ಕಾಗಿ `transientRateLimitedProviders` ಅನ್ನು ನಿಗ್ರಹಿಸುವುದರ ಸಂಯೋಜನೆಯಾಗಿದೆ ("ಎರಡು-ಹಂತದ ವಿನ್ಯಾಸ" ಮತ್ತು `targetExhaustion.ts` ನಲ್ಲಿನ `isAgentrouterConnectionQuotaScope` ಶಾಖೆಯ ಕೋಡ್ ಕಾಮೆಂಟ್ ನೋಡಿ): ಆ ಸೆಟ್ ಅನ್ನು ಗುರುತಿಸದೆ ಬಿಟ್ಟಿರುವುದರಿಂದ, `combo.ts` ನ `allowRateLimitedConnection` ಬಲವಂತದ-ಅನುಮತಿ (`open-sse/services/combo.ts:1005-1013`, `:2734-2738`) ಪ್ರೊವೈಡರ್ನ ಉಳಿದ ಲೆಗ್ಗಳಿಗೆ ಸಕ್ರಿಯವಾಗುವುದಿಲ್ಲ; ಆದ್ದರಿಂದ ಕ್ರೆಡೆನ್ಶಿಯಲ್ ಆಯ್ಕೆಯ `rateLimitedUntil` ಫಿಲ್ಟರ್ (`src/sse/services/auth.ts:1238`) ಅನ್ನು ಸಾಮಾನ್ಯವಾಗಿ ಗೌರವಿಸಲಾಗುತ್ತದೆ ಮತ್ತು ಉಳಿದ ಲೆಗ್ ಬೇರೆ, ಇನ್ನೂ ಅರ್ಹವಾಗಿರುವ agentrouter ಸಂಪರ್ಕವನ್ನು ಆಯ್ಕೆಮಾಡುತ್ತದೆ ಅಥವಾ ಲಭ್ಯವಿರುವ ಕ್ರೆಡೆನ್ಶಿಯಲ್ಗಳಿಲ್ಲದೆ ವಿಫಲವಾಗುತ್ತದೆ — ಈ ಶಾಖೆ ಇದೀಗ ಕೂಲ್ಡೌನ್ಗೆ ಒಳಪಡಿಸಿದ ಸಂಪರ್ಕಕ್ಕೆ ಅದು ಬಲವಂತವಾಗಿ ಮರಳುವುದಿಲ್ಲ. ### ಎರಡು-ಹಂತದ ವಿನ್ಯಾಸ: ಸ್ಥಿತಿಯ ಮರುನಿರೂಪಣೆ, ನಂತರ ವರ್ಗೀಕರಣ ಸ್ಥಿತಿಯ ಮರುನಿರೂಪಣೆ (`upstreamStatusRestatement.ts`) ಮತ್ತು ಪ್ರೊವೈಡರ್ ವರ್ಗೀಕರಣ ನಿಯಮಗಳು (`open-sse/config/providerErrorRules.ts`, `providerRuleRegistry`) ಎರಡೂ ಪ್ರೊವೈಡರ್ ಐಡಿ ಮತ್ತು ಪಠ್ಯ ಗುರುತುಗಳನ್ನು ಕೀಲಿಗಳಾಗಿ ಬಳಸುವ ಪ್ರತ್ಯೇಕ ರಿಜಿಸ್ಟ್ರಿಗಳಾಗಿವೆ, ಆದರೆ ಅವು ವಿಭಿನ್ನ ಸ್ಥಳಗಳಲ್ಲಿ ಚಲಿಸುತ್ತವೆ ಮತ್ತು ವಿಭಿನ್ನ ಉದ್ದೇಶಗಳನ್ನು ಪೂರೈಸುತ್ತವೆ: ಮರುನಿರೂಪಣೆಯು `chatCore.ts` ನಲ್ಲಿ HTTP ಸ್ಥಿತಿಯನ್ನು ಆರಂಭದಲ್ಲೇ ಮರುಬರೆಯುತ್ತದೆ; ವರ್ಗೀಕರಣ ನಿಯಮಗಳು `checkFallbackError()` (`open-sse/services/accountFallback.ts`) ಒಳಗೆ ಫಾಲ್ಬ್ಯಾಕ್ `reason` ಮತ್ತು ಲಾಕ್ `scope` (`model` / `provider` / `connection`) ಅನ್ನು ಆಯ್ಕೆಮಾಡುತ್ತವೆ. ವರ್ಗೀಕರಣ ನಿಯಮಗಳು `providerErrorRules.ts` ನಲ್ಲಿನ `FULL_TEXT_RULE_PROVIDERS` ಅನುಮತಿಪಟ್ಟಿಯಲ್ಲಿ ಸೇರಿಸಲಾದ ಪ್ರೊವೈಡರ್ಗಳಿಗೆ ಮಾತ್ರ ಸಂಪೂರ್ಣ ದೋಷ **ಪಠ್ಯ**ವನ್ನು ನೋಡುತ್ತವೆ (`额度不足` ನಂತಹ ಬಾಡಿ ಗುರುತುಗಳನ್ನು ಹೊಂದಿಸಲು ಇದು ಅಗತ್ಯ) — ಪ್ರಸ್ತುತ ಕೇವಲ `"agentrouter"`. ಇತರ ಪ್ರತಿಯೊಂದು **ಅಂತರ್ನಿರ್ಮಿತ ಕ್ಯಾಟಲಾಗ್** ಪ್ರೊವೈಡರ್ಗಾಗಿ, `checkFallbackError` ಎಂಬುದು `getProviderErrorRuleMatch` ಗೆ ರಚನಾತ್ಮಕ ದೋಷವನ್ನು (`{code, type}`) ಮಾತ್ರ ನೀಡುತ್ತದೆ; ಇದು ಹೆಡರ್/ಸ್ಥಿತಿ/ಕೋಡ್ ಆಧಾರಿತ ನಿಯಮಗಳಿಗೆ ಸಾಕಾಗುತ್ತದೆ, ಆದರೆ ಬಾಡಿ-ಪಠ್ಯದ ಗುರುತುಗಳನ್ನು ಕಾಣುವುದಿಲ್ಲ. `resolveRuleMatchBody()` ಸಹಾಯಕವು ಈ ಆಯ್ಕೆಯನ್ನು ನಿರ್ವಹಿಸುತ್ತದೆ: ಅನುಮತಿಪಟ್ಟಿಯಲ್ಲಿರುವ ಪ್ರೊವೈಡರ್ಗಳಿಗೆ ಸಂಪೂರ್ಣ ದೋಷ ಪಠ್ಯ, ಇಲ್ಲದಿದ್ದರೆ ರಚನಾತ್ಮಕ ದೋಷ. ಒಂದು **ಅಂತರ್ನಿರ್ಮಿತ** ಪ್ರೊವೈಡರ್ ಅನ್ನು `FULL_TEXT_RULE_PROVIDERS` ಗೆ ಸೇರಿಸುವುದು ಸ್ಪಷ್ಟವಾದ ಪ್ರತಿ-ಪ್ರೊವೈಡರ್ ಆಯ್ಕೆಯಾಗಿದೆ — ಪಟ್ಟಿಯಲ್ಲಿಲ್ಲದ ಪ್ರತಿಯೊಂದು ಪ್ರೊವೈಡರ್ನ ಡೀಫಾಲ್ಟ್ ಮಾರ್ಗವು ಬೈಟ್ಗೆ-ಬೈಟ್ ಬದಲಾಗದಂತೆ ಉಳಿಯಲು ಇದು ಅಸ್ತಿತ್ವದಲ್ಲಿದೆ. ನಿಯಮದ `scope` (`model` / `provider` / `connection`) ಎಂಬುದು `FULL_TEXT_RULE_PROVIDERS` ಗಿಂತ ಪ್ರತ್ಯೇಕವಾದ ಆಯ್ಕೆಯಾಗಿದೆ: `checkFallbackError` ಅದನ್ನು `fallbackResult.ruleScope` ಆಗಿ ಮಾತ್ರ ಹೊರತರುತ್ತದೆ; ಅದೇ ಫೈಲ್ನಲ್ಲಿರುವ `HONORS_RULE_LOCK_SCOPE_PROVIDERS` ಅನುಮತಿಪಟ್ಟಿಯಲ್ಲಿರುವ ಪ್ರೊವೈಡರ್ಗಳಿಗೆ ಮಾತ್ರ ಡೌನ್ಸ್ಟ್ರೀಮ್ ಬಳಕೆದಾರರು ಅದನ್ನು ಮಾಹಿತಿಪೂರ್ಣ ಲೇಬಲ್ಗಿಂತ ಹೆಚ್ಚಾಗಿ ಗೌರವಿಸುತ್ತಾರೆ (`honorsRuleLockScope()` ಮೂಲಕ ನಿಯಂತ್ರಿಸಲಾಗಿದೆ — ಇಂದು ಕೇವಲ `"agentrouter"`). ಪ್ರೊವೈಡರ್ ಆ ಅನುಮತಿಪಟ್ಟಿಯಲ್ಲಿ ಸೇರಿದ ಬಳಿಕ `scope: "connection"` ಹೊಂದಾಣಿಕೆ ವಾಸ್ತವವಾಗಿ ಏನು ಮಾಡುತ್ತದೆ ಎಂಬುದಕ್ಕಾಗಿ ಮೇಲಿನ "ಮರುನಿರೂಪಿಸಲಾದ ಕೋಟಾ ದೋಷಗಳು" ನೋಡಿ. **#11104 — ಆಪರೇಟರ್ ಘೋಷಿಸಿದ ನಿಯಮಗಳು ಎರಡೂ ಅನುಮತಿಪಟ್ಟಿಗಳನ್ನು ಬೈಪಾಸ್ ಮಾಡುತ್ತವೆ.** ಆಪರೇಟರ್ ಈ ಫೈಲ್ ಅನ್ನು ಸಂಪಾದಿಸದೆಯೇ ರನ್ಟೈಮ್ನಲ್ಲಿ `settings.providerErrorRules` (`open-sse/config/providerErrorRules.ts::setOperatorProviderErrorRules`) ಮೂಲಕ ಪ್ರತಿ-ಪ್ರೊವೈಡರ್ ನಿಯಮವನ್ನು ಘೋಷಿಸಬಹುದು. ಅಂತರ್ನಿರ್ಮಿತ ಕ್ಯಾಟಲಾಗ್ ನಿಯಮಗಳ **ಡೀಫಾಲ್ಟ್** ನಡವಳಿಕೆಯನ್ನು ರಕ್ಷಿಸಲು ಉದ್ದೇಶಿಸಲಾದ `FULL_TEXT_RULE_PROVIDERS`/`HONORS_RULE_LOCK_SCOPE_PROVIDERS` ಅನುಮತಿಪಟ್ಟಿಗಳ ಹಿಂದೆ ಆಪರೇಟರ್ ನಿಯಮವನ್ನು ನಿಯಂತ್ರಿಸಿದರೆ, ಈಗಾಗಲೇ ಅಲ್ಲಿ ಪಟ್ಟಿಮಾಡಿರುವ ಪ್ರೊವೈಡರ್ಗಳನ್ನು ಹೊರತುಪಡಿಸಿ ಉಳಿದ ಪ್ರತಿಯೊಂದು ಪ್ರೊವೈಡರ್ಗೆ ಸೆಟ್ಟಿಂಗ್ಗಳ ಕಾರ್ಯವಿಧಾನವು ನಿಷ್ಕ್ರಿಯವಾಗುತ್ತದೆ; ಏಕೆಂದರೆ ನಿಯಮವನ್ನು ಘೋಷಿಸುವುದೇ ಆಪರೇಟರ್ನ ಸ್ಪಷ್ಟ ಆಯ್ಕೆಯಾಗಿದೆ. `resolveRuleMatchBody()` ಮತ್ತು `honorsRuleLockScope()` ಎರಡೂ ಮೊದಲು `hasOperatorRuleForProvider()` ಅನ್ನು ಪರಿಶೀಲಿಸುತ್ತವೆ: ಆಪರೇಟರ್ ನಿಯಮವಿರುವ ಪ್ರೊವೈಡರ್, ಅದು ಎರಡರಲ್ಲಿ ಯಾವುದಾದರೂ ಅನುಮತಿಪಟ್ಟಿಯಲ್ಲಿ ಕಾಣಿಸಿಕೊಳ್ಳುತ್ತದೆಯೇ ಎಂಬುದನ್ನು ಲೆಕ್ಕಿಸದೆ, ಕಚ್ಚಾ ದೋಷ ಪಠ್ಯವನ್ನು ಪಡೆಯುತ್ತದೆ ಮತ್ತು ಅದರ ಘೋಷಿತ `scope` ಅನ್ನು ಗೌರವಿಸಲಾಗುತ್ತದೆ. **ತಿಳಿದಿರುವ ಕೊರತೆ — HTTP 400 ಗಾಗಿ `providerRuleRegistry` ಅನ್ನು ಎಂದಿಗೂ ಪರಾಮರ್ಶಿಸಲಾಗುವುದಿಲ್ಲ.** `checkFallbackError` ನ `BAD_REQUEST` ಶಾಖೆಯು ಸ್ಥಿತಿ 400 ಅನ್ನು ಸಂಪೂರ್ಣವಾಗಿ ತನ್ನದೇ ಪ್ಯಾಟರ್ನ್ ಅರೇಗಳ ಮೂಲಕ ವರ್ಗೀಕರಿಸುತ್ತದೆ (`MODEL_ACCESS_DENIED_PATTERNS`, `CONTEXT_OVERFLOW_PATTERNS`, ಇತ್ಯಾದಿ `accountFallback.ts` ನಲ್ಲಿ) ಮತ್ತು ಅದರ ಮೇಲಿರುವ `configuredRule`/`getProviderErrorRuleMatch` ಶಾಖೆಯನ್ನು ತಲುಪುವ ಮೊದಲೇ ಹಿಂದಿರುಗುತ್ತದೆ. `status: 400` ಹೊಂದಿರುವ ಅಂತರ್ನಿರ್ಮಿತ ಕ್ಯಾಟಲಾಗ್ ನಿಯಮವು (ಅಥವಾ ಆಪರೇಟರ್ ನಿಯಮವು) ವಾಕ್ಯರಚನೆಯ ದೃಷ್ಟಿಯಿಂದ ಮಾನ್ಯವಾಗಿದ್ದರೂ ಎಂದಿಗೂ ಚಲಿಸುವುದಿಲ್ಲ. ಇಂದು ಯಾವುದೇ ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ ನಿಯಮವು 400 ಅನ್ನು ಗುರಿಯಾಗಿಸುವುದಿಲ್ಲ, ಆದ್ದರಿಂದ ಪ್ರೊಡಕ್ಷನ್ನಲ್ಲಿ ಯಾವುದಕ್ಕೂ ಪರಿಣಾಮವಿಲ್ಲ — ಆದರೆ ಭವಿಷ್ಯದ 400 ನಿಯಮಕ್ಕೆ ಮೊದಲು ಈ ಶಾಖೆಯನ್ನು ಬದಲಾಯಿಸಬೇಕಾಗುತ್ತದೆ; ಇದು ಕೇವಲ ನಿಯಮವೊಂದನ್ನು ಸೇರಿಸುವುದಕ್ಕಿಂತ ದೊಡ್ಡ ಬದಲಾವಣೆಯಾಗಿದೆ (ಇದು ಈಗಾಗಲೇ ಪ್ಯಾಟರ್ನ್-ಅರೇ ನಡವಳಿಕೆಯನ್ನು ಅವಲಂಬಿಸಿರುವ ಪ್ರತಿಯೊಂದು ಪ್ರೊವೈಡರ್ಗಾಗಿ 400 ಅನ್ನು ಮರುವರ್ಗೀಕರಿಸುತ್ತದೆ) ಮತ್ತು ಏಕ-ಪ್ರೊವೈಡರ್ ನಿಯಮ ಸೇರ್ಪಡೆಯ ವ್ಯಾಪ್ತಿಯಿಂದ ಹೊರಗಿದೆ. ### ಹೊಸ ಕೋಟಾ-ತಪ್ಪಾಗಿ-ಹೇಳುವ ಗೇಟ್ವೇ ಸೇರಿಸುವುದು 1. `statusRestatementRegistry` ನಲ್ಲಿ ಒಂದು ನಿಯಮ array ಅನ್ನು ನೋಂದಾಯಿಸಿ (`open-sse/config/upstreamStatusRestatement.ts`). `textMarkers` ಅನ್ನು ಪ್ರೊವೈಡರ್-ನಿರ್ದಿಷ್ಟವಾಗಿ ಇರಿಸಿ; `CREDITS_EXHAUSTED_SIGNALS` (`open-sse/services/accountFallback.ts`) ಗೆ ಢಿಕ್ಕಿ ಹೊಡೆಯುವ ಸಾಮಾನ್ಯ ಇಂಗ್ಲಿಷ್ ನುಡಿಗಟ್ಟುಗಳನ್ನು ಎಂದಿಗೂ ಮರುಬಳಕೆ ಮಾಡಬೇಡಿ. 2. ಸರಿಯಾದ ಲಾಕ್ ವ್ಯಾಪ್ತಿಯನ್ನು ಆಯ್ಕೆಮಾಡಲು (ಖಾತೆ-ವ್ಯಾಪ್ತಿಯ ಕೋಟಾಗಾಗಿ `connection`, ಪ್ರತಿ-ಮಾಡೆಲ್ ದೋಷಗಳಿಗಾಗಿ `model`) ಐಚ್ಛಿಕವಾಗಿ `open-sse/config/providerErrorRules.ts` (`providerRuleRegistry`) ನಲ್ಲಿ ವರ್ಗೀಕರಣ ನಿಯಮಗಳನ್ನು ನೋಂದಾಯಿಸಿ. ಈ ಹಂತವು production ನಲ್ಲಿ ಕೇವಲ ಆ ಪ್ರೊವೈಡರ್ಗಳಿಗೆ ಪರಿಣಾಮ ಬೀರುತ್ತದೆ — ಯಾವುಗಳ ನಿಯಮಗಳಿಗೆ ಪೂರ್ಣ ದೋಷ ಪಠ್ಯ (body markers) ಬೇಕಾಗುತ್ತದೆಯೋ: ಅದೇ ಫೈಲ್ನಲ್ಲಿ ಪ್ರೊವೈಡರ್ id ಅನ್ನು `FULL_TEXT_RULE_PROVIDERS` ಗೆ ಸೇರಿಸಿ — ಇಲ್ಲವಾದರೆ `checkFallbackError` ನಿಯಮಕ್ಕೆ ಯಾವಾಗಲೂ structured `{code, type}` ದೋಷವನ್ನು ಮಾತ್ರ ಹಸ್ತಾಂತರಿಸುತ್ತದೆ ಮತ್ತು body-text ನಿಯಮವು ಲೈವ್ ಟ್ರಾಫಿಕ್ಗೆ ಎಂದಿಗೂ ಹೊಂದಿಕೆಯಾಗುವುದಿಲ್ಲ. ಸಂಪೂರ್ಣವಾಗಿ `status`/`headers` ಮೇಲೆ ಮಾತ್ರ ಹೊಂದಿಕೆಯಾಗುವ ನಿಯಮಗಳಿಗೆ (Opencode ಅಥವಾ Minimax ನಂತಹುವು) ಈ opt-in ಅಗತ್ಯವಿಲ್ಲ. ಪ್ರತ್ಯೇಕವಾಗಿ, ನಿಯಮವು `scope: "connection"` ಅನ್ನು ಘೋಷಿಸಿದ್ದು, ಉದ್ದೇಶವು ನಿಜವಾದ connection-ವ್ಯಾಪ್ತಿಯ ಕೂಲ್ಡೌನ್ ಜೊತೆಗೆ ಅದೇ-ವಿನಂತಿಯ combo ಸ್ಕಿಪ್ ಆಗಿದ್ದರೆ (ಕೇವಲ ಮಾಹಿತಿ ಲೇಬಲ್ ಅಲ್ಲ), ಅದೇ ಫೈಲ್ನಲ್ಲಿ ಪ್ರೊವೈಡರ್ id ಅನ್ನು `HONORS_RULE_LOCK_SCOPE_PROVIDERS` ಗೆ ಸೇರಿಸಿ — `markAccountUnavailable()` (`src/sse/services/auth.ts`) ಮತ್ತು `applyComboTargetExhaustion()` (`open-sse/services/combo/targetExhaustion.ts`) ನಲ್ಲಿ `isAgentrouterConnectionQuotaScope()`-ಶೈಲಿಯ ಬಳಕೆಯನ್ನು ನಿಯಂತ್ರಿಸುವುದು ಇದೇ; ಇದು ಇಲ್ಲದಿದ್ದರೆ, `scope` ಇನ್ನೂ `fallbackResult.ruleScope` ಮೂಲಕ ಹರಿಯುತ್ತದೆ ಆದರೆ ಏನೂ ಅದರ ಮೇಲೆ ಕ್ರಿಯಿಸುವುದಿಲ್ಲ. 3. `tests/unit/upstream-status-restatement.test.ts` ಮತ್ತು `tests/unit/agentrouter-error-rules.test.ts` ಅನ್ನು ಅನುಕರಿಸುವ ಯೂನಿಟ್ ಟೆಸ್ಟ್ಗಳನ್ನು ಸೇರಿಸಿ (not-permanent / not-creditsExhausted ಗಾರ್ಡ್ಗಳು ಸೇರಿದಂತೆ, ಮತ್ತು — ಪ್ರೊವೈಡರ್ಗೆ allowlist ಬೇಕಾದರೆ — `resolveRuleMatchBody()` ಆ ಪ್ರೊವೈಡರ್ಗೆ ಮಾತ್ರ ಪೂರ್ಣ ಪಠ್ಯವನ್ನು ಹಿಂದಿರುಗಿಸುತ್ತದೆ ಎಂದು ದೃಢೀಕರಿಸುವ ಟೆಸ್ಟ್). `chatCore.ts`, `classifyError`, ಅಥವಾ combo ಗೆ ಯಾವುದೇ ಬದಲಾವಣೆಗಳು ಅಗತ್ಯವಿಲ್ಲ. #### Egress-ಬಕೆಟ್ ಮಾಡಲಾದ ಲಾಕ್ (#10880) `EGRESS_BUCKETED_LOCK_PROVIDERS` ನಲ್ಲಿರುವ ಪ್ರೊವೈಡರ್ಗಳನ್ನು (opencode ಕುಟುಂಬ) IP-ಬಕೆಟ್ ಮಾಡಲಾದ ಅಪ್ಸ್ಟ್ರೀಮ್ ಎಂದು ಪರಿಗಣಿಸಲಾಗುತ್ತದೆ (opencode ಉಚಿತ ಶ್ರೇಣಿಯು IP-ಬಕೆಟ್ ಮಾಡಲಾದದ್ದು, ಖಾತೆ-ಬಕೆಟ್ ಮಾಡಲಾದದ್ದು ಅಲ್ಲ — #9611 ನೋಡಿ): status-429 ಎಂದು ವರ್ಗೀಕರಿಸಲಾದ `quota_exhausted` **ಅಥವಾ** `rate_limit_exceeded`, ವಿಫಲವಾದ ಕನೆಕ್ಷನ್ನ ಕೊನೆಯ ತಿಳಿದ egress IP ಗೆ ಹೊಂದಿಕೆಯಾಗುವ ಪ್ರತಿ allowlist-ಮಾಡಲಾದ-ಕುಟುಂಬದ ಕನೆಕ್ಷನ್ ಅನ್ನು, ರೋಟೇಶನ್ ಅವುಗಳನ್ನು ಪ್ರಯತ್ನಿಸುವ ಮೊದಲು ಕೂಲ್ ಡೌನ್ ಮಾಡುತ್ತದೆ — N-1 ಖಚಿತವಾಗಿ-ವಿಫಲವಾಗುವ ಅಪ್ಸ್ಟ್ರೀಮ್ ಕರೆಗಳನ್ನು ತಪ್ಪಿಸುತ್ತದೆ (#10460/#10525 ರ ಅದೇ ಆಕಾರ). `rate_limit_exceeded` ಅನ್ನು ಉದ್ದೇಶಪೂರ್ವಕವಾಗಿ ಸೇರಿಸಲಾಗಿದೆ: `markAccountUnavailable` ಮಾರ್ಗದಲ್ಲಿ opencode-ನಿರ್ದಿಷ್ಟ ನಿಯಮಗಳು ಎಂದಿಗೂ ಹೊಂದಿಕೆಯಾಗುವುದಿಲ್ಲ (`checkFallbackError` ಗೆ headers/body ಹಸ್ತಾಂತರಿಸಲಾಗುವುದಿಲ್ಲ, opencode `FULL_TEXT_RULE_PROVIDERS` ನಲ್ಲಿ ಇಲ್ಲ), ಆದ್ದರಿಂದ subscription-quota ಪಠ್ಯವನ್ನು ("monthly usage limit reached") ಹೊತ್ತ body ಹೊಂದಿರುವ 429 ಅನ್ನು `status_429` ನಿಯಮವನ್ನು ತಲುಪುವ ಮೊದಲೇ quota-text fallback (`buildSubscriptionQuotaFallback`, `accountFallback.ts`; 1h ಕೂಲ್ಡೌನ್) ಮೂಲಕ `quota_exhausted` ಎಂದು ವರ್ಗೀಕರಿಸಲಾಗುತ್ತದೆ — ಆದರೆ quota-text-ರಹಿತ 429 (ಸರಳ rate limiting) `status_429` ನಿಯಮದ ಮೂಲಕ `rate_limit_exceeded` ಎಂದು ವರ್ಗೀಕರಿಸಲ್ಪಡುತ್ತದೆ ಮತ್ತು ಇನ್ನೂ IP ಕುಟುಂಬವನ್ನು ಕೂಲ್ ಡೌನ್ ಮಾಡುತ್ತದೆ. allowlist-ಮಾಡಲಾದ ಪ್ರೊವೈಡರ್ಗೆ IP-ಬಕೆಟ್ ಮಾಡಲಾದ rate limit ಎಂಬುದು ಕೋಟಾ ಖಾಲಿಯಾದ ಸಂಕೇತಕ್ಕೆ ಸಮನಾದ ಸಂಕೇತ. ಪ್ರಾಮಾಣಿಕ ಮಿತಿಗಳು: - **ಬೆಸ್ಟ್-ಎಫರ್ಟ್**: ಲಾಕ್ ಕನೆಕ್ಷನ್ನ ಕೊನೆಯ ತಿಳಿದ `egress_ip` ಅನ್ನು `proxy_logs` ನಿಂದ ರಿಸಾಲ್ವ್ ಮಾಡುತ್ತದೆ (24h ವಿಂಡೋ, ಸಿಂಕ್ರೊನಸ್, ಕ್ಯಾಶೆ ಇಲ್ಲ). ಕೋಲ್ಡ್ ಕ್ಯಾಶೆ (egress IP ಅನ್ನು ಎಂದಿಗೂ ಪ್ರೋಬ್ ಮಾಡಲಾಗಿಲ್ಲ) ಅಥವಾ ರೋವೇ ಇಲ್ಲ → ವಿಫಲ ಕನೆಕ್ಷನ್ ಅನ್ನು ಬ್ರಾಂಚ್ ಇನ್ನೂ ಕೂಲ್ ಮಾಡುತ್ತದೆ (ಇಂದಿನಂತೆಯೇ ದಾಖಲಿಸಲಾಗುತ್ತದೆ), ಕೇವಲ ಯಾವುದೇ ಸಿಬ್ಲಿಂಗ್ ಲಾಕ್ ಆಗುವುದಿಲ್ಲ. - **ಎಂದಿಗೂ ಟರ್ಮಿನಲ್ ಅಲ್ಲ**: ಕೂಲ್ಡೌನ್ ಎಂಬುದು ರಿನ್ಯೂ ಆಗುವ ಕೋಟಾ ವಿಂಡೋ (`testStatus: "unavailable"`); IP-ಮಟ್ಟದ ಸಿಗ್ನಲ್ನಿಂದ ಶಾಶ್ವತ ಸ್ಥಿತಿಯನ್ನು ಎಂದಿಗೂ ತರಲಾಗುವುದಿಲ್ಲ. `disableCooling` ಕನೆಕ್ಷನ್ಗಳು ಬ್ರಾಂಚ್ ಅನ್ನು ಸಂಪೂರ್ಣವಾಗಿ ಸ್ಕಿಪ್ ಮಾಡುತ್ತವೆ. - **ಅಲೋಲಿಸ್ಟ್ ಮಾಡಲಾದ ಫ್ಯಾಮಿಲಿಗೆ ಲಾಕ್ ಗ್ರ್ಯಾನುಲಾರಿಟಿ ಬದಲಾಗುತ್ತದೆ**: ಇದು ಸ್ಕೋಪ್ ಬದಲಾವಣೆ, ಕೇವಲ ಸಿಬ್ಲಿಂಗ್ ಆಪ್ಟಿಮೈಸೇಶನ್ ಅಲ್ಲ. opencode ಒಂದು `passthroughModels` ಪ್ರೊವೈಡರ್ ಆಗಿರುವುದರಿಂದ, ಈ ಬ್ರಾಂಚ್ಗೆ ಮೊದಲು 429 ಪ್ರತಿ-MODEL ಲಾಕ್ಔಟ್ ಅನ್ನು ಉಂಟುಮಾಡುತ್ತಿತ್ತು; ಈಗ ಅದು ಕನೆಕ್ಷನ್ ಕೂಲ್ಡೌನ್ ಅನ್ನು ಉಂಟುಮಾಡುತ್ತದೆ — ಯಾವುದೇ ಸಿಬ್ಲಿಂಗ್ ಇಲ್ಲದೆ ಏಕೈಕ ಕನೆಕ್ಷನ್ ಅನ್ನು ರನ್ ಮಾಡುವ ಆಪರೇಟರ್ಗೂ ಸಹ. opencode ರೂಲ್ ಟೇಬಲ್ ಈಗಾಗಲೇ ಸರಿಯೆಂದು ಘೋಷಿಸಿರುವ ಗ್ರ್ಯಾನುಲಾರಿಟಿ ಅದೇ (`scope: "connection"`, `providerErrorRules.ts`), opencode `HONORS_RULE_LOCK_SCOPE_PROVIDERS` ನಲ್ಲಿ ಇಲ್ಲದ ಕಾರಣ ಇಲ್ಲಿಯವರೆಗೆ ಎಂದಿಗೂ ಅನುಸರಿಸಲಾಗಿಲ್ಲ. ಬ್ರಾಂಚ್ ವಿಫಲ ಕನೆಕ್ಷನ್ನ ಕೂಲ್ಡೌನ್ + `backoffLevel` ಅನ್ನು ಸ್ವತಃ ಬರೆಯುತ್ತದೆ, ಕನೆಕ್ಷನ್-ಸ್ಕೋಪ್ಡ್ agentrouter ಬ್ರಾಂಚ್ ಅನ್ನು ಮಿರರ್ ಮಾಡುತ್ತದೆ, ಮತ್ತು ರಿಟರ್ನ್ ಮಾಡುತ್ತದೆ — ಪ್ರತಿ-ಮಾಡೆಲ್ ಬ್ಲಾಕ್ ಮತ್ತು ಕೆಳಗಿನ ಜೆನೆರಿಕ್ ಪಾತ್ ಅನ್ನು ಎಂದಿಗೂ ತಲುಪಲಾಗುವುದಿಲ್ಲ. - **ಕಾಂಬೊ ಸೇರಿದೆ**: agentrouter ಬ್ರಾಂಚ್ನಂತೆ, ಈ ಸ್ಕೋಪ್ ಕಾಂಬೊ ಕಾಲರ್ 429 ಗೆ ಅನ್ವಯಿಸುವ `persistUnavailableState`/`isCombo` ಡೌನ್ಗ್ರೇಡ್ ಅನ್ನು ಉದ್ದೇಶಪೂರ್ವಕವಾಗಿ ನಿರ್ಲಕ್ಷಿಸುತ್ತದೆ. ಪ್ರತಿ-ಮಾಡೆಲ್ ಲಾಕ್ಔಟ್ ಈ ಸ್ಕೋಪ್ನ ದುರ್ಬಲ ರೂಪವಲ್ಲ, ಅದು ತಪ್ಪು ಯೂನಿಟ್: ಅದು ಎಕ್ಸಾಸ್ಟ್ ಆದ IP ಬಗ್ಗೆ ಏನನ್ನೂ ಹೇಳುವುದಿಲ್ಲ, ಆದ್ದರಿಂದ ಕಾಂಬೊ ರೊಟೇಶನ್ ಪ್ರತಿ ಸಿಬ್ಲಿಂಗ್ಗೆ ಖಚಿತವಾಗಿ ವಿಫಲವಾಗುವ ಒಂದು ಕರೆಯನ್ನು ಸುಡುತ್ತಲೇ ಇರುತ್ತದೆ. - **ಸಿಬ್ಲಿಂಗ್ ಸುರಕ್ಷತೆ**: ಈಗಾಗಲೇ ಟರ್ಮಿನಲ್ ಆಗಿರುವ (banned/credits_exhausted) ಅಥವಾ ಈಗಾಗಲೇ ಹೆಚ್ಚು ಉದ್ದದ ಕೂಲ್ಡೌನ್ನಲ್ಲಿರುವ ಸಿಬ್ಲಿಂಗ್ ಅನ್ನು ಎಂದಿಗೂ ಓವರ್ರೈಟ್ ಮಾಡಲಾಗುವುದಿಲ್ಲ. - **ಎಕ್ಸ್ಕ್ಲೂಸಿವ್ ಅಲೋಲಿಸ್ಟ್**: `EGRESS_BUCKETED_LOCK_PROVIDERS` ಅನ್ನು ವಿಸ್ತರಿಸುವುದು ಸ್ಪಷ್ಟ ಓನರ್ ನಿರ್ಧಾರ; ಯಾವುದೇ ಜೆನೆರಿಕ್ ವೈರಿಂಗ್ ಇಲ್ಲ (ಪ್ಯಾಟರ್ನ್ #10334/#10419). ಸಿಬ್ಲಿಂಗ್ ಕ್ವೆರಿ ಅದನ್ನು SQL ಲಿಟರಲ್ ಆಗಿ ಪುನರಾವರ್ತಿಸುವ ಬದಲು ಅದೇ ಅಲೋಲಿಸ್ಟ್ ಅನ್ನು ಬೈಂಡ್ ಮಾಡುತ್ತದೆ, ಆದ್ದರಿಂದ ಅದನ್ನು ವಿಸ್ತರಿಸುವುದು ಒಂದು-ಸಾಲಿನ ಬದಲಾವಣೆಯಾಗಿಯೇ ಉಳಿಯುತ್ತದೆ. - **Egress IP ರೊಟೇಶನ್, ಎರಡೂ ದಿಕ್ಕುಗಳಲ್ಲಿ**: ಲುಕ್ಅಪ್ ವಿಂಡೋ (24h) egress-IP ಕ್ಯಾಶೆ TTL (5 ನಿಮಿಷ) ಗಿಂತ ಬಹಳ ವಿಶಾಲವಾಗಿದೆ, ಆದ್ದರಿಂದ "ಕೊನೆಯ ತಿಳಿದ IP" ಎಂಬುದು ಇತಿಹಾಸ, ಪ್ರಸ್ತುತ ಸ್ಥಿತಿಯಲ್ಲ. ಕನೆಕ್ಷನ್ನ ಪ್ರಾಕ್ಸಿ ವಿಂಡೋದೊಳಗೆ ರೊಟೇಟ್ ಆಗಿದ್ದರೆ, ಲಾಕ್ ನಿಜವಾಗಿ ಹಂಚಿಕೊಂಡ IP ಅನ್ನು **ಮಿಸ್ ಮಾಡಬಹುದು** (ದಾಖಲಾದ IP ಹೊಸದು, ಎಕ್ಸಾಸ್ಟ್ ಆಗದ್ದು) — ಮತ್ತು ಸಮ್ಮಿತೀಯವಾಗಿ, ಎಕ್ಸಾಸ್ಟ್ ಆದ IP ಯಿಂದ **ಈ ನಡುವೆ ರೊಟೇಟ್ ಆಗಿ ಹೋಗಿರುವ ಸಿಬ್ಲಿಂಗ್ ಅನ್ನು ಕೂಲ್ ಮಾಡಬಹುದು**. ಎರಡನೇ ಸಂದರ್ಭ ಆ ಸಿಬ್ಲಿಂಗ್ಗೆ ಒಂದು ಕೂಲ್ಡೌನ್ ವಿಂಡೋ ಬೆಲೆ ಬೀರುತ್ತದೆ; ಎರಡೂ ಇತಿಹಾಸ-ಆಧಾರಿತ ಲುಕ್ಅಪ್ನ ಸ್ವೀಕರಿಸಲಾದ ಬೆಸ್ಟ್-ಎಫರ್ಟ್ ಮಿತಿಗಳು. - **ವೆಚ್ಚ**: `proxy_logs` ನ ಎರಡು ಬೌಂಡೆಡ್ ಸ್ಕ್ಯಾನ್ಗಳು (`idx_pl_timestamp` ಮೂಲಕ ವಿಂಡೋ-ಫಿಲ್ಟರ್ ಮಾಡಲಾಗಿದೆ), ಕೇವಲ 429 ಆವೃತ್ತಿಯಲ್ಲಿ. ಹೊಸ ಇಂಡೆಕ್ಸ್ ಇಲ್ಲ (ಮೈಗ್ರೇಶನ್ 134 YAGNI). ಮಧ್ಯಮ ಗಾತ್ರದ ನಿಜ-ಟ್ರಾಫಿಕ್ DB ಕಾಪಿಯಲ್ಲಿ ಅಳೆಯಲಾಗಿದೆ; ಹೈ-ಥ್ರೂಪುಟ್ ಇನ್ಸ್ಟಾನ್ಸ್ ಅದೇ ವಿಂಡೋದಲ್ಲಿ ಅನುಪಾತದಲ್ಲಿಯೇ ಹೆಚ್ಚು ರೋಗಳನ್ನು ಹೊಂದಿರುತ್ತದೆ. --- ## ಇತರ ಸ್ಥೈರ್ಯ ವೈಶಿಷ್ಟ್ಯಗಳು - **20 ರೌಟಿಂಗ್ ತಂತ್ರಗಳು** (priority, weighted, round-robin, context-relay, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, quota-weighted, strict-random, auto, lkgp, context-optimized, cache-optimized, fusion, pipeline) — [AUTO-COMBO.md](../routing/AUTO-COMBO.md) ನೋಡಿ. - **ರೀಸೆಟ್-ಅವೇರ್ ರೌಟಿಂಗ್** (v3.8.0) — ಕೋಟಾ ಮರುಹೊಂದಿಸುವ ಸಮಯದ ಮೂಲಕ ಸಂಪರ್ಕಗಳಿಗೆ ಆದ್ಯತೆ ನೀಡುತ್ತದೆ. - **ಹಿನ್ನೆಲೆ ಮೋಡ್ ಡಿಗ್ರಡೇಶನ್** — Responses API `background: true` ಅನ್ನು ಎಚ್ಚರಿಕೆಯೊಂದಿಗೆ ಸಿಂಕ್ ಗೆ ಇಳಿಸಲಾಗುತ್ತದೆ. - **ಡೈನಾಮಿಕ್ ಟೂಲ್ ಲಿಮಿಟ್ ಪತ್ತೆ** — ಟೂಲ್ ಸಂಖ್ಯೆಯ ಮಿತಿಗಳನ್ನು ತಲುಪಿದಾಗ ಪ್ರೊವೈಡರ್ಗಳನ್ನು ಹಿಮ್ಮೆಟ್ಟಿಸುತ್ತದೆ. - **ತುರ್ತು ಫಾಲ್ಬ್ಯಾಕ್** — `OMNIROUTE_EMERGENCY_FALLBACK` ಮೂಲಕ ನಿಯಂತ್ರಿಸಲಾಗುತ್ತದೆ; ಆಪರೇಟರ್ಗಳು ಮರುಪ್ರಾರಂಭವಿಲ್ಲದೆ Feature Flags ಪುಟದಿಂದ ಅದನ್ನು ಅಧಿಕ್ರಮಿಸಬಹುದು. --- ## ಡೀಬಗ್ಗಿಂಗ್ - Weighted combo `503 all_targets_cooling_down` ಎಂದು ಉತ್ತರಿಸಿದಾಗ (`Retry-After` ಸೆಟ್ ಮಾಡಲಾಗಿದೆ, `diagnostics.excluded` ಪ್ರತಿ ಟಾರ್ಗೆಟ್ ಅನ್ನು `model_lockout` / `circuit_open` / `provider_cooldown` / `unavailable` ನೊಂದಿಗೆ ಪಟ್ಟಿ ಮಾಡುತ್ತದೆ) → ಪೂಲ್ ಕಾನ್ಫಿಗರ್ ಆಗಿದೆ ಮತ್ತು ಸಂಪರ್ಕಗೊಂಡಿದೆ, ಪ್ರತಿ ಟಾರ್ಗೆಟ್ ಕೇವಲ ಸ್ಥೈರ್ಯ ಟೈಮರ್ ಮೂಲಕ ಹೊರಗಿಡಲಾಗಿದೆ; `[COMBO] Weighted selection: every target excluded before dispatch — …` ಎಚ್ಚರಿಕೆಯು ಕಾರಣಗಳು ಮತ್ತು ಉಳಿದ ಸೆಕೆಂಡುಗಳನ್ನು ಹೆಸರಿಸುತ್ತದೆ. ಅದೇ ಕಾಂಬೊದಿಂದ ಬಂದ `404 no_executable_targets` ಎಂದರೆ ಯಾವುದೇ ಸ್ಥೈರ್ಯ ಟೈಮರ್ ಭಾಗವಹಿಸಿಲ್ಲ (ಚಲಾಯಿಸಲು ಏನೂ ಇಲ್ಲ, ಅಥವಾ ಪ್ರತಿ ಖಾತೆಯು ಲಭ್ಯತೆ ಪರೀಕ್ಷೆಯಲ್ಲಿ ವಿಫಲವಾಗಿದೆ). `targetResolution.ts` ನಲ್ಲಿ ಸಂಗ್ರಹಿಸಲಾದ ಹೊರತಾಕಿಕೆಗಳಿಂದ `open-sse/services/combo/pinRecovery.ts` ನಲ್ಲಿ ನಿರ್ಮಿಸಲಾಗಿದೆ. - ಪ್ರೊವೈಡರ್ಗೆ ಎಲ್ಲಾ ಕೀಲಿಗಳನ್ನು ಸ್ಕಿಪ್ ಮಾಡಲಾಗಿದೆ → circuit breaker ಸ್ಥಿತಿ ಮತ್ತು ಪ್ರತಿ ಸಂಪರ್ಕದ `rateLimitedUntil`/`testStatus` ಎರಡನ್ನೂ ಪರಿಶೀಲಿಸಿ. - ಮರುಹೊಂದಿಸುವ ವಿಂಡೋ ನಂತರ ಪ್ರೊವೈಡರ್ ಶಾಶ್ವತವಾಗಿ ಹೊರಗಿಡಲಾಗಿದೆ → `getStatus()`/`canExecute()` ಬದಲಿಗೆ ಕಚ್ಚಾ `state` ಓದುವ ಕೋಡ್. - ಒಂದು ಕೀಲಿ ವಿಫಲವಾಗಿದೆ, ಇತರವು ಕೆಲಸ ಮಾಡಬೇಕು → circuit breaker ಗಿಂತ connection cooldown ಅನ್ನು ಆದ್ಯತೆ ನೀಡಿ. - ಕೇವಲ ಒಂದು ಮಾಡೆಲ್ ವಿಫಲವಾಗಿದೆ → connection cooldown ಗಿಂತ model lockout ಅನ್ನು ಆದ್ಯತೆ ನೀಡಿ. - ಸ್ಥಿತಿ ಸ್ವಯಂ-ಚೇತರಿಸಿಕೊಳ್ಳಬೇಕು ಆದರೆ ಆಗುತ್ತಿಲ್ಲ → ಭವಿಷ್ಯದ ಟೈಮ್ಸ್ಟ್ಯಾಂಪ್ + ಅವಧಿ ಮೀರಿದ ಸ್ಥಿತಿಯನ್ನು ರಿಫ್ರೆಶ್ ಮಾಡುವ ಓದುವ ಮಾರ್ಗವನ್ನು ಪರಿಶೀಲಿಸಿ. ಶಾಶ್ವತ ಸ್ಥಿತಿಗಳಿಗೆ ಕೈಯಾರೆ ಬದಲಾವಣೆಗಳು ಅಗತ್ಯ. --- ## ರನ್ಟೈಮ್ ಸ್ಥಿತಿ — ಏಜೆಂಟ್ ತ್ವರಿತ ಉಲ್ಲೇಖ > `AGENTS.md` → "Resilience Runtime State" (PR #12743) ಇಂದ ಅಕ್ಷರಶಃ ಸರಿಸಲಾಗಿದೆ, ಆದ್ದರಿಂದ ಏಜೆಂಟ್ > ಮಾರ್ಗದರ್ಶಿಯು 40k ಸಂದರ್ಭ ಬಜೆಟ್ಗಿಂತ ಕೆಳಗೆ ಉಳಿಯುತ್ತದೆ. ಇದು ಮೇಲಿನ ವಿಭಾಗಗಳ ಸಂಕ್ಷಿಪ್ತ, > ಏಜೆಂಟ್-ಮುಖೀ ನೋಟವಾಗಿದೆ; ಸಂಖ್ಯಾತ್ಮಕ ವಿಭಾಗಗಳು ಸಂಪೂರ್ಣ ಉಲ್ಲೇಖವಾಗಿ ಉಳಿಯುತ್ತವೆ. OmniRoute ಮೂರು ಪರಸ್ಪರ ಸಂಬಂಧಿತ ಆದರೆ ಭಿನ್ನವಾದ ತಾತ್ಕಾಲಿಕ-ವಿಫಲತೆ ಕ್ರಮಗಳನ್ನು ಹೊಂದಿದೆ. ರೌಟಿಂಗ್ ನಡವಳಿಕೆಯನ್ನು ಡೀಬಗ್ ಮಾಡುವಾಗ ಅವುಗಳ ವ್ಯಾಪ್ತಿಯನ್ನು ಪ್ರತ್ಯೇಕವಾಗಿಡಿ. ಒಟ್ಟುನೋಟದ ನಕ್ಷೆಗಾಗಿ [3-ಪದರ ಸ್ಥೈರ್ಯ ರೇಖಾಚಿತ್ರ](../diagrams/exported/resilience-3layers.svg) (ಮೂಲ: [diagrams/resilience-3layers.mmd](../diagrams/resilience-3layers.mmd)) ನೋಡಿ. ### ಪ್ರೊವೈಡರ್ ಸರ್ಕ್ಯೂಟ್ ಬ್ರೇಕರ್ **ವ್ಯಾಪ್ತಿ**: ಇಡೀ ಪ್ರೊವೈಡರ್, ಉದಾ. `glm`, `openai`, `anthropic`. **ಉದ್ದೇಶ**: ಅಪ್ಸ್ಟ್ರೀಮ್/ಸೇವಾ ಮಟ್ಟದಲ್ಲಿ ಪದೇ ಪದೇ ವಿಫಲವಾಗುತ್ತಿರುವ ಪ್ರೊವೈಡರ್ಗೆ ಟ್ರಾಫಿಕ್ ಕಳುಹಿಸುವುದನ್ನು ನಿಲ್ಲಿಸುವುದು, ಇದರಿಂದ ಒಂದು ಅನಾರೋಗ್ಯಕರ ಪ್ರೊವೈಡರ್ ಪ್ರತಿ ವಿನಂತಿಯನ್ನು ನಿಧಾನಗೊಳಿಸುವುದಿಲ್ಲ. **ಅನುಷ್ಠಾನ**: - ಕೋರ್ ಕ್ಲಾಸ್: `src/shared/utils/circuitBreaker.ts` - ಚಾಟ್ ಗೇಟ್/ಎಕ್ಸಿಕ್ಯೂಶನ್ ವೈರಿಂಗ್: `src/sse/handlers/chatHelpers.ts`, `src/sse/handlers/chat.ts` - ರನ್ಟೈಮ್ ಸ್ಥಿತಿ API: `src/app/api/monitoring/health/route.ts` - ಹಂಚಿಕೊಂಡ ರ್ಯಾಪರ್ಗಳು: `open-sse/services/accountFallback.ts` - ಶೇಖರಿಸಲಾದ ಸ್ಥಿತಿ ಟೇಬಲ್: `domain_circuit_breakers` **ಸ್ಥಿತಿಗಳು** (4 — `src/shared/utils/circuitBreaker.ts`): - `CLOSED`: ಸಾಮಾನ್ಯ ಟ್ರಾಫಿಕ್ ಅನ್ನು ಅನುಮತಿಸಲಾಗಿದೆ. - `DEGRADED`: ಮುಂಚಿನ-ಎಚ್ಚರಿಕೆ ಬ್ಯಾಂಡ್ — ವಿಫಲತೆಗಳು ಡಿಗ್ರಡೇಶನ್ ಮಿತಿಯನ್ನು ದಾಟಿವೆ ಆದರೆ ಇನ್ನೂ ಬ್ರೇಕರ್ ಮಿತಿಯನ್ನು ದಾಟಿಲ್ಲ; ಟ್ರಾಫಿಕ್ ಇನ್ನೂ ಹರಿಯುತ್ತದೆ, ಡ್ಯಾಶ್ಬೋರ್ಡ್ಗಳು ಎಚ್ಚರಿಕೆಯನ್ನು ತೋರಿಸುತ್ತವೆ. ಮಾನ್ಯ ಸಂಪರ್ಕ ಪರೀಕ್ಷೆ ಅಥವಾ ಹೊಸ ವಿಫಲತೆಯಿಲ್ಲದ ಶಾಂತ ವಿಂಡೋ ಅದನ್ನು `CLOSED` ಗೆ ಹಿಂತಿರುಗಿಸುತ್ತದೆ (`docs/architecture/RESILIENCE_GUIDE.md` ನಲ್ಲಿ ವಿಂಡೋ ಇದೆ). - `OPEN`: ಪ್ರೊವೈಡರ್ ತಾತ್ಕಾಲಿಕವಾಗಿ ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ; ಕರೆದವರಿಗೆ ಪ್ರೊವೈಡರ್-ಸರ್ಕ್ಯೂಟ್-ತೆರೆದ ಪ್ರತಿಕ್ರಿಯೆ ಸಿಗುತ್ತದೆ ಅಥವಾ ಕಾಂಬೊ ರೌಟಿಂಗ್ ಬೇರೆ ಟಾರ್ಗೆಟ್ಗೆ ಸ್ಕಿಪ್ ಮಾಡುತ್ತದೆ. - `HALF_OPEN`: ಮರುಹೊಂದಿಸುವ ಸಮಯಮಿತಿ ಕಳೆದಿದೆ; ಪರೀಕ್ಷಾ ವಿನಂತಿಯನ್ನು ಅನುಮತಿಸಿ. ಯಶಸ್ಸು ಬ್ರೇಕರ್ ಅನ್ನು ಮುಚ್ಚುತ್ತದೆ, ವಿಫಲತೆಯು ಅದನ್ನು ಮತ್ತೆ ತೆರೆಯುತ್ತದೆ. **ಡೀಫಾಲ್ಟ್ಗಳು** (`open-sse/config/constants.ts` → `PROVIDER_PROFILES`, `src/lib/resilience/settings.ts` ನಲ್ಲಿರುವ `DEFAULT_RESILIENCE_SETTINGS.providerBreaker` ಮೂಲಕ ಬಳಸಲಾಗುತ್ತದೆ → `src/sse/handlers/chatHelpers.ts` ನಲ್ಲಿ `getCircuitBreaker(provider, …)`). ಇಡೀ-ಪ್ರೊವೈಡರ್ ಬ್ರೇಕರ್ `circuitBreakerThreshold` / `circuitBreakerReset` ಮೇಲೆ ಚಲಿಸುತ್ತದೆ: | ಪ್ರೊಫೈಲ್ | ಡಿಗ್ರೇಡ್ ಆಗುವ ಸ್ಥಾನ | ತೆರೆಯುವ ಸ್ಥಾನ (`circuitBreakerThreshold`) | ಮರುಹೊಂದಿಸುವುದು (`circuitBreakerReset`) | | -------- | ------------------: | ----------------------------------------: | -------------------------------------: | | OAuth | `5` | `8` | `60s` | | API key | `7` | `12` | `30s` | | Local | (ಲೆಕ್ಕಹಾಕಲಾದ) | `2` | `15s` | `PROVIDER_PROFILES` ಸಹ `providerFailureThreshold` (10/15/2), `providerFailureWindowMs` (15/30/5 ನಿಮಿಷ) ಮತ್ತು `providerCooldownMs` (5/10/1 ನಿಮಿಷ) ಅನ್ನು ವ್ಯಾಖ್ಯಾನಿಸುತ್ತದೆ: ಇವು **ಆಪ್ಟ್-ಇನ್ ಗ್ಲೋಬಲ್ Provider Cooldown ನ ವಿಂಡೋ ಗೇಟ್** ಅನ್ನು ಚಾಲಾಯಿಸುತ್ತವೆ (`PROVIDER_COOLDOWN_ENABLED`, ಡೀಫಾಲ್ಟ್ ಆಫ್) — `open-sse/services/providerCooldownTracker.ts` ನಲ್ಲಿನ ಪ್ರೊವೈಡರ್-ಮಟ್ಟದ ಎಂಟ್ರಿಯು `providerFailureWindowMs` ಒಳಗೆ `providerFailureThreshold` ವಿಫಲತೆಗಳ ನಂತರ ಮಾತ್ರ ಕೂಲಿಂಗ್ ಆಗುತ್ತಿದೆ ಎಂದು ಎಣಿಸಲಾಗುತ್ತದೆ, ಮತ್ತು ನಂತರ `providerCooldownMs` ಗಾಗಿ ಕೂಲ್ ಆಗುತ್ತದೆ. ಇವು ಲೈವ್ ಬ್ರೇಕರ್ನ ಮಿತಿಗಳಲ್ಲ — ಬ್ರೇಕರ್ ನಡವಳಿಕೆಯನ್ನು ನಿರೀಕ್ಷಿಸಿ ಅವುಗಳನ್ನು ಟ್ಯೂನ್ ಮಾಡಬೇಡಿ. ಪ್ರತಿ ಡೀಫಾಲ್ಟ್ ಅನ್ನು `OMNIROUTE_PROVIDER_BREAKER_*` ಮತ್ತು `OMNIROUTE_CIRCUIT_BREAKER_*` ಎನ್ವಿ ವೇರಿಯೇಬಲ್ಗಳ ಮೂಲಕ ಅಧಿಕ್ರಮಿಸಬಹುದು; ರನ್ಟೈಮ್-ನಿಖರ ಉಲ್ಲೇಖ ಟೇಬಲ್ `docs/architecture/RESILIENCE_GUIDE.md` ನಲ್ಲಿ ಇದೆ. ಪ್ರೊವೈಡರ್-ಮಟ್ಟದ ವಿಫಲತೆ ಸ್ಥಿತಿಗಳು ಮಾತ್ರ ಪ್ರೊವೈಡರ್ ಬ್ರೇಕರ್ ಅನ್ನು ಟ್ರಿಪ್ ಮಾಡಬೇಕು: ```ts (408, 500, 502, 503, 504); ``` ಹೆಚ್ಚಿನ `401`, `403`, ಅಥವಾ `429` ಸಂದರ್ಭಗಳಂತಹ ಸಾಮಾನ್ಯ ಖಾತೆ/ಕೀಲಿ/ಮಾಡೆಲ್ ದೋಷಗಳಿಗೆ ಇಡೀ-ಪ್ರೊವೈಡರ್ ಬ್ರೇಕರ್ ಅನ್ನು ಟ್ರಿಪ್ ಮಾಡಬೇಡಿ. ಅವು ಸಾಮಾನ್ಯವಾಗಿ connection cooldown ಅಥವಾ model lockout ಗೆ ಸೇರಿವೆ. ಸಾಮಾನ್ಯ API-ಕೀಲಿ ಪ್ರೊವೈಡರ್ `403` ಅನ್ನು ಟರ್ಮಿನಲ್ ಪ್ರೊವೈಡರ್/ಖಾತೆ ದೋಷವೆಂದು ವರ್ಗೀಕರಿಸದ ಹೊರತು ಚೇತರಿಸಿಕೊಳ್ಳಬಹುದಾದುದಾಗಿರಬೇಕು. ಬ್ರೇಕರ್ ಹಿನ್ನೆಲೆ ಟೈಮರ್ ಬಳಸದೆ, ಸೋಮಾರಿ ಚೇತರಿಕೆಯನ್ನು (lazy recovery) ಬಳಸುತ್ತದೆ. `OPEN` ಅವಧಿ ಮುಗಿದಾಗ, `getStatus()`, `canExecute()`, ಮತ್ತು `getRetryAfterMs()` ನಂತಹ ಓದುವಿಕೆಗಳು ಸ್ಥಿತಿಯನ್ನು `HALF_OPEN` ಗೆ ರಿಫ್ರೆಶ್ ಮಾಡುತ್ತವೆ, ಆದ್ದರಿಂದ ಡ್ಯಾಶ್ಬೋರ್ಡ್ಗಳು ಮತ್ತು ಕಾಂಬೊ ಅಭ್ಯರ್ಥಿ ನಿರ್ಮಾಪಕರು ಅವಧಿ ಮೀರಿದ ಪ್ರೊವೈಡರ್ ಅನ್ನು ಶಾಶ್ವತವಾಗಿ ಹೊರಗಿಡುತ್ತಲೇ ಇರುವುದಿಲ್ಲ. ### ಸಂಪರ್ಕ ಕೂಲ್ಡೌನ್ **ವ್ಯಾಪ್ತಿ**: ಒಂದು ಪ್ರೊವೈಡರ್ ಸಂಪರ್ಕ/ಖಾತೆ/ಕೀ. **ಉದ್ದೇಶ**: ಅದೇ ಪ್ರೊವೈಡರ್ಗಾಗಿ ಇತರ ಸಂಪರ್ಕಗಳು ವಿನಂತಿಗಳನ್ನು ಸೇವಿಸುತ್ತಲೇ ಇರಲು ಅವಕಾಶ ನೀಡುತ್ತಾ, ಒಂದು ಕೆಟ್ಟ ಕೀ/ಖಾತೆಯನ್ನು ತಾತ್ಕಾಲಿಕವಾಗಿ ಬಿಟ್ಟುಬಿಡುವುದು. **ಅನುಷ್ಠಾನ**: - ಬರಹ/ನವೀಕರಣ ಮಾರ್ಗ: `src/sse/services/auth.ts::markAccountUnavailable()` - ಖಾತೆ ಆಯ್ಕೆ/ಶೋಧನೆ: `src/sse/services/auth.ts::getProviderCredentials...` - ಕೂಲ್ಡೌನ್ ಲೆಕ್ಕಾಚಾರ: `open-sse/services/accountFallback.ts::checkFallbackError()` - ಸೆಟ್ಟಿಂಗ್ಗಳು: `src/lib/resilience/settings.ts` ಪ್ರೊವೈಡರ್ ಸಂಪರ್ಕಗಳ ಮೇಲಿನ ಪ್ರಮುಖ ಫೀಲ್ಡ್ಗಳು: ```ts rateLimitedUntil; testStatus: "unavailable"; lastError; lastErrorType; errorCode; backoffLevel; ``` ಖಾತೆ ಆಯ್ಕೆಯ ಸಮಯದಲ್ಲಿ, ಈ ಕೆಳಗಿನ ಸ್ಥಿತಿಯಿದ್ದಾಗ ಸಂಪರ್ಕವನ್ನು ಬಿಟ್ಟುಬಿಡಲಾಗುತ್ತದೆ: ```ts new Date(rateLimitedUntil).getTime() > Date.now(); ``` ಕೂಲ್ಡೌನ್ಗಳು ಸಹ ಸೋಮಾರಿಯಾಗಿವೆ: `rateLimitedUntil` ಹಿಂದಿನ ಸಮಯದಲ್ಲಿದ್ದಾಗ, ಸಂಪರ್ಕವು ಮತ್ತೆ ಅರ್ಹವಾಗುತ್ತದೆ. ಯಶಸ್ವಿ ಬಳಕೆಯ ನಂತರ, `clearAccountError()` `testStatus`, `rateLimitedUntil`, ದೋಷ ಫೀಲ್ಡ್ಗಳು ಮತ್ತು `backoffLevel` ಅನ್ನು ತೆರವುಗೊಳಿಸುತ್ತದೆ. ಡೀಫಾಲ್ಟ್ ಸಂಪರ್ಕ ಕೂಲ್ಡೌನ್ ನಡವಳಿಕೆ: - OAuth ಮೂಲ ಕೂಲ್ಡೌನ್: `5s`. - API-ಕೀ ಮೂಲ ಕೂಲ್ಡೌನ್: `3s`. - API-ಕೀ `429` ಲಭ್ಯವಿದ್ದಾಗ ಅಪ್ಸ್ಟ್ರೀಮ್ ಮರುಪ್ರಯತ್ನ ಸುಳಿವುಗಳಿಗೆ (`Retry-After`, ರೀಸೆಟ್ ಹೆಡರ್ಗಳು, ಅಥವಾ ಪಾರ್ಸ್ ಮಾಡಬಹುದಾದ ರೀಸೆಟ್ ಪಠ್ಯ) ಆದ್ಯತೆ ನೀಡಬೇಕು. - ಪುನರಾವರ್ತಿತ ಚೇತರಿಸಿಕೊಳ್ಳಬಹುದಾದ ವಿಫಲತೆಗಳು ಘಾತಾಂಕೀಯ ಬ್ಯಾಕ್ಆಫ್ ಅನ್ನು ಬಳಸುತ್ತವೆ: ```ts baseCooldownMs * 2 ** failureIndex; ``` ಆಂಟಿ-ಥಂಡರಿಂಗ್-ಹರ್ಡ್ ರಕ್ಷಣೆಯು (anti-thundering-herd guard) ಅದೇ ಸಂಪರ್ಕದ ಮೇಲಿನ ಏಕಕಾಲಿಕ ವಿಫಲತೆಗಳು ಕೂಲ್ಡೌನ್ ಅನ್ನು ಪದೇ ಪದೇ ವಿಸ್ತರಿಸುವುದನ್ನು ಅಥವಾ `backoffLevel` ಅನ್ನು ಎರಡು ಬಾರಿ ಹೆಚ್ಚಿಸುವುದನ್ನು ತಡೆಯುತ್ತದೆ. ಟರ್ಮಿನಲ್ ಸ್ಥಿತಿಗಳು ಕೂಲ್ಡೌನ್ಗಳಲ್ಲ. `banned`, `expired` (`EXPIRED_RETRY_MAX` ಮೂಲಕ N ಸೀಮಿತ ಮರುಪ್ರಯತ್ನಗಳ ನಂತರ ಮಾತ್ರ ಟರ್ಮಿನಲ್ ಆಗುತ್ತದೆ), ಮತ್ತು `credits_exhausted` ಗಳು ರುಜುವಾತುಗಳು/ಸೆಟ್ಟಿಂಗ್ಗಳು ಬದಲಾಗುವವರೆಗೆ ಅಥವಾ ಆಪರೇಟರ್ ಅವುಗಳನ್ನು ರೀಸೆಟ್ ಮಾಡುವವರೆಗೆ ಲಭ್ಯವಿಲ್ಲದಂತೆಯೇ ಉಳಿಯುವುದು ಉದ್ದೇಶ. ತಾತ್ಕಾಲಿಕ ಕೂಲ್ಡೌನ್ ಸ್ಥಿತಿಯೊಂದಿಗೆ ಟರ್ಮಿನಲ್ ಸ್ಥಿತಿಗಳನ್ನು ಬದಲಾಯಿಸಬೇಡಿ. ### ಮಾದರಿ ಲಾಕ್ಔಟ್ **ವ್ಯಾಪ್ತಿ**: ಪ್ರೊವೈಡರ್ + ಸಂಪರ್ಕ + ಮಾದರಿ. **ಉದ್ದೇಶ**: ಆ ಸಂಪರ್ಕಕ್ಕೆ ಕೇವಲ ಒಂದು ಮಾದರಿ ಲಭ್ಯವಿಲ್ಲದಿದ್ದಾಗ ಅಥವಾ ಕೋಟಾ-ಸೀಮಿತವಾಗಿದ್ದಾಗ, ಇಡೀ ಸಂಪರ್ಕವನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸುವುದನ್ನು ತಪ್ಪಿಸುವುದು. ಉದಾಹರಣೆಗಳು: - ಪ್ರತಿ-ಮಾದರಿ ಕೋಟಾ ಪ್ರೊವೈಡರ್ಗಳು `429` ಹಿಂತಿರುಗಿಸುವುದು. - ಒಂದು ಕಾಣೆಯಾದ ಮಾದರಿಗಾಗಿ ಸ್ಥಳೀಯ ಪ್ರೊವೈಡರ್ಗಳು `404` ಹಿಂತಿರುಗಿಸುವುದು. - ಆಯ್ದ Grok ಮೋಡ್ಗಳಂತಹ ಪ್ರೊವೈಡರ್-ನಿರ್ದಿಷ್ಟ ಮೋಡ್/ಮಾದರಿ ಅನುಮತಿ ವಿಫಲತೆಗಳು. ಮಾದರಿ ಲಾಕ್ಔಟ್ `open-sse/services/accountFallback.ts` ನಲ್ಲಿ ಇದೆ ಮತ್ತು ಅದೇ ಸಂಪರ್ಕವು ಇತರ ಮಾದರಿಗಳಿಗೆ ಸೇವೆ ಸಲ್ಲಿಸುತ್ತಲೇ ಇರಲು ಅನುಮತಿಸುತ್ತದೆ. ### ಡಿಬಗ್ಗಿಂಗ್ ಮಾರ್ಗದರ್ಶನ - ಪ್ರೊವೈಡರ್ಗಾಗಿ ಎಲ್ಲಾ ಕೀಗಳನ್ನು ಬಿಟ್ಟುಬಿಡಲಾಗಿದ್ದರೆ, ಪ್ರೊವೈಡರ್ ಬ್ರೇಕರ್ ಸ್ಥಿತಿ ಮತ್ತು ಪ್ರತಿ ಸಂಪರ್ಕದ `rateLimitedUntil`/`testStatus` ಎರಡನ್ನೂ ಪರಿಶೀಲಿಸಿ. - ರೀಸೆಟ್ ವಿಂಡೋ ನಂತರ ಪ್ರೊವೈಡರ್ ಶಾಶ್ವತವಾಗಿ ಹೊರಗಿಡಲಾಗಿರುವಂತೆ ತೋಚಿದರೆ, `getStatus()`/`canExecute()` ಬಳಸುವ ಬದಲು ಕೋಡ್ ಕಚ್ಚಾ `state` ಅನ್ನು ಓದುತ್ತಿದೆಯೇ ಎಂದು ಪರಿಶೀಲಿಸಿ. - ಒಂದು ಪ್ರೊವೈಡರ್ ಕೀ ವಿಫಲವಾದರೆ ಆದರೆ ಇತರವು ಕೆಲಸ ಮಾಡಬೇಕಾದರೆ, ಪ್ರೊವೈಡರ್ ಬ್ರೇಕರ್ಗಿಂತ ಸಂಪರ್ಕ ಕೂಲ್ಡೌನ್ ಅನ್ನು ಆದ್ಯತೆ ನೀಡಿ. - ಕೇವಲ ಒಂದು ಮಾದರಿ ವಿಫಲವಾದರೆ, ಸಂಪರ್ಕ ಕೂಲ್ಡೌನ್ಗಿಂತ ಮಾದರಿ ಲಾಕ್ಔಟ್ ಅನ್ನು ಆದ್ಯತೆ ನೀಡಿ. - ಒಂದು ಸ್ಥಿತಿ ತಾನಾಗಿ ಚೇತರಿಸಿಕೊಳ್ಳಬೇಕಾದರೆ, ಅದು ಭವಿಷ್ಯದ ಟೈಮ್ಸ್ಟ್ಯಾಂಪ್/ರೀಸೆಟ್ ಟೈಮ್ಔಟ್ ಮತ್ತು ಅವಧಿ ಮೀರಿದ ಸ್ಥಿತಿಯನ್ನು ರಿಫ್ರೆಶ್ ಮಾಡುವ ಓದುವ ಮಾರ್ಗವನ್ನು ಹೊಂದಿರಬೇಕು. ಶಾಶ್ವತ ಸ್ಥಿತಿಗಳಿಗೆ ಹಸ್ತಚಾಲಿತ ರುಜುವಾತು ಅಥವಾ ಕಾನ್ಫಿಗ್ ಬದಲಾವಣೆಗಳು ಅಗತ್ಯವಿರುತ್ತವೆ. --- ## TLS ಫಿಂಗರ್ಪ್ರಿಂಟಿಂಗ್ & ಸ್ಟೆಲ್ತ್ ಪ್ರೊವೈಡರ್-ನಿರ್ದಿಷ್ಟ ಸ್ಟೆಲ್ತ್ (JA3/JA4, CCH, ಅಸ್ಪಷ್ಟೀಕರಣ) ಪ್ರತ್ಯೇಕವಾಗಿ ದಾಖಲೀಕರಿಸಲಾಗಿದೆ — `docs/security/STEALTH_GUIDE.md` ಅನ್ನು ನೋಡಿ (git; `/docs` ಗೆ ಕಂಪೈಲ್ ಮಾಡಲಾಗಿಲ್ಲ). --- ## ಸ್ಥಿತಿಸ್ಥಾಪಕತ್ವ ಪರೀಕ್ಷೆ (ಹಂತ 8 · ಬ್ಲಾಕ್ C) ಸ್ಥಿತಿಸ್ಥಾಪಕತ್ವ ತರ್ಕದ ಯೂನಿಟ್ ಟೆಸ್ಟ್ಗಳಿಗೆ ಹೆಚ್ಚುವರಿಯಾಗಿ, ಮೂರು ಟೆಸ್ಟ್ಗಳು ನಿಜವಾದ ಒತ್ತಡ/ವೈಫಲ್ಯ ಪರಿಸ್ಥಿತಿಗಳಲ್ಲಿ ರನ್ಟೈಮ್ ಅನ್ನು ಚಲಾಯಿಸುತ್ತವೆ (ಎಲ್ಲವೂ integration/nightly — ಯಾವುದೂ PR ಗಳನ್ನು ನಿರ್ಬಂಧಿಸುವುದಿಲ್ಲ): | ಟೆಸ್ಟ್ | ಏನು | ರನ್ | | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | | Chaos | ನಕಲಿ-ಅಪ್ಸ್ಟ್ರೀಮ್ ನೋಡ್ ನಿಜವಾದ latency/reset/timeout/503 ಅನ್ನು ಇಂಜೆಕ್ಟ್ ಮಾಡುತ್ತದೆ; ಸರ್ಕ್ಯೂಟ್ ಬ್ರೇಕರ್ ತೆರೆಯುತ್ತದೆ/ಮರುಪಡೆಯುತ್ತದೆ ಮತ್ತು `checkFallbackError` 503 ಅನ್ನು ಮರುಪಡೆಯಬಹುದಾದ ಫಾಲ್ಬ್ಯಾಕ್ ಎಂದು ವರ್ಗೀಕರಿಸುತ್ತದೆ ಎಂದು ಮೌಲ್ಯೀಕರಿಸುತ್ತದೆ. | `RUN_CHAOS_INT=1 npm run test:chaos` | | Heap-growth | `--expose-gc` ಅಡಿಯಲ್ಲಿ `createSSEStream` ಗೆ ಸುಮಾರು 500 ಸ್ಟ್ರೀಮ್ಗಳು; ಹೀಪ್ ಮಿತಿಯನ್ನು ಮೀರಿ ಬೆಳದರೆ ವಿಫಲವಾಗುತ್ತದೆ (OOM ಗಾರ್ಡ್ #3069). | `npm run test:heap` | | k6 soak | `/api/monitoring/health` ವಿರುದ್ಧ ನಿರಂತರ ಲೋಡ್; p95/ದೋಷ ಮಿತಿಗಳು. | `k6 run tests/load/k6-soak.js` (nightly) | `.github/workflows/nightly-resilience.yml` ಮೂಲಕ ಸಂಯೋಜಿಸಲಾಗಿದೆ (cron + dispatch). ಡೀಫಾಲ್ಟ್ `test:integration` ನಲ್ಲಿ, chaos ಮತ್ತು heap ಸ್ವಯಂ-ಸ್ಕಿಪ್ ಆಗುತ್ತವೆ (`RUN_CHAOS_INT`/`--expose-gc` ಇಲ್ಲದೆ). --- ## ಇದನ್ನೂ ನೋಡಿ - [ಆರ್ಕಿಟೆಕ್ಚರ್ ಮಾರ್ಗದರ್ಶಿ](./ARCHITECTURE.md) — ಸಿಸ್ಟಮ್ ಆರ್ಕಿಟೆಕ್ಚರ್ ಮತ್ತು ಆಂತರಿಕಗಳು - [ಬಳಕೆದಾರ ಮಾರ್ಗದರ್ಶಿ](../guides/USER_GUIDE.md) — ಪ್ರೊವೈಡರ್ಗಳು, ಕಾಂಬೊಗಳು, CLI ಏಕೀಕರಣ - [Auto-Combo ಎಂಜಿನ್](../routing/AUTO-COMBO.md) — 16-ಅಂಶದ ಸ್ಕೋರಿಂಗ್, ಮೋಡ್ ಪ್ಯಾಕ್ಗಳು