---
title: Interactive
icon: "lucide/Wrench"
description: Create components that your agent can use to interact with the user.
---
import InstallSDKSnippet from "@/snippets/install-sdk.mdx"
import { IframeSwitcher } from "@/components/content"
import RunAndConnect from "@/snippets/integrations/deepagents/run-and-connect.mdx"
import FrontEndToolsImpl from "@/snippets/integrations/deepagents/frontend-tools.mdx"
import { Tabs, Tab } from "fumadocs-ui/components/tabs"

{/* TODO: swap feature-viewer URLs back to /deepagents/ once the dojo supports that route */}
<IframeSwitcher
  id="frontend-tools-based-hitl-example"
  exampleUrl="https://feature-viewer.copilotkit.ai/langgraph/feature/human_in_the_loop?sidebar=false&chatDefaultOpen=false"
  codeUrl="https://feature-viewer.copilotkit.ai/langgraph/feature/human_in_the_loop?view=code&sidebar=false&codeLayout=tabs"
  exampleLabel="Demo"
  codeLabel="Code"
  height="700px"
/>

## What is this?
Frontend tools enable you to define client-side functions that your Deep Agents agent can invoke, with execution happening entirely in the user's browser. When your agent calls a frontend tool,
the logic runs on the client side, giving you direct access to the frontend environment.

This can be utilized for to let [your agent control the UI](/deepagents/frontend-tools), [generative UI](/deepagents/frontend-tools), or for Human-in-the-loop interactions.

In this guide, we cover the use of frontend tools for Human-in-the-loop.

## When should I use this?
Use frontend tools when you need your agent to interact with client-side primitives such as:
- Reading or modifying React component state
- Accessing browser APIs like localStorage, sessionStorage, or cookies
- Triggering UI updates or animations
- Interacting with third-party frontend libraries
- Performing actions that require the user's immediate browser context

## Implementation

<Steps>
    <Step>
      ### Run and connect your agent
      <RunAndConnect components={props.components} />
    </Step>

    <Step>
        ### Create a frontend human-in-the-loop tool

        Frontend tools can be leveraged in a variety of ways. One of those ways is to have a human-in-the-loop flow where the response
        of the tool is gated by a user's decision.

        In this example we will simulate a "approval" flow for executing a command. First, use the `useHumanInTheLoop` hook to create a tool that
        prompts the user for approval.

        ```tsx title="page.tsx"
        import { useHumanInTheLoop } from "@copilotkit/react-core/v2" // [!code highlight]
        import { z } from "zod";

        export function Page() {
          // ...

          // [!code highlight:20]
          useHumanInTheLoop({
            name: "humanApprovedCommand",
            description: "Ask 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 <></>;
              return (
                <div>
                  <pre>{args.command}</pre>
                  {/* [!code highlight:2] */}
                  <button onClick={() => respond?.(`Command is APPROVED`)}>Approve</button>
                  <button onClick={() => respond?.(`Command is DENIED`)}>Deny</button>
                </div>
              );
            },
          });

          // ...
        }
        ```
    </Step>
    <Step>
        ### Install the CopilotKit SDK

        Now, we'll need to modify the agent to access these frontend tools. In your terminal, navigate to your agent's folder and continue from there!

        <InstallSDKSnippet components={props.components}/>
    </Step>
    <Step>
        ### Wire CopilotKit state into your agent

        To access the frontend tools provided by CopilotKit, register the CopilotKit state alongside any custom state your agent needs.

        <Tabs groupId="agent_language" items={['Python', 'TypeScript']} persist>
            <Tab value="Python">
                In Python, inherit from `CopilotKitState` in your agent's state definition:

                ```python title="agent.py"
                from copilotkit import CopilotKitState # [!code highlight]

                class YourAgentState(CopilotKitState): # [!code highlight]
                    your_additional_properties: str
                ```
            </Tab>
            <Tab value="TypeScript">
                In TypeScript, define your custom state as a middleware via `createMiddleware` and compose it with `copilotkitMiddleware`:

                ```ts title="agent.ts"
                import { createMiddleware } from "langchain";
                import { copilotkitMiddleware } from "@copilotkit/sdk-js/langgraph"; // [!code highlight]
                import { z } from "zod";

                export const yourStateMiddleware = createMiddleware({
                    name: "YourAgentState",
                    stateSchema: z.object({
                        yourAdditionalProperty: z.string().optional(),
                    }),
                });

                // Pass both middlewares when constructing the agent:
                // createDeepAgent({ middleware: [yourStateMiddleware, copilotkitMiddleware], ... })
                ```
            </Tab>
        </Tabs>

        By doing this, your agent's state will include the `copilotkit` property, which contains the frontend tools that can be accessed and invoked.
    </Step>
    <Step>
        ### Accessing Frontend Tools

        Once your agent's state includes the `copilotkit` property, you can access the frontend tools and utilize them within your agent's logic.

        Here's how you can call a frontend tool from your agent:

        <FrontEndToolsImpl components={props.components} />

        These tools are automatically populated by CopilotKit and are compatible with LangChain's tool call definitions, making it straightforward to integrate them into your agent's workflow.
    </Step>
    <Step>
        ### Give it a try!
        You've now given your agent the ability to directly call any frontend tools you've defined. These tools will be available to the agent where they can be used as needed.
    </Step>
</Steps>
