Issue
chat-streaming.js guards its post-stream message reload on a function that does not exist, so the reload never happens.
Both call sites look like this:
if (finalData.reload_messages && finalData.conversation_id
&& typeof window.chatMessages?.loadMessages === 'function') {
window.chatMessages.loadMessages(finalData.conversation_id);
}
application/single_app/static/js/chat/chat-streaming.js:1449 (generated-image branch)
application/single_app/static/js/chat/chat-streaming.js:1515 (standard assistant branch)
window.chatMessages is assigned in chat-messages.js and exposes exactly six functions:
window.chatMessages = {
applyMaskedState,
applySearchHighlight,
appendMessage,
clearSearchHighlight,
extractSuggestedFollowUpPrompts,
scrollToMessageSmooth
};
loadMessages is not among them. typeof is therefore always undefined, the condition is always false, and the reload is dead code.
git log -S "loadMessages," on chat-messages.js returns nothing, so loadMessages was never exported on that object. This is not a regression — the guard has never worked since it was introduced in commit 54e37c87 ("made streaming primary").
Expected Behavior
When the backend signals reload_messages: true, the browser should refetch the conversation so messages the plugin persisted directly into Cosmos become visible without a manual page reload.
Actual Behavior
Nothing happens. Those messages stay invisible until the user reloads the page or reselects the conversation.
What sets reload_messages
route_backend_chats.py:20082 sends 'reload_messages': reload_messages_required, which is set at route_backend_chats.py:19283-19287 when any agent plugin result trips result_requires_message_reload(). That helper is documented as:
"Heuristically detect plugin outputs that inject new Cosmos messages (e.g., chart images)."
It returns True for payloads carrying reload_messages, requires_message_reload, metadata.requires_message_reload, a non-empty image_url, type == 'image_url', or a mime starting with image/ — recursively through dicts and lists.
Impact — needs sizing before a fix
Impact is likely narrower than it first appears, and should be measured rather than assumed:
- The final-payload handler separately renders
finalData.image_url via appendMessage('image', ...) at chat-streaming.js:1433, so a single generated chart probably still displays.
- The breakage is limited to additional message documents a plugin persisted beyond what the streaming payload carries.
Collaborative conversations are not affected by this specific path: the collaboration bridge sets 'reload_messages': bool(stream_payload.get('error')), and any payload carrying error short-circuits earlier at processStreamData's if (data.error) branch.
Suggested Approach
- Build a repro: a plugin whose result trips
result_requires_message_reload() and writes an extra message document, then confirm what is actually missing from the transcript.
- Only then decide the fix. Exporting
loadMessages on window.chatMessages is a one-line change, but it switches on a code path that has never executed in production — worth checking for double-rendering, scroll jumps, or interference with streaming state before enabling it.
- Add a functional test asserting the guarded symbol is actually exported, so a dead guard like this cannot ship again.
Notes
Found while fixing #1281 (PR #1283). Deliberately left out of that PR because it is unrelated to the shared-conversation defects and needs a repro to size correctly.
Issue
chat-streaming.jsguards its post-stream message reload on a function that does not exist, so the reload never happens.Both call sites look like this:
application/single_app/static/js/chat/chat-streaming.js:1449(generated-image branch)application/single_app/static/js/chat/chat-streaming.js:1515(standard assistant branch)window.chatMessagesis assigned inchat-messages.jsand exposes exactly six functions:loadMessagesis not among them.typeofis therefore alwaysundefined, the condition is always false, and the reload is dead code.git log -S "loadMessages,"onchat-messages.jsreturns nothing, soloadMessageswas never exported on that object. This is not a regression — the guard has never worked since it was introduced in commit54e37c87("made streaming primary").Expected Behavior
When the backend signals
reload_messages: true, the browser should refetch the conversation so messages the plugin persisted directly into Cosmos become visible without a manual page reload.Actual Behavior
Nothing happens. Those messages stay invisible until the user reloads the page or reselects the conversation.
What sets
reload_messagesroute_backend_chats.py:20082sends'reload_messages': reload_messages_required, which is set atroute_backend_chats.py:19283-19287when any agent plugin result tripsresult_requires_message_reload(). That helper is documented as:It returns
Truefor payloads carryingreload_messages,requires_message_reload,metadata.requires_message_reload, a non-emptyimage_url,type == 'image_url', or amimestarting withimage/— recursively through dicts and lists.Impact — needs sizing before a fix
Impact is likely narrower than it first appears, and should be measured rather than assumed:
finalData.image_urlviaappendMessage('image', ...)atchat-streaming.js:1433, so a single generated chart probably still displays.Collaborative conversations are not affected by this specific path: the collaboration bridge sets
'reload_messages': bool(stream_payload.get('error')), and any payload carryingerrorshort-circuits earlier atprocessStreamData'sif (data.error)branch.Suggested Approach
result_requires_message_reload()and writes an extra message document, then confirm what is actually missing from the transcript.loadMessagesonwindow.chatMessagesis a one-line change, but it switches on a code path that has never executed in production — worth checking for double-rendering, scroll jumps, or interference with streaming state before enabling it.Notes
Found while fixing #1281 (PR #1283). Deliberately left out of that PR because it is unrelated to the shared-conversation defects and needs a repro to size correctly.