Skip to content

Post-stream message reload is dead code: window.chatMessages.loadMessages is never exported #1286

Description

@paullizer

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

  1. 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.
  2. 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.
  3. 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.

Metadata

Metadata

Labels

bugSomething isn't working

Type

No type

Projects

Status
Pending Evaluation

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions