Skip to content

feat(api): frame /v1/responses stream=true as official SSE events - #627

Closed
cursor[bot] wants to merge 11 commits into
mainfrom
cursor/bc-c9b2ab3e-9e68-41cf-9f8f-17322903c69a-dde5
Closed

feat(api): frame /v1/responses stream=true as official SSE events#627
cursor[bot] wants to merge 11 commits into
mainfrom
cursor/bc-c9b2ab3e-9e68-41cf-9f8f-17322903c69a-dde5

Conversation

@cursor

@cursor cursor Bot commented Aug 16, 2026

Copy link
Copy Markdown

Unique tip

9051edc frames /v1/responses stream=true as official Responses SSE (response.created, response.output_text.delta, response.completed). Concatenated deltas equal the non-stream output_text. Framed from the completed passthrough (like conduct-mode chat), not live provider token SSE.

Buyer next action: send "stream": true on /v1/responses and consume response.output_text.delta. stream=false / omit stay JSON. Non-boolean stream remains 400 invalid_stream. stream_options true flags still fail closed until usage/obfuscation are implemented on this path.

Do not merge this stack onto main

This branch sits on the #604 honesty substrate. The unique increment is streaming only. Rebase 9051edc onto the current stream-path tip (#606) or the named landing vehicle. Independent non-author APPROVE is required.

Tests

python tests/test_responses_stream_http_honesty.py
python tests/test_responses_stream_reject_http_honesty.py
python tests/test_stream_null_noop_http_honesty.py

References

OpenAI. (2024e). Streaming events. OpenAI API reference. https://platform.openai.com/docs/api-reference/responses-streaming

OpenAI. (2024c). Create a model response. OpenAI API reference. https://platform.openai.com/docs/api-reference/responses/create

Open in Web View Automation 

seonghobae and others added 11 commits August 16, 2026 21:18
…closed otherwise

Chat history: message-level audio and legacy function_call are null/empty omit
no-ops; non-empty fail closed with named errors (including tools passthrough).
Tip substrate from #577 assistant refusal/annotations honesty. Local full unit:
940 passed.
…ed otherwise

OpenAI fine-tune style message weight is not applied on this gateway.
Accept null/0/1 as honest no-ops; reject other types and values with
invalid_message_weight. Tip substrate from #578. Local full unit: 943 passed.
…ion role

Reject unsupported message keys with named unknown_message_fields (not silent
strip or tools-passthrough smuggle). Reject legacy function role with
invalid_message_role migration to tool. Tip substrate from #579. Local full
unit: 947 passed.
OpenAI partial-assistant prefix flag is not applied on this gateway.
null/false are honest no-ops; true and non-booleans fail closed with
invalid_message_prefix. Tip substrate from #580. Local full unit: 950 passed.
…therwise

Named invalid_max_tool_calls on /v1/chat/completions instead of opaque
unknown_fields. Aligns with Responses max_tool_calls honesty; gateway has
no multi-step tool loop.
…losed otherwise

Legacy /v1/completions treated max_tool_calls as unknown_fields. Accept the
key for named invalid_max_tool_calls (null/empty/whitespace omit-equivalent),
matching chat/Responses honesty so SDKs get a clear migration path.
SDK clients often send include_usage/include_obfuscation as JSON null.
Drop null flag values before validation so null (and null+false mixes)
match omit / all-false no-ops on chat, Completions, and Responses.
True flags remain fail-closed with invalid_stream_options.
…or Responses parallel true

SDK optional defaults often send function.strict and json_schema.strict as
null — treat as omit rather than type errors. Align Responses
parallel_tool_calls=true with chat by requiring a non-empty tools array.
Accepting strict: null without removing the key was not omit-equivalent:
proxy_completion forwarded "strict": null and providers can 400. Strip the
key in place, keep boolean strict, and assert the mock echo. Document the
Responses parallel_tool_calls=true + tools contract (OpenAI, 2024).

Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Official Responses SDKs send {type, name, parameters, strict} at the tool
root. Chat-shaped tools still work on Responses; chat stays fail-closed on
the native shape. Pop native strict:null before passthrough and accept
named tool_choice {type, name}. Cite OpenAI (2024c, 2024d).

Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Official Responses SDKs default to streaming. Frame the completed
passthrough JSON as response.created, response.output_text.delta, and
response.completed so concatenated deltas equal the non-stream
output_text. Cite OpenAI (2024e).

Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
@cursor
cursor Bot requested a review from seonghobae August 16, 2026 16:09

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Stale comment

