fix(llm): 流式路径加首 token 前 per-provider 重试(CR-H6)

This commit is contained in:
Yaojia Wang
2026-07-08 10:26:29 +02:00
parent 51fe9f44fe
commit 8a2b1b09dc
2 changed files with 60 additions and 2 deletions

View File

@@ -132,6 +132,31 @@ async def test_missing_adapter_in_chain_skipped(req: LlmRequest) -> None:
assert resp.served_by.fell_back is True
async def test_stream_retries_before_first_token_then_succeeds(req: LlmRequest) -> None:
# CR-H6首 token 前的瞬时失败应 per-provider 退避重试(对称 run 的 _complete_with_retry
# 而非直接烧掉一个回退名额切备用。max_retries=2 → 最多 3 次尝试;前两次 transient、
# 第三次成功 → 主 provider 服务,备用零调用。
primary = ScriptedAdapter(
"deepseek", text="流式重试后成功", failures=[transient(), transient()]
)
backup = ScriptedAdapter("openai", text="备用")
ledger = FakeLedger()
gw = Gateway(
{"deepseek": primary, "openai": backup},
ledger,
chain_resolver=chain_resolver(chain(("deepseek", "deepseek-chat"), ("openai", "gpt-4o"))),
max_retries=2,
)
collected = [d.text async for d in gw.stream(req)]
assert "".join(collected) == "流式重试后成功"
assert primary.stream_calls == 3 # 2 次失败 + 1 次成功(重试在首 token 前)
assert backup.stream_calls == 0 # 未切备用
assert len(ledger.records) == 1
assert ledger.records[0].provider == "deepseek"
# ---- 熔断器 ----