
Security News
RubyGems Adds Cooldown Feature to Bundler for Newly Published Gems
RubyGems and Bundler 4.0.13 introduced an opt-in cooldown feature that delays newly published gems during dependency resolution.
@bdky/chat-pilot-kit-react
Advanced tools
chat-pilot-kit 的 React 封装,提供 Provider、Context、Hooks 和 ReactNodeViewRenderer
React adapter for @bdky/chat-pilot-kit — provides Provider, Hooks, NodeView components, and i18n support for building AI chat interfaces.
English | 简体中文
npm install @bdky/chat-pilot-kit-react @bdky/chat-pilot-kit
# or
yarn add @bdky/chat-pilot-kit-react @bdky/chat-pilot-kit
Peer dependencies: React ≥ 16.8
import {createChatPilotKit, BaseAgentService} from '@bdky/chat-pilot-kit';
import {
ChatPilotKitProvider,
useConversations,
useChatPilotKit,
NodeRenderer,
getDefaultReactExtensions,
} from '@bdky/chat-pilot-kit-react';
import '@bdky/chat-pilot-kit-react/styles.css';
// 1. Implement your agent service
class MyAgentService extends BaseAgentService {
async run(query, context) {
// call your AI backend and stream responses
}
}
// 2. Create the controller
const controller = createChatPilotKit({
agentService: new MyAgentService(),
extensions: getDefaultReactExtensions(),
});
// 3. Wrap your app
export default function App() {
return (
<ChatPilotKitProvider controller={controller}>
<Chat />
</ChatPilotKitProvider>
);
}
// 4. Build your chat UI
function Chat() {
const {controller} = useChatPilotKit();
const conversations = useConversations();
return (
<div>
{conversations.map(conv =>
conv.nodes.map(node => (
<NodeRenderer
key={node.id}
node={node}
conversation={conv.bean}
/>
))
)}
<button onClick={() => controller.query('Hello')}>Send</button>
</div>
);
}
Import the bundled CSS once at your app entry point:
import '@bdky/chat-pilot-kit-react/styles.css';
ChatPilotKitProviderContext provider that makes the controller available to all child components.
<ChatPilotKitProvider controller={controller}>
{children}
</ChatPilotKitProvider>
| Prop | Type | Description |
|---|---|---|
controller | ChatPilotKitController | Controller created by createChatPilotKit() |
children | ReactNode | — |
useChatPilotKit()Returns the controller from context. Throws if called outside ChatPilotKitProvider.
const {controller} = useChatPilotKit();
await controller.query('Hello');
await controller.queryWithAttachments('Check this file', attachments);
controller.interrupt();
controller.clear();
controller.importConversations(inputs, {position: 'prepend'});
const snapshots = controller.exportConversations();
useConversations()Returns a reactive list of all conversations, automatically synced with controller state.
const conversations = useConversations();
// conversations: IConversationItem[]
// Each item: { conversationId, role, nodes, completed, bean }
useChatPilotKitEvents(props)Subscribe to controller lifecycle events. All callbacks are optional.
useChatPilotKitEvents({
onReady: () => {},
onConversationAdd: (payload) => {},
onConversationChange: (payload) => {
if (payload.completed && payload.role === 'aiWorker') {
setLoading(false);
}
},
onNodeAdd: (payload) => {},
onNodeUpdate: (payload) => {},
onError: (payload) => { console.error(payload); },
onInterrupt: () => {},
onClear: () => {},
onTtft: (payload) => {},
onHistoryImport: (payload) => {},
onNodeInteraction: (payload) => {},
});
useNodeInteraction(props)Bidirectional communication with NodeView components — listen to interactions and send commands.
const {sendCommand} = useNodeInteraction({
filter: 'click', // string | string[] | (type) => boolean
onInteraction: (payload) => {
console.log(payload.type, payload.data, payload.nodeId);
},
});
// Send a command to a specific node
sendCommand(nodeId, 'highlight', {color: 'yellow'});
NodeViews are React components that render individual conversation nodes. The SDK ships 8 built-in NodeViews and a registration system for custom ones.
NodeRendererRenders a single ConversationNode using its registered NodeView.
<NodeRenderer node={node} conversation={conv.bean} />
Register all built-in NodeViews at once:
import {getDefaultReactExtensions} from '@bdky/chat-pilot-kit-react';
const controller = createChatPilotKit({
extensions: getDefaultReactExtensions(),
// ...
});
Or register individually:
import {
ReactTextExtension,
ReactMarkdownExtension,
ReactThinkingBlockExtension,
ReactToolCallExtension,
ReactImageExtension,
ReactFileExtension,
ReactAudioExtension,
ReactVideoExtension,
} from '@bdky/chat-pilot-kit-react';
Replace a built-in NodeView or register a new one:
import {
ReactMarkdownExtension,
ReactNodeViewRenderer,
MarkdownNodeView,
} from '@bdky/chat-pilot-kit-react';
import type {NodeViewProps, MarkdownNode} from '@bdky/chat-pilot-kit';
// Wrap a built-in NodeView with custom props
const MyMarkdown: FC<NodeViewProps<MarkdownNode>> = (props) => (
<MarkdownNodeView {...props} className="my-markdown" />
);
// Or write a fully custom NodeView
const CustomMarkdown: FC<NodeViewProps<MarkdownNode>> = ({node}) => (
<div className="custom">{node.content}</div>
);
const MyMarkdownExtension = ReactMarkdownExtension.extend({
addNodeView() {
return ReactNodeViewRenderer(MyMarkdown);
}
});
All built-in NodeView components accept optional extension props for secondary customization without replacing the entire component.
| Prop | Type | Description |
|---|---|---|
className | string | Appended to the root element alongside built-in BEM classes |
style | CSSProperties | Merged onto the root element |
dataAttributes | Record<\data-${string}`, string | number | boolean>` | Forwarded as data-* attributes on the root element |
ThinkingBlockNodeView<ThinkingBlockNodeView
{...props}
defaultOpen={false}
slots={{
icon: <MyIcon />,
label: <span>Thinking...</span>,
content: (text) => <pre className="custom-pre">{text}</pre>,
}}
/>
| Prop | Type | Default |
|---|---|---|
defaultOpen | boolean | true |
slots.icon | ReactNode | Built-in bulb SVG |
slots.label | ReactNode | i18n label |
slots.content | (text: string) => ReactNode | <pre> block |
ToolCallNodeView<ToolCallNodeView
{...props}
defaultOpen={true}
slots={{
icon: <TerminalIcon />,
badge: (status, label) => <MyBadge status={status}>{label}</MyBadge>,
argsContent: (args) => <JsonViewer data={args} />,
resultContent: (result) => <JsonViewer data={result} />,
errorContent: (error) => <Alert type="error">{error}</Alert>,
}}
/>
| Prop | Type | Default |
|---|---|---|
defaultOpen | boolean | false |
slots.icon | ReactNode | Built-in terminal SVG |
slots.badge | (status: ToolCallStatus, label: string) => ReactNode | Built-in badge |
slots.argsContent | (args: unknown) => ReactNode | JSON <pre> |
slots.resultContent | (result: unknown) => ReactNode | JSON <pre> |
slots.errorContent | (error: string) => ReactNode | Error <div> |
ImageNodeView| Prop | Type |
|---|---|
slots.image | (props: {src, alt, width?, height?}) => ReactNode |
slots.caption | (alt: string) => ReactNode |
FileNodeView| Prop | Type |
|---|---|
slots.icon | (fileType: string) => ReactNode |
slots.downloadIcon | ReactNode |
AudioNodeView| Prop | Type | Description |
|---|---|---|
audioProps | AudioHTMLAttributes<HTMLAudioElement> | Forwarded to the <audio> element |
VideoNodeView| Prop | Type | Description |
|---|---|---|
videoProps | VideoHTMLAttributes<HTMLVideoElement> | Forwarded to the <video> element |
TextNodeView and MarkdownNodeView support common props only (no slots).
Built-in NodeViews (ThinkingBlock, ToolCall) support English and Simplified Chinese out of the box.
import {CpkTranslationsProvider} from '@bdky/chat-pilot-kit-react';
<CpkTranslationsProvider locale="zh-CN">
{/* ThinkingBlockNodeView and ToolCallNodeView will use Chinese labels */}
<App />
</CpkTranslationsProvider>
Override specific strings:
<CpkTranslationsProvider
locale="en"
translations={{
thinkingBlockLabel: 'Reasoning',
toolCallStatusRunning: 'Executing...',
}}
>
<App />
</CpkTranslationsProvider>
Available keys: thinkingBlockLabel, toolCallStatusPending, toolCallStatusRunning, toolCallStatusCompleted, toolCallStatusError, toolCallArguments, toolCallResult.
NodeView styles use CSS custom properties under the --cpk-node-* namespace. Override them to theme all NodeViews at once:
:root {
--cpk-node-surface: #ffffff;
--cpk-node-text-primary: #111827;
--cpk-node-accent: #2563eb;
--cpk-node-panel-bg: #f9fafb;
--cpk-node-border: #e5e7eb;
}
[data-theme='dark'] {
--cpk-node-surface: #1e1e2e;
--cpk-node-text-primary: #cdd6f4;
--cpk-node-accent: #89b4fa;
--cpk-node-panel-bg: #181825;
--cpk-node-border: #313244;
}
The theme system respects both prefers-color-scheme media query and explicit data-theme="light" | "dark" attributes on any ancestor element.
All types are exported from the package root:
import type {
// From @bdky/chat-pilot-kit (re-exported)
NodeViewProps,
ConversationNode,
ConversationBean,
ConversationRole,
IConversationBeanInput,
IAttachmentInput,
INodeInteractionPayload,
INodeViewCommand,
BaseAgentService,
// React-specific
ReactNodeViewComponent,
NodeViewExtensionProps,
ThinkingBlockNodeViewExtProps,
ToolCallNodeViewExtProps,
ImageNodeViewExtProps,
FileNodeViewExtProps,
AudioNodeViewExtProps,
VideoNodeViewExtProps,
ToolCallStatus,
CpkTranslations,
} from '@bdky/chat-pilot-kit-react';
MIT © Baidu Keyue Team
FAQs
chat-pilot-kit 的 React 封装,提供 Provider、Context、Hooks 和 ReactNodeViewRenderer
We found that @bdky/chat-pilot-kit-react demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 3 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
RubyGems and Bundler 4.0.13 introduced an opt-in cooldown feature that delays newly published gems during dependency resolution.

Security News
pnpm 11.5 now recognizes npm staged publish approvals in release metadata, preventing those releases from being mistaken for lower-trust package publishes.

Security News
Federal audit finds NIST lacked a plan to clear the NVD backlog, wasted funds on duplicate work, and delayed use of CISA data.