feat: give zhipu, moonshot, anthropic and google a wire of their own
Eight segments now, and each one holds a ThinkingWire instead of two fixed fragments: off, on_base, and the key a tier gets written to. The two fragments could not say "on, at this depth", which is what every current generation model wants. Two deliberate behaviour changes fall out of it. The openai segment stops reporting its shape as unknown — reasoning_effort is OpenAI's own field, not a vendor dialect, so a compatible endpoint behind the gateway takes it. And minimax's on-tier stops carrying a hardcoded medium: that was the library picking a price for the caller, and medium is not even a tier GLM, kimi or deepseek serve. The issue #5 guards stay; their sample moves from "the openai segment" to an explicitly registered unknown one, which is what they always meant to test.
This commit is contained in:
@@ -16,6 +16,7 @@ from polygateway.errors import (
|
||||
)
|
||||
from polygateway.middleware.telemetry import TelemetryEmitter
|
||||
from polygateway.pricing import ModelPrice, PricingTable
|
||||
from polygateway.providers import ProviderProfile, ThinkingWire, register_provider
|
||||
from polygateway.transports._http_errors import summarize_body
|
||||
from polygateway.transports.openai_compat import (
|
||||
OpenAICompatTransport,
|
||||
@@ -60,10 +61,11 @@ def _sse_stream(*frames, done=True):
|
||||
return httpx.Response(200, content=text.encode(), headers={"content-type": "text/event-stream"})
|
||||
|
||||
|
||||
def _transport_for(handler):
|
||||
def _transport_for(handler, *, registry=None):
|
||||
mock = httpx.MockTransport(handler)
|
||||
return OpenAICompatTransport(
|
||||
client_factory=lambda src: httpx.AsyncClient(base_url=src.base_url, transport=mock)
|
||||
client_factory=lambda src: httpx.AsyncClient(base_url=src.base_url, transport=mock),
|
||||
registry=registry,
|
||||
)
|
||||
|
||||
|
||||
@@ -666,7 +668,9 @@ class TestRequestShaping:
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("enable_thinking", "expected"),
|
||||
[(True, "medium"), (False, "none")],
|
||||
# 开档不再附 medium(2026-09-04): 那是替下游做的档位判断,且 medium 不在
|
||||
# GLM/kimi/deepseek 的档位表里。MiniMax 开启档本就无需参数,要强度请配档位
|
||||
[(True, None), (False, "none")],
|
||||
)
|
||||
async def test_minimax_injects_reasoning_effort(self, enable_thinking, expected):
|
||||
"""issue #5: MiniMax 认的是 reasoning_effort,不是 enable_thinking。"""
|
||||
@@ -680,7 +684,10 @@ class TestRequestShaping:
|
||||
name="mm", provider="minimax", model="MiniMax-M3", enable_thinking=enable_thinking
|
||||
)
|
||||
await _complete(_transport_for(handler), source)
|
||||
assert seen["reasoning_effort"] == expected
|
||||
if expected is None:
|
||||
assert "reasoning_effort" not in seen
|
||||
else:
|
||||
assert seen["reasoning_effort"] == expected
|
||||
assert "enable_thinking" not in seen # 旧形态实测被静默丢弃,不再下发
|
||||
|
||||
async def test_extra_body_overrides_the_profile_slot(self):
|
||||
@@ -758,9 +765,15 @@ class TestRequestShaping:
|
||||
def handler(request): # pragma: no cover - 不该走到发请求
|
||||
raise AssertionError("请求不该发出")
|
||||
|
||||
source = _source(name="k3", provider="openai", model="kimi-k3", enable_thinking=False)
|
||||
# 2026-09-04 起默认表 8 段全部有形态,守卫样本改为显式注册的未知段
|
||||
mystery = ProviderProfile(
|
||||
name="mystery",
|
||||
thinking=ThinkingWire(off=None, on_base=None, effort_key=None),
|
||||
strip_think_tags=False,
|
||||
)
|
||||
source = _source(name="k3", provider="mystery", model="kimi-k3", enable_thinking=False)
|
||||
with pytest.raises(RequestRejectedError, match="register_provider"):
|
||||
await _complete(_transport_for(handler), source)
|
||||
await _complete(_transport_for(handler, registry=register_provider(mystery)), source)
|
||||
|
||||
async def test_overlay_merged_into_payload(self):
|
||||
seen = {}
|
||||
|
||||
Reference in New Issue
Block a user