A feature-rich, beautifully crafted React AI chat component library
Kira Chat 是一个基于 React 的 AI 聊天组件库,提供开箱即用的聊天界面。支持流式输出、Markdown 渲染、数学公式、代码高亮和工具调用可视化。采用适配器模式,只需实现一个函数即可接入任何 AI 后端。内置 CSS Token 主题系统,通过变量即可完全定制外观,支持亮色/暗色/跟随系统三种模式。
English | 简体中文
npm install @hakurei/kira-chat
import '@hakurei/kira-chat/styles'
import { AIChat } from '@hakurei/kira-chat'
import type { AIAdapter } from '@hakurei/kira-chat'
const adapter: AIAdapter = async ({ messages, onChunk, onComplete, signal }) => {
const res = await fetch('https://api.openai.com/v1/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${import.meta.env.VITE_OPENAI_KEY}`,
},
body: JSON.stringify({
model: 'gpt-4o',
stream: true,
messages: messages.map((m) => ({ role: m.role, content: m.content })),
}),
signal,
})
const reader = res.body!.getReader()
const decoder = new TextDecoder()
while (true) {
const { done, value } = await reader.read()
if (done) break
const text = decoder.decode(value)
for (const line of text.split('\n')) {
if (!line.startsWith('data: ') || line === 'data: [DONE]') continue
try {
const json = JSON.parse(line.slice(6))
const chunk = json.choices?.[0]?.delta?.content
if (chunk) onChunk?.(chunk)
} catch {}
}
}
onComplete?.({ id: '', role: 'assistant', content: '', status: 'done', createdAt: Date.now() })
}
export default function App() {
return (
<AIChat
adapter={adapter}
theme={{ preset: 'light' }}
height="100vh"
/>
)
}
所有颜色均通过 CSS 自定义属性(变量)控制,格式为 RGB 三元组(不含 alpha),方便配合 Tailwind 的 /opacity 语法。
[data-hk-theme="light"] {
--hk-primary: 99 102 241; /* indigo-500 */
--hk-primary-foreground: 255 255 255;
--hk-background: 255 255 255;
--hk-foreground: 15 23 42;
--hk-surface: 248 250 252;
--hk-border: 226 232 240;
/* ... */
}
<AIChat
theme={{
preset: 'light', // 'light' | 'dark' | 'auto'
light: {
primary: '168 85 247', // purple-500
primaryForeground: '255 255 255',
accent: '217 70 239',
radiusLg: '20px', // 更大圆角
},
dark: {
primary: '192 132 252', // purple-400
},
}}
/>
| Token | CSS 变量 | 说明 |
|---|---|---|
primary | --hk-primary | 主色调(按钮、链接等) |
primaryForeground | --hk-primary-foreground | 主色调前景(白/黑) |
background | --hk-background | 根背景色 |
surface | --hk-surface | 卡片/侧栏背景 |
surfaceElevated | --hk-surface-elevated | 悬浮/高亮背景 |
foreground | --hk-foreground | 主文字色 |
border | --hk-border | 边框色 |
muted | --hk-muted | 次要背景 |
mutedForeground | --hk-muted-foreground | 次要文字 |
destructive | --hk-destructive | 危险/错误色 |
success | --hk-success | 成功色 |
radiusSm/Md/Lg/Xl | --hk-radius-* | 圆角尺寸 |
fontSans/Mono | --hk-font-* | 字体栈 |
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
adapter | AIAdapter | -- | AI 请求适配器(核心) |
conversations | Conversation[] | -- | 受控会话列表 |
activeConversationId | string | -- | 当前激活会话 |
tools | ToolDefinition[] | -- | 工具定义列表 |
theme | ThemeConfig | { preset: 'light' } | 主题配置 |
showSidebar | boolean | true | 是否显示侧栏 |
allowAttachments | boolean | false | 允许文件附件 |
placeholder | string | -- | 输入框占位文本 |
welcomeTitle | string | -- | 欢迎页标题 |
height | string | number | '100%' | 容器高度 |
onConversationCreate | (c: Conversation) => void | -- | 新建会话回调 |
onConversationSelect | (id: string) => void | -- | 切换会话回调 |
onMessageSend | (msg, cid) => void | -- | 发送消息回调 |
type AIAdapter = (options: SendMessageOptions) => Promise<void>
interface SendMessageOptions {
conversationId: string
messages: Message[] // 历史消息
onChunk?: (chunk: string) => void // 流式文本块
onToolCall?: (toolCall: ToolCall) => void // 工具调用
onComplete?: (message: Message) => void // 完成
onError?: (error: Error) => void // 错误
signal?: AbortSignal // 取消信号
}
interface ToolDefinition {
name: string
description?: string
parameters?: Record<string, unknown> // JSON Schema
icon?: React.ReactNode // 自定义图标
renderCall?: (call: ToolCall) => React.ReactNode // 自定义输入渲染
renderResult?: (result: ToolResult, call?: ToolCall) => React.ReactNode // 自定义结果渲染
}
所有子组件均可独立引入:
import {
ChatWindow,
ChatInput,
MessageBubble,
ToolCallCard,
ConversationList,
MarkdownRenderer,
ThemeProvider,
} from '@hakurei/kira-chat'
<ThemeProvider theme={{ preset: 'dark', dark: { primary: '56 189 248' } }}>
<YourApp />
</ThemeProvider>
组件内置 Zustand store,可通过 useChatStore Hook 直接操作:
import { useChatStore } from '@hakurei/kira-chat'
function MyComponent() {
const {
conversations,
activeConversationId,
createConversation,
deleteConversation,
addMessage,
stopStreaming,
} = useChatStore()
// ...
}
git clone https://github.com/hakurei/kira-chat.git
cd kira-chat
npm install
npm run dev # 启动 Demo 演示页
构建库:
npm run build # 输出到 dist/
欢迎提交 Issue 和 Pull Request!
MIT © hakurei