fix: address completion verdict review findings

- fidelity cacheability also requires a non-empty projected body, so
  think-tag-only answers are no longer cached
- a no-argument tool sent with arguments null only is a deterministic
  dialect: ResultInvalid tool_arguments_null instead of retried
- text mode treats choice index null as 0 and no longer lets False pose
  as 0
- null-only tool_calls elements no longer produce an empty tool_calls
  list; non-stream fidelity checks role before the verdict; warning
  paths are length-bounded
- docs: ARCHITECTURE 7.8 field counts, README cache/watchdog wording,
  CHANGELOG notes, review record in the design, hook note in the plan

Red: 8 new tests failed before this change (e.g.
test_openai_cacheable_requires_projected_body,
test_null_arguments_tool_is_result_invalid_stream,
test_text_mode_choice_index_null_is_zero[None-True]).
This commit is contained in:
2026-10-15 00:22:07 -04:00
parent 31942f55f1
commit abcdf6930e
12 changed files with 179 additions and 27 deletions
+11
View File
@@ -1116,3 +1116,14 @@ async def test_new_fields_roundtrip_through_cache():
assert stored["finish_reason"] == "stop" and stored["stream_end"] == "eof_after_finish"
hit = await mw(ChatRequest(messages=_MSGS), terminal)
assert hit.cache_hit is True and hit.finish_reason == "stop" and hit.stream_end is None
async def test_fidelity_think_only_projection_not_cached():
"""审查 I1: qwen think 标签剥离后投影为空的保真结果不写缓存。"""
completion = OpenAIChatCompletion(
{"role": "assistant", "content": "<think>x</think>"}, "stop", "up", None
)
response = _resp(content="", thinking="x", finish_reason="stop", completion=completion)
backend = InMemoryCache()
await _mw(backend)(ChatRequest(messages=_MSGS, response_mode="openai"), _Terminal(response))
assert not backend._store