agentic-api 1.0.6 → 2.0.26

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 (103) hide show
  1. package/README.md +118 -22
  2. package/dist/src/agents/agents.example.d.ts +3 -0
  3. package/dist/src/agents/agents.example.js +38 -0
  4. package/dist/src/agents/authentication.js +2 -0
  5. package/dist/src/agents/prompts.d.ts +2 -2
  6. package/dist/src/agents/prompts.js +112 -49
  7. package/dist/src/agents/reducer.core.d.ts +12 -0
  8. package/dist/src/agents/reducer.core.js +207 -0
  9. package/dist/src/agents/reducer.d.ts +3 -0
  10. package/dist/src/agents/reducer.example.d.ts +28 -0
  11. package/dist/src/agents/reducer.example.js +118 -0
  12. package/dist/src/agents/reducer.js +19 -0
  13. package/dist/src/agents/reducer.loaders.d.ts +34 -0
  14. package/dist/src/agents/reducer.loaders.js +122 -0
  15. package/dist/src/agents/reducer.process.d.ts +16 -0
  16. package/dist/src/agents/reducer.process.js +143 -0
  17. package/dist/src/agents/reducer.tools.d.ts +29 -0
  18. package/dist/src/agents/reducer.tools.js +157 -0
  19. package/dist/src/agents/reducer.types.d.ts +50 -0
  20. package/dist/src/agents/reducer.types.js +5 -0
  21. package/dist/src/agents/simulator.d.ts +47 -0
  22. package/dist/src/agents/simulator.executor.d.ts +26 -0
  23. package/dist/src/agents/simulator.executor.js +132 -0
  24. package/dist/src/agents/simulator.js +205 -0
  25. package/dist/src/agents/simulator.prompts.d.ts +16 -0
  26. package/dist/src/agents/simulator.prompts.js +108 -0
  27. package/dist/src/agents/simulator.types.d.ts +42 -0
  28. package/dist/src/agents/simulator.types.js +2 -0
  29. package/dist/src/agents/simulator.utils.d.ts +20 -0
  30. package/dist/src/agents/simulator.utils.js +87 -0
  31. package/dist/src/execute.d.ts +13 -6
  32. package/dist/src/execute.js +351 -85
  33. package/dist/src/index.d.ts +9 -0
  34. package/dist/src/index.js +14 -0
  35. package/dist/src/princing.openai.d.ts +9 -2
  36. package/dist/src/princing.openai.js +15 -11
  37. package/dist/src/prompts.d.ts +3 -2
  38. package/dist/src/prompts.js +159 -19
  39. package/dist/src/rag/embeddings.d.ts +103 -0
  40. package/dist/src/rag/embeddings.js +466 -0
  41. package/dist/src/rag/index.d.ts +12 -0
  42. package/dist/src/rag/index.js +40 -0
  43. package/dist/src/rag/lucene.d.ts +45 -0
  44. package/dist/src/rag/lucene.js +227 -0
  45. package/dist/src/rag/parser.d.ts +68 -0
  46. package/dist/src/rag/parser.js +192 -0
  47. package/dist/src/rag/tools.d.ts +76 -0
  48. package/dist/src/rag/tools.js +196 -0
  49. package/dist/src/rag/types.d.ts +178 -0
  50. package/dist/src/rag/types.js +21 -0
  51. package/dist/src/rag/usecase.d.ts +16 -0
  52. package/dist/src/rag/usecase.js +79 -0
  53. package/dist/src/rules/errors.d.ts +60 -0
  54. package/dist/src/rules/errors.js +97 -0
  55. package/dist/src/rules/git/git.e2e.helper.d.ts +104 -0
  56. package/dist/src/rules/git/git.e2e.helper.js +488 -0
  57. package/dist/src/rules/git/git.health.d.ts +66 -0
  58. package/dist/src/rules/git/git.health.js +354 -0
  59. package/dist/src/rules/git/git.helper.d.ts +129 -0
  60. package/dist/src/rules/git/git.helper.js +53 -0
  61. package/dist/src/rules/git/index.d.ts +6 -0
  62. package/dist/src/rules/git/index.js +76 -0
  63. package/dist/src/rules/git/repo.d.ts +128 -0
  64. package/dist/src/rules/git/repo.js +900 -0
  65. package/dist/src/rules/git/repo.pr.d.ts +137 -0
  66. package/dist/src/rules/git/repo.pr.js +589 -0
  67. package/dist/src/rules/git/repo.tools.d.ts +134 -0
  68. package/dist/src/rules/git/repo.tools.js +730 -0
  69. package/dist/src/rules/index.d.ts +8 -0
  70. package/dist/src/rules/index.js +25 -0
  71. package/dist/src/rules/messages.d.ts +17 -0
  72. package/dist/src/rules/messages.js +21 -0
  73. package/dist/src/rules/types.ctrl.d.ts +28 -0
  74. package/dist/src/rules/types.ctrl.js +2 -0
  75. package/dist/src/rules/types.d.ts +510 -0
  76. package/dist/src/rules/types.helpers.d.ts +132 -0
  77. package/dist/src/rules/types.helpers.js +2 -0
  78. package/dist/src/rules/types.js +33 -0
  79. package/dist/src/rules/user.mapper.d.ts +61 -0
  80. package/dist/src/rules/user.mapper.js +160 -0
  81. package/dist/src/rules/utils/slug.d.ts +22 -0
  82. package/dist/src/rules/utils/slug.js +35 -0
  83. package/dist/src/rules/utils.matter.d.ts +66 -0
  84. package/dist/src/rules/utils.matter.js +208 -0
  85. package/dist/src/rules/utils.slug.d.ts +22 -0
  86. package/dist/src/rules/utils.slug.js +35 -0
  87. package/dist/src/scrapper.d.ts +3 -2
  88. package/dist/src/scrapper.js +33 -37
  89. package/dist/src/stategraph/index.d.ts +8 -0
  90. package/dist/src/stategraph/index.js +21 -0
  91. package/dist/src/stategraph/stategraph.d.ts +91 -0
  92. package/dist/src/stategraph/stategraph.js +241 -0
  93. package/dist/src/stategraph/stategraph.storage.d.ts +41 -0
  94. package/dist/src/stategraph/stategraph.storage.js +166 -0
  95. package/dist/src/stategraph/types.d.ts +139 -0
  96. package/dist/src/stategraph/types.js +19 -0
  97. package/dist/src/types.d.ts +62 -39
  98. package/dist/src/types.js +53 -89
  99. package/dist/src/usecase.d.ts +4 -0
  100. package/dist/src/usecase.js +44 -0
  101. package/dist/src/utils.d.ts +12 -5
  102. package/dist/src/utils.js +30 -13
  103. package/package.json +9 -3
@@ -0,0 +1,227 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.LuceneManager = void 0;
7
+ const fs_1 = require("fs");
8
+ const path_1 = __importDefault(require("path"));
9
+ // @ts-ignore - MiniSearch sera ajouté comme dépendance
10
+ const minisearch_1 = __importDefault(require("minisearch"));
11
+ // Import des stopwords français (devra être installé comme dépendance)
12
+ let stopwordsFr = [];
13
+ try {
14
+ // Fallback si le package n'est pas disponible
15
+ const sw = require('stopwords-fr');
16
+ stopwordsFr = sw.default || sw;
17
+ }
18
+ catch (error) {
19
+ // Liste réduite de stopwords français de base
20
+ stopwordsFr = [
21
+ 'le', 'de', 'et', 'à', 'un', 'il', 'être', 'et', 'en', 'avoir', 'que', 'pour',
22
+ 'dans', 'ce', 'son', 'une', 'sur', 'avec', 'ne', 'se', 'pas', 'tout', 'plus',
23
+ 'par', 'grand', 'en', 'me', 'bien', 'elle', 'si', 'tout', 'son', 'nous', 'te',
24
+ 'ou', 'mais', 'y', 'mon', 'lui', 'nous', 'comme', 'a', 'les', 'du', 'au', 'des'
25
+ ];
26
+ }
27
+ class LuceneManager {
28
+ constructor(config, baseDir) {
29
+ this.config = {
30
+ fields: ['query'],
31
+ storeFields: ['query', 'service', 'filename'],
32
+ ...config
33
+ };
34
+ this.indexFile = config.outputFile
35
+ ? path_1.default.join(baseDir, config.outputFile)
36
+ : path_1.default.join(baseDir, 'minisearch-queries.json');
37
+ this.miniSearch = new minisearch_1.default({
38
+ fields: this.config.fields,
39
+ storeFields: this.config.storeFields,
40
+ processTerm: this.processTerm.bind(this)
41
+ });
42
+ // Charger l'index existant si disponible
43
+ this.loadIndex();
44
+ }
45
+ /**
46
+ * Traitement des termes pour la recherche
47
+ */
48
+ processTerm(term) {
49
+ // Ignorer les stopwords et les termes trop courts
50
+ if (stopwordsFr.includes(term.toLowerCase()) || term.length <= 2) {
51
+ return null;
52
+ }
53
+ return term.toLowerCase();
54
+ }
55
+ /**
56
+ * Charge un index existant
57
+ */
58
+ loadIndex() {
59
+ if ((0, fs_1.existsSync)(this.indexFile)) {
60
+ try {
61
+ const indexData = JSON.parse((0, fs_1.readFileSync)(this.indexFile, 'utf8'));
62
+ this.miniSearch = minisearch_1.default.loadJSON(JSON.stringify(indexData), {
63
+ fields: this.config.fields,
64
+ storeFields: this.config.storeFields,
65
+ processTerm: this.processTerm.bind(this)
66
+ });
67
+ console.log('Index Lucene chargé:', this.indexFile);
68
+ }
69
+ catch (error) {
70
+ console.error('Erreur lors du chargement de l\'index Lucene:', error);
71
+ }
72
+ }
73
+ }
74
+ /**
75
+ * Construit l'index Lucene à partir des fichiers de requêtes
76
+ */
77
+ async buildIndex(queriesDir) {
78
+ const queriesPath = queriesDir || this.config.queriesDir || './queries/';
79
+ if (!(0, fs_1.existsSync)(queriesPath)) {
80
+ throw new Error(`Répertoire des requêtes non trouvé: ${queriesPath}`);
81
+ }
82
+ // Lister tous les fichiers JSON dans le répertoire
83
+ const jsonFiles = (0, fs_1.readdirSync)(queriesPath)
84
+ .filter(file => file.endsWith('.json'))
85
+ .filter(file => !file.includes('unauthorized') && !file.startsWith('skip.'))
86
+ .map(file => path_1.default.join(queriesPath, file));
87
+ if (jsonFiles.length === 0) {
88
+ throw new Error(`Aucun fichier JSON trouvé dans: ${queriesPath}`);
89
+ }
90
+ let indexId = 1;
91
+ const documents = [];
92
+ const services = new Set();
93
+ for (const file of jsonFiles) {
94
+ const filename = path_1.default.basename(file, path_1.default.extname(file));
95
+ // Le service est décrit dans le nom du fichier (premier mot avant le premier "-")
96
+ const service = filename.split('-')[0];
97
+ services.add(service);
98
+ process.stdout.write(`Préparation index Lucene pour ${filename} : `);
99
+ try {
100
+ const content = JSON.parse((0, fs_1.readFileSync)(file, 'utf8'));
101
+ if (!Array.isArray(content) || content.length === 0) {
102
+ console.log('❌ Aucune requête trouvée dans', file);
103
+ continue;
104
+ }
105
+ for (const coverage of content) {
106
+ if (coverage.question) {
107
+ documents.push({
108
+ id: (indexId++).toString(),
109
+ query: coverage.question,
110
+ service,
111
+ filename
112
+ });
113
+ process.stdout.write('.');
114
+ }
115
+ }
116
+ console.log(' ✅');
117
+ }
118
+ catch (error) {
119
+ console.log(`❌ Erreur lors de la lecture de ${file}:`, error);
120
+ }
121
+ }
122
+ if (documents.length === 0) {
123
+ throw new Error('Aucun document à indexer');
124
+ }
125
+ // Construire l'index
126
+ console.log(`Construction de l'index Lucene avec ${documents.length} documents...`);
127
+ this.miniSearch.addAll(documents);
128
+ // Sauvegarder l'index
129
+ this.saveIndex();
130
+ console.log(`Index Lucene créé avec succès: ${documents.length} requêtes, ${services.size} services`);
131
+ return;
132
+ }
133
+ /**
134
+ * Sauvegarde l'index
135
+ */
136
+ saveIndex() {
137
+ try {
138
+ const indexData = this.miniSearch.toJSON();
139
+ (0, fs_1.writeFileSync)(this.indexFile, JSON.stringify(indexData), { encoding: 'utf8', flag: 'w' });
140
+ console.log('Index Lucene sauvegardé:', this.indexFile);
141
+ }
142
+ catch (error) {
143
+ console.error('Erreur lors de la sauvegarde de l\'index Lucene:', error);
144
+ }
145
+ }
146
+ /**
147
+ * Recherche dans l'index Lucene
148
+ */
149
+ // search(query: string, options?: {
150
+ // limit?: number;
151
+ // fuzzy?: boolean | number;
152
+ // prefix?: boolean;
153
+ // filter?: (result: LuceneIndexDocument & { score: number }) => boolean;
154
+ // }): LuceneSearchResult {
155
+ // const startTime = Date.now();
156
+ // const searchOptions = {
157
+ // fuzzy: options?.fuzzy ?? 0.2,
158
+ // prefix: options?.prefix ?? true,
159
+ // ...options
160
+ // };
161
+ // try {
162
+ // const rawResults = this.miniSearch.search(query, searchOptions as any);
163
+ // let results = rawResults.map((result: any) => ({
164
+ // id: result.id,
165
+ // query: result.query,
166
+ // service: result.service,
167
+ // filename: result.filename,
168
+ // score: result.score
169
+ // }));
170
+ // // Appliquer un filtre personnalisé si fourni
171
+ // if (options?.filter) {
172
+ // results = results.filter(options.filter);
173
+ // }
174
+ // // Limiter les résultats
175
+ // if (options?.limit) {
176
+ // results = results.slice(0, options.limit);
177
+ // }
178
+ // return {
179
+ // results,
180
+ // searchTime: Date.now() - startTime
181
+ // };
182
+ // } catch (error) {
183
+ // console.error('Erreur lors de la recherche Lucene:', error);
184
+ // return {
185
+ // results: [],
186
+ // searchTime: Date.now() - startTime
187
+ // };
188
+ // }
189
+ // }
190
+ /**
191
+ * Obtient les statistiques de l'index
192
+ */
193
+ getStats() {
194
+ const documentCount = this.miniSearch.documentCount;
195
+ const services = new Set();
196
+ // Parcourir tous les documents pour compter les services
197
+ try {
198
+ // Note: MiniSearch ne fournit pas directement accès aux documents
199
+ // Cette méthode pourrait nécessiter une amélioration
200
+ const indexData = this.miniSearch.toJSON();
201
+ if (indexData && typeof indexData === 'object') {
202
+ // Estimation basée sur la taille de l'index sérialisé
203
+ const indexSizeKB = Math.round(JSON.stringify(indexData).length / 1024);
204
+ return {
205
+ totalDocuments: documentCount,
206
+ totalServices: services.size,
207
+ indexSize: indexSizeKB > 1024 ? `${Math.round(indexSizeKB / 1024)}MB` : `${indexSizeKB}KB`
208
+ };
209
+ }
210
+ }
211
+ catch (error) {
212
+ console.error('Erreur lors du calcul des statistiques:', error);
213
+ }
214
+ return {
215
+ totalDocuments: documentCount,
216
+ totalServices: 0,
217
+ indexSize: 'inconnu'
218
+ };
219
+ }
220
+ /**
221
+ * Vérifie si l'index est prêt
222
+ */
223
+ isReady() {
224
+ return this.miniSearch.documentCount > 0;
225
+ }
226
+ }
227
+ exports.LuceneManager = LuceneManager;
@@ -0,0 +1,68 @@
1
+ import { ParsedDocument, DocumentSection } from './types';
2
+ /**
3
+ * Découpe le contenu d'un document en sections séparées par '---'
4
+ *
5
+ * @param content Contenu du document
6
+ * @param filename Nom du fichier (pour le titre par défaut)
7
+ * @returns Sections et header du document
8
+ */
9
+ export declare function getSections(content: string, filename: string): ParsedDocument;
10
+ /**
11
+ * Récupère une section spécifique d'un document à partir de son ID
12
+ *
13
+ * @param id - ID numérique du document dans l'index
14
+ * @param ids - Mapping des IDs vers les noms de fichiers avec références de sections
15
+ * @param prefix - Chemin de base vers les documents
16
+ * @returns Objet contenant la source, le titre et le contenu de la section
17
+ * @throws Error si l'ID de document est invalide ou si la section n'existe pas
18
+ */
19
+ export declare const getDocumentBySection: (id: number, ids: any, prefix: string) => {
20
+ source: any;
21
+ content: string;
22
+ title?: undefined;
23
+ } | {
24
+ source: any;
25
+ title: string | undefined;
26
+ content: DocumentSection;
27
+ };
28
+ /**
29
+ * Normalise un vecteur avec la norme L2
30
+ *
31
+ * @param vector Vecteur à normaliser
32
+ * @returns Vecteur normalisé
33
+ */
34
+ export declare function l2Normalize(vector: number[]): number[];
35
+ /**
36
+ * Génère un slug unique pour un fichier
37
+ *
38
+ * @param filename Nom du fichier
39
+ * @param sectionIndex Index de la section (optionnel)
40
+ * @returns Slug unique
41
+ */
42
+ export declare function generateDocumentRef(filename: string, sectionIndex?: number): string;
43
+ /**
44
+ * Parse une référence de document pour extraire le nom de fichier et l'index de section
45
+ *
46
+ * @param ref Référence du document (filename#section-X)
47
+ * @returns Nom de fichier et index de section
48
+ */
49
+ export declare function parseDocumentRef(ref: string): {
50
+ filename: string;
51
+ sectionIndex?: number;
52
+ };
53
+ /**
54
+ * Nettoie un bloc Markdown : supprime les préfixes « Titre: » et « Section: »
55
+ * (placés en début de ligne, avec ou sans espaces avant/après les deux-points).
56
+ *
57
+ * @param input Texte brut à nettoyer
58
+ * @returns Texte sans les entités Titre: et Section:
59
+ */
60
+ export declare function sectionParseValues(input: string): string;
61
+ export declare function sectionParseKey(key: string, input: string): string | null;
62
+ /**
63
+ * Supprime les blocs <thinking> du contenu généré par l'IA
64
+ *
65
+ * @param content Contenu markdown avec potentiels blocs <thinking>
66
+ * @returns Contenu nettoyé sans les blocs <thinking>
67
+ */
68
+ export declare function removeThinkingBlocks(content: string): string;
@@ -0,0 +1,192 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getDocumentBySection = void 0;
7
+ exports.getSections = getSections;
8
+ exports.l2Normalize = l2Normalize;
9
+ exports.generateDocumentRef = generateDocumentRef;
10
+ exports.parseDocumentRef = parseDocumentRef;
11
+ exports.sectionParseValues = sectionParseValues;
12
+ exports.sectionParseKey = sectionParseKey;
13
+ exports.removeThinkingBlocks = removeThinkingBlocks;
14
+ const fs_1 = require("fs");
15
+ const path_1 = __importDefault(require("path"));
16
+ const rules_1 = require("../rules");
17
+ /**
18
+ * Découpe le contenu d'un document en sections séparées par '---'
19
+ *
20
+ * @param content Contenu du document
21
+ * @param filename Nom du fichier (pour le titre par défaut)
22
+ * @returns Sections et header du document
23
+ */
24
+ function getSections(content, filename) {
25
+ // IMPORTANT: Cette fonction traite les fichiers transformés par RAGGenerator
26
+ // qui utilisent le format "Titre: ..." et "Section: ..." délimité par "---"
27
+ // Vérifier si le contenu contient un front-matter,
28
+ // celui-ci contient le nom du fichier d'origine et le nom du service!
29
+ let { matter, content: contentWithoutMatter } = (0, rules_1.matterParse)(content);
30
+ // imprimer une alarm
31
+ if (matter?.mergeBase && matter?.createdBy) {
32
+ console.log('🔔 No standard matter found in file:', matter);
33
+ }
34
+ // S'assurer que matter contient au minimum filename et title
35
+ matter = {
36
+ ...matter,
37
+ filename,
38
+ title: matter.title || filename // Utiliser le filename comme titre par défaut
39
+ };
40
+ content = contentWithoutMatter || content;
41
+ //
42
+ // le contenu est toujours sans le front-matter!
43
+ const rawSections = content.split('---').map(section => section.trim());
44
+ if (!rawSections.length) {
45
+ return {
46
+ filename,
47
+ sections: [],
48
+ content,
49
+ matter
50
+ };
51
+ }
52
+ // Transformer les sections brutes en DocumentSection
53
+ const sections = rawSections
54
+ .map((content, index) => ({
55
+ content: content.trim(),
56
+ index,
57
+ lines: content.split('\n').length,
58
+ title: sectionParseKey('titre', content) || undefined
59
+ }))
60
+ .filter(section => section.lines > 2); // Filtrer les sections trop courtes
61
+ //
62
+ // le matter contient les informations du fichier d'origine! (service, responssable, fichier, etc.)
63
+ return {
64
+ filename,
65
+ sections,
66
+ content,
67
+ matter
68
+ };
69
+ }
70
+ /**
71
+ * Récupère une section spécifique d'un document à partir de son ID
72
+ *
73
+ * @param id - ID numérique du document dans l'index
74
+ * @param ids - Mapping des IDs vers les noms de fichiers avec références de sections
75
+ * @param prefix - Chemin de base vers les documents
76
+ * @returns Objet contenant la source, le titre et le contenu de la section
77
+ * @throws Error si l'ID de document est invalide ou si la section n'existe pas
78
+ */
79
+ const getDocumentBySection = (id, ids, prefix) => {
80
+ const fullname = ids[id + ''];
81
+ const [filename, ref] = fullname?.split('#') || [];
82
+ if (!filename) {
83
+ console.log('❌❌ Invalid document id :' + fullname, id);
84
+ throw new Error('Invalid document id :' + fullname);
85
+ }
86
+ const content = (0, fs_1.readFileSync)(path_1.default.join(prefix, filename), 'utf8');
87
+ const { sections } = getSections(content, filename);
88
+ if (!sections.length) {
89
+ return {
90
+ source: fullname,
91
+ content: 'Le document n\'est plus disponible'
92
+ };
93
+ }
94
+ // Parse number of 'section-123'
95
+ const sectionNumber = parseInt(ref.match(/\d+/)[0]);
96
+ const section = sections[sectionNumber];
97
+ // console.log('--- DBG getDocument : section', sectionNumber, section?.length);
98
+ return {
99
+ source: fullname,
100
+ title: section.title,
101
+ content: section
102
+ };
103
+ };
104
+ exports.getDocumentBySection = getDocumentBySection;
105
+ // extractSectionTitle supprimée - remplacée par sectionParseKey('titre', content)
106
+ /**
107
+ * Normalise un vecteur avec la norme L2
108
+ *
109
+ * @param vector Vecteur à normaliser
110
+ * @returns Vecteur normalisé
111
+ */
112
+ function l2Normalize(vector) {
113
+ const norm = Math.sqrt(vector.reduce((sum, val) => sum + val * val, 0));
114
+ return vector.map(val => val / norm);
115
+ }
116
+ /**
117
+ * Génère un slug unique pour un fichier
118
+ *
119
+ * @param filename Nom du fichier
120
+ * @param sectionIndex Index de la section (optionnel)
121
+ * @returns Slug unique
122
+ */
123
+ function generateDocumentRef(filename, sectionIndex) {
124
+ const baseRef = filename.replace(/\.[^/.]+$/, ''); // Retirer l'extension
125
+ return sectionIndex !== undefined ? `${baseRef}#section-${sectionIndex}` : baseRef;
126
+ }
127
+ /**
128
+ * Parse une référence de document pour extraire le nom de fichier et l'index de section
129
+ *
130
+ * @param ref Référence du document (filename#section-X)
131
+ * @returns Nom de fichier et index de section
132
+ */
133
+ function parseDocumentRef(ref) {
134
+ const [filename, sectionPart] = ref.split('#');
135
+ if (!sectionPart) {
136
+ return { filename };
137
+ }
138
+ const match = sectionPart.match(/section-(\d+)/);
139
+ if (match) {
140
+ return { filename, sectionIndex: parseInt(match[1]) };
141
+ }
142
+ return { filename };
143
+ }
144
+ /**
145
+ * Nettoie un bloc Markdown : supprime les préfixes « Titre: » et « Section: »
146
+ * (placés en début de ligne, avec ou sans espaces avant/après les deux-points).
147
+ *
148
+ * @param input Texte brut à nettoyer
149
+ * @returns Texte sans les entités Titre: et Section:
150
+ */
151
+ function sectionParseValues(input) {
152
+ return input
153
+ // 1. Retirer les lignes vides en tête pour éviter des espaces résiduels
154
+ .replace(/^\s*\n/, '')
155
+ // 2. Supprimer « Titre: » ou « Section: » exclusivement en début de ligne
156
+ .replace(/^\s*(Titre|Section)\s*:\s*/gim, '')
157
+ // 3. Supprimer les espaces superflus qui pourraient rester
158
+ .trim();
159
+ }
160
+ function sectionParseKey(key, input) {
161
+ // Normaliser la clé recherchée en minuscules
162
+ const normalizedKey = key.toLowerCase().trim();
163
+ // Diviser le texte en lignes
164
+ const lines = input.split('\n');
165
+ // Chercher la ligne qui commence par la clé (case-insensitive)
166
+ for (const line of lines) {
167
+ const trimmedLine = line.trim();
168
+ // Vérifier si la ligne contient un ':'
169
+ if (trimmedLine.includes(':')) {
170
+ const [lineKey, ...valueParts] = trimmedLine.split(':');
171
+ const normalizedLineKey = lineKey.trim().toLowerCase();
172
+ // Comparer les clés en mode case-insensitive
173
+ if (normalizedLineKey === normalizedKey) {
174
+ const value = valueParts.join(':').trim();
175
+ // Retourner la valeur, même si elle est vide
176
+ return value;
177
+ }
178
+ }
179
+ }
180
+ // Si la clé n'est pas trouvée, lever une exception
181
+ // throw new Error(`Clé "${key}" non trouvée dans la section`);
182
+ return null;
183
+ }
184
+ /**
185
+ * Supprime les blocs <thinking> du contenu généré par l'IA
186
+ *
187
+ * @param content Contenu markdown avec potentiels blocs <thinking>
188
+ * @returns Contenu nettoyé sans les blocs <thinking>
189
+ */
190
+ function removeThinkingBlocks(content) {
191
+ return content.replace(/<thinking>[\s\S]*?<\/thinking>/g, '').trim();
192
+ }
@@ -0,0 +1,76 @@
1
+ import OpenAI from 'openai';
2
+ import { RAGConfig } from './types';
3
+ /**
4
+ * Crée les outils RAG pour un agent
5
+ */
6
+ declare const createTools: (openai: OpenAI, config: RAGConfig) => {
7
+ toolsReferencesContent: {
8
+ type: "function";
9
+ function: {
10
+ name: string;
11
+ description: string;
12
+ parameters: {
13
+ type: string;
14
+ properties: {
15
+ service: {
16
+ type: string;
17
+ description: string;
18
+ };
19
+ source: {
20
+ type: string;
21
+ description: string;
22
+ };
23
+ };
24
+ required: never[];
25
+ additionalProperties: boolean;
26
+ };
27
+ };
28
+ };
29
+ toolsKnowledge: {
30
+ type: "function";
31
+ function: {
32
+ name: string;
33
+ description: string;
34
+ parameters: {
35
+ type: string;
36
+ properties: {
37
+ question: {
38
+ type: string;
39
+ description: string;
40
+ };
41
+ justification: {
42
+ type: string;
43
+ description: string;
44
+ };
45
+ action_suivante: {
46
+ type: string;
47
+ description: string;
48
+ };
49
+ };
50
+ required: string[];
51
+ additionalProperties: boolean;
52
+ };
53
+ };
54
+ };
55
+ lookupReferencesContent: ({ service, source }: {
56
+ service?: string;
57
+ source?: string;
58
+ }) => Promise<{
59
+ content: string;
60
+ }>;
61
+ lookupKnowledge: (args: any, debug?: boolean) => Promise<{
62
+ content: string;
63
+ documents?: undefined;
64
+ scores?: undefined;
65
+ } | {
66
+ documents: {
67
+ id: number;
68
+ ref: string;
69
+ score: number;
70
+ content: string;
71
+ }[];
72
+ scores: number[];
73
+ content?: undefined;
74
+ }>;
75
+ };
76
+ export { createTools };