agentic-api 1.0.6 → 2.0.31
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/README.md +336 -76
- package/dist/src/agents/agents.example.d.ts +3 -0
- package/dist/src/agents/agents.example.js +38 -0
- package/dist/src/agents/authentication.js +2 -0
- package/dist/src/agents/prompts.d.ts +2 -2
- package/dist/src/agents/prompts.js +112 -49
- package/dist/src/agents/reducer.core.d.ts +12 -0
- package/dist/src/agents/reducer.core.js +207 -0
- package/dist/src/agents/reducer.d.ts +3 -0
- package/dist/src/agents/reducer.example.d.ts +28 -0
- package/dist/src/agents/reducer.example.js +118 -0
- package/dist/src/agents/reducer.js +19 -0
- package/dist/src/agents/reducer.loaders.d.ts +34 -0
- package/dist/src/agents/reducer.loaders.js +122 -0
- package/dist/src/agents/reducer.process.d.ts +16 -0
- package/dist/src/agents/reducer.process.js +143 -0
- package/dist/src/agents/reducer.tools.d.ts +29 -0
- package/dist/src/agents/reducer.tools.js +157 -0
- package/dist/src/agents/reducer.types.d.ts +50 -0
- package/dist/src/agents/reducer.types.js +5 -0
- package/dist/src/agents/simulator.d.ts +47 -0
- package/dist/src/agents/simulator.executor.d.ts +26 -0
- package/dist/src/agents/simulator.executor.js +132 -0
- package/dist/src/agents/simulator.js +205 -0
- package/dist/src/agents/simulator.prompts.d.ts +16 -0
- package/dist/src/agents/simulator.prompts.js +108 -0
- package/dist/src/agents/simulator.types.d.ts +42 -0
- package/dist/src/agents/simulator.types.js +2 -0
- package/dist/src/agents/simulator.utils.d.ts +20 -0
- package/dist/src/agents/simulator.utils.js +87 -0
- package/dist/src/execute.d.ts +13 -6
- package/dist/src/execute.js +351 -85
- package/dist/src/index.d.ts +9 -0
- package/dist/src/index.js +14 -0
- package/dist/src/princing.openai.d.ts +9 -2
- package/dist/src/princing.openai.js +15 -11
- package/dist/src/prompts.d.ts +3 -2
- package/dist/src/prompts.js +159 -19
- package/dist/src/rag/embeddings.d.ts +103 -0
- package/dist/src/rag/embeddings.js +466 -0
- package/dist/src/rag/index.d.ts +12 -0
- package/dist/src/rag/index.js +40 -0
- package/dist/src/rag/lucene.d.ts +45 -0
- package/dist/src/rag/lucene.js +227 -0
- package/dist/src/rag/parser.d.ts +68 -0
- package/dist/src/rag/parser.js +192 -0
- package/dist/src/rag/tools.d.ts +76 -0
- package/dist/src/rag/tools.js +196 -0
- package/dist/src/rag/types.d.ts +178 -0
- package/dist/src/rag/types.js +21 -0
- package/dist/src/rag/usecase.d.ts +16 -0
- package/dist/src/rag/usecase.js +79 -0
- package/dist/src/rules/errors.d.ts +60 -0
- package/dist/src/rules/errors.js +97 -0
- package/dist/src/rules/git/git.e2e.helper.d.ts +104 -0
- package/dist/src/rules/git/git.e2e.helper.js +488 -0
- package/dist/src/rules/git/git.health.d.ts +66 -0
- package/dist/src/rules/git/git.health.js +354 -0
- package/dist/src/rules/git/git.helper.d.ts +129 -0
- package/dist/src/rules/git/git.helper.js +53 -0
- package/dist/src/rules/git/index.d.ts +6 -0
- package/dist/src/rules/git/index.js +76 -0
- package/dist/src/rules/git/repo.d.ts +128 -0
- package/dist/src/rules/git/repo.js +900 -0
- package/dist/src/rules/git/repo.pr.d.ts +137 -0
- package/dist/src/rules/git/repo.pr.js +589 -0
- package/dist/src/rules/git/repo.tools.d.ts +134 -0
- package/dist/src/rules/git/repo.tools.js +730 -0
- package/dist/src/rules/index.d.ts +8 -0
- package/dist/src/rules/index.js +25 -0
- package/dist/src/rules/messages.d.ts +17 -0
- package/dist/src/rules/messages.js +21 -0
- package/dist/src/rules/types.ctrl.d.ts +28 -0
- package/dist/src/rules/types.ctrl.js +2 -0
- package/dist/src/rules/types.d.ts +510 -0
- package/dist/src/rules/types.helpers.d.ts +132 -0
- package/dist/src/rules/types.helpers.js +2 -0
- package/dist/src/rules/types.js +33 -0
- package/dist/src/rules/user.mapper.d.ts +61 -0
- package/dist/src/rules/user.mapper.js +160 -0
- package/dist/src/rules/utils/slug.d.ts +22 -0
- package/dist/src/rules/utils/slug.js +35 -0
- package/dist/src/rules/utils.matter.d.ts +66 -0
- package/dist/src/rules/utils.matter.js +208 -0
- package/dist/src/rules/utils.slug.d.ts +22 -0
- package/dist/src/rules/utils.slug.js +35 -0
- package/dist/src/scrapper.d.ts +3 -2
- package/dist/src/scrapper.js +33 -37
- package/dist/src/stategraph/index.d.ts +8 -0
- package/dist/src/stategraph/index.js +21 -0
- package/dist/src/stategraph/stategraph.d.ts +91 -0
- package/dist/src/stategraph/stategraph.js +241 -0
- package/dist/src/stategraph/stategraph.storage.d.ts +41 -0
- package/dist/src/stategraph/stategraph.storage.js +166 -0
- package/dist/src/stategraph/types.d.ts +139 -0
- package/dist/src/stategraph/types.js +19 -0
- package/dist/src/types.d.ts +62 -39
- package/dist/src/types.js +53 -89
- package/dist/src/usecase.d.ts +4 -0
- package/dist/src/usecase.js +44 -0
- package/dist/src/utils.d.ts +12 -5
- package/dist/src/utils.js +30 -13
- package/package.json +9 -3
|
@@ -0,0 +1,466 @@
|
|
|
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.Embeddings = void 0;
|
|
7
|
+
const hnswlib_node_1 = require("hnswlib-node");
|
|
8
|
+
const fs_1 = require("fs");
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
const types_1 = require("./types");
|
|
11
|
+
const parser_1 = require("./parser");
|
|
12
|
+
const utils_1 = require("../utils");
|
|
13
|
+
const usecase_1 = require("./usecase");
|
|
14
|
+
class Embeddings {
|
|
15
|
+
constructor(config) {
|
|
16
|
+
this.vectorsIndex = null;
|
|
17
|
+
this.metadata = null;
|
|
18
|
+
this.mapping = null;
|
|
19
|
+
this.config = config;
|
|
20
|
+
this.vectorsFile = path_1.default.join(config.baseDir, types_1.RAG_FILES.VECTORS);
|
|
21
|
+
this.space = config.dimensions || 1536;
|
|
22
|
+
this.distance = config.distance || 'cosine';
|
|
23
|
+
this.inmemory = config.inmemory || false;
|
|
24
|
+
this.debug = false;
|
|
25
|
+
// Charger l'index existant si disponible et pas en mode inmemory
|
|
26
|
+
if (!this.inmemory && (0, fs_1.existsSync)(this.vectorsFile)) {
|
|
27
|
+
this.loadIndex();
|
|
28
|
+
}
|
|
29
|
+
// Charger les métadonnées et mapping si disponibles
|
|
30
|
+
if (!this.inmemory) {
|
|
31
|
+
this.loadMetadata();
|
|
32
|
+
this.loadMapping();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Retourne le prochain ID documentaire stable et met à jour metadata.docLastID.
|
|
37
|
+
* Pré-conditions: this.mapping et this.metadata sont chargés.
|
|
38
|
+
*/
|
|
39
|
+
getNextID() {
|
|
40
|
+
// Si non initialisé, partir du plus grand ID du mapping
|
|
41
|
+
if (this.metadata.docLastID == null || this.metadata.docLastID <= 0) {
|
|
42
|
+
const maxFromMapping = Object.keys(this.mapping.mapping || {})
|
|
43
|
+
.map(k => parseInt(k, 10))
|
|
44
|
+
.filter(n => !isNaN(n))
|
|
45
|
+
.reduce((a, b) => Math.max(a, b), 999);
|
|
46
|
+
this.metadata.docLastID = maxFromMapping + 1;
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
this.metadata.docLastID = this.metadata.docLastID + 1;
|
|
50
|
+
}
|
|
51
|
+
const next = this.metadata.docLastID;
|
|
52
|
+
this.saveMetadata(this.metadata);
|
|
53
|
+
return next;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Retourne l'ID documentaire pour un fichier. Si non trouvé, attribue un nouvel ID.
|
|
57
|
+
* Stratégie: utiliser le mapping id -> "filename#section-0".
|
|
58
|
+
*/
|
|
59
|
+
getOrAssignDocumentID(file) {
|
|
60
|
+
const base = path_1.default.basename(file, path_1.default.extname(file));
|
|
61
|
+
// Chercher un ID existant dans le mapping (section-0 comme ancrage documentaire)
|
|
62
|
+
const found = Object.entries(this.mapping.mapping || {}).find(([id, ref]) => {
|
|
63
|
+
return typeof ref === 'string' && ref.startsWith(`${base}#section-0`);
|
|
64
|
+
});
|
|
65
|
+
if (found) {
|
|
66
|
+
return parseInt(found[0], 10);
|
|
67
|
+
}
|
|
68
|
+
// Sinon, générer un nouvel ID documentaire
|
|
69
|
+
return this.getNextID();
|
|
70
|
+
}
|
|
71
|
+
async extractAndSaveDocumentUseCases(document) {
|
|
72
|
+
const { queries, cost } = await (0, usecase_1.extractDocumentUseCases)(document);
|
|
73
|
+
const filename = path_1.default.basename(document.filename, path_1.default.extname(document.filename));
|
|
74
|
+
const docQueries = {
|
|
75
|
+
type: 'use-cases',
|
|
76
|
+
version: this.config.version,
|
|
77
|
+
tag: this.config.tag,
|
|
78
|
+
source: document.filename,
|
|
79
|
+
file: (0, utils_1.toSlug)(filename) + '.json',
|
|
80
|
+
cost,
|
|
81
|
+
queries
|
|
82
|
+
};
|
|
83
|
+
(0, usecase_1.saveUseCases)(docQueries, this.config);
|
|
84
|
+
return docQueries;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Charge les documents du RAG
|
|
88
|
+
* IMPORTANT: C'est le document produit pour le RAG, ce n'est pas le document source!
|
|
89
|
+
* @param file Le fichier à charger depuis git
|
|
90
|
+
*/
|
|
91
|
+
async loadDocumentOnRAG(file) {
|
|
92
|
+
try {
|
|
93
|
+
// The document is always in the baseDir!
|
|
94
|
+
const filePath = path_1.default.join(this.config.baseDir, file);
|
|
95
|
+
// ✅ FIX: Vérifier l'existence du fichier avant de le lire
|
|
96
|
+
// if (!existsSync(filePath)) {
|
|
97
|
+
// const error = new Error(`ENOENT: no such file or directory, open '${filePath}'`);
|
|
98
|
+
// (error as any).code = 'ENOENT';
|
|
99
|
+
// (error as any).errno = -2;
|
|
100
|
+
// (error as any).syscall = 'open';
|
|
101
|
+
// (error as any).path = filePath;
|
|
102
|
+
// throw error;
|
|
103
|
+
// }
|
|
104
|
+
const content = (0, fs_1.readFileSync)(filePath, 'utf8');
|
|
105
|
+
const parsedDocument = (0, parser_1.getSections)(content, file);
|
|
106
|
+
return parsedDocument;
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
console.error('Erreur lors du chargement du document:', error);
|
|
110
|
+
throw error;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Charge les use cases d'un document
|
|
115
|
+
* @param document Le document de référence pour le RAG `loadDocumentOnRAG(file)`
|
|
116
|
+
* @returns Les use cases du document
|
|
117
|
+
*/
|
|
118
|
+
async loadDocumentUseCases(document) {
|
|
119
|
+
const filename = path_1.default.basename(document.filename, path_1.default.extname(document.filename));
|
|
120
|
+
return (0, usecase_1.loadUseCases)((0, utils_1.toSlug)(filename) + '.json', this.config);
|
|
121
|
+
}
|
|
122
|
+
async listDocumentsOnRAG() {
|
|
123
|
+
const filesWithSection = Object.values(this.mapping?.mapping || {});
|
|
124
|
+
const files = new Set(filesWithSection.map(f => f.replace(/#.*$/, '')));
|
|
125
|
+
return Array.from(files).map(filename => filename.endsWith('.md') ? filename : filename + '.md');
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Recherche par similarité dans l'index
|
|
129
|
+
*/
|
|
130
|
+
searchKnn(vectors, options = {}) {
|
|
131
|
+
const startTime = Date.now();
|
|
132
|
+
const { neighbors = 5, ef = 250 } = options;
|
|
133
|
+
if (!this.vectorsIndex) {
|
|
134
|
+
return {
|
|
135
|
+
results: [],
|
|
136
|
+
searchTime: Date.now() - startTime
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
// Configurer ef pour la recherche
|
|
140
|
+
this.vectorsIndex.setEf(ef);
|
|
141
|
+
const result = this.vectorsIndex.searchKnn(vectors, neighbors);
|
|
142
|
+
if (!result || !result.neighbors || !result.neighbors.length) {
|
|
143
|
+
return {
|
|
144
|
+
results: [],
|
|
145
|
+
searchTime: Date.now() - startTime
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
const ids = result.neighbors;
|
|
149
|
+
const scores = result.distances.map(s => parseFloat((1 - s).toFixed(3)));
|
|
150
|
+
if (this.debug) {
|
|
151
|
+
console.log('Scores de recherche KNN:', scores);
|
|
152
|
+
}
|
|
153
|
+
const results = ids.map((id, idx) => {
|
|
154
|
+
const ref = this.mapping?.mapping[id.toString()] || '';
|
|
155
|
+
const docRef = this.metadata?.documents[id.toString()];
|
|
156
|
+
return {
|
|
157
|
+
id,
|
|
158
|
+
ref,
|
|
159
|
+
score: scores[idx],
|
|
160
|
+
content: docRef?.content || ''
|
|
161
|
+
};
|
|
162
|
+
}).filter(r => r.ref && r.content);
|
|
163
|
+
return {
|
|
164
|
+
results,
|
|
165
|
+
searchTime: Date.now() - startTime
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Recherche sémantique avec OpenAI
|
|
170
|
+
*/
|
|
171
|
+
async semanticSearch(question, options = {}) {
|
|
172
|
+
const startTime = Date.now();
|
|
173
|
+
const openai = (0, utils_1.openaiInstance)();
|
|
174
|
+
// Créer l'embedding de la question
|
|
175
|
+
const embedding = await openai.embeddings.create({
|
|
176
|
+
model: 'text-embedding-3-small',
|
|
177
|
+
input: question,
|
|
178
|
+
dimensions: this.space,
|
|
179
|
+
encoding_format: 'float',
|
|
180
|
+
});
|
|
181
|
+
const queryVector = (0, parser_1.l2Normalize)(embedding.data[0].embedding);
|
|
182
|
+
// Rechercher dans l'index
|
|
183
|
+
const result = this.searchKnn(queryVector, options);
|
|
184
|
+
// Mettre à jour le temps total (incluant l'appel OpenAI)
|
|
185
|
+
result.searchTime = Date.now() - startTime;
|
|
186
|
+
return result;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Obtient les métadonnées du RAG
|
|
190
|
+
* @returns Les métadonnées du RAG
|
|
191
|
+
*/
|
|
192
|
+
getMetadata() {
|
|
193
|
+
return this.metadata;
|
|
194
|
+
}
|
|
195
|
+
getMapping() {
|
|
196
|
+
return this.mapping;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Vérifie si l'index est prêt
|
|
200
|
+
*/
|
|
201
|
+
isReady() {
|
|
202
|
+
if (this.inmemory) {
|
|
203
|
+
return this.vectorsIndex !== null;
|
|
204
|
+
}
|
|
205
|
+
return this.vectorsIndex !== null && this.metadata !== null && this.mapping !== null;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Réinitialise l'index
|
|
209
|
+
*/
|
|
210
|
+
resetKnn() {
|
|
211
|
+
this.vectorsIndex = new hnswlib_node_1.HierarchicalNSW(this.distance, this.space);
|
|
212
|
+
this.metadata = null;
|
|
213
|
+
this.mapping = null;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Crée un nouvel index HierarchicalNSW avec documents parsés
|
|
217
|
+
* ou met à jour l'index existant avec de nouveaux documents
|
|
218
|
+
*/
|
|
219
|
+
async indexFromDocuments(documents, options) {
|
|
220
|
+
const ef = options?.ef || this.config.hnswConfig?.ef || 200;
|
|
221
|
+
const m = options?.m || this.config.hnswConfig?.m || 32;
|
|
222
|
+
const isUpdate = options?.update || false;
|
|
223
|
+
const prepare = options?.prepare || ((input) => input);
|
|
224
|
+
let startId = this.config.startId || 1000;
|
|
225
|
+
const openai = (0, utils_1.openaiInstance)();
|
|
226
|
+
const vectors = {};
|
|
227
|
+
const documentRefs = {};
|
|
228
|
+
const documentReferences = {};
|
|
229
|
+
// Si c'est une mise à jour, charger l'état existant
|
|
230
|
+
if (isUpdate && this.mapping && this.metadata) {
|
|
231
|
+
Object.assign(documentRefs, this.mapping.mapping);
|
|
232
|
+
Object.assign(documentReferences, this.metadata.documents);
|
|
233
|
+
// Trouver le prochain ID disponible
|
|
234
|
+
const existingIds = Object.keys(documentRefs).map(id => parseInt(id));
|
|
235
|
+
startId = existingIds.length ? Math.max(...existingIds) + 1 : startId;
|
|
236
|
+
}
|
|
237
|
+
console.log(`Traitement de ${documents.length} documents...`);
|
|
238
|
+
for (const doc of documents) {
|
|
239
|
+
const filename = path_1.default.basename(doc.filename, path_1.default.extname(doc.filename));
|
|
240
|
+
process.stdout.write(`Traitement: ${filename}`);
|
|
241
|
+
const { sections } = doc;
|
|
242
|
+
if (!sections.length) {
|
|
243
|
+
console.log(`❌ Aucune section trouvée dans ${filename}`);
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
246
|
+
// Traiter chaque section
|
|
247
|
+
for (let index = 0; index < sections.length; index++) {
|
|
248
|
+
const section = sections[index];
|
|
249
|
+
const hasEnoughContent = section.lines > 2;
|
|
250
|
+
if (!hasEnoughContent) {
|
|
251
|
+
continue;
|
|
252
|
+
}
|
|
253
|
+
// Vérifier si cette section existe déjà (pour les mises à jour)
|
|
254
|
+
const ref = `${filename}#section-${index}`;
|
|
255
|
+
const existingId = Object.keys(documentRefs).find(id => documentRefs[id] === ref);
|
|
256
|
+
if (isUpdate && existingId) {
|
|
257
|
+
console.log(`Section ${ref} déjà indexée, ignorée`);
|
|
258
|
+
continue;
|
|
259
|
+
}
|
|
260
|
+
// Créer l'embedding de la section
|
|
261
|
+
const embedding = await openai.embeddings.create({
|
|
262
|
+
model: "text-embedding-3-small",
|
|
263
|
+
input: prepare(section.content),
|
|
264
|
+
dimensions: this.space,
|
|
265
|
+
encoding_format: "float",
|
|
266
|
+
});
|
|
267
|
+
const normalizedVectors = (0, parser_1.l2Normalize)(embedding.data[0].embedding);
|
|
268
|
+
// Stocker avec le nouveau format d'ID
|
|
269
|
+
vectors[startId] = normalizedVectors;
|
|
270
|
+
documentRefs[startId] = ref;
|
|
271
|
+
// Créer la référence de document
|
|
272
|
+
documentReferences[startId] = {
|
|
273
|
+
filename: filename + '.md',
|
|
274
|
+
sectionIndex: index,
|
|
275
|
+
ref,
|
|
276
|
+
title: section.title || `Section ${index}`,
|
|
277
|
+
content: section.content,
|
|
278
|
+
metadata: doc.matter
|
|
279
|
+
};
|
|
280
|
+
startId++;
|
|
281
|
+
process.stdout.write(hasEnoughContent ? ':' : '.');
|
|
282
|
+
}
|
|
283
|
+
//
|
|
284
|
+
// let enough room for new sections on future updates
|
|
285
|
+
const pad = 20 - sections.length;
|
|
286
|
+
startId += pad;
|
|
287
|
+
console.log(' done');
|
|
288
|
+
}
|
|
289
|
+
// Créer ou mettre à jour l'index HierarchicalNSW
|
|
290
|
+
const newVectors = Object.keys(vectors).filter(id => vectors[id]);
|
|
291
|
+
const totalVectors = Object.keys(documentRefs).length;
|
|
292
|
+
if (newVectors.length === 0 && !isUpdate) {
|
|
293
|
+
throw new Error('Aucun vecteur à indexer');
|
|
294
|
+
}
|
|
295
|
+
if (!this.vectorsIndex || !isUpdate) {
|
|
296
|
+
// Créer un nouvel index
|
|
297
|
+
const allowReplaceDeleted = true;
|
|
298
|
+
this.vectorsIndex = new hnswlib_node_1.HierarchicalNSW(this.distance, this.space);
|
|
299
|
+
console.log(`Initialisation de l'index pour ${totalVectors} entrées (ef:${ef}, m:${m})`);
|
|
300
|
+
this.vectorsIndex.initIndex(totalVectors + 100, m, ef, 0, allowReplaceDeleted);
|
|
301
|
+
// Ajouter tous les vecteurs
|
|
302
|
+
for (const item of Object.keys(documentRefs)) {
|
|
303
|
+
const id = parseInt(item);
|
|
304
|
+
const vector = vectors[item] || this.getVectorFromExistingIndex(id);
|
|
305
|
+
if (vector) {
|
|
306
|
+
this.vectorsIndex.addPoint(vector, id);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
else {
|
|
311
|
+
//
|
|
312
|
+
// FIXME this is not working, ids must be restored from de RAGMapping ids <=> documentRefs
|
|
313
|
+
// Mettre à jour l'index existant
|
|
314
|
+
console.log(`Mise à jour de l'index avec ${newVectors.length} nouveaux vecteurs`);
|
|
315
|
+
const replaceDeleted = true;
|
|
316
|
+
for (const item of newVectors) {
|
|
317
|
+
const id = parseInt(item);
|
|
318
|
+
// le point existant n’apparaît plus
|
|
319
|
+
this.vectorsIndex.markDelete(id);
|
|
320
|
+
this.vectorsIndex.addPoint(vectors[item], id, replaceDeleted);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
// Sauvegarder l'index
|
|
324
|
+
if (!this.inmemory) {
|
|
325
|
+
this.vectorsIndex.writeIndexSync(this.vectorsFile);
|
|
326
|
+
console.log('Index sauvegardé:', this.vectorsFile);
|
|
327
|
+
}
|
|
328
|
+
// Créer le tag de version
|
|
329
|
+
const tag = this.config.tag || (0, types_1.generateVersionTag)();
|
|
330
|
+
const version = this.config.version || '1.0';
|
|
331
|
+
// Créer et sauvegarder le mapping
|
|
332
|
+
const mapping = {
|
|
333
|
+
type: 'mapping',
|
|
334
|
+
version,
|
|
335
|
+
tag,
|
|
336
|
+
mapping: documentRefs,
|
|
337
|
+
createdAt: new Date().toISOString()
|
|
338
|
+
};
|
|
339
|
+
this.saveMapping(mapping);
|
|
340
|
+
// Créer et sauvegarder les métadonnées
|
|
341
|
+
const metadata = {
|
|
342
|
+
version,
|
|
343
|
+
tag,
|
|
344
|
+
createdAt: new Date().toISOString(),
|
|
345
|
+
config: this.config,
|
|
346
|
+
documents: documentReferences,
|
|
347
|
+
checkpoint: {
|
|
348
|
+
branch: options?.branch || '',
|
|
349
|
+
hash: options?.lastCommit || ''
|
|
350
|
+
},
|
|
351
|
+
stats: {
|
|
352
|
+
totalDocuments: documents.length,
|
|
353
|
+
totalSections: totalVectors,
|
|
354
|
+
vectorDimensions: this.space,
|
|
355
|
+
indexSize: `${Math.round(totalVectors * this.space * 4 / 1024 / 1024)}MB`
|
|
356
|
+
},
|
|
357
|
+
files: {
|
|
358
|
+
vectorsFile: types_1.RAG_FILES.VECTORS,
|
|
359
|
+
mappingFile: types_1.RAG_FILES.MAPPING,
|
|
360
|
+
queriesFile: types_1.RAG_FILES.QUERIES
|
|
361
|
+
}
|
|
362
|
+
};
|
|
363
|
+
this.saveMetadata(metadata);
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Charge l'index HierarchicalNSW existant
|
|
367
|
+
*/
|
|
368
|
+
loadIndex() {
|
|
369
|
+
try {
|
|
370
|
+
this.vectorsIndex = new hnswlib_node_1.HierarchicalNSW(this.distance, this.space);
|
|
371
|
+
this.vectorsIndex.readIndexSync(this.vectorsFile);
|
|
372
|
+
if (this.debug) {
|
|
373
|
+
console.log('Index HierarchicalNSW chargé:', this.vectorsFile);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
catch (error) {
|
|
377
|
+
console.error('Erreur lors du chargement de l\'index:', error);
|
|
378
|
+
this.vectorsIndex = null;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
/**
|
|
382
|
+
* Charge les métadonnées du fichier rag-metadata.json
|
|
383
|
+
*/
|
|
384
|
+
loadMetadata() {
|
|
385
|
+
const metadataFile = path_1.default.join(this.config.baseDir, types_1.RAG_FILES.METADATA);
|
|
386
|
+
if ((0, fs_1.existsSync)(metadataFile)) {
|
|
387
|
+
try {
|
|
388
|
+
this.metadata = JSON.parse((0, fs_1.readFileSync)(metadataFile, 'utf8'));
|
|
389
|
+
if (this.debug) {
|
|
390
|
+
console.log('Métadonnées RAG chargées:', metadataFile);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
catch (error) {
|
|
394
|
+
console.error('Erreur lors du chargement des métadonnées:', error);
|
|
395
|
+
throw error;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Charge le mapping des IDs
|
|
401
|
+
*/
|
|
402
|
+
loadMapping() {
|
|
403
|
+
const mappingFile = path_1.default.join(this.config.baseDir, types_1.RAG_FILES.MAPPING);
|
|
404
|
+
if ((0, fs_1.existsSync)(mappingFile)) {
|
|
405
|
+
try {
|
|
406
|
+
this.mapping = JSON.parse((0, fs_1.readFileSync)(mappingFile, 'utf8'));
|
|
407
|
+
if (this.debug) {
|
|
408
|
+
console.log('Mapping RAG chargé:', mappingFile);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
catch (error) {
|
|
412
|
+
console.error('Erreur lors du chargement du mapping:', error);
|
|
413
|
+
throw error;
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* Sauvegarde les métadonnées dans rag-metadata.json
|
|
419
|
+
*/
|
|
420
|
+
saveMetadata(metadata) {
|
|
421
|
+
// Toujours assigner les métadonnées en mémoire
|
|
422
|
+
this.metadata = metadata;
|
|
423
|
+
// En mode inmemory, on ne sauvegarde pas sur disque
|
|
424
|
+
if (this.inmemory)
|
|
425
|
+
return;
|
|
426
|
+
const metadataFile = path_1.default.join(this.config.baseDir, types_1.RAG_FILES.METADATA);
|
|
427
|
+
try {
|
|
428
|
+
(0, fs_1.writeFileSync)(metadataFile, JSON.stringify(metadata, null, 2), 'utf8');
|
|
429
|
+
if (this.debug) {
|
|
430
|
+
console.log('Métadonnées sauvegardées:', metadataFile);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
catch (error) {
|
|
434
|
+
console.error('Erreur lors de la sauvegarde des métadonnées:', error);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
/**
|
|
438
|
+
* Sauvegarde le mapping des IDs
|
|
439
|
+
*/
|
|
440
|
+
saveMapping(mapping) {
|
|
441
|
+
// Toujours assigner le mapping en mémoire
|
|
442
|
+
this.mapping = mapping;
|
|
443
|
+
// En mode inmemory, on ne sauvegarde pas sur disque
|
|
444
|
+
if (this.inmemory)
|
|
445
|
+
return;
|
|
446
|
+
const mappingFile = path_1.default.join(this.config.baseDir, types_1.RAG_FILES.MAPPING);
|
|
447
|
+
try {
|
|
448
|
+
(0, fs_1.writeFileSync)(mappingFile, JSON.stringify(mapping, null, 2), 'utf8');
|
|
449
|
+
if (this.debug) {
|
|
450
|
+
console.log('Mapping sauvegardé:', mappingFile);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
catch (error) {
|
|
454
|
+
console.error('Erreur lors de la sauvegarde du mapping:', error);
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
/**
|
|
458
|
+
* Récupère un vecteur depuis l'index existant (pour les mises à jour)
|
|
459
|
+
*/
|
|
460
|
+
getVectorFromExistingIndex(id) {
|
|
461
|
+
// Cette méthode devrait être implémentée si hnswlib-node le permet
|
|
462
|
+
// Pour l'instant, on retourne null
|
|
463
|
+
return null;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
exports.Embeddings = Embeddings;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.RAGManager = void 0;
|
|
18
|
+
__exportStar(require("./types"), exports);
|
|
19
|
+
__exportStar(require("./parser"), exports);
|
|
20
|
+
__exportStar(require("./embeddings"), exports);
|
|
21
|
+
__exportStar(require("./usecase"), exports);
|
|
22
|
+
/**
|
|
23
|
+
* Configuration par défaut pour le RAG
|
|
24
|
+
*/
|
|
25
|
+
// const DEFAULT_RAG_CONFIG: Partial<RAGConfig> = {
|
|
26
|
+
// vectorsFile: 'hnsw-vectors',
|
|
27
|
+
// dimensions: 1536,
|
|
28
|
+
// distance: 'cosine',
|
|
29
|
+
// filterInput: '',
|
|
30
|
+
// hnswConfig: {
|
|
31
|
+
// ef: 200,
|
|
32
|
+
// m: 32
|
|
33
|
+
// }
|
|
34
|
+
// };
|
|
35
|
+
/**
|
|
36
|
+
* Gestionnaire RAG principal
|
|
37
|
+
*/
|
|
38
|
+
class RAGManager {
|
|
39
|
+
}
|
|
40
|
+
exports.RAGManager = RAGManager;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
type LuceneConfig = any;
|
|
2
|
+
export interface LuceneIndexDocument {
|
|
3
|
+
id: string;
|
|
4
|
+
query: string;
|
|
5
|
+
service: string;
|
|
6
|
+
filename: string;
|
|
7
|
+
}
|
|
8
|
+
export declare class LuceneManager {
|
|
9
|
+
private miniSearch;
|
|
10
|
+
private config;
|
|
11
|
+
private indexFile;
|
|
12
|
+
constructor(config: LuceneConfig, baseDir: string);
|
|
13
|
+
/**
|
|
14
|
+
* Traitement des termes pour la recherche
|
|
15
|
+
*/
|
|
16
|
+
private processTerm;
|
|
17
|
+
/**
|
|
18
|
+
* Charge un index existant
|
|
19
|
+
*/
|
|
20
|
+
private loadIndex;
|
|
21
|
+
/**
|
|
22
|
+
* Construit l'index Lucene à partir des fichiers de requêtes
|
|
23
|
+
*/
|
|
24
|
+
buildIndex(queriesDir?: string): Promise<void>;
|
|
25
|
+
/**
|
|
26
|
+
* Sauvegarde l'index
|
|
27
|
+
*/
|
|
28
|
+
private saveIndex;
|
|
29
|
+
/**
|
|
30
|
+
* Recherche dans l'index Lucene
|
|
31
|
+
*/
|
|
32
|
+
/**
|
|
33
|
+
* Obtient les statistiques de l'index
|
|
34
|
+
*/
|
|
35
|
+
getStats(): {
|
|
36
|
+
totalDocuments: number;
|
|
37
|
+
totalServices: number;
|
|
38
|
+
indexSize: string;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Vérifie si l'index est prêt
|
|
42
|
+
*/
|
|
43
|
+
isReady(): boolean;
|
|
44
|
+
}
|
|
45
|
+
export {};
|