feat: wire the tier through the transport and keep each tier's warning distinct

The transport now hands back the tier it actually sent, and that tier
rides TransportResult into LLMResponse. It is not the requested one:
under EFFORT_FALLBACK=nearest a medium request goes out as low, and
telemetry grouping by the requested tier would file the row under a tier
that never left the process.

Reconciliation judges the same tier instead of the old enable_thinking
bool, and the warning throttle keys on it. Keyed on the bool, every tier
of one model shared a single key, so the second contradiction was
silenced for the lifetime of the transport. The predicate is an identity
check against Effort.NONE on purpose -- the member's value is the
non-empty string "none", so any truthiness test would send every strength
tier down the "asked to disable" branch and invert the alarm.
This commit is contained in:
2026-09-05 05:00:29 -04:00
parent 5dfb15e6a2
commit 848dc0aa7f
8 changed files with 279 additions and 48 deletions
+65 -11
View File
@@ -445,10 +445,14 @@ class TestResolveThinking:
class TestReconcileThinking:
"""声明 × 观测对账(设计 §5): 矛盾出文案,不表态出 None。
"""声明 × 观测对账(设计 §4.3): 矛盾出文案,不表态出 None。
文案本身是被断言对象——判定与日志分离正是为此: 告警内容可直接比对,不必
去解析日志格式。
判据自 2026-09-05 起是**档位**而非布尔(设计 §4.3): `Effort.NONE` 走"要求
关闭"一支,其余档走"要求开启"一支。档位化不是换个参数名——文案里写的是本次
真正发出去的那一档,而 transport 的节流键正按它分离,两者必须同源。
"""
_CAP = ThinkingCapability(
@@ -458,7 +462,7 @@ class TestReconcileThinking:
def test_off_but_observed_with_a_registered_capability_blames_the_table(self):
"""已登记却实测推理了 = 能力表漂移: 必须附 evidence 与更新指路。"""
msg = reconcile_thinking(
enable_thinking=False,
effort=Effort.NONE,
observation=ThinkingObservation.OBSERVED,
capability=self._CAP,
model="MiniMax-M3",
@@ -471,7 +475,7 @@ class TestReconcileThinking:
def test_off_but_observed_unregistered_never_claims_a_table_entry(self):
"""未登记模型没有"能力表声称"这回事——说它就是撒谎。"""
msg = reconcile_thinking(
enable_thinking=False,
effort=Effort.NONE,
observation=ThinkingObservation.OBSERVED,
capability=None,
model="MiniMax-M9",
@@ -483,13 +487,13 @@ class TestReconcileThinking:
def test_registered_and_unregistered_wordings_differ(self):
registered = reconcile_thinking(
enable_thinking=False,
effort=Effort.NONE,
observation=ThinkingObservation.OBSERVED,
capability=self._CAP,
model="MiniMax-M3",
)
unregistered = reconcile_thinking(
enable_thinking=False,
effort=Effort.NONE,
observation=ThinkingObservation.OBSERVED,
capability=None,
model="MiniMax-M3",
@@ -500,7 +504,7 @@ class TestReconcileThinking:
def test_on_but_absent_is_a_contradiction(self, capability):
"""上游明确上报未推理: 这是唯一的正面证伪,与能力表登记与否无关。"""
msg = reconcile_thinking(
enable_thinking=True,
effort=Effort.AUTO,
observation=ThinkingObservation.ABSENT,
capability=capability,
model="qwen3.7-plus",
@@ -512,7 +516,7 @@ class TestReconcileThinking:
def test_on_but_unknown_admits_it_cannot_confirm(self, capability):
"""issue #17 的诚实版本: 明说"我注入了,但我看不见结果""""
msg = reconcile_thinking(
enable_thinking=True,
effort=Effort.AUTO,
observation=ThinkingObservation.UNKNOWN,
capability=capability,
model="MiniMax-M3",
@@ -529,7 +533,7 @@ class TestReconcileThinking:
"""
assert (
reconcile_thinking(
enable_thinking=False,
effort=Effort.NONE,
observation=ThinkingObservation.ABSENT,
capability=self._CAP,
model="qwen3.7-plus",
@@ -541,7 +545,7 @@ class TestReconcileThinking:
"""UNKNOWN 没有证伪力: 拿它报警等于每次关闭调用都喊(M3 关闭档恒落此档)。"""
assert (
reconcile_thinking(
enable_thinking=False,
effort=Effort.NONE,
observation=ThinkingObservation.UNKNOWN,
capability=self._CAP,
model="MiniMax-M3",
@@ -557,7 +561,7 @@ class TestReconcileThinking:
"""调用方不表态,就无从谈"违背""""
assert (
reconcile_thinking(
enable_thinking=None,
effort=None,
observation=observation,
capability=self._CAP,
model="MiniMax-M3",
@@ -568,7 +572,7 @@ class TestReconcileThinking:
def test_on_and_observed_is_exactly_what_was_asked_for(self):
assert (
reconcile_thinking(
enable_thinking=True,
effort=Effort.AUTO,
observation=ThinkingObservation.OBSERVED,
capability=self._CAP,
model="MiniMax-M3",
@@ -576,6 +580,56 @@ class TestReconcileThinking:
is None
)
@pytest.mark.parametrize("effort", [Effort.LOW, Effort.HIGH, Effort.MAX])
def test_a_strength_tier_is_an_on_request_not_an_off_one(self, effort):
"""强度档必须走"要求开启"一支: 观测到推理正是它要的结果,不得报警。
判据写成真值性(`if not effort`)会在这里翻车——`Effort.NONE` 的取值是
非空串 `"none"`,恒为真;那种写法会把每一个强度档都送进"要求关闭"分支,
于是"想了"被当成矛盾,而"没想"反倒沉默,告警方向整个颠倒。
"""
assert (
reconcile_thinking(
effort=effort,
observation=ThinkingObservation.OBSERVED,
capability=ThinkingCapability((Effort.LOW, Effort.HIGH, Effort.MAX), "构造"),
model="glm-5.3",
)
is None
)
def test_the_wording_names_the_tier_that_was_asked_for(self):
"""文案要写出**本次这一档**: 节流键按档分离,文案不分档就看不出是哪一档。"""
low = reconcile_thinking(
effort=Effort.LOW,
observation=ThinkingObservation.ABSENT,
capability=None,
model="glm-5.3",
)
max_ = reconcile_thinking(
effort=Effort.MAX,
observation=ThinkingObservation.ABSENT,
capability=None,
model="glm-5.3",
)
assert low is not None and max_ is not None
assert "low" in low and "max" in max_
assert low != max_
def test_none_and_observed_is_the_issue_20_contradiction(self):
"""请求 `none` 却观测到推理 —— issue #20 要恢复的那条报警,判据是**档位相等**。
与上一条互为对照: 同样是 OBSERVED,`none` 必须喊、强度档必须沉默。把分支
条件写反(`is not Effort.NONE`)会让这两条同时红,单有一条则抓不住。
"""
msg = reconcile_thinking(
effort=Effort.NONE,
observation=ThinkingObservation.OBSERVED,
capability=None,
model="glm-5.3",
)
assert msg is not None and "none" in msg
class TestEffortVocabulary:
"""八档封闭词汇(设计 §3.1);`auto` 不可省——9 个纯开关型模型无强度档可填。"""