npm package: @nileshnilutudu/chatbot-sdk
Description: Universal SDK for Murmu AI Chatbot - Works with Web and React Native
Author: nileshnilutudu
Latest version: 1.0.3

# @nileshnilutudu/chatbot-sdk

Universal SDK for Murmu AI Chatbot - Works seamlessly with **Web** and **React Native** applications.

## Features

- 🌐 **Universal**: Works with Web (React, Vue, Angular, etc.) and React Native
- 📝 **TypeScript**: Full TypeScript support with type definitions
- 🚀 **Simple API**: Easy-to-use client with intuitive methods
- 📤 **File Upload**: Train your chatbot with PDF documents
- 💬 **Chat Interface**: Send questions and get AI-powered responses
- ⚡ **Lightweight**: Minimal dependencies
- 🔄 **Promise-based**: Modern async/await API

## Installation

```bash
npm install @nileshnilutudu/chatbot-sdk
```

or

```bash
yarn add @nileshnilutudu/chatbot-sdk
```

## Quick Start

### Web (React, Vue, Angular, etc.)

```typescript
import { createClient } from '@nileshnilutudu/chatbot-sdk';

// Create client instance
const client = createClient({
  baseUrl: 'http://localhost:3000'
});

// Upload and train with a PDF
const fileInput = document.querySelector('input[type="file"]');
const file = fileInput.files[0];

const trainResponse = await client.train({
  file: file,
  tenantId: 1
});
console.log('Trained successfully:', trainResponse);

// Ask a question
const chatResponse = await client.chat({
  tenantId: 1,
  sessionId: 1,
  question: 'What are your operating hours?'
});
console.log('Answer:', chatResponse.answer);
console.log('Sources:', chatResponse.sources);
```

### React Native

```typescript
import { createClient } from '@nileshnilutudu/chatbot-sdk';
import DocumentPicker from 'react-native-document-picker';

// Create client instance
const client = createClient({
  baseUrl: 'http://your-backend-url.com'
});

// Pick and upload a PDF
const pickAndUpload = async () => {
  try {
    const result = await DocumentPicker.getDocumentAsync({
      type: 'application/pdf'
    });
    
    if (result.type === 'success') {
      const trainResponse = await client.train({
        file: {
          uri: result.uri,
          type: 'application/pdf',
          name: result.name
        },
        tenantId: 1
      });
      console.log('Trained successfully:', trainResponse);
    }
  } catch (err) {
    console.error('Error:', err);
  }
};

// Ask a question
const askQuestion = async (question: string) => {
  const response = await client.chat({
    tenantId: 1,
    sessionId: 1,
    question: question
  });
  return response.answer;
};
```

## API Reference

### `createClient(config)`

Creates a new ChatbotClient instance.

**Parameters:**
- `config.baseUrl` (string, required): Backend API base URL
- `config.timeout` (number, optional): Request timeout in milliseconds (default: 30000)
- `config.headers` (object, optional): Additional headers to include in requests

**Returns:** `ChatbotClient` instance

```typescript
const client = createClient({
  baseUrl: 'https://api.example.com',
  timeout: 60000,
  headers: {
    'Authorization': 'Bearer token123'
  }
});
```

### `client.train(request)`

Upload and train the chatbot with a PDF document.

**Parameters:**
- `request.file` (File | RNFile): PDF file to upload
  - Web: Standard `File` object from input element
  - React Native: Object with `{ uri, type, name }`
- `request.tenantId` (number): Tenant identifier

**Returns:** Promise<TrainResponse>

```typescript
// Web
const response = await client.train({
  file: file, // File object
  tenantId: 1
});

// React Native
const response = await client.train({
  file: {
    uri: 'file:///path/to/file.pdf',
    type: 'application/pdf',
    name: 'document.pdf'
  },
  tenantId: 1
});
```

**Response:**
```typescript
{
  success: boolean;
  mode: 'mock' | 'production';
  chunksProcessed?: number;
}
```

### `client.chat(request)`

Send a chat message and get AI response.

**Parameters:**
- `request.tenantId` (number): Tenant identifier
- `request.sessionId` (number): Chat session identifier
- `request.question` (string): User's question

**Returns:** Promise<ChatResponse>

```typescript
const response = await client.chat({
  tenantId: 1,
  sessionId: 1,
  question: 'What services do you offer?'
});
```

**Response:**
```typescript
{
  answer: string;              // AI-generated answer
  sources: ChatSource[];       // Relevant source chunks
  mode: 'mock' | 'production';
}
```

### `client.updateConfig(config)`

Update SDK configuration after initialization.

```typescript
client.updateConfig({
  timeout: 45000,
  headers: { 'X-Custom-Header': 'value' }
});
```

### `client.getConfig()`

Get current SDK configuration.

```typescript
const config = client.getConfig();
console.log('Current baseUrl:', config.baseUrl);
```

## Complete Examples

All examples are available in the `examples/` directory:
- **react-example.tsx** - Full-featured React component (TypeScript)
- **react-example-js.jsx** - React component (JavaScript)
- **react-native-example.tsx** - React Native mobile app
- **web-example.html** - Vanilla JavaScript (no framework)

See [examples/README.md](./examples/README.md) for detailed usage instructions.

### React Web App (TypeScript)

