Components as Tools
Let your agent render rich React components directly in the chat by calling them as tools.
"""MS Agent Framework agent backing the Tool-Based Generative UI demo.The frontend registers `render_bar_chart` and `render_pie_chart` tools via`useComponent`. CopilotKit's runtime forwards those frontend tool definitionsto the agent at request time, so the agent can call them by name.There are no backend tools here -- the agent's job is to recognize chartintent in the user's message and emit a tool call with structured chart data.The frontend then renders the result inline."""from __future__ import annotationsfrom textwrap import dedentfrom agent_framework import Agent, BaseChatClientfrom agent_framework_ag_ui import AgentFrameworkAgentSYSTEM_PROMPT = dedent( """ You are a data visualization assistant. When the user asks for a chart, call `render_bar_chart` or `render_pie_chart` with a concise title, short description, and a `data` array of `{label, value}` items. Pick bar for comparisons over a small set of categories; pick pie for composition / share-of-whole. Keep chat responses brief -- let the chart do the talking. After you finish executing tools, send a brief final assistant message so it persists in the conversation. """).strip()def create_gen_ui_tool_based_agent(chat_client: BaseChatClient) -> AgentFrameworkAgent: """Instantiate the Tool-Based Generative UI demo agent.""" base_agent = Agent( client=chat_client, name="gen_ui_tool_based_agent", instructions=SYSTEM_PROMPT, # Both rendering tools (`render_bar_chart`, `render_pie_chart`) are # registered on the frontend via `useComponent`. The runtime forwards # them as tool definitions at request time. tools=[], ) return AgentFrameworkAgent( agent=base_agent, name="CopilotKitMSAgentGenUiToolBasedAgent", description=( "Data-visualization assistant that turns chart requests into " "frontend-rendered bar and pie charts via tool calls." ), require_confirmation=False, )What is this?#
Tool-based Generative UI is the simplest form of Generative UI: you register
a React component with useComponent, and CopilotKit exposes it to the
agent as a tool. When the agent calls the tool, CopilotKit renders your
component inline in the chat, passing the tool's arguments straight through
as typed props.
Unlike tool rendering, which wraps a real backend tool in a custom UI, tool-based GenUI is the component. There is no handler, no user interaction, no server-side execution. The agent decides when to show it, populates the data, and CopilotKit paints it.
When should I use this?#
Use useComponent when you want to:
- Display rich UI (cards, charts, tables, dashboards) inline in the chat
- Show structured data the agent has derived from its reasoning
- Render previews, status indicators, or visual summaries
- Let the agent present information beyond plain text
For components that need user interaction, see Human-in-the-loop. For operational transparency around a real backend tool, see Tool rendering.
How it works in code#
useComponent takes a name, a Zod schema for its props, and the component
to render. The runtime registers it as a frontend tool so the agent can
discover it, and Zod validates the LLM's arguments before they reach your
component.
import React from "react";import { CopilotChat, CopilotKit, useComponent,} from "@copilotkit/react-core/v2";import { BarChart, barChartPropsSchema } from "./bar-chart";import { PieChart, pieChartPropsSchema } from "./pie-chart";import { useSuggestions } from "./suggestions";function Chat() { useComponent({ name: "render_bar_chart", description: "Display a bar chart with labeled numeric values.", parameters: barChartPropsSchema, render: BarChart, });The component itself is ordinary React: it reads only its props and can stream in as the agent fills the payload. The example above uses Recharts for the bar chart; it doesn't know anything about CopilotKit.
The name you pass to useComponent is what the agent sees as the tool
name. Make it a verb like render_bar_chart or show_weather so the LLM
reliably picks it when the user asks for that visualization.
