TL;DR
In this guide, you will learn how to build a frontend for your Microsoft Agent Framework (Python) Agents using AG-UI Protocol and CopilotKit. Microsoft Agent Framework (Python) will power the AI agents backend, while CopilotKit powers the frontend, and then AG-UI creates a bridge that enables the frontend to communicate with the backend.
Before we jump in, here is what we will cover:
Understanding the Microsoft Agent Framework?
Setting up a Microsoft Agent Framework + AG-UI + CopilotKit agent using CLI
Integrating your Microsoft Agent Framework agent with AG-UI protocol in the backend
Building a frontend for your Microsoft Agent Framework + AG-UI agent using CopilotKit
Here is a preview of what you can build using Microsoft Agent Framework (Python) + AG-UI + CopilotKit.
What is the Microsoft Agent Framework?
The Microsoft Agent Framework (MAF) is an open-source development kit (SDK) and runtime for building and deploying AI agents and multi-agent workflows in both Python and NET.
MAF is considered the next generation of Microsoft's previous agent-related projects, unifying the strengths of AutoGen (for innovative multi-agent orchestration) and Semantic Kernel (for enterprise-grade features and production readiness).
The core purpose of the framework is to allow developers to create sophisticated AI applications that involve:
Individual AI agents that use Large Language Models (LLMs) to reason, make decisions, and use tools.
Complex multi-agent systems where multiple agents collaborate to solve complex, multi-step tasks.
The Python implementation offers a developer-friendly experience that is highly suitable for building and testing agentic systems quickly.
If you want to dive deeper into how Microsoft Agent Framework works and its setup, check out the docs here: Microsoft Agent Framework docs.
Prerequisites
Before you begin, you'll need the following:
OpenAI or Azure OpenAI credentials (for the Microsoft Agent Framework agent)
Python 3.12+
Node.js 20+
-
Any of the following package managers:
- pnpm (recommended)
- npm
- yarn
- bun
Setting up a Microsoft Agent Framework + AG-UI + CopilotKit agent using CLI
In this section, you will learn how to set up a full-stack Microsoft Agent Framework (Python) agent using a CLI command that sets up the backend using AG-UI protocol and the frontend using CopilotKit.
Let’s get started.
Step 1: Run CLI command
If you don’t already have a Microsoft Agent Framework agent, you can set up one quickly by running the CLI command below in your terminal.
npx copilotkit@latest init -m microsoft-agent-framework-py
Then give your project a name as shown below.
Step 2: Install dependencies
Once your project has been created successfully, install dependencies using your preferred package manager:
# Using pnpm (recommended)
pnpm install
# Using npm
npm install
# Using yarn
yarn install
# Using bun
bun install
Step 3: Set up your agent credentials
After installing the dependencies, set up your agent credentials. The backend automatically uses Azure when the Azure env vars below are present; otherwise, it falls back to OpenAI.
To set up your agent credentials, create a .env file inside the agent folder with one of the following configurations:
OpenAI:
OPENAI_API_KEY=sk-...your-openai-key-here...
OPENAI_CHAT_MODEL_ID=gpt-4o-mini
Azure OpenAI:
AZURE_OPENAI_ENDPOINT=https://your-resource.openai.azure.com/
AZURE_OPENAI_CHAT_DEPLOYMENT_NAME=gpt-4o-mini
# If you are not relying on az login:
# AZURE_OPENAI_API_KEY=...
Step 4: Run development server
Then start the development server using your preferred package manager:
# Using pnpm
pnpm dev
# Using npm
npm run dev
# Using yarn
yarn dev
# Using bun
bun run dev
Once the development server is running, navigate to http://localhost:3000/ and you should see your Microsoft Agent Framework (Python) + AG-UI + CopilotKit agent up and running.
Congrats! You've successfully set up a full-stack Microsoft Agent Framework agent. Your AI agent is now ready to use! Try playing around with the suggestions in the chat to test the integration.
Integrating your Microsoft Agent Framework agent with AG-UI protocol in the backend
In this section, you will learn how to integrate your Microsoft Agent Framework agent with AG-UI protocol to expose it to the frontend.
Let’s jump in.
Step 1: Install Microsoft Agent Framework + AG-UI packages
To get started, install the Microsoft Agent Framework + AG-UI packages together with other necessary dependencies using the commands below.
uv pip install agent-framework, agent-framework-ag-ui, azure-identity
Step 2: Define your agent state
Once you have installed the required packages, use a JSON schema to define the structure of the agent state that will be synchronised between the backend and the frontend UI, as shown below.
from __future__ import annotations
from textwrap import dedent
from typing import Annotated
# Import core agent framework components for building conversational AI agents
from agent_framework import ChatAgent, ChatClientProtocol, ai_function
# Import CopilotKit integration layer that bridges Agent Framework with the frontend
from agent_framework_ag_ui import AgentFrameworkAgent
from pydantic import Field
# STATE_SCHEMA: Defines the structure of agent state
STATE_SCHEMA: dict[str, object] = {
"proverbs": {
"type": "array", # Proverbs is a list/array of items
"items": {"type": "string"}, # Each item in the array is a string
"description": "Ordered list of the user's saved proverbs.", # Human-readable description
}
}
// ...
After that, use a state config JSON schema to tell the agent which tool function to call when it needs to update state, as shown below.
from __future__ import annotations
from textwrap import dedent
from typing import Annotated
# Import core agent framework components for building conversational AI agents
from agent_framework import ChatAgent, ChatClientProtocol, ai_function
# Import CopilotKit integration layer that bridges Agent Framework with the frontend
from agent_framework_ag_ui import AgentFrameworkAgent
from pydantic import Field
// ...
# PREDICT_STATE_CONFIG: Maps state fields to the tools that modify them.
# This tells your agent which tool function to call when the agent needs to update
# a particular piece of state, and which argument of that tool contains the new state value.
PREDICT_STATE_CONFIG: dict[str, dict[str, str]] = {
"proverbs": {
"tool": "update_proverbs", # The name of the tool function that updates proverbs
"tool_argument": "proverbs", # The parameter name in that tool that receives the new proverb list
}
}
// ...
Step 3: Define your agent tools
After defining your agent state, configure your agent tools using the @ai_function decorator to mark them as tools that your AI agent can call, as shown below. The name and description help the agent to understand when and how to use these tools.
from __future__ import annotations
from textwrap import dedent
from typing import Annotated
# Import core agent framework components for building conversational AI agents
from agent_framework import ChatAgent, ChatClientProtocol, ai_function
# Import CopilotKit integration layer that bridges Agent Framework with the frontend
from agent_framework_ag_ui import AgentFrameworkAgent
from pydantic import Field
// ...
# @ai_function decorator: Marks this as a tool that the AI agent can call.
# The name and description help the LLM understand when and how to use this tool.
@ai_function(
name="update_proverbs",
description=(
"Replace the entire list of proverbs with the provided values. "
"Always include every proverb you want to keep."
),
)
def update_proverbs(
proverbs: Annotated[
list[str], # The function accepts a list of strings
Field(
description=(
# This description guides the LLM on how to use this parameter correctly.
# Emphasises that this should be the COMPLETE list, not a partial update.
"The complete source of truth for the user's proverbs. "
"Maintain ordering and include the full list on each call."
)
),
],
) -> str:
"""
Persist the provided set of proverbs.
Returns:
A confirmation message indicating how many proverbs are now tracked.
"""
return f"Proverbs updated. Tracking {len(proverbs)} item(s)."
# Weather tool: Demonstrates frontend UI integration through tool calls.
# When the agent calls this function, CopilotKit can render a weather card in the UI.
@ai_function(
name="get_weather",
description="Share a quick weather update for a location. Use this to render the frontend weather card.",
)
def get_weather(
location: Annotated[str, Field(description="The city or region to describe. Use fully spelled out names.")],
) -> str:
"""
Return a short natural language weather summary.
Args:
location: The city or region name to get the weather for.
Returns:
A friendly weather description string that can be displayed to the user.
"""
# Normalise the location string: remove whitespace, capitalise words
normalized = location.strip().title() or "the requested location"
# Return a mock weather response (in production, this would query a real API)
return (
f"The weather in {normalised} is mild with a light breeze. "
"Skies are mostly clear—perfect for planning something fun."
)
# Human-in-the-loop tool: Demonstrates requiring explicit user approval before executing.
# The approval_mode="always_require" parameter ensures this function will pause execution
# and wait for the user to explicitly approve or reject the action via the UI.
@ai_function(
name="go_to_moon",
description="Request a playful human-in-the-loop confirmation before launching a mission to the moon.",
approval_mode="always_require", # CRITICAL: Forces user approval before this tool executes
)
def go_to_moon() -> str:
"""
Request human approval before continuing.
Returns:
A message confirming the approval request has been initiated.
"""
return "Mission control requested. Awaiting human approval for the lunar launch."
Step 4: Create, configure and integrate your agent with AG-UI protocol
Once you have defined your agent tools, create your agent with Microsoft Agent Framework. Then configure the agent with instructions, chat client, and tools, as shown below.
from __future__ import annotations
from textwrap import dedent
from typing import Annotated
# Import core agent framework components for building conversational AI agents
from agent_framework import ChatAgent, ChatClientProtocol, ai_function
# Import CopilotKit integration layer that bridges Agent Framework with the frontend
from agent_framework_ag_ui import AgentFrameworkAgent
from pydantic import Field
// ...
def create_agent(chat_client: ChatClientProtocol) -> AgentFrameworkAgent:
"""
Instantiate the Microsoft Agent Framework with AG-UI.
This is the main entry point for creating the agent. It configures the base ChatAgent
with instructions and tools, then wraps it in an AgentFrameworkAgent for AG-UI integration.
Args:
chat_client: The chat client protocol implementation that handles LLM communication.
Returns:
A fully configured AgentFrameworkAgent ready to handle user interactions.
"""
# Step 1: Create the base ChatAgent with Microsoft Agent Framework
# This agent handles the core conversational logic and tool execution
base_agent = ChatAgent(
name="proverbs_agent", # Internal identifier for this agent
# System instructions: These guide the agent's behaviour throughout the conversation.
# The instructions are carefully crafted to ensure proper state management,
# tool usage, and user experience.
instructions=dedent(
"""
You help users brainstorm, organize, and refine proverbs while coordinating UI updates.
// ...
""".strip()
),
# The chat client handles actual LLM API calls (e.g., to OpenAI, Azure OpenAI, etc.)
chat_client=chat_client,
# Tools: These are the functions the agent can call to perform actions
tools=[update_proverbs, get_weather, go_to_moon],
)
// ...
After that, wrap your agent with AgentFrameworkAgent middleware for frontend communication using AG-UI, as shown below.
from __future__ import annotations
from textwrap import dedent
from typing import Annotated
# Import core agent framework components for building conversational AI agents
from agent_framework import ChatAgent, ChatClientProtocol, ai_function
# Import CopilotKit integration layer that bridges Agent Framework with the frontend
from agent_framework_ag_ui import AgentFrameworkAgent
from pydantic import Field
// ...
def create_agent(chat_client: ChatClientProtocol) -> AgentFrameworkAgent:
"""
Instantiate the Microsoft Agent Framework with AG-UI.
This is the main entry point for creating the agent. It configures the base ChatAgent
with instructions and tools, then wraps it in an AgentFrameworkAgent for CopilotKit integration.
Args:
chat_client: The chat client protocol implementation that handles LLM communication.
Returns:
A fully configured AgentFrameworkAgent ready to handle user interactions.
"""
# Step 1: Create the base ChatAgent with Microsoft Agent Framework
# This agent handles the core conversational logic and tool execution
// ...
# Step 2: Wrap the base agent in an AgentFrameworkAgent for AG-UI integration
# This wrapper adds CopilotKit-specific features like state sync and frontend coordination
return AgentFrameworkAgent(
agent=base_agent, # The underlying ChatAgent we just configured
name="CopilotKitMicrosoftAgentFrameworkAgent", # Display name for the agent
description="Manages proverbs, weather snippets, and human-in-the-loop moon launches.",
# STATE_SCHEMA tells CopilotKit what state this agent manages
state_schema=STATE_SCHEMA,
# PREDICT_STATE_CONFIG maps state fields to the tools that update them
predict_state_config=PREDICT_STATE_CONFIG,
# require_confirmation=False means the agent can update the state and continue
# without waiting for explicit user confirmation after each state change.
# This allows for smoother conversational flow.
require_confirmation=False,
)
Step 5: Build and configure chat client
Once you have wrapped your agent with AgentFrameworkAgent middleware, build and configure a chat client with Azure OpenAI or OpenAI credentials using their respective clients, as shown below in the ./main.py file.
from __future__ import annotations
import os
# Uvicorn: ASGI server for running FastAPI applications
import uvicorn
# ChatClientProtocol: Interface that all chat clients must implement
from agent_framework._clients import ChatClientProtocol
// ...
# Load environment variables from .env file (must be done before accessing os.getenv)
# This allows developers to configure API keys and endpoints without hardcoding them
load_dotenv()
def _build_chat_client() -> ChatClientProtocol:
"""
Build and configure the appropriate chat client based on environment variables.
Returns:
ChatClientProtocol: A configured chat client ready to communicate with an LLM.
Raises:
RuntimeError: If credentials are missing or invalid.
"""
try:
# Option 1: Azure OpenAI Service
# Check if Azure OpenAI endpoint is configured
if bool(os.getenv("AZURE_OPENAI_ENDPOINT")):
# Azure OpenAI uses deployment names instead of model IDs
# Deployments are custom instances of models you create in Azure
deployment_name = os.getenv("AZURE_OPENAI_CHAT_DEPLOYMENT_NAME", "gpt-4o-mini")
return AzureOpenAIChatClient(
# DefaultAzureCredential tries multiple authentication methods:
# 1. Environment variables (AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, etc.)
# 2. Managed Identity (if running on Azure infrastructure)
# 3. Azure CLI credentials (for local development)
credential=DefaultAzureCredential(),
# The name of your deployed model in Azure OpenAI Studio
deployment_name=deployment_name,
# Your Azure OpenAI resource endpoint (e.g., https://my-resource.openai.azure.com/)
endpoint=os.getenv("AZURE_OPENAI_ENDPOINT"),
)
# Option 2: OpenAI API (public service)
# Check if OpenAI API key is configured
if bool(os.getenv("OPENAI_API_KEY")):
return OpenAIChatClient(
# Model identifier from OpenAI's catalogue (e.g., gpt-4o-mini, gpt-4, etc.)
model_id=os.getenv("OPENAI_CHAT_MODEL_ID", "gpt-4o-mini"),
# Your OpenAI API key from platform.openai.com
api_key=os.getenv("OPENAI_API_KEY"),
)
# If neither Azure nor OpenAI credentials are found, raise an error
raise ValueError("Either AZURE_OPENAI_ENDPOINT or OPENAI_API_KEY environment variable is required")
except Exception as exc: # pragma: no cover
# Catch any initialization errors and provide a helpful message
raise RuntimeError(
"Unable to initialize the chat client. Double-check your API credentials as documented in README.md."
) from exc
Then configure your Microsoft Agent Framework + AG-UI agent with the chat client, as shown below.
from __future__ import annotations
import os
# Uvicorn: ASGI server for running FastAPI applications
import uvicorn
# ChatClientProtocol: Interface that all chat clients must implement
from agent_framework._clients import ChatClientProtocol
// ...
# Step 1: Initialize the chat client
# This creates the connection to either Azure OpenAI or OpenAI API
chat_client = _build_chat_client()
# Step 2: Create the agent with the configured chat client
# This instantiates our MAF + AG-UI agent with all its tools and instructions
my_agent = create_agent(chat_client)
// ...
Step 6: Add a FastAPI server and configure your agent endpoint
Once you have built the chat client with credentials, add a FastAPI server that exposes your Microsoft Agent Framework agent over AG-UI, as shown below.
from __future__ import annotations
import os
# Uvicorn: ASGI server for running FastAPI applications
import uvicorn
# add_agent_framework_fastapi_endpoint: CopilotKit integration that registers agent endpoints
from agent_framework_ag_ui import add_agent_framework_fastapi_endpoint
# dotenv: Loads environment variables from .env file
from dotenv import load_dotenv
# FastAPI: Modern web framework for building APIs
from fastapi import FastAPI
# CORSMiddleware: Handles Cross-Origin Resource Sharing for frontend communication
from fastapi.middleware.cors import CORSMiddleware
// ...
# Step 3: Create the FastAPI application
# FastAPI will handle HTTP requests from the frontend and route them to our agent
app = FastAPI(title="CopilotKit + Microsoft Agent Framework (Python)")
# Step 4: Configure CORS (Cross-Origin Resource Sharing)
# This is essential for allowing the frontend (running on a different port/domain)
# to communicate with this backend API
app.add_middleware(
CORSMiddleware,
# allow_origins=["*"] means accept requests from any domain
# In production, you should restrict this to your specific frontend domain(s)
# e.g., allow_origins=["https://myapp.com", "https://www.myapp.com"]
allow_origins=["*"],
# Allow cookies and authentication headers to be included in requests
allow_credentials=True,
# Allow all HTTP methods (GET, POST, PUT, DELETE, etc.)
allow_methods=["*"],
# Allow all headers (Content-Type, Authorization, etc.)
allow_headers=["*"],
)
# Step 5: Register the CopilotKit endpoint
# This function adds the necessary routes to handle CopilotKit's communication protocol
# It creates endpoints for:
# - Agent chat interactions
# - State synchronization
# - Tool execution
# - Streaming responses
add_agent_framework_fastapi_endpoint(
app=app, # The FastAPI application to add routes to
agent=my_agent, # Our configured agent instance
path="/", # Base path for CopilotKit endpoints (frontend will connect here)
)
# ============================================================================
# Main Entry Point
# ============================================================================
if __name__ == "__main__":
# This block runs only when executing this file directly (not when imported)
# It starts the web server that listens for requests from the frontend
# Read server configuration from environment variables with sensible defaults
host = os.getenv("AGENT_HOST", "0.0.0.0") # 0.0.0.0 means listen on all network interfaces
port = int(os.getenv("AGENT_PORT", "8000")) # Default to port 8000
# Start the Uvicorn ASGI server
# - "main:app" references the 'app' variable in the 'main' module
# - host and port determine where the server listens
# - reload=True enables auto-restart when code changes (great for development)
# NOTE: In production, set reload=False for better performance and stability
uvicorn.run("main:app", host=host, port=port, reload=True)
Congrats! You've successfully integrated your Python Microsoft Agent Framework Agent with AG-UI protocol, and it is available at http://localhost:8000 (or specified port) endpoint.
Let’s now see how to add a frontend to your AG-UI wrapped Microsoft Agent Framework agent.
Building a frontend for your Microsoft Agent Framework + AG-UI agent using CopilotKit
In this section, you will learn how to add a frontend to your Microsoft Agent Framework + AG-UI agent using CopilotKit, which runs anywhere that React runs.
Let’s get started.
Step 1: Install CopilotKit packages
To get started, install the latest packages for CopilotKit into your frontend.
npm install @copilotkit/react-ui @copilotkit/react-core @copilotkit/runtime
Step 2: Set up the Copilot Runtime instance
Once you have installed CopilotKit packages, set up the copilot runtime instance with an HttpAgent instance in the /api/copilotkit API route that enables your frontend to make HTTP requests to the backend.
import {
CopilotRuntime, // Main runtime that manages agent communication
ExperimentalEmptyAdapter, // Service adapter for single-agent setups
copilotRuntimeNextJSAppRouterEndpoint, // Next.js App Router endpoint handler
} from "@copilotkit/runtime";
// Import AG-UI client for connecting to Microsoft Agent Framework agents
import { HttpAgent } from "@ag-ui/client";
// Import Next.js types for request handling
import { NextRequest } from "next/server";
// Create a service adapter for the CopilotKit runtime
const serviceAdapter = new ExperimentalEmptyAdapter();
// Create the main CopilotRuntime instance that manages communication between the frontend and backend agents
const runtime = new CopilotRuntime({
// Define the agents that will be available to the frontend
agents: {
// Configure the ADK agent connection
my_agent: new HttpAgent({
// Specify the URL where the Microsoft Agent Framework agent is running
url: "http://localhost:8000/",
}),
},
});
// Export the POST handler for the API route
export const POST = async (req: NextRequest) => {
// Create the request handler using CopilotKit's Next.js helper
const { handleRequest } = copilotRuntimeNextJSAppRouterEndpoint({
runtime, // The CopilotRuntime instance we configured
serviceAdapter, // The service adapter for agent coordination
endpoint: "/api/copilotkit", // The endpoint path (matches this file's location)
});
return handleRequest(req);
};
Step 3: Set up CopilotKit provider
After setting up a Copilot Runtime instance, set up the CopilotKit provider component that manages your ADK agent sessions.
To set up the CopilotKit Provider, the [<CopilotKit>](https://docs.copilotkit.ai/reference/components/CopilotKit) component must wrap the Copilot-aware parts of your application.
For most use cases, it's appropriate to wrap the CopilotKit provider around the entire app, e.g., in your layout.tsx file.
// Step 1: Import necessary types and components from Next.js and CopilotKit
import type { Metadata } from "next";
import { CopilotKit } from "@copilotkit/react-core";
import "./globals.css";
import "@copilotkit/react-ui/styles.css";
// Step 2: Define metadata for the application, used by Next.js for SEO and page headers
export const metadata: Metadata = {
title: "Create Next App",
description: "Generated by create next app",
};
// Step 3: Define the RootLayout component, which wraps the entire application
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
// Step 4: Return the JSX structure for the layout
return (
<html lang="en">
<body className={"antialiased"}>
{/* Step 5: Wrap the children components with CopilotKit provider to enable CopilotKit functionality */}
<CopilotKit runtimeUrl="/api/copilotkit" agent="my_agent">
{children}
</CopilotKit>
</body>
</html>
);
}
Step 4: Set up a Copilot UI component
Once you have set up the CopilotKit Provider, set up a Copilot UI component that enables you to interact with your ADK agent. CopilotKit ships with a number of built-in chat components, which include CopilotPopup, CopilotSidebar, and CopilotChat.
To set up a Copilot UI component, define it alongside your core page components, e.g. in your page.tsx file.
"use client";
import { CopilotKitCSSProperties, CopilotSidebar } from "@copilotkit/react-ui";
import { useState } from "react";
export default function CopilotKitPage() {
const [themeColor, setThemeColor] = useState("#6366f1");
// ...
return (
<main style={{ "--copilot-kit-primary-color": themeColor } as CopilotKitCSSProperties}>
<CopilotSidebar
disableSystemMessage={true}
clickOutsideToClose={false}
labels={{
title: "Popup Assistant",
initial: "👋 Hi, there! You're chatting with an agent.",
}}
suggestions={[
{
title: "Generative UI",
message: "Get the weather in San Francisco.",
},
{
title: "Frontend Tools",
message: "Set the theme to green.",
},
{
title: "Human in the Loop",
message: "Please go to the moon.",
},
{
title: "Write Agent State",
message: "Add a proverb about AI.",
},
{
title: "Update Agent State",
message: "Please remove 1 random proverb from the list if there are any.",
},
{
title: "Read Agent State",
message: "What are the proverbs?",
},
]}
>
<YourMainContent themeColor={themeColor} />
</CopilotSidebar>
</main>
);
}
Step 5: Sync your Microsoft Agent Framework agent state with the frontend
After setting up a Copilot UI component, sync your Microsoft Agent Framework agent state with the frontend using CopilotKit hooks.
To sync your Microsoft Agent Framework agent state with the frontend, use the CopilotKit useCoAgent hook that allows you to share state bidirectionally between your application and the agent.
"use client";
import { useCoAgent } from "@copilotkit/react-core";
// State of the agent, make sure this aligns with your agent's state.
type AgentState = {
proverbs: string[];
}
function YourMainContent({ themeColor }: { themeColor: string }) {
// 🪁 Shared State: https://docs.copilotkit.ai/coagents/shared-state
const { state, setState } = useCoAgent<AgentState>({
name: "my_agent",
initialState: {
proverbs: [
"CopilotKit may be new, but it's the best thing since sliced bread.",
],
},
})
// ...
return (
// ...
)
To render your agent's state, progress, outputs, or tool calls with custom UI components in real-time, you can use tool-based Generative UI.
"use client";
import { useCoAgent, useCopilotAction } from "@copilotkit/react-core";
// ...
function YourMainContent({ themeColor }: { themeColor: string }) {
// ...
//🪁 Generative UI: https://docs.copilotkit.ai/coagents/generative-ui
useCopilotAction({
name: "get_weather",
description: "Get the weather for a given location.",
available: "disabled",
parameters: [
{ name: "location", type: "string", required: true },
],
render: ({ args }) => {
return <WeatherCard location={args.location} themeColor={themeColor} />
},
});
return ( ... )
Then try asking the agent to get the weather for a location. You should see the custom UI component that we added renders the get weather tool call and displays the arguments that were passed to the tool.
Step 6: Implementing Human-in-the-Loop (HITL) in the frontend
Human-in-the-loop (HITL) allows agents to request human input or approval during execution, making AI systems more reliable and trustworthy. This pattern is essential when building AI applications that need to handle complex decisions or actions that require human judgment.
You can learn more about Human in the Loop here on CopilotKit docs.
To implement Human-in-the-Loop (HITL) in the frontend, you need to use the CopilotKit useCopilotKitAction hook with the renderAndWaitForResponse method, which allows returning values asynchronously from the render function, as shown in the src/app/page.tsx file.
import { MoonCard } from "@/components/moon";
import { useCopilotAction } from "@copilotkit/react-core";
// ...
function YourMainContent({ themeColor }: { themeColor: string }) {
// ...
// 🪁 Human In the Loop: https://docs.copilotkit.ai/pydantic-ai/human-in-the-loop
useCopilotAction(
{
name: "go_to_moon",
description: "Go to the moon on request.",
renderAndWaitForResponse: ({ respond, status }) => {
return <MoonCard themeColor={themeColor} status={status} respond={respond} />;
},
},
[themeColor],
);
return (
// ...
);
}
Then try asking the agent to go to the moon. Then the agent will trigger frontend actions by tool/action name to request human input or feedback during execution, and you are prompted with a choice (rendered inside the chat UI). Then you can choose by pressing a button in the chat UI, as shown below.
Step 7: Stream your Microsoft Agent Framework agent responses in the frontend
Once you have synced your Microsoft Agent Framework agent state with the frontend, stream your MAF agent responses or results in the frontend.
To stream your Microsoft Agent Framework agent responses or results in the frontend, pass the agent’s state field values to the frontend components, as shown below.
"use client";
import { useCoAgent } from "@copilotkit/react-core";
import { ProverbsCard } from "@/components/proverbs";
// State of the agent, make sure this aligns with your agent's state.
type AgentState = {
proverbs: string[];
}
function YourMainContent({ themeColor }: { themeColor: string }) {
// 🪁 Shared State: https://docs.copilotkit.ai/coagents/shared-state
const { state, setState } = useCoAgent<AgentState>({
name: "my_agent",
initialState: {
proverbs: [
"CopilotKit may be new, but it's the best thing since sliced bread.",
],
},
})
// ...
return (
<div
style={{ backgroundColor: themeColor }}
className="h-screen flex justify-center items-center flex-col transition-colors duration-300"
>
<ProverbsCard state={state} setState={setState} />
</div>
);
}
If you query your Microsoft Agent Framework agent, you should see the agent’s response or results streaming in the UI, as shown below.
Conclusion
In this guide, we have walked through the steps of building a frontend for your Microsoft Agent Framework agent using AG-UI protocol and CopilotKit.
While we’ve explored a couple of features, we have barely scratched the surface of the countless use cases for CopilotKit, ranging from building interactive AI chatbots to building agentic solutions—in essence, CopilotKit lets you add a ton of useful AI capabilities to your products in minutes.
Hopefully, this guide makes it easier for you to integrate AI-powered Copilots into your existing application.
Follow CopilotKit on Twitter and say hi, and if you'd like to build something cool, join the Discord community.







Top comments (5)
Looking forward to building this, thanks
This is awesome, Bonnie, great tutorial!
Nice!
There seems to be a lot of frameworks popping up, I didn't hear about Microsoft but it makes sense, there are a lot of people in their ecosystem. When did they release it?
Alex, Microsoft announced MAF last week at the .NET 10 conf.
Looks very nice, thanks for posting