fix: close the failure modes review found in the new code

Three of them were the same shape as the bug this branch exists to fix:
something goes wrong, the library swallows it, and the caller is left
with a number that means the opposite of what happened.

The throttle key had no source in it. Five sources on one model is the
normal case here, so the first one to break would warn once and silence
the other four for the life of the process, and the message never said
which gateway to look at.

An unknown verdict in a cached entry threw away the whole response. The
rehydrator tolerates unknown fields but not unknown values of a known
field, so two library versions sharing a Redis would each invalidate
the other's entries: halved hit rate, and the only log line says the
cache rebuild failed. A purely observational field should not be able
to void a response whose content is intact.

Normalising for telemetry now degrades instead of raising, both for a
bare string and for a value outside the domain. Either one used to
reach the same except and cost the whole row, which is exactly how
1.3.0 lost nineteen calls without anyone noticing.
This commit is contained in:
2026-08-26 02:37:24 -04:00
parent c0b544d233
commit 1307a02b92
9 changed files with 270 additions and 30 deletions
+5 -1
View File
@@ -32,7 +32,11 @@ def observe_thinking(*, thinking: str, reasoning_tokens: int | None) -> Thinking
"""
if thinking.strip():
return ThinkingObservation.OBSERVED
if reasoning_tokens is None:
# 负数与 None 同档: `ABSENT` 是"上游明确上报未推理"这个最强的正面结论,坏
# 数据给不出它。当前 transport 已在边界把负数归 None,这里仍要自己闭合——本
# 函数对外承诺"外部输入校验后使用",第二个 transport 直接填该值时,漏判会
# 给出一个方向相反的强结论(P5)
if reasoning_tokens is None or reasoning_tokens < 0:
return ThinkingObservation.UNKNOWN
return ThinkingObservation.OBSERVED if reasoning_tokens > 0 else ThinkingObservation.ABSENT