Skip to content

AG-UI 项目解读

项目信息

  • 项目名称:AG-UI
  • 项目描述: AG-UI(Agent-User Interaction Protocol)是一个开放的、轻量级的、基于事件的协议标准,用于标准化 AI Agent 与用户界面之间的通信。它是 Agentic 协议栈中的"用户交互层",与 MCP(Agent ↔ Tools)和 A2A(Agent ↔ Agent)形成互补的三层架构。
  • 项目地址:https://github.com/ag-ui-protocol/ag-ui
  • 官方文档:https://docs.ag-ui.com/introduction

核心价值

  1. 标准化 Agent-UI 交互:约 30 种标准事件类型,覆盖文本流、工具调用、状态同步、推理过程等所有 Agent-UI 交互场景
  2. 框架无关:18+ 框架集成适配器,同一套前端代码可以对接 LangGraph、CrewAI、Mastra 等不同后端
  3. 多语言支持:TypeScript 参考实现 + Python SDK + 7 个社区语言 SDK (Go, Java, Kotlin, Ruby, Rust, Dart, C++)
  4. 传输层无关:支持 SSE (JSON)、HTTP Binary (Protobuf)、WebSockets 等多种传输方式

1. 项目概览

1.1 项目定位与核心价值

AG-UI(Agent-User Interaction Protocol)是一个开放的、轻量级的、基于事件的协议标准,用于标准化 AI Agent 与用户界面之间的通信。它是 Agentic 协议栈中的"用户交互层",与 MCP(Agent ↔ Tools)和 A2A(Agent ↔ Agent)形成互补的三层架构。

一句话定位:AG-UI 是 Agent 世界中的"USB 协议"——统一接口标准,让任何 Agent 后端都能与任何前端 UI 无缝协作。

核心价值

  1. 标准化 Agent-UI 交互:约 30 种标准事件类型,覆盖文本流、工具调用、状态同步、推理过程等所有 Agent-UI 交互场景
  2. 框架无关:18+ 框架集成适配器,同一套前端代码可以对接 LangGraph、CrewAI、Mastra 等不同后端
  3. 多语言支持:TypeScript 参考实现 + Python SDK + 7 个社区语言 SDK (Go, Java, Kotlin, Ruby, Rust, Dart, C++)
  4. 传输层无关:支持 SSE (JSON)、HTTP Binary (Protobuf)、WebSockets 等多种传输方式

1.2 目标用户与使用场景

用户画像典型场景
前端开发者构建 AI-powered Chat UI,使用统一 API 对接不同的 Agent 后端
Agent 框架维护者为框架添加"前端友好"的输出能力,提升框架的用户体验
全栈 AI 团队Agent 与 UI 层解耦,前后端独立演进,支持多框架切换

核心业务场景

  • Agentic Chat:实时流式对话,边生成边显示
  • Generative UI:Agent 动态决定渲染的 UI 组件(表单、图表、地图等)
  • Human-in-the-Loop:Agent 在关键操作前暂停,等待用户确认
  • Shared State:Agent 状态实时同步到前端,用户可观察"思考过程"

1.3 核心技术亮点

  • Observable 流模式(RxJS):原生支持多值推送、操作符链、取消订阅,比 Promise/AsyncIterator 更灵活
  • 双重序列化(SSE + Protobuf):调试友好 + 生产高性能,通过 HTTP Accept 头自动协商
  • JSON Patch (RFC 6902) 增量状态:类似 Git 的 snapshot + diff 模型,减少网络开销
  • 责任链中间件:可插拔的横切关注点实现,支持 A2A 代理、MCP 工具集成、向后兼容
  • 版本化向后兼容:内置 3 层向后兼容中间件(v0.0.39/45/47),平滑升级协议

1.4 技术栈与选型对比

技术选型选择方案替代方案选择原因
流处理RxJS ObservableAsyncIterator / EventEmitter多值推送、操作符链、内建取消订阅
序列化SSE JSON + Protobuf纯 JSON / 纯 Protobuf兼顾调试便利性和生产性能
状态同步JSON Patch (RFC 6902)完整状态快照 / CRDT轻量增量更新,适合高频状态变更
类型验证Zodio-ts / YupTypeScript 原生类型推断、链式 API
构建系统pnpm + NxTurborepo / Lerna缓存、并行 30、独立版本管理
包管理pnpm workspacenpm workspaces / yarn严格的依赖隔离、节省磁盘空间

1.5 生态位分析

+------------------------------------------------------------------+
|                    Agentic 协议栈 (The Stack)                       |
|                                                                   |
|   +---------------------+   AG-UI (本仓库)                         |
|   | Agent ↔ UI 交互层   |   "让 Agent 与用户界面实时交互"            |
|   +---------------------+                                         |
|            ^                                                       |
|            |                                                       |
|   +---------------------+   A2A (Agent-to-Agent)                  |
|   | Agent ↔ Agent 通信层 |   "让多个 Agent 相互通信协作"             |
|   +---------------------+                                         |
|            ^                                                       |
|            |                                                       |
|   +---------------------+   MCP (Model Context Protocol)           |
|   | Agent ↔ Tools 工具层 |   "让 Agent 使用外部工具和数据源"         |
|   +---------------------+                                         |
+------------------------------------------------------------------+

2. 整体架构设计

2.1 架构概述

AG-UI 采用基于事件的协议中间件架构,核心思想是"标准化事件总线 + 可插拔适配器"。系统分为六个逻辑层:

  • 协议定义层 (Core):定义约 30 种标准事件类型、核心实体(Message、ToolCall、State)和 Zod Schema 验证
  • 客户端运行时 (Client):提供 AbstractAgent 抽象基类、HttpAgent HTTP 客户端、Subscriber 事件监听系统和 Middleware 中间件管道
  • 编解码层 (Encoder/Proto):负责事件序列化(SSE JSON / Protobuf 二进制)和传输协议适配
  • 集成适配层 (Integrations):18+ 框架适配器,将各 Agent 框架的专有输出转换为 AG-UI 标准事件
  • 中间件层 (Middlewares):横切关注点实现(A2A 代理通信、MCP 工具集成、事件节流、向后兼容等)
  • 应用层 (Apps):Dojo 演示平台和 CLI 示例

2.2 整体架构图

text
+===================================================================================+
|                              AG-UI 整体架构 (Layered Architecture)                  |
+===================================================================================+

+------------------------------------------+  +-----------------------------------+
|         应用层 (Application Layer)        |  |         文档层 (Docs)             |
|  +------------------+  +---------------+ |  |  concepts/ quickstart/ tutorials/  |
|  | AG-UI Dojo       |  | CLI Example   | |  |  sdk/ development/                |
|  | (Next.js + E2E)  |  | (Terminal UI) | |  |                                   |
|  +------------------+  +---------------+ |  +-----------------------------------+
+---------------------------+------------------+
                            | (HTTP / SSE / Protobuf)
                            v
+===================================================================================+
|                      中间件层 (Middleware Layer)                                    |
|  +----------------+  +------------------+  +---------------------+                |
|  | A2A Middleware  |  | A2UI Middleware  |  | MCP Middleware      |                |
|  | (Agent-to-Agent)|  | (Cross-Platform  |  | (Tool Integration)  |                |
|  |                 |  |  UI Rendering)   |  |                     |                |
|  +----------------+  +------------------+  +---------------------+                |
|  +------------------------------+  +-----------------------------+                |
|  | MCP Apps Middleware           |  | Event Throttle Middleware   |                |
|  | (Generative UI Support)       |  | (Rate Limiting)             |                |
|  +------------------------------+  +-----------------------------+                |
+===================================================================================+
                            |
                            v
+===================================================================================+
|                      客户端运行时层 (Client Runtime Layer)                          |
|                                                                                   |
|  +-----------------------------------------------------------------------+        |
|  |                    AbstractAgent (抽象基类)                            |        |
|  |  - messages: Message[]      - state: State                           |        |
|  |  - subscribers: AgentSubscriber[]     - middlewares: Middleware[]     |        |
|  |  - abstract run(input: RunAgentInput): Observable<BaseEvent>         |        |
|  |                                                                       |        |
|  |  runAgent() Pipeline:                                                |        |
|  |  +-> prepareInput --> middlewareChain.run() --> transformChunks()    |        |
|  |  |-> verifyEvents() --> takeUntil(detach$) --> apply(events)         |        |
|  |  |-> processApplyEvents() --> catchError() --> finalize()            |        |
|  +-----------------------------------------------------------------------+        |
|                                                                                   |
|  +----------------------------+  +-----------------------------------+            |
|  | HttpAgent                  |  | AgentSubscriber System            |            |
|  | - url: string              |  | - onRunStartedEvent()             |            |
|  | - headers: Record<string>  |  | - onTextMessageContentEvent()     |            |
|  | - run(): Observable        |  | - onToolCallStartEvent()          |            |
|  |   via SSE or Protobuf      |  | - onStateSnapshotEvent()          |            |
|  +----------------------------+  | - onRunFinishedEvent()            |            |
|                                   +-----------------------------------+            |
+===================================================================================+
                            |
                            v
