Back to Copilotkit

State Rendering

showcase/shell-docs/src/content/docs/integrations/adk/generative-ui/state-rendering.mdx

1.57.05.0 KB
Original Source

{/_ <IframeSwitcher id="agent-state-example" exampleUrl="https://feature-viewer.copilotkit.ai/adk-middleware/feature/agentic_generative_ui?sidebar=false&chatDefaultOpen=false" codeUrl="https://feature-viewer.copilotkit.ai/adk-middleware/feature/agentic_generative_ui?view=code&sidebar=false&codeLayout=tabs" exampleLabel="Demo" codeLabel="Code" height="700px" /> _/}

What is this?

All ADK Agents are stateful. This means that as your agent progresses through nodes, a state object is passed between them perserving the overall state of a session. CopilotKit allows you to render this state in your application with custom UI components, which we call Agentic Generative UI.

When should I use this?

Rendering the state of your agent in the UI is useful when you want to provide the user with feedback about the overall state of a session. A great example of this is a situation where a user and an agent are working together to solve a problem. The agent can store a draft in its state which is then rendered in the UI.

Implementation

<Steps> <Step> ### Run and connect your agent <RunAndConnect /> </Step> <Step> ### Set up your agent with state
Create your ADK agent with a stateful structure. Here's a complete example that tracks language selection:

```python title="agent.py"
from typing import Dict
from fastapi import FastAPI
from pydantic import BaseModel
from ag_ui_adk import ADKAgent, add_adk_fastapi_endpoint
from google.adk.agents import LlmAgent
from google.adk.tools import ToolContext


class AgentState(BaseModel):
    """State for the agent."""
    language: str = "english"


def set_language(tool_context: ToolContext, new_language: str) -> Dict[str, str]:
    """Sets the language preference for the user.

    Args:
        tool_context (ToolContext): The tool context for accessing state.
        new_language (str): The language to save in state.

    Returns:
        Dict[str, str]: A dictionary indicating success status and message.
    """
    tool_context.state["language"] = new_language
    return {"status": "success", "message": f"Language set to {new_language}"}


agent = LlmAgent(
    name="my_agent",
    model="gemini-2.5-flash",
    instruction="You are a helpful assistant that can change language settings.",
    tools=[set_language],
)

adk_agent = ADKAgent(
    adk_agent=agent,
    app_name="demo_app",
    user_id="demo_user",
    session_timeout_seconds=3600,
    use_in_memory_services=True,
)

app = FastAPI()
add_adk_fastapi_endpoint(app, adk_agent, path="/")

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000)
```
</Step> <Step> ### Render state of the agent in the chat Now we can utilize `useAgent` with a `render` function to render the state of our agent **in the chat**.
```tsx title="app/page.tsx"
// ...
// ...

// Define the state of the agent, should match the state of your ADK Agent.
type AgentState = {
  language: string;
};

function YourMainContent() {
  // ...

  // [!code highlight:13]
  // styles omitted for brevity
  useAgent({
    agentId: "my_agent",
    render: ({ state }) => (
      <div>
        Current language: {state.language || 'not set'}
      </div>
    ),
  });

  // ...

  return <div>...</div>;
}
```

<Callout type="warn" title="Important">
  The `name` parameter must exactly match the agent name you defined in your CopilotRuntime configuration (e.g., `my_agent` from the quickstart).
</Callout>
</Step> <Step> ### Render state outside of the chat You can also render the state of your agent **outside of the chat**. This is useful when you want to render the state of your agent anywhere other than the chat.
```tsx title="app/page.tsx"
// ...

// Define the state of the agent, should match the state of your ADK Agent.
type AgentState = {
  language: string;
};

function YourMainContent() {
  // ...

  // [!code highlight:3]
  const { agent } = useAgent({
    agentId: "my_agent",
  })

  // ...

  return (
    <div>
      <div className="flex flex-col gap-2 mt-4">
        Current language: {agent.state?.language || 'not set'}
      </div>
    </div>
  )
}
```

<Callout type="warn" title="Important">
  The `name` parameter must exactly match the agent name you defined in your CopilotRuntime configuration (e.g., `my_agent` from the quickstart).
</Callout>
</Step> <Step> ### Give it a try!
You've now created a component that will render the agent's state in the chat.

<video
  src="https://cdn.copilotkit.ai/docs/copilotkit/images/coagents/agentic-generative-ui.mp4"
  className="rounded-lg shadow-xl"
  loop
  playsInline
  controls
  autoPlay
  muted
/>
</Step> </Steps>