@retrivora-ai/rag-engine 1.8.2 → 1.8.3
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/handlers/index.js +142 -16
- package/dist/handlers/index.mjs +5848 -17
- package/dist/index.d.mts +9 -15
- package/dist/index.d.ts +9 -15
- package/dist/index.js +1355 -919
- package/dist/index.mjs +1437 -896
- package/dist/server.d.mts +6 -0
- package/dist/server.d.ts +6 -0
- package/dist/server.js +171 -17
- package/dist/server.mjs +5923 -68
- package/package.json +6 -6
- package/src/app/globals.css +35 -11
- package/src/components/ChatWidget.tsx +0 -1
- package/src/components/MarkdownComponents.tsx +3 -0
- package/src/components/MessageBubble.tsx +3 -2
- package/src/components/ObservabilityPanel.tsx +1 -1
- package/src/components/UIDispatcher.tsx +0 -3
- package/src/config/ConfigBuilder.ts +38 -1
- package/src/core/LangChainAgent.ts +1 -4
- package/src/core/Pipeline.ts +31 -18
- package/src/core/QueryProcessor.ts +65 -0
- package/src/rag/Reranker.ts +99 -6
- package/src/utils/ProductExtractor.ts +3 -3
- package/dist/ChromaDBProvider-MIDOR4FW.mjs +0 -8
- package/dist/MilvusProvider-U7SKC27V.mjs +0 -8
- package/dist/MongoDBProvider-YNKC7EJ6.mjs +0 -8
- package/dist/MultiTablePostgresProvider-ZLGSKTJR.mjs +0 -8
- package/dist/PineconeProvider-QZNRKTN2.mjs +0 -8
- package/dist/QdrantProvider-RLJTNGPY.mjs +0 -8
- package/dist/RedisProvider-SR65SCKV.mjs +0 -8
- package/dist/SimpleGraphProvider-SLOXO4M7.mjs +0 -62
- package/dist/UniversalVectorProvider-IN67OS56.mjs +0 -9
- package/dist/WeaviateProvider-5FWDFITI.mjs +0 -8
- package/dist/chunk-5AJ4XHLW.mjs +0 -201
- package/dist/chunk-5YGUXK7Z.mjs +0 -80
- package/dist/chunk-CFVEZTBJ.mjs +0 -102
- package/dist/chunk-ICKRMZQK.mjs +0 -76
- package/dist/chunk-IMP6FUCY.mjs +0 -30
- package/dist/chunk-LR3VMDVK.mjs +0 -157
- package/dist/chunk-LZVVLSDN.mjs +0 -4077
- package/dist/chunk-M6JSPGAR.mjs +0 -117
- package/dist/chunk-OZFBG4BA.mjs +0 -291
- package/dist/chunk-PSFPZXHX.mjs +0 -245
- package/dist/chunk-U55XRW3U.mjs +0 -96
- package/dist/chunk-VUQJVIJT.mjs +0 -148
- package/dist/chunk-X4TOT24V.mjs +0 -89
- package/dist/chunk-YLTMFW4M.mjs +0 -49
package/dist/server.d.mts
CHANGED
|
@@ -353,6 +353,7 @@ declare class ConfigBuilder {
|
|
|
353
353
|
private _embedding?;
|
|
354
354
|
private _ui?;
|
|
355
355
|
private _rag?;
|
|
356
|
+
private _graphDb?;
|
|
356
357
|
/**
|
|
357
358
|
* Set the project/application ID for namespacing
|
|
358
359
|
*/
|
|
@@ -369,6 +370,10 @@ declare class ConfigBuilder {
|
|
|
369
370
|
* Configure the embedding provider
|
|
370
371
|
*/
|
|
371
372
|
embedding(provider: EmbeddingProvider | 'auto', model?: string, apiKey?: string, options?: Record<string, unknown>): this;
|
|
373
|
+
/**
|
|
374
|
+
* Configure the graph database provider
|
|
375
|
+
*/
|
|
376
|
+
graphDb(provider: string | 'auto', options?: Record<string, unknown>): this;
|
|
372
377
|
/**
|
|
373
378
|
* Set RAG-specific pipeline parameters
|
|
374
379
|
*/
|
|
@@ -390,6 +395,7 @@ declare class ConfigBuilder {
|
|
|
390
395
|
private _autoDetectVectorDb;
|
|
391
396
|
private _autoDetectLLM;
|
|
392
397
|
private _autoDetectEmbedding;
|
|
398
|
+
private _autoDetectGraphDb;
|
|
393
399
|
}
|
|
394
400
|
/**
|
|
395
401
|
* Preset configurations for common provider combinations
|
package/dist/server.d.ts
CHANGED
|
@@ -353,6 +353,7 @@ declare class ConfigBuilder {
|
|
|
353
353
|
private _embedding?;
|
|
354
354
|
private _ui?;
|
|
355
355
|
private _rag?;
|
|
356
|
+
private _graphDb?;
|
|
356
357
|
/**
|
|
357
358
|
* Set the project/application ID for namespacing
|
|
358
359
|
*/
|
|
@@ -369,6 +370,10 @@ declare class ConfigBuilder {
|
|
|
369
370
|
* Configure the embedding provider
|
|
370
371
|
*/
|
|
371
372
|
embedding(provider: EmbeddingProvider | 'auto', model?: string, apiKey?: string, options?: Record<string, unknown>): this;
|
|
373
|
+
/**
|
|
374
|
+
* Configure the graph database provider
|
|
375
|
+
*/
|
|
376
|
+
graphDb(provider: string | 'auto', options?: Record<string, unknown>): this;
|
|
372
377
|
/**
|
|
373
378
|
* Set RAG-specific pipeline parameters
|
|
374
379
|
*/
|
|
@@ -390,6 +395,7 @@ declare class ConfigBuilder {
|
|
|
390
395
|
private _autoDetectVectorDb;
|
|
391
396
|
private _autoDetectLLM;
|
|
392
397
|
private _autoDetectEmbedding;
|
|
398
|
+
private _autoDetectGraphDb;
|
|
393
399
|
}
|
|
394
400
|
/**
|
|
395
401
|
* Preset configurations for common provider combinations
|
package/dist/server.js
CHANGED
|
@@ -3451,11 +3451,70 @@ Text to extract from:
|
|
|
3451
3451
|
// src/rag/Reranker.ts
|
|
3452
3452
|
var Reranker = class {
|
|
3453
3453
|
/**
|
|
3454
|
-
* Re-ranks matches based on a secondary relevance score.
|
|
3455
|
-
* In a production environment, this would call a Cross-Encoder model.
|
|
3456
|
-
* Here we implement a placeholder that filters by score and limits count.
|
|
3454
|
+
* Re-ranks matches based on a secondary relevance score using an LLM.
|
|
3457
3455
|
*/
|
|
3458
|
-
async rerank(matches, query, limit = 5) {
|
|
3456
|
+
async rerank(matches, query, limit = 5, llm) {
|
|
3457
|
+
if (!llm || matches.length <= 1) {
|
|
3458
|
+
const keywords = query.toLowerCase().replace(/[^\w\s]/g, "").split(/\s+/).filter((w) => w.length > 2);
|
|
3459
|
+
if (keywords.length === 0) {
|
|
3460
|
+
return matches.sort((a, b) => b.score - a.score).slice(0, limit);
|
|
3461
|
+
}
|
|
3462
|
+
const scoredMatches = matches.map((match) => {
|
|
3463
|
+
const contentLower = match.content.toLowerCase();
|
|
3464
|
+
let keywordScore = 0;
|
|
3465
|
+
keywords.forEach((keyword) => {
|
|
3466
|
+
if (contentLower.includes(keyword)) {
|
|
3467
|
+
keywordScore += 1;
|
|
3468
|
+
}
|
|
3469
|
+
});
|
|
3470
|
+
const normalizedKeywordScore = keywordScore / keywords.length;
|
|
3471
|
+
const combinedScore = match.score + normalizedKeywordScore * 0.5;
|
|
3472
|
+
return __spreadProps(__spreadValues({}, match), {
|
|
3473
|
+
score: combinedScore
|
|
3474
|
+
});
|
|
3475
|
+
});
|
|
3476
|
+
return scoredMatches.sort((a, b) => b.score - a.score).slice(0, limit);
|
|
3477
|
+
}
|
|
3478
|
+
try {
|
|
3479
|
+
const topN = matches.slice(0, 10);
|
|
3480
|
+
const prompt = `You are a relevance ranking expert.
|
|
3481
|
+
Given the following user query and a list of retrieved document chunks, rank the chunks by relevance to the query.
|
|
3482
|
+
Return the result as a comma-separated list of document indices in order of relevance, from most relevant to least relevant.
|
|
3483
|
+
Use the indices provided in brackets like [0], [1], etc.
|
|
3484
|
+
Only return the indices (e.g., "2,0,1"), nothing else. Do not include brackets in the output.
|
|
3485
|
+
|
|
3486
|
+
Query: "${query}"
|
|
3487
|
+
|
|
3488
|
+
Documents:
|
|
3489
|
+
${topN.map((m, i) => `[${i}] ${m.content.replace(/\n/g, " ")}`).join("\n")}`;
|
|
3490
|
+
const response = await llm.chat(
|
|
3491
|
+
[{ role: "user", content: prompt }],
|
|
3492
|
+
"",
|
|
3493
|
+
{ temperature: 0, maxTokens: 50 }
|
|
3494
|
+
);
|
|
3495
|
+
const cleanedResponse = response.trim().replace(/[\[\]\s]/g, "");
|
|
3496
|
+
const rankedIndices = cleanedResponse.split(",").map(Number).filter((n) => !isNaN(n));
|
|
3497
|
+
if (rankedIndices.length > 0) {
|
|
3498
|
+
const rankedMatches = [];
|
|
3499
|
+
const usedIndices = /* @__PURE__ */ new Set();
|
|
3500
|
+
for (const index of rankedIndices) {
|
|
3501
|
+
if (index >= 0 && index < topN.length && !usedIndices.has(index)) {
|
|
3502
|
+
rankedMatches.push(topN[index]);
|
|
3503
|
+
usedIndices.add(index);
|
|
3504
|
+
}
|
|
3505
|
+
}
|
|
3506
|
+
for (let i = 0; i < topN.length; i++) {
|
|
3507
|
+
if (!usedIndices.has(i)) {
|
|
3508
|
+
rankedMatches.push(topN[i]);
|
|
3509
|
+
}
|
|
3510
|
+
}
|
|
3511
|
+
const rest = matches.slice(10);
|
|
3512
|
+
rankedMatches.push(...rest);
|
|
3513
|
+
return rankedMatches.slice(0, limit);
|
|
3514
|
+
}
|
|
3515
|
+
} catch (error) {
|
|
3516
|
+
console.warn("[Reranker] LLM re-ranking failed, falling back to score-based sorting:", error);
|
|
3517
|
+
}
|
|
3459
3518
|
return matches.sort((a, b) => b.score - a.score).slice(0, limit);
|
|
3460
3519
|
}
|
|
3461
3520
|
};
|
|
@@ -3515,7 +3574,7 @@ var LangChainAgent = class {
|
|
|
3515
3574
|
*/
|
|
3516
3575
|
async initialize(chatModel) {
|
|
3517
3576
|
try {
|
|
3518
|
-
const [{ DynamicTool },
|
|
3577
|
+
const [{ DynamicTool }, , { createAgent }] = await Promise.all([
|
|
3519
3578
|
import("@langchain/core/tools"),
|
|
3520
3579
|
import("@langchain/core/messages"),
|
|
3521
3580
|
import("langchain")
|
|
@@ -3565,7 +3624,6 @@ When presenting structured data, statistics, or comparisons, decide if it is bes
|
|
|
3565
3624
|
tools: [searchTool],
|
|
3566
3625
|
systemPrompt: finalSystemPrompt
|
|
3567
3626
|
});
|
|
3568
|
-
void HumanMessage;
|
|
3569
3627
|
} catch (error) {
|
|
3570
3628
|
const isMissing = error instanceof Error && error.message.includes("Cannot find module");
|
|
3571
3629
|
const hint = isMissing ? " Make sure 'langchain' and '@langchain/core' are installed:\n npm install langchain @langchain/core" : "";
|
|
@@ -4049,6 +4107,69 @@ var QueryProcessor = class {
|
|
|
4049
4107
|
if (filter.keywords && filter.keywords.length === 0) delete filter.keywords;
|
|
4050
4108
|
return filter;
|
|
4051
4109
|
}
|
|
4110
|
+
/**
|
|
4111
|
+
* Determines the retrieval strategy based on the query content.
|
|
4112
|
+
*/
|
|
4113
|
+
static async determineRetrievalStrategy(query, llm, customGraphKeywords, customVectorKeywords) {
|
|
4114
|
+
if (llm) {
|
|
4115
|
+
try {
|
|
4116
|
+
const prompt = `You are a routing expert in a RAG system.
|
|
4117
|
+
Given the user query, determine which retrieval mechanism is needed:
|
|
4118
|
+
- 'vector': For semantic search, finding specific documents or content based on similarity.
|
|
4119
|
+
- 'graph': For finding relationships between entities, multi-hop questions, or network structures.
|
|
4120
|
+
- 'both': If the query requires both specific content and relationship/structural analysis.
|
|
4121
|
+
|
|
4122
|
+
Query: "${query}"
|
|
4123
|
+
|
|
4124
|
+
Return ONLY 'vector', 'graph', or 'both'. No explanation.`;
|
|
4125
|
+
const response = await llm.chat(
|
|
4126
|
+
[{ role: "user", content: prompt }],
|
|
4127
|
+
"",
|
|
4128
|
+
{ temperature: 0, maxTokens: 10 }
|
|
4129
|
+
);
|
|
4130
|
+
const cleanResponse = response.trim().toLowerCase();
|
|
4131
|
+
if (cleanResponse.includes("vector")) return "vector";
|
|
4132
|
+
if (cleanResponse.includes("graph")) return "graph";
|
|
4133
|
+
if (cleanResponse.includes("both")) return "both";
|
|
4134
|
+
} catch (error) {
|
|
4135
|
+
console.warn("[QueryProcessor] LLM strategy classification failed, falling back to keywords:", error);
|
|
4136
|
+
}
|
|
4137
|
+
}
|
|
4138
|
+
const normalized = query.toLowerCase();
|
|
4139
|
+
const graphKeywords = customGraphKeywords || [
|
|
4140
|
+
"relationship",
|
|
4141
|
+
"connect",
|
|
4142
|
+
"link",
|
|
4143
|
+
"network",
|
|
4144
|
+
"friend",
|
|
4145
|
+
"colleague",
|
|
4146
|
+
"manager",
|
|
4147
|
+
"hierarchy",
|
|
4148
|
+
"multi-hop",
|
|
4149
|
+
"shortest path",
|
|
4150
|
+
"between",
|
|
4151
|
+
"related to",
|
|
4152
|
+
"associated with",
|
|
4153
|
+
"belongs to",
|
|
4154
|
+
"part of"
|
|
4155
|
+
];
|
|
4156
|
+
const hasGraphKeyword = graphKeywords.some((kw) => normalized.includes(kw));
|
|
4157
|
+
const vectorKeywords = customVectorKeywords || [
|
|
4158
|
+
"find",
|
|
4159
|
+
"search",
|
|
4160
|
+
"tell me about",
|
|
4161
|
+
"what is",
|
|
4162
|
+
"how to",
|
|
4163
|
+
"documents about"
|
|
4164
|
+
];
|
|
4165
|
+
const hasVectorKeyword = vectorKeywords.some((kw) => normalized.includes(kw));
|
|
4166
|
+
if (hasGraphKeyword && !hasVectorKeyword) {
|
|
4167
|
+
return "graph";
|
|
4168
|
+
} else if (hasGraphKeyword && hasVectorKeyword) {
|
|
4169
|
+
return "both";
|
|
4170
|
+
}
|
|
4171
|
+
return "vector";
|
|
4172
|
+
}
|
|
4052
4173
|
};
|
|
4053
4174
|
|
|
4054
4175
|
// src/utils/synonyms.ts
|
|
@@ -5158,6 +5279,7 @@ var Pipeline = class {
|
|
|
5158
5279
|
let context = sources.length ? sources.map((m, i) => `[Source ${i + 1}]
|
|
5159
5280
|
${m.content}`).join("\n\n---\n\n") : "No relevant context found.";
|
|
5160
5281
|
if (graphData && graphData.nodes.length > 0) {
|
|
5282
|
+
console.log(`[Graph Retrieval] Found ${graphData.nodes.length} relevant entities.`);
|
|
5161
5283
|
const graphContext = graphData.nodes.map(
|
|
5162
5284
|
(n) => `Entity: ${n.label} (${n.id})${n.properties ? " - " + JSON.stringify(n.properties) : ""}`
|
|
5163
5285
|
).join("\n");
|
|
@@ -5223,7 +5345,7 @@ ${context}`;
|
|
|
5223
5345
|
};
|
|
5224
5346
|
const hallucinationResult = yield new __await(scoreHallucination(this.llmProvider, fullReply, context).catch(() => void 0));
|
|
5225
5347
|
const trainedSchema = yield new __await(trainingPromise);
|
|
5226
|
-
const uiTransformation = yield new __await(this.generateUiTransformation(question, sources,
|
|
5348
|
+
const uiTransformation = yield new __await(this.generateUiTransformation(question, sources, trainedSchema));
|
|
5227
5349
|
const trace = {
|
|
5228
5350
|
requestId,
|
|
5229
5351
|
query: question,
|
|
@@ -5262,7 +5384,7 @@ ${context}`;
|
|
|
5262
5384
|
* Universal retrieval method combining all enabled providers.
|
|
5263
5385
|
* Uses an LRU-bounded embedding cache to avoid re-embedding the same query.
|
|
5264
5386
|
*/
|
|
5265
|
-
async generateUiTransformation(question, sources,
|
|
5387
|
+
async generateUiTransformation(question, sources, trainedSchema) {
|
|
5266
5388
|
if (!sources || sources.length === 0) {
|
|
5267
5389
|
return UITransformer.transform(question, sources, this.config, trainedSchema);
|
|
5268
5390
|
}
|
|
@@ -5279,15 +5401,19 @@ ${context}`;
|
|
|
5279
5401
|
const topK = (_b = options.topK) != null ? _b : 5;
|
|
5280
5402
|
const cacheKey = `${ns}::${query}`;
|
|
5281
5403
|
let queryVector = this.embeddingCache.get(cacheKey);
|
|
5404
|
+
const strategy = await QueryProcessor.determineRetrievalStrategy(query, this.llmProvider);
|
|
5405
|
+
console.debug(`[Pipeline] Determined retrieval strategy: ${strategy}`);
|
|
5282
5406
|
const [retrievedVector, graphData] = await Promise.all([
|
|
5283
|
-
|
|
5284
|
-
|
|
5407
|
+
// Only embed if we need vector search (strategy is 'vector' or 'both')
|
|
5408
|
+
strategy === "vector" || strategy === "both" ? queryVector ? Promise.resolve(queryVector) : this.embeddingProvider.embed(query, { taskType: "query" }) : Promise.resolve([]),
|
|
5409
|
+
// Only query graph if we need graph search (strategy is 'graph' or 'both')
|
|
5410
|
+
(strategy === "graph" || strategy === "both") && this.graphDB && ((_c = this.config.rag) == null ? void 0 : _c.useGraphRetrieval) ? this.graphDB.query(query) : Promise.resolve(void 0)
|
|
5285
5411
|
]);
|
|
5286
|
-
if (!queryVector) {
|
|
5412
|
+
if ((strategy === "vector" || strategy === "both") && !queryVector && retrievedVector && retrievedVector.length > 0) {
|
|
5287
5413
|
this.embeddingCache.set(cacheKey, retrievedVector);
|
|
5288
5414
|
queryVector = retrievedVector;
|
|
5289
5415
|
}
|
|
5290
|
-
const sources = await this.vectorDB.query(queryVector, topK, ns, options.filter);
|
|
5416
|
+
const sources = (strategy === "vector" || strategy === "both") && queryVector && queryVector.length > 0 ? await this.vectorDB.query(queryVector, topK, ns, options.filter) : [];
|
|
5291
5417
|
return { sources, graphData };
|
|
5292
5418
|
}
|
|
5293
5419
|
/** Rewrite the user query for better retrieval performance. */
|
|
@@ -5316,13 +5442,13 @@ Optimized Search Query:`;
|
|
|
5316
5442
|
await this.initialize();
|
|
5317
5443
|
const ns = namespace != null ? namespace : this.config.projectId;
|
|
5318
5444
|
try {
|
|
5319
|
-
const { sources } = await this.retrieve(query, { namespace: ns, topK:
|
|
5445
|
+
const { sources } = await this.retrieve(query, { namespace: ns, topK: 5 });
|
|
5320
5446
|
if (sources.length === 0) return [];
|
|
5321
5447
|
const context = sources.map((s) => s.content).join("\n\n---\n\n");
|
|
5322
|
-
const prompt = `Based on the following snippets from a document, what are
|
|
5448
|
+
const prompt = `Based on the following snippets from a document, what are at least 5 short, relevant questions a user might ask?
|
|
5323
5449
|
Focus on questions that can be answered by the context.
|
|
5324
5450
|
Keep each question under 10 words and make them very specific to the content.
|
|
5325
|
-
Return ONLY a JSON array of strings like ["Question 1", "Question 2", "Question 3"].
|
|
5451
|
+
Return ONLY a JSON array of strings like ["Question 1", "Question 2", "Question 3", "Question 4", "Question 5"].
|
|
5326
5452
|
|
|
5327
5453
|
Context:
|
|
5328
5454
|
${context}
|
|
@@ -5339,7 +5465,7 @@ Suggestions:`;
|
|
|
5339
5465
|
if (match) {
|
|
5340
5466
|
const suggestions = JSON.parse(match[0]);
|
|
5341
5467
|
if (Array.isArray(suggestions)) {
|
|
5342
|
-
return suggestions.map((s) => String(s)).slice(0,
|
|
5468
|
+
return suggestions.map((s) => String(s)).slice(0, 5);
|
|
5343
5469
|
}
|
|
5344
5470
|
}
|
|
5345
5471
|
} catch (error) {
|
|
@@ -5581,6 +5707,20 @@ var ConfigBuilder = class {
|
|
|
5581
5707
|
}
|
|
5582
5708
|
return this;
|
|
5583
5709
|
}
|
|
5710
|
+
/**
|
|
5711
|
+
* Configure the graph database provider
|
|
5712
|
+
*/
|
|
5713
|
+
graphDb(provider, options) {
|
|
5714
|
+
if (provider === "auto") {
|
|
5715
|
+
this._graphDb = this._autoDetectGraphDb();
|
|
5716
|
+
} else {
|
|
5717
|
+
this._graphDb = {
|
|
5718
|
+
provider,
|
|
5719
|
+
options: options != null ? options : {}
|
|
5720
|
+
};
|
|
5721
|
+
}
|
|
5722
|
+
return this;
|
|
5723
|
+
}
|
|
5584
5724
|
/**
|
|
5585
5725
|
* Set RAG-specific pipeline parameters
|
|
5586
5726
|
*/
|
|
@@ -5614,13 +5754,18 @@ var ConfigBuilder = class {
|
|
|
5614
5754
|
${missing.join("\n ")}`
|
|
5615
5755
|
);
|
|
5616
5756
|
}
|
|
5757
|
+
const ragConfig = (_a = this._rag) != null ? _a : { chunkSize: 1e3, chunkOverlap: 200, topK: 5 };
|
|
5758
|
+
if (process.env.RAG_USE_GRAPH_RETRIEVAL === "true") {
|
|
5759
|
+
ragConfig.useGraphRetrieval = true;
|
|
5760
|
+
}
|
|
5617
5761
|
return __spreadValues({
|
|
5618
5762
|
projectId: this._projectId,
|
|
5619
5763
|
vectorDb: this._vectorDb,
|
|
5620
5764
|
llm: this._llm,
|
|
5621
5765
|
embedding: this._embedding,
|
|
5622
5766
|
ui: this._rag ? this._ui : void 0,
|
|
5623
|
-
rag:
|
|
5767
|
+
rag: ragConfig,
|
|
5768
|
+
graphDb: this._graphDb
|
|
5624
5769
|
}, this._ui ? { ui: this._ui } : {});
|
|
5625
5770
|
}
|
|
5626
5771
|
/**
|
|
@@ -5668,6 +5813,15 @@ var ConfigBuilder = class {
|
|
|
5668
5813
|
}
|
|
5669
5814
|
return { provider: "openai", model: "text-embedding-3-small", apiKey: process.env.OPENAI_API_KEY };
|
|
5670
5815
|
}
|
|
5816
|
+
_autoDetectGraphDb() {
|
|
5817
|
+
if (process.env.GRAPH_DB_PROVIDER) {
|
|
5818
|
+
return {
|
|
5819
|
+
provider: process.env.GRAPH_DB_PROVIDER,
|
|
5820
|
+
options: {}
|
|
5821
|
+
};
|
|
5822
|
+
}
|
|
5823
|
+
return void 0;
|
|
5824
|
+
}
|
|
5671
5825
|
};
|
|
5672
5826
|
var PRESETS = {
|
|
5673
5827
|
/** OpenAI + Pinecone: Production-ready cloud setup */
|