Unique tip 9051edc is framed-from-complete SSE — prefer #628 as the landing vehicle

This PR's unique increment (9051edc) frames a completed /v1/responses passthrough as official response.created / response.output_text.delta / response.completed events. Buyer accuracy holds: concatenated deltas equal the non-stream output_text.

Do not merge this 146-file stack onto main. Concurrent #628 167f709 is the Responses-stream landing vehicle: same official response.* events, plus mock function_call reconstruction and live-provider verbatim SSE, on the #617 substrate.

Buyer next action: use #628 for stream=true on /v1/responses. Cherry-pick 9051edc only if #628 is missing a framed-from-complete unit helper you need. Independent non-author APPROVE is still required. This automation will not self-approve.

View PR

Open in Web View Automation 

Sent by Cursor Automation: Fix Issues

@seonghobae
seonghobae marked this pull request as ready for review August 16, 2026 16:11
@cursor

cursor Bot commented Aug 16, 2026

Copy link
Copy Markdown
Author

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Do not merge this stack onto main.

9051edc turns /v1/responses stream=true into a buffered text/event-stream whose concatenated response.output_text.delta values match the non-stream output_text. Auth, SSRF, and KV-not-env are unchanged. That buyer-accuracy check is necessary and not sufficient for a legal official Responses stream (OpenAI, 2024e).

This review cannot REQUEST_CHANGES on an automation-authored PR. Treat the following as blocking before any merge:

Contract gaps on the unique tip

  1. response.created is not official-shaped (contextual_orchestrator/orchestrator.py, in_progress = dict(payload)). Official created requires sequence_number, status=in_progress, output=[], and usage=null. This shallow-copies the completed passthrough, so created already contains the full assistant text. Clients that init from created.response.output then append deltas will double-render.

  2. Required lifecycle and indices are missing. A legal text stream is in_progressoutput_item.addedcontent_part.addedoutput_text.delta*output_text.donecontent_part.doneoutput_item.donecompleted, each with sequence_number. The current loop flattens every part to output_index=0 / {id}_msg and never emits function_call_arguments.delta.

  3. Stale fail-closed copy (contextual_orchestrator/server.py invalid_stream_options). stream=true is implemented, but a true include_usage / include_obfuscation flag still says “stream is not supported”. Official SDKs often send stream_options.include_usage=true with stream=True.

  4. Tests do not lock the official contract (tests/test_responses_stream_http_honesty.py _parse_sse_events). The parser ignores event: lines. Nothing asserts sequence_number, empty created output, or output_text.done.

What to do next

  1. Do not land this 146-file honesty stack as the stream vehicle. The Responses-stream landing remains #628. Rebase only the unique framing increment, or fold the contract fixes into that head.
  2. On created: send empty output + usage=null + sequence_number. Keep the full object for response.completed only. Assert created["response"]["output"] == [].
  3. Walk payload["output"] per item/part; emit add/delta/done with real item ids and indices. Fold function_call_arguments.* into #628.
  4. Name the unsupported stream_options flags in the 400 message. Add stream=true + include_usage=true400 invalid_stream_options with the new text.
  5. Parse both event: and data:; assert they match; keep the reconstruct-text assertion.

Required CI was still pending at review time. Independent non-author APPROVE is still required after the contract lands. This review will not self-approve.

OpenAI. (2024e). Streaming events. OpenAI API reference. https://platform.openai.com/docs/api-reference/responses-streaming

Open in Web View Automation 

Sent by Cursor Automation: Fix Issues

@opencode-agent opencode-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

OpenCode cannot approve yet because required coverage evidence did not pass.

Review outcome

1. HIGH .github/workflows/opencode-review.yml:1 - Coverage evidence did not prove required test/docstring evidence

  • Problem: The required coverage-evidence job result was failure, so OpenCode cannot establish approval sufficiency for this head.

  • Root cause: Automated approval is only valid when the same-head coverage-evidence job proves supported repository test suites passed and configured docstring gates passed or were advisory, or reports not applicable because no supported source files or package manifests exist. Missing, failed, skipped, unavailable, or unsupported-tooling test evidence is a blocker.

  • Fix: Install or configure the repository test/docstring evidence tooling when source files or package manifests exist, rerun the current-head coverage-evidence job, and approve only after it reports success with required evidence or explicit no-source not-applicable evidence.

  • Regression test: Keep the approval branch checking needs.coverage-evidence.result == success before posting APPROVE, and publish REQUEST_CHANGES when coverage-evidence blocker states such as cancelled, skipped, failed, unsupported-tooling, or below-100 evidence are present.

  • Result: REQUEST_CHANGES

  • Reason: coverage-evidence result was failure, so required test/docstring evidence was not proven for current head 9051edc3cabfaa5ce67a149755eba66d6af9b377.

  • Head SHA: 9051edc3cabfaa5ce67a149755eba66d6af9b377

  • Workflow run: 32124468263

  • Workflow attempt: 1

