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:
@@ -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。
|
||||
|
||||
@@ -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` 且**不丢整行**(遥测必录);与缓存回放同一方向。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user