@retrivora-ai/rag-engine 2.3.0 → 2.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{LicenseValidator-CENvo9o2.d.mts → BatchProcessor-7yV-UCHW.d.mts} +142 -3
- package/dist/{LicenseValidator-CsjJp2PP.d.ts → BatchProcessor-BfzuU4cK.d.ts} +142 -3
- package/dist/handlers/index.d.mts +1 -1
- package/dist/handlers/index.d.ts +1 -1
- package/dist/handlers/index.js +880 -327
- package/dist/handlers/index.mjs +880 -327
- package/dist/index-DR_O_B-W.d.ts +394 -0
- package/dist/index-fnpaCuma.d.mts +394 -0
- package/dist/index.css +58 -0
- package/dist/index.d.mts +63 -3
- package/dist/index.d.ts +63 -3
- package/dist/index.js +452 -35
- package/dist/index.mjs +451 -37
- package/dist/server.d.mts +35 -73
- package/dist/server.d.ts +35 -73
- package/dist/server.js +910 -341
- package/dist/server.mjs +910 -341
- package/package.json +1 -1
- package/src/components/ChatWidget.tsx +147 -46
- package/src/components/ChatWindow.tsx +52 -8
- package/src/core/BatchProcessor.ts +42 -4
- package/src/core/CircuitBreaker.ts +118 -0
- package/src/core/DatabaseStorage.ts +55 -24
- package/src/core/FreeTierLimitsGuard.ts +281 -0
- package/src/core/LicenseValidator.ts +66 -2
- package/src/core/LicenseVerifier.ts +31 -3
- package/src/core/VectorPlugin.ts +30 -0
- package/src/handlers/index.ts +491 -36
- package/src/index.css +58 -0
- package/src/index.ts +4 -0
- package/src/server.ts +1 -0
- package/dist/index-BPJ3KDYI.d.ts +0 -195
- package/dist/index-Dmq5lH0j.d.mts +0 -195
package/dist/handlers/index.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);
|
|
@@ -2559,8 +2559,8 @@ var UI_BORDER_RADIUS_OPTIONS = ["none", "sm", "md", "lg", "xl", "full"];
|
|
|
2559
2559
|
|
|
2560
2560
|
// src/config/serverConfig.ts
|
|
2561
2561
|
function readString(env, name) {
|
|
2562
|
-
var
|
|
2563
|
-
const value = (
|
|
2562
|
+
var _a3;
|
|
2563
|
+
const value = (_a3 = env[name]) == null ? void 0 : _a3.trim();
|
|
2564
2564
|
return value ? value : void 0;
|
|
2565
2565
|
}
|
|
2566
2566
|
function readNumber(env, name, fallback) {
|
|
@@ -2573,16 +2573,16 @@ function readNumber(env, name, fallback) {
|
|
|
2573
2573
|
return parsed;
|
|
2574
2574
|
}
|
|
2575
2575
|
function readEnum(env, name, fallback, allowed) {
|
|
2576
|
-
var
|
|
2577
|
-
const value = (
|
|
2576
|
+
var _a3;
|
|
2577
|
+
const value = (_a3 = readString(env, name)) != null ? _a3 : fallback;
|
|
2578
2578
|
if (allowed.includes(value)) {
|
|
2579
2579
|
return value;
|
|
2580
2580
|
}
|
|
2581
2581
|
throw new Error(`[getRagConfig] ${name} must be one of: ${allowed.join(", ")}`);
|
|
2582
2582
|
}
|
|
2583
2583
|
function getEnvConfig(env = process.env, base) {
|
|
2584
|
-
var
|
|
2585
|
-
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;
|
|
2586
2586
|
const jwtProjectId = (() => {
|
|
2587
2587
|
if (!licenseKey) return void 0;
|
|
2588
2588
|
try {
|
|
@@ -2663,7 +2663,7 @@ function getEnvConfig(env = process.env, base) {
|
|
|
2663
2663
|
rest: "default",
|
|
2664
2664
|
custom: "default"
|
|
2665
2665
|
};
|
|
2666
|
-
const
|
|
2666
|
+
const isFreeTier2 = (() => {
|
|
2667
2667
|
if (!licenseKey) return true;
|
|
2668
2668
|
try {
|
|
2669
2669
|
const payload = LicenseVerifier.verify(licenseKey, projectId);
|
|
@@ -2674,13 +2674,13 @@ function getEnvConfig(env = process.env, base) {
|
|
|
2674
2674
|
}
|
|
2675
2675
|
})();
|
|
2676
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";
|
|
2677
|
-
const defaultLlmProvider =
|
|
2677
|
+
const defaultLlmProvider = isFreeTier2 ? "universal_rest" : "universal_rest";
|
|
2678
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;
|
|
2679
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;
|
|
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 :
|
|
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";
|
|
2681
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;
|
|
2682
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";
|
|
2683
|
-
const defaultEmbeddingProvider =
|
|
2683
|
+
const defaultEmbeddingProvider = isFreeTier2 ? "universal_rest" : "universal_rest";
|
|
2684
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;
|
|
2685
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;
|
|
2686
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";
|
|
@@ -2770,8 +2770,8 @@ function getEnvConfig(env = process.env, base) {
|
|
|
2770
2770
|
}
|
|
2771
2771
|
} : {}), {
|
|
2772
2772
|
mcpServers: (() => {
|
|
2773
|
-
var
|
|
2774
|
-
const raw = (
|
|
2773
|
+
var _a4;
|
|
2774
|
+
const raw = (_a4 = readString(env, "MCP_SERVERS")) != null ? _a4 : readString(env, "NEXT_PUBLIC_MCP_SERVERS");
|
|
2775
2775
|
if (!raw) return void 0;
|
|
2776
2776
|
try {
|
|
2777
2777
|
return JSON.parse(raw);
|
|
@@ -2816,10 +2816,10 @@ var ConfigResolver = class {
|
|
|
2816
2816
|
* fallback behavior.
|
|
2817
2817
|
*/
|
|
2818
2818
|
static resolveUniversal(hostConfig, env = process.env) {
|
|
2819
|
-
var
|
|
2819
|
+
var _a3;
|
|
2820
2820
|
if (!hostConfig) return this.resolve(void 0, env);
|
|
2821
2821
|
const normalized = __spreadProps(__spreadValues({}, hostConfig), {
|
|
2822
|
-
vectorDb: (
|
|
2822
|
+
vectorDb: (_a3 = hostConfig.vectorDb) != null ? _a3 : hostConfig.vectorDatabase,
|
|
2823
2823
|
rag: this.mergeRetrievalWorkflow(hostConfig.rag, hostConfig.retrieval, hostConfig.workflow)
|
|
2824
2824
|
});
|
|
2825
2825
|
return this.resolve(normalized, env);
|
|
@@ -2839,11 +2839,11 @@ var ConfigResolver = class {
|
|
|
2839
2839
|
}
|
|
2840
2840
|
}
|
|
2841
2841
|
static mergeRetrievalWorkflow(rag, retrieval, workflow) {
|
|
2842
|
-
var
|
|
2842
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
2843
2843
|
if (!rag && !retrieval && !workflow) return void 0;
|
|
2844
2844
|
const normalized = __spreadValues({}, rag != null ? rag : {});
|
|
2845
2845
|
if (retrieval) {
|
|
2846
|
-
normalized.topK = (
|
|
2846
|
+
normalized.topK = (_a3 = retrieval.topK) != null ? _a3 : normalized.topK;
|
|
2847
2847
|
normalized.scoreThreshold = (_b = retrieval.scoreThreshold) != null ? _b : normalized.scoreThreshold;
|
|
2848
2848
|
normalized.useReranking = (_c = retrieval.useReranking) != null ? _c : normalized.useReranking;
|
|
2849
2849
|
if (retrieval.strategy === "hybrid") normalized.architecture = (_d = normalized.architecture) != null ? _d : "hybrid";
|
|
@@ -2971,8 +2971,8 @@ var OpenAIProvider = class {
|
|
|
2971
2971
|
};
|
|
2972
2972
|
}
|
|
2973
2973
|
async chat(messages, context, options) {
|
|
2974
|
-
var
|
|
2975
|
-
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.";
|
|
2976
2976
|
const systemMessage = {
|
|
2977
2977
|
role: "system",
|
|
2978
2978
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -2996,8 +2996,8 @@ var OpenAIProvider = class {
|
|
|
2996
2996
|
}
|
|
2997
2997
|
chatStream(messages, context, options) {
|
|
2998
2998
|
return __asyncGenerator(this, null, function* () {
|
|
2999
|
-
var
|
|
3000
|
-
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.";
|
|
3001
3001
|
const systemMessage = {
|
|
3002
3002
|
role: "system",
|
|
3003
3003
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3044,8 +3044,8 @@ var OpenAIProvider = class {
|
|
|
3044
3044
|
return results[0];
|
|
3045
3045
|
}
|
|
3046
3046
|
async batchEmbed(texts, options) {
|
|
3047
|
-
var
|
|
3048
|
-
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";
|
|
3049
3049
|
const apiKey = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.apiKey) != null ? _e : this.llmConfig.apiKey;
|
|
3050
3050
|
const client = apiKey !== this.llmConfig.apiKey ? new import_openai.default({ apiKey }) : this.client;
|
|
3051
3051
|
const response = await client.embeddings.create({ model, input: texts });
|
|
@@ -3122,8 +3122,8 @@ var AnthropicProvider = class {
|
|
|
3122
3122
|
};
|
|
3123
3123
|
}
|
|
3124
3124
|
async chat(messages, context, options) {
|
|
3125
|
-
var
|
|
3126
|
-
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.";
|
|
3127
3127
|
const system = buildSystemContent(basePrompt, context);
|
|
3128
3128
|
const anthropicMessages = messages.map((m) => ({
|
|
3129
3129
|
role: m.role === "assistant" ? "assistant" : "user",
|
|
@@ -3161,8 +3161,8 @@ var AnthropicProvider = class {
|
|
|
3161
3161
|
}
|
|
3162
3162
|
chatStream(messages, context, options) {
|
|
3163
3163
|
return __asyncGenerator(this, null, function* () {
|
|
3164
|
-
var
|
|
3165
|
-
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.";
|
|
3166
3166
|
const system = buildSystemContent(basePrompt, context);
|
|
3167
3167
|
const anthropicMessages = messages.map((m) => ({
|
|
3168
3168
|
role: m.role === "assistant" ? "assistant" : "user",
|
|
@@ -3246,8 +3246,8 @@ var AnthropicProvider = class {
|
|
|
3246
3246
|
var import_axios = __toESM(require("axios"));
|
|
3247
3247
|
var OllamaProvider = class {
|
|
3248
3248
|
constructor(llmConfig, embeddingConfig) {
|
|
3249
|
-
var
|
|
3250
|
-
const rawBaseURL = ((
|
|
3249
|
+
var _a3, _b, _c;
|
|
3250
|
+
const rawBaseURL = ((_a3 = llmConfig.baseUrl) != null ? _a3 : "http://localhost:11434").replace(/\/+$/, "");
|
|
3251
3251
|
const baseURL = rawBaseURL.replace(/\/(?:api\/v1|v1|api)$/i, "");
|
|
3252
3252
|
const timeout = Number((_b = llmConfig.options) == null ? void 0 : _b.timeout) || 3e5;
|
|
3253
3253
|
const headers = ((_c = llmConfig.options) == null ? void 0 : _c.headers) || {};
|
|
@@ -3307,8 +3307,8 @@ var OllamaProvider = class {
|
|
|
3307
3307
|
};
|
|
3308
3308
|
}
|
|
3309
3309
|
async chat(messages, context, options) {
|
|
3310
|
-
var
|
|
3311
|
-
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.";
|
|
3312
3312
|
const system = buildSystemContent(basePrompt, context);
|
|
3313
3313
|
const { data } = await this.http.post("/api/chat", {
|
|
3314
3314
|
model: this.llmConfig.model,
|
|
@@ -3326,8 +3326,8 @@ var OllamaProvider = class {
|
|
|
3326
3326
|
}
|
|
3327
3327
|
chatStream(messages, context, options) {
|
|
3328
3328
|
return __asyncGenerator(this, null, function* () {
|
|
3329
|
-
var
|
|
3330
|
-
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.";
|
|
3331
3331
|
const system = buildSystemContent(basePrompt, context);
|
|
3332
3332
|
const response = yield new __await(this.http.post("/api/chat", {
|
|
3333
3333
|
model: this.llmConfig.model,
|
|
@@ -3385,8 +3385,8 @@ var OllamaProvider = class {
|
|
|
3385
3385
|
});
|
|
3386
3386
|
}
|
|
3387
3387
|
async embed(text, options) {
|
|
3388
|
-
var
|
|
3389
|
-
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";
|
|
3390
3390
|
const baseURL = (_f = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.baseUrl) != null ? _e : this.llmConfig.baseUrl) != null ? _f : "http://localhost:11434";
|
|
3391
3391
|
const client = baseURL !== ((_g2 = this.llmConfig.baseUrl) != null ? _g2 : "http://localhost:11434") ? import_axios.default.create({ baseURL, timeout: 6e4 }) : this.http;
|
|
3392
3392
|
let prompt = text;
|
|
@@ -3487,9 +3487,9 @@ var GeminiProvider = class {
|
|
|
3487
3487
|
static getHealthChecker() {
|
|
3488
3488
|
return {
|
|
3489
3489
|
async check(config) {
|
|
3490
|
-
var
|
|
3490
|
+
var _a3, _b;
|
|
3491
3491
|
const timestamp = Date.now();
|
|
3492
|
-
const apiKey = (_b = (
|
|
3492
|
+
const apiKey = (_b = (_a3 = config.apiKey) != null ? _a3 : process.env.GOOGLE_GENAI_API_KEY) != null ? _b : "";
|
|
3493
3493
|
const modelName = sanitizeModel(config.model);
|
|
3494
3494
|
try {
|
|
3495
3495
|
const { GoogleGenerativeAI: GoogleGenerativeAI2 } = await import("@google/generative-ai");
|
|
@@ -3519,16 +3519,16 @@ var GeminiProvider = class {
|
|
|
3519
3519
|
/** Resolve the embedding client — uses a separate client when the embedding
|
|
3520
3520
|
* API key differs from the LLM API key. */
|
|
3521
3521
|
get embeddingClient() {
|
|
3522
|
-
var
|
|
3523
|
-
if (((
|
|
3522
|
+
var _a3;
|
|
3523
|
+
if (((_a3 = this.embeddingConfig) == null ? void 0 : _a3.apiKey) && this.embeddingConfig.apiKey !== this.llmConfig.apiKey) {
|
|
3524
3524
|
return buildClient(this.embeddingConfig.apiKey);
|
|
3525
3525
|
}
|
|
3526
3526
|
return this.client;
|
|
3527
3527
|
}
|
|
3528
3528
|
/** Resolve the embedding model to use, in order of specificity. */
|
|
3529
3529
|
resolveEmbeddingModel(optionsModel) {
|
|
3530
|
-
var
|
|
3531
|
-
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);
|
|
3532
3532
|
}
|
|
3533
3533
|
/**
|
|
3534
3534
|
* Convert ChatMessage[] to the Gemini contents format.
|
|
@@ -3548,8 +3548,8 @@ var GeminiProvider = class {
|
|
|
3548
3548
|
// ILLMProvider — chat
|
|
3549
3549
|
// -------------------------------------------------------------------------
|
|
3550
3550
|
async chat(messages, context, options) {
|
|
3551
|
-
var
|
|
3552
|
-
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.";
|
|
3553
3553
|
const model = this.client.getGenerativeModel({
|
|
3554
3554
|
model: this.llmConfig.model,
|
|
3555
3555
|
systemInstruction: buildSystemContent(basePrompt, context)
|
|
@@ -3566,8 +3566,8 @@ var GeminiProvider = class {
|
|
|
3566
3566
|
}
|
|
3567
3567
|
chatStream(messages, context, options) {
|
|
3568
3568
|
return __asyncGenerator(this, null, function* () {
|
|
3569
|
-
var
|
|
3570
|
-
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.";
|
|
3571
3571
|
const model = this.client.getGenerativeModel({
|
|
3572
3572
|
model: this.llmConfig.model,
|
|
3573
3573
|
systemInstruction: buildSystemContent(basePrompt, context)
|
|
@@ -3602,11 +3602,11 @@ var GeminiProvider = class {
|
|
|
3602
3602
|
// ILLMProvider — embeddings
|
|
3603
3603
|
// -------------------------------------------------------------------------
|
|
3604
3604
|
async embed(text, options) {
|
|
3605
|
-
var
|
|
3605
|
+
var _a3, _b;
|
|
3606
3606
|
const content = applyPrefix(
|
|
3607
3607
|
text,
|
|
3608
3608
|
options == null ? void 0 : options.taskType,
|
|
3609
|
-
(
|
|
3609
|
+
(_a3 = this.embeddingConfig) == null ? void 0 : _a3.queryPrefix,
|
|
3610
3610
|
(_b = this.embeddingConfig) == null ? void 0 : _b.documentPrefix
|
|
3611
3611
|
);
|
|
3612
3612
|
const modelName = this.resolveEmbeddingModel(options == null ? void 0 : options.model);
|
|
@@ -3623,7 +3623,7 @@ var GeminiProvider = class {
|
|
|
3623
3623
|
const modelName = this.resolveEmbeddingModel(options == null ? void 0 : options.model);
|
|
3624
3624
|
const model = this.embeddingClient.getGenerativeModel({ model: modelName });
|
|
3625
3625
|
const requests = texts.map((text) => {
|
|
3626
|
-
var
|
|
3626
|
+
var _a3, _b;
|
|
3627
3627
|
return {
|
|
3628
3628
|
content: {
|
|
3629
3629
|
role: "user",
|
|
@@ -3631,7 +3631,7 @@ var GeminiProvider = class {
|
|
|
3631
3631
|
text: applyPrefix(
|
|
3632
3632
|
text,
|
|
3633
3633
|
options == null ? void 0 : options.taskType,
|
|
3634
|
-
(
|
|
3634
|
+
(_a3 = this.embeddingConfig) == null ? void 0 : _a3.queryPrefix,
|
|
3635
3635
|
(_b = this.embeddingConfig) == null ? void 0 : _b.documentPrefix
|
|
3636
3636
|
)
|
|
3637
3637
|
}]
|
|
@@ -3648,8 +3648,8 @@ var GeminiProvider = class {
|
|
|
3648
3648
|
throw err;
|
|
3649
3649
|
});
|
|
3650
3650
|
return response.embeddings.map((e) => {
|
|
3651
|
-
var
|
|
3652
|
-
return (
|
|
3651
|
+
var _a3;
|
|
3652
|
+
return (_a3 = e.values) != null ? _a3 : [];
|
|
3653
3653
|
});
|
|
3654
3654
|
}
|
|
3655
3655
|
// -------------------------------------------------------------------------
|
|
@@ -3738,8 +3738,8 @@ var GroqProvider = class {
|
|
|
3738
3738
|
};
|
|
3739
3739
|
}
|
|
3740
3740
|
async chat(messages, context, options) {
|
|
3741
|
-
var
|
|
3742
|
-
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.";
|
|
3743
3743
|
const systemMessage = {
|
|
3744
3744
|
role: "system",
|
|
3745
3745
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3763,8 +3763,8 @@ var GroqProvider = class {
|
|
|
3763
3763
|
}
|
|
3764
3764
|
chatStream(messages, context, options) {
|
|
3765
3765
|
return __asyncGenerator(this, null, function* () {
|
|
3766
|
-
var
|
|
3767
|
-
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.";
|
|
3768
3768
|
const systemMessage = {
|
|
3769
3769
|
role: "system",
|
|
3770
3770
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3898,8 +3898,8 @@ var QwenProvider = class {
|
|
|
3898
3898
|
};
|
|
3899
3899
|
}
|
|
3900
3900
|
async chat(messages, context, options) {
|
|
3901
|
-
var
|
|
3902
|
-
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.";
|
|
3903
3903
|
const systemMessage = {
|
|
3904
3904
|
role: "system",
|
|
3905
3905
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3923,8 +3923,8 @@ var QwenProvider = class {
|
|
|
3923
3923
|
}
|
|
3924
3924
|
chatStream(messages, context, options) {
|
|
3925
3925
|
return __asyncGenerator(this, null, function* () {
|
|
3926
|
-
var
|
|
3927
|
-
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.";
|
|
3928
3928
|
const systemMessage = {
|
|
3929
3929
|
role: "system",
|
|
3930
3930
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3971,8 +3971,8 @@ var QwenProvider = class {
|
|
|
3971
3971
|
return results[0];
|
|
3972
3972
|
}
|
|
3973
3973
|
async batchEmbed(texts, options) {
|
|
3974
|
-
var
|
|
3975
|
-
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";
|
|
3976
3976
|
const apiKey = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.apiKey) != null ? _e : this.llmConfig.apiKey;
|
|
3977
3977
|
const client = apiKey !== this.llmConfig.apiKey ? new import_openai3.default({
|
|
3978
3978
|
apiKey,
|
|
@@ -4033,9 +4033,9 @@ var LLM_PROFILES = {
|
|
|
4033
4033
|
|
|
4034
4034
|
// src/llm/providers/UniversalLLMAdapter.ts
|
|
4035
4035
|
function extractContent(obj) {
|
|
4036
|
-
var
|
|
4036
|
+
var _a3, _b, _c;
|
|
4037
4037
|
if (!obj || typeof obj !== "object") return void 0;
|
|
4038
|
-
const choice = (
|
|
4038
|
+
const choice = (_a3 = obj.choices) == null ? void 0 : _a3[0];
|
|
4039
4039
|
if (!choice) return void 0;
|
|
4040
4040
|
if (typeof ((_b = choice.message) == null ? void 0 : _b.content) === "string") return choice.message.content;
|
|
4041
4041
|
if (typeof ((_c = choice.delta) == null ? void 0 : _c.content) === "string") return choice.delta.content;
|
|
@@ -4045,10 +4045,10 @@ function extractContent(obj) {
|
|
|
4045
4045
|
}
|
|
4046
4046
|
var UniversalLLMAdapter = class {
|
|
4047
4047
|
constructor(config) {
|
|
4048
|
-
var
|
|
4048
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h;
|
|
4049
4049
|
this.model = config.model;
|
|
4050
4050
|
const llmConfig = config;
|
|
4051
|
-
const options = (
|
|
4051
|
+
const options = (_a3 = llmConfig.options) != null ? _a3 : {};
|
|
4052
4052
|
let profile = {};
|
|
4053
4053
|
if (typeof options.profile === "string") {
|
|
4054
4054
|
profile = LLM_PROFILES[options.profile] || {};
|
|
@@ -4074,8 +4074,8 @@ var UniversalLLMAdapter = class {
|
|
|
4074
4074
|
});
|
|
4075
4075
|
}
|
|
4076
4076
|
async chat(messages, context) {
|
|
4077
|
-
var
|
|
4078
|
-
const path2 = (
|
|
4077
|
+
var _a3, _b, _c, _d, _e;
|
|
4078
|
+
const path2 = (_a3 = this.opts.chatPath) != null ? _a3 : "/chat/completions";
|
|
4079
4079
|
const safeMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
|
|
4080
4080
|
role: m.role || "user",
|
|
4081
4081
|
content: typeof m.content === "string" ? m.content : m.content != null ? String(m.content) : ""
|
|
@@ -4141,8 +4141,8 @@ ${context != null ? context : "None"}` },
|
|
|
4141
4141
|
*/
|
|
4142
4142
|
chatStream(messages, context) {
|
|
4143
4143
|
return __asyncGenerator(this, null, function* () {
|
|
4144
|
-
var
|
|
4145
|
-
const path2 = (
|
|
4144
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
4145
|
+
const path2 = (_a3 = this.opts.chatPath) != null ? _a3 : "/chat/completions";
|
|
4146
4146
|
const url = `${this.baseUrl.replace(/\/$/, "")}${path2}`;
|
|
4147
4147
|
const extractPath = ((_b = this.opts.responseExtractPath) != null ? _b : "choices[0].message.content").replace("message.content", "delta.content");
|
|
4148
4148
|
const safeMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
|
|
@@ -4268,8 +4268,8 @@ ${context != null ? context : "None"}` },
|
|
|
4268
4268
|
});
|
|
4269
4269
|
}
|
|
4270
4270
|
async embed(text) {
|
|
4271
|
-
var
|
|
4272
|
-
const path2 = (
|
|
4271
|
+
var _a3, _b, _c, _d, _e;
|
|
4272
|
+
const path2 = (_a3 = this.opts.embedPath) != null ? _a3 : "/embeddings";
|
|
4273
4273
|
const payload = this.opts.embedPayloadTemplate ? buildPayload(this.opts.embedPayloadTemplate, { input: text, model: this.model }) : { input: text, model: this.model };
|
|
4274
4274
|
try {
|
|
4275
4275
|
const { data: data2 } = await this.http.post(path2, payload);
|
|
@@ -4358,7 +4358,7 @@ var LLMFactory = class _LLMFactory {
|
|
|
4358
4358
|
];
|
|
4359
4359
|
}
|
|
4360
4360
|
static create(llmConfig, embeddingConfig) {
|
|
4361
|
-
var
|
|
4361
|
+
var _a3, _b, _c;
|
|
4362
4362
|
switch (llmConfig.provider) {
|
|
4363
4363
|
case "openai":
|
|
4364
4364
|
return new OpenAIProvider(llmConfig, embeddingConfig);
|
|
@@ -4377,7 +4377,7 @@ var LLMFactory = class _LLMFactory {
|
|
|
4377
4377
|
case "custom":
|
|
4378
4378
|
return new UniversalLLMAdapter(llmConfig);
|
|
4379
4379
|
default: {
|
|
4380
|
-
const providerName = String((
|
|
4380
|
+
const providerName = String((_a3 = llmConfig.provider) != null ? _a3 : "").toLowerCase();
|
|
4381
4381
|
const customFactory = customProviders.get(providerName);
|
|
4382
4382
|
if (customFactory) {
|
|
4383
4383
|
return customFactory(llmConfig);
|
|
@@ -4479,7 +4479,7 @@ var ProviderRegistry = class {
|
|
|
4479
4479
|
return null;
|
|
4480
4480
|
}
|
|
4481
4481
|
static async loadVectorProviderClass(provider) {
|
|
4482
|
-
var
|
|
4482
|
+
var _a3;
|
|
4483
4483
|
if (this.vectorProviders[provider]) return this.vectorProviders[provider];
|
|
4484
4484
|
switch (provider) {
|
|
4485
4485
|
case "pinecone": {
|
|
@@ -4488,7 +4488,7 @@ var ProviderRegistry = class {
|
|
|
4488
4488
|
}
|
|
4489
4489
|
case "pgvector":
|
|
4490
4490
|
case "postgresql": {
|
|
4491
|
-
const postgresMode = ((
|
|
4491
|
+
const postgresMode = ((_a3 = process.env.POSTGRES_MODE) != null ? _a3 : "multi").toLowerCase();
|
|
4492
4492
|
if (postgresMode === "single") {
|
|
4493
4493
|
const { PostgreSQLProvider: PostgreSQLProvider2 } = await Promise.resolve().then(() => (init_PostgreSQLProvider(), PostgreSQLProvider_exports));
|
|
4494
4494
|
return PostgreSQLProvider2;
|
|
@@ -4711,7 +4711,7 @@ var ConfigValidator = class {
|
|
|
4711
4711
|
// package.json
|
|
4712
4712
|
var package_default = {
|
|
4713
4713
|
name: "@retrivora-ai/rag-engine",
|
|
4714
|
-
version: "2.3.
|
|
4714
|
+
version: "2.3.1",
|
|
4715
4715
|
description: "Retrivora AI is a plug-and-play AI engine for RAG chat experiences \u2014 generic vector DB + LLM provider, embeddable or standalone.",
|
|
4716
4716
|
author: "Abhinav Alkuchi",
|
|
4717
4717
|
license: "UNLICENSED",
|
|
@@ -5016,8 +5016,8 @@ var Reranker = class {
|
|
|
5016
5016
|
return matches.sort((a, b) => b.score - a.score).slice(0, limit);
|
|
5017
5017
|
}
|
|
5018
5018
|
const scoredMatches = matches.map((match) => {
|
|
5019
|
-
var
|
|
5020
|
-
const contentLower = ((
|
|
5019
|
+
var _a3;
|
|
5020
|
+
const contentLower = ((_a3 = match == null ? void 0 : match.content) != null ? _a3 : "").toLowerCase();
|
|
5021
5021
|
let keywordScore = 0;
|
|
5022
5022
|
keywords.forEach((keyword) => {
|
|
5023
5023
|
if (contentLower.includes(keyword)) {
|
|
@@ -5039,8 +5039,8 @@ var Reranker = class {
|
|
|
5039
5039
|
|
|
5040
5040
|
Documents:
|
|
5041
5041
|
${topN.map((m, i) => {
|
|
5042
|
-
var
|
|
5043
|
-
return `[${i}] ${((
|
|
5042
|
+
var _a3;
|
|
5043
|
+
return `[${i}] ${((_a3 = m == null ? void 0 : m.content) != null ? _a3 : "").replace(/\n/g, " ")}`;
|
|
5044
5044
|
}).join("\n")}` }],
|
|
5045
5045
|
"",
|
|
5046
5046
|
{
|
|
@@ -5084,11 +5084,11 @@ var LlamaIndexIngestor = class {
|
|
|
5084
5084
|
* than standard character-count splitting.
|
|
5085
5085
|
*/
|
|
5086
5086
|
async chunk(text, options = {}) {
|
|
5087
|
-
var
|
|
5087
|
+
var _a3, _b;
|
|
5088
5088
|
try {
|
|
5089
5089
|
const { Document, SentenceSplitter, MetadataMode } = await import(`${"llamaindex"}`);
|
|
5090
5090
|
const splitter = new SentenceSplitter({
|
|
5091
|
-
chunkSize: (
|
|
5091
|
+
chunkSize: (_a3 = options.chunkSize) != null ? _a3 : 1e3,
|
|
5092
5092
|
chunkOverlap: (_b = options.chunkOverlap) != null ? _b : 200
|
|
5093
5093
|
});
|
|
5094
5094
|
const doc = new Document({ text, metadata: options.metadata || {} });
|
|
@@ -5197,7 +5197,7 @@ ${error instanceof Error ? error.message : String(error)}`
|
|
|
5197
5197
|
* The agent returns `{ messages: [...] }` — the last message is the final answer.
|
|
5198
5198
|
*/
|
|
5199
5199
|
async run(input, chatHistory = []) {
|
|
5200
|
-
var
|
|
5200
|
+
var _a3, _b, _c;
|
|
5201
5201
|
if (!this.agent) {
|
|
5202
5202
|
throw new Error("[LangChainAgent] Agent not initialized. Call initialize() first.");
|
|
5203
5203
|
}
|
|
@@ -5208,7 +5208,7 @@ ${error instanceof Error ? error.message : String(error)}`
|
|
|
5208
5208
|
const response = await this.agent.invoke({
|
|
5209
5209
|
messages: [...historyMessages, new HumanMessage(input)]
|
|
5210
5210
|
});
|
|
5211
|
-
const lastMessage = (
|
|
5211
|
+
const lastMessage = (_a3 = response == null ? void 0 : response.messages) == null ? void 0 : _a3.at(-1);
|
|
5212
5212
|
if (lastMessage && typeof lastMessage.content === "string") {
|
|
5213
5213
|
return lastMessage.content;
|
|
5214
5214
|
}
|
|
@@ -5260,7 +5260,7 @@ var MCPClient = class {
|
|
|
5260
5260
|
}
|
|
5261
5261
|
}
|
|
5262
5262
|
async connectStdio() {
|
|
5263
|
-
var
|
|
5263
|
+
var _a3;
|
|
5264
5264
|
const cmd = this.config.command;
|
|
5265
5265
|
if (!cmd) {
|
|
5266
5266
|
throw new Error(`[MCPClient] Command option is required for stdio transport on "${this.config.name}"`);
|
|
@@ -5275,7 +5275,7 @@ var MCPClient = class {
|
|
|
5275
5275
|
this.stdioBuffer += data.toString("utf-8");
|
|
5276
5276
|
this.processStdioLines();
|
|
5277
5277
|
});
|
|
5278
|
-
(
|
|
5278
|
+
(_a3 = this.childProcess.stderr) == null ? void 0 : _a3.on("data", (data) => {
|
|
5279
5279
|
console.warn(`[MCPClient] [stderr] [${this.config.name}]:`, data.toString("utf-8"));
|
|
5280
5280
|
});
|
|
5281
5281
|
this.childProcess.on("close", (code) => {
|
|
@@ -5350,14 +5350,14 @@ var MCPClient = class {
|
|
|
5350
5350
|
}
|
|
5351
5351
|
}
|
|
5352
5352
|
async sendNotification(method, params) {
|
|
5353
|
-
var
|
|
5353
|
+
var _a3;
|
|
5354
5354
|
const notification = {
|
|
5355
5355
|
jsonrpc: "2.0",
|
|
5356
5356
|
method,
|
|
5357
5357
|
params
|
|
5358
5358
|
};
|
|
5359
5359
|
if (this.config.transport === "stdio") {
|
|
5360
|
-
if ((
|
|
5360
|
+
if ((_a3 = this.childProcess) == null ? void 0 : _a3.stdin) {
|
|
5361
5361
|
this.childProcess.stdin.write(JSON.stringify(notification) + "\n", "utf-8");
|
|
5362
5362
|
}
|
|
5363
5363
|
} else if (this.sseUrl) {
|
|
@@ -5435,11 +5435,11 @@ var MCPRegistry = class {
|
|
|
5435
5435
|
// src/core/MultiAgentCoordinator.ts
|
|
5436
5436
|
var MultiAgentCoordinator = class {
|
|
5437
5437
|
constructor(options) {
|
|
5438
|
-
var
|
|
5438
|
+
var _a3;
|
|
5439
5439
|
this.llmProvider = options.llmProvider;
|
|
5440
5440
|
this.mcpRegistry = options.mcpRegistry;
|
|
5441
5441
|
this.documentSearch = options.documentSearch;
|
|
5442
|
-
this.maxIterations = (
|
|
5442
|
+
this.maxIterations = (_a3 = options.maxIterations) != null ? _a3 : 5;
|
|
5443
5443
|
}
|
|
5444
5444
|
/**
|
|
5445
5445
|
* Run the multi-agent coordination loop synchronously and return the final response.
|
|
@@ -5491,8 +5491,8 @@ Available Tools:
|
|
|
5491
5491
|
|
|
5492
5492
|
${mcpTools.length > 0 ? "MCP Server Tools:" : ""}
|
|
5493
5493
|
${mcpTools.map((mt) => {
|
|
5494
|
-
var
|
|
5495
|
-
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."}`;
|
|
5496
5496
|
}).join("\n")}
|
|
5497
5497
|
|
|
5498
5498
|
Tool Calling Protocol:
|
|
@@ -5650,6 +5650,100 @@ ${toolResultText}`
|
|
|
5650
5650
|
}
|
|
5651
5651
|
};
|
|
5652
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
|
+
|
|
5653
5747
|
// src/core/BatchProcessor.ts
|
|
5654
5748
|
function isTransientError(error) {
|
|
5655
5749
|
if (!(error instanceof Error)) return false;
|
|
@@ -5673,7 +5767,34 @@ function calculateBackoffDelay(attempt, initialDelayMs, maxDelayMs, multiplier)
|
|
|
5673
5767
|
function sleep(ms) {
|
|
5674
5768
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
5675
5769
|
}
|
|
5676
|
-
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
|
+
}
|
|
5677
5798
|
/**
|
|
5678
5799
|
* Processes an array of items in configurable batches with retry logic.
|
|
5679
5800
|
*
|
|
@@ -5714,7 +5835,7 @@ var BatchProcessor = class {
|
|
|
5714
5835
|
let lastError;
|
|
5715
5836
|
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
5716
5837
|
try {
|
|
5717
|
-
const result = await processor(batch);
|
|
5838
|
+
const result = await _BatchProcessor.executeWithCircuitBreaker(() => processor(batch));
|
|
5718
5839
|
results.push(result);
|
|
5719
5840
|
success = true;
|
|
5720
5841
|
break;
|
|
@@ -5772,7 +5893,7 @@ ${errorMessages}`
|
|
|
5772
5893
|
let lastError;
|
|
5773
5894
|
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
5774
5895
|
try {
|
|
5775
|
-
const result = await processor(item);
|
|
5896
|
+
const result = await _BatchProcessor.executeWithCircuitBreaker(() => processor(item));
|
|
5776
5897
|
results.push(result);
|
|
5777
5898
|
success = true;
|
|
5778
5899
|
break;
|
|
@@ -5845,7 +5966,7 @@ ${errorMessages}`
|
|
|
5845
5966
|
}));
|
|
5846
5967
|
const chunkPromises = chunk.map(async ({ item, originalIndex }) => {
|
|
5847
5968
|
try {
|
|
5848
|
-
const result = await processor(item);
|
|
5969
|
+
const result = await _BatchProcessor.executeWithCircuitBreaker(() => processor(item));
|
|
5849
5970
|
return { success: true, result, index: originalIndex };
|
|
5850
5971
|
} catch (err) {
|
|
5851
5972
|
const error = err instanceof Error ? err : new Error(String(err));
|
|
@@ -5873,6 +5994,12 @@ ${errorMessages}`
|
|
|
5873
5994
|
return { results, errors, totalProcessed, totalFailed };
|
|
5874
5995
|
}
|
|
5875
5996
|
};
|
|
5997
|
+
_BatchProcessor.cb = new CircuitBreaker({
|
|
5998
|
+
failureThreshold: 5,
|
|
5999
|
+
resetTimeoutMs: 3e4,
|
|
6000
|
+
halfOpenMaxCalls: 1
|
|
6001
|
+
});
|
|
6002
|
+
var BatchProcessor = _BatchProcessor;
|
|
5876
6003
|
|
|
5877
6004
|
// src/config/EmbeddingStrategy.ts
|
|
5878
6005
|
var EmbeddingStrategyResolver = class {
|
|
@@ -5970,7 +6097,7 @@ var QueryProcessor = class {
|
|
|
5970
6097
|
* @param validFields Optional list of known filterable fields to look for
|
|
5971
6098
|
*/
|
|
5972
6099
|
static extractQueryFieldHints(question, validFields = []) {
|
|
5973
|
-
var
|
|
6100
|
+
var _a3, _b, _c, _d;
|
|
5974
6101
|
if (!question.trim()) return [];
|
|
5975
6102
|
const hints = /* @__PURE__ */ new Map();
|
|
5976
6103
|
const addHint = (value, field) => {
|
|
@@ -6050,7 +6177,7 @@ var QueryProcessor = class {
|
|
|
6050
6177
|
];
|
|
6051
6178
|
for (const p of universalPatterns) {
|
|
6052
6179
|
for (const match of question.matchAll(p.regex)) {
|
|
6053
|
-
const val = p.group ? (
|
|
6180
|
+
const val = p.group ? (_a3 = match[p.group]) != null ? _a3 : match[0] : match[0];
|
|
6054
6181
|
if (!val) continue;
|
|
6055
6182
|
if (p.field) addHint(val, p.field);
|
|
6056
6183
|
else addHint(val);
|
|
@@ -6274,11 +6401,11 @@ var LLMRouter = class {
|
|
|
6274
6401
|
* When provided it is used directly as the 'default' role without re-constructing.
|
|
6275
6402
|
*/
|
|
6276
6403
|
async initialize(prebuiltDefault) {
|
|
6277
|
-
var
|
|
6404
|
+
var _a3;
|
|
6278
6405
|
const defaultModel = prebuiltDefault != null ? prebuiltDefault : LLMFactory.create(this.config.llm, this.config.embedding);
|
|
6279
6406
|
this.models.set("default", defaultModel);
|
|
6280
6407
|
const envFastModel = process.env.FAST_LLM_MODEL;
|
|
6281
|
-
const providerFastDefault = (
|
|
6408
|
+
const providerFastDefault = (_a3 = FAST_MODEL_DEFAULTS[this.config.llm.provider]) != null ? _a3 : "";
|
|
6282
6409
|
const fastModelName = envFastModel || providerFastDefault;
|
|
6283
6410
|
if (fastModelName && fastModelName !== this.config.llm.model) {
|
|
6284
6411
|
console.log(`[LLMRouter] Fast role \u2192 provider="${this.config.llm.provider}" model="${fastModelName}"`);
|
|
@@ -6297,8 +6424,8 @@ var LLMRouter = class {
|
|
|
6297
6424
|
* Falls back to 'default' if the requested role is not registered.
|
|
6298
6425
|
*/
|
|
6299
6426
|
get(role) {
|
|
6300
|
-
var
|
|
6301
|
-
const provider = (
|
|
6427
|
+
var _a3;
|
|
6428
|
+
const provider = (_a3 = this.models.get(role)) != null ? _a3 : this.models.get("default");
|
|
6302
6429
|
if (!provider) {
|
|
6303
6430
|
throw new Error(`[LLMRouter] No provider registered for role: "${role}". Did you call initialize()?`);
|
|
6304
6431
|
}
|
|
@@ -6384,8 +6511,8 @@ var IntentClassifier = class {
|
|
|
6384
6511
|
numericFieldCount = numericKeys.size;
|
|
6385
6512
|
categoricalFieldCount = catKeys.size;
|
|
6386
6513
|
if (productKeyMatches >= 2 || docs.some((d) => {
|
|
6387
|
-
var
|
|
6388
|
-
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");
|
|
6389
6516
|
})) {
|
|
6390
6517
|
isProductLike = true;
|
|
6391
6518
|
}
|
|
@@ -6667,8 +6794,8 @@ var TextRendererStrategy = class {
|
|
|
6667
6794
|
}
|
|
6668
6795
|
const docs = Array.isArray(data) ? data : [];
|
|
6669
6796
|
const text = docs.map((d) => {
|
|
6670
|
-
var
|
|
6671
|
-
return (
|
|
6797
|
+
var _a3;
|
|
6798
|
+
return (_a3 = d == null ? void 0 : d.content) != null ? _a3 : "";
|
|
6672
6799
|
}).join("\n\n");
|
|
6673
6800
|
return { type: "text", title, data: { content: text || "No detailed content available." } };
|
|
6674
6801
|
}
|
|
@@ -6811,9 +6938,9 @@ var LRUDecisionCache = class {
|
|
|
6811
6938
|
this.maxSize = maxSize;
|
|
6812
6939
|
}
|
|
6813
6940
|
generateKey(context) {
|
|
6814
|
-
var
|
|
6941
|
+
var _a3, _b;
|
|
6815
6942
|
const q = (context.userQuery || "").toLowerCase().trim();
|
|
6816
|
-
const docCount = (_b = (
|
|
6943
|
+
const docCount = (_b = (_a3 = context.retrievedDocuments) == null ? void 0 : _a3.length) != null ? _b : 0;
|
|
6817
6944
|
return `${q}::docs:${docCount}`;
|
|
6818
6945
|
}
|
|
6819
6946
|
get(context) {
|
|
@@ -6914,7 +7041,7 @@ var UITransformer = class _UITransformer {
|
|
|
6914
7041
|
* Prefer `analyzeAndDecide()` in production.
|
|
6915
7042
|
*/
|
|
6916
7043
|
static transform(userQuery, retrievedData, config, trainedSchema, intent) {
|
|
6917
|
-
var
|
|
7044
|
+
var _a3, _b, _c;
|
|
6918
7045
|
if (!retrievedData || retrievedData.length === 0) {
|
|
6919
7046
|
return this.createTextResponse("No data available", "No relevant data found for your query.");
|
|
6920
7047
|
}
|
|
@@ -6934,7 +7061,7 @@ var UITransformer = class _UITransformer {
|
|
|
6934
7061
|
return this.transformToBarChart(filteredData, profile, userQuery, resolvedIntent.visualizationHint === "ranking");
|
|
6935
7062
|
}
|
|
6936
7063
|
if (resolvedIntent.visualizationHint === "distribution") {
|
|
6937
|
-
return (
|
|
7064
|
+
return (_a3 = this.transformToHistogram(profile, userQuery)) != null ? _a3 : this.transformToBarChart(filteredData, profile, userQuery);
|
|
6938
7065
|
}
|
|
6939
7066
|
if (resolvedIntent.visualizationHint === "correlation") {
|
|
6940
7067
|
return (_b = this.transformToScatterPlot(profile, userQuery)) != null ? _b : this.transformToBarChart(filteredData, profile, userQuery);
|
|
@@ -7267,11 +7394,11 @@ ${schemaProfileText}` : ""}`;
|
|
|
7267
7394
|
};
|
|
7268
7395
|
}
|
|
7269
7396
|
static transformToPieChart(data, profile, query = "") {
|
|
7270
|
-
var
|
|
7397
|
+
var _a3;
|
|
7271
7398
|
const dimension = profile ? this.selectDimensionField(profile, query) : void 0;
|
|
7272
7399
|
const categories = dimension ? Array.from(new Set(profile.records.map((record) => {
|
|
7273
|
-
var
|
|
7274
|
-
return String((
|
|
7400
|
+
var _a4;
|
|
7401
|
+
return String((_a4 = record.fields[dimension.key]) != null ? _a4 : "");
|
|
7275
7402
|
}).filter(Boolean))) : this.detectCategories(data);
|
|
7276
7403
|
if (categories.length === 0) return null;
|
|
7277
7404
|
const categoryData = dimension && profile ? this.aggregateProfileByDimension(profile, dimension.key) : this.aggregateByCategory(data, categories);
|
|
@@ -7281,7 +7408,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7281
7408
|
});
|
|
7282
7409
|
return {
|
|
7283
7410
|
type: "pie_chart",
|
|
7284
|
-
title: `Distribution by ${(
|
|
7411
|
+
title: `Distribution by ${(_a3 = dimension == null ? void 0 : dimension.label) != null ? _a3 : "Category"}`,
|
|
7285
7412
|
description: `Showing breakdown across ${pieData.length} categories`,
|
|
7286
7413
|
data: pieData
|
|
7287
7414
|
};
|
|
@@ -7291,8 +7418,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7291
7418
|
const valueField = profile.numericFields[0];
|
|
7292
7419
|
const buckets = /* @__PURE__ */ new Map();
|
|
7293
7420
|
profile.records.forEach((record) => {
|
|
7294
|
-
var
|
|
7295
|
-
const timestamp = String((
|
|
7421
|
+
var _a3, _b, _c;
|
|
7422
|
+
const timestamp = String((_a3 = record.fields[dateField.key]) != null ? _a3 : "");
|
|
7296
7423
|
const value = (_b = this.toFiniteNumber(record.fields[valueField.key])) != null ? _b : 0;
|
|
7297
7424
|
buckets.set(timestamp, ((_c = buckets.get(timestamp)) != null ? _c : 0) + value);
|
|
7298
7425
|
});
|
|
@@ -7305,23 +7432,23 @@ ${schemaProfileText}` : ""}`;
|
|
|
7305
7432
|
};
|
|
7306
7433
|
}
|
|
7307
7434
|
static transformToBarChart(data, profile, query = "", horizontal = false) {
|
|
7308
|
-
var
|
|
7435
|
+
var _a3;
|
|
7309
7436
|
const dimension = profile ? this.selectDimensionField(profile, query) : void 0;
|
|
7310
7437
|
const measure = profile ? this.selectNumericField(profile, query) : void 0;
|
|
7311
7438
|
const aggregate = dimension && profile ? this.aggregateProfileByDimension(profile, dimension.key, measure == null ? void 0 : measure.key) : this.aggregateByCategory(data, this.detectCategories(data));
|
|
7312
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);
|
|
7313
7440
|
const fallbackData = barData.length > 0 ? barData : data.slice(0, 12).map((item, index) => {
|
|
7314
|
-
var
|
|
7441
|
+
var _a4, _b, _c, _d, _e;
|
|
7315
7442
|
const meta = item.metadata || {};
|
|
7316
7443
|
const label = String(
|
|
7317
|
-
(_c = (_b = (
|
|
7444
|
+
(_c = (_b = (_a4 = this.getDynamicVal(meta, "name")) != null ? _a4 : meta.label) != null ? _b : meta.title) != null ? _c : `Result ${index + 1}`
|
|
7318
7445
|
);
|
|
7319
7446
|
const value = (_e = (_d = this.extractNumericValue(meta)) != null ? _d : item.score) != null ? _e : 0;
|
|
7320
7447
|
return { category: label, value: Number(value) };
|
|
7321
7448
|
});
|
|
7322
7449
|
return {
|
|
7323
7450
|
type: horizontal ? "horizontal_bar" : "bar_chart",
|
|
7324
|
-
title: dimension ? `${(
|
|
7451
|
+
title: dimension ? `${(_a3 = measure == null ? void 0 : measure.label) != null ? _a3 : "Count"} by ${dimension.label}` : "Comparison",
|
|
7325
7452
|
description: `Showing ${fallbackData.length} comparable values`,
|
|
7326
7453
|
data: fallbackData
|
|
7327
7454
|
};
|
|
@@ -7356,11 +7483,11 @@ ${schemaProfileText}` : ""}`;
|
|
|
7356
7483
|
if (fields.length < 2) return null;
|
|
7357
7484
|
const [xField, yField] = fields;
|
|
7358
7485
|
const points = profile.records.map((record) => {
|
|
7359
|
-
var
|
|
7486
|
+
var _a3;
|
|
7360
7487
|
const x = this.toFiniteNumber(record.fields[xField.key]);
|
|
7361
7488
|
const y = this.toFiniteNumber(record.fields[yField.key]);
|
|
7362
7489
|
if (x === null || y === null) return null;
|
|
7363
|
-
return { x, y, label: String((
|
|
7490
|
+
return { x, y, label: String((_a3 = this.getRecordLabel(record)) != null ? _a3 : record.id) };
|
|
7364
7491
|
}).filter((point) => point !== null).slice(0, 100);
|
|
7365
7492
|
if (points.length === 0) return null;
|
|
7366
7493
|
return {
|
|
@@ -7390,9 +7517,9 @@ ${schemaProfileText}` : ""}`;
|
|
|
7390
7517
|
static transformToRadarChart(data) {
|
|
7391
7518
|
const attributeMap = {};
|
|
7392
7519
|
data.forEach((item) => {
|
|
7393
|
-
var
|
|
7520
|
+
var _a3, _b, _c;
|
|
7394
7521
|
const meta = item.metadata || {};
|
|
7395
|
-
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");
|
|
7396
7523
|
Object.entries(meta).forEach(([key, val]) => {
|
|
7397
7524
|
if (typeof val === "number" && !["price", "id"].includes(key.toLowerCase())) {
|
|
7398
7525
|
if (!attributeMap[key]) attributeMap[key] = {};
|
|
@@ -7408,8 +7535,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7408
7535
|
title: "Product Comparison",
|
|
7409
7536
|
description: `Comparing ${data.length} items across ${radarData.length} attributes`,
|
|
7410
7537
|
data: radarData.length > 0 ? radarData : data.map((d) => {
|
|
7411
|
-
var
|
|
7412
|
-
return { attribute: ((
|
|
7538
|
+
var _a3;
|
|
7539
|
+
return { attribute: ((_a3 = d == null ? void 0 : d.content) != null ? _a3 : "").substring(0, 40) };
|
|
7413
7540
|
})
|
|
7414
7541
|
};
|
|
7415
7542
|
}
|
|
@@ -7428,8 +7555,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7428
7555
|
return this.createTextResponse(
|
|
7429
7556
|
"Retrieved Context",
|
|
7430
7557
|
data.map((item) => {
|
|
7431
|
-
var
|
|
7432
|
-
return (
|
|
7558
|
+
var _a3;
|
|
7559
|
+
return (_a3 = item == null ? void 0 : item.content) != null ? _a3 : "";
|
|
7433
7560
|
}).join("\n\n"),
|
|
7434
7561
|
`Found ${data.length} relevant results`
|
|
7435
7562
|
);
|
|
@@ -7480,11 +7607,11 @@ ${schemaProfileText}` : ""}`;
|
|
|
7480
7607
|
return null;
|
|
7481
7608
|
}
|
|
7482
7609
|
static normalizeTransformation(payload) {
|
|
7483
|
-
var
|
|
7610
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j;
|
|
7484
7611
|
if (!payload || typeof payload !== "object") return null;
|
|
7485
7612
|
const p = payload;
|
|
7486
7613
|
const type = this.normalizeVisualizationType(
|
|
7487
|
-
String((_c = (_b = (
|
|
7614
|
+
String((_c = (_b = (_a3 = p.type) != null ? _a3 : p.view) != null ? _b : p.chartType) != null ? _c : "")
|
|
7488
7615
|
);
|
|
7489
7616
|
if (!type) return null;
|
|
7490
7617
|
const title = String((_e = (_d = p.title) != null ? _d : p.heading) != null ? _e : "Visualization");
|
|
@@ -7495,7 +7622,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7495
7622
|
return this.validateTransformation(transformation) ? transformation : null;
|
|
7496
7623
|
}
|
|
7497
7624
|
static normalizeVisualizationType(type) {
|
|
7498
|
-
var
|
|
7625
|
+
var _a3;
|
|
7499
7626
|
const mapping = {
|
|
7500
7627
|
pie: "pie_chart",
|
|
7501
7628
|
pie_chart: "pie_chart",
|
|
@@ -7523,7 +7650,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7523
7650
|
product_carousel: "product_carousel",
|
|
7524
7651
|
carousel: "carousel"
|
|
7525
7652
|
};
|
|
7526
|
-
return (
|
|
7653
|
+
return (_a3 = mapping[type.toLowerCase()]) != null ? _a3 : null;
|
|
7527
7654
|
}
|
|
7528
7655
|
static validateTransformation(t) {
|
|
7529
7656
|
const { type, data } = t;
|
|
@@ -7639,7 +7766,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7639
7766
|
}
|
|
7640
7767
|
static profileData(data) {
|
|
7641
7768
|
const records = (data || []).filter((item) => Boolean(item && typeof item === "object")).map((item) => {
|
|
7642
|
-
var
|
|
7769
|
+
var _a3, _b;
|
|
7643
7770
|
const fields2 = {};
|
|
7644
7771
|
Object.entries(item.metadata || {}).forEach(([key, value]) => {
|
|
7645
7772
|
const primitive = this.toPrimitive(value);
|
|
@@ -7648,7 +7775,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7648
7775
|
if (!fields2.content && item.content) fields2.content = item.content.substring(0, 500);
|
|
7649
7776
|
return {
|
|
7650
7777
|
id: item.id,
|
|
7651
|
-
content: (
|
|
7778
|
+
content: (_a3 = item.content) != null ? _a3 : "",
|
|
7652
7779
|
score: (_b = item.score) != null ? _b : 0,
|
|
7653
7780
|
fields: fields2,
|
|
7654
7781
|
source: item
|
|
@@ -7729,16 +7856,16 @@ ${schemaProfileText}` : ""}`;
|
|
|
7729
7856
|
return null;
|
|
7730
7857
|
}
|
|
7731
7858
|
static selectDimensionField(profile, query) {
|
|
7732
|
-
var
|
|
7859
|
+
var _a3, _b;
|
|
7733
7860
|
const productCategory = profile.categoricalFields.find(
|
|
7734
7861
|
(field) => /category|department|collection|type|group|segment|region|country|state|city/i.test(field.key)
|
|
7735
7862
|
);
|
|
7736
7863
|
const ranked = this.rankFieldsByQuery(profile.categoricalFields, query);
|
|
7737
|
-
return (_b = (
|
|
7864
|
+
return (_b = (_a3 = ranked[0]) != null ? _a3 : productCategory) != null ? _b : profile.categoricalFields[0];
|
|
7738
7865
|
}
|
|
7739
7866
|
static selectNumericField(profile, query) {
|
|
7740
|
-
var
|
|
7741
|
-
return (
|
|
7867
|
+
var _a3;
|
|
7868
|
+
return (_a3 = this.rankFieldsByQuery(profile.numericFields, query)[0]) != null ? _a3 : profile.numericFields[0];
|
|
7742
7869
|
}
|
|
7743
7870
|
static rankFieldsByQuery(fields, query) {
|
|
7744
7871
|
const q = query.toLowerCase();
|
|
@@ -7767,8 +7894,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7767
7894
|
static aggregateProfileByDimension(profile, dimensionKey, measureKey) {
|
|
7768
7895
|
const result = {};
|
|
7769
7896
|
profile.records.forEach((record) => {
|
|
7770
|
-
var
|
|
7771
|
-
const category = String((
|
|
7897
|
+
var _a3, _b, _c;
|
|
7898
|
+
const category = String((_a3 = record.fields[dimensionKey]) != null ? _a3 : "Other").trim() || "Other";
|
|
7772
7899
|
const value = measureKey ? (_b = this.toFiniteNumber(record.fields[measureKey])) != null ? _b : 0 : 1;
|
|
7773
7900
|
result[category] = ((_c = result[category]) != null ? _c : 0) + value;
|
|
7774
7901
|
});
|
|
@@ -7848,8 +7975,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7848
7975
|
static aggregateByCategory(data, categories) {
|
|
7849
7976
|
const result = Object.fromEntries(categories.map((c) => [c, 0]));
|
|
7850
7977
|
data.forEach((item) => {
|
|
7851
|
-
var
|
|
7852
|
-
const cat = (
|
|
7978
|
+
var _a3;
|
|
7979
|
+
const cat = (_a3 = this.getProductCategory(item)) != null ? _a3 : "Other";
|
|
7853
7980
|
if (Object.prototype.hasOwnProperty.call(result, cat)) result[cat]++;
|
|
7854
7981
|
else result["Other"] = (result["Other"] || 0) + 1;
|
|
7855
7982
|
});
|
|
@@ -7857,17 +7984,17 @@ ${schemaProfileText}` : ""}`;
|
|
|
7857
7984
|
}
|
|
7858
7985
|
static extractTimeSeriesData(data) {
|
|
7859
7986
|
return data.map((item) => {
|
|
7860
|
-
var
|
|
7987
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
7861
7988
|
const meta = item.metadata || {};
|
|
7862
7989
|
return {
|
|
7863
|
-
timestamp: (_b = (
|
|
7990
|
+
timestamp: (_b = (_a3 = meta.timestamp) != null ? _a3 : meta.date) != null ? _b : (/* @__PURE__ */ new Date()).toISOString(),
|
|
7864
7991
|
value: (_d = (_c = meta.value) != null ? _c : item.score) != null ? _d : 0,
|
|
7865
7992
|
label: (_f = meta.label) != null ? _f : ((_e = item == null ? void 0 : item.content) != null ? _e : "").substring(0, 50)
|
|
7866
7993
|
};
|
|
7867
7994
|
});
|
|
7868
7995
|
}
|
|
7869
7996
|
static extractNumericValue(meta) {
|
|
7870
|
-
var
|
|
7997
|
+
var _a3;
|
|
7871
7998
|
const preferredKeys = [
|
|
7872
7999
|
"value",
|
|
7873
8000
|
"count",
|
|
@@ -7882,7 +8009,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7882
8009
|
"price"
|
|
7883
8010
|
];
|
|
7884
8011
|
for (const key of preferredKeys) {
|
|
7885
|
-
const raw = (
|
|
8012
|
+
const raw = (_a3 = resolveMetadataValue(meta, key)) != null ? _a3 : meta[key];
|
|
7886
8013
|
const value = typeof raw === "number" ? raw : Number(String(raw != null ? raw : "").replace(/[$,% ,]/g, ""));
|
|
7887
8014
|
if (Number.isFinite(value)) return value;
|
|
7888
8015
|
}
|
|
@@ -7977,8 +8104,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7977
8104
|
}, query.includes(normalizedField) ? 3 : 0);
|
|
7978
8105
|
}
|
|
7979
8106
|
static resolveTableCellValue(item, column) {
|
|
7980
|
-
var
|
|
7981
|
-
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);
|
|
7982
8109
|
const meta = item.metadata || {};
|
|
7983
8110
|
const normalizedColumn = this.normalizeComparableField(column);
|
|
7984
8111
|
const exactMetadata = Object.entries(meta).find(
|
|
@@ -8030,8 +8157,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
8030
8157
|
let inStock = 0;
|
|
8031
8158
|
let outOfStock = 0;
|
|
8032
8159
|
data.forEach((d) => {
|
|
8033
|
-
var
|
|
8034
|
-
const cat = (
|
|
8160
|
+
var _a3, _b;
|
|
8161
|
+
const cat = (_a3 = this.getProductCategory(d)) != null ? _a3 : "Other";
|
|
8035
8162
|
if (cat === category) {
|
|
8036
8163
|
const quantity = (_b = this.extractStockQuantity(d)) != null ? _b : 1;
|
|
8037
8164
|
if (this.determineStockStatus(d)) inStock += quantity;
|
|
@@ -8077,9 +8204,9 @@ ${schemaProfileText}` : ""}`;
|
|
|
8077
8204
|
}
|
|
8078
8205
|
// ─── Product Extraction ───────────────────────────────────────────────────
|
|
8079
8206
|
static getDynamicVal(meta, uiKey, config, trainedSchema) {
|
|
8080
|
-
var
|
|
8207
|
+
var _a3;
|
|
8081
8208
|
if (!meta) return void 0;
|
|
8082
|
-
const mapping = (
|
|
8209
|
+
const mapping = (_a3 = config == null ? void 0 : config.rag) == null ? void 0 : _a3.uiMapping;
|
|
8083
8210
|
if ((mapping == null ? void 0 : mapping[uiKey]) && meta[mapping[uiKey]] !== void 0) return meta[mapping[uiKey]];
|
|
8084
8211
|
if (trainedSchema && typeof trainedSchema === "object") {
|
|
8085
8212
|
const trainedKey = trainedSchema[uiKey];
|
|
@@ -8088,7 +8215,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
8088
8215
|
return resolveMetadataValue(meta, uiKey);
|
|
8089
8216
|
}
|
|
8090
8217
|
static extractProductInfo(item, config, trainedSchema) {
|
|
8091
|
-
var
|
|
8218
|
+
var _a3, _b;
|
|
8092
8219
|
if (!item) return null;
|
|
8093
8220
|
const meta = item.metadata || {};
|
|
8094
8221
|
const content = item.content || "";
|
|
@@ -8096,7 +8223,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
8096
8223
|
const price = this.getDynamicVal(meta, "price", config, trainedSchema);
|
|
8097
8224
|
const brand = this.getDynamicVal(meta, "brand", config, trainedSchema);
|
|
8098
8225
|
const description = this.cleanProductDescription(
|
|
8099
|
-
(
|
|
8226
|
+
(_a3 = this.extractProductDescriptionFromContent(content)) != null ? _a3 : this.getProductDescriptionValue(meta, config, trainedSchema)
|
|
8100
8227
|
);
|
|
8101
8228
|
if (name || this.isProductData(item)) {
|
|
8102
8229
|
let finalName = name ? String(name) : void 0;
|
|
@@ -8231,10 +8358,10 @@ RULES:
|
|
|
8231
8358
|
}
|
|
8232
8359
|
static buildContextSummary(sources, maxChars = 6e3) {
|
|
8233
8360
|
const items = (sources || []).filter(Boolean).map((s, i) => {
|
|
8234
|
-
var
|
|
8361
|
+
var _a3, _b, _c, _d;
|
|
8235
8362
|
return {
|
|
8236
8363
|
index: i + 1,
|
|
8237
|
-
content: (_b = (
|
|
8364
|
+
content: (_b = (_a3 = s == null ? void 0 : s.content) == null ? void 0 : _a3.substring(0, 400)) != null ? _b : "",
|
|
8238
8365
|
metadata: (_c = s == null ? void 0 : s.metadata) != null ? _c : {},
|
|
8239
8366
|
score: (_d = s == null ? void 0 : s.score) != null ? _d : 0
|
|
8240
8367
|
};
|
|
@@ -8274,7 +8401,7 @@ var SchemaMapper = class {
|
|
|
8274
8401
|
return promise;
|
|
8275
8402
|
}
|
|
8276
8403
|
static async _doTrain(llm, cacheKey, keys) {
|
|
8277
|
-
var
|
|
8404
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
|
|
8278
8405
|
console.log(`[SchemaMapper] \u{1F9E0} Training on new schema keys: ${keys.join(", ")}`);
|
|
8279
8406
|
const propertyList = Object.entries(this.TARGET_PROPERTIES).map(([prop, desc]) => `- ${prop} (${desc})`).join("\n");
|
|
8280
8407
|
const messages = [
|
|
@@ -8290,7 +8417,7 @@ Return a JSON object like {"name":"Title","price":"Price",...}. Omit unmapped pr
|
|
|
8290
8417
|
}
|
|
8291
8418
|
];
|
|
8292
8419
|
try {
|
|
8293
|
-
const baseUrl = (
|
|
8420
|
+
const baseUrl = (_a3 = llm == null ? void 0 : llm.baseUrl) != null ? _a3 : "";
|
|
8294
8421
|
const apiKey = (_b = llm == null ? void 0 : llm.apiKey) != null ? _b : "";
|
|
8295
8422
|
const model = (_c = llm == null ? void 0 : llm.model) != null ? _c : "llama-3.1-8b-instant";
|
|
8296
8423
|
let responseText;
|
|
@@ -8465,9 +8592,9 @@ var Pipeline = class {
|
|
|
8465
8592
|
this.initialised = false;
|
|
8466
8593
|
/** Namespace-specific static cold context cache for CAG */
|
|
8467
8594
|
this.coldContexts = /* @__PURE__ */ new Map();
|
|
8468
|
-
var
|
|
8595
|
+
var _a3, _b, _c, _d, _e;
|
|
8469
8596
|
this.chunker = new DocumentChunker(
|
|
8470
|
-
(_b = (
|
|
8597
|
+
(_b = (_a3 = config.rag) == null ? void 0 : _a3.chunkSize) != null ? _b : 1e3,
|
|
8471
8598
|
(_d = (_c = config.rag) == null ? void 0 : _c.chunkOverlap) != null ? _d : 200
|
|
8472
8599
|
);
|
|
8473
8600
|
if (((_e = config.rag) == null ? void 0 : _e.chunkingStrategy) === "llamaindex") {
|
|
@@ -8483,7 +8610,7 @@ var Pipeline = class {
|
|
|
8483
8610
|
return this.initialised ? this.llmProvider : void 0;
|
|
8484
8611
|
}
|
|
8485
8612
|
async initialize() {
|
|
8486
|
-
var
|
|
8613
|
+
var _a3, _b, _c, _d;
|
|
8487
8614
|
if (this.initialised) return;
|
|
8488
8615
|
const chartInstruction = `You are a helpful assistant. Use the provided context to answer questions accurately.
|
|
8489
8616
|
|
|
@@ -8526,7 +8653,7 @@ var Pipeline = class {
|
|
|
8526
8653
|
this.entityExtractor = new EntityExtractor(this.llmProvider);
|
|
8527
8654
|
}
|
|
8528
8655
|
await this.vectorDB.initialize();
|
|
8529
|
-
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) {
|
|
8530
8657
|
this.mcpRegistry = new MCPRegistry(this.config.mcpServers || []);
|
|
8531
8658
|
this.multiAgentCoordinator = new MultiAgentCoordinator({
|
|
8532
8659
|
llmProvider: this.llmProvider,
|
|
@@ -8544,8 +8671,8 @@ var Pipeline = class {
|
|
|
8544
8671
|
this.initialised = true;
|
|
8545
8672
|
}
|
|
8546
8673
|
async loadColdContext(ns) {
|
|
8547
|
-
var
|
|
8548
|
-
const cagConfig = (
|
|
8674
|
+
var _a3, _b;
|
|
8675
|
+
const cagConfig = (_a3 = this.config.rag) == null ? void 0 : _a3.cag;
|
|
8549
8676
|
if (!cagConfig || !cagConfig.enabled) return;
|
|
8550
8677
|
try {
|
|
8551
8678
|
const coldNs = cagConfig.coldNamespace || ns;
|
|
@@ -8598,12 +8725,12 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8598
8725
|
}
|
|
8599
8726
|
/** Step 1: Chunk the document content. */
|
|
8600
8727
|
async prepareChunks(doc) {
|
|
8601
|
-
var
|
|
8728
|
+
var _a3, _b;
|
|
8602
8729
|
if (this.llamaIngestor) {
|
|
8603
8730
|
return this.llamaIngestor.chunk(doc.content, {
|
|
8604
8731
|
docId: doc.docId,
|
|
8605
8732
|
metadata: doc.metadata,
|
|
8606
|
-
chunkSize: (
|
|
8733
|
+
chunkSize: (_a3 = this.config.rag) == null ? void 0 : _a3.chunkSize,
|
|
8607
8734
|
chunkOverlap: (_b = this.config.rag) == null ? void 0 : _b.chunkOverlap
|
|
8608
8735
|
});
|
|
8609
8736
|
}
|
|
@@ -8701,9 +8828,9 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8701
8828
|
return { reply, sources };
|
|
8702
8829
|
}
|
|
8703
8830
|
async ask(question, history = [], namespace) {
|
|
8704
|
-
var
|
|
8831
|
+
var _a3, _b;
|
|
8705
8832
|
await this.initialize();
|
|
8706
|
-
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) {
|
|
8707
8834
|
return await this.multiAgentCoordinator.run(question, history);
|
|
8708
8835
|
}
|
|
8709
8836
|
const stream = this.askStream(question, history, namespace);
|
|
@@ -8738,9 +8865,9 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8738
8865
|
}
|
|
8739
8866
|
askStream(_0) {
|
|
8740
8867
|
return __asyncGenerator(this, arguments, function* (question, history = [], namespace) {
|
|
8741
|
-
var
|
|
8868
|
+
var _a3, _b;
|
|
8742
8869
|
yield new __await(this.initialize());
|
|
8743
|
-
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) {
|
|
8744
8871
|
const stream2 = this.multiAgentCoordinator.runStream(question, history);
|
|
8745
8872
|
try {
|
|
8746
8873
|
for (var iter = __forAwait(stream2), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
|
|
@@ -8789,10 +8916,10 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8789
8916
|
*/
|
|
8790
8917
|
askStreamInternal(_0) {
|
|
8791
8918
|
return __asyncGenerator(this, arguments, function* (question, history = [], namespace) {
|
|
8792
|
-
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;
|
|
8793
8920
|
yield new __await(this.initialize());
|
|
8794
8921
|
const ns = formatNamespace(namespace != null ? namespace : this.config.projectId);
|
|
8795
|
-
const topK = (_b = (
|
|
8922
|
+
const topK = (_b = (_a3 = this.config.rag) == null ? void 0 : _a3.topK) != null ? _b : 5;
|
|
8796
8923
|
const scoreThreshold = (_d = (_c = this.config.rag) == null ? void 0 : _c.scoreThreshold) != null ? _d : 0.3;
|
|
8797
8924
|
const requestId = `req_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
8798
8925
|
const requestStart = performance.now();
|
|
@@ -8841,8 +8968,8 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8841
8968
|
const rerankStart = performance.now();
|
|
8842
8969
|
const structuredSources = this.applyStructuredFilters(rawSources, filter).filter((s) => Boolean(s && typeof s === "object"));
|
|
8843
8970
|
let fullSources = hasNumericPredicates ? structuredSources : structuredSources.filter((m) => {
|
|
8844
|
-
var
|
|
8845
|
-
return ((
|
|
8971
|
+
var _a4;
|
|
8972
|
+
return ((_a4 = m == null ? void 0 : m.score) != null ? _a4 : 0) >= scoreThreshold;
|
|
8846
8973
|
});
|
|
8847
8974
|
const rerankLimit = Math.max(retrievalLimit, fullSources.length);
|
|
8848
8975
|
const useReranking = arch !== "naive" && (arch === "retrieve-and-rerank" || ((_m = this.config.rag) == null ? void 0 : _m.useReranking));
|
|
@@ -8855,13 +8982,13 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8855
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]
|
|
8856
8983
|
|
|
8857
8984
|
` + promptSources.map((m, i) => {
|
|
8858
|
-
var
|
|
8985
|
+
var _a4;
|
|
8859
8986
|
return `[Source ${i + 1}]
|
|
8860
|
-
${(
|
|
8987
|
+
${(_a4 = m == null ? void 0 : m.content) != null ? _a4 : ""}`;
|
|
8861
8988
|
}).join("\n\n---\n\n") : "No relevant context found.";
|
|
8862
8989
|
const sources = [...fullSources].filter((s) => Boolean(s && typeof s === "object")).sort((a, b) => {
|
|
8863
|
-
var
|
|
8864
|
-
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);
|
|
8865
8992
|
});
|
|
8866
8993
|
if (graphData && graphData.nodes.length > 0) {
|
|
8867
8994
|
const graphContext = graphData.nodes.map(
|
|
@@ -8889,10 +9016,10 @@ ${context}`;
|
|
|
8889
9016
|
yield {
|
|
8890
9017
|
reply: "",
|
|
8891
9018
|
sources: (sources || []).filter((s) => Boolean(s && typeof s === "object")).map((s) => {
|
|
8892
|
-
var
|
|
9019
|
+
var _a4, _b2, _c2;
|
|
8893
9020
|
return {
|
|
8894
9021
|
id: s.id,
|
|
8895
|
-
score: (
|
|
9022
|
+
score: (_a4 = s.score) != null ? _a4 : 0,
|
|
8896
9023
|
content: (_b2 = s == null ? void 0 : s.content) != null ? _b2 : "",
|
|
8897
9024
|
metadata: (_c2 = s == null ? void 0 : s.metadata) != null ? _c2 : {},
|
|
8898
9025
|
namespace: ns
|
|
@@ -9085,11 +9212,11 @@ ${context}`;
|
|
|
9085
9212
|
systemPrompt,
|
|
9086
9213
|
userPrompt: question + finalRestrictionSuffix,
|
|
9087
9214
|
chunks: (sources || []).filter(Boolean).map((s) => {
|
|
9088
|
-
var
|
|
9215
|
+
var _a4, _b2;
|
|
9089
9216
|
return {
|
|
9090
9217
|
id: s.id,
|
|
9091
9218
|
score: s.score,
|
|
9092
|
-
content: (
|
|
9219
|
+
content: (_a4 = s == null ? void 0 : s.content) != null ? _a4 : "",
|
|
9093
9220
|
metadata: (_b2 = s == null ? void 0 : s.metadata) != null ? _b2 : {},
|
|
9094
9221
|
namespace: ns
|
|
9095
9222
|
};
|
|
@@ -9108,7 +9235,7 @@ ${context}`;
|
|
|
9108
9235
|
const telemetryUrl = ((_B = this.config.telemetry) == null ? void 0 : _B.url) || process.env.TELEMETRY_URL || process.env.NEXT_PUBLIC_TELEMETRY_URL || defaultUrl;
|
|
9109
9236
|
const absoluteUrl = telemetryUrl.startsWith("http") ? telemetryUrl : "https://www.retrivora.com" + (telemetryUrl.startsWith("/") ? telemetryUrl : "/" + telemetryUrl);
|
|
9110
9237
|
(async () => {
|
|
9111
|
-
var
|
|
9238
|
+
var _a4, _b2, _c2, _d2, _e2;
|
|
9112
9239
|
try {
|
|
9113
9240
|
let finalTrace = trace;
|
|
9114
9241
|
if (!awaitHallucination && runHallucination) {
|
|
@@ -9117,7 +9244,7 @@ ${context}`;
|
|
|
9117
9244
|
finalTrace = buildTrace(backgroundScoreResult);
|
|
9118
9245
|
}
|
|
9119
9246
|
}
|
|
9120
|
-
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";
|
|
9121
9248
|
const providerName = (finalTrace == null ? void 0 : finalTrace.provider) || ((_b2 = this.config.llm) == null ? void 0 : _b2.provider) || "groq";
|
|
9122
9249
|
const tokenCount = Number(((_c2 = finalTrace == null ? void 0 : finalTrace.tokens) == null ? void 0 : _c2.totalTokens) || 0);
|
|
9123
9250
|
const costEst = Number(((_d2 = finalTrace == null ? void 0 : finalTrace.tokens) == null ? void 0 : _d2.estimatedCostUsd) || 0);
|
|
@@ -9171,7 +9298,7 @@ ${context}`;
|
|
|
9171
9298
|
* Uses an LRU-bounded embedding cache to avoid re-embedding the same query.
|
|
9172
9299
|
*/
|
|
9173
9300
|
async generateUiTransformation(question, sources, cachedSchema, forceDeterministic = false) {
|
|
9174
|
-
var
|
|
9301
|
+
var _a3;
|
|
9175
9302
|
if (!sources || sources.length === 0) {
|
|
9176
9303
|
return UITransformer.transform(question, sources, this.config, cachedSchema);
|
|
9177
9304
|
}
|
|
@@ -9184,7 +9311,7 @@ ${context}`;
|
|
|
9184
9311
|
{ visualizationHint: "product_browse", recommendedChart: "text", filterInStockOnly: false, wantsExplicitTable: false, isTemporal: false, isComparison: false, language: "en" }
|
|
9185
9312
|
);
|
|
9186
9313
|
}
|
|
9187
|
-
const enableLlmUiTransform = ((
|
|
9314
|
+
const enableLlmUiTransform = ((_a3 = this.config.llm.options) == null ? void 0 : _a3.enableLlmUiTransform) === true;
|
|
9188
9315
|
if (forceDeterministic || !enableLlmUiTransform) {
|
|
9189
9316
|
return UITransformer.transform(question, sources, this.config, cachedSchema);
|
|
9190
9317
|
}
|
|
@@ -9202,15 +9329,15 @@ ${context}`;
|
|
|
9202
9329
|
const value = this.resolveNumericPredicateValue(source, predicate);
|
|
9203
9330
|
return value !== null && this.matchesNumericPredicate(value, predicate);
|
|
9204
9331
|
})).sort((a, b) => {
|
|
9205
|
-
var
|
|
9332
|
+
var _a3, _b;
|
|
9206
9333
|
const primary = predicates[0];
|
|
9207
|
-
const aValue = (
|
|
9334
|
+
const aValue = (_a3 = this.resolveNumericPredicateValue(a, primary)) != null ? _a3 : 0;
|
|
9208
9335
|
const bValue = (_b = this.resolveNumericPredicateValue(b, primary)) != null ? _b : 0;
|
|
9209
9336
|
return primary.operator === "lt" || primary.operator === "lte" ? aValue - bValue : bValue - aValue;
|
|
9210
9337
|
});
|
|
9211
9338
|
}
|
|
9212
9339
|
resolveNumericPredicateValue(source, predicate) {
|
|
9213
|
-
var
|
|
9340
|
+
var _a3;
|
|
9214
9341
|
if (!source) return null;
|
|
9215
9342
|
const meta = source.metadata || {};
|
|
9216
9343
|
const field = predicate.field;
|
|
@@ -9223,7 +9350,7 @@ ${context}`;
|
|
|
9223
9350
|
const value = this.toFiniteNumber(Array.isArray(fuzzy) ? fuzzy[1] : fuzzy.value);
|
|
9224
9351
|
if (value !== null) return value;
|
|
9225
9352
|
}
|
|
9226
|
-
const contentValue = this.extractNumericValueFromContent((
|
|
9353
|
+
const contentValue = this.extractNumericValueFromContent((_a3 = source.content) != null ? _a3 : "", field);
|
|
9227
9354
|
if (contentValue !== null) return contentValue;
|
|
9228
9355
|
}
|
|
9229
9356
|
for (const [key, value] of entries) {
|
|
@@ -9279,8 +9406,8 @@ ${context}`;
|
|
|
9279
9406
|
return Number.isFinite(numeric) ? numeric : null;
|
|
9280
9407
|
}
|
|
9281
9408
|
async retrieve(query, options) {
|
|
9282
|
-
var
|
|
9283
|
-
const ns = formatNamespace((
|
|
9409
|
+
var _a3, _b, _c, _d, _e, _f, _g2;
|
|
9410
|
+
const ns = formatNamespace((_a3 = options.namespace) != null ? _a3 : this.config.projectId);
|
|
9284
9411
|
const topK = (_b = options.topK) != null ? _b : 5;
|
|
9285
9412
|
const cacheKey = `${ns}::${query}`;
|
|
9286
9413
|
let queryVector = this.embeddingCache.get(cacheKey);
|
|
@@ -9325,11 +9452,11 @@ ${context}`;
|
|
|
9325
9452
|
namespace: ns,
|
|
9326
9453
|
count: resolvedSources.length,
|
|
9327
9454
|
sample: resolvedSources.slice(0, 2).map((s) => {
|
|
9328
|
-
var
|
|
9455
|
+
var _a4;
|
|
9329
9456
|
return {
|
|
9330
9457
|
id: s == null ? void 0 : s.id,
|
|
9331
9458
|
score: s == null ? void 0 : s.score,
|
|
9332
|
-
contentSnippet: String((
|
|
9459
|
+
contentSnippet: String((_a4 = s == null ? void 0 : s.content) != null ? _a4 : "").substring(0, 150),
|
|
9333
9460
|
metadata: s == null ? void 0 : s.metadata
|
|
9334
9461
|
};
|
|
9335
9462
|
})
|
|
@@ -9343,8 +9470,8 @@ Focus on extracting the core intent and entities. Do not answer the question, ju
|
|
|
9343
9470
|
|
|
9344
9471
|
History:
|
|
9345
9472
|
${(history || []).map((m) => {
|
|
9346
|
-
var
|
|
9347
|
-
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 : ""}`;
|
|
9348
9475
|
}).join("\n")}
|
|
9349
9476
|
|
|
9350
9477
|
New Question: ${question}
|
|
@@ -9371,8 +9498,8 @@ Optimized Search Query:`;
|
|
|
9371
9498
|
const { sources } = await this.retrieve(query, { namespace: ns, topK: 5 });
|
|
9372
9499
|
if (!sources || sources.length === 0) return [];
|
|
9373
9500
|
const context = sources.map((s) => {
|
|
9374
|
-
var
|
|
9375
|
-
return (
|
|
9501
|
+
var _a3;
|
|
9502
|
+
return (_a3 = s == null ? void 0 : s.content) != null ? _a3 : "";
|
|
9376
9503
|
}).join("\n\n---\n\n");
|
|
9377
9504
|
const prompt = `Based on the following snippets from a document, what are at least 5 short, relevant questions a user might ask?
|
|
9378
9505
|
Focus on questions that can be answered by the context.
|
|
@@ -9510,18 +9637,200 @@ var ProviderHealthCheck = class {
|
|
|
9510
9637
|
}
|
|
9511
9638
|
};
|
|
9512
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
|
+
|
|
9513
9822
|
// src/core/VectorPlugin.ts
|
|
9514
9823
|
var VectorPlugin = class {
|
|
9515
9824
|
constructor(hostConfig) {
|
|
9516
9825
|
const resolvedConfig = ConfigResolver.resolve(hostConfig);
|
|
9517
9826
|
this.config = resolvedConfig;
|
|
9518
9827
|
this.validationPromise = (async () => {
|
|
9519
|
-
var
|
|
9828
|
+
var _a3;
|
|
9520
9829
|
await ConfigValidator.validateAndThrow(resolvedConfig);
|
|
9521
9830
|
LicenseVerifier.verify(
|
|
9522
9831
|
resolvedConfig.licenseKey,
|
|
9523
9832
|
resolvedConfig.projectId,
|
|
9524
|
-
(
|
|
9833
|
+
(_a3 = resolvedConfig.vectorDb) == null ? void 0 : _a3.provider
|
|
9525
9834
|
);
|
|
9526
9835
|
})();
|
|
9527
9836
|
this.validationPromise.catch(() => {
|
|
@@ -9555,16 +9864,32 @@ var VectorPlugin = class {
|
|
|
9555
9864
|
this.config.embedding
|
|
9556
9865
|
);
|
|
9557
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
|
+
}
|
|
9558
9874
|
/**
|
|
9559
9875
|
* Run a chat query.
|
|
9560
9876
|
*/
|
|
9561
9877
|
async chat(message, history = [], namespace) {
|
|
9878
|
+
var _a3;
|
|
9562
9879
|
try {
|
|
9563
9880
|
await this.validationPromise;
|
|
9564
9881
|
} catch (err) {
|
|
9565
9882
|
throw wrapError(err, "CONFIGURATION_ERROR");
|
|
9566
9883
|
}
|
|
9567
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
|
+
}
|
|
9568
9893
|
return await this.pipeline.ask(message, history, namespace);
|
|
9569
9894
|
} catch (err) {
|
|
9570
9895
|
const msg = String(err);
|
|
@@ -9572,6 +9897,9 @@ var VectorPlugin = class {
|
|
|
9572
9897
|
if (msg.includes("Embed") || msg.includes("embed")) {
|
|
9573
9898
|
defaultCode = "EMBEDDING_FAILED";
|
|
9574
9899
|
}
|
|
9900
|
+
if (msg.toLowerCase().includes("token limit")) {
|
|
9901
|
+
defaultCode = "RATE_LIMITED";
|
|
9902
|
+
}
|
|
9575
9903
|
throw wrapError(err, defaultCode);
|
|
9576
9904
|
}
|
|
9577
9905
|
}
|
|
@@ -9580,12 +9908,21 @@ var VectorPlugin = class {
|
|
|
9580
9908
|
*/
|
|
9581
9909
|
chatStream(_0) {
|
|
9582
9910
|
return __asyncGenerator(this, arguments, function* (message, history = [], namespace) {
|
|
9911
|
+
var _a3;
|
|
9583
9912
|
try {
|
|
9584
9913
|
yield new __await(this.validationPromise);
|
|
9585
9914
|
} catch (err) {
|
|
9586
9915
|
throw wrapError(err, "CONFIGURATION_ERROR");
|
|
9587
9916
|
}
|
|
9588
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
|
+
}
|
|
9589
9926
|
const stream = this.pipeline.askStream(message, history, namespace);
|
|
9590
9927
|
try {
|
|
9591
9928
|
for (var iter = __forAwait(stream), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
|
|
@@ -9608,6 +9945,9 @@ var VectorPlugin = class {
|
|
|
9608
9945
|
if (msg.includes("Embed") || msg.includes("embed")) {
|
|
9609
9946
|
defaultCode = "EMBEDDING_FAILED";
|
|
9610
9947
|
}
|
|
9948
|
+
if (msg.toLowerCase().includes("token limit")) {
|
|
9949
|
+
defaultCode = "RATE_LIMITED";
|
|
9950
|
+
}
|
|
9611
9951
|
throw wrapError(err, defaultCode);
|
|
9612
9952
|
}
|
|
9613
9953
|
});
|
|
@@ -9655,8 +9995,8 @@ var DocumentParser = class {
|
|
|
9655
9995
|
* Extract text from a File or Buffer based on its type.
|
|
9656
9996
|
*/
|
|
9657
9997
|
static async parse(file, fileName, mimeType) {
|
|
9658
|
-
var
|
|
9659
|
-
const extension = ((
|
|
9998
|
+
var _a3;
|
|
9999
|
+
const extension = ((_a3 = fileName.split(".").pop()) == null ? void 0 : _a3.toLowerCase()) || "";
|
|
9660
10000
|
if (extension === "txt" || extension === "md" || mimeType === "text/plain" || mimeType === "text/markdown") {
|
|
9661
10001
|
return this.readAsText(file);
|
|
9662
10002
|
}
|
|
@@ -9747,9 +10087,9 @@ var DatabaseStorage = class {
|
|
|
9747
10087
|
this.fallbackDir = this.isServerless ? path.join(os.tmpdir(), ".retrivora") : path.join(process.cwd(), ".retrivora");
|
|
9748
10088
|
this.historyFile = path.join(this.fallbackDir, "history.json");
|
|
9749
10089
|
this.feedbackFile = path.join(this.fallbackDir, "feedback.json");
|
|
9750
|
-
var
|
|
10090
|
+
var _a3, _b, _c, _d, _e;
|
|
9751
10091
|
this.config = config;
|
|
9752
|
-
this.provider = ((
|
|
10092
|
+
this.provider = ((_a3 = config.vectorDb) == null ? void 0 : _a3.provider) || "fs";
|
|
9753
10093
|
const rawHistoryTable = ((_c = (_b = config.rag) == null ? void 0 : _b.history) == null ? void 0 : _c.tableName) || "retrivora_history";
|
|
9754
10094
|
const rawFeedbackTable = ((_e = (_d = config.rag) == null ? void 0 : _d.feedback) == null ? void 0 : _e.tableName) || "retrivora_feedback";
|
|
9755
10095
|
this.historyTableName = rawHistoryTable.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
@@ -9784,16 +10124,16 @@ var DatabaseStorage = class {
|
|
|
9784
10124
|
}
|
|
9785
10125
|
}
|
|
9786
10126
|
checkHistoryEnabled() {
|
|
9787
|
-
var
|
|
10127
|
+
var _a3, _b;
|
|
9788
10128
|
this.checkPremiumSubscription();
|
|
9789
|
-
if (((_b = (
|
|
10129
|
+
if (((_b = (_a3 = this.config.rag) == null ? void 0 : _a3.history) == null ? void 0 : _b.enabled) === false) {
|
|
9790
10130
|
throw new Error("[Retrivora SDK] Chat History is disabled in RagConfig.");
|
|
9791
10131
|
}
|
|
9792
10132
|
}
|
|
9793
10133
|
checkFeedbackEnabled() {
|
|
9794
|
-
var
|
|
10134
|
+
var _a3, _b;
|
|
9795
10135
|
this.checkPremiumSubscription();
|
|
9796
|
-
if (((_b = (
|
|
10136
|
+
if (((_b = (_a3 = this.config.rag) == null ? void 0 : _a3.feedback) == null ? void 0 : _b.enabled) === false) {
|
|
9797
10137
|
throw new Error("[Retrivora SDK] User Feedback is disabled in RagConfig.");
|
|
9798
10138
|
}
|
|
9799
10139
|
}
|
|
@@ -9960,8 +10300,11 @@ var DatabaseStorage = class {
|
|
|
9960
10300
|
this.writeLocalFile(this.historyFile, history);
|
|
9961
10301
|
}
|
|
9962
10302
|
}
|
|
9963
|
-
async getHistory(sessionId) {
|
|
10303
|
+
async getHistory(sessionId, projectIds) {
|
|
9964
10304
|
this.checkHistoryEnabled();
|
|
10305
|
+
if (projectIds && projectIds.length > 0 && !this.sessionInScope(sessionId, projectIds)) {
|
|
10306
|
+
return [];
|
|
10307
|
+
}
|
|
9965
10308
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
9966
10309
|
const pool = await this.getPGPool();
|
|
9967
10310
|
const res = await pool.query(
|
|
@@ -9991,8 +10334,11 @@ var DatabaseStorage = class {
|
|
|
9991
10334
|
return history.filter((h) => h.session_id === sessionId).sort((a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime());
|
|
9992
10335
|
}
|
|
9993
10336
|
}
|
|
9994
|
-
async clearHistory(sessionId) {
|
|
10337
|
+
async clearHistory(sessionId, projectIds) {
|
|
9995
10338
|
this.checkHistoryEnabled();
|
|
10339
|
+
if (projectIds && projectIds.length > 0 && !this.sessionInScope(sessionId, projectIds)) {
|
|
10340
|
+
return;
|
|
10341
|
+
}
|
|
9996
10342
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
9997
10343
|
const pool = await this.getPGPool();
|
|
9998
10344
|
await pool.query(`DELETE FROM ${this.historyTableName} WHERE session_id = $1`, [sessionId]);
|
|
@@ -10011,21 +10357,36 @@ var DatabaseStorage = class {
|
|
|
10011
10357
|
this.writeLocalFile(this.feedbackFile, filteredFeedback);
|
|
10012
10358
|
}
|
|
10013
10359
|
}
|
|
10014
|
-
|
|
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) {
|
|
10015
10374
|
this.checkHistoryEnabled();
|
|
10375
|
+
let raw = [];
|
|
10016
10376
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
10017
10377
|
const pool = await this.getPGPool();
|
|
10018
10378
|
const res = await pool.query(`SELECT DISTINCT session_id FROM ${this.historyTableName}`);
|
|
10019
|
-
|
|
10379
|
+
raw = res.rows.map((r) => r.session_id);
|
|
10020
10380
|
} else if (this.provider === "mongodb") {
|
|
10021
10381
|
await this.getMongoClient();
|
|
10022
10382
|
const db = this.getMongoDb();
|
|
10023
|
-
|
|
10383
|
+
raw = await db.collection(this.historyTableName).distinct("session_id");
|
|
10024
10384
|
} else {
|
|
10025
10385
|
const history = this.readLocalFile(this.historyFile);
|
|
10026
|
-
|
|
10027
|
-
return Array.from(sessions);
|
|
10386
|
+
raw = Array.from(new Set(history.map((h) => h.session_id)));
|
|
10028
10387
|
}
|
|
10388
|
+
if (!projectIds || projectIds.length === 0) return raw;
|
|
10389
|
+
return raw.filter((sid) => this.sessionInScope(sid, projectIds));
|
|
10029
10390
|
}
|
|
10030
10391
|
// ─── Feedback Operations ──────────────────────────────────────────────────
|
|
10031
10392
|
async saveFeedback(feedback) {
|
|
@@ -10078,8 +10439,9 @@ var DatabaseStorage = class {
|
|
|
10078
10439
|
this.writeLocalFile(this.feedbackFile, list);
|
|
10079
10440
|
}
|
|
10080
10441
|
}
|
|
10081
|
-
async getFeedback(messageId) {
|
|
10442
|
+
async getFeedback(messageId, projectIds) {
|
|
10082
10443
|
this.checkFeedbackEnabled();
|
|
10444
|
+
let item = null;
|
|
10083
10445
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
10084
10446
|
const pool = await this.getPGPool();
|
|
10085
10447
|
const res = await pool.query(
|
|
@@ -10088,28 +10450,34 @@ var DatabaseStorage = class {
|
|
|
10088
10450
|
WHERE message_id = $1`,
|
|
10089
10451
|
[messageId]
|
|
10090
10452
|
);
|
|
10091
|
-
|
|
10453
|
+
item = res.rows[0] || null;
|
|
10092
10454
|
} else if (this.provider === "mongodb") {
|
|
10093
10455
|
await this.getMongoClient();
|
|
10094
10456
|
const db = this.getMongoDb();
|
|
10095
10457
|
const col = db.collection(this.feedbackTableName);
|
|
10096
|
-
const
|
|
10097
|
-
if (
|
|
10098
|
-
|
|
10099
|
-
|
|
10100
|
-
|
|
10101
|
-
|
|
10102
|
-
|
|
10103
|
-
|
|
10104
|
-
|
|
10105
|
-
|
|
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
|
+
}
|
|
10106
10469
|
} else {
|
|
10107
10470
|
const list = this.readLocalFile(this.feedbackFile);
|
|
10108
|
-
|
|
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;
|
|
10109
10475
|
}
|
|
10476
|
+
return item;
|
|
10110
10477
|
}
|
|
10111
|
-
async listFeedback() {
|
|
10478
|
+
async listFeedback(projectIds) {
|
|
10112
10479
|
this.checkFeedbackEnabled();
|
|
10480
|
+
let raw = [];
|
|
10113
10481
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
10114
10482
|
const pool = await this.getPGPool();
|
|
10115
10483
|
const res = await pool.query(
|
|
@@ -10117,13 +10485,13 @@ var DatabaseStorage = class {
|
|
|
10117
10485
|
FROM ${this.feedbackTableName}
|
|
10118
10486
|
ORDER BY created_at DESC`
|
|
10119
10487
|
);
|
|
10120
|
-
|
|
10488
|
+
raw = res.rows;
|
|
10121
10489
|
} else if (this.provider === "mongodb") {
|
|
10122
10490
|
await this.getMongoClient();
|
|
10123
10491
|
const db = this.getMongoDb();
|
|
10124
10492
|
const col = db.collection(this.feedbackTableName);
|
|
10125
10493
|
const items = await col.find({}).sort({ created_at: -1 }).toArray();
|
|
10126
|
-
|
|
10494
|
+
raw = items.map((item) => ({
|
|
10127
10495
|
id: item.id,
|
|
10128
10496
|
messageId: item.message_id,
|
|
10129
10497
|
sessionId: item.session_id,
|
|
@@ -10133,8 +10501,10 @@ var DatabaseStorage = class {
|
|
|
10133
10501
|
}));
|
|
10134
10502
|
} else {
|
|
10135
10503
|
const list = this.readLocalFile(this.feedbackFile);
|
|
10136
|
-
|
|
10504
|
+
raw = [...list].sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime());
|
|
10137
10505
|
}
|
|
10506
|
+
if (!projectIds || projectIds.length === 0) return raw;
|
|
10507
|
+
return raw.filter((f) => this.sessionInScope(f.sessionId, projectIds));
|
|
10138
10508
|
}
|
|
10139
10509
|
async disconnect() {
|
|
10140
10510
|
if (this.pgPool) {
|
|
@@ -10197,8 +10567,8 @@ var _g = global;
|
|
|
10197
10567
|
var _a;
|
|
10198
10568
|
var rateLimiter = (_a = _g.__retrivoraRateLimiter) != null ? _a : _g.__retrivoraRateLimiter = new RateLimiter(6e4, 30);
|
|
10199
10569
|
function getRateLimitKey(req) {
|
|
10200
|
-
var
|
|
10201
|
-
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";
|
|
10202
10572
|
return `ip:${ip}`;
|
|
10203
10573
|
}
|
|
10204
10574
|
function checkRateLimit(req) {
|
|
@@ -10220,6 +10590,66 @@ function checkRateLimit(req) {
|
|
|
10220
10590
|
}
|
|
10221
10591
|
return null;
|
|
10222
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
|
+
}
|
|
10223
10653
|
var MAX_MESSAGE_LENGTH = 8e3;
|
|
10224
10654
|
function sanitizeInput(raw) {
|
|
10225
10655
|
const stripped = raw.replace(/[\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F-\u009F]/g, "");
|
|
@@ -10241,7 +10671,7 @@ function getOrCreatePlugin(configOrPlugin) {
|
|
|
10241
10671
|
return _g[cacheKey];
|
|
10242
10672
|
}
|
|
10243
10673
|
function reportTelemetry(req, plugin, action, status, details, trace) {
|
|
10244
|
-
var
|
|
10674
|
+
var _a3, _b, _c, _d, _e, _f, _g2;
|
|
10245
10675
|
try {
|
|
10246
10676
|
const config = plugin.getConfig();
|
|
10247
10677
|
const licenseKey = config.licenseKey || process.env.RAG_LICENSE_KEY || process.env.RETRIVORA_LICENSE_KEY || process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY;
|
|
@@ -10256,7 +10686,7 @@ function reportTelemetry(req, plugin, action, status, details, trace) {
|
|
|
10256
10686
|
absoluteUrl = `${proto}://${host}${telemetryUrl}`;
|
|
10257
10687
|
}
|
|
10258
10688
|
const projectId = config.projectId || "default";
|
|
10259
|
-
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";
|
|
10260
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";
|
|
10261
10691
|
const tokens = Number(((_e = trace == null ? void 0 : trace.tokens) == null ? void 0 : _e.totalTokens) || (trace == null ? void 0 : trace.totalTokens) || 0);
|
|
10262
10692
|
const costUsd = Number(((_f = trace == null ? void 0 : trace.tokens) == null ? void 0 : _f.estimatedCostUsd) || (trace == null ? void 0 : trace.costUsd) || 0);
|
|
@@ -10280,7 +10710,6 @@ function reportTelemetry(req, plugin, action, status, details, trace) {
|
|
|
10280
10710
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
10281
10711
|
details
|
|
10282
10712
|
};
|
|
10283
|
-
console.log(`[Retrivora SDK Telemetry] Dispatching telemetry -> Feature: "${action}", Status: "${status}", Project: "${projectId}", Latency: ${latencyMs}ms`);
|
|
10284
10713
|
fetch(absoluteUrl, {
|
|
10285
10714
|
method: "POST",
|
|
10286
10715
|
headers: {
|
|
@@ -10338,14 +10767,39 @@ function createChatHandler(configOrPlugin, options) {
|
|
|
10338
10767
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
10339
10768
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
10340
10769
|
return async function POST(req, context) {
|
|
10341
|
-
var
|
|
10770
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
10342
10771
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10343
10772
|
if (authResult) return authResult;
|
|
10344
10773
|
const rateLimited = checkRateLimit(req);
|
|
10345
10774
|
if (rateLimited) return rateLimited;
|
|
10775
|
+
const config = plugin.getConfig();
|
|
10346
10776
|
try {
|
|
10347
10777
|
const body = await req.json();
|
|
10348
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
|
+
}
|
|
10349
10803
|
let rawMessage = bodyObj.message;
|
|
10350
10804
|
if (!rawMessage && Array.isArray(bodyObj.messages) && bodyObj.messages.length > 0) {
|
|
10351
10805
|
const lastMsg = bodyObj.messages[bodyObj.messages.length - 1];
|
|
@@ -10377,7 +10831,7 @@ function createChatHandler(configOrPlugin, options) {
|
|
|
10377
10831
|
uiTransformation: result.ui_transformation,
|
|
10378
10832
|
trace: result.trace
|
|
10379
10833
|
}).catch((err) => console.warn("[createChatHandler] Failed to save assistant message:", err));
|
|
10380
|
-
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);
|
|
10381
10835
|
return import_server.NextResponse.json(__spreadProps(__spreadValues({}, result), {
|
|
10382
10836
|
messageId: assistantMsgId,
|
|
10383
10837
|
userMessageId: userMsgId
|
|
@@ -10394,14 +10848,15 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10394
10848
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
10395
10849
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
10396
10850
|
return async function POST(req, context) {
|
|
10397
|
-
var
|
|
10851
|
+
var _a3, _b, _c;
|
|
10398
10852
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10399
10853
|
if (authResult) return authResult;
|
|
10400
10854
|
const rateLimited = checkRateLimit(req);
|
|
10401
10855
|
if (rateLimited) return rateLimited;
|
|
10856
|
+
const config = plugin.getConfig();
|
|
10402
10857
|
let body;
|
|
10403
10858
|
try {
|
|
10404
|
-
if ((
|
|
10859
|
+
if ((_a3 = req.headers.get("content-type")) == null ? void 0 : _a3.includes("multipart/form-data")) {
|
|
10405
10860
|
const uploader = createUploadHandler(plugin, { onAuthorize });
|
|
10406
10861
|
return uploader(req);
|
|
10407
10862
|
}
|
|
@@ -10413,6 +10868,30 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10413
10868
|
});
|
|
10414
10869
|
}
|
|
10415
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
|
+
}
|
|
10416
10895
|
let rawMessage = bodyObj.message;
|
|
10417
10896
|
if (!rawMessage && Array.isArray(bodyObj.messages) && bodyObj.messages.length > 0) {
|
|
10418
10897
|
const lastMsg = bodyObj.messages[bodyObj.messages.length - 1];
|
|
@@ -10442,7 +10921,7 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10442
10921
|
let isActive = true;
|
|
10443
10922
|
const stream = new ReadableStream({
|
|
10444
10923
|
async start(controller) {
|
|
10445
|
-
var
|
|
10924
|
+
var _a4, _b2, _c2, _d, _e;
|
|
10446
10925
|
const enqueue = (text) => {
|
|
10447
10926
|
if (!isActive) return;
|
|
10448
10927
|
try {
|
|
@@ -10475,7 +10954,7 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10475
10954
|
let uiTransformation = responseChunk == null ? void 0 : responseChunk.ui_transformation;
|
|
10476
10955
|
if (sources.length > 0) {
|
|
10477
10956
|
try {
|
|
10478
|
-
uiTransformation = (
|
|
10957
|
+
uiTransformation = (_a4 = responseChunk == null ? void 0 : responseChunk.ui_transformation) != null ? _a4 : UITransformer.transform(message, sources, plugin.getConfig());
|
|
10479
10958
|
if (uiTransformation) {
|
|
10480
10959
|
enqueue(sseUIFrame(uiTransformation));
|
|
10481
10960
|
}
|
|
@@ -10499,7 +10978,7 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10499
10978
|
uiTransformation,
|
|
10500
10979
|
trace: responseChunk == null ? void 0 : responseChunk.trace
|
|
10501
10980
|
}).catch((err) => console.warn("[createStreamHandler] Failed to save assistant message:", err));
|
|
10502
|
-
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);
|
|
10503
10982
|
}
|
|
10504
10983
|
}
|
|
10505
10984
|
} catch (temp) {
|
|
@@ -10549,12 +11028,36 @@ function createIngestHandler(configOrPlugin, options) {
|
|
|
10549
11028
|
return async function POST(req, context) {
|
|
10550
11029
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10551
11030
|
if (authResult) return authResult;
|
|
11031
|
+
const config = plugin.getConfig();
|
|
10552
11032
|
try {
|
|
10553
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;
|
|
10554
11036
|
const { documents, namespace } = body;
|
|
10555
11037
|
if (!Array.isArray(documents) || documents.length === 0) {
|
|
10556
11038
|
return import_server.NextResponse.json({ error: "documents array is required" }, { status: 400 });
|
|
10557
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
|
+
}
|
|
10558
11061
|
const results = await plugin.ingest(documents, namespace);
|
|
10559
11062
|
reportTelemetry(req, plugin, "DOCUMENT_INGESTION", "success", `Ingested ${documents.length} document(s)`);
|
|
10560
11063
|
return import_server.NextResponse.json({ results });
|
|
@@ -10591,7 +11094,7 @@ function createLicenseHandler(configOrPlugin, options) {
|
|
|
10591
11094
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
10592
11095
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
10593
11096
|
return async function POST(req) {
|
|
10594
|
-
var
|
|
11097
|
+
var _a3;
|
|
10595
11098
|
if (req) {
|
|
10596
11099
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10597
11100
|
if (authResult) return authResult;
|
|
@@ -10599,7 +11102,7 @@ function createLicenseHandler(configOrPlugin, options) {
|
|
|
10599
11102
|
try {
|
|
10600
11103
|
const body = await req.json().catch(() => ({}));
|
|
10601
11104
|
const config = plugin.getConfig();
|
|
10602
|
-
const rawKey = req.headers.get("x-license-key") || (body == null ? void 0 : body.licenseKey) || ((
|
|
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 || "";
|
|
10603
11106
|
const licenseKey = (rawKey || "").trim().replace(/^["']|["']$/g, "").trim();
|
|
10604
11107
|
const projectId = (body == null ? void 0 : body.projectId) || config.projectId || "my-rag-app";
|
|
10605
11108
|
const payload = LicenseVerifier.verify(licenseKey, projectId);
|
|
@@ -10634,6 +11137,9 @@ function createUploadHandler(configOrPlugin, options) {
|
|
|
10634
11137
|
return async function POST(req, context) {
|
|
10635
11138
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10636
11139
|
if (authResult) return authResult;
|
|
11140
|
+
const config = plugin.getConfig();
|
|
11141
|
+
const licenseCheck = enforceLicense(req, config);
|
|
11142
|
+
if (!licenseCheck.ok) return licenseCheck.response;
|
|
10637
11143
|
try {
|
|
10638
11144
|
const formData = await req.formData();
|
|
10639
11145
|
const files = formData.getAll("files");
|
|
@@ -10643,6 +11149,26 @@ function createUploadHandler(configOrPlugin, options) {
|
|
|
10643
11149
|
if (!files || files.length === 0) {
|
|
10644
11150
|
return import_server.NextResponse.json({ error: "No files provided" }, { status: 400 });
|
|
10645
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
|
+
}
|
|
10646
11172
|
const documents = [];
|
|
10647
11173
|
for (const file of files) {
|
|
10648
11174
|
const isExcel = file.name.toLowerCase().endsWith(".xlsx") || file.name.toLowerCase().endsWith(".xls") || file.type.includes("spreadsheet") || file.type.includes("excel");
|
|
@@ -10752,13 +11278,22 @@ function createSuggestionsHandler(configOrPlugin, options) {
|
|
|
10752
11278
|
return async function handler(req) {
|
|
10753
11279
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10754
11280
|
if (authResult) return authResult;
|
|
11281
|
+
const config = plugin.getConfig();
|
|
11282
|
+
const licenseCheck = enforceLicense(req, config);
|
|
11283
|
+
if (!licenseCheck.ok) return licenseCheck.response;
|
|
10755
11284
|
try {
|
|
10756
11285
|
let query = "";
|
|
10757
11286
|
let namespace = void 0;
|
|
11287
|
+
let bodyLicenseKey = void 0;
|
|
10758
11288
|
if (req.method === "POST") {
|
|
10759
11289
|
const body = await req.json().catch(() => ({}));
|
|
10760
11290
|
query = body.query || "";
|
|
10761
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
|
+
}
|
|
10762
11297
|
} else {
|
|
10763
11298
|
const url = new URL(req.url);
|
|
10764
11299
|
query = url.searchParams.get("query") || "";
|
|
@@ -10781,14 +11316,16 @@ function createHistoryHandler(configOrPlugin, options) {
|
|
|
10781
11316
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
10782
11317
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
10783
11318
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
11319
|
+
const onResolveScope = options == null ? void 0 : options.onResolveScope;
|
|
10784
11320
|
return async function handler(req) {
|
|
10785
11321
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10786
11322
|
if (authResult) return authResult;
|
|
11323
|
+
const scope = onResolveScope ? await onResolveScope(req) : void 0;
|
|
10787
11324
|
const url = new URL(req.url);
|
|
10788
11325
|
const sessionId = url.searchParams.get("sessionId") || "default";
|
|
10789
11326
|
if (req.method === "GET") {
|
|
10790
11327
|
try {
|
|
10791
|
-
const history = await storage.getHistory(sessionId);
|
|
11328
|
+
const history = await storage.getHistory(sessionId, scope);
|
|
10792
11329
|
return import_server.NextResponse.json({ history });
|
|
10793
11330
|
} catch (err) {
|
|
10794
11331
|
const message = err instanceof Error ? err.message : "Failed to fetch history";
|
|
@@ -10798,7 +11335,7 @@ function createHistoryHandler(configOrPlugin, options) {
|
|
|
10798
11335
|
try {
|
|
10799
11336
|
const body = await req.json().catch(() => ({}));
|
|
10800
11337
|
const sid = body.sessionId || sessionId;
|
|
10801
|
-
await storage.clearHistory(sid);
|
|
11338
|
+
await storage.clearHistory(sid, scope);
|
|
10802
11339
|
return import_server.NextResponse.json({ success: true });
|
|
10803
11340
|
} catch (err) {
|
|
10804
11341
|
const message = err instanceof Error ? err.message : "Failed to clear history";
|
|
@@ -10812,18 +11349,20 @@ function createFeedbackHandler(configOrPlugin, options) {
|
|
|
10812
11349
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
10813
11350
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
10814
11351
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
11352
|
+
const onResolveScope = options == null ? void 0 : options.onResolveScope;
|
|
10815
11353
|
return async function handler(req) {
|
|
10816
11354
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10817
11355
|
if (authResult) return authResult;
|
|
11356
|
+
const scope = onResolveScope ? await onResolveScope(req) : void 0;
|
|
10818
11357
|
if (req.method === "GET") {
|
|
10819
11358
|
try {
|
|
10820
11359
|
const url = new URL(req.url);
|
|
10821
11360
|
const messageId = url.searchParams.get("messageId");
|
|
10822
11361
|
if (!messageId) {
|
|
10823
|
-
const feedbackList = await storage.listFeedback();
|
|
11362
|
+
const feedbackList = await storage.listFeedback(scope);
|
|
10824
11363
|
return import_server.NextResponse.json({ feedback: feedbackList });
|
|
10825
11364
|
}
|
|
10826
|
-
const feedback = await storage.getFeedback(messageId);
|
|
11365
|
+
const feedback = await storage.getFeedback(messageId, scope);
|
|
10827
11366
|
return import_server.NextResponse.json({ feedback });
|
|
10828
11367
|
} catch (err) {
|
|
10829
11368
|
const message = err instanceof Error ? err.message : "Failed to fetch feedback";
|
|
@@ -10839,6 +11378,17 @@ function createFeedbackHandler(configOrPlugin, options) {
|
|
|
10839
11378
|
if (!rating) {
|
|
10840
11379
|
return import_server.NextResponse.json({ error: "rating is required" }, { status: 400 });
|
|
10841
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
|
+
}
|
|
10842
11392
|
await storage.saveFeedback({ messageId, sessionId, rating, comment });
|
|
10843
11393
|
return import_server.NextResponse.json({ success: true });
|
|
10844
11394
|
} catch (err) {
|
|
@@ -10853,14 +11403,15 @@ function createSessionsHandler(configOrPlugin, options) {
|
|
|
10853
11403
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
10854
11404
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
10855
11405
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
11406
|
+
const onResolveScope = options == null ? void 0 : options.onResolveScope;
|
|
10856
11407
|
return async function GET(req) {
|
|
10857
11408
|
if (req) {
|
|
10858
11409
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10859
11410
|
if (authResult) return authResult;
|
|
10860
11411
|
}
|
|
10861
|
-
void req;
|
|
10862
11412
|
try {
|
|
10863
|
-
const
|
|
11413
|
+
const scope = req && onResolveScope ? await onResolveScope(req) : void 0;
|
|
11414
|
+
const sessions = await storage.listSessions(scope);
|
|
10864
11415
|
return import_server.NextResponse.json({ sessions });
|
|
10865
11416
|
} catch (err) {
|
|
10866
11417
|
const message = err instanceof Error ? err.message : "Failed to list sessions";
|
|
@@ -10871,15 +11422,17 @@ function createSessionsHandler(configOrPlugin, options) {
|
|
|
10871
11422
|
function createRagHandler(configOrPlugin, options) {
|
|
10872
11423
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
10873
11424
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
10874
|
-
const
|
|
10875
|
-
const
|
|
10876
|
-
const
|
|
10877
|
-
const
|
|
10878
|
-
const
|
|
10879
|
-
const
|
|
10880
|
-
const
|
|
10881
|
-
const
|
|
10882
|
-
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);
|
|
10883
11436
|
async function routePostRequest(req, segment) {
|
|
10884
11437
|
switch (segment) {
|
|
10885
11438
|
case "chat":
|
|
@@ -10921,7 +11474,7 @@ function createRagHandler(configOrPlugin, options) {
|
|
|
10921
11474
|
}
|
|
10922
11475
|
}
|
|
10923
11476
|
async function getSegment(req, context) {
|
|
10924
|
-
var
|
|
11477
|
+
var _a3, _b;
|
|
10925
11478
|
const contentType = req.headers.get("content-type") || "";
|
|
10926
11479
|
if (contentType.includes("multipart/form-data")) {
|
|
10927
11480
|
return "upload";
|
|
@@ -10938,7 +11491,7 @@ function createRagHandler(configOrPlugin, options) {
|
|
|
10938
11491
|
if (pathname.endsWith("/history")) return "history";
|
|
10939
11492
|
} catch (e) {
|
|
10940
11493
|
}
|
|
10941
|
-
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;
|
|
10942
11495
|
const segments = (resolvedParams == null ? void 0 : resolvedParams.retrivora) || ((_b = resolvedParams == null ? void 0 : resolvedParams.params) == null ? void 0 : _b.retrivora) || [];
|
|
10943
11496
|
const joined = segments.join("/");
|
|
10944
11497
|
return joined || "chat";
|