@retrivora-ai/rag-engine 2.2.9 → 2.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{LicenseValidator-CENvo9o2.d.mts → BatchProcessor-7yV-UCHW.d.mts} +142 -3
- package/dist/{LicenseValidator-CsjJp2PP.d.ts → BatchProcessor-BfzuU4cK.d.ts} +142 -3
- package/dist/handlers/index.d.mts +1 -1
- package/dist/handlers/index.d.ts +1 -1
- package/dist/handlers/index.js +883 -328
- package/dist/handlers/index.mjs +883 -328
- package/dist/index-DR_O_B-W.d.ts +394 -0
- package/dist/index-fnpaCuma.d.mts +394 -0
- package/dist/index.css +58 -0
- package/dist/index.d.mts +63 -3
- package/dist/index.d.ts +63 -3
- package/dist/index.js +456 -37
- package/dist/index.mjs +455 -39
- package/dist/server.d.mts +35 -73
- package/dist/server.d.ts +35 -73
- package/dist/server.js +914 -342
- package/dist/server.mjs +914 -342
- package/package.json +1 -1
- package/src/components/ChatWidget.tsx +147 -46
- package/src/components/ChatWindow.tsx +52 -8
- package/src/core/BatchProcessor.ts +42 -4
- package/src/core/CircuitBreaker.ts +118 -0
- package/src/core/DatabaseStorage.ts +55 -24
- package/src/core/FreeTierLimitsGuard.ts +281 -0
- package/src/core/LicenseValidator.ts +69 -3
- package/src/core/LicenseVerifier.ts +43 -14
- package/src/core/VectorPlugin.ts +30 -0
- package/src/handlers/index.ts +495 -38
- package/src/index.css +58 -0
- package/src/index.ts +4 -0
- package/src/server.ts +1 -0
- package/dist/index-BPJ3KDYI.d.ts +0 -195
- package/dist/index-Dmq5lH0j.d.mts +0 -195
package/dist/handlers/index.mjs
CHANGED
|
@@ -150,7 +150,7 @@ var init_ConfigFetcher = __esm({
|
|
|
150
150
|
* Fetch full project configuration (vectorDb + embedding + llm) from Retrivora Control Plane.
|
|
151
151
|
*/
|
|
152
152
|
static async fetchRemoteConfig(projectId, licenseKey) {
|
|
153
|
-
var
|
|
153
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
|
|
154
154
|
const cacheKey = `${projectId}:${licenseKey || ""}`;
|
|
155
155
|
const now = Date.now();
|
|
156
156
|
const cached = this.cache.get(cacheKey);
|
|
@@ -176,7 +176,7 @@ var init_ConfigFetcher = __esm({
|
|
|
176
176
|
});
|
|
177
177
|
if (res.ok) {
|
|
178
178
|
const data = await res.json();
|
|
179
|
-
if ((data == null ? void 0 : data.success) && ((
|
|
179
|
+
if ((data == null ? void 0 : data.success) && ((_a3 = data == null ? void 0 : data.vectorDb) == null ? void 0 : _a3.apiKey)) {
|
|
180
180
|
const fetchedProjectId = data.projectId || projectId;
|
|
181
181
|
const config = {
|
|
182
182
|
projectId: fetchedProjectId,
|
|
@@ -212,9 +212,9 @@ var init_ConfigFetcher = __esm({
|
|
|
212
212
|
}
|
|
213
213
|
/** Convenience: fetch only vector DB config (backwards compat). */
|
|
214
214
|
static async fetchRemoteVectorConfig(projectId, licenseKey) {
|
|
215
|
-
var
|
|
215
|
+
var _a3;
|
|
216
216
|
const config = await this.fetchRemoteConfig(projectId, licenseKey);
|
|
217
|
-
return (
|
|
217
|
+
return (_a3 = config == null ? void 0 : config.vectorDb) != null ? _a3 : null;
|
|
218
218
|
}
|
|
219
219
|
};
|
|
220
220
|
ConfigFetcher.cache = /* @__PURE__ */ new Map();
|
|
@@ -263,7 +263,7 @@ var init_PineconeProvider = __esm({
|
|
|
263
263
|
static getHealthChecker() {
|
|
264
264
|
return {
|
|
265
265
|
async check(config) {
|
|
266
|
-
var
|
|
266
|
+
var _a3, _b;
|
|
267
267
|
const opts = config.options || {};
|
|
268
268
|
const indexName = config.indexName;
|
|
269
269
|
const timestamp = Date.now();
|
|
@@ -271,7 +271,7 @@ var init_PineconeProvider = __esm({
|
|
|
271
271
|
const { Pinecone: Pinecone2 } = await import("@pinecone-database/pinecone");
|
|
272
272
|
const client = new Pinecone2({ apiKey: opts.apiKey });
|
|
273
273
|
const indexes = await client.listIndexes();
|
|
274
|
-
const indexNames = (_b = (
|
|
274
|
+
const indexNames = (_b = (_a3 = indexes.indexes) == null ? void 0 : _a3.map((i) => i.name)) != null ? _b : [];
|
|
275
275
|
if (!indexNames.includes(indexName)) {
|
|
276
276
|
return {
|
|
277
277
|
healthy: false,
|
|
@@ -298,7 +298,7 @@ var init_PineconeProvider = __esm({
|
|
|
298
298
|
};
|
|
299
299
|
}
|
|
300
300
|
async initialize() {
|
|
301
|
-
var
|
|
301
|
+
var _a3, _b;
|
|
302
302
|
if (this.client) return;
|
|
303
303
|
let key = this.apiKey || process.env.PINECONE_API_KEY || "";
|
|
304
304
|
if (!key) {
|
|
@@ -335,7 +335,7 @@ var init_PineconeProvider = __esm({
|
|
|
335
335
|
this.client = new Pinecone({ apiKey: key });
|
|
336
336
|
try {
|
|
337
337
|
const indexes = await this.client.listIndexes();
|
|
338
|
-
const names = (_b = (
|
|
338
|
+
const names = (_b = (_a3 = indexes.indexes) == null ? void 0 : _a3.map((i) => i.name)) != null ? _b : [];
|
|
339
339
|
if (!names.includes(this.indexName)) {
|
|
340
340
|
console.warn(`[PineconeProvider] Target index "${this.indexName}" not listed. Proceeding with configured index name.`);
|
|
341
341
|
}
|
|
@@ -354,13 +354,13 @@ var init_PineconeProvider = __esm({
|
|
|
354
354
|
return namespace ? idx.namespace(namespace) : idx.namespace("");
|
|
355
355
|
}
|
|
356
356
|
async upsert(doc, namespace) {
|
|
357
|
-
var
|
|
357
|
+
var _a3;
|
|
358
358
|
const targetIdx = await this.getActiveIndex(namespace);
|
|
359
359
|
await targetIdx.upsert({
|
|
360
360
|
records: [{
|
|
361
361
|
id: String(doc.id),
|
|
362
362
|
values: doc.vector,
|
|
363
|
-
metadata: __spreadValues({ content: doc.content }, (
|
|
363
|
+
metadata: __spreadValues({ content: doc.content }, (_a3 = doc.metadata) != null ? _a3 : {})
|
|
364
364
|
}]
|
|
365
365
|
});
|
|
366
366
|
}
|
|
@@ -369,18 +369,18 @@ var init_PineconeProvider = __esm({
|
|
|
369
369
|
const BATCH = 100;
|
|
370
370
|
for (let i = 0; i < docs.length; i += BATCH) {
|
|
371
371
|
const records = docs.slice(i, i + BATCH).map((d) => {
|
|
372
|
-
var
|
|
372
|
+
var _a3;
|
|
373
373
|
return {
|
|
374
374
|
id: String(d.id),
|
|
375
375
|
values: d.vector,
|
|
376
|
-
metadata: __spreadValues({ content: d.content }, (
|
|
376
|
+
metadata: __spreadValues({ content: d.content }, (_a3 = d.metadata) != null ? _a3 : {})
|
|
377
377
|
};
|
|
378
378
|
});
|
|
379
379
|
await targetIdx.upsert({ records });
|
|
380
380
|
}
|
|
381
381
|
}
|
|
382
382
|
async query(vector, topK, namespace, filter) {
|
|
383
|
-
var
|
|
383
|
+
var _a3;
|
|
384
384
|
const targetIdx = await this.getActiveIndex(namespace);
|
|
385
385
|
const pineconeFilter = this.sanitizeFilter(filter);
|
|
386
386
|
const result = await targetIdx.query(__spreadValues({
|
|
@@ -388,11 +388,11 @@ var init_PineconeProvider = __esm({
|
|
|
388
388
|
topK,
|
|
389
389
|
includeMetadata: true
|
|
390
390
|
}, Object.keys(pineconeFilter).length > 0 ? { filter: pineconeFilter } : {}));
|
|
391
|
-
return ((
|
|
392
|
-
var
|
|
391
|
+
return ((_a3 = result.matches) != null ? _a3 : []).map((m) => {
|
|
392
|
+
var _a4, _b;
|
|
393
393
|
return {
|
|
394
394
|
id: m.id,
|
|
395
|
-
score: (
|
|
395
|
+
score: (_a4 = m.score) != null ? _a4 : 0,
|
|
396
396
|
content: ((_b = m.metadata) == null ? void 0 : _b.content) || "",
|
|
397
397
|
metadata: m.metadata
|
|
398
398
|
};
|
|
@@ -435,13 +435,13 @@ var init_PostgreSQLProvider = __esm({
|
|
|
435
435
|
init_BaseVectorProvider();
|
|
436
436
|
PostgreSQLProvider = class extends BaseVectorProvider {
|
|
437
437
|
constructor(config) {
|
|
438
|
-
var
|
|
438
|
+
var _a3;
|
|
439
439
|
super(config);
|
|
440
440
|
this.tableName = this.indexName.replace(/[^a-z0-9_]/gi, "_");
|
|
441
441
|
const opts = config.options;
|
|
442
442
|
if (!opts.connectionString) throw new Error("[PostgreSQLProvider] options.connectionString is required");
|
|
443
443
|
this.connectionString = opts.connectionString;
|
|
444
|
-
this.dimensions = (
|
|
444
|
+
this.dimensions = (_a3 = opts.dimensions) != null ? _a3 : 1536;
|
|
445
445
|
}
|
|
446
446
|
static getValidator() {
|
|
447
447
|
return {
|
|
@@ -522,7 +522,7 @@ var init_PostgreSQLProvider = __esm({
|
|
|
522
522
|
}
|
|
523
523
|
}
|
|
524
524
|
async upsert(doc, namespace = "") {
|
|
525
|
-
var
|
|
525
|
+
var _a3;
|
|
526
526
|
const vectorLiteral = `[${doc.vector.join(",")}]`;
|
|
527
527
|
await this.pool.query(
|
|
528
528
|
`INSERT INTO ${this.tableName} (id, namespace, content, metadata, embedding)
|
|
@@ -532,7 +532,7 @@ var init_PostgreSQLProvider = __esm({
|
|
|
532
532
|
content = EXCLUDED.content,
|
|
533
533
|
metadata = EXCLUDED.metadata,
|
|
534
534
|
embedding = EXCLUDED.embedding`,
|
|
535
|
-
[doc.id, namespace, doc.content, JSON.stringify((
|
|
535
|
+
[doc.id, namespace, doc.content, JSON.stringify((_a3 = doc.metadata) != null ? _a3 : {}), vectorLiteral]
|
|
536
536
|
);
|
|
537
537
|
}
|
|
538
538
|
async batchUpsert(docs, namespace = "") {
|
|
@@ -545,9 +545,9 @@ var init_PostgreSQLProvider = __esm({
|
|
|
545
545
|
const batch = docs.slice(i, i + BATCH_SIZE);
|
|
546
546
|
const values = [];
|
|
547
547
|
const valuePlaceholders = batch.map((doc, idx) => {
|
|
548
|
-
var
|
|
548
|
+
var _a3;
|
|
549
549
|
const offset = idx * 5;
|
|
550
|
-
values.push(doc.id, namespace, doc.content, JSON.stringify((
|
|
550
|
+
values.push(doc.id, namespace, doc.content, JSON.stringify((_a3 = doc.metadata) != null ? _a3 : {}), `[${doc.vector.join(",")}]`);
|
|
551
551
|
return `($${offset + 1}, $${offset + 2}, $${offset + 3}, $${offset + 4}, $${offset + 5}::vector)`;
|
|
552
552
|
}).join(", ");
|
|
553
553
|
const query = `
|
|
@@ -630,8 +630,8 @@ var init_PostgreSQLProvider = __esm({
|
|
|
630
630
|
|
|
631
631
|
// src/utils/synonyms.ts
|
|
632
632
|
function resolveMetadataValue(meta, uiKey) {
|
|
633
|
-
var
|
|
634
|
-
const synonyms = (
|
|
633
|
+
var _a3;
|
|
634
|
+
const synonyms = (_a3 = FIELD_SYNONYMS[uiKey]) != null ? _a3 : [];
|
|
635
635
|
const keys = Object.keys(meta);
|
|
636
636
|
const systemKeys = ["namespace", "filename", "filesize", "filetype", "docid", "uploadedat", "dimension", "chunkindex"];
|
|
637
637
|
let match = keys.find((k) => k.toLowerCase() === uiKey.toLowerCase());
|
|
@@ -718,14 +718,14 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
718
718
|
init_synonyms();
|
|
719
719
|
MultiTablePostgresProvider = class extends BaseVectorProvider {
|
|
720
720
|
constructor(config) {
|
|
721
|
-
var
|
|
721
|
+
var _a3, _b, _c;
|
|
722
722
|
super(config);
|
|
723
723
|
const opts = config.options || {};
|
|
724
724
|
if (!opts.connectionString) {
|
|
725
725
|
throw new Error("[MultiTablePostgresProvider] options.connectionString is required");
|
|
726
726
|
}
|
|
727
727
|
this.connectionString = opts.connectionString;
|
|
728
|
-
this.dimensions = (
|
|
728
|
+
this.dimensions = (_a3 = opts.dimensions) != null ? _a3 : 768;
|
|
729
729
|
this.tables = [];
|
|
730
730
|
const rawSearchFields = (_c = (_b = opts.searchFields) != null ? _b : process.env.VECTOR_DB_SEARCH_FIELDS) != null ? _c : ["name", "product_name", "productname", "title"];
|
|
731
731
|
this.searchFields = typeof rawSearchFields === "string" ? rawSearchFields.split(",").map((f) => f.trim()).filter(Boolean) : rawSearchFields;
|
|
@@ -783,11 +783,11 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
783
783
|
* Batch upsert documents by dynamically provisioning tables and columns based on CSV headers.
|
|
784
784
|
*/
|
|
785
785
|
async batchUpsert(docs, namespace = "") {
|
|
786
|
-
var
|
|
786
|
+
var _a3;
|
|
787
787
|
if (docs.length === 0) return;
|
|
788
788
|
const docsByFile = {};
|
|
789
789
|
for (const doc of docs) {
|
|
790
|
-
const fileName = ((
|
|
790
|
+
const fileName = ((_a3 = doc.metadata) == null ? void 0 : _a3.fileName) || this.uploadTable;
|
|
791
791
|
if (!docsByFile[fileName]) docsByFile[fileName] = [];
|
|
792
792
|
docsByFile[fileName].push(doc);
|
|
793
793
|
}
|
|
@@ -840,11 +840,11 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
840
840
|
const headerColumns = csvHeaders.map((h) => `"${h}"`).join(", ");
|
|
841
841
|
const allColumns = `id, ${headerColumns ? headerColumns + ", " : ""}namespace, content, metadata, embedding`;
|
|
842
842
|
const valuePlaceholders = batch.map((doc, idx) => {
|
|
843
|
-
var
|
|
843
|
+
var _a4, _b;
|
|
844
844
|
const offset = idx * (5 + csvHeaders.length);
|
|
845
845
|
values.push(doc.id);
|
|
846
846
|
for (const h of csvHeaders) {
|
|
847
|
-
values.push(String(((
|
|
847
|
+
values.push(String(((_a4 = doc.metadata) == null ? void 0 : _a4[h]) || ""));
|
|
848
848
|
}
|
|
849
849
|
values.push(namespace, doc.content, JSON.stringify((_b = doc.metadata) != null ? _b : {}), `[${doc.vector.join(",")}]`);
|
|
850
850
|
const docPlaceholders = [];
|
|
@@ -883,7 +883,7 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
883
883
|
* Query all configured tables and merge results, sorted by cosine similarity score.
|
|
884
884
|
*/
|
|
885
885
|
async query(vector, topK, _namespace, _filter) {
|
|
886
|
-
var
|
|
886
|
+
var _a3;
|
|
887
887
|
if (!this.pool) {
|
|
888
888
|
throw new Error("[MultiTablePostgresProvider] Provider not initialized. Call initialize() first.");
|
|
889
889
|
}
|
|
@@ -914,11 +914,11 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
914
914
|
const filterParams = [];
|
|
915
915
|
if (metadataFilters && Object.keys(metadataFilters).length > 0) {
|
|
916
916
|
const conditions = Object.entries(metadataFilters).map(([key, val]) => {
|
|
917
|
-
var
|
|
917
|
+
var _a5;
|
|
918
918
|
filterParams.push(String(val));
|
|
919
919
|
const baseOffset = queryText && dynamicKeywordQuery ? 2 : 1;
|
|
920
920
|
const paramIdx = baseOffset + filterParams.length;
|
|
921
|
-
const synonyms = (
|
|
921
|
+
const synonyms = (_a5 = FIELD_SYNONYMS[key]) != null ? _a5 : [];
|
|
922
922
|
const keysToCheck = [key, ...synonyms];
|
|
923
923
|
const coalesceExprs = keysToCheck.flatMap((k) => [
|
|
924
924
|
`metadata->>'${k}'`,
|
|
@@ -987,7 +987,7 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
987
987
|
}
|
|
988
988
|
const tableResults = [];
|
|
989
989
|
for (const row of result.rows) {
|
|
990
|
-
const
|
|
990
|
+
const _a4 = row, { hybrid_score, id } = _a4, rest = __objRest(_a4, ["hybrid_score", "id"]);
|
|
991
991
|
delete rest.embedding;
|
|
992
992
|
delete rest.vector_score;
|
|
993
993
|
delete rest.keyword_score;
|
|
@@ -1016,10 +1016,10 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
1016
1016
|
}
|
|
1017
1017
|
allResults.sort((a, b) => b.score - a.score);
|
|
1018
1018
|
if (allResults.length === 0) return [];
|
|
1019
|
-
const bestMatchTable = (
|
|
1019
|
+
const bestMatchTable = (_a3 = allResults[0].metadata) == null ? void 0 : _a3.source_table;
|
|
1020
1020
|
const finalSorted = allResults.filter((res) => {
|
|
1021
|
-
var
|
|
1022
|
-
return ((
|
|
1021
|
+
var _a4;
|
|
1022
|
+
return ((_a4 = res.metadata) == null ? void 0 : _a4.source_table) === bestMatchTable;
|
|
1023
1023
|
});
|
|
1024
1024
|
console.log(`[MultiTablePostgresProvider] --- Search Complete ---`);
|
|
1025
1025
|
console.log(`[MultiTablePostgresProvider] Final top match from "${bestMatchTable}" with score ${finalSorted[0].score.toFixed(4)}`);
|
|
@@ -1424,14 +1424,14 @@ var init_QdrantProvider = __esm({
|
|
|
1424
1424
|
* Samples points from the collection to discover available payload fields.
|
|
1425
1425
|
*/
|
|
1426
1426
|
async discoverSchema() {
|
|
1427
|
-
var
|
|
1427
|
+
var _a3;
|
|
1428
1428
|
try {
|
|
1429
1429
|
const { data } = await this.http.post(`/collections/${this.indexName}/points/scroll`, {
|
|
1430
1430
|
limit: 20,
|
|
1431
1431
|
with_payload: true,
|
|
1432
1432
|
with_vector: false
|
|
1433
1433
|
});
|
|
1434
|
-
const points = ((
|
|
1434
|
+
const points = ((_a3 = data.result) == null ? void 0 : _a3.points) || [];
|
|
1435
1435
|
const keys = /* @__PURE__ */ new Set();
|
|
1436
1436
|
for (const point of points) {
|
|
1437
1437
|
const payload = point.payload || {};
|
|
@@ -1457,12 +1457,12 @@ var init_QdrantProvider = __esm({
|
|
|
1457
1457
|
* Ensures the collection exists. Creates it if missing.
|
|
1458
1458
|
*/
|
|
1459
1459
|
async ensureCollection() {
|
|
1460
|
-
var
|
|
1460
|
+
var _a3;
|
|
1461
1461
|
try {
|
|
1462
1462
|
await this.http.get(`/collections/${this.indexName}`);
|
|
1463
1463
|
console.log(`[QdrantProvider] \u2705 Collection "${this.indexName}" already exists.`);
|
|
1464
1464
|
} catch (err) {
|
|
1465
|
-
if (axios4.isAxiosError(err) && ((
|
|
1465
|
+
if (axios4.isAxiosError(err) && ((_a3 = err.response) == null ? void 0 : _a3.status) === 404) {
|
|
1466
1466
|
const opts = this.config.options;
|
|
1467
1467
|
const dimensionsForCreate = opts.dimensions || 1536;
|
|
1468
1468
|
console.log(`[QdrantProvider] \u23F3 Creating collection "${this.indexName}" (dimensions: ${dimensionsForCreate})...`);
|
|
@@ -1482,7 +1482,7 @@ var init_QdrantProvider = __esm({
|
|
|
1482
1482
|
* Ensures that a payload field has an index.
|
|
1483
1483
|
*/
|
|
1484
1484
|
async ensureIndex(fieldName, schema = "keyword") {
|
|
1485
|
-
var
|
|
1485
|
+
var _a3;
|
|
1486
1486
|
let fullPath = fieldName;
|
|
1487
1487
|
if (!this.isFlatPayload && !fieldName.includes(".") && fieldName !== "namespace" && fieldName !== this.contentField) {
|
|
1488
1488
|
fullPath = `${this.metadataField}.${fieldName}`;
|
|
@@ -1495,7 +1495,7 @@ var init_QdrantProvider = __esm({
|
|
|
1495
1495
|
console.log(`[QdrantProvider] \u2705 Ensured ${schema} index for "${fullPath}"`);
|
|
1496
1496
|
} catch (err) {
|
|
1497
1497
|
let status;
|
|
1498
|
-
if (axios4.isAxiosError(err)) status = (
|
|
1498
|
+
if (axios4.isAxiosError(err)) status = (_a3 = err.response) == null ? void 0 : _a3.status;
|
|
1499
1499
|
if (status === 409) return;
|
|
1500
1500
|
console.warn(`[QdrantProvider] \u26A0\uFE0F Could not ensure index for "${fullPath}":`, err instanceof Error ? err.message : String(err));
|
|
1501
1501
|
}
|
|
@@ -1524,7 +1524,7 @@ var init_QdrantProvider = __esm({
|
|
|
1524
1524
|
await this.http.put(`/collections/${this.indexName}/points`, payload);
|
|
1525
1525
|
}
|
|
1526
1526
|
async query(vector, topK, namespace, _filter) {
|
|
1527
|
-
var
|
|
1527
|
+
var _a3;
|
|
1528
1528
|
const must = [];
|
|
1529
1529
|
if (namespace) {
|
|
1530
1530
|
must.push({ key: "namespace", match: { value: namespace } });
|
|
@@ -1546,7 +1546,7 @@ var init_QdrantProvider = __esm({
|
|
|
1546
1546
|
limit: topK,
|
|
1547
1547
|
with_payload: true,
|
|
1548
1548
|
params: {
|
|
1549
|
-
hnsw_ef: ((
|
|
1549
|
+
hnsw_ef: ((_a3 = this.config.options) == null ? void 0 : _a3.efSearch) || Math.max(topK * 20, 128),
|
|
1550
1550
|
exact: false
|
|
1551
1551
|
},
|
|
1552
1552
|
filter: must.length > 0 ? { must } : void 0
|
|
@@ -1641,13 +1641,13 @@ var init_ChromaDBProvider = __esm({
|
|
|
1641
1641
|
* Get or create the ChromaDB collection.
|
|
1642
1642
|
*/
|
|
1643
1643
|
async initialize() {
|
|
1644
|
-
var
|
|
1644
|
+
var _a3;
|
|
1645
1645
|
try {
|
|
1646
1646
|
const { data } = await this.http.get(`/api/v1/collections/${this.indexName}`);
|
|
1647
1647
|
this.collectionId = data.id;
|
|
1648
1648
|
console.log(`[ChromaDBProvider] \u2705 Collection "${this.indexName}" found (id: ${this.collectionId})`);
|
|
1649
1649
|
} catch (err) {
|
|
1650
|
-
if (axios5.isAxiosError(err) && ((
|
|
1650
|
+
if (axios5.isAxiosError(err) && ((_a3 = err.response) == null ? void 0 : _a3.status) === 404) {
|
|
1651
1651
|
console.log(`[ChromaDBProvider] \u23F3 Collection "${this.indexName}" not found. Creating...`);
|
|
1652
1652
|
const { data } = await this.http.post("/api/v1/collections", {
|
|
1653
1653
|
name: this.indexName
|
|
@@ -1868,7 +1868,7 @@ var init_WeaviateProvider = __esm({
|
|
|
1868
1868
|
await this.http.post("/v1/batch/objects", payload);
|
|
1869
1869
|
}
|
|
1870
1870
|
async query(vector, topK, namespace, _filter) {
|
|
1871
|
-
var
|
|
1871
|
+
var _a3, _b;
|
|
1872
1872
|
const queryText = _filter == null ? void 0 : _filter.queryText;
|
|
1873
1873
|
const sanitizedFilter = this.sanitizeFilter(_filter);
|
|
1874
1874
|
const searchParams = queryText ? `hybrid: { query: ${JSON.stringify(queryText)}, alpha: 0.5 }` : `nearVector: { vector: ${JSON.stringify(vector)} }`;
|
|
@@ -1894,7 +1894,7 @@ var init_WeaviateProvider = __esm({
|
|
|
1894
1894
|
`
|
|
1895
1895
|
};
|
|
1896
1896
|
const { data } = await this.http.post("/v1/graphql", graphqlQuery);
|
|
1897
|
-
const results = ((_b = (
|
|
1897
|
+
const results = ((_b = (_a3 = data.data) == null ? void 0 : _a3.Get) == null ? void 0 : _b[this.indexName]) || [];
|
|
1898
1898
|
return results.map((res) => ({
|
|
1899
1899
|
id: res["_additional"].id,
|
|
1900
1900
|
score: 1 - res["_additional"].distance,
|
|
@@ -1977,21 +1977,21 @@ var init_UniversalVectorProvider = __esm({
|
|
|
1977
1977
|
}
|
|
1978
1978
|
}
|
|
1979
1979
|
async initialize() {
|
|
1980
|
-
var
|
|
1980
|
+
var _a3;
|
|
1981
1981
|
this.http = axios8.create({
|
|
1982
1982
|
baseURL: this.opts.baseUrl,
|
|
1983
1983
|
headers: __spreadValues({
|
|
1984
1984
|
"Content-Type": "application/json"
|
|
1985
1985
|
}, this.opts.headers),
|
|
1986
|
-
timeout: (
|
|
1986
|
+
timeout: (_a3 = this.opts.timeout) != null ? _a3 : 3e4
|
|
1987
1987
|
});
|
|
1988
1988
|
if (!await this.ping()) {
|
|
1989
1989
|
throw new Error(`[UniversalVectorProvider] Failed to connect to ${this.opts.baseUrl}`);
|
|
1990
1990
|
}
|
|
1991
1991
|
}
|
|
1992
1992
|
async upsert(doc, namespace) {
|
|
1993
|
-
var
|
|
1994
|
-
const endpoint = (
|
|
1993
|
+
var _a3, _b, _c;
|
|
1994
|
+
const endpoint = (_a3 = this.opts.upsertEndpoint) != null ? _a3 : "/upsert";
|
|
1995
1995
|
const template = (_b = this.opts.upsertTemplate) != null ? _b : JSON.stringify({
|
|
1996
1996
|
id: "{{id}}",
|
|
1997
1997
|
vector: "{{vector}}",
|
|
@@ -2024,8 +2024,8 @@ var init_UniversalVectorProvider = __esm({
|
|
|
2024
2024
|
}
|
|
2025
2025
|
}
|
|
2026
2026
|
async query(vector, topK, namespace, filter) {
|
|
2027
|
-
var
|
|
2028
|
-
const endpoint = (
|
|
2027
|
+
var _a3, _b;
|
|
2028
|
+
const endpoint = (_a3 = this.opts.queryEndpoint) != null ? _a3 : "/query";
|
|
2029
2029
|
const template = (_b = this.opts.queryTemplate) != null ? _b : JSON.stringify({
|
|
2030
2030
|
vector: "{{vector}}",
|
|
2031
2031
|
limit: "{{topK}}",
|
|
@@ -2051,9 +2051,9 @@ var init_UniversalVectorProvider = __esm({
|
|
|
2051
2051
|
);
|
|
2052
2052
|
}
|
|
2053
2053
|
return results.map((item) => {
|
|
2054
|
-
var
|
|
2054
|
+
var _a4, _b2, _c, _d, _e, _f, _g2;
|
|
2055
2055
|
return {
|
|
2056
|
-
id: item[(
|
|
2056
|
+
id: item[(_a4 = this.opts.queryIdField) != null ? _a4 : "id"],
|
|
2057
2057
|
score: (_c = item[(_b2 = this.opts.queryScoreField) != null ? _b2 : "score"]) != null ? _c : 0,
|
|
2058
2058
|
content: (_e = item[(_d = this.opts.queryContentField) != null ? _d : "content"]) != null ? _e : "",
|
|
2059
2059
|
metadata: (_g2 = item[(_f = this.opts.queryMetadataField) != null ? _f : "metadata"]) != null ? _g2 : {}
|
|
@@ -2066,8 +2066,8 @@ var init_UniversalVectorProvider = __esm({
|
|
|
2066
2066
|
}
|
|
2067
2067
|
}
|
|
2068
2068
|
async delete(id, namespace) {
|
|
2069
|
-
var
|
|
2070
|
-
const endpoint = (
|
|
2069
|
+
var _a3, _b;
|
|
2070
|
+
const endpoint = (_a3 = this.opts.deleteEndpoint) != null ? _a3 : "/delete";
|
|
2071
2071
|
const template = (_b = this.opts.deleteTemplate) != null ? _b : JSON.stringify({
|
|
2072
2072
|
id: "{{id}}",
|
|
2073
2073
|
namespace: "{{namespace}}"
|
|
@@ -2085,8 +2085,8 @@ var init_UniversalVectorProvider = __esm({
|
|
|
2085
2085
|
}
|
|
2086
2086
|
}
|
|
2087
2087
|
async deleteNamespace(namespace) {
|
|
2088
|
-
var
|
|
2089
|
-
const endpoint = (
|
|
2088
|
+
var _a3;
|
|
2089
|
+
const endpoint = (_a3 = this.opts.deleteNamespaceEndpoint) != null ? _a3 : "/delete-namespace";
|
|
2090
2090
|
try {
|
|
2091
2091
|
await this.http.post(endpoint, { namespace });
|
|
2092
2092
|
} catch (error) {
|
|
@@ -2096,9 +2096,9 @@ var init_UniversalVectorProvider = __esm({
|
|
|
2096
2096
|
}
|
|
2097
2097
|
}
|
|
2098
2098
|
async ping() {
|
|
2099
|
-
var
|
|
2099
|
+
var _a3;
|
|
2100
2100
|
try {
|
|
2101
|
-
const endpoint = (
|
|
2101
|
+
const endpoint = (_a3 = this.opts.pingEndpoint) != null ? _a3 : "/health";
|
|
2102
2102
|
const response = await this.http.get(endpoint, { timeout: 5e3 });
|
|
2103
2103
|
return response.status >= 200 && response.status < 300;
|
|
2104
2104
|
} catch (e) {
|
|
@@ -2235,13 +2235,13 @@ var AuthenticationException = class extends RetrivoraError {
|
|
|
2235
2235
|
}
|
|
2236
2236
|
};
|
|
2237
2237
|
function wrapError(err, defaultCode, defaultMessage) {
|
|
2238
|
-
var
|
|
2238
|
+
var _a3;
|
|
2239
2239
|
if (err instanceof RetrivoraError) {
|
|
2240
2240
|
return err;
|
|
2241
2241
|
}
|
|
2242
2242
|
const error = err;
|
|
2243
2243
|
const message = (error == null ? void 0 : error.message) || defaultMessage || String(err);
|
|
2244
|
-
const status = (error == null ? void 0 : error.status) || (error == null ? void 0 : error.statusCode) || ((
|
|
2244
|
+
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);
|
|
2245
2245
|
const code = error == null ? void 0 : error.code;
|
|
2246
2246
|
if (status === 429 || /rate[- ]?limit/i.test(message) || code === "RATE_LIMIT_EXCEEDED") {
|
|
2247
2247
|
return new RateLimitException(message, err);
|
|
@@ -2310,7 +2310,8 @@ var LicenseVerifier = class {
|
|
|
2310
2310
|
};
|
|
2311
2311
|
}
|
|
2312
2312
|
try {
|
|
2313
|
-
const
|
|
2313
|
+
const sanitizedKey = (licenseKey || "").trim().replace(/^["']|["']$/g, "").trim();
|
|
2314
|
+
const rawToken = sanitizedKey.replace(/^rtv_/i, "").trim();
|
|
2314
2315
|
const parts = rawToken.split(".");
|
|
2315
2316
|
if (parts.length !== 3) {
|
|
2316
2317
|
throw new Error("Malformed token structure (expected 3 parts).");
|
|
@@ -2522,8 +2523,8 @@ var UI_BORDER_RADIUS_OPTIONS = ["none", "sm", "md", "lg", "xl", "full"];
|
|
|
2522
2523
|
|
|
2523
2524
|
// src/config/serverConfig.ts
|
|
2524
2525
|
function readString(env, name) {
|
|
2525
|
-
var
|
|
2526
|
-
const value = (
|
|
2526
|
+
var _a3;
|
|
2527
|
+
const value = (_a3 = env[name]) == null ? void 0 : _a3.trim();
|
|
2527
2528
|
return value ? value : void 0;
|
|
2528
2529
|
}
|
|
2529
2530
|
function readNumber(env, name, fallback) {
|
|
@@ -2536,16 +2537,16 @@ function readNumber(env, name, fallback) {
|
|
|
2536
2537
|
return parsed;
|
|
2537
2538
|
}
|
|
2538
2539
|
function readEnum(env, name, fallback, allowed) {
|
|
2539
|
-
var
|
|
2540
|
-
const value = (
|
|
2540
|
+
var _a3;
|
|
2541
|
+
const value = (_a3 = readString(env, name)) != null ? _a3 : fallback;
|
|
2541
2542
|
if (allowed.includes(value)) {
|
|
2542
2543
|
return value;
|
|
2543
2544
|
}
|
|
2544
2545
|
throw new Error(`[getRagConfig] ${name} must be one of: ${allowed.join(", ")}`);
|
|
2545
2546
|
}
|
|
2546
2547
|
function getEnvConfig(env = process.env, base) {
|
|
2547
|
-
var
|
|
2548
|
-
const licenseKey = (_d = (_c = (_b = (
|
|
2548
|
+
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;
|
|
2549
|
+
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;
|
|
2549
2550
|
const jwtProjectId = (() => {
|
|
2550
2551
|
if (!licenseKey) return void 0;
|
|
2551
2552
|
try {
|
|
@@ -2626,7 +2627,7 @@ function getEnvConfig(env = process.env, base) {
|
|
|
2626
2627
|
rest: "default",
|
|
2627
2628
|
custom: "default"
|
|
2628
2629
|
};
|
|
2629
|
-
const
|
|
2630
|
+
const isFreeTier2 = (() => {
|
|
2630
2631
|
if (!licenseKey) return true;
|
|
2631
2632
|
try {
|
|
2632
2633
|
const payload = LicenseVerifier.verify(licenseKey, projectId);
|
|
@@ -2637,13 +2638,13 @@ function getEnvConfig(env = process.env, base) {
|
|
|
2637
2638
|
}
|
|
2638
2639
|
})();
|
|
2639
2640
|
const defaultGatewayUrl = (_ra = (_qa = readString(env, "LITELLM_BASE_URL")) != null ? _qa : readString(env, "LLM_BASE_URL")) != null ? _ra : "https://www.retrivora.com/api/v1";
|
|
2640
|
-
const defaultLlmProvider =
|
|
2641
|
+
const defaultLlmProvider = isFreeTier2 ? "universal_rest" : "universal_rest";
|
|
2641
2642
|
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;
|
|
2642
2643
|
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;
|
|
2643
|
-
const llmModel = (_Ca = (_Aa = readString(env, "LLM_MODEL")) != null ? _Aa : (_za = base == null ? void 0 : base.llm) == null ? void 0 : _za.model) != null ? _Ca :
|
|
2644
|
+
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";
|
|
2644
2645
|
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;
|
|
2645
2646
|
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";
|
|
2646
|
-
const defaultEmbeddingProvider =
|
|
2647
|
+
const defaultEmbeddingProvider = isFreeTier2 ? "universal_rest" : "universal_rest";
|
|
2647
2648
|
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;
|
|
2648
2649
|
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;
|
|
2649
2650
|
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";
|
|
@@ -2733,8 +2734,8 @@ function getEnvConfig(env = process.env, base) {
|
|
|
2733
2734
|
}
|
|
2734
2735
|
} : {}), {
|
|
2735
2736
|
mcpServers: (() => {
|
|
2736
|
-
var
|
|
2737
|
-
const raw = (
|
|
2737
|
+
var _a4;
|
|
2738
|
+
const raw = (_a4 = readString(env, "MCP_SERVERS")) != null ? _a4 : readString(env, "NEXT_PUBLIC_MCP_SERVERS");
|
|
2738
2739
|
if (!raw) return void 0;
|
|
2739
2740
|
try {
|
|
2740
2741
|
return JSON.parse(raw);
|
|
@@ -2779,10 +2780,10 @@ var ConfigResolver = class {
|
|
|
2779
2780
|
* fallback behavior.
|
|
2780
2781
|
*/
|
|
2781
2782
|
static resolveUniversal(hostConfig, env = process.env) {
|
|
2782
|
-
var
|
|
2783
|
+
var _a3;
|
|
2783
2784
|
if (!hostConfig) return this.resolve(void 0, env);
|
|
2784
2785
|
const normalized = __spreadProps(__spreadValues({}, hostConfig), {
|
|
2785
|
-
vectorDb: (
|
|
2786
|
+
vectorDb: (_a3 = hostConfig.vectorDb) != null ? _a3 : hostConfig.vectorDatabase,
|
|
2786
2787
|
rag: this.mergeRetrievalWorkflow(hostConfig.rag, hostConfig.retrieval, hostConfig.workflow)
|
|
2787
2788
|
});
|
|
2788
2789
|
return this.resolve(normalized, env);
|
|
@@ -2802,11 +2803,11 @@ var ConfigResolver = class {
|
|
|
2802
2803
|
}
|
|
2803
2804
|
}
|
|
2804
2805
|
static mergeRetrievalWorkflow(rag, retrieval, workflow) {
|
|
2805
|
-
var
|
|
2806
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
2806
2807
|
if (!rag && !retrieval && !workflow) return void 0;
|
|
2807
2808
|
const normalized = __spreadValues({}, rag != null ? rag : {});
|
|
2808
2809
|
if (retrieval) {
|
|
2809
|
-
normalized.topK = (
|
|
2810
|
+
normalized.topK = (_a3 = retrieval.topK) != null ? _a3 : normalized.topK;
|
|
2810
2811
|
normalized.scoreThreshold = (_b = retrieval.scoreThreshold) != null ? _b : normalized.scoreThreshold;
|
|
2811
2812
|
normalized.useReranking = (_c = retrieval.useReranking) != null ? _c : normalized.useReranking;
|
|
2812
2813
|
if (retrieval.strategy === "hybrid") normalized.architecture = (_d = normalized.architecture) != null ? _d : "hybrid";
|
|
@@ -2934,8 +2935,8 @@ var OpenAIProvider = class {
|
|
|
2934
2935
|
};
|
|
2935
2936
|
}
|
|
2936
2937
|
async chat(messages, context, options) {
|
|
2937
|
-
var
|
|
2938
|
-
const basePrompt = (_b = (
|
|
2938
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i;
|
|
2939
|
+
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.";
|
|
2939
2940
|
const systemMessage = {
|
|
2940
2941
|
role: "system",
|
|
2941
2942
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -2959,8 +2960,8 @@ var OpenAIProvider = class {
|
|
|
2959
2960
|
}
|
|
2960
2961
|
chatStream(messages, context, options) {
|
|
2961
2962
|
return __asyncGenerator(this, null, function* () {
|
|
2962
|
-
var
|
|
2963
|
-
const basePrompt = (_b = (
|
|
2963
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h;
|
|
2964
|
+
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.";
|
|
2964
2965
|
const systemMessage = {
|
|
2965
2966
|
role: "system",
|
|
2966
2967
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3007,8 +3008,8 @@ var OpenAIProvider = class {
|
|
|
3007
3008
|
return results[0];
|
|
3008
3009
|
}
|
|
3009
3010
|
async batchEmbed(texts, options) {
|
|
3010
|
-
var
|
|
3011
|
-
const model = (_c = (_b = options == null ? void 0 : options.model) != null ? _b : (
|
|
3011
|
+
var _a3, _b, _c, _d, _e;
|
|
3012
|
+
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";
|
|
3012
3013
|
const apiKey = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.apiKey) != null ? _e : this.llmConfig.apiKey;
|
|
3013
3014
|
const client = apiKey !== this.llmConfig.apiKey ? new OpenAI({ apiKey }) : this.client;
|
|
3014
3015
|
const response = await client.embeddings.create({ model, input: texts });
|
|
@@ -3085,8 +3086,8 @@ var AnthropicProvider = class {
|
|
|
3085
3086
|
};
|
|
3086
3087
|
}
|
|
3087
3088
|
async chat(messages, context, options) {
|
|
3088
|
-
var
|
|
3089
|
-
const basePrompt = (_b = (
|
|
3089
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
|
|
3090
|
+
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.";
|
|
3090
3091
|
const system = buildSystemContent(basePrompt, context);
|
|
3091
3092
|
const anthropicMessages = messages.map((m) => ({
|
|
3092
3093
|
role: m.role === "assistant" ? "assistant" : "user",
|
|
@@ -3124,8 +3125,8 @@ var AnthropicProvider = class {
|
|
|
3124
3125
|
}
|
|
3125
3126
|
chatStream(messages, context, options) {
|
|
3126
3127
|
return __asyncGenerator(this, null, function* () {
|
|
3127
|
-
var
|
|
3128
|
-
const basePrompt = (_b = (
|
|
3128
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
|
|
3129
|
+
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.";
|
|
3129
3130
|
const system = buildSystemContent(basePrompt, context);
|
|
3130
3131
|
const anthropicMessages = messages.map((m) => ({
|
|
3131
3132
|
role: m.role === "assistant" ? "assistant" : "user",
|
|
@@ -3209,8 +3210,8 @@ var AnthropicProvider = class {
|
|
|
3209
3210
|
import axios from "axios";
|
|
3210
3211
|
var OllamaProvider = class {
|
|
3211
3212
|
constructor(llmConfig, embeddingConfig) {
|
|
3212
|
-
var
|
|
3213
|
-
const rawBaseURL = ((
|
|
3213
|
+
var _a3, _b, _c;
|
|
3214
|
+
const rawBaseURL = ((_a3 = llmConfig.baseUrl) != null ? _a3 : "http://localhost:11434").replace(/\/+$/, "");
|
|
3214
3215
|
const baseURL = rawBaseURL.replace(/\/(?:api\/v1|v1|api)$/i, "");
|
|
3215
3216
|
const timeout = Number((_b = llmConfig.options) == null ? void 0 : _b.timeout) || 3e5;
|
|
3216
3217
|
const headers = ((_c = llmConfig.options) == null ? void 0 : _c.headers) || {};
|
|
@@ -3270,8 +3271,8 @@ var OllamaProvider = class {
|
|
|
3270
3271
|
};
|
|
3271
3272
|
}
|
|
3272
3273
|
async chat(messages, context, options) {
|
|
3273
|
-
var
|
|
3274
|
-
const basePrompt = (_b = (
|
|
3274
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
3275
|
+
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.";
|
|
3275
3276
|
const system = buildSystemContent(basePrompt, context);
|
|
3276
3277
|
const { data } = await this.http.post("/api/chat", {
|
|
3277
3278
|
model: this.llmConfig.model,
|
|
@@ -3289,8 +3290,8 @@ var OllamaProvider = class {
|
|
|
3289
3290
|
}
|
|
3290
3291
|
chatStream(messages, context, options) {
|
|
3291
3292
|
return __asyncGenerator(this, null, function* () {
|
|
3292
|
-
var
|
|
3293
|
-
const basePrompt = (_b = (
|
|
3293
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h;
|
|
3294
|
+
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.";
|
|
3294
3295
|
const system = buildSystemContent(basePrompt, context);
|
|
3295
3296
|
const response = yield new __await(this.http.post("/api/chat", {
|
|
3296
3297
|
model: this.llmConfig.model,
|
|
@@ -3348,8 +3349,8 @@ var OllamaProvider = class {
|
|
|
3348
3349
|
});
|
|
3349
3350
|
}
|
|
3350
3351
|
async embed(text, options) {
|
|
3351
|
-
var
|
|
3352
|
-
const model = (_c = (_b = options == null ? void 0 : options.model) != null ? _b : (
|
|
3352
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
|
|
3353
|
+
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";
|
|
3353
3354
|
const baseURL = (_f = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.baseUrl) != null ? _e : this.llmConfig.baseUrl) != null ? _f : "http://localhost:11434";
|
|
3354
3355
|
const client = baseURL !== ((_g2 = this.llmConfig.baseUrl) != null ? _g2 : "http://localhost:11434") ? axios.create({ baseURL, timeout: 6e4 }) : this.http;
|
|
3355
3356
|
let prompt = text;
|
|
@@ -3450,9 +3451,9 @@ var GeminiProvider = class {
|
|
|
3450
3451
|
static getHealthChecker() {
|
|
3451
3452
|
return {
|
|
3452
3453
|
async check(config) {
|
|
3453
|
-
var
|
|
3454
|
+
var _a3, _b;
|
|
3454
3455
|
const timestamp = Date.now();
|
|
3455
|
-
const apiKey = (_b = (
|
|
3456
|
+
const apiKey = (_b = (_a3 = config.apiKey) != null ? _a3 : process.env.GOOGLE_GENAI_API_KEY) != null ? _b : "";
|
|
3456
3457
|
const modelName = sanitizeModel(config.model);
|
|
3457
3458
|
try {
|
|
3458
3459
|
const { GoogleGenerativeAI: GoogleGenerativeAI2 } = await import("@google/generative-ai");
|
|
@@ -3482,16 +3483,16 @@ var GeminiProvider = class {
|
|
|
3482
3483
|
/** Resolve the embedding client — uses a separate client when the embedding
|
|
3483
3484
|
* API key differs from the LLM API key. */
|
|
3484
3485
|
get embeddingClient() {
|
|
3485
|
-
var
|
|
3486
|
-
if (((
|
|
3486
|
+
var _a3;
|
|
3487
|
+
if (((_a3 = this.embeddingConfig) == null ? void 0 : _a3.apiKey) && this.embeddingConfig.apiKey !== this.llmConfig.apiKey) {
|
|
3487
3488
|
return buildClient(this.embeddingConfig.apiKey);
|
|
3488
3489
|
}
|
|
3489
3490
|
return this.client;
|
|
3490
3491
|
}
|
|
3491
3492
|
/** Resolve the embedding model to use, in order of specificity. */
|
|
3492
3493
|
resolveEmbeddingModel(optionsModel) {
|
|
3493
|
-
var
|
|
3494
|
-
return sanitizeModel((_b = optionsModel != null ? optionsModel : (
|
|
3494
|
+
var _a3, _b;
|
|
3495
|
+
return sanitizeModel((_b = optionsModel != null ? optionsModel : (_a3 = this.embeddingConfig) == null ? void 0 : _a3.model) != null ? _b : DEFAULT_EMBEDDING_MODEL);
|
|
3495
3496
|
}
|
|
3496
3497
|
/**
|
|
3497
3498
|
* Convert ChatMessage[] to the Gemini contents format.
|
|
@@ -3511,8 +3512,8 @@ var GeminiProvider = class {
|
|
|
3511
3512
|
// ILLMProvider — chat
|
|
3512
3513
|
// -------------------------------------------------------------------------
|
|
3513
3514
|
async chat(messages, context, options) {
|
|
3514
|
-
var
|
|
3515
|
-
const basePrompt = (_b = (
|
|
3515
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
3516
|
+
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.";
|
|
3516
3517
|
const model = this.client.getGenerativeModel({
|
|
3517
3518
|
model: this.llmConfig.model,
|
|
3518
3519
|
systemInstruction: buildSystemContent(basePrompt, context)
|
|
@@ -3529,8 +3530,8 @@ var GeminiProvider = class {
|
|
|
3529
3530
|
}
|
|
3530
3531
|
chatStream(messages, context, options) {
|
|
3531
3532
|
return __asyncGenerator(this, null, function* () {
|
|
3532
|
-
var
|
|
3533
|
-
const basePrompt = (_b = (
|
|
3533
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
3534
|
+
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.";
|
|
3534
3535
|
const model = this.client.getGenerativeModel({
|
|
3535
3536
|
model: this.llmConfig.model,
|
|
3536
3537
|
systemInstruction: buildSystemContent(basePrompt, context)
|
|
@@ -3565,11 +3566,11 @@ var GeminiProvider = class {
|
|
|
3565
3566
|
// ILLMProvider — embeddings
|
|
3566
3567
|
// -------------------------------------------------------------------------
|
|
3567
3568
|
async embed(text, options) {
|
|
3568
|
-
var
|
|
3569
|
+
var _a3, _b;
|
|
3569
3570
|
const content = applyPrefix(
|
|
3570
3571
|
text,
|
|
3571
3572
|
options == null ? void 0 : options.taskType,
|
|
3572
|
-
(
|
|
3573
|
+
(_a3 = this.embeddingConfig) == null ? void 0 : _a3.queryPrefix,
|
|
3573
3574
|
(_b = this.embeddingConfig) == null ? void 0 : _b.documentPrefix
|
|
3574
3575
|
);
|
|
3575
3576
|
const modelName = this.resolveEmbeddingModel(options == null ? void 0 : options.model);
|
|
@@ -3586,7 +3587,7 @@ var GeminiProvider = class {
|
|
|
3586
3587
|
const modelName = this.resolveEmbeddingModel(options == null ? void 0 : options.model);
|
|
3587
3588
|
const model = this.embeddingClient.getGenerativeModel({ model: modelName });
|
|
3588
3589
|
const requests = texts.map((text) => {
|
|
3589
|
-
var
|
|
3590
|
+
var _a3, _b;
|
|
3590
3591
|
return {
|
|
3591
3592
|
content: {
|
|
3592
3593
|
role: "user",
|
|
@@ -3594,7 +3595,7 @@ var GeminiProvider = class {
|
|
|
3594
3595
|
text: applyPrefix(
|
|
3595
3596
|
text,
|
|
3596
3597
|
options == null ? void 0 : options.taskType,
|
|
3597
|
-
(
|
|
3598
|
+
(_a3 = this.embeddingConfig) == null ? void 0 : _a3.queryPrefix,
|
|
3598
3599
|
(_b = this.embeddingConfig) == null ? void 0 : _b.documentPrefix
|
|
3599
3600
|
)
|
|
3600
3601
|
}]
|
|
@@ -3611,8 +3612,8 @@ var GeminiProvider = class {
|
|
|
3611
3612
|
throw err;
|
|
3612
3613
|
});
|
|
3613
3614
|
return response.embeddings.map((e) => {
|
|
3614
|
-
var
|
|
3615
|
-
return (
|
|
3615
|
+
var _a3;
|
|
3616
|
+
return (_a3 = e.values) != null ? _a3 : [];
|
|
3616
3617
|
});
|
|
3617
3618
|
}
|
|
3618
3619
|
// -------------------------------------------------------------------------
|
|
@@ -3701,8 +3702,8 @@ var GroqProvider = class {
|
|
|
3701
3702
|
};
|
|
3702
3703
|
}
|
|
3703
3704
|
async chat(messages, context, options) {
|
|
3704
|
-
var
|
|
3705
|
-
const basePrompt = (_b = (
|
|
3705
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i;
|
|
3706
|
+
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.";
|
|
3706
3707
|
const systemMessage = {
|
|
3707
3708
|
role: "system",
|
|
3708
3709
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3726,8 +3727,8 @@ var GroqProvider = class {
|
|
|
3726
3727
|
}
|
|
3727
3728
|
chatStream(messages, context, options) {
|
|
3728
3729
|
return __asyncGenerator(this, null, function* () {
|
|
3729
|
-
var
|
|
3730
|
-
const basePrompt = (_b = (
|
|
3730
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h;
|
|
3731
|
+
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.";
|
|
3731
3732
|
const systemMessage = {
|
|
3732
3733
|
role: "system",
|
|
3733
3734
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3861,8 +3862,8 @@ var QwenProvider = class {
|
|
|
3861
3862
|
};
|
|
3862
3863
|
}
|
|
3863
3864
|
async chat(messages, context, options) {
|
|
3864
|
-
var
|
|
3865
|
-
const basePrompt = (_b = (
|
|
3865
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i;
|
|
3866
|
+
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.";
|
|
3866
3867
|
const systemMessage = {
|
|
3867
3868
|
role: "system",
|
|
3868
3869
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3886,8 +3887,8 @@ var QwenProvider = class {
|
|
|
3886
3887
|
}
|
|
3887
3888
|
chatStream(messages, context, options) {
|
|
3888
3889
|
return __asyncGenerator(this, null, function* () {
|
|
3889
|
-
var
|
|
3890
|
-
const basePrompt = (_b = (
|
|
3890
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h;
|
|
3891
|
+
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.";
|
|
3891
3892
|
const systemMessage = {
|
|
3892
3893
|
role: "system",
|
|
3893
3894
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3934,8 +3935,8 @@ var QwenProvider = class {
|
|
|
3934
3935
|
return results[0];
|
|
3935
3936
|
}
|
|
3936
3937
|
async batchEmbed(texts, options) {
|
|
3937
|
-
var
|
|
3938
|
-
const model = (_c = (_b = options == null ? void 0 : options.model) != null ? _b : (
|
|
3938
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
3939
|
+
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";
|
|
3939
3940
|
const apiKey = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.apiKey) != null ? _e : this.llmConfig.apiKey;
|
|
3940
3941
|
const client = apiKey !== this.llmConfig.apiKey ? new OpenAI3({
|
|
3941
3942
|
apiKey,
|
|
@@ -3996,9 +3997,9 @@ var LLM_PROFILES = {
|
|
|
3996
3997
|
|
|
3997
3998
|
// src/llm/providers/UniversalLLMAdapter.ts
|
|
3998
3999
|
function extractContent(obj) {
|
|
3999
|
-
var
|
|
4000
|
+
var _a3, _b, _c;
|
|
4000
4001
|
if (!obj || typeof obj !== "object") return void 0;
|
|
4001
|
-
const choice = (
|
|
4002
|
+
const choice = (_a3 = obj.choices) == null ? void 0 : _a3[0];
|
|
4002
4003
|
if (!choice) return void 0;
|
|
4003
4004
|
if (typeof ((_b = choice.message) == null ? void 0 : _b.content) === "string") return choice.message.content;
|
|
4004
4005
|
if (typeof ((_c = choice.delta) == null ? void 0 : _c.content) === "string") return choice.delta.content;
|
|
@@ -4008,10 +4009,10 @@ function extractContent(obj) {
|
|
|
4008
4009
|
}
|
|
4009
4010
|
var UniversalLLMAdapter = class {
|
|
4010
4011
|
constructor(config) {
|
|
4011
|
-
var
|
|
4012
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h;
|
|
4012
4013
|
this.model = config.model;
|
|
4013
4014
|
const llmConfig = config;
|
|
4014
|
-
const options = (
|
|
4015
|
+
const options = (_a3 = llmConfig.options) != null ? _a3 : {};
|
|
4015
4016
|
let profile = {};
|
|
4016
4017
|
if (typeof options.profile === "string") {
|
|
4017
4018
|
profile = LLM_PROFILES[options.profile] || {};
|
|
@@ -4037,8 +4038,8 @@ var UniversalLLMAdapter = class {
|
|
|
4037
4038
|
});
|
|
4038
4039
|
}
|
|
4039
4040
|
async chat(messages, context) {
|
|
4040
|
-
var
|
|
4041
|
-
const path2 = (
|
|
4041
|
+
var _a3, _b, _c, _d, _e;
|
|
4042
|
+
const path2 = (_a3 = this.opts.chatPath) != null ? _a3 : "/chat/completions";
|
|
4042
4043
|
const safeMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
|
|
4043
4044
|
role: m.role || "user",
|
|
4044
4045
|
content: typeof m.content === "string" ? m.content : m.content != null ? String(m.content) : ""
|
|
@@ -4104,8 +4105,8 @@ ${context != null ? context : "None"}` },
|
|
|
4104
4105
|
*/
|
|
4105
4106
|
chatStream(messages, context) {
|
|
4106
4107
|
return __asyncGenerator(this, null, function* () {
|
|
4107
|
-
var
|
|
4108
|
-
const path2 = (
|
|
4108
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
4109
|
+
const path2 = (_a3 = this.opts.chatPath) != null ? _a3 : "/chat/completions";
|
|
4109
4110
|
const url = `${this.baseUrl.replace(/\/$/, "")}${path2}`;
|
|
4110
4111
|
const extractPath = ((_b = this.opts.responseExtractPath) != null ? _b : "choices[0].message.content").replace("message.content", "delta.content");
|
|
4111
4112
|
const safeMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
|
|
@@ -4231,8 +4232,8 @@ ${context != null ? context : "None"}` },
|
|
|
4231
4232
|
});
|
|
4232
4233
|
}
|
|
4233
4234
|
async embed(text) {
|
|
4234
|
-
var
|
|
4235
|
-
const path2 = (
|
|
4235
|
+
var _a3, _b, _c, _d, _e;
|
|
4236
|
+
const path2 = (_a3 = this.opts.embedPath) != null ? _a3 : "/embeddings";
|
|
4236
4237
|
const payload = this.opts.embedPayloadTemplate ? buildPayload(this.opts.embedPayloadTemplate, { input: text, model: this.model }) : { input: text, model: this.model };
|
|
4237
4238
|
try {
|
|
4238
4239
|
const { data: data2 } = await this.http.post(path2, payload);
|
|
@@ -4321,7 +4322,7 @@ var LLMFactory = class _LLMFactory {
|
|
|
4321
4322
|
];
|
|
4322
4323
|
}
|
|
4323
4324
|
static create(llmConfig, embeddingConfig) {
|
|
4324
|
-
var
|
|
4325
|
+
var _a3, _b, _c;
|
|
4325
4326
|
switch (llmConfig.provider) {
|
|
4326
4327
|
case "openai":
|
|
4327
4328
|
return new OpenAIProvider(llmConfig, embeddingConfig);
|
|
@@ -4340,7 +4341,7 @@ var LLMFactory = class _LLMFactory {
|
|
|
4340
4341
|
case "custom":
|
|
4341
4342
|
return new UniversalLLMAdapter(llmConfig);
|
|
4342
4343
|
default: {
|
|
4343
|
-
const providerName = String((
|
|
4344
|
+
const providerName = String((_a3 = llmConfig.provider) != null ? _a3 : "").toLowerCase();
|
|
4344
4345
|
const customFactory = customProviders.get(providerName);
|
|
4345
4346
|
if (customFactory) {
|
|
4346
4347
|
return customFactory(llmConfig);
|
|
@@ -4442,7 +4443,7 @@ var ProviderRegistry = class {
|
|
|
4442
4443
|
return null;
|
|
4443
4444
|
}
|
|
4444
4445
|
static async loadVectorProviderClass(provider) {
|
|
4445
|
-
var
|
|
4446
|
+
var _a3;
|
|
4446
4447
|
if (this.vectorProviders[provider]) return this.vectorProviders[provider];
|
|
4447
4448
|
switch (provider) {
|
|
4448
4449
|
case "pinecone": {
|
|
@@ -4451,7 +4452,7 @@ var ProviderRegistry = class {
|
|
|
4451
4452
|
}
|
|
4452
4453
|
case "pgvector":
|
|
4453
4454
|
case "postgresql": {
|
|
4454
|
-
const postgresMode = ((
|
|
4455
|
+
const postgresMode = ((_a3 = process.env.POSTGRES_MODE) != null ? _a3 : "multi").toLowerCase();
|
|
4455
4456
|
if (postgresMode === "single") {
|
|
4456
4457
|
const { PostgreSQLProvider: PostgreSQLProvider2 } = await Promise.resolve().then(() => (init_PostgreSQLProvider(), PostgreSQLProvider_exports));
|
|
4457
4458
|
return PostgreSQLProvider2;
|
|
@@ -4674,7 +4675,7 @@ var ConfigValidator = class {
|
|
|
4674
4675
|
// package.json
|
|
4675
4676
|
var package_default = {
|
|
4676
4677
|
name: "@retrivora-ai/rag-engine",
|
|
4677
|
-
version: "2.
|
|
4678
|
+
version: "2.3.1",
|
|
4678
4679
|
description: "Retrivora AI is a plug-and-play AI engine for RAG chat experiences \u2014 generic vector DB + LLM provider, embeddable or standalone.",
|
|
4679
4680
|
author: "Abhinav Alkuchi",
|
|
4680
4681
|
license: "UNLICENSED",
|
|
@@ -4979,8 +4980,8 @@ var Reranker = class {
|
|
|
4979
4980
|
return matches.sort((a, b) => b.score - a.score).slice(0, limit);
|
|
4980
4981
|
}
|
|
4981
4982
|
const scoredMatches = matches.map((match) => {
|
|
4982
|
-
var
|
|
4983
|
-
const contentLower = ((
|
|
4983
|
+
var _a3;
|
|
4984
|
+
const contentLower = ((_a3 = match == null ? void 0 : match.content) != null ? _a3 : "").toLowerCase();
|
|
4984
4985
|
let keywordScore = 0;
|
|
4985
4986
|
keywords.forEach((keyword) => {
|
|
4986
4987
|
if (contentLower.includes(keyword)) {
|
|
@@ -5002,8 +5003,8 @@ var Reranker = class {
|
|
|
5002
5003
|
|
|
5003
5004
|
Documents:
|
|
5004
5005
|
${topN.map((m, i) => {
|
|
5005
|
-
var
|
|
5006
|
-
return `[${i}] ${((
|
|
5006
|
+
var _a3;
|
|
5007
|
+
return `[${i}] ${((_a3 = m == null ? void 0 : m.content) != null ? _a3 : "").replace(/\n/g, " ")}`;
|
|
5007
5008
|
}).join("\n")}` }],
|
|
5008
5009
|
"",
|
|
5009
5010
|
{
|
|
@@ -5047,11 +5048,11 @@ var LlamaIndexIngestor = class {
|
|
|
5047
5048
|
* than standard character-count splitting.
|
|
5048
5049
|
*/
|
|
5049
5050
|
async chunk(text, options = {}) {
|
|
5050
|
-
var
|
|
5051
|
+
var _a3, _b;
|
|
5051
5052
|
try {
|
|
5052
5053
|
const { Document, SentenceSplitter, MetadataMode } = await import(`${"llamaindex"}`);
|
|
5053
5054
|
const splitter = new SentenceSplitter({
|
|
5054
|
-
chunkSize: (
|
|
5055
|
+
chunkSize: (_a3 = options.chunkSize) != null ? _a3 : 1e3,
|
|
5055
5056
|
chunkOverlap: (_b = options.chunkOverlap) != null ? _b : 200
|
|
5056
5057
|
});
|
|
5057
5058
|
const doc = new Document({ text, metadata: options.metadata || {} });
|
|
@@ -5160,7 +5161,7 @@ ${error instanceof Error ? error.message : String(error)}`
|
|
|
5160
5161
|
* The agent returns `{ messages: [...] }` — the last message is the final answer.
|
|
5161
5162
|
*/
|
|
5162
5163
|
async run(input, chatHistory = []) {
|
|
5163
|
-
var
|
|
5164
|
+
var _a3, _b, _c;
|
|
5164
5165
|
if (!this.agent) {
|
|
5165
5166
|
throw new Error("[LangChainAgent] Agent not initialized. Call initialize() first.");
|
|
5166
5167
|
}
|
|
@@ -5171,7 +5172,7 @@ ${error instanceof Error ? error.message : String(error)}`
|
|
|
5171
5172
|
const response = await this.agent.invoke({
|
|
5172
5173
|
messages: [...historyMessages, new HumanMessage(input)]
|
|
5173
5174
|
});
|
|
5174
|
-
const lastMessage = (
|
|
5175
|
+
const lastMessage = (_a3 = response == null ? void 0 : response.messages) == null ? void 0 : _a3.at(-1);
|
|
5175
5176
|
if (lastMessage && typeof lastMessage.content === "string") {
|
|
5176
5177
|
return lastMessage.content;
|
|
5177
5178
|
}
|
|
@@ -5223,7 +5224,7 @@ var MCPClient = class {
|
|
|
5223
5224
|
}
|
|
5224
5225
|
}
|
|
5225
5226
|
async connectStdio() {
|
|
5226
|
-
var
|
|
5227
|
+
var _a3;
|
|
5227
5228
|
const cmd = this.config.command;
|
|
5228
5229
|
if (!cmd) {
|
|
5229
5230
|
throw new Error(`[MCPClient] Command option is required for stdio transport on "${this.config.name}"`);
|
|
@@ -5238,7 +5239,7 @@ var MCPClient = class {
|
|
|
5238
5239
|
this.stdioBuffer += data.toString("utf-8");
|
|
5239
5240
|
this.processStdioLines();
|
|
5240
5241
|
});
|
|
5241
|
-
(
|
|
5242
|
+
(_a3 = this.childProcess.stderr) == null ? void 0 : _a3.on("data", (data) => {
|
|
5242
5243
|
console.warn(`[MCPClient] [stderr] [${this.config.name}]:`, data.toString("utf-8"));
|
|
5243
5244
|
});
|
|
5244
5245
|
this.childProcess.on("close", (code) => {
|
|
@@ -5313,14 +5314,14 @@ var MCPClient = class {
|
|
|
5313
5314
|
}
|
|
5314
5315
|
}
|
|
5315
5316
|
async sendNotification(method, params) {
|
|
5316
|
-
var
|
|
5317
|
+
var _a3;
|
|
5317
5318
|
const notification = {
|
|
5318
5319
|
jsonrpc: "2.0",
|
|
5319
5320
|
method,
|
|
5320
5321
|
params
|
|
5321
5322
|
};
|
|
5322
5323
|
if (this.config.transport === "stdio") {
|
|
5323
|
-
if ((
|
|
5324
|
+
if ((_a3 = this.childProcess) == null ? void 0 : _a3.stdin) {
|
|
5324
5325
|
this.childProcess.stdin.write(JSON.stringify(notification) + "\n", "utf-8");
|
|
5325
5326
|
}
|
|
5326
5327
|
} else if (this.sseUrl) {
|
|
@@ -5398,11 +5399,11 @@ var MCPRegistry = class {
|
|
|
5398
5399
|
// src/core/MultiAgentCoordinator.ts
|
|
5399
5400
|
var MultiAgentCoordinator = class {
|
|
5400
5401
|
constructor(options) {
|
|
5401
|
-
var
|
|
5402
|
+
var _a3;
|
|
5402
5403
|
this.llmProvider = options.llmProvider;
|
|
5403
5404
|
this.mcpRegistry = options.mcpRegistry;
|
|
5404
5405
|
this.documentSearch = options.documentSearch;
|
|
5405
|
-
this.maxIterations = (
|
|
5406
|
+
this.maxIterations = (_a3 = options.maxIterations) != null ? _a3 : 5;
|
|
5406
5407
|
}
|
|
5407
5408
|
/**
|
|
5408
5409
|
* Run the multi-agent coordination loop synchronously and return the final response.
|
|
@@ -5454,8 +5455,8 @@ Available Tools:
|
|
|
5454
5455
|
|
|
5455
5456
|
${mcpTools.length > 0 ? "MCP Server Tools:" : ""}
|
|
5456
5457
|
${mcpTools.map((mt) => {
|
|
5457
|
-
var
|
|
5458
|
-
return `- ${mt.tool.name}(${JSON.stringify(((
|
|
5458
|
+
var _a3;
|
|
5459
|
+
return `- ${mt.tool.name}(${JSON.stringify(((_a3 = mt.tool.inputSchema) == null ? void 0 : _a3.properties) || {})}): ${mt.tool.description || "No description provided."}`;
|
|
5459
5460
|
}).join("\n")}
|
|
5460
5461
|
|
|
5461
5462
|
Tool Calling Protocol:
|
|
@@ -5613,6 +5614,100 @@ ${toolResultText}`
|
|
|
5613
5614
|
}
|
|
5614
5615
|
};
|
|
5615
5616
|
|
|
5617
|
+
// src/core/CircuitBreaker.ts
|
|
5618
|
+
var CircuitBreaker = class {
|
|
5619
|
+
constructor(options = {}) {
|
|
5620
|
+
this.state = "closed";
|
|
5621
|
+
this.failureCount = 0;
|
|
5622
|
+
this.successCount = 0;
|
|
5623
|
+
this.lastFailureAt = 0;
|
|
5624
|
+
this.halfOpenCalls = 0;
|
|
5625
|
+
var _a3, _b, _c;
|
|
5626
|
+
this.failureThreshold = (_a3 = options.failureThreshold) != null ? _a3 : 5;
|
|
5627
|
+
this.resetTimeoutMs = (_b = options.resetTimeoutMs) != null ? _b : 3e4;
|
|
5628
|
+
this.halfOpenMaxCalls = (_c = options.halfOpenMaxCalls) != null ? _c : 1;
|
|
5629
|
+
}
|
|
5630
|
+
record(success) {
|
|
5631
|
+
const now = Date.now();
|
|
5632
|
+
if (success) {
|
|
5633
|
+
this.successCount++;
|
|
5634
|
+
if (this.state === "half-open") {
|
|
5635
|
+
this.state = "closed";
|
|
5636
|
+
this.failureCount = 0;
|
|
5637
|
+
this.halfOpenCalls = 0;
|
|
5638
|
+
this.successCount = 1;
|
|
5639
|
+
} else if (this.state === "closed") {
|
|
5640
|
+
if (this.successCount >= this.failureThreshold) {
|
|
5641
|
+
this.failureCount = Math.max(0, this.failureCount - 1);
|
|
5642
|
+
this.successCount = 0;
|
|
5643
|
+
}
|
|
5644
|
+
}
|
|
5645
|
+
} else {
|
|
5646
|
+
this.failureCount++;
|
|
5647
|
+
this.lastFailureAt = now;
|
|
5648
|
+
this.successCount = 0;
|
|
5649
|
+
if (this.state === "half-open") {
|
|
5650
|
+
this.state = "open";
|
|
5651
|
+
this.halfOpenCalls = 0;
|
|
5652
|
+
} else if (this.state === "closed" && this.failureCount >= this.failureThreshold) {
|
|
5653
|
+
this.state = "open";
|
|
5654
|
+
}
|
|
5655
|
+
}
|
|
5656
|
+
}
|
|
5657
|
+
canExecute() {
|
|
5658
|
+
const now = Date.now();
|
|
5659
|
+
if (this.state === "closed") {
|
|
5660
|
+
return true;
|
|
5661
|
+
}
|
|
5662
|
+
if (this.state === "open") {
|
|
5663
|
+
if (now - this.lastFailureAt >= this.resetTimeoutMs) {
|
|
5664
|
+
this.state = "half-open";
|
|
5665
|
+
this.halfOpenCalls = 0;
|
|
5666
|
+
return true;
|
|
5667
|
+
}
|
|
5668
|
+
return false;
|
|
5669
|
+
}
|
|
5670
|
+
if (this.state === "half-open") {
|
|
5671
|
+
return this.halfOpenCalls < this.halfOpenMaxCalls;
|
|
5672
|
+
}
|
|
5673
|
+
return true;
|
|
5674
|
+
}
|
|
5675
|
+
async wrap(fn) {
|
|
5676
|
+
if (!this.canExecute()) {
|
|
5677
|
+
const retryAfterSec = Math.ceil(
|
|
5678
|
+
Math.max(0, this.resetTimeoutMs - (Date.now() - this.lastFailureAt)) / 1e3
|
|
5679
|
+
);
|
|
5680
|
+
throw new Error(
|
|
5681
|
+
`Circuit breaker is open. Try again in ${retryAfterSec}s. Failed ${this.failureCount}/${this.failureThreshold} consecutive calls.`
|
|
5682
|
+
);
|
|
5683
|
+
}
|
|
5684
|
+
if (this.state === "half-open") {
|
|
5685
|
+
this.halfOpenCalls++;
|
|
5686
|
+
}
|
|
5687
|
+
try {
|
|
5688
|
+
const result = await fn();
|
|
5689
|
+
this.record(true);
|
|
5690
|
+
return result;
|
|
5691
|
+
} catch (err) {
|
|
5692
|
+
this.record(false);
|
|
5693
|
+
throw err;
|
|
5694
|
+
}
|
|
5695
|
+
}
|
|
5696
|
+
getState() {
|
|
5697
|
+
return this.state;
|
|
5698
|
+
}
|
|
5699
|
+
getFailureCount() {
|
|
5700
|
+
return this.failureCount;
|
|
5701
|
+
}
|
|
5702
|
+
reset() {
|
|
5703
|
+
this.state = "closed";
|
|
5704
|
+
this.failureCount = 0;
|
|
5705
|
+
this.successCount = 0;
|
|
5706
|
+
this.lastFailureAt = 0;
|
|
5707
|
+
this.halfOpenCalls = 0;
|
|
5708
|
+
}
|
|
5709
|
+
};
|
|
5710
|
+
|
|
5616
5711
|
// src/core/BatchProcessor.ts
|
|
5617
5712
|
function isTransientError(error) {
|
|
5618
5713
|
if (!(error instanceof Error)) return false;
|
|
@@ -5636,7 +5731,34 @@ function calculateBackoffDelay(attempt, initialDelayMs, maxDelayMs, multiplier)
|
|
|
5636
5731
|
function sleep(ms) {
|
|
5637
5732
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
5638
5733
|
}
|
|
5639
|
-
var
|
|
5734
|
+
var _BatchProcessor = class _BatchProcessor {
|
|
5735
|
+
/**
|
|
5736
|
+
* Execute a processor call through the circuit breaker.
|
|
5737
|
+
* Only transient failures count toward opening the circuit.
|
|
5738
|
+
*/
|
|
5739
|
+
static async executeWithCircuitBreaker(processor) {
|
|
5740
|
+
if (!this.cb.canExecute()) {
|
|
5741
|
+
const retryAfterSec = Math.ceil(
|
|
5742
|
+
Math.max(0, 3e4 - (Date.now() - this.cb.lastFailureAt || 0)) / 1e3
|
|
5743
|
+
);
|
|
5744
|
+
throw new Error(
|
|
5745
|
+
`[BatchProcessor] Circuit breaker is open. Try again in ${retryAfterSec}s.`
|
|
5746
|
+
);
|
|
5747
|
+
}
|
|
5748
|
+
if (this.cb.state === "half-open") {
|
|
5749
|
+
this.cb.halfOpenCalls++;
|
|
5750
|
+
}
|
|
5751
|
+
try {
|
|
5752
|
+
const result = await processor();
|
|
5753
|
+
this.cb.record(true);
|
|
5754
|
+
return result;
|
|
5755
|
+
} catch (err) {
|
|
5756
|
+
if (isTransientError(err)) {
|
|
5757
|
+
this.cb.record(false);
|
|
5758
|
+
}
|
|
5759
|
+
throw err;
|
|
5760
|
+
}
|
|
5761
|
+
}
|
|
5640
5762
|
/**
|
|
5641
5763
|
* Processes an array of items in configurable batches with retry logic.
|
|
5642
5764
|
*
|
|
@@ -5677,7 +5799,7 @@ var BatchProcessor = class {
|
|
|
5677
5799
|
let lastError;
|
|
5678
5800
|
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
5679
5801
|
try {
|
|
5680
|
-
const result = await processor(batch);
|
|
5802
|
+
const result = await _BatchProcessor.executeWithCircuitBreaker(() => processor(batch));
|
|
5681
5803
|
results.push(result);
|
|
5682
5804
|
success = true;
|
|
5683
5805
|
break;
|
|
@@ -5735,7 +5857,7 @@ ${errorMessages}`
|
|
|
5735
5857
|
let lastError;
|
|
5736
5858
|
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
5737
5859
|
try {
|
|
5738
|
-
const result = await processor(item);
|
|
5860
|
+
const result = await _BatchProcessor.executeWithCircuitBreaker(() => processor(item));
|
|
5739
5861
|
results.push(result);
|
|
5740
5862
|
success = true;
|
|
5741
5863
|
break;
|
|
@@ -5808,7 +5930,7 @@ ${errorMessages}`
|
|
|
5808
5930
|
}));
|
|
5809
5931
|
const chunkPromises = chunk.map(async ({ item, originalIndex }) => {
|
|
5810
5932
|
try {
|
|
5811
|
-
const result = await processor(item);
|
|
5933
|
+
const result = await _BatchProcessor.executeWithCircuitBreaker(() => processor(item));
|
|
5812
5934
|
return { success: true, result, index: originalIndex };
|
|
5813
5935
|
} catch (err) {
|
|
5814
5936
|
const error = err instanceof Error ? err : new Error(String(err));
|
|
@@ -5836,6 +5958,12 @@ ${errorMessages}`
|
|
|
5836
5958
|
return { results, errors, totalProcessed, totalFailed };
|
|
5837
5959
|
}
|
|
5838
5960
|
};
|
|
5961
|
+
_BatchProcessor.cb = new CircuitBreaker({
|
|
5962
|
+
failureThreshold: 5,
|
|
5963
|
+
resetTimeoutMs: 3e4,
|
|
5964
|
+
halfOpenMaxCalls: 1
|
|
5965
|
+
});
|
|
5966
|
+
var BatchProcessor = _BatchProcessor;
|
|
5839
5967
|
|
|
5840
5968
|
// src/config/EmbeddingStrategy.ts
|
|
5841
5969
|
var EmbeddingStrategyResolver = class {
|
|
@@ -5933,7 +6061,7 @@ var QueryProcessor = class {
|
|
|
5933
6061
|
* @param validFields Optional list of known filterable fields to look for
|
|
5934
6062
|
*/
|
|
5935
6063
|
static extractQueryFieldHints(question, validFields = []) {
|
|
5936
|
-
var
|
|
6064
|
+
var _a3, _b, _c, _d;
|
|
5937
6065
|
if (!question.trim()) return [];
|
|
5938
6066
|
const hints = /* @__PURE__ */ new Map();
|
|
5939
6067
|
const addHint = (value, field) => {
|
|
@@ -6013,7 +6141,7 @@ var QueryProcessor = class {
|
|
|
6013
6141
|
];
|
|
6014
6142
|
for (const p of universalPatterns) {
|
|
6015
6143
|
for (const match of question.matchAll(p.regex)) {
|
|
6016
|
-
const val = p.group ? (
|
|
6144
|
+
const val = p.group ? (_a3 = match[p.group]) != null ? _a3 : match[0] : match[0];
|
|
6017
6145
|
if (!val) continue;
|
|
6018
6146
|
if (p.field) addHint(val, p.field);
|
|
6019
6147
|
else addHint(val);
|
|
@@ -6237,11 +6365,11 @@ var LLMRouter = class {
|
|
|
6237
6365
|
* When provided it is used directly as the 'default' role without re-constructing.
|
|
6238
6366
|
*/
|
|
6239
6367
|
async initialize(prebuiltDefault) {
|
|
6240
|
-
var
|
|
6368
|
+
var _a3;
|
|
6241
6369
|
const defaultModel = prebuiltDefault != null ? prebuiltDefault : LLMFactory.create(this.config.llm, this.config.embedding);
|
|
6242
6370
|
this.models.set("default", defaultModel);
|
|
6243
6371
|
const envFastModel = process.env.FAST_LLM_MODEL;
|
|
6244
|
-
const providerFastDefault = (
|
|
6372
|
+
const providerFastDefault = (_a3 = FAST_MODEL_DEFAULTS[this.config.llm.provider]) != null ? _a3 : "";
|
|
6245
6373
|
const fastModelName = envFastModel || providerFastDefault;
|
|
6246
6374
|
if (fastModelName && fastModelName !== this.config.llm.model) {
|
|
6247
6375
|
console.log(`[LLMRouter] Fast role \u2192 provider="${this.config.llm.provider}" model="${fastModelName}"`);
|
|
@@ -6260,8 +6388,8 @@ var LLMRouter = class {
|
|
|
6260
6388
|
* Falls back to 'default' if the requested role is not registered.
|
|
6261
6389
|
*/
|
|
6262
6390
|
get(role) {
|
|
6263
|
-
var
|
|
6264
|
-
const provider = (
|
|
6391
|
+
var _a3;
|
|
6392
|
+
const provider = (_a3 = this.models.get(role)) != null ? _a3 : this.models.get("default");
|
|
6265
6393
|
if (!provider) {
|
|
6266
6394
|
throw new Error(`[LLMRouter] No provider registered for role: "${role}". Did you call initialize()?`);
|
|
6267
6395
|
}
|
|
@@ -6347,8 +6475,8 @@ var IntentClassifier = class {
|
|
|
6347
6475
|
numericFieldCount = numericKeys.size;
|
|
6348
6476
|
categoricalFieldCount = catKeys.size;
|
|
6349
6477
|
if (productKeyMatches >= 2 || docs.some((d) => {
|
|
6350
|
-
var
|
|
6351
|
-
return ((
|
|
6478
|
+
var _a3, _b;
|
|
6479
|
+
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");
|
|
6352
6480
|
})) {
|
|
6353
6481
|
isProductLike = true;
|
|
6354
6482
|
}
|
|
@@ -6630,8 +6758,8 @@ var TextRendererStrategy = class {
|
|
|
6630
6758
|
}
|
|
6631
6759
|
const docs = Array.isArray(data) ? data : [];
|
|
6632
6760
|
const text = docs.map((d) => {
|
|
6633
|
-
var
|
|
6634
|
-
return (
|
|
6761
|
+
var _a3;
|
|
6762
|
+
return (_a3 = d == null ? void 0 : d.content) != null ? _a3 : "";
|
|
6635
6763
|
}).join("\n\n");
|
|
6636
6764
|
return { type: "text", title, data: { content: text || "No detailed content available." } };
|
|
6637
6765
|
}
|
|
@@ -6774,9 +6902,9 @@ var LRUDecisionCache = class {
|
|
|
6774
6902
|
this.maxSize = maxSize;
|
|
6775
6903
|
}
|
|
6776
6904
|
generateKey(context) {
|
|
6777
|
-
var
|
|
6905
|
+
var _a3, _b;
|
|
6778
6906
|
const q = (context.userQuery || "").toLowerCase().trim();
|
|
6779
|
-
const docCount = (_b = (
|
|
6907
|
+
const docCount = (_b = (_a3 = context.retrievedDocuments) == null ? void 0 : _a3.length) != null ? _b : 0;
|
|
6780
6908
|
return `${q}::docs:${docCount}`;
|
|
6781
6909
|
}
|
|
6782
6910
|
get(context) {
|
|
@@ -6877,7 +7005,7 @@ var UITransformer = class _UITransformer {
|
|
|
6877
7005
|
* Prefer `analyzeAndDecide()` in production.
|
|
6878
7006
|
*/
|
|
6879
7007
|
static transform(userQuery, retrievedData, config, trainedSchema, intent) {
|
|
6880
|
-
var
|
|
7008
|
+
var _a3, _b, _c;
|
|
6881
7009
|
if (!retrievedData || retrievedData.length === 0) {
|
|
6882
7010
|
return this.createTextResponse("No data available", "No relevant data found for your query.");
|
|
6883
7011
|
}
|
|
@@ -6897,7 +7025,7 @@ var UITransformer = class _UITransformer {
|
|
|
6897
7025
|
return this.transformToBarChart(filteredData, profile, userQuery, resolvedIntent.visualizationHint === "ranking");
|
|
6898
7026
|
}
|
|
6899
7027
|
if (resolvedIntent.visualizationHint === "distribution") {
|
|
6900
|
-
return (
|
|
7028
|
+
return (_a3 = this.transformToHistogram(profile, userQuery)) != null ? _a3 : this.transformToBarChart(filteredData, profile, userQuery);
|
|
6901
7029
|
}
|
|
6902
7030
|
if (resolvedIntent.visualizationHint === "correlation") {
|
|
6903
7031
|
return (_b = this.transformToScatterPlot(profile, userQuery)) != null ? _b : this.transformToBarChart(filteredData, profile, userQuery);
|
|
@@ -7230,11 +7358,11 @@ ${schemaProfileText}` : ""}`;
|
|
|
7230
7358
|
};
|
|
7231
7359
|
}
|
|
7232
7360
|
static transformToPieChart(data, profile, query = "") {
|
|
7233
|
-
var
|
|
7361
|
+
var _a3;
|
|
7234
7362
|
const dimension = profile ? this.selectDimensionField(profile, query) : void 0;
|
|
7235
7363
|
const categories = dimension ? Array.from(new Set(profile.records.map((record) => {
|
|
7236
|
-
var
|
|
7237
|
-
return String((
|
|
7364
|
+
var _a4;
|
|
7365
|
+
return String((_a4 = record.fields[dimension.key]) != null ? _a4 : "");
|
|
7238
7366
|
}).filter(Boolean))) : this.detectCategories(data);
|
|
7239
7367
|
if (categories.length === 0) return null;
|
|
7240
7368
|
const categoryData = dimension && profile ? this.aggregateProfileByDimension(profile, dimension.key) : this.aggregateByCategory(data, categories);
|
|
@@ -7244,7 +7372,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7244
7372
|
});
|
|
7245
7373
|
return {
|
|
7246
7374
|
type: "pie_chart",
|
|
7247
|
-
title: `Distribution by ${(
|
|
7375
|
+
title: `Distribution by ${(_a3 = dimension == null ? void 0 : dimension.label) != null ? _a3 : "Category"}`,
|
|
7248
7376
|
description: `Showing breakdown across ${pieData.length} categories`,
|
|
7249
7377
|
data: pieData
|
|
7250
7378
|
};
|
|
@@ -7254,8 +7382,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7254
7382
|
const valueField = profile.numericFields[0];
|
|
7255
7383
|
const buckets = /* @__PURE__ */ new Map();
|
|
7256
7384
|
profile.records.forEach((record) => {
|
|
7257
|
-
var
|
|
7258
|
-
const timestamp = String((
|
|
7385
|
+
var _a3, _b, _c;
|
|
7386
|
+
const timestamp = String((_a3 = record.fields[dateField.key]) != null ? _a3 : "");
|
|
7259
7387
|
const value = (_b = this.toFiniteNumber(record.fields[valueField.key])) != null ? _b : 0;
|
|
7260
7388
|
buckets.set(timestamp, ((_c = buckets.get(timestamp)) != null ? _c : 0) + value);
|
|
7261
7389
|
});
|
|
@@ -7268,23 +7396,23 @@ ${schemaProfileText}` : ""}`;
|
|
|
7268
7396
|
};
|
|
7269
7397
|
}
|
|
7270
7398
|
static transformToBarChart(data, profile, query = "", horizontal = false) {
|
|
7271
|
-
var
|
|
7399
|
+
var _a3;
|
|
7272
7400
|
const dimension = profile ? this.selectDimensionField(profile, query) : void 0;
|
|
7273
7401
|
const measure = profile ? this.selectNumericField(profile, query) : void 0;
|
|
7274
7402
|
const aggregate = dimension && profile ? this.aggregateProfileByDimension(profile, dimension.key, measure == null ? void 0 : measure.key) : this.aggregateByCategory(data, this.detectCategories(data));
|
|
7275
7403
|
const barData = Object.entries(aggregate).map(([category, value]) => ({ category, value: Number(value) })).sort((a, b) => horizontal ? b.value - a.value : 0).slice(0, 12);
|
|
7276
7404
|
const fallbackData = barData.length > 0 ? barData : data.slice(0, 12).map((item, index) => {
|
|
7277
|
-
var
|
|
7405
|
+
var _a4, _b, _c, _d, _e;
|
|
7278
7406
|
const meta = item.metadata || {};
|
|
7279
7407
|
const label = String(
|
|
7280
|
-
(_c = (_b = (
|
|
7408
|
+
(_c = (_b = (_a4 = this.getDynamicVal(meta, "name")) != null ? _a4 : meta.label) != null ? _b : meta.title) != null ? _c : `Result ${index + 1}`
|
|
7281
7409
|
);
|
|
7282
7410
|
const value = (_e = (_d = this.extractNumericValue(meta)) != null ? _d : item.score) != null ? _e : 0;
|
|
7283
7411
|
return { category: label, value: Number(value) };
|
|
7284
7412
|
});
|
|
7285
7413
|
return {
|
|
7286
7414
|
type: horizontal ? "horizontal_bar" : "bar_chart",
|
|
7287
|
-
title: dimension ? `${(
|
|
7415
|
+
title: dimension ? `${(_a3 = measure == null ? void 0 : measure.label) != null ? _a3 : "Count"} by ${dimension.label}` : "Comparison",
|
|
7288
7416
|
description: `Showing ${fallbackData.length} comparable values`,
|
|
7289
7417
|
data: fallbackData
|
|
7290
7418
|
};
|
|
@@ -7319,11 +7447,11 @@ ${schemaProfileText}` : ""}`;
|
|
|
7319
7447
|
if (fields.length < 2) return null;
|
|
7320
7448
|
const [xField, yField] = fields;
|
|
7321
7449
|
const points = profile.records.map((record) => {
|
|
7322
|
-
var
|
|
7450
|
+
var _a3;
|
|
7323
7451
|
const x = this.toFiniteNumber(record.fields[xField.key]);
|
|
7324
7452
|
const y = this.toFiniteNumber(record.fields[yField.key]);
|
|
7325
7453
|
if (x === null || y === null) return null;
|
|
7326
|
-
return { x, y, label: String((
|
|
7454
|
+
return { x, y, label: String((_a3 = this.getRecordLabel(record)) != null ? _a3 : record.id) };
|
|
7327
7455
|
}).filter((point) => point !== null).slice(0, 100);
|
|
7328
7456
|
if (points.length === 0) return null;
|
|
7329
7457
|
return {
|
|
@@ -7353,9 +7481,9 @@ ${schemaProfileText}` : ""}`;
|
|
|
7353
7481
|
static transformToRadarChart(data) {
|
|
7354
7482
|
const attributeMap = {};
|
|
7355
7483
|
data.forEach((item) => {
|
|
7356
|
-
var
|
|
7484
|
+
var _a3, _b, _c;
|
|
7357
7485
|
const meta = item.metadata || {};
|
|
7358
|
-
const seriesName = String((_c = (_b = (
|
|
7486
|
+
const seriesName = String((_c = (_b = (_a3 = meta.name) != null ? _a3 : meta.product) != null ? _b : item.id) != null ? _c : "Item");
|
|
7359
7487
|
Object.entries(meta).forEach(([key, val]) => {
|
|
7360
7488
|
if (typeof val === "number" && !["price", "id"].includes(key.toLowerCase())) {
|
|
7361
7489
|
if (!attributeMap[key]) attributeMap[key] = {};
|
|
@@ -7371,8 +7499,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7371
7499
|
title: "Product Comparison",
|
|
7372
7500
|
description: `Comparing ${data.length} items across ${radarData.length} attributes`,
|
|
7373
7501
|
data: radarData.length > 0 ? radarData : data.map((d) => {
|
|
7374
|
-
var
|
|
7375
|
-
return { attribute: ((
|
|
7502
|
+
var _a3;
|
|
7503
|
+
return { attribute: ((_a3 = d == null ? void 0 : d.content) != null ? _a3 : "").substring(0, 40) };
|
|
7376
7504
|
})
|
|
7377
7505
|
};
|
|
7378
7506
|
}
|
|
@@ -7391,8 +7519,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7391
7519
|
return this.createTextResponse(
|
|
7392
7520
|
"Retrieved Context",
|
|
7393
7521
|
data.map((item) => {
|
|
7394
|
-
var
|
|
7395
|
-
return (
|
|
7522
|
+
var _a3;
|
|
7523
|
+
return (_a3 = item == null ? void 0 : item.content) != null ? _a3 : "";
|
|
7396
7524
|
}).join("\n\n"),
|
|
7397
7525
|
`Found ${data.length} relevant results`
|
|
7398
7526
|
);
|
|
@@ -7443,11 +7571,11 @@ ${schemaProfileText}` : ""}`;
|
|
|
7443
7571
|
return null;
|
|
7444
7572
|
}
|
|
7445
7573
|
static normalizeTransformation(payload) {
|
|
7446
|
-
var
|
|
7574
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j;
|
|
7447
7575
|
if (!payload || typeof payload !== "object") return null;
|
|
7448
7576
|
const p = payload;
|
|
7449
7577
|
const type = this.normalizeVisualizationType(
|
|
7450
|
-
String((_c = (_b = (
|
|
7578
|
+
String((_c = (_b = (_a3 = p.type) != null ? _a3 : p.view) != null ? _b : p.chartType) != null ? _c : "")
|
|
7451
7579
|
);
|
|
7452
7580
|
if (!type) return null;
|
|
7453
7581
|
const title = String((_e = (_d = p.title) != null ? _d : p.heading) != null ? _e : "Visualization");
|
|
@@ -7458,7 +7586,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7458
7586
|
return this.validateTransformation(transformation) ? transformation : null;
|
|
7459
7587
|
}
|
|
7460
7588
|
static normalizeVisualizationType(type) {
|
|
7461
|
-
var
|
|
7589
|
+
var _a3;
|
|
7462
7590
|
const mapping = {
|
|
7463
7591
|
pie: "pie_chart",
|
|
7464
7592
|
pie_chart: "pie_chart",
|
|
@@ -7486,7 +7614,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7486
7614
|
product_carousel: "product_carousel",
|
|
7487
7615
|
carousel: "carousel"
|
|
7488
7616
|
};
|
|
7489
|
-
return (
|
|
7617
|
+
return (_a3 = mapping[type.toLowerCase()]) != null ? _a3 : null;
|
|
7490
7618
|
}
|
|
7491
7619
|
static validateTransformation(t) {
|
|
7492
7620
|
const { type, data } = t;
|
|
@@ -7602,7 +7730,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7602
7730
|
}
|
|
7603
7731
|
static profileData(data) {
|
|
7604
7732
|
const records = (data || []).filter((item) => Boolean(item && typeof item === "object")).map((item) => {
|
|
7605
|
-
var
|
|
7733
|
+
var _a3, _b;
|
|
7606
7734
|
const fields2 = {};
|
|
7607
7735
|
Object.entries(item.metadata || {}).forEach(([key, value]) => {
|
|
7608
7736
|
const primitive = this.toPrimitive(value);
|
|
@@ -7611,7 +7739,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7611
7739
|
if (!fields2.content && item.content) fields2.content = item.content.substring(0, 500);
|
|
7612
7740
|
return {
|
|
7613
7741
|
id: item.id,
|
|
7614
|
-
content: (
|
|
7742
|
+
content: (_a3 = item.content) != null ? _a3 : "",
|
|
7615
7743
|
score: (_b = item.score) != null ? _b : 0,
|
|
7616
7744
|
fields: fields2,
|
|
7617
7745
|
source: item
|
|
@@ -7692,16 +7820,16 @@ ${schemaProfileText}` : ""}`;
|
|
|
7692
7820
|
return null;
|
|
7693
7821
|
}
|
|
7694
7822
|
static selectDimensionField(profile, query) {
|
|
7695
|
-
var
|
|
7823
|
+
var _a3, _b;
|
|
7696
7824
|
const productCategory = profile.categoricalFields.find(
|
|
7697
7825
|
(field) => /category|department|collection|type|group|segment|region|country|state|city/i.test(field.key)
|
|
7698
7826
|
);
|
|
7699
7827
|
const ranked = this.rankFieldsByQuery(profile.categoricalFields, query);
|
|
7700
|
-
return (_b = (
|
|
7828
|
+
return (_b = (_a3 = ranked[0]) != null ? _a3 : productCategory) != null ? _b : profile.categoricalFields[0];
|
|
7701
7829
|
}
|
|
7702
7830
|
static selectNumericField(profile, query) {
|
|
7703
|
-
var
|
|
7704
|
-
return (
|
|
7831
|
+
var _a3;
|
|
7832
|
+
return (_a3 = this.rankFieldsByQuery(profile.numericFields, query)[0]) != null ? _a3 : profile.numericFields[0];
|
|
7705
7833
|
}
|
|
7706
7834
|
static rankFieldsByQuery(fields, query) {
|
|
7707
7835
|
const q = query.toLowerCase();
|
|
@@ -7730,8 +7858,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7730
7858
|
static aggregateProfileByDimension(profile, dimensionKey, measureKey) {
|
|
7731
7859
|
const result = {};
|
|
7732
7860
|
profile.records.forEach((record) => {
|
|
7733
|
-
var
|
|
7734
|
-
const category = String((
|
|
7861
|
+
var _a3, _b, _c;
|
|
7862
|
+
const category = String((_a3 = record.fields[dimensionKey]) != null ? _a3 : "Other").trim() || "Other";
|
|
7735
7863
|
const value = measureKey ? (_b = this.toFiniteNumber(record.fields[measureKey])) != null ? _b : 0 : 1;
|
|
7736
7864
|
result[category] = ((_c = result[category]) != null ? _c : 0) + value;
|
|
7737
7865
|
});
|
|
@@ -7811,8 +7939,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7811
7939
|
static aggregateByCategory(data, categories) {
|
|
7812
7940
|
const result = Object.fromEntries(categories.map((c) => [c, 0]));
|
|
7813
7941
|
data.forEach((item) => {
|
|
7814
|
-
var
|
|
7815
|
-
const cat = (
|
|
7942
|
+
var _a3;
|
|
7943
|
+
const cat = (_a3 = this.getProductCategory(item)) != null ? _a3 : "Other";
|
|
7816
7944
|
if (Object.prototype.hasOwnProperty.call(result, cat)) result[cat]++;
|
|
7817
7945
|
else result["Other"] = (result["Other"] || 0) + 1;
|
|
7818
7946
|
});
|
|
@@ -7820,17 +7948,17 @@ ${schemaProfileText}` : ""}`;
|
|
|
7820
7948
|
}
|
|
7821
7949
|
static extractTimeSeriesData(data) {
|
|
7822
7950
|
return data.map((item) => {
|
|
7823
|
-
var
|
|
7951
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
7824
7952
|
const meta = item.metadata || {};
|
|
7825
7953
|
return {
|
|
7826
|
-
timestamp: (_b = (
|
|
7954
|
+
timestamp: (_b = (_a3 = meta.timestamp) != null ? _a3 : meta.date) != null ? _b : (/* @__PURE__ */ new Date()).toISOString(),
|
|
7827
7955
|
value: (_d = (_c = meta.value) != null ? _c : item.score) != null ? _d : 0,
|
|
7828
7956
|
label: (_f = meta.label) != null ? _f : ((_e = item == null ? void 0 : item.content) != null ? _e : "").substring(0, 50)
|
|
7829
7957
|
};
|
|
7830
7958
|
});
|
|
7831
7959
|
}
|
|
7832
7960
|
static extractNumericValue(meta) {
|
|
7833
|
-
var
|
|
7961
|
+
var _a3;
|
|
7834
7962
|
const preferredKeys = [
|
|
7835
7963
|
"value",
|
|
7836
7964
|
"count",
|
|
@@ -7845,7 +7973,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7845
7973
|
"price"
|
|
7846
7974
|
];
|
|
7847
7975
|
for (const key of preferredKeys) {
|
|
7848
|
-
const raw = (
|
|
7976
|
+
const raw = (_a3 = resolveMetadataValue(meta, key)) != null ? _a3 : meta[key];
|
|
7849
7977
|
const value = typeof raw === "number" ? raw : Number(String(raw != null ? raw : "").replace(/[$,% ,]/g, ""));
|
|
7850
7978
|
if (Number.isFinite(value)) return value;
|
|
7851
7979
|
}
|
|
@@ -7940,8 +8068,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7940
8068
|
}, query.includes(normalizedField) ? 3 : 0);
|
|
7941
8069
|
}
|
|
7942
8070
|
static resolveTableCellValue(item, column) {
|
|
7943
|
-
var
|
|
7944
|
-
if (column === "Content") return ((
|
|
8071
|
+
var _a3, _b, _c;
|
|
8072
|
+
if (column === "Content") return ((_a3 = item == null ? void 0 : item.content) != null ? _a3 : "").substring(0, 100);
|
|
7945
8073
|
const meta = item.metadata || {};
|
|
7946
8074
|
const normalizedColumn = this.normalizeComparableField(column);
|
|
7947
8075
|
const exactMetadata = Object.entries(meta).find(
|
|
@@ -7993,8 +8121,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7993
8121
|
let inStock = 0;
|
|
7994
8122
|
let outOfStock = 0;
|
|
7995
8123
|
data.forEach((d) => {
|
|
7996
|
-
var
|
|
7997
|
-
const cat = (
|
|
8124
|
+
var _a3, _b;
|
|
8125
|
+
const cat = (_a3 = this.getProductCategory(d)) != null ? _a3 : "Other";
|
|
7998
8126
|
if (cat === category) {
|
|
7999
8127
|
const quantity = (_b = this.extractStockQuantity(d)) != null ? _b : 1;
|
|
8000
8128
|
if (this.determineStockStatus(d)) inStock += quantity;
|
|
@@ -8040,9 +8168,9 @@ ${schemaProfileText}` : ""}`;
|
|
|
8040
8168
|
}
|
|
8041
8169
|
// ─── Product Extraction ───────────────────────────────────────────────────
|
|
8042
8170
|
static getDynamicVal(meta, uiKey, config, trainedSchema) {
|
|
8043
|
-
var
|
|
8171
|
+
var _a3;
|
|
8044
8172
|
if (!meta) return void 0;
|
|
8045
|
-
const mapping = (
|
|
8173
|
+
const mapping = (_a3 = config == null ? void 0 : config.rag) == null ? void 0 : _a3.uiMapping;
|
|
8046
8174
|
if ((mapping == null ? void 0 : mapping[uiKey]) && meta[mapping[uiKey]] !== void 0) return meta[mapping[uiKey]];
|
|
8047
8175
|
if (trainedSchema && typeof trainedSchema === "object") {
|
|
8048
8176
|
const trainedKey = trainedSchema[uiKey];
|
|
@@ -8051,7 +8179,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
8051
8179
|
return resolveMetadataValue(meta, uiKey);
|
|
8052
8180
|
}
|
|
8053
8181
|
static extractProductInfo(item, config, trainedSchema) {
|
|
8054
|
-
var
|
|
8182
|
+
var _a3, _b;
|
|
8055
8183
|
if (!item) return null;
|
|
8056
8184
|
const meta = item.metadata || {};
|
|
8057
8185
|
const content = item.content || "";
|
|
@@ -8059,7 +8187,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
8059
8187
|
const price = this.getDynamicVal(meta, "price", config, trainedSchema);
|
|
8060
8188
|
const brand = this.getDynamicVal(meta, "brand", config, trainedSchema);
|
|
8061
8189
|
const description = this.cleanProductDescription(
|
|
8062
|
-
(
|
|
8190
|
+
(_a3 = this.extractProductDescriptionFromContent(content)) != null ? _a3 : this.getProductDescriptionValue(meta, config, trainedSchema)
|
|
8063
8191
|
);
|
|
8064
8192
|
if (name || this.isProductData(item)) {
|
|
8065
8193
|
let finalName = name ? String(name) : void 0;
|
|
@@ -8194,10 +8322,10 @@ RULES:
|
|
|
8194
8322
|
}
|
|
8195
8323
|
static buildContextSummary(sources, maxChars = 6e3) {
|
|
8196
8324
|
const items = (sources || []).filter(Boolean).map((s, i) => {
|
|
8197
|
-
var
|
|
8325
|
+
var _a3, _b, _c, _d;
|
|
8198
8326
|
return {
|
|
8199
8327
|
index: i + 1,
|
|
8200
|
-
content: (_b = (
|
|
8328
|
+
content: (_b = (_a3 = s == null ? void 0 : s.content) == null ? void 0 : _a3.substring(0, 400)) != null ? _b : "",
|
|
8201
8329
|
metadata: (_c = s == null ? void 0 : s.metadata) != null ? _c : {},
|
|
8202
8330
|
score: (_d = s == null ? void 0 : s.score) != null ? _d : 0
|
|
8203
8331
|
};
|
|
@@ -8237,7 +8365,7 @@ var SchemaMapper = class {
|
|
|
8237
8365
|
return promise;
|
|
8238
8366
|
}
|
|
8239
8367
|
static async _doTrain(llm, cacheKey, keys) {
|
|
8240
|
-
var
|
|
8368
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
|
|
8241
8369
|
console.log(`[SchemaMapper] \u{1F9E0} Training on new schema keys: ${keys.join(", ")}`);
|
|
8242
8370
|
const propertyList = Object.entries(this.TARGET_PROPERTIES).map(([prop, desc]) => `- ${prop} (${desc})`).join("\n");
|
|
8243
8371
|
const messages = [
|
|
@@ -8253,7 +8381,7 @@ Return a JSON object like {"name":"Title","price":"Price",...}. Omit unmapped pr
|
|
|
8253
8381
|
}
|
|
8254
8382
|
];
|
|
8255
8383
|
try {
|
|
8256
|
-
const baseUrl = (
|
|
8384
|
+
const baseUrl = (_a3 = llm == null ? void 0 : llm.baseUrl) != null ? _a3 : "";
|
|
8257
8385
|
const apiKey = (_b = llm == null ? void 0 : llm.apiKey) != null ? _b : "";
|
|
8258
8386
|
const model = (_c = llm == null ? void 0 : llm.model) != null ? _c : "llama-3.1-8b-instant";
|
|
8259
8387
|
let responseText;
|
|
@@ -8428,9 +8556,9 @@ var Pipeline = class {
|
|
|
8428
8556
|
this.initialised = false;
|
|
8429
8557
|
/** Namespace-specific static cold context cache for CAG */
|
|
8430
8558
|
this.coldContexts = /* @__PURE__ */ new Map();
|
|
8431
|
-
var
|
|
8559
|
+
var _a3, _b, _c, _d, _e;
|
|
8432
8560
|
this.chunker = new DocumentChunker(
|
|
8433
|
-
(_b = (
|
|
8561
|
+
(_b = (_a3 = config.rag) == null ? void 0 : _a3.chunkSize) != null ? _b : 1e3,
|
|
8434
8562
|
(_d = (_c = config.rag) == null ? void 0 : _c.chunkOverlap) != null ? _d : 200
|
|
8435
8563
|
);
|
|
8436
8564
|
if (((_e = config.rag) == null ? void 0 : _e.chunkingStrategy) === "llamaindex") {
|
|
@@ -8446,7 +8574,7 @@ var Pipeline = class {
|
|
|
8446
8574
|
return this.initialised ? this.llmProvider : void 0;
|
|
8447
8575
|
}
|
|
8448
8576
|
async initialize() {
|
|
8449
|
-
var
|
|
8577
|
+
var _a3, _b, _c, _d;
|
|
8450
8578
|
if (this.initialised) return;
|
|
8451
8579
|
const chartInstruction = `You are a helpful assistant. Use the provided context to answer questions accurately.
|
|
8452
8580
|
|
|
@@ -8489,7 +8617,7 @@ var Pipeline = class {
|
|
|
8489
8617
|
this.entityExtractor = new EntityExtractor(this.llmProvider);
|
|
8490
8618
|
}
|
|
8491
8619
|
await this.vectorDB.initialize();
|
|
8492
|
-
if (((
|
|
8620
|
+
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) {
|
|
8493
8621
|
this.mcpRegistry = new MCPRegistry(this.config.mcpServers || []);
|
|
8494
8622
|
this.multiAgentCoordinator = new MultiAgentCoordinator({
|
|
8495
8623
|
llmProvider: this.llmProvider,
|
|
@@ -8507,8 +8635,8 @@ var Pipeline = class {
|
|
|
8507
8635
|
this.initialised = true;
|
|
8508
8636
|
}
|
|
8509
8637
|
async loadColdContext(ns) {
|
|
8510
|
-
var
|
|
8511
|
-
const cagConfig = (
|
|
8638
|
+
var _a3, _b;
|
|
8639
|
+
const cagConfig = (_a3 = this.config.rag) == null ? void 0 : _a3.cag;
|
|
8512
8640
|
if (!cagConfig || !cagConfig.enabled) return;
|
|
8513
8641
|
try {
|
|
8514
8642
|
const coldNs = cagConfig.coldNamespace || ns;
|
|
@@ -8561,12 +8689,12 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8561
8689
|
}
|
|
8562
8690
|
/** Step 1: Chunk the document content. */
|
|
8563
8691
|
async prepareChunks(doc) {
|
|
8564
|
-
var
|
|
8692
|
+
var _a3, _b;
|
|
8565
8693
|
if (this.llamaIngestor) {
|
|
8566
8694
|
return this.llamaIngestor.chunk(doc.content, {
|
|
8567
8695
|
docId: doc.docId,
|
|
8568
8696
|
metadata: doc.metadata,
|
|
8569
|
-
chunkSize: (
|
|
8697
|
+
chunkSize: (_a3 = this.config.rag) == null ? void 0 : _a3.chunkSize,
|
|
8570
8698
|
chunkOverlap: (_b = this.config.rag) == null ? void 0 : _b.chunkOverlap
|
|
8571
8699
|
});
|
|
8572
8700
|
}
|
|
@@ -8664,9 +8792,9 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8664
8792
|
return { reply, sources };
|
|
8665
8793
|
}
|
|
8666
8794
|
async ask(question, history = [], namespace) {
|
|
8667
|
-
var
|
|
8795
|
+
var _a3, _b;
|
|
8668
8796
|
await this.initialize();
|
|
8669
|
-
if ((((
|
|
8797
|
+
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) {
|
|
8670
8798
|
return await this.multiAgentCoordinator.run(question, history);
|
|
8671
8799
|
}
|
|
8672
8800
|
const stream = this.askStream(question, history, namespace);
|
|
@@ -8701,9 +8829,9 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8701
8829
|
}
|
|
8702
8830
|
askStream(_0) {
|
|
8703
8831
|
return __asyncGenerator(this, arguments, function* (question, history = [], namespace) {
|
|
8704
|
-
var
|
|
8832
|
+
var _a3, _b;
|
|
8705
8833
|
yield new __await(this.initialize());
|
|
8706
|
-
if ((((
|
|
8834
|
+
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) {
|
|
8707
8835
|
const stream2 = this.multiAgentCoordinator.runStream(question, history);
|
|
8708
8836
|
try {
|
|
8709
8837
|
for (var iter = __forAwait(stream2), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
|
|
@@ -8752,10 +8880,10 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8752
8880
|
*/
|
|
8753
8881
|
askStreamInternal(_0) {
|
|
8754
8882
|
return __asyncGenerator(this, arguments, function* (question, history = [], namespace) {
|
|
8755
|
-
var
|
|
8883
|
+
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;
|
|
8756
8884
|
yield new __await(this.initialize());
|
|
8757
8885
|
const ns = formatNamespace(namespace != null ? namespace : this.config.projectId);
|
|
8758
|
-
const topK = (_b = (
|
|
8886
|
+
const topK = (_b = (_a3 = this.config.rag) == null ? void 0 : _a3.topK) != null ? _b : 5;
|
|
8759
8887
|
const scoreThreshold = (_d = (_c = this.config.rag) == null ? void 0 : _c.scoreThreshold) != null ? _d : 0.3;
|
|
8760
8888
|
const requestId = `req_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
8761
8889
|
const requestStart = performance.now();
|
|
@@ -8804,8 +8932,8 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8804
8932
|
const rerankStart = performance.now();
|
|
8805
8933
|
const structuredSources = this.applyStructuredFilters(rawSources, filter).filter((s) => Boolean(s && typeof s === "object"));
|
|
8806
8934
|
let fullSources = hasNumericPredicates ? structuredSources : structuredSources.filter((m) => {
|
|
8807
|
-
var
|
|
8808
|
-
return ((
|
|
8935
|
+
var _a4;
|
|
8936
|
+
return ((_a4 = m == null ? void 0 : m.score) != null ? _a4 : 0) >= scoreThreshold;
|
|
8809
8937
|
});
|
|
8810
8938
|
const rerankLimit = Math.max(retrievalLimit, fullSources.length);
|
|
8811
8939
|
const useReranking = arch !== "naive" && (arch === "retrieve-and-rerank" || ((_m = this.config.rag) == null ? void 0 : _m.useReranking));
|
|
@@ -8818,13 +8946,13 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8818
8946
|
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]
|
|
8819
8947
|
|
|
8820
8948
|
` + promptSources.map((m, i) => {
|
|
8821
|
-
var
|
|
8949
|
+
var _a4;
|
|
8822
8950
|
return `[Source ${i + 1}]
|
|
8823
|
-
${(
|
|
8951
|
+
${(_a4 = m == null ? void 0 : m.content) != null ? _a4 : ""}`;
|
|
8824
8952
|
}).join("\n\n---\n\n") : "No relevant context found.";
|
|
8825
8953
|
const sources = [...fullSources].filter((s) => Boolean(s && typeof s === "object")).sort((a, b) => {
|
|
8826
|
-
var
|
|
8827
|
-
return ((
|
|
8954
|
+
var _a4, _b2;
|
|
8955
|
+
return ((_a4 = b == null ? void 0 : b.score) != null ? _a4 : 0) - ((_b2 = a == null ? void 0 : a.score) != null ? _b2 : 0);
|
|
8828
8956
|
});
|
|
8829
8957
|
if (graphData && graphData.nodes.length > 0) {
|
|
8830
8958
|
const graphContext = graphData.nodes.map(
|
|
@@ -8852,10 +8980,10 @@ ${context}`;
|
|
|
8852
8980
|
yield {
|
|
8853
8981
|
reply: "",
|
|
8854
8982
|
sources: (sources || []).filter((s) => Boolean(s && typeof s === "object")).map((s) => {
|
|
8855
|
-
var
|
|
8983
|
+
var _a4, _b2, _c2;
|
|
8856
8984
|
return {
|
|
8857
8985
|
id: s.id,
|
|
8858
|
-
score: (
|
|
8986
|
+
score: (_a4 = s.score) != null ? _a4 : 0,
|
|
8859
8987
|
content: (_b2 = s == null ? void 0 : s.content) != null ? _b2 : "",
|
|
8860
8988
|
metadata: (_c2 = s == null ? void 0 : s.metadata) != null ? _c2 : {},
|
|
8861
8989
|
namespace: ns
|
|
@@ -9048,11 +9176,11 @@ ${context}`;
|
|
|
9048
9176
|
systemPrompt,
|
|
9049
9177
|
userPrompt: question + finalRestrictionSuffix,
|
|
9050
9178
|
chunks: (sources || []).filter(Boolean).map((s) => {
|
|
9051
|
-
var
|
|
9179
|
+
var _a4, _b2;
|
|
9052
9180
|
return {
|
|
9053
9181
|
id: s.id,
|
|
9054
9182
|
score: s.score,
|
|
9055
|
-
content: (
|
|
9183
|
+
content: (_a4 = s == null ? void 0 : s.content) != null ? _a4 : "",
|
|
9056
9184
|
metadata: (_b2 = s == null ? void 0 : s.metadata) != null ? _b2 : {},
|
|
9057
9185
|
namespace: ns
|
|
9058
9186
|
};
|
|
@@ -9071,7 +9199,7 @@ ${context}`;
|
|
|
9071
9199
|
const telemetryUrl = ((_B = this.config.telemetry) == null ? void 0 : _B.url) || process.env.TELEMETRY_URL || process.env.NEXT_PUBLIC_TELEMETRY_URL || defaultUrl;
|
|
9072
9200
|
const absoluteUrl = telemetryUrl.startsWith("http") ? telemetryUrl : "https://www.retrivora.com" + (telemetryUrl.startsWith("/") ? telemetryUrl : "/" + telemetryUrl);
|
|
9073
9201
|
(async () => {
|
|
9074
|
-
var
|
|
9202
|
+
var _a4, _b2, _c2, _d2, _e2;
|
|
9075
9203
|
try {
|
|
9076
9204
|
let finalTrace = trace;
|
|
9077
9205
|
if (!awaitHallucination && runHallucination) {
|
|
@@ -9080,7 +9208,7 @@ ${context}`;
|
|
|
9080
9208
|
finalTrace = buildTrace(backgroundScoreResult);
|
|
9081
9209
|
}
|
|
9082
9210
|
}
|
|
9083
|
-
const modelName = (finalTrace == null ? void 0 : finalTrace.model) || ((
|
|
9211
|
+
const modelName = (finalTrace == null ? void 0 : finalTrace.model) || ((_a4 = this.config.llm) == null ? void 0 : _a4.model) || "llama-3.1-8b-instant";
|
|
9084
9212
|
const providerName = (finalTrace == null ? void 0 : finalTrace.provider) || ((_b2 = this.config.llm) == null ? void 0 : _b2.provider) || "groq";
|
|
9085
9213
|
const tokenCount = Number(((_c2 = finalTrace == null ? void 0 : finalTrace.tokens) == null ? void 0 : _c2.totalTokens) || 0);
|
|
9086
9214
|
const costEst = Number(((_d2 = finalTrace == null ? void 0 : finalTrace.tokens) == null ? void 0 : _d2.estimatedCostUsd) || 0);
|
|
@@ -9134,7 +9262,7 @@ ${context}`;
|
|
|
9134
9262
|
* Uses an LRU-bounded embedding cache to avoid re-embedding the same query.
|
|
9135
9263
|
*/
|
|
9136
9264
|
async generateUiTransformation(question, sources, cachedSchema, forceDeterministic = false) {
|
|
9137
|
-
var
|
|
9265
|
+
var _a3;
|
|
9138
9266
|
if (!sources || sources.length === 0) {
|
|
9139
9267
|
return UITransformer.transform(question, sources, this.config, cachedSchema);
|
|
9140
9268
|
}
|
|
@@ -9147,7 +9275,7 @@ ${context}`;
|
|
|
9147
9275
|
{ visualizationHint: "product_browse", recommendedChart: "text", filterInStockOnly: false, wantsExplicitTable: false, isTemporal: false, isComparison: false, language: "en" }
|
|
9148
9276
|
);
|
|
9149
9277
|
}
|
|
9150
|
-
const enableLlmUiTransform = ((
|
|
9278
|
+
const enableLlmUiTransform = ((_a3 = this.config.llm.options) == null ? void 0 : _a3.enableLlmUiTransform) === true;
|
|
9151
9279
|
if (forceDeterministic || !enableLlmUiTransform) {
|
|
9152
9280
|
return UITransformer.transform(question, sources, this.config, cachedSchema);
|
|
9153
9281
|
}
|
|
@@ -9165,15 +9293,15 @@ ${context}`;
|
|
|
9165
9293
|
const value = this.resolveNumericPredicateValue(source, predicate);
|
|
9166
9294
|
return value !== null && this.matchesNumericPredicate(value, predicate);
|
|
9167
9295
|
})).sort((a, b) => {
|
|
9168
|
-
var
|
|
9296
|
+
var _a3, _b;
|
|
9169
9297
|
const primary = predicates[0];
|
|
9170
|
-
const aValue = (
|
|
9298
|
+
const aValue = (_a3 = this.resolveNumericPredicateValue(a, primary)) != null ? _a3 : 0;
|
|
9171
9299
|
const bValue = (_b = this.resolveNumericPredicateValue(b, primary)) != null ? _b : 0;
|
|
9172
9300
|
return primary.operator === "lt" || primary.operator === "lte" ? aValue - bValue : bValue - aValue;
|
|
9173
9301
|
});
|
|
9174
9302
|
}
|
|
9175
9303
|
resolveNumericPredicateValue(source, predicate) {
|
|
9176
|
-
var
|
|
9304
|
+
var _a3;
|
|
9177
9305
|
if (!source) return null;
|
|
9178
9306
|
const meta = source.metadata || {};
|
|
9179
9307
|
const field = predicate.field;
|
|
@@ -9186,7 +9314,7 @@ ${context}`;
|
|
|
9186
9314
|
const value = this.toFiniteNumber(Array.isArray(fuzzy) ? fuzzy[1] : fuzzy.value);
|
|
9187
9315
|
if (value !== null) return value;
|
|
9188
9316
|
}
|
|
9189
|
-
const contentValue = this.extractNumericValueFromContent((
|
|
9317
|
+
const contentValue = this.extractNumericValueFromContent((_a3 = source.content) != null ? _a3 : "", field);
|
|
9190
9318
|
if (contentValue !== null) return contentValue;
|
|
9191
9319
|
}
|
|
9192
9320
|
for (const [key, value] of entries) {
|
|
@@ -9242,8 +9370,8 @@ ${context}`;
|
|
|
9242
9370
|
return Number.isFinite(numeric) ? numeric : null;
|
|
9243
9371
|
}
|
|
9244
9372
|
async retrieve(query, options) {
|
|
9245
|
-
var
|
|
9246
|
-
const ns = formatNamespace((
|
|
9373
|
+
var _a3, _b, _c, _d, _e, _f, _g2;
|
|
9374
|
+
const ns = formatNamespace((_a3 = options.namespace) != null ? _a3 : this.config.projectId);
|
|
9247
9375
|
const topK = (_b = options.topK) != null ? _b : 5;
|
|
9248
9376
|
const cacheKey = `${ns}::${query}`;
|
|
9249
9377
|
let queryVector = this.embeddingCache.get(cacheKey);
|
|
@@ -9288,11 +9416,11 @@ ${context}`;
|
|
|
9288
9416
|
namespace: ns,
|
|
9289
9417
|
count: resolvedSources.length,
|
|
9290
9418
|
sample: resolvedSources.slice(0, 2).map((s) => {
|
|
9291
|
-
var
|
|
9419
|
+
var _a4;
|
|
9292
9420
|
return {
|
|
9293
9421
|
id: s == null ? void 0 : s.id,
|
|
9294
9422
|
score: s == null ? void 0 : s.score,
|
|
9295
|
-
contentSnippet: String((
|
|
9423
|
+
contentSnippet: String((_a4 = s == null ? void 0 : s.content) != null ? _a4 : "").substring(0, 150),
|
|
9296
9424
|
metadata: s == null ? void 0 : s.metadata
|
|
9297
9425
|
};
|
|
9298
9426
|
})
|
|
@@ -9306,8 +9434,8 @@ Focus on extracting the core intent and entities. Do not answer the question, ju
|
|
|
9306
9434
|
|
|
9307
9435
|
History:
|
|
9308
9436
|
${(history || []).map((m) => {
|
|
9309
|
-
var
|
|
9310
|
-
return `${(m == null ? void 0 : m.role) || "user"}: ${(
|
|
9437
|
+
var _a3;
|
|
9438
|
+
return `${(m == null ? void 0 : m.role) || "user"}: ${(_a3 = m == null ? void 0 : m.content) != null ? _a3 : ""}`;
|
|
9311
9439
|
}).join("\n")}
|
|
9312
9440
|
|
|
9313
9441
|
New Question: ${question}
|
|
@@ -9334,8 +9462,8 @@ Optimized Search Query:`;
|
|
|
9334
9462
|
const { sources } = await this.retrieve(query, { namespace: ns, topK: 5 });
|
|
9335
9463
|
if (!sources || sources.length === 0) return [];
|
|
9336
9464
|
const context = sources.map((s) => {
|
|
9337
|
-
var
|
|
9338
|
-
return (
|
|
9465
|
+
var _a3;
|
|
9466
|
+
return (_a3 = s == null ? void 0 : s.content) != null ? _a3 : "";
|
|
9339
9467
|
}).join("\n\n---\n\n");
|
|
9340
9468
|
const prompt = `Based on the following snippets from a document, what are at least 5 short, relevant questions a user might ask?
|
|
9341
9469
|
Focus on questions that can be answered by the context.
|
|
@@ -9473,18 +9601,200 @@ var ProviderHealthCheck = class {
|
|
|
9473
9601
|
}
|
|
9474
9602
|
};
|
|
9475
9603
|
|
|
9604
|
+
// src/core/FreeTierLimitsGuard.ts
|
|
9605
|
+
var FREE_TIER_QUOTAS = {
|
|
9606
|
+
MAX_DOCUMENTS: 25,
|
|
9607
|
+
MAX_FILE_SIZE_BYTES: 20 * 1024 * 1024,
|
|
9608
|
+
MAX_STORAGE_BYTES: 250 * 1024 * 1024,
|
|
9609
|
+
MAX_TRIAL_REQUEST_UNITS: 500,
|
|
9610
|
+
MAX_DAILY_REQUEST_UNITS: 50,
|
|
9611
|
+
TRIAL_DURATION_DAYS: 14,
|
|
9612
|
+
GRACE_PERIOD_DAYS: 2,
|
|
9613
|
+
MAX_RPM: 10,
|
|
9614
|
+
MAX_RPH: 100,
|
|
9615
|
+
MAX_RPD: 500,
|
|
9616
|
+
MAX_CONCURRENT_REQUESTS: 2,
|
|
9617
|
+
MAX_INPUT_TOKENS: 2e4,
|
|
9618
|
+
MAX_OUTPUT_TOKENS: 4e3,
|
|
9619
|
+
UPGRADE_REMINDER_DAYS: [7, 12, 14],
|
|
9620
|
+
MAX_USERS: 1,
|
|
9621
|
+
MAX_NAMESPACES: 1,
|
|
9622
|
+
MAX_PROJECTS: 1
|
|
9623
|
+
};
|
|
9624
|
+
var FreeTierLimitsGuard = class {
|
|
9625
|
+
static calculateTrialTimestamps(startedAt) {
|
|
9626
|
+
const startDate = startedAt ? new Date(startedAt) : /* @__PURE__ */ new Date();
|
|
9627
|
+
const trialStartedAtMs = startDate.getTime();
|
|
9628
|
+
const trialExpiresAtMs = trialStartedAtMs + FREE_TIER_QUOTAS.TRIAL_DURATION_DAYS * 24 * 60 * 60 * 1e3;
|
|
9629
|
+
const gracePeriodExpiresAtMs = trialStartedAtMs + (FREE_TIER_QUOTAS.TRIAL_DURATION_DAYS + FREE_TIER_QUOTAS.GRACE_PERIOD_DAYS) * 24 * 60 * 60 * 1e3;
|
|
9630
|
+
return {
|
|
9631
|
+
trial_started_at: new Date(trialStartedAtMs).toISOString(),
|
|
9632
|
+
trial_expires_at: new Date(trialExpiresAtMs).toISOString(),
|
|
9633
|
+
grace_period_expires_at: new Date(gracePeriodExpiresAtMs).toISOString()
|
|
9634
|
+
};
|
|
9635
|
+
}
|
|
9636
|
+
static calculateRequestUnits(operationType, options) {
|
|
9637
|
+
var _a3;
|
|
9638
|
+
const op = operationType.toLowerCase().trim();
|
|
9639
|
+
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")) {
|
|
9640
|
+
return 0;
|
|
9641
|
+
}
|
|
9642
|
+
if (op.includes("image")) {
|
|
9643
|
+
return 10;
|
|
9644
|
+
}
|
|
9645
|
+
if (op.includes("embedding")) {
|
|
9646
|
+
const chunks = (_a3 = options == null ? void 0 : options.chunkCount) != null ? _a3 : 1;
|
|
9647
|
+
return Math.max(1, Math.ceil(chunks / 1e3));
|
|
9648
|
+
}
|
|
9649
|
+
return 1;
|
|
9650
|
+
}
|
|
9651
|
+
static checkTrialStatus(startedAt, totalUnitsUsed = 0, nowServerTime = /* @__PURE__ */ new Date()) {
|
|
9652
|
+
const timestamps = this.calculateTrialTimestamps(startedAt);
|
|
9653
|
+
const startMs = new Date(timestamps.trial_started_at).getTime();
|
|
9654
|
+
const expireMs = new Date(timestamps.trial_expires_at).getTime();
|
|
9655
|
+
const graceExpireMs = new Date(timestamps.grace_period_expires_at).getTime();
|
|
9656
|
+
const nowMs = nowServerTime.getTime();
|
|
9657
|
+
const daysElapsed = Math.floor(Math.max(0, nowMs - startMs) / (1e3 * 60 * 60 * 24));
|
|
9658
|
+
const daysRemaining = Math.max(0, Math.ceil((expireMs - nowMs) / (1e3 * 60 * 60 * 24)));
|
|
9659
|
+
const isConsumedUnits = totalUnitsUsed >= FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS;
|
|
9660
|
+
const isExpiredTime = nowMs > expireMs;
|
|
9661
|
+
const isPastGraceTime = nowMs > graceExpireMs;
|
|
9662
|
+
let status = "active";
|
|
9663
|
+
let reason;
|
|
9664
|
+
if (isPastGraceTime || isConsumedUnits && isExpiredTime) {
|
|
9665
|
+
status = "expired";
|
|
9666
|
+
reason = "Trial period and grace period have expired. Upgrade your plan.";
|
|
9667
|
+
} else if (isExpiredTime || isConsumedUnits) {
|
|
9668
|
+
status = "grace_period";
|
|
9669
|
+
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).";
|
|
9670
|
+
}
|
|
9671
|
+
let upgradeReminderDue;
|
|
9672
|
+
if (FREE_TIER_QUOTAS.UPGRADE_REMINDER_DAYS.includes(daysElapsed)) {
|
|
9673
|
+
upgradeReminderDue = daysElapsed;
|
|
9674
|
+
}
|
|
9675
|
+
let usageReminderDue;
|
|
9676
|
+
const usagePercent = totalUnitsUsed / FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS * 100;
|
|
9677
|
+
if (usagePercent >= 100) {
|
|
9678
|
+
usageReminderDue = "100%";
|
|
9679
|
+
} else if (usagePercent >= 90) {
|
|
9680
|
+
usageReminderDue = "90%";
|
|
9681
|
+
} else if (usagePercent >= 80) {
|
|
9682
|
+
usageReminderDue = "80%";
|
|
9683
|
+
}
|
|
9684
|
+
return {
|
|
9685
|
+
status,
|
|
9686
|
+
daysElapsed,
|
|
9687
|
+
daysRemaining,
|
|
9688
|
+
isGracePeriod: status === "grace_period",
|
|
9689
|
+
isExpired: status === "expired",
|
|
9690
|
+
upgradeReminderDue,
|
|
9691
|
+
usageReminderDue,
|
|
9692
|
+
reason
|
|
9693
|
+
};
|
|
9694
|
+
}
|
|
9695
|
+
static checkIngestionAllowed(stats, incomingSizeBytes = 0) {
|
|
9696
|
+
var _a3, _b;
|
|
9697
|
+
const docs = (_a3 = stats.documentCount) != null ? _a3 : 0;
|
|
9698
|
+
const storage = (_b = stats.totalStorageBytes) != null ? _b : 0;
|
|
9699
|
+
if (incomingSizeBytes > FREE_TIER_QUOTAS.MAX_FILE_SIZE_BYTES) {
|
|
9700
|
+
const mbSize = (incomingSizeBytes / (1024 * 1024)).toFixed(1);
|
|
9701
|
+
return {
|
|
9702
|
+
allowed: false,
|
|
9703
|
+
reason: `[FreeTierIngestor] File size (${mbSize}MB) exceeds maximum allowed size of 20MB under Free Tier rules.`
|
|
9704
|
+
};
|
|
9705
|
+
}
|
|
9706
|
+
if (docs >= FREE_TIER_QUOTAS.MAX_DOCUMENTS) {
|
|
9707
|
+
return {
|
|
9708
|
+
allowed: false,
|
|
9709
|
+
reason: `Document limit reached (${docs}/${FREE_TIER_QUOTAS.MAX_DOCUMENTS}). Upgrade to Pro to ingest more documents.`
|
|
9710
|
+
};
|
|
9711
|
+
}
|
|
9712
|
+
if (storage + incomingSizeBytes > FREE_TIER_QUOTAS.MAX_STORAGE_BYTES) {
|
|
9713
|
+
const mbUsed = (storage / (1024 * 1024)).toFixed(1);
|
|
9714
|
+
return {
|
|
9715
|
+
allowed: false,
|
|
9716
|
+
reason: `Storage quota exceeded (${mbUsed}MB / 250MB). Upgrade for unlimited storage.`
|
|
9717
|
+
};
|
|
9718
|
+
}
|
|
9719
|
+
return { allowed: true };
|
|
9720
|
+
}
|
|
9721
|
+
static checkRequestAllowed(params) {
|
|
9722
|
+
var _a3, _b, _c;
|
|
9723
|
+
const op = (_a3 = params.operationType) != null ? _a3 : "chat";
|
|
9724
|
+
const costUnits = this.calculateRequestUnits(op, { chunkCount: params.chunkCount });
|
|
9725
|
+
if (costUnits === 0) {
|
|
9726
|
+
return { allowed: true, costUnits: 0 };
|
|
9727
|
+
}
|
|
9728
|
+
if (params.inputTokens && params.inputTokens > FREE_TIER_QUOTAS.MAX_INPUT_TOKENS) {
|
|
9729
|
+
return {
|
|
9730
|
+
allowed: false,
|
|
9731
|
+
reason: "Token limit exceeded. Upgrade your plan.",
|
|
9732
|
+
costUnits
|
|
9733
|
+
};
|
|
9734
|
+
}
|
|
9735
|
+
if (params.outputTokens && params.outputTokens > FREE_TIER_QUOTAS.MAX_OUTPUT_TOKENS) {
|
|
9736
|
+
return {
|
|
9737
|
+
allowed: false,
|
|
9738
|
+
reason: "Token limit exceeded. Upgrade your plan.",
|
|
9739
|
+
costUnits
|
|
9740
|
+
};
|
|
9741
|
+
}
|
|
9742
|
+
if (params.concurrentRequests && params.concurrentRequests > FREE_TIER_QUOTAS.MAX_CONCURRENT_REQUESTS) {
|
|
9743
|
+
return {
|
|
9744
|
+
allowed: false,
|
|
9745
|
+
reason: `Concurrent limit exceeded (max ${FREE_TIER_QUOTAS.MAX_CONCURRENT_REQUESTS} active requests). Please wait for active streams to finish.`,
|
|
9746
|
+
costUnits
|
|
9747
|
+
};
|
|
9748
|
+
}
|
|
9749
|
+
const totalUnits = (_b = params.totalUnitsUsed) != null ? _b : 0;
|
|
9750
|
+
const trialStatus = this.checkTrialStatus(params.trialStartedAt, totalUnits, params.nowServerTime);
|
|
9751
|
+
if (trialStatus.status === "expired" || trialStatus.status === "grace_period") {
|
|
9752
|
+
return {
|
|
9753
|
+
allowed: false,
|
|
9754
|
+
reason: trialStatus.reason || "Trial limit reached. Upgrade your plan.",
|
|
9755
|
+
costUnits
|
|
9756
|
+
};
|
|
9757
|
+
}
|
|
9758
|
+
if (totalUnits + costUnits > FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS) {
|
|
9759
|
+
return {
|
|
9760
|
+
allowed: false,
|
|
9761
|
+
reason: `Total trial request unit limit reached (${totalUnits}/${FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS}). Upgrade your plan.`,
|
|
9762
|
+
costUnits
|
|
9763
|
+
};
|
|
9764
|
+
}
|
|
9765
|
+
const dailyUnits = (_c = params.dailyUnitsUsed) != null ? _c : 0;
|
|
9766
|
+
if (dailyUnits + costUnits > FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS) {
|
|
9767
|
+
return {
|
|
9768
|
+
allowed: false,
|
|
9769
|
+
reason: `Daily request quota limit reached (${dailyUnits}/${FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS} units/day). Quota resets tomorrow.`,
|
|
9770
|
+
costUnits
|
|
9771
|
+
};
|
|
9772
|
+
}
|
|
9773
|
+
return { allowed: true, costUnits };
|
|
9774
|
+
}
|
|
9775
|
+
static checkQueryAllowed(dailyQueriesCount = 0) {
|
|
9776
|
+
if (dailyQueriesCount >= FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS) {
|
|
9777
|
+
return {
|
|
9778
|
+
allowed: false,
|
|
9779
|
+
reason: `Daily query limit reached (${FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS}/day). Quota resets tomorrow.`
|
|
9780
|
+
};
|
|
9781
|
+
}
|
|
9782
|
+
return { allowed: true };
|
|
9783
|
+
}
|
|
9784
|
+
};
|
|
9785
|
+
|
|
9476
9786
|
// src/core/VectorPlugin.ts
|
|
9477
9787
|
var VectorPlugin = class {
|
|
9478
9788
|
constructor(hostConfig) {
|
|
9479
9789
|
const resolvedConfig = ConfigResolver.resolve(hostConfig);
|
|
9480
9790
|
this.config = resolvedConfig;
|
|
9481
9791
|
this.validationPromise = (async () => {
|
|
9482
|
-
var
|
|
9792
|
+
var _a3;
|
|
9483
9793
|
await ConfigValidator.validateAndThrow(resolvedConfig);
|
|
9484
9794
|
LicenseVerifier.verify(
|
|
9485
9795
|
resolvedConfig.licenseKey,
|
|
9486
9796
|
resolvedConfig.projectId,
|
|
9487
|
-
(
|
|
9797
|
+
(_a3 = resolvedConfig.vectorDb) == null ? void 0 : _a3.provider
|
|
9488
9798
|
);
|
|
9489
9799
|
})();
|
|
9490
9800
|
this.validationPromise.catch(() => {
|
|
@@ -9518,16 +9828,32 @@ var VectorPlugin = class {
|
|
|
9518
9828
|
this.config.embedding
|
|
9519
9829
|
);
|
|
9520
9830
|
}
|
|
9831
|
+
estimateInputTokens(message, history = []) {
|
|
9832
|
+
const allContent = message.length + history.reduce((acc, m) => {
|
|
9833
|
+
var _a3, _b;
|
|
9834
|
+
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);
|
|
9835
|
+
}, 0);
|
|
9836
|
+
return Math.ceil(allContent / 4);
|
|
9837
|
+
}
|
|
9521
9838
|
/**
|
|
9522
9839
|
* Run a chat query.
|
|
9523
9840
|
*/
|
|
9524
9841
|
async chat(message, history = [], namespace) {
|
|
9842
|
+
var _a3;
|
|
9525
9843
|
try {
|
|
9526
9844
|
await this.validationPromise;
|
|
9527
9845
|
} catch (err) {
|
|
9528
9846
|
throw wrapError(err, "CONFIGURATION_ERROR");
|
|
9529
9847
|
}
|
|
9530
9848
|
try {
|
|
9849
|
+
const inputTokens = this.estimateInputTokens(message, history);
|
|
9850
|
+
const tokenCheck = FreeTierLimitsGuard.checkRequestAllowed({
|
|
9851
|
+
operationType: "chat",
|
|
9852
|
+
inputTokens
|
|
9853
|
+
});
|
|
9854
|
+
if (!tokenCheck.allowed && ((_a3 = tokenCheck.reason) == null ? void 0 : _a3.toLowerCase().includes("token"))) {
|
|
9855
|
+
throw wrapError(new Error(tokenCheck.reason), "RATE_LIMITED");
|
|
9856
|
+
}
|
|
9531
9857
|
return await this.pipeline.ask(message, history, namespace);
|
|
9532
9858
|
} catch (err) {
|
|
9533
9859
|
const msg = String(err);
|
|
@@ -9535,6 +9861,9 @@ var VectorPlugin = class {
|
|
|
9535
9861
|
if (msg.includes("Embed") || msg.includes("embed")) {
|
|
9536
9862
|
defaultCode = "EMBEDDING_FAILED";
|
|
9537
9863
|
}
|
|
9864
|
+
if (msg.toLowerCase().includes("token limit")) {
|
|
9865
|
+
defaultCode = "RATE_LIMITED";
|
|
9866
|
+
}
|
|
9538
9867
|
throw wrapError(err, defaultCode);
|
|
9539
9868
|
}
|
|
9540
9869
|
}
|
|
@@ -9543,12 +9872,21 @@ var VectorPlugin = class {
|
|
|
9543
9872
|
*/
|
|
9544
9873
|
chatStream(_0) {
|
|
9545
9874
|
return __asyncGenerator(this, arguments, function* (message, history = [], namespace) {
|
|
9875
|
+
var _a3;
|
|
9546
9876
|
try {
|
|
9547
9877
|
yield new __await(this.validationPromise);
|
|
9548
9878
|
} catch (err) {
|
|
9549
9879
|
throw wrapError(err, "CONFIGURATION_ERROR");
|
|
9550
9880
|
}
|
|
9551
9881
|
try {
|
|
9882
|
+
const inputTokens = this.estimateInputTokens(message, history);
|
|
9883
|
+
const tokenCheck = FreeTierLimitsGuard.checkRequestAllowed({
|
|
9884
|
+
operationType: "chat_stream",
|
|
9885
|
+
inputTokens
|
|
9886
|
+
});
|
|
9887
|
+
if (!tokenCheck.allowed && ((_a3 = tokenCheck.reason) == null ? void 0 : _a3.toLowerCase().includes("token"))) {
|
|
9888
|
+
throw wrapError(new Error(tokenCheck.reason), "RATE_LIMITED");
|
|
9889
|
+
}
|
|
9552
9890
|
const stream = this.pipeline.askStream(message, history, namespace);
|
|
9553
9891
|
try {
|
|
9554
9892
|
for (var iter = __forAwait(stream), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
|
|
@@ -9571,6 +9909,9 @@ var VectorPlugin = class {
|
|
|
9571
9909
|
if (msg.includes("Embed") || msg.includes("embed")) {
|
|
9572
9910
|
defaultCode = "EMBEDDING_FAILED";
|
|
9573
9911
|
}
|
|
9912
|
+
if (msg.toLowerCase().includes("token limit")) {
|
|
9913
|
+
defaultCode = "RATE_LIMITED";
|
|
9914
|
+
}
|
|
9574
9915
|
throw wrapError(err, defaultCode);
|
|
9575
9916
|
}
|
|
9576
9917
|
});
|
|
@@ -9618,8 +9959,8 @@ var DocumentParser = class {
|
|
|
9618
9959
|
* Extract text from a File or Buffer based on its type.
|
|
9619
9960
|
*/
|
|
9620
9961
|
static async parse(file, fileName, mimeType) {
|
|
9621
|
-
var
|
|
9622
|
-
const extension = ((
|
|
9962
|
+
var _a3;
|
|
9963
|
+
const extension = ((_a3 = fileName.split(".").pop()) == null ? void 0 : _a3.toLowerCase()) || "";
|
|
9623
9964
|
if (extension === "txt" || extension === "md" || mimeType === "text/plain" || mimeType === "text/markdown") {
|
|
9624
9965
|
return this.readAsText(file);
|
|
9625
9966
|
}
|
|
@@ -9710,9 +10051,9 @@ var DatabaseStorage = class {
|
|
|
9710
10051
|
this.fallbackDir = this.isServerless ? path.join(os.tmpdir(), ".retrivora") : path.join(process.cwd(), ".retrivora");
|
|
9711
10052
|
this.historyFile = path.join(this.fallbackDir, "history.json");
|
|
9712
10053
|
this.feedbackFile = path.join(this.fallbackDir, "feedback.json");
|
|
9713
|
-
var
|
|
10054
|
+
var _a3, _b, _c, _d, _e;
|
|
9714
10055
|
this.config = config;
|
|
9715
|
-
this.provider = ((
|
|
10056
|
+
this.provider = ((_a3 = config.vectorDb) == null ? void 0 : _a3.provider) || "fs";
|
|
9716
10057
|
const rawHistoryTable = ((_c = (_b = config.rag) == null ? void 0 : _b.history) == null ? void 0 : _c.tableName) || "retrivora_history";
|
|
9717
10058
|
const rawFeedbackTable = ((_e = (_d = config.rag) == null ? void 0 : _d.feedback) == null ? void 0 : _e.tableName) || "retrivora_feedback";
|
|
9718
10059
|
this.historyTableName = rawHistoryTable.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
@@ -9747,16 +10088,16 @@ var DatabaseStorage = class {
|
|
|
9747
10088
|
}
|
|
9748
10089
|
}
|
|
9749
10090
|
checkHistoryEnabled() {
|
|
9750
|
-
var
|
|
10091
|
+
var _a3, _b;
|
|
9751
10092
|
this.checkPremiumSubscription();
|
|
9752
|
-
if (((_b = (
|
|
10093
|
+
if (((_b = (_a3 = this.config.rag) == null ? void 0 : _a3.history) == null ? void 0 : _b.enabled) === false) {
|
|
9753
10094
|
throw new Error("[Retrivora SDK] Chat History is disabled in RagConfig.");
|
|
9754
10095
|
}
|
|
9755
10096
|
}
|
|
9756
10097
|
checkFeedbackEnabled() {
|
|
9757
|
-
var
|
|
10098
|
+
var _a3, _b;
|
|
9758
10099
|
this.checkPremiumSubscription();
|
|
9759
|
-
if (((_b = (
|
|
10100
|
+
if (((_b = (_a3 = this.config.rag) == null ? void 0 : _a3.feedback) == null ? void 0 : _b.enabled) === false) {
|
|
9760
10101
|
throw new Error("[Retrivora SDK] User Feedback is disabled in RagConfig.");
|
|
9761
10102
|
}
|
|
9762
10103
|
}
|
|
@@ -9923,8 +10264,11 @@ var DatabaseStorage = class {
|
|
|
9923
10264
|
this.writeLocalFile(this.historyFile, history);
|
|
9924
10265
|
}
|
|
9925
10266
|
}
|
|
9926
|
-
async getHistory(sessionId) {
|
|
10267
|
+
async getHistory(sessionId, projectIds) {
|
|
9927
10268
|
this.checkHistoryEnabled();
|
|
10269
|
+
if (projectIds && projectIds.length > 0 && !this.sessionInScope(sessionId, projectIds)) {
|
|
10270
|
+
return [];
|
|
10271
|
+
}
|
|
9928
10272
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
9929
10273
|
const pool = await this.getPGPool();
|
|
9930
10274
|
const res = await pool.query(
|
|
@@ -9954,8 +10298,11 @@ var DatabaseStorage = class {
|
|
|
9954
10298
|
return history.filter((h) => h.session_id === sessionId).sort((a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime());
|
|
9955
10299
|
}
|
|
9956
10300
|
}
|
|
9957
|
-
async clearHistory(sessionId) {
|
|
10301
|
+
async clearHistory(sessionId, projectIds) {
|
|
9958
10302
|
this.checkHistoryEnabled();
|
|
10303
|
+
if (projectIds && projectIds.length > 0 && !this.sessionInScope(sessionId, projectIds)) {
|
|
10304
|
+
return;
|
|
10305
|
+
}
|
|
9959
10306
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
9960
10307
|
const pool = await this.getPGPool();
|
|
9961
10308
|
await pool.query(`DELETE FROM ${this.historyTableName} WHERE session_id = $1`, [sessionId]);
|
|
@@ -9974,21 +10321,36 @@ var DatabaseStorage = class {
|
|
|
9974
10321
|
this.writeLocalFile(this.feedbackFile, filteredFeedback);
|
|
9975
10322
|
}
|
|
9976
10323
|
}
|
|
9977
|
-
|
|
10324
|
+
/**
|
|
10325
|
+
* Return true when `sessionId` falls into the allowed `projectIds` scope.
|
|
10326
|
+
* When `projectIds` is empty / undefined we allow the call (legacy behavior
|
|
10327
|
+
* for non-multi-tenant consumers). Session ids typically begin with the
|
|
10328
|
+
* project id they were created for, so we prefix-match as well as contains-match
|
|
10329
|
+
* to catch sharded / suffix-style ids used by some integrations.
|
|
10330
|
+
*/
|
|
10331
|
+
sessionInScope(sessionId, projectIds) {
|
|
10332
|
+
if (!projectIds || projectIds.length === 0) return true;
|
|
10333
|
+
return projectIds.some(
|
|
10334
|
+
(pid) => pid && (sessionId === pid || sessionId.startsWith(pid) || sessionId.includes(pid))
|
|
10335
|
+
);
|
|
10336
|
+
}
|
|
10337
|
+
async listSessions(projectIds) {
|
|
9978
10338
|
this.checkHistoryEnabled();
|
|
10339
|
+
let raw = [];
|
|
9979
10340
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
9980
10341
|
const pool = await this.getPGPool();
|
|
9981
10342
|
const res = await pool.query(`SELECT DISTINCT session_id FROM ${this.historyTableName}`);
|
|
9982
|
-
|
|
10343
|
+
raw = res.rows.map((r) => r.session_id);
|
|
9983
10344
|
} else if (this.provider === "mongodb") {
|
|
9984
10345
|
await this.getMongoClient();
|
|
9985
10346
|
const db = this.getMongoDb();
|
|
9986
|
-
|
|
10347
|
+
raw = await db.collection(this.historyTableName).distinct("session_id");
|
|
9987
10348
|
} else {
|
|
9988
10349
|
const history = this.readLocalFile(this.historyFile);
|
|
9989
|
-
|
|
9990
|
-
return Array.from(sessions);
|
|
10350
|
+
raw = Array.from(new Set(history.map((h) => h.session_id)));
|
|
9991
10351
|
}
|
|
10352
|
+
if (!projectIds || projectIds.length === 0) return raw;
|
|
10353
|
+
return raw.filter((sid) => this.sessionInScope(sid, projectIds));
|
|
9992
10354
|
}
|
|
9993
10355
|
// ─── Feedback Operations ──────────────────────────────────────────────────
|
|
9994
10356
|
async saveFeedback(feedback) {
|
|
@@ -10041,8 +10403,9 @@ var DatabaseStorage = class {
|
|
|
10041
10403
|
this.writeLocalFile(this.feedbackFile, list);
|
|
10042
10404
|
}
|
|
10043
10405
|
}
|
|
10044
|
-
async getFeedback(messageId) {
|
|
10406
|
+
async getFeedback(messageId, projectIds) {
|
|
10045
10407
|
this.checkFeedbackEnabled();
|
|
10408
|
+
let item = null;
|
|
10046
10409
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
10047
10410
|
const pool = await this.getPGPool();
|
|
10048
10411
|
const res = await pool.query(
|
|
@@ -10051,28 +10414,34 @@ var DatabaseStorage = class {
|
|
|
10051
10414
|
WHERE message_id = $1`,
|
|
10052
10415
|
[messageId]
|
|
10053
10416
|
);
|
|
10054
|
-
|
|
10417
|
+
item = res.rows[0] || null;
|
|
10055
10418
|
} else if (this.provider === "mongodb") {
|
|
10056
10419
|
await this.getMongoClient();
|
|
10057
10420
|
const db = this.getMongoDb();
|
|
10058
10421
|
const col = db.collection(this.feedbackTableName);
|
|
10059
|
-
const
|
|
10060
|
-
if (
|
|
10061
|
-
|
|
10062
|
-
|
|
10063
|
-
|
|
10064
|
-
|
|
10065
|
-
|
|
10066
|
-
|
|
10067
|
-
|
|
10068
|
-
|
|
10422
|
+
const raw = await col.findOne({ message_id: messageId });
|
|
10423
|
+
if (raw) {
|
|
10424
|
+
item = {
|
|
10425
|
+
id: raw.id,
|
|
10426
|
+
messageId: raw.message_id,
|
|
10427
|
+
sessionId: raw.session_id,
|
|
10428
|
+
rating: raw.rating,
|
|
10429
|
+
comment: raw.comment,
|
|
10430
|
+
createdAt: raw.created_at
|
|
10431
|
+
};
|
|
10432
|
+
}
|
|
10069
10433
|
} else {
|
|
10070
10434
|
const list = this.readLocalFile(this.feedbackFile);
|
|
10071
|
-
|
|
10435
|
+
item = list.find((f) => f.message_id === messageId) || null;
|
|
10436
|
+
}
|
|
10437
|
+
if (item && projectIds && projectIds.length > 0) {
|
|
10438
|
+
return this.sessionInScope(item.sessionId, projectIds) ? item : null;
|
|
10072
10439
|
}
|
|
10440
|
+
return item;
|
|
10073
10441
|
}
|
|
10074
|
-
async listFeedback() {
|
|
10442
|
+
async listFeedback(projectIds) {
|
|
10075
10443
|
this.checkFeedbackEnabled();
|
|
10444
|
+
let raw = [];
|
|
10076
10445
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
10077
10446
|
const pool = await this.getPGPool();
|
|
10078
10447
|
const res = await pool.query(
|
|
@@ -10080,13 +10449,13 @@ var DatabaseStorage = class {
|
|
|
10080
10449
|
FROM ${this.feedbackTableName}
|
|
10081
10450
|
ORDER BY created_at DESC`
|
|
10082
10451
|
);
|
|
10083
|
-
|
|
10452
|
+
raw = res.rows;
|
|
10084
10453
|
} else if (this.provider === "mongodb") {
|
|
10085
10454
|
await this.getMongoClient();
|
|
10086
10455
|
const db = this.getMongoDb();
|
|
10087
10456
|
const col = db.collection(this.feedbackTableName);
|
|
10088
10457
|
const items = await col.find({}).sort({ created_at: -1 }).toArray();
|
|
10089
|
-
|
|
10458
|
+
raw = items.map((item) => ({
|
|
10090
10459
|
id: item.id,
|
|
10091
10460
|
messageId: item.message_id,
|
|
10092
10461
|
sessionId: item.session_id,
|
|
@@ -10096,8 +10465,10 @@ var DatabaseStorage = class {
|
|
|
10096
10465
|
}));
|
|
10097
10466
|
} else {
|
|
10098
10467
|
const list = this.readLocalFile(this.feedbackFile);
|
|
10099
|
-
|
|
10468
|
+
raw = [...list].sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime());
|
|
10100
10469
|
}
|
|
10470
|
+
if (!projectIds || projectIds.length === 0) return raw;
|
|
10471
|
+
return raw.filter((f) => this.sessionInScope(f.sessionId, projectIds));
|
|
10101
10472
|
}
|
|
10102
10473
|
async disconnect() {
|
|
10103
10474
|
if (this.pgPool) {
|
|
@@ -10160,8 +10531,8 @@ var _g = global;
|
|
|
10160
10531
|
var _a;
|
|
10161
10532
|
var rateLimiter = (_a = _g.__retrivoraRateLimiter) != null ? _a : _g.__retrivoraRateLimiter = new RateLimiter(6e4, 30);
|
|
10162
10533
|
function getRateLimitKey(req) {
|
|
10163
|
-
var
|
|
10164
|
-
const ip = ((_b = (
|
|
10534
|
+
var _a3, _b;
|
|
10535
|
+
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";
|
|
10165
10536
|
return `ip:${ip}`;
|
|
10166
10537
|
}
|
|
10167
10538
|
function checkRateLimit(req) {
|
|
@@ -10183,6 +10554,66 @@ function checkRateLimit(req) {
|
|
|
10183
10554
|
}
|
|
10184
10555
|
return null;
|
|
10185
10556
|
}
|
|
10557
|
+
var FREE_TIER_NAMES = /* @__PURE__ */ new Set(["hobby", "free", "free_trial", "trial"]);
|
|
10558
|
+
function isFreeTier(tier) {
|
|
10559
|
+
if (!tier) return true;
|
|
10560
|
+
return FREE_TIER_NAMES.has(tier.toLowerCase().trim());
|
|
10561
|
+
}
|
|
10562
|
+
var _a2;
|
|
10563
|
+
var _freeTierGuardInstance = (_a2 = _g.__retrivoraFreeTierGuard) != null ? _a2 : _g.__retrivoraFreeTierGuard = new FreeTierLimitsGuard();
|
|
10564
|
+
function createPaymentRequiredResponse(reason, details) {
|
|
10565
|
+
const body = __spreadProps(__spreadValues({
|
|
10566
|
+
type: "https://retrivora.com/docs/errors/payment-required",
|
|
10567
|
+
title: "Payment Required",
|
|
10568
|
+
status: 402,
|
|
10569
|
+
detail: reason,
|
|
10570
|
+
code: "FREE_TIER_LIMIT_EXCEEDED",
|
|
10571
|
+
instance: void 0
|
|
10572
|
+
}, details != null ? details : {}), {
|
|
10573
|
+
quota: {
|
|
10574
|
+
maxDailyRequestUnits: FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS,
|
|
10575
|
+
maxTrialRequestUnits: FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS,
|
|
10576
|
+
maxDocuments: FREE_TIER_QUOTAS.MAX_DOCUMENTS,
|
|
10577
|
+
maxStorageBytes: FREE_TIER_QUOTAS.MAX_STORAGE_BYTES,
|
|
10578
|
+
upgradeUrl: "https://retrivora.com/pricing"
|
|
10579
|
+
}
|
|
10580
|
+
});
|
|
10581
|
+
return new Response(JSON.stringify(body), {
|
|
10582
|
+
status: 402,
|
|
10583
|
+
headers: {
|
|
10584
|
+
"Content-Type": "application/problem+json"
|
|
10585
|
+
}
|
|
10586
|
+
});
|
|
10587
|
+
}
|
|
10588
|
+
function resolveLicenseKey(req, config, bodyLicenseKey) {
|
|
10589
|
+
var _a3;
|
|
10590
|
+
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 || "";
|
|
10591
|
+
}
|
|
10592
|
+
function enforceLicense(req, config, bodyLicenseKey) {
|
|
10593
|
+
const rawKey = resolveLicenseKey(req, config, bodyLicenseKey);
|
|
10594
|
+
const licenseKey = (rawKey || "").trim().replace(/^["']|["']$/g, "").trim();
|
|
10595
|
+
const projectId = config.projectId || "my-rag-app";
|
|
10596
|
+
try {
|
|
10597
|
+
const payload = LicenseVerifier.verify(licenseKey, projectId);
|
|
10598
|
+
return { ok: true, payload };
|
|
10599
|
+
} catch (err) {
|
|
10600
|
+
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.";
|
|
10601
|
+
const body = {
|
|
10602
|
+
error: {
|
|
10603
|
+
code: "LICENSE_REVOKED",
|
|
10604
|
+
message: "Your Retrivora license key has been terminated, suspended, or revoked. Access denied."
|
|
10605
|
+
},
|
|
10606
|
+
details: message
|
|
10607
|
+
};
|
|
10608
|
+
return {
|
|
10609
|
+
ok: false,
|
|
10610
|
+
response: new Response(JSON.stringify(body), {
|
|
10611
|
+
status: 403,
|
|
10612
|
+
headers: { "Content-Type": "application/json" }
|
|
10613
|
+
})
|
|
10614
|
+
};
|
|
10615
|
+
}
|
|
10616
|
+
}
|
|
10186
10617
|
var MAX_MESSAGE_LENGTH = 8e3;
|
|
10187
10618
|
function sanitizeInput(raw) {
|
|
10188
10619
|
const stripped = raw.replace(/[\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F-\u009F]/g, "");
|
|
@@ -10204,7 +10635,7 @@ function getOrCreatePlugin(configOrPlugin) {
|
|
|
10204
10635
|
return _g[cacheKey];
|
|
10205
10636
|
}
|
|
10206
10637
|
function reportTelemetry(req, plugin, action, status, details, trace) {
|
|
10207
|
-
var
|
|
10638
|
+
var _a3, _b, _c, _d, _e, _f, _g2;
|
|
10208
10639
|
try {
|
|
10209
10640
|
const config = plugin.getConfig();
|
|
10210
10641
|
const licenseKey = config.licenseKey || process.env.RAG_LICENSE_KEY || process.env.RETRIVORA_LICENSE_KEY || process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY;
|
|
@@ -10219,7 +10650,7 @@ function reportTelemetry(req, plugin, action, status, details, trace) {
|
|
|
10219
10650
|
absoluteUrl = `${proto}://${host}${telemetryUrl}`;
|
|
10220
10651
|
}
|
|
10221
10652
|
const projectId = config.projectId || "default";
|
|
10222
|
-
const model = (trace == null ? void 0 : trace.model) || ((
|
|
10653
|
+
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";
|
|
10223
10654
|
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";
|
|
10224
10655
|
const tokens = Number(((_e = trace == null ? void 0 : trace.tokens) == null ? void 0 : _e.totalTokens) || (trace == null ? void 0 : trace.totalTokens) || 0);
|
|
10225
10656
|
const costUsd = Number(((_f = trace == null ? void 0 : trace.tokens) == null ? void 0 : _f.estimatedCostUsd) || (trace == null ? void 0 : trace.costUsd) || 0);
|
|
@@ -10243,7 +10674,6 @@ function reportTelemetry(req, plugin, action, status, details, trace) {
|
|
|
10243
10674
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
10244
10675
|
details
|
|
10245
10676
|
};
|
|
10246
|
-
console.log(`[Retrivora SDK Telemetry] Dispatching telemetry -> Feature: "${action}", Status: "${status}", Project: "${projectId}", Latency: ${latencyMs}ms`);
|
|
10247
10677
|
fetch(absoluteUrl, {
|
|
10248
10678
|
method: "POST",
|
|
10249
10679
|
headers: {
|
|
@@ -10301,14 +10731,39 @@ function createChatHandler(configOrPlugin, options) {
|
|
|
10301
10731
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
10302
10732
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
10303
10733
|
return async function POST(req, context) {
|
|
10304
|
-
var
|
|
10734
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
10305
10735
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10306
10736
|
if (authResult) return authResult;
|
|
10307
10737
|
const rateLimited = checkRateLimit(req);
|
|
10308
10738
|
if (rateLimited) return rateLimited;
|
|
10739
|
+
const config = plugin.getConfig();
|
|
10309
10740
|
try {
|
|
10310
10741
|
const body = await req.json();
|
|
10311
10742
|
const bodyObj = body != null ? body : {};
|
|
10743
|
+
const licenseCheck = enforceLicense(req, config, bodyObj == null ? void 0 : bodyObj.licenseKey);
|
|
10744
|
+
if (!licenseCheck.ok) return licenseCheck.response;
|
|
10745
|
+
if (isFreeTier(licenseCheck.payload.tier)) {
|
|
10746
|
+
const estimatedInputTokens = Math.ceil(
|
|
10747
|
+
((((_a3 = bodyObj.message) == null ? void 0 : _a3.length) || 0) + (Array.isArray(bodyObj.messages) ? bodyObj.messages.reduce((a, m) => {
|
|
10748
|
+
var _a4, _b2;
|
|
10749
|
+
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);
|
|
10750
|
+
}, 0) : 0) + (((_b = bodyObj.history) == null ? void 0 : _b.reduce((a, m) => {
|
|
10751
|
+
var _a4, _b2;
|
|
10752
|
+
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);
|
|
10753
|
+
}, 0)) || 0)) / 4
|
|
10754
|
+
);
|
|
10755
|
+
const chatCheck = FreeTierLimitsGuard.checkRequestAllowed({
|
|
10756
|
+
operationType: "chat",
|
|
10757
|
+
inputTokens: estimatedInputTokens,
|
|
10758
|
+
projectId: licenseCheck.payload.projectId
|
|
10759
|
+
});
|
|
10760
|
+
if (!chatCheck.allowed) {
|
|
10761
|
+
return createPaymentRequiredResponse(
|
|
10762
|
+
chatCheck.reason || "Free tier quota exceeded.",
|
|
10763
|
+
{ tier: licenseCheck.payload.tier, projectId: licenseCheck.payload.projectId }
|
|
10764
|
+
);
|
|
10765
|
+
}
|
|
10766
|
+
}
|
|
10312
10767
|
let rawMessage = bodyObj.message;
|
|
10313
10768
|
if (!rawMessage && Array.isArray(bodyObj.messages) && bodyObj.messages.length > 0) {
|
|
10314
10769
|
const lastMsg = bodyObj.messages[bodyObj.messages.length - 1];
|
|
@@ -10340,7 +10795,7 @@ function createChatHandler(configOrPlugin, options) {
|
|
|
10340
10795
|
uiTransformation: result.ui_transformation,
|
|
10341
10796
|
trace: result.trace
|
|
10342
10797
|
}).catch((err) => console.warn("[createChatHandler] Failed to save assistant message:", err));
|
|
10343
|
-
reportTelemetry(req, plugin, "QUERY_GENERATION", "success", `Tokens: ${((
|
|
10798
|
+
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);
|
|
10344
10799
|
return NextResponse.json(__spreadProps(__spreadValues({}, result), {
|
|
10345
10800
|
messageId: assistantMsgId,
|
|
10346
10801
|
userMessageId: userMsgId
|
|
@@ -10357,14 +10812,15 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10357
10812
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
10358
10813
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
10359
10814
|
return async function POST(req, context) {
|
|
10360
|
-
var
|
|
10815
|
+
var _a3, _b, _c;
|
|
10361
10816
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10362
10817
|
if (authResult) return authResult;
|
|
10363
10818
|
const rateLimited = checkRateLimit(req);
|
|
10364
10819
|
if (rateLimited) return rateLimited;
|
|
10820
|
+
const config = plugin.getConfig();
|
|
10365
10821
|
let body;
|
|
10366
10822
|
try {
|
|
10367
|
-
if ((
|
|
10823
|
+
if ((_a3 = req.headers.get("content-type")) == null ? void 0 : _a3.includes("multipart/form-data")) {
|
|
10368
10824
|
const uploader = createUploadHandler(plugin, { onAuthorize });
|
|
10369
10825
|
return uploader(req);
|
|
10370
10826
|
}
|
|
@@ -10376,6 +10832,30 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10376
10832
|
});
|
|
10377
10833
|
}
|
|
10378
10834
|
const bodyObj = body != null ? body : {};
|
|
10835
|
+
const licenseCheck = enforceLicense(req, config, bodyObj == null ? void 0 : bodyObj.licenseKey);
|
|
10836
|
+
if (!licenseCheck.ok) return licenseCheck.response;
|
|
10837
|
+
if (isFreeTier(licenseCheck.payload.tier)) {
|
|
10838
|
+
const estimatedInputTokens = Math.ceil(
|
|
10839
|
+
((((_b = bodyObj.message) == null ? void 0 : _b.length) || 0) + (Array.isArray(bodyObj.messages) ? bodyObj.messages.reduce((a, m) => {
|
|
10840
|
+
var _a4, _b2;
|
|
10841
|
+
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);
|
|
10842
|
+
}, 0) : 0) + (((_c = bodyObj.history) == null ? void 0 : _c.reduce((a, m) => {
|
|
10843
|
+
var _a4, _b2;
|
|
10844
|
+
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);
|
|
10845
|
+
}, 0)) || 0)) / 4
|
|
10846
|
+
);
|
|
10847
|
+
const chatCheck = FreeTierLimitsGuard.checkRequestAllowed({
|
|
10848
|
+
operationType: "chat_stream",
|
|
10849
|
+
inputTokens: estimatedInputTokens,
|
|
10850
|
+
projectId: licenseCheck.payload.projectId
|
|
10851
|
+
});
|
|
10852
|
+
if (!chatCheck.allowed) {
|
|
10853
|
+
return createPaymentRequiredResponse(
|
|
10854
|
+
chatCheck.reason || "Free tier quota exceeded.",
|
|
10855
|
+
{ tier: licenseCheck.payload.tier, projectId: licenseCheck.payload.projectId }
|
|
10856
|
+
);
|
|
10857
|
+
}
|
|
10858
|
+
}
|
|
10379
10859
|
let rawMessage = bodyObj.message;
|
|
10380
10860
|
if (!rawMessage && Array.isArray(bodyObj.messages) && bodyObj.messages.length > 0) {
|
|
10381
10861
|
const lastMsg = bodyObj.messages[bodyObj.messages.length - 1];
|
|
@@ -10405,7 +10885,7 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10405
10885
|
let isActive = true;
|
|
10406
10886
|
const stream = new ReadableStream({
|
|
10407
10887
|
async start(controller) {
|
|
10408
|
-
var
|
|
10888
|
+
var _a4, _b2, _c2, _d, _e;
|
|
10409
10889
|
const enqueue = (text) => {
|
|
10410
10890
|
if (!isActive) return;
|
|
10411
10891
|
try {
|
|
@@ -10438,7 +10918,7 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10438
10918
|
let uiTransformation = responseChunk == null ? void 0 : responseChunk.ui_transformation;
|
|
10439
10919
|
if (sources.length > 0) {
|
|
10440
10920
|
try {
|
|
10441
|
-
uiTransformation = (
|
|
10921
|
+
uiTransformation = (_a4 = responseChunk == null ? void 0 : responseChunk.ui_transformation) != null ? _a4 : UITransformer.transform(message, sources, plugin.getConfig());
|
|
10442
10922
|
if (uiTransformation) {
|
|
10443
10923
|
enqueue(sseUIFrame(uiTransformation));
|
|
10444
10924
|
}
|
|
@@ -10462,7 +10942,7 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10462
10942
|
uiTransformation,
|
|
10463
10943
|
trace: responseChunk == null ? void 0 : responseChunk.trace
|
|
10464
10944
|
}).catch((err) => console.warn("[createStreamHandler] Failed to save assistant message:", err));
|
|
10465
|
-
reportTelemetry(req, plugin, "QUERY_GENERATION", "success", `Tokens: ${((
|
|
10945
|
+
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);
|
|
10466
10946
|
}
|
|
10467
10947
|
}
|
|
10468
10948
|
} catch (temp) {
|
|
@@ -10512,12 +10992,36 @@ function createIngestHandler(configOrPlugin, options) {
|
|
|
10512
10992
|
return async function POST(req, context) {
|
|
10513
10993
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10514
10994
|
if (authResult) return authResult;
|
|
10995
|
+
const config = plugin.getConfig();
|
|
10515
10996
|
try {
|
|
10516
10997
|
const body = await req.json();
|
|
10998
|
+
const licenseCheck = enforceLicense(req, config, body == null ? void 0 : body.licenseKey);
|
|
10999
|
+
if (!licenseCheck.ok) return licenseCheck.response;
|
|
10517
11000
|
const { documents, namespace } = body;
|
|
10518
11001
|
if (!Array.isArray(documents) || documents.length === 0) {
|
|
10519
11002
|
return NextResponse.json({ error: "documents array is required" }, { status: 400 });
|
|
10520
11003
|
}
|
|
11004
|
+
if (isFreeTier(licenseCheck.payload.tier)) {
|
|
11005
|
+
const totalIncomingBytes = documents.reduce(
|
|
11006
|
+
(sum, d) => sum + Buffer.byteLength(d.content || "", "utf8"),
|
|
11007
|
+
0
|
|
11008
|
+
);
|
|
11009
|
+
const ingestCheck = FreeTierLimitsGuard.checkIngestionAllowed(
|
|
11010
|
+
{ documentCount: documents.length },
|
|
11011
|
+
totalIncomingBytes
|
|
11012
|
+
);
|
|
11013
|
+
if (!ingestCheck.allowed) {
|
|
11014
|
+
return createPaymentRequiredResponse(
|
|
11015
|
+
ingestCheck.reason || "Free tier ingestion limit reached.",
|
|
11016
|
+
{
|
|
11017
|
+
tier: licenseCheck.payload.tier,
|
|
11018
|
+
projectId: licenseCheck.payload.projectId,
|
|
11019
|
+
documents: documents.length,
|
|
11020
|
+
incomingBytes: totalIncomingBytes
|
|
11021
|
+
}
|
|
11022
|
+
);
|
|
11023
|
+
}
|
|
11024
|
+
}
|
|
10521
11025
|
const results = await plugin.ingest(documents, namespace);
|
|
10522
11026
|
reportTelemetry(req, plugin, "DOCUMENT_INGESTION", "success", `Ingested ${documents.length} document(s)`);
|
|
10523
11027
|
return NextResponse.json({ results });
|
|
@@ -10554,7 +11058,7 @@ function createLicenseHandler(configOrPlugin, options) {
|
|
|
10554
11058
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
10555
11059
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
10556
11060
|
return async function POST(req) {
|
|
10557
|
-
var
|
|
11061
|
+
var _a3;
|
|
10558
11062
|
if (req) {
|
|
10559
11063
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10560
11064
|
if (authResult) return authResult;
|
|
@@ -10562,7 +11066,8 @@ function createLicenseHandler(configOrPlugin, options) {
|
|
|
10562
11066
|
try {
|
|
10563
11067
|
const body = await req.json().catch(() => ({}));
|
|
10564
11068
|
const config = plugin.getConfig();
|
|
10565
|
-
const
|
|
11069
|
+
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 || "";
|
|
11070
|
+
const licenseKey = (rawKey || "").trim().replace(/^["']|["']$/g, "").trim();
|
|
10566
11071
|
const projectId = (body == null ? void 0 : body.projectId) || config.projectId || "my-rag-app";
|
|
10567
11072
|
const payload = LicenseVerifier.verify(licenseKey, projectId);
|
|
10568
11073
|
return NextResponse.json({
|
|
@@ -10596,6 +11101,9 @@ function createUploadHandler(configOrPlugin, options) {
|
|
|
10596
11101
|
return async function POST(req, context) {
|
|
10597
11102
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10598
11103
|
if (authResult) return authResult;
|
|
11104
|
+
const config = plugin.getConfig();
|
|
11105
|
+
const licenseCheck = enforceLicense(req, config);
|
|
11106
|
+
if (!licenseCheck.ok) return licenseCheck.response;
|
|
10599
11107
|
try {
|
|
10600
11108
|
const formData = await req.formData();
|
|
10601
11109
|
const files = formData.getAll("files");
|
|
@@ -10605,6 +11113,26 @@ function createUploadHandler(configOrPlugin, options) {
|
|
|
10605
11113
|
if (!files || files.length === 0) {
|
|
10606
11114
|
return NextResponse.json({ error: "No files provided" }, { status: 400 });
|
|
10607
11115
|
}
|
|
11116
|
+
if (isFreeTier(licenseCheck.payload.tier)) {
|
|
11117
|
+
const totalUploadBytes = files.reduce((sum, f) => sum + (f.size || 0), 0);
|
|
11118
|
+
const uploadCheck = FreeTierLimitsGuard.checkIngestionAllowed(
|
|
11119
|
+
{ documentCount: files.length },
|
|
11120
|
+
totalUploadBytes
|
|
11121
|
+
);
|
|
11122
|
+
if (!uploadCheck.allowed) {
|
|
11123
|
+
return createPaymentRequiredResponse(
|
|
11124
|
+
uploadCheck.reason || "Free tier upload limit reached.",
|
|
11125
|
+
{
|
|
11126
|
+
tier: licenseCheck.payload.tier,
|
|
11127
|
+
projectId: licenseCheck.payload.projectId,
|
|
11128
|
+
fileCount: files.length,
|
|
11129
|
+
totalUploadBytes,
|
|
11130
|
+
maxFileSizeBytes: FREE_TIER_QUOTAS.MAX_FILE_SIZE_BYTES,
|
|
11131
|
+
maxStorageBytes: FREE_TIER_QUOTAS.MAX_STORAGE_BYTES
|
|
11132
|
+
}
|
|
11133
|
+
);
|
|
11134
|
+
}
|
|
11135
|
+
}
|
|
10608
11136
|
const documents = [];
|
|
10609
11137
|
for (const file of files) {
|
|
10610
11138
|
const isExcel = file.name.toLowerCase().endsWith(".xlsx") || file.name.toLowerCase().endsWith(".xls") || file.type.includes("spreadsheet") || file.type.includes("excel");
|
|
@@ -10714,13 +11242,22 @@ function createSuggestionsHandler(configOrPlugin, options) {
|
|
|
10714
11242
|
return async function handler(req) {
|
|
10715
11243
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10716
11244
|
if (authResult) return authResult;
|
|
11245
|
+
const config = plugin.getConfig();
|
|
11246
|
+
const licenseCheck = enforceLicense(req, config);
|
|
11247
|
+
if (!licenseCheck.ok) return licenseCheck.response;
|
|
10717
11248
|
try {
|
|
10718
11249
|
let query = "";
|
|
10719
11250
|
let namespace = void 0;
|
|
11251
|
+
let bodyLicenseKey = void 0;
|
|
10720
11252
|
if (req.method === "POST") {
|
|
10721
11253
|
const body = await req.json().catch(() => ({}));
|
|
10722
11254
|
query = body.query || "";
|
|
10723
11255
|
namespace = body.namespace;
|
|
11256
|
+
bodyLicenseKey = body.licenseKey;
|
|
11257
|
+
if (bodyLicenseKey) {
|
|
11258
|
+
const recheck = enforceLicense(req, config, bodyLicenseKey);
|
|
11259
|
+
if (!recheck.ok) return recheck.response;
|
|
11260
|
+
}
|
|
10724
11261
|
} else {
|
|
10725
11262
|
const url = new URL(req.url);
|
|
10726
11263
|
query = url.searchParams.get("query") || "";
|
|
@@ -10743,14 +11280,16 @@ function createHistoryHandler(configOrPlugin, options) {
|
|
|
10743
11280
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
10744
11281
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
10745
11282
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
11283
|
+
const onResolveScope = options == null ? void 0 : options.onResolveScope;
|
|
10746
11284
|
return async function handler(req) {
|
|
10747
11285
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10748
11286
|
if (authResult) return authResult;
|
|
11287
|
+
const scope = onResolveScope ? await onResolveScope(req) : void 0;
|
|
10749
11288
|
const url = new URL(req.url);
|
|
10750
11289
|
const sessionId = url.searchParams.get("sessionId") || "default";
|
|
10751
11290
|
if (req.method === "GET") {
|
|
10752
11291
|
try {
|
|
10753
|
-
const history = await storage.getHistory(sessionId);
|
|
11292
|
+
const history = await storage.getHistory(sessionId, scope);
|
|
10754
11293
|
return NextResponse.json({ history });
|
|
10755
11294
|
} catch (err) {
|
|
10756
11295
|
const message = err instanceof Error ? err.message : "Failed to fetch history";
|
|
@@ -10760,7 +11299,7 @@ function createHistoryHandler(configOrPlugin, options) {
|
|
|
10760
11299
|
try {
|
|
10761
11300
|
const body = await req.json().catch(() => ({}));
|
|
10762
11301
|
const sid = body.sessionId || sessionId;
|
|
10763
|
-
await storage.clearHistory(sid);
|
|
11302
|
+
await storage.clearHistory(sid, scope);
|
|
10764
11303
|
return NextResponse.json({ success: true });
|
|
10765
11304
|
} catch (err) {
|
|
10766
11305
|
const message = err instanceof Error ? err.message : "Failed to clear history";
|
|
@@ -10774,18 +11313,20 @@ function createFeedbackHandler(configOrPlugin, options) {
|
|
|
10774
11313
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
10775
11314
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
10776
11315
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
11316
|
+
const onResolveScope = options == null ? void 0 : options.onResolveScope;
|
|
10777
11317
|
return async function handler(req) {
|
|
10778
11318
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10779
11319
|
if (authResult) return authResult;
|
|
11320
|
+
const scope = onResolveScope ? await onResolveScope(req) : void 0;
|
|
10780
11321
|
if (req.method === "GET") {
|
|
10781
11322
|
try {
|
|
10782
11323
|
const url = new URL(req.url);
|
|
10783
11324
|
const messageId = url.searchParams.get("messageId");
|
|
10784
11325
|
if (!messageId) {
|
|
10785
|
-
const feedbackList = await storage.listFeedback();
|
|
11326
|
+
const feedbackList = await storage.listFeedback(scope);
|
|
10786
11327
|
return NextResponse.json({ feedback: feedbackList });
|
|
10787
11328
|
}
|
|
10788
|
-
const feedback = await storage.getFeedback(messageId);
|
|
11329
|
+
const feedback = await storage.getFeedback(messageId, scope);
|
|
10789
11330
|
return NextResponse.json({ feedback });
|
|
10790
11331
|
} catch (err) {
|
|
10791
11332
|
const message = err instanceof Error ? err.message : "Failed to fetch feedback";
|
|
@@ -10801,6 +11342,17 @@ function createFeedbackHandler(configOrPlugin, options) {
|
|
|
10801
11342
|
if (!rating) {
|
|
10802
11343
|
return NextResponse.json({ error: "rating is required" }, { status: 400 });
|
|
10803
11344
|
}
|
|
11345
|
+
if (scope && scope.length > 0) {
|
|
11346
|
+
const matches = scope.some(
|
|
11347
|
+
(pid) => pid && (sessionId === pid || sessionId.startsWith(pid) || sessionId.includes(pid))
|
|
11348
|
+
);
|
|
11349
|
+
if (!matches) {
|
|
11350
|
+
return NextResponse.json(
|
|
11351
|
+
{ error: "sessionId is outside the authorized project scope" },
|
|
11352
|
+
{ status: 403 }
|
|
11353
|
+
);
|
|
11354
|
+
}
|
|
11355
|
+
}
|
|
10804
11356
|
await storage.saveFeedback({ messageId, sessionId, rating, comment });
|
|
10805
11357
|
return NextResponse.json({ success: true });
|
|
10806
11358
|
} catch (err) {
|
|
@@ -10815,14 +11367,15 @@ function createSessionsHandler(configOrPlugin, options) {
|
|
|
10815
11367
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
10816
11368
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
10817
11369
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
11370
|
+
const onResolveScope = options == null ? void 0 : options.onResolveScope;
|
|
10818
11371
|
return async function GET(req) {
|
|
10819
11372
|
if (req) {
|
|
10820
11373
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10821
11374
|
if (authResult) return authResult;
|
|
10822
11375
|
}
|
|
10823
|
-
void req;
|
|
10824
11376
|
try {
|
|
10825
|
-
const
|
|
11377
|
+
const scope = req && onResolveScope ? await onResolveScope(req) : void 0;
|
|
11378
|
+
const sessions = await storage.listSessions(scope);
|
|
10826
11379
|
return NextResponse.json({ sessions });
|
|
10827
11380
|
} catch (err) {
|
|
10828
11381
|
const message = err instanceof Error ? err.message : "Failed to list sessions";
|
|
@@ -10833,15 +11386,17 @@ function createSessionsHandler(configOrPlugin, options) {
|
|
|
10833
11386
|
function createRagHandler(configOrPlugin, options) {
|
|
10834
11387
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
10835
11388
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
10836
|
-
const
|
|
10837
|
-
const
|
|
10838
|
-
const
|
|
10839
|
-
const
|
|
10840
|
-
const
|
|
10841
|
-
const
|
|
10842
|
-
const
|
|
10843
|
-
const
|
|
10844
|
-
const
|
|
11389
|
+
const onResolveScope = options == null ? void 0 : options.onResolveScope;
|
|
11390
|
+
const scopeableOptions = { onAuthorize, onResolveScope };
|
|
11391
|
+
const chatHandler = createChatHandler(plugin, scopeableOptions);
|
|
11392
|
+
const streamHandler = createStreamHandler(plugin, scopeableOptions);
|
|
11393
|
+
const uploadHandler = createUploadHandler(plugin, scopeableOptions);
|
|
11394
|
+
const healthHandler = createHealthHandler(plugin, scopeableOptions);
|
|
11395
|
+
const suggestionsHandler = createSuggestionsHandler(plugin, scopeableOptions);
|
|
11396
|
+
const historyHandler = createHistoryHandler(plugin, scopeableOptions);
|
|
11397
|
+
const feedbackHandler = createFeedbackHandler(plugin, scopeableOptions);
|
|
11398
|
+
const sessionsHandler = createSessionsHandler(plugin, scopeableOptions);
|
|
11399
|
+
const licenseHandler = createLicenseHandler(plugin, scopeableOptions);
|
|
10845
11400
|
async function routePostRequest(req, segment) {
|
|
10846
11401
|
switch (segment) {
|
|
10847
11402
|
case "chat":
|
|
@@ -10883,7 +11438,7 @@ function createRagHandler(configOrPlugin, options) {
|
|
|
10883
11438
|
}
|
|
10884
11439
|
}
|
|
10885
11440
|
async function getSegment(req, context) {
|
|
10886
|
-
var
|
|
11441
|
+
var _a3, _b;
|
|
10887
11442
|
const contentType = req.headers.get("content-type") || "";
|
|
10888
11443
|
if (contentType.includes("multipart/form-data")) {
|
|
10889
11444
|
return "upload";
|
|
@@ -10900,7 +11455,7 @@ function createRagHandler(configOrPlugin, options) {
|
|
|
10900
11455
|
if (pathname.endsWith("/history")) return "history";
|
|
10901
11456
|
} catch (e) {
|
|
10902
11457
|
}
|
|
10903
|
-
const resolvedParams = typeof ((
|
|
11458
|
+
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;
|
|
10904
11459
|
const segments = (resolvedParams == null ? void 0 : resolvedParams.retrivora) || ((_b = resolvedParams == null ? void 0 : resolvedParams.params) == null ? void 0 : _b.retrivora) || [];
|
|
10905
11460
|
const joined = segments.join("/");
|
|
10906
11461
|
return joined || "chat";
|