Interactive Input
Two mechanisms let the agent pause mid-turn and get human input instead of guessing: ask_user for clarifying questions,
and pauseAfter as a backstop that stops runaway agents and asks the user whether to continue.
ask_user — mid-turn questions
ask_user is a Copilot SDK tool the agent can call to ask a question with optional choice buttons. The agent's execution
pauses until the user responds or the wait times out.
How it feels to the user
A question widget appears inline in chat — the question text plus buttons for each choice, optionally a freeform text box. The user clicks or types and the agent continues. After answering, the widget switches to a read-only "Answered: value" state.
How to enable it
ask_user is not enabled by default. Opt in per agent:
includeSdkTools:
- ask_user
Timeout
If the user doesn't respond within AGENT_SERVER_ASK_USER_TIMEOUT_MS (default 5 minutes), the bridge auto-resolves
with "No response from user (timed out)" and the agent continues with that as the answer. Adjust the env var if
your agents ask questions that reasonably take longer to think about.
pauseAfter — "should I continue?" checkpoints
Without a stop signal, an LLM can spiral on a long task — dozens of tool calls, minutes of processing. pauseAfter
is an agent-level policy that automatically pauses execution and asks the user "Continue or stop?" when a threshold is hit.
Two thresholds, whichever trips first:
| Threshold | Meaning |
|---|---|
pauseAfter.toolCalls | Max tool calls before pausing. |
pauseAfter.timeoutMinutes | Max active processing time. Excludes time spent waiting for ask_user responses. |
Default (when not configured): 50 tool calls, 5 minutes.
What happens when a threshold trips
- The SDK turn is aborted cleanly.
- A pause prompt is emitted via the
ask_userchannel: Continue or Stop. - If the user chooses Continue → tool counters reset, a continuation prompt is sent, the agent resumes in a new SDK turn with history preserved.
- If the user chooses Stop (or the pause prompt times out) → the task ends gracefully, partial results are persisted.
Configuration
pauseAfter:
toolCalls: 100
timeoutMinutes: 10
For long-running batch agents (bulk imports, mass tagging), raise both values. For interactive assistants, the defaults are usually right.
Edge cases worth knowing
- SSE reconnect — the
ask_userwidget is replayed from the TaskRunner buffer. If the user clicks after the request already resolved or timed out, the 404 is handled silently. - Cancel while waiting —
POST /chat/:sessionId/cancelcancels the pendingask_userrequest and aborts the SDK turn cleanly. - Agent switch while waiting — pending requests are cancelled for the old agent before the switch completes.
- Inactivity timeout — if no SDK events arrive for
AGENT_SERVER_INACTIVITY_TIMEOUT_MS(default 5 minutes) and noask_useris pending, the task ends with a "no activity" message. This is a separate fallback frompauseAfter.
Related reading
- Architecture → Request Lifecycle — how the abort-and-resume dance works at the task level.
- Architecture → Tool Security —
ask_useris an SDK tool governed by the pre-tool-use hook. - Configuration → Agents —
pauseAfterandincludeSdkToolsfields.