Skip to content

Commit a8ef922

Browse files
committed
fix(runner): flush assistant text per message to preserve session replay interleaving
Previously runInner accumulated all assistant text into a single strings.Builder and only wrote one assistant entry at the end of the run. Tool calls were recorded eagerly, so replaying a session saw all tools collapse into one big activity group and the intermediate assistant progress messages disappeared. Flush the builder after each streaming/non-streaming assistant message so the JSONL keeps the real message/tool interleaving. Session history reconstruction already handles content before/after tool calls correctly. Fixes the 'message grouped into activity group after switching sessions' issue in the desktop/web UI.
1 parent 55ff916 commit a8ef922

1 file changed

Lines changed: 16 additions & 0 deletions

File tree

internal/runner/runner.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,14 @@ func runInner(
438438
h.OnAgentText(chunk.Content)
439439
}
440440
}
441+
// Flush assistant text at the end of each assistant message so the
442+
// session file preserves the true message/tool interleaving. Without
443+
// this, the whole run accumulates into a single assistant entry and
444+
// replay collapses all surrounding tool calls into one big group.
445+
if rec != nil && assistantText.Len() > 0 {
446+
rec.RecordAssistant(assistantText.String())
447+
assistantText.Reset()
448+
}
441449
// Notify and record accumulated tool calls in index order.
442450
// All tool calls from this assistant message form one batch.
443451
indices := make([]int, 0, len(pending))
@@ -490,9 +498,17 @@ func runInner(
490498
assistantText.WriteString(mo.Message.Content)
491499
h.OnAgentText(mo.Message.Content)
492500
}
501+
// Flush non-streaming assistant text immediately so each assistant
502+
// message is a distinct session entry with its surrounding tool calls.
503+
if rec != nil && assistantText.Len() > 0 {
504+
rec.RecordAssistant(assistantText.String())
505+
assistantText.Reset()
506+
}
493507
}
494508
}
495509

510+
// Final safety flush for any remaining text (e.g. returns above that skip
511+
// the per-message flush, or trailing content after the last tool batch).
496512
if rec != nil && assistantText.Len() > 0 {
497513
rec.RecordAssistant(assistantText.String())
498514
}

0 commit comments

Comments
 (0)