SuperAPI AI Directory

ag2-ag-ui

Agents & models

View repository

Updated 10-15 10:12

About this skill

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

Feature Status
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.