+===================================================================================+
|                       编解码层 (Encoding / Decoding Layer)                          |
|                                                                                   |
|  +---------------------------------+  +-------------------------------------+     |
|  | EventEncoder (@ag-ui/encoder)   |  | Proto Codec (@ag-ui/proto)          |     |
|  | - encodeSSE(event): string      |  | - encode(event): Uint8Array         |     |
|  | - encodeBinary(event):Uint8Array|  | - decode(bytes): BaseEvent          |     |
|  | - encodeProtobuf(event): bytes  |  | - Protobuf Schema Definitions       |     |
|  | - getContentType(): string      |  |                                     |     |
|  +---------------------------------+  +-------------------------------------+     |
|                                                                                   |
|  +---------------------------------+  +-------------------------------------+     |
|  | SSE Parser                      |  | Proto Parser                        |     |
|  | - parseSSEStream(): Observable  |  | - parseProtoStream(): Observable    |     |
|  |   data: {...}\n\n stream        |  |   [4B length][protobuf bytes]...    |     |
|  +---------------------------------+  +-------------------------------------+     |
+===================================================================================+
                            |
                            v
+===================================================================================+
|                      协议定义层 (Protocol Definition Layer)                         |
|                                                                                   |
|  +-----------------------------------------------------------------------+        |
|  |                       @ag-ui/core                                     |        |
|  |                                                                       |        |
|  |  Event Types (~30):                                                  |        |
|  |  +-- Lifecycle:  RUN_STARTED, RUN_FINISHED, RUN_ERROR                 |        |
|  |  +-- Text Msg:   TEXT_MESSAGE_START/CONTENT/END/CHUNK                 |        |
|  |  +-- Tool Call:  TOOL_CALL_START/ARGS/END/RESULT/CHUNK                |        |
|  |  +-- Reasoning:  REASONING_START/MESSAGE_*/END                        |        |
|  |  +-- State:      STATE_SNAPSHOT, STATE_DELTA, MESSAGES_SNAPSHOT       |        |
|  |  +-- Activity:   ACTIVITY_SNAPSHOT, ACTIVITY_DELTA                    |        |
|  |  +-- Steps:      STEP_STARTED, STEP_FINISHED                          |        |
|  |  +-- Other:      RAW, CUSTOM                                         |        |
|  |                                                                       |        |
|  |  Core Types:                                                          |        |
|  |  +-- RunAgentInput, Message, ToolCall, State, Interrupt              |        |
|  |  +-- AgentCapabilities (Identity, Transport, Tools, Output, etc.)     |        |
|  |                                                                       |        |
|  |  All validated via Zod Schemas at runtime                             |        |
|  +-----------------------------------------------------------------------+        |
+===================================================================================+
                            ^
                            | (事件转换)
+===================================================================================+
|                    集成适配层 (Integration Adapter Layer)                            |
|                                                                                   |
|  +--------+  +---------+  +---------+  +--------+  +----------+  +---------+     |
|  |LangGraph|  | CrewAI  |  | Mastra  |  | Pydantic|  | Vercel   |  | Google  |     |
|  | Python  |  | Python  |  | TS      |  | AI      |  | AI SDK   |  | ADK     |     |
|  +--------+  +---------+  +---------+  +--------+  +----------+  +---------+     |
|  | LlamaIndex | Agno  |  | AWS-Strands| | MS Agent |  | LangChain|  | WatsonX |    |
|  +--------+  +---------+  +---------+  +--------+  +----------+  +---------+     |
|  |  + 8 more integrations...                                             |        |
|  +-----------------------------------------------------------------------+        |
|                                                                                   |
|  Each integration:                                                                 |
|  1. Translates framework-specific events -> AG-UI standard events                 |
|  2. Python server + TypeScript client (even for Python-only frameworks)           |
|  3. Examples showcasing features (agentic chat, gen UI, HITL, shared state)       |
+===================================================================================+

2.3 目录结构

shell
ag-ui/
├── .github/                          # 【配置】CI/CD 工作流与 Issue/PR 模板
   ├── workflows/                    # 【配置】26+ GitHub Actions 工作流(lint/test/publish/e2e)
   ├── ISSUE_TEMPLATE/               # 【配置】Bug/Feature/Doc Issue 模板(3 个)
   └── scripts/                      # 【配置】CI 辅助脚本
├── apps/                             # 【UI 视图】示例应用与演示平台
   ├── dojo/                         # 【UI 视图】AG-UI Dojo - 协议功能演示与 e2e 测试平台
   ├── src/                      # 【UI 视图】Next.js App Router 源码
   ├── agents.ts            # 【业务模块】所有集成 Agent 的注册配置中心
   ├── menu.ts              # 【业务模块】侧边栏菜单与功能特性声明(单一事实来源)
   ├── env.ts               # 【业务模块】Agent URL 环境变量定义
   ├── proxy.ts            # 【核心基建】API 代理中间件
   ├── config.ts           # 【配置】Dojo 全局配置
   ├── app/                 # 【UI 视图】Next.js App Router 页面路由
   ├── components/          # 【UI 视图】React 组件(Chat UI, 配置面板等)
   ├── contexts/            # 【UI 视图】React Context(Agent 状态、配置上下文)
   ├── lib/                 # 【工具集】通用工具库
   ├── types/               # 【核心基建】Dojo 类型定义
   ├── utils/               # 【工具集】工具函数
   └── styles/              # 【UI 视图】样式文件
   ├── e2e/                      # 【质量保证】Playwright 端到端测试
   ├── tests/               # 【质量保证】各集成功能测试(按框架分目录)
   ├── featurePages/        # 【质量保证】共享功能测试页面对象
   └── pages/               # 【质量保证】框架特定页面对象
   └── scripts/                  # 【工具集】Dojo 准备/运行/构建脚本
   └── client-cli-example/           # 【UI 视图】CLI 终端 Agent 示例
       └── src/                      # 【UI 视图】Agent 实现 + Weather/Browser 工具
├── sdks/                             # 【核心基建】多语言 SDK 实现
   ├── typescript/                   # 【核心基建】TypeScript 主 SDK(协议参考实现)
   └── packages/
       ├── core/                 # 【核心基建】@ag-ui/core - 事件定义、Schema 验证、核心类型
   └── src/
       ├── events.ts     # 【核心基建】EventType 枚举 + 30 个事件 Zod Schema 定义
       ├── types.ts      # 【核心基建】Message/ToolCall/State/RunAgentInput 类型
       ├── capabilities.ts # 【核心基建】AgentCapabilities 能力声明 Schema
       └── event-factories.ts # 【工具集】事件工厂函数
       ├── client/               # 【核心基建】@ag-ui/client - Agent 运行时引擎
   └── src/
       ├── agent/        # 【核心基建】AbstractAgent + HttpAgent + Subscriber
       ├── run/          # 【核心基建】HTTP 请求执行 + 流读取
       ├── transform/    # 【核心基建】SSE/Proto 流解析 → BaseEvent 转换
       ├── apply/        # 【核心基建】事件应用到 messages/state 逻辑
       ├── middleware/   # 【核心基建】Middleware 抽象 + 向后兼容中间件
       ├── chunks/       # 【核心基建】CHUNK 事件合并 → CONTENT 事件
       ├── verify/       # 【核心基建】事件序列合法性验证
       ├── interrupts/   # 【核心基建】Human-in-the-Loop 中断处理
       ├── legacy/       # 【核心基建】旧版协议事件兼容转换
       └── compact/      # 【核心基建】事件压缩/优化
       ├── encoder/              # 【核心基建】@ag-ui/encoder - 事件编码器
   └── src/
       ├── encoder.ts    # 【核心基建】SSE/Protobuf 双模编码
       └── media-type.ts # 【核心基建】HTTP Accept 头协商
       ├── proto/                # 【核心基建】@ag-ui/proto - Protobuf 协议实现
   └── src/
       ├── proto.ts      # 【核心基建】Protobuf encode/decode
       └── proto/        # 【核心基建】.proto 定义文件
       ├── cli/                  # 【工具集】create-ag-ui-app - 项目脚手架 CLI
       └── a2ui-toolkit/         # 【工具集】@ag-ui/a2ui-toolkit - 跨平台 UI 工具
   ├── python/                       # 【核心基建】Python SDK 参考实现
   ├── ag_ui/                    # 【核心基建】Python 核心包
   ├── core/                 # 【核心基建】事件类型、Schema、核心类型(对等 TypeScript core)
   └── encoder/              # 【核心基建】SSE 编码器
   ├── a2ui_toolkit/             # 【工具集】Python A2UI Toolkit
   └── tests/                    # 【质量保证】Python 单元测试
   └── community/                    # 【业务模块】社区维护的多语言 SDK
       ├── go/                       # 【业务模块】Go SDK(pkg + example)
       ├── java/                     # 【业务模块】Java SDK(packages + clients + servers + integrations)
       ├── kotlin/                   # 【业务模块】Kotlin SDK(library + examples)
       ├── ruby/                     # 【业务模块】Ruby SDK(lib + test + example)
       ├── rust/                     # 【业务模块】Rust SDK(crates + client)
       ├── dart/                     # 【业务模块】Dart SDK(lib + test + example)
       └── c++/                      # 【业务模块】C++ SDK(src + tests)
