test: give two silent guards something to fail on again

`test_extra_body_overrides_the_profile_slot` guards that a source's
`extra_body` wins over the slot the profile injects. Since T5 made
`enable_thinking=True` mean `auto`, its minimax fixture injected an empty
fragment — swapping the two update calls changed nothing and the whole
suite stayed green, while a real source (zhipu, glm-5.3, tier `low`)
would have shipped `low` instead of the `high` the caller wrote. Move the
fixture onto that combination, where the two sides write the same key.

`emit_attempt`'s docstring promises `reasoning_applies` carries no
default so that a missed argument is a TypeError rather than a silent
`True`; nothing enforced it. Pin the signature the way `record_llm_call`
is already pinned.
This commit is contained in:
2026-09-05 06:54:40 -04:00
parent 4866e6b858
commit f9b357b9d7
2 changed files with 29 additions and 5 deletions
+14 -5
View File
@@ -747,7 +747,13 @@ class TestRequestShaping:
assert "enable_thinking" not in seen # 旧形态实测被静默丢弃,不再下发
async def test_extra_body_overrides_the_profile_slot(self):
"""注入顺序即优先级: profile → extra_body → overlay,两行不可调换。"""
"""注入顺序即优先级: profile → extra_body → overlay,两行不可调换。
固定用 **zhipu + glm-5.3 + 源级 low** 这组: 判据必须落在一个 profile
**真的写了值**的键上,两边写同一个键才谈得上谁覆盖谁。用 minimax +
`enable_thinking=True` 是测不出来的——T5 起 `True ≡ auto`,而 auto 的注入
片段就是 minimax 的 `on_base`(空字典),两行怎么调换结果都一样,断言恒真。
"""
seen = {}
def handler(request):
@@ -755,14 +761,17 @@ class TestRequestShaping:
return _sse_stream(_chunk(content="x"), _chunk(usage=_USAGE))
source = _source(
name="mm",
provider="minimax",
model="MiniMax-M3",
enable_thinking=True,
name="zp",
provider="zhipu",
model="glm-5.3",
reasoning_effort="low",
extra_body={"reasoning_effort": "high"},
)
await _complete(_transport_for(handler), source)
# profile 注入的是 low,extra_body 后写故发出去的是 high;顺序一调换就变 low,
# 即下游写在 extra_body 里的覆盖被库悄悄顶掉(issue #20 的成因形态)
assert seen["reasoning_effort"] == "high"
assert seen["thinking"] == {"type": "enabled"} # profile 独有的那半边仍在
async def test_model_that_cannot_disable_is_rejected_not_silently_ignored(self):
"""M2.x 关不掉推理: 必须是四分类之一的 RequestRejected,不是裸 ValueError。
+15
View File
@@ -1421,6 +1421,21 @@ class TestEmitterReasoningEffort:
)
assert rec.rows[0]["reasoning_effort"] is None
def test_reasoning_applies_has_no_default(self):
"""上一条测的是"传了 False 会怎样",这条测的是"**漏传**会怎样"
`reasoning_applies` 的约定是不设默认值(与 `TelemetryRecorder` 同款):库外
无第三方调用者,写全签名成本为零,而默认 `True` 会让将来新增的第四条 emit
路径(又一个非推理客户端)漏传时静默落进 chat 口径——一次 embedding 失败被
挂上源上误配的 `auto` 档,正是上一条测试要防的形态,却绕过了它的断言。
约定只写在 docstring 里是没有执法点的,故在此以 `inspect.signature` 实测。
"""
import inspect
param = inspect.signature(TelemetryEmitter.emit_attempt).parameters["reasoning_applies"]
assert param.default is inspect.Parameter.empty
assert param.kind is inspect.Parameter.KEYWORD_ONLY
async def test_an_out_of_domain_tier_degrades_but_keeps_the_row(self):
"""域外取值降级为 `NULL` 且**不丢整行**(遥测必录);与缓存回放同一方向。