feat: let one call ask for a different tier than its source defaults to

The three-layer priority (call > source > enable_thinking sugar > silence)
now lives in one pure function, thinking.effective_effort(). The assembly
guard and the request hot path used to each carry their own inline copy of
the sugar conversion; two copies of the same judgement drift into the worst
shape there is - passes at assembly, raises at runtime.

The guard now also honours effort_fallback, so a source that opted into
nearest is no longer sentenced at assembly for a tier it could have mapped.
This commit is contained in:
2026-09-05 02:15:25 -04:00
parent 603a835f60
commit 1f13eb18ab
5 changed files with 177 additions and 7 deletions
+65
View File
@@ -13,6 +13,7 @@ from polygateway.thinking import (
DEFAULT_CAPABILITIES,
ThinkingCapability,
ThinkingUnsupportedError,
effective_effort,
get_capability,
observe_thinking,
reconcile_thinking,
@@ -616,3 +617,67 @@ class TestCapabilityTierList:
assert get_capability("MiniMax-M2.7").can_disable is False
assert get_capability("MiniMax-M2.5").can_disable is False
assert get_capability("MiniMax-M3").can_disable is True
class TestEffectiveEffort:
"""三层优先级的**唯一**判定处(设计 §4.2): 请求级 > 源级 > 语法糖 > 不表态。
收口成一个纯函数,是因为它此前在装配守卫与 transport 里各写了一份就地转换:
两份各自演化的判定,迟早会在"装配期放行、运行期报错"这种最难查的形态上分叉。
"""
def test_request_beats_source(self):
assert (
effective_effort(
request_effort=Effort.MAX, source_effort=Effort.LOW, enable_thinking=None
)
is Effort.MAX
)
def test_source_beats_sugar(self):
assert (
effective_effort(request_effort=None, source_effort=Effort.HIGH, enable_thinking=None)
is Effort.HIGH
)
def test_none_request_does_not_clear_source(self):
"""请求级"没表态"绝不能被读成"要求关闭"——那会静默改掉源级的默认档。"""
assert (
effective_effort(request_effort=None, source_effort=Effort.LOW, enable_thinking=None)
is Effort.LOW
)
def test_request_none_tier_is_an_opinion(self):
"""`Effort.NONE` 是一次明确的表态,必须压过源级档位而不是被当成缺省。"""
assert (
effective_effort(
request_effort=Effort.NONE, source_effort=Effort.MAX, enable_thinking=None
)
is Effort.NONE
)
def test_enable_thinking_true_is_auto(self):
"""`True` → `auto`(开启但不指定强度),而**不是**旧版硬编码的 medium。"""
assert (
effective_effort(request_effort=None, source_effort=None, enable_thinking=True)
is Effort.AUTO
)
def test_enable_thinking_false_is_the_none_tier(self):
assert (
effective_effort(request_effort=None, source_effort=None, enable_thinking=False)
is Effort.NONE
)
def test_sugar_is_the_last_word_only(self):
"""语法糖排在最末: 显式配了档位就以档位为准(矛盾组合已被构造期挡下)。"""
assert (
effective_effort(request_effort=None, source_effort=Effort.LOW, enable_thinking=True)
is Effort.LOW
)
def test_all_absent_is_no_opinion(self):
"""三层都不表态 → None(随模型默认),与 `Effort.NONE` 严格区分。"""
assert (
effective_effort(request_effort=None, source_effort=None, enable_thinking=None) is None
)