Skip to content

Missing 'response.content_part.added' SSE event in Responses API streaming - breaks Codex CLI compatibility #2875

@jerryan999

Description

@jerryan999

Description

When using the OpenAI Responses API (/v1/responses) with stream: true, Sub2API emits SSE events in this order:

event: response.created
event: response.output_item.added
event: response.output_text.delta    ← content starts here
event: response.output_text.done
event: response.output_item.done
event: response.completed

The response.content_part.added event is missing after response.output_item.added and before response.output_text.delta.

Expected SSE Event Sequence

Per the OpenAI Responses API streaming specification, the correct sequence should be:

event: response.created
event: response.output_item.added
event: response.content_part.added   ← MISSING in Sub2API
event: response.output_text.delta
event: response.output_text.done
event: response.content_part.done    ← MISSING in Sub2API
event: response.output_item.done
event: response.completed

Impact

Clients that strictly follow the OpenAI Responses API event model (such as OpenAI Codex CLI) fail to process streaming responses. Codex CLI logs:

ERROR codex_core::util: OutputTextDelta without active item

It discards all output_text.delta content because there is no active content part to associate it with. The HTTP response returns 200 OK, the SSE stream is well-formed, but the text content is never delivered to the user.

Reproduction

curl -s -N -X POST http://localhost:8080/v1/responses \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <your-key>" \
  -d '{"model":"deepseek-v4-flash","input":"hello","stream":true}' \
  | grep "^event:"

Expected output includes response.content_part.added; actual output jumps directly from response.output_item.added to response.output_text.delta.

Environment

  • Sub2API version: weishaw/sub2api:0.1.132 (latest as of 2026-05-29)
  • Client: OpenAI Codex CLI v0.135.0

Suggested Fix

Before emitting response.output_text.delta, add:

event: response.content_part.added
data: {"type":"response.content_part.added","part":{"type":"output_text","text":""},"item_id":"<item_id>"}

And after response.output_text.done, emit:

event: response.content_part.done
data: {"type":"response.content_part.done","part":{"type":"output_text","text":"<full_text>"},"item_id":"<item_id>"}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions