> ## Documentation Index
> Fetch the complete documentation index at: https://ai-kb.automationanywhere.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Chat SDK

> Intégrez des interfaces de chat conversationnel dans votre application à l'aide du SDK Chat EKB.

Le ChatSDK est le composant principal du SDK EKB Content Creator qui vous permet de créer des applications d'IA conversationnelle en toute simplicité. Il fournit une gestion complète des chats, un traitement des messages, des réponses en streaming et une intégration avec la base de connaissances. Dans cet article, vous apprendrez à installer le SDK et à vous lancer rapidement avec notre exemple « Quick Start ». Vous pouvez explorer les diverses options de configuration, en savoir plus sur l'authentification et les méthodes principales que vous pouvez utiliser avec ce SDK. Vous découvrirez également des exemples de cas d'usage.

## Installation

```bash theme={null}
npm install @odin-ai-staging/sdk
```

## Quick Start

```typescript theme={null}
import { ChatSDK } from '@odin-ai-staging/sdk';

// Initialize the SDK
const chatSDK = new ChatSDK({
  baseUrl: 'https://your-api-endpoint.com/',
  projectId: 'your-project-id',
  apiKey: 'your-api-key',
  apiSecret: 'your-api-secret'
});

// Create a chat and send a message
async function quickExample() {
  // Create a new chat
  const chat = await chatSDK.createChat('My First Chat');
  
  // Send a message
  const response = await chatSDK.sendMessage('Hello, how can you help me?', {
    chatId: chat.chat_id
  });
  
  console.log('AI Response:', response.message);
}
```

## Configuration

### ChatSDKConfig Interface

```typescript theme={null}
interface ChatSDKConfig {
  baseUrl: string;          // API endpoint URL
  projectId: string;        // Your project identifier
  apiKey?: string;          // API key for authentication
  apiSecret?: string;       // API secret for authentication
  accessToken?: string;     // Access token for web app usage
}
```

### Configuration Options

* **baseUrl**: L'URL de base de votre point de terminaison API
* **projectId**: Votre identifiant de projet unique
* **apiKey** & **apiSecret**: Pour l'authentification côté serveur
* **accessToken**: Pour l'authentification côté client (applications web)

## Authentication

Le ChatSDK supporte deux méthodes d'authentification :

### API Key Authentication (Côté serveur)

```typescript theme={null}
const chatSDK = new ChatSDK({
  baseUrl: 'https://api.example.com/',
  projectId: 'proj_123',
  apiKey: 'your-api-key',
  apiSecret: 'your-api-secret'
});
```

### Access Token Authentication (Côté client)

```typescript theme={null}
const chatSDK = new ChatSDK({
  baseUrl: 'https://api.example.com/',
  projectId: 'proj_123',
  accessToken: 'your-access-token'
});
```

## Core Methods

### Chat Management

#### `createChat(name?, documentKeys?)`

Crée une nouvelle conversation de chat.

```typescript theme={null}
async createChat(
  name?: string,           // Optional chat name (defaults to "Untitled")
  documentKeys?: string[]  // Optional document keys for knowledge base context
): Promise<CreateChatResponse>
```

**Exemple :**

```typescript theme={null}
// Create a basic chat
const chat = await chatSDK.createChat('Customer Support Chat');

// Create a chat with knowledge base context
const chatWithDocs = await chatSDK.createChat(
  'Product Documentation Chat',
  ['doc_key_1', 'doc_key_2']
);
```

#### `listChats(cursor?, limit?)`

Récupère une liste paginée de chats dans le projet.

```typescript theme={null}
async listChats(
  cursor?: number,  // Optional cursor for pagination
  limit?: number    // Number of chats to return (default: 30, max: 100)
): Promise<ListChatsResponse>
```

**Exemple :**

```typescript theme={null}
// Get first 10 chats
const chats = await chatSDK.listChats(undefined, 10);

// Get next page using cursor
if (chats.next_cursor) {
  const nextPage = await chatSDK.listChats(chats.next_cursor, 10);
}
```

#### `getChatHistory(chatId)`

Récupère un chat avec son historique de messages complet.

```typescript theme={null}
async getChatHistory(chatId: string): Promise<ChatHistoryResponse>
```

**Exemple :**

```typescript theme={null}
const chatHistory = await chatSDK.getChatHistory('chat_123');
console.log('Messages:', chatHistory.messages);
```

#### `deleteChat(chatId)`

