OpenAI subscription stream failures are fatal after the first model event聽#19
Description
Problem
An OpenAI subscription response stream can terminate the ACP session after model output has started, even when the underlying failure is a transient response-body interruption. Kit retries the same failure before the first model event, but Kit 0.1.86 treated it as fatal after an event had been emitted.
Version
kit 0.1.86
Environment
- OS: Darwin 25.5.0
- Architecture: arm64
- Surface/host: ACP
- Provider:
openai-subscription
Reproduction
- Start an ACP session using
openai-subscription. - Begin a model turn and allow at least one
ModelTurnEventto be emitted. - Interrupt the HTTP response body before the provider sends
response.completed(for a deterministic test, serve an SSE response with a truncatedContent-Length).
The reported session ran for approximately 54 seconds after its last completed tool result before the response stream ended.
Actual behavior
The turn terminates with a fatal provider error and does not persist a completed assistant item:
openai-subscription stream transport failed
(timeout=false, connect=false, request=false, body=false, decode=true)
Sanitized fatal diagnostics:
{
"stage": "stream",
"retryable": false,
"attempt": 1,
"reqwest": {
"timeout": false,
"connect": false,
"request": false,
"body": false,
"decode": true
},
"source_chain": [
{ "kind": "hyper" },
{ "kind": "io", "classification": "unexpected_eof" }
]
}Reqwest reports decode=true because Response::bytes_stream() wraps response-body frame failures as decode errors. The low-level cause was unexpected_eof.
Expected behavior
Kit should recover from a transient post-event interruption without assuming that a non-deterministic model will replay the same SSE frames. After ACP v2 is available, Kit can replace the in-progress assistant message with the new authoritative response. Recovery must not duplicate text or reasoning, and tool calls must not execute twice.
Dependencies
- Blocked by feat(acp): add v2 mid-turn steering聽#24, which moves Kit's ACP integration to v2. The recovery design depends on ACP v2 message identity and replacement semantics; raw provider-frame replay is not a safe basis for recovery.
Related work
- Draft implementation: fix: replace interrupted OpenAI responses safely聽#10
- Earlier pre-event stream retry work:
8729c84
Activity
walker-tx commentedon Aug 26, 2026
Observed another occurrence on a newer Kit version.
Environment
0.1.91openai-subscriptionBehavior
An ordinary agent turn terminated with the existing fatal stream-transport error rather than completing:
The sanitized schema-v2 diagnostics reported stage
stream,retryable: false, attempt 1, reqwestdecode: truewith timeout/connect/request/body all false, followed by a Hyper source and an I/O source classified asunexpected_eof. The source chain was neither unknown nor truncated.This confirms the post-event
decode=true/unexpected_eoffailure remains reproducible in0.1.91. Kit marked it non-retryable on the first attempt.