@retrivora-ai/rag-engine 2.3.0 → 2.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{LicenseValidator-CENvo9o2.d.mts → BatchProcessor-7yV-UCHW.d.mts} +142 -3
- package/dist/{LicenseValidator-CsjJp2PP.d.ts → BatchProcessor-BfzuU4cK.d.ts} +142 -3
- package/dist/handlers/index.d.mts +1 -1
- package/dist/handlers/index.d.ts +1 -1
- package/dist/handlers/index.js +880 -327
- package/dist/handlers/index.mjs +880 -327
- package/dist/index-DR_O_B-W.d.ts +394 -0
- package/dist/index-fnpaCuma.d.mts +394 -0
- package/dist/index.css +58 -0
- package/dist/index.d.mts +63 -3
- package/dist/index.d.ts +63 -3
- package/dist/index.js +452 -35
- package/dist/index.mjs +451 -37
- package/dist/server.d.mts +35 -73
- package/dist/server.d.ts +35 -73
- package/dist/server.js +910 -341
- package/dist/server.mjs +910 -341
- package/package.json +1 -1
- package/src/components/ChatWidget.tsx +147 -46
- package/src/components/ChatWindow.tsx +52 -8
- package/src/core/BatchProcessor.ts +42 -4
- package/src/core/CircuitBreaker.ts +118 -0
- package/src/core/DatabaseStorage.ts +55 -24
- package/src/core/FreeTierLimitsGuard.ts +281 -0
- package/src/core/LicenseValidator.ts +66 -2
- package/src/core/LicenseVerifier.ts +31 -3
- package/src/core/VectorPlugin.ts +30 -0
- package/src/handlers/index.ts +491 -36
- package/src/index.css +58 -0
- package/src/index.ts +4 -0
- package/src/server.ts +1 -0
- package/dist/index-BPJ3KDYI.d.ts +0 -195
- package/dist/index-Dmq5lH0j.d.mts +0 -195
package/dist/server.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);
|
|
@@ -2630,8 +2630,8 @@ var UI_BORDER_RADIUS_OPTIONS = ["none", "sm", "md", "lg", "xl", "full"];
|
|
|
2630
2630
|
|
|
2631
2631
|
// src/config/serverConfig.ts
|
|
2632
2632
|
function readString(env, name) {
|
|
2633
|
-
var
|
|
2634
|
-
const value = (
|
|
2633
|
+
var _a3;
|
|
2634
|
+
const value = (_a3 = env[name]) == null ? void 0 : _a3.trim();
|
|
2635
2635
|
return value ? value : void 0;
|
|
2636
2636
|
}
|
|
2637
2637
|
function readNumber(env, name, fallback) {
|
|
@@ -2644,8 +2644,8 @@ function readNumber(env, name, fallback) {
|
|
|
2644
2644
|
return parsed;
|
|
2645
2645
|
}
|
|
2646
2646
|
function readEnum(env, name, fallback, allowed) {
|
|
2647
|
-
var
|
|
2648
|
-
const value = (
|
|
2647
|
+
var _a3;
|
|
2648
|
+
const value = (_a3 = readString(env, name)) != null ? _a3 : fallback;
|
|
2649
2649
|
if (allowed.includes(value)) {
|
|
2650
2650
|
return value;
|
|
2651
2651
|
}
|
|
@@ -2655,8 +2655,8 @@ function getRagConfig(baseConfig, env = process.env) {
|
|
|
2655
2655
|
return getEnvConfig(env, baseConfig);
|
|
2656
2656
|
}
|
|
2657
2657
|
function getEnvConfig(env = process.env, base) {
|
|
2658
|
-
var
|
|
2659
|
-
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;
|
|
2660
2660
|
const jwtProjectId = (() => {
|
|
2661
2661
|
if (!licenseKey) return void 0;
|
|
2662
2662
|
try {
|
|
@@ -2737,7 +2737,7 @@ function getEnvConfig(env = process.env, base) {
|
|
|
2737
2737
|
rest: "default",
|
|
2738
2738
|
custom: "default"
|
|
2739
2739
|
};
|
|
2740
|
-
const
|
|
2740
|
+
const isFreeTier2 = (() => {
|
|
2741
2741
|
if (!licenseKey) return true;
|
|
2742
2742
|
try {
|
|
2743
2743
|
const payload = LicenseVerifier.verify(licenseKey, projectId);
|
|
@@ -2748,13 +2748,13 @@ function getEnvConfig(env = process.env, base) {
|
|
|
2748
2748
|
}
|
|
2749
2749
|
})();
|
|
2750
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";
|
|
2751
|
-
const defaultLlmProvider =
|
|
2751
|
+
const defaultLlmProvider = isFreeTier2 ? "universal_rest" : "universal_rest";
|
|
2752
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;
|
|
2753
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;
|
|
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 :
|
|
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";
|
|
2755
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;
|
|
2756
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";
|
|
2757
|
-
const defaultEmbeddingProvider =
|
|
2757
|
+
const defaultEmbeddingProvider = isFreeTier2 ? "universal_rest" : "universal_rest";
|
|
2758
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;
|
|
2759
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;
|
|
2760
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";
|
|
@@ -2844,8 +2844,8 @@ function getEnvConfig(env = process.env, base) {
|
|
|
2844
2844
|
}
|
|
2845
2845
|
} : {}), {
|
|
2846
2846
|
mcpServers: (() => {
|
|
2847
|
-
var
|
|
2848
|
-
const raw = (
|
|
2847
|
+
var _a4;
|
|
2848
|
+
const raw = (_a4 = readString(env, "MCP_SERVERS")) != null ? _a4 : readString(env, "NEXT_PUBLIC_MCP_SERVERS");
|
|
2849
2849
|
if (!raw) return void 0;
|
|
2850
2850
|
try {
|
|
2851
2851
|
return JSON.parse(raw);
|
|
@@ -2890,10 +2890,10 @@ var ConfigResolver = class {
|
|
|
2890
2890
|
* fallback behavior.
|
|
2891
2891
|
*/
|
|
2892
2892
|
static resolveUniversal(hostConfig, env = process.env) {
|
|
2893
|
-
var
|
|
2893
|
+
var _a3;
|
|
2894
2894
|
if (!hostConfig) return this.resolve(void 0, env);
|
|
2895
2895
|
const normalized = __spreadProps(__spreadValues({}, hostConfig), {
|
|
2896
|
-
vectorDb: (
|
|
2896
|
+
vectorDb: (_a3 = hostConfig.vectorDb) != null ? _a3 : hostConfig.vectorDatabase,
|
|
2897
2897
|
rag: this.mergeRetrievalWorkflow(hostConfig.rag, hostConfig.retrieval, hostConfig.workflow)
|
|
2898
2898
|
});
|
|
2899
2899
|
return this.resolve(normalized, env);
|
|
@@ -2913,11 +2913,11 @@ var ConfigResolver = class {
|
|
|
2913
2913
|
}
|
|
2914
2914
|
}
|
|
2915
2915
|
static mergeRetrievalWorkflow(rag, retrieval, workflow) {
|
|
2916
|
-
var
|
|
2916
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
2917
2917
|
if (!rag && !retrieval && !workflow) return void 0;
|
|
2918
2918
|
const normalized = __spreadValues({}, rag != null ? rag : {});
|
|
2919
2919
|
if (retrieval) {
|
|
2920
|
-
normalized.topK = (
|
|
2920
|
+
normalized.topK = (_a3 = retrieval.topK) != null ? _a3 : normalized.topK;
|
|
2921
2921
|
normalized.scoreThreshold = (_b = retrieval.scoreThreshold) != null ? _b : normalized.scoreThreshold;
|
|
2922
2922
|
normalized.useReranking = (_c = retrieval.useReranking) != null ? _c : normalized.useReranking;
|
|
2923
2923
|
if (retrieval.strategy === "hybrid") normalized.architecture = (_d = normalized.architecture) != null ? _d : "hybrid";
|
|
@@ -3045,8 +3045,8 @@ var OpenAIProvider = class {
|
|
|
3045
3045
|
};
|
|
3046
3046
|
}
|
|
3047
3047
|
async chat(messages, context, options) {
|
|
3048
|
-
var
|
|
3049
|
-
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.";
|
|
3050
3050
|
const systemMessage = {
|
|
3051
3051
|
role: "system",
|
|
3052
3052
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3070,8 +3070,8 @@ var OpenAIProvider = class {
|
|
|
3070
3070
|
}
|
|
3071
3071
|
chatStream(messages, context, options) {
|
|
3072
3072
|
return __asyncGenerator(this, null, function* () {
|
|
3073
|
-
var
|
|
3074
|
-
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.";
|
|
3075
3075
|
const systemMessage = {
|
|
3076
3076
|
role: "system",
|
|
3077
3077
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3118,8 +3118,8 @@ var OpenAIProvider = class {
|
|
|
3118
3118
|
return results[0];
|
|
3119
3119
|
}
|
|
3120
3120
|
async batchEmbed(texts, options) {
|
|
3121
|
-
var
|
|
3122
|
-
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";
|
|
3123
3123
|
const apiKey = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.apiKey) != null ? _e : this.llmConfig.apiKey;
|
|
3124
3124
|
const client = apiKey !== this.llmConfig.apiKey ? new import_openai.default({ apiKey }) : this.client;
|
|
3125
3125
|
const response = await client.embeddings.create({ model, input: texts });
|
|
@@ -3196,8 +3196,8 @@ var AnthropicProvider = class {
|
|
|
3196
3196
|
};
|
|
3197
3197
|
}
|
|
3198
3198
|
async chat(messages, context, options) {
|
|
3199
|
-
var
|
|
3200
|
-
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.";
|
|
3201
3201
|
const system = buildSystemContent(basePrompt, context);
|
|
3202
3202
|
const anthropicMessages = messages.map((m) => ({
|
|
3203
3203
|
role: m.role === "assistant" ? "assistant" : "user",
|
|
@@ -3235,8 +3235,8 @@ var AnthropicProvider = class {
|
|
|
3235
3235
|
}
|
|
3236
3236
|
chatStream(messages, context, options) {
|
|
3237
3237
|
return __asyncGenerator(this, null, function* () {
|
|
3238
|
-
var
|
|
3239
|
-
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.";
|
|
3240
3240
|
const system = buildSystemContent(basePrompt, context);
|
|
3241
3241
|
const anthropicMessages = messages.map((m) => ({
|
|
3242
3242
|
role: m.role === "assistant" ? "assistant" : "user",
|
|
@@ -3320,8 +3320,8 @@ var AnthropicProvider = class {
|
|
|
3320
3320
|
var import_axios = __toESM(require("axios"));
|
|
3321
3321
|
var OllamaProvider = class {
|
|
3322
3322
|
constructor(llmConfig, embeddingConfig) {
|
|
3323
|
-
var
|
|
3324
|
-
const rawBaseURL = ((
|
|
3323
|
+
var _a3, _b, _c;
|
|
3324
|
+
const rawBaseURL = ((_a3 = llmConfig.baseUrl) != null ? _a3 : "http://localhost:11434").replace(/\/+$/, "");
|
|
3325
3325
|
const baseURL = rawBaseURL.replace(/\/(?:api\/v1|v1|api)$/i, "");
|
|
3326
3326
|
const timeout = Number((_b = llmConfig.options) == null ? void 0 : _b.timeout) || 3e5;
|
|
3327
3327
|
const headers = ((_c = llmConfig.options) == null ? void 0 : _c.headers) || {};
|
|
@@ -3381,8 +3381,8 @@ var OllamaProvider = class {
|
|
|
3381
3381
|
};
|
|
3382
3382
|
}
|
|
3383
3383
|
async chat(messages, context, options) {
|
|
3384
|
-
var
|
|
3385
|
-
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.";
|
|
3386
3386
|
const system = buildSystemContent(basePrompt, context);
|
|
3387
3387
|
const { data } = await this.http.post("/api/chat", {
|
|
3388
3388
|
model: this.llmConfig.model,
|
|
@@ -3400,8 +3400,8 @@ var OllamaProvider = class {
|
|
|
3400
3400
|
}
|
|
3401
3401
|
chatStream(messages, context, options) {
|
|
3402
3402
|
return __asyncGenerator(this, null, function* () {
|
|
3403
|
-
var
|
|
3404
|
-
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.";
|
|
3405
3405
|
const system = buildSystemContent(basePrompt, context);
|
|
3406
3406
|
const response = yield new __await(this.http.post("/api/chat", {
|
|
3407
3407
|
model: this.llmConfig.model,
|
|
@@ -3459,8 +3459,8 @@ var OllamaProvider = class {
|
|
|
3459
3459
|
});
|
|
3460
3460
|
}
|
|
3461
3461
|
async embed(text, options) {
|
|
3462
|
-
var
|
|
3463
|
-
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";
|
|
3464
3464
|
const baseURL = (_f = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.baseUrl) != null ? _e : this.llmConfig.baseUrl) != null ? _f : "http://localhost:11434";
|
|
3465
3465
|
const client = baseURL !== ((_g2 = this.llmConfig.baseUrl) != null ? _g2 : "http://localhost:11434") ? import_axios.default.create({ baseURL, timeout: 6e4 }) : this.http;
|
|
3466
3466
|
let prompt = text;
|
|
@@ -3561,9 +3561,9 @@ var GeminiProvider = class {
|
|
|
3561
3561
|
static getHealthChecker() {
|
|
3562
3562
|
return {
|
|
3563
3563
|
async check(config) {
|
|
3564
|
-
var
|
|
3564
|
+
var _a3, _b;
|
|
3565
3565
|
const timestamp = Date.now();
|
|
3566
|
-
const apiKey = (_b = (
|
|
3566
|
+
const apiKey = (_b = (_a3 = config.apiKey) != null ? _a3 : process.env.GOOGLE_GENAI_API_KEY) != null ? _b : "";
|
|
3567
3567
|
const modelName = sanitizeModel(config.model);
|
|
3568
3568
|
try {
|
|
3569
3569
|
const { GoogleGenerativeAI: GoogleGenerativeAI2 } = await import("@google/generative-ai");
|
|
@@ -3593,16 +3593,16 @@ var GeminiProvider = class {
|
|
|
3593
3593
|
/** Resolve the embedding client — uses a separate client when the embedding
|
|
3594
3594
|
* API key differs from the LLM API key. */
|
|
3595
3595
|
get embeddingClient() {
|
|
3596
|
-
var
|
|
3597
|
-
if (((
|
|
3596
|
+
var _a3;
|
|
3597
|
+
if (((_a3 = this.embeddingConfig) == null ? void 0 : _a3.apiKey) && this.embeddingConfig.apiKey !== this.llmConfig.apiKey) {
|
|
3598
3598
|
return buildClient(this.embeddingConfig.apiKey);
|
|
3599
3599
|
}
|
|
3600
3600
|
return this.client;
|
|
3601
3601
|
}
|
|
3602
3602
|
/** Resolve the embedding model to use, in order of specificity. */
|
|
3603
3603
|
resolveEmbeddingModel(optionsModel) {
|
|
3604
|
-
var
|
|
3605
|
-
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);
|
|
3606
3606
|
}
|
|
3607
3607
|
/**
|
|
3608
3608
|
* Convert ChatMessage[] to the Gemini contents format.
|
|
@@ -3622,8 +3622,8 @@ var GeminiProvider = class {
|
|
|
3622
3622
|
// ILLMProvider — chat
|
|
3623
3623
|
// -------------------------------------------------------------------------
|
|
3624
3624
|
async chat(messages, context, options) {
|
|
3625
|
-
var
|
|
3626
|
-
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.";
|
|
3627
3627
|
const model = this.client.getGenerativeModel({
|
|
3628
3628
|
model: this.llmConfig.model,
|
|
3629
3629
|
systemInstruction: buildSystemContent(basePrompt, context)
|
|
@@ -3640,8 +3640,8 @@ var GeminiProvider = class {
|
|
|
3640
3640
|
}
|
|
3641
3641
|
chatStream(messages, context, options) {
|
|
3642
3642
|
return __asyncGenerator(this, null, function* () {
|
|
3643
|
-
var
|
|
3644
|
-
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.";
|
|
3645
3645
|
const model = this.client.getGenerativeModel({
|
|
3646
3646
|
model: this.llmConfig.model,
|
|
3647
3647
|
systemInstruction: buildSystemContent(basePrompt, context)
|
|
@@ -3676,11 +3676,11 @@ var GeminiProvider = class {
|
|
|
3676
3676
|
// ILLMProvider — embeddings
|
|
3677
3677
|
// -------------------------------------------------------------------------
|
|
3678
3678
|
async embed(text, options) {
|
|
3679
|
-
var
|
|
3679
|
+
var _a3, _b;
|
|
3680
3680
|
const content = applyPrefix(
|
|
3681
3681
|
text,
|
|
3682
3682
|
options == null ? void 0 : options.taskType,
|
|
3683
|
-
(
|
|
3683
|
+
(_a3 = this.embeddingConfig) == null ? void 0 : _a3.queryPrefix,
|
|
3684
3684
|
(_b = this.embeddingConfig) == null ? void 0 : _b.documentPrefix
|
|
3685
3685
|
);
|
|
3686
3686
|
const modelName = this.resolveEmbeddingModel(options == null ? void 0 : options.model);
|
|
@@ -3697,7 +3697,7 @@ var GeminiProvider = class {
|
|
|
3697
3697
|
const modelName = this.resolveEmbeddingModel(options == null ? void 0 : options.model);
|
|
3698
3698
|
const model = this.embeddingClient.getGenerativeModel({ model: modelName });
|
|
3699
3699
|
const requests = texts.map((text) => {
|
|
3700
|
-
var
|
|
3700
|
+
var _a3, _b;
|
|
3701
3701
|
return {
|
|
3702
3702
|
content: {
|
|
3703
3703
|
role: "user",
|
|
@@ -3705,7 +3705,7 @@ var GeminiProvider = class {
|
|
|
3705
3705
|
text: applyPrefix(
|
|
3706
3706
|
text,
|
|
3707
3707
|
options == null ? void 0 : options.taskType,
|
|
3708
|
-
(
|
|
3708
|
+
(_a3 = this.embeddingConfig) == null ? void 0 : _a3.queryPrefix,
|
|
3709
3709
|
(_b = this.embeddingConfig) == null ? void 0 : _b.documentPrefix
|
|
3710
3710
|
)
|
|
3711
3711
|
}]
|
|
@@ -3722,8 +3722,8 @@ var GeminiProvider = class {
|
|
|
3722
3722
|
throw err;
|
|
3723
3723
|
});
|
|
3724
3724
|
return response.embeddings.map((e) => {
|
|
3725
|
-
var
|
|
3726
|
-
return (
|
|
3725
|
+
var _a3;
|
|
3726
|
+
return (_a3 = e.values) != null ? _a3 : [];
|
|
3727
3727
|
});
|
|
3728
3728
|
}
|
|
3729
3729
|
// -------------------------------------------------------------------------
|
|
@@ -3812,8 +3812,8 @@ var GroqProvider = class {
|
|
|
3812
3812
|
};
|
|
3813
3813
|
}
|
|
3814
3814
|
async chat(messages, context, options) {
|
|
3815
|
-
var
|
|
3816
|
-
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.";
|
|
3817
3817
|
const systemMessage = {
|
|
3818
3818
|
role: "system",
|
|
3819
3819
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3837,8 +3837,8 @@ var GroqProvider = class {
|
|
|
3837
3837
|
}
|
|
3838
3838
|
chatStream(messages, context, options) {
|
|
3839
3839
|
return __asyncGenerator(this, null, function* () {
|
|
3840
|
-
var
|
|
3841
|
-
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.";
|
|
3842
3842
|
const systemMessage = {
|
|
3843
3843
|
role: "system",
|
|
3844
3844
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3972,8 +3972,8 @@ var QwenProvider = class {
|
|
|
3972
3972
|
};
|
|
3973
3973
|
}
|
|
3974
3974
|
async chat(messages, context, options) {
|
|
3975
|
-
var
|
|
3976
|
-
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.";
|
|
3977
3977
|
const systemMessage = {
|
|
3978
3978
|
role: "system",
|
|
3979
3979
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3997,8 +3997,8 @@ var QwenProvider = class {
|
|
|
3997
3997
|
}
|
|
3998
3998
|
chatStream(messages, context, options) {
|
|
3999
3999
|
return __asyncGenerator(this, null, function* () {
|
|
4000
|
-
var
|
|
4001
|
-
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.";
|
|
4002
4002
|
const systemMessage = {
|
|
4003
4003
|
role: "system",
|
|
4004
4004
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -4045,8 +4045,8 @@ var QwenProvider = class {
|
|
|
4045
4045
|
return results[0];
|
|
4046
4046
|
}
|
|
4047
4047
|
async batchEmbed(texts, options) {
|
|
4048
|
-
var
|
|
4049
|
-
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";
|
|
4050
4050
|
const apiKey = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.apiKey) != null ? _e : this.llmConfig.apiKey;
|
|
4051
4051
|
const client = apiKey !== this.llmConfig.apiKey ? new import_openai3.default({
|
|
4052
4052
|
apiKey,
|
|
@@ -4146,9 +4146,9 @@ var VECTOR_PROFILES = {
|
|
|
4146
4146
|
|
|
4147
4147
|
// src/llm/providers/UniversalLLMAdapter.ts
|
|
4148
4148
|
function extractContent(obj) {
|
|
4149
|
-
var
|
|
4149
|
+
var _a3, _b, _c;
|
|
4150
4150
|
if (!obj || typeof obj !== "object") return void 0;
|
|
4151
|
-
const choice = (
|
|
4151
|
+
const choice = (_a3 = obj.choices) == null ? void 0 : _a3[0];
|
|
4152
4152
|
if (!choice) return void 0;
|
|
4153
4153
|
if (typeof ((_b = choice.message) == null ? void 0 : _b.content) === "string") return choice.message.content;
|
|
4154
4154
|
if (typeof ((_c = choice.delta) == null ? void 0 : _c.content) === "string") return choice.delta.content;
|
|
@@ -4158,10 +4158,10 @@ function extractContent(obj) {
|
|
|
4158
4158
|
}
|
|
4159
4159
|
var UniversalLLMAdapter = class {
|
|
4160
4160
|
constructor(config) {
|
|
4161
|
-
var
|
|
4161
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h;
|
|
4162
4162
|
this.model = config.model;
|
|
4163
4163
|
const llmConfig = config;
|
|
4164
|
-
const options = (
|
|
4164
|
+
const options = (_a3 = llmConfig.options) != null ? _a3 : {};
|
|
4165
4165
|
let profile = {};
|
|
4166
4166
|
if (typeof options.profile === "string") {
|
|
4167
4167
|
profile = LLM_PROFILES[options.profile] || {};
|
|
@@ -4187,8 +4187,8 @@ var UniversalLLMAdapter = class {
|
|
|
4187
4187
|
});
|
|
4188
4188
|
}
|
|
4189
4189
|
async chat(messages, context) {
|
|
4190
|
-
var
|
|
4191
|
-
const path2 = (
|
|
4190
|
+
var _a3, _b, _c, _d, _e;
|
|
4191
|
+
const path2 = (_a3 = this.opts.chatPath) != null ? _a3 : "/chat/completions";
|
|
4192
4192
|
const safeMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
|
|
4193
4193
|
role: m.role || "user",
|
|
4194
4194
|
content: typeof m.content === "string" ? m.content : m.content != null ? String(m.content) : ""
|
|
@@ -4254,8 +4254,8 @@ ${context != null ? context : "None"}` },
|
|
|
4254
4254
|
*/
|
|
4255
4255
|
chatStream(messages, context) {
|
|
4256
4256
|
return __asyncGenerator(this, null, function* () {
|
|
4257
|
-
var
|
|
4258
|
-
const path2 = (
|
|
4257
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
4258
|
+
const path2 = (_a3 = this.opts.chatPath) != null ? _a3 : "/chat/completions";
|
|
4259
4259
|
const url = `${this.baseUrl.replace(/\/$/, "")}${path2}`;
|
|
4260
4260
|
const extractPath = ((_b = this.opts.responseExtractPath) != null ? _b : "choices[0].message.content").replace("message.content", "delta.content");
|
|
4261
4261
|
const safeMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
|
|
@@ -4381,8 +4381,8 @@ ${context != null ? context : "None"}` },
|
|
|
4381
4381
|
});
|
|
4382
4382
|
}
|
|
4383
4383
|
async embed(text) {
|
|
4384
|
-
var
|
|
4385
|
-
const path2 = (
|
|
4384
|
+
var _a3, _b, _c, _d, _e;
|
|
4385
|
+
const path2 = (_a3 = this.opts.embedPath) != null ? _a3 : "/embeddings";
|
|
4386
4386
|
const payload = this.opts.embedPayloadTemplate ? buildPayload(this.opts.embedPayloadTemplate, { input: text, model: this.model }) : { input: text, model: this.model };
|
|
4387
4387
|
try {
|
|
4388
4388
|
const { data: data2 } = await this.http.post(path2, payload);
|
|
@@ -4471,7 +4471,7 @@ var LLMFactory = class _LLMFactory {
|
|
|
4471
4471
|
];
|
|
4472
4472
|
}
|
|
4473
4473
|
static create(llmConfig, embeddingConfig) {
|
|
4474
|
-
var
|
|
4474
|
+
var _a3, _b, _c;
|
|
4475
4475
|
switch (llmConfig.provider) {
|
|
4476
4476
|
case "openai":
|
|
4477
4477
|
return new OpenAIProvider(llmConfig, embeddingConfig);
|
|
@@ -4490,7 +4490,7 @@ var LLMFactory = class _LLMFactory {
|
|
|
4490
4490
|
case "custom":
|
|
4491
4491
|
return new UniversalLLMAdapter(llmConfig);
|
|
4492
4492
|
default: {
|
|
4493
|
-
const providerName = String((
|
|
4493
|
+
const providerName = String((_a3 = llmConfig.provider) != null ? _a3 : "").toLowerCase();
|
|
4494
4494
|
const customFactory = customProviders.get(providerName);
|
|
4495
4495
|
if (customFactory) {
|
|
4496
4496
|
return customFactory(llmConfig);
|
|
@@ -4592,7 +4592,7 @@ var ProviderRegistry = class {
|
|
|
4592
4592
|
return null;
|
|
4593
4593
|
}
|
|
4594
4594
|
static async loadVectorProviderClass(provider) {
|
|
4595
|
-
var
|
|
4595
|
+
var _a3;
|
|
4596
4596
|
if (this.vectorProviders[provider]) return this.vectorProviders[provider];
|
|
4597
4597
|
switch (provider) {
|
|
4598
4598
|
case "pinecone": {
|
|
@@ -4601,7 +4601,7 @@ var ProviderRegistry = class {
|
|
|
4601
4601
|
}
|
|
4602
4602
|
case "pgvector":
|
|
4603
4603
|
case "postgresql": {
|
|
4604
|
-
const postgresMode = ((
|
|
4604
|
+
const postgresMode = ((_a3 = process.env.POSTGRES_MODE) != null ? _a3 : "multi").toLowerCase();
|
|
4605
4605
|
if (postgresMode === "single") {
|
|
4606
4606
|
const { PostgreSQLProvider: PostgreSQLProvider2 } = await Promise.resolve().then(() => (init_PostgreSQLProvider(), PostgreSQLProvider_exports));
|
|
4607
4607
|
return PostgreSQLProvider2;
|
|
@@ -4824,7 +4824,7 @@ var ConfigValidator = class {
|
|
|
4824
4824
|
// package.json
|
|
4825
4825
|
var package_default = {
|
|
4826
4826
|
name: "@retrivora-ai/rag-engine",
|
|
4827
|
-
version: "2.3.
|
|
4827
|
+
version: "2.3.1",
|
|
4828
4828
|
description: "Retrivora AI is a plug-and-play AI engine for RAG chat experiences \u2014 generic vector DB + LLM provider, embeddable or standalone.",
|
|
4829
4829
|
author: "Abhinav Alkuchi",
|
|
4830
4830
|
license: "UNLICENSED",
|
|
@@ -5129,8 +5129,8 @@ var Reranker = class {
|
|
|
5129
5129
|
return matches.sort((a, b) => b.score - a.score).slice(0, limit);
|
|
5130
5130
|
}
|
|
5131
5131
|
const scoredMatches = matches.map((match) => {
|
|
5132
|
-
var
|
|
5133
|
-
const contentLower = ((
|
|
5132
|
+
var _a3;
|
|
5133
|
+
const contentLower = ((_a3 = match == null ? void 0 : match.content) != null ? _a3 : "").toLowerCase();
|
|
5134
5134
|
let keywordScore = 0;
|
|
5135
5135
|
keywords.forEach((keyword) => {
|
|
5136
5136
|
if (contentLower.includes(keyword)) {
|
|
@@ -5152,8 +5152,8 @@ var Reranker = class {
|
|
|
5152
5152
|
|
|
5153
5153
|
Documents:
|
|
5154
5154
|
${topN.map((m, i) => {
|
|
5155
|
-
var
|
|
5156
|
-
return `[${i}] ${((
|
|
5155
|
+
var _a3;
|
|
5156
|
+
return `[${i}] ${((_a3 = m == null ? void 0 : m.content) != null ? _a3 : "").replace(/\n/g, " ")}`;
|
|
5157
5157
|
}).join("\n")}` }],
|
|
5158
5158
|
"",
|
|
5159
5159
|
{
|
|
@@ -5197,11 +5197,11 @@ var LlamaIndexIngestor = class {
|
|
|
5197
5197
|
* than standard character-count splitting.
|
|
5198
5198
|
*/
|
|
5199
5199
|
async chunk(text, options = {}) {
|
|
5200
|
-
var
|
|
5200
|
+
var _a3, _b;
|
|
5201
5201
|
try {
|
|
5202
5202
|
const { Document, SentenceSplitter, MetadataMode } = await import(`${"llamaindex"}`);
|
|
5203
5203
|
const splitter = new SentenceSplitter({
|
|
5204
|
-
chunkSize: (
|
|
5204
|
+
chunkSize: (_a3 = options.chunkSize) != null ? _a3 : 1e3,
|
|
5205
5205
|
chunkOverlap: (_b = options.chunkOverlap) != null ? _b : 200
|
|
5206
5206
|
});
|
|
5207
5207
|
const doc = new Document({ text, metadata: options.metadata || {} });
|
|
@@ -5310,7 +5310,7 @@ ${error instanceof Error ? error.message : String(error)}`
|
|
|
5310
5310
|
* The agent returns `{ messages: [...] }` — the last message is the final answer.
|
|
5311
5311
|
*/
|
|
5312
5312
|
async run(input, chatHistory = []) {
|
|
5313
|
-
var
|
|
5313
|
+
var _a3, _b, _c;
|
|
5314
5314
|
if (!this.agent) {
|
|
5315
5315
|
throw new Error("[LangChainAgent] Agent not initialized. Call initialize() first.");
|
|
5316
5316
|
}
|
|
@@ -5321,7 +5321,7 @@ ${error instanceof Error ? error.message : String(error)}`
|
|
|
5321
5321
|
const response = await this.agent.invoke({
|
|
5322
5322
|
messages: [...historyMessages, new HumanMessage(input)]
|
|
5323
5323
|
});
|
|
5324
|
-
const lastMessage = (
|
|
5324
|
+
const lastMessage = (_a3 = response == null ? void 0 : response.messages) == null ? void 0 : _a3.at(-1);
|
|
5325
5325
|
if (lastMessage && typeof lastMessage.content === "string") {
|
|
5326
5326
|
return lastMessage.content;
|
|
5327
5327
|
}
|
|
@@ -5373,7 +5373,7 @@ var MCPClient = class {
|
|
|
5373
5373
|
}
|
|
5374
5374
|
}
|
|
5375
5375
|
async connectStdio() {
|
|
5376
|
-
var
|
|
5376
|
+
var _a3;
|
|
5377
5377
|
const cmd = this.config.command;
|
|
5378
5378
|
if (!cmd) {
|
|
5379
5379
|
throw new Error(`[MCPClient] Command option is required for stdio transport on "${this.config.name}"`);
|
|
@@ -5388,7 +5388,7 @@ var MCPClient = class {
|
|
|
5388
5388
|
this.stdioBuffer += data.toString("utf-8");
|
|
5389
5389
|
this.processStdioLines();
|
|
5390
5390
|
});
|
|
5391
|
-
(
|
|
5391
|
+
(_a3 = this.childProcess.stderr) == null ? void 0 : _a3.on("data", (data) => {
|
|
5392
5392
|
console.warn(`[MCPClient] [stderr] [${this.config.name}]:`, data.toString("utf-8"));
|
|
5393
5393
|
});
|
|
5394
5394
|
this.childProcess.on("close", (code) => {
|
|
@@ -5463,14 +5463,14 @@ var MCPClient = class {
|
|
|
5463
5463
|
}
|
|
5464
5464
|
}
|
|
5465
5465
|
async sendNotification(method, params) {
|
|
5466
|
-
var
|
|
5466
|
+
var _a3;
|
|
5467
5467
|
const notification = {
|
|
5468
5468
|
jsonrpc: "2.0",
|
|
5469
5469
|
method,
|
|
5470
5470
|
params
|
|
5471
5471
|
};
|
|
5472
5472
|
if (this.config.transport === "stdio") {
|
|
5473
|
-
if ((
|
|
5473
|
+
if ((_a3 = this.childProcess) == null ? void 0 : _a3.stdin) {
|
|
5474
5474
|
this.childProcess.stdin.write(JSON.stringify(notification) + "\n", "utf-8");
|
|
5475
5475
|
}
|
|
5476
5476
|
} else if (this.sseUrl) {
|
|
@@ -5548,11 +5548,11 @@ var MCPRegistry = class {
|
|
|
5548
5548
|
// src/core/MultiAgentCoordinator.ts
|
|
5549
5549
|
var MultiAgentCoordinator = class {
|
|
5550
5550
|
constructor(options) {
|
|
5551
|
-
var
|
|
5551
|
+
var _a3;
|
|
5552
5552
|
this.llmProvider = options.llmProvider;
|
|
5553
5553
|
this.mcpRegistry = options.mcpRegistry;
|
|
5554
5554
|
this.documentSearch = options.documentSearch;
|
|
5555
|
-
this.maxIterations = (
|
|
5555
|
+
this.maxIterations = (_a3 = options.maxIterations) != null ? _a3 : 5;
|
|
5556
5556
|
}
|
|
5557
5557
|
/**
|
|
5558
5558
|
* Run the multi-agent coordination loop synchronously and return the final response.
|
|
@@ -5604,8 +5604,8 @@ Available Tools:
|
|
|
5604
5604
|
|
|
5605
5605
|
${mcpTools.length > 0 ? "MCP Server Tools:" : ""}
|
|
5606
5606
|
${mcpTools.map((mt) => {
|
|
5607
|
-
var
|
|
5608
|
-
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."}`;
|
|
5609
5609
|
}).join("\n")}
|
|
5610
5610
|
|
|
5611
5611
|
Tool Calling Protocol:
|
|
@@ -5763,6 +5763,100 @@ ${toolResultText}`
|
|
|
5763
5763
|
}
|
|
5764
5764
|
};
|
|
5765
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
|
+
|
|
5766
5860
|
// src/core/BatchProcessor.ts
|
|
5767
5861
|
function isTransientError(error) {
|
|
5768
5862
|
if (!(error instanceof Error)) return false;
|
|
@@ -5786,7 +5880,34 @@ function calculateBackoffDelay(attempt, initialDelayMs, maxDelayMs, multiplier)
|
|
|
5786
5880
|
function sleep(ms) {
|
|
5787
5881
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
5788
5882
|
}
|
|
5789
|
-
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
|
+
}
|
|
5790
5911
|
/**
|
|
5791
5912
|
* Processes an array of items in configurable batches with retry logic.
|
|
5792
5913
|
*
|
|
@@ -5827,7 +5948,7 @@ var BatchProcessor = class {
|
|
|
5827
5948
|
let lastError;
|
|
5828
5949
|
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
5829
5950
|
try {
|
|
5830
|
-
const result = await processor(batch);
|
|
5951
|
+
const result = await _BatchProcessor.executeWithCircuitBreaker(() => processor(batch));
|
|
5831
5952
|
results.push(result);
|
|
5832
5953
|
success = true;
|
|
5833
5954
|
break;
|
|
@@ -5885,7 +6006,7 @@ ${errorMessages}`
|
|
|
5885
6006
|
let lastError;
|
|
5886
6007
|
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
5887
6008
|
try {
|
|
5888
|
-
const result = await processor(item);
|
|
6009
|
+
const result = await _BatchProcessor.executeWithCircuitBreaker(() => processor(item));
|
|
5889
6010
|
results.push(result);
|
|
5890
6011
|
success = true;
|
|
5891
6012
|
break;
|
|
@@ -5958,7 +6079,7 @@ ${errorMessages}`
|
|
|
5958
6079
|
}));
|
|
5959
6080
|
const chunkPromises = chunk.map(async ({ item, originalIndex }) => {
|
|
5960
6081
|
try {
|
|
5961
|
-
const result = await processor(item);
|
|
6082
|
+
const result = await _BatchProcessor.executeWithCircuitBreaker(() => processor(item));
|
|
5962
6083
|
return { success: true, result, index: originalIndex };
|
|
5963
6084
|
} catch (err) {
|
|
5964
6085
|
const error = err instanceof Error ? err : new Error(String(err));
|
|
@@ -5986,6 +6107,12 @@ ${errorMessages}`
|
|
|
5986
6107
|
return { results, errors, totalProcessed, totalFailed };
|
|
5987
6108
|
}
|
|
5988
6109
|
};
|
|
6110
|
+
_BatchProcessor.cb = new CircuitBreaker({
|
|
6111
|
+
failureThreshold: 5,
|
|
6112
|
+
resetTimeoutMs: 3e4,
|
|
6113
|
+
halfOpenMaxCalls: 1
|
|
6114
|
+
});
|
|
6115
|
+
var BatchProcessor = _BatchProcessor;
|
|
5989
6116
|
|
|
5990
6117
|
// src/config/EmbeddingStrategy.ts
|
|
5991
6118
|
var EmbeddingStrategy = /* @__PURE__ */ ((EmbeddingStrategy2) => {
|
|
@@ -6089,7 +6216,7 @@ var QueryProcessor = class {
|
|
|
6089
6216
|
* @param validFields Optional list of known filterable fields to look for
|
|
6090
6217
|
*/
|
|
6091
6218
|
static extractQueryFieldHints(question, validFields = []) {
|
|
6092
|
-
var
|
|
6219
|
+
var _a3, _b, _c, _d;
|
|
6093
6220
|
if (!question.trim()) return [];
|
|
6094
6221
|
const hints = /* @__PURE__ */ new Map();
|
|
6095
6222
|
const addHint = (value, field) => {
|
|
@@ -6169,7 +6296,7 @@ var QueryProcessor = class {
|
|
|
6169
6296
|
];
|
|
6170
6297
|
for (const p of universalPatterns) {
|
|
6171
6298
|
for (const match of question.matchAll(p.regex)) {
|
|
6172
|
-
const val = p.group ? (
|
|
6299
|
+
const val = p.group ? (_a3 = match[p.group]) != null ? _a3 : match[0] : match[0];
|
|
6173
6300
|
if (!val) continue;
|
|
6174
6301
|
if (p.field) addHint(val, p.field);
|
|
6175
6302
|
else addHint(val);
|
|
@@ -6393,11 +6520,11 @@ var LLMRouter = class {
|
|
|
6393
6520
|
* When provided it is used directly as the 'default' role without re-constructing.
|
|
6394
6521
|
*/
|
|
6395
6522
|
async initialize(prebuiltDefault) {
|
|
6396
|
-
var
|
|
6523
|
+
var _a3;
|
|
6397
6524
|
const defaultModel = prebuiltDefault != null ? prebuiltDefault : LLMFactory.create(this.config.llm, this.config.embedding);
|
|
6398
6525
|
this.models.set("default", defaultModel);
|
|
6399
6526
|
const envFastModel = process.env.FAST_LLM_MODEL;
|
|
6400
|
-
const providerFastDefault = (
|
|
6527
|
+
const providerFastDefault = (_a3 = FAST_MODEL_DEFAULTS[this.config.llm.provider]) != null ? _a3 : "";
|
|
6401
6528
|
const fastModelName = envFastModel || providerFastDefault;
|
|
6402
6529
|
if (fastModelName && fastModelName !== this.config.llm.model) {
|
|
6403
6530
|
console.log(`[LLMRouter] Fast role \u2192 provider="${this.config.llm.provider}" model="${fastModelName}"`);
|
|
@@ -6416,8 +6543,8 @@ var LLMRouter = class {
|
|
|
6416
6543
|
* Falls back to 'default' if the requested role is not registered.
|
|
6417
6544
|
*/
|
|
6418
6545
|
get(role) {
|
|
6419
|
-
var
|
|
6420
|
-
const provider = (
|
|
6546
|
+
var _a3;
|
|
6547
|
+
const provider = (_a3 = this.models.get(role)) != null ? _a3 : this.models.get("default");
|
|
6421
6548
|
if (!provider) {
|
|
6422
6549
|
throw new Error(`[LLMRouter] No provider registered for role: "${role}". Did you call initialize()?`);
|
|
6423
6550
|
}
|
|
@@ -6503,8 +6630,8 @@ var IntentClassifier = class {
|
|
|
6503
6630
|
numericFieldCount = numericKeys.size;
|
|
6504
6631
|
categoricalFieldCount = catKeys.size;
|
|
6505
6632
|
if (productKeyMatches >= 2 || docs.some((d) => {
|
|
6506
|
-
var
|
|
6507
|
-
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");
|
|
6508
6635
|
})) {
|
|
6509
6636
|
isProductLike = true;
|
|
6510
6637
|
}
|
|
@@ -6786,8 +6913,8 @@ var TextRendererStrategy = class {
|
|
|
6786
6913
|
}
|
|
6787
6914
|
const docs = Array.isArray(data) ? data : [];
|
|
6788
6915
|
const text = docs.map((d) => {
|
|
6789
|
-
var
|
|
6790
|
-
return (
|
|
6916
|
+
var _a3;
|
|
6917
|
+
return (_a3 = d == null ? void 0 : d.content) != null ? _a3 : "";
|
|
6791
6918
|
}).join("\n\n");
|
|
6792
6919
|
return { type: "text", title, data: { content: text || "No detailed content available." } };
|
|
6793
6920
|
}
|
|
@@ -6930,9 +7057,9 @@ var LRUDecisionCache = class {
|
|
|
6930
7057
|
this.maxSize = maxSize;
|
|
6931
7058
|
}
|
|
6932
7059
|
generateKey(context) {
|
|
6933
|
-
var
|
|
7060
|
+
var _a3, _b;
|
|
6934
7061
|
const q = (context.userQuery || "").toLowerCase().trim();
|
|
6935
|
-
const docCount = (_b = (
|
|
7062
|
+
const docCount = (_b = (_a3 = context.retrievedDocuments) == null ? void 0 : _a3.length) != null ? _b : 0;
|
|
6936
7063
|
return `${q}::docs:${docCount}`;
|
|
6937
7064
|
}
|
|
6938
7065
|
get(context) {
|
|
@@ -7041,7 +7168,7 @@ var UITransformer = class _UITransformer {
|
|
|
7041
7168
|
* Prefer `analyzeAndDecide()` in production.
|
|
7042
7169
|
*/
|
|
7043
7170
|
static transform(userQuery, retrievedData, config, trainedSchema, intent) {
|
|
7044
|
-
var
|
|
7171
|
+
var _a3, _b, _c;
|
|
7045
7172
|
if (!retrievedData || retrievedData.length === 0) {
|
|
7046
7173
|
return this.createTextResponse("No data available", "No relevant data found for your query.");
|
|
7047
7174
|
}
|
|
@@ -7061,7 +7188,7 @@ var UITransformer = class _UITransformer {
|
|
|
7061
7188
|
return this.transformToBarChart(filteredData, profile, userQuery, resolvedIntent.visualizationHint === "ranking");
|
|
7062
7189
|
}
|
|
7063
7190
|
if (resolvedIntent.visualizationHint === "distribution") {
|
|
7064
|
-
return (
|
|
7191
|
+
return (_a3 = this.transformToHistogram(profile, userQuery)) != null ? _a3 : this.transformToBarChart(filteredData, profile, userQuery);
|
|
7065
7192
|
}
|
|
7066
7193
|
if (resolvedIntent.visualizationHint === "correlation") {
|
|
7067
7194
|
return (_b = this.transformToScatterPlot(profile, userQuery)) != null ? _b : this.transformToBarChart(filteredData, profile, userQuery);
|
|
@@ -7394,11 +7521,11 @@ ${schemaProfileText}` : ""}`;
|
|
|
7394
7521
|
};
|
|
7395
7522
|
}
|
|
7396
7523
|
static transformToPieChart(data, profile, query = "") {
|
|
7397
|
-
var
|
|
7524
|
+
var _a3;
|
|
7398
7525
|
const dimension = profile ? this.selectDimensionField(profile, query) : void 0;
|
|
7399
7526
|
const categories = dimension ? Array.from(new Set(profile.records.map((record) => {
|
|
7400
|
-
var
|
|
7401
|
-
return String((
|
|
7527
|
+
var _a4;
|
|
7528
|
+
return String((_a4 = record.fields[dimension.key]) != null ? _a4 : "");
|
|
7402
7529
|
}).filter(Boolean))) : this.detectCategories(data);
|
|
7403
7530
|
if (categories.length === 0) return null;
|
|
7404
7531
|
const categoryData = dimension && profile ? this.aggregateProfileByDimension(profile, dimension.key) : this.aggregateByCategory(data, categories);
|
|
@@ -7408,7 +7535,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7408
7535
|
});
|
|
7409
7536
|
return {
|
|
7410
7537
|
type: "pie_chart",
|
|
7411
|
-
title: `Distribution by ${(
|
|
7538
|
+
title: `Distribution by ${(_a3 = dimension == null ? void 0 : dimension.label) != null ? _a3 : "Category"}`,
|
|
7412
7539
|
description: `Showing breakdown across ${pieData.length} categories`,
|
|
7413
7540
|
data: pieData
|
|
7414
7541
|
};
|
|
@@ -7418,8 +7545,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7418
7545
|
const valueField = profile.numericFields[0];
|
|
7419
7546
|
const buckets = /* @__PURE__ */ new Map();
|
|
7420
7547
|
profile.records.forEach((record) => {
|
|
7421
|
-
var
|
|
7422
|
-
const timestamp = String((
|
|
7548
|
+
var _a3, _b, _c;
|
|
7549
|
+
const timestamp = String((_a3 = record.fields[dateField.key]) != null ? _a3 : "");
|
|
7423
7550
|
const value = (_b = this.toFiniteNumber(record.fields[valueField.key])) != null ? _b : 0;
|
|
7424
7551
|
buckets.set(timestamp, ((_c = buckets.get(timestamp)) != null ? _c : 0) + value);
|
|
7425
7552
|
});
|
|
@@ -7432,23 +7559,23 @@ ${schemaProfileText}` : ""}`;
|
|
|
7432
7559
|
};
|
|
7433
7560
|
}
|
|
7434
7561
|
static transformToBarChart(data, profile, query = "", horizontal = false) {
|
|
7435
|
-
var
|
|
7562
|
+
var _a3;
|
|
7436
7563
|
const dimension = profile ? this.selectDimensionField(profile, query) : void 0;
|
|
7437
7564
|
const measure = profile ? this.selectNumericField(profile, query) : void 0;
|
|
7438
7565
|
const aggregate = dimension && profile ? this.aggregateProfileByDimension(profile, dimension.key, measure == null ? void 0 : measure.key) : this.aggregateByCategory(data, this.detectCategories(data));
|
|
7439
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);
|
|
7440
7567
|
const fallbackData = barData.length > 0 ? barData : data.slice(0, 12).map((item, index) => {
|
|
7441
|
-
var
|
|
7568
|
+
var _a4, _b, _c, _d, _e;
|
|
7442
7569
|
const meta = item.metadata || {};
|
|
7443
7570
|
const label = String(
|
|
7444
|
-
(_c = (_b = (
|
|
7571
|
+
(_c = (_b = (_a4 = this.getDynamicVal(meta, "name")) != null ? _a4 : meta.label) != null ? _b : meta.title) != null ? _c : `Result ${index + 1}`
|
|
7445
7572
|
);
|
|
7446
7573
|
const value = (_e = (_d = this.extractNumericValue(meta)) != null ? _d : item.score) != null ? _e : 0;
|
|
7447
7574
|
return { category: label, value: Number(value) };
|
|
7448
7575
|
});
|
|
7449
7576
|
return {
|
|
7450
7577
|
type: horizontal ? "horizontal_bar" : "bar_chart",
|
|
7451
|
-
title: dimension ? `${(
|
|
7578
|
+
title: dimension ? `${(_a3 = measure == null ? void 0 : measure.label) != null ? _a3 : "Count"} by ${dimension.label}` : "Comparison",
|
|
7452
7579
|
description: `Showing ${fallbackData.length} comparable values`,
|
|
7453
7580
|
data: fallbackData
|
|
7454
7581
|
};
|
|
@@ -7483,11 +7610,11 @@ ${schemaProfileText}` : ""}`;
|
|
|
7483
7610
|
if (fields.length < 2) return null;
|
|
7484
7611
|
const [xField, yField] = fields;
|
|
7485
7612
|
const points = profile.records.map((record) => {
|
|
7486
|
-
var
|
|
7613
|
+
var _a3;
|
|
7487
7614
|
const x = this.toFiniteNumber(record.fields[xField.key]);
|
|
7488
7615
|
const y = this.toFiniteNumber(record.fields[yField.key]);
|
|
7489
7616
|
if (x === null || y === null) return null;
|
|
7490
|
-
return { x, y, label: String((
|
|
7617
|
+
return { x, y, label: String((_a3 = this.getRecordLabel(record)) != null ? _a3 : record.id) };
|
|
7491
7618
|
}).filter((point) => point !== null).slice(0, 100);
|
|
7492
7619
|
if (points.length === 0) return null;
|
|
7493
7620
|
return {
|
|
@@ -7517,9 +7644,9 @@ ${schemaProfileText}` : ""}`;
|
|
|
7517
7644
|
static transformToRadarChart(data) {
|
|
7518
7645
|
const attributeMap = {};
|
|
7519
7646
|
data.forEach((item) => {
|
|
7520
|
-
var
|
|
7647
|
+
var _a3, _b, _c;
|
|
7521
7648
|
const meta = item.metadata || {};
|
|
7522
|
-
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");
|
|
7523
7650
|
Object.entries(meta).forEach(([key, val]) => {
|
|
7524
7651
|
if (typeof val === "number" && !["price", "id"].includes(key.toLowerCase())) {
|
|
7525
7652
|
if (!attributeMap[key]) attributeMap[key] = {};
|
|
@@ -7535,8 +7662,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7535
7662
|
title: "Product Comparison",
|
|
7536
7663
|
description: `Comparing ${data.length} items across ${radarData.length} attributes`,
|
|
7537
7664
|
data: radarData.length > 0 ? radarData : data.map((d) => {
|
|
7538
|
-
var
|
|
7539
|
-
return { attribute: ((
|
|
7665
|
+
var _a3;
|
|
7666
|
+
return { attribute: ((_a3 = d == null ? void 0 : d.content) != null ? _a3 : "").substring(0, 40) };
|
|
7540
7667
|
})
|
|
7541
7668
|
};
|
|
7542
7669
|
}
|
|
@@ -7555,8 +7682,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7555
7682
|
return this.createTextResponse(
|
|
7556
7683
|
"Retrieved Context",
|
|
7557
7684
|
data.map((item) => {
|
|
7558
|
-
var
|
|
7559
|
-
return (
|
|
7685
|
+
var _a3;
|
|
7686
|
+
return (_a3 = item == null ? void 0 : item.content) != null ? _a3 : "";
|
|
7560
7687
|
}).join("\n\n"),
|
|
7561
7688
|
`Found ${data.length} relevant results`
|
|
7562
7689
|
);
|
|
@@ -7607,11 +7734,11 @@ ${schemaProfileText}` : ""}`;
|
|
|
7607
7734
|
return null;
|
|
7608
7735
|
}
|
|
7609
7736
|
static normalizeTransformation(payload) {
|
|
7610
|
-
var
|
|
7737
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j;
|
|
7611
7738
|
if (!payload || typeof payload !== "object") return null;
|
|
7612
7739
|
const p = payload;
|
|
7613
7740
|
const type = this.normalizeVisualizationType(
|
|
7614
|
-
String((_c = (_b = (
|
|
7741
|
+
String((_c = (_b = (_a3 = p.type) != null ? _a3 : p.view) != null ? _b : p.chartType) != null ? _c : "")
|
|
7615
7742
|
);
|
|
7616
7743
|
if (!type) return null;
|
|
7617
7744
|
const title = String((_e = (_d = p.title) != null ? _d : p.heading) != null ? _e : "Visualization");
|
|
@@ -7622,7 +7749,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7622
7749
|
return this.validateTransformation(transformation) ? transformation : null;
|
|
7623
7750
|
}
|
|
7624
7751
|
static normalizeVisualizationType(type) {
|
|
7625
|
-
var
|
|
7752
|
+
var _a3;
|
|
7626
7753
|
const mapping = {
|
|
7627
7754
|
pie: "pie_chart",
|
|
7628
7755
|
pie_chart: "pie_chart",
|
|
@@ -7650,7 +7777,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7650
7777
|
product_carousel: "product_carousel",
|
|
7651
7778
|
carousel: "carousel"
|
|
7652
7779
|
};
|
|
7653
|
-
return (
|
|
7780
|
+
return (_a3 = mapping[type.toLowerCase()]) != null ? _a3 : null;
|
|
7654
7781
|
}
|
|
7655
7782
|
static validateTransformation(t) {
|
|
7656
7783
|
const { type, data } = t;
|
|
@@ -7766,7 +7893,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7766
7893
|
}
|
|
7767
7894
|
static profileData(data) {
|
|
7768
7895
|
const records = (data || []).filter((item) => Boolean(item && typeof item === "object")).map((item) => {
|
|
7769
|
-
var
|
|
7896
|
+
var _a3, _b;
|
|
7770
7897
|
const fields2 = {};
|
|
7771
7898
|
Object.entries(item.metadata || {}).forEach(([key, value]) => {
|
|
7772
7899
|
const primitive = this.toPrimitive(value);
|
|
@@ -7775,7 +7902,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7775
7902
|
if (!fields2.content && item.content) fields2.content = item.content.substring(0, 500);
|
|
7776
7903
|
return {
|
|
7777
7904
|
id: item.id,
|
|
7778
|
-
content: (
|
|
7905
|
+
content: (_a3 = item.content) != null ? _a3 : "",
|
|
7779
7906
|
score: (_b = item.score) != null ? _b : 0,
|
|
7780
7907
|
fields: fields2,
|
|
7781
7908
|
source: item
|
|
@@ -7856,16 +7983,16 @@ ${schemaProfileText}` : ""}`;
|
|
|
7856
7983
|
return null;
|
|
7857
7984
|
}
|
|
7858
7985
|
static selectDimensionField(profile, query) {
|
|
7859
|
-
var
|
|
7986
|
+
var _a3, _b;
|
|
7860
7987
|
const productCategory = profile.categoricalFields.find(
|
|
7861
7988
|
(field) => /category|department|collection|type|group|segment|region|country|state|city/i.test(field.key)
|
|
7862
7989
|
);
|
|
7863
7990
|
const ranked = this.rankFieldsByQuery(profile.categoricalFields, query);
|
|
7864
|
-
return (_b = (
|
|
7991
|
+
return (_b = (_a3 = ranked[0]) != null ? _a3 : productCategory) != null ? _b : profile.categoricalFields[0];
|
|
7865
7992
|
}
|
|
7866
7993
|
static selectNumericField(profile, query) {
|
|
7867
|
-
var
|
|
7868
|
-
return (
|
|
7994
|
+
var _a3;
|
|
7995
|
+
return (_a3 = this.rankFieldsByQuery(profile.numericFields, query)[0]) != null ? _a3 : profile.numericFields[0];
|
|
7869
7996
|
}
|
|
7870
7997
|
static rankFieldsByQuery(fields, query) {
|
|
7871
7998
|
const q = query.toLowerCase();
|
|
@@ -7894,8 +8021,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7894
8021
|
static aggregateProfileByDimension(profile, dimensionKey, measureKey) {
|
|
7895
8022
|
const result = {};
|
|
7896
8023
|
profile.records.forEach((record) => {
|
|
7897
|
-
var
|
|
7898
|
-
const category = String((
|
|
8024
|
+
var _a3, _b, _c;
|
|
8025
|
+
const category = String((_a3 = record.fields[dimensionKey]) != null ? _a3 : "Other").trim() || "Other";
|
|
7899
8026
|
const value = measureKey ? (_b = this.toFiniteNumber(record.fields[measureKey])) != null ? _b : 0 : 1;
|
|
7900
8027
|
result[category] = ((_c = result[category]) != null ? _c : 0) + value;
|
|
7901
8028
|
});
|
|
@@ -7975,8 +8102,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7975
8102
|
static aggregateByCategory(data, categories) {
|
|
7976
8103
|
const result = Object.fromEntries(categories.map((c) => [c, 0]));
|
|
7977
8104
|
data.forEach((item) => {
|
|
7978
|
-
var
|
|
7979
|
-
const cat = (
|
|
8105
|
+
var _a3;
|
|
8106
|
+
const cat = (_a3 = this.getProductCategory(item)) != null ? _a3 : "Other";
|
|
7980
8107
|
if (Object.prototype.hasOwnProperty.call(result, cat)) result[cat]++;
|
|
7981
8108
|
else result["Other"] = (result["Other"] || 0) + 1;
|
|
7982
8109
|
});
|
|
@@ -7984,17 +8111,17 @@ ${schemaProfileText}` : ""}`;
|
|
|
7984
8111
|
}
|
|
7985
8112
|
static extractTimeSeriesData(data) {
|
|
7986
8113
|
return data.map((item) => {
|
|
7987
|
-
var
|
|
8114
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
7988
8115
|
const meta = item.metadata || {};
|
|
7989
8116
|
return {
|
|
7990
|
-
timestamp: (_b = (
|
|
8117
|
+
timestamp: (_b = (_a3 = meta.timestamp) != null ? _a3 : meta.date) != null ? _b : (/* @__PURE__ */ new Date()).toISOString(),
|
|
7991
8118
|
value: (_d = (_c = meta.value) != null ? _c : item.score) != null ? _d : 0,
|
|
7992
8119
|
label: (_f = meta.label) != null ? _f : ((_e = item == null ? void 0 : item.content) != null ? _e : "").substring(0, 50)
|
|
7993
8120
|
};
|
|
7994
8121
|
});
|
|
7995
8122
|
}
|
|
7996
8123
|
static extractNumericValue(meta) {
|
|
7997
|
-
var
|
|
8124
|
+
var _a3;
|
|
7998
8125
|
const preferredKeys = [
|
|
7999
8126
|
"value",
|
|
8000
8127
|
"count",
|
|
@@ -8009,7 +8136,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
8009
8136
|
"price"
|
|
8010
8137
|
];
|
|
8011
8138
|
for (const key of preferredKeys) {
|
|
8012
|
-
const raw = (
|
|
8139
|
+
const raw = (_a3 = resolveMetadataValue(meta, key)) != null ? _a3 : meta[key];
|
|
8013
8140
|
const value = typeof raw === "number" ? raw : Number(String(raw != null ? raw : "").replace(/[$,% ,]/g, ""));
|
|
8014
8141
|
if (Number.isFinite(value)) return value;
|
|
8015
8142
|
}
|
|
@@ -8104,8 +8231,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
8104
8231
|
}, query.includes(normalizedField) ? 3 : 0);
|
|
8105
8232
|
}
|
|
8106
8233
|
static resolveTableCellValue(item, column) {
|
|
8107
|
-
var
|
|
8108
|
-
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);
|
|
8109
8236
|
const meta = item.metadata || {};
|
|
8110
8237
|
const normalizedColumn = this.normalizeComparableField(column);
|
|
8111
8238
|
const exactMetadata = Object.entries(meta).find(
|
|
@@ -8157,8 +8284,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
8157
8284
|
let inStock = 0;
|
|
8158
8285
|
let outOfStock = 0;
|
|
8159
8286
|
data.forEach((d) => {
|
|
8160
|
-
var
|
|
8161
|
-
const cat = (
|
|
8287
|
+
var _a3, _b;
|
|
8288
|
+
const cat = (_a3 = this.getProductCategory(d)) != null ? _a3 : "Other";
|
|
8162
8289
|
if (cat === category) {
|
|
8163
8290
|
const quantity = (_b = this.extractStockQuantity(d)) != null ? _b : 1;
|
|
8164
8291
|
if (this.determineStockStatus(d)) inStock += quantity;
|
|
@@ -8204,9 +8331,9 @@ ${schemaProfileText}` : ""}`;
|
|
|
8204
8331
|
}
|
|
8205
8332
|
// ─── Product Extraction ───────────────────────────────────────────────────
|
|
8206
8333
|
static getDynamicVal(meta, uiKey, config, trainedSchema) {
|
|
8207
|
-
var
|
|
8334
|
+
var _a3;
|
|
8208
8335
|
if (!meta) return void 0;
|
|
8209
|
-
const mapping = (
|
|
8336
|
+
const mapping = (_a3 = config == null ? void 0 : config.rag) == null ? void 0 : _a3.uiMapping;
|
|
8210
8337
|
if ((mapping == null ? void 0 : mapping[uiKey]) && meta[mapping[uiKey]] !== void 0) return meta[mapping[uiKey]];
|
|
8211
8338
|
if (trainedSchema && typeof trainedSchema === "object") {
|
|
8212
8339
|
const trainedKey = trainedSchema[uiKey];
|
|
@@ -8215,7 +8342,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
8215
8342
|
return resolveMetadataValue(meta, uiKey);
|
|
8216
8343
|
}
|
|
8217
8344
|
static extractProductInfo(item, config, trainedSchema) {
|
|
8218
|
-
var
|
|
8345
|
+
var _a3, _b;
|
|
8219
8346
|
if (!item) return null;
|
|
8220
8347
|
const meta = item.metadata || {};
|
|
8221
8348
|
const content = item.content || "";
|
|
@@ -8223,7 +8350,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
8223
8350
|
const price = this.getDynamicVal(meta, "price", config, trainedSchema);
|
|
8224
8351
|
const brand = this.getDynamicVal(meta, "brand", config, trainedSchema);
|
|
8225
8352
|
const description = this.cleanProductDescription(
|
|
8226
|
-
(
|
|
8353
|
+
(_a3 = this.extractProductDescriptionFromContent(content)) != null ? _a3 : this.getProductDescriptionValue(meta, config, trainedSchema)
|
|
8227
8354
|
);
|
|
8228
8355
|
if (name || this.isProductData(item)) {
|
|
8229
8356
|
let finalName = name ? String(name) : void 0;
|
|
@@ -8358,10 +8485,10 @@ RULES:
|
|
|
8358
8485
|
}
|
|
8359
8486
|
static buildContextSummary(sources, maxChars = 6e3) {
|
|
8360
8487
|
const items = (sources || []).filter(Boolean).map((s, i) => {
|
|
8361
|
-
var
|
|
8488
|
+
var _a3, _b, _c, _d;
|
|
8362
8489
|
return {
|
|
8363
8490
|
index: i + 1,
|
|
8364
|
-
content: (_b = (
|
|
8491
|
+
content: (_b = (_a3 = s == null ? void 0 : s.content) == null ? void 0 : _a3.substring(0, 400)) != null ? _b : "",
|
|
8365
8492
|
metadata: (_c = s == null ? void 0 : s.metadata) != null ? _c : {},
|
|
8366
8493
|
score: (_d = s == null ? void 0 : s.score) != null ? _d : 0
|
|
8367
8494
|
};
|
|
@@ -8401,7 +8528,7 @@ var SchemaMapper = class {
|
|
|
8401
8528
|
return promise;
|
|
8402
8529
|
}
|
|
8403
8530
|
static async _doTrain(llm, cacheKey, keys) {
|
|
8404
|
-
var
|
|
8531
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
|
|
8405
8532
|
console.log(`[SchemaMapper] \u{1F9E0} Training on new schema keys: ${keys.join(", ")}`);
|
|
8406
8533
|
const propertyList = Object.entries(this.TARGET_PROPERTIES).map(([prop, desc]) => `- ${prop} (${desc})`).join("\n");
|
|
8407
8534
|
const messages = [
|
|
@@ -8417,7 +8544,7 @@ Return a JSON object like {"name":"Title","price":"Price",...}. Omit unmapped pr
|
|
|
8417
8544
|
}
|
|
8418
8545
|
];
|
|
8419
8546
|
try {
|
|
8420
|
-
const baseUrl = (
|
|
8547
|
+
const baseUrl = (_a3 = llm == null ? void 0 : llm.baseUrl) != null ? _a3 : "";
|
|
8421
8548
|
const apiKey = (_b = llm == null ? void 0 : llm.apiKey) != null ? _b : "";
|
|
8422
8549
|
const model = (_c = llm == null ? void 0 : llm.model) != null ? _c : "llama-3.1-8b-instant";
|
|
8423
8550
|
let responseText;
|
|
@@ -8592,9 +8719,9 @@ var Pipeline = class {
|
|
|
8592
8719
|
this.initialised = false;
|
|
8593
8720
|
/** Namespace-specific static cold context cache for CAG */
|
|
8594
8721
|
this.coldContexts = /* @__PURE__ */ new Map();
|
|
8595
|
-
var
|
|
8722
|
+
var _a3, _b, _c, _d, _e;
|
|
8596
8723
|
this.chunker = new DocumentChunker(
|
|
8597
|
-
(_b = (
|
|
8724
|
+
(_b = (_a3 = config.rag) == null ? void 0 : _a3.chunkSize) != null ? _b : 1e3,
|
|
8598
8725
|
(_d = (_c = config.rag) == null ? void 0 : _c.chunkOverlap) != null ? _d : 200
|
|
8599
8726
|
);
|
|
8600
8727
|
if (((_e = config.rag) == null ? void 0 : _e.chunkingStrategy) === "llamaindex") {
|
|
@@ -8610,7 +8737,7 @@ var Pipeline = class {
|
|
|
8610
8737
|
return this.initialised ? this.llmProvider : void 0;
|
|
8611
8738
|
}
|
|
8612
8739
|
async initialize() {
|
|
8613
|
-
var
|
|
8740
|
+
var _a3, _b, _c, _d;
|
|
8614
8741
|
if (this.initialised) return;
|
|
8615
8742
|
const chartInstruction = `You are a helpful assistant. Use the provided context to answer questions accurately.
|
|
8616
8743
|
|
|
@@ -8653,7 +8780,7 @@ var Pipeline = class {
|
|
|
8653
8780
|
this.entityExtractor = new EntityExtractor(this.llmProvider);
|
|
8654
8781
|
}
|
|
8655
8782
|
await this.vectorDB.initialize();
|
|
8656
|
-
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) {
|
|
8657
8784
|
this.mcpRegistry = new MCPRegistry(this.config.mcpServers || []);
|
|
8658
8785
|
this.multiAgentCoordinator = new MultiAgentCoordinator({
|
|
8659
8786
|
llmProvider: this.llmProvider,
|
|
@@ -8671,8 +8798,8 @@ var Pipeline = class {
|
|
|
8671
8798
|
this.initialised = true;
|
|
8672
8799
|
}
|
|
8673
8800
|
async loadColdContext(ns) {
|
|
8674
|
-
var
|
|
8675
|
-
const cagConfig = (
|
|
8801
|
+
var _a3, _b;
|
|
8802
|
+
const cagConfig = (_a3 = this.config.rag) == null ? void 0 : _a3.cag;
|
|
8676
8803
|
if (!cagConfig || !cagConfig.enabled) return;
|
|
8677
8804
|
try {
|
|
8678
8805
|
const coldNs = cagConfig.coldNamespace || ns;
|
|
@@ -8725,12 +8852,12 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8725
8852
|
}
|
|
8726
8853
|
/** Step 1: Chunk the document content. */
|
|
8727
8854
|
async prepareChunks(doc) {
|
|
8728
|
-
var
|
|
8855
|
+
var _a3, _b;
|
|
8729
8856
|
if (this.llamaIngestor) {
|
|
8730
8857
|
return this.llamaIngestor.chunk(doc.content, {
|
|
8731
8858
|
docId: doc.docId,
|
|
8732
8859
|
metadata: doc.metadata,
|
|
8733
|
-
chunkSize: (
|
|
8860
|
+
chunkSize: (_a3 = this.config.rag) == null ? void 0 : _a3.chunkSize,
|
|
8734
8861
|
chunkOverlap: (_b = this.config.rag) == null ? void 0 : _b.chunkOverlap
|
|
8735
8862
|
});
|
|
8736
8863
|
}
|
|
@@ -8828,9 +8955,9 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8828
8955
|
return { reply, sources };
|
|
8829
8956
|
}
|
|
8830
8957
|
async ask(question, history = [], namespace) {
|
|
8831
|
-
var
|
|
8958
|
+
var _a3, _b;
|
|
8832
8959
|
await this.initialize();
|
|
8833
|
-
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) {
|
|
8834
8961
|
return await this.multiAgentCoordinator.run(question, history);
|
|
8835
8962
|
}
|
|
8836
8963
|
const stream = this.askStream(question, history, namespace);
|
|
@@ -8865,9 +8992,9 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8865
8992
|
}
|
|
8866
8993
|
askStream(_0) {
|
|
8867
8994
|
return __asyncGenerator(this, arguments, function* (question, history = [], namespace) {
|
|
8868
|
-
var
|
|
8995
|
+
var _a3, _b;
|
|
8869
8996
|
yield new __await(this.initialize());
|
|
8870
|
-
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) {
|
|
8871
8998
|
const stream2 = this.multiAgentCoordinator.runStream(question, history);
|
|
8872
8999
|
try {
|
|
8873
9000
|
for (var iter = __forAwait(stream2), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
|
|
@@ -8916,10 +9043,10 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8916
9043
|
*/
|
|
8917
9044
|
askStreamInternal(_0) {
|
|
8918
9045
|
return __asyncGenerator(this, arguments, function* (question, history = [], namespace) {
|
|
8919
|
-
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;
|
|
8920
9047
|
yield new __await(this.initialize());
|
|
8921
9048
|
const ns = formatNamespace(namespace != null ? namespace : this.config.projectId);
|
|
8922
|
-
const topK = (_b = (
|
|
9049
|
+
const topK = (_b = (_a3 = this.config.rag) == null ? void 0 : _a3.topK) != null ? _b : 5;
|
|
8923
9050
|
const scoreThreshold = (_d = (_c = this.config.rag) == null ? void 0 : _c.scoreThreshold) != null ? _d : 0.3;
|
|
8924
9051
|
const requestId = `req_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
8925
9052
|
const requestStart = performance.now();
|
|
@@ -8968,8 +9095,8 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8968
9095
|
const rerankStart = performance.now();
|
|
8969
9096
|
const structuredSources = this.applyStructuredFilters(rawSources, filter).filter((s) => Boolean(s && typeof s === "object"));
|
|
8970
9097
|
let fullSources = hasNumericPredicates ? structuredSources : structuredSources.filter((m) => {
|
|
8971
|
-
var
|
|
8972
|
-
return ((
|
|
9098
|
+
var _a4;
|
|
9099
|
+
return ((_a4 = m == null ? void 0 : m.score) != null ? _a4 : 0) >= scoreThreshold;
|
|
8973
9100
|
});
|
|
8974
9101
|
const rerankLimit = Math.max(retrievalLimit, fullSources.length);
|
|
8975
9102
|
const useReranking = arch !== "naive" && (arch === "retrieve-and-rerank" || ((_m = this.config.rag) == null ? void 0 : _m.useReranking));
|
|
@@ -8982,13 +9109,13 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8982
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]
|
|
8983
9110
|
|
|
8984
9111
|
` + promptSources.map((m, i) => {
|
|
8985
|
-
var
|
|
9112
|
+
var _a4;
|
|
8986
9113
|
return `[Source ${i + 1}]
|
|
8987
|
-
${(
|
|
9114
|
+
${(_a4 = m == null ? void 0 : m.content) != null ? _a4 : ""}`;
|
|
8988
9115
|
}).join("\n\n---\n\n") : "No relevant context found.";
|
|
8989
9116
|
const sources = [...fullSources].filter((s) => Boolean(s && typeof s === "object")).sort((a, b) => {
|
|
8990
|
-
var
|
|
8991
|
-
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);
|
|
8992
9119
|
});
|
|
8993
9120
|
if (graphData && graphData.nodes.length > 0) {
|
|
8994
9121
|
const graphContext = graphData.nodes.map(
|
|
@@ -9016,10 +9143,10 @@ ${context}`;
|
|
|
9016
9143
|
yield {
|
|
9017
9144
|
reply: "",
|
|
9018
9145
|
sources: (sources || []).filter((s) => Boolean(s && typeof s === "object")).map((s) => {
|
|
9019
|
-
var
|
|
9146
|
+
var _a4, _b2, _c2;
|
|
9020
9147
|
return {
|
|
9021
9148
|
id: s.id,
|
|
9022
|
-
score: (
|
|
9149
|
+
score: (_a4 = s.score) != null ? _a4 : 0,
|
|
9023
9150
|
content: (_b2 = s == null ? void 0 : s.content) != null ? _b2 : "",
|
|
9024
9151
|
metadata: (_c2 = s == null ? void 0 : s.metadata) != null ? _c2 : {},
|
|
9025
9152
|
namespace: ns
|
|
@@ -9212,11 +9339,11 @@ ${context}`;
|
|
|
9212
9339
|
systemPrompt,
|
|
9213
9340
|
userPrompt: question + finalRestrictionSuffix,
|
|
9214
9341
|
chunks: (sources || []).filter(Boolean).map((s) => {
|
|
9215
|
-
var
|
|
9342
|
+
var _a4, _b2;
|
|
9216
9343
|
return {
|
|
9217
9344
|
id: s.id,
|
|
9218
9345
|
score: s.score,
|
|
9219
|
-
content: (
|
|
9346
|
+
content: (_a4 = s == null ? void 0 : s.content) != null ? _a4 : "",
|
|
9220
9347
|
metadata: (_b2 = s == null ? void 0 : s.metadata) != null ? _b2 : {},
|
|
9221
9348
|
namespace: ns
|
|
9222
9349
|
};
|
|
@@ -9235,7 +9362,7 @@ ${context}`;
|
|
|
9235
9362
|
const telemetryUrl = ((_B = this.config.telemetry) == null ? void 0 : _B.url) || process.env.TELEMETRY_URL || process.env.NEXT_PUBLIC_TELEMETRY_URL || defaultUrl;
|
|
9236
9363
|
const absoluteUrl = telemetryUrl.startsWith("http") ? telemetryUrl : "https://www.retrivora.com" + (telemetryUrl.startsWith("/") ? telemetryUrl : "/" + telemetryUrl);
|
|
9237
9364
|
(async () => {
|
|
9238
|
-
var
|
|
9365
|
+
var _a4, _b2, _c2, _d2, _e2;
|
|
9239
9366
|
try {
|
|
9240
9367
|
let finalTrace = trace;
|
|
9241
9368
|
if (!awaitHallucination && runHallucination) {
|
|
@@ -9244,7 +9371,7 @@ ${context}`;
|
|
|
9244
9371
|
finalTrace = buildTrace(backgroundScoreResult);
|
|
9245
9372
|
}
|
|
9246
9373
|
}
|
|
9247
|
-
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";
|
|
9248
9375
|
const providerName = (finalTrace == null ? void 0 : finalTrace.provider) || ((_b2 = this.config.llm) == null ? void 0 : _b2.provider) || "groq";
|
|
9249
9376
|
const tokenCount = Number(((_c2 = finalTrace == null ? void 0 : finalTrace.tokens) == null ? void 0 : _c2.totalTokens) || 0);
|
|
9250
9377
|
const costEst = Number(((_d2 = finalTrace == null ? void 0 : finalTrace.tokens) == null ? void 0 : _d2.estimatedCostUsd) || 0);
|
|
@@ -9298,7 +9425,7 @@ ${context}`;
|
|
|
9298
9425
|
* Uses an LRU-bounded embedding cache to avoid re-embedding the same query.
|
|
9299
9426
|
*/
|
|
9300
9427
|
async generateUiTransformation(question, sources, cachedSchema, forceDeterministic = false) {
|
|
9301
|
-
var
|
|
9428
|
+
var _a3;
|
|
9302
9429
|
if (!sources || sources.length === 0) {
|
|
9303
9430
|
return UITransformer.transform(question, sources, this.config, cachedSchema);
|
|
9304
9431
|
}
|
|
@@ -9311,7 +9438,7 @@ ${context}`;
|
|
|
9311
9438
|
{ visualizationHint: "product_browse", recommendedChart: "text", filterInStockOnly: false, wantsExplicitTable: false, isTemporal: false, isComparison: false, language: "en" }
|
|
9312
9439
|
);
|
|
9313
9440
|
}
|
|
9314
|
-
const enableLlmUiTransform = ((
|
|
9441
|
+
const enableLlmUiTransform = ((_a3 = this.config.llm.options) == null ? void 0 : _a3.enableLlmUiTransform) === true;
|
|
9315
9442
|
if (forceDeterministic || !enableLlmUiTransform) {
|
|
9316
9443
|
return UITransformer.transform(question, sources, this.config, cachedSchema);
|
|
9317
9444
|
}
|
|
@@ -9329,15 +9456,15 @@ ${context}`;
|
|
|
9329
9456
|
const value = this.resolveNumericPredicateValue(source, predicate);
|
|
9330
9457
|
return value !== null && this.matchesNumericPredicate(value, predicate);
|
|
9331
9458
|
})).sort((a, b) => {
|
|
9332
|
-
var
|
|
9459
|
+
var _a3, _b;
|
|
9333
9460
|
const primary = predicates[0];
|
|
9334
|
-
const aValue = (
|
|
9461
|
+
const aValue = (_a3 = this.resolveNumericPredicateValue(a, primary)) != null ? _a3 : 0;
|
|
9335
9462
|
const bValue = (_b = this.resolveNumericPredicateValue(b, primary)) != null ? _b : 0;
|
|
9336
9463
|
return primary.operator === "lt" || primary.operator === "lte" ? aValue - bValue : bValue - aValue;
|
|
9337
9464
|
});
|
|
9338
9465
|
}
|
|
9339
9466
|
resolveNumericPredicateValue(source, predicate) {
|
|
9340
|
-
var
|
|
9467
|
+
var _a3;
|
|
9341
9468
|
if (!source) return null;
|
|
9342
9469
|
const meta = source.metadata || {};
|
|
9343
9470
|
const field = predicate.field;
|
|
@@ -9350,7 +9477,7 @@ ${context}`;
|
|
|
9350
9477
|
const value = this.toFiniteNumber(Array.isArray(fuzzy) ? fuzzy[1] : fuzzy.value);
|
|
9351
9478
|
if (value !== null) return value;
|
|
9352
9479
|
}
|
|
9353
|
-
const contentValue = this.extractNumericValueFromContent((
|
|
9480
|
+
const contentValue = this.extractNumericValueFromContent((_a3 = source.content) != null ? _a3 : "", field);
|
|
9354
9481
|
if (contentValue !== null) return contentValue;
|
|
9355
9482
|
}
|
|
9356
9483
|
for (const [key, value] of entries) {
|
|
@@ -9406,8 +9533,8 @@ ${context}`;
|
|
|
9406
9533
|
return Number.isFinite(numeric) ? numeric : null;
|
|
9407
9534
|
}
|
|
9408
9535
|
async retrieve(query, options) {
|
|
9409
|
-
var
|
|
9410
|
-
const ns = formatNamespace((
|
|
9536
|
+
var _a3, _b, _c, _d, _e, _f, _g2;
|
|
9537
|
+
const ns = formatNamespace((_a3 = options.namespace) != null ? _a3 : this.config.projectId);
|
|
9411
9538
|
const topK = (_b = options.topK) != null ? _b : 5;
|
|
9412
9539
|
const cacheKey = `${ns}::${query}`;
|
|
9413
9540
|
let queryVector = this.embeddingCache.get(cacheKey);
|
|
@@ -9452,11 +9579,11 @@ ${context}`;
|
|
|
9452
9579
|
namespace: ns,
|
|
9453
9580
|
count: resolvedSources.length,
|
|
9454
9581
|
sample: resolvedSources.slice(0, 2).map((s) => {
|
|
9455
|
-
var
|
|
9582
|
+
var _a4;
|
|
9456
9583
|
return {
|
|
9457
9584
|
id: s == null ? void 0 : s.id,
|
|
9458
9585
|
score: s == null ? void 0 : s.score,
|
|
9459
|
-
contentSnippet: String((
|
|
9586
|
+
contentSnippet: String((_a4 = s == null ? void 0 : s.content) != null ? _a4 : "").substring(0, 150),
|
|
9460
9587
|
metadata: s == null ? void 0 : s.metadata
|
|
9461
9588
|
};
|
|
9462
9589
|
})
|
|
@@ -9470,8 +9597,8 @@ Focus on extracting the core intent and entities. Do not answer the question, ju
|
|
|
9470
9597
|
|
|
9471
9598
|
History:
|
|
9472
9599
|
${(history || []).map((m) => {
|
|
9473
|
-
var
|
|
9474
|
-
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 : ""}`;
|
|
9475
9602
|
}).join("\n")}
|
|
9476
9603
|
|
|
9477
9604
|
New Question: ${question}
|
|
@@ -9498,8 +9625,8 @@ Optimized Search Query:`;
|
|
|
9498
9625
|
const { sources } = await this.retrieve(query, { namespace: ns, topK: 5 });
|
|
9499
9626
|
if (!sources || sources.length === 0) return [];
|
|
9500
9627
|
const context = sources.map((s) => {
|
|
9501
|
-
var
|
|
9502
|
-
return (
|
|
9628
|
+
var _a3;
|
|
9629
|
+
return (_a3 = s == null ? void 0 : s.content) != null ? _a3 : "";
|
|
9503
9630
|
}).join("\n\n---\n\n");
|
|
9504
9631
|
const prompt = `Based on the following snippets from a document, what are at least 5 short, relevant questions a user might ask?
|
|
9505
9632
|
Focus on questions that can be answered by the context.
|
|
@@ -9541,13 +9668,13 @@ var Retrivora = class {
|
|
|
9541
9668
|
this.pipeline = new Pipeline(this.config);
|
|
9542
9669
|
}
|
|
9543
9670
|
async initialize() {
|
|
9544
|
-
var
|
|
9671
|
+
var _a3;
|
|
9545
9672
|
try {
|
|
9546
9673
|
await ConfigValidator.validateAndThrow(this.config);
|
|
9547
9674
|
LicenseVerifier.verify(
|
|
9548
9675
|
this.config.licenseKey,
|
|
9549
9676
|
this.config.projectId,
|
|
9550
|
-
(
|
|
9677
|
+
(_a3 = this.config.vectorDb) == null ? void 0 : _a3.provider
|
|
9551
9678
|
);
|
|
9552
9679
|
await LicenseVerifier.verifyIP(this.config.licenseKey);
|
|
9553
9680
|
} catch (err) {
|
|
@@ -9720,18 +9847,200 @@ var ProviderHealthCheck = class {
|
|
|
9720
9847
|
}
|
|
9721
9848
|
};
|
|
9722
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
|
+
|
|
9723
10032
|
// src/core/VectorPlugin.ts
|
|
9724
10033
|
var VectorPlugin = class {
|
|
9725
10034
|
constructor(hostConfig) {
|
|
9726
10035
|
const resolvedConfig = ConfigResolver.resolve(hostConfig);
|
|
9727
10036
|
this.config = resolvedConfig;
|
|
9728
10037
|
this.validationPromise = (async () => {
|
|
9729
|
-
var
|
|
10038
|
+
var _a3;
|
|
9730
10039
|
await ConfigValidator.validateAndThrow(resolvedConfig);
|
|
9731
10040
|
LicenseVerifier.verify(
|
|
9732
10041
|
resolvedConfig.licenseKey,
|
|
9733
10042
|
resolvedConfig.projectId,
|
|
9734
|
-
(
|
|
10043
|
+
(_a3 = resolvedConfig.vectorDb) == null ? void 0 : _a3.provider
|
|
9735
10044
|
);
|
|
9736
10045
|
})();
|
|
9737
10046
|
this.validationPromise.catch(() => {
|
|
@@ -9765,16 +10074,32 @@ var VectorPlugin = class {
|
|
|
9765
10074
|
this.config.embedding
|
|
9766
10075
|
);
|
|
9767
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
|
+
}
|
|
9768
10084
|
/**
|
|
9769
10085
|
* Run a chat query.
|
|
9770
10086
|
*/
|
|
9771
10087
|
async chat(message, history = [], namespace) {
|
|
10088
|
+
var _a3;
|
|
9772
10089
|
try {
|
|
9773
10090
|
await this.validationPromise;
|
|
9774
10091
|
} catch (err) {
|
|
9775
10092
|
throw wrapError(err, "CONFIGURATION_ERROR");
|
|
9776
10093
|
}
|
|
9777
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
|
+
}
|
|
9778
10103
|
return await this.pipeline.ask(message, history, namespace);
|
|
9779
10104
|
} catch (err) {
|
|
9780
10105
|
const msg = String(err);
|
|
@@ -9782,6 +10107,9 @@ var VectorPlugin = class {
|
|
|
9782
10107
|
if (msg.includes("Embed") || msg.includes("embed")) {
|
|
9783
10108
|
defaultCode = "EMBEDDING_FAILED";
|
|
9784
10109
|
}
|
|
10110
|
+
if (msg.toLowerCase().includes("token limit")) {
|
|
10111
|
+
defaultCode = "RATE_LIMITED";
|
|
10112
|
+
}
|
|
9785
10113
|
throw wrapError(err, defaultCode);
|
|
9786
10114
|
}
|
|
9787
10115
|
}
|
|
@@ -9790,12 +10118,21 @@ var VectorPlugin = class {
|
|
|
9790
10118
|
*/
|
|
9791
10119
|
chatStream(_0) {
|
|
9792
10120
|
return __asyncGenerator(this, arguments, function* (message, history = [], namespace) {
|
|
10121
|
+
var _a3;
|
|
9793
10122
|
try {
|
|
9794
10123
|
yield new __await(this.validationPromise);
|
|
9795
10124
|
} catch (err) {
|
|
9796
10125
|
throw wrapError(err, "CONFIGURATION_ERROR");
|
|
9797
10126
|
}
|
|
9798
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
|
+
}
|
|
9799
10136
|
const stream = this.pipeline.askStream(message, history, namespace);
|
|
9800
10137
|
try {
|
|
9801
10138
|
for (var iter = __forAwait(stream), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
|
|
@@ -9818,6 +10155,9 @@ var VectorPlugin = class {
|
|
|
9818
10155
|
if (msg.includes("Embed") || msg.includes("embed")) {
|
|
9819
10156
|
defaultCode = "EMBEDDING_FAILED";
|
|
9820
10157
|
}
|
|
10158
|
+
if (msg.toLowerCase().includes("token limit")) {
|
|
10159
|
+
defaultCode = "RATE_LIMITED";
|
|
10160
|
+
}
|
|
9821
10161
|
throw wrapError(err, defaultCode);
|
|
9822
10162
|
}
|
|
9823
10163
|
});
|
|
@@ -9872,13 +10212,13 @@ var ConfigBuilder = class {
|
|
|
9872
10212
|
* Configure the vector database provider
|
|
9873
10213
|
*/
|
|
9874
10214
|
vectorDb(provider, options) {
|
|
9875
|
-
var
|
|
10215
|
+
var _a3;
|
|
9876
10216
|
if (provider === "auto") {
|
|
9877
10217
|
this._vectorDb = this._autoDetectVectorDb();
|
|
9878
10218
|
} else {
|
|
9879
10219
|
this._vectorDb = {
|
|
9880
10220
|
provider,
|
|
9881
|
-
indexName: (
|
|
10221
|
+
indexName: (_a3 = options == null ? void 0 : options.indexName) != null ? _a3 : "default",
|
|
9882
10222
|
options: __spreadValues({}, options)
|
|
9883
10223
|
};
|
|
9884
10224
|
}
|
|
@@ -9888,7 +10228,7 @@ var ConfigBuilder = class {
|
|
|
9888
10228
|
* Configure the LLM provider for chat
|
|
9889
10229
|
*/
|
|
9890
10230
|
llm(provider, model, apiKey, options) {
|
|
9891
|
-
var
|
|
10231
|
+
var _a3, _b;
|
|
9892
10232
|
if (provider === "auto") {
|
|
9893
10233
|
this._llm = this._autoDetectLLM();
|
|
9894
10234
|
} else {
|
|
@@ -9897,7 +10237,7 @@ var ConfigBuilder = class {
|
|
|
9897
10237
|
model: model != null ? model : "default-model",
|
|
9898
10238
|
apiKey,
|
|
9899
10239
|
systemPrompt: options == null ? void 0 : options.systemPrompt,
|
|
9900
|
-
maxTokens: (
|
|
10240
|
+
maxTokens: (_a3 = options == null ? void 0 : options.maxTokens) != null ? _a3 : 1024,
|
|
9901
10241
|
temperature: (_b = options == null ? void 0 : options.temperature) != null ? _b : 0.7,
|
|
9902
10242
|
baseUrl: options == null ? void 0 : options.baseUrl,
|
|
9903
10243
|
options
|
|
@@ -9940,8 +10280,8 @@ var ConfigBuilder = class {
|
|
|
9940
10280
|
* Set RAG-specific pipeline parameters
|
|
9941
10281
|
*/
|
|
9942
10282
|
rag(options) {
|
|
9943
|
-
var
|
|
9944
|
-
this._rag = __spreadValues(__spreadValues({}, (
|
|
10283
|
+
var _a3;
|
|
10284
|
+
this._rag = __spreadValues(__spreadValues({}, (_a3 = this._rag) != null ? _a3 : {}), options);
|
|
9945
10285
|
return this;
|
|
9946
10286
|
}
|
|
9947
10287
|
/**
|
|
@@ -9957,7 +10297,7 @@ var ConfigBuilder = class {
|
|
|
9957
10297
|
* Throws if required fields (projectId, vectorDb, llm, embedding) are not set.
|
|
9958
10298
|
*/
|
|
9959
10299
|
build() {
|
|
9960
|
-
var
|
|
10300
|
+
var _a3;
|
|
9961
10301
|
const missing = [];
|
|
9962
10302
|
if (!this._projectId) missing.push('projectId (call .projectId("my-app"))');
|
|
9963
10303
|
if (!this._vectorDb) missing.push('vectorDb (call .vectorDb("pinecone", { ... }))');
|
|
@@ -9969,7 +10309,7 @@ var ConfigBuilder = class {
|
|
|
9969
10309
|
${missing.join("\n ")}`
|
|
9970
10310
|
);
|
|
9971
10311
|
}
|
|
9972
|
-
const ragConfig = (
|
|
10312
|
+
const ragConfig = (_a3 = this._rag) != null ? _a3 : { chunkSize: 1e3, chunkOverlap: 200, topK: 5 };
|
|
9973
10313
|
if (process.env.RAG_USE_GRAPH_RETRIEVAL === "true") {
|
|
9974
10314
|
ragConfig.useGraphRetrieval = true;
|
|
9975
10315
|
}
|
|
@@ -10065,8 +10405,8 @@ var DocumentParser = class {
|
|
|
10065
10405
|
* Extract text from a File or Buffer based on its type.
|
|
10066
10406
|
*/
|
|
10067
10407
|
static async parse(file, fileName, mimeType) {
|
|
10068
|
-
var
|
|
10069
|
-
const extension = ((
|
|
10408
|
+
var _a3;
|
|
10409
|
+
const extension = ((_a3 = fileName.split(".").pop()) == null ? void 0 : _a3.toLowerCase()) || "";
|
|
10070
10410
|
if (extension === "txt" || extension === "md" || mimeType === "text/plain" || mimeType === "text/markdown") {
|
|
10071
10411
|
return this.readAsText(file);
|
|
10072
10412
|
}
|
|
@@ -10173,9 +10513,9 @@ var DatabaseStorage = class {
|
|
|
10173
10513
|
this.fallbackDir = this.isServerless ? path.join(os.tmpdir(), ".retrivora") : path.join(process.cwd(), ".retrivora");
|
|
10174
10514
|
this.historyFile = path.join(this.fallbackDir, "history.json");
|
|
10175
10515
|
this.feedbackFile = path.join(this.fallbackDir, "feedback.json");
|
|
10176
|
-
var
|
|
10516
|
+
var _a3, _b, _c, _d, _e;
|
|
10177
10517
|
this.config = config;
|
|
10178
|
-
this.provider = ((
|
|
10518
|
+
this.provider = ((_a3 = config.vectorDb) == null ? void 0 : _a3.provider) || "fs";
|
|
10179
10519
|
const rawHistoryTable = ((_c = (_b = config.rag) == null ? void 0 : _b.history) == null ? void 0 : _c.tableName) || "retrivora_history";
|
|
10180
10520
|
const rawFeedbackTable = ((_e = (_d = config.rag) == null ? void 0 : _d.feedback) == null ? void 0 : _e.tableName) || "retrivora_feedback";
|
|
10181
10521
|
this.historyTableName = rawHistoryTable.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
@@ -10210,16 +10550,16 @@ var DatabaseStorage = class {
|
|
|
10210
10550
|
}
|
|
10211
10551
|
}
|
|
10212
10552
|
checkHistoryEnabled() {
|
|
10213
|
-
var
|
|
10553
|
+
var _a3, _b;
|
|
10214
10554
|
this.checkPremiumSubscription();
|
|
10215
|
-
if (((_b = (
|
|
10555
|
+
if (((_b = (_a3 = this.config.rag) == null ? void 0 : _a3.history) == null ? void 0 : _b.enabled) === false) {
|
|
10216
10556
|
throw new Error("[Retrivora SDK] Chat History is disabled in RagConfig.");
|
|
10217
10557
|
}
|
|
10218
10558
|
}
|
|
10219
10559
|
checkFeedbackEnabled() {
|
|
10220
|
-
var
|
|
10560
|
+
var _a3, _b;
|
|
10221
10561
|
this.checkPremiumSubscription();
|
|
10222
|
-
if (((_b = (
|
|
10562
|
+
if (((_b = (_a3 = this.config.rag) == null ? void 0 : _a3.feedback) == null ? void 0 : _b.enabled) === false) {
|
|
10223
10563
|
throw new Error("[Retrivora SDK] User Feedback is disabled in RagConfig.");
|
|
10224
10564
|
}
|
|
10225
10565
|
}
|
|
@@ -10386,8 +10726,11 @@ var DatabaseStorage = class {
|
|
|
10386
10726
|
this.writeLocalFile(this.historyFile, history);
|
|
10387
10727
|
}
|
|
10388
10728
|
}
|
|
10389
|
-
async getHistory(sessionId) {
|
|
10729
|
+
async getHistory(sessionId, projectIds) {
|
|
10390
10730
|
this.checkHistoryEnabled();
|
|
10731
|
+
if (projectIds && projectIds.length > 0 && !this.sessionInScope(sessionId, projectIds)) {
|
|
10732
|
+
return [];
|
|
10733
|
+
}
|
|
10391
10734
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
10392
10735
|
const pool = await this.getPGPool();
|
|
10393
10736
|
const res = await pool.query(
|
|
@@ -10417,8 +10760,11 @@ var DatabaseStorage = class {
|
|
|
10417
10760
|
return history.filter((h) => h.session_id === sessionId).sort((a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime());
|
|
10418
10761
|
}
|
|
10419
10762
|
}
|
|
10420
|
-
async clearHistory(sessionId) {
|
|
10763
|
+
async clearHistory(sessionId, projectIds) {
|
|
10421
10764
|
this.checkHistoryEnabled();
|
|
10765
|
+
if (projectIds && projectIds.length > 0 && !this.sessionInScope(sessionId, projectIds)) {
|
|
10766
|
+
return;
|
|
10767
|
+
}
|
|
10422
10768
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
10423
10769
|
const pool = await this.getPGPool();
|
|
10424
10770
|
await pool.query(`DELETE FROM ${this.historyTableName} WHERE session_id = $1`, [sessionId]);
|
|
@@ -10437,21 +10783,36 @@ var DatabaseStorage = class {
|
|
|
10437
10783
|
this.writeLocalFile(this.feedbackFile, filteredFeedback);
|
|
10438
10784
|
}
|
|
10439
10785
|
}
|
|
10440
|
-
|
|
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) {
|
|
10441
10800
|
this.checkHistoryEnabled();
|
|
10801
|
+
let raw = [];
|
|
10442
10802
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
10443
10803
|
const pool = await this.getPGPool();
|
|
10444
10804
|
const res = await pool.query(`SELECT DISTINCT session_id FROM ${this.historyTableName}`);
|
|
10445
|
-
|
|
10805
|
+
raw = res.rows.map((r) => r.session_id);
|
|
10446
10806
|
} else if (this.provider === "mongodb") {
|
|
10447
10807
|
await this.getMongoClient();
|
|
10448
10808
|
const db = this.getMongoDb();
|
|
10449
|
-
|
|
10809
|
+
raw = await db.collection(this.historyTableName).distinct("session_id");
|
|
10450
10810
|
} else {
|
|
10451
10811
|
const history = this.readLocalFile(this.historyFile);
|
|
10452
|
-
|
|
10453
|
-
return Array.from(sessions);
|
|
10812
|
+
raw = Array.from(new Set(history.map((h) => h.session_id)));
|
|
10454
10813
|
}
|
|
10814
|
+
if (!projectIds || projectIds.length === 0) return raw;
|
|
10815
|
+
return raw.filter((sid) => this.sessionInScope(sid, projectIds));
|
|
10455
10816
|
}
|
|
10456
10817
|
// ─── Feedback Operations ──────────────────────────────────────────────────
|
|
10457
10818
|
async saveFeedback(feedback) {
|
|
@@ -10504,8 +10865,9 @@ var DatabaseStorage = class {
|
|
|
10504
10865
|
this.writeLocalFile(this.feedbackFile, list);
|
|
10505
10866
|
}
|
|
10506
10867
|
}
|
|
10507
|
-
async getFeedback(messageId) {
|
|
10868
|
+
async getFeedback(messageId, projectIds) {
|
|
10508
10869
|
this.checkFeedbackEnabled();
|
|
10870
|
+
let item = null;
|
|
10509
10871
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
10510
10872
|
const pool = await this.getPGPool();
|
|
10511
10873
|
const res = await pool.query(
|
|
@@ -10514,28 +10876,34 @@ var DatabaseStorage = class {
|
|
|
10514
10876
|
WHERE message_id = $1`,
|
|
10515
10877
|
[messageId]
|
|
10516
10878
|
);
|
|
10517
|
-
|
|
10879
|
+
item = res.rows[0] || null;
|
|
10518
10880
|
} else if (this.provider === "mongodb") {
|
|
10519
10881
|
await this.getMongoClient();
|
|
10520
10882
|
const db = this.getMongoDb();
|
|
10521
10883
|
const col = db.collection(this.feedbackTableName);
|
|
10522
|
-
const
|
|
10523
|
-
if (
|
|
10524
|
-
|
|
10525
|
-
|
|
10526
|
-
|
|
10527
|
-
|
|
10528
|
-
|
|
10529
|
-
|
|
10530
|
-
|
|
10531
|
-
|
|
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
|
+
}
|
|
10532
10895
|
} else {
|
|
10533
10896
|
const list = this.readLocalFile(this.feedbackFile);
|
|
10534
|
-
|
|
10897
|
+
item = list.find((f) => f.message_id === messageId) || null;
|
|
10535
10898
|
}
|
|
10899
|
+
if (item && projectIds && projectIds.length > 0) {
|
|
10900
|
+
return this.sessionInScope(item.sessionId, projectIds) ? item : null;
|
|
10901
|
+
}
|
|
10902
|
+
return item;
|
|
10536
10903
|
}
|
|
10537
|
-
async listFeedback() {
|
|
10904
|
+
async listFeedback(projectIds) {
|
|
10538
10905
|
this.checkFeedbackEnabled();
|
|
10906
|
+
let raw = [];
|
|
10539
10907
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
10540
10908
|
const pool = await this.getPGPool();
|
|
10541
10909
|
const res = await pool.query(
|
|
@@ -10543,13 +10911,13 @@ var DatabaseStorage = class {
|
|
|
10543
10911
|
FROM ${this.feedbackTableName}
|
|
10544
10912
|
ORDER BY created_at DESC`
|
|
10545
10913
|
);
|
|
10546
|
-
|
|
10914
|
+
raw = res.rows;
|
|
10547
10915
|
} else if (this.provider === "mongodb") {
|
|
10548
10916
|
await this.getMongoClient();
|
|
10549
10917
|
const db = this.getMongoDb();
|
|
10550
10918
|
const col = db.collection(this.feedbackTableName);
|
|
10551
10919
|
const items = await col.find({}).sort({ created_at: -1 }).toArray();
|
|
10552
|
-
|
|
10920
|
+
raw = items.map((item) => ({
|
|
10553
10921
|
id: item.id,
|
|
10554
10922
|
messageId: item.message_id,
|
|
10555
10923
|
sessionId: item.session_id,
|
|
@@ -10559,8 +10927,10 @@ var DatabaseStorage = class {
|
|
|
10559
10927
|
}));
|
|
10560
10928
|
} else {
|
|
10561
10929
|
const list = this.readLocalFile(this.feedbackFile);
|
|
10562
|
-
|
|
10930
|
+
raw = [...list].sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime());
|
|
10563
10931
|
}
|
|
10932
|
+
if (!projectIds || projectIds.length === 0) return raw;
|
|
10933
|
+
return raw.filter((f) => this.sessionInScope(f.sessionId, projectIds));
|
|
10564
10934
|
}
|
|
10565
10935
|
async disconnect() {
|
|
10566
10936
|
if (this.pgPool) {
|
|
@@ -10623,8 +10993,8 @@ var _g = global;
|
|
|
10623
10993
|
var _a;
|
|
10624
10994
|
var rateLimiter = (_a = _g.__retrivoraRateLimiter) != null ? _a : _g.__retrivoraRateLimiter = new RateLimiter(6e4, 30);
|
|
10625
10995
|
function getRateLimitKey(req) {
|
|
10626
|
-
var
|
|
10627
|
-
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";
|
|
10628
10998
|
return `ip:${ip}`;
|
|
10629
10999
|
}
|
|
10630
11000
|
function checkRateLimit(req) {
|
|
@@ -10646,6 +11016,66 @@ function checkRateLimit(req) {
|
|
|
10646
11016
|
}
|
|
10647
11017
|
return null;
|
|
10648
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
|
+
}
|
|
10649
11079
|
var MAX_MESSAGE_LENGTH = 8e3;
|
|
10650
11080
|
function sanitizeInput(raw) {
|
|
10651
11081
|
const stripped = raw.replace(/[\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F-\u009F]/g, "");
|
|
@@ -10667,7 +11097,7 @@ function getOrCreatePlugin(configOrPlugin) {
|
|
|
10667
11097
|
return _g[cacheKey];
|
|
10668
11098
|
}
|
|
10669
11099
|
function reportTelemetry(req, plugin, action, status, details, trace) {
|
|
10670
|
-
var
|
|
11100
|
+
var _a3, _b, _c, _d, _e, _f, _g2;
|
|
10671
11101
|
try {
|
|
10672
11102
|
const config = plugin.getConfig();
|
|
10673
11103
|
const licenseKey = config.licenseKey || process.env.RAG_LICENSE_KEY || process.env.RETRIVORA_LICENSE_KEY || process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY;
|
|
@@ -10682,7 +11112,7 @@ function reportTelemetry(req, plugin, action, status, details, trace) {
|
|
|
10682
11112
|
absoluteUrl = `${proto}://${host}${telemetryUrl}`;
|
|
10683
11113
|
}
|
|
10684
11114
|
const projectId = config.projectId || "default";
|
|
10685
|
-
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";
|
|
10686
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";
|
|
10687
11117
|
const tokens = Number(((_e = trace == null ? void 0 : trace.tokens) == null ? void 0 : _e.totalTokens) || (trace == null ? void 0 : trace.totalTokens) || 0);
|
|
10688
11118
|
const costUsd = Number(((_f = trace == null ? void 0 : trace.tokens) == null ? void 0 : _f.estimatedCostUsd) || (trace == null ? void 0 : trace.costUsd) || 0);
|
|
@@ -10706,7 +11136,6 @@ function reportTelemetry(req, plugin, action, status, details, trace) {
|
|
|
10706
11136
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
10707
11137
|
details
|
|
10708
11138
|
};
|
|
10709
|
-
console.log(`[Retrivora SDK Telemetry] Dispatching telemetry -> Feature: "${action}", Status: "${status}", Project: "${projectId}", Latency: ${latencyMs}ms`);
|
|
10710
11139
|
fetch(absoluteUrl, {
|
|
10711
11140
|
method: "POST",
|
|
10712
11141
|
headers: {
|
|
@@ -10764,14 +11193,39 @@ function createChatHandler(configOrPlugin, options) {
|
|
|
10764
11193
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
10765
11194
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
10766
11195
|
return async function POST(req, context) {
|
|
10767
|
-
var
|
|
11196
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
10768
11197
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10769
11198
|
if (authResult) return authResult;
|
|
10770
11199
|
const rateLimited = checkRateLimit(req);
|
|
10771
11200
|
if (rateLimited) return rateLimited;
|
|
11201
|
+
const config = plugin.getConfig();
|
|
10772
11202
|
try {
|
|
10773
11203
|
const body = await req.json();
|
|
10774
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
|
+
}
|
|
10775
11229
|
let rawMessage = bodyObj.message;
|
|
10776
11230
|
if (!rawMessage && Array.isArray(bodyObj.messages) && bodyObj.messages.length > 0) {
|
|
10777
11231
|
const lastMsg = bodyObj.messages[bodyObj.messages.length - 1];
|
|
@@ -10803,7 +11257,7 @@ function createChatHandler(configOrPlugin, options) {
|
|
|
10803
11257
|
uiTransformation: result.ui_transformation,
|
|
10804
11258
|
trace: result.trace
|
|
10805
11259
|
}).catch((err) => console.warn("[createChatHandler] Failed to save assistant message:", err));
|
|
10806
|
-
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);
|
|
10807
11261
|
return import_server.NextResponse.json(__spreadProps(__spreadValues({}, result), {
|
|
10808
11262
|
messageId: assistantMsgId,
|
|
10809
11263
|
userMessageId: userMsgId
|
|
@@ -10820,14 +11274,15 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10820
11274
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
10821
11275
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
10822
11276
|
return async function POST(req, context) {
|
|
10823
|
-
var
|
|
11277
|
+
var _a3, _b, _c;
|
|
10824
11278
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10825
11279
|
if (authResult) return authResult;
|
|
10826
11280
|
const rateLimited = checkRateLimit(req);
|
|
10827
11281
|
if (rateLimited) return rateLimited;
|
|
11282
|
+
const config = plugin.getConfig();
|
|
10828
11283
|
let body;
|
|
10829
11284
|
try {
|
|
10830
|
-
if ((
|
|
11285
|
+
if ((_a3 = req.headers.get("content-type")) == null ? void 0 : _a3.includes("multipart/form-data")) {
|
|
10831
11286
|
const uploader = createUploadHandler(plugin, { onAuthorize });
|
|
10832
11287
|
return uploader(req);
|
|
10833
11288
|
}
|
|
@@ -10839,6 +11294,30 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10839
11294
|
});
|
|
10840
11295
|
}
|
|
10841
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
|
+
}
|
|
10842
11321
|
let rawMessage = bodyObj.message;
|
|
10843
11322
|
if (!rawMessage && Array.isArray(bodyObj.messages) && bodyObj.messages.length > 0) {
|
|
10844
11323
|
const lastMsg = bodyObj.messages[bodyObj.messages.length - 1];
|
|
@@ -10868,7 +11347,7 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10868
11347
|
let isActive = true;
|
|
10869
11348
|
const stream = new ReadableStream({
|
|
10870
11349
|
async start(controller) {
|
|
10871
|
-
var
|
|
11350
|
+
var _a4, _b2, _c2, _d, _e;
|
|
10872
11351
|
const enqueue = (text) => {
|
|
10873
11352
|
if (!isActive) return;
|
|
10874
11353
|
try {
|
|
@@ -10901,7 +11380,7 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10901
11380
|
let uiTransformation = responseChunk == null ? void 0 : responseChunk.ui_transformation;
|
|
10902
11381
|
if (sources.length > 0) {
|
|
10903
11382
|
try {
|
|
10904
|
-
uiTransformation = (
|
|
11383
|
+
uiTransformation = (_a4 = responseChunk == null ? void 0 : responseChunk.ui_transformation) != null ? _a4 : UITransformer.transform(message, sources, plugin.getConfig());
|
|
10905
11384
|
if (uiTransformation) {
|
|
10906
11385
|
enqueue(sseUIFrame(uiTransformation));
|
|
10907
11386
|
}
|
|
@@ -10925,7 +11404,7 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10925
11404
|
uiTransformation,
|
|
10926
11405
|
trace: responseChunk == null ? void 0 : responseChunk.trace
|
|
10927
11406
|
}).catch((err) => console.warn("[createStreamHandler] Failed to save assistant message:", err));
|
|
10928
|
-
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);
|
|
10929
11408
|
}
|
|
10930
11409
|
}
|
|
10931
11410
|
} catch (temp) {
|
|
@@ -10975,12 +11454,36 @@ function createIngestHandler(configOrPlugin, options) {
|
|
|
10975
11454
|
return async function POST(req, context) {
|
|
10976
11455
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10977
11456
|
if (authResult) return authResult;
|
|
11457
|
+
const config = plugin.getConfig();
|
|
10978
11458
|
try {
|
|
10979
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;
|
|
10980
11462
|
const { documents, namespace } = body;
|
|
10981
11463
|
if (!Array.isArray(documents) || documents.length === 0) {
|
|
10982
11464
|
return import_server.NextResponse.json({ error: "documents array is required" }, { status: 400 });
|
|
10983
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
|
+
}
|
|
10984
11487
|
const results = await plugin.ingest(documents, namespace);
|
|
10985
11488
|
reportTelemetry(req, plugin, "DOCUMENT_INGESTION", "success", `Ingested ${documents.length} document(s)`);
|
|
10986
11489
|
return import_server.NextResponse.json({ results });
|
|
@@ -11017,7 +11520,7 @@ function createLicenseHandler(configOrPlugin, options) {
|
|
|
11017
11520
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
11018
11521
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
11019
11522
|
return async function POST(req) {
|
|
11020
|
-
var
|
|
11523
|
+
var _a3;
|
|
11021
11524
|
if (req) {
|
|
11022
11525
|
const authResult = await checkAuth(req, onAuthorize);
|
|
11023
11526
|
if (authResult) return authResult;
|
|
@@ -11025,7 +11528,7 @@ function createLicenseHandler(configOrPlugin, options) {
|
|
|
11025
11528
|
try {
|
|
11026
11529
|
const body = await req.json().catch(() => ({}));
|
|
11027
11530
|
const config = plugin.getConfig();
|
|
11028
|
-
const rawKey = req.headers.get("x-license-key") || (body == null ? void 0 : body.licenseKey) || ((
|
|
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 || "";
|
|
11029
11532
|
const licenseKey = (rawKey || "").trim().replace(/^["']|["']$/g, "").trim();
|
|
11030
11533
|
const projectId = (body == null ? void 0 : body.projectId) || config.projectId || "my-rag-app";
|
|
11031
11534
|
const payload = LicenseVerifier.verify(licenseKey, projectId);
|
|
@@ -11060,6 +11563,9 @@ function createUploadHandler(configOrPlugin, options) {
|
|
|
11060
11563
|
return async function POST(req, context) {
|
|
11061
11564
|
const authResult = await checkAuth(req, onAuthorize);
|
|
11062
11565
|
if (authResult) return authResult;
|
|
11566
|
+
const config = plugin.getConfig();
|
|
11567
|
+
const licenseCheck = enforceLicense(req, config);
|
|
11568
|
+
if (!licenseCheck.ok) return licenseCheck.response;
|
|
11063
11569
|
try {
|
|
11064
11570
|
const formData = await req.formData();
|
|
11065
11571
|
const files = formData.getAll("files");
|
|
@@ -11069,6 +11575,26 @@ function createUploadHandler(configOrPlugin, options) {
|
|
|
11069
11575
|
if (!files || files.length === 0) {
|
|
11070
11576
|
return import_server.NextResponse.json({ error: "No files provided" }, { status: 400 });
|
|
11071
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
|
+
}
|
|
11072
11598
|
const documents = [];
|
|
11073
11599
|
for (const file of files) {
|
|
11074
11600
|
const isExcel = file.name.toLowerCase().endsWith(".xlsx") || file.name.toLowerCase().endsWith(".xls") || file.type.includes("spreadsheet") || file.type.includes("excel");
|
|
@@ -11178,13 +11704,22 @@ function createSuggestionsHandler(configOrPlugin, options) {
|
|
|
11178
11704
|
return async function handler(req) {
|
|
11179
11705
|
const authResult = await checkAuth(req, onAuthorize);
|
|
11180
11706
|
if (authResult) return authResult;
|
|
11707
|
+
const config = plugin.getConfig();
|
|
11708
|
+
const licenseCheck = enforceLicense(req, config);
|
|
11709
|
+
if (!licenseCheck.ok) return licenseCheck.response;
|
|
11181
11710
|
try {
|
|
11182
11711
|
let query = "";
|
|
11183
11712
|
let namespace = void 0;
|
|
11713
|
+
let bodyLicenseKey = void 0;
|
|
11184
11714
|
if (req.method === "POST") {
|
|
11185
11715
|
const body = await req.json().catch(() => ({}));
|
|
11186
11716
|
query = body.query || "";
|
|
11187
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
|
+
}
|
|
11188
11723
|
} else {
|
|
11189
11724
|
const url = new URL(req.url);
|
|
11190
11725
|
query = url.searchParams.get("query") || "";
|
|
@@ -11207,14 +11742,16 @@ function createHistoryHandler(configOrPlugin, options) {
|
|
|
11207
11742
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
11208
11743
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
11209
11744
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
11745
|
+
const onResolveScope = options == null ? void 0 : options.onResolveScope;
|
|
11210
11746
|
return async function handler(req) {
|
|
11211
11747
|
const authResult = await checkAuth(req, onAuthorize);
|
|
11212
11748
|
if (authResult) return authResult;
|
|
11749
|
+
const scope = onResolveScope ? await onResolveScope(req) : void 0;
|
|
11213
11750
|
const url = new URL(req.url);
|
|
11214
11751
|
const sessionId = url.searchParams.get("sessionId") || "default";
|
|
11215
11752
|
if (req.method === "GET") {
|
|
11216
11753
|
try {
|
|
11217
|
-
const history = await storage.getHistory(sessionId);
|
|
11754
|
+
const history = await storage.getHistory(sessionId, scope);
|
|
11218
11755
|
return import_server.NextResponse.json({ history });
|
|
11219
11756
|
} catch (err) {
|
|
11220
11757
|
const message = err instanceof Error ? err.message : "Failed to fetch history";
|
|
@@ -11224,7 +11761,7 @@ function createHistoryHandler(configOrPlugin, options) {
|
|
|
11224
11761
|
try {
|
|
11225
11762
|
const body = await req.json().catch(() => ({}));
|
|
11226
11763
|
const sid = body.sessionId || sessionId;
|
|
11227
|
-
await storage.clearHistory(sid);
|
|
11764
|
+
await storage.clearHistory(sid, scope);
|
|
11228
11765
|
return import_server.NextResponse.json({ success: true });
|
|
11229
11766
|
} catch (err) {
|
|
11230
11767
|
const message = err instanceof Error ? err.message : "Failed to clear history";
|
|
@@ -11238,18 +11775,20 @@ function createFeedbackHandler(configOrPlugin, options) {
|
|
|
11238
11775
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
11239
11776
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
11240
11777
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
11778
|
+
const onResolveScope = options == null ? void 0 : options.onResolveScope;
|
|
11241
11779
|
return async function handler(req) {
|
|
11242
11780
|
const authResult = await checkAuth(req, onAuthorize);
|
|
11243
11781
|
if (authResult) return authResult;
|
|
11782
|
+
const scope = onResolveScope ? await onResolveScope(req) : void 0;
|
|
11244
11783
|
if (req.method === "GET") {
|
|
11245
11784
|
try {
|
|
11246
11785
|
const url = new URL(req.url);
|
|
11247
11786
|
const messageId = url.searchParams.get("messageId");
|
|
11248
11787
|
if (!messageId) {
|
|
11249
|
-
const feedbackList = await storage.listFeedback();
|
|
11788
|
+
const feedbackList = await storage.listFeedback(scope);
|
|
11250
11789
|
return import_server.NextResponse.json({ feedback: feedbackList });
|
|
11251
11790
|
}
|
|
11252
|
-
const feedback = await storage.getFeedback(messageId);
|
|
11791
|
+
const feedback = await storage.getFeedback(messageId, scope);
|
|
11253
11792
|
return import_server.NextResponse.json({ feedback });
|
|
11254
11793
|
} catch (err) {
|
|
11255
11794
|
const message = err instanceof Error ? err.message : "Failed to fetch feedback";
|
|
@@ -11265,6 +11804,17 @@ function createFeedbackHandler(configOrPlugin, options) {
|
|
|
11265
11804
|
if (!rating) {
|
|
11266
11805
|
return import_server.NextResponse.json({ error: "rating is required" }, { status: 400 });
|
|
11267
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
|
+
}
|
|
11268
11818
|
await storage.saveFeedback({ messageId, sessionId, rating, comment });
|
|
11269
11819
|
return import_server.NextResponse.json({ success: true });
|
|
11270
11820
|
} catch (err) {
|
|
@@ -11279,14 +11829,15 @@ function createSessionsHandler(configOrPlugin, options) {
|
|
|
11279
11829
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
11280
11830
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
11281
11831
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
11832
|
+
const onResolveScope = options == null ? void 0 : options.onResolveScope;
|
|
11282
11833
|
return async function GET(req) {
|
|
11283
11834
|
if (req) {
|
|
11284
11835
|
const authResult = await checkAuth(req, onAuthorize);
|
|
11285
11836
|
if (authResult) return authResult;
|
|
11286
11837
|
}
|
|
11287
|
-
void req;
|
|
11288
11838
|
try {
|
|
11289
|
-
const
|
|
11839
|
+
const scope = req && onResolveScope ? await onResolveScope(req) : void 0;
|
|
11840
|
+
const sessions = await storage.listSessions(scope);
|
|
11290
11841
|
return import_server.NextResponse.json({ sessions });
|
|
11291
11842
|
} catch (err) {
|
|
11292
11843
|
const message = err instanceof Error ? err.message : "Failed to list sessions";
|
|
@@ -11297,15 +11848,17 @@ function createSessionsHandler(configOrPlugin, options) {
|
|
|
11297
11848
|
function createRagHandler(configOrPlugin, options) {
|
|
11298
11849
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
11299
11850
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
11300
|
-
const
|
|
11301
|
-
const
|
|
11302
|
-
const
|
|
11303
|
-
const
|
|
11304
|
-
const
|
|
11305
|
-
const
|
|
11306
|
-
const
|
|
11307
|
-
const
|
|
11308
|
-
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);
|
|
11309
11862
|
async function routePostRequest(req, segment) {
|
|
11310
11863
|
switch (segment) {
|
|
11311
11864
|
case "chat":
|
|
@@ -11347,7 +11900,7 @@ function createRagHandler(configOrPlugin, options) {
|
|
|
11347
11900
|
}
|
|
11348
11901
|
}
|
|
11349
11902
|
async function getSegment(req, context) {
|
|
11350
|
-
var
|
|
11903
|
+
var _a3, _b;
|
|
11351
11904
|
const contentType = req.headers.get("content-type") || "";
|
|
11352
11905
|
if (contentType.includes("multipart/form-data")) {
|
|
11353
11906
|
return "upload";
|
|
@@ -11364,7 +11917,7 @@ function createRagHandler(configOrPlugin, options) {
|
|
|
11364
11917
|
if (pathname.endsWith("/history")) return "history";
|
|
11365
11918
|
} catch (e) {
|
|
11366
11919
|
}
|
|
11367
|
-
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;
|
|
11368
11921
|
const segments = (resolvedParams == null ? void 0 : resolvedParams.retrivora) || ((_b = resolvedParams == null ? void 0 : resolvedParams.params) == null ? void 0 : _b.retrivora) || [];
|
|
11369
11922
|
const joined = segments.join("/");
|
|
11370
11923
|
return joined || "chat";
|
|
@@ -11397,6 +11950,7 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
11397
11950
|
constructor() {
|
|
11398
11951
|
this.cache = /* @__PURE__ */ new Map();
|
|
11399
11952
|
}
|
|
11953
|
+
/** @returns Singleton instance of the validator (shared cache across all consumers). */
|
|
11400
11954
|
static getInstance() {
|
|
11401
11955
|
if (!_LicenseValidator.instance) {
|
|
11402
11956
|
_LicenseValidator.instance = new _LicenseValidator();
|
|
@@ -11404,7 +11958,12 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
11404
11958
|
return _LicenseValidator.instance;
|
|
11405
11959
|
}
|
|
11406
11960
|
/**
|
|
11407
|
-
*
|
|
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.
|
|
11408
11967
|
*/
|
|
11409
11968
|
purgeCache(licenseKey) {
|
|
11410
11969
|
if (licenseKey) {
|
|
@@ -11414,10 +11973,20 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
11414
11973
|
}
|
|
11415
11974
|
}
|
|
11416
11975
|
/**
|
|
11417
|
-
*
|
|
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.
|
|
11418
11987
|
*/
|
|
11419
11988
|
async validate(request) {
|
|
11420
|
-
var
|
|
11989
|
+
var _a3;
|
|
11421
11990
|
const {
|
|
11422
11991
|
licenseKey,
|
|
11423
11992
|
projectId,
|
|
@@ -11435,7 +12004,7 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
11435
12004
|
}
|
|
11436
12005
|
return void 0;
|
|
11437
12006
|
};
|
|
11438
|
-
const rawKey = licenseKey || getHeader("x-license-key") || ((
|
|
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 : "") || "";
|
|
11439
12008
|
const effectiveLicenseKey = (rawKey || "").trim().replace(/^["']|["']$/g, "").trim();
|
|
11440
12009
|
if (!effectiveLicenseKey) {
|
|
11441
12010
|
this.purgeCache(effectiveLicenseKey);
|