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:
@@ -66,6 +66,18 @@ class TestObserveThinking:
|
||||
observe_thinking(thinking="想了想", reasoning_tokens=0) is ThinkingObservation.OBSERVED
|
||||
)
|
||||
|
||||
@pytest.mark.parametrize("negative", [-1, -205])
|
||||
def test_negative_token_count_is_not_evidence_of_absence(self, negative):
|
||||
"""负数是坏数据,不是"上游明确上报未推理"这个最强的正面结论。
|
||||
|
||||
当前 transport 已在边界把负数归 `None`,所以这条走不通;但本函数的
|
||||
docstring 自称"外部输入校验后使用",第二个 transport 直接填该值时,
|
||||
`> 0 else ABSENT` 会给出一个方向相反的强结论。函数自身必须闭合(P5)。
|
||||
"""
|
||||
assert observe_thinking(thinking="", reasoning_tokens=negative) is (
|
||||
ThinkingObservation.UNKNOWN
|
||||
)
|
||||
|
||||
|
||||
class TestThinkingObservationEnum:
|
||||
def test_values_are_stable_strings(self):
|
||||
@@ -85,7 +97,12 @@ class TestThinkingObservationEnum:
|
||||
|
||||
@pytest.mark.parametrize("bogus", ["", "OBSERVED", "yes", "none"])
|
||||
def test_unknown_strings_are_rejected(bogus):
|
||||
"""非法值必须抛 ValueError: 缓存回放靠它把污染数据挡成"未命中"(设计 §6)。"""
|
||||
"""非法值必须抛 ValueError: 缓存回放与遥测归一化都靠它识别域外取值(设计 §6)。
|
||||
|
||||
两处接住这个 ValueError 后**降级而非作废**(缓存复活内容 + 记 UNKNOWN、遥测
|
||||
照常落行),但降级的前提是构造器真的会拒绝——它一旦放行,域外取值就会一路
|
||||
进到 `LLMResponse` 与遥测列里。
|
||||
"""
|
||||
with pytest.raises(ValueError):
|
||||
ThinkingObservation(bogus)
|
||||
|
||||
@@ -239,6 +256,23 @@ class TestReconcileThinking:
|
||||
assert msg is not None
|
||||
assert "MiniMax-M3" in msg
|
||||
|
||||
def test_off_and_absent_stays_silent(self):
|
||||
"""要求关闭 + 上游明确上报未推理 = 要求被满足,没有可报的矛盾。
|
||||
|
||||
这一格与 `test_off_and_unknown_stays_silent` 的沉默理由**不同**: 那里是
|
||||
"没有证伪力",这里是"正面证实要求已满足"。两者都必须沉默,漏测哪一格,
|
||||
把 Phase 2 的判据写成 `is ABSENT` 之类的反向条件都不会被抓住。
|
||||
"""
|
||||
assert (
|
||||
reconcile_thinking(
|
||||
enable_thinking=False,
|
||||
observation=ThinkingObservation.ABSENT,
|
||||
capability=self._CAP,
|
||||
model="qwen3.7-plus",
|
||||
)
|
||||
is None
|
||||
)
|
||||
|
||||
def test_off_and_unknown_stays_silent(self):
|
||||
"""UNKNOWN 没有证伪力: 拿它报警等于每次关闭调用都喊(M3 关闭档恒落此档)。"""
|
||||
assert (
|
||||
|
||||
Reference in New Issue
Block a user