@cuadra-ai/uikit
v0.5.0
Published
A production-ready React UI kit for building AI chat experiences with the Cuadra AI API
Maintainers
Readme
@cuadra-ai/uikit
A production-ready React UI kit for building AI chat experiences with the Cuadra AI API, built on top of assistant-ui.
📚 Full Documentation | 🌐 Website
Features
- 🚀 Ready-to-use chat components - Pre-built thread list, message display, and composer
- 🎨 Beautiful UI - Textured card design with theme support (light/dark/system)
- 🔄 Multiple chat modes - Single chat or multi-thread support
- 🤖 Model selection - Fixed model or dynamic model selector
- 📦 Two build formats:
- Library build (ESM/CJS) - For use in React applications
- Widget build (UMD) - For direct browser embedding via script tag
- 🔐 Flexible authentication - Bearer token or proxy mode for backend-handled auth
- ⚡ Streaming support - Real-time message streaming via SSE
- 🧵 Thread management - Create, rename, delete, and switch between chat threads
- 🌐 i18n ready - Language/locale support
Installation
npm install @cuadra-ai/uikitPeer Dependencies
This package requires the following peer dependencies:
npm install react react-domNote: @assistant-ui/react and @assistant-ui/react-markdown are bundled dependencies and don't need to be installed separately.
Usage
Using CuadraChat Component (Recommended)
The CuadraChat component is the easiest way to get started. It's an all-in-one component that handles everything for you.
Styles are automatically included when you import components from @cuadra-ai/uikit. You don't need to manually import styles unless you're using a custom build setup. If styles don't load automatically, you can manually import them:
import '@cuadra-ai/uikit/styles';Basic Example
import { CuadraChat } from '@cuadra-ai/uikit';
function App() {
return (
<div style={{ height: '100vh' }}>
<CuadraChat
baseUrl="https://api.cuadra.ai"
sessionToken="your-session-token"
mode="multiChat"
modelMode="fixed"
modelId="your-model-id" // Get this from dashboard.cuadra.ai
/>
</div>
);
}Note: Model IDs are provided in your Cuadra AI Dashboard. Create and manage your models there, then use the model ID in your code.
With Model Selector
import { CuadraChat } from '@cuadra-ai/uikit';
import { useState } from 'react';
function App() {
const [modelId, setModelId] = useState<string | null>(null);
return (
<div style={{ height: '100vh' }}>
<CuadraChat
baseUrl="https://api.cuadra.ai"
sessionToken="your-session-token"
mode="multiChat"
modelMode="selector"
modelId={modelId || undefined}
onModelChange={setModelId}
/>
</div>
);
}Proxy Mode (Backend Authentication)
When your backend handles authentication, use proxyUrl instead of baseUrl:
import { CuadraChat } from '@cuadra-ai/uikit';
function App() {
return (
<div style={{ height: '100vh' }}>
<CuadraChat
proxyUrl="/api/chat"
mode="multiChat"
modelMode="fixed"
modelId="your-model-id"
/>
</div>
);
}New V2 Props (Recommended)
The new V2 props API groups related options for better organization:
import { CuadraChat } from '@cuadra-ai/uikit';
function App() {
return (
<div style={{ height: '100vh' }}>
<CuadraChat
connection={{
baseUrl: "https://api.cuadra.ai",
sessionToken: "your-session-token",
}}
chat={{
mode: "multiChat",
modelMode: "fixed",
modelId: "your-model-id",
enableReasoning: true,
}}
ui={{
theme: "system",
welcomeTitle: "Welcome to Chat",
welcomeSubtitle: "How can I help you today?",
suggestions: [
{ prompt: "What is Cuadra AI?" },
{ prompt: "How do I get started?" }
],
}}
callbacks={{
onChatCreated: (chatId) => console.log('Chat:', chatId),
onError: (error) => console.error(error),
}}
className="my-custom-class"
/>
</div>
);
}With Context Provider (External Control)
Use CuadraChatProvider to control the chat from anywhere in your component tree:
import { CuadraChat, CuadraChatProvider, useCuadraChat } from '@cuadra-ai/uikit';
function ChatControls() {
const { controls, isReady } = useCuadraChat();
return (
<button
onClick={() => controls?.sendMessage('Hello!')}
disabled={!isReady}
>
Send Hello
</button>
);
}
function App() {
return (
<CuadraChatProvider>
<ChatControls />
<CuadraChat
connection={{ baseUrl: "https://api.cuadra.ai" }}
chat={{ modelId: "your-model-id" }}
/>
</CuadraChatProvider>
);
}With Error Boundary
CuadraChat includes built-in error handling:
import { CuadraChat } from '@cuadra-ai/uikit';
function App() {
return (
<CuadraChat
connection={{ baseUrl: "https://api.cuadra.ai" }}
chat={{ modelId: "your-model-id" }}
errorFallback={(error, reset) => (
<div>
<p>Something went wrong: {error.message}</p>
<button onClick={reset}>Retry</button>
</div>
)}
/>
);
}Legacy Props (Still Supported)
import { CuadraChat } from '@cuadra-ai/uikit';
function App() {
return (
<div style={{ height: '100vh' }}>
<CuadraChat
baseUrl="https://api.cuadra.ai"
sessionToken="your-session-token"
mode="multiChat"
modelMode="fixed"
modelId="your-model-id"
className="my-custom-class"
showThemeToggle={true}
theme="system"
language="en"
welcomeTitle="Welcome to Chat"
welcomeSubtitle="How can I help you today?"
extraTopPadding="2rem"
suggestions={[
{ prompt: "What is Cuadra AI?" },
{ prompt: "How do I get started?" },
{ prompt: "Show me examples" }
]}
onChatCreated={(chatId) => {
console.log('Chat created:', chatId);
}}
onThreadIdUpdate={(oldId, newId) => {
console.log('Thread updated:', oldId, '->', newId);
}}
onError={(error) => {
console.error('Error:', error);
}}
/>
</div>
);
}Widget Mode (Script Tag - Compiled JS)
The widget build allows you to embed the chat interface directly in any HTML page without a build step.
Basic HTML Setup
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Cuadra Chat</title>
<link rel="stylesheet" href="https://unpkg.com/@cuadra-ai/uikit@latest/dist/widget/cuadra-uikit.css">
<style>
body {
margin: 0;
padding: 0;
height: 100vh;
}
#cuadra-chat {
height: 100vh;
width: 100%;
}
</style>
</head>
<body>
<div id="cuadra-chat"></div>
<script src="https://unpkg.com/@cuadra-ai/uikit@latest/dist/widget/cuadra-uikit.umd.js"></script>
<script>
CuadraUIKit.init({
baseUrl: 'https://api.cuadra.ai',
sessionToken: 'your-session-token',
mode: 'multiChat',
modelMode: 'fixed',
modelId: 'your-model-id',
});
</script>
</body>
</html>With Data Attributes (Auto-initialization)
<div id="cuadra-chat"
data-base-url="https://api.cuadra.ai"
data-session-token="your-session-token"
data-mode="multiChat"
data-model-mode="fixed"
data-model-id="your-model-id"
style="height: 100vh; width: 100%;">
</div>
<script src="https://unpkg.com/@cuadra-ai/uikit@latest/dist/widget/cuadra-uikit.umd.js"></script>Proxy Mode (Widget)
<div id="cuadra-chat" style="height: 100vh; width: 100%;"></div>
<script src="https://unpkg.com/@cuadra-ai/uikit@latest/dist/widget/cuadra-uikit.umd.js"></script>
<script>
CuadraUIKit.init({
proxyUrl: '/api/chat',
mode: 'multiChat',
modelMode: 'fixed',
modelId: 'your-model-id',
});
</script>For detailed widget API documentation, see the full documentation.
API Reference
V2 Props (Recommended)
| Prop Group | Prop | Type | Description |
|------------|------|------|-------------|
| connection | baseUrl | string | Cuadra API base URL |
| | proxyUrl | string | Proxy URL for backend auth |
| | sessionToken | string \| null | Bearer token |
| chat | mode | 'singleChat' \| 'multiChat' | Chat mode (default: 'multiChat') |
| | modelMode | 'fixed' \| 'selector' | Model selection mode (default: 'fixed') |
| | modelId | string | Model ID from dashboard |
| | systemPrompt | string | System prompt |
| | ephemeral | boolean | Auto-delete chats on close |
| | enableReasoning | boolean | Enable thinking output |
| | enableAttachments | boolean | Enable file attachments |
| ui | theme | 'light' \| 'dark' \| 'system' | Theme mode (default: 'system') |
| | showThemeToggle | boolean | Show toggle (default: true) |
| | welcomeTitle | string | Welcome screen title |
| | welcomeSubtitle | string | Welcome screen subtitle |
| | suggestions | Array<Suggestion> | Welcome screen suggestions |
| | inputPlaceholder | string | Input field placeholder |
| callbacks | onChatCreated | (id: string) => void | Called when chat created |
| | onError | (error: Error) => void | Error callback |
| | onModelChange | (id: string) => void | Model change callback |
| errorFallback | | ReactNode \| Function | Custom error UI |
| className | | string | Container CSS class |
Exported Hooks
| Hook | Description |
|------|-------------|
| useCuadraChat() | Access chat controls from context (requires CuadraChatProvider) |
| useCuadraChatOptional() | Same as above, returns null if no provider |
Exported Utilities
| Utility | Description |
|---------|-------------|
| sanitizeSystemPrompt() | Remove injection patterns from prompts |
| isValidUrl() | Validate URL uses http/https |
| validateBaseUrl() | Validate API base URL with details |
| generateSecureUUID() | Crypto-secure UUID generation |
| createAttachmentAdapter() | Create file attachment adapter with validation |
Legacy Props (Still Supported)
| Prop | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| baseUrl | string | Yes* | - | Cuadra API base URL (e.g., 'https://api.cuadra.ai') |
| proxyUrl | string | Yes* | - | Proxy URL for backend-handled auth (e.g., '/api/chat') |
| sessionToken | string \| null | No | null | Bearer token for authentication |
| mode | 'singleChat' \| 'multiChat' | No | 'multiChat' | Chat mode |
| modelMode | 'fixed' \| 'selector' | No | 'fixed' | Model selection mode |
| modelId | string | Yes** | - | Model ID from dashboard.cuadra.ai (required if modelMode='fixed') |
| onModelChange | (modelId: string) => void | No | - | Callback when model changes (selector mode) |
| ephemeral | boolean | No | false | Create temporary chats that auto-delete |
| systemPrompt | string | No | - | System prompt for the assistant |
| initialThreadId | string | No | - | Load existing thread (multiChat mode) |
| className | string | No | - | Container className for styling |
| showThemeToggle | boolean | No | true | Show theme toggle button |
| theme | 'light' \| 'dark' \| 'system' | No | 'system' | Initial theme |
| language | string | No | - | Language/locale for i18n (e.g., 'en', 'es', 'fr') |
| welcomeTitle | string | No | - | Welcome screen title |
| welcomeSubtitle | string | No | - | Welcome screen subtitle |
| extraTopPadding | string | No | - | Extra top padding for thread viewport (e.g., '1rem', '2rem') |
| suggestions | Array<{ prompt: string }> | No | - | Suggestions to show in welcome screen |
| onError | (error: Error) => void | No | - | Error callback |
| onChatCreated | (chatId: string) => void | No | - | Callback when chat is created |
| onThreadIdUpdate | (oldId: string, newId: string) => void | No | - | Callback when thread ID updates |
* Either baseUrl or proxyUrl is required
** Required if modelMode='fixed'
License
MIT License
Third-Party Licenses: This package bundles code from third-party libraries in the widget build. The THIRD_PARTY_LICENSES.md file is included in the published package for attribution and license information.
Support
For issues and questions:
- 📚 Documentation - Full API reference and guides
- 🌐 Website - Learn more about Cuadra AI
- 📧 Support: [email protected]
