Skip to content

Skip OpenRouter upstreams that do not cache - #307

Merged
regnull merged 2 commits into
mainfrom
feat/upstream-cache-learning
Oct 18, 2026
Merged

regnull merged 2 commits into
mainfrom
feat/upstream-cache-learning

Conversation

@regnull

@regnull regnull commented Oct 18, 2026

Copy link
Copy Markdown
Owner

Why

#305 pins each bot to the upstream that served its last call, but OpenRouter's price-weighted default routing picks cheap upstreams first, and those barely cache. Since that deploy, 123 calls sat on OpenInference, Venice and PrimeIntellect with 1.7% of prompt tokens cached (avg 22.9k prompt, 0.4k cached).

What

UpstreamPins now learns which upstreams cache:

  • Judged calls: only a call served by the same upstream as the run's previous call, where the prompt's start should be cached. Calls that switched upstream are cold and not judged.
  • Miss: under 25% of the prompt cached. A hit resets the streak.
  • Three misses in a row skip that upstream for the model (shared across bots) for 6h and unpin every bot pinned to it.
  • Requests: skipped slugs go in provider.ignore alongside the pin's order/allow_fallbacks, so OpenRouter picks elsewhere and the next pin lands on a different upstream.
  • Safety: at most 10 skips per model (the oldest lapses first) so routing never runs out; skips expire so upstreams are re-tested. An explicit openrouter_provider_order still bypasses everything.
  • Each skip is logged; README updated.

Tests

  • tests/test_upstream.py: miss streak and reset, skip/unpin/expiry, the 10-skip cap, the full middleware sequence (pinned → 3 warm misses → ignore → repinned to a caching upstream), and switched calls not being judged.
  • Backend: 837 passed; ruff clean.

🤖 Generated with Claude Code

regnull and others added 2 commits October 18, 2026 12:06
Pinning kept bots on whichever upstream OpenRouter picked first, and its price-weighted default picks
cheap upstreams that barely cache: after #305 bots sat on OpenInference, Venice and PrimeIntellect
with ~2% of prompt tokens cached. Judge warm calls (same upstream as the run's previous call): three
in a row with under 25% cached skip that upstream for the model for 6h via provider.ignore and unpin
its bots, so they settle on an upstream that caches. Capped at 10 skips per model; skips lapse.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d, per bot

Review fixes for the cache learning:
- Only skip an upstream when the model's endpoint list is known and another upstream remains, so the
  ignore list can never cover every upstream and fail all calls with 'no endpoints'.
- Judge a warm call against min(this prompt, previous prompt): a big new tool result can only be
  cached from the call after it, so it no longer counts as a miss.
- Miss streaks are per bot, so one bot's hit does not hide another's misses and ordinary misses from
  several bots do not add up to a skip.
- A pin to a skipped upstream (re-pinned by a call in flight) is dropped from the request.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@regnull
regnull merged commit 6f76cb9 into main Oct 18, 2026
4 checks passed
@regnull
regnull deleted the feat/upstream-cache-learning branch October 18, 2026 16:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant