showcase/shell-docs/src/content/docs/shared-state.mdx
Agentic Copilots maintain a shared state that seamlessly connects your UI with the agent's execution. This shared state system allows you to:
<ImageZoom src="https://cdn.copilotkit.ai/docs/copilotkit/images/coagents/SharedStateCoAgents.gif" alt="Shared State Demo" width={1000} height={1000} className="rounded-lg shadow-lg border mt-0" />
<InlineDemo demo="shared-state-read-write" />Use shared state when you want to facilitate collaboration between your agent and the user. Updates flow both ways: the agent's outputs are automatically reflected in the UI, and any inputs the user updates in the UI are automatically reflected in the agent's execution.
Shared state is a single object that both the UI and the agent can read and write. In practice, most apps split it into at least two conceptual slices:
The example below wires both sides against a single AgentState
schema with preferences (UI-written) and notes (agent-written).
The useAgent hook subscribes your component to state changes. Pass
UseAgentUpdate.OnStateChanged and every mutation the agent makes to
its state triggers a re-render; your UI is a reactive window into the
agent's world.
Once subscribed, the agent-authored slice of state is just data you
render. The NotesCard below is a plain presentational component. It
doesn't know about CopilotKit at all; it just receives notes as a
prop from the parent page.
Writes flow the other direction via agent.setState. Every call
replaces the named fields; on the agent's next turn, the new values are
visible to the backend (via middleware, prompt injection, or direct
reads from state) and influence the reply.
The form that generates those writes is, again, a plain controlled
component. Every onChange bubbles up to the parent, which calls
agent.setState, keeping the UI and the agent in lockstep.
Two common extensions of the basic pattern:
useAgentContext
publishes read-only values to the agent without opening up write
access.<IntegrationGrid path="shared-state" exclude={["agno", "agent-spec"]} />