├── integrations/                     # 【业务模块】18+ AI 框架事件适配器
   ├── langgraph/                    # 【业务模块】LangGraph (Python + TypeScript) - Partnership
   ├── crew-ai/                      # 【业务模块】CrewAI (Python + TypeScript) - Partnership
   ├── mastra/                       # 【业务模块】Mastra (TypeScript) - 1st Party
   ├── langchain/                    # 【业务模块】LangChain (TypeScript) - 1st Party
   ├── vercel-ai-sdk/                # 【业务模块】Vercel AI SDK (TypeScript) - 1st Party
   ├── adk-middleware/               # 【业务模块】Google ADK (Python + TypeScript) - 1st Party
   ├── agno/                         # 【业务模块】Agno (Python + TypeScript) - 1st Party
   ├── pydantic-ai/                  # 【业务模块】Pydantic AI (Python + TypeScript) - 1st Party
   ├── llama-index/                  # 【业务模块】LlamaIndex (Python + TypeScript) - 1st Party
   ├── aws-strands/                  # 【业务模块】AWS Strands (Python + TypeScript) - 1st Party
   ├── microsoft-agent-framework/    # 【业务模块】MS Agent Framework (.NET + Python) - 1st Party
   ├── ag2/                          # 【业务模块】AG2 (Python + TypeScript) - 1st Party
   ├── watsonx/                      # 【业务模块】IBM WatsonX (Python + TypeScript) - 1st Party
   ├── claude-agent-sdk/             # 【业务模块】Claude Agent SDK (Python + TypeScript) - Community
   ├── langroid/                     # 【业务模块】Langroid (Python + TypeScript) - Community
   ├── a2a/                          # 【业务模块】A2A 协议 (TypeScript) - Partnership
   ├── agent-spec/                   # 【业务模块】Oracle Agent Spec (Python) - Partnership
   ├── server-starter/               # 【业务模块】服务端快速启动模板 (Python + TypeScript)
   ├── server-starter-all-features/ # 【业务模块】全功能服务端模板 (Python + TypeScript)
   └── community/                    # 【业务模块】社区贡献集成
       ├── cloudflare-agents/        # 【业务模块】Cloudflare Agents
       ├── genkit/                   # 【业务模块】Google Genkit
       └── spring-ai/                # 【业务模块】Spring AI
├── middlewares/                      # 【核心基建】可插拔中间件层
   ├── a2a-middleware/               # 【核心基建】Agent-to-Agent 通信代理中间件
   ├── a2ui-middleware/              # 【核心基建】跨平台 UI 渲染指令中间件
   ├── mcp-middleware/               # 【核心基建】MCP 工具调用桥接中间件
   ├── mcp-apps-middleware/          # 【核心基建】MCP Apps 生成式 UI 中间件
   ├── event-throttle-middleware/    # 【核心基建】高频事件节流/限流中间件
   └── middleware-starter/           # 【核心基建】中间件开发快速启动模板
├── docs/                             # 【配置】中文/英文文档站点
   ├── concepts/                     # 【配置】核心概念(events, agents, state 等)
   ├── quickstart/                   # 【配置】快速入门指南
   ├── tutorials/                    # 【配置】分步教程
   ├── sdk/                          # 【配置】各语言 SDK 参考文档
   ├── development/                  # 【配置】开发指南
   ├── drafts/                       # 【配置】文档草稿
   ├── images/                       # 【配置】文档图片资源
   ├── icons/                        # 【配置】图标资源
   └── snippets/                     # 【配置】代码片段
├── scripts/                          # 【工具集】构建、发布与管理脚本
   └── release/                      # 【工具集】版本发布自动化脚本
├── package.json                      # 【配置】Monorepo 根配置(pnpm workspace + Nx)
├── pnpm-workspace.yaml               # 【配置】pnpm 工作空间包路径定义
├── nx.json                           # 【配置】Nx 构建编排(并行 30、独立版本、缓存策略)
├── pnpm-lock.yaml                    # 【配置】依赖锁定(pnpm 10.33.4)
├── .pnpmfile.cjs                     # 【配置】pnpm hooks(依赖覆盖/兼容处理)
├── lefthook.yml                      # 【配置】Git hooks 配置
├── render.yaml                       # 【配置】Render.com 部署配置
├── jitpack.yml                       # 【配置】JitPack Java 构建配置
├── README.md                         # 【配置】英文 README(定位、集成列表、SDK 矩阵)
├── CONTRIBUTING.md                   # 【配置】贡献指南(8 步集成 PR 流程)
├── CLAUDE.md                         # 【配置】AI 编程助手项目指引
├── AGENTS.md                         # 【配置】AI Agent 全局配置
├── LICENSE                           # 【配置】MIT 开源许可证
├── .mcp.json                         # 【配置】MCP 服务端声明
├── .npmrc                            # 【配置】npm 配置
└── .gitignore                        # 【配置】Git 忽略规则

3. 模块依赖与调用关系

3.1 全局入口与核心路由

逻辑说明:AG-UI 是一个协议库而非服务端应用,没有传统意义上的"请求路由"。其"入口"是从用户代码创建 Agent 实例并调用 runAgent() 方法开始的。核心调用链路为:用户创建 HttpAgent(或自定义 Agent 子类)→ 调用 runAgent() → 中间件管道 → run(input) → HTTP 请求 → 响应流解析 → 事件处理管道 → Subscriber 回调。

调用拓扑

text
用户代码 (User Application)
  |
  +--> new HttpAgent({ url: "...", headers: {...} })
  |      |
  |      +--> AbstractAgent.constructor()
  |      |      +-- 初始化 messages, state
  |      |      +-- 注入向后兼容中间件 (BackwardCompatibility_0_0_39/45/47)
  |      |      +-- resolveAgentDebugConfig()
  |      |
  |      +--> agent.use(middleware)  [可选:注册中间件]
  |      +--> agent.subscribe(subscriber)  [可选:注册事件监听器]
  |
  +--> agent.runAgent(parameters?)
         |
         +-- prepareRunAgentInput()
         |     +-- 合并 messages, state, tools, context, forwardedProps
         |     +-- 生成 runId
         |
         +-- onInitialize() -> 通知所有 subscribers.onRunInitialized()
         |
         +-- pipeline([
         |     |-- middlewareChain.run(input)
         |     |     |-- Middleware 1 -> Middleware 2 -> ... -> agent.run(input)
         |     |     |     |-- HttpAgent.run(input):
         |     |     |           +-- runHttpRequest(fetch)
         |     |     |           +-- transformHttpEventStream()
         |     |     |                 +-- parseSSEStream() 或 parseProtoStream()
         |     |     |                 +-- EventSchemas.parse() (Zod 验证)
         |     |
         |     |-- transformChunks()   [TEXT_MESSAGE_CHUNK -> CONTENT]
         |     |-- verifyEvents()      [事件序列验证]
         |     |-- takeUntil(detach$)  [中断信号处理]
         |     |-- apply(input, events, subscribers)
         |     |     +-- defaultApplyEvents()
         |     |     +-- 更新 messages[], state[]
         |     |     +-- 调用 subscribers.onXxxEvent()
         |     |-- processApplyEvents()
         |     |-- catchError() -> onError()
         |     |-- finalize() -> onFinalize()
         |   ])
         |
         +-- 返回 { result, newMessages }

3.2 包依赖关系图 (Package Dependency Graph)

逻辑说明:TypeScript SDK 的 6 个核心包形成清晰的层次依赖。Core 是零依赖基础层,Proto 和 Encoder 依赖 Core,Client 依赖所有下层包(Core、Encoder、Proto),CLI 和 A2UI Toolkit 是顶层消费者。

依赖拓扑

