Repository navigation
Conversation
Fabilin
requested changes
Nov 12, 2026
Fabilin
left a comment
Member
There was a problem hiding this comment.
Thank you for your contribution. Just a small comment regarding the new configuration 😉
| timeoutBetweenMessage?: number; | ||
| widgets?: { [id: string]: (props: unknown) => JSX.Element }; | ||
| disableSse?: boolean; | ||
| streamMode?: 'delta'; |
Member
There was a problem hiding this comment.
This new field is redundant, TockOptions already contains the network settings through inheritance. Most properties in this specific interface are legacy support.
isFrameOfOtherRequest only filtered correlated frames while a local request was in flight (inFlightRequestIds.size > 0). An idle tab thus accepted a foreign tab's partial frames, then rejected the rest once it sent its own question, leaving an orphan provisional bubble never finalized nor recorded. For the same reason a late frame arriving after the local request completed could still be handled. Drop the size > 0 guard: a correlated frame is accepted only while its request is in flight here. This also secures the error path - the request id is removed from the in-flight set in sendMessage's finally (on success or failure), so a late partial frame is now foreign and dropped, and can no longer reset error to false via the reducer. Frames without a request id (notifications) still always pass.
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.
Title: Support Tock RAG streaming: streamMode: 'delta' option and fix SSE response counting
Context
Tock's web connector can now stream RAG answers progressively on the regular /sse?userid= channel when tock_web_sse=true (server-side
change: Tock PR #2129). It uses the standard streaming contract TRK already knows:
No new event type or endpoint is introduced. This PR makes TRK handle that flow correctly and adds an optional, bandwidth-friendly
delta mode.
Changes
handleSseBotResponse counted every SSE frame, and handlePostBotResponse then sliced the POST response starting from that counter. With
N partial frames, a POST response arriving before the final SSE frame was sliced from index N and displayed nothing, and the final SSE
frame was then ignored.
Frames flagged TOCK_STREAM_RESPONSE=true are now handled but not counted. The POST response (or the final SSE frame) replaces the
message by RESPONSE_ID.
▎ Note for reviewers: with the Bot API streaming and tock_web_connector_merge_stream_response=false, frames carry fragments and the
▎ POST response re-dispatches them through UPDATE_MESSAGE. This is the one existing flow whose behavior I could not fully validate.
▎ Please check it on your side.
By default each frame carries the whole accumulated text (already rendered to HTML by the server). For long answers this transfers a
lot of redundant data. With streamMode: 'delta', TRK sends "streamMode": "delta" in the POST body and the server only sends the part of
the text that changed:
The server renders markdown exactly as in the default mode and sends the end of the rendered text, so the display is identical in both
modes (raw token fragments were tried first and abandoned: the display was condensed until the rendered final answer arrived).
Option wiring: TockOptions.streamMode, NetworkSettings.streamMode, copied by renderChat, and added to the POST body in useTock.ts only
when set.
streamMode documented in the NetworkSettings and renderChat options tables, and the "Streamed responses" section completed.
Backward compatibility
Testing
display, same rendering in both modes, final answer replaces the bubble with footnotes.