Skip to main content

Quick Start

Build a complete Digital Employee interactive interface in 5 minutes.

Minimal Example

import {PilotKit, ControlPanel} from '@bdky/aaas-pilot-kit-react-widget';
import '@bdky/aaas-pilot-kit-react-widget/styles.css';

function App() {
return (
<div style={{width: '100vw', height: '100vh'}}>
<PilotKit
token="your-token"
figureId="your-figure-id"
ttsPer="your-tts-per"
agentConfig={{
robotId: 'your-robot-id'
}}
>
<ControlPanel />
</PilotKit>
</div>
);
}

This minimal example will:

  • Render Digital Human image
  • Display voice/text input control panel
  • Automatically handle ASR, TTS, conversation flow

Complete Example

Here is a complete example containing all commonly used components:

import {useState, useRef} from 'react';
import {
PilotKit,
ConversationList,
Subtitle,
ControlPanel,
RecommendedQuestions,
StartupScreen,
LoadingOverlay,
StatusOverlay,
Layout,
FillAdapter,
useIsMobile,
type IPilotKitRef
} from '@bdky/aaas-pilot-kit-react-widget';
import '@bdky/aaas-pilot-kit-react-widget/styles.css';

function App() {
const [showStartup, setShowStartup] = useState(false);
const [showLoading, setShowLoading] = useState(true);
const [showBusy, setShowBusy] = useState(false);
const [showConversationList, setShowConversationList] = useState(false);

const isMobile = useIsMobile();
const pilotKitRef = useRef<IPilotKitRef>(null);

// Busy state
if (showBusy) {
return (
<StatusOverlay
show
message="Sorry, I'm busy right now, please try again later"
buttonText="Redial"
avatar={<img src="/avatar.jpg" alt="" />}
onButtonClick={() => {
setShowBusy(false);
setShowLoading(true);
}}
/>
);
}

return (
<div style={{width: '100vw', height: '100vh'}}>
<PilotKit
ref={pilotKitRef}
token="your-token"
figureId="your-figure-id"
ttsPer="your-tts-per"
agentConfig={{robotId: 'your-robot-id'}}
prologue="Hello, I'm a Digital Employee, how can I help you today?"
interruptible
onReady={() => setShowLoading(false)}
onNeedManualActivation={() => {
setShowLoading(false);
setShowStartup(true);
}}
onBusy={() => setShowBusy(true)}
>
<Layout direction="vertical" hCenter>
<FillAdapter />

{/* Conversation list */}
{showConversationList && (
<ConversationList
onClose={() => setShowConversationList(false)}
/>
)}

{/* Recommended questions */}
<RecommendedQuestions
questions={['Introduce yourself', 'What can you do?']}
onQuestionClick={q => pilotKitRef.current?.input(q)}
style={{marginBottom: 10}}
/>

{/* Subtitle (display on PC) */}
{!isMobile && !showConversationList && (
<Subtitle
showSpeaker
expandable
onExpand={() => setShowConversationList(true)}
style={{marginBottom: 10}}
/>
)}

{/* Control panel */}
<ControlPanel style={{marginBottom: 30}} />
</Layout>

{/* iOS manual activation page */}
<StartupScreen
show={showStartup}
title="Start Conversation"
buttonText="Activate"
avatar={<img src="/avatar.jpg" alt="" />}
hintText="For better recognition results, please experience in a quiet environment"
onReady={() => setShowStartup(false)}
/>

{/* Loading */}
<LoadingOverlay
show={showLoading}
description="Connecting..."
avatar={<img src="/avatar.jpg" alt="" />}
/>
</PilotKit>
</div>
);
}

Code Analysis

1. PilotKit Core Container

PilotKit is the core of the entire application, it:

  • Built-in AaaSPilotKitProvider, no need to manually wrap
  • Automatically mounts Digital Human rendering
  • Provides ref to access controller methods
<PilotKit
ref={pilotKitRef}
token="xxx" // Authentication token
figureId="xxx" // Digital Human image ID
ttsPer="xxx" // TTS voice
agentConfig={{...}} // Agent configuration
prologue="..." // Opening remarks
onReady={() => {...}} // Ready callback
>
{/* Child components */}
</PilotKit>

2. Layout

Use Layout + FillAdapter to achieve flexible layout:

<Layout direction="vertical" hCenter>
<FillAdapter /> {/* Occupy remaining space */}
<ConversationList /> {/* Conversation list */}
<ControlPanel /> {/* Control panel */}
</Layout>

3. Overlay Components

Overlay components are used to display different states:

  • StartupScreen: iOS iframe scenarios require user manual activation
  • LoadingOverlay: Loading state
  • StatusOverlay: Busy, timeout, and other states

4. Responsive Adaptation

Use useIsMobile() Hook to detect device type:

const isMobile = useIsMobile();

// Mobile doesn't show subtitle, directly show conversation list
{!isMobile && <Subtitle />}

Next Steps