mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-09-16 11:52:26 +03:00
Extend the Claude empty-response detector in open-sse/utils/stream.ts to also catch an upstream connection that opens (HTTP 200) and closes having sent literally zero bytes -- no message_start at all. The existing hasClaudeAssistantLifecycle() gate only fired once a lifecycle event had been observed, so this shape silently completed the client stream with a 200 and no content instead of surfacing a 502, matching the reported symptom for claude-fable-5-max past ~1800 messages. New streamClaudeEmptyBody.ts module keeps the frozen stream.ts file size unchanged while adding the combined partial-lifecycle + truly-empty check.
35 lines
1.4 KiB
TypeScript
35 lines
1.4 KiB
TypeScript
/**
|
|
* #12398 — decides whether a Claude-format stream must be aborted with an
|
|
* upstream error at flush time because the client got no usable content.
|
|
*
|
|
* Covers two shapes:
|
|
* - "partial lifecycle": message_start (and optionally message_delta /
|
|
* message_stop) arrived but no content block ever did — this was already
|
|
* correctly handled before #12398 and is preserved here unchanged.
|
|
* - "truly empty": the upstream connection closed having sent literally
|
|
* zero bytes (HTTP 200, not even a message_start). The lifecycle flags
|
|
* above can never catch this shape since none of them are ever set — the
|
|
* caller must additionally know whether ANY upstream chunk ever arrived.
|
|
*
|
|
* Callers must additionally require a Claude-format client (this function
|
|
* does not take that flag — both call sites in stream.ts only ever reach
|
|
* here already scoped to a Claude-format response).
|
|
*/
|
|
type ClaudeEmptyLifecycleLike = {
|
|
hasError: boolean;
|
|
hasContentBlock: boolean;
|
|
hasMessageStart: boolean;
|
|
hasMessageDelta: boolean;
|
|
hasMessageStop: boolean;
|
|
};
|
|
|
|
export function shouldAbortEmptyClaudeStream(
|
|
lifecycle: ClaudeEmptyLifecycleLike,
|
|
sawAnyUpstreamPayload: boolean
|
|
): boolean {
|
|
if (lifecycle.hasError || lifecycle.hasContentBlock) return false;
|
|
const hasPartialLifecycle =
|
|
lifecycle.hasMessageStart || lifecycle.hasMessageDelta || lifecycle.hasMessageStop;
|
|
return hasPartialLifecycle || !sawAnyUpstreamPayload;
|
|
}
|