agentic-api 2.0.31 → 2.0.314
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.
- package/dist/src/agents/agents.example.js +21 -22
- package/dist/src/agents/authentication.js +1 -2
- package/dist/src/agents/prompts.d.ts +5 -4
- package/dist/src/agents/prompts.js +42 -87
- package/dist/src/agents/reducer.core.d.ts +24 -2
- package/dist/src/agents/reducer.core.js +125 -35
- package/dist/src/agents/reducer.loaders.d.ts +55 -1
- package/dist/src/agents/reducer.loaders.js +114 -1
- package/dist/src/agents/reducer.types.d.ts +45 -2
- package/dist/src/agents/semantic.js +1 -2
- package/dist/src/agents/simulator.d.ts +4 -0
- package/dist/src/agents/simulator.executor.d.ts +5 -1
- package/dist/src/agents/simulator.executor.js +41 -9
- package/dist/src/agents/simulator.js +86 -28
- package/dist/src/agents/simulator.prompts.d.ts +3 -2
- package/dist/src/agents/simulator.prompts.js +52 -78
- package/dist/src/agents/simulator.types.d.ts +20 -5
- package/dist/src/agents/simulator.utils.d.ts +7 -2
- package/dist/src/agents/simulator.utils.js +33 -11
- package/dist/src/agents/system.js +1 -2
- package/dist/src/execute.d.ts +17 -3
- package/dist/src/execute.js +156 -158
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/{princing.openai.d.ts → pricing.llm.d.ts} +6 -0
- package/dist/src/pricing.llm.js +234 -0
- package/dist/src/prompts.d.ts +13 -4
- package/dist/src/prompts.js +221 -114
- package/dist/src/rag/embeddings.d.ts +36 -18
- package/dist/src/rag/embeddings.js +125 -128
- package/dist/src/rag/index.d.ts +5 -5
- package/dist/src/rag/index.js +14 -17
- package/dist/src/rag/parser.d.ts +2 -1
- package/dist/src/rag/parser.js +11 -14
- package/dist/src/rag/rag.examples.d.ts +27 -0
- package/dist/src/rag/rag.examples.js +151 -0
- package/dist/src/rag/rag.manager.d.ts +383 -0
- package/dist/src/rag/rag.manager.js +1378 -0
- package/dist/src/rag/types.d.ts +128 -12
- package/dist/src/rag/types.js +100 -1
- package/dist/src/rag/usecase.d.ts +37 -0
- package/dist/src/rag/usecase.js +96 -7
- package/dist/src/rules/git/git.e2e.helper.js +1 -0
- package/dist/src/rules/git/git.health.d.ts +57 -0
- package/dist/src/rules/git/git.health.js +281 -1
- package/dist/src/rules/git/index.d.ts +2 -2
- package/dist/src/rules/git/index.js +12 -1
- package/dist/src/rules/git/repo.d.ts +117 -0
- package/dist/src/rules/git/repo.js +536 -0
- package/dist/src/rules/git/repo.tools.d.ts +22 -1
- package/dist/src/rules/git/repo.tools.js +50 -1
- package/dist/src/rules/types.d.ts +16 -14
- package/dist/src/rules/utils.matter.d.ts +0 -4
- package/dist/src/rules/utils.matter.js +26 -7
- package/dist/src/scrapper.d.ts +15 -22
- package/dist/src/scrapper.js +57 -110
- package/dist/src/stategraph/index.d.ts +1 -1
- package/dist/src/stategraph/stategraph.d.ts +31 -2
- package/dist/src/stategraph/stategraph.js +93 -6
- package/dist/src/stategraph/stategraph.storage.js +4 -0
- package/dist/src/stategraph/types.d.ts +22 -0
- package/dist/src/types.d.ts +4 -2
- package/dist/src/types.js +1 -1
- package/dist/src/usecase.d.ts +11 -2
- package/dist/src/usecase.js +27 -35
- package/dist/src/utils.d.ts +32 -18
- package/dist/src/utils.js +60 -126
- package/package.json +7 -2
- package/dist/src/agents/digestor.test.d.ts +0 -1
- package/dist/src/agents/digestor.test.js +0 -45
- package/dist/src/agents/reducer.example.d.ts +0 -28
- package/dist/src/agents/reducer.example.js +0 -118
- package/dist/src/agents/reducer.process.d.ts +0 -16
- package/dist/src/agents/reducer.process.js +0 -143
- package/dist/src/agents/reducer.tools.d.ts +0 -29
- package/dist/src/agents/reducer.tools.js +0 -157
- package/dist/src/agents/simpleExample.d.ts +0 -3
- package/dist/src/agents/simpleExample.js +0 -38
- package/dist/src/agents/system-review.d.ts +0 -5
- package/dist/src/agents/system-review.js +0 -181
- package/dist/src/agents/systemReview.d.ts +0 -4
- package/dist/src/agents/systemReview.js +0 -22
- package/dist/src/princing.openai.js +0 -54
- package/dist/src/rag/tools.d.ts +0 -76
- package/dist/src/rag/tools.js +0 -196
- package/dist/src/rules/user.mapper.d.ts +0 -61
- package/dist/src/rules/user.mapper.js +0 -160
- package/dist/src/rules/utils/slug.d.ts +0 -22
- package/dist/src/rules/utils/slug.js +0 -35
package/dist/src/rag/types.d.ts
CHANGED
|
@@ -44,16 +44,6 @@ export interface RAGMetadata {
|
|
|
44
44
|
config: RAGConfig;
|
|
45
45
|
/** Mapping ID → référence document/section */
|
|
46
46
|
documents: Record<string, DocumentReference>;
|
|
47
|
-
/**
|
|
48
|
-
* Dernier identifiant documentaire attribué.
|
|
49
|
-
* Utilisé pour générer un ID documentaire stable (matter.id) indépendant du nom de fichier.
|
|
50
|
-
*/
|
|
51
|
-
docLastID?: number;
|
|
52
|
-
/** Checkpoint avec le hash du dernier commit de la branche */
|
|
53
|
-
checkpoint: {
|
|
54
|
-
branch: string;
|
|
55
|
-
hash: string;
|
|
56
|
-
};
|
|
57
47
|
/** Statistiques de l'index */
|
|
58
48
|
stats: {
|
|
59
49
|
totalDocuments: number;
|
|
@@ -98,13 +88,25 @@ export interface DocumentSection {
|
|
|
98
88
|
export interface ParsedDocument {
|
|
99
89
|
/** Nom du fichier source dans GIT*/
|
|
100
90
|
filename: string;
|
|
101
|
-
/** Métadonnées du front-matter */
|
|
102
|
-
matter:
|
|
91
|
+
/** Métadonnées du front-matter (id et title obligatoires) */
|
|
92
|
+
matter: RAGMatter;
|
|
103
93
|
/** Contenu sans le front-matter */
|
|
104
94
|
content: string;
|
|
105
95
|
/** Sections du document */
|
|
106
96
|
sections: DocumentSection[];
|
|
107
97
|
}
|
|
98
|
+
/**
|
|
99
|
+
* Métadonnées du front-matter d'un document RAG
|
|
100
|
+
* IMPORTANT: id et title sont obligatoires
|
|
101
|
+
*/
|
|
102
|
+
export interface RAGMatter {
|
|
103
|
+
/** Identifiant documentaire stable (entier positif, max 2^32-1 pour hnswlib) */
|
|
104
|
+
id: number;
|
|
105
|
+
/** Titre descriptif du document */
|
|
106
|
+
title: string;
|
|
107
|
+
/** Propriétés optionnelles supplémentaires */
|
|
108
|
+
[key: string]: string | Date | number | boolean;
|
|
109
|
+
}
|
|
108
110
|
export interface RAGRef {
|
|
109
111
|
/** ID du document */
|
|
110
112
|
id: number;
|
|
@@ -158,6 +160,32 @@ export interface DocumentQueries {
|
|
|
158
160
|
queries: UserQuery[];
|
|
159
161
|
/** Coût de l'extraction */
|
|
160
162
|
cost: number;
|
|
163
|
+
/** fingerprint content hash (SHA-256 du contenu source) - Optionnel pour rétrocompatibilité */
|
|
164
|
+
fingerprint?: string;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Résultat de la construction d'un index vectoriel
|
|
168
|
+
*
|
|
169
|
+
* Retourné par Embeddings.indexFromDocuments() pour que RAGManager
|
|
170
|
+
* puisse créer les métadonnées complètes du RAG.
|
|
171
|
+
*
|
|
172
|
+
* Cette interface sépare clairement les responsabilités :
|
|
173
|
+
* - Embeddings : Construction de l'index vectoriel
|
|
174
|
+
* - RAGManager : Gestion des métadonnées et du cycle de vie
|
|
175
|
+
*/
|
|
176
|
+
export interface IndexBuildResult {
|
|
177
|
+
/** Nombre total de vecteurs indexés */
|
|
178
|
+
totalVectors: number;
|
|
179
|
+
/** Dimensions des vecteurs */
|
|
180
|
+
vectorDimensions: number;
|
|
181
|
+
/** Références des documents avec leurs métadonnées */
|
|
182
|
+
documents: Record<string, DocumentReference>;
|
|
183
|
+
/** Mapping ID -> ref des sections */
|
|
184
|
+
mapping: Record<string, string>;
|
|
185
|
+
/** Tag de version généré */
|
|
186
|
+
tag: string;
|
|
187
|
+
/** Version du format */
|
|
188
|
+
version: string;
|
|
161
189
|
}
|
|
162
190
|
/** Interface pour le fichier de mapping des IDs */
|
|
163
191
|
export interface RAGMapping {
|
|
@@ -176,3 +204,91 @@ export interface RAGMapping {
|
|
|
176
204
|
* Génère un tag de version au format vYYYYMMDD
|
|
177
205
|
*/
|
|
178
206
|
export declare function generateVersionTag(): string;
|
|
207
|
+
/**
|
|
208
|
+
* Contraintes pour les IDs hnswlib-node
|
|
209
|
+
* Les labels dans hnswlib sont des entiers non-signés 32 bits
|
|
210
|
+
*/
|
|
211
|
+
export declare const HNSW_ID_CONSTRAINTS: {
|
|
212
|
+
readonly MIN: 0;
|
|
213
|
+
readonly MAX: 4294967295;
|
|
214
|
+
readonly RESERVED_START: 0;
|
|
215
|
+
readonly RESERVED_END: 999;
|
|
216
|
+
};
|
|
217
|
+
/**
|
|
218
|
+
* Vérifie si un ID est valide pour hnswlib-node
|
|
219
|
+
*
|
|
220
|
+
* Les contraintes sont :
|
|
221
|
+
* - Doit être un entier
|
|
222
|
+
* - Doit être >= 0
|
|
223
|
+
* - Doit être <= 2^32-1 (4294967295)
|
|
224
|
+
* - Doit être > 999 (pour éviter les IDs réservés)
|
|
225
|
+
*
|
|
226
|
+
* @param id L'ID à vérifier
|
|
227
|
+
* @returns true si l'ID est valide, false sinon
|
|
228
|
+
*
|
|
229
|
+
* @example
|
|
230
|
+
* ```typescript
|
|
231
|
+
* isValidHNSWID(1000) // true
|
|
232
|
+
* isValidHNSWID(999) // false (réservé)
|
|
233
|
+
* isValidHNSWID(-1) // false (négatif)
|
|
234
|
+
* isValidHNSWID(1.5) // false (pas un entier)
|
|
235
|
+
* ```
|
|
236
|
+
*/
|
|
237
|
+
export declare function isValidHNSWID(id: number): boolean;
|
|
238
|
+
/**
|
|
239
|
+
* Vérifie si les métadonnées RAGMatter sont valides
|
|
240
|
+
*
|
|
241
|
+
* Les contraintes sont :
|
|
242
|
+
* - id et title doivent être définis
|
|
243
|
+
* - id doit être un entier valide pour hnswlib (> 999, < 2^32)
|
|
244
|
+
* - title doit être une chaîne non vide
|
|
245
|
+
*
|
|
246
|
+
* @param matter Les métadonnées à vérifier
|
|
247
|
+
* @returns true si les métadonnées sont valides, false sinon
|
|
248
|
+
* @throws Error avec un message descriptif si les métadonnées sont invalides
|
|
249
|
+
*
|
|
250
|
+
* @example
|
|
251
|
+
* ```typescript
|
|
252
|
+
* isValidRAGMatter({ id: 1000, title: 'Mon document' }) // true
|
|
253
|
+
* isValidRAGMatter({ id: 999, title: 'Test' }) // throws (ID réservé)
|
|
254
|
+
* isValidRAGMatter({ id: 1000, title: '' }) // throws (titre vide)
|
|
255
|
+
* ```
|
|
256
|
+
*/
|
|
257
|
+
export declare function isValidRAGMatter(matter: any): matter is RAGMatter;
|
|
258
|
+
/** Interface pour une entrée du registre RAG */
|
|
259
|
+
export interface RAGRegistryEntry {
|
|
260
|
+
/** Identifiant unique (slug) */
|
|
261
|
+
name: string;
|
|
262
|
+
/** Chemin vers le dossier du RAGConfig (tempPath si building, destDir si active) */
|
|
263
|
+
configPath: string;
|
|
264
|
+
/** Chemin de destination finale (utilisé pour remplacer configPath après build) */
|
|
265
|
+
destDir?: string;
|
|
266
|
+
/** Statut du RAG */
|
|
267
|
+
status: 'active' | 'building' | 'archived' | 'error' | 'paused';
|
|
268
|
+
/** Description optionnelle du RAG */
|
|
269
|
+
description?: string;
|
|
270
|
+
/** Hash du dernier commit Git (checkpoint pour builds incrémentaux) */
|
|
271
|
+
checkpoint?: string;
|
|
272
|
+
}
|
|
273
|
+
/** Interface pour le registre des RAG */
|
|
274
|
+
export interface RAGRegistry {
|
|
275
|
+
/** Version du registre */
|
|
276
|
+
version: string;
|
|
277
|
+
/** Liste des RAG disponibles */
|
|
278
|
+
registries: Record<string, RAGRegistryEntry>;
|
|
279
|
+
/** RAG par défaut (par défaut: 'RAGRegistry') */
|
|
280
|
+
defaultName?: string;
|
|
281
|
+
}
|
|
282
|
+
/** Configuration du gestionnaire RAG */
|
|
283
|
+
export interface RAGManagerConfig {
|
|
284
|
+
/** Répertoire de base du registre */
|
|
285
|
+
baseDir: string;
|
|
286
|
+
/** Répertoire temporaire pour les constructions */
|
|
287
|
+
tempDir?: string;
|
|
288
|
+
/** Répertoire d'archives */
|
|
289
|
+
archiveDir?: string;
|
|
290
|
+
/** Nombre maximum d'archives par RAG */
|
|
291
|
+
maxArchives?: number;
|
|
292
|
+
/** Mode verbose */
|
|
293
|
+
verbose?: boolean;
|
|
294
|
+
}
|
package/dist/src/rag/types.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.RAG_FILES = void 0;
|
|
3
|
+
exports.HNSW_ID_CONSTRAINTS = exports.RAG_FILES = void 0;
|
|
4
4
|
exports.generateVersionTag = generateVersionTag;
|
|
5
|
+
exports.isValidHNSWID = isValidHNSWID;
|
|
6
|
+
exports.isValidRAGMatter = isValidRAGMatter;
|
|
5
7
|
// Constantes pour les noms de fichiers RAG
|
|
6
8
|
exports.RAG_FILES = {
|
|
7
9
|
VECTORS: 'rag-hnsw.dat',
|
|
@@ -19,3 +21,100 @@ function generateVersionTag() {
|
|
|
19
21
|
const day = String(today.getDate()).padStart(2, '0');
|
|
20
22
|
return `v${year}${month}${day}`;
|
|
21
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Contraintes pour les IDs hnswlib-node
|
|
26
|
+
* Les labels dans hnswlib sont des entiers non-signés 32 bits
|
|
27
|
+
*/
|
|
28
|
+
exports.HNSW_ID_CONSTRAINTS = {
|
|
29
|
+
MIN: 0,
|
|
30
|
+
MAX: 4294967295, // 2^32 - 1
|
|
31
|
+
RESERVED_START: 0,
|
|
32
|
+
RESERVED_END: 999 // IDs réservés pour usage interne
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Vérifie si un ID est valide pour hnswlib-node
|
|
36
|
+
*
|
|
37
|
+
* Les contraintes sont :
|
|
38
|
+
* - Doit être un entier
|
|
39
|
+
* - Doit être >= 0
|
|
40
|
+
* - Doit être <= 2^32-1 (4294967295)
|
|
41
|
+
* - Doit être > 999 (pour éviter les IDs réservés)
|
|
42
|
+
*
|
|
43
|
+
* @param id L'ID à vérifier
|
|
44
|
+
* @returns true si l'ID est valide, false sinon
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```typescript
|
|
48
|
+
* isValidHNSWID(1000) // true
|
|
49
|
+
* isValidHNSWID(999) // false (réservé)
|
|
50
|
+
* isValidHNSWID(-1) // false (négatif)
|
|
51
|
+
* isValidHNSWID(1.5) // false (pas un entier)
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
function isValidHNSWID(id) {
|
|
55
|
+
return (Number.isInteger(id) &&
|
|
56
|
+
id >= exports.HNSW_ID_CONSTRAINTS.MIN &&
|
|
57
|
+
id <= exports.HNSW_ID_CONSTRAINTS.MAX &&
|
|
58
|
+
id > exports.HNSW_ID_CONSTRAINTS.RESERVED_END);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Vérifie si les métadonnées RAGMatter sont valides
|
|
62
|
+
*
|
|
63
|
+
* Les contraintes sont :
|
|
64
|
+
* - id et title doivent être définis
|
|
65
|
+
* - id doit être un entier valide pour hnswlib (> 999, < 2^32)
|
|
66
|
+
* - title doit être une chaîne non vide
|
|
67
|
+
*
|
|
68
|
+
* @param matter Les métadonnées à vérifier
|
|
69
|
+
* @returns true si les métadonnées sont valides, false sinon
|
|
70
|
+
* @throws Error avec un message descriptif si les métadonnées sont invalides
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* ```typescript
|
|
74
|
+
* isValidRAGMatter({ id: 1000, title: 'Mon document' }) // true
|
|
75
|
+
* isValidRAGMatter({ id: 999, title: 'Test' }) // throws (ID réservé)
|
|
76
|
+
* isValidRAGMatter({ id: 1000, title: '' }) // throws (titre vide)
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
function isValidRAGMatter(matter) {
|
|
80
|
+
// Vérifier que matter existe
|
|
81
|
+
if (!matter || typeof matter !== 'object' || Array.isArray(matter)) {
|
|
82
|
+
throw new Error('RAGMatter: matter est requis et doit être un objet');
|
|
83
|
+
}
|
|
84
|
+
// Vérifier que id existe et est un nombre
|
|
85
|
+
if (matter.id === undefined || matter.id === null) {
|
|
86
|
+
// Message plus explicite si le matter est complètement vide
|
|
87
|
+
const matterKeys = Object.keys(matter);
|
|
88
|
+
if (matterKeys.length === 0) {
|
|
89
|
+
throw new Error('RAGMatter: le front-matter est vide. Le contenu fourni ne contient probablement pas de front-matter YAML. Utilisez matterSerialize() pour ajouter le front-matter avant d\'appeler getSections().');
|
|
90
|
+
}
|
|
91
|
+
throw new Error(`RAGMatter: le champ "id" est obligatoire (matter reçu: ${JSON.stringify(matter)})`);
|
|
92
|
+
}
|
|
93
|
+
if (typeof matter.id !== 'number') {
|
|
94
|
+
throw new Error(`RAGMatter: le champ "id" doit être un nombre (reçu: ${typeof matter.id})`);
|
|
95
|
+
}
|
|
96
|
+
// Vérifier que l'ID est valide pour hnswlib
|
|
97
|
+
if (!isValidHNSWID(matter.id)) {
|
|
98
|
+
if (!Number.isInteger(matter.id)) {
|
|
99
|
+
throw new Error(`RAGMatter: l'ID ${matter.id} doit être un entier`);
|
|
100
|
+
}
|
|
101
|
+
if (matter.id <= exports.HNSW_ID_CONSTRAINTS.RESERVED_END) {
|
|
102
|
+
throw new Error(`RAGMatter: l'ID ${matter.id} est réservé (doit être > ${exports.HNSW_ID_CONSTRAINTS.RESERVED_END})`);
|
|
103
|
+
}
|
|
104
|
+
if (matter.id > exports.HNSW_ID_CONSTRAINTS.MAX) {
|
|
105
|
+
throw new Error(`RAGMatter: l'ID ${matter.id} dépasse la limite maximale (${exports.HNSW_ID_CONSTRAINTS.MAX})`);
|
|
106
|
+
}
|
|
107
|
+
throw new Error(`RAGMatter: l'ID ${matter.id} n'est pas valide`);
|
|
108
|
+
}
|
|
109
|
+
// Vérifier que title existe et est une chaîne non vide
|
|
110
|
+
if (matter.title === undefined || matter.title === null) {
|
|
111
|
+
throw new Error('RAGMatter: le champ "title" est obligatoire');
|
|
112
|
+
}
|
|
113
|
+
if (typeof matter.title !== 'string') {
|
|
114
|
+
throw new Error(`RAGMatter: le champ "title" doit être une chaîne (reçu: ${typeof matter.title})`);
|
|
115
|
+
}
|
|
116
|
+
if (matter.title.trim().length === 0) {
|
|
117
|
+
throw new Error('RAGMatter: le champ "title" ne peut pas être vide');
|
|
118
|
+
}
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
import { DocumentQueries, UserQuery, RAGConfig, ParsedDocument } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Calcule le fingerprint SHA-256 d'un contenu
|
|
4
|
+
* Utilisé pour détecter si un document a changé et nécessite une re-extraction
|
|
5
|
+
*
|
|
6
|
+
* @param content Contenu du document
|
|
7
|
+
* @returns Hash SHA-256 en hexadécimal
|
|
8
|
+
*/
|
|
9
|
+
export declare function calculateFingerprint(content: string): string;
|
|
2
10
|
/**
|
|
3
11
|
* Extrait tous les use cases d'un document parsé
|
|
4
12
|
*/
|
|
@@ -14,3 +22,32 @@ export declare function saveUseCases(queries: DocumentQueries, config: RAGConfig
|
|
|
14
22
|
* Charge les use cases depuis un fichier JSON
|
|
15
23
|
*/
|
|
16
24
|
export declare function loadUseCases(file: string, config: RAGConfig): DocumentQueries;
|
|
25
|
+
/**
|
|
26
|
+
* Extrait et sauvegarde les use cases d'un document
|
|
27
|
+
* Fonction standalone indépendante de la classe Embeddings
|
|
28
|
+
*
|
|
29
|
+
* Optimisation: Utilise un fingerprint (SHA-256) pour détecter si le document a changé.
|
|
30
|
+
* Si le fingerprint est identique, retourne les use cases existants sans re-extraction.
|
|
31
|
+
*
|
|
32
|
+
* @param document Document parsé
|
|
33
|
+
* @param baseDir Dossier où sauvegarder le fichier .query.json
|
|
34
|
+
* @param version Version du RAG (optionnel)
|
|
35
|
+
* @param tag Tag de version (optionnel)
|
|
36
|
+
* @param options Options d'extraction
|
|
37
|
+
* @param options.force Forcer la re-extraction même si le fingerprint est identique
|
|
38
|
+
* @param options.verbose Afficher les logs détaillés
|
|
39
|
+
* @returns Les queries extraites avec leur coût
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```typescript
|
|
43
|
+
* // Extraction avec cache (skip si fingerprint identique)
|
|
44
|
+
* const queries = await extractAndSaveDocumentUseCases(doc, './rag');
|
|
45
|
+
*
|
|
46
|
+
* // Forcer la re-extraction
|
|
47
|
+
* const queries = await extractAndSaveDocumentUseCases(doc, './rag', '1.0', 'v1', { force: true });
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export declare function extractAndSaveDocumentUseCases(document: ParsedDocument, baseDir: string, version?: string, tag?: string, options?: {
|
|
51
|
+
force?: boolean;
|
|
52
|
+
verbose?: boolean;
|
|
53
|
+
}): Promise<DocumentQueries>;
|
package/dist/src/rag/usecase.js
CHANGED
|
@@ -3,12 +3,26 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.calculateFingerprint = calculateFingerprint;
|
|
6
7
|
exports.extractDocumentUseCases = extractDocumentUseCases;
|
|
7
8
|
exports.saveUseCases = saveUseCases;
|
|
8
9
|
exports.loadUseCases = loadUseCases;
|
|
10
|
+
exports.extractAndSaveDocumentUseCases = extractAndSaveDocumentUseCases;
|
|
9
11
|
const fs_1 = require("fs");
|
|
10
12
|
const path_1 = __importDefault(require("path"));
|
|
13
|
+
const crypto_1 = require("crypto");
|
|
14
|
+
const types_1 = require("./types");
|
|
11
15
|
const usecase_1 = require("../usecase");
|
|
16
|
+
/**
|
|
17
|
+
* Calcule le fingerprint SHA-256 d'un contenu
|
|
18
|
+
* Utilisé pour détecter si un document a changé et nécessite une re-extraction
|
|
19
|
+
*
|
|
20
|
+
* @param content Contenu du document
|
|
21
|
+
* @returns Hash SHA-256 en hexadécimal
|
|
22
|
+
*/
|
|
23
|
+
function calculateFingerprint(content) {
|
|
24
|
+
return (0, crypto_1.createHash)('sha256').update(content, 'utf8').digest('hex');
|
|
25
|
+
}
|
|
12
26
|
/**
|
|
13
27
|
* Extrait tous les use cases d'un document parsé
|
|
14
28
|
*/
|
|
@@ -26,22 +40,22 @@ async function extractDocumentUseCases(parsedDocument) {
|
|
|
26
40
|
continue;
|
|
27
41
|
}
|
|
28
42
|
try {
|
|
29
|
-
const { json, cost } = await (0, usecase_1.
|
|
30
|
-
const result = JSON.parse(json);
|
|
43
|
+
const { json, cost } = await (0, usecase_1.llmExtractUserQueries)(section.content, filename);
|
|
44
|
+
const result = json ? JSON.parse(json) : { queries: [] };
|
|
31
45
|
if (result.queries && Array.isArray(result.queries)) {
|
|
32
46
|
// Enrichir chaque query avec les informations de section
|
|
33
47
|
const enrichedQueries = result.queries.map((query) => ({
|
|
34
48
|
...query,
|
|
35
49
|
filename: path_1.default.basename(filename, path_1.default.extname(filename)),
|
|
36
|
-
sectionIndex: index,
|
|
37
|
-
ref: `${path_1.default.basename(filename, path_1.default.extname(filename))}#section-${index}`
|
|
50
|
+
sectionIndex: section.index,
|
|
51
|
+
ref: `${path_1.default.basename(filename, path_1.default.extname(filename))}#section-${section.index}`
|
|
38
52
|
}));
|
|
39
53
|
allQueries.push(...enrichedQueries);
|
|
40
54
|
}
|
|
41
55
|
totalCost += cost;
|
|
42
56
|
}
|
|
43
57
|
catch (error) {
|
|
44
|
-
console.error(`Erreur lors de l'extraction des use cases pour ${filename}, section ${index}:`, error);
|
|
58
|
+
console.error(`Erreur lors de l'extraction des use cases pour ${filename}, section ${index}:`, error.message);
|
|
45
59
|
}
|
|
46
60
|
}
|
|
47
61
|
return { queries: allQueries, cost: totalCost };
|
|
@@ -52,8 +66,12 @@ async function extractDocumentUseCases(parsedDocument) {
|
|
|
52
66
|
function saveUseCases(queries, config) {
|
|
53
67
|
try {
|
|
54
68
|
const file = path_1.default.join(config.baseDir, queries.file);
|
|
69
|
+
// Créer le répertoire s'il n'existe pas
|
|
70
|
+
const dir = path_1.default.dirname(file);
|
|
71
|
+
if (!(0, fs_1.existsSync)(dir)) {
|
|
72
|
+
(0, fs_1.mkdirSync)(dir, { recursive: true });
|
|
73
|
+
}
|
|
55
74
|
(0, fs_1.writeFileSync)(file, JSON.stringify(queries, null, 2), 'utf8');
|
|
56
|
-
console.log(`🔔 Use cases sauvegardés: ${file}`);
|
|
57
75
|
}
|
|
58
76
|
catch (error) {
|
|
59
77
|
console.error('Erreur lors de la sauvegarde des use cases:', error);
|
|
@@ -73,7 +91,78 @@ function loadUseCases(file, config) {
|
|
|
73
91
|
return JSON.parse((0, fs_1.readFileSync)(queriesFile, 'utf8'));
|
|
74
92
|
}
|
|
75
93
|
catch (error) {
|
|
76
|
-
console.error('🔔 Erreur lors du chargement des use cases:', error);
|
|
94
|
+
console.error('🔔 Erreur lors du chargement des use cases:', error.message);
|
|
77
95
|
throw new Error(`Erreur lors du chargement des use cases: ${queriesFile} ${error.message}`);
|
|
78
96
|
}
|
|
79
97
|
}
|
|
98
|
+
/**
|
|
99
|
+
* Extrait et sauvegarde les use cases d'un document
|
|
100
|
+
* Fonction standalone indépendante de la classe Embeddings
|
|
101
|
+
*
|
|
102
|
+
* Optimisation: Utilise un fingerprint (SHA-256) pour détecter si le document a changé.
|
|
103
|
+
* Si le fingerprint est identique, retourne les use cases existants sans re-extraction.
|
|
104
|
+
*
|
|
105
|
+
* @param document Document parsé
|
|
106
|
+
* @param baseDir Dossier où sauvegarder le fichier .query.json
|
|
107
|
+
* @param version Version du RAG (optionnel)
|
|
108
|
+
* @param tag Tag de version (optionnel)
|
|
109
|
+
* @param options Options d'extraction
|
|
110
|
+
* @param options.force Forcer la re-extraction même si le fingerprint est identique
|
|
111
|
+
* @param options.verbose Afficher les logs détaillés
|
|
112
|
+
* @returns Les queries extraites avec leur coût
|
|
113
|
+
*
|
|
114
|
+
* @example
|
|
115
|
+
* ```typescript
|
|
116
|
+
* // Extraction avec cache (skip si fingerprint identique)
|
|
117
|
+
* const queries = await extractAndSaveDocumentUseCases(doc, './rag');
|
|
118
|
+
*
|
|
119
|
+
* // Forcer la re-extraction
|
|
120
|
+
* const queries = await extractAndSaveDocumentUseCases(doc, './rag', '1.0', 'v1', { force: true });
|
|
121
|
+
* ```
|
|
122
|
+
*/
|
|
123
|
+
async function extractAndSaveDocumentUseCases(document, baseDir, version, tag, options = {}) {
|
|
124
|
+
const { force = false, verbose = false } = options;
|
|
125
|
+
const filename = path_1.default.basename(document.filename, path_1.default.extname(document.filename));
|
|
126
|
+
const queryFile = path_1.default.join(baseDir, filename + '.query.json');
|
|
127
|
+
// Calculer le fingerprint du contenu source
|
|
128
|
+
const fingerprint = calculateFingerprint(document.content || '');
|
|
129
|
+
// Vérifier si le fichier existe déjà et si le fingerprint est identique
|
|
130
|
+
if (!force && (0, fs_1.existsSync)(queryFile)) {
|
|
131
|
+
try {
|
|
132
|
+
const existingQueries = JSON.parse((0, fs_1.readFileSync)(queryFile, 'utf8'));
|
|
133
|
+
// Comparer le fingerprint
|
|
134
|
+
if (existingQueries.fingerprint === fingerprint) {
|
|
135
|
+
if (verbose) {
|
|
136
|
+
console.log(`⏭️ Use cases à jour (fingerprint identique): ${document.filename}`);
|
|
137
|
+
}
|
|
138
|
+
return existingQueries;
|
|
139
|
+
}
|
|
140
|
+
else if (verbose) {
|
|
141
|
+
console.log(`🔄 Contenu modifié (fingerprint différent): ${document.filename}`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
// Si erreur de lecture, on continue avec l'extraction
|
|
146
|
+
if (verbose) {
|
|
147
|
+
console.warn(`⚠️ Erreur lecture use cases existants: ${error}`);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
// Extraction nécessaire (fichier inexistant, fingerprint différent, ou force=true)
|
|
152
|
+
if (verbose && force) {
|
|
153
|
+
console.log(`🔄 Re-extraction forcée: ${document.filename}`);
|
|
154
|
+
}
|
|
155
|
+
const { queries, cost } = await extractDocumentUseCases(document);
|
|
156
|
+
const docQueries = {
|
|
157
|
+
type: 'use-cases',
|
|
158
|
+
version: version || '1.0',
|
|
159
|
+
tag: tag || (0, types_1.generateVersionTag)(),
|
|
160
|
+
source: document.filename,
|
|
161
|
+
file: filename + '.query.json',
|
|
162
|
+
cost,
|
|
163
|
+
queries,
|
|
164
|
+
fingerprint // ✅ Ajouter le fingerprint
|
|
165
|
+
};
|
|
166
|
+
saveUseCases(docQueries, { baseDir });
|
|
167
|
+
return docQueries;
|
|
168
|
+
}
|
|
@@ -404,6 +404,7 @@ class GitE2EFactory {
|
|
|
404
404
|
gitConfig,
|
|
405
405
|
autoCleanup: options?.autoCleanup ?? true
|
|
406
406
|
};
|
|
407
|
+
testConfig.gitConfig.verbose = options?.customConfig?.verbose ?? false;
|
|
407
408
|
const helper = new GitE2EHelper(testConfig);
|
|
408
409
|
// Set test environment
|
|
409
410
|
process.env.NODE_ENV = 'test';
|
|
@@ -1,4 +1,16 @@
|
|
|
1
1
|
import { RulesGitConfig, GitHealthStatus } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Rapport d'analyse des IDs
|
|
4
|
+
*/
|
|
5
|
+
export interface SafeIDsReport {
|
|
6
|
+
scanned: number;
|
|
7
|
+
valid: number;
|
|
8
|
+
missingID: string[];
|
|
9
|
+
missingTitle: string[];
|
|
10
|
+
invalidID: string[];
|
|
11
|
+
duplicateID: string[];
|
|
12
|
+
errors: string[];
|
|
13
|
+
}
|
|
2
14
|
/**
|
|
3
15
|
* Git Repository Health Manager
|
|
4
16
|
*
|
|
@@ -63,4 +75,49 @@ export declare class GitHealthManager {
|
|
|
63
75
|
* - Erreurs de traitement par branche → continue avec les autres
|
|
64
76
|
*/
|
|
65
77
|
migrateNotes(): Promise<void>;
|
|
78
|
+
/**
|
|
79
|
+
* Analyse les IDs des documents Markdown dans une branche
|
|
80
|
+
*
|
|
81
|
+
* @param branch Branche à analyser (par défaut: toutes les branches)
|
|
82
|
+
* @returns Rapport d'analyse avec les fichiers problématiques
|
|
83
|
+
*/
|
|
84
|
+
analyseSafeIDs(branch?: string): Promise<SafeIDsReport>;
|
|
85
|
+
/**
|
|
86
|
+
* Répare les IDs problématiques identifiés dans un rapport d'analyse
|
|
87
|
+
*
|
|
88
|
+
* @param report Rapport d'analyse généré par analyseSafeIDs
|
|
89
|
+
* @param options Options de réparation
|
|
90
|
+
* @param options.dryRun Mode simulation (affiche les réparations sans modifier)
|
|
91
|
+
* @returns Rapport mis à jour avec les fichiers réparés
|
|
92
|
+
*/
|
|
93
|
+
repairSafeIDs(report: SafeIDsReport, options?: {
|
|
94
|
+
dryRun?: boolean;
|
|
95
|
+
}): Promise<SafeIDsReport>;
|
|
96
|
+
/**
|
|
97
|
+
* Vérifie et répare les IDs manquants dans tous les documents Markdown du repository
|
|
98
|
+
*
|
|
99
|
+
* Cette méthode orchestre l'analyse et la réparation :
|
|
100
|
+
* 1. Analyse les documents avec analyseSafeIDs()
|
|
101
|
+
* 2. Si autoFix est activé, répare avec repairSafeIDs()
|
|
102
|
+
*
|
|
103
|
+
* @param options Options de scan et réparation
|
|
104
|
+
* @param options.branch Branche spécifique à scanner (par défaut: toutes les branches)
|
|
105
|
+
* @param options.autoFix Active la réparation automatique (par défaut: false)
|
|
106
|
+
* @param options.dryRun Mode simulation (affiche les problèmes sans modifier)
|
|
107
|
+
* @returns Résumé des documents scannés et réparés
|
|
108
|
+
*/
|
|
109
|
+
ensureSafeIDS(options?: {
|
|
110
|
+
branch?: string;
|
|
111
|
+
autoFix?: boolean;
|
|
112
|
+
dryRun?: boolean;
|
|
113
|
+
}): Promise<{
|
|
114
|
+
scanned: number;
|
|
115
|
+
valid: number;
|
|
116
|
+
missingID: number;
|
|
117
|
+
missingTitle: number;
|
|
118
|
+
invalidID: number;
|
|
119
|
+
duplicateID: number;
|
|
120
|
+
fixed: number;
|
|
121
|
+
errors: string[];
|
|
122
|
+
}>;
|
|
66
123
|
}
|