```typescript
import React, { useState } from 'react';
import { createClient, ChatResponse } from '@nileshnilutudu/chatbot-sdk';

const client = createClient({ baseUrl: 'http://localhost:3000' });

function ChatbotApp() {
  const [question, setQuestion] = useState('');
  const [response, setResponse] = useState<ChatResponse | null>(null);
  const [loading, setLoading] = useState(false);

  const handleFileUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (!file) return;

    setLoading(true);
    try {
      const result = await client.train({ file, tenantId: 1 });
      alert('PDF uploaded successfully!');
    } catch (error) {
      alert('Error uploading PDF: ' + error.message);
    } finally {
      setLoading(false);
    }
  };

  const handleAskQuestion = async () => {
    if (!question.trim()) return;

    setLoading(true);
    try {
      const result = await client.chat({
        tenantId: 1,
        sessionId: 1,
        question
      });
      setResponse(result);
    } catch (error) {
      alert('Error: ' + error.message);
    } finally {
      setLoading(false);
    }
  };

  return (
    <div>
      <h1>AI Chatbot</h1>
      
      <div>
        <h2>Upload PDF</h2>
        <input type="file" accept=".pdf" onChange={handleFileUpload} />
      </div>

      <div>
        <h2>Ask a Question</h2>
        <input
          type="text"
          value={question}
          onChange={(e) => setQuestion(e.target.value)}
          placeholder="Enter your question..."
        />
        <button onClick={handleAskQuestion} disabled={loading}>
          {loading ? 'Loading...' : 'Ask'}
        </button>
      </div>

      {response && (
        <div>
          <h3>Answer:</h3>
          <p>{response.answer}</p>
          <h4>Sources:</h4>
          {response.sources.map((source, i) => (
            <div key={i}>
              <p>Score: {source.score.toFixed(3)}</p>
              <p>{source.metadata.text.substring(0, 200)}...</p>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

export default ChatbotApp;
```

### React Native App

```typescript
import React, { useState } from 'react';
import { View, Text, TextInput, Button, ScrollView } from 'react-native';
import DocumentPicker from 'react-native-document-picker';
import { createClient, ChatResponse } from '@nileshnilutudu/chatbot-sdk';

const client = createClient({ baseUrl: 'https://your-api.com' });

export default function ChatbotScreen() {
  const [question, setQuestion] = useState('');
  const [response, setResponse] = useState<ChatResponse | null>(null);
  const [loading, setLoading] = useState(false);

  const uploadPDF = async () => {
    try {
      const result = await DocumentPicker.getDocumentAsync({
        type: 'application/pdf'
      });
      
      if (result.type === 'success') {
        setLoading(true);
        await client.train({
          file: {
            uri: result.uri,
            type: 'application/pdf',
            name: result.name
          },
          tenantId: 1
        });
        alert('PDF uploaded successfully!');
      }
    } catch (error) {
      alert('Error: ' + error.message);
    } finally {
      setLoading(false);
    }
  };

  const askQuestion = async () => {
    if (!question.trim()) return;

    setLoading(true);
    try {
      const result = await client.chat({
        tenantId: 1,
        sessionId: 1,
        question
      });
      setResponse(result);
    } catch (error) {
      alert('Error: ' + error.message);
    } finally {
      setLoading(false);
    }
  };

  return (
    <ScrollView style={{ padding: 20 }}>
      <Text style={{ fontSize: 24, fontWeight: 'bold' }}>AI Chatbot</Text>
      
      <Button title="Upload PDF" onPress={uploadPDF} />
      
      <TextInput
        style={{ borderWidth: 1, padding: 10, marginVertical: 10 }}
        value={question}
        onChangeText={setQuestion}
        placeholder="Enter your question..."
      />
      
      <Button
        title={loading ? 'Loading...' : 'Ask Question'}
        onPress={askQuestion}
        disabled={loading}
      />

      {response && (
        <View style={{ marginTop: 20 }}>
          <Text style={{ fontWeight: 'bold' }}>Answer:</Text>
          <Text>{response.answer}</Text>
          
          <Text style={{ fontWeight: 'bold', marginTop: 10 }}>Sources:</Text>
          {response.sources.map((source, i) => (
            <View key={i} style={{ marginTop: 5 }}>
              <Text>Score: {source.score.toFixed(3)}</Text>
              <Text>{source.metadata.text.substring(0, 150)}...</Text>
            </View>
          ))}
        </View>
      )}
    </ScrollView>
  );
}
```

## TypeScript Support

The SDK is written in TypeScript and provides full type definitions:

```typescript
import {
  ChatbotClient,
  createClient,
  ChatbotConfig,
  ChatRequest,
  ChatResponse,
  TrainRequest,
  TrainResponse,
  ChatSource,
  ApiError
} from '@nileshnilutudu/chatbot-sdk';
```

## Error Handling

The SDK throws errors for failed requests. Always wrap calls in try-catch:

```typescript
try {
  const response = await client.chat({
    tenantId: 1,
    sessionId: 1,
    question: 'Hello?'
  });
} catch (error) {
  console.error('Failed to get response:', error.message);
  // Handle error appropriately
}
```

## Configuration

### Custom Headers

Add authentication or custom headers:

```typescript
const client = createClient({
  baseUrl: 'https://api.example.com',
  headers: {
    'Authorization': 'Bearer your-token',
    'X-Custom-Header': 'value'
  }
});
```

### Timeout

Set custom timeout (default is 30 seconds):

```typescript
const client = createClient({
  baseUrl: 'https://api.example.com',
  timeout: 60000 // 60 seconds
});
```

## License

MIT

## Support

For issues and questions, please open an issue on GitHub.