# Subscription-first routing (Hausa) 🌐 **Languages:** 🇺🇸 [English](../../../../routing/SUBSCRIPTION_LADDER.md) · 🇪🇹 [am](../../../am/docs/routing/SUBSCRIPTION_LADDER.md) · 🇸🇦 [ar](../../../ar/docs/routing/SUBSCRIPTION_LADDER.md) · 🇦🇿 [az](../../../az/docs/routing/SUBSCRIPTION_LADDER.md) · 🇧🇬 [bg](../../../bg/docs/routing/SUBSCRIPTION_LADDER.md) · 🇧🇩 [bn](../../../bn/docs/routing/SUBSCRIPTION_LADDER.md) · 🇧🇦 [bs](../../../bs/docs/routing/SUBSCRIPTION_LADDER.md) · 🇨🇿 [cs](../../../cs/docs/routing/SUBSCRIPTION_LADDER.md) · 🇩🇰 [da](../../../da/docs/routing/SUBSCRIPTION_LADDER.md) · 🇩🇪 [de](../../../de/docs/routing/SUBSCRIPTION_LADDER.md) · 🇬🇷 [el](../../../el/docs/routing/SUBSCRIPTION_LADDER.md) · 🇪🇸 [es](../../../es/docs/routing/SUBSCRIPTION_LADDER.md) · 🇪🇪 [et](../../../et/docs/routing/SUBSCRIPTION_LADDER.md) · 🇮🇷 [fa](../../../fa/docs/routing/SUBSCRIPTION_LADDER.md) · 🇫🇮 [fi](../../../fi/docs/routing/SUBSCRIPTION_LADDER.md) · 🇫🇷 [fr](../../../fr/docs/routing/SUBSCRIPTION_LADDER.md) · 🇮🇪 [ga](../../../ga/docs/routing/SUBSCRIPTION_LADDER.md) · 🇮🇳 [gu](../../../gu/docs/routing/SUBSCRIPTION_LADDER.md) · 🇮🇱 [he](../../../he/docs/routing/SUBSCRIPTION_LADDER.md) · 🇮🇳 [hi](../../../hi/docs/routing/SUBSCRIPTION_LADDER.md) · 🇭🇷 [hr](../../../hr/docs/routing/SUBSCRIPTION_LADDER.md) · 🇭🇺 [hu](../../../hu/docs/routing/SUBSCRIPTION_LADDER.md) · 🇦🇲 [hy](../../../hy/docs/routing/SUBSCRIPTION_LADDER.md) · 🇮🇩 [id](../../../id/docs/routing/SUBSCRIPTION_LADDER.md) · 🇳🇬 [ig](../../../ig/docs/routing/SUBSCRIPTION_LADDER.md) · 🇮🇹 [it](../../../it/docs/routing/SUBSCRIPTION_LADDER.md) · 🇯🇵 [ja](../../../ja/docs/routing/SUBSCRIPTION_LADDER.md) · 🇬🇪 [ka](../../../ka/docs/routing/SUBSCRIPTION_LADDER.md) · 🇰🇭 [km](../../../km/docs/routing/SUBSCRIPTION_LADDER.md) · 🇮🇳 [kn](../../../kn/docs/routing/SUBSCRIPTION_LADDER.md) · 🇰🇷 [ko](../../../ko/docs/routing/SUBSCRIPTION_LADDER.md) · 🇱🇹 [lt](../../../lt/docs/routing/SUBSCRIPTION_LADDER.md) · 🇱🇻 [lv](../../../lv/docs/routing/SUBSCRIPTION_LADDER.md) · 🇮🇳 [ml](../../../ml/docs/routing/SUBSCRIPTION_LADDER.md) · 🇮🇳 [mr](../../../mr/docs/routing/SUBSCRIPTION_LADDER.md) · 🇲🇾 [ms](../../../ms/docs/routing/SUBSCRIPTION_LADDER.md) · 🇲🇹 [mt](../../../mt/docs/routing/SUBSCRIPTION_LADDER.md) · 🇲🇲 [my](../../../my/docs/routing/SUBSCRIPTION_LADDER.md) · 🇳🇵 [ne](../../../ne/docs/routing/SUBSCRIPTION_LADDER.md) · 🇳🇱 [nl](../../../nl/docs/routing/SUBSCRIPTION_LADDER.md) · 🇳🇴 [no](../../../no/docs/routing/SUBSCRIPTION_LADDER.md) · 🇮🇳 [or](../../../or/docs/routing/SUBSCRIPTION_LADDER.md) · 🇮🇳 [pa](../../../pa/docs/routing/SUBSCRIPTION_LADDER.md) · 🇵🇭 [phi](../../../phi/docs/routing/SUBSCRIPTION_LADDER.md) · 🇵🇱 [pl](../../../pl/docs/routing/SUBSCRIPTION_LADDER.md) · 🇵🇹 [pt](../../../pt/docs/routing/SUBSCRIPTION_LADDER.md) · 🇧🇷 [pt-BR](../../../pt-BR/docs/routing/SUBSCRIPTION_LADDER.md) · 🇷🇴 [ro](../../../ro/docs/routing/SUBSCRIPTION_LADDER.md) · 🇷🇺 [ru](../../../ru/docs/routing/SUBSCRIPTION_LADDER.md) · 🇱🇰 [si](../../../si/docs/routing/SUBSCRIPTION_LADDER.md) · 🇸🇰 [sk](../../../sk/docs/routing/SUBSCRIPTION_LADDER.md) · 🇸🇮 [sl](../../../sl/docs/routing/SUBSCRIPTION_LADDER.md) · 🇷🇸 [sr](../../../sr/docs/routing/SUBSCRIPTION_LADDER.md) · 🇸🇪 [sv](../../../sv/docs/routing/SUBSCRIPTION_LADDER.md) · 🇰🇪 [sw](../../../sw/docs/routing/SUBSCRIPTION_LADDER.md) · 🇮🇳 [ta](../../../ta/docs/routing/SUBSCRIPTION_LADDER.md) · 🇮🇳 [te](../../../te/docs/routing/SUBSCRIPTION_LADDER.md) · 🇹🇭 [th](../../../th/docs/routing/SUBSCRIPTION_LADDER.md) · 🇹🇷 [tr](../../../tr/docs/routing/SUBSCRIPTION_LADDER.md) · 🇺🇦 [uk-UA](../../../uk-UA/docs/routing/SUBSCRIPTION_LADDER.md) · 🇵🇰 [ur](../../../ur/docs/routing/SUBSCRIPTION_LADDER.md) · 🇺🇿 [uz](../../../uz/docs/routing/SUBSCRIPTION_LADDER.md) · 🇻🇳 [vi](../../../vi/docs/routing/SUBSCRIPTION_LADDER.md) · 🇳🇬 [yo](../../../yo/docs/routing/SUBSCRIPTION_LADDER.md) · 🇨🇳 [zh-CN](../../../zh-CN/docs/routing/SUBSCRIPTION_LADDER.md) · 🇹🇼 [zh-TW](../../../zh-TW/docs/routing/SUBSCRIPTION_LADDER.md) --- > Sabbin ids guda biyu na `auto/*` — `auto/subscription` da `auto/thrifty`. Dukansu sai an zaɓi amfani da su ta hanyar > nema: babu abin da zai bi ta cikinsu sai idan mai kira ya nemi id ɗin da suna, kuma babu > wani pool, strategy, ko default da yake canzawa. ## Dalilin samuwar wannan OmniRoute ya riga ya amsa tambayoyi biyu game da farashi, amma babu ɗayansu da yake amsa tambayar da yawancin masu gudanarwa suke yi. | Tsarin da yake akwai | Abin da yake amsawa | | -------------------------------------------------------- | ------------------------------------------------- | | `hidePaidModels` (`autoCombo/paidModelFilter.ts`) | "an jera wannan model a matsayin kyauta?" | | `freeAccessPolicy: "strict"` (`strictZeroCostFilter.ts`) | "wannan connection zai iya cajina a kowane hali?" | | `quotaPreflight` (`combo/quotaExhaustionCutoff.ts`) | "wannan connection ya kusa kai iyakarsa?" | | `budgetCap` / `budgetFallback` (`autoCombo/engine.ts`) | "ƙayyade kashe kuɗi, koma zuwa mafi arha" | Duk wani tsarin da ke amfani da kyauta kawai **yana rufewa idan ya gaza** — idan free pool ya ƙare, zai zama pool mara komai, ba zai taɓa haura zuwa zaɓi mai kuɗi ba — kuma duk wani tsarin ɓangaren biyan kuɗi bai bambanta matakai ba. Babu ɗayansu da yake amsa: > "Yi amfani da quota ɗin da na riga na biya. Idan ya ƙare, ko dai a tsaya, ko a haura mataki ɗaya bayan ɗaya ta cikin > zaɓuɓɓukan biyan kuɗi mafi arha — sannan a dawo da zarar quota ɗin ya sake farawa." ## Billing halayyar connection ce, ba ta model ba `classifyTier()` (`open-sse/services/tierResolver.ts`) yana amfani da `(provider, model)` a matsayin maɓalli, sannan ya dawo da `free | cheap | premium` daga farashin catalog. Amma ko request zai haifar da ƙarin kuɗi ya danganta ne da **connection ɗin da ya aiwatar da shi**: model iri ɗaya yana cikin plan ba tare da ƙarin kuɗi ba ta hanyar Claude Code OAuth connection, amma ana cajin kowane token idan an yi amfani da API-key connection. `provider_connections.auth_type` ba ingantaccen wakili ba ne a kowane ɓangare — akwai OAuth connections masu cajin amfani, haka kuma akwai API-key connections da suke cikin plan ba tare da ƙarin kuɗi ba (Copilot seat token ba API key mai cajin amfani ba ne). Don haka billing class yana fitowa ne daga **catalog da aka tsara da hannu**, `open-sse/config/connectionBillingCatalog.ts`, wanda aka saita da hannu bisa sharuɗɗan da kowane provider ya wallafa — irin tsarin da `FreeModelBudget.hardStopGuaranteed` ya riga ya kafa don free models. ```ts type ConnectionBillingClass = "subscription" | "metered" | "keyless" | "unknown"; type ConnectionOverageBehavior = "hard-stop" | "meters-to-paid" | "unknown"; ``` Tsarin tantancewa (`autoCombo/connectionBilling.ts`): synthetic no-auth sentinel → `keyless`; catalog entry da ya dace da provider **da kuma** `authType`; provider-wide entry; in ba haka ba `unknown`. **Wanda ba a tsara a catalog ba ba kyauta ba ne** — ana ɗaukar `unknown` a matsayin `metered` a ko’ina, don haka provider da aka ƙara gobe zai fara ne a wajen subscription rung kuma dole ne a saka shi cikin catalog da gangan. ## Tsarin rung Akwai rungs guda biyar bisa tsarin haura. Bambancinsu ya wuce farashi kawai — kowannensu yana da **nasa** alamar ƙarewa, shi ya sa wannan ba kawai tsarin jera abubuwa ba ne. | # | Rung | Abubuwan da ke cikinsa | Lokacin da ya ƙare | | --- | -------------- | -------------------------------------------------- | ---------------------------------- | | 0 | `subscription` | `billing: "subscription"` da aka tsara a catalog | quota window ya kai cutoff ko ƙasa | | 1 | `keyless` | synthetic no-auth path | connection cooldown / breaker | | 2 | `free` | metered connection, `classifyTier() === "free"` | free allowance ya ƙare | | 3 | `cheap` | metered connection, `classifyTier() === "cheap"` | an cinye per-rung budget | | 4 | `premium` | metered connection, `classifyTier() === "premium"` | an cinye per-rung budget | Rungs 0-2 suna ƙarewa ne bisa **quota**, wanda ake iya gani kuma tuni ana bibiyarsa. Rungs 3-4 ba su da quota — paid connection zai ci gaba da aiki har abada — don haka alamar ƙarewa mai ma’ana kaɗai gare su ita ce **budget** na kowane rung. Idan babu shi, "haura idan cheap ya ƙare" ba shi da abin da zai kunna shi. ## `auto/subscription` — gaza a rufe Pool = mataki na 0 kawai, an takaita shi ga haɗe-haɗen da wuce iyakarsu yake da rubutacciyar manufar `hard-stop`, kuma aka tabbatar kai tsaye cewa kowannensu yana da isasshen saura a ƙayyadadden kaso. Ana cire duk abin da bai fito fili ba: mai samarwa da ba a tantance ba, karatun ƙayyadadden kaso da ba za a iya tabbatarwa ba, tsohon karatu, ko wuce iyaka da ake lissafawa a matsayin abin biya. Pool mara komai shi ne amsar da **aka nufa**, ba matsala ba ce — hanyar pool mara komai da mai kira yake da ita tana mayar da shi kuskure bayyananne maimakon komawa a ɓoye zuwa zaɓin da za a biya kuɗi. Wannan shi ne cikakken alƙawarin id ɗin. Da gangan `keyless` **bai** cancanta ba: wannan rukuni yana nufin "tsarin da nake biya", don haka backend marar buƙatar tantancewa bai dace da shi ba. Yi amfani da `auto/thrifty` (ko `auto/best-free`) don wannan. ### Tsaron haɗi Ba koyaushe ake ɗaure ɗan takara da haɗi guda ɗaya ba — ɗan takara na ma'ana yana ɗauke da jerin izini na `allowedConnectionIds`, sannan daga baya, a lokacin aikawa, `open-sse/services/combo/autoStrategy.ts` ne yake zaɓar asusun da za a yi amfani da shi a zahiri. Saboda haka, rukunan biyu suna tabbatar da **kowane haɗi ɗaya bayan ɗaya** kuma suna sake rubuta `allowedConnectionIds` zuwa ainihin ƙaramin rukunin da ya tsira — ba cikakken jerin asali ba, kuma ba wani mamba guda da aka zaɓa barkatai ba. Saboda `autoStrategy.ts` tuni yana tilasta wannan array a matsayin tsayayyen jerin izini, sake rubuta shi a nan yana sa "wanda aka tabbatar" da "wanda aka yi amfani da shi a zahiri" su zama rukuni ɗaya ta hanyar tsarin gini. Wannan shi ne invariant iri ɗaya, da kuma dalili iri ɗaya, kamar na [STRICT_ZERO_COST](./STRICT_ZERO_COST.md). ## `auto/thrifty` — haura mataki ɗaya a lokaci guda Pool = duk matakan, an jera su bisa index na mataki, tare da cire ƴan takarar da suka ƙare daga shiga. Har yanzu injin `auto` yana ba da maki **a cikin** pool ɗin da ya tsira: tsani ne yake yanke shawarar waɗanne matakai za su shiga aiki, ba da maki kuma yana yanke shawarar wane ɗan takara zai yi nasara a cikinsu. Jerin yana da daidaito a cikin kowane mataki, don haka wannan overlay ba ya sake jujjuya tsarin fifikon da mai ba da maki ya tsara. Wannan overlay ne na tsarawa + tacewa, **ba** sabon dispatcher ba ne: speculative loop na `combo.ts` tuni yana bi ta kan targets bisa jeri kuma yana wucewa zuwa na gaba idan an gaza, don haka ƙarewar albarkatu a lokacin aiki da preflight bai gano ba har yanzu tana haifar da haurawa zuwa mataki na gaba a cikin request ɗin nan ɗaya. Inda `auto/subscription` yake gaza a **rufe**, `auto/thrifty` yana gaza a **buɗe**: har yanzu za a fara gwada haɗin da ke cikin tsarin biyan kuɗi ko da babu ingantaccen karatun ƙayyadadden kaso. Gwada shi ba ya cin kuɗi, kuma idan aka gano cewa ya ƙare, hanyar wucewa kan gazawa za ta isa mataki na gaba ko ta yaya — amma ƙin gwada shi zai aika request ɗin zuwa mataki mai kuɗi saboda rashin telemetry, wato ainihin sakamakon da aka ƙirƙiri wannan rukuni domin kauce masa. ## Komawa tsarin bayan sake saiti Dole abubuwa uku masu zaman kansu su ƙare kafin routing ya koma mataki na 0. Gyara ɗaya kawai zai bar tsanin a makale a matakan biyan kuɗi na dogon lokaci bayan an sake cika tsarin. 1. **Cache na matsayin ƙayyadadden kaso** — `freeAccessQuota.ts` yana yin cache ga kowane `(provider, connection)` da TTL na 180s. Shigar cache da `resetAt` nata ya riga ya wuce tana bayyana taga da ba ta wanzu yanzu, don haka yanzu ana ɗaukarta tsohuwa **ba tare da la'akari da shekarunta ba** kuma hakan yana tilasta sabuntawa. Idan babu wannan, tsarin da aka sake cikawa da tsakar dare zai ci gaba da nuna cewa ya ƙare har sai TTL ya ƙare da kansa. 2. **Matsayin tsanin kansa** — babu shi, bisa ƙira. Ana sake lissafa cancantar mataki daga matsayin ƙayyadadden kaso kai tsaye a duk lokacin gina pool; babu wani rikodin "a halin yanzu muna mataki na 3" da aka adana wanda zai iya wuce lokacin sake saiti ya kuma makale routing. 3. **Lokacin dakatar da haɗi** — 429 da ya nuna ƙarewa yana saita `rateLimitedUntil` daga exponential backoff, wanda ga haɗin tsari zai iya wuce ainihin lokacin sake saiti. `clampCooldownToReset()` (`subscriptionLadder.ts`) yana taƙaita lokacin dakatarwa zuwa ainihin lokacin sake saiti na upstream kuma ba zai taɓa tsawaita shi ba. **An aiwatar da shi kuma an gwada shi amma har yanzu ba a haɗa shi ba**: ana invalidating cache na ƙayyadadden kaso a cikin `src/sse/services/auth.ts` _kafin_ a rubuta kowane lokacin dakatarwa, don haka dole ne a kama `resetAt` da wuri a cikin wannan function — canji ne ga resilience hot path da ya dace da nasa PR da aka yi wa bita. Har zuwa lokacin, sake shiga zai jira lokacin dakatar da haɗin ya ƙare (wanda tuni ya fi son alamun `Retry-After` na upstream idan mai samarwa ya aika su). ### Hana kai-komo Ana sake shigar da matakin da aka sake saita yanzu ne kawai idan ya haura `reentryMinRemainingPercent` (tsoho 5), yayin da haɗin da tuni yake aiki sai dai kawai ya kasance sama da `exitCutoffPercent` (tsoho 2, daidai da `quotaPreflight.defaultThresholdPercent`). Tazarar ita ce hysteresis band — idan babu ita, haɗin da yake kai-komo kusa da iyakar yankewa zai riƙa sauyawa tsakanin matakai a requests masu jere. ## Kanfigareshan Don daidaitawa kawai. Da gangan **babu** tutar `enabled`: maɓallin da zai iya kashe waɗannan zai bar `auto/subscription` yana ci gaba da samar da dukkan tarin a ɓoye — har da samfuran biya — ƙarƙashin sunan da ke alƙawarin akasin haka. ```jsonc { "subscriptionLadder": { "exitCutoffPercent": 2, "reentryMinRemainingPercent": 5, "rungBudgetUsd": { "cheap": 5.0, "premium": 0 }, // 0 yana kashe matakin gaba ɗaya }, } ``` Toshewa bisa kasafin kuɗi ba ya aiki har sai an haɗa mai warware bayanan kashe kuɗi: idan babu bayanan lissafi, ana jera matakin biya amma ba a taɓa toshe shi ba. Tun daga v3.8.51, tsarin yana karɓar saitin `rungBudgetUsd` amma har yanzu BA a tilasta amfani da shi ba — ɗauke shi a matsayin kanfigareshan da aka tanada, ba a matsayin iyakar kashe kuɗi mai aiki ba. Jera matakai, ƙarewa bisa ƙayyadadden kaso, da sake shiga bayan sake saiti duk suna aiki ba tare da shi ba. ## Haɗawa `subscription` da `thrifty` ƙimomin `AutoTier` ne, don haka suna haɗuwa da kowane rukuni: `auto/coding:thrifty`, `auto/reasoning:subscription`, da sauransu. Ana tallata tsayayyun ids guda biyu (`auto/subscription`, `auto/thrifty`) a cikin `/v1/models` da dashboard. Babu ɗaya daga cikin ids ɗin da yake matakin biya, don haka `isPaidTierAutoId()` yana mayar da `false` ga dukansu, kuma `auto/subscription` yana tsira daga `hidePaidModels`. ## Inda lambar take | Abin da ya shafa | Fayil | | ----------------------------------- | --------------------------------------------------- | | Zaɓaɓɓun bayanan caji | `open-sse/config/connectionBillingCatalog.ts` | | Mai rarrabewa | `open-sse/services/autoCombo/connectionBilling.ts` | | Matakai, rukuni biyun, sake shiga | `open-sse/services/autoCombo/subscriptionLadder.ts` | | Haɗawa cikin tarin zaɓuɓɓuka | `open-sse/services/autoCombo/virtualFactory.ts` | | Tsufar cache mai lura da sake saiti | `open-sse/services/autoCombo/freeAccessQuota.ts` | | Fuskar mataki | `open-sse/services/autoCombo/suffixComposition.ts` | | ids da ake tallatawa | `open-sse/services/autoCombo/builtinCatalog.ts` | | Gwaje-gwaje | `tests/unit/autoCombo/subscription-ladder.test.ts` |