---
title: Readables
icon: "lucide/BookA"
description: Share app specific context with your agent.
hideTOC: true
---

import { Tabs, Tab } from "fumadocs-ui/components/tabs";
import {
    TailoredContent,
    TailoredContentOption,
} from "@/components/react/tailored-content.tsx";

One of the most common use cases for CopilotKit is to register app state and context using `useAgentContext`.
This way, you can notify CopilotKit of what is going on in your app in real time.
Some examples might be: the current user, the current page, etc.

This context can then be shared with your LangChain agent.

## Implementation
<Callout>
    Check out the [Frontend Data documentation](/built-in-agent/agent-app-context) to understand what this is and how to use it.
</Callout>

<TailoredContent
    className="step"
    id="impl"
>
    <TailoredContentOption
        id="graph"
        title="Custom graph"
        description="I'm using a custom graph, where I define the nodes and edges myself."
    >
        <Steps>
            <Step>
                ### Add the data to the Copilot

                The `useAgentContext` hook is used to add data as context to the agent.

                ```tsx title="YourComponent.tsx"
                "use client" // only necessary if you are using Next.js with the App Router. // [!code highlight]
                import { useAgentContext } from "@copilotkit/react-core/v2"; // [!code highlight]
                import { useState } from 'react';

                export function YourComponent() {
                  // Create colleagues state with some sample data
                  const [colleagues, setColleagues] = useState([
                    { id: 1, name: "John Doe", role: "Developer" },
                    { id: 2, name: "Jane Smith", role: "Designer" },
                    { id: 3, name: "Bob Wilson", role: "Product Manager" }
                  ]);

                  // Share context with the agent
                  // [!code highlight:4]
                  useAgentContext({
                    description: "The current user's colleagues",
                    value: colleagues,
                  });
                  return (
                    // Your custom UI component
                    <>...</>
                  );
                }
                ```
            </Step>

            <Step>
                ### Set up your agent state
                Make sure your agent state inherits from CopilotKit state definition

                <Tabs groupId="language_langgraph_agent" items={['Python', 'TypeScript']} default="Python" persist>
                    <Tab value="Python">
                        ```python title="agent.py"
                        # ...
                        from copilotkit import CopilotKitState # extends MessagesState
                        # ...

                        # This is the state of the agent.
                        # It inherits from the CopilotKitState properties from CopilotKit.
                        class AgentState(CopilotKitState):
                            # ... Your defined state properties
                        ```
                    </Tab>
                    <Tab value="TypeScript">
                        ```typescript title="agent-js/src/agent.ts"
                        // ...
                        import { StateSchema } from "@langchain/langgraph";
                        import { CopilotKitStateSchema } from "@copilotkit/sdk-js/langgraph";
                        // ...

                        // This is the state of the agent.
                        // It inherits from the CopilotKitState properties from CopilotKit.
                        export const AgentStateSchema = new StateSchema({
                          // ... Your defined state properties
                          ...CopilotKitStateSchema.fields,
                        });
                        export type AgentState = typeof AgentStateSchema.State;
                        ```
                    </Tab>
                </Tabs>

            </Step>

            <Step>
                ### Consume the data in your LangChain agent
                The state of a LangChain agent is the "hub" for applicative information used by the agent.
                Naturally, the context from CopilotKit will be injected there.

                <Tabs groupId="language_langgraph_agent" items={['Python', 'TypeScript']} default="Python" persist>
                    <Tab value="Python">
                        ```python title="agent.py"
                        from langchain_core.messages import SystemMessage
                        from langchain_openai import ChatOpenAI
                        from copilotkit import CopilotKitState

                        # add the agent state definition from the previous step
                        class AgentState(CopilotKitState):
                            # ... Your defined state properties

                        def chat_node(state: AgentState, config: RunnableConfig):
                            # Extract the colleagues from CopilotKit context
                            colleagues_context_item = next(
                                (item for item in state["copilotkit"]["context"] if item.get("description") == "The current user's colleagues"),
                                None
                            )
                            colleagues = colleagues_context_item.get("value") if colleagues_context_item else []

                            # Provide the list of colleagues to the LLM
                            system_message = SystemMessage(
                                content=f"""You are a helpful assistant that can help emailing colleagues.
                                The user's colleagues are: {colleagues}"""
                            )

                            response = ChatOpenAI(model="gpt-5.4").invoke(
                                [system_message, *state["messages"]],
                                config
                            )

                            return {
                                **state,
                                "messages": response,
                            }
                        ```
                    </Tab>
                    <Tab value="TypeScript">
                        ```typescript title="agent-js/src/agent.ts"
                        import { SystemMessage } from "@langchain/core/messages";
                        import { ChatOpenAI } from "@langchain/openai";

                        // add the agent state definition from the previous step
                        export const AgentStateSchema = new StateSchema({
                          // ... Your defined state properties
                          ...CopilotKitStateSchema.fields,
                        });
                        export type AgentState = typeof AgentStateSchema.State;

                        async function chat_node(state: AgentState, config: RunnableConfig) {
                          // Extract the colleagues from CopilotKit context
                          const copilotKitContext = state.copilotKit.context
                          const colleaguesContextItem = copilotKitContext.find(contextItem => contextItem.description === 'The current user\'s colleagues"')

                          // Provide the list of colleagues to the LLM
                          const systemMessage = new SystemMessage({
                            content: `
                              You are a helpful assistant that can help emailing colleagues.
                              The user's colleagues are: ${colleaguesContextItem.value}
                            `,
                          });

                          const response = await new ChatOpenAI({ model: "gpt-5.4" }).invoke(
                            [systemMessage, ...state.messages],
                            config
                          );

                          return {
                            ...state,
                            messages: response,
                          };
                        }
                        ```
                    </Tab>
                </Tabs>
            </Step>

            <Step>
                ### Give it a try!
                Ask your agent a question about the context. It should be able to answer!
            </Step>
        </Steps>
    </TailoredContentOption>
    <TailoredContentOption
        id="prebuilt"
        title="Prebuilt agent"
        description={`I'm using a prebuilt agent like "create_agent" by LangGraph`}
    >
        <Steps>
            <Step>
                ### Add the data to the Copilot

                The `useAgentContext` hook is used to add data as context to the agent.

                ```tsx title="YourComponent.tsx"
                "use client" // only necessary if you are using Next.js with the App Router. // [!code highlight]
                import { useAgentContext } from "@copilotkit/react-core/v2"; // [!code highlight]
                import { useState } from 'react';

                export function YourComponent() {
                  // Create colleagues state with some sample data
                  const [colleagues, setColleagues] = useState([
                    { id: 1, name: "John Doe", role: "Developer" },
                    { id: 2, name: "Jane Smith", role: "Designer" },
                    { id: 3, name: "Bob Wilson", role: "Product Manager" }
                  ]);

                  // Share context with the agent
                  // [!code highlight:4]
                  useAgentContext({
                    description: "The current user's colleagues",
                    value: colleagues,
                  });
                  return (
                    // Your custom UI component
                    <>...</>
                  );
                }
                ```
            </Step>

            <Step>
                ### Consume the data in your LangChain agent
                The state of a LangChain agent is the "hub" for applicative information used by the agent.
                Naturally, the context from CopilotKit will be injected there.
                In addition, the CopilotKitMiddleware is what takes context, and passes it on to your agent

                <Tabs groupId="language_langgraph_agent" items={['Python', 'TypeScript']} default="Python" persist>
                    <Tab value="Python">
                        ```python title="agent.py"
                        from langchain.agents import create_agent
                        from copilotkit import CopilotKitMiddleware, CopilotKitState # [!code highlight]

                        graph = create_agent( # Works the same for "create_react_agent" or similar options
                            model="openai:gpt-5.4",
                            tools=[],  # Backend tools go here
                            middleware=[CopilotKitMiddleware()], # [!code highlight]
                            system_prompt="You are a helpful assistant.",
                            state_schema=CopilotKitState # [!code highlight]
                        )
                        ```
                    </Tab>
                    <Tab value="TypeScript">
                        ```typescript title="agent-js/src/agent.ts"
                        import { createAgent } from "langchain";
                        import { copilotkitMiddleware } from "@copilotkit/sdk-js/langgraph"; // [!code highlight]

                        export const agenticChatGraph = createAgent({ // Works the same for "create_react_agent" or similar options
                          model: "openai:gpt-5.4",
                          tools: [],  // Backend tools go here
                          middleware: [copilotkitMiddleware], // [!code highlight]
                          systemPrompt: "You are a helpful assistant.",
                        });
                        ```
                    </Tab>
                </Tabs>
            </Step>

            <Step>
                ### Give it a try!
                Ask your agent a question about the context. It should be able to answer!
            </Step>
        </Steps>
    </TailoredContentOption>
</TailoredContent>
