本文へ移動
cccskills
無料GitHub で公開

ag-ui

AG-UI (Agent-User Interaction Protocol) is an open, event-based protocol that streams an AI agent's text, tool calls, state and lifecycle events to a frontend over HTTP and Server-Sent Events. Use when the user wants to build an AG-UI server, connect an agent or framework (LangGraph, Mastra, CrewAI, Pydantic AI) to a React or custom UI, stream agent progress and state, or use CopilotKit with AG-UI.

インストール方法を見る

含まれるファイル(2)

  • SKILL.md10.9 KB
  • _scores.json2.2 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

AG-UI — Agent-User Interaction Protocol

Overview

AG-UI standardizes how an agent backend talks to a user-facing app. The app POSTs one JSON RunAgentInput (thread id, run id, messages, state, tools, context, forwarded props); the agent answers with a stream of typed events. It sits beside MCP (agents to tools) and A2A (agent to agent). The protocol was created by the CopilotKit team and is implemented by LangGraph, Mastra, CrewAI, Pydantic AI, Google ADK, Microsoft Agent Framework, AWS Strands, Agno, LlamaIndex, AG2 and others. Version 1.0 shipped in September 2026; this skill was checked against @ag-ui/core/client/encoder 1.0.1 and the Python ag-ui-protocol 1.0.0.

