@vox-ai/react
v1.2.0
Published
vox.ai React Library
Downloads
759
Readme
@vox-ai/react
vox.ai voice agent를 React 앱에서 사용하기 위한 hook 라이브러리.
설치
npm install @vox-ai/react
# or
yarn add @vox-ai/react
# or
pnpm add @vox-ai/react빠른 시작
import { useConversation } from "@vox-ai/react";
export function VoiceWidget() {
const conversation = useConversation({
onConnect: () => console.log("연결됨"),
onDisconnect: () => console.log("연결 종료"),
onStatusChange: (status) => console.log("status:", status),
onAgentStateChange: (agentState) => console.log("agentState:", agentState),
onMessage: (message) => console.log(`${message.source}: ${message.text}`),
onError: (error) => console.error("error:", error.message),
});
const start = async () => {
// 마이크 권한 요청 (UI에서 사전 안내 권장)
await navigator.mediaDevices.getUserMedia({ audio: true });
const conversationId = await conversation.startSession({
agentId: "YOUR_AGENT_ID",
apiKey: "YOUR_API_KEY",
});
console.log("session started:", conversationId);
};
return (
<div>
<button onClick={start} disabled={conversation.status !== "disconnected"}>
Start
</button>
<button onClick={conversation.endSession}>End</button>
<p>Status: {conversation.status}</p>
<p>Agent State: {conversation.agentState ?? "unknown"}</p>
<p>Speaking: {conversation.isSpeaking ? "Yes" : "No"}</p>
</div>
);
}useConversation(options?)
콜백 (hook 초기화 시 전달)
| 콜백 | 시그니처 | 설명 |
|------|----------|------|
| onConnect | () => void | 연결 성공 |
| onDisconnect | () => void | 연결 종료 |
| onStatusChange | (status: ConversationStatus) => void | Status 변경 ("disconnected" → "connecting" → "connected") |
| onAgentStateChange | (agentState: AgentState) => void | LiveKit lk.agent.state 변경 ("initializing", "idle", "listening", "thinking", "speaking") |
| onMessage | (message: ConversationMessage) => void | 메시지 수신 (user transcription, agent response) |
| onError | (error: Error) => void | 에러 발생 |
Hook 옵션
| 옵션 | 타입 | 설명 |
|------|------|------|
| textOnly | boolean | Text-only session 기본값. true면 microphone/audio 없이 chat mode로 연결 |
React State
| State | 타입 | 설명 |
|-------|------|------|
| status | ConversationStatus | "disconnected" | "connecting" | "connected" |
| agentState | AgentState \| undefined | 에이전트가 발행한 lk.agent.state 값 |
| isSpeaking | boolean | agentState === "speaking" 기반 편의 값 |
| micMuted | boolean | 마이크 음소거 상태 |
| messages | ConversationMessage[] | 현재 세션에서 주고받은 메시지 배열 |
JS SDK의
getStatus(),getAgentState(),getMicMuted()에 대응. React에서는 state로 제공되므로 자동 re-render.
메서드
세션 제어
// 세션 시작 — conversationId를 반환
const conversationId = await conversation.startSession({
agentId: "YOUR_AGENT_ID",
apiKey: "YOUR_API_KEY",
});
// 세션 종료
await conversation.endSession();
// 세션 ID 조회
const id = conversation.getId();
// Agent state 조회
const agentState = conversation.getAgentState();
// 현재 세션 메시지 조회
const messages = conversation.getMessages();startSession 옵션
| 옵션 | 타입 | 필수 | 설명 |
|------|------|------|------|
| agentId | string | O | Agent ID |
| apiKey | string | O | API key |
| agentVersion | string | | Agent version ("current", "production", "v1" 등, default: "current") |
| textOnly | boolean | | Hook 기본값을 override하는 per-session text-only 설정 |
| dynamicVariables | Record<string, string \| number \| boolean> | | Agent prompt에 주입할 dynamic variables |
| metadata | Record<string, unknown> | | Call metadata (webhook, call log에 포함) |
| visitorId | string | | 같은 브라우저 방문자를 하나의 customer로 재사용할 안정적인 ID. 생략하면 자동 생성 |
visitorId는 @vox-ai/client 0.2.1 이상에서 지원합니다.
vox.ai 내부 Customer UUID를 입력하는 필드가 아닙니다. 에이전트의 Memory가 켜져
있으면 첫 응답 전에 해당 Customer와 에이전트 범위의 Memory를 자동으로 불러옵니다.
메시지 전송
// 텍스트 메시지 전송 (음성 대신 텍스트 입력)
await conversation.sendUserMessage("안녕하세요");메시지 히스토리
conversation.messages.forEach((message) => {
console.log(message.source, message.text, message.isFinal);
});
const snapshot = conversation.getMessages();messages는 React state라서 메시지 갱신 시 자동 re-rendergetMessages()는 현재 시점의 메시지 배열 snapshot 반환
마이크 제어
// 음소거
await conversation.setMicMuted(true);
// 음소거 해제
await conversation.setMicMuted(false);
// 현재 상태는 conversation.micMuted 로 확인볼륨 제어
// Agent 음성 볼륨 설정 (0.0 ~ 1.0)
conversation.setVolume({ volume: 0.5 });오디오 모니터링
// 입출력 볼륨 (0.0 ~ 1.0)
const inputVol = conversation.getInputVolume();
const outputVol = conversation.getOutputVolume();
// Frequency data (Uint8Array, 시각화용)
const inputFreq = conversation.getInputByteFrequencyData();
const outputFreq = conversation.getOutputByteFrequencyData();디바이스 전환
// 입력 디바이스 변경
await conversation.changeInputDevice({ inputDeviceId: "device-id" });
// 출력 디바이스 변경
await conversation.changeOutputDevice({ outputDeviceId: "device-id" });디바이스 목록은 navigator.mediaDevices.enumerateDevices()로 조회.
Dynamic Variables / Metadata
const conversationId = await conversation.startSession({
agentId: "YOUR_AGENT_ID",
apiKey: "YOUR_API_KEY",
agentVersion: "production",
dynamicVariables: {
userName: "홍길동",
userType: "premium",
accountBalance: 50000,
},
metadata: {
sessionId: "sess_abc123",
source: "mobile-app",
},
});dynamicVariables— Agent prompt에서{{userName}}형식으로 참조metadata— Outbound webhook과 call log에 포함
Text Only
const conversation = useConversation({
textOnly: true,
});
await conversation.startSession({
agentId: "YOUR_AGENT_ID",
apiKey: "YOUR_API_KEY",
});
await conversation.sendUserMessage("텍스트로만 테스트할게요");- text-only session은 microphone 권한을 요청하지 않음
- 에이전트 응답은 LiveKit text stream으로 수신됨
- audio 전용 API는 안전한 no-op 또는 zero-value를 반환
Export 타입
import type {
AgentState,
ConversationMessage,
ConversationSource,
ConversationStatus,
InputDeviceConfig,
OutputDeviceConfig,
SetVolumeParams,
StartConversationOptions,
UseConversationOptions,
} from "@vox-ai/react";JS SDK와의 관계
| JS SDK (@vox-ai/client) | React SDK (@vox-ai/react) |
|---------------------------|----------------------------|
| Conversation.startSession(opts) | conversation.startSession(opts) |
| getMessages() | messages / getMessages() |
| getStatus() | status (React state) |
| getAgentState() | agentState (React state) |
| getMicMuted() | micMuted (React state) |
| 나머지 method/callback | 동일 |
참고
- 인증은
apiKey직접 전달 방식 - 내부 연결은 LiveKit WebRTC 기반
- 브라우저별 audio device 제약이 있을 수 있음
조직 API 키 보안
apiKey는 조직 범위 secret입니다. 신뢰할 수 없는 공개 페이지에는 SDK 대신 공개 widget ID를 사용하는 Widget을 사용하세요.- 앱이나 번들에 포함된 키는 추출될 수 있습니다. 회수 가능한 전용 키를 사용하고, 노출이 확인되면 즉시 로테이션하세요.
