fix(pixel-edge): accumulate trailing buffered content and synthesize fallback finish - #5608
Open
vaibhavsrv wants to merge 1 commit into
Open
vaibhavsrv wants to merge 1 commit into
vaibhavsrv wants to merge 1 commit into
Conversation
vaibhavsrv
force-pushed
the
fix/pixel-edge-buffered-stream-flush
branch
2 times, most recently
from
September 17, 2026 04:27
699b935 to
7706ffc
Compare
vaibhavsrv
force-pushed
the
fix/pixel-edge-buffered-stream-flush
branch
from
September 17, 2026 04:34
7706ffc to
1d5b5a8
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why this matters
In
ods/extensions/services/pixel-edge/pixel_edge.py,_stream_upstream()handles chunked Server-Sent Events (SSE) streaming from model inference runtimes, buffering text to detect and replace empty or reserved responses before streaming to client applications. When an upstream model finishes streaming and the final SSE event does not contain a trailing newline before EOF, the remaining bytes are parsed frombuffered(lines 1350-1362) and queued intopendingviaqueue_pending(line, event, content, finish_reason). However, unlike chunk processing in the main loop (line 1338),_stream_upstream()omitted updatingpending_text += contentfor this trailing chunk. Consequently, when a model finishes generation in a single un-terminated chunk or emits its final text across EOF,pending_textremains empty (""), triggering theif not normalized or normalized in _RESERVED_ASSISTANT_REPLIES:guard at line 1365. This causes the valid model response to be thrown away and replaced withempty_reply_fallback. Furthermore,replace_pending(template, synthesize_finish=False)at line 1370 passedsynthesize_finish=Falseat EOF, emitting the fallback payload without a terminalfinish_reason: "stop"chunk and leaving client SSE consumers stalled.This fix surgically accumulates
if content is not None: pending_text += contentwhen queuing trailingbufferedevents, preventing false-positive empty reply replacement of valid model answers. It also inspectshas_finish = any(item[3] is not None for item in pending)and synthesizes a terminal finish event when executing genuine empty reply fallback at EOF. Existing line length caps, prelude byte limits, and activity tracking remain untouched.Validation
b'data: {"model":"m","choices":[{"delta":{"content":"Tokyo"}}]}') leftpending_textas"", causing_stream_upstream()to replace "Tokyo" withempty_reply_fallbackwithout a finish reason ("finish_reason": null)."finish_reason": "stop"."[Pixel-edge] suites: 2 passed. New-test Ruff, ShellCheck, and diff checks pass; new regressions wired into Linux CI."Overlap check
fix(dashboard-api): recognize reasoning tokens and tool calls in pixel chat stream): Addressed dashboard SSE stream consumption for reasoning and tool tokens; does not touch edge runtime buffer parsing.fix(model-contract): coerce integer float token limits in projection): Addressed integer float coercion inods/bin/pixel_model_contract.py; does not touch edge streaming.fix(pixel-relay): return 502 bad gateway when upstream model router is unavailable): Addressed upstream connectivity error boundaries inpixel-model-relay; does not touch edge runtime chunk accumulation.fix(pixel-edge): accumulate content before finish reason in stream fallback guard): Focused on mid-stream finish reason precedence; this patch addresses EOF trailing buffer accumulation and terminal fallback synthesis.Risk / AI disclosure
AI-assisted investigation, implementation and CLI regressions. This strengthens SSE trailing buffer accumulation and fallback termination, not runtime admission. Independent human review and platform/runtime qualification remain gates. No running configuration, deployment or upstream merge changed.
Follow-up integration evidence
Composed with #5607 at 6e118f4 without conflicts. Production and test diffs passed together; pixel edge stream and single chunk checks remain intact.
Backlog composition was local-only (production/test diffs, excluding workflow/Makefile wiring); it is not an upstream merge or independent human approval. Declared live-review gates remain open.