showcase/shell-docs/src/content/docs/integrations/ag2/readables.mdx
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 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 AG2 backend.
<TailoredContent className="step" id="impl"
<TailoredContentOption
id="graph"
title="Custom agent"
description="I'm using a custom AG2 agent configuration."
>
<Steps>
<Step>
### Add the data to the Copilot
The [`useAgentContext` hook](/reference/v2/hooks/useAgentContext) is used to add data as context to the Copilot.
```tsx title="YourComponent.tsx" showLineNumbers {1, 7-10}
"use client" // only necessary if you are using Next.js with the App Router. // [!code highlight]
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" }
]);
// Define Copilot readable state
// [!code highlight:4]
useAgentContext({
description: "The current user's colleagues",
value: colleagues,
});
return (
// Your custom UI component
<>...</>
);
}
```
</Step>
<Step>
### Set up your agent state
In AG2, readables arrive as AG-UI context data. Use `ContextVariables` to access that data.
<Tabs groupId="language_ag2_readables_state" items={['Python']} default="Python" persist>
<Tab value="Python">
```python title="agent.py"
from autogen import ContextVariables
def get_readable(context: ContextVariables, description: str):
copilot = context.get("copilotkit", {})
context_items = copilot.get("context", [])
return next(
(item.get("value") for item in context_items if item.get("description") == description),
None,
)
```
</Tab>
</Tabs>
</Step>
<Step>
### Consume the data in your AG2 backend
Your AG2 tools and prompts can consume readable context directly from `ContextVariables`.
<Tabs groupId="language_ag2_readables_backend" items={['Python']} default="Python" persist>
<Tab value="Python">
```python title="agent.py"
from fastapi import FastAPI, Header
from fastapi.responses import StreamingResponse
from autogen import ContextVariables, ConversableAgent, LLMConfig
from autogen.ag_ui import AGUIStream, RunAgentInput
def get_readable(context: ContextVariables, description: str):
copilot = context.get("copilotkit", {})
context_items = copilot.get("context", [])
return next(
(item.get("value") for item in context_items if item.get("description") == description),
[],
)
agent = ConversableAgent(
name="assistant",
system_message=(
"You are a helpful assistant that can help emailing colleagues. "
"Call `get_colleagues` before suggesting recipients."
),
llm_config=LLMConfig({"model": "gpt-5.4-mini"}),
)
@agent.register_for_llm(description="Return the current user's colleagues from CopilotKit readables.")
def get_colleagues(context: ContextVariables) -> list[dict]:
return get_readable(context, "The current user's colleagues") or []
agent.register_for_execution(name="get_colleagues")(get_colleagues)
stream = AGUIStream(agent)
app = FastAPI()
@app.post("/chat")
async def run_agent(
message: RunAgentInput,
accept: str | None = Header(None),
):
return StreamingResponse(
stream.dispatch(message, accept=accept),
media_type=accept or "text/event-stream",
)
```
</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="Minimal setup"
description="I want the simplest AG2 setup that still reads CopilotKit readables."
>
<Steps>
<Step>
### Add the data to the Copilot
The [`useAgentContext` hook](/reference/v2/hooks/useAgentContext) is used to add data as context to the Copilot.
```tsx title="YourComponent.tsx" showLineNumbers {1, 7-10}
"use client" // only necessary if you are using Next.js with the App Router. // [!code highlight]
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" }
]);
// Define Copilot readable state
// [!code highlight:4]
useAgentContext({
description: "The current user's colleagues",
value: colleagues,
});
return (
// Your custom UI component
<>...</>
);
}
```
</Step>
<Step>
### Consume the data in your AG2 backend
For a minimal backend, parse context directly inside a registered AG2 tool and expose it through AG-UI.
<Tabs groupId="language_ag2_readables_minimal" items={['Python']} default="Python" persist>
<Tab value="Python">
```python title="agent.py"
from fastapi import FastAPI, Header
from fastapi.responses import StreamingResponse
from autogen import ContextVariables, ConversableAgent, LLMConfig
from autogen.ag_ui import AGUIStream, RunAgentInput
agent = ConversableAgent(
name="assistant",
system_message="You are a helpful assistant.",
llm_config=LLMConfig({"model": "gpt-5.4-mini"}),
)
@agent.register_for_llm(description="Read colleagues from CopilotKit readable context.")
def list_colleagues(context: ContextVariables) -> list[dict]:
copilot = context.get("copilotkit", {})
context_items = copilot.get("context", [])
entry = next(
(item for item in context_items if item.get("description") == "The current user's colleagues"),
None,
)
return entry.get("value", []) if entry else []
agent.register_for_execution(name="list_colleagues")(list_colleagues)
stream = AGUIStream(agent)
app = FastAPI()
@app.post("/chat")
async def run_agent(
message: RunAgentInput,
accept: str | None = Header(None),
):
return StreamingResponse(
stream.dispatch(message, accept=accept),
media_type=accept or "text/event-stream",
)
```
</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>