@boostecom/provider 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/README.md +90 -0
  2. package/dist/index.cjs +2522 -0
  3. package/dist/index.cjs.map +1 -0
  4. package/dist/index.d.cts +848 -0
  5. package/dist/index.d.ts +848 -0
  6. package/dist/index.js +2484 -0
  7. package/dist/index.js.map +1 -0
  8. package/docs/content/README.md +337 -0
  9. package/docs/content/agent-teams.mdx +324 -0
  10. package/docs/content/api.mdx +757 -0
  11. package/docs/content/best-practices.mdx +624 -0
  12. package/docs/content/examples.mdx +675 -0
  13. package/docs/content/guide.mdx +516 -0
  14. package/docs/content/index.mdx +99 -0
  15. package/docs/content/installation.mdx +246 -0
  16. package/docs/content/skills.mdx +548 -0
  17. package/docs/content/troubleshooting.mdx +588 -0
  18. package/docs/examples/README.md +499 -0
  19. package/docs/examples/abort-signal.ts +125 -0
  20. package/docs/examples/agent-teams.ts +122 -0
  21. package/docs/examples/basic-usage.ts +73 -0
  22. package/docs/examples/check-cli.ts +51 -0
  23. package/docs/examples/conversation-history.ts +69 -0
  24. package/docs/examples/custom-config.ts +90 -0
  25. package/docs/examples/generate-object-constraints.ts +209 -0
  26. package/docs/examples/generate-object.ts +211 -0
  27. package/docs/examples/hooks-callbacks.ts +63 -0
  28. package/docs/examples/images.ts +76 -0
  29. package/docs/examples/integration-test.ts +241 -0
  30. package/docs/examples/limitations.ts +150 -0
  31. package/docs/examples/logging-custom-logger.ts +99 -0
  32. package/docs/examples/logging-default.ts +55 -0
  33. package/docs/examples/logging-disabled.ts +74 -0
  34. package/docs/examples/logging-verbose.ts +64 -0
  35. package/docs/examples/long-running-tasks.ts +179 -0
  36. package/docs/examples/message-injection.ts +210 -0
  37. package/docs/examples/mid-stream-injection.ts +126 -0
  38. package/docs/examples/run-all-examples.sh +48 -0
  39. package/docs/examples/sdk-tools-callbacks.ts +49 -0
  40. package/docs/examples/skills-discovery.ts +144 -0
  41. package/docs/examples/skills-management.ts +140 -0
  42. package/docs/examples/stream-object.ts +80 -0
  43. package/docs/examples/streaming.ts +52 -0
  44. package/docs/examples/structured-output-repro.ts +227 -0
  45. package/docs/examples/tool-management.ts +215 -0
  46. package/docs/examples/tool-streaming.ts +132 -0
  47. package/docs/examples/zod4-compatibility-test.ts +290 -0
  48. package/docs/src/claude-code-language-model.test.ts +3883 -0
  49. package/docs/src/claude-code-language-model.ts +2586 -0
  50. package/docs/src/claude-code-provider.test.ts +97 -0
  51. package/docs/src/claude-code-provider.ts +179 -0
  52. package/docs/src/convert-to-claude-code-messages.images.test.ts +104 -0
  53. package/docs/src/convert-to-claude-code-messages.test.ts +193 -0
  54. package/docs/src/convert-to-claude-code-messages.ts +419 -0
  55. package/docs/src/errors.test.ts +213 -0
  56. package/docs/src/errors.ts +216 -0
  57. package/docs/src/index.test.ts +49 -0
  58. package/docs/src/index.ts +98 -0
  59. package/docs/src/logger.integration.test.ts +164 -0
  60. package/docs/src/logger.test.ts +184 -0
  61. package/docs/src/logger.ts +65 -0
  62. package/docs/src/map-claude-code-finish-reason.test.ts +120 -0
  63. package/docs/src/map-claude-code-finish-reason.ts +60 -0
  64. package/docs/src/mcp-helpers.test.ts +71 -0
  65. package/docs/src/mcp-helpers.ts +123 -0
  66. package/docs/src/message-injection.test.ts +460 -0
  67. package/docs/src/types.ts +447 -0
  68. package/docs/src/validation.test.ts +558 -0
  69. package/docs/src/validation.ts +360 -0
  70. package/package.json +124 -0
