@retrivora-ai/rag-engine 2.3.0 → 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 +880 -327
- package/dist/handlers/index.mjs +880 -327
- 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 +452 -35
- package/dist/index.mjs +451 -37
- package/dist/server.d.mts +35 -73
- package/dist/server.d.ts +35 -73
- package/dist/server.js +910 -341
- package/dist/server.mjs +910 -341
- 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 +66 -2
- package/src/core/LicenseVerifier.ts +31 -3
- package/src/core/VectorPlugin.ts +30 -0
- package/src/handlers/index.ts +491 -36
- 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);
|
|
@@ -2530,8 +2530,8 @@ var UI_BORDER_RADIUS_OPTIONS = ["none", "sm", "md", "lg", "xl", "full"];
|
|
|
2530
2530
|
|
|
2531
2531
|
// src/config/serverConfig.ts
|
|
2532
2532
|
function readString(env, name) {
|
|
2533
|
-
var
|
|
2534
|
-
const value = (
|
|
2533
|
+
var _a3;
|
|
2534
|
+
const value = (_a3 = env[name]) == null ? void 0 : _a3.trim();
|
|
2535
2535
|
return value ? value : void 0;
|
|
2536
2536
|
}
|
|
2537
2537
|
function readNumber(env, name, fallback) {
|
|
@@ -2544,8 +2544,8 @@ function readNumber(env, name, fallback) {
|
|
|
2544
2544
|
return parsed;
|
|
2545
2545
|
}
|
|
2546
2546
|
function readEnum(env, name, fallback, allowed) {
|
|
2547
|
-
var
|
|
2548
|
-
const value = (
|
|
2547
|
+
var _a3;
|
|
2548
|
+
const value = (_a3 = readString(env, name)) != null ? _a3 : fallback;
|
|
2549
2549
|
if (allowed.includes(value)) {
|
|
2550
2550
|
return value;
|
|
2551
2551
|
}
|
|
@@ -2555,8 +2555,8 @@ function getRagConfig(baseConfig, env = process.env) {
|
|
|
2555
2555
|
return getEnvConfig(env, baseConfig);
|
|
2556
2556
|
}
|
|
2557
2557
|
function getEnvConfig(env = process.env, base) {
|
|
2558
|
-
var
|
|
2559
|
-
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;
|
|
2560
2560
|
const jwtProjectId = (() => {
|
|
2561
2561
|
if (!licenseKey) return void 0;
|
|
2562
2562
|
try {
|
|
@@ -2637,7 +2637,7 @@ function getEnvConfig(env = process.env, base) {
|
|
|
2637
2637
|
rest: "default",
|
|
2638
2638
|
custom: "default"
|
|
2639
2639
|
};
|
|
2640
|
-
const
|
|
2640
|
+
const isFreeTier2 = (() => {
|
|
2641
2641
|
if (!licenseKey) return true;
|
|
2642
2642
|
try {
|
|
2643
2643
|
const payload = LicenseVerifier.verify(licenseKey, projectId);
|
|
@@ -2648,13 +2648,13 @@ function getEnvConfig(env = process.env, base) {
|
|
|
2648
2648
|
}
|
|
2649
2649
|
})();
|
|
2650
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";
|
|
2651
|
-
const defaultLlmProvider =
|
|
2651
|
+
const defaultLlmProvider = isFreeTier2 ? "universal_rest" : "universal_rest";
|
|
2652
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;
|
|
2653
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;
|
|
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 :
|
|
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";
|
|
2655
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;
|
|
2656
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";
|
|
2657
|
-
const defaultEmbeddingProvider =
|
|
2657
|
+
const defaultEmbeddingProvider = isFreeTier2 ? "universal_rest" : "universal_rest";
|
|
2658
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;
|
|
2659
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;
|
|
2660
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";
|
|
@@ -2744,8 +2744,8 @@ function getEnvConfig(env = process.env, base) {
|
|
|
2744
2744
|
}
|
|
2745
2745
|
} : {}), {
|
|
2746
2746
|
mcpServers: (() => {
|
|
2747
|
-
var
|
|
2748
|
-
const raw = (
|
|
2747
|
+
var _a4;
|
|
2748
|
+
const raw = (_a4 = readString(env, "MCP_SERVERS")) != null ? _a4 : readString(env, "NEXT_PUBLIC_MCP_SERVERS");
|
|
2749
2749
|
if (!raw) return void 0;
|
|
2750
2750
|
try {
|
|
2751
2751
|
return JSON.parse(raw);
|
|
@@ -2790,10 +2790,10 @@ var ConfigResolver = class {
|
|
|
2790
2790
|
* fallback behavior.
|
|
2791
2791
|
*/
|
|
2792
2792
|
static resolveUniversal(hostConfig, env = process.env) {
|
|
2793
|
-
var
|
|
2793
|
+
var _a3;
|
|
2794
2794
|
if (!hostConfig) return this.resolve(void 0, env);
|
|
2795
2795
|
const normalized = __spreadProps(__spreadValues({}, hostConfig), {
|
|
2796
|
-
vectorDb: (
|
|
2796
|
+
vectorDb: (_a3 = hostConfig.vectorDb) != null ? _a3 : hostConfig.vectorDatabase,
|
|
2797
2797
|
rag: this.mergeRetrievalWorkflow(hostConfig.rag, hostConfig.retrieval, hostConfig.workflow)
|
|
2798
2798
|
});
|
|
2799
2799
|
return this.resolve(normalized, env);
|
|
@@ -2813,11 +2813,11 @@ var ConfigResolver = class {
|
|
|
2813
2813
|
}
|
|
2814
2814
|
}
|
|
2815
2815
|
static mergeRetrievalWorkflow(rag, retrieval, workflow) {
|
|
2816
|
-
var
|
|
2816
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
2817
2817
|
if (!rag && !retrieval && !workflow) return void 0;
|
|
2818
2818
|
const normalized = __spreadValues({}, rag != null ? rag : {});
|
|
2819
2819
|
if (retrieval) {
|
|
2820
|
-
normalized.topK = (
|
|
2820
|
+
normalized.topK = (_a3 = retrieval.topK) != null ? _a3 : normalized.topK;
|
|
2821
2821
|
normalized.scoreThreshold = (_b = retrieval.scoreThreshold) != null ? _b : normalized.scoreThreshold;
|
|
2822
2822
|
normalized.useReranking = (_c = retrieval.useReranking) != null ? _c : normalized.useReranking;
|
|
2823
2823
|
if (retrieval.strategy === "hybrid") normalized.architecture = (_d = normalized.architecture) != null ? _d : "hybrid";
|
|
@@ -2945,8 +2945,8 @@ var OpenAIProvider = class {
|
|
|
2945
2945
|
};
|
|
2946
2946
|
}
|
|
2947
2947
|
async chat(messages, context, options) {
|
|
2948
|
-
var
|
|
2949
|
-
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.";
|
|
2950
2950
|
const systemMessage = {
|
|
2951
2951
|
role: "system",
|
|
2952
2952
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -2970,8 +2970,8 @@ var OpenAIProvider = class {
|
|
|
2970
2970
|
}
|
|
2971
2971
|
chatStream(messages, context, options) {
|
|
2972
2972
|
return __asyncGenerator(this, null, function* () {
|
|
2973
|
-
var
|
|
2974
|
-
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.";
|
|
2975
2975
|
const systemMessage = {
|
|
2976
2976
|
role: "system",
|
|
2977
2977
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3018,8 +3018,8 @@ var OpenAIProvider = class {
|
|
|
3018
3018
|
return results[0];
|
|
3019
3019
|
}
|
|
3020
3020
|
async batchEmbed(texts, options) {
|
|
3021
|
-
var
|
|
3022
|
-
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";
|
|
3023
3023
|
const apiKey = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.apiKey) != null ? _e : this.llmConfig.apiKey;
|
|
3024
3024
|
const client = apiKey !== this.llmConfig.apiKey ? new OpenAI({ apiKey }) : this.client;
|
|
3025
3025
|
const response = await client.embeddings.create({ model, input: texts });
|
|
@@ -3096,8 +3096,8 @@ var AnthropicProvider = class {
|
|
|
3096
3096
|
};
|
|
3097
3097
|
}
|
|
3098
3098
|
async chat(messages, context, options) {
|
|
3099
|
-
var
|
|
3100
|
-
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.";
|
|
3101
3101
|
const system = buildSystemContent(basePrompt, context);
|
|
3102
3102
|
const anthropicMessages = messages.map((m) => ({
|
|
3103
3103
|
role: m.role === "assistant" ? "assistant" : "user",
|
|
@@ -3135,8 +3135,8 @@ var AnthropicProvider = class {
|
|
|
3135
3135
|
}
|
|
3136
3136
|
chatStream(messages, context, options) {
|
|
3137
3137
|
return __asyncGenerator(this, null, function* () {
|
|
3138
|
-
var
|
|
3139
|
-
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.";
|
|
3140
3140
|
const system = buildSystemContent(basePrompt, context);
|
|
3141
3141
|
const anthropicMessages = messages.map((m) => ({
|
|
3142
3142
|
role: m.role === "assistant" ? "assistant" : "user",
|
|
@@ -3220,8 +3220,8 @@ var AnthropicProvider = class {
|
|
|
3220
3220
|
import axios from "axios";
|
|
3221
3221
|
var OllamaProvider = class {
|
|
3222
3222
|
constructor(llmConfig, embeddingConfig) {
|
|
3223
|
-
var
|
|
3224
|
-
const rawBaseURL = ((
|
|
3223
|
+
var _a3, _b, _c;
|
|
3224
|
+
const rawBaseURL = ((_a3 = llmConfig.baseUrl) != null ? _a3 : "http://localhost:11434").replace(/\/+$/, "");
|
|
3225
3225
|
const baseURL = rawBaseURL.replace(/\/(?:api\/v1|v1|api)$/i, "");
|
|
3226
3226
|
const timeout = Number((_b = llmConfig.options) == null ? void 0 : _b.timeout) || 3e5;
|
|
3227
3227
|
const headers = ((_c = llmConfig.options) == null ? void 0 : _c.headers) || {};
|
|
@@ -3281,8 +3281,8 @@ var OllamaProvider = class {
|
|
|
3281
3281
|
};
|
|
3282
3282
|
}
|
|
3283
3283
|
async chat(messages, context, options) {
|
|
3284
|
-
var
|
|
3285
|
-
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.";
|
|
3286
3286
|
const system = buildSystemContent(basePrompt, context);
|
|
3287
3287
|
const { data } = await this.http.post("/api/chat", {
|
|
3288
3288
|
model: this.llmConfig.model,
|
|
@@ -3300,8 +3300,8 @@ var OllamaProvider = class {
|
|
|
3300
3300
|
}
|
|
3301
3301
|
chatStream(messages, context, options) {
|
|
3302
3302
|
return __asyncGenerator(this, null, function* () {
|
|
3303
|
-
var
|
|
3304
|
-
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.";
|
|
3305
3305
|
const system = buildSystemContent(basePrompt, context);
|
|
3306
3306
|
const response = yield new __await(this.http.post("/api/chat", {
|
|
3307
3307
|
model: this.llmConfig.model,
|
|
@@ -3359,8 +3359,8 @@ var OllamaProvider = class {
|
|
|
3359
3359
|
});
|
|
3360
3360
|
}
|
|
3361
3361
|
async embed(text, options) {
|
|
3362
|
-
var
|
|
3363
|
-
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";
|
|
3364
3364
|
const baseURL = (_f = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.baseUrl) != null ? _e : this.llmConfig.baseUrl) != null ? _f : "http://localhost:11434";
|
|
3365
3365
|
const client = baseURL !== ((_g2 = this.llmConfig.baseUrl) != null ? _g2 : "http://localhost:11434") ? axios.create({ baseURL, timeout: 6e4 }) : this.http;
|
|
3366
3366
|
let prompt = text;
|
|
@@ -3461,9 +3461,9 @@ var GeminiProvider = class {
|
|
|
3461
3461
|
static getHealthChecker() {
|
|
3462
3462
|
return {
|
|
3463
3463
|
async check(config) {
|
|
3464
|
-
var
|
|
3464
|
+
var _a3, _b;
|
|
3465
3465
|
const timestamp = Date.now();
|
|
3466
|
-
const apiKey = (_b = (
|
|
3466
|
+
const apiKey = (_b = (_a3 = config.apiKey) != null ? _a3 : process.env.GOOGLE_GENAI_API_KEY) != null ? _b : "";
|
|
3467
3467
|
const modelName = sanitizeModel(config.model);
|
|
3468
3468
|
try {
|
|
3469
3469
|
const { GoogleGenerativeAI: GoogleGenerativeAI2 } = await import("@google/generative-ai");
|
|
@@ -3493,16 +3493,16 @@ var GeminiProvider = class {
|
|
|
3493
3493
|
/** Resolve the embedding client — uses a separate client when the embedding
|
|
3494
3494
|
* API key differs from the LLM API key. */
|
|
3495
3495
|
get embeddingClient() {
|
|
3496
|
-
var
|
|
3497
|
-
if (((
|
|
3496
|
+
var _a3;
|
|
3497
|
+
if (((_a3 = this.embeddingConfig) == null ? void 0 : _a3.apiKey) && this.embeddingConfig.apiKey !== this.llmConfig.apiKey) {
|
|
3498
3498
|
return buildClient(this.embeddingConfig.apiKey);
|
|
3499
3499
|
}
|
|
3500
3500
|
return this.client;
|
|
3501
3501
|
}
|
|
3502
3502
|
/** Resolve the embedding model to use, in order of specificity. */
|
|
3503
3503
|
resolveEmbeddingModel(optionsModel) {
|
|
3504
|
-
var
|
|
3505
|
-
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);
|
|
3506
3506
|
}
|
|
3507
3507
|
/**
|
|
3508
3508
|
* Convert ChatMessage[] to the Gemini contents format.
|
|
@@ -3522,8 +3522,8 @@ var GeminiProvider = class {
|
|
|
3522
3522
|
// ILLMProvider — chat
|
|
3523
3523
|
// -------------------------------------------------------------------------
|
|
3524
3524
|
async chat(messages, context, options) {
|
|
3525
|
-
var
|
|
3526
|
-
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.";
|
|
3527
3527
|
const model = this.client.getGenerativeModel({
|
|
3528
3528
|
model: this.llmConfig.model,
|
|
3529
3529
|
systemInstruction: buildSystemContent(basePrompt, context)
|
|
@@ -3540,8 +3540,8 @@ var GeminiProvider = class {
|
|
|
3540
3540
|
}
|
|
3541
3541
|
chatStream(messages, context, options) {
|
|
3542
3542
|
return __asyncGenerator(this, null, function* () {
|
|
3543
|
-
var
|
|
3544
|
-
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.";
|
|
3545
3545
|
const model = this.client.getGenerativeModel({
|
|
3546
3546
|
model: this.llmConfig.model,
|
|
3547
3547
|
systemInstruction: buildSystemContent(basePrompt, context)
|
|
@@ -3576,11 +3576,11 @@ var GeminiProvider = class {
|
|
|
3576
3576
|
// ILLMProvider — embeddings
|
|
3577
3577
|
// -------------------------------------------------------------------------
|
|
3578
3578
|
async embed(text, options) {
|
|
3579
|
-
var
|
|
3579
|
+
var _a3, _b;
|
|
3580
3580
|
const content = applyPrefix(
|
|
3581
3581
|
text,
|
|
3582
3582
|
options == null ? void 0 : options.taskType,
|
|
3583
|
-
(
|
|
3583
|
+
(_a3 = this.embeddingConfig) == null ? void 0 : _a3.queryPrefix,
|
|
3584
3584
|
(_b = this.embeddingConfig) == null ? void 0 : _b.documentPrefix
|
|
3585
3585
|
);
|
|
3586
3586
|
const modelName = this.resolveEmbeddingModel(options == null ? void 0 : options.model);
|
|
@@ -3597,7 +3597,7 @@ var GeminiProvider = class {
|
|
|
3597
3597
|
const modelName = this.resolveEmbeddingModel(options == null ? void 0 : options.model);
|
|
3598
3598
|
const model = this.embeddingClient.getGenerativeModel({ model: modelName });
|
|
3599
3599
|
const requests = texts.map((text) => {
|
|
3600
|
-
var
|
|
3600
|
+
var _a3, _b;
|
|
3601
3601
|
return {
|
|
3602
3602
|
content: {
|
|
3603
3603
|
role: "user",
|
|
@@ -3605,7 +3605,7 @@ var GeminiProvider = class {
|
|
|
3605
3605
|
text: applyPrefix(
|
|
3606
3606
|
text,
|
|
3607
3607
|
options == null ? void 0 : options.taskType,
|
|
3608
|
-
(
|
|
3608
|
+
(_a3 = this.embeddingConfig) == null ? void 0 : _a3.queryPrefix,
|
|
3609
3609
|
(_b = this.embeddingConfig) == null ? void 0 : _b.documentPrefix
|
|
3610
3610
|
)
|
|
3611
3611
|
}]
|
|
@@ -3622,8 +3622,8 @@ var GeminiProvider = class {
|
|
|
3622
3622
|
throw err;
|
|
3623
3623
|
});
|
|
3624
3624
|
return response.embeddings.map((e) => {
|
|
3625
|
-
var
|
|
3626
|
-
return (
|
|
3625
|
+
var _a3;
|
|
3626
|
+
return (_a3 = e.values) != null ? _a3 : [];
|
|
3627
3627
|
});
|
|
3628
3628
|
}
|
|
3629
3629
|
// -------------------------------------------------------------------------
|
|
@@ -3712,8 +3712,8 @@ var GroqProvider = class {
|
|
|
3712
3712
|
};
|
|
3713
3713
|
}
|
|
3714
3714
|
async chat(messages, context, options) {
|
|
3715
|
-
var
|
|
3716
|
-
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.";
|
|
3717
3717
|
const systemMessage = {
|
|
3718
3718
|
role: "system",
|
|
3719
3719
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3737,8 +3737,8 @@ var GroqProvider = class {
|
|
|
3737
3737
|
}
|
|
3738
3738
|
chatStream(messages, context, options) {
|
|
3739
3739
|
return __asyncGenerator(this, null, function* () {
|
|
3740
|
-
var
|
|
3741
|
-
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.";
|
|
3742
3742
|
const systemMessage = {
|
|
3743
3743
|
role: "system",
|
|
3744
3744
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3872,8 +3872,8 @@ var QwenProvider = class {
|
|
|
3872
3872
|
};
|
|
3873
3873
|
}
|
|
3874
3874
|
async chat(messages, context, options) {
|
|
3875
|
-
var
|
|
3876
|
-
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.";
|
|
3877
3877
|
const systemMessage = {
|
|
3878
3878
|
role: "system",
|
|
3879
3879
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3897,8 +3897,8 @@ var QwenProvider = class {
|
|
|
3897
3897
|
}
|
|
3898
3898
|
chatStream(messages, context, options) {
|
|
3899
3899
|
return __asyncGenerator(this, null, function* () {
|
|
3900
|
-
var
|
|
3901
|
-
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.";
|
|
3902
3902
|
const systemMessage = {
|
|
3903
3903
|
role: "system",
|
|
3904
3904
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3945,8 +3945,8 @@ var QwenProvider = class {
|
|
|
3945
3945
|
return results[0];
|
|
3946
3946
|
}
|
|
3947
3947
|
async batchEmbed(texts, options) {
|
|
3948
|
-
var
|
|
3949
|
-
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";
|
|
3950
3950
|
const apiKey = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.apiKey) != null ? _e : this.llmConfig.apiKey;
|
|
3951
3951
|
const client = apiKey !== this.llmConfig.apiKey ? new OpenAI3({
|
|
3952
3952
|
apiKey,
|
|
@@ -4046,9 +4046,9 @@ var VECTOR_PROFILES = {
|
|
|
4046
4046
|
|
|
4047
4047
|
// src/llm/providers/UniversalLLMAdapter.ts
|
|
4048
4048
|
function extractContent(obj) {
|
|
4049
|
-
var
|
|
4049
|
+
var _a3, _b, _c;
|
|
4050
4050
|
if (!obj || typeof obj !== "object") return void 0;
|
|
4051
|
-
const choice = (
|
|
4051
|
+
const choice = (_a3 = obj.choices) == null ? void 0 : _a3[0];
|
|
4052
4052
|
if (!choice) return void 0;
|
|
4053
4053
|
if (typeof ((_b = choice.message) == null ? void 0 : _b.content) === "string") return choice.message.content;
|
|
4054
4054
|
if (typeof ((_c = choice.delta) == null ? void 0 : _c.content) === "string") return choice.delta.content;
|
|
@@ -4058,10 +4058,10 @@ function extractContent(obj) {
|
|
|
4058
4058
|
}
|
|
4059
4059
|
var UniversalLLMAdapter = class {
|
|
4060
4060
|
constructor(config) {
|
|
4061
|
-
var
|
|
4061
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h;
|
|
4062
4062
|
this.model = config.model;
|
|
4063
4063
|
const llmConfig = config;
|
|
4064
|
-
const options = (
|
|
4064
|
+
const options = (_a3 = llmConfig.options) != null ? _a3 : {};
|
|
4065
4065
|
let profile = {};
|
|
4066
4066
|
if (typeof options.profile === "string") {
|
|
4067
4067
|
profile = LLM_PROFILES[options.profile] || {};
|
|
@@ -4087,8 +4087,8 @@ var UniversalLLMAdapter = class {
|
|
|
4087
4087
|
});
|
|
4088
4088
|
}
|
|
4089
4089
|
async chat(messages, context) {
|
|
4090
|
-
var
|
|
4091
|
-
const path2 = (
|
|
4090
|
+
var _a3, _b, _c, _d, _e;
|
|
4091
|
+
const path2 = (_a3 = this.opts.chatPath) != null ? _a3 : "/chat/completions";
|
|
4092
4092
|
const safeMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
|
|
4093
4093
|
role: m.role || "user",
|
|
4094
4094
|
content: typeof m.content === "string" ? m.content : m.content != null ? String(m.content) : ""
|
|
@@ -4154,8 +4154,8 @@ ${context != null ? context : "None"}` },
|
|
|
4154
4154
|
*/
|
|
4155
4155
|
chatStream(messages, context) {
|
|
4156
4156
|
return __asyncGenerator(this, null, function* () {
|
|
4157
|
-
var
|
|
4158
|
-
const path2 = (
|
|
4157
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
4158
|
+
const path2 = (_a3 = this.opts.chatPath) != null ? _a3 : "/chat/completions";
|
|
4159
4159
|
const url = `${this.baseUrl.replace(/\/$/, "")}${path2}`;
|
|
4160
4160
|
const extractPath = ((_b = this.opts.responseExtractPath) != null ? _b : "choices[0].message.content").replace("message.content", "delta.content");
|
|
4161
4161
|
const safeMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
|
|
@@ -4281,8 +4281,8 @@ ${context != null ? context : "None"}` },
|
|
|
4281
4281
|
});
|
|
4282
4282
|
}
|
|
4283
4283
|
async embed(text) {
|
|
4284
|
-
var
|
|
4285
|
-
const path2 = (
|
|
4284
|
+
var _a3, _b, _c, _d, _e;
|
|
4285
|
+
const path2 = (_a3 = this.opts.embedPath) != null ? _a3 : "/embeddings";
|
|
4286
4286
|
const payload = this.opts.embedPayloadTemplate ? buildPayload(this.opts.embedPayloadTemplate, { input: text, model: this.model }) : { input: text, model: this.model };
|
|
4287
4287
|
try {
|
|
4288
4288
|
const { data: data2 } = await this.http.post(path2, payload);
|
|
@@ -4371,7 +4371,7 @@ var LLMFactory = class _LLMFactory {
|
|
|
4371
4371
|
];
|
|
4372
4372
|
}
|
|
4373
4373
|
static create(llmConfig, embeddingConfig) {
|
|
4374
|
-
var
|
|
4374
|
+
var _a3, _b, _c;
|
|
4375
4375
|
switch (llmConfig.provider) {
|
|
4376
4376
|
case "openai":
|
|
4377
4377
|
return new OpenAIProvider(llmConfig, embeddingConfig);
|
|
@@ -4390,7 +4390,7 @@ var LLMFactory = class _LLMFactory {
|
|
|
4390
4390
|
case "custom":
|
|
4391
4391
|
return new UniversalLLMAdapter(llmConfig);
|
|
4392
4392
|
default: {
|
|
4393
|
-
const providerName = String((
|
|
4393
|
+
const providerName = String((_a3 = llmConfig.provider) != null ? _a3 : "").toLowerCase();
|
|
4394
4394
|
const customFactory = customProviders.get(providerName);
|
|
4395
4395
|
if (customFactory) {
|
|
4396
4396
|
return customFactory(llmConfig);
|
|
@@ -4492,7 +4492,7 @@ var ProviderRegistry = class {
|
|
|
4492
4492
|
return null;
|
|
4493
4493
|
}
|
|
4494
4494
|
static async loadVectorProviderClass(provider) {
|
|
4495
|
-
var
|
|
4495
|
+
var _a3;
|
|
4496
4496
|
if (this.vectorProviders[provider]) return this.vectorProviders[provider];
|
|
4497
4497
|
switch (provider) {
|
|
4498
4498
|
case "pinecone": {
|
|
@@ -4501,7 +4501,7 @@ var ProviderRegistry = class {
|
|
|
4501
4501
|
}
|
|
4502
4502
|
case "pgvector":
|
|
4503
4503
|
case "postgresql": {
|
|
4504
|
-
const postgresMode = ((
|
|
4504
|
+
const postgresMode = ((_a3 = process.env.POSTGRES_MODE) != null ? _a3 : "multi").toLowerCase();
|
|
4505
4505
|
if (postgresMode === "single") {
|
|
4506
4506
|
const { PostgreSQLProvider: PostgreSQLProvider2 } = await Promise.resolve().then(() => (init_PostgreSQLProvider(), PostgreSQLProvider_exports));
|
|
4507
4507
|
return PostgreSQLProvider2;
|
|
@@ -4724,7 +4724,7 @@ var ConfigValidator = class {
|
|
|
4724
4724
|
// package.json
|
|
4725
4725
|
var package_default = {
|
|
4726
4726
|
name: "@retrivora-ai/rag-engine",
|
|
4727
|
-
version: "2.3.
|
|
4727
|
+
version: "2.3.1",
|
|
4728
4728
|
description: "Retrivora AI is a plug-and-play AI engine for RAG chat experiences \u2014 generic vector DB + LLM provider, embeddable or standalone.",
|
|
4729
4729
|
author: "Abhinav Alkuchi",
|
|
4730
4730
|
license: "UNLICENSED",
|
|
@@ -5029,8 +5029,8 @@ var Reranker = class {
|
|
|
5029
5029
|
return matches.sort((a, b) => b.score - a.score).slice(0, limit);
|
|
5030
5030
|
}
|
|
5031
5031
|
const scoredMatches = matches.map((match) => {
|
|
5032
|
-
var
|
|
5033
|
-
const contentLower = ((
|
|
5032
|
+
var _a3;
|
|
5033
|
+
const contentLower = ((_a3 = match == null ? void 0 : match.content) != null ? _a3 : "").toLowerCase();
|
|
5034
5034
|
let keywordScore = 0;
|
|
5035
5035
|
keywords.forEach((keyword) => {
|
|
5036
5036
|
if (contentLower.includes(keyword)) {
|
|
@@ -5052,8 +5052,8 @@ var Reranker = class {
|
|
|
5052
5052
|
|
|
5053
5053
|
Documents:
|
|
5054
5054
|
${topN.map((m, i) => {
|
|
5055
|
-
var
|
|
5056
|
-
return `[${i}] ${((
|
|
5055
|
+
var _a3;
|
|
5056
|
+
return `[${i}] ${((_a3 = m == null ? void 0 : m.content) != null ? _a3 : "").replace(/\n/g, " ")}`;
|
|
5057
5057
|
}).join("\n")}` }],
|
|
5058
5058
|
"",
|
|
5059
5059
|
{
|
|
@@ -5097,11 +5097,11 @@ var LlamaIndexIngestor = class {
|
|
|
5097
5097
|
* than standard character-count splitting.
|
|
5098
5098
|
*/
|
|
5099
5099
|
async chunk(text, options = {}) {
|
|
5100
|
-
var
|
|
5100
|
+
var _a3, _b;
|
|
5101
5101
|
try {
|
|
5102
5102
|
const { Document, SentenceSplitter, MetadataMode } = await import(`${"llamaindex"}`);
|
|
5103
5103
|
const splitter = new SentenceSplitter({
|
|
5104
|
-
chunkSize: (
|
|
5104
|
+
chunkSize: (_a3 = options.chunkSize) != null ? _a3 : 1e3,
|
|
5105
5105
|
chunkOverlap: (_b = options.chunkOverlap) != null ? _b : 200
|
|
5106
5106
|
});
|
|
5107
5107
|
const doc = new Document({ text, metadata: options.metadata || {} });
|
|
@@ -5210,7 +5210,7 @@ ${error instanceof Error ? error.message : String(error)}`
|
|
|
5210
5210
|
* The agent returns `{ messages: [...] }` — the last message is the final answer.
|
|
5211
5211
|
*/
|
|
5212
5212
|
async run(input, chatHistory = []) {
|
|
5213
|
-
var
|
|
5213
|
+
var _a3, _b, _c;
|
|
5214
5214
|
if (!this.agent) {
|
|
5215
5215
|
throw new Error("[LangChainAgent] Agent not initialized. Call initialize() first.");
|
|
5216
5216
|
}
|
|
@@ -5221,7 +5221,7 @@ ${error instanceof Error ? error.message : String(error)}`
|
|
|
5221
5221
|
const response = await this.agent.invoke({
|
|
5222
5222
|
messages: [...historyMessages, new HumanMessage(input)]
|
|
5223
5223
|
});
|
|
5224
|
-
const lastMessage = (
|
|
5224
|
+
const lastMessage = (_a3 = response == null ? void 0 : response.messages) == null ? void 0 : _a3.at(-1);
|
|
5225
5225
|
if (lastMessage && typeof lastMessage.content === "string") {
|
|
5226
5226
|
return lastMessage.content;
|
|
5227
5227
|
}
|
|
@@ -5273,7 +5273,7 @@ var MCPClient = class {
|
|
|
5273
5273
|
}
|
|
5274
5274
|
}
|
|
5275
5275
|
async connectStdio() {
|
|
5276
|
-
var
|
|
5276
|
+
var _a3;
|
|
5277
5277
|
const cmd = this.config.command;
|
|
5278
5278
|
if (!cmd) {
|
|
5279
5279
|
throw new Error(`[MCPClient] Command option is required for stdio transport on "${this.config.name}"`);
|
|
@@ -5288,7 +5288,7 @@ var MCPClient = class {
|
|
|
5288
5288
|
this.stdioBuffer += data.toString("utf-8");
|
|
5289
5289
|
this.processStdioLines();
|
|
5290
5290
|
});
|
|
5291
|
-
(
|
|
5291
|
+
(_a3 = this.childProcess.stderr) == null ? void 0 : _a3.on("data", (data) => {
|
|
5292
5292
|
console.warn(`[MCPClient] [stderr] [${this.config.name}]:`, data.toString("utf-8"));
|
|
5293
5293
|
});
|
|
5294
5294
|
this.childProcess.on("close", (code) => {
|
|
@@ -5363,14 +5363,14 @@ var MCPClient = class {
|
|
|
5363
5363
|
}
|
|
5364
5364
|
}
|
|
5365
5365
|
async sendNotification(method, params) {
|
|
5366
|
-
var
|
|
5366
|
+
var _a3;
|
|
5367
5367
|
const notification = {
|
|
5368
5368
|
jsonrpc: "2.0",
|
|
5369
5369
|
method,
|
|
5370
5370
|
params
|
|
5371
5371
|
};
|
|
5372
5372
|
if (this.config.transport === "stdio") {
|
|
5373
|
-
if ((
|
|
5373
|
+
if ((_a3 = this.childProcess) == null ? void 0 : _a3.stdin) {
|
|
5374
5374
|
this.childProcess.stdin.write(JSON.stringify(notification) + "\n", "utf-8");
|
|
5375
5375
|
}
|
|
5376
5376
|
} else if (this.sseUrl) {
|
|
@@ -5448,11 +5448,11 @@ var MCPRegistry = class {
|
|
|
5448
5448
|
// src/core/MultiAgentCoordinator.ts
|
|
5449
5449
|
var MultiAgentCoordinator = class {
|
|
5450
5450
|
constructor(options) {
|
|
5451
|
-
var
|
|
5451
|
+
var _a3;
|
|
5452
5452
|
this.llmProvider = options.llmProvider;
|
|
5453
5453
|
this.mcpRegistry = options.mcpRegistry;
|
|
5454
5454
|
this.documentSearch = options.documentSearch;
|
|
5455
|
-
this.maxIterations = (
|
|
5455
|
+
this.maxIterations = (_a3 = options.maxIterations) != null ? _a3 : 5;
|
|
5456
5456
|
}
|
|
5457
5457
|
/**
|
|
5458
5458
|
* Run the multi-agent coordination loop synchronously and return the final response.
|
|
@@ -5504,8 +5504,8 @@ Available Tools:
|
|
|
5504
5504
|
|
|
5505
5505
|
${mcpTools.length > 0 ? "MCP Server Tools:" : ""}
|
|
5506
5506
|
${mcpTools.map((mt) => {
|
|
5507
|
-
var
|
|
5508
|
-
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."}`;
|
|
5509
5509
|
}).join("\n")}
|
|
5510
5510
|
|
|
5511
5511
|
Tool Calling Protocol:
|
|
@@ -5663,6 +5663,100 @@ ${toolResultText}`
|
|
|
5663
5663
|
}
|
|
5664
5664
|
};
|
|
5665
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
|
+
|
|
5666
5760
|
// src/core/BatchProcessor.ts
|
|
5667
5761
|
function isTransientError(error) {
|
|
5668
5762
|
if (!(error instanceof Error)) return false;
|
|
@@ -5686,7 +5780,34 @@ function calculateBackoffDelay(attempt, initialDelayMs, maxDelayMs, multiplier)
|
|
|
5686
5780
|
function sleep(ms) {
|
|
5687
5781
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
5688
5782
|
}
|
|
5689
|
-
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
|
+
}
|
|
5690
5811
|
/**
|
|
5691
5812
|
* Processes an array of items in configurable batches with retry logic.
|
|
5692
5813
|
*
|
|
@@ -5727,7 +5848,7 @@ var BatchProcessor = class {
|
|
|
5727
5848
|
let lastError;
|
|
5728
5849
|
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
5729
5850
|
try {
|
|
5730
|
-
const result = await processor(batch);
|
|
5851
|
+
const result = await _BatchProcessor.executeWithCircuitBreaker(() => processor(batch));
|
|
5731
5852
|
results.push(result);
|
|
5732
5853
|
success = true;
|
|
5733
5854
|
break;
|
|
@@ -5785,7 +5906,7 @@ ${errorMessages}`
|
|
|
5785
5906
|
let lastError;
|
|
5786
5907
|
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
5787
5908
|
try {
|
|
5788
|
-
const result = await processor(item);
|
|
5909
|
+
const result = await _BatchProcessor.executeWithCircuitBreaker(() => processor(item));
|
|
5789
5910
|
results.push(result);
|
|
5790
5911
|
success = true;
|
|
5791
5912
|
break;
|
|
@@ -5858,7 +5979,7 @@ ${errorMessages}`
|
|
|
5858
5979
|
}));
|
|
5859
5980
|
const chunkPromises = chunk.map(async ({ item, originalIndex }) => {
|
|
5860
5981
|
try {
|
|
5861
|
-
const result = await processor(item);
|
|
5982
|
+
const result = await _BatchProcessor.executeWithCircuitBreaker(() => processor(item));
|
|
5862
5983
|
return { success: true, result, index: originalIndex };
|
|
5863
5984
|
} catch (err) {
|
|
5864
5985
|
const error = err instanceof Error ? err : new Error(String(err));
|
|
@@ -5886,6 +6007,12 @@ ${errorMessages}`
|
|
|
5886
6007
|
return { results, errors, totalProcessed, totalFailed };
|
|
5887
6008
|
}
|
|
5888
6009
|
};
|
|
6010
|
+
_BatchProcessor.cb = new CircuitBreaker({
|
|
6011
|
+
failureThreshold: 5,
|
|
6012
|
+
resetTimeoutMs: 3e4,
|
|
6013
|
+
halfOpenMaxCalls: 1
|
|
6014
|
+
});
|
|
6015
|
+
var BatchProcessor = _BatchProcessor;
|
|
5889
6016
|
|
|
5890
6017
|
// src/config/EmbeddingStrategy.ts
|
|
5891
6018
|
var EmbeddingStrategy = /* @__PURE__ */ ((EmbeddingStrategy2) => {
|
|
@@ -5989,7 +6116,7 @@ var QueryProcessor = class {
|
|
|
5989
6116
|
* @param validFields Optional list of known filterable fields to look for
|
|
5990
6117
|
*/
|
|
5991
6118
|
static extractQueryFieldHints(question, validFields = []) {
|
|
5992
|
-
var
|
|
6119
|
+
var _a3, _b, _c, _d;
|
|
5993
6120
|
if (!question.trim()) return [];
|
|
5994
6121
|
const hints = /* @__PURE__ */ new Map();
|
|
5995
6122
|
const addHint = (value, field) => {
|
|
@@ -6069,7 +6196,7 @@ var QueryProcessor = class {
|
|
|
6069
6196
|
];
|
|
6070
6197
|
for (const p of universalPatterns) {
|
|
6071
6198
|
for (const match of question.matchAll(p.regex)) {
|
|
6072
|
-
const val = p.group ? (
|
|
6199
|
+
const val = p.group ? (_a3 = match[p.group]) != null ? _a3 : match[0] : match[0];
|
|
6073
6200
|
if (!val) continue;
|
|
6074
6201
|
if (p.field) addHint(val, p.field);
|
|
6075
6202
|
else addHint(val);
|
|
@@ -6293,11 +6420,11 @@ var LLMRouter = class {
|
|
|
6293
6420
|
* When provided it is used directly as the 'default' role without re-constructing.
|
|
6294
6421
|
*/
|
|
6295
6422
|
async initialize(prebuiltDefault) {
|
|
6296
|
-
var
|
|
6423
|
+
var _a3;
|
|
6297
6424
|
const defaultModel = prebuiltDefault != null ? prebuiltDefault : LLMFactory.create(this.config.llm, this.config.embedding);
|
|
6298
6425
|
this.models.set("default", defaultModel);
|
|
6299
6426
|
const envFastModel = process.env.FAST_LLM_MODEL;
|
|
6300
|
-
const providerFastDefault = (
|
|
6427
|
+
const providerFastDefault = (_a3 = FAST_MODEL_DEFAULTS[this.config.llm.provider]) != null ? _a3 : "";
|
|
6301
6428
|
const fastModelName = envFastModel || providerFastDefault;
|
|
6302
6429
|
if (fastModelName && fastModelName !== this.config.llm.model) {
|
|
6303
6430
|
console.log(`[LLMRouter] Fast role \u2192 provider="${this.config.llm.provider}" model="${fastModelName}"`);
|
|
@@ -6316,8 +6443,8 @@ var LLMRouter = class {
|
|
|
6316
6443
|
* Falls back to 'default' if the requested role is not registered.
|
|
6317
6444
|
*/
|
|
6318
6445
|
get(role) {
|
|
6319
|
-
var
|
|
6320
|
-
const provider = (
|
|
6446
|
+
var _a3;
|
|
6447
|
+
const provider = (_a3 = this.models.get(role)) != null ? _a3 : this.models.get("default");
|
|
6321
6448
|
if (!provider) {
|
|
6322
6449
|
throw new Error(`[LLMRouter] No provider registered for role: "${role}". Did you call initialize()?`);
|
|
6323
6450
|
}
|
|
@@ -6403,8 +6530,8 @@ var IntentClassifier = class {
|
|
|
6403
6530
|
numericFieldCount = numericKeys.size;
|
|
6404
6531
|
categoricalFieldCount = catKeys.size;
|
|
6405
6532
|
if (productKeyMatches >= 2 || docs.some((d) => {
|
|
6406
|
-
var
|
|
6407
|
-
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");
|
|
6408
6535
|
})) {
|
|
6409
6536
|
isProductLike = true;
|
|
6410
6537
|
}
|
|
@@ -6686,8 +6813,8 @@ var TextRendererStrategy = class {
|
|
|
6686
6813
|
}
|
|
6687
6814
|
const docs = Array.isArray(data) ? data : [];
|
|
6688
6815
|
const text = docs.map((d) => {
|
|
6689
|
-
var
|
|
6690
|
-
return (
|
|
6816
|
+
var _a3;
|
|
6817
|
+
return (_a3 = d == null ? void 0 : d.content) != null ? _a3 : "";
|
|
6691
6818
|
}).join("\n\n");
|
|
6692
6819
|
return { type: "text", title, data: { content: text || "No detailed content available." } };
|
|
6693
6820
|
}
|
|
@@ -6830,9 +6957,9 @@ var LRUDecisionCache = class {
|
|
|
6830
6957
|
this.maxSize = maxSize;
|
|
6831
6958
|
}
|
|
6832
6959
|
generateKey(context) {
|
|
6833
|
-
var
|
|
6960
|
+
var _a3, _b;
|
|
6834
6961
|
const q = (context.userQuery || "").toLowerCase().trim();
|
|
6835
|
-
const docCount = (_b = (
|
|
6962
|
+
const docCount = (_b = (_a3 = context.retrievedDocuments) == null ? void 0 : _a3.length) != null ? _b : 0;
|
|
6836
6963
|
return `${q}::docs:${docCount}`;
|
|
6837
6964
|
}
|
|
6838
6965
|
get(context) {
|
|
@@ -6941,7 +7068,7 @@ var UITransformer = class _UITransformer {
|
|
|
6941
7068
|
* Prefer `analyzeAndDecide()` in production.
|
|
6942
7069
|
*/
|
|
6943
7070
|
static transform(userQuery, retrievedData, config, trainedSchema, intent) {
|
|
6944
|
-
var
|
|
7071
|
+
var _a3, _b, _c;
|
|
6945
7072
|
if (!retrievedData || retrievedData.length === 0) {
|
|
6946
7073
|
return this.createTextResponse("No data available", "No relevant data found for your query.");
|
|
6947
7074
|
}
|
|
@@ -6961,7 +7088,7 @@ var UITransformer = class _UITransformer {
|
|
|
6961
7088
|
return this.transformToBarChart(filteredData, profile, userQuery, resolvedIntent.visualizationHint === "ranking");
|
|
6962
7089
|
}
|
|
6963
7090
|
if (resolvedIntent.visualizationHint === "distribution") {
|
|
6964
|
-
return (
|
|
7091
|
+
return (_a3 = this.transformToHistogram(profile, userQuery)) != null ? _a3 : this.transformToBarChart(filteredData, profile, userQuery);
|
|
6965
7092
|
}
|
|
6966
7093
|
if (resolvedIntent.visualizationHint === "correlation") {
|
|
6967
7094
|
return (_b = this.transformToScatterPlot(profile, userQuery)) != null ? _b : this.transformToBarChart(filteredData, profile, userQuery);
|
|
@@ -7294,11 +7421,11 @@ ${schemaProfileText}` : ""}`;
|
|
|
7294
7421
|
};
|
|
7295
7422
|
}
|
|
7296
7423
|
static transformToPieChart(data, profile, query = "") {
|
|
7297
|
-
var
|
|
7424
|
+
var _a3;
|
|
7298
7425
|
const dimension = profile ? this.selectDimensionField(profile, query) : void 0;
|
|
7299
7426
|
const categories = dimension ? Array.from(new Set(profile.records.map((record) => {
|
|
7300
|
-
var
|
|
7301
|
-
return String((
|
|
7427
|
+
var _a4;
|
|
7428
|
+
return String((_a4 = record.fields[dimension.key]) != null ? _a4 : "");
|
|
7302
7429
|
}).filter(Boolean))) : this.detectCategories(data);
|
|
7303
7430
|
if (categories.length === 0) return null;
|
|
7304
7431
|
const categoryData = dimension && profile ? this.aggregateProfileByDimension(profile, dimension.key) : this.aggregateByCategory(data, categories);
|
|
@@ -7308,7 +7435,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7308
7435
|
});
|
|
7309
7436
|
return {
|
|
7310
7437
|
type: "pie_chart",
|
|
7311
|
-
title: `Distribution by ${(
|
|
7438
|
+
title: `Distribution by ${(_a3 = dimension == null ? void 0 : dimension.label) != null ? _a3 : "Category"}`,
|
|
7312
7439
|
description: `Showing breakdown across ${pieData.length} categories`,
|
|
7313
7440
|
data: pieData
|
|
7314
7441
|
};
|
|
@@ -7318,8 +7445,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7318
7445
|
const valueField = profile.numericFields[0];
|
|
7319
7446
|
const buckets = /* @__PURE__ */ new Map();
|
|
7320
7447
|
profile.records.forEach((record) => {
|
|
7321
|
-
var
|
|
7322
|
-
const timestamp = String((
|
|
7448
|
+
var _a3, _b, _c;
|
|
7449
|
+
const timestamp = String((_a3 = record.fields[dateField.key]) != null ? _a3 : "");
|
|
7323
7450
|
const value = (_b = this.toFiniteNumber(record.fields[valueField.key])) != null ? _b : 0;
|
|
7324
7451
|
buckets.set(timestamp, ((_c = buckets.get(timestamp)) != null ? _c : 0) + value);
|
|
7325
7452
|
});
|
|
@@ -7332,23 +7459,23 @@ ${schemaProfileText}` : ""}`;
|
|
|
7332
7459
|
};
|
|
7333
7460
|
}
|
|
7334
7461
|
static transformToBarChart(data, profile, query = "", horizontal = false) {
|
|
7335
|
-
var
|
|
7462
|
+
var _a3;
|
|
7336
7463
|
const dimension = profile ? this.selectDimensionField(profile, query) : void 0;
|
|
7337
7464
|
const measure = profile ? this.selectNumericField(profile, query) : void 0;
|
|
7338
7465
|
const aggregate = dimension && profile ? this.aggregateProfileByDimension(profile, dimension.key, measure == null ? void 0 : measure.key) : this.aggregateByCategory(data, this.detectCategories(data));
|
|
7339
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);
|
|
7340
7467
|
const fallbackData = barData.length > 0 ? barData : data.slice(0, 12).map((item, index) => {
|
|
7341
|
-
var
|
|
7468
|
+
var _a4, _b, _c, _d, _e;
|
|
7342
7469
|
const meta = item.metadata || {};
|
|
7343
7470
|
const label = String(
|
|
7344
|
-
(_c = (_b = (
|
|
7471
|
+
(_c = (_b = (_a4 = this.getDynamicVal(meta, "name")) != null ? _a4 : meta.label) != null ? _b : meta.title) != null ? _c : `Result ${index + 1}`
|
|
7345
7472
|
);
|
|
7346
7473
|
const value = (_e = (_d = this.extractNumericValue(meta)) != null ? _d : item.score) != null ? _e : 0;
|
|
7347
7474
|
return { category: label, value: Number(value) };
|
|
7348
7475
|
});
|
|
7349
7476
|
return {
|
|
7350
7477
|
type: horizontal ? "horizontal_bar" : "bar_chart",
|
|
7351
|
-
title: dimension ? `${(
|
|
7478
|
+
title: dimension ? `${(_a3 = measure == null ? void 0 : measure.label) != null ? _a3 : "Count"} by ${dimension.label}` : "Comparison",
|
|
7352
7479
|
description: `Showing ${fallbackData.length} comparable values`,
|
|
7353
7480
|
data: fallbackData
|
|
7354
7481
|
};
|
|
@@ -7383,11 +7510,11 @@ ${schemaProfileText}` : ""}`;
|
|
|
7383
7510
|
if (fields.length < 2) return null;
|
|
7384
7511
|
const [xField, yField] = fields;
|
|
7385
7512
|
const points = profile.records.map((record) => {
|
|
7386
|
-
var
|
|
7513
|
+
var _a3;
|
|
7387
7514
|
const x = this.toFiniteNumber(record.fields[xField.key]);
|
|
7388
7515
|
const y = this.toFiniteNumber(record.fields[yField.key]);
|
|
7389
7516
|
if (x === null || y === null) return null;
|
|
7390
|
-
return { x, y, label: String((
|
|
7517
|
+
return { x, y, label: String((_a3 = this.getRecordLabel(record)) != null ? _a3 : record.id) };
|
|
7391
7518
|
}).filter((point) => point !== null).slice(0, 100);
|
|
7392
7519
|
if (points.length === 0) return null;
|
|
7393
7520
|
return {
|
|
@@ -7417,9 +7544,9 @@ ${schemaProfileText}` : ""}`;
|
|
|
7417
7544
|
static transformToRadarChart(data) {
|
|
7418
7545
|
const attributeMap = {};
|
|
7419
7546
|
data.forEach((item) => {
|
|
7420
|
-
var
|
|
7547
|
+
var _a3, _b, _c;
|
|
7421
7548
|
const meta = item.metadata || {};
|
|
7422
|
-
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");
|
|
7423
7550
|
Object.entries(meta).forEach(([key, val]) => {
|
|
7424
7551
|
if (typeof val === "number" && !["price", "id"].includes(key.toLowerCase())) {
|
|
7425
7552
|
if (!attributeMap[key]) attributeMap[key] = {};
|
|
@@ -7435,8 +7562,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7435
7562
|
title: "Product Comparison",
|
|
7436
7563
|
description: `Comparing ${data.length} items across ${radarData.length} attributes`,
|
|
7437
7564
|
data: radarData.length > 0 ? radarData : data.map((d) => {
|
|
7438
|
-
var
|
|
7439
|
-
return { attribute: ((
|
|
7565
|
+
var _a3;
|
|
7566
|
+
return { attribute: ((_a3 = d == null ? void 0 : d.content) != null ? _a3 : "").substring(0, 40) };
|
|
7440
7567
|
})
|
|
7441
7568
|
};
|
|
7442
7569
|
}
|
|
@@ -7455,8 +7582,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7455
7582
|
return this.createTextResponse(
|
|
7456
7583
|
"Retrieved Context",
|
|
7457
7584
|
data.map((item) => {
|
|
7458
|
-
var
|
|
7459
|
-
return (
|
|
7585
|
+
var _a3;
|
|
7586
|
+
return (_a3 = item == null ? void 0 : item.content) != null ? _a3 : "";
|
|
7460
7587
|
}).join("\n\n"),
|
|
7461
7588
|
`Found ${data.length} relevant results`
|
|
7462
7589
|
);
|
|
@@ -7507,11 +7634,11 @@ ${schemaProfileText}` : ""}`;
|
|
|
7507
7634
|
return null;
|
|
7508
7635
|
}
|
|
7509
7636
|
static normalizeTransformation(payload) {
|
|
7510
|
-
var
|
|
7637
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j;
|
|
7511
7638
|
if (!payload || typeof payload !== "object") return null;
|
|
7512
7639
|
const p = payload;
|
|
7513
7640
|
const type = this.normalizeVisualizationType(
|
|
7514
|
-
String((_c = (_b = (
|
|
7641
|
+
String((_c = (_b = (_a3 = p.type) != null ? _a3 : p.view) != null ? _b : p.chartType) != null ? _c : "")
|
|
7515
7642
|
);
|
|
7516
7643
|
if (!type) return null;
|
|
7517
7644
|
const title = String((_e = (_d = p.title) != null ? _d : p.heading) != null ? _e : "Visualization");
|
|
@@ -7522,7 +7649,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7522
7649
|
return this.validateTransformation(transformation) ? transformation : null;
|
|
7523
7650
|
}
|
|
7524
7651
|
static normalizeVisualizationType(type) {
|
|
7525
|
-
var
|
|
7652
|
+
var _a3;
|
|
7526
7653
|
const mapping = {
|
|
7527
7654
|
pie: "pie_chart",
|
|
7528
7655
|
pie_chart: "pie_chart",
|
|
@@ -7550,7 +7677,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7550
7677
|
product_carousel: "product_carousel",
|
|
7551
7678
|
carousel: "carousel"
|
|
7552
7679
|
};
|
|
7553
|
-
return (
|
|
7680
|
+
return (_a3 = mapping[type.toLowerCase()]) != null ? _a3 : null;
|
|
7554
7681
|
}
|
|
7555
7682
|
static validateTransformation(t) {
|
|
7556
7683
|
const { type, data } = t;
|
|
@@ -7666,7 +7793,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7666
7793
|
}
|
|
7667
7794
|
static profileData(data) {
|
|
7668
7795
|
const records = (data || []).filter((item) => Boolean(item && typeof item === "object")).map((item) => {
|
|
7669
|
-
var
|
|
7796
|
+
var _a3, _b;
|
|
7670
7797
|
const fields2 = {};
|
|
7671
7798
|
Object.entries(item.metadata || {}).forEach(([key, value]) => {
|
|
7672
7799
|
const primitive = this.toPrimitive(value);
|
|
@@ -7675,7 +7802,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7675
7802
|
if (!fields2.content && item.content) fields2.content = item.content.substring(0, 500);
|
|
7676
7803
|
return {
|
|
7677
7804
|
id: item.id,
|
|
7678
|
-
content: (
|
|
7805
|
+
content: (_a3 = item.content) != null ? _a3 : "",
|
|
7679
7806
|
score: (_b = item.score) != null ? _b : 0,
|
|
7680
7807
|
fields: fields2,
|
|
7681
7808
|
source: item
|
|
@@ -7756,16 +7883,16 @@ ${schemaProfileText}` : ""}`;
|
|
|
7756
7883
|
return null;
|
|
7757
7884
|
}
|
|
7758
7885
|
static selectDimensionField(profile, query) {
|
|
7759
|
-
var
|
|
7886
|
+
var _a3, _b;
|
|
7760
7887
|
const productCategory = profile.categoricalFields.find(
|
|
7761
7888
|
(field) => /category|department|collection|type|group|segment|region|country|state|city/i.test(field.key)
|
|
7762
7889
|
);
|
|
7763
7890
|
const ranked = this.rankFieldsByQuery(profile.categoricalFields, query);
|
|
7764
|
-
return (_b = (
|
|
7891
|
+
return (_b = (_a3 = ranked[0]) != null ? _a3 : productCategory) != null ? _b : profile.categoricalFields[0];
|
|
7765
7892
|
}
|
|
7766
7893
|
static selectNumericField(profile, query) {
|
|
7767
|
-
var
|
|
7768
|
-
return (
|
|
7894
|
+
var _a3;
|
|
7895
|
+
return (_a3 = this.rankFieldsByQuery(profile.numericFields, query)[0]) != null ? _a3 : profile.numericFields[0];
|
|
7769
7896
|
}
|
|
7770
7897
|
static rankFieldsByQuery(fields, query) {
|
|
7771
7898
|
const q = query.toLowerCase();
|
|
@@ -7794,8 +7921,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7794
7921
|
static aggregateProfileByDimension(profile, dimensionKey, measureKey) {
|
|
7795
7922
|
const result = {};
|
|
7796
7923
|
profile.records.forEach((record) => {
|
|
7797
|
-
var
|
|
7798
|
-
const category = String((
|
|
7924
|
+
var _a3, _b, _c;
|
|
7925
|
+
const category = String((_a3 = record.fields[dimensionKey]) != null ? _a3 : "Other").trim() || "Other";
|
|
7799
7926
|
const value = measureKey ? (_b = this.toFiniteNumber(record.fields[measureKey])) != null ? _b : 0 : 1;
|
|
7800
7927
|
result[category] = ((_c = result[category]) != null ? _c : 0) + value;
|
|
7801
7928
|
});
|
|
@@ -7875,8 +8002,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7875
8002
|
static aggregateByCategory(data, categories) {
|
|
7876
8003
|
const result = Object.fromEntries(categories.map((c) => [c, 0]));
|
|
7877
8004
|
data.forEach((item) => {
|
|
7878
|
-
var
|
|
7879
|
-
const cat = (
|
|
8005
|
+
var _a3;
|
|
8006
|
+
const cat = (_a3 = this.getProductCategory(item)) != null ? _a3 : "Other";
|
|
7880
8007
|
if (Object.prototype.hasOwnProperty.call(result, cat)) result[cat]++;
|
|
7881
8008
|
else result["Other"] = (result["Other"] || 0) + 1;
|
|
7882
8009
|
});
|
|
@@ -7884,17 +8011,17 @@ ${schemaProfileText}` : ""}`;
|
|
|
7884
8011
|
}
|
|
7885
8012
|
static extractTimeSeriesData(data) {
|
|
7886
8013
|
return data.map((item) => {
|
|
7887
|
-
var
|
|
8014
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
7888
8015
|
const meta = item.metadata || {};
|
|
7889
8016
|
return {
|
|
7890
|
-
timestamp: (_b = (
|
|
8017
|
+
timestamp: (_b = (_a3 = meta.timestamp) != null ? _a3 : meta.date) != null ? _b : (/* @__PURE__ */ new Date()).toISOString(),
|
|
7891
8018
|
value: (_d = (_c = meta.value) != null ? _c : item.score) != null ? _d : 0,
|
|
7892
8019
|
label: (_f = meta.label) != null ? _f : ((_e = item == null ? void 0 : item.content) != null ? _e : "").substring(0, 50)
|
|
7893
8020
|
};
|
|
7894
8021
|
});
|
|
7895
8022
|
}
|
|
7896
8023
|
static extractNumericValue(meta) {
|
|
7897
|
-
var
|
|
8024
|
+
var _a3;
|
|
7898
8025
|
const preferredKeys = [
|
|
7899
8026
|
"value",
|
|
7900
8027
|
"count",
|
|
@@ -7909,7 +8036,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7909
8036
|
"price"
|
|
7910
8037
|
];
|
|
7911
8038
|
for (const key of preferredKeys) {
|
|
7912
|
-
const raw = (
|
|
8039
|
+
const raw = (_a3 = resolveMetadataValue(meta, key)) != null ? _a3 : meta[key];
|
|
7913
8040
|
const value = typeof raw === "number" ? raw : Number(String(raw != null ? raw : "").replace(/[$,% ,]/g, ""));
|
|
7914
8041
|
if (Number.isFinite(value)) return value;
|
|
7915
8042
|
}
|
|
@@ -8004,8 +8131,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
8004
8131
|
}, query.includes(normalizedField) ? 3 : 0);
|
|
8005
8132
|
}
|
|
8006
8133
|
static resolveTableCellValue(item, column) {
|
|
8007
|
-
var
|
|
8008
|
-
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);
|
|
8009
8136
|
const meta = item.metadata || {};
|
|
8010
8137
|
const normalizedColumn = this.normalizeComparableField(column);
|
|
8011
8138
|
const exactMetadata = Object.entries(meta).find(
|
|
@@ -8057,8 +8184,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
8057
8184
|
let inStock = 0;
|
|
8058
8185
|
let outOfStock = 0;
|
|
8059
8186
|
data.forEach((d) => {
|
|
8060
|
-
var
|
|
8061
|
-
const cat = (
|
|
8187
|
+
var _a3, _b;
|
|
8188
|
+
const cat = (_a3 = this.getProductCategory(d)) != null ? _a3 : "Other";
|
|
8062
8189
|
if (cat === category) {
|
|
8063
8190
|
const quantity = (_b = this.extractStockQuantity(d)) != null ? _b : 1;
|
|
8064
8191
|
if (this.determineStockStatus(d)) inStock += quantity;
|
|
@@ -8104,9 +8231,9 @@ ${schemaProfileText}` : ""}`;
|
|
|
8104
8231
|
}
|
|
8105
8232
|
// ─── Product Extraction ───────────────────────────────────────────────────
|
|
8106
8233
|
static getDynamicVal(meta, uiKey, config, trainedSchema) {
|
|
8107
|
-
var
|
|
8234
|
+
var _a3;
|
|
8108
8235
|
if (!meta) return void 0;
|
|
8109
|
-
const mapping = (
|
|
8236
|
+
const mapping = (_a3 = config == null ? void 0 : config.rag) == null ? void 0 : _a3.uiMapping;
|
|
8110
8237
|
if ((mapping == null ? void 0 : mapping[uiKey]) && meta[mapping[uiKey]] !== void 0) return meta[mapping[uiKey]];
|
|
8111
8238
|
if (trainedSchema && typeof trainedSchema === "object") {
|
|
8112
8239
|
const trainedKey = trainedSchema[uiKey];
|
|
@@ -8115,7 +8242,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
8115
8242
|
return resolveMetadataValue(meta, uiKey);
|
|
8116
8243
|
}
|
|
8117
8244
|
static extractProductInfo(item, config, trainedSchema) {
|
|
8118
|
-
var
|
|
8245
|
+
var _a3, _b;
|
|
8119
8246
|
if (!item) return null;
|
|
8120
8247
|
const meta = item.metadata || {};
|
|
8121
8248
|
const content = item.content || "";
|
|
@@ -8123,7 +8250,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
8123
8250
|
const price = this.getDynamicVal(meta, "price", config, trainedSchema);
|
|
8124
8251
|
const brand = this.getDynamicVal(meta, "brand", config, trainedSchema);
|
|
8125
8252
|
const description = this.cleanProductDescription(
|
|
8126
|
-
(
|
|
8253
|
+
(_a3 = this.extractProductDescriptionFromContent(content)) != null ? _a3 : this.getProductDescriptionValue(meta, config, trainedSchema)
|
|
8127
8254
|
);
|
|
8128
8255
|
if (name || this.isProductData(item)) {
|
|
8129
8256
|
let finalName = name ? String(name) : void 0;
|
|
@@ -8258,10 +8385,10 @@ RULES:
|
|
|
8258
8385
|
}
|
|
8259
8386
|
static buildContextSummary(sources, maxChars = 6e3) {
|
|
8260
8387
|
const items = (sources || []).filter(Boolean).map((s, i) => {
|
|
8261
|
-
var
|
|
8388
|
+
var _a3, _b, _c, _d;
|
|
8262
8389
|
return {
|
|
8263
8390
|
index: i + 1,
|
|
8264
|
-
content: (_b = (
|
|
8391
|
+
content: (_b = (_a3 = s == null ? void 0 : s.content) == null ? void 0 : _a3.substring(0, 400)) != null ? _b : "",
|
|
8265
8392
|
metadata: (_c = s == null ? void 0 : s.metadata) != null ? _c : {},
|
|
8266
8393
|
score: (_d = s == null ? void 0 : s.score) != null ? _d : 0
|
|
8267
8394
|
};
|
|
@@ -8301,7 +8428,7 @@ var SchemaMapper = class {
|
|
|
8301
8428
|
return promise;
|
|
8302
8429
|
}
|
|
8303
8430
|
static async _doTrain(llm, cacheKey, keys) {
|
|
8304
|
-
var
|
|
8431
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
|
|
8305
8432
|
console.log(`[SchemaMapper] \u{1F9E0} Training on new schema keys: ${keys.join(", ")}`);
|
|
8306
8433
|
const propertyList = Object.entries(this.TARGET_PROPERTIES).map(([prop, desc]) => `- ${prop} (${desc})`).join("\n");
|
|
8307
8434
|
const messages = [
|
|
@@ -8317,7 +8444,7 @@ Return a JSON object like {"name":"Title","price":"Price",...}. Omit unmapped pr
|
|
|
8317
8444
|
}
|
|
8318
8445
|
];
|
|
8319
8446
|
try {
|
|
8320
|
-
const baseUrl = (
|
|
8447
|
+
const baseUrl = (_a3 = llm == null ? void 0 : llm.baseUrl) != null ? _a3 : "";
|
|
8321
8448
|
const apiKey = (_b = llm == null ? void 0 : llm.apiKey) != null ? _b : "";
|
|
8322
8449
|
const model = (_c = llm == null ? void 0 : llm.model) != null ? _c : "llama-3.1-8b-instant";
|
|
8323
8450
|
let responseText;
|
|
@@ -8492,9 +8619,9 @@ var Pipeline = class {
|
|
|
8492
8619
|
this.initialised = false;
|
|
8493
8620
|
/** Namespace-specific static cold context cache for CAG */
|
|
8494
8621
|
this.coldContexts = /* @__PURE__ */ new Map();
|
|
8495
|
-
var
|
|
8622
|
+
var _a3, _b, _c, _d, _e;
|
|
8496
8623
|
this.chunker = new DocumentChunker(
|
|
8497
|
-
(_b = (
|
|
8624
|
+
(_b = (_a3 = config.rag) == null ? void 0 : _a3.chunkSize) != null ? _b : 1e3,
|
|
8498
8625
|
(_d = (_c = config.rag) == null ? void 0 : _c.chunkOverlap) != null ? _d : 200
|
|
8499
8626
|
);
|
|
8500
8627
|
if (((_e = config.rag) == null ? void 0 : _e.chunkingStrategy) === "llamaindex") {
|
|
@@ -8510,7 +8637,7 @@ var Pipeline = class {
|
|
|
8510
8637
|
return this.initialised ? this.llmProvider : void 0;
|
|
8511
8638
|
}
|
|
8512
8639
|
async initialize() {
|
|
8513
|
-
var
|
|
8640
|
+
var _a3, _b, _c, _d;
|
|
8514
8641
|
if (this.initialised) return;
|
|
8515
8642
|
const chartInstruction = `You are a helpful assistant. Use the provided context to answer questions accurately.
|
|
8516
8643
|
|
|
@@ -8553,7 +8680,7 @@ var Pipeline = class {
|
|
|
8553
8680
|
this.entityExtractor = new EntityExtractor(this.llmProvider);
|
|
8554
8681
|
}
|
|
8555
8682
|
await this.vectorDB.initialize();
|
|
8556
|
-
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) {
|
|
8557
8684
|
this.mcpRegistry = new MCPRegistry(this.config.mcpServers || []);
|
|
8558
8685
|
this.multiAgentCoordinator = new MultiAgentCoordinator({
|
|
8559
8686
|
llmProvider: this.llmProvider,
|
|
@@ -8571,8 +8698,8 @@ var Pipeline = class {
|
|
|
8571
8698
|
this.initialised = true;
|
|
8572
8699
|
}
|
|
8573
8700
|
async loadColdContext(ns) {
|
|
8574
|
-
var
|
|
8575
|
-
const cagConfig = (
|
|
8701
|
+
var _a3, _b;
|
|
8702
|
+
const cagConfig = (_a3 = this.config.rag) == null ? void 0 : _a3.cag;
|
|
8576
8703
|
if (!cagConfig || !cagConfig.enabled) return;
|
|
8577
8704
|
try {
|
|
8578
8705
|
const coldNs = cagConfig.coldNamespace || ns;
|
|
@@ -8625,12 +8752,12 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8625
8752
|
}
|
|
8626
8753
|
/** Step 1: Chunk the document content. */
|
|
8627
8754
|
async prepareChunks(doc) {
|
|
8628
|
-
var
|
|
8755
|
+
var _a3, _b;
|
|
8629
8756
|
if (this.llamaIngestor) {
|
|
8630
8757
|
return this.llamaIngestor.chunk(doc.content, {
|
|
8631
8758
|
docId: doc.docId,
|
|
8632
8759
|
metadata: doc.metadata,
|
|
8633
|
-
chunkSize: (
|
|
8760
|
+
chunkSize: (_a3 = this.config.rag) == null ? void 0 : _a3.chunkSize,
|
|
8634
8761
|
chunkOverlap: (_b = this.config.rag) == null ? void 0 : _b.chunkOverlap
|
|
8635
8762
|
});
|
|
8636
8763
|
}
|
|
@@ -8728,9 +8855,9 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8728
8855
|
return { reply, sources };
|
|
8729
8856
|
}
|
|
8730
8857
|
async ask(question, history = [], namespace) {
|
|
8731
|
-
var
|
|
8858
|
+
var _a3, _b;
|
|
8732
8859
|
await this.initialize();
|
|
8733
|
-
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) {
|
|
8734
8861
|
return await this.multiAgentCoordinator.run(question, history);
|
|
8735
8862
|
}
|
|
8736
8863
|
const stream = this.askStream(question, history, namespace);
|
|
@@ -8765,9 +8892,9 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8765
8892
|
}
|
|
8766
8893
|
askStream(_0) {
|
|
8767
8894
|
return __asyncGenerator(this, arguments, function* (question, history = [], namespace) {
|
|
8768
|
-
var
|
|
8895
|
+
var _a3, _b;
|
|
8769
8896
|
yield new __await(this.initialize());
|
|
8770
|
-
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) {
|
|
8771
8898
|
const stream2 = this.multiAgentCoordinator.runStream(question, history);
|
|
8772
8899
|
try {
|
|
8773
8900
|
for (var iter = __forAwait(stream2), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
|
|
@@ -8816,10 +8943,10 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8816
8943
|
*/
|
|
8817
8944
|
askStreamInternal(_0) {
|
|
8818
8945
|
return __asyncGenerator(this, arguments, function* (question, history = [], namespace) {
|
|
8819
|
-
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;
|
|
8820
8947
|
yield new __await(this.initialize());
|
|
8821
8948
|
const ns = formatNamespace(namespace != null ? namespace : this.config.projectId);
|
|
8822
|
-
const topK = (_b = (
|
|
8949
|
+
const topK = (_b = (_a3 = this.config.rag) == null ? void 0 : _a3.topK) != null ? _b : 5;
|
|
8823
8950
|
const scoreThreshold = (_d = (_c = this.config.rag) == null ? void 0 : _c.scoreThreshold) != null ? _d : 0.3;
|
|
8824
8951
|
const requestId = `req_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
8825
8952
|
const requestStart = performance.now();
|
|
@@ -8868,8 +8995,8 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8868
8995
|
const rerankStart = performance.now();
|
|
8869
8996
|
const structuredSources = this.applyStructuredFilters(rawSources, filter).filter((s) => Boolean(s && typeof s === "object"));
|
|
8870
8997
|
let fullSources = hasNumericPredicates ? structuredSources : structuredSources.filter((m) => {
|
|
8871
|
-
var
|
|
8872
|
-
return ((
|
|
8998
|
+
var _a4;
|
|
8999
|
+
return ((_a4 = m == null ? void 0 : m.score) != null ? _a4 : 0) >= scoreThreshold;
|
|
8873
9000
|
});
|
|
8874
9001
|
const rerankLimit = Math.max(retrievalLimit, fullSources.length);
|
|
8875
9002
|
const useReranking = arch !== "naive" && (arch === "retrieve-and-rerank" || ((_m = this.config.rag) == null ? void 0 : _m.useReranking));
|
|
@@ -8882,13 +9009,13 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8882
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]
|
|
8883
9010
|
|
|
8884
9011
|
` + promptSources.map((m, i) => {
|
|
8885
|
-
var
|
|
9012
|
+
var _a4;
|
|
8886
9013
|
return `[Source ${i + 1}]
|
|
8887
|
-
${(
|
|
9014
|
+
${(_a4 = m == null ? void 0 : m.content) != null ? _a4 : ""}`;
|
|
8888
9015
|
}).join("\n\n---\n\n") : "No relevant context found.";
|
|
8889
9016
|
const sources = [...fullSources].filter((s) => Boolean(s && typeof s === "object")).sort((a, b) => {
|
|
8890
|
-
var
|
|
8891
|
-
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);
|
|
8892
9019
|
});
|
|
8893
9020
|
if (graphData && graphData.nodes.length > 0) {
|
|
8894
9021
|
const graphContext = graphData.nodes.map(
|
|
@@ -8916,10 +9043,10 @@ ${context}`;
|
|
|
8916
9043
|
yield {
|
|
8917
9044
|
reply: "",
|
|
8918
9045
|
sources: (sources || []).filter((s) => Boolean(s && typeof s === "object")).map((s) => {
|
|
8919
|
-
var
|
|
9046
|
+
var _a4, _b2, _c2;
|
|
8920
9047
|
return {
|
|
8921
9048
|
id: s.id,
|
|
8922
|
-
score: (
|
|
9049
|
+
score: (_a4 = s.score) != null ? _a4 : 0,
|
|
8923
9050
|
content: (_b2 = s == null ? void 0 : s.content) != null ? _b2 : "",
|
|
8924
9051
|
metadata: (_c2 = s == null ? void 0 : s.metadata) != null ? _c2 : {},
|
|
8925
9052
|
namespace: ns
|
|
@@ -9112,11 +9239,11 @@ ${context}`;
|
|
|
9112
9239
|
systemPrompt,
|
|
9113
9240
|
userPrompt: question + finalRestrictionSuffix,
|
|
9114
9241
|
chunks: (sources || []).filter(Boolean).map((s) => {
|
|
9115
|
-
var
|
|
9242
|
+
var _a4, _b2;
|
|
9116
9243
|
return {
|
|
9117
9244
|
id: s.id,
|
|
9118
9245
|
score: s.score,
|
|
9119
|
-
content: (
|
|
9246
|
+
content: (_a4 = s == null ? void 0 : s.content) != null ? _a4 : "",
|
|
9120
9247
|
metadata: (_b2 = s == null ? void 0 : s.metadata) != null ? _b2 : {},
|
|
9121
9248
|
namespace: ns
|
|
9122
9249
|
};
|
|
@@ -9135,7 +9262,7 @@ ${context}`;
|
|
|
9135
9262
|
const telemetryUrl = ((_B = this.config.telemetry) == null ? void 0 : _B.url) || process.env.TELEMETRY_URL || process.env.NEXT_PUBLIC_TELEMETRY_URL || defaultUrl;
|
|
9136
9263
|
const absoluteUrl = telemetryUrl.startsWith("http") ? telemetryUrl : "https://www.retrivora.com" + (telemetryUrl.startsWith("/") ? telemetryUrl : "/" + telemetryUrl);
|
|
9137
9264
|
(async () => {
|
|
9138
|
-
var
|
|
9265
|
+
var _a4, _b2, _c2, _d2, _e2;
|
|
9139
9266
|
try {
|
|
9140
9267
|
let finalTrace = trace;
|
|
9141
9268
|
if (!awaitHallucination && runHallucination) {
|
|
@@ -9144,7 +9271,7 @@ ${context}`;
|
|
|
9144
9271
|
finalTrace = buildTrace(backgroundScoreResult);
|
|
9145
9272
|
}
|
|
9146
9273
|
}
|
|
9147
|
-
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";
|
|
9148
9275
|
const providerName = (finalTrace == null ? void 0 : finalTrace.provider) || ((_b2 = this.config.llm) == null ? void 0 : _b2.provider) || "groq";
|
|
9149
9276
|
const tokenCount = Number(((_c2 = finalTrace == null ? void 0 : finalTrace.tokens) == null ? void 0 : _c2.totalTokens) || 0);
|
|
9150
9277
|
const costEst = Number(((_d2 = finalTrace == null ? void 0 : finalTrace.tokens) == null ? void 0 : _d2.estimatedCostUsd) || 0);
|
|
@@ -9198,7 +9325,7 @@ ${context}`;
|
|
|
9198
9325
|
* Uses an LRU-bounded embedding cache to avoid re-embedding the same query.
|
|
9199
9326
|
*/
|
|
9200
9327
|
async generateUiTransformation(question, sources, cachedSchema, forceDeterministic = false) {
|
|
9201
|
-
var
|
|
9328
|
+
var _a3;
|
|
9202
9329
|
if (!sources || sources.length === 0) {
|
|
9203
9330
|
return UITransformer.transform(question, sources, this.config, cachedSchema);
|
|
9204
9331
|
}
|
|
@@ -9211,7 +9338,7 @@ ${context}`;
|
|
|
9211
9338
|
{ visualizationHint: "product_browse", recommendedChart: "text", filterInStockOnly: false, wantsExplicitTable: false, isTemporal: false, isComparison: false, language: "en" }
|
|
9212
9339
|
);
|
|
9213
9340
|
}
|
|
9214
|
-
const enableLlmUiTransform = ((
|
|
9341
|
+
const enableLlmUiTransform = ((_a3 = this.config.llm.options) == null ? void 0 : _a3.enableLlmUiTransform) === true;
|
|
9215
9342
|
if (forceDeterministic || !enableLlmUiTransform) {
|
|
9216
9343
|
return UITransformer.transform(question, sources, this.config, cachedSchema);
|
|
9217
9344
|
}
|
|
@@ -9229,15 +9356,15 @@ ${context}`;
|
|
|
9229
9356
|
const value = this.resolveNumericPredicateValue(source, predicate);
|
|
9230
9357
|
return value !== null && this.matchesNumericPredicate(value, predicate);
|
|
9231
9358
|
})).sort((a, b) => {
|
|
9232
|
-
var
|
|
9359
|
+
var _a3, _b;
|
|
9233
9360
|
const primary = predicates[0];
|
|
9234
|
-
const aValue = (
|
|
9361
|
+
const aValue = (_a3 = this.resolveNumericPredicateValue(a, primary)) != null ? _a3 : 0;
|
|
9235
9362
|
const bValue = (_b = this.resolveNumericPredicateValue(b, primary)) != null ? _b : 0;
|
|
9236
9363
|
return primary.operator === "lt" || primary.operator === "lte" ? aValue - bValue : bValue - aValue;
|
|
9237
9364
|
});
|
|
9238
9365
|
}
|
|
9239
9366
|
resolveNumericPredicateValue(source, predicate) {
|
|
9240
|
-
var
|
|
9367
|
+
var _a3;
|
|
9241
9368
|
if (!source) return null;
|
|
9242
9369
|
const meta = source.metadata || {};
|
|
9243
9370
|
const field = predicate.field;
|
|
@@ -9250,7 +9377,7 @@ ${context}`;
|
|
|
9250
9377
|
const value = this.toFiniteNumber(Array.isArray(fuzzy) ? fuzzy[1] : fuzzy.value);
|
|
9251
9378
|
if (value !== null) return value;
|
|
9252
9379
|
}
|
|
9253
|
-
const contentValue = this.extractNumericValueFromContent((
|
|
9380
|
+
const contentValue = this.extractNumericValueFromContent((_a3 = source.content) != null ? _a3 : "", field);
|
|
9254
9381
|
if (contentValue !== null) return contentValue;
|
|
9255
9382
|
}
|
|
9256
9383
|
for (const [key, value] of entries) {
|
|
@@ -9306,8 +9433,8 @@ ${context}`;
|
|
|
9306
9433
|
return Number.isFinite(numeric) ? numeric : null;
|
|
9307
9434
|
}
|
|
9308
9435
|
async retrieve(query, options) {
|
|
9309
|
-
var
|
|
9310
|
-
const ns = formatNamespace((
|
|
9436
|
+
var _a3, _b, _c, _d, _e, _f, _g2;
|
|
9437
|
+
const ns = formatNamespace((_a3 = options.namespace) != null ? _a3 : this.config.projectId);
|
|
9311
9438
|
const topK = (_b = options.topK) != null ? _b : 5;
|
|
9312
9439
|
const cacheKey = `${ns}::${query}`;
|
|
9313
9440
|
let queryVector = this.embeddingCache.get(cacheKey);
|
|
@@ -9352,11 +9479,11 @@ ${context}`;
|
|
|
9352
9479
|
namespace: ns,
|
|
9353
9480
|
count: resolvedSources.length,
|
|
9354
9481
|
sample: resolvedSources.slice(0, 2).map((s) => {
|
|
9355
|
-
var
|
|
9482
|
+
var _a4;
|
|
9356
9483
|
return {
|
|
9357
9484
|
id: s == null ? void 0 : s.id,
|
|
9358
9485
|
score: s == null ? void 0 : s.score,
|
|
9359
|
-
contentSnippet: String((
|
|
9486
|
+
contentSnippet: String((_a4 = s == null ? void 0 : s.content) != null ? _a4 : "").substring(0, 150),
|
|
9360
9487
|
metadata: s == null ? void 0 : s.metadata
|
|
9361
9488
|
};
|
|
9362
9489
|
})
|
|
@@ -9370,8 +9497,8 @@ Focus on extracting the core intent and entities. Do not answer the question, ju
|
|
|
9370
9497
|
|
|
9371
9498
|
History:
|
|
9372
9499
|
${(history || []).map((m) => {
|
|
9373
|
-
var
|
|
9374
|
-
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 : ""}`;
|
|
9375
9502
|
}).join("\n")}
|
|
9376
9503
|
|
|
9377
9504
|
New Question: ${question}
|
|
@@ -9398,8 +9525,8 @@ Optimized Search Query:`;
|
|
|
9398
9525
|
const { sources } = await this.retrieve(query, { namespace: ns, topK: 5 });
|
|
9399
9526
|
if (!sources || sources.length === 0) return [];
|
|
9400
9527
|
const context = sources.map((s) => {
|
|
9401
|
-
var
|
|
9402
|
-
return (
|
|
9528
|
+
var _a3;
|
|
9529
|
+
return (_a3 = s == null ? void 0 : s.content) != null ? _a3 : "";
|
|
9403
9530
|
}).join("\n\n---\n\n");
|
|
9404
9531
|
const prompt = `Based on the following snippets from a document, what are at least 5 short, relevant questions a user might ask?
|
|
9405
9532
|
Focus on questions that can be answered by the context.
|
|
@@ -9441,13 +9568,13 @@ var Retrivora = class {
|
|
|
9441
9568
|
this.pipeline = new Pipeline(this.config);
|
|
9442
9569
|
}
|
|
9443
9570
|
async initialize() {
|
|
9444
|
-
var
|
|
9571
|
+
var _a3;
|
|
9445
9572
|
try {
|
|
9446
9573
|
await ConfigValidator.validateAndThrow(this.config);
|
|
9447
9574
|
LicenseVerifier.verify(
|
|
9448
9575
|
this.config.licenseKey,
|
|
9449
9576
|
this.config.projectId,
|
|
9450
|
-
(
|
|
9577
|
+
(_a3 = this.config.vectorDb) == null ? void 0 : _a3.provider
|
|
9451
9578
|
);
|
|
9452
9579
|
await LicenseVerifier.verifyIP(this.config.licenseKey);
|
|
9453
9580
|
} catch (err) {
|
|
@@ -9620,18 +9747,200 @@ var ProviderHealthCheck = class {
|
|
|
9620
9747
|
}
|
|
9621
9748
|
};
|
|
9622
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
|
+
|
|
9623
9932
|
// src/core/VectorPlugin.ts
|
|
9624
9933
|
var VectorPlugin = class {
|
|
9625
9934
|
constructor(hostConfig) {
|
|
9626
9935
|
const resolvedConfig = ConfigResolver.resolve(hostConfig);
|
|
9627
9936
|
this.config = resolvedConfig;
|
|
9628
9937
|
this.validationPromise = (async () => {
|
|
9629
|
-
var
|
|
9938
|
+
var _a3;
|
|
9630
9939
|
await ConfigValidator.validateAndThrow(resolvedConfig);
|
|
9631
9940
|
LicenseVerifier.verify(
|
|
9632
9941
|
resolvedConfig.licenseKey,
|
|
9633
9942
|
resolvedConfig.projectId,
|
|
9634
|
-
(
|
|
9943
|
+
(_a3 = resolvedConfig.vectorDb) == null ? void 0 : _a3.provider
|
|
9635
9944
|
);
|
|
9636
9945
|
})();
|
|
9637
9946
|
this.validationPromise.catch(() => {
|
|
@@ -9665,16 +9974,32 @@ var VectorPlugin = class {
|
|
|
9665
9974
|
this.config.embedding
|
|
9666
9975
|
);
|
|
9667
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
|
+
}
|
|
9668
9984
|
/**
|
|
9669
9985
|
* Run a chat query.
|
|
9670
9986
|
*/
|
|
9671
9987
|
async chat(message, history = [], namespace) {
|
|
9988
|
+
var _a3;
|
|
9672
9989
|
try {
|
|
9673
9990
|
await this.validationPromise;
|
|
9674
9991
|
} catch (err) {
|
|
9675
9992
|
throw wrapError(err, "CONFIGURATION_ERROR");
|
|
9676
9993
|
}
|
|
9677
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
|
+
}
|
|
9678
10003
|
return await this.pipeline.ask(message, history, namespace);
|
|
9679
10004
|
} catch (err) {
|
|
9680
10005
|
const msg = String(err);
|
|
@@ -9682,6 +10007,9 @@ var VectorPlugin = class {
|
|
|
9682
10007
|
if (msg.includes("Embed") || msg.includes("embed")) {
|
|
9683
10008
|
defaultCode = "EMBEDDING_FAILED";
|
|
9684
10009
|
}
|
|
10010
|
+
if (msg.toLowerCase().includes("token limit")) {
|
|
10011
|
+
defaultCode = "RATE_LIMITED";
|
|
10012
|
+
}
|
|
9685
10013
|
throw wrapError(err, defaultCode);
|
|
9686
10014
|
}
|
|
9687
10015
|
}
|
|
@@ -9690,12 +10018,21 @@ var VectorPlugin = class {
|
|
|
9690
10018
|
*/
|
|
9691
10019
|
chatStream(_0) {
|
|
9692
10020
|
return __asyncGenerator(this, arguments, function* (message, history = [], namespace) {
|
|
10021
|
+
var _a3;
|
|
9693
10022
|
try {
|
|
9694
10023
|
yield new __await(this.validationPromise);
|
|
9695
10024
|
} catch (err) {
|
|
9696
10025
|
throw wrapError(err, "CONFIGURATION_ERROR");
|
|
9697
10026
|
}
|
|
9698
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
|
+
}
|
|
9699
10036
|
const stream = this.pipeline.askStream(message, history, namespace);
|
|
9700
10037
|
try {
|
|
9701
10038
|
for (var iter = __forAwait(stream), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
|
|
@@ -9718,6 +10055,9 @@ var VectorPlugin = class {
|
|
|
9718
10055
|
if (msg.includes("Embed") || msg.includes("embed")) {
|
|
9719
10056
|
defaultCode = "EMBEDDING_FAILED";
|
|
9720
10057
|
}
|
|
10058
|
+
if (msg.toLowerCase().includes("token limit")) {
|
|
10059
|
+
defaultCode = "RATE_LIMITED";
|
|
10060
|
+
}
|
|
9721
10061
|
throw wrapError(err, defaultCode);
|
|
9722
10062
|
}
|
|
9723
10063
|
});
|
|
@@ -9772,13 +10112,13 @@ var ConfigBuilder = class {
|
|
|
9772
10112
|
* Configure the vector database provider
|
|
9773
10113
|
*/
|
|
9774
10114
|
vectorDb(provider, options) {
|
|
9775
|
-
var
|
|
10115
|
+
var _a3;
|
|
9776
10116
|
if (provider === "auto") {
|
|
9777
10117
|
this._vectorDb = this._autoDetectVectorDb();
|
|
9778
10118
|
} else {
|
|
9779
10119
|
this._vectorDb = {
|
|
9780
10120
|
provider,
|
|
9781
|
-
indexName: (
|
|
10121
|
+
indexName: (_a3 = options == null ? void 0 : options.indexName) != null ? _a3 : "default",
|
|
9782
10122
|
options: __spreadValues({}, options)
|
|
9783
10123
|
};
|
|
9784
10124
|
}
|
|
@@ -9788,7 +10128,7 @@ var ConfigBuilder = class {
|
|
|
9788
10128
|
* Configure the LLM provider for chat
|
|
9789
10129
|
*/
|
|
9790
10130
|
llm(provider, model, apiKey, options) {
|
|
9791
|
-
var
|
|
10131
|
+
var _a3, _b;
|
|
9792
10132
|
if (provider === "auto") {
|
|
9793
10133
|
this._llm = this._autoDetectLLM();
|
|
9794
10134
|
} else {
|
|
@@ -9797,7 +10137,7 @@ var ConfigBuilder = class {
|
|
|
9797
10137
|
model: model != null ? model : "default-model",
|
|
9798
10138
|
apiKey,
|
|
9799
10139
|
systemPrompt: options == null ? void 0 : options.systemPrompt,
|
|
9800
|
-
maxTokens: (
|
|
10140
|
+
maxTokens: (_a3 = options == null ? void 0 : options.maxTokens) != null ? _a3 : 1024,
|
|
9801
10141
|
temperature: (_b = options == null ? void 0 : options.temperature) != null ? _b : 0.7,
|
|
9802
10142
|
baseUrl: options == null ? void 0 : options.baseUrl,
|
|
9803
10143
|
options
|
|
@@ -9840,8 +10180,8 @@ var ConfigBuilder = class {
|
|
|
9840
10180
|
* Set RAG-specific pipeline parameters
|
|
9841
10181
|
*/
|
|
9842
10182
|
rag(options) {
|
|
9843
|
-
var
|
|
9844
|
-
this._rag = __spreadValues(__spreadValues({}, (
|
|
10183
|
+
var _a3;
|
|
10184
|
+
this._rag = __spreadValues(__spreadValues({}, (_a3 = this._rag) != null ? _a3 : {}), options);
|
|
9845
10185
|
return this;
|
|
9846
10186
|
}
|
|
9847
10187
|
/**
|
|
@@ -9857,7 +10197,7 @@ var ConfigBuilder = class {
|
|
|
9857
10197
|
* Throws if required fields (projectId, vectorDb, llm, embedding) are not set.
|
|
9858
10198
|
*/
|
|
9859
10199
|
build() {
|
|
9860
|
-
var
|
|
10200
|
+
var _a3;
|
|
9861
10201
|
const missing = [];
|
|
9862
10202
|
if (!this._projectId) missing.push('projectId (call .projectId("my-app"))');
|
|
9863
10203
|
if (!this._vectorDb) missing.push('vectorDb (call .vectorDb("pinecone", { ... }))');
|
|
@@ -9869,7 +10209,7 @@ var ConfigBuilder = class {
|
|
|
9869
10209
|
${missing.join("\n ")}`
|
|
9870
10210
|
);
|
|
9871
10211
|
}
|
|
9872
|
-
const ragConfig = (
|
|
10212
|
+
const ragConfig = (_a3 = this._rag) != null ? _a3 : { chunkSize: 1e3, chunkOverlap: 200, topK: 5 };
|
|
9873
10213
|
if (process.env.RAG_USE_GRAPH_RETRIEVAL === "true") {
|
|
9874
10214
|
ragConfig.useGraphRetrieval = true;
|
|
9875
10215
|
}
|
|
@@ -9965,8 +10305,8 @@ var DocumentParser = class {
|
|
|
9965
10305
|
* Extract text from a File or Buffer based on its type.
|
|
9966
10306
|
*/
|
|
9967
10307
|
static async parse(file, fileName, mimeType) {
|
|
9968
|
-
var
|
|
9969
|
-
const extension = ((
|
|
10308
|
+
var _a3;
|
|
10309
|
+
const extension = ((_a3 = fileName.split(".").pop()) == null ? void 0 : _a3.toLowerCase()) || "";
|
|
9970
10310
|
if (extension === "txt" || extension === "md" || mimeType === "text/plain" || mimeType === "text/markdown") {
|
|
9971
10311
|
return this.readAsText(file);
|
|
9972
10312
|
}
|
|
@@ -10073,9 +10413,9 @@ var DatabaseStorage = class {
|
|
|
10073
10413
|
this.fallbackDir = this.isServerless ? path.join(os.tmpdir(), ".retrivora") : path.join(process.cwd(), ".retrivora");
|
|
10074
10414
|
this.historyFile = path.join(this.fallbackDir, "history.json");
|
|
10075
10415
|
this.feedbackFile = path.join(this.fallbackDir, "feedback.json");
|
|
10076
|
-
var
|
|
10416
|
+
var _a3, _b, _c, _d, _e;
|
|
10077
10417
|
this.config = config;
|
|
10078
|
-
this.provider = ((
|
|
10418
|
+
this.provider = ((_a3 = config.vectorDb) == null ? void 0 : _a3.provider) || "fs";
|
|
10079
10419
|
const rawHistoryTable = ((_c = (_b = config.rag) == null ? void 0 : _b.history) == null ? void 0 : _c.tableName) || "retrivora_history";
|
|
10080
10420
|
const rawFeedbackTable = ((_e = (_d = config.rag) == null ? void 0 : _d.feedback) == null ? void 0 : _e.tableName) || "retrivora_feedback";
|
|
10081
10421
|
this.historyTableName = rawHistoryTable.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
@@ -10110,16 +10450,16 @@ var DatabaseStorage = class {
|
|
|
10110
10450
|
}
|
|
10111
10451
|
}
|
|
10112
10452
|
checkHistoryEnabled() {
|
|
10113
|
-
var
|
|
10453
|
+
var _a3, _b;
|
|
10114
10454
|
this.checkPremiumSubscription();
|
|
10115
|
-
if (((_b = (
|
|
10455
|
+
if (((_b = (_a3 = this.config.rag) == null ? void 0 : _a3.history) == null ? void 0 : _b.enabled) === false) {
|
|
10116
10456
|
throw new Error("[Retrivora SDK] Chat History is disabled in RagConfig.");
|
|
10117
10457
|
}
|
|
10118
10458
|
}
|
|
10119
10459
|
checkFeedbackEnabled() {
|
|
10120
|
-
var
|
|
10460
|
+
var _a3, _b;
|
|
10121
10461
|
this.checkPremiumSubscription();
|
|
10122
|
-
if (((_b = (
|
|
10462
|
+
if (((_b = (_a3 = this.config.rag) == null ? void 0 : _a3.feedback) == null ? void 0 : _b.enabled) === false) {
|
|
10123
10463
|
throw new Error("[Retrivora SDK] User Feedback is disabled in RagConfig.");
|
|
10124
10464
|
}
|
|
10125
10465
|
}
|
|
@@ -10286,8 +10626,11 @@ var DatabaseStorage = class {
|
|
|
10286
10626
|
this.writeLocalFile(this.historyFile, history);
|
|
10287
10627
|
}
|
|
10288
10628
|
}
|
|
10289
|
-
async getHistory(sessionId) {
|
|
10629
|
+
async getHistory(sessionId, projectIds) {
|
|
10290
10630
|
this.checkHistoryEnabled();
|
|
10631
|
+
if (projectIds && projectIds.length > 0 && !this.sessionInScope(sessionId, projectIds)) {
|
|
10632
|
+
return [];
|
|
10633
|
+
}
|
|
10291
10634
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
10292
10635
|
const pool = await this.getPGPool();
|
|
10293
10636
|
const res = await pool.query(
|
|
@@ -10317,8 +10660,11 @@ var DatabaseStorage = class {
|
|
|
10317
10660
|
return history.filter((h) => h.session_id === sessionId).sort((a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime());
|
|
10318
10661
|
}
|
|
10319
10662
|
}
|
|
10320
|
-
async clearHistory(sessionId) {
|
|
10663
|
+
async clearHistory(sessionId, projectIds) {
|
|
10321
10664
|
this.checkHistoryEnabled();
|
|
10665
|
+
if (projectIds && projectIds.length > 0 && !this.sessionInScope(sessionId, projectIds)) {
|
|
10666
|
+
return;
|
|
10667
|
+
}
|
|
10322
10668
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
10323
10669
|
const pool = await this.getPGPool();
|
|
10324
10670
|
await pool.query(`DELETE FROM ${this.historyTableName} WHERE session_id = $1`, [sessionId]);
|
|
@@ -10337,21 +10683,36 @@ var DatabaseStorage = class {
|
|
|
10337
10683
|
this.writeLocalFile(this.feedbackFile, filteredFeedback);
|
|
10338
10684
|
}
|
|
10339
10685
|
}
|
|
10340
|
-
|
|
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) {
|
|
10341
10700
|
this.checkHistoryEnabled();
|
|
10701
|
+
let raw = [];
|
|
10342
10702
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
10343
10703
|
const pool = await this.getPGPool();
|
|
10344
10704
|
const res = await pool.query(`SELECT DISTINCT session_id FROM ${this.historyTableName}`);
|
|
10345
|
-
|
|
10705
|
+
raw = res.rows.map((r) => r.session_id);
|
|
10346
10706
|
} else if (this.provider === "mongodb") {
|
|
10347
10707
|
await this.getMongoClient();
|
|
10348
10708
|
const db = this.getMongoDb();
|
|
10349
|
-
|
|
10709
|
+
raw = await db.collection(this.historyTableName).distinct("session_id");
|
|
10350
10710
|
} else {
|
|
10351
10711
|
const history = this.readLocalFile(this.historyFile);
|
|
10352
|
-
|
|
10353
|
-
return Array.from(sessions);
|
|
10712
|
+
raw = Array.from(new Set(history.map((h) => h.session_id)));
|
|
10354
10713
|
}
|
|
10714
|
+
if (!projectIds || projectIds.length === 0) return raw;
|
|
10715
|
+
return raw.filter((sid) => this.sessionInScope(sid, projectIds));
|
|
10355
10716
|
}
|
|
10356
10717
|
// ─── Feedback Operations ──────────────────────────────────────────────────
|
|
10357
10718
|
async saveFeedback(feedback) {
|
|
@@ -10404,8 +10765,9 @@ var DatabaseStorage = class {
|
|
|
10404
10765
|
this.writeLocalFile(this.feedbackFile, list);
|
|
10405
10766
|
}
|
|
10406
10767
|
}
|
|
10407
|
-
async getFeedback(messageId) {
|
|
10768
|
+
async getFeedback(messageId, projectIds) {
|
|
10408
10769
|
this.checkFeedbackEnabled();
|
|
10770
|
+
let item = null;
|
|
10409
10771
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
10410
10772
|
const pool = await this.getPGPool();
|
|
10411
10773
|
const res = await pool.query(
|
|
@@ -10414,28 +10776,34 @@ var DatabaseStorage = class {
|
|
|
10414
10776
|
WHERE message_id = $1`,
|
|
10415
10777
|
[messageId]
|
|
10416
10778
|
);
|
|
10417
|
-
|
|
10779
|
+
item = res.rows[0] || null;
|
|
10418
10780
|
} else if (this.provider === "mongodb") {
|
|
10419
10781
|
await this.getMongoClient();
|
|
10420
10782
|
const db = this.getMongoDb();
|
|
10421
10783
|
const col = db.collection(this.feedbackTableName);
|
|
10422
|
-
const
|
|
10423
|
-
if (
|
|
10424
|
-
|
|
10425
|
-
|
|
10426
|
-
|
|
10427
|
-
|
|
10428
|
-
|
|
10429
|
-
|
|
10430
|
-
|
|
10431
|
-
|
|
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
|
+
}
|
|
10432
10795
|
} else {
|
|
10433
10796
|
const list = this.readLocalFile(this.feedbackFile);
|
|
10434
|
-
|
|
10797
|
+
item = list.find((f) => f.message_id === messageId) || null;
|
|
10435
10798
|
}
|
|
10799
|
+
if (item && projectIds && projectIds.length > 0) {
|
|
10800
|
+
return this.sessionInScope(item.sessionId, projectIds) ? item : null;
|
|
10801
|
+
}
|
|
10802
|
+
return item;
|
|
10436
10803
|
}
|
|
10437
|
-
async listFeedback() {
|
|
10804
|
+
async listFeedback(projectIds) {
|
|
10438
10805
|
this.checkFeedbackEnabled();
|
|
10806
|
+
let raw = [];
|
|
10439
10807
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
10440
10808
|
const pool = await this.getPGPool();
|
|
10441
10809
|
const res = await pool.query(
|
|
@@ -10443,13 +10811,13 @@ var DatabaseStorage = class {
|
|
|
10443
10811
|
FROM ${this.feedbackTableName}
|
|
10444
10812
|
ORDER BY created_at DESC`
|
|
10445
10813
|
);
|
|
10446
|
-
|
|
10814
|
+
raw = res.rows;
|
|
10447
10815
|
} else if (this.provider === "mongodb") {
|
|
10448
10816
|
await this.getMongoClient();
|
|
10449
10817
|
const db = this.getMongoDb();
|
|
10450
10818
|
const col = db.collection(this.feedbackTableName);
|
|
10451
10819
|
const items = await col.find({}).sort({ created_at: -1 }).toArray();
|
|
10452
|
-
|
|
10820
|
+
raw = items.map((item) => ({
|
|
10453
10821
|
id: item.id,
|
|
10454
10822
|
messageId: item.message_id,
|
|
10455
10823
|
sessionId: item.session_id,
|
|
@@ -10459,8 +10827,10 @@ var DatabaseStorage = class {
|
|
|
10459
10827
|
}));
|
|
10460
10828
|
} else {
|
|
10461
10829
|
const list = this.readLocalFile(this.feedbackFile);
|
|
10462
|
-
|
|
10830
|
+
raw = [...list].sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime());
|
|
10463
10831
|
}
|
|
10832
|
+
if (!projectIds || projectIds.length === 0) return raw;
|
|
10833
|
+
return raw.filter((f) => this.sessionInScope(f.sessionId, projectIds));
|
|
10464
10834
|
}
|
|
10465
10835
|
async disconnect() {
|
|
10466
10836
|
if (this.pgPool) {
|
|
@@ -10523,8 +10893,8 @@ var _g = global;
|
|
|
10523
10893
|
var _a;
|
|
10524
10894
|
var rateLimiter = (_a = _g.__retrivoraRateLimiter) != null ? _a : _g.__retrivoraRateLimiter = new RateLimiter(6e4, 30);
|
|
10525
10895
|
function getRateLimitKey(req) {
|
|
10526
|
-
var
|
|
10527
|
-
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";
|
|
10528
10898
|
return `ip:${ip}`;
|
|
10529
10899
|
}
|
|
10530
10900
|
function checkRateLimit(req) {
|
|
@@ -10546,6 +10916,66 @@ function checkRateLimit(req) {
|
|
|
10546
10916
|
}
|
|
10547
10917
|
return null;
|
|
10548
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
|
+
}
|
|
10549
10979
|
var MAX_MESSAGE_LENGTH = 8e3;
|
|
10550
10980
|
function sanitizeInput(raw) {
|
|
10551
10981
|
const stripped = raw.replace(/[\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F-\u009F]/g, "");
|
|
@@ -10567,7 +10997,7 @@ function getOrCreatePlugin(configOrPlugin) {
|
|
|
10567
10997
|
return _g[cacheKey];
|
|
10568
10998
|
}
|
|
10569
10999
|
function reportTelemetry(req, plugin, action, status, details, trace) {
|
|
10570
|
-
var
|
|
11000
|
+
var _a3, _b, _c, _d, _e, _f, _g2;
|
|
10571
11001
|
try {
|
|
10572
11002
|
const config = plugin.getConfig();
|
|
10573
11003
|
const licenseKey = config.licenseKey || process.env.RAG_LICENSE_KEY || process.env.RETRIVORA_LICENSE_KEY || process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY;
|
|
@@ -10582,7 +11012,7 @@ function reportTelemetry(req, plugin, action, status, details, trace) {
|
|
|
10582
11012
|
absoluteUrl = `${proto}://${host}${telemetryUrl}`;
|
|
10583
11013
|
}
|
|
10584
11014
|
const projectId = config.projectId || "default";
|
|
10585
|
-
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";
|
|
10586
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";
|
|
10587
11017
|
const tokens = Number(((_e = trace == null ? void 0 : trace.tokens) == null ? void 0 : _e.totalTokens) || (trace == null ? void 0 : trace.totalTokens) || 0);
|
|
10588
11018
|
const costUsd = Number(((_f = trace == null ? void 0 : trace.tokens) == null ? void 0 : _f.estimatedCostUsd) || (trace == null ? void 0 : trace.costUsd) || 0);
|
|
@@ -10606,7 +11036,6 @@ function reportTelemetry(req, plugin, action, status, details, trace) {
|
|
|
10606
11036
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
10607
11037
|
details
|
|
10608
11038
|
};
|
|
10609
|
-
console.log(`[Retrivora SDK Telemetry] Dispatching telemetry -> Feature: "${action}", Status: "${status}", Project: "${projectId}", Latency: ${latencyMs}ms`);
|
|
10610
11039
|
fetch(absoluteUrl, {
|
|
10611
11040
|
method: "POST",
|
|
10612
11041
|
headers: {
|
|
@@ -10664,14 +11093,39 @@ function createChatHandler(configOrPlugin, options) {
|
|
|
10664
11093
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
10665
11094
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
10666
11095
|
return async function POST(req, context) {
|
|
10667
|
-
var
|
|
11096
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
10668
11097
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10669
11098
|
if (authResult) return authResult;
|
|
10670
11099
|
const rateLimited = checkRateLimit(req);
|
|
10671
11100
|
if (rateLimited) return rateLimited;
|
|
11101
|
+
const config = plugin.getConfig();
|
|
10672
11102
|
try {
|
|
10673
11103
|
const body = await req.json();
|
|
10674
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
|
+
}
|
|
10675
11129
|
let rawMessage = bodyObj.message;
|
|
10676
11130
|
if (!rawMessage && Array.isArray(bodyObj.messages) && bodyObj.messages.length > 0) {
|
|
10677
11131
|
const lastMsg = bodyObj.messages[bodyObj.messages.length - 1];
|
|
@@ -10703,7 +11157,7 @@ function createChatHandler(configOrPlugin, options) {
|
|
|
10703
11157
|
uiTransformation: result.ui_transformation,
|
|
10704
11158
|
trace: result.trace
|
|
10705
11159
|
}).catch((err) => console.warn("[createChatHandler] Failed to save assistant message:", err));
|
|
10706
|
-
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);
|
|
10707
11161
|
return NextResponse.json(__spreadProps(__spreadValues({}, result), {
|
|
10708
11162
|
messageId: assistantMsgId,
|
|
10709
11163
|
userMessageId: userMsgId
|
|
@@ -10720,14 +11174,15 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10720
11174
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
10721
11175
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
10722
11176
|
return async function POST(req, context) {
|
|
10723
|
-
var
|
|
11177
|
+
var _a3, _b, _c;
|
|
10724
11178
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10725
11179
|
if (authResult) return authResult;
|
|
10726
11180
|
const rateLimited = checkRateLimit(req);
|
|
10727
11181
|
if (rateLimited) return rateLimited;
|
|
11182
|
+
const config = plugin.getConfig();
|
|
10728
11183
|
let body;
|
|
10729
11184
|
try {
|
|
10730
|
-
if ((
|
|
11185
|
+
if ((_a3 = req.headers.get("content-type")) == null ? void 0 : _a3.includes("multipart/form-data")) {
|
|
10731
11186
|
const uploader = createUploadHandler(plugin, { onAuthorize });
|
|
10732
11187
|
return uploader(req);
|
|
10733
11188
|
}
|
|
@@ -10739,6 +11194,30 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10739
11194
|
});
|
|
10740
11195
|
}
|
|
10741
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
|
+
}
|
|
10742
11221
|
let rawMessage = bodyObj.message;
|
|
10743
11222
|
if (!rawMessage && Array.isArray(bodyObj.messages) && bodyObj.messages.length > 0) {
|
|
10744
11223
|
const lastMsg = bodyObj.messages[bodyObj.messages.length - 1];
|
|
@@ -10768,7 +11247,7 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10768
11247
|
let isActive = true;
|
|
10769
11248
|
const stream = new ReadableStream({
|
|
10770
11249
|
async start(controller) {
|
|
10771
|
-
var
|
|
11250
|
+
var _a4, _b2, _c2, _d, _e;
|
|
10772
11251
|
const enqueue = (text) => {
|
|
10773
11252
|
if (!isActive) return;
|
|
10774
11253
|
try {
|
|
@@ -10801,7 +11280,7 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10801
11280
|
let uiTransformation = responseChunk == null ? void 0 : responseChunk.ui_transformation;
|
|
10802
11281
|
if (sources.length > 0) {
|
|
10803
11282
|
try {
|
|
10804
|
-
uiTransformation = (
|
|
11283
|
+
uiTransformation = (_a4 = responseChunk == null ? void 0 : responseChunk.ui_transformation) != null ? _a4 : UITransformer.transform(message, sources, plugin.getConfig());
|
|
10805
11284
|
if (uiTransformation) {
|
|
10806
11285
|
enqueue(sseUIFrame(uiTransformation));
|
|
10807
11286
|
}
|
|
@@ -10825,7 +11304,7 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10825
11304
|
uiTransformation,
|
|
10826
11305
|
trace: responseChunk == null ? void 0 : responseChunk.trace
|
|
10827
11306
|
}).catch((err) => console.warn("[createStreamHandler] Failed to save assistant message:", err));
|
|
10828
|
-
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);
|
|
10829
11308
|
}
|
|
10830
11309
|
}
|
|
10831
11310
|
} catch (temp) {
|
|
@@ -10875,12 +11354,36 @@ function createIngestHandler(configOrPlugin, options) {
|
|
|
10875
11354
|
return async function POST(req, context) {
|
|
10876
11355
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10877
11356
|
if (authResult) return authResult;
|
|
11357
|
+
const config = plugin.getConfig();
|
|
10878
11358
|
try {
|
|
10879
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;
|
|
10880
11362
|
const { documents, namespace } = body;
|
|
10881
11363
|
if (!Array.isArray(documents) || documents.length === 0) {
|
|
10882
11364
|
return NextResponse.json({ error: "documents array is required" }, { status: 400 });
|
|
10883
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
|
+
}
|
|
10884
11387
|
const results = await plugin.ingest(documents, namespace);
|
|
10885
11388
|
reportTelemetry(req, plugin, "DOCUMENT_INGESTION", "success", `Ingested ${documents.length} document(s)`);
|
|
10886
11389
|
return NextResponse.json({ results });
|
|
@@ -10917,7 +11420,7 @@ function createLicenseHandler(configOrPlugin, options) {
|
|
|
10917
11420
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
10918
11421
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
10919
11422
|
return async function POST(req) {
|
|
10920
|
-
var
|
|
11423
|
+
var _a3;
|
|
10921
11424
|
if (req) {
|
|
10922
11425
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10923
11426
|
if (authResult) return authResult;
|
|
@@ -10925,7 +11428,7 @@ function createLicenseHandler(configOrPlugin, options) {
|
|
|
10925
11428
|
try {
|
|
10926
11429
|
const body = await req.json().catch(() => ({}));
|
|
10927
11430
|
const config = plugin.getConfig();
|
|
10928
|
-
const rawKey = req.headers.get("x-license-key") || (body == null ? void 0 : body.licenseKey) || ((
|
|
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 || "";
|
|
10929
11432
|
const licenseKey = (rawKey || "").trim().replace(/^["']|["']$/g, "").trim();
|
|
10930
11433
|
const projectId = (body == null ? void 0 : body.projectId) || config.projectId || "my-rag-app";
|
|
10931
11434
|
const payload = LicenseVerifier.verify(licenseKey, projectId);
|
|
@@ -10960,6 +11463,9 @@ function createUploadHandler(configOrPlugin, options) {
|
|
|
10960
11463
|
return async function POST(req, context) {
|
|
10961
11464
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10962
11465
|
if (authResult) return authResult;
|
|
11466
|
+
const config = plugin.getConfig();
|
|
11467
|
+
const licenseCheck = enforceLicense(req, config);
|
|
11468
|
+
if (!licenseCheck.ok) return licenseCheck.response;
|
|
10963
11469
|
try {
|
|
10964
11470
|
const formData = await req.formData();
|
|
10965
11471
|
const files = formData.getAll("files");
|
|
@@ -10969,6 +11475,26 @@ function createUploadHandler(configOrPlugin, options) {
|
|
|
10969
11475
|
if (!files || files.length === 0) {
|
|
10970
11476
|
return NextResponse.json({ error: "No files provided" }, { status: 400 });
|
|
10971
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
|
+
}
|
|
10972
11498
|
const documents = [];
|
|
10973
11499
|
for (const file of files) {
|
|
10974
11500
|
const isExcel = file.name.toLowerCase().endsWith(".xlsx") || file.name.toLowerCase().endsWith(".xls") || file.type.includes("spreadsheet") || file.type.includes("excel");
|
|
@@ -11078,13 +11604,22 @@ function createSuggestionsHandler(configOrPlugin, options) {
|
|
|
11078
11604
|
return async function handler(req) {
|
|
11079
11605
|
const authResult = await checkAuth(req, onAuthorize);
|
|
11080
11606
|
if (authResult) return authResult;
|
|
11607
|
+
const config = plugin.getConfig();
|
|
11608
|
+
const licenseCheck = enforceLicense(req, config);
|
|
11609
|
+
if (!licenseCheck.ok) return licenseCheck.response;
|
|
11081
11610
|
try {
|
|
11082
11611
|
let query = "";
|
|
11083
11612
|
let namespace = void 0;
|
|
11613
|
+
let bodyLicenseKey = void 0;
|
|
11084
11614
|
if (req.method === "POST") {
|
|
11085
11615
|
const body = await req.json().catch(() => ({}));
|
|
11086
11616
|
query = body.query || "";
|
|
11087
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
|
+
}
|
|
11088
11623
|
} else {
|
|
11089
11624
|
const url = new URL(req.url);
|
|
11090
11625
|
query = url.searchParams.get("query") || "";
|
|
@@ -11107,14 +11642,16 @@ function createHistoryHandler(configOrPlugin, options) {
|
|
|
11107
11642
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
11108
11643
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
11109
11644
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
11645
|
+
const onResolveScope = options == null ? void 0 : options.onResolveScope;
|
|
11110
11646
|
return async function handler(req) {
|
|
11111
11647
|
const authResult = await checkAuth(req, onAuthorize);
|
|
11112
11648
|
if (authResult) return authResult;
|
|
11649
|
+
const scope = onResolveScope ? await onResolveScope(req) : void 0;
|
|
11113
11650
|
const url = new URL(req.url);
|
|
11114
11651
|
const sessionId = url.searchParams.get("sessionId") || "default";
|
|
11115
11652
|
if (req.method === "GET") {
|
|
11116
11653
|
try {
|
|
11117
|
-
const history = await storage.getHistory(sessionId);
|
|
11654
|
+
const history = await storage.getHistory(sessionId, scope);
|
|
11118
11655
|
return NextResponse.json({ history });
|
|
11119
11656
|
} catch (err) {
|
|
11120
11657
|
const message = err instanceof Error ? err.message : "Failed to fetch history";
|
|
@@ -11124,7 +11661,7 @@ function createHistoryHandler(configOrPlugin, options) {
|
|
|
11124
11661
|
try {
|
|
11125
11662
|
const body = await req.json().catch(() => ({}));
|
|
11126
11663
|
const sid = body.sessionId || sessionId;
|
|
11127
|
-
await storage.clearHistory(sid);
|
|
11664
|
+
await storage.clearHistory(sid, scope);
|
|
11128
11665
|
return NextResponse.json({ success: true });
|
|
11129
11666
|
} catch (err) {
|
|
11130
11667
|
const message = err instanceof Error ? err.message : "Failed to clear history";
|
|
@@ -11138,18 +11675,20 @@ function createFeedbackHandler(configOrPlugin, options) {
|
|
|
11138
11675
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
11139
11676
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
11140
11677
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
11678
|
+
const onResolveScope = options == null ? void 0 : options.onResolveScope;
|
|
11141
11679
|
return async function handler(req) {
|
|
11142
11680
|
const authResult = await checkAuth(req, onAuthorize);
|
|
11143
11681
|
if (authResult) return authResult;
|
|
11682
|
+
const scope = onResolveScope ? await onResolveScope(req) : void 0;
|
|
11144
11683
|
if (req.method === "GET") {
|
|
11145
11684
|
try {
|
|
11146
11685
|
const url = new URL(req.url);
|
|
11147
11686
|
const messageId = url.searchParams.get("messageId");
|
|
11148
11687
|
if (!messageId) {
|
|
11149
|
-
const feedbackList = await storage.listFeedback();
|
|
11688
|
+
const feedbackList = await storage.listFeedback(scope);
|
|
11150
11689
|
return NextResponse.json({ feedback: feedbackList });
|
|
11151
11690
|
}
|
|
11152
|
-
const feedback = await storage.getFeedback(messageId);
|
|
11691
|
+
const feedback = await storage.getFeedback(messageId, scope);
|
|
11153
11692
|
return NextResponse.json({ feedback });
|
|
11154
11693
|
} catch (err) {
|
|
11155
11694
|
const message = err instanceof Error ? err.message : "Failed to fetch feedback";
|
|
@@ -11165,6 +11704,17 @@ function createFeedbackHandler(configOrPlugin, options) {
|
|
|
11165
11704
|
if (!rating) {
|
|
11166
11705
|
return NextResponse.json({ error: "rating is required" }, { status: 400 });
|
|
11167
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
|
+
}
|
|
11168
11718
|
await storage.saveFeedback({ messageId, sessionId, rating, comment });
|
|
11169
11719
|
return NextResponse.json({ success: true });
|
|
11170
11720
|
} catch (err) {
|
|
@@ -11179,14 +11729,15 @@ function createSessionsHandler(configOrPlugin, options) {
|
|
|
11179
11729
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
11180
11730
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
11181
11731
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
11732
|
+
const onResolveScope = options == null ? void 0 : options.onResolveScope;
|
|
11182
11733
|
return async function GET(req) {
|
|
11183
11734
|
if (req) {
|
|
11184
11735
|
const authResult = await checkAuth(req, onAuthorize);
|
|
11185
11736
|
if (authResult) return authResult;
|
|
11186
11737
|
}
|
|
11187
|
-
void req;
|
|
11188
11738
|
try {
|
|
11189
|
-
const
|
|
11739
|
+
const scope = req && onResolveScope ? await onResolveScope(req) : void 0;
|
|
11740
|
+
const sessions = await storage.listSessions(scope);
|
|
11190
11741
|
return NextResponse.json({ sessions });
|
|
11191
11742
|
} catch (err) {
|
|
11192
11743
|
const message = err instanceof Error ? err.message : "Failed to list sessions";
|
|
@@ -11197,15 +11748,17 @@ function createSessionsHandler(configOrPlugin, options) {
|
|
|
11197
11748
|
function createRagHandler(configOrPlugin, options) {
|
|
11198
11749
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
11199
11750
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
11200
|
-
const
|
|
11201
|
-
const
|
|
11202
|
-
const
|
|
11203
|
-
const
|
|
11204
|
-
const
|
|
11205
|
-
const
|
|
11206
|
-
const
|
|
11207
|
-
const
|
|
11208
|
-
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);
|
|
11209
11762
|
async function routePostRequest(req, segment) {
|
|
11210
11763
|
switch (segment) {
|
|
11211
11764
|
case "chat":
|
|
@@ -11247,7 +11800,7 @@ function createRagHandler(configOrPlugin, options) {
|
|
|
11247
11800
|
}
|
|
11248
11801
|
}
|
|
11249
11802
|
async function getSegment(req, context) {
|
|
11250
|
-
var
|
|
11803
|
+
var _a3, _b;
|
|
11251
11804
|
const contentType = req.headers.get("content-type") || "";
|
|
11252
11805
|
if (contentType.includes("multipart/form-data")) {
|
|
11253
11806
|
return "upload";
|
|
@@ -11264,7 +11817,7 @@ function createRagHandler(configOrPlugin, options) {
|
|
|
11264
11817
|
if (pathname.endsWith("/history")) return "history";
|
|
11265
11818
|
} catch (e) {
|
|
11266
11819
|
}
|
|
11267
|
-
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;
|
|
11268
11821
|
const segments = (resolvedParams == null ? void 0 : resolvedParams.retrivora) || ((_b = resolvedParams == null ? void 0 : resolvedParams.params) == null ? void 0 : _b.retrivora) || [];
|
|
11269
11822
|
const joined = segments.join("/");
|
|
11270
11823
|
return joined || "chat";
|
|
@@ -11297,6 +11850,7 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
11297
11850
|
constructor() {
|
|
11298
11851
|
this.cache = /* @__PURE__ */ new Map();
|
|
11299
11852
|
}
|
|
11853
|
+
/** @returns Singleton instance of the validator (shared cache across all consumers). */
|
|
11300
11854
|
static getInstance() {
|
|
11301
11855
|
if (!_LicenseValidator.instance) {
|
|
11302
11856
|
_LicenseValidator.instance = new _LicenseValidator();
|
|
@@ -11304,7 +11858,12 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
11304
11858
|
return _LicenseValidator.instance;
|
|
11305
11859
|
}
|
|
11306
11860
|
/**
|
|
11307
|
-
*
|
|
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.
|
|
11308
11867
|
*/
|
|
11309
11868
|
purgeCache(licenseKey) {
|
|
11310
11869
|
if (licenseKey) {
|
|
@@ -11314,10 +11873,20 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
11314
11873
|
}
|
|
11315
11874
|
}
|
|
11316
11875
|
/**
|
|
11317
|
-
*
|
|
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.
|
|
11318
11887
|
*/
|
|
11319
11888
|
async validate(request) {
|
|
11320
|
-
var
|
|
11889
|
+
var _a3;
|
|
11321
11890
|
const {
|
|
11322
11891
|
licenseKey,
|
|
11323
11892
|
projectId,
|
|
@@ -11335,7 +11904,7 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
11335
11904
|
}
|
|
11336
11905
|
return void 0;
|
|
11337
11906
|
};
|
|
11338
|
-
const rawKey = licenseKey || getHeader("x-license-key") || ((
|
|
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 : "") || "";
|
|
11339
11908
|
const effectiveLicenseKey = (rawKey || "").trim().replace(/^["']|["']$/g, "").trim();
|
|
11340
11909
|
if (!effectiveLicenseKey) {
|
|
11341
11910
|
this.purgeCache(effectiveLicenseKey);
|