React SDK
@kapaai/agent-react provides a complete chat UI with streaming, tool execution, and theming. It depends on @kapaai/agent-core as a peer dependency — install both packages.
Installation
- npm
- yarn
- pnpm
npm install @kapaai/agent-core @kapaai/agent-react
yarn add @kapaai/agent-core @kapaai/agent-react
pnpm add @kapaai/agent-core @kapaai/agent-react
Components
| Component | Description |
|---|---|
AgentProvider | Wraps your app with chat state and theming. Required. |
AgentChat | Full chat UI — header, messages, input, footer. Fills its parent container. |
AgentPanel | Slide-in drawer wrapping AgentChat. |
AgentFooter | Attribution footer with optional custom content via branding.footerExtra. |
Hooks
| Hook | Description |
|---|---|
useAgentChat() | Access chat state and actions (messages, sendMessage, approveToolCall, etc.). Required for headless mode. |
useAgentColorScheme() | Toggle or set the color scheme. See Theming. |
Utilities
| Export | Description |
|---|---|
createToolHelper<TContext>() | Type-safe tool definition factory with Zod inference for execute and render args. See Custom tools. |
Headless mode
You can use AgentProvider + useAgentChat() without any SDK UI components to build a fully custom chat interface:
import { AgentProvider, useAgentChat } from '@kapaai/agent-react';
const CustomChat = () => {
const {
messages,
isStreaming,
inputValue,
setInputValue,
sendMessage,
resetConversation,
stopGeneration,
approveToolCall,
rejectToolCall,
} = useAgentChat();
return (
<div>
{messages.map((msg, i) => (
<div key={i}>
<strong>{msg.role}:</strong> {msg.content}
</div>
))}
<input
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
onKeyDown={(e) => {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
sendMessage(inputValue);
}
}}
/>
</div>
);
};
function App() {
return (
<AgentProvider
getSessionToken={async () => {
const res = await fetch('/api/session', { method: 'POST' });
return res.json();
}}
projectId="your-project-id"
integrationId="your-integration-id"
>
<CustomChat />
</AgentProvider>
);
}
In headless mode you handle all rendering — message bubbles, tool call cards, approval buttons, streaming indicators. The hook gives you the data and actions, you build the UI.
For the message data structure (ConversationMessage, ContentBlock, ToolCallDisplay, ToolCallStatus), see Message format in the core SDK docs. The types are the same — @kapaai/agent-react re-exports them from @kapaai/agent-core.
useAgentChat() return value
| Field | Type | Description |
|---|---|---|
messages | ConversationMessage[] | All messages in the conversation. |
isStreaming | boolean | Whether the agent is currently streaming a response. |
threadId | string | null | Current conversation thread ID. |
inputValue | string | Current input field value. |
setInputValue | (value: string) => void | Update the input field value. |
sendMessage | (text: string) => Promise<void> | Send a message and trigger the agent loop. |
resetConversation | () => void | Clear messages and abort any in-progress request. |
stopGeneration | () => void | Abort the current streaming response. |
approveToolCall | (id: string) => void | Approve a tool waiting for confirmation. |
rejectToolCall | (id: string) => void | Reject a tool waiting for confirmation. |
Lower-level components
These components are also exported for advanced customization. They require AgentProvider for theming context:
| Component | Description |
|---|---|
AgentInput | Textarea with send/stop button. |
AgentMessageBubble | Renders a single message (user bubble, assistant markdown, or error alert). |
ToolCallCard | Expandable tool call card with args/response/sources tabs. |
ToolCallGroup | Container for grouping tool cards. |
SourceTiles | Source attribution tiles with favicons. |
ExamplePrompts | Starter prompt buttons for empty conversations. |
ShimmerText | Animated shimmer text for loading states. |