@retrivora-ai/rag-engine 2.2.9 → 2.3.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.
- package/dist/{LicenseValidator-CENvo9o2.d.mts → BatchProcessor-7yV-UCHW.d.mts} +142 -3
- package/dist/{LicenseValidator-CsjJp2PP.d.ts → BatchProcessor-BfzuU4cK.d.ts} +142 -3
- package/dist/handlers/index.d.mts +1 -1
- package/dist/handlers/index.d.ts +1 -1
- package/dist/handlers/index.js +883 -328
- package/dist/handlers/index.mjs +883 -328
- package/dist/index-DR_O_B-W.d.ts +394 -0
- package/dist/index-fnpaCuma.d.mts +394 -0
- package/dist/index.css +58 -0
- package/dist/index.d.mts +63 -3
- package/dist/index.d.ts +63 -3
- package/dist/index.js +456 -37
- package/dist/index.mjs +455 -39
- package/dist/server.d.mts +35 -73
- package/dist/server.d.ts +35 -73
- package/dist/server.js +914 -342
- package/dist/server.mjs +914 -342
- package/package.json +1 -1
- package/src/components/ChatWidget.tsx +147 -46
- package/src/components/ChatWindow.tsx +52 -8
- package/src/core/BatchProcessor.ts +42 -4
- package/src/core/CircuitBreaker.ts +118 -0
- package/src/core/DatabaseStorage.ts +55 -24
- package/src/core/FreeTierLimitsGuard.ts +281 -0
- package/src/core/LicenseValidator.ts +69 -3
- package/src/core/LicenseVerifier.ts +43 -14
- package/src/core/VectorPlugin.ts +30 -0
- package/src/handlers/index.ts +495 -38
- package/src/index.css +58 -0
- package/src/index.ts +4 -0
- package/src/server.ts +1 -0
- package/dist/index-BPJ3KDYI.d.ts +0 -195
- package/dist/index-Dmq5lH0j.d.mts +0 -195
package/dist/server.mjs
CHANGED
|
@@ -150,7 +150,7 @@ var init_ConfigFetcher = __esm({
|
|
|
150
150
|
* Fetch full project configuration (vectorDb + embedding + llm) from Retrivora Control Plane.
|
|
151
151
|
*/
|
|
152
152
|
static async fetchRemoteConfig(projectId, licenseKey) {
|
|
153
|
-
var
|
|
153
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
|
|
154
154
|
const cacheKey = `${projectId}:${licenseKey || ""}`;
|
|
155
155
|
const now = Date.now();
|
|
156
156
|
const cached = this.cache.get(cacheKey);
|
|
@@ -176,7 +176,7 @@ var init_ConfigFetcher = __esm({
|
|
|
176
176
|
});
|
|
177
177
|
if (res.ok) {
|
|
178
178
|
const data = await res.json();
|
|
179
|
-
if ((data == null ? void 0 : data.success) && ((
|
|
179
|
+
if ((data == null ? void 0 : data.success) && ((_a3 = data == null ? void 0 : data.vectorDb) == null ? void 0 : _a3.apiKey)) {
|
|
180
180
|
const fetchedProjectId = data.projectId || projectId;
|
|
181
181
|
const config = {
|
|
182
182
|
projectId: fetchedProjectId,
|
|
@@ -212,9 +212,9 @@ var init_ConfigFetcher = __esm({
|
|
|
212
212
|
}
|
|
213
213
|
/** Convenience: fetch only vector DB config (backwards compat). */
|
|
214
214
|
static async fetchRemoteVectorConfig(projectId, licenseKey) {
|
|
215
|
-
var
|
|
215
|
+
var _a3;
|
|
216
216
|
const config = await this.fetchRemoteConfig(projectId, licenseKey);
|
|
217
|
-
return (
|
|
217
|
+
return (_a3 = config == null ? void 0 : config.vectorDb) != null ? _a3 : null;
|
|
218
218
|
}
|
|
219
219
|
};
|
|
220
220
|
ConfigFetcher.cache = /* @__PURE__ */ new Map();
|
|
@@ -263,7 +263,7 @@ var init_PineconeProvider = __esm({
|
|
|
263
263
|
static getHealthChecker() {
|
|
264
264
|
return {
|
|
265
265
|
async check(config) {
|
|
266
|
-
var
|
|
266
|
+
var _a3, _b;
|
|
267
267
|
const opts = config.options || {};
|
|
268
268
|
const indexName = config.indexName;
|
|
269
269
|
const timestamp = Date.now();
|
|
@@ -271,7 +271,7 @@ var init_PineconeProvider = __esm({
|
|
|
271
271
|
const { Pinecone: Pinecone2 } = await import("@pinecone-database/pinecone");
|
|
272
272
|
const client = new Pinecone2({ apiKey: opts.apiKey });
|
|
273
273
|
const indexes = await client.listIndexes();
|
|
274
|
-
const indexNames = (_b = (
|
|
274
|
+
const indexNames = (_b = (_a3 = indexes.indexes) == null ? void 0 : _a3.map((i) => i.name)) != null ? _b : [];
|
|
275
275
|
if (!indexNames.includes(indexName)) {
|
|
276
276
|
return {
|
|
277
277
|
healthy: false,
|
|
@@ -298,7 +298,7 @@ var init_PineconeProvider = __esm({
|
|
|
298
298
|
};
|
|
299
299
|
}
|
|
300
300
|
async initialize() {
|
|
301
|
-
var
|
|
301
|
+
var _a3, _b;
|
|
302
302
|
if (this.client) return;
|
|
303
303
|
let key = this.apiKey || process.env.PINECONE_API_KEY || "";
|
|
304
304
|
if (!key) {
|
|
@@ -335,7 +335,7 @@ var init_PineconeProvider = __esm({
|
|
|
335
335
|
this.client = new Pinecone({ apiKey: key });
|
|
336
336
|
try {
|
|
337
337
|
const indexes = await this.client.listIndexes();
|
|
338
|
-
const names = (_b = (
|
|
338
|
+
const names = (_b = (_a3 = indexes.indexes) == null ? void 0 : _a3.map((i) => i.name)) != null ? _b : [];
|
|
339
339
|
if (!names.includes(this.indexName)) {
|
|
340
340
|
console.warn(`[PineconeProvider] Target index "${this.indexName}" not listed. Proceeding with configured index name.`);
|
|
341
341
|
}
|
|
@@ -354,13 +354,13 @@ var init_PineconeProvider = __esm({
|
|
|
354
354
|
return namespace ? idx.namespace(namespace) : idx.namespace("");
|
|
355
355
|
}
|
|
356
356
|
async upsert(doc, namespace) {
|
|
357
|
-
var
|
|
357
|
+
var _a3;
|
|
358
358
|
const targetIdx = await this.getActiveIndex(namespace);
|
|
359
359
|
await targetIdx.upsert({
|
|
360
360
|
records: [{
|
|
361
361
|
id: String(doc.id),
|
|
362
362
|
values: doc.vector,
|
|
363
|
-
metadata: __spreadValues({ content: doc.content }, (
|
|
363
|
+
metadata: __spreadValues({ content: doc.content }, (_a3 = doc.metadata) != null ? _a3 : {})
|
|
364
364
|
}]
|
|
365
365
|
});
|
|
366
366
|
}
|
|
@@ -369,18 +369,18 @@ var init_PineconeProvider = __esm({
|
|
|
369
369
|
const BATCH = 100;
|
|
370
370
|
for (let i = 0; i < docs.length; i += BATCH) {
|
|
371
371
|
const records = docs.slice(i, i + BATCH).map((d) => {
|
|
372
|
-
var
|
|
372
|
+
var _a3;
|
|
373
373
|
return {
|
|
374
374
|
id: String(d.id),
|
|
375
375
|
values: d.vector,
|
|
376
|
-
metadata: __spreadValues({ content: d.content }, (
|
|
376
|
+
metadata: __spreadValues({ content: d.content }, (_a3 = d.metadata) != null ? _a3 : {})
|
|
377
377
|
};
|
|
378
378
|
});
|
|
379
379
|
await targetIdx.upsert({ records });
|
|
380
380
|
}
|
|
381
381
|
}
|
|
382
382
|
async query(vector, topK, namespace, filter) {
|
|
383
|
-
var
|
|
383
|
+
var _a3;
|
|
384
384
|
const targetIdx = await this.getActiveIndex(namespace);
|
|
385
385
|
const pineconeFilter = this.sanitizeFilter(filter);
|
|
386
386
|
const result = await targetIdx.query(__spreadValues({
|
|
@@ -388,11 +388,11 @@ var init_PineconeProvider = __esm({
|
|
|
388
388
|
topK,
|
|
389
389
|
includeMetadata: true
|
|
390
390
|
}, Object.keys(pineconeFilter).length > 0 ? { filter: pineconeFilter } : {}));
|
|
391
|
-
return ((
|
|
392
|
-
var
|
|
391
|
+
return ((_a3 = result.matches) != null ? _a3 : []).map((m) => {
|
|
392
|
+
var _a4, _b;
|
|
393
393
|
return {
|
|
394
394
|
id: m.id,
|
|
395
|
-
score: (
|
|
395
|
+
score: (_a4 = m.score) != null ? _a4 : 0,
|
|
396
396
|
content: ((_b = m.metadata) == null ? void 0 : _b.content) || "",
|
|
397
397
|
metadata: m.metadata
|
|
398
398
|
};
|
|
@@ -435,13 +435,13 @@ var init_PostgreSQLProvider = __esm({
|
|
|
435
435
|
init_BaseVectorProvider();
|
|
436
436
|
PostgreSQLProvider = class extends BaseVectorProvider {
|
|
437
437
|
constructor(config) {
|
|
438
|
-
var
|
|
438
|
+
var _a3;
|
|
439
439
|
super(config);
|
|
440
440
|
this.tableName = this.indexName.replace(/[^a-z0-9_]/gi, "_");
|
|
441
441
|
const opts = config.options;
|
|
442
442
|
if (!opts.connectionString) throw new Error("[PostgreSQLProvider] options.connectionString is required");
|
|
443
443
|
this.connectionString = opts.connectionString;
|
|
444
|
-
this.dimensions = (
|
|
444
|
+
this.dimensions = (_a3 = opts.dimensions) != null ? _a3 : 1536;
|
|
445
445
|
}
|
|
446
446
|
static getValidator() {
|
|
447
447
|
return {
|
|
@@ -522,7 +522,7 @@ var init_PostgreSQLProvider = __esm({
|
|
|
522
522
|
}
|
|
523
523
|
}
|
|
524
524
|
async upsert(doc, namespace = "") {
|
|
525
|
-
var
|
|
525
|
+
var _a3;
|
|
526
526
|
const vectorLiteral = `[${doc.vector.join(",")}]`;
|
|
527
527
|
await this.pool.query(
|
|
528
528
|
`INSERT INTO ${this.tableName} (id, namespace, content, metadata, embedding)
|
|
@@ -532,7 +532,7 @@ var init_PostgreSQLProvider = __esm({
|
|
|
532
532
|
content = EXCLUDED.content,
|
|
533
533
|
metadata = EXCLUDED.metadata,
|
|
534
534
|
embedding = EXCLUDED.embedding`,
|
|
535
|
-
[doc.id, namespace, doc.content, JSON.stringify((
|
|
535
|
+
[doc.id, namespace, doc.content, JSON.stringify((_a3 = doc.metadata) != null ? _a3 : {}), vectorLiteral]
|
|
536
536
|
);
|
|
537
537
|
}
|
|
538
538
|
async batchUpsert(docs, namespace = "") {
|
|
@@ -545,9 +545,9 @@ var init_PostgreSQLProvider = __esm({
|
|
|
545
545
|
const batch = docs.slice(i, i + BATCH_SIZE);
|
|
546
546
|
const values = [];
|
|
547
547
|
const valuePlaceholders = batch.map((doc, idx) => {
|
|
548
|
-
var
|
|
548
|
+
var _a3;
|
|
549
549
|
const offset = idx * 5;
|
|
550
|
-
values.push(doc.id, namespace, doc.content, JSON.stringify((
|
|
550
|
+
values.push(doc.id, namespace, doc.content, JSON.stringify((_a3 = doc.metadata) != null ? _a3 : {}), `[${doc.vector.join(",")}]`);
|
|
551
551
|
return `($${offset + 1}, $${offset + 2}, $${offset + 3}, $${offset + 4}, $${offset + 5}::vector)`;
|
|
552
552
|
}).join(", ");
|
|
553
553
|
const query = `
|
|
@@ -630,8 +630,8 @@ var init_PostgreSQLProvider = __esm({
|
|
|
630
630
|
|
|
631
631
|
// src/utils/synonyms.ts
|
|
632
632
|
function resolveMetadataValue(meta, uiKey) {
|
|
633
|
-
var
|
|
634
|
-
const synonyms = (
|
|
633
|
+
var _a3;
|
|
634
|
+
const synonyms = (_a3 = FIELD_SYNONYMS[uiKey]) != null ? _a3 : [];
|
|
635
635
|
const keys = Object.keys(meta);
|
|
636
636
|
const systemKeys = ["namespace", "filename", "filesize", "filetype", "docid", "uploadedat", "dimension", "chunkindex"];
|
|
637
637
|
let match = keys.find((k) => k.toLowerCase() === uiKey.toLowerCase());
|
|
@@ -718,14 +718,14 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
718
718
|
init_synonyms();
|
|
719
719
|
MultiTablePostgresProvider = class extends BaseVectorProvider {
|
|
720
720
|
constructor(config) {
|
|
721
|
-
var
|
|
721
|
+
var _a3, _b, _c;
|
|
722
722
|
super(config);
|
|
723
723
|
const opts = config.options || {};
|
|
724
724
|
if (!opts.connectionString) {
|
|
725
725
|
throw new Error("[MultiTablePostgresProvider] options.connectionString is required");
|
|
726
726
|
}
|
|
727
727
|
this.connectionString = opts.connectionString;
|
|
728
|
-
this.dimensions = (
|
|
728
|
+
this.dimensions = (_a3 = opts.dimensions) != null ? _a3 : 768;
|
|
729
729
|
this.tables = [];
|
|
730
730
|
const rawSearchFields = (_c = (_b = opts.searchFields) != null ? _b : process.env.VECTOR_DB_SEARCH_FIELDS) != null ? _c : ["name", "product_name", "productname", "title"];
|
|
731
731
|
this.searchFields = typeof rawSearchFields === "string" ? rawSearchFields.split(",").map((f) => f.trim()).filter(Boolean) : rawSearchFields;
|
|
@@ -783,11 +783,11 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
783
783
|
* Batch upsert documents by dynamically provisioning tables and columns based on CSV headers.
|
|
784
784
|
*/
|
|
785
785
|
async batchUpsert(docs, namespace = "") {
|
|
786
|
-
var
|
|
786
|
+
var _a3;
|
|
787
787
|
if (docs.length === 0) return;
|
|
788
788
|
const docsByFile = {};
|
|
789
789
|
for (const doc of docs) {
|
|
790
|
-
const fileName = ((
|
|
790
|
+
const fileName = ((_a3 = doc.metadata) == null ? void 0 : _a3.fileName) || this.uploadTable;
|
|
791
791
|
if (!docsByFile[fileName]) docsByFile[fileName] = [];
|
|
792
792
|
docsByFile[fileName].push(doc);
|
|
793
793
|
}
|
|
@@ -840,11 +840,11 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
840
840
|
const headerColumns = csvHeaders.map((h) => `"${h}"`).join(", ");
|
|
841
841
|
const allColumns = `id, ${headerColumns ? headerColumns + ", " : ""}namespace, content, metadata, embedding`;
|
|
842
842
|
const valuePlaceholders = batch.map((doc, idx) => {
|
|
843
|
-
var
|
|
843
|
+
var _a4, _b;
|
|
844
844
|
const offset = idx * (5 + csvHeaders.length);
|
|
845
845
|
values.push(doc.id);
|
|
846
846
|
for (const h of csvHeaders) {
|
|
847
|
-
values.push(String(((
|
|
847
|
+
values.push(String(((_a4 = doc.metadata) == null ? void 0 : _a4[h]) || ""));
|
|
848
848
|
}
|
|
849
849
|
values.push(namespace, doc.content, JSON.stringify((_b = doc.metadata) != null ? _b : {}), `[${doc.vector.join(",")}]`);
|
|
850
850
|
const docPlaceholders = [];
|
|
@@ -883,7 +883,7 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
883
883
|
* Query all configured tables and merge results, sorted by cosine similarity score.
|
|
884
884
|
*/
|
|
885
885
|
async query(vector, topK, _namespace, _filter) {
|
|
886
|
-
var
|
|
886
|
+
var _a3;
|
|
887
887
|
if (!this.pool) {
|
|
888
888
|
throw new Error("[MultiTablePostgresProvider] Provider not initialized. Call initialize() first.");
|
|
889
889
|
}
|
|
@@ -914,11 +914,11 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
914
914
|
const filterParams = [];
|
|
915
915
|
if (metadataFilters && Object.keys(metadataFilters).length > 0) {
|
|
916
916
|
const conditions = Object.entries(metadataFilters).map(([key, val]) => {
|
|
917
|
-
var
|
|
917
|
+
var _a5;
|
|
918
918
|
filterParams.push(String(val));
|
|
919
919
|
const baseOffset = queryText && dynamicKeywordQuery ? 2 : 1;
|
|
920
920
|
const paramIdx = baseOffset + filterParams.length;
|
|
921
|
-
const synonyms = (
|
|
921
|
+
const synonyms = (_a5 = FIELD_SYNONYMS[key]) != null ? _a5 : [];
|
|
922
922
|
const keysToCheck = [key, ...synonyms];
|
|
923
923
|
const coalesceExprs = keysToCheck.flatMap((k) => [
|
|
924
924
|
`metadata->>'${k}'`,
|
|
@@ -987,7 +987,7 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
987
987
|
}
|
|
988
988
|
const tableResults = [];
|
|
989
989
|
for (const row of result.rows) {
|
|
990
|
-
const
|
|
990
|
+
const _a4 = row, { hybrid_score, id } = _a4, rest = __objRest(_a4, ["hybrid_score", "id"]);
|
|
991
991
|
delete rest.embedding;
|
|
992
992
|
delete rest.vector_score;
|
|
993
993
|
delete rest.keyword_score;
|
|
@@ -1016,10 +1016,10 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
1016
1016
|
}
|
|
1017
1017
|
allResults.sort((a, b) => b.score - a.score);
|
|
1018
1018
|
if (allResults.length === 0) return [];
|
|
1019
|
-
const bestMatchTable = (
|
|
1019
|
+
const bestMatchTable = (_a3 = allResults[0].metadata) == null ? void 0 : _a3.source_table;
|
|
1020
1020
|
const finalSorted = allResults.filter((res) => {
|
|
1021
|
-
var
|
|
1022
|
-
return ((
|
|
1021
|
+
var _a4;
|
|
1022
|
+
return ((_a4 = res.metadata) == null ? void 0 : _a4.source_table) === bestMatchTable;
|
|
1023
1023
|
});
|
|
1024
1024
|
console.log(`[MultiTablePostgresProvider] --- Search Complete ---`);
|
|
1025
1025
|
console.log(`[MultiTablePostgresProvider] Final top match from "${bestMatchTable}" with score ${finalSorted[0].score.toFixed(4)}`);
|
|
@@ -1424,14 +1424,14 @@ var init_QdrantProvider = __esm({
|
|
|
1424
1424
|
* Samples points from the collection to discover available payload fields.
|
|
1425
1425
|
*/
|
|
1426
1426
|
async discoverSchema() {
|
|
1427
|
-
var
|
|
1427
|
+
var _a3;
|
|
1428
1428
|
try {
|
|
1429
1429
|
const { data } = await this.http.post(`/collections/${this.indexName}/points/scroll`, {
|
|
1430
1430
|
limit: 20,
|
|
1431
1431
|
with_payload: true,
|
|
1432
1432
|
with_vector: false
|
|
1433
1433
|
});
|
|
1434
|
-
const points = ((
|
|
1434
|
+
const points = ((_a3 = data.result) == null ? void 0 : _a3.points) || [];
|
|
1435
1435
|
const keys = /* @__PURE__ */ new Set();
|
|
1436
1436
|
for (const point of points) {
|
|
1437
1437
|
const payload = point.payload || {};
|
|
@@ -1457,12 +1457,12 @@ var init_QdrantProvider = __esm({
|
|
|
1457
1457
|
* Ensures the collection exists. Creates it if missing.
|
|
1458
1458
|
*/
|
|
1459
1459
|
async ensureCollection() {
|
|
1460
|
-
var
|
|
1460
|
+
var _a3;
|
|
1461
1461
|
try {
|
|
1462
1462
|
await this.http.get(`/collections/${this.indexName}`);
|
|
1463
1463
|
console.log(`[QdrantProvider] \u2705 Collection "${this.indexName}" already exists.`);
|
|
1464
1464
|
} catch (err) {
|
|
1465
|
-
if (axios4.isAxiosError(err) && ((
|
|
1465
|
+
if (axios4.isAxiosError(err) && ((_a3 = err.response) == null ? void 0 : _a3.status) === 404) {
|
|
1466
1466
|
const opts = this.config.options;
|
|
1467
1467
|
const dimensionsForCreate = opts.dimensions || 1536;
|
|
1468
1468
|
console.log(`[QdrantProvider] \u23F3 Creating collection "${this.indexName}" (dimensions: ${dimensionsForCreate})...`);
|
|
@@ -1482,7 +1482,7 @@ var init_QdrantProvider = __esm({
|
|
|
1482
1482
|
* Ensures that a payload field has an index.
|
|
1483
1483
|
*/
|
|
1484
1484
|
async ensureIndex(fieldName, schema = "keyword") {
|
|
1485
|
-
var
|
|
1485
|
+
var _a3;
|
|
1486
1486
|
let fullPath = fieldName;
|
|
1487
1487
|
if (!this.isFlatPayload && !fieldName.includes(".") && fieldName !== "namespace" && fieldName !== this.contentField) {
|
|
1488
1488
|
fullPath = `${this.metadataField}.${fieldName}`;
|
|
@@ -1495,7 +1495,7 @@ var init_QdrantProvider = __esm({
|
|
|
1495
1495
|
console.log(`[QdrantProvider] \u2705 Ensured ${schema} index for "${fullPath}"`);
|
|
1496
1496
|
} catch (err) {
|
|
1497
1497
|
let status;
|
|
1498
|
-
if (axios4.isAxiosError(err)) status = (
|
|
1498
|
+
if (axios4.isAxiosError(err)) status = (_a3 = err.response) == null ? void 0 : _a3.status;
|
|
1499
1499
|
if (status === 409) return;
|
|
1500
1500
|
console.warn(`[QdrantProvider] \u26A0\uFE0F Could not ensure index for "${fullPath}":`, err instanceof Error ? err.message : String(err));
|
|
1501
1501
|
}
|
|
@@ -1524,7 +1524,7 @@ var init_QdrantProvider = __esm({
|
|
|
1524
1524
|
await this.http.put(`/collections/${this.indexName}/points`, payload);
|
|
1525
1525
|
}
|
|
1526
1526
|
async query(vector, topK, namespace, _filter) {
|
|
1527
|
-
var
|
|
1527
|
+
var _a3;
|
|
1528
1528
|
const must = [];
|
|
1529
1529
|
if (namespace) {
|
|
1530
1530
|
must.push({ key: "namespace", match: { value: namespace } });
|
|
@@ -1546,7 +1546,7 @@ var init_QdrantProvider = __esm({
|
|
|
1546
1546
|
limit: topK,
|
|
1547
1547
|
with_payload: true,
|
|
1548
1548
|
params: {
|
|
1549
|
-
hnsw_ef: ((
|
|
1549
|
+
hnsw_ef: ((_a3 = this.config.options) == null ? void 0 : _a3.efSearch) || Math.max(topK * 20, 128),
|
|
1550
1550
|
exact: false
|
|
1551
1551
|
},
|
|
1552
1552
|
filter: must.length > 0 ? { must } : void 0
|
|
@@ -1641,13 +1641,13 @@ var init_ChromaDBProvider = __esm({
|
|
|
1641
1641
|
* Get or create the ChromaDB collection.
|
|
1642
1642
|
*/
|
|
1643
1643
|
async initialize() {
|
|
1644
|
-
var
|
|
1644
|
+
var _a3;
|
|
1645
1645
|
try {
|
|
1646
1646
|
const { data } = await this.http.get(`/api/v1/collections/${this.indexName}`);
|
|
1647
1647
|
this.collectionId = data.id;
|
|
1648
1648
|
console.log(`[ChromaDBProvider] \u2705 Collection "${this.indexName}" found (id: ${this.collectionId})`);
|
|
1649
1649
|
} catch (err) {
|
|
1650
|
-
if (axios5.isAxiosError(err) && ((
|
|
1650
|
+
if (axios5.isAxiosError(err) && ((_a3 = err.response) == null ? void 0 : _a3.status) === 404) {
|
|
1651
1651
|
console.log(`[ChromaDBProvider] \u23F3 Collection "${this.indexName}" not found. Creating...`);
|
|
1652
1652
|
const { data } = await this.http.post("/api/v1/collections", {
|
|
1653
1653
|
name: this.indexName
|
|
@@ -1868,7 +1868,7 @@ var init_WeaviateProvider = __esm({
|
|
|
1868
1868
|
await this.http.post("/v1/batch/objects", payload);
|
|
1869
1869
|
}
|
|
1870
1870
|
async query(vector, topK, namespace, _filter) {
|
|
1871
|
-
var
|
|
1871
|
+
var _a3, _b;
|
|
1872
1872
|
const queryText = _filter == null ? void 0 : _filter.queryText;
|
|
1873
1873
|
const sanitizedFilter = this.sanitizeFilter(_filter);
|
|
1874
1874
|
const searchParams = queryText ? `hybrid: { query: ${JSON.stringify(queryText)}, alpha: 0.5 }` : `nearVector: { vector: ${JSON.stringify(vector)} }`;
|
|
@@ -1894,7 +1894,7 @@ var init_WeaviateProvider = __esm({
|
|
|
1894
1894
|
`
|
|
1895
1895
|
};
|
|
1896
1896
|
const { data } = await this.http.post("/v1/graphql", graphqlQuery);
|
|
1897
|
-
const results = ((_b = (
|
|
1897
|
+
const results = ((_b = (_a3 = data.data) == null ? void 0 : _a3.Get) == null ? void 0 : _b[this.indexName]) || [];
|
|
1898
1898
|
return results.map((res) => ({
|
|
1899
1899
|
id: res["_additional"].id,
|
|
1900
1900
|
score: 1 - res["_additional"].distance,
|
|
@@ -1977,21 +1977,21 @@ var init_UniversalVectorProvider = __esm({
|
|
|
1977
1977
|
}
|
|
1978
1978
|
}
|
|
1979
1979
|
async initialize() {
|
|
1980
|
-
var
|
|
1980
|
+
var _a3;
|
|
1981
1981
|
this.http = axios8.create({
|
|
1982
1982
|
baseURL: this.opts.baseUrl,
|
|
1983
1983
|
headers: __spreadValues({
|
|
1984
1984
|
"Content-Type": "application/json"
|
|
1985
1985
|
}, this.opts.headers),
|
|
1986
|
-
timeout: (
|
|
1986
|
+
timeout: (_a3 = this.opts.timeout) != null ? _a3 : 3e4
|
|
1987
1987
|
});
|
|
1988
1988
|
if (!await this.ping()) {
|
|
1989
1989
|
throw new Error(`[UniversalVectorProvider] Failed to connect to ${this.opts.baseUrl}`);
|
|
1990
1990
|
}
|
|
1991
1991
|
}
|
|
1992
1992
|
async upsert(doc, namespace) {
|
|
1993
|
-
var
|
|
1994
|
-
const endpoint = (
|
|
1993
|
+
var _a3, _b, _c;
|
|
1994
|
+
const endpoint = (_a3 = this.opts.upsertEndpoint) != null ? _a3 : "/upsert";
|
|
1995
1995
|
const template = (_b = this.opts.upsertTemplate) != null ? _b : JSON.stringify({
|
|
1996
1996
|
id: "{{id}}",
|
|
1997
1997
|
vector: "{{vector}}",
|
|
@@ -2024,8 +2024,8 @@ var init_UniversalVectorProvider = __esm({
|
|
|
2024
2024
|
}
|
|
2025
2025
|
}
|
|
2026
2026
|
async query(vector, topK, namespace, filter) {
|
|
2027
|
-
var
|
|
2028
|
-
const endpoint = (
|
|
2027
|
+
var _a3, _b;
|
|
2028
|
+
const endpoint = (_a3 = this.opts.queryEndpoint) != null ? _a3 : "/query";
|
|
2029
2029
|
const template = (_b = this.opts.queryTemplate) != null ? _b : JSON.stringify({
|
|
2030
2030
|
vector: "{{vector}}",
|
|
2031
2031
|
limit: "{{topK}}",
|
|
@@ -2051,9 +2051,9 @@ var init_UniversalVectorProvider = __esm({
|
|
|
2051
2051
|
);
|
|
2052
2052
|
}
|
|
2053
2053
|
return results.map((item) => {
|
|
2054
|
-
var
|
|
2054
|
+
var _a4, _b2, _c, _d, _e, _f, _g2;
|
|
2055
2055
|
return {
|
|
2056
|
-
id: item[(
|
|
2056
|
+
id: item[(_a4 = this.opts.queryIdField) != null ? _a4 : "id"],
|
|
2057
2057
|
score: (_c = item[(_b2 = this.opts.queryScoreField) != null ? _b2 : "score"]) != null ? _c : 0,
|
|
2058
2058
|
content: (_e = item[(_d = this.opts.queryContentField) != null ? _d : "content"]) != null ? _e : "",
|
|
2059
2059
|
metadata: (_g2 = item[(_f = this.opts.queryMetadataField) != null ? _f : "metadata"]) != null ? _g2 : {}
|
|
@@ -2066,8 +2066,8 @@ var init_UniversalVectorProvider = __esm({
|
|
|
2066
2066
|
}
|
|
2067
2067
|
}
|
|
2068
2068
|
async delete(id, namespace) {
|
|
2069
|
-
var
|
|
2070
|
-
const endpoint = (
|
|
2069
|
+
var _a3, _b;
|
|
2070
|
+
const endpoint = (_a3 = this.opts.deleteEndpoint) != null ? _a3 : "/delete";
|
|
2071
2071
|
const template = (_b = this.opts.deleteTemplate) != null ? _b : JSON.stringify({
|
|
2072
2072
|
id: "{{id}}",
|
|
2073
2073
|
namespace: "{{namespace}}"
|
|
@@ -2085,8 +2085,8 @@ var init_UniversalVectorProvider = __esm({
|
|
|
2085
2085
|
}
|
|
2086
2086
|
}
|
|
2087
2087
|
async deleteNamespace(namespace) {
|
|
2088
|
-
var
|
|
2089
|
-
const endpoint = (
|
|
2088
|
+
var _a3;
|
|
2089
|
+
const endpoint = (_a3 = this.opts.deleteNamespaceEndpoint) != null ? _a3 : "/delete-namespace";
|
|
2090
2090
|
try {
|
|
2091
2091
|
await this.http.post(endpoint, { namespace });
|
|
2092
2092
|
} catch (error) {
|
|
@@ -2096,9 +2096,9 @@ var init_UniversalVectorProvider = __esm({
|
|
|
2096
2096
|
}
|
|
2097
2097
|
}
|
|
2098
2098
|
async ping() {
|
|
2099
|
-
var
|
|
2099
|
+
var _a3;
|
|
2100
2100
|
try {
|
|
2101
|
-
const endpoint = (
|
|
2101
|
+
const endpoint = (_a3 = this.opts.pingEndpoint) != null ? _a3 : "/health";
|
|
2102
2102
|
const response = await this.http.get(endpoint, { timeout: 5e3 });
|
|
2103
2103
|
return response.status >= 200 && response.status < 300;
|
|
2104
2104
|
} catch (e) {
|
|
@@ -2242,13 +2242,13 @@ var LicenseValidationError = class extends RetrivoraError {
|
|
|
2242
2242
|
}
|
|
2243
2243
|
};
|
|
2244
2244
|
function wrapError(err, defaultCode, defaultMessage) {
|
|
2245
|
-
var
|
|
2245
|
+
var _a3;
|
|
2246
2246
|
if (err instanceof RetrivoraError) {
|
|
2247
2247
|
return err;
|
|
2248
2248
|
}
|
|
2249
2249
|
const error = err;
|
|
2250
2250
|
const message = (error == null ? void 0 : error.message) || defaultMessage || String(err);
|
|
2251
|
-
const status = (error == null ? void 0 : error.status) || (error == null ? void 0 : error.statusCode) || ((
|
|
2251
|
+
const status = (error == null ? void 0 : error.status) || (error == null ? void 0 : error.statusCode) || ((_a3 = error == null ? void 0 : error.response) == null ? void 0 : _a3.status);
|
|
2252
2252
|
const code = error == null ? void 0 : error.code;
|
|
2253
2253
|
if (status === 429 || /rate[- ]?limit/i.test(message) || code === "RATE_LIMIT_EXCEEDED") {
|
|
2254
2254
|
return new RateLimitException(message, err);
|
|
@@ -2317,7 +2317,8 @@ var LicenseVerifier = class {
|
|
|
2317
2317
|
};
|
|
2318
2318
|
}
|
|
2319
2319
|
try {
|
|
2320
|
-
const
|
|
2320
|
+
const sanitizedKey = (licenseKey || "").trim().replace(/^["']|["']$/g, "").trim();
|
|
2321
|
+
const rawToken = sanitizedKey.replace(/^rtv_/i, "").trim();
|
|
2321
2322
|
const parts = rawToken.split(".");
|
|
2322
2323
|
if (parts.length !== 3) {
|
|
2323
2324
|
throw new Error("Malformed token structure (expected 3 parts).");
|
|
@@ -2529,8 +2530,8 @@ var UI_BORDER_RADIUS_OPTIONS = ["none", "sm", "md", "lg", "xl", "full"];
|
|
|
2529
2530
|
|
|
2530
2531
|
// src/config/serverConfig.ts
|
|
2531
2532
|
function readString(env, name) {
|
|
2532
|
-
var
|
|
2533
|
-
const value = (
|
|
2533
|
+
var _a3;
|
|
2534
|
+
const value = (_a3 = env[name]) == null ? void 0 : _a3.trim();
|
|
2534
2535
|
return value ? value : void 0;
|
|
2535
2536
|
}
|
|
2536
2537
|
function readNumber(env, name, fallback) {
|
|
@@ -2543,8 +2544,8 @@ function readNumber(env, name, fallback) {
|
|
|
2543
2544
|
return parsed;
|
|
2544
2545
|
}
|
|
2545
2546
|
function readEnum(env, name, fallback, allowed) {
|
|
2546
|
-
var
|
|
2547
|
-
const value = (
|
|
2547
|
+
var _a3;
|
|
2548
|
+
const value = (_a3 = readString(env, name)) != null ? _a3 : fallback;
|
|
2548
2549
|
if (allowed.includes(value)) {
|
|
2549
2550
|
return value;
|
|
2550
2551
|
}
|
|
@@ -2554,8 +2555,8 @@ function getRagConfig(baseConfig, env = process.env) {
|
|
|
2554
2555
|
return getEnvConfig(env, baseConfig);
|
|
2555
2556
|
}
|
|
2556
2557
|
function getEnvConfig(env = process.env, base) {
|
|
2557
|
-
var
|
|
2558
|
-
const licenseKey = (_d = (_c = (_b = (
|
|
2558
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X, _Y, _Z, __, _$, _aa, _ba, _ca, _da, _ea, _fa, _ga, _ha, _ia, _ja, _ka, _la, _ma, _na, _oa, _pa, _qa, _ra, _sa, _ta, _ua, _va, _wa, _xa, _ya, _za, _Aa, _Ba, _Ca, _Da, _Ea, _Fa, _Ga, _Ha, _Ia, _Ja, _Ka, _La, _Ma, _Na, _Oa, _Pa, _Qa, _Ra, _Sa, _Ta, _Ua, _Va, _Wa, _Xa, _Ya, _Za, __a, _$a, _ab, _bb, _cb, _db, _eb, _fb, _gb, _hb, _ib, _jb, _kb, _lb, _mb, _nb, _ob, _pb, _qb, _rb, _sb, _tb, _ub, _vb, _wb, _xb, _yb, _zb, _Ab, _Bb, _Cb, _Db, _Eb, _Fb, _Gb, _Hb, _Ib, _Jb, _Kb;
|
|
2559
|
+
const licenseKey = (_d = (_c = (_b = (_a3 = readString(env, "RAG_LICENSE_KEY")) != null ? _a3 : readString(env, "RETRIVORA_LICENSE_KEY")) != null ? _b : readString(env, "NEXT_PUBLIC_RETRIVORA_LICENSE_KEY")) != null ? _c : readString(env, "LICENSE_KEY")) != null ? _d : base == null ? void 0 : base.licenseKey;
|
|
2559
2560
|
const jwtProjectId = (() => {
|
|
2560
2561
|
if (!licenseKey) return void 0;
|
|
2561
2562
|
try {
|
|
@@ -2636,7 +2637,7 @@ function getEnvConfig(env = process.env, base) {
|
|
|
2636
2637
|
rest: "default",
|
|
2637
2638
|
custom: "default"
|
|
2638
2639
|
};
|
|
2639
|
-
const
|
|
2640
|
+
const isFreeTier2 = (() => {
|
|
2640
2641
|
if (!licenseKey) return true;
|
|
2641
2642
|
try {
|
|
2642
2643
|
const payload = LicenseVerifier.verify(licenseKey, projectId);
|
|
@@ -2647,13 +2648,13 @@ function getEnvConfig(env = process.env, base) {
|
|
|
2647
2648
|
}
|
|
2648
2649
|
})();
|
|
2649
2650
|
const defaultGatewayUrl = (_ra = (_qa = readString(env, "LITELLM_BASE_URL")) != null ? _qa : readString(env, "LLM_BASE_URL")) != null ? _ra : "https://www.retrivora.com/api/v1";
|
|
2650
|
-
const defaultLlmProvider =
|
|
2651
|
+
const defaultLlmProvider = isFreeTier2 ? "universal_rest" : "universal_rest";
|
|
2651
2652
|
const llmProvider = (_ua = (_ta = readEnum(env, "LLM_PROVIDER", defaultLlmProvider, LLM_PROVIDERS)) != null ? _ta : (_sa = base == null ? void 0 : base.llm) == null ? void 0 : _sa.provider) != null ? _ua : defaultLlmProvider;
|
|
2652
2653
|
const llmBaseUrl = (_ya = (_xa = (_va = readString(env, "LITELLM_BASE_URL")) != null ? _va : readString(env, "LLM_BASE_URL")) != null ? _xa : (_wa = base == null ? void 0 : base.llm) == null ? void 0 : _wa.baseUrl) != null ? _ya : defaultGatewayUrl;
|
|
2653
|
-
const llmModel = (_Ca = (_Aa = readString(env, "LLM_MODEL")) != null ? _Aa : (_za = base == null ? void 0 : base.llm) == null ? void 0 : _za.model) != null ? _Ca :
|
|
2654
|
+
const llmModel = (_Ca = (_Aa = readString(env, "LLM_MODEL")) != null ? _Aa : (_za = base == null ? void 0 : base.llm) == null ? void 0 : _za.model) != null ? _Ca : isFreeTier2 ? "llama-3.1-8b-instant" : (_Ba = DEFAULT_MODEL_BY_PROVIDER[llmProvider]) != null ? _Ba : "gpt-4o";
|
|
2654
2655
|
const llmApiKey = (_Ia = (_Ha = (_Fa = (_Ea = (_Da = llmApiKeyByProvider[llmProvider]) != null ? _Da : readString(env, "LLM_API_KEY")) != null ? _Ea : readString(env, "LITELLM_MASTER_KEY")) != null ? _Fa : readString(env, "LITELLM_API_KEY")) != null ? _Ha : (_Ga = base == null ? void 0 : base.llm) == null ? void 0 : _Ga.apiKey) != null ? _Ia : licenseKey;
|
|
2655
2656
|
const llmProfile = (_Ma = (_La = readString(env, "LLM_UNIVERSAL_PROFILE")) != null ? _La : (_Ka = (_Ja = base == null ? void 0 : base.llm) == null ? void 0 : _Ja.options) == null ? void 0 : _Ka.profile) != null ? _Ma : "litellm";
|
|
2656
|
-
const defaultEmbeddingProvider =
|
|
2657
|
+
const defaultEmbeddingProvider = isFreeTier2 ? "universal_rest" : "universal_rest";
|
|
2657
2658
|
const embeddingProvider = (_Pa = (_Oa = readEnum(env, "EMBEDDING_PROVIDER", defaultEmbeddingProvider, EMBEDDING_PROVIDERS)) != null ? _Oa : (_Na = base == null ? void 0 : base.embedding) == null ? void 0 : _Na.provider) != null ? _Pa : defaultEmbeddingProvider;
|
|
2658
2659
|
const embeddingBaseUrl = (_Ua = (_Ta = (_Ra = (_Qa = readString(env, "LITELLM_BASE_URL")) != null ? _Qa : readString(env, "EMBEDDING_BASE_URL")) != null ? _Ra : readString(env, "LLM_BASE_URL")) != null ? _Ta : (_Sa = base == null ? void 0 : base.embedding) == null ? void 0 : _Sa.baseUrl) != null ? _Ua : defaultGatewayUrl;
|
|
2659
2660
|
const embeddingModel = (_Xa = (_Wa = readString(env, "EMBEDDING_MODEL")) != null ? _Wa : (_Va = base == null ? void 0 : base.embedding) == null ? void 0 : _Va.model) != null ? _Xa : "text-embedding-004";
|
|
@@ -2743,8 +2744,8 @@ function getEnvConfig(env = process.env, base) {
|
|
|
2743
2744
|
}
|
|
2744
2745
|
} : {}), {
|
|
2745
2746
|
mcpServers: (() => {
|
|
2746
|
-
var
|
|
2747
|
-
const raw = (
|
|
2747
|
+
var _a4;
|
|
2748
|
+
const raw = (_a4 = readString(env, "MCP_SERVERS")) != null ? _a4 : readString(env, "NEXT_PUBLIC_MCP_SERVERS");
|
|
2748
2749
|
if (!raw) return void 0;
|
|
2749
2750
|
try {
|
|
2750
2751
|
return JSON.parse(raw);
|
|
@@ -2789,10 +2790,10 @@ var ConfigResolver = class {
|
|
|
2789
2790
|
* fallback behavior.
|
|
2790
2791
|
*/
|
|
2791
2792
|
static resolveUniversal(hostConfig, env = process.env) {
|
|
2792
|
-
var
|
|
2793
|
+
var _a3;
|
|
2793
2794
|
if (!hostConfig) return this.resolve(void 0, env);
|
|
2794
2795
|
const normalized = __spreadProps(__spreadValues({}, hostConfig), {
|
|
2795
|
-
vectorDb: (
|
|
2796
|
+
vectorDb: (_a3 = hostConfig.vectorDb) != null ? _a3 : hostConfig.vectorDatabase,
|
|
2796
2797
|
rag: this.mergeRetrievalWorkflow(hostConfig.rag, hostConfig.retrieval, hostConfig.workflow)
|
|
2797
2798
|
});
|
|
2798
2799
|
return this.resolve(normalized, env);
|
|
@@ -2812,11 +2813,11 @@ var ConfigResolver = class {
|
|
|
2812
2813
|
}
|
|
2813
2814
|
}
|
|
2814
2815
|
static mergeRetrievalWorkflow(rag, retrieval, workflow) {
|
|
2815
|
-
var
|
|
2816
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
2816
2817
|
if (!rag && !retrieval && !workflow) return void 0;
|
|
2817
2818
|
const normalized = __spreadValues({}, rag != null ? rag : {});
|
|
2818
2819
|
if (retrieval) {
|
|
2819
|
-
normalized.topK = (
|
|
2820
|
+
normalized.topK = (_a3 = retrieval.topK) != null ? _a3 : normalized.topK;
|
|
2820
2821
|
normalized.scoreThreshold = (_b = retrieval.scoreThreshold) != null ? _b : normalized.scoreThreshold;
|
|
2821
2822
|
normalized.useReranking = (_c = retrieval.useReranking) != null ? _c : normalized.useReranking;
|
|
2822
2823
|
if (retrieval.strategy === "hybrid") normalized.architecture = (_d = normalized.architecture) != null ? _d : "hybrid";
|
|
@@ -2944,8 +2945,8 @@ var OpenAIProvider = class {
|
|
|
2944
2945
|
};
|
|
2945
2946
|
}
|
|
2946
2947
|
async chat(messages, context, options) {
|
|
2947
|
-
var
|
|
2948
|
-
const basePrompt = (_b = (
|
|
2948
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i;
|
|
2949
|
+
const basePrompt = (_b = (_a3 = options == null ? void 0 : options.systemPrompt) != null ? _a3 : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Answer questions based on the provided context.";
|
|
2949
2950
|
const systemMessage = {
|
|
2950
2951
|
role: "system",
|
|
2951
2952
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -2969,8 +2970,8 @@ var OpenAIProvider = class {
|
|
|
2969
2970
|
}
|
|
2970
2971
|
chatStream(messages, context, options) {
|
|
2971
2972
|
return __asyncGenerator(this, null, function* () {
|
|
2972
|
-
var
|
|
2973
|
-
const basePrompt = (_b = (
|
|
2973
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h;
|
|
2974
|
+
const basePrompt = (_b = (_a3 = options == null ? void 0 : options.systemPrompt) != null ? _a3 : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Answer questions based on the provided context.";
|
|
2974
2975
|
const systemMessage = {
|
|
2975
2976
|
role: "system",
|
|
2976
2977
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3017,8 +3018,8 @@ var OpenAIProvider = class {
|
|
|
3017
3018
|
return results[0];
|
|
3018
3019
|
}
|
|
3019
3020
|
async batchEmbed(texts, options) {
|
|
3020
|
-
var
|
|
3021
|
-
const model = (_c = (_b = options == null ? void 0 : options.model) != null ? _b : (
|
|
3021
|
+
var _a3, _b, _c, _d, _e;
|
|
3022
|
+
const model = (_c = (_b = options == null ? void 0 : options.model) != null ? _b : (_a3 = this.embeddingConfig) == null ? void 0 : _a3.model) != null ? _c : "text-embedding-3-small";
|
|
3022
3023
|
const apiKey = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.apiKey) != null ? _e : this.llmConfig.apiKey;
|
|
3023
3024
|
const client = apiKey !== this.llmConfig.apiKey ? new OpenAI({ apiKey }) : this.client;
|
|
3024
3025
|
const response = await client.embeddings.create({ model, input: texts });
|
|
@@ -3095,8 +3096,8 @@ var AnthropicProvider = class {
|
|
|
3095
3096
|
};
|
|
3096
3097
|
}
|
|
3097
3098
|
async chat(messages, context, options) {
|
|
3098
|
-
var
|
|
3099
|
-
const basePrompt = (_b = (
|
|
3099
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
|
|
3100
|
+
const basePrompt = (_b = (_a3 = options == null ? void 0 : options.systemPrompt) != null ? _a3 : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Use the context below to answer the user's question accurately.";
|
|
3100
3101
|
const system = buildSystemContent(basePrompt, context);
|
|
3101
3102
|
const anthropicMessages = messages.map((m) => ({
|
|
3102
3103
|
role: m.role === "assistant" ? "assistant" : "user",
|
|
@@ -3134,8 +3135,8 @@ var AnthropicProvider = class {
|
|
|
3134
3135
|
}
|
|
3135
3136
|
chatStream(messages, context, options) {
|
|
3136
3137
|
return __asyncGenerator(this, null, function* () {
|
|
3137
|
-
var
|
|
3138
|
-
const basePrompt = (_b = (
|
|
3138
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
|
|
3139
|
+
const basePrompt = (_b = (_a3 = options == null ? void 0 : options.systemPrompt) != null ? _a3 : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Use the context below to answer the user's question accurately.";
|
|
3139
3140
|
const system = buildSystemContent(basePrompt, context);
|
|
3140
3141
|
const anthropicMessages = messages.map((m) => ({
|
|
3141
3142
|
role: m.role === "assistant" ? "assistant" : "user",
|
|
@@ -3219,8 +3220,8 @@ var AnthropicProvider = class {
|
|
|
3219
3220
|
import axios from "axios";
|
|
3220
3221
|
var OllamaProvider = class {
|
|
3221
3222
|
constructor(llmConfig, embeddingConfig) {
|
|
3222
|
-
var
|
|
3223
|
-
const rawBaseURL = ((
|
|
3223
|
+
var _a3, _b, _c;
|
|
3224
|
+
const rawBaseURL = ((_a3 = llmConfig.baseUrl) != null ? _a3 : "http://localhost:11434").replace(/\/+$/, "");
|
|
3224
3225
|
const baseURL = rawBaseURL.replace(/\/(?:api\/v1|v1|api)$/i, "");
|
|
3225
3226
|
const timeout = Number((_b = llmConfig.options) == null ? void 0 : _b.timeout) || 3e5;
|
|
3226
3227
|
const headers = ((_c = llmConfig.options) == null ? void 0 : _c.headers) || {};
|
|
@@ -3280,8 +3281,8 @@ var OllamaProvider = class {
|
|
|
3280
3281
|
};
|
|
3281
3282
|
}
|
|
3282
3283
|
async chat(messages, context, options) {
|
|
3283
|
-
var
|
|
3284
|
-
const basePrompt = (_b = (
|
|
3284
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
3285
|
+
const basePrompt = (_b = (_a3 = options == null ? void 0 : options.systemPrompt) != null ? _a3 : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Use the provided context to answer the user's question.";
|
|
3285
3286
|
const system = buildSystemContent(basePrompt, context);
|
|
3286
3287
|
const { data } = await this.http.post("/api/chat", {
|
|
3287
3288
|
model: this.llmConfig.model,
|
|
@@ -3299,8 +3300,8 @@ var OllamaProvider = class {
|
|
|
3299
3300
|
}
|
|
3300
3301
|
chatStream(messages, context, options) {
|
|
3301
3302
|
return __asyncGenerator(this, null, function* () {
|
|
3302
|
-
var
|
|
3303
|
-
const basePrompt = (_b = (
|
|
3303
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h;
|
|
3304
|
+
const basePrompt = (_b = (_a3 = options == null ? void 0 : options.systemPrompt) != null ? _a3 : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Use the provided context to answer the user's question.";
|
|
3304
3305
|
const system = buildSystemContent(basePrompt, context);
|
|
3305
3306
|
const response = yield new __await(this.http.post("/api/chat", {
|
|
3306
3307
|
model: this.llmConfig.model,
|
|
@@ -3358,8 +3359,8 @@ var OllamaProvider = class {
|
|
|
3358
3359
|
});
|
|
3359
3360
|
}
|
|
3360
3361
|
async embed(text, options) {
|
|
3361
|
-
var
|
|
3362
|
-
const model = (_c = (_b = options == null ? void 0 : options.model) != null ? _b : (
|
|
3362
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
|
|
3363
|
+
const model = (_c = (_b = options == null ? void 0 : options.model) != null ? _b : (_a3 = this.embeddingConfig) == null ? void 0 : _a3.model) != null ? _c : "nomic-embed-text";
|
|
3363
3364
|
const baseURL = (_f = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.baseUrl) != null ? _e : this.llmConfig.baseUrl) != null ? _f : "http://localhost:11434";
|
|
3364
3365
|
const client = baseURL !== ((_g2 = this.llmConfig.baseUrl) != null ? _g2 : "http://localhost:11434") ? axios.create({ baseURL, timeout: 6e4 }) : this.http;
|
|
3365
3366
|
let prompt = text;
|
|
@@ -3460,9 +3461,9 @@ var GeminiProvider = class {
|
|
|
3460
3461
|
static getHealthChecker() {
|
|
3461
3462
|
return {
|
|
3462
3463
|
async check(config) {
|
|
3463
|
-
var
|
|
3464
|
+
var _a3, _b;
|
|
3464
3465
|
const timestamp = Date.now();
|
|
3465
|
-
const apiKey = (_b = (
|
|
3466
|
+
const apiKey = (_b = (_a3 = config.apiKey) != null ? _a3 : process.env.GOOGLE_GENAI_API_KEY) != null ? _b : "";
|
|
3466
3467
|
const modelName = sanitizeModel(config.model);
|
|
3467
3468
|
try {
|
|
3468
3469
|
const { GoogleGenerativeAI: GoogleGenerativeAI2 } = await import("@google/generative-ai");
|
|
@@ -3492,16 +3493,16 @@ var GeminiProvider = class {
|
|
|
3492
3493
|
/** Resolve the embedding client — uses a separate client when the embedding
|
|
3493
3494
|
* API key differs from the LLM API key. */
|
|
3494
3495
|
get embeddingClient() {
|
|
3495
|
-
var
|
|
3496
|
-
if (((
|
|
3496
|
+
var _a3;
|
|
3497
|
+
if (((_a3 = this.embeddingConfig) == null ? void 0 : _a3.apiKey) && this.embeddingConfig.apiKey !== this.llmConfig.apiKey) {
|
|
3497
3498
|
return buildClient(this.embeddingConfig.apiKey);
|
|
3498
3499
|
}
|
|
3499
3500
|
return this.client;
|
|
3500
3501
|
}
|
|
3501
3502
|
/** Resolve the embedding model to use, in order of specificity. */
|
|
3502
3503
|
resolveEmbeddingModel(optionsModel) {
|
|
3503
|
-
var
|
|
3504
|
-
return sanitizeModel((_b = optionsModel != null ? optionsModel : (
|
|
3504
|
+
var _a3, _b;
|
|
3505
|
+
return sanitizeModel((_b = optionsModel != null ? optionsModel : (_a3 = this.embeddingConfig) == null ? void 0 : _a3.model) != null ? _b : DEFAULT_EMBEDDING_MODEL);
|
|
3505
3506
|
}
|
|
3506
3507
|
/**
|
|
3507
3508
|
* Convert ChatMessage[] to the Gemini contents format.
|
|
@@ -3521,8 +3522,8 @@ var GeminiProvider = class {
|
|
|
3521
3522
|
// ILLMProvider — chat
|
|
3522
3523
|
// -------------------------------------------------------------------------
|
|
3523
3524
|
async chat(messages, context, options) {
|
|
3524
|
-
var
|
|
3525
|
-
const basePrompt = (_b = (
|
|
3525
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
3526
|
+
const basePrompt = (_b = (_a3 = options == null ? void 0 : options.systemPrompt) != null ? _a3 : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Answer questions based on the provided context.";
|
|
3526
3527
|
const model = this.client.getGenerativeModel({
|
|
3527
3528
|
model: this.llmConfig.model,
|
|
3528
3529
|
systemInstruction: buildSystemContent(basePrompt, context)
|
|
@@ -3539,8 +3540,8 @@ var GeminiProvider = class {
|
|
|
3539
3540
|
}
|
|
3540
3541
|
chatStream(messages, context, options) {
|
|
3541
3542
|
return __asyncGenerator(this, null, function* () {
|
|
3542
|
-
var
|
|
3543
|
-
const basePrompt = (_b = (
|
|
3543
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
3544
|
+
const basePrompt = (_b = (_a3 = options == null ? void 0 : options.systemPrompt) != null ? _a3 : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Answer questions based on the provided context.";
|
|
3544
3545
|
const model = this.client.getGenerativeModel({
|
|
3545
3546
|
model: this.llmConfig.model,
|
|
3546
3547
|
systemInstruction: buildSystemContent(basePrompt, context)
|
|
@@ -3575,11 +3576,11 @@ var GeminiProvider = class {
|
|
|
3575
3576
|
// ILLMProvider — embeddings
|
|
3576
3577
|
// -------------------------------------------------------------------------
|
|
3577
3578
|
async embed(text, options) {
|
|
3578
|
-
var
|
|
3579
|
+
var _a3, _b;
|
|
3579
3580
|
const content = applyPrefix(
|
|
3580
3581
|
text,
|
|
3581
3582
|
options == null ? void 0 : options.taskType,
|
|
3582
|
-
(
|
|
3583
|
+
(_a3 = this.embeddingConfig) == null ? void 0 : _a3.queryPrefix,
|
|
3583
3584
|
(_b = this.embeddingConfig) == null ? void 0 : _b.documentPrefix
|
|
3584
3585
|
);
|
|
3585
3586
|
const modelName = this.resolveEmbeddingModel(options == null ? void 0 : options.model);
|
|
@@ -3596,7 +3597,7 @@ var GeminiProvider = class {
|
|
|
3596
3597
|
const modelName = this.resolveEmbeddingModel(options == null ? void 0 : options.model);
|
|
3597
3598
|
const model = this.embeddingClient.getGenerativeModel({ model: modelName });
|
|
3598
3599
|
const requests = texts.map((text) => {
|
|
3599
|
-
var
|
|
3600
|
+
var _a3, _b;
|
|
3600
3601
|
return {
|
|
3601
3602
|
content: {
|
|
3602
3603
|
role: "user",
|
|
@@ -3604,7 +3605,7 @@ var GeminiProvider = class {
|
|
|
3604
3605
|
text: applyPrefix(
|
|
3605
3606
|
text,
|
|
3606
3607
|
options == null ? void 0 : options.taskType,
|
|
3607
|
-
(
|
|
3608
|
+
(_a3 = this.embeddingConfig) == null ? void 0 : _a3.queryPrefix,
|
|
3608
3609
|
(_b = this.embeddingConfig) == null ? void 0 : _b.documentPrefix
|
|
3609
3610
|
)
|
|
3610
3611
|
}]
|
|
@@ -3621,8 +3622,8 @@ var GeminiProvider = class {
|
|
|
3621
3622
|
throw err;
|
|
3622
3623
|
});
|
|
3623
3624
|
return response.embeddings.map((e) => {
|
|
3624
|
-
var
|
|
3625
|
-
return (
|
|
3625
|
+
var _a3;
|
|
3626
|
+
return (_a3 = e.values) != null ? _a3 : [];
|
|
3626
3627
|
});
|
|
3627
3628
|
}
|
|
3628
3629
|
// -------------------------------------------------------------------------
|
|
@@ -3711,8 +3712,8 @@ var GroqProvider = class {
|
|
|
3711
3712
|
};
|
|
3712
3713
|
}
|
|
3713
3714
|
async chat(messages, context, options) {
|
|
3714
|
-
var
|
|
3715
|
-
const basePrompt = (_b = (
|
|
3715
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i;
|
|
3716
|
+
const basePrompt = (_b = (_a3 = options == null ? void 0 : options.systemPrompt) != null ? _a3 : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Answer questions based on the provided context.";
|
|
3716
3717
|
const systemMessage = {
|
|
3717
3718
|
role: "system",
|
|
3718
3719
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3736,8 +3737,8 @@ var GroqProvider = class {
|
|
|
3736
3737
|
}
|
|
3737
3738
|
chatStream(messages, context, options) {
|
|
3738
3739
|
return __asyncGenerator(this, null, function* () {
|
|
3739
|
-
var
|
|
3740
|
-
const basePrompt = (_b = (
|
|
3740
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h;
|
|
3741
|
+
const basePrompt = (_b = (_a3 = options == null ? void 0 : options.systemPrompt) != null ? _a3 : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Answer questions based on the provided context.";
|
|
3741
3742
|
const systemMessage = {
|
|
3742
3743
|
role: "system",
|
|
3743
3744
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3871,8 +3872,8 @@ var QwenProvider = class {
|
|
|
3871
3872
|
};
|
|
3872
3873
|
}
|
|
3873
3874
|
async chat(messages, context, options) {
|
|
3874
|
-
var
|
|
3875
|
-
const basePrompt = (_b = (
|
|
3875
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i;
|
|
3876
|
+
const basePrompt = (_b = (_a3 = options == null ? void 0 : options.systemPrompt) != null ? _a3 : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Answer questions based on the provided context.";
|
|
3876
3877
|
const systemMessage = {
|
|
3877
3878
|
role: "system",
|
|
3878
3879
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3896,8 +3897,8 @@ var QwenProvider = class {
|
|
|
3896
3897
|
}
|
|
3897
3898
|
chatStream(messages, context, options) {
|
|
3898
3899
|
return __asyncGenerator(this, null, function* () {
|
|
3899
|
-
var
|
|
3900
|
-
const basePrompt = (_b = (
|
|
3900
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h;
|
|
3901
|
+
const basePrompt = (_b = (_a3 = options == null ? void 0 : options.systemPrompt) != null ? _a3 : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Answer questions based on the provided context.";
|
|
3901
3902
|
const systemMessage = {
|
|
3902
3903
|
role: "system",
|
|
3903
3904
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3944,8 +3945,8 @@ var QwenProvider = class {
|
|
|
3944
3945
|
return results[0];
|
|
3945
3946
|
}
|
|
3946
3947
|
async batchEmbed(texts, options) {
|
|
3947
|
-
var
|
|
3948
|
-
const model = (_c = (_b = options == null ? void 0 : options.model) != null ? _b : (
|
|
3948
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
3949
|
+
const model = (_c = (_b = options == null ? void 0 : options.model) != null ? _b : (_a3 = this.embeddingConfig) == null ? void 0 : _a3.model) != null ? _c : "text-embedding-v1";
|
|
3949
3950
|
const apiKey = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.apiKey) != null ? _e : this.llmConfig.apiKey;
|
|
3950
3951
|
const client = apiKey !== this.llmConfig.apiKey ? new OpenAI3({
|
|
3951
3952
|
apiKey,
|
|
@@ -4045,9 +4046,9 @@ var VECTOR_PROFILES = {
|
|
|
4045
4046
|
|
|
4046
4047
|
// src/llm/providers/UniversalLLMAdapter.ts
|
|
4047
4048
|
function extractContent(obj) {
|
|
4048
|
-
var
|
|
4049
|
+
var _a3, _b, _c;
|
|
4049
4050
|
if (!obj || typeof obj !== "object") return void 0;
|
|
4050
|
-
const choice = (
|
|
4051
|
+
const choice = (_a3 = obj.choices) == null ? void 0 : _a3[0];
|
|
4051
4052
|
if (!choice) return void 0;
|
|
4052
4053
|
if (typeof ((_b = choice.message) == null ? void 0 : _b.content) === "string") return choice.message.content;
|
|
4053
4054
|
if (typeof ((_c = choice.delta) == null ? void 0 : _c.content) === "string") return choice.delta.content;
|
|
@@ -4057,10 +4058,10 @@ function extractContent(obj) {
|
|
|
4057
4058
|
}
|
|
4058
4059
|
var UniversalLLMAdapter = class {
|
|
4059
4060
|
constructor(config) {
|
|
4060
|
-
var
|
|
4061
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h;
|
|
4061
4062
|
this.model = config.model;
|
|
4062
4063
|
const llmConfig = config;
|
|
4063
|
-
const options = (
|
|
4064
|
+
const options = (_a3 = llmConfig.options) != null ? _a3 : {};
|
|
4064
4065
|
let profile = {};
|
|
4065
4066
|
if (typeof options.profile === "string") {
|
|
4066
4067
|
profile = LLM_PROFILES[options.profile] || {};
|
|
@@ -4086,8 +4087,8 @@ var UniversalLLMAdapter = class {
|
|
|
4086
4087
|
});
|
|
4087
4088
|
}
|
|
4088
4089
|
async chat(messages, context) {
|
|
4089
|
-
var
|
|
4090
|
-
const path2 = (
|
|
4090
|
+
var _a3, _b, _c, _d, _e;
|
|
4091
|
+
const path2 = (_a3 = this.opts.chatPath) != null ? _a3 : "/chat/completions";
|
|
4091
4092
|
const safeMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
|
|
4092
4093
|
role: m.role || "user",
|
|
4093
4094
|
content: typeof m.content === "string" ? m.content : m.content != null ? String(m.content) : ""
|
|
@@ -4153,8 +4154,8 @@ ${context != null ? context : "None"}` },
|
|
|
4153
4154
|
*/
|
|
4154
4155
|
chatStream(messages, context) {
|
|
4155
4156
|
return __asyncGenerator(this, null, function* () {
|
|
4156
|
-
var
|
|
4157
|
-
const path2 = (
|
|
4157
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
4158
|
+
const path2 = (_a3 = this.opts.chatPath) != null ? _a3 : "/chat/completions";
|
|
4158
4159
|
const url = `${this.baseUrl.replace(/\/$/, "")}${path2}`;
|
|
4159
4160
|
const extractPath = ((_b = this.opts.responseExtractPath) != null ? _b : "choices[0].message.content").replace("message.content", "delta.content");
|
|
4160
4161
|
const safeMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
|
|
@@ -4280,8 +4281,8 @@ ${context != null ? context : "None"}` },
|
|
|
4280
4281
|
});
|
|
4281
4282
|
}
|
|
4282
4283
|
async embed(text) {
|
|
4283
|
-
var
|
|
4284
|
-
const path2 = (
|
|
4284
|
+
var _a3, _b, _c, _d, _e;
|
|
4285
|
+
const path2 = (_a3 = this.opts.embedPath) != null ? _a3 : "/embeddings";
|
|
4285
4286
|
const payload = this.opts.embedPayloadTemplate ? buildPayload(this.opts.embedPayloadTemplate, { input: text, model: this.model }) : { input: text, model: this.model };
|
|
4286
4287
|
try {
|
|
4287
4288
|
const { data: data2 } = await this.http.post(path2, payload);
|
|
@@ -4370,7 +4371,7 @@ var LLMFactory = class _LLMFactory {
|
|
|
4370
4371
|
];
|
|
4371
4372
|
}
|
|
4372
4373
|
static create(llmConfig, embeddingConfig) {
|
|
4373
|
-
var
|
|
4374
|
+
var _a3, _b, _c;
|
|
4374
4375
|
switch (llmConfig.provider) {
|
|
4375
4376
|
case "openai":
|
|
4376
4377
|
return new OpenAIProvider(llmConfig, embeddingConfig);
|
|
@@ -4389,7 +4390,7 @@ var LLMFactory = class _LLMFactory {
|
|
|
4389
4390
|
case "custom":
|
|
4390
4391
|
return new UniversalLLMAdapter(llmConfig);
|
|
4391
4392
|
default: {
|
|
4392
|
-
const providerName = String((
|
|
4393
|
+
const providerName = String((_a3 = llmConfig.provider) != null ? _a3 : "").toLowerCase();
|
|
4393
4394
|
const customFactory = customProviders.get(providerName);
|
|
4394
4395
|
if (customFactory) {
|
|
4395
4396
|
return customFactory(llmConfig);
|
|
@@ -4491,7 +4492,7 @@ var ProviderRegistry = class {
|
|
|
4491
4492
|
return null;
|
|
4492
4493
|
}
|
|
4493
4494
|
static async loadVectorProviderClass(provider) {
|
|
4494
|
-
var
|
|
4495
|
+
var _a3;
|
|
4495
4496
|
if (this.vectorProviders[provider]) return this.vectorProviders[provider];
|
|
4496
4497
|
switch (provider) {
|
|
4497
4498
|
case "pinecone": {
|
|
@@ -4500,7 +4501,7 @@ var ProviderRegistry = class {
|
|
|
4500
4501
|
}
|
|
4501
4502
|
case "pgvector":
|
|
4502
4503
|
case "postgresql": {
|
|
4503
|
-
const postgresMode = ((
|
|
4504
|
+
const postgresMode = ((_a3 = process.env.POSTGRES_MODE) != null ? _a3 : "multi").toLowerCase();
|
|
4504
4505
|
if (postgresMode === "single") {
|
|
4505
4506
|
const { PostgreSQLProvider: PostgreSQLProvider2 } = await Promise.resolve().then(() => (init_PostgreSQLProvider(), PostgreSQLProvider_exports));
|
|
4506
4507
|
return PostgreSQLProvider2;
|
|
@@ -4723,7 +4724,7 @@ var ConfigValidator = class {
|
|
|
4723
4724
|
// package.json
|
|
4724
4725
|
var package_default = {
|
|
4725
4726
|
name: "@retrivora-ai/rag-engine",
|
|
4726
|
-
version: "2.
|
|
4727
|
+
version: "2.3.1",
|
|
4727
4728
|
description: "Retrivora AI is a plug-and-play AI engine for RAG chat experiences \u2014 generic vector DB + LLM provider, embeddable or standalone.",
|
|
4728
4729
|
author: "Abhinav Alkuchi",
|
|
4729
4730
|
license: "UNLICENSED",
|
|
@@ -5028,8 +5029,8 @@ var Reranker = class {
|
|
|
5028
5029
|
return matches.sort((a, b) => b.score - a.score).slice(0, limit);
|
|
5029
5030
|
}
|
|
5030
5031
|
const scoredMatches = matches.map((match) => {
|
|
5031
|
-
var
|
|
5032
|
-
const contentLower = ((
|
|
5032
|
+
var _a3;
|
|
5033
|
+
const contentLower = ((_a3 = match == null ? void 0 : match.content) != null ? _a3 : "").toLowerCase();
|
|
5033
5034
|
let keywordScore = 0;
|
|
5034
5035
|
keywords.forEach((keyword) => {
|
|
5035
5036
|
if (contentLower.includes(keyword)) {
|
|
@@ -5051,8 +5052,8 @@ var Reranker = class {
|
|
|
5051
5052
|
|
|
5052
5053
|
Documents:
|
|
5053
5054
|
${topN.map((m, i) => {
|
|
5054
|
-
var
|
|
5055
|
-
return `[${i}] ${((
|
|
5055
|
+
var _a3;
|
|
5056
|
+
return `[${i}] ${((_a3 = m == null ? void 0 : m.content) != null ? _a3 : "").replace(/\n/g, " ")}`;
|
|
5056
5057
|
}).join("\n")}` }],
|
|
5057
5058
|
"",
|
|
5058
5059
|
{
|
|
@@ -5096,11 +5097,11 @@ var LlamaIndexIngestor = class {
|
|
|
5096
5097
|
* than standard character-count splitting.
|
|
5097
5098
|
*/
|
|
5098
5099
|
async chunk(text, options = {}) {
|
|
5099
|
-
var
|
|
5100
|
+
var _a3, _b;
|
|
5100
5101
|
try {
|
|
5101
5102
|
const { Document, SentenceSplitter, MetadataMode } = await import(`${"llamaindex"}`);
|
|
5102
5103
|
const splitter = new SentenceSplitter({
|
|
5103
|
-
chunkSize: (
|
|
5104
|
+
chunkSize: (_a3 = options.chunkSize) != null ? _a3 : 1e3,
|
|
5104
5105
|
chunkOverlap: (_b = options.chunkOverlap) != null ? _b : 200
|
|
5105
5106
|
});
|
|
5106
5107
|
const doc = new Document({ text, metadata: options.metadata || {} });
|
|
@@ -5209,7 +5210,7 @@ ${error instanceof Error ? error.message : String(error)}`
|
|
|
5209
5210
|
* The agent returns `{ messages: [...] }` — the last message is the final answer.
|
|
5210
5211
|
*/
|
|
5211
5212
|
async run(input, chatHistory = []) {
|
|
5212
|
-
var
|
|
5213
|
+
var _a3, _b, _c;
|
|
5213
5214
|
if (!this.agent) {
|
|
5214
5215
|
throw new Error("[LangChainAgent] Agent not initialized. Call initialize() first.");
|
|
5215
5216
|
}
|
|
@@ -5220,7 +5221,7 @@ ${error instanceof Error ? error.message : String(error)}`
|
|
|
5220
5221
|
const response = await this.agent.invoke({
|
|
5221
5222
|
messages: [...historyMessages, new HumanMessage(input)]
|
|
5222
5223
|
});
|
|
5223
|
-
const lastMessage = (
|
|
5224
|
+
const lastMessage = (_a3 = response == null ? void 0 : response.messages) == null ? void 0 : _a3.at(-1);
|
|
5224
5225
|
if (lastMessage && typeof lastMessage.content === "string") {
|
|
5225
5226
|
return lastMessage.content;
|
|
5226
5227
|
}
|
|
@@ -5272,7 +5273,7 @@ var MCPClient = class {
|
|
|
5272
5273
|
}
|
|
5273
5274
|
}
|
|
5274
5275
|
async connectStdio() {
|
|
5275
|
-
var
|
|
5276
|
+
var _a3;
|
|
5276
5277
|
const cmd = this.config.command;
|
|
5277
5278
|
if (!cmd) {
|
|
5278
5279
|
throw new Error(`[MCPClient] Command option is required for stdio transport on "${this.config.name}"`);
|
|
@@ -5287,7 +5288,7 @@ var MCPClient = class {
|
|
|
5287
5288
|
this.stdioBuffer += data.toString("utf-8");
|
|
5288
5289
|
this.processStdioLines();
|
|
5289
5290
|
});
|
|
5290
|
-
(
|
|
5291
|
+
(_a3 = this.childProcess.stderr) == null ? void 0 : _a3.on("data", (data) => {
|
|
5291
5292
|
console.warn(`[MCPClient] [stderr] [${this.config.name}]:`, data.toString("utf-8"));
|
|
5292
5293
|
});
|
|
5293
5294
|
this.childProcess.on("close", (code) => {
|
|
@@ -5362,14 +5363,14 @@ var MCPClient = class {
|
|
|
5362
5363
|
}
|
|
5363
5364
|
}
|
|
5364
5365
|
async sendNotification(method, params) {
|
|
5365
|
-
var
|
|
5366
|
+
var _a3;
|
|
5366
5367
|
const notification = {
|
|
5367
5368
|
jsonrpc: "2.0",
|
|
5368
5369
|
method,
|
|
5369
5370
|
params
|
|
5370
5371
|
};
|
|
5371
5372
|
if (this.config.transport === "stdio") {
|
|
5372
|
-
if ((
|
|
5373
|
+
if ((_a3 = this.childProcess) == null ? void 0 : _a3.stdin) {
|
|
5373
5374
|
this.childProcess.stdin.write(JSON.stringify(notification) + "\n", "utf-8");
|
|
5374
5375
|
}
|
|
5375
5376
|
} else if (this.sseUrl) {
|
|
@@ -5447,11 +5448,11 @@ var MCPRegistry = class {
|
|
|
5447
5448
|
// src/core/MultiAgentCoordinator.ts
|
|
5448
5449
|
var MultiAgentCoordinator = class {
|
|
5449
5450
|
constructor(options) {
|
|
5450
|
-
var
|
|
5451
|
+
var _a3;
|
|
5451
5452
|
this.llmProvider = options.llmProvider;
|
|
5452
5453
|
this.mcpRegistry = options.mcpRegistry;
|
|
5453
5454
|
this.documentSearch = options.documentSearch;
|
|
5454
|
-
this.maxIterations = (
|
|
5455
|
+
this.maxIterations = (_a3 = options.maxIterations) != null ? _a3 : 5;
|
|
5455
5456
|
}
|
|
5456
5457
|
/**
|
|
5457
5458
|
* Run the multi-agent coordination loop synchronously and return the final response.
|
|
@@ -5503,8 +5504,8 @@ Available Tools:
|
|
|
5503
5504
|
|
|
5504
5505
|
${mcpTools.length > 0 ? "MCP Server Tools:" : ""}
|
|
5505
5506
|
${mcpTools.map((mt) => {
|
|
5506
|
-
var
|
|
5507
|
-
return `- ${mt.tool.name}(${JSON.stringify(((
|
|
5507
|
+
var _a3;
|
|
5508
|
+
return `- ${mt.tool.name}(${JSON.stringify(((_a3 = mt.tool.inputSchema) == null ? void 0 : _a3.properties) || {})}): ${mt.tool.description || "No description provided."}`;
|
|
5508
5509
|
}).join("\n")}
|
|
5509
5510
|
|
|
5510
5511
|
Tool Calling Protocol:
|
|
@@ -5662,6 +5663,100 @@ ${toolResultText}`
|
|
|
5662
5663
|
}
|
|
5663
5664
|
};
|
|
5664
5665
|
|
|
5666
|
+
// src/core/CircuitBreaker.ts
|
|
5667
|
+
var CircuitBreaker = class {
|
|
5668
|
+
constructor(options = {}) {
|
|
5669
|
+
this.state = "closed";
|
|
5670
|
+
this.failureCount = 0;
|
|
5671
|
+
this.successCount = 0;
|
|
5672
|
+
this.lastFailureAt = 0;
|
|
5673
|
+
this.halfOpenCalls = 0;
|
|
5674
|
+
var _a3, _b, _c;
|
|
5675
|
+
this.failureThreshold = (_a3 = options.failureThreshold) != null ? _a3 : 5;
|
|
5676
|
+
this.resetTimeoutMs = (_b = options.resetTimeoutMs) != null ? _b : 3e4;
|
|
5677
|
+
this.halfOpenMaxCalls = (_c = options.halfOpenMaxCalls) != null ? _c : 1;
|
|
5678
|
+
}
|
|
5679
|
+
record(success) {
|
|
5680
|
+
const now = Date.now();
|
|
5681
|
+
if (success) {
|
|
5682
|
+
this.successCount++;
|
|
5683
|
+
if (this.state === "half-open") {
|
|
5684
|
+
this.state = "closed";
|
|
5685
|
+
this.failureCount = 0;
|
|
5686
|
+
this.halfOpenCalls = 0;
|
|
5687
|
+
this.successCount = 1;
|
|
5688
|
+
} else if (this.state === "closed") {
|
|
5689
|
+
if (this.successCount >= this.failureThreshold) {
|
|
5690
|
+
this.failureCount = Math.max(0, this.failureCount - 1);
|
|
5691
|
+
this.successCount = 0;
|
|
5692
|
+
}
|
|
5693
|
+
}
|
|
5694
|
+
} else {
|
|
5695
|
+
this.failureCount++;
|
|
5696
|
+
this.lastFailureAt = now;
|
|
5697
|
+
this.successCount = 0;
|
|
5698
|
+
if (this.state === "half-open") {
|
|
5699
|
+
this.state = "open";
|
|
5700
|
+
this.halfOpenCalls = 0;
|
|
5701
|
+
} else if (this.state === "closed" && this.failureCount >= this.failureThreshold) {
|
|
5702
|
+
this.state = "open";
|
|
5703
|
+
}
|
|
5704
|
+
}
|
|
5705
|
+
}
|
|
5706
|
+
canExecute() {
|
|
5707
|
+
const now = Date.now();
|
|
5708
|
+
if (this.state === "closed") {
|
|
5709
|
+
return true;
|
|
5710
|
+
}
|
|
5711
|
+
if (this.state === "open") {
|
|
5712
|
+
if (now - this.lastFailureAt >= this.resetTimeoutMs) {
|
|
5713
|
+
this.state = "half-open";
|
|
5714
|
+
this.halfOpenCalls = 0;
|
|
5715
|
+
return true;
|
|
5716
|
+
}
|
|
5717
|
+
return false;
|
|
5718
|
+
}
|
|
5719
|
+
if (this.state === "half-open") {
|
|
5720
|
+
return this.halfOpenCalls < this.halfOpenMaxCalls;
|
|
5721
|
+
}
|
|
5722
|
+
return true;
|
|
5723
|
+
}
|
|
5724
|
+
async wrap(fn) {
|
|
5725
|
+
if (!this.canExecute()) {
|
|
5726
|
+
const retryAfterSec = Math.ceil(
|
|
5727
|
+
Math.max(0, this.resetTimeoutMs - (Date.now() - this.lastFailureAt)) / 1e3
|
|
5728
|
+
);
|
|
5729
|
+
throw new Error(
|
|
5730
|
+
`Circuit breaker is open. Try again in ${retryAfterSec}s. Failed ${this.failureCount}/${this.failureThreshold} consecutive calls.`
|
|
5731
|
+
);
|
|
5732
|
+
}
|
|
5733
|
+
if (this.state === "half-open") {
|
|
5734
|
+
this.halfOpenCalls++;
|
|
5735
|
+
}
|
|
5736
|
+
try {
|
|
5737
|
+
const result = await fn();
|
|
5738
|
+
this.record(true);
|
|
5739
|
+
return result;
|
|
5740
|
+
} catch (err) {
|
|
5741
|
+
this.record(false);
|
|
5742
|
+
throw err;
|
|
5743
|
+
}
|
|
5744
|
+
}
|
|
5745
|
+
getState() {
|
|
5746
|
+
return this.state;
|
|
5747
|
+
}
|
|
5748
|
+
getFailureCount() {
|
|
5749
|
+
return this.failureCount;
|
|
5750
|
+
}
|
|
5751
|
+
reset() {
|
|
5752
|
+
this.state = "closed";
|
|
5753
|
+
this.failureCount = 0;
|
|
5754
|
+
this.successCount = 0;
|
|
5755
|
+
this.lastFailureAt = 0;
|
|
5756
|
+
this.halfOpenCalls = 0;
|
|
5757
|
+
}
|
|
5758
|
+
};
|
|
5759
|
+
|
|
5665
5760
|
// src/core/BatchProcessor.ts
|
|
5666
5761
|
function isTransientError(error) {
|
|
5667
5762
|
if (!(error instanceof Error)) return false;
|
|
@@ -5685,7 +5780,34 @@ function calculateBackoffDelay(attempt, initialDelayMs, maxDelayMs, multiplier)
|
|
|
5685
5780
|
function sleep(ms) {
|
|
5686
5781
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
5687
5782
|
}
|
|
5688
|
-
var
|
|
5783
|
+
var _BatchProcessor = class _BatchProcessor {
|
|
5784
|
+
/**
|
|
5785
|
+
* Execute a processor call through the circuit breaker.
|
|
5786
|
+
* Only transient failures count toward opening the circuit.
|
|
5787
|
+
*/
|
|
5788
|
+
static async executeWithCircuitBreaker(processor) {
|
|
5789
|
+
if (!this.cb.canExecute()) {
|
|
5790
|
+
const retryAfterSec = Math.ceil(
|
|
5791
|
+
Math.max(0, 3e4 - (Date.now() - this.cb.lastFailureAt || 0)) / 1e3
|
|
5792
|
+
);
|
|
5793
|
+
throw new Error(
|
|
5794
|
+
`[BatchProcessor] Circuit breaker is open. Try again in ${retryAfterSec}s.`
|
|
5795
|
+
);
|
|
5796
|
+
}
|
|
5797
|
+
if (this.cb.state === "half-open") {
|
|
5798
|
+
this.cb.halfOpenCalls++;
|
|
5799
|
+
}
|
|
5800
|
+
try {
|
|
5801
|
+
const result = await processor();
|
|
5802
|
+
this.cb.record(true);
|
|
5803
|
+
return result;
|
|
5804
|
+
} catch (err) {
|
|
5805
|
+
if (isTransientError(err)) {
|
|
5806
|
+
this.cb.record(false);
|
|
5807
|
+
}
|
|
5808
|
+
throw err;
|
|
5809
|
+
}
|
|
5810
|
+
}
|
|
5689
5811
|
/**
|
|
5690
5812
|
* Processes an array of items in configurable batches with retry logic.
|
|
5691
5813
|
*
|
|
@@ -5726,7 +5848,7 @@ var BatchProcessor = class {
|
|
|
5726
5848
|
let lastError;
|
|
5727
5849
|
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
5728
5850
|
try {
|
|
5729
|
-
const result = await processor(batch);
|
|
5851
|
+
const result = await _BatchProcessor.executeWithCircuitBreaker(() => processor(batch));
|
|
5730
5852
|
results.push(result);
|
|
5731
5853
|
success = true;
|
|
5732
5854
|
break;
|
|
@@ -5784,7 +5906,7 @@ ${errorMessages}`
|
|
|
5784
5906
|
let lastError;
|
|
5785
5907
|
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
5786
5908
|
try {
|
|
5787
|
-
const result = await processor(item);
|
|
5909
|
+
const result = await _BatchProcessor.executeWithCircuitBreaker(() => processor(item));
|
|
5788
5910
|
results.push(result);
|
|
5789
5911
|
success = true;
|
|
5790
5912
|
break;
|
|
@@ -5857,7 +5979,7 @@ ${errorMessages}`
|
|
|
5857
5979
|
}));
|
|
5858
5980
|
const chunkPromises = chunk.map(async ({ item, originalIndex }) => {
|
|
5859
5981
|
try {
|
|
5860
|
-
const result = await processor(item);
|
|
5982
|
+
const result = await _BatchProcessor.executeWithCircuitBreaker(() => processor(item));
|
|
5861
5983
|
return { success: true, result, index: originalIndex };
|
|
5862
5984
|
} catch (err) {
|
|
5863
5985
|
const error = err instanceof Error ? err : new Error(String(err));
|
|
@@ -5885,6 +6007,12 @@ ${errorMessages}`
|
|
|
5885
6007
|
return { results, errors, totalProcessed, totalFailed };
|
|
5886
6008
|
}
|
|
5887
6009
|
};
|
|
6010
|
+
_BatchProcessor.cb = new CircuitBreaker({
|
|
6011
|
+
failureThreshold: 5,
|
|
6012
|
+
resetTimeoutMs: 3e4,
|
|
6013
|
+
halfOpenMaxCalls: 1
|
|
6014
|
+
});
|
|
6015
|
+
var BatchProcessor = _BatchProcessor;
|
|
5888
6016
|
|
|
5889
6017
|
// src/config/EmbeddingStrategy.ts
|
|
5890
6018
|
var EmbeddingStrategy = /* @__PURE__ */ ((EmbeddingStrategy2) => {
|
|
@@ -5988,7 +6116,7 @@ var QueryProcessor = class {
|
|
|
5988
6116
|
* @param validFields Optional list of known filterable fields to look for
|
|
5989
6117
|
*/
|
|
5990
6118
|
static extractQueryFieldHints(question, validFields = []) {
|
|
5991
|
-
var
|
|
6119
|
+
var _a3, _b, _c, _d;
|
|
5992
6120
|
if (!question.trim()) return [];
|
|
5993
6121
|
const hints = /* @__PURE__ */ new Map();
|
|
5994
6122
|
const addHint = (value, field) => {
|
|
@@ -6068,7 +6196,7 @@ var QueryProcessor = class {
|
|
|
6068
6196
|
];
|
|
6069
6197
|
for (const p of universalPatterns) {
|
|
6070
6198
|
for (const match of question.matchAll(p.regex)) {
|
|
6071
|
-
const val = p.group ? (
|
|
6199
|
+
const val = p.group ? (_a3 = match[p.group]) != null ? _a3 : match[0] : match[0];
|
|
6072
6200
|
if (!val) continue;
|
|
6073
6201
|
if (p.field) addHint(val, p.field);
|
|
6074
6202
|
else addHint(val);
|
|
@@ -6292,11 +6420,11 @@ var LLMRouter = class {
|
|
|
6292
6420
|
* When provided it is used directly as the 'default' role without re-constructing.
|
|
6293
6421
|
*/
|
|
6294
6422
|
async initialize(prebuiltDefault) {
|
|
6295
|
-
var
|
|
6423
|
+
var _a3;
|
|
6296
6424
|
const defaultModel = prebuiltDefault != null ? prebuiltDefault : LLMFactory.create(this.config.llm, this.config.embedding);
|
|
6297
6425
|
this.models.set("default", defaultModel);
|
|
6298
6426
|
const envFastModel = process.env.FAST_LLM_MODEL;
|
|
6299
|
-
const providerFastDefault = (
|
|
6427
|
+
const providerFastDefault = (_a3 = FAST_MODEL_DEFAULTS[this.config.llm.provider]) != null ? _a3 : "";
|
|
6300
6428
|
const fastModelName = envFastModel || providerFastDefault;
|
|
6301
6429
|
if (fastModelName && fastModelName !== this.config.llm.model) {
|
|
6302
6430
|
console.log(`[LLMRouter] Fast role \u2192 provider="${this.config.llm.provider}" model="${fastModelName}"`);
|
|
@@ -6315,8 +6443,8 @@ var LLMRouter = class {
|
|
|
6315
6443
|
* Falls back to 'default' if the requested role is not registered.
|
|
6316
6444
|
*/
|
|
6317
6445
|
get(role) {
|
|
6318
|
-
var
|
|
6319
|
-
const provider = (
|
|
6446
|
+
var _a3;
|
|
6447
|
+
const provider = (_a3 = this.models.get(role)) != null ? _a3 : this.models.get("default");
|
|
6320
6448
|
if (!provider) {
|
|
6321
6449
|
throw new Error(`[LLMRouter] No provider registered for role: "${role}". Did you call initialize()?`);
|
|
6322
6450
|
}
|
|
@@ -6402,8 +6530,8 @@ var IntentClassifier = class {
|
|
|
6402
6530
|
numericFieldCount = numericKeys.size;
|
|
6403
6531
|
categoricalFieldCount = catKeys.size;
|
|
6404
6532
|
if (productKeyMatches >= 2 || docs.some((d) => {
|
|
6405
|
-
var
|
|
6406
|
-
return ((
|
|
6533
|
+
var _a3, _b;
|
|
6534
|
+
return ((_a3 = d == null ? void 0 : d.content) != null ? _a3 : "").toLowerCase().includes("price") || ((_b = d == null ? void 0 : d.content) != null ? _b : "").toLowerCase().includes("brand");
|
|
6407
6535
|
})) {
|
|
6408
6536
|
isProductLike = true;
|
|
6409
6537
|
}
|
|
@@ -6685,8 +6813,8 @@ var TextRendererStrategy = class {
|
|
|
6685
6813
|
}
|
|
6686
6814
|
const docs = Array.isArray(data) ? data : [];
|
|
6687
6815
|
const text = docs.map((d) => {
|
|
6688
|
-
var
|
|
6689
|
-
return (
|
|
6816
|
+
var _a3;
|
|
6817
|
+
return (_a3 = d == null ? void 0 : d.content) != null ? _a3 : "";
|
|
6690
6818
|
}).join("\n\n");
|
|
6691
6819
|
return { type: "text", title, data: { content: text || "No detailed content available." } };
|
|
6692
6820
|
}
|
|
@@ -6829,9 +6957,9 @@ var LRUDecisionCache = class {
|
|
|
6829
6957
|
this.maxSize = maxSize;
|
|
6830
6958
|
}
|
|
6831
6959
|
generateKey(context) {
|
|
6832
|
-
var
|
|
6960
|
+
var _a3, _b;
|
|
6833
6961
|
const q = (context.userQuery || "").toLowerCase().trim();
|
|
6834
|
-
const docCount = (_b = (
|
|
6962
|
+
const docCount = (_b = (_a3 = context.retrievedDocuments) == null ? void 0 : _a3.length) != null ? _b : 0;
|
|
6835
6963
|
return `${q}::docs:${docCount}`;
|
|
6836
6964
|
}
|
|
6837
6965
|
get(context) {
|
|
@@ -6940,7 +7068,7 @@ var UITransformer = class _UITransformer {
|
|
|
6940
7068
|
* Prefer `analyzeAndDecide()` in production.
|
|
6941
7069
|
*/
|
|
6942
7070
|
static transform(userQuery, retrievedData, config, trainedSchema, intent) {
|
|
6943
|
-
var
|
|
7071
|
+
var _a3, _b, _c;
|
|
6944
7072
|
if (!retrievedData || retrievedData.length === 0) {
|
|
6945
7073
|
return this.createTextResponse("No data available", "No relevant data found for your query.");
|
|
6946
7074
|
}
|
|
@@ -6960,7 +7088,7 @@ var UITransformer = class _UITransformer {
|
|
|
6960
7088
|
return this.transformToBarChart(filteredData, profile, userQuery, resolvedIntent.visualizationHint === "ranking");
|
|
6961
7089
|
}
|
|
6962
7090
|
if (resolvedIntent.visualizationHint === "distribution") {
|
|
6963
|
-
return (
|
|
7091
|
+
return (_a3 = this.transformToHistogram(profile, userQuery)) != null ? _a3 : this.transformToBarChart(filteredData, profile, userQuery);
|
|
6964
7092
|
}
|
|
6965
7093
|
if (resolvedIntent.visualizationHint === "correlation") {
|
|
6966
7094
|
return (_b = this.transformToScatterPlot(profile, userQuery)) != null ? _b : this.transformToBarChart(filteredData, profile, userQuery);
|
|
@@ -7293,11 +7421,11 @@ ${schemaProfileText}` : ""}`;
|
|
|
7293
7421
|
};
|
|
7294
7422
|
}
|
|
7295
7423
|
static transformToPieChart(data, profile, query = "") {
|
|
7296
|
-
var
|
|
7424
|
+
var _a3;
|
|
7297
7425
|
const dimension = profile ? this.selectDimensionField(profile, query) : void 0;
|
|
7298
7426
|
const categories = dimension ? Array.from(new Set(profile.records.map((record) => {
|
|
7299
|
-
var
|
|
7300
|
-
return String((
|
|
7427
|
+
var _a4;
|
|
7428
|
+
return String((_a4 = record.fields[dimension.key]) != null ? _a4 : "");
|
|
7301
7429
|
}).filter(Boolean))) : this.detectCategories(data);
|
|
7302
7430
|
if (categories.length === 0) return null;
|
|
7303
7431
|
const categoryData = dimension && profile ? this.aggregateProfileByDimension(profile, dimension.key) : this.aggregateByCategory(data, categories);
|
|
@@ -7307,7 +7435,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7307
7435
|
});
|
|
7308
7436
|
return {
|
|
7309
7437
|
type: "pie_chart",
|
|
7310
|
-
title: `Distribution by ${(
|
|
7438
|
+
title: `Distribution by ${(_a3 = dimension == null ? void 0 : dimension.label) != null ? _a3 : "Category"}`,
|
|
7311
7439
|
description: `Showing breakdown across ${pieData.length} categories`,
|
|
7312
7440
|
data: pieData
|
|
7313
7441
|
};
|
|
@@ -7317,8 +7445,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7317
7445
|
const valueField = profile.numericFields[0];
|
|
7318
7446
|
const buckets = /* @__PURE__ */ new Map();
|
|
7319
7447
|
profile.records.forEach((record) => {
|
|
7320
|
-
var
|
|
7321
|
-
const timestamp = String((
|
|
7448
|
+
var _a3, _b, _c;
|
|
7449
|
+
const timestamp = String((_a3 = record.fields[dateField.key]) != null ? _a3 : "");
|
|
7322
7450
|
const value = (_b = this.toFiniteNumber(record.fields[valueField.key])) != null ? _b : 0;
|
|
7323
7451
|
buckets.set(timestamp, ((_c = buckets.get(timestamp)) != null ? _c : 0) + value);
|
|
7324
7452
|
});
|
|
@@ -7331,23 +7459,23 @@ ${schemaProfileText}` : ""}`;
|
|
|
7331
7459
|
};
|
|
7332
7460
|
}
|
|
7333
7461
|
static transformToBarChart(data, profile, query = "", horizontal = false) {
|
|
7334
|
-
var
|
|
7462
|
+
var _a3;
|
|
7335
7463
|
const dimension = profile ? this.selectDimensionField(profile, query) : void 0;
|
|
7336
7464
|
const measure = profile ? this.selectNumericField(profile, query) : void 0;
|
|
7337
7465
|
const aggregate = dimension && profile ? this.aggregateProfileByDimension(profile, dimension.key, measure == null ? void 0 : measure.key) : this.aggregateByCategory(data, this.detectCategories(data));
|
|
7338
7466
|
const barData = Object.entries(aggregate).map(([category, value]) => ({ category, value: Number(value) })).sort((a, b) => horizontal ? b.value - a.value : 0).slice(0, 12);
|
|
7339
7467
|
const fallbackData = barData.length > 0 ? barData : data.slice(0, 12).map((item, index) => {
|
|
7340
|
-
var
|
|
7468
|
+
var _a4, _b, _c, _d, _e;
|
|
7341
7469
|
const meta = item.metadata || {};
|
|
7342
7470
|
const label = String(
|
|
7343
|
-
(_c = (_b = (
|
|
7471
|
+
(_c = (_b = (_a4 = this.getDynamicVal(meta, "name")) != null ? _a4 : meta.label) != null ? _b : meta.title) != null ? _c : `Result ${index + 1}`
|
|
7344
7472
|
);
|
|
7345
7473
|
const value = (_e = (_d = this.extractNumericValue(meta)) != null ? _d : item.score) != null ? _e : 0;
|
|
7346
7474
|
return { category: label, value: Number(value) };
|
|
7347
7475
|
});
|
|
7348
7476
|
return {
|
|
7349
7477
|
type: horizontal ? "horizontal_bar" : "bar_chart",
|
|
7350
|
-
title: dimension ? `${(
|
|
7478
|
+
title: dimension ? `${(_a3 = measure == null ? void 0 : measure.label) != null ? _a3 : "Count"} by ${dimension.label}` : "Comparison",
|
|
7351
7479
|
description: `Showing ${fallbackData.length} comparable values`,
|
|
7352
7480
|
data: fallbackData
|
|
7353
7481
|
};
|
|
@@ -7382,11 +7510,11 @@ ${schemaProfileText}` : ""}`;
|
|
|
7382
7510
|
if (fields.length < 2) return null;
|
|
7383
7511
|
const [xField, yField] = fields;
|
|
7384
7512
|
const points = profile.records.map((record) => {
|
|
7385
|
-
var
|
|
7513
|
+
var _a3;
|
|
7386
7514
|
const x = this.toFiniteNumber(record.fields[xField.key]);
|
|
7387
7515
|
const y = this.toFiniteNumber(record.fields[yField.key]);
|
|
7388
7516
|
if (x === null || y === null) return null;
|
|
7389
|
-
return { x, y, label: String((
|
|
7517
|
+
return { x, y, label: String((_a3 = this.getRecordLabel(record)) != null ? _a3 : record.id) };
|
|
7390
7518
|
}).filter((point) => point !== null).slice(0, 100);
|
|
7391
7519
|
if (points.length === 0) return null;
|
|
7392
7520
|
return {
|
|
@@ -7416,9 +7544,9 @@ ${schemaProfileText}` : ""}`;
|
|
|
7416
7544
|
static transformToRadarChart(data) {
|
|
7417
7545
|
const attributeMap = {};
|
|
7418
7546
|
data.forEach((item) => {
|
|
7419
|
-
var
|
|
7547
|
+
var _a3, _b, _c;
|
|
7420
7548
|
const meta = item.metadata || {};
|
|
7421
|
-
const seriesName = String((_c = (_b = (
|
|
7549
|
+
const seriesName = String((_c = (_b = (_a3 = meta.name) != null ? _a3 : meta.product) != null ? _b : item.id) != null ? _c : "Item");
|
|
7422
7550
|
Object.entries(meta).forEach(([key, val]) => {
|
|
7423
7551
|
if (typeof val === "number" && !["price", "id"].includes(key.toLowerCase())) {
|
|
7424
7552
|
if (!attributeMap[key]) attributeMap[key] = {};
|
|
@@ -7434,8 +7562,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7434
7562
|
title: "Product Comparison",
|
|
7435
7563
|
description: `Comparing ${data.length} items across ${radarData.length} attributes`,
|
|
7436
7564
|
data: radarData.length > 0 ? radarData : data.map((d) => {
|
|
7437
|
-
var
|
|
7438
|
-
return { attribute: ((
|
|
7565
|
+
var _a3;
|
|
7566
|
+
return { attribute: ((_a3 = d == null ? void 0 : d.content) != null ? _a3 : "").substring(0, 40) };
|
|
7439
7567
|
})
|
|
7440
7568
|
};
|
|
7441
7569
|
}
|
|
@@ -7454,8 +7582,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7454
7582
|
return this.createTextResponse(
|
|
7455
7583
|
"Retrieved Context",
|
|
7456
7584
|
data.map((item) => {
|
|
7457
|
-
var
|
|
7458
|
-
return (
|
|
7585
|
+
var _a3;
|
|
7586
|
+
return (_a3 = item == null ? void 0 : item.content) != null ? _a3 : "";
|
|
7459
7587
|
}).join("\n\n"),
|
|
7460
7588
|
`Found ${data.length} relevant results`
|
|
7461
7589
|
);
|
|
@@ -7506,11 +7634,11 @@ ${schemaProfileText}` : ""}`;
|
|
|
7506
7634
|
return null;
|
|
7507
7635
|
}
|
|
7508
7636
|
static normalizeTransformation(payload) {
|
|
7509
|
-
var
|
|
7637
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j;
|
|
7510
7638
|
if (!payload || typeof payload !== "object") return null;
|
|
7511
7639
|
const p = payload;
|
|
7512
7640
|
const type = this.normalizeVisualizationType(
|
|
7513
|
-
String((_c = (_b = (
|
|
7641
|
+
String((_c = (_b = (_a3 = p.type) != null ? _a3 : p.view) != null ? _b : p.chartType) != null ? _c : "")
|
|
7514
7642
|
);
|
|
7515
7643
|
if (!type) return null;
|
|
7516
7644
|
const title = String((_e = (_d = p.title) != null ? _d : p.heading) != null ? _e : "Visualization");
|
|
@@ -7521,7 +7649,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7521
7649
|
return this.validateTransformation(transformation) ? transformation : null;
|
|
7522
7650
|
}
|
|
7523
7651
|
static normalizeVisualizationType(type) {
|
|
7524
|
-
var
|
|
7652
|
+
var _a3;
|
|
7525
7653
|
const mapping = {
|
|
7526
7654
|
pie: "pie_chart",
|
|
7527
7655
|
pie_chart: "pie_chart",
|
|
@@ -7549,7 +7677,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7549
7677
|
product_carousel: "product_carousel",
|
|
7550
7678
|
carousel: "carousel"
|
|
7551
7679
|
};
|
|
7552
|
-
return (
|
|
7680
|
+
return (_a3 = mapping[type.toLowerCase()]) != null ? _a3 : null;
|
|
7553
7681
|
}
|
|
7554
7682
|
static validateTransformation(t) {
|
|
7555
7683
|
const { type, data } = t;
|
|
@@ -7665,7 +7793,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7665
7793
|
}
|
|
7666
7794
|
static profileData(data) {
|
|
7667
7795
|
const records = (data || []).filter((item) => Boolean(item && typeof item === "object")).map((item) => {
|
|
7668
|
-
var
|
|
7796
|
+
var _a3, _b;
|
|
7669
7797
|
const fields2 = {};
|
|
7670
7798
|
Object.entries(item.metadata || {}).forEach(([key, value]) => {
|
|
7671
7799
|
const primitive = this.toPrimitive(value);
|
|
@@ -7674,7 +7802,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7674
7802
|
if (!fields2.content && item.content) fields2.content = item.content.substring(0, 500);
|
|
7675
7803
|
return {
|
|
7676
7804
|
id: item.id,
|
|
7677
|
-
content: (
|
|
7805
|
+
content: (_a3 = item.content) != null ? _a3 : "",
|
|
7678
7806
|
score: (_b = item.score) != null ? _b : 0,
|
|
7679
7807
|
fields: fields2,
|
|
7680
7808
|
source: item
|
|
@@ -7755,16 +7883,16 @@ ${schemaProfileText}` : ""}`;
|
|
|
7755
7883
|
return null;
|
|
7756
7884
|
}
|
|
7757
7885
|
static selectDimensionField(profile, query) {
|
|
7758
|
-
var
|
|
7886
|
+
var _a3, _b;
|
|
7759
7887
|
const productCategory = profile.categoricalFields.find(
|
|
7760
7888
|
(field) => /category|department|collection|type|group|segment|region|country|state|city/i.test(field.key)
|
|
7761
7889
|
);
|
|
7762
7890
|
const ranked = this.rankFieldsByQuery(profile.categoricalFields, query);
|
|
7763
|
-
return (_b = (
|
|
7891
|
+
return (_b = (_a3 = ranked[0]) != null ? _a3 : productCategory) != null ? _b : profile.categoricalFields[0];
|
|
7764
7892
|
}
|
|
7765
7893
|
static selectNumericField(profile, query) {
|
|
7766
|
-
var
|
|
7767
|
-
return (
|
|
7894
|
+
var _a3;
|
|
7895
|
+
return (_a3 = this.rankFieldsByQuery(profile.numericFields, query)[0]) != null ? _a3 : profile.numericFields[0];
|
|
7768
7896
|
}
|
|
7769
7897
|
static rankFieldsByQuery(fields, query) {
|
|
7770
7898
|
const q = query.toLowerCase();
|
|
@@ -7793,8 +7921,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7793
7921
|
static aggregateProfileByDimension(profile, dimensionKey, measureKey) {
|
|
7794
7922
|
const result = {};
|
|
7795
7923
|
profile.records.forEach((record) => {
|
|
7796
|
-
var
|
|
7797
|
-
const category = String((
|
|
7924
|
+
var _a3, _b, _c;
|
|
7925
|
+
const category = String((_a3 = record.fields[dimensionKey]) != null ? _a3 : "Other").trim() || "Other";
|
|
7798
7926
|
const value = measureKey ? (_b = this.toFiniteNumber(record.fields[measureKey])) != null ? _b : 0 : 1;
|
|
7799
7927
|
result[category] = ((_c = result[category]) != null ? _c : 0) + value;
|
|
7800
7928
|
});
|
|
@@ -7874,8 +8002,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7874
8002
|
static aggregateByCategory(data, categories) {
|
|
7875
8003
|
const result = Object.fromEntries(categories.map((c) => [c, 0]));
|
|
7876
8004
|
data.forEach((item) => {
|
|
7877
|
-
var
|
|
7878
|
-
const cat = (
|
|
8005
|
+
var _a3;
|
|
8006
|
+
const cat = (_a3 = this.getProductCategory(item)) != null ? _a3 : "Other";
|
|
7879
8007
|
if (Object.prototype.hasOwnProperty.call(result, cat)) result[cat]++;
|
|
7880
8008
|
else result["Other"] = (result["Other"] || 0) + 1;
|
|
7881
8009
|
});
|
|
@@ -7883,17 +8011,17 @@ ${schemaProfileText}` : ""}`;
|
|
|
7883
8011
|
}
|
|
7884
8012
|
static extractTimeSeriesData(data) {
|
|
7885
8013
|
return data.map((item) => {
|
|
7886
|
-
var
|
|
8014
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
7887
8015
|
const meta = item.metadata || {};
|
|
7888
8016
|
return {
|
|
7889
|
-
timestamp: (_b = (
|
|
8017
|
+
timestamp: (_b = (_a3 = meta.timestamp) != null ? _a3 : meta.date) != null ? _b : (/* @__PURE__ */ new Date()).toISOString(),
|
|
7890
8018
|
value: (_d = (_c = meta.value) != null ? _c : item.score) != null ? _d : 0,
|
|
7891
8019
|
label: (_f = meta.label) != null ? _f : ((_e = item == null ? void 0 : item.content) != null ? _e : "").substring(0, 50)
|
|
7892
8020
|
};
|
|
7893
8021
|
});
|
|
7894
8022
|
}
|
|
7895
8023
|
static extractNumericValue(meta) {
|
|
7896
|
-
var
|
|
8024
|
+
var _a3;
|
|
7897
8025
|
const preferredKeys = [
|
|
7898
8026
|
"value",
|
|
7899
8027
|
"count",
|
|
@@ -7908,7 +8036,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7908
8036
|
"price"
|
|
7909
8037
|
];
|
|
7910
8038
|
for (const key of preferredKeys) {
|
|
7911
|
-
const raw = (
|
|
8039
|
+
const raw = (_a3 = resolveMetadataValue(meta, key)) != null ? _a3 : meta[key];
|
|
7912
8040
|
const value = typeof raw === "number" ? raw : Number(String(raw != null ? raw : "").replace(/[$,% ,]/g, ""));
|
|
7913
8041
|
if (Number.isFinite(value)) return value;
|
|
7914
8042
|
}
|
|
@@ -8003,8 +8131,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
8003
8131
|
}, query.includes(normalizedField) ? 3 : 0);
|
|
8004
8132
|
}
|
|
8005
8133
|
static resolveTableCellValue(item, column) {
|
|
8006
|
-
var
|
|
8007
|
-
if (column === "Content") return ((
|
|
8134
|
+
var _a3, _b, _c;
|
|
8135
|
+
if (column === "Content") return ((_a3 = item == null ? void 0 : item.content) != null ? _a3 : "").substring(0, 100);
|
|
8008
8136
|
const meta = item.metadata || {};
|
|
8009
8137
|
const normalizedColumn = this.normalizeComparableField(column);
|
|
8010
8138
|
const exactMetadata = Object.entries(meta).find(
|
|
@@ -8056,8 +8184,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
8056
8184
|
let inStock = 0;
|
|
8057
8185
|
let outOfStock = 0;
|
|
8058
8186
|
data.forEach((d) => {
|
|
8059
|
-
var
|
|
8060
|
-
const cat = (
|
|
8187
|
+
var _a3, _b;
|
|
8188
|
+
const cat = (_a3 = this.getProductCategory(d)) != null ? _a3 : "Other";
|
|
8061
8189
|
if (cat === category) {
|
|
8062
8190
|
const quantity = (_b = this.extractStockQuantity(d)) != null ? _b : 1;
|
|
8063
8191
|
if (this.determineStockStatus(d)) inStock += quantity;
|
|
@@ -8103,9 +8231,9 @@ ${schemaProfileText}` : ""}`;
|
|
|
8103
8231
|
}
|
|
8104
8232
|
// ─── Product Extraction ───────────────────────────────────────────────────
|
|
8105
8233
|
static getDynamicVal(meta, uiKey, config, trainedSchema) {
|
|
8106
|
-
var
|
|
8234
|
+
var _a3;
|
|
8107
8235
|
if (!meta) return void 0;
|
|
8108
|
-
const mapping = (
|
|
8236
|
+
const mapping = (_a3 = config == null ? void 0 : config.rag) == null ? void 0 : _a3.uiMapping;
|
|
8109
8237
|
if ((mapping == null ? void 0 : mapping[uiKey]) && meta[mapping[uiKey]] !== void 0) return meta[mapping[uiKey]];
|
|
8110
8238
|
if (trainedSchema && typeof trainedSchema === "object") {
|
|
8111
8239
|
const trainedKey = trainedSchema[uiKey];
|
|
@@ -8114,7 +8242,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
8114
8242
|
return resolveMetadataValue(meta, uiKey);
|
|
8115
8243
|
}
|
|
8116
8244
|
static extractProductInfo(item, config, trainedSchema) {
|
|
8117
|
-
var
|
|
8245
|
+
var _a3, _b;
|
|
8118
8246
|
if (!item) return null;
|
|
8119
8247
|
const meta = item.metadata || {};
|
|
8120
8248
|
const content = item.content || "";
|
|
@@ -8122,7 +8250,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
8122
8250
|
const price = this.getDynamicVal(meta, "price", config, trainedSchema);
|
|
8123
8251
|
const brand = this.getDynamicVal(meta, "brand", config, trainedSchema);
|
|
8124
8252
|
const description = this.cleanProductDescription(
|
|
8125
|
-
(
|
|
8253
|
+
(_a3 = this.extractProductDescriptionFromContent(content)) != null ? _a3 : this.getProductDescriptionValue(meta, config, trainedSchema)
|
|
8126
8254
|
);
|
|
8127
8255
|
if (name || this.isProductData(item)) {
|
|
8128
8256
|
let finalName = name ? String(name) : void 0;
|
|
@@ -8257,10 +8385,10 @@ RULES:
|
|
|
8257
8385
|
}
|
|
8258
8386
|
static buildContextSummary(sources, maxChars = 6e3) {
|
|
8259
8387
|
const items = (sources || []).filter(Boolean).map((s, i) => {
|
|
8260
|
-
var
|
|
8388
|
+
var _a3, _b, _c, _d;
|
|
8261
8389
|
return {
|
|
8262
8390
|
index: i + 1,
|
|
8263
|
-
content: (_b = (
|
|
8391
|
+
content: (_b = (_a3 = s == null ? void 0 : s.content) == null ? void 0 : _a3.substring(0, 400)) != null ? _b : "",
|
|
8264
8392
|
metadata: (_c = s == null ? void 0 : s.metadata) != null ? _c : {},
|
|
8265
8393
|
score: (_d = s == null ? void 0 : s.score) != null ? _d : 0
|
|
8266
8394
|
};
|
|
@@ -8300,7 +8428,7 @@ var SchemaMapper = class {
|
|
|
8300
8428
|
return promise;
|
|
8301
8429
|
}
|
|
8302
8430
|
static async _doTrain(llm, cacheKey, keys) {
|
|
8303
|
-
var
|
|
8431
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
|
|
8304
8432
|
console.log(`[SchemaMapper] \u{1F9E0} Training on new schema keys: ${keys.join(", ")}`);
|
|
8305
8433
|
const propertyList = Object.entries(this.TARGET_PROPERTIES).map(([prop, desc]) => `- ${prop} (${desc})`).join("\n");
|
|
8306
8434
|
const messages = [
|
|
@@ -8316,7 +8444,7 @@ Return a JSON object like {"name":"Title","price":"Price",...}. Omit unmapped pr
|
|
|
8316
8444
|
}
|
|
8317
8445
|
];
|
|
8318
8446
|
try {
|
|
8319
|
-
const baseUrl = (
|
|
8447
|
+
const baseUrl = (_a3 = llm == null ? void 0 : llm.baseUrl) != null ? _a3 : "";
|
|
8320
8448
|
const apiKey = (_b = llm == null ? void 0 : llm.apiKey) != null ? _b : "";
|
|
8321
8449
|
const model = (_c = llm == null ? void 0 : llm.model) != null ? _c : "llama-3.1-8b-instant";
|
|
8322
8450
|
let responseText;
|
|
@@ -8491,9 +8619,9 @@ var Pipeline = class {
|
|
|
8491
8619
|
this.initialised = false;
|
|
8492
8620
|
/** Namespace-specific static cold context cache for CAG */
|
|
8493
8621
|
this.coldContexts = /* @__PURE__ */ new Map();
|
|
8494
|
-
var
|
|
8622
|
+
var _a3, _b, _c, _d, _e;
|
|
8495
8623
|
this.chunker = new DocumentChunker(
|
|
8496
|
-
(_b = (
|
|
8624
|
+
(_b = (_a3 = config.rag) == null ? void 0 : _a3.chunkSize) != null ? _b : 1e3,
|
|
8497
8625
|
(_d = (_c = config.rag) == null ? void 0 : _c.chunkOverlap) != null ? _d : 200
|
|
8498
8626
|
);
|
|
8499
8627
|
if (((_e = config.rag) == null ? void 0 : _e.chunkingStrategy) === "llamaindex") {
|
|
@@ -8509,7 +8637,7 @@ var Pipeline = class {
|
|
|
8509
8637
|
return this.initialised ? this.llmProvider : void 0;
|
|
8510
8638
|
}
|
|
8511
8639
|
async initialize() {
|
|
8512
|
-
var
|
|
8640
|
+
var _a3, _b, _c, _d;
|
|
8513
8641
|
if (this.initialised) return;
|
|
8514
8642
|
const chartInstruction = `You are a helpful assistant. Use the provided context to answer questions accurately.
|
|
8515
8643
|
|
|
@@ -8552,7 +8680,7 @@ var Pipeline = class {
|
|
|
8552
8680
|
this.entityExtractor = new EntityExtractor(this.llmProvider);
|
|
8553
8681
|
}
|
|
8554
8682
|
await this.vectorDB.initialize();
|
|
8555
|
-
if (((
|
|
8683
|
+
if (((_a3 = this.config.rag) == null ? void 0 : _a3.architecture) === "agentic" || ((_b = this.config.rag) == null ? void 0 : _b.architecture) === "multi-agent" || this.config.mcpServers && this.config.mcpServers.length > 0) {
|
|
8556
8684
|
this.mcpRegistry = new MCPRegistry(this.config.mcpServers || []);
|
|
8557
8685
|
this.multiAgentCoordinator = new MultiAgentCoordinator({
|
|
8558
8686
|
llmProvider: this.llmProvider,
|
|
@@ -8570,8 +8698,8 @@ var Pipeline = class {
|
|
|
8570
8698
|
this.initialised = true;
|
|
8571
8699
|
}
|
|
8572
8700
|
async loadColdContext(ns) {
|
|
8573
|
-
var
|
|
8574
|
-
const cagConfig = (
|
|
8701
|
+
var _a3, _b;
|
|
8702
|
+
const cagConfig = (_a3 = this.config.rag) == null ? void 0 : _a3.cag;
|
|
8575
8703
|
if (!cagConfig || !cagConfig.enabled) return;
|
|
8576
8704
|
try {
|
|
8577
8705
|
const coldNs = cagConfig.coldNamespace || ns;
|
|
@@ -8624,12 +8752,12 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8624
8752
|
}
|
|
8625
8753
|
/** Step 1: Chunk the document content. */
|
|
8626
8754
|
async prepareChunks(doc) {
|
|
8627
|
-
var
|
|
8755
|
+
var _a3, _b;
|
|
8628
8756
|
if (this.llamaIngestor) {
|
|
8629
8757
|
return this.llamaIngestor.chunk(doc.content, {
|
|
8630
8758
|
docId: doc.docId,
|
|
8631
8759
|
metadata: doc.metadata,
|
|
8632
|
-
chunkSize: (
|
|
8760
|
+
chunkSize: (_a3 = this.config.rag) == null ? void 0 : _a3.chunkSize,
|
|
8633
8761
|
chunkOverlap: (_b = this.config.rag) == null ? void 0 : _b.chunkOverlap
|
|
8634
8762
|
});
|
|
8635
8763
|
}
|
|
@@ -8727,9 +8855,9 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8727
8855
|
return { reply, sources };
|
|
8728
8856
|
}
|
|
8729
8857
|
async ask(question, history = [], namespace) {
|
|
8730
|
-
var
|
|
8858
|
+
var _a3, _b;
|
|
8731
8859
|
await this.initialize();
|
|
8732
|
-
if ((((
|
|
8860
|
+
if ((((_a3 = this.config.rag) == null ? void 0 : _a3.architecture) === "agentic" || ((_b = this.config.rag) == null ? void 0 : _b.architecture) === "multi-agent" || this.config.mcpServers && this.config.mcpServers.length > 0) && this.multiAgentCoordinator) {
|
|
8733
8861
|
return await this.multiAgentCoordinator.run(question, history);
|
|
8734
8862
|
}
|
|
8735
8863
|
const stream = this.askStream(question, history, namespace);
|
|
@@ -8764,9 +8892,9 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8764
8892
|
}
|
|
8765
8893
|
askStream(_0) {
|
|
8766
8894
|
return __asyncGenerator(this, arguments, function* (question, history = [], namespace) {
|
|
8767
|
-
var
|
|
8895
|
+
var _a3, _b;
|
|
8768
8896
|
yield new __await(this.initialize());
|
|
8769
|
-
if ((((
|
|
8897
|
+
if ((((_a3 = this.config.rag) == null ? void 0 : _a3.architecture) === "agentic" || ((_b = this.config.rag) == null ? void 0 : _b.architecture) === "multi-agent" || this.config.mcpServers && this.config.mcpServers.length > 0) && this.multiAgentCoordinator) {
|
|
8770
8898
|
const stream2 = this.multiAgentCoordinator.runStream(question, history);
|
|
8771
8899
|
try {
|
|
8772
8900
|
for (var iter = __forAwait(stream2), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
|
|
@@ -8815,10 +8943,10 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8815
8943
|
*/
|
|
8816
8944
|
askStreamInternal(_0) {
|
|
8817
8945
|
return __asyncGenerator(this, arguments, function* (question, history = [], namespace) {
|
|
8818
|
-
var
|
|
8946
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B;
|
|
8819
8947
|
yield new __await(this.initialize());
|
|
8820
8948
|
const ns = formatNamespace(namespace != null ? namespace : this.config.projectId);
|
|
8821
|
-
const topK = (_b = (
|
|
8949
|
+
const topK = (_b = (_a3 = this.config.rag) == null ? void 0 : _a3.topK) != null ? _b : 5;
|
|
8822
8950
|
const scoreThreshold = (_d = (_c = this.config.rag) == null ? void 0 : _c.scoreThreshold) != null ? _d : 0.3;
|
|
8823
8951
|
const requestId = `req_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
8824
8952
|
const requestStart = performance.now();
|
|
@@ -8867,8 +8995,8 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8867
8995
|
const rerankStart = performance.now();
|
|
8868
8996
|
const structuredSources = this.applyStructuredFilters(rawSources, filter).filter((s) => Boolean(s && typeof s === "object"));
|
|
8869
8997
|
let fullSources = hasNumericPredicates ? structuredSources : structuredSources.filter((m) => {
|
|
8870
|
-
var
|
|
8871
|
-
return ((
|
|
8998
|
+
var _a4;
|
|
8999
|
+
return ((_a4 = m == null ? void 0 : m.score) != null ? _a4 : 0) >= scoreThreshold;
|
|
8872
9000
|
});
|
|
8873
9001
|
const rerankLimit = Math.max(retrievalLimit, fullSources.length);
|
|
8874
9002
|
const useReranking = arch !== "naive" && (arch === "retrieve-and-rerank" || ((_m = this.config.rag) == null ? void 0 : _m.useReranking));
|
|
@@ -8881,13 +9009,13 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8881
9009
|
let context = promptSources.length ? `[SEARCH SUMMARY: Found ${totalCount} matching record(s) out of ${rawSources.length} total resources searched in database. Context includes top ${promptSources.length} relevant records]
|
|
8882
9010
|
|
|
8883
9011
|
` + promptSources.map((m, i) => {
|
|
8884
|
-
var
|
|
9012
|
+
var _a4;
|
|
8885
9013
|
return `[Source ${i + 1}]
|
|
8886
|
-
${(
|
|
9014
|
+
${(_a4 = m == null ? void 0 : m.content) != null ? _a4 : ""}`;
|
|
8887
9015
|
}).join("\n\n---\n\n") : "No relevant context found.";
|
|
8888
9016
|
const sources = [...fullSources].filter((s) => Boolean(s && typeof s === "object")).sort((a, b) => {
|
|
8889
|
-
var
|
|
8890
|
-
return ((
|
|
9017
|
+
var _a4, _b2;
|
|
9018
|
+
return ((_a4 = b == null ? void 0 : b.score) != null ? _a4 : 0) - ((_b2 = a == null ? void 0 : a.score) != null ? _b2 : 0);
|
|
8891
9019
|
});
|
|
8892
9020
|
if (graphData && graphData.nodes.length > 0) {
|
|
8893
9021
|
const graphContext = graphData.nodes.map(
|
|
@@ -8915,10 +9043,10 @@ ${context}`;
|
|
|
8915
9043
|
yield {
|
|
8916
9044
|
reply: "",
|
|
8917
9045
|
sources: (sources || []).filter((s) => Boolean(s && typeof s === "object")).map((s) => {
|
|
8918
|
-
var
|
|
9046
|
+
var _a4, _b2, _c2;
|
|
8919
9047
|
return {
|
|
8920
9048
|
id: s.id,
|
|
8921
|
-
score: (
|
|
9049
|
+
score: (_a4 = s.score) != null ? _a4 : 0,
|
|
8922
9050
|
content: (_b2 = s == null ? void 0 : s.content) != null ? _b2 : "",
|
|
8923
9051
|
metadata: (_c2 = s == null ? void 0 : s.metadata) != null ? _c2 : {},
|
|
8924
9052
|
namespace: ns
|
|
@@ -9111,11 +9239,11 @@ ${context}`;
|
|
|
9111
9239
|
systemPrompt,
|
|
9112
9240
|
userPrompt: question + finalRestrictionSuffix,
|
|
9113
9241
|
chunks: (sources || []).filter(Boolean).map((s) => {
|
|
9114
|
-
var
|
|
9242
|
+
var _a4, _b2;
|
|
9115
9243
|
return {
|
|
9116
9244
|
id: s.id,
|
|
9117
9245
|
score: s.score,
|
|
9118
|
-
content: (
|
|
9246
|
+
content: (_a4 = s == null ? void 0 : s.content) != null ? _a4 : "",
|
|
9119
9247
|
metadata: (_b2 = s == null ? void 0 : s.metadata) != null ? _b2 : {},
|
|
9120
9248
|
namespace: ns
|
|
9121
9249
|
};
|
|
@@ -9134,7 +9262,7 @@ ${context}`;
|
|
|
9134
9262
|
const telemetryUrl = ((_B = this.config.telemetry) == null ? void 0 : _B.url) || process.env.TELEMETRY_URL || process.env.NEXT_PUBLIC_TELEMETRY_URL || defaultUrl;
|
|
9135
9263
|
const absoluteUrl = telemetryUrl.startsWith("http") ? telemetryUrl : "https://www.retrivora.com" + (telemetryUrl.startsWith("/") ? telemetryUrl : "/" + telemetryUrl);
|
|
9136
9264
|
(async () => {
|
|
9137
|
-
var
|
|
9265
|
+
var _a4, _b2, _c2, _d2, _e2;
|
|
9138
9266
|
try {
|
|
9139
9267
|
let finalTrace = trace;
|
|
9140
9268
|
if (!awaitHallucination && runHallucination) {
|
|
@@ -9143,7 +9271,7 @@ ${context}`;
|
|
|
9143
9271
|
finalTrace = buildTrace(backgroundScoreResult);
|
|
9144
9272
|
}
|
|
9145
9273
|
}
|
|
9146
|
-
const modelName = (finalTrace == null ? void 0 : finalTrace.model) || ((
|
|
9274
|
+
const modelName = (finalTrace == null ? void 0 : finalTrace.model) || ((_a4 = this.config.llm) == null ? void 0 : _a4.model) || "llama-3.1-8b-instant";
|
|
9147
9275
|
const providerName = (finalTrace == null ? void 0 : finalTrace.provider) || ((_b2 = this.config.llm) == null ? void 0 : _b2.provider) || "groq";
|
|
9148
9276
|
const tokenCount = Number(((_c2 = finalTrace == null ? void 0 : finalTrace.tokens) == null ? void 0 : _c2.totalTokens) || 0);
|
|
9149
9277
|
const costEst = Number(((_d2 = finalTrace == null ? void 0 : finalTrace.tokens) == null ? void 0 : _d2.estimatedCostUsd) || 0);
|
|
@@ -9197,7 +9325,7 @@ ${context}`;
|
|
|
9197
9325
|
* Uses an LRU-bounded embedding cache to avoid re-embedding the same query.
|
|
9198
9326
|
*/
|
|
9199
9327
|
async generateUiTransformation(question, sources, cachedSchema, forceDeterministic = false) {
|
|
9200
|
-
var
|
|
9328
|
+
var _a3;
|
|
9201
9329
|
if (!sources || sources.length === 0) {
|
|
9202
9330
|
return UITransformer.transform(question, sources, this.config, cachedSchema);
|
|
9203
9331
|
}
|
|
@@ -9210,7 +9338,7 @@ ${context}`;
|
|
|
9210
9338
|
{ visualizationHint: "product_browse", recommendedChart: "text", filterInStockOnly: false, wantsExplicitTable: false, isTemporal: false, isComparison: false, language: "en" }
|
|
9211
9339
|
);
|
|
9212
9340
|
}
|
|
9213
|
-
const enableLlmUiTransform = ((
|
|
9341
|
+
const enableLlmUiTransform = ((_a3 = this.config.llm.options) == null ? void 0 : _a3.enableLlmUiTransform) === true;
|
|
9214
9342
|
if (forceDeterministic || !enableLlmUiTransform) {
|
|
9215
9343
|
return UITransformer.transform(question, sources, this.config, cachedSchema);
|
|
9216
9344
|
}
|
|
@@ -9228,15 +9356,15 @@ ${context}`;
|
|
|
9228
9356
|
const value = this.resolveNumericPredicateValue(source, predicate);
|
|
9229
9357
|
return value !== null && this.matchesNumericPredicate(value, predicate);
|
|
9230
9358
|
})).sort((a, b) => {
|
|
9231
|
-
var
|
|
9359
|
+
var _a3, _b;
|
|
9232
9360
|
const primary = predicates[0];
|
|
9233
|
-
const aValue = (
|
|
9361
|
+
const aValue = (_a3 = this.resolveNumericPredicateValue(a, primary)) != null ? _a3 : 0;
|
|
9234
9362
|
const bValue = (_b = this.resolveNumericPredicateValue(b, primary)) != null ? _b : 0;
|
|
9235
9363
|
return primary.operator === "lt" || primary.operator === "lte" ? aValue - bValue : bValue - aValue;
|
|
9236
9364
|
});
|
|
9237
9365
|
}
|
|
9238
9366
|
resolveNumericPredicateValue(source, predicate) {
|
|
9239
|
-
var
|
|
9367
|
+
var _a3;
|
|
9240
9368
|
if (!source) return null;
|
|
9241
9369
|
const meta = source.metadata || {};
|
|
9242
9370
|
const field = predicate.field;
|
|
@@ -9249,7 +9377,7 @@ ${context}`;
|
|
|
9249
9377
|
const value = this.toFiniteNumber(Array.isArray(fuzzy) ? fuzzy[1] : fuzzy.value);
|
|
9250
9378
|
if (value !== null) return value;
|
|
9251
9379
|
}
|
|
9252
|
-
const contentValue = this.extractNumericValueFromContent((
|
|
9380
|
+
const contentValue = this.extractNumericValueFromContent((_a3 = source.content) != null ? _a3 : "", field);
|
|
9253
9381
|
if (contentValue !== null) return contentValue;
|
|
9254
9382
|
}
|
|
9255
9383
|
for (const [key, value] of entries) {
|
|
@@ -9305,8 +9433,8 @@ ${context}`;
|
|
|
9305
9433
|
return Number.isFinite(numeric) ? numeric : null;
|
|
9306
9434
|
}
|
|
9307
9435
|
async retrieve(query, options) {
|
|
9308
|
-
var
|
|
9309
|
-
const ns = formatNamespace((
|
|
9436
|
+
var _a3, _b, _c, _d, _e, _f, _g2;
|
|
9437
|
+
const ns = formatNamespace((_a3 = options.namespace) != null ? _a3 : this.config.projectId);
|
|
9310
9438
|
const topK = (_b = options.topK) != null ? _b : 5;
|
|
9311
9439
|
const cacheKey = `${ns}::${query}`;
|
|
9312
9440
|
let queryVector = this.embeddingCache.get(cacheKey);
|
|
@@ -9351,11 +9479,11 @@ ${context}`;
|
|
|
9351
9479
|
namespace: ns,
|
|
9352
9480
|
count: resolvedSources.length,
|
|
9353
9481
|
sample: resolvedSources.slice(0, 2).map((s) => {
|
|
9354
|
-
var
|
|
9482
|
+
var _a4;
|
|
9355
9483
|
return {
|
|
9356
9484
|
id: s == null ? void 0 : s.id,
|
|
9357
9485
|
score: s == null ? void 0 : s.score,
|
|
9358
|
-
contentSnippet: String((
|
|
9486
|
+
contentSnippet: String((_a4 = s == null ? void 0 : s.content) != null ? _a4 : "").substring(0, 150),
|
|
9359
9487
|
metadata: s == null ? void 0 : s.metadata
|
|
9360
9488
|
};
|
|
9361
9489
|
})
|
|
@@ -9369,8 +9497,8 @@ Focus on extracting the core intent and entities. Do not answer the question, ju
|
|
|
9369
9497
|
|
|
9370
9498
|
History:
|
|
9371
9499
|
${(history || []).map((m) => {
|
|
9372
|
-
var
|
|
9373
|
-
return `${(m == null ? void 0 : m.role) || "user"}: ${(
|
|
9500
|
+
var _a3;
|
|
9501
|
+
return `${(m == null ? void 0 : m.role) || "user"}: ${(_a3 = m == null ? void 0 : m.content) != null ? _a3 : ""}`;
|
|
9374
9502
|
}).join("\n")}
|
|
9375
9503
|
|
|
9376
9504
|
New Question: ${question}
|
|
@@ -9397,8 +9525,8 @@ Optimized Search Query:`;
|
|
|
9397
9525
|
const { sources } = await this.retrieve(query, { namespace: ns, topK: 5 });
|
|
9398
9526
|
if (!sources || sources.length === 0) return [];
|
|
9399
9527
|
const context = sources.map((s) => {
|
|
9400
|
-
var
|
|
9401
|
-
return (
|
|
9528
|
+
var _a3;
|
|
9529
|
+
return (_a3 = s == null ? void 0 : s.content) != null ? _a3 : "";
|
|
9402
9530
|
}).join("\n\n---\n\n");
|
|
9403
9531
|
const prompt = `Based on the following snippets from a document, what are at least 5 short, relevant questions a user might ask?
|
|
9404
9532
|
Focus on questions that can be answered by the context.
|
|
@@ -9440,13 +9568,13 @@ var Retrivora = class {
|
|
|
9440
9568
|
this.pipeline = new Pipeline(this.config);
|
|
9441
9569
|
}
|
|
9442
9570
|
async initialize() {
|
|
9443
|
-
var
|
|
9571
|
+
var _a3;
|
|
9444
9572
|
try {
|
|
9445
9573
|
await ConfigValidator.validateAndThrow(this.config);
|
|
9446
9574
|
LicenseVerifier.verify(
|
|
9447
9575
|
this.config.licenseKey,
|
|
9448
9576
|
this.config.projectId,
|
|
9449
|
-
(
|
|
9577
|
+
(_a3 = this.config.vectorDb) == null ? void 0 : _a3.provider
|
|
9450
9578
|
);
|
|
9451
9579
|
await LicenseVerifier.verifyIP(this.config.licenseKey);
|
|
9452
9580
|
} catch (err) {
|
|
@@ -9619,18 +9747,200 @@ var ProviderHealthCheck = class {
|
|
|
9619
9747
|
}
|
|
9620
9748
|
};
|
|
9621
9749
|
|
|
9750
|
+
// src/core/FreeTierLimitsGuard.ts
|
|
9751
|
+
var FREE_TIER_QUOTAS = {
|
|
9752
|
+
MAX_DOCUMENTS: 25,
|
|
9753
|
+
MAX_FILE_SIZE_BYTES: 20 * 1024 * 1024,
|
|
9754
|
+
MAX_STORAGE_BYTES: 250 * 1024 * 1024,
|
|
9755
|
+
MAX_TRIAL_REQUEST_UNITS: 500,
|
|
9756
|
+
MAX_DAILY_REQUEST_UNITS: 50,
|
|
9757
|
+
TRIAL_DURATION_DAYS: 14,
|
|
9758
|
+
GRACE_PERIOD_DAYS: 2,
|
|
9759
|
+
MAX_RPM: 10,
|
|
9760
|
+
MAX_RPH: 100,
|
|
9761
|
+
MAX_RPD: 500,
|
|
9762
|
+
MAX_CONCURRENT_REQUESTS: 2,
|
|
9763
|
+
MAX_INPUT_TOKENS: 2e4,
|
|
9764
|
+
MAX_OUTPUT_TOKENS: 4e3,
|
|
9765
|
+
UPGRADE_REMINDER_DAYS: [7, 12, 14],
|
|
9766
|
+
MAX_USERS: 1,
|
|
9767
|
+
MAX_NAMESPACES: 1,
|
|
9768
|
+
MAX_PROJECTS: 1
|
|
9769
|
+
};
|
|
9770
|
+
var FreeTierLimitsGuard = class {
|
|
9771
|
+
static calculateTrialTimestamps(startedAt) {
|
|
9772
|
+
const startDate = startedAt ? new Date(startedAt) : /* @__PURE__ */ new Date();
|
|
9773
|
+
const trialStartedAtMs = startDate.getTime();
|
|
9774
|
+
const trialExpiresAtMs = trialStartedAtMs + FREE_TIER_QUOTAS.TRIAL_DURATION_DAYS * 24 * 60 * 60 * 1e3;
|
|
9775
|
+
const gracePeriodExpiresAtMs = trialStartedAtMs + (FREE_TIER_QUOTAS.TRIAL_DURATION_DAYS + FREE_TIER_QUOTAS.GRACE_PERIOD_DAYS) * 24 * 60 * 60 * 1e3;
|
|
9776
|
+
return {
|
|
9777
|
+
trial_started_at: new Date(trialStartedAtMs).toISOString(),
|
|
9778
|
+
trial_expires_at: new Date(trialExpiresAtMs).toISOString(),
|
|
9779
|
+
grace_period_expires_at: new Date(gracePeriodExpiresAtMs).toISOString()
|
|
9780
|
+
};
|
|
9781
|
+
}
|
|
9782
|
+
static calculateRequestUnits(operationType, options) {
|
|
9783
|
+
var _a3;
|
|
9784
|
+
const op = operationType.toLowerCase().trim();
|
|
9785
|
+
if (op.includes("suggestion") || op.includes("template") || op.includes("history") || op.includes("model") || op.includes("health") || op.includes("auth") || op.includes("license") || op.includes("usage") || op.includes("feedback") || op.includes("analytic")) {
|
|
9786
|
+
return 0;
|
|
9787
|
+
}
|
|
9788
|
+
if (op.includes("image")) {
|
|
9789
|
+
return 10;
|
|
9790
|
+
}
|
|
9791
|
+
if (op.includes("embedding")) {
|
|
9792
|
+
const chunks = (_a3 = options == null ? void 0 : options.chunkCount) != null ? _a3 : 1;
|
|
9793
|
+
return Math.max(1, Math.ceil(chunks / 1e3));
|
|
9794
|
+
}
|
|
9795
|
+
return 1;
|
|
9796
|
+
}
|
|
9797
|
+
static checkTrialStatus(startedAt, totalUnitsUsed = 0, nowServerTime = /* @__PURE__ */ new Date()) {
|
|
9798
|
+
const timestamps = this.calculateTrialTimestamps(startedAt);
|
|
9799
|
+
const startMs = new Date(timestamps.trial_started_at).getTime();
|
|
9800
|
+
const expireMs = new Date(timestamps.trial_expires_at).getTime();
|
|
9801
|
+
const graceExpireMs = new Date(timestamps.grace_period_expires_at).getTime();
|
|
9802
|
+
const nowMs = nowServerTime.getTime();
|
|
9803
|
+
const daysElapsed = Math.floor(Math.max(0, nowMs - startMs) / (1e3 * 60 * 60 * 24));
|
|
9804
|
+
const daysRemaining = Math.max(0, Math.ceil((expireMs - nowMs) / (1e3 * 60 * 60 * 24)));
|
|
9805
|
+
const isConsumedUnits = totalUnitsUsed >= FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS;
|
|
9806
|
+
const isExpiredTime = nowMs > expireMs;
|
|
9807
|
+
const isPastGraceTime = nowMs > graceExpireMs;
|
|
9808
|
+
let status = "active";
|
|
9809
|
+
let reason;
|
|
9810
|
+
if (isPastGraceTime || isConsumedUnits && isExpiredTime) {
|
|
9811
|
+
status = "expired";
|
|
9812
|
+
reason = "Trial period and grace period have expired. Upgrade your plan.";
|
|
9813
|
+
} else if (isExpiredTime || isConsumedUnits) {
|
|
9814
|
+
status = "grace_period";
|
|
9815
|
+
reason = isConsumedUnits ? "Total trial request quota (500 units) consumed. Grace period active (dashboard access only)." : "14-day trial period expired. 2-day grace period active (dashboard access only).";
|
|
9816
|
+
}
|
|
9817
|
+
let upgradeReminderDue;
|
|
9818
|
+
if (FREE_TIER_QUOTAS.UPGRADE_REMINDER_DAYS.includes(daysElapsed)) {
|
|
9819
|
+
upgradeReminderDue = daysElapsed;
|
|
9820
|
+
}
|
|
9821
|
+
let usageReminderDue;
|
|
9822
|
+
const usagePercent = totalUnitsUsed / FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS * 100;
|
|
9823
|
+
if (usagePercent >= 100) {
|
|
9824
|
+
usageReminderDue = "100%";
|
|
9825
|
+
} else if (usagePercent >= 90) {
|
|
9826
|
+
usageReminderDue = "90%";
|
|
9827
|
+
} else if (usagePercent >= 80) {
|
|
9828
|
+
usageReminderDue = "80%";
|
|
9829
|
+
}
|
|
9830
|
+
return {
|
|
9831
|
+
status,
|
|
9832
|
+
daysElapsed,
|
|
9833
|
+
daysRemaining,
|
|
9834
|
+
isGracePeriod: status === "grace_period",
|
|
9835
|
+
isExpired: status === "expired",
|
|
9836
|
+
upgradeReminderDue,
|
|
9837
|
+
usageReminderDue,
|
|
9838
|
+
reason
|
|
9839
|
+
};
|
|
9840
|
+
}
|
|
9841
|
+
static checkIngestionAllowed(stats, incomingSizeBytes = 0) {
|
|
9842
|
+
var _a3, _b;
|
|
9843
|
+
const docs = (_a3 = stats.documentCount) != null ? _a3 : 0;
|
|
9844
|
+
const storage = (_b = stats.totalStorageBytes) != null ? _b : 0;
|
|
9845
|
+
if (incomingSizeBytes > FREE_TIER_QUOTAS.MAX_FILE_SIZE_BYTES) {
|
|
9846
|
+
const mbSize = (incomingSizeBytes / (1024 * 1024)).toFixed(1);
|
|
9847
|
+
return {
|
|
9848
|
+
allowed: false,
|
|
9849
|
+
reason: `[FreeTierIngestor] File size (${mbSize}MB) exceeds maximum allowed size of 20MB under Free Tier rules.`
|
|
9850
|
+
};
|
|
9851
|
+
}
|
|
9852
|
+
if (docs >= FREE_TIER_QUOTAS.MAX_DOCUMENTS) {
|
|
9853
|
+
return {
|
|
9854
|
+
allowed: false,
|
|
9855
|
+
reason: `Document limit reached (${docs}/${FREE_TIER_QUOTAS.MAX_DOCUMENTS}). Upgrade to Pro to ingest more documents.`
|
|
9856
|
+
};
|
|
9857
|
+
}
|
|
9858
|
+
if (storage + incomingSizeBytes > FREE_TIER_QUOTAS.MAX_STORAGE_BYTES) {
|
|
9859
|
+
const mbUsed = (storage / (1024 * 1024)).toFixed(1);
|
|
9860
|
+
return {
|
|
9861
|
+
allowed: false,
|
|
9862
|
+
reason: `Storage quota exceeded (${mbUsed}MB / 250MB). Upgrade for unlimited storage.`
|
|
9863
|
+
};
|
|
9864
|
+
}
|
|
9865
|
+
return { allowed: true };
|
|
9866
|
+
}
|
|
9867
|
+
static checkRequestAllowed(params) {
|
|
9868
|
+
var _a3, _b, _c;
|
|
9869
|
+
const op = (_a3 = params.operationType) != null ? _a3 : "chat";
|
|
9870
|
+
const costUnits = this.calculateRequestUnits(op, { chunkCount: params.chunkCount });
|
|
9871
|
+
if (costUnits === 0) {
|
|
9872
|
+
return { allowed: true, costUnits: 0 };
|
|
9873
|
+
}
|
|
9874
|
+
if (params.inputTokens && params.inputTokens > FREE_TIER_QUOTAS.MAX_INPUT_TOKENS) {
|
|
9875
|
+
return {
|
|
9876
|
+
allowed: false,
|
|
9877
|
+
reason: "Token limit exceeded. Upgrade your plan.",
|
|
9878
|
+
costUnits
|
|
9879
|
+
};
|
|
9880
|
+
}
|
|
9881
|
+
if (params.outputTokens && params.outputTokens > FREE_TIER_QUOTAS.MAX_OUTPUT_TOKENS) {
|
|
9882
|
+
return {
|
|
9883
|
+
allowed: false,
|
|
9884
|
+
reason: "Token limit exceeded. Upgrade your plan.",
|
|
9885
|
+
costUnits
|
|
9886
|
+
};
|
|
9887
|
+
}
|
|
9888
|
+
if (params.concurrentRequests && params.concurrentRequests > FREE_TIER_QUOTAS.MAX_CONCURRENT_REQUESTS) {
|
|
9889
|
+
return {
|
|
9890
|
+
allowed: false,
|
|
9891
|
+
reason: `Concurrent limit exceeded (max ${FREE_TIER_QUOTAS.MAX_CONCURRENT_REQUESTS} active requests). Please wait for active streams to finish.`,
|
|
9892
|
+
costUnits
|
|
9893
|
+
};
|
|
9894
|
+
}
|
|
9895
|
+
const totalUnits = (_b = params.totalUnitsUsed) != null ? _b : 0;
|
|
9896
|
+
const trialStatus = this.checkTrialStatus(params.trialStartedAt, totalUnits, params.nowServerTime);
|
|
9897
|
+
if (trialStatus.status === "expired" || trialStatus.status === "grace_period") {
|
|
9898
|
+
return {
|
|
9899
|
+
allowed: false,
|
|
9900
|
+
reason: trialStatus.reason || "Trial limit reached. Upgrade your plan.",
|
|
9901
|
+
costUnits
|
|
9902
|
+
};
|
|
9903
|
+
}
|
|
9904
|
+
if (totalUnits + costUnits > FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS) {
|
|
9905
|
+
return {
|
|
9906
|
+
allowed: false,
|
|
9907
|
+
reason: `Total trial request unit limit reached (${totalUnits}/${FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS}). Upgrade your plan.`,
|
|
9908
|
+
costUnits
|
|
9909
|
+
};
|
|
9910
|
+
}
|
|
9911
|
+
const dailyUnits = (_c = params.dailyUnitsUsed) != null ? _c : 0;
|
|
9912
|
+
if (dailyUnits + costUnits > FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS) {
|
|
9913
|
+
return {
|
|
9914
|
+
allowed: false,
|
|
9915
|
+
reason: `Daily request quota limit reached (${dailyUnits}/${FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS} units/day). Quota resets tomorrow.`,
|
|
9916
|
+
costUnits
|
|
9917
|
+
};
|
|
9918
|
+
}
|
|
9919
|
+
return { allowed: true, costUnits };
|
|
9920
|
+
}
|
|
9921
|
+
static checkQueryAllowed(dailyQueriesCount = 0) {
|
|
9922
|
+
if (dailyQueriesCount >= FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS) {
|
|
9923
|
+
return {
|
|
9924
|
+
allowed: false,
|
|
9925
|
+
reason: `Daily query limit reached (${FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS}/day). Quota resets tomorrow.`
|
|
9926
|
+
};
|
|
9927
|
+
}
|
|
9928
|
+
return { allowed: true };
|
|
9929
|
+
}
|
|
9930
|
+
};
|
|
9931
|
+
|
|
9622
9932
|
// src/core/VectorPlugin.ts
|
|
9623
9933
|
var VectorPlugin = class {
|
|
9624
9934
|
constructor(hostConfig) {
|
|
9625
9935
|
const resolvedConfig = ConfigResolver.resolve(hostConfig);
|
|
9626
9936
|
this.config = resolvedConfig;
|
|
9627
9937
|
this.validationPromise = (async () => {
|
|
9628
|
-
var
|
|
9938
|
+
var _a3;
|
|
9629
9939
|
await ConfigValidator.validateAndThrow(resolvedConfig);
|
|
9630
9940
|
LicenseVerifier.verify(
|
|
9631
9941
|
resolvedConfig.licenseKey,
|
|
9632
9942
|
resolvedConfig.projectId,
|
|
9633
|
-
(
|
|
9943
|
+
(_a3 = resolvedConfig.vectorDb) == null ? void 0 : _a3.provider
|
|
9634
9944
|
);
|
|
9635
9945
|
})();
|
|
9636
9946
|
this.validationPromise.catch(() => {
|
|
@@ -9664,16 +9974,32 @@ var VectorPlugin = class {
|
|
|
9664
9974
|
this.config.embedding
|
|
9665
9975
|
);
|
|
9666
9976
|
}
|
|
9977
|
+
estimateInputTokens(message, history = []) {
|
|
9978
|
+
const allContent = message.length + history.reduce((acc, m) => {
|
|
9979
|
+
var _a3, _b;
|
|
9980
|
+
return acc + (((_a3 = m == null ? void 0 : m.content) == null ? void 0 : _a3.length) || ((_b = m == null ? void 0 : m.text) == null ? void 0 : _b.length) || 0);
|
|
9981
|
+
}, 0);
|
|
9982
|
+
return Math.ceil(allContent / 4);
|
|
9983
|
+
}
|
|
9667
9984
|
/**
|
|
9668
9985
|
* Run a chat query.
|
|
9669
9986
|
*/
|
|
9670
9987
|
async chat(message, history = [], namespace) {
|
|
9988
|
+
var _a3;
|
|
9671
9989
|
try {
|
|
9672
9990
|
await this.validationPromise;
|
|
9673
9991
|
} catch (err) {
|
|
9674
9992
|
throw wrapError(err, "CONFIGURATION_ERROR");
|
|
9675
9993
|
}
|
|
9676
9994
|
try {
|
|
9995
|
+
const inputTokens = this.estimateInputTokens(message, history);
|
|
9996
|
+
const tokenCheck = FreeTierLimitsGuard.checkRequestAllowed({
|
|
9997
|
+
operationType: "chat",
|
|
9998
|
+
inputTokens
|
|
9999
|
+
});
|
|
10000
|
+
if (!tokenCheck.allowed && ((_a3 = tokenCheck.reason) == null ? void 0 : _a3.toLowerCase().includes("token"))) {
|
|
10001
|
+
throw wrapError(new Error(tokenCheck.reason), "RATE_LIMITED");
|
|
10002
|
+
}
|
|
9677
10003
|
return await this.pipeline.ask(message, history, namespace);
|
|
9678
10004
|
} catch (err) {
|
|
9679
10005
|
const msg = String(err);
|
|
@@ -9681,6 +10007,9 @@ var VectorPlugin = class {
|
|
|
9681
10007
|
if (msg.includes("Embed") || msg.includes("embed")) {
|
|
9682
10008
|
defaultCode = "EMBEDDING_FAILED";
|
|
9683
10009
|
}
|
|
10010
|
+
if (msg.toLowerCase().includes("token limit")) {
|
|
10011
|
+
defaultCode = "RATE_LIMITED";
|
|
10012
|
+
}
|
|
9684
10013
|
throw wrapError(err, defaultCode);
|
|
9685
10014
|
}
|
|
9686
10015
|
}
|
|
@@ -9689,12 +10018,21 @@ var VectorPlugin = class {
|
|
|
9689
10018
|
*/
|
|
9690
10019
|
chatStream(_0) {
|
|
9691
10020
|
return __asyncGenerator(this, arguments, function* (message, history = [], namespace) {
|
|
10021
|
+
var _a3;
|
|
9692
10022
|
try {
|
|
9693
10023
|
yield new __await(this.validationPromise);
|
|
9694
10024
|
} catch (err) {
|
|
9695
10025
|
throw wrapError(err, "CONFIGURATION_ERROR");
|
|
9696
10026
|
}
|
|
9697
10027
|
try {
|
|
10028
|
+
const inputTokens = this.estimateInputTokens(message, history);
|
|
10029
|
+
const tokenCheck = FreeTierLimitsGuard.checkRequestAllowed({
|
|
10030
|
+
operationType: "chat_stream",
|
|
10031
|
+
inputTokens
|
|
10032
|
+
});
|
|
10033
|
+
if (!tokenCheck.allowed && ((_a3 = tokenCheck.reason) == null ? void 0 : _a3.toLowerCase().includes("token"))) {
|
|
10034
|
+
throw wrapError(new Error(tokenCheck.reason), "RATE_LIMITED");
|
|
10035
|
+
}
|
|
9698
10036
|
const stream = this.pipeline.askStream(message, history, namespace);
|
|
9699
10037
|
try {
|
|
9700
10038
|
for (var iter = __forAwait(stream), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
|
|
@@ -9717,6 +10055,9 @@ var VectorPlugin = class {
|
|
|
9717
10055
|
if (msg.includes("Embed") || msg.includes("embed")) {
|
|
9718
10056
|
defaultCode = "EMBEDDING_FAILED";
|
|
9719
10057
|
}
|
|
10058
|
+
if (msg.toLowerCase().includes("token limit")) {
|
|
10059
|
+
defaultCode = "RATE_LIMITED";
|
|
10060
|
+
}
|
|
9720
10061
|
throw wrapError(err, defaultCode);
|
|
9721
10062
|
}
|
|
9722
10063
|
});
|
|
@@ -9771,13 +10112,13 @@ var ConfigBuilder = class {
|
|
|
9771
10112
|
* Configure the vector database provider
|
|
9772
10113
|
*/
|
|
9773
10114
|
vectorDb(provider, options) {
|
|
9774
|
-
var
|
|
10115
|
+
var _a3;
|
|
9775
10116
|
if (provider === "auto") {
|
|
9776
10117
|
this._vectorDb = this._autoDetectVectorDb();
|
|
9777
10118
|
} else {
|
|
9778
10119
|
this._vectorDb = {
|
|
9779
10120
|
provider,
|
|
9780
|
-
indexName: (
|
|
10121
|
+
indexName: (_a3 = options == null ? void 0 : options.indexName) != null ? _a3 : "default",
|
|
9781
10122
|
options: __spreadValues({}, options)
|
|
9782
10123
|
};
|
|
9783
10124
|
}
|
|
@@ -9787,7 +10128,7 @@ var ConfigBuilder = class {
|
|
|
9787
10128
|
* Configure the LLM provider for chat
|
|
9788
10129
|
*/
|
|
9789
10130
|
llm(provider, model, apiKey, options) {
|
|
9790
|
-
var
|
|
10131
|
+
var _a3, _b;
|
|
9791
10132
|
if (provider === "auto") {
|
|
9792
10133
|
this._llm = this._autoDetectLLM();
|
|
9793
10134
|
} else {
|
|
@@ -9796,7 +10137,7 @@ var ConfigBuilder = class {
|
|
|
9796
10137
|
model: model != null ? model : "default-model",
|
|
9797
10138
|
apiKey,
|
|
9798
10139
|
systemPrompt: options == null ? void 0 : options.systemPrompt,
|
|
9799
|
-
maxTokens: (
|
|
10140
|
+
maxTokens: (_a3 = options == null ? void 0 : options.maxTokens) != null ? _a3 : 1024,
|
|
9800
10141
|
temperature: (_b = options == null ? void 0 : options.temperature) != null ? _b : 0.7,
|
|
9801
10142
|
baseUrl: options == null ? void 0 : options.baseUrl,
|
|
9802
10143
|
options
|
|
@@ -9839,8 +10180,8 @@ var ConfigBuilder = class {
|
|
|
9839
10180
|
* Set RAG-specific pipeline parameters
|
|
9840
10181
|
*/
|
|
9841
10182
|
rag(options) {
|
|
9842
|
-
var
|
|
9843
|
-
this._rag = __spreadValues(__spreadValues({}, (
|
|
10183
|
+
var _a3;
|
|
10184
|
+
this._rag = __spreadValues(__spreadValues({}, (_a3 = this._rag) != null ? _a3 : {}), options);
|
|
9844
10185
|
return this;
|
|
9845
10186
|
}
|
|
9846
10187
|
/**
|
|
@@ -9856,7 +10197,7 @@ var ConfigBuilder = class {
|
|
|
9856
10197
|
* Throws if required fields (projectId, vectorDb, llm, embedding) are not set.
|
|
9857
10198
|
*/
|
|
9858
10199
|
build() {
|
|
9859
|
-
var
|
|
10200
|
+
var _a3;
|
|
9860
10201
|
const missing = [];
|
|
9861
10202
|
if (!this._projectId) missing.push('projectId (call .projectId("my-app"))');
|
|
9862
10203
|
if (!this._vectorDb) missing.push('vectorDb (call .vectorDb("pinecone", { ... }))');
|
|
@@ -9868,7 +10209,7 @@ var ConfigBuilder = class {
|
|
|
9868
10209
|
${missing.join("\n ")}`
|
|
9869
10210
|
);
|
|
9870
10211
|
}
|
|
9871
|
-
const ragConfig = (
|
|
10212
|
+
const ragConfig = (_a3 = this._rag) != null ? _a3 : { chunkSize: 1e3, chunkOverlap: 200, topK: 5 };
|
|
9872
10213
|
if (process.env.RAG_USE_GRAPH_RETRIEVAL === "true") {
|
|
9873
10214
|
ragConfig.useGraphRetrieval = true;
|
|
9874
10215
|
}
|
|
@@ -9964,8 +10305,8 @@ var DocumentParser = class {
|
|
|
9964
10305
|
* Extract text from a File or Buffer based on its type.
|
|
9965
10306
|
*/
|
|
9966
10307
|
static async parse(file, fileName, mimeType) {
|
|
9967
|
-
var
|
|
9968
|
-
const extension = ((
|
|
10308
|
+
var _a3;
|
|
10309
|
+
const extension = ((_a3 = fileName.split(".").pop()) == null ? void 0 : _a3.toLowerCase()) || "";
|
|
9969
10310
|
if (extension === "txt" || extension === "md" || mimeType === "text/plain" || mimeType === "text/markdown") {
|
|
9970
10311
|
return this.readAsText(file);
|
|
9971
10312
|
}
|
|
@@ -10072,9 +10413,9 @@ var DatabaseStorage = class {
|
|
|
10072
10413
|
this.fallbackDir = this.isServerless ? path.join(os.tmpdir(), ".retrivora") : path.join(process.cwd(), ".retrivora");
|
|
10073
10414
|
this.historyFile = path.join(this.fallbackDir, "history.json");
|
|
10074
10415
|
this.feedbackFile = path.join(this.fallbackDir, "feedback.json");
|
|
10075
|
-
var
|
|
10416
|
+
var _a3, _b, _c, _d, _e;
|
|
10076
10417
|
this.config = config;
|
|
10077
|
-
this.provider = ((
|
|
10418
|
+
this.provider = ((_a3 = config.vectorDb) == null ? void 0 : _a3.provider) || "fs";
|
|
10078
10419
|
const rawHistoryTable = ((_c = (_b = config.rag) == null ? void 0 : _b.history) == null ? void 0 : _c.tableName) || "retrivora_history";
|
|
10079
10420
|
const rawFeedbackTable = ((_e = (_d = config.rag) == null ? void 0 : _d.feedback) == null ? void 0 : _e.tableName) || "retrivora_feedback";
|
|
10080
10421
|
this.historyTableName = rawHistoryTable.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
@@ -10109,16 +10450,16 @@ var DatabaseStorage = class {
|
|
|
10109
10450
|
}
|
|
10110
10451
|
}
|
|
10111
10452
|
checkHistoryEnabled() {
|
|
10112
|
-
var
|
|
10453
|
+
var _a3, _b;
|
|
10113
10454
|
this.checkPremiumSubscription();
|
|
10114
|
-
if (((_b = (
|
|
10455
|
+
if (((_b = (_a3 = this.config.rag) == null ? void 0 : _a3.history) == null ? void 0 : _b.enabled) === false) {
|
|
10115
10456
|
throw new Error("[Retrivora SDK] Chat History is disabled in RagConfig.");
|
|
10116
10457
|
}
|
|
10117
10458
|
}
|
|
10118
10459
|
checkFeedbackEnabled() {
|
|
10119
|
-
var
|
|
10460
|
+
var _a3, _b;
|
|
10120
10461
|
this.checkPremiumSubscription();
|
|
10121
|
-
if (((_b = (
|
|
10462
|
+
if (((_b = (_a3 = this.config.rag) == null ? void 0 : _a3.feedback) == null ? void 0 : _b.enabled) === false) {
|
|
10122
10463
|
throw new Error("[Retrivora SDK] User Feedback is disabled in RagConfig.");
|
|
10123
10464
|
}
|
|
10124
10465
|
}
|
|
@@ -10285,8 +10626,11 @@ var DatabaseStorage = class {
|
|
|
10285
10626
|
this.writeLocalFile(this.historyFile, history);
|
|
10286
10627
|
}
|
|
10287
10628
|
}
|
|
10288
|
-
async getHistory(sessionId) {
|
|
10629
|
+
async getHistory(sessionId, projectIds) {
|
|
10289
10630
|
this.checkHistoryEnabled();
|
|
10631
|
+
if (projectIds && projectIds.length > 0 && !this.sessionInScope(sessionId, projectIds)) {
|
|
10632
|
+
return [];
|
|
10633
|
+
}
|
|
10290
10634
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
10291
10635
|
const pool = await this.getPGPool();
|
|
10292
10636
|
const res = await pool.query(
|
|
@@ -10316,8 +10660,11 @@ var DatabaseStorage = class {
|
|
|
10316
10660
|
return history.filter((h) => h.session_id === sessionId).sort((a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime());
|
|
10317
10661
|
}
|
|
10318
10662
|
}
|
|
10319
|
-
async clearHistory(sessionId) {
|
|
10663
|
+
async clearHistory(sessionId, projectIds) {
|
|
10320
10664
|
this.checkHistoryEnabled();
|
|
10665
|
+
if (projectIds && projectIds.length > 0 && !this.sessionInScope(sessionId, projectIds)) {
|
|
10666
|
+
return;
|
|
10667
|
+
}
|
|
10321
10668
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
10322
10669
|
const pool = await this.getPGPool();
|
|
10323
10670
|
await pool.query(`DELETE FROM ${this.historyTableName} WHERE session_id = $1`, [sessionId]);
|
|
@@ -10336,21 +10683,36 @@ var DatabaseStorage = class {
|
|
|
10336
10683
|
this.writeLocalFile(this.feedbackFile, filteredFeedback);
|
|
10337
10684
|
}
|
|
10338
10685
|
}
|
|
10339
|
-
|
|
10686
|
+
/**
|
|
10687
|
+
* Return true when `sessionId` falls into the allowed `projectIds` scope.
|
|
10688
|
+
* When `projectIds` is empty / undefined we allow the call (legacy behavior
|
|
10689
|
+
* for non-multi-tenant consumers). Session ids typically begin with the
|
|
10690
|
+
* project id they were created for, so we prefix-match as well as contains-match
|
|
10691
|
+
* to catch sharded / suffix-style ids used by some integrations.
|
|
10692
|
+
*/
|
|
10693
|
+
sessionInScope(sessionId, projectIds) {
|
|
10694
|
+
if (!projectIds || projectIds.length === 0) return true;
|
|
10695
|
+
return projectIds.some(
|
|
10696
|
+
(pid) => pid && (sessionId === pid || sessionId.startsWith(pid) || sessionId.includes(pid))
|
|
10697
|
+
);
|
|
10698
|
+
}
|
|
10699
|
+
async listSessions(projectIds) {
|
|
10340
10700
|
this.checkHistoryEnabled();
|
|
10701
|
+
let raw = [];
|
|
10341
10702
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
10342
10703
|
const pool = await this.getPGPool();
|
|
10343
10704
|
const res = await pool.query(`SELECT DISTINCT session_id FROM ${this.historyTableName}`);
|
|
10344
|
-
|
|
10705
|
+
raw = res.rows.map((r) => r.session_id);
|
|
10345
10706
|
} else if (this.provider === "mongodb") {
|
|
10346
10707
|
await this.getMongoClient();
|
|
10347
10708
|
const db = this.getMongoDb();
|
|
10348
|
-
|
|
10709
|
+
raw = await db.collection(this.historyTableName).distinct("session_id");
|
|
10349
10710
|
} else {
|
|
10350
10711
|
const history = this.readLocalFile(this.historyFile);
|
|
10351
|
-
|
|
10352
|
-
return Array.from(sessions);
|
|
10712
|
+
raw = Array.from(new Set(history.map((h) => h.session_id)));
|
|
10353
10713
|
}
|
|
10714
|
+
if (!projectIds || projectIds.length === 0) return raw;
|
|
10715
|
+
return raw.filter((sid) => this.sessionInScope(sid, projectIds));
|
|
10354
10716
|
}
|
|
10355
10717
|
// ─── Feedback Operations ──────────────────────────────────────────────────
|
|
10356
10718
|
async saveFeedback(feedback) {
|
|
@@ -10403,8 +10765,9 @@ var DatabaseStorage = class {
|
|
|
10403
10765
|
this.writeLocalFile(this.feedbackFile, list);
|
|
10404
10766
|
}
|
|
10405
10767
|
}
|
|
10406
|
-
async getFeedback(messageId) {
|
|
10768
|
+
async getFeedback(messageId, projectIds) {
|
|
10407
10769
|
this.checkFeedbackEnabled();
|
|
10770
|
+
let item = null;
|
|
10408
10771
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
10409
10772
|
const pool = await this.getPGPool();
|
|
10410
10773
|
const res = await pool.query(
|
|
@@ -10413,28 +10776,34 @@ var DatabaseStorage = class {
|
|
|
10413
10776
|
WHERE message_id = $1`,
|
|
10414
10777
|
[messageId]
|
|
10415
10778
|
);
|
|
10416
|
-
|
|
10779
|
+
item = res.rows[0] || null;
|
|
10417
10780
|
} else if (this.provider === "mongodb") {
|
|
10418
10781
|
await this.getMongoClient();
|
|
10419
10782
|
const db = this.getMongoDb();
|
|
10420
10783
|
const col = db.collection(this.feedbackTableName);
|
|
10421
|
-
const
|
|
10422
|
-
if (
|
|
10423
|
-
|
|
10424
|
-
|
|
10425
|
-
|
|
10426
|
-
|
|
10427
|
-
|
|
10428
|
-
|
|
10429
|
-
|
|
10430
|
-
|
|
10784
|
+
const raw = await col.findOne({ message_id: messageId });
|
|
10785
|
+
if (raw) {
|
|
10786
|
+
item = {
|
|
10787
|
+
id: raw.id,
|
|
10788
|
+
messageId: raw.message_id,
|
|
10789
|
+
sessionId: raw.session_id,
|
|
10790
|
+
rating: raw.rating,
|
|
10791
|
+
comment: raw.comment,
|
|
10792
|
+
createdAt: raw.created_at
|
|
10793
|
+
};
|
|
10794
|
+
}
|
|
10431
10795
|
} else {
|
|
10432
10796
|
const list = this.readLocalFile(this.feedbackFile);
|
|
10433
|
-
|
|
10797
|
+
item = list.find((f) => f.message_id === messageId) || null;
|
|
10434
10798
|
}
|
|
10799
|
+
if (item && projectIds && projectIds.length > 0) {
|
|
10800
|
+
return this.sessionInScope(item.sessionId, projectIds) ? item : null;
|
|
10801
|
+
}
|
|
10802
|
+
return item;
|
|
10435
10803
|
}
|
|
10436
|
-
async listFeedback() {
|
|
10804
|
+
async listFeedback(projectIds) {
|
|
10437
10805
|
this.checkFeedbackEnabled();
|
|
10806
|
+
let raw = [];
|
|
10438
10807
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
10439
10808
|
const pool = await this.getPGPool();
|
|
10440
10809
|
const res = await pool.query(
|
|
@@ -10442,13 +10811,13 @@ var DatabaseStorage = class {
|
|
|
10442
10811
|
FROM ${this.feedbackTableName}
|
|
10443
10812
|
ORDER BY created_at DESC`
|
|
10444
10813
|
);
|
|
10445
|
-
|
|
10814
|
+
raw = res.rows;
|
|
10446
10815
|
} else if (this.provider === "mongodb") {
|
|
10447
10816
|
await this.getMongoClient();
|
|
10448
10817
|
const db = this.getMongoDb();
|
|
10449
10818
|
const col = db.collection(this.feedbackTableName);
|
|
10450
10819
|
const items = await col.find({}).sort({ created_at: -1 }).toArray();
|
|
10451
|
-
|
|
10820
|
+
raw = items.map((item) => ({
|
|
10452
10821
|
id: item.id,
|
|
10453
10822
|
messageId: item.message_id,
|
|
10454
10823
|
sessionId: item.session_id,
|
|
@@ -10458,8 +10827,10 @@ var DatabaseStorage = class {
|
|
|
10458
10827
|
}));
|
|
10459
10828
|
} else {
|
|
10460
10829
|
const list = this.readLocalFile(this.feedbackFile);
|
|
10461
|
-
|
|
10830
|
+
raw = [...list].sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime());
|
|
10462
10831
|
}
|
|
10832
|
+
if (!projectIds || projectIds.length === 0) return raw;
|
|
10833
|
+
return raw.filter((f) => this.sessionInScope(f.sessionId, projectIds));
|
|
10463
10834
|
}
|
|
10464
10835
|
async disconnect() {
|
|
10465
10836
|
if (this.pgPool) {
|
|
@@ -10522,8 +10893,8 @@ var _g = global;
|
|
|
10522
10893
|
var _a;
|
|
10523
10894
|
var rateLimiter = (_a = _g.__retrivoraRateLimiter) != null ? _a : _g.__retrivoraRateLimiter = new RateLimiter(6e4, 30);
|
|
10524
10895
|
function getRateLimitKey(req) {
|
|
10525
|
-
var
|
|
10526
|
-
const ip = ((_b = (
|
|
10896
|
+
var _a3, _b;
|
|
10897
|
+
const ip = ((_b = (_a3 = req.headers.get("x-forwarded-for")) == null ? void 0 : _a3.split(",")[0]) == null ? void 0 : _b.trim()) || req.headers.get("x-real-ip") || "127.0.0.1";
|
|
10527
10898
|
return `ip:${ip}`;
|
|
10528
10899
|
}
|
|
10529
10900
|
function checkRateLimit(req) {
|
|
@@ -10545,6 +10916,66 @@ function checkRateLimit(req) {
|
|
|
10545
10916
|
}
|
|
10546
10917
|
return null;
|
|
10547
10918
|
}
|
|
10919
|
+
var FREE_TIER_NAMES = /* @__PURE__ */ new Set(["hobby", "free", "free_trial", "trial"]);
|
|
10920
|
+
function isFreeTier(tier) {
|
|
10921
|
+
if (!tier) return true;
|
|
10922
|
+
return FREE_TIER_NAMES.has(tier.toLowerCase().trim());
|
|
10923
|
+
}
|
|
10924
|
+
var _a2;
|
|
10925
|
+
var _freeTierGuardInstance = (_a2 = _g.__retrivoraFreeTierGuard) != null ? _a2 : _g.__retrivoraFreeTierGuard = new FreeTierLimitsGuard();
|
|
10926
|
+
function createPaymentRequiredResponse(reason, details) {
|
|
10927
|
+
const body = __spreadProps(__spreadValues({
|
|
10928
|
+
type: "https://retrivora.com/docs/errors/payment-required",
|
|
10929
|
+
title: "Payment Required",
|
|
10930
|
+
status: 402,
|
|
10931
|
+
detail: reason,
|
|
10932
|
+
code: "FREE_TIER_LIMIT_EXCEEDED",
|
|
10933
|
+
instance: void 0
|
|
10934
|
+
}, details != null ? details : {}), {
|
|
10935
|
+
quota: {
|
|
10936
|
+
maxDailyRequestUnits: FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS,
|
|
10937
|
+
maxTrialRequestUnits: FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS,
|
|
10938
|
+
maxDocuments: FREE_TIER_QUOTAS.MAX_DOCUMENTS,
|
|
10939
|
+
maxStorageBytes: FREE_TIER_QUOTAS.MAX_STORAGE_BYTES,
|
|
10940
|
+
upgradeUrl: "https://retrivora.com/pricing"
|
|
10941
|
+
}
|
|
10942
|
+
});
|
|
10943
|
+
return new Response(JSON.stringify(body), {
|
|
10944
|
+
status: 402,
|
|
10945
|
+
headers: {
|
|
10946
|
+
"Content-Type": "application/problem+json"
|
|
10947
|
+
}
|
|
10948
|
+
});
|
|
10949
|
+
}
|
|
10950
|
+
function resolveLicenseKey(req, config, bodyLicenseKey) {
|
|
10951
|
+
var _a3;
|
|
10952
|
+
return req.headers.get("x-license-key") || bodyLicenseKey || ((_a3 = req.headers.get("authorization")) == null ? void 0 : _a3.replace(/^Bearer\s+/i, "")) || config.licenseKey || process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY || process.env.RETRIVORA_LICENSE_KEY || process.env.RAG_LICENSE_KEY || "";
|
|
10953
|
+
}
|
|
10954
|
+
function enforceLicense(req, config, bodyLicenseKey) {
|
|
10955
|
+
const rawKey = resolveLicenseKey(req, config, bodyLicenseKey);
|
|
10956
|
+
const licenseKey = (rawKey || "").trim().replace(/^["']|["']$/g, "").trim();
|
|
10957
|
+
const projectId = config.projectId || "my-rag-app";
|
|
10958
|
+
try {
|
|
10959
|
+
const payload = LicenseVerifier.verify(licenseKey, projectId);
|
|
10960
|
+
return { ok: true, payload };
|
|
10961
|
+
} catch (err) {
|
|
10962
|
+
const message = err instanceof Error ? err.message : "Missing or invalid RETRIVORA_LICENSE_KEY. Set NEXT_PUBLIC_RETRIVORA_LICENSE_KEY in your environment or contact your administrator.";
|
|
10963
|
+
const body = {
|
|
10964
|
+
error: {
|
|
10965
|
+
code: "LICENSE_REVOKED",
|
|
10966
|
+
message: "Your Retrivora license key has been terminated, suspended, or revoked. Access denied."
|
|
10967
|
+
},
|
|
10968
|
+
details: message
|
|
10969
|
+
};
|
|
10970
|
+
return {
|
|
10971
|
+
ok: false,
|
|
10972
|
+
response: new Response(JSON.stringify(body), {
|
|
10973
|
+
status: 403,
|
|
10974
|
+
headers: { "Content-Type": "application/json" }
|
|
10975
|
+
})
|
|
10976
|
+
};
|
|
10977
|
+
}
|
|
10978
|
+
}
|
|
10548
10979
|
var MAX_MESSAGE_LENGTH = 8e3;
|
|
10549
10980
|
function sanitizeInput(raw) {
|
|
10550
10981
|
const stripped = raw.replace(/[\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F-\u009F]/g, "");
|
|
@@ -10566,7 +10997,7 @@ function getOrCreatePlugin(configOrPlugin) {
|
|
|
10566
10997
|
return _g[cacheKey];
|
|
10567
10998
|
}
|
|
10568
10999
|
function reportTelemetry(req, plugin, action, status, details, trace) {
|
|
10569
|
-
var
|
|
11000
|
+
var _a3, _b, _c, _d, _e, _f, _g2;
|
|
10570
11001
|
try {
|
|
10571
11002
|
const config = plugin.getConfig();
|
|
10572
11003
|
const licenseKey = config.licenseKey || process.env.RAG_LICENSE_KEY || process.env.RETRIVORA_LICENSE_KEY || process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY;
|
|
@@ -10581,7 +11012,7 @@ function reportTelemetry(req, plugin, action, status, details, trace) {
|
|
|
10581
11012
|
absoluteUrl = `${proto}://${host}${telemetryUrl}`;
|
|
10582
11013
|
}
|
|
10583
11014
|
const projectId = config.projectId || "default";
|
|
10584
|
-
const model = (trace == null ? void 0 : trace.model) || ((
|
|
11015
|
+
const model = (trace == null ? void 0 : trace.model) || ((_a3 = config.llm) == null ? void 0 : _a3.model) || ((_b = config.embedding) == null ? void 0 : _b.model) || "llama-3.1-8b-instant";
|
|
10585
11016
|
const provider = (trace == null ? void 0 : trace.provider) || ((_c = config.llm) == null ? void 0 : _c.provider) || ((_d = config.embedding) == null ? void 0 : _d.provider) || "groq";
|
|
10586
11017
|
const tokens = Number(((_e = trace == null ? void 0 : trace.tokens) == null ? void 0 : _e.totalTokens) || (trace == null ? void 0 : trace.totalTokens) || 0);
|
|
10587
11018
|
const costUsd = Number(((_f = trace == null ? void 0 : trace.tokens) == null ? void 0 : _f.estimatedCostUsd) || (trace == null ? void 0 : trace.costUsd) || 0);
|
|
@@ -10605,7 +11036,6 @@ function reportTelemetry(req, plugin, action, status, details, trace) {
|
|
|
10605
11036
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
10606
11037
|
details
|
|
10607
11038
|
};
|
|
10608
|
-
console.log(`[Retrivora SDK Telemetry] Dispatching telemetry -> Feature: "${action}", Status: "${status}", Project: "${projectId}", Latency: ${latencyMs}ms`);
|
|
10609
11039
|
fetch(absoluteUrl, {
|
|
10610
11040
|
method: "POST",
|
|
10611
11041
|
headers: {
|
|
@@ -10663,14 +11093,39 @@ function createChatHandler(configOrPlugin, options) {
|
|
|
10663
11093
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
10664
11094
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
10665
11095
|
return async function POST(req, context) {
|
|
10666
|
-
var
|
|
11096
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
10667
11097
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10668
11098
|
if (authResult) return authResult;
|
|
10669
11099
|
const rateLimited = checkRateLimit(req);
|
|
10670
11100
|
if (rateLimited) return rateLimited;
|
|
11101
|
+
const config = plugin.getConfig();
|
|
10671
11102
|
try {
|
|
10672
11103
|
const body = await req.json();
|
|
10673
11104
|
const bodyObj = body != null ? body : {};
|
|
11105
|
+
const licenseCheck = enforceLicense(req, config, bodyObj == null ? void 0 : bodyObj.licenseKey);
|
|
11106
|
+
if (!licenseCheck.ok) return licenseCheck.response;
|
|
11107
|
+
if (isFreeTier(licenseCheck.payload.tier)) {
|
|
11108
|
+
const estimatedInputTokens = Math.ceil(
|
|
11109
|
+
((((_a3 = bodyObj.message) == null ? void 0 : _a3.length) || 0) + (Array.isArray(bodyObj.messages) ? bodyObj.messages.reduce((a, m) => {
|
|
11110
|
+
var _a4, _b2;
|
|
11111
|
+
return a + (((_a4 = m == null ? void 0 : m.content) == null ? void 0 : _a4.length) || ((_b2 = m == null ? void 0 : m.text) == null ? void 0 : _b2.length) || 0);
|
|
11112
|
+
}, 0) : 0) + (((_b = bodyObj.history) == null ? void 0 : _b.reduce((a, m) => {
|
|
11113
|
+
var _a4, _b2;
|
|
11114
|
+
return a + (((_a4 = m == null ? void 0 : m.content) == null ? void 0 : _a4.length) || ((_b2 = m == null ? void 0 : m.text) == null ? void 0 : _b2.length) || 0);
|
|
11115
|
+
}, 0)) || 0)) / 4
|
|
11116
|
+
);
|
|
11117
|
+
const chatCheck = FreeTierLimitsGuard.checkRequestAllowed({
|
|
11118
|
+
operationType: "chat",
|
|
11119
|
+
inputTokens: estimatedInputTokens,
|
|
11120
|
+
projectId: licenseCheck.payload.projectId
|
|
11121
|
+
});
|
|
11122
|
+
if (!chatCheck.allowed) {
|
|
11123
|
+
return createPaymentRequiredResponse(
|
|
11124
|
+
chatCheck.reason || "Free tier quota exceeded.",
|
|
11125
|
+
{ tier: licenseCheck.payload.tier, projectId: licenseCheck.payload.projectId }
|
|
11126
|
+
);
|
|
11127
|
+
}
|
|
11128
|
+
}
|
|
10674
11129
|
let rawMessage = bodyObj.message;
|
|
10675
11130
|
if (!rawMessage && Array.isArray(bodyObj.messages) && bodyObj.messages.length > 0) {
|
|
10676
11131
|
const lastMsg = bodyObj.messages[bodyObj.messages.length - 1];
|
|
@@ -10702,7 +11157,7 @@ function createChatHandler(configOrPlugin, options) {
|
|
|
10702
11157
|
uiTransformation: result.ui_transformation,
|
|
10703
11158
|
trace: result.trace
|
|
10704
11159
|
}).catch((err) => console.warn("[createChatHandler] Failed to save assistant message:", err));
|
|
10705
|
-
reportTelemetry(req, plugin, "QUERY_GENERATION", "success", `Tokens: ${((
|
|
11160
|
+
reportTelemetry(req, plugin, "QUERY_GENERATION", "success", `Tokens: ${((_d = (_c = result.trace) == null ? void 0 : _c.tokens) == null ? void 0 : _d.totalTokens) || 0}, Latency: ${((_f = (_e = result.trace) == null ? void 0 : _e.latency) == null ? void 0 : _f.totalMs) || 0}ms`, result.trace);
|
|
10706
11161
|
return NextResponse.json(__spreadProps(__spreadValues({}, result), {
|
|
10707
11162
|
messageId: assistantMsgId,
|
|
10708
11163
|
userMessageId: userMsgId
|
|
@@ -10719,14 +11174,15 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10719
11174
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
10720
11175
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
10721
11176
|
return async function POST(req, context) {
|
|
10722
|
-
var
|
|
11177
|
+
var _a3, _b, _c;
|
|
10723
11178
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10724
11179
|
if (authResult) return authResult;
|
|
10725
11180
|
const rateLimited = checkRateLimit(req);
|
|
10726
11181
|
if (rateLimited) return rateLimited;
|
|
11182
|
+
const config = plugin.getConfig();
|
|
10727
11183
|
let body;
|
|
10728
11184
|
try {
|
|
10729
|
-
if ((
|
|
11185
|
+
if ((_a3 = req.headers.get("content-type")) == null ? void 0 : _a3.includes("multipart/form-data")) {
|
|
10730
11186
|
const uploader = createUploadHandler(plugin, { onAuthorize });
|
|
10731
11187
|
return uploader(req);
|
|
10732
11188
|
}
|
|
@@ -10738,6 +11194,30 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10738
11194
|
});
|
|
10739
11195
|
}
|
|
10740
11196
|
const bodyObj = body != null ? body : {};
|
|
11197
|
+
const licenseCheck = enforceLicense(req, config, bodyObj == null ? void 0 : bodyObj.licenseKey);
|
|
11198
|
+
if (!licenseCheck.ok) return licenseCheck.response;
|
|
11199
|
+
if (isFreeTier(licenseCheck.payload.tier)) {
|
|
11200
|
+
const estimatedInputTokens = Math.ceil(
|
|
11201
|
+
((((_b = bodyObj.message) == null ? void 0 : _b.length) || 0) + (Array.isArray(bodyObj.messages) ? bodyObj.messages.reduce((a, m) => {
|
|
11202
|
+
var _a4, _b2;
|
|
11203
|
+
return a + (((_a4 = m == null ? void 0 : m.content) == null ? void 0 : _a4.length) || ((_b2 = m == null ? void 0 : m.text) == null ? void 0 : _b2.length) || 0);
|
|
11204
|
+
}, 0) : 0) + (((_c = bodyObj.history) == null ? void 0 : _c.reduce((a, m) => {
|
|
11205
|
+
var _a4, _b2;
|
|
11206
|
+
return a + (((_a4 = m == null ? void 0 : m.content) == null ? void 0 : _a4.length) || ((_b2 = m == null ? void 0 : m.text) == null ? void 0 : _b2.length) || 0);
|
|
11207
|
+
}, 0)) || 0)) / 4
|
|
11208
|
+
);
|
|
11209
|
+
const chatCheck = FreeTierLimitsGuard.checkRequestAllowed({
|
|
11210
|
+
operationType: "chat_stream",
|
|
11211
|
+
inputTokens: estimatedInputTokens,
|
|
11212
|
+
projectId: licenseCheck.payload.projectId
|
|
11213
|
+
});
|
|
11214
|
+
if (!chatCheck.allowed) {
|
|
11215
|
+
return createPaymentRequiredResponse(
|
|
11216
|
+
chatCheck.reason || "Free tier quota exceeded.",
|
|
11217
|
+
{ tier: licenseCheck.payload.tier, projectId: licenseCheck.payload.projectId }
|
|
11218
|
+
);
|
|
11219
|
+
}
|
|
11220
|
+
}
|
|
10741
11221
|
let rawMessage = bodyObj.message;
|
|
10742
11222
|
if (!rawMessage && Array.isArray(bodyObj.messages) && bodyObj.messages.length > 0) {
|
|
10743
11223
|
const lastMsg = bodyObj.messages[bodyObj.messages.length - 1];
|
|
@@ -10767,7 +11247,7 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10767
11247
|
let isActive = true;
|
|
10768
11248
|
const stream = new ReadableStream({
|
|
10769
11249
|
async start(controller) {
|
|
10770
|
-
var
|
|
11250
|
+
var _a4, _b2, _c2, _d, _e;
|
|
10771
11251
|
const enqueue = (text) => {
|
|
10772
11252
|
if (!isActive) return;
|
|
10773
11253
|
try {
|
|
@@ -10800,7 +11280,7 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10800
11280
|
let uiTransformation = responseChunk == null ? void 0 : responseChunk.ui_transformation;
|
|
10801
11281
|
if (sources.length > 0) {
|
|
10802
11282
|
try {
|
|
10803
|
-
uiTransformation = (
|
|
11283
|
+
uiTransformation = (_a4 = responseChunk == null ? void 0 : responseChunk.ui_transformation) != null ? _a4 : UITransformer.transform(message, sources, plugin.getConfig());
|
|
10804
11284
|
if (uiTransformation) {
|
|
10805
11285
|
enqueue(sseUIFrame(uiTransformation));
|
|
10806
11286
|
}
|
|
@@ -10824,7 +11304,7 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10824
11304
|
uiTransformation,
|
|
10825
11305
|
trace: responseChunk == null ? void 0 : responseChunk.trace
|
|
10826
11306
|
}).catch((err) => console.warn("[createStreamHandler] Failed to save assistant message:", err));
|
|
10827
|
-
reportTelemetry(req, plugin, "QUERY_GENERATION", "success", `Tokens: ${((
|
|
11307
|
+
reportTelemetry(req, plugin, "QUERY_GENERATION", "success", `Tokens: ${((_c2 = (_b2 = responseChunk == null ? void 0 : responseChunk.trace) == null ? void 0 : _b2.tokens) == null ? void 0 : _c2.totalTokens) || 0}, Latency: ${((_e = (_d = responseChunk == null ? void 0 : responseChunk.trace) == null ? void 0 : _d.latency) == null ? void 0 : _e.totalMs) || 0}ms`, responseChunk == null ? void 0 : responseChunk.trace);
|
|
10828
11308
|
}
|
|
10829
11309
|
}
|
|
10830
11310
|
} catch (temp) {
|
|
@@ -10874,12 +11354,36 @@ function createIngestHandler(configOrPlugin, options) {
|
|
|
10874
11354
|
return async function POST(req, context) {
|
|
10875
11355
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10876
11356
|
if (authResult) return authResult;
|
|
11357
|
+
const config = plugin.getConfig();
|
|
10877
11358
|
try {
|
|
10878
11359
|
const body = await req.json();
|
|
11360
|
+
const licenseCheck = enforceLicense(req, config, body == null ? void 0 : body.licenseKey);
|
|
11361
|
+
if (!licenseCheck.ok) return licenseCheck.response;
|
|
10879
11362
|
const { documents, namespace } = body;
|
|
10880
11363
|
if (!Array.isArray(documents) || documents.length === 0) {
|
|
10881
11364
|
return NextResponse.json({ error: "documents array is required" }, { status: 400 });
|
|
10882
11365
|
}
|
|
11366
|
+
if (isFreeTier(licenseCheck.payload.tier)) {
|
|
11367
|
+
const totalIncomingBytes = documents.reduce(
|
|
11368
|
+
(sum, d) => sum + Buffer.byteLength(d.content || "", "utf8"),
|
|
11369
|
+
0
|
|
11370
|
+
);
|
|
11371
|
+
const ingestCheck = FreeTierLimitsGuard.checkIngestionAllowed(
|
|
11372
|
+
{ documentCount: documents.length },
|
|
11373
|
+
totalIncomingBytes
|
|
11374
|
+
);
|
|
11375
|
+
if (!ingestCheck.allowed) {
|
|
11376
|
+
return createPaymentRequiredResponse(
|
|
11377
|
+
ingestCheck.reason || "Free tier ingestion limit reached.",
|
|
11378
|
+
{
|
|
11379
|
+
tier: licenseCheck.payload.tier,
|
|
11380
|
+
projectId: licenseCheck.payload.projectId,
|
|
11381
|
+
documents: documents.length,
|
|
11382
|
+
incomingBytes: totalIncomingBytes
|
|
11383
|
+
}
|
|
11384
|
+
);
|
|
11385
|
+
}
|
|
11386
|
+
}
|
|
10883
11387
|
const results = await plugin.ingest(documents, namespace);
|
|
10884
11388
|
reportTelemetry(req, plugin, "DOCUMENT_INGESTION", "success", `Ingested ${documents.length} document(s)`);
|
|
10885
11389
|
return NextResponse.json({ results });
|
|
@@ -10916,7 +11420,7 @@ function createLicenseHandler(configOrPlugin, options) {
|
|
|
10916
11420
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
10917
11421
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
10918
11422
|
return async function POST(req) {
|
|
10919
|
-
var
|
|
11423
|
+
var _a3;
|
|
10920
11424
|
if (req) {
|
|
10921
11425
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10922
11426
|
if (authResult) return authResult;
|
|
@@ -10924,7 +11428,8 @@ function createLicenseHandler(configOrPlugin, options) {
|
|
|
10924
11428
|
try {
|
|
10925
11429
|
const body = await req.json().catch(() => ({}));
|
|
10926
11430
|
const config = plugin.getConfig();
|
|
10927
|
-
const
|
|
11431
|
+
const rawKey = req.headers.get("x-license-key") || (body == null ? void 0 : body.licenseKey) || ((_a3 = req.headers.get("authorization")) == null ? void 0 : _a3.replace(/^Bearer\s+/i, "")) || config.licenseKey || process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY || process.env.RETRIVORA_LICENSE_KEY || "";
|
|
11432
|
+
const licenseKey = (rawKey || "").trim().replace(/^["']|["']$/g, "").trim();
|
|
10928
11433
|
const projectId = (body == null ? void 0 : body.projectId) || config.projectId || "my-rag-app";
|
|
10929
11434
|
const payload = LicenseVerifier.verify(licenseKey, projectId);
|
|
10930
11435
|
return NextResponse.json({
|
|
@@ -10958,6 +11463,9 @@ function createUploadHandler(configOrPlugin, options) {
|
|
|
10958
11463
|
return async function POST(req, context) {
|
|
10959
11464
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10960
11465
|
if (authResult) return authResult;
|
|
11466
|
+
const config = plugin.getConfig();
|
|
11467
|
+
const licenseCheck = enforceLicense(req, config);
|
|
11468
|
+
if (!licenseCheck.ok) return licenseCheck.response;
|
|
10961
11469
|
try {
|
|
10962
11470
|
const formData = await req.formData();
|
|
10963
11471
|
const files = formData.getAll("files");
|
|
@@ -10967,6 +11475,26 @@ function createUploadHandler(configOrPlugin, options) {
|
|
|
10967
11475
|
if (!files || files.length === 0) {
|
|
10968
11476
|
return NextResponse.json({ error: "No files provided" }, { status: 400 });
|
|
10969
11477
|
}
|
|
11478
|
+
if (isFreeTier(licenseCheck.payload.tier)) {
|
|
11479
|
+
const totalUploadBytes = files.reduce((sum, f) => sum + (f.size || 0), 0);
|
|
11480
|
+
const uploadCheck = FreeTierLimitsGuard.checkIngestionAllowed(
|
|
11481
|
+
{ documentCount: files.length },
|
|
11482
|
+
totalUploadBytes
|
|
11483
|
+
);
|
|
11484
|
+
if (!uploadCheck.allowed) {
|
|
11485
|
+
return createPaymentRequiredResponse(
|
|
11486
|
+
uploadCheck.reason || "Free tier upload limit reached.",
|
|
11487
|
+
{
|
|
11488
|
+
tier: licenseCheck.payload.tier,
|
|
11489
|
+
projectId: licenseCheck.payload.projectId,
|
|
11490
|
+
fileCount: files.length,
|
|
11491
|
+
totalUploadBytes,
|
|
11492
|
+
maxFileSizeBytes: FREE_TIER_QUOTAS.MAX_FILE_SIZE_BYTES,
|
|
11493
|
+
maxStorageBytes: FREE_TIER_QUOTAS.MAX_STORAGE_BYTES
|
|
11494
|
+
}
|
|
11495
|
+
);
|
|
11496
|
+
}
|
|
11497
|
+
}
|
|
10970
11498
|
const documents = [];
|
|
10971
11499
|
for (const file of files) {
|
|
10972
11500
|
const isExcel = file.name.toLowerCase().endsWith(".xlsx") || file.name.toLowerCase().endsWith(".xls") || file.type.includes("spreadsheet") || file.type.includes("excel");
|
|
@@ -11076,13 +11604,22 @@ function createSuggestionsHandler(configOrPlugin, options) {
|
|
|
11076
11604
|
return async function handler(req) {
|
|
11077
11605
|
const authResult = await checkAuth(req, onAuthorize);
|
|
11078
11606
|
if (authResult) return authResult;
|
|
11607
|
+
const config = plugin.getConfig();
|
|
11608
|
+
const licenseCheck = enforceLicense(req, config);
|
|
11609
|
+
if (!licenseCheck.ok) return licenseCheck.response;
|
|
11079
11610
|
try {
|
|
11080
11611
|
let query = "";
|
|
11081
11612
|
let namespace = void 0;
|
|
11613
|
+
let bodyLicenseKey = void 0;
|
|
11082
11614
|
if (req.method === "POST") {
|
|
11083
11615
|
const body = await req.json().catch(() => ({}));
|
|
11084
11616
|
query = body.query || "";
|
|
11085
11617
|
namespace = body.namespace;
|
|
11618
|
+
bodyLicenseKey = body.licenseKey;
|
|
11619
|
+
if (bodyLicenseKey) {
|
|
11620
|
+
const recheck = enforceLicense(req, config, bodyLicenseKey);
|
|
11621
|
+
if (!recheck.ok) return recheck.response;
|
|
11622
|
+
}
|
|
11086
11623
|
} else {
|
|
11087
11624
|
const url = new URL(req.url);
|
|
11088
11625
|
query = url.searchParams.get("query") || "";
|
|
@@ -11105,14 +11642,16 @@ function createHistoryHandler(configOrPlugin, options) {
|
|
|
11105
11642
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
11106
11643
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
11107
11644
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
11645
|
+
const onResolveScope = options == null ? void 0 : options.onResolveScope;
|
|
11108
11646
|
return async function handler(req) {
|
|
11109
11647
|
const authResult = await checkAuth(req, onAuthorize);
|
|
11110
11648
|
if (authResult) return authResult;
|
|
11649
|
+
const scope = onResolveScope ? await onResolveScope(req) : void 0;
|
|
11111
11650
|
const url = new URL(req.url);
|
|
11112
11651
|
const sessionId = url.searchParams.get("sessionId") || "default";
|
|
11113
11652
|
if (req.method === "GET") {
|
|
11114
11653
|
try {
|
|
11115
|
-
const history = await storage.getHistory(sessionId);
|
|
11654
|
+
const history = await storage.getHistory(sessionId, scope);
|
|
11116
11655
|
return NextResponse.json({ history });
|
|
11117
11656
|
} catch (err) {
|
|
11118
11657
|
const message = err instanceof Error ? err.message : "Failed to fetch history";
|
|
@@ -11122,7 +11661,7 @@ function createHistoryHandler(configOrPlugin, options) {
|
|
|
11122
11661
|
try {
|
|
11123
11662
|
const body = await req.json().catch(() => ({}));
|
|
11124
11663
|
const sid = body.sessionId || sessionId;
|
|
11125
|
-
await storage.clearHistory(sid);
|
|
11664
|
+
await storage.clearHistory(sid, scope);
|
|
11126
11665
|
return NextResponse.json({ success: true });
|
|
11127
11666
|
} catch (err) {
|
|
11128
11667
|
const message = err instanceof Error ? err.message : "Failed to clear history";
|
|
@@ -11136,18 +11675,20 @@ function createFeedbackHandler(configOrPlugin, options) {
|
|
|
11136
11675
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
11137
11676
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
11138
11677
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
11678
|
+
const onResolveScope = options == null ? void 0 : options.onResolveScope;
|
|
11139
11679
|
return async function handler(req) {
|
|
11140
11680
|
const authResult = await checkAuth(req, onAuthorize);
|
|
11141
11681
|
if (authResult) return authResult;
|
|
11682
|
+
const scope = onResolveScope ? await onResolveScope(req) : void 0;
|
|
11142
11683
|
if (req.method === "GET") {
|
|
11143
11684
|
try {
|
|
11144
11685
|
const url = new URL(req.url);
|
|
11145
11686
|
const messageId = url.searchParams.get("messageId");
|
|
11146
11687
|
if (!messageId) {
|
|
11147
|
-
const feedbackList = await storage.listFeedback();
|
|
11688
|
+
const feedbackList = await storage.listFeedback(scope);
|
|
11148
11689
|
return NextResponse.json({ feedback: feedbackList });
|
|
11149
11690
|
}
|
|
11150
|
-
const feedback = await storage.getFeedback(messageId);
|
|
11691
|
+
const feedback = await storage.getFeedback(messageId, scope);
|
|
11151
11692
|
return NextResponse.json({ feedback });
|
|
11152
11693
|
} catch (err) {
|
|
11153
11694
|
const message = err instanceof Error ? err.message : "Failed to fetch feedback";
|
|
@@ -11163,6 +11704,17 @@ function createFeedbackHandler(configOrPlugin, options) {
|
|
|
11163
11704
|
if (!rating) {
|
|
11164
11705
|
return NextResponse.json({ error: "rating is required" }, { status: 400 });
|
|
11165
11706
|
}
|
|
11707
|
+
if (scope && scope.length > 0) {
|
|
11708
|
+
const matches = scope.some(
|
|
11709
|
+
(pid) => pid && (sessionId === pid || sessionId.startsWith(pid) || sessionId.includes(pid))
|
|
11710
|
+
);
|
|
11711
|
+
if (!matches) {
|
|
11712
|
+
return NextResponse.json(
|
|
11713
|
+
{ error: "sessionId is outside the authorized project scope" },
|
|
11714
|
+
{ status: 403 }
|
|
11715
|
+
);
|
|
11716
|
+
}
|
|
11717
|
+
}
|
|
11166
11718
|
await storage.saveFeedback({ messageId, sessionId, rating, comment });
|
|
11167
11719
|
return NextResponse.json({ success: true });
|
|
11168
11720
|
} catch (err) {
|
|
@@ -11177,14 +11729,15 @@ function createSessionsHandler(configOrPlugin, options) {
|
|
|
11177
11729
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
11178
11730
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
11179
11731
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
11732
|
+
const onResolveScope = options == null ? void 0 : options.onResolveScope;
|
|
11180
11733
|
return async function GET(req) {
|
|
11181
11734
|
if (req) {
|
|
11182
11735
|
const authResult = await checkAuth(req, onAuthorize);
|
|
11183
11736
|
if (authResult) return authResult;
|
|
11184
11737
|
}
|
|
11185
|
-
void req;
|
|
11186
11738
|
try {
|
|
11187
|
-
const
|
|
11739
|
+
const scope = req && onResolveScope ? await onResolveScope(req) : void 0;
|
|
11740
|
+
const sessions = await storage.listSessions(scope);
|
|
11188
11741
|
return NextResponse.json({ sessions });
|
|
11189
11742
|
} catch (err) {
|
|
11190
11743
|
const message = err instanceof Error ? err.message : "Failed to list sessions";
|
|
@@ -11195,15 +11748,17 @@ function createSessionsHandler(configOrPlugin, options) {
|
|
|
11195
11748
|
function createRagHandler(configOrPlugin, options) {
|
|
11196
11749
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
11197
11750
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
11198
|
-
const
|
|
11199
|
-
const
|
|
11200
|
-
const
|
|
11201
|
-
const
|
|
11202
|
-
const
|
|
11203
|
-
const
|
|
11204
|
-
const
|
|
11205
|
-
const
|
|
11206
|
-
const
|
|
11751
|
+
const onResolveScope = options == null ? void 0 : options.onResolveScope;
|
|
11752
|
+
const scopeableOptions = { onAuthorize, onResolveScope };
|
|
11753
|
+
const chatHandler = createChatHandler(plugin, scopeableOptions);
|
|
11754
|
+
const streamHandler = createStreamHandler(plugin, scopeableOptions);
|
|
11755
|
+
const uploadHandler = createUploadHandler(plugin, scopeableOptions);
|
|
11756
|
+
const healthHandler = createHealthHandler(plugin, scopeableOptions);
|
|
11757
|
+
const suggestionsHandler = createSuggestionsHandler(plugin, scopeableOptions);
|
|
11758
|
+
const historyHandler = createHistoryHandler(plugin, scopeableOptions);
|
|
11759
|
+
const feedbackHandler = createFeedbackHandler(plugin, scopeableOptions);
|
|
11760
|
+
const sessionsHandler = createSessionsHandler(plugin, scopeableOptions);
|
|
11761
|
+
const licenseHandler = createLicenseHandler(plugin, scopeableOptions);
|
|
11207
11762
|
async function routePostRequest(req, segment) {
|
|
11208
11763
|
switch (segment) {
|
|
11209
11764
|
case "chat":
|
|
@@ -11245,7 +11800,7 @@ function createRagHandler(configOrPlugin, options) {
|
|
|
11245
11800
|
}
|
|
11246
11801
|
}
|
|
11247
11802
|
async function getSegment(req, context) {
|
|
11248
|
-
var
|
|
11803
|
+
var _a3, _b;
|
|
11249
11804
|
const contentType = req.headers.get("content-type") || "";
|
|
11250
11805
|
if (contentType.includes("multipart/form-data")) {
|
|
11251
11806
|
return "upload";
|
|
@@ -11262,7 +11817,7 @@ function createRagHandler(configOrPlugin, options) {
|
|
|
11262
11817
|
if (pathname.endsWith("/history")) return "history";
|
|
11263
11818
|
} catch (e) {
|
|
11264
11819
|
}
|
|
11265
|
-
const resolvedParams = typeof ((
|
|
11820
|
+
const resolvedParams = typeof ((_a3 = context == null ? void 0 : context.params) == null ? void 0 : _a3.then) === "function" ? await context.params : context == null ? void 0 : context.params;
|
|
11266
11821
|
const segments = (resolvedParams == null ? void 0 : resolvedParams.retrivora) || ((_b = resolvedParams == null ? void 0 : resolvedParams.params) == null ? void 0 : _b.retrivora) || [];
|
|
11267
11822
|
const joined = segments.join("/");
|
|
11268
11823
|
return joined || "chat";
|
|
@@ -11295,6 +11850,7 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
11295
11850
|
constructor() {
|
|
11296
11851
|
this.cache = /* @__PURE__ */ new Map();
|
|
11297
11852
|
}
|
|
11853
|
+
/** @returns Singleton instance of the validator (shared cache across all consumers). */
|
|
11298
11854
|
static getInstance() {
|
|
11299
11855
|
if (!_LicenseValidator.instance) {
|
|
11300
11856
|
_LicenseValidator.instance = new _LicenseValidator();
|
|
@@ -11302,7 +11858,12 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
11302
11858
|
return _LicenseValidator.instance;
|
|
11303
11859
|
}
|
|
11304
11860
|
/**
|
|
11305
|
-
*
|
|
11861
|
+
* Purge entries from the local success cache.
|
|
11862
|
+
*
|
|
11863
|
+
* @param licenseKey - Optional. If provided, only that key's cache entry is
|
|
11864
|
+
* removed. If omitted the entire cache is cleared.
|
|
11865
|
+
* Callers use this after any 401/403 to ensure the next
|
|
11866
|
+
* validate() call re-validates against the server.
|
|
11306
11867
|
*/
|
|
11307
11868
|
purgeCache(licenseKey) {
|
|
11308
11869
|
if (licenseKey) {
|
|
@@ -11312,10 +11873,20 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
11312
11873
|
}
|
|
11313
11874
|
}
|
|
11314
11875
|
/**
|
|
11315
|
-
*
|
|
11876
|
+
* Primary validation entry-point for UI / hook consumers.
|
|
11877
|
+
*
|
|
11878
|
+
* Resolves the license key, consults the local success cache, performs a
|
|
11879
|
+
* server POST for authoritative status, and falls back to local RSA
|
|
11880
|
+
* signature verification if the server can't be reached.
|
|
11881
|
+
*
|
|
11882
|
+
* @throws LicenseValidationError - When no key is provided OR both the
|
|
11883
|
+
* server call AND the local-RSA fallback report an invalid/expired key.
|
|
11884
|
+
* @throws SDKVersionUnsupportedError - When server reports forceUpgrade=true.
|
|
11885
|
+
* @returns A `LicenseValidationResponse` that the UI can use to enable or
|
|
11886
|
+
* lock the chat widget.
|
|
11316
11887
|
*/
|
|
11317
11888
|
async validate(request) {
|
|
11318
|
-
var
|
|
11889
|
+
var _a3;
|
|
11319
11890
|
const {
|
|
11320
11891
|
licenseKey,
|
|
11321
11892
|
projectId,
|
|
@@ -11333,7 +11904,8 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
11333
11904
|
}
|
|
11334
11905
|
return void 0;
|
|
11335
11906
|
};
|
|
11336
|
-
const
|
|
11907
|
+
const rawKey = licenseKey || getHeader("x-license-key") || ((_a3 = getHeader("authorization")) == null ? void 0 : _a3.replace(/^Bearer\s+/i, "")) || (typeof process !== "undefined" ? process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY || process.env.RETRIVORA_LICENSE_KEY : "") || "";
|
|
11908
|
+
const effectiveLicenseKey = (rawKey || "").trim().replace(/^["']|["']$/g, "").trim();
|
|
11337
11909
|
if (!effectiveLicenseKey) {
|
|
11338
11910
|
this.purgeCache(effectiveLicenseKey);
|
|
11339
11911
|
throw new LicenseValidationError("Missing RETRIVORA_LICENSE_KEY in request. Set NEXT_PUBLIC_RETRIVORA_LICENSE_KEY in your environment or pass licenseKey as a prop.");
|