Interactive components
Create approval flows where the agent pauses and waits for human input.
Open your coding agent in your project's folder, or in an empty folder for a new app.This runs in a coding agent on your computer.
This feature (gen-ui-interrupt) hasn't been tagged in any Google Antigravity cell yet. Try CopilotKit's Built-in Agent, LangGraph (Python), LangGraph (TypeScript).
What is this?#
Interactive generative UI creates flows where the agent pauses execution and waits for user input before continuing. This enables approval workflows, confirmation dialogs, and any scenario where human judgment is needed mid-execution.
When should I use this?#
Use interactive generative UI when you need:
- Approval/rejection flows (e.g. "Run this command?")
- User decisions that the agent should know about
- Confirmation dialogs with structured responses
- Any flow where the agent pauses for human judgment
How it works in code#
Install the Antigravity AG-UI adapter
pip install ag-ui-antigravity google-antigravityAsk for the human with a frontend tool
The simplest route is an ordinary frontend tool. Register it in the
browser with useHumanInTheLoop, or with useFrontendTool and an async
handler that resolves once the user has answered. Each run carries that
tool definition to the agent, the adapter rebuilds it as a custom
Antigravity tool, and when the model calls it the call parks as an awaited
coroutine — the SSE response for that run closes, and the adapter resolves
the parked call from a later HTTP run with whatever the handler returned.
The model receives that value as the tool's real return value, so there is
no proxy tool and no fire-and-forget long-running-tool workaround.
Or pause a server tool with experimental_interrupt()
When the backend decides it needs the user, a Python server tool can pause
itself on an AG-UI interrupt with the adapter's experimental
experimental_interrupt() and carry on with the answer:
from ag_ui_antigravity import experimental_interrupt
async def schedule_meeting(topic: str, attendee: str) -> str:
"""Books a meeting once the user picks a time."""
answer = await experimental_interrupt(
"schedule_meeting",
message=f"Pick a time for {topic}",
metadata={"topic": topic, "attendee": attendee},
)
if not answer.resolved:
return f"Not scheduled ({answer.status})."
return f"Scheduled for {answer.payload['chosen_label']}."The run ends with RUN_FINISHED carrying an interrupt outcome, which
useInterrupt renders; the payload the user resolves it with comes back
unchanged in answer.payload. answer.status is "resolved",
"cancelled" or "abandoned" (the user sent a new message instead).
Name the tool in the agent's instructions
That leaves the agent with one job: knowing the tool exists and when to
call it. A model that is never told about book_call will answer in prose
and the picker will never mount.
from agents._common import build
HITL_IN_CHAT_PROMPT = (
"You help users book an onboarding call with the sales team. "
"When they ask to book a call, call the frontend-provided "
"`book_call` tool with a short topic and the user's name. "
"Keep any chat reply to one short sentence."
)
def hitl_in_chat_agent():
return build(system_instructions=HITL_IN_CHAT_PROMPT)
The frontend tool is dispatched to the browser at most once per turn
(deduplicate_tool_calls, on by default), so a model that re-issues the
same call after the harness backgrounds it does not ask the user twice.
ask_question is off in this showcase
Antigravity's own ask_question built-in tool — the one primitive that would
park on a real AG-UI interrupt — is disabled here with
CapabilitiesConfig(enabled_tools=[BuiltinTools.FINISH]). The CopilotKit
demos answer a tool call with a ToolMessage, not an interrupt resume, so
a turn that parked on ask_question would wait forever. FINISH has to stay
enabled: it is how the harness ends a turn.
This framework implements the same interactive pause shape with a
Promise-based frontend tool. The agent calls schedule_meeting, the client
renders the picker, and the tool result resolves only after the user chooses a
slot or cancels.