npm package: @phonely-ai/web
Description: Phonely Web SDK for AI voice calls
Author: phonely-ai
Latest version: 0.0.7

# @phonely-ai/web

A professional SDK for integrating Phonely's AI voice call capabilities into web applications. Built on top of Daily.js, this SDK provides a simple and robust interface for managing AI voice calls.

## Installation

```bash
npm install @phonely-ai/web
```

## Quick Start

```typescript
import PhonelySDK, {PhonelyEvent} from '@phonely-ai/web';

// Initialize the SDK
const phonely = new PhonelySDK();

// Start a call
const callId = await phonely.call({
    agentId: 'your_agent_id'
});

// Listen for events
phonely.on(PhonelyEvent.CALL_JOINED, () => {
    console.log('Call joined successfully');
});

// End the call
await phonely.endCall();
```

## React Hook Example

```typescript
import { PhonelySDK, PhonelyEvent } from '@phonely-ai/web';

function usePhonely(agentId: string) {
  const [isCalling, setIsCalling] = useState(false);
  const phonelyRef = useRef<PhonelySDK | null>(null);

  useEffect(() => {
    // Initialize SDK
    phonelyRef.current = new PhonelySDK();

    // Set up event listeners
    phonelyRef.current.on(PhonelyEvent.CALL_JOINED, () => {
      setIsCalling(true);
    });

    return () => {
      if (phonelyRef.current) {
        phonelyRef.current.endCall().catch(console.error);
      }
    };
  }, []);

  const startCall = async () => {
    try {
      await phonelyRef.current?.call({ agentId });
    } catch (error) {
      console.error('Call failed:', error);
    }
  };

  const endCall = async () => {
    try {
      await phonelyRef.current?.endCall();
      setIsCalling(false);
    } catch (error) {
      console.error('End call failed:', error);
    }
  };

  return { isCalling, startCall, endCall };
}
```

## Live Transcript

```typescript
// Enable transcript in config
const phonely = new PhonelySDK({
  transcript: {
    enabled: true,
    autoStart: true,  // Starts automatically when call joins
    pollingInterval: 2000,  // Poll every 2 seconds
    includeRoles: ['user', 'assistant']  // Filter by roles
  }
});

// Listen for transcript messages
phonely.on(PhonelyEvent.TRANSCRIPT_MESSAGE, (event) => {
  const { message, allMessages } = event;
  console.log('New message:', message.content);
  console.log('All messages:', allMessages);
});

// Manual control
phonely.startTranscript();  // Start transcript
phonely.stopTranscript();   // Stop transcript
const messages = phonely.getTranscript();  // Get all messages
```

## API Reference

### PhonelySDK Configuration

```typescript
interface PhonelyConfig {
  apiKey?: string;  // Optional for now
  voiceApiBaseUrl?: string;
  apiBaseUrl?: string;
  dailyConfig?: {
    avoidEval?: boolean;
    alwaysIncludeMicInPermissionPrompt?: boolean;
  };
  dailyCallObject?: {
    audioSource?: boolean | MediaStreamTrack;
    videoSource?: boolean | MediaStreamTrack;
    startAudioOff?: boolean;
  };
  transcript?: {
    enabled?: boolean;  // Enable transcript functionality
    autoStart?: boolean;  // Auto-start when call joins (default: true)
    pollingInterval?: number;  // Polling interval in ms (default: 2000)
    maxRetries?: number;  // Max retry attempts (default: 5)
    includeRoles?: string[];  // Filter by roles (default: ['user', 'assistant'])
  };
}
```

### Methods

#### `call(options: CallOptions): Promise<string>`
Initiates a call with an AI assistant.
- `options.agentId`: ID of the agent to call
- `options.metadata?`: Additional metadata for the call
- Returns: Promise resolving to the call ID

### Runtime Variables (Web SDK)

If your workflow uses **Runtime Variables**, you must pass values at call start using `metadata.callOverrides.liveVariables`.

How it works:
- In the workflow editor, create a Runtime Variable and copy its **Runtime Variable ID**.
- Pass that ID as `uuid` in `liveVariables`.
- The `value` is the runtime value you want to inject for this call.

Example:

```typescript
await phonely.call({
  agentId: 'nPhns6zaVgCyMZQ8i9ke',
  metadata: {
    callOverrides: {
      liveVariables: [
        {
          uuid: '7fc58831-f651-4084-ab5e-70c7c695d8ca', // Runtime Variable ID from workflow editor
          value: 'You are testing the runtime variable now',
        },
      ],
    },
  },
});
```

Notes:
- `uuid` must match the Runtime Variable ID exactly.
- This is currently supported for Web SDK calls.

#### `endCall(): Promise<void>`
Ends the current call.

#### `setAudioEnabled(enabled: boolean): Promise<void>`
Enables or disables the local audio.

#### `getParticipants(): Participant[]`
Gets all participants in the call.

#### `sendMessage(content: string): Promise<void>`
Sends a message to the call.

#### `startTranscript(): void`
Starts live transcript polling.

#### `stopTranscript(): void`
Stops live transcript polling.

#### `getTranscript(): TranscriptMessage[]`
Gets all transcript messages.

#### `isTranscriptActive(): boolean`
Checks if transcript is currently active.

### Events

```typescript
enum PhonelyEvent {
  CALL_JOINED = 'call-joined',
  CALL_LEFT = 'call-left',
  PARTICIPANT_JOINED = 'participant-joined',
  PARTICIPANT_LEFT = 'participant-left',
  PARTICIPANT_UPDATED = 'participant-updated',
  MESSAGE = 'message',
  VOLUME_LEVEL = 'volume-level',
  SPEECH_START = 'speech-start',
  SPEECH_END = 'speech-end',
  CALL_START_PROGRESS = 'call-start-progress',
  TRANSCRIPT_STARTED = 'transcript-started',
  TRANSCRIPT_STOPPED = 'transcript-stopped',
  TRANSCRIPT_MESSAGE = 'transcript-message',
  TRANSCRIPT_ERROR = 'transcript-error',
  ERROR = 'error'
}
```

## License

MIT