npm package: @omnia-voice/sdk
Description: Omnia Voice SDK - Build voice AI experiences with ease
Author: Omnia
Latest version: 0.2.3

# @omnia/voice-sdk

Build voice AI experiences with ease. The Omnia Voice SDK provides a simple way to integrate voice AI agents into your web and mobile applications.

## Features

- 🎙️ **Real-time voice conversations** with AI agents
- 🔊 **High-quality audio** via WebRTC
- 📝 **Live transcription** of conversations
- ⚛️ **React hooks** for easy integration
- 📱 **Works on web and mobile**
- 🔒 **Secure** - API key authentication

## Installation

```bash
npm install @omnia/voice-sdk
# or
yarn add @omnia/voice-sdk
# or
pnpm add @omnia/voice-sdk
```

## Quick Start

### Vanilla JavaScript/TypeScript

```typescript
import { OmniaVoice } from '@omnia/voice-sdk';

// Create client
const voice = new OmniaVoice({
  apiKey: 'your-api-key',
});

// Listen for events
voice.on('transcriptUpdated', (entry) => {
  console.log(`${entry.role}: ${entry.text}`);
});

voice.on('agentStateChanged', (state) => {
  console.log(`Agent is now: ${state}`);
});

// Connect to an agent
await voice.connect({ agentId: 'agent-123' });

// ... conversation happens automatically ...

// Disconnect when done
await voice.disconnect();
```

### React

```tsx
import {
  OmniaVoiceProvider,
  useOmniaVoice,
} from '@omnia/voice-sdk/react';

// Wrap your app with the provider
function App() {
  return (
    <OmniaVoiceProvider config={{ apiKey: 'your-api-key' }}>
      <VoiceChat />
    </OmniaVoiceProvider>
  );
}

// Use the hook in your components
function VoiceChat() {
  const {
    connect,
    disconnect,
    isConnected,
    agentState,
    transcript,
  } = useOmniaVoice();

  return (
    <div>
      <p>Agent: {agentState}</p>

      <button
        onClick={() =>
          isConnected ? disconnect() : connect({ agentId: 'agent-123' })
        }
      >
        {isConnected ? 'End Call' : 'Start Call'}
      </button>

      <div>
        {transcript.map((entry) => (
          <p key={entry.id}>
            <strong>{entry.role}:</strong> {entry.text}
          </p>
        ))}
      </div>
    </div>
  );
}
```

## API Reference

### OmniaVoice

The main client class.

```typescript
const voice = new OmniaVoice(config);
```

#### Config Options