Supprime un chat et tous ses messages de manière permanente.

```typescript theme={null}
async deleteChat(chatId: string): Promise<void>
```

**Exemple :**

```typescript theme={null}
await chatSDK.deleteChat('chat_123');
```

#### `updateChatName(chatId, newName)`

Met à jour le nom d'affichage d'un chat existant.

```typescript theme={null}
async updateChatName(chatId: string, newName: string): Promise<void>
```

**Exemple :**

```typescript theme={null}
await chatSDK.updateChatName('chat_123', 'Updated Chat Name');
```

### Message Handling

#### `sendMessage(message, options?)`

Envoie un message et reçoit la réponse de l'IA.

```typescript theme={null}
async sendMessage(
  message: string,
  options?: SendMessageOptions
): Promise<SendMessageResponse>
```

**SendMessageOptions:**

```typescript theme={null}
interface SendMessageOptions {
  chatId?: string;          // Target chat ID
  agentType?: AgentType;    // Type of AI agent to use
  agentId?: string;         // Specific agent ID
  documentKeys?: string[];  // Knowledge base documents
  images?: File[];          // Image attachments
  metadata?: Record<string, any>;  // Custom metadata
  modelName?: ModelName;    // AI model to use
  useKnowledgebase?: boolean;      // Enable knowledge base
  isTest?: boolean;         // Test mode flag
  googleSearch?: boolean;   // Enable web search
  formatInstructions?: string;     // Response format guidance
  ignoreChatHistory?: boolean;     // Ignore conversation history
  exampleJson?: string;     // Example JSON for structured responses
  skipStream?: boolean;     // Disable streaming
}
```

**Exemple :**

```typescript theme={null}
// Basic message
const response = await chatSDK.sendMessage('What is artificial intelligence?', {
  chatId: 'chat_123'
});

// Advanced message with options
const advancedResponse = await chatSDK.sendMessage(
  'Analyze this data and provide insights',
  {
    chatId: 'chat_123',
    modelName: 'gpt-4o',
    useKnowledgebase: true,
    googleSearch: true,
    formatInstructions: 'Provide response in bullet points'
  }
);
```

#### `sendFeedback(messageId, chatId, feedback)`

Fournit des retours sur une réponse d'IA.

```typescript theme={null}
async sendFeedback(
  messageId: string,
  chatId: string,
  feedback: boolean  // true = thumbs up, false = thumbs down
): Promise<void>
```

**Exemple :**

```typescript theme={null}
// Positive feedback
await chatSDK.sendFeedback('msg_123', 'chat_123', true);

// Negative feedback
await chatSDK.sendFeedback('msg_123', 'chat_123', false);
```

## Streaming Support

### `sendMessageStream(message, options)`

Envoie un message avec une réponse en streaming en temps réel.

```typescript theme={null}
async sendMessageStream(
  message: string,
  options: SendMessageOptions & StreamCallbacks
): Promise<void>
```

**StreamCallbacks:**

```typescript theme={null}
interface StreamCallbacks {
  onChunk?: (chunk: string) => void;           // Text chunks
  onMessageObject?: (messageObject: any) => void;  // Structured data
  onComplete?: (message: Message) => void;     // Final message
  onError?: (error: Error) => void;           // Error handler
  onChatNameUpdate?: (chatName: string) => void;   // Chat name changes
  onDocumentChunk?: (chunk: string) => void;  // Document processing updates
  onMessageEnd?: () => void;                  // Stream completion
}
```

**Exemple :**

```typescript theme={null}
await chatSDK.sendMessageStream(
  'Tell me about machine learning',
  {
    chatId: 'chat_123',
    onChunk: (chunk) => {
      // Display text as it streams in
      console.log('Chunk:', chunk);
      updateUI(chunk);
    },
    onComplete: (message) => {
      console.log('Complete message:', message);
      finalizeUI(message);
    },
    onError: (error) => {
      console.error('Stream error:', error);
      showError(error.message);
    }
  }
);
```

## Error Handling

Le SDK lance des objets `APIError` pour les défaillances liées à l'API :

```typescript theme={null}
interface APIError {
  message: string;  // Error description
  status: number;   // HTTP status code
  detail?: string;  // Additional error details
}
```

**Exemple :**

```typescript theme={null}
try {
  const response = await chatSDK.sendMessage('Hello');
} catch (error) {
  if (error instanceof APIError) {
    console.error(`API Error ${error.status}: ${error.message}`);
    if (error.detail) {
      console.error('Details:', error.detail);
    }
  } else {
    console.error('Unexpected error:', error);
  }
}
```

## Examples

### Basic Chat Application

Dans cet exemple, vous apprendrez comment créer une application de chat basique à l'aide du SDK EKB avec des échanges de messages simples et non diffusés. Vous commencez par créer une classe `SimpleChatApp` qui initialise le ChatSDK avec vos credentials API extraits des variables d'environnement (URL de base, ID de projet, clé API et secret). La classe suit votre session de chat actuelle avec `currentChatId` et fournit trois méthodes principales : `startNewChat()` crée une nouvelle conversation de chat avec un nom personnalisé, `sendMessage()` envoie un message à l'IA et retourne la réponse complète (créant automatiquement un nouveau chat s'il n'en existe pas), et `getChatList()` récupère toutes vos conversations de chat existantes. Contrairement aux implémentations en streaming, cette approche attend la réponse complète de l'IA avant de l'afficher, ce qui la rend parfaite pour les cas d'usage simples où vous n'avez pas besoin de mises à jour en temps réel token par token. L'exemple utilise le modèle GPT-4o-mini et inclut la gestion des erreurs tout au long, avec journalisation en console pour vous aider à suivre le flux de la conversation—vous donnant une base directe pour créer une fonctionnalité de chatbot basique sans la complexité des callbacks de streaming.

```typescript theme={null}
import { ChatSDK } from '@odin-ai-staging/sdk';

class SimpleChatApp {
  private chatSDK: ChatSDK;
  private currentChatId?: string;

  constructor() {
    this.chatSDK = new ChatSDK({
      baseUrl: process.env.API_BASE_URL,
      projectId: process.env.PROJECT_ID,
      apiKey: process.env.API_KEY,
      apiSecret: process.env.API_SECRET
    });
  }

  async startNewChat(name: string = 'New Chat') {
    try {
      const chat = await this.chatSDK.createChat(name);
      this.currentChatId = chat.chat_id;
      console.log(`Created chat: ${chat.name} (${chat.chat_id})`);
      return chat;
    } catch (error) {
      console.error('Failed to create chat:', error);
      throw error;
    }
  }

  async sendMessage(message: string) {
    if (!this.currentChatId) {
      await this.startNewChat();
    }

    try {
      const response = await this.chatSDK.sendMessage(message, {
        chatId: this.currentChatId,
        modelName: 'gpt-4o-mini'
      });

      console.log('User:', message);
      console.log('AI:', response.message);
      
      return response;
    } catch (error) {
      console.error('Failed to send message:', error);
      throw error;
    }
  }

  async getChatList() {
    try {
      const chats = await this.chatSDK.listChats();
      return chats.chats;
    } catch (error) {
      console.error('Failed to get chat list:', error);
      throw error;
    }
  }
}

// Usage
const app = new SimpleChatApp();
await app.sendMessage('Hello, how are you?');
```

### Streaming Chat with Real-time Updates

Dans cet exemple, vous apprendrez comment créer une interface de chat en streaming qui se connecte à l'API EKB et affiche les réponses de l'IA en temps réel. Vous commencez par créer une classe `StreamingChat` qui initialise le ChatSDK avec vos credentials API et une référence à un élément HTML où les messages apparaîtront. Lorsque vous envoyez un message à l'aide de `sendStreamingMessage()`, vous configurerez des gestionnaires de callbacks qui traitent la réponse en streaming au fur et à mesure qu'elle arrive : le callback `onChunk` ajoute chaque morceau de texte à votre UI immédiatement (créant cet effet « saisie » caractéristique), tandis que `onMessageObject` vous permet de gérer du contenu riche comme les images. Vous implémenterez également la gestion des erreurs avec `onError`, mettrez à jour le titre de votre chat avec `onChatNameUpdate`, et utiliserez `onComplete` pour ajouter des boutons de retours pouce vers le haut/bas une fois que le message a fini de diffuser. Cet exemple vous montre comment afficher des images dynamiquement, collecter les retours des utilisateurs sur les réponses de l'IA, et configurer le chat pour utiliser GPT-4o avec l'intégration de la Base de Connaissances—vous donnant tout ce dont vous avez besoin pour créer une interface de type ChatGPT avec des réponses en streaming en temps réel et des fonctionnalités interactives.