text
@ag-ui/core (v0.0.55)                  <-- 零外部运行时依赖(仅 zod)
  ^
  |
  +-- @ag-ui/proto (v0.0.55)           <-- 依赖 core + @bufbuild/protobuf
  |     ^
  |     |
  +-- @ag-ui/encoder (v0.0.55)         <-- 依赖 core + proto
  |     ^
  |     |
  +-- @ag-ui/client (v0.0.55)          <-- 依赖 core + encoder + proto + rxjs + uuid + fast-json-patch
        ^
        |
        +-- @ag-ui/cli (create-ag-ui-app)  <-- 依赖 client + 脚手架模板
        +-- @ag-ui/a2ui-toolkit             <-- 依赖 client + A2UI 规范
        |
        +-- integrations/*/typescript/       <-- 各集成 TypeScript 客户端
        +-- middlewares/*                    <-- A2A/A2UI/MCP/Throttle 中间件
        +-- apps/dojo                        <-- 演示应用

3.3 核心业务实体与关联

实体定义

  • RunAgentInput:一次 Agent 执行的输入,包含 threadId、runId、messages(对话历史)、state(当前状态)、tools(可用工具列表)、context(上下文数组)、forwardedProps(透传属性)
  • Message:对话消息,分为 UserMessage、AssistantMessage、SystemMessage、DeveloperMessage、ToolMessage,AssistantMessage 可包含 ToolCall 数组
  • BaseEvent:所有事件的基类,约 30 种具体事件类型,每种有独立 Schema
  • State:Agent 状态的通用容器(Record<string, any>),通过 STATE_SNAPSHOT(全量)和 STATE_DELTA(JSON Patch 增量)管理
  • Interrupt:Human-in-the-Loop 中断,Agent 暂停等待用户输入
  • AgentCapabilities:Agent 能力声明,包含 Identity、Transport、Tools、Output、State、Reasoning、Multimodal 等子能力

实体引用拓扑

text
[RunAgentInput] 1 ---> N [Message]           (对话历史)
                         |
                         +-- [UserMessage]
                         +-- [AssistantMessage]  1 ---> N [ToolCall]
                         |                                +-- id, name, arguments
                         +-- [SystemMessage]
                         +-- [ToolMessage]
[RunAgentInput] 1 ---> 1 [State]              (当前状态: {})
[RunAgentInput] 1 ---> N [Tool]               (可用工具: [{name, schema}])

[AbstractAgent] 1 ---> N [Message]            (累积的对话消息)
[AbstractAgent] 1 ---> 1 [State]              (累积的状态)
[AbstractAgent] 1 ---> N [AgentSubscriber]     (事件监听器)
[AbstractAgent] 1 ---> N [Middleware]          (中间件管道)

[RunAgentInput] --run()--> Observable<BaseEvent>
                              |
                              +-- [RunStartedEvent]
                              +-- [TextMessageStartEvent]
                              +-- [TextMessageContentEvent] * N
                              +-- [TextMessageEndEvent]
                              +-- [ToolCallStartEvent] -> [ToolCallArgsEvent] * N -> [ToolCallEndEvent]
                              +-- [ToolCallResultEvent]
                              +-- [StateSnapshotEvent] / [StateDeltaEvent]
                              +-- [ReasoningStartEvent] -> ... -> [ReasoningEndEvent]
                              +-- [RunFinishedEvent] / [RunErrorEvent]

4. 核心模块详解

模块一:AbstractAgent(Agent 运行时引擎)

  • 模块名称:AbstractAgent (@ag-ui/client)

  • 设计说明:AbstractAgent 是整个客户端运行时的核心抽象。它使用模板方法模式(Template Method Pattern)定义了 Agent 执行的完整生命周期,子类只需实现 run(input): Observable<BaseEvent> 方法即可接入。内部使用 RxJS Observable 管道实现事件流的声明式处理,使用观察者模式(Observer Pattern)实现 Subscriber 系统,使用责任链模式(Chain of Responsibility)实现中间件管道。

  • 内部结构图 (plainText)

text
+===========================================================================+
|                        AbstractAgent 内部结构                              |
+===========================================================================+
|                                                                           |
|  +-------------------------------+                                        |
|  |       Agent 状态管理           |                                        |
|  |  - messages: Message[]        |  <-- apply() 自动更新                  |
|  |  - state: State               |  <-- apply() 自动更新                  |
|  |  - threadId: string           |                                        |
|  |  - isRunning: boolean         |                                        |
|  |  - pendingInterrupts: Interrupt[] |                                    |
|  +-------------------------------+                                        |
|                                                                           |
|  +-------------------------------+                                        |
|  |     中间件管道 (责任链)       |                                        |
|  |  middlewares: Middleware[]    |  <-- use() 注册                        |
|  |                               |                                        |
|  |  reduceRight 构建链:          |                                        |
|  |  MW1 ──> MW2 ──> ... ──>     |                                        |
|  |  agent.run(input)  [末端]     |                                        |
|  +-------------------------------+                                        |
|                                                                           |
|  +-------------------------------+                                        |
|  |     Subscriber 系统 (观察者)   |                                        |
|  |  subscribers: AgentSubscriber[]|  <-- subscribe() 注册                 |
|  |                               |                                        |
|  |  生命周期:                     |                                        |
|  |  onRunInitialized ─> onEvent ─> onRunFinalized                        |
|  |                               |                                        |
|  |  事件级:                       |                                        |
|  |  onTextMessageStartEvent()    |                                        |
|  |  onTextMessageContentEvent()  |                                        |
|  |  onToolCallStartEvent()       |                                        |
|  |  ... (每个事件类型都有回调)     |                                        |
|  +-------------------------------+                                        |
|                                                                           |
|  +-------------------------------+                                        |
|  |     runAgent() 管道 (RxJS)     |                                        |
|  |                               |                                        |
|  |  of(input)                    |                                        |
|  |    |-> middlewareChain.run()   |  ← 中间件链入口                       |
|  |    |-> transformChunks()      |  ← CHUNK → CONTENT 合并              |
|  |    |-> verifyEvents()         |  ← 事件序列合法性校验                 |
|  |    |-> takeUntil(detach$)     |  ← 中断: 停止处理流                   |
|  |    |-> apply()                |  ← 应用事件到 messages/state          |
|  |    |-> processApplyEvents()   |  ← 触发 Subscriber 回调               |
|  |    |-> catchError()           |  ← 错误 → onError → Subscriber       |
|  |    |-> finalize()             |  ← 清理 → onFinalize → Subscriber    |
|  |                               |                                        |
|  +-------------------------------+                                        |
|                                                                           |
+===========================================================================+

模块二:HttpAgent(HTTP 传输客户端)

  • 模块名称:HttpAgent (@ag-ui/client)

  • 设计说明:HttpAgent 继承 AbstractAgent,实现了基于 HTTP POST + SSE/Protobuf 的事件流传输。其核心设计是内容协商机制:通过 HTTP Accept 头声明支持的格式,根据响应的 Content-Type 自动选择 SSE JSON 解析器或 Protobuf 二进制解析器。使用 fetch API 的 ReadableStream 实现真正的流式读取。

  • 内部结构图 (plainText)

text
+===========================================================================+
|                        HttpAgent 请求处理流程                              |
+===========================================================================+
|                                                                           |
|  HttpAgent.run(input: RunAgentInput)                                      |
|    |                                                                      |
|    +--> requestInit(input): RequestInit                                   |
|    |      { method: "POST",                                               |
|    |        headers: { "Content-Type": "application/json",                |
|    |                   "Accept": "text/event-stream",                     |
|    |                   ...customHeaders },                                |
|    |        body: JSON.stringify(input) }                                 |
|    |                                                                      |
|    +--> fetch(url, requestInit)                                           |
|    |      |                                                               |
|    |      +--> runHttpRequest(fetchResponse)                              |
|    |             |                                                        |
|    |             +--> defer(() => fetch())  [延迟执行]                    |
|    |             +--> switchMap(response)                                 |
|    |                   |                                                  |
|    |                   +-- response.ok?                                   |
|    |                   |   YES: ReadableStream.getReader()                |
|    |                   |   NO:  read error body -> throwError()           |
|    |                   |                                                  |
|    |                   +-- Observable<HttpEvent>                          |
|    |                        |-- HEADERS event (status, headers)           |
|    |                        |-- DATA event (Uint8Array chunk) *N          |
|    |                                                                      |
|    +--> transformHttpEventStream(httpEvents$)                             |
|           |                                                               |
|           +--> HEADERS arrived:                                           |
|           |      Content-Type = "application/x-ag-ui-proto+proto"?       |
|           |        YES -> parseProtoStream(bufferSubject$)               |
|           |        NO  -> parseSSEStream(bufferSubject$)                 |
|           |                                                               |
|           +--> SSE Path:                                                  |
|           |      "data: {...}\n\n" -> JSON.parse -> EventSchemas.parse   |
|           |                                                               |
|           +--> Protobuf Path:                                             |
|           |      [4B length][protobuf bytes] -> proto.decode()           |
|           |                                                               |
|           +--> emit BaseEvent to eventSubject$                            |
|                                                                           |
+===========================================================================+

模块三:事件编解码系统 (Event Encoder / Proto)

  • 模块名称:@ag-ui/encoder + @ag-ui/proto

  • 设计说明:Encoder 封装了 SSE 和 Protobuf 两种编码方式,通过 HTTP Accept 头自动协商。Proto 层使用 Protocol Buffers 定义所有事件的消息格式,提供类型安全的二进制序列化。这种双模设计让同一套代码可以兼顾调试便利性(SSE JSON)和生产性能(Protobuf)。

  • 内部结构图 (plainText)

text
+===========================================================================+
|                    事件编解码系统 (Dual-Mode Codec)                        |
+===========================================================================+
|                                                                           |
|  +-----------------------------+   +-------------------------------+      |
|  | EventEncoder (encoder)      |   | Proto Codec (proto)           |      |
|  |                             |   |                               |      |
|  | encode(event: BaseEvent)    |   | encode(event) -> Uint8Array   |      |
|  |   |                         |   |   |                           |      |
|  |   +-> acceptsProtobuf?      |   |   +-> proto.message           |      |
|  |       YES: encodeProtobuf() |   |       .encode(value)          |      |
|  |       NO:  encodeSSE()      |   |       .toBinary()             |      |
|  |                             |   |                               |      |
|  | encodeSSE(event): string    |   | decode(bytes) -> BaseEvent    |      |
|  |   return `data: ${JSON}     |   |   |                           |      |
|  |            .stringify(e)}\n\n`|  |   +-> proto.message           |      |
|  |                             |   |       .decode(bytes)          |      |
|  | encodeProtobuf(event):      |   |       .toJson()               |      |
|  |   Uint8Array                |   |                               |      |
|  |   [4B big-endian length]    |   | AGUI_MEDIA_TYPE:              |      |
|  |   [protobuf message bytes]  |   |   "application/              |      |
|  |                             |   |    x-ag-ui-proto+proto"       |      |
|  | getContentType():           |   |                               |      |
|  |   acceptsProtobuf?          |   | Proto Schema (.proto -> TS):  |      |
|  |     AGUI_MEDIA_TYPE         |   |   message BaseEvent {...}     |      |
|  |     : "text/event-stream"   |   |   message RunAgentInput {...} |      |
|  +-----------------------------+   +-------------------------------+      |
|                                                                           |
|  解析器 (Parsers, in client):                                             |
|  +-----------------------------+   +-------------------------------+      |
|  | parseSSEStream()            |   | parseProtoStream()            |      |
|  | ReadableStream<Uint8Array> |   | ReadableStream<Uint8Array>    |      |
|  |   -> split by "\n\n"        |   |   -> accumulate buffer        |      |
|  |   -> extract "data: {...}"  |   |   -> read [4B length]         |      |
|  |   -> JSON.parse()           |   |   -> read [message bytes]     |      |
|  |   -> Observable<string>     |   |   -> proto.decode()           |      |
|  +-----------------------------+   |   -> Observable<BaseEvent>    |      |
|                                     +-------------------------------+      |
+===========================================================================+

模块四:Middleware 中间件系统

  • 模块名称:Middleware (@ag-ui/client)

  • 设计说明:Middleware 是 AG-UI 的可插拔横切关注点实现机制。每个中间件拦截 Agent 的 run() 调用,可以在事件流上追加、过滤、转换事件,或修改 Agent 的 messages/state。使用 reduceRight 构建责任链,中间件按注册顺序执行(后注册的先执行)。核心中间件如 A2A 中间件通过此机制实现了完整的 Agent-to-Agent 代理模式。

  • 内部结构图

text
+===========================================================================+
|                      Middleware 中间件机制                                  |
+===========================================================================+
|                                                                           |
|  注册: agent.use(mw1).use(mw2)                                           |
|                                                                           |
|  构建 (reduceRight):                                                      |
|    agent.run(input)  <-- 原始 Agent                                      |
|    |                                                                      |
|    +-- MW2.run(input, agent)                                              |
|          |                                                                |
|          +-- 前置处理 (修改 input, 注入事件)                              |
|          +-- next.run(input)  -->  MW1.run(input, agent)                  |
|          |                          |                                     |
|          |                          +-- runNextWithState():               |
|          |                          |     - 调用 next.run(input)          |
|          |                          |     - 追踪 messages/state 变更      |
|          |                          |     - 返回 {event, messages, state} |
|          |                          |     - 使用 concatMap 逐个处理       |
|          |                                                                |
|          +-- 后置处理 (过滤/转换/追加事件)                                |
|          +-- return Observable<BaseEvent>                                 |
|                                                                           |
|  内部中间件 (自动注入, 按版本):                                            |
|    BackwardCompatibility_0_0_39  <-- 旧版 THINKING 事件兼容               |
|    BackwardCompatibility_0_0_45  <-- 旧版消息格式兼容                     |
|    BackwardCompatibility_0_0_47  <-- 旧版 BinaryInput 兼容                |
|                                                                           |
|  外部中间件 (用户注册):                                                    |
|    +-- A2aMiddleware         <-- Agent-to-Agent 代理通信                  |
|    +-- A2uiMiddleware        <-- 跨平台 UI 渲染指令注入                   |
|    +-- McpMiddleware         <-- MCP 工具调用代理                         |
|    +-- McpAppsMiddleware     <-- 生成式 UI (MCP Apps)                     |
|    +-- EventThrottleMiddleware <-- 高频事件节流                           |
|    +-- FunctionMiddleware    <-- 自定义函数中间件                         |
|                                                                           |
+===========================================================================+

模块五:集成适配器模式 (Integration Pattern)

  • 模块名称:Framework Integrations (integrations/*)

  • 设计说明:每个框架集成遵循统一的适配器模式。Python 端实现 AG-UI 协议的事件发射(通常作为 FastAPI/Flask endpoint),TypeScript 端提供 HttpAgent 封装。核心工作是将框架特定的事件(如 LangGraph 的 on_chat_model_stream)翻译为 AG-UI 标准事件(TEXT_MESSAGE_CONTENT),同时处理工具调用、状态管理等。

  • 内部结构图 (plainText)

text
+===========================================================================+
|                   Integration 适配器模式 (以 LangGraph 为例)               |
+===========================================================================+
|                                                                           |
|  +-----------------------------+   +-------------------------------+      |
|  |  Python Server (FastAPI)    |   |  TypeScript Client             |      |
|  |                             |   |                               |      |
|  |  POST /api/agent            |   |  import { HttpAgent }          |      |
|  |    |                        |   |       from "@ag-ui/client"     |      |
|  |    +-> RunAgentInput 解析   |   |                               |      |
|  |    |   (from JSON body)     |   |  new HttpAgent({               |      |
|  |    |                        |   |    url: "/api/agent"           |      |
|  |    +-> LangGraph Agent      |   |  })                           |      |
|  |    |   .astream_events()    |   |                               |      |
|  |    |                        |   |  agent.runAgent()              |      |
|  |    +-> Event 翻译:          |   |    .subscribe(callbacks)       |      |
|  |    |                        |   |                               |      |
|  |    |   LangGraph Event      |   |   AG-UI Event                  |      |
|  |    |   ─────────────────    |   |   ──────────                   |      |
|  |    |   on_chat_model_start  | ->|   TEXT_MESSAGE_START           |      |
|  |    |   on_chat_model_stream | ->|   TEXT_MESSAGE_CONTENT         |      |
|  |    |   on_chat_model_end    | ->|   TEXT_MESSAGE_END             |      |
|  |    |   on_tool_start        | ->|   TOOL_CALL_START              |      |
|  |    |   on_tool_end          | ->|   TOOL_CALL_END                |      |
|  |    |   custom state write   | ->|   STATE_SNAPSHOT / STATE_DELTA |      |
|  |    |                        |   |                               |      |
|  |    +-> SSE StreamingResponse|   |                               |      |
|  |         data: {event}\n\n   |   |                               |      |
|  +-----------------------------+   +-------------------------------+      |
|                                                                           |
|  目录结构模板:                                                             |
|    integrations/<framework>/                                              |
|    ├── python/               ← Python 服务端适配器                        |
|    │   ├── examples/         ← Dojo 演示示例                              |
|    │   └── pyproject.toml    ← 包定义                                    |
|    └── typescript/           ← TypeScript 客户端封装                      |
|        ├── src/index.ts      ← HttpAgent 导出                             |
|        └── package.json      ← 包定义                                    |
|                                                                           |
+===========================================================================+

5. 关键数据流程

场景一:标准 Agentic Chat 完整生命周期

场景说明:用户通过 Chat UI 发送一条消息,Agent 执行过程中产生流式文本输出、工具调用、状态更新,最终返回结果。这是 AG-UI 最核心的数据流转场景。

流转时序图 (Mermaid)

场景二:Human-in-the-Loop 中断与恢复

场景说明:Agent 在执行过程中遇到需要用户确认的操作,通过 Interrupt 机制暂停执行。用户在 UI 中提供响应后,Agent 在下一轮 run 中恢复执行。

流转时序图 (Mermaid)


6. 接口与契约规范 (Interface & Contract Specs)

6.1 AG-UI 协议规范

typescript
/**
 * AG-UI Protocol TypeScript Type Definitions
 * 官方 AG-UI 协议 TypeScript 类型声明
 * 基于: /Users/sqliang/ai-workspace/open-source-projects/agent-and-genui/ag-ui/sdks/typescript/packages/core/src/events.ts
 * 
 * 版本: 完整协议类型定义,包含所有事件类型和字段
 */

