Put a question to the reader on a row of its own

An AskUserQuestion arrived in the middle of a run of tool calls and was
folded into the collapsed card with them, so the one row where somebody
was asked something -- and the answer they gave -- was hidden behind
"Called 6 tools" like any other grep.

It now starts a run of its own and ends the one before it, which needs no
change to the grouping: a run of one is drawn as itself. The calls around
it become a group before and a group after, so where the work stopped to
ask is legible from the shape of the transcript without opening anything.

Echo's `/ask` now runs three ordinary calls on each side of the question,
because that is the shape this has to be looked at in and there was no
way to produce it.
This commit is contained in:
iris committed 2026-08-30 02:00:48 -04:00
1 parent 09f7f8d203
commit bc0a48799c
3 files changed
+63 -9

No files matched your search

+29 -1
View File
@@ -12,7 +12,10 @@
//! - `/question [text]` -- a question, exercising the answer path.
//! - `/ask` -- an AskUserQuestion call: two questions on one tool call,
//! with descriptions, a preview and a multi-select, which is the shape
//! that is awkward to get a real model to produce on demand.
//! that is awkward to get a real model to produce on demand. Wrapped in
//! a run of ordinary calls on each side, because being asked something
//! happens in the middle of work and the screen has to keep it out of
//! the collapsed group around it.
//! - `/slow [seconds]` -- a turn that stays running (default 30), so states that only
//! exist *while* something is happening can be looked at.
//! - `/error [text]` -- a failure, which is otherwise awkward to cause.
@@ -103,6 +106,26 @@ pub struct EchoDriver {
}
impl EchoDriver {
/// A short run of ordinary calls, to sit either side of something.
///
/// Three, because two is the fewest that groups and three makes it
/// obvious the group is a group -- and because the point of the
/// fixture is what a question looks like with work around it.
fn some_calls(&self, label: &str) {
for index in 0..3 {
let id = format!("echo-{label}-{index}-{}", super::random_hex());
self.emit(Event::ToolStart {
id: id.clone(),
tool: "echo-tool".to_string(),
input: serde_json::json!({ "step": format!("{label} {index}") }),
});
self.emit(Event::ToolEnd {
id,
output: format!("{label} step {index} finished"),
});
}
}
/// An AskUserQuestion call, in the shape the CLI sends one.
///
/// Two questions on one call, because that is where the display is
@@ -175,6 +198,7 @@ impl EchoDriver {
self.emit(Event::Status {
state: SessionStatus::Running,
});
self.some_calls("before");
self.emit(Event::ToolStart {
id: call.clone(),
tool: "AskUserQuestion".to_string(),
@@ -714,6 +738,10 @@ impl Driver for EchoDriver {
id: call,
output: format!("answered: {answer}"),
});
// The work carries on where it left off, which is what makes
// the asked-here row a boundary with a group on each side
// rather than the last thing in the turn.
self.some_calls("after");
} else {
self.emit(Event::AssistantText {
delta: format!("You answered: {answer}"),