There are no @ag-ui/server or @ag-ui/react packages and no AgentServer/useAgent in @ag-ui/*. The SDK packages are @ag-ui/core (types and constants), @ag-ui/client (HttpAgent, subscribers), @ag-ui/encoder (EventEncoder) and, per framework, @ag-ui/langgraph, @ag-ui/mastra and so on. The React layer comes from CopilotKit (@copilotkit/react-core/v2).

Instructions

Event vocabulary

Every event has a type. The families:

  • Lifecycle: RUN_STARTED, RUN_FINISHED, RUN_ERROR, STEP_STARTED, STEP_FINISHED
  • Text: TEXT_MESSAGE_START, TEXT_MESSAGE_CONTENT (with delta), TEXT_MESSAGE_END, plus a compact TEXT_MESSAGE_CHUNK
  • Tool calls: TOOL_CALL_START, TOOL_CALL_ARGS (streamed JSON delta), TOOL_CALL_END, TOOL_CALL_RESULT
  • State: STATE_SNAPSHOT (replace the whole state), STATE_DELTA (JSON Patch operations), MESSAGES_SNAPSHOT
  • Activity: ACTIVITY_SNAPSHOT, ACTIVITY_DELTA; Reasoning: REASONING_* (these replace the deprecated THINKING_*); Subagents: SUBAGENT_STARTED / FINISHED / ERROR
  • Escape hatches: RAW and CUSTOM (name plus value)

A run starts with RUN_STARTED and ends with RUN_FINISHED or RUN_ERROR. Every opened message, tool call or reasoning span must be closed before the run finishes, or the 1.0 client fails the run.

A Node.js server (HTTP + SSE)

npm install --save-exact @ag-ui/core@1.0.1 @ag-ui/encoder@1.0.1 @ag-ui/client@1.0.1
// server.mjs: a minimal AG-UI endpoint on POST /agent
import { createServer } from 'node:http';
import { randomUUID } from 'node:crypto';
import { EventType } from '@ag-ui/core';
import { EventEncoder } from '@ag-ui/encoder';

createServer(async (req, res) => {
  if (req.method !== 'POST' || req.url !== '/agent') return res.writeHead(404).end();
  let body = '';
  for await (const chunk of req) body += chunk;
  const input = JSON.parse(body);                      // RunAgentInput
  const encoder = new EventEncoder({ accept: req.headers.accept });
  res.writeHead(200, { 'Content-Type': encoder.getContentType(), 'Cache-Control': 'no-cache' });
  const send = (event) => res.write(encoder.encode(event));

  send({ type: EventType.RUN_STARTED, threadId: input.threadId, runId: input.runId });
  send({ type: EventType.STATE_SNAPSHOT, snapshot: { status: 'searching', progress: 0 } });

  const callId = randomUUID();
  send({ type: EventType.TOOL_CALL_START, toolCallId: callId, toolCallName: 'search_orders' });
  send({ type: EventType.TOOL_CALL_ARGS, toolCallId: callId, delta: JSON.stringify({ email: 'maria@brightbasket.dev' }) });
  send({ type: EventType.TOOL_CALL_END, toolCallId: callId });
  send({ type: EventType.TOOL_CALL_RESULT, messageId: randomUUID(), toolCallId: callId, content: JSON.stringify({ orders: 3 }), role: 'tool' });
  send({ type: EventType.STATE_DELTA, delta: [{ op: 'replace', path: '/progress', value: 100 }] });

  const messageId = randomUUID();
  send({ type: EventType.TEXT_MESSAGE_START, messageId, role: 'assistant' });
  for (const word of ['Maria', 'has', '3', 'open', 'orders.']) {
    send({ type: EventType.TEXT_MESSAGE_CONTENT, messageId, delta: word + ' ' });
  }
  send({ type: EventType.TEXT_MESSAGE_END, messageId });

  send({ type: EventType.RUN_FINISHED, threadId: input.threadId, runId: input.runId });
  res.end();
}).listen(8787, '127.0.0.1');

If you hit a failure after the stream has opened, send RUN_ERROR (message, optional code) instead of changing the HTTP status. Reject bad input before streaming with a normal HTTP error status.

A Python server

pip install ag-ui-protocol fastapi uvicorn
# app.py
import uuid
from fastapi import FastAPI, Request
from fastapi.responses import StreamingResponse
from ag_ui.core import (RunAgentInput, EventType, RunStartedEvent, RunFinishedEvent,
                        TextMessageStartEvent, TextMessageContentEvent, TextMessageEndEvent)
from ag_ui.encoder import EventEncoder

app = FastAPI()

@app.post("/agent")
async def agent(input_data: RunAgentInput, request: Request):
    encoder = EventEncoder(accept=request.headers.get("accept"))

    async def events():
        yield encoder.encode(RunStartedEvent(type=EventType.RUN_STARTED, thread_id=input_data.thread_id, run_id=input_data.run_id))
        message_id = str(uuid.uuid4())
        yield encoder.encode(TextMessageStartEvent(type=EventType.TEXT_MESSAGE_START, message_id=message_id, role="assistant"))
        yield encoder.encode(TextMessageContentEvent(type=EventType.TEXT_MESSAGE_CONTENT, message_id=message_id, delta="Hello from AG-UI"))
        yield encoder.encode(TextMessageEndEvent(type=EventType.TEXT_MESSAGE_END, message_id=message_id))
        yield encoder.encode(RunFinishedEvent(type=EventType.RUN_FINISHED, thread_id=input_data.thread_id, run_id=input_data.run_id))

    return StreamingResponse(events(), media_type=encoder.get_content_type())

Run it with uvicorn app:app --port 8000. Python field names are snake_case; on the wire they are camelCase (threadId, runId).

A TypeScript client

// client.mjs
import { HttpAgent } from '@ag-ui/client';

const agent = new HttpAgent({ url: 'http://127.0.0.1:8787/agent' });
agent.messages = [{ id: 'm1', role: 'user', content: 'How many open orders does maria@brightbasket.dev have?' }];

await agent.runAgent({}, {
  onTextMessageContentEvent: ({ event }) => process.stdout.write(event.delta),
  onToolCallEndEvent: ({ toolCallName, toolCallArgs }) => console.log('[tool]', toolCallName, toolCallArgs),
  onStateChanged: ({ state }) => console.log('[state]', JSON.stringify(state)),
  onRunFailedEvent: ({ error }) => console.error('run failed', error),
});
console.log(agent.messages, agent.state);   // the client has applied every event for you

runAgent applies events to agent.messages and agent.state (including STATE_DELTA patches) and calls subscriber hooks such as onRunStartedEvent, onTextMessageStartEvent, onToolCallResultEvent, onStateSnapshotEvent, onCustomEvent and onNewMessage.

React with CopilotKit

CopilotKit is the React layer built on AG-UI. Register your AG-UI endpoint in the Copilot Runtime, then use the hooks. Check the CopilotKit docs for your framework's exact quickstart.

// app/api/copilotkit/[[...slug]]/route.ts
import { CopilotRuntime, createCopilotRuntimeHandler, InMemoryAgentRunner } from "@copilotkit/runtime/v2";
import { HttpAgent } from "@ag-ui/client";

const runtime = new CopilotRuntime({
  agents: { support: new HttpAgent({ url: "http://127.0.0.1:8787/agent" }) },   // the agent's own URL, not /api/copilotkit
  runner: new InMemoryAgentRunner(),
});
const handler = createCopilotRuntimeHandler({ runtime, basePath: "/api/copilotkit" });
export const GET = handler; export const POST = handler; export const PATCH = handler; export const DELETE = handler;
// app/page.tsx
import { CopilotKit, CopilotChat } from "@copilotkit/react-core/v2";

export default function Page() {
  return (
    <CopilotKit runtimeUrl="/api/copilotkit" useSingleEndpoint={false}>
      <CopilotChat agentId="support" />
    </CopilotKit>
  );
}

For a fully custom UI use useAgent({ agentId }) (exposes messages, isRunning) and useCopilotKit() (copilotkit.runAgent({ agent })), plus useFrontendTool, useHumanInTheLoop and useRenderToolCall for tools the UI handles itself. Scaffold a project with npx create-ag-ui-app@latest or npx copilotkit@latest create.

Examples

Example 1: "Stream my agent's progress and results to the browser"

Run the Node server above (node server.mjs) and the client (node client.mjs). The client prints [state] {"status":"searching","progress":0}, then [tool] search_orders { email: 'maria@brightbasket.dev' }, then the streamed sentence Maria has 3 open orders., and ends with agent.state equal to { status: 'searching', progress: 100 } because the STATE_DELTA patch was applied.

Example 2: "Put our existing LangGraph agent behind a React chat"

Keep the LangGraph agent as is, expose it through its AG-UI integration (@ag-ui/langgraph for JS; the Python package from the LangGraph quickstart), register the agent's URL with new HttpAgent({ url }) in the runtime agents map as shown above, and render <CopilotChat agentId="support" />. Tool calls and state changes then appear in the UI without custom parsing.

Guidelines

  • Pin @ag-ui/client to one version across your app and @copilotkit/runtime; two copies cause subtle type and instance errors.
  • 1.0 is strict: unknown event types are dropped with a warning, unknown properties are stripped (put extra data in metadata, or send it to the agent in forwardedProps), a malformed known field fails the run, and unclosed messages, tool calls or reasoning spans at RUN_FINISHED fail the run. Optional fields must be absent, not null.
  • Validators moved to @ag-ui/core/schemas and need zod (3.25.18+ or 4.x); the @ag-ui/core main entry is types only.
  • Replace THINKING_* events with REASONING_*; the client still translates old streams and warns, but the shims expire.
  • Use STATE_DELTA (JSON Patch) for small frequent changes and STATE_SNAPSHOT to resync; keep agent state serializable and free of secrets, because it reaches the browser.
  • Authenticate the endpoint yourself (headers, cookies, tokens); the protocol does not. Human-in-the-loop confirmations are enforced on the server, not only in the UI.
  • Debug with the AG-UI Dojo (dojo.ag-ui.com) and by curl -N against your endpoint with Accept: text/event-stream.

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

Scripts and configures production rendering in Autodesk 3ds Max with the V-Ray and Corona renderers: output size and files, render elements, denoising, light mix, batch and command-line rendering, and network rendering. Use when a user asks to set up a production render, render several cameras in one batch, render from the command line or on a render farm, add render passes for compositing, or cut render time for archviz and product shots.

日本語の概要は準備中です。原文の説明を表示しています。

TerminalSkills/skills1632026年10月4日 更新

Covers scripting Autodesk 3ds Max, the 3D modeling and rendering application, with MAXScript and Python (pymxs): scene manipulation, object creation, material assignment, camera and light setup, batch operations, and file I/O. Use when tasks involve automating repetitive 3ds Max workflows, batch processing scenes, running scripts headless with 3dsmaxbatch, creating custom tools, or scripting scene setup for archviz, product visualization, or VFX.

日本語の概要は準備中です。原文の説明を表示しています。

TerminalSkills/skills1632026年10月4日 更新

3proxy

無料

3proxy is a small open-source proxy server that runs HTTP/HTTPS, SOCKS4/5, SNI and TCP/UDP port-mapping proxies from one config file. Use when a user asks to set up an HTTP or SOCKS5 proxy, add proxy users and passwords, write 3proxy access rules, chain or rotate upstream (parent) proxies, limit bandwidth, connections or monthly traffic per user, run 3proxy in Docker, or fix a 3proxy.cfg that will not start.

日本語の概要は準備中です。原文の説明を表示しています。

TerminalSkills/skills1632026年10月4日 更新

Builds Agent2Agent (A2A) servers and clients, the open protocol (originally from Google, now under the Linux Foundation) that lets AI agents from different frameworks call each other. Use when the user wants to create an A2A-compliant agent, build an Agent Card, implement task management, connect agents across frameworks, set up agent discovery, handle streaming responses, implement push notifications, or orchestrate multi-agent workflows. Trigger words: a2a, agent to agent, agent2agent, a2a protocol, a2a server, a2a client, agent card, agent interoperability, agent collaboration, multi-agent, agent discovery, a2a sdk, a2a task.

日本語の概要は準備中です。原文の説明を表示しています。

TerminalSkills/skills1632026年10月4日 更新

Plans a controlled experiment (A/B test) so its result can be trusted: writes the hypothesis, picks one primary metric and the guardrails, computes sample size and run time, specifies how visitors are assigned and when exposure is logged, and reads out the result with a confidence interval. Use when someone says "set up an A/B test", "split test this page", "how many visitors do I need", "how long should the experiment run", "is this result significant", "can I stop the test early", or wants to test a headline, price, layout or onboarding change against the current version.

日本語の概要は準備中です。原文の説明を表示しています。

TerminalSkills/skills1632026年10月4日 更新

ably

無料

Ably is a hosted realtime messaging service: clients publish and subscribe to named channels over WebSockets, see who is present, replay message history, and resume after a dropped connection. Use when a user asks to "add realtime updates", "push live notifications to the browser", "show who is online", "add a chat room with typing indicators", "publish from a serverless function", or "authenticate Ably clients without exposing the API key". Covers the ably 2.x JavaScript SDK (Realtime and REST), JWT token authentication, presence, history and rewind, batch publishing, and the @ably/chat 1.x SDK.

日本語の概要は準備中です。原文の説明を表示しています。

TerminalSkills/skills1632026年10月4日 更新

TerminalSkills のスキルをすべて見る

このスキルの問題を報告する