Keep the running tool call outside its group

A run of adjacent calls is drawn as one collapsed card, which hid the one
thing worth seeing without opening anything: the command the session is
running right now. It is a row of its own while it runs and folds back into
the run when it ends.

Grouping stays a display decision, so the pieces a running call cuts a run
into are keyed there. The first piece keeps the run's name -- that name is
what survives a page of history landing in front of it -- and later pieces
take their own first call's id behind it, since the call a run was named
after can itself be the one running.

The echo rig's /tools gap now runs between a call's start and its end rather
than between one call and the next, which is where a real session's time goes
and what makes the running state observable at all.

Checked with ktfmtFormat, compileDebugKotlin, testDebugUnitTest (new
ToolRowsTest) and lintDebug, cargo fmt/clippy/test, and on the emulator
against the sandbox: "Called 2 tools" with the live Bash card beneath it.
This commit is contained in:
iris-ai committed 2026-09-15 01:13:03 -04:00
1 parent b9b777acaf
commit 036eb375aa
5 files changed
+172 -45

No files matched your search

+10 -8
View File
@@ -601,10 +601,15 @@ impl EchoDriver {
.and_then(|w| w.parse().ok())
.unwrap_or(3usize)
.clamp(2, 12);
// How long to wait between calls, default none. A run that arrives
// all at once cannot exercise a run *growing*: the case worth
// watching is a call somebody has opened and is reading when the
// next one turns it into a group.
// How long each call spends running, default none. A run that
// arrives all at once cannot exercise a run *growing*: the case
// worth watching is a call somebody has opened and is reading when
// the next one turns it into a group. Spent between the call's start
// and its end rather than between one call and the next, because
// that is where a real session's time goes -- and a call is drawn
// outside its group while it runs, which is a state nothing could
// see while every call here ended a few milliseconds after it
// started.
let gap = Duration::from_secs(
words
.next()
@@ -700,9 +705,6 @@ impl EchoDriver {
if let Some((count, gap)) = many_tools {
for i in 1..=count {
if i > 1 {
tokio::time::sleep(gap).await;
}
let id = format!("t-{}", super::random_hex());
send(Event::ToolStart {
id: id.clone(),
@@ -733,7 +735,7 @@ impl EchoDriver {
});
}
}
tokio::time::sleep(DELTA_DELAY).await;
tokio::time::sleep(DELTA_DELAY + gap).await;
send(Event::ToolEnd {
id,
output: format!("call {i} finished"),