Human in the loop¶
Where the agent asks the user: approvals, questions and forms.
Confirmation (tool approval)¶
Approve or deny a tool call, with a reason or edited arguments.

| API | ToolCall(part, onApproval) |
| AI Elements | Confirmation |
| Artifact | ai-elements-ui |
| Reference | ToolCall |
Respect approvalAnswers: only offer reasons/edited input supported by the backend. Approval must resume the waiting tool, not create a new user turn.
import androidx.compose.runtime.Composable
import dev.ai.elements.core.chat.ChatController
import dev.ai.elements.core.model.ToolPart
import dev.ai.elements.core.model.ToolState
import dev.ai.elements.ui.chat.ToolCall
@Composable
fun ConfirmationExample(part: ToolPart, controller: ChatController) {
ToolCall(part.copy(state = ToolState.APPROVAL_REQUESTED), onDecision = { controller.respondToApproval(part.id, it) })
}
Question¶
A multiple-choice question from the agent.

| API | Question(prompt, options, multiple, onSubmit) |
| Artifact | ai-elements-ui |
| Reference | Question |
Store the returned selected ids/text and forward them to your agent. answered prevents resubmitting a completed question.
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import dev.ai.elements.ui.chat.Question
import dev.ai.elements.ui.chat.QuestionAnswer
import dev.ai.elements.ui.chat.QuestionOption
@Composable
fun QuestionExample() {
var answer by remember { mutableStateOf<QuestionAnswer?>(null) }
Question("Choose a platform", listOf(QuestionOption("android", "Android")), answered = answer, onSubmit = { answer = it })
}
Input request (form)¶
A form the agent asks the user to fill, from a JSON Schema (AG-UI interrupts, MCP elicitation).

| API | InputRequestCard(request, onRespond) |
| Artifact | ai-elements-ui |
| Reference | InputRequestCard |
Use the exact request id when responding. Forms validate the supported JSON Schema fields; URL requests require the user to complete the external flow.