Files
OmniRoute/src/lib/db
Markus Hartung c9daf99e37 fix(combo): clear LKGP pin when its target fails, not only set it on success (#10034)
setLKGP() was only ever called on success — nothing invalidated a "last
known good provider" pin once that provider started failing, so a
*separate* subsequent request kept re-selecting the same just-failed
target via applyStrategyOrdering.ts's LKGP reordering.

Live incident: an OpenClaw request to combo "default" (routerStrategy:
lkgp) got a real reasoning + apply_patch tool call from
opencode-zen/big-pickle, then 3 separate follow-up requests over the
next ~2 minutes each independently re-selected the same big-pickle
target and each timed out with "504 Stream produced no non-ping SSE
event within 95000ms" before the client gave up — instead of failing
over to any of the combo's other 12 models.

Root cause confirmed via code read: circuit breaker and model lockout
deliberately don't react to this failure class (isStreamReadinessFailureErrorBody
exempts STREAM_READINESS_TIMEOUT/combo_target_timeout 504s from tripping
the provider breaker, and REQUEST_SCOPED_UPSTREAM_ERROR_CODES suppresses
model-lockout recording for the same class — both intentional, to avoid
poisoning a healthy provider on request-specific timing). Nothing else
in the system was clearing the stale LKGP pin, so it kept winning
target-selection ordering for every new top-level request.

Fix: add clearLKGP(comboName, modelId) to src/lib/db/settings/lkgp.ts,
export it through settings.ts/localDb.ts, and call it (mirroring the
existing setLKGP-on-success call pattern exactly, same two keys) in both
combo.ts's per-target failure paths -- handleComboChat's "Done retrying
this model" block and handleRoundRobinCombo's structurally identical
twin -- right where a target is finally given up on and the loop moves
to the next one.

TDD: new regression test in tests/unit/combo-routing-engine.test.ts
("clears LKGP after the last-known-good target fails") reproduces the
exact live scenario -- confirmed failing against the pre-fix code,
passing after. Added direct unit coverage for clearLKGP itself in
tests/unit/db-settings-crud.test.ts (deletes only the targeted key,
sibling keys survive; no-op on an unset key doesn't throw) and
registered the new export in db-settings-split.test.ts's public API
surface characterization test.

Test plan:
- Full combo/LKGP-related suite (combo-routing-engine, db-settings-crud,
  db-settings-split, combo-strategy-fallbacks,
  combo-selected-connection-success,
  delete-provider-connection-invalidates-lkgp-8887, db-read-cache) --
  183/183 passing.
- npx tsc --noEmit -- clean for all changed files (pre-existing unrelated
  errors elsewhere in the same test files confirmed identical against a
  pristine upstream/release/v3.8.50 checkout, zero diff at those lines).
- npm run lint -- clean (new test's any usage properly typed, not left
  to inflate the file's frozen any-budget suppression).

⚠️ base-red inherited: #9985
2026-08-13 04:02:34 -03:00
..
2026-05-04 10:52:28 -03:00
2026-06-19 06:49:01 -03:00
2026-06-20 14:55:24 -03:00
2026-06-20 14:55:24 -03:00
2026-07-04 13:00:30 -03:00
2026-07-02 10:47:13 -03:00
2026-06-11 18:52:29 -03:00
2026-05-26 23:51:47 -03:00
2026-06-29 16:51:03 -03:00
2026-06-29 08:40:06 -03:00
2026-07-04 13:00:30 -03:00
2026-05-26 23:51:47 -03:00
2026-05-26 23:51:47 -03:00
2026-07-13 09:12:40 -03:00
2026-06-11 18:52:29 -03:00
2026-05-23 01:46:59 -03:00
2026-05-24 18:05:58 -03:00
2026-06-12 23:49:22 -03:00
2026-06-11 18:52:29 -03:00
2026-07-13 09:12:40 -03:00
2026-06-22 03:17:02 -03:00
2026-06-04 20:05:38 -03:00
2026-07-13 09:12:40 -03:00
2026-06-11 18:52:29 -03:00
2026-06-25 13:17:40 -03:00
2026-07-02 10:47:13 -03:00
2026-07-13 09:12:40 -03:00
2026-07-13 09:12:40 -03:00
2026-06-11 18:52:29 -03:00
2026-05-26 23:51:47 -03:00
2026-06-11 18:52:29 -03:00
2026-06-23 17:06:18 -03:00
2026-05-29 12:44:29 -03:00
2026-06-11 18:52:29 -03:00
2026-06-23 17:06:18 -03:00
2026-06-30 06:54:29 -03:00
2026-06-27 09:07:12 -03:00