Back to Copilotkit

Interactive Components

showcase/shell-docs/src/content/docs/generative-ui/your-components/interactive.mdx

1.57.02.9 KB
Original Source

What is this?

Interactive generative UI extends display components with user interaction. Your agent renders components that users can click, type into, or manipulate — and the results flow back to the agent as tool results.

This is how you build human-in-the-loop flows: the agent requests a decision, the user responds, and the agent continues with that response as input.

<InlineDemo integration="langgraph-python" demo="hitl-in-chat" />

When should I use this?

Use interactive generative UI when you want to:

  • Let users confirm or modify agent suggestions inline
  • Build form-like interactions within the chat
  • Create approval workflows where users can accept/reject agent actions
  • Add interactive controls (sliders, toggles, selectors) to agent outputs

How it works in code

The primitive is useHumanInTheLoop. Unlike useComponent (display-only) or useFrontendTool (handler-driven), useHumanInTheLoop exposes a respond callback to your render function. When the user clicks a button or submits a form, you call respond(value) — that value becomes the tool's result and the agent continues the turn.

tsx
import { z } from "zod";
import { useHumanInTheLoop } from "@copilotkit/react-core/v2";

useHumanInTheLoop({
  name: "humanApprovedCommand",
  description: "Ask a human for approval to run a command.",
  parameters: z.object({
    command: z.string().describe("The command to run"),
  }),
  render: ({ args, respond, status }) => {
    if (status !== "executing") return null;

    return (
      <div>
        <pre>{args.command}</pre>
        <button onClick={() => respond?.("Command is APPROVED")}>Approve</button>
        <button onClick={() => respond?.("Command is DENIED")}>Deny</button>
      </div>
    );
  },
});

Statuses:

  • "inProgress" — the LLM is still streaming arguments; don't render anything irreversible yet.
  • "executing" — the agent is waiting for the user's response. Show your form / buttons.
  • "complete" — the user has responded (or the call was cancelled). Collapse to a confirmation view.

Working with the Built-in Agent

No backend wiring needed — the Built-in Agent sees the interactive tool in its tool list the same way it sees a regular frontend tool, and respond(value) feeds the result straight back into the next agent turn.

Pattern: approval flow

The cell above demonstrates a command-approval flow:

  1. The agent proposes a command (e.g. rm -rf ./cache)
  2. The UI renders an Approve / Deny pair
  3. respond(...) sends "APPROVED" or "DENIED" back
  4. The agent reads the result and either executes or bails