| Option | Type | Required | Description |
|--------|------|----------|-------------|
| `apiKey` | string | Yes | Your Omnia API key |
| `baseUrl` | string | No | API base URL (default: https://api.play-omnia.com) |
| `debug` | boolean | No | Enable debug logging |

#### Methods

| Method | Description |
|--------|-------------|
| `connect(options)` | Connect to a voice agent |
| `disconnect()` | Disconnect from the call |
| `setMicrophoneEnabled(enabled)` | Enable/disable microphone |
| `sendMessage(text)` | Send a text message to the agent |
| `on(event, callback)` | Add event listener |
| `off(event, callback)` | Remove event listener |

#### Properties

| Property | Type | Description |
|----------|------|-------------|
| `connectionState` | ConnectionState | Current connection state |
| `agentState` | AgentState | Current agent state |
| `isMicrophoneEnabled` | boolean | Whether microphone is enabled |
| `transcript` | TranscriptEntry[] | Conversation transcript |
| `duration` | number | Call duration in ms |

#### Events

| Event | Payload | Description |
|-------|---------|-------------|
| `connectionStateChanged` | ConnectionState | Connection state changed |
| `agentStateChanged` | AgentState | Agent state changed |
| `transcriptUpdated` | TranscriptEntry | New transcript entry |
| `callStarted` | ConnectionDetails | Call started |
| `callEnded` | number | Call ended (duration in ms) |
| `error` | Error | Error occurred |

### Connect Options

```typescript
interface ConnectOptions {
  // Use a pre-configured agent from your dashboard
  agentId?: string;

  // Or provide raw configuration
  config?: {
    systemPrompt?: string;
    greeting?: string;
    voice?: string;
    language?: string;
    temperature?: number;
    recordingEnabled?: boolean;
  };

  // Override specific agent settings
  overrides?: {
    greeting?: string;
    // ... any config field
  };

  // Custom metadata
  metadata?: Record<string, any>;
}
```

### React Hooks

#### useOmniaVoice

Main hook for voice functionality.

```typescript
const {
  // State
  connectionState,
  agentState,
  isMicrophoneEnabled,
  transcript,
  duration,
  isConnected,
  isConnecting,

  // Actions
  connect,
  disconnect,
  setMicrophoneEnabled,
  sendMessage,
} = useOmniaVoice();
```

#### useVoiceCall

Simplified hook for call management.

```typescript
const {
  startCall,
  endCall,
  toggleCall,
  isLoading,
  error,
  isConnected,
} = useVoiceCall({ agentId: 'agent-123' });
```

#### useMicrophone

Hook for microphone control.

```typescript
const {
  isMuted,
  isEnabled,
  toggle,
  mute,
  unmute,
} = useMicrophone();
```

#### useTranscript

Get the conversation transcript.

```typescript
const transcript = useTranscript();
```

#### useFormattedDuration

Get the call duration as mm:ss.

```typescript
const duration = useFormattedDuration(); // "02:30"
```

## Types

### ConnectionState

```typescript
type ConnectionState =
  | 'disconnected'
  | 'connecting'
  | 'connected'
  | 'reconnecting'
  | 'failed'
```

### AgentState

```typescript
type AgentState =
  | 'idle'
  | 'listening'
  | 'thinking'
  | 'speaking'
```

### TranscriptEntry

```typescript
interface TranscriptEntry {
  id: string;
  role: 'user' | 'agent';
  text: string;
  isFinal: boolean;
  timestamp: number;
}
```

## Examples

### Basic Voice Chat

```tsx
import { OmniaVoiceProvider, useOmniaVoice } from '@omnia/voice-sdk/react';

function VoiceChat() {
  const { connect, disconnect, isConnected, transcript, agentState } = useOmniaVoice();

  return (
    <div className="voice-chat">
      <div className="status">
        Agent: <span className={agentState}>{agentState}</span>
      </div>

      <div className="transcript">
        {transcript.map((entry) => (
          <div key={entry.id} className={`message ${entry.role}`}>
            {entry.text}
          </div>
        ))}
      </div>

      <button
        onClick={() => isConnected ? disconnect() : connect({ agentId: 'my-agent' })}
        className={isConnected ? 'end-call' : 'start-call'}
      >
        {isConnected ? '🔴 End Call' : '🟢 Start Call'}
      </button>
    </div>
  );
}
```

### With Microphone Control

```tsx
function VoiceChatWithMic() {
  const { connect, disconnect, isConnected } = useOmniaVoice();
  const { isMuted, toggle } = useMicrophone();

  return (
    <div>
      <button onClick={() => isConnected ? disconnect() : connect({ agentId: 'my-agent' })}>
        {isConnected ? 'End' : 'Start'}
      </button>

      {isConnected && (
        <button onClick={toggle}>
          {isMuted ? '🔇 Unmute' : '🔊 Mute'}
        </button>
      )}
    </div>
  );
}
```

### Dynamic Configuration

```tsx
function DynamicAgent() {
  const { connect } = useOmniaVoice();

  const startCustomAgent = () => {
    connect({
      config: {
        systemPrompt: 'You are a friendly sales assistant for our shoe store.',
        greeting: 'Welcome to ShoeWorld! What kind of shoes are you looking for today?',
        voice: 'Sarah',
        language: 'en',
      },
    });
  };

  return <button onClick={startCustomAgent}>Talk to Sales</button>;
}
```

## License

MIT