mirror of
https://gitcode.com/JianFeeeee/ModelRouter.git
synced 2026-09-19 16:39:15 +00:00
Report: an allowance-metered source (sensenova) had its deepseek model sitting at pref -10 while the WebUI showed zero failures. All three numbers were accurate, and they exposed three compounding problems. 1. Quota exhaustion cost the SAME score as a real failure. RecordQuotaExhausted intentionally avoids failCount (an exhausted allowance is not a fault), so the UI showed fails=0 / cooling=false — yet it deducted the full prefFailStep (5). For a metered source, running out of budget is an everyday event, so the score drifted deep negative with no visible cause. Now quota and 429 events cost prefQuotaStep (1): the cooldown already keeps the slot out of rotation until the window resets, the score only needs a mild preference for slots with budget. 2. Recovery was 5:1 asymmetric. A failure cost -5 but a success only +1, so a slot at -10 needed ten consecutive successes just to reach neutral — which it could never get, because a low score makes the scheduler not pick it in the first place (starvation). Success now rewards prefSuccessStep (2): recovery from -10 needs five successes, while a real failure still outweighs one. 3. No idle decay. A penalised slot kept its negative score forever once it stopped being selected. Pref() now applies lazy decay: after prefDecayAfter (2 min) of no outcome, the score drifts one step back toward 0 per interval (never past 0, never touches positive scores). Applied in Pref() and TryProbe(), so a naturally-recovered idle slot is schedulable again without needing a probe. The failure penalty itself is unchanged (prefFailStep=5), so genuinely broken upstreams are still marked as clearly worse than healthy ones. Tests: quota penalty lighter than failure; 5 quota resets stay well above the floor with failCount untouched; 429 is quota-class; recovery from -10 needs <=5; idle decay rehabilitates a written-off slot, stops at 0, and never drags a positive score; decay repeatedly lifts a slot off the prefMin floor. Updated the two pre-existing tests that asserted the old -5/129 +1 values.