Keep open tool cards out of groups

This commit is contained in:
iris-ai committed 2026-09-15 22:43:45 -04:00
1 parent 33b130b6bb
commit 9bcf0f1a48
4 files changed
+55 -48

No files matched your search

@@ -97,15 +97,20 @@ sealed class TranscriptRow {
* A single call is left alone: "Called 1 tool" hides a card to say the same thing in more words,
* and the run this exists for is the burst of five greps nobody wants to scroll past.
*
* The last call is left alone too, and so is one still running wherever in its run it sits. What
* the session is doing, or did last, is the one thing worth seeing without opening anything, and a
* heading counting it hides it. What folds a call back into its run is therefore not finishing but
* being overtaken: anything arriving behind it, a reply included, makes it history.
* The last call is left alone too, as is one still running or one the reader has open, wherever in
* its run it sits. What the session is doing, did last, or is being read is the one thing worth
* seeing without a heading hiding it. A finished call therefore folds back into its run only once
* it has been overtaken and is closed.
*/
fun groupToolRuns(items: List<TranscriptItem>): List<TranscriptRow> =
DebugStats.timed("grouped tool runs") { groupRuns(items) }
fun groupToolRuns(
items: List<TranscriptItem>,
expandedTools: Set<String> = emptySet(),
): List<TranscriptRow> = DebugStats.timed("grouped tool runs") { groupRuns(items, expandedTools) }
private fun groupRuns(items: List<TranscriptItem>): List<TranscriptRow> {
private fun groupRuns(
items: List<TranscriptItem>,
expandedTools: Set<String>,
): List<TranscriptRow> {
val rows = mutableListOf<TranscriptRow>()
var run = mutableListOf<TranscriptItem.ToolRun>()
// The run being walked, and how many rows it has produced so far -- which is what decides the
@@ -143,9 +148,9 @@ private fun groupRuns(items: List<TranscriptItem>): List<TranscriptRow> {
when {
call == null -> rows += TranscriptRow.Single(item)
// Standing outside the run is the call's place in the list as it is now, not something
// recorded on the call: the same finished call is a row of its own while it is the last
// thing that happened and part of its group once a reply lands behind it.
call.done && index != items.lastIndex -> run += call
// recorded on the call: the same finished call is a row of its own while it is last or
// open, and part of its group once something follows it and the reader closes it.
call.done && call.id !in expandedTools && index != items.lastIndex -> run += call
else -> {
flush()
run += call