feat: carry the reasoning verdict through to LLMResponse
Both assembly paths fill it, streaming and non-streaming alike. Filling only one is exactly the divergence this issue exposed: M3 returns reasoning prose over SSE and nothing at all over the plain endpoint, so a verdict computed on one path says nothing about the other. The field defaults to UNKNOWN on both TransportResult and LLMResponse. A transport that does not judge should not get to declare absence on the provider's behalf, and a default that stays silent is the only one that cannot lie.
This commit is contained in:
@@ -27,6 +27,7 @@ from polygateway.types import (
|
||||
GlobalLimits,
|
||||
RetryPolicy,
|
||||
SourceConfig,
|
||||
ThinkingObservation,
|
||||
TransportResult,
|
||||
)
|
||||
from tests.contracts.conftest import FakeClock
|
||||
@@ -225,6 +226,29 @@ class TestObservabilityPassthrough:
|
||||
assert resp.cached_prompt_tokens is None and resp.model_reported is None
|
||||
assert resp.reasoning_tokens is None
|
||||
|
||||
async def test_thinking_observation_reaches_the_response(self):
|
||||
"""issue #16/#17: 裁定归 transport,中间件只透传,不得在途中改判。"""
|
||||
result = TransportResult(
|
||||
content="ok",
|
||||
thinking="想一下",
|
||||
prompt_tokens=10,
|
||||
completion_tokens=5,
|
||||
usage_source="measured",
|
||||
ttft_ms=12.0,
|
||||
max_inter_token_ms=3.0,
|
||||
raw={},
|
||||
thinking_observation=ThinkingObservation.OBSERVED,
|
||||
)
|
||||
mw, *_ = _harness([_src("a")], [result])
|
||||
resp = await mw(_REQ)
|
||||
assert resp.thinking_observation is ThinkingObservation.OBSERVED
|
||||
|
||||
async def test_unjudged_transport_result_stays_unknown(self):
|
||||
"""不裁定的 transport(如 OCR)透传出来仍是 UNKNOWN,不被默认成 ABSENT。"""
|
||||
mw, *_ = _harness([_src("a")], [_ok()])
|
||||
resp = await mw(_REQ)
|
||||
assert resp.thinking_observation is ThinkingObservation.UNKNOWN
|
||||
|
||||
|
||||
class TestRetryAndFailover:
|
||||
async def test_transient_switches_source_then_succeeds(self):
|
||||
|
||||
Reference in New Issue
Block a user