mcpField
A
ag2-ag-ui

ag2-ag-ui

github.com/ag2aiAgent workflows1267 installsUpdated 13w ago
Repository

About ag2-ag-ui

An AG-UI integration guide for developers building web interfaces for AG2 agents. It describes a FastAPI backend and CopilotKit frontend setup, and lists the event types supported for streaming agent activity to the UI.

Key features

  1. 01Run lifecycle events
  2. 02Streaming text and reasoning events
  3. 03Tool-call lifecycle events
  4. 04Shared-state snapshots
  5. 05Sub-task step events

Use cases

  1. 01Rendering AG2 conversations in React or Next.js
  2. 02Streaming text and reasoning to a UI
  3. 03Showing backend tool-call results
  4. 04Syncing shared state and sub-task progress

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/ag2ai/ag2-skills --skill ag2-ag-ui

After installing, type/ag2-ag-uiin Claude Code to confirm it loaded.

Details

From the project README

AG-UI integration

When to use

  • The user is building a web UI (React / Next.js / anything HTTP+SSE) that should talk to an AG2 agent.
  • They want streaming text, reasoning, tool-call rendering, shared state sync, or sub-task step tracking surfaced to the frontend with a standard protocol — not a custom REST/WebSocket contract.
  • They're using or considering CopilotKit (the recommended React client).

For a custom narrow-purpose API where you own the contract end-to-end, skip AG-UI and write a plain endpoint instead.

Supported AG-UI features

FeatureStatus
Run lifecycle (RUN_STARTED / RUN_FINISHED / RUN_ERROR)✓
Streaming text events (TEXT_MESSAGE_START / _CONTENT / _END / _CHUNK)✓
Reasoning events (REASONING_START / _END, REASONING_MESSAGE_START / _CONTENT / _END)✓
Backend tool lifecycle (TOOL_CALL_START / _ARGS / _RESULT / _END)✓
Frontend-tool dispatch (TOOL_CALL_CHUNK for client tools in RunAgentInput.tools)✓
Shared-state snapshots (STATE_SNAPSHOT)✓
Sub-task steps (STEP_STARTED / STEP_FINISHED, emitted on TaskStarted / TaskCompleted)✓
Human input checkpoints surfaced as AG-UI events✗ — no human-input event family; hitl_hook passes through to agent.ask

Installation

pip install "ag2[ag-ui]"

Required. Run this install before delivering the code. If you cannot run commands, state the exact pip install command.

60-second recipe — FastAPI server

from fastapi import FastAPI, Header
from fastapi.responses import StreamingResponse

from ag2 import Agent
from ag2.ag_ui import AGUIStream, RunAgentInput
from ag2.config import OpenAIConfig

agent = Agent(
    name="support_bot",
    prompt="You help users with billing questions.",
    config=OpenAIConfig(model="gpt-4o-mini"),
)

stream = AGUIStream(agent)
app = FastAPI()

@app.post("/chat")
async def run_agent(message: RunAgentInput, accept: str | None = Header(None)) -> StreamingResponse:
    return StreamingResponse(
        stream.dispatch(message, accept=accept),
        media_type=accept or "text/event-stream",
    )
uvicorn run_ag_ui:app --reload --port 8000

Test:

curl -N -X POST http://127.0.0.1:8000/chat \
  -H "Content-Type: application/json" \
  -H "Accept: text/event-stream" \
  -d '{"thread_id":"t1","run_id":"r1","messages":[{"id":"m1","role":"user","content":"Hello"}],"state":{},"context":[],"tools":[]}'

Lower-friction alternative — build_asgi()

If you don't need custom auth / middleware, mount the ASGI endpoint directly:

from ag2.ag_ui import AGUIStream
from fastapi import FastAPI

app = FastAPI()
stream = AGUIStream(agent)
app.mount("/chat", stream.build_asgi())

CopilotKit frontend (recommended for React / Next.js)

Two ways to start:

# Option A — CopilotKit bootstrap
npx copilotkit@latest create -f ag2

# Option B — clone the reference starter
# https://github.com/ag2ai/ag2-copilotkit-starter

The starter layout:

ag2-copilotkit-starter/
├── agent-py/     # Python backend (AG2 + AG-UI)
└── ui-react/     # React + CopilotKit frontend

Backend serves /chat on port 8008 by default. The Next.js route at ui-react/app/api/copilotkit/route.ts bridges the UI to the backend:

import { HttpAgent } from "@ag-ui/client";
import { CopilotRuntime, ExperimentalEmptyAdapter, copilotRuntimeNextJSAppRouterEndpoint } from "@copilotkit/runtime";
import { NextRequest } from "next/server";

const agent = new HttpAgent({ url: "http://localhost:8008/chat" });
const runtime = new CopilotRuntime({ agents: { weather_agent: agent } });

export async function POST(req: NextRequest) {
  const { handleRequest } = copilotRuntimeNextJSAppRouterEndpoint({
    runtime,
    serviceAdapter: new ExperimentalEmptyAdapter(),
    endpoint: "/api/copilotkit",
  });
  return handleRequest(req);
}

Wrap your app:

import { CopilotKit } from "@copilotkit/react-core";
import "@copilotkit/react-ui/styles.css";

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <CopilotKit agent="weather_agent" runtimeUrl="/api/copilotkit">
          {children}
        </CopilotKit>
      </body>
    </html>
  );
}

Render chat (<CopilotChat />), and use useCopilotAction({...}) in client components to render generative UI tied to backend tool calls.

Production checklist

  • CORS — allow your frontend origin on the AG-UI backend (POST, OPTIONS, auth headers).
  • Auth — protect both /api/copilotkit (Next.js route) and backend /chat. Don't rely on client-only secrets.
  • SSE buffering — verify backend response is Content-Type: text/event-stream and that proxy layers (Nginx, CloudFront, etc.) don't buffer SSE.
  • Timeouts / retries — conservative values for long-running tool workflows; only retry idempotent requests.
  • Tool inputs are untrusted — validate and authorize server-side before invoking privileged tools. Log tool execution with request IDs.
  • Tool name parity — frontend useCopilotAction name must match backend @tool name exactly.

Going deeper

Common pitfalls

  • Missing ag-ui extra — pip install "ag2[ag-ui]" is required; without it from ag2.ag_ui import AGUIStream will fail.
  • CORS blocked — frontend can't hit the backend in dev. Add CORSMiddleware to the FastAPI app for the dev origin.
  • No streaming output — proxy or Content-Type issue. Test with raw curl -N first to isolate.
  • Tool UI not rendering — tool name on the React side (useCopilotAction({ name: "..." })) doesn't exactly match the backend @tool name.
  • Putting the endpoint behind a SSE-incompatible proxy — many proxies buffer event-stream responses by default. Disable buffering on the route.
  • Trying to use AGUIStream with classic ConversableAgent — the description here covers ag2.Agent. Classic AG2 agents can be exposed differently; check the AG2 docs for that path.

Comments

Markdown supported