Aller au contenu principal

Premier Appel et Streaming en TypeScript

Envoyer votre première requête

Maintenant que le SDK est installé, passons à la pratique. La méthode chat.complete() du SDK TypeScript est l’équivalent exact de celle du SDK Python :

import 'dotenv/config';
import { Mistral } from '@mistralai/mistralai';

const client = new Mistral({
  apiKey: process.env.MISTRAL_API_KEY,
});

async function main() {
  const response = await client.chat.complete({
    model: 'mistral-small-latest',
    messages: [
      {
        role: 'user',
        content: 'Expliquez le concept de closure en JavaScript en trois phrases.',
      },
    ],
  });

  console.log(response.choices?.[0]?.message?.content);
}

main();

Comprendre la réponse

La structure de la réponse est identique à celle du SDK Python. En TypeScript, vous bénéficiez du typage :

async function analyserReponse() {
  const response = await client.chat.complete({
    model: 'mistral-small-latest',
    messages: [
      { role: 'user', content: 'Quelle est la capitale de la France ?' },
    ],
    maxTokens: 100,
  });

  // Texte de la réponse
  const texte = response.choices?.[0]?.message?.content;

  // Raison d'arrêt
  const finRaison = response.choices?.[0]?.finishReason;

  // Statistiques de tokens
  const tokensEntree = response.usage?.promptTokens;
  const tokensSortie = response.usage?.completionTokens;

  console.log(`Réponse : ${texte}`);
  console.log(`Tokens : ${tokensEntree} entrée + ${tokensSortie} sortie`);
  console.log(`Arrêt : ${finRaison}`);
}

Streaming en TypeScript

Le streaming est essentiel pour les interfaces web. Le SDK TypeScript utilise des générateurs asynchrones :

async function streamReponse() {
  const stream = await client.chat.stream({
    model: 'mistral-small-latest',
    messages: [
      {
        role: 'user',
        content: 'Décrivez les cinq principaux design patterns en JavaScript.',
      },
    ],
  });

  for await (const chunk of stream) {
    const content = chunk.data.choices[0]?.delta?.content;
    if (content) {
      process.stdout.write(content);
    }
  }
  console.log();
}

Intégration avec un serveur Express

Voici comment exposer le streaming via Server-Sent Events (SSE) dans une API Express :

import express from 'express';
import { Mistral } from '@mistralai/mistralai';

const app = express();
const client = new Mistral({ apiKey: process.env.MISTRAL_API_KEY });

app.get('/api/chat', async (req, res) => {
  const question = req.query.q as string;

  res.setHeader('Content-Type', 'text/event-stream');
  res.setHeader('Cache-Control', 'no-cache');
  res.setHeader('Connection', 'keep-alive');

  const stream = await client.chat.stream({
    model: 'mistral-small-latest',
    messages: [{ role: 'user', content: question }],
  });

  for await (const chunk of stream) {
    const content = chunk.data.choices[0]?.delta?.content;
    if (content) {
      res.write(`data: ${JSON.stringify({ text: content })}\n\n`);
    }
  }

  res.write('data: [DONE]\n\n');
  res.end();
});

app.listen(3000, () => console.log('Serveur sur le port 3000'));

Conversations multi-tour en TypeScript

La gestion de l’historique suit le même principe qu’en Python — vous maintenez un tableau de messages :

import { Mistral } from '@mistralai/mistralai';

type Message = {
  role: 'system' | 'user' | 'assistant';
  content: string;
};

const client = new Mistral({ apiKey: process.env.MISTRAL_API_KEY });

const historique: Message[] = [
  {
    role: 'system',
    content: 'Vous êtes un assistant expert en TypeScript. Répondez en français.',
  },
];

async function poserQuestion(question: string): Promise<string> {
  historique.push({ role: 'user', content: question });

  const response = await client.chat.complete({
    model: 'mistral-small-latest',
    messages: historique,
  });

  const reponse = response.choices?.[0]?.message?.content ?? '';
  historique.push({ role: 'assistant', content: reponse });

  return reponse;
}

async function main() {
  console.log(await poserQuestion('Qu\'est-ce qu\'un type générique ?'));
  console.log(await poserQuestion('Montrez-moi un exemple concret.'));
  console.log(await poserQuestion('Comment ajouter des contraintes ?'));
}

main();

Paramètres avancés

Le SDK TypeScript expose les mêmes paramètres que le SDK Python :

const response = await client.chat.complete({
  model: 'mistral-large-latest',
  messages: [
    { role: 'user', content: 'Proposez une architecture pour un SaaS B2B.' },
  ],
  temperature: 0.5,
  maxTokens: 1000,
  topP: 0.95,
});

Gestion d’erreurs

try {
  const response = await client.chat.complete({
    model: 'mistral-small-latest',
    messages: [{ role: 'user', content: 'Bonjour !' }],
  });
  console.log(response.choices?.[0]?.message?.content);
} catch (error) {
  if (error instanceof Error) {
    console.error(`Erreur API Mistral : ${error.message}`);
  }
}

Points clés à retenir

  • client.chat.complete() est asynchrone — utilisez await
  • Le streaming utilise for await...of sur le résultat de client.chat.stream()
  • Le typage TypeScript détecte les erreurs de paramètres à la compilation
  • L’intégration SSE avec Express est directe pour les interfaces web temps réel
  • L’historique de conversation se gère avec un tableau typé Message[]