Back to Copilotkit

Shared State

showcase/shell-docs/src/content/docs/shared-state.mdx

1.57.23.6 KB
Original Source

What is shared state?

Agentic Copilots maintain a shared state that seamlessly connects your UI with the agent's execution. This shared state system allows you to:

  • Display the agent's current progress and intermediate results
  • Update the agent's state through UI interactions
  • React to state changes in real-time across your application

<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" />

When should I use this?

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.

<OpsPlatformCTA variant="inline" title="Building stateful agents?" body="Persistent threads ship with the Enterprise Intelligence Platform on the free Developer tier." surface="docs_shared_state" />

Reading agent state

Subscribe a component to the agent's state with useAgent. Any time the agent mutates its state — for example via a tool call — the hook fires and your UI re-renders with the new values.

<Snippet region="use-agent-read" cell="shared-state-read-write" title="frontend/src/app/page.tsx — useAgent subscription" />

The returned agent.state is just a plain object. Read it like any other piece of React state and render the parts you care about — agent-written notes, structured outputs, progress indicators, anything the agent has put there.

Writing agent state

The same agent object exposes a setState setter. Calling it from a UI event handler pushes the new value into shared state, and the agent reads it back on its next turn — so the UI's writes visibly steer the model.

<Snippet region="use-agent-write" cell="shared-state-read-write" title="frontend/src/app/page.tsx — agent.setState" />

This is what makes the channel two-way: the UI doesn't just observe the agent, it can hand the agent fresh inputs (preferences, selections, partial work) without going through the chat thread.

Rendering shared state in the UI

Because agent.state is plain React data, the UI layer is whatever you'd normally build. The demo on this page wires the agent's outputs into a small card component and feeds user edits back through setState.

<Snippet region="notes-card-render" cell="shared-state-read-write" title="frontend/src/app/page.tsx — NotesCard" />

Streaming partial state updates

By default, agent state only updates between node transitions, so a long-running tool call appears as one big burst at the end. State streaming forwards a specific tool argument straight into a state key as it's being generated, so the UI can watch the answer assemble token-by-token.

<Snippet region="state-streaming-middleware" cell="shared-state-streaming" title="backend — StateStreamingMiddleware" />

See State streaming for the full walkthrough, including the corresponding useAgent subscription on the frontend.

Read-only context

When the value is UI-owned and the agent should read it but never write it back — current user, selected record, scroll position — reach for useAgentContext instead of full shared state. It publishes values as a one-way UI → agent channel that auto-unregisters on unmount.

See Agent read-only context for the full pattern.

<FeatureIntegrations feature="shared-state-read-write" />

<IntegrationGrid path="shared-state" exclude={["agno", "agent-spec", "spring-ai", "langroid"]} />