@@ -660,6 +660,29 @@ Each scenario is documented in this format:
660660- **Status**: Unit-covered (preset matching, catalog aliases, Completions
661661 compat); rendered UI scenario Draft
662662
663+ #### E2E-248: Responses turn completes without waiting for the server to close the connection
664+
665+ - **Preconditions**: A provider whose model pins `api: "openai-responses"` (or
666+ a provider with `apiStyle: "responses"`) is configured; the endpoint is
667+ fronted by a proxy that holds the HTTP connection open after the final
668+ SSE event (a local reverse proxy or a stub server that never sends FIN).
669+ - **Steps**: 1) Start a session with that model and send a short prompt. 2)
670+ Capture the SSE frames and confirm the server emitted
671+ `response.completed` with `status: "completed"` and usage. 3) Keep the
672+ stub/proxy connection open without sending a TCP FIN. 4) Observe the
673+ assistant turn state and send a follow-up prompt.
674+ - **Expected**: The turn completes as soon as `response.completed` is
675+ finalized: usage is recorded, `stopReason` is `stop`, and the client stops
676+ consuming the stream (the underlying request is aborted) instead of
677+ blocking on the idle connection. The composer becomes idle immediately and
678+ the follow-up turn starts normally. The stream must not hang when the
679+ server never closes the connection.
680+ - **Specs linked**: `03-runtime/11-provider-model-system.md` (§16.1)
681+ - **Acceptance**: B (provider Responses compatibility)
682+ - **Milestone**: M2
683+ - **Status**: Unit-covered (stream processor terminates on the terminal
684+ event via the pi-ai patch); live-proxy scenario Draft
685+
663686#### E2E-005E: DeepSeek thinking replay includes reasoning_content on aggregator endpoints
664687
665688- **Preconditions**: An OpenAI-compatible provider whose base URL is not
0 commit comments