// ============================================================
// 公共类型 (Common Types)
// ============================================================

/** JSON Patch 操作 (RFC 6902) */
interface JSONPatchOperation {
  op: "add" | "remove" | "replace" | "move" | "copy" | "test";
  path: string; // JSON Pointer 路径,如 "/count"
  value?: unknown; // add, replace, test 操作所需
  from?: string; // move, copy 操作的源路径
}

/** 工具调用中的函数调用 */
interface FunctionCall {
  name: string;
  arguments: string; // JSON 字符串
}

/** 工具调用 */
interface ToolCall {
  id: string;
  type: "function";
  function: FunctionCall;
  encryptedValue?: string;
}

/** 消息角色枚举 */
type MessageRole = 
  | "developer" 
  | "system" 
  | "assistant" 
  | "user" 
  | "tool" 
  | "activity" 
  | "reasoning";

/** 文本输入内容 */
interface TextInputContent {
  type: "text";
  text: string;
}

/** 图片输入内容 */
interface ImageInputContent {
  type: "image";
  source: {
    type: "data" | "url";
    value: string;
    mimeType?: string;
  };
  metadata?: unknown;
}

/** 音频输入内容 */
interface AudioInputContent {
  type: "audio";
  source: {
    type: "data" | "url";
    value: string;
    mimeType?: string;
  };
  metadata?: unknown;
}

/** 视频输入内容 */
interface VideoInputContent {
  type: "video";
  source: {
    type: "data" | "url";
    value: string;
    mimeType?: string;
  };
  metadata?: unknown;
}

/** 文档输入内容 */
interface DocumentInputContent {
  type: "document";
  source: {
    type: "data" | "url";
    value: string;
    mimeType?: string;
  };
  metadata?: unknown;
}

/** 输入内容联合类型 */
type InputContent = TextInputContent | ImageInputContent | AudioInputContent | VideoInputContent | DocumentInputContent;

/** 开发者消息 */
interface DeveloperMessage {
  id: string;
  role: "developer";
  content: string;
  name?: string;
  encryptedValue?: string;
}

/** 系统消息 */
interface SystemMessage {
  id: string;
  role: "system";
  content: string;
  name?: string;
  encryptedValue?: string;
}

/** Assistant 消息 */
interface AssistantMessage {
  id: string;
  role: "assistant";
  content?: string;
  name?: string;
  encryptedValue?: string;
  toolCalls?: ToolCall[];
}

/** 用户消息 */
interface UserMessage {
  id: string;
  role: "user";
  content: string | InputContent[];
  name?: string;
  encryptedValue?: string;
}

/** 工具消息 */
interface ToolMessage {
  id: string;
  role: "tool";
  content: string;
  toolCallId: string;
  error?: string;
  encryptedValue?: string;
}

