fix: OpenAI compliance audit — .stream() events, streamed usage, request-id, parse/raw-response#20
Conversation
5659482 to
058c262
Compare
|
Rebased onto current main (post #7–#11). Also folded in audit issue #6:
|
|
Also — beyond the #16 textual overlap: this PR's event-based |
|
Confirming the breaking change is intentional: iterating |
…est-id, escape hatches - #1 .stream() now yields OpenAI ChatCompletionStreamEvents (content.delta/done, tool-call events) via ChatCompletionStreamState; <think>/<precontext> stripped from content events; text_deltas() for plain tokens; create(stream=True) unchanged. - #2 streamed usage + system_fingerprint captured on get_final_completion(). - #3 _request_id carried onto the returned completion. - #6 parse()/with_raw_response/with_streaming_response exposed on the wrapper (no more AttributeError; parse delegates to the OpenAI client, model default + guard). Rebased onto main (post #7–#11).
058c262 to
2b127bd
Compare
Supersedes #19 (closed — its Issue-1 handling was documentation-only, which didn't resolve the contract collision). This does the proper fix and re-carries #19's other fixes.
Issue #1 (the proper fix):
.stream()now yields OpenAI eventsOur
.stream()shadowed OpenAI's method name but yielded rawChatCompletionChunks instead of event objects — so a migrator'sfor event in stream: if event.type == "content.delta"ran, then crashed. Now.stream()yields the real OpenAIChatCompletionStreamEvents (content.delta,content.done,chunk,tool_calls.function.arguments.delta/done, …) via openai'sChatCompletionStreamState, with Interfaze's inline<think>/<precontext>side-channels filtered out of the content events (buffered across chunk boundaries, flushed beforecontent.done).get_final_completion()still returns the extendedInterfazeChatCompletion(reasoning/precontext/vcache/usage).Live-verified against the API with
reasoning_effort:"high":text_deltas()for plain-token consumers;create(stream=True)unchanged (raw chunks, OpenAI Way A)..stream()now yields events, not chunks (it was never OpenAI-compatible before). Deliberate — that's the whole point of the audit finding.Also carried from #19 (unchanged, still needed)
usage—_Statecaptureschunk.usage+system_fingerprint(the usage chunk has emptychoices, so it's read before the choices check).get_final_completion().usageis now populated._request_idcarried throughto_interfaze.Repository→InterfazeAI/interfaze-python..stream()now documented as event-yielding), inputs portability, escape hatch, task-return.Note
Depends on
openai.lib.streaming.chat.ChatCompletionStreamState(openai's helper-lib surface, like our existing_thenUnwrapuse). The event tests act as the guard — they'd fail if a futureopenaichanged its accumulation. Worth a tighteropenaipin if this contract must be durable.Verify:
ruff+mypy --strictclean; 36 tests pass (event-contract, no-leak-in-events, tool-call events,text_deltas, async parity, double-consume, streamed usage).