Keep tool group keys unique across transcript
This commit is contained in:
1 parent
f00a178cf0
commit
947ea8ecf2
2 files changed
+35
-12
No files matched your search
@@ -113,24 +113,27 @@ private fun groupRuns(
|
|||||||
): List<TranscriptRow> {
|
): List<TranscriptRow> {
|
||||||
val rows = mutableListOf<TranscriptRow>()
|
val rows = mutableListOf<TranscriptRow>()
|
||||||
var run = mutableListOf<TranscriptItem.ToolRun>()
|
var run = mutableListOf<TranscriptItem.ToolRun>()
|
||||||
// The run being walked, and how many rows it has produced so far -- which is what decides the
|
// A run can occupy more than one non-adjacent piece, so claimed keys span the whole transcript
|
||||||
// keys below.
|
// rather than resetting at each piece.
|
||||||
var runId: String? = null
|
var runId: String? = null
|
||||||
var emitted = 0
|
val claimedKeys = mutableSetOf<String>()
|
||||||
|
|
||||||
fun flush() {
|
fun flush() {
|
||||||
val first = run.firstOrNull() ?: return
|
val first = run.firstOrNull() ?: return
|
||||||
// The first row a run produces keeps the run's name, which is the name that survives a page
|
// The first piece keeps the run's name, which survives a page landing in front of it
|
||||||
// of history landing in front of it ([adoptRun]); losing it is the transcript stepping
|
// ([adoptRun]). Later pieces qualify that name with their first call; the suffix is the
|
||||||
// under whoever is reading. The pieces a call standing on its own cuts off the back of the
|
// final guard because a duplicate LazyColumn key takes down the whole screen.
|
||||||
// run have no such name, so each takes its own first call's id, which is unique because a
|
var key = first.runId
|
||||||
// call id is. The run's name goes in front of it because the two can otherwise be the same
|
if (!claimedKeys.add(key)) {
|
||||||
// string: the call a run was named after can itself be the one standing on its own.
|
key = "${first.runId}/${first.id}"
|
||||||
val key = if (emitted == 0) first.runId else "${first.runId}/${first.id}"
|
var suffix = 2
|
||||||
|
while (!claimedKeys.add(key)) {
|
||||||
|
key = "${first.runId}/${first.id}/${suffix++}"
|
||||||
|
}
|
||||||
|
}
|
||||||
rows +=
|
rows +=
|
||||||
if (run.size == 1) TranscriptRow.Single(first, key)
|
if (run.size == 1) TranscriptRow.Single(first, key)
|
||||||
else TranscriptRow.Tools(run.toList(), key)
|
else TranscriptRow.Tools(run.toList(), key)
|
||||||
emitted++
|
|
||||||
run = mutableListOf()
|
run = mutableListOf()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,7 +146,6 @@ private fun groupRuns(
|
|||||||
if (call == null || call.runId != runId) {
|
if (call == null || call.runId != runId) {
|
||||||
flush()
|
flush()
|
||||||
runId = call?.runId
|
runId = call?.runId
|
||||||
emitted = 0
|
|
||||||
}
|
}
|
||||||
when {
|
when {
|
||||||
call == null -> rows += TranscriptRow.Single(item)
|
call == null -> rows += TranscriptRow.Single(item)
|
||||||
|
|||||||
@@ -111,6 +111,27 @@ class ToolRowsTest {
|
|||||||
assertEquals("b", rows.first().key)
|
assertEquals("b", rows.first().key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun a_run_that_reappears_after_another_row_keeps_distinct_keys() {
|
||||||
|
val rows =
|
||||||
|
groupToolRuns(
|
||||||
|
listOf(
|
||||||
|
call("older", runId = "exec-1"),
|
||||||
|
call("older-2", runId = "exec-1"),
|
||||||
|
reply(),
|
||||||
|
call("exec-1", runId = "exec-1"),
|
||||||
|
call("newer", runId = "exec-1"),
|
||||||
|
reply(),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
assertTrue(rows[0] is TranscriptRow.Tools, "$rows")
|
||||||
|
assertTrue(rows[2] is TranscriptRow.Tools, "$rows")
|
||||||
|
assertKeysDistinct(rows)
|
||||||
|
assertEquals("exec-1", rows[0].key)
|
||||||
|
assertEquals("exec-1/exec-1", rows[2].key)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finishing is not what folds a call back in -- being overtaken is. A session that has run its
|
* Finishing is not what folds a call back in -- being overtaken is. A session that has run its
|
||||||
* last command and is writing its reply leaves that command standing until the reply starts.
|
* last command and is writing its reply leaves that command standing until the reply starts.
|
||||||
|
|||||||
Reference in new issue
Block a user