@@ -0,0 +1,675 @@
1
+ ---
2
+ title: Exemples pratiques
3
+ description: Exemples concrets pour intégrer Claude Code dans vos applications
4
+ ---
5
+
6
+ # Exemples pratiques
7
+
8
+ Cette page présente des exemples concrets d'intégration du provider Claude Code dans différents types d'applications.
9
+
10
+ ## Applications web
11
+
12
+ ### API REST avec Express
13
+
14
+ Créez une API REST qui utilise Claude pour générer du contenu :
15
+
16
+ ```typescript title="server.ts"
17
+ import express from 'express';
18
+ import { generateText } from 'ai';
19
+ import { claudeCode } from '@boostecom/provider';
20
+
21
+ const app = express();
22
+ app.use(express.json());
23
+
24
+ // Endpoint pour génération de texte
25
+ app.post('/api/generate', async (req, res) => {
26
+ try {
27
+ const { prompt, model = 'haiku' } = req.body;
28
+
29
+ if (!prompt) {
30
+ return res.status(400).json({ error: 'Prompt requis' });
31
+ }
32
+
33
+ const { text, usage } = await generateText({
34
+ model: claudeCode(model),
35
+ prompt,
36
+ });
37
+
38
+ res.json({
39
+ text,
40
+ usage,
41
+ model,
42
+ });
43
+ } catch (error: any) {
44
+ console.error('Erreur:', error);
45
+ res.status(500).json({ error: error.message });
46
+ }
47
+ });
48
+
49
+ // Endpoint pour génération d'objets structurés
50
+ app.post('/api/extract', async (req, res) => {
51
+ try {
52
+ const { text } = req.body;
53
+
54
+ const { object } = await generateObject({
55
+ model: claudeCode('sonnet'),
56
+ schema: z.object({
57
+ nom: z.string(),
58
+ email: z.string().describe('Email (ex: user@example.com)'),
59
+ sujet: z.string(),
60
+ sentiment: z.enum(['positif', 'neutre', 'negatif']),
61
+ }),
62
+ prompt: `Extrait les informations de contact de ce texte: ${text}`,
63
+ });
64
+
65
+ res.json({ data: object });
66
+ } catch (error: any) {
67
+ res.status(500).json({ error: error.message });
68
+ }
69
+ });
70
+
71
+ app.listen(3000, () => {
72
+ console.log('🚀 Serveur démarré sur http://localhost:3000');
73
+ });
74
+ ```
75
+
76
+ ### API avec streaming SSE (Server-Sent Events)
77
+
78
+ Diffusez les réponses en temps réel vers le client :
79
+
80
+ ```typescript title="server.ts"
81
+ import express from 'express';
82
+ import { streamText } from 'ai';
83
+ import { claudeCode } from '@boostecom/provider';
84
+
85
+ const app = express();
86
+ app.use(express.json());
87
+
88
+ app.post('/api/stream', async (req, res) => {
89
+ const { prompt } = req.body;
90
+
91
+ // Configurer SSE
92
+ res.setHeader('Content-Type', 'text/event-stream');
93
+ res.setHeader('Cache-Control', 'no-cache');
94
+ res.setHeader('Connection', 'keep-alive');
95
+
96
+ try {
97
+ const result = streamText({
98
+ model: claudeCode('sonnet'),
99
+ prompt,
100
+ });
101
+
102
+ for await (const chunk of result.textStream) {
103
+ // Envoyer chaque fragment au client
104
+ res.write(`data: ${JSON.stringify({ text: chunk })}\n\n`);
105
+ }
106
+
107
+ res.write('data: [DONE]\n\n');
108
+ res.end();
109
+ } catch (error: any) {
110
+ res.write(`data: ${JSON.stringify({ error: error.message })}\n\n`);
111
+ res.end();
112
+ }
113
+ });
114
+
115
+ app.listen(3000);
116
+ ```
117
+
118
+ ```typescript title="client.ts"
119
+ // Côté client
120
+ async function streamFromAPI(prompt: string) {
121
+ const response = await fetch('http://localhost:3000/api/stream', {
122
+ method: 'POST',
123
+ headers: { 'Content-Type': 'application/json' },
124
+ body: JSON.stringify({ prompt }),
125
+ });
126
+
127
+ const reader = response.body?.getReader();
128
+ const decoder = new TextDecoder();
129
+
130
+ while (true) {
131
+ const { done, value } = await reader!.read();
132
+ if (done) break;
133
+
134
+ const chunk = decoder.decode(value);
135
+ const lines = chunk.split('\n');
136
+
137
+ for (const line of lines) {
138
+ if (line.startsWith('data: ')) {
139
+ const data = line.slice(6);
140
+ if (data === '[DONE]') return;
141
+
142
+ const parsed = JSON.parse(data);
143
+ process.stdout.write(parsed.text);
144
+ }
145
+ }
146
+ }
147
+ }
148
+
149
+ streamFromAPI('Raconte une histoire courte');
150
+ ```
151
+
152
+ ### Next.js App Router
153
+
154
+ Intégration avec Next.js 13+ et le App Router :
155
+
156
+ ```typescript title="app/api/chat/route.ts"
157
+ import { streamText } from 'ai';
158
+ import { claudeCode } from '@boostecom/provider';
159
+ import type { CoreMessage } from 'ai';
160
+
161
+ export const runtime = 'nodejs'; // Important pour le CLI
162
+
163
+ export async function POST(req: Request) {
164
+ try {
165
+ const { messages }: { messages: CoreMessage[] } = await req.json();
166
+
167
+ const result = streamText({
168
+ model: claudeCode('sonnet'),
169
+ messages,
170
+ });
171
+
172
+ // Retourner le stream AI SDK (compatible avec useChat)
173
+ return result.toDataStreamResponse();
174
+ } catch (error: any) {
175
+ return new Response(JSON.stringify({ error: error.message }), {
176
+ status: 500,
177
+ headers: { 'Content-Type': 'application/json' },
178
+ });
179
+ }
180
+ }
181
+ ```
182
+
183
+ ```typescript title="app/chat/page.tsx"
184
+ 'use client';
185
+
186
+ import { useChat } from 'ai/react';
187
+
188
+ export default function ChatPage() {
189
+ const { messages, input, handleInputChange, handleSubmit, isLoading } = useChat({
190
+ api: '/api/chat',
191
+ });
192
+
193
+ return (
194
+ <div className="flex flex-col h-screen max-w-2xl mx-auto p-4">
195
+ <div className="flex-1 overflow-y-auto space-y-4 mb-4">
196
+ {messages.map((message) => (
197
+ <div
198
+ key={message.id}
199
+ className={`p-4 rounded-lg ${
200
+ message.role === 'user'
201
+ ? 'bg-blue-100 ml-auto'
202
+ : 'bg-gray-100'
203
+ }`}
204
+ >
205
+ <div className="font-bold mb-1">
206
+ {message.role === 'user' ? 'Vous' : 'Claude'}
207
+ </div>
208
+ <div>{message.content}</div>
209
+ </div>
210
+ ))}
211
+ {isLoading && (
212
+ <div className="bg-gray-100 p-4 rounded-lg">
213
+ <div className="animate-pulse">Claude réfléchit...</div>
214
+ </div>
215
+ )}
216
+ </div>
217
+
218
+ <form onSubmit={handleSubmit} className="flex gap-2">
219
+ <input
220
+ value={input}
221
+ onChange={handleInputChange}
222
+ placeholder="Tapez votre message..."
223
+ className="flex-1 p-2 border rounded"
224
+ disabled={isLoading}
225
+ />
226
+ <button
227
+ type="submit"
228
+ disabled={isLoading}
229
+ className="px-4 py-2 bg-blue-500 text-white rounded disabled:bg-gray-300"
230
+ >
231
+ Envoyer
232
+ </button>
233
+ </form>
234
+ </div>
235
+ );
236
+ }
237
+ ```
238
+
239
+ ## Outils et scripts
240
+
241
+ ### Analyseur de code
242
+
243
+ Script pour analyser et améliorer du code :
244
+
245
+ ```typescript title="code-analyzer.ts"
246
+ import { generateObject } from 'ai';
247
+ import { claudeCode } from '@boostecom/provider';
248
+ import { z } from 'zod';
249
+ import { readFileSync } from 'fs';
250
+
251
+ async function analyzeCode(filePath: string) {
252
+ const code = readFileSync(filePath, 'utf-8');
253
+
254
+ const { object } = await generateObject({
255
+ model: claudeCode('opus', {
256
+ allowedTools: ['Read'], // Permettre la lecture
257
+ }),
258
+ schema: z.object({
259
+ qualite: z.number().min(0).max(10).describe('Score de qualité sur 10'),
260
+ problemes: z.array(z.object({
261
+ ligne: z.number().optional(),
262
+ severite: z.enum(['faible', 'moyen', 'critique']),
263
+ description: z.string(),
264
+ })),
265
+ suggestions: z.array(z.string()),
266
+ refactoring: z.string().optional().describe('Code refactorisé si nécessaire'),
267
+ }),
268
+ prompt: `Analyse ce code et donne des suggestions d'amélioration:\n\n${code}`,
269
+ });
270
+
271
+ return object;
272
+ }
273
+
274
+ // Utilisation
275
+ const analysis = await analyzeCode('./src/index.ts');
276
+
277
+ console.log(`📊 Qualité: ${analysis.qualite}/10\n`);
278
+
279
+ if (analysis.problemes.length > 0) {
280
+ console.log('⚠️ Problèmes détectés:');
281
+ analysis.problemes.forEach((p, i) => {
282
+ console.log(` ${i + 1}. [${p.severite}] ${p.description}`);
283
+ });
284
+ console.log();
285
+ }
286
+
287
+ if (analysis.suggestions.length > 0) {
288
+ console.log('💡 Suggestions:');
289
+ analysis.suggestions.forEach((s, i) => {
290
+ console.log(` ${i + 1}. ${s}`);
291
+ });
292
+ }
293
+
294
+ if (analysis.refactoring) {
295
+ console.log('\n✨ Code refactorisé proposé:');
296
+ console.log(analysis.refactoring);
297
+ }
298
+ ```
299
+
300
+ ### Générateur de documentation
301
+
302
+ Générez automatiquement de la documentation depuis votre code :
303
+
304
+ ```typescript title="doc-generator.ts"
305
+ import { streamText } from 'ai';
306
+ import { claudeCode } from '@boostecom/provider';
307
+ import { readFileSync, writeFileSync } from 'fs';
308
+ import { glob } from 'glob';
309
+
310
+ async function generateDocs(pattern: string) {
311
+ const files = await glob(pattern);
312
+
313
+ for (const file of files) {
314
+ console.log(`📝 Génération de la doc pour ${file}...`);
315
+
316
+ const code = readFileSync(file, 'utf-8');
317
+
318
+ const result = streamText({
319
+ model: claudeCode('sonnet', {
320
+ allowedTools: ['Read'],
321
+ }),
322
+ prompt: `Génère une documentation détaillée en Markdown pour ce code.
323
+ Include:
324
+ - Description générale
325
+ - Paramètres et types
326
+ - Valeurs de retour
327
+ - Exemples d'utilisation
328
+ - Notes importantes
329
+
330
+ Code:
331
+ ${code}`,
332
+ });
333
+
334
+ let doc = '';
335
+ for await (const chunk of result.textStream) {
336
+ doc += chunk;
337
+ }
338
+
339
+ // Sauvegarder la documentation
340
+ const docFile = file.replace(/\.(ts|js)$/, '.md');
341
+ writeFileSync(docFile, doc);
342
+
343
+ console.log(`✅ Documentation sauvegardée dans ${docFile}\n`);
344
+ }
345
+ }
346
+
347
+ // Générer la doc pour tous les fichiers TypeScript
348
+ generateDocs('src/**/*.ts');
349
+ ```
350
+
351
+ ### Assistant CLI interactif
352
+
353
+ Créez un assistant en ligne de commande :
354
+
355
+ ```typescript title="cli-assistant.ts"
356
+ #!/usr/bin/env node
357
+
358
+ import { streamText } from 'ai';
359
+ import { claudeCode } from '@boostecom/provider';
360
+ import * as readline from 'readline';
361
+ import type { CoreMessage } from 'ai';
362
+ import chalk from 'chalk';
363
+
364
+ const messages: CoreMessage[] = [];
365
+ const rl = readline.createInterface({
366
+ input: process.stdin,
367
+ output: process.stdout,
368
+ });
369
+
370
+ async function chat() {
371
+ rl.question(chalk.blue('Vous: '), async (userInput) => {
372
+ if (userInput.toLowerCase() === 'exit') {
373
+ console.log(chalk.green('\n👋 Au revoir!'));
374
+ rl.close();
375
+ return;
376
+ }
377
+
378
+ if (userInput.toLowerCase() === 'clear') {
379
+ messages.length = 0;
380
+ console.log(chalk.yellow('🗑️ Historique effacé\n'));
381
+ chat();
382
+ return;
383
+ }
384
+
385
+ messages.push({ role: 'user', content: userInput });
386
+
387
+ const result = streamText({
388
+ model: claudeCode('sonnet', {
389
+ systemPrompt: 'Tu es un assistant de développement en ligne de commande. ' +
390
+ 'Aide l\'utilisateur avec ses questions de programmation.',
391
+ allowedTools: ['Read', 'LS', 'Bash(git:*)'],
392
+ verbose: false,
393
+ }),
394
+ messages,
395
+ });
396
+
397
+ process.stdout.write(chalk.green('Claude: '));
398
+
399
+ let assistantResponse = '';
400
+ for await (const chunk of result.textStream) {
401
+ process.stdout.write(chunk);
402
+ assistantResponse += chunk;
403
+ }
404
+
405
+ console.log('\n');
406
+ messages.push({ role: 'assistant', content: assistantResponse });
407
+
408
+ chat();
409
+ });
410
+ }
411
+
412
+ console.log(chalk.bold('\n🤖 Assistant CLI Claude Code'));
413
+ console.log(chalk.dim('Commandes: exit (quitter), clear (effacer historique)\n'));
414
+
415
+ chat();
416
+ ```
417
+
418
+ ```bash
419
+ # Rendre le script exécutable
420
+ chmod +x cli-assistant.ts
421
+
422
+ # Lancer l'assistant
423
+ ./cli-assistant.ts
424
+ ```
425
+
426
+ ## Traitement par lots
427
+
428
+ ### Traduction de fichiers en masse
429
+
430
+ ```typescript title="batch-translator.ts"
431
+ import { generateObject } from 'ai';
432
+ import { claudeCode } from '@boostecom/provider';
433
+ import { z } from 'zod';
434
+ import { readFileSync, writeFileSync } from 'fs';
435
+ import { glob } from 'glob';
436
+ import { parse } from 'path';
437
+
438
+ async function translateFiles(pattern: string, targetLang: string) {
439
+ const files = await glob(pattern);
440
+
441
+ for (const file of files) {
442
+ console.log(`🌐 Traduction de ${file} vers ${targetLang}...`);
443
+
444
+ const content = readFileSync(file, 'utf-8');
445
+ const json = JSON.parse(content);
446
+
447
+ const { object } = await generateObject({
448
+ model: claudeCode('sonnet'),
449
+ schema: z.record(z.string()),
450
+ prompt: `Traduis toutes les valeurs de cet objet JSON en ${targetLang}.
451
+ Garde les clés identiques, traduis seulement les valeurs.
452
+
453
+ JSON à traduire:
454
+ ${JSON.stringify(json, null, 2)}`,
455
+ });
456
+
457
+ // Sauvegarder la traduction
458
+ const { dir, name } = parse(file);
459
+ const outputFile = `${dir}/${name}.${targetLang}.json`;
460
+ writeFileSync(outputFile, JSON.stringify(object, null, 2));
461
+
462
+ console.log(`✅ Sauvegardé dans ${outputFile}\n`);
463
+ }
464
+ }
465
+
466
+ // Traduire tous les fichiers i18n en espagnol
467
+ translateFiles('i18n/en/**/*.json', 'es');
468
+ ```
469
+
470
+ ### Extraction de données en masse
471
+
472
+ ```typescript title="batch-extractor.ts"
473
+ import { generateObject } from 'ai';
474
+ import { claudeCode } from '@boostecom/provider';
475
+ import { z } from 'zod';
476
+
477
+ const productSchema = z.object({
478
+ nom: z.string(),
479
+ prix: z.number().describe('Prix en euros'),
480
+ description: z.string(),
481
+ caracteristiques: z.array(z.string()),
482
+ categorie: z.enum(['electronique', 'vetements', 'maison', 'autre']),
483
+ });
484
+
485
+ async function extractProducts(htmlPages: string[]) {
486
+ const products = [];
487
+
488
+ for (const html of htmlPages) {
489
+ console.log('🔍 Extraction des données...');
490
+
491
+ const { object } = await generateObject({
492
+ model: claudeCode('haiku'), // Haiku pour rapidité et coût
493
+ schema: productSchema,
494
+ prompt: `Extrait les informations produit de ce HTML:\n\n${html}`,
495
+ });
496
+
497
+ products.push(object);
498
+ }
499
+
500
+ return products;
501
+ }
502
+
503
+ // Exemple d'utilisation
504
+ const htmlPages = [
505
+ '<html>...</html>',
506
+ '<html>...</html>',
507
+ ];
508
+
509
+ const products = await extractProducts(htmlPages);
510
+ console.log('✅ Produits extraits:', products);
511
+ ```
512
+
513
+ ## Intégration avec bases de données
514
+
515
+ ### Génération de requêtes SQL
516
+
517
+ ```typescript title="sql-generator.ts"
518
+ import { generateObject } from 'ai';
519
+ import { claudeCode } from '@boostecom/provider';
520
+ import { z } from 'zod';
521
+
522
+ const schema = z.object({
523
+ query: z.string().describe('Requête SQL'),
524
+ explication: z.string(),
525
+ parametres: z.array(z.object({
526
+ nom: z.string(),
527
+ type: z.string(),
528
+ description: z.string(),
529
+ })).optional(),
530
+ });
531
+
532
+ async function generateSQL(naturalLanguage: string, dbSchema: string) {
533
+ const { object } = await generateObject({
534
+ model: claudeCode('opus'),
535
+ schema,
536
+ prompt: `Génère une requête SQL pour: "${naturalLanguage}"
537
+
538
+ Schéma de la base de données:
539
+ ${dbSchema}
540
+
541
+ Utilise des paramètres préparés pour éviter les injections SQL.`,
542
+ });
543
+
544
+ return object;
545
+ }
546
+
547
+ // Exemple
548
+ const dbSchema = `
549
+ CREATE TABLE users (
550
+ id INT PRIMARY KEY,
551
+ name VARCHAR(255),
552
+ email VARCHAR(255),
553
+ created_at TIMESTAMP
554
+ );
555
+
556
+ CREATE TABLE orders (
557
+ id INT PRIMARY KEY,
558
+ user_id INT REFERENCES users(id),
559
+ amount DECIMAL(10, 2),
560
+ status VARCHAR(50)
561
+ );
562
+ `;
563
+
564
+ const result = await generateSQL(
565
+ 'Trouve tous les utilisateurs qui ont commandé plus de 100€ ce mois',
566
+ dbSchema
567
+ );
568
+
569
+ console.log('📝 Requête:', result.query);
570
+ console.log('💡 Explication:', result.explication);
571
+ if (result.parametres) {
572
+ console.log('⚙️ Paramètres:', result.parametres);
573
+ }
574
+ ```
575
+
576
+ ### Analyse de logs avec stockage
577
+
578
+ ```typescript title="log-analyzer.ts"
579
+ import { generateObject } from 'ai';
580
+ import { claudeCode } from '@boostecom/provider';
581
+ import { z } from 'zod';
582
+ import { PrismaClient } from '@prisma/client';
583
+
584
+ const prisma = new PrismaClient();
585
+
586
+ const logAnalysisSchema = z.object({
587
+ niveau: z.enum(['info', 'warning', 'error', 'critical']),
588
+ resume: z.string(),
589
+ cause_probable: z.string().optional(),
590
+ action_recommandee: z.string().optional(),
591
+ tags: z.array(z.string()),
592
+ });
593
+
594
+ async function analyzeAndStoreLogs(logLines: string[]) {
595
+ for (const line of logLines) {
596
+ const { object } = await generateObject({
597
+ model: claudeCode('haiku'),
598
+ schema: logAnalysisSchema,
599
+ prompt: `Analyse cette ligne de log et extrais les informations:\n${line}`,
600
+ });
601
+
602
+ // Stocker en base de données
603
+ await prisma.logAnalysis.create({
604
+ data: {
605
+ originalLog: line,
606
+ niveau: object.niveau,
607
+ resume: object.resume,
608
+ causeProbable: object.cause_probable,
609
+ actionRecommandee: object.action_recommandee,
610
+ tags: object.tags,
611
+ analyzedAt: new Date(),
612
+ },
613
+ });
614
+ }
615
+
616
+ console.log(`✅ ${logLines.length} logs analysés et stockés`);
617
+ }
618
+
619
+ // Exemple
620
+ const logs = [
621
+ '[2025-02-07 10:23:45] ERROR: Database connection timeout after 30s',
622
+ '[2025-02-07 10:24:12] WARNING: High memory usage: 92%',
623
+ ];
624
+
625
+ await analyzeAndStoreLogs(logs);
626
+ ```
627
+
628
+ ## Intégration avec services tiers
629
+
630
+ ### Slack Bot
631
+
632
+ ```typescript title="slack-bot.ts"
633
+ import { App } from '@slack/bolt';
634
+ import { streamText } from 'ai';
635
+ import { claudeCode } from '@boostecom/provider';
636
+
637
+ const app = new App({
638
+ token: process.env.SLACK_BOT_TOKEN,
639
+ signingSecret: process.env.SLACK_SIGNING_SECRET,
640
+ });
641
+
642
+ app.message(async ({ message, say }) => {
643
+ if (message.subtype || !('text' in message)) return;
644
+
645
+ const userMessage = message.text;
646
+
647
+ // Ignorer les messages sans mention du bot
648
+ if (!userMessage.includes('<@BOT_USER_ID>')) return;
649
+
650
+ try {
651
+ const result = streamText({
652
+ model: claudeCode('sonnet'),
653
+ prompt: userMessage,
654
+ });
655
+
656
+ let response = '';
657
+ for await (const chunk of result.textStream) {
658
+ response += chunk;
659
+ }
660
+
661
+ await say(response);
662
+ } catch (error) {
663
+ await say('Désolé, une erreur est survenue.');
664
+ }
665
+ });
666
+
667
+ await app.start(process.env.PORT || 3000);
668
+ console.log('⚡️ Slack bot démarré');
669
+ ```
670
+
671
+ ## Prochaines étapes
672
+
673
+ - [Skills](/docs/skills) - Créer des compétences personnalisées
674
+ - [Agent Teams](/docs/agent-teams) - Créer des équipes d'agents spécialisés
675
+ - [Best Practices](/docs/best-practices) - Conseils et optimisations