Bug description
After a WebUI assistant turn completes, content that was visible while/just after streaming can appear to disappear from the chat transcript. In the observed case, the user specifically requested Markdown diff blocks; the assistant produced a final answer with multiple fenced diff blocks, but after completion those diff boxes were no longer visible in the WebUI. Live tool-call messages/cards also appeared to disappear.
Important: the backend/session data still contained the content. This appears to be a frontend settled-render/reconciliation issue, not data loss.
Observed evidence
A local WebUI session was inspected through the API after the UI no longer showed the expected content. The API response still contained:
- A persisted assistant message with the requested diff-heavy final answer.
- Multiple Markdown fences, including fenced
diff blocks.
- Session-level
tool_calls metadata.
- Additional persisted
role: "tool" transcript rows.
So the content existed in the API response but was not reliably visible in the completed transcript UI.
Steps to reproduce / scenario
- In WebUI, ask the agent to perform a multi-step task with tool calls and request that edits be shown in Markdown diff blocks.
- Agent streams progress, tool activity, and a final assistant answer with fenced
diff blocks.
- After completion / settled render / session refresh, inspect the visible chat transcript.
- Some requested output that was visible earlier (diff boxes) may no longer be visible; live tool-call messages/cards also appear to be removed or not reconstructed in an equivalent settled view.
- Fetching
GET /api/session?session_id=<sid> shows the data is still in the session payload.
Expected behavior
- Final assistant Markdown that is persisted in
session.messages should remain visible after stream completion and any active-session refresh.
- Requested fenced diff blocks should not disappear from the visible transcript.
- If raw
role: "tool" messages are intentionally hidden, the settled Activity/tool-card view should preserve enough visible affordance/details that the user does not perceive tool activity as disappearing.
Actual behavior
- The persisted assistant answer still contains the requested diff blocks, but the WebUI view made them appear to disappear after completion.
- Raw tool rows are present in
session.messages, and session-level tool_calls exists, but visible live tool activity can vanish or change substantially once done triggers settled rendering.
Relevant code paths / suspected areas
Recent commits in this area look relevant:
Frontend render paths observed locally:
static/messages.js done handler replaces local stream state with d.session.messages, clears live tool cards, sets S.busy=false, then calls renderMessages({preserveScroll:true}).
static/sessions.js::refreshActiveSessionIfExternallyUpdated() can call loadSession(sid, {force:true, externalRefreshReason: ...}) after completion/focus/poll.
static/ui.js::renderMessages() intentionally filters role === "tool" messages out of visible transcript:
const vis=S.messages.filter(m=>{
if(!m||!m.role||m.role==='tool')return false;
...
});
and:
for(const m of S.messages){
if(!m||!m.role||m.role==='tool'){rawIdx++;continue;}
...
}
Settled tool cards are then reconstructed from S.toolCalls / per-message metadata. The bug may be in one of:
- live stream DOM -> settled session DOM replacement;
- active-session external refresh overwriting the DOM with a different render window/scroll state;
- message windowing / “Load earlier messages” hiding content unexpectedly;
- raw
tool rows being hidden while settled Activity reconstruction does not preserve the user-visible live evidence;
- Markdown render/post-processing for long diff-heavy messages after DOM replacement.
Debug notes
This was verified with direct API inspection, not just visual observation. The diff-heavy answer was still present in session.messages, so a fix should likely focus on frontend render/reconciliation/scroll/windowing rather than backend persistence.
I just want to say, however, how impressed I am with this project, and particularly how far it has come in the 2-3 weeks I've been using it.
Bug description
After a WebUI assistant turn completes, content that was visible while/just after streaming can appear to disappear from the chat transcript. In the observed case, the user specifically requested Markdown diff blocks; the assistant produced a final answer with multiple fenced
diffblocks, but after completion those diff boxes were no longer visible in the WebUI. Live tool-call messages/cards also appeared to disappear.Important: the backend/session data still contained the content. This appears to be a frontend settled-render/reconciliation issue, not data loss.
Observed evidence
A local WebUI session was inspected through the API after the UI no longer showed the expected content. The API response still contained:
diffblocks.tool_callsmetadata.role: "tool"transcript rows.So the content existed in the API response but was not reliably visible in the completed transcript UI.
Steps to reproduce / scenario
diffblocks.GET /api/session?session_id=<sid>shows the data is still in the session payload.Expected behavior
session.messagesshould remain visible after stream completion and any active-session refresh.role: "tool"messages are intentionally hidden, the settled Activity/tool-card view should preserve enough visible affordance/details that the user does not perceive tool activity as disappearing.Actual behavior
session.messages, and session-leveltool_callsexists, but visible live tool activity can vanish or change substantially oncedonetriggers settled rendering.Relevant code paths / suspected areas
Recent commits in this area look relevant:
Frontend render paths observed locally:
static/messages.jsdonehandler replaces local stream state withd.session.messages, clears live tool cards, setsS.busy=false, then callsrenderMessages({preserveScroll:true}).static/sessions.js::refreshActiveSessionIfExternallyUpdated()can callloadSession(sid, {force:true, externalRefreshReason: ...})after completion/focus/poll.static/ui.js::renderMessages()intentionally filtersrole === "tool"messages out of visible transcript:and:
Settled tool cards are then reconstructed from
S.toolCalls/ per-message metadata. The bug may be in one of:toolrows being hidden while settled Activity reconstruction does not preserve the user-visible live evidence;Debug notes
This was verified with direct API inspection, not just visual observation. The diff-heavy answer was still present in
session.messages, so a fix should likely focus on frontend render/reconciliation/scroll/windowing rather than backend persistence.I just want to say, however, how impressed I am with this project, and particularly how far it has come in the 2-3 weeks I've been using it.