Skip to content

fix: close Open Responses conformance gaps in schema, vision input, a…#136

Merged
alez007 merged 2 commits into
mainfrom
fix/open-responses-conformance-pass1
Jul 23, 2026
Merged

fix: close Open Responses conformance gaps in schema, vision input, a…#136
alez007 merged 2 commits into
mainfrom
fix/open-responses-conformance-pass1

Conversation

@alez007

@alez007 alez007 commented Jul 23, 2026

Copy link
Copy Markdown
Owner

…nd SSE termination

Vision content parts (input_image) in Responses message input were silently dropped in translation to chat messages; adds required ResponseObject fields (completed_at, truncation, service_tier, etc.) with spec-correct defaults, backfills echoed tools/text/temperature/top_p to match OpenAI's effective values, omits encrypted_content when unset, and emits the SSE [DONE] sentinel on clean stream completion.

…nd SSE termination

Vision content parts (input_image) in Responses message input were silently
dropped in translation to chat messages; adds required ResponseObject fields
(completed_at, truncation, service_tier, etc.) with spec-correct defaults,
backfills echoed tools/text/temperature/top_p to match OpenAI's effective
values, omits encrypted_content when unset, and emits the SSE [DONE]
sentinel on clean stream completion.
@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Closes OpenAI Responses API conformance gaps by aligning response schema defaults and streaming termination semantics, and by ensuring vision (input_image) parts in Responses message input are preserved when translating to chat messages.

Changes:

  • Add spec-aligned ResponseObject fields/defaults (e.g., completed_at, penalties, truncation/service tier) and ensure completed_at is only set on completed terminal responses.
  • Preserve vision content parts during Responses→Chat translation and reject unsupported content-part types.
  • Emit the SSE data: [DONE]\n\n sentinel on clean streaming completion and extend tests to cover these behaviors.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
tests/test_vllm_responses.py Asserts [DONE] sentinel on clean stream completion and absence on failed streams.
tests/test_responses_utils.py Adds coverage for build_response_from_parsed and completed_at behavior.
tests/test_responses_streaming.py Validates completed_at presence/absence across streaming event envelopes and incomplete termination.
tests/test_responses_adapter.py Adds coverage for image content translation, required response fields/defaults, echoed tool backfilling, and encrypted_content omission.
modelship/openai/utils/responses.py Sets completed_at for non-streaming completed responses.
modelship/openai/protocol/responses/streaming.py Sets completed_at only on terminal completed streaming envelope.
modelship/openai/protocol/responses/schemas.py Adds schema fields/defaults and omits encrypted_content when unset via serializer.
modelship/openai/protocol/responses/adapter.py Preserves image parts in message content, backfills effective defaults in response echo, and normalizes echoed tools.
modelship/infer/base_infer.py Emits SSE [DONE] sentinel after clean Responses stream completion.
Comments suppressed due to low confidence (1)

modelship/openai/protocol/responses/adapter.py:212

  • For text parts, _content_to_chat appends {"type": "text", "text": p.get("text")} without validating that text is a string. Because the request schema doesn’t type-check input items, a non-string text can make the later "".join(...) raise TypeError, turning a bad request into a 500. Validate (or skip) non-string text and raise UnsupportedResponsesFeatureError instead.
        ptype = p.get("type")
        if ptype in _CONTENT_TEXT_TYPES:
            parts.append({"type": "text", "text": p.get("text")})
        elif ptype in _CONTENT_IMAGE_TYPES:

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread modelship/openai/protocol/responses/adapter.py Outdated
…ing it

_content_to_chat and _text_of both fell back to str(content) for a shape
that was neither a string nor a list (e.g. a bare dict), silently baking
malformed request content into the prompt instead of rejecting it with a
400.
@alez007
alez007 merged commit fcb1e5d into main Jul 23, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants