@retrivora-ai/rag-engine 2.3.0 → 2.3.2
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 +881 -331
- package/dist/handlers/index.mjs +881 -331
- 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 +454 -36
- package/dist/index.mjs +453 -38
- package/dist/server.d.mts +35 -73
- package/dist/server.d.ts +35 -73
- package/dist/server.js +911 -345
- package/dist/server.mjs +911 -345
- package/package.json +3 -2
- package/src/components/ChatWidget.tsx +149 -48
- package/src/components/ChatWindow.tsx +52 -9
- package/src/components/CodeViewer.tsx +1 -1
- 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/LangChainAgent.ts +0 -2
- 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/providers/vectordb/MilvusProvider.ts +0 -1
- package/src/providers/vectordb/MongoDBProvider.ts +0 -1
- package/src/providers/vectordb/MultiTablePostgresProvider.ts +2 -2
- package/src/providers/vectordb/RedisProvider.ts +0 -1
- package/src/providers/vectordb/WeaviateProvider.ts +0 -1
- package/src/rag/LlamaIndexIngestor.ts +0 -1
- package/src/server.ts +1 -0
- package/dist/index-BPJ3KDYI.d.ts +0 -195
- package/dist/index-Dmq5lH0j.d.mts +0 -195
package/dist/server.mjs
CHANGED
|
@@ -150,7 +150,7 @@ var init_ConfigFetcher = __esm({
|
|
|
150
150
|
* Fetch full project configuration (vectorDb + embedding + llm) from Retrivora Control Plane.
|
|
151
151
|
*/
|
|
152
152
|
static async fetchRemoteConfig(projectId, licenseKey) {
|
|
153
|
-
var
|
|
153
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
|
|
154
154
|
const cacheKey = `${projectId}:${licenseKey || ""}`;
|
|
155
155
|
const now = Date.now();
|
|
156
156
|
const cached = this.cache.get(cacheKey);
|
|
@@ -176,7 +176,7 @@ var init_ConfigFetcher = __esm({
|
|
|
176
176
|
});
|
|
177
177
|
if (res.ok) {
|
|
178
178
|
const data = await res.json();
|
|
179
|
-
if ((data == null ? void 0 : data.success) && ((
|
|
179
|
+
if ((data == null ? void 0 : data.success) && ((_a3 = data == null ? void 0 : data.vectorDb) == null ? void 0 : _a3.apiKey)) {
|
|
180
180
|
const fetchedProjectId = data.projectId || projectId;
|
|
181
181
|
const config = {
|
|
182
182
|
projectId: fetchedProjectId,
|
|
@@ -212,9 +212,9 @@ var init_ConfigFetcher = __esm({
|
|
|
212
212
|
}
|
|
213
213
|
/** Convenience: fetch only vector DB config (backwards compat). */
|
|
214
214
|
static async fetchRemoteVectorConfig(projectId, licenseKey) {
|
|
215
|
-
var
|
|
215
|
+
var _a3;
|
|
216
216
|
const config = await this.fetchRemoteConfig(projectId, licenseKey);
|
|
217
|
-
return (
|
|
217
|
+
return (_a3 = config == null ? void 0 : config.vectorDb) != null ? _a3 : null;
|
|
218
218
|
}
|
|
219
219
|
};
|
|
220
220
|
ConfigFetcher.cache = /* @__PURE__ */ new Map();
|
|
@@ -263,7 +263,7 @@ var init_PineconeProvider = __esm({
|
|
|
263
263
|
static getHealthChecker() {
|
|
264
264
|
return {
|
|
265
265
|
async check(config) {
|
|
266
|
-
var
|
|
266
|
+
var _a3, _b;
|
|
267
267
|
const opts = config.options || {};
|
|
268
268
|
const indexName = config.indexName;
|
|
269
269
|
const timestamp = Date.now();
|
|
@@ -271,7 +271,7 @@ var init_PineconeProvider = __esm({
|
|
|
271
271
|
const { Pinecone: Pinecone2 } = await import("@pinecone-database/pinecone");
|
|
272
272
|
const client = new Pinecone2({ apiKey: opts.apiKey });
|
|
273
273
|
const indexes = await client.listIndexes();
|
|
274
|
-
const indexNames = (_b = (
|
|
274
|
+
const indexNames = (_b = (_a3 = indexes.indexes) == null ? void 0 : _a3.map((i) => i.name)) != null ? _b : [];
|
|
275
275
|
if (!indexNames.includes(indexName)) {
|
|
276
276
|
return {
|
|
277
277
|
healthy: false,
|
|
@@ -298,7 +298,7 @@ var init_PineconeProvider = __esm({
|
|
|
298
298
|
};
|
|
299
299
|
}
|
|
300
300
|
async initialize() {
|
|
301
|
-
var
|
|
301
|
+
var _a3, _b;
|
|
302
302
|
if (this.client) return;
|
|
303
303
|
let key = this.apiKey || process.env.PINECONE_API_KEY || "";
|
|
304
304
|
if (!key) {
|
|
@@ -335,7 +335,7 @@ var init_PineconeProvider = __esm({
|
|
|
335
335
|
this.client = new Pinecone({ apiKey: key });
|
|
336
336
|
try {
|
|
337
337
|
const indexes = await this.client.listIndexes();
|
|
338
|
-
const names = (_b = (
|
|
338
|
+
const names = (_b = (_a3 = indexes.indexes) == null ? void 0 : _a3.map((i) => i.name)) != null ? _b : [];
|
|
339
339
|
if (!names.includes(this.indexName)) {
|
|
340
340
|
console.warn(`[PineconeProvider] Target index "${this.indexName}" not listed. Proceeding with configured index name.`);
|
|
341
341
|
}
|
|
@@ -354,13 +354,13 @@ var init_PineconeProvider = __esm({
|
|
|
354
354
|
return namespace ? idx.namespace(namespace) : idx.namespace("");
|
|
355
355
|
}
|
|
356
356
|
async upsert(doc, namespace) {
|
|
357
|
-
var
|
|
357
|
+
var _a3;
|
|
358
358
|
const targetIdx = await this.getActiveIndex(namespace);
|
|
359
359
|
await targetIdx.upsert({
|
|
360
360
|
records: [{
|
|
361
361
|
id: String(doc.id),
|
|
362
362
|
values: doc.vector,
|
|
363
|
-
metadata: __spreadValues({ content: doc.content }, (
|
|
363
|
+
metadata: __spreadValues({ content: doc.content }, (_a3 = doc.metadata) != null ? _a3 : {})
|
|
364
364
|
}]
|
|
365
365
|
});
|
|
366
366
|
}
|
|
@@ -369,18 +369,18 @@ var init_PineconeProvider = __esm({
|
|
|
369
369
|
const BATCH = 100;
|
|
370
370
|
for (let i = 0; i < docs.length; i += BATCH) {
|
|
371
371
|
const records = docs.slice(i, i + BATCH).map((d) => {
|
|
372
|
-
var
|
|
372
|
+
var _a3;
|
|
373
373
|
return {
|
|
374
374
|
id: String(d.id),
|
|
375
375
|
values: d.vector,
|
|
376
|
-
metadata: __spreadValues({ content: d.content }, (
|
|
376
|
+
metadata: __spreadValues({ content: d.content }, (_a3 = d.metadata) != null ? _a3 : {})
|
|
377
377
|
};
|
|
378
378
|
});
|
|
379
379
|
await targetIdx.upsert({ records });
|
|
380
380
|
}
|
|
381
381
|
}
|
|
382
382
|
async query(vector, topK, namespace, filter) {
|
|
383
|
-
var
|
|
383
|
+
var _a3;
|
|
384
384
|
const targetIdx = await this.getActiveIndex(namespace);
|
|
385
385
|
const pineconeFilter = this.sanitizeFilter(filter);
|
|
386
386
|
const result = await targetIdx.query(__spreadValues({
|
|
@@ -388,11 +388,11 @@ var init_PineconeProvider = __esm({
|
|
|
388
388
|
topK,
|
|
389
389
|
includeMetadata: true
|
|
390
390
|
}, Object.keys(pineconeFilter).length > 0 ? { filter: pineconeFilter } : {}));
|
|
391
|
-
return ((
|
|
392
|
-
var
|
|
391
|
+
return ((_a3 = result.matches) != null ? _a3 : []).map((m) => {
|
|
392
|
+
var _a4, _b;
|
|
393
393
|
return {
|
|
394
394
|
id: m.id,
|
|
395
|
-
score: (
|
|
395
|
+
score: (_a4 = m.score) != null ? _a4 : 0,
|
|
396
396
|
content: ((_b = m.metadata) == null ? void 0 : _b.content) || "",
|
|
397
397
|
metadata: m.metadata
|
|
398
398
|
};
|
|
@@ -435,13 +435,13 @@ var init_PostgreSQLProvider = __esm({
|
|
|
435
435
|
init_BaseVectorProvider();
|
|
436
436
|
PostgreSQLProvider = class extends BaseVectorProvider {
|
|
437
437
|
constructor(config) {
|
|
438
|
-
var
|
|
438
|
+
var _a3;
|
|
439
439
|
super(config);
|
|
440
440
|
this.tableName = this.indexName.replace(/[^a-z0-9_]/gi, "_");
|
|
441
441
|
const opts = config.options;
|
|
442
442
|
if (!opts.connectionString) throw new Error("[PostgreSQLProvider] options.connectionString is required");
|
|
443
443
|
this.connectionString = opts.connectionString;
|
|
444
|
-
this.dimensions = (
|
|
444
|
+
this.dimensions = (_a3 = opts.dimensions) != null ? _a3 : 1536;
|
|
445
445
|
}
|
|
446
446
|
static getValidator() {
|
|
447
447
|
return {
|
|
@@ -522,7 +522,7 @@ var init_PostgreSQLProvider = __esm({
|
|
|
522
522
|
}
|
|
523
523
|
}
|
|
524
524
|
async upsert(doc, namespace = "") {
|
|
525
|
-
var
|
|
525
|
+
var _a3;
|
|
526
526
|
const vectorLiteral = `[${doc.vector.join(",")}]`;
|
|
527
527
|
await this.pool.query(
|
|
528
528
|
`INSERT INTO ${this.tableName} (id, namespace, content, metadata, embedding)
|
|
@@ -532,7 +532,7 @@ var init_PostgreSQLProvider = __esm({
|
|
|
532
532
|
content = EXCLUDED.content,
|
|
533
533
|
metadata = EXCLUDED.metadata,
|
|
534
534
|
embedding = EXCLUDED.embedding`,
|
|
535
|
-
[doc.id, namespace, doc.content, JSON.stringify((
|
|
535
|
+
[doc.id, namespace, doc.content, JSON.stringify((_a3 = doc.metadata) != null ? _a3 : {}), vectorLiteral]
|
|
536
536
|
);
|
|
537
537
|
}
|
|
538
538
|
async batchUpsert(docs, namespace = "") {
|
|
@@ -545,9 +545,9 @@ var init_PostgreSQLProvider = __esm({
|
|
|
545
545
|
const batch = docs.slice(i, i + BATCH_SIZE);
|
|
546
546
|
const values = [];
|
|
547
547
|
const valuePlaceholders = batch.map((doc, idx) => {
|
|
548
|
-
var
|
|
548
|
+
var _a3;
|
|
549
549
|
const offset = idx * 5;
|
|
550
|
-
values.push(doc.id, namespace, doc.content, JSON.stringify((
|
|
550
|
+
values.push(doc.id, namespace, doc.content, JSON.stringify((_a3 = doc.metadata) != null ? _a3 : {}), `[${doc.vector.join(",")}]`);
|
|
551
551
|
return `($${offset + 1}, $${offset + 2}, $${offset + 3}, $${offset + 4}, $${offset + 5}::vector)`;
|
|
552
552
|
}).join(", ");
|
|
553
553
|
const query = `
|
|
@@ -630,8 +630,8 @@ var init_PostgreSQLProvider = __esm({
|
|
|
630
630
|
|
|
631
631
|
// src/utils/synonyms.ts
|
|
632
632
|
function resolveMetadataValue(meta, uiKey) {
|
|
633
|
-
var
|
|
634
|
-
const synonyms = (
|
|
633
|
+
var _a3;
|
|
634
|
+
const synonyms = (_a3 = FIELD_SYNONYMS[uiKey]) != null ? _a3 : [];
|
|
635
635
|
const keys = Object.keys(meta);
|
|
636
636
|
const systemKeys = ["namespace", "filename", "filesize", "filetype", "docid", "uploadedat", "dimension", "chunkindex"];
|
|
637
637
|
let match = keys.find((k) => k.toLowerCase() === uiKey.toLowerCase());
|
|
@@ -718,14 +718,14 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
718
718
|
init_synonyms();
|
|
719
719
|
MultiTablePostgresProvider = class extends BaseVectorProvider {
|
|
720
720
|
constructor(config) {
|
|
721
|
-
var
|
|
721
|
+
var _a3, _b, _c;
|
|
722
722
|
super(config);
|
|
723
723
|
const opts = config.options || {};
|
|
724
724
|
if (!opts.connectionString) {
|
|
725
725
|
throw new Error("[MultiTablePostgresProvider] options.connectionString is required");
|
|
726
726
|
}
|
|
727
727
|
this.connectionString = opts.connectionString;
|
|
728
|
-
this.dimensions = (
|
|
728
|
+
this.dimensions = (_a3 = opts.dimensions) != null ? _a3 : 768;
|
|
729
729
|
this.tables = [];
|
|
730
730
|
const rawSearchFields = (_c = (_b = opts.searchFields) != null ? _b : process.env.VECTOR_DB_SEARCH_FIELDS) != null ? _c : ["name", "product_name", "productname", "title"];
|
|
731
731
|
this.searchFields = typeof rawSearchFields === "string" ? rawSearchFields.split(",").map((f) => f.trim()).filter(Boolean) : rawSearchFields;
|
|
@@ -783,11 +783,11 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
783
783
|
* Batch upsert documents by dynamically provisioning tables and columns based on CSV headers.
|
|
784
784
|
*/
|
|
785
785
|
async batchUpsert(docs, namespace = "") {
|
|
786
|
-
var
|
|
786
|
+
var _a3;
|
|
787
787
|
if (docs.length === 0) return;
|
|
788
788
|
const docsByFile = {};
|
|
789
789
|
for (const doc of docs) {
|
|
790
|
-
const fileName = ((
|
|
790
|
+
const fileName = ((_a3 = doc.metadata) == null ? void 0 : _a3.fileName) || this.uploadTable;
|
|
791
791
|
if (!docsByFile[fileName]) docsByFile[fileName] = [];
|
|
792
792
|
docsByFile[fileName].push(doc);
|
|
793
793
|
}
|
|
@@ -840,11 +840,11 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
840
840
|
const headerColumns = csvHeaders.map((h) => `"${h}"`).join(", ");
|
|
841
841
|
const allColumns = `id, ${headerColumns ? headerColumns + ", " : ""}namespace, content, metadata, embedding`;
|
|
842
842
|
const valuePlaceholders = batch.map((doc, idx) => {
|
|
843
|
-
var
|
|
843
|
+
var _a4, _b;
|
|
844
844
|
const offset = idx * (5 + csvHeaders.length);
|
|
845
845
|
values.push(doc.id);
|
|
846
846
|
for (const h of csvHeaders) {
|
|
847
|
-
values.push(String(((
|
|
847
|
+
values.push(String(((_a4 = doc.metadata) == null ? void 0 : _a4[h]) || ""));
|
|
848
848
|
}
|
|
849
849
|
values.push(namespace, doc.content, JSON.stringify((_b = doc.metadata) != null ? _b : {}), `[${doc.vector.join(",")}]`);
|
|
850
850
|
const docPlaceholders = [];
|
|
@@ -883,7 +883,7 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
883
883
|
* Query all configured tables and merge results, sorted by cosine similarity score.
|
|
884
884
|
*/
|
|
885
885
|
async query(vector, topK, _namespace, _filter) {
|
|
886
|
-
var
|
|
886
|
+
var _a3;
|
|
887
887
|
if (!this.pool) {
|
|
888
888
|
throw new Error("[MultiTablePostgresProvider] Provider not initialized. Call initialize() first.");
|
|
889
889
|
}
|
|
@@ -914,11 +914,11 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
914
914
|
const filterParams = [];
|
|
915
915
|
if (metadataFilters && Object.keys(metadataFilters).length > 0) {
|
|
916
916
|
const conditions = Object.entries(metadataFilters).map(([key, val]) => {
|
|
917
|
-
var
|
|
917
|
+
var _a5;
|
|
918
918
|
filterParams.push(String(val));
|
|
919
919
|
const baseOffset = queryText && dynamicKeywordQuery ? 2 : 1;
|
|
920
920
|
const paramIdx = baseOffset + filterParams.length;
|
|
921
|
-
const synonyms = (
|
|
921
|
+
const synonyms = (_a5 = FIELD_SYNONYMS[key]) != null ? _a5 : [];
|
|
922
922
|
const keysToCheck = [key, ...synonyms];
|
|
923
923
|
const coalesceExprs = keysToCheck.flatMap((k) => [
|
|
924
924
|
`metadata->>'${k}'`,
|
|
@@ -987,7 +987,7 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
987
987
|
}
|
|
988
988
|
const tableResults = [];
|
|
989
989
|
for (const row of result.rows) {
|
|
990
|
-
const
|
|
990
|
+
const _a4 = row, { hybrid_score, id } = _a4, rest = __objRest(_a4, ["hybrid_score", "id"]);
|
|
991
991
|
delete rest.embedding;
|
|
992
992
|
delete rest.vector_score;
|
|
993
993
|
delete rest.keyword_score;
|
|
@@ -1016,10 +1016,10 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
1016
1016
|
}
|
|
1017
1017
|
allResults.sort((a, b) => b.score - a.score);
|
|
1018
1018
|
if (allResults.length === 0) return [];
|
|
1019
|
-
const bestMatchTable = (
|
|
1019
|
+
const bestMatchTable = (_a3 = allResults[0].metadata) == null ? void 0 : _a3.source_table;
|
|
1020
1020
|
const finalSorted = allResults.filter((res) => {
|
|
1021
|
-
var
|
|
1022
|
-
return ((
|
|
1021
|
+
var _a4;
|
|
1022
|
+
return ((_a4 = res.metadata) == null ? void 0 : _a4.source_table) === bestMatchTable;
|
|
1023
1023
|
});
|
|
1024
1024
|
console.log(`[MultiTablePostgresProvider] --- Search Complete ---`);
|
|
1025
1025
|
console.log(`[MultiTablePostgresProvider] Final top match from "${bestMatchTable}" with score ${finalSorted[0].score.toFixed(4)}`);
|
|
@@ -1340,7 +1340,6 @@ var init_MilvusProvider = __esm({
|
|
|
1340
1340
|
metadata: res["metadata"] || {}
|
|
1341
1341
|
}));
|
|
1342
1342
|
}
|
|
1343
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1344
1343
|
async delete(id, _namespace) {
|
|
1345
1344
|
await this.http.post("/v1/vector/delete", {
|
|
1346
1345
|
collectionName: this.indexName,
|
|
@@ -1424,14 +1423,14 @@ var init_QdrantProvider = __esm({
|
|
|
1424
1423
|
* Samples points from the collection to discover available payload fields.
|
|
1425
1424
|
*/
|
|
1426
1425
|
async discoverSchema() {
|
|
1427
|
-
var
|
|
1426
|
+
var _a3;
|
|
1428
1427
|
try {
|
|
1429
1428
|
const { data } = await this.http.post(`/collections/${this.indexName}/points/scroll`, {
|
|
1430
1429
|
limit: 20,
|
|
1431
1430
|
with_payload: true,
|
|
1432
1431
|
with_vector: false
|
|
1433
1432
|
});
|
|
1434
|
-
const points = ((
|
|
1433
|
+
const points = ((_a3 = data.result) == null ? void 0 : _a3.points) || [];
|
|
1435
1434
|
const keys = /* @__PURE__ */ new Set();
|
|
1436
1435
|
for (const point of points) {
|
|
1437
1436
|
const payload = point.payload || {};
|
|
@@ -1457,12 +1456,12 @@ var init_QdrantProvider = __esm({
|
|
|
1457
1456
|
* Ensures the collection exists. Creates it if missing.
|
|
1458
1457
|
*/
|
|
1459
1458
|
async ensureCollection() {
|
|
1460
|
-
var
|
|
1459
|
+
var _a3;
|
|
1461
1460
|
try {
|
|
1462
1461
|
await this.http.get(`/collections/${this.indexName}`);
|
|
1463
1462
|
console.log(`[QdrantProvider] \u2705 Collection "${this.indexName}" already exists.`);
|
|
1464
1463
|
} catch (err) {
|
|
1465
|
-
if (axios4.isAxiosError(err) && ((
|
|
1464
|
+
if (axios4.isAxiosError(err) && ((_a3 = err.response) == null ? void 0 : _a3.status) === 404) {
|
|
1466
1465
|
const opts = this.config.options;
|
|
1467
1466
|
const dimensionsForCreate = opts.dimensions || 1536;
|
|
1468
1467
|
console.log(`[QdrantProvider] \u23F3 Creating collection "${this.indexName}" (dimensions: ${dimensionsForCreate})...`);
|
|
@@ -1482,7 +1481,7 @@ var init_QdrantProvider = __esm({
|
|
|
1482
1481
|
* Ensures that a payload field has an index.
|
|
1483
1482
|
*/
|
|
1484
1483
|
async ensureIndex(fieldName, schema = "keyword") {
|
|
1485
|
-
var
|
|
1484
|
+
var _a3;
|
|
1486
1485
|
let fullPath = fieldName;
|
|
1487
1486
|
if (!this.isFlatPayload && !fieldName.includes(".") && fieldName !== "namespace" && fieldName !== this.contentField) {
|
|
1488
1487
|
fullPath = `${this.metadataField}.${fieldName}`;
|
|
@@ -1495,7 +1494,7 @@ var init_QdrantProvider = __esm({
|
|
|
1495
1494
|
console.log(`[QdrantProvider] \u2705 Ensured ${schema} index for "${fullPath}"`);
|
|
1496
1495
|
} catch (err) {
|
|
1497
1496
|
let status;
|
|
1498
|
-
if (axios4.isAxiosError(err)) status = (
|
|
1497
|
+
if (axios4.isAxiosError(err)) status = (_a3 = err.response) == null ? void 0 : _a3.status;
|
|
1499
1498
|
if (status === 409) return;
|
|
1500
1499
|
console.warn(`[QdrantProvider] \u26A0\uFE0F Could not ensure index for "${fullPath}":`, err instanceof Error ? err.message : String(err));
|
|
1501
1500
|
}
|
|
@@ -1524,7 +1523,7 @@ var init_QdrantProvider = __esm({
|
|
|
1524
1523
|
await this.http.put(`/collections/${this.indexName}/points`, payload);
|
|
1525
1524
|
}
|
|
1526
1525
|
async query(vector, topK, namespace, _filter) {
|
|
1527
|
-
var
|
|
1526
|
+
var _a3;
|
|
1528
1527
|
const must = [];
|
|
1529
1528
|
if (namespace) {
|
|
1530
1529
|
must.push({ key: "namespace", match: { value: namespace } });
|
|
@@ -1546,7 +1545,7 @@ var init_QdrantProvider = __esm({
|
|
|
1546
1545
|
limit: topK,
|
|
1547
1546
|
with_payload: true,
|
|
1548
1547
|
params: {
|
|
1549
|
-
hnsw_ef: ((
|
|
1548
|
+
hnsw_ef: ((_a3 = this.config.options) == null ? void 0 : _a3.efSearch) || Math.max(topK * 20, 128),
|
|
1550
1549
|
exact: false
|
|
1551
1550
|
},
|
|
1552
1551
|
filter: must.length > 0 ? { must } : void 0
|
|
@@ -1641,13 +1640,13 @@ var init_ChromaDBProvider = __esm({
|
|
|
1641
1640
|
* Get or create the ChromaDB collection.
|
|
1642
1641
|
*/
|
|
1643
1642
|
async initialize() {
|
|
1644
|
-
var
|
|
1643
|
+
var _a3;
|
|
1645
1644
|
try {
|
|
1646
1645
|
const { data } = await this.http.get(`/api/v1/collections/${this.indexName}`);
|
|
1647
1646
|
this.collectionId = data.id;
|
|
1648
1647
|
console.log(`[ChromaDBProvider] \u2705 Collection "${this.indexName}" found (id: ${this.collectionId})`);
|
|
1649
1648
|
} catch (err) {
|
|
1650
|
-
if (axios5.isAxiosError(err) && ((
|
|
1649
|
+
if (axios5.isAxiosError(err) && ((_a3 = err.response) == null ? void 0 : _a3.status) === 404) {
|
|
1651
1650
|
console.log(`[ChromaDBProvider] \u23F3 Collection "${this.indexName}" not found. Creating...`);
|
|
1652
1651
|
const { data } = await this.http.post("/api/v1/collections", {
|
|
1653
1652
|
name: this.indexName
|
|
@@ -1765,7 +1764,6 @@ var init_RedisProvider = __esm({
|
|
|
1765
1764
|
await this.upsert(doc, namespace);
|
|
1766
1765
|
}
|
|
1767
1766
|
}
|
|
1768
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1769
1767
|
async query(vector, topK, namespace, _filter) {
|
|
1770
1768
|
const payload = {
|
|
1771
1769
|
index: this.indexName,
|
|
@@ -1868,7 +1866,7 @@ var init_WeaviateProvider = __esm({
|
|
|
1868
1866
|
await this.http.post("/v1/batch/objects", payload);
|
|
1869
1867
|
}
|
|
1870
1868
|
async query(vector, topK, namespace, _filter) {
|
|
1871
|
-
var
|
|
1869
|
+
var _a3, _b;
|
|
1872
1870
|
const queryText = _filter == null ? void 0 : _filter.queryText;
|
|
1873
1871
|
const sanitizedFilter = this.sanitizeFilter(_filter);
|
|
1874
1872
|
const searchParams = queryText ? `hybrid: { query: ${JSON.stringify(queryText)}, alpha: 0.5 }` : `nearVector: { vector: ${JSON.stringify(vector)} }`;
|
|
@@ -1894,7 +1892,7 @@ var init_WeaviateProvider = __esm({
|
|
|
1894
1892
|
`
|
|
1895
1893
|
};
|
|
1896
1894
|
const { data } = await this.http.post("/v1/graphql", graphqlQuery);
|
|
1897
|
-
const results = ((_b = (
|
|
1895
|
+
const results = ((_b = (_a3 = data.data) == null ? void 0 : _a3.Get) == null ? void 0 : _b[this.indexName]) || [];
|
|
1898
1896
|
return results.map((res) => ({
|
|
1899
1897
|
id: res["_additional"].id,
|
|
1900
1898
|
score: 1 - res["_additional"].distance,
|
|
@@ -1902,7 +1900,6 @@ var init_WeaviateProvider = __esm({
|
|
|
1902
1900
|
metadata: res["metadata"] ? JSON.parse(res["metadata"]) : {}
|
|
1903
1901
|
}));
|
|
1904
1902
|
}
|
|
1905
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1906
1903
|
async delete(id, _namespace) {
|
|
1907
1904
|
await this.http.delete(`/v1/objects/${this.indexName}/${id}`);
|
|
1908
1905
|
}
|
|
@@ -1977,21 +1974,21 @@ var init_UniversalVectorProvider = __esm({
|
|
|
1977
1974
|
}
|
|
1978
1975
|
}
|
|
1979
1976
|
async initialize() {
|
|
1980
|
-
var
|
|
1977
|
+
var _a3;
|
|
1981
1978
|
this.http = axios8.create({
|
|
1982
1979
|
baseURL: this.opts.baseUrl,
|
|
1983
1980
|
headers: __spreadValues({
|
|
1984
1981
|
"Content-Type": "application/json"
|
|
1985
1982
|
}, this.opts.headers),
|
|
1986
|
-
timeout: (
|
|
1983
|
+
timeout: (_a3 = this.opts.timeout) != null ? _a3 : 3e4
|
|
1987
1984
|
});
|
|
1988
1985
|
if (!await this.ping()) {
|
|
1989
1986
|
throw new Error(`[UniversalVectorProvider] Failed to connect to ${this.opts.baseUrl}`);
|
|
1990
1987
|
}
|
|
1991
1988
|
}
|
|
1992
1989
|
async upsert(doc, namespace) {
|
|
1993
|
-
var
|
|
1994
|
-
const endpoint = (
|
|
1990
|
+
var _a3, _b, _c;
|
|
1991
|
+
const endpoint = (_a3 = this.opts.upsertEndpoint) != null ? _a3 : "/upsert";
|
|
1995
1992
|
const template = (_b = this.opts.upsertTemplate) != null ? _b : JSON.stringify({
|
|
1996
1993
|
id: "{{id}}",
|
|
1997
1994
|
vector: "{{vector}}",
|
|
@@ -2024,8 +2021,8 @@ var init_UniversalVectorProvider = __esm({
|
|
|
2024
2021
|
}
|
|
2025
2022
|
}
|
|
2026
2023
|
async query(vector, topK, namespace, filter) {
|
|
2027
|
-
var
|
|
2028
|
-
const endpoint = (
|
|
2024
|
+
var _a3, _b;
|
|
2025
|
+
const endpoint = (_a3 = this.opts.queryEndpoint) != null ? _a3 : "/query";
|
|
2029
2026
|
const template = (_b = this.opts.queryTemplate) != null ? _b : JSON.stringify({
|
|
2030
2027
|
vector: "{{vector}}",
|
|
2031
2028
|
limit: "{{topK}}",
|
|
@@ -2051,9 +2048,9 @@ var init_UniversalVectorProvider = __esm({
|
|
|
2051
2048
|
);
|
|
2052
2049
|
}
|
|
2053
2050
|
return results.map((item) => {
|
|
2054
|
-
var
|
|
2051
|
+
var _a4, _b2, _c, _d, _e, _f, _g2;
|
|
2055
2052
|
return {
|
|
2056
|
-
id: item[(
|
|
2053
|
+
id: item[(_a4 = this.opts.queryIdField) != null ? _a4 : "id"],
|
|
2057
2054
|
score: (_c = item[(_b2 = this.opts.queryScoreField) != null ? _b2 : "score"]) != null ? _c : 0,
|
|
2058
2055
|
content: (_e = item[(_d = this.opts.queryContentField) != null ? _d : "content"]) != null ? _e : "",
|
|
2059
2056
|
metadata: (_g2 = item[(_f = this.opts.queryMetadataField) != null ? _f : "metadata"]) != null ? _g2 : {}
|
|
@@ -2066,8 +2063,8 @@ var init_UniversalVectorProvider = __esm({
|
|
|
2066
2063
|
}
|
|
2067
2064
|
}
|
|
2068
2065
|
async delete(id, namespace) {
|
|
2069
|
-
var
|
|
2070
|
-
const endpoint = (
|
|
2066
|
+
var _a3, _b;
|
|
2067
|
+
const endpoint = (_a3 = this.opts.deleteEndpoint) != null ? _a3 : "/delete";
|
|
2071
2068
|
const template = (_b = this.opts.deleteTemplate) != null ? _b : JSON.stringify({
|
|
2072
2069
|
id: "{{id}}",
|
|
2073
2070
|
namespace: "{{namespace}}"
|
|
@@ -2085,8 +2082,8 @@ var init_UniversalVectorProvider = __esm({
|
|
|
2085
2082
|
}
|
|
2086
2083
|
}
|
|
2087
2084
|
async deleteNamespace(namespace) {
|
|
2088
|
-
var
|
|
2089
|
-
const endpoint = (
|
|
2085
|
+
var _a3;
|
|
2086
|
+
const endpoint = (_a3 = this.opts.deleteNamespaceEndpoint) != null ? _a3 : "/delete-namespace";
|
|
2090
2087
|
try {
|
|
2091
2088
|
await this.http.post(endpoint, { namespace });
|
|
2092
2089
|
} catch (error) {
|
|
@@ -2096,9 +2093,9 @@ var init_UniversalVectorProvider = __esm({
|
|
|
2096
2093
|
}
|
|
2097
2094
|
}
|
|
2098
2095
|
async ping() {
|
|
2099
|
-
var
|
|
2096
|
+
var _a3;
|
|
2100
2097
|
try {
|
|
2101
|
-
const endpoint = (
|
|
2098
|
+
const endpoint = (_a3 = this.opts.pingEndpoint) != null ? _a3 : "/health";
|
|
2102
2099
|
const response = await this.http.get(endpoint, { timeout: 5e3 });
|
|
2103
2100
|
return response.status >= 200 && response.status < 300;
|
|
2104
2101
|
} catch (e) {
|
|
@@ -2242,13 +2239,13 @@ var LicenseValidationError = class extends RetrivoraError {
|
|
|
2242
2239
|
}
|
|
2243
2240
|
};
|
|
2244
2241
|
function wrapError(err, defaultCode, defaultMessage) {
|
|
2245
|
-
var
|
|
2242
|
+
var _a3;
|
|
2246
2243
|
if (err instanceof RetrivoraError) {
|
|
2247
2244
|
return err;
|
|
2248
2245
|
}
|
|
2249
2246
|
const error = err;
|
|
2250
2247
|
const message = (error == null ? void 0 : error.message) || defaultMessage || String(err);
|
|
2251
|
-
const status = (error == null ? void 0 : error.status) || (error == null ? void 0 : error.statusCode) || ((
|
|
2248
|
+
const status = (error == null ? void 0 : error.status) || (error == null ? void 0 : error.statusCode) || ((_a3 = error == null ? void 0 : error.response) == null ? void 0 : _a3.status);
|
|
2252
2249
|
const code = error == null ? void 0 : error.code;
|
|
2253
2250
|
if (status === 429 || /rate[- ]?limit/i.test(message) || code === "RATE_LIMIT_EXCEEDED") {
|
|
2254
2251
|
return new RateLimitException(message, err);
|
|
@@ -2530,8 +2527,8 @@ var UI_BORDER_RADIUS_OPTIONS = ["none", "sm", "md", "lg", "xl", "full"];
|
|
|
2530
2527
|
|
|
2531
2528
|
// src/config/serverConfig.ts
|
|
2532
2529
|
function readString(env, name) {
|
|
2533
|
-
var
|
|
2534
|
-
const value = (
|
|
2530
|
+
var _a3;
|
|
2531
|
+
const value = (_a3 = env[name]) == null ? void 0 : _a3.trim();
|
|
2535
2532
|
return value ? value : void 0;
|
|
2536
2533
|
}
|
|
2537
2534
|
function readNumber(env, name, fallback) {
|
|
@@ -2544,8 +2541,8 @@ function readNumber(env, name, fallback) {
|
|
|
2544
2541
|
return parsed;
|
|
2545
2542
|
}
|
|
2546
2543
|
function readEnum(env, name, fallback, allowed) {
|
|
2547
|
-
var
|
|
2548
|
-
const value = (
|
|
2544
|
+
var _a3;
|
|
2545
|
+
const value = (_a3 = readString(env, name)) != null ? _a3 : fallback;
|
|
2549
2546
|
if (allowed.includes(value)) {
|
|
2550
2547
|
return value;
|
|
2551
2548
|
}
|
|
@@ -2555,8 +2552,8 @@ function getRagConfig(baseConfig, env = process.env) {
|
|
|
2555
2552
|
return getEnvConfig(env, baseConfig);
|
|
2556
2553
|
}
|
|
2557
2554
|
function getEnvConfig(env = process.env, base) {
|
|
2558
|
-
var
|
|
2559
|
-
const licenseKey = (_d = (_c = (_b = (
|
|
2555
|
+
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;
|
|
2556
|
+
const licenseKey = (_d = (_c = (_b = (_a3 = readString(env, "RAG_LICENSE_KEY")) != null ? _a3 : readString(env, "RETRIVORA_LICENSE_KEY")) != null ? _b : readString(env, "NEXT_PUBLIC_RETRIVORA_LICENSE_KEY")) != null ? _c : readString(env, "LICENSE_KEY")) != null ? _d : base == null ? void 0 : base.licenseKey;
|
|
2560
2557
|
const jwtProjectId = (() => {
|
|
2561
2558
|
if (!licenseKey) return void 0;
|
|
2562
2559
|
try {
|
|
@@ -2637,7 +2634,7 @@ function getEnvConfig(env = process.env, base) {
|
|
|
2637
2634
|
rest: "default",
|
|
2638
2635
|
custom: "default"
|
|
2639
2636
|
};
|
|
2640
|
-
const
|
|
2637
|
+
const isFreeTier2 = (() => {
|
|
2641
2638
|
if (!licenseKey) return true;
|
|
2642
2639
|
try {
|
|
2643
2640
|
const payload = LicenseVerifier.verify(licenseKey, projectId);
|
|
@@ -2648,13 +2645,13 @@ function getEnvConfig(env = process.env, base) {
|
|
|
2648
2645
|
}
|
|
2649
2646
|
})();
|
|
2650
2647
|
const defaultGatewayUrl = (_ra = (_qa = readString(env, "LITELLM_BASE_URL")) != null ? _qa : readString(env, "LLM_BASE_URL")) != null ? _ra : "https://www.retrivora.com/api/v1";
|
|
2651
|
-
const defaultLlmProvider =
|
|
2648
|
+
const defaultLlmProvider = isFreeTier2 ? "universal_rest" : "universal_rest";
|
|
2652
2649
|
const llmProvider = (_ua = (_ta = readEnum(env, "LLM_PROVIDER", defaultLlmProvider, LLM_PROVIDERS)) != null ? _ta : (_sa = base == null ? void 0 : base.llm) == null ? void 0 : _sa.provider) != null ? _ua : defaultLlmProvider;
|
|
2653
2650
|
const llmBaseUrl = (_ya = (_xa = (_va = readString(env, "LITELLM_BASE_URL")) != null ? _va : readString(env, "LLM_BASE_URL")) != null ? _xa : (_wa = base == null ? void 0 : base.llm) == null ? void 0 : _wa.baseUrl) != null ? _ya : defaultGatewayUrl;
|
|
2654
|
-
const llmModel = (_Ca = (_Aa = readString(env, "LLM_MODEL")) != null ? _Aa : (_za = base == null ? void 0 : base.llm) == null ? void 0 : _za.model) != null ? _Ca :
|
|
2651
|
+
const llmModel = (_Ca = (_Aa = readString(env, "LLM_MODEL")) != null ? _Aa : (_za = base == null ? void 0 : base.llm) == null ? void 0 : _za.model) != null ? _Ca : isFreeTier2 ? "llama-3.1-8b-instant" : (_Ba = DEFAULT_MODEL_BY_PROVIDER[llmProvider]) != null ? _Ba : "gpt-4o";
|
|
2655
2652
|
const llmApiKey = (_Ia = (_Ha = (_Fa = (_Ea = (_Da = llmApiKeyByProvider[llmProvider]) != null ? _Da : readString(env, "LLM_API_KEY")) != null ? _Ea : readString(env, "LITELLM_MASTER_KEY")) != null ? _Fa : readString(env, "LITELLM_API_KEY")) != null ? _Ha : (_Ga = base == null ? void 0 : base.llm) == null ? void 0 : _Ga.apiKey) != null ? _Ia : licenseKey;
|
|
2656
2653
|
const llmProfile = (_Ma = (_La = readString(env, "LLM_UNIVERSAL_PROFILE")) != null ? _La : (_Ka = (_Ja = base == null ? void 0 : base.llm) == null ? void 0 : _Ja.options) == null ? void 0 : _Ka.profile) != null ? _Ma : "litellm";
|
|
2657
|
-
const defaultEmbeddingProvider =
|
|
2654
|
+
const defaultEmbeddingProvider = isFreeTier2 ? "universal_rest" : "universal_rest";
|
|
2658
2655
|
const embeddingProvider = (_Pa = (_Oa = readEnum(env, "EMBEDDING_PROVIDER", defaultEmbeddingProvider, EMBEDDING_PROVIDERS)) != null ? _Oa : (_Na = base == null ? void 0 : base.embedding) == null ? void 0 : _Na.provider) != null ? _Pa : defaultEmbeddingProvider;
|
|
2659
2656
|
const embeddingBaseUrl = (_Ua = (_Ta = (_Ra = (_Qa = readString(env, "LITELLM_BASE_URL")) != null ? _Qa : readString(env, "EMBEDDING_BASE_URL")) != null ? _Ra : readString(env, "LLM_BASE_URL")) != null ? _Ta : (_Sa = base == null ? void 0 : base.embedding) == null ? void 0 : _Sa.baseUrl) != null ? _Ua : defaultGatewayUrl;
|
|
2660
2657
|
const embeddingModel = (_Xa = (_Wa = readString(env, "EMBEDDING_MODEL")) != null ? _Wa : (_Va = base == null ? void 0 : base.embedding) == null ? void 0 : _Va.model) != null ? _Xa : "text-embedding-004";
|
|
@@ -2744,8 +2741,8 @@ function getEnvConfig(env = process.env, base) {
|
|
|
2744
2741
|
}
|
|
2745
2742
|
} : {}), {
|
|
2746
2743
|
mcpServers: (() => {
|
|
2747
|
-
var
|
|
2748
|
-
const raw = (
|
|
2744
|
+
var _a4;
|
|
2745
|
+
const raw = (_a4 = readString(env, "MCP_SERVERS")) != null ? _a4 : readString(env, "NEXT_PUBLIC_MCP_SERVERS");
|
|
2749
2746
|
if (!raw) return void 0;
|
|
2750
2747
|
try {
|
|
2751
2748
|
return JSON.parse(raw);
|
|
@@ -2790,10 +2787,10 @@ var ConfigResolver = class {
|
|
|
2790
2787
|
* fallback behavior.
|
|
2791
2788
|
*/
|
|
2792
2789
|
static resolveUniversal(hostConfig, env = process.env) {
|
|
2793
|
-
var
|
|
2790
|
+
var _a3;
|
|
2794
2791
|
if (!hostConfig) return this.resolve(void 0, env);
|
|
2795
2792
|
const normalized = __spreadProps(__spreadValues({}, hostConfig), {
|
|
2796
|
-
vectorDb: (
|
|
2793
|
+
vectorDb: (_a3 = hostConfig.vectorDb) != null ? _a3 : hostConfig.vectorDatabase,
|
|
2797
2794
|
rag: this.mergeRetrievalWorkflow(hostConfig.rag, hostConfig.retrieval, hostConfig.workflow)
|
|
2798
2795
|
});
|
|
2799
2796
|
return this.resolve(normalized, env);
|
|
@@ -2813,11 +2810,11 @@ var ConfigResolver = class {
|
|
|
2813
2810
|
}
|
|
2814
2811
|
}
|
|
2815
2812
|
static mergeRetrievalWorkflow(rag, retrieval, workflow) {
|
|
2816
|
-
var
|
|
2813
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
2817
2814
|
if (!rag && !retrieval && !workflow) return void 0;
|
|
2818
2815
|
const normalized = __spreadValues({}, rag != null ? rag : {});
|
|
2819
2816
|
if (retrieval) {
|
|
2820
|
-
normalized.topK = (
|
|
2817
|
+
normalized.topK = (_a3 = retrieval.topK) != null ? _a3 : normalized.topK;
|
|
2821
2818
|
normalized.scoreThreshold = (_b = retrieval.scoreThreshold) != null ? _b : normalized.scoreThreshold;
|
|
2822
2819
|
normalized.useReranking = (_c = retrieval.useReranking) != null ? _c : normalized.useReranking;
|
|
2823
2820
|
if (retrieval.strategy === "hybrid") normalized.architecture = (_d = normalized.architecture) != null ? _d : "hybrid";
|
|
@@ -2945,8 +2942,8 @@ var OpenAIProvider = class {
|
|
|
2945
2942
|
};
|
|
2946
2943
|
}
|
|
2947
2944
|
async chat(messages, context, options) {
|
|
2948
|
-
var
|
|
2949
|
-
const basePrompt = (_b = (
|
|
2945
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i;
|
|
2946
|
+
const basePrompt = (_b = (_a3 = options == null ? void 0 : options.systemPrompt) != null ? _a3 : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Answer questions based on the provided context.";
|
|
2950
2947
|
const systemMessage = {
|
|
2951
2948
|
role: "system",
|
|
2952
2949
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -2970,8 +2967,8 @@ var OpenAIProvider = class {
|
|
|
2970
2967
|
}
|
|
2971
2968
|
chatStream(messages, context, options) {
|
|
2972
2969
|
return __asyncGenerator(this, null, function* () {
|
|
2973
|
-
var
|
|
2974
|
-
const basePrompt = (_b = (
|
|
2970
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h;
|
|
2971
|
+
const basePrompt = (_b = (_a3 = options == null ? void 0 : options.systemPrompt) != null ? _a3 : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Answer questions based on the provided context.";
|
|
2975
2972
|
const systemMessage = {
|
|
2976
2973
|
role: "system",
|
|
2977
2974
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3018,8 +3015,8 @@ var OpenAIProvider = class {
|
|
|
3018
3015
|
return results[0];
|
|
3019
3016
|
}
|
|
3020
3017
|
async batchEmbed(texts, options) {
|
|
3021
|
-
var
|
|
3022
|
-
const model = (_c = (_b = options == null ? void 0 : options.model) != null ? _b : (
|
|
3018
|
+
var _a3, _b, _c, _d, _e;
|
|
3019
|
+
const model = (_c = (_b = options == null ? void 0 : options.model) != null ? _b : (_a3 = this.embeddingConfig) == null ? void 0 : _a3.model) != null ? _c : "text-embedding-3-small";
|
|
3023
3020
|
const apiKey = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.apiKey) != null ? _e : this.llmConfig.apiKey;
|
|
3024
3021
|
const client = apiKey !== this.llmConfig.apiKey ? new OpenAI({ apiKey }) : this.client;
|
|
3025
3022
|
const response = await client.embeddings.create({ model, input: texts });
|
|
@@ -3096,8 +3093,8 @@ var AnthropicProvider = class {
|
|
|
3096
3093
|
};
|
|
3097
3094
|
}
|
|
3098
3095
|
async chat(messages, context, options) {
|
|
3099
|
-
var
|
|
3100
|
-
const basePrompt = (_b = (
|
|
3096
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
|
|
3097
|
+
const basePrompt = (_b = (_a3 = options == null ? void 0 : options.systemPrompt) != null ? _a3 : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Use the context below to answer the user's question accurately.";
|
|
3101
3098
|
const system = buildSystemContent(basePrompt, context);
|
|
3102
3099
|
const anthropicMessages = messages.map((m) => ({
|
|
3103
3100
|
role: m.role === "assistant" ? "assistant" : "user",
|
|
@@ -3135,8 +3132,8 @@ var AnthropicProvider = class {
|
|
|
3135
3132
|
}
|
|
3136
3133
|
chatStream(messages, context, options) {
|
|
3137
3134
|
return __asyncGenerator(this, null, function* () {
|
|
3138
|
-
var
|
|
3139
|
-
const basePrompt = (_b = (
|
|
3135
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
|
|
3136
|
+
const basePrompt = (_b = (_a3 = options == null ? void 0 : options.systemPrompt) != null ? _a3 : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Use the context below to answer the user's question accurately.";
|
|
3140
3137
|
const system = buildSystemContent(basePrompt, context);
|
|
3141
3138
|
const anthropicMessages = messages.map((m) => ({
|
|
3142
3139
|
role: m.role === "assistant" ? "assistant" : "user",
|
|
@@ -3220,8 +3217,8 @@ var AnthropicProvider = class {
|
|
|
3220
3217
|
import axios from "axios";
|
|
3221
3218
|
var OllamaProvider = class {
|
|
3222
3219
|
constructor(llmConfig, embeddingConfig) {
|
|
3223
|
-
var
|
|
3224
|
-
const rawBaseURL = ((
|
|
3220
|
+
var _a3, _b, _c;
|
|
3221
|
+
const rawBaseURL = ((_a3 = llmConfig.baseUrl) != null ? _a3 : "http://localhost:11434").replace(/\/+$/, "");
|
|
3225
3222
|
const baseURL = rawBaseURL.replace(/\/(?:api\/v1|v1|api)$/i, "");
|
|
3226
3223
|
const timeout = Number((_b = llmConfig.options) == null ? void 0 : _b.timeout) || 3e5;
|
|
3227
3224
|
const headers = ((_c = llmConfig.options) == null ? void 0 : _c.headers) || {};
|
|
@@ -3281,8 +3278,8 @@ var OllamaProvider = class {
|
|
|
3281
3278
|
};
|
|
3282
3279
|
}
|
|
3283
3280
|
async chat(messages, context, options) {
|
|
3284
|
-
var
|
|
3285
|
-
const basePrompt = (_b = (
|
|
3281
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
3282
|
+
const basePrompt = (_b = (_a3 = options == null ? void 0 : options.systemPrompt) != null ? _a3 : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Use the provided context to answer the user's question.";
|
|
3286
3283
|
const system = buildSystemContent(basePrompt, context);
|
|
3287
3284
|
const { data } = await this.http.post("/api/chat", {
|
|
3288
3285
|
model: this.llmConfig.model,
|
|
@@ -3300,8 +3297,8 @@ var OllamaProvider = class {
|
|
|
3300
3297
|
}
|
|
3301
3298
|
chatStream(messages, context, options) {
|
|
3302
3299
|
return __asyncGenerator(this, null, function* () {
|
|
3303
|
-
var
|
|
3304
|
-
const basePrompt = (_b = (
|
|
3300
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h;
|
|
3301
|
+
const basePrompt = (_b = (_a3 = options == null ? void 0 : options.systemPrompt) != null ? _a3 : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Use the provided context to answer the user's question.";
|
|
3305
3302
|
const system = buildSystemContent(basePrompt, context);
|
|
3306
3303
|
const response = yield new __await(this.http.post("/api/chat", {
|
|
3307
3304
|
model: this.llmConfig.model,
|
|
@@ -3359,8 +3356,8 @@ var OllamaProvider = class {
|
|
|
3359
3356
|
});
|
|
3360
3357
|
}
|
|
3361
3358
|
async embed(text, options) {
|
|
3362
|
-
var
|
|
3363
|
-
const model = (_c = (_b = options == null ? void 0 : options.model) != null ? _b : (
|
|
3359
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
|
|
3360
|
+
const model = (_c = (_b = options == null ? void 0 : options.model) != null ? _b : (_a3 = this.embeddingConfig) == null ? void 0 : _a3.model) != null ? _c : "nomic-embed-text";
|
|
3364
3361
|
const baseURL = (_f = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.baseUrl) != null ? _e : this.llmConfig.baseUrl) != null ? _f : "http://localhost:11434";
|
|
3365
3362
|
const client = baseURL !== ((_g2 = this.llmConfig.baseUrl) != null ? _g2 : "http://localhost:11434") ? axios.create({ baseURL, timeout: 6e4 }) : this.http;
|
|
3366
3363
|
let prompt = text;
|
|
@@ -3461,9 +3458,9 @@ var GeminiProvider = class {
|
|
|
3461
3458
|
static getHealthChecker() {
|
|
3462
3459
|
return {
|
|
3463
3460
|
async check(config) {
|
|
3464
|
-
var
|
|
3461
|
+
var _a3, _b;
|
|
3465
3462
|
const timestamp = Date.now();
|
|
3466
|
-
const apiKey = (_b = (
|
|
3463
|
+
const apiKey = (_b = (_a3 = config.apiKey) != null ? _a3 : process.env.GOOGLE_GENAI_API_KEY) != null ? _b : "";
|
|
3467
3464
|
const modelName = sanitizeModel(config.model);
|
|
3468
3465
|
try {
|
|
3469
3466
|
const { GoogleGenerativeAI: GoogleGenerativeAI2 } = await import("@google/generative-ai");
|
|
@@ -3493,16 +3490,16 @@ var GeminiProvider = class {
|
|
|
3493
3490
|
/** Resolve the embedding client — uses a separate client when the embedding
|
|
3494
3491
|
* API key differs from the LLM API key. */
|
|
3495
3492
|
get embeddingClient() {
|
|
3496
|
-
var
|
|
3497
|
-
if (((
|
|
3493
|
+
var _a3;
|
|
3494
|
+
if (((_a3 = this.embeddingConfig) == null ? void 0 : _a3.apiKey) && this.embeddingConfig.apiKey !== this.llmConfig.apiKey) {
|
|
3498
3495
|
return buildClient(this.embeddingConfig.apiKey);
|
|
3499
3496
|
}
|
|
3500
3497
|
return this.client;
|
|
3501
3498
|
}
|
|
3502
3499
|
/** Resolve the embedding model to use, in order of specificity. */
|
|
3503
3500
|
resolveEmbeddingModel(optionsModel) {
|
|
3504
|
-
var
|
|
3505
|
-
return sanitizeModel((_b = optionsModel != null ? optionsModel : (
|
|
3501
|
+
var _a3, _b;
|
|
3502
|
+
return sanitizeModel((_b = optionsModel != null ? optionsModel : (_a3 = this.embeddingConfig) == null ? void 0 : _a3.model) != null ? _b : DEFAULT_EMBEDDING_MODEL);
|
|
3506
3503
|
}
|
|
3507
3504
|
/**
|
|
3508
3505
|
* Convert ChatMessage[] to the Gemini contents format.
|
|
@@ -3522,8 +3519,8 @@ var GeminiProvider = class {
|
|
|
3522
3519
|
// ILLMProvider — chat
|
|
3523
3520
|
// -------------------------------------------------------------------------
|
|
3524
3521
|
async chat(messages, context, options) {
|
|
3525
|
-
var
|
|
3526
|
-
const basePrompt = (_b = (
|
|
3522
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
3523
|
+
const basePrompt = (_b = (_a3 = options == null ? void 0 : options.systemPrompt) != null ? _a3 : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Answer questions based on the provided context.";
|
|
3527
3524
|
const model = this.client.getGenerativeModel({
|
|
3528
3525
|
model: this.llmConfig.model,
|
|
3529
3526
|
systemInstruction: buildSystemContent(basePrompt, context)
|
|
@@ -3540,8 +3537,8 @@ var GeminiProvider = class {
|
|
|
3540
3537
|
}
|
|
3541
3538
|
chatStream(messages, context, options) {
|
|
3542
3539
|
return __asyncGenerator(this, null, function* () {
|
|
3543
|
-
var
|
|
3544
|
-
const basePrompt = (_b = (
|
|
3540
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
3541
|
+
const basePrompt = (_b = (_a3 = options == null ? void 0 : options.systemPrompt) != null ? _a3 : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Answer questions based on the provided context.";
|
|
3545
3542
|
const model = this.client.getGenerativeModel({
|
|
3546
3543
|
model: this.llmConfig.model,
|
|
3547
3544
|
systemInstruction: buildSystemContent(basePrompt, context)
|
|
@@ -3576,11 +3573,11 @@ var GeminiProvider = class {
|
|
|
3576
3573
|
// ILLMProvider — embeddings
|
|
3577
3574
|
// -------------------------------------------------------------------------
|
|
3578
3575
|
async embed(text, options) {
|
|
3579
|
-
var
|
|
3576
|
+
var _a3, _b;
|
|
3580
3577
|
const content = applyPrefix(
|
|
3581
3578
|
text,
|
|
3582
3579
|
options == null ? void 0 : options.taskType,
|
|
3583
|
-
(
|
|
3580
|
+
(_a3 = this.embeddingConfig) == null ? void 0 : _a3.queryPrefix,
|
|
3584
3581
|
(_b = this.embeddingConfig) == null ? void 0 : _b.documentPrefix
|
|
3585
3582
|
);
|
|
3586
3583
|
const modelName = this.resolveEmbeddingModel(options == null ? void 0 : options.model);
|
|
@@ -3597,7 +3594,7 @@ var GeminiProvider = class {
|
|
|
3597
3594
|
const modelName = this.resolveEmbeddingModel(options == null ? void 0 : options.model);
|
|
3598
3595
|
const model = this.embeddingClient.getGenerativeModel({ model: modelName });
|
|
3599
3596
|
const requests = texts.map((text) => {
|
|
3600
|
-
var
|
|
3597
|
+
var _a3, _b;
|
|
3601
3598
|
return {
|
|
3602
3599
|
content: {
|
|
3603
3600
|
role: "user",
|
|
@@ -3605,7 +3602,7 @@ var GeminiProvider = class {
|
|
|
3605
3602
|
text: applyPrefix(
|
|
3606
3603
|
text,
|
|
3607
3604
|
options == null ? void 0 : options.taskType,
|
|
3608
|
-
(
|
|
3605
|
+
(_a3 = this.embeddingConfig) == null ? void 0 : _a3.queryPrefix,
|
|
3609
3606
|
(_b = this.embeddingConfig) == null ? void 0 : _b.documentPrefix
|
|
3610
3607
|
)
|
|
3611
3608
|
}]
|
|
@@ -3622,8 +3619,8 @@ var GeminiProvider = class {
|
|
|
3622
3619
|
throw err;
|
|
3623
3620
|
});
|
|
3624
3621
|
return response.embeddings.map((e) => {
|
|
3625
|
-
var
|
|
3626
|
-
return (
|
|
3622
|
+
var _a3;
|
|
3623
|
+
return (_a3 = e.values) != null ? _a3 : [];
|
|
3627
3624
|
});
|
|
3628
3625
|
}
|
|
3629
3626
|
// -------------------------------------------------------------------------
|
|
@@ -3712,8 +3709,8 @@ var GroqProvider = class {
|
|
|
3712
3709
|
};
|
|
3713
3710
|
}
|
|
3714
3711
|
async chat(messages, context, options) {
|
|
3715
|
-
var
|
|
3716
|
-
const basePrompt = (_b = (
|
|
3712
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i;
|
|
3713
|
+
const basePrompt = (_b = (_a3 = options == null ? void 0 : options.systemPrompt) != null ? _a3 : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Answer questions based on the provided context.";
|
|
3717
3714
|
const systemMessage = {
|
|
3718
3715
|
role: "system",
|
|
3719
3716
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3737,8 +3734,8 @@ var GroqProvider = class {
|
|
|
3737
3734
|
}
|
|
3738
3735
|
chatStream(messages, context, options) {
|
|
3739
3736
|
return __asyncGenerator(this, null, function* () {
|
|
3740
|
-
var
|
|
3741
|
-
const basePrompt = (_b = (
|
|
3737
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h;
|
|
3738
|
+
const basePrompt = (_b = (_a3 = options == null ? void 0 : options.systemPrompt) != null ? _a3 : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Answer questions based on the provided context.";
|
|
3742
3739
|
const systemMessage = {
|
|
3743
3740
|
role: "system",
|
|
3744
3741
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3872,8 +3869,8 @@ var QwenProvider = class {
|
|
|
3872
3869
|
};
|
|
3873
3870
|
}
|
|
3874
3871
|
async chat(messages, context, options) {
|
|
3875
|
-
var
|
|
3876
|
-
const basePrompt = (_b = (
|
|
3872
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i;
|
|
3873
|
+
const basePrompt = (_b = (_a3 = options == null ? void 0 : options.systemPrompt) != null ? _a3 : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Answer questions based on the provided context.";
|
|
3877
3874
|
const systemMessage = {
|
|
3878
3875
|
role: "system",
|
|
3879
3876
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3897,8 +3894,8 @@ var QwenProvider = class {
|
|
|
3897
3894
|
}
|
|
3898
3895
|
chatStream(messages, context, options) {
|
|
3899
3896
|
return __asyncGenerator(this, null, function* () {
|
|
3900
|
-
var
|
|
3901
|
-
const basePrompt = (_b = (
|
|
3897
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h;
|
|
3898
|
+
const basePrompt = (_b = (_a3 = options == null ? void 0 : options.systemPrompt) != null ? _a3 : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Answer questions based on the provided context.";
|
|
3902
3899
|
const systemMessage = {
|
|
3903
3900
|
role: "system",
|
|
3904
3901
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3945,8 +3942,8 @@ var QwenProvider = class {
|
|
|
3945
3942
|
return results[0];
|
|
3946
3943
|
}
|
|
3947
3944
|
async batchEmbed(texts, options) {
|
|
3948
|
-
var
|
|
3949
|
-
const model = (_c = (_b = options == null ? void 0 : options.model) != null ? _b : (
|
|
3945
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
3946
|
+
const model = (_c = (_b = options == null ? void 0 : options.model) != null ? _b : (_a3 = this.embeddingConfig) == null ? void 0 : _a3.model) != null ? _c : "text-embedding-v1";
|
|
3950
3947
|
const apiKey = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.apiKey) != null ? _e : this.llmConfig.apiKey;
|
|
3951
3948
|
const client = apiKey !== this.llmConfig.apiKey ? new OpenAI3({
|
|
3952
3949
|
apiKey,
|
|
@@ -4046,9 +4043,9 @@ var VECTOR_PROFILES = {
|
|
|
4046
4043
|
|
|
4047
4044
|
// src/llm/providers/UniversalLLMAdapter.ts
|
|
4048
4045
|
function extractContent(obj) {
|
|
4049
|
-
var
|
|
4046
|
+
var _a3, _b, _c;
|
|
4050
4047
|
if (!obj || typeof obj !== "object") return void 0;
|
|
4051
|
-
const choice = (
|
|
4048
|
+
const choice = (_a3 = obj.choices) == null ? void 0 : _a3[0];
|
|
4052
4049
|
if (!choice) return void 0;
|
|
4053
4050
|
if (typeof ((_b = choice.message) == null ? void 0 : _b.content) === "string") return choice.message.content;
|
|
4054
4051
|
if (typeof ((_c = choice.delta) == null ? void 0 : _c.content) === "string") return choice.delta.content;
|
|
@@ -4058,10 +4055,10 @@ function extractContent(obj) {
|
|
|
4058
4055
|
}
|
|
4059
4056
|
var UniversalLLMAdapter = class {
|
|
4060
4057
|
constructor(config) {
|
|
4061
|
-
var
|
|
4058
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h;
|
|
4062
4059
|
this.model = config.model;
|
|
4063
4060
|
const llmConfig = config;
|
|
4064
|
-
const options = (
|
|
4061
|
+
const options = (_a3 = llmConfig.options) != null ? _a3 : {};
|
|
4065
4062
|
let profile = {};
|
|
4066
4063
|
if (typeof options.profile === "string") {
|
|
4067
4064
|
profile = LLM_PROFILES[options.profile] || {};
|
|
@@ -4087,8 +4084,8 @@ var UniversalLLMAdapter = class {
|
|
|
4087
4084
|
});
|
|
4088
4085
|
}
|
|
4089
4086
|
async chat(messages, context) {
|
|
4090
|
-
var
|
|
4091
|
-
const path2 = (
|
|
4087
|
+
var _a3, _b, _c, _d, _e;
|
|
4088
|
+
const path2 = (_a3 = this.opts.chatPath) != null ? _a3 : "/chat/completions";
|
|
4092
4089
|
const safeMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
|
|
4093
4090
|
role: m.role || "user",
|
|
4094
4091
|
content: typeof m.content === "string" ? m.content : m.content != null ? String(m.content) : ""
|
|
@@ -4154,8 +4151,8 @@ ${context != null ? context : "None"}` },
|
|
|
4154
4151
|
*/
|
|
4155
4152
|
chatStream(messages, context) {
|
|
4156
4153
|
return __asyncGenerator(this, null, function* () {
|
|
4157
|
-
var
|
|
4158
|
-
const path2 = (
|
|
4154
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
4155
|
+
const path2 = (_a3 = this.opts.chatPath) != null ? _a3 : "/chat/completions";
|
|
4159
4156
|
const url = `${this.baseUrl.replace(/\/$/, "")}${path2}`;
|
|
4160
4157
|
const extractPath = ((_b = this.opts.responseExtractPath) != null ? _b : "choices[0].message.content").replace("message.content", "delta.content");
|
|
4161
4158
|
const safeMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
|
|
@@ -4281,8 +4278,8 @@ ${context != null ? context : "None"}` },
|
|
|
4281
4278
|
});
|
|
4282
4279
|
}
|
|
4283
4280
|
async embed(text) {
|
|
4284
|
-
var
|
|
4285
|
-
const path2 = (
|
|
4281
|
+
var _a3, _b, _c, _d, _e;
|
|
4282
|
+
const path2 = (_a3 = this.opts.embedPath) != null ? _a3 : "/embeddings";
|
|
4286
4283
|
const payload = this.opts.embedPayloadTemplate ? buildPayload(this.opts.embedPayloadTemplate, { input: text, model: this.model }) : { input: text, model: this.model };
|
|
4287
4284
|
try {
|
|
4288
4285
|
const { data: data2 } = await this.http.post(path2, payload);
|
|
@@ -4371,7 +4368,7 @@ var LLMFactory = class _LLMFactory {
|
|
|
4371
4368
|
];
|
|
4372
4369
|
}
|
|
4373
4370
|
static create(llmConfig, embeddingConfig) {
|
|
4374
|
-
var
|
|
4371
|
+
var _a3, _b, _c;
|
|
4375
4372
|
switch (llmConfig.provider) {
|
|
4376
4373
|
case "openai":
|
|
4377
4374
|
return new OpenAIProvider(llmConfig, embeddingConfig);
|
|
@@ -4390,7 +4387,7 @@ var LLMFactory = class _LLMFactory {
|
|
|
4390
4387
|
case "custom":
|
|
4391
4388
|
return new UniversalLLMAdapter(llmConfig);
|
|
4392
4389
|
default: {
|
|
4393
|
-
const providerName = String((
|
|
4390
|
+
const providerName = String((_a3 = llmConfig.provider) != null ? _a3 : "").toLowerCase();
|
|
4394
4391
|
const customFactory = customProviders.get(providerName);
|
|
4395
4392
|
if (customFactory) {
|
|
4396
4393
|
return customFactory(llmConfig);
|
|
@@ -4492,7 +4489,7 @@ var ProviderRegistry = class {
|
|
|
4492
4489
|
return null;
|
|
4493
4490
|
}
|
|
4494
4491
|
static async loadVectorProviderClass(provider) {
|
|
4495
|
-
var
|
|
4492
|
+
var _a3;
|
|
4496
4493
|
if (this.vectorProviders[provider]) return this.vectorProviders[provider];
|
|
4497
4494
|
switch (provider) {
|
|
4498
4495
|
case "pinecone": {
|
|
@@ -4501,7 +4498,7 @@ var ProviderRegistry = class {
|
|
|
4501
4498
|
}
|
|
4502
4499
|
case "pgvector":
|
|
4503
4500
|
case "postgresql": {
|
|
4504
|
-
const postgresMode = ((
|
|
4501
|
+
const postgresMode = ((_a3 = process.env.POSTGRES_MODE) != null ? _a3 : "multi").toLowerCase();
|
|
4505
4502
|
if (postgresMode === "single") {
|
|
4506
4503
|
const { PostgreSQLProvider: PostgreSQLProvider2 } = await Promise.resolve().then(() => (init_PostgreSQLProvider(), PostgreSQLProvider_exports));
|
|
4507
4504
|
return PostgreSQLProvider2;
|
|
@@ -4724,7 +4721,7 @@ var ConfigValidator = class {
|
|
|
4724
4721
|
// package.json
|
|
4725
4722
|
var package_default = {
|
|
4726
4723
|
name: "@retrivora-ai/rag-engine",
|
|
4727
|
-
version: "2.3.
|
|
4724
|
+
version: "2.3.2",
|
|
4728
4725
|
description: "Retrivora AI is a plug-and-play AI engine for RAG chat experiences \u2014 generic vector DB + LLM provider, embeddable or standalone.",
|
|
4729
4726
|
author: "Abhinav Alkuchi",
|
|
4730
4727
|
license: "UNLICENSED",
|
|
@@ -4803,6 +4800,7 @@ var package_default = {
|
|
|
4803
4800
|
build: "npm run build:pkg",
|
|
4804
4801
|
"build:pkg": "npx @tailwindcss/cli -i src/tailwind.css -o src/index.css && tsup src/index.ts src/handlers/index.ts src/server.ts --format cjs,esm --dts --clean --no-splitting --tsconfig tsconfig.build.json --external react,react-dom,next,mongodb,pg,openai,@anthropic-ai/sdk,@pinecone-database/pinecone,axios,lucide-react,mammoth,pdf-parse,xlsx,react-markdown,remark-gfm,next-themes,langchain,@langchain/core,@langchain/openai,llamaindex --inject-style && npx @tailwindcss/cli -i src/tailwind.css -o dist/index.css",
|
|
4805
4802
|
lint: "eslint",
|
|
4803
|
+
typecheck: "tsc --noEmit -p tsconfig.build.json",
|
|
4806
4804
|
clean: "rm -rf dist"
|
|
4807
4805
|
},
|
|
4808
4806
|
peerDependencies: {
|
|
@@ -5029,8 +5027,8 @@ var Reranker = class {
|
|
|
5029
5027
|
return matches.sort((a, b) => b.score - a.score).slice(0, limit);
|
|
5030
5028
|
}
|
|
5031
5029
|
const scoredMatches = matches.map((match) => {
|
|
5032
|
-
var
|
|
5033
|
-
const contentLower = ((
|
|
5030
|
+
var _a3;
|
|
5031
|
+
const contentLower = ((_a3 = match == null ? void 0 : match.content) != null ? _a3 : "").toLowerCase();
|
|
5034
5032
|
let keywordScore = 0;
|
|
5035
5033
|
keywords.forEach((keyword) => {
|
|
5036
5034
|
if (contentLower.includes(keyword)) {
|
|
@@ -5052,8 +5050,8 @@ var Reranker = class {
|
|
|
5052
5050
|
|
|
5053
5051
|
Documents:
|
|
5054
5052
|
${topN.map((m, i) => {
|
|
5055
|
-
var
|
|
5056
|
-
return `[${i}] ${((
|
|
5053
|
+
var _a3;
|
|
5054
|
+
return `[${i}] ${((_a3 = m == null ? void 0 : m.content) != null ? _a3 : "").replace(/\n/g, " ")}`;
|
|
5057
5055
|
}).join("\n")}` }],
|
|
5058
5056
|
"",
|
|
5059
5057
|
{
|
|
@@ -5097,11 +5095,11 @@ var LlamaIndexIngestor = class {
|
|
|
5097
5095
|
* than standard character-count splitting.
|
|
5098
5096
|
*/
|
|
5099
5097
|
async chunk(text, options = {}) {
|
|
5100
|
-
var
|
|
5098
|
+
var _a3, _b;
|
|
5101
5099
|
try {
|
|
5102
5100
|
const { Document, SentenceSplitter, MetadataMode } = await import(`${"llamaindex"}`);
|
|
5103
5101
|
const splitter = new SentenceSplitter({
|
|
5104
|
-
chunkSize: (
|
|
5102
|
+
chunkSize: (_a3 = options.chunkSize) != null ? _a3 : 1e3,
|
|
5105
5103
|
chunkOverlap: (_b = options.chunkOverlap) != null ? _b : 200
|
|
5106
5104
|
});
|
|
5107
5105
|
const doc = new Document({ text, metadata: options.metadata || {} });
|
|
@@ -5189,7 +5187,6 @@ When presenting structured data, statistics, or comparisons, decide if it is bes
|
|
|
5189
5187
|
finalSystemPrompt += chartInstruction;
|
|
5190
5188
|
}
|
|
5191
5189
|
this.agent = createAgent({
|
|
5192
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5193
5190
|
model: chatModel,
|
|
5194
5191
|
tools: [searchTool],
|
|
5195
5192
|
systemPrompt: finalSystemPrompt
|
|
@@ -5210,7 +5207,7 @@ ${error instanceof Error ? error.message : String(error)}`
|
|
|
5210
5207
|
* The agent returns `{ messages: [...] }` — the last message is the final answer.
|
|
5211
5208
|
*/
|
|
5212
5209
|
async run(input, chatHistory = []) {
|
|
5213
|
-
var
|
|
5210
|
+
var _a3, _b, _c;
|
|
5214
5211
|
if (!this.agent) {
|
|
5215
5212
|
throw new Error("[LangChainAgent] Agent not initialized. Call initialize() first.");
|
|
5216
5213
|
}
|
|
@@ -5221,7 +5218,7 @@ ${error instanceof Error ? error.message : String(error)}`
|
|
|
5221
5218
|
const response = await this.agent.invoke({
|
|
5222
5219
|
messages: [...historyMessages, new HumanMessage(input)]
|
|
5223
5220
|
});
|
|
5224
|
-
const lastMessage = (
|
|
5221
|
+
const lastMessage = (_a3 = response == null ? void 0 : response.messages) == null ? void 0 : _a3.at(-1);
|
|
5225
5222
|
if (lastMessage && typeof lastMessage.content === "string") {
|
|
5226
5223
|
return lastMessage.content;
|
|
5227
5224
|
}
|
|
@@ -5273,7 +5270,7 @@ var MCPClient = class {
|
|
|
5273
5270
|
}
|
|
5274
5271
|
}
|
|
5275
5272
|
async connectStdio() {
|
|
5276
|
-
var
|
|
5273
|
+
var _a3;
|
|
5277
5274
|
const cmd = this.config.command;
|
|
5278
5275
|
if (!cmd) {
|
|
5279
5276
|
throw new Error(`[MCPClient] Command option is required for stdio transport on "${this.config.name}"`);
|
|
@@ -5288,7 +5285,7 @@ var MCPClient = class {
|
|
|
5288
5285
|
this.stdioBuffer += data.toString("utf-8");
|
|
5289
5286
|
this.processStdioLines();
|
|
5290
5287
|
});
|
|
5291
|
-
(
|
|
5288
|
+
(_a3 = this.childProcess.stderr) == null ? void 0 : _a3.on("data", (data) => {
|
|
5292
5289
|
console.warn(`[MCPClient] [stderr] [${this.config.name}]:`, data.toString("utf-8"));
|
|
5293
5290
|
});
|
|
5294
5291
|
this.childProcess.on("close", (code) => {
|
|
@@ -5363,14 +5360,14 @@ var MCPClient = class {
|
|
|
5363
5360
|
}
|
|
5364
5361
|
}
|
|
5365
5362
|
async sendNotification(method, params) {
|
|
5366
|
-
var
|
|
5363
|
+
var _a3;
|
|
5367
5364
|
const notification = {
|
|
5368
5365
|
jsonrpc: "2.0",
|
|
5369
5366
|
method,
|
|
5370
5367
|
params
|
|
5371
5368
|
};
|
|
5372
5369
|
if (this.config.transport === "stdio") {
|
|
5373
|
-
if ((
|
|
5370
|
+
if ((_a3 = this.childProcess) == null ? void 0 : _a3.stdin) {
|
|
5374
5371
|
this.childProcess.stdin.write(JSON.stringify(notification) + "\n", "utf-8");
|
|
5375
5372
|
}
|
|
5376
5373
|
} else if (this.sseUrl) {
|
|
@@ -5448,11 +5445,11 @@ var MCPRegistry = class {
|
|
|
5448
5445
|
// src/core/MultiAgentCoordinator.ts
|
|
5449
5446
|
var MultiAgentCoordinator = class {
|
|
5450
5447
|
constructor(options) {
|
|
5451
|
-
var
|
|
5448
|
+
var _a3;
|
|
5452
5449
|
this.llmProvider = options.llmProvider;
|
|
5453
5450
|
this.mcpRegistry = options.mcpRegistry;
|
|
5454
5451
|
this.documentSearch = options.documentSearch;
|
|
5455
|
-
this.maxIterations = (
|
|
5452
|
+
this.maxIterations = (_a3 = options.maxIterations) != null ? _a3 : 5;
|
|
5456
5453
|
}
|
|
5457
5454
|
/**
|
|
5458
5455
|
* Run the multi-agent coordination loop synchronously and return the final response.
|
|
@@ -5504,8 +5501,8 @@ Available Tools:
|
|
|
5504
5501
|
|
|
5505
5502
|
${mcpTools.length > 0 ? "MCP Server Tools:" : ""}
|
|
5506
5503
|
${mcpTools.map((mt) => {
|
|
5507
|
-
var
|
|
5508
|
-
return `- ${mt.tool.name}(${JSON.stringify(((
|
|
5504
|
+
var _a3;
|
|
5505
|
+
return `- ${mt.tool.name}(${JSON.stringify(((_a3 = mt.tool.inputSchema) == null ? void 0 : _a3.properties) || {})}): ${mt.tool.description || "No description provided."}`;
|
|
5509
5506
|
}).join("\n")}
|
|
5510
5507
|
|
|
5511
5508
|
Tool Calling Protocol:
|
|
@@ -5663,6 +5660,100 @@ ${toolResultText}`
|
|
|
5663
5660
|
}
|
|
5664
5661
|
};
|
|
5665
5662
|
|
|
5663
|
+
// src/core/CircuitBreaker.ts
|
|
5664
|
+
var CircuitBreaker = class {
|
|
5665
|
+
constructor(options = {}) {
|
|
5666
|
+
this.state = "closed";
|
|
5667
|
+
this.failureCount = 0;
|
|
5668
|
+
this.successCount = 0;
|
|
5669
|
+
this.lastFailureAt = 0;
|
|
5670
|
+
this.halfOpenCalls = 0;
|
|
5671
|
+
var _a3, _b, _c;
|
|
5672
|
+
this.failureThreshold = (_a3 = options.failureThreshold) != null ? _a3 : 5;
|
|
5673
|
+
this.resetTimeoutMs = (_b = options.resetTimeoutMs) != null ? _b : 3e4;
|
|
5674
|
+
this.halfOpenMaxCalls = (_c = options.halfOpenMaxCalls) != null ? _c : 1;
|
|
5675
|
+
}
|
|
5676
|
+
record(success) {
|
|
5677
|
+
const now = Date.now();
|
|
5678
|
+
if (success) {
|
|
5679
|
+
this.successCount++;
|
|
5680
|
+
if (this.state === "half-open") {
|
|
5681
|
+
this.state = "closed";
|
|
5682
|
+
this.failureCount = 0;
|
|
5683
|
+
this.halfOpenCalls = 0;
|
|
5684
|
+
this.successCount = 1;
|
|
5685
|
+
} else if (this.state === "closed") {
|
|
5686
|
+
if (this.successCount >= this.failureThreshold) {
|
|
5687
|
+
this.failureCount = Math.max(0, this.failureCount - 1);
|
|
5688
|
+
this.successCount = 0;
|
|
5689
|
+
}
|
|
5690
|
+
}
|
|
5691
|
+
} else {
|
|
5692
|
+
this.failureCount++;
|
|
5693
|
+
this.lastFailureAt = now;
|
|
5694
|
+
this.successCount = 0;
|
|
5695
|
+
if (this.state === "half-open") {
|
|
5696
|
+
this.state = "open";
|
|
5697
|
+
this.halfOpenCalls = 0;
|
|
5698
|
+
} else if (this.state === "closed" && this.failureCount >= this.failureThreshold) {
|
|
5699
|
+
this.state = "open";
|
|
5700
|
+
}
|
|
5701
|
+
}
|
|
5702
|
+
}
|
|
5703
|
+
canExecute() {
|
|
5704
|
+
const now = Date.now();
|
|
5705
|
+
if (this.state === "closed") {
|
|
5706
|
+
return true;
|
|
5707
|
+
}
|
|
5708
|
+
if (this.state === "open") {
|
|
5709
|
+
if (now - this.lastFailureAt >= this.resetTimeoutMs) {
|
|
5710
|
+
this.state = "half-open";
|
|
5711
|
+
this.halfOpenCalls = 0;
|
|
5712
|
+
return true;
|
|
5713
|
+
}
|
|
5714
|
+
return false;
|
|
5715
|
+
}
|
|
5716
|
+
if (this.state === "half-open") {
|
|
5717
|
+
return this.halfOpenCalls < this.halfOpenMaxCalls;
|
|
5718
|
+
}
|
|
5719
|
+
return true;
|
|
5720
|
+
}
|
|
5721
|
+
async wrap(fn) {
|
|
5722
|
+
if (!this.canExecute()) {
|
|
5723
|
+
const retryAfterSec = Math.ceil(
|
|
5724
|
+
Math.max(0, this.resetTimeoutMs - (Date.now() - this.lastFailureAt)) / 1e3
|
|
5725
|
+
);
|
|
5726
|
+
throw new Error(
|
|
5727
|
+
`Circuit breaker is open. Try again in ${retryAfterSec}s. Failed ${this.failureCount}/${this.failureThreshold} consecutive calls.`
|
|
5728
|
+
);
|
|
5729
|
+
}
|
|
5730
|
+
if (this.state === "half-open") {
|
|
5731
|
+
this.halfOpenCalls++;
|
|
5732
|
+
}
|
|
5733
|
+
try {
|
|
5734
|
+
const result = await fn();
|
|
5735
|
+
this.record(true);
|
|
5736
|
+
return result;
|
|
5737
|
+
} catch (err) {
|
|
5738
|
+
this.record(false);
|
|
5739
|
+
throw err;
|
|
5740
|
+
}
|
|
5741
|
+
}
|
|
5742
|
+
getState() {
|
|
5743
|
+
return this.state;
|
|
5744
|
+
}
|
|
5745
|
+
getFailureCount() {
|
|
5746
|
+
return this.failureCount;
|
|
5747
|
+
}
|
|
5748
|
+
reset() {
|
|
5749
|
+
this.state = "closed";
|
|
5750
|
+
this.failureCount = 0;
|
|
5751
|
+
this.successCount = 0;
|
|
5752
|
+
this.lastFailureAt = 0;
|
|
5753
|
+
this.halfOpenCalls = 0;
|
|
5754
|
+
}
|
|
5755
|
+
};
|
|
5756
|
+
|
|
5666
5757
|
// src/core/BatchProcessor.ts
|
|
5667
5758
|
function isTransientError(error) {
|
|
5668
5759
|
if (!(error instanceof Error)) return false;
|
|
@@ -5686,7 +5777,34 @@ function calculateBackoffDelay(attempt, initialDelayMs, maxDelayMs, multiplier)
|
|
|
5686
5777
|
function sleep(ms) {
|
|
5687
5778
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
5688
5779
|
}
|
|
5689
|
-
var
|
|
5780
|
+
var _BatchProcessor = class _BatchProcessor {
|
|
5781
|
+
/**
|
|
5782
|
+
* Execute a processor call through the circuit breaker.
|
|
5783
|
+
* Only transient failures count toward opening the circuit.
|
|
5784
|
+
*/
|
|
5785
|
+
static async executeWithCircuitBreaker(processor) {
|
|
5786
|
+
if (!this.cb.canExecute()) {
|
|
5787
|
+
const retryAfterSec = Math.ceil(
|
|
5788
|
+
Math.max(0, 3e4 - (Date.now() - this.cb.lastFailureAt || 0)) / 1e3
|
|
5789
|
+
);
|
|
5790
|
+
throw new Error(
|
|
5791
|
+
`[BatchProcessor] Circuit breaker is open. Try again in ${retryAfterSec}s.`
|
|
5792
|
+
);
|
|
5793
|
+
}
|
|
5794
|
+
if (this.cb.state === "half-open") {
|
|
5795
|
+
this.cb.halfOpenCalls++;
|
|
5796
|
+
}
|
|
5797
|
+
try {
|
|
5798
|
+
const result = await processor();
|
|
5799
|
+
this.cb.record(true);
|
|
5800
|
+
return result;
|
|
5801
|
+
} catch (err) {
|
|
5802
|
+
if (isTransientError(err)) {
|
|
5803
|
+
this.cb.record(false);
|
|
5804
|
+
}
|
|
5805
|
+
throw err;
|
|
5806
|
+
}
|
|
5807
|
+
}
|
|
5690
5808
|
/**
|
|
5691
5809
|
* Processes an array of items in configurable batches with retry logic.
|
|
5692
5810
|
*
|
|
@@ -5727,7 +5845,7 @@ var BatchProcessor = class {
|
|
|
5727
5845
|
let lastError;
|
|
5728
5846
|
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
5729
5847
|
try {
|
|
5730
|
-
const result = await processor(batch);
|
|
5848
|
+
const result = await _BatchProcessor.executeWithCircuitBreaker(() => processor(batch));
|
|
5731
5849
|
results.push(result);
|
|
5732
5850
|
success = true;
|
|
5733
5851
|
break;
|
|
@@ -5785,7 +5903,7 @@ ${errorMessages}`
|
|
|
5785
5903
|
let lastError;
|
|
5786
5904
|
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
5787
5905
|
try {
|
|
5788
|
-
const result = await processor(item);
|
|
5906
|
+
const result = await _BatchProcessor.executeWithCircuitBreaker(() => processor(item));
|
|
5789
5907
|
results.push(result);
|
|
5790
5908
|
success = true;
|
|
5791
5909
|
break;
|
|
@@ -5858,7 +5976,7 @@ ${errorMessages}`
|
|
|
5858
5976
|
}));
|
|
5859
5977
|
const chunkPromises = chunk.map(async ({ item, originalIndex }) => {
|
|
5860
5978
|
try {
|
|
5861
|
-
const result = await processor(item);
|
|
5979
|
+
const result = await _BatchProcessor.executeWithCircuitBreaker(() => processor(item));
|
|
5862
5980
|
return { success: true, result, index: originalIndex };
|
|
5863
5981
|
} catch (err) {
|
|
5864
5982
|
const error = err instanceof Error ? err : new Error(String(err));
|
|
@@ -5886,6 +6004,12 @@ ${errorMessages}`
|
|
|
5886
6004
|
return { results, errors, totalProcessed, totalFailed };
|
|
5887
6005
|
}
|
|
5888
6006
|
};
|
|
6007
|
+
_BatchProcessor.cb = new CircuitBreaker({
|
|
6008
|
+
failureThreshold: 5,
|
|
6009
|
+
resetTimeoutMs: 3e4,
|
|
6010
|
+
halfOpenMaxCalls: 1
|
|
6011
|
+
});
|
|
6012
|
+
var BatchProcessor = _BatchProcessor;
|
|
5889
6013
|
|
|
5890
6014
|
// src/config/EmbeddingStrategy.ts
|
|
5891
6015
|
var EmbeddingStrategy = /* @__PURE__ */ ((EmbeddingStrategy2) => {
|
|
@@ -5989,7 +6113,7 @@ var QueryProcessor = class {
|
|
|
5989
6113
|
* @param validFields Optional list of known filterable fields to look for
|
|
5990
6114
|
*/
|
|
5991
6115
|
static extractQueryFieldHints(question, validFields = []) {
|
|
5992
|
-
var
|
|
6116
|
+
var _a3, _b, _c, _d;
|
|
5993
6117
|
if (!question.trim()) return [];
|
|
5994
6118
|
const hints = /* @__PURE__ */ new Map();
|
|
5995
6119
|
const addHint = (value, field) => {
|
|
@@ -6069,7 +6193,7 @@ var QueryProcessor = class {
|
|
|
6069
6193
|
];
|
|
6070
6194
|
for (const p of universalPatterns) {
|
|
6071
6195
|
for (const match of question.matchAll(p.regex)) {
|
|
6072
|
-
const val = p.group ? (
|
|
6196
|
+
const val = p.group ? (_a3 = match[p.group]) != null ? _a3 : match[0] : match[0];
|
|
6073
6197
|
if (!val) continue;
|
|
6074
6198
|
if (p.field) addHint(val, p.field);
|
|
6075
6199
|
else addHint(val);
|
|
@@ -6293,11 +6417,11 @@ var LLMRouter = class {
|
|
|
6293
6417
|
* When provided it is used directly as the 'default' role without re-constructing.
|
|
6294
6418
|
*/
|
|
6295
6419
|
async initialize(prebuiltDefault) {
|
|
6296
|
-
var
|
|
6420
|
+
var _a3;
|
|
6297
6421
|
const defaultModel = prebuiltDefault != null ? prebuiltDefault : LLMFactory.create(this.config.llm, this.config.embedding);
|
|
6298
6422
|
this.models.set("default", defaultModel);
|
|
6299
6423
|
const envFastModel = process.env.FAST_LLM_MODEL;
|
|
6300
|
-
const providerFastDefault = (
|
|
6424
|
+
const providerFastDefault = (_a3 = FAST_MODEL_DEFAULTS[this.config.llm.provider]) != null ? _a3 : "";
|
|
6301
6425
|
const fastModelName = envFastModel || providerFastDefault;
|
|
6302
6426
|
if (fastModelName && fastModelName !== this.config.llm.model) {
|
|
6303
6427
|
console.log(`[LLMRouter] Fast role \u2192 provider="${this.config.llm.provider}" model="${fastModelName}"`);
|
|
@@ -6316,8 +6440,8 @@ var LLMRouter = class {
|
|
|
6316
6440
|
* Falls back to 'default' if the requested role is not registered.
|
|
6317
6441
|
*/
|
|
6318
6442
|
get(role) {
|
|
6319
|
-
var
|
|
6320
|
-
const provider = (
|
|
6443
|
+
var _a3;
|
|
6444
|
+
const provider = (_a3 = this.models.get(role)) != null ? _a3 : this.models.get("default");
|
|
6321
6445
|
if (!provider) {
|
|
6322
6446
|
throw new Error(`[LLMRouter] No provider registered for role: "${role}". Did you call initialize()?`);
|
|
6323
6447
|
}
|
|
@@ -6403,8 +6527,8 @@ var IntentClassifier = class {
|
|
|
6403
6527
|
numericFieldCount = numericKeys.size;
|
|
6404
6528
|
categoricalFieldCount = catKeys.size;
|
|
6405
6529
|
if (productKeyMatches >= 2 || docs.some((d) => {
|
|
6406
|
-
var
|
|
6407
|
-
return ((
|
|
6530
|
+
var _a3, _b;
|
|
6531
|
+
return ((_a3 = d == null ? void 0 : d.content) != null ? _a3 : "").toLowerCase().includes("price") || ((_b = d == null ? void 0 : d.content) != null ? _b : "").toLowerCase().includes("brand");
|
|
6408
6532
|
})) {
|
|
6409
6533
|
isProductLike = true;
|
|
6410
6534
|
}
|
|
@@ -6686,8 +6810,8 @@ var TextRendererStrategy = class {
|
|
|
6686
6810
|
}
|
|
6687
6811
|
const docs = Array.isArray(data) ? data : [];
|
|
6688
6812
|
const text = docs.map((d) => {
|
|
6689
|
-
var
|
|
6690
|
-
return (
|
|
6813
|
+
var _a3;
|
|
6814
|
+
return (_a3 = d == null ? void 0 : d.content) != null ? _a3 : "";
|
|
6691
6815
|
}).join("\n\n");
|
|
6692
6816
|
return { type: "text", title, data: { content: text || "No detailed content available." } };
|
|
6693
6817
|
}
|
|
@@ -6830,9 +6954,9 @@ var LRUDecisionCache = class {
|
|
|
6830
6954
|
this.maxSize = maxSize;
|
|
6831
6955
|
}
|
|
6832
6956
|
generateKey(context) {
|
|
6833
|
-
var
|
|
6957
|
+
var _a3, _b;
|
|
6834
6958
|
const q = (context.userQuery || "").toLowerCase().trim();
|
|
6835
|
-
const docCount = (_b = (
|
|
6959
|
+
const docCount = (_b = (_a3 = context.retrievedDocuments) == null ? void 0 : _a3.length) != null ? _b : 0;
|
|
6836
6960
|
return `${q}::docs:${docCount}`;
|
|
6837
6961
|
}
|
|
6838
6962
|
get(context) {
|
|
@@ -6941,7 +7065,7 @@ var UITransformer = class _UITransformer {
|
|
|
6941
7065
|
* Prefer `analyzeAndDecide()` in production.
|
|
6942
7066
|
*/
|
|
6943
7067
|
static transform(userQuery, retrievedData, config, trainedSchema, intent) {
|
|
6944
|
-
var
|
|
7068
|
+
var _a3, _b, _c;
|
|
6945
7069
|
if (!retrievedData || retrievedData.length === 0) {
|
|
6946
7070
|
return this.createTextResponse("No data available", "No relevant data found for your query.");
|
|
6947
7071
|
}
|
|
@@ -6961,7 +7085,7 @@ var UITransformer = class _UITransformer {
|
|
|
6961
7085
|
return this.transformToBarChart(filteredData, profile, userQuery, resolvedIntent.visualizationHint === "ranking");
|
|
6962
7086
|
}
|
|
6963
7087
|
if (resolvedIntent.visualizationHint === "distribution") {
|
|
6964
|
-
return (
|
|
7088
|
+
return (_a3 = this.transformToHistogram(profile, userQuery)) != null ? _a3 : this.transformToBarChart(filteredData, profile, userQuery);
|
|
6965
7089
|
}
|
|
6966
7090
|
if (resolvedIntent.visualizationHint === "correlation") {
|
|
6967
7091
|
return (_b = this.transformToScatterPlot(profile, userQuery)) != null ? _b : this.transformToBarChart(filteredData, profile, userQuery);
|
|
@@ -7294,11 +7418,11 @@ ${schemaProfileText}` : ""}`;
|
|
|
7294
7418
|
};
|
|
7295
7419
|
}
|
|
7296
7420
|
static transformToPieChart(data, profile, query = "") {
|
|
7297
|
-
var
|
|
7421
|
+
var _a3;
|
|
7298
7422
|
const dimension = profile ? this.selectDimensionField(profile, query) : void 0;
|
|
7299
7423
|
const categories = dimension ? Array.from(new Set(profile.records.map((record) => {
|
|
7300
|
-
var
|
|
7301
|
-
return String((
|
|
7424
|
+
var _a4;
|
|
7425
|
+
return String((_a4 = record.fields[dimension.key]) != null ? _a4 : "");
|
|
7302
7426
|
}).filter(Boolean))) : this.detectCategories(data);
|
|
7303
7427
|
if (categories.length === 0) return null;
|
|
7304
7428
|
const categoryData = dimension && profile ? this.aggregateProfileByDimension(profile, dimension.key) : this.aggregateByCategory(data, categories);
|
|
@@ -7308,7 +7432,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7308
7432
|
});
|
|
7309
7433
|
return {
|
|
7310
7434
|
type: "pie_chart",
|
|
7311
|
-
title: `Distribution by ${(
|
|
7435
|
+
title: `Distribution by ${(_a3 = dimension == null ? void 0 : dimension.label) != null ? _a3 : "Category"}`,
|
|
7312
7436
|
description: `Showing breakdown across ${pieData.length} categories`,
|
|
7313
7437
|
data: pieData
|
|
7314
7438
|
};
|
|
@@ -7318,8 +7442,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7318
7442
|
const valueField = profile.numericFields[0];
|
|
7319
7443
|
const buckets = /* @__PURE__ */ new Map();
|
|
7320
7444
|
profile.records.forEach((record) => {
|
|
7321
|
-
var
|
|
7322
|
-
const timestamp = String((
|
|
7445
|
+
var _a3, _b, _c;
|
|
7446
|
+
const timestamp = String((_a3 = record.fields[dateField.key]) != null ? _a3 : "");
|
|
7323
7447
|
const value = (_b = this.toFiniteNumber(record.fields[valueField.key])) != null ? _b : 0;
|
|
7324
7448
|
buckets.set(timestamp, ((_c = buckets.get(timestamp)) != null ? _c : 0) + value);
|
|
7325
7449
|
});
|
|
@@ -7332,23 +7456,23 @@ ${schemaProfileText}` : ""}`;
|
|
|
7332
7456
|
};
|
|
7333
7457
|
}
|
|
7334
7458
|
static transformToBarChart(data, profile, query = "", horizontal = false) {
|
|
7335
|
-
var
|
|
7459
|
+
var _a3;
|
|
7336
7460
|
const dimension = profile ? this.selectDimensionField(profile, query) : void 0;
|
|
7337
7461
|
const measure = profile ? this.selectNumericField(profile, query) : void 0;
|
|
7338
7462
|
const aggregate = dimension && profile ? this.aggregateProfileByDimension(profile, dimension.key, measure == null ? void 0 : measure.key) : this.aggregateByCategory(data, this.detectCategories(data));
|
|
7339
7463
|
const barData = Object.entries(aggregate).map(([category, value]) => ({ category, value: Number(value) })).sort((a, b) => horizontal ? b.value - a.value : 0).slice(0, 12);
|
|
7340
7464
|
const fallbackData = barData.length > 0 ? barData : data.slice(0, 12).map((item, index) => {
|
|
7341
|
-
var
|
|
7465
|
+
var _a4, _b, _c, _d, _e;
|
|
7342
7466
|
const meta = item.metadata || {};
|
|
7343
7467
|
const label = String(
|
|
7344
|
-
(_c = (_b = (
|
|
7468
|
+
(_c = (_b = (_a4 = this.getDynamicVal(meta, "name")) != null ? _a4 : meta.label) != null ? _b : meta.title) != null ? _c : `Result ${index + 1}`
|
|
7345
7469
|
);
|
|
7346
7470
|
const value = (_e = (_d = this.extractNumericValue(meta)) != null ? _d : item.score) != null ? _e : 0;
|
|
7347
7471
|
return { category: label, value: Number(value) };
|
|
7348
7472
|
});
|
|
7349
7473
|
return {
|
|
7350
7474
|
type: horizontal ? "horizontal_bar" : "bar_chart",
|
|
7351
|
-
title: dimension ? `${(
|
|
7475
|
+
title: dimension ? `${(_a3 = measure == null ? void 0 : measure.label) != null ? _a3 : "Count"} by ${dimension.label}` : "Comparison",
|
|
7352
7476
|
description: `Showing ${fallbackData.length} comparable values`,
|
|
7353
7477
|
data: fallbackData
|
|
7354
7478
|
};
|
|
@@ -7383,11 +7507,11 @@ ${schemaProfileText}` : ""}`;
|
|
|
7383
7507
|
if (fields.length < 2) return null;
|
|
7384
7508
|
const [xField, yField] = fields;
|
|
7385
7509
|
const points = profile.records.map((record) => {
|
|
7386
|
-
var
|
|
7510
|
+
var _a3;
|
|
7387
7511
|
const x = this.toFiniteNumber(record.fields[xField.key]);
|
|
7388
7512
|
const y = this.toFiniteNumber(record.fields[yField.key]);
|
|
7389
7513
|
if (x === null || y === null) return null;
|
|
7390
|
-
return { x, y, label: String((
|
|
7514
|
+
return { x, y, label: String((_a3 = this.getRecordLabel(record)) != null ? _a3 : record.id) };
|
|
7391
7515
|
}).filter((point) => point !== null).slice(0, 100);
|
|
7392
7516
|
if (points.length === 0) return null;
|
|
7393
7517
|
return {
|
|
@@ -7417,9 +7541,9 @@ ${schemaProfileText}` : ""}`;
|
|
|
7417
7541
|
static transformToRadarChart(data) {
|
|
7418
7542
|
const attributeMap = {};
|
|
7419
7543
|
data.forEach((item) => {
|
|
7420
|
-
var
|
|
7544
|
+
var _a3, _b, _c;
|
|
7421
7545
|
const meta = item.metadata || {};
|
|
7422
|
-
const seriesName = String((_c = (_b = (
|
|
7546
|
+
const seriesName = String((_c = (_b = (_a3 = meta.name) != null ? _a3 : meta.product) != null ? _b : item.id) != null ? _c : "Item");
|
|
7423
7547
|
Object.entries(meta).forEach(([key, val]) => {
|
|
7424
7548
|
if (typeof val === "number" && !["price", "id"].includes(key.toLowerCase())) {
|
|
7425
7549
|
if (!attributeMap[key]) attributeMap[key] = {};
|
|
@@ -7435,8 +7559,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7435
7559
|
title: "Product Comparison",
|
|
7436
7560
|
description: `Comparing ${data.length} items across ${radarData.length} attributes`,
|
|
7437
7561
|
data: radarData.length > 0 ? radarData : data.map((d) => {
|
|
7438
|
-
var
|
|
7439
|
-
return { attribute: ((
|
|
7562
|
+
var _a3;
|
|
7563
|
+
return { attribute: ((_a3 = d == null ? void 0 : d.content) != null ? _a3 : "").substring(0, 40) };
|
|
7440
7564
|
})
|
|
7441
7565
|
};
|
|
7442
7566
|
}
|
|
@@ -7455,8 +7579,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7455
7579
|
return this.createTextResponse(
|
|
7456
7580
|
"Retrieved Context",
|
|
7457
7581
|
data.map((item) => {
|
|
7458
|
-
var
|
|
7459
|
-
return (
|
|
7582
|
+
var _a3;
|
|
7583
|
+
return (_a3 = item == null ? void 0 : item.content) != null ? _a3 : "";
|
|
7460
7584
|
}).join("\n\n"),
|
|
7461
7585
|
`Found ${data.length} relevant results`
|
|
7462
7586
|
);
|
|
@@ -7507,11 +7631,11 @@ ${schemaProfileText}` : ""}`;
|
|
|
7507
7631
|
return null;
|
|
7508
7632
|
}
|
|
7509
7633
|
static normalizeTransformation(payload) {
|
|
7510
|
-
var
|
|
7634
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j;
|
|
7511
7635
|
if (!payload || typeof payload !== "object") return null;
|
|
7512
7636
|
const p = payload;
|
|
7513
7637
|
const type = this.normalizeVisualizationType(
|
|
7514
|
-
String((_c = (_b = (
|
|
7638
|
+
String((_c = (_b = (_a3 = p.type) != null ? _a3 : p.view) != null ? _b : p.chartType) != null ? _c : "")
|
|
7515
7639
|
);
|
|
7516
7640
|
if (!type) return null;
|
|
7517
7641
|
const title = String((_e = (_d = p.title) != null ? _d : p.heading) != null ? _e : "Visualization");
|
|
@@ -7522,7 +7646,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7522
7646
|
return this.validateTransformation(transformation) ? transformation : null;
|
|
7523
7647
|
}
|
|
7524
7648
|
static normalizeVisualizationType(type) {
|
|
7525
|
-
var
|
|
7649
|
+
var _a3;
|
|
7526
7650
|
const mapping = {
|
|
7527
7651
|
pie: "pie_chart",
|
|
7528
7652
|
pie_chart: "pie_chart",
|
|
@@ -7550,7 +7674,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7550
7674
|
product_carousel: "product_carousel",
|
|
7551
7675
|
carousel: "carousel"
|
|
7552
7676
|
};
|
|
7553
|
-
return (
|
|
7677
|
+
return (_a3 = mapping[type.toLowerCase()]) != null ? _a3 : null;
|
|
7554
7678
|
}
|
|
7555
7679
|
static validateTransformation(t) {
|
|
7556
7680
|
const { type, data } = t;
|
|
@@ -7666,7 +7790,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7666
7790
|
}
|
|
7667
7791
|
static profileData(data) {
|
|
7668
7792
|
const records = (data || []).filter((item) => Boolean(item && typeof item === "object")).map((item) => {
|
|
7669
|
-
var
|
|
7793
|
+
var _a3, _b;
|
|
7670
7794
|
const fields2 = {};
|
|
7671
7795
|
Object.entries(item.metadata || {}).forEach(([key, value]) => {
|
|
7672
7796
|
const primitive = this.toPrimitive(value);
|
|
@@ -7675,7 +7799,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7675
7799
|
if (!fields2.content && item.content) fields2.content = item.content.substring(0, 500);
|
|
7676
7800
|
return {
|
|
7677
7801
|
id: item.id,
|
|
7678
|
-
content: (
|
|
7802
|
+
content: (_a3 = item.content) != null ? _a3 : "",
|
|
7679
7803
|
score: (_b = item.score) != null ? _b : 0,
|
|
7680
7804
|
fields: fields2,
|
|
7681
7805
|
source: item
|
|
@@ -7756,16 +7880,16 @@ ${schemaProfileText}` : ""}`;
|
|
|
7756
7880
|
return null;
|
|
7757
7881
|
}
|
|
7758
7882
|
static selectDimensionField(profile, query) {
|
|
7759
|
-
var
|
|
7883
|
+
var _a3, _b;
|
|
7760
7884
|
const productCategory = profile.categoricalFields.find(
|
|
7761
7885
|
(field) => /category|department|collection|type|group|segment|region|country|state|city/i.test(field.key)
|
|
7762
7886
|
);
|
|
7763
7887
|
const ranked = this.rankFieldsByQuery(profile.categoricalFields, query);
|
|
7764
|
-
return (_b = (
|
|
7888
|
+
return (_b = (_a3 = ranked[0]) != null ? _a3 : productCategory) != null ? _b : profile.categoricalFields[0];
|
|
7765
7889
|
}
|
|
7766
7890
|
static selectNumericField(profile, query) {
|
|
7767
|
-
var
|
|
7768
|
-
return (
|
|
7891
|
+
var _a3;
|
|
7892
|
+
return (_a3 = this.rankFieldsByQuery(profile.numericFields, query)[0]) != null ? _a3 : profile.numericFields[0];
|
|
7769
7893
|
}
|
|
7770
7894
|
static rankFieldsByQuery(fields, query) {
|
|
7771
7895
|
const q = query.toLowerCase();
|
|
@@ -7794,8 +7918,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7794
7918
|
static aggregateProfileByDimension(profile, dimensionKey, measureKey) {
|
|
7795
7919
|
const result = {};
|
|
7796
7920
|
profile.records.forEach((record) => {
|
|
7797
|
-
var
|
|
7798
|
-
const category = String((
|
|
7921
|
+
var _a3, _b, _c;
|
|
7922
|
+
const category = String((_a3 = record.fields[dimensionKey]) != null ? _a3 : "Other").trim() || "Other";
|
|
7799
7923
|
const value = measureKey ? (_b = this.toFiniteNumber(record.fields[measureKey])) != null ? _b : 0 : 1;
|
|
7800
7924
|
result[category] = ((_c = result[category]) != null ? _c : 0) + value;
|
|
7801
7925
|
});
|
|
@@ -7875,8 +7999,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7875
7999
|
static aggregateByCategory(data, categories) {
|
|
7876
8000
|
const result = Object.fromEntries(categories.map((c) => [c, 0]));
|
|
7877
8001
|
data.forEach((item) => {
|
|
7878
|
-
var
|
|
7879
|
-
const cat = (
|
|
8002
|
+
var _a3;
|
|
8003
|
+
const cat = (_a3 = this.getProductCategory(item)) != null ? _a3 : "Other";
|
|
7880
8004
|
if (Object.prototype.hasOwnProperty.call(result, cat)) result[cat]++;
|
|
7881
8005
|
else result["Other"] = (result["Other"] || 0) + 1;
|
|
7882
8006
|
});
|
|
@@ -7884,17 +8008,17 @@ ${schemaProfileText}` : ""}`;
|
|
|
7884
8008
|
}
|
|
7885
8009
|
static extractTimeSeriesData(data) {
|
|
7886
8010
|
return data.map((item) => {
|
|
7887
|
-
var
|
|
8011
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
7888
8012
|
const meta = item.metadata || {};
|
|
7889
8013
|
return {
|
|
7890
|
-
timestamp: (_b = (
|
|
8014
|
+
timestamp: (_b = (_a3 = meta.timestamp) != null ? _a3 : meta.date) != null ? _b : (/* @__PURE__ */ new Date()).toISOString(),
|
|
7891
8015
|
value: (_d = (_c = meta.value) != null ? _c : item.score) != null ? _d : 0,
|
|
7892
8016
|
label: (_f = meta.label) != null ? _f : ((_e = item == null ? void 0 : item.content) != null ? _e : "").substring(0, 50)
|
|
7893
8017
|
};
|
|
7894
8018
|
});
|
|
7895
8019
|
}
|
|
7896
8020
|
static extractNumericValue(meta) {
|
|
7897
|
-
var
|
|
8021
|
+
var _a3;
|
|
7898
8022
|
const preferredKeys = [
|
|
7899
8023
|
"value",
|
|
7900
8024
|
"count",
|
|
@@ -7909,7 +8033,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7909
8033
|
"price"
|
|
7910
8034
|
];
|
|
7911
8035
|
for (const key of preferredKeys) {
|
|
7912
|
-
const raw = (
|
|
8036
|
+
const raw = (_a3 = resolveMetadataValue(meta, key)) != null ? _a3 : meta[key];
|
|
7913
8037
|
const value = typeof raw === "number" ? raw : Number(String(raw != null ? raw : "").replace(/[$,% ,]/g, ""));
|
|
7914
8038
|
if (Number.isFinite(value)) return value;
|
|
7915
8039
|
}
|
|
@@ -8004,8 +8128,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
8004
8128
|
}, query.includes(normalizedField) ? 3 : 0);
|
|
8005
8129
|
}
|
|
8006
8130
|
static resolveTableCellValue(item, column) {
|
|
8007
|
-
var
|
|
8008
|
-
if (column === "Content") return ((
|
|
8131
|
+
var _a3, _b, _c;
|
|
8132
|
+
if (column === "Content") return ((_a3 = item == null ? void 0 : item.content) != null ? _a3 : "").substring(0, 100);
|
|
8009
8133
|
const meta = item.metadata || {};
|
|
8010
8134
|
const normalizedColumn = this.normalizeComparableField(column);
|
|
8011
8135
|
const exactMetadata = Object.entries(meta).find(
|
|
@@ -8057,8 +8181,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
8057
8181
|
let inStock = 0;
|
|
8058
8182
|
let outOfStock = 0;
|
|
8059
8183
|
data.forEach((d) => {
|
|
8060
|
-
var
|
|
8061
|
-
const cat = (
|
|
8184
|
+
var _a3, _b;
|
|
8185
|
+
const cat = (_a3 = this.getProductCategory(d)) != null ? _a3 : "Other";
|
|
8062
8186
|
if (cat === category) {
|
|
8063
8187
|
const quantity = (_b = this.extractStockQuantity(d)) != null ? _b : 1;
|
|
8064
8188
|
if (this.determineStockStatus(d)) inStock += quantity;
|
|
@@ -8104,9 +8228,9 @@ ${schemaProfileText}` : ""}`;
|
|
|
8104
8228
|
}
|
|
8105
8229
|
// ─── Product Extraction ───────────────────────────────────────────────────
|
|
8106
8230
|
static getDynamicVal(meta, uiKey, config, trainedSchema) {
|
|
8107
|
-
var
|
|
8231
|
+
var _a3;
|
|
8108
8232
|
if (!meta) return void 0;
|
|
8109
|
-
const mapping = (
|
|
8233
|
+
const mapping = (_a3 = config == null ? void 0 : config.rag) == null ? void 0 : _a3.uiMapping;
|
|
8110
8234
|
if ((mapping == null ? void 0 : mapping[uiKey]) && meta[mapping[uiKey]] !== void 0) return meta[mapping[uiKey]];
|
|
8111
8235
|
if (trainedSchema && typeof trainedSchema === "object") {
|
|
8112
8236
|
const trainedKey = trainedSchema[uiKey];
|
|
@@ -8115,7 +8239,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
8115
8239
|
return resolveMetadataValue(meta, uiKey);
|
|
8116
8240
|
}
|
|
8117
8241
|
static extractProductInfo(item, config, trainedSchema) {
|
|
8118
|
-
var
|
|
8242
|
+
var _a3, _b;
|
|
8119
8243
|
if (!item) return null;
|
|
8120
8244
|
const meta = item.metadata || {};
|
|
8121
8245
|
const content = item.content || "";
|
|
@@ -8123,7 +8247,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
8123
8247
|
const price = this.getDynamicVal(meta, "price", config, trainedSchema);
|
|
8124
8248
|
const brand = this.getDynamicVal(meta, "brand", config, trainedSchema);
|
|
8125
8249
|
const description = this.cleanProductDescription(
|
|
8126
|
-
(
|
|
8250
|
+
(_a3 = this.extractProductDescriptionFromContent(content)) != null ? _a3 : this.getProductDescriptionValue(meta, config, trainedSchema)
|
|
8127
8251
|
);
|
|
8128
8252
|
if (name || this.isProductData(item)) {
|
|
8129
8253
|
let finalName = name ? String(name) : void 0;
|
|
@@ -8258,10 +8382,10 @@ RULES:
|
|
|
8258
8382
|
}
|
|
8259
8383
|
static buildContextSummary(sources, maxChars = 6e3) {
|
|
8260
8384
|
const items = (sources || []).filter(Boolean).map((s, i) => {
|
|
8261
|
-
var
|
|
8385
|
+
var _a3, _b, _c, _d;
|
|
8262
8386
|
return {
|
|
8263
8387
|
index: i + 1,
|
|
8264
|
-
content: (_b = (
|
|
8388
|
+
content: (_b = (_a3 = s == null ? void 0 : s.content) == null ? void 0 : _a3.substring(0, 400)) != null ? _b : "",
|
|
8265
8389
|
metadata: (_c = s == null ? void 0 : s.metadata) != null ? _c : {},
|
|
8266
8390
|
score: (_d = s == null ? void 0 : s.score) != null ? _d : 0
|
|
8267
8391
|
};
|
|
@@ -8301,7 +8425,7 @@ var SchemaMapper = class {
|
|
|
8301
8425
|
return promise;
|
|
8302
8426
|
}
|
|
8303
8427
|
static async _doTrain(llm, cacheKey, keys) {
|
|
8304
|
-
var
|
|
8428
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
|
|
8305
8429
|
console.log(`[SchemaMapper] \u{1F9E0} Training on new schema keys: ${keys.join(", ")}`);
|
|
8306
8430
|
const propertyList = Object.entries(this.TARGET_PROPERTIES).map(([prop, desc]) => `- ${prop} (${desc})`).join("\n");
|
|
8307
8431
|
const messages = [
|
|
@@ -8317,7 +8441,7 @@ Return a JSON object like {"name":"Title","price":"Price",...}. Omit unmapped pr
|
|
|
8317
8441
|
}
|
|
8318
8442
|
];
|
|
8319
8443
|
try {
|
|
8320
|
-
const baseUrl = (
|
|
8444
|
+
const baseUrl = (_a3 = llm == null ? void 0 : llm.baseUrl) != null ? _a3 : "";
|
|
8321
8445
|
const apiKey = (_b = llm == null ? void 0 : llm.apiKey) != null ? _b : "";
|
|
8322
8446
|
const model = (_c = llm == null ? void 0 : llm.model) != null ? _c : "llama-3.1-8b-instant";
|
|
8323
8447
|
let responseText;
|
|
@@ -8492,9 +8616,9 @@ var Pipeline = class {
|
|
|
8492
8616
|
this.initialised = false;
|
|
8493
8617
|
/** Namespace-specific static cold context cache for CAG */
|
|
8494
8618
|
this.coldContexts = /* @__PURE__ */ new Map();
|
|
8495
|
-
var
|
|
8619
|
+
var _a3, _b, _c, _d, _e;
|
|
8496
8620
|
this.chunker = new DocumentChunker(
|
|
8497
|
-
(_b = (
|
|
8621
|
+
(_b = (_a3 = config.rag) == null ? void 0 : _a3.chunkSize) != null ? _b : 1e3,
|
|
8498
8622
|
(_d = (_c = config.rag) == null ? void 0 : _c.chunkOverlap) != null ? _d : 200
|
|
8499
8623
|
);
|
|
8500
8624
|
if (((_e = config.rag) == null ? void 0 : _e.chunkingStrategy) === "llamaindex") {
|
|
@@ -8510,7 +8634,7 @@ var Pipeline = class {
|
|
|
8510
8634
|
return this.initialised ? this.llmProvider : void 0;
|
|
8511
8635
|
}
|
|
8512
8636
|
async initialize() {
|
|
8513
|
-
var
|
|
8637
|
+
var _a3, _b, _c, _d;
|
|
8514
8638
|
if (this.initialised) return;
|
|
8515
8639
|
const chartInstruction = `You are a helpful assistant. Use the provided context to answer questions accurately.
|
|
8516
8640
|
|
|
@@ -8553,7 +8677,7 @@ var Pipeline = class {
|
|
|
8553
8677
|
this.entityExtractor = new EntityExtractor(this.llmProvider);
|
|
8554
8678
|
}
|
|
8555
8679
|
await this.vectorDB.initialize();
|
|
8556
|
-
if (((
|
|
8680
|
+
if (((_a3 = this.config.rag) == null ? void 0 : _a3.architecture) === "agentic" || ((_b = this.config.rag) == null ? void 0 : _b.architecture) === "multi-agent" || this.config.mcpServers && this.config.mcpServers.length > 0) {
|
|
8557
8681
|
this.mcpRegistry = new MCPRegistry(this.config.mcpServers || []);
|
|
8558
8682
|
this.multiAgentCoordinator = new MultiAgentCoordinator({
|
|
8559
8683
|
llmProvider: this.llmProvider,
|
|
@@ -8571,8 +8695,8 @@ var Pipeline = class {
|
|
|
8571
8695
|
this.initialised = true;
|
|
8572
8696
|
}
|
|
8573
8697
|
async loadColdContext(ns) {
|
|
8574
|
-
var
|
|
8575
|
-
const cagConfig = (
|
|
8698
|
+
var _a3, _b;
|
|
8699
|
+
const cagConfig = (_a3 = this.config.rag) == null ? void 0 : _a3.cag;
|
|
8576
8700
|
if (!cagConfig || !cagConfig.enabled) return;
|
|
8577
8701
|
try {
|
|
8578
8702
|
const coldNs = cagConfig.coldNamespace || ns;
|
|
@@ -8625,12 +8749,12 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8625
8749
|
}
|
|
8626
8750
|
/** Step 1: Chunk the document content. */
|
|
8627
8751
|
async prepareChunks(doc) {
|
|
8628
|
-
var
|
|
8752
|
+
var _a3, _b;
|
|
8629
8753
|
if (this.llamaIngestor) {
|
|
8630
8754
|
return this.llamaIngestor.chunk(doc.content, {
|
|
8631
8755
|
docId: doc.docId,
|
|
8632
8756
|
metadata: doc.metadata,
|
|
8633
|
-
chunkSize: (
|
|
8757
|
+
chunkSize: (_a3 = this.config.rag) == null ? void 0 : _a3.chunkSize,
|
|
8634
8758
|
chunkOverlap: (_b = this.config.rag) == null ? void 0 : _b.chunkOverlap
|
|
8635
8759
|
});
|
|
8636
8760
|
}
|
|
@@ -8728,9 +8852,9 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8728
8852
|
return { reply, sources };
|
|
8729
8853
|
}
|
|
8730
8854
|
async ask(question, history = [], namespace) {
|
|
8731
|
-
var
|
|
8855
|
+
var _a3, _b;
|
|
8732
8856
|
await this.initialize();
|
|
8733
|
-
if ((((
|
|
8857
|
+
if ((((_a3 = this.config.rag) == null ? void 0 : _a3.architecture) === "agentic" || ((_b = this.config.rag) == null ? void 0 : _b.architecture) === "multi-agent" || this.config.mcpServers && this.config.mcpServers.length > 0) && this.multiAgentCoordinator) {
|
|
8734
8858
|
return await this.multiAgentCoordinator.run(question, history);
|
|
8735
8859
|
}
|
|
8736
8860
|
const stream = this.askStream(question, history, namespace);
|
|
@@ -8765,9 +8889,9 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8765
8889
|
}
|
|
8766
8890
|
askStream(_0) {
|
|
8767
8891
|
return __asyncGenerator(this, arguments, function* (question, history = [], namespace) {
|
|
8768
|
-
var
|
|
8892
|
+
var _a3, _b;
|
|
8769
8893
|
yield new __await(this.initialize());
|
|
8770
|
-
if ((((
|
|
8894
|
+
if ((((_a3 = this.config.rag) == null ? void 0 : _a3.architecture) === "agentic" || ((_b = this.config.rag) == null ? void 0 : _b.architecture) === "multi-agent" || this.config.mcpServers && this.config.mcpServers.length > 0) && this.multiAgentCoordinator) {
|
|
8771
8895
|
const stream2 = this.multiAgentCoordinator.runStream(question, history);
|
|
8772
8896
|
try {
|
|
8773
8897
|
for (var iter = __forAwait(stream2), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
|
|
@@ -8816,10 +8940,10 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8816
8940
|
*/
|
|
8817
8941
|
askStreamInternal(_0) {
|
|
8818
8942
|
return __asyncGenerator(this, arguments, function* (question, history = [], namespace) {
|
|
8819
|
-
var
|
|
8943
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B;
|
|
8820
8944
|
yield new __await(this.initialize());
|
|
8821
8945
|
const ns = formatNamespace(namespace != null ? namespace : this.config.projectId);
|
|
8822
|
-
const topK = (_b = (
|
|
8946
|
+
const topK = (_b = (_a3 = this.config.rag) == null ? void 0 : _a3.topK) != null ? _b : 5;
|
|
8823
8947
|
const scoreThreshold = (_d = (_c = this.config.rag) == null ? void 0 : _c.scoreThreshold) != null ? _d : 0.3;
|
|
8824
8948
|
const requestId = `req_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
8825
8949
|
const requestStart = performance.now();
|
|
@@ -8868,8 +8992,8 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8868
8992
|
const rerankStart = performance.now();
|
|
8869
8993
|
const structuredSources = this.applyStructuredFilters(rawSources, filter).filter((s) => Boolean(s && typeof s === "object"));
|
|
8870
8994
|
let fullSources = hasNumericPredicates ? structuredSources : structuredSources.filter((m) => {
|
|
8871
|
-
var
|
|
8872
|
-
return ((
|
|
8995
|
+
var _a4;
|
|
8996
|
+
return ((_a4 = m == null ? void 0 : m.score) != null ? _a4 : 0) >= scoreThreshold;
|
|
8873
8997
|
});
|
|
8874
8998
|
const rerankLimit = Math.max(retrievalLimit, fullSources.length);
|
|
8875
8999
|
const useReranking = arch !== "naive" && (arch === "retrieve-and-rerank" || ((_m = this.config.rag) == null ? void 0 : _m.useReranking));
|
|
@@ -8882,13 +9006,13 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8882
9006
|
let context = promptSources.length ? `[SEARCH SUMMARY: Found ${totalCount} matching record(s) out of ${rawSources.length} total resources searched in database. Context includes top ${promptSources.length} relevant records]
|
|
8883
9007
|
|
|
8884
9008
|
` + promptSources.map((m, i) => {
|
|
8885
|
-
var
|
|
9009
|
+
var _a4;
|
|
8886
9010
|
return `[Source ${i + 1}]
|
|
8887
|
-
${(
|
|
9011
|
+
${(_a4 = m == null ? void 0 : m.content) != null ? _a4 : ""}`;
|
|
8888
9012
|
}).join("\n\n---\n\n") : "No relevant context found.";
|
|
8889
9013
|
const sources = [...fullSources].filter((s) => Boolean(s && typeof s === "object")).sort((a, b) => {
|
|
8890
|
-
var
|
|
8891
|
-
return ((
|
|
9014
|
+
var _a4, _b2;
|
|
9015
|
+
return ((_a4 = b == null ? void 0 : b.score) != null ? _a4 : 0) - ((_b2 = a == null ? void 0 : a.score) != null ? _b2 : 0);
|
|
8892
9016
|
});
|
|
8893
9017
|
if (graphData && graphData.nodes.length > 0) {
|
|
8894
9018
|
const graphContext = graphData.nodes.map(
|
|
@@ -8916,10 +9040,10 @@ ${context}`;
|
|
|
8916
9040
|
yield {
|
|
8917
9041
|
reply: "",
|
|
8918
9042
|
sources: (sources || []).filter((s) => Boolean(s && typeof s === "object")).map((s) => {
|
|
8919
|
-
var
|
|
9043
|
+
var _a4, _b2, _c2;
|
|
8920
9044
|
return {
|
|
8921
9045
|
id: s.id,
|
|
8922
|
-
score: (
|
|
9046
|
+
score: (_a4 = s.score) != null ? _a4 : 0,
|
|
8923
9047
|
content: (_b2 = s == null ? void 0 : s.content) != null ? _b2 : "",
|
|
8924
9048
|
metadata: (_c2 = s == null ? void 0 : s.metadata) != null ? _c2 : {},
|
|
8925
9049
|
namespace: ns
|
|
@@ -9112,11 +9236,11 @@ ${context}`;
|
|
|
9112
9236
|
systemPrompt,
|
|
9113
9237
|
userPrompt: question + finalRestrictionSuffix,
|
|
9114
9238
|
chunks: (sources || []).filter(Boolean).map((s) => {
|
|
9115
|
-
var
|
|
9239
|
+
var _a4, _b2;
|
|
9116
9240
|
return {
|
|
9117
9241
|
id: s.id,
|
|
9118
9242
|
score: s.score,
|
|
9119
|
-
content: (
|
|
9243
|
+
content: (_a4 = s == null ? void 0 : s.content) != null ? _a4 : "",
|
|
9120
9244
|
metadata: (_b2 = s == null ? void 0 : s.metadata) != null ? _b2 : {},
|
|
9121
9245
|
namespace: ns
|
|
9122
9246
|
};
|
|
@@ -9135,7 +9259,7 @@ ${context}`;
|
|
|
9135
9259
|
const telemetryUrl = ((_B = this.config.telemetry) == null ? void 0 : _B.url) || process.env.TELEMETRY_URL || process.env.NEXT_PUBLIC_TELEMETRY_URL || defaultUrl;
|
|
9136
9260
|
const absoluteUrl = telemetryUrl.startsWith("http") ? telemetryUrl : "https://www.retrivora.com" + (telemetryUrl.startsWith("/") ? telemetryUrl : "/" + telemetryUrl);
|
|
9137
9261
|
(async () => {
|
|
9138
|
-
var
|
|
9262
|
+
var _a4, _b2, _c2, _d2, _e2;
|
|
9139
9263
|
try {
|
|
9140
9264
|
let finalTrace = trace;
|
|
9141
9265
|
if (!awaitHallucination && runHallucination) {
|
|
@@ -9144,7 +9268,7 @@ ${context}`;
|
|
|
9144
9268
|
finalTrace = buildTrace(backgroundScoreResult);
|
|
9145
9269
|
}
|
|
9146
9270
|
}
|
|
9147
|
-
const modelName = (finalTrace == null ? void 0 : finalTrace.model) || ((
|
|
9271
|
+
const modelName = (finalTrace == null ? void 0 : finalTrace.model) || ((_a4 = this.config.llm) == null ? void 0 : _a4.model) || "llama-3.1-8b-instant";
|
|
9148
9272
|
const providerName = (finalTrace == null ? void 0 : finalTrace.provider) || ((_b2 = this.config.llm) == null ? void 0 : _b2.provider) || "groq";
|
|
9149
9273
|
const tokenCount = Number(((_c2 = finalTrace == null ? void 0 : finalTrace.tokens) == null ? void 0 : _c2.totalTokens) || 0);
|
|
9150
9274
|
const costEst = Number(((_d2 = finalTrace == null ? void 0 : finalTrace.tokens) == null ? void 0 : _d2.estimatedCostUsd) || 0);
|
|
@@ -9198,7 +9322,7 @@ ${context}`;
|
|
|
9198
9322
|
* Uses an LRU-bounded embedding cache to avoid re-embedding the same query.
|
|
9199
9323
|
*/
|
|
9200
9324
|
async generateUiTransformation(question, sources, cachedSchema, forceDeterministic = false) {
|
|
9201
|
-
var
|
|
9325
|
+
var _a3;
|
|
9202
9326
|
if (!sources || sources.length === 0) {
|
|
9203
9327
|
return UITransformer.transform(question, sources, this.config, cachedSchema);
|
|
9204
9328
|
}
|
|
@@ -9211,7 +9335,7 @@ ${context}`;
|
|
|
9211
9335
|
{ visualizationHint: "product_browse", recommendedChart: "text", filterInStockOnly: false, wantsExplicitTable: false, isTemporal: false, isComparison: false, language: "en" }
|
|
9212
9336
|
);
|
|
9213
9337
|
}
|
|
9214
|
-
const enableLlmUiTransform = ((
|
|
9338
|
+
const enableLlmUiTransform = ((_a3 = this.config.llm.options) == null ? void 0 : _a3.enableLlmUiTransform) === true;
|
|
9215
9339
|
if (forceDeterministic || !enableLlmUiTransform) {
|
|
9216
9340
|
return UITransformer.transform(question, sources, this.config, cachedSchema);
|
|
9217
9341
|
}
|
|
@@ -9229,15 +9353,15 @@ ${context}`;
|
|
|
9229
9353
|
const value = this.resolveNumericPredicateValue(source, predicate);
|
|
9230
9354
|
return value !== null && this.matchesNumericPredicate(value, predicate);
|
|
9231
9355
|
})).sort((a, b) => {
|
|
9232
|
-
var
|
|
9356
|
+
var _a3, _b;
|
|
9233
9357
|
const primary = predicates[0];
|
|
9234
|
-
const aValue = (
|
|
9358
|
+
const aValue = (_a3 = this.resolveNumericPredicateValue(a, primary)) != null ? _a3 : 0;
|
|
9235
9359
|
const bValue = (_b = this.resolveNumericPredicateValue(b, primary)) != null ? _b : 0;
|
|
9236
9360
|
return primary.operator === "lt" || primary.operator === "lte" ? aValue - bValue : bValue - aValue;
|
|
9237
9361
|
});
|
|
9238
9362
|
}
|
|
9239
9363
|
resolveNumericPredicateValue(source, predicate) {
|
|
9240
|
-
var
|
|
9364
|
+
var _a3;
|
|
9241
9365
|
if (!source) return null;
|
|
9242
9366
|
const meta = source.metadata || {};
|
|
9243
9367
|
const field = predicate.field;
|
|
@@ -9250,7 +9374,7 @@ ${context}`;
|
|
|
9250
9374
|
const value = this.toFiniteNumber(Array.isArray(fuzzy) ? fuzzy[1] : fuzzy.value);
|
|
9251
9375
|
if (value !== null) return value;
|
|
9252
9376
|
}
|
|
9253
|
-
const contentValue = this.extractNumericValueFromContent((
|
|
9377
|
+
const contentValue = this.extractNumericValueFromContent((_a3 = source.content) != null ? _a3 : "", field);
|
|
9254
9378
|
if (contentValue !== null) return contentValue;
|
|
9255
9379
|
}
|
|
9256
9380
|
for (const [key, value] of entries) {
|
|
@@ -9306,8 +9430,8 @@ ${context}`;
|
|
|
9306
9430
|
return Number.isFinite(numeric) ? numeric : null;
|
|
9307
9431
|
}
|
|
9308
9432
|
async retrieve(query, options) {
|
|
9309
|
-
var
|
|
9310
|
-
const ns = formatNamespace((
|
|
9433
|
+
var _a3, _b, _c, _d, _e, _f, _g2;
|
|
9434
|
+
const ns = formatNamespace((_a3 = options.namespace) != null ? _a3 : this.config.projectId);
|
|
9311
9435
|
const topK = (_b = options.topK) != null ? _b : 5;
|
|
9312
9436
|
const cacheKey = `${ns}::${query}`;
|
|
9313
9437
|
let queryVector = this.embeddingCache.get(cacheKey);
|
|
@@ -9352,11 +9476,11 @@ ${context}`;
|
|
|
9352
9476
|
namespace: ns,
|
|
9353
9477
|
count: resolvedSources.length,
|
|
9354
9478
|
sample: resolvedSources.slice(0, 2).map((s) => {
|
|
9355
|
-
var
|
|
9479
|
+
var _a4;
|
|
9356
9480
|
return {
|
|
9357
9481
|
id: s == null ? void 0 : s.id,
|
|
9358
9482
|
score: s == null ? void 0 : s.score,
|
|
9359
|
-
contentSnippet: String((
|
|
9483
|
+
contentSnippet: String((_a4 = s == null ? void 0 : s.content) != null ? _a4 : "").substring(0, 150),
|
|
9360
9484
|
metadata: s == null ? void 0 : s.metadata
|
|
9361
9485
|
};
|
|
9362
9486
|
})
|
|
@@ -9370,8 +9494,8 @@ Focus on extracting the core intent and entities. Do not answer the question, ju
|
|
|
9370
9494
|
|
|
9371
9495
|
History:
|
|
9372
9496
|
${(history || []).map((m) => {
|
|
9373
|
-
var
|
|
9374
|
-
return `${(m == null ? void 0 : m.role) || "user"}: ${(
|
|
9497
|
+
var _a3;
|
|
9498
|
+
return `${(m == null ? void 0 : m.role) || "user"}: ${(_a3 = m == null ? void 0 : m.content) != null ? _a3 : ""}`;
|
|
9375
9499
|
}).join("\n")}
|
|
9376
9500
|
|
|
9377
9501
|
New Question: ${question}
|
|
@@ -9398,8 +9522,8 @@ Optimized Search Query:`;
|
|
|
9398
9522
|
const { sources } = await this.retrieve(query, { namespace: ns, topK: 5 });
|
|
9399
9523
|
if (!sources || sources.length === 0) return [];
|
|
9400
9524
|
const context = sources.map((s) => {
|
|
9401
|
-
var
|
|
9402
|
-
return (
|
|
9525
|
+
var _a3;
|
|
9526
|
+
return (_a3 = s == null ? void 0 : s.content) != null ? _a3 : "";
|
|
9403
9527
|
}).join("\n\n---\n\n");
|
|
9404
9528
|
const prompt = `Based on the following snippets from a document, what are at least 5 short, relevant questions a user might ask?
|
|
9405
9529
|
Focus on questions that can be answered by the context.
|
|
@@ -9441,13 +9565,13 @@ var Retrivora = class {
|
|
|
9441
9565
|
this.pipeline = new Pipeline(this.config);
|
|
9442
9566
|
}
|
|
9443
9567
|
async initialize() {
|
|
9444
|
-
var
|
|
9568
|
+
var _a3;
|
|
9445
9569
|
try {
|
|
9446
9570
|
await ConfigValidator.validateAndThrow(this.config);
|
|
9447
9571
|
LicenseVerifier.verify(
|
|
9448
9572
|
this.config.licenseKey,
|
|
9449
9573
|
this.config.projectId,
|
|
9450
|
-
(
|
|
9574
|
+
(_a3 = this.config.vectorDb) == null ? void 0 : _a3.provider
|
|
9451
9575
|
);
|
|
9452
9576
|
await LicenseVerifier.verifyIP(this.config.licenseKey);
|
|
9453
9577
|
} catch (err) {
|
|
@@ -9620,18 +9744,200 @@ var ProviderHealthCheck = class {
|
|
|
9620
9744
|
}
|
|
9621
9745
|
};
|
|
9622
9746
|
|
|
9747
|
+
// src/core/FreeTierLimitsGuard.ts
|
|
9748
|
+
var FREE_TIER_QUOTAS = {
|
|
9749
|
+
MAX_DOCUMENTS: 25,
|
|
9750
|
+
MAX_FILE_SIZE_BYTES: 20 * 1024 * 1024,
|
|
9751
|
+
MAX_STORAGE_BYTES: 250 * 1024 * 1024,
|
|
9752
|
+
MAX_TRIAL_REQUEST_UNITS: 500,
|
|
9753
|
+
MAX_DAILY_REQUEST_UNITS: 50,
|
|
9754
|
+
TRIAL_DURATION_DAYS: 14,
|
|
9755
|
+
GRACE_PERIOD_DAYS: 2,
|
|
9756
|
+
MAX_RPM: 10,
|
|
9757
|
+
MAX_RPH: 100,
|
|
9758
|
+
MAX_RPD: 500,
|
|
9759
|
+
MAX_CONCURRENT_REQUESTS: 2,
|
|
9760
|
+
MAX_INPUT_TOKENS: 2e4,
|
|
9761
|
+
MAX_OUTPUT_TOKENS: 4e3,
|
|
9762
|
+
UPGRADE_REMINDER_DAYS: [7, 12, 14],
|
|
9763
|
+
MAX_USERS: 1,
|
|
9764
|
+
MAX_NAMESPACES: 1,
|
|
9765
|
+
MAX_PROJECTS: 1
|
|
9766
|
+
};
|
|
9767
|
+
var FreeTierLimitsGuard = class {
|
|
9768
|
+
static calculateTrialTimestamps(startedAt) {
|
|
9769
|
+
const startDate = startedAt ? new Date(startedAt) : /* @__PURE__ */ new Date();
|
|
9770
|
+
const trialStartedAtMs = startDate.getTime();
|
|
9771
|
+
const trialExpiresAtMs = trialStartedAtMs + FREE_TIER_QUOTAS.TRIAL_DURATION_DAYS * 24 * 60 * 60 * 1e3;
|
|
9772
|
+
const gracePeriodExpiresAtMs = trialStartedAtMs + (FREE_TIER_QUOTAS.TRIAL_DURATION_DAYS + FREE_TIER_QUOTAS.GRACE_PERIOD_DAYS) * 24 * 60 * 60 * 1e3;
|
|
9773
|
+
return {
|
|
9774
|
+
trial_started_at: new Date(trialStartedAtMs).toISOString(),
|
|
9775
|
+
trial_expires_at: new Date(trialExpiresAtMs).toISOString(),
|
|
9776
|
+
grace_period_expires_at: new Date(gracePeriodExpiresAtMs).toISOString()
|
|
9777
|
+
};
|
|
9778
|
+
}
|
|
9779
|
+
static calculateRequestUnits(operationType, options) {
|
|
9780
|
+
var _a3;
|
|
9781
|
+
const op = operationType.toLowerCase().trim();
|
|
9782
|
+
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")) {
|
|
9783
|
+
return 0;
|
|
9784
|
+
}
|
|
9785
|
+
if (op.includes("image")) {
|
|
9786
|
+
return 10;
|
|
9787
|
+
}
|
|
9788
|
+
if (op.includes("embedding")) {
|
|
9789
|
+
const chunks = (_a3 = options == null ? void 0 : options.chunkCount) != null ? _a3 : 1;
|
|
9790
|
+
return Math.max(1, Math.ceil(chunks / 1e3));
|
|
9791
|
+
}
|
|
9792
|
+
return 1;
|
|
9793
|
+
}
|
|
9794
|
+
static checkTrialStatus(startedAt, totalUnitsUsed = 0, nowServerTime = /* @__PURE__ */ new Date()) {
|
|
9795
|
+
const timestamps = this.calculateTrialTimestamps(startedAt);
|
|
9796
|
+
const startMs = new Date(timestamps.trial_started_at).getTime();
|
|
9797
|
+
const expireMs = new Date(timestamps.trial_expires_at).getTime();
|
|
9798
|
+
const graceExpireMs = new Date(timestamps.grace_period_expires_at).getTime();
|
|
9799
|
+
const nowMs = nowServerTime.getTime();
|
|
9800
|
+
const daysElapsed = Math.floor(Math.max(0, nowMs - startMs) / (1e3 * 60 * 60 * 24));
|
|
9801
|
+
const daysRemaining = Math.max(0, Math.ceil((expireMs - nowMs) / (1e3 * 60 * 60 * 24)));
|
|
9802
|
+
const isConsumedUnits = totalUnitsUsed >= FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS;
|
|
9803
|
+
const isExpiredTime = nowMs > expireMs;
|
|
9804
|
+
const isPastGraceTime = nowMs > graceExpireMs;
|
|
9805
|
+
let status = "active";
|
|
9806
|
+
let reason;
|
|
9807
|
+
if (isPastGraceTime || isConsumedUnits && isExpiredTime) {
|
|
9808
|
+
status = "expired";
|
|
9809
|
+
reason = "Trial period and grace period have expired. Upgrade your plan.";
|
|
9810
|
+
} else if (isExpiredTime || isConsumedUnits) {
|
|
9811
|
+
status = "grace_period";
|
|
9812
|
+
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).";
|
|
9813
|
+
}
|
|
9814
|
+
let upgradeReminderDue;
|
|
9815
|
+
if (FREE_TIER_QUOTAS.UPGRADE_REMINDER_DAYS.includes(daysElapsed)) {
|
|
9816
|
+
upgradeReminderDue = daysElapsed;
|
|
9817
|
+
}
|
|
9818
|
+
let usageReminderDue;
|
|
9819
|
+
const usagePercent = totalUnitsUsed / FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS * 100;
|
|
9820
|
+
if (usagePercent >= 100) {
|
|
9821
|
+
usageReminderDue = "100%";
|
|
9822
|
+
} else if (usagePercent >= 90) {
|
|
9823
|
+
usageReminderDue = "90%";
|
|
9824
|
+
} else if (usagePercent >= 80) {
|
|
9825
|
+
usageReminderDue = "80%";
|
|
9826
|
+
}
|
|
9827
|
+
return {
|
|
9828
|
+
status,
|
|
9829
|
+
daysElapsed,
|
|
9830
|
+
daysRemaining,
|
|
9831
|
+
isGracePeriod: status === "grace_period",
|
|
9832
|
+
isExpired: status === "expired",
|
|
9833
|
+
upgradeReminderDue,
|
|
9834
|
+
usageReminderDue,
|
|
9835
|
+
reason
|
|
9836
|
+
};
|
|
9837
|
+
}
|
|
9838
|
+
static checkIngestionAllowed(stats, incomingSizeBytes = 0) {
|
|
9839
|
+
var _a3, _b;
|
|
9840
|
+
const docs = (_a3 = stats.documentCount) != null ? _a3 : 0;
|
|
9841
|
+
const storage = (_b = stats.totalStorageBytes) != null ? _b : 0;
|
|
9842
|
+
if (incomingSizeBytes > FREE_TIER_QUOTAS.MAX_FILE_SIZE_BYTES) {
|
|
9843
|
+
const mbSize = (incomingSizeBytes / (1024 * 1024)).toFixed(1);
|
|
9844
|
+
return {
|
|
9845
|
+
allowed: false,
|
|
9846
|
+
reason: `[FreeTierIngestor] File size (${mbSize}MB) exceeds maximum allowed size of 20MB under Free Tier rules.`
|
|
9847
|
+
};
|
|
9848
|
+
}
|
|
9849
|
+
if (docs >= FREE_TIER_QUOTAS.MAX_DOCUMENTS) {
|
|
9850
|
+
return {
|
|
9851
|
+
allowed: false,
|
|
9852
|
+
reason: `Document limit reached (${docs}/${FREE_TIER_QUOTAS.MAX_DOCUMENTS}). Upgrade to Pro to ingest more documents.`
|
|
9853
|
+
};
|
|
9854
|
+
}
|
|
9855
|
+
if (storage + incomingSizeBytes > FREE_TIER_QUOTAS.MAX_STORAGE_BYTES) {
|
|
9856
|
+
const mbUsed = (storage / (1024 * 1024)).toFixed(1);
|
|
9857
|
+
return {
|
|
9858
|
+
allowed: false,
|
|
9859
|
+
reason: `Storage quota exceeded (${mbUsed}MB / 250MB). Upgrade for unlimited storage.`
|
|
9860
|
+
};
|
|
9861
|
+
}
|
|
9862
|
+
return { allowed: true };
|
|
9863
|
+
}
|
|
9864
|
+
static checkRequestAllowed(params) {
|
|
9865
|
+
var _a3, _b, _c;
|
|
9866
|
+
const op = (_a3 = params.operationType) != null ? _a3 : "chat";
|
|
9867
|
+
const costUnits = this.calculateRequestUnits(op, { chunkCount: params.chunkCount });
|
|
9868
|
+
if (costUnits === 0) {
|
|
9869
|
+
return { allowed: true, costUnits: 0 };
|
|
9870
|
+
}
|
|
9871
|
+
if (params.inputTokens && params.inputTokens > FREE_TIER_QUOTAS.MAX_INPUT_TOKENS) {
|
|
9872
|
+
return {
|
|
9873
|
+
allowed: false,
|
|
9874
|
+
reason: "Token limit exceeded. Upgrade your plan.",
|
|
9875
|
+
costUnits
|
|
9876
|
+
};
|
|
9877
|
+
}
|
|
9878
|
+
if (params.outputTokens && params.outputTokens > FREE_TIER_QUOTAS.MAX_OUTPUT_TOKENS) {
|
|
9879
|
+
return {
|
|
9880
|
+
allowed: false,
|
|
9881
|
+
reason: "Token limit exceeded. Upgrade your plan.",
|
|
9882
|
+
costUnits
|
|
9883
|
+
};
|
|
9884
|
+
}
|
|
9885
|
+
if (params.concurrentRequests && params.concurrentRequests > FREE_TIER_QUOTAS.MAX_CONCURRENT_REQUESTS) {
|
|
9886
|
+
return {
|
|
9887
|
+
allowed: false,
|
|
9888
|
+
reason: `Concurrent limit exceeded (max ${FREE_TIER_QUOTAS.MAX_CONCURRENT_REQUESTS} active requests). Please wait for active streams to finish.`,
|
|
9889
|
+
costUnits
|
|
9890
|
+
};
|
|
9891
|
+
}
|
|
9892
|
+
const totalUnits = (_b = params.totalUnitsUsed) != null ? _b : 0;
|
|
9893
|
+
const trialStatus = this.checkTrialStatus(params.trialStartedAt, totalUnits, params.nowServerTime);
|
|
9894
|
+
if (trialStatus.status === "expired" || trialStatus.status === "grace_period") {
|
|
9895
|
+
return {
|
|
9896
|
+
allowed: false,
|
|
9897
|
+
reason: trialStatus.reason || "Trial limit reached. Upgrade your plan.",
|
|
9898
|
+
costUnits
|
|
9899
|
+
};
|
|
9900
|
+
}
|
|
9901
|
+
if (totalUnits + costUnits > FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS) {
|
|
9902
|
+
return {
|
|
9903
|
+
allowed: false,
|
|
9904
|
+
reason: `Total trial request unit limit reached (${totalUnits}/${FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS}). Upgrade your plan.`,
|
|
9905
|
+
costUnits
|
|
9906
|
+
};
|
|
9907
|
+
}
|
|
9908
|
+
const dailyUnits = (_c = params.dailyUnitsUsed) != null ? _c : 0;
|
|
9909
|
+
if (dailyUnits + costUnits > FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS) {
|
|
9910
|
+
return {
|
|
9911
|
+
allowed: false,
|
|
9912
|
+
reason: `Daily request quota limit reached (${dailyUnits}/${FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS} units/day). Quota resets tomorrow.`,
|
|
9913
|
+
costUnits
|
|
9914
|
+
};
|
|
9915
|
+
}
|
|
9916
|
+
return { allowed: true, costUnits };
|
|
9917
|
+
}
|
|
9918
|
+
static checkQueryAllowed(dailyQueriesCount = 0) {
|
|
9919
|
+
if (dailyQueriesCount >= FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS) {
|
|
9920
|
+
return {
|
|
9921
|
+
allowed: false,
|
|
9922
|
+
reason: `Daily query limit reached (${FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS}/day). Quota resets tomorrow.`
|
|
9923
|
+
};
|
|
9924
|
+
}
|
|
9925
|
+
return { allowed: true };
|
|
9926
|
+
}
|
|
9927
|
+
};
|
|
9928
|
+
|
|
9623
9929
|
// src/core/VectorPlugin.ts
|
|
9624
9930
|
var VectorPlugin = class {
|
|
9625
9931
|
constructor(hostConfig) {
|
|
9626
9932
|
const resolvedConfig = ConfigResolver.resolve(hostConfig);
|
|
9627
9933
|
this.config = resolvedConfig;
|
|
9628
9934
|
this.validationPromise = (async () => {
|
|
9629
|
-
var
|
|
9935
|
+
var _a3;
|
|
9630
9936
|
await ConfigValidator.validateAndThrow(resolvedConfig);
|
|
9631
9937
|
LicenseVerifier.verify(
|
|
9632
9938
|
resolvedConfig.licenseKey,
|
|
9633
9939
|
resolvedConfig.projectId,
|
|
9634
|
-
(
|
|
9940
|
+
(_a3 = resolvedConfig.vectorDb) == null ? void 0 : _a3.provider
|
|
9635
9941
|
);
|
|
9636
9942
|
})();
|
|
9637
9943
|
this.validationPromise.catch(() => {
|
|
@@ -9665,16 +9971,32 @@ var VectorPlugin = class {
|
|
|
9665
9971
|
this.config.embedding
|
|
9666
9972
|
);
|
|
9667
9973
|
}
|
|
9974
|
+
estimateInputTokens(message, history = []) {
|
|
9975
|
+
const allContent = message.length + history.reduce((acc, m) => {
|
|
9976
|
+
var _a3, _b;
|
|
9977
|
+
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);
|
|
9978
|
+
}, 0);
|
|
9979
|
+
return Math.ceil(allContent / 4);
|
|
9980
|
+
}
|
|
9668
9981
|
/**
|
|
9669
9982
|
* Run a chat query.
|
|
9670
9983
|
*/
|
|
9671
9984
|
async chat(message, history = [], namespace) {
|
|
9985
|
+
var _a3;
|
|
9672
9986
|
try {
|
|
9673
9987
|
await this.validationPromise;
|
|
9674
9988
|
} catch (err) {
|
|
9675
9989
|
throw wrapError(err, "CONFIGURATION_ERROR");
|
|
9676
9990
|
}
|
|
9677
9991
|
try {
|
|
9992
|
+
const inputTokens = this.estimateInputTokens(message, history);
|
|
9993
|
+
const tokenCheck = FreeTierLimitsGuard.checkRequestAllowed({
|
|
9994
|
+
operationType: "chat",
|
|
9995
|
+
inputTokens
|
|
9996
|
+
});
|
|
9997
|
+
if (!tokenCheck.allowed && ((_a3 = tokenCheck.reason) == null ? void 0 : _a3.toLowerCase().includes("token"))) {
|
|
9998
|
+
throw wrapError(new Error(tokenCheck.reason), "RATE_LIMITED");
|
|
9999
|
+
}
|
|
9678
10000
|
return await this.pipeline.ask(message, history, namespace);
|
|
9679
10001
|
} catch (err) {
|
|
9680
10002
|
const msg = String(err);
|
|
@@ -9682,6 +10004,9 @@ var VectorPlugin = class {
|
|
|
9682
10004
|
if (msg.includes("Embed") || msg.includes("embed")) {
|
|
9683
10005
|
defaultCode = "EMBEDDING_FAILED";
|
|
9684
10006
|
}
|
|
10007
|
+
if (msg.toLowerCase().includes("token limit")) {
|
|
10008
|
+
defaultCode = "RATE_LIMITED";
|
|
10009
|
+
}
|
|
9685
10010
|
throw wrapError(err, defaultCode);
|
|
9686
10011
|
}
|
|
9687
10012
|
}
|
|
@@ -9690,12 +10015,21 @@ var VectorPlugin = class {
|
|
|
9690
10015
|
*/
|
|
9691
10016
|
chatStream(_0) {
|
|
9692
10017
|
return __asyncGenerator(this, arguments, function* (message, history = [], namespace) {
|
|
10018
|
+
var _a3;
|
|
9693
10019
|
try {
|
|
9694
10020
|
yield new __await(this.validationPromise);
|
|
9695
10021
|
} catch (err) {
|
|
9696
10022
|
throw wrapError(err, "CONFIGURATION_ERROR");
|
|
9697
10023
|
}
|
|
9698
10024
|
try {
|
|
10025
|
+
const inputTokens = this.estimateInputTokens(message, history);
|
|
10026
|
+
const tokenCheck = FreeTierLimitsGuard.checkRequestAllowed({
|
|
10027
|
+
operationType: "chat_stream",
|
|
10028
|
+
inputTokens
|
|
10029
|
+
});
|
|
10030
|
+
if (!tokenCheck.allowed && ((_a3 = tokenCheck.reason) == null ? void 0 : _a3.toLowerCase().includes("token"))) {
|
|
10031
|
+
throw wrapError(new Error(tokenCheck.reason), "RATE_LIMITED");
|
|
10032
|
+
}
|
|
9699
10033
|
const stream = this.pipeline.askStream(message, history, namespace);
|
|
9700
10034
|
try {
|
|
9701
10035
|
for (var iter = __forAwait(stream), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
|
|
@@ -9718,6 +10052,9 @@ var VectorPlugin = class {
|
|
|
9718
10052
|
if (msg.includes("Embed") || msg.includes("embed")) {
|
|
9719
10053
|
defaultCode = "EMBEDDING_FAILED";
|
|
9720
10054
|
}
|
|
10055
|
+
if (msg.toLowerCase().includes("token limit")) {
|
|
10056
|
+
defaultCode = "RATE_LIMITED";
|
|
10057
|
+
}
|
|
9721
10058
|
throw wrapError(err, defaultCode);
|
|
9722
10059
|
}
|
|
9723
10060
|
});
|
|
@@ -9772,13 +10109,13 @@ var ConfigBuilder = class {
|
|
|
9772
10109
|
* Configure the vector database provider
|
|
9773
10110
|
*/
|
|
9774
10111
|
vectorDb(provider, options) {
|
|
9775
|
-
var
|
|
10112
|
+
var _a3;
|
|
9776
10113
|
if (provider === "auto") {
|
|
9777
10114
|
this._vectorDb = this._autoDetectVectorDb();
|
|
9778
10115
|
} else {
|
|
9779
10116
|
this._vectorDb = {
|
|
9780
10117
|
provider,
|
|
9781
|
-
indexName: (
|
|
10118
|
+
indexName: (_a3 = options == null ? void 0 : options.indexName) != null ? _a3 : "default",
|
|
9782
10119
|
options: __spreadValues({}, options)
|
|
9783
10120
|
};
|
|
9784
10121
|
}
|
|
@@ -9788,7 +10125,7 @@ var ConfigBuilder = class {
|
|
|
9788
10125
|
* Configure the LLM provider for chat
|
|
9789
10126
|
*/
|
|
9790
10127
|
llm(provider, model, apiKey, options) {
|
|
9791
|
-
var
|
|
10128
|
+
var _a3, _b;
|
|
9792
10129
|
if (provider === "auto") {
|
|
9793
10130
|
this._llm = this._autoDetectLLM();
|
|
9794
10131
|
} else {
|
|
@@ -9797,7 +10134,7 @@ var ConfigBuilder = class {
|
|
|
9797
10134
|
model: model != null ? model : "default-model",
|
|
9798
10135
|
apiKey,
|
|
9799
10136
|
systemPrompt: options == null ? void 0 : options.systemPrompt,
|
|
9800
|
-
maxTokens: (
|
|
10137
|
+
maxTokens: (_a3 = options == null ? void 0 : options.maxTokens) != null ? _a3 : 1024,
|
|
9801
10138
|
temperature: (_b = options == null ? void 0 : options.temperature) != null ? _b : 0.7,
|
|
9802
10139
|
baseUrl: options == null ? void 0 : options.baseUrl,
|
|
9803
10140
|
options
|
|
@@ -9840,8 +10177,8 @@ var ConfigBuilder = class {
|
|
|
9840
10177
|
* Set RAG-specific pipeline parameters
|
|
9841
10178
|
*/
|
|
9842
10179
|
rag(options) {
|
|
9843
|
-
var
|
|
9844
|
-
this._rag = __spreadValues(__spreadValues({}, (
|
|
10180
|
+
var _a3;
|
|
10181
|
+
this._rag = __spreadValues(__spreadValues({}, (_a3 = this._rag) != null ? _a3 : {}), options);
|
|
9845
10182
|
return this;
|
|
9846
10183
|
}
|
|
9847
10184
|
/**
|
|
@@ -9857,7 +10194,7 @@ var ConfigBuilder = class {
|
|
|
9857
10194
|
* Throws if required fields (projectId, vectorDb, llm, embedding) are not set.
|
|
9858
10195
|
*/
|
|
9859
10196
|
build() {
|
|
9860
|
-
var
|
|
10197
|
+
var _a3;
|
|
9861
10198
|
const missing = [];
|
|
9862
10199
|
if (!this._projectId) missing.push('projectId (call .projectId("my-app"))');
|
|
9863
10200
|
if (!this._vectorDb) missing.push('vectorDb (call .vectorDb("pinecone", { ... }))');
|
|
@@ -9869,7 +10206,7 @@ var ConfigBuilder = class {
|
|
|
9869
10206
|
${missing.join("\n ")}`
|
|
9870
10207
|
);
|
|
9871
10208
|
}
|
|
9872
|
-
const ragConfig = (
|
|
10209
|
+
const ragConfig = (_a3 = this._rag) != null ? _a3 : { chunkSize: 1e3, chunkOverlap: 200, topK: 5 };
|
|
9873
10210
|
if (process.env.RAG_USE_GRAPH_RETRIEVAL === "true") {
|
|
9874
10211
|
ragConfig.useGraphRetrieval = true;
|
|
9875
10212
|
}
|
|
@@ -9965,8 +10302,8 @@ var DocumentParser = class {
|
|
|
9965
10302
|
* Extract text from a File or Buffer based on its type.
|
|
9966
10303
|
*/
|
|
9967
10304
|
static async parse(file, fileName, mimeType) {
|
|
9968
|
-
var
|
|
9969
|
-
const extension = ((
|
|
10305
|
+
var _a3;
|
|
10306
|
+
const extension = ((_a3 = fileName.split(".").pop()) == null ? void 0 : _a3.toLowerCase()) || "";
|
|
9970
10307
|
if (extension === "txt" || extension === "md" || mimeType === "text/plain" || mimeType === "text/markdown") {
|
|
9971
10308
|
return this.readAsText(file);
|
|
9972
10309
|
}
|
|
@@ -10073,9 +10410,9 @@ var DatabaseStorage = class {
|
|
|
10073
10410
|
this.fallbackDir = this.isServerless ? path.join(os.tmpdir(), ".retrivora") : path.join(process.cwd(), ".retrivora");
|
|
10074
10411
|
this.historyFile = path.join(this.fallbackDir, "history.json");
|
|
10075
10412
|
this.feedbackFile = path.join(this.fallbackDir, "feedback.json");
|
|
10076
|
-
var
|
|
10413
|
+
var _a3, _b, _c, _d, _e;
|
|
10077
10414
|
this.config = config;
|
|
10078
|
-
this.provider = ((
|
|
10415
|
+
this.provider = ((_a3 = config.vectorDb) == null ? void 0 : _a3.provider) || "fs";
|
|
10079
10416
|
const rawHistoryTable = ((_c = (_b = config.rag) == null ? void 0 : _b.history) == null ? void 0 : _c.tableName) || "retrivora_history";
|
|
10080
10417
|
const rawFeedbackTable = ((_e = (_d = config.rag) == null ? void 0 : _d.feedback) == null ? void 0 : _e.tableName) || "retrivora_feedback";
|
|
10081
10418
|
this.historyTableName = rawHistoryTable.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
@@ -10110,16 +10447,16 @@ var DatabaseStorage = class {
|
|
|
10110
10447
|
}
|
|
10111
10448
|
}
|
|
10112
10449
|
checkHistoryEnabled() {
|
|
10113
|
-
var
|
|
10450
|
+
var _a3, _b;
|
|
10114
10451
|
this.checkPremiumSubscription();
|
|
10115
|
-
if (((_b = (
|
|
10452
|
+
if (((_b = (_a3 = this.config.rag) == null ? void 0 : _a3.history) == null ? void 0 : _b.enabled) === false) {
|
|
10116
10453
|
throw new Error("[Retrivora SDK] Chat History is disabled in RagConfig.");
|
|
10117
10454
|
}
|
|
10118
10455
|
}
|
|
10119
10456
|
checkFeedbackEnabled() {
|
|
10120
|
-
var
|
|
10457
|
+
var _a3, _b;
|
|
10121
10458
|
this.checkPremiumSubscription();
|
|
10122
|
-
if (((_b = (
|
|
10459
|
+
if (((_b = (_a3 = this.config.rag) == null ? void 0 : _a3.feedback) == null ? void 0 : _b.enabled) === false) {
|
|
10123
10460
|
throw new Error("[Retrivora SDK] User Feedback is disabled in RagConfig.");
|
|
10124
10461
|
}
|
|
10125
10462
|
}
|
|
@@ -10286,8 +10623,11 @@ var DatabaseStorage = class {
|
|
|
10286
10623
|
this.writeLocalFile(this.historyFile, history);
|
|
10287
10624
|
}
|
|
10288
10625
|
}
|
|
10289
|
-
async getHistory(sessionId) {
|
|
10626
|
+
async getHistory(sessionId, projectIds) {
|
|
10290
10627
|
this.checkHistoryEnabled();
|
|
10628
|
+
if (projectIds && projectIds.length > 0 && !this.sessionInScope(sessionId, projectIds)) {
|
|
10629
|
+
return [];
|
|
10630
|
+
}
|
|
10291
10631
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
10292
10632
|
const pool = await this.getPGPool();
|
|
10293
10633
|
const res = await pool.query(
|
|
@@ -10317,8 +10657,11 @@ var DatabaseStorage = class {
|
|
|
10317
10657
|
return history.filter((h) => h.session_id === sessionId).sort((a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime());
|
|
10318
10658
|
}
|
|
10319
10659
|
}
|
|
10320
|
-
async clearHistory(sessionId) {
|
|
10660
|
+
async clearHistory(sessionId, projectIds) {
|
|
10321
10661
|
this.checkHistoryEnabled();
|
|
10662
|
+
if (projectIds && projectIds.length > 0 && !this.sessionInScope(sessionId, projectIds)) {
|
|
10663
|
+
return;
|
|
10664
|
+
}
|
|
10322
10665
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
10323
10666
|
const pool = await this.getPGPool();
|
|
10324
10667
|
await pool.query(`DELETE FROM ${this.historyTableName} WHERE session_id = $1`, [sessionId]);
|
|
@@ -10337,21 +10680,36 @@ var DatabaseStorage = class {
|
|
|
10337
10680
|
this.writeLocalFile(this.feedbackFile, filteredFeedback);
|
|
10338
10681
|
}
|
|
10339
10682
|
}
|
|
10340
|
-
|
|
10683
|
+
/**
|
|
10684
|
+
* Return true when `sessionId` falls into the allowed `projectIds` scope.
|
|
10685
|
+
* When `projectIds` is empty / undefined we allow the call (legacy behavior
|
|
10686
|
+
* for non-multi-tenant consumers). Session ids typically begin with the
|
|
10687
|
+
* project id they were created for, so we prefix-match as well as contains-match
|
|
10688
|
+
* to catch sharded / suffix-style ids used by some integrations.
|
|
10689
|
+
*/
|
|
10690
|
+
sessionInScope(sessionId, projectIds) {
|
|
10691
|
+
if (!projectIds || projectIds.length === 0) return true;
|
|
10692
|
+
return projectIds.some(
|
|
10693
|
+
(pid) => pid && (sessionId === pid || sessionId.startsWith(pid) || sessionId.includes(pid))
|
|
10694
|
+
);
|
|
10695
|
+
}
|
|
10696
|
+
async listSessions(projectIds) {
|
|
10341
10697
|
this.checkHistoryEnabled();
|
|
10698
|
+
let raw = [];
|
|
10342
10699
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
10343
10700
|
const pool = await this.getPGPool();
|
|
10344
10701
|
const res = await pool.query(`SELECT DISTINCT session_id FROM ${this.historyTableName}`);
|
|
10345
|
-
|
|
10702
|
+
raw = res.rows.map((r) => r.session_id);
|
|
10346
10703
|
} else if (this.provider === "mongodb") {
|
|
10347
10704
|
await this.getMongoClient();
|
|
10348
10705
|
const db = this.getMongoDb();
|
|
10349
|
-
|
|
10706
|
+
raw = await db.collection(this.historyTableName).distinct("session_id");
|
|
10350
10707
|
} else {
|
|
10351
10708
|
const history = this.readLocalFile(this.historyFile);
|
|
10352
|
-
|
|
10353
|
-
return Array.from(sessions);
|
|
10709
|
+
raw = Array.from(new Set(history.map((h) => h.session_id)));
|
|
10354
10710
|
}
|
|
10711
|
+
if (!projectIds || projectIds.length === 0) return raw;
|
|
10712
|
+
return raw.filter((sid) => this.sessionInScope(sid, projectIds));
|
|
10355
10713
|
}
|
|
10356
10714
|
// ─── Feedback Operations ──────────────────────────────────────────────────
|
|
10357
10715
|
async saveFeedback(feedback) {
|
|
@@ -10404,8 +10762,9 @@ var DatabaseStorage = class {
|
|
|
10404
10762
|
this.writeLocalFile(this.feedbackFile, list);
|
|
10405
10763
|
}
|
|
10406
10764
|
}
|
|
10407
|
-
async getFeedback(messageId) {
|
|
10765
|
+
async getFeedback(messageId, projectIds) {
|
|
10408
10766
|
this.checkFeedbackEnabled();
|
|
10767
|
+
let item = null;
|
|
10409
10768
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
10410
10769
|
const pool = await this.getPGPool();
|
|
10411
10770
|
const res = await pool.query(
|
|
@@ -10414,28 +10773,34 @@ var DatabaseStorage = class {
|
|
|
10414
10773
|
WHERE message_id = $1`,
|
|
10415
10774
|
[messageId]
|
|
10416
10775
|
);
|
|
10417
|
-
|
|
10776
|
+
item = res.rows[0] || null;
|
|
10418
10777
|
} else if (this.provider === "mongodb") {
|
|
10419
10778
|
await this.getMongoClient();
|
|
10420
10779
|
const db = this.getMongoDb();
|
|
10421
10780
|
const col = db.collection(this.feedbackTableName);
|
|
10422
|
-
const
|
|
10423
|
-
if (
|
|
10424
|
-
|
|
10425
|
-
|
|
10426
|
-
|
|
10427
|
-
|
|
10428
|
-
|
|
10429
|
-
|
|
10430
|
-
|
|
10431
|
-
|
|
10781
|
+
const raw = await col.findOne({ message_id: messageId });
|
|
10782
|
+
if (raw) {
|
|
10783
|
+
item = {
|
|
10784
|
+
id: raw.id,
|
|
10785
|
+
messageId: raw.message_id,
|
|
10786
|
+
sessionId: raw.session_id,
|
|
10787
|
+
rating: raw.rating,
|
|
10788
|
+
comment: raw.comment,
|
|
10789
|
+
createdAt: raw.created_at
|
|
10790
|
+
};
|
|
10791
|
+
}
|
|
10432
10792
|
} else {
|
|
10433
10793
|
const list = this.readLocalFile(this.feedbackFile);
|
|
10434
|
-
|
|
10794
|
+
item = list.find((f) => f.message_id === messageId) || null;
|
|
10435
10795
|
}
|
|
10796
|
+
if (item && projectIds && projectIds.length > 0) {
|
|
10797
|
+
return this.sessionInScope(item.sessionId, projectIds) ? item : null;
|
|
10798
|
+
}
|
|
10799
|
+
return item;
|
|
10436
10800
|
}
|
|
10437
|
-
async listFeedback() {
|
|
10801
|
+
async listFeedback(projectIds) {
|
|
10438
10802
|
this.checkFeedbackEnabled();
|
|
10803
|
+
let raw = [];
|
|
10439
10804
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
10440
10805
|
const pool = await this.getPGPool();
|
|
10441
10806
|
const res = await pool.query(
|
|
@@ -10443,13 +10808,13 @@ var DatabaseStorage = class {
|
|
|
10443
10808
|
FROM ${this.feedbackTableName}
|
|
10444
10809
|
ORDER BY created_at DESC`
|
|
10445
10810
|
);
|
|
10446
|
-
|
|
10811
|
+
raw = res.rows;
|
|
10447
10812
|
} else if (this.provider === "mongodb") {
|
|
10448
10813
|
await this.getMongoClient();
|
|
10449
10814
|
const db = this.getMongoDb();
|
|
10450
10815
|
const col = db.collection(this.feedbackTableName);
|
|
10451
10816
|
const items = await col.find({}).sort({ created_at: -1 }).toArray();
|
|
10452
|
-
|
|
10817
|
+
raw = items.map((item) => ({
|
|
10453
10818
|
id: item.id,
|
|
10454
10819
|
messageId: item.message_id,
|
|
10455
10820
|
sessionId: item.session_id,
|
|
@@ -10459,8 +10824,10 @@ var DatabaseStorage = class {
|
|
|
10459
10824
|
}));
|
|
10460
10825
|
} else {
|
|
10461
10826
|
const list = this.readLocalFile(this.feedbackFile);
|
|
10462
|
-
|
|
10827
|
+
raw = [...list].sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime());
|
|
10463
10828
|
}
|
|
10829
|
+
if (!projectIds || projectIds.length === 0) return raw;
|
|
10830
|
+
return raw.filter((f) => this.sessionInScope(f.sessionId, projectIds));
|
|
10464
10831
|
}
|
|
10465
10832
|
async disconnect() {
|
|
10466
10833
|
if (this.pgPool) {
|
|
@@ -10523,8 +10890,8 @@ var _g = global;
|
|
|
10523
10890
|
var _a;
|
|
10524
10891
|
var rateLimiter = (_a = _g.__retrivoraRateLimiter) != null ? _a : _g.__retrivoraRateLimiter = new RateLimiter(6e4, 30);
|
|
10525
10892
|
function getRateLimitKey(req) {
|
|
10526
|
-
var
|
|
10527
|
-
const ip = ((_b = (
|
|
10893
|
+
var _a3, _b;
|
|
10894
|
+
const ip = ((_b = (_a3 = req.headers.get("x-forwarded-for")) == null ? void 0 : _a3.split(",")[0]) == null ? void 0 : _b.trim()) || req.headers.get("x-real-ip") || "127.0.0.1";
|
|
10528
10895
|
return `ip:${ip}`;
|
|
10529
10896
|
}
|
|
10530
10897
|
function checkRateLimit(req) {
|
|
@@ -10546,6 +10913,66 @@ function checkRateLimit(req) {
|
|
|
10546
10913
|
}
|
|
10547
10914
|
return null;
|
|
10548
10915
|
}
|
|
10916
|
+
var FREE_TIER_NAMES = /* @__PURE__ */ new Set(["hobby", "free", "free_trial", "trial"]);
|
|
10917
|
+
function isFreeTier(tier) {
|
|
10918
|
+
if (!tier) return true;
|
|
10919
|
+
return FREE_TIER_NAMES.has(tier.toLowerCase().trim());
|
|
10920
|
+
}
|
|
10921
|
+
var _a2;
|
|
10922
|
+
var _freeTierGuardInstance = (_a2 = _g.__retrivoraFreeTierGuard) != null ? _a2 : _g.__retrivoraFreeTierGuard = new FreeTierLimitsGuard();
|
|
10923
|
+
function createPaymentRequiredResponse(reason, details) {
|
|
10924
|
+
const body = __spreadProps(__spreadValues({
|
|
10925
|
+
type: "https://retrivora.com/docs/errors/payment-required",
|
|
10926
|
+
title: "Payment Required",
|
|
10927
|
+
status: 402,
|
|
10928
|
+
detail: reason,
|
|
10929
|
+
code: "FREE_TIER_LIMIT_EXCEEDED",
|
|
10930
|
+
instance: void 0
|
|
10931
|
+
}, details != null ? details : {}), {
|
|
10932
|
+
quota: {
|
|
10933
|
+
maxDailyRequestUnits: FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS,
|
|
10934
|
+
maxTrialRequestUnits: FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS,
|
|
10935
|
+
maxDocuments: FREE_TIER_QUOTAS.MAX_DOCUMENTS,
|
|
10936
|
+
maxStorageBytes: FREE_TIER_QUOTAS.MAX_STORAGE_BYTES,
|
|
10937
|
+
upgradeUrl: "https://retrivora.com/pricing"
|
|
10938
|
+
}
|
|
10939
|
+
});
|
|
10940
|
+
return new Response(JSON.stringify(body), {
|
|
10941
|
+
status: 402,
|
|
10942
|
+
headers: {
|
|
10943
|
+
"Content-Type": "application/problem+json"
|
|
10944
|
+
}
|
|
10945
|
+
});
|
|
10946
|
+
}
|
|
10947
|
+
function resolveLicenseKey(req, config, bodyLicenseKey) {
|
|
10948
|
+
var _a3;
|
|
10949
|
+
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 || "";
|
|
10950
|
+
}
|
|
10951
|
+
function enforceLicense(req, config, bodyLicenseKey) {
|
|
10952
|
+
const rawKey = resolveLicenseKey(req, config, bodyLicenseKey);
|
|
10953
|
+
const licenseKey = (rawKey || "").trim().replace(/^["']|["']$/g, "").trim();
|
|
10954
|
+
const projectId = config.projectId || "my-rag-app";
|
|
10955
|
+
try {
|
|
10956
|
+
const payload = LicenseVerifier.verify(licenseKey, projectId);
|
|
10957
|
+
return { ok: true, payload };
|
|
10958
|
+
} catch (err) {
|
|
10959
|
+
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.";
|
|
10960
|
+
const body = {
|
|
10961
|
+
error: {
|
|
10962
|
+
code: "LICENSE_REVOKED",
|
|
10963
|
+
message: "Your Retrivora license key has been terminated, suspended, or revoked. Access denied."
|
|
10964
|
+
},
|
|
10965
|
+
details: message
|
|
10966
|
+
};
|
|
10967
|
+
return {
|
|
10968
|
+
ok: false,
|
|
10969
|
+
response: new Response(JSON.stringify(body), {
|
|
10970
|
+
status: 403,
|
|
10971
|
+
headers: { "Content-Type": "application/json" }
|
|
10972
|
+
})
|
|
10973
|
+
};
|
|
10974
|
+
}
|
|
10975
|
+
}
|
|
10549
10976
|
var MAX_MESSAGE_LENGTH = 8e3;
|
|
10550
10977
|
function sanitizeInput(raw) {
|
|
10551
10978
|
const stripped = raw.replace(/[\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F-\u009F]/g, "");
|
|
@@ -10567,7 +10994,7 @@ function getOrCreatePlugin(configOrPlugin) {
|
|
|
10567
10994
|
return _g[cacheKey];
|
|
10568
10995
|
}
|
|
10569
10996
|
function reportTelemetry(req, plugin, action, status, details, trace) {
|
|
10570
|
-
var
|
|
10997
|
+
var _a3, _b, _c, _d, _e, _f, _g2;
|
|
10571
10998
|
try {
|
|
10572
10999
|
const config = plugin.getConfig();
|
|
10573
11000
|
const licenseKey = config.licenseKey || process.env.RAG_LICENSE_KEY || process.env.RETRIVORA_LICENSE_KEY || process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY;
|
|
@@ -10582,7 +11009,7 @@ function reportTelemetry(req, plugin, action, status, details, trace) {
|
|
|
10582
11009
|
absoluteUrl = `${proto}://${host}${telemetryUrl}`;
|
|
10583
11010
|
}
|
|
10584
11011
|
const projectId = config.projectId || "default";
|
|
10585
|
-
const model = (trace == null ? void 0 : trace.model) || ((
|
|
11012
|
+
const model = (trace == null ? void 0 : trace.model) || ((_a3 = config.llm) == null ? void 0 : _a3.model) || ((_b = config.embedding) == null ? void 0 : _b.model) || "llama-3.1-8b-instant";
|
|
10586
11013
|
const provider = (trace == null ? void 0 : trace.provider) || ((_c = config.llm) == null ? void 0 : _c.provider) || ((_d = config.embedding) == null ? void 0 : _d.provider) || "groq";
|
|
10587
11014
|
const tokens = Number(((_e = trace == null ? void 0 : trace.tokens) == null ? void 0 : _e.totalTokens) || (trace == null ? void 0 : trace.totalTokens) || 0);
|
|
10588
11015
|
const costUsd = Number(((_f = trace == null ? void 0 : trace.tokens) == null ? void 0 : _f.estimatedCostUsd) || (trace == null ? void 0 : trace.costUsd) || 0);
|
|
@@ -10606,7 +11033,6 @@ function reportTelemetry(req, plugin, action, status, details, trace) {
|
|
|
10606
11033
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
10607
11034
|
details
|
|
10608
11035
|
};
|
|
10609
|
-
console.log(`[Retrivora SDK Telemetry] Dispatching telemetry -> Feature: "${action}", Status: "${status}", Project: "${projectId}", Latency: ${latencyMs}ms`);
|
|
10610
11036
|
fetch(absoluteUrl, {
|
|
10611
11037
|
method: "POST",
|
|
10612
11038
|
headers: {
|
|
@@ -10664,14 +11090,39 @@ function createChatHandler(configOrPlugin, options) {
|
|
|
10664
11090
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
10665
11091
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
10666
11092
|
return async function POST(req, context) {
|
|
10667
|
-
var
|
|
11093
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
10668
11094
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10669
11095
|
if (authResult) return authResult;
|
|
10670
11096
|
const rateLimited = checkRateLimit(req);
|
|
10671
11097
|
if (rateLimited) return rateLimited;
|
|
11098
|
+
const config = plugin.getConfig();
|
|
10672
11099
|
try {
|
|
10673
11100
|
const body = await req.json();
|
|
10674
11101
|
const bodyObj = body != null ? body : {};
|
|
11102
|
+
const licenseCheck = enforceLicense(req, config, bodyObj == null ? void 0 : bodyObj.licenseKey);
|
|
11103
|
+
if (!licenseCheck.ok) return licenseCheck.response;
|
|
11104
|
+
if (isFreeTier(licenseCheck.payload.tier)) {
|
|
11105
|
+
const estimatedInputTokens = Math.ceil(
|
|
11106
|
+
((((_a3 = bodyObj.message) == null ? void 0 : _a3.length) || 0) + (Array.isArray(bodyObj.messages) ? bodyObj.messages.reduce((a, m) => {
|
|
11107
|
+
var _a4, _b2;
|
|
11108
|
+
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);
|
|
11109
|
+
}, 0) : 0) + (((_b = bodyObj.history) == null ? void 0 : _b.reduce((a, m) => {
|
|
11110
|
+
var _a4, _b2;
|
|
11111
|
+
return a + (((_a4 = m == null ? void 0 : m.content) == null ? void 0 : _a4.length) || ((_b2 = m == null ? void 0 : m.text) == null ? void 0 : _b2.length) || 0);
|
|
11112
|
+
}, 0)) || 0)) / 4
|
|
11113
|
+
);
|
|
11114
|
+
const chatCheck = FreeTierLimitsGuard.checkRequestAllowed({
|
|
11115
|
+
operationType: "chat",
|
|
11116
|
+
inputTokens: estimatedInputTokens,
|
|
11117
|
+
projectId: licenseCheck.payload.projectId
|
|
11118
|
+
});
|
|
11119
|
+
if (!chatCheck.allowed) {
|
|
11120
|
+
return createPaymentRequiredResponse(
|
|
11121
|
+
chatCheck.reason || "Free tier quota exceeded.",
|
|
11122
|
+
{ tier: licenseCheck.payload.tier, projectId: licenseCheck.payload.projectId }
|
|
11123
|
+
);
|
|
11124
|
+
}
|
|
11125
|
+
}
|
|
10675
11126
|
let rawMessage = bodyObj.message;
|
|
10676
11127
|
if (!rawMessage && Array.isArray(bodyObj.messages) && bodyObj.messages.length > 0) {
|
|
10677
11128
|
const lastMsg = bodyObj.messages[bodyObj.messages.length - 1];
|
|
@@ -10703,7 +11154,7 @@ function createChatHandler(configOrPlugin, options) {
|
|
|
10703
11154
|
uiTransformation: result.ui_transformation,
|
|
10704
11155
|
trace: result.trace
|
|
10705
11156
|
}).catch((err) => console.warn("[createChatHandler] Failed to save assistant message:", err));
|
|
10706
|
-
reportTelemetry(req, plugin, "QUERY_GENERATION", "success", `Tokens: ${((
|
|
11157
|
+
reportTelemetry(req, plugin, "QUERY_GENERATION", "success", `Tokens: ${((_d = (_c = result.trace) == null ? void 0 : _c.tokens) == null ? void 0 : _d.totalTokens) || 0}, Latency: ${((_f = (_e = result.trace) == null ? void 0 : _e.latency) == null ? void 0 : _f.totalMs) || 0}ms`, result.trace);
|
|
10707
11158
|
return NextResponse.json(__spreadProps(__spreadValues({}, result), {
|
|
10708
11159
|
messageId: assistantMsgId,
|
|
10709
11160
|
userMessageId: userMsgId
|
|
@@ -10720,14 +11171,15 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10720
11171
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
10721
11172
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
10722
11173
|
return async function POST(req, context) {
|
|
10723
|
-
var
|
|
11174
|
+
var _a3, _b, _c;
|
|
10724
11175
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10725
11176
|
if (authResult) return authResult;
|
|
10726
11177
|
const rateLimited = checkRateLimit(req);
|
|
10727
11178
|
if (rateLimited) return rateLimited;
|
|
11179
|
+
const config = plugin.getConfig();
|
|
10728
11180
|
let body;
|
|
10729
11181
|
try {
|
|
10730
|
-
if ((
|
|
11182
|
+
if ((_a3 = req.headers.get("content-type")) == null ? void 0 : _a3.includes("multipart/form-data")) {
|
|
10731
11183
|
const uploader = createUploadHandler(plugin, { onAuthorize });
|
|
10732
11184
|
return uploader(req);
|
|
10733
11185
|
}
|
|
@@ -10739,6 +11191,30 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10739
11191
|
});
|
|
10740
11192
|
}
|
|
10741
11193
|
const bodyObj = body != null ? body : {};
|
|
11194
|
+
const licenseCheck = enforceLicense(req, config, bodyObj == null ? void 0 : bodyObj.licenseKey);
|
|
11195
|
+
if (!licenseCheck.ok) return licenseCheck.response;
|
|
11196
|
+
if (isFreeTier(licenseCheck.payload.tier)) {
|
|
11197
|
+
const estimatedInputTokens = Math.ceil(
|
|
11198
|
+
((((_b = bodyObj.message) == null ? void 0 : _b.length) || 0) + (Array.isArray(bodyObj.messages) ? bodyObj.messages.reduce((a, m) => {
|
|
11199
|
+
var _a4, _b2;
|
|
11200
|
+
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);
|
|
11201
|
+
}, 0) : 0) + (((_c = bodyObj.history) == null ? void 0 : _c.reduce((a, m) => {
|
|
11202
|
+
var _a4, _b2;
|
|
11203
|
+
return a + (((_a4 = m == null ? void 0 : m.content) == null ? void 0 : _a4.length) || ((_b2 = m == null ? void 0 : m.text) == null ? void 0 : _b2.length) || 0);
|
|
11204
|
+
}, 0)) || 0)) / 4
|
|
11205
|
+
);
|
|
11206
|
+
const chatCheck = FreeTierLimitsGuard.checkRequestAllowed({
|
|
11207
|
+
operationType: "chat_stream",
|
|
11208
|
+
inputTokens: estimatedInputTokens,
|
|
11209
|
+
projectId: licenseCheck.payload.projectId
|
|
11210
|
+
});
|
|
11211
|
+
if (!chatCheck.allowed) {
|
|
11212
|
+
return createPaymentRequiredResponse(
|
|
11213
|
+
chatCheck.reason || "Free tier quota exceeded.",
|
|
11214
|
+
{ tier: licenseCheck.payload.tier, projectId: licenseCheck.payload.projectId }
|
|
11215
|
+
);
|
|
11216
|
+
}
|
|
11217
|
+
}
|
|
10742
11218
|
let rawMessage = bodyObj.message;
|
|
10743
11219
|
if (!rawMessage && Array.isArray(bodyObj.messages) && bodyObj.messages.length > 0) {
|
|
10744
11220
|
const lastMsg = bodyObj.messages[bodyObj.messages.length - 1];
|
|
@@ -10768,7 +11244,7 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10768
11244
|
let isActive = true;
|
|
10769
11245
|
const stream = new ReadableStream({
|
|
10770
11246
|
async start(controller) {
|
|
10771
|
-
var
|
|
11247
|
+
var _a4, _b2, _c2, _d, _e;
|
|
10772
11248
|
const enqueue = (text) => {
|
|
10773
11249
|
if (!isActive) return;
|
|
10774
11250
|
try {
|
|
@@ -10801,7 +11277,7 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10801
11277
|
let uiTransformation = responseChunk == null ? void 0 : responseChunk.ui_transformation;
|
|
10802
11278
|
if (sources.length > 0) {
|
|
10803
11279
|
try {
|
|
10804
|
-
uiTransformation = (
|
|
11280
|
+
uiTransformation = (_a4 = responseChunk == null ? void 0 : responseChunk.ui_transformation) != null ? _a4 : UITransformer.transform(message, sources, plugin.getConfig());
|
|
10805
11281
|
if (uiTransformation) {
|
|
10806
11282
|
enqueue(sseUIFrame(uiTransformation));
|
|
10807
11283
|
}
|
|
@@ -10825,7 +11301,7 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10825
11301
|
uiTransformation,
|
|
10826
11302
|
trace: responseChunk == null ? void 0 : responseChunk.trace
|
|
10827
11303
|
}).catch((err) => console.warn("[createStreamHandler] Failed to save assistant message:", err));
|
|
10828
|
-
reportTelemetry(req, plugin, "QUERY_GENERATION", "success", `Tokens: ${((
|
|
11304
|
+
reportTelemetry(req, plugin, "QUERY_GENERATION", "success", `Tokens: ${((_c2 = (_b2 = responseChunk == null ? void 0 : responseChunk.trace) == null ? void 0 : _b2.tokens) == null ? void 0 : _c2.totalTokens) || 0}, Latency: ${((_e = (_d = responseChunk == null ? void 0 : responseChunk.trace) == null ? void 0 : _d.latency) == null ? void 0 : _e.totalMs) || 0}ms`, responseChunk == null ? void 0 : responseChunk.trace);
|
|
10829
11305
|
}
|
|
10830
11306
|
}
|
|
10831
11307
|
} catch (temp) {
|
|
@@ -10875,12 +11351,36 @@ function createIngestHandler(configOrPlugin, options) {
|
|
|
10875
11351
|
return async function POST(req, context) {
|
|
10876
11352
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10877
11353
|
if (authResult) return authResult;
|
|
11354
|
+
const config = plugin.getConfig();
|
|
10878
11355
|
try {
|
|
10879
11356
|
const body = await req.json();
|
|
11357
|
+
const licenseCheck = enforceLicense(req, config, body == null ? void 0 : body.licenseKey);
|
|
11358
|
+
if (!licenseCheck.ok) return licenseCheck.response;
|
|
10880
11359
|
const { documents, namespace } = body;
|
|
10881
11360
|
if (!Array.isArray(documents) || documents.length === 0) {
|
|
10882
11361
|
return NextResponse.json({ error: "documents array is required" }, { status: 400 });
|
|
10883
11362
|
}
|
|
11363
|
+
if (isFreeTier(licenseCheck.payload.tier)) {
|
|
11364
|
+
const totalIncomingBytes = documents.reduce(
|
|
11365
|
+
(sum, d) => sum + Buffer.byteLength(d.content || "", "utf8"),
|
|
11366
|
+
0
|
|
11367
|
+
);
|
|
11368
|
+
const ingestCheck = FreeTierLimitsGuard.checkIngestionAllowed(
|
|
11369
|
+
{ documentCount: documents.length },
|
|
11370
|
+
totalIncomingBytes
|
|
11371
|
+
);
|
|
11372
|
+
if (!ingestCheck.allowed) {
|
|
11373
|
+
return createPaymentRequiredResponse(
|
|
11374
|
+
ingestCheck.reason || "Free tier ingestion limit reached.",
|
|
11375
|
+
{
|
|
11376
|
+
tier: licenseCheck.payload.tier,
|
|
11377
|
+
projectId: licenseCheck.payload.projectId,
|
|
11378
|
+
documents: documents.length,
|
|
11379
|
+
incomingBytes: totalIncomingBytes
|
|
11380
|
+
}
|
|
11381
|
+
);
|
|
11382
|
+
}
|
|
11383
|
+
}
|
|
10884
11384
|
const results = await plugin.ingest(documents, namespace);
|
|
10885
11385
|
reportTelemetry(req, plugin, "DOCUMENT_INGESTION", "success", `Ingested ${documents.length} document(s)`);
|
|
10886
11386
|
return NextResponse.json({ results });
|
|
@@ -10917,7 +11417,7 @@ function createLicenseHandler(configOrPlugin, options) {
|
|
|
10917
11417
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
10918
11418
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
10919
11419
|
return async function POST(req) {
|
|
10920
|
-
var
|
|
11420
|
+
var _a3;
|
|
10921
11421
|
if (req) {
|
|
10922
11422
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10923
11423
|
if (authResult) return authResult;
|
|
@@ -10925,7 +11425,7 @@ function createLicenseHandler(configOrPlugin, options) {
|
|
|
10925
11425
|
try {
|
|
10926
11426
|
const body = await req.json().catch(() => ({}));
|
|
10927
11427
|
const config = plugin.getConfig();
|
|
10928
|
-
const rawKey = req.headers.get("x-license-key") || (body == null ? void 0 : body.licenseKey) || ((
|
|
11428
|
+
const rawKey = req.headers.get("x-license-key") || (body == null ? void 0 : body.licenseKey) || ((_a3 = req.headers.get("authorization")) == null ? void 0 : _a3.replace(/^Bearer\s+/i, "")) || config.licenseKey || process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY || process.env.RETRIVORA_LICENSE_KEY || "";
|
|
10929
11429
|
const licenseKey = (rawKey || "").trim().replace(/^["']|["']$/g, "").trim();
|
|
10930
11430
|
const projectId = (body == null ? void 0 : body.projectId) || config.projectId || "my-rag-app";
|
|
10931
11431
|
const payload = LicenseVerifier.verify(licenseKey, projectId);
|
|
@@ -10960,6 +11460,9 @@ function createUploadHandler(configOrPlugin, options) {
|
|
|
10960
11460
|
return async function POST(req, context) {
|
|
10961
11461
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10962
11462
|
if (authResult) return authResult;
|
|
11463
|
+
const config = plugin.getConfig();
|
|
11464
|
+
const licenseCheck = enforceLicense(req, config);
|
|
11465
|
+
if (!licenseCheck.ok) return licenseCheck.response;
|
|
10963
11466
|
try {
|
|
10964
11467
|
const formData = await req.formData();
|
|
10965
11468
|
const files = formData.getAll("files");
|
|
@@ -10969,6 +11472,26 @@ function createUploadHandler(configOrPlugin, options) {
|
|
|
10969
11472
|
if (!files || files.length === 0) {
|
|
10970
11473
|
return NextResponse.json({ error: "No files provided" }, { status: 400 });
|
|
10971
11474
|
}
|
|
11475
|
+
if (isFreeTier(licenseCheck.payload.tier)) {
|
|
11476
|
+
const totalUploadBytes = files.reduce((sum, f) => sum + (f.size || 0), 0);
|
|
11477
|
+
const uploadCheck = FreeTierLimitsGuard.checkIngestionAllowed(
|
|
11478
|
+
{ documentCount: files.length },
|
|
11479
|
+
totalUploadBytes
|
|
11480
|
+
);
|
|
11481
|
+
if (!uploadCheck.allowed) {
|
|
11482
|
+
return createPaymentRequiredResponse(
|
|
11483
|
+
uploadCheck.reason || "Free tier upload limit reached.",
|
|
11484
|
+
{
|
|
11485
|
+
tier: licenseCheck.payload.tier,
|
|
11486
|
+
projectId: licenseCheck.payload.projectId,
|
|
11487
|
+
fileCount: files.length,
|
|
11488
|
+
totalUploadBytes,
|
|
11489
|
+
maxFileSizeBytes: FREE_TIER_QUOTAS.MAX_FILE_SIZE_BYTES,
|
|
11490
|
+
maxStorageBytes: FREE_TIER_QUOTAS.MAX_STORAGE_BYTES
|
|
11491
|
+
}
|
|
11492
|
+
);
|
|
11493
|
+
}
|
|
11494
|
+
}
|
|
10972
11495
|
const documents = [];
|
|
10973
11496
|
for (const file of files) {
|
|
10974
11497
|
const isExcel = file.name.toLowerCase().endsWith(".xlsx") || file.name.toLowerCase().endsWith(".xls") || file.type.includes("spreadsheet") || file.type.includes("excel");
|
|
@@ -11078,13 +11601,22 @@ function createSuggestionsHandler(configOrPlugin, options) {
|
|
|
11078
11601
|
return async function handler(req) {
|
|
11079
11602
|
const authResult = await checkAuth(req, onAuthorize);
|
|
11080
11603
|
if (authResult) return authResult;
|
|
11604
|
+
const config = plugin.getConfig();
|
|
11605
|
+
const licenseCheck = enforceLicense(req, config);
|
|
11606
|
+
if (!licenseCheck.ok) return licenseCheck.response;
|
|
11081
11607
|
try {
|
|
11082
11608
|
let query = "";
|
|
11083
11609
|
let namespace = void 0;
|
|
11610
|
+
let bodyLicenseKey = void 0;
|
|
11084
11611
|
if (req.method === "POST") {
|
|
11085
11612
|
const body = await req.json().catch(() => ({}));
|
|
11086
11613
|
query = body.query || "";
|
|
11087
11614
|
namespace = body.namespace;
|
|
11615
|
+
bodyLicenseKey = body.licenseKey;
|
|
11616
|
+
if (bodyLicenseKey) {
|
|
11617
|
+
const recheck = enforceLicense(req, config, bodyLicenseKey);
|
|
11618
|
+
if (!recheck.ok) return recheck.response;
|
|
11619
|
+
}
|
|
11088
11620
|
} else {
|
|
11089
11621
|
const url = new URL(req.url);
|
|
11090
11622
|
query = url.searchParams.get("query") || "";
|
|
@@ -11107,14 +11639,16 @@ function createHistoryHandler(configOrPlugin, options) {
|
|
|
11107
11639
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
11108
11640
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
11109
11641
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
11642
|
+
const onResolveScope = options == null ? void 0 : options.onResolveScope;
|
|
11110
11643
|
return async function handler(req) {
|
|
11111
11644
|
const authResult = await checkAuth(req, onAuthorize);
|
|
11112
11645
|
if (authResult) return authResult;
|
|
11646
|
+
const scope = onResolveScope ? await onResolveScope(req) : void 0;
|
|
11113
11647
|
const url = new URL(req.url);
|
|
11114
11648
|
const sessionId = url.searchParams.get("sessionId") || "default";
|
|
11115
11649
|
if (req.method === "GET") {
|
|
11116
11650
|
try {
|
|
11117
|
-
const history = await storage.getHistory(sessionId);
|
|
11651
|
+
const history = await storage.getHistory(sessionId, scope);
|
|
11118
11652
|
return NextResponse.json({ history });
|
|
11119
11653
|
} catch (err) {
|
|
11120
11654
|
const message = err instanceof Error ? err.message : "Failed to fetch history";
|
|
@@ -11124,7 +11658,7 @@ function createHistoryHandler(configOrPlugin, options) {
|
|
|
11124
11658
|
try {
|
|
11125
11659
|
const body = await req.json().catch(() => ({}));
|
|
11126
11660
|
const sid = body.sessionId || sessionId;
|
|
11127
|
-
await storage.clearHistory(sid);
|
|
11661
|
+
await storage.clearHistory(sid, scope);
|
|
11128
11662
|
return NextResponse.json({ success: true });
|
|
11129
11663
|
} catch (err) {
|
|
11130
11664
|
const message = err instanceof Error ? err.message : "Failed to clear history";
|
|
@@ -11138,18 +11672,20 @@ function createFeedbackHandler(configOrPlugin, options) {
|
|
|
11138
11672
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
11139
11673
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
11140
11674
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
11675
|
+
const onResolveScope = options == null ? void 0 : options.onResolveScope;
|
|
11141
11676
|
return async function handler(req) {
|
|
11142
11677
|
const authResult = await checkAuth(req, onAuthorize);
|
|
11143
11678
|
if (authResult) return authResult;
|
|
11679
|
+
const scope = onResolveScope ? await onResolveScope(req) : void 0;
|
|
11144
11680
|
if (req.method === "GET") {
|
|
11145
11681
|
try {
|
|
11146
11682
|
const url = new URL(req.url);
|
|
11147
11683
|
const messageId = url.searchParams.get("messageId");
|
|
11148
11684
|
if (!messageId) {
|
|
11149
|
-
const feedbackList = await storage.listFeedback();
|
|
11685
|
+
const feedbackList = await storage.listFeedback(scope);
|
|
11150
11686
|
return NextResponse.json({ feedback: feedbackList });
|
|
11151
11687
|
}
|
|
11152
|
-
const feedback = await storage.getFeedback(messageId);
|
|
11688
|
+
const feedback = await storage.getFeedback(messageId, scope);
|
|
11153
11689
|
return NextResponse.json({ feedback });
|
|
11154
11690
|
} catch (err) {
|
|
11155
11691
|
const message = err instanceof Error ? err.message : "Failed to fetch feedback";
|
|
@@ -11165,6 +11701,17 @@ function createFeedbackHandler(configOrPlugin, options) {
|
|
|
11165
11701
|
if (!rating) {
|
|
11166
11702
|
return NextResponse.json({ error: "rating is required" }, { status: 400 });
|
|
11167
11703
|
}
|
|
11704
|
+
if (scope && scope.length > 0) {
|
|
11705
|
+
const matches = scope.some(
|
|
11706
|
+
(pid) => pid && (sessionId === pid || sessionId.startsWith(pid) || sessionId.includes(pid))
|
|
11707
|
+
);
|
|
11708
|
+
if (!matches) {
|
|
11709
|
+
return NextResponse.json(
|
|
11710
|
+
{ error: "sessionId is outside the authorized project scope" },
|
|
11711
|
+
{ status: 403 }
|
|
11712
|
+
);
|
|
11713
|
+
}
|
|
11714
|
+
}
|
|
11168
11715
|
await storage.saveFeedback({ messageId, sessionId, rating, comment });
|
|
11169
11716
|
return NextResponse.json({ success: true });
|
|
11170
11717
|
} catch (err) {
|
|
@@ -11179,14 +11726,15 @@ function createSessionsHandler(configOrPlugin, options) {
|
|
|
11179
11726
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
11180
11727
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
11181
11728
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
11729
|
+
const onResolveScope = options == null ? void 0 : options.onResolveScope;
|
|
11182
11730
|
return async function GET(req) {
|
|
11183
11731
|
if (req) {
|
|
11184
11732
|
const authResult = await checkAuth(req, onAuthorize);
|
|
11185
11733
|
if (authResult) return authResult;
|
|
11186
11734
|
}
|
|
11187
|
-
void req;
|
|
11188
11735
|
try {
|
|
11189
|
-
const
|
|
11736
|
+
const scope = req && onResolveScope ? await onResolveScope(req) : void 0;
|
|
11737
|
+
const sessions = await storage.listSessions(scope);
|
|
11190
11738
|
return NextResponse.json({ sessions });
|
|
11191
11739
|
} catch (err) {
|
|
11192
11740
|
const message = err instanceof Error ? err.message : "Failed to list sessions";
|
|
@@ -11197,15 +11745,17 @@ function createSessionsHandler(configOrPlugin, options) {
|
|
|
11197
11745
|
function createRagHandler(configOrPlugin, options) {
|
|
11198
11746
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
11199
11747
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
11200
|
-
const
|
|
11201
|
-
const
|
|
11202
|
-
const
|
|
11203
|
-
const
|
|
11204
|
-
const
|
|
11205
|
-
const
|
|
11206
|
-
const
|
|
11207
|
-
const
|
|
11208
|
-
const
|
|
11748
|
+
const onResolveScope = options == null ? void 0 : options.onResolveScope;
|
|
11749
|
+
const scopeableOptions = { onAuthorize, onResolveScope };
|
|
11750
|
+
const chatHandler = createChatHandler(plugin, scopeableOptions);
|
|
11751
|
+
const streamHandler = createStreamHandler(plugin, scopeableOptions);
|
|
11752
|
+
const uploadHandler = createUploadHandler(plugin, scopeableOptions);
|
|
11753
|
+
const healthHandler = createHealthHandler(plugin, scopeableOptions);
|
|
11754
|
+
const suggestionsHandler = createSuggestionsHandler(plugin, scopeableOptions);
|
|
11755
|
+
const historyHandler = createHistoryHandler(plugin, scopeableOptions);
|
|
11756
|
+
const feedbackHandler = createFeedbackHandler(plugin, scopeableOptions);
|
|
11757
|
+
const sessionsHandler = createSessionsHandler(plugin, scopeableOptions);
|
|
11758
|
+
const licenseHandler = createLicenseHandler(plugin, scopeableOptions);
|
|
11209
11759
|
async function routePostRequest(req, segment) {
|
|
11210
11760
|
switch (segment) {
|
|
11211
11761
|
case "chat":
|
|
@@ -11247,7 +11797,7 @@ function createRagHandler(configOrPlugin, options) {
|
|
|
11247
11797
|
}
|
|
11248
11798
|
}
|
|
11249
11799
|
async function getSegment(req, context) {
|
|
11250
|
-
var
|
|
11800
|
+
var _a3, _b;
|
|
11251
11801
|
const contentType = req.headers.get("content-type") || "";
|
|
11252
11802
|
if (contentType.includes("multipart/form-data")) {
|
|
11253
11803
|
return "upload";
|
|
@@ -11264,7 +11814,7 @@ function createRagHandler(configOrPlugin, options) {
|
|
|
11264
11814
|
if (pathname.endsWith("/history")) return "history";
|
|
11265
11815
|
} catch (e) {
|
|
11266
11816
|
}
|
|
11267
|
-
const resolvedParams = typeof ((
|
|
11817
|
+
const resolvedParams = typeof ((_a3 = context == null ? void 0 : context.params) == null ? void 0 : _a3.then) === "function" ? await context.params : context == null ? void 0 : context.params;
|
|
11268
11818
|
const segments = (resolvedParams == null ? void 0 : resolvedParams.retrivora) || ((_b = resolvedParams == null ? void 0 : resolvedParams.params) == null ? void 0 : _b.retrivora) || [];
|
|
11269
11819
|
const joined = segments.join("/");
|
|
11270
11820
|
return joined || "chat";
|
|
@@ -11297,6 +11847,7 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
11297
11847
|
constructor() {
|
|
11298
11848
|
this.cache = /* @__PURE__ */ new Map();
|
|
11299
11849
|
}
|
|
11850
|
+
/** @returns Singleton instance of the validator (shared cache across all consumers). */
|
|
11300
11851
|
static getInstance() {
|
|
11301
11852
|
if (!_LicenseValidator.instance) {
|
|
11302
11853
|
_LicenseValidator.instance = new _LicenseValidator();
|
|
@@ -11304,7 +11855,12 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
11304
11855
|
return _LicenseValidator.instance;
|
|
11305
11856
|
}
|
|
11306
11857
|
/**
|
|
11307
|
-
*
|
|
11858
|
+
* Purge entries from the local success cache.
|
|
11859
|
+
*
|
|
11860
|
+
* @param licenseKey - Optional. If provided, only that key's cache entry is
|
|
11861
|
+
* removed. If omitted the entire cache is cleared.
|
|
11862
|
+
* Callers use this after any 401/403 to ensure the next
|
|
11863
|
+
* validate() call re-validates against the server.
|
|
11308
11864
|
*/
|
|
11309
11865
|
purgeCache(licenseKey) {
|
|
11310
11866
|
if (licenseKey) {
|
|
@@ -11314,10 +11870,20 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
11314
11870
|
}
|
|
11315
11871
|
}
|
|
11316
11872
|
/**
|
|
11317
|
-
*
|
|
11873
|
+
* Primary validation entry-point for UI / hook consumers.
|
|
11874
|
+
*
|
|
11875
|
+
* Resolves the license key, consults the local success cache, performs a
|
|
11876
|
+
* server POST for authoritative status, and falls back to local RSA
|
|
11877
|
+
* signature verification if the server can't be reached.
|
|
11878
|
+
*
|
|
11879
|
+
* @throws LicenseValidationError - When no key is provided OR both the
|
|
11880
|
+
* server call AND the local-RSA fallback report an invalid/expired key.
|
|
11881
|
+
* @throws SDKVersionUnsupportedError - When server reports forceUpgrade=true.
|
|
11882
|
+
* @returns A `LicenseValidationResponse` that the UI can use to enable or
|
|
11883
|
+
* lock the chat widget.
|
|
11318
11884
|
*/
|
|
11319
11885
|
async validate(request) {
|
|
11320
|
-
var
|
|
11886
|
+
var _a3;
|
|
11321
11887
|
const {
|
|
11322
11888
|
licenseKey,
|
|
11323
11889
|
projectId,
|
|
@@ -11335,7 +11901,7 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
11335
11901
|
}
|
|
11336
11902
|
return void 0;
|
|
11337
11903
|
};
|
|
11338
|
-
const rawKey = licenseKey || getHeader("x-license-key") || ((
|
|
11904
|
+
const rawKey = licenseKey || getHeader("x-license-key") || ((_a3 = getHeader("authorization")) == null ? void 0 : _a3.replace(/^Bearer\s+/i, "")) || (typeof process !== "undefined" ? process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY || process.env.RETRIVORA_LICENSE_KEY : "") || "";
|
|
11339
11905
|
const effectiveLicenseKey = (rawKey || "").trim().replace(/^["']|["']$/g, "").trim();
|
|
11340
11906
|
if (!effectiveLicenseKey) {
|
|
11341
11907
|
this.purgeCache(effectiveLicenseKey);
|