AG-UI Headless UI 接入
@cloudbase/agent-react-core 提供在 React 应用中接入 AG-Kit 对话能力所需的核心 API,可用于快速对接符合 AG-UI 协议的 AI Agent。
功能概览
- 聊天状态管理
- 消息发送与中止
- 会话线程切换
- 客户端工具注册
- 自定义 Tool Call 渲染
- 传输层接入
安装
npm install @cloudbase/agent-react-core
快速开始
推荐先使用 AgKit 初始化运行时,再在子组件中通过 useChat 读取消息和发送内容。
import cloudbase from "@cloudbase/js-sdk";
import { AgKit, CloudBaseTransport, useChat } from "@cloudbase/agent-react-core";
const app = cloudbase.init({ env: "your-env-id" });
const transport = new CloudBaseTransport({
app,
agentId: "your-agent-id",
});
function ChatView() {
const { uiMessages, sendMessage, streaming, abort } = useChat();
return (
<div>
<button onClick={() => sendMessage("你好")}>发送</button>
<button onClick={abort} disabled={!streaming}>
停止
</button>
{uiMessages.map((message) => (
<div key={message.id}>
<strong>{message.role}:</strong> {message.content}
</div>
))}
</div>
);
}
export function App() {
return (
<AgKit transport={transport}>
<ChatView />
</AgKit>
);
}
API 参考
AgKit
AgKit 用于初始化聊天运行时,并向子组件提供上下文。
AgKitProps
| 选项 | 必填 | 类型 | 说明 |
|---|---|---|---|
transport | 是 | Transport | 传输层实例,负责把消息发送到后端并消费事件流 |
defaultThreadId | 否 | string | 首次初始化时使用的默认线程 ID,仅在运行时初始化时生效 |
instanceId | 否 | string | 多聊天实例场景下用于隔离状态的实例标识 |
children | 是 | React.ReactNode | 子组件 |
示例
<AgKit transport={transport} defaultThreadId="thread-001">
<ChatView />
</AgKit>
useChat
useChat 提供聊天过程中的核心状态和操作方法。
入参 UseChatOptions
| 选项 | 必填 | 类型 | 说明 |
|---|---|---|---|
instanceId | 否 | string | 多实例场景下的实例标识,用于关联特定的 AgKit 实例 |
返回值 UseChatReturn
| 选项 | 类型 | 说明 |
|---|---|---|
messages | Message[] | 底层原始消息数据 |
uiMessages | UIMessage[] | 适合直接渲染的消息列表(合并连续 assistant 消息,支持 parts 结构) |
streaming | boolean | 是否正在流式响应 |
error | AGUIClientError \| null | 当前错误状态 |
initialized | boolean | 运行时是否已完成初始化 |
actions | Record<string, Action> | 当前已注册的工具(Action)字典 |
sendMessage | (input: string \| ToolMessage) => Promise<void> | 发送文本消息或工具消息 |
clearMessages | () => void | 清空所有消息 |
addAction | (action: Action) => void | 注册一个 Action |
removeAction | (actionName: string) => void | 按名称移除一个 Action |
switchThread | (threadId: string, options?: SwitchThreadOptions) => void | 切换会话线程 |
abort | () => void | 中止当前请求 |
SwitchThreadOptions
| 选项 | 必填 | 类型 | 说明 |
|---|---|---|---|
clearMessages | 否 | boolean | 切换线程时是否清空当前消息 |
abortActiveRun | 否 | boolean | 切换线程时是否中止正在进行的请求 |
示例
function ChatActions() {
const { uiMessages, sendMessage, streaming, abort, clearMessages } = useChat();
return (
<div>
<button onClick={() => sendMessage("介绍一下 AG-Kit")}>发送消息</button>
<button onClick={abort} disabled={!streaming}>
停止生成
</button>
<button onClick={clearMessages}>清空消息</button>
{uiMessages.map((message) => (
<div key={message.id}>{message.content}</div>
))}
</div>
);
}
useHeadlessChat
useHeadlessChat 是 useChat 的独立版本,无需 AgKit Provider 即可使用,适合需要完全控制运行时生命周期的场景。
入参 UseHeadlessChatOptions
| 选项 | 必填 | 类型 | 说明 |
|---|---|---|---|
transport | 是 | Transport | 传输层实例 |
threadId | 否 | string | 初始线程 ID |
instanceId | 否 | string | 多实例场景下的实例标识 |
返回值
与 useChat 返回值一致,参见 UseChatReturn。
示例
function HeadlessChat() {
const transport = useMemo(() => new CloudBaseTransport({ app, agentId: "xxx" }), []);
const { uiMessages, sendMessage } = useHeadlessChat({ transport });
return (
<div>
{uiMessages.map((msg) => (
<div key={msg.id}>{msg.parts.map((p) => p.type === "text" && p.text)}</div>
))}
<button onClick={() => sendMessage("Hello")}>Send</button>
</div>
);
}
useClientTool
useClientTool 用于注册客户端工具。注册后,模型可以发起对应工具调用,前端可选择在本地执行并返回结果。
入参 UseClientToolOptions
| 选项 | 必填 | 类型 | 说明 |
|---|---|---|---|
name | 是 | string | 工具名称(唯一键) |
description | 是 | string | 发送给模型的工具描述 |
parameters | 是 | object | 发送给模型的 JSON Schema 参数定义 |
handler | 否 | (params: ToolHandlerParams) => string \| Promise<string> | 本地工具处理函数 |
render | 否 | (context: ToolRenderContext) => string \| React.ReactElement | 自定义工具渲染函数 |
instanceId | 否 | string | 多实例支持的实例标识 |
enabled | 否 | boolean | 是否启用工具注册,默认 true |
ToolHandlerParams
| 选项 | 类型 | 说明 |
|---|---|---|
name | string | 工具名称 |
description | string | 工具描述 |
toolCallId | string | 本次调用的唯一 ID |
args | Record<string, unknown> | 模型传入的参数 |
ToolRenderContext
| 选项 | 类型 | 说明 |
|---|---|---|
toolCall | ToolCallState | 工具调用的完整状态 |
respond | (result: string) => void | 向模型返回工具结果 |
示例
import { useClientTool } from "@cloudbase/agent-react-core";
function ToolRegistration() {
useClientTool({
name: "get_local_weather",
description: "获取本地天气",
parameters: {
type: "object",
properties: {
city: { type: "string" },
},
},
handler: ({ args }) => {
return JSON.stringify({
city: String(args.city ?? "Shanghai"),
weather: "sunny",
});
},
});
return null;
}
适合以下场景:
- 读取浏览器本地能力
- 调用前端上下文中的业务方法
- 将工具结果以结构化数据返回给模型
useToolCall
useToolCall 用于为指定工具注册自定义渲染函数,便于在消息列表中展示更适合业务场景的交互界面。
入参 UseToolCallOptions
| 选项 | 必填 | 类型 | 说明 |
|---|---|---|---|
name | 是 | string | 工具名称(唯一键) |
render | 是 | (context: ToolRenderContext) => string \| React.ReactElement | 自定义渲染函数 |
instanceId | 否 | string | 多实例支持的实例标识 |
enabled | 否 | boolean | 是否启用渲染注册,默认 true |
示例
import { useToolCall } from "@cloudbase/agent-react-core";
function ToolRenderer() {
useToolCall({
name: "get_local_weather",
render: ({ toolCall }) => (
<div>
天气工具参数:{JSON.stringify(toolCall.args)}
</div>
),
});
return null;
}
适合以下场景:
- 展示工具参数和执行结果
- 为工具调用增加确认交互
- 以卡片、表格或自定义视图渲染工具输出
Transport
Transport 接口
所有传输层都需要实现 Transport 接口:
| 方法 | 类型 | 说明 |
|---|---|---|
run | (input: RunAgentInput) => AsyncIterable<BaseEvent> | 执行 agent 运行,返回事件异步迭代器 |
abort | () => void | 中止当前运行 |
若需对接自定义后端,可自行实现 Transport 接口。
CloudBaseTransport
内置传输层,用于对接 CloudBase Agent 的 SSE 接口。支持 Bearer Token 鉴权、Token 过期自动重试和 AbortController 中止。
构造参数
| 选项 | 必填 | 类型 | 说明 |
|---|---|---|---|
app | 是 | cloudbase.app.App | CloudBase JS SDK 应用实例 |
agentId | 是 | string | Agent ID |
fetch | 否 | typeof globalThis.fetch | 自定义 fetch 函数,默认使用 globalThis.fetch |
headers | 否 | Record<string, string> | 自定义请求头 |
示例
import cloudbase from "@cloudbase/js-sdk";
import { CloudBaseTransport } from "@cloudbase/agent-react-core";
const app = cloudbase.init({ env: "your-env-id" });
const transport = new CloudBaseTransport({
app,
agentId: "your-agent-id",
});