/** 活动消息 */
interface ActivityMessage {
  id: string;
  role: "activity";
  activityType: string;
  content: Record<string, unknown>;
}

/** 推理消息 */
interface ReasoningMessage {
  id: string;
  role: "reasoning";
  content: string;
  encryptedValue?: string;
}

/** 消息联合类型 */
type Message = DeveloperMessage | SystemMessage | AssistantMessage | UserMessage | ToolMessage | ActivityMessage | ReasoningMessage;

/** 工具定义 */
interface Tool {
  name: string;
  description: string;
  parameters: Record<string, unknown>; // JSON Schema
  metadata?: Record<string, unknown>;
}

/** 上下文项 */
interface Context {
  description: string;
  value: string;
}

/** 中断/打断 */
interface Interrupt {
  id: string;
  reason: string;
  message?: string;
  toolCallId?: string;
  responseSchema?: Record<string, unknown>;
  expiresAt?: string;
  metadata?: Record<string, unknown>;
}

/** 恢复条目 */
interface ResumeEntry {
  interruptId: string;
  status: "resolved" | "cancelled";
  payload?: unknown;
}

/** Agent 输入 */
interface RunAgentInput {
  threadId: string;
  runId: string;
  parentRunId?: string;
  state: unknown;
  messages: Message[];
  tools: Tool[];
  context: Context[];
  forwardedProps: unknown;
  resume?: ResumeEntry[];
}

// ============================================================
// 事件类型枚举 (Event Type Enum)
// ============================================================

/** AG-UI 事件类型 */
enum EventType {
  // 文本消息事件
  TEXT_MESSAGE_START = "TEXT_MESSAGE_START",
  TEXT_MESSAGE_CONTENT = "TEXT_MESSAGE_CONTENT",
  TEXT_MESSAGE_END = "TEXT_MESSAGE_END",
  TEXT_MESSAGE_CHUNK = "TEXT_MESSAGE_CHUNK",
  
  // 工具调用事件
  TOOL_CALL_START = "TOOL_CALL_START",
  TOOL_CALL_ARGS = "TOOL_CALL_ARGS",
  TOOL_CALL_END = "TOOL_CALL_END",
  TOOL_CALL_CHUNK = "TOOL_CALL_CHUNK",
  TOOL_CALL_RESULT = "TOOL_CALL_RESULT",
  
  // 状态管理事件
  STATE_SNAPSHOT = "STATE_SNAPSHOT",
  STATE_DELTA = "STATE_DELTA",
  MESSAGES_SNAPSHOT = "MESSAGES_SNAPSHOT",
  ACTIVITY_SNAPSHOT = "ACTIVITY_SNAPSHOT",
  ACTIVITY_DELTA = "ACTIVITY_DELTA",
  
  // 生命周期事件
  RUN_STARTED = "RUN_STARTED",
  RUN_FINISHED = "RUN_FINISHED",
  RUN_ERROR = "RUN_ERROR",
  STEP_STARTED = "STEP_STARTED",
  STEP_FINISHED = "STEP_FINISHED",
  
  // 推理事件 (THINKING 已废弃,使用 REASONING)
  THINKING_START = "THINKING_START",
  THINKING_END = "THINKING_END",
  THINKING_TEXT_MESSAGE_START = "THINKING_TEXT_MESSAGE_START",
  THINKING_TEXT_MESSAGE_CONTENT = "THINKING_TEXT_MESSAGE_CONTENT",
  THINKING_TEXT_MESSAGE_END = "THINKING_TEXT_MESSAGE_END",
  
  // 推理事件 (新版本)
  REASONING_START = "REASONING_START",
  REASONING_MESSAGE_START = "REASONING_MESSAGE_START",
  REASONING_MESSAGE_CONTENT = "REASONING_MESSAGE_CONTENT",
  REASONING_MESSAGE_END = "REASONING_MESSAGE_END",
  REASONING_MESSAGE_CHUNK = "REASONING_MESSAGE_CHUNK",
  REASONING_END = "REASONING_END",
  REASONING_ENCRYPTED_VALUE = "REASONING_ENCRYPTED_VALUE",
  
  // 特殊事件
  RAW = "RAW",
  CUSTOM = "CUSTOM",
}

// ============================================================
// 基础事件 (Base Event)
// ============================================================

/** 基础事件,所有事件都继承自此 */
interface BaseEvent {
  /** 事件类型,用于 discriminator */
  type: EventType;
  /** Unix 毫秒时间戳 */
  timestamp?: number;
  /** 原始事件数据,用于调试 */
  rawEvent?: unknown;
}

// ============================================================
// 文本消息事件 (Text Message Events)
// ============================================================

/** 文本消息开始事件 */
interface TextMessageStartEvent extends BaseEvent {
  type: EventType.TEXT_MESSAGE_START;
  /** 消息唯一 ID */
  messageId: string;
  /** 发送者角色,默认 "assistant" */
  role?: "developer" | "system" | "assistant" | "user";
  /** 可选名称 */
  name?: string;
}

/** 文本消息内容事件 (流式) */
interface TextMessageContentEvent extends BaseEvent {
  type: EventType.TEXT_MESSAGE_CONTENT;
  /** 关联的消息 ID */
  messageId: string;
  /** 文本内容片段 (非空) */
  delta: string;
}

/** 文本消息结束事件 */
interface TextMessageEndEvent extends BaseEvent {
  type: EventType.TEXT_MESSAGE_END;
  /** 关联的消息 ID */
  messageId: string;
}

/** 文本消息块事件 (便捷性事件) */
interface TextMessageChunkEvent extends BaseEvent {
  type: EventType.TEXT_MESSAGE_CHUNK;
  /** 消息 ID (首次必须提供) */
  messageId?: string;
  /** 发送者角色 */
  role?: "developer" | "system" | "assistant" | "user";
  /** 文本内容 */
  delta?: string;
  /** 名称 */
  name?: string;
}

// ============================================================
// 工具调用事件 (Tool Call Events)
// ============================================================

/** 工具调用开始事件 */
interface ToolCallStartEvent extends BaseEvent {
  type: EventType.TOOL_CALL_START;
  /** 工具调用唯一 ID */
  toolCallId: string;
  /** 被调用的工具名称 */
  toolCallName: string;
  /** 父消息 ID */
  parentMessageId?: string;
}

/** 工具参数事件 (流式) */
interface ToolCallArgsEvent extends BaseEvent {
  type: EventType.TOOL_CALL_ARGS;
  /** 关联的工具调用 ID */
  toolCallId: string;
  /** 参数 JSON 片段 */
  delta: string;
}

/** 工具调用结束事件 */
interface ToolCallEndEvent extends BaseEvent {
  type: EventType.TOOL_CALL_END;
  /** 关联的工具调用 ID */
  toolCallId: string;
}

/** 工具调用结果事件 */
interface ToolCallResultEvent extends BaseEvent {
  type: EventType.TOOL_CALL_RESULT;
  /** 结果消息 ID */
  messageId: string;
  /** 关联的工具调用 ID */
  toolCallId: string;
  /** 结果内容 */
  content: string;
  /** 角色,默认 "tool" */
  role?: "tool";
}

/** 工具调用块事件 (便捷性事件) */
interface ToolCallChunkEvent extends BaseEvent {
  type: EventType.TOOL_CALL_CHUNK;
  /** 工具调用 ID */
  toolCallId?: string;
  /** 工具名称 */
  toolCallName?: string;
  /** 父消息 ID */
  parentMessageId?: string;
  /** 内容片段 */
  delta?: string;
}

// ============================================================
// 状态管理事件 (State Management Events)
// ============================================================

/** 状态快照事件 */
interface StateSnapshotEvent extends BaseEvent {
  type: EventType.STATE_SNAPSHOT;
  /** 完整状态对象 */
  snapshot: unknown;
}

/** 状态增量事件 (JSON Patch) */
interface StateDeltaEvent extends BaseEvent {
  type: EventType.STATE_DELTA;
  /** JSON Patch 操作数组 */
  delta: JSONPatchOperation[];
}

/** 消息历史快照事件 */
interface MessagesSnapshotEvent extends BaseEvent {
  type: EventType.MESSAGES_SNAPSHOT;
  /** 完整消息数组 */
  messages: Message[];
}

/** 活动快照事件 */
interface ActivitySnapshotEvent extends BaseEvent {
  type: EventType.ACTIVITY_SNAPSHOT;
  /** 消息 ID */
  messageId: string;
  /** 活动类型 */
  activityType: string;
  /** 活动内容 */
  content: Record<string, unknown>;
  /** 是否替换,默认 true */
  replace?: boolean;
}

/** 活动增量事件 */
interface ActivityDeltaEvent extends BaseEvent {
  type: EventType.ACTIVITY_DELTA;
  /** 消息 ID */
  messageId: string;
  /** 活动类型 */
  activityType: string;
  /** JSON Patch 操作数组 */
  patch: JSONPatchOperation[];
}

// ============================================================
// 生命周期事件 (Lifecycle Events)
// ============================================================

/** 运行开始事件 */
interface RunStartedEvent extends BaseEvent {
  type: EventType.RUN_STARTED;
  /** 线程/会话 ID */
  threadId: string;
  /** 唯一运行 ID */
  runId: string;
  /** 父运行 ID */
  parentRunId?: string;
  /** Agent 输入 */
  input?: RunAgentInput;
}

/** 运行成功结局 */
interface RunFinishedSuccessOutcome {
  type: "success";
}

