Skip to main content

AG-UI Headless UI Integration

@cloudbase/agent-react-core provides the core APIs needed to integrate AG-Kit conversational capabilities in React applications, enabling quick integration with AI Agents that conform to the AG-UI protocol.

Feature Overview

  • Chat state management
  • Message sending and aborting
  • Session thread switching
  • Client-side tool registration
  • Custom Tool Call rendering
  • Transport layer integration

Installation

npm install @cloudbase/agent-react-core

Quick Start

It is recommended to first initialize the runtime with AgKit, then read messages and send content in child components via 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("你好")}>Send</button>
<button onClick={abort} disabled={!streaming}>
Stop
</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 Reference

AgKit

AgKit is used to initialize the chat runtime and provide context to child components.

AgKitProps

OptionRequiredTypeDescription
transportYesTransportTransport layer instance responsible for sending messages to the backend and consuming the event stream
defaultThreadIdNostringDefault thread ID used during initial initialization, only effective at runtime initialization
instanceIdNostringInstance identifier for isolating state in multi-chat instance scenarios
childrenYesReact.ReactNodeChild components

Example

<AgKit transport={transport} defaultThreadId="thread-001">
<ChatView />
</AgKit>

useChat

useChat provides the core state and operation methods during the chat process.

Parameters UseChatOptions

OptionRequiredTypeDescription
instanceIdNostringInstance identifier for multi-instance scenarios, used to associate with a specific AgKit instance

Return Value UseChatReturn

OptionTypeDescription
messagesMessage[]Underlying raw message data
uiMessagesUIMessage[]Message list suitable for direct rendering (merges consecutive assistant messages, supports parts structure)
streamingbooleanWhether a streaming response is in progress
errorAGUIClientError \| nullCurrent error state
initializedbooleanWhether the runtime has completed initialization
actionsRecord<string, Action>Dictionary of currently registered tools (Actions)
sendMessage(input: string \| ToolMessage) => Promise<void>Send a text message or tool message
clearMessages() => voidClear all messages
addAction(action: Action) => voidRegister an Action
removeAction(actionName: string) => voidRemove an Action by name
switchThread(threadId: string, options?: SwitchThreadOptions) => voidSwitch session thread
abort() => voidAbort the current request

SwitchThreadOptions

OptionRequiredTypeDescription
clearMessagesNobooleanWhether to clear current messages when switching threads
abortActiveRunNobooleanWhether to abort the ongoing request when switching threads

Example

function ChatActions() {
const { uiMessages, sendMessage, streaming, abort, clearMessages } = useChat();

return (
<div>
<button onClick={() => sendMessage("介绍一下 AG-Kit")}>Send Message</button>
<button onClick={abort} disabled={!streaming}>
Stop Generating
</button>
<button onClick={clearMessages}>Clear Messages</button>

{uiMessages.map((message) => (
<div key={message.id}>{message.content}</div>
))}
</div>
);
}

useHeadlessChat

useHeadlessChat is a standalone version of useChat that can be used without the AgKit Provider, suitable for scenarios that require full control over the runtime lifecycle.

Parameters UseHeadlessChatOptions

OptionRequiredTypeDescription
transportYesTransportTransport layer instance
threadIdNostringInitial thread ID
instanceIdNostringInstance identifier for multi-instance scenarios

Return Value

Same as the useChat return value, see UseChatReturn.

Example

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 is used to register client-side tools. Once registered, the model can initiate corresponding tool calls, and the frontend can optionally execute them locally and return results.

Parameters UseClientToolOptions

OptionRequiredTypeDescription
nameYesstringTool name (unique key)
descriptionYesstringTool description sent to the model
parametersYesobjectJSON Schema parameter definition sent to the model
handlerNo(params: ToolHandlerParams) => string \| Promise<string>Local tool handler function
renderNo(context: ToolRenderContext) => string \| React.ReactElementCustom tool render function
instanceIdNostringInstance identifier for multi-instance support
enabledNobooleanWhether to enable tool registration, defaults to true

ToolHandlerParams

OptionTypeDescription
namestringTool name
descriptionstringTool description
toolCallIdstringUnique ID for this call
argsRecord<string, unknown>Parameters passed by the model

ToolRenderContext

OptionTypeDescription
toolCallToolCallStateComplete state of the tool call
respond(result: string) => voidReturn tool result to the model

Example

import { useClientTool } from "@cloudbase/agent-react-core";

function ToolRegistration() {
useClientTool({
name: "get_local_weather",
description: "Get local weather",
parameters: {
type: "object",
properties: {
city: { type: "string" },
},
},
handler: ({ args }) => {
return JSON.stringify({
city: String(args.city ?? "Shanghai"),
weather: "sunny",
});
},
});

return null;
}

Suitable for the following scenarios:

  • Reading browser local capabilities
  • Calling business methods in the frontend context
  • Returning tool results as structured data to the model

useToolCall

useToolCall is used to register a custom render function for a specified tool, making it easy to display interaction interfaces tailored to business scenarios in the message list.

Parameters UseToolCallOptions

OptionRequiredTypeDescription
nameYesstringTool name (unique key)
renderYes(context: ToolRenderContext) => string \| React.ReactElementCustom render function
instanceIdNostringInstance identifier for multi-instance support
enabledNobooleanWhether to enable render registration, defaults to true

Example

import { useToolCall } from "@cloudbase/agent-react-core";

function ToolRenderer() {
useToolCall({
name: "get_local_weather",
render: ({ toolCall }) => (
<div>
Weather tool parameters: {JSON.stringify(toolCall.args)}
</div>
),
});

return null;
}

Suitable for the following scenarios:

  • Displaying tool parameters and execution results
  • Adding confirmation interactions for tool calls
  • Rendering tool output as cards, tables, or custom views

Transport

Transport Interface

All transport layers need to implement the Transport interface:

MethodTypeDescription
run(input: RunAgentInput) => AsyncIterable<BaseEvent>Execute an agent run and return an async event iterator
abort() => voidAbort the current run

To connect to a custom backend, you can implement the Transport interface yourself.

CloudBaseTransport

Built-in transport layer for connecting to the CloudBase Agent SSE interface. Supports Bearer Token authentication, automatic retry on token expiration, and AbortController cancellation.

Constructor Parameters

OptionRequiredTypeDescription
appYescloudbase.app.AppCloudBase JS SDK application instance
agentIdYesstringAgent ID
fetchNotypeof globalThis.fetchCustom fetch function, defaults to globalThis.fetch
headersNoRecord<string, string>Custom request headers

Example

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",
});