@@ -128,28 +128,33 @@ async def test_an_upstream_that_keeps_missing_warm_calls_is_skipped_and_unpinned
128128 pins = UpstreamPins (_fetch )
129129 await pins .record ("bot1" , "glm" , "Z.AI" )
130130 await pins .record ("bot2" , "glm" , "Z.AI" )
131- pins .observe_cache ("glm" , "z-ai" , 20_000 , 0 )
132- pins .observe_cache ("glm" , "z-ai" , 20_000 , 0 )
133- pins .observe_cache ("glm" , "z-ai" , 20_000 , 15_000 ) # a hit resets the streak
134- pins .observe_cache ("glm" , "z-ai" , 20_000 , 700 )
135- pins .observe_cache ("glm" , "z-ai" , 20_000 , 0 )
131+ pins .observe_cache ("bot1" , " glm" , "z-ai" , 20_000 , 0 )
132+ pins .observe_cache ("bot1" , " glm" , "z-ai" , 20_000 , 0 )
133+ pins .observe_cache ("bot1" , " glm" , "z-ai" , 20_000 , 15_000 ) # a hit resets the streak
134+ pins .observe_cache ("bot1" , " glm" , "z-ai" , 20_000 , 700 )
135+ pins .observe_cache ("bot1" , " glm" , "z-ai" , 20_000 , 0 )
136136 assert pins .ignored ("glm" ) == [] and pins .pinned ("bot1" , "glm" ) == "z-ai"
137- pins .observe_cache ("glm" , "z-ai" , 20_000 , 0 )
137+ pins .observe_cache ("bot1" , " glm" , "z-ai" , 20_000 , 0 )
138138 assert pins .ignored ("glm" ) == ["z-ai" ]
139139 assert pins .pinned ("bot1" , "glm" ) is None and pins .pinned ("bot2" , "glm" ) is None
140140 assert pins .ignored ("other-model" ) == [] # skips are per model
141141 clock [0 ] += 6 * 3600 + 1
142142 assert pins .ignored ("glm" ) == [] # and lapse, so the upstream gets another chance
143143
144144
145- def test_the_skip_list_is_capped_so_routing_never_runs_out (monkeypatch ):
145+ async def test_the_skip_list_is_capped_so_routing_never_runs_out (monkeypatch ):
146146 clock = [1000.0 ]
147147 monkeypatch .setattr ("openbot.runtime.upstream.time.monotonic" , lambda : clock [0 ])
148- pins = UpstreamPins (_fetch )
148+
149+ async def many (m ):
150+ return {f"host { i } " : f"host{ i } " for i in range (20 )}
151+
152+ pins = UpstreamPins (many )
153+ await pins .slug_for ("glm" , "host 0" ) # loads the endpoint list
149154 for i in range (12 ):
150155 clock [0 ] += 1
151156 for _ in range (3 ):
152- pins .observe_cache ("glm" , f"host{ i } " , 20_000 , 0 )
157+ pins .observe_cache ("bot1" , " glm" , f"host{ i } " , 20_000 , 0 )
153158 skipped = pins .ignored ("glm" )
154159 assert len (skipped ) == 10 and "host0" not in skipped and "host11" in skipped
155160
@@ -188,3 +193,75 @@ async def handler(request):
188193 for _ in range (8 ):
189194 await mw .awrap_model_call (_request (model ()), handler )
190195 assert pins .ignored ("z-ai/glm-5.3-flash" ) == []
196+
197+
198+ async def test_the_last_upstream_left_is_never_skipped ():
199+ """An ignore list naming every upstream would fail every call to the model with "no endpoints"."""
200+
201+ async def two (m ):
202+ return {"z.ai" : "z-ai" , "deepinfra" : "deepinfra" }
203+
204+ pins = UpstreamPins (two )
205+ await pins .slug_for ("glm" , "Z.AI" )
206+ for slug in ("z-ai" , "deepinfra" ):
207+ for _ in range (3 ):
208+ pins .observe_cache ("bot1" , "glm" , slug , 20_000 , 0 )
209+ assert pins .ignored ("glm" ) == ["z-ai" ] # deepinfra is all that is left, so it stays
210+
211+ async def offline (m ):
212+ raise OSError ("down" )
213+
214+ blind = UpstreamPins (offline )
215+ await blind .slug_for ("glm" , "Z.AI" )
216+ for _ in range (3 ):
217+ blind .observe_cache ("bot1" , "glm" , "z-ai" , 20_000 , 0 )
218+ assert blind .ignored ("glm" ) == [] # without the endpoint list it cannot tell, so it skips nothing
219+
220+
221+ async def test_warm_calls_are_judged_on_what_could_have_been_cached (settings ):
222+ """A big tool result makes the next prompt much longer; only the previous call's part of it can be
223+ cached, so 8k cached of a 38k prompt that followed an 8k one is a full hit, not a miss."""
224+ settings .openrouter_provider_order = []
225+ pins = UpstreamPins (_fetch )
226+ mw = StickyUpstreamMiddleware (pins , "bot1" , "z-ai/glm-5.3-flash" , settings )
227+ # Each warm call has under 25% of its whole prompt cached, but all of the previous call's.
228+ calls = iter ([(8_000 , 0 ), (38_000 , 8_000 ), (160_000 , 38_000 ), (700_000 , 160_000 )])
229+
230+ async def handler (request ):
231+ prompt , cached = next (calls )
232+ return AIMessage ("ok" , response_metadata = {UPSTREAM_KEY : ["Z.AI" ]}, usage_metadata = _usage (prompt , cached ))
233+
234+ for _ in range (4 ):
235+ await mw .awrap_model_call (_request (model ()), handler )
236+ assert pins .ignored ("z-ai/glm-5.3-flash" ) == []
237+
238+
239+ async def test_miss_streaks_are_per_bot ():
240+ pins = UpstreamPins (_fetch )
241+ await pins .slug_for ("glm" , "Z.AI" )
242+ for bot in ("bot1" , "bot2" , "bot3" ): # one ordinary miss each does not add up to a skip
243+ pins .observe_cache (bot , "glm" , "z-ai" , 20_000 , 0 )
244+ pins .observe_cache ("bot1" , "glm" , "z-ai" , 20_000 , 0 )
245+ pins .observe_cache ("bot2" , "glm" , "z-ai" , 20_000 , 15_000 ) # bot2's hit does not clear bot1's streak
246+ pins .observe_cache ("bot1" , "glm" , "z-ai" , 20_000 , 0 )
247+ assert pins .ignored ("glm" ) == ["z-ai" ]
248+
249+
250+ async def test_a_pin_to_a_skipped_upstream_is_not_sent (settings ):
251+ """A call in flight when its upstream was skipped re-pins the bot to it; the request must not then
252+ name the same upstream in both order and ignore."""
253+ settings .openrouter_provider_order = []
254+ pins = UpstreamPins (_fetch )
255+ await pins .slug_for ("z-ai/glm-5.3-flash" , "Z.AI" )
256+ for _ in range (3 ):
257+ pins .observe_cache ("bot2" , "z-ai/glm-5.3-flash" , "z-ai" , 20_000 , 0 )
258+ await pins .record ("bot1" , "z-ai/glm-5.3-flash" , "Z.AI" )
259+ mw = StickyUpstreamMiddleware (pins , "bot1" , "z-ai/glm-5.3-flash" , settings )
260+ sent = []
261+
262+ async def handler (request ):
263+ sent .append (request .model_settings ["extra_body" ]["provider" ])
264+ return AIMessage ("ok" )
265+
266+ await mw .awrap_model_call (_request (model ()), handler )
267+ assert sent == [{"ignore" : ["z-ai" ]}]
0 commit comments