@kapaai/agent-react
v1.1.0
Published
Kapa Agent Framework — React components and hooks for building AI agents with chat UI, tool cards, theming, and streaming
Readme
Kapa Agent Framework — React
Build in-product AI agents powered by your knowledge base — with a ready-made chat UI, custom tools, theming, and streaming.
What is Kapa Agent Framework?
The Kapa Agent Framework lets you embed an AI agent in your product that can answer questions from your knowledge base and take actions through custom tools. The agent runs a multi-turn loop: it streams responses, calls tools (with optional user approval), and continues until it has a final answer.
@kapaai/agent-react provides React components and hooks on top of @kapaai/agent-core. Use the built-in UI for a complete chat experience, or use only the hooks to build a fully custom interface.
Installation
npm install @kapaai/agent-reactFor type-safe tool definitions with Zod (optional):
npm install zod zod-to-json-schemaQuick Start
import { createToolHelper } from "@kapaai/agent-core";
import { AgentProvider, AgentChat } from "@kapaai/agent-react";
import { z } from "zod";
const tool = createToolHelper<{ api: ApiClient }>();
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"
model="kapa-agent-1.0"
tools={[
tool({
name: "search_orders",
description: "Search customer orders",
parameters: z.object({ query: z.string() }),
execute: async ({ query }, ctx) => ctx.api.searchOrders(query),
}),
]}
context={{ api: myApiClient }}
theme={{ accentColor: "#2563eb", colorScheme: "dark" }}
>
<div style={{ height: 600 }}>
<AgentChat
branding={{
title: "Support Agent",
examplePrompts: ["What are my recent orders?"],
}}
/>
</div>
</AgentProvider>
);
}Features
- Ready-made chat UI — Full chat panel with messages, tool cards, sources, and streaming out of the box
- Headless mode — Use only
useAgentChat()hook to build a completely custom UI - Custom tools — Define tools with Zod schemas for type-safe argument inference
- Generative UI — Tools can render custom React components per execution state via
renderprop - Human-in-the-loop — Tools can require user approval before execution
- Conversation history —
AgentChatshows a history toggle when the session hasexternal_owner_id;<AgentThreadHistory />is also exported standalone. SetenableHistory={true}onAgentProviderto opt in. - Model selection — Pin to a specific agent model version (e.g.
kapa-agent-1.0) - Theming — Accent color, dark/light mode, font, border radius — all configurable
- Localization: Built-in translations for 14 languages, selected with a single
localeprop - Slide-in panel —
AgentPanelcomponent for drawer-style chat - Analytics events — Optional
onEventcallback for monitoring agent interactions - Session management — Automatic token refresh and 401 retry (via agent-core)
Headless Usage
Use only the hooks to build your own chat interface — no SDK components required:
import { AgentProvider, useAgentChat } from "@kapaai/agent-react";
const ChatUI = () => {
const {
messages,
isStreaming,
sendMessage,
approveToolCall,
rejectToolCall,
} = useAgentChat();
// Render your own UI using messages array.
// Each assistant message has a blocks array with text and tool_calls blocks.
};Custom Tool Rendering
Tools can provide a render function for custom inline UI based on execution state:
tool({
name: "get_usage",
description: "Get API usage for the current billing period",
parameters: z.object({}),
execute: async (_args, ctx) => ctx.api.getUsage(),
render: ({ status, result }) => {
if (status === "executing") return <p>Loading...</p>;
if (status === "completed") return <UsageChart data={result} />;
return null; // fall back to default tool card
},
});Tools that need user confirmation before execution:
tool({
name: "delete_project",
description: "Delete a project",
parameters: z.object({ projectId: z.string() }),
needsApproval: true,
execute: async ({ projectId }, ctx) => ctx.api.deleteProject(projectId),
});Theming
<AgentProvider
theme={{
accentColor: "#2563eb", // any hex — generates a 10-shade palette
colorScheme: "dark", // 'dark' | 'light' | 'auto'
radius: "soft", // 'sharp' | 'soft' | 'round' | 'pill'
fontSize: 14, // base font size in px
fontFamily: "Inter, system-ui, sans-serif",
}}
>Toggle the color scheme at runtime:
import { useAgentColorScheme } from "@kapaai/agent-react";
const { colorScheme, toggleColorScheme } = useAgentColorScheme();Localization
The UI ships with built-in translations. Pass locale to select one:
<AgentProvider locale="nl" {...otherProps}>Supported languages: English (default), Chinese (Simplified), Czech, Dutch, Finnish, French, German, Italian, Japanese, Korean, Polish, Portuguese, Russian, and Spanish.
Regional tags
locale is a BCP 47 tag. A regional tag such as nl-BE or pt-PT uses the base-language translation and keeps the region for number, date, and plural formatting. Chinese ships in Simplified script, so zh, zh-CN, and zh-Hans use it, while zh-TW, zh-HK, and zh-Hant fall back to English. A missing, malformed, or unsupported tag also falls back to English.
The resolved tag is set as the lang attribute on each element that shows built-in text, so screen readers switch pronunciation for those labels. Your own content, the agent's answers, tool names, and tool output keep the host page's language.
Loading and failures
English is bundled with the package. Every other language is a separate chunk that loads the first time it is requested and stays cached for the page, so providers that request the same language share one download.
Until the first requested language is ready, components keep their outer size and render no English text. The chat shows its header, branding title, and close button during that time, and the rest of its content appears with the language. With server rendering, a non-English locale renders that placeholder on the server and fills in after hydration. When locale changes later, the current language stays on screen until the new one is ready, and the conversation, input, focus, and scroll position are kept.
If the first language fails to load or does not arrive within a few seconds, the UI settles on English. If a later change fails, the current language stays. A download that arrives after the wait is kept and used the next time that language is requested. A download the browser recorded as failed cannot be retried until the page reloads, because browsers remember a failed module load for the life of the page.
Integrator-owned content
AgentChatBranding wins over the translated defaults: title, subtitle, and inputPlaceholder replace the built-in header title, empty-state heading, and input placeholder. Translate your branding, example prompts, tool display names, tool output, and tool errors yourself, because the UI renders them as given. The one exception is the fallback the SDK substitutes when a tool throws a value that is not an Error, which is translated. Agent answers and thread titles come from the server and are also shown unchanged.
Slide-in Panel
import { AgentPanel } from "@kapaai/agent-react";
<AgentPanel
open={isOpen}
onClose={() => setIsOpen(false)}
width={480}
top={60}
branding={{ title: "Help" }}
/>;Analytics Events
<AgentProvider
onEvent={(event) => {
analytics.track(`agent_${event.type}`, event.data);
}}
>Events: message_sent, response_completed, response_error, generation_stopped, tool_executed, tool_approved, tool_denied, conversation_reset, thread_resumed, thread_deleted, panel_opened, panel_closed.
Authentication
Session tokens are created server-side using your Kapa API key, then passed to the agent via getSessionToken. The API key never reaches the browser.
Browser → Your backend → POST /agent/v1/projects/{id}/agent/sessions/ (with API key)
Browser ← session token
Browser → Kapa API → POST /agent/v1/projects/{id}/agent/chat/ (with session token)Resources
- Documentation — Full setup guide, API reference, and integration patterns
- Examples — Runnable examples (React, Next.js, headless React, vanilla JS)
@kapaai/agent-core— Headless core package (included as a dependency)
