@retrivora-ai/rag-engine 2.3.0 → 2.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{LicenseValidator-CENvo9o2.d.mts → BatchProcessor-7yV-UCHW.d.mts} +142 -3
- package/dist/{LicenseValidator-CsjJp2PP.d.ts → BatchProcessor-BfzuU4cK.d.ts} +142 -3
- package/dist/handlers/index.d.mts +1 -1
- package/dist/handlers/index.d.ts +1 -1
- package/dist/handlers/index.js +881 -331
- package/dist/handlers/index.mjs +881 -331
- package/dist/index-DR_O_B-W.d.ts +394 -0
- package/dist/index-fnpaCuma.d.mts +394 -0
- package/dist/index.css +58 -0
- package/dist/index.d.mts +63 -3
- package/dist/index.d.ts +63 -3
- package/dist/index.js +454 -36
- package/dist/index.mjs +453 -38
- package/dist/server.d.mts +35 -73
- package/dist/server.d.ts +35 -73
- package/dist/server.js +911 -345
- package/dist/server.mjs +911 -345
- package/package.json +3 -2
- package/src/components/ChatWidget.tsx +149 -48
- package/src/components/ChatWindow.tsx +52 -9
- package/src/components/CodeViewer.tsx +1 -1
- package/src/core/BatchProcessor.ts +42 -4
- package/src/core/CircuitBreaker.ts +118 -0
- package/src/core/DatabaseStorage.ts +55 -24
- package/src/core/FreeTierLimitsGuard.ts +281 -0
- package/src/core/LangChainAgent.ts +0 -2
- package/src/core/LicenseValidator.ts +66 -2
- package/src/core/LicenseVerifier.ts +31 -3
- package/src/core/VectorPlugin.ts +30 -0
- package/src/handlers/index.ts +491 -36
- package/src/index.css +58 -0
- package/src/index.ts +4 -0
- package/src/providers/vectordb/MilvusProvider.ts +0 -1
- package/src/providers/vectordb/MongoDBProvider.ts +0 -1
- package/src/providers/vectordb/MultiTablePostgresProvider.ts +2 -2
- package/src/providers/vectordb/RedisProvider.ts +0 -1
- package/src/providers/vectordb/WeaviateProvider.ts +0 -1
- package/src/rag/LlamaIndexIngestor.ts +0 -1
- package/src/server.ts +1 -0
- package/dist/index-BPJ3KDYI.d.ts +0 -195
- package/dist/index-Dmq5lH0j.d.mts +0 -195
package/dist/server.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) {
|
|
@@ -2342,13 +2339,13 @@ var LicenseValidationError = class extends RetrivoraError {
|
|
|
2342
2339
|
}
|
|
2343
2340
|
};
|
|
2344
2341
|
function wrapError(err, defaultCode, defaultMessage) {
|
|
2345
|
-
var
|
|
2342
|
+
var _a3;
|
|
2346
2343
|
if (err instanceof RetrivoraError) {
|
|
2347
2344
|
return err;
|
|
2348
2345
|
}
|
|
2349
2346
|
const error = err;
|
|
2350
2347
|
const message = (error == null ? void 0 : error.message) || defaultMessage || String(err);
|
|
2351
|
-
const status = (error == null ? void 0 : error.status) || (error == null ? void 0 : error.statusCode) || ((
|
|
2348
|
+
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);
|
|
2352
2349
|
const code = error == null ? void 0 : error.code;
|
|
2353
2350
|
if (status === 429 || /rate[- ]?limit/i.test(message) || code === "RATE_LIMIT_EXCEEDED") {
|
|
2354
2351
|
return new RateLimitException(message, err);
|
|
@@ -2630,8 +2627,8 @@ var UI_BORDER_RADIUS_OPTIONS = ["none", "sm", "md", "lg", "xl", "full"];
|
|
|
2630
2627
|
|
|
2631
2628
|
// src/config/serverConfig.ts
|
|
2632
2629
|
function readString(env, name) {
|
|
2633
|
-
var
|
|
2634
|
-
const value = (
|
|
2630
|
+
var _a3;
|
|
2631
|
+
const value = (_a3 = env[name]) == null ? void 0 : _a3.trim();
|
|
2635
2632
|
return value ? value : void 0;
|
|
2636
2633
|
}
|
|
2637
2634
|
function readNumber(env, name, fallback) {
|
|
@@ -2644,8 +2641,8 @@ function readNumber(env, name, fallback) {
|
|
|
2644
2641
|
return parsed;
|
|
2645
2642
|
}
|
|
2646
2643
|
function readEnum(env, name, fallback, allowed) {
|
|
2647
|
-
var
|
|
2648
|
-
const value = (
|
|
2644
|
+
var _a3;
|
|
2645
|
+
const value = (_a3 = readString(env, name)) != null ? _a3 : fallback;
|
|
2649
2646
|
if (allowed.includes(value)) {
|
|
2650
2647
|
return value;
|
|
2651
2648
|
}
|
|
@@ -2655,8 +2652,8 @@ function getRagConfig(baseConfig, env = process.env) {
|
|
|
2655
2652
|
return getEnvConfig(env, baseConfig);
|
|
2656
2653
|
}
|
|
2657
2654
|
function getEnvConfig(env = process.env, base) {
|
|
2658
|
-
var
|
|
2659
|
-
const licenseKey = (_d = (_c = (_b = (
|
|
2655
|
+
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;
|
|
2656
|
+
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;
|
|
2660
2657
|
const jwtProjectId = (() => {
|
|
2661
2658
|
if (!licenseKey) return void 0;
|
|
2662
2659
|
try {
|
|
@@ -2737,7 +2734,7 @@ function getEnvConfig(env = process.env, base) {
|
|
|
2737
2734
|
rest: "default",
|
|
2738
2735
|
custom: "default"
|
|
2739
2736
|
};
|
|
2740
|
-
const
|
|
2737
|
+
const isFreeTier2 = (() => {
|
|
2741
2738
|
if (!licenseKey) return true;
|
|
2742
2739
|
try {
|
|
2743
2740
|
const payload = LicenseVerifier.verify(licenseKey, projectId);
|
|
@@ -2748,13 +2745,13 @@ function getEnvConfig(env = process.env, base) {
|
|
|
2748
2745
|
}
|
|
2749
2746
|
})();
|
|
2750
2747
|
const defaultGatewayUrl = (_ra = (_qa = readString(env, "LITELLM_BASE_URL")) != null ? _qa : readString(env, "LLM_BASE_URL")) != null ? _ra : "https://www.retrivora.com/api/v1";
|
|
2751
|
-
const defaultLlmProvider =
|
|
2748
|
+
const defaultLlmProvider = isFreeTier2 ? "universal_rest" : "universal_rest";
|
|
2752
2749
|
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;
|
|
2753
2750
|
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;
|
|
2754
|
-
const llmModel = (_Ca = (_Aa = readString(env, "LLM_MODEL")) != null ? _Aa : (_za = base == null ? void 0 : base.llm) == null ? void 0 : _za.model) != null ? _Ca :
|
|
2751
|
+
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";
|
|
2755
2752
|
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;
|
|
2756
2753
|
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";
|
|
2757
|
-
const defaultEmbeddingProvider =
|
|
2754
|
+
const defaultEmbeddingProvider = isFreeTier2 ? "universal_rest" : "universal_rest";
|
|
2758
2755
|
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;
|
|
2759
2756
|
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;
|
|
2760
2757
|
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";
|
|
@@ -2844,8 +2841,8 @@ function getEnvConfig(env = process.env, base) {
|
|
|
2844
2841
|
}
|
|
2845
2842
|
} : {}), {
|
|
2846
2843
|
mcpServers: (() => {
|
|
2847
|
-
var
|
|
2848
|
-
const raw = (
|
|
2844
|
+
var _a4;
|
|
2845
|
+
const raw = (_a4 = readString(env, "MCP_SERVERS")) != null ? _a4 : readString(env, "NEXT_PUBLIC_MCP_SERVERS");
|
|
2849
2846
|
if (!raw) return void 0;
|
|
2850
2847
|
try {
|
|
2851
2848
|
return JSON.parse(raw);
|
|
@@ -2890,10 +2887,10 @@ var ConfigResolver = class {
|
|
|
2890
2887
|
* fallback behavior.
|
|
2891
2888
|
*/
|
|
2892
2889
|
static resolveUniversal(hostConfig, env = process.env) {
|
|
2893
|
-
var
|
|
2890
|
+
var _a3;
|
|
2894
2891
|
if (!hostConfig) return this.resolve(void 0, env);
|
|
2895
2892
|
const normalized = __spreadProps(__spreadValues({}, hostConfig), {
|
|
2896
|
-
vectorDb: (
|
|
2893
|
+
vectorDb: (_a3 = hostConfig.vectorDb) != null ? _a3 : hostConfig.vectorDatabase,
|
|
2897
2894
|
rag: this.mergeRetrievalWorkflow(hostConfig.rag, hostConfig.retrieval, hostConfig.workflow)
|
|
2898
2895
|
});
|
|
2899
2896
|
return this.resolve(normalized, env);
|
|
@@ -2913,11 +2910,11 @@ var ConfigResolver = class {
|
|
|
2913
2910
|
}
|
|
2914
2911
|
}
|
|
2915
2912
|
static mergeRetrievalWorkflow(rag, retrieval, workflow) {
|
|
2916
|
-
var
|
|
2913
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
2917
2914
|
if (!rag && !retrieval && !workflow) return void 0;
|
|
2918
2915
|
const normalized = __spreadValues({}, rag != null ? rag : {});
|
|
2919
2916
|
if (retrieval) {
|
|
2920
|
-
normalized.topK = (
|
|
2917
|
+
normalized.topK = (_a3 = retrieval.topK) != null ? _a3 : normalized.topK;
|
|
2921
2918
|
normalized.scoreThreshold = (_b = retrieval.scoreThreshold) != null ? _b : normalized.scoreThreshold;
|
|
2922
2919
|
normalized.useReranking = (_c = retrieval.useReranking) != null ? _c : normalized.useReranking;
|
|
2923
2920
|
if (retrieval.strategy === "hybrid") normalized.architecture = (_d = normalized.architecture) != null ? _d : "hybrid";
|
|
@@ -3045,8 +3042,8 @@ var OpenAIProvider = class {
|
|
|
3045
3042
|
};
|
|
3046
3043
|
}
|
|
3047
3044
|
async chat(messages, context, options) {
|
|
3048
|
-
var
|
|
3049
|
-
const basePrompt = (_b = (
|
|
3045
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i;
|
|
3046
|
+
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.";
|
|
3050
3047
|
const systemMessage = {
|
|
3051
3048
|
role: "system",
|
|
3052
3049
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3070,8 +3067,8 @@ var OpenAIProvider = class {
|
|
|
3070
3067
|
}
|
|
3071
3068
|
chatStream(messages, context, options) {
|
|
3072
3069
|
return __asyncGenerator(this, null, function* () {
|
|
3073
|
-
var
|
|
3074
|
-
const basePrompt = (_b = (
|
|
3070
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h;
|
|
3071
|
+
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.";
|
|
3075
3072
|
const systemMessage = {
|
|
3076
3073
|
role: "system",
|
|
3077
3074
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3118,8 +3115,8 @@ var OpenAIProvider = class {
|
|
|
3118
3115
|
return results[0];
|
|
3119
3116
|
}
|
|
3120
3117
|
async batchEmbed(texts, options) {
|
|
3121
|
-
var
|
|
3122
|
-
const model = (_c = (_b = options == null ? void 0 : options.model) != null ? _b : (
|
|
3118
|
+
var _a3, _b, _c, _d, _e;
|
|
3119
|
+
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";
|
|
3123
3120
|
const apiKey = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.apiKey) != null ? _e : this.llmConfig.apiKey;
|
|
3124
3121
|
const client = apiKey !== this.llmConfig.apiKey ? new import_openai.default({ apiKey }) : this.client;
|
|
3125
3122
|
const response = await client.embeddings.create({ model, input: texts });
|
|
@@ -3196,8 +3193,8 @@ var AnthropicProvider = class {
|
|
|
3196
3193
|
};
|
|
3197
3194
|
}
|
|
3198
3195
|
async chat(messages, context, options) {
|
|
3199
|
-
var
|
|
3200
|
-
const basePrompt = (_b = (
|
|
3196
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
|
|
3197
|
+
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.";
|
|
3201
3198
|
const system = buildSystemContent(basePrompt, context);
|
|
3202
3199
|
const anthropicMessages = messages.map((m) => ({
|
|
3203
3200
|
role: m.role === "assistant" ? "assistant" : "user",
|
|
@@ -3235,8 +3232,8 @@ var AnthropicProvider = class {
|
|
|
3235
3232
|
}
|
|
3236
3233
|
chatStream(messages, context, options) {
|
|
3237
3234
|
return __asyncGenerator(this, null, function* () {
|
|
3238
|
-
var
|
|
3239
|
-
const basePrompt = (_b = (
|
|
3235
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
|
|
3236
|
+
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.";
|
|
3240
3237
|
const system = buildSystemContent(basePrompt, context);
|
|
3241
3238
|
const anthropicMessages = messages.map((m) => ({
|
|
3242
3239
|
role: m.role === "assistant" ? "assistant" : "user",
|
|
@@ -3320,8 +3317,8 @@ var AnthropicProvider = class {
|
|
|
3320
3317
|
var import_axios = __toESM(require("axios"));
|
|
3321
3318
|
var OllamaProvider = class {
|
|
3322
3319
|
constructor(llmConfig, embeddingConfig) {
|
|
3323
|
-
var
|
|
3324
|
-
const rawBaseURL = ((
|
|
3320
|
+
var _a3, _b, _c;
|
|
3321
|
+
const rawBaseURL = ((_a3 = llmConfig.baseUrl) != null ? _a3 : "http://localhost:11434").replace(/\/+$/, "");
|
|
3325
3322
|
const baseURL = rawBaseURL.replace(/\/(?:api\/v1|v1|api)$/i, "");
|
|
3326
3323
|
const timeout = Number((_b = llmConfig.options) == null ? void 0 : _b.timeout) || 3e5;
|
|
3327
3324
|
const headers = ((_c = llmConfig.options) == null ? void 0 : _c.headers) || {};
|
|
@@ -3381,8 +3378,8 @@ var OllamaProvider = class {
|
|
|
3381
3378
|
};
|
|
3382
3379
|
}
|
|
3383
3380
|
async chat(messages, context, options) {
|
|
3384
|
-
var
|
|
3385
|
-
const basePrompt = (_b = (
|
|
3381
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
3382
|
+
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.";
|
|
3386
3383
|
const system = buildSystemContent(basePrompt, context);
|
|
3387
3384
|
const { data } = await this.http.post("/api/chat", {
|
|
3388
3385
|
model: this.llmConfig.model,
|
|
@@ -3400,8 +3397,8 @@ var OllamaProvider = class {
|
|
|
3400
3397
|
}
|
|
3401
3398
|
chatStream(messages, context, options) {
|
|
3402
3399
|
return __asyncGenerator(this, null, function* () {
|
|
3403
|
-
var
|
|
3404
|
-
const basePrompt = (_b = (
|
|
3400
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h;
|
|
3401
|
+
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.";
|
|
3405
3402
|
const system = buildSystemContent(basePrompt, context);
|
|
3406
3403
|
const response = yield new __await(this.http.post("/api/chat", {
|
|
3407
3404
|
model: this.llmConfig.model,
|
|
@@ -3459,8 +3456,8 @@ var OllamaProvider = class {
|
|
|
3459
3456
|
});
|
|
3460
3457
|
}
|
|
3461
3458
|
async embed(text, options) {
|
|
3462
|
-
var
|
|
3463
|
-
const model = (_c = (_b = options == null ? void 0 : options.model) != null ? _b : (
|
|
3459
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
|
|
3460
|
+
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";
|
|
3464
3461
|
const baseURL = (_f = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.baseUrl) != null ? _e : this.llmConfig.baseUrl) != null ? _f : "http://localhost:11434";
|
|
3465
3462
|
const client = baseURL !== ((_g2 = this.llmConfig.baseUrl) != null ? _g2 : "http://localhost:11434") ? import_axios.default.create({ baseURL, timeout: 6e4 }) : this.http;
|
|
3466
3463
|
let prompt = text;
|
|
@@ -3561,9 +3558,9 @@ var GeminiProvider = class {
|
|
|
3561
3558
|
static getHealthChecker() {
|
|
3562
3559
|
return {
|
|
3563
3560
|
async check(config) {
|
|
3564
|
-
var
|
|
3561
|
+
var _a3, _b;
|
|
3565
3562
|
const timestamp = Date.now();
|
|
3566
|
-
const apiKey = (_b = (
|
|
3563
|
+
const apiKey = (_b = (_a3 = config.apiKey) != null ? _a3 : process.env.GOOGLE_GENAI_API_KEY) != null ? _b : "";
|
|
3567
3564
|
const modelName = sanitizeModel(config.model);
|
|
3568
3565
|
try {
|
|
3569
3566
|
const { GoogleGenerativeAI: GoogleGenerativeAI2 } = await import("@google/generative-ai");
|
|
@@ -3593,16 +3590,16 @@ var GeminiProvider = class {
|
|
|
3593
3590
|
/** Resolve the embedding client — uses a separate client when the embedding
|
|
3594
3591
|
* API key differs from the LLM API key. */
|
|
3595
3592
|
get embeddingClient() {
|
|
3596
|
-
var
|
|
3597
|
-
if (((
|
|
3593
|
+
var _a3;
|
|
3594
|
+
if (((_a3 = this.embeddingConfig) == null ? void 0 : _a3.apiKey) && this.embeddingConfig.apiKey !== this.llmConfig.apiKey) {
|
|
3598
3595
|
return buildClient(this.embeddingConfig.apiKey);
|
|
3599
3596
|
}
|
|
3600
3597
|
return this.client;
|
|
3601
3598
|
}
|
|
3602
3599
|
/** Resolve the embedding model to use, in order of specificity. */
|
|
3603
3600
|
resolveEmbeddingModel(optionsModel) {
|
|
3604
|
-
var
|
|
3605
|
-
return sanitizeModel((_b = optionsModel != null ? optionsModel : (
|
|
3601
|
+
var _a3, _b;
|
|
3602
|
+
return sanitizeModel((_b = optionsModel != null ? optionsModel : (_a3 = this.embeddingConfig) == null ? void 0 : _a3.model) != null ? _b : DEFAULT_EMBEDDING_MODEL);
|
|
3606
3603
|
}
|
|
3607
3604
|
/**
|
|
3608
3605
|
* Convert ChatMessage[] to the Gemini contents format.
|
|
@@ -3622,8 +3619,8 @@ var GeminiProvider = class {
|
|
|
3622
3619
|
// ILLMProvider — chat
|
|
3623
3620
|
// -------------------------------------------------------------------------
|
|
3624
3621
|
async chat(messages, context, options) {
|
|
3625
|
-
var
|
|
3626
|
-
const basePrompt = (_b = (
|
|
3622
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
3623
|
+
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.";
|
|
3627
3624
|
const model = this.client.getGenerativeModel({
|
|
3628
3625
|
model: this.llmConfig.model,
|
|
3629
3626
|
systemInstruction: buildSystemContent(basePrompt, context)
|
|
@@ -3640,8 +3637,8 @@ var GeminiProvider = class {
|
|
|
3640
3637
|
}
|
|
3641
3638
|
chatStream(messages, context, options) {
|
|
3642
3639
|
return __asyncGenerator(this, null, function* () {
|
|
3643
|
-
var
|
|
3644
|
-
const basePrompt = (_b = (
|
|
3640
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
3641
|
+
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.";
|
|
3645
3642
|
const model = this.client.getGenerativeModel({
|
|
3646
3643
|
model: this.llmConfig.model,
|
|
3647
3644
|
systemInstruction: buildSystemContent(basePrompt, context)
|
|
@@ -3676,11 +3673,11 @@ var GeminiProvider = class {
|
|
|
3676
3673
|
// ILLMProvider — embeddings
|
|
3677
3674
|
// -------------------------------------------------------------------------
|
|
3678
3675
|
async embed(text, options) {
|
|
3679
|
-
var
|
|
3676
|
+
var _a3, _b;
|
|
3680
3677
|
const content = applyPrefix(
|
|
3681
3678
|
text,
|
|
3682
3679
|
options == null ? void 0 : options.taskType,
|
|
3683
|
-
(
|
|
3680
|
+
(_a3 = this.embeddingConfig) == null ? void 0 : _a3.queryPrefix,
|
|
3684
3681
|
(_b = this.embeddingConfig) == null ? void 0 : _b.documentPrefix
|
|
3685
3682
|
);
|
|
3686
3683
|
const modelName = this.resolveEmbeddingModel(options == null ? void 0 : options.model);
|
|
@@ -3697,7 +3694,7 @@ var GeminiProvider = class {
|
|
|
3697
3694
|
const modelName = this.resolveEmbeddingModel(options == null ? void 0 : options.model);
|
|
3698
3695
|
const model = this.embeddingClient.getGenerativeModel({ model: modelName });
|
|
3699
3696
|
const requests = texts.map((text) => {
|
|
3700
|
-
var
|
|
3697
|
+
var _a3, _b;
|
|
3701
3698
|
return {
|
|
3702
3699
|
content: {
|
|
3703
3700
|
role: "user",
|
|
@@ -3705,7 +3702,7 @@ var GeminiProvider = class {
|
|
|
3705
3702
|
text: applyPrefix(
|
|
3706
3703
|
text,
|
|
3707
3704
|
options == null ? void 0 : options.taskType,
|
|
3708
|
-
(
|
|
3705
|
+
(_a3 = this.embeddingConfig) == null ? void 0 : _a3.queryPrefix,
|
|
3709
3706
|
(_b = this.embeddingConfig) == null ? void 0 : _b.documentPrefix
|
|
3710
3707
|
)
|
|
3711
3708
|
}]
|
|
@@ -3722,8 +3719,8 @@ var GeminiProvider = class {
|
|
|
3722
3719
|
throw err;
|
|
3723
3720
|
});
|
|
3724
3721
|
return response.embeddings.map((e) => {
|
|
3725
|
-
var
|
|
3726
|
-
return (
|
|
3722
|
+
var _a3;
|
|
3723
|
+
return (_a3 = e.values) != null ? _a3 : [];
|
|
3727
3724
|
});
|
|
3728
3725
|
}
|
|
3729
3726
|
// -------------------------------------------------------------------------
|
|
@@ -3812,8 +3809,8 @@ var GroqProvider = class {
|
|
|
3812
3809
|
};
|
|
3813
3810
|
}
|
|
3814
3811
|
async chat(messages, context, options) {
|
|
3815
|
-
var
|
|
3816
|
-
const basePrompt = (_b = (
|
|
3812
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i;
|
|
3813
|
+
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.";
|
|
3817
3814
|
const systemMessage = {
|
|
3818
3815
|
role: "system",
|
|
3819
3816
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3837,8 +3834,8 @@ var GroqProvider = class {
|
|
|
3837
3834
|
}
|
|
3838
3835
|
chatStream(messages, context, options) {
|
|
3839
3836
|
return __asyncGenerator(this, null, function* () {
|
|
3840
|
-
var
|
|
3841
|
-
const basePrompt = (_b = (
|
|
3837
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h;
|
|
3838
|
+
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.";
|
|
3842
3839
|
const systemMessage = {
|
|
3843
3840
|
role: "system",
|
|
3844
3841
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3972,8 +3969,8 @@ var QwenProvider = class {
|
|
|
3972
3969
|
};
|
|
3973
3970
|
}
|
|
3974
3971
|
async chat(messages, context, options) {
|
|
3975
|
-
var
|
|
3976
|
-
const basePrompt = (_b = (
|
|
3972
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i;
|
|
3973
|
+
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.";
|
|
3977
3974
|
const systemMessage = {
|
|
3978
3975
|
role: "system",
|
|
3979
3976
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -3997,8 +3994,8 @@ var QwenProvider = class {
|
|
|
3997
3994
|
}
|
|
3998
3995
|
chatStream(messages, context, options) {
|
|
3999
3996
|
return __asyncGenerator(this, null, function* () {
|
|
4000
|
-
var
|
|
4001
|
-
const basePrompt = (_b = (
|
|
3997
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h;
|
|
3998
|
+
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.";
|
|
4002
3999
|
const systemMessage = {
|
|
4003
4000
|
role: "system",
|
|
4004
4001
|
content: buildSystemContent(basePrompt, context)
|
|
@@ -4045,8 +4042,8 @@ var QwenProvider = class {
|
|
|
4045
4042
|
return results[0];
|
|
4046
4043
|
}
|
|
4047
4044
|
async batchEmbed(texts, options) {
|
|
4048
|
-
var
|
|
4049
|
-
const model = (_c = (_b = options == null ? void 0 : options.model) != null ? _b : (
|
|
4045
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
4046
|
+
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";
|
|
4050
4047
|
const apiKey = (_e = (_d = this.embeddingConfig) == null ? void 0 : _d.apiKey) != null ? _e : this.llmConfig.apiKey;
|
|
4051
4048
|
const client = apiKey !== this.llmConfig.apiKey ? new import_openai3.default({
|
|
4052
4049
|
apiKey,
|
|
@@ -4146,9 +4143,9 @@ var VECTOR_PROFILES = {
|
|
|
4146
4143
|
|
|
4147
4144
|
// src/llm/providers/UniversalLLMAdapter.ts
|
|
4148
4145
|
function extractContent(obj) {
|
|
4149
|
-
var
|
|
4146
|
+
var _a3, _b, _c;
|
|
4150
4147
|
if (!obj || typeof obj !== "object") return void 0;
|
|
4151
|
-
const choice = (
|
|
4148
|
+
const choice = (_a3 = obj.choices) == null ? void 0 : _a3[0];
|
|
4152
4149
|
if (!choice) return void 0;
|
|
4153
4150
|
if (typeof ((_b = choice.message) == null ? void 0 : _b.content) === "string") return choice.message.content;
|
|
4154
4151
|
if (typeof ((_c = choice.delta) == null ? void 0 : _c.content) === "string") return choice.delta.content;
|
|
@@ -4158,10 +4155,10 @@ function extractContent(obj) {
|
|
|
4158
4155
|
}
|
|
4159
4156
|
var UniversalLLMAdapter = class {
|
|
4160
4157
|
constructor(config) {
|
|
4161
|
-
var
|
|
4158
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h;
|
|
4162
4159
|
this.model = config.model;
|
|
4163
4160
|
const llmConfig = config;
|
|
4164
|
-
const options = (
|
|
4161
|
+
const options = (_a3 = llmConfig.options) != null ? _a3 : {};
|
|
4165
4162
|
let profile = {};
|
|
4166
4163
|
if (typeof options.profile === "string") {
|
|
4167
4164
|
profile = LLM_PROFILES[options.profile] || {};
|
|
@@ -4187,8 +4184,8 @@ var UniversalLLMAdapter = class {
|
|
|
4187
4184
|
});
|
|
4188
4185
|
}
|
|
4189
4186
|
async chat(messages, context) {
|
|
4190
|
-
var
|
|
4191
|
-
const path2 = (
|
|
4187
|
+
var _a3, _b, _c, _d, _e;
|
|
4188
|
+
const path2 = (_a3 = this.opts.chatPath) != null ? _a3 : "/chat/completions";
|
|
4192
4189
|
const safeMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
|
|
4193
4190
|
role: m.role || "user",
|
|
4194
4191
|
content: typeof m.content === "string" ? m.content : m.content != null ? String(m.content) : ""
|
|
@@ -4254,8 +4251,8 @@ ${context != null ? context : "None"}` },
|
|
|
4254
4251
|
*/
|
|
4255
4252
|
chatStream(messages, context) {
|
|
4256
4253
|
return __asyncGenerator(this, null, function* () {
|
|
4257
|
-
var
|
|
4258
|
-
const path2 = (
|
|
4254
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
4255
|
+
const path2 = (_a3 = this.opts.chatPath) != null ? _a3 : "/chat/completions";
|
|
4259
4256
|
const url = `${this.baseUrl.replace(/\/$/, "")}${path2}`;
|
|
4260
4257
|
const extractPath = ((_b = this.opts.responseExtractPath) != null ? _b : "choices[0].message.content").replace("message.content", "delta.content");
|
|
4261
4258
|
const safeMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
|
|
@@ -4381,8 +4378,8 @@ ${context != null ? context : "None"}` },
|
|
|
4381
4378
|
});
|
|
4382
4379
|
}
|
|
4383
4380
|
async embed(text) {
|
|
4384
|
-
var
|
|
4385
|
-
const path2 = (
|
|
4381
|
+
var _a3, _b, _c, _d, _e;
|
|
4382
|
+
const path2 = (_a3 = this.opts.embedPath) != null ? _a3 : "/embeddings";
|
|
4386
4383
|
const payload = this.opts.embedPayloadTemplate ? buildPayload(this.opts.embedPayloadTemplate, { input: text, model: this.model }) : { input: text, model: this.model };
|
|
4387
4384
|
try {
|
|
4388
4385
|
const { data: data2 } = await this.http.post(path2, payload);
|
|
@@ -4471,7 +4468,7 @@ var LLMFactory = class _LLMFactory {
|
|
|
4471
4468
|
];
|
|
4472
4469
|
}
|
|
4473
4470
|
static create(llmConfig, embeddingConfig) {
|
|
4474
|
-
var
|
|
4471
|
+
var _a3, _b, _c;
|
|
4475
4472
|
switch (llmConfig.provider) {
|
|
4476
4473
|
case "openai":
|
|
4477
4474
|
return new OpenAIProvider(llmConfig, embeddingConfig);
|
|
@@ -4490,7 +4487,7 @@ var LLMFactory = class _LLMFactory {
|
|
|
4490
4487
|
case "custom":
|
|
4491
4488
|
return new UniversalLLMAdapter(llmConfig);
|
|
4492
4489
|
default: {
|
|
4493
|
-
const providerName = String((
|
|
4490
|
+
const providerName = String((_a3 = llmConfig.provider) != null ? _a3 : "").toLowerCase();
|
|
4494
4491
|
const customFactory = customProviders.get(providerName);
|
|
4495
4492
|
if (customFactory) {
|
|
4496
4493
|
return customFactory(llmConfig);
|
|
@@ -4592,7 +4589,7 @@ var ProviderRegistry = class {
|
|
|
4592
4589
|
return null;
|
|
4593
4590
|
}
|
|
4594
4591
|
static async loadVectorProviderClass(provider) {
|
|
4595
|
-
var
|
|
4592
|
+
var _a3;
|
|
4596
4593
|
if (this.vectorProviders[provider]) return this.vectorProviders[provider];
|
|
4597
4594
|
switch (provider) {
|
|
4598
4595
|
case "pinecone": {
|
|
@@ -4601,7 +4598,7 @@ var ProviderRegistry = class {
|
|
|
4601
4598
|
}
|
|
4602
4599
|
case "pgvector":
|
|
4603
4600
|
case "postgresql": {
|
|
4604
|
-
const postgresMode = ((
|
|
4601
|
+
const postgresMode = ((_a3 = process.env.POSTGRES_MODE) != null ? _a3 : "multi").toLowerCase();
|
|
4605
4602
|
if (postgresMode === "single") {
|
|
4606
4603
|
const { PostgreSQLProvider: PostgreSQLProvider2 } = await Promise.resolve().then(() => (init_PostgreSQLProvider(), PostgreSQLProvider_exports));
|
|
4607
4604
|
return PostgreSQLProvider2;
|
|
@@ -4824,7 +4821,7 @@ var ConfigValidator = class {
|
|
|
4824
4821
|
// package.json
|
|
4825
4822
|
var package_default = {
|
|
4826
4823
|
name: "@retrivora-ai/rag-engine",
|
|
4827
|
-
version: "2.3.
|
|
4824
|
+
version: "2.3.2",
|
|
4828
4825
|
description: "Retrivora AI is a plug-and-play AI engine for RAG chat experiences \u2014 generic vector DB + LLM provider, embeddable or standalone.",
|
|
4829
4826
|
author: "Abhinav Alkuchi",
|
|
4830
4827
|
license: "UNLICENSED",
|
|
@@ -4903,6 +4900,7 @@ var package_default = {
|
|
|
4903
4900
|
build: "npm run build:pkg",
|
|
4904
4901
|
"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",
|
|
4905
4902
|
lint: "eslint",
|
|
4903
|
+
typecheck: "tsc --noEmit -p tsconfig.build.json",
|
|
4906
4904
|
clean: "rm -rf dist"
|
|
4907
4905
|
},
|
|
4908
4906
|
peerDependencies: {
|
|
@@ -5129,8 +5127,8 @@ var Reranker = class {
|
|
|
5129
5127
|
return matches.sort((a, b) => b.score - a.score).slice(0, limit);
|
|
5130
5128
|
}
|
|
5131
5129
|
const scoredMatches = matches.map((match) => {
|
|
5132
|
-
var
|
|
5133
|
-
const contentLower = ((
|
|
5130
|
+
var _a3;
|
|
5131
|
+
const contentLower = ((_a3 = match == null ? void 0 : match.content) != null ? _a3 : "").toLowerCase();
|
|
5134
5132
|
let keywordScore = 0;
|
|
5135
5133
|
keywords.forEach((keyword) => {
|
|
5136
5134
|
if (contentLower.includes(keyword)) {
|
|
@@ -5152,8 +5150,8 @@ var Reranker = class {
|
|
|
5152
5150
|
|
|
5153
5151
|
Documents:
|
|
5154
5152
|
${topN.map((m, i) => {
|
|
5155
|
-
var
|
|
5156
|
-
return `[${i}] ${((
|
|
5153
|
+
var _a3;
|
|
5154
|
+
return `[${i}] ${((_a3 = m == null ? void 0 : m.content) != null ? _a3 : "").replace(/\n/g, " ")}`;
|
|
5157
5155
|
}).join("\n")}` }],
|
|
5158
5156
|
"",
|
|
5159
5157
|
{
|
|
@@ -5197,11 +5195,11 @@ var LlamaIndexIngestor = class {
|
|
|
5197
5195
|
* than standard character-count splitting.
|
|
5198
5196
|
*/
|
|
5199
5197
|
async chunk(text, options = {}) {
|
|
5200
|
-
var
|
|
5198
|
+
var _a3, _b;
|
|
5201
5199
|
try {
|
|
5202
5200
|
const { Document, SentenceSplitter, MetadataMode } = await import(`${"llamaindex"}`);
|
|
5203
5201
|
const splitter = new SentenceSplitter({
|
|
5204
|
-
chunkSize: (
|
|
5202
|
+
chunkSize: (_a3 = options.chunkSize) != null ? _a3 : 1e3,
|
|
5205
5203
|
chunkOverlap: (_b = options.chunkOverlap) != null ? _b : 200
|
|
5206
5204
|
});
|
|
5207
5205
|
const doc = new Document({ text, metadata: options.metadata || {} });
|
|
@@ -5289,7 +5287,6 @@ When presenting structured data, statistics, or comparisons, decide if it is bes
|
|
|
5289
5287
|
finalSystemPrompt += chartInstruction;
|
|
5290
5288
|
}
|
|
5291
5289
|
this.agent = createAgent({
|
|
5292
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5293
5290
|
model: chatModel,
|
|
5294
5291
|
tools: [searchTool],
|
|
5295
5292
|
systemPrompt: finalSystemPrompt
|
|
@@ -5310,7 +5307,7 @@ ${error instanceof Error ? error.message : String(error)}`
|
|
|
5310
5307
|
* The agent returns `{ messages: [...] }` — the last message is the final answer.
|
|
5311
5308
|
*/
|
|
5312
5309
|
async run(input, chatHistory = []) {
|
|
5313
|
-
var
|
|
5310
|
+
var _a3, _b, _c;
|
|
5314
5311
|
if (!this.agent) {
|
|
5315
5312
|
throw new Error("[LangChainAgent] Agent not initialized. Call initialize() first.");
|
|
5316
5313
|
}
|
|
@@ -5321,7 +5318,7 @@ ${error instanceof Error ? error.message : String(error)}`
|
|
|
5321
5318
|
const response = await this.agent.invoke({
|
|
5322
5319
|
messages: [...historyMessages, new HumanMessage(input)]
|
|
5323
5320
|
});
|
|
5324
|
-
const lastMessage = (
|
|
5321
|
+
const lastMessage = (_a3 = response == null ? void 0 : response.messages) == null ? void 0 : _a3.at(-1);
|
|
5325
5322
|
if (lastMessage && typeof lastMessage.content === "string") {
|
|
5326
5323
|
return lastMessage.content;
|
|
5327
5324
|
}
|
|
@@ -5373,7 +5370,7 @@ var MCPClient = class {
|
|
|
5373
5370
|
}
|
|
5374
5371
|
}
|
|
5375
5372
|
async connectStdio() {
|
|
5376
|
-
var
|
|
5373
|
+
var _a3;
|
|
5377
5374
|
const cmd = this.config.command;
|
|
5378
5375
|
if (!cmd) {
|
|
5379
5376
|
throw new Error(`[MCPClient] Command option is required for stdio transport on "${this.config.name}"`);
|
|
@@ -5388,7 +5385,7 @@ var MCPClient = class {
|
|
|
5388
5385
|
this.stdioBuffer += data.toString("utf-8");
|
|
5389
5386
|
this.processStdioLines();
|
|
5390
5387
|
});
|
|
5391
|
-
(
|
|
5388
|
+
(_a3 = this.childProcess.stderr) == null ? void 0 : _a3.on("data", (data) => {
|
|
5392
5389
|
console.warn(`[MCPClient] [stderr] [${this.config.name}]:`, data.toString("utf-8"));
|
|
5393
5390
|
});
|
|
5394
5391
|
this.childProcess.on("close", (code) => {
|
|
@@ -5463,14 +5460,14 @@ var MCPClient = class {
|
|
|
5463
5460
|
}
|
|
5464
5461
|
}
|
|
5465
5462
|
async sendNotification(method, params) {
|
|
5466
|
-
var
|
|
5463
|
+
var _a3;
|
|
5467
5464
|
const notification = {
|
|
5468
5465
|
jsonrpc: "2.0",
|
|
5469
5466
|
method,
|
|
5470
5467
|
params
|
|
5471
5468
|
};
|
|
5472
5469
|
if (this.config.transport === "stdio") {
|
|
5473
|
-
if ((
|
|
5470
|
+
if ((_a3 = this.childProcess) == null ? void 0 : _a3.stdin) {
|
|
5474
5471
|
this.childProcess.stdin.write(JSON.stringify(notification) + "\n", "utf-8");
|
|
5475
5472
|
}
|
|
5476
5473
|
} else if (this.sseUrl) {
|
|
@@ -5548,11 +5545,11 @@ var MCPRegistry = class {
|
|
|
5548
5545
|
// src/core/MultiAgentCoordinator.ts
|
|
5549
5546
|
var MultiAgentCoordinator = class {
|
|
5550
5547
|
constructor(options) {
|
|
5551
|
-
var
|
|
5548
|
+
var _a3;
|
|
5552
5549
|
this.llmProvider = options.llmProvider;
|
|
5553
5550
|
this.mcpRegistry = options.mcpRegistry;
|
|
5554
5551
|
this.documentSearch = options.documentSearch;
|
|
5555
|
-
this.maxIterations = (
|
|
5552
|
+
this.maxIterations = (_a3 = options.maxIterations) != null ? _a3 : 5;
|
|
5556
5553
|
}
|
|
5557
5554
|
/**
|
|
5558
5555
|
* Run the multi-agent coordination loop synchronously and return the final response.
|
|
@@ -5604,8 +5601,8 @@ Available Tools:
|
|
|
5604
5601
|
|
|
5605
5602
|
${mcpTools.length > 0 ? "MCP Server Tools:" : ""}
|
|
5606
5603
|
${mcpTools.map((mt) => {
|
|
5607
|
-
var
|
|
5608
|
-
return `- ${mt.tool.name}(${JSON.stringify(((
|
|
5604
|
+
var _a3;
|
|
5605
|
+
return `- ${mt.tool.name}(${JSON.stringify(((_a3 = mt.tool.inputSchema) == null ? void 0 : _a3.properties) || {})}): ${mt.tool.description || "No description provided."}`;
|
|
5609
5606
|
}).join("\n")}
|
|
5610
5607
|
|
|
5611
5608
|
Tool Calling Protocol:
|
|
@@ -5763,6 +5760,100 @@ ${toolResultText}`
|
|
|
5763
5760
|
}
|
|
5764
5761
|
};
|
|
5765
5762
|
|
|
5763
|
+
// src/core/CircuitBreaker.ts
|
|
5764
|
+
var CircuitBreaker = class {
|
|
5765
|
+
constructor(options = {}) {
|
|
5766
|
+
this.state = "closed";
|
|
5767
|
+
this.failureCount = 0;
|
|
5768
|
+
this.successCount = 0;
|
|
5769
|
+
this.lastFailureAt = 0;
|
|
5770
|
+
this.halfOpenCalls = 0;
|
|
5771
|
+
var _a3, _b, _c;
|
|
5772
|
+
this.failureThreshold = (_a3 = options.failureThreshold) != null ? _a3 : 5;
|
|
5773
|
+
this.resetTimeoutMs = (_b = options.resetTimeoutMs) != null ? _b : 3e4;
|
|
5774
|
+
this.halfOpenMaxCalls = (_c = options.halfOpenMaxCalls) != null ? _c : 1;
|
|
5775
|
+
}
|
|
5776
|
+
record(success) {
|
|
5777
|
+
const now = Date.now();
|
|
5778
|
+
if (success) {
|
|
5779
|
+
this.successCount++;
|
|
5780
|
+
if (this.state === "half-open") {
|
|
5781
|
+
this.state = "closed";
|
|
5782
|
+
this.failureCount = 0;
|
|
5783
|
+
this.halfOpenCalls = 0;
|
|
5784
|
+
this.successCount = 1;
|
|
5785
|
+
} else if (this.state === "closed") {
|
|
5786
|
+
if (this.successCount >= this.failureThreshold) {
|
|
5787
|
+
this.failureCount = Math.max(0, this.failureCount - 1);
|
|
5788
|
+
this.successCount = 0;
|
|
5789
|
+
}
|
|
5790
|
+
}
|
|
5791
|
+
} else {
|
|
5792
|
+
this.failureCount++;
|
|
5793
|
+
this.lastFailureAt = now;
|
|
5794
|
+
this.successCount = 0;
|
|
5795
|
+
if (this.state === "half-open") {
|
|
5796
|
+
this.state = "open";
|
|
5797
|
+
this.halfOpenCalls = 0;
|
|
5798
|
+
} else if (this.state === "closed" && this.failureCount >= this.failureThreshold) {
|
|
5799
|
+
this.state = "open";
|
|
5800
|
+
}
|
|
5801
|
+
}
|
|
5802
|
+
}
|
|
5803
|
+
canExecute() {
|
|
5804
|
+
const now = Date.now();
|
|
5805
|
+
if (this.state === "closed") {
|
|
5806
|
+
return true;
|
|
5807
|
+
}
|
|
5808
|
+
if (this.state === "open") {
|
|
5809
|
+
if (now - this.lastFailureAt >= this.resetTimeoutMs) {
|
|
5810
|
+
this.state = "half-open";
|
|
5811
|
+
this.halfOpenCalls = 0;
|
|
5812
|
+
return true;
|
|
5813
|
+
}
|
|
5814
|
+
return false;
|
|
5815
|
+
}
|
|
5816
|
+
if (this.state === "half-open") {
|
|
5817
|
+
return this.halfOpenCalls < this.halfOpenMaxCalls;
|
|
5818
|
+
}
|
|
5819
|
+
return true;
|
|
5820
|
+
}
|
|
5821
|
+
async wrap(fn) {
|
|
5822
|
+
if (!this.canExecute()) {
|
|
5823
|
+
const retryAfterSec = Math.ceil(
|
|
5824
|
+
Math.max(0, this.resetTimeoutMs - (Date.now() - this.lastFailureAt)) / 1e3
|
|
5825
|
+
);
|
|
5826
|
+
throw new Error(
|
|
5827
|
+
`Circuit breaker is open. Try again in ${retryAfterSec}s. Failed ${this.failureCount}/${this.failureThreshold} consecutive calls.`
|
|
5828
|
+
);
|
|
5829
|
+
}
|
|
5830
|
+
if (this.state === "half-open") {
|
|
5831
|
+
this.halfOpenCalls++;
|
|
5832
|
+
}
|
|
5833
|
+
try {
|
|
5834
|
+
const result = await fn();
|
|
5835
|
+
this.record(true);
|
|
5836
|
+
return result;
|
|
5837
|
+
} catch (err) {
|
|
5838
|
+
this.record(false);
|
|
5839
|
+
throw err;
|
|
5840
|
+
}
|
|
5841
|
+
}
|
|
5842
|
+
getState() {
|
|
5843
|
+
return this.state;
|
|
5844
|
+
}
|
|
5845
|
+
getFailureCount() {
|
|
5846
|
+
return this.failureCount;
|
|
5847
|
+
}
|
|
5848
|
+
reset() {
|
|
5849
|
+
this.state = "closed";
|
|
5850
|
+
this.failureCount = 0;
|
|
5851
|
+
this.successCount = 0;
|
|
5852
|
+
this.lastFailureAt = 0;
|
|
5853
|
+
this.halfOpenCalls = 0;
|
|
5854
|
+
}
|
|
5855
|
+
};
|
|
5856
|
+
|
|
5766
5857
|
// src/core/BatchProcessor.ts
|
|
5767
5858
|
function isTransientError(error) {
|
|
5768
5859
|
if (!(error instanceof Error)) return false;
|
|
@@ -5786,7 +5877,34 @@ function calculateBackoffDelay(attempt, initialDelayMs, maxDelayMs, multiplier)
|
|
|
5786
5877
|
function sleep(ms) {
|
|
5787
5878
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
5788
5879
|
}
|
|
5789
|
-
var
|
|
5880
|
+
var _BatchProcessor = class _BatchProcessor {
|
|
5881
|
+
/**
|
|
5882
|
+
* Execute a processor call through the circuit breaker.
|
|
5883
|
+
* Only transient failures count toward opening the circuit.
|
|
5884
|
+
*/
|
|
5885
|
+
static async executeWithCircuitBreaker(processor) {
|
|
5886
|
+
if (!this.cb.canExecute()) {
|
|
5887
|
+
const retryAfterSec = Math.ceil(
|
|
5888
|
+
Math.max(0, 3e4 - (Date.now() - this.cb.lastFailureAt || 0)) / 1e3
|
|
5889
|
+
);
|
|
5890
|
+
throw new Error(
|
|
5891
|
+
`[BatchProcessor] Circuit breaker is open. Try again in ${retryAfterSec}s.`
|
|
5892
|
+
);
|
|
5893
|
+
}
|
|
5894
|
+
if (this.cb.state === "half-open") {
|
|
5895
|
+
this.cb.halfOpenCalls++;
|
|
5896
|
+
}
|
|
5897
|
+
try {
|
|
5898
|
+
const result = await processor();
|
|
5899
|
+
this.cb.record(true);
|
|
5900
|
+
return result;
|
|
5901
|
+
} catch (err) {
|
|
5902
|
+
if (isTransientError(err)) {
|
|
5903
|
+
this.cb.record(false);
|
|
5904
|
+
}
|
|
5905
|
+
throw err;
|
|
5906
|
+
}
|
|
5907
|
+
}
|
|
5790
5908
|
/**
|
|
5791
5909
|
* Processes an array of items in configurable batches with retry logic.
|
|
5792
5910
|
*
|
|
@@ -5827,7 +5945,7 @@ var BatchProcessor = class {
|
|
|
5827
5945
|
let lastError;
|
|
5828
5946
|
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
5829
5947
|
try {
|
|
5830
|
-
const result = await processor(batch);
|
|
5948
|
+
const result = await _BatchProcessor.executeWithCircuitBreaker(() => processor(batch));
|
|
5831
5949
|
results.push(result);
|
|
5832
5950
|
success = true;
|
|
5833
5951
|
break;
|
|
@@ -5885,7 +6003,7 @@ ${errorMessages}`
|
|
|
5885
6003
|
let lastError;
|
|
5886
6004
|
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
5887
6005
|
try {
|
|
5888
|
-
const result = await processor(item);
|
|
6006
|
+
const result = await _BatchProcessor.executeWithCircuitBreaker(() => processor(item));
|
|
5889
6007
|
results.push(result);
|
|
5890
6008
|
success = true;
|
|
5891
6009
|
break;
|
|
@@ -5958,7 +6076,7 @@ ${errorMessages}`
|
|
|
5958
6076
|
}));
|
|
5959
6077
|
const chunkPromises = chunk.map(async ({ item, originalIndex }) => {
|
|
5960
6078
|
try {
|
|
5961
|
-
const result = await processor(item);
|
|
6079
|
+
const result = await _BatchProcessor.executeWithCircuitBreaker(() => processor(item));
|
|
5962
6080
|
return { success: true, result, index: originalIndex };
|
|
5963
6081
|
} catch (err) {
|
|
5964
6082
|
const error = err instanceof Error ? err : new Error(String(err));
|
|
@@ -5986,6 +6104,12 @@ ${errorMessages}`
|
|
|
5986
6104
|
return { results, errors, totalProcessed, totalFailed };
|
|
5987
6105
|
}
|
|
5988
6106
|
};
|
|
6107
|
+
_BatchProcessor.cb = new CircuitBreaker({
|
|
6108
|
+
failureThreshold: 5,
|
|
6109
|
+
resetTimeoutMs: 3e4,
|
|
6110
|
+
halfOpenMaxCalls: 1
|
|
6111
|
+
});
|
|
6112
|
+
var BatchProcessor = _BatchProcessor;
|
|
5989
6113
|
|
|
5990
6114
|
// src/config/EmbeddingStrategy.ts
|
|
5991
6115
|
var EmbeddingStrategy = /* @__PURE__ */ ((EmbeddingStrategy2) => {
|
|
@@ -6089,7 +6213,7 @@ var QueryProcessor = class {
|
|
|
6089
6213
|
* @param validFields Optional list of known filterable fields to look for
|
|
6090
6214
|
*/
|
|
6091
6215
|
static extractQueryFieldHints(question, validFields = []) {
|
|
6092
|
-
var
|
|
6216
|
+
var _a3, _b, _c, _d;
|
|
6093
6217
|
if (!question.trim()) return [];
|
|
6094
6218
|
const hints = /* @__PURE__ */ new Map();
|
|
6095
6219
|
const addHint = (value, field) => {
|
|
@@ -6169,7 +6293,7 @@ var QueryProcessor = class {
|
|
|
6169
6293
|
];
|
|
6170
6294
|
for (const p of universalPatterns) {
|
|
6171
6295
|
for (const match of question.matchAll(p.regex)) {
|
|
6172
|
-
const val = p.group ? (
|
|
6296
|
+
const val = p.group ? (_a3 = match[p.group]) != null ? _a3 : match[0] : match[0];
|
|
6173
6297
|
if (!val) continue;
|
|
6174
6298
|
if (p.field) addHint(val, p.field);
|
|
6175
6299
|
else addHint(val);
|
|
@@ -6393,11 +6517,11 @@ var LLMRouter = class {
|
|
|
6393
6517
|
* When provided it is used directly as the 'default' role without re-constructing.
|
|
6394
6518
|
*/
|
|
6395
6519
|
async initialize(prebuiltDefault) {
|
|
6396
|
-
var
|
|
6520
|
+
var _a3;
|
|
6397
6521
|
const defaultModel = prebuiltDefault != null ? prebuiltDefault : LLMFactory.create(this.config.llm, this.config.embedding);
|
|
6398
6522
|
this.models.set("default", defaultModel);
|
|
6399
6523
|
const envFastModel = process.env.FAST_LLM_MODEL;
|
|
6400
|
-
const providerFastDefault = (
|
|
6524
|
+
const providerFastDefault = (_a3 = FAST_MODEL_DEFAULTS[this.config.llm.provider]) != null ? _a3 : "";
|
|
6401
6525
|
const fastModelName = envFastModel || providerFastDefault;
|
|
6402
6526
|
if (fastModelName && fastModelName !== this.config.llm.model) {
|
|
6403
6527
|
console.log(`[LLMRouter] Fast role \u2192 provider="${this.config.llm.provider}" model="${fastModelName}"`);
|
|
@@ -6416,8 +6540,8 @@ var LLMRouter = class {
|
|
|
6416
6540
|
* Falls back to 'default' if the requested role is not registered.
|
|
6417
6541
|
*/
|
|
6418
6542
|
get(role) {
|
|
6419
|
-
var
|
|
6420
|
-
const provider = (
|
|
6543
|
+
var _a3;
|
|
6544
|
+
const provider = (_a3 = this.models.get(role)) != null ? _a3 : this.models.get("default");
|
|
6421
6545
|
if (!provider) {
|
|
6422
6546
|
throw new Error(`[LLMRouter] No provider registered for role: "${role}". Did you call initialize()?`);
|
|
6423
6547
|
}
|
|
@@ -6503,8 +6627,8 @@ var IntentClassifier = class {
|
|
|
6503
6627
|
numericFieldCount = numericKeys.size;
|
|
6504
6628
|
categoricalFieldCount = catKeys.size;
|
|
6505
6629
|
if (productKeyMatches >= 2 || docs.some((d) => {
|
|
6506
|
-
var
|
|
6507
|
-
return ((
|
|
6630
|
+
var _a3, _b;
|
|
6631
|
+
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");
|
|
6508
6632
|
})) {
|
|
6509
6633
|
isProductLike = true;
|
|
6510
6634
|
}
|
|
@@ -6786,8 +6910,8 @@ var TextRendererStrategy = class {
|
|
|
6786
6910
|
}
|
|
6787
6911
|
const docs = Array.isArray(data) ? data : [];
|
|
6788
6912
|
const text = docs.map((d) => {
|
|
6789
|
-
var
|
|
6790
|
-
return (
|
|
6913
|
+
var _a3;
|
|
6914
|
+
return (_a3 = d == null ? void 0 : d.content) != null ? _a3 : "";
|
|
6791
6915
|
}).join("\n\n");
|
|
6792
6916
|
return { type: "text", title, data: { content: text || "No detailed content available." } };
|
|
6793
6917
|
}
|
|
@@ -6930,9 +7054,9 @@ var LRUDecisionCache = class {
|
|
|
6930
7054
|
this.maxSize = maxSize;
|
|
6931
7055
|
}
|
|
6932
7056
|
generateKey(context) {
|
|
6933
|
-
var
|
|
7057
|
+
var _a3, _b;
|
|
6934
7058
|
const q = (context.userQuery || "").toLowerCase().trim();
|
|
6935
|
-
const docCount = (_b = (
|
|
7059
|
+
const docCount = (_b = (_a3 = context.retrievedDocuments) == null ? void 0 : _a3.length) != null ? _b : 0;
|
|
6936
7060
|
return `${q}::docs:${docCount}`;
|
|
6937
7061
|
}
|
|
6938
7062
|
get(context) {
|
|
@@ -7041,7 +7165,7 @@ var UITransformer = class _UITransformer {
|
|
|
7041
7165
|
* Prefer `analyzeAndDecide()` in production.
|
|
7042
7166
|
*/
|
|
7043
7167
|
static transform(userQuery, retrievedData, config, trainedSchema, intent) {
|
|
7044
|
-
var
|
|
7168
|
+
var _a3, _b, _c;
|
|
7045
7169
|
if (!retrievedData || retrievedData.length === 0) {
|
|
7046
7170
|
return this.createTextResponse("No data available", "No relevant data found for your query.");
|
|
7047
7171
|
}
|
|
@@ -7061,7 +7185,7 @@ var UITransformer = class _UITransformer {
|
|
|
7061
7185
|
return this.transformToBarChart(filteredData, profile, userQuery, resolvedIntent.visualizationHint === "ranking");
|
|
7062
7186
|
}
|
|
7063
7187
|
if (resolvedIntent.visualizationHint === "distribution") {
|
|
7064
|
-
return (
|
|
7188
|
+
return (_a3 = this.transformToHistogram(profile, userQuery)) != null ? _a3 : this.transformToBarChart(filteredData, profile, userQuery);
|
|
7065
7189
|
}
|
|
7066
7190
|
if (resolvedIntent.visualizationHint === "correlation") {
|
|
7067
7191
|
return (_b = this.transformToScatterPlot(profile, userQuery)) != null ? _b : this.transformToBarChart(filteredData, profile, userQuery);
|
|
@@ -7394,11 +7518,11 @@ ${schemaProfileText}` : ""}`;
|
|
|
7394
7518
|
};
|
|
7395
7519
|
}
|
|
7396
7520
|
static transformToPieChart(data, profile, query = "") {
|
|
7397
|
-
var
|
|
7521
|
+
var _a3;
|
|
7398
7522
|
const dimension = profile ? this.selectDimensionField(profile, query) : void 0;
|
|
7399
7523
|
const categories = dimension ? Array.from(new Set(profile.records.map((record) => {
|
|
7400
|
-
var
|
|
7401
|
-
return String((
|
|
7524
|
+
var _a4;
|
|
7525
|
+
return String((_a4 = record.fields[dimension.key]) != null ? _a4 : "");
|
|
7402
7526
|
}).filter(Boolean))) : this.detectCategories(data);
|
|
7403
7527
|
if (categories.length === 0) return null;
|
|
7404
7528
|
const categoryData = dimension && profile ? this.aggregateProfileByDimension(profile, dimension.key) : this.aggregateByCategory(data, categories);
|
|
@@ -7408,7 +7532,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7408
7532
|
});
|
|
7409
7533
|
return {
|
|
7410
7534
|
type: "pie_chart",
|
|
7411
|
-
title: `Distribution by ${(
|
|
7535
|
+
title: `Distribution by ${(_a3 = dimension == null ? void 0 : dimension.label) != null ? _a3 : "Category"}`,
|
|
7412
7536
|
description: `Showing breakdown across ${pieData.length} categories`,
|
|
7413
7537
|
data: pieData
|
|
7414
7538
|
};
|
|
@@ -7418,8 +7542,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7418
7542
|
const valueField = profile.numericFields[0];
|
|
7419
7543
|
const buckets = /* @__PURE__ */ new Map();
|
|
7420
7544
|
profile.records.forEach((record) => {
|
|
7421
|
-
var
|
|
7422
|
-
const timestamp = String((
|
|
7545
|
+
var _a3, _b, _c;
|
|
7546
|
+
const timestamp = String((_a3 = record.fields[dateField.key]) != null ? _a3 : "");
|
|
7423
7547
|
const value = (_b = this.toFiniteNumber(record.fields[valueField.key])) != null ? _b : 0;
|
|
7424
7548
|
buckets.set(timestamp, ((_c = buckets.get(timestamp)) != null ? _c : 0) + value);
|
|
7425
7549
|
});
|
|
@@ -7432,23 +7556,23 @@ ${schemaProfileText}` : ""}`;
|
|
|
7432
7556
|
};
|
|
7433
7557
|
}
|
|
7434
7558
|
static transformToBarChart(data, profile, query = "", horizontal = false) {
|
|
7435
|
-
var
|
|
7559
|
+
var _a3;
|
|
7436
7560
|
const dimension = profile ? this.selectDimensionField(profile, query) : void 0;
|
|
7437
7561
|
const measure = profile ? this.selectNumericField(profile, query) : void 0;
|
|
7438
7562
|
const aggregate = dimension && profile ? this.aggregateProfileByDimension(profile, dimension.key, measure == null ? void 0 : measure.key) : this.aggregateByCategory(data, this.detectCategories(data));
|
|
7439
7563
|
const barData = Object.entries(aggregate).map(([category, value]) => ({ category, value: Number(value) })).sort((a, b) => horizontal ? b.value - a.value : 0).slice(0, 12);
|
|
7440
7564
|
const fallbackData = barData.length > 0 ? barData : data.slice(0, 12).map((item, index) => {
|
|
7441
|
-
var
|
|
7565
|
+
var _a4, _b, _c, _d, _e;
|
|
7442
7566
|
const meta = item.metadata || {};
|
|
7443
7567
|
const label = String(
|
|
7444
|
-
(_c = (_b = (
|
|
7568
|
+
(_c = (_b = (_a4 = this.getDynamicVal(meta, "name")) != null ? _a4 : meta.label) != null ? _b : meta.title) != null ? _c : `Result ${index + 1}`
|
|
7445
7569
|
);
|
|
7446
7570
|
const value = (_e = (_d = this.extractNumericValue(meta)) != null ? _d : item.score) != null ? _e : 0;
|
|
7447
7571
|
return { category: label, value: Number(value) };
|
|
7448
7572
|
});
|
|
7449
7573
|
return {
|
|
7450
7574
|
type: horizontal ? "horizontal_bar" : "bar_chart",
|
|
7451
|
-
title: dimension ? `${(
|
|
7575
|
+
title: dimension ? `${(_a3 = measure == null ? void 0 : measure.label) != null ? _a3 : "Count"} by ${dimension.label}` : "Comparison",
|
|
7452
7576
|
description: `Showing ${fallbackData.length} comparable values`,
|
|
7453
7577
|
data: fallbackData
|
|
7454
7578
|
};
|
|
@@ -7483,11 +7607,11 @@ ${schemaProfileText}` : ""}`;
|
|
|
7483
7607
|
if (fields.length < 2) return null;
|
|
7484
7608
|
const [xField, yField] = fields;
|
|
7485
7609
|
const points = profile.records.map((record) => {
|
|
7486
|
-
var
|
|
7610
|
+
var _a3;
|
|
7487
7611
|
const x = this.toFiniteNumber(record.fields[xField.key]);
|
|
7488
7612
|
const y = this.toFiniteNumber(record.fields[yField.key]);
|
|
7489
7613
|
if (x === null || y === null) return null;
|
|
7490
|
-
return { x, y, label: String((
|
|
7614
|
+
return { x, y, label: String((_a3 = this.getRecordLabel(record)) != null ? _a3 : record.id) };
|
|
7491
7615
|
}).filter((point) => point !== null).slice(0, 100);
|
|
7492
7616
|
if (points.length === 0) return null;
|
|
7493
7617
|
return {
|
|
@@ -7517,9 +7641,9 @@ ${schemaProfileText}` : ""}`;
|
|
|
7517
7641
|
static transformToRadarChart(data) {
|
|
7518
7642
|
const attributeMap = {};
|
|
7519
7643
|
data.forEach((item) => {
|
|
7520
|
-
var
|
|
7644
|
+
var _a3, _b, _c;
|
|
7521
7645
|
const meta = item.metadata || {};
|
|
7522
|
-
const seriesName = String((_c = (_b = (
|
|
7646
|
+
const seriesName = String((_c = (_b = (_a3 = meta.name) != null ? _a3 : meta.product) != null ? _b : item.id) != null ? _c : "Item");
|
|
7523
7647
|
Object.entries(meta).forEach(([key, val]) => {
|
|
7524
7648
|
if (typeof val === "number" && !["price", "id"].includes(key.toLowerCase())) {
|
|
7525
7649
|
if (!attributeMap[key]) attributeMap[key] = {};
|
|
@@ -7535,8 +7659,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7535
7659
|
title: "Product Comparison",
|
|
7536
7660
|
description: `Comparing ${data.length} items across ${radarData.length} attributes`,
|
|
7537
7661
|
data: radarData.length > 0 ? radarData : data.map((d) => {
|
|
7538
|
-
var
|
|
7539
|
-
return { attribute: ((
|
|
7662
|
+
var _a3;
|
|
7663
|
+
return { attribute: ((_a3 = d == null ? void 0 : d.content) != null ? _a3 : "").substring(0, 40) };
|
|
7540
7664
|
})
|
|
7541
7665
|
};
|
|
7542
7666
|
}
|
|
@@ -7555,8 +7679,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7555
7679
|
return this.createTextResponse(
|
|
7556
7680
|
"Retrieved Context",
|
|
7557
7681
|
data.map((item) => {
|
|
7558
|
-
var
|
|
7559
|
-
return (
|
|
7682
|
+
var _a3;
|
|
7683
|
+
return (_a3 = item == null ? void 0 : item.content) != null ? _a3 : "";
|
|
7560
7684
|
}).join("\n\n"),
|
|
7561
7685
|
`Found ${data.length} relevant results`
|
|
7562
7686
|
);
|
|
@@ -7607,11 +7731,11 @@ ${schemaProfileText}` : ""}`;
|
|
|
7607
7731
|
return null;
|
|
7608
7732
|
}
|
|
7609
7733
|
static normalizeTransformation(payload) {
|
|
7610
|
-
var
|
|
7734
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j;
|
|
7611
7735
|
if (!payload || typeof payload !== "object") return null;
|
|
7612
7736
|
const p = payload;
|
|
7613
7737
|
const type = this.normalizeVisualizationType(
|
|
7614
|
-
String((_c = (_b = (
|
|
7738
|
+
String((_c = (_b = (_a3 = p.type) != null ? _a3 : p.view) != null ? _b : p.chartType) != null ? _c : "")
|
|
7615
7739
|
);
|
|
7616
7740
|
if (!type) return null;
|
|
7617
7741
|
const title = String((_e = (_d = p.title) != null ? _d : p.heading) != null ? _e : "Visualization");
|
|
@@ -7622,7 +7746,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7622
7746
|
return this.validateTransformation(transformation) ? transformation : null;
|
|
7623
7747
|
}
|
|
7624
7748
|
static normalizeVisualizationType(type) {
|
|
7625
|
-
var
|
|
7749
|
+
var _a3;
|
|
7626
7750
|
const mapping = {
|
|
7627
7751
|
pie: "pie_chart",
|
|
7628
7752
|
pie_chart: "pie_chart",
|
|
@@ -7650,7 +7774,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7650
7774
|
product_carousel: "product_carousel",
|
|
7651
7775
|
carousel: "carousel"
|
|
7652
7776
|
};
|
|
7653
|
-
return (
|
|
7777
|
+
return (_a3 = mapping[type.toLowerCase()]) != null ? _a3 : null;
|
|
7654
7778
|
}
|
|
7655
7779
|
static validateTransformation(t) {
|
|
7656
7780
|
const { type, data } = t;
|
|
@@ -7766,7 +7890,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7766
7890
|
}
|
|
7767
7891
|
static profileData(data) {
|
|
7768
7892
|
const records = (data || []).filter((item) => Boolean(item && typeof item === "object")).map((item) => {
|
|
7769
|
-
var
|
|
7893
|
+
var _a3, _b;
|
|
7770
7894
|
const fields2 = {};
|
|
7771
7895
|
Object.entries(item.metadata || {}).forEach(([key, value]) => {
|
|
7772
7896
|
const primitive = this.toPrimitive(value);
|
|
@@ -7775,7 +7899,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7775
7899
|
if (!fields2.content && item.content) fields2.content = item.content.substring(0, 500);
|
|
7776
7900
|
return {
|
|
7777
7901
|
id: item.id,
|
|
7778
|
-
content: (
|
|
7902
|
+
content: (_a3 = item.content) != null ? _a3 : "",
|
|
7779
7903
|
score: (_b = item.score) != null ? _b : 0,
|
|
7780
7904
|
fields: fields2,
|
|
7781
7905
|
source: item
|
|
@@ -7856,16 +7980,16 @@ ${schemaProfileText}` : ""}`;
|
|
|
7856
7980
|
return null;
|
|
7857
7981
|
}
|
|
7858
7982
|
static selectDimensionField(profile, query) {
|
|
7859
|
-
var
|
|
7983
|
+
var _a3, _b;
|
|
7860
7984
|
const productCategory = profile.categoricalFields.find(
|
|
7861
7985
|
(field) => /category|department|collection|type|group|segment|region|country|state|city/i.test(field.key)
|
|
7862
7986
|
);
|
|
7863
7987
|
const ranked = this.rankFieldsByQuery(profile.categoricalFields, query);
|
|
7864
|
-
return (_b = (
|
|
7988
|
+
return (_b = (_a3 = ranked[0]) != null ? _a3 : productCategory) != null ? _b : profile.categoricalFields[0];
|
|
7865
7989
|
}
|
|
7866
7990
|
static selectNumericField(profile, query) {
|
|
7867
|
-
var
|
|
7868
|
-
return (
|
|
7991
|
+
var _a3;
|
|
7992
|
+
return (_a3 = this.rankFieldsByQuery(profile.numericFields, query)[0]) != null ? _a3 : profile.numericFields[0];
|
|
7869
7993
|
}
|
|
7870
7994
|
static rankFieldsByQuery(fields, query) {
|
|
7871
7995
|
const q = query.toLowerCase();
|
|
@@ -7894,8 +8018,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7894
8018
|
static aggregateProfileByDimension(profile, dimensionKey, measureKey) {
|
|
7895
8019
|
const result = {};
|
|
7896
8020
|
profile.records.forEach((record) => {
|
|
7897
|
-
var
|
|
7898
|
-
const category = String((
|
|
8021
|
+
var _a3, _b, _c;
|
|
8022
|
+
const category = String((_a3 = record.fields[dimensionKey]) != null ? _a3 : "Other").trim() || "Other";
|
|
7899
8023
|
const value = measureKey ? (_b = this.toFiniteNumber(record.fields[measureKey])) != null ? _b : 0 : 1;
|
|
7900
8024
|
result[category] = ((_c = result[category]) != null ? _c : 0) + value;
|
|
7901
8025
|
});
|
|
@@ -7975,8 +8099,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7975
8099
|
static aggregateByCategory(data, categories) {
|
|
7976
8100
|
const result = Object.fromEntries(categories.map((c) => [c, 0]));
|
|
7977
8101
|
data.forEach((item) => {
|
|
7978
|
-
var
|
|
7979
|
-
const cat = (
|
|
8102
|
+
var _a3;
|
|
8103
|
+
const cat = (_a3 = this.getProductCategory(item)) != null ? _a3 : "Other";
|
|
7980
8104
|
if (Object.prototype.hasOwnProperty.call(result, cat)) result[cat]++;
|
|
7981
8105
|
else result["Other"] = (result["Other"] || 0) + 1;
|
|
7982
8106
|
});
|
|
@@ -7984,17 +8108,17 @@ ${schemaProfileText}` : ""}`;
|
|
|
7984
8108
|
}
|
|
7985
8109
|
static extractTimeSeriesData(data) {
|
|
7986
8110
|
return data.map((item) => {
|
|
7987
|
-
var
|
|
8111
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
7988
8112
|
const meta = item.metadata || {};
|
|
7989
8113
|
return {
|
|
7990
|
-
timestamp: (_b = (
|
|
8114
|
+
timestamp: (_b = (_a3 = meta.timestamp) != null ? _a3 : meta.date) != null ? _b : (/* @__PURE__ */ new Date()).toISOString(),
|
|
7991
8115
|
value: (_d = (_c = meta.value) != null ? _c : item.score) != null ? _d : 0,
|
|
7992
8116
|
label: (_f = meta.label) != null ? _f : ((_e = item == null ? void 0 : item.content) != null ? _e : "").substring(0, 50)
|
|
7993
8117
|
};
|
|
7994
8118
|
});
|
|
7995
8119
|
}
|
|
7996
8120
|
static extractNumericValue(meta) {
|
|
7997
|
-
var
|
|
8121
|
+
var _a3;
|
|
7998
8122
|
const preferredKeys = [
|
|
7999
8123
|
"value",
|
|
8000
8124
|
"count",
|
|
@@ -8009,7 +8133,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
8009
8133
|
"price"
|
|
8010
8134
|
];
|
|
8011
8135
|
for (const key of preferredKeys) {
|
|
8012
|
-
const raw = (
|
|
8136
|
+
const raw = (_a3 = resolveMetadataValue(meta, key)) != null ? _a3 : meta[key];
|
|
8013
8137
|
const value = typeof raw === "number" ? raw : Number(String(raw != null ? raw : "").replace(/[$,% ,]/g, ""));
|
|
8014
8138
|
if (Number.isFinite(value)) return value;
|
|
8015
8139
|
}
|
|
@@ -8104,8 +8228,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
8104
8228
|
}, query.includes(normalizedField) ? 3 : 0);
|
|
8105
8229
|
}
|
|
8106
8230
|
static resolveTableCellValue(item, column) {
|
|
8107
|
-
var
|
|
8108
|
-
if (column === "Content") return ((
|
|
8231
|
+
var _a3, _b, _c;
|
|
8232
|
+
if (column === "Content") return ((_a3 = item == null ? void 0 : item.content) != null ? _a3 : "").substring(0, 100);
|
|
8109
8233
|
const meta = item.metadata || {};
|
|
8110
8234
|
const normalizedColumn = this.normalizeComparableField(column);
|
|
8111
8235
|
const exactMetadata = Object.entries(meta).find(
|
|
@@ -8157,8 +8281,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
8157
8281
|
let inStock = 0;
|
|
8158
8282
|
let outOfStock = 0;
|
|
8159
8283
|
data.forEach((d) => {
|
|
8160
|
-
var
|
|
8161
|
-
const cat = (
|
|
8284
|
+
var _a3, _b;
|
|
8285
|
+
const cat = (_a3 = this.getProductCategory(d)) != null ? _a3 : "Other";
|
|
8162
8286
|
if (cat === category) {
|
|
8163
8287
|
const quantity = (_b = this.extractStockQuantity(d)) != null ? _b : 1;
|
|
8164
8288
|
if (this.determineStockStatus(d)) inStock += quantity;
|
|
@@ -8204,9 +8328,9 @@ ${schemaProfileText}` : ""}`;
|
|
|
8204
8328
|
}
|
|
8205
8329
|
// ─── Product Extraction ───────────────────────────────────────────────────
|
|
8206
8330
|
static getDynamicVal(meta, uiKey, config, trainedSchema) {
|
|
8207
|
-
var
|
|
8331
|
+
var _a3;
|
|
8208
8332
|
if (!meta) return void 0;
|
|
8209
|
-
const mapping = (
|
|
8333
|
+
const mapping = (_a3 = config == null ? void 0 : config.rag) == null ? void 0 : _a3.uiMapping;
|
|
8210
8334
|
if ((mapping == null ? void 0 : mapping[uiKey]) && meta[mapping[uiKey]] !== void 0) return meta[mapping[uiKey]];
|
|
8211
8335
|
if (trainedSchema && typeof trainedSchema === "object") {
|
|
8212
8336
|
const trainedKey = trainedSchema[uiKey];
|
|
@@ -8215,7 +8339,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
8215
8339
|
return resolveMetadataValue(meta, uiKey);
|
|
8216
8340
|
}
|
|
8217
8341
|
static extractProductInfo(item, config, trainedSchema) {
|
|
8218
|
-
var
|
|
8342
|
+
var _a3, _b;
|
|
8219
8343
|
if (!item) return null;
|
|
8220
8344
|
const meta = item.metadata || {};
|
|
8221
8345
|
const content = item.content || "";
|
|
@@ -8223,7 +8347,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
8223
8347
|
const price = this.getDynamicVal(meta, "price", config, trainedSchema);
|
|
8224
8348
|
const brand = this.getDynamicVal(meta, "brand", config, trainedSchema);
|
|
8225
8349
|
const description = this.cleanProductDescription(
|
|
8226
|
-
(
|
|
8350
|
+
(_a3 = this.extractProductDescriptionFromContent(content)) != null ? _a3 : this.getProductDescriptionValue(meta, config, trainedSchema)
|
|
8227
8351
|
);
|
|
8228
8352
|
if (name || this.isProductData(item)) {
|
|
8229
8353
|
let finalName = name ? String(name) : void 0;
|
|
@@ -8358,10 +8482,10 @@ RULES:
|
|
|
8358
8482
|
}
|
|
8359
8483
|
static buildContextSummary(sources, maxChars = 6e3) {
|
|
8360
8484
|
const items = (sources || []).filter(Boolean).map((s, i) => {
|
|
8361
|
-
var
|
|
8485
|
+
var _a3, _b, _c, _d;
|
|
8362
8486
|
return {
|
|
8363
8487
|
index: i + 1,
|
|
8364
|
-
content: (_b = (
|
|
8488
|
+
content: (_b = (_a3 = s == null ? void 0 : s.content) == null ? void 0 : _a3.substring(0, 400)) != null ? _b : "",
|
|
8365
8489
|
metadata: (_c = s == null ? void 0 : s.metadata) != null ? _c : {},
|
|
8366
8490
|
score: (_d = s == null ? void 0 : s.score) != null ? _d : 0
|
|
8367
8491
|
};
|
|
@@ -8401,7 +8525,7 @@ var SchemaMapper = class {
|
|
|
8401
8525
|
return promise;
|
|
8402
8526
|
}
|
|
8403
8527
|
static async _doTrain(llm, cacheKey, keys) {
|
|
8404
|
-
var
|
|
8528
|
+
var _a3, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
|
|
8405
8529
|
console.log(`[SchemaMapper] \u{1F9E0} Training on new schema keys: ${keys.join(", ")}`);
|
|
8406
8530
|
const propertyList = Object.entries(this.TARGET_PROPERTIES).map(([prop, desc]) => `- ${prop} (${desc})`).join("\n");
|
|
8407
8531
|
const messages = [
|
|
@@ -8417,7 +8541,7 @@ Return a JSON object like {"name":"Title","price":"Price",...}. Omit unmapped pr
|
|
|
8417
8541
|
}
|
|
8418
8542
|
];
|
|
8419
8543
|
try {
|
|
8420
|
-
const baseUrl = (
|
|
8544
|
+
const baseUrl = (_a3 = llm == null ? void 0 : llm.baseUrl) != null ? _a3 : "";
|
|
8421
8545
|
const apiKey = (_b = llm == null ? void 0 : llm.apiKey) != null ? _b : "";
|
|
8422
8546
|
const model = (_c = llm == null ? void 0 : llm.model) != null ? _c : "llama-3.1-8b-instant";
|
|
8423
8547
|
let responseText;
|
|
@@ -8592,9 +8716,9 @@ var Pipeline = class {
|
|
|
8592
8716
|
this.initialised = false;
|
|
8593
8717
|
/** Namespace-specific static cold context cache for CAG */
|
|
8594
8718
|
this.coldContexts = /* @__PURE__ */ new Map();
|
|
8595
|
-
var
|
|
8719
|
+
var _a3, _b, _c, _d, _e;
|
|
8596
8720
|
this.chunker = new DocumentChunker(
|
|
8597
|
-
(_b = (
|
|
8721
|
+
(_b = (_a3 = config.rag) == null ? void 0 : _a3.chunkSize) != null ? _b : 1e3,
|
|
8598
8722
|
(_d = (_c = config.rag) == null ? void 0 : _c.chunkOverlap) != null ? _d : 200
|
|
8599
8723
|
);
|
|
8600
8724
|
if (((_e = config.rag) == null ? void 0 : _e.chunkingStrategy) === "llamaindex") {
|
|
@@ -8610,7 +8734,7 @@ var Pipeline = class {
|
|
|
8610
8734
|
return this.initialised ? this.llmProvider : void 0;
|
|
8611
8735
|
}
|
|
8612
8736
|
async initialize() {
|
|
8613
|
-
var
|
|
8737
|
+
var _a3, _b, _c, _d;
|
|
8614
8738
|
if (this.initialised) return;
|
|
8615
8739
|
const chartInstruction = `You are a helpful assistant. Use the provided context to answer questions accurately.
|
|
8616
8740
|
|
|
@@ -8653,7 +8777,7 @@ var Pipeline = class {
|
|
|
8653
8777
|
this.entityExtractor = new EntityExtractor(this.llmProvider);
|
|
8654
8778
|
}
|
|
8655
8779
|
await this.vectorDB.initialize();
|
|
8656
|
-
if (((
|
|
8780
|
+
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) {
|
|
8657
8781
|
this.mcpRegistry = new MCPRegistry(this.config.mcpServers || []);
|
|
8658
8782
|
this.multiAgentCoordinator = new MultiAgentCoordinator({
|
|
8659
8783
|
llmProvider: this.llmProvider,
|
|
@@ -8671,8 +8795,8 @@ var Pipeline = class {
|
|
|
8671
8795
|
this.initialised = true;
|
|
8672
8796
|
}
|
|
8673
8797
|
async loadColdContext(ns) {
|
|
8674
|
-
var
|
|
8675
|
-
const cagConfig = (
|
|
8798
|
+
var _a3, _b;
|
|
8799
|
+
const cagConfig = (_a3 = this.config.rag) == null ? void 0 : _a3.cag;
|
|
8676
8800
|
if (!cagConfig || !cagConfig.enabled) return;
|
|
8677
8801
|
try {
|
|
8678
8802
|
const coldNs = cagConfig.coldNamespace || ns;
|
|
@@ -8725,12 +8849,12 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8725
8849
|
}
|
|
8726
8850
|
/** Step 1: Chunk the document content. */
|
|
8727
8851
|
async prepareChunks(doc) {
|
|
8728
|
-
var
|
|
8852
|
+
var _a3, _b;
|
|
8729
8853
|
if (this.llamaIngestor) {
|
|
8730
8854
|
return this.llamaIngestor.chunk(doc.content, {
|
|
8731
8855
|
docId: doc.docId,
|
|
8732
8856
|
metadata: doc.metadata,
|
|
8733
|
-
chunkSize: (
|
|
8857
|
+
chunkSize: (_a3 = this.config.rag) == null ? void 0 : _a3.chunkSize,
|
|
8734
8858
|
chunkOverlap: (_b = this.config.rag) == null ? void 0 : _b.chunkOverlap
|
|
8735
8859
|
});
|
|
8736
8860
|
}
|
|
@@ -8828,9 +8952,9 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8828
8952
|
return { reply, sources };
|
|
8829
8953
|
}
|
|
8830
8954
|
async ask(question, history = [], namespace) {
|
|
8831
|
-
var
|
|
8955
|
+
var _a3, _b;
|
|
8832
8956
|
await this.initialize();
|
|
8833
|
-
if ((((
|
|
8957
|
+
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) {
|
|
8834
8958
|
return await this.multiAgentCoordinator.run(question, history);
|
|
8835
8959
|
}
|
|
8836
8960
|
const stream = this.askStream(question, history, namespace);
|
|
@@ -8865,9 +8989,9 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8865
8989
|
}
|
|
8866
8990
|
askStream(_0) {
|
|
8867
8991
|
return __asyncGenerator(this, arguments, function* (question, history = [], namespace) {
|
|
8868
|
-
var
|
|
8992
|
+
var _a3, _b;
|
|
8869
8993
|
yield new __await(this.initialize());
|
|
8870
|
-
if ((((
|
|
8994
|
+
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) {
|
|
8871
8995
|
const stream2 = this.multiAgentCoordinator.runStream(question, history);
|
|
8872
8996
|
try {
|
|
8873
8997
|
for (var iter = __forAwait(stream2), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
|
|
@@ -8916,10 +9040,10 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8916
9040
|
*/
|
|
8917
9041
|
askStreamInternal(_0) {
|
|
8918
9042
|
return __asyncGenerator(this, arguments, function* (question, history = [], namespace) {
|
|
8919
|
-
var
|
|
9043
|
+
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;
|
|
8920
9044
|
yield new __await(this.initialize());
|
|
8921
9045
|
const ns = formatNamespace(namespace != null ? namespace : this.config.projectId);
|
|
8922
|
-
const topK = (_b = (
|
|
9046
|
+
const topK = (_b = (_a3 = this.config.rag) == null ? void 0 : _a3.topK) != null ? _b : 5;
|
|
8923
9047
|
const scoreThreshold = (_d = (_c = this.config.rag) == null ? void 0 : _c.scoreThreshold) != null ? _d : 0.3;
|
|
8924
9048
|
const requestId = `req_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
8925
9049
|
const requestStart = performance.now();
|
|
@@ -8968,8 +9092,8 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8968
9092
|
const rerankStart = performance.now();
|
|
8969
9093
|
const structuredSources = this.applyStructuredFilters(rawSources, filter).filter((s) => Boolean(s && typeof s === "object"));
|
|
8970
9094
|
let fullSources = hasNumericPredicates ? structuredSources : structuredSources.filter((m) => {
|
|
8971
|
-
var
|
|
8972
|
-
return ((
|
|
9095
|
+
var _a4;
|
|
9096
|
+
return ((_a4 = m == null ? void 0 : m.score) != null ? _a4 : 0) >= scoreThreshold;
|
|
8973
9097
|
});
|
|
8974
9098
|
const rerankLimit = Math.max(retrievalLimit, fullSources.length);
|
|
8975
9099
|
const useReranking = arch !== "naive" && (arch === "retrieve-and-rerank" || ((_m = this.config.rag) == null ? void 0 : _m.useReranking));
|
|
@@ -8982,13 +9106,13 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8982
9106
|
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]
|
|
8983
9107
|
|
|
8984
9108
|
` + promptSources.map((m, i) => {
|
|
8985
|
-
var
|
|
9109
|
+
var _a4;
|
|
8986
9110
|
return `[Source ${i + 1}]
|
|
8987
|
-
${(
|
|
9111
|
+
${(_a4 = m == null ? void 0 : m.content) != null ? _a4 : ""}`;
|
|
8988
9112
|
}).join("\n\n---\n\n") : "No relevant context found.";
|
|
8989
9113
|
const sources = [...fullSources].filter((s) => Boolean(s && typeof s === "object")).sort((a, b) => {
|
|
8990
|
-
var
|
|
8991
|
-
return ((
|
|
9114
|
+
var _a4, _b2;
|
|
9115
|
+
return ((_a4 = b == null ? void 0 : b.score) != null ? _a4 : 0) - ((_b2 = a == null ? void 0 : a.score) != null ? _b2 : 0);
|
|
8992
9116
|
});
|
|
8993
9117
|
if (graphData && graphData.nodes.length > 0) {
|
|
8994
9118
|
const graphContext = graphData.nodes.map(
|
|
@@ -9016,10 +9140,10 @@ ${context}`;
|
|
|
9016
9140
|
yield {
|
|
9017
9141
|
reply: "",
|
|
9018
9142
|
sources: (sources || []).filter((s) => Boolean(s && typeof s === "object")).map((s) => {
|
|
9019
|
-
var
|
|
9143
|
+
var _a4, _b2, _c2;
|
|
9020
9144
|
return {
|
|
9021
9145
|
id: s.id,
|
|
9022
|
-
score: (
|
|
9146
|
+
score: (_a4 = s.score) != null ? _a4 : 0,
|
|
9023
9147
|
content: (_b2 = s == null ? void 0 : s.content) != null ? _b2 : "",
|
|
9024
9148
|
metadata: (_c2 = s == null ? void 0 : s.metadata) != null ? _c2 : {},
|
|
9025
9149
|
namespace: ns
|
|
@@ -9212,11 +9336,11 @@ ${context}`;
|
|
|
9212
9336
|
systemPrompt,
|
|
9213
9337
|
userPrompt: question + finalRestrictionSuffix,
|
|
9214
9338
|
chunks: (sources || []).filter(Boolean).map((s) => {
|
|
9215
|
-
var
|
|
9339
|
+
var _a4, _b2;
|
|
9216
9340
|
return {
|
|
9217
9341
|
id: s.id,
|
|
9218
9342
|
score: s.score,
|
|
9219
|
-
content: (
|
|
9343
|
+
content: (_a4 = s == null ? void 0 : s.content) != null ? _a4 : "",
|
|
9220
9344
|
metadata: (_b2 = s == null ? void 0 : s.metadata) != null ? _b2 : {},
|
|
9221
9345
|
namespace: ns
|
|
9222
9346
|
};
|
|
@@ -9235,7 +9359,7 @@ ${context}`;
|
|
|
9235
9359
|
const telemetryUrl = ((_B = this.config.telemetry) == null ? void 0 : _B.url) || process.env.TELEMETRY_URL || process.env.NEXT_PUBLIC_TELEMETRY_URL || defaultUrl;
|
|
9236
9360
|
const absoluteUrl = telemetryUrl.startsWith("http") ? telemetryUrl : "https://www.retrivora.com" + (telemetryUrl.startsWith("/") ? telemetryUrl : "/" + telemetryUrl);
|
|
9237
9361
|
(async () => {
|
|
9238
|
-
var
|
|
9362
|
+
var _a4, _b2, _c2, _d2, _e2;
|
|
9239
9363
|
try {
|
|
9240
9364
|
let finalTrace = trace;
|
|
9241
9365
|
if (!awaitHallucination && runHallucination) {
|
|
@@ -9244,7 +9368,7 @@ ${context}`;
|
|
|
9244
9368
|
finalTrace = buildTrace(backgroundScoreResult);
|
|
9245
9369
|
}
|
|
9246
9370
|
}
|
|
9247
|
-
const modelName = (finalTrace == null ? void 0 : finalTrace.model) || ((
|
|
9371
|
+
const modelName = (finalTrace == null ? void 0 : finalTrace.model) || ((_a4 = this.config.llm) == null ? void 0 : _a4.model) || "llama-3.1-8b-instant";
|
|
9248
9372
|
const providerName = (finalTrace == null ? void 0 : finalTrace.provider) || ((_b2 = this.config.llm) == null ? void 0 : _b2.provider) || "groq";
|
|
9249
9373
|
const tokenCount = Number(((_c2 = finalTrace == null ? void 0 : finalTrace.tokens) == null ? void 0 : _c2.totalTokens) || 0);
|
|
9250
9374
|
const costEst = Number(((_d2 = finalTrace == null ? void 0 : finalTrace.tokens) == null ? void 0 : _d2.estimatedCostUsd) || 0);
|
|
@@ -9298,7 +9422,7 @@ ${context}`;
|
|
|
9298
9422
|
* Uses an LRU-bounded embedding cache to avoid re-embedding the same query.
|
|
9299
9423
|
*/
|
|
9300
9424
|
async generateUiTransformation(question, sources, cachedSchema, forceDeterministic = false) {
|
|
9301
|
-
var
|
|
9425
|
+
var _a3;
|
|
9302
9426
|
if (!sources || sources.length === 0) {
|
|
9303
9427
|
return UITransformer.transform(question, sources, this.config, cachedSchema);
|
|
9304
9428
|
}
|
|
@@ -9311,7 +9435,7 @@ ${context}`;
|
|
|
9311
9435
|
{ visualizationHint: "product_browse", recommendedChart: "text", filterInStockOnly: false, wantsExplicitTable: false, isTemporal: false, isComparison: false, language: "en" }
|
|
9312
9436
|
);
|
|
9313
9437
|
}
|
|
9314
|
-
const enableLlmUiTransform = ((
|
|
9438
|
+
const enableLlmUiTransform = ((_a3 = this.config.llm.options) == null ? void 0 : _a3.enableLlmUiTransform) === true;
|
|
9315
9439
|
if (forceDeterministic || !enableLlmUiTransform) {
|
|
9316
9440
|
return UITransformer.transform(question, sources, this.config, cachedSchema);
|
|
9317
9441
|
}
|
|
@@ -9329,15 +9453,15 @@ ${context}`;
|
|
|
9329
9453
|
const value = this.resolveNumericPredicateValue(source, predicate);
|
|
9330
9454
|
return value !== null && this.matchesNumericPredicate(value, predicate);
|
|
9331
9455
|
})).sort((a, b) => {
|
|
9332
|
-
var
|
|
9456
|
+
var _a3, _b;
|
|
9333
9457
|
const primary = predicates[0];
|
|
9334
|
-
const aValue = (
|
|
9458
|
+
const aValue = (_a3 = this.resolveNumericPredicateValue(a, primary)) != null ? _a3 : 0;
|
|
9335
9459
|
const bValue = (_b = this.resolveNumericPredicateValue(b, primary)) != null ? _b : 0;
|
|
9336
9460
|
return primary.operator === "lt" || primary.operator === "lte" ? aValue - bValue : bValue - aValue;
|
|
9337
9461
|
});
|
|
9338
9462
|
}
|
|
9339
9463
|
resolveNumericPredicateValue(source, predicate) {
|
|
9340
|
-
var
|
|
9464
|
+
var _a3;
|
|
9341
9465
|
if (!source) return null;
|
|
9342
9466
|
const meta = source.metadata || {};
|
|
9343
9467
|
const field = predicate.field;
|
|
@@ -9350,7 +9474,7 @@ ${context}`;
|
|
|
9350
9474
|
const value = this.toFiniteNumber(Array.isArray(fuzzy) ? fuzzy[1] : fuzzy.value);
|
|
9351
9475
|
if (value !== null) return value;
|
|
9352
9476
|
}
|
|
9353
|
-
const contentValue = this.extractNumericValueFromContent((
|
|
9477
|
+
const contentValue = this.extractNumericValueFromContent((_a3 = source.content) != null ? _a3 : "", field);
|
|
9354
9478
|
if (contentValue !== null) return contentValue;
|
|
9355
9479
|
}
|
|
9356
9480
|
for (const [key, value] of entries) {
|
|
@@ -9406,8 +9530,8 @@ ${context}`;
|
|
|
9406
9530
|
return Number.isFinite(numeric) ? numeric : null;
|
|
9407
9531
|
}
|
|
9408
9532
|
async retrieve(query, options) {
|
|
9409
|
-
var
|
|
9410
|
-
const ns = formatNamespace((
|
|
9533
|
+
var _a3, _b, _c, _d, _e, _f, _g2;
|
|
9534
|
+
const ns = formatNamespace((_a3 = options.namespace) != null ? _a3 : this.config.projectId);
|
|
9411
9535
|
const topK = (_b = options.topK) != null ? _b : 5;
|
|
9412
9536
|
const cacheKey = `${ns}::${query}`;
|
|
9413
9537
|
let queryVector = this.embeddingCache.get(cacheKey);
|
|
@@ -9452,11 +9576,11 @@ ${context}`;
|
|
|
9452
9576
|
namespace: ns,
|
|
9453
9577
|
count: resolvedSources.length,
|
|
9454
9578
|
sample: resolvedSources.slice(0, 2).map((s) => {
|
|
9455
|
-
var
|
|
9579
|
+
var _a4;
|
|
9456
9580
|
return {
|
|
9457
9581
|
id: s == null ? void 0 : s.id,
|
|
9458
9582
|
score: s == null ? void 0 : s.score,
|
|
9459
|
-
contentSnippet: String((
|
|
9583
|
+
contentSnippet: String((_a4 = s == null ? void 0 : s.content) != null ? _a4 : "").substring(0, 150),
|
|
9460
9584
|
metadata: s == null ? void 0 : s.metadata
|
|
9461
9585
|
};
|
|
9462
9586
|
})
|
|
@@ -9470,8 +9594,8 @@ Focus on extracting the core intent and entities. Do not answer the question, ju
|
|
|
9470
9594
|
|
|
9471
9595
|
History:
|
|
9472
9596
|
${(history || []).map((m) => {
|
|
9473
|
-
var
|
|
9474
|
-
return `${(m == null ? void 0 : m.role) || "user"}: ${(
|
|
9597
|
+
var _a3;
|
|
9598
|
+
return `${(m == null ? void 0 : m.role) || "user"}: ${(_a3 = m == null ? void 0 : m.content) != null ? _a3 : ""}`;
|
|
9475
9599
|
}).join("\n")}
|
|
9476
9600
|
|
|
9477
9601
|
New Question: ${question}
|
|
@@ -9498,8 +9622,8 @@ Optimized Search Query:`;
|
|
|
9498
9622
|
const { sources } = await this.retrieve(query, { namespace: ns, topK: 5 });
|
|
9499
9623
|
if (!sources || sources.length === 0) return [];
|
|
9500
9624
|
const context = sources.map((s) => {
|
|
9501
|
-
var
|
|
9502
|
-
return (
|
|
9625
|
+
var _a3;
|
|
9626
|
+
return (_a3 = s == null ? void 0 : s.content) != null ? _a3 : "";
|
|
9503
9627
|
}).join("\n\n---\n\n");
|
|
9504
9628
|
const prompt = `Based on the following snippets from a document, what are at least 5 short, relevant questions a user might ask?
|
|
9505
9629
|
Focus on questions that can be answered by the context.
|
|
@@ -9541,13 +9665,13 @@ var Retrivora = class {
|
|
|
9541
9665
|
this.pipeline = new Pipeline(this.config);
|
|
9542
9666
|
}
|
|
9543
9667
|
async initialize() {
|
|
9544
|
-
var
|
|
9668
|
+
var _a3;
|
|
9545
9669
|
try {
|
|
9546
9670
|
await ConfigValidator.validateAndThrow(this.config);
|
|
9547
9671
|
LicenseVerifier.verify(
|
|
9548
9672
|
this.config.licenseKey,
|
|
9549
9673
|
this.config.projectId,
|
|
9550
|
-
(
|
|
9674
|
+
(_a3 = this.config.vectorDb) == null ? void 0 : _a3.provider
|
|
9551
9675
|
);
|
|
9552
9676
|
await LicenseVerifier.verifyIP(this.config.licenseKey);
|
|
9553
9677
|
} catch (err) {
|
|
@@ -9720,18 +9844,200 @@ var ProviderHealthCheck = class {
|
|
|
9720
9844
|
}
|
|
9721
9845
|
};
|
|
9722
9846
|
|
|
9847
|
+
// src/core/FreeTierLimitsGuard.ts
|
|
9848
|
+
var FREE_TIER_QUOTAS = {
|
|
9849
|
+
MAX_DOCUMENTS: 25,
|
|
9850
|
+
MAX_FILE_SIZE_BYTES: 20 * 1024 * 1024,
|
|
9851
|
+
MAX_STORAGE_BYTES: 250 * 1024 * 1024,
|
|
9852
|
+
MAX_TRIAL_REQUEST_UNITS: 500,
|
|
9853
|
+
MAX_DAILY_REQUEST_UNITS: 50,
|
|
9854
|
+
TRIAL_DURATION_DAYS: 14,
|
|
9855
|
+
GRACE_PERIOD_DAYS: 2,
|
|
9856
|
+
MAX_RPM: 10,
|
|
9857
|
+
MAX_RPH: 100,
|
|
9858
|
+
MAX_RPD: 500,
|
|
9859
|
+
MAX_CONCURRENT_REQUESTS: 2,
|
|
9860
|
+
MAX_INPUT_TOKENS: 2e4,
|
|
9861
|
+
MAX_OUTPUT_TOKENS: 4e3,
|
|
9862
|
+
UPGRADE_REMINDER_DAYS: [7, 12, 14],
|
|
9863
|
+
MAX_USERS: 1,
|
|
9864
|
+
MAX_NAMESPACES: 1,
|
|
9865
|
+
MAX_PROJECTS: 1
|
|
9866
|
+
};
|
|
9867
|
+
var FreeTierLimitsGuard = class {
|
|
9868
|
+
static calculateTrialTimestamps(startedAt) {
|
|
9869
|
+
const startDate = startedAt ? new Date(startedAt) : /* @__PURE__ */ new Date();
|
|
9870
|
+
const trialStartedAtMs = startDate.getTime();
|
|
9871
|
+
const trialExpiresAtMs = trialStartedAtMs + FREE_TIER_QUOTAS.TRIAL_DURATION_DAYS * 24 * 60 * 60 * 1e3;
|
|
9872
|
+
const gracePeriodExpiresAtMs = trialStartedAtMs + (FREE_TIER_QUOTAS.TRIAL_DURATION_DAYS + FREE_TIER_QUOTAS.GRACE_PERIOD_DAYS) * 24 * 60 * 60 * 1e3;
|
|
9873
|
+
return {
|
|
9874
|
+
trial_started_at: new Date(trialStartedAtMs).toISOString(),
|
|
9875
|
+
trial_expires_at: new Date(trialExpiresAtMs).toISOString(),
|
|
9876
|
+
grace_period_expires_at: new Date(gracePeriodExpiresAtMs).toISOString()
|
|
9877
|
+
};
|
|
9878
|
+
}
|
|
9879
|
+
static calculateRequestUnits(operationType, options) {
|
|
9880
|
+
var _a3;
|
|
9881
|
+
const op = operationType.toLowerCase().trim();
|
|
9882
|
+
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")) {
|
|
9883
|
+
return 0;
|
|
9884
|
+
}
|
|
9885
|
+
if (op.includes("image")) {
|
|
9886
|
+
return 10;
|
|
9887
|
+
}
|
|
9888
|
+
if (op.includes("embedding")) {
|
|
9889
|
+
const chunks = (_a3 = options == null ? void 0 : options.chunkCount) != null ? _a3 : 1;
|
|
9890
|
+
return Math.max(1, Math.ceil(chunks / 1e3));
|
|
9891
|
+
}
|
|
9892
|
+
return 1;
|
|
9893
|
+
}
|
|
9894
|
+
static checkTrialStatus(startedAt, totalUnitsUsed = 0, nowServerTime = /* @__PURE__ */ new Date()) {
|
|
9895
|
+
const timestamps = this.calculateTrialTimestamps(startedAt);
|
|
9896
|
+
const startMs = new Date(timestamps.trial_started_at).getTime();
|
|
9897
|
+
const expireMs = new Date(timestamps.trial_expires_at).getTime();
|
|
9898
|
+
const graceExpireMs = new Date(timestamps.grace_period_expires_at).getTime();
|
|
9899
|
+
const nowMs = nowServerTime.getTime();
|
|
9900
|
+
const daysElapsed = Math.floor(Math.max(0, nowMs - startMs) / (1e3 * 60 * 60 * 24));
|
|
9901
|
+
const daysRemaining = Math.max(0, Math.ceil((expireMs - nowMs) / (1e3 * 60 * 60 * 24)));
|
|
9902
|
+
const isConsumedUnits = totalUnitsUsed >= FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS;
|
|
9903
|
+
const isExpiredTime = nowMs > expireMs;
|
|
9904
|
+
const isPastGraceTime = nowMs > graceExpireMs;
|
|
9905
|
+
let status = "active";
|
|
9906
|
+
let reason;
|
|
9907
|
+
if (isPastGraceTime || isConsumedUnits && isExpiredTime) {
|
|
9908
|
+
status = "expired";
|
|
9909
|
+
reason = "Trial period and grace period have expired. Upgrade your plan.";
|
|
9910
|
+
} else if (isExpiredTime || isConsumedUnits) {
|
|
9911
|
+
status = "grace_period";
|
|
9912
|
+
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).";
|
|
9913
|
+
}
|
|
9914
|
+
let upgradeReminderDue;
|
|
9915
|
+
if (FREE_TIER_QUOTAS.UPGRADE_REMINDER_DAYS.includes(daysElapsed)) {
|
|
9916
|
+
upgradeReminderDue = daysElapsed;
|
|
9917
|
+
}
|
|
9918
|
+
let usageReminderDue;
|
|
9919
|
+
const usagePercent = totalUnitsUsed / FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS * 100;
|
|
9920
|
+
if (usagePercent >= 100) {
|
|
9921
|
+
usageReminderDue = "100%";
|
|
9922
|
+
} else if (usagePercent >= 90) {
|
|
9923
|
+
usageReminderDue = "90%";
|
|
9924
|
+
} else if (usagePercent >= 80) {
|
|
9925
|
+
usageReminderDue = "80%";
|
|
9926
|
+
}
|
|
9927
|
+
return {
|
|
9928
|
+
status,
|
|
9929
|
+
daysElapsed,
|
|
9930
|
+
daysRemaining,
|
|
9931
|
+
isGracePeriod: status === "grace_period",
|
|
9932
|
+
isExpired: status === "expired",
|
|
9933
|
+
upgradeReminderDue,
|
|
9934
|
+
usageReminderDue,
|
|
9935
|
+
reason
|
|
9936
|
+
};
|
|
9937
|
+
}
|
|
9938
|
+
static checkIngestionAllowed(stats, incomingSizeBytes = 0) {
|
|
9939
|
+
var _a3, _b;
|
|
9940
|
+
const docs = (_a3 = stats.documentCount) != null ? _a3 : 0;
|
|
9941
|
+
const storage = (_b = stats.totalStorageBytes) != null ? _b : 0;
|
|
9942
|
+
if (incomingSizeBytes > FREE_TIER_QUOTAS.MAX_FILE_SIZE_BYTES) {
|
|
9943
|
+
const mbSize = (incomingSizeBytes / (1024 * 1024)).toFixed(1);
|
|
9944
|
+
return {
|
|
9945
|
+
allowed: false,
|
|
9946
|
+
reason: `[FreeTierIngestor] File size (${mbSize}MB) exceeds maximum allowed size of 20MB under Free Tier rules.`
|
|
9947
|
+
};
|
|
9948
|
+
}
|
|
9949
|
+
if (docs >= FREE_TIER_QUOTAS.MAX_DOCUMENTS) {
|
|
9950
|
+
return {
|
|
9951
|
+
allowed: false,
|
|
9952
|
+
reason: `Document limit reached (${docs}/${FREE_TIER_QUOTAS.MAX_DOCUMENTS}). Upgrade to Pro to ingest more documents.`
|
|
9953
|
+
};
|
|
9954
|
+
}
|
|
9955
|
+
if (storage + incomingSizeBytes > FREE_TIER_QUOTAS.MAX_STORAGE_BYTES) {
|
|
9956
|
+
const mbUsed = (storage / (1024 * 1024)).toFixed(1);
|
|
9957
|
+
return {
|
|
9958
|
+
allowed: false,
|
|
9959
|
+
reason: `Storage quota exceeded (${mbUsed}MB / 250MB). Upgrade for unlimited storage.`
|
|
9960
|
+
};
|
|
9961
|
+
}
|
|
9962
|
+
return { allowed: true };
|
|
9963
|
+
}
|
|
9964
|
+
static checkRequestAllowed(params) {
|
|
9965
|
+
var _a3, _b, _c;
|
|
9966
|
+
const op = (_a3 = params.operationType) != null ? _a3 : "chat";
|
|
9967
|
+
const costUnits = this.calculateRequestUnits(op, { chunkCount: params.chunkCount });
|
|
9968
|
+
if (costUnits === 0) {
|
|
9969
|
+
return { allowed: true, costUnits: 0 };
|
|
9970
|
+
}
|
|
9971
|
+
if (params.inputTokens && params.inputTokens > FREE_TIER_QUOTAS.MAX_INPUT_TOKENS) {
|
|
9972
|
+
return {
|
|
9973
|
+
allowed: false,
|
|
9974
|
+
reason: "Token limit exceeded. Upgrade your plan.",
|
|
9975
|
+
costUnits
|
|
9976
|
+
};
|
|
9977
|
+
}
|
|
9978
|
+
if (params.outputTokens && params.outputTokens > FREE_TIER_QUOTAS.MAX_OUTPUT_TOKENS) {
|
|
9979
|
+
return {
|
|
9980
|
+
allowed: false,
|
|
9981
|
+
reason: "Token limit exceeded. Upgrade your plan.",
|
|
9982
|
+
costUnits
|
|
9983
|
+
};
|
|
9984
|
+
}
|
|
9985
|
+
if (params.concurrentRequests && params.concurrentRequests > FREE_TIER_QUOTAS.MAX_CONCURRENT_REQUESTS) {
|
|
9986
|
+
return {
|
|
9987
|
+
allowed: false,
|
|
9988
|
+
reason: `Concurrent limit exceeded (max ${FREE_TIER_QUOTAS.MAX_CONCURRENT_REQUESTS} active requests). Please wait for active streams to finish.`,
|
|
9989
|
+
costUnits
|
|
9990
|
+
};
|
|
9991
|
+
}
|
|
9992
|
+
const totalUnits = (_b = params.totalUnitsUsed) != null ? _b : 0;
|
|
9993
|
+
const trialStatus = this.checkTrialStatus(params.trialStartedAt, totalUnits, params.nowServerTime);
|
|
9994
|
+
if (trialStatus.status === "expired" || trialStatus.status === "grace_period") {
|
|
9995
|
+
return {
|
|
9996
|
+
allowed: false,
|
|
9997
|
+
reason: trialStatus.reason || "Trial limit reached. Upgrade your plan.",
|
|
9998
|
+
costUnits
|
|
9999
|
+
};
|
|
10000
|
+
}
|
|
10001
|
+
if (totalUnits + costUnits > FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS) {
|
|
10002
|
+
return {
|
|
10003
|
+
allowed: false,
|
|
10004
|
+
reason: `Total trial request unit limit reached (${totalUnits}/${FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS}). Upgrade your plan.`,
|
|
10005
|
+
costUnits
|
|
10006
|
+
};
|
|
10007
|
+
}
|
|
10008
|
+
const dailyUnits = (_c = params.dailyUnitsUsed) != null ? _c : 0;
|
|
10009
|
+
if (dailyUnits + costUnits > FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS) {
|
|
10010
|
+
return {
|
|
10011
|
+
allowed: false,
|
|
10012
|
+
reason: `Daily request quota limit reached (${dailyUnits}/${FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS} units/day). Quota resets tomorrow.`,
|
|
10013
|
+
costUnits
|
|
10014
|
+
};
|
|
10015
|
+
}
|
|
10016
|
+
return { allowed: true, costUnits };
|
|
10017
|
+
}
|
|
10018
|
+
static checkQueryAllowed(dailyQueriesCount = 0) {
|
|
10019
|
+
if (dailyQueriesCount >= FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS) {
|
|
10020
|
+
return {
|
|
10021
|
+
allowed: false,
|
|
10022
|
+
reason: `Daily query limit reached (${FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS}/day). Quota resets tomorrow.`
|
|
10023
|
+
};
|
|
10024
|
+
}
|
|
10025
|
+
return { allowed: true };
|
|
10026
|
+
}
|
|
10027
|
+
};
|
|
10028
|
+
|
|
9723
10029
|
// src/core/VectorPlugin.ts
|
|
9724
10030
|
var VectorPlugin = class {
|
|
9725
10031
|
constructor(hostConfig) {
|
|
9726
10032
|
const resolvedConfig = ConfigResolver.resolve(hostConfig);
|
|
9727
10033
|
this.config = resolvedConfig;
|
|
9728
10034
|
this.validationPromise = (async () => {
|
|
9729
|
-
var
|
|
10035
|
+
var _a3;
|
|
9730
10036
|
await ConfigValidator.validateAndThrow(resolvedConfig);
|
|
9731
10037
|
LicenseVerifier.verify(
|
|
9732
10038
|
resolvedConfig.licenseKey,
|
|
9733
10039
|
resolvedConfig.projectId,
|
|
9734
|
-
(
|
|
10040
|
+
(_a3 = resolvedConfig.vectorDb) == null ? void 0 : _a3.provider
|
|
9735
10041
|
);
|
|
9736
10042
|
})();
|
|
9737
10043
|
this.validationPromise.catch(() => {
|
|
@@ -9765,16 +10071,32 @@ var VectorPlugin = class {
|
|
|
9765
10071
|
this.config.embedding
|
|
9766
10072
|
);
|
|
9767
10073
|
}
|
|
10074
|
+
estimateInputTokens(message, history = []) {
|
|
10075
|
+
const allContent = message.length + history.reduce((acc, m) => {
|
|
10076
|
+
var _a3, _b;
|
|
10077
|
+
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);
|
|
10078
|
+
}, 0);
|
|
10079
|
+
return Math.ceil(allContent / 4);
|
|
10080
|
+
}
|
|
9768
10081
|
/**
|
|
9769
10082
|
* Run a chat query.
|
|
9770
10083
|
*/
|
|
9771
10084
|
async chat(message, history = [], namespace) {
|
|
10085
|
+
var _a3;
|
|
9772
10086
|
try {
|
|
9773
10087
|
await this.validationPromise;
|
|
9774
10088
|
} catch (err) {
|
|
9775
10089
|
throw wrapError(err, "CONFIGURATION_ERROR");
|
|
9776
10090
|
}
|
|
9777
10091
|
try {
|
|
10092
|
+
const inputTokens = this.estimateInputTokens(message, history);
|
|
10093
|
+
const tokenCheck = FreeTierLimitsGuard.checkRequestAllowed({
|
|
10094
|
+
operationType: "chat",
|
|
10095
|
+
inputTokens
|
|
10096
|
+
});
|
|
10097
|
+
if (!tokenCheck.allowed && ((_a3 = tokenCheck.reason) == null ? void 0 : _a3.toLowerCase().includes("token"))) {
|
|
10098
|
+
throw wrapError(new Error(tokenCheck.reason), "RATE_LIMITED");
|
|
10099
|
+
}
|
|
9778
10100
|
return await this.pipeline.ask(message, history, namespace);
|
|
9779
10101
|
} catch (err) {
|
|
9780
10102
|
const msg = String(err);
|
|
@@ -9782,6 +10104,9 @@ var VectorPlugin = class {
|
|
|
9782
10104
|
if (msg.includes("Embed") || msg.includes("embed")) {
|
|
9783
10105
|
defaultCode = "EMBEDDING_FAILED";
|
|
9784
10106
|
}
|
|
10107
|
+
if (msg.toLowerCase().includes("token limit")) {
|
|
10108
|
+
defaultCode = "RATE_LIMITED";
|
|
10109
|
+
}
|
|
9785
10110
|
throw wrapError(err, defaultCode);
|
|
9786
10111
|
}
|
|
9787
10112
|
}
|
|
@@ -9790,12 +10115,21 @@ var VectorPlugin = class {
|
|
|
9790
10115
|
*/
|
|
9791
10116
|
chatStream(_0) {
|
|
9792
10117
|
return __asyncGenerator(this, arguments, function* (message, history = [], namespace) {
|
|
10118
|
+
var _a3;
|
|
9793
10119
|
try {
|
|
9794
10120
|
yield new __await(this.validationPromise);
|
|
9795
10121
|
} catch (err) {
|
|
9796
10122
|
throw wrapError(err, "CONFIGURATION_ERROR");
|
|
9797
10123
|
}
|
|
9798
10124
|
try {
|
|
10125
|
+
const inputTokens = this.estimateInputTokens(message, history);
|
|
10126
|
+
const tokenCheck = FreeTierLimitsGuard.checkRequestAllowed({
|
|
10127
|
+
operationType: "chat_stream",
|
|
10128
|
+
inputTokens
|
|
10129
|
+
});
|
|
10130
|
+
if (!tokenCheck.allowed && ((_a3 = tokenCheck.reason) == null ? void 0 : _a3.toLowerCase().includes("token"))) {
|
|
10131
|
+
throw wrapError(new Error(tokenCheck.reason), "RATE_LIMITED");
|
|
10132
|
+
}
|
|
9799
10133
|
const stream = this.pipeline.askStream(message, history, namespace);
|
|
9800
10134
|
try {
|
|
9801
10135
|
for (var iter = __forAwait(stream), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
|
|
@@ -9818,6 +10152,9 @@ var VectorPlugin = class {
|
|
|
9818
10152
|
if (msg.includes("Embed") || msg.includes("embed")) {
|
|
9819
10153
|
defaultCode = "EMBEDDING_FAILED";
|
|
9820
10154
|
}
|
|
10155
|
+
if (msg.toLowerCase().includes("token limit")) {
|
|
10156
|
+
defaultCode = "RATE_LIMITED";
|
|
10157
|
+
}
|
|
9821
10158
|
throw wrapError(err, defaultCode);
|
|
9822
10159
|
}
|
|
9823
10160
|
});
|
|
@@ -9872,13 +10209,13 @@ var ConfigBuilder = class {
|
|
|
9872
10209
|
* Configure the vector database provider
|
|
9873
10210
|
*/
|
|
9874
10211
|
vectorDb(provider, options) {
|
|
9875
|
-
var
|
|
10212
|
+
var _a3;
|
|
9876
10213
|
if (provider === "auto") {
|
|
9877
10214
|
this._vectorDb = this._autoDetectVectorDb();
|
|
9878
10215
|
} else {
|
|
9879
10216
|
this._vectorDb = {
|
|
9880
10217
|
provider,
|
|
9881
|
-
indexName: (
|
|
10218
|
+
indexName: (_a3 = options == null ? void 0 : options.indexName) != null ? _a3 : "default",
|
|
9882
10219
|
options: __spreadValues({}, options)
|
|
9883
10220
|
};
|
|
9884
10221
|
}
|
|
@@ -9888,7 +10225,7 @@ var ConfigBuilder = class {
|
|
|
9888
10225
|
* Configure the LLM provider for chat
|
|
9889
10226
|
*/
|
|
9890
10227
|
llm(provider, model, apiKey, options) {
|
|
9891
|
-
var
|
|
10228
|
+
var _a3, _b;
|
|
9892
10229
|
if (provider === "auto") {
|
|
9893
10230
|
this._llm = this._autoDetectLLM();
|
|
9894
10231
|
} else {
|
|
@@ -9897,7 +10234,7 @@ var ConfigBuilder = class {
|
|
|
9897
10234
|
model: model != null ? model : "default-model",
|
|
9898
10235
|
apiKey,
|
|
9899
10236
|
systemPrompt: options == null ? void 0 : options.systemPrompt,
|
|
9900
|
-
maxTokens: (
|
|
10237
|
+
maxTokens: (_a3 = options == null ? void 0 : options.maxTokens) != null ? _a3 : 1024,
|
|
9901
10238
|
temperature: (_b = options == null ? void 0 : options.temperature) != null ? _b : 0.7,
|
|
9902
10239
|
baseUrl: options == null ? void 0 : options.baseUrl,
|
|
9903
10240
|
options
|
|
@@ -9940,8 +10277,8 @@ var ConfigBuilder = class {
|
|
|
9940
10277
|
* Set RAG-specific pipeline parameters
|
|
9941
10278
|
*/
|
|
9942
10279
|
rag(options) {
|
|
9943
|
-
var
|
|
9944
|
-
this._rag = __spreadValues(__spreadValues({}, (
|
|
10280
|
+
var _a3;
|
|
10281
|
+
this._rag = __spreadValues(__spreadValues({}, (_a3 = this._rag) != null ? _a3 : {}), options);
|
|
9945
10282
|
return this;
|
|
9946
10283
|
}
|
|
9947
10284
|
/**
|
|
@@ -9957,7 +10294,7 @@ var ConfigBuilder = class {
|
|
|
9957
10294
|
* Throws if required fields (projectId, vectorDb, llm, embedding) are not set.
|
|
9958
10295
|
*/
|
|
9959
10296
|
build() {
|
|
9960
|
-
var
|
|
10297
|
+
var _a3;
|
|
9961
10298
|
const missing = [];
|
|
9962
10299
|
if (!this._projectId) missing.push('projectId (call .projectId("my-app"))');
|
|
9963
10300
|
if (!this._vectorDb) missing.push('vectorDb (call .vectorDb("pinecone", { ... }))');
|
|
@@ -9969,7 +10306,7 @@ var ConfigBuilder = class {
|
|
|
9969
10306
|
${missing.join("\n ")}`
|
|
9970
10307
|
);
|
|
9971
10308
|
}
|
|
9972
|
-
const ragConfig = (
|
|
10309
|
+
const ragConfig = (_a3 = this._rag) != null ? _a3 : { chunkSize: 1e3, chunkOverlap: 200, topK: 5 };
|
|
9973
10310
|
if (process.env.RAG_USE_GRAPH_RETRIEVAL === "true") {
|
|
9974
10311
|
ragConfig.useGraphRetrieval = true;
|
|
9975
10312
|
}
|
|
@@ -10065,8 +10402,8 @@ var DocumentParser = class {
|
|
|
10065
10402
|
* Extract text from a File or Buffer based on its type.
|
|
10066
10403
|
*/
|
|
10067
10404
|
static async parse(file, fileName, mimeType) {
|
|
10068
|
-
var
|
|
10069
|
-
const extension = ((
|
|
10405
|
+
var _a3;
|
|
10406
|
+
const extension = ((_a3 = fileName.split(".").pop()) == null ? void 0 : _a3.toLowerCase()) || "";
|
|
10070
10407
|
if (extension === "txt" || extension === "md" || mimeType === "text/plain" || mimeType === "text/markdown") {
|
|
10071
10408
|
return this.readAsText(file);
|
|
10072
10409
|
}
|
|
@@ -10173,9 +10510,9 @@ var DatabaseStorage = class {
|
|
|
10173
10510
|
this.fallbackDir = this.isServerless ? path.join(os.tmpdir(), ".retrivora") : path.join(process.cwd(), ".retrivora");
|
|
10174
10511
|
this.historyFile = path.join(this.fallbackDir, "history.json");
|
|
10175
10512
|
this.feedbackFile = path.join(this.fallbackDir, "feedback.json");
|
|
10176
|
-
var
|
|
10513
|
+
var _a3, _b, _c, _d, _e;
|
|
10177
10514
|
this.config = config;
|
|
10178
|
-
this.provider = ((
|
|
10515
|
+
this.provider = ((_a3 = config.vectorDb) == null ? void 0 : _a3.provider) || "fs";
|
|
10179
10516
|
const rawHistoryTable = ((_c = (_b = config.rag) == null ? void 0 : _b.history) == null ? void 0 : _c.tableName) || "retrivora_history";
|
|
10180
10517
|
const rawFeedbackTable = ((_e = (_d = config.rag) == null ? void 0 : _d.feedback) == null ? void 0 : _e.tableName) || "retrivora_feedback";
|
|
10181
10518
|
this.historyTableName = rawHistoryTable.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
@@ -10210,16 +10547,16 @@ var DatabaseStorage = class {
|
|
|
10210
10547
|
}
|
|
10211
10548
|
}
|
|
10212
10549
|
checkHistoryEnabled() {
|
|
10213
|
-
var
|
|
10550
|
+
var _a3, _b;
|
|
10214
10551
|
this.checkPremiumSubscription();
|
|
10215
|
-
if (((_b = (
|
|
10552
|
+
if (((_b = (_a3 = this.config.rag) == null ? void 0 : _a3.history) == null ? void 0 : _b.enabled) === false) {
|
|
10216
10553
|
throw new Error("[Retrivora SDK] Chat History is disabled in RagConfig.");
|
|
10217
10554
|
}
|
|
10218
10555
|
}
|
|
10219
10556
|
checkFeedbackEnabled() {
|
|
10220
|
-
var
|
|
10557
|
+
var _a3, _b;
|
|
10221
10558
|
this.checkPremiumSubscription();
|
|
10222
|
-
if (((_b = (
|
|
10559
|
+
if (((_b = (_a3 = this.config.rag) == null ? void 0 : _a3.feedback) == null ? void 0 : _b.enabled) === false) {
|
|
10223
10560
|
throw new Error("[Retrivora SDK] User Feedback is disabled in RagConfig.");
|
|
10224
10561
|
}
|
|
10225
10562
|
}
|
|
@@ -10386,8 +10723,11 @@ var DatabaseStorage = class {
|
|
|
10386
10723
|
this.writeLocalFile(this.historyFile, history);
|
|
10387
10724
|
}
|
|
10388
10725
|
}
|
|
10389
|
-
async getHistory(sessionId) {
|
|
10726
|
+
async getHistory(sessionId, projectIds) {
|
|
10390
10727
|
this.checkHistoryEnabled();
|
|
10728
|
+
if (projectIds && projectIds.length > 0 && !this.sessionInScope(sessionId, projectIds)) {
|
|
10729
|
+
return [];
|
|
10730
|
+
}
|
|
10391
10731
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
10392
10732
|
const pool = await this.getPGPool();
|
|
10393
10733
|
const res = await pool.query(
|
|
@@ -10417,8 +10757,11 @@ var DatabaseStorage = class {
|
|
|
10417
10757
|
return history.filter((h) => h.session_id === sessionId).sort((a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime());
|
|
10418
10758
|
}
|
|
10419
10759
|
}
|
|
10420
|
-
async clearHistory(sessionId) {
|
|
10760
|
+
async clearHistory(sessionId, projectIds) {
|
|
10421
10761
|
this.checkHistoryEnabled();
|
|
10762
|
+
if (projectIds && projectIds.length > 0 && !this.sessionInScope(sessionId, projectIds)) {
|
|
10763
|
+
return;
|
|
10764
|
+
}
|
|
10422
10765
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
10423
10766
|
const pool = await this.getPGPool();
|
|
10424
10767
|
await pool.query(`DELETE FROM ${this.historyTableName} WHERE session_id = $1`, [sessionId]);
|
|
@@ -10437,21 +10780,36 @@ var DatabaseStorage = class {
|
|
|
10437
10780
|
this.writeLocalFile(this.feedbackFile, filteredFeedback);
|
|
10438
10781
|
}
|
|
10439
10782
|
}
|
|
10440
|
-
|
|
10783
|
+
/**
|
|
10784
|
+
* Return true when `sessionId` falls into the allowed `projectIds` scope.
|
|
10785
|
+
* When `projectIds` is empty / undefined we allow the call (legacy behavior
|
|
10786
|
+
* for non-multi-tenant consumers). Session ids typically begin with the
|
|
10787
|
+
* project id they were created for, so we prefix-match as well as contains-match
|
|
10788
|
+
* to catch sharded / suffix-style ids used by some integrations.
|
|
10789
|
+
*/
|
|
10790
|
+
sessionInScope(sessionId, projectIds) {
|
|
10791
|
+
if (!projectIds || projectIds.length === 0) return true;
|
|
10792
|
+
return projectIds.some(
|
|
10793
|
+
(pid) => pid && (sessionId === pid || sessionId.startsWith(pid) || sessionId.includes(pid))
|
|
10794
|
+
);
|
|
10795
|
+
}
|
|
10796
|
+
async listSessions(projectIds) {
|
|
10441
10797
|
this.checkHistoryEnabled();
|
|
10798
|
+
let raw = [];
|
|
10442
10799
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
10443
10800
|
const pool = await this.getPGPool();
|
|
10444
10801
|
const res = await pool.query(`SELECT DISTINCT session_id FROM ${this.historyTableName}`);
|
|
10445
|
-
|
|
10802
|
+
raw = res.rows.map((r) => r.session_id);
|
|
10446
10803
|
} else if (this.provider === "mongodb") {
|
|
10447
10804
|
await this.getMongoClient();
|
|
10448
10805
|
const db = this.getMongoDb();
|
|
10449
|
-
|
|
10806
|
+
raw = await db.collection(this.historyTableName).distinct("session_id");
|
|
10450
10807
|
} else {
|
|
10451
10808
|
const history = this.readLocalFile(this.historyFile);
|
|
10452
|
-
|
|
10453
|
-
return Array.from(sessions);
|
|
10809
|
+
raw = Array.from(new Set(history.map((h) => h.session_id)));
|
|
10454
10810
|
}
|
|
10811
|
+
if (!projectIds || projectIds.length === 0) return raw;
|
|
10812
|
+
return raw.filter((sid) => this.sessionInScope(sid, projectIds));
|
|
10455
10813
|
}
|
|
10456
10814
|
// ─── Feedback Operations ──────────────────────────────────────────────────
|
|
10457
10815
|
async saveFeedback(feedback) {
|
|
@@ -10504,8 +10862,9 @@ var DatabaseStorage = class {
|
|
|
10504
10862
|
this.writeLocalFile(this.feedbackFile, list);
|
|
10505
10863
|
}
|
|
10506
10864
|
}
|
|
10507
|
-
async getFeedback(messageId) {
|
|
10865
|
+
async getFeedback(messageId, projectIds) {
|
|
10508
10866
|
this.checkFeedbackEnabled();
|
|
10867
|
+
let item = null;
|
|
10509
10868
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
10510
10869
|
const pool = await this.getPGPool();
|
|
10511
10870
|
const res = await pool.query(
|
|
@@ -10514,28 +10873,34 @@ var DatabaseStorage = class {
|
|
|
10514
10873
|
WHERE message_id = $1`,
|
|
10515
10874
|
[messageId]
|
|
10516
10875
|
);
|
|
10517
|
-
|
|
10876
|
+
item = res.rows[0] || null;
|
|
10518
10877
|
} else if (this.provider === "mongodb") {
|
|
10519
10878
|
await this.getMongoClient();
|
|
10520
10879
|
const db = this.getMongoDb();
|
|
10521
10880
|
const col = db.collection(this.feedbackTableName);
|
|
10522
|
-
const
|
|
10523
|
-
if (
|
|
10524
|
-
|
|
10525
|
-
|
|
10526
|
-
|
|
10527
|
-
|
|
10528
|
-
|
|
10529
|
-
|
|
10530
|
-
|
|
10531
|
-
|
|
10881
|
+
const raw = await col.findOne({ message_id: messageId });
|
|
10882
|
+
if (raw) {
|
|
10883
|
+
item = {
|
|
10884
|
+
id: raw.id,
|
|
10885
|
+
messageId: raw.message_id,
|
|
10886
|
+
sessionId: raw.session_id,
|
|
10887
|
+
rating: raw.rating,
|
|
10888
|
+
comment: raw.comment,
|
|
10889
|
+
createdAt: raw.created_at
|
|
10890
|
+
};
|
|
10891
|
+
}
|
|
10532
10892
|
} else {
|
|
10533
10893
|
const list = this.readLocalFile(this.feedbackFile);
|
|
10534
|
-
|
|
10894
|
+
item = list.find((f) => f.message_id === messageId) || null;
|
|
10535
10895
|
}
|
|
10896
|
+
if (item && projectIds && projectIds.length > 0) {
|
|
10897
|
+
return this.sessionInScope(item.sessionId, projectIds) ? item : null;
|
|
10898
|
+
}
|
|
10899
|
+
return item;
|
|
10536
10900
|
}
|
|
10537
|
-
async listFeedback() {
|
|
10901
|
+
async listFeedback(projectIds) {
|
|
10538
10902
|
this.checkFeedbackEnabled();
|
|
10903
|
+
let raw = [];
|
|
10539
10904
|
if (this.provider === "postgresql" || this.provider === "pgvector") {
|
|
10540
10905
|
const pool = await this.getPGPool();
|
|
10541
10906
|
const res = await pool.query(
|
|
@@ -10543,13 +10908,13 @@ var DatabaseStorage = class {
|
|
|
10543
10908
|
FROM ${this.feedbackTableName}
|
|
10544
10909
|
ORDER BY created_at DESC`
|
|
10545
10910
|
);
|
|
10546
|
-
|
|
10911
|
+
raw = res.rows;
|
|
10547
10912
|
} else if (this.provider === "mongodb") {
|
|
10548
10913
|
await this.getMongoClient();
|
|
10549
10914
|
const db = this.getMongoDb();
|
|
10550
10915
|
const col = db.collection(this.feedbackTableName);
|
|
10551
10916
|
const items = await col.find({}).sort({ created_at: -1 }).toArray();
|
|
10552
|
-
|
|
10917
|
+
raw = items.map((item) => ({
|
|
10553
10918
|
id: item.id,
|
|
10554
10919
|
messageId: item.message_id,
|
|
10555
10920
|
sessionId: item.session_id,
|
|
@@ -10559,8 +10924,10 @@ var DatabaseStorage = class {
|
|
|
10559
10924
|
}));
|
|
10560
10925
|
} else {
|
|
10561
10926
|
const list = this.readLocalFile(this.feedbackFile);
|
|
10562
|
-
|
|
10927
|
+
raw = [...list].sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime());
|
|
10563
10928
|
}
|
|
10929
|
+
if (!projectIds || projectIds.length === 0) return raw;
|
|
10930
|
+
return raw.filter((f) => this.sessionInScope(f.sessionId, projectIds));
|
|
10564
10931
|
}
|
|
10565
10932
|
async disconnect() {
|
|
10566
10933
|
if (this.pgPool) {
|
|
@@ -10623,8 +10990,8 @@ var _g = global;
|
|
|
10623
10990
|
var _a;
|
|
10624
10991
|
var rateLimiter = (_a = _g.__retrivoraRateLimiter) != null ? _a : _g.__retrivoraRateLimiter = new RateLimiter(6e4, 30);
|
|
10625
10992
|
function getRateLimitKey(req) {
|
|
10626
|
-
var
|
|
10627
|
-
const ip = ((_b = (
|
|
10993
|
+
var _a3, _b;
|
|
10994
|
+
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";
|
|
10628
10995
|
return `ip:${ip}`;
|
|
10629
10996
|
}
|
|
10630
10997
|
function checkRateLimit(req) {
|
|
@@ -10646,6 +11013,66 @@ function checkRateLimit(req) {
|
|
|
10646
11013
|
}
|
|
10647
11014
|
return null;
|
|
10648
11015
|
}
|
|
11016
|
+
var FREE_TIER_NAMES = /* @__PURE__ */ new Set(["hobby", "free", "free_trial", "trial"]);
|
|
11017
|
+
function isFreeTier(tier) {
|
|
11018
|
+
if (!tier) return true;
|
|
11019
|
+
return FREE_TIER_NAMES.has(tier.toLowerCase().trim());
|
|
11020
|
+
}
|
|
11021
|
+
var _a2;
|
|
11022
|
+
var _freeTierGuardInstance = (_a2 = _g.__retrivoraFreeTierGuard) != null ? _a2 : _g.__retrivoraFreeTierGuard = new FreeTierLimitsGuard();
|
|
11023
|
+
function createPaymentRequiredResponse(reason, details) {
|
|
11024
|
+
const body = __spreadProps(__spreadValues({
|
|
11025
|
+
type: "https://retrivora.com/docs/errors/payment-required",
|
|
11026
|
+
title: "Payment Required",
|
|
11027
|
+
status: 402,
|
|
11028
|
+
detail: reason,
|
|
11029
|
+
code: "FREE_TIER_LIMIT_EXCEEDED",
|
|
11030
|
+
instance: void 0
|
|
11031
|
+
}, details != null ? details : {}), {
|
|
11032
|
+
quota: {
|
|
11033
|
+
maxDailyRequestUnits: FREE_TIER_QUOTAS.MAX_DAILY_REQUEST_UNITS,
|
|
11034
|
+
maxTrialRequestUnits: FREE_TIER_QUOTAS.MAX_TRIAL_REQUEST_UNITS,
|
|
11035
|
+
maxDocuments: FREE_TIER_QUOTAS.MAX_DOCUMENTS,
|
|
11036
|
+
maxStorageBytes: FREE_TIER_QUOTAS.MAX_STORAGE_BYTES,
|
|
11037
|
+
upgradeUrl: "https://retrivora.com/pricing"
|
|
11038
|
+
}
|
|
11039
|
+
});
|
|
11040
|
+
return new Response(JSON.stringify(body), {
|
|
11041
|
+
status: 402,
|
|
11042
|
+
headers: {
|
|
11043
|
+
"Content-Type": "application/problem+json"
|
|
11044
|
+
}
|
|
11045
|
+
});
|
|
11046
|
+
}
|
|
11047
|
+
function resolveLicenseKey(req, config, bodyLicenseKey) {
|
|
11048
|
+
var _a3;
|
|
11049
|
+
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 || "";
|
|
11050
|
+
}
|
|
11051
|
+
function enforceLicense(req, config, bodyLicenseKey) {
|
|
11052
|
+
const rawKey = resolveLicenseKey(req, config, bodyLicenseKey);
|
|
11053
|
+
const licenseKey = (rawKey || "").trim().replace(/^["']|["']$/g, "").trim();
|
|
11054
|
+
const projectId = config.projectId || "my-rag-app";
|
|
11055
|
+
try {
|
|
11056
|
+
const payload = LicenseVerifier.verify(licenseKey, projectId);
|
|
11057
|
+
return { ok: true, payload };
|
|
11058
|
+
} catch (err) {
|
|
11059
|
+
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.";
|
|
11060
|
+
const body = {
|
|
11061
|
+
error: {
|
|
11062
|
+
code: "LICENSE_REVOKED",
|
|
11063
|
+
message: "Your Retrivora license key has been terminated, suspended, or revoked. Access denied."
|
|
11064
|
+
},
|
|
11065
|
+
details: message
|
|
11066
|
+
};
|
|
11067
|
+
return {
|
|
11068
|
+
ok: false,
|
|
11069
|
+
response: new Response(JSON.stringify(body), {
|
|
11070
|
+
status: 403,
|
|
11071
|
+
headers: { "Content-Type": "application/json" }
|
|
11072
|
+
})
|
|
11073
|
+
};
|
|
11074
|
+
}
|
|
11075
|
+
}
|
|
10649
11076
|
var MAX_MESSAGE_LENGTH = 8e3;
|
|
10650
11077
|
function sanitizeInput(raw) {
|
|
10651
11078
|
const stripped = raw.replace(/[\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F-\u009F]/g, "");
|
|
@@ -10667,7 +11094,7 @@ function getOrCreatePlugin(configOrPlugin) {
|
|
|
10667
11094
|
return _g[cacheKey];
|
|
10668
11095
|
}
|
|
10669
11096
|
function reportTelemetry(req, plugin, action, status, details, trace) {
|
|
10670
|
-
var
|
|
11097
|
+
var _a3, _b, _c, _d, _e, _f, _g2;
|
|
10671
11098
|
try {
|
|
10672
11099
|
const config = plugin.getConfig();
|
|
10673
11100
|
const licenseKey = config.licenseKey || process.env.RAG_LICENSE_KEY || process.env.RETRIVORA_LICENSE_KEY || process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY;
|
|
@@ -10682,7 +11109,7 @@ function reportTelemetry(req, plugin, action, status, details, trace) {
|
|
|
10682
11109
|
absoluteUrl = `${proto}://${host}${telemetryUrl}`;
|
|
10683
11110
|
}
|
|
10684
11111
|
const projectId = config.projectId || "default";
|
|
10685
|
-
const model = (trace == null ? void 0 : trace.model) || ((
|
|
11112
|
+
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";
|
|
10686
11113
|
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";
|
|
10687
11114
|
const tokens = Number(((_e = trace == null ? void 0 : trace.tokens) == null ? void 0 : _e.totalTokens) || (trace == null ? void 0 : trace.totalTokens) || 0);
|
|
10688
11115
|
const costUsd = Number(((_f = trace == null ? void 0 : trace.tokens) == null ? void 0 : _f.estimatedCostUsd) || (trace == null ? void 0 : trace.costUsd) || 0);
|
|
@@ -10706,7 +11133,6 @@ function reportTelemetry(req, plugin, action, status, details, trace) {
|
|
|
10706
11133
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
10707
11134
|
details
|
|
10708
11135
|
};
|
|
10709
|
-
console.log(`[Retrivora SDK Telemetry] Dispatching telemetry -> Feature: "${action}", Status: "${status}", Project: "${projectId}", Latency: ${latencyMs}ms`);
|
|
10710
11136
|
fetch(absoluteUrl, {
|
|
10711
11137
|
method: "POST",
|
|
10712
11138
|
headers: {
|
|
@@ -10764,14 +11190,39 @@ function createChatHandler(configOrPlugin, options) {
|
|
|
10764
11190
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
10765
11191
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
10766
11192
|
return async function POST(req, context) {
|
|
10767
|
-
var
|
|
11193
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
10768
11194
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10769
11195
|
if (authResult) return authResult;
|
|
10770
11196
|
const rateLimited = checkRateLimit(req);
|
|
10771
11197
|
if (rateLimited) return rateLimited;
|
|
11198
|
+
const config = plugin.getConfig();
|
|
10772
11199
|
try {
|
|
10773
11200
|
const body = await req.json();
|
|
10774
11201
|
const bodyObj = body != null ? body : {};
|
|
11202
|
+
const licenseCheck = enforceLicense(req, config, bodyObj == null ? void 0 : bodyObj.licenseKey);
|
|
11203
|
+
if (!licenseCheck.ok) return licenseCheck.response;
|
|
11204
|
+
if (isFreeTier(licenseCheck.payload.tier)) {
|
|
11205
|
+
const estimatedInputTokens = Math.ceil(
|
|
11206
|
+
((((_a3 = bodyObj.message) == null ? void 0 : _a3.length) || 0) + (Array.isArray(bodyObj.messages) ? bodyObj.messages.reduce((a, m) => {
|
|
11207
|
+
var _a4, _b2;
|
|
11208
|
+
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);
|
|
11209
|
+
}, 0) : 0) + (((_b = bodyObj.history) == null ? void 0 : _b.reduce((a, m) => {
|
|
11210
|
+
var _a4, _b2;
|
|
11211
|
+
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);
|
|
11212
|
+
}, 0)) || 0)) / 4
|
|
11213
|
+
);
|
|
11214
|
+
const chatCheck = FreeTierLimitsGuard.checkRequestAllowed({
|
|
11215
|
+
operationType: "chat",
|
|
11216
|
+
inputTokens: estimatedInputTokens,
|
|
11217
|
+
projectId: licenseCheck.payload.projectId
|
|
11218
|
+
});
|
|
11219
|
+
if (!chatCheck.allowed) {
|
|
11220
|
+
return createPaymentRequiredResponse(
|
|
11221
|
+
chatCheck.reason || "Free tier quota exceeded.",
|
|
11222
|
+
{ tier: licenseCheck.payload.tier, projectId: licenseCheck.payload.projectId }
|
|
11223
|
+
);
|
|
11224
|
+
}
|
|
11225
|
+
}
|
|
10775
11226
|
let rawMessage = bodyObj.message;
|
|
10776
11227
|
if (!rawMessage && Array.isArray(bodyObj.messages) && bodyObj.messages.length > 0) {
|
|
10777
11228
|
const lastMsg = bodyObj.messages[bodyObj.messages.length - 1];
|
|
@@ -10803,7 +11254,7 @@ function createChatHandler(configOrPlugin, options) {
|
|
|
10803
11254
|
uiTransformation: result.ui_transformation,
|
|
10804
11255
|
trace: result.trace
|
|
10805
11256
|
}).catch((err) => console.warn("[createChatHandler] Failed to save assistant message:", err));
|
|
10806
|
-
reportTelemetry(req, plugin, "QUERY_GENERATION", "success", `Tokens: ${((
|
|
11257
|
+
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);
|
|
10807
11258
|
return import_server.NextResponse.json(__spreadProps(__spreadValues({}, result), {
|
|
10808
11259
|
messageId: assistantMsgId,
|
|
10809
11260
|
userMessageId: userMsgId
|
|
@@ -10820,14 +11271,15 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10820
11271
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
10821
11272
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
10822
11273
|
return async function POST(req, context) {
|
|
10823
|
-
var
|
|
11274
|
+
var _a3, _b, _c;
|
|
10824
11275
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10825
11276
|
if (authResult) return authResult;
|
|
10826
11277
|
const rateLimited = checkRateLimit(req);
|
|
10827
11278
|
if (rateLimited) return rateLimited;
|
|
11279
|
+
const config = plugin.getConfig();
|
|
10828
11280
|
let body;
|
|
10829
11281
|
try {
|
|
10830
|
-
if ((
|
|
11282
|
+
if ((_a3 = req.headers.get("content-type")) == null ? void 0 : _a3.includes("multipart/form-data")) {
|
|
10831
11283
|
const uploader = createUploadHandler(plugin, { onAuthorize });
|
|
10832
11284
|
return uploader(req);
|
|
10833
11285
|
}
|
|
@@ -10839,6 +11291,30 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10839
11291
|
});
|
|
10840
11292
|
}
|
|
10841
11293
|
const bodyObj = body != null ? body : {};
|
|
11294
|
+
const licenseCheck = enforceLicense(req, config, bodyObj == null ? void 0 : bodyObj.licenseKey);
|
|
11295
|
+
if (!licenseCheck.ok) return licenseCheck.response;
|
|
11296
|
+
if (isFreeTier(licenseCheck.payload.tier)) {
|
|
11297
|
+
const estimatedInputTokens = Math.ceil(
|
|
11298
|
+
((((_b = bodyObj.message) == null ? void 0 : _b.length) || 0) + (Array.isArray(bodyObj.messages) ? bodyObj.messages.reduce((a, m) => {
|
|
11299
|
+
var _a4, _b2;
|
|
11300
|
+
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);
|
|
11301
|
+
}, 0) : 0) + (((_c = bodyObj.history) == null ? void 0 : _c.reduce((a, m) => {
|
|
11302
|
+
var _a4, _b2;
|
|
11303
|
+
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);
|
|
11304
|
+
}, 0)) || 0)) / 4
|
|
11305
|
+
);
|
|
11306
|
+
const chatCheck = FreeTierLimitsGuard.checkRequestAllowed({
|
|
11307
|
+
operationType: "chat_stream",
|
|
11308
|
+
inputTokens: estimatedInputTokens,
|
|
11309
|
+
projectId: licenseCheck.payload.projectId
|
|
11310
|
+
});
|
|
11311
|
+
if (!chatCheck.allowed) {
|
|
11312
|
+
return createPaymentRequiredResponse(
|
|
11313
|
+
chatCheck.reason || "Free tier quota exceeded.",
|
|
11314
|
+
{ tier: licenseCheck.payload.tier, projectId: licenseCheck.payload.projectId }
|
|
11315
|
+
);
|
|
11316
|
+
}
|
|
11317
|
+
}
|
|
10842
11318
|
let rawMessage = bodyObj.message;
|
|
10843
11319
|
if (!rawMessage && Array.isArray(bodyObj.messages) && bodyObj.messages.length > 0) {
|
|
10844
11320
|
const lastMsg = bodyObj.messages[bodyObj.messages.length - 1];
|
|
@@ -10868,7 +11344,7 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10868
11344
|
let isActive = true;
|
|
10869
11345
|
const stream = new ReadableStream({
|
|
10870
11346
|
async start(controller) {
|
|
10871
|
-
var
|
|
11347
|
+
var _a4, _b2, _c2, _d, _e;
|
|
10872
11348
|
const enqueue = (text) => {
|
|
10873
11349
|
if (!isActive) return;
|
|
10874
11350
|
try {
|
|
@@ -10901,7 +11377,7 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10901
11377
|
let uiTransformation = responseChunk == null ? void 0 : responseChunk.ui_transformation;
|
|
10902
11378
|
if (sources.length > 0) {
|
|
10903
11379
|
try {
|
|
10904
|
-
uiTransformation = (
|
|
11380
|
+
uiTransformation = (_a4 = responseChunk == null ? void 0 : responseChunk.ui_transformation) != null ? _a4 : UITransformer.transform(message, sources, plugin.getConfig());
|
|
10905
11381
|
if (uiTransformation) {
|
|
10906
11382
|
enqueue(sseUIFrame(uiTransformation));
|
|
10907
11383
|
}
|
|
@@ -10925,7 +11401,7 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10925
11401
|
uiTransformation,
|
|
10926
11402
|
trace: responseChunk == null ? void 0 : responseChunk.trace
|
|
10927
11403
|
}).catch((err) => console.warn("[createStreamHandler] Failed to save assistant message:", err));
|
|
10928
|
-
reportTelemetry(req, plugin, "QUERY_GENERATION", "success", `Tokens: ${((
|
|
11404
|
+
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);
|
|
10929
11405
|
}
|
|
10930
11406
|
}
|
|
10931
11407
|
} catch (temp) {
|
|
@@ -10975,12 +11451,36 @@ function createIngestHandler(configOrPlugin, options) {
|
|
|
10975
11451
|
return async function POST(req, context) {
|
|
10976
11452
|
const authResult = await checkAuth(req, onAuthorize);
|
|
10977
11453
|
if (authResult) return authResult;
|
|
11454
|
+
const config = plugin.getConfig();
|
|
10978
11455
|
try {
|
|
10979
11456
|
const body = await req.json();
|
|
11457
|
+
const licenseCheck = enforceLicense(req, config, body == null ? void 0 : body.licenseKey);
|
|
11458
|
+
if (!licenseCheck.ok) return licenseCheck.response;
|
|
10980
11459
|
const { documents, namespace } = body;
|
|
10981
11460
|
if (!Array.isArray(documents) || documents.length === 0) {
|
|
10982
11461
|
return import_server.NextResponse.json({ error: "documents array is required" }, { status: 400 });
|
|
10983
11462
|
}
|
|
11463
|
+
if (isFreeTier(licenseCheck.payload.tier)) {
|
|
11464
|
+
const totalIncomingBytes = documents.reduce(
|
|
11465
|
+
(sum, d) => sum + Buffer.byteLength(d.content || "", "utf8"),
|
|
11466
|
+
0
|
|
11467
|
+
);
|
|
11468
|
+
const ingestCheck = FreeTierLimitsGuard.checkIngestionAllowed(
|
|
11469
|
+
{ documentCount: documents.length },
|
|
11470
|
+
totalIncomingBytes
|
|
11471
|
+
);
|
|
11472
|
+
if (!ingestCheck.allowed) {
|
|
11473
|
+
return createPaymentRequiredResponse(
|
|
11474
|
+
ingestCheck.reason || "Free tier ingestion limit reached.",
|
|
11475
|
+
{
|
|
11476
|
+
tier: licenseCheck.payload.tier,
|
|
11477
|
+
projectId: licenseCheck.payload.projectId,
|
|
11478
|
+
documents: documents.length,
|
|
11479
|
+
incomingBytes: totalIncomingBytes
|
|
11480
|
+
}
|
|
11481
|
+
);
|
|
11482
|
+
}
|
|
11483
|
+
}
|
|
10984
11484
|
const results = await plugin.ingest(documents, namespace);
|
|
10985
11485
|
reportTelemetry(req, plugin, "DOCUMENT_INGESTION", "success", `Ingested ${documents.length} document(s)`);
|
|
10986
11486
|
return import_server.NextResponse.json({ results });
|
|
@@ -11017,7 +11517,7 @@ function createLicenseHandler(configOrPlugin, options) {
|
|
|
11017
11517
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
11018
11518
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
11019
11519
|
return async function POST(req) {
|
|
11020
|
-
var
|
|
11520
|
+
var _a3;
|
|
11021
11521
|
if (req) {
|
|
11022
11522
|
const authResult = await checkAuth(req, onAuthorize);
|
|
11023
11523
|
if (authResult) return authResult;
|
|
@@ -11025,7 +11525,7 @@ function createLicenseHandler(configOrPlugin, options) {
|
|
|
11025
11525
|
try {
|
|
11026
11526
|
const body = await req.json().catch(() => ({}));
|
|
11027
11527
|
const config = plugin.getConfig();
|
|
11028
|
-
const rawKey = req.headers.get("x-license-key") || (body == null ? void 0 : body.licenseKey) || ((
|
|
11528
|
+
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 || "";
|
|
11029
11529
|
const licenseKey = (rawKey || "").trim().replace(/^["']|["']$/g, "").trim();
|
|
11030
11530
|
const projectId = (body == null ? void 0 : body.projectId) || config.projectId || "my-rag-app";
|
|
11031
11531
|
const payload = LicenseVerifier.verify(licenseKey, projectId);
|
|
@@ -11060,6 +11560,9 @@ function createUploadHandler(configOrPlugin, options) {
|
|
|
11060
11560
|
return async function POST(req, context) {
|
|
11061
11561
|
const authResult = await checkAuth(req, onAuthorize);
|
|
11062
11562
|
if (authResult) return authResult;
|
|
11563
|
+
const config = plugin.getConfig();
|
|
11564
|
+
const licenseCheck = enforceLicense(req, config);
|
|
11565
|
+
if (!licenseCheck.ok) return licenseCheck.response;
|
|
11063
11566
|
try {
|
|
11064
11567
|
const formData = await req.formData();
|
|
11065
11568
|
const files = formData.getAll("files");
|
|
@@ -11069,6 +11572,26 @@ function createUploadHandler(configOrPlugin, options) {
|
|
|
11069
11572
|
if (!files || files.length === 0) {
|
|
11070
11573
|
return import_server.NextResponse.json({ error: "No files provided" }, { status: 400 });
|
|
11071
11574
|
}
|
|
11575
|
+
if (isFreeTier(licenseCheck.payload.tier)) {
|
|
11576
|
+
const totalUploadBytes = files.reduce((sum, f) => sum + (f.size || 0), 0);
|
|
11577
|
+
const uploadCheck = FreeTierLimitsGuard.checkIngestionAllowed(
|
|
11578
|
+
{ documentCount: files.length },
|
|
11579
|
+
totalUploadBytes
|
|
11580
|
+
);
|
|
11581
|
+
if (!uploadCheck.allowed) {
|
|
11582
|
+
return createPaymentRequiredResponse(
|
|
11583
|
+
uploadCheck.reason || "Free tier upload limit reached.",
|
|
11584
|
+
{
|
|
11585
|
+
tier: licenseCheck.payload.tier,
|
|
11586
|
+
projectId: licenseCheck.payload.projectId,
|
|
11587
|
+
fileCount: files.length,
|
|
11588
|
+
totalUploadBytes,
|
|
11589
|
+
maxFileSizeBytes: FREE_TIER_QUOTAS.MAX_FILE_SIZE_BYTES,
|
|
11590
|
+
maxStorageBytes: FREE_TIER_QUOTAS.MAX_STORAGE_BYTES
|
|
11591
|
+
}
|
|
11592
|
+
);
|
|
11593
|
+
}
|
|
11594
|
+
}
|
|
11072
11595
|
const documents = [];
|
|
11073
11596
|
for (const file of files) {
|
|
11074
11597
|
const isExcel = file.name.toLowerCase().endsWith(".xlsx") || file.name.toLowerCase().endsWith(".xls") || file.type.includes("spreadsheet") || file.type.includes("excel");
|
|
@@ -11178,13 +11701,22 @@ function createSuggestionsHandler(configOrPlugin, options) {
|
|
|
11178
11701
|
return async function handler(req) {
|
|
11179
11702
|
const authResult = await checkAuth(req, onAuthorize);
|
|
11180
11703
|
if (authResult) return authResult;
|
|
11704
|
+
const config = plugin.getConfig();
|
|
11705
|
+
const licenseCheck = enforceLicense(req, config);
|
|
11706
|
+
if (!licenseCheck.ok) return licenseCheck.response;
|
|
11181
11707
|
try {
|
|
11182
11708
|
let query = "";
|
|
11183
11709
|
let namespace = void 0;
|
|
11710
|
+
let bodyLicenseKey = void 0;
|
|
11184
11711
|
if (req.method === "POST") {
|
|
11185
11712
|
const body = await req.json().catch(() => ({}));
|
|
11186
11713
|
query = body.query || "";
|
|
11187
11714
|
namespace = body.namespace;
|
|
11715
|
+
bodyLicenseKey = body.licenseKey;
|
|
11716
|
+
if (bodyLicenseKey) {
|
|
11717
|
+
const recheck = enforceLicense(req, config, bodyLicenseKey);
|
|
11718
|
+
if (!recheck.ok) return recheck.response;
|
|
11719
|
+
}
|
|
11188
11720
|
} else {
|
|
11189
11721
|
const url = new URL(req.url);
|
|
11190
11722
|
query = url.searchParams.get("query") || "";
|
|
@@ -11207,14 +11739,16 @@ function createHistoryHandler(configOrPlugin, options) {
|
|
|
11207
11739
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
11208
11740
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
11209
11741
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
11742
|
+
const onResolveScope = options == null ? void 0 : options.onResolveScope;
|
|
11210
11743
|
return async function handler(req) {
|
|
11211
11744
|
const authResult = await checkAuth(req, onAuthorize);
|
|
11212
11745
|
if (authResult) return authResult;
|
|
11746
|
+
const scope = onResolveScope ? await onResolveScope(req) : void 0;
|
|
11213
11747
|
const url = new URL(req.url);
|
|
11214
11748
|
const sessionId = url.searchParams.get("sessionId") || "default";
|
|
11215
11749
|
if (req.method === "GET") {
|
|
11216
11750
|
try {
|
|
11217
|
-
const history = await storage.getHistory(sessionId);
|
|
11751
|
+
const history = await storage.getHistory(sessionId, scope);
|
|
11218
11752
|
return import_server.NextResponse.json({ history });
|
|
11219
11753
|
} catch (err) {
|
|
11220
11754
|
const message = err instanceof Error ? err.message : "Failed to fetch history";
|
|
@@ -11224,7 +11758,7 @@ function createHistoryHandler(configOrPlugin, options) {
|
|
|
11224
11758
|
try {
|
|
11225
11759
|
const body = await req.json().catch(() => ({}));
|
|
11226
11760
|
const sid = body.sessionId || sessionId;
|
|
11227
|
-
await storage.clearHistory(sid);
|
|
11761
|
+
await storage.clearHistory(sid, scope);
|
|
11228
11762
|
return import_server.NextResponse.json({ success: true });
|
|
11229
11763
|
} catch (err) {
|
|
11230
11764
|
const message = err instanceof Error ? err.message : "Failed to clear history";
|
|
@@ -11238,18 +11772,20 @@ function createFeedbackHandler(configOrPlugin, options) {
|
|
|
11238
11772
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
11239
11773
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
11240
11774
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
11775
|
+
const onResolveScope = options == null ? void 0 : options.onResolveScope;
|
|
11241
11776
|
return async function handler(req) {
|
|
11242
11777
|
const authResult = await checkAuth(req, onAuthorize);
|
|
11243
11778
|
if (authResult) return authResult;
|
|
11779
|
+
const scope = onResolveScope ? await onResolveScope(req) : void 0;
|
|
11244
11780
|
if (req.method === "GET") {
|
|
11245
11781
|
try {
|
|
11246
11782
|
const url = new URL(req.url);
|
|
11247
11783
|
const messageId = url.searchParams.get("messageId");
|
|
11248
11784
|
if (!messageId) {
|
|
11249
|
-
const feedbackList = await storage.listFeedback();
|
|
11785
|
+
const feedbackList = await storage.listFeedback(scope);
|
|
11250
11786
|
return import_server.NextResponse.json({ feedback: feedbackList });
|
|
11251
11787
|
}
|
|
11252
|
-
const feedback = await storage.getFeedback(messageId);
|
|
11788
|
+
const feedback = await storage.getFeedback(messageId, scope);
|
|
11253
11789
|
return import_server.NextResponse.json({ feedback });
|
|
11254
11790
|
} catch (err) {
|
|
11255
11791
|
const message = err instanceof Error ? err.message : "Failed to fetch feedback";
|
|
@@ -11265,6 +11801,17 @@ function createFeedbackHandler(configOrPlugin, options) {
|
|
|
11265
11801
|
if (!rating) {
|
|
11266
11802
|
return import_server.NextResponse.json({ error: "rating is required" }, { status: 400 });
|
|
11267
11803
|
}
|
|
11804
|
+
if (scope && scope.length > 0) {
|
|
11805
|
+
const matches = scope.some(
|
|
11806
|
+
(pid) => pid && (sessionId === pid || sessionId.startsWith(pid) || sessionId.includes(pid))
|
|
11807
|
+
);
|
|
11808
|
+
if (!matches) {
|
|
11809
|
+
return import_server.NextResponse.json(
|
|
11810
|
+
{ error: "sessionId is outside the authorized project scope" },
|
|
11811
|
+
{ status: 403 }
|
|
11812
|
+
);
|
|
11813
|
+
}
|
|
11814
|
+
}
|
|
11268
11815
|
await storage.saveFeedback({ messageId, sessionId, rating, comment });
|
|
11269
11816
|
return import_server.NextResponse.json({ success: true });
|
|
11270
11817
|
} catch (err) {
|
|
@@ -11279,14 +11826,15 @@ function createSessionsHandler(configOrPlugin, options) {
|
|
|
11279
11826
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
11280
11827
|
const storage = new DatabaseStorage(plugin.getConfig());
|
|
11281
11828
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
11829
|
+
const onResolveScope = options == null ? void 0 : options.onResolveScope;
|
|
11282
11830
|
return async function GET(req) {
|
|
11283
11831
|
if (req) {
|
|
11284
11832
|
const authResult = await checkAuth(req, onAuthorize);
|
|
11285
11833
|
if (authResult) return authResult;
|
|
11286
11834
|
}
|
|
11287
|
-
void req;
|
|
11288
11835
|
try {
|
|
11289
|
-
const
|
|
11836
|
+
const scope = req && onResolveScope ? await onResolveScope(req) : void 0;
|
|
11837
|
+
const sessions = await storage.listSessions(scope);
|
|
11290
11838
|
return import_server.NextResponse.json({ sessions });
|
|
11291
11839
|
} catch (err) {
|
|
11292
11840
|
const message = err instanceof Error ? err.message : "Failed to list sessions";
|
|
@@ -11297,15 +11845,17 @@ function createSessionsHandler(configOrPlugin, options) {
|
|
|
11297
11845
|
function createRagHandler(configOrPlugin, options) {
|
|
11298
11846
|
const plugin = getOrCreatePlugin(configOrPlugin);
|
|
11299
11847
|
const onAuthorize = options == null ? void 0 : options.onAuthorize;
|
|
11300
|
-
const
|
|
11301
|
-
const
|
|
11302
|
-
const
|
|
11303
|
-
const
|
|
11304
|
-
const
|
|
11305
|
-
const
|
|
11306
|
-
const
|
|
11307
|
-
const
|
|
11308
|
-
const
|
|
11848
|
+
const onResolveScope = options == null ? void 0 : options.onResolveScope;
|
|
11849
|
+
const scopeableOptions = { onAuthorize, onResolveScope };
|
|
11850
|
+
const chatHandler = createChatHandler(plugin, scopeableOptions);
|
|
11851
|
+
const streamHandler = createStreamHandler(plugin, scopeableOptions);
|
|
11852
|
+
const uploadHandler = createUploadHandler(plugin, scopeableOptions);
|
|
11853
|
+
const healthHandler = createHealthHandler(plugin, scopeableOptions);
|
|
11854
|
+
const suggestionsHandler = createSuggestionsHandler(plugin, scopeableOptions);
|
|
11855
|
+
const historyHandler = createHistoryHandler(plugin, scopeableOptions);
|
|
11856
|
+
const feedbackHandler = createFeedbackHandler(plugin, scopeableOptions);
|
|
11857
|
+
const sessionsHandler = createSessionsHandler(plugin, scopeableOptions);
|
|
11858
|
+
const licenseHandler = createLicenseHandler(plugin, scopeableOptions);
|
|
11309
11859
|
async function routePostRequest(req, segment) {
|
|
11310
11860
|
switch (segment) {
|
|
11311
11861
|
case "chat":
|
|
@@ -11347,7 +11897,7 @@ function createRagHandler(configOrPlugin, options) {
|
|
|
11347
11897
|
}
|
|
11348
11898
|
}
|
|
11349
11899
|
async function getSegment(req, context) {
|
|
11350
|
-
var
|
|
11900
|
+
var _a3, _b;
|
|
11351
11901
|
const contentType = req.headers.get("content-type") || "";
|
|
11352
11902
|
if (contentType.includes("multipart/form-data")) {
|
|
11353
11903
|
return "upload";
|
|
@@ -11364,7 +11914,7 @@ function createRagHandler(configOrPlugin, options) {
|
|
|
11364
11914
|
if (pathname.endsWith("/history")) return "history";
|
|
11365
11915
|
} catch (e) {
|
|
11366
11916
|
}
|
|
11367
|
-
const resolvedParams = typeof ((
|
|
11917
|
+
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;
|
|
11368
11918
|
const segments = (resolvedParams == null ? void 0 : resolvedParams.retrivora) || ((_b = resolvedParams == null ? void 0 : resolvedParams.params) == null ? void 0 : _b.retrivora) || [];
|
|
11369
11919
|
const joined = segments.join("/");
|
|
11370
11920
|
return joined || "chat";
|
|
@@ -11397,6 +11947,7 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
11397
11947
|
constructor() {
|
|
11398
11948
|
this.cache = /* @__PURE__ */ new Map();
|
|
11399
11949
|
}
|
|
11950
|
+
/** @returns Singleton instance of the validator (shared cache across all consumers). */
|
|
11400
11951
|
static getInstance() {
|
|
11401
11952
|
if (!_LicenseValidator.instance) {
|
|
11402
11953
|
_LicenseValidator.instance = new _LicenseValidator();
|
|
@@ -11404,7 +11955,12 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
11404
11955
|
return _LicenseValidator.instance;
|
|
11405
11956
|
}
|
|
11406
11957
|
/**
|
|
11407
|
-
*
|
|
11958
|
+
* Purge entries from the local success cache.
|
|
11959
|
+
*
|
|
11960
|
+
* @param licenseKey - Optional. If provided, only that key's cache entry is
|
|
11961
|
+
* removed. If omitted the entire cache is cleared.
|
|
11962
|
+
* Callers use this after any 401/403 to ensure the next
|
|
11963
|
+
* validate() call re-validates against the server.
|
|
11408
11964
|
*/
|
|
11409
11965
|
purgeCache(licenseKey) {
|
|
11410
11966
|
if (licenseKey) {
|
|
@@ -11414,10 +11970,20 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
11414
11970
|
}
|
|
11415
11971
|
}
|
|
11416
11972
|
/**
|
|
11417
|
-
*
|
|
11973
|
+
* Primary validation entry-point for UI / hook consumers.
|
|
11974
|
+
*
|
|
11975
|
+
* Resolves the license key, consults the local success cache, performs a
|
|
11976
|
+
* server POST for authoritative status, and falls back to local RSA
|
|
11977
|
+
* signature verification if the server can't be reached.
|
|
11978
|
+
*
|
|
11979
|
+
* @throws LicenseValidationError - When no key is provided OR both the
|
|
11980
|
+
* server call AND the local-RSA fallback report an invalid/expired key.
|
|
11981
|
+
* @throws SDKVersionUnsupportedError - When server reports forceUpgrade=true.
|
|
11982
|
+
* @returns A `LicenseValidationResponse` that the UI can use to enable or
|
|
11983
|
+
* lock the chat widget.
|
|
11418
11984
|
*/
|
|
11419
11985
|
async validate(request) {
|
|
11420
|
-
var
|
|
11986
|
+
var _a3;
|
|
11421
11987
|
const {
|
|
11422
11988
|
licenseKey,
|
|
11423
11989
|
projectId,
|
|
@@ -11435,7 +12001,7 @@ var _LicenseValidator = class _LicenseValidator {
|
|
|
11435
12001
|
}
|
|
11436
12002
|
return void 0;
|
|
11437
12003
|
};
|
|
11438
|
-
const rawKey = licenseKey || getHeader("x-license-key") || ((
|
|
12004
|
+
const rawKey = licenseKey || getHeader("x-license-key") || ((_a3 = getHeader("authorization")) == null ? void 0 : _a3.replace(/^Bearer\s+/i, "")) || (typeof process !== "undefined" ? process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY || process.env.RETRIVORA_LICENSE_KEY : "") || "";
|
|
11439
12005
|
const effectiveLicenseKey = (rawKey || "").trim().replace(/^["']|["']$/g, "").trim();
|
|
11440
12006
|
if (!effectiveLicenseKey) {
|
|
11441
12007
|
this.purgeCache(effectiveLicenseKey);
|