/** 运行中断结局 */
interface RunFinishedInterruptOutcome {
  type: "interrupt";
  /** 中断列表,至少一个 */
  interrupts: Interrupt[];
}

/** 运行结局联合类型 */
type RunFinishedOutcome = RunFinishedSuccessOutcome | RunFinishedInterruptOutcome;

/** 运行结束事件 */
interface RunFinishedEvent extends BaseEvent {
  type: EventType.RUN_FINISHED;
  /** 线程/会话 ID */
  threadId: string;
  /** 唯一运行 ID */
  runId: string;
  /** 运行返回结果 */
  result?: unknown;
  /** 结果结局 */
  outcome?: RunFinishedOutcome;
}

/** 运行错误事件 */
interface RunErrorEvent extends BaseEvent {
  type: EventType.RUN_ERROR;
  /** 错误信息 */
  message: string;
  /** 错误代码 */
  code?: string;
}

/** 步骤开始事件 */
interface StepStartedEvent extends BaseEvent {
  type: EventType.STEP_STARTED;
  /** 步骤名称 */
  stepName: string;
}

/** 步骤结束事件 */
interface StepFinishedEvent extends BaseEvent {
  type: EventType.STEP_FINISHED;
  /** 步骤名称 */
  stepName: string;
}

// ============================================================
// 推理事件 (Reasoning Events)
// ============================================================

/** 推理加密值子类型 */
type ReasoningEncryptedValueSubtype = "tool-call" | "message";

/** 推理开始事件 */
interface ReasoningStartEvent extends BaseEvent {
  type: EventType.REASONING_START;
  /** 推理消息 ID */
  messageId: string;
}

/** 推理消息开始事件 */
interface ReasoningMessageStartEvent extends BaseEvent {
  type: EventType.REASONING_MESSAGE_START;
  /** 推理消息 ID */
  messageId: string;
  /** 角色,固定为 "reasoning" */
  role: "reasoning";
}

/** 推理消息内容事件 (流式) */
interface ReasoningMessageContentEvent extends BaseEvent {
  type: EventType.REASONING_MESSAGE_CONTENT;
  /** 关联的推理消息 ID */
  messageId: string;
  /** 推理内容片段 */
  delta: string;
}

/** 推理消息结束事件 */
interface ReasoningMessageEndEvent extends BaseEvent {
  type: EventType.REASONING_MESSAGE_END;
  /** 关联的推理消息 ID */
  messageId: string;
}

/** 推理消息块事件 (便捷性事件) */
interface ReasoningMessageChunkEvent extends BaseEvent {
  type: EventType.REASONING_MESSAGE_CHUNK;
  /** 推理消息 ID */
  messageId?: string;
  /** 内容片段 */
  delta?: string;
}

/** 推理结束事件 */
interface ReasoningEndEvent extends BaseEvent {
  type: EventType.REASONING_END;
  /** 推理消息 ID */
  messageId: string;
}

/** 推理加密值事件 */
interface ReasoningEncryptedValueEvent extends BaseEvent {
  type: EventType.REASONING_ENCRYPTED_VALUE;
  /** 子类型 */
  subtype: ReasoningEncryptedValueSubtype;
  /** 关联实体 ID */
  entityId: string;
  /** 加密值 */
  encryptedValue: string;
}

// ============================================================
// 已废弃的推理事件 (Deprecated Thinking Events)
// ============================================================

/** @deprecated 使用 ReasoningStartEvent 替代 */
interface ThinkingStartEvent extends BaseEvent {
  type: EventType.THINKING_START;
  /** 标题 */
  title?: string;
}

/** @deprecated 使用 ReasoningEndEvent 替代 */
interface ThinkingEndEvent extends BaseEvent {
  type: EventType.THINKING_END;
}

/** @deprecated 使用 ReasoningMessageStartEvent 替代 */
interface ThinkingTextMessageStartEvent extends BaseEvent {
  type: EventType.THINKING_TEXT_MESSAGE_START;
}

/** @deprecated 使用 ReasoningMessageContentEvent 替代 */
interface ThinkingTextMessageContentEvent extends BaseEvent {
  type: EventType.THINKING_TEXT_MESSAGE_CONTENT;
  /** 内容片段 */
  delta: string;
}

/** @deprecated 使用 ReasoningMessageEndEvent 替代 */
interface ThinkingTextMessageEndEvent extends BaseEvent {
  type: EventType.THINKING_TEXT_MESSAGE_END;
}

// ============================================================
// 特殊事件 (Special Events)
// ============================================================

/** 原始事件 (透传) */
interface RawEvent extends BaseEvent {
  type: EventType.RAW;
  /** 原始数据 */
  event: unknown;
  /** 来源 */
  source?: string;
}

/** 自定义事件 */
interface CustomEvent extends BaseEvent {
  type: EventType.CUSTOM;
  /** 事件名称 */
  name: string;
  /** 事件值 */
  value?: unknown;
}

// ============================================================
// 联合类型 (Union Type)
// ============================================================

/** AG-UI 所有事件联合类型 */
type AGUIEvent =
  | TextMessageStartEvent
  | TextMessageContentEvent
  | TextMessageEndEvent
  | TextMessageChunkEvent
  | ToolCallStartEvent
  | ToolCallArgsEvent
  | ToolCallEndEvent
  | ToolCallResultEvent
  | ToolCallChunkEvent
  | StateSnapshotEvent
  | StateDeltaEvent
  | MessagesSnapshotEvent
  | ActivitySnapshotEvent
  | ActivityDeltaEvent
  | RunStartedEvent
  | RunFinishedEvent
  | RunErrorEvent
  | StepStartedEvent
  | StepFinishedEvent
  | ReasoningStartEvent
  | ReasoningMessageStartEvent
  | ReasoningMessageContentEvent
  | ReasoningMessageEndEvent
  | ReasoningMessageChunkEvent
  | ReasoningEndEvent
  | ReasoningEncryptedValueEvent
  | ThinkingStartEvent
  | ThinkingEndEvent
  | ThinkingTextMessageStartEvent
  | ThinkingTextMessageContentEvent
  | ThinkingTextMessageEndEvent
  | RawEvent
  | CustomEvent;

// ============================================================
// SSE 帧类型 (SSE Frame Types)
// ============================================================

/** SSE 帧 */
interface SSEFrame {
  /** 事件类型 */
  event?: string;
  /** 事件 ID,格式: EventType_timestamp */
  id?: string;
  /** 事件数据 JSON 字符串 */
  data: string;
}

/** SSE 事件 */
interface SSEEvent {
  /** 事件类型 */
  eventType: string;
  /** 事件 ID */
  id: string;
  /** 解析后的事件数据 */
  data: AGUIEvent;
}

// ============================================================
// 导出 (Exports)
// ============================================================

export {
  EventType,
  type AGUIEvent,
  type BaseEvent,
  type TextMessageStartEvent,
  type TextMessageContentEvent,
  type TextMessageEndEvent,
  type TextMessageChunkEvent,
  type ToolCallStartEvent,
  type ToolCallArgsEvent,
  type ToolCallEndEvent,
  type ToolCallResultEvent,
  type ToolCallChunkEvent,
  type StateSnapshotEvent,
  type StateDeltaEvent,
  type MessagesSnapshotEvent,
  type ActivitySnapshotEvent,
  type ActivityDeltaEvent,
  type RunStartedEvent,
  type RunFinishedEvent,
  type RunFinishedOutcome,
  type RunFinishedSuccessOutcome,
  type RunFinishedInterruptOutcome,
  type RunErrorEvent,
  type StepStartedEvent,
  type StepFinishedEvent,
  type ReasoningStartEvent,
  type ReasoningMessageStartEvent,
  type ReasoningMessageContentEvent,
  type ReasoningMessageEndEvent,
  type ReasoningMessageChunkEvent,
  type ReasoningEndEvent,
  type ReasoningEncryptedValueEvent,
  type ReasoningEncryptedValueSubtype,
  type ThinkingStartEvent,
  type ThinkingEndEvent,
  type ThinkingTextMessageStartEvent,
  type ThinkingTextMessageContentEvent,
  type ThinkingTextMessageEndEvent,
  type RawEvent,
  type CustomEvent,
  type SSEFrame,
  type SSEEvent,
  type JSONPatchOperation,
  type Message,
  type MessageRole,
  type ToolCall,
  type FunctionCall,
  type Tool,
  type Context,
  type Interrupt,
  type ResumeEntry,
  type RunAgentInput,
  type InputContent,
  type TextInputContent,
  type ImageInputContent,
  type AudioInputContent,
  type VideoInputContent,
  type DocumentInputContent,
  type DeveloperMessage,
  type SystemMessage,
  type AssistantMessage,
  type UserMessage,
  type ToolMessage,
  type ActivityMessage,
  type ReasoningMessage,
};

6.2 核心内部模块契约 (TypeScript Interfaces)

typescript
/**
 * AG-UI 核心 Agent 抽象契约
 * 所有 Agent 实现必须实现此接口
 */
export abstract class AbstractAgent {
  /** Agent 唯一标识 */
  public agentId?: string;
  /** Agent 描述 */
  public description: string;
  /** 对话线程 ID,跨多次 run 持久化 */
  public threadId: string;
  /** 累积的对话消息 */
  public messages: Message[];
  /** 累积的状态对象 */
  public state: State;
  /** 事件订阅者列表 */
  public subscribers: AgentSubscriber[];
  /** Agent 是否正在执行 */
  public isRunning: boolean;
  /** 待处理的中断列表(Human-in-the-Loop) */
  public pendingInterrupts: Interrupt[];

