- 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]).
Null is treated as absent at every layer; unknown delta, tool and
function fields merge by OpenAI streaming conventions (strings concat,
label keys idempotent, indexed arrays by index) and conflicts drop the
key and record its path instead of failing the call. The accumulator
now tracks finish and usage-after-finish in both modes, exposes the
reasoning alias, and non-stream parsing splits shape checks from
snapshot construction.
Red: 20 of 47 tests in tests/unit/test_openai_completion.py failed
before this change (e.g. test_null_known_and_unknown_fields_are_absent
raised TransientError 未知 delta 字段; finish_seen/raw_message missing).
Add faithful single-choice chat results, tool stream activity, error-frame retries, and isolated protocol caching.
Reject empty cached completions with the same value predicate as transport, add regression coverage, and adopt Apache-2.0.