@retrivora-ai/rag-engine 2.2.9 → 2.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{LicenseValidator-CENvo9o2.d.mts → BatchProcessor-7yV-UCHW.d.mts} +142 -3
- package/dist/{LicenseValidator-CsjJp2PP.d.ts → BatchProcessor-BfzuU4cK.d.ts} +142 -3
- package/dist/handlers/index.d.mts +1 -1
- package/dist/handlers/index.d.ts +1 -1
- package/dist/handlers/index.js +883 -328
- package/dist/handlers/index.mjs +883 -328
- package/dist/index-DR_O_B-W.d.ts +394 -0
- package/dist/index-fnpaCuma.d.mts +394 -0
- package/dist/index.css +58 -0
- package/dist/index.d.mts +63 -3
- package/dist/index.d.ts +63 -3
- package/dist/index.js +456 -37
- package/dist/index.mjs +455 -39
- package/dist/server.d.mts +35 -73
- package/dist/server.d.ts +35 -73
- package/dist/server.js +914 -342
- package/dist/server.mjs +914 -342
- package/package.json +1 -1
- package/src/components/ChatWidget.tsx +147 -46
- package/src/components/ChatWindow.tsx +52 -8
- package/src/core/BatchProcessor.ts +42 -4
- package/src/core/CircuitBreaker.ts +118 -0
- package/src/core/DatabaseStorage.ts +55 -24
- package/src/core/FreeTierLimitsGuard.ts +281 -0
- package/src/core/LicenseValidator.ts +69 -3
- package/src/core/LicenseVerifier.ts +43 -14
- package/src/core/VectorPlugin.ts +30 -0
- package/src/handlers/index.ts +495 -38
- package/src/index.css +58 -0
- package/src/index.ts +4 -0
- package/src/server.ts +1 -0
- package/dist/index-BPJ3KDYI.d.ts +0 -195
- package/dist/index-Dmq5lH0j.d.mts +0 -195
package/dist/handlers/index.js
CHANGED
|
@@ -165,7 +165,7 @@ var init_ConfigFetcher = __esm({
|
|
|
165
165
|
* Fetch full project configuration (vectorDb + embedding + llm) from Retrivora Control Plane.
|
|
166
166
|
*/
|
|
167
167
|
static async fetchRemoteConfig(projectId, licenseKey) {
|
|
168
|
-
var
|
|
168
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
|
|
169
169
|
const cacheKey = `${projectId}:${licenseKey || ""}`;
|
|
170
170
|
const now = Date.now();
|
|
171
171
|
const cached = this.cache.get(cacheKey);
|
|
@@ -191,7 +191,7 @@ var init_ConfigFetcher = __esm({
|
|
|
191
191
|
});
|
|
192
192
|
if (res.ok) {
|
|
193
193
|
const data = await res.json();
|
|
194
|
-
if ((data == null ? void 0 : data.success) && ((
|
|
194
|
+
if ((data == null ? void 0 : data.success) && ((_a3 = data == null ? void 0 : data.vectorDb) == null ? void 0 : _a3.apiKey)) {
|
|
195
195
|
const fetchedProjectId = data.projectId || projectId;
|
|
196
196
|
const config = {
|
|
197
197
|
projectId: fetchedProjectId,
|
|
@@ -227,9 +227,9 @@ var init_ConfigFetcher = __esm({
|
|
|
227
227
|
}
|
|
228
228
|
/** Convenience: fetch only vector DB config (backwards compat). */
|
|
229
229
|
static async fetchRemoteVectorConfig(projectId, licenseKey) {
|
|
230
|
-
var
|
|
230
|
+
var _a3;
|
|
231
231
|
const config = await this.fetchRemoteConfig(projectId, licenseKey);
|
|
232
|
-
return (
|
|
232
|
+
return (_a3 = config == null ? void 0 : config.vectorDb) != null ? _a3 : null;
|
|
233
233
|
}
|
|
234
234
|
};
|
|
235
235
|
ConfigFetcher.cache = /* @__PURE__ */ new Map();
|
|
@@ -278,7 +278,7 @@ var init_PineconeProvider = __esm({
|
|
|
278
278
|
static getHealthChecker() {
|
|
279
279
|
return {
|
|
280
280
|
async check(config) {
|
|
281
|
-
var
|
|
281
|
+
var _a3, _b;
|
|
282
282
|
const opts = config.options || {};
|
|
283
283
|
const indexName = config.indexName;
|
|
284
284
|
const timestamp = Date.now();
|
|
@@ -286,7 +286,7 @@ var init_PineconeProvider = __esm({
|
|
|
286
286
|
const { Pinecone: Pinecone2 } = await import("@pinecone-database/pinecone");
|
|
287
287
|
const client = new Pinecone2({ apiKey: opts.apiKey });
|
|
288
288
|
const indexes = await client.listIndexes();
|
|
289
|
-
const indexNames = (_b = (
|
|
289
|
+
const indexNames = (_b = (_a3 = indexes.indexes) == null ? void 0 : _a3.map((i) => i.name)) != null ? _b : [];
|
|
290
290
|
if (!indexNames.includes(indexName)) {
|
|
291
291
|
return {
|
|
292
292
|
healthy: false,
|
|
@@ -313,7 +313,7 @@ var init_PineconeProvider = __esm({
|
|
|
313
313
|
};
|
|
314
314
|
}
|
|
315
315
|
async initialize() {
|
|
316
|
-
var
|
|
316
|
+
var _a3, _b;
|
|
317
317
|
if (this.client) return;
|
|
318
318
|
let key = this.apiKey || process.env.PINECONE_API_KEY || "";
|
|
319
319
|
if (!key) {
|
|
@@ -350,7 +350,7 @@ var init_PineconeProvider = __esm({
|
|
|
350
350
|
this.client = new import_pinecone.Pinecone({ apiKey: key });
|
|
351
351
|
try {
|
|
352
352
|
const indexes = await this.client.listIndexes();
|
|
353
|
-
const names = (_b = (
|
|
353
|
+
const names = (_b = (_a3 = indexes.indexes) == null ? void 0 : _a3.map((i) => i.name)) != null ? _b : [];
|
|
354
354
|
if (!names.includes(this.indexName)) {
|
|
355
355
|
console.warn(`[PineconeProvider] Target index "${this.indexName}" not listed. Proceeding with configured index name.`);
|
|
356
356
|
}
|
|
@@ -369,13 +369,13 @@ var init_PineconeProvider = __esm({
|
|
|
369
369
|
return namespace ? idx.namespace(namespace) : idx.namespace("");
|
|
370
370
|
}
|
|
371
371
|
async upsert(doc, namespace) {
|
|
372
|
-
var
|
|
372
|
+
var _a3;
|
|
373
373
|
const targetIdx = await this.getActiveIndex(namespace);
|
|
374
374
|
await targetIdx.upsert({
|
|
375
375
|
records: [{
|
|
376
376
|
id: String(doc.id),
|
|
377
377
|
values: doc.vector,
|
|
378
|
-
metadata: __spreadValues({ content: doc.content }, (
|
|
378
|
+
metadata: __spreadValues({ content: doc.content }, (_a3 = doc.metadata) != null ? _a3 : {})
|
|
379
379
|
}]
|
|
380
380
|
});
|
|
381
381
|
}
|
|
@@ -384,18 +384,18 @@ var init_PineconeProvider = __esm({
|
|
|
384
384
|
const BATCH = 100;
|
|
385
385
|
for (let i = 0; i < docs.length; i += BATCH) {
|
|
386
386
|
const records = docs.slice(i, i + BATCH).map((d) => {
|
|
387
|
-
var
|
|
387
|
+
var _a3;
|
|
388
388
|
return {
|
|
389
389
|
id: String(d.id),
|
|
390
390
|
values: d.vector,
|
|
391
|
-
metadata: __spreadValues({ content: d.content }, (
|
|
391
|
+
metadata: __spreadValues({ content: d.content }, (_a3 = d.metadata) != null ? _a3 : {})
|
|
392
392
|
};
|
|
393
393
|
});
|
|
394
394
|
await targetIdx.upsert({ records });
|
|
395
395
|
}
|
|
396
396
|
}
|
|
397
397
|
async query(vector, topK, namespace, filter) {
|
|
398
|
-
var
|
|
398
|
+
var _a3;
|
|
399
399
|
const targetIdx = await this.getActiveIndex(namespace);
|
|
400
400
|
const pineconeFilter = this.sanitizeFilter(filter);
|
|
401
401
|
const result = await targetIdx.query(__spreadValues({
|
|
@@ -403,11 +403,11 @@ var init_PineconeProvider = __esm({
|
|
|
403
403
|
topK,
|
|
404
404
|
includeMetadata: true
|
|
405
405
|
}, Object.keys(pineconeFilter).length > 0 ? { filter: pineconeFilter } : {}));
|
|
406
|
-
return ((
|
|
407
|
-
var
|
|
406
|
+
return ((_a3 = result.matches) != null ? _a3 : []).map((m) => {
|
|
407
|
+
var _a4, _b;
|
|
408
408
|
return {
|
|
409
409
|
id: m.id,
|
|
410
|
-
score: (
|
|
410
|
+
score: (_a4 = m.score) != null ? _a4 : 0,
|
|
411
411
|
content: ((_b = m.metadata) == null ? void 0 : _b.content) || "",
|
|
412
412
|
metadata: m.metadata
|
|
413
413
|
};
|
|
@@ -450,13 +450,13 @@ var init_PostgreSQLProvider = __esm({
|
|
|
450
450
|
init_BaseVectorProvider();
|
|
451
451
|
PostgreSQLProvider = class extends BaseVectorProvider {
|
|
452
452
|
constructor(config) {
|
|
453
|
-
var
|
|
453
|
+
var _a3;
|
|
454
454
|
super(config);
|
|
455
455
|
this.tableName = this.indexName.replace(/[^a-z0-9_]/gi, "_");
|
|
456
456
|
const opts = config.options;
|
|
457
457
|
if (!opts.connectionString) throw new Error("[PostgreSQLProvider] options.connectionString is required");
|
|
458
458
|
this.connectionString = opts.connectionString;
|
|
459
|
-
this.dimensions = (
|
|
459
|
+
this.dimensions = (_a3 = opts.dimensions) != null ? _a3 : 1536;
|
|
460
460
|
}
|
|
461
461
|
static getValidator() {
|
|
462
462
|
return {
|
|
@@ -537,7 +537,7 @@ var init_PostgreSQLProvider = __esm({
|
|
|
537
537
|
}
|
|
538
538
|
}
|
|
539
539
|
async upsert(doc, namespace = "") {
|
|
540
|
-
var
|
|
540
|
+
var _a3;
|
|
541
541
|
const vectorLiteral = `[${doc.vector.join(",")}]`;
|
|
542
542
|
await this.pool.query(
|
|
543
543
|
`INSERT INTO ${this.tableName} (id, namespace, content, metadata, embedding)
|
|
@@ -547,7 +547,7 @@ var init_PostgreSQLProvider = __esm({
|
|
|
547
547
|
content = EXCLUDED.content,
|
|
548
548
|
metadata = EXCLUDED.metadata,
|
|
549
549
|
embedding = EXCLUDED.embedding`,
|
|
550
|
-
[doc.id, namespace, doc.content, JSON.stringify((
|
|
550
|
+
[doc.id, namespace, doc.content, JSON.stringify((_a3 = doc.metadata) != null ? _a3 : {}), vectorLiteral]
|
|
551
551
|
);
|
|
552
552
|
}
|
|
553
553
|
async batchUpsert(docs, namespace = "") {
|
|
@@ -560,9 +560,9 @@ var init_PostgreSQLProvider = __esm({
|
|
|
560
560
|
const batch = docs.slice(i, i + BATCH_SIZE);
|
|
561
561
|
const values = [];
|
|
562
562
|
const valuePlaceholders = batch.map((doc, idx) => {
|
|
563
|
-
var
|
|
563
|
+
var _a3;
|
|
564
564
|
const offset = idx * 5;
|
|
565
|
-
values.push(doc.id, namespace, doc.content, JSON.stringify((
|
|
565
|
+
values.push(doc.id, namespace, doc.content, JSON.stringify((_a3 = doc.metadata) != null ? _a3 : {}), `[${doc.vector.join(",")}]`);
|
|
566
566
|
return `($${offset + 1}, $${offset + 2}, $${offset + 3}, $${offset + 4}, $${offset + 5}::vector)`;
|
|
567
567
|
}).join(", ");
|
|
568
568
|
const query = `
|
|
@@ -645,8 +645,8 @@ var init_PostgreSQLProvider = __esm({
|
|
|
645
645
|
|
|
646
646
|
// src/utils/synonyms.ts
|
|
647
647
|
function resolveMetadataValue(meta, uiKey) {
|
|
648
|
-
var
|
|
649
|
-
const synonyms = (
|
|
648
|
+
var _a3;
|
|
649
|
+
const synonyms = (_a3 = FIELD_SYNONYMS[uiKey]) != null ? _a3 : [];
|
|
650
650
|
const keys = Object.keys(meta);
|
|
651
651
|
const systemKeys = ["namespace", "filename", "filesize", "filetype", "docid", "uploadedat", "dimension", "chunkindex"];
|
|
652
652
|
let match = keys.find((k) => k.toLowerCase() === uiKey.toLowerCase());
|
|
@@ -733,14 +733,14 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
733
733
|
init_synonyms();
|
|
734
734
|
MultiTablePostgresProvider = class extends BaseVectorProvider {
|
|
735
735
|
constructor(config) {
|
|
736
|
-
var
|
|
736
|
+
var _a3, _b, _c;
|
|
737
737
|
super(config);
|
|
738
738
|
const opts = config.options || {};
|
|
739
739
|
if (!opts.connectionString) {
|
|
740
740
|
throw new Error("[MultiTablePostgresProvider] options.connectionString is required");
|
|
741
741
|
}
|
|
742
742
|
this.connectionString = opts.connectionString;
|
|
743
|
-
this.dimensions = (
|
|
743
|
+
this.dimensions = (_a3 = opts.dimensions) != null ? _a3 : 768;
|
|
744
744
|
this.tables = [];
|
|
745
745
|
const rawSearchFields = (_c = (_b = opts.searchFields) != null ? _b : process.env.VECTOR_DB_SEARCH_FIELDS) != null ? _c : ["name", "product_name", "productname", "title"];
|
|
746
746
|
this.searchFields = typeof rawSearchFields === "string" ? rawSearchFields.split(",").map((f) => f.trim()).filter(Boolean) : rawSearchFields;
|
|
@@ -798,11 +798,11 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
798
798
|
* Batch upsert documents by dynamically provisioning tables and columns based on CSV headers.
|
|
799
799
|
*/
|
|
800
800
|
async batchUpsert(docs, namespace = "") {
|
|
801
|
-
var
|
|
801
|
+
var _a3;
|
|
802
802
|
if (docs.length === 0) return;
|
|
803
803
|
const docsByFile = {};
|
|
804
804
|
for (const doc of docs) {
|
|
805
|
-
const fileName = ((
|
|
805
|
+
const fileName = ((_a3 = doc.metadata) == null ? void 0 : _a3.fileName) || this.uploadTable;
|
|
806
806
|
if (!docsByFile[fileName]) docsByFile[fileName] = [];
|
|
807
807
|
docsByFile[fileName].push(doc);
|
|
808
808
|
}
|
|
@@ -855,11 +855,11 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
855
855
|
const headerColumns = csvHeaders.map((h) => `"${h}"`).join(", ");
|
|
856
856
|
const allColumns = `id, ${headerColumns ? headerColumns + ", " : ""}namespace, content, metadata, embedding`;
|
|
857
857
|
const valuePlaceholders = batch.map((doc, idx) => {
|
|
858
|
-
var
|
|
858
|
+
var _a4, _b;
|
|
859
859
|
const offset = idx * (5 + csvHeaders.length);
|
|
860
860
|
values.push(doc.id);
|
|
861
861
|
for (const h of csvHeaders) {
|
|
862
|
-
values.push(String(((
|
|
862
|
+
values.push(String(((_a4 = doc.metadata) == null ? void 0 : _a4[h]) || ""));
|
|
863
863
|
}
|
|
864
864
|
values.push(namespace, doc.content, JSON.stringify((_b = doc.metadata) != null ? _b : {}), `[${doc.vector.join(",")}]`);
|
|
865
865
|
const docPlaceholders = [];
|
|
@@ -898,7 +898,7 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
898
898
|
* Query all configured tables and merge results, sorted by cosine similarity score.
|
|
899
899
|
*/
|
|
900
900
|
async query(vector, topK, _namespace, _filter) {
|
|
901
|
-
var
|
|
901
|
+
var _a3;
|
|
902
902
|
if (!this.pool) {
|
|
903
903
|
throw new Error("[MultiTablePostgresProvider] Provider not initialized. Call initialize() first.");
|
|
904
904
|
}
|
|
@@ -929,11 +929,11 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
929
929
|
const filterParams = [];
|
|
930
930
|
if (metadataFilters && Object.keys(metadataFilters).length > 0) {
|
|
931
931
|
const conditions = Object.entries(metadataFilters).map(([key, val]) => {
|
|
932
|
-
var
|
|
932
|
+
var _a5;
|
|
933
933
|
filterParams.push(String(val));
|
|
934
934
|
const baseOffset = queryText && dynamicKeywordQuery ? 2 : 1;
|
|
935
935
|
const paramIdx = baseOffset + filterParams.length;
|
|
936
|
-
const synonyms = (
|
|
936
|
+
const synonyms = (_a5 = FIELD_SYNONYMS[key]) != null ? _a5 : [];
|
|
937
937
|
const keysToCheck = [key, ...synonyms];
|
|
938
938
|
const coalesceExprs = keysToCheck.flatMap((k) => [
|
|
939
939
|
`metadata->>'${k}'`,
|
|
@@ -1002,7 +1002,7 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
1002
1002
|
}
|
|
1003
1003
|
const tableResults = [];
|
|
1004
1004
|
for (const row of result.rows) {
|
|
1005
|
-
const
|
|
1005
|
+
const _a4 = row, { hybrid_score, id } = _a4, rest = __objRest(_a4, ["hybrid_score", "id"]);
|
|
1006
1006
|
delete rest.embedding;
|
|
1007
1007
|
delete rest.vector_score;
|
|
1008
1008
|
delete rest.keyword_score;
|
|
@@ -1031,10 +1031,10 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
1031
1031
|
}
|
|
1032
1032
|
allResults.sort((a, b) => b.score - a.score);
|
|
1033
1033
|
if (allResults.length === 0) return [];
|
|
1034
|
-
const bestMatchTable = (
|
|
1034
|
+
const bestMatchTable = (_a3 = allResults[0].metadata) == null ? void 0 : _a3.source_table;
|
|
1035
1035
|
const finalSorted = allResults.filter((res) => {
|
|
1036
|
-
var
|
|
1037
|
-
return ((
|
|
1036
|
+
var _a4;
|
|
1037
|
+
return ((_a4 = res.metadata) == null ? void 0 : _a4.source_table) === bestMatchTable;
|
|
1038
1038
|
});
|
|
1039
1039
|
console.log(`[MultiTablePostgresProvider] --- Search Complete ---`);
|
|
1040
1040
|
console.log(`[MultiTablePostgresProvider] Final top match from "${bestMatchTable}" with score ${finalSorted[0].score.toFixed(4)}`);
|
|
@@ -1439,14 +1439,14 @@ var init_QdrantProvider = __esm({
|
|
|
1439
1439
|
* Samples points from the collection to discover available payload fields.
|
|
1440
1440
|
*/
|
|
1441
1441
|
async discoverSchema() {
|
|
1442
|
-
var
|
|
1442
|
+
var _a3;
|
|
1443
1443
|
try {
|
|
1444
1444
|
const { data } = await this.http.post(`/collections/${this.indexName}/points/scroll`, {
|
|
1445
1445
|
limit: 20,
|
|
1446
1446
|
with_payload: true,
|
|
1447
1447
|
with_vector: false
|
|
1448
1448
|
});
|
|
1449
|
-
const points = ((
|
|
1449
|
+
const points = ((_a3 = data.result) == null ? void 0 : _a3.points) || [];
|
|
1450
1450
|
const keys = /* @__PURE__ */ new Set();
|
|
1451
1451
|
for (const point of points) {
|
|
1452
1452
|
const payload = point.payload || {};
|
|
@@ -1472,12 +1472,12 @@ var init_QdrantProvider = __esm({
|
|
|
1472
1472
|
* Ensures the collection exists. Creates it if missing.
|
|
1473
1473
|
*/
|
|
1474
1474
|
async ensureCollection() {
|
|
1475
|
-
var
|
|
1475
|
+
var _a3;
|
|
1476
1476
|
try {
|
|
1477
1477
|
await this.http.get(`/collections/${this.indexName}`);
|
|
1478
1478
|
console.log(`[QdrantProvider] \u2705 Collection "${this.indexName}" already exists.`);
|
|
1479
1479
|
} catch (err) {
|
|
1480
|
-
if (import_axios4.default.isAxiosError(err) && ((
|
|
1480
|
+
if (import_axios4.default.isAxiosError(err) && ((_a3 = err.response) == null ? void 0 : _a3.status) === 404) {
|
|
1481
1481
|
const opts = this.config.options;
|
|
1482
1482
|
const dimensionsForCreate = opts.dimensions || 1536;
|
|
1483
1483
|
console.log(`[QdrantProvider] \u23F3 Creating collection "${this.indexName}" (dimensions: ${dimensionsForCreate})...`);
|
|
@@ -1497,7 +1497,7 @@ var init_QdrantProvider = __esm({
|
|
|
1497
1497
|
* Ensures that a payload field has an index.
|
|
1498
1498
|
*/
|
|
1499
1499
|
async ensureIndex(fieldName, schema = "keyword") {
|
|
1500
|
-
var
|
|
1500
|
+
var _a3;
|
|
1501
1501
|
let fullPath = fieldName;
|
|
1502
1502
|
if (!this.isFlatPayload && !fieldName.includes(".") && fieldName !== "namespace" && fieldName !== this.contentField) {
|
|
1503
1503
|
fullPath = `${this.metadataField}.${fieldName}`;
|
|
@@ -1510,7 +1510,7 @@ var init_QdrantProvider = __esm({
|
|
|
1510
1510
|
console.log(`[QdrantProvider] \u2705 Ensured ${schema} index for "${fullPath}"`);
|
|
1511
1511
|
} catch (err) {
|
|
1512
1512
|
let status;
|
|
1513
|
-
if (import_axios4.default.isAxiosError(err)) status = (
|
|
1513
|
+
if (import_axios4.default.isAxiosError(err)) status = (_a3 = err.response) == null ? void 0 : _a3.status;
|
|
1514
1514
|
if (status === 409) return;
|
|
1515
1515
|
console.warn(`[QdrantProvider] \u26A0\uFE0F Could not ensure index for "${fullPath}":`, err instanceof Error ? err.message : String(err));
|
|
1516
1516
|
}
|
|
@@ -1539,7 +1539,7 @@ var init_QdrantProvider = __esm({
|
|
|
1539
1539
|
await this.http.put(`/collections/${this.indexName}/points`, payload);
|
|
1540
1540
|
}
|
|
1541
1541
|
async query(vector, topK, namespace, _filter) {
|
|
1542
|
-
var
|
|
1542
|
+
var _a3;
|
|
1543
1543
|
const must = [];
|
|
1544
1544
|
if (namespace) {
|
|
1545
1545
|
must.push({ key: "namespace", match: { value: namespace } });
|
|
@@ -1561,7 +1561,7 @@ var init_QdrantProvider = __esm({
|
|
|
1561
1561
|
limit: topK,
|
|
1562
1562
|
with_payload: true,
|
|
1563
1563
|
params: {
|
|
1564
|
-
hnsw_ef: ((
|
|
1564
|
+
hnsw_ef: ((_a3 = this.config.options) == null ? void 0 : _a3.efSearch) || Math.max(topK * 20, 128),
|
|
1565
1565
|
exact: false
|
|
1566
1566
|
},
|
|
1567
1567
|
filter: must.length > 0 ? { must } : void 0
|
|
@@ -1656,13 +1656,13 @@ var init_ChromaDBProvider = __esm({
|
|
|
1656
1656
|
* Get or create the ChromaDB collection.
|
|
1657
1657
|
*/
|
|
1658
1658
|
async initialize() {
|
|
1659
|
-
var
|
|
1659
|
+
var _a3;
|
|
1660
1660
|
try {
|
|
1661
1661
|
const { data } = await this.http.get(`/api/v1/collections/${this.indexName}`);
|
|
1662
1662
|
this.collectionId = data.id;
|
|
1663
1663
|
console.log(`[ChromaDBProvider] \u2705 Collection "${this.indexName}" found (id: ${this.collectionId})`);
|
|
1664
1664
|
} catch (err) {
|
|
1665
|
-
if (import_axios5.default.isAxiosError(err) && ((
|
|
1665
|
+
if (import_axios5.default.isAxiosError(err) && ((_a3 = err.response) == null ? void 0 : _a3.status) === 404) {
|
|
1666
1666
|
console.log(`[ChromaDBProvider] \u23F3 Collection "${this.indexName}" not found. Creating...`);
|
|
1667
1667
|
const { data } = await this.http.post("/api/v1/collections", {
|
|
1668
1668
|
name: this.indexName
|
|
@@ -1883,7 +1883,7 @@ var init_WeaviateProvider = __esm({
|
|
|
1883
1883
|
await this.http.post("/v1/batch/objects", payload);
|
|
1884
1884
|
}
|
|
1885
1885
|
async query(vector, topK, namespace, _filter) {
|
|
1886
|
-
var
|
|
1886
|
+
var _a3, _b;
|
|
1887
1887
|
const queryText = _filter == null ? void 0 : _filter.queryText;
|
|
1888
1888
|
const sanitizedFilter = this.sanitizeFilter(_filter);
|
|
1889
1889
|
const searchParams = queryText ? `hybrid: { query: ${JSON.stringify(queryText)}, alpha: 0.5 }` : `nearVector: { vector: ${JSON.stringify(vector)} }`;
|
|
@@ -1909,7 +1909,7 @@ var init_WeaviateProvider = __esm({
|
|
|
1909
1909
|
`
|
|
1910
1910
|
};
|
|
1911
1911
|
const { data } = await this.http.post("/v1/graphql", graphqlQuery);
|
|
1912
|
-
const results = ((_b = (
|
|
1912
|
+
const results = ((_b = (_a3 = data.data) == null ? void 0 : _a3.Get) == null ? void 0 : _b[this.indexName]) || [];
|
|
1913
1913
|
return results.map((res) => ({
|
|
1914
1914
|
id: res["_additional"].id,
|
|
1915
1915
|
score: 1 - res["_additional"].distance,
|
|
@@ -1992,21 +1992,21 @@ var init_UniversalVectorProvider = __esm({
|
|
|
1992
1992
|
}
|
|
1993
1993
|
}
|
|
1994
1994
|
async initialize() {
|
|
1995
|
-
var
|
|
1995
|
+
var _a3;
|
|
1996
1996
|
this.http = import_axios8.default.create({
|
|
1997
1997
|
baseURL: this.opts.baseUrl,
|
|
1998
1998
|
headers: __spreadValues({
|
|
1999
1999
|
"Content-Type": "application/json"
|
|
2000
2000
|
}, this.opts.headers),
|
|
2001
|
-
timeout: (
|
|
2001
|
+
timeout: (_a3 = this.opts.timeout) != null ? _a3 : 3e4
|
|
2002
2002
|
});
|
|
2003
2003
|
if (!await this.ping()) {
|
|
2004
2004
|
throw new Error(`[UniversalVectorProvider] Failed to connect to ${this.opts.baseUrl}`);
|
|
2005
2005
|
}
|
|
2006
2006
|
}
|
|
2007
2007
|
async upsert(doc, namespace) {
|
|
2008
|
-
var
|
|
2009
|
-
const endpoint = (
|
|
2008
|
+
var _a3, _b, _c;
|
|
2009
|
+
const endpoint = (_a3 = this.opts.upsertEndpoint) != null ? _a3 : "/upsert";
|
|
2010
2010
|
const template = (_b = this.opts.upsertTemplate) != null ? _b : JSON.stringify({
|
|
2011
2011
|
id: "{{id}}",
|
|
2012
2012
|
vector: "{{vector}}",
|
|
@@ -2039,8 +2039,8 @@ var init_UniversalVectorProvider = __esm({
|
|
|
2039
2039
|
}
|
|
2040
2040
|
}
|
|
2041
2041
|
async query(vector, topK, namespace, filter) {
|
|
2042
|
-
var
|
|
2043
|
-
const endpoint = (
|
|
2042
|
+
var _a3, _b;
|
|
2043
|
+
const endpoint = (_a3 = this.opts.queryEndpoint) != null ? _a3 : "/query";
|
|
2044
2044
|
const template = (_b = this.opts.queryTemplate) != null ? _b : JSON.stringify({
|
|
2045
2045
|
vector: "{{vector}}",
|
|
2046
2046
|
limit: "{{topK}}",
|
|
@@ -2066,9 +2066,9 @@ var init_UniversalVectorProvider = __esm({
|
|
|
2066
2066
|
);
|
|
2067
2067
|
}
|
|
2068
2068
|
return results.map((item) => {
|
|
2069
|
-
var
|
|
2069
|
+
var _a4, _b2, _c, _d, _e, _f, _g2;
|
|
2070
2070
|
return {
|
|
2071
|
-
id: item[(
|
|
2071
|
+
id: item[(_a4 = this.opts.queryIdField) != null ? _a4 : "id"],
|
|
2072
2072
|
score: (_c = item[(_b2 = this.opts.queryScoreField) != null ? _b2 : "score"]) != null ? _c : 0,
|
|
2073
2073
|
content: (_e = item[(_d = this.opts.queryContentField) != null ? _d : "content"]) != null ? _e : "",
|
|
2074
2074
|
metadata: (_g2 = item[(_f = this.opts.queryMetadataField) != null ? _f : "metadata"]) != null ? _g2 : {}
|
|
@@ -2081,8 +2081,8 @@ var init_UniversalVectorProvider = __esm({
|
|
|
2081
2081
|
}
|
|
2082
2082
|
}
|
|
2083
2083
|
async delete(id, namespace) {
|
|
2084
|
-
var
|
|
2085
|
-
const endpoint = (
|
|
2084
|
+
var _a3, _b;
|
|
2085
|
+
const endpoint = (_a3 = this.opts.deleteEndpoint) != null ? _a3 : "/delete";
|
|
2086
2086
|
const template = (_b = this.opts.deleteTemplate) != null ? _b : JSON.stringify({
|
|
2087
2087
|
id: "{{id}}",
|
|
2088
2088
|
namespace: "{{namespace}}"
|
|
@@ -2100,8 +2100,8 @@ var init_UniversalVectorProvider = __esm({
|
|
|
2100
2100
|
}
|
|
2101
2101
|
}
|
|
2102
2102
|
async deleteNamespace(namespace) {
|
|
2103
|
-
var
|
|
2104
|
-
const endpoint = (
|
|
2103
|
+
var _a3;
|
|
2104
|
+
const endpoint = (_a3 = this.opts.deleteNamespaceEndpoint) != null ? _a3 : "/delete-namespace";
|
|
2105
2105
|
try {
|
|
2106
2106
|
await this.http.post(endpoint, { namespace });
|
|
2107
2107
|
} catch (error) {
|
|
@@ -2111,9 +2111,9 @@ var init_UniversalVectorProvider = __esm({
|
|
|
2111
2111
|
}
|
|
2112
2112
|
}
|
|
2113
2113
|
async ping() {
|
|
2114
|
-
var
|
|
2114
|
+
var _a3;
|
|
2115
2115
|
try {
|
|
2116
|
-
const endpoint = (
|
|
2116
|
+
const endpoint = (_a3 = this.opts.pingEndpoint) != null ? _a3 : "/health";
|
|
2117
2117
|
const response = await this.http.get(endpoint, { timeout: 5e3 });
|
|
2118
2118
|
return response.status >= 200 && response.status < 300;
|
|
2119
2119
|
} catch (e) {
|
|
@@ -2271,13 +2271,13 @@ var AuthenticationException = class extends RetrivoraError {
|
|
|
2271
2271
|
}
|
|
2272
2272
|
};
|
|
2273
2273
|
function wrapError(err, defaultCode, defaultMessage) {
|
|
2274
|
-
var
|
|
2274
|
+
var _a3;
|
|
2275
2275
|
if (err instanceof RetrivoraError) {
|
|
2276
2276
|
return err;
|
|
2277
2277
|
}
|
|
2278
2278
|
const error = err;
|
|
2279
2279
|
const message = (error == null ? void 0 : error.message) || defaultMessage || String(err);
|
|
2280
|
-
const status = (error == null ? void 0 : error.status) || (error == null ? void 0 : error.statusCode) || ((
|
|
2280
|
+
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);
|
|
2281
2281
|
const code = error == null ? void 0 : error.code;
|
|
2282
2282
|
if (status === 429 || /rate[- ]?limit/i.test(message) || code === "RATE_LIMIT_EXCEEDED") {
|
|
2283
2283
|
return new RateLimitException(message, err);
|
|
@@ -2346,7 +2346,8 @@ var LicenseVerifier = class {
|
|
|
2346
2346
|
};
|
|
2347
2347
|
}
|
|
2348
2348
|
try {
|
|
2349
|
-
const
|
|
2349
|
+
const sanitizedKey = (licenseKey || "").trim().replace(/^["']|["']$/g, "").trim();
|
|
2350
|
+
const rawToken = sanitizedKey.replace(/^rtv_/i, "").trim();
|
|
2350
2351
|
const parts = rawToken.split(".");
|
|
2351
2352
|
if (parts.length !== 3) {
|
|
2352
2353
|
throw new Error("Malformed token structure (expected 3 parts).");
|
|
@@ -2558,8 +2559,8 @@ var UI_BORDER_RADIUS_OPTIONS = ["none", "sm", "md", "lg", "xl", "full"];
|
|
|
2558
2559
|
|
|
2559
2560
|
// src/config/serverConfig.ts
|
|
2560
2561
|
function readString(env, name) {
|
|
2561
|
-
var
|
|
2562
|
-
const value = (
|
|
2562
|
+
var _a3;
|
|
2563
|
+
const value = (_a3 = env[name]) == null ? void 0 : _a3.trim();
|
|
2563
2564
|
return value ? value : void 0;
|
|
2564
2565
|
}
|
|
2565
2566
|
function readNumber(env, name, fallback) {
|
|
@@ -2572,16 +2573,16 @@ function readNumber(env, name, fallback) {
|
|
|
2572
2573
|
return parsed;
|
|
2573
2574
|
}
|
|
2574
2575
|
function readEnum(env, name, fallback, allowed) {
|
|
2575
|
-
var
|
|
2576
|
-
const value = (
|
|
2576
|
+
var _a3;
|
|
2577
|
+
const value = (_a3 = readString(env, name)) != null ? _a3 : fallback;
|
|
2577
2578
|
if (allowed.includes(value)) {
|
|
2578
2579
|
return value;
|
|
2579
2580
|
}
|
|
2580
2581
|
throw new Error(`[getRagConfig] ${name} must be one of: ${allowed.join(", ")}`);
|
|
2581
2582
|
}
|
|
2582
2583
|
function getEnvConfig(env = process.env, base) {
|
|
2583
|
-
var
|
|
2584
|
-
const licenseKey = (_d = (_c = (_b = (
|
|
2584
|
+
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;
|
|
2585
|
+
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;
|
|
2585
2586
|
const jwtProjectId = (() => {
|
|
2586
2587
|
if (!licenseKey) return void 0;
|
|
2587
2588
|
try {
|
|
@@ -2662,7 +2663,7 @@ function getEnvConfig(env = process.env, base) {
|
|
|
2662
2663
|
rest: "default",
|
|
2663
2664
|
custom: "default"
|
|
2664
2665
|
};
|
|
2665
|
-
const
|
|
2666
|
+
const isFreeTier2 = (() => {
|
|
2666
2667
|
if (!licenseKey) return true;
|
|
2667
2668
|
try {
|
|
2668
2669
|
const payload = LicenseVerifier.verify(licenseKey, projectId);
|
|
@@ -2673,13 +2674,13 @@ function getEnvConfig(env = process.env, base) {
|
|
|
2673
2674
|
}
|
|
2674
2675
|
})();
|
|
2675
2676
|
const defaultGatewayUrl = (_ra = (_qa = readString(env, "LITELLM_BASE_URL")) != null ? _qa : readString(env, "LLM_BASE_URL")) != null ? _ra : "https://www.retrivora.com/api/v1";
|
|
2676
|
-
const defaultLlmProvider =
|
|
2677
|
+
const defaultLlmProvider = isFreeTier2 ? "universal_rest" : "universal_rest";
|
|
2677
2678
|
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;
|
|
2678
2679
|
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;
|
|
2679
|
-
const llmModel = (_Ca = (_Aa = readString(env, "LLM_MODEL")) != null ? _Aa : (_za = base == null ? void 0 : base.llm) == null ? void 0 : _za.model) != null ? _Ca :
|
|
2680
|
+
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";
|
|
2680
2681
|
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;
|
|
2681
2682
|
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";
|
|
2682
|
-
const defaultEmbeddingProvider =
|
|
2683
|
+
const defaultEmbeddingProvider = isFreeTier2 ? "universal_rest" : "universal_rest";
|
|
2683
2684
|
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;
|
|
2684
2685
|
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;
|
|
2685
2686
|
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";
|
|
@@ -2769,8 +2770,8 @@ function getEnvConfig(env = process.env, base) {
|
|
|
2769
2770
|
}
|
|
2770
2771
|
} : {}), {
|
|
2771
2772
|
mcpServers: (() => {
|
|
2772
|
-
var
|
|
2773
|
-
const raw = (
|
|
2773
|
+
var _a4;
|
|
2774
|
+
const raw = (_a4 = readString(env, "MCP_SERVERS")) != null ? _a4 : readString(env, "NEXT_PUBLIC_MCP_SERVERS");
|
|
2774
2775
|
if (!raw) return void 0;
|
|
2775
2776
|
try {
|
|
2776
2777
|
return JSON.parse(raw);
|
|
@@ -2815,10 +2816,10 @@ var ConfigResolver = class {
|
|
|
2815
2816
|
* fallback behavior.
|
|
2816
2817
|
*/
|
|
2817
2818
|
static resolveUniversal(hostConfig, env = process.env) {
|
|
2818
|
-
var
|
|
2819
|
+
var _a3;
|
|
2819
2820
|
if (!hostConfig) return this.resolve(void 0, env);
|
|
2820
2821
|
const normalized = __spreadProps(__spreadValues({}, hostConfig), {
|
|
2821
|
-
vectorDb: (
|
|
2822
|
+
vectorDb: (_a3 = hostConfig.vectorDb) != null ? _a3 : hostConfig.vectorDatabase,
|
|
2822
2823
|
rag: this.mergeRetrievalWorkflow(hostConfig.rag, hostConfig.retrieval, hostConfig.workflow)
|
|
2823
2824
|
});
|
|
2824
2825
|
return this.resolve(normalized, env);
|
|
@@ -2838,11 +2839,11 @@ var ConfigResolver = class {
|
|
|
2838
2839
|
}
|
|
2839
2840
|
}
|
|
2840
2841
|
static mergeRetrievalWorkflow(rag, retrieval, workflow) {
|
|
2841
|
-
var
|
|
2842
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
2842
2843
|
if (!rag && !retrieval && !workflow) return void 0;
|
|
2843
2844
|
const normalized = __spreadValues({}, rag != null ? rag : {});
|
|
2844
2845
|
if (retrieval) {
|
|
2845
|
-
normalized.topK = (
|
|
2846
|
+
normalized.topK = (_a3 = retrieval.topK) != null ? _a3 : normalized.topK;
|
|
2846
2847
|
normalized.scoreThreshold = (_b = retrieval.scoreThreshold) != null ? _b : normalized.scoreThreshold;
|
|
2847
2848
|
normalized.useReranking = (_c = retrieval.useReranking) != null ? _c : normalized.useReranking;
|
|
2848
2849
|
if (retrieval.strategy === "hybrid") normalized.architecture = (_d = normalized.architecture) != null ? _d : "hybrid";
|
|
@@ -2970,8 +2971,8 @@ var OpenAIProvider = class {
|
|
|
2970
2971
|
};
|
|
2971
2972
|
}
|
|
2972
2973
|
async chat(messages, context, options) {
|
|
2973
|
-
var
|
|
2974
|
-
const basePrompt = (_b = (
|
|
2974
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i;
|
|
2975
|
+
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
2976
|
const systemMessage = {
|
|
2976
2977
|
role: "system",
|
|
2977
2978
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -2995,8 +2996,8 @@ var OpenAIProvider = class {
|
|
|
2995
2996
|
}
|
|
2996
2997
|
chatStream(messages, context, options) {
|
|
2997
2998
|
return __asyncGenerator(this, null, function* () {
|
|
2998
|
-
var
|
|
2999
|
-
const basePrompt = (_b = (
|
|
2999
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h;
|
|
3000
|
+
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.";
|
|
3000
3001
|
const systemMessage = {
|
|
3001
3002
|
role: "system",
|
|
3002
3003
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3043,8 +3044,8 @@ var OpenAIProvider = class {
|
|
|
3043
3044
|
return results[0];
|
|
3044
3045
|
}
|
|
3045
3046
|
async batchEmbed(texts, options) {
|
|
3046
|
-
var
|
|
3047
|
-
const model = (_c = (_b = options == null ? void 0 : options.model) != null ? _b : (
|
|
3047
|
+
var _a3, _b, _c, _d, _e;
|
|
3048
|
+
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";
|
|
3048
3049
|
const apiKey = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.apiKey) != null ? _e : this.llmConfig.apiKey;
|
|
3049
3050
|
const client = apiKey !== this.llmConfig.apiKey ? new import_openai.default({ apiKey }) : this.client;
|
|
3050
3051
|
const response = await client.embeddings.create({ model, input: texts });
|
|
@@ -3121,8 +3122,8 @@ var AnthropicProvider = class {
|
|
|
3121
3122
|
};
|
|
3122
3123
|
}
|
|
3123
3124
|
async chat(messages, context, options) {
|
|
3124
|
-
var
|
|
3125
|
-
const basePrompt = (_b = (
|
|
3125
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
|
|
3126
|
+
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.";
|
|
3126
3127
|
const system = buildSystemContent(basePrompt, context);
|
|
3127
3128
|
const anthropicMessages = messages.map((m) => ({
|
|
3128
3129
|
role: m.role === "assistant" ? "assistant" : "user",
|
|
@@ -3160,8 +3161,8 @@ var AnthropicProvider = class {
|
|
|
3160
3161
|
}
|
|
3161
3162
|
chatStream(messages, context, options) {
|
|
3162
3163
|
return __asyncGenerator(this, null, function* () {
|
|
3163
|
-
var
|
|
3164
|
-
const basePrompt = (_b = (
|
|
3164
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
|
|
3165
|
+
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.";
|
|
3165
3166
|
const system = buildSystemContent(basePrompt, context);
|
|
3166
3167
|
const anthropicMessages = messages.map((m) => ({
|
|
3167
3168
|
role: m.role === "assistant" ? "assistant" : "user",
|
|
@@ -3245,8 +3246,8 @@ var AnthropicProvider = class {
|
|
|
3245
3246
|
var import_axios = __toESM(require("axios"));
|
|
3246
3247
|
var OllamaProvider = class {
|
|
3247
3248
|
constructor(llmConfig, embeddingConfig) {
|
|
3248
|
-
var
|
|
3249
|
-
const rawBaseURL = ((
|
|
3249
|
+
var _a3, _b, _c;
|
|
3250
|
+
const rawBaseURL = ((_a3 = llmConfig.baseUrl) != null ? _a3 : "http://localhost:11434").replace(/\/+$/, "");
|
|
3250
3251
|
const baseURL = rawBaseURL.replace(/\/(?:api\/v1|v1|api)$/i, "");
|
|
3251
3252
|
const timeout = Number((_b = llmConfig.options) == null ? void 0 : _b.timeout) || 3e5;
|
|
3252
3253
|
const headers = ((_c = llmConfig.options) == null ? void 0 : _c.headers) || {};
|
|
@@ -3306,8 +3307,8 @@ var OllamaProvider = class {
|
|
|
3306
3307
|
};
|
|
3307
3308
|
}
|
|
3308
3309
|
async chat(messages, context, options) {
|
|
3309
|
-
var
|
|
3310
|
-
const basePrompt = (_b = (
|
|
3310
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
3311
|
+
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.";
|
|
3311
3312
|
const system = buildSystemContent(basePrompt, context);
|
|
3312
3313
|
const { data } = await this.http.post("/api/chat", {
|
|
3313
3314
|
model: this.llmConfig.model,
|
|
@@ -3325,8 +3326,8 @@ var OllamaProvider = class {
|
|
|
3325
3326
|
}
|
|
3326
3327
|
chatStream(messages, context, options) {
|
|
3327
3328
|
return __asyncGenerator(this, null, function* () {
|
|
3328
|
-
var
|
|
3329
|
-
const basePrompt = (_b = (
|
|
3329
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h;
|
|
3330
|
+
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.";
|
|
3330
3331
|
const system = buildSystemContent(basePrompt, context);
|
|
3331
3332
|
const response = yield new __await(this.http.post("/api/chat", {
|
|
3332
3333
|
model: this.llmConfig.model,
|
|
@@ -3384,8 +3385,8 @@ var OllamaProvider = class {
|
|
|
3384
3385
|
});
|
|
3385
3386
|
}
|
|
3386
3387
|
async embed(text, options) {
|
|
3387
|
-
var
|
|
3388
|
-
const model = (_c = (_b = options == null ? void 0 : options.model) != null ? _b : (
|
|
3388
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
|
|
3389
|
+
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";
|
|
3389
3390
|
const baseURL = (_f = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.baseUrl) != null ? _e : this.llmConfig.baseUrl) != null ? _f : "http://localhost:11434";
|
|
3390
3391
|
const client = baseURL !== ((_g2 = this.llmConfig.baseUrl) != null ? _g2 : "http://localhost:11434") ? import_axios.default.create({ baseURL, timeout: 6e4 }) : this.http;
|
|
3391
3392
|
let prompt = text;
|
|
@@ -3486,9 +3487,9 @@ var GeminiProvider = class {
|
|
|
3486
3487
|
static getHealthChecker() {
|
|
3487
3488
|
return {
|
|
3488
3489
|
async check(config) {
|
|
3489
|
-
var
|
|
3490
|
+
var _a3, _b;
|
|
3490
3491
|
const timestamp = Date.now();
|
|
3491
|
-
const apiKey = (_b = (
|
|
3492
|
+
const apiKey = (_b = (_a3 = config.apiKey) != null ? _a3 : process.env.GOOGLE_GENAI_API_KEY) != null ? _b : "";
|
|
3492
3493
|
const modelName = sanitizeModel(config.model);
|
|
3493
3494
|
try {
|
|
3494
3495
|
const { GoogleGenerativeAI: GoogleGenerativeAI2 } = await import("@google/generative-ai");
|
|
@@ -3518,16 +3519,16 @@ var GeminiProvider = class {
|
|
|
3518
3519
|
/** Resolve the embedding client — uses a separate client when the embedding
|
|
3519
3520
|
* API key differs from the LLM API key. */
|
|
3520
3521
|
get embeddingClient() {
|
|
3521
|
-
var
|
|
3522
|
-
if (((
|
|
3522
|
+
var _a3;
|
|
3523
|
+
if (((_a3 = this.embeddingConfig) == null ? void 0 : _a3.apiKey) && this.embeddingConfig.apiKey !== this.llmConfig.apiKey) {
|
|
3523
3524
|
return buildClient(this.embeddingConfig.apiKey);
|
|
3524
3525
|
}
|
|
3525
3526
|
return this.client;
|
|
3526
3527
|
}
|
|
3527
3528
|
/** Resolve the embedding model to use, in order of specificity. */
|
|
3528
3529
|
resolveEmbeddingModel(optionsModel) {
|
|
3529
|
-
var
|
|
3530
|
-
return sanitizeModel((_b = optionsModel != null ? optionsModel : (
|
|
3530
|
+
var _a3, _b;
|
|
3531
|
+
return sanitizeModel((_b = optionsModel != null ? optionsModel : (_a3 = this.embeddingConfig) == null ? void 0 : _a3.model) != null ? _b : DEFAULT_EMBEDDING_MODEL);
|
|
3531
3532
|
}
|
|
3532
3533
|
/**
|
|
3533
3534
|
* Convert ChatMessage[] to the Gemini contents format.
|
|
@@ -3547,8 +3548,8 @@ var GeminiProvider = class {
|
|
|
3547
3548
|
// ILLMProvider — chat
|
|
3548
3549
|
// -------------------------------------------------------------------------
|
|
3549
3550
|
async chat(messages, context, options) {
|
|
3550
|
-
var
|
|
3551
|
-
const basePrompt = (_b = (
|
|
3551
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
3552
|
+
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.";
|
|
3552
3553
|
const model = this.client.getGenerativeModel({
|
|
3553
3554
|
model: this.llmConfig.model,
|
|
3554
3555
|
systemInstruction: buildSystemContent(basePrompt, context)
|
|
@@ -3565,8 +3566,8 @@ var GeminiProvider = class {
|
|
|
3565
3566
|
}
|
|
3566
3567
|
chatStream(messages, context, options) {
|
|
3567
3568
|
return __asyncGenerator(this, null, function* () {
|
|
3568
|
-
var
|
|
3569
|
-
const basePrompt = (_b = (
|
|
3569
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
3570
|
+
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.";
|
|
3570
3571
|
const model = this.client.getGenerativeModel({
|
|
3571
3572
|
model: this.llmConfig.model,
|
|
3572
3573
|
systemInstruction: buildSystemContent(basePrompt, context)
|
|
@@ -3601,11 +3602,11 @@ var GeminiProvider = class {
|
|
|
3601
3602
|
// ILLMProvider — embeddings
|
|
3602
3603
|
// -------------------------------------------------------------------------
|
|
3603
3604
|
async embed(text, options) {
|
|
3604
|
-
var
|
|
3605
|
+
var _a3, _b;
|
|
3605
3606
|
const content = applyPrefix(
|
|
3606
3607
|
text,
|
|
3607
3608
|
options == null ? void 0 : options.taskType,
|
|
3608
|
-
(
|
|
3609
|
+
(_a3 = this.embeddingConfig) == null ? void 0 : _a3.queryPrefix,
|
|
3609
3610
|
(_b = this.embeddingConfig) == null ? void 0 : _b.documentPrefix
|
|
3610
3611
|
);
|
|
3611
3612
|
const modelName = this.resolveEmbeddingModel(options == null ? void 0 : options.model);
|
|
@@ -3622,7 +3623,7 @@ var GeminiProvider = class {
|
|
|
3622
3623
|
const modelName = this.resolveEmbeddingModel(options == null ? void 0 : options.model);
|
|
3623
3624
|
const model = this.embeddingClient.getGenerativeModel({ model: modelName });
|
|
3624
3625
|
const requests = texts.map((text) => {
|
|
3625
|
-
var
|
|
3626
|
+
var _a3, _b;
|
|
3626
3627
|
return {
|
|
3627
3628
|
content: {
|
|
3628
3629
|
role: "user",
|
|
@@ -3630,7 +3631,7 @@ var GeminiProvider = class {
|
|
|
3630
3631
|
text: applyPrefix(
|
|
3631
3632
|
text,
|
|
3632
3633
|
options == null ? void 0 : options.taskType,
|
|
3633
|
-
(
|
|
3634
|
+
(_a3 = this.embeddingConfig) == null ? void 0 : _a3.queryPrefix,
|
|
3634
3635
|
(_b = this.embeddingConfig) == null ? void 0 : _b.documentPrefix
|
|
3635
3636
|
)
|
|
3636
3637
|
}]
|
|
@@ -3647,8 +3648,8 @@ var GeminiProvider = class {
|
|
|
3647
3648
|
throw err;
|
|
3648
3649
|
});
|
|
3649
3650
|
return response.embeddings.map((e) => {
|
|
3650
|
-
var
|
|
3651
|
-
return (
|
|
3651
|
+
var _a3;
|
|
3652
|
+
return (_a3 = e.values) != null ? _a3 : [];
|
|
3652
3653
|
});
|
|
3653
3654
|
}
|
|
3654
3655
|
// -------------------------------------------------------------------------
|
|
@@ -3737,8 +3738,8 @@ var GroqProvider = class {
|
|
|
3737
3738
|
};
|
|
3738
3739
|
}
|
|
3739
3740
|
async chat(messages, context, options) {
|
|
3740
|
-
var
|
|
3741
|
-
const basePrompt = (_b = (
|
|
3741
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i;
|
|
3742
|
+
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
3743
|
const systemMessage = {
|
|
3743
3744
|
role: "system",
|
|
3744
3745
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3762,8 +3763,8 @@ var GroqProvider = class {
|
|
|
3762
3763
|
}
|
|
3763
3764
|
chatStream(messages, context, options) {
|
|
3764
3765
|
return __asyncGenerator(this, null, function* () {
|
|
3765
|
-
var
|
|
3766
|
-
const basePrompt = (_b = (
|
|
3766
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h;
|
|
3767
|
+
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.";
|
|
3767
3768
|
const systemMessage = {
|
|
3768
3769
|
role: "system",
|
|
3769
3770
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3897,8 +3898,8 @@ var QwenProvider = class {
|
|
|
3897
3898
|
};
|
|
3898
3899
|
}
|
|
3899
3900
|
async chat(messages, context, options) {
|
|
3900
|
-
var
|
|
3901
|
-
const basePrompt = (_b = (
|
|
3901
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i;
|
|
3902
|
+
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
3903
|
const systemMessage = {
|
|
3903
3904
|
role: "system",
|
|
3904
3905
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3922,8 +3923,8 @@ var QwenProvider = class {
|
|
|
3922
3923
|
}
|
|
3923
3924
|
chatStream(messages, context, options) {
|
|
3924
3925
|
return __asyncGenerator(this, null, function* () {
|
|
3925
|
-
var
|
|
3926
|
-
const basePrompt = (_b = (
|
|
3926
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h;
|
|
3927
|
+
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.";
|
|
3927
3928
|
const systemMessage = {
|
|
3928
3929
|
role: "system",
|
|
3929
3930
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3970,8 +3971,8 @@ var QwenProvider = class {
|
|
|
3970
3971
|
return results[0];
|
|
3971
3972
|
}
|
|
3972
3973
|
async batchEmbed(texts, options) {
|
|
3973
|
-
var
|
|
3974
|
-
const model = (_c = (_b = options == null ? void 0 : options.model) != null ? _b : (
|
|
3974
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
3975
|
+
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";
|
|
3975
3976
|
const apiKey = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.apiKey) != null ? _e : this.llmConfig.apiKey;
|
|
3976
3977
|
const client = apiKey !== this.llmConfig.apiKey ? new import_openai3.default({
|
|
3977
3978
|
apiKey,
|
|
@@ -4032,9 +4033,9 @@ var LLM_PROFILES = {
|
|
|
4032
4033
|
|
|
4033
4034
|
// src/llm/providers/UniversalLLMAdapter.ts
|
|
4034
4035
|
function extractContent(obj) {
|
|
4035
|
-
var
|
|
4036
|
+
var _a3, _b, _c;
|
|
4036
4037
|
if (!obj || typeof obj !== "object") return void 0;
|
|
4037
|
-
const choice = (
|
|
4038
|
+
const choice = (_a3 = obj.choices) == null ? void 0 : _a3[0];
|
|
4038
4039
|
if (!choice) return void 0;
|
|
4039
4040
|
if (typeof ((_b = choice.message) == null ? void 0 : _b.content) === "string") return choice.message.content;
|
|
4040
4041
|
if (typeof ((_c = choice.delta) == null ? void 0 : _c.content) === "string") return choice.delta.content;
|
|
@@ -4044,10 +4045,10 @@ function extractContent(obj) {
|
|
|
4044
4045
|
}
|
|
4045
4046
|
var UniversalLLMAdapter = class {
|
|
4046
4047
|
constructor(config) {
|
|
4047
|
-
var
|
|
4048
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h;
|
|
4048
4049
|
this.model = config.model;
|
|
4049
4050
|
const llmConfig = config;
|
|
4050
|
-
const options = (
|
|
4051
|
+
const options = (_a3 = llmConfig.options) != null ? _a3 : {};
|
|
4051
4052
|
let profile = {};
|
|
4052
4053
|
if (typeof options.profile === "string") {
|
|
4053
4054
|
profile = LLM_PROFILES[options.profile] || {};
|
|
@@ -4073,8 +4074,8 @@ var UniversalLLMAdapter = class {
|
|
|
4073
4074
|
});
|
|
4074
4075
|
}
|
|
4075
4076
|
async chat(messages, context) {
|
|
4076
|
-
var
|
|
4077
|
-
const path2 = (
|
|
4077
|
+
var _a3, _b, _c, _d, _e;
|
|
4078
|
+
const path2 = (_a3 = this.opts.chatPath) != null ? _a3 : "/chat/completions";
|
|
4078
4079
|
const safeMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
|
|
4079
4080
|
role: m.role || "user",
|
|
4080
4081
|
content: typeof m.content === "string" ? m.content : m.content != null ? String(m.content) : ""
|
|
@@ -4140,8 +4141,8 @@ ${context != null ? context : "None"}` },
|
|
|
4140
4141
|
*/
|
|
4141
4142
|
chatStream(messages, context) {
|
|
4142
4143
|
return __asyncGenerator(this, null, function* () {
|
|
4143
|
-
var
|
|
4144
|
-
const path2 = (
|
|
4144
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
4145
|
+
const path2 = (_a3 = this.opts.chatPath) != null ? _a3 : "/chat/completions";
|
|
4145
4146
|
const url = `${this.baseUrl.replace(/\/$/, "")}${path2}`;
|
|
4146
4147
|
const extractPath = ((_b = this.opts.responseExtractPath) != null ? _b : "choices[0].message.content").replace("message.content", "delta.content");
|
|
4147
4148
|
const safeMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
|
|
@@ -4267,8 +4268,8 @@ ${context != null ? context : "None"}` },
|
|
|
4267
4268
|
});
|
|
4268
4269
|
}
|
|
4269
4270
|
async embed(text) {
|
|
4270
|
-
var
|
|
4271
|
-
const path2 = (
|
|
4271
|
+
var _a3, _b, _c, _d, _e;
|
|
4272
|
+
const path2 = (_a3 = this.opts.embedPath) != null ? _a3 : "/embeddings";
|
|
4272
4273
|
const payload = this.opts.embedPayloadTemplate ? buildPayload(this.opts.embedPayloadTemplate, { input: text, model: this.model }) : { input: text, model: this.model };
|
|
4273
4274
|
try {
|
|
4274
4275
|
const { data: data2 } = await this.http.post(path2, payload);
|
|
@@ -4357,7 +4358,7 @@ var LLMFactory = class _LLMFactory {
|
|
|
4357
4358
|
];
|
|
4358
4359
|
}
|
|
4359
4360
|
static create(llmConfig, embeddingConfig) {
|
|
4360
|
-
var
|
|
4361
|
+
var _a3, _b, _c;
|
|
4361
4362
|
switch (llmConfig.provider) {
|
|
4362
4363
|
case "openai":
|
|
4363
4364
|
return new OpenAIProvider(llmConfig, embeddingConfig);
|
|
@@ -4376,7 +4377,7 @@ var LLMFactory = class _LLMFactory {
|
|
|
4376
4377
|
case "custom":
|
|
4377
4378
|
return new UniversalLLMAdapter(llmConfig);
|
|
4378
4379
|
default: {
|
|
4379
|
-
const providerName = String((
|
|
4380
|
+
const providerName = String((_a3 = llmConfig.provider) != null ? _a3 : "").toLowerCase();
|
|
4380
4381
|
const customFactory = customProviders.get(providerName);
|
|
4381
4382
|
if (customFactory) {
|
|
4382
4383
|
return customFactory(llmConfig);
|
|
@@ -4478,7 +4479,7 @@ var ProviderRegistry = class {
|
|
|
4478
4479
|
return null;
|
|
4479
4480
|
}
|
|
4480
4481
|
static async loadVectorProviderClass(provider) {
|
|
4481
|
-
var
|
|
4482
|
+
var _a3;
|
|
4482
4483
|
if (this.vectorProviders[provider]) return this.vectorProviders[provider];
|
|
4483
4484
|
switch (provider) {
|
|
4484
4485
|
case "pinecone": {
|
|
@@ -4487,7 +4488,7 @@ var ProviderRegistry = class {
|
|
|
4487
4488
|
}
|
|
4488
4489
|
case "pgvector":
|
|
4489
4490
|
case "postgresql": {
|
|
4490
|
-
const postgresMode = ((
|
|
4491
|
+
const postgresMode = ((_a3 = process.env.POSTGRES_MODE) != null ? _a3 : "multi").toLowerCase();
|
|
4491
4492
|
if (postgresMode === "single") {
|
|
4492
4493
|
const { PostgreSQLProvider: PostgreSQLProvider2 } = await Promise.resolve().then(() => (init_PostgreSQLProvider(), PostgreSQLProvider_exports));
|
|
4493
4494
|
return PostgreSQLProvider2;
|
|
@@ -4710,7 +4711,7 @@ var ConfigValidator = class {
|
|
|
4710
4711
|
// package.json
|
|
4711
4712
|
var package_default = {
|
|
4712
4713
|
name: "@retrivora-ai/rag-engine",
|
|
4713
|
-
version: "2.
|
|
4714
|
+
version: "2.3.1",
|
|
4714
4715
|
description: "Retrivora AI is a plug-and-play AI engine for RAG chat experiences \u2014 generic vector DB + LLM provider, embeddable or standalone.",
|
|
4715
4716
|
author: "Abhinav Alkuchi",
|
|
4716
4717
|
license: "UNLICENSED",
|
|
@@ -5015,8 +5016,8 @@ var Reranker = class {
|
|
|
5015
5016
|
return matches.sort((a, b) => b.score - a.score).slice(0, limit);
|
|
5016
5017
|
}
|
|
5017
5018
|
const scoredMatches = matches.map((match) => {
|
|
5018
|
-
var
|
|
5019
|
-
const contentLower = ((
|
|
5019
|
+
var _a3;
|
|
5020
|
+
const contentLower = ((_a3 = match == null ? void 0 : match.content) != null ? _a3 : "").toLowerCase();
|
|
5020
5021
|
let keywordScore = 0;
|
|
5021
5022
|
keywords.forEach((keyword) => {
|
|
5022
5023
|
if (contentLower.includes(keyword)) {
|
|
@@ -5038,8 +5039,8 @@ var Reranker = class {
|
|
|
5038
5039
|
|
|
5039
5040
|
Documents:
|
|
5040
5041
|
${topN.map((m, i) => {
|
|
5041
|
-
var
|
|
5042
|
-
return `[${i}] ${((
|
|
5042
|
+
var _a3;
|
|
5043
|
+
return `[${i}] ${((_a3 = m == null ? void 0 : m.content) != null ? _a3 : "").replace(/\n/g, " ")}`;
|
|
5043
5044
|
}).join("\n")}` }],
|
|
5044
5045
|
"",
|
|
5045
5046
|
{
|
|
@@ -5083,11 +5084,11 @@ var LlamaIndexIngestor = class {
|
|
|
5083
5084
|
* than standard character-count splitting.
|
|
5084
5085
|
*/
|
|
5085
5086
|
async chunk(text, options = {}) {
|
|
5086
|
-
var
|
|
5087
|
+
var _a3, _b;
|
|
5087
5088
|
try {
|
|
5088
5089
|
const { Document, SentenceSplitter, MetadataMode } = await import(`${"llamaindex"}`);
|
|
5089
5090
|
const splitter = new SentenceSplitter({
|
|
5090
|
-
chunkSize: (
|
|
5091
|
+
chunkSize: (_a3 = options.chunkSize) != null ? _a3 : 1e3,
|
|
5091
5092
|
chunkOverlap: (_b = options.chunkOverlap) != null ? _b : 200
|
|
5092
5093
|
});
|
|
5093
5094
|
const doc = new Document({ text, metadata: options.metadata || {} });
|
|
@@ -5196,7 +5197,7 @@ ${error instanceof Error ? error.message : String(error)}`
|
|
|
5196
5197
|
* The agent returns `{ messages: [...] }` — the last message is the final answer.
|
|
5197
5198
|
*/
|
|
5198
5199
|
async run(input, chatHistory = []) {
|
|
5199
|
-
var
|
|
5200
|
+
var _a3, _b, _c;
|
|
5200
5201
|
if (!this.agent) {
|
|
5201
5202
|
throw new Error("[LangChainAgent] Agent not initialized. Call initialize() first.");
|
|
5202
5203
|
}
|
|
@@ -5207,7 +5208,7 @@ ${error instanceof Error ? error.message : String(error)}`
|
|
|
5207
5208
|
const response = await this.agent.invoke({
|
|
5208
5209
|
messages: [...historyMessages, new HumanMessage(input)]
|
|
5209
5210
|
});
|
|
5210
|
-
const lastMessage = (
|
|
5211
|
+
const lastMessage = (_a3 = response == null ? void 0 : response.messages) == null ? void 0 : _a3.at(-1);
|
|
5211
5212
|
if (lastMessage && typeof lastMessage.content === "string") {
|
|
5212
5213
|
return lastMessage.content;
|
|
5213
5214
|
}
|
|
@@ -5259,7 +5260,7 @@ var MCPClient = class {
|
|
|
5259
5260
|
}
|
|
5260
5261
|
}
|
|
5261
5262
|
async connectStdio() {
|
|
5262
|
-
var
|
|
5263
|
+
var _a3;
|
|
5263
5264
|
const cmd = this.config.command;
|
|
5264
5265
|
if (!cmd) {
|
|
5265
5266
|
throw new Error(`[MCPClient] Command option is required for stdio transport on "${this.config.name}"`);
|
|
@@ -5274,7 +5275,7 @@ var MCPClient = class {
|
|
|
5274
5275
|
this.stdioBuffer += data.toString("utf-8");
|
|
5275
5276
|
this.processStdioLines();
|
|
5276
5277
|
});
|
|
5277
|
-
(
|
|
5278
|
+
(_a3 = this.childProcess.stderr) == null ? void 0 : _a3.on("data", (data) => {
|
|
5278
5279
|
console.warn(`[MCPClient] [stderr] [${this.config.name}]:`, data.toString("utf-8"));
|
|
5279
5280
|
});
|
|
5280
5281
|
this.childProcess.on("close", (code) => {
|
|
@@ -5349,14 +5350,14 @@ var MCPClient = class {
|
|
|
5349
5350
|
}
|
|
5350
5351
|
}
|
|
5351
5352
|
async sendNotification(method, params) {
|
|
5352
|
-
var
|
|
5353
|
+
var _a3;
|
|
5353
5354
|
const notification = {
|
|
5354
5355
|
jsonrpc: "2.0",
|
|
5355
5356
|
method,
|
|
5356
5357
|
params
|
|
5357
5358
|
};
|
|
5358
5359
|
if (this.config.transport === "stdio") {
|
|
5359
|
-
if ((
|
|
5360
|
+
if ((_a3 = this.childProcess) == null ? void 0 : _a3.stdin) {
|
|
5360
5361
|
this.childProcess.stdin.write(JSON.stringify(notification) + "\n", "utf-8");
|
|
5361
5362
|
}
|
|
5362
5363
|
} else if (this.sseUrl) {
|
|
@@ -5434,11 +5435,11 @@ var MCPRegistry = class {
|
|
|
5434
5435
|
// src/core/MultiAgentCoordinator.ts
|
|
5435
5436
|
var MultiAgentCoordinator = class {
|
|
5436
5437
|
constructor(options) {
|
|
5437
|
-
var
|
|
5438
|
+
var _a3;
|
|
5438
5439
|
this.llmProvider = options.llmProvider;
|
|
5439
5440
|
this.mcpRegistry = options.mcpRegistry;
|
|
5440
5441
|
this.documentSearch = options.documentSearch;
|
|
5441
|
-
this.maxIterations = (
|
|
5442
|
+
this.maxIterations = (_a3 = options.maxIterations) != null ? _a3 : 5;
|
|
5442
5443
|
}
|
|
5443
5444
|
/**
|
|
5444
5445
|
* Run the multi-agent coordination loop synchronously and return the final response.
|
|
@@ -5490,8 +5491,8 @@ Available Tools:
|
|
|
5490
5491
|
|
|
5491
5492
|
${mcpTools.length > 0 ? "MCP Server Tools:" : ""}
|
|
5492
5493
|
${mcpTools.map((mt) => {
|
|
5493
|
-
var
|
|
5494
|
-
return `- ${mt.tool.name}(${JSON.stringify(((
|
|
5494
|
+
var _a3;
|
|
5495
|
+
return `- ${mt.tool.name}(${JSON.stringify(((_a3 = mt.tool.inputSchema) == null ? void 0 : _a3.properties) || {})}): ${mt.tool.description || "No description provided."}`;
|
|
5495
5496
|
}).join("\n")}
|
|
5496
5497
|
|
|
5497
5498
|
Tool Calling Protocol:
|
|
@@ -5649,6 +5650,100 @@ ${toolResultText}`
|
|
|
5649
5650
|
}
|
|
5650
5651
|
};
|
|
5651
5652
|
|
|
5653
|
+
// src/core/CircuitBreaker.ts
|
|
5654
|
+
var CircuitBreaker = class {
|
|
5655
|
+
constructor(options = {}) {
|
|
5656
|
+
this.state = "closed";
|
|
5657
|
+
this.failureCount = 0;
|
|
5658
|
+
this.successCount = 0;
|
|
5659
|
+
this.lastFailureAt = 0;
|
|
5660
|
+
this.halfOpenCalls = 0;
|
|
5661
|
+
var _a3, _b, _c;
|
|
5662
|
+
this.failureThreshold = (_a3 = options.failureThreshold) != null ? _a3 : 5;
|
|
5663
|
+
this.resetTimeoutMs = (_b = options.resetTimeoutMs) != null ? _b : 3e4;
|
|
5664
|
+
this.halfOpenMaxCalls = (_c = options.halfOpenMaxCalls) != null ? _c : 1;
|
|
5665
|
+
}
|
|
5666
|
+
record(success) {
|
|
5667
|
+
const now = Date.now();
|
|
5668
|
+
if (success) {
|
|
5669
|
+
this.successCount++;
|
|
5670
|
+
if (this.state === "half-open") {
|
|
5671
|
+
this.state = "closed";
|
|
5672
|
+
this.failureCount = 0;
|
|
5673
|
+
this.halfOpenCalls = 0;
|
|
5674
|
+
this.successCount = 1;
|
|
5675
|
+
} else if (this.state === "closed") {
|
|
5676
|
+
if (this.successCount >= this.failureThreshold) {
|
|
5677
|
+
this.failureCount = Math.max(0, this.failureCount - 1);
|
|
5678
|
+
this.successCount = 0;
|
|
5679
|
+
}
|
|
5680
|
+
}
|
|
5681
|
+
} else {
|
|
5682
|
+
this.failureCount++;
|
|
5683
|
+
this.lastFailureAt = now;
|
|
5684
|
+
this.successCount = 0;
|
|
5685
|
+
if (this.state === "half-open") {
|
|
5686
|
+
this.state = "open";
|
|
5687
|
+
this.halfOpenCalls = 0;
|
|
5688
|
+
} else if (this.state === "closed" && this.failureCount >= this.failureThreshold) {
|
|
5689
|
+
this.state = "open";
|
|
5690
|
+
}
|
|
5691
|
+
}
|
|
5692
|
+
}
|
|
5693
|
+
canExecute() {
|
|
5694
|
+
const now = Date.now();
|
|
5695
|
+
if (this.state === "closed") {
|
|
5696
|
+
return true;
|
|
5697
|
+
}
|
|
5698
|
+
if (this.state === "open") {
|
|
5699
|
+
if (now - this.lastFailureAt >= this.resetTimeoutMs) {
|
|
5700
|
+
this.state = "half-open";
|
|
5701
|
+
this.halfOpenCalls = 0;
|
|
5702
|
+
return true;
|
|
5703
|
+
}
|
|
5704
|
+
return false;
|
|
5705
|
+
}
|
|
5706
|
+
if (this.state === "half-open") {
|
|
5707
|
+
return this.halfOpenCalls < this.halfOpenMaxCalls;
|
|
5708
|
+
}
|
|
5709
|
+
return true;
|
|
5710
|
+
}
|
|
5711
|
+
async wrap(fn) {
|
|
5712
|
+
if (!this.canExecute()) {
|
|
5713
|
+
const retryAfterSec = Math.ceil(
|
|
5714
|
+
Math.max(0, this.resetTimeoutMs - (Date.now() - this.lastFailureAt)) / 1e3
|
|
5715
|
+
);
|
|
5716
|
+
throw new Error(
|
|
5717
|
+
`Circuit breaker is open. Try again in ${retryAfterSec}s. Failed ${this.failureCount}/${this.failureThreshold} consecutive calls.`
|
|
5718
|
+
);
|
|
5719
|
+
}
|
|
5720
|
+
if (this.state === "half-open") {
|
|
5721
|
+
this.halfOpenCalls++;
|
|
5722
|
+
}
|
|
5723
|
+
try {
|
|
5724
|
+
const result = await fn();
|
|
5725
|
+
this.record(true);
|
|
5726
|
+
return result;
|
|
5727
|
+
} catch (err) {
|
|
5728
|
+
this.record(false);
|
|
5729
|
+
throw err;
|
|
5730
|
+
}
|
|
5731
|
+
}
|
|
5732
|
+
getState() {
|
|
5733
|
+
return this.state;
|
|
5734
|
+
}
|
|
5735
|
+
getFailureCount() {
|
|
5736
|
+
return this.failureCount;
|
|
5737
|
+
}
|
|
5738
|
+
reset() {
|
|
5739
|
+
this.state = "closed";
|
|
5740
|
+
this.failureCount = 0;
|
|
5741
|
+
this.successCount = 0;
|
|
5742
|
+
this.lastFailureAt = 0;
|
|
5743
|
+
this.halfOpenCalls = 0;
|
|
5744
|
+
}
|
|
5745
|
+
};
|
|
5746
|
+
|
|
5652
5747
|
// src/core/BatchProcessor.ts
|
|
5653
5748
|
function isTransientError(error) {
|
|
5654
5749
|
if (!(error instanceof Error)) return false;
|
|
@@ -5672,7 +5767,34 @@ function calculateBackoffDelay(attempt, initialDelayMs, maxDelayMs, multiplier)
|
|
|
5672
5767
|
function sleep(ms) {
|
|
5673
5768
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
5674
5769
|
}
|
|
5675
|
-
var
|
|
5770
|
+
var _BatchProcessor = class _BatchProcessor {
|
|
5771
|
+
/**
|
|
5772
|
+
* Execute a processor call through the circuit breaker.
|
|
5773
|
+
* Only transient failures count toward opening the circuit.
|
|
5774
|
+
*/
|
|
5775
|
+
static async executeWithCircuitBreaker(processor) {
|
|
5776
|
+
if (!this.cb.canExecute()) {
|
|
5777
|
+
const retryAfterSec = Math.ceil(
|
|
5778
|
+
Math.max(0, 3e4 - (Date.now() - this.cb.lastFailureAt || 0)) / 1e3
|
|
5779
|
+
);
|
|
5780
|
+
throw new Error(
|
|
5781
|
+
`[BatchProcessor] Circuit breaker is open. Try again in ${retryAfterSec}s.`
|
|
5782
|
+
);
|
|
5783
|
+
}
|
|
5784
|
+
if (this.cb.state === "half-open") {
|
|
5785
|
+
this.cb.halfOpenCalls++;
|
|
5786
|
+
}
|
|
5787
|
+
try {
|
|
5788
|
+
const result = await processor();
|
|
5789
|
+
this.cb.record(true);
|
|
5790
|
+
return result;
|
|
5791
|
+
} catch (err) {
|
|
5792
|
+
if (isTransientError(err)) {
|
|
5793
|
+
this.cb.record(false);
|
|
5794
|
+
}
|
|
5795
|
+
throw err;
|
|
5796
|
+
}
|
|
5797
|
+
}
|
|
5676
5798
|
/**
|
|
5677
5799
|
* Processes an array of items in configurable batches with retry logic.
|
|
5678
5800
|
*
|
|
@@ -5713,7 +5835,7 @@ var BatchProcessor = class {
|
|
|
5713
5835
|
let lastError;
|
|
5714
5836
|
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
5715
5837
|
try {
|
|
5716
|
-
const result = await processor(batch);
|
|
5838
|
+
const result = await _BatchProcessor.executeWithCircuitBreaker(() => processor(batch));
|
|
5717
5839
|
results.push(result);
|
|
5718
5840
|
success = true;
|
|
5719
5841
|
break;
|
|
@@ -5771,7 +5893,7 @@ ${errorMessages}`
|
|
|
5771
5893
|
let lastError;
|
|
5772
5894
|
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
5773
5895
|
try {
|
|
5774
|
-
const result = await processor(item);
|
|
5896
|
+
const result = await _BatchProcessor.executeWithCircuitBreaker(() => processor(item));
|
|
5775
5897
|
results.push(result);
|
|
5776
5898
|
success = true;
|
|
5777
5899
|
break;
|
|
@@ -5844,7 +5966,7 @@ ${errorMessages}`
|
|
|
5844
5966
|
}));
|
|
5845
5967
|
const chunkPromises = chunk.map(async ({ item, originalIndex }) => {
|
|
5846
5968
|
try {
|
|
5847
|
-
const result = await processor(item);
|
|
5969
|
+
const result = await _BatchProcessor.executeWithCircuitBreaker(() => processor(item));
|
|
5848
5970
|
return { success: true, result, index: originalIndex };
|
|
5849
5971
|
} catch (err) {
|
|
5850
5972
|
const error = err instanceof Error ? err : new Error(String(err));
|
|
@@ -5872,6 +5994,12 @@ ${errorMessages}`
|
|
|
5872
5994
|
return { results, errors, totalProcessed, totalFailed };
|
|
5873
5995
|
}
|
|
5874
5996
|
};
|
|
5997
|
+
_BatchProcessor.cb = new CircuitBreaker({
|
|
5998
|
+
failureThreshold: 5,
|
|
5999
|
+
resetTimeoutMs: 3e4,
|
|
6000
|
+
halfOpenMaxCalls: 1
|
|
6001
|
+
});
|
|
6002
|
+
var BatchProcessor = _BatchProcessor;
|
|
5875
6003
|
|
|
5876
6004
|
// src/config/EmbeddingStrategy.ts
|
|
5877
6005
|
var EmbeddingStrategyResolver = class {
|
|
@@ -5969,7 +6097,7 @@ var QueryProcessor = class {
|
|
|
5969
6097
|
* @param validFields Optional list of known filterable fields to look for
|
|
5970
6098
|
*/
|
|
5971
6099
|
static extractQueryFieldHints(question, validFields = []) {
|
|
5972
|
-
var
|
|
6100
|
+
var _a3, _b, _c, _d;
|
|
5973
6101
|
if (!question.trim()) return [];
|
|
5974
6102
|
const hints = /* @__PURE__ */ new Map();
|
|
5975
6103
|
const addHint = (value, field) => {
|
|
@@ -6049,7 +6177,7 @@ var QueryProcessor = class {
|
|
|
6049
6177
|
];
|
|
6050
6178
|
for (const p of universalPatterns) {
|
|
6051
6179
|
for (const match of question.matchAll(p.regex)) {
|
|
6052
|
-
const val = p.group ? (
|
|
6180
|
+
const val = p.group ? (_a3 = match[p.group]) != null ? _a3 : match[0] : match[0];
|
|
6053
6181
|
if (!val) continue;
|
|
6054
6182
|
if (p.field) addHint(val, p.field);
|
|
6055
6183
|
else addHint(val);
|
|
@@ -6273,11 +6401,11 @@ var LLMRouter = class {
|
|
|
6273
6401
|
* When provided it is used directly as the 'default' role without re-constructing.
|
|
6274
6402
|
*/
|
|
6275
6403
|
async initialize(prebuiltDefault) {
|
|
6276
|
-
var
|
|
6404
|
+
var _a3;
|
|
6277
6405
|
const defaultModel = prebuiltDefault != null ? prebuiltDefault : LLMFactory.create(this.config.llm, this.config.embedding);
|
|
6278
6406
|
this.models.set("default", defaultModel);
|
|
6279
6407
|
const envFastModel = process.env.FAST_LLM_MODEL;
|
|
6280
|
-
const providerFastDefault = (
|
|
6408
|
+
const providerFastDefault = (_a3 = FAST_MODEL_DEFAULTS[this.config.llm.provider]) != null ? _a3 : "";
|
|
6281
6409
|
const fastModelName = envFastModel || providerFastDefault;
|
|
6282
6410
|
if (fastModelName && fastModelName !== this.config.llm.model) {
|
|
6283
6411
|
console.log(`[LLMRouter] Fast role \u2192 provider="${this.config.llm.provider}" model="${fastModelName}"`);
|
|
@@ -6296,8 +6424,8 @@ var LLMRouter = class {
|
|
|
6296
6424
|
* Falls back to 'default' if the requested role is not registered.
|
|
6297
6425
|
*/
|
|
6298
6426
|
get(role) {
|
|
6299
|
-
var
|
|
6300
|
-
const provider = (
|
|
6427
|
+
var _a3;
|
|
6428
|
+
const provider = (_a3 = this.models.get(role)) != null ? _a3 : this.models.get("default");
|
|
6301
6429
|
if (!provider) {
|
|
6302
6430
|
throw new Error(`[LLMRouter] No provider registered for role: "${role}". Did you call initialize()?`);
|
|
6303
6431
|
}
|
|
@@ -6383,8 +6511,8 @@ var IntentClassifier = class {
|
|
|
6383
6511
|
numericFieldCount = numericKeys.size;
|
|
6384
6512
|
categoricalFieldCount = catKeys.size;
|
|
6385
6513
|
if (productKeyMatches >= 2 || docs.some((d) => {
|
|
6386
|
-
var
|
|
6387
|
-
return ((
|
|
6514
|
+
var _a3, _b;
|
|
6515
|
+
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");
|
|
6388
6516
|
})) {
|
|
6389
6517
|
isProductLike = true;
|
|
6390
6518
|
}
|
|
@@ -6666,8 +6794,8 @@ var TextRendererStrategy = class {
|
|
|
6666
6794
|
}
|
|
6667
6795
|
const docs = Array.isArray(data) ? data : [];
|
|
6668
6796
|
const text = docs.map((d) => {
|
|
6669
|
-
var
|
|
6670
|
-
return (
|
|
6797
|
+
var _a3;
|
|
6798
|
+
return (_a3 = d == null ? void 0 : d.content) != null ? _a3 : "";
|
|
6671
6799
|
}).join("\n\n");
|
|
6672
6800
|
return { type: "text", title, data: { content: text || "No detailed content available." } };
|
|
6673
6801
|
}
|
|
@@ -6810,9 +6938,9 @@ var LRUDecisionCache = class {
|
|
|
6810
6938
|
this.maxSize = maxSize;
|
|
6811
6939
|
}
|
|
6812
6940
|
generateKey(context) {
|
|
6813
|
-
var
|
|
6941
|
+
var _a3, _b;
|
|
6814
6942
|
const q = (context.userQuery || "").toLowerCase().trim();
|
|
6815
|
-
const docCount = (_b = (
|
|
6943
|
+
const docCount = (_b = (_a3 = context.retrievedDocuments) == null ? void 0 : _a3.length) != null ? _b : 0;
|
|
6816
6944
|
return `${q}::docs:${docCount}`;
|
|
6817
6945
|
}
|
|
6818
6946
|
get(context) {
|
|
@@ -6913,7 +7041,7 @@ var UITransformer = class _UITransformer {
|
|
|
6913
7041
|
* Prefer `analyzeAndDecide()` in production.
|
|
6914
7042
|
*/
|
|
6915
7043
|
static transform(userQuery, retrievedData, config, trainedSchema, intent) {
|
|
6916
|
-
var
|
|
7044
|
+
var _a3, _b, _c;
|
|
6917
7045
|
if (!retrievedData || retrievedData.length === 0) {
|
|
6918
7046
|
return this.createTextResponse("No data available", "No relevant data found for your query.");
|
|
6919
7047
|
}
|
|
@@ -6933,7 +7061,7 @@ var UITransformer = class _UITransformer {
|
|
|
6933
7061
|
return this.transformToBarChart(filteredData, profile, userQuery, resolvedIntent.visualizationHint === "ranking");
|
|
6934
7062
|
}
|
|
6935
7063
|
if (resolvedIntent.visualizationHint === "distribution") {
|
|
6936
|
-
return (
|
|
7064
|
+
return (_a3 = this.transformToHistogram(profile, userQuery)) != null ? _a3 : this.transformToBarChart(filteredData, profile, userQuery);
|
|
6937
7065
|
}
|
|
6938
7066
|
if (resolvedIntent.visualizationHint === "correlation") {
|
|
6939
7067
|
return (_b = this.transformToScatterPlot(profile, userQuery)) != null ? _b : this.transformToBarChart(filteredData, profile, userQuery);
|
|
@@ -7266,11 +7394,11 @@ ${schemaProfileText}` : ""}`;
|
|
|
7266
7394
|
};
|
|
7267
7395
|
}
|
|
7268
7396
|
static transformToPieChart(data, profile, query = "") {
|
|
7269
|
-
var
|
|
7397
|
+
var _a3;
|
|
7270
7398
|
const dimension = profile ? this.selectDimensionField(profile, query) : void 0;
|
|
7271
7399
|
const categories = dimension ? Array.from(new Set(profile.records.map((record) => {
|
|
7272
|
-
var
|
|
7273
|
-
return String((
|
|
7400
|
+
var _a4;
|
|
7401
|
+
return String((_a4 = record.fields[dimension.key]) != null ? _a4 : "");
|
|
7274
7402
|
}).filter(Boolean))) : this.detectCategories(data);
|
|
7275
7403
|
if (categories.length === 0) return null;
|
|
7276
7404
|
const categoryData = dimension && profile ? this.aggregateProfileByDimension(profile, dimension.key) : this.aggregateByCategory(data, categories);
|
|
@@ -7280,7 +7408,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7280
7408
|
});
|
|
7281
7409
|
return {
|
|
7282
7410
|
type: "pie_chart",
|
|
7283
|
-
title: `Distribution by ${(
|
|
7411
|
+
title: `Distribution by ${(_a3 = dimension == null ? void 0 : dimension.label) != null ? _a3 : "Category"}`,
|
|
7284
7412
|
description: `Showing breakdown across ${pieData.length} categories`,
|
|
7285
7413
|
data: pieData
|
|
7286
7414
|
};
|
|
@@ -7290,8 +7418,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7290
7418
|
const valueField = profile.numericFields[0];
|
|
7291
7419
|
const buckets = /* @__PURE__ */ new Map();
|
|
7292
7420
|
profile.records.forEach((record) => {
|
|
7293
|
-
var
|
|
7294
|
-
const timestamp = String((
|
|
7421
|
+
var _a3, _b, _c;
|
|
7422
|
+
const timestamp = String((_a3 = record.fields[dateField.key]) != null ? _a3 : "");
|
|
7295
7423
|
const value = (_b = this.toFiniteNumber(record.fields[valueField.key])) != null ? _b : 0;
|
|
7296
7424
|
buckets.set(timestamp, ((_c = buckets.get(timestamp)) != null ? _c : 0) + value);
|
|
7297
7425
|
});
|
|
@@ -7304,23 +7432,23 @@ ${schemaProfileText}` : ""}`;
|
|
|
7304
7432
|
};
|
|
7305
7433
|
}
|
|
7306
7434
|
static transformToBarChart(data, profile, query = "", horizontal = false) {
|
|
7307
|
-
var
|
|
7435
|
+
var _a3;
|
|
7308
7436
|
const dimension = profile ? this.selectDimensionField(profile, query) : void 0;
|
|
7309
7437
|
const measure = profile ? this.selectNumericField(profile, query) : void 0;
|
|
7310
7438
|
const aggregate = dimension && profile ? this.aggregateProfileByDimension(profile, dimension.key, measure == null ? void 0 : measure.key) : this.aggregateByCategory(data, this.detectCategories(data));
|
|
7311
7439
|
const barData = Object.entries(aggregate).map(([category, value]) => ({ category, value: Number(value) })).sort((a, b) => horizontal ? b.value - a.value : 0).slice(0, 12);
|
|
7312
7440
|
const fallbackData = barData.length > 0 ? barData : data.slice(0, 12).map((item, index) => {
|
|
7313
|
-
var
|
|
7441
|
+
var _a4, _b, _c, _d, _e;
|
|
7314
7442
|
const meta = item.metadata || {};
|
|
7315
7443
|
const label = String(
|
|
7316
|
-
(_c = (_b = (
|
|
7444
|
+
(_c = (_b = (_a4 = this.getDynamicVal(meta, "name")) != null ? _a4 : meta.label) != null ? _b : meta.title) != null ? _c : `Result ${index + 1}`
|
|
7317
7445
|
);
|
|
7318
7446
|
const value = (_e = (_d = this.extractNumericValue(meta)) != null ? _d : item.score) != null ? _e : 0;
|
|
7319
7447
|
return { category: label, value: Number(value) };
|
|
7320
7448
|
});
|
|
7321
7449
|
return {
|
|
7322
7450
|
type: horizontal ? "horizontal_bar" : "bar_chart",
|
|
7323
|
-
title: dimension ? `${(
|
|
7451
|
+
title: dimension ? `${(_a3 = measure == null ? void 0 : measure.label) != null ? _a3 : "Count"} by ${dimension.label}` : "Comparison",
|
|
7324
7452
|
description: `Showing ${fallbackData.length} comparable values`,
|
|
7325
7453
|
data: fallbackData
|
|
7326
7454
|
};
|
|
@@ -7355,11 +7483,11 @@ ${schemaProfileText}` : ""}`;
|
|
|
7355
7483
|
if (fields.length < 2) return null;
|
|
7356
7484
|
const [xField, yField] = fields;
|
|
7357
7485
|
const points = profile.records.map((record) => {
|
|
7358
|
-
var
|
|
7486
|
+
var _a3;
|
|
7359
7487
|
const x = this.toFiniteNumber(record.fields[xField.key]);
|
|
7360
7488
|
const y = this.toFiniteNumber(record.fields[yField.key]);
|
|
7361
7489
|
if (x === null || y === null) return null;
|
|
7362
|
-
return { x, y, label: String((
|
|
7490
|
+
return { x, y, label: String((_a3 = this.getRecordLabel(record)) != null ? _a3 : record.id) };
|
|
7363
7491
|
}).filter((point) => point !== null).slice(0, 100);
|
|
7364
7492
|
if (points.length === 0) return null;
|
|
7365
7493
|
return {
|
|
@@ -7389,9 +7517,9 @@ ${schemaProfileText}` : ""}`;
|
|
|
7389
7517
|
static transformToRadarChart(data) {
|
|
7390
7518
|
const attributeMap = {};
|
|
7391
7519
|
data.forEach((item) => {
|
|
7392
|
-
var
|
|
7520
|
+
var _a3, _b, _c;
|
|
7393
7521
|
const meta = item.metadata || {};
|
|
7394
|
-
const seriesName = String((_c = (_b = (
|
|
7522
|
+
const seriesName = String((_c = (_b = (_a3 = meta.name) != null ? _a3 : meta.product) != null ? _b : item.id) != null ? _c : "Item");
|
|
7395
7523
|
Object.entries(meta).forEach(([key, val]) => {
|
|
7396
7524
|
if (typeof val === "number" && !["price", "id"].includes(key.toLowerCase())) {
|
|
7397
7525
|
if (!attributeMap[key]) attributeMap[key] = {};
|
|
@@ -7407,8 +7535,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7407
7535
|
title: "Product Comparison",
|
|
7408
7536
|
description: `Comparing ${data.length} items across ${radarData.length} attributes`,
|
|
7409
7537
|
data: radarData.length > 0 ? radarData : data.map((d) => {
|
|
7410
|
-
var
|
|
7411
|
-
return { attribute: ((
|
|
7538
|
+
var _a3;
|
|
7539
|
+
return { attribute: ((_a3 = d == null ? void 0 : d.content) != null ? _a3 : "").substring(0, 40) };
|
|
7412
7540
|
})
|
|
7413
7541
|
};
|
|
7414
7542
|
}
|
|
@@ -7427,8 +7555,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7427
7555
|
return this.createTextResponse(
|
|
7428
7556
|
"Retrieved Context",
|
|
7429
7557
|
data.map((item) => {
|
|
7430
|
-
var
|
|
7431
|
-
return (
|
|
7558
|
+
var _a3;
|
|
7559
|
+
return (_a3 = item == null ? void 0 : item.content) != null ? _a3 : "";
|
|
7432
7560
|
}).join("\n\n"),
|
|
7433
7561
|
`Found ${data.length} relevant results`
|
|
7434
7562
|
);
|
|
@@ -7479,11 +7607,11 @@ ${schemaProfileText}` : ""}`;
|
|
|
7479
7607
|
return null;
|
|
7480
7608
|
}
|
|
7481
7609
|
static normalizeTransformation(payload) {
|
|
7482
|
-
var
|
|
7610
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j;
|
|
7483
7611
|
if (!payload || typeof payload !== "object") return null;
|
|
7484
7612
|
const p = payload;
|
|
7485
7613
|
const type = this.normalizeVisualizationType(
|
|
7486
|
-
String((_c = (_b = (
|
|
7614
|
+
String((_c = (_b = (_a3 = p.type) != null ? _a3 : p.view) != null ? _b : p.chartType) != null ? _c : "")
|
|
7487
7615
|
);
|
|
7488
7616
|
if (!type) return null;
|
|
7489
7617
|
const title = String((_e = (_d = p.title) != null ? _d : p.heading) != null ? _e : "Visualization");
|
|
@@ -7494,7 +7622,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7494
7622
|
return this.validateTransformation(transformation) ? transformation : null;
|
|
7495
7623
|
}
|
|
7496
7624
|
static normalizeVisualizationType(type) {
|
|
7497
|
-
var
|
|
7625
|
+
var _a3;
|
|
7498
7626
|
const mapping = {
|
|
7499
7627
|
pie: "pie_chart",
|
|
7500
7628
|
pie_chart: "pie_chart",
|
|
@@ -7522,7 +7650,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7522
7650
|
product_carousel: "product_carousel",
|
|
7523
7651
|
carousel: "carousel"
|
|
7524
7652
|
};
|
|
7525
|
-
return (
|
|
7653
|
+
return (_a3 = mapping[type.toLowerCase()]) != null ? _a3 : null;
|
|
7526
7654
|
}
|
|
7527
7655
|
static validateTransformation(t) {
|
|
7528
7656
|
const { type, data } = t;
|
|
@@ -7638,7 +7766,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7638
7766
|
}
|
|
7639
7767
|
static profileData(data) {
|
|
7640
7768
|
const records = (data || []).filter((item) => Boolean(item && typeof item === "object")).map((item) => {
|
|
7641
|
-
var
|
|
7769
|
+
var _a3, _b;
|
|
7642
7770
|
const fields2 = {};
|
|
7643
7771
|
Object.entries(item.metadata || {}).forEach(([key, value]) => {
|
|
7644
7772
|
const primitive = this.toPrimitive(value);
|
|
@@ -7647,7 +7775,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7647
7775
|
if (!fields2.content && item.content) fields2.content = item.content.substring(0, 500);
|
|
7648
7776
|
return {
|
|
7649
7777
|
id: item.id,
|
|
7650
|
-
content: (
|
|
7778
|
+
content: (_a3 = item.content) != null ? _a3 : "",
|
|
7651
7779
|
score: (_b = item.score) != null ? _b : 0,
|
|
7652
7780
|
fields: fields2,
|
|
7653
7781
|
source: item
|
|
@@ -7728,16 +7856,16 @@ ${schemaProfileText}` : ""}`;
|
|
|
7728
7856
|
return null;
|
|
7729
7857
|
}
|
|
7730
7858
|
static selectDimensionField(profile, query) {
|
|
7731
|
-
var
|
|
7859
|
+
var _a3, _b;
|
|
7732
7860
|
const productCategory = profile.categoricalFields.find(
|
|
7733
7861
|
(field) => /category|department|collection|type|group|segment|region|country|state|city/i.test(field.key)
|
|
7734
7862
|
);
|
|
7735
7863
|
const ranked = this.rankFieldsByQuery(profile.categoricalFields, query);
|
|
7736
|
-
return (_b = (
|
|
7864
|
+
return (_b = (_a3 = ranked[0]) != null ? _a3 : productCategory) != null ? _b : profile.categoricalFields[0];
|
|
7737
7865
|
}
|
|
7738
7866
|
static selectNumericField(profile, query) {
|
|
7739
|
-
var
|
|
7740
|
-
return (
|
|
7867
|
+
var _a3;
|
|
7868
|
+
return (_a3 = this.rankFieldsByQuery(profile.numericFields, query)[0]) != null ? _a3 : profile.numericFields[0];
|
|
7741
7869
|
}
|
|
7742
7870
|
static rankFieldsByQuery(fields, query) {
|
|
7743
7871
|
const q = query.toLowerCase();
|
|
@@ -7766,8 +7894,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7766
7894
|
static aggregateProfileByDimension(profile, dimensionKey, measureKey) {
|
|
7767
7895
|
const result = {};
|
|
7768
7896
|
profile.records.forEach((record) => {
|
|
7769
|
-
var
|
|
7770
|
-
const category = String((
|
|
7897
|
+
var _a3, _b, _c;
|
|
7898
|
+
const category = String((_a3 = record.fields[dimensionKey]) != null ? _a3 : "Other").trim() || "Other";
|
|
7771
7899
|
const value = measureKey ? (_b = this.toFiniteNumber(record.fields[measureKey])) != null ? _b : 0 : 1;
|
|
7772
7900
|
result[category] = ((_c = result[category]) != null ? _c : 0) + value;
|
|
7773
7901
|
});
|
|
@@ -7847,8 +7975,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7847
7975
|
static aggregateByCategory(data, categories) {
|
|
7848
7976
|
const result = Object.fromEntries(categories.map((c) => [c, 0]));
|
|
7849
7977
|
data.forEach((item) => {
|
|
7850
|
-
var
|
|
7851
|
-
const cat = (
|
|
7978
|
+
var _a3;
|
|
7979
|
+
const cat = (_a3 = this.getProductCategory(item)) != null ? _a3 : "Other";
|
|
7852
7980
|
if (Object.prototype.hasOwnProperty.call(result, cat)) result[cat]++;
|
|
7853
7981
|
else result["Other"] = (result["Other"] || 0) + 1;
|
|
7854
7982
|
});
|
|
@@ -7856,17 +7984,17 @@ ${schemaProfileText}` : ""}`;
|
|
|
7856
7984
|
}
|
|
7857
7985
|
static extractTimeSeriesData(data) {
|
|
7858
7986
|
return data.map((item) => {
|
|
7859
|
-
var
|
|
7987
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
7860
7988
|
const meta = item.metadata || {};
|
|
7861
7989
|
return {
|
|
7862
|
-
timestamp: (_b = (
|
|
7990
|
+
timestamp: (_b = (_a3 = meta.timestamp) != null ? _a3 : meta.date) != null ? _b : (/* @__PURE__ */ new Date()).toISOString(),
|
|
7863
7991
|
value: (_d = (_c = meta.value) != null ? _c : item.score) != null ? _d : 0,
|
|
7864
7992
|
label: (_f = meta.label) != null ? _f : ((_e = item == null ? void 0 : item.content) != null ? _e : "").substring(0, 50)
|
|
7865
7993
|
};
|
|
7866
7994
|
});
|
|
7867
7995
|
}
|
|
7868
7996
|
static extractNumericValue(meta) {
|
|
7869
|
-
var
|
|
7997
|
+
var _a3;
|
|
7870
7998
|
const preferredKeys = [
|
|
7871
7999
|
"value",
|
|
7872
8000
|
"count",
|
|
@@ -7881,7 +8009,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7881
8009
|
"price"
|
|
7882
8010
|
];
|
|
7883
8011
|
for (const key of preferredKeys) {
|
|
7884
|
-
const raw = (
|
|
8012
|
+
const raw = (_a3 = resolveMetadataValue(meta, key)) != null ? _a3 : meta[key];
|
|
7885
8013
|
const value = typeof raw === "number" ? raw : Number(String(raw != null ? raw : "").replace(/[$,% ,]/g, ""));
|
|
7886
8014
|
if (Number.isFinite(value)) return value;
|
|
7887
8015
|
}
|
|
@@ -7976,8 +8104,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7976
8104
|
}, query.includes(normalizedField) ? 3 : 0);
|
|
7977
8105
|
}
|
|
7978
8106
|
static resolveTableCellValue(item, column) {
|
|
7979
|
-
var
|
|
7980
|
-
if (column === "Content") return ((
|
|
8107
|
+
var _a3, _b, _c;
|
|
8108
|
+
if (column === "Content") return ((_a3 = item == null ? void 0 : item.content) != null ? _a3 : "").substring(0, 100);
|
|
7981
8109
|
const meta = item.metadata || {};
|
|
7982
8110
|
const normalizedColumn = this.normalizeComparableField(column);
|
|
7983
8111
|
const exactMetadata = Object.entries(meta).find(
|
|
@@ -8029,8 +8157,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
8029
8157
|
let inStock = 0;
|
|
8030
8158
|
let outOfStock = 0;
|
|
8031
8159
|
data.forEach((d) => {
|
|
8032
|
-
var
|
|
8033
|
-
const cat = (
|
|
8160
|
+
var _a3, _b;
|
|
8161
|
+
const cat = (_a3 = this.getProductCategory(d)) != null ? _a3 : "Other";
|
|
8034
8162
|
if (cat === category) {
|
|
8035
8163
|
const quantity = (_b = this.extractStockQuantity(d)) != null ? _b : 1;
|
|
8036
8164
|
if (this.determineStockStatus(d)) inStock += quantity;
|
|
@@ -8076,9 +8204,9 @@ ${schemaProfileText}` : ""}`;
|
|
|
8076
8204
|
}
|
|
8077
8205
|
// ─── Product Extraction ───────────────────────────────────────────────────
|
|
8078
8206
|
static getDynamicVal(meta, uiKey, config, trainedSchema) {
|
|
8079
|
-
var
|
|
8207
|
+
var _a3;
|
|
8080
8208
|
if (!meta) return void 0;
|
|
8081
|
-
const mapping = (
|
|
8209
|
+
const mapping = (_a3 = config == null ? void 0 : config.rag) == null ? void 0 : _a3.uiMapping;
|
|
8082
8210
|
if ((mapping == null ? void 0 : mapping[uiKey]) && meta[mapping[uiKey]] !== void 0) return meta[mapping[uiKey]];
|
|
8083
8211
|
if (trainedSchema && typeof trainedSchema === "object") {
|
|
8084
8212
|
const trainedKey = trainedSchema[uiKey];
|
|
@@ -8087,7 +8215,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
8087
8215
|
return resolveMetadataValue(meta, uiKey);
|
|
8088
8216
|
}
|
|
8089
8217
|
static extractProductInfo(item, config, trainedSchema) {
|
|
8090
|
-
var
|
|
8218
|
+
var _a3, _b;
|
|
8091
8219
|
if (!item) return null;
|
|
8092
8220
|
const meta = item.metadata || {};
|
|
8093
8221
|
const content = item.content || "";
|
|
@@ -8095,7 +8223,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
8095
8223
|
const price = this.getDynamicVal(meta, "price", config, trainedSchema);
|
|
8096
8224
|
const brand = this.getDynamicVal(meta, "brand", config, trainedSchema);
|
|
8097
8225
|
const description = this.cleanProductDescription(
|
|
8098
|
-
(
|
|
8226
|
+
(_a3 = this.extractProductDescriptionFromContent(content)) != null ? _a3 : this.getProductDescriptionValue(meta, config, trainedSchema)
|
|
8099
8227
|
);
|
|
8100
8228
|
if (name || this.isProductData(item)) {
|
|
8101
8229
|
let finalName = name ? String(name) : void 0;
|
|
@@ -8230,10 +8358,10 @@ RULES:
|
|
|
8230
8358
|
}
|
|
8231
8359
|
static buildContextSummary(sources, maxChars = 6e3) {
|
|
8232
8360
|
const items = (sources || []).filter(Boolean).map((s, i) => {
|
|
8233
|
-
var
|
|
8361
|
+
var _a3, _b, _c, _d;
|
|
8234
8362
|
return {
|
|
8235
8363
|
index: i + 1,
|
|
8236
|
-
content: (_b = (
|
|
8364
|
+
content: (_b = (_a3 = s == null ? void 0 : s.content) == null ? void 0 : _a3.substring(0, 400)) != null ? _b : "",
|
|
8237
8365
|
metadata: (_c = s == null ? void 0 : s.metadata) != null ? _c : {},
|
|
8238
8366
|
score: (_d = s == null ? void 0 : s.score) != null ? _d : 0
|
|
8239
8367
|
};
|
|
@@ -8273,7 +8401,7 @@ var SchemaMapper = class {
|
|
|
8273
8401
|
return promise;
|
|
8274
8402
|
}
|
|
8275
8403
|
static async _doTrain(llm, cacheKey, keys) {
|
|
8276
|
-
var
|
|
8404
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
|
|
8277
8405
|
console.log(`[SchemaMapper] \u{1F9E0} Training on new schema keys: ${keys.join(", ")}`);
|
|
8278
8406
|
const propertyList = Object.entries(this.TARGET_PROPERTIES).map(([prop, desc]) => `- ${prop} (${desc})`).join("\n");
|
|
8279
8407
|
const messages = [
|
|
@@ -8289,7 +8417,7 @@ Return a JSON object like {"name":"Title","price":"Price",...}. Omit unmapped pr
|
|
|
8289
8417
|
}
|
|
8290
8418
|
];
|
|
8291
8419
|
try {
|
|
8292
|
-
const baseUrl = (
|
|
8420
|
+
const baseUrl = (_a3 = llm == null ? void 0 : llm.baseUrl) != null ? _a3 : "";
|
|
8293
8421
|
const apiKey = (_b = llm == null ? void 0 : llm.apiKey) != null ? _b : "";
|
|
8294
8422
|
const model = (_c = llm == null ? void 0 : llm.model) != null ? _c : "llama-3.1-8b-instant";
|
|
8295
8423
|
let responseText;
|
|
@@ -8464,9 +8592,9 @@ var Pipeline = class {
|
|
|
8464
8592
|
this.initialised = false;
|
|
8465
8593
|
/** Namespace-specific static cold context cache for CAG */
|
|
8466
8594
|
this.coldContexts = /* @__PURE__ */ new Map();
|
|
8467
|
-
var
|
|
8595
|
+
var _a3, _b, _c, _d, _e;
|
|
8468
8596
|
this.chunker = new DocumentChunker(
|
|
8469
|
-
(_b = (
|
|
8597
|
+
(_b = (_a3 = config.rag) == null ? void 0 : _a3.chunkSize) != null ? _b : 1e3,
|
|
8470
8598
|
(_d = (_c = config.rag) == null ? void 0 : _c.chunkOverlap) != null ? _d : 200
|
|
8471
8599
|
);
|
|
8472
8600
|
if (((_e = config.rag) == null ? void 0 : _e.chunkingStrategy) === "llamaindex") {
|
|
@@ -8482,7 +8610,7 @@ var Pipeline = class {
|
|
|
8482
8610
|
return this.initialised ? this.llmProvider : void 0;
|
|
8483
8611
|
}
|
|
8484
8612
|
async initialize() {
|
|
8485
|
-
var
|
|
8613
|
+
var _a3, _b, _c, _d;
|
|
8486
8614
|
if (this.initialised) return;
|
|
8487
8615
|
const chartInstruction = `You are a helpful assistant. Use the provided context to answer questions accurately.
|
|
8488
8616
|
|
|
@@ -8525,7 +8653,7 @@ var Pipeline = class {
|
|
|
8525
8653
|
this.entityExtractor = new EntityExtractor(this.llmProvider);
|
|
8526
8654
|
}
|
|
8527
8655
|
await this.vectorDB.initialize();
|
|
8528
|
-
if (((
|
|
8656
|
+
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) {
|
|
8529
8657
|
this.mcpRegistry = new MCPRegistry(this.config.mcpServers || []);
|
|
8530
8658
|
this.multiAgentCoordinator = new MultiAgentCoordinator({
|
|
8531
8659
|
llmProvider: this.llmProvider,
|
|
@@ -8543,8 +8671,8 @@ var Pipeline = class {
|
|
|
8543
8671
|
this.initialised = true;
|
|
8544
8672
|
}
|
|
8545
8673
|
async loadColdContext(ns) {
|
|
8546
|
-
var
|
|
8547
|
-
const cagConfig = (
|
|
8674
|
+
var _a3, _b;
|
|
8675
|
+
const cagConfig = (_a3 = this.config.rag) == null ? void 0 : _a3.cag;
|
|
8548
8676
|
if (!cagConfig || !cagConfig.enabled) return;
|
|
8549
8677
|
try {
|
|
8550
8678
|
const coldNs = cagConfig.coldNamespace || ns;
|
|
@@ -8597,12 +8725,12 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8597
8725
|
}
|
|
8598
8726
|
/** Step 1: Chunk the document content. */
|
|
8599
8727
|
async prepareChunks(doc) {
|
|
8600
|
-
var
|
|
8728
|
+
var _a3, _b;
|
|
8601
8729
|
if (this.llamaIngestor) {
|
|
8602
8730
|
return this.llamaIngestor.chunk(doc.content, {
|
|
8603
8731
|
docId: doc.docId,
|
|
8604
8732
|
metadata: doc.metadata,
|
|
8605
|
-
chunkSize: (
|
|
8733
|
+
chunkSize: (_a3 = this.config.rag) == null ? void 0 : _a3.chunkSize,
|
|
8606
8734
|
chunkOverlap: (_b = this.config.rag) == null ? void 0 : _b.chunkOverlap
|
|
8607
8735
|
});
|
|
8608
8736
|
}
|
|
@@ -8700,9 +8828,9 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8700
8828
|
return { reply, sources };
|
|
8701
8829
|
}
|
|
8702
8830
|
async ask(question, history = [], namespace) {
|
|
8703
|
-
var
|
|
8831
|
+
var _a3, _b;
|
|
8704
8832
|
await this.initialize();
|
|
8705
|
-
if ((((
|
|
8833
|
+
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) {
|
|
8706
8834
|
return await this.multiAgentCoordinator.run(question, history);
|
|
8707
8835
|
}
|
|
8708
8836
|
const stream = this.askStream(question, history, namespace);
|
|
@@ -8737,9 +8865,9 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8737
8865
|
}
|
|
8738
8866
|
askStream(_0) {
|
|
8739
8867
|
return __asyncGenerator(this, arguments, function* (question, history = [], namespace) {
|
|
8740
|
-
var
|
|
8868
|
+
var _a3, _b;
|
|
8741
8869
|
yield new __await(this.initialize());
|
|
8742
|
-
if ((((
|
|
8870
|
+
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) {
|
|
8743
8871
|
const stream2 = this.multiAgentCoordinator.runStream(question, history);
|
|
8744
8872
|
try {
|
|
8745
8873
|
for (var iter = __forAwait(stream2), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
|
|
@@ -8788,10 +8916,10 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8788
8916
|
*/
|
|
8789
8917
|
askStreamInternal(_0) {
|
|
8790
8918
|
return __asyncGenerator(this, arguments, function* (question, history = [], namespace) {
|
|
8791
|
-
var
|
|
8919
|
+
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;
|
|
8792
8920
|
yield new __await(this.initialize());
|
|
8793
8921
|
const ns = formatNamespace(namespace != null ? namespace : this.config.projectId);
|
|
8794
|
-
const topK = (_b = (
|
|
8922
|
+
const topK = (_b = (_a3 = this.config.rag) == null ? void 0 : _a3.topK) != null ? _b : 5;
|
|
8795
8923
|
const scoreThreshold = (_d = (_c = this.config.rag) == null ? void 0 : _c.scoreThreshold) != null ? _d : 0.3;
|
|
8796
8924
|
const requestId = `req_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
8797
8925
|
const requestStart = performance.now();
|
|
@@ -8840,8 +8968,8 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8840
8968
|
const rerankStart = performance.now();
|
|
8841
8969
|
const structuredSources = this.applyStructuredFilters(rawSources, filter).filter((s) => Boolean(s && typeof s === "object"));
|
|
8842
8970
|
let fullSources = hasNumericPredicates ? structuredSources : structuredSources.filter((m) => {
|
|
8843
|
-
var
|
|
8844
|
-
return ((
|
|
8971
|
+
var _a4;
|
|
8972
|
+
return ((_a4 = m == null ? void 0 : m.score) != null ? _a4 : 0) >= scoreThreshold;
|
|
8845
8973
|
});
|
|
8846
8974
|
const rerankLimit = Math.max(retrievalLimit, fullSources.length);
|
|
8847
8975
|
const useReranking = arch !== "naive" && (arch === "retrieve-and-rerank" || ((_m = this.config.rag) == null ? void 0 : _m.useReranking));
|
|
@@ -8854,13 +8982,13 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8854
8982
|
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]
|
|
8855
8983
|
|
|
8856
8984
|
` + promptSources.map((m, i) => {
|
|
8857
|
-
var
|
|
8985
|
+
var _a4;
|
|
8858
8986
|
return `[Source ${i + 1}]
|
|
8859
|
-
${(
|
|
8987
|
+
${(_a4 = m == null ? void 0 : m.content) != null ? _a4 : ""}`;
|
|
8860
8988
|
}).join("\n\n---\n\n") : "No relevant context found.";
|
|
8861
8989
|
const sources = [...fullSources].filter((s) => Boolean(s && typeof s === "object")).sort((a, b) => {
|
|
8862
|
-
var
|
|
8863
|
-
return ((
|
|
8990
|
+
var _a4, _b2;
|
|
8991
|
+
return ((_a4 = b == null ? void 0 : b.score) != null ? _a4 : 0) - ((_b2 = a == null ? void 0 : a.score) != null ? _b2 : 0);
|
|
8864
8992
|
});
|
|
8865
8993
|
if (graphData && graphData.nodes.length > 0) {
|
|
8866
8994
|
const graphContext = graphData.nodes.map(
|
|
@@ -8888,10 +9016,10 @@ ${context}`;
|
|
|
8888
9016
|
yield {
|
|
8889
9017
|
reply: "",
|
|
8890
9018
|
sources: (sources || []).filter((s) => Boolean(s && typeof s === "object")).map((s) => {
|
|
8891
|
-
var
|
|
9019
|
+
var _a4, _b2, _c2;
|
|
8892
9020
|
return {
|
|
8893
9021
|
id: s.id,
|
|
8894
|
-
score: (
|
|
9022
|
+
score: (_a4 = s.score) != null ? _a4 : 0,
|
|
8895
9023
|
content: (_b2 = s == null ? void 0 : s.content) != null ? _b2 : "",
|
|
8896
9024
|
metadata: (_c2 = s == null ? void 0 : s.metadata) != null ? _c2 : {},
|
|
8897
9025
|
namespace: ns
|
|
@@ -9084,11 +9212,11 @@ ${context}`;
|
|
|
9084
9212
|
systemPrompt,
|
|
9085
9213
|
userPrompt: question + finalRestrictionSuffix,
|
|
9086
9214
|
chunks: (sources || []).filter(Boolean).map((s) => {
|
|
9087
|
-
var
|
|
9215
|
+
var _a4, _b2;
|
|
9088
9216
|
return {
|
|
9089
9217
|
id: s.id,
|
|
9090
9218
|
score: s.score,
|
|
9091
|
-
content: (
|
|
9219
|
+
content: (_a4 = s == null ? void 0 : s.content) != null ? _a4 : "",
|
|
9092
9220
|
metadata: (_b2 = s == null ? void 0 : s.metadata) != null ? _b2 : {},
|
|
9093
9221
|
namespace: ns
|
|
9094
9222
|
};
|
|
@@ -9107,7 +9235,7 @@ ${context}`;
|
|
|
9107
9235
|
const telemetryUrl = ((_B = this.config.telemetry) == null ? void 0 : _B.url) || process.env.TELEMETRY_URL || process.env.NEXT_PUBLIC_TELEMETRY_URL || defaultUrl;
|
|
9108
9236
|
const absoluteUrl = telemetryUrl.startsWith("http") ? telemetryUrl : "https://www.retrivora.com" + (telemetryUrl.startsWith("/") ? telemetryUrl : "/" + telemetryUrl);
|
|
9109
9237
|
(async () => {
|
|
9110
|
-
var
|
|
9238
|
+
var _a4, _b2, _c2, _d2, _e2;
|
|
9111
9239
|
try {
|
|
9112
9240
|
let finalTrace = trace;
|
|
9113
9241
|
if (!awaitHallucination && runHallucination) {
|
|
@@ -9116,7 +9244,7 @@ ${context}`;
|
|
|
9116
9244
|
finalTrace = buildTrace(backgroundScoreResult);
|
|
9117
9245
|
}
|
|
9118
9246
|
}
|
|
9119
|
-
const modelName = (finalTrace == null ? void 0 : finalTrace.model) || ((
|
|
9247
|
+
const modelName = (finalTrace == null ? void 0 : finalTrace.model) || ((_a4 = this.config.llm) == null ? void 0 : _a4.model) || "llama-3.1-8b-instant";
|
|
9120
9248
|
const providerName = (finalTrace == null ? void 0 : finalTrace.provider) || ((_b2 = this.config.llm) == null ? void 0 : _b2.provider) || "groq";
|
|
9121
9249
|
const tokenCount = Number(((_c2 = finalTrace == null ? void 0 : finalTrace.tokens) == null ? void 0 : _c2.totalTokens) || 0);
|
|
9122
9250
|
const costEst = Number(((_d2 = finalTrace == null ? void 0 : finalTrace.tokens) == null ? void 0 : _d2.estimatedCostUsd) || 0);
|
|
@@ -9170,7 +9298,7 @@ ${context}`;
|
|
|
9170
9298
|
* Uses an LRU-bounded embedding cache to avoid re-embedding the same query.
|
|
9171
9299
|
*/
|
|
9172
9300
|
async generateUiTransformation(question, sources, cachedSchema, forceDeterministic = false) {
|
|
9173
|
-
var
|
|
9301
|
+
var _a3;
|
|
9174
9302
|
if (!sources || sources.length === 0) {
|
|
9175
9303
|
return UITransformer.transform(question, sources, this.config, cachedSchema);
|
|
9176
9304
|
}
|
|
@@ -9183,7 +9311,7 @@ ${context}`;
|
|
|
9183
9311
|
{ visualizationHint: "product_browse", recommendedChart: "text", filterInStockOnly: false, wantsExplicitTable: false, isTemporal: false, isComparison: false, language: "en" }
|
|
9184
9312
|
);
|
|
9185
9313
|
}
|
|
9186
|
-
const enableLlmUiTransform = ((
|
|
9314
|
+
const enableLlmUiTransform = ((_a3 = this.config.llm.options) == null ? void 0 : _a3.enableLlmUiTransform) === true;
|
|
9187
9315
|
if (forceDeterministic || !enableLlmUiTransform) {
|
|
9188
9316
|
return UITransformer.transform(question, sources, this.config, cachedSchema);
|
|
9189
9317
|
}
|
|
@@ -9201,15 +9329,15 @@ ${context}`;
|
|
|
9201
9329
|
const value = this.resolveNumericPredicateValue(source, predicate);
|
|
9202
9330
|
return value !== null && this.matchesNumericPredicate(value, predicate);
|
|
9203
9331
|
})).sort((a, b) => {
|
|
9204
|
-
var
|
|
9332
|
+
var _a3, _b;
|
|
9205
9333
|
const primary = predicates[0];
|
|
9206
|
-
const aValue = (
|
|
9334
|
+
const aValue = (_a3 = this.resolveNumericPredicateValue(a, primary)) != null ? _a3 : 0;
|
|
9207
9335
|
const bValue = (_b = this.resolveNumericPredicateValue(b, primary)) != null ? _b : 0;
|
|
9208
9336
|
return primary.operator === "lt" || primary.operator === "lte" ? aValue - bValue : bValue - aValue;
|
|
9209
9337
|
});
|
|
9210
9338
|
}
|
|
9211
9339
|
resolveNumericPredicateValue(source, predicate) {
|
|
9212
|
-
var
|
|
9340
|
+
var _a3;
|
|
9213
9341
|
if (!source) return null;
|
|
9214
9342
|
const meta = source.metadata || {};
|
|
9215
9343
|
const field = predicate.field;
|
|
@@ -9222,7 +9350,7 @@ ${context}`;
|
|
|
9222
9350
|
const value = this.toFiniteNumber(Array.isArray(fuzzy) ? fuzzy[1] : fuzzy.value);
|
|
9223
9351
|
if (value !== null) return value;
|
|
9224
9352
|
}
|
|
9225
|
-
const contentValue = this.extractNumericValueFromContent((
|
|
9353
|
+
const contentValue = this.extractNumericValueFromContent((_a3 = source.content) != null ? _a3 : "", field);
|
|
9226
9354
|
if (contentValue !== null) return contentValue;
|
|
9227
9355
|
}
|
|
9228
9356
|
for (const [key, value] of entries) {
|
|
@@ -9278,8 +9406,8 @@ ${context}`;
|
|
|
9278
9406
|
return Number.isFinite(numeric) ? numeric : null;
|
|
9279
9407
|
}
|
|
9280
9408
|
async retrieve(query, options) {
|
|
9281
|
-
var
|
|
9282
|
-
const ns = formatNamespace((
|
|
9409
|
+
var _a3, _b, _c, _d, _e, _f, _g2;
|
|
9410
|
+
const ns = formatNamespace((_a3 = options.namespace) != null ? _a3 : this.config.projectId);
|
|
9283
9411
|
const topK = (_b = options.topK) != null ? _b : 5;
|
|
9284
9412
|
const cacheKey = `${ns}::${query}`;
|
|
9285
9413
|
let queryVector = this.embeddingCache.get(cacheKey);
|
|
@@ -9324,11 +9452,11 @@ ${context}`;
|
|
|
9324
9452
|
namespace: ns,
|
|
9325
9453
|
count: resolvedSources.length,
|
|
9326
9454
|
sample: resolvedSources.slice(0, 2).map((s) => {
|
|
9327
|
-
var
|
|
9455
|
+
var _a4;
|
|
9328
9456
|
return {
|
|
9329
9457
|
id: s == null ? void 0 : s.id,
|
|
9330
9458
|
score: s == null ? void 0 : s.score,
|
|
9331
|
-
contentSnippet: String((
|
|
9459
|
+
contentSnippet: String((_a4 = s == null ? void 0 : s.content) != null ? _a4 : "").substring(0, 150),
|
|
9332
9460
|
metadata: s == null ? void 0 : s.metadata
|
|
9333
9461
|
};
|
|
9334
9462
|
})
|
|
@@ -9342,8 +9470,8 @@ Focus on extracting the core intent and entities. Do not answer the question, ju
|
|
|
9342
9470
|
|
|
9343
9471
|
History:
|
|
9344
9472
|
${(history || []).map((m) => {
|
|
9345
|
-
var
|
|
9346
|
-
return `${(m == null ? void 0 : m.role) || "user"}: ${(
|
|
9473
|
+
var _a3;
|
|
9474
|
+
return `${(m == null ? void 0 : m.role) || "user"}: ${(_a3 = m == null ? void 0 : m.content) != null ? _a3 : ""}`;
|
|
9347
9475
|
}).join("\n")}
|
|
9348
9476
|
|
|
9349
9477
|
New Question: ${question}
|
|
@@ -9370,8 +9498,8 @@ Optimized Search Query:`;
|
|
|
9370
9498
|
const { sources } = await this.retrieve(query, { namespace: ns, topK: 5 });
|
|
9371
9499
|
if (!sources || sources.length === 0) return [];
|
|
9372
9500
|
const context = sources.map((s) => {
|
|
9373
|
-
var
|
|
9374
|
-
return (
|
|
9501
|
+
var _a3;
|
|
9502
|
+
return (_a3 = s == null ? void 0 : s.content) != null ? _a3 : "";
|
|
9375
9503
|
}).join("\n\n---\n\n");
|
|
9376
9504
|
const prompt = `Based on the following snippets from a document, what are at least 5 short, relevant questions a user might ask?
|
|
9377
9505
|
Focus on questions that can be answered by the context.
|
|
@@ -9509,18 +9637,200 @@ var ProviderHealthCheck = class {
|
|
|
9509
9637
|
}
|
|
9510
9638
|
};
|
|
9511
9639
|
|
|
9640
|
+
// src/core/FreeTierLimitsGuard.ts
|
|
9641
|
+
var FREE_TIER_QUOTAS = {
|
|
9642
|
+
MAX_DOCUMENTS: 25,
|
|
9643
|
+
MAX_FILE_SIZE_BYTES: 20 * 1024 * 1024,
|
|
9644
|
+
MAX_STORAGE_BYTES: 250 * 1024 * 1024,
|
|
9645
|
+
MAX_TRIAL_REQUEST_UNITS: 500,
|
|
9646
|
+
MAX_DAILY_REQUEST_UNITS: 50,
|
|
9647
|
+
TRIAL_DURATION_DAYS: 14,
|
|
9648
|
+
GRACE_PERIOD_DAYS: 2,
|
|
9649
|
+
MAX_RPM: 10,
|
|
9650
|
+
MAX_RPH: 100,
|
|
9651
|
+
MAX_RPD: 500,
|
|
9652
|
+
MAX_CONCURRENT_REQUESTS: 2,
|
|
9653
|
+
MAX_INPUT_TOKENS: 2e4,
|
|
9654
|
+
MAX_OUTPUT_TOKENS: 4e3,
|
|
9655
|
+
UPGRADE_REMINDER_DAYS: [7, 12, 14],
|
|
9656
|
+
MAX_USERS: 1,
|
|
9657
|
+
MAX_NAMESPACES: 1,
|
|
9658
|
+
MAX_PROJECTS: 1
|
|
9659
|
+
};
|
|
9660
|
+
var FreeTierLimitsGuard = class {
|
|
9661
|
+
static calculateTrialTimestamps(startedAt) {
|
|
9662
|
+
const startDate = startedAt ? new Date(startedAt) : /* @__PURE__ */ new Date();
|
|
9663
|
+
const trialStartedAtMs = startDate.getTime();
|
|
9664
|
+
const trialExpiresAtMs = trialStartedAtMs + FREE_TIER_QUOTAS.TRIAL_DURATION_DAYS * 24 * 60 * 60 * 1e3;
|
|
9665
|
+
const gracePeriodExpiresAtMs = trialStartedAtMs + (FREE_TIER_QUOTAS.TRIAL_DURATION_DAYS + FREE_TIER_QUOTAS.GRACE_PERIOD_DAYS) * 24 * 60 * 60 * 1e3;
|
|
9666
|
+
return {
|
|
9667
|
+
trial_started_at: new Date(trialStartedAtMs).toISOString(),
|
|
9668
|
+
trial_expires_at: new Date(trialExpiresAtMs).toISOString(),
|
|
9669
|
+
grace_period_expires_at: new Date(gracePeriodExpiresAtMs).toISOString()
|
|
9670
|
+
};
|
|
9671
|
+
}
|
|
9672
|
+
static calculateRequestUnits(operationType, options) {
|
|
9673
|
+
var _a3;
|
|
9674
|
+
const op = operationType.toLowerCase().trim();
|
|
9675
|
+
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")) {
|
|
9676
|
+
return 0;
|
|
9677
|
+
}
|
|
9678
|
+
if (op.includes("image")) {
|
|
9679
|
+
return 10;
|
|
9680
|
+
}
|
|
9681
|
+
if (op.includes("embedding")) {
|
|
9682
|
+
const chunks = (_a3 = options == null ? void 0 : options.chunkCount) != null ? _a3 : 1;
|
|
9683
|
+
return Math.max(1, Math.ceil(chunks / 1e3));
|
|
9684
|
+
}
|
|
9685
|
+
return 1;
|
|
9686
|
+
}
|
|
9687
|
+
static checkTrialStatus(startedAt, totalUnitsUsed = 0, nowServerTime = /* @__PURE__ */ new Date()) {
|
|
9688
|
+
const timestamps = this.calculateTrialTimestamps(startedAt);
|
|
9689
|
+
const startMs = new Date(timestamps.trial_started_at).getTime();
|
|
9690
|
+
const expireMs = new Date(timestamps.trial_expires_at).getTime();
|
|
9691
|
+
const graceExpireMs = new Date(timestamps.grace_period_expires_at).getTime();
|
|
9692
|
+
const nowMs = nowServerTime.getTime();
|
|
9693
|
+
const daysElapsed = Math.floor(Math.max(0, nowMs - startMs) / (1e3 * 60 * 60 * 24));
|
|
9694
|
+
const daysRemaining = Math.max(0, Math.ceil((expireMs - nowMs) / (1e3 * 60 * 60 * 24)));
|
|
9695
|
+
const isConsumedUnits = totalUnitsUsed >= FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS;
|
|
9696
|
+
const isExpiredTime = nowMs > expireMs;
|
|
9697
|
+
const isPastGraceTime = nowMs > graceExpireMs;
|
|
9698
|
+
let status = "active";
|
|
9699
|
+
let reason;
|
|
9700
|
+
if (isPastGraceTime || isConsumedUnits && isExpiredTime) {
|
|
9701
|
+
status = "expired";
|
|
9702
|
+
reason = "Trial period and grace period have expired. Upgrade your plan.";
|
|
9703
|
+
} else if (isExpiredTime || isConsumedUnits) {
|
|
9704
|
+
status = "grace_period";
|
|
9705
|
+
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).";
|
|
9706
|
+
}
|
|
9707
|
+
let upgradeReminderDue;
|
|
9708
|
+
if (FREE_TIER_QUOTAS.UPGRADE_REMINDER_DAYS.includes(daysElapsed)) {
|
|
9709
|
+
upgradeReminderDue = daysElapsed;
|
|
9710
|
+
}
|
|
9711
|
+
let usageReminderDue;
|
|
9712
|
+
const usagePercent = totalUnitsUsed / FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS * 100;
|
|
9713
|
+
if (usagePercent >= 100) {
|
|
9714
|
+
usageReminderDue = "100%";
|
|
9715
|
+
} else if (usagePercent >= 90) {
|
|
9716
|
+
usageReminderDue = "90%";
|
|
9717
|
+
} else if (usagePercent >= 80) {
|
|
9718
|
+
usageReminderDue = "80%";
|
|
9719
|
+
}
|
|
9720
|
+
return {
|
|
9721
|
+
status,
|
|
9722
|
+
daysElapsed,
|
|
9723
|
+
daysRemaining,
|
|
9724
|
+
isGracePeriod: status === "grace_period",
|
|
9725
|
+
isExpired: status === "expired",
|
|
9726
|
+
upgradeReminderDue,
|
|
9727
|
+
usageReminderDue,
|
|
9728
|
+
reason
|
|
9729
|
+
};
|
|
9730
|
+
}
|
|
9731
|
+
static checkIngestionAllowed(stats, incomingSizeBytes = 0) {
|
|
9732
|
+
var _a3, _b;
|
|
9733
|
+
const docs = (_a3 = stats.documentCount) != null ? _a3 : 0;
|
|
9734
|
+
const storage = (_b = stats.totalStorageBytes) != null ? _b : 0;
|
|
9735
|
+
if (incomingSizeBytes > FREE_TIER_QUOTAS.MAX_FILE_SIZE_BYTES) {
|
|
9736
|
+
const mbSize = (incomingSizeBytes / (1024 * 1024)).toFixed(1);
|
|
9737
|
+
return {
|
|
9738
|
+
allowed: false,
|
|
9739
|
+
reason: `[FreeTierIngestor] File size (${mbSize}MB) exceeds maximum allowed size of 20MB under Free Tier rules.`
|
|
9740
|
+
};
|
|
9741
|
+
}
|
|
9742
|
+
if (docs >= FREE_TIER_QUOTAS.MAX_DOCUMENTS) {
|
|
9743
|
+
return {
|
|
9744
|
+
allowed: false,
|
|
9745
|
+
reason: `Document limit reached (${docs}/${FREE_TIER_QUOTAS.MAX_DOCUMENTS}). Upgrade to Pro to ingest more documents.`
|
|
9746
|
+
};
|
|
9747
|
+
}
|
|
9748
|
+
if (storage + incomingSizeBytes > FREE_TIER_QUOTAS.MAX_STORAGE_BYTES) {
|
|
9749
|
+
const mbUsed = (storage / (1024 * 1024)).toFixed(1);
|
|
9750
|
+
return {
|
|
9751
|
+
allowed: false,
|
|
9752
|
+
reason: `Storage quota exceeded (${mbUsed}MB / 250MB). Upgrade for unlimited storage.`
|
|
9753
|
+
};
|
|
9754
|
+
}
|
|
9755
|
+
return { allowed: true };
|
|
9756
|
+
}
|
|
9757
|
+
static checkRequestAllowed(params) {
|
|
9758
|
+
var _a3, _b, _c;
|
|
9759
|
+
const op = (_a3 = params.operationType) != null ? _a3 : "chat";
|
|
9760
|
+
const costUnits = this.calculateRequestUnits(op, { chunkCount: params.chunkCount });
|
|
9761
|
+
if (costUnits === 0) {
|
|
9762
|
+
return { allowed: true, costUnits: 0 };
|
|
9763
|
+
}
|
|
9764
|
+
if (params.inputTokens && params.inputTokens > FREE_TIER_QUOTAS.MAX_INPUT_TOKENS) {
|
|
9765
|
+
return {
|
|
9766
|
+
allowed: false,
|
|
9767
|
+
reason: "Token limit exceeded. Upgrade your plan.",
|
|
9768
|
+
costUnits
|
|
9769
|
+
};
|
|
9770
|
+
}
|
|
9771
|
+
if (params.outputTokens && params.outputTokens > FREE_TIER_QUOTAS.MAX_OUTPUT_TOKENS) {
|
|
9772
|
+
return {
|
|
9773
|
+
allowed: false,
|
|
9774
|
+
reason: "Token limit exceeded. Upgrade your plan.",
|
|
9775
|
+
costUnits
|
|
9776
|
+
};
|
|
9777
|
+
}
|
|
9778
|
+
if (params.concurrentRequests && params.concurrentRequests > FREE_TIER_QUOTAS.MAX_CONCURRENT_REQUESTS) {
|
|
9779
|
+
return {
|
|
9780
|
+
allowed: false,
|
|
9781
|
+
reason: `Concurrent limit exceeded (max ${FREE_TIER_QUOTAS.MAX_CONCURRENT_REQUESTS} active requests). Please wait for active streams to finish.`,
|
|
9782
|
+
costUnits
|
|
9783
|
+
};
|
|
9784
|
+
}
|
|
9785
|
+
const totalUnits = (_b = params.totalUnitsUsed) != null ? _b : 0;
|
|
9786
|
+
const trialStatus = this.checkTrialStatus(params.trialStartedAt, totalUnits, params.nowServerTime);
|
|
9787
|
+
if (trialStatus.status === "expired" || trialStatus.status === "grace_period") {
|
|
9788
|
+
return {
|
|
9789
|
+
allowed: false,
|
|
9790
|
+
reason: trialStatus.reason || "Trial limit reached. Upgrade your plan.",
|
|
9791
|
+
costUnits
|
|
9792
|
+
};
|
|
9793
|
+
}
|
|
9794
|
+
if (totalUnits + costUnits > FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS) {
|
|
9795
|
+
return {
|
|
9796
|
+
allowed: false,
|
|
9797
|
+
reason: `Total trial request unit limit reached (${totalUnits}/${FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS}). Upgrade your plan.`,
|
|
9798
|
+
costUnits
|
|
9799
|
+
};
|
|
9800
|
+
}
|
|
9801
|
+
const dailyUnits = (_c = params.dailyUnitsUsed) != null ? _c : 0;
|
|
9802
|
+
if (dailyUnits + costUnits > FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS) {
|
|
9803
|
+
return {
|
|
9804
|
+
allowed: false,
|
|
9805
|
+
reason: `Daily request quota limit reached (${dailyUnits}/${FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS} units/day). Quota resets tomorrow.`,
|
|
9806
|
+
costUnits
|
|
9807
|
+
};
|
|
9808
|
+
}
|
|
9809
|
+
return { allowed: true, costUnits };
|
|
9810
|
+
}
|
|
9811
|
+
static checkQueryAllowed(dailyQueriesCount = 0) {
|
|
9812
|
+
if (dailyQueriesCount >= FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS) {
|
|
9813
|
+
return {
|
|
9814
|
+
allowed: false,
|
|
9815
|
+
reason: `Daily query limit reached (${FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS}/day). Quota resets tomorrow.`
|
|
9816
|
+
};
|
|
9817
|
+
}
|
|
9818
|
+
return { allowed: true };
|
|
9819
|
+
}
|
|
9820
|
+
};
|
|
9821
|
+
|
|
9512
9822
|
// src/core/VectorPlugin.ts
|
|
9513
9823
|
var VectorPlugin = class {
|
|
9514
9824
|
constructor(hostConfig) {
|
|
9515
9825
|
const resolvedConfig = ConfigResolver.resolve(hostConfig);
|
|
9516
9826
|
this.config = resolvedConfig;
|
|
9517
9827
|
this.validationPromise = (async () => {
|
|
9518
|
-
var
|
|
9828
|
+
var _a3;
|
|
9519
9829
|
await ConfigValidator.validateAndThrow(resolvedConfig);
|
|
9520
9830
|
LicenseVerifier.verify(
|
|
9521
9831
|
resolvedConfig.licenseKey,
|
|
9522
9832
|
resolvedConfig.projectId,
|
|
9523
|
-
(
|
|
9833
|
+
(_a3 = resolvedConfig.vectorDb) == null ? void 0 : _a3.provider
|
|
9524
9834
|
);
|
|
9525
9835
|
})();
|
|
9526
9836
|
this.validationPromise.catch(() => {
|
|
@@ -9554,16 +9864,32 @@ var VectorPlugin = class {
|
|
|
9554
9864
|
this.config.embedding
|
|
9555
9865
|
);
|
|
9556
9866
|
}
|
|
9867
|
+
estimateInputTokens(message, history = []) {
|
|
9868
|
+
const allContent = message.length + history.reduce((acc, m) => {
|
|
9869
|
+
var _a3, _b;
|
|
9870
|
+
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);
|
|
9871
|
+
}, 0);
|
|
9872
|
+
return Math.ceil(allContent / 4);
|
|
9873
|
+
}
|
|
9557
9874
|
/**
|
|
9558
9875
|
* Run a chat query.
|
|
9559
9876
|
*/
|
|
9560
9877
|
async chat(message, history = [], namespace) {
|
|
9878
|
+
var _a3;
|
|
9561
9879
|
try {
|
|
9562
9880
|
await this.validationPromise;
|
|
9563
9881
|
} catch (err) {
|
|
9564
9882
|
throw wrapError(err, "CONFIGURATION_ERROR");
|
|
9565
9883
|
}
|
|
9566
9884
|
try {
|
|
9885
|
+
const inputTokens = this.estimateInputTokens(message, history);
|
|
9886
|
+
const tokenCheck = FreeTierLimitsGuard.checkRequestAllowed({
|
|
9887
|
+
operationType: "chat",
|
|
9888
|
+
inputTokens
|
|
9889
|
+
});
|
|
9890
|
+
if (!tokenCheck.allowed && ((_a3 = tokenCheck.reason) == null ? void 0 : _a3.toLowerCase().includes("token"))) {
|
|
9891
|
+
throw wrapError(new Error(tokenCheck.reason), "RATE_LIMITED");
|
|
9892
|
+
}
|
|
9567
9893
|
return await this.pipeline.ask(message, history, namespace);
|
|
9568
9894
|
} catch (err) {
|
|
9569
9895
|
const msg = String(err);
|
|
@@ -9571,6 +9897,9 @@ var VectorPlugin = class {
|
|
|
9571
9897
|
if (msg.includes("Embed") || msg.includes("embed")) {
|
|
9572
9898
|
defaultCode = "EMBEDDING_FAILED";
|
|
9573
9899
|
}
|
|
9900
|
+
if (msg.toLowerCase().includes("token limit")) {
|
|
9901
|
+
defaultCode = "RATE_LIMITED";
|
|
9902
|
+
}
|
|
9574
9903
|
throw wrapError(err, defaultCode);
|
|
9575
9904
|
}
|
|
9576
9905
|
}
|
|
@@ -9579,12 +9908,21 @@ var VectorPlugin = class {
|
|
|
9579
9908
|
*/
|
|
9580
9909
|
chatStream(_0) {
|
|
9581
9910
|
return __asyncGenerator(this, arguments, function* (message, history = [], namespace) {
|
|
9911
|
+
var _a3;
|
|
9582
9912
|
try {
|
|
9583
9913
|
yield new __await(this.validationPromise);
|
|
9584
9914
|
} catch (err) {
|
|
9585
9915
|
throw wrapError(err, "CONFIGURATION_ERROR");
|
|
9586
9916
|
}
|
|
9587
9917
|
try {
|
|
9918
|
+
const inputTokens = this.estimateInputTokens(message, history);
|
|
9919
|
+
const tokenCheck = FreeTierLimitsGuard.checkRequestAllowed({
|
|
9920
|
+
operationType: "chat_stream",
|
|
9921
|
+
inputTokens
|
|
9922
|
+
});
|
|
9923
|
+
if (!tokenCheck.allowed && ((_a3 = tokenCheck.reason) == null ? void 0 : _a3.toLowerCase().includes("token"))) {
|
|
9924
|
+
throw wrapError(new Error(tokenCheck.reason), "RATE_LIMITED");
|
|
9925
|
+
}
|
|
9588
9926
|
const stream = this.pipeline.askStream(message, history, namespace);
|
|
9589
9927
|
try {
|
|
9590
9928
|
for (var iter = __forAwait(stream), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
|
|
@@ -9607,6 +9945,9 @@ var VectorPlugin = class {
|
|
|
9607
9945
|
if (msg.includes("Embed") || msg.includes("embed")) {
|
|
9608
9946
|
defaultCode = "EMBEDDING_FAILED";
|
|
9609
9947
|
}
|
|
9948
|
+
if (msg.toLowerCase().includes("token limit")) {
|
|
9949
|
+
defaultCode = "RATE_LIMITED";
|
|
9950
|
+
}
|
|
9610
9951
|
throw wrapError(err, defaultCode);
|
|
9611
9952
|
}
|
|
9612
9953
|
});
|
|
@@ -9654,8 +9995,8 @@ var DocumentParser = class {
|
|
|
9654
9995
|
* Extract text from a File or Buffer based on its type.
|
|
9655
9996
|
*/
|
|
9656
9997
|
static async parse(file, fileName, mimeType) {
|
|
9657
|
-
var
|
|
9658
|
-
const extension = ((
|
|
9998
|
+
var _a3;
|
|
9999
|
+
const extension = ((_a3 = fileName.split(".").pop()) == null ? void 0 : _a3.toLowerCase()) || "";
|
|
9659
10000
|
if (extension === "txt" || extension === "md" || mimeType === "text/plain" || mimeType === "text/markdown") {
|
|
9660
10001
|
return this.readAsText(file);
|
|
9661
10002
|
}
|
|
@@ -9746,9 +10087,9 @@ var DatabaseStorage = class {
|
|
|
9746
10087
|
this.fallbackDir = this.isServerless ? path.join(os.tmpdir(), ".retrivora") : path.join(process.cwd(), ".retrivora");
|
|
9747
10088
|
this.historyFile = path.join(this.fallbackDir, "history.json");
|
|
9748
10089
|
this.feedbackFile = path.join(this.fallbackDir, "feedback.json");
|
|
9749
|
-
var
|
|
10090
|
+
var _a3, _b, _c, _d, _e;
|
|
9750
10091
|
this.config = config;
|
|
9751
|
-
this.provider = ((
|
|
10092
|
+
this.provider = ((_a3 = config.vectorDb) == null ? void 0 : _a3.provider) || "fs";
|
|
9752
10093
|
const rawHistoryTable = ((_c = (_b = config.rag) == null ? void 0 : _b.history) == null ? void 0 : _c.tableName) || "retrivora_history";
|
|
9753
10094
|
const rawFeedbackTable = ((_e = (_d = config.rag) == null ? void 0 : _d.feedback) == null ? void 0 : _e.tableName) || "retrivora_feedback";
|
|
9754
10095
|
this.historyTableName = rawHistoryTable.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
@@ -9783,16 +10124,16 @@ var DatabaseStorage = class {
|
|
|
9783
10124
|
}
|
|
9784
10125
|
}
|
|
9785
10126
|
checkHistoryEnabled() {
|
|
9786
|
-
var
|
|
10127
|
+
var _a3, _b;
|
|
9787
10128
|
this.checkPremiumSubscription();
|
|
9788
|
-
if (((_b = (
|
|
10129
|
+
if (((_b = (_a3 = this.config.rag) == null ? void 0 : _a3.history) == null ? void 0 : _b.enabled) === false) {
|
|
9789
10130
|
throw new Error("[Retrivora SDK] Chat History is disabled in RagConfig.");
|
|
9790
10131
|
}
|
|
9791
10132
|
}
|
|
9792
10133
|
checkFeedbackEnabled() {
|
|
9793
|
-
var
|
|
10134
|
+
var _a3, _b;
|
|
9794
10135
|
this.checkPremiumSubscription();
|
|
9795
|
-
if (((_b = (
|
|
10136
|
+
if (((_b = (_a3 = this.config.rag) == null ? void 0 : _a3.feedback) == null ? void 0 : _b.enabled) === false) {
|
|
9796
10137
|
throw new Error("[Retrivora SDK] User Feedback is disabled in RagConfig.");
|
|
9797
10138
|
}
|
|
9798
10139
|
}
|
|
@@ -9959,8 +10300,11 @@ var DatabaseStorage = class {
|
|
|
9959
10300
|
this.writeLocalFile(this.historyFile, history);
|
|
9960
10301
|
}
|
|
9961
10302
|
}
|
|
9962
|
-
async getHistory(sessionId) {
|
|
10303
|
+
async getHistory(sessionId, projectIds) {
|
|
9963
10304
|
this.checkHistoryEnabled();
|
|
10305
|
+
if (projectIds && projectIds.length > 0 && !this.sessionInScope(sessionId, projectIds)) {
|
|
10306
|
+
return [];
|
|
10307
|
+
}
|
|
9964
10308
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
9965
10309
|
const pool = await this.getPGPool();
|
|
9966
10310
|
const res = await pool.query(
|
|
@@ -9990,8 +10334,11 @@ var DatabaseStorage = class {
|
|
|
9990
10334
|
return history.filter((h) => h.session_id === sessionId).sort((a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime());
|
|
9991
10335
|
}
|
|
9992
10336
|
}
|
|
9993
|
-
async clearHistory(sessionId) {
|
|
10337
|
+
async clearHistory(sessionId, projectIds) {
|
|
9994
10338
|
this.checkHistoryEnabled();
|
|
10339
|
+
if (projectIds && projectIds.length > 0 && !this.sessionInScope(sessionId, projectIds)) {
|
|
10340
|
+
return;
|
|
10341
|
+
}
|
|
9995
10342
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
9996
10343
|
const pool = await this.getPGPool();
|
|
9997
10344
|
await pool.query(`DELETE FROM ${this.historyTableName} WHERE session_id = $1`, [sessionId]);
|
|
@@ -10010,21 +10357,36 @@ var DatabaseStorage = class {
|
|
|
10010
10357
|
this.writeLocalFile(this.feedbackFile, filteredFeedback);
|
|
10011
10358
|
}
|
|
10012
10359
|
}
|
|
10013
|
-
|
|
10360
|
+
/**
|
|
10361
|
+
* Return true when `sessionId` falls into the allowed `projectIds` scope.
|
|
10362
|
+
* When `projectIds` is empty / undefined we allow the call (legacy behavior
|
|
10363
|
+
* for non-multi-tenant consumers). Session ids typically begin with the
|
|
10364
|
+
* project id they were created for, so we prefix-match as well as contains-match
|
|
10365
|
+
* to catch sharded / suffix-style ids used by some integrations.
|
|
10366
|
+
*/
|
|
10367
|
+
sessionInScope(sessionId, projectIds) {
|
|
10368
|
+
if (!projectIds || projectIds.length === 0) return true;
|
|
10369
|
+
return projectIds.some(
|
|
10370
|
+
(pid) => pid && (sessionId === pid || sessionId.startsWith(pid) || sessionId.includes(pid))
|
|
10371
|
+
);
|
|
10372
|
+
}
|
|
10373
|
+
async listSessions(projectIds) {
|
|
10014
10374
|
this.checkHistoryEnabled();
|
|
10375
|
+
let raw = [];
|
|
10015
10376
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
10016
10377
|
const pool = await this.getPGPool();
|
|
10017
10378
|
const res = await pool.query(`SELECT DISTINCT session_id FROM ${this.historyTableName}`);
|
|
10018
|
-
|
|
10379
|
+
raw = res.rows.map((r) => r.session_id);
|
|
10019
10380
|
} else if (this.provider === "mongodb") {
|
|
10020
10381
|
await this.getMongoClient();
|
|
10021
10382
|
const db = this.getMongoDb();
|
|
10022
|
-
|
|
10383
|
+
raw = await db.collection(this.historyTableName).distinct("session_id");
|
|
10023
10384
|
} else {
|
|
10024
10385
|
const history = this.readLocalFile(this.historyFile);
|
|
10025
|
-
|
|
10026
|
-
return Array.from(sessions);
|
|
10386
|
+
raw = Array.from(new Set(history.map((h) => h.session_id)));
|
|
10027
10387
|
}
|
|
10388
|
+
if (!projectIds || projectIds.length === 0) return raw;
|
|
10389
|
+
return raw.filter((sid) => this.sessionInScope(sid, projectIds));
|
|
10028
10390
|
}
|
|
10029
10391
|
// ─── Feedback Operations ──────────────────────────────────────────────────
|
|
10030
10392
|
async saveFeedback(feedback) {
|
|
@@ -10077,8 +10439,9 @@ var DatabaseStorage = class {
|
|
|
10077
10439
|
this.writeLocalFile(this.feedbackFile, list);
|
|
10078
10440
|
}
|
|
10079
10441
|
}
|
|
10080
|
-
async getFeedback(messageId) {
|
|
10442
|
+
async getFeedback(messageId, projectIds) {
|
|
10081
10443
|
this.checkFeedbackEnabled();
|
|
10444
|
+
let item = null;
|
|
10082
10445
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
10083
10446
|
const pool = await this.getPGPool();
|
|
10084
10447
|
const res = await pool.query(
|
|
@@ -10087,28 +10450,34 @@ var DatabaseStorage = class {
|
|
|
10087
10450
|
WHERE message_id = $1`,
|
|
10088
10451
|
[messageId]
|
|
10089
10452
|
);
|
|
10090
|
-
|
|
10453
|
+
item = res.rows[0] || null;
|
|
10091
10454
|
} else if (this.provider === "mongodb") {
|
|
10092
10455
|
await this.getMongoClient();
|
|
10093
10456
|
const db = this.getMongoDb();
|
|
10094
10457
|
const col = db.collection(this.feedbackTableName);
|
|
10095
|
-
const
|
|
10096
|
-
if (
|
|
10097
|
-
|
|
10098
|
-
|
|
10099
|
-
|
|
10100
|
-
|
|
10101
|
-
|
|
10102
|
-
|
|
10103
|
-
|
|
10104
|
-
|
|
10458
|
+
const raw = await col.findOne({ message_id: messageId });
|
|
10459
|
+
if (raw) {
|
|
10460
|
+
item = {
|
|
10461
|
+
id: raw.id,
|
|
10462
|
+
messageId: raw.message_id,
|
|
10463
|
+
sessionId: raw.session_id,
|
|
10464
|
+
rating: raw.rating,
|
|
10465
|
+
comment: raw.comment,
|
|
10466
|
+
createdAt: raw.created_at
|
|
10467
|
+
};
|
|
10468
|
+
}
|
|
10105
10469
|
} else {
|
|
10106
10470
|
const list = this.readLocalFile(this.feedbackFile);
|
|
10107
|
-
|
|
10471
|
+
item = list.find((f) => f.message_id === messageId) || null;
|
|
10472
|
+
}
|
|
10473
|
+
if (item && projectIds && projectIds.length > 0) {
|
|
10474
|
+
return this.sessionInScope(item.sessionId, projectIds) ? item : null;
|
|
10108
10475
|
}
|
|
10476
|
+
return item;
|
|
10109
10477
|
}
|
|
10110
|
-
async listFeedback() {
|
|
10478
|
+
async listFeedback(projectIds) {
|
|
10111
10479
|
this.checkFeedbackEnabled();
|
|
10480
|
+
let raw = [];
|
|
10112
10481
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
10113
10482
|
const pool = await this.getPGPool();
|
|
10114
10483
|
const res = await pool.query(
|
|
@@ -10116,13 +10485,13 @@ var DatabaseStorage = class {
|
|
|
10116
10485
|
FROM ${this.feedbackTableName}
|
|
10117
10486
|
ORDER BY created_at DESC`
|
|
10118
10487
|
);
|
|
10119
|
-
|
|
10488
|
+
raw = res.rows;
|
|
10120
10489
|
} else if (this.provider === "mongodb") {
|
|
10121
10490
|
await this.getMongoClient();
|
|
10122
10491
|
const db = this.getMongoDb();
|
|
10123
10492
|
const col = db.collection(this.feedbackTableName);
|
|
10124
10493
|
const items = await col.find({}).sort({ created_at: -1 }).toArray();
|
|
10125
|
-
|
|
10494
|
+
raw = items.map((item) => ({
|
|
10126
10495
|
id: item.id,
|
|
10127
10496
|
messageId: item.message_id,
|
|
10128
10497
|
sessionId: item.session_id,
|
|
@@ -10132,8 +10501,10 @@ var DatabaseStorage = class {
|
|
|
10132
10501
|
}));
|
|
10133
10502
|
} else {
|
|
10134
10503
|
const list = this.readLocalFile(this.feedbackFile);
|
|
10135
|
-
|
|
10504
|
+
raw = [...list].sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime());
|
|
10136
10505
|
}
|
|
10506
|
+
if (!projectIds || projectIds.length === 0) return raw;
|
|
10507
|
+
return raw.filter((f) => this.sessionInScope(f.sessionId, projectIds));
|
|
10137
10508
|
}
|
|
10138
10509
|
async disconnect() {
|
|
10139
10510
|
if (this.pgPool) {
|
|
@@ -10196,8 +10567,8 @@ var _g = global;
|
|
|
10196
10567
|
var _a;
|
|
10197
10568
|
var rateLimiter = (_a = _g.__retrivoraRateLimiter) != null ? _a : _g.__retrivoraRateLimiter = new RateLimiter(6e4, 30);
|
|
10198
10569
|
function getRateLimitKey(req) {
|
|
10199
|
-
var
|
|
10200
|
-
const ip = ((_b = (
|
|
10570
|
+
var _a3, _b;
|
|
10571
|
+
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";
|
|
10201
10572
|
return `ip:${ip}`;
|
|
10202
10573
|
}
|
|
10203
10574
|
function checkRateLimit(req) {
|
|
@@ -10219,6 +10590,66 @@ function checkRateLimit(req) {
|
|
|
10219
10590
|
}
|
|
10220
10591
|
return null;
|
|
10221
10592
|
}
|
|
10593
|
+
var FREE_TIER_NAMES = /* @__PURE__ */ new Set(["hobby", "free", "free_trial", "trial"]);
|
|
10594
|
+
function isFreeTier(tier) {
|
|
10595
|
+
if (!tier) return true;
|
|
10596
|
+
return FREE_TIER_NAMES.has(tier.toLowerCase().trim());
|
|
10597
|
+
}
|
|
10598
|
+
var _a2;
|
|
10599
|
+
var _freeTierGuardInstance = (_a2 = _g.__retrivoraFreeTierGuard) != null ? _a2 : _g.__retrivoraFreeTierGuard = new FreeTierLimitsGuard();
|
|
10600
|
+
function createPaymentRequiredResponse(reason, details) {
|
|
10601
|
+
const body = __spreadProps(__spreadValues({
|
|
10602
|
+
type: "https://retrivora.com/docs/errors/payment-required",
|
|
10603
|
+
title: "Payment Required",
|
|
10604
|
+
status: 402,
|
|
10605
|
+
detail: reason,
|
|
10606
|
+
code: "FREE_TIER_LIMIT_EXCEEDED",
|
|
10607
|
+
instance: void 0
|
|
10608
|
+
}, details != null ? details : {}), {
|
|
10609
|
+
quota: {
|
|
10610
|
+
maxDailyRequestUnits: FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS,
|
|
10611
|
+
maxTrialRequestUnits: FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS,
|
|
10612
|
+
maxDocuments: FREE_TIER_QUOTAS.MAX_DOCUMENTS,
|
|
10613
|
+
maxStorageBytes: FREE_TIER_QUOTAS.MAX_STORAGE_BYTES,
|
|
10614
|
+
upgradeUrl: "https://retrivora.com/pricing"
|
|
10615
|
+
}
|
|
10616
|
+
});
|
|
10617
|
+
return new Response(JSON.stringify(body), {
|
|
10618
|
+
status: 402,
|
|
10619
|
+
headers: {
|
|
10620
|
+
"Content-Type": "application/problem+json"
|
|
10621
|
+
}
|
|
10622
|
+
});
|
|
10623
|
+
}
|
|
10624
|
+
function resolveLicenseKey(req, config, bodyLicenseKey) {
|
|
10625
|
+
var _a3;
|
|
10626
|
+
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 || "";
|
|
10627
|
+
}
|
|
10628
|
+
function enforceLicense(req, config, bodyLicenseKey) {
|
|
10629
|
+
const rawKey = resolveLicenseKey(req, config, bodyLicenseKey);
|
|
10630
|
+
const licenseKey = (rawKey || "").trim().replace(/^["']|["']$/g, "").trim();
|
|
10631
|
+
const projectId = config.projectId || "my-rag-app";
|
|
10632
|
+
try {
|
|
10633
|
+
const payload = LicenseVerifier.verify(licenseKey, projectId);
|
|
10634
|
+
return { ok: true, payload };
|
|
10635
|
+
} catch (err) {
|
|
10636
|
+
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.";
|
|
10637
|
+
const body = {
|
|
10638
|
+
error: {
|
|
10639
|
+
code: "LICENSE_REVOKED",
|
|
10640
|
+
message: "Your Retrivora license key has been terminated, suspended, or revoked. Access denied."
|
|
10641
|
+
},
|
|
10642
|
+
details: message
|
|
10643
|
+
};
|
|
10644
|
+
return {
|
|
10645
|
+
ok: false,
|
|
10646
|
+
response: new Response(JSON.stringify(body), {
|
|
10647
|
+
status: 403,
|
|
10648
|
+
headers: { "Content-Type": "application/json" }
|
|
10649
|
+
})
|
|
10650
|
+
};
|
|
10651
|
+
}
|
|
10652
|
+
}
|
|
10222
10653
|
var MAX_MESSAGE_LENGTH = 8e3;
|
|
10223
10654
|
function sanitizeInput(raw) {
|
|
10224
10655
|
const stripped = raw.replace(/[\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F-\u009F]/g, "");
|
|
@@ -10240,7 +10671,7 @@ function getOrCreatePlugin(configOrPlugin) {
|
|
|
10240
10671
|
return _g[cacheKey];
|
|
10241
10672
|
}
|
|
10242
10673
|
function reportTelemetry(req, plugin, action, status, details, trace) {
|
|
10243
|
-
var
|
|
10674
|
+
var _a3, _b, _c, _d, _e, _f, _g2;
|
|
10244
10675
|
try {
|
|
10245
10676
|
const config = plugin.getConfig();
|
|
10246
10677
|
const licenseKey = config.licenseKey || process.env.RAG_LICENSE_KEY || process.env.RETRIVORA_LICENSE_KEY || process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY;
|
|
@@ -10255,7 +10686,7 @@ function reportTelemetry(req, plugin, action, status, details, trace) {
|
|
|
10255
10686
|
absoluteUrl = `${proto}://${host}${telemetryUrl}`;
|
|
10256
10687
|
}
|
|
10257
10688
|
const projectId = config.projectId || "default";
|
|
10258
|
-
const model = (trace == null ? void 0 : trace.model) || ((
|
|
10689
|
+
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";
|
|
10259
10690
|
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";
|
|
10260
10691
|
const tokens = Number(((_e = trace == null ? void 0 : trace.tokens) == null ? void 0 : _e.totalTokens) || (trace == null ? void 0 : trace.totalTokens) || 0);
|
|
10261
10692
|
const costUsd = Number(((_f = trace == null ? void 0 : trace.tokens) == null ? void 0 : _f.estimatedCostUsd) || (trace == null ? void 0 : trace.costUsd) || 0);
|
|
@@ -10279,7 +10710,6 @@ function reportTelemetry(req, plugin, action, status, details, trace) {
|
|
|
10279
10710
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
10280
10711
|
details
|
|
10281
10712
|
};
|
|
10282
|
-
console.log(`[Retrivora SDK Telemetry] Dispatching telemetry -> Feature: "${action}", Status: "${status}", Project: "${projectId}", Latency: ${latencyMs}ms`);
|
|
10283
10713
|
fetch(absoluteUrl, {
|
|
10284
10714
|
method: "POST",
|
|
10285
10715
|
headers: {
|
|
@@ -10337,14 +10767,39 @@ function createChatHandler(configOrPlugin, options) {
|
|
|
10337
10767
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
10338
10768
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
10339
10769
|
return async function POST(req, context) {
|
|
10340
|
-
var
|
|
10770
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
10341
10771
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10342
10772
|
if (authResult) return authResult;
|
|
10343
10773
|
const rateLimited = checkRateLimit(req);
|
|
10344
10774
|
if (rateLimited) return rateLimited;
|
|
10775
|
+
const config = plugin.getConfig();
|
|
10345
10776
|
try {
|
|
10346
10777
|
const body = await req.json();
|
|
10347
10778
|
const bodyObj = body != null ? body : {};
|
|
10779
|
+
const licenseCheck = enforceLicense(req, config, bodyObj == null ? void 0 : bodyObj.licenseKey);
|
|
10780
|
+
if (!licenseCheck.ok) return licenseCheck.response;
|
|
10781
|
+
if (isFreeTier(licenseCheck.payload.tier)) {
|
|
10782
|
+
const estimatedInputTokens = Math.ceil(
|
|
10783
|
+
((((_a3 = bodyObj.message) == null ? void 0 : _a3.length) || 0) + (Array.isArray(bodyObj.messages) ? bodyObj.messages.reduce((a, m) => {
|
|
10784
|
+
var _a4, _b2;
|
|
10785
|
+
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);
|
|
10786
|
+
}, 0) : 0) + (((_b = bodyObj.history) == null ? void 0 : _b.reduce((a, m) => {
|
|
10787
|
+
var _a4, _b2;
|
|
10788
|
+
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);
|
|
10789
|
+
}, 0)) || 0)) / 4
|
|
10790
|
+
);
|
|
10791
|
+
const chatCheck = FreeTierLimitsGuard.checkRequestAllowed({
|
|
10792
|
+
operationType: "chat",
|
|
10793
|
+
inputTokens: estimatedInputTokens,
|
|
10794
|
+
projectId: licenseCheck.payload.projectId
|
|
10795
|
+
});
|
|
10796
|
+
if (!chatCheck.allowed) {
|
|
10797
|
+
return createPaymentRequiredResponse(
|
|
10798
|
+
chatCheck.reason || "Free tier quota exceeded.",
|
|
10799
|
+
{ tier: licenseCheck.payload.tier, projectId: licenseCheck.payload.projectId }
|
|
10800
|
+
);
|
|
10801
|
+
}
|
|
10802
|
+
}
|
|
10348
10803
|
let rawMessage = bodyObj.message;
|
|
10349
10804
|
if (!rawMessage && Array.isArray(bodyObj.messages) && bodyObj.messages.length > 0) {
|
|
10350
10805
|
const lastMsg = bodyObj.messages[bodyObj.messages.length - 1];
|
|
@@ -10376,7 +10831,7 @@ function createChatHandler(configOrPlugin, options) {
|
|
|
10376
10831
|
uiTransformation: result.ui_transformation,
|
|
10377
10832
|
trace: result.trace
|
|
10378
10833
|
}).catch((err) => console.warn("[createChatHandler] Failed to save assistant message:", err));
|
|
10379
|
-
reportTelemetry(req, plugin, "QUERY_GENERATION", "success", `Tokens: ${((
|
|
10834
|
+
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);
|
|
10380
10835
|
return import_server.NextResponse.json(__spreadProps(__spreadValues({}, result), {
|
|
10381
10836
|
messageId: assistantMsgId,
|
|
10382
10837
|
userMessageId: userMsgId
|
|
@@ -10393,14 +10848,15 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10393
10848
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
10394
10849
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
10395
10850
|
return async function POST(req, context) {
|
|
10396
|
-
var
|
|
10851
|
+
var _a3, _b, _c;
|
|
10397
10852
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10398
10853
|
if (authResult) return authResult;
|
|
10399
10854
|
const rateLimited = checkRateLimit(req);
|
|
10400
10855
|
if (rateLimited) return rateLimited;
|
|
10856
|
+
const config = plugin.getConfig();
|
|
10401
10857
|
let body;
|
|
10402
10858
|
try {
|
|
10403
|
-
if ((
|
|
10859
|
+
if ((_a3 = req.headers.get("content-type")) == null ? void 0 : _a3.includes("multipart/form-data")) {
|
|
10404
10860
|
const uploader = createUploadHandler(plugin, { onAuthorize });
|
|
10405
10861
|
return uploader(req);
|
|
10406
10862
|
}
|
|
@@ -10412,6 +10868,30 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10412
10868
|
});
|
|
10413
10869
|
}
|
|
10414
10870
|
const bodyObj = body != null ? body : {};
|
|
10871
|
+
const licenseCheck = enforceLicense(req, config, bodyObj == null ? void 0 : bodyObj.licenseKey);
|
|
10872
|
+
if (!licenseCheck.ok) return licenseCheck.response;
|
|
10873
|
+
if (isFreeTier(licenseCheck.payload.tier)) {
|
|
10874
|
+
const estimatedInputTokens = Math.ceil(
|
|
10875
|
+
((((_b = bodyObj.message) == null ? void 0 : _b.length) || 0) + (Array.isArray(bodyObj.messages) ? bodyObj.messages.reduce((a, m) => {
|
|
10876
|
+
var _a4, _b2;
|
|
10877
|
+
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);
|
|
10878
|
+
}, 0) : 0) + (((_c = bodyObj.history) == null ? void 0 : _c.reduce((a, m) => {
|
|
10879
|
+
var _a4, _b2;
|
|
10880
|
+
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);
|
|
10881
|
+
}, 0)) || 0)) / 4
|
|
10882
|
+
);
|
|
10883
|
+
const chatCheck = FreeTierLimitsGuard.checkRequestAllowed({
|
|
10884
|
+
operationType: "chat_stream",
|
|
10885
|
+
inputTokens: estimatedInputTokens,
|
|
10886
|
+
projectId: licenseCheck.payload.projectId
|
|
10887
|
+
});
|
|
10888
|
+
if (!chatCheck.allowed) {
|
|
10889
|
+
return createPaymentRequiredResponse(
|
|
10890
|
+
chatCheck.reason || "Free tier quota exceeded.",
|
|
10891
|
+
{ tier: licenseCheck.payload.tier, projectId: licenseCheck.payload.projectId }
|
|
10892
|
+
);
|
|
10893
|
+
}
|
|
10894
|
+
}
|
|
10415
10895
|
let rawMessage = bodyObj.message;
|
|
10416
10896
|
if (!rawMessage && Array.isArray(bodyObj.messages) && bodyObj.messages.length > 0) {
|
|
10417
10897
|
const lastMsg = bodyObj.messages[bodyObj.messages.length - 1];
|
|
@@ -10441,7 +10921,7 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10441
10921
|
let isActive = true;
|
|
10442
10922
|
const stream = new ReadableStream({
|
|
10443
10923
|
async start(controller) {
|
|
10444
|
-
var
|
|
10924
|
+
var _a4, _b2, _c2, _d, _e;
|
|
10445
10925
|
const enqueue = (text) => {
|
|
10446
10926
|
if (!isActive) return;
|
|
10447
10927
|
try {
|
|
@@ -10474,7 +10954,7 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10474
10954
|
let uiTransformation = responseChunk == null ? void 0 : responseChunk.ui_transformation;
|
|
10475
10955
|
if (sources.length > 0) {
|
|
10476
10956
|
try {
|
|
10477
|
-
uiTransformation = (
|
|
10957
|
+
uiTransformation = (_a4 = responseChunk == null ? void 0 : responseChunk.ui_transformation) != null ? _a4 : UITransformer.transform(message, sources, plugin.getConfig());
|
|
10478
10958
|
if (uiTransformation) {
|
|
10479
10959
|
enqueue(sseUIFrame(uiTransformation));
|
|
10480
10960
|
}
|
|
@@ -10498,7 +10978,7 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10498
10978
|
uiTransformation,
|
|
10499
10979
|
trace: responseChunk == null ? void 0 : responseChunk.trace
|
|
10500
10980
|
}).catch((err) => console.warn("[createStreamHandler] Failed to save assistant message:", err));
|
|
10501
|
-
reportTelemetry(req, plugin, "QUERY_GENERATION", "success", `Tokens: ${((
|
|
10981
|
+
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);
|
|
10502
10982
|
}
|
|
10503
10983
|
}
|
|
10504
10984
|
} catch (temp) {
|
|
@@ -10548,12 +11028,36 @@ function createIngestHandler(configOrPlugin, options) {
|
|
|
10548
11028
|
return async function POST(req, context) {
|
|
10549
11029
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10550
11030
|
if (authResult) return authResult;
|
|
11031
|
+
const config = plugin.getConfig();
|
|
10551
11032
|
try {
|
|
10552
11033
|
const body = await req.json();
|
|
11034
|
+
const licenseCheck = enforceLicense(req, config, body == null ? void 0 : body.licenseKey);
|
|
11035
|
+
if (!licenseCheck.ok) return licenseCheck.response;
|
|
10553
11036
|
const { documents, namespace } = body;
|
|
10554
11037
|
if (!Array.isArray(documents) || documents.length === 0) {
|
|
10555
11038
|
return import_server.NextResponse.json({ error: "documents array is required" }, { status: 400 });
|
|
10556
11039
|
}
|
|
11040
|
+
if (isFreeTier(licenseCheck.payload.tier)) {
|
|
11041
|
+
const totalIncomingBytes = documents.reduce(
|
|
11042
|
+
(sum, d) => sum + Buffer.byteLength(d.content || "", "utf8"),
|
|
11043
|
+
0
|
|
11044
|
+
);
|
|
11045
|
+
const ingestCheck = FreeTierLimitsGuard.checkIngestionAllowed(
|
|
11046
|
+
{ documentCount: documents.length },
|
|
11047
|
+
totalIncomingBytes
|
|
11048
|
+
);
|
|
11049
|
+
if (!ingestCheck.allowed) {
|
|
11050
|
+
return createPaymentRequiredResponse(
|
|
11051
|
+
ingestCheck.reason || "Free tier ingestion limit reached.",
|
|
11052
|
+
{
|
|
11053
|
+
tier: licenseCheck.payload.tier,
|
|
11054
|
+
projectId: licenseCheck.payload.projectId,
|
|
11055
|
+
documents: documents.length,
|
|
11056
|
+
incomingBytes: totalIncomingBytes
|
|
11057
|
+
}
|
|
11058
|
+
);
|
|
11059
|
+
}
|
|
11060
|
+
}
|
|
10557
11061
|
const results = await plugin.ingest(documents, namespace);
|
|
10558
11062
|
reportTelemetry(req, plugin, "DOCUMENT_INGESTION", "success", `Ingested ${documents.length} document(s)`);
|
|
10559
11063
|
return import_server.NextResponse.json({ results });
|
|
@@ -10590,7 +11094,7 @@ function createLicenseHandler(configOrPlugin, options) {
|
|
|
10590
11094
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
10591
11095
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
10592
11096
|
return async function POST(req) {
|
|
10593
|
-
var
|
|
11097
|
+
var _a3;
|
|
10594
11098
|
if (req) {
|
|
10595
11099
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10596
11100
|
if (authResult) return authResult;
|
|
@@ -10598,7 +11102,8 @@ function createLicenseHandler(configOrPlugin, options) {
|
|
|
10598
11102
|
try {
|
|
10599
11103
|
const body = await req.json().catch(() => ({}));
|
|
10600
11104
|
const config = plugin.getConfig();
|
|
10601
|
-
const
|
|
11105
|
+
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 || "";
|
|
11106
|
+
const licenseKey = (rawKey || "").trim().replace(/^["']|["']$/g, "").trim();
|
|
10602
11107
|
const projectId = (body == null ? void 0 : body.projectId) || config.projectId || "my-rag-app";
|
|
10603
11108
|
const payload = LicenseVerifier.verify(licenseKey, projectId);
|
|
10604
11109
|
return import_server.NextResponse.json({
|
|
@@ -10632,6 +11137,9 @@ function createUploadHandler(configOrPlugin, options) {
|
|
|
10632
11137
|
return async function POST(req, context) {
|
|
10633
11138
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10634
11139
|
if (authResult) return authResult;
|
|
11140
|
+
const config = plugin.getConfig();
|
|
11141
|
+
const licenseCheck = enforceLicense(req, config);
|
|
11142
|
+
if (!licenseCheck.ok) return licenseCheck.response;
|
|
10635
11143
|
try {
|
|
10636
11144
|
const formData = await req.formData();
|
|
10637
11145
|
const files = formData.getAll("files");
|
|
@@ -10641,6 +11149,26 @@ function createUploadHandler(configOrPlugin, options) {
|
|
|
10641
11149
|
if (!files || files.length === 0) {
|
|
10642
11150
|
return import_server.NextResponse.json({ error: "No files provided" }, { status: 400 });
|
|
10643
11151
|
}
|
|
11152
|
+
if (isFreeTier(licenseCheck.payload.tier)) {
|
|
11153
|
+
const totalUploadBytes = files.reduce((sum, f) => sum + (f.size || 0), 0);
|
|
11154
|
+
const uploadCheck = FreeTierLimitsGuard.checkIngestionAllowed(
|
|
11155
|
+
{ documentCount: files.length },
|
|
11156
|
+
totalUploadBytes
|
|
11157
|
+
);
|
|
11158
|
+
if (!uploadCheck.allowed) {
|
|
11159
|
+
return createPaymentRequiredResponse(
|
|
11160
|
+
uploadCheck.reason || "Free tier upload limit reached.",
|
|
11161
|
+
{
|
|
11162
|
+
tier: licenseCheck.payload.tier,
|
|
11163
|
+
projectId: licenseCheck.payload.projectId,
|
|
11164
|
+
fileCount: files.length,
|
|
11165
|
+
totalUploadBytes,
|
|
11166
|
+
maxFileSizeBytes: FREE_TIER_QUOTAS.MAX_FILE_SIZE_BYTES,
|
|
11167
|
+
maxStorageBytes: FREE_TIER_QUOTAS.MAX_STORAGE_BYTES
|
|
11168
|
+
}
|
|
11169
|
+
);
|
|
11170
|
+
}
|
|
11171
|
+
}
|
|
10644
11172
|
const documents = [];
|
|
10645
11173
|
for (const file of files) {
|
|
10646
11174
|
const isExcel = file.name.toLowerCase().endsWith(".xlsx") || file.name.toLowerCase().endsWith(".xls") || file.type.includes("spreadsheet") || file.type.includes("excel");
|
|
@@ -10750,13 +11278,22 @@ function createSuggestionsHandler(configOrPlugin, options) {
|
|
|
10750
11278
|
return async function handler(req) {
|
|
10751
11279
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10752
11280
|
if (authResult) return authResult;
|
|
11281
|
+
const config = plugin.getConfig();
|
|
11282
|
+
const licenseCheck = enforceLicense(req, config);
|
|
11283
|
+
if (!licenseCheck.ok) return licenseCheck.response;
|
|
10753
11284
|
try {
|
|
10754
11285
|
let query = "";
|
|
10755
11286
|
let namespace = void 0;
|
|
11287
|
+
let bodyLicenseKey = void 0;
|
|
10756
11288
|
if (req.method === "POST") {
|
|
10757
11289
|
const body = await req.json().catch(() => ({}));
|
|
10758
11290
|
query = body.query || "";
|
|
10759
11291
|
namespace = body.namespace;
|
|
11292
|
+
bodyLicenseKey = body.licenseKey;
|
|
11293
|
+
if (bodyLicenseKey) {
|
|
11294
|
+
const recheck = enforceLicense(req, config, bodyLicenseKey);
|
|
11295
|
+
if (!recheck.ok) return recheck.response;
|
|
11296
|
+
}
|
|
10760
11297
|
} else {
|
|
10761
11298
|
const url = new URL(req.url);
|
|
10762
11299
|
query = url.searchParams.get("query") || "";
|
|
@@ -10779,14 +11316,16 @@ function createHistoryHandler(configOrPlugin, options) {
|
|
|
10779
11316
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
10780
11317
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
10781
11318
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
11319
|
+
const onResolveScope = options == null ? void 0 : options.onResolveScope;
|
|
10782
11320
|
return async function handler(req) {
|
|
10783
11321
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10784
11322
|
if (authResult) return authResult;
|
|
11323
|
+
const scope = onResolveScope ? await onResolveScope(req) : void 0;
|
|
10785
11324
|
const url = new URL(req.url);
|
|
10786
11325
|
const sessionId = url.searchParams.get("sessionId") || "default";
|
|
10787
11326
|
if (req.method === "GET") {
|
|
10788
11327
|
try {
|
|
10789
|
-
const history = await storage.getHistory(sessionId);
|
|
11328
|
+
const history = await storage.getHistory(sessionId, scope);
|
|
10790
11329
|
return import_server.NextResponse.json({ history });
|
|
10791
11330
|
} catch (err) {
|
|
10792
11331
|
const message = err instanceof Error ? err.message : "Failed to fetch history";
|
|
@@ -10796,7 +11335,7 @@ function createHistoryHandler(configOrPlugin, options) {
|
|
|
10796
11335
|
try {
|
|
10797
11336
|
const body = await req.json().catch(() => ({}));
|
|
10798
11337
|
const sid = body.sessionId || sessionId;
|
|
10799
|
-
await storage.clearHistory(sid);
|
|
11338
|
+
await storage.clearHistory(sid, scope);
|
|
10800
11339
|
return import_server.NextResponse.json({ success: true });
|
|
10801
11340
|
} catch (err) {
|
|
10802
11341
|
const message = err instanceof Error ? err.message : "Failed to clear history";
|
|
@@ -10810,18 +11349,20 @@ function createFeedbackHandler(configOrPlugin, options) {
|
|
|
10810
11349
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
10811
11350
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
10812
11351
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
11352
|
+
const onResolveScope = options == null ? void 0 : options.onResolveScope;
|
|
10813
11353
|
return async function handler(req) {
|
|
10814
11354
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10815
11355
|
if (authResult) return authResult;
|
|
11356
|
+
const scope = onResolveScope ? await onResolveScope(req) : void 0;
|
|
10816
11357
|
if (req.method === "GET") {
|
|
10817
11358
|
try {
|
|
10818
11359
|
const url = new URL(req.url);
|
|
10819
11360
|
const messageId = url.searchParams.get("messageId");
|
|
10820
11361
|
if (!messageId) {
|
|
10821
|
-
const feedbackList = await storage.listFeedback();
|
|
11362
|
+
const feedbackList = await storage.listFeedback(scope);
|
|
10822
11363
|
return import_server.NextResponse.json({ feedback: feedbackList });
|
|
10823
11364
|
}
|
|
10824
|
-
const feedback = await storage.getFeedback(messageId);
|
|
11365
|
+
const feedback = await storage.getFeedback(messageId, scope);
|
|
10825
11366
|
return import_server.NextResponse.json({ feedback });
|
|
10826
11367
|
} catch (err) {
|
|
10827
11368
|
const message = err instanceof Error ? err.message : "Failed to fetch feedback";
|
|
@@ -10837,6 +11378,17 @@ function createFeedbackHandler(configOrPlugin, options) {
|
|
|
10837
11378
|
if (!rating) {
|
|
10838
11379
|
return import_server.NextResponse.json({ error: "rating is required" }, { status: 400 });
|
|
10839
11380
|
}
|
|
11381
|
+
if (scope && scope.length > 0) {
|
|
11382
|
+
const matches = scope.some(
|
|
11383
|
+
(pid) => pid && (sessionId === pid || sessionId.startsWith(pid) || sessionId.includes(pid))
|
|
11384
|
+
);
|
|
11385
|
+
if (!matches) {
|
|
11386
|
+
return import_server.NextResponse.json(
|
|
11387
|
+
{ error: "sessionId is outside the authorized project scope" },
|
|
11388
|
+
{ status: 403 }
|
|
11389
|
+
);
|
|
11390
|
+
}
|
|
11391
|
+
}
|
|
10840
11392
|
await storage.saveFeedback({ messageId, sessionId, rating, comment });
|
|
10841
11393
|
return import_server.NextResponse.json({ success: true });
|
|
10842
11394
|
} catch (err) {
|
|
@@ -10851,14 +11403,15 @@ function createSessionsHandler(configOrPlugin, options) {
|
|
|
10851
11403
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
10852
11404
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
10853
11405
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
11406
|
+
const onResolveScope = options == null ? void 0 : options.onResolveScope;
|
|
10854
11407
|
return async function GET(req) {
|
|
10855
11408
|
if (req) {
|
|
10856
11409
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10857
11410
|
if (authResult) return authResult;
|
|
10858
11411
|
}
|
|
10859
|
-
void req;
|
|
10860
11412
|
try {
|
|
10861
|
-
const
|
|
11413
|
+
const scope = req && onResolveScope ? await onResolveScope(req) : void 0;
|
|
11414
|
+
const sessions = await storage.listSessions(scope);
|
|
10862
11415
|
return import_server.NextResponse.json({ sessions });
|
|
10863
11416
|
} catch (err) {
|
|
10864
11417
|
const message = err instanceof Error ? err.message : "Failed to list sessions";
|
|
@@ -10869,15 +11422,17 @@ function createSessionsHandler(configOrPlugin, options) {
|
|
|
10869
11422
|
function createRagHandler(configOrPlugin, options) {
|
|
10870
11423
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
10871
11424
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
10872
|
-
const
|
|
10873
|
-
const
|
|
10874
|
-
const
|
|
10875
|
-
const
|
|
10876
|
-
const
|
|
10877
|
-
const
|
|
10878
|
-
const
|
|
10879
|
-
const
|
|
10880
|
-
const
|
|
11425
|
+
const onResolveScope = options == null ? void 0 : options.onResolveScope;
|
|
11426
|
+
const scopeableOptions = { onAuthorize, onResolveScope };
|
|
11427
|
+
const chatHandler = createChatHandler(plugin, scopeableOptions);
|
|
11428
|
+
const streamHandler = createStreamHandler(plugin, scopeableOptions);
|
|
11429
|
+
const uploadHandler = createUploadHandler(plugin, scopeableOptions);
|
|
11430
|
+
const healthHandler = createHealthHandler(plugin, scopeableOptions);
|
|
11431
|
+
const suggestionsHandler = createSuggestionsHandler(plugin, scopeableOptions);
|
|
11432
|
+
const historyHandler = createHistoryHandler(plugin, scopeableOptions);
|
|
11433
|
+
const feedbackHandler = createFeedbackHandler(plugin, scopeableOptions);
|
|
11434
|
+
const sessionsHandler = createSessionsHandler(plugin, scopeableOptions);
|
|
11435
|
+
const licenseHandler = createLicenseHandler(plugin, scopeableOptions);
|
|
10881
11436
|
async function routePostRequest(req, segment) {
|
|
10882
11437
|
switch (segment) {
|
|
10883
11438
|
case "chat":
|
|
@@ -10919,7 +11474,7 @@ function createRagHandler(configOrPlugin, options) {
|
|
|
10919
11474
|
}
|
|
10920
11475
|
}
|
|
10921
11476
|
async function getSegment(req, context) {
|
|
10922
|
-
var
|
|
11477
|
+
var _a3, _b;
|
|
10923
11478
|
const contentType = req.headers.get("content-type") || "";
|
|
10924
11479
|
if (contentType.includes("multipart/form-data")) {
|
|
10925
11480
|
return "upload";
|
|
@@ -10936,7 +11491,7 @@ function createRagHandler(configOrPlugin, options) {
|
|
|
10936
11491
|
if (pathname.endsWith("/history")) return "history";
|
|
10937
11492
|
} catch (e) {
|
|
10938
11493
|
}
|
|
10939
|
-
const resolvedParams = typeof ((
|
|
11494
|
+
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;
|
|
10940
11495
|
const segments = (resolvedParams == null ? void 0 : resolvedParams.retrivora) || ((_b = resolvedParams == null ? void 0 : resolvedParams.params) == null ? void 0 : _b.retrivora) || [];
|
|
10941
11496
|
const joined = segments.join("/");
|
|
10942
11497
|
return joined || "chat";
|