← Back
[W] Writing

Designing the wait for an AI agent

Software used to take a few hundred milliseconds to respond. A spinner was fine.

An agent might take five minutes, doing 30 things, and you're sitting there watching. That's a new interface problem, and I've spent a lot of this year on it, building the AI blocks in HextaUI.

Run the same task both ways.

Simulated, but built from what the real blocks show. Run it with just a spinner, then with real states. Press Stop halfway through too.

The two versions take roughly the same time, and the second feels shorter. More importantly, you can make decisions with it. You can see it reading the wrong file and stop it.

Show the work, then fold it away

There are two opposite needs here. While it's running, you want to see everything, to check it's on the right track. Afterwards, you only want the result.

So I treat it as a single thing that changes shape.

  • Stream each test into its file
  • Update the count as they finish
  • Fold into one line 118 passed, 2 failed in 4.2s
How Test Results works. The summary stays one click from the detail, so nothing is lost.

A failure shouldn't stay hidden in the fold, though. In the demo the red is right there in the summary line. The real block goes further, with word-level diffs between expected and received, and actions like Rerun failed and Ask to fix.

The states nobody demos

It's easy to demo streaming. These are the ones that catch you out once a real person is using it.

What happens What people expect
They press Stop It says it stopped, and nothing else changes.
They scroll up to reread It doesn't drag them back to the bottom on every token.
A tool call needs approval It waits for them, and doesn't look stuck.
A command fails They see the error and the failing line, in a readable form.
Work is handed to subagents One line per run, with live activity and a way to stop it.

The first two are the ones I see broken most often, and both make people feel the software has stopped listening to them. That's the feeling to avoid. A long-running agent is a bit like having someone else at your keyboard, so you want to know you can still interrupt them.

Say what it's doing, specifically

"Read lib/auth.ts, 42 lines" is useful. "Processing..." isn't.

It's the difference between a person telling you what they're working on and a person saying they're busy. And specific labels get something else for free: if you know the codebase, you can spot a wrong turn immediately.

How much is too much

There's a line, and I don't think I've completely found it. Show every token of reasoning and it's noise, but hide it all and you're back to the spinner.

My rule so far is to show actions and collapse thought. What the agent did to your project is always visible, and what it was thinking is available if you ask. In the Thinking block, the reasoning streams and then folds away, and it's labelled by how long it took.

A wait becomes much easier when it feels like watching work rather than waiting for a result. It also makes the agent easier to trust, because you've seen how it got there.

Next