@retrivora-ai/rag-engine 2.3.0 → 2.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{LicenseValidator-CENvo9o2.d.mts → BatchProcessor-7yV-UCHW.d.mts} +142 -3
- package/dist/{LicenseValidator-CsjJp2PP.d.ts → BatchProcessor-BfzuU4cK.d.ts} +142 -3
- package/dist/handlers/index.d.mts +1 -1
- package/dist/handlers/index.d.ts +1 -1
- package/dist/handlers/index.js +881 -331
- package/dist/handlers/index.mjs +881 -331
- package/dist/index-DR_O_B-W.d.ts +394 -0
- package/dist/index-fnpaCuma.d.mts +394 -0
- package/dist/index.css +58 -0
- package/dist/index.d.mts +63 -3
- package/dist/index.d.ts +63 -3
- package/dist/index.js +454 -36
- package/dist/index.mjs +453 -38
- package/dist/server.d.mts +35 -73
- package/dist/server.d.ts +35 -73
- package/dist/server.js +911 -345
- package/dist/server.mjs +911 -345
- package/package.json +3 -2
- package/src/components/ChatWidget.tsx +149 -48
- package/src/components/ChatWindow.tsx +52 -9
- package/src/components/CodeViewer.tsx +1 -1
- package/src/core/BatchProcessor.ts +42 -4
- package/src/core/CircuitBreaker.ts +118 -0
- package/src/core/DatabaseStorage.ts +55 -24
- package/src/core/FreeTierLimitsGuard.ts +281 -0
- package/src/core/LangChainAgent.ts +0 -2
- package/src/core/LicenseValidator.ts +66 -2
- package/src/core/LicenseVerifier.ts +31 -3
- package/src/core/VectorPlugin.ts +30 -0
- package/src/handlers/index.ts +491 -36
- package/src/index.css +58 -0
- package/src/index.ts +4 -0
- package/src/providers/vectordb/MilvusProvider.ts +0 -1
- package/src/providers/vectordb/MongoDBProvider.ts +0 -1
- package/src/providers/vectordb/MultiTablePostgresProvider.ts +2 -2
- package/src/providers/vectordb/RedisProvider.ts +0 -1
- package/src/providers/vectordb/WeaviateProvider.ts +0 -1
- package/src/rag/LlamaIndexIngestor.ts +0 -1
- package/src/server.ts +1 -0
- package/dist/index-BPJ3KDYI.d.ts +0 -195
- package/dist/index-Dmq5lH0j.d.mts +0 -195
package/dist/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)}`);
|
|
@@ -1355,7 +1355,6 @@ var init_MilvusProvider = __esm({
|
|
|
1355
1355
|
metadata: res["metadata"] || {}
|
|
1356
1356
|
}));
|
|
1357
1357
|
}
|
|
1358
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1359
1358
|
async delete(id, _namespace) {
|
|
1360
1359
|
await this.http.post("/v1/vector/delete", {
|
|
1361
1360
|
collectionName: this.indexName,
|
|
@@ -1439,14 +1438,14 @@ var init_QdrantProvider = __esm({
|
|
|
1439
1438
|
* Samples points from the collection to discover available payload fields.
|
|
1440
1439
|
*/
|
|
1441
1440
|
async discoverSchema() {
|
|
1442
|
-
var
|
|
1441
|
+
var _a3;
|
|
1443
1442
|
try {
|
|
1444
1443
|
const { data } = await this.http.post(`/collections/${this.indexName}/points/scroll`, {
|
|
1445
1444
|
limit: 20,
|
|
1446
1445
|
with_payload: true,
|
|
1447
1446
|
with_vector: false
|
|
1448
1447
|
});
|
|
1449
|
-
const points = ((
|
|
1448
|
+
const points = ((_a3 = data.result) == null ? void 0 : _a3.points) || [];
|
|
1450
1449
|
const keys = /* @__PURE__ */ new Set();
|
|
1451
1450
|
for (const point of points) {
|
|
1452
1451
|
const payload = point.payload || {};
|
|
@@ -1472,12 +1471,12 @@ var init_QdrantProvider = __esm({
|
|
|
1472
1471
|
* Ensures the collection exists. Creates it if missing.
|
|
1473
1472
|
*/
|
|
1474
1473
|
async ensureCollection() {
|
|
1475
|
-
var
|
|
1474
|
+
var _a3;
|
|
1476
1475
|
try {
|
|
1477
1476
|
await this.http.get(`/collections/${this.indexName}`);
|
|
1478
1477
|
console.log(`[QdrantProvider] \u2705 Collection "${this.indexName}" already exists.`);
|
|
1479
1478
|
} catch (err) {
|
|
1480
|
-
if (import_axios4.default.isAxiosError(err) && ((
|
|
1479
|
+
if (import_axios4.default.isAxiosError(err) && ((_a3 = err.response) == null ? void 0 : _a3.status) === 404) {
|
|
1481
1480
|
const opts = this.config.options;
|
|
1482
1481
|
const dimensionsForCreate = opts.dimensions || 1536;
|
|
1483
1482
|
console.log(`[QdrantProvider] \u23F3 Creating collection "${this.indexName}" (dimensions: ${dimensionsForCreate})...`);
|
|
@@ -1497,7 +1496,7 @@ var init_QdrantProvider = __esm({
|
|
|
1497
1496
|
* Ensures that a payload field has an index.
|
|
1498
1497
|
*/
|
|
1499
1498
|
async ensureIndex(fieldName, schema = "keyword") {
|
|
1500
|
-
var
|
|
1499
|
+
var _a3;
|
|
1501
1500
|
let fullPath = fieldName;
|
|
1502
1501
|
if (!this.isFlatPayload && !fieldName.includes(".") && fieldName !== "namespace" && fieldName !== this.contentField) {
|
|
1503
1502
|
fullPath = `${this.metadataField}.${fieldName}`;
|
|
@@ -1510,7 +1509,7 @@ var init_QdrantProvider = __esm({
|
|
|
1510
1509
|
console.log(`[QdrantProvider] \u2705 Ensured ${schema} index for "${fullPath}"`);
|
|
1511
1510
|
} catch (err) {
|
|
1512
1511
|
let status;
|
|
1513
|
-
if (import_axios4.default.isAxiosError(err)) status = (
|
|
1512
|
+
if (import_axios4.default.isAxiosError(err)) status = (_a3 = err.response) == null ? void 0 : _a3.status;
|
|
1514
1513
|
if (status === 409) return;
|
|
1515
1514
|
console.warn(`[QdrantProvider] \u26A0\uFE0F Could not ensure index for "${fullPath}":`, err instanceof Error ? err.message : String(err));
|
|
1516
1515
|
}
|
|
@@ -1539,7 +1538,7 @@ var init_QdrantProvider = __esm({
|
|
|
1539
1538
|
await this.http.put(`/collections/${this.indexName}/points`, payload);
|
|
1540
1539
|
}
|
|
1541
1540
|
async query(vector, topK, namespace, _filter) {
|
|
1542
|
-
var
|
|
1541
|
+
var _a3;
|
|
1543
1542
|
const must = [];
|
|
1544
1543
|
if (namespace) {
|
|
1545
1544
|
must.push({ key: "namespace", match: { value: namespace } });
|
|
@@ -1561,7 +1560,7 @@ var init_QdrantProvider = __esm({
|
|
|
1561
1560
|
limit: topK,
|
|
1562
1561
|
with_payload: true,
|
|
1563
1562
|
params: {
|
|
1564
|
-
hnsw_ef: ((
|
|
1563
|
+
hnsw_ef: ((_a3 = this.config.options) == null ? void 0 : _a3.efSearch) || Math.max(topK * 20, 128),
|
|
1565
1564
|
exact: false
|
|
1566
1565
|
},
|
|
1567
1566
|
filter: must.length > 0 ? { must } : void 0
|
|
@@ -1656,13 +1655,13 @@ var init_ChromaDBProvider = __esm({
|
|
|
1656
1655
|
* Get or create the ChromaDB collection.
|
|
1657
1656
|
*/
|
|
1658
1657
|
async initialize() {
|
|
1659
|
-
var
|
|
1658
|
+
var _a3;
|
|
1660
1659
|
try {
|
|
1661
1660
|
const { data } = await this.http.get(`/api/v1/collections/${this.indexName}`);
|
|
1662
1661
|
this.collectionId = data.id;
|
|
1663
1662
|
console.log(`[ChromaDBProvider] \u2705 Collection "${this.indexName}" found (id: ${this.collectionId})`);
|
|
1664
1663
|
} catch (err) {
|
|
1665
|
-
if (import_axios5.default.isAxiosError(err) && ((
|
|
1664
|
+
if (import_axios5.default.isAxiosError(err) && ((_a3 = err.response) == null ? void 0 : _a3.status) === 404) {
|
|
1666
1665
|
console.log(`[ChromaDBProvider] \u23F3 Collection "${this.indexName}" not found. Creating...`);
|
|
1667
1666
|
const { data } = await this.http.post("/api/v1/collections", {
|
|
1668
1667
|
name: this.indexName
|
|
@@ -1780,7 +1779,6 @@ var init_RedisProvider = __esm({
|
|
|
1780
1779
|
await this.upsert(doc, namespace);
|
|
1781
1780
|
}
|
|
1782
1781
|
}
|
|
1783
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1784
1782
|
async query(vector, topK, namespace, _filter) {
|
|
1785
1783
|
const payload = {
|
|
1786
1784
|
index: this.indexName,
|
|
@@ -1883,7 +1881,7 @@ var init_WeaviateProvider = __esm({
|
|
|
1883
1881
|
await this.http.post("/v1/batch/objects", payload);
|
|
1884
1882
|
}
|
|
1885
1883
|
async query(vector, topK, namespace, _filter) {
|
|
1886
|
-
var
|
|
1884
|
+
var _a3, _b;
|
|
1887
1885
|
const queryText = _filter == null ? void 0 : _filter.queryText;
|
|
1888
1886
|
const sanitizedFilter = this.sanitizeFilter(_filter);
|
|
1889
1887
|
const searchParams = queryText ? `hybrid: { query: ${JSON.stringify(queryText)}, alpha: 0.5 }` : `nearVector: { vector: ${JSON.stringify(vector)} }`;
|
|
@@ -1909,7 +1907,7 @@ var init_WeaviateProvider = __esm({
|
|
|
1909
1907
|
`
|
|
1910
1908
|
};
|
|
1911
1909
|
const { data } = await this.http.post("/v1/graphql", graphqlQuery);
|
|
1912
|
-
const results = ((_b = (
|
|
1910
|
+
const results = ((_b = (_a3 = data.data) == null ? void 0 : _a3.Get) == null ? void 0 : _b[this.indexName]) || [];
|
|
1913
1911
|
return results.map((res) => ({
|
|
1914
1912
|
id: res["_additional"].id,
|
|
1915
1913
|
score: 1 - res["_additional"].distance,
|
|
@@ -1917,7 +1915,6 @@ var init_WeaviateProvider = __esm({
|
|
|
1917
1915
|
metadata: res["metadata"] ? JSON.parse(res["metadata"]) : {}
|
|
1918
1916
|
}));
|
|
1919
1917
|
}
|
|
1920
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1921
1918
|
async delete(id, _namespace) {
|
|
1922
1919
|
await this.http.delete(`/v1/objects/${this.indexName}/${id}`);
|
|
1923
1920
|
}
|
|
@@ -1992,21 +1989,21 @@ var init_UniversalVectorProvider = __esm({
|
|
|
1992
1989
|
}
|
|
1993
1990
|
}
|
|
1994
1991
|
async initialize() {
|
|
1995
|
-
var
|
|
1992
|
+
var _a3;
|
|
1996
1993
|
this.http = import_axios8.default.create({
|
|
1997
1994
|
baseURL: this.opts.baseUrl,
|
|
1998
1995
|
headers: __spreadValues({
|
|
1999
1996
|
"Content-Type": "application/json"
|
|
2000
1997
|
}, this.opts.headers),
|
|
2001
|
-
timeout: (
|
|
1998
|
+
timeout: (_a3 = this.opts.timeout) != null ? _a3 : 3e4
|
|
2002
1999
|
});
|
|
2003
2000
|
if (!await this.ping()) {
|
|
2004
2001
|
throw new Error(`[UniversalVectorProvider] Failed to connect to ${this.opts.baseUrl}`);
|
|
2005
2002
|
}
|
|
2006
2003
|
}
|
|
2007
2004
|
async upsert(doc, namespace) {
|
|
2008
|
-
var
|
|
2009
|
-
const endpoint = (
|
|
2005
|
+
var _a3, _b, _c;
|
|
2006
|
+
const endpoint = (_a3 = this.opts.upsertEndpoint) != null ? _a3 : "/upsert";
|
|
2010
2007
|
const template = (_b = this.opts.upsertTemplate) != null ? _b : JSON.stringify({
|
|
2011
2008
|
id: "{{id}}",
|
|
2012
2009
|
vector: "{{vector}}",
|
|
@@ -2039,8 +2036,8 @@ var init_UniversalVectorProvider = __esm({
|
|
|
2039
2036
|
}
|
|
2040
2037
|
}
|
|
2041
2038
|
async query(vector, topK, namespace, filter) {
|
|
2042
|
-
var
|
|
2043
|
-
const endpoint = (
|
|
2039
|
+
var _a3, _b;
|
|
2040
|
+
const endpoint = (_a3 = this.opts.queryEndpoint) != null ? _a3 : "/query";
|
|
2044
2041
|
const template = (_b = this.opts.queryTemplate) != null ? _b : JSON.stringify({
|
|
2045
2042
|
vector: "{{vector}}",
|
|
2046
2043
|
limit: "{{topK}}",
|
|
@@ -2066,9 +2063,9 @@ var init_UniversalVectorProvider = __esm({
|
|
|
2066
2063
|
);
|
|
2067
2064
|
}
|
|
2068
2065
|
return results.map((item) => {
|
|
2069
|
-
var
|
|
2066
|
+
var _a4, _b2, _c, _d, _e, _f, _g2;
|
|
2070
2067
|
return {
|
|
2071
|
-
id: item[(
|
|
2068
|
+
id: item[(_a4 = this.opts.queryIdField) != null ? _a4 : "id"],
|
|
2072
2069
|
score: (_c = item[(_b2 = this.opts.queryScoreField) != null ? _b2 : "score"]) != null ? _c : 0,
|
|
2073
2070
|
content: (_e = item[(_d = this.opts.queryContentField) != null ? _d : "content"]) != null ? _e : "",
|
|
2074
2071
|
metadata: (_g2 = item[(_f = this.opts.queryMetadataField) != null ? _f : "metadata"]) != null ? _g2 : {}
|
|
@@ -2081,8 +2078,8 @@ var init_UniversalVectorProvider = __esm({
|
|
|
2081
2078
|
}
|
|
2082
2079
|
}
|
|
2083
2080
|
async delete(id, namespace) {
|
|
2084
|
-
var
|
|
2085
|
-
const endpoint = (
|
|
2081
|
+
var _a3, _b;
|
|
2082
|
+
const endpoint = (_a3 = this.opts.deleteEndpoint) != null ? _a3 : "/delete";
|
|
2086
2083
|
const template = (_b = this.opts.deleteTemplate) != null ? _b : JSON.stringify({
|
|
2087
2084
|
id: "{{id}}",
|
|
2088
2085
|
namespace: "{{namespace}}"
|
|
@@ -2100,8 +2097,8 @@ var init_UniversalVectorProvider = __esm({
|
|
|
2100
2097
|
}
|
|
2101
2098
|
}
|
|
2102
2099
|
async deleteNamespace(namespace) {
|
|
2103
|
-
var
|
|
2104
|
-
const endpoint = (
|
|
2100
|
+
var _a3;
|
|
2101
|
+
const endpoint = (_a3 = this.opts.deleteNamespaceEndpoint) != null ? _a3 : "/delete-namespace";
|
|
2105
2102
|
try {
|
|
2106
2103
|
await this.http.post(endpoint, { namespace });
|
|
2107
2104
|
} catch (error) {
|
|
@@ -2111,9 +2108,9 @@ var init_UniversalVectorProvider = __esm({
|
|
|
2111
2108
|
}
|
|
2112
2109
|
}
|
|
2113
2110
|
async ping() {
|
|
2114
|
-
var
|
|
2111
|
+
var _a3;
|
|
2115
2112
|
try {
|
|
2116
|
-
const endpoint = (
|
|
2113
|
+
const endpoint = (_a3 = this.opts.pingEndpoint) != null ? _a3 : "/health";
|
|
2117
2114
|
const response = await this.http.get(endpoint, { timeout: 5e3 });
|
|
2118
2115
|
return response.status >= 200 && response.status < 300;
|
|
2119
2116
|
} catch (e) {
|
|
@@ -2271,13 +2268,13 @@ var AuthenticationException = class extends RetrivoraError {
|
|
|
2271
2268
|
}
|
|
2272
2269
|
};
|
|
2273
2270
|
function wrapError(err, defaultCode, defaultMessage) {
|
|
2274
|
-
var
|
|
2271
|
+
var _a3;
|
|
2275
2272
|
if (err instanceof RetrivoraError) {
|
|
2276
2273
|
return err;
|
|
2277
2274
|
}
|
|
2278
2275
|
const error = err;
|
|
2279
2276
|
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) || ((
|
|
2277
|
+
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
2278
|
const code = error == null ? void 0 : error.code;
|
|
2282
2279
|
if (status === 429 || /rate[- ]?limit/i.test(message) || code === "RATE_LIMIT_EXCEEDED") {
|
|
2283
2280
|
return new RateLimitException(message, err);
|
|
@@ -2559,8 +2556,8 @@ var UI_BORDER_RADIUS_OPTIONS = ["none", "sm", "md", "lg", "xl", "full"];
|
|
|
2559
2556
|
|
|
2560
2557
|
// src/config/serverConfig.ts
|
|
2561
2558
|
function readString(env, name) {
|
|
2562
|
-
var
|
|
2563
|
-
const value = (
|
|
2559
|
+
var _a3;
|
|
2560
|
+
const value = (_a3 = env[name]) == null ? void 0 : _a3.trim();
|
|
2564
2561
|
return value ? value : void 0;
|
|
2565
2562
|
}
|
|
2566
2563
|
function readNumber(env, name, fallback) {
|
|
@@ -2573,16 +2570,16 @@ function readNumber(env, name, fallback) {
|
|
|
2573
2570
|
return parsed;
|
|
2574
2571
|
}
|
|
2575
2572
|
function readEnum(env, name, fallback, allowed) {
|
|
2576
|
-
var
|
|
2577
|
-
const value = (
|
|
2573
|
+
var _a3;
|
|
2574
|
+
const value = (_a3 = readString(env, name)) != null ? _a3 : fallback;
|
|
2578
2575
|
if (allowed.includes(value)) {
|
|
2579
2576
|
return value;
|
|
2580
2577
|
}
|
|
2581
2578
|
throw new Error(`[getRagConfig] ${name} must be one of: ${allowed.join(", ")}`);
|
|
2582
2579
|
}
|
|
2583
2580
|
function getEnvConfig(env = process.env, base) {
|
|
2584
|
-
var
|
|
2585
|
-
const licenseKey = (_d = (_c = (_b = (
|
|
2581
|
+
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;
|
|
2582
|
+
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
2583
|
const jwtProjectId = (() => {
|
|
2587
2584
|
if (!licenseKey) return void 0;
|
|
2588
2585
|
try {
|
|
@@ -2663,7 +2660,7 @@ function getEnvConfig(env = process.env, base) {
|
|
|
2663
2660
|
rest: "default",
|
|
2664
2661
|
custom: "default"
|
|
2665
2662
|
};
|
|
2666
|
-
const
|
|
2663
|
+
const isFreeTier2 = (() => {
|
|
2667
2664
|
if (!licenseKey) return true;
|
|
2668
2665
|
try {
|
|
2669
2666
|
const payload = LicenseVerifier.verify(licenseKey, projectId);
|
|
@@ -2674,13 +2671,13 @@ function getEnvConfig(env = process.env, base) {
|
|
|
2674
2671
|
}
|
|
2675
2672
|
})();
|
|
2676
2673
|
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 =
|
|
2674
|
+
const defaultLlmProvider = isFreeTier2 ? "universal_rest" : "universal_rest";
|
|
2678
2675
|
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
2676
|
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 :
|
|
2677
|
+
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
2678
|
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
2679
|
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 =
|
|
2680
|
+
const defaultEmbeddingProvider = isFreeTier2 ? "universal_rest" : "universal_rest";
|
|
2684
2681
|
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
2682
|
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
2683
|
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 +2767,8 @@ function getEnvConfig(env = process.env, base) {
|
|
|
2770
2767
|
}
|
|
2771
2768
|
} : {}), {
|
|
2772
2769
|
mcpServers: (() => {
|
|
2773
|
-
var
|
|
2774
|
-
const raw = (
|
|
2770
|
+
var _a4;
|
|
2771
|
+
const raw = (_a4 = readString(env, "MCP_SERVERS")) != null ? _a4 : readString(env, "NEXT_PUBLIC_MCP_SERVERS");
|
|
2775
2772
|
if (!raw) return void 0;
|
|
2776
2773
|
try {
|
|
2777
2774
|
return JSON.parse(raw);
|
|
@@ -2816,10 +2813,10 @@ var ConfigResolver = class {
|
|
|
2816
2813
|
* fallback behavior.
|
|
2817
2814
|
*/
|
|
2818
2815
|
static resolveUniversal(hostConfig, env = process.env) {
|
|
2819
|
-
var
|
|
2816
|
+
var _a3;
|
|
2820
2817
|
if (!hostConfig) return this.resolve(void 0, env);
|
|
2821
2818
|
const normalized = __spreadProps(__spreadValues({}, hostConfig), {
|
|
2822
|
-
vectorDb: (
|
|
2819
|
+
vectorDb: (_a3 = hostConfig.vectorDb) != null ? _a3 : hostConfig.vectorDatabase,
|
|
2823
2820
|
rag: this.mergeRetrievalWorkflow(hostConfig.rag, hostConfig.retrieval, hostConfig.workflow)
|
|
2824
2821
|
});
|
|
2825
2822
|
return this.resolve(normalized, env);
|
|
@@ -2839,11 +2836,11 @@ var ConfigResolver = class {
|
|
|
2839
2836
|
}
|
|
2840
2837
|
}
|
|
2841
2838
|
static mergeRetrievalWorkflow(rag, retrieval, workflow) {
|
|
2842
|
-
var
|
|
2839
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
2843
2840
|
if (!rag && !retrieval && !workflow) return void 0;
|
|
2844
2841
|
const normalized = __spreadValues({}, rag != null ? rag : {});
|
|
2845
2842
|
if (retrieval) {
|
|
2846
|
-
normalized.topK = (
|
|
2843
|
+
normalized.topK = (_a3 = retrieval.topK) != null ? _a3 : normalized.topK;
|
|
2847
2844
|
normalized.scoreThreshold = (_b = retrieval.scoreThreshold) != null ? _b : normalized.scoreThreshold;
|
|
2848
2845
|
normalized.useReranking = (_c = retrieval.useReranking) != null ? _c : normalized.useReranking;
|
|
2849
2846
|
if (retrieval.strategy === "hybrid") normalized.architecture = (_d = normalized.architecture) != null ? _d : "hybrid";
|
|
@@ -2971,8 +2968,8 @@ var OpenAIProvider = class {
|
|
|
2971
2968
|
};
|
|
2972
2969
|
}
|
|
2973
2970
|
async chat(messages, context, options) {
|
|
2974
|
-
var
|
|
2975
|
-
const basePrompt = (_b = (
|
|
2971
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i;
|
|
2972
|
+
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
2973
|
const systemMessage = {
|
|
2977
2974
|
role: "system",
|
|
2978
2975
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -2996,8 +2993,8 @@ var OpenAIProvider = class {
|
|
|
2996
2993
|
}
|
|
2997
2994
|
chatStream(messages, context, options) {
|
|
2998
2995
|
return __asyncGenerator(this, null, function* () {
|
|
2999
|
-
var
|
|
3000
|
-
const basePrompt = (_b = (
|
|
2996
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h;
|
|
2997
|
+
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
2998
|
const systemMessage = {
|
|
3002
2999
|
role: "system",
|
|
3003
3000
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3044,8 +3041,8 @@ var OpenAIProvider = class {
|
|
|
3044
3041
|
return results[0];
|
|
3045
3042
|
}
|
|
3046
3043
|
async batchEmbed(texts, options) {
|
|
3047
|
-
var
|
|
3048
|
-
const model = (_c = (_b = options == null ? void 0 : options.model) != null ? _b : (
|
|
3044
|
+
var _a3, _b, _c, _d, _e;
|
|
3045
|
+
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
3046
|
const apiKey = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.apiKey) != null ? _e : this.llmConfig.apiKey;
|
|
3050
3047
|
const client = apiKey !== this.llmConfig.apiKey ? new import_openai.default({ apiKey }) : this.client;
|
|
3051
3048
|
const response = await client.embeddings.create({ model, input: texts });
|
|
@@ -3122,8 +3119,8 @@ var AnthropicProvider = class {
|
|
|
3122
3119
|
};
|
|
3123
3120
|
}
|
|
3124
3121
|
async chat(messages, context, options) {
|
|
3125
|
-
var
|
|
3126
|
-
const basePrompt = (_b = (
|
|
3122
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
|
|
3123
|
+
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
3124
|
const system = buildSystemContent(basePrompt, context);
|
|
3128
3125
|
const anthropicMessages = messages.map((m) => ({
|
|
3129
3126
|
role: m.role === "assistant" ? "assistant" : "user",
|
|
@@ -3161,8 +3158,8 @@ var AnthropicProvider = class {
|
|
|
3161
3158
|
}
|
|
3162
3159
|
chatStream(messages, context, options) {
|
|
3163
3160
|
return __asyncGenerator(this, null, function* () {
|
|
3164
|
-
var
|
|
3165
|
-
const basePrompt = (_b = (
|
|
3161
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
|
|
3162
|
+
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
3163
|
const system = buildSystemContent(basePrompt, context);
|
|
3167
3164
|
const anthropicMessages = messages.map((m) => ({
|
|
3168
3165
|
role: m.role === "assistant" ? "assistant" : "user",
|
|
@@ -3246,8 +3243,8 @@ var AnthropicProvider = class {
|
|
|
3246
3243
|
var import_axios = __toESM(require("axios"));
|
|
3247
3244
|
var OllamaProvider = class {
|
|
3248
3245
|
constructor(llmConfig, embeddingConfig) {
|
|
3249
|
-
var
|
|
3250
|
-
const rawBaseURL = ((
|
|
3246
|
+
var _a3, _b, _c;
|
|
3247
|
+
const rawBaseURL = ((_a3 = llmConfig.baseUrl) != null ? _a3 : "http://localhost:11434").replace(/\/+$/, "");
|
|
3251
3248
|
const baseURL = rawBaseURL.replace(/\/(?:api\/v1|v1|api)$/i, "");
|
|
3252
3249
|
const timeout = Number((_b = llmConfig.options) == null ? void 0 : _b.timeout) || 3e5;
|
|
3253
3250
|
const headers = ((_c = llmConfig.options) == null ? void 0 : _c.headers) || {};
|
|
@@ -3307,8 +3304,8 @@ var OllamaProvider = class {
|
|
|
3307
3304
|
};
|
|
3308
3305
|
}
|
|
3309
3306
|
async chat(messages, context, options) {
|
|
3310
|
-
var
|
|
3311
|
-
const basePrompt = (_b = (
|
|
3307
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
3308
|
+
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
3309
|
const system = buildSystemContent(basePrompt, context);
|
|
3313
3310
|
const { data } = await this.http.post("/api/chat", {
|
|
3314
3311
|
model: this.llmConfig.model,
|
|
@@ -3326,8 +3323,8 @@ var OllamaProvider = class {
|
|
|
3326
3323
|
}
|
|
3327
3324
|
chatStream(messages, context, options) {
|
|
3328
3325
|
return __asyncGenerator(this, null, function* () {
|
|
3329
|
-
var
|
|
3330
|
-
const basePrompt = (_b = (
|
|
3326
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h;
|
|
3327
|
+
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
3328
|
const system = buildSystemContent(basePrompt, context);
|
|
3332
3329
|
const response = yield new __await(this.http.post("/api/chat", {
|
|
3333
3330
|
model: this.llmConfig.model,
|
|
@@ -3385,8 +3382,8 @@ var OllamaProvider = class {
|
|
|
3385
3382
|
});
|
|
3386
3383
|
}
|
|
3387
3384
|
async embed(text, options) {
|
|
3388
|
-
var
|
|
3389
|
-
const model = (_c = (_b = options == null ? void 0 : options.model) != null ? _b : (
|
|
3385
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
|
|
3386
|
+
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
3387
|
const baseURL = (_f = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.baseUrl) != null ? _e : this.llmConfig.baseUrl) != null ? _f : "http://localhost:11434";
|
|
3391
3388
|
const client = baseURL !== ((_g2 = this.llmConfig.baseUrl) != null ? _g2 : "http://localhost:11434") ? import_axios.default.create({ baseURL, timeout: 6e4 }) : this.http;
|
|
3392
3389
|
let prompt = text;
|
|
@@ -3487,9 +3484,9 @@ var GeminiProvider = class {
|
|
|
3487
3484
|
static getHealthChecker() {
|
|
3488
3485
|
return {
|
|
3489
3486
|
async check(config) {
|
|
3490
|
-
var
|
|
3487
|
+
var _a3, _b;
|
|
3491
3488
|
const timestamp = Date.now();
|
|
3492
|
-
const apiKey = (_b = (
|
|
3489
|
+
const apiKey = (_b = (_a3 = config.apiKey) != null ? _a3 : process.env.GOOGLE_GENAI_API_KEY) != null ? _b : "";
|
|
3493
3490
|
const modelName = sanitizeModel(config.model);
|
|
3494
3491
|
try {
|
|
3495
3492
|
const { GoogleGenerativeAI: GoogleGenerativeAI2 } = await import("@google/generative-ai");
|
|
@@ -3519,16 +3516,16 @@ var GeminiProvider = class {
|
|
|
3519
3516
|
/** Resolve the embedding client — uses a separate client when the embedding
|
|
3520
3517
|
* API key differs from the LLM API key. */
|
|
3521
3518
|
get embeddingClient() {
|
|
3522
|
-
var
|
|
3523
|
-
if (((
|
|
3519
|
+
var _a3;
|
|
3520
|
+
if (((_a3 = this.embeddingConfig) == null ? void 0 : _a3.apiKey) && this.embeddingConfig.apiKey !== this.llmConfig.apiKey) {
|
|
3524
3521
|
return buildClient(this.embeddingConfig.apiKey);
|
|
3525
3522
|
}
|
|
3526
3523
|
return this.client;
|
|
3527
3524
|
}
|
|
3528
3525
|
/** Resolve the embedding model to use, in order of specificity. */
|
|
3529
3526
|
resolveEmbeddingModel(optionsModel) {
|
|
3530
|
-
var
|
|
3531
|
-
return sanitizeModel((_b = optionsModel != null ? optionsModel : (
|
|
3527
|
+
var _a3, _b;
|
|
3528
|
+
return sanitizeModel((_b = optionsModel != null ? optionsModel : (_a3 = this.embeddingConfig) == null ? void 0 : _a3.model) != null ? _b : DEFAULT_EMBEDDING_MODEL);
|
|
3532
3529
|
}
|
|
3533
3530
|
/**
|
|
3534
3531
|
* Convert ChatMessage[] to the Gemini contents format.
|
|
@@ -3548,8 +3545,8 @@ var GeminiProvider = class {
|
|
|
3548
3545
|
// ILLMProvider — chat
|
|
3549
3546
|
// -------------------------------------------------------------------------
|
|
3550
3547
|
async chat(messages, context, options) {
|
|
3551
|
-
var
|
|
3552
|
-
const basePrompt = (_b = (
|
|
3548
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
3549
|
+
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
3550
|
const model = this.client.getGenerativeModel({
|
|
3554
3551
|
model: this.llmConfig.model,
|
|
3555
3552
|
systemInstruction: buildSystemContent(basePrompt, context)
|
|
@@ -3566,8 +3563,8 @@ var GeminiProvider = class {
|
|
|
3566
3563
|
}
|
|
3567
3564
|
chatStream(messages, context, options) {
|
|
3568
3565
|
return __asyncGenerator(this, null, function* () {
|
|
3569
|
-
var
|
|
3570
|
-
const basePrompt = (_b = (
|
|
3566
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
3567
|
+
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
3568
|
const model = this.client.getGenerativeModel({
|
|
3572
3569
|
model: this.llmConfig.model,
|
|
3573
3570
|
systemInstruction: buildSystemContent(basePrompt, context)
|
|
@@ -3602,11 +3599,11 @@ var GeminiProvider = class {
|
|
|
3602
3599
|
// ILLMProvider — embeddings
|
|
3603
3600
|
// -------------------------------------------------------------------------
|
|
3604
3601
|
async embed(text, options) {
|
|
3605
|
-
var
|
|
3602
|
+
var _a3, _b;
|
|
3606
3603
|
const content = applyPrefix(
|
|
3607
3604
|
text,
|
|
3608
3605
|
options == null ? void 0 : options.taskType,
|
|
3609
|
-
(
|
|
3606
|
+
(_a3 = this.embeddingConfig) == null ? void 0 : _a3.queryPrefix,
|
|
3610
3607
|
(_b = this.embeddingConfig) == null ? void 0 : _b.documentPrefix
|
|
3611
3608
|
);
|
|
3612
3609
|
const modelName = this.resolveEmbeddingModel(options == null ? void 0 : options.model);
|
|
@@ -3623,7 +3620,7 @@ var GeminiProvider = class {
|
|
|
3623
3620
|
const modelName = this.resolveEmbeddingModel(options == null ? void 0 : options.model);
|
|
3624
3621
|
const model = this.embeddingClient.getGenerativeModel({ model: modelName });
|
|
3625
3622
|
const requests = texts.map((text) => {
|
|
3626
|
-
var
|
|
3623
|
+
var _a3, _b;
|
|
3627
3624
|
return {
|
|
3628
3625
|
content: {
|
|
3629
3626
|
role: "user",
|
|
@@ -3631,7 +3628,7 @@ var GeminiProvider = class {
|
|
|
3631
3628
|
text: applyPrefix(
|
|
3632
3629
|
text,
|
|
3633
3630
|
options == null ? void 0 : options.taskType,
|
|
3634
|
-
(
|
|
3631
|
+
(_a3 = this.embeddingConfig) == null ? void 0 : _a3.queryPrefix,
|
|
3635
3632
|
(_b = this.embeddingConfig) == null ? void 0 : _b.documentPrefix
|
|
3636
3633
|
)
|
|
3637
3634
|
}]
|
|
@@ -3648,8 +3645,8 @@ var GeminiProvider = class {
|
|
|
3648
3645
|
throw err;
|
|
3649
3646
|
});
|
|
3650
3647
|
return response.embeddings.map((e) => {
|
|
3651
|
-
var
|
|
3652
|
-
return (
|
|
3648
|
+
var _a3;
|
|
3649
|
+
return (_a3 = e.values) != null ? _a3 : [];
|
|
3653
3650
|
});
|
|
3654
3651
|
}
|
|
3655
3652
|
// -------------------------------------------------------------------------
|
|
@@ -3738,8 +3735,8 @@ var GroqProvider = class {
|
|
|
3738
3735
|
};
|
|
3739
3736
|
}
|
|
3740
3737
|
async chat(messages, context, options) {
|
|
3741
|
-
var
|
|
3742
|
-
const basePrompt = (_b = (
|
|
3738
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i;
|
|
3739
|
+
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
3740
|
const systemMessage = {
|
|
3744
3741
|
role: "system",
|
|
3745
3742
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3763,8 +3760,8 @@ var GroqProvider = class {
|
|
|
3763
3760
|
}
|
|
3764
3761
|
chatStream(messages, context, options) {
|
|
3765
3762
|
return __asyncGenerator(this, null, function* () {
|
|
3766
|
-
var
|
|
3767
|
-
const basePrompt = (_b = (
|
|
3763
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h;
|
|
3764
|
+
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
3765
|
const systemMessage = {
|
|
3769
3766
|
role: "system",
|
|
3770
3767
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3898,8 +3895,8 @@ var QwenProvider = class {
|
|
|
3898
3895
|
};
|
|
3899
3896
|
}
|
|
3900
3897
|
async chat(messages, context, options) {
|
|
3901
|
-
var
|
|
3902
|
-
const basePrompt = (_b = (
|
|
3898
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i;
|
|
3899
|
+
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
3900
|
const systemMessage = {
|
|
3904
3901
|
role: "system",
|
|
3905
3902
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3923,8 +3920,8 @@ var QwenProvider = class {
|
|
|
3923
3920
|
}
|
|
3924
3921
|
chatStream(messages, context, options) {
|
|
3925
3922
|
return __asyncGenerator(this, null, function* () {
|
|
3926
|
-
var
|
|
3927
|
-
const basePrompt = (_b = (
|
|
3923
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h;
|
|
3924
|
+
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
3925
|
const systemMessage = {
|
|
3929
3926
|
role: "system",
|
|
3930
3927
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3971,8 +3968,8 @@ var QwenProvider = class {
|
|
|
3971
3968
|
return results[0];
|
|
3972
3969
|
}
|
|
3973
3970
|
async batchEmbed(texts, options) {
|
|
3974
|
-
var
|
|
3975
|
-
const model = (_c = (_b = options == null ? void 0 : options.model) != null ? _b : (
|
|
3971
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
3972
|
+
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
3973
|
const apiKey = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.apiKey) != null ? _e : this.llmConfig.apiKey;
|
|
3977
3974
|
const client = apiKey !== this.llmConfig.apiKey ? new import_openai3.default({
|
|
3978
3975
|
apiKey,
|
|
@@ -4033,9 +4030,9 @@ var LLM_PROFILES = {
|
|
|
4033
4030
|
|
|
4034
4031
|
// src/llm/providers/UniversalLLMAdapter.ts
|
|
4035
4032
|
function extractContent(obj) {
|
|
4036
|
-
var
|
|
4033
|
+
var _a3, _b, _c;
|
|
4037
4034
|
if (!obj || typeof obj !== "object") return void 0;
|
|
4038
|
-
const choice = (
|
|
4035
|
+
const choice = (_a3 = obj.choices) == null ? void 0 : _a3[0];
|
|
4039
4036
|
if (!choice) return void 0;
|
|
4040
4037
|
if (typeof ((_b = choice.message) == null ? void 0 : _b.content) === "string") return choice.message.content;
|
|
4041
4038
|
if (typeof ((_c = choice.delta) == null ? void 0 : _c.content) === "string") return choice.delta.content;
|
|
@@ -4045,10 +4042,10 @@ function extractContent(obj) {
|
|
|
4045
4042
|
}
|
|
4046
4043
|
var UniversalLLMAdapter = class {
|
|
4047
4044
|
constructor(config) {
|
|
4048
|
-
var
|
|
4045
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h;
|
|
4049
4046
|
this.model = config.model;
|
|
4050
4047
|
const llmConfig = config;
|
|
4051
|
-
const options = (
|
|
4048
|
+
const options = (_a3 = llmConfig.options) != null ? _a3 : {};
|
|
4052
4049
|
let profile = {};
|
|
4053
4050
|
if (typeof options.profile === "string") {
|
|
4054
4051
|
profile = LLM_PROFILES[options.profile] || {};
|
|
@@ -4074,8 +4071,8 @@ var UniversalLLMAdapter = class {
|
|
|
4074
4071
|
});
|
|
4075
4072
|
}
|
|
4076
4073
|
async chat(messages, context) {
|
|
4077
|
-
var
|
|
4078
|
-
const path2 = (
|
|
4074
|
+
var _a3, _b, _c, _d, _e;
|
|
4075
|
+
const path2 = (_a3 = this.opts.chatPath) != null ? _a3 : "/chat/completions";
|
|
4079
4076
|
const safeMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
|
|
4080
4077
|
role: m.role || "user",
|
|
4081
4078
|
content: typeof m.content === "string" ? m.content : m.content != null ? String(m.content) : ""
|
|
@@ -4141,8 +4138,8 @@ ${context != null ? context : "None"}` },
|
|
|
4141
4138
|
*/
|
|
4142
4139
|
chatStream(messages, context) {
|
|
4143
4140
|
return __asyncGenerator(this, null, function* () {
|
|
4144
|
-
var
|
|
4145
|
-
const path2 = (
|
|
4141
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
4142
|
+
const path2 = (_a3 = this.opts.chatPath) != null ? _a3 : "/chat/completions";
|
|
4146
4143
|
const url = `${this.baseUrl.replace(/\/$/, "")}${path2}`;
|
|
4147
4144
|
const extractPath = ((_b = this.opts.responseExtractPath) != null ? _b : "choices[0].message.content").replace("message.content", "delta.content");
|
|
4148
4145
|
const safeMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
|
|
@@ -4268,8 +4265,8 @@ ${context != null ? context : "None"}` },
|
|
|
4268
4265
|
});
|
|
4269
4266
|
}
|
|
4270
4267
|
async embed(text) {
|
|
4271
|
-
var
|
|
4272
|
-
const path2 = (
|
|
4268
|
+
var _a3, _b, _c, _d, _e;
|
|
4269
|
+
const path2 = (_a3 = this.opts.embedPath) != null ? _a3 : "/embeddings";
|
|
4273
4270
|
const payload = this.opts.embedPayloadTemplate ? buildPayload(this.opts.embedPayloadTemplate, { input: text, model: this.model }) : { input: text, model: this.model };
|
|
4274
4271
|
try {
|
|
4275
4272
|
const { data: data2 } = await this.http.post(path2, payload);
|
|
@@ -4358,7 +4355,7 @@ var LLMFactory = class _LLMFactory {
|
|
|
4358
4355
|
];
|
|
4359
4356
|
}
|
|
4360
4357
|
static create(llmConfig, embeddingConfig) {
|
|
4361
|
-
var
|
|
4358
|
+
var _a3, _b, _c;
|
|
4362
4359
|
switch (llmConfig.provider) {
|
|
4363
4360
|
case "openai":
|
|
4364
4361
|
return new OpenAIProvider(llmConfig, embeddingConfig);
|
|
@@ -4377,7 +4374,7 @@ var LLMFactory = class _LLMFactory {
|
|
|
4377
4374
|
case "custom":
|
|
4378
4375
|
return new UniversalLLMAdapter(llmConfig);
|
|
4379
4376
|
default: {
|
|
4380
|
-
const providerName = String((
|
|
4377
|
+
const providerName = String((_a3 = llmConfig.provider) != null ? _a3 : "").toLowerCase();
|
|
4381
4378
|
const customFactory = customProviders.get(providerName);
|
|
4382
4379
|
if (customFactory) {
|
|
4383
4380
|
return customFactory(llmConfig);
|
|
@@ -4479,7 +4476,7 @@ var ProviderRegistry = class {
|
|
|
4479
4476
|
return null;
|
|
4480
4477
|
}
|
|
4481
4478
|
static async loadVectorProviderClass(provider) {
|
|
4482
|
-
var
|
|
4479
|
+
var _a3;
|
|
4483
4480
|
if (this.vectorProviders[provider]) return this.vectorProviders[provider];
|
|
4484
4481
|
switch (provider) {
|
|
4485
4482
|
case "pinecone": {
|
|
@@ -4488,7 +4485,7 @@ var ProviderRegistry = class {
|
|
|
4488
4485
|
}
|
|
4489
4486
|
case "pgvector":
|
|
4490
4487
|
case "postgresql": {
|
|
4491
|
-
const postgresMode = ((
|
|
4488
|
+
const postgresMode = ((_a3 = process.env.POSTGRES_MODE) != null ? _a3 : "multi").toLowerCase();
|
|
4492
4489
|
if (postgresMode === "single") {
|
|
4493
4490
|
const { PostgreSQLProvider: PostgreSQLProvider2 } = await Promise.resolve().then(() => (init_PostgreSQLProvider(), PostgreSQLProvider_exports));
|
|
4494
4491
|
return PostgreSQLProvider2;
|
|
@@ -4711,7 +4708,7 @@ var ConfigValidator = class {
|
|
|
4711
4708
|
// package.json
|
|
4712
4709
|
var package_default = {
|
|
4713
4710
|
name: "@retrivora-ai/rag-engine",
|
|
4714
|
-
version: "2.3.
|
|
4711
|
+
version: "2.3.2",
|
|
4715
4712
|
description: "Retrivora AI is a plug-and-play AI engine for RAG chat experiences \u2014 generic vector DB + LLM provider, embeddable or standalone.",
|
|
4716
4713
|
author: "Abhinav Alkuchi",
|
|
4717
4714
|
license: "UNLICENSED",
|
|
@@ -4790,6 +4787,7 @@ var package_default = {
|
|
|
4790
4787
|
build: "npm run build:pkg",
|
|
4791
4788
|
"build:pkg": "npx @tailwindcss/cli -i src/tailwind.css -o src/index.css && tsup src/index.ts src/handlers/index.ts src/server.ts --format cjs,esm --dts --clean --no-splitting --tsconfig tsconfig.build.json --external react,react-dom,next,mongodb,pg,openai,@anthropic-ai/sdk,@pinecone-database/pinecone,axios,lucide-react,mammoth,pdf-parse,xlsx,react-markdown,remark-gfm,next-themes,langchain,@langchain/core,@langchain/openai,llamaindex --inject-style && npx @tailwindcss/cli -i src/tailwind.css -o dist/index.css",
|
|
4792
4789
|
lint: "eslint",
|
|
4790
|
+
typecheck: "tsc --noEmit -p tsconfig.build.json",
|
|
4793
4791
|
clean: "rm -rf dist"
|
|
4794
4792
|
},
|
|
4795
4793
|
peerDependencies: {
|
|
@@ -5016,8 +5014,8 @@ var Reranker = class {
|
|
|
5016
5014
|
return matches.sort((a, b) => b.score - a.score).slice(0, limit);
|
|
5017
5015
|
}
|
|
5018
5016
|
const scoredMatches = matches.map((match) => {
|
|
5019
|
-
var
|
|
5020
|
-
const contentLower = ((
|
|
5017
|
+
var _a3;
|
|
5018
|
+
const contentLower = ((_a3 = match == null ? void 0 : match.content) != null ? _a3 : "").toLowerCase();
|
|
5021
5019
|
let keywordScore = 0;
|
|
5022
5020
|
keywords.forEach((keyword) => {
|
|
5023
5021
|
if (contentLower.includes(keyword)) {
|
|
@@ -5039,8 +5037,8 @@ var Reranker = class {
|
|
|
5039
5037
|
|
|
5040
5038
|
Documents:
|
|
5041
5039
|
${topN.map((m, i) => {
|
|
5042
|
-
var
|
|
5043
|
-
return `[${i}] ${((
|
|
5040
|
+
var _a3;
|
|
5041
|
+
return `[${i}] ${((_a3 = m == null ? void 0 : m.content) != null ? _a3 : "").replace(/\n/g, " ")}`;
|
|
5044
5042
|
}).join("\n")}` }],
|
|
5045
5043
|
"",
|
|
5046
5044
|
{
|
|
@@ -5084,11 +5082,11 @@ var LlamaIndexIngestor = class {
|
|
|
5084
5082
|
* than standard character-count splitting.
|
|
5085
5083
|
*/
|
|
5086
5084
|
async chunk(text, options = {}) {
|
|
5087
|
-
var
|
|
5085
|
+
var _a3, _b;
|
|
5088
5086
|
try {
|
|
5089
5087
|
const { Document, SentenceSplitter, MetadataMode } = await import(`${"llamaindex"}`);
|
|
5090
5088
|
const splitter = new SentenceSplitter({
|
|
5091
|
-
chunkSize: (
|
|
5089
|
+
chunkSize: (_a3 = options.chunkSize) != null ? _a3 : 1e3,
|
|
5092
5090
|
chunkOverlap: (_b = options.chunkOverlap) != null ? _b : 200
|
|
5093
5091
|
});
|
|
5094
5092
|
const doc = new Document({ text, metadata: options.metadata || {} });
|
|
@@ -5176,7 +5174,6 @@ When presenting structured data, statistics, or comparisons, decide if it is bes
|
|
|
5176
5174
|
finalSystemPrompt += chartInstruction;
|
|
5177
5175
|
}
|
|
5178
5176
|
this.agent = createAgent({
|
|
5179
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5180
5177
|
model: chatModel,
|
|
5181
5178
|
tools: [searchTool],
|
|
5182
5179
|
systemPrompt: finalSystemPrompt
|
|
@@ -5197,7 +5194,7 @@ ${error instanceof Error ? error.message : String(error)}`
|
|
|
5197
5194
|
* The agent returns `{ messages: [...] }` — the last message is the final answer.
|
|
5198
5195
|
*/
|
|
5199
5196
|
async run(input, chatHistory = []) {
|
|
5200
|
-
var
|
|
5197
|
+
var _a3, _b, _c;
|
|
5201
5198
|
if (!this.agent) {
|
|
5202
5199
|
throw new Error("[LangChainAgent] Agent not initialized. Call initialize() first.");
|
|
5203
5200
|
}
|
|
@@ -5208,7 +5205,7 @@ ${error instanceof Error ? error.message : String(error)}`
|
|
|
5208
5205
|
const response = await this.agent.invoke({
|
|
5209
5206
|
messages: [...historyMessages, new HumanMessage(input)]
|
|
5210
5207
|
});
|
|
5211
|
-
const lastMessage = (
|
|
5208
|
+
const lastMessage = (_a3 = response == null ? void 0 : response.messages) == null ? void 0 : _a3.at(-1);
|
|
5212
5209
|
if (lastMessage && typeof lastMessage.content === "string") {
|
|
5213
5210
|
return lastMessage.content;
|
|
5214
5211
|
}
|
|
@@ -5260,7 +5257,7 @@ var MCPClient = class {
|
|
|
5260
5257
|
}
|
|
5261
5258
|
}
|
|
5262
5259
|
async connectStdio() {
|
|
5263
|
-
var
|
|
5260
|
+
var _a3;
|
|
5264
5261
|
const cmd = this.config.command;
|
|
5265
5262
|
if (!cmd) {
|
|
5266
5263
|
throw new Error(`[MCPClient] Command option is required for stdio transport on "${this.config.name}"`);
|
|
@@ -5275,7 +5272,7 @@ var MCPClient = class {
|
|
|
5275
5272
|
this.stdioBuffer += data.toString("utf-8");
|
|
5276
5273
|
this.processStdioLines();
|
|
5277
5274
|
});
|
|
5278
|
-
(
|
|
5275
|
+
(_a3 = this.childProcess.stderr) == null ? void 0 : _a3.on("data", (data) => {
|
|
5279
5276
|
console.warn(`[MCPClient] [stderr] [${this.config.name}]:`, data.toString("utf-8"));
|
|
5280
5277
|
});
|
|
5281
5278
|
this.childProcess.on("close", (code) => {
|
|
@@ -5350,14 +5347,14 @@ var MCPClient = class {
|
|
|
5350
5347
|
}
|
|
5351
5348
|
}
|
|
5352
5349
|
async sendNotification(method, params) {
|
|
5353
|
-
var
|
|
5350
|
+
var _a3;
|
|
5354
5351
|
const notification = {
|
|
5355
5352
|
jsonrpc: "2.0",
|
|
5356
5353
|
method,
|
|
5357
5354
|
params
|
|
5358
5355
|
};
|
|
5359
5356
|
if (this.config.transport === "stdio") {
|
|
5360
|
-
if ((
|
|
5357
|
+
if ((_a3 = this.childProcess) == null ? void 0 : _a3.stdin) {
|
|
5361
5358
|
this.childProcess.stdin.write(JSON.stringify(notification) + "\n", "utf-8");
|
|
5362
5359
|
}
|
|
5363
5360
|
} else if (this.sseUrl) {
|
|
@@ -5435,11 +5432,11 @@ var MCPRegistry = class {
|
|
|
5435
5432
|
// src/core/MultiAgentCoordinator.ts
|
|
5436
5433
|
var MultiAgentCoordinator = class {
|
|
5437
5434
|
constructor(options) {
|
|
5438
|
-
var
|
|
5435
|
+
var _a3;
|
|
5439
5436
|
this.llmProvider = options.llmProvider;
|
|
5440
5437
|
this.mcpRegistry = options.mcpRegistry;
|
|
5441
5438
|
this.documentSearch = options.documentSearch;
|
|
5442
|
-
this.maxIterations = (
|
|
5439
|
+
this.maxIterations = (_a3 = options.maxIterations) != null ? _a3 : 5;
|
|
5443
5440
|
}
|
|
5444
5441
|
/**
|
|
5445
5442
|
* Run the multi-agent coordination loop synchronously and return the final response.
|
|
@@ -5491,8 +5488,8 @@ Available Tools:
|
|
|
5491
5488
|
|
|
5492
5489
|
${mcpTools.length > 0 ? "MCP Server Tools:" : ""}
|
|
5493
5490
|
${mcpTools.map((mt) => {
|
|
5494
|
-
var
|
|
5495
|
-
return `- ${mt.tool.name}(${JSON.stringify(((
|
|
5491
|
+
var _a3;
|
|
5492
|
+
return `- ${mt.tool.name}(${JSON.stringify(((_a3 = mt.tool.inputSchema) == null ? void 0 : _a3.properties) || {})}): ${mt.tool.description || "No description provided."}`;
|
|
5496
5493
|
}).join("\n")}
|
|
5497
5494
|
|
|
5498
5495
|
Tool Calling Protocol:
|
|
@@ -5650,6 +5647,100 @@ ${toolResultText}`
|
|
|
5650
5647
|
}
|
|
5651
5648
|
};
|
|
5652
5649
|
|
|
5650
|
+
// src/core/CircuitBreaker.ts
|
|
5651
|
+
var CircuitBreaker = class {
|
|
5652
|
+
constructor(options = {}) {
|
|
5653
|
+
this.state = "closed";
|
|
5654
|
+
this.failureCount = 0;
|
|
5655
|
+
this.successCount = 0;
|
|
5656
|
+
this.lastFailureAt = 0;
|
|
5657
|
+
this.halfOpenCalls = 0;
|
|
5658
|
+
var _a3, _b, _c;
|
|
5659
|
+
this.failureThreshold = (_a3 = options.failureThreshold) != null ? _a3 : 5;
|
|
5660
|
+
this.resetTimeoutMs = (_b = options.resetTimeoutMs) != null ? _b : 3e4;
|
|
5661
|
+
this.halfOpenMaxCalls = (_c = options.halfOpenMaxCalls) != null ? _c : 1;
|
|
5662
|
+
}
|
|
5663
|
+
record(success) {
|
|
5664
|
+
const now = Date.now();
|
|
5665
|
+
if (success) {
|
|
5666
|
+
this.successCount++;
|
|
5667
|
+
if (this.state === "half-open") {
|
|
5668
|
+
this.state = "closed";
|
|
5669
|
+
this.failureCount = 0;
|
|
5670
|
+
this.halfOpenCalls = 0;
|
|
5671
|
+
this.successCount = 1;
|
|
5672
|
+
} else if (this.state === "closed") {
|
|
5673
|
+
if (this.successCount >= this.failureThreshold) {
|
|
5674
|
+
this.failureCount = Math.max(0, this.failureCount - 1);
|
|
5675
|
+
this.successCount = 0;
|
|
5676
|
+
}
|
|
5677
|
+
}
|
|
5678
|
+
} else {
|
|
5679
|
+
this.failureCount++;
|
|
5680
|
+
this.lastFailureAt = now;
|
|
5681
|
+
this.successCount = 0;
|
|
5682
|
+
if (this.state === "half-open") {
|
|
5683
|
+
this.state = "open";
|
|
5684
|
+
this.halfOpenCalls = 0;
|
|
5685
|
+
} else if (this.state === "closed" && this.failureCount >= this.failureThreshold) {
|
|
5686
|
+
this.state = "open";
|
|
5687
|
+
}
|
|
5688
|
+
}
|
|
5689
|
+
}
|
|
5690
|
+
canExecute() {
|
|
5691
|
+
const now = Date.now();
|
|
5692
|
+
if (this.state === "closed") {
|
|
5693
|
+
return true;
|
|
5694
|
+
}
|
|
5695
|
+
if (this.state === "open") {
|
|
5696
|
+
if (now - this.lastFailureAt >= this.resetTimeoutMs) {
|
|
5697
|
+
this.state = "half-open";
|
|
5698
|
+
this.halfOpenCalls = 0;
|
|
5699
|
+
return true;
|
|
5700
|
+
}
|
|
5701
|
+
return false;
|
|
5702
|
+
}
|
|
5703
|
+
if (this.state === "half-open") {
|
|
5704
|
+
return this.halfOpenCalls < this.halfOpenMaxCalls;
|
|
5705
|
+
}
|
|
5706
|
+
return true;
|
|
5707
|
+
}
|
|
5708
|
+
async wrap(fn) {
|
|
5709
|
+
if (!this.canExecute()) {
|
|
5710
|
+
const retryAfterSec = Math.ceil(
|
|
5711
|
+
Math.max(0, this.resetTimeoutMs - (Date.now() - this.lastFailureAt)) / 1e3
|
|
5712
|
+
);
|
|
5713
|
+
throw new Error(
|
|
5714
|
+
`Circuit breaker is open. Try again in ${retryAfterSec}s. Failed ${this.failureCount}/${this.failureThreshold} consecutive calls.`
|
|
5715
|
+
);
|
|
5716
|
+
}
|
|
5717
|
+
if (this.state === "half-open") {
|
|
5718
|
+
this.halfOpenCalls++;
|
|
5719
|
+
}
|
|
5720
|
+
try {
|
|
5721
|
+
const result = await fn();
|
|
5722
|
+
this.record(true);
|
|
5723
|
+
return result;
|
|
5724
|
+
} catch (err) {
|
|
5725
|
+
this.record(false);
|
|
5726
|
+
throw err;
|
|
5727
|
+
}
|
|
5728
|
+
}
|
|
5729
|
+
getState() {
|
|
5730
|
+
return this.state;
|
|
5731
|
+
}
|
|
5732
|
+
getFailureCount() {
|
|
5733
|
+
return this.failureCount;
|
|
5734
|
+
}
|
|
5735
|
+
reset() {
|
|
5736
|
+
this.state = "closed";
|
|
5737
|
+
this.failureCount = 0;
|
|
5738
|
+
this.successCount = 0;
|
|
5739
|
+
this.lastFailureAt = 0;
|
|
5740
|
+
this.halfOpenCalls = 0;
|
|
5741
|
+
}
|
|
5742
|
+
};
|
|
5743
|
+
|
|
5653
5744
|
// src/core/BatchProcessor.ts
|
|
5654
5745
|
function isTransientError(error) {
|
|
5655
5746
|
if (!(error instanceof Error)) return false;
|
|
@@ -5673,7 +5764,34 @@ function calculateBackoffDelay(attempt, initialDelayMs, maxDelayMs, multiplier)
|
|
|
5673
5764
|
function sleep(ms) {
|
|
5674
5765
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
5675
5766
|
}
|
|
5676
|
-
var
|
|
5767
|
+
var _BatchProcessor = class _BatchProcessor {
|
|
5768
|
+
/**
|
|
5769
|
+
* Execute a processor call through the circuit breaker.
|
|
5770
|
+
* Only transient failures count toward opening the circuit.
|
|
5771
|
+
*/
|
|
5772
|
+
static async executeWithCircuitBreaker(processor) {
|
|
5773
|
+
if (!this.cb.canExecute()) {
|
|
5774
|
+
const retryAfterSec = Math.ceil(
|
|
5775
|
+
Math.max(0, 3e4 - (Date.now() - this.cb.lastFailureAt || 0)) / 1e3
|
|
5776
|
+
);
|
|
5777
|
+
throw new Error(
|
|
5778
|
+
`[BatchProcessor] Circuit breaker is open. Try again in ${retryAfterSec}s.`
|
|
5779
|
+
);
|
|
5780
|
+
}
|
|
5781
|
+
if (this.cb.state === "half-open") {
|
|
5782
|
+
this.cb.halfOpenCalls++;
|
|
5783
|
+
}
|
|
5784
|
+
try {
|
|
5785
|
+
const result = await processor();
|
|
5786
|
+
this.cb.record(true);
|
|
5787
|
+
return result;
|
|
5788
|
+
} catch (err) {
|
|
5789
|
+
if (isTransientError(err)) {
|
|
5790
|
+
this.cb.record(false);
|
|
5791
|
+
}
|
|
5792
|
+
throw err;
|
|
5793
|
+
}
|
|
5794
|
+
}
|
|
5677
5795
|
/**
|
|
5678
5796
|
* Processes an array of items in configurable batches with retry logic.
|
|
5679
5797
|
*
|
|
@@ -5714,7 +5832,7 @@ var BatchProcessor = class {
|
|
|
5714
5832
|
let lastError;
|
|
5715
5833
|
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
5716
5834
|
try {
|
|
5717
|
-
const result = await processor(batch);
|
|
5835
|
+
const result = await _BatchProcessor.executeWithCircuitBreaker(() => processor(batch));
|
|
5718
5836
|
results.push(result);
|
|
5719
5837
|
success = true;
|
|
5720
5838
|
break;
|
|
@@ -5772,7 +5890,7 @@ ${errorMessages}`
|
|
|
5772
5890
|
let lastError;
|
|
5773
5891
|
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
5774
5892
|
try {
|
|
5775
|
-
const result = await processor(item);
|
|
5893
|
+
const result = await _BatchProcessor.executeWithCircuitBreaker(() => processor(item));
|
|
5776
5894
|
results.push(result);
|
|
5777
5895
|
success = true;
|
|
5778
5896
|
break;
|
|
@@ -5845,7 +5963,7 @@ ${errorMessages}`
|
|
|
5845
5963
|
}));
|
|
5846
5964
|
const chunkPromises = chunk.map(async ({ item, originalIndex }) => {
|
|
5847
5965
|
try {
|
|
5848
|
-
const result = await processor(item);
|
|
5966
|
+
const result = await _BatchProcessor.executeWithCircuitBreaker(() => processor(item));
|
|
5849
5967
|
return { success: true, result, index: originalIndex };
|
|
5850
5968
|
} catch (err) {
|
|
5851
5969
|
const error = err instanceof Error ? err : new Error(String(err));
|
|
@@ -5873,6 +5991,12 @@ ${errorMessages}`
|
|
|
5873
5991
|
return { results, errors, totalProcessed, totalFailed };
|
|
5874
5992
|
}
|
|
5875
5993
|
};
|
|
5994
|
+
_BatchProcessor.cb = new CircuitBreaker({
|
|
5995
|
+
failureThreshold: 5,
|
|
5996
|
+
resetTimeoutMs: 3e4,
|
|
5997
|
+
halfOpenMaxCalls: 1
|
|
5998
|
+
});
|
|
5999
|
+
var BatchProcessor = _BatchProcessor;
|
|
5876
6000
|
|
|
5877
6001
|
// src/config/EmbeddingStrategy.ts
|
|
5878
6002
|
var EmbeddingStrategyResolver = class {
|
|
@@ -5970,7 +6094,7 @@ var QueryProcessor = class {
|
|
|
5970
6094
|
* @param validFields Optional list of known filterable fields to look for
|
|
5971
6095
|
*/
|
|
5972
6096
|
static extractQueryFieldHints(question, validFields = []) {
|
|
5973
|
-
var
|
|
6097
|
+
var _a3, _b, _c, _d;
|
|
5974
6098
|
if (!question.trim()) return [];
|
|
5975
6099
|
const hints = /* @__PURE__ */ new Map();
|
|
5976
6100
|
const addHint = (value, field) => {
|
|
@@ -6050,7 +6174,7 @@ var QueryProcessor = class {
|
|
|
6050
6174
|
];
|
|
6051
6175
|
for (const p of universalPatterns) {
|
|
6052
6176
|
for (const match of question.matchAll(p.regex)) {
|
|
6053
|
-
const val = p.group ? (
|
|
6177
|
+
const val = p.group ? (_a3 = match[p.group]) != null ? _a3 : match[0] : match[0];
|
|
6054
6178
|
if (!val) continue;
|
|
6055
6179
|
if (p.field) addHint(val, p.field);
|
|
6056
6180
|
else addHint(val);
|
|
@@ -6274,11 +6398,11 @@ var LLMRouter = class {
|
|
|
6274
6398
|
* When provided it is used directly as the 'default' role without re-constructing.
|
|
6275
6399
|
*/
|
|
6276
6400
|
async initialize(prebuiltDefault) {
|
|
6277
|
-
var
|
|
6401
|
+
var _a3;
|
|
6278
6402
|
const defaultModel = prebuiltDefault != null ? prebuiltDefault : LLMFactory.create(this.config.llm, this.config.embedding);
|
|
6279
6403
|
this.models.set("default", defaultModel);
|
|
6280
6404
|
const envFastModel = process.env.FAST_LLM_MODEL;
|
|
6281
|
-
const providerFastDefault = (
|
|
6405
|
+
const providerFastDefault = (_a3 = FAST_MODEL_DEFAULTS[this.config.llm.provider]) != null ? _a3 : "";
|
|
6282
6406
|
const fastModelName = envFastModel || providerFastDefault;
|
|
6283
6407
|
if (fastModelName && fastModelName !== this.config.llm.model) {
|
|
6284
6408
|
console.log(`[LLMRouter] Fast role \u2192 provider="${this.config.llm.provider}" model="${fastModelName}"`);
|
|
@@ -6297,8 +6421,8 @@ var LLMRouter = class {
|
|
|
6297
6421
|
* Falls back to 'default' if the requested role is not registered.
|
|
6298
6422
|
*/
|
|
6299
6423
|
get(role) {
|
|
6300
|
-
var
|
|
6301
|
-
const provider = (
|
|
6424
|
+
var _a3;
|
|
6425
|
+
const provider = (_a3 = this.models.get(role)) != null ? _a3 : this.models.get("default");
|
|
6302
6426
|
if (!provider) {
|
|
6303
6427
|
throw new Error(`[LLMRouter] No provider registered for role: "${role}". Did you call initialize()?`);
|
|
6304
6428
|
}
|
|
@@ -6384,8 +6508,8 @@ var IntentClassifier = class {
|
|
|
6384
6508
|
numericFieldCount = numericKeys.size;
|
|
6385
6509
|
categoricalFieldCount = catKeys.size;
|
|
6386
6510
|
if (productKeyMatches >= 2 || docs.some((d) => {
|
|
6387
|
-
var
|
|
6388
|
-
return ((
|
|
6511
|
+
var _a3, _b;
|
|
6512
|
+
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
6513
|
})) {
|
|
6390
6514
|
isProductLike = true;
|
|
6391
6515
|
}
|
|
@@ -6667,8 +6791,8 @@ var TextRendererStrategy = class {
|
|
|
6667
6791
|
}
|
|
6668
6792
|
const docs = Array.isArray(data) ? data : [];
|
|
6669
6793
|
const text = docs.map((d) => {
|
|
6670
|
-
var
|
|
6671
|
-
return (
|
|
6794
|
+
var _a3;
|
|
6795
|
+
return (_a3 = d == null ? void 0 : d.content) != null ? _a3 : "";
|
|
6672
6796
|
}).join("\n\n");
|
|
6673
6797
|
return { type: "text", title, data: { content: text || "No detailed content available." } };
|
|
6674
6798
|
}
|
|
@@ -6811,9 +6935,9 @@ var LRUDecisionCache = class {
|
|
|
6811
6935
|
this.maxSize = maxSize;
|
|
6812
6936
|
}
|
|
6813
6937
|
generateKey(context) {
|
|
6814
|
-
var
|
|
6938
|
+
var _a3, _b;
|
|
6815
6939
|
const q = (context.userQuery || "").toLowerCase().trim();
|
|
6816
|
-
const docCount = (_b = (
|
|
6940
|
+
const docCount = (_b = (_a3 = context.retrievedDocuments) == null ? void 0 : _a3.length) != null ? _b : 0;
|
|
6817
6941
|
return `${q}::docs:${docCount}`;
|
|
6818
6942
|
}
|
|
6819
6943
|
get(context) {
|
|
@@ -6914,7 +7038,7 @@ var UITransformer = class _UITransformer {
|
|
|
6914
7038
|
* Prefer `analyzeAndDecide()` in production.
|
|
6915
7039
|
*/
|
|
6916
7040
|
static transform(userQuery, retrievedData, config, trainedSchema, intent) {
|
|
6917
|
-
var
|
|
7041
|
+
var _a3, _b, _c;
|
|
6918
7042
|
if (!retrievedData || retrievedData.length === 0) {
|
|
6919
7043
|
return this.createTextResponse("No data available", "No relevant data found for your query.");
|
|
6920
7044
|
}
|
|
@@ -6934,7 +7058,7 @@ var UITransformer = class _UITransformer {
|
|
|
6934
7058
|
return this.transformToBarChart(filteredData, profile, userQuery, resolvedIntent.visualizationHint === "ranking");
|
|
6935
7059
|
}
|
|
6936
7060
|
if (resolvedIntent.visualizationHint === "distribution") {
|
|
6937
|
-
return (
|
|
7061
|
+
return (_a3 = this.transformToHistogram(profile, userQuery)) != null ? _a3 : this.transformToBarChart(filteredData, profile, userQuery);
|
|
6938
7062
|
}
|
|
6939
7063
|
if (resolvedIntent.visualizationHint === "correlation") {
|
|
6940
7064
|
return (_b = this.transformToScatterPlot(profile, userQuery)) != null ? _b : this.transformToBarChart(filteredData, profile, userQuery);
|
|
@@ -7267,11 +7391,11 @@ ${schemaProfileText}` : ""}`;
|
|
|
7267
7391
|
};
|
|
7268
7392
|
}
|
|
7269
7393
|
static transformToPieChart(data, profile, query = "") {
|
|
7270
|
-
var
|
|
7394
|
+
var _a3;
|
|
7271
7395
|
const dimension = profile ? this.selectDimensionField(profile, query) : void 0;
|
|
7272
7396
|
const categories = dimension ? Array.from(new Set(profile.records.map((record) => {
|
|
7273
|
-
var
|
|
7274
|
-
return String((
|
|
7397
|
+
var _a4;
|
|
7398
|
+
return String((_a4 = record.fields[dimension.key]) != null ? _a4 : "");
|
|
7275
7399
|
}).filter(Boolean))) : this.detectCategories(data);
|
|
7276
7400
|
if (categories.length === 0) return null;
|
|
7277
7401
|
const categoryData = dimension && profile ? this.aggregateProfileByDimension(profile, dimension.key) : this.aggregateByCategory(data, categories);
|
|
@@ -7281,7 +7405,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7281
7405
|
});
|
|
7282
7406
|
return {
|
|
7283
7407
|
type: "pie_chart",
|
|
7284
|
-
title: `Distribution by ${(
|
|
7408
|
+
title: `Distribution by ${(_a3 = dimension == null ? void 0 : dimension.label) != null ? _a3 : "Category"}`,
|
|
7285
7409
|
description: `Showing breakdown across ${pieData.length} categories`,
|
|
7286
7410
|
data: pieData
|
|
7287
7411
|
};
|
|
@@ -7291,8 +7415,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7291
7415
|
const valueField = profile.numericFields[0];
|
|
7292
7416
|
const buckets = /* @__PURE__ */ new Map();
|
|
7293
7417
|
profile.records.forEach((record) => {
|
|
7294
|
-
var
|
|
7295
|
-
const timestamp = String((
|
|
7418
|
+
var _a3, _b, _c;
|
|
7419
|
+
const timestamp = String((_a3 = record.fields[dateField.key]) != null ? _a3 : "");
|
|
7296
7420
|
const value = (_b = this.toFiniteNumber(record.fields[valueField.key])) != null ? _b : 0;
|
|
7297
7421
|
buckets.set(timestamp, ((_c = buckets.get(timestamp)) != null ? _c : 0) + value);
|
|
7298
7422
|
});
|
|
@@ -7305,23 +7429,23 @@ ${schemaProfileText}` : ""}`;
|
|
|
7305
7429
|
};
|
|
7306
7430
|
}
|
|
7307
7431
|
static transformToBarChart(data, profile, query = "", horizontal = false) {
|
|
7308
|
-
var
|
|
7432
|
+
var _a3;
|
|
7309
7433
|
const dimension = profile ? this.selectDimensionField(profile, query) : void 0;
|
|
7310
7434
|
const measure = profile ? this.selectNumericField(profile, query) : void 0;
|
|
7311
7435
|
const aggregate = dimension && profile ? this.aggregateProfileByDimension(profile, dimension.key, measure == null ? void 0 : measure.key) : this.aggregateByCategory(data, this.detectCategories(data));
|
|
7312
7436
|
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
7437
|
const fallbackData = barData.length > 0 ? barData : data.slice(0, 12).map((item, index) => {
|
|
7314
|
-
var
|
|
7438
|
+
var _a4, _b, _c, _d, _e;
|
|
7315
7439
|
const meta = item.metadata || {};
|
|
7316
7440
|
const label = String(
|
|
7317
|
-
(_c = (_b = (
|
|
7441
|
+
(_c = (_b = (_a4 = this.getDynamicVal(meta, "name")) != null ? _a4 : meta.label) != null ? _b : meta.title) != null ? _c : `Result ${index + 1}`
|
|
7318
7442
|
);
|
|
7319
7443
|
const value = (_e = (_d = this.extractNumericValue(meta)) != null ? _d : item.score) != null ? _e : 0;
|
|
7320
7444
|
return { category: label, value: Number(value) };
|
|
7321
7445
|
});
|
|
7322
7446
|
return {
|
|
7323
7447
|
type: horizontal ? "horizontal_bar" : "bar_chart",
|
|
7324
|
-
title: dimension ? `${(
|
|
7448
|
+
title: dimension ? `${(_a3 = measure == null ? void 0 : measure.label) != null ? _a3 : "Count"} by ${dimension.label}` : "Comparison",
|
|
7325
7449
|
description: `Showing ${fallbackData.length} comparable values`,
|
|
7326
7450
|
data: fallbackData
|
|
7327
7451
|
};
|
|
@@ -7356,11 +7480,11 @@ ${schemaProfileText}` : ""}`;
|
|
|
7356
7480
|
if (fields.length < 2) return null;
|
|
7357
7481
|
const [xField, yField] = fields;
|
|
7358
7482
|
const points = profile.records.map((record) => {
|
|
7359
|
-
var
|
|
7483
|
+
var _a3;
|
|
7360
7484
|
const x = this.toFiniteNumber(record.fields[xField.key]);
|
|
7361
7485
|
const y = this.toFiniteNumber(record.fields[yField.key]);
|
|
7362
7486
|
if (x === null || y === null) return null;
|
|
7363
|
-
return { x, y, label: String((
|
|
7487
|
+
return { x, y, label: String((_a3 = this.getRecordLabel(record)) != null ? _a3 : record.id) };
|
|
7364
7488
|
}).filter((point) => point !== null).slice(0, 100);
|
|
7365
7489
|
if (points.length === 0) return null;
|
|
7366
7490
|
return {
|
|
@@ -7390,9 +7514,9 @@ ${schemaProfileText}` : ""}`;
|
|
|
7390
7514
|
static transformToRadarChart(data) {
|
|
7391
7515
|
const attributeMap = {};
|
|
7392
7516
|
data.forEach((item) => {
|
|
7393
|
-
var
|
|
7517
|
+
var _a3, _b, _c;
|
|
7394
7518
|
const meta = item.metadata || {};
|
|
7395
|
-
const seriesName = String((_c = (_b = (
|
|
7519
|
+
const seriesName = String((_c = (_b = (_a3 = meta.name) != null ? _a3 : meta.product) != null ? _b : item.id) != null ? _c : "Item");
|
|
7396
7520
|
Object.entries(meta).forEach(([key, val]) => {
|
|
7397
7521
|
if (typeof val === "number" && !["price", "id"].includes(key.toLowerCase())) {
|
|
7398
7522
|
if (!attributeMap[key]) attributeMap[key] = {};
|
|
@@ -7408,8 +7532,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7408
7532
|
title: "Product Comparison",
|
|
7409
7533
|
description: `Comparing ${data.length} items across ${radarData.length} attributes`,
|
|
7410
7534
|
data: radarData.length > 0 ? radarData : data.map((d) => {
|
|
7411
|
-
var
|
|
7412
|
-
return { attribute: ((
|
|
7535
|
+
var _a3;
|
|
7536
|
+
return { attribute: ((_a3 = d == null ? void 0 : d.content) != null ? _a3 : "").substring(0, 40) };
|
|
7413
7537
|
})
|
|
7414
7538
|
};
|
|
7415
7539
|
}
|
|
@@ -7428,8 +7552,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7428
7552
|
return this.createTextResponse(
|
|
7429
7553
|
"Retrieved Context",
|
|
7430
7554
|
data.map((item) => {
|
|
7431
|
-
var
|
|
7432
|
-
return (
|
|
7555
|
+
var _a3;
|
|
7556
|
+
return (_a3 = item == null ? void 0 : item.content) != null ? _a3 : "";
|
|
7433
7557
|
}).join("\n\n"),
|
|
7434
7558
|
`Found ${data.length} relevant results`
|
|
7435
7559
|
);
|
|
@@ -7480,11 +7604,11 @@ ${schemaProfileText}` : ""}`;
|
|
|
7480
7604
|
return null;
|
|
7481
7605
|
}
|
|
7482
7606
|
static normalizeTransformation(payload) {
|
|
7483
|
-
var
|
|
7607
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j;
|
|
7484
7608
|
if (!payload || typeof payload !== "object") return null;
|
|
7485
7609
|
const p = payload;
|
|
7486
7610
|
const type = this.normalizeVisualizationType(
|
|
7487
|
-
String((_c = (_b = (
|
|
7611
|
+
String((_c = (_b = (_a3 = p.type) != null ? _a3 : p.view) != null ? _b : p.chartType) != null ? _c : "")
|
|
7488
7612
|
);
|
|
7489
7613
|
if (!type) return null;
|
|
7490
7614
|
const title = String((_e = (_d = p.title) != null ? _d : p.heading) != null ? _e : "Visualization");
|
|
@@ -7495,7 +7619,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7495
7619
|
return this.validateTransformation(transformation) ? transformation : null;
|
|
7496
7620
|
}
|
|
7497
7621
|
static normalizeVisualizationType(type) {
|
|
7498
|
-
var
|
|
7622
|
+
var _a3;
|
|
7499
7623
|
const mapping = {
|
|
7500
7624
|
pie: "pie_chart",
|
|
7501
7625
|
pie_chart: "pie_chart",
|
|
@@ -7523,7 +7647,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7523
7647
|
product_carousel: "product_carousel",
|
|
7524
7648
|
carousel: "carousel"
|
|
7525
7649
|
};
|
|
7526
|
-
return (
|
|
7650
|
+
return (_a3 = mapping[type.toLowerCase()]) != null ? _a3 : null;
|
|
7527
7651
|
}
|
|
7528
7652
|
static validateTransformation(t) {
|
|
7529
7653
|
const { type, data } = t;
|
|
@@ -7639,7 +7763,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7639
7763
|
}
|
|
7640
7764
|
static profileData(data) {
|
|
7641
7765
|
const records = (data || []).filter((item) => Boolean(item && typeof item === "object")).map((item) => {
|
|
7642
|
-
var
|
|
7766
|
+
var _a3, _b;
|
|
7643
7767
|
const fields2 = {};
|
|
7644
7768
|
Object.entries(item.metadata || {}).forEach(([key, value]) => {
|
|
7645
7769
|
const primitive = this.toPrimitive(value);
|
|
@@ -7648,7 +7772,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7648
7772
|
if (!fields2.content && item.content) fields2.content = item.content.substring(0, 500);
|
|
7649
7773
|
return {
|
|
7650
7774
|
id: item.id,
|
|
7651
|
-
content: (
|
|
7775
|
+
content: (_a3 = item.content) != null ? _a3 : "",
|
|
7652
7776
|
score: (_b = item.score) != null ? _b : 0,
|
|
7653
7777
|
fields: fields2,
|
|
7654
7778
|
source: item
|
|
@@ -7729,16 +7853,16 @@ ${schemaProfileText}` : ""}`;
|
|
|
7729
7853
|
return null;
|
|
7730
7854
|
}
|
|
7731
7855
|
static selectDimensionField(profile, query) {
|
|
7732
|
-
var
|
|
7856
|
+
var _a3, _b;
|
|
7733
7857
|
const productCategory = profile.categoricalFields.find(
|
|
7734
7858
|
(field) => /category|department|collection|type|group|segment|region|country|state|city/i.test(field.key)
|
|
7735
7859
|
);
|
|
7736
7860
|
const ranked = this.rankFieldsByQuery(profile.categoricalFields, query);
|
|
7737
|
-
return (_b = (
|
|
7861
|
+
return (_b = (_a3 = ranked[0]) != null ? _a3 : productCategory) != null ? _b : profile.categoricalFields[0];
|
|
7738
7862
|
}
|
|
7739
7863
|
static selectNumericField(profile, query) {
|
|
7740
|
-
var
|
|
7741
|
-
return (
|
|
7864
|
+
var _a3;
|
|
7865
|
+
return (_a3 = this.rankFieldsByQuery(profile.numericFields, query)[0]) != null ? _a3 : profile.numericFields[0];
|
|
7742
7866
|
}
|
|
7743
7867
|
static rankFieldsByQuery(fields, query) {
|
|
7744
7868
|
const q = query.toLowerCase();
|
|
@@ -7767,8 +7891,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7767
7891
|
static aggregateProfileByDimension(profile, dimensionKey, measureKey) {
|
|
7768
7892
|
const result = {};
|
|
7769
7893
|
profile.records.forEach((record) => {
|
|
7770
|
-
var
|
|
7771
|
-
const category = String((
|
|
7894
|
+
var _a3, _b, _c;
|
|
7895
|
+
const category = String((_a3 = record.fields[dimensionKey]) != null ? _a3 : "Other").trim() || "Other";
|
|
7772
7896
|
const value = measureKey ? (_b = this.toFiniteNumber(record.fields[measureKey])) != null ? _b : 0 : 1;
|
|
7773
7897
|
result[category] = ((_c = result[category]) != null ? _c : 0) + value;
|
|
7774
7898
|
});
|
|
@@ -7848,8 +7972,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7848
7972
|
static aggregateByCategory(data, categories) {
|
|
7849
7973
|
const result = Object.fromEntries(categories.map((c) => [c, 0]));
|
|
7850
7974
|
data.forEach((item) => {
|
|
7851
|
-
var
|
|
7852
|
-
const cat = (
|
|
7975
|
+
var _a3;
|
|
7976
|
+
const cat = (_a3 = this.getProductCategory(item)) != null ? _a3 : "Other";
|
|
7853
7977
|
if (Object.prototype.hasOwnProperty.call(result, cat)) result[cat]++;
|
|
7854
7978
|
else result["Other"] = (result["Other"] || 0) + 1;
|
|
7855
7979
|
});
|
|
@@ -7857,17 +7981,17 @@ ${schemaProfileText}` : ""}`;
|
|
|
7857
7981
|
}
|
|
7858
7982
|
static extractTimeSeriesData(data) {
|
|
7859
7983
|
return data.map((item) => {
|
|
7860
|
-
var
|
|
7984
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
7861
7985
|
const meta = item.metadata || {};
|
|
7862
7986
|
return {
|
|
7863
|
-
timestamp: (_b = (
|
|
7987
|
+
timestamp: (_b = (_a3 = meta.timestamp) != null ? _a3 : meta.date) != null ? _b : (/* @__PURE__ */ new Date()).toISOString(),
|
|
7864
7988
|
value: (_d = (_c = meta.value) != null ? _c : item.score) != null ? _d : 0,
|
|
7865
7989
|
label: (_f = meta.label) != null ? _f : ((_e = item == null ? void 0 : item.content) != null ? _e : "").substring(0, 50)
|
|
7866
7990
|
};
|
|
7867
7991
|
});
|
|
7868
7992
|
}
|
|
7869
7993
|
static extractNumericValue(meta) {
|
|
7870
|
-
var
|
|
7994
|
+
var _a3;
|
|
7871
7995
|
const preferredKeys = [
|
|
7872
7996
|
"value",
|
|
7873
7997
|
"count",
|
|
@@ -7882,7 +8006,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7882
8006
|
"price"
|
|
7883
8007
|
];
|
|
7884
8008
|
for (const key of preferredKeys) {
|
|
7885
|
-
const raw = (
|
|
8009
|
+
const raw = (_a3 = resolveMetadataValue(meta, key)) != null ? _a3 : meta[key];
|
|
7886
8010
|
const value = typeof raw === "number" ? raw : Number(String(raw != null ? raw : "").replace(/[$,% ,]/g, ""));
|
|
7887
8011
|
if (Number.isFinite(value)) return value;
|
|
7888
8012
|
}
|
|
@@ -7977,8 +8101,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7977
8101
|
}, query.includes(normalizedField) ? 3 : 0);
|
|
7978
8102
|
}
|
|
7979
8103
|
static resolveTableCellValue(item, column) {
|
|
7980
|
-
var
|
|
7981
|
-
if (column === "Content") return ((
|
|
8104
|
+
var _a3, _b, _c;
|
|
8105
|
+
if (column === "Content") return ((_a3 = item == null ? void 0 : item.content) != null ? _a3 : "").substring(0, 100);
|
|
7982
8106
|
const meta = item.metadata || {};
|
|
7983
8107
|
const normalizedColumn = this.normalizeComparableField(column);
|
|
7984
8108
|
const exactMetadata = Object.entries(meta).find(
|
|
@@ -8030,8 +8154,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
8030
8154
|
let inStock = 0;
|
|
8031
8155
|
let outOfStock = 0;
|
|
8032
8156
|
data.forEach((d) => {
|
|
8033
|
-
var
|
|
8034
|
-
const cat = (
|
|
8157
|
+
var _a3, _b;
|
|
8158
|
+
const cat = (_a3 = this.getProductCategory(d)) != null ? _a3 : "Other";
|
|
8035
8159
|
if (cat === category) {
|
|
8036
8160
|
const quantity = (_b = this.extractStockQuantity(d)) != null ? _b : 1;
|
|
8037
8161
|
if (this.determineStockStatus(d)) inStock += quantity;
|
|
@@ -8077,9 +8201,9 @@ ${schemaProfileText}` : ""}`;
|
|
|
8077
8201
|
}
|
|
8078
8202
|
// ─── Product Extraction ───────────────────────────────────────────────────
|
|
8079
8203
|
static getDynamicVal(meta, uiKey, config, trainedSchema) {
|
|
8080
|
-
var
|
|
8204
|
+
var _a3;
|
|
8081
8205
|
if (!meta) return void 0;
|
|
8082
|
-
const mapping = (
|
|
8206
|
+
const mapping = (_a3 = config == null ? void 0 : config.rag) == null ? void 0 : _a3.uiMapping;
|
|
8083
8207
|
if ((mapping == null ? void 0 : mapping[uiKey]) && meta[mapping[uiKey]] !== void 0) return meta[mapping[uiKey]];
|
|
8084
8208
|
if (trainedSchema && typeof trainedSchema === "object") {
|
|
8085
8209
|
const trainedKey = trainedSchema[uiKey];
|
|
@@ -8088,7 +8212,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
8088
8212
|
return resolveMetadataValue(meta, uiKey);
|
|
8089
8213
|
}
|
|
8090
8214
|
static extractProductInfo(item, config, trainedSchema) {
|
|
8091
|
-
var
|
|
8215
|
+
var _a3, _b;
|
|
8092
8216
|
if (!item) return null;
|
|
8093
8217
|
const meta = item.metadata || {};
|
|
8094
8218
|
const content = item.content || "";
|
|
@@ -8096,7 +8220,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
8096
8220
|
const price = this.getDynamicVal(meta, "price", config, trainedSchema);
|
|
8097
8221
|
const brand = this.getDynamicVal(meta, "brand", config, trainedSchema);
|
|
8098
8222
|
const description = this.cleanProductDescription(
|
|
8099
|
-
(
|
|
8223
|
+
(_a3 = this.extractProductDescriptionFromContent(content)) != null ? _a3 : this.getProductDescriptionValue(meta, config, trainedSchema)
|
|
8100
8224
|
);
|
|
8101
8225
|
if (name || this.isProductData(item)) {
|
|
8102
8226
|
let finalName = name ? String(name) : void 0;
|
|
@@ -8231,10 +8355,10 @@ RULES:
|
|
|
8231
8355
|
}
|
|
8232
8356
|
static buildContextSummary(sources, maxChars = 6e3) {
|
|
8233
8357
|
const items = (sources || []).filter(Boolean).map((s, i) => {
|
|
8234
|
-
var
|
|
8358
|
+
var _a3, _b, _c, _d;
|
|
8235
8359
|
return {
|
|
8236
8360
|
index: i + 1,
|
|
8237
|
-
content: (_b = (
|
|
8361
|
+
content: (_b = (_a3 = s == null ? void 0 : s.content) == null ? void 0 : _a3.substring(0, 400)) != null ? _b : "",
|
|
8238
8362
|
metadata: (_c = s == null ? void 0 : s.metadata) != null ? _c : {},
|
|
8239
8363
|
score: (_d = s == null ? void 0 : s.score) != null ? _d : 0
|
|
8240
8364
|
};
|
|
@@ -8274,7 +8398,7 @@ var SchemaMapper = class {
|
|
|
8274
8398
|
return promise;
|
|
8275
8399
|
}
|
|
8276
8400
|
static async _doTrain(llm, cacheKey, keys) {
|
|
8277
|
-
var
|
|
8401
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
|
|
8278
8402
|
console.log(`[SchemaMapper] \u{1F9E0} Training on new schema keys: ${keys.join(", ")}`);
|
|
8279
8403
|
const propertyList = Object.entries(this.TARGET_PROPERTIES).map(([prop, desc]) => `- ${prop} (${desc})`).join("\n");
|
|
8280
8404
|
const messages = [
|
|
@@ -8290,7 +8414,7 @@ Return a JSON object like {"name":"Title","price":"Price",...}. Omit unmapped pr
|
|
|
8290
8414
|
}
|
|
8291
8415
|
];
|
|
8292
8416
|
try {
|
|
8293
|
-
const baseUrl = (
|
|
8417
|
+
const baseUrl = (_a3 = llm == null ? void 0 : llm.baseUrl) != null ? _a3 : "";
|
|
8294
8418
|
const apiKey = (_b = llm == null ? void 0 : llm.apiKey) != null ? _b : "";
|
|
8295
8419
|
const model = (_c = llm == null ? void 0 : llm.model) != null ? _c : "llama-3.1-8b-instant";
|
|
8296
8420
|
let responseText;
|
|
@@ -8465,9 +8589,9 @@ var Pipeline = class {
|
|
|
8465
8589
|
this.initialised = false;
|
|
8466
8590
|
/** Namespace-specific static cold context cache for CAG */
|
|
8467
8591
|
this.coldContexts = /* @__PURE__ */ new Map();
|
|
8468
|
-
var
|
|
8592
|
+
var _a3, _b, _c, _d, _e;
|
|
8469
8593
|
this.chunker = new DocumentChunker(
|
|
8470
|
-
(_b = (
|
|
8594
|
+
(_b = (_a3 = config.rag) == null ? void 0 : _a3.chunkSize) != null ? _b : 1e3,
|
|
8471
8595
|
(_d = (_c = config.rag) == null ? void 0 : _c.chunkOverlap) != null ? _d : 200
|
|
8472
8596
|
);
|
|
8473
8597
|
if (((_e = config.rag) == null ? void 0 : _e.chunkingStrategy) === "llamaindex") {
|
|
@@ -8483,7 +8607,7 @@ var Pipeline = class {
|
|
|
8483
8607
|
return this.initialised ? this.llmProvider : void 0;
|
|
8484
8608
|
}
|
|
8485
8609
|
async initialize() {
|
|
8486
|
-
var
|
|
8610
|
+
var _a3, _b, _c, _d;
|
|
8487
8611
|
if (this.initialised) return;
|
|
8488
8612
|
const chartInstruction = `You are a helpful assistant. Use the provided context to answer questions accurately.
|
|
8489
8613
|
|
|
@@ -8526,7 +8650,7 @@ var Pipeline = class {
|
|
|
8526
8650
|
this.entityExtractor = new EntityExtractor(this.llmProvider);
|
|
8527
8651
|
}
|
|
8528
8652
|
await this.vectorDB.initialize();
|
|
8529
|
-
if (((
|
|
8653
|
+
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
8654
|
this.mcpRegistry = new MCPRegistry(this.config.mcpServers || []);
|
|
8531
8655
|
this.multiAgentCoordinator = new MultiAgentCoordinator({
|
|
8532
8656
|
llmProvider: this.llmProvider,
|
|
@@ -8544,8 +8668,8 @@ var Pipeline = class {
|
|
|
8544
8668
|
this.initialised = true;
|
|
8545
8669
|
}
|
|
8546
8670
|
async loadColdContext(ns) {
|
|
8547
|
-
var
|
|
8548
|
-
const cagConfig = (
|
|
8671
|
+
var _a3, _b;
|
|
8672
|
+
const cagConfig = (_a3 = this.config.rag) == null ? void 0 : _a3.cag;
|
|
8549
8673
|
if (!cagConfig || !cagConfig.enabled) return;
|
|
8550
8674
|
try {
|
|
8551
8675
|
const coldNs = cagConfig.coldNamespace || ns;
|
|
@@ -8598,12 +8722,12 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8598
8722
|
}
|
|
8599
8723
|
/** Step 1: Chunk the document content. */
|
|
8600
8724
|
async prepareChunks(doc) {
|
|
8601
|
-
var
|
|
8725
|
+
var _a3, _b;
|
|
8602
8726
|
if (this.llamaIngestor) {
|
|
8603
8727
|
return this.llamaIngestor.chunk(doc.content, {
|
|
8604
8728
|
docId: doc.docId,
|
|
8605
8729
|
metadata: doc.metadata,
|
|
8606
|
-
chunkSize: (
|
|
8730
|
+
chunkSize: (_a3 = this.config.rag) == null ? void 0 : _a3.chunkSize,
|
|
8607
8731
|
chunkOverlap: (_b = this.config.rag) == null ? void 0 : _b.chunkOverlap
|
|
8608
8732
|
});
|
|
8609
8733
|
}
|
|
@@ -8701,9 +8825,9 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8701
8825
|
return { reply, sources };
|
|
8702
8826
|
}
|
|
8703
8827
|
async ask(question, history = [], namespace) {
|
|
8704
|
-
var
|
|
8828
|
+
var _a3, _b;
|
|
8705
8829
|
await this.initialize();
|
|
8706
|
-
if ((((
|
|
8830
|
+
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
8831
|
return await this.multiAgentCoordinator.run(question, history);
|
|
8708
8832
|
}
|
|
8709
8833
|
const stream = this.askStream(question, history, namespace);
|
|
@@ -8738,9 +8862,9 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8738
8862
|
}
|
|
8739
8863
|
askStream(_0) {
|
|
8740
8864
|
return __asyncGenerator(this, arguments, function* (question, history = [], namespace) {
|
|
8741
|
-
var
|
|
8865
|
+
var _a3, _b;
|
|
8742
8866
|
yield new __await(this.initialize());
|
|
8743
|
-
if ((((
|
|
8867
|
+
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
8868
|
const stream2 = this.multiAgentCoordinator.runStream(question, history);
|
|
8745
8869
|
try {
|
|
8746
8870
|
for (var iter = __forAwait(stream2), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
|
|
@@ -8789,10 +8913,10 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8789
8913
|
*/
|
|
8790
8914
|
askStreamInternal(_0) {
|
|
8791
8915
|
return __asyncGenerator(this, arguments, function* (question, history = [], namespace) {
|
|
8792
|
-
var
|
|
8916
|
+
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
8917
|
yield new __await(this.initialize());
|
|
8794
8918
|
const ns = formatNamespace(namespace != null ? namespace : this.config.projectId);
|
|
8795
|
-
const topK = (_b = (
|
|
8919
|
+
const topK = (_b = (_a3 = this.config.rag) == null ? void 0 : _a3.topK) != null ? _b : 5;
|
|
8796
8920
|
const scoreThreshold = (_d = (_c = this.config.rag) == null ? void 0 : _c.scoreThreshold) != null ? _d : 0.3;
|
|
8797
8921
|
const requestId = `req_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
8798
8922
|
const requestStart = performance.now();
|
|
@@ -8841,8 +8965,8 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8841
8965
|
const rerankStart = performance.now();
|
|
8842
8966
|
const structuredSources = this.applyStructuredFilters(rawSources, filter).filter((s) => Boolean(s && typeof s === "object"));
|
|
8843
8967
|
let fullSources = hasNumericPredicates ? structuredSources : structuredSources.filter((m) => {
|
|
8844
|
-
var
|
|
8845
|
-
return ((
|
|
8968
|
+
var _a4;
|
|
8969
|
+
return ((_a4 = m == null ? void 0 : m.score) != null ? _a4 : 0) >= scoreThreshold;
|
|
8846
8970
|
});
|
|
8847
8971
|
const rerankLimit = Math.max(retrievalLimit, fullSources.length);
|
|
8848
8972
|
const useReranking = arch !== "naive" && (arch === "retrieve-and-rerank" || ((_m = this.config.rag) == null ? void 0 : _m.useReranking));
|
|
@@ -8855,13 +8979,13 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8855
8979
|
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
8980
|
|
|
8857
8981
|
` + promptSources.map((m, i) => {
|
|
8858
|
-
var
|
|
8982
|
+
var _a4;
|
|
8859
8983
|
return `[Source ${i + 1}]
|
|
8860
|
-
${(
|
|
8984
|
+
${(_a4 = m == null ? void 0 : m.content) != null ? _a4 : ""}`;
|
|
8861
8985
|
}).join("\n\n---\n\n") : "No relevant context found.";
|
|
8862
8986
|
const sources = [...fullSources].filter((s) => Boolean(s && typeof s === "object")).sort((a, b) => {
|
|
8863
|
-
var
|
|
8864
|
-
return ((
|
|
8987
|
+
var _a4, _b2;
|
|
8988
|
+
return ((_a4 = b == null ? void 0 : b.score) != null ? _a4 : 0) - ((_b2 = a == null ? void 0 : a.score) != null ? _b2 : 0);
|
|
8865
8989
|
});
|
|
8866
8990
|
if (graphData && graphData.nodes.length > 0) {
|
|
8867
8991
|
const graphContext = graphData.nodes.map(
|
|
@@ -8889,10 +9013,10 @@ ${context}`;
|
|
|
8889
9013
|
yield {
|
|
8890
9014
|
reply: "",
|
|
8891
9015
|
sources: (sources || []).filter((s) => Boolean(s && typeof s === "object")).map((s) => {
|
|
8892
|
-
var
|
|
9016
|
+
var _a4, _b2, _c2;
|
|
8893
9017
|
return {
|
|
8894
9018
|
id: s.id,
|
|
8895
|
-
score: (
|
|
9019
|
+
score: (_a4 = s.score) != null ? _a4 : 0,
|
|
8896
9020
|
content: (_b2 = s == null ? void 0 : s.content) != null ? _b2 : "",
|
|
8897
9021
|
metadata: (_c2 = s == null ? void 0 : s.metadata) != null ? _c2 : {},
|
|
8898
9022
|
namespace: ns
|
|
@@ -9085,11 +9209,11 @@ ${context}`;
|
|
|
9085
9209
|
systemPrompt,
|
|
9086
9210
|
userPrompt: question + finalRestrictionSuffix,
|
|
9087
9211
|
chunks: (sources || []).filter(Boolean).map((s) => {
|
|
9088
|
-
var
|
|
9212
|
+
var _a4, _b2;
|
|
9089
9213
|
return {
|
|
9090
9214
|
id: s.id,
|
|
9091
9215
|
score: s.score,
|
|
9092
|
-
content: (
|
|
9216
|
+
content: (_a4 = s == null ? void 0 : s.content) != null ? _a4 : "",
|
|
9093
9217
|
metadata: (_b2 = s == null ? void 0 : s.metadata) != null ? _b2 : {},
|
|
9094
9218
|
namespace: ns
|
|
9095
9219
|
};
|
|
@@ -9108,7 +9232,7 @@ ${context}`;
|
|
|
9108
9232
|
const telemetryUrl = ((_B = this.config.telemetry) == null ? void 0 : _B.url) || process.env.TELEMETRY_URL || process.env.NEXT_PUBLIC_TELEMETRY_URL || defaultUrl;
|
|
9109
9233
|
const absoluteUrl = telemetryUrl.startsWith("http") ? telemetryUrl : "https://www.retrivora.com" + (telemetryUrl.startsWith("/") ? telemetryUrl : "/" + telemetryUrl);
|
|
9110
9234
|
(async () => {
|
|
9111
|
-
var
|
|
9235
|
+
var _a4, _b2, _c2, _d2, _e2;
|
|
9112
9236
|
try {
|
|
9113
9237
|
let finalTrace = trace;
|
|
9114
9238
|
if (!awaitHallucination && runHallucination) {
|
|
@@ -9117,7 +9241,7 @@ ${context}`;
|
|
|
9117
9241
|
finalTrace = buildTrace(backgroundScoreResult);
|
|
9118
9242
|
}
|
|
9119
9243
|
}
|
|
9120
|
-
const modelName = (finalTrace == null ? void 0 : finalTrace.model) || ((
|
|
9244
|
+
const modelName = (finalTrace == null ? void 0 : finalTrace.model) || ((_a4 = this.config.llm) == null ? void 0 : _a4.model) || "llama-3.1-8b-instant";
|
|
9121
9245
|
const providerName = (finalTrace == null ? void 0 : finalTrace.provider) || ((_b2 = this.config.llm) == null ? void 0 : _b2.provider) || "groq";
|
|
9122
9246
|
const tokenCount = Number(((_c2 = finalTrace == null ? void 0 : finalTrace.tokens) == null ? void 0 : _c2.totalTokens) || 0);
|
|
9123
9247
|
const costEst = Number(((_d2 = finalTrace == null ? void 0 : finalTrace.tokens) == null ? void 0 : _d2.estimatedCostUsd) || 0);
|
|
@@ -9171,7 +9295,7 @@ ${context}`;
|
|
|
9171
9295
|
* Uses an LRU-bounded embedding cache to avoid re-embedding the same query.
|
|
9172
9296
|
*/
|
|
9173
9297
|
async generateUiTransformation(question, sources, cachedSchema, forceDeterministic = false) {
|
|
9174
|
-
var
|
|
9298
|
+
var _a3;
|
|
9175
9299
|
if (!sources || sources.length === 0) {
|
|
9176
9300
|
return UITransformer.transform(question, sources, this.config, cachedSchema);
|
|
9177
9301
|
}
|
|
@@ -9184,7 +9308,7 @@ ${context}`;
|
|
|
9184
9308
|
{ visualizationHint: "product_browse", recommendedChart: "text", filterInStockOnly: false, wantsExplicitTable: false, isTemporal: false, isComparison: false, language: "en" }
|
|
9185
9309
|
);
|
|
9186
9310
|
}
|
|
9187
|
-
const enableLlmUiTransform = ((
|
|
9311
|
+
const enableLlmUiTransform = ((_a3 = this.config.llm.options) == null ? void 0 : _a3.enableLlmUiTransform) === true;
|
|
9188
9312
|
if (forceDeterministic || !enableLlmUiTransform) {
|
|
9189
9313
|
return UITransformer.transform(question, sources, this.config, cachedSchema);
|
|
9190
9314
|
}
|
|
@@ -9202,15 +9326,15 @@ ${context}`;
|
|
|
9202
9326
|
const value = this.resolveNumericPredicateValue(source, predicate);
|
|
9203
9327
|
return value !== null && this.matchesNumericPredicate(value, predicate);
|
|
9204
9328
|
})).sort((a, b) => {
|
|
9205
|
-
var
|
|
9329
|
+
var _a3, _b;
|
|
9206
9330
|
const primary = predicates[0];
|
|
9207
|
-
const aValue = (
|
|
9331
|
+
const aValue = (_a3 = this.resolveNumericPredicateValue(a, primary)) != null ? _a3 : 0;
|
|
9208
9332
|
const bValue = (_b = this.resolveNumericPredicateValue(b, primary)) != null ? _b : 0;
|
|
9209
9333
|
return primary.operator === "lt" || primary.operator === "lte" ? aValue - bValue : bValue - aValue;
|
|
9210
9334
|
});
|
|
9211
9335
|
}
|
|
9212
9336
|
resolveNumericPredicateValue(source, predicate) {
|
|
9213
|
-
var
|
|
9337
|
+
var _a3;
|
|
9214
9338
|
if (!source) return null;
|
|
9215
9339
|
const meta = source.metadata || {};
|
|
9216
9340
|
const field = predicate.field;
|
|
@@ -9223,7 +9347,7 @@ ${context}`;
|
|
|
9223
9347
|
const value = this.toFiniteNumber(Array.isArray(fuzzy) ? fuzzy[1] : fuzzy.value);
|
|
9224
9348
|
if (value !== null) return value;
|
|
9225
9349
|
}
|
|
9226
|
-
const contentValue = this.extractNumericValueFromContent((
|
|
9350
|
+
const contentValue = this.extractNumericValueFromContent((_a3 = source.content) != null ? _a3 : "", field);
|
|
9227
9351
|
if (contentValue !== null) return contentValue;
|
|
9228
9352
|
}
|
|
9229
9353
|
for (const [key, value] of entries) {
|
|
@@ -9279,8 +9403,8 @@ ${context}`;
|
|
|
9279
9403
|
return Number.isFinite(numeric) ? numeric : null;
|
|
9280
9404
|
}
|
|
9281
9405
|
async retrieve(query, options) {
|
|
9282
|
-
var
|
|
9283
|
-
const ns = formatNamespace((
|
|
9406
|
+
var _a3, _b, _c, _d, _e, _f, _g2;
|
|
9407
|
+
const ns = formatNamespace((_a3 = options.namespace) != null ? _a3 : this.config.projectId);
|
|
9284
9408
|
const topK = (_b = options.topK) != null ? _b : 5;
|
|
9285
9409
|
const cacheKey = `${ns}::${query}`;
|
|
9286
9410
|
let queryVector = this.embeddingCache.get(cacheKey);
|
|
@@ -9325,11 +9449,11 @@ ${context}`;
|
|
|
9325
9449
|
namespace: ns,
|
|
9326
9450
|
count: resolvedSources.length,
|
|
9327
9451
|
sample: resolvedSources.slice(0, 2).map((s) => {
|
|
9328
|
-
var
|
|
9452
|
+
var _a4;
|
|
9329
9453
|
return {
|
|
9330
9454
|
id: s == null ? void 0 : s.id,
|
|
9331
9455
|
score: s == null ? void 0 : s.score,
|
|
9332
|
-
contentSnippet: String((
|
|
9456
|
+
contentSnippet: String((_a4 = s == null ? void 0 : s.content) != null ? _a4 : "").substring(0, 150),
|
|
9333
9457
|
metadata: s == null ? void 0 : s.metadata
|
|
9334
9458
|
};
|
|
9335
9459
|
})
|
|
@@ -9343,8 +9467,8 @@ Focus on extracting the core intent and entities. Do not answer the question, ju
|
|
|
9343
9467
|
|
|
9344
9468
|
History:
|
|
9345
9469
|
${(history || []).map((m) => {
|
|
9346
|
-
var
|
|
9347
|
-
return `${(m == null ? void 0 : m.role) || "user"}: ${(
|
|
9470
|
+
var _a3;
|
|
9471
|
+
return `${(m == null ? void 0 : m.role) || "user"}: ${(_a3 = m == null ? void 0 : m.content) != null ? _a3 : ""}`;
|
|
9348
9472
|
}).join("\n")}
|
|
9349
9473
|
|
|
9350
9474
|
New Question: ${question}
|
|
@@ -9371,8 +9495,8 @@ Optimized Search Query:`;
|
|
|
9371
9495
|
const { sources } = await this.retrieve(query, { namespace: ns, topK: 5 });
|
|
9372
9496
|
if (!sources || sources.length === 0) return [];
|
|
9373
9497
|
const context = sources.map((s) => {
|
|
9374
|
-
var
|
|
9375
|
-
return (
|
|
9498
|
+
var _a3;
|
|
9499
|
+
return (_a3 = s == null ? void 0 : s.content) != null ? _a3 : "";
|
|
9376
9500
|
}).join("\n\n---\n\n");
|
|
9377
9501
|
const prompt = `Based on the following snippets from a document, what are at least 5 short, relevant questions a user might ask?
|
|
9378
9502
|
Focus on questions that can be answered by the context.
|
|
@@ -9510,18 +9634,200 @@ var ProviderHealthCheck = class {
|
|
|
9510
9634
|
}
|
|
9511
9635
|
};
|
|
9512
9636
|
|
|
9637
|
+
// src/core/FreeTierLimitsGuard.ts
|
|
9638
|
+
var FREE_TIER_QUOTAS = {
|
|
9639
|
+
MAX_DOCUMENTS: 25,
|
|
9640
|
+
MAX_FILE_SIZE_BYTES: 20 * 1024 * 1024,
|
|
9641
|
+
MAX_STORAGE_BYTES: 250 * 1024 * 1024,
|
|
9642
|
+
MAX_TRIAL_REQUEST_UNITS: 500,
|
|
9643
|
+
MAX_DAILY_REQUEST_UNITS: 50,
|
|
9644
|
+
TRIAL_DURATION_DAYS: 14,
|
|
9645
|
+
GRACE_PERIOD_DAYS: 2,
|
|
9646
|
+
MAX_RPM: 10,
|
|
9647
|
+
MAX_RPH: 100,
|
|
9648
|
+
MAX_RPD: 500,
|
|
9649
|
+
MAX_CONCURRENT_REQUESTS: 2,
|
|
9650
|
+
MAX_INPUT_TOKENS: 2e4,
|
|
9651
|
+
MAX_OUTPUT_TOKENS: 4e3,
|
|
9652
|
+
UPGRADE_REMINDER_DAYS: [7, 12, 14],
|
|
9653
|
+
MAX_USERS: 1,
|
|
9654
|
+
MAX_NAMESPACES: 1,
|
|
9655
|
+
MAX_PROJECTS: 1
|
|
9656
|
+
};
|
|
9657
|
+
var FreeTierLimitsGuard = class {
|
|
9658
|
+
static calculateTrialTimestamps(startedAt) {
|
|
9659
|
+
const startDate = startedAt ? new Date(startedAt) : /* @__PURE__ */ new Date();
|
|
9660
|
+
const trialStartedAtMs = startDate.getTime();
|
|
9661
|
+
const trialExpiresAtMs = trialStartedAtMs + FREE_TIER_QUOTAS.TRIAL_DURATION_DAYS * 24 * 60 * 60 * 1e3;
|
|
9662
|
+
const gracePeriodExpiresAtMs = trialStartedAtMs + (FREE_TIER_QUOTAS.TRIAL_DURATION_DAYS + FREE_TIER_QUOTAS.GRACE_PERIOD_DAYS) * 24 * 60 * 60 * 1e3;
|
|
9663
|
+
return {
|
|
9664
|
+
trial_started_at: new Date(trialStartedAtMs).toISOString(),
|
|
9665
|
+
trial_expires_at: new Date(trialExpiresAtMs).toISOString(),
|
|
9666
|
+
grace_period_expires_at: new Date(gracePeriodExpiresAtMs).toISOString()
|
|
9667
|
+
};
|
|
9668
|
+
}
|
|
9669
|
+
static calculateRequestUnits(operationType, options) {
|
|
9670
|
+
var _a3;
|
|
9671
|
+
const op = operationType.toLowerCase().trim();
|
|
9672
|
+
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")) {
|
|
9673
|
+
return 0;
|
|
9674
|
+
}
|
|
9675
|
+
if (op.includes("image")) {
|
|
9676
|
+
return 10;
|
|
9677
|
+
}
|
|
9678
|
+
if (op.includes("embedding")) {
|
|
9679
|
+
const chunks = (_a3 = options == null ? void 0 : options.chunkCount) != null ? _a3 : 1;
|
|
9680
|
+
return Math.max(1, Math.ceil(chunks / 1e3));
|
|
9681
|
+
}
|
|
9682
|
+
return 1;
|
|
9683
|
+
}
|
|
9684
|
+
static checkTrialStatus(startedAt, totalUnitsUsed = 0, nowServerTime = /* @__PURE__ */ new Date()) {
|
|
9685
|
+
const timestamps = this.calculateTrialTimestamps(startedAt);
|
|
9686
|
+
const startMs = new Date(timestamps.trial_started_at).getTime();
|
|
9687
|
+
const expireMs = new Date(timestamps.trial_expires_at).getTime();
|
|
9688
|
+
const graceExpireMs = new Date(timestamps.grace_period_expires_at).getTime();
|
|
9689
|
+
const nowMs = nowServerTime.getTime();
|
|
9690
|
+
const daysElapsed = Math.floor(Math.max(0, nowMs - startMs) / (1e3 * 60 * 60 * 24));
|
|
9691
|
+
const daysRemaining = Math.max(0, Math.ceil((expireMs - nowMs) / (1e3 * 60 * 60 * 24)));
|
|
9692
|
+
const isConsumedUnits = totalUnitsUsed >= FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS;
|
|
9693
|
+
const isExpiredTime = nowMs > expireMs;
|
|
9694
|
+
const isPastGraceTime = nowMs > graceExpireMs;
|
|
9695
|
+
let status = "active";
|
|
9696
|
+
let reason;
|
|
9697
|
+
if (isPastGraceTime || isConsumedUnits && isExpiredTime) {
|
|
9698
|
+
status = "expired";
|
|
9699
|
+
reason = "Trial period and grace period have expired. Upgrade your plan.";
|
|
9700
|
+
} else if (isExpiredTime || isConsumedUnits) {
|
|
9701
|
+
status = "grace_period";
|
|
9702
|
+
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).";
|
|
9703
|
+
}
|
|
9704
|
+
let upgradeReminderDue;
|
|
9705
|
+
if (FREE_TIER_QUOTAS.UPGRADE_REMINDER_DAYS.includes(daysElapsed)) {
|
|
9706
|
+
upgradeReminderDue = daysElapsed;
|
|
9707
|
+
}
|
|
9708
|
+
let usageReminderDue;
|
|
9709
|
+
const usagePercent = totalUnitsUsed / FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS * 100;
|
|
9710
|
+
if (usagePercent >= 100) {
|
|
9711
|
+
usageReminderDue = "100%";
|
|
9712
|
+
} else if (usagePercent >= 90) {
|
|
9713
|
+
usageReminderDue = "90%";
|
|
9714
|
+
} else if (usagePercent >= 80) {
|
|
9715
|
+
usageReminderDue = "80%";
|
|
9716
|
+
}
|
|
9717
|
+
return {
|
|
9718
|
+
status,
|
|
9719
|
+
daysElapsed,
|
|
9720
|
+
daysRemaining,
|
|
9721
|
+
isGracePeriod: status === "grace_period",
|
|
9722
|
+
isExpired: status === "expired",
|
|
9723
|
+
upgradeReminderDue,
|
|
9724
|
+
usageReminderDue,
|
|
9725
|
+
reason
|
|
9726
|
+
};
|
|
9727
|
+
}
|
|
9728
|
+
static checkIngestionAllowed(stats, incomingSizeBytes = 0) {
|
|
9729
|
+
var _a3, _b;
|
|
9730
|
+
const docs = (_a3 = stats.documentCount) != null ? _a3 : 0;
|
|
9731
|
+
const storage = (_b = stats.totalStorageBytes) != null ? _b : 0;
|
|
9732
|
+
if (incomingSizeBytes > FREE_TIER_QUOTAS.MAX_FILE_SIZE_BYTES) {
|
|
9733
|
+
const mbSize = (incomingSizeBytes / (1024 * 1024)).toFixed(1);
|
|
9734
|
+
return {
|
|
9735
|
+
allowed: false,
|
|
9736
|
+
reason: `[FreeTierIngestor] File size (${mbSize}MB) exceeds maximum allowed size of 20MB under Free Tier rules.`
|
|
9737
|
+
};
|
|
9738
|
+
}
|
|
9739
|
+
if (docs >= FREE_TIER_QUOTAS.MAX_DOCUMENTS) {
|
|
9740
|
+
return {
|
|
9741
|
+
allowed: false,
|
|
9742
|
+
reason: `Document limit reached (${docs}/${FREE_TIER_QUOTAS.MAX_DOCUMENTS}). Upgrade to Pro to ingest more documents.`
|
|
9743
|
+
};
|
|
9744
|
+
}
|
|
9745
|
+
if (storage + incomingSizeBytes > FREE_TIER_QUOTAS.MAX_STORAGE_BYTES) {
|
|
9746
|
+
const mbUsed = (storage / (1024 * 1024)).toFixed(1);
|
|
9747
|
+
return {
|
|
9748
|
+
allowed: false,
|
|
9749
|
+
reason: `Storage quota exceeded (${mbUsed}MB / 250MB). Upgrade for unlimited storage.`
|
|
9750
|
+
};
|
|
9751
|
+
}
|
|
9752
|
+
return { allowed: true };
|
|
9753
|
+
}
|
|
9754
|
+
static checkRequestAllowed(params) {
|
|
9755
|
+
var _a3, _b, _c;
|
|
9756
|
+
const op = (_a3 = params.operationType) != null ? _a3 : "chat";
|
|
9757
|
+
const costUnits = this.calculateRequestUnits(op, { chunkCount: params.chunkCount });
|
|
9758
|
+
if (costUnits === 0) {
|
|
9759
|
+
return { allowed: true, costUnits: 0 };
|
|
9760
|
+
}
|
|
9761
|
+
if (params.inputTokens && params.inputTokens > FREE_TIER_QUOTAS.MAX_INPUT_TOKENS) {
|
|
9762
|
+
return {
|
|
9763
|
+
allowed: false,
|
|
9764
|
+
reason: "Token limit exceeded. Upgrade your plan.",
|
|
9765
|
+
costUnits
|
|
9766
|
+
};
|
|
9767
|
+
}
|
|
9768
|
+
if (params.outputTokens && params.outputTokens > FREE_TIER_QUOTAS.MAX_OUTPUT_TOKENS) {
|
|
9769
|
+
return {
|
|
9770
|
+
allowed: false,
|
|
9771
|
+
reason: "Token limit exceeded. Upgrade your plan.",
|
|
9772
|
+
costUnits
|
|
9773
|
+
};
|
|
9774
|
+
}
|
|
9775
|
+
if (params.concurrentRequests && params.concurrentRequests > FREE_TIER_QUOTAS.MAX_CONCURRENT_REQUESTS) {
|
|
9776
|
+
return {
|
|
9777
|
+
allowed: false,
|
|
9778
|
+
reason: `Concurrent limit exceeded (max ${FREE_TIER_QUOTAS.MAX_CONCURRENT_REQUESTS} active requests). Please wait for active streams to finish.`,
|
|
9779
|
+
costUnits
|
|
9780
|
+
};
|
|
9781
|
+
}
|
|
9782
|
+
const totalUnits = (_b = params.totalUnitsUsed) != null ? _b : 0;
|
|
9783
|
+
const trialStatus = this.checkTrialStatus(params.trialStartedAt, totalUnits, params.nowServerTime);
|
|
9784
|
+
if (trialStatus.status === "expired" || trialStatus.status === "grace_period") {
|
|
9785
|
+
return {
|
|
9786
|
+
allowed: false,
|
|
9787
|
+
reason: trialStatus.reason || "Trial limit reached. Upgrade your plan.",
|
|
9788
|
+
costUnits
|
|
9789
|
+
};
|
|
9790
|
+
}
|
|
9791
|
+
if (totalUnits + costUnits > FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS) {
|
|
9792
|
+
return {
|
|
9793
|
+
allowed: false,
|
|
9794
|
+
reason: `Total trial request unit limit reached (${totalUnits}/${FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS}). Upgrade your plan.`,
|
|
9795
|
+
costUnits
|
|
9796
|
+
};
|
|
9797
|
+
}
|
|
9798
|
+
const dailyUnits = (_c = params.dailyUnitsUsed) != null ? _c : 0;
|
|
9799
|
+
if (dailyUnits + costUnits > FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS) {
|
|
9800
|
+
return {
|
|
9801
|
+
allowed: false,
|
|
9802
|
+
reason: `Daily request quota limit reached (${dailyUnits}/${FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS} units/day). Quota resets tomorrow.`,
|
|
9803
|
+
costUnits
|
|
9804
|
+
};
|
|
9805
|
+
}
|
|
9806
|
+
return { allowed: true, costUnits };
|
|
9807
|
+
}
|
|
9808
|
+
static checkQueryAllowed(dailyQueriesCount = 0) {
|
|
9809
|
+
if (dailyQueriesCount >= FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS) {
|
|
9810
|
+
return {
|
|
9811
|
+
allowed: false,
|
|
9812
|
+
reason: `Daily query limit reached (${FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS}/day). Quota resets tomorrow.`
|
|
9813
|
+
};
|
|
9814
|
+
}
|
|
9815
|
+
return { allowed: true };
|
|
9816
|
+
}
|
|
9817
|
+
};
|
|
9818
|
+
|
|
9513
9819
|
// src/core/VectorPlugin.ts
|
|
9514
9820
|
var VectorPlugin = class {
|
|
9515
9821
|
constructor(hostConfig) {
|
|
9516
9822
|
const resolvedConfig = ConfigResolver.resolve(hostConfig);
|
|
9517
9823
|
this.config = resolvedConfig;
|
|
9518
9824
|
this.validationPromise = (async () => {
|
|
9519
|
-
var
|
|
9825
|
+
var _a3;
|
|
9520
9826
|
await ConfigValidator.validateAndThrow(resolvedConfig);
|
|
9521
9827
|
LicenseVerifier.verify(
|
|
9522
9828
|
resolvedConfig.licenseKey,
|
|
9523
9829
|
resolvedConfig.projectId,
|
|
9524
|
-
(
|
|
9830
|
+
(_a3 = resolvedConfig.vectorDb) == null ? void 0 : _a3.provider
|
|
9525
9831
|
);
|
|
9526
9832
|
})();
|
|
9527
9833
|
this.validationPromise.catch(() => {
|
|
@@ -9555,16 +9861,32 @@ var VectorPlugin = class {
|
|
|
9555
9861
|
this.config.embedding
|
|
9556
9862
|
);
|
|
9557
9863
|
}
|
|
9864
|
+
estimateInputTokens(message, history = []) {
|
|
9865
|
+
const allContent = message.length + history.reduce((acc, m) => {
|
|
9866
|
+
var _a3, _b;
|
|
9867
|
+
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);
|
|
9868
|
+
}, 0);
|
|
9869
|
+
return Math.ceil(allContent / 4);
|
|
9870
|
+
}
|
|
9558
9871
|
/**
|
|
9559
9872
|
* Run a chat query.
|
|
9560
9873
|
*/
|
|
9561
9874
|
async chat(message, history = [], namespace) {
|
|
9875
|
+
var _a3;
|
|
9562
9876
|
try {
|
|
9563
9877
|
await this.validationPromise;
|
|
9564
9878
|
} catch (err) {
|
|
9565
9879
|
throw wrapError(err, "CONFIGURATION_ERROR");
|
|
9566
9880
|
}
|
|
9567
9881
|
try {
|
|
9882
|
+
const inputTokens = this.estimateInputTokens(message, history);
|
|
9883
|
+
const tokenCheck = FreeTierLimitsGuard.checkRequestAllowed({
|
|
9884
|
+
operationType: "chat",
|
|
9885
|
+
inputTokens
|
|
9886
|
+
});
|
|
9887
|
+
if (!tokenCheck.allowed && ((_a3 = tokenCheck.reason) == null ? void 0 : _a3.toLowerCase().includes("token"))) {
|
|
9888
|
+
throw wrapError(new Error(tokenCheck.reason), "RATE_LIMITED");
|
|
9889
|
+
}
|
|
9568
9890
|
return await this.pipeline.ask(message, history, namespace);
|
|
9569
9891
|
} catch (err) {
|
|
9570
9892
|
const msg = String(err);
|
|
@@ -9572,6 +9894,9 @@ var VectorPlugin = class {
|
|
|
9572
9894
|
if (msg.includes("Embed") || msg.includes("embed")) {
|
|
9573
9895
|
defaultCode = "EMBEDDING_FAILED";
|
|
9574
9896
|
}
|
|
9897
|
+
if (msg.toLowerCase().includes("token limit")) {
|
|
9898
|
+
defaultCode = "RATE_LIMITED";
|
|
9899
|
+
}
|
|
9575
9900
|
throw wrapError(err, defaultCode);
|
|
9576
9901
|
}
|
|
9577
9902
|
}
|
|
@@ -9580,12 +9905,21 @@ var VectorPlugin = class {
|
|
|
9580
9905
|
*/
|
|
9581
9906
|
chatStream(_0) {
|
|
9582
9907
|
return __asyncGenerator(this, arguments, function* (message, history = [], namespace) {
|
|
9908
|
+
var _a3;
|
|
9583
9909
|
try {
|
|
9584
9910
|
yield new __await(this.validationPromise);
|
|
9585
9911
|
} catch (err) {
|
|
9586
9912
|
throw wrapError(err, "CONFIGURATION_ERROR");
|
|
9587
9913
|
}
|
|
9588
9914
|
try {
|
|
9915
|
+
const inputTokens = this.estimateInputTokens(message, history);
|
|
9916
|
+
const tokenCheck = FreeTierLimitsGuard.checkRequestAllowed({
|
|
9917
|
+
operationType: "chat_stream",
|
|
9918
|
+
inputTokens
|
|
9919
|
+
});
|
|
9920
|
+
if (!tokenCheck.allowed && ((_a3 = tokenCheck.reason) == null ? void 0 : _a3.toLowerCase().includes("token"))) {
|
|
9921
|
+
throw wrapError(new Error(tokenCheck.reason), "RATE_LIMITED");
|
|
9922
|
+
}
|
|
9589
9923
|
const stream = this.pipeline.askStream(message, history, namespace);
|
|
9590
9924
|
try {
|
|
9591
9925
|
for (var iter = __forAwait(stream), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
|
|
@@ -9608,6 +9942,9 @@ var VectorPlugin = class {
|
|
|
9608
9942
|
if (msg.includes("Embed") || msg.includes("embed")) {
|
|
9609
9943
|
defaultCode = "EMBEDDING_FAILED";
|
|
9610
9944
|
}
|
|
9945
|
+
if (msg.toLowerCase().includes("token limit")) {
|
|
9946
|
+
defaultCode = "RATE_LIMITED";
|
|
9947
|
+
}
|
|
9611
9948
|
throw wrapError(err, defaultCode);
|
|
9612
9949
|
}
|
|
9613
9950
|
});
|
|
@@ -9655,8 +9992,8 @@ var DocumentParser = class {
|
|
|
9655
9992
|
* Extract text from a File or Buffer based on its type.
|
|
9656
9993
|
*/
|
|
9657
9994
|
static async parse(file, fileName, mimeType) {
|
|
9658
|
-
var
|
|
9659
|
-
const extension = ((
|
|
9995
|
+
var _a3;
|
|
9996
|
+
const extension = ((_a3 = fileName.split(".").pop()) == null ? void 0 : _a3.toLowerCase()) || "";
|
|
9660
9997
|
if (extension === "txt" || extension === "md" || mimeType === "text/plain" || mimeType === "text/markdown") {
|
|
9661
9998
|
return this.readAsText(file);
|
|
9662
9999
|
}
|
|
@@ -9747,9 +10084,9 @@ var DatabaseStorage = class {
|
|
|
9747
10084
|
this.fallbackDir = this.isServerless ? path.join(os.tmpdir(), ".retrivora") : path.join(process.cwd(), ".retrivora");
|
|
9748
10085
|
this.historyFile = path.join(this.fallbackDir, "history.json");
|
|
9749
10086
|
this.feedbackFile = path.join(this.fallbackDir, "feedback.json");
|
|
9750
|
-
var
|
|
10087
|
+
var _a3, _b, _c, _d, _e;
|
|
9751
10088
|
this.config = config;
|
|
9752
|
-
this.provider = ((
|
|
10089
|
+
this.provider = ((_a3 = config.vectorDb) == null ? void 0 : _a3.provider) || "fs";
|
|
9753
10090
|
const rawHistoryTable = ((_c = (_b = config.rag) == null ? void 0 : _b.history) == null ? void 0 : _c.tableName) || "retrivora_history";
|
|
9754
10091
|
const rawFeedbackTable = ((_e = (_d = config.rag) == null ? void 0 : _d.feedback) == null ? void 0 : _e.tableName) || "retrivora_feedback";
|
|
9755
10092
|
this.historyTableName = rawHistoryTable.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
@@ -9784,16 +10121,16 @@ var DatabaseStorage = class {
|
|
|
9784
10121
|
}
|
|
9785
10122
|
}
|
|
9786
10123
|
checkHistoryEnabled() {
|
|
9787
|
-
var
|
|
10124
|
+
var _a3, _b;
|
|
9788
10125
|
this.checkPremiumSubscription();
|
|
9789
|
-
if (((_b = (
|
|
10126
|
+
if (((_b = (_a3 = this.config.rag) == null ? void 0 : _a3.history) == null ? void 0 : _b.enabled) === false) {
|
|
9790
10127
|
throw new Error("[Retrivora SDK] Chat History is disabled in RagConfig.");
|
|
9791
10128
|
}
|
|
9792
10129
|
}
|
|
9793
10130
|
checkFeedbackEnabled() {
|
|
9794
|
-
var
|
|
10131
|
+
var _a3, _b;
|
|
9795
10132
|
this.checkPremiumSubscription();
|
|
9796
|
-
if (((_b = (
|
|
10133
|
+
if (((_b = (_a3 = this.config.rag) == null ? void 0 : _a3.feedback) == null ? void 0 : _b.enabled) === false) {
|
|
9797
10134
|
throw new Error("[Retrivora SDK] User Feedback is disabled in RagConfig.");
|
|
9798
10135
|
}
|
|
9799
10136
|
}
|
|
@@ -9960,8 +10297,11 @@ var DatabaseStorage = class {
|
|
|
9960
10297
|
this.writeLocalFile(this.historyFile, history);
|
|
9961
10298
|
}
|
|
9962
10299
|
}
|
|
9963
|
-
async getHistory(sessionId) {
|
|
10300
|
+
async getHistory(sessionId, projectIds) {
|
|
9964
10301
|
this.checkHistoryEnabled();
|
|
10302
|
+
if (projectIds && projectIds.length > 0 && !this.sessionInScope(sessionId, projectIds)) {
|
|
10303
|
+
return [];
|
|
10304
|
+
}
|
|
9965
10305
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
9966
10306
|
const pool = await this.getPGPool();
|
|
9967
10307
|
const res = await pool.query(
|
|
@@ -9991,8 +10331,11 @@ var DatabaseStorage = class {
|
|
|
9991
10331
|
return history.filter((h) => h.session_id === sessionId).sort((a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime());
|
|
9992
10332
|
}
|
|
9993
10333
|
}
|
|
9994
|
-
async clearHistory(sessionId) {
|
|
10334
|
+
async clearHistory(sessionId, projectIds) {
|
|
9995
10335
|
this.checkHistoryEnabled();
|
|
10336
|
+
if (projectIds && projectIds.length > 0 && !this.sessionInScope(sessionId, projectIds)) {
|
|
10337
|
+
return;
|
|
10338
|
+
}
|
|
9996
10339
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
9997
10340
|
const pool = await this.getPGPool();
|
|
9998
10341
|
await pool.query(`DELETE FROM ${this.historyTableName} WHERE session_id = $1`, [sessionId]);
|
|
@@ -10011,21 +10354,36 @@ var DatabaseStorage = class {
|
|
|
10011
10354
|
this.writeLocalFile(this.feedbackFile, filteredFeedback);
|
|
10012
10355
|
}
|
|
10013
10356
|
}
|
|
10014
|
-
|
|
10357
|
+
/**
|
|
10358
|
+
* Return true when `sessionId` falls into the allowed `projectIds` scope.
|
|
10359
|
+
* When `projectIds` is empty / undefined we allow the call (legacy behavior
|
|
10360
|
+
* for non-multi-tenant consumers). Session ids typically begin with the
|
|
10361
|
+
* project id they were created for, so we prefix-match as well as contains-match
|
|
10362
|
+
* to catch sharded / suffix-style ids used by some integrations.
|
|
10363
|
+
*/
|
|
10364
|
+
sessionInScope(sessionId, projectIds) {
|
|
10365
|
+
if (!projectIds || projectIds.length === 0) return true;
|
|
10366
|
+
return projectIds.some(
|
|
10367
|
+
(pid) => pid && (sessionId === pid || sessionId.startsWith(pid) || sessionId.includes(pid))
|
|
10368
|
+
);
|
|
10369
|
+
}
|
|
10370
|
+
async listSessions(projectIds) {
|
|
10015
10371
|
this.checkHistoryEnabled();
|
|
10372
|
+
let raw = [];
|
|
10016
10373
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
10017
10374
|
const pool = await this.getPGPool();
|
|
10018
10375
|
const res = await pool.query(`SELECT DISTINCT session_id FROM ${this.historyTableName}`);
|
|
10019
|
-
|
|
10376
|
+
raw = res.rows.map((r) => r.session_id);
|
|
10020
10377
|
} else if (this.provider === "mongodb") {
|
|
10021
10378
|
await this.getMongoClient();
|
|
10022
10379
|
const db = this.getMongoDb();
|
|
10023
|
-
|
|
10380
|
+
raw = await db.collection(this.historyTableName).distinct("session_id");
|
|
10024
10381
|
} else {
|
|
10025
10382
|
const history = this.readLocalFile(this.historyFile);
|
|
10026
|
-
|
|
10027
|
-
return Array.from(sessions);
|
|
10383
|
+
raw = Array.from(new Set(history.map((h) => h.session_id)));
|
|
10028
10384
|
}
|
|
10385
|
+
if (!projectIds || projectIds.length === 0) return raw;
|
|
10386
|
+
return raw.filter((sid) => this.sessionInScope(sid, projectIds));
|
|
10029
10387
|
}
|
|
10030
10388
|
// ─── Feedback Operations ──────────────────────────────────────────────────
|
|
10031
10389
|
async saveFeedback(feedback) {
|
|
@@ -10078,8 +10436,9 @@ var DatabaseStorage = class {
|
|
|
10078
10436
|
this.writeLocalFile(this.feedbackFile, list);
|
|
10079
10437
|
}
|
|
10080
10438
|
}
|
|
10081
|
-
async getFeedback(messageId) {
|
|
10439
|
+
async getFeedback(messageId, projectIds) {
|
|
10082
10440
|
this.checkFeedbackEnabled();
|
|
10441
|
+
let item = null;
|
|
10083
10442
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
10084
10443
|
const pool = await this.getPGPool();
|
|
10085
10444
|
const res = await pool.query(
|
|
@@ -10088,28 +10447,34 @@ var DatabaseStorage = class {
|
|
|
10088
10447
|
WHERE message_id = $1`,
|
|
10089
10448
|
[messageId]
|
|
10090
10449
|
);
|
|
10091
|
-
|
|
10450
|
+
item = res.rows[0] || null;
|
|
10092
10451
|
} else if (this.provider === "mongodb") {
|
|
10093
10452
|
await this.getMongoClient();
|
|
10094
10453
|
const db = this.getMongoDb();
|
|
10095
10454
|
const col = db.collection(this.feedbackTableName);
|
|
10096
|
-
const
|
|
10097
|
-
if (
|
|
10098
|
-
|
|
10099
|
-
|
|
10100
|
-
|
|
10101
|
-
|
|
10102
|
-
|
|
10103
|
-
|
|
10104
|
-
|
|
10105
|
-
|
|
10455
|
+
const raw = await col.findOne({ message_id: messageId });
|
|
10456
|
+
if (raw) {
|
|
10457
|
+
item = {
|
|
10458
|
+
id: raw.id,
|
|
10459
|
+
messageId: raw.message_id,
|
|
10460
|
+
sessionId: raw.session_id,
|
|
10461
|
+
rating: raw.rating,
|
|
10462
|
+
comment: raw.comment,
|
|
10463
|
+
createdAt: raw.created_at
|
|
10464
|
+
};
|
|
10465
|
+
}
|
|
10106
10466
|
} else {
|
|
10107
10467
|
const list = this.readLocalFile(this.feedbackFile);
|
|
10108
|
-
|
|
10468
|
+
item = list.find((f) => f.message_id === messageId) || null;
|
|
10469
|
+
}
|
|
10470
|
+
if (item && projectIds && projectIds.length > 0) {
|
|
10471
|
+
return this.sessionInScope(item.sessionId, projectIds) ? item : null;
|
|
10109
10472
|
}
|
|
10473
|
+
return item;
|
|
10110
10474
|
}
|
|
10111
|
-
async listFeedback() {
|
|
10475
|
+
async listFeedback(projectIds) {
|
|
10112
10476
|
this.checkFeedbackEnabled();
|
|
10477
|
+
let raw = [];
|
|
10113
10478
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
10114
10479
|
const pool = await this.getPGPool();
|
|
10115
10480
|
const res = await pool.query(
|
|
@@ -10117,13 +10482,13 @@ var DatabaseStorage = class {
|
|
|
10117
10482
|
FROM ${this.feedbackTableName}
|
|
10118
10483
|
ORDER BY created_at DESC`
|
|
10119
10484
|
);
|
|
10120
|
-
|
|
10485
|
+
raw = res.rows;
|
|
10121
10486
|
} else if (this.provider === "mongodb") {
|
|
10122
10487
|
await this.getMongoClient();
|
|
10123
10488
|
const db = this.getMongoDb();
|
|
10124
10489
|
const col = db.collection(this.feedbackTableName);
|
|
10125
10490
|
const items = await col.find({}).sort({ created_at: -1 }).toArray();
|
|
10126
|
-
|
|
10491
|
+
raw = items.map((item) => ({
|
|
10127
10492
|
id: item.id,
|
|
10128
10493
|
messageId: item.message_id,
|
|
10129
10494
|
sessionId: item.session_id,
|
|
@@ -10133,8 +10498,10 @@ var DatabaseStorage = class {
|
|
|
10133
10498
|
}));
|
|
10134
10499
|
} else {
|
|
10135
10500
|
const list = this.readLocalFile(this.feedbackFile);
|
|
10136
|
-
|
|
10501
|
+
raw = [...list].sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime());
|
|
10137
10502
|
}
|
|
10503
|
+
if (!projectIds || projectIds.length === 0) return raw;
|
|
10504
|
+
return raw.filter((f) => this.sessionInScope(f.sessionId, projectIds));
|
|
10138
10505
|
}
|
|
10139
10506
|
async disconnect() {
|
|
10140
10507
|
if (this.pgPool) {
|
|
@@ -10197,8 +10564,8 @@ var _g = global;
|
|
|
10197
10564
|
var _a;
|
|
10198
10565
|
var rateLimiter = (_a = _g.__retrivoraRateLimiter) != null ? _a : _g.__retrivoraRateLimiter = new RateLimiter(6e4, 30);
|
|
10199
10566
|
function getRateLimitKey(req) {
|
|
10200
|
-
var
|
|
10201
|
-
const ip = ((_b = (
|
|
10567
|
+
var _a3, _b;
|
|
10568
|
+
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
10569
|
return `ip:${ip}`;
|
|
10203
10570
|
}
|
|
10204
10571
|
function checkRateLimit(req) {
|
|
@@ -10220,6 +10587,66 @@ function checkRateLimit(req) {
|
|
|
10220
10587
|
}
|
|
10221
10588
|
return null;
|
|
10222
10589
|
}
|
|
10590
|
+
var FREE_TIER_NAMES = /* @__PURE__ */ new Set(["hobby", "free", "free_trial", "trial"]);
|
|
10591
|
+
function isFreeTier(tier) {
|
|
10592
|
+
if (!tier) return true;
|
|
10593
|
+
return FREE_TIER_NAMES.has(tier.toLowerCase().trim());
|
|
10594
|
+
}
|
|
10595
|
+
var _a2;
|
|
10596
|
+
var _freeTierGuardInstance = (_a2 = _g.__retrivoraFreeTierGuard) != null ? _a2 : _g.__retrivoraFreeTierGuard = new FreeTierLimitsGuard();
|
|
10597
|
+
function createPaymentRequiredResponse(reason, details) {
|
|
10598
|
+
const body = __spreadProps(__spreadValues({
|
|
10599
|
+
type: "https://retrivora.com/docs/errors/payment-required",
|
|
10600
|
+
title: "Payment Required",
|
|
10601
|
+
status: 402,
|
|
10602
|
+
detail: reason,
|
|
10603
|
+
code: "FREE_TIER_LIMIT_EXCEEDED",
|
|
10604
|
+
instance: void 0
|
|
10605
|
+
}, details != null ? details : {}), {
|
|
10606
|
+
quota: {
|
|
10607
|
+
maxDailyRequestUnits: FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS,
|
|
10608
|
+
maxTrialRequestUnits: FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS,
|
|
10609
|
+
maxDocuments: FREE_TIER_QUOTAS.MAX_DOCUMENTS,
|
|
10610
|
+
maxStorageBytes: FREE_TIER_QUOTAS.MAX_STORAGE_BYTES,
|
|
10611
|
+
upgradeUrl: "https://retrivora.com/pricing"
|
|
10612
|
+
}
|
|
10613
|
+
});
|
|
10614
|
+
return new Response(JSON.stringify(body), {
|
|
10615
|
+
status: 402,
|
|
10616
|
+
headers: {
|
|
10617
|
+
"Content-Type": "application/problem+json"
|
|
10618
|
+
}
|
|
10619
|
+
});
|
|
10620
|
+
}
|
|
10621
|
+
function resolveLicenseKey(req, config, bodyLicenseKey) {
|
|
10622
|
+
var _a3;
|
|
10623
|
+
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 || "";
|
|
10624
|
+
}
|
|
10625
|
+
function enforceLicense(req, config, bodyLicenseKey) {
|
|
10626
|
+
const rawKey = resolveLicenseKey(req, config, bodyLicenseKey);
|
|
10627
|
+
const licenseKey = (rawKey || "").trim().replace(/^["']|["']$/g, "").trim();
|
|
10628
|
+
const projectId = config.projectId || "my-rag-app";
|
|
10629
|
+
try {
|
|
10630
|
+
const payload = LicenseVerifier.verify(licenseKey, projectId);
|
|
10631
|
+
return { ok: true, payload };
|
|
10632
|
+
} catch (err) {
|
|
10633
|
+
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.";
|
|
10634
|
+
const body = {
|
|
10635
|
+
error: {
|
|
10636
|
+
code: "LICENSE_REVOKED",
|
|
10637
|
+
message: "Your Retrivora license key has been terminated, suspended, or revoked. Access denied."
|
|
10638
|
+
},
|
|
10639
|
+
details: message
|
|
10640
|
+
};
|
|
10641
|
+
return {
|
|
10642
|
+
ok: false,
|
|
10643
|
+
response: new Response(JSON.stringify(body), {
|
|
10644
|
+
status: 403,
|
|
10645
|
+
headers: { "Content-Type": "application/json" }
|
|
10646
|
+
})
|
|
10647
|
+
};
|
|
10648
|
+
}
|
|
10649
|
+
}
|
|
10223
10650
|
var MAX_MESSAGE_LENGTH = 8e3;
|
|
10224
10651
|
function sanitizeInput(raw) {
|
|
10225
10652
|
const stripped = raw.replace(/[\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F-\u009F]/g, "");
|
|
@@ -10241,7 +10668,7 @@ function getOrCreatePlugin(configOrPlugin) {
|
|
|
10241
10668
|
return _g[cacheKey];
|
|
10242
10669
|
}
|
|
10243
10670
|
function reportTelemetry(req, plugin, action, status, details, trace) {
|
|
10244
|
-
var
|
|
10671
|
+
var _a3, _b, _c, _d, _e, _f, _g2;
|
|
10245
10672
|
try {
|
|
10246
10673
|
const config = plugin.getConfig();
|
|
10247
10674
|
const licenseKey = config.licenseKey || process.env.RAG_LICENSE_KEY || process.env.RETRIVORA_LICENSE_KEY || process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY;
|
|
@@ -10256,7 +10683,7 @@ function reportTelemetry(req, plugin, action, status, details, trace) {
|
|
|
10256
10683
|
absoluteUrl = `${proto}://${host}${telemetryUrl}`;
|
|
10257
10684
|
}
|
|
10258
10685
|
const projectId = config.projectId || "default";
|
|
10259
|
-
const model = (trace == null ? void 0 : trace.model) || ((
|
|
10686
|
+
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
10687
|
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
10688
|
const tokens = Number(((_e = trace == null ? void 0 : trace.tokens) == null ? void 0 : _e.totalTokens) || (trace == null ? void 0 : trace.totalTokens) || 0);
|
|
10262
10689
|
const costUsd = Number(((_f = trace == null ? void 0 : trace.tokens) == null ? void 0 : _f.estimatedCostUsd) || (trace == null ? void 0 : trace.costUsd) || 0);
|
|
@@ -10280,7 +10707,6 @@ function reportTelemetry(req, plugin, action, status, details, trace) {
|
|
|
10280
10707
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
10281
10708
|
details
|
|
10282
10709
|
};
|
|
10283
|
-
console.log(`[Retrivora SDK Telemetry] Dispatching telemetry -> Feature: "${action}", Status: "${status}", Project: "${projectId}", Latency: ${latencyMs}ms`);
|
|
10284
10710
|
fetch(absoluteUrl, {
|
|
10285
10711
|
method: "POST",
|
|
10286
10712
|
headers: {
|
|
@@ -10338,14 +10764,39 @@ function createChatHandler(configOrPlugin, options) {
|
|
|
10338
10764
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
10339
10765
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
10340
10766
|
return async function POST(req, context) {
|
|
10341
|
-
var
|
|
10767
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
10342
10768
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10343
10769
|
if (authResult) return authResult;
|
|
10344
10770
|
const rateLimited = checkRateLimit(req);
|
|
10345
10771
|
if (rateLimited) return rateLimited;
|
|
10772
|
+
const config = plugin.getConfig();
|
|
10346
10773
|
try {
|
|
10347
10774
|
const body = await req.json();
|
|
10348
10775
|
const bodyObj = body != null ? body : {};
|
|
10776
|
+
const licenseCheck = enforceLicense(req, config, bodyObj == null ? void 0 : bodyObj.licenseKey);
|
|
10777
|
+
if (!licenseCheck.ok) return licenseCheck.response;
|
|
10778
|
+
if (isFreeTier(licenseCheck.payload.tier)) {
|
|
10779
|
+
const estimatedInputTokens = Math.ceil(
|
|
10780
|
+
((((_a3 = bodyObj.message) == null ? void 0 : _a3.length) || 0) + (Array.isArray(bodyObj.messages) ? bodyObj.messages.reduce((a, m) => {
|
|
10781
|
+
var _a4, _b2;
|
|
10782
|
+
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);
|
|
10783
|
+
}, 0) : 0) + (((_b = bodyObj.history) == null ? void 0 : _b.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)) / 4
|
|
10787
|
+
);
|
|
10788
|
+
const chatCheck = FreeTierLimitsGuard.checkRequestAllowed({
|
|
10789
|
+
operationType: "chat",
|
|
10790
|
+
inputTokens: estimatedInputTokens,
|
|
10791
|
+
projectId: licenseCheck.payload.projectId
|
|
10792
|
+
});
|
|
10793
|
+
if (!chatCheck.allowed) {
|
|
10794
|
+
return createPaymentRequiredResponse(
|
|
10795
|
+
chatCheck.reason || "Free tier quota exceeded.",
|
|
10796
|
+
{ tier: licenseCheck.payload.tier, projectId: licenseCheck.payload.projectId }
|
|
10797
|
+
);
|
|
10798
|
+
}
|
|
10799
|
+
}
|
|
10349
10800
|
let rawMessage = bodyObj.message;
|
|
10350
10801
|
if (!rawMessage && Array.isArray(bodyObj.messages) && bodyObj.messages.length > 0) {
|
|
10351
10802
|
const lastMsg = bodyObj.messages[bodyObj.messages.length - 1];
|
|
@@ -10377,7 +10828,7 @@ function createChatHandler(configOrPlugin, options) {
|
|
|
10377
10828
|
uiTransformation: result.ui_transformation,
|
|
10378
10829
|
trace: result.trace
|
|
10379
10830
|
}).catch((err) => console.warn("[createChatHandler] Failed to save assistant message:", err));
|
|
10380
|
-
reportTelemetry(req, plugin, "QUERY_GENERATION", "success", `Tokens: ${((
|
|
10831
|
+
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
10832
|
return import_server.NextResponse.json(__spreadProps(__spreadValues({}, result), {
|
|
10382
10833
|
messageId: assistantMsgId,
|
|
10383
10834
|
userMessageId: userMsgId
|
|
@@ -10394,14 +10845,15 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10394
10845
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
10395
10846
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
10396
10847
|
return async function POST(req, context) {
|
|
10397
|
-
var
|
|
10848
|
+
var _a3, _b, _c;
|
|
10398
10849
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10399
10850
|
if (authResult) return authResult;
|
|
10400
10851
|
const rateLimited = checkRateLimit(req);
|
|
10401
10852
|
if (rateLimited) return rateLimited;
|
|
10853
|
+
const config = plugin.getConfig();
|
|
10402
10854
|
let body;
|
|
10403
10855
|
try {
|
|
10404
|
-
if ((
|
|
10856
|
+
if ((_a3 = req.headers.get("content-type")) == null ? void 0 : _a3.includes("multipart/form-data")) {
|
|
10405
10857
|
const uploader = createUploadHandler(plugin, { onAuthorize });
|
|
10406
10858
|
return uploader(req);
|
|
10407
10859
|
}
|
|
@@ -10413,6 +10865,30 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10413
10865
|
});
|
|
10414
10866
|
}
|
|
10415
10867
|
const bodyObj = body != null ? body : {};
|
|
10868
|
+
const licenseCheck = enforceLicense(req, config, bodyObj == null ? void 0 : bodyObj.licenseKey);
|
|
10869
|
+
if (!licenseCheck.ok) return licenseCheck.response;
|
|
10870
|
+
if (isFreeTier(licenseCheck.payload.tier)) {
|
|
10871
|
+
const estimatedInputTokens = Math.ceil(
|
|
10872
|
+
((((_b = bodyObj.message) == null ? void 0 : _b.length) || 0) + (Array.isArray(bodyObj.messages) ? bodyObj.messages.reduce((a, m) => {
|
|
10873
|
+
var _a4, _b2;
|
|
10874
|
+
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);
|
|
10875
|
+
}, 0) : 0) + (((_c = bodyObj.history) == null ? void 0 : _c.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)) / 4
|
|
10879
|
+
);
|
|
10880
|
+
const chatCheck = FreeTierLimitsGuard.checkRequestAllowed({
|
|
10881
|
+
operationType: "chat_stream",
|
|
10882
|
+
inputTokens: estimatedInputTokens,
|
|
10883
|
+
projectId: licenseCheck.payload.projectId
|
|
10884
|
+
});
|
|
10885
|
+
if (!chatCheck.allowed) {
|
|
10886
|
+
return createPaymentRequiredResponse(
|
|
10887
|
+
chatCheck.reason || "Free tier quota exceeded.",
|
|
10888
|
+
{ tier: licenseCheck.payload.tier, projectId: licenseCheck.payload.projectId }
|
|
10889
|
+
);
|
|
10890
|
+
}
|
|
10891
|
+
}
|
|
10416
10892
|
let rawMessage = bodyObj.message;
|
|
10417
10893
|
if (!rawMessage && Array.isArray(bodyObj.messages) && bodyObj.messages.length > 0) {
|
|
10418
10894
|
const lastMsg = bodyObj.messages[bodyObj.messages.length - 1];
|
|
@@ -10442,7 +10918,7 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10442
10918
|
let isActive = true;
|
|
10443
10919
|
const stream = new ReadableStream({
|
|
10444
10920
|
async start(controller) {
|
|
10445
|
-
var
|
|
10921
|
+
var _a4, _b2, _c2, _d, _e;
|
|
10446
10922
|
const enqueue = (text) => {
|
|
10447
10923
|
if (!isActive) return;
|
|
10448
10924
|
try {
|
|
@@ -10475,7 +10951,7 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10475
10951
|
let uiTransformation = responseChunk == null ? void 0 : responseChunk.ui_transformation;
|
|
10476
10952
|
if (sources.length > 0) {
|
|
10477
10953
|
try {
|
|
10478
|
-
uiTransformation = (
|
|
10954
|
+
uiTransformation = (_a4 = responseChunk == null ? void 0 : responseChunk.ui_transformation) != null ? _a4 : UITransformer.transform(message, sources, plugin.getConfig());
|
|
10479
10955
|
if (uiTransformation) {
|
|
10480
10956
|
enqueue(sseUIFrame(uiTransformation));
|
|
10481
10957
|
}
|
|
@@ -10499,7 +10975,7 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10499
10975
|
uiTransformation,
|
|
10500
10976
|
trace: responseChunk == null ? void 0 : responseChunk.trace
|
|
10501
10977
|
}).catch((err) => console.warn("[createStreamHandler] Failed to save assistant message:", err));
|
|
10502
|
-
reportTelemetry(req, plugin, "QUERY_GENERATION", "success", `Tokens: ${((
|
|
10978
|
+
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
10979
|
}
|
|
10504
10980
|
}
|
|
10505
10981
|
} catch (temp) {
|
|
@@ -10549,12 +11025,36 @@ function createIngestHandler(configOrPlugin, options) {
|
|
|
10549
11025
|
return async function POST(req, context) {
|
|
10550
11026
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10551
11027
|
if (authResult) return authResult;
|
|
11028
|
+
const config = plugin.getConfig();
|
|
10552
11029
|
try {
|
|
10553
11030
|
const body = await req.json();
|
|
11031
|
+
const licenseCheck = enforceLicense(req, config, body == null ? void 0 : body.licenseKey);
|
|
11032
|
+
if (!licenseCheck.ok) return licenseCheck.response;
|
|
10554
11033
|
const { documents, namespace } = body;
|
|
10555
11034
|
if (!Array.isArray(documents) || documents.length === 0) {
|
|
10556
11035
|
return import_server.NextResponse.json({ error: "documents array is required" }, { status: 400 });
|
|
10557
11036
|
}
|
|
11037
|
+
if (isFreeTier(licenseCheck.payload.tier)) {
|
|
11038
|
+
const totalIncomingBytes = documents.reduce(
|
|
11039
|
+
(sum, d) => sum + Buffer.byteLength(d.content || "", "utf8"),
|
|
11040
|
+
0
|
|
11041
|
+
);
|
|
11042
|
+
const ingestCheck = FreeTierLimitsGuard.checkIngestionAllowed(
|
|
11043
|
+
{ documentCount: documents.length },
|
|
11044
|
+
totalIncomingBytes
|
|
11045
|
+
);
|
|
11046
|
+
if (!ingestCheck.allowed) {
|
|
11047
|
+
return createPaymentRequiredResponse(
|
|
11048
|
+
ingestCheck.reason || "Free tier ingestion limit reached.",
|
|
11049
|
+
{
|
|
11050
|
+
tier: licenseCheck.payload.tier,
|
|
11051
|
+
projectId: licenseCheck.payload.projectId,
|
|
11052
|
+
documents: documents.length,
|
|
11053
|
+
incomingBytes: totalIncomingBytes
|
|
11054
|
+
}
|
|
11055
|
+
);
|
|
11056
|
+
}
|
|
11057
|
+
}
|
|
10558
11058
|
const results = await plugin.ingest(documents, namespace);
|
|
10559
11059
|
reportTelemetry(req, plugin, "DOCUMENT_INGESTION", "success", `Ingested ${documents.length} document(s)`);
|
|
10560
11060
|
return import_server.NextResponse.json({ results });
|
|
@@ -10591,7 +11091,7 @@ function createLicenseHandler(configOrPlugin, options) {
|
|
|
10591
11091
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
10592
11092
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
10593
11093
|
return async function POST(req) {
|
|
10594
|
-
var
|
|
11094
|
+
var _a3;
|
|
10595
11095
|
if (req) {
|
|
10596
11096
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10597
11097
|
if (authResult) return authResult;
|
|
@@ -10599,7 +11099,7 @@ function createLicenseHandler(configOrPlugin, options) {
|
|
|
10599
11099
|
try {
|
|
10600
11100
|
const body = await req.json().catch(() => ({}));
|
|
10601
11101
|
const config = plugin.getConfig();
|
|
10602
|
-
const rawKey = req.headers.get("x-license-key") || (body == null ? void 0 : body.licenseKey) || ((
|
|
11102
|
+
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
11103
|
const licenseKey = (rawKey || "").trim().replace(/^["']|["']$/g, "").trim();
|
|
10604
11104
|
const projectId = (body == null ? void 0 : body.projectId) || config.projectId || "my-rag-app";
|
|
10605
11105
|
const payload = LicenseVerifier.verify(licenseKey, projectId);
|
|
@@ -10634,6 +11134,9 @@ function createUploadHandler(configOrPlugin, options) {
|
|
|
10634
11134
|
return async function POST(req, context) {
|
|
10635
11135
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10636
11136
|
if (authResult) return authResult;
|
|
11137
|
+
const config = plugin.getConfig();
|
|
11138
|
+
const licenseCheck = enforceLicense(req, config);
|
|
11139
|
+
if (!licenseCheck.ok) return licenseCheck.response;
|
|
10637
11140
|
try {
|
|
10638
11141
|
const formData = await req.formData();
|
|
10639
11142
|
const files = formData.getAll("files");
|
|
@@ -10643,6 +11146,26 @@ function createUploadHandler(configOrPlugin, options) {
|
|
|
10643
11146
|
if (!files || files.length === 0) {
|
|
10644
11147
|
return import_server.NextResponse.json({ error: "No files provided" }, { status: 400 });
|
|
10645
11148
|
}
|
|
11149
|
+
if (isFreeTier(licenseCheck.payload.tier)) {
|
|
11150
|
+
const totalUploadBytes = files.reduce((sum, f) => sum + (f.size || 0), 0);
|
|
11151
|
+
const uploadCheck = FreeTierLimitsGuard.checkIngestionAllowed(
|
|
11152
|
+
{ documentCount: files.length },
|
|
11153
|
+
totalUploadBytes
|
|
11154
|
+
);
|
|
11155
|
+
if (!uploadCheck.allowed) {
|
|
11156
|
+
return createPaymentRequiredResponse(
|
|
11157
|
+
uploadCheck.reason || "Free tier upload limit reached.",
|
|
11158
|
+
{
|
|
11159
|
+
tier: licenseCheck.payload.tier,
|
|
11160
|
+
projectId: licenseCheck.payload.projectId,
|
|
11161
|
+
fileCount: files.length,
|
|
11162
|
+
totalUploadBytes,
|
|
11163
|
+
maxFileSizeBytes: FREE_TIER_QUOTAS.MAX_FILE_SIZE_BYTES,
|
|
11164
|
+
maxStorageBytes: FREE_TIER_QUOTAS.MAX_STORAGE_BYTES
|
|
11165
|
+
}
|
|
11166
|
+
);
|
|
11167
|
+
}
|
|
11168
|
+
}
|
|
10646
11169
|
const documents = [];
|
|
10647
11170
|
for (const file of files) {
|
|
10648
11171
|
const isExcel = file.name.toLowerCase().endsWith(".xlsx") || file.name.toLowerCase().endsWith(".xls") || file.type.includes("spreadsheet") || file.type.includes("excel");
|
|
@@ -10752,13 +11275,22 @@ function createSuggestionsHandler(configOrPlugin, options) {
|
|
|
10752
11275
|
return async function handler(req) {
|
|
10753
11276
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10754
11277
|
if (authResult) return authResult;
|
|
11278
|
+
const config = plugin.getConfig();
|
|
11279
|
+
const licenseCheck = enforceLicense(req, config);
|
|
11280
|
+
if (!licenseCheck.ok) return licenseCheck.response;
|
|
10755
11281
|
try {
|
|
10756
11282
|
let query = "";
|
|
10757
11283
|
let namespace = void 0;
|
|
11284
|
+
let bodyLicenseKey = void 0;
|
|
10758
11285
|
if (req.method === "POST") {
|
|
10759
11286
|
const body = await req.json().catch(() => ({}));
|
|
10760
11287
|
query = body.query || "";
|
|
10761
11288
|
namespace = body.namespace;
|
|
11289
|
+
bodyLicenseKey = body.licenseKey;
|
|
11290
|
+
if (bodyLicenseKey) {
|
|
11291
|
+
const recheck = enforceLicense(req, config, bodyLicenseKey);
|
|
11292
|
+
if (!recheck.ok) return recheck.response;
|
|
11293
|
+
}
|
|
10762
11294
|
} else {
|
|
10763
11295
|
const url = new URL(req.url);
|
|
10764
11296
|
query = url.searchParams.get("query") || "";
|
|
@@ -10781,14 +11313,16 @@ function createHistoryHandler(configOrPlugin, options) {
|
|
|
10781
11313
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
10782
11314
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
10783
11315
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
11316
|
+
const onResolveScope = options == null ? void 0 : options.onResolveScope;
|
|
10784
11317
|
return async function handler(req) {
|
|
10785
11318
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10786
11319
|
if (authResult) return authResult;
|
|
11320
|
+
const scope = onResolveScope ? await onResolveScope(req) : void 0;
|
|
10787
11321
|
const url = new URL(req.url);
|
|
10788
11322
|
const sessionId = url.searchParams.get("sessionId") || "default";
|
|
10789
11323
|
if (req.method === "GET") {
|
|
10790
11324
|
try {
|
|
10791
|
-
const history = await storage.getHistory(sessionId);
|
|
11325
|
+
const history = await storage.getHistory(sessionId, scope);
|
|
10792
11326
|
return import_server.NextResponse.json({ history });
|
|
10793
11327
|
} catch (err) {
|
|
10794
11328
|
const message = err instanceof Error ? err.message : "Failed to fetch history";
|
|
@@ -10798,7 +11332,7 @@ function createHistoryHandler(configOrPlugin, options) {
|
|
|
10798
11332
|
try {
|
|
10799
11333
|
const body = await req.json().catch(() => ({}));
|
|
10800
11334
|
const sid = body.sessionId || sessionId;
|
|
10801
|
-
await storage.clearHistory(sid);
|
|
11335
|
+
await storage.clearHistory(sid, scope);
|
|
10802
11336
|
return import_server.NextResponse.json({ success: true });
|
|
10803
11337
|
} catch (err) {
|
|
10804
11338
|
const message = err instanceof Error ? err.message : "Failed to clear history";
|
|
@@ -10812,18 +11346,20 @@ function createFeedbackHandler(configOrPlugin, options) {
|
|
|
10812
11346
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
10813
11347
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
10814
11348
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
11349
|
+
const onResolveScope = options == null ? void 0 : options.onResolveScope;
|
|
10815
11350
|
return async function handler(req) {
|
|
10816
11351
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10817
11352
|
if (authResult) return authResult;
|
|
11353
|
+
const scope = onResolveScope ? await onResolveScope(req) : void 0;
|
|
10818
11354
|
if (req.method === "GET") {
|
|
10819
11355
|
try {
|
|
10820
11356
|
const url = new URL(req.url);
|
|
10821
11357
|
const messageId = url.searchParams.get("messageId");
|
|
10822
11358
|
if (!messageId) {
|
|
10823
|
-
const feedbackList = await storage.listFeedback();
|
|
11359
|
+
const feedbackList = await storage.listFeedback(scope);
|
|
10824
11360
|
return import_server.NextResponse.json({ feedback: feedbackList });
|
|
10825
11361
|
}
|
|
10826
|
-
const feedback = await storage.getFeedback(messageId);
|
|
11362
|
+
const feedback = await storage.getFeedback(messageId, scope);
|
|
10827
11363
|
return import_server.NextResponse.json({ feedback });
|
|
10828
11364
|
} catch (err) {
|
|
10829
11365
|
const message = err instanceof Error ? err.message : "Failed to fetch feedback";
|
|
@@ -10839,6 +11375,17 @@ function createFeedbackHandler(configOrPlugin, options) {
|
|
|
10839
11375
|
if (!rating) {
|
|
10840
11376
|
return import_server.NextResponse.json({ error: "rating is required" }, { status: 400 });
|
|
10841
11377
|
}
|
|
11378
|
+
if (scope && scope.length > 0) {
|
|
11379
|
+
const matches = scope.some(
|
|
11380
|
+
(pid) => pid && (sessionId === pid || sessionId.startsWith(pid) || sessionId.includes(pid))
|
|
11381
|
+
);
|
|
11382
|
+
if (!matches) {
|
|
11383
|
+
return import_server.NextResponse.json(
|
|
11384
|
+
{ error: "sessionId is outside the authorized project scope" },
|
|
11385
|
+
{ status: 403 }
|
|
11386
|
+
);
|
|
11387
|
+
}
|
|
11388
|
+
}
|
|
10842
11389
|
await storage.saveFeedback({ messageId, sessionId, rating, comment });
|
|
10843
11390
|
return import_server.NextResponse.json({ success: true });
|
|
10844
11391
|
} catch (err) {
|
|
@@ -10853,14 +11400,15 @@ function createSessionsHandler(configOrPlugin, options) {
|
|
|
10853
11400
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
10854
11401
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
10855
11402
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
11403
|
+
const onResolveScope = options == null ? void 0 : options.onResolveScope;
|
|
10856
11404
|
return async function GET(req) {
|
|
10857
11405
|
if (req) {
|
|
10858
11406
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10859
11407
|
if (authResult) return authResult;
|
|
10860
11408
|
}
|
|
10861
|
-
void req;
|
|
10862
11409
|
try {
|
|
10863
|
-
const
|
|
11410
|
+
const scope = req && onResolveScope ? await onResolveScope(req) : void 0;
|
|
11411
|
+
const sessions = await storage.listSessions(scope);
|
|
10864
11412
|
return import_server.NextResponse.json({ sessions });
|
|
10865
11413
|
} catch (err) {
|
|
10866
11414
|
const message = err instanceof Error ? err.message : "Failed to list sessions";
|
|
@@ -10871,15 +11419,17 @@ function createSessionsHandler(configOrPlugin, options) {
|
|
|
10871
11419
|
function createRagHandler(configOrPlugin, options) {
|
|
10872
11420
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
10873
11421
|
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
|
|
11422
|
+
const onResolveScope = options == null ? void 0 : options.onResolveScope;
|
|
11423
|
+
const scopeableOptions = { onAuthorize, onResolveScope };
|
|
11424
|
+
const chatHandler = createChatHandler(plugin, scopeableOptions);
|
|
11425
|
+
const streamHandler = createStreamHandler(plugin, scopeableOptions);
|
|
11426
|
+
const uploadHandler = createUploadHandler(plugin, scopeableOptions);
|
|
11427
|
+
const healthHandler = createHealthHandler(plugin, scopeableOptions);
|
|
11428
|
+
const suggestionsHandler = createSuggestionsHandler(plugin, scopeableOptions);
|
|
11429
|
+
const historyHandler = createHistoryHandler(plugin, scopeableOptions);
|
|
11430
|
+
const feedbackHandler = createFeedbackHandler(plugin, scopeableOptions);
|
|
11431
|
+
const sessionsHandler = createSessionsHandler(plugin, scopeableOptions);
|
|
11432
|
+
const licenseHandler = createLicenseHandler(plugin, scopeableOptions);
|
|
10883
11433
|
async function routePostRequest(req, segment) {
|
|
10884
11434
|
switch (segment) {
|
|
10885
11435
|
case "chat":
|
|
@@ -10921,7 +11471,7 @@ function createRagHandler(configOrPlugin, options) {
|
|
|
10921
11471
|
}
|
|
10922
11472
|
}
|
|
10923
11473
|
async function getSegment(req, context) {
|
|
10924
|
-
var
|
|
11474
|
+
var _a3, _b;
|
|
10925
11475
|
const contentType = req.headers.get("content-type") || "";
|
|
10926
11476
|
if (contentType.includes("multipart/form-data")) {
|
|
10927
11477
|
return "upload";
|
|
@@ -10938,7 +11488,7 @@ function createRagHandler(configOrPlugin, options) {
|
|
|
10938
11488
|
if (pathname.endsWith("/history")) return "history";
|
|
10939
11489
|
} catch (e) {
|
|
10940
11490
|
}
|
|
10941
|
-
const resolvedParams = typeof ((
|
|
11491
|
+
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
11492
|
const segments = (resolvedParams == null ? void 0 : resolvedParams.retrivora) || ((_b = resolvedParams == null ? void 0 : resolvedParams.params) == null ? void 0 : _b.retrivora) || [];
|
|
10943
11493
|
const joined = segments.join("/");
|
|
10944
11494
|
return joined || "chat";
|