@retrivora-ai/rag-engine 2.2.9 → 2.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{LicenseValidator-CENvo9o2.d.mts → BatchProcessor-7yV-UCHW.d.mts} +142 -3
- package/dist/{LicenseValidator-CsjJp2PP.d.ts → BatchProcessor-BfzuU4cK.d.ts} +142 -3
- package/dist/handlers/index.d.mts +1 -1
- package/dist/handlers/index.d.ts +1 -1
- package/dist/handlers/index.js +883 -328
- package/dist/handlers/index.mjs +883 -328
- package/dist/index-DR_O_B-W.d.ts +394 -0
- package/dist/index-fnpaCuma.d.mts +394 -0
- package/dist/index.css +58 -0
- package/dist/index.d.mts +63 -3
- package/dist/index.d.ts +63 -3
- package/dist/index.js +456 -37
- package/dist/index.mjs +455 -39
- package/dist/server.d.mts +35 -73
- package/dist/server.d.ts +35 -73
- package/dist/server.js +914 -342
- package/dist/server.mjs +914 -342
- package/package.json +1 -1
- package/src/components/ChatWidget.tsx +147 -46
- package/src/components/ChatWindow.tsx +52 -8
- package/src/core/BatchProcessor.ts +42 -4
- package/src/core/CircuitBreaker.ts +118 -0
- package/src/core/DatabaseStorage.ts +55 -24
- package/src/core/FreeTierLimitsGuard.ts +281 -0
- package/src/core/LicenseValidator.ts +69 -3
- package/src/core/LicenseVerifier.ts +43 -14
- package/src/core/VectorPlugin.ts +30 -0
- package/src/handlers/index.ts +495 -38
- package/src/index.css +58 -0
- package/src/index.ts +4 -0
- package/src/server.ts +1 -0
- package/dist/index-BPJ3KDYI.d.ts +0 -195
- package/dist/index-Dmq5lH0j.d.mts +0 -195
package/dist/server.js
CHANGED
|
@@ -165,7 +165,7 @@ var init_ConfigFetcher = __esm({
|
|
|
165
165
|
* Fetch full project configuration (vectorDb + embedding + llm) from Retrivora Control Plane.
|
|
166
166
|
*/
|
|
167
167
|
static async fetchRemoteConfig(projectId, licenseKey) {
|
|
168
|
-
var
|
|
168
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
|
|
169
169
|
const cacheKey = `${projectId}:${licenseKey || ""}`;
|
|
170
170
|
const now = Date.now();
|
|
171
171
|
const cached = this.cache.get(cacheKey);
|
|
@@ -191,7 +191,7 @@ var init_ConfigFetcher = __esm({
|
|
|
191
191
|
});
|
|
192
192
|
if (res.ok) {
|
|
193
193
|
const data = await res.json();
|
|
194
|
-
if ((data == null ? void 0 : data.success) && ((
|
|
194
|
+
if ((data == null ? void 0 : data.success) && ((_a3 = data == null ? void 0 : data.vectorDb) == null ? void 0 : _a3.apiKey)) {
|
|
195
195
|
const fetchedProjectId = data.projectId || projectId;
|
|
196
196
|
const config = {
|
|
197
197
|
projectId: fetchedProjectId,
|
|
@@ -227,9 +227,9 @@ var init_ConfigFetcher = __esm({
|
|
|
227
227
|
}
|
|
228
228
|
/** Convenience: fetch only vector DB config (backwards compat). */
|
|
229
229
|
static async fetchRemoteVectorConfig(projectId, licenseKey) {
|
|
230
|
-
var
|
|
230
|
+
var _a3;
|
|
231
231
|
const config = await this.fetchRemoteConfig(projectId, licenseKey);
|
|
232
|
-
return (
|
|
232
|
+
return (_a3 = config == null ? void 0 : config.vectorDb) != null ? _a3 : null;
|
|
233
233
|
}
|
|
234
234
|
};
|
|
235
235
|
ConfigFetcher.cache = /* @__PURE__ */ new Map();
|
|
@@ -278,7 +278,7 @@ var init_PineconeProvider = __esm({
|
|
|
278
278
|
static getHealthChecker() {
|
|
279
279
|
return {
|
|
280
280
|
async check(config) {
|
|
281
|
-
var
|
|
281
|
+
var _a3, _b;
|
|
282
282
|
const opts = config.options || {};
|
|
283
283
|
const indexName = config.indexName;
|
|
284
284
|
const timestamp = Date.now();
|
|
@@ -286,7 +286,7 @@ var init_PineconeProvider = __esm({
|
|
|
286
286
|
const { Pinecone: Pinecone2 } = await import("@pinecone-database/pinecone");
|
|
287
287
|
const client = new Pinecone2({ apiKey: opts.apiKey });
|
|
288
288
|
const indexes = await client.listIndexes();
|
|
289
|
-
const indexNames = (_b = (
|
|
289
|
+
const indexNames = (_b = (_a3 = indexes.indexes) == null ? void 0 : _a3.map((i) => i.name)) != null ? _b : [];
|
|
290
290
|
if (!indexNames.includes(indexName)) {
|
|
291
291
|
return {
|
|
292
292
|
healthy: false,
|
|
@@ -313,7 +313,7 @@ var init_PineconeProvider = __esm({
|
|
|
313
313
|
};
|
|
314
314
|
}
|
|
315
315
|
async initialize() {
|
|
316
|
-
var
|
|
316
|
+
var _a3, _b;
|
|
317
317
|
if (this.client) return;
|
|
318
318
|
let key = this.apiKey || process.env.PINECONE_API_KEY || "";
|
|
319
319
|
if (!key) {
|
|
@@ -350,7 +350,7 @@ var init_PineconeProvider = __esm({
|
|
|
350
350
|
this.client = new import_pinecone.Pinecone({ apiKey: key });
|
|
351
351
|
try {
|
|
352
352
|
const indexes = await this.client.listIndexes();
|
|
353
|
-
const names = (_b = (
|
|
353
|
+
const names = (_b = (_a3 = indexes.indexes) == null ? void 0 : _a3.map((i) => i.name)) != null ? _b : [];
|
|
354
354
|
if (!names.includes(this.indexName)) {
|
|
355
355
|
console.warn(`[PineconeProvider] Target index "${this.indexName}" not listed. Proceeding with configured index name.`);
|
|
356
356
|
}
|
|
@@ -369,13 +369,13 @@ var init_PineconeProvider = __esm({
|
|
|
369
369
|
return namespace ? idx.namespace(namespace) : idx.namespace("");
|
|
370
370
|
}
|
|
371
371
|
async upsert(doc, namespace) {
|
|
372
|
-
var
|
|
372
|
+
var _a3;
|
|
373
373
|
const targetIdx = await this.getActiveIndex(namespace);
|
|
374
374
|
await targetIdx.upsert({
|
|
375
375
|
records: [{
|
|
376
376
|
id: String(doc.id),
|
|
377
377
|
values: doc.vector,
|
|
378
|
-
metadata: __spreadValues({ content: doc.content }, (
|
|
378
|
+
metadata: __spreadValues({ content: doc.content }, (_a3 = doc.metadata) != null ? _a3 : {})
|
|
379
379
|
}]
|
|
380
380
|
});
|
|
381
381
|
}
|
|
@@ -384,18 +384,18 @@ var init_PineconeProvider = __esm({
|
|
|
384
384
|
const BATCH = 100;
|
|
385
385
|
for (let i = 0; i < docs.length; i += BATCH) {
|
|
386
386
|
const records = docs.slice(i, i + BATCH).map((d) => {
|
|
387
|
-
var
|
|
387
|
+
var _a3;
|
|
388
388
|
return {
|
|
389
389
|
id: String(d.id),
|
|
390
390
|
values: d.vector,
|
|
391
|
-
metadata: __spreadValues({ content: d.content }, (
|
|
391
|
+
metadata: __spreadValues({ content: d.content }, (_a3 = d.metadata) != null ? _a3 : {})
|
|
392
392
|
};
|
|
393
393
|
});
|
|
394
394
|
await targetIdx.upsert({ records });
|
|
395
395
|
}
|
|
396
396
|
}
|
|
397
397
|
async query(vector, topK, namespace, filter) {
|
|
398
|
-
var
|
|
398
|
+
var _a3;
|
|
399
399
|
const targetIdx = await this.getActiveIndex(namespace);
|
|
400
400
|
const pineconeFilter = this.sanitizeFilter(filter);
|
|
401
401
|
const result = await targetIdx.query(__spreadValues({
|
|
@@ -403,11 +403,11 @@ var init_PineconeProvider = __esm({
|
|
|
403
403
|
topK,
|
|
404
404
|
includeMetadata: true
|
|
405
405
|
}, Object.keys(pineconeFilter).length > 0 ? { filter: pineconeFilter } : {}));
|
|
406
|
-
return ((
|
|
407
|
-
var
|
|
406
|
+
return ((_a3 = result.matches) != null ? _a3 : []).map((m) => {
|
|
407
|
+
var _a4, _b;
|
|
408
408
|
return {
|
|
409
409
|
id: m.id,
|
|
410
|
-
score: (
|
|
410
|
+
score: (_a4 = m.score) != null ? _a4 : 0,
|
|
411
411
|
content: ((_b = m.metadata) == null ? void 0 : _b.content) || "",
|
|
412
412
|
metadata: m.metadata
|
|
413
413
|
};
|
|
@@ -450,13 +450,13 @@ var init_PostgreSQLProvider = __esm({
|
|
|
450
450
|
init_BaseVectorProvider();
|
|
451
451
|
PostgreSQLProvider = class extends BaseVectorProvider {
|
|
452
452
|
constructor(config) {
|
|
453
|
-
var
|
|
453
|
+
var _a3;
|
|
454
454
|
super(config);
|
|
455
455
|
this.tableName = this.indexName.replace(/[^a-z0-9_]/gi, "_");
|
|
456
456
|
const opts = config.options;
|
|
457
457
|
if (!opts.connectionString) throw new Error("[PostgreSQLProvider] options.connectionString is required");
|
|
458
458
|
this.connectionString = opts.connectionString;
|
|
459
|
-
this.dimensions = (
|
|
459
|
+
this.dimensions = (_a3 = opts.dimensions) != null ? _a3 : 1536;
|
|
460
460
|
}
|
|
461
461
|
static getValidator() {
|
|
462
462
|
return {
|
|
@@ -537,7 +537,7 @@ var init_PostgreSQLProvider = __esm({
|
|
|
537
537
|
}
|
|
538
538
|
}
|
|
539
539
|
async upsert(doc, namespace = "") {
|
|
540
|
-
var
|
|
540
|
+
var _a3;
|
|
541
541
|
const vectorLiteral = `[${doc.vector.join(",")}]`;
|
|
542
542
|
await this.pool.query(
|
|
543
543
|
`INSERT INTO ${this.tableName} (id, namespace, content, metadata, embedding)
|
|
@@ -547,7 +547,7 @@ var init_PostgreSQLProvider = __esm({
|
|
|
547
547
|
content = EXCLUDED.content,
|
|
548
548
|
metadata = EXCLUDED.metadata,
|
|
549
549
|
embedding = EXCLUDED.embedding`,
|
|
550
|
-
[doc.id, namespace, doc.content, JSON.stringify((
|
|
550
|
+
[doc.id, namespace, doc.content, JSON.stringify((_a3 = doc.metadata) != null ? _a3 : {}), vectorLiteral]
|
|
551
551
|
);
|
|
552
552
|
}
|
|
553
553
|
async batchUpsert(docs, namespace = "") {
|
|
@@ -560,9 +560,9 @@ var init_PostgreSQLProvider = __esm({
|
|
|
560
560
|
const batch = docs.slice(i, i + BATCH_SIZE);
|
|
561
561
|
const values = [];
|
|
562
562
|
const valuePlaceholders = batch.map((doc, idx) => {
|
|
563
|
-
var
|
|
563
|
+
var _a3;
|
|
564
564
|
const offset = idx * 5;
|
|
565
|
-
values.push(doc.id, namespace, doc.content, JSON.stringify((
|
|
565
|
+
values.push(doc.id, namespace, doc.content, JSON.stringify((_a3 = doc.metadata) != null ? _a3 : {}), `[${doc.vector.join(",")}]`);
|
|
566
566
|
return `($${offset + 1}, $${offset + 2}, $${offset + 3}, $${offset + 4}, $${offset + 5}::vector)`;
|
|
567
567
|
}).join(", ");
|
|
568
568
|
const query = `
|
|
@@ -645,8 +645,8 @@ var init_PostgreSQLProvider = __esm({
|
|
|
645
645
|
|
|
646
646
|
// src/utils/synonyms.ts
|
|
647
647
|
function resolveMetadataValue(meta, uiKey) {
|
|
648
|
-
var
|
|
649
|
-
const synonyms = (
|
|
648
|
+
var _a3;
|
|
649
|
+
const synonyms = (_a3 = FIELD_SYNONYMS[uiKey]) != null ? _a3 : [];
|
|
650
650
|
const keys = Object.keys(meta);
|
|
651
651
|
const systemKeys = ["namespace", "filename", "filesize", "filetype", "docid", "uploadedat", "dimension", "chunkindex"];
|
|
652
652
|
let match = keys.find((k) => k.toLowerCase() === uiKey.toLowerCase());
|
|
@@ -733,14 +733,14 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
733
733
|
init_synonyms();
|
|
734
734
|
MultiTablePostgresProvider = class extends BaseVectorProvider {
|
|
735
735
|
constructor(config) {
|
|
736
|
-
var
|
|
736
|
+
var _a3, _b, _c;
|
|
737
737
|
super(config);
|
|
738
738
|
const opts = config.options || {};
|
|
739
739
|
if (!opts.connectionString) {
|
|
740
740
|
throw new Error("[MultiTablePostgresProvider] options.connectionString is required");
|
|
741
741
|
}
|
|
742
742
|
this.connectionString = opts.connectionString;
|
|
743
|
-
this.dimensions = (
|
|
743
|
+
this.dimensions = (_a3 = opts.dimensions) != null ? _a3 : 768;
|
|
744
744
|
this.tables = [];
|
|
745
745
|
const rawSearchFields = (_c = (_b = opts.searchFields) != null ? _b : process.env.VECTOR_DB_SEARCH_FIELDS) != null ? _c : ["name", "product_name", "productname", "title"];
|
|
746
746
|
this.searchFields = typeof rawSearchFields === "string" ? rawSearchFields.split(",").map((f) => f.trim()).filter(Boolean) : rawSearchFields;
|
|
@@ -798,11 +798,11 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
798
798
|
* Batch upsert documents by dynamically provisioning tables and columns based on CSV headers.
|
|
799
799
|
*/
|
|
800
800
|
async batchUpsert(docs, namespace = "") {
|
|
801
|
-
var
|
|
801
|
+
var _a3;
|
|
802
802
|
if (docs.length === 0) return;
|
|
803
803
|
const docsByFile = {};
|
|
804
804
|
for (const doc of docs) {
|
|
805
|
-
const fileName = ((
|
|
805
|
+
const fileName = ((_a3 = doc.metadata) == null ? void 0 : _a3.fileName) || this.uploadTable;
|
|
806
806
|
if (!docsByFile[fileName]) docsByFile[fileName] = [];
|
|
807
807
|
docsByFile[fileName].push(doc);
|
|
808
808
|
}
|
|
@@ -855,11 +855,11 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
855
855
|
const headerColumns = csvHeaders.map((h) => `"${h}"`).join(", ");
|
|
856
856
|
const allColumns = `id, ${headerColumns ? headerColumns + ", " : ""}namespace, content, metadata, embedding`;
|
|
857
857
|
const valuePlaceholders = batch.map((doc, idx) => {
|
|
858
|
-
var
|
|
858
|
+
var _a4, _b;
|
|
859
859
|
const offset = idx * (5 + csvHeaders.length);
|
|
860
860
|
values.push(doc.id);
|
|
861
861
|
for (const h of csvHeaders) {
|
|
862
|
-
values.push(String(((
|
|
862
|
+
values.push(String(((_a4 = doc.metadata) == null ? void 0 : _a4[h]) || ""));
|
|
863
863
|
}
|
|
864
864
|
values.push(namespace, doc.content, JSON.stringify((_b = doc.metadata) != null ? _b : {}), `[${doc.vector.join(",")}]`);
|
|
865
865
|
const docPlaceholders = [];
|
|
@@ -898,7 +898,7 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
898
898
|
* Query all configured tables and merge results, sorted by cosine similarity score.
|
|
899
899
|
*/
|
|
900
900
|
async query(vector, topK, _namespace, _filter) {
|
|
901
|
-
var
|
|
901
|
+
var _a3;
|
|
902
902
|
if (!this.pool) {
|
|
903
903
|
throw new Error("[MultiTablePostgresProvider] Provider not initialized. Call initialize() first.");
|
|
904
904
|
}
|
|
@@ -929,11 +929,11 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
929
929
|
const filterParams = [];
|
|
930
930
|
if (metadataFilters && Object.keys(metadataFilters).length > 0) {
|
|
931
931
|
const conditions = Object.entries(metadataFilters).map(([key, val]) => {
|
|
932
|
-
var
|
|
932
|
+
var _a5;
|
|
933
933
|
filterParams.push(String(val));
|
|
934
934
|
const baseOffset = queryText && dynamicKeywordQuery ? 2 : 1;
|
|
935
935
|
const paramIdx = baseOffset + filterParams.length;
|
|
936
|
-
const synonyms = (
|
|
936
|
+
const synonyms = (_a5 = FIELD_SYNONYMS[key]) != null ? _a5 : [];
|
|
937
937
|
const keysToCheck = [key, ...synonyms];
|
|
938
938
|
const coalesceExprs = keysToCheck.flatMap((k) => [
|
|
939
939
|
`metadata->>'${k}'`,
|
|
@@ -1002,7 +1002,7 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
1002
1002
|
}
|
|
1003
1003
|
const tableResults = [];
|
|
1004
1004
|
for (const row of result.rows) {
|
|
1005
|
-
const
|
|
1005
|
+
const _a4 = row, { hybrid_score, id } = _a4, rest = __objRest(_a4, ["hybrid_score", "id"]);
|
|
1006
1006
|
delete rest.embedding;
|
|
1007
1007
|
delete rest.vector_score;
|
|
1008
1008
|
delete rest.keyword_score;
|
|
@@ -1031,10 +1031,10 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
1031
1031
|
}
|
|
1032
1032
|
allResults.sort((a, b) => b.score - a.score);
|
|
1033
1033
|
if (allResults.length === 0) return [];
|
|
1034
|
-
const bestMatchTable = (
|
|
1034
|
+
const bestMatchTable = (_a3 = allResults[0].metadata) == null ? void 0 : _a3.source_table;
|
|
1035
1035
|
const finalSorted = allResults.filter((res) => {
|
|
1036
|
-
var
|
|
1037
|
-
return ((
|
|
1036
|
+
var _a4;
|
|
1037
|
+
return ((_a4 = res.metadata) == null ? void 0 : _a4.source_table) === bestMatchTable;
|
|
1038
1038
|
});
|
|
1039
1039
|
console.log(`[MultiTablePostgresProvider] --- Search Complete ---`);
|
|
1040
1040
|
console.log(`[MultiTablePostgresProvider] Final top match from "${bestMatchTable}" with score ${finalSorted[0].score.toFixed(4)}`);
|
|
@@ -1439,14 +1439,14 @@ var init_QdrantProvider = __esm({
|
|
|
1439
1439
|
* Samples points from the collection to discover available payload fields.
|
|
1440
1440
|
*/
|
|
1441
1441
|
async discoverSchema() {
|
|
1442
|
-
var
|
|
1442
|
+
var _a3;
|
|
1443
1443
|
try {
|
|
1444
1444
|
const { data } = await this.http.post(`/collections/${this.indexName}/points/scroll`, {
|
|
1445
1445
|
limit: 20,
|
|
1446
1446
|
with_payload: true,
|
|
1447
1447
|
with_vector: false
|
|
1448
1448
|
});
|
|
1449
|
-
const points = ((
|
|
1449
|
+
const points = ((_a3 = data.result) == null ? void 0 : _a3.points) || [];
|
|
1450
1450
|
const keys = /* @__PURE__ */ new Set();
|
|
1451
1451
|
for (const point of points) {
|
|
1452
1452
|
const payload = point.payload || {};
|
|
@@ -1472,12 +1472,12 @@ var init_QdrantProvider = __esm({
|
|
|
1472
1472
|
* Ensures the collection exists. Creates it if missing.
|
|
1473
1473
|
*/
|
|
1474
1474
|
async ensureCollection() {
|
|
1475
|
-
var
|
|
1475
|
+
var _a3;
|
|
1476
1476
|
try {
|
|
1477
1477
|
await this.http.get(`/collections/${this.indexName}`);
|
|
1478
1478
|
console.log(`[QdrantProvider] \u2705 Collection "${this.indexName}" already exists.`);
|
|
1479
1479
|
} catch (err) {
|
|
1480
|
-
if (import_axios4.default.isAxiosError(err) && ((
|
|
1480
|
+
if (import_axios4.default.isAxiosError(err) && ((_a3 = err.response) == null ? void 0 : _a3.status) === 404) {
|
|
1481
1481
|
const opts = this.config.options;
|
|
1482
1482
|
const dimensionsForCreate = opts.dimensions || 1536;
|
|
1483
1483
|
console.log(`[QdrantProvider] \u23F3 Creating collection "${this.indexName}" (dimensions: ${dimensionsForCreate})...`);
|
|
@@ -1497,7 +1497,7 @@ var init_QdrantProvider = __esm({
|
|
|
1497
1497
|
* Ensures that a payload field has an index.
|
|
1498
1498
|
*/
|
|
1499
1499
|
async ensureIndex(fieldName, schema = "keyword") {
|
|
1500
|
-
var
|
|
1500
|
+
var _a3;
|
|
1501
1501
|
let fullPath = fieldName;
|
|
1502
1502
|
if (!this.isFlatPayload && !fieldName.includes(".") && fieldName !== "namespace" && fieldName !== this.contentField) {
|
|
1503
1503
|
fullPath = `${this.metadataField}.${fieldName}`;
|
|
@@ -1510,7 +1510,7 @@ var init_QdrantProvider = __esm({
|
|
|
1510
1510
|
console.log(`[QdrantProvider] \u2705 Ensured ${schema} index for "${fullPath}"`);
|
|
1511
1511
|
} catch (err) {
|
|
1512
1512
|
let status;
|
|
1513
|
-
if (import_axios4.default.isAxiosError(err)) status = (
|
|
1513
|
+
if (import_axios4.default.isAxiosError(err)) status = (_a3 = err.response) == null ? void 0 : _a3.status;
|
|
1514
1514
|
if (status === 409) return;
|
|
1515
1515
|
console.warn(`[QdrantProvider] \u26A0\uFE0F Could not ensure index for "${fullPath}":`, err instanceof Error ? err.message : String(err));
|
|
1516
1516
|
}
|
|
@@ -1539,7 +1539,7 @@ var init_QdrantProvider = __esm({
|
|
|
1539
1539
|
await this.http.put(`/collections/${this.indexName}/points`, payload);
|
|
1540
1540
|
}
|
|
1541
1541
|
async query(vector, topK, namespace, _filter) {
|
|
1542
|
-
var
|
|
1542
|
+
var _a3;
|
|
1543
1543
|
const must = [];
|
|
1544
1544
|
if (namespace) {
|
|
1545
1545
|
must.push({ key: "namespace", match: { value: namespace } });
|
|
@@ -1561,7 +1561,7 @@ var init_QdrantProvider = __esm({
|
|
|
1561
1561
|
limit: topK,
|
|
1562
1562
|
with_payload: true,
|
|
1563
1563
|
params: {
|
|
1564
|
-
hnsw_ef: ((
|
|
1564
|
+
hnsw_ef: ((_a3 = this.config.options) == null ? void 0 : _a3.efSearch) || Math.max(topK * 20, 128),
|
|
1565
1565
|
exact: false
|
|
1566
1566
|
},
|
|
1567
1567
|
filter: must.length > 0 ? { must } : void 0
|
|
@@ -1656,13 +1656,13 @@ var init_ChromaDBProvider = __esm({
|
|
|
1656
1656
|
* Get or create the ChromaDB collection.
|
|
1657
1657
|
*/
|
|
1658
1658
|
async initialize() {
|
|
1659
|
-
var
|
|
1659
|
+
var _a3;
|
|
1660
1660
|
try {
|
|
1661
1661
|
const { data } = await this.http.get(`/api/v1/collections/${this.indexName}`);
|
|
1662
1662
|
this.collectionId = data.id;
|
|
1663
1663
|
console.log(`[ChromaDBProvider] \u2705 Collection "${this.indexName}" found (id: ${this.collectionId})`);
|
|
1664
1664
|
} catch (err) {
|
|
1665
|
-
if (import_axios5.default.isAxiosError(err) && ((
|
|
1665
|
+
if (import_axios5.default.isAxiosError(err) && ((_a3 = err.response) == null ? void 0 : _a3.status) === 404) {
|
|
1666
1666
|
console.log(`[ChromaDBProvider] \u23F3 Collection "${this.indexName}" not found. Creating...`);
|
|
1667
1667
|
const { data } = await this.http.post("/api/v1/collections", {
|
|
1668
1668
|
name: this.indexName
|
|
@@ -1883,7 +1883,7 @@ var init_WeaviateProvider = __esm({
|
|
|
1883
1883
|
await this.http.post("/v1/batch/objects", payload);
|
|
1884
1884
|
}
|
|
1885
1885
|
async query(vector, topK, namespace, _filter) {
|
|
1886
|
-
var
|
|
1886
|
+
var _a3, _b;
|
|
1887
1887
|
const queryText = _filter == null ? void 0 : _filter.queryText;
|
|
1888
1888
|
const sanitizedFilter = this.sanitizeFilter(_filter);
|
|
1889
1889
|
const searchParams = queryText ? `hybrid: { query: ${JSON.stringify(queryText)}, alpha: 0.5 }` : `nearVector: { vector: ${JSON.stringify(vector)} }`;
|
|
@@ -1909,7 +1909,7 @@ var init_WeaviateProvider = __esm({
|
|
|
1909
1909
|
`
|
|
1910
1910
|
};
|
|
1911
1911
|
const { data } = await this.http.post("/v1/graphql", graphqlQuery);
|
|
1912
|
-
const results = ((_b = (
|
|
1912
|
+
const results = ((_b = (_a3 = data.data) == null ? void 0 : _a3.Get) == null ? void 0 : _b[this.indexName]) || [];
|
|
1913
1913
|
return results.map((res) => ({
|
|
1914
1914
|
id: res["_additional"].id,
|
|
1915
1915
|
score: 1 - res["_additional"].distance,
|
|
@@ -1992,21 +1992,21 @@ var init_UniversalVectorProvider = __esm({
|
|
|
1992
1992
|
}
|
|
1993
1993
|
}
|
|
1994
1994
|
async initialize() {
|
|
1995
|
-
var
|
|
1995
|
+
var _a3;
|
|
1996
1996
|
this.http = import_axios8.default.create({
|
|
1997
1997
|
baseURL: this.opts.baseUrl,
|
|
1998
1998
|
headers: __spreadValues({
|
|
1999
1999
|
"Content-Type": "application/json"
|
|
2000
2000
|
}, this.opts.headers),
|
|
2001
|
-
timeout: (
|
|
2001
|
+
timeout: (_a3 = this.opts.timeout) != null ? _a3 : 3e4
|
|
2002
2002
|
});
|
|
2003
2003
|
if (!await this.ping()) {
|
|
2004
2004
|
throw new Error(`[UniversalVectorProvider] Failed to connect to ${this.opts.baseUrl}`);
|
|
2005
2005
|
}
|
|
2006
2006
|
}
|
|
2007
2007
|
async upsert(doc, namespace) {
|
|
2008
|
-
var
|
|
2009
|
-
const endpoint = (
|
|
2008
|
+
var _a3, _b, _c;
|
|
2009
|
+
const endpoint = (_a3 = this.opts.upsertEndpoint) != null ? _a3 : "/upsert";
|
|
2010
2010
|
const template = (_b = this.opts.upsertTemplate) != null ? _b : JSON.stringify({
|
|
2011
2011
|
id: "{{id}}",
|
|
2012
2012
|
vector: "{{vector}}",
|
|
@@ -2039,8 +2039,8 @@ var init_UniversalVectorProvider = __esm({
|
|
|
2039
2039
|
}
|
|
2040
2040
|
}
|
|
2041
2041
|
async query(vector, topK, namespace, filter) {
|
|
2042
|
-
var
|
|
2043
|
-
const endpoint = (
|
|
2042
|
+
var _a3, _b;
|
|
2043
|
+
const endpoint = (_a3 = this.opts.queryEndpoint) != null ? _a3 : "/query";
|
|
2044
2044
|
const template = (_b = this.opts.queryTemplate) != null ? _b : JSON.stringify({
|
|
2045
2045
|
vector: "{{vector}}",
|
|
2046
2046
|
limit: "{{topK}}",
|
|
@@ -2066,9 +2066,9 @@ var init_UniversalVectorProvider = __esm({
|
|
|
2066
2066
|
);
|
|
2067
2067
|
}
|
|
2068
2068
|
return results.map((item) => {
|
|
2069
|
-
var
|
|
2069
|
+
var _a4, _b2, _c, _d, _e, _f, _g2;
|
|
2070
2070
|
return {
|
|
2071
|
-
id: item[(
|
|
2071
|
+
id: item[(_a4 = this.opts.queryIdField) != null ? _a4 : "id"],
|
|
2072
2072
|
score: (_c = item[(_b2 = this.opts.queryScoreField) != null ? _b2 : "score"]) != null ? _c : 0,
|
|
2073
2073
|
content: (_e = item[(_d = this.opts.queryContentField) != null ? _d : "content"]) != null ? _e : "",
|
|
2074
2074
|
metadata: (_g2 = item[(_f = this.opts.queryMetadataField) != null ? _f : "metadata"]) != null ? _g2 : {}
|
|
@@ -2081,8 +2081,8 @@ var init_UniversalVectorProvider = __esm({
|
|
|
2081
2081
|
}
|
|
2082
2082
|
}
|
|
2083
2083
|
async delete(id, namespace) {
|
|
2084
|
-
var
|
|
2085
|
-
const endpoint = (
|
|
2084
|
+
var _a3, _b;
|
|
2085
|
+
const endpoint = (_a3 = this.opts.deleteEndpoint) != null ? _a3 : "/delete";
|
|
2086
2086
|
const template = (_b = this.opts.deleteTemplate) != null ? _b : JSON.stringify({
|
|
2087
2087
|
id: "{{id}}",
|
|
2088
2088
|
namespace: "{{namespace}}"
|
|
@@ -2100,8 +2100,8 @@ var init_UniversalVectorProvider = __esm({
|
|
|
2100
2100
|
}
|
|
2101
2101
|
}
|
|
2102
2102
|
async deleteNamespace(namespace) {
|
|
2103
|
-
var
|
|
2104
|
-
const endpoint = (
|
|
2103
|
+
var _a3;
|
|
2104
|
+
const endpoint = (_a3 = this.opts.deleteNamespaceEndpoint) != null ? _a3 : "/delete-namespace";
|
|
2105
2105
|
try {
|
|
2106
2106
|
await this.http.post(endpoint, { namespace });
|
|
2107
2107
|
} catch (error) {
|
|
@@ -2111,9 +2111,9 @@ var init_UniversalVectorProvider = __esm({
|
|
|
2111
2111
|
}
|
|
2112
2112
|
}
|
|
2113
2113
|
async ping() {
|
|
2114
|
-
var
|
|
2114
|
+
var _a3;
|
|
2115
2115
|
try {
|
|
2116
|
-
const endpoint = (
|
|
2116
|
+
const endpoint = (_a3 = this.opts.pingEndpoint) != null ? _a3 : "/health";
|
|
2117
2117
|
const response = await this.http.get(endpoint, { timeout: 5e3 });
|
|
2118
2118
|
return response.status >= 200 && response.status < 300;
|
|
2119
2119
|
} catch (e) {
|
|
@@ -2342,13 +2342,13 @@ var LicenseValidationError = class extends RetrivoraError {
|
|
|
2342
2342
|
}
|
|
2343
2343
|
};
|
|
2344
2344
|
function wrapError(err, defaultCode, defaultMessage) {
|
|
2345
|
-
var
|
|
2345
|
+
var _a3;
|
|
2346
2346
|
if (err instanceof RetrivoraError) {
|
|
2347
2347
|
return err;
|
|
2348
2348
|
}
|
|
2349
2349
|
const error = err;
|
|
2350
2350
|
const message = (error == null ? void 0 : error.message) || defaultMessage || String(err);
|
|
2351
|
-
const status = (error == null ? void 0 : error.status) || (error == null ? void 0 : error.statusCode) || ((
|
|
2351
|
+
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);
|
|
2352
2352
|
const code = error == null ? void 0 : error.code;
|
|
2353
2353
|
if (status === 429 || /rate[- ]?limit/i.test(message) || code === "RATE_LIMIT_EXCEEDED") {
|
|
2354
2354
|
return new RateLimitException(message, err);
|
|
@@ -2417,7 +2417,8 @@ var LicenseVerifier = class {
|
|
|
2417
2417
|
};
|
|
2418
2418
|
}
|
|
2419
2419
|
try {
|
|
2420
|
-
const
|
|
2420
|
+
const sanitizedKey = (licenseKey || "").trim().replace(/^["']|["']$/g, "").trim();
|
|
2421
|
+
const rawToken = sanitizedKey.replace(/^rtv_/i, "").trim();
|
|
2421
2422
|
const parts = rawToken.split(".");
|
|
2422
2423
|
if (parts.length !== 3) {
|
|
2423
2424
|
throw new Error("Malformed token structure (expected 3 parts).");
|
|
@@ -2629,8 +2630,8 @@ var UI_BORDER_RADIUS_OPTIONS = ["none", "sm", "md", "lg", "xl", "full"];
|
|
|
2629
2630
|
|
|
2630
2631
|
// src/config/serverConfig.ts
|
|
2631
2632
|
function readString(env, name) {
|
|
2632
|
-
var
|
|
2633
|
-
const value = (
|
|
2633
|
+
var _a3;
|
|
2634
|
+
const value = (_a3 = env[name]) == null ? void 0 : _a3.trim();
|
|
2634
2635
|
return value ? value : void 0;
|
|
2635
2636
|
}
|
|
2636
2637
|
function readNumber(env, name, fallback) {
|
|
@@ -2643,8 +2644,8 @@ function readNumber(env, name, fallback) {
|
|
|
2643
2644
|
return parsed;
|
|
2644
2645
|
}
|
|
2645
2646
|
function readEnum(env, name, fallback, allowed) {
|
|
2646
|
-
var
|
|
2647
|
-
const value = (
|
|
2647
|
+
var _a3;
|
|
2648
|
+
const value = (_a3 = readString(env, name)) != null ? _a3 : fallback;
|
|
2648
2649
|
if (allowed.includes(value)) {
|
|
2649
2650
|
return value;
|
|
2650
2651
|
}
|
|
@@ -2654,8 +2655,8 @@ function getRagConfig(baseConfig, env = process.env) {
|
|
|
2654
2655
|
return getEnvConfig(env, baseConfig);
|
|
2655
2656
|
}
|
|
2656
2657
|
function getEnvConfig(env = process.env, base) {
|
|
2657
|
-
var
|
|
2658
|
-
const licenseKey = (_d = (_c = (_b = (
|
|
2658
|
+
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;
|
|
2659
|
+
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;
|
|
2659
2660
|
const jwtProjectId = (() => {
|
|
2660
2661
|
if (!licenseKey) return void 0;
|
|
2661
2662
|
try {
|
|
@@ -2736,7 +2737,7 @@ function getEnvConfig(env = process.env, base) {
|
|
|
2736
2737
|
rest: "default",
|
|
2737
2738
|
custom: "default"
|
|
2738
2739
|
};
|
|
2739
|
-
const
|
|
2740
|
+
const isFreeTier2 = (() => {
|
|
2740
2741
|
if (!licenseKey) return true;
|
|
2741
2742
|
try {
|
|
2742
2743
|
const payload = LicenseVerifier.verify(licenseKey, projectId);
|
|
@@ -2747,13 +2748,13 @@ function getEnvConfig(env = process.env, base) {
|
|
|
2747
2748
|
}
|
|
2748
2749
|
})();
|
|
2749
2750
|
const defaultGatewayUrl = (_ra = (_qa = readString(env, "LITELLM_BASE_URL")) != null ? _qa : readString(env, "LLM_BASE_URL")) != null ? _ra : "https://www.retrivora.com/api/v1";
|
|
2750
|
-
const defaultLlmProvider =
|
|
2751
|
+
const defaultLlmProvider = isFreeTier2 ? "universal_rest" : "universal_rest";
|
|
2751
2752
|
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;
|
|
2752
2753
|
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;
|
|
2753
|
-
const llmModel = (_Ca = (_Aa = readString(env, "LLM_MODEL")) != null ? _Aa : (_za = base == null ? void 0 : base.llm) == null ? void 0 : _za.model) != null ? _Ca :
|
|
2754
|
+
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";
|
|
2754
2755
|
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;
|
|
2755
2756
|
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";
|
|
2756
|
-
const defaultEmbeddingProvider =
|
|
2757
|
+
const defaultEmbeddingProvider = isFreeTier2 ? "universal_rest" : "universal_rest";
|
|
2757
2758
|
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;
|
|
2758
2759
|
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;
|
|
2759
2760
|
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";
|
|
@@ -2843,8 +2844,8 @@ function getEnvConfig(env = process.env, base) {
|
|
|
2843
2844
|
}
|
|
2844
2845
|
} : {}), {
|
|
2845
2846
|
mcpServers: (() => {
|
|
2846
|
-
var
|
|
2847
|
-
const raw = (
|
|
2847
|
+
var _a4;
|
|
2848
|
+
const raw = (_a4 = readString(env, "MCP_SERVERS")) != null ? _a4 : readString(env, "NEXT_PUBLIC_MCP_SERVERS");
|
|
2848
2849
|
if (!raw) return void 0;
|
|
2849
2850
|
try {
|
|
2850
2851
|
return JSON.parse(raw);
|
|
@@ -2889,10 +2890,10 @@ var ConfigResolver = class {
|
|
|
2889
2890
|
* fallback behavior.
|
|
2890
2891
|
*/
|
|
2891
2892
|
static resolveUniversal(hostConfig, env = process.env) {
|
|
2892
|
-
var
|
|
2893
|
+
var _a3;
|
|
2893
2894
|
if (!hostConfig) return this.resolve(void 0, env);
|
|
2894
2895
|
const normalized = __spreadProps(__spreadValues({}, hostConfig), {
|
|
2895
|
-
vectorDb: (
|
|
2896
|
+
vectorDb: (_a3 = hostConfig.vectorDb) != null ? _a3 : hostConfig.vectorDatabase,
|
|
2896
2897
|
rag: this.mergeRetrievalWorkflow(hostConfig.rag, hostConfig.retrieval, hostConfig.workflow)
|
|
2897
2898
|
});
|
|
2898
2899
|
return this.resolve(normalized, env);
|
|
@@ -2912,11 +2913,11 @@ var ConfigResolver = class {
|
|
|
2912
2913
|
}
|
|
2913
2914
|
}
|
|
2914
2915
|
static mergeRetrievalWorkflow(rag, retrieval, workflow) {
|
|
2915
|
-
var
|
|
2916
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
2916
2917
|
if (!rag && !retrieval && !workflow) return void 0;
|
|
2917
2918
|
const normalized = __spreadValues({}, rag != null ? rag : {});
|
|
2918
2919
|
if (retrieval) {
|
|
2919
|
-
normalized.topK = (
|
|
2920
|
+
normalized.topK = (_a3 = retrieval.topK) != null ? _a3 : normalized.topK;
|
|
2920
2921
|
normalized.scoreThreshold = (_b = retrieval.scoreThreshold) != null ? _b : normalized.scoreThreshold;
|
|
2921
2922
|
normalized.useReranking = (_c = retrieval.useReranking) != null ? _c : normalized.useReranking;
|
|
2922
2923
|
if (retrieval.strategy === "hybrid") normalized.architecture = (_d = normalized.architecture) != null ? _d : "hybrid";
|
|
@@ -3044,8 +3045,8 @@ var OpenAIProvider = class {
|
|
|
3044
3045
|
};
|
|
3045
3046
|
}
|
|
3046
3047
|
async chat(messages, context, options) {
|
|
3047
|
-
var
|
|
3048
|
-
const basePrompt = (_b = (
|
|
3048
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i;
|
|
3049
|
+
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.";
|
|
3049
3050
|
const systemMessage = {
|
|
3050
3051
|
role: "system",
|
|
3051
3052
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3069,8 +3070,8 @@ var OpenAIProvider = class {
|
|
|
3069
3070
|
}
|
|
3070
3071
|
chatStream(messages, context, options) {
|
|
3071
3072
|
return __asyncGenerator(this, null, function* () {
|
|
3072
|
-
var
|
|
3073
|
-
const basePrompt = (_b = (
|
|
3073
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h;
|
|
3074
|
+
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.";
|
|
3074
3075
|
const systemMessage = {
|
|
3075
3076
|
role: "system",
|
|
3076
3077
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3117,8 +3118,8 @@ var OpenAIProvider = class {
|
|
|
3117
3118
|
return results[0];
|
|
3118
3119
|
}
|
|
3119
3120
|
async batchEmbed(texts, options) {
|
|
3120
|
-
var
|
|
3121
|
-
const model = (_c = (_b = options == null ? void 0 : options.model) != null ? _b : (
|
|
3121
|
+
var _a3, _b, _c, _d, _e;
|
|
3122
|
+
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";
|
|
3122
3123
|
const apiKey = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.apiKey) != null ? _e : this.llmConfig.apiKey;
|
|
3123
3124
|
const client = apiKey !== this.llmConfig.apiKey ? new import_openai.default({ apiKey }) : this.client;
|
|
3124
3125
|
const response = await client.embeddings.create({ model, input: texts });
|
|
@@ -3195,8 +3196,8 @@ var AnthropicProvider = class {
|
|
|
3195
3196
|
};
|
|
3196
3197
|
}
|
|
3197
3198
|
async chat(messages, context, options) {
|
|
3198
|
-
var
|
|
3199
|
-
const basePrompt = (_b = (
|
|
3199
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
|
|
3200
|
+
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.";
|
|
3200
3201
|
const system = buildSystemContent(basePrompt, context);
|
|
3201
3202
|
const anthropicMessages = messages.map((m) => ({
|
|
3202
3203
|
role: m.role === "assistant" ? "assistant" : "user",
|
|
@@ -3234,8 +3235,8 @@ var AnthropicProvider = class {
|
|
|
3234
3235
|
}
|
|
3235
3236
|
chatStream(messages, context, options) {
|
|
3236
3237
|
return __asyncGenerator(this, null, function* () {
|
|
3237
|
-
var
|
|
3238
|
-
const basePrompt = (_b = (
|
|
3238
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
|
|
3239
|
+
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.";
|
|
3239
3240
|
const system = buildSystemContent(basePrompt, context);
|
|
3240
3241
|
const anthropicMessages = messages.map((m) => ({
|
|
3241
3242
|
role: m.role === "assistant" ? "assistant" : "user",
|
|
@@ -3319,8 +3320,8 @@ var AnthropicProvider = class {
|
|
|
3319
3320
|
var import_axios = __toESM(require("axios"));
|
|
3320
3321
|
var OllamaProvider = class {
|
|
3321
3322
|
constructor(llmConfig, embeddingConfig) {
|
|
3322
|
-
var
|
|
3323
|
-
const rawBaseURL = ((
|
|
3323
|
+
var _a3, _b, _c;
|
|
3324
|
+
const rawBaseURL = ((_a3 = llmConfig.baseUrl) != null ? _a3 : "http://localhost:11434").replace(/\/+$/, "");
|
|
3324
3325
|
const baseURL = rawBaseURL.replace(/\/(?:api\/v1|v1|api)$/i, "");
|
|
3325
3326
|
const timeout = Number((_b = llmConfig.options) == null ? void 0 : _b.timeout) || 3e5;
|
|
3326
3327
|
const headers = ((_c = llmConfig.options) == null ? void 0 : _c.headers) || {};
|
|
@@ -3380,8 +3381,8 @@ var OllamaProvider = class {
|
|
|
3380
3381
|
};
|
|
3381
3382
|
}
|
|
3382
3383
|
async chat(messages, context, options) {
|
|
3383
|
-
var
|
|
3384
|
-
const basePrompt = (_b = (
|
|
3384
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
3385
|
+
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.";
|
|
3385
3386
|
const system = buildSystemContent(basePrompt, context);
|
|
3386
3387
|
const { data } = await this.http.post("/api/chat", {
|
|
3387
3388
|
model: this.llmConfig.model,
|
|
@@ -3399,8 +3400,8 @@ var OllamaProvider = class {
|
|
|
3399
3400
|
}
|
|
3400
3401
|
chatStream(messages, context, options) {
|
|
3401
3402
|
return __asyncGenerator(this, null, function* () {
|
|
3402
|
-
var
|
|
3403
|
-
const basePrompt = (_b = (
|
|
3403
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h;
|
|
3404
|
+
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.";
|
|
3404
3405
|
const system = buildSystemContent(basePrompt, context);
|
|
3405
3406
|
const response = yield new __await(this.http.post("/api/chat", {
|
|
3406
3407
|
model: this.llmConfig.model,
|
|
@@ -3458,8 +3459,8 @@ var OllamaProvider = class {
|
|
|
3458
3459
|
});
|
|
3459
3460
|
}
|
|
3460
3461
|
async embed(text, options) {
|
|
3461
|
-
var
|
|
3462
|
-
const model = (_c = (_b = options == null ? void 0 : options.model) != null ? _b : (
|
|
3462
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
|
|
3463
|
+
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";
|
|
3463
3464
|
const baseURL = (_f = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.baseUrl) != null ? _e : this.llmConfig.baseUrl) != null ? _f : "http://localhost:11434";
|
|
3464
3465
|
const client = baseURL !== ((_g2 = this.llmConfig.baseUrl) != null ? _g2 : "http://localhost:11434") ? import_axios.default.create({ baseURL, timeout: 6e4 }) : this.http;
|
|
3465
3466
|
let prompt = text;
|
|
@@ -3560,9 +3561,9 @@ var GeminiProvider = class {
|
|
|
3560
3561
|
static getHealthChecker() {
|
|
3561
3562
|
return {
|
|
3562
3563
|
async check(config) {
|
|
3563
|
-
var
|
|
3564
|
+
var _a3, _b;
|
|
3564
3565
|
const timestamp = Date.now();
|
|
3565
|
-
const apiKey = (_b = (
|
|
3566
|
+
const apiKey = (_b = (_a3 = config.apiKey) != null ? _a3 : process.env.GOOGLE_GENAI_API_KEY) != null ? _b : "";
|
|
3566
3567
|
const modelName = sanitizeModel(config.model);
|
|
3567
3568
|
try {
|
|
3568
3569
|
const { GoogleGenerativeAI: GoogleGenerativeAI2 } = await import("@google/generative-ai");
|
|
@@ -3592,16 +3593,16 @@ var GeminiProvider = class {
|
|
|
3592
3593
|
/** Resolve the embedding client — uses a separate client when the embedding
|
|
3593
3594
|
* API key differs from the LLM API key. */
|
|
3594
3595
|
get embeddingClient() {
|
|
3595
|
-
var
|
|
3596
|
-
if (((
|
|
3596
|
+
var _a3;
|
|
3597
|
+
if (((_a3 = this.embeddingConfig) == null ? void 0 : _a3.apiKey) && this.embeddingConfig.apiKey !== this.llmConfig.apiKey) {
|
|
3597
3598
|
return buildClient(this.embeddingConfig.apiKey);
|
|
3598
3599
|
}
|
|
3599
3600
|
return this.client;
|
|
3600
3601
|
}
|
|
3601
3602
|
/** Resolve the embedding model to use, in order of specificity. */
|
|
3602
3603
|
resolveEmbeddingModel(optionsModel) {
|
|
3603
|
-
var
|
|
3604
|
-
return sanitizeModel((_b = optionsModel != null ? optionsModel : (
|
|
3604
|
+
var _a3, _b;
|
|
3605
|
+
return sanitizeModel((_b = optionsModel != null ? optionsModel : (_a3 = this.embeddingConfig) == null ? void 0 : _a3.model) != null ? _b : DEFAULT_EMBEDDING_MODEL);
|
|
3605
3606
|
}
|
|
3606
3607
|
/**
|
|
3607
3608
|
* Convert ChatMessage[] to the Gemini contents format.
|
|
@@ -3621,8 +3622,8 @@ var GeminiProvider = class {
|
|
|
3621
3622
|
// ILLMProvider — chat
|
|
3622
3623
|
// -------------------------------------------------------------------------
|
|
3623
3624
|
async chat(messages, context, options) {
|
|
3624
|
-
var
|
|
3625
|
-
const basePrompt = (_b = (
|
|
3625
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
3626
|
+
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.";
|
|
3626
3627
|
const model = this.client.getGenerativeModel({
|
|
3627
3628
|
model: this.llmConfig.model,
|
|
3628
3629
|
systemInstruction: buildSystemContent(basePrompt, context)
|
|
@@ -3639,8 +3640,8 @@ var GeminiProvider = class {
|
|
|
3639
3640
|
}
|
|
3640
3641
|
chatStream(messages, context, options) {
|
|
3641
3642
|
return __asyncGenerator(this, null, function* () {
|
|
3642
|
-
var
|
|
3643
|
-
const basePrompt = (_b = (
|
|
3643
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
3644
|
+
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.";
|
|
3644
3645
|
const model = this.client.getGenerativeModel({
|
|
3645
3646
|
model: this.llmConfig.model,
|
|
3646
3647
|
systemInstruction: buildSystemContent(basePrompt, context)
|
|
@@ -3675,11 +3676,11 @@ var GeminiProvider = class {
|
|
|
3675
3676
|
// ILLMProvider — embeddings
|
|
3676
3677
|
// -------------------------------------------------------------------------
|
|
3677
3678
|
async embed(text, options) {
|
|
3678
|
-
var
|
|
3679
|
+
var _a3, _b;
|
|
3679
3680
|
const content = applyPrefix(
|
|
3680
3681
|
text,
|
|
3681
3682
|
options == null ? void 0 : options.taskType,
|
|
3682
|
-
(
|
|
3683
|
+
(_a3 = this.embeddingConfig) == null ? void 0 : _a3.queryPrefix,
|
|
3683
3684
|
(_b = this.embeddingConfig) == null ? void 0 : _b.documentPrefix
|
|
3684
3685
|
);
|
|
3685
3686
|
const modelName = this.resolveEmbeddingModel(options == null ? void 0 : options.model);
|
|
@@ -3696,7 +3697,7 @@ var GeminiProvider = class {
|
|
|
3696
3697
|
const modelName = this.resolveEmbeddingModel(options == null ? void 0 : options.model);
|
|
3697
3698
|
const model = this.embeddingClient.getGenerativeModel({ model: modelName });
|
|
3698
3699
|
const requests = texts.map((text) => {
|
|
3699
|
-
var
|
|
3700
|
+
var _a3, _b;
|
|
3700
3701
|
return {
|
|
3701
3702
|
content: {
|
|
3702
3703
|
role: "user",
|
|
@@ -3704,7 +3705,7 @@ var GeminiProvider = class {
|
|
|
3704
3705
|
text: applyPrefix(
|
|
3705
3706
|
text,
|
|
3706
3707
|
options == null ? void 0 : options.taskType,
|
|
3707
|
-
(
|
|
3708
|
+
(_a3 = this.embeddingConfig) == null ? void 0 : _a3.queryPrefix,
|
|
3708
3709
|
(_b = this.embeddingConfig) == null ? void 0 : _b.documentPrefix
|
|
3709
3710
|
)
|
|
3710
3711
|
}]
|
|
@@ -3721,8 +3722,8 @@ var GeminiProvider = class {
|
|
|
3721
3722
|
throw err;
|
|
3722
3723
|
});
|
|
3723
3724
|
return response.embeddings.map((e) => {
|
|
3724
|
-
var
|
|
3725
|
-
return (
|
|
3725
|
+
var _a3;
|
|
3726
|
+
return (_a3 = e.values) != null ? _a3 : [];
|
|
3726
3727
|
});
|
|
3727
3728
|
}
|
|
3728
3729
|
// -------------------------------------------------------------------------
|
|
@@ -3811,8 +3812,8 @@ var GroqProvider = class {
|
|
|
3811
3812
|
};
|
|
3812
3813
|
}
|
|
3813
3814
|
async chat(messages, context, options) {
|
|
3814
|
-
var
|
|
3815
|
-
const basePrompt = (_b = (
|
|
3815
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i;
|
|
3816
|
+
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.";
|
|
3816
3817
|
const systemMessage = {
|
|
3817
3818
|
role: "system",
|
|
3818
3819
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3836,8 +3837,8 @@ var GroqProvider = class {
|
|
|
3836
3837
|
}
|
|
3837
3838
|
chatStream(messages, context, options) {
|
|
3838
3839
|
return __asyncGenerator(this, null, function* () {
|
|
3839
|
-
var
|
|
3840
|
-
const basePrompt = (_b = (
|
|
3840
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h;
|
|
3841
|
+
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.";
|
|
3841
3842
|
const systemMessage = {
|
|
3842
3843
|
role: "system",
|
|
3843
3844
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3971,8 +3972,8 @@ var QwenProvider = class {
|
|
|
3971
3972
|
};
|
|
3972
3973
|
}
|
|
3973
3974
|
async chat(messages, context, options) {
|
|
3974
|
-
var
|
|
3975
|
-
const basePrompt = (_b = (
|
|
3975
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i;
|
|
3976
|
+
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.";
|
|
3976
3977
|
const systemMessage = {
|
|
3977
3978
|
role: "system",
|
|
3978
3979
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3996,8 +3997,8 @@ var QwenProvider = class {
|
|
|
3996
3997
|
}
|
|
3997
3998
|
chatStream(messages, context, options) {
|
|
3998
3999
|
return __asyncGenerator(this, null, function* () {
|
|
3999
|
-
var
|
|
4000
|
-
const basePrompt = (_b = (
|
|
4000
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h;
|
|
4001
|
+
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.";
|
|
4001
4002
|
const systemMessage = {
|
|
4002
4003
|
role: "system",
|
|
4003
4004
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -4044,8 +4045,8 @@ var QwenProvider = class {
|
|
|
4044
4045
|
return results[0];
|
|
4045
4046
|
}
|
|
4046
4047
|
async batchEmbed(texts, options) {
|
|
4047
|
-
var
|
|
4048
|
-
const model = (_c = (_b = options == null ? void 0 : options.model) != null ? _b : (
|
|
4048
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
4049
|
+
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";
|
|
4049
4050
|
const apiKey = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.apiKey) != null ? _e : this.llmConfig.apiKey;
|
|
4050
4051
|
const client = apiKey !== this.llmConfig.apiKey ? new import_openai3.default({
|
|
4051
4052
|
apiKey,
|
|
@@ -4145,9 +4146,9 @@ var VECTOR_PROFILES = {
|
|
|
4145
4146
|
|
|
4146
4147
|
// src/llm/providers/UniversalLLMAdapter.ts
|
|
4147
4148
|
function extractContent(obj) {
|
|
4148
|
-
var
|
|
4149
|
+
var _a3, _b, _c;
|
|
4149
4150
|
if (!obj || typeof obj !== "object") return void 0;
|
|
4150
|
-
const choice = (
|
|
4151
|
+
const choice = (_a3 = obj.choices) == null ? void 0 : _a3[0];
|
|
4151
4152
|
if (!choice) return void 0;
|
|
4152
4153
|
if (typeof ((_b = choice.message) == null ? void 0 : _b.content) === "string") return choice.message.content;
|
|
4153
4154
|
if (typeof ((_c = choice.delta) == null ? void 0 : _c.content) === "string") return choice.delta.content;
|
|
@@ -4157,10 +4158,10 @@ function extractContent(obj) {
|
|
|
4157
4158
|
}
|
|
4158
4159
|
var UniversalLLMAdapter = class {
|
|
4159
4160
|
constructor(config) {
|
|
4160
|
-
var
|
|
4161
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h;
|
|
4161
4162
|
this.model = config.model;
|
|
4162
4163
|
const llmConfig = config;
|
|
4163
|
-
const options = (
|
|
4164
|
+
const options = (_a3 = llmConfig.options) != null ? _a3 : {};
|
|
4164
4165
|
let profile = {};
|
|
4165
4166
|
if (typeof options.profile === "string") {
|
|
4166
4167
|
profile = LLM_PROFILES[options.profile] || {};
|
|
@@ -4186,8 +4187,8 @@ var UniversalLLMAdapter = class {
|
|
|
4186
4187
|
});
|
|
4187
4188
|
}
|
|
4188
4189
|
async chat(messages, context) {
|
|
4189
|
-
var
|
|
4190
|
-
const path2 = (
|
|
4190
|
+
var _a3, _b, _c, _d, _e;
|
|
4191
|
+
const path2 = (_a3 = this.opts.chatPath) != null ? _a3 : "/chat/completions";
|
|
4191
4192
|
const safeMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
|
|
4192
4193
|
role: m.role || "user",
|
|
4193
4194
|
content: typeof m.content === "string" ? m.content : m.content != null ? String(m.content) : ""
|
|
@@ -4253,8 +4254,8 @@ ${context != null ? context : "None"}` },
|
|
|
4253
4254
|
*/
|
|
4254
4255
|
chatStream(messages, context) {
|
|
4255
4256
|
return __asyncGenerator(this, null, function* () {
|
|
4256
|
-
var
|
|
4257
|
-
const path2 = (
|
|
4257
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
4258
|
+
const path2 = (_a3 = this.opts.chatPath) != null ? _a3 : "/chat/completions";
|
|
4258
4259
|
const url = `${this.baseUrl.replace(/\/$/, "")}${path2}`;
|
|
4259
4260
|
const extractPath = ((_b = this.opts.responseExtractPath) != null ? _b : "choices[0].message.content").replace("message.content", "delta.content");
|
|
4260
4261
|
const safeMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
|
|
@@ -4380,8 +4381,8 @@ ${context != null ? context : "None"}` },
|
|
|
4380
4381
|
});
|
|
4381
4382
|
}
|
|
4382
4383
|
async embed(text) {
|
|
4383
|
-
var
|
|
4384
|
-
const path2 = (
|
|
4384
|
+
var _a3, _b, _c, _d, _e;
|
|
4385
|
+
const path2 = (_a3 = this.opts.embedPath) != null ? _a3 : "/embeddings";
|
|
4385
4386
|
const payload = this.opts.embedPayloadTemplate ? buildPayload(this.opts.embedPayloadTemplate, { input: text, model: this.model }) : { input: text, model: this.model };
|
|
4386
4387
|
try {
|
|
4387
4388
|
const { data: data2 } = await this.http.post(path2, payload);
|
|
@@ -4470,7 +4471,7 @@ var LLMFactory = class _LLMFactory {
|
|
|
4470
4471
|
];
|
|
4471
4472
|
}
|
|
4472
4473
|
static create(llmConfig, embeddingConfig) {
|
|
4473
|
-
var
|
|
4474
|
+
var _a3, _b, _c;
|
|
4474
4475
|
switch (llmConfig.provider) {
|
|
4475
4476
|
case "openai":
|
|
4476
4477
|
return new OpenAIProvider(llmConfig, embeddingConfig);
|
|
@@ -4489,7 +4490,7 @@ var LLMFactory = class _LLMFactory {
|
|
|
4489
4490
|
case "custom":
|
|
4490
4491
|
return new UniversalLLMAdapter(llmConfig);
|
|
4491
4492
|
default: {
|
|
4492
|
-
const providerName = String((
|
|
4493
|
+
const providerName = String((_a3 = llmConfig.provider) != null ? _a3 : "").toLowerCase();
|
|
4493
4494
|
const customFactory = customProviders.get(providerName);
|
|
4494
4495
|
if (customFactory) {
|
|
4495
4496
|
return customFactory(llmConfig);
|
|
@@ -4591,7 +4592,7 @@ var ProviderRegistry = class {
|
|
|
4591
4592
|
return null;
|
|
4592
4593
|
}
|
|
4593
4594
|
static async loadVectorProviderClass(provider) {
|
|
4594
|
-
var
|
|
4595
|
+
var _a3;
|
|
4595
4596
|
if (this.vectorProviders[provider]) return this.vectorProviders[provider];
|
|
4596
4597
|
switch (provider) {
|
|
4597
4598
|
case "pinecone": {
|
|
@@ -4600,7 +4601,7 @@ var ProviderRegistry = class {
|
|
|
4600
4601
|
}
|
|
4601
4602
|
case "pgvector":
|
|
4602
4603
|
case "postgresql": {
|
|
4603
|
-
const postgresMode = ((
|
|
4604
|
+
const postgresMode = ((_a3 = process.env.POSTGRES_MODE) != null ? _a3 : "multi").toLowerCase();
|
|
4604
4605
|
if (postgresMode === "single") {
|
|
4605
4606
|
const { PostgreSQLProvider: PostgreSQLProvider2 } = await Promise.resolve().then(() => (init_PostgreSQLProvider(), PostgreSQLProvider_exports));
|
|
4606
4607
|
return PostgreSQLProvider2;
|
|
@@ -4823,7 +4824,7 @@ var ConfigValidator = class {
|
|
|
4823
4824
|
// package.json
|
|
4824
4825
|
var package_default = {
|
|
4825
4826
|
name: "@retrivora-ai/rag-engine",
|
|
4826
|
-
version: "2.
|
|
4827
|
+
version: "2.3.1",
|
|
4827
4828
|
description: "Retrivora AI is a plug-and-play AI engine for RAG chat experiences \u2014 generic vector DB + LLM provider, embeddable or standalone.",
|
|
4828
4829
|
author: "Abhinav Alkuchi",
|
|
4829
4830
|
license: "UNLICENSED",
|
|
@@ -5128,8 +5129,8 @@ var Reranker = class {
|
|
|
5128
5129
|
return matches.sort((a, b) => b.score - a.score).slice(0, limit);
|
|
5129
5130
|
}
|
|
5130
5131
|
const scoredMatches = matches.map((match) => {
|
|
5131
|
-
var
|
|
5132
|
-
const contentLower = ((
|
|
5132
|
+
var _a3;
|
|
5133
|
+
const contentLower = ((_a3 = match == null ? void 0 : match.content) != null ? _a3 : "").toLowerCase();
|
|
5133
5134
|
let keywordScore = 0;
|
|
5134
5135
|
keywords.forEach((keyword) => {
|
|
5135
5136
|
if (contentLower.includes(keyword)) {
|
|
@@ -5151,8 +5152,8 @@ var Reranker = class {
|
|
|
5151
5152
|
|
|
5152
5153
|
Documents:
|
|
5153
5154
|
${topN.map((m, i) => {
|
|
5154
|
-
var
|
|
5155
|
-
return `[${i}] ${((
|
|
5155
|
+
var _a3;
|
|
5156
|
+
return `[${i}] ${((_a3 = m == null ? void 0 : m.content) != null ? _a3 : "").replace(/\n/g, " ")}`;
|
|
5156
5157
|
}).join("\n")}` }],
|
|
5157
5158
|
"",
|
|
5158
5159
|
{
|
|
@@ -5196,11 +5197,11 @@ var LlamaIndexIngestor = class {
|
|
|
5196
5197
|
* than standard character-count splitting.
|
|
5197
5198
|
*/
|
|
5198
5199
|
async chunk(text, options = {}) {
|
|
5199
|
-
var
|
|
5200
|
+
var _a3, _b;
|
|
5200
5201
|
try {
|
|
5201
5202
|
const { Document, SentenceSplitter, MetadataMode } = await import(`${"llamaindex"}`);
|
|
5202
5203
|
const splitter = new SentenceSplitter({
|
|
5203
|
-
chunkSize: (
|
|
5204
|
+
chunkSize: (_a3 = options.chunkSize) != null ? _a3 : 1e3,
|
|
5204
5205
|
chunkOverlap: (_b = options.chunkOverlap) != null ? _b : 200
|
|
5205
5206
|
});
|
|
5206
5207
|
const doc = new Document({ text, metadata: options.metadata || {} });
|
|
@@ -5309,7 +5310,7 @@ ${error instanceof Error ? error.message : String(error)}`
|
|
|
5309
5310
|
* The agent returns `{ messages: [...] }` — the last message is the final answer.
|
|
5310
5311
|
*/
|
|
5311
5312
|
async run(input, chatHistory = []) {
|
|
5312
|
-
var
|
|
5313
|
+
var _a3, _b, _c;
|
|
5313
5314
|
if (!this.agent) {
|
|
5314
5315
|
throw new Error("[LangChainAgent] Agent not initialized. Call initialize() first.");
|
|
5315
5316
|
}
|
|
@@ -5320,7 +5321,7 @@ ${error instanceof Error ? error.message : String(error)}`
|
|
|
5320
5321
|
const response = await this.agent.invoke({
|
|
5321
5322
|
messages: [...historyMessages, new HumanMessage(input)]
|
|
5322
5323
|
});
|
|
5323
|
-
const lastMessage = (
|
|
5324
|
+
const lastMessage = (_a3 = response == null ? void 0 : response.messages) == null ? void 0 : _a3.at(-1);
|
|
5324
5325
|
if (lastMessage && typeof lastMessage.content === "string") {
|
|
5325
5326
|
return lastMessage.content;
|
|
5326
5327
|
}
|
|
@@ -5372,7 +5373,7 @@ var MCPClient = class {
|
|
|
5372
5373
|
}
|
|
5373
5374
|
}
|
|
5374
5375
|
async connectStdio() {
|
|
5375
|
-
var
|
|
5376
|
+
var _a3;
|
|
5376
5377
|
const cmd = this.config.command;
|
|
5377
5378
|
if (!cmd) {
|
|
5378
5379
|
throw new Error(`[MCPClient] Command option is required for stdio transport on "${this.config.name}"`);
|
|
@@ -5387,7 +5388,7 @@ var MCPClient = class {
|
|
|
5387
5388
|
this.stdioBuffer += data.toString("utf-8");
|
|
5388
5389
|
this.processStdioLines();
|
|
5389
5390
|
});
|
|
5390
|
-
(
|
|
5391
|
+
(_a3 = this.childProcess.stderr) == null ? void 0 : _a3.on("data", (data) => {
|
|
5391
5392
|
console.warn(`[MCPClient] [stderr] [${this.config.name}]:`, data.toString("utf-8"));
|
|
5392
5393
|
});
|
|
5393
5394
|
this.childProcess.on("close", (code) => {
|
|
@@ -5462,14 +5463,14 @@ var MCPClient = class {
|
|
|
5462
5463
|
}
|
|
5463
5464
|
}
|
|
5464
5465
|
async sendNotification(method, params) {
|
|
5465
|
-
var
|
|
5466
|
+
var _a3;
|
|
5466
5467
|
const notification = {
|
|
5467
5468
|
jsonrpc: "2.0",
|
|
5468
5469
|
method,
|
|
5469
5470
|
params
|
|
5470
5471
|
};
|
|
5471
5472
|
if (this.config.transport === "stdio") {
|
|
5472
|
-
if ((
|
|
5473
|
+
if ((_a3 = this.childProcess) == null ? void 0 : _a3.stdin) {
|
|
5473
5474
|
this.childProcess.stdin.write(JSON.stringify(notification) + "\n", "utf-8");
|
|
5474
5475
|
}
|
|
5475
5476
|
} else if (this.sseUrl) {
|
|
@@ -5547,11 +5548,11 @@ var MCPRegistry = class {
|
|
|
5547
5548
|
// src/core/MultiAgentCoordinator.ts
|
|
5548
5549
|
var MultiAgentCoordinator = class {
|
|
5549
5550
|
constructor(options) {
|
|
5550
|
-
var
|
|
5551
|
+
var _a3;
|
|
5551
5552
|
this.llmProvider = options.llmProvider;
|
|
5552
5553
|
this.mcpRegistry = options.mcpRegistry;
|
|
5553
5554
|
this.documentSearch = options.documentSearch;
|
|
5554
|
-
this.maxIterations = (
|
|
5555
|
+
this.maxIterations = (_a3 = options.maxIterations) != null ? _a3 : 5;
|
|
5555
5556
|
}
|
|
5556
5557
|
/**
|
|
5557
5558
|
* Run the multi-agent coordination loop synchronously and return the final response.
|
|
@@ -5603,8 +5604,8 @@ Available Tools:
|
|
|
5603
5604
|
|
|
5604
5605
|
${mcpTools.length > 0 ? "MCP Server Tools:" : ""}
|
|
5605
5606
|
${mcpTools.map((mt) => {
|
|
5606
|
-
var
|
|
5607
|
-
return `- ${mt.tool.name}(${JSON.stringify(((
|
|
5607
|
+
var _a3;
|
|
5608
|
+
return `- ${mt.tool.name}(${JSON.stringify(((_a3 = mt.tool.inputSchema) == null ? void 0 : _a3.properties) || {})}): ${mt.tool.description || "No description provided."}`;
|
|
5608
5609
|
}).join("\n")}
|
|
5609
5610
|
|
|
5610
5611
|
Tool Calling Protocol:
|
|
@@ -5762,6 +5763,100 @@ ${toolResultText}`
|
|
|
5762
5763
|
}
|
|
5763
5764
|
};
|
|
5764
5765
|
|
|
5766
|
+
// src/core/CircuitBreaker.ts
|
|
5767
|
+
var CircuitBreaker = class {
|
|
5768
|
+
constructor(options = {}) {
|
|
5769
|
+
this.state = "closed";
|
|
5770
|
+
this.failureCount = 0;
|
|
5771
|
+
this.successCount = 0;
|
|
5772
|
+
this.lastFailureAt = 0;
|
|
5773
|
+
this.halfOpenCalls = 0;
|
|
5774
|
+
var _a3, _b, _c;
|
|
5775
|
+
this.failureThreshold = (_a3 = options.failureThreshold) != null ? _a3 : 5;
|
|
5776
|
+
this.resetTimeoutMs = (_b = options.resetTimeoutMs) != null ? _b : 3e4;
|
|
5777
|
+
this.halfOpenMaxCalls = (_c = options.halfOpenMaxCalls) != null ? _c : 1;
|
|
5778
|
+
}
|
|
5779
|
+
record(success) {
|
|
5780
|
+
const now = Date.now();
|
|
5781
|
+
if (success) {
|
|
5782
|
+
this.successCount++;
|
|
5783
|
+
if (this.state === "half-open") {
|
|
5784
|
+
this.state = "closed";
|
|
5785
|
+
this.failureCount = 0;
|
|
5786
|
+
this.halfOpenCalls = 0;
|
|
5787
|
+
this.successCount = 1;
|
|
5788
|
+
} else if (this.state === "closed") {
|
|
5789
|
+
if (this.successCount >= this.failureThreshold) {
|
|
5790
|
+
this.failureCount = Math.max(0, this.failureCount - 1);
|
|
5791
|
+
this.successCount = 0;
|
|
5792
|
+
}
|
|
5793
|
+
}
|
|
5794
|
+
} else {
|
|
5795
|
+
this.failureCount++;
|
|
5796
|
+
this.lastFailureAt = now;
|
|
5797
|
+
this.successCount = 0;
|
|
5798
|
+
if (this.state === "half-open") {
|
|
5799
|
+
this.state = "open";
|
|
5800
|
+
this.halfOpenCalls = 0;
|
|
5801
|
+
} else if (this.state === "closed" && this.failureCount >= this.failureThreshold) {
|
|
5802
|
+
this.state = "open";
|
|
5803
|
+
}
|
|
5804
|
+
}
|
|
5805
|
+
}
|
|
5806
|
+
canExecute() {
|
|
5807
|
+
const now = Date.now();
|
|
5808
|
+
if (this.state === "closed") {
|
|
5809
|
+
return true;
|
|
5810
|
+
}
|
|
5811
|
+
if (this.state === "open") {
|
|
5812
|
+
if (now - this.lastFailureAt >= this.resetTimeoutMs) {
|
|
5813
|
+
this.state = "half-open";
|
|
5814
|
+
this.halfOpenCalls = 0;
|
|
5815
|
+
return true;
|
|
5816
|
+
}
|
|
5817
|
+
return false;
|
|
5818
|
+
}
|
|
5819
|
+
if (this.state === "half-open") {
|
|
5820
|
+
return this.halfOpenCalls < this.halfOpenMaxCalls;
|
|
5821
|
+
}
|
|
5822
|
+
return true;
|
|
5823
|
+
}
|
|
5824
|
+
async wrap(fn) {
|
|
5825
|
+
if (!this.canExecute()) {
|
|
5826
|
+
const retryAfterSec = Math.ceil(
|
|
5827
|
+
Math.max(0, this.resetTimeoutMs - (Date.now() - this.lastFailureAt)) / 1e3
|
|
5828
|
+
);
|
|
5829
|
+
throw new Error(
|
|
5830
|
+
`Circuit breaker is open. Try again in ${retryAfterSec}s. Failed ${this.failureCount}/${this.failureThreshold} consecutive calls.`
|
|
5831
|
+
);
|
|
5832
|
+
}
|
|
5833
|
+
if (this.state === "half-open") {
|
|
5834
|
+
this.halfOpenCalls++;
|
|
5835
|
+
}
|
|
5836
|
+
try {
|
|
5837
|
+
const result = await fn();
|
|
5838
|
+
this.record(true);
|
|
5839
|
+
return result;
|
|
5840
|
+
} catch (err) {
|
|
5841
|
+
this.record(false);
|
|
5842
|
+
throw err;
|
|
5843
|
+
}
|
|
5844
|
+
}
|
|
5845
|
+
getState() {
|
|
5846
|
+
return this.state;
|
|
5847
|
+
}
|
|
5848
|
+
getFailureCount() {
|
|
5849
|
+
return this.failureCount;
|
|
5850
|
+
}
|
|
5851
|
+
reset() {
|
|
5852
|
+
this.state = "closed";
|
|
5853
|
+
this.failureCount = 0;
|
|
5854
|
+
this.successCount = 0;
|
|
5855
|
+
this.lastFailureAt = 0;
|
|
5856
|
+
this.halfOpenCalls = 0;
|
|
5857
|
+
}
|
|
5858
|
+
};
|
|
5859
|
+
|
|
5765
5860
|
// src/core/BatchProcessor.ts
|
|
5766
5861
|
function isTransientError(error) {
|
|
5767
5862
|
if (!(error instanceof Error)) return false;
|
|
@@ -5785,7 +5880,34 @@ function calculateBackoffDelay(attempt, initialDelayMs, maxDelayMs, multiplier)
|
|
|
5785
5880
|
function sleep(ms) {
|
|
5786
5881
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
5787
5882
|
}
|
|
5788
|
-
var
|
|
5883
|
+
var _BatchProcessor = class _BatchProcessor {
|
|
5884
|
+
/**
|
|
5885
|
+
* Execute a processor call through the circuit breaker.
|
|
5886
|
+
* Only transient failures count toward opening the circuit.
|
|
5887
|
+
*/
|
|
5888
|
+
static async executeWithCircuitBreaker(processor) {
|
|
5889
|
+
if (!this.cb.canExecute()) {
|
|
5890
|
+
const retryAfterSec = Math.ceil(
|
|
5891
|
+
Math.max(0, 3e4 - (Date.now() - this.cb.lastFailureAt || 0)) / 1e3
|
|
5892
|
+
);
|
|
5893
|
+
throw new Error(
|
|
5894
|
+
`[BatchProcessor] Circuit breaker is open. Try again in ${retryAfterSec}s.`
|
|
5895
|
+
);
|
|
5896
|
+
}
|
|
5897
|
+
if (this.cb.state === "half-open") {
|
|
5898
|
+
this.cb.halfOpenCalls++;
|
|
5899
|
+
}
|
|
5900
|
+
try {
|
|
5901
|
+
const result = await processor();
|
|
5902
|
+
this.cb.record(true);
|
|
5903
|
+
return result;
|
|
5904
|
+
} catch (err) {
|
|
5905
|
+
if (isTransientError(err)) {
|
|
5906
|
+
this.cb.record(false);
|
|
5907
|
+
}
|
|
5908
|
+
throw err;
|
|
5909
|
+
}
|
|
5910
|
+
}
|
|
5789
5911
|
/**
|
|
5790
5912
|
* Processes an array of items in configurable batches with retry logic.
|
|
5791
5913
|
*
|
|
@@ -5826,7 +5948,7 @@ var BatchProcessor = class {
|
|
|
5826
5948
|
let lastError;
|
|
5827
5949
|
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
5828
5950
|
try {
|
|
5829
|
-
const result = await processor(batch);
|
|
5951
|
+
const result = await _BatchProcessor.executeWithCircuitBreaker(() => processor(batch));
|
|
5830
5952
|
results.push(result);
|
|
5831
5953
|
success = true;
|
|
5832
5954
|
break;
|
|
@@ -5884,7 +6006,7 @@ ${errorMessages}`
|
|
|
5884
6006
|
let lastError;
|
|
5885
6007
|
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
5886
6008
|
try {
|
|
5887
|
-
const result = await processor(item);
|
|
6009
|
+
const result = await _BatchProcessor.executeWithCircuitBreaker(() => processor(item));
|
|
5888
6010
|
results.push(result);
|
|
5889
6011
|
success = true;
|
|
5890
6012
|
break;
|
|
@@ -5957,7 +6079,7 @@ ${errorMessages}`
|
|
|
5957
6079
|
}));
|
|
5958
6080
|
const chunkPromises = chunk.map(async ({ item, originalIndex }) => {
|
|
5959
6081
|
try {
|
|
5960
|
-
const result = await processor(item);
|
|
6082
|
+
const result = await _BatchProcessor.executeWithCircuitBreaker(() => processor(item));
|
|
5961
6083
|
return { success: true, result, index: originalIndex };
|
|
5962
6084
|
} catch (err) {
|
|
5963
6085
|
const error = err instanceof Error ? err : new Error(String(err));
|
|
@@ -5985,6 +6107,12 @@ ${errorMessages}`
|
|
|
5985
6107
|
return { results, errors, totalProcessed, totalFailed };
|
|
5986
6108
|
}
|
|
5987
6109
|
};
|
|
6110
|
+
_BatchProcessor.cb = new CircuitBreaker({
|
|
6111
|
+
failureThreshold: 5,
|
|
6112
|
+
resetTimeoutMs: 3e4,
|
|
6113
|
+
halfOpenMaxCalls: 1
|
|
6114
|
+
});
|
|
6115
|
+
var BatchProcessor = _BatchProcessor;
|
|
5988
6116
|
|
|
5989
6117
|
// src/config/EmbeddingStrategy.ts
|
|
5990
6118
|
var EmbeddingStrategy = /* @__PURE__ */ ((EmbeddingStrategy2) => {
|
|
@@ -6088,7 +6216,7 @@ var QueryProcessor = class {
|
|
|
6088
6216
|
* @param validFields Optional list of known filterable fields to look for
|
|
6089
6217
|
*/
|
|
6090
6218
|
static extractQueryFieldHints(question, validFields = []) {
|
|
6091
|
-
var
|
|
6219
|
+
var _a3, _b, _c, _d;
|
|
6092
6220
|
if (!question.trim()) return [];
|
|
6093
6221
|
const hints = /* @__PURE__ */ new Map();
|
|
6094
6222
|
const addHint = (value, field) => {
|
|
@@ -6168,7 +6296,7 @@ var QueryProcessor = class {
|
|
|
6168
6296
|
];
|
|
6169
6297
|
for (const p of universalPatterns) {
|
|
6170
6298
|
for (const match of question.matchAll(p.regex)) {
|
|
6171
|
-
const val = p.group ? (
|
|
6299
|
+
const val = p.group ? (_a3 = match[p.group]) != null ? _a3 : match[0] : match[0];
|
|
6172
6300
|
if (!val) continue;
|
|
6173
6301
|
if (p.field) addHint(val, p.field);
|
|
6174
6302
|
else addHint(val);
|
|
@@ -6392,11 +6520,11 @@ var LLMRouter = class {
|
|
|
6392
6520
|
* When provided it is used directly as the 'default' role without re-constructing.
|
|
6393
6521
|
*/
|
|
6394
6522
|
async initialize(prebuiltDefault) {
|
|
6395
|
-
var
|
|
6523
|
+
var _a3;
|
|
6396
6524
|
const defaultModel = prebuiltDefault != null ? prebuiltDefault : LLMFactory.create(this.config.llm, this.config.embedding);
|
|
6397
6525
|
this.models.set("default", defaultModel);
|
|
6398
6526
|
const envFastModel = process.env.FAST_LLM_MODEL;
|
|
6399
|
-
const providerFastDefault = (
|
|
6527
|
+
const providerFastDefault = (_a3 = FAST_MODEL_DEFAULTS[this.config.llm.provider]) != null ? _a3 : "";
|
|
6400
6528
|
const fastModelName = envFastModel || providerFastDefault;
|
|
6401
6529
|
if (fastModelName && fastModelName !== this.config.llm.model) {
|
|
6402
6530
|
console.log(`[LLMRouter] Fast role \u2192 provider="${this.config.llm.provider}" model="${fastModelName}"`);
|
|
@@ -6415,8 +6543,8 @@ var LLMRouter = class {
|
|
|
6415
6543
|
* Falls back to 'default' if the requested role is not registered.
|
|
6416
6544
|
*/
|
|
6417
6545
|
get(role) {
|
|
6418
|
-
var
|
|
6419
|
-
const provider = (
|
|
6546
|
+
var _a3;
|
|
6547
|
+
const provider = (_a3 = this.models.get(role)) != null ? _a3 : this.models.get("default");
|
|
6420
6548
|
if (!provider) {
|
|
6421
6549
|
throw new Error(`[LLMRouter] No provider registered for role: "${role}". Did you call initialize()?`);
|
|
6422
6550
|
}
|
|
@@ -6502,8 +6630,8 @@ var IntentClassifier = class {
|
|
|
6502
6630
|
numericFieldCount = numericKeys.size;
|
|
6503
6631
|
categoricalFieldCount = catKeys.size;
|
|
6504
6632
|
if (productKeyMatches >= 2 || docs.some((d) => {
|
|
6505
|
-
var
|
|
6506
|
-
return ((
|
|
6633
|
+
var _a3, _b;
|
|
6634
|
+
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");
|
|
6507
6635
|
})) {
|
|
6508
6636
|
isProductLike = true;
|
|
6509
6637
|
}
|
|
@@ -6785,8 +6913,8 @@ var TextRendererStrategy = class {
|
|
|
6785
6913
|
}
|
|
6786
6914
|
const docs = Array.isArray(data) ? data : [];
|
|
6787
6915
|
const text = docs.map((d) => {
|
|
6788
|
-
var
|
|
6789
|
-
return (
|
|
6916
|
+
var _a3;
|
|
6917
|
+
return (_a3 = d == null ? void 0 : d.content) != null ? _a3 : "";
|
|
6790
6918
|
}).join("\n\n");
|
|
6791
6919
|
return { type: "text", title, data: { content: text || "No detailed content available." } };
|
|
6792
6920
|
}
|
|
@@ -6929,9 +7057,9 @@ var LRUDecisionCache = class {
|
|
|
6929
7057
|
this.maxSize = maxSize;
|
|
6930
7058
|
}
|
|
6931
7059
|
generateKey(context) {
|
|
6932
|
-
var
|
|
7060
|
+
var _a3, _b;
|
|
6933
7061
|
const q = (context.userQuery || "").toLowerCase().trim();
|
|
6934
|
-
const docCount = (_b = (
|
|
7062
|
+
const docCount = (_b = (_a3 = context.retrievedDocuments) == null ? void 0 : _a3.length) != null ? _b : 0;
|
|
6935
7063
|
return `${q}::docs:${docCount}`;
|
|
6936
7064
|
}
|
|
6937
7065
|
get(context) {
|
|
@@ -7040,7 +7168,7 @@ var UITransformer = class _UITransformer {
|
|
|
7040
7168
|
* Prefer `analyzeAndDecide()` in production.
|
|
7041
7169
|
*/
|
|
7042
7170
|
static transform(userQuery, retrievedData, config, trainedSchema, intent) {
|
|
7043
|
-
var
|
|
7171
|
+
var _a3, _b, _c;
|
|
7044
7172
|
if (!retrievedData || retrievedData.length === 0) {
|
|
7045
7173
|
return this.createTextResponse("No data available", "No relevant data found for your query.");
|
|
7046
7174
|
}
|
|
@@ -7060,7 +7188,7 @@ var UITransformer = class _UITransformer {
|
|
|
7060
7188
|
return this.transformToBarChart(filteredData, profile, userQuery, resolvedIntent.visualizationHint === "ranking");
|
|
7061
7189
|
}
|
|
7062
7190
|
if (resolvedIntent.visualizationHint === "distribution") {
|
|
7063
|
-
return (
|
|
7191
|
+
return (_a3 = this.transformToHistogram(profile, userQuery)) != null ? _a3 : this.transformToBarChart(filteredData, profile, userQuery);
|
|
7064
7192
|
}
|
|
7065
7193
|
if (resolvedIntent.visualizationHint === "correlation") {
|
|
7066
7194
|
return (_b = this.transformToScatterPlot(profile, userQuery)) != null ? _b : this.transformToBarChart(filteredData, profile, userQuery);
|
|
@@ -7393,11 +7521,11 @@ ${schemaProfileText}` : ""}`;
|
|
|
7393
7521
|
};
|
|
7394
7522
|
}
|
|
7395
7523
|
static transformToPieChart(data, profile, query = "") {
|
|
7396
|
-
var
|
|
7524
|
+
var _a3;
|
|
7397
7525
|
const dimension = profile ? this.selectDimensionField(profile, query) : void 0;
|
|
7398
7526
|
const categories = dimension ? Array.from(new Set(profile.records.map((record) => {
|
|
7399
|
-
var
|
|
7400
|
-
return String((
|
|
7527
|
+
var _a4;
|
|
7528
|
+
return String((_a4 = record.fields[dimension.key]) != null ? _a4 : "");
|
|
7401
7529
|
}).filter(Boolean))) : this.detectCategories(data);
|
|
7402
7530
|
if (categories.length === 0) return null;
|
|
7403
7531
|
const categoryData = dimension && profile ? this.aggregateProfileByDimension(profile, dimension.key) : this.aggregateByCategory(data, categories);
|
|
@@ -7407,7 +7535,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7407
7535
|
});
|
|
7408
7536
|
return {
|
|
7409
7537
|
type: "pie_chart",
|
|
7410
|
-
title: `Distribution by ${(
|
|
7538
|
+
title: `Distribution by ${(_a3 = dimension == null ? void 0 : dimension.label) != null ? _a3 : "Category"}`,
|
|
7411
7539
|
description: `Showing breakdown across ${pieData.length} categories`,
|
|
7412
7540
|
data: pieData
|
|
7413
7541
|
};
|
|
@@ -7417,8 +7545,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7417
7545
|
const valueField = profile.numericFields[0];
|
|
7418
7546
|
const buckets = /* @__PURE__ */ new Map();
|
|
7419
7547
|
profile.records.forEach((record) => {
|
|
7420
|
-
var
|
|
7421
|
-
const timestamp = String((
|
|
7548
|
+
var _a3, _b, _c;
|
|
7549
|
+
const timestamp = String((_a3 = record.fields[dateField.key]) != null ? _a3 : "");
|
|
7422
7550
|
const value = (_b = this.toFiniteNumber(record.fields[valueField.key])) != null ? _b : 0;
|
|
7423
7551
|
buckets.set(timestamp, ((_c = buckets.get(timestamp)) != null ? _c : 0) + value);
|
|
7424
7552
|
});
|
|
@@ -7431,23 +7559,23 @@ ${schemaProfileText}` : ""}`;
|
|
|
7431
7559
|
};
|
|
7432
7560
|
}
|
|
7433
7561
|
static transformToBarChart(data, profile, query = "", horizontal = false) {
|
|
7434
|
-
var
|
|
7562
|
+
var _a3;
|
|
7435
7563
|
const dimension = profile ? this.selectDimensionField(profile, query) : void 0;
|
|
7436
7564
|
const measure = profile ? this.selectNumericField(profile, query) : void 0;
|
|
7437
7565
|
const aggregate = dimension && profile ? this.aggregateProfileByDimension(profile, dimension.key, measure == null ? void 0 : measure.key) : this.aggregateByCategory(data, this.detectCategories(data));
|
|
7438
7566
|
const barData = Object.entries(aggregate).map(([category, value]) => ({ category, value: Number(value) })).sort((a, b) => horizontal ? b.value - a.value : 0).slice(0, 12);
|
|
7439
7567
|
const fallbackData = barData.length > 0 ? barData : data.slice(0, 12).map((item, index) => {
|
|
7440
|
-
var
|
|
7568
|
+
var _a4, _b, _c, _d, _e;
|
|
7441
7569
|
const meta = item.metadata || {};
|
|
7442
7570
|
const label = String(
|
|
7443
|
-
(_c = (_b = (
|
|
7571
|
+
(_c = (_b = (_a4 = this.getDynamicVal(meta, "name")) != null ? _a4 : meta.label) != null ? _b : meta.title) != null ? _c : `Result ${index + 1}`
|
|
7444
7572
|
);
|
|
7445
7573
|
const value = (_e = (_d = this.extractNumericValue(meta)) != null ? _d : item.score) != null ? _e : 0;
|
|
7446
7574
|
return { category: label, value: Number(value) };
|
|
7447
7575
|
});
|
|
7448
7576
|
return {
|
|
7449
7577
|
type: horizontal ? "horizontal_bar" : "bar_chart",
|
|
7450
|
-
title: dimension ? `${(
|
|
7578
|
+
title: dimension ? `${(_a3 = measure == null ? void 0 : measure.label) != null ? _a3 : "Count"} by ${dimension.label}` : "Comparison",
|
|
7451
7579
|
description: `Showing ${fallbackData.length} comparable values`,
|
|
7452
7580
|
data: fallbackData
|
|
7453
7581
|
};
|
|
@@ -7482,11 +7610,11 @@ ${schemaProfileText}` : ""}`;
|
|
|
7482
7610
|
if (fields.length < 2) return null;
|
|
7483
7611
|
const [xField, yField] = fields;
|
|
7484
7612
|
const points = profile.records.map((record) => {
|
|
7485
|
-
var
|
|
7613
|
+
var _a3;
|
|
7486
7614
|
const x = this.toFiniteNumber(record.fields[xField.key]);
|
|
7487
7615
|
const y = this.toFiniteNumber(record.fields[yField.key]);
|
|
7488
7616
|
if (x === null || y === null) return null;
|
|
7489
|
-
return { x, y, label: String((
|
|
7617
|
+
return { x, y, label: String((_a3 = this.getRecordLabel(record)) != null ? _a3 : record.id) };
|
|
7490
7618
|
}).filter((point) => point !== null).slice(0, 100);
|
|
7491
7619
|
if (points.length === 0) return null;
|
|
7492
7620
|
return {
|
|
@@ -7516,9 +7644,9 @@ ${schemaProfileText}` : ""}`;
|
|
|
7516
7644
|
static transformToRadarChart(data) {
|
|
7517
7645
|
const attributeMap = {};
|
|
7518
7646
|
data.forEach((item) => {
|
|
7519
|
-
var
|
|
7647
|
+
var _a3, _b, _c;
|
|
7520
7648
|
const meta = item.metadata || {};
|
|
7521
|
-
const seriesName = String((_c = (_b = (
|
|
7649
|
+
const seriesName = String((_c = (_b = (_a3 = meta.name) != null ? _a3 : meta.product) != null ? _b : item.id) != null ? _c : "Item");
|
|
7522
7650
|
Object.entries(meta).forEach(([key, val]) => {
|
|
7523
7651
|
if (typeof val === "number" && !["price", "id"].includes(key.toLowerCase())) {
|
|
7524
7652
|
if (!attributeMap[key]) attributeMap[key] = {};
|
|
@@ -7534,8 +7662,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7534
7662
|
title: "Product Comparison",
|
|
7535
7663
|
description: `Comparing ${data.length} items across ${radarData.length} attributes`,
|
|
7536
7664
|
data: radarData.length > 0 ? radarData : data.map((d) => {
|
|
7537
|
-
var
|
|
7538
|
-
return { attribute: ((
|
|
7665
|
+
var _a3;
|
|
7666
|
+
return { attribute: ((_a3 = d == null ? void 0 : d.content) != null ? _a3 : "").substring(0, 40) };
|
|
7539
7667
|
})
|
|
7540
7668
|
};
|
|
7541
7669
|
}
|
|
@@ -7554,8 +7682,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7554
7682
|
return this.createTextResponse(
|
|
7555
7683
|
"Retrieved Context",
|
|
7556
7684
|
data.map((item) => {
|
|
7557
|
-
var
|
|
7558
|
-
return (
|
|
7685
|
+
var _a3;
|
|
7686
|
+
return (_a3 = item == null ? void 0 : item.content) != null ? _a3 : "";
|
|
7559
7687
|
}).join("\n\n"),
|
|
7560
7688
|
`Found ${data.length} relevant results`
|
|
7561
7689
|
);
|
|
@@ -7606,11 +7734,11 @@ ${schemaProfileText}` : ""}`;
|
|
|
7606
7734
|
return null;
|
|
7607
7735
|
}
|
|
7608
7736
|
static normalizeTransformation(payload) {
|
|
7609
|
-
var
|
|
7737
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j;
|
|
7610
7738
|
if (!payload || typeof payload !== "object") return null;
|
|
7611
7739
|
const p = payload;
|
|
7612
7740
|
const type = this.normalizeVisualizationType(
|
|
7613
|
-
String((_c = (_b = (
|
|
7741
|
+
String((_c = (_b = (_a3 = p.type) != null ? _a3 : p.view) != null ? _b : p.chartType) != null ? _c : "")
|
|
7614
7742
|
);
|
|
7615
7743
|
if (!type) return null;
|
|
7616
7744
|
const title = String((_e = (_d = p.title) != null ? _d : p.heading) != null ? _e : "Visualization");
|
|
@@ -7621,7 +7749,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7621
7749
|
return this.validateTransformation(transformation) ? transformation : null;
|
|
7622
7750
|
}
|
|
7623
7751
|
static normalizeVisualizationType(type) {
|
|
7624
|
-
var
|
|
7752
|
+
var _a3;
|
|
7625
7753
|
const mapping = {
|
|
7626
7754
|
pie: "pie_chart",
|
|
7627
7755
|
pie_chart: "pie_chart",
|
|
@@ -7649,7 +7777,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7649
7777
|
product_carousel: "product_carousel",
|
|
7650
7778
|
carousel: "carousel"
|
|
7651
7779
|
};
|
|
7652
|
-
return (
|
|
7780
|
+
return (_a3 = mapping[type.toLowerCase()]) != null ? _a3 : null;
|
|
7653
7781
|
}
|
|
7654
7782
|
static validateTransformation(t) {
|
|
7655
7783
|
const { type, data } = t;
|
|
@@ -7765,7 +7893,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7765
7893
|
}
|
|
7766
7894
|
static profileData(data) {
|
|
7767
7895
|
const records = (data || []).filter((item) => Boolean(item && typeof item === "object")).map((item) => {
|
|
7768
|
-
var
|
|
7896
|
+
var _a3, _b;
|
|
7769
7897
|
const fields2 = {};
|
|
7770
7898
|
Object.entries(item.metadata || {}).forEach(([key, value]) => {
|
|
7771
7899
|
const primitive = this.toPrimitive(value);
|
|
@@ -7774,7 +7902,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7774
7902
|
if (!fields2.content && item.content) fields2.content = item.content.substring(0, 500);
|
|
7775
7903
|
return {
|
|
7776
7904
|
id: item.id,
|
|
7777
|
-
content: (
|
|
7905
|
+
content: (_a3 = item.content) != null ? _a3 : "",
|
|
7778
7906
|
score: (_b = item.score) != null ? _b : 0,
|
|
7779
7907
|
fields: fields2,
|
|
7780
7908
|
source: item
|
|
@@ -7855,16 +7983,16 @@ ${schemaProfileText}` : ""}`;
|
|
|
7855
7983
|
return null;
|
|
7856
7984
|
}
|
|
7857
7985
|
static selectDimensionField(profile, query) {
|
|
7858
|
-
var
|
|
7986
|
+
var _a3, _b;
|
|
7859
7987
|
const productCategory = profile.categoricalFields.find(
|
|
7860
7988
|
(field) => /category|department|collection|type|group|segment|region|country|state|city/i.test(field.key)
|
|
7861
7989
|
);
|
|
7862
7990
|
const ranked = this.rankFieldsByQuery(profile.categoricalFields, query);
|
|
7863
|
-
return (_b = (
|
|
7991
|
+
return (_b = (_a3 = ranked[0]) != null ? _a3 : productCategory) != null ? _b : profile.categoricalFields[0];
|
|
7864
7992
|
}
|
|
7865
7993
|
static selectNumericField(profile, query) {
|
|
7866
|
-
var
|
|
7867
|
-
return (
|
|
7994
|
+
var _a3;
|
|
7995
|
+
return (_a3 = this.rankFieldsByQuery(profile.numericFields, query)[0]) != null ? _a3 : profile.numericFields[0];
|
|
7868
7996
|
}
|
|
7869
7997
|
static rankFieldsByQuery(fields, query) {
|
|
7870
7998
|
const q = query.toLowerCase();
|
|
@@ -7893,8 +8021,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7893
8021
|
static aggregateProfileByDimension(profile, dimensionKey, measureKey) {
|
|
7894
8022
|
const result = {};
|
|
7895
8023
|
profile.records.forEach((record) => {
|
|
7896
|
-
var
|
|
7897
|
-
const category = String((
|
|
8024
|
+
var _a3, _b, _c;
|
|
8025
|
+
const category = String((_a3 = record.fields[dimensionKey]) != null ? _a3 : "Other").trim() || "Other";
|
|
7898
8026
|
const value = measureKey ? (_b = this.toFiniteNumber(record.fields[measureKey])) != null ? _b : 0 : 1;
|
|
7899
8027
|
result[category] = ((_c = result[category]) != null ? _c : 0) + value;
|
|
7900
8028
|
});
|
|
@@ -7974,8 +8102,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7974
8102
|
static aggregateByCategory(data, categories) {
|
|
7975
8103
|
const result = Object.fromEntries(categories.map((c) => [c, 0]));
|
|
7976
8104
|
data.forEach((item) => {
|
|
7977
|
-
var
|
|
7978
|
-
const cat = (
|
|
8105
|
+
var _a3;
|
|
8106
|
+
const cat = (_a3 = this.getProductCategory(item)) != null ? _a3 : "Other";
|
|
7979
8107
|
if (Object.prototype.hasOwnProperty.call(result, cat)) result[cat]++;
|
|
7980
8108
|
else result["Other"] = (result["Other"] || 0) + 1;
|
|
7981
8109
|
});
|
|
@@ -7983,17 +8111,17 @@ ${schemaProfileText}` : ""}`;
|
|
|
7983
8111
|
}
|
|
7984
8112
|
static extractTimeSeriesData(data) {
|
|
7985
8113
|
return data.map((item) => {
|
|
7986
|
-
var
|
|
8114
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
7987
8115
|
const meta = item.metadata || {};
|
|
7988
8116
|
return {
|
|
7989
|
-
timestamp: (_b = (
|
|
8117
|
+
timestamp: (_b = (_a3 = meta.timestamp) != null ? _a3 : meta.date) != null ? _b : (/* @__PURE__ */ new Date()).toISOString(),
|
|
7990
8118
|
value: (_d = (_c = meta.value) != null ? _c : item.score) != null ? _d : 0,
|
|
7991
8119
|
label: (_f = meta.label) != null ? _f : ((_e = item == null ? void 0 : item.content) != null ? _e : "").substring(0, 50)
|
|
7992
8120
|
};
|
|
7993
8121
|
});
|
|
7994
8122
|
}
|
|
7995
8123
|
static extractNumericValue(meta) {
|
|
7996
|
-
var
|
|
8124
|
+
var _a3;
|
|
7997
8125
|
const preferredKeys = [
|
|
7998
8126
|
"value",
|
|
7999
8127
|
"count",
|
|
@@ -8008,7 +8136,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
8008
8136
|
"price"
|
|
8009
8137
|
];
|
|
8010
8138
|
for (const key of preferredKeys) {
|
|
8011
|
-
const raw = (
|
|
8139
|
+
const raw = (_a3 = resolveMetadataValue(meta, key)) != null ? _a3 : meta[key];
|
|
8012
8140
|
const value = typeof raw === "number" ? raw : Number(String(raw != null ? raw : "").replace(/[$,% ,]/g, ""));
|
|
8013
8141
|
if (Number.isFinite(value)) return value;
|
|
8014
8142
|
}
|
|
@@ -8103,8 +8231,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
8103
8231
|
}, query.includes(normalizedField) ? 3 : 0);
|
|
8104
8232
|
}
|
|
8105
8233
|
static resolveTableCellValue(item, column) {
|
|
8106
|
-
var
|
|
8107
|
-
if (column === "Content") return ((
|
|
8234
|
+
var _a3, _b, _c;
|
|
8235
|
+
if (column === "Content") return ((_a3 = item == null ? void 0 : item.content) != null ? _a3 : "").substring(0, 100);
|
|
8108
8236
|
const meta = item.metadata || {};
|
|
8109
8237
|
const normalizedColumn = this.normalizeComparableField(column);
|
|
8110
8238
|
const exactMetadata = Object.entries(meta).find(
|
|
@@ -8156,8 +8284,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
8156
8284
|
let inStock = 0;
|
|
8157
8285
|
let outOfStock = 0;
|
|
8158
8286
|
data.forEach((d) => {
|
|
8159
|
-
var
|
|
8160
|
-
const cat = (
|
|
8287
|
+
var _a3, _b;
|
|
8288
|
+
const cat = (_a3 = this.getProductCategory(d)) != null ? _a3 : "Other";
|
|
8161
8289
|
if (cat === category) {
|
|
8162
8290
|
const quantity = (_b = this.extractStockQuantity(d)) != null ? _b : 1;
|
|
8163
8291
|
if (this.determineStockStatus(d)) inStock += quantity;
|
|
@@ -8203,9 +8331,9 @@ ${schemaProfileText}` : ""}`;
|
|
|
8203
8331
|
}
|
|
8204
8332
|
// ─── Product Extraction ───────────────────────────────────────────────────
|
|
8205
8333
|
static getDynamicVal(meta, uiKey, config, trainedSchema) {
|
|
8206
|
-
var
|
|
8334
|
+
var _a3;
|
|
8207
8335
|
if (!meta) return void 0;
|
|
8208
|
-
const mapping = (
|
|
8336
|
+
const mapping = (_a3 = config == null ? void 0 : config.rag) == null ? void 0 : _a3.uiMapping;
|
|
8209
8337
|
if ((mapping == null ? void 0 : mapping[uiKey]) && meta[mapping[uiKey]] !== void 0) return meta[mapping[uiKey]];
|
|
8210
8338
|
if (trainedSchema && typeof trainedSchema === "object") {
|
|
8211
8339
|
const trainedKey = trainedSchema[uiKey];
|
|
@@ -8214,7 +8342,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
8214
8342
|
return resolveMetadataValue(meta, uiKey);
|
|
8215
8343
|
}
|
|
8216
8344
|
static extractProductInfo(item, config, trainedSchema) {
|
|
8217
|
-
var
|
|
8345
|
+
var _a3, _b;
|
|
8218
8346
|
if (!item) return null;
|
|
8219
8347
|
const meta = item.metadata || {};
|
|
8220
8348
|
const content = item.content || "";
|
|
@@ -8222,7 +8350,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
8222
8350
|
const price = this.getDynamicVal(meta, "price", config, trainedSchema);
|
|
8223
8351
|
const brand = this.getDynamicVal(meta, "brand", config, trainedSchema);
|
|
8224
8352
|
const description = this.cleanProductDescription(
|
|
8225
|
-
(
|
|
8353
|
+
(_a3 = this.extractProductDescriptionFromContent(content)) != null ? _a3 : this.getProductDescriptionValue(meta, config, trainedSchema)
|
|
8226
8354
|
);
|
|
8227
8355
|
if (name || this.isProductData(item)) {
|
|
8228
8356
|
let finalName = name ? String(name) : void 0;
|
|
@@ -8357,10 +8485,10 @@ RULES:
|
|
|
8357
8485
|
}
|
|
8358
8486
|
static buildContextSummary(sources, maxChars = 6e3) {
|
|
8359
8487
|
const items = (sources || []).filter(Boolean).map((s, i) => {
|
|
8360
|
-
var
|
|
8488
|
+
var _a3, _b, _c, _d;
|
|
8361
8489
|
return {
|
|
8362
8490
|
index: i + 1,
|
|
8363
|
-
content: (_b = (
|
|
8491
|
+
content: (_b = (_a3 = s == null ? void 0 : s.content) == null ? void 0 : _a3.substring(0, 400)) != null ? _b : "",
|
|
8364
8492
|
metadata: (_c = s == null ? void 0 : s.metadata) != null ? _c : {},
|
|
8365
8493
|
score: (_d = s == null ? void 0 : s.score) != null ? _d : 0
|
|
8366
8494
|
};
|
|
@@ -8400,7 +8528,7 @@ var SchemaMapper = class {
|
|
|
8400
8528
|
return promise;
|
|
8401
8529
|
}
|
|
8402
8530
|
static async _doTrain(llm, cacheKey, keys) {
|
|
8403
|
-
var
|
|
8531
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
|
|
8404
8532
|
console.log(`[SchemaMapper] \u{1F9E0} Training on new schema keys: ${keys.join(", ")}`);
|
|
8405
8533
|
const propertyList = Object.entries(this.TARGET_PROPERTIES).map(([prop, desc]) => `- ${prop} (${desc})`).join("\n");
|
|
8406
8534
|
const messages = [
|
|
@@ -8416,7 +8544,7 @@ Return a JSON object like {"name":"Title","price":"Price",...}. Omit unmapped pr
|
|
|
8416
8544
|
}
|
|
8417
8545
|
];
|
|
8418
8546
|
try {
|
|
8419
|
-
const baseUrl = (
|
|
8547
|
+
const baseUrl = (_a3 = llm == null ? void 0 : llm.baseUrl) != null ? _a3 : "";
|
|
8420
8548
|
const apiKey = (_b = llm == null ? void 0 : llm.apiKey) != null ? _b : "";
|
|
8421
8549
|
const model = (_c = llm == null ? void 0 : llm.model) != null ? _c : "llama-3.1-8b-instant";
|
|
8422
8550
|
let responseText;
|
|
@@ -8591,9 +8719,9 @@ var Pipeline = class {
|
|
|
8591
8719
|
this.initialised = false;
|
|
8592
8720
|
/** Namespace-specific static cold context cache for CAG */
|
|
8593
8721
|
this.coldContexts = /* @__PURE__ */ new Map();
|
|
8594
|
-
var
|
|
8722
|
+
var _a3, _b, _c, _d, _e;
|
|
8595
8723
|
this.chunker = new DocumentChunker(
|
|
8596
|
-
(_b = (
|
|
8724
|
+
(_b = (_a3 = config.rag) == null ? void 0 : _a3.chunkSize) != null ? _b : 1e3,
|
|
8597
8725
|
(_d = (_c = config.rag) == null ? void 0 : _c.chunkOverlap) != null ? _d : 200
|
|
8598
8726
|
);
|
|
8599
8727
|
if (((_e = config.rag) == null ? void 0 : _e.chunkingStrategy) === "llamaindex") {
|
|
@@ -8609,7 +8737,7 @@ var Pipeline = class {
|
|
|
8609
8737
|
return this.initialised ? this.llmProvider : void 0;
|
|
8610
8738
|
}
|
|
8611
8739
|
async initialize() {
|
|
8612
|
-
var
|
|
8740
|
+
var _a3, _b, _c, _d;
|
|
8613
8741
|
if (this.initialised) return;
|
|
8614
8742
|
const chartInstruction = `You are a helpful assistant. Use the provided context to answer questions accurately.
|
|
8615
8743
|
|
|
@@ -8652,7 +8780,7 @@ var Pipeline = class {
|
|
|
8652
8780
|
this.entityExtractor = new EntityExtractor(this.llmProvider);
|
|
8653
8781
|
}
|
|
8654
8782
|
await this.vectorDB.initialize();
|
|
8655
|
-
if (((
|
|
8783
|
+
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) {
|
|
8656
8784
|
this.mcpRegistry = new MCPRegistry(this.config.mcpServers || []);
|
|
8657
8785
|
this.multiAgentCoordinator = new MultiAgentCoordinator({
|
|
8658
8786
|
llmProvider: this.llmProvider,
|
|
@@ -8670,8 +8798,8 @@ var Pipeline = class {
|
|
|
8670
8798
|
this.initialised = true;
|
|
8671
8799
|
}
|
|
8672
8800
|
async loadColdContext(ns) {
|
|
8673
|
-
var
|
|
8674
|
-
const cagConfig = (
|
|
8801
|
+
var _a3, _b;
|
|
8802
|
+
const cagConfig = (_a3 = this.config.rag) == null ? void 0 : _a3.cag;
|
|
8675
8803
|
if (!cagConfig || !cagConfig.enabled) return;
|
|
8676
8804
|
try {
|
|
8677
8805
|
const coldNs = cagConfig.coldNamespace || ns;
|
|
@@ -8724,12 +8852,12 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8724
8852
|
}
|
|
8725
8853
|
/** Step 1: Chunk the document content. */
|
|
8726
8854
|
async prepareChunks(doc) {
|
|
8727
|
-
var
|
|
8855
|
+
var _a3, _b;
|
|
8728
8856
|
if (this.llamaIngestor) {
|
|
8729
8857
|
return this.llamaIngestor.chunk(doc.content, {
|
|
8730
8858
|
docId: doc.docId,
|
|
8731
8859
|
metadata: doc.metadata,
|
|
8732
|
-
chunkSize: (
|
|
8860
|
+
chunkSize: (_a3 = this.config.rag) == null ? void 0 : _a3.chunkSize,
|
|
8733
8861
|
chunkOverlap: (_b = this.config.rag) == null ? void 0 : _b.chunkOverlap
|
|
8734
8862
|
});
|
|
8735
8863
|
}
|
|
@@ -8827,9 +8955,9 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8827
8955
|
return { reply, sources };
|
|
8828
8956
|
}
|
|
8829
8957
|
async ask(question, history = [], namespace) {
|
|
8830
|
-
var
|
|
8958
|
+
var _a3, _b;
|
|
8831
8959
|
await this.initialize();
|
|
8832
|
-
if ((((
|
|
8960
|
+
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) {
|
|
8833
8961
|
return await this.multiAgentCoordinator.run(question, history);
|
|
8834
8962
|
}
|
|
8835
8963
|
const stream = this.askStream(question, history, namespace);
|
|
@@ -8864,9 +8992,9 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8864
8992
|
}
|
|
8865
8993
|
askStream(_0) {
|
|
8866
8994
|
return __asyncGenerator(this, arguments, function* (question, history = [], namespace) {
|
|
8867
|
-
var
|
|
8995
|
+
var _a3, _b;
|
|
8868
8996
|
yield new __await(this.initialize());
|
|
8869
|
-
if ((((
|
|
8997
|
+
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) {
|
|
8870
8998
|
const stream2 = this.multiAgentCoordinator.runStream(question, history);
|
|
8871
8999
|
try {
|
|
8872
9000
|
for (var iter = __forAwait(stream2), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
|
|
@@ -8915,10 +9043,10 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8915
9043
|
*/
|
|
8916
9044
|
askStreamInternal(_0) {
|
|
8917
9045
|
return __asyncGenerator(this, arguments, function* (question, history = [], namespace) {
|
|
8918
|
-
var
|
|
9046
|
+
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;
|
|
8919
9047
|
yield new __await(this.initialize());
|
|
8920
9048
|
const ns = formatNamespace(namespace != null ? namespace : this.config.projectId);
|
|
8921
|
-
const topK = (_b = (
|
|
9049
|
+
const topK = (_b = (_a3 = this.config.rag) == null ? void 0 : _a3.topK) != null ? _b : 5;
|
|
8922
9050
|
const scoreThreshold = (_d = (_c = this.config.rag) == null ? void 0 : _c.scoreThreshold) != null ? _d : 0.3;
|
|
8923
9051
|
const requestId = `req_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
8924
9052
|
const requestStart = performance.now();
|
|
@@ -8967,8 +9095,8 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8967
9095
|
const rerankStart = performance.now();
|
|
8968
9096
|
const structuredSources = this.applyStructuredFilters(rawSources, filter).filter((s) => Boolean(s && typeof s === "object"));
|
|
8969
9097
|
let fullSources = hasNumericPredicates ? structuredSources : structuredSources.filter((m) => {
|
|
8970
|
-
var
|
|
8971
|
-
return ((
|
|
9098
|
+
var _a4;
|
|
9099
|
+
return ((_a4 = m == null ? void 0 : m.score) != null ? _a4 : 0) >= scoreThreshold;
|
|
8972
9100
|
});
|
|
8973
9101
|
const rerankLimit = Math.max(retrievalLimit, fullSources.length);
|
|
8974
9102
|
const useReranking = arch !== "naive" && (arch === "retrieve-and-rerank" || ((_m = this.config.rag) == null ? void 0 : _m.useReranking));
|
|
@@ -8981,13 +9109,13 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8981
9109
|
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]
|
|
8982
9110
|
|
|
8983
9111
|
` + promptSources.map((m, i) => {
|
|
8984
|
-
var
|
|
9112
|
+
var _a4;
|
|
8985
9113
|
return `[Source ${i + 1}]
|
|
8986
|
-
${(
|
|
9114
|
+
${(_a4 = m == null ? void 0 : m.content) != null ? _a4 : ""}`;
|
|
8987
9115
|
}).join("\n\n---\n\n") : "No relevant context found.";
|
|
8988
9116
|
const sources = [...fullSources].filter((s) => Boolean(s && typeof s === "object")).sort((a, b) => {
|
|
8989
|
-
var
|
|
8990
|
-
return ((
|
|
9117
|
+
var _a4, _b2;
|
|
9118
|
+
return ((_a4 = b == null ? void 0 : b.score) != null ? _a4 : 0) - ((_b2 = a == null ? void 0 : a.score) != null ? _b2 : 0);
|
|
8991
9119
|
});
|
|
8992
9120
|
if (graphData && graphData.nodes.length > 0) {
|
|
8993
9121
|
const graphContext = graphData.nodes.map(
|
|
@@ -9015,10 +9143,10 @@ ${context}`;
|
|
|
9015
9143
|
yield {
|
|
9016
9144
|
reply: "",
|
|
9017
9145
|
sources: (sources || []).filter((s) => Boolean(s && typeof s === "object")).map((s) => {
|
|
9018
|
-
var
|
|
9146
|
+
var _a4, _b2, _c2;
|
|
9019
9147
|
return {
|
|
9020
9148
|
id: s.id,
|
|
9021
|
-
score: (
|
|
9149
|
+
score: (_a4 = s.score) != null ? _a4 : 0,
|
|
9022
9150
|
content: (_b2 = s == null ? void 0 : s.content) != null ? _b2 : "",
|
|
9023
9151
|
metadata: (_c2 = s == null ? void 0 : s.metadata) != null ? _c2 : {},
|
|
9024
9152
|
namespace: ns
|
|
@@ -9211,11 +9339,11 @@ ${context}`;
|
|
|
9211
9339
|
systemPrompt,
|
|
9212
9340
|
userPrompt: question + finalRestrictionSuffix,
|
|
9213
9341
|
chunks: (sources || []).filter(Boolean).map((s) => {
|
|
9214
|
-
var
|
|
9342
|
+
var _a4, _b2;
|
|
9215
9343
|
return {
|
|
9216
9344
|
id: s.id,
|
|
9217
9345
|
score: s.score,
|
|
9218
|
-
content: (
|
|
9346
|
+
content: (_a4 = s == null ? void 0 : s.content) != null ? _a4 : "",
|
|
9219
9347
|
metadata: (_b2 = s == null ? void 0 : s.metadata) != null ? _b2 : {},
|
|
9220
9348
|
namespace: ns
|
|
9221
9349
|
};
|
|
@@ -9234,7 +9362,7 @@ ${context}`;
|
|
|
9234
9362
|
const telemetryUrl = ((_B = this.config.telemetry) == null ? void 0 : _B.url) || process.env.TELEMETRY_URL || process.env.NEXT_PUBLIC_TELEMETRY_URL || defaultUrl;
|
|
9235
9363
|
const absoluteUrl = telemetryUrl.startsWith("http") ? telemetryUrl : "https://www.retrivora.com" + (telemetryUrl.startsWith("/") ? telemetryUrl : "/" + telemetryUrl);
|
|
9236
9364
|
(async () => {
|
|
9237
|
-
var
|
|
9365
|
+
var _a4, _b2, _c2, _d2, _e2;
|
|
9238
9366
|
try {
|
|
9239
9367
|
let finalTrace = trace;
|
|
9240
9368
|
if (!awaitHallucination && runHallucination) {
|
|
@@ -9243,7 +9371,7 @@ ${context}`;
|
|
|
9243
9371
|
finalTrace = buildTrace(backgroundScoreResult);
|
|
9244
9372
|
}
|
|
9245
9373
|
}
|
|
9246
|
-
const modelName = (finalTrace == null ? void 0 : finalTrace.model) || ((
|
|
9374
|
+
const modelName = (finalTrace == null ? void 0 : finalTrace.model) || ((_a4 = this.config.llm) == null ? void 0 : _a4.model) || "llama-3.1-8b-instant";
|
|
9247
9375
|
const providerName = (finalTrace == null ? void 0 : finalTrace.provider) || ((_b2 = this.config.llm) == null ? void 0 : _b2.provider) || "groq";
|
|
9248
9376
|
const tokenCount = Number(((_c2 = finalTrace == null ? void 0 : finalTrace.tokens) == null ? void 0 : _c2.totalTokens) || 0);
|
|
9249
9377
|
const costEst = Number(((_d2 = finalTrace == null ? void 0 : finalTrace.tokens) == null ? void 0 : _d2.estimatedCostUsd) || 0);
|
|
@@ -9297,7 +9425,7 @@ ${context}`;
|
|
|
9297
9425
|
* Uses an LRU-bounded embedding cache to avoid re-embedding the same query.
|
|
9298
9426
|
*/
|
|
9299
9427
|
async generateUiTransformation(question, sources, cachedSchema, forceDeterministic = false) {
|
|
9300
|
-
var
|
|
9428
|
+
var _a3;
|
|
9301
9429
|
if (!sources || sources.length === 0) {
|
|
9302
9430
|
return UITransformer.transform(question, sources, this.config, cachedSchema);
|
|
9303
9431
|
}
|
|
@@ -9310,7 +9438,7 @@ ${context}`;
|
|
|
9310
9438
|
{ visualizationHint: "product_browse", recommendedChart: "text", filterInStockOnly: false, wantsExplicitTable: false, isTemporal: false, isComparison: false, language: "en" }
|
|
9311
9439
|
);
|
|
9312
9440
|
}
|
|
9313
|
-
const enableLlmUiTransform = ((
|
|
9441
|
+
const enableLlmUiTransform = ((_a3 = this.config.llm.options) == null ? void 0 : _a3.enableLlmUiTransform) === true;
|
|
9314
9442
|
if (forceDeterministic || !enableLlmUiTransform) {
|
|
9315
9443
|
return UITransformer.transform(question, sources, this.config, cachedSchema);
|
|
9316
9444
|
}
|
|
@@ -9328,15 +9456,15 @@ ${context}`;
|
|
|
9328
9456
|
const value = this.resolveNumericPredicateValue(source, predicate);
|
|
9329
9457
|
return value !== null && this.matchesNumericPredicate(value, predicate);
|
|
9330
9458
|
})).sort((a, b) => {
|
|
9331
|
-
var
|
|
9459
|
+
var _a3, _b;
|
|
9332
9460
|
const primary = predicates[0];
|
|
9333
|
-
const aValue = (
|
|
9461
|
+
const aValue = (_a3 = this.resolveNumericPredicateValue(a, primary)) != null ? _a3 : 0;
|
|
9334
9462
|
const bValue = (_b = this.resolveNumericPredicateValue(b, primary)) != null ? _b : 0;
|
|
9335
9463
|
return primary.operator === "lt" || primary.operator === "lte" ? aValue - bValue : bValue - aValue;
|
|
9336
9464
|
});
|
|
9337
9465
|
}
|
|
9338
9466
|
resolveNumericPredicateValue(source, predicate) {
|
|
9339
|
-
var
|
|
9467
|
+
var _a3;
|
|
9340
9468
|
if (!source) return null;
|
|
9341
9469
|
const meta = source.metadata || {};
|
|
9342
9470
|
const field = predicate.field;
|
|
@@ -9349,7 +9477,7 @@ ${context}`;
|
|
|
9349
9477
|
const value = this.toFiniteNumber(Array.isArray(fuzzy) ? fuzzy[1] : fuzzy.value);
|
|
9350
9478
|
if (value !== null) return value;
|
|
9351
9479
|
}
|
|
9352
|
-
const contentValue = this.extractNumericValueFromContent((
|
|
9480
|
+
const contentValue = this.extractNumericValueFromContent((_a3 = source.content) != null ? _a3 : "", field);
|
|
9353
9481
|
if (contentValue !== null) return contentValue;
|
|
9354
9482
|
}
|
|
9355
9483
|
for (const [key, value] of entries) {
|
|
@@ -9405,8 +9533,8 @@ ${context}`;
|
|
|
9405
9533
|
return Number.isFinite(numeric) ? numeric : null;
|
|
9406
9534
|
}
|
|
9407
9535
|
async retrieve(query, options) {
|
|
9408
|
-
var
|
|
9409
|
-
const ns = formatNamespace((
|
|
9536
|
+
var _a3, _b, _c, _d, _e, _f, _g2;
|
|
9537
|
+
const ns = formatNamespace((_a3 = options.namespace) != null ? _a3 : this.config.projectId);
|
|
9410
9538
|
const topK = (_b = options.topK) != null ? _b : 5;
|
|
9411
9539
|
const cacheKey = `${ns}::${query}`;
|
|
9412
9540
|
let queryVector = this.embeddingCache.get(cacheKey);
|
|
@@ -9451,11 +9579,11 @@ ${context}`;
|
|
|
9451
9579
|
namespace: ns,
|
|
9452
9580
|
count: resolvedSources.length,
|
|
9453
9581
|
sample: resolvedSources.slice(0, 2).map((s) => {
|
|
9454
|
-
var
|
|
9582
|
+
var _a4;
|
|
9455
9583
|
return {
|
|
9456
9584
|
id: s == null ? void 0 : s.id,
|
|
9457
9585
|
score: s == null ? void 0 : s.score,
|
|
9458
|
-
contentSnippet: String((
|
|
9586
|
+
contentSnippet: String((_a4 = s == null ? void 0 : s.content) != null ? _a4 : "").substring(0, 150),
|
|
9459
9587
|
metadata: s == null ? void 0 : s.metadata
|
|
9460
9588
|
};
|
|
9461
9589
|
})
|
|
@@ -9469,8 +9597,8 @@ Focus on extracting the core intent and entities. Do not answer the question, ju
|
|
|
9469
9597
|
|
|
9470
9598
|
History:
|
|
9471
9599
|
${(history || []).map((m) => {
|
|
9472
|
-
var
|
|
9473
|
-
return `${(m == null ? void 0 : m.role) || "user"}: ${(
|
|
9600
|
+
var _a3;
|
|
9601
|
+
return `${(m == null ? void 0 : m.role) || "user"}: ${(_a3 = m == null ? void 0 : m.content) != null ? _a3 : ""}`;
|
|
9474
9602
|
}).join("\n")}
|
|
9475
9603
|
|
|
9476
9604
|
New Question: ${question}
|
|
@@ -9497,8 +9625,8 @@ Optimized Search Query:`;
|
|
|
9497
9625
|
const { sources } = await this.retrieve(query, { namespace: ns, topK: 5 });
|
|
9498
9626
|
if (!sources || sources.length === 0) return [];
|
|
9499
9627
|
const context = sources.map((s) => {
|
|
9500
|
-
var
|
|
9501
|
-
return (
|
|
9628
|
+
var _a3;
|
|
9629
|
+
return (_a3 = s == null ? void 0 : s.content) != null ? _a3 : "";
|
|
9502
9630
|
}).join("\n\n---\n\n");
|
|
9503
9631
|
const prompt = `Based on the following snippets from a document, what are at least 5 short, relevant questions a user might ask?
|
|
9504
9632
|
Focus on questions that can be answered by the context.
|
|
@@ -9540,13 +9668,13 @@ var Retrivora = class {
|
|
|
9540
9668
|
this.pipeline = new Pipeline(this.config);
|
|
9541
9669
|
}
|
|
9542
9670
|
async initialize() {
|
|
9543
|
-
var
|
|
9671
|
+
var _a3;
|
|
9544
9672
|
try {
|
|
9545
9673
|
await ConfigValidator.validateAndThrow(this.config);
|
|
9546
9674
|
LicenseVerifier.verify(
|
|
9547
9675
|
this.config.licenseKey,
|
|
9548
9676
|
this.config.projectId,
|
|
9549
|
-
(
|
|
9677
|
+
(_a3 = this.config.vectorDb) == null ? void 0 : _a3.provider
|
|
9550
9678
|
);
|
|
9551
9679
|
await LicenseVerifier.verifyIP(this.config.licenseKey);
|
|
9552
9680
|
} catch (err) {
|
|
@@ -9719,18 +9847,200 @@ var ProviderHealthCheck = class {
|
|
|
9719
9847
|
}
|
|
9720
9848
|
};
|
|
9721
9849
|
|
|
9850
|
+
// src/core/FreeTierLimitsGuard.ts
|
|
9851
|
+
var FREE_TIER_QUOTAS = {
|
|
9852
|
+
MAX_DOCUMENTS: 25,
|
|
9853
|
+
MAX_FILE_SIZE_BYTES: 20 * 1024 * 1024,
|
|
9854
|
+
MAX_STORAGE_BYTES: 250 * 1024 * 1024,
|
|
9855
|
+
MAX_TRIAL_REQUEST_UNITS: 500,
|
|
9856
|
+
MAX_DAILY_REQUEST_UNITS: 50,
|
|
9857
|
+
TRIAL_DURATION_DAYS: 14,
|
|
9858
|
+
GRACE_PERIOD_DAYS: 2,
|
|
9859
|
+
MAX_RPM: 10,
|
|
9860
|
+
MAX_RPH: 100,
|
|
9861
|
+
MAX_RPD: 500,
|
|
9862
|
+
MAX_CONCURRENT_REQUESTS: 2,
|
|
9863
|
+
MAX_INPUT_TOKENS: 2e4,
|
|
9864
|
+
MAX_OUTPUT_TOKENS: 4e3,
|
|
9865
|
+
UPGRADE_REMINDER_DAYS: [7, 12, 14],
|
|
9866
|
+
MAX_USERS: 1,
|
|
9867
|
+
MAX_NAMESPACES: 1,
|
|
9868
|
+
MAX_PROJECTS: 1
|
|
9869
|
+
};
|
|
9870
|
+
var FreeTierLimitsGuard = class {
|
|
9871
|
+
static calculateTrialTimestamps(startedAt) {
|
|
9872
|
+
const startDate = startedAt ? new Date(startedAt) : /* @__PURE__ */ new Date();
|
|
9873
|
+
const trialStartedAtMs = startDate.getTime();
|
|
9874
|
+
const trialExpiresAtMs = trialStartedAtMs + FREE_TIER_QUOTAS.TRIAL_DURATION_DAYS * 24 * 60 * 60 * 1e3;
|
|
9875
|
+
const gracePeriodExpiresAtMs = trialStartedAtMs + (FREE_TIER_QUOTAS.TRIAL_DURATION_DAYS + FREE_TIER_QUOTAS.GRACE_PERIOD_DAYS) * 24 * 60 * 60 * 1e3;
|
|
9876
|
+
return {
|
|
9877
|
+
trial_started_at: new Date(trialStartedAtMs).toISOString(),
|
|
9878
|
+
trial_expires_at: new Date(trialExpiresAtMs).toISOString(),
|
|
9879
|
+
grace_period_expires_at: new Date(gracePeriodExpiresAtMs).toISOString()
|
|
9880
|
+
};
|
|
9881
|
+
}
|
|
9882
|
+
static calculateRequestUnits(operationType, options) {
|
|
9883
|
+
var _a3;
|
|
9884
|
+
const op = operationType.toLowerCase().trim();
|
|
9885
|
+
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")) {
|
|
9886
|
+
return 0;
|
|
9887
|
+
}
|
|
9888
|
+
if (op.includes("image")) {
|
|
9889
|
+
return 10;
|
|
9890
|
+
}
|
|
9891
|
+
if (op.includes("embedding")) {
|
|
9892
|
+
const chunks = (_a3 = options == null ? void 0 : options.chunkCount) != null ? _a3 : 1;
|
|
9893
|
+
return Math.max(1, Math.ceil(chunks / 1e3));
|
|
9894
|
+
}
|
|
9895
|
+
return 1;
|
|
9896
|
+
}
|
|
9897
|
+
static checkTrialStatus(startedAt, totalUnitsUsed = 0, nowServerTime = /* @__PURE__ */ new Date()) {
|
|
9898
|
+
const timestamps = this.calculateTrialTimestamps(startedAt);
|
|
9899
|
+
const startMs = new Date(timestamps.trial_started_at).getTime();
|
|
9900
|
+
const expireMs = new Date(timestamps.trial_expires_at).getTime();
|
|
9901
|
+
const graceExpireMs = new Date(timestamps.grace_period_expires_at).getTime();
|
|
9902
|
+
const nowMs = nowServerTime.getTime();
|
|
9903
|
+
const daysElapsed = Math.floor(Math.max(0, nowMs - startMs) / (1e3 * 60 * 60 * 24));
|
|
9904
|
+
const daysRemaining = Math.max(0, Math.ceil((expireMs - nowMs) / (1e3 * 60 * 60 * 24)));
|
|
9905
|
+
const isConsumedUnits = totalUnitsUsed >= FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS;
|
|
9906
|
+
const isExpiredTime = nowMs > expireMs;
|
|
9907
|
+
const isPastGraceTime = nowMs > graceExpireMs;
|
|
9908
|
+
let status = "active";
|
|
9909
|
+
let reason;
|
|
9910
|
+
if (isPastGraceTime || isConsumedUnits && isExpiredTime) {
|
|
9911
|
+
status = "expired";
|
|
9912
|
+
reason = "Trial period and grace period have expired. Upgrade your plan.";
|
|
9913
|
+
} else if (isExpiredTime || isConsumedUnits) {
|
|
9914
|
+
status = "grace_period";
|
|
9915
|
+
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).";
|
|
9916
|
+
}
|
|
9917
|
+
let upgradeReminderDue;
|
|
9918
|
+
if (FREE_TIER_QUOTAS.UPGRADE_REMINDER_DAYS.includes(daysElapsed)) {
|
|
9919
|
+
upgradeReminderDue = daysElapsed;
|
|
9920
|
+
}
|
|
9921
|
+
let usageReminderDue;
|
|
9922
|
+
const usagePercent = totalUnitsUsed / FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS * 100;
|
|
9923
|
+
if (usagePercent >= 100) {
|
|
9924
|
+
usageReminderDue = "100%";
|
|
9925
|
+
} else if (usagePercent >= 90) {
|
|
9926
|
+
usageReminderDue = "90%";
|
|
9927
|
+
} else if (usagePercent >= 80) {
|
|
9928
|
+
usageReminderDue = "80%";
|
|
9929
|
+
}
|
|
9930
|
+
return {
|
|
9931
|
+
status,
|
|
9932
|
+
daysElapsed,
|
|
9933
|
+
daysRemaining,
|
|
9934
|
+
isGracePeriod: status === "grace_period",
|
|
9935
|
+
isExpired: status === "expired",
|
|
9936
|
+
upgradeReminderDue,
|
|
9937
|
+
usageReminderDue,
|
|
9938
|
+
reason
|
|
9939
|
+
};
|
|
9940
|
+
}
|
|
9941
|
+
static checkIngestionAllowed(stats, incomingSizeBytes = 0) {
|
|
9942
|
+
var _a3, _b;
|
|
9943
|
+
const docs = (_a3 = stats.documentCount) != null ? _a3 : 0;
|
|
9944
|
+
const storage = (_b = stats.totalStorageBytes) != null ? _b : 0;
|
|
9945
|
+
if (incomingSizeBytes > FREE_TIER_QUOTAS.MAX_FILE_SIZE_BYTES) {
|
|
9946
|
+
const mbSize = (incomingSizeBytes / (1024 * 1024)).toFixed(1);
|
|
9947
|
+
return {
|
|
9948
|
+
allowed: false,
|
|
9949
|
+
reason: `[FreeTierIngestor] File size (${mbSize}MB) exceeds maximum allowed size of 20MB under Free Tier rules.`
|
|
9950
|
+
};
|
|
9951
|
+
}
|
|
9952
|
+
if (docs >= FREE_TIER_QUOTAS.MAX_DOCUMENTS) {
|
|
9953
|
+
return {
|
|
9954
|
+
allowed: false,
|
|
9955
|
+
reason: `Document limit reached (${docs}/${FREE_TIER_QUOTAS.MAX_DOCUMENTS}). Upgrade to Pro to ingest more documents.`
|
|
9956
|
+
};
|
|
9957
|
+
}
|
|
9958
|
+
if (storage + incomingSizeBytes > FREE_TIER_QUOTAS.MAX_STORAGE_BYTES) {
|
|
9959
|
+
const mbUsed = (storage / (1024 * 1024)).toFixed(1);
|
|
9960
|
+
return {
|
|
9961
|
+
allowed: false,
|
|
9962
|
+
reason: `Storage quota exceeded (${mbUsed}MB / 250MB). Upgrade for unlimited storage.`
|
|
9963
|
+
};
|
|
9964
|
+
}
|
|
9965
|
+
return { allowed: true };
|
|
9966
|
+
}
|
|
9967
|
+
static checkRequestAllowed(params) {
|
|
9968
|
+
var _a3, _b, _c;
|
|
9969
|
+
const op = (_a3 = params.operationType) != null ? _a3 : "chat";
|
|
9970
|
+
const costUnits = this.calculateRequestUnits(op, { chunkCount: params.chunkCount });
|
|
9971
|
+
if (costUnits === 0) {
|
|
9972
|
+
return { allowed: true, costUnits: 0 };
|
|
9973
|
+
}
|
|
9974
|
+
if (params.inputTokens && params.inputTokens > FREE_TIER_QUOTAS.MAX_INPUT_TOKENS) {
|
|
9975
|
+
return {
|
|
9976
|
+
allowed: false,
|
|
9977
|
+
reason: "Token limit exceeded. Upgrade your plan.",
|
|
9978
|
+
costUnits
|
|
9979
|
+
};
|
|
9980
|
+
}
|
|
9981
|
+
if (params.outputTokens && params.outputTokens > FREE_TIER_QUOTAS.MAX_OUTPUT_TOKENS) {
|
|
9982
|
+
return {
|
|
9983
|
+
allowed: false,
|
|
9984
|
+
reason: "Token limit exceeded. Upgrade your plan.",
|
|
9985
|
+
costUnits
|
|
9986
|
+
};
|
|
9987
|
+
}
|
|
9988
|
+
if (params.concurrentRequests && params.concurrentRequests > FREE_TIER_QUOTAS.MAX_CONCURRENT_REQUESTS) {
|
|
9989
|
+
return {
|
|
9990
|
+
allowed: false,
|
|
9991
|
+
reason: `Concurrent limit exceeded (max ${FREE_TIER_QUOTAS.MAX_CONCURRENT_REQUESTS} active requests). Please wait for active streams to finish.`,
|
|
9992
|
+
costUnits
|
|
9993
|
+
};
|
|
9994
|
+
}
|
|
9995
|
+
const totalUnits = (_b = params.totalUnitsUsed) != null ? _b : 0;
|
|
9996
|
+
const trialStatus = this.checkTrialStatus(params.trialStartedAt, totalUnits, params.nowServerTime);
|
|
9997
|
+
if (trialStatus.status === "expired" || trialStatus.status === "grace_period") {
|
|
9998
|
+
return {
|
|
9999
|
+
allowed: false,
|
|
10000
|
+
reason: trialStatus.reason || "Trial limit reached. Upgrade your plan.",
|
|
10001
|
+
costUnits
|
|
10002
|
+
};
|
|
10003
|
+
}
|
|
10004
|
+
if (totalUnits + costUnits > FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS) {
|
|
10005
|
+
return {
|
|
10006
|
+
allowed: false,
|
|
10007
|
+
reason: `Total trial request unit limit reached (${totalUnits}/${FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS}). Upgrade your plan.`,
|
|
10008
|
+
costUnits
|
|
10009
|
+
};
|
|
10010
|
+
}
|
|
10011
|
+
const dailyUnits = (_c = params.dailyUnitsUsed) != null ? _c : 0;
|
|
10012
|
+
if (dailyUnits + costUnits > FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS) {
|
|
10013
|
+
return {
|
|
10014
|
+
allowed: false,
|
|
10015
|
+
reason: `Daily request quota limit reached (${dailyUnits}/${FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS} units/day). Quota resets tomorrow.`,
|
|
10016
|
+
costUnits
|
|
10017
|
+
};
|
|
10018
|
+
}
|
|
10019
|
+
return { allowed: true, costUnits };
|
|
10020
|
+
}
|
|
10021
|
+
static checkQueryAllowed(dailyQueriesCount = 0) {
|
|
10022
|
+
if (dailyQueriesCount >= FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS) {
|
|
10023
|
+
return {
|
|
10024
|
+
allowed: false,
|
|
10025
|
+
reason: `Daily query limit reached (${FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS}/day). Quota resets tomorrow.`
|
|
10026
|
+
};
|
|
10027
|
+
}
|
|
10028
|
+
return { allowed: true };
|
|
10029
|
+
}
|
|
10030
|
+
};
|
|
10031
|
+
|
|
9722
10032
|
// src/core/VectorPlugin.ts
|
|
9723
10033
|
var VectorPlugin = class {
|
|
9724
10034
|
constructor(hostConfig) {
|
|
9725
10035
|
const resolvedConfig = ConfigResolver.resolve(hostConfig);
|
|
9726
10036
|
this.config = resolvedConfig;
|
|
9727
10037
|
this.validationPromise = (async () => {
|
|
9728
|
-
var
|
|
10038
|
+
var _a3;
|
|
9729
10039
|
await ConfigValidator.validateAndThrow(resolvedConfig);
|
|
9730
10040
|
LicenseVerifier.verify(
|
|
9731
10041
|
resolvedConfig.licenseKey,
|
|
9732
10042
|
resolvedConfig.projectId,
|
|
9733
|
-
(
|
|
10043
|
+
(_a3 = resolvedConfig.vectorDb) == null ? void 0 : _a3.provider
|
|
9734
10044
|
);
|
|
9735
10045
|
})();
|
|
9736
10046
|
this.validationPromise.catch(() => {
|
|
@@ -9764,16 +10074,32 @@ var VectorPlugin = class {
|
|
|
9764
10074
|
this.config.embedding
|
|
9765
10075
|
);
|
|
9766
10076
|
}
|
|
10077
|
+
estimateInputTokens(message, history = []) {
|
|
10078
|
+
const allContent = message.length + history.reduce((acc, m) => {
|
|
10079
|
+
var _a3, _b;
|
|
10080
|
+
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);
|
|
10081
|
+
}, 0);
|
|
10082
|
+
return Math.ceil(allContent / 4);
|
|
10083
|
+
}
|
|
9767
10084
|
/**
|
|
9768
10085
|
* Run a chat query.
|
|
9769
10086
|
*/
|
|
9770
10087
|
async chat(message, history = [], namespace) {
|
|
10088
|
+
var _a3;
|
|
9771
10089
|
try {
|
|
9772
10090
|
await this.validationPromise;
|
|
9773
10091
|
} catch (err) {
|
|
9774
10092
|
throw wrapError(err, "CONFIGURATION_ERROR");
|
|
9775
10093
|
}
|
|
9776
10094
|
try {
|
|
10095
|
+
const inputTokens = this.estimateInputTokens(message, history);
|
|
10096
|
+
const tokenCheck = FreeTierLimitsGuard.checkRequestAllowed({
|
|
10097
|
+
operationType: "chat",
|
|
10098
|
+
inputTokens
|
|
10099
|
+
});
|
|
10100
|
+
if (!tokenCheck.allowed && ((_a3 = tokenCheck.reason) == null ? void 0 : _a3.toLowerCase().includes("token"))) {
|
|
10101
|
+
throw wrapError(new Error(tokenCheck.reason), "RATE_LIMITED");
|
|
10102
|
+
}
|
|
9777
10103
|
return await this.pipeline.ask(message, history, namespace);
|
|
9778
10104
|
} catch (err) {
|
|
9779
10105
|
const msg = String(err);
|
|
@@ -9781,6 +10107,9 @@ var VectorPlugin = class {
|
|
|
9781
10107
|
if (msg.includes("Embed") || msg.includes("embed")) {
|
|
9782
10108
|
defaultCode = "EMBEDDING_FAILED";
|
|
9783
10109
|
}
|
|
10110
|
+
if (msg.toLowerCase().includes("token limit")) {
|
|
10111
|
+
defaultCode = "RATE_LIMITED";
|
|
10112
|
+
}
|
|
9784
10113
|
throw wrapError(err, defaultCode);
|
|
9785
10114
|
}
|
|
9786
10115
|
}
|
|
@@ -9789,12 +10118,21 @@ var VectorPlugin = class {
|
|
|
9789
10118
|
*/
|
|
9790
10119
|
chatStream(_0) {
|
|
9791
10120
|
return __asyncGenerator(this, arguments, function* (message, history = [], namespace) {
|
|
10121
|
+
var _a3;
|
|
9792
10122
|
try {
|
|
9793
10123
|
yield new __await(this.validationPromise);
|
|
9794
10124
|
} catch (err) {
|
|
9795
10125
|
throw wrapError(err, "CONFIGURATION_ERROR");
|
|
9796
10126
|
}
|
|
9797
10127
|
try {
|
|
10128
|
+
const inputTokens = this.estimateInputTokens(message, history);
|
|
10129
|
+
const tokenCheck = FreeTierLimitsGuard.checkRequestAllowed({
|
|
10130
|
+
operationType: "chat_stream",
|
|
10131
|
+
inputTokens
|
|
10132
|
+
});
|
|
10133
|
+
if (!tokenCheck.allowed && ((_a3 = tokenCheck.reason) == null ? void 0 : _a3.toLowerCase().includes("token"))) {
|
|
10134
|
+
throw wrapError(new Error(tokenCheck.reason), "RATE_LIMITED");
|
|
10135
|
+
}
|
|
9798
10136
|
const stream = this.pipeline.askStream(message, history, namespace);
|
|
9799
10137
|
try {
|
|
9800
10138
|
for (var iter = __forAwait(stream), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
|
|
@@ -9817,6 +10155,9 @@ var VectorPlugin = class {
|
|
|
9817
10155
|
if (msg.includes("Embed") || msg.includes("embed")) {
|
|
9818
10156
|
defaultCode = "EMBEDDING_FAILED";
|
|
9819
10157
|
}
|
|
10158
|
+
if (msg.toLowerCase().includes("token limit")) {
|
|
10159
|
+
defaultCode = "RATE_LIMITED";
|
|
10160
|
+
}
|
|
9820
10161
|
throw wrapError(err, defaultCode);
|
|
9821
10162
|
}
|
|
9822
10163
|
});
|
|
@@ -9871,13 +10212,13 @@ var ConfigBuilder = class {
|
|
|
9871
10212
|
* Configure the vector database provider
|
|
9872
10213
|
*/
|
|
9873
10214
|
vectorDb(provider, options) {
|
|
9874
|
-
var
|
|
10215
|
+
var _a3;
|
|
9875
10216
|
if (provider === "auto") {
|
|
9876
10217
|
this._vectorDb = this._autoDetectVectorDb();
|
|
9877
10218
|
} else {
|
|
9878
10219
|
this._vectorDb = {
|
|
9879
10220
|
provider,
|
|
9880
|
-
indexName: (
|
|
10221
|
+
indexName: (_a3 = options == null ? void 0 : options.indexName) != null ? _a3 : "default",
|
|
9881
10222
|
options: __spreadValues({}, options)
|
|
9882
10223
|
};
|
|
9883
10224
|
}
|
|
@@ -9887,7 +10228,7 @@ var ConfigBuilder = class {
|
|
|
9887
10228
|
* Configure the LLM provider for chat
|
|
9888
10229
|
*/
|
|
9889
10230
|
llm(provider, model, apiKey, options) {
|
|
9890
|
-
var
|
|
10231
|
+
var _a3, _b;
|
|
9891
10232
|
if (provider === "auto") {
|
|
9892
10233
|
this._llm = this._autoDetectLLM();
|
|
9893
10234
|
} else {
|
|
@@ -9896,7 +10237,7 @@ var ConfigBuilder = class {
|
|
|
9896
10237
|
model: model != null ? model : "default-model",
|
|
9897
10238
|
apiKey,
|
|
9898
10239
|
systemPrompt: options == null ? void 0 : options.systemPrompt,
|
|
9899
|
-
maxTokens: (
|
|
10240
|
+
maxTokens: (_a3 = options == null ? void 0 : options.maxTokens) != null ? _a3 : 1024,
|
|
9900
10241
|
temperature: (_b = options == null ? void 0 : options.temperature) != null ? _b : 0.7,
|
|
9901
10242
|
baseUrl: options == null ? void 0 : options.baseUrl,
|
|
9902
10243
|
options
|
|
@@ -9939,8 +10280,8 @@ var ConfigBuilder = class {
|
|
|
9939
10280
|
* Set RAG-specific pipeline parameters
|
|
9940
10281
|
*/
|
|
9941
10282
|
rag(options) {
|
|
9942
|
-
var
|
|
9943
|
-
this._rag = __spreadValues(__spreadValues({}, (
|
|
10283
|
+
var _a3;
|
|
10284
|
+
this._rag = __spreadValues(__spreadValues({}, (_a3 = this._rag) != null ? _a3 : {}), options);
|
|
9944
10285
|
return this;
|
|
9945
10286
|
}
|
|
9946
10287
|
/**
|
|
@@ -9956,7 +10297,7 @@ var ConfigBuilder = class {
|
|
|
9956
10297
|
* Throws if required fields (projectId, vectorDb, llm, embedding) are not set.
|
|
9957
10298
|
*/
|
|
9958
10299
|
build() {
|
|
9959
|
-
var
|
|
10300
|
+
var _a3;
|
|
9960
10301
|
const missing = [];
|
|
9961
10302
|
if (!this._projectId) missing.push('projectId (call .projectId("my-app"))');
|
|
9962
10303
|
if (!this._vectorDb) missing.push('vectorDb (call .vectorDb("pinecone", { ... }))');
|
|
@@ -9968,7 +10309,7 @@ var ConfigBuilder = class {
|
|
|
9968
10309
|
${missing.join("\n ")}`
|
|
9969
10310
|
);
|
|
9970
10311
|
}
|
|
9971
|
-
const ragConfig = (
|
|
10312
|
+
const ragConfig = (_a3 = this._rag) != null ? _a3 : { chunkSize: 1e3, chunkOverlap: 200, topK: 5 };
|
|
9972
10313
|
if (process.env.RAG_USE_GRAPH_RETRIEVAL === "true") {
|
|
9973
10314
|
ragConfig.useGraphRetrieval = true;
|
|
9974
10315
|
}
|
|
@@ -10064,8 +10405,8 @@ var DocumentParser = class {
|
|
|
10064
10405
|
* Extract text from a File or Buffer based on its type.
|
|
10065
10406
|
*/
|
|
10066
10407
|
static async parse(file, fileName, mimeType) {
|
|
10067
|
-
var
|
|
10068
|
-
const extension = ((
|
|
10408
|
+
var _a3;
|
|
10409
|
+
const extension = ((_a3 = fileName.split(".").pop()) == null ? void 0 : _a3.toLowerCase()) || "";
|
|
10069
10410
|
if (extension === "txt" || extension === "md" || mimeType === "text/plain" || mimeType === "text/markdown") {
|
|
10070
10411
|
return this.readAsText(file);
|
|
10071
10412
|
}
|
|
@@ -10172,9 +10513,9 @@ var DatabaseStorage = class {
|
|
|
10172
10513
|
this.fallbackDir = this.isServerless ? path.join(os.tmpdir(), ".retrivora") : path.join(process.cwd(), ".retrivora");
|
|
10173
10514
|
this.historyFile = path.join(this.fallbackDir, "history.json");
|
|
10174
10515
|
this.feedbackFile = path.join(this.fallbackDir, "feedback.json");
|
|
10175
|
-
var
|
|
10516
|
+
var _a3, _b, _c, _d, _e;
|
|
10176
10517
|
this.config = config;
|
|
10177
|
-
this.provider = ((
|
|
10518
|
+
this.provider = ((_a3 = config.vectorDb) == null ? void 0 : _a3.provider) || "fs";
|
|
10178
10519
|
const rawHistoryTable = ((_c = (_b = config.rag) == null ? void 0 : _b.history) == null ? void 0 : _c.tableName) || "retrivora_history";
|
|
10179
10520
|
const rawFeedbackTable = ((_e = (_d = config.rag) == null ? void 0 : _d.feedback) == null ? void 0 : _e.tableName) || "retrivora_feedback";
|
|
10180
10521
|
this.historyTableName = rawHistoryTable.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
@@ -10209,16 +10550,16 @@ var DatabaseStorage = class {
|
|
|
10209
10550
|
}
|
|
10210
10551
|
}
|
|
10211
10552
|
checkHistoryEnabled() {
|
|
10212
|
-
var
|
|
10553
|
+
var _a3, _b;
|
|
10213
10554
|
this.checkPremiumSubscription();
|
|
10214
|
-
if (((_b = (
|
|
10555
|
+
if (((_b = (_a3 = this.config.rag) == null ? void 0 : _a3.history) == null ? void 0 : _b.enabled) === false) {
|
|
10215
10556
|
throw new Error("[Retrivora SDK] Chat History is disabled in RagConfig.");
|
|
10216
10557
|
}
|
|
10217
10558
|
}
|
|
10218
10559
|
checkFeedbackEnabled() {
|
|
10219
|
-
var
|
|
10560
|
+
var _a3, _b;
|
|
10220
10561
|
this.checkPremiumSubscription();
|
|
10221
|
-
if (((_b = (
|
|
10562
|
+
if (((_b = (_a3 = this.config.rag) == null ? void 0 : _a3.feedback) == null ? void 0 : _b.enabled) === false) {
|
|
10222
10563
|
throw new Error("[Retrivora SDK] User Feedback is disabled in RagConfig.");
|
|
10223
10564
|
}
|
|
10224
10565
|
}
|
|
@@ -10385,8 +10726,11 @@ var DatabaseStorage = class {
|
|
|
10385
10726
|
this.writeLocalFile(this.historyFile, history);
|
|
10386
10727
|
}
|
|
10387
10728
|
}
|
|
10388
|
-
async getHistory(sessionId) {
|
|
10729
|
+
async getHistory(sessionId, projectIds) {
|
|
10389
10730
|
this.checkHistoryEnabled();
|
|
10731
|
+
if (projectIds && projectIds.length > 0 && !this.sessionInScope(sessionId, projectIds)) {
|
|
10732
|
+
return [];
|
|
10733
|
+
}
|
|
10390
10734
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
10391
10735
|
const pool = await this.getPGPool();
|
|
10392
10736
|
const res = await pool.query(
|
|
@@ -10416,8 +10760,11 @@ var DatabaseStorage = class {
|
|
|
10416
10760
|
return history.filter((h) => h.session_id === sessionId).sort((a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime());
|
|
10417
10761
|
}
|
|
10418
10762
|
}
|
|
10419
|
-
async clearHistory(sessionId) {
|
|
10763
|
+
async clearHistory(sessionId, projectIds) {
|
|
10420
10764
|
this.checkHistoryEnabled();
|
|
10765
|
+
if (projectIds && projectIds.length > 0 && !this.sessionInScope(sessionId, projectIds)) {
|
|
10766
|
+
return;
|
|
10767
|
+
}
|
|
10421
10768
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
10422
10769
|
const pool = await this.getPGPool();
|
|
10423
10770
|
await pool.query(`DELETE FROM ${this.historyTableName} WHERE session_id = $1`, [sessionId]);
|
|
@@ -10436,21 +10783,36 @@ var DatabaseStorage = class {
|
|
|
10436
10783
|
this.writeLocalFile(this.feedbackFile, filteredFeedback);
|
|
10437
10784
|
}
|
|
10438
10785
|
}
|
|
10439
|
-
|
|
10786
|
+
/**
|
|
10787
|
+
* Return true when `sessionId` falls into the allowed `projectIds` scope.
|
|
10788
|
+
* When `projectIds` is empty / undefined we allow the call (legacy behavior
|
|
10789
|
+
* for non-multi-tenant consumers). Session ids typically begin with the
|
|
10790
|
+
* project id they were created for, so we prefix-match as well as contains-match
|
|
10791
|
+
* to catch sharded / suffix-style ids used by some integrations.
|
|
10792
|
+
*/
|
|
10793
|
+
sessionInScope(sessionId, projectIds) {
|
|
10794
|
+
if (!projectIds || projectIds.length === 0) return true;
|
|
10795
|
+
return projectIds.some(
|
|
10796
|
+
(pid) => pid && (sessionId === pid || sessionId.startsWith(pid) || sessionId.includes(pid))
|
|
10797
|
+
);
|
|
10798
|
+
}
|
|
10799
|
+
async listSessions(projectIds) {
|
|
10440
10800
|
this.checkHistoryEnabled();
|
|
10801
|
+
let raw = [];
|
|
10441
10802
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
10442
10803
|
const pool = await this.getPGPool();
|
|
10443
10804
|
const res = await pool.query(`SELECT DISTINCT session_id FROM ${this.historyTableName}`);
|
|
10444
|
-
|
|
10805
|
+
raw = res.rows.map((r) => r.session_id);
|
|
10445
10806
|
} else if (this.provider === "mongodb") {
|
|
10446
10807
|
await this.getMongoClient();
|
|
10447
10808
|
const db = this.getMongoDb();
|
|
10448
|
-
|
|
10809
|
+
raw = await db.collection(this.historyTableName).distinct("session_id");
|
|
10449
10810
|
} else {
|
|
10450
10811
|
const history = this.readLocalFile(this.historyFile);
|
|
10451
|
-
|
|
10452
|
-
return Array.from(sessions);
|
|
10812
|
+
raw = Array.from(new Set(history.map((h) => h.session_id)));
|
|
10453
10813
|
}
|
|
10814
|
+
if (!projectIds || projectIds.length === 0) return raw;
|
|
10815
|
+
return raw.filter((sid) => this.sessionInScope(sid, projectIds));
|
|
10454
10816
|
}
|
|
10455
10817
|
// ─── Feedback Operations ──────────────────────────────────────────────────
|
|
10456
10818
|
async saveFeedback(feedback) {
|
|
@@ -10503,8 +10865,9 @@ var DatabaseStorage = class {
|
|
|
10503
10865
|
this.writeLocalFile(this.feedbackFile, list);
|
|
10504
10866
|
}
|
|
10505
10867
|
}
|
|
10506
|
-
async getFeedback(messageId) {
|
|
10868
|
+
async getFeedback(messageId, projectIds) {
|
|
10507
10869
|
this.checkFeedbackEnabled();
|
|
10870
|
+
let item = null;
|
|
10508
10871
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
10509
10872
|
const pool = await this.getPGPool();
|
|
10510
10873
|
const res = await pool.query(
|
|
@@ -10513,28 +10876,34 @@ var DatabaseStorage = class {
|
|
|
10513
10876
|
WHERE message_id = $1`,
|
|
10514
10877
|
[messageId]
|
|
10515
10878
|
);
|
|
10516
|
-
|
|
10879
|
+
item = res.rows[0] || null;
|
|
10517
10880
|
} else if (this.provider === "mongodb") {
|
|
10518
10881
|
await this.getMongoClient();
|
|
10519
10882
|
const db = this.getMongoDb();
|
|
10520
10883
|
const col = db.collection(this.feedbackTableName);
|
|
10521
|
-
const
|
|
10522
|
-
if (
|
|
10523
|
-
|
|
10524
|
-
|
|
10525
|
-
|
|
10526
|
-
|
|
10527
|
-
|
|
10528
|
-
|
|
10529
|
-
|
|
10530
|
-
|
|
10884
|
+
const raw = await col.findOne({ message_id: messageId });
|
|
10885
|
+
if (raw) {
|
|
10886
|
+
item = {
|
|
10887
|
+
id: raw.id,
|
|
10888
|
+
messageId: raw.message_id,
|
|
10889
|
+
sessionId: raw.session_id,
|
|
10890
|
+
rating: raw.rating,
|
|
10891
|
+
comment: raw.comment,
|
|
10892
|
+
createdAt: raw.created_at
|
|
10893
|
+
};
|
|
10894
|
+
}
|
|
10531
10895
|
} else {
|
|
10532
10896
|
const list = this.readLocalFile(this.feedbackFile);
|
|
10533
|
-
|
|
10897
|
+
item = list.find((f) => f.message_id === messageId) || null;
|
|
10534
10898
|
}
|
|
10899
|
+
if (item && projectIds && projectIds.length > 0) {
|
|
10900
|
+
return this.sessionInScope(item.sessionId, projectIds) ? item : null;
|
|
10901
|
+
}
|
|
10902
|
+
return item;
|
|
10535
10903
|
}
|
|
10536
|
-
async listFeedback() {
|
|
10904
|
+
async listFeedback(projectIds) {
|
|
10537
10905
|
this.checkFeedbackEnabled();
|
|
10906
|
+
let raw = [];
|
|
10538
10907
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
10539
10908
|
const pool = await this.getPGPool();
|
|
10540
10909
|
const res = await pool.query(
|
|
@@ -10542,13 +10911,13 @@ var DatabaseStorage = class {
|
|
|
10542
10911
|
FROM ${this.feedbackTableName}
|
|
10543
10912
|
ORDER BY created_at DESC`
|
|
10544
10913
|
);
|
|
10545
|
-
|
|
10914
|
+
raw = res.rows;
|
|
10546
10915
|
} else if (this.provider === "mongodb") {
|
|
10547
10916
|
await this.getMongoClient();
|
|
10548
10917
|
const db = this.getMongoDb();
|
|
10549
10918
|
const col = db.collection(this.feedbackTableName);
|
|
10550
10919
|
const items = await col.find({}).sort({ created_at: -1 }).toArray();
|
|
10551
|
-
|
|
10920
|
+
raw = items.map((item) => ({
|
|
10552
10921
|
id: item.id,
|
|
10553
10922
|
messageId: item.message_id,
|
|
10554
10923
|
sessionId: item.session_id,
|
|
@@ -10558,8 +10927,10 @@ var DatabaseStorage = class {
|
|
|
10558
10927
|
}));
|
|
10559
10928
|
} else {
|
|
10560
10929
|
const list = this.readLocalFile(this.feedbackFile);
|
|
10561
|
-
|
|
10930
|
+
raw = [...list].sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime());
|
|
10562
10931
|
}
|
|
10932
|
+
if (!projectIds || projectIds.length === 0) return raw;
|
|
10933
|
+
return raw.filter((f) => this.sessionInScope(f.sessionId, projectIds));
|
|
10563
10934
|
}
|
|
10564
10935
|
async disconnect() {
|
|
10565
10936
|
if (this.pgPool) {
|
|
@@ -10622,8 +10993,8 @@ var _g = global;
|
|
|
10622
10993
|
var _a;
|
|
10623
10994
|
var rateLimiter = (_a = _g.__retrivoraRateLimiter) != null ? _a : _g.__retrivoraRateLimiter = new RateLimiter(6e4, 30);
|
|
10624
10995
|
function getRateLimitKey(req) {
|
|
10625
|
-
var
|
|
10626
|
-
const ip = ((_b = (
|
|
10996
|
+
var _a3, _b;
|
|
10997
|
+
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";
|
|
10627
10998
|
return `ip:${ip}`;
|
|
10628
10999
|
}
|
|
10629
11000
|
function checkRateLimit(req) {
|
|
@@ -10645,6 +11016,66 @@ function checkRateLimit(req) {
|
|
|
10645
11016
|
}
|
|
10646
11017
|
return null;
|
|
10647
11018
|
}
|
|
11019
|
+
var FREE_TIER_NAMES = /* @__PURE__ */ new Set(["hobby", "free", "free_trial", "trial"]);
|
|
11020
|
+
function isFreeTier(tier) {
|
|
11021
|
+
if (!tier) return true;
|
|
11022
|
+
return FREE_TIER_NAMES.has(tier.toLowerCase().trim());
|
|
11023
|
+
}
|
|
11024
|
+
var _a2;
|
|
11025
|
+
var _freeTierGuardInstance = (_a2 = _g.__retrivoraFreeTierGuard) != null ? _a2 : _g.__retrivoraFreeTierGuard = new FreeTierLimitsGuard();
|
|
11026
|
+
function createPaymentRequiredResponse(reason, details) {
|
|
11027
|
+
const body = __spreadProps(__spreadValues({
|
|
11028
|
+
type: "https://retrivora.com/docs/errors/payment-required",
|
|
11029
|
+
title: "Payment Required",
|
|
11030
|
+
status: 402,
|
|
11031
|
+
detail: reason,
|
|
11032
|
+
code: "FREE_TIER_LIMIT_EXCEEDED",
|
|
11033
|
+
instance: void 0
|
|
11034
|
+
}, details != null ? details : {}), {
|
|
11035
|
+
quota: {
|
|
11036
|
+
maxDailyRequestUnits: FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS,
|
|
11037
|
+
maxTrialRequestUnits: FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS,
|
|
11038
|
+
maxDocuments: FREE_TIER_QUOTAS.MAX_DOCUMENTS,
|
|
11039
|
+
maxStorageBytes: FREE_TIER_QUOTAS.MAX_STORAGE_BYTES,
|
|
11040
|
+
upgradeUrl: "https://retrivora.com/pricing"
|
|
11041
|
+
}
|
|
11042
|
+
});
|
|
11043
|
+
return new Response(JSON.stringify(body), {
|
|
11044
|
+
status: 402,
|
|
11045
|
+
headers: {
|
|
11046
|
+
"Content-Type": "application/problem+json"
|
|
11047
|
+
}
|
|
11048
|
+
});
|
|
11049
|
+
}
|
|
11050
|
+
function resolveLicenseKey(req, config, bodyLicenseKey) {
|
|
11051
|
+
var _a3;
|
|
11052
|
+
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 || "";
|
|
11053
|
+
}
|
|
11054
|
+
function enforceLicense(req, config, bodyLicenseKey) {
|
|
11055
|
+
const rawKey = resolveLicenseKey(req, config, bodyLicenseKey);
|
|
11056
|
+
const licenseKey = (rawKey || "").trim().replace(/^["']|["']$/g, "").trim();
|
|
11057
|
+
const projectId = config.projectId || "my-rag-app";
|
|
11058
|
+
try {
|
|
11059
|
+
const payload = LicenseVerifier.verify(licenseKey, projectId);
|
|
11060
|
+
return { ok: true, payload };
|
|
11061
|
+
} catch (err) {
|
|
11062
|
+
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.";
|
|
11063
|
+
const body = {
|
|
11064
|
+
error: {
|
|
11065
|
+
code: "LICENSE_REVOKED",
|
|
11066
|
+
message: "Your Retrivora license key has been terminated, suspended, or revoked. Access denied."
|
|
11067
|
+
},
|
|
11068
|
+
details: message
|
|
11069
|
+
};
|
|
11070
|
+
return {
|
|
11071
|
+
ok: false,
|
|
11072
|
+
response: new Response(JSON.stringify(body), {
|
|
11073
|
+
status: 403,
|
|
11074
|
+
headers: { "Content-Type": "application/json" }
|
|
11075
|
+
})
|
|
11076
|
+
};
|
|
11077
|
+
}
|
|
11078
|
+
}
|
|
10648
11079
|
var MAX_MESSAGE_LENGTH = 8e3;
|
|
10649
11080
|
function sanitizeInput(raw) {
|
|
10650
11081
|
const stripped = raw.replace(/[\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F-\u009F]/g, "");
|
|
@@ -10666,7 +11097,7 @@ function getOrCreatePlugin(configOrPlugin) {
|
|
|
10666
11097
|
return _g[cacheKey];
|
|
10667
11098
|
}
|
|
10668
11099
|
function reportTelemetry(req, plugin, action, status, details, trace) {
|
|
10669
|
-
var
|
|
11100
|
+
var _a3, _b, _c, _d, _e, _f, _g2;
|
|
10670
11101
|
try {
|
|
10671
11102
|
const config = plugin.getConfig();
|
|
10672
11103
|
const licenseKey = config.licenseKey || process.env.RAG_LICENSE_KEY || process.env.RETRIVORA_LICENSE_KEY || process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY;
|
|
@@ -10681,7 +11112,7 @@ function reportTelemetry(req, plugin, action, status, details, trace) {
|
|
|
10681
11112
|
absoluteUrl = `${proto}://${host}${telemetryUrl}`;
|
|
10682
11113
|
}
|
|
10683
11114
|
const projectId = config.projectId || "default";
|
|
10684
|
-
const model = (trace == null ? void 0 : trace.model) || ((
|
|
11115
|
+
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";
|
|
10685
11116
|
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";
|
|
10686
11117
|
const tokens = Number(((_e = trace == null ? void 0 : trace.tokens) == null ? void 0 : _e.totalTokens) || (trace == null ? void 0 : trace.totalTokens) || 0);
|
|
10687
11118
|
const costUsd = Number(((_f = trace == null ? void 0 : trace.tokens) == null ? void 0 : _f.estimatedCostUsd) || (trace == null ? void 0 : trace.costUsd) || 0);
|
|
@@ -10705,7 +11136,6 @@ function reportTelemetry(req, plugin, action, status, details, trace) {
|
|
|
10705
11136
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
10706
11137
|
details
|
|
10707
11138
|
};
|
|
10708
|
-
console.log(`[Retrivora SDK Telemetry] Dispatching telemetry -> Feature: "${action}", Status: "${status}", Project: "${projectId}", Latency: ${latencyMs}ms`);
|
|
10709
11139
|
fetch(absoluteUrl, {
|
|
10710
11140
|
method: "POST",
|
|
10711
11141
|
headers: {
|
|
@@ -10763,14 +11193,39 @@ function createChatHandler(configOrPlugin, options) {
|
|
|
10763
11193
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
10764
11194
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
10765
11195
|
return async function POST(req, context) {
|
|
10766
|
-
var
|
|
11196
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
10767
11197
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10768
11198
|
if (authResult) return authResult;
|
|
10769
11199
|
const rateLimited = checkRateLimit(req);
|
|
10770
11200
|
if (rateLimited) return rateLimited;
|
|
11201
|
+
const config = plugin.getConfig();
|
|
10771
11202
|
try {
|
|
10772
11203
|
const body = await req.json();
|
|
10773
11204
|
const bodyObj = body != null ? body : {};
|
|
11205
|
+
const licenseCheck = enforceLicense(req, config, bodyObj == null ? void 0 : bodyObj.licenseKey);
|
|
11206
|
+
if (!licenseCheck.ok) return licenseCheck.response;
|
|
11207
|
+
if (isFreeTier(licenseCheck.payload.tier)) {
|
|
11208
|
+
const estimatedInputTokens = Math.ceil(
|
|
11209
|
+
((((_a3 = bodyObj.message) == null ? void 0 : _a3.length) || 0) + (Array.isArray(bodyObj.messages) ? bodyObj.messages.reduce((a, m) => {
|
|
11210
|
+
var _a4, _b2;
|
|
11211
|
+
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);
|
|
11212
|
+
}, 0) : 0) + (((_b = bodyObj.history) == null ? void 0 : _b.reduce((a, m) => {
|
|
11213
|
+
var _a4, _b2;
|
|
11214
|
+
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);
|
|
11215
|
+
}, 0)) || 0)) / 4
|
|
11216
|
+
);
|
|
11217
|
+
const chatCheck = FreeTierLimitsGuard.checkRequestAllowed({
|
|
11218
|
+
operationType: "chat",
|
|
11219
|
+
inputTokens: estimatedInputTokens,
|
|
11220
|
+
projectId: licenseCheck.payload.projectId
|
|
11221
|
+
});
|
|
11222
|
+
if (!chatCheck.allowed) {
|
|
11223
|
+
return createPaymentRequiredResponse(
|
|
11224
|
+
chatCheck.reason || "Free tier quota exceeded.",
|
|
11225
|
+
{ tier: licenseCheck.payload.tier, projectId: licenseCheck.payload.projectId }
|
|
11226
|
+
);
|
|
11227
|
+
}
|
|
11228
|
+
}
|
|
10774
11229
|
let rawMessage = bodyObj.message;
|
|
10775
11230
|
if (!rawMessage && Array.isArray(bodyObj.messages) && bodyObj.messages.length > 0) {
|
|
10776
11231
|
const lastMsg = bodyObj.messages[bodyObj.messages.length - 1];
|
|
@@ -10802,7 +11257,7 @@ function createChatHandler(configOrPlugin, options) {
|
|
|
10802
11257
|
uiTransformation: result.ui_transformation,
|
|
10803
11258
|
trace: result.trace
|
|
10804
11259
|
}).catch((err) => console.warn("[createChatHandler] Failed to save assistant message:", err));
|
|
10805
|
-
reportTelemetry(req, plugin, "QUERY_GENERATION", "success", `Tokens: ${((
|
|
11260
|
+
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);
|
|
10806
11261
|
return import_server.NextResponse.json(__spreadProps(__spreadValues({}, result), {
|
|
10807
11262
|
messageId: assistantMsgId,
|
|
10808
11263
|
userMessageId: userMsgId
|
|
@@ -10819,14 +11274,15 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10819
11274
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
10820
11275
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
10821
11276
|
return async function POST(req, context) {
|
|
10822
|
-
var
|
|
11277
|
+
var _a3, _b, _c;
|
|
10823
11278
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10824
11279
|
if (authResult) return authResult;
|
|
10825
11280
|
const rateLimited = checkRateLimit(req);
|
|
10826
11281
|
if (rateLimited) return rateLimited;
|
|
11282
|
+
const config = plugin.getConfig();
|
|
10827
11283
|
let body;
|
|
10828
11284
|
try {
|
|
10829
|
-
if ((
|
|
11285
|
+
if ((_a3 = req.headers.get("content-type")) == null ? void 0 : _a3.includes("multipart/form-data")) {
|
|
10830
11286
|
const uploader = createUploadHandler(plugin, { onAuthorize });
|
|
10831
11287
|
return uploader(req);
|
|
10832
11288
|
}
|
|
@@ -10838,6 +11294,30 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10838
11294
|
});
|
|
10839
11295
|
}
|
|
10840
11296
|
const bodyObj = body != null ? body : {};
|
|
11297
|
+
const licenseCheck = enforceLicense(req, config, bodyObj == null ? void 0 : bodyObj.licenseKey);
|
|
11298
|
+
if (!licenseCheck.ok) return licenseCheck.response;
|
|
11299
|
+
if (isFreeTier(licenseCheck.payload.tier)) {
|
|
11300
|
+
const estimatedInputTokens = Math.ceil(
|
|
11301
|
+
((((_b = bodyObj.message) == null ? void 0 : _b.length) || 0) + (Array.isArray(bodyObj.messages) ? bodyObj.messages.reduce((a, m) => {
|
|
11302
|
+
var _a4, _b2;
|
|
11303
|
+
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);
|
|
11304
|
+
}, 0) : 0) + (((_c = bodyObj.history) == null ? void 0 : _c.reduce((a, m) => {
|
|
11305
|
+
var _a4, _b2;
|
|
11306
|
+
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);
|
|
11307
|
+
}, 0)) || 0)) / 4
|
|
11308
|
+
);
|
|
11309
|
+
const chatCheck = FreeTierLimitsGuard.checkRequestAllowed({
|
|
11310
|
+
operationType: "chat_stream",
|
|
11311
|
+
inputTokens: estimatedInputTokens,
|
|
11312
|
+
projectId: licenseCheck.payload.projectId
|
|
11313
|
+
});
|
|
11314
|
+
if (!chatCheck.allowed) {
|
|
11315
|
+
return createPaymentRequiredResponse(
|
|
11316
|
+
chatCheck.reason || "Free tier quota exceeded.",
|
|
11317
|
+
{ tier: licenseCheck.payload.tier, projectId: licenseCheck.payload.projectId }
|
|
11318
|
+
);
|
|
11319
|
+
}
|
|
11320
|
+
}
|
|
10841
11321
|
let rawMessage = bodyObj.message;
|
|
10842
11322
|
if (!rawMessage && Array.isArray(bodyObj.messages) && bodyObj.messages.length > 0) {
|
|
10843
11323
|
const lastMsg = bodyObj.messages[bodyObj.messages.length - 1];
|
|
@@ -10867,7 +11347,7 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10867
11347
|
let isActive = true;
|
|
10868
11348
|
const stream = new ReadableStream({
|
|
10869
11349
|
async start(controller) {
|
|
10870
|
-
var
|
|
11350
|
+
var _a4, _b2, _c2, _d, _e;
|
|
10871
11351
|
const enqueue = (text) => {
|
|
10872
11352
|
if (!isActive) return;
|
|
10873
11353
|
try {
|
|
@@ -10900,7 +11380,7 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10900
11380
|
let uiTransformation = responseChunk == null ? void 0 : responseChunk.ui_transformation;
|
|
10901
11381
|
if (sources.length > 0) {
|
|
10902
11382
|
try {
|
|
10903
|
-
uiTransformation = (
|
|
11383
|
+
uiTransformation = (_a4 = responseChunk == null ? void 0 : responseChunk.ui_transformation) != null ? _a4 : UITransformer.transform(message, sources, plugin.getConfig());
|
|
10904
11384
|
if (uiTransformation) {
|
|
10905
11385
|
enqueue(sseUIFrame(uiTransformation));
|
|
10906
11386
|
}
|
|
@@ -10924,7 +11404,7 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10924
11404
|
uiTransformation,
|
|
10925
11405
|
trace: responseChunk == null ? void 0 : responseChunk.trace
|
|
10926
11406
|
}).catch((err) => console.warn("[createStreamHandler] Failed to save assistant message:", err));
|
|
10927
|
-
reportTelemetry(req, plugin, "QUERY_GENERATION", "success", `Tokens: ${((
|
|
11407
|
+
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);
|
|
10928
11408
|
}
|
|
10929
11409
|
}
|
|
10930
11410
|
} catch (temp) {
|
|
@@ -10974,12 +11454,36 @@ function createIngestHandler(configOrPlugin, options) {
|
|
|
10974
11454
|
return async function POST(req, context) {
|
|
10975
11455
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10976
11456
|
if (authResult) return authResult;
|
|
11457
|
+
const config = plugin.getConfig();
|
|
10977
11458
|
try {
|
|
10978
11459
|
const body = await req.json();
|
|
11460
|
+
const licenseCheck = enforceLicense(req, config, body == null ? void 0 : body.licenseKey);
|
|
11461
|
+
if (!licenseCheck.ok) return licenseCheck.response;
|
|
10979
11462
|
const { documents, namespace } = body;
|
|
10980
11463
|
if (!Array.isArray(documents) || documents.length === 0) {
|
|
10981
11464
|
return import_server.NextResponse.json({ error: "documents array is required" }, { status: 400 });
|
|
10982
11465
|
}
|
|
11466
|
+
if (isFreeTier(licenseCheck.payload.tier)) {
|
|
11467
|
+
const totalIncomingBytes = documents.reduce(
|
|
11468
|
+
(sum, d) => sum + Buffer.byteLength(d.content || "", "utf8"),
|
|
11469
|
+
0
|
|
11470
|
+
);
|
|
11471
|
+
const ingestCheck = FreeTierLimitsGuard.checkIngestionAllowed(
|
|
11472
|
+
{ documentCount: documents.length },
|
|
11473
|
+
totalIncomingBytes
|
|
11474
|
+
);
|
|
11475
|
+
if (!ingestCheck.allowed) {
|
|
11476
|
+
return createPaymentRequiredResponse(
|
|
11477
|
+
ingestCheck.reason || "Free tier ingestion limit reached.",
|
|
11478
|
+
{
|
|
11479
|
+
tier: licenseCheck.payload.tier,
|
|
11480
|
+
projectId: licenseCheck.payload.projectId,
|
|
11481
|
+
documents: documents.length,
|
|
11482
|
+
incomingBytes: totalIncomingBytes
|
|
11483
|
+
}
|
|
11484
|
+
);
|
|
11485
|
+
}
|
|
11486
|
+
}
|
|
10983
11487
|
const results = await plugin.ingest(documents, namespace);
|
|
10984
11488
|
reportTelemetry(req, plugin, "DOCUMENT_INGESTION", "success", `Ingested ${documents.length} document(s)`);
|
|
10985
11489
|
return import_server.NextResponse.json({ results });
|
|
@@ -11016,7 +11520,7 @@ function createLicenseHandler(configOrPlugin, options) {
|
|
|
11016
11520
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
11017
11521
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
11018
11522
|
return async function POST(req) {
|
|
11019
|
-
var
|
|
11523
|
+
var _a3;
|
|
11020
11524
|
if (req) {
|
|
11021
11525
|
const authResult = await checkAuth(req, onAuthorize);
|
|
11022
11526
|
if (authResult) return authResult;
|
|
@@ -11024,7 +11528,8 @@ function createLicenseHandler(configOrPlugin, options) {
|
|
|
11024
11528
|
try {
|
|
11025
11529
|
const body = await req.json().catch(() => ({}));
|
|
11026
11530
|
const config = plugin.getConfig();
|
|
11027
|
-
const
|
|
11531
|
+
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 || "";
|
|
11532
|
+
const licenseKey = (rawKey || "").trim().replace(/^["']|["']$/g, "").trim();
|
|
11028
11533
|
const projectId = (body == null ? void 0 : body.projectId) || config.projectId || "my-rag-app";
|
|
11029
11534
|
const payload = LicenseVerifier.verify(licenseKey, projectId);
|
|
11030
11535
|
return import_server.NextResponse.json({
|
|
@@ -11058,6 +11563,9 @@ function createUploadHandler(configOrPlugin, options) {
|
|
|
11058
11563
|
return async function POST(req, context) {
|
|
11059
11564
|
const authResult = await checkAuth(req, onAuthorize);
|
|
11060
11565
|
if (authResult) return authResult;
|
|
11566
|
+
const config = plugin.getConfig();
|
|
11567
|
+
const licenseCheck = enforceLicense(req, config);
|
|
11568
|
+
if (!licenseCheck.ok) return licenseCheck.response;
|
|
11061
11569
|
try {
|
|
11062
11570
|
const formData = await req.formData();
|
|
11063
11571
|
const files = formData.getAll("files");
|
|
@@ -11067,6 +11575,26 @@ function createUploadHandler(configOrPlugin, options) {
|
|
|
11067
11575
|
if (!files || files.length === 0) {
|
|
11068
11576
|
return import_server.NextResponse.json({ error: "No files provided" }, { status: 400 });
|
|
11069
11577
|
}
|
|
11578
|
+
if (isFreeTier(licenseCheck.payload.tier)) {
|
|
11579
|
+
const totalUploadBytes = files.reduce((sum, f) => sum + (f.size || 0), 0);
|
|
11580
|
+
const uploadCheck = FreeTierLimitsGuard.checkIngestionAllowed(
|
|
11581
|
+
{ documentCount: files.length },
|
|
11582
|
+
totalUploadBytes
|
|
11583
|
+
);
|
|
11584
|
+
if (!uploadCheck.allowed) {
|
|
11585
|
+
return createPaymentRequiredResponse(
|
|
11586
|
+
uploadCheck.reason || "Free tier upload limit reached.",
|
|
11587
|
+
{
|
|
11588
|
+
tier: licenseCheck.payload.tier,
|
|
11589
|
+
projectId: licenseCheck.payload.projectId,
|
|
11590
|
+
fileCount: files.length,
|
|
11591
|
+
totalUploadBytes,
|
|
11592
|
+
maxFileSizeBytes: FREE_TIER_QUOTAS.MAX_FILE_SIZE_BYTES,
|
|
11593
|
+
maxStorageBytes: FREE_TIER_QUOTAS.MAX_STORAGE_BYTES
|
|
11594
|
+
}
|
|
11595
|
+
);
|
|
11596
|
+
}
|
|
11597
|
+
}
|
|
11070
11598
|
const documents = [];
|
|
11071
11599
|
for (const file of files) {
|
|
11072
11600
|
const isExcel = file.name.toLowerCase().endsWith(".xlsx") || file.name.toLowerCase().endsWith(".xls") || file.type.includes("spreadsheet") || file.type.includes("excel");
|
|
@@ -11176,13 +11704,22 @@ function createSuggestionsHandler(configOrPlugin, options) {
|
|
|
11176
11704
|
return async function handler(req) {
|
|
11177
11705
|
const authResult = await checkAuth(req, onAuthorize);
|
|
11178
11706
|
if (authResult) return authResult;
|
|
11707
|
+
const config = plugin.getConfig();
|
|
11708
|
+
const licenseCheck = enforceLicense(req, config);
|
|
11709
|
+
if (!licenseCheck.ok) return licenseCheck.response;
|
|
11179
11710
|
try {
|
|
11180
11711
|
let query = "";
|
|
11181
11712
|
let namespace = void 0;
|
|
11713
|
+
let bodyLicenseKey = void 0;
|
|
11182
11714
|
if (req.method === "POST") {
|
|
11183
11715
|
const body = await req.json().catch(() => ({}));
|
|
11184
11716
|
query = body.query || "";
|
|
11185
11717
|
namespace = body.namespace;
|
|
11718
|
+
bodyLicenseKey = body.licenseKey;
|
|
11719
|
+
if (bodyLicenseKey) {
|
|
11720
|
+
const recheck = enforceLicense(req, config, bodyLicenseKey);
|
|
11721
|
+
if (!recheck.ok) return recheck.response;
|
|
11722
|
+
}
|
|
11186
11723
|
} else {
|
|
11187
11724
|
const url = new URL(req.url);
|
|
11188
11725
|
query = url.searchParams.get("query") || "";
|
|
@@ -11205,14 +11742,16 @@ function createHistoryHandler(configOrPlugin, options) {
|
|
|
11205
11742
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
11206
11743
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
11207
11744
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
11745
|
+
const onResolveScope = options == null ? void 0 : options.onResolveScope;
|
|
11208
11746
|
return async function handler(req) {
|
|
11209
11747
|
const authResult = await checkAuth(req, onAuthorize);
|
|
11210
11748
|
if (authResult) return authResult;
|
|
11749
|
+
const scope = onResolveScope ? await onResolveScope(req) : void 0;
|
|
11211
11750
|
const url = new URL(req.url);
|
|
11212
11751
|
const sessionId = url.searchParams.get("sessionId") || "default";
|
|
11213
11752
|
if (req.method === "GET") {
|
|
11214
11753
|
try {
|
|
11215
|
-
const history = await storage.getHistory(sessionId);
|
|
11754
|
+
const history = await storage.getHistory(sessionId, scope);
|
|
11216
11755
|
return import_server.NextResponse.json({ history });
|
|
11217
11756
|
} catch (err) {
|
|
11218
11757
|
const message = err instanceof Error ? err.message : "Failed to fetch history";
|
|
@@ -11222,7 +11761,7 @@ function createHistoryHandler(configOrPlugin, options) {
|
|
|
11222
11761
|
try {
|
|
11223
11762
|
const body = await req.json().catch(() => ({}));
|
|
11224
11763
|
const sid = body.sessionId || sessionId;
|
|
11225
|
-
await storage.clearHistory(sid);
|
|
11764
|
+
await storage.clearHistory(sid, scope);
|
|
11226
11765
|
return import_server.NextResponse.json({ success: true });
|
|
11227
11766
|
} catch (err) {
|
|
11228
11767
|
const message = err instanceof Error ? err.message : "Failed to clear history";
|
|
@@ -11236,18 +11775,20 @@ function createFeedbackHandler(configOrPlugin, options) {
|
|
|
11236
11775
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
11237
11776
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
11238
11777
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
11778
|
+
const onResolveScope = options == null ? void 0 : options.onResolveScope;
|
|
11239
11779
|
return async function handler(req) {
|
|
11240
11780
|
const authResult = await checkAuth(req, onAuthorize);
|
|
11241
11781
|
if (authResult) return authResult;
|
|
11782
|
+
const scope = onResolveScope ? await onResolveScope(req) : void 0;
|
|
11242
11783
|
if (req.method === "GET") {
|
|
11243
11784
|
try {
|
|
11244
11785
|
const url = new URL(req.url);
|
|
11245
11786
|
const messageId = url.searchParams.get("messageId");
|
|
11246
11787
|
if (!messageId) {
|
|
11247
|
-
const feedbackList = await storage.listFeedback();
|
|
11788
|
+
const feedbackList = await storage.listFeedback(scope);
|
|
11248
11789
|
return import_server.NextResponse.json({ feedback: feedbackList });
|
|
11249
11790
|
}
|
|
11250
|
-
const feedback = await storage.getFeedback(messageId);
|
|
11791
|
+
const feedback = await storage.getFeedback(messageId, scope);
|
|
11251
11792
|
return import_server.NextResponse.json({ feedback });
|
|
11252
11793
|
} catch (err) {
|
|
11253
11794
|
const message = err instanceof Error ? err.message : "Failed to fetch feedback";
|
|
@@ -11263,6 +11804,17 @@ function createFeedbackHandler(configOrPlugin, options) {
|
|
|
11263
11804
|
if (!rating) {
|
|
11264
11805
|
return import_server.NextResponse.json({ error: "rating is required" }, { status: 400 });
|
|
11265
11806
|
}
|
|
11807
|
+
if (scope && scope.length > 0) {
|
|
11808
|
+
const matches = scope.some(
|
|
11809
|
+
(pid) => pid && (sessionId === pid || sessionId.startsWith(pid) || sessionId.includes(pid))
|
|
11810
|
+
);
|
|
11811
|
+
if (!matches) {
|
|
11812
|
+
return import_server.NextResponse.json(
|
|
11813
|
+
{ error: "sessionId is outside the authorized project scope" },
|
|
11814
|
+
{ status: 403 }
|
|
11815
|
+
);
|
|
11816
|
+
}
|
|
11817
|
+
}
|
|
11266
11818
|
await storage.saveFeedback({ messageId, sessionId, rating, comment });
|
|
11267
11819
|
return import_server.NextResponse.json({ success: true });
|
|
11268
11820
|
} catch (err) {
|
|
@@ -11277,14 +11829,15 @@ function createSessionsHandler(configOrPlugin, options) {
|
|
|
11277
11829
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
11278
11830
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
11279
11831
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
11832
|
+
const onResolveScope = options == null ? void 0 : options.onResolveScope;
|
|
11280
11833
|
return async function GET(req) {
|
|
11281
11834
|
if (req) {
|
|
11282
11835
|
const authResult = await checkAuth(req, onAuthorize);
|
|
11283
11836
|
if (authResult) return authResult;
|
|
11284
11837
|
}
|
|
11285
|
-
void req;
|
|
11286
11838
|
try {
|
|
11287
|
-
const
|
|
11839
|
+
const scope = req && onResolveScope ? await onResolveScope(req) : void 0;
|
|
11840
|
+
const sessions = await storage.listSessions(scope);
|
|
11288
11841
|
return import_server.NextResponse.json({ sessions });
|
|
11289
11842
|
} catch (err) {
|
|
11290
11843
|
const message = err instanceof Error ? err.message : "Failed to list sessions";
|
|
@@ -11295,15 +11848,17 @@ function createSessionsHandler(configOrPlugin, options) {
|
|
|
11295
11848
|
function createRagHandler(configOrPlugin, options) {
|
|
11296
11849
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
11297
11850
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
11298
|
-
const
|
|
11299
|
-
const
|
|
11300
|
-
const
|
|
11301
|
-
const
|
|
11302
|
-
const
|
|
11303
|
-
const
|
|
11304
|
-
const
|
|
11305
|
-
const
|
|
11306
|
-
const
|
|
11851
|
+
const onResolveScope = options == null ? void 0 : options.onResolveScope;
|
|
11852
|
+
const scopeableOptions = { onAuthorize, onResolveScope };
|
|
11853
|
+
const chatHandler = createChatHandler(plugin, scopeableOptions);
|
|
11854
|
+
const streamHandler = createStreamHandler(plugin, scopeableOptions);
|
|
11855
|
+
const uploadHandler = createUploadHandler(plugin, scopeableOptions);
|
|
11856
|
+
const healthHandler = createHealthHandler(plugin, scopeableOptions);
|
|
11857
|
+
const suggestionsHandler = createSuggestionsHandler(plugin, scopeableOptions);
|
|
11858
|
+
const historyHandler = createHistoryHandler(plugin, scopeableOptions);
|
|
11859
|
+
const feedbackHandler = createFeedbackHandler(plugin, scopeableOptions);
|
|
11860
|
+
const sessionsHandler = createSessionsHandler(plugin, scopeableOptions);
|
|
11861
|
+
const licenseHandler = createLicenseHandler(plugin, scopeableOptions);
|
|
11307
11862
|
async function routePostRequest(req, segment) {
|
|
11308
11863
|
switch (segment) {
|
|
11309
11864
|
case "chat":
|
|
@@ -11345,7 +11900,7 @@ function createRagHandler(configOrPlugin, options) {
|
|
|
11345
11900
|
}
|
|
11346
11901
|
}
|
|
11347
11902
|
async function getSegment(req, context) {
|
|
11348
|
-
var
|
|
11903
|
+
var _a3, _b;
|
|
11349
11904
|
const contentType = req.headers.get("content-type") || "";
|
|
11350
11905
|
if (contentType.includes("multipart/form-data")) {
|
|
11351
11906
|
return "upload";
|
|
@@ -11362,7 +11917,7 @@ function createRagHandler(configOrPlugin, options) {
|
|
|
11362
11917
|
if (pathname.endsWith("/history")) return "history";
|
|
11363
11918
|
} catch (e) {
|
|
11364
11919
|
}
|
|
11365
|
-
const resolvedParams = typeof ((
|
|
11920
|
+
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;
|
|
11366
11921
|
const segments = (resolvedParams == null ? void 0 : resolvedParams.retrivora) || ((_b = resolvedParams == null ? void 0 : resolvedParams.params) == null ? void 0 : _b.retrivora) || [];
|
|
11367
11922
|
const joined = segments.join("/");
|
|
11368
11923
|
return joined || "chat";
|
|
@@ -11395,6 +11950,7 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
11395
11950
|
constructor() {
|
|
11396
11951
|
this.cache = /* @__PURE__ */ new Map();
|
|
11397
11952
|
}
|
|
11953
|
+
/** @returns Singleton instance of the validator (shared cache across all consumers). */
|
|
11398
11954
|
static getInstance() {
|
|
11399
11955
|
if (!_LicenseValidator.instance) {
|
|
11400
11956
|
_LicenseValidator.instance = new _LicenseValidator();
|
|
@@ -11402,7 +11958,12 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
11402
11958
|
return _LicenseValidator.instance;
|
|
11403
11959
|
}
|
|
11404
11960
|
/**
|
|
11405
|
-
*
|
|
11961
|
+
* Purge entries from the local success cache.
|
|
11962
|
+
*
|
|
11963
|
+
* @param licenseKey - Optional. If provided, only that key's cache entry is
|
|
11964
|
+
* removed. If omitted the entire cache is cleared.
|
|
11965
|
+
* Callers use this after any 401/403 to ensure the next
|
|
11966
|
+
* validate() call re-validates against the server.
|
|
11406
11967
|
*/
|
|
11407
11968
|
purgeCache(licenseKey) {
|
|
11408
11969
|
if (licenseKey) {
|
|
@@ -11412,10 +11973,20 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
11412
11973
|
}
|
|
11413
11974
|
}
|
|
11414
11975
|
/**
|
|
11415
|
-
*
|
|
11976
|
+
* Primary validation entry-point for UI / hook consumers.
|
|
11977
|
+
*
|
|
11978
|
+
* Resolves the license key, consults the local success cache, performs a
|
|
11979
|
+
* server POST for authoritative status, and falls back to local RSA
|
|
11980
|
+
* signature verification if the server can't be reached.
|
|
11981
|
+
*
|
|
11982
|
+
* @throws LicenseValidationError - When no key is provided OR both the
|
|
11983
|
+
* server call AND the local-RSA fallback report an invalid/expired key.
|
|
11984
|
+
* @throws SDKVersionUnsupportedError - When server reports forceUpgrade=true.
|
|
11985
|
+
* @returns A `LicenseValidationResponse` that the UI can use to enable or
|
|
11986
|
+
* lock the chat widget.
|
|
11416
11987
|
*/
|
|
11417
11988
|
async validate(request) {
|
|
11418
|
-
var
|
|
11989
|
+
var _a3;
|
|
11419
11990
|
const {
|
|
11420
11991
|
licenseKey,
|
|
11421
11992
|
projectId,
|
|
@@ -11433,7 +12004,8 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
11433
12004
|
}
|
|
11434
12005
|
return void 0;
|
|
11435
12006
|
};
|
|
11436
|
-
const
|
|
12007
|
+
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 : "") || "";
|
|
12008
|
+
const effectiveLicenseKey = (rawKey || "").trim().replace(/^["']|["']$/g, "").trim();
|
|
11437
12009
|
if (!effectiveLicenseKey) {
|
|
11438
12010
|
this.purgeCache(effectiveLicenseKey);
|
|
11439
12011
|
throw new LicenseValidationError("Missing RETRIVORA_LICENSE_KEY in request. Set NEXT_PUBLIC_RETRIVORA_LICENSE_KEY in your environment or pass licenseKey as a prop.");
|