diff --git a/tests/unit/test_client.py b/tests/unit/test_client.py index 92467b1..1a4c35b 100644 --- a/tests/unit/test_client.py +++ b/tests/unit/test_client.py @@ -298,10 +298,14 @@ class TestReasoningEffortPriority: class TestEffortFallbackWiring: """源级 `effort_fallback` 必须真的走到 `resolve_thinking`(issue #20)。 - 只测配置值域与纯函数是不够的: 变异实测显示把 transport 里的 - `fallback=source.effort_fallback` 换成硬编码 `"error"`,全套单测依然全绿—— - `nearest` 是人类明确要求实现的功能,没有这条端到端用例它会在零告警下变成 - 死代码(2026-09-05 独立验证查出)。故断言看**发出去的字节**。 + 只测配置值域与纯函数是不够的: 变异实测显示把 `fallback=source.effort_fallback` + 换成硬编码 `"error"`,全套单测依然全绿——`nearest` 是人类明确要求实现的功能, + 没有端到端用例它会在零告警下变成死代码(2026-09-05 独立验证查出)。 + + **该形态有两道门,必须各测各的**: transport 那道决定发出去的字节,`_guard_thinking` + 那道决定装配能不能过。只钉住 transport,装配守卫退化成硬编码 `error` 时,配了 + `nearest` 的源会在**运行期本来跑得起来**的情况下于装配期当场被判死,而这半边 + 第一轮修复时正是漏掉的那半边(M22)。 """ def _capturing_client(self, captured, **overrides): @@ -330,6 +334,30 @@ class TestEffortFallbackWiring: ) assert captured == [] # 请求根本没发出去 + def test_nearest_survives_the_assembly_guard(self): + """装配守卫也必须用源级 `fallback`: 运行期能映射的源不该在装配期被判死。 + + 源级 `medium` + glm-5.3(只有 low/high/max)是 `nearest` 唯一能被观测到的 + 装配期形态——守卫硬编码 `error` 时,这次 `from_env` 会抛 + `ThinkingUnsupportedError` 而不是返回 client。 + """ + env = dict(_ENV) + for key in list(env): + if key.startswith("LLM__QWEN__"): + del env[key] + env.update( + { + "LLM__ZHIPU__1__BASE_URL": "https://gw.example/v1", + "LLM__ZHIPU__1__API_KEY": "sk-a", + "LLM__ZHIPU__1__MODEL": "glm-5.3", + "LLM__ZHIPU__1__TIMEOUT_S": "120", + "LLM__ZHIPU__1__REASONING_EFFORT": "medium", + "LLM__ZHIPU__1__EFFORT_FALLBACK": "nearest", + } + ) + client = GatewayClient.from_env("LLM", env=env) + assert isinstance(client, GatewayClient) + class TestAppliedTierReachesTheCaller: """`LLMResponse.applied_effort` 报的是**真正发出去的**那一档(计划 T8-5)。