feat: feed selector health and demote in-call failed sources

RetryMW keeps a per-call failure map (local, never instance state):
a source failing twice in one call yields to the next candidate.
Attempt outcomes feed OutcomeAwareSelector behind a swallow-and-warn
guard; ResultInvalid and provider-rejected paths record success with
count_attempt=False so the breaker window stays clean. Same accounting
applied in EmbeddingClient.
This commit is contained in:
2026-07-21 09:55:08 -04:00
parent e69dc05fd5
commit 4c2a148db9
5 changed files with 139 additions and 13 deletions
+2 -1
View File
@@ -303,7 +303,8 @@ class EmbeddingClient:
"""终态异常的门控写回(与 RetryMW 同口径): 坏结果/网关健康拒绝 ≠ 坏服务
→ 记成功;网关没响应的拒绝若持探针则归还。"""
if isinstance(exc, ResultInvalidError) or exc.status_code is not None:
await self._record_quietly(self._breaker.record_success(entry))
# M2.5 §3.1: 记成功但不计失败率窗口样本(坏结果/坏请求 ≠ 坏服务)
await self._record_quietly(self._breaker.record_success(entry, count_attempt=False))
elif entry.is_probe:
await self._record_quietly(self._breaker.release_probe(entry))