feat: accept sampling overlay on chat() and per-source extra_body
Priority is structured injection > per-call overlay > per-source config, and extra_body now takes part in the cache fingerprint.
This commit is contained in:
@@ -445,6 +445,27 @@ class TestRequestShaping:
|
||||
)
|
||||
assert seen["response_format"] == {"type": "json_object"}
|
||||
|
||||
async def test_extra_body_merged_and_outranked_by_overlay(self):
|
||||
"""顺序即优先级: thinking profile → extra_body → overlay(issue #4)。"""
|
||||
seen = {}
|
||||
|
||||
def handler(request):
|
||||
seen.update(json.loads(request.content))
|
||||
return _sse_stream(_chunk(content="x"), _chunk(usage=_USAGE))
|
||||
|
||||
await _complete(
|
||||
_transport_for(handler),
|
||||
_source(extra_body={"temperature": 0, "top_p": 0.9}),
|
||||
overlay={"temperature": 1},
|
||||
)
|
||||
assert seen["temperature"] == 1 # 调用级覆盖配置级
|
||||
assert seen["top_p"] == 0.9 # 未被顶掉的配置级键保留
|
||||
|
||||
async def test_extra_body_cannot_break_governed_keys(self):
|
||||
"""治理键由 payload 骨架拥有;extra_body 的保护键在构造期已被拦下。"""
|
||||
with pytest.raises(ValueError, match="stream"):
|
||||
_source(extra_body={"stream": False})
|
||||
|
||||
|
||||
class TestErrorTranslation:
|
||||
@pytest.mark.parametrize(
|
||||
|
||||
Reference in New Issue
Block a user