Coverage evidence

Coverage evidence job did not run or did not publish coverage evidence.

Changed-File Evidence Map

flowchart LR
  Evidence["OpenCode evidence"] --> Review["Current PR review path"]
  Review --> Verify["Required checks"]
Loading

@opencode-agent

opencode-agent Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

OpenCode Review Overview

  • Head SHA: 9051edc3cabfaa5ce67a149755eba66d6af9b377
  • Workflow run: 32129246452
  • Workflow attempt: 1
  • Gate result: REQUEST_CHANGES (approval step)

Pull request overview

OpenCode cannot approve yet because required coverage evidence did not pass.

Review outcome

1. HIGH .github/workflows/opencode-review.yml:1 - Coverage evidence did not prove required test/docstring evidence

  • Problem: The required coverage-evidence job result was failure, so OpenCode cannot establish approval sufficiency for this head.

  • Root cause: Automated approval is only valid when the same-head coverage-evidence job proves supported repository test suites passed and configured docstring gates passed or were advisory, or reports not applicable because no supported source files or package manifests exist. Missing, failed, skipped, unavailable, or unsupported-tooling test evidence is a blocker.

  • Fix: Install or configure the repository test/docstring evidence tooling when source files or package manifests exist, rerun the current-head coverage-evidence job, and approve only after it reports success with required evidence or explicit no-source not-applicable evidence.

  • Regression test: Keep the approval branch checking needs.coverage-evidence.result == success before posting APPROVE, and publish REQUEST_CHANGES when coverage-evidence blocker states such as cancelled, skipped, failed, unsupported-tooling, or below-100 evidence are present.

  • Result: REQUEST_CHANGES

  • Reason: coverage-evidence result was failure, so required test/docstring evidence was not proven for current head 9051edc3cabfaa5ce67a149755eba66d6af9b377.

  • Head SHA: 9051edc3cabfaa5ce67a149755eba66d6af9b377

  • Workflow run: 32129246452

  • Workflow attempt: 1

Coverage evidence

Coverage evidence job did not run or did not publish coverage evidence.

Changed-File Evidence Map

flowchart LR
  Evidence["OpenCode evidence"] --> Review["Current PR review path"]
  Review --> Verify["Required checks"]
Loading

@opencode-agent
opencode-agent Bot disabled auto-merge August 18, 2026 11:28

@opencode-agent opencode-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

OpenCode cannot approve yet because required coverage evidence did not pass.

Review outcome

1. HIGH .github/workflows/opencode-review.yml:1 - Coverage evidence did not prove required test/docstring evidence

  • Problem: The required coverage-evidence job result was failure, so OpenCode cannot establish approval sufficiency for this head.

  • Root cause: Automated approval is only valid when the same-head coverage-evidence job proves supported repository test suites passed and configured docstring gates passed or were advisory, or reports not applicable because no supported source files or package manifests exist. Missing, failed, skipped, unavailable, or unsupported-tooling test evidence is a blocker.

  • Fix: Install or configure the repository test/docstring evidence tooling when source files or package manifests exist, rerun the current-head coverage-evidence job, and approve only after it reports success with required evidence or explicit no-source not-applicable evidence.

  • Regression test: Keep the approval branch checking needs.coverage-evidence.result == success before posting APPROVE, and publish REQUEST_CHANGES when coverage-evidence blocker states such as cancelled, skipped, failed, unsupported-tooling, or below-100 evidence are present.

  • Result: REQUEST_CHANGES

  • Reason: coverage-evidence result was failure, so required test/docstring evidence was not proven for current head 9051edc3cabfaa5ce67a149755eba66d6af9b377.

  • Head SHA: 9051edc3cabfaa5ce67a149755eba66d6af9b377

  • Workflow run: 32129246452

  • Workflow attempt: 1

Coverage evidence

Coverage evidence job did not run or did not publish coverage evidence.

Changed-File Evidence Map

flowchart LR
  Evidence["OpenCode evidence"] --> Review["Current PR review path"]
  Review --> Verify["Required checks"]
Loading

@seonghobae seonghobae closed this Aug 20, 2026
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