Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@bdky/chat-pilot-kit-react

Package Overview
Dependencies
Maintainers
3
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@bdky/chat-pilot-kit-react

chat-pilot-kit 的 React 封装,提供 Provider、Context、Hooks 和 ReactNodeViewRenderer

latest
npmnpm
Version
1.0.5
Version published
Maintainers
3
Created
Source

@bdky/chat-pilot-kit-react

React adapter for @bdky/chat-pilot-kit — provides Provider, Hooks, NodeView components, and i18n support for building AI chat interfaces.

English | 简体中文

npm version license TypeScript

Installation

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

Quick Start

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>
    );
}

Styles

Import the bundled CSS once at your app entry point:

import '@bdky/chat-pilot-kit-react/styles.css';

API Reference

ChatPilotKitProvider

Context provider that makes the controller available to all child components.

<ChatPilotKitProvider controller={controller}>
    {children}
</ChatPilotKitProvider>
PropTypeDescription
controllerChatPilotKitControllerController created by createChatPilotKit()
childrenReactNode

Hooks

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'});

NodeView System

NodeViews are React components that render individual conversation nodes. The SDK ships 8 built-in NodeViews and a registration system for custom ones.

NodeRenderer

Renders a single ConversationNode using its registered NodeView.

<NodeRenderer node={node} conversation={conv.bean} />

Built-in Extensions

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';

Custom NodeViews

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);
    }
});

NodeView Extension Props

All built-in NodeView components accept optional extension props for secondary customization without replacing the entire component.

Common Props (all NodeViews)

PropTypeDescription
classNamestringAppended to the root element alongside built-in BEM classes
styleCSSPropertiesMerged onto the root element
dataAttributesRecord<\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>,
    }}
/>
PropTypeDefault
defaultOpenbooleantrue
slots.iconReactNodeBuilt-in bulb SVG
slots.labelReactNodei18n 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>,
    }}
/>
PropTypeDefault
defaultOpenbooleanfalse
slots.iconReactNodeBuilt-in terminal SVG
slots.badge(status: ToolCallStatus, label: string) => ReactNodeBuilt-in badge
slots.argsContent(args: unknown) => ReactNodeJSON <pre>
slots.resultContent(result: unknown) => ReactNodeJSON <pre>
slots.errorContent(error: string) => ReactNodeError <div>

ImageNodeView

PropType
slots.image(props: {src, alt, width?, height?}) => ReactNode
slots.caption(alt: string) => ReactNode

FileNodeView

PropType
slots.icon(fileType: string) => ReactNode
slots.downloadIconReactNode

AudioNodeView

PropTypeDescription
audioPropsAudioHTMLAttributes<HTMLAudioElement>Forwarded to the <audio> element

VideoNodeView

PropTypeDescription
videoPropsVideoHTMLAttributes<HTMLVideoElement>Forwarded to the <video> element

TextNodeView and MarkdownNodeView support common props only (no slots).

i18n

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.

Theming

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.

TypeScript

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';

License

MIT © Baidu Keyue Team

Keywords

react

FAQs

Package last updated on 09 May 2026

Did you know?

Socket

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.

Install

Related posts