```typescript theme={null}
import { ChatSDK, StreamCallbacks } from '@odin-ai-staging/sdk';

class StreamingChat {
  private chatSDK: ChatSDK;
  private messageElement: HTMLElement;

  constructor(messageElement: HTMLElement) {
    this.messageElement = messageElement;
    this.chatSDK = new ChatSDK({
      baseUrl: 'https://your-api.com/',
      projectId: 'your-project-id',
      accessToken: 'your-access-token'
    });
  }

  async sendStreamingMessage(message: string, chatId: string) {
    // Clear previous content
    this.messageElement.innerHTML = '';

    const callbacks: StreamCallbacks = {
      onChunk: (chunk: string) => {
        // Append each chunk to the UI
        this.messageElement.innerHTML += chunk;
        this.messageElement.scrollIntoView();
      },

      onMessageObject: (messageObj: any) => {
        // Handle structured data like images, cards, etc.
        if (messageObj.image_urls) {
          this.displayImages(messageObj.image_urls);
        }
      },

      onComplete: (message: any) => {
        console.log('Message complete:', message);
        // Add final styling, enable feedback buttons, etc.
        this.finalizeMessage(message);
      },

      onError: (error: Error) => {
        console.error('Streaming error:', error);
        this.messageElement.innerHTML = `Error: ${error.message}`;
      },

      onChatNameUpdate: (chatName: string) => {
        // Update chat title in UI
        document.title = chatName;
      }
    };

    try {
      await this.chatSDK.sendMessageStream(message, {
        chatId,
        modelName: 'gpt-4o',
        useKnowledgebase: true,
        ...callbacks
      });
    } catch (error) {
      console.error('Failed to send streaming message:', error);
    }
  }

  private displayImages(imageUrls: string[]) {
    imageUrls.forEach(url => {
      const img = document.createElement('img');
      img.src = url;
      img.style.maxWidth = '100%';
      this.messageElement.appendChild(img);
    });
  }

  private finalizeMessage(message: any) {
    // Add feedback buttons
    const feedbackDiv = document.createElement('div');
    feedbackDiv.innerHTML = `
      <button onclick="this.provideFeedback('${message.id}', true)">👍</button>
      <button onclick="this.provideFeedback('${message.id}', false)">👎</button>
    `;
    this.messageElement.appendChild(feedbackDiv);
  }

  async provideFeedback(messageId: string, isPositive: boolean) {
    try {
      await this.chatSDK.sendFeedback(messageId, 'chat_id', isPositive);
      console.log('Feedback sent successfully');
    } catch (error) {
      console.error('Failed to send feedback:', error);
    }
  }
}
```

### Knowledge Base Integration

Dans cet exemple, vous découvrirez comment créer une application de chat alimentée par la Base de Connaissances qui peut répondre aux questions en fonction de documents spécifiques que vous téléchargez dans votre Base de Connaissances. La classe `KnowledgeBasedChat` initialise le ChatSDK avec vos credentials API à partir des variables d'environnement, puis utilise deux méthodes principales pour interagir avec vos documents : `createDocumentChat()` configure une nouvelle session de chat liée à des documents spécifiques en passant un tableau de documentKeys (identifiants uniques pour vos documents téléchargés), et `askDocumentQuestion()` envoie des questions à l'IA avec les fonctionnalités de la Base de Connaissances activées. Lorsque vous posez des questions, vous configurerez le chat pour utiliser `useKnowledgebase: true` et spécifier `agentType: 'document_agent'` pour vous assurer que l'IA récupère les informations pertinentes de vos documents, tandis que `formatInstructions` indique à l'IA d'inclure les citations de ses sources. La réponse inclut une propriété sources qui vous montre quels documents l'IA a référencés lors de la génération de sa réponse, ce qui la rend parfaite pour construire des systèmes Q\&A de documents, des assistants de recherche, ou toute application où vous avez besoin de réponses d'IA ancrées dans du contenu spécifique plutôt que dans des connaissances générales. Cela permet une transparence totale dans la façon dont l'IA est arrivée à ses réponses.

