fix: address independent verification findings
Classify empty completions as transient per human ruling (fixes flaky real-gateway smoke and prevents caching empty responses), rename the factory injection parameter gate to breaker per the frozen design, rewrite the probe-entry cleanup without except BaseException, declare python-dotenv explicitly, add a mid-backoff cancellation test, and record all implementation errata in the design and architecture docs.
This commit is contained in:
@@ -161,6 +161,33 @@ class TestMissingDoneSemantics:
|
||||
await _complete(_transport_for(handler), _source(missing_done="salvage"))
|
||||
|
||||
|
||||
class TestEmptyCompletion:
|
||||
"""空补全 → TransientError(2026-07-20 人类裁决;MiniMax 间歇形态,绝不缓存)。"""
|
||||
|
||||
async def test_stream_zero_content_with_done_is_transient(self):
|
||||
def handler(request):
|
||||
return _sse_stream(_chunk(reasoning="only thinking"), _chunk(usage=_USAGE))
|
||||
|
||||
with pytest.raises(TransientError, match="empty_completion"):
|
||||
await _complete(_transport_for(handler), _source())
|
||||
|
||||
async def test_non_stream_empty_content_is_transient(self):
|
||||
def handler(request):
|
||||
return httpx.Response(
|
||||
200, json={"choices": [{"message": {"content": ""}}], "usage": _USAGE}
|
||||
)
|
||||
|
||||
with pytest.raises(TransientError, match="empty_completion"):
|
||||
await _complete(_transport_for(handler), _source(), stream=False)
|
||||
|
||||
async def test_think_only_content_after_strip_is_transient(self):
|
||||
def handler(request):
|
||||
return _sse_stream(_chunk(content="<think>hmm</think>"), _chunk(usage=_USAGE))
|
||||
|
||||
with pytest.raises(TransientError, match="empty_completion"):
|
||||
await _complete(_transport_for(handler), _source())
|
||||
|
||||
|
||||
class TestNonStreamFastPath:
|
||||
async def test_non_stream_parses_message(self):
|
||||
def handler(request):
|
||||
|
||||
Reference in New Issue
Block a user