  /**
   * 核心执行方法 - 子类必须实现
   * @param input - Agent 执行输入
   * @returns 标准 AG-UI 事件 Observable 流
   */
  abstract run(input: RunAgentInput): Observable<BaseEvent>;

  /**
   * 执行一次完整的 Agent run(含中间件、验证、apply、subscriber 通知)
   * @param parameters - 可选参数(runId, tools, context, resume)
   * @param subscriber - 可选的单次 subscriber
   * @returns 执行结果(包含 result 和新增的 messages)
   */
  public async runAgent(
    parameters?: RunAgentParameters,
    subscriber?: AgentSubscriber,
  ): Promise<RunAgentResult>;

  /** 注册中间件 */
  public use(...middlewares: (Middleware | MiddlewareFunction)[]): this;

  /** 订阅事件 */
  public subscribe(subscriber: AgentSubscriber): { unsubscribe(): void };

  /** 中断当前运行 */
  abortRun(): void;

  /** 声明 Agent 能力 */
  getCapabilities?(): Promise<AgentCapabilities>;
}

/**
 * Agent 执行输入契约
 */
export interface RunAgentInput {
  threadId: string;
  runId: string;
  messages: Message[];
  state: State;
  tools: Tool[];
  context: Context[];
  forwardedProps: Record<string, any>;
  resume?: ResumeEntry[];
}

/**
 * Agent 执行结果契约
 */
export interface RunAgentResult {
  result: any;
  newMessages: Message[];
}

6.3 AgentSubscriber 事件监听契约 (核心回调)

typescript
/**
 * Agent 事件订阅者契约
 * 每个回调都可以返回 AgentStateMutation 来修改 agent 的 messages 或 state
 */
export interface AgentSubscriber {
  /** 请求生命周期 */
  onRunInitialized?(params: AgentSubscriberParams): MaybePromise<AgentStateMutation | void>;
  onRunFailed?(params: { error: Error } & AgentSubscriberParams): MaybePromise<AgentStateMutation | void>;
  onRunFinalized?(params: AgentSubscriberParams): MaybePromise<AgentStateMutation | void>;

  /** 通用事件(所有事件类型都会触发) */
  onEvent?(params: { event: BaseEvent } & AgentSubscriberParams): MaybePromise<AgentStateMutation | void>;

  /** 生命周期事件 */
  onRunStartedEvent?(params: { event: RunStartedEvent } & AgentSubscriberParams): MaybePromise<AgentStateMutation | void>;
  onRunFinishedEvent?(params: RunFinishedParams): MaybePromise<AgentStateMutation | void>;
  onRunErrorEvent?(params: { event: RunErrorEvent } & AgentSubscriberParams): MaybePromise<AgentStateMutation | void>;

  /** 文本消息事件 */
  onTextMessageStartEvent?(params: { event: TextMessageStartEvent } & AgentSubscriberParams): MaybePromise<AgentStateMutation | void>;
  onTextMessageContentEvent?(params: { event: TextMessageContentEvent } & AgentSubscriberParams): MaybePromise<AgentStateMutation | void>;
  onTextMessageEndEvent?(params: { event: TextMessageEndEvent } & AgentSubscriberParams): MaybePromise<AgentStateMutation | void>;

  /** 工具调用事件 */
  onToolCallStartEvent?(params: { event: ToolCallStartEvent } & AgentSubscriberParams): MaybePromise<AgentStateMutation | void>;
  onToolCallArgsEvent?(params: { event: ToolCallArgsEvent } & AgentSubscriberParams): MaybePromise<AgentStateMutation | void>;
  onToolCallEndEvent?(params: { event: ToolCallEndEvent } & AgentSubscriberParams): MaybePromise<AgentStateMutation | void>;
  onToolCallResultEvent?(params: { event: ToolCallResultEvent } & AgentSubscriberParams): MaybePromise<AgentStateMutation | void>;

  /** 状态事件 */
  onStateSnapshotEvent?(params: { event: StateSnapshotEvent } & AgentSubscriberParams): MaybePromise<AgentStateMutation | void>;
  onStateDeltaEvent?(params: { event: StateDeltaEvent } & AgentSubscriberParams): MaybePromise<AgentStateMutation | void>;
  onMessagesSnapshotEvent?(params: { event: MessagesSnapshotEvent } & AgentSubscriberParams): MaybePromise<AgentStateMutation | void>;

  /** 步骤事件 */
  onStepStartedEvent?(params: { event: StepStartedEvent } & AgentSubscriberParams): MaybePromise<AgentStateMutation | void>;
  onStepFinishedEvent?(params: { event: StepFinishedEvent } & AgentSubscriberParams): MaybePromise<AgentStateMutation | void>;

  /** 推理事件 */
  onReasoningStartEvent?(params: { event: ReasoningStartEvent } & AgentSubscriberParams): MaybePromise<AgentStateMutation | void>;
  onReasoningMessageStartEvent?(params: { event: ReasoningMessageStartEvent } & AgentSubscriberParams): MaybePromise<AgentStateMutation | void>;
  onReasoningMessageContentEvent?(params: { event: ReasoningMessageContentEvent } & AgentSubscriberParams): MaybePromise<AgentStateMutation | void>;
  onReasoningMessageEndEvent?(params: { event: ReasoningMessageEndEvent } & AgentSubscriberParams): MaybePromise<AgentStateMutation | void>;
  onReasoningEndEvent?(params: { event: ReasoningEndEvent } & AgentSubscriberParams): MaybePromise<AgentStateMutation | void>;

  /** Activity 事件 */
  onActivitySnapshotEvent?(params: { event: ActivitySnapshotEvent } & AgentSubscriberParams): MaybePromise<AgentStateMutation | void>;
  onActivityDeltaEvent?(params: { event: ActivityDeltaEvent } & AgentSubscriberParams): MaybePromise<AgentStateMutation | void>;

  /** 其他事件 */
  onRawEvent?(params: { event: RawEvent } & AgentSubscriberParams): MaybePromise<AgentStateMutation | void>;
  onCustomEvent?(params: { event: CustomEvent } & AgentSubscriberParams): MaybePromise<AgentStateMutation | void>;
}

6.4 Middleware 中间件契约

typescript
/**
 * 中间件抽象基类
 * 拦截 Agent.run() 调用,可在事件流上做前置/后置处理
 */
export abstract class Middleware {
  /**
   * 核心中间件方法
   * @param input - 当前 RunAgentInput
   * @param next - 责任链中的下一个 Agent
   * @returns 事件 Observable
   */
  abstract run(input: RunAgentInput, next: AbstractAgent): Observable<BaseEvent>;

  /** 运行下一个 agent 并自动进行 chunk 转换 */
  protected runNext(input: RunAgentInput, next: AbstractAgent): Observable<BaseEvent>;

  /** 运行下一个 agent 并追踪 state/messages 变化 */
  protected runNextWithState(
    input: RunAgentInput,
    next: AbstractAgent,
  ): Observable<EventWithState>;
}

/** 函数式中间件类型 */
export type MiddlewareFunction = (
  input: RunAgentInput,
  next: AbstractAgent,
) => Observable<BaseEvent>;

6.5 Agent 能力声明契约

typescript
/**
 * Agent 能力声明契约
 * 用于客户端发现和适配 Agent 功能
 */
export interface AgentCapabilities {
  /** Agent 身份信息(名称、版本、提供商) */
  identity?: IdentityCapabilities;
  /** 支持的传输方式(SSE、WebSocket、HTTP Binary) */
  transport?: TransportCapabilities;
  /** 工具调用能力 */
  tools?: ToolsCapabilities;
  /** 输出格式支持 */
  output?: OutputCapabilities;
  /** 状态管理能力 */
  state?: StateCapabilities;
  /** 多 Agent 编排能力 */
  multiAgent?: MultiAgentCapabilities;
  /** 推理/思考能力 */
  reasoning?: ReasoningCapabilities;
  /** 多模态输入支持 */
  multimodalInput?: MultimodalInputCapabilities;
  /** 多模态输出支持 */
  multimodalOutput?: MultimodalOutputCapabilities;
  /** 执行能力 */
  execution?: ExecutionCapabilities;
  /** Human-in-the-Loop 支持 */
  humanInTheLoop?: HumanInTheLoopCapabilities;
}

7. 快速开始

7.1 环境配置

bash
# 要求 Node.js >= 18 + pnpm >= 10
pnpm install
pnpm build

7.2 安装与运行

bash
# 安装核心 SDK
npm install @ag-ui/core @ag-ui/client

# 创建新项目
npx create-ag-ui-app my-agent-app

# 运行 Dojo 演示平台
cd apps/dojo
pnpm dev

7.3 典型用例

typescript
import { HttpAgent } from "@ag-ui/client";

// 1. 创建 Agent
const agent = new HttpAgent({
  url: "http://localhost:8000/api/agent",
  headers: { "Authorization": "Bearer token" }
});

// 2. 订阅事件
agent.subscribe({
  onTextMessageContentEvent: ({ event }) => {
    console.log(event.delta); // 实时文本增量
  },
  onToolCallStartEvent: ({ event }) => {
    console.log("Agent 调用工具:", event.toolCallName);
  }
});

// 3. 执行
const { result, newMessages } = await agent.runAgent({
  tools: [/* 前端工具 */],
  context: [/* 上下文 */]
});