@retrivora-ai/rag-engine 2.3.0 → 2.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{LicenseValidator-CENvo9o2.d.mts → BatchProcessor-7yV-UCHW.d.mts} +142 -3
- package/dist/{LicenseValidator-CsjJp2PP.d.ts → BatchProcessor-BfzuU4cK.d.ts} +142 -3
- package/dist/handlers/index.d.mts +1 -1
- package/dist/handlers/index.d.ts +1 -1
- package/dist/handlers/index.js +880 -327
- package/dist/handlers/index.mjs +880 -327
- package/dist/index-DR_O_B-W.d.ts +394 -0
- package/dist/index-fnpaCuma.d.mts +394 -0
- package/dist/index.css +58 -0
- package/dist/index.d.mts +63 -3
- package/dist/index.d.ts +63 -3
- package/dist/index.js +452 -35
- package/dist/index.mjs +451 -37
- package/dist/server.d.mts +35 -73
- package/dist/server.d.ts +35 -73
- package/dist/server.js +910 -341
- package/dist/server.mjs +910 -341
- package/package.json +1 -1
- package/src/components/ChatWidget.tsx +147 -46
- package/src/components/ChatWindow.tsx +52 -8
- package/src/core/BatchProcessor.ts +42 -4
- package/src/core/CircuitBreaker.ts +118 -0
- package/src/core/DatabaseStorage.ts +55 -24
- package/src/core/FreeTierLimitsGuard.ts +281 -0
- package/src/core/LicenseValidator.ts +66 -2
- package/src/core/LicenseVerifier.ts +31 -3
- package/src/core/VectorPlugin.ts +30 -0
- package/src/handlers/index.ts +491 -36
- package/src/index.css +58 -0
- package/src/index.ts +4 -0
- package/src/server.ts +1 -0
- package/dist/index-BPJ3KDYI.d.ts +0 -195
- package/dist/index-Dmq5lH0j.d.mts +0 -195
package/dist/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);
|
|
@@ -2523,8 +2523,8 @@ var UI_BORDER_RADIUS_OPTIONS = ["none", "sm", "md", "lg", "xl", "full"];
|
|
|
2523
2523
|
|
|
2524
2524
|
// src/config/serverConfig.ts
|
|
2525
2525
|
function readString(env, name) {
|
|
2526
|
-
var
|
|
2527
|
-
const value = (
|
|
2526
|
+
var _a3;
|
|
2527
|
+
const value = (_a3 = env[name]) == null ? void 0 : _a3.trim();
|
|
2528
2528
|
return value ? value : void 0;
|
|
2529
2529
|
}
|
|
2530
2530
|
function readNumber(env, name, fallback) {
|
|
@@ -2537,16 +2537,16 @@ function readNumber(env, name, fallback) {
|
|
|
2537
2537
|
return parsed;
|
|
2538
2538
|
}
|
|
2539
2539
|
function readEnum(env, name, fallback, allowed) {
|
|
2540
|
-
var
|
|
2541
|
-
const value = (
|
|
2540
|
+
var _a3;
|
|
2541
|
+
const value = (_a3 = readString(env, name)) != null ? _a3 : fallback;
|
|
2542
2542
|
if (allowed.includes(value)) {
|
|
2543
2543
|
return value;
|
|
2544
2544
|
}
|
|
2545
2545
|
throw new Error(`[getRagConfig] ${name} must be one of: ${allowed.join(", ")}`);
|
|
2546
2546
|
}
|
|
2547
2547
|
function getEnvConfig(env = process.env, base) {
|
|
2548
|
-
var
|
|
2549
|
-
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;
|
|
2550
2550
|
const jwtProjectId = (() => {
|
|
2551
2551
|
if (!licenseKey) return void 0;
|
|
2552
2552
|
try {
|
|
@@ -2627,7 +2627,7 @@ function getEnvConfig(env = process.env, base) {
|
|
|
2627
2627
|
rest: "default",
|
|
2628
2628
|
custom: "default"
|
|
2629
2629
|
};
|
|
2630
|
-
const
|
|
2630
|
+
const isFreeTier2 = (() => {
|
|
2631
2631
|
if (!licenseKey) return true;
|
|
2632
2632
|
try {
|
|
2633
2633
|
const payload = LicenseVerifier.verify(licenseKey, projectId);
|
|
@@ -2638,13 +2638,13 @@ function getEnvConfig(env = process.env, base) {
|
|
|
2638
2638
|
}
|
|
2639
2639
|
})();
|
|
2640
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";
|
|
2641
|
-
const defaultLlmProvider =
|
|
2641
|
+
const defaultLlmProvider = isFreeTier2 ? "universal_rest" : "universal_rest";
|
|
2642
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;
|
|
2643
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;
|
|
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 :
|
|
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";
|
|
2645
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;
|
|
2646
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";
|
|
2647
|
-
const defaultEmbeddingProvider =
|
|
2647
|
+
const defaultEmbeddingProvider = isFreeTier2 ? "universal_rest" : "universal_rest";
|
|
2648
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;
|
|
2649
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;
|
|
2650
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";
|
|
@@ -2734,8 +2734,8 @@ function getEnvConfig(env = process.env, base) {
|
|
|
2734
2734
|
}
|
|
2735
2735
|
} : {}), {
|
|
2736
2736
|
mcpServers: (() => {
|
|
2737
|
-
var
|
|
2738
|
-
const raw = (
|
|
2737
|
+
var _a4;
|
|
2738
|
+
const raw = (_a4 = readString(env, "MCP_SERVERS")) != null ? _a4 : readString(env, "NEXT_PUBLIC_MCP_SERVERS");
|
|
2739
2739
|
if (!raw) return void 0;
|
|
2740
2740
|
try {
|
|
2741
2741
|
return JSON.parse(raw);
|
|
@@ -2780,10 +2780,10 @@ var ConfigResolver = class {
|
|
|
2780
2780
|
* fallback behavior.
|
|
2781
2781
|
*/
|
|
2782
2782
|
static resolveUniversal(hostConfig, env = process.env) {
|
|
2783
|
-
var
|
|
2783
|
+
var _a3;
|
|
2784
2784
|
if (!hostConfig) return this.resolve(void 0, env);
|
|
2785
2785
|
const normalized = __spreadProps(__spreadValues({}, hostConfig), {
|
|
2786
|
-
vectorDb: (
|
|
2786
|
+
vectorDb: (_a3 = hostConfig.vectorDb) != null ? _a3 : hostConfig.vectorDatabase,
|
|
2787
2787
|
rag: this.mergeRetrievalWorkflow(hostConfig.rag, hostConfig.retrieval, hostConfig.workflow)
|
|
2788
2788
|
});
|
|
2789
2789
|
return this.resolve(normalized, env);
|
|
@@ -2803,11 +2803,11 @@ var ConfigResolver = class {
|
|
|
2803
2803
|
}
|
|
2804
2804
|
}
|
|
2805
2805
|
static mergeRetrievalWorkflow(rag, retrieval, workflow) {
|
|
2806
|
-
var
|
|
2806
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
2807
2807
|
if (!rag && !retrieval && !workflow) return void 0;
|
|
2808
2808
|
const normalized = __spreadValues({}, rag != null ? rag : {});
|
|
2809
2809
|
if (retrieval) {
|
|
2810
|
-
normalized.topK = (
|
|
2810
|
+
normalized.topK = (_a3 = retrieval.topK) != null ? _a3 : normalized.topK;
|
|
2811
2811
|
normalized.scoreThreshold = (_b = retrieval.scoreThreshold) != null ? _b : normalized.scoreThreshold;
|
|
2812
2812
|
normalized.useReranking = (_c = retrieval.useReranking) != null ? _c : normalized.useReranking;
|
|
2813
2813
|
if (retrieval.strategy === "hybrid") normalized.architecture = (_d = normalized.architecture) != null ? _d : "hybrid";
|
|
@@ -2935,8 +2935,8 @@ var OpenAIProvider = class {
|
|
|
2935
2935
|
};
|
|
2936
2936
|
}
|
|
2937
2937
|
async chat(messages, context, options) {
|
|
2938
|
-
var
|
|
2939
|
-
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.";
|
|
2940
2940
|
const systemMessage = {
|
|
2941
2941
|
role: "system",
|
|
2942
2942
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -2960,8 +2960,8 @@ var OpenAIProvider = class {
|
|
|
2960
2960
|
}
|
|
2961
2961
|
chatStream(messages, context, options) {
|
|
2962
2962
|
return __asyncGenerator(this, null, function* () {
|
|
2963
|
-
var
|
|
2964
|
-
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.";
|
|
2965
2965
|
const systemMessage = {
|
|
2966
2966
|
role: "system",
|
|
2967
2967
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3008,8 +3008,8 @@ var OpenAIProvider = class {
|
|
|
3008
3008
|
return results[0];
|
|
3009
3009
|
}
|
|
3010
3010
|
async batchEmbed(texts, options) {
|
|
3011
|
-
var
|
|
3012
|
-
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";
|
|
3013
3013
|
const apiKey = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.apiKey) != null ? _e : this.llmConfig.apiKey;
|
|
3014
3014
|
const client = apiKey !== this.llmConfig.apiKey ? new OpenAI({ apiKey }) : this.client;
|
|
3015
3015
|
const response = await client.embeddings.create({ model, input: texts });
|
|
@@ -3086,8 +3086,8 @@ var AnthropicProvider = class {
|
|
|
3086
3086
|
};
|
|
3087
3087
|
}
|
|
3088
3088
|
async chat(messages, context, options) {
|
|
3089
|
-
var
|
|
3090
|
-
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.";
|
|
3091
3091
|
const system = buildSystemContent(basePrompt, context);
|
|
3092
3092
|
const anthropicMessages = messages.map((m) => ({
|
|
3093
3093
|
role: m.role === "assistant" ? "assistant" : "user",
|
|
@@ -3125,8 +3125,8 @@ var AnthropicProvider = class {
|
|
|
3125
3125
|
}
|
|
3126
3126
|
chatStream(messages, context, options) {
|
|
3127
3127
|
return __asyncGenerator(this, null, function* () {
|
|
3128
|
-
var
|
|
3129
|
-
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.";
|
|
3130
3130
|
const system = buildSystemContent(basePrompt, context);
|
|
3131
3131
|
const anthropicMessages = messages.map((m) => ({
|
|
3132
3132
|
role: m.role === "assistant" ? "assistant" : "user",
|
|
@@ -3210,8 +3210,8 @@ var AnthropicProvider = class {
|
|
|
3210
3210
|
import axios from "axios";
|
|
3211
3211
|
var OllamaProvider = class {
|
|
3212
3212
|
constructor(llmConfig, embeddingConfig) {
|
|
3213
|
-
var
|
|
3214
|
-
const rawBaseURL = ((
|
|
3213
|
+
var _a3, _b, _c;
|
|
3214
|
+
const rawBaseURL = ((_a3 = llmConfig.baseUrl) != null ? _a3 : "http://localhost:11434").replace(/\/+$/, "");
|
|
3215
3215
|
const baseURL = rawBaseURL.replace(/\/(?:api\/v1|v1|api)$/i, "");
|
|
3216
3216
|
const timeout = Number((_b = llmConfig.options) == null ? void 0 : _b.timeout) || 3e5;
|
|
3217
3217
|
const headers = ((_c = llmConfig.options) == null ? void 0 : _c.headers) || {};
|
|
@@ -3271,8 +3271,8 @@ var OllamaProvider = class {
|
|
|
3271
3271
|
};
|
|
3272
3272
|
}
|
|
3273
3273
|
async chat(messages, context, options) {
|
|
3274
|
-
var
|
|
3275
|
-
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.";
|
|
3276
3276
|
const system = buildSystemContent(basePrompt, context);
|
|
3277
3277
|
const { data } = await this.http.post("/api/chat", {
|
|
3278
3278
|
model: this.llmConfig.model,
|
|
@@ -3290,8 +3290,8 @@ var OllamaProvider = class {
|
|
|
3290
3290
|
}
|
|
3291
3291
|
chatStream(messages, context, options) {
|
|
3292
3292
|
return __asyncGenerator(this, null, function* () {
|
|
3293
|
-
var
|
|
3294
|
-
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.";
|
|
3295
3295
|
const system = buildSystemContent(basePrompt, context);
|
|
3296
3296
|
const response = yield new __await(this.http.post("/api/chat", {
|
|
3297
3297
|
model: this.llmConfig.model,
|
|
@@ -3349,8 +3349,8 @@ var OllamaProvider = class {
|
|
|
3349
3349
|
});
|
|
3350
3350
|
}
|
|
3351
3351
|
async embed(text, options) {
|
|
3352
|
-
var
|
|
3353
|
-
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";
|
|
3354
3354
|
const baseURL = (_f = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.baseUrl) != null ? _e : this.llmConfig.baseUrl) != null ? _f : "http://localhost:11434";
|
|
3355
3355
|
const client = baseURL !== ((_g2 = this.llmConfig.baseUrl) != null ? _g2 : "http://localhost:11434") ? axios.create({ baseURL, timeout: 6e4 }) : this.http;
|
|
3356
3356
|
let prompt = text;
|
|
@@ -3451,9 +3451,9 @@ var GeminiProvider = class {
|
|
|
3451
3451
|
static getHealthChecker() {
|
|
3452
3452
|
return {
|
|
3453
3453
|
async check(config) {
|
|
3454
|
-
var
|
|
3454
|
+
var _a3, _b;
|
|
3455
3455
|
const timestamp = Date.now();
|
|
3456
|
-
const apiKey = (_b = (
|
|
3456
|
+
const apiKey = (_b = (_a3 = config.apiKey) != null ? _a3 : process.env.GOOGLE_GENAI_API_KEY) != null ? _b : "";
|
|
3457
3457
|
const modelName = sanitizeModel(config.model);
|
|
3458
3458
|
try {
|
|
3459
3459
|
const { GoogleGenerativeAI: GoogleGenerativeAI2 } = await import("@google/generative-ai");
|
|
@@ -3483,16 +3483,16 @@ var GeminiProvider = class {
|
|
|
3483
3483
|
/** Resolve the embedding client — uses a separate client when the embedding
|
|
3484
3484
|
* API key differs from the LLM API key. */
|
|
3485
3485
|
get embeddingClient() {
|
|
3486
|
-
var
|
|
3487
|
-
if (((
|
|
3486
|
+
var _a3;
|
|
3487
|
+
if (((_a3 = this.embeddingConfig) == null ? void 0 : _a3.apiKey) && this.embeddingConfig.apiKey !== this.llmConfig.apiKey) {
|
|
3488
3488
|
return buildClient(this.embeddingConfig.apiKey);
|
|
3489
3489
|
}
|
|
3490
3490
|
return this.client;
|
|
3491
3491
|
}
|
|
3492
3492
|
/** Resolve the embedding model to use, in order of specificity. */
|
|
3493
3493
|
resolveEmbeddingModel(optionsModel) {
|
|
3494
|
-
var
|
|
3495
|
-
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);
|
|
3496
3496
|
}
|
|
3497
3497
|
/**
|
|
3498
3498
|
* Convert ChatMessage[] to the Gemini contents format.
|
|
@@ -3512,8 +3512,8 @@ var GeminiProvider = class {
|
|
|
3512
3512
|
// ILLMProvider — chat
|
|
3513
3513
|
// -------------------------------------------------------------------------
|
|
3514
3514
|
async chat(messages, context, options) {
|
|
3515
|
-
var
|
|
3516
|
-
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.";
|
|
3517
3517
|
const model = this.client.getGenerativeModel({
|
|
3518
3518
|
model: this.llmConfig.model,
|
|
3519
3519
|
systemInstruction: buildSystemContent(basePrompt, context)
|
|
@@ -3530,8 +3530,8 @@ var GeminiProvider = class {
|
|
|
3530
3530
|
}
|
|
3531
3531
|
chatStream(messages, context, options) {
|
|
3532
3532
|
return __asyncGenerator(this, null, function* () {
|
|
3533
|
-
var
|
|
3534
|
-
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.";
|
|
3535
3535
|
const model = this.client.getGenerativeModel({
|
|
3536
3536
|
model: this.llmConfig.model,
|
|
3537
3537
|
systemInstruction: buildSystemContent(basePrompt, context)
|
|
@@ -3566,11 +3566,11 @@ var GeminiProvider = class {
|
|
|
3566
3566
|
// ILLMProvider — embeddings
|
|
3567
3567
|
// -------------------------------------------------------------------------
|
|
3568
3568
|
async embed(text, options) {
|
|
3569
|
-
var
|
|
3569
|
+
var _a3, _b;
|
|
3570
3570
|
const content = applyPrefix(
|
|
3571
3571
|
text,
|
|
3572
3572
|
options == null ? void 0 : options.taskType,
|
|
3573
|
-
(
|
|
3573
|
+
(_a3 = this.embeddingConfig) == null ? void 0 : _a3.queryPrefix,
|
|
3574
3574
|
(_b = this.embeddingConfig) == null ? void 0 : _b.documentPrefix
|
|
3575
3575
|
);
|
|
3576
3576
|
const modelName = this.resolveEmbeddingModel(options == null ? void 0 : options.model);
|
|
@@ -3587,7 +3587,7 @@ var GeminiProvider = class {
|
|
|
3587
3587
|
const modelName = this.resolveEmbeddingModel(options == null ? void 0 : options.model);
|
|
3588
3588
|
const model = this.embeddingClient.getGenerativeModel({ model: modelName });
|
|
3589
3589
|
const requests = texts.map((text) => {
|
|
3590
|
-
var
|
|
3590
|
+
var _a3, _b;
|
|
3591
3591
|
return {
|
|
3592
3592
|
content: {
|
|
3593
3593
|
role: "user",
|
|
@@ -3595,7 +3595,7 @@ var GeminiProvider = class {
|
|
|
3595
3595
|
text: applyPrefix(
|
|
3596
3596
|
text,
|
|
3597
3597
|
options == null ? void 0 : options.taskType,
|
|
3598
|
-
(
|
|
3598
|
+
(_a3 = this.embeddingConfig) == null ? void 0 : _a3.queryPrefix,
|
|
3599
3599
|
(_b = this.embeddingConfig) == null ? void 0 : _b.documentPrefix
|
|
3600
3600
|
)
|
|
3601
3601
|
}]
|
|
@@ -3612,8 +3612,8 @@ var GeminiProvider = class {
|
|
|
3612
3612
|
throw err;
|
|
3613
3613
|
});
|
|
3614
3614
|
return response.embeddings.map((e) => {
|
|
3615
|
-
var
|
|
3616
|
-
return (
|
|
3615
|
+
var _a3;
|
|
3616
|
+
return (_a3 = e.values) != null ? _a3 : [];
|
|
3617
3617
|
});
|
|
3618
3618
|
}
|
|
3619
3619
|
// -------------------------------------------------------------------------
|
|
@@ -3702,8 +3702,8 @@ var GroqProvider = class {
|
|
|
3702
3702
|
};
|
|
3703
3703
|
}
|
|
3704
3704
|
async chat(messages, context, options) {
|
|
3705
|
-
var
|
|
3706
|
-
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.";
|
|
3707
3707
|
const systemMessage = {
|
|
3708
3708
|
role: "system",
|
|
3709
3709
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3727,8 +3727,8 @@ var GroqProvider = class {
|
|
|
3727
3727
|
}
|
|
3728
3728
|
chatStream(messages, context, options) {
|
|
3729
3729
|
return __asyncGenerator(this, null, function* () {
|
|
3730
|
-
var
|
|
3731
|
-
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.";
|
|
3732
3732
|
const systemMessage = {
|
|
3733
3733
|
role: "system",
|
|
3734
3734
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3862,8 +3862,8 @@ var QwenProvider = class {
|
|
|
3862
3862
|
};
|
|
3863
3863
|
}
|
|
3864
3864
|
async chat(messages, context, options) {
|
|
3865
|
-
var
|
|
3866
|
-
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.";
|
|
3867
3867
|
const systemMessage = {
|
|
3868
3868
|
role: "system",
|
|
3869
3869
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3887,8 +3887,8 @@ var QwenProvider = class {
|
|
|
3887
3887
|
}
|
|
3888
3888
|
chatStream(messages, context, options) {
|
|
3889
3889
|
return __asyncGenerator(this, null, function* () {
|
|
3890
|
-
var
|
|
3891
|
-
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.";
|
|
3892
3892
|
const systemMessage = {
|
|
3893
3893
|
role: "system",
|
|
3894
3894
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3935,8 +3935,8 @@ var QwenProvider = class {
|
|
|
3935
3935
|
return results[0];
|
|
3936
3936
|
}
|
|
3937
3937
|
async batchEmbed(texts, options) {
|
|
3938
|
-
var
|
|
3939
|
-
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";
|
|
3940
3940
|
const apiKey = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.apiKey) != null ? _e : this.llmConfig.apiKey;
|
|
3941
3941
|
const client = apiKey !== this.llmConfig.apiKey ? new OpenAI3({
|
|
3942
3942
|
apiKey,
|
|
@@ -3997,9 +3997,9 @@ var LLM_PROFILES = {
|
|
|
3997
3997
|
|
|
3998
3998
|
// src/llm/providers/UniversalLLMAdapter.ts
|
|
3999
3999
|
function extractContent(obj) {
|
|
4000
|
-
var
|
|
4000
|
+
var _a3, _b, _c;
|
|
4001
4001
|
if (!obj || typeof obj !== "object") return void 0;
|
|
4002
|
-
const choice = (
|
|
4002
|
+
const choice = (_a3 = obj.choices) == null ? void 0 : _a3[0];
|
|
4003
4003
|
if (!choice) return void 0;
|
|
4004
4004
|
if (typeof ((_b = choice.message) == null ? void 0 : _b.content) === "string") return choice.message.content;
|
|
4005
4005
|
if (typeof ((_c = choice.delta) == null ? void 0 : _c.content) === "string") return choice.delta.content;
|
|
@@ -4009,10 +4009,10 @@ function extractContent(obj) {
|
|
|
4009
4009
|
}
|
|
4010
4010
|
var UniversalLLMAdapter = class {
|
|
4011
4011
|
constructor(config) {
|
|
4012
|
-
var
|
|
4012
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h;
|
|
4013
4013
|
this.model = config.model;
|
|
4014
4014
|
const llmConfig = config;
|
|
4015
|
-
const options = (
|
|
4015
|
+
const options = (_a3 = llmConfig.options) != null ? _a3 : {};
|
|
4016
4016
|
let profile = {};
|
|
4017
4017
|
if (typeof options.profile === "string") {
|
|
4018
4018
|
profile = LLM_PROFILES[options.profile] || {};
|
|
@@ -4038,8 +4038,8 @@ var UniversalLLMAdapter = class {
|
|
|
4038
4038
|
});
|
|
4039
4039
|
}
|
|
4040
4040
|
async chat(messages, context) {
|
|
4041
|
-
var
|
|
4042
|
-
const path2 = (
|
|
4041
|
+
var _a3, _b, _c, _d, _e;
|
|
4042
|
+
const path2 = (_a3 = this.opts.chatPath) != null ? _a3 : "/chat/completions";
|
|
4043
4043
|
const safeMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
|
|
4044
4044
|
role: m.role || "user",
|
|
4045
4045
|
content: typeof m.content === "string" ? m.content : m.content != null ? String(m.content) : ""
|
|
@@ -4105,8 +4105,8 @@ ${context != null ? context : "None"}` },
|
|
|
4105
4105
|
*/
|
|
4106
4106
|
chatStream(messages, context) {
|
|
4107
4107
|
return __asyncGenerator(this, null, function* () {
|
|
4108
|
-
var
|
|
4109
|
-
const path2 = (
|
|
4108
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
4109
|
+
const path2 = (_a3 = this.opts.chatPath) != null ? _a3 : "/chat/completions";
|
|
4110
4110
|
const url = `${this.baseUrl.replace(/\/$/, "")}${path2}`;
|
|
4111
4111
|
const extractPath = ((_b = this.opts.responseExtractPath) != null ? _b : "choices[0].message.content").replace("message.content", "delta.content");
|
|
4112
4112
|
const safeMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
|
|
@@ -4232,8 +4232,8 @@ ${context != null ? context : "None"}` },
|
|
|
4232
4232
|
});
|
|
4233
4233
|
}
|
|
4234
4234
|
async embed(text) {
|
|
4235
|
-
var
|
|
4236
|
-
const path2 = (
|
|
4235
|
+
var _a3, _b, _c, _d, _e;
|
|
4236
|
+
const path2 = (_a3 = this.opts.embedPath) != null ? _a3 : "/embeddings";
|
|
4237
4237
|
const payload = this.opts.embedPayloadTemplate ? buildPayload(this.opts.embedPayloadTemplate, { input: text, model: this.model }) : { input: text, model: this.model };
|
|
4238
4238
|
try {
|
|
4239
4239
|
const { data: data2 } = await this.http.post(path2, payload);
|
|
@@ -4322,7 +4322,7 @@ var LLMFactory = class _LLMFactory {
|
|
|
4322
4322
|
];
|
|
4323
4323
|
}
|
|
4324
4324
|
static create(llmConfig, embeddingConfig) {
|
|
4325
|
-
var
|
|
4325
|
+
var _a3, _b, _c;
|
|
4326
4326
|
switch (llmConfig.provider) {
|
|
4327
4327
|
case "openai":
|
|
4328
4328
|
return new OpenAIProvider(llmConfig, embeddingConfig);
|
|
@@ -4341,7 +4341,7 @@ var LLMFactory = class _LLMFactory {
|
|
|
4341
4341
|
case "custom":
|
|
4342
4342
|
return new UniversalLLMAdapter(llmConfig);
|
|
4343
4343
|
default: {
|
|
4344
|
-
const providerName = String((
|
|
4344
|
+
const providerName = String((_a3 = llmConfig.provider) != null ? _a3 : "").toLowerCase();
|
|
4345
4345
|
const customFactory = customProviders.get(providerName);
|
|
4346
4346
|
if (customFactory) {
|
|
4347
4347
|
return customFactory(llmConfig);
|
|
@@ -4443,7 +4443,7 @@ var ProviderRegistry = class {
|
|
|
4443
4443
|
return null;
|
|
4444
4444
|
}
|
|
4445
4445
|
static async loadVectorProviderClass(provider) {
|
|
4446
|
-
var
|
|
4446
|
+
var _a3;
|
|
4447
4447
|
if (this.vectorProviders[provider]) return this.vectorProviders[provider];
|
|
4448
4448
|
switch (provider) {
|
|
4449
4449
|
case "pinecone": {
|
|
@@ -4452,7 +4452,7 @@ var ProviderRegistry = class {
|
|
|
4452
4452
|
}
|
|
4453
4453
|
case "pgvector":
|
|
4454
4454
|
case "postgresql": {
|
|
4455
|
-
const postgresMode = ((
|
|
4455
|
+
const postgresMode = ((_a3 = process.env.POSTGRES_MODE) != null ? _a3 : "multi").toLowerCase();
|
|
4456
4456
|
if (postgresMode === "single") {
|
|
4457
4457
|
const { PostgreSQLProvider: PostgreSQLProvider2 } = await Promise.resolve().then(() => (init_PostgreSQLProvider(), PostgreSQLProvider_exports));
|
|
4458
4458
|
return PostgreSQLProvider2;
|
|
@@ -4675,7 +4675,7 @@ var ConfigValidator = class {
|
|
|
4675
4675
|
// package.json
|
|
4676
4676
|
var package_default = {
|
|
4677
4677
|
name: "@retrivora-ai/rag-engine",
|
|
4678
|
-
version: "2.3.
|
|
4678
|
+
version: "2.3.1",
|
|
4679
4679
|
description: "Retrivora AI is a plug-and-play AI engine for RAG chat experiences \u2014 generic vector DB + LLM provider, embeddable or standalone.",
|
|
4680
4680
|
author: "Abhinav Alkuchi",
|
|
4681
4681
|
license: "UNLICENSED",
|
|
@@ -4980,8 +4980,8 @@ var Reranker = class {
|
|
|
4980
4980
|
return matches.sort((a, b) => b.score - a.score).slice(0, limit);
|
|
4981
4981
|
}
|
|
4982
4982
|
const scoredMatches = matches.map((match) => {
|
|
4983
|
-
var
|
|
4984
|
-
const contentLower = ((
|
|
4983
|
+
var _a3;
|
|
4984
|
+
const contentLower = ((_a3 = match == null ? void 0 : match.content) != null ? _a3 : "").toLowerCase();
|
|
4985
4985
|
let keywordScore = 0;
|
|
4986
4986
|
keywords.forEach((keyword) => {
|
|
4987
4987
|
if (contentLower.includes(keyword)) {
|
|
@@ -5003,8 +5003,8 @@ var Reranker = class {
|
|
|
5003
5003
|
|
|
5004
5004
|
Documents:
|
|
5005
5005
|
${topN.map((m, i) => {
|
|
5006
|
-
var
|
|
5007
|
-
return `[${i}] ${((
|
|
5006
|
+
var _a3;
|
|
5007
|
+
return `[${i}] ${((_a3 = m == null ? void 0 : m.content) != null ? _a3 : "").replace(/\n/g, " ")}`;
|
|
5008
5008
|
}).join("\n")}` }],
|
|
5009
5009
|
"",
|
|
5010
5010
|
{
|
|
@@ -5048,11 +5048,11 @@ var LlamaIndexIngestor = class {
|
|
|
5048
5048
|
* than standard character-count splitting.
|
|
5049
5049
|
*/
|
|
5050
5050
|
async chunk(text, options = {}) {
|
|
5051
|
-
var
|
|
5051
|
+
var _a3, _b;
|
|
5052
5052
|
try {
|
|
5053
5053
|
const { Document, SentenceSplitter, MetadataMode } = await import(`${"llamaindex"}`);
|
|
5054
5054
|
const splitter = new SentenceSplitter({
|
|
5055
|
-
chunkSize: (
|
|
5055
|
+
chunkSize: (_a3 = options.chunkSize) != null ? _a3 : 1e3,
|
|
5056
5056
|
chunkOverlap: (_b = options.chunkOverlap) != null ? _b : 200
|
|
5057
5057
|
});
|
|
5058
5058
|
const doc = new Document({ text, metadata: options.metadata || {} });
|
|
@@ -5161,7 +5161,7 @@ ${error instanceof Error ? error.message : String(error)}`
|
|
|
5161
5161
|
* The agent returns `{ messages: [...] }` — the last message is the final answer.
|
|
5162
5162
|
*/
|
|
5163
5163
|
async run(input, chatHistory = []) {
|
|
5164
|
-
var
|
|
5164
|
+
var _a3, _b, _c;
|
|
5165
5165
|
if (!this.agent) {
|
|
5166
5166
|
throw new Error("[LangChainAgent] Agent not initialized. Call initialize() first.");
|
|
5167
5167
|
}
|
|
@@ -5172,7 +5172,7 @@ ${error instanceof Error ? error.message : String(error)}`
|
|
|
5172
5172
|
const response = await this.agent.invoke({
|
|
5173
5173
|
messages: [...historyMessages, new HumanMessage(input)]
|
|
5174
5174
|
});
|
|
5175
|
-
const lastMessage = (
|
|
5175
|
+
const lastMessage = (_a3 = response == null ? void 0 : response.messages) == null ? void 0 : _a3.at(-1);
|
|
5176
5176
|
if (lastMessage && typeof lastMessage.content === "string") {
|
|
5177
5177
|
return lastMessage.content;
|
|
5178
5178
|
}
|
|
@@ -5224,7 +5224,7 @@ var MCPClient = class {
|
|
|
5224
5224
|
}
|
|
5225
5225
|
}
|
|
5226
5226
|
async connectStdio() {
|
|
5227
|
-
var
|
|
5227
|
+
var _a3;
|
|
5228
5228
|
const cmd = this.config.command;
|
|
5229
5229
|
if (!cmd) {
|
|
5230
5230
|
throw new Error(`[MCPClient] Command option is required for stdio transport on "${this.config.name}"`);
|
|
@@ -5239,7 +5239,7 @@ var MCPClient = class {
|
|
|
5239
5239
|
this.stdioBuffer += data.toString("utf-8");
|
|
5240
5240
|
this.processStdioLines();
|
|
5241
5241
|
});
|
|
5242
|
-
(
|
|
5242
|
+
(_a3 = this.childProcess.stderr) == null ? void 0 : _a3.on("data", (data) => {
|
|
5243
5243
|
console.warn(`[MCPClient] [stderr] [${this.config.name}]:`, data.toString("utf-8"));
|
|
5244
5244
|
});
|
|
5245
5245
|
this.childProcess.on("close", (code) => {
|
|
@@ -5314,14 +5314,14 @@ var MCPClient = class {
|
|
|
5314
5314
|
}
|
|
5315
5315
|
}
|
|
5316
5316
|
async sendNotification(method, params) {
|
|
5317
|
-
var
|
|
5317
|
+
var _a3;
|
|
5318
5318
|
const notification = {
|
|
5319
5319
|
jsonrpc: "2.0",
|
|
5320
5320
|
method,
|
|
5321
5321
|
params
|
|
5322
5322
|
};
|
|
5323
5323
|
if (this.config.transport === "stdio") {
|
|
5324
|
-
if ((
|
|
5324
|
+
if ((_a3 = this.childProcess) == null ? void 0 : _a3.stdin) {
|
|
5325
5325
|
this.childProcess.stdin.write(JSON.stringify(notification) + "\n", "utf-8");
|
|
5326
5326
|
}
|
|
5327
5327
|
} else if (this.sseUrl) {
|
|
@@ -5399,11 +5399,11 @@ var MCPRegistry = class {
|
|
|
5399
5399
|
// src/core/MultiAgentCoordinator.ts
|
|
5400
5400
|
var MultiAgentCoordinator = class {
|
|
5401
5401
|
constructor(options) {
|
|
5402
|
-
var
|
|
5402
|
+
var _a3;
|
|
5403
5403
|
this.llmProvider = options.llmProvider;
|
|
5404
5404
|
this.mcpRegistry = options.mcpRegistry;
|
|
5405
5405
|
this.documentSearch = options.documentSearch;
|
|
5406
|
-
this.maxIterations = (
|
|
5406
|
+
this.maxIterations = (_a3 = options.maxIterations) != null ? _a3 : 5;
|
|
5407
5407
|
}
|
|
5408
5408
|
/**
|
|
5409
5409
|
* Run the multi-agent coordination loop synchronously and return the final response.
|
|
@@ -5455,8 +5455,8 @@ Available Tools:
|
|
|
5455
5455
|
|
|
5456
5456
|
${mcpTools.length > 0 ? "MCP Server Tools:" : ""}
|
|
5457
5457
|
${mcpTools.map((mt) => {
|
|
5458
|
-
var
|
|
5459
|
-
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."}`;
|
|
5460
5460
|
}).join("\n")}
|
|
5461
5461
|
|
|
5462
5462
|
Tool Calling Protocol:
|
|
@@ -5614,6 +5614,100 @@ ${toolResultText}`
|
|
|
5614
5614
|
}
|
|
5615
5615
|
};
|
|
5616
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
|
+
|
|
5617
5711
|
// src/core/BatchProcessor.ts
|
|
5618
5712
|
function isTransientError(error) {
|
|
5619
5713
|
if (!(error instanceof Error)) return false;
|
|
@@ -5637,7 +5731,34 @@ function calculateBackoffDelay(attempt, initialDelayMs, maxDelayMs, multiplier)
|
|
|
5637
5731
|
function sleep(ms) {
|
|
5638
5732
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
5639
5733
|
}
|
|
5640
|
-
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
|
+
}
|
|
5641
5762
|
/**
|
|
5642
5763
|
* Processes an array of items in configurable batches with retry logic.
|
|
5643
5764
|
*
|
|
@@ -5678,7 +5799,7 @@ var BatchProcessor = class {
|
|
|
5678
5799
|
let lastError;
|
|
5679
5800
|
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
5680
5801
|
try {
|
|
5681
|
-
const result = await processor(batch);
|
|
5802
|
+
const result = await _BatchProcessor.executeWithCircuitBreaker(() => processor(batch));
|
|
5682
5803
|
results.push(result);
|
|
5683
5804
|
success = true;
|
|
5684
5805
|
break;
|
|
@@ -5736,7 +5857,7 @@ ${errorMessages}`
|
|
|
5736
5857
|
let lastError;
|
|
5737
5858
|
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
5738
5859
|
try {
|
|
5739
|
-
const result = await processor(item);
|
|
5860
|
+
const result = await _BatchProcessor.executeWithCircuitBreaker(() => processor(item));
|
|
5740
5861
|
results.push(result);
|
|
5741
5862
|
success = true;
|
|
5742
5863
|
break;
|
|
@@ -5809,7 +5930,7 @@ ${errorMessages}`
|
|
|
5809
5930
|
}));
|
|
5810
5931
|
const chunkPromises = chunk.map(async ({ item, originalIndex }) => {
|
|
5811
5932
|
try {
|
|
5812
|
-
const result = await processor(item);
|
|
5933
|
+
const result = await _BatchProcessor.executeWithCircuitBreaker(() => processor(item));
|
|
5813
5934
|
return { success: true, result, index: originalIndex };
|
|
5814
5935
|
} catch (err) {
|
|
5815
5936
|
const error = err instanceof Error ? err : new Error(String(err));
|
|
@@ -5837,6 +5958,12 @@ ${errorMessages}`
|
|
|
5837
5958
|
return { results, errors, totalProcessed, totalFailed };
|
|
5838
5959
|
}
|
|
5839
5960
|
};
|
|
5961
|
+
_BatchProcessor.cb = new CircuitBreaker({
|
|
5962
|
+
failureThreshold: 5,
|
|
5963
|
+
resetTimeoutMs: 3e4,
|
|
5964
|
+
halfOpenMaxCalls: 1
|
|
5965
|
+
});
|
|
5966
|
+
var BatchProcessor = _BatchProcessor;
|
|
5840
5967
|
|
|
5841
5968
|
// src/config/EmbeddingStrategy.ts
|
|
5842
5969
|
var EmbeddingStrategyResolver = class {
|
|
@@ -5934,7 +6061,7 @@ var QueryProcessor = class {
|
|
|
5934
6061
|
* @param validFields Optional list of known filterable fields to look for
|
|
5935
6062
|
*/
|
|
5936
6063
|
static extractQueryFieldHints(question, validFields = []) {
|
|
5937
|
-
var
|
|
6064
|
+
var _a3, _b, _c, _d;
|
|
5938
6065
|
if (!question.trim()) return [];
|
|
5939
6066
|
const hints = /* @__PURE__ */ new Map();
|
|
5940
6067
|
const addHint = (value, field) => {
|
|
@@ -6014,7 +6141,7 @@ var QueryProcessor = class {
|
|
|
6014
6141
|
];
|
|
6015
6142
|
for (const p of universalPatterns) {
|
|
6016
6143
|
for (const match of question.matchAll(p.regex)) {
|
|
6017
|
-
const val = p.group ? (
|
|
6144
|
+
const val = p.group ? (_a3 = match[p.group]) != null ? _a3 : match[0] : match[0];
|
|
6018
6145
|
if (!val) continue;
|
|
6019
6146
|
if (p.field) addHint(val, p.field);
|
|
6020
6147
|
else addHint(val);
|
|
@@ -6238,11 +6365,11 @@ var LLMRouter = class {
|
|
|
6238
6365
|
* When provided it is used directly as the 'default' role without re-constructing.
|
|
6239
6366
|
*/
|
|
6240
6367
|
async initialize(prebuiltDefault) {
|
|
6241
|
-
var
|
|
6368
|
+
var _a3;
|
|
6242
6369
|
const defaultModel = prebuiltDefault != null ? prebuiltDefault : LLMFactory.create(this.config.llm, this.config.embedding);
|
|
6243
6370
|
this.models.set("default", defaultModel);
|
|
6244
6371
|
const envFastModel = process.env.FAST_LLM_MODEL;
|
|
6245
|
-
const providerFastDefault = (
|
|
6372
|
+
const providerFastDefault = (_a3 = FAST_MODEL_DEFAULTS[this.config.llm.provider]) != null ? _a3 : "";
|
|
6246
6373
|
const fastModelName = envFastModel || providerFastDefault;
|
|
6247
6374
|
if (fastModelName && fastModelName !== this.config.llm.model) {
|
|
6248
6375
|
console.log(`[LLMRouter] Fast role \u2192 provider="${this.config.llm.provider}" model="${fastModelName}"`);
|
|
@@ -6261,8 +6388,8 @@ var LLMRouter = class {
|
|
|
6261
6388
|
* Falls back to 'default' if the requested role is not registered.
|
|
6262
6389
|
*/
|
|
6263
6390
|
get(role) {
|
|
6264
|
-
var
|
|
6265
|
-
const provider = (
|
|
6391
|
+
var _a3;
|
|
6392
|
+
const provider = (_a3 = this.models.get(role)) != null ? _a3 : this.models.get("default");
|
|
6266
6393
|
if (!provider) {
|
|
6267
6394
|
throw new Error(`[LLMRouter] No provider registered for role: "${role}". Did you call initialize()?`);
|
|
6268
6395
|
}
|
|
@@ -6348,8 +6475,8 @@ var IntentClassifier = class {
|
|
|
6348
6475
|
numericFieldCount = numericKeys.size;
|
|
6349
6476
|
categoricalFieldCount = catKeys.size;
|
|
6350
6477
|
if (productKeyMatches >= 2 || docs.some((d) => {
|
|
6351
|
-
var
|
|
6352
|
-
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");
|
|
6353
6480
|
})) {
|
|
6354
6481
|
isProductLike = true;
|
|
6355
6482
|
}
|
|
@@ -6631,8 +6758,8 @@ var TextRendererStrategy = class {
|
|
|
6631
6758
|
}
|
|
6632
6759
|
const docs = Array.isArray(data) ? data : [];
|
|
6633
6760
|
const text = docs.map((d) => {
|
|
6634
|
-
var
|
|
6635
|
-
return (
|
|
6761
|
+
var _a3;
|
|
6762
|
+
return (_a3 = d == null ? void 0 : d.content) != null ? _a3 : "";
|
|
6636
6763
|
}).join("\n\n");
|
|
6637
6764
|
return { type: "text", title, data: { content: text || "No detailed content available." } };
|
|
6638
6765
|
}
|
|
@@ -6775,9 +6902,9 @@ var LRUDecisionCache = class {
|
|
|
6775
6902
|
this.maxSize = maxSize;
|
|
6776
6903
|
}
|
|
6777
6904
|
generateKey(context) {
|
|
6778
|
-
var
|
|
6905
|
+
var _a3, _b;
|
|
6779
6906
|
const q = (context.userQuery || "").toLowerCase().trim();
|
|
6780
|
-
const docCount = (_b = (
|
|
6907
|
+
const docCount = (_b = (_a3 = context.retrievedDocuments) == null ? void 0 : _a3.length) != null ? _b : 0;
|
|
6781
6908
|
return `${q}::docs:${docCount}`;
|
|
6782
6909
|
}
|
|
6783
6910
|
get(context) {
|
|
@@ -6878,7 +7005,7 @@ var UITransformer = class _UITransformer {
|
|
|
6878
7005
|
* Prefer `analyzeAndDecide()` in production.
|
|
6879
7006
|
*/
|
|
6880
7007
|
static transform(userQuery, retrievedData, config, trainedSchema, intent) {
|
|
6881
|
-
var
|
|
7008
|
+
var _a3, _b, _c;
|
|
6882
7009
|
if (!retrievedData || retrievedData.length === 0) {
|
|
6883
7010
|
return this.createTextResponse("No data available", "No relevant data found for your query.");
|
|
6884
7011
|
}
|
|
@@ -6898,7 +7025,7 @@ var UITransformer = class _UITransformer {
|
|
|
6898
7025
|
return this.transformToBarChart(filteredData, profile, userQuery, resolvedIntent.visualizationHint === "ranking");
|
|
6899
7026
|
}
|
|
6900
7027
|
if (resolvedIntent.visualizationHint === "distribution") {
|
|
6901
|
-
return (
|
|
7028
|
+
return (_a3 = this.transformToHistogram(profile, userQuery)) != null ? _a3 : this.transformToBarChart(filteredData, profile, userQuery);
|
|
6902
7029
|
}
|
|
6903
7030
|
if (resolvedIntent.visualizationHint === "correlation") {
|
|
6904
7031
|
return (_b = this.transformToScatterPlot(profile, userQuery)) != null ? _b : this.transformToBarChart(filteredData, profile, userQuery);
|
|
@@ -7231,11 +7358,11 @@ ${schemaProfileText}` : ""}`;
|
|
|
7231
7358
|
};
|
|
7232
7359
|
}
|
|
7233
7360
|
static transformToPieChart(data, profile, query = "") {
|
|
7234
|
-
var
|
|
7361
|
+
var _a3;
|
|
7235
7362
|
const dimension = profile ? this.selectDimensionField(profile, query) : void 0;
|
|
7236
7363
|
const categories = dimension ? Array.from(new Set(profile.records.map((record) => {
|
|
7237
|
-
var
|
|
7238
|
-
return String((
|
|
7364
|
+
var _a4;
|
|
7365
|
+
return String((_a4 = record.fields[dimension.key]) != null ? _a4 : "");
|
|
7239
7366
|
}).filter(Boolean))) : this.detectCategories(data);
|
|
7240
7367
|
if (categories.length === 0) return null;
|
|
7241
7368
|
const categoryData = dimension && profile ? this.aggregateProfileByDimension(profile, dimension.key) : this.aggregateByCategory(data, categories);
|
|
@@ -7245,7 +7372,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7245
7372
|
});
|
|
7246
7373
|
return {
|
|
7247
7374
|
type: "pie_chart",
|
|
7248
|
-
title: `Distribution by ${(
|
|
7375
|
+
title: `Distribution by ${(_a3 = dimension == null ? void 0 : dimension.label) != null ? _a3 : "Category"}`,
|
|
7249
7376
|
description: `Showing breakdown across ${pieData.length} categories`,
|
|
7250
7377
|
data: pieData
|
|
7251
7378
|
};
|
|
@@ -7255,8 +7382,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7255
7382
|
const valueField = profile.numericFields[0];
|
|
7256
7383
|
const buckets = /* @__PURE__ */ new Map();
|
|
7257
7384
|
profile.records.forEach((record) => {
|
|
7258
|
-
var
|
|
7259
|
-
const timestamp = String((
|
|
7385
|
+
var _a3, _b, _c;
|
|
7386
|
+
const timestamp = String((_a3 = record.fields[dateField.key]) != null ? _a3 : "");
|
|
7260
7387
|
const value = (_b = this.toFiniteNumber(record.fields[valueField.key])) != null ? _b : 0;
|
|
7261
7388
|
buckets.set(timestamp, ((_c = buckets.get(timestamp)) != null ? _c : 0) + value);
|
|
7262
7389
|
});
|
|
@@ -7269,23 +7396,23 @@ ${schemaProfileText}` : ""}`;
|
|
|
7269
7396
|
};
|
|
7270
7397
|
}
|
|
7271
7398
|
static transformToBarChart(data, profile, query = "", horizontal = false) {
|
|
7272
|
-
var
|
|
7399
|
+
var _a3;
|
|
7273
7400
|
const dimension = profile ? this.selectDimensionField(profile, query) : void 0;
|
|
7274
7401
|
const measure = profile ? this.selectNumericField(profile, query) : void 0;
|
|
7275
7402
|
const aggregate = dimension && profile ? this.aggregateProfileByDimension(profile, dimension.key, measure == null ? void 0 : measure.key) : this.aggregateByCategory(data, this.detectCategories(data));
|
|
7276
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);
|
|
7277
7404
|
const fallbackData = barData.length > 0 ? barData : data.slice(0, 12).map((item, index) => {
|
|
7278
|
-
var
|
|
7405
|
+
var _a4, _b, _c, _d, _e;
|
|
7279
7406
|
const meta = item.metadata || {};
|
|
7280
7407
|
const label = String(
|
|
7281
|
-
(_c = (_b = (
|
|
7408
|
+
(_c = (_b = (_a4 = this.getDynamicVal(meta, "name")) != null ? _a4 : meta.label) != null ? _b : meta.title) != null ? _c : `Result ${index + 1}`
|
|
7282
7409
|
);
|
|
7283
7410
|
const value = (_e = (_d = this.extractNumericValue(meta)) != null ? _d : item.score) != null ? _e : 0;
|
|
7284
7411
|
return { category: label, value: Number(value) };
|
|
7285
7412
|
});
|
|
7286
7413
|
return {
|
|
7287
7414
|
type: horizontal ? "horizontal_bar" : "bar_chart",
|
|
7288
|
-
title: dimension ? `${(
|
|
7415
|
+
title: dimension ? `${(_a3 = measure == null ? void 0 : measure.label) != null ? _a3 : "Count"} by ${dimension.label}` : "Comparison",
|
|
7289
7416
|
description: `Showing ${fallbackData.length} comparable values`,
|
|
7290
7417
|
data: fallbackData
|
|
7291
7418
|
};
|
|
@@ -7320,11 +7447,11 @@ ${schemaProfileText}` : ""}`;
|
|
|
7320
7447
|
if (fields.length < 2) return null;
|
|
7321
7448
|
const [xField, yField] = fields;
|
|
7322
7449
|
const points = profile.records.map((record) => {
|
|
7323
|
-
var
|
|
7450
|
+
var _a3;
|
|
7324
7451
|
const x = this.toFiniteNumber(record.fields[xField.key]);
|
|
7325
7452
|
const y = this.toFiniteNumber(record.fields[yField.key]);
|
|
7326
7453
|
if (x === null || y === null) return null;
|
|
7327
|
-
return { x, y, label: String((
|
|
7454
|
+
return { x, y, label: String((_a3 = this.getRecordLabel(record)) != null ? _a3 : record.id) };
|
|
7328
7455
|
}).filter((point) => point !== null).slice(0, 100);
|
|
7329
7456
|
if (points.length === 0) return null;
|
|
7330
7457
|
return {
|
|
@@ -7354,9 +7481,9 @@ ${schemaProfileText}` : ""}`;
|
|
|
7354
7481
|
static transformToRadarChart(data) {
|
|
7355
7482
|
const attributeMap = {};
|
|
7356
7483
|
data.forEach((item) => {
|
|
7357
|
-
var
|
|
7484
|
+
var _a3, _b, _c;
|
|
7358
7485
|
const meta = item.metadata || {};
|
|
7359
|
-
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");
|
|
7360
7487
|
Object.entries(meta).forEach(([key, val]) => {
|
|
7361
7488
|
if (typeof val === "number" && !["price", "id"].includes(key.toLowerCase())) {
|
|
7362
7489
|
if (!attributeMap[key]) attributeMap[key] = {};
|
|
@@ -7372,8 +7499,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7372
7499
|
title: "Product Comparison",
|
|
7373
7500
|
description: `Comparing ${data.length} items across ${radarData.length} attributes`,
|
|
7374
7501
|
data: radarData.length > 0 ? radarData : data.map((d) => {
|
|
7375
|
-
var
|
|
7376
|
-
return { attribute: ((
|
|
7502
|
+
var _a3;
|
|
7503
|
+
return { attribute: ((_a3 = d == null ? void 0 : d.content) != null ? _a3 : "").substring(0, 40) };
|
|
7377
7504
|
})
|
|
7378
7505
|
};
|
|
7379
7506
|
}
|
|
@@ -7392,8 +7519,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7392
7519
|
return this.createTextResponse(
|
|
7393
7520
|
"Retrieved Context",
|
|
7394
7521
|
data.map((item) => {
|
|
7395
|
-
var
|
|
7396
|
-
return (
|
|
7522
|
+
var _a3;
|
|
7523
|
+
return (_a3 = item == null ? void 0 : item.content) != null ? _a3 : "";
|
|
7397
7524
|
}).join("\n\n"),
|
|
7398
7525
|
`Found ${data.length} relevant results`
|
|
7399
7526
|
);
|
|
@@ -7444,11 +7571,11 @@ ${schemaProfileText}` : ""}`;
|
|
|
7444
7571
|
return null;
|
|
7445
7572
|
}
|
|
7446
7573
|
static normalizeTransformation(payload) {
|
|
7447
|
-
var
|
|
7574
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j;
|
|
7448
7575
|
if (!payload || typeof payload !== "object") return null;
|
|
7449
7576
|
const p = payload;
|
|
7450
7577
|
const type = this.normalizeVisualizationType(
|
|
7451
|
-
String((_c = (_b = (
|
|
7578
|
+
String((_c = (_b = (_a3 = p.type) != null ? _a3 : p.view) != null ? _b : p.chartType) != null ? _c : "")
|
|
7452
7579
|
);
|
|
7453
7580
|
if (!type) return null;
|
|
7454
7581
|
const title = String((_e = (_d = p.title) != null ? _d : p.heading) != null ? _e : "Visualization");
|
|
@@ -7459,7 +7586,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7459
7586
|
return this.validateTransformation(transformation) ? transformation : null;
|
|
7460
7587
|
}
|
|
7461
7588
|
static normalizeVisualizationType(type) {
|
|
7462
|
-
var
|
|
7589
|
+
var _a3;
|
|
7463
7590
|
const mapping = {
|
|
7464
7591
|
pie: "pie_chart",
|
|
7465
7592
|
pie_chart: "pie_chart",
|
|
@@ -7487,7 +7614,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7487
7614
|
product_carousel: "product_carousel",
|
|
7488
7615
|
carousel: "carousel"
|
|
7489
7616
|
};
|
|
7490
|
-
return (
|
|
7617
|
+
return (_a3 = mapping[type.toLowerCase()]) != null ? _a3 : null;
|
|
7491
7618
|
}
|
|
7492
7619
|
static validateTransformation(t) {
|
|
7493
7620
|
const { type, data } = t;
|
|
@@ -7603,7 +7730,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7603
7730
|
}
|
|
7604
7731
|
static profileData(data) {
|
|
7605
7732
|
const records = (data || []).filter((item) => Boolean(item && typeof item === "object")).map((item) => {
|
|
7606
|
-
var
|
|
7733
|
+
var _a3, _b;
|
|
7607
7734
|
const fields2 = {};
|
|
7608
7735
|
Object.entries(item.metadata || {}).forEach(([key, value]) => {
|
|
7609
7736
|
const primitive = this.toPrimitive(value);
|
|
@@ -7612,7 +7739,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7612
7739
|
if (!fields2.content && item.content) fields2.content = item.content.substring(0, 500);
|
|
7613
7740
|
return {
|
|
7614
7741
|
id: item.id,
|
|
7615
|
-
content: (
|
|
7742
|
+
content: (_a3 = item.content) != null ? _a3 : "",
|
|
7616
7743
|
score: (_b = item.score) != null ? _b : 0,
|
|
7617
7744
|
fields: fields2,
|
|
7618
7745
|
source: item
|
|
@@ -7693,16 +7820,16 @@ ${schemaProfileText}` : ""}`;
|
|
|
7693
7820
|
return null;
|
|
7694
7821
|
}
|
|
7695
7822
|
static selectDimensionField(profile, query) {
|
|
7696
|
-
var
|
|
7823
|
+
var _a3, _b;
|
|
7697
7824
|
const productCategory = profile.categoricalFields.find(
|
|
7698
7825
|
(field) => /category|department|collection|type|group|segment|region|country|state|city/i.test(field.key)
|
|
7699
7826
|
);
|
|
7700
7827
|
const ranked = this.rankFieldsByQuery(profile.categoricalFields, query);
|
|
7701
|
-
return (_b = (
|
|
7828
|
+
return (_b = (_a3 = ranked[0]) != null ? _a3 : productCategory) != null ? _b : profile.categoricalFields[0];
|
|
7702
7829
|
}
|
|
7703
7830
|
static selectNumericField(profile, query) {
|
|
7704
|
-
var
|
|
7705
|
-
return (
|
|
7831
|
+
var _a3;
|
|
7832
|
+
return (_a3 = this.rankFieldsByQuery(profile.numericFields, query)[0]) != null ? _a3 : profile.numericFields[0];
|
|
7706
7833
|
}
|
|
7707
7834
|
static rankFieldsByQuery(fields, query) {
|
|
7708
7835
|
const q = query.toLowerCase();
|
|
@@ -7731,8 +7858,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7731
7858
|
static aggregateProfileByDimension(profile, dimensionKey, measureKey) {
|
|
7732
7859
|
const result = {};
|
|
7733
7860
|
profile.records.forEach((record) => {
|
|
7734
|
-
var
|
|
7735
|
-
const category = String((
|
|
7861
|
+
var _a3, _b, _c;
|
|
7862
|
+
const category = String((_a3 = record.fields[dimensionKey]) != null ? _a3 : "Other").trim() || "Other";
|
|
7736
7863
|
const value = measureKey ? (_b = this.toFiniteNumber(record.fields[measureKey])) != null ? _b : 0 : 1;
|
|
7737
7864
|
result[category] = ((_c = result[category]) != null ? _c : 0) + value;
|
|
7738
7865
|
});
|
|
@@ -7812,8 +7939,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7812
7939
|
static aggregateByCategory(data, categories) {
|
|
7813
7940
|
const result = Object.fromEntries(categories.map((c) => [c, 0]));
|
|
7814
7941
|
data.forEach((item) => {
|
|
7815
|
-
var
|
|
7816
|
-
const cat = (
|
|
7942
|
+
var _a3;
|
|
7943
|
+
const cat = (_a3 = this.getProductCategory(item)) != null ? _a3 : "Other";
|
|
7817
7944
|
if (Object.prototype.hasOwnProperty.call(result, cat)) result[cat]++;
|
|
7818
7945
|
else result["Other"] = (result["Other"] || 0) + 1;
|
|
7819
7946
|
});
|
|
@@ -7821,17 +7948,17 @@ ${schemaProfileText}` : ""}`;
|
|
|
7821
7948
|
}
|
|
7822
7949
|
static extractTimeSeriesData(data) {
|
|
7823
7950
|
return data.map((item) => {
|
|
7824
|
-
var
|
|
7951
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
7825
7952
|
const meta = item.metadata || {};
|
|
7826
7953
|
return {
|
|
7827
|
-
timestamp: (_b = (
|
|
7954
|
+
timestamp: (_b = (_a3 = meta.timestamp) != null ? _a3 : meta.date) != null ? _b : (/* @__PURE__ */ new Date()).toISOString(),
|
|
7828
7955
|
value: (_d = (_c = meta.value) != null ? _c : item.score) != null ? _d : 0,
|
|
7829
7956
|
label: (_f = meta.label) != null ? _f : ((_e = item == null ? void 0 : item.content) != null ? _e : "").substring(0, 50)
|
|
7830
7957
|
};
|
|
7831
7958
|
});
|
|
7832
7959
|
}
|
|
7833
7960
|
static extractNumericValue(meta) {
|
|
7834
|
-
var
|
|
7961
|
+
var _a3;
|
|
7835
7962
|
const preferredKeys = [
|
|
7836
7963
|
"value",
|
|
7837
7964
|
"count",
|
|
@@ -7846,7 +7973,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7846
7973
|
"price"
|
|
7847
7974
|
];
|
|
7848
7975
|
for (const key of preferredKeys) {
|
|
7849
|
-
const raw = (
|
|
7976
|
+
const raw = (_a3 = resolveMetadataValue(meta, key)) != null ? _a3 : meta[key];
|
|
7850
7977
|
const value = typeof raw === "number" ? raw : Number(String(raw != null ? raw : "").replace(/[$,% ,]/g, ""));
|
|
7851
7978
|
if (Number.isFinite(value)) return value;
|
|
7852
7979
|
}
|
|
@@ -7941,8 +8068,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7941
8068
|
}, query.includes(normalizedField) ? 3 : 0);
|
|
7942
8069
|
}
|
|
7943
8070
|
static resolveTableCellValue(item, column) {
|
|
7944
|
-
var
|
|
7945
|
-
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);
|
|
7946
8073
|
const meta = item.metadata || {};
|
|
7947
8074
|
const normalizedColumn = this.normalizeComparableField(column);
|
|
7948
8075
|
const exactMetadata = Object.entries(meta).find(
|
|
@@ -7994,8 +8121,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7994
8121
|
let inStock = 0;
|
|
7995
8122
|
let outOfStock = 0;
|
|
7996
8123
|
data.forEach((d) => {
|
|
7997
|
-
var
|
|
7998
|
-
const cat = (
|
|
8124
|
+
var _a3, _b;
|
|
8125
|
+
const cat = (_a3 = this.getProductCategory(d)) != null ? _a3 : "Other";
|
|
7999
8126
|
if (cat === category) {
|
|
8000
8127
|
const quantity = (_b = this.extractStockQuantity(d)) != null ? _b : 1;
|
|
8001
8128
|
if (this.determineStockStatus(d)) inStock += quantity;
|
|
@@ -8041,9 +8168,9 @@ ${schemaProfileText}` : ""}`;
|
|
|
8041
8168
|
}
|
|
8042
8169
|
// ─── Product Extraction ───────────────────────────────────────────────────
|
|
8043
8170
|
static getDynamicVal(meta, uiKey, config, trainedSchema) {
|
|
8044
|
-
var
|
|
8171
|
+
var _a3;
|
|
8045
8172
|
if (!meta) return void 0;
|
|
8046
|
-
const mapping = (
|
|
8173
|
+
const mapping = (_a3 = config == null ? void 0 : config.rag) == null ? void 0 : _a3.uiMapping;
|
|
8047
8174
|
if ((mapping == null ? void 0 : mapping[uiKey]) && meta[mapping[uiKey]] !== void 0) return meta[mapping[uiKey]];
|
|
8048
8175
|
if (trainedSchema && typeof trainedSchema === "object") {
|
|
8049
8176
|
const trainedKey = trainedSchema[uiKey];
|
|
@@ -8052,7 +8179,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
8052
8179
|
return resolveMetadataValue(meta, uiKey);
|
|
8053
8180
|
}
|
|
8054
8181
|
static extractProductInfo(item, config, trainedSchema) {
|
|
8055
|
-
var
|
|
8182
|
+
var _a3, _b;
|
|
8056
8183
|
if (!item) return null;
|
|
8057
8184
|
const meta = item.metadata || {};
|
|
8058
8185
|
const content = item.content || "";
|
|
@@ -8060,7 +8187,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
8060
8187
|
const price = this.getDynamicVal(meta, "price", config, trainedSchema);
|
|
8061
8188
|
const brand = this.getDynamicVal(meta, "brand", config, trainedSchema);
|
|
8062
8189
|
const description = this.cleanProductDescription(
|
|
8063
|
-
(
|
|
8190
|
+
(_a3 = this.extractProductDescriptionFromContent(content)) != null ? _a3 : this.getProductDescriptionValue(meta, config, trainedSchema)
|
|
8064
8191
|
);
|
|
8065
8192
|
if (name || this.isProductData(item)) {
|
|
8066
8193
|
let finalName = name ? String(name) : void 0;
|
|
@@ -8195,10 +8322,10 @@ RULES:
|
|
|
8195
8322
|
}
|
|
8196
8323
|
static buildContextSummary(sources, maxChars = 6e3) {
|
|
8197
8324
|
const items = (sources || []).filter(Boolean).map((s, i) => {
|
|
8198
|
-
var
|
|
8325
|
+
var _a3, _b, _c, _d;
|
|
8199
8326
|
return {
|
|
8200
8327
|
index: i + 1,
|
|
8201
|
-
content: (_b = (
|
|
8328
|
+
content: (_b = (_a3 = s == null ? void 0 : s.content) == null ? void 0 : _a3.substring(0, 400)) != null ? _b : "",
|
|
8202
8329
|
metadata: (_c = s == null ? void 0 : s.metadata) != null ? _c : {},
|
|
8203
8330
|
score: (_d = s == null ? void 0 : s.score) != null ? _d : 0
|
|
8204
8331
|
};
|
|
@@ -8238,7 +8365,7 @@ var SchemaMapper = class {
|
|
|
8238
8365
|
return promise;
|
|
8239
8366
|
}
|
|
8240
8367
|
static async _doTrain(llm, cacheKey, keys) {
|
|
8241
|
-
var
|
|
8368
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
|
|
8242
8369
|
console.log(`[SchemaMapper] \u{1F9E0} Training on new schema keys: ${keys.join(", ")}`);
|
|
8243
8370
|
const propertyList = Object.entries(this.TARGET_PROPERTIES).map(([prop, desc]) => `- ${prop} (${desc})`).join("\n");
|
|
8244
8371
|
const messages = [
|
|
@@ -8254,7 +8381,7 @@ Return a JSON object like {"name":"Title","price":"Price",...}. Omit unmapped pr
|
|
|
8254
8381
|
}
|
|
8255
8382
|
];
|
|
8256
8383
|
try {
|
|
8257
|
-
const baseUrl = (
|
|
8384
|
+
const baseUrl = (_a3 = llm == null ? void 0 : llm.baseUrl) != null ? _a3 : "";
|
|
8258
8385
|
const apiKey = (_b = llm == null ? void 0 : llm.apiKey) != null ? _b : "";
|
|
8259
8386
|
const model = (_c = llm == null ? void 0 : llm.model) != null ? _c : "llama-3.1-8b-instant";
|
|
8260
8387
|
let responseText;
|
|
@@ -8429,9 +8556,9 @@ var Pipeline = class {
|
|
|
8429
8556
|
this.initialised = false;
|
|
8430
8557
|
/** Namespace-specific static cold context cache for CAG */
|
|
8431
8558
|
this.coldContexts = /* @__PURE__ */ new Map();
|
|
8432
|
-
var
|
|
8559
|
+
var _a3, _b, _c, _d, _e;
|
|
8433
8560
|
this.chunker = new DocumentChunker(
|
|
8434
|
-
(_b = (
|
|
8561
|
+
(_b = (_a3 = config.rag) == null ? void 0 : _a3.chunkSize) != null ? _b : 1e3,
|
|
8435
8562
|
(_d = (_c = config.rag) == null ? void 0 : _c.chunkOverlap) != null ? _d : 200
|
|
8436
8563
|
);
|
|
8437
8564
|
if (((_e = config.rag) == null ? void 0 : _e.chunkingStrategy) === "llamaindex") {
|
|
@@ -8447,7 +8574,7 @@ var Pipeline = class {
|
|
|
8447
8574
|
return this.initialised ? this.llmProvider : void 0;
|
|
8448
8575
|
}
|
|
8449
8576
|
async initialize() {
|
|
8450
|
-
var
|
|
8577
|
+
var _a3, _b, _c, _d;
|
|
8451
8578
|
if (this.initialised) return;
|
|
8452
8579
|
const chartInstruction = `You are a helpful assistant. Use the provided context to answer questions accurately.
|
|
8453
8580
|
|
|
@@ -8490,7 +8617,7 @@ var Pipeline = class {
|
|
|
8490
8617
|
this.entityExtractor = new EntityExtractor(this.llmProvider);
|
|
8491
8618
|
}
|
|
8492
8619
|
await this.vectorDB.initialize();
|
|
8493
|
-
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) {
|
|
8494
8621
|
this.mcpRegistry = new MCPRegistry(this.config.mcpServers || []);
|
|
8495
8622
|
this.multiAgentCoordinator = new MultiAgentCoordinator({
|
|
8496
8623
|
llmProvider: this.llmProvider,
|
|
@@ -8508,8 +8635,8 @@ var Pipeline = class {
|
|
|
8508
8635
|
this.initialised = true;
|
|
8509
8636
|
}
|
|
8510
8637
|
async loadColdContext(ns) {
|
|
8511
|
-
var
|
|
8512
|
-
const cagConfig = (
|
|
8638
|
+
var _a3, _b;
|
|
8639
|
+
const cagConfig = (_a3 = this.config.rag) == null ? void 0 : _a3.cag;
|
|
8513
8640
|
if (!cagConfig || !cagConfig.enabled) return;
|
|
8514
8641
|
try {
|
|
8515
8642
|
const coldNs = cagConfig.coldNamespace || ns;
|
|
@@ -8562,12 +8689,12 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8562
8689
|
}
|
|
8563
8690
|
/** Step 1: Chunk the document content. */
|
|
8564
8691
|
async prepareChunks(doc) {
|
|
8565
|
-
var
|
|
8692
|
+
var _a3, _b;
|
|
8566
8693
|
if (this.llamaIngestor) {
|
|
8567
8694
|
return this.llamaIngestor.chunk(doc.content, {
|
|
8568
8695
|
docId: doc.docId,
|
|
8569
8696
|
metadata: doc.metadata,
|
|
8570
|
-
chunkSize: (
|
|
8697
|
+
chunkSize: (_a3 = this.config.rag) == null ? void 0 : _a3.chunkSize,
|
|
8571
8698
|
chunkOverlap: (_b = this.config.rag) == null ? void 0 : _b.chunkOverlap
|
|
8572
8699
|
});
|
|
8573
8700
|
}
|
|
@@ -8665,9 +8792,9 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8665
8792
|
return { reply, sources };
|
|
8666
8793
|
}
|
|
8667
8794
|
async ask(question, history = [], namespace) {
|
|
8668
|
-
var
|
|
8795
|
+
var _a3, _b;
|
|
8669
8796
|
await this.initialize();
|
|
8670
|
-
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) {
|
|
8671
8798
|
return await this.multiAgentCoordinator.run(question, history);
|
|
8672
8799
|
}
|
|
8673
8800
|
const stream = this.askStream(question, history, namespace);
|
|
@@ -8702,9 +8829,9 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8702
8829
|
}
|
|
8703
8830
|
askStream(_0) {
|
|
8704
8831
|
return __asyncGenerator(this, arguments, function* (question, history = [], namespace) {
|
|
8705
|
-
var
|
|
8832
|
+
var _a3, _b;
|
|
8706
8833
|
yield new __await(this.initialize());
|
|
8707
|
-
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) {
|
|
8708
8835
|
const stream2 = this.multiAgentCoordinator.runStream(question, history);
|
|
8709
8836
|
try {
|
|
8710
8837
|
for (var iter = __forAwait(stream2), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
|
|
@@ -8753,10 +8880,10 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8753
8880
|
*/
|
|
8754
8881
|
askStreamInternal(_0) {
|
|
8755
8882
|
return __asyncGenerator(this, arguments, function* (question, history = [], namespace) {
|
|
8756
|
-
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;
|
|
8757
8884
|
yield new __await(this.initialize());
|
|
8758
8885
|
const ns = formatNamespace(namespace != null ? namespace : this.config.projectId);
|
|
8759
|
-
const topK = (_b = (
|
|
8886
|
+
const topK = (_b = (_a3 = this.config.rag) == null ? void 0 : _a3.topK) != null ? _b : 5;
|
|
8760
8887
|
const scoreThreshold = (_d = (_c = this.config.rag) == null ? void 0 : _c.scoreThreshold) != null ? _d : 0.3;
|
|
8761
8888
|
const requestId = `req_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
8762
8889
|
const requestStart = performance.now();
|
|
@@ -8805,8 +8932,8 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8805
8932
|
const rerankStart = performance.now();
|
|
8806
8933
|
const structuredSources = this.applyStructuredFilters(rawSources, filter).filter((s) => Boolean(s && typeof s === "object"));
|
|
8807
8934
|
let fullSources = hasNumericPredicates ? structuredSources : structuredSources.filter((m) => {
|
|
8808
|
-
var
|
|
8809
|
-
return ((
|
|
8935
|
+
var _a4;
|
|
8936
|
+
return ((_a4 = m == null ? void 0 : m.score) != null ? _a4 : 0) >= scoreThreshold;
|
|
8810
8937
|
});
|
|
8811
8938
|
const rerankLimit = Math.max(retrievalLimit, fullSources.length);
|
|
8812
8939
|
const useReranking = arch !== "naive" && (arch === "retrieve-and-rerank" || ((_m = this.config.rag) == null ? void 0 : _m.useReranking));
|
|
@@ -8819,13 +8946,13 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8819
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]
|
|
8820
8947
|
|
|
8821
8948
|
` + promptSources.map((m, i) => {
|
|
8822
|
-
var
|
|
8949
|
+
var _a4;
|
|
8823
8950
|
return `[Source ${i + 1}]
|
|
8824
|
-
${(
|
|
8951
|
+
${(_a4 = m == null ? void 0 : m.content) != null ? _a4 : ""}`;
|
|
8825
8952
|
}).join("\n\n---\n\n") : "No relevant context found.";
|
|
8826
8953
|
const sources = [...fullSources].filter((s) => Boolean(s && typeof s === "object")).sort((a, b) => {
|
|
8827
|
-
var
|
|
8828
|
-
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);
|
|
8829
8956
|
});
|
|
8830
8957
|
if (graphData && graphData.nodes.length > 0) {
|
|
8831
8958
|
const graphContext = graphData.nodes.map(
|
|
@@ -8853,10 +8980,10 @@ ${context}`;
|
|
|
8853
8980
|
yield {
|
|
8854
8981
|
reply: "",
|
|
8855
8982
|
sources: (sources || []).filter((s) => Boolean(s && typeof s === "object")).map((s) => {
|
|
8856
|
-
var
|
|
8983
|
+
var _a4, _b2, _c2;
|
|
8857
8984
|
return {
|
|
8858
8985
|
id: s.id,
|
|
8859
|
-
score: (
|
|
8986
|
+
score: (_a4 = s.score) != null ? _a4 : 0,
|
|
8860
8987
|
content: (_b2 = s == null ? void 0 : s.content) != null ? _b2 : "",
|
|
8861
8988
|
metadata: (_c2 = s == null ? void 0 : s.metadata) != null ? _c2 : {},
|
|
8862
8989
|
namespace: ns
|
|
@@ -9049,11 +9176,11 @@ ${context}`;
|
|
|
9049
9176
|
systemPrompt,
|
|
9050
9177
|
userPrompt: question + finalRestrictionSuffix,
|
|
9051
9178
|
chunks: (sources || []).filter(Boolean).map((s) => {
|
|
9052
|
-
var
|
|
9179
|
+
var _a4, _b2;
|
|
9053
9180
|
return {
|
|
9054
9181
|
id: s.id,
|
|
9055
9182
|
score: s.score,
|
|
9056
|
-
content: (
|
|
9183
|
+
content: (_a4 = s == null ? void 0 : s.content) != null ? _a4 : "",
|
|
9057
9184
|
metadata: (_b2 = s == null ? void 0 : s.metadata) != null ? _b2 : {},
|
|
9058
9185
|
namespace: ns
|
|
9059
9186
|
};
|
|
@@ -9072,7 +9199,7 @@ ${context}`;
|
|
|
9072
9199
|
const telemetryUrl = ((_B = this.config.telemetry) == null ? void 0 : _B.url) || process.env.TELEMETRY_URL || process.env.NEXT_PUBLIC_TELEMETRY_URL || defaultUrl;
|
|
9073
9200
|
const absoluteUrl = telemetryUrl.startsWith("http") ? telemetryUrl : "https://www.retrivora.com" + (telemetryUrl.startsWith("/") ? telemetryUrl : "/" + telemetryUrl);
|
|
9074
9201
|
(async () => {
|
|
9075
|
-
var
|
|
9202
|
+
var _a4, _b2, _c2, _d2, _e2;
|
|
9076
9203
|
try {
|
|
9077
9204
|
let finalTrace = trace;
|
|
9078
9205
|
if (!awaitHallucination && runHallucination) {
|
|
@@ -9081,7 +9208,7 @@ ${context}`;
|
|
|
9081
9208
|
finalTrace = buildTrace(backgroundScoreResult);
|
|
9082
9209
|
}
|
|
9083
9210
|
}
|
|
9084
|
-
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";
|
|
9085
9212
|
const providerName = (finalTrace == null ? void 0 : finalTrace.provider) || ((_b2 = this.config.llm) == null ? void 0 : _b2.provider) || "groq";
|
|
9086
9213
|
const tokenCount = Number(((_c2 = finalTrace == null ? void 0 : finalTrace.tokens) == null ? void 0 : _c2.totalTokens) || 0);
|
|
9087
9214
|
const costEst = Number(((_d2 = finalTrace == null ? void 0 : finalTrace.tokens) == null ? void 0 : _d2.estimatedCostUsd) || 0);
|
|
@@ -9135,7 +9262,7 @@ ${context}`;
|
|
|
9135
9262
|
* Uses an LRU-bounded embedding cache to avoid re-embedding the same query.
|
|
9136
9263
|
*/
|
|
9137
9264
|
async generateUiTransformation(question, sources, cachedSchema, forceDeterministic = false) {
|
|
9138
|
-
var
|
|
9265
|
+
var _a3;
|
|
9139
9266
|
if (!sources || sources.length === 0) {
|
|
9140
9267
|
return UITransformer.transform(question, sources, this.config, cachedSchema);
|
|
9141
9268
|
}
|
|
@@ -9148,7 +9275,7 @@ ${context}`;
|
|
|
9148
9275
|
{ visualizationHint: "product_browse", recommendedChart: "text", filterInStockOnly: false, wantsExplicitTable: false, isTemporal: false, isComparison: false, language: "en" }
|
|
9149
9276
|
);
|
|
9150
9277
|
}
|
|
9151
|
-
const enableLlmUiTransform = ((
|
|
9278
|
+
const enableLlmUiTransform = ((_a3 = this.config.llm.options) == null ? void 0 : _a3.enableLlmUiTransform) === true;
|
|
9152
9279
|
if (forceDeterministic || !enableLlmUiTransform) {
|
|
9153
9280
|
return UITransformer.transform(question, sources, this.config, cachedSchema);
|
|
9154
9281
|
}
|
|
@@ -9166,15 +9293,15 @@ ${context}`;
|
|
|
9166
9293
|
const value = this.resolveNumericPredicateValue(source, predicate);
|
|
9167
9294
|
return value !== null && this.matchesNumericPredicate(value, predicate);
|
|
9168
9295
|
})).sort((a, b) => {
|
|
9169
|
-
var
|
|
9296
|
+
var _a3, _b;
|
|
9170
9297
|
const primary = predicates[0];
|
|
9171
|
-
const aValue = (
|
|
9298
|
+
const aValue = (_a3 = this.resolveNumericPredicateValue(a, primary)) != null ? _a3 : 0;
|
|
9172
9299
|
const bValue = (_b = this.resolveNumericPredicateValue(b, primary)) != null ? _b : 0;
|
|
9173
9300
|
return primary.operator === "lt" || primary.operator === "lte" ? aValue - bValue : bValue - aValue;
|
|
9174
9301
|
});
|
|
9175
9302
|
}
|
|
9176
9303
|
resolveNumericPredicateValue(source, predicate) {
|
|
9177
|
-
var
|
|
9304
|
+
var _a3;
|
|
9178
9305
|
if (!source) return null;
|
|
9179
9306
|
const meta = source.metadata || {};
|
|
9180
9307
|
const field = predicate.field;
|
|
@@ -9187,7 +9314,7 @@ ${context}`;
|
|
|
9187
9314
|
const value = this.toFiniteNumber(Array.isArray(fuzzy) ? fuzzy[1] : fuzzy.value);
|
|
9188
9315
|
if (value !== null) return value;
|
|
9189
9316
|
}
|
|
9190
|
-
const contentValue = this.extractNumericValueFromContent((
|
|
9317
|
+
const contentValue = this.extractNumericValueFromContent((_a3 = source.content) != null ? _a3 : "", field);
|
|
9191
9318
|
if (contentValue !== null) return contentValue;
|
|
9192
9319
|
}
|
|
9193
9320
|
for (const [key, value] of entries) {
|
|
@@ -9243,8 +9370,8 @@ ${context}`;
|
|
|
9243
9370
|
return Number.isFinite(numeric) ? numeric : null;
|
|
9244
9371
|
}
|
|
9245
9372
|
async retrieve(query, options) {
|
|
9246
|
-
var
|
|
9247
|
-
const ns = formatNamespace((
|
|
9373
|
+
var _a3, _b, _c, _d, _e, _f, _g2;
|
|
9374
|
+
const ns = formatNamespace((_a3 = options.namespace) != null ? _a3 : this.config.projectId);
|
|
9248
9375
|
const topK = (_b = options.topK) != null ? _b : 5;
|
|
9249
9376
|
const cacheKey = `${ns}::${query}`;
|
|
9250
9377
|
let queryVector = this.embeddingCache.get(cacheKey);
|
|
@@ -9289,11 +9416,11 @@ ${context}`;
|
|
|
9289
9416
|
namespace: ns,
|
|
9290
9417
|
count: resolvedSources.length,
|
|
9291
9418
|
sample: resolvedSources.slice(0, 2).map((s) => {
|
|
9292
|
-
var
|
|
9419
|
+
var _a4;
|
|
9293
9420
|
return {
|
|
9294
9421
|
id: s == null ? void 0 : s.id,
|
|
9295
9422
|
score: s == null ? void 0 : s.score,
|
|
9296
|
-
contentSnippet: String((
|
|
9423
|
+
contentSnippet: String((_a4 = s == null ? void 0 : s.content) != null ? _a4 : "").substring(0, 150),
|
|
9297
9424
|
metadata: s == null ? void 0 : s.metadata
|
|
9298
9425
|
};
|
|
9299
9426
|
})
|
|
@@ -9307,8 +9434,8 @@ Focus on extracting the core intent and entities. Do not answer the question, ju
|
|
|
9307
9434
|
|
|
9308
9435
|
History:
|
|
9309
9436
|
${(history || []).map((m) => {
|
|
9310
|
-
var
|
|
9311
|
-
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 : ""}`;
|
|
9312
9439
|
}).join("\n")}
|
|
9313
9440
|
|
|
9314
9441
|
New Question: ${question}
|
|
@@ -9335,8 +9462,8 @@ Optimized Search Query:`;
|
|
|
9335
9462
|
const { sources } = await this.retrieve(query, { namespace: ns, topK: 5 });
|
|
9336
9463
|
if (!sources || sources.length === 0) return [];
|
|
9337
9464
|
const context = sources.map((s) => {
|
|
9338
|
-
var
|
|
9339
|
-
return (
|
|
9465
|
+
var _a3;
|
|
9466
|
+
return (_a3 = s == null ? void 0 : s.content) != null ? _a3 : "";
|
|
9340
9467
|
}).join("\n\n---\n\n");
|
|
9341
9468
|
const prompt = `Based on the following snippets from a document, what are at least 5 short, relevant questions a user might ask?
|
|
9342
9469
|
Focus on questions that can be answered by the context.
|
|
@@ -9474,18 +9601,200 @@ var ProviderHealthCheck = class {
|
|
|
9474
9601
|
}
|
|
9475
9602
|
};
|
|
9476
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
|
+
|
|
9477
9786
|
// src/core/VectorPlugin.ts
|
|
9478
9787
|
var VectorPlugin = class {
|
|
9479
9788
|
constructor(hostConfig) {
|
|
9480
9789
|
const resolvedConfig = ConfigResolver.resolve(hostConfig);
|
|
9481
9790
|
this.config = resolvedConfig;
|
|
9482
9791
|
this.validationPromise = (async () => {
|
|
9483
|
-
var
|
|
9792
|
+
var _a3;
|
|
9484
9793
|
await ConfigValidator.validateAndThrow(resolvedConfig);
|
|
9485
9794
|
LicenseVerifier.verify(
|
|
9486
9795
|
resolvedConfig.licenseKey,
|
|
9487
9796
|
resolvedConfig.projectId,
|
|
9488
|
-
(
|
|
9797
|
+
(_a3 = resolvedConfig.vectorDb) == null ? void 0 : _a3.provider
|
|
9489
9798
|
);
|
|
9490
9799
|
})();
|
|
9491
9800
|
this.validationPromise.catch(() => {
|
|
@@ -9519,16 +9828,32 @@ var VectorPlugin = class {
|
|
|
9519
9828
|
this.config.embedding
|
|
9520
9829
|
);
|
|
9521
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
|
+
}
|
|
9522
9838
|
/**
|
|
9523
9839
|
* Run a chat query.
|
|
9524
9840
|
*/
|
|
9525
9841
|
async chat(message, history = [], namespace) {
|
|
9842
|
+
var _a3;
|
|
9526
9843
|
try {
|
|
9527
9844
|
await this.validationPromise;
|
|
9528
9845
|
} catch (err) {
|
|
9529
9846
|
throw wrapError(err, "CONFIGURATION_ERROR");
|
|
9530
9847
|
}
|
|
9531
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
|
+
}
|
|
9532
9857
|
return await this.pipeline.ask(message, history, namespace);
|
|
9533
9858
|
} catch (err) {
|
|
9534
9859
|
const msg = String(err);
|
|
@@ -9536,6 +9861,9 @@ var VectorPlugin = class {
|
|
|
9536
9861
|
if (msg.includes("Embed") || msg.includes("embed")) {
|
|
9537
9862
|
defaultCode = "EMBEDDING_FAILED";
|
|
9538
9863
|
}
|
|
9864
|
+
if (msg.toLowerCase().includes("token limit")) {
|
|
9865
|
+
defaultCode = "RATE_LIMITED";
|
|
9866
|
+
}
|
|
9539
9867
|
throw wrapError(err, defaultCode);
|
|
9540
9868
|
}
|
|
9541
9869
|
}
|
|
@@ -9544,12 +9872,21 @@ var VectorPlugin = class {
|
|
|
9544
9872
|
*/
|
|
9545
9873
|
chatStream(_0) {
|
|
9546
9874
|
return __asyncGenerator(this, arguments, function* (message, history = [], namespace) {
|
|
9875
|
+
var _a3;
|
|
9547
9876
|
try {
|
|
9548
9877
|
yield new __await(this.validationPromise);
|
|
9549
9878
|
} catch (err) {
|
|
9550
9879
|
throw wrapError(err, "CONFIGURATION_ERROR");
|
|
9551
9880
|
}
|
|
9552
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
|
+
}
|
|
9553
9890
|
const stream = this.pipeline.askStream(message, history, namespace);
|
|
9554
9891
|
try {
|
|
9555
9892
|
for (var iter = __forAwait(stream), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
|
|
@@ -9572,6 +9909,9 @@ var VectorPlugin = class {
|
|
|
9572
9909
|
if (msg.includes("Embed") || msg.includes("embed")) {
|
|
9573
9910
|
defaultCode = "EMBEDDING_FAILED";
|
|
9574
9911
|
}
|
|
9912
|
+
if (msg.toLowerCase().includes("token limit")) {
|
|
9913
|
+
defaultCode = "RATE_LIMITED";
|
|
9914
|
+
}
|
|
9575
9915
|
throw wrapError(err, defaultCode);
|
|
9576
9916
|
}
|
|
9577
9917
|
});
|
|
@@ -9619,8 +9959,8 @@ var DocumentParser = class {
|
|
|
9619
9959
|
* Extract text from a File or Buffer based on its type.
|
|
9620
9960
|
*/
|
|
9621
9961
|
static async parse(file, fileName, mimeType) {
|
|
9622
|
-
var
|
|
9623
|
-
const extension = ((
|
|
9962
|
+
var _a3;
|
|
9963
|
+
const extension = ((_a3 = fileName.split(".").pop()) == null ? void 0 : _a3.toLowerCase()) || "";
|
|
9624
9964
|
if (extension === "txt" || extension === "md" || mimeType === "text/plain" || mimeType === "text/markdown") {
|
|
9625
9965
|
return this.readAsText(file);
|
|
9626
9966
|
}
|
|
@@ -9711,9 +10051,9 @@ var DatabaseStorage = class {
|
|
|
9711
10051
|
this.fallbackDir = this.isServerless ? path.join(os.tmpdir(), ".retrivora") : path.join(process.cwd(), ".retrivora");
|
|
9712
10052
|
this.historyFile = path.join(this.fallbackDir, "history.json");
|
|
9713
10053
|
this.feedbackFile = path.join(this.fallbackDir, "feedback.json");
|
|
9714
|
-
var
|
|
10054
|
+
var _a3, _b, _c, _d, _e;
|
|
9715
10055
|
this.config = config;
|
|
9716
|
-
this.provider = ((
|
|
10056
|
+
this.provider = ((_a3 = config.vectorDb) == null ? void 0 : _a3.provider) || "fs";
|
|
9717
10057
|
const rawHistoryTable = ((_c = (_b = config.rag) == null ? void 0 : _b.history) == null ? void 0 : _c.tableName) || "retrivora_history";
|
|
9718
10058
|
const rawFeedbackTable = ((_e = (_d = config.rag) == null ? void 0 : _d.feedback) == null ? void 0 : _e.tableName) || "retrivora_feedback";
|
|
9719
10059
|
this.historyTableName = rawHistoryTable.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
@@ -9748,16 +10088,16 @@ var DatabaseStorage = class {
|
|
|
9748
10088
|
}
|
|
9749
10089
|
}
|
|
9750
10090
|
checkHistoryEnabled() {
|
|
9751
|
-
var
|
|
10091
|
+
var _a3, _b;
|
|
9752
10092
|
this.checkPremiumSubscription();
|
|
9753
|
-
if (((_b = (
|
|
10093
|
+
if (((_b = (_a3 = this.config.rag) == null ? void 0 : _a3.history) == null ? void 0 : _b.enabled) === false) {
|
|
9754
10094
|
throw new Error("[Retrivora SDK] Chat History is disabled in RagConfig.");
|
|
9755
10095
|
}
|
|
9756
10096
|
}
|
|
9757
10097
|
checkFeedbackEnabled() {
|
|
9758
|
-
var
|
|
10098
|
+
var _a3, _b;
|
|
9759
10099
|
this.checkPremiumSubscription();
|
|
9760
|
-
if (((_b = (
|
|
10100
|
+
if (((_b = (_a3 = this.config.rag) == null ? void 0 : _a3.feedback) == null ? void 0 : _b.enabled) === false) {
|
|
9761
10101
|
throw new Error("[Retrivora SDK] User Feedback is disabled in RagConfig.");
|
|
9762
10102
|
}
|
|
9763
10103
|
}
|
|
@@ -9924,8 +10264,11 @@ var DatabaseStorage = class {
|
|
|
9924
10264
|
this.writeLocalFile(this.historyFile, history);
|
|
9925
10265
|
}
|
|
9926
10266
|
}
|
|
9927
|
-
async getHistory(sessionId) {
|
|
10267
|
+
async getHistory(sessionId, projectIds) {
|
|
9928
10268
|
this.checkHistoryEnabled();
|
|
10269
|
+
if (projectIds && projectIds.length > 0 && !this.sessionInScope(sessionId, projectIds)) {
|
|
10270
|
+
return [];
|
|
10271
|
+
}
|
|
9929
10272
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
9930
10273
|
const pool = await this.getPGPool();
|
|
9931
10274
|
const res = await pool.query(
|
|
@@ -9955,8 +10298,11 @@ var DatabaseStorage = class {
|
|
|
9955
10298
|
return history.filter((h) => h.session_id === sessionId).sort((a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime());
|
|
9956
10299
|
}
|
|
9957
10300
|
}
|
|
9958
|
-
async clearHistory(sessionId) {
|
|
10301
|
+
async clearHistory(sessionId, projectIds) {
|
|
9959
10302
|
this.checkHistoryEnabled();
|
|
10303
|
+
if (projectIds && projectIds.length > 0 && !this.sessionInScope(sessionId, projectIds)) {
|
|
10304
|
+
return;
|
|
10305
|
+
}
|
|
9960
10306
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
9961
10307
|
const pool = await this.getPGPool();
|
|
9962
10308
|
await pool.query(`DELETE FROM ${this.historyTableName} WHERE session_id = $1`, [sessionId]);
|
|
@@ -9975,21 +10321,36 @@ var DatabaseStorage = class {
|
|
|
9975
10321
|
this.writeLocalFile(this.feedbackFile, filteredFeedback);
|
|
9976
10322
|
}
|
|
9977
10323
|
}
|
|
9978
|
-
|
|
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) {
|
|
9979
10338
|
this.checkHistoryEnabled();
|
|
10339
|
+
let raw = [];
|
|
9980
10340
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
9981
10341
|
const pool = await this.getPGPool();
|
|
9982
10342
|
const res = await pool.query(`SELECT DISTINCT session_id FROM ${this.historyTableName}`);
|
|
9983
|
-
|
|
10343
|
+
raw = res.rows.map((r) => r.session_id);
|
|
9984
10344
|
} else if (this.provider === "mongodb") {
|
|
9985
10345
|
await this.getMongoClient();
|
|
9986
10346
|
const db = this.getMongoDb();
|
|
9987
|
-
|
|
10347
|
+
raw = await db.collection(this.historyTableName).distinct("session_id");
|
|
9988
10348
|
} else {
|
|
9989
10349
|
const history = this.readLocalFile(this.historyFile);
|
|
9990
|
-
|
|
9991
|
-
return Array.from(sessions);
|
|
10350
|
+
raw = Array.from(new Set(history.map((h) => h.session_id)));
|
|
9992
10351
|
}
|
|
10352
|
+
if (!projectIds || projectIds.length === 0) return raw;
|
|
10353
|
+
return raw.filter((sid) => this.sessionInScope(sid, projectIds));
|
|
9993
10354
|
}
|
|
9994
10355
|
// ─── Feedback Operations ──────────────────────────────────────────────────
|
|
9995
10356
|
async saveFeedback(feedback) {
|
|
@@ -10042,8 +10403,9 @@ var DatabaseStorage = class {
|
|
|
10042
10403
|
this.writeLocalFile(this.feedbackFile, list);
|
|
10043
10404
|
}
|
|
10044
10405
|
}
|
|
10045
|
-
async getFeedback(messageId) {
|
|
10406
|
+
async getFeedback(messageId, projectIds) {
|
|
10046
10407
|
this.checkFeedbackEnabled();
|
|
10408
|
+
let item = null;
|
|
10047
10409
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
10048
10410
|
const pool = await this.getPGPool();
|
|
10049
10411
|
const res = await pool.query(
|
|
@@ -10052,28 +10414,34 @@ var DatabaseStorage = class {
|
|
|
10052
10414
|
WHERE message_id = $1`,
|
|
10053
10415
|
[messageId]
|
|
10054
10416
|
);
|
|
10055
|
-
|
|
10417
|
+
item = res.rows[0] || null;
|
|
10056
10418
|
} else if (this.provider === "mongodb") {
|
|
10057
10419
|
await this.getMongoClient();
|
|
10058
10420
|
const db = this.getMongoDb();
|
|
10059
10421
|
const col = db.collection(this.feedbackTableName);
|
|
10060
|
-
const
|
|
10061
|
-
if (
|
|
10062
|
-
|
|
10063
|
-
|
|
10064
|
-
|
|
10065
|
-
|
|
10066
|
-
|
|
10067
|
-
|
|
10068
|
-
|
|
10069
|
-
|
|
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
|
+
}
|
|
10070
10433
|
} else {
|
|
10071
10434
|
const list = this.readLocalFile(this.feedbackFile);
|
|
10072
|
-
|
|
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;
|
|
10073
10439
|
}
|
|
10440
|
+
return item;
|
|
10074
10441
|
}
|
|
10075
|
-
async listFeedback() {
|
|
10442
|
+
async listFeedback(projectIds) {
|
|
10076
10443
|
this.checkFeedbackEnabled();
|
|
10444
|
+
let raw = [];
|
|
10077
10445
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
10078
10446
|
const pool = await this.getPGPool();
|
|
10079
10447
|
const res = await pool.query(
|
|
@@ -10081,13 +10449,13 @@ var DatabaseStorage = class {
|
|
|
10081
10449
|
FROM ${this.feedbackTableName}
|
|
10082
10450
|
ORDER BY created_at DESC`
|
|
10083
10451
|
);
|
|
10084
|
-
|
|
10452
|
+
raw = res.rows;
|
|
10085
10453
|
} else if (this.provider === "mongodb") {
|
|
10086
10454
|
await this.getMongoClient();
|
|
10087
10455
|
const db = this.getMongoDb();
|
|
10088
10456
|
const col = db.collection(this.feedbackTableName);
|
|
10089
10457
|
const items = await col.find({}).sort({ created_at: -1 }).toArray();
|
|
10090
|
-
|
|
10458
|
+
raw = items.map((item) => ({
|
|
10091
10459
|
id: item.id,
|
|
10092
10460
|
messageId: item.message_id,
|
|
10093
10461
|
sessionId: item.session_id,
|
|
@@ -10097,8 +10465,10 @@ var DatabaseStorage = class {
|
|
|
10097
10465
|
}));
|
|
10098
10466
|
} else {
|
|
10099
10467
|
const list = this.readLocalFile(this.feedbackFile);
|
|
10100
|
-
|
|
10468
|
+
raw = [...list].sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime());
|
|
10101
10469
|
}
|
|
10470
|
+
if (!projectIds || projectIds.length === 0) return raw;
|
|
10471
|
+
return raw.filter((f) => this.sessionInScope(f.sessionId, projectIds));
|
|
10102
10472
|
}
|
|
10103
10473
|
async disconnect() {
|
|
10104
10474
|
if (this.pgPool) {
|
|
@@ -10161,8 +10531,8 @@ var _g = global;
|
|
|
10161
10531
|
var _a;
|
|
10162
10532
|
var rateLimiter = (_a = _g.__retrivoraRateLimiter) != null ? _a : _g.__retrivoraRateLimiter = new RateLimiter(6e4, 30);
|
|
10163
10533
|
function getRateLimitKey(req) {
|
|
10164
|
-
var
|
|
10165
|
-
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";
|
|
10166
10536
|
return `ip:${ip}`;
|
|
10167
10537
|
}
|
|
10168
10538
|
function checkRateLimit(req) {
|
|
@@ -10184,6 +10554,66 @@ function checkRateLimit(req) {
|
|
|
10184
10554
|
}
|
|
10185
10555
|
return null;
|
|
10186
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
|
+
}
|
|
10187
10617
|
var MAX_MESSAGE_LENGTH = 8e3;
|
|
10188
10618
|
function sanitizeInput(raw) {
|
|
10189
10619
|
const stripped = raw.replace(/[\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F-\u009F]/g, "");
|
|
@@ -10205,7 +10635,7 @@ function getOrCreatePlugin(configOrPlugin) {
|
|
|
10205
10635
|
return _g[cacheKey];
|
|
10206
10636
|
}
|
|
10207
10637
|
function reportTelemetry(req, plugin, action, status, details, trace) {
|
|
10208
|
-
var
|
|
10638
|
+
var _a3, _b, _c, _d, _e, _f, _g2;
|
|
10209
10639
|
try {
|
|
10210
10640
|
const config = plugin.getConfig();
|
|
10211
10641
|
const licenseKey = config.licenseKey || process.env.RAG_LICENSE_KEY || process.env.RETRIVORA_LICENSE_KEY || process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY;
|
|
@@ -10220,7 +10650,7 @@ function reportTelemetry(req, plugin, action, status, details, trace) {
|
|
|
10220
10650
|
absoluteUrl = `${proto}://${host}${telemetryUrl}`;
|
|
10221
10651
|
}
|
|
10222
10652
|
const projectId = config.projectId || "default";
|
|
10223
|
-
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";
|
|
10224
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";
|
|
10225
10655
|
const tokens = Number(((_e = trace == null ? void 0 : trace.tokens) == null ? void 0 : _e.totalTokens) || (trace == null ? void 0 : trace.totalTokens) || 0);
|
|
10226
10656
|
const costUsd = Number(((_f = trace == null ? void 0 : trace.tokens) == null ? void 0 : _f.estimatedCostUsd) || (trace == null ? void 0 : trace.costUsd) || 0);
|
|
@@ -10244,7 +10674,6 @@ function reportTelemetry(req, plugin, action, status, details, trace) {
|
|
|
10244
10674
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
10245
10675
|
details
|
|
10246
10676
|
};
|
|
10247
|
-
console.log(`[Retrivora SDK Telemetry] Dispatching telemetry -> Feature: "${action}", Status: "${status}", Project: "${projectId}", Latency: ${latencyMs}ms`);
|
|
10248
10677
|
fetch(absoluteUrl, {
|
|
10249
10678
|
method: "POST",
|
|
10250
10679
|
headers: {
|
|
@@ -10302,14 +10731,39 @@ function createChatHandler(configOrPlugin, options) {
|
|
|
10302
10731
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
10303
10732
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
10304
10733
|
return async function POST(req, context) {
|
|
10305
|
-
var
|
|
10734
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
10306
10735
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10307
10736
|
if (authResult) return authResult;
|
|
10308
10737
|
const rateLimited = checkRateLimit(req);
|
|
10309
10738
|
if (rateLimited) return rateLimited;
|
|
10739
|
+
const config = plugin.getConfig();
|
|
10310
10740
|
try {
|
|
10311
10741
|
const body = await req.json();
|
|
10312
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
|
+
}
|
|
10313
10767
|
let rawMessage = bodyObj.message;
|
|
10314
10768
|
if (!rawMessage && Array.isArray(bodyObj.messages) && bodyObj.messages.length > 0) {
|
|
10315
10769
|
const lastMsg = bodyObj.messages[bodyObj.messages.length - 1];
|
|
@@ -10341,7 +10795,7 @@ function createChatHandler(configOrPlugin, options) {
|
|
|
10341
10795
|
uiTransformation: result.ui_transformation,
|
|
10342
10796
|
trace: result.trace
|
|
10343
10797
|
}).catch((err) => console.warn("[createChatHandler] Failed to save assistant message:", err));
|
|
10344
|
-
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);
|
|
10345
10799
|
return NextResponse.json(__spreadProps(__spreadValues({}, result), {
|
|
10346
10800
|
messageId: assistantMsgId,
|
|
10347
10801
|
userMessageId: userMsgId
|
|
@@ -10358,14 +10812,15 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10358
10812
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
10359
10813
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
10360
10814
|
return async function POST(req, context) {
|
|
10361
|
-
var
|
|
10815
|
+
var _a3, _b, _c;
|
|
10362
10816
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10363
10817
|
if (authResult) return authResult;
|
|
10364
10818
|
const rateLimited = checkRateLimit(req);
|
|
10365
10819
|
if (rateLimited) return rateLimited;
|
|
10820
|
+
const config = plugin.getConfig();
|
|
10366
10821
|
let body;
|
|
10367
10822
|
try {
|
|
10368
|
-
if ((
|
|
10823
|
+
if ((_a3 = req.headers.get("content-type")) == null ? void 0 : _a3.includes("multipart/form-data")) {
|
|
10369
10824
|
const uploader = createUploadHandler(plugin, { onAuthorize });
|
|
10370
10825
|
return uploader(req);
|
|
10371
10826
|
}
|
|
@@ -10377,6 +10832,30 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10377
10832
|
});
|
|
10378
10833
|
}
|
|
10379
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
|
+
}
|
|
10380
10859
|
let rawMessage = bodyObj.message;
|
|
10381
10860
|
if (!rawMessage && Array.isArray(bodyObj.messages) && bodyObj.messages.length > 0) {
|
|
10382
10861
|
const lastMsg = bodyObj.messages[bodyObj.messages.length - 1];
|
|
@@ -10406,7 +10885,7 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10406
10885
|
let isActive = true;
|
|
10407
10886
|
const stream = new ReadableStream({
|
|
10408
10887
|
async start(controller) {
|
|
10409
|
-
var
|
|
10888
|
+
var _a4, _b2, _c2, _d, _e;
|
|
10410
10889
|
const enqueue = (text) => {
|
|
10411
10890
|
if (!isActive) return;
|
|
10412
10891
|
try {
|
|
@@ -10439,7 +10918,7 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10439
10918
|
let uiTransformation = responseChunk == null ? void 0 : responseChunk.ui_transformation;
|
|
10440
10919
|
if (sources.length > 0) {
|
|
10441
10920
|
try {
|
|
10442
|
-
uiTransformation = (
|
|
10921
|
+
uiTransformation = (_a4 = responseChunk == null ? void 0 : responseChunk.ui_transformation) != null ? _a4 : UITransformer.transform(message, sources, plugin.getConfig());
|
|
10443
10922
|
if (uiTransformation) {
|
|
10444
10923
|
enqueue(sseUIFrame(uiTransformation));
|
|
10445
10924
|
}
|
|
@@ -10463,7 +10942,7 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10463
10942
|
uiTransformation,
|
|
10464
10943
|
trace: responseChunk == null ? void 0 : responseChunk.trace
|
|
10465
10944
|
}).catch((err) => console.warn("[createStreamHandler] Failed to save assistant message:", err));
|
|
10466
|
-
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);
|
|
10467
10946
|
}
|
|
10468
10947
|
}
|
|
10469
10948
|
} catch (temp) {
|
|
@@ -10513,12 +10992,36 @@ function createIngestHandler(configOrPlugin, options) {
|
|
|
10513
10992
|
return async function POST(req, context) {
|
|
10514
10993
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10515
10994
|
if (authResult) return authResult;
|
|
10995
|
+
const config = plugin.getConfig();
|
|
10516
10996
|
try {
|
|
10517
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;
|
|
10518
11000
|
const { documents, namespace } = body;
|
|
10519
11001
|
if (!Array.isArray(documents) || documents.length === 0) {
|
|
10520
11002
|
return NextResponse.json({ error: "documents array is required" }, { status: 400 });
|
|
10521
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
|
+
}
|
|
10522
11025
|
const results = await plugin.ingest(documents, namespace);
|
|
10523
11026
|
reportTelemetry(req, plugin, "DOCUMENT_INGESTION", "success", `Ingested ${documents.length} document(s)`);
|
|
10524
11027
|
return NextResponse.json({ results });
|
|
@@ -10555,7 +11058,7 @@ function createLicenseHandler(configOrPlugin, options) {
|
|
|
10555
11058
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
10556
11059
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
10557
11060
|
return async function POST(req) {
|
|
10558
|
-
var
|
|
11061
|
+
var _a3;
|
|
10559
11062
|
if (req) {
|
|
10560
11063
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10561
11064
|
if (authResult) return authResult;
|
|
@@ -10563,7 +11066,7 @@ function createLicenseHandler(configOrPlugin, options) {
|
|
|
10563
11066
|
try {
|
|
10564
11067
|
const body = await req.json().catch(() => ({}));
|
|
10565
11068
|
const config = plugin.getConfig();
|
|
10566
|
-
const rawKey = req.headers.get("x-license-key") || (body == null ? void 0 : body.licenseKey) || ((
|
|
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 || "";
|
|
10567
11070
|
const licenseKey = (rawKey || "").trim().replace(/^["']|["']$/g, "").trim();
|
|
10568
11071
|
const projectId = (body == null ? void 0 : body.projectId) || config.projectId || "my-rag-app";
|
|
10569
11072
|
const payload = LicenseVerifier.verify(licenseKey, projectId);
|
|
@@ -10598,6 +11101,9 @@ function createUploadHandler(configOrPlugin, options) {
|
|
|
10598
11101
|
return async function POST(req, context) {
|
|
10599
11102
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10600
11103
|
if (authResult) return authResult;
|
|
11104
|
+
const config = plugin.getConfig();
|
|
11105
|
+
const licenseCheck = enforceLicense(req, config);
|
|
11106
|
+
if (!licenseCheck.ok) return licenseCheck.response;
|
|
10601
11107
|
try {
|
|
10602
11108
|
const formData = await req.formData();
|
|
10603
11109
|
const files = formData.getAll("files");
|
|
@@ -10607,6 +11113,26 @@ function createUploadHandler(configOrPlugin, options) {
|
|
|
10607
11113
|
if (!files || files.length === 0) {
|
|
10608
11114
|
return NextResponse.json({ error: "No files provided" }, { status: 400 });
|
|
10609
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
|
+
}
|
|
10610
11136
|
const documents = [];
|
|
10611
11137
|
for (const file of files) {
|
|
10612
11138
|
const isExcel = file.name.toLowerCase().endsWith(".xlsx") || file.name.toLowerCase().endsWith(".xls") || file.type.includes("spreadsheet") || file.type.includes("excel");
|
|
@@ -10716,13 +11242,22 @@ function createSuggestionsHandler(configOrPlugin, options) {
|
|
|
10716
11242
|
return async function handler(req) {
|
|
10717
11243
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10718
11244
|
if (authResult) return authResult;
|
|
11245
|
+
const config = plugin.getConfig();
|
|
11246
|
+
const licenseCheck = enforceLicense(req, config);
|
|
11247
|
+
if (!licenseCheck.ok) return licenseCheck.response;
|
|
10719
11248
|
try {
|
|
10720
11249
|
let query = "";
|
|
10721
11250
|
let namespace = void 0;
|
|
11251
|
+
let bodyLicenseKey = void 0;
|
|
10722
11252
|
if (req.method === "POST") {
|
|
10723
11253
|
const body = await req.json().catch(() => ({}));
|
|
10724
11254
|
query = body.query || "";
|
|
10725
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
|
+
}
|
|
10726
11261
|
} else {
|
|
10727
11262
|
const url = new URL(req.url);
|
|
10728
11263
|
query = url.searchParams.get("query") || "";
|
|
@@ -10745,14 +11280,16 @@ function createHistoryHandler(configOrPlugin, options) {
|
|
|
10745
11280
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
10746
11281
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
10747
11282
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
11283
|
+
const onResolveScope = options == null ? void 0 : options.onResolveScope;
|
|
10748
11284
|
return async function handler(req) {
|
|
10749
11285
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10750
11286
|
if (authResult) return authResult;
|
|
11287
|
+
const scope = onResolveScope ? await onResolveScope(req) : void 0;
|
|
10751
11288
|
const url = new URL(req.url);
|
|
10752
11289
|
const sessionId = url.searchParams.get("sessionId") || "default";
|
|
10753
11290
|
if (req.method === "GET") {
|
|
10754
11291
|
try {
|
|
10755
|
-
const history = await storage.getHistory(sessionId);
|
|
11292
|
+
const history = await storage.getHistory(sessionId, scope);
|
|
10756
11293
|
return NextResponse.json({ history });
|
|
10757
11294
|
} catch (err) {
|
|
10758
11295
|
const message = err instanceof Error ? err.message : "Failed to fetch history";
|
|
@@ -10762,7 +11299,7 @@ function createHistoryHandler(configOrPlugin, options) {
|
|
|
10762
11299
|
try {
|
|
10763
11300
|
const body = await req.json().catch(() => ({}));
|
|
10764
11301
|
const sid = body.sessionId || sessionId;
|
|
10765
|
-
await storage.clearHistory(sid);
|
|
11302
|
+
await storage.clearHistory(sid, scope);
|
|
10766
11303
|
return NextResponse.json({ success: true });
|
|
10767
11304
|
} catch (err) {
|
|
10768
11305
|
const message = err instanceof Error ? err.message : "Failed to clear history";
|
|
@@ -10776,18 +11313,20 @@ function createFeedbackHandler(configOrPlugin, options) {
|
|
|
10776
11313
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
10777
11314
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
10778
11315
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
11316
|
+
const onResolveScope = options == null ? void 0 : options.onResolveScope;
|
|
10779
11317
|
return async function handler(req) {
|
|
10780
11318
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10781
11319
|
if (authResult) return authResult;
|
|
11320
|
+
const scope = onResolveScope ? await onResolveScope(req) : void 0;
|
|
10782
11321
|
if (req.method === "GET") {
|
|
10783
11322
|
try {
|
|
10784
11323
|
const url = new URL(req.url);
|
|
10785
11324
|
const messageId = url.searchParams.get("messageId");
|
|
10786
11325
|
if (!messageId) {
|
|
10787
|
-
const feedbackList = await storage.listFeedback();
|
|
11326
|
+
const feedbackList = await storage.listFeedback(scope);
|
|
10788
11327
|
return NextResponse.json({ feedback: feedbackList });
|
|
10789
11328
|
}
|
|
10790
|
-
const feedback = await storage.getFeedback(messageId);
|
|
11329
|
+
const feedback = await storage.getFeedback(messageId, scope);
|
|
10791
11330
|
return NextResponse.json({ feedback });
|
|
10792
11331
|
} catch (err) {
|
|
10793
11332
|
const message = err instanceof Error ? err.message : "Failed to fetch feedback";
|
|
@@ -10803,6 +11342,17 @@ function createFeedbackHandler(configOrPlugin, options) {
|
|
|
10803
11342
|
if (!rating) {
|
|
10804
11343
|
return NextResponse.json({ error: "rating is required" }, { status: 400 });
|
|
10805
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
|
+
}
|
|
10806
11356
|
await storage.saveFeedback({ messageId, sessionId, rating, comment });
|
|
10807
11357
|
return NextResponse.json({ success: true });
|
|
10808
11358
|
} catch (err) {
|
|
@@ -10817,14 +11367,15 @@ function createSessionsHandler(configOrPlugin, options) {
|
|
|
10817
11367
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
10818
11368
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
10819
11369
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
11370
|
+
const onResolveScope = options == null ? void 0 : options.onResolveScope;
|
|
10820
11371
|
return async function GET(req) {
|
|
10821
11372
|
if (req) {
|
|
10822
11373
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10823
11374
|
if (authResult) return authResult;
|
|
10824
11375
|
}
|
|
10825
|
-
void req;
|
|
10826
11376
|
try {
|
|
10827
|
-
const
|
|
11377
|
+
const scope = req && onResolveScope ? await onResolveScope(req) : void 0;
|
|
11378
|
+
const sessions = await storage.listSessions(scope);
|
|
10828
11379
|
return NextResponse.json({ sessions });
|
|
10829
11380
|
} catch (err) {
|
|
10830
11381
|
const message = err instanceof Error ? err.message : "Failed to list sessions";
|
|
@@ -10835,15 +11386,17 @@ function createSessionsHandler(configOrPlugin, options) {
|
|
|
10835
11386
|
function createRagHandler(configOrPlugin, options) {
|
|
10836
11387
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
10837
11388
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
10838
|
-
const
|
|
10839
|
-
const
|
|
10840
|
-
const
|
|
10841
|
-
const
|
|
10842
|
-
const
|
|
10843
|
-
const
|
|
10844
|
-
const
|
|
10845
|
-
const
|
|
10846
|
-
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);
|
|
10847
11400
|
async function routePostRequest(req, segment) {
|
|
10848
11401
|
switch (segment) {
|
|
10849
11402
|
case "chat":
|
|
@@ -10885,7 +11438,7 @@ function createRagHandler(configOrPlugin, options) {
|
|
|
10885
11438
|
}
|
|
10886
11439
|
}
|
|
10887
11440
|
async function getSegment(req, context) {
|
|
10888
|
-
var
|
|
11441
|
+
var _a3, _b;
|
|
10889
11442
|
const contentType = req.headers.get("content-type") || "";
|
|
10890
11443
|
if (contentType.includes("multipart/form-data")) {
|
|
10891
11444
|
return "upload";
|
|
@@ -10902,7 +11455,7 @@ function createRagHandler(configOrPlugin, options) {
|
|
|
10902
11455
|
if (pathname.endsWith("/history")) return "history";
|
|
10903
11456
|
} catch (e) {
|
|
10904
11457
|
}
|
|
10905
|
-
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;
|
|
10906
11459
|
const segments = (resolvedParams == null ? void 0 : resolvedParams.retrivora) || ((_b = resolvedParams == null ? void 0 : resolvedParams.params) == null ? void 0 : _b.retrivora) || [];
|
|
10907
11460
|
const joined = segments.join("/");
|
|
10908
11461
|
return joined || "chat";
|