```typescript theme={null}
import { ChatSDK } from '@odin-ai-staging/sdk';

class KnowledgeBasedChat {
  private chatSDK: ChatSDK;

  constructor() {
    this.chatSDK = new ChatSDK({
      baseUrl: process.env.API_BASE_URL,
      projectId: process.env.PROJECT_ID,
      apiKey: process.env.API_KEY,
      apiSecret: process.env.API_SECRET
    });
  }

  async createDocumentChat(documentKeys: string[], chatName?: string) {
    try {
      const chat = await this.chatSDK.createChat(
        chatName || 'Document Q&A',
        documentKeys
      );
      
      console.log(`Created document chat with ${documentKeys.length} documents`);
      return chat;
    } catch (error) {
      console.error('Failed to create document chat:', error);
      throw error;
    }
  }

  async askDocumentQuestion(question: string, chatId: string, documentKeys?: string[]) {
    try {
      const response = await this.chatSDK.sendMessage(question, {
        chatId,
        documentKeys,
        useKnowledgebase: true,
        agentType: 'document_agent',
        formatInstructions: 'Provide citations for your sources'
      });

      // Display sources if available
      if (response.message.sources) {
        console.log('Sources:', response.message.sources);
      }

      return response;
    } catch (error) {
      console.error('Failed to ask document question:', error);
      throw error;
    }
  }
}

// Usage
const kbChat = new KnowledgeBasedChat();
const chat = await kbChat.createDocumentChat(['doc_1', 'doc_2'], 'Product FAQ');
const answer = await kbChat.askDocumentQuestion(
  'What are the key features of the product?',
  chat.chat_id
);
```

## Best Practices

### Error Handling

Implémentez toujours une gestion appropriée des erreurs pour toutes les méthodes du SDK :

```typescript theme={null}
try {
  const response = await chatSDK.sendMessage(message, options);
  // Handle success
} catch (error) {
  if (error instanceof APIError) {
    // Handle API errors
    console.error(`API Error: ${error.message}`);
  } else {
    // Handle unexpected errors
    console.error('Unexpected error:', error);
  }
}
```

### Streaming for Better UX

Utilisez le streaming pour les réponses plus longues afin de fournir des retours en temps réel :

```typescript theme={null}
// Instead of waiting for complete response
const response = await chatSDK.sendMessage(longQuery);

// Use streaming for better user experience
await chatSDK.sendMessageStream(longQuery, {
  onChunk: (chunk) => updateUI(chunk),
  onComplete: (message) => finalizeUI(message)
});
```

### Optimize API Calls

* Réutilisez les ID de chat au lieu de créer de nouveaux chats pour chaque message
* Utilisez la pagination pour les listes de chats
* Implémentez la mise en cache pour les données fréquemment consultées

```typescript theme={null}
class OptimizedChatManager {
  private chatCache = new Map<string, any>();
  private currentChatId?: string;

  async getOrCreateChat(name?: string) {
    if (this.currentChatId) {
      return this.currentChatId;
    }

    const chat = await this.chatSDK.createChat(name);
    this.currentChatId = chat.chat_id;
    return this.currentChatId;
  }

  async getCachedChatHistory(chatId: string) {
    if (this.chatCache.has(chatId)) {
      return this.chatCache.get(chatId);
    }

    const history = await this.chatSDK.getChatHistory(chatId);
    this.chatCache.set(chatId, history);
    return history;
  }
}
```

### Configuration Management

Stockez la configuration de manière sécurisée et utilisez les variables d'environnement :

```typescript theme={null}
// Good: Use environment variables
const chatSDK = new ChatSDK({
  baseUrl: process.env.ODIN_API_BASE_URL,
  projectId: process.env.ODIN_PROJECT_ID,
  apiKey: process.env.ODIN_API_KEY,
  apiSecret: process.env.ODIN_API_SECRET
});

// Bad: Hardcode credentials
const chatSDK = new ChatSDK({
  baseUrl: 'https://api.example.com',
  projectId: 'hardcoded-project-id',
  apiKey: 'hardcoded-api-key',
  apiSecret: 'hardcoded-secret'
});
```

### Memory Management

Nettoyez les ressources et évitez les fuites mémoire :

```typescript theme={null}
class ChatApplication {
  private activeStreams = new Set<AbortController>();

  async sendStreamingMessage(message: string, options: any) {
    const controller = new AbortController();
    this.activeStreams.add(controller);

    try {
      await this.chatSDK.sendMessageStream(message, {
        ...options,
        signal: controller.signal  // If supported
      });
    } finally {
      this.activeStreams.delete(controller);
    }
  }

  cleanup() {
    // Cancel all active streams
    this.activeStreams.forEach(controller => controller.abort());
    this.activeStreams.clear();
  }
}
```
