fix: reject conflicting raw reasoning overrides before sending

This commit is contained in:
2026-09-09 01:26:34 -04:00
parent 1ee74c35a8
commit 8e61a66342
4 changed files with 213 additions and 110 deletions
+19 -8
View File
@@ -34,7 +34,12 @@ from polygateway.sources import (
RoundRobinSelector,
SourceCooldownMemo,
)
from polygateway.thinking import effective_effort, get_capability, resolve_thinking
from polygateway.thinking import (
effective_effort,
get_capability,
resolve_thinking,
validate_thinking_raw,
)
from polygateway.transports.openai_compat import OpenAICompatTransport
from polygateway.types import (
ChatRequest,
@@ -82,21 +87,26 @@ def _guard_thinking(
就带着指路信息炸掉。`get_provider` 现在就是同一形态的双点调用。
"""
for source, profile in zip(sources, profiles, strict=True):
effort = effective_effort(
request_effort=None,
source_effort=source.reasoning_effort,
enable_thinking=source.enable_thinking,
)
resolve_thinking(
profile,
get_capability(source.model, table=capabilities),
# 装配期看不见请求级档位(它逐次调用才产生),故只解源级两层;请求级
# 只能在运行期由 transport 校验(设计 §10 的装配期/运行期分工)
effective_effort(
request_effort=None,
source_effort=source.reasoning_effort,
enable_thinking=source.enable_thinking,
),
effort,
model=source.model,
# 与 transport 用同一个 fallback,否则配了 nearest 的源会在装配期就被
# 判死,而它在运行期本来是能映射到最近档跑起来的
fallback=source.effort_fallback,
)
validate_thinking_raw(
source.extra_body,
effort=effort,
wire=profile.thinking,
origin=f"{source.name} extra_body",
)
def _fingerprint_mark(source: SourceConfig) -> str:
@@ -359,6 +369,7 @@ class GatewayClient:
if reasoning_effort is None
else coerce_effort(reasoning_effort, origin="chat(reasoning_effort=...)")
)
validate_thinking_raw(sampling, effort=effort, wire=None, origin="chat overlay")
request = ChatRequest(
messages=messages,
session_id=session_id,
+9 -5
View File
@@ -34,6 +34,7 @@ from polygateway.thinking import (
observe_thinking,
reconcile_thinking,
resolve_thinking,
validate_thinking_raw,
)
from polygateway.transports._http_errors import compose_message, summarize_body
from polygateway.types import (
@@ -371,20 +372,23 @@ class OpenAICompatTransport:
self._warned_models.add(source.model)
# 三层优先级在此汇合: 请求级 > 源级 > enable_thinking 语法糖(设计 §4.2)。
# 判定与装配守卫共用同一个纯函数,两处分叉就会变成"装配期放行、运行期报错"
effort = effective_effort(
request_effort=reasoning_effort,
source_effort=source.reasoning_effort,
enable_thinking=source.enable_thinking,
)
resolution = resolve_thinking(
profile,
capability,
effective_effort(
request_effort=reasoning_effort,
source_effort=source.reasoning_effort,
enable_thinking=source.enable_thinking,
),
effort,
model=source.model,
# 源级 `EFFORT_FALLBACK` 必须真的走到这里: 硬编码 "error" 会让人类明确
# 要求实现的 `nearest` 在零告警下变成死代码(2026-09-05 独立验证查出)
fallback=source.effort_fallback,
warn_unregistered=first_time,
)
for raw, origin in ((source.extra_body, "source extra_body"), (overlay, "request overlay")):
validate_thinking_raw(raw, effort=effort, wire=profile.thinking, origin=origin)
payload.update(resolution.payload)
# 顺序即优先级(issue #4 设计决策 A): 配置级 extra_body 在前,调用级
# overlay(含结构化注入)在后覆盖之。两行不可调换