4d4bd19
CopilotKitDocs
  • Docs
  • Integrations
  • Reference
  • Free Developer Access
Get Started
QuickstartCoding Agents
Concepts
ArchitectureGenerative UI OverviewOSS vs Enterprise
Agentic Protocols
OverviewAG-UIAG-UI MiddlewareMCPA2A
Build Chat UIs
Prebuilt Components
CopilotChatCopilotSidebarCopilotPopup
Custom Look and Feel
CSS CustomizationSlots (Subcomponents)Fully Headless UIReasoning Messages
Multimodal AttachmentsVoice
Build Generative UI
Controlled
Tool-based Generative UITool RenderingState RenderingReasoning
Your Components
Display ComponentsInteractive Components
Declarative
A2UIDynamic Schema A2UIFixed Schema A2UI
Open-Ended
MCP Apps
Adding Agent Powers
Frontend ToolsShared State
Human-in-the-Loop
HITL OverviewPausing the Agent for InputHeadless Interrupts
Sub-AgentsAgent ConfigProgrammatic Control
Agents & Backends
Built-in Agent
Backend
Copilot RuntimeFactory ModeAG-UI
Runtime Server AdapterAuthentication
LangGraph (Python)
Your Components
Display-onlyInteractiveInterrupt-based
Shared state
Reading agent stateWriting agent stateInput/Output SchemasState streaming
ReadablesInterruptsConfigurableSubgraphsDeep Agents
Advanced
Disabling state streamingManually emitting messagesExiting the agent loop
Persistence
Loading Agent StateThreadsMessage Persistence
Videos
Video: Research Canvas
Error Debugging & ObservabilityCommon LangGraph issues
Troubleshooting Copilots
Migrate to AG-UI
Observe & Operate
InspectorVS Code Extension
Troubleshooting
Common Copilot IssuesError Debugging & ObservabilityDebug ModeAG-UI Event InspectorHook ExplorerError Observability Connectors
Enterprise
CopilotKit PremiumHow the Enterprise Intelligence Platform WorksHow Threads & Persistence WorkObservabilitySelf-Hosting IntelligenceThreads
Deploy
AWS AgentCore
What's New
Full MCP Apps SupportLangGraph Deep Agents in CopilotKitA2UI Launches with full AG-UI SupportCopilotKit v1.50Generative UI Spec SupportA2A and MCP Handshake
Migrate
Migrate to V2Migrate to 1.8.2
Other
Contributing
Code ContributionsDocumentation Contributions
Anonymous Telemetry
LangGraph (Python)Shared StateAgent Read-Only Context

Agent Read-Only Context

Publish UI values to the agent as a one-way read-only channel via useAgentContext.

What is this?#

Sometimes you want the agent to know something about the current UI, like the logged-in user, the current page, or a recent activity log, but you don't want the agent to be able to modify it. That's what useAgentContext is for: a one-way UI → agent channel for read-only context.

Unlike full shared state (where the agent can call tools that mutate the state back to the UI), useAgentContext values are pure inputs. The agent sees them on every turn via the runtime's context injection, but it has no setter and no tool to write them back.

Live Demo: LangGraph (Python) — readonly-state-agent-contextOpen full demo →

When should I use this?#

Reach for useAgentContext instead of full shared state when:

  • The value is UI-owned and has no meaning to the agent beyond "what the user is looking at right now".
  • The agent should read but never write (user identity, feature flags, selected record, scroll position).
  • You want the value to automatically unregister on unmount (e.g. the "current record" context disappears when you leave the page).

Think of it as "props for the agent".

How it works in code#

Call useAgentContext({ description, value }) once per value you want to publish. Each call registers a dynamic context entry with the runtime that is:

  • Refreshed whenever value changes (React re-renders).
  • Automatically removed when the component unmounts.
  • Surfaced to the agent via the backend's CopilotKitMiddleware, which threads the entries into the model's message history on every turn.
frontend/src/app/page.tsx — useAgentContext
L37–48
  useAgentContext({
    description: "The currently logged-in user's display name",
    value: userName,
  });
  useAgentContext({
    description: "The user's IANA timezone (used when mentioning times)",
    value: userTimezone,
  });
  useAgentContext({
    description: "The user's recent activity in the app, newest first",
    value: recentActivity,
  });

The description is important: it's a short human-readable label the agent sees alongside the value, so it knows what to do with it. Treat it like a parameter docstring.

Wire it to your own state#

useAgentContext doesn't care where the value comes from: local state, a React Context, Redux, a query cache, anything. The only requirement is that the identity of the value is stable enough for React to avoid a render loop. In the demo we use a handful of useState hooks; in a real app these would likely come from an auth provider, a router hook, and your domain state stores.

frontend/src/app/page.tsx — sourcing context values
L3–35
import React, { useState } from "react";
import {
  CopilotKit,
  CopilotPopup,
  useAgentContext,
} from "@copilotkit/react-core/v2";

import { ACTIVITIES, DemoLayout } from "./demo-layout";
import { useReadonlyStateAgentContextSuggestions } from "./suggestions";

export default function ReadonlyStateAgentContextDemo() {
  return (
    <CopilotKit
      runtimeUrl="/api/copilotkit"
      agent="readonly-state-agent-context"
    >
      <DemoContent />
      <CopilotPopup
        agentId="readonly-state-agent-context"
        defaultOpen={true}
        labels={{ chatInputPlaceholder: "Ask about your context..." }}
      />
    </CopilotKit>
  );
}

function DemoContent() {
  const [userName, setUserName] = useState("Atai");
  const [userTimezone, setUserTimezone] = useState("America/Los_Angeles");
  const [recentActivity, setRecentActivity] = useState<string[]>([
    ACTIVITIES[0],
    ACTIVITIES[2],
  ]);

Read-only, by design#

Because the agent never sees a setter or a mutation tool for these values, there's no way for a confused LLM to "update" them. That makes useAgentContext the right tool whenever the value in question is an input, not a field: the "context object passed to the agent on every turn", rather than "shared workspace you both edit".

When you need both reads and writes, you want full shared state instead.

Related#

  • Shared State (overview) — bidirectional reads + writes.
  • State streaming — stream agent-written state back to the UI during a run.
Supported by
Built-in Agent (TanStack AI)LangGraph (Python)LangGraph (TypeScript)LangGraph (FastAPI)Google ADKMastraCrewAI (Crews)PydanticAIClaude Agent SDK (Python)Claude Agent SDK (TypeScript)AgnoAG2LlamaIndexAWS StrandsLangroidMS Agent Framework (Python)MS Agent Framework (.NET)Spring AI