Skip to main content

快速开始

为 React 应用提供的 AaaS Pilot Kit 封装库,包含 Provider、上下文和常用 hooks。

安装

统一使用公网包 @bdky/aaas-pilot-kit-react

npm

$ npm install @bdky/aaas-pilot-kit-react

yarn

$ yarn add @bdky/aaas-pilot-kit-react
依赖说明

核心能力依赖 @bdky/aaas-pilot-kit,请参考 Vanilla SDK 配置选项 了解完整配置项 IOptions

快速开始

基本使用

import {
AaaSPilotKitProvider,
useAaaSPilotKit,
useAaaSPilotKitEvents,
useConversationList
} from '@bdky/aaas-pilot-kit-react';
import {type IOptions} from '@bdky/aaas-pilot-kit';

const options: IOptions = {
token: 'your-auth-token-here',
figureId: '209337',
ttsPer: 'LITE_audiobook_female_1',
// agentConfig: 若未提供自定义 agentService,此配置必填
agentConfig: {
token: 'xxxx',
robotId: 'xxxx'
}
};

function App() {
return (
<AaaSPilotKitProvider options={options}>
<Dashboard />
</AaaSPilotKitProvider>
);
}

function Dashboard() {
const {controller, isReady, isMuted, isRendering} = useAaaSPilotKit();
const {conversationList} = useConversationList();

useAaaSPilotKitEvents({
onReady: () => console.log('AI 助手已就绪'),
onAsrMessage: payload => console.log('ASR:', payload.text)
});

return (
<section>
<div>状态:{isReady ? '就绪' : '初始化中'}</div>
<div>静音:{isMuted ? '是' : '否'}</div>
<div>渲染:{isRendering ? '进行中' : '空闲'}</div>
<div>对话数:{conversationList.length}</div>
<button onClick={() => controller?.input('你好')}>发送消息</button>
</section>
);
}

完整示例

import {useRef, useEffect} from 'react';
import {
AaaSPilotKitProvider,
useAaaSPilotKit,
useAaaSPilotKitEvents,
useConversationList,
useConversation
} from '@bdky/aaas-pilot-kit-react';

// 配置选项
const options = {
token: 'your-auth-token-here',
figureId: '209337',
ttsPer: 'LITE_audiobook_female_1',
// agentConfig: 若未提供自定义 agentService,此配置必填
agentConfig: {
token: 'your-token',
robotId: 'your-robot-id'
},
// 其他配置...
};

function App() {
return (
<AaaSPilotKitProvider options={options}>
<div className="app">
<AvatarContainer />
<ChatPanel />
<ControlPanel />
</div>
</AaaSPilotKitProvider>
);
}

// 数字人容器
function AvatarContainer() {
const {controller, isReady} = useAaaSPilotKit();
const containerRef = useRef<HTMLDivElement>(null);

useEffect(
() => {
if (controller && containerRef.current) {
controller.mount(containerRef.current);
}
},
[isReady, controller]
);

if (!isReady) {
return (
<div>呼叫中...</div>
);
}

return (
<div
ref={containerRef}
className="avatar-container"
style={{width: '400px', height: '600px'}}
/>
);
}

// 对话面板
function ChatPanel() {
const {conversationList} = useConversationList();

return (
<div className="chat-panel">
<h3>对话记录</h3>
{conversationList.map(conversation => (
<ConversationItem
key={conversation.id}
conversation={conversation}
/>
))}
</div>
);
}

// 单个对话项
function ConversationItem({conversation}) {
const {conversationContents} = useConversation(conversation);

return (
<div className="conversation-item">
<div className="conversation-type">
{conversation.type === 'client' ? '用户' : 'AI助手'}
</div>
<div className="conversation-content">
{conversationContents.map(item => (
<div key={item.uiId} className={`content-item ${item.completed ? 'completed' : 'typing'}`}>
{item.content}
</div>
))}
</div>
</div>
);
}

// 控制面板
function ControlPanel() {
const {controller, isReady, isMuted, isRendering} = useAaaSPilotKit();

useAaaSPilotKitEvents({
onReady: () => console.log('AI 助手已就绪'),
onError: (error) => console.error('错误:', error),
onAsrMessage: (payload) => console.log('语音识别:', payload.text),
onConversationChange: (payload) => console.log('对话更新:', payload)
});

const handleSendMessage = () => {
const message = prompt('请输入消息:');
if (message && controller) {
controller.input(message);
}
};

const handleToggleMute = () => {
if (controller) {
controller.mute(!isMuted);
}
};

const handleInterrupt = () => {
if (controller) {
controller.interrupt('用户手动打断');
}
};

return (
<div className="control-panel">
<div className="status">
<span>状态: {isReady ? '就绪' : '初始化中'}</span>
<span>渲染: {isRendering ? '进行中' : '空闲'}</span>
</div>
<div className="controls">
<button
onClick={handleSendMessage}
disabled={!isReady}
>
发送消息
</button>
<button
onClick={handleToggleMute}
disabled={!isReady}
>
{isMuted ? '取消静音' : '静音'}
</button>
<button
onClick={handleInterrupt}
disabled={!isReady || !isRendering}
>
打断
</button>
</div>
</div>
);
}

export default App;

TypeScript 支持

React SDK 提供完整的 TypeScript 类型支持:

import type {
IAaaSPilotKitProvider,
IAaaSPilotKitProviderProps,
IUseAaaSPilotKitResult,
IUseAaaSPilotKitEventsProps,
IUseConversationResult,
IUseConversationListResult
} from '@bdky/aaas-pilot-kit-react';

// 组件 props 类型定义
interface DashboardProps {
className?: string;
onReady?: () => void;
}

function Dashboard({ className, onReady }: DashboardProps) {
const {controller, isReady}: IUseAaaSPilotKitResult = useAaaSPilotKit();

useAaaSPilotKitEvents({
onReady: onReady
});

// ...
}

与状态管理库集成

与 Redux 集成

import {useDispatch, useSelector} from 'react-redux';
import {updateConversations, setAvatarStatus} from './store/avatarSlice';

function Dashboard() {
const dispatch = useDispatch();
const {isReady} = useAaaSPilotKit();

useAaaSPilotKitEvents({
onReady: () => {
dispatch(setAvatarStatus('ready'));
},
onConversationChange: (payload) => {
dispatch(updateConversations(payload));
}
});

// ...
}

与 Zustand 集成

import {useAvatarStore} from './store/avatarStore';

function Dashboard() {
const setStatus = useAvatarStore(state => state.setStatus);
const addConversation = useAvatarStore(state => state.addConversation);

useAaaSPilotKitEvents({
onReady: () => setStatus('ready'),
onConversationAdd: addConversation
});

// ...
}

下一步