The operator
A busy owner with a secretary who handles the load
Operators run several agents the way an owner leans on a secretary — they want to glance, decide, and move on. Every escalation that shouts, can't be put down, or dead-ends the agent is friction. This redesign makes the agent's questions quiet by default, answerable in one or two taps, and never a dead end.
Can't be dismissed
Today the question is a big always-open card pinned above the composer. There's no way to set it aside, and stacking several squeezes the conversation off-screen.
A second question dead-ends
If the agent needs to ask again while one is pending, it hits a hard block and tells itself to "stop and wait" — the new question is silently lost.
The answer
One collapsible "needs you" accordion that queues every open question, steps through them, and accepts a one-tap answer, a typed answer, a dismissal, or a plain reply.
Today — and where it hurts
The current EscalationQuestionCard renders open and un-dismissible, one card per question. Here's two pending — and the tool error the agent gets on the third.
Two questions = two full cards, banner, no chevron, no close
A customer wants a refund outside our 30-day window. Approve a one-time exception?
How should I answer the pricing question?
↑ pins ~360px above the composer; the feed gets the scraps.
The third question the agent tries to ask — silently dropped
Input
{
"answer_kind": "open",
"question": "They're asking how to create an
account — can I share the sign-up link?"
}
Output
"You already have an unanswered question waiting for your owner on this conversation. Stop and wait for their answer instead of asking again."
The bug: the partial-unique index (thread_id) WHERE status='pending' caps the agent at one open question. The second decision the operator could have made in the same glance never reaches them.
The "needs you" accordion
Same container family as the thread's ToolCallCard (a Collapsible with a chevron header), tinted agent-green and carrying a count. Pinned above the composer, collapsed by default so the conversation keeps its room.
Resting — one question (collapsed pill)
Resting — several queued
Loading (skeleton) · & settled (loop-close) marker
Expanded — a single question keeps the 1-tap shortcut (no stepper, no review)
A customer wants a refund outside our 30-day window. Approve a one-time exception?
Single-question path is unchanged from today — one tap answers and the card settles. We only add the stepper when 2+ are queued.
Multiple questions — step, answer, send
When the queue holds 2+ questions the body becomes a stepper: ‹ 1 of 3 › with progress dots. Each answer is staged (not yet sent) so the operator can go back and change it — then one Send hands them all to the agent. Like reviewing before you approve.
Q1 — yes/no
A customer wants a refund outside our 30-day window. Approve a one-time exception?
Q2 — options · Q1 staged (back enabled)
How should I answer the pricing question?
A staged answer shows selected (coral ring + check). Tapping a different option restages; ‹ goes back to revisit Q1.
Review & send (all staged)
Refund exception?
Yes
Pricing question?
Offer the 10% intro discount
Sign-up link?
loquent.dev/start — walk them through it
3 questions cleared in 3 taps + 1 send. The pencil edits a staged answer in place. Nothing reaches the agent until Send.
Open question — type then stage
What's the earliest install date I can promise?
Step menu — set aside, or let the agent decide
A customer wants a refund outside our 30-day window. Approve a one-time exception?
Hide just collapses (stays pending). Let the agent decide resolves it as declined — use your judgment, so the agent never stalls waiting on a question the owner won't answer.
Stale — conversation moved on (server 409)
This conversation has moved on, so your agent can no longer act on this question.
Per-question — a stale one doesn't block the rest of the queue.
"I'll just reply myself"
Often the fastest answer is to type a reply in the composer. When the operator sends a message while a question is open, the agent checks whether it already answers — and clears the queue without a second action.
1 · Operator sends their own reply
2 · Agent checks the reply
The next agent turn is told the open questions + the operator's message and asked which (if any) it resolves — no model guessing in the UI.
3 · Resolved from the reply
Refund exception → Yes
Pricing question → 10% intro discount
If the reply only answers some, the rest stay in the queue. If it answers none, the card returns to pending — nothing is lost.
In the conversation
Collapsed, the accordion is a single line above the composer — the feed keeps its height (this also fixes the squished-feed scroll bug). Tapping it (or arriving from the notification) expands the stepper in place.
Resting — feed keeps its room
Expanded — stepper, feed dims behind
How should I answer the discount request?
Contactless threads (scheduled tasks)
The same accordion mounts at the top of AiAgentThreadView for threads with no contact — a scheduled check-in agent that needs a go/no-go. Identical interaction; it just lives above the thread instead of the composer.
Your scheduled check-in for the Q3 leads is due. Send it now?
What changes underneath
The UI above implies a few backend changes and three decisions worth your sign-off before we build.
1Queue, don't block
Drop the partial-unique index (thread_id) WHERE status='pending' so a thread can hold several pending questions. escalate_to_user stops returning the "you already have a question" string and just appends. The agent's prompt still nudges it to batch related asks, but a genuine second question is no longer lost.
migration: drop index · list_thread_escalations_api already returns all pending · API gains a batch answer_many
2Reply reconciliation
When the operator sends a normal message while questions are open, the next agent turn receives the open questions + that message and decides which it resolves (a small structured step, not UI heuristics). Resolved ones are marked answered with source "from operator reply"; the card reflects it live over the existing thread event stream.
runtime: feed open escalations into the turn · mark answered when matched
Three calls for you
a · Submit model for 2+ questions
Recommend stage-then-send (answers held locally, one Send commits all — review-before-approve, your "like Claude Code"). Alternative: commit each answer on tap so the agent can start sooner, losing the single review+undo. → going with stage-then-send unless you say otherwise.
b · "Let the agent decide" — keep it?
Gives the operator a true one-tap exit that won't stall the agent (resolves as declined → use judgment). Risk: an agent acting without a wanted answer. → recommend keeping, tucked under the step menu (not a primary button).
c · Default expansion
Collapsed by default; auto-expanded only when arriving from the notification deep-link (they came to answer). → matches the locked deep-link behavior; no change needed.
Mockup chrome (device frames, scene letters, annotation rails, crosshatch) is review-only and never ships. Every product surface uses real Aurora tokens — warm paper, the single coral primary reserved for Send, the agent-green identity tile for the "needs you" accordion, serif display for the questions, soft shadows, pill controls. This redesign rebuilds EscalationQuestionCard as a collapsible queue and relaxes the one-pending-per-thread constraint.