npm package: @sable-ai/react
Description: React hooks and components for Sable AI SDK
Latest version: 0.1.31

# @sable-ai/react

React hooks and components for the Sable AI SDK. This package provides React-specific bindings for the Sable AI platform, making it easy to integrate AI-powered text and voice capabilities into your React applications.

## Features

- **React Context Integration**: Easily manage AI agent state across your application
- **TypeScript Support**: Full TypeScript type definitions included
- **Modular Design**: Pick and choose only the features you need
- **Storybook Documentation**: Interactive component documentation and examples

## Installation

```bash
npm install @sable-ai/react @sable-ai/core @sable-ai/text-agent @sable-ai/voice-agent
# or
yarn add @sable-ai/react @sable-ai/core @sable-ai/text-agent @sable-ai/voice-agent
```

## Quick Start

### 1. Wrap your application with SableProvider

```tsx
import { SableProvider } from '@sable-ai/react';
import { createTextAgent } from '@sable-ai/text-agent';
import { VoiceAgent } from '@sable-ai/voice-agent';

function App() {
  return (
    <SableProvider 
      config={{
        textAgent: createTextAgent({
          apiKey: 'your-api-key',
          // other text agent options
        }),
        voiceAgent: new VoiceAgent({
          // voice agent options
          debug: process.env.NODE_ENV !== 'production',
          // other VoiceAgent options
        })
      }}
    >
      <YourApp />
    </SableProvider>
  );
}
```

### 2. Use hooks in your components

```tsx
import { useTextAgent, useVoiceAgent } from '@sable-ai/react';

function MyComponent() {
  const textAgent = useTextAgent();
  const voiceAgent = useVoiceAgent();
  
  const handleSendMessage = async () => {
    const response = await textAgent.sendMessage('Hello, world!');
    console.log(response);
  };

  return (
    <div>
      <button onClick={handleSendMessage}>
        Send Message
      </button>
    </div>
  );
}
```

## API Reference

### Components

#### `SableProvider`

The root provider component that makes the Sable AI functionality available to your React component tree.

**Props:**
- `config`: (Optional) Object containing configuration for the Sable AI agents
  - `textAgentOptions`: Configuration options for the TextAgent (optional)
  - `voiceAgentOptions`: Configuration options for the VoiceAgent (optional)
  - `debug`: Enable debug logging (optional, default: `false`)
  - `onError`: Callback function that's called when an error occurs during initialization or operation (optional)
  - `onReady`: Callback function that's called when the agents have been successfully initialized and are ready to be used (optional)

**Example:**
```tsx
<SableProvider
  config={{
    textAgentOptions: { 
      /* TextAgent configuration options */
      apiKey: 'your-api-key',
      // other TextAgent options
    },
    voiceAgentOptions: {
      /* VoiceAgent configuration options */
      debug: process.env.NODE_ENV !== 'production',
      // other VoiceAgent options
    },
    debug: process.env.NODE_ENV !== 'production',
    // Optional error handler
    onError: (error) => {
      console.error('Sable AI Error:', error);
      // Handle error (e.g., show error toast)
    },
    // Optional ready handler
    onReady: () => {
      console.log('Sable AI is ready!');
      // Perform actions when agents are ready
    }
  }}
>
  <YourApp />
</SableProvider>
```

### Hooks

#### `useSable()`

Access the Sable context directly. Returns the full context value including both agents, loading state, and error handling.

**Returns:**
```typescript
{
  textAgent: TextAgent | null;
  voiceAgent: VoiceAgent | null;
  isLoading: boolean;
  error: Error | null;
  initialize: (config: SableConfig) => Promise<void>;
  reset: () => void;
}
```

**Example:**
```tsx
const { textAgent, voiceAgent, isLoading, error } = useSable();
```

#### `useTextAgent()`

Hook to access the TextAgent instance. Throws an error if used outside of SableProvider or if TextAgent is not configured.

**Returns:** `TextAgent` instance

**Example:**
```tsx
const textAgent = useTextAgent();
const response = await textAgent.sendMessage('Hello!');
```

#### `useVoiceAgent()`

Hook to access the VoiceAgent instance. Throws an error if used outside of SableProvider or if VoiceAgent is not configured.

**Returns:** `VoiceAgent` instance

**Example:**
```tsx
const voiceAgent = useVoiceAgent();
await voiceAgent.startCall({
  onMessage: (message) => console.log('New message:', message)
});
```

## Development

### Prerequisites

- Node.js 16+
- npm or yarn

### Setup

1. Clone the repository
2. Install dependencies:
   ```bash
   npm install
   # or
   yarn
   ```

### Available Scripts

- `npm run dev` - Start development server with hot reload
- `npm run build` - Build the package for production
- `npm run test` - Run tests
- `npm run lint` - Run ESLint
- `npm run storybook` - Start Storybook for component development
- `npm run build-storybook` - Build Storybook for deployment

### Testing with Storybook

This project uses [Storybook](https://storybook.js.org/) for component development and testing. To get started:

1. Start the Storybook development server:
   ```bash
   npm run storybook
   ```
   This will open Storybook at http://localhost:6006

2. Browse the available component stories in the sidebar
3. Interact with components in the Canvas tab
4. View component documentation in the Docs tab

#### Writing Stories

Stories are located in the `src/stories` directory. Each component should have its own story file that demonstrates its various states and props.

Example story:
```tsx
import React from 'react';
import { Meta, StoryObj } from '@storybook/react';
import { YourComponent } from '../components/YourComponent';

export default {
  title: 'Components/YourComponent',
  component: YourComponent,
  parameters: {
    layout: 'centered',
  },
} as Meta<typeof YourComponent>;

export const Default: StoryObj<typeof YourComponent> = {
  args: {
    // Default props
  },
};

// Additional variants
export const WithCustomProps: StoryObj<typeof YourComponent> = {
  args: {
    // Custom props
  },
};
```

### Best Practices

1. **Component Design**
   - Keep components small and focused on a single responsibility
   - Use TypeScript interfaces for all props
   - Document prop types and component usage with JSDoc

2. **State Management**
   - Use React hooks for local component state
   - Lift state up when multiple components need access to the same data
   - Consider using context for global application state

3. **Performance**
   - Use `React.memo` for expensive components
   - Memoize callbacks with `useCallback`
   - Use `useMemo` for expensive calculations

4. **Testing**
   - Write unit tests for utility functions
   - Use React Testing Library for component tests
   - Add stories for visual testing in Storybook

## Internal Development

For internal development guidelines and contribution process, please refer to the internal documentation.