@retrivora-ai/rag-engine 1.9.3 → 1.9.7
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/README.md +59 -7
- package/dist/{ILLMProvider-Bw2A28nU.d.mts → ILLMProvider-Bhk6zJOK.d.mts} +43 -7
- package/dist/{ILLMProvider-Bw2A28nU.d.ts → ILLMProvider-Bhk6zJOK.d.ts} +43 -7
- package/dist/handlers/index.d.mts +2 -2
- package/dist/handlers/index.d.ts +2 -2
- package/dist/handlers/index.js +737 -237
- package/dist/handlers/index.mjs +736 -237
- package/dist/index-B9J_XEh0.d.ts +187 -0
- package/dist/index-BJ4cd-t5.d.mts +187 -0
- package/dist/{index-B70ZLkfG.d.mts → index-Bu7T6xgr.d.ts} +20 -3
- package/dist/{index-DVu-mkAM.d.ts → index-C3SVtPYg.d.mts} +20 -3
- package/dist/index.css +237 -10
- package/dist/index.d.mts +13 -5
- package/dist/index.d.ts +13 -5
- package/dist/index.js +365 -164
- package/dist/index.mjs +350 -158
- package/dist/server.d.mts +15 -94
- package/dist/server.d.ts +15 -94
- package/dist/server.js +850 -239
- package/dist/server.mjs +839 -238
- package/package.json +2 -4
- package/src/app/api/chat/route.ts +2 -2
- package/src/app/api/health/route.ts +3 -2
- package/src/app/api/ingest/route.ts +3 -2
- package/src/app/api/suggestions/route.ts +3 -2
- package/src/app/api/upload/route.ts +3 -2
- package/src/app/constants.tsx +168 -148
- package/src/app/layout.tsx +5 -18
- package/src/app/types.ts +17 -17
- package/src/components/ChatWidget.tsx +3 -1
- package/src/components/ChatWindow.tsx +5 -1
- package/src/components/DocViewer.tsx +71 -5
- package/src/components/Documentation.tsx +74 -11
- package/src/components/MessageBubble.tsx +39 -2
- package/src/components/ThinkingBlock.tsx +75 -0
- package/src/components/VisualizationRenderer.tsx +27 -1
- package/src/components/constants.tsx +275 -0
- package/src/config/RagConfig.ts +47 -0
- package/src/config/constants.ts +1 -0
- package/src/config/serverConfig.ts +25 -0
- package/src/core/ConfigResolver.ts +73 -22
- package/src/core/ConfigValidator.ts +2 -1
- package/src/core/Pipeline.ts +226 -68
- package/src/core/ProviderRegistry.ts +16 -7
- package/src/core/QueryProcessor.ts +38 -4
- package/src/core/Retrivora.ts +91 -0
- package/src/core/VectorPlugin.ts +62 -8
- package/src/exceptions/index.ts +111 -0
- package/src/handlers/index.ts +73 -0
- package/src/hooks/useRagChat.ts +30 -5
- package/src/index.ts +27 -1
- package/src/lib/plugin.ts +24 -0
- package/src/llm/LLMFactory.ts +8 -4
- package/src/llm/providers/AnthropicProvider.ts +70 -20
- package/src/llm/providers/GeminiProvider.ts +14 -15
- package/src/llm/providers/OllamaProvider.ts +13 -16
- package/src/llm/providers/OpenAIProvider.ts +9 -14
- package/src/llm/providers/UniversalLLMAdapter.ts +5 -5
- package/src/llm/utils.ts +46 -0
- package/src/providers/vectordb/MongoDBProvider.ts +9 -4
- package/src/providers/vectordb/MultiTablePostgresProvider.ts +45 -13
- package/src/rag/EntityExtractor.ts +2 -2
- package/src/rag/Reranker.ts +9 -16
- package/src/server.ts +30 -1
- package/src/types/chat.ts +9 -0
- package/src/types/props.ts +38 -1
- package/src/utils/UITransformer.ts +73 -4
- package/dist/DocumentChunker-Dh9TvmGG.d.mts +0 -45
- package/dist/DocumentChunker-Dh9TvmGG.d.ts +0 -45
package/dist/server.js
CHANGED
|
@@ -10,9 +10,6 @@ var __getProtoOf = Object.getPrototypeOf;
|
|
|
10
10
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
11
11
|
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
12
12
|
var __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : /* @__PURE__ */ Symbol.for("Symbol." + name);
|
|
13
|
-
var __typeError = (msg) => {
|
|
14
|
-
throw TypeError(msg);
|
|
15
|
-
};
|
|
16
13
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
17
14
|
var __spreadValues = (a, b) => {
|
|
18
15
|
for (var prop in b || (b = {}))
|
|
@@ -77,34 +74,6 @@ var __asyncGenerator = (__this, __arguments, generator) => {
|
|
|
77
74
|
}, method = (k, call, wait, clear) => it[k] = (x) => (call = new Promise((yes, no, run) => (run = () => resume(k, x, yes, no), q ? q.then(run) : run())), clear = () => q === wait && (q = 0), q = wait = call.then(clear, clear), call), q, it = {};
|
|
78
75
|
return generator = generator.apply(__this, __arguments), it[__knownSymbol("asyncIterator")] = () => it, method("next"), method("throw"), method("return"), it;
|
|
79
76
|
};
|
|
80
|
-
var __yieldStar = (value) => {
|
|
81
|
-
var obj = value[__knownSymbol("asyncIterator")], isAwait = false, method, it = {};
|
|
82
|
-
if (obj == null) {
|
|
83
|
-
obj = value[__knownSymbol("iterator")]();
|
|
84
|
-
method = (k) => it[k] = (x) => obj[k](x);
|
|
85
|
-
} else {
|
|
86
|
-
obj = obj.call(value);
|
|
87
|
-
method = (k) => it[k] = (v) => {
|
|
88
|
-
if (isAwait) {
|
|
89
|
-
isAwait = false;
|
|
90
|
-
if (k === "throw") throw v;
|
|
91
|
-
return v;
|
|
92
|
-
}
|
|
93
|
-
isAwait = true;
|
|
94
|
-
return {
|
|
95
|
-
done: false,
|
|
96
|
-
value: new __await(new Promise((resolve) => {
|
|
97
|
-
var x = obj[k](v);
|
|
98
|
-
if (!(x instanceof Object)) __typeError("Object expected");
|
|
99
|
-
resolve(x);
|
|
100
|
-
}), 1)
|
|
101
|
-
};
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
|
-
return it[__knownSymbol("iterator")] = () => it, method("next"), "throw" in obj ? method("throw") : it.throw = (x) => {
|
|
105
|
-
throw x;
|
|
106
|
-
}, "return" in obj && method("return"), it;
|
|
107
|
-
};
|
|
108
77
|
var __forAwait = (obj, it, method) => (it = obj[__knownSymbol("asyncIterator")]) ? it.call(obj) : (obj = obj[__knownSymbol("iterator")](), it = {}, method = (key, fn) => (fn = obj[key]) && (it[key] = (arg) => new Promise((yes, no, done) => (arg = fn.call(obj, arg), done = arg.done, Promise.resolve(arg.value).then((value) => yes({ value, done }), no)))), method("next"), method("return"), it);
|
|
109
78
|
|
|
110
79
|
// src/utils/templateUtils.ts
|
|
@@ -661,6 +630,11 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
661
630
|
CREATE INDEX IF NOT EXISTS ${this.uploadTable}_embedding_idx
|
|
662
631
|
ON ${this.uploadTable}
|
|
663
632
|
USING hnsw (embedding vector_cosine_ops)
|
|
633
|
+
`);
|
|
634
|
+
await client.query(`
|
|
635
|
+
CREATE INDEX IF NOT EXISTS "${this.uploadTable}_fts_idx"
|
|
636
|
+
ON "${this.uploadTable}"
|
|
637
|
+
USING gin (to_tsvector('english', content))
|
|
664
638
|
`);
|
|
665
639
|
const res = await client.query(`
|
|
666
640
|
SELECT table_name
|
|
@@ -731,6 +705,11 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
731
705
|
CREATE INDEX IF NOT EXISTS "${tableName}_embedding_idx"
|
|
732
706
|
ON "${tableName}"
|
|
733
707
|
USING hnsw (embedding vector_cosine_ops)
|
|
708
|
+
`);
|
|
709
|
+
await client.query(`
|
|
710
|
+
CREATE INDEX IF NOT EXISTS "${tableName}_fts_idx"
|
|
711
|
+
ON "${tableName}"
|
|
712
|
+
USING gin (to_tsvector('english', content))
|
|
734
713
|
`);
|
|
735
714
|
if (!this.tables.includes(tableName)) {
|
|
736
715
|
this.tables.push(tableName);
|
|
@@ -822,8 +801,11 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
822
801
|
const paramIdx = baseOffset + filterParams.length;
|
|
823
802
|
const synonyms = (_a3 = FIELD_SYNONYMS[key]) != null ? _a3 : [];
|
|
824
803
|
const keysToCheck = [key, ...synonyms];
|
|
825
|
-
const coalesceExprs = keysToCheck.
|
|
826
|
-
|
|
804
|
+
const coalesceExprs = keysToCheck.flatMap((k) => [
|
|
805
|
+
`metadata->>'${k}'`,
|
|
806
|
+
`to_jsonb(t)->>'${k}'`
|
|
807
|
+
]);
|
|
808
|
+
return `COALESCE(${coalesceExprs.map((expr) => `LOWER(${expr})`).join(", ")}) = LOWER($${paramIdx})`;
|
|
827
809
|
});
|
|
828
810
|
whereClause = `WHERE ${conditions.join(" AND ")}`;
|
|
829
811
|
}
|
|
@@ -834,16 +816,35 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
834
816
|
CASE WHEN LOWER(val) IN (${entityHints.map((h) => `'${h.replace(/'/g, "''")}'`).join(", ")})
|
|
835
817
|
THEN 1.0 ELSE 0.0 END
|
|
836
818
|
), 0)
|
|
837
|
-
FROM jsonb_each_text(
|
|
819
|
+
FROM jsonb_each_text(COALESCE(v.metadata, k.metadata)) AS kv(key, val)
|
|
838
820
|
WHERE key IN (${this.searchFields.map((f) => `'${f}'`).join(", ")})
|
|
839
821
|
) * 3.0` : "";
|
|
840
822
|
sqlQuery = `
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
823
|
+
WITH vector_search AS (
|
|
824
|
+
SELECT *, (1 - (embedding <=> $1::vector)) AS vector_score
|
|
825
|
+
FROM "${table}" t
|
|
826
|
+
${whereClause}
|
|
827
|
+
ORDER BY embedding <=> $1::vector ASC
|
|
828
|
+
LIMIT ${tableLimit}
|
|
829
|
+
),
|
|
830
|
+
keyword_search AS (
|
|
831
|
+
SELECT *, COALESCE(ts_rank(to_tsvector('english', content), to_tsquery('english', $2)), 0) AS keyword_score
|
|
832
|
+
FROM "${table}" t
|
|
833
|
+
WHERE ${whereClause ? whereClause.replace("WHERE", "") : "TRUE"}
|
|
834
|
+
AND to_tsvector('english', content) @@ to_tsquery('english', $2)
|
|
835
|
+
ORDER BY keyword_score DESC
|
|
836
|
+
LIMIT ${tableLimit}
|
|
837
|
+
)
|
|
838
|
+
SELECT
|
|
839
|
+
COALESCE(v.id, k.id) AS id,
|
|
840
|
+
COALESCE(v.namespace, k.namespace) AS namespace,
|
|
841
|
+
COALESCE(v.content, k.content) AS content,
|
|
842
|
+
COALESCE(v.metadata, k.metadata) AS metadata,
|
|
843
|
+
COALESCE(v.vector_score, 0) AS vector_score,
|
|
844
|
+
COALESCE(k.keyword_score, 0) AS keyword_score,
|
|
845
|
+
(COALESCE(v.vector_score, 0) + COALESCE(k.keyword_score, 0) * 2.0 ${exactNameScoreExpr}) AS hybrid_score
|
|
846
|
+
FROM vector_search v
|
|
847
|
+
FULL OUTER JOIN keyword_search k ON v.id = k.id
|
|
847
848
|
ORDER BY hybrid_score DESC
|
|
848
849
|
LIMIT ${tableLimit}
|
|
849
850
|
`;
|
|
@@ -854,7 +855,7 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
854
855
|
(1 - (embedding <=> $1::vector)) AS hybrid_score
|
|
855
856
|
FROM "${table}" t
|
|
856
857
|
${whereClause}
|
|
857
|
-
ORDER BY
|
|
858
|
+
ORDER BY embedding <=> $1::vector ASC
|
|
858
859
|
LIMIT ${tableLimit}
|
|
859
860
|
`;
|
|
860
861
|
params = [vectorLiteral, ...filterParams];
|
|
@@ -1060,7 +1061,11 @@ var init_MongoDBProvider = __esm({
|
|
|
1060
1061
|
if (key === "namespace") {
|
|
1061
1062
|
vectorSearchFilter.namespace = value;
|
|
1062
1063
|
} else {
|
|
1063
|
-
|
|
1064
|
+
if (typeof value === "string") {
|
|
1065
|
+
matchFilter[key] = { $regex: new RegExp(`^${value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}$`, "i") };
|
|
1066
|
+
} else {
|
|
1067
|
+
matchFilter[key] = value;
|
|
1068
|
+
}
|
|
1064
1069
|
}
|
|
1065
1070
|
}
|
|
1066
1071
|
const pipeline = [
|
|
@@ -2066,14 +2071,17 @@ var init_SimpleGraphProvider = __esm({
|
|
|
2066
2071
|
var server_exports = {};
|
|
2067
2072
|
__export(server_exports, {
|
|
2068
2073
|
AnthropicProvider: () => AnthropicProvider,
|
|
2074
|
+
AuthenticationException: () => AuthenticationException,
|
|
2069
2075
|
BaseVectorProvider: () => BaseVectorProvider,
|
|
2070
2076
|
BatchProcessor: () => BatchProcessor,
|
|
2071
2077
|
ChromaDBProvider: () => ChromaDBProvider,
|
|
2072
2078
|
ConfigBuilder: () => ConfigBuilder,
|
|
2073
2079
|
ConfigResolver: () => ConfigResolver,
|
|
2074
2080
|
ConfigValidator: () => ConfigValidator,
|
|
2081
|
+
ConfigurationException: () => ConfigurationException,
|
|
2075
2082
|
DocumentChunker: () => DocumentChunker,
|
|
2076
2083
|
DocumentParser: () => DocumentParser,
|
|
2084
|
+
EmbeddingFailedException: () => EmbeddingFailedException,
|
|
2077
2085
|
EmbeddingStrategy: () => EmbeddingStrategy,
|
|
2078
2086
|
EmbeddingStrategyResolver: () => EmbeddingStrategyResolver,
|
|
2079
2087
|
LLMFactory: () => LLMFactory,
|
|
@@ -2088,9 +2096,14 @@ __export(server_exports, {
|
|
|
2088
2096
|
Pipeline: () => Pipeline,
|
|
2089
2097
|
PostgreSQLProvider: () => PostgreSQLProvider,
|
|
2090
2098
|
ProviderHealthCheck: () => ProviderHealthCheck,
|
|
2099
|
+
ProviderNotFoundException: () => ProviderNotFoundException,
|
|
2091
2100
|
ProviderRegistry: () => ProviderRegistry,
|
|
2092
2101
|
QdrantProvider: () => QdrantProvider,
|
|
2102
|
+
RateLimitException: () => RateLimitException,
|
|
2093
2103
|
RedisProvider: () => RedisProvider,
|
|
2104
|
+
RetrievalException: () => RetrievalException,
|
|
2105
|
+
Retrivora: () => Retrivora,
|
|
2106
|
+
RetrivoraError: () => RetrivoraError,
|
|
2094
2107
|
UniversalLLMAdapter: () => UniversalLLMAdapter,
|
|
2095
2108
|
UniversalVectorProvider: () => UniversalVectorProvider,
|
|
2096
2109
|
VECTOR_PROFILES: () => VECTOR_PROFILES,
|
|
@@ -2100,13 +2113,15 @@ __export(server_exports, {
|
|
|
2100
2113
|
createFromPreset: () => createFromPreset,
|
|
2101
2114
|
createHealthHandler: () => createHealthHandler,
|
|
2102
2115
|
createIngestHandler: () => createIngestHandler,
|
|
2116
|
+
createRagHandler: () => createRagHandler,
|
|
2103
2117
|
createStreamHandler: () => createStreamHandler,
|
|
2104
2118
|
createUploadHandler: () => createUploadHandler,
|
|
2105
2119
|
getRagConfig: () => getRagConfig,
|
|
2106
2120
|
sseErrorFrame: () => sseErrorFrame,
|
|
2107
2121
|
sseFrame: () => sseFrame,
|
|
2108
2122
|
sseMetaFrame: () => sseMetaFrame,
|
|
2109
|
-
sseTextFrame: () => sseTextFrame
|
|
2123
|
+
sseTextFrame: () => sseTextFrame,
|
|
2124
|
+
wrapError: () => wrapError
|
|
2110
2125
|
});
|
|
2111
2126
|
module.exports = __toCommonJS(server_exports);
|
|
2112
2127
|
|
|
@@ -2181,7 +2196,7 @@ function getRagConfig(baseConfig, env = process.env) {
|
|
|
2181
2196
|
return getEnvConfig(env, baseConfig);
|
|
2182
2197
|
}
|
|
2183
2198
|
function getEnvConfig(env = process.env, base) {
|
|
2184
|
-
var _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, _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;
|
|
2199
|
+
var _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, _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;
|
|
2185
2200
|
const projectId = (_c = (_b = (_a = readString(env, "RAG_PROJECT_ID")) != null ? _a : readString(env, "NEXT_PUBLIC_PROJECT_ID")) != null ? _b : base == null ? void 0 : base.projectId) != null ? _c : "__default__";
|
|
2186
2201
|
const vectorProvider = readEnum(env, "VECTOR_DB_PROVIDER", "pinecone", VECTOR_DB_PROVIDERS);
|
|
2187
2202
|
const llmProvider = readEnum(env, "LLM_PROVIDER", "openai", LLM_PROVIDERS);
|
|
@@ -2251,7 +2266,7 @@ function getEnvConfig(env = process.env, base) {
|
|
|
2251
2266
|
rest: "default",
|
|
2252
2267
|
custom: "default"
|
|
2253
2268
|
};
|
|
2254
|
-
return {
|
|
2269
|
+
return __spreadValues({
|
|
2255
2270
|
projectId,
|
|
2256
2271
|
vectorDb: {
|
|
2257
2272
|
provider: vectorProvider,
|
|
@@ -2267,7 +2282,9 @@ function getEnvConfig(env = process.env, base) {
|
|
|
2267
2282
|
maxTokens: readNumber(env, "LLM_MAX_TOKENS", 4096),
|
|
2268
2283
|
temperature: readNumber(env, "LLM_TEMPERATURE", 0.7),
|
|
2269
2284
|
options: {
|
|
2270
|
-
profile: readString(env, "LLM_UNIVERSAL_PROFILE")
|
|
2285
|
+
profile: readString(env, "LLM_UNIVERSAL_PROFILE"),
|
|
2286
|
+
thinking: readString(env, "LLM_THINKING") === "true" || readString(env, "LLM_THINKING") === "enabled" ? true : readString(env, "LLM_THINKING") === "false" ? false : void 0,
|
|
2287
|
+
thinkingBudget: env.LLM_THINKING_BUDGET ? parseInt(env.LLM_THINKING_BUDGET, 10) : void 0
|
|
2271
2288
|
}
|
|
2272
2289
|
},
|
|
2273
2290
|
embedding: {
|
|
@@ -2299,9 +2316,34 @@ function getEnvConfig(env = process.env, base) {
|
|
|
2299
2316
|
topK: readNumber(env, "RAG_TOP_K", 5),
|
|
2300
2317
|
scoreThreshold: readNumber(env, "RAG_SCORE_THRESHOLD", 0),
|
|
2301
2318
|
chunkSize: readNumber(env, "RAG_CHUNK_SIZE", 1e3),
|
|
2302
|
-
chunkOverlap: readNumber(env, "RAG_CHUNK_OVERLAP", 200)
|
|
2319
|
+
chunkOverlap: readNumber(env, "RAG_CHUNK_OVERLAP", 200),
|
|
2320
|
+
filterableFields: (_Ha = readString(env, "RAG_FILTERABLE_FIELDS")) == null ? void 0 : _Ha.split(",").map((f) => f.trim()),
|
|
2321
|
+
// Query pipeline toggles — read from .env.local
|
|
2322
|
+
useQueryTransformation: readString(env, "RAG_USE_QUERY_TRANSFORMATION") === "true",
|
|
2323
|
+
useReranking: readString(env, "RAG_USE_RERANKING") === "true",
|
|
2324
|
+
useGraphRetrieval: readString(env, "RAG_USE_GRAPH_RETRIEVAL") === "true",
|
|
2325
|
+
architecture: (_Ia = readString(env, "RAG_ARCHITECTURE")) != null ? _Ia : "simple",
|
|
2326
|
+
chunkingStrategy: (_Ja = readString(env, "RAG_CHUNKING_STRATEGY")) != null ? _Ja : "recursive",
|
|
2327
|
+
uiMapping: (() => {
|
|
2328
|
+
const raw = readString(env, "RAG_UI_MAPPING");
|
|
2329
|
+
if (!raw) return void 0;
|
|
2330
|
+
try {
|
|
2331
|
+
return JSON.parse(raw);
|
|
2332
|
+
} catch (e) {
|
|
2333
|
+
return void 0;
|
|
2334
|
+
}
|
|
2335
|
+
})()
|
|
2303
2336
|
}
|
|
2304
|
-
}
|
|
2337
|
+
}, readString(env, "GRAPH_DB_PROVIDER") ? {
|
|
2338
|
+
graphDb: {
|
|
2339
|
+
provider: readString(env, "GRAPH_DB_PROVIDER"),
|
|
2340
|
+
options: {
|
|
2341
|
+
uri: readString(env, "GRAPH_DB_URI"),
|
|
2342
|
+
username: readString(env, "GRAPH_DB_USERNAME"),
|
|
2343
|
+
password: readString(env, "GRAPH_DB_PASSWORD")
|
|
2344
|
+
}
|
|
2345
|
+
}
|
|
2346
|
+
} : {});
|
|
2305
2347
|
}
|
|
2306
2348
|
|
|
2307
2349
|
// src/core/ConfigResolver.ts
|
|
@@ -2330,6 +2372,20 @@ var ConfigResolver = class {
|
|
|
2330
2372
|
rag: hostConfig.rag ? __spreadValues(__spreadValues({}, envConfig.rag), hostConfig.rag) : envConfig.rag
|
|
2331
2373
|
});
|
|
2332
2374
|
}
|
|
2375
|
+
/**
|
|
2376
|
+
* Resolves the public SDK config shape used by `new Retrivora({...})`.
|
|
2377
|
+
* Supports aliases from the product prompt while preserving existing env
|
|
2378
|
+
* fallback behavior.
|
|
2379
|
+
*/
|
|
2380
|
+
static resolveUniversal(hostConfig, env = process.env) {
|
|
2381
|
+
var _a;
|
|
2382
|
+
if (!hostConfig) return this.resolve(void 0, env);
|
|
2383
|
+
const normalized = __spreadProps(__spreadValues({}, hostConfig), {
|
|
2384
|
+
vectorDb: (_a = hostConfig.vectorDb) != null ? _a : hostConfig.vectorDatabase,
|
|
2385
|
+
rag: this.mergeRetrievalWorkflow(hostConfig.rag, hostConfig.retrieval, hostConfig.workflow)
|
|
2386
|
+
});
|
|
2387
|
+
return this.resolve(normalized, env);
|
|
2388
|
+
}
|
|
2333
2389
|
/**
|
|
2334
2390
|
* Validates the configuration for required fields.
|
|
2335
2391
|
*/
|
|
@@ -2344,10 +2400,53 @@ var ConfigResolver = class {
|
|
|
2344
2400
|
throw new Error("[ConfigResolver] llm.provider is required");
|
|
2345
2401
|
}
|
|
2346
2402
|
}
|
|
2403
|
+
static mergeRetrievalWorkflow(rag, retrieval, workflow) {
|
|
2404
|
+
var _a, _b, _c, _d, _e;
|
|
2405
|
+
if (!rag && !retrieval && !workflow) return void 0;
|
|
2406
|
+
const normalized = __spreadValues({}, rag != null ? rag : {});
|
|
2407
|
+
if (retrieval) {
|
|
2408
|
+
normalized.topK = (_a = retrieval.topK) != null ? _a : normalized.topK;
|
|
2409
|
+
normalized.scoreThreshold = (_b = retrieval.scoreThreshold) != null ? _b : normalized.scoreThreshold;
|
|
2410
|
+
normalized.useReranking = (_c = retrieval.useReranking) != null ? _c : normalized.useReranking;
|
|
2411
|
+
if (retrieval.strategy === "hybrid") normalized.architecture = (_d = normalized.architecture) != null ? _d : "hybrid";
|
|
2412
|
+
if (retrieval.strategy === "agentic") normalized.architecture = "agentic";
|
|
2413
|
+
if (retrieval.strategy === "contextual-compression") normalized.useReranking = true;
|
|
2414
|
+
}
|
|
2415
|
+
if (workflow == null ? void 0 : workflow.type) {
|
|
2416
|
+
const type = workflow.type;
|
|
2417
|
+
if (type === "agentic" || type === "agentic-rag") normalized.architecture = "agentic";
|
|
2418
|
+
else if (type === "hybrid-rag") normalized.architecture = "hybrid";
|
|
2419
|
+
else if (type === "graph-rag") {
|
|
2420
|
+
normalized.architecture = "graph";
|
|
2421
|
+
normalized.useGraphRetrieval = true;
|
|
2422
|
+
} else if (type === "simple-rag" || type === "rag") {
|
|
2423
|
+
normalized.architecture = (_e = normalized.architecture) != null ? _e : "simple";
|
|
2424
|
+
}
|
|
2425
|
+
}
|
|
2426
|
+
return normalized;
|
|
2427
|
+
}
|
|
2347
2428
|
};
|
|
2348
2429
|
|
|
2349
2430
|
// src/llm/providers/OpenAIProvider.ts
|
|
2350
2431
|
var import_openai = __toESM(require("openai"));
|
|
2432
|
+
|
|
2433
|
+
// src/llm/utils.ts
|
|
2434
|
+
function buildSystemContent(systemPrompt, context) {
|
|
2435
|
+
const noContext = !context || context.trim() === "" || context.trim() === "No relevant context found.";
|
|
2436
|
+
if (systemPrompt.includes("{{context}}")) {
|
|
2437
|
+
return systemPrompt.replace("{{context}}", noContext ? "" : context);
|
|
2438
|
+
}
|
|
2439
|
+
if (noContext) {
|
|
2440
|
+
return systemPrompt;
|
|
2441
|
+
}
|
|
2442
|
+
return `${systemPrompt}
|
|
2443
|
+
|
|
2444
|
+
---
|
|
2445
|
+
Context:
|
|
2446
|
+
${context}`;
|
|
2447
|
+
}
|
|
2448
|
+
|
|
2449
|
+
// src/llm/providers/OpenAIProvider.ts
|
|
2351
2450
|
var OpenAIProvider = class {
|
|
2352
2451
|
constructor(llmConfig, embeddingConfig) {
|
|
2353
2452
|
if (!llmConfig.apiKey) throw new Error("[OpenAIProvider] llmConfig.apiKey is required");
|
|
@@ -2411,16 +2510,10 @@ var OpenAIProvider = class {
|
|
|
2411
2510
|
}
|
|
2412
2511
|
async chat(messages, context, options) {
|
|
2413
2512
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
2414
|
-
const
|
|
2415
|
-
|
|
2416
|
-
Context:
|
|
2417
|
-
${context}`;
|
|
2513
|
+
const basePrompt = (_b = (_a = options == null ? void 0 : options.systemPrompt) != null ? _a : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Answer questions based on the provided context.";
|
|
2418
2514
|
const systemMessage = {
|
|
2419
2515
|
role: "system",
|
|
2420
|
-
content:
|
|
2421
|
-
|
|
2422
|
-
Context:
|
|
2423
|
-
${context}`
|
|
2516
|
+
content: buildSystemContent(basePrompt, context)
|
|
2424
2517
|
};
|
|
2425
2518
|
const formattedMessages = [
|
|
2426
2519
|
systemMessage,
|
|
@@ -2441,16 +2534,10 @@ ${context}`
|
|
|
2441
2534
|
chatStream(messages, context, options) {
|
|
2442
2535
|
return __asyncGenerator(this, null, function* () {
|
|
2443
2536
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
2444
|
-
const
|
|
2445
|
-
|
|
2446
|
-
Context:
|
|
2447
|
-
${context}`;
|
|
2537
|
+
const basePrompt = (_b = (_a = options == null ? void 0 : options.systemPrompt) != null ? _a : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Answer questions based on the provided context.";
|
|
2448
2538
|
const systemMessage = {
|
|
2449
2539
|
role: "system",
|
|
2450
|
-
content:
|
|
2451
|
-
|
|
2452
|
-
Context:
|
|
2453
|
-
${context}`
|
|
2540
|
+
content: buildSystemContent(basePrompt, context)
|
|
2454
2541
|
};
|
|
2455
2542
|
const formattedMessages = [
|
|
2456
2543
|
systemMessage,
|
|
@@ -2571,58 +2658,87 @@ var AnthropicProvider = class {
|
|
|
2571
2658
|
};
|
|
2572
2659
|
}
|
|
2573
2660
|
async chat(messages, context, options) {
|
|
2574
|
-
var _a, _b, _c, _d;
|
|
2575
|
-
const
|
|
2576
|
-
|
|
2577
|
-
Context:
|
|
2578
|
-
${context}`;
|
|
2579
|
-
const system = resolvedPrompt.includes("{{context}}") ? resolvedPrompt.replace("{{context}}", context) : (options == null ? void 0 : options.systemPrompt) ? resolvedPrompt : `${resolvedPrompt}
|
|
2580
|
-
|
|
2581
|
-
Context:
|
|
2582
|
-
${context}`;
|
|
2661
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
2662
|
+
const basePrompt = (_b = (_a = options == null ? void 0 : options.systemPrompt) != null ? _a : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Use the context below to answer the user's question accurately.";
|
|
2663
|
+
const system = buildSystemContent(basePrompt, context);
|
|
2583
2664
|
const anthropicMessages = messages.map((m) => ({
|
|
2584
2665
|
role: m.role === "assistant" ? "assistant" : "user",
|
|
2585
2666
|
content: m.content
|
|
2586
2667
|
}));
|
|
2587
|
-
const
|
|
2668
|
+
const isClaude37 = this.llmConfig.model.includes("claude-3-7-sonnet");
|
|
2669
|
+
const isThinkingEnabled = ((_c = this.llmConfig.options) == null ? void 0 : _c.thinking) === true || ((_d = this.llmConfig.options) == null ? void 0 : _d.thinking) === "enabled" || isClaude37 && ((_e = this.llmConfig.options) == null ? void 0 : _e.thinking) !== false;
|
|
2670
|
+
const extraParams = {};
|
|
2671
|
+
if (isThinkingEnabled && isClaude37) {
|
|
2672
|
+
extraParams.betas = ["interleaved-thinking-2025-05-14"];
|
|
2673
|
+
const maxTokens = (_g = (_f = options == null ? void 0 : options.maxTokens) != null ? _f : this.llmConfig.maxTokens) != null ? _g : 4096;
|
|
2674
|
+
const budget = Math.min(
|
|
2675
|
+
typeof ((_h = this.llmConfig.options) == null ? void 0 : _h.thinkingBudget) === "number" ? (_i = this.llmConfig.options) == null ? void 0 : _i.thinkingBudget : 2048,
|
|
2676
|
+
maxTokens - 1
|
|
2677
|
+
);
|
|
2678
|
+
extraParams.thinking = {
|
|
2679
|
+
type: "enabled",
|
|
2680
|
+
budget_tokens: budget
|
|
2681
|
+
};
|
|
2682
|
+
extraParams.max_tokens = Math.max(maxTokens, budget + 1024);
|
|
2683
|
+
}
|
|
2684
|
+
const response = await this.client.messages.create(__spreadValues({
|
|
2588
2685
|
model: this.llmConfig.model,
|
|
2589
|
-
max_tokens: (
|
|
2686
|
+
max_tokens: (_k = (_j = options == null ? void 0 : options.maxTokens) != null ? _j : this.llmConfig.maxTokens) != null ? _k : 1024,
|
|
2590
2687
|
system,
|
|
2591
2688
|
messages: anthropicMessages
|
|
2592
|
-
});
|
|
2593
|
-
|
|
2594
|
-
|
|
2689
|
+
}, extraParams));
|
|
2690
|
+
let reply = "";
|
|
2691
|
+
for (const block of response.content) {
|
|
2692
|
+
if (block.type === "text") {
|
|
2693
|
+
reply += block.text;
|
|
2694
|
+
}
|
|
2695
|
+
}
|
|
2696
|
+
return reply;
|
|
2595
2697
|
}
|
|
2596
2698
|
chatStream(messages, context, options) {
|
|
2597
2699
|
return __asyncGenerator(this, null, function* () {
|
|
2598
|
-
var _a, _b, _c, _d;
|
|
2599
|
-
const
|
|
2600
|
-
|
|
2601
|
-
Context:
|
|
2602
|
-
${context}`;
|
|
2603
|
-
const system = resolvedPrompt.includes("{{context}}") ? resolvedPrompt.replace("{{context}}", context) : (options == null ? void 0 : options.systemPrompt) ? resolvedPrompt : `${resolvedPrompt}
|
|
2604
|
-
|
|
2605
|
-
Context:
|
|
2606
|
-
${context}`;
|
|
2700
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
2701
|
+
const basePrompt = (_b = (_a = options == null ? void 0 : options.systemPrompt) != null ? _a : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Use the context below to answer the user's question accurately.";
|
|
2702
|
+
const system = buildSystemContent(basePrompt, context);
|
|
2607
2703
|
const anthropicMessages = messages.map((m) => ({
|
|
2608
2704
|
role: m.role === "assistant" ? "assistant" : "user",
|
|
2609
2705
|
content: m.content
|
|
2610
2706
|
}));
|
|
2611
|
-
const
|
|
2707
|
+
const isClaude37 = this.llmConfig.model.includes("claude-3-7-sonnet");
|
|
2708
|
+
const isThinkingEnabled = ((_c = this.llmConfig.options) == null ? void 0 : _c.thinking) === true || ((_d = this.llmConfig.options) == null ? void 0 : _d.thinking) === "enabled" || isClaude37 && ((_e = this.llmConfig.options) == null ? void 0 : _e.thinking) !== false;
|
|
2709
|
+
const extraParams = {};
|
|
2710
|
+
if (isThinkingEnabled && isClaude37) {
|
|
2711
|
+
extraParams.betas = ["interleaved-thinking-2025-05-14"];
|
|
2712
|
+
const maxTokens = (_g = (_f = options == null ? void 0 : options.maxTokens) != null ? _f : this.llmConfig.maxTokens) != null ? _g : 4096;
|
|
2713
|
+
const budget = Math.min(
|
|
2714
|
+
typeof ((_h = this.llmConfig.options) == null ? void 0 : _h.thinkingBudget) === "number" ? (_i = this.llmConfig.options) == null ? void 0 : _i.thinkingBudget : 2048,
|
|
2715
|
+
maxTokens - 1
|
|
2716
|
+
);
|
|
2717
|
+
extraParams.thinking = {
|
|
2718
|
+
type: "enabled",
|
|
2719
|
+
budget_tokens: budget
|
|
2720
|
+
};
|
|
2721
|
+
extraParams.max_tokens = Math.max(maxTokens, budget + 1024);
|
|
2722
|
+
}
|
|
2723
|
+
const stream = yield new __await(this.client.messages.create(__spreadValues({
|
|
2612
2724
|
model: this.llmConfig.model,
|
|
2613
|
-
max_tokens: (
|
|
2725
|
+
max_tokens: (_k = (_j = options == null ? void 0 : options.maxTokens) != null ? _j : this.llmConfig.maxTokens) != null ? _k : 1024,
|
|
2614
2726
|
system,
|
|
2615
2727
|
messages: anthropicMessages,
|
|
2616
2728
|
stream: true
|
|
2617
|
-
}));
|
|
2729
|
+
}, extraParams)));
|
|
2618
2730
|
if (!stream) {
|
|
2619
2731
|
throw new Error("[AnthropicProvider] messages.create stream is undefined");
|
|
2620
2732
|
}
|
|
2621
2733
|
try {
|
|
2622
2734
|
for (var iter = __forAwait(stream), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
|
|
2623
2735
|
const chunk = temp.value;
|
|
2624
|
-
if (chunk.type === "content_block_delta"
|
|
2625
|
-
|
|
2736
|
+
if (chunk.type === "content_block_delta") {
|
|
2737
|
+
if (chunk.delta.type === "text_delta") {
|
|
2738
|
+
yield chunk.delta.text;
|
|
2739
|
+
} else if (chunk.delta.type === "thinking_delta") {
|
|
2740
|
+
yield `\0THINKING\0${chunk.delta.thinking}`;
|
|
2741
|
+
}
|
|
2626
2742
|
}
|
|
2627
2743
|
}
|
|
2628
2744
|
} catch (temp) {
|
|
@@ -2666,9 +2782,10 @@ ${context}`;
|
|
|
2666
2782
|
var import_axios = __toESM(require("axios"));
|
|
2667
2783
|
var OllamaProvider = class {
|
|
2668
2784
|
constructor(llmConfig, embeddingConfig) {
|
|
2669
|
-
var _a;
|
|
2785
|
+
var _a, _b;
|
|
2670
2786
|
const baseURL = (_a = llmConfig.baseUrl) != null ? _a : "http://localhost:11434";
|
|
2671
|
-
|
|
2787
|
+
const timeout = Number((_b = llmConfig.options) == null ? void 0 : _b.timeout) || 3e5;
|
|
2788
|
+
this.http = import_axios.default.create({ baseURL, timeout });
|
|
2672
2789
|
this.llmConfig = llmConfig;
|
|
2673
2790
|
this.embeddingConfig = embeddingConfig;
|
|
2674
2791
|
}
|
|
@@ -2724,14 +2841,15 @@ var OllamaProvider = class {
|
|
|
2724
2841
|
};
|
|
2725
2842
|
}
|
|
2726
2843
|
async chat(messages, context, options) {
|
|
2727
|
-
var _a, _b, _c, _d;
|
|
2728
|
-
const
|
|
2844
|
+
var _a, _b, _c, _d, _e, _f;
|
|
2845
|
+
const basePrompt = (_b = (_a = options == null ? void 0 : options.systemPrompt) != null ? _a : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Use the provided context to answer the user's question.";
|
|
2846
|
+
const system = buildSystemContent(basePrompt, context);
|
|
2729
2847
|
const { data } = await this.http.post("/api/chat", {
|
|
2730
2848
|
model: this.llmConfig.model,
|
|
2731
2849
|
stream: false,
|
|
2732
2850
|
options: {
|
|
2733
|
-
temperature: (
|
|
2734
|
-
num_predict: (
|
|
2851
|
+
temperature: (_d = (_c = options == null ? void 0 : options.temperature) != null ? _c : this.llmConfig.temperature) != null ? _d : 0.7,
|
|
2852
|
+
num_predict: (_f = (_e = options == null ? void 0 : options.maxTokens) != null ? _e : this.llmConfig.maxTokens) != null ? _f : 1024
|
|
2735
2853
|
},
|
|
2736
2854
|
messages: [
|
|
2737
2855
|
{ role: "system", content: system },
|
|
@@ -2742,14 +2860,15 @@ var OllamaProvider = class {
|
|
|
2742
2860
|
}
|
|
2743
2861
|
chatStream(messages, context, options) {
|
|
2744
2862
|
return __asyncGenerator(this, null, function* () {
|
|
2745
|
-
var _a, _b, _c, _d, _e, _f;
|
|
2746
|
-
const
|
|
2863
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
2864
|
+
const basePrompt = (_b = (_a = options == null ? void 0 : options.systemPrompt) != null ? _a : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Use the provided context to answer the user's question.";
|
|
2865
|
+
const system = buildSystemContent(basePrompt, context);
|
|
2747
2866
|
const response = yield new __await(this.http.post("/api/chat", {
|
|
2748
2867
|
model: this.llmConfig.model,
|
|
2749
2868
|
stream: true,
|
|
2750
2869
|
options: {
|
|
2751
|
-
temperature: (
|
|
2752
|
-
num_predict: (
|
|
2870
|
+
temperature: (_d = (_c = options == null ? void 0 : options.temperature) != null ? _c : this.llmConfig.temperature) != null ? _d : 0.7,
|
|
2871
|
+
num_predict: (_f = (_e = options == null ? void 0 : options.maxTokens) != null ? _e : this.llmConfig.maxTokens) != null ? _f : 1024
|
|
2753
2872
|
},
|
|
2754
2873
|
messages: [
|
|
2755
2874
|
{ role: "system", content: system },
|
|
@@ -2771,7 +2890,7 @@ var OllamaProvider = class {
|
|
|
2771
2890
|
if (!line.trim()) continue;
|
|
2772
2891
|
try {
|
|
2773
2892
|
const json = JSON.parse(line);
|
|
2774
|
-
if ((
|
|
2893
|
+
if ((_g = json.message) == null ? void 0 : _g.content) {
|
|
2775
2894
|
yield json.message.content;
|
|
2776
2895
|
}
|
|
2777
2896
|
if (json.done) return;
|
|
@@ -2793,26 +2912,12 @@ var OllamaProvider = class {
|
|
|
2793
2912
|
if (lineBuffer.trim()) {
|
|
2794
2913
|
try {
|
|
2795
2914
|
const json = JSON.parse(lineBuffer);
|
|
2796
|
-
if ((
|
|
2915
|
+
if ((_h = json.message) == null ? void 0 : _h.content) yield json.message.content;
|
|
2797
2916
|
} catch (e) {
|
|
2798
2917
|
}
|
|
2799
2918
|
}
|
|
2800
2919
|
});
|
|
2801
2920
|
}
|
|
2802
|
-
buildSystemPrompt(context, overridePrompt) {
|
|
2803
|
-
var _a;
|
|
2804
|
-
if (overridePrompt) {
|
|
2805
|
-
return overridePrompt;
|
|
2806
|
-
}
|
|
2807
|
-
const systemPrompt = (_a = this.llmConfig.systemPrompt) != null ? _a : `You are a helpful assistant. Use the provided context to answer the user's question.
|
|
2808
|
-
|
|
2809
|
-
Context:
|
|
2810
|
-
${context}`;
|
|
2811
|
-
return systemPrompt.includes("{{context}}") ? systemPrompt.replace("{{context}}", context) : `${systemPrompt}
|
|
2812
|
-
|
|
2813
|
-
Context:
|
|
2814
|
-
${context}`;
|
|
2815
|
-
}
|
|
2816
2921
|
async embed(text, options) {
|
|
2817
2922
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
2818
2923
|
const model = (_c = (_b = options == null ? void 0 : options.model) != null ? _b : (_a = this.embeddingConfig) == null ? void 0 : _a.model) != null ? _c : "nomic-embed-text";
|
|
@@ -2959,21 +3064,6 @@ var GeminiProvider = class {
|
|
|
2959
3064
|
var _a, _b;
|
|
2960
3065
|
return sanitizeModel((_b = optionsModel != null ? optionsModel : (_a = this.embeddingConfig) == null ? void 0 : _a.model) != null ? _b : DEFAULT_EMBEDDING_MODEL);
|
|
2961
3066
|
}
|
|
2962
|
-
/**
|
|
2963
|
-
* Build the system instruction string, inserting the RAG context either via
|
|
2964
|
-
* the `{{context}}` placeholder or by appending it.
|
|
2965
|
-
*/
|
|
2966
|
-
buildSystemInstruction(context) {
|
|
2967
|
-
var _a;
|
|
2968
|
-
const base = (_a = this.llmConfig.systemPrompt) != null ? _a : `You are a helpful assistant. Answer questions based on the provided context.
|
|
2969
|
-
|
|
2970
|
-
Context:
|
|
2971
|
-
${context}`;
|
|
2972
|
-
return base.includes("{{context}}") ? base.replace("{{context}}", context) : `${base}
|
|
2973
|
-
|
|
2974
|
-
Context:
|
|
2975
|
-
${context}`;
|
|
2976
|
-
}
|
|
2977
3067
|
/**
|
|
2978
3068
|
* Convert ChatMessage[] to the Gemini contents format.
|
|
2979
3069
|
*
|
|
@@ -2992,16 +3082,17 @@ ${context}`;
|
|
|
2992
3082
|
// ILLMProvider — chat
|
|
2993
3083
|
// -------------------------------------------------------------------------
|
|
2994
3084
|
async chat(messages, context, options) {
|
|
2995
|
-
var _a, _b, _c, _d;
|
|
3085
|
+
var _a, _b, _c, _d, _e, _f;
|
|
3086
|
+
const basePrompt = (_b = (_a = options == null ? void 0 : options.systemPrompt) != null ? _a : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Answer questions based on the provided context.";
|
|
2996
3087
|
const model = this.client.getGenerativeModel({
|
|
2997
3088
|
model: this.llmConfig.model,
|
|
2998
|
-
systemInstruction:
|
|
3089
|
+
systemInstruction: buildSystemContent(basePrompt, context)
|
|
2999
3090
|
});
|
|
3000
3091
|
const result = await model.generateContent({
|
|
3001
3092
|
contents: this.buildGeminiContents(messages),
|
|
3002
3093
|
generationConfig: {
|
|
3003
|
-
temperature: (
|
|
3004
|
-
maxOutputTokens: (
|
|
3094
|
+
temperature: (_d = (_c = options == null ? void 0 : options.temperature) != null ? _c : this.llmConfig.temperature) != null ? _d : DEFAULT_TEMPERATURE,
|
|
3095
|
+
maxOutputTokens: (_f = (_e = options == null ? void 0 : options.maxTokens) != null ? _e : this.llmConfig.maxTokens) != null ? _f : DEFAULT_MAX_TOKENS,
|
|
3005
3096
|
stopSequences: options == null ? void 0 : options.stop
|
|
3006
3097
|
}
|
|
3007
3098
|
});
|
|
@@ -3009,16 +3100,17 @@ ${context}`;
|
|
|
3009
3100
|
}
|
|
3010
3101
|
chatStream(messages, context, options) {
|
|
3011
3102
|
return __asyncGenerator(this, null, function* () {
|
|
3012
|
-
var _a, _b, _c, _d;
|
|
3103
|
+
var _a, _b, _c, _d, _e, _f;
|
|
3104
|
+
const basePrompt = (_b = (_a = options == null ? void 0 : options.systemPrompt) != null ? _a : this.llmConfig.systemPrompt) != null ? _b : "You are a helpful assistant. Answer questions based on the provided context.";
|
|
3013
3105
|
const model = this.client.getGenerativeModel({
|
|
3014
3106
|
model: this.llmConfig.model,
|
|
3015
|
-
systemInstruction:
|
|
3107
|
+
systemInstruction: buildSystemContent(basePrompt, context)
|
|
3016
3108
|
});
|
|
3017
3109
|
const result = yield new __await(model.generateContentStream({
|
|
3018
3110
|
contents: this.buildGeminiContents(messages),
|
|
3019
3111
|
generationConfig: {
|
|
3020
|
-
temperature: (
|
|
3021
|
-
maxOutputTokens: (
|
|
3112
|
+
temperature: (_d = (_c = options == null ? void 0 : options.temperature) != null ? _c : this.llmConfig.temperature) != null ? _d : DEFAULT_TEMPERATURE,
|
|
3113
|
+
maxOutputTokens: (_f = (_e = options == null ? void 0 : options.maxTokens) != null ? _e : this.llmConfig.maxTokens) != null ? _f : DEFAULT_MAX_TOKENS,
|
|
3022
3114
|
stopSequences: options == null ? void 0 : options.stop
|
|
3023
3115
|
}
|
|
3024
3116
|
}));
|
|
@@ -3385,6 +3477,78 @@ ${context != null ? context : "None"}` },
|
|
|
3385
3477
|
}
|
|
3386
3478
|
};
|
|
3387
3479
|
|
|
3480
|
+
// src/exceptions/index.ts
|
|
3481
|
+
var RetrivoraError = class extends Error {
|
|
3482
|
+
constructor(message, code, details) {
|
|
3483
|
+
super(message);
|
|
3484
|
+
this.name = new.target.name;
|
|
3485
|
+
this.code = code;
|
|
3486
|
+
this.details = details;
|
|
3487
|
+
}
|
|
3488
|
+
};
|
|
3489
|
+
var ProviderNotFoundException = class extends RetrivoraError {
|
|
3490
|
+
constructor(providerType, provider, details) {
|
|
3491
|
+
super(`Unsupported ${providerType} provider: ${provider}`, "PROVIDER_NOT_FOUND", details);
|
|
3492
|
+
}
|
|
3493
|
+
};
|
|
3494
|
+
var EmbeddingFailedException = class extends RetrivoraError {
|
|
3495
|
+
constructor(message = "Embedding generation failed", details) {
|
|
3496
|
+
super(message, "EMBEDDING_FAILED", details);
|
|
3497
|
+
}
|
|
3498
|
+
};
|
|
3499
|
+
var RetrievalException = class extends RetrivoraError {
|
|
3500
|
+
constructor(message = "Retrieval failed", details) {
|
|
3501
|
+
super(message, "RETRIEVAL_FAILED", details);
|
|
3502
|
+
}
|
|
3503
|
+
};
|
|
3504
|
+
var RateLimitException = class extends RetrivoraError {
|
|
3505
|
+
constructor(message = "Provider rate limit exceeded", details) {
|
|
3506
|
+
super(message, "RATE_LIMITED", details);
|
|
3507
|
+
}
|
|
3508
|
+
};
|
|
3509
|
+
var ConfigurationException = class extends RetrivoraError {
|
|
3510
|
+
constructor(message, details) {
|
|
3511
|
+
super(message, "CONFIGURATION_ERROR", details);
|
|
3512
|
+
}
|
|
3513
|
+
};
|
|
3514
|
+
var AuthenticationException = class extends RetrivoraError {
|
|
3515
|
+
constructor(message = "Provider authentication failed", details) {
|
|
3516
|
+
super(message, "AUTHENTICATION_ERROR", details);
|
|
3517
|
+
}
|
|
3518
|
+
};
|
|
3519
|
+
function wrapError(err, defaultCode, defaultMessage) {
|
|
3520
|
+
var _a;
|
|
3521
|
+
if (err instanceof RetrivoraError) {
|
|
3522
|
+
return err;
|
|
3523
|
+
}
|
|
3524
|
+
const error = err;
|
|
3525
|
+
const message = (error == null ? void 0 : error.message) || defaultMessage || String(err);
|
|
3526
|
+
const status = (error == null ? void 0 : error.status) || (error == null ? void 0 : error.statusCode) || ((_a = error == null ? void 0 : error.response) == null ? void 0 : _a.status);
|
|
3527
|
+
const code = error == null ? void 0 : error.code;
|
|
3528
|
+
if (status === 429 || /rate[- ]?limit/i.test(message) || code === "RATE_LIMIT_EXCEEDED") {
|
|
3529
|
+
return new RateLimitException(message, err);
|
|
3530
|
+
}
|
|
3531
|
+
if (status === 401 || status === 403 || /unauthorized|auth|api[- ]?key/i.test(message) || code === "INVALID_API_KEY") {
|
|
3532
|
+
return new AuthenticationException(message, err);
|
|
3533
|
+
}
|
|
3534
|
+
switch (defaultCode) {
|
|
3535
|
+
case "PROVIDER_NOT_FOUND":
|
|
3536
|
+
return new ProviderNotFoundException("provider", message, err);
|
|
3537
|
+
case "EMBEDDING_FAILED":
|
|
3538
|
+
return new EmbeddingFailedException(message, err);
|
|
3539
|
+
case "RETRIEVAL_FAILED":
|
|
3540
|
+
return new RetrievalException(message, err);
|
|
3541
|
+
case "RATE_LIMITED":
|
|
3542
|
+
return new RateLimitException(message, err);
|
|
3543
|
+
case "CONFIGURATION_ERROR":
|
|
3544
|
+
return new ConfigurationException(message, err);
|
|
3545
|
+
case "AUTHENTICATION_ERROR":
|
|
3546
|
+
return new AuthenticationException(message, err);
|
|
3547
|
+
default:
|
|
3548
|
+
return new RetrivoraError(message, defaultCode, err);
|
|
3549
|
+
}
|
|
3550
|
+
}
|
|
3551
|
+
|
|
3388
3552
|
// src/llm/LLMFactory.ts
|
|
3389
3553
|
var customProviders = /* @__PURE__ */ new Map();
|
|
3390
3554
|
var LLMFactory = class _LLMFactory {
|
|
@@ -3430,7 +3594,7 @@ var LLMFactory = class _LLMFactory {
|
|
|
3430
3594
|
];
|
|
3431
3595
|
}
|
|
3432
3596
|
static create(llmConfig, embeddingConfig) {
|
|
3433
|
-
var _a, _b;
|
|
3597
|
+
var _a, _b, _c;
|
|
3434
3598
|
switch (llmConfig.provider) {
|
|
3435
3599
|
case "openai":
|
|
3436
3600
|
return new OpenAIProvider(llmConfig, embeddingConfig);
|
|
@@ -3453,8 +3617,13 @@ var LLMFactory = class _LLMFactory {
|
|
|
3453
3617
|
if (llmConfig.baseUrl || ((_b = llmConfig.options) == null ? void 0 : _b.baseUrl)) {
|
|
3454
3618
|
return new UniversalLLMAdapter(llmConfig);
|
|
3455
3619
|
}
|
|
3456
|
-
throw new
|
|
3457
|
-
|
|
3620
|
+
throw new ProviderNotFoundException(
|
|
3621
|
+
"llm",
|
|
3622
|
+
(_c = llmConfig.provider) != null ? _c : "undefined",
|
|
3623
|
+
{
|
|
3624
|
+
message: `Unknown provider "${llmConfig.provider}". Register a custom provider with LLMFactory.register().`,
|
|
3625
|
+
available: _LLMFactory.listProviders()
|
|
3626
|
+
}
|
|
3458
3627
|
);
|
|
3459
3628
|
}
|
|
3460
3629
|
}
|
|
@@ -3585,7 +3754,7 @@ var ProviderRegistry = class {
|
|
|
3585
3754
|
return UniversalVectorProvider2;
|
|
3586
3755
|
}
|
|
3587
3756
|
default:
|
|
3588
|
-
throw new
|
|
3757
|
+
throw new ProviderNotFoundException("vector", provider);
|
|
3589
3758
|
}
|
|
3590
3759
|
}
|
|
3591
3760
|
static async createVectorProvider(config) {
|
|
@@ -3603,12 +3772,18 @@ var ProviderRegistry = class {
|
|
|
3603
3772
|
return new SimpleGraphProvider2(config);
|
|
3604
3773
|
}
|
|
3605
3774
|
default:
|
|
3606
|
-
throw new
|
|
3775
|
+
throw new ProviderNotFoundException("graph", provider);
|
|
3607
3776
|
}
|
|
3608
3777
|
}
|
|
3609
3778
|
static createLLMProvider(llmConfig, embeddingConfig) {
|
|
3610
3779
|
return LLMFactory.create(llmConfig, embeddingConfig);
|
|
3611
3780
|
}
|
|
3781
|
+
static registerLLMProvider(name, factory) {
|
|
3782
|
+
LLMFactory.register(name, factory);
|
|
3783
|
+
}
|
|
3784
|
+
static createEmbeddingProvider(embeddingConfig) {
|
|
3785
|
+
return LLMFactory.createEmbeddingProvider(embeddingConfig);
|
|
3786
|
+
}
|
|
3612
3787
|
};
|
|
3613
3788
|
ProviderRegistry.vectorProviders = {};
|
|
3614
3789
|
ProviderRegistry.graphProviders = {};
|
|
@@ -3755,8 +3930,8 @@ var ConfigValidator = class {
|
|
|
3755
3930
|
const errorItems = errors.filter((e) => e.severity === "error");
|
|
3756
3931
|
if (errorItems.length > 0) {
|
|
3757
3932
|
const message = errorItems.map((e) => `${e.field}: ${e.message}${e.suggestion ? ` (${e.suggestion})` : ""}`).join("\n ");
|
|
3758
|
-
throw new
|
|
3759
|
-
${message}
|
|
3933
|
+
throw new ConfigurationException(`[ConfigValidator] Configuration validation failed:
|
|
3934
|
+
${message}`, errorItems);
|
|
3760
3935
|
}
|
|
3761
3936
|
}
|
|
3762
3937
|
};
|
|
@@ -3943,20 +4118,17 @@ var Reranker = class {
|
|
|
3943
4118
|
}
|
|
3944
4119
|
try {
|
|
3945
4120
|
const topN = matches.slice(0, 10);
|
|
3946
|
-
const
|
|
3947
|
-
|
|
3948
|
-
Return the result as a comma-separated list of document indices in order of relevance, from most relevant to least relevant.
|
|
3949
|
-
Use the indices provided in brackets like [0], [1], etc.
|
|
3950
|
-
Only return the indices (e.g., "2,0,1"), nothing else. Do not include brackets in the output.
|
|
3951
|
-
|
|
3952
|
-
Query: "${query}"
|
|
4121
|
+
const response = await llm.chat(
|
|
4122
|
+
[{ role: "user", content: `Query: "${query}"
|
|
3953
4123
|
|
|
3954
4124
|
Documents:
|
|
3955
|
-
${topN.map((m, i) => `[${i}] ${m.content.replace(/\n/g, " ")}`).join("\n")}
|
|
3956
|
-
const response = await llm.chat(
|
|
3957
|
-
[{ role: "user", content: prompt }],
|
|
4125
|
+
${topN.map((m, i) => `[${i}] ${m.content.replace(/\n/g, " ")}`).join("\n")}` }],
|
|
3958
4126
|
"",
|
|
3959
|
-
{
|
|
4127
|
+
{
|
|
4128
|
+
systemPrompt: 'You are a relevance ranking expert. Given the user query and a list of retrieved document chunks, rank the chunks by relevance to the query. Return the result as a comma-separated list of document indices in order of relevance, from most relevant to least relevant. Use the indices provided in brackets like [0], [1], etc. Only return the indices (e.g., "2,0,1"), nothing else. Do not include brackets in the output.',
|
|
4129
|
+
temperature: 0,
|
|
4130
|
+
maxTokens: 50
|
|
4131
|
+
}
|
|
3960
4132
|
);
|
|
3961
4133
|
const cleanedResponse = response.trim().replace(/[\[\]\s]/g, "");
|
|
3962
4134
|
const rankedIndices = cleanedResponse.split(",").map(Number).filter((n) => !isNaN(n));
|
|
@@ -4468,6 +4640,18 @@ var QueryProcessor = class {
|
|
|
4468
4640
|
}, normalizedField ? { field: normalizedField } : {}));
|
|
4469
4641
|
}
|
|
4470
4642
|
};
|
|
4643
|
+
const activeValidFields = validFields.length > 0 ? validFields : ["brand", "category", "price", "rating", "stock", "stock_quantity", "status", "name", "title"];
|
|
4644
|
+
const resolveValidField = (fieldStr) => {
|
|
4645
|
+
const cleaned = this.normalizeHintValue(fieldStr).replace(/\b(?:provide|show|get|give|list|all|the|a|an|of|organizations?|companies?|records?|items?|whose|with|having|where|that|which|have|has|is|are|was|were)\b/gi, " ").replace(/\s+/g, " ").trim();
|
|
4646
|
+
const comparable = (v) => v.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
4647
|
+
const cleanedComparable = comparable(cleaned);
|
|
4648
|
+
if (!cleanedComparable) return null;
|
|
4649
|
+
const matchedField = activeValidFields.find((fieldName) => {
|
|
4650
|
+
const candidate = comparable(fieldName);
|
|
4651
|
+
return candidate === cleanedComparable || candidate.includes(cleanedComparable) || cleanedComparable.includes(candidate);
|
|
4652
|
+
});
|
|
4653
|
+
return matchedField != null ? matchedField : null;
|
|
4654
|
+
};
|
|
4471
4655
|
for (const match of question.matchAll(/["']([^"']{2,100})["']/g)) {
|
|
4472
4656
|
addHint(match[1]);
|
|
4473
4657
|
}
|
|
@@ -4492,7 +4676,13 @@ var QueryProcessor = class {
|
|
|
4492
4676
|
const field = match[1];
|
|
4493
4677
|
const value = match[2];
|
|
4494
4678
|
if (field && !this.isLikelyPromptPhrase(field)) {
|
|
4495
|
-
|
|
4679
|
+
const resolvedField = resolveValidField(field);
|
|
4680
|
+
if (resolvedField) {
|
|
4681
|
+
addHint(value, resolvedField);
|
|
4682
|
+
} else {
|
|
4683
|
+
addHint(value);
|
|
4684
|
+
addHint(field);
|
|
4685
|
+
}
|
|
4496
4686
|
}
|
|
4497
4687
|
}
|
|
4498
4688
|
if (validFields.length > 0) {
|
|
@@ -4538,12 +4728,16 @@ var QueryProcessor = class {
|
|
|
4538
4728
|
];
|
|
4539
4729
|
for (const pattern of fieldValuePatterns) {
|
|
4540
4730
|
for (const match of question.matchAll(pattern)) {
|
|
4541
|
-
const field =
|
|
4731
|
+
const field = (_c = match[1]) != null ? _c : "";
|
|
4542
4732
|
const value = (_d = match[2]) != null ? _d : "";
|
|
4543
|
-
|
|
4544
|
-
|
|
4733
|
+
const resolvedField = resolveValidField(field);
|
|
4734
|
+
if (resolvedField) {
|
|
4735
|
+
addHint(value, resolvedField);
|
|
4545
4736
|
} else {
|
|
4546
4737
|
addHint(value);
|
|
4738
|
+
if (field && !this.isLikelyPromptPhrase(field)) {
|
|
4739
|
+
addHint(field);
|
|
4740
|
+
}
|
|
4547
4741
|
}
|
|
4548
4742
|
}
|
|
4549
4743
|
}
|
|
@@ -4770,7 +4964,7 @@ var LLMRouter = class {
|
|
|
4770
4964
|
|
|
4771
4965
|
// src/utils/UITransformer.ts
|
|
4772
4966
|
init_synonyms();
|
|
4773
|
-
var UITransformer = class {
|
|
4967
|
+
var UITransformer = class _UITransformer {
|
|
4774
4968
|
// ─── Public Entry Points ─────────────────────────────────────────────────
|
|
4775
4969
|
/**
|
|
4776
4970
|
* Heuristic-only transform (no LLM required).
|
|
@@ -4832,7 +5026,7 @@ var UITransformer = class {
|
|
|
4832
5026
|
static async analyzeAndDecide(query, sources, llm) {
|
|
4833
5027
|
let intent;
|
|
4834
5028
|
try {
|
|
4835
|
-
intent = await this.detectIntent(query, llm);
|
|
5029
|
+
intent = await this.detectIntent(query, llm, sources);
|
|
4836
5030
|
console.debug("[UITransformer] Detected intent:", intent);
|
|
4837
5031
|
} catch (err) {
|
|
4838
5032
|
console.warn("[UITransformer] Intent detection failed; using heuristic.", err);
|
|
@@ -4850,11 +5044,23 @@ var UITransformer = class {
|
|
|
4850
5044
|
try {
|
|
4851
5045
|
const context = this.buildContextSummary(sources);
|
|
4852
5046
|
const systemPrompt = this.buildVisualizationSystemPrompt();
|
|
5047
|
+
const profile = this.profileData(sources);
|
|
5048
|
+
const schemaContext = `
|
|
5049
|
+
RETRIEVED DATA SCHEMA:
|
|
5050
|
+
- Numeric fields (measures): ${profile.numericFields.map((f) => `${f.key} (unique values: ${f.uniqueCount})`).join(", ") || "None"}
|
|
5051
|
+
- Category fields (dimensions): ${profile.categoricalFields.map((f) => `${f.key} (unique values: ${f.uniqueCount})`).join(", ") || "None"}
|
|
5052
|
+
- Date fields (temporal): ${profile.dateFields.map((f) => `${f.key} (unique values: ${f.uniqueCount})`).join(", ") || "None"}
|
|
5053
|
+
- Boolean fields: ${profile.booleanFields.map((f) => `${f.key} (unique values: ${f.uniqueCount})`).join(", ") || "None"}
|
|
5054
|
+
- Text/Other fields: ${profile.fields.filter((f) => f.kind === "text").map((f) => f.key).join(", ") || "None"}
|
|
5055
|
+
`;
|
|
4853
5056
|
const userPrompt = [
|
|
4854
5057
|
`USER QUESTION: ${query}`,
|
|
4855
5058
|
"",
|
|
4856
5059
|
`DETECTED INTENT (JSON): ${JSON.stringify(intent)}`,
|
|
4857
5060
|
"",
|
|
5061
|
+
`RETRIEVED DATA SCHEMA:`,
|
|
5062
|
+
schemaContext,
|
|
5063
|
+
"",
|
|
4858
5064
|
"RETRIEVED DATA (JSON):",
|
|
4859
5065
|
context
|
|
4860
5066
|
].join("\n");
|
|
@@ -4865,6 +5071,20 @@ var UITransformer = class {
|
|
|
4865
5071
|
);
|
|
4866
5072
|
const parsed = this.parseTransformationResponse(rawResponse);
|
|
4867
5073
|
if (parsed) {
|
|
5074
|
+
let isCompatible = true;
|
|
5075
|
+
if (parsed.type === "line_chart" && (profile.dateFields.length === 0 || profile.numericFields.length === 0)) {
|
|
5076
|
+
isCompatible = false;
|
|
5077
|
+
} else if (["bar_chart", "horizontal_bar", "pie_chart", "donut_chart"].includes(parsed.type) && (profile.categoricalFields.length === 0 && profile.numericFields.length === 0)) {
|
|
5078
|
+
isCompatible = false;
|
|
5079
|
+
} else if (parsed.type === "scatter_plot" && profile.numericFields.length < 2) {
|
|
5080
|
+
isCompatible = false;
|
|
5081
|
+
} else if (parsed.type === "metric_card" && profile.numericFields.length === 0) {
|
|
5082
|
+
isCompatible = false;
|
|
5083
|
+
}
|
|
5084
|
+
if (!isCompatible) {
|
|
5085
|
+
console.warn(`[UITransformer] LLM chose incompatible visualization type "${parsed.type}" for retrieved schema. Falling back to heuristic.`);
|
|
5086
|
+
return this.transform(query, sources, void 0, void 0, intent);
|
|
5087
|
+
}
|
|
4868
5088
|
const intentAllowsTable = intent.wantsExplicitTable || ["tabular", "table", "geographic"].includes(intent.visualizationHint);
|
|
4869
5089
|
const intentWantsPieLikeChart = ["pie_chart", "donut_chart"].includes(intent.recommendedChart) || ["composition", "category_breakdown"].includes(intent.visualizationHint);
|
|
4870
5090
|
if (parsed.type === "table" && !intentAllowsTable) {
|
|
@@ -4894,7 +5114,26 @@ var UITransformer = class {
|
|
|
4894
5114
|
* - The intent object can be reused across both the heuristic and LLM paths.
|
|
4895
5115
|
* - It is easy to unit-test intent detection in isolation.
|
|
4896
5116
|
*/
|
|
4897
|
-
static async detectIntent(query, llm) {
|
|
5117
|
+
static async detectIntent(query, llm, sources) {
|
|
5118
|
+
let schemaProfileText = "";
|
|
5119
|
+
if (sources && sources.length > 0) {
|
|
5120
|
+
const profile = this.profileData(sources);
|
|
5121
|
+
const hasProducts = sources.some((item) => this.isProductData(item));
|
|
5122
|
+
schemaProfileText = `
|
|
5123
|
+
RETRIEVED DATA SCHEMA:
|
|
5124
|
+
- Numeric fields (measures): ${profile.numericFields.map((f) => `${f.key} (unique values: ${f.uniqueCount})`).join(", ") || "None"}
|
|
5125
|
+
- Category fields (dimensions): ${profile.categoricalFields.map((f) => `${f.key} (unique values: ${f.uniqueCount})`).join(", ") || "None"}
|
|
5126
|
+
- Date fields (temporal): ${profile.dateFields.map((f) => `${f.key} (unique values: ${f.uniqueCount})`).join(", ") || "None"}
|
|
5127
|
+
- Boolean fields: ${profile.booleanFields.map((f) => `${f.key} (unique values: ${f.uniqueCount})`).join(", ") || "None"}
|
|
5128
|
+
- Text fields: ${profile.fields.filter((f) => f.kind === "text").map((f) => f.key).join(", ") || "None"}
|
|
5129
|
+
|
|
5130
|
+
Please choose visualizationHint and recommendedChart dynamically based on the available schema.
|
|
5131
|
+
- Do NOT recommend "trend" or "line_chart" if there are no Date fields.
|
|
5132
|
+
- Do NOT recommend numeric-dependent visualizations (like bar_chart, line_chart, pie_chart, scatter_plot, histogram, metric_card) if there are no Numeric fields. Fall back to tabular/table or text.
|
|
5133
|
+
- If there are multiple metadata fields but no clear categories or numbers, "tabular"/"table" is a highly accurate default.
|
|
5134
|
+
${hasProducts ? `- Note: The retrieved data matches product/catalog structure. If the user query is looking for, exploring, searching, browsing, or listing products/items, you MUST recommend visualizationHint: "product_browse" and recommendedChart: "text".` : ""}
|
|
5135
|
+
`;
|
|
5136
|
+
}
|
|
4898
5137
|
const systemPrompt = `You are an intent classifier for a product-search RAG system.
|
|
4899
5138
|
Given a user query, return ONLY a valid JSON object with this exact shape \u2014 no prose, no markdown:
|
|
4900
5139
|
|
|
@@ -4930,8 +5169,11 @@ RULES:
|
|
|
4930
5169
|
- isTemporal: true if time words appear (trend, historical, over time, last year, monthly, etc.)
|
|
4931
5170
|
- isComparison: true if user compares, ranks, or contrasts entities or categories.
|
|
4932
5171
|
- language: detect from the query text itself; default "en" if uncertain.`;
|
|
5172
|
+
const userPrompt = `QUERY: ${query}${schemaProfileText ? `
|
|
5173
|
+
|
|
5174
|
+
${schemaProfileText}` : ""}`;
|
|
4933
5175
|
const rawResponse = await llm.chat(
|
|
4934
|
-
[{ role: "user", content:
|
|
5176
|
+
[{ role: "user", content: userPrompt }],
|
|
4935
5177
|
"",
|
|
4936
5178
|
{ systemPrompt, temperature: 0 }
|
|
4937
5179
|
);
|
|
@@ -5374,10 +5616,21 @@ RULES:
|
|
|
5374
5616
|
const hasEntityTerms = /\b(organization|organisations?|organizations?|company|companies|employee|employees|staff|headcount|workforce)\b/.test(q);
|
|
5375
5617
|
return asksForRecords && (hasNumericPredicate || hasEntityTerms);
|
|
5376
5618
|
}
|
|
5619
|
+
/** @internal kept private for transform() internal logic */
|
|
5377
5620
|
static isProductQuery(query) {
|
|
5621
|
+
return _UITransformer._productQueryTest(query);
|
|
5622
|
+
}
|
|
5623
|
+
/**
|
|
5624
|
+
* Public entry-point for external callers (e.g. Pipeline)
|
|
5625
|
+
* to check whether a query maps to product_browse without triggering an LLM call.
|
|
5626
|
+
*/
|
|
5627
|
+
static isProductQueryPublic(query) {
|
|
5628
|
+
return _UITransformer._productQueryTest(query);
|
|
5629
|
+
}
|
|
5630
|
+
static _productQueryTest(query) {
|
|
5378
5631
|
const q = query.toLowerCase();
|
|
5379
5632
|
const productTerms = /\b(product|products|item|items|sku|catalog|catalogue|price|prices|brand|model|stock|inventory|in stock|out of stock|buy|shop)\b/.test(q);
|
|
5380
|
-
const productAction = /\b(recommend|suggest|describe|description|detail|details|about|show|find|search|browse|list)\b/.test(q);
|
|
5633
|
+
const productAction = /\b(recommend|suggest|describe|description|detail|details|about|show|find|search|browse|list|explore|exploring)\b/.test(q);
|
|
5381
5634
|
const nonProductEntityTerms = /\b(organization|organisations?|organizations?|company|companies|employee|employees|staff|headcount|workforce)\b/.test(q);
|
|
5382
5635
|
return productTerms && productAction && !nonProductEntityTerms;
|
|
5383
5636
|
}
|
|
@@ -6150,23 +6403,19 @@ function estimateCostUsd(promptTokens, completionTokens, model) {
|
|
|
6150
6403
|
async function scoreHallucination(llm, answer, context) {
|
|
6151
6404
|
const maxContextChars = 3e3;
|
|
6152
6405
|
const truncatedContext = context.length > maxContextChars ? context.slice(0, maxContextChars) + "\n...[truncated]" : context;
|
|
6153
|
-
|
|
6154
|
-
|
|
6155
|
-
CONTEXT:
|
|
6406
|
+
try {
|
|
6407
|
+
const raw = await llm.chat(
|
|
6408
|
+
[{ role: "user", content: `CONTEXT:
|
|
6156
6409
|
${truncatedContext}
|
|
6157
6410
|
|
|
6158
6411
|
ANSWER:
|
|
6159
|
-
${answer}
|
|
6160
|
-
|
|
6161
|
-
Return ONLY a valid JSON object with no markdown fences:
|
|
6162
|
-
{"score": <float 0-1>, "reason": "<one sentence>"}
|
|
6163
|
-
|
|
6164
|
-
Where score 0 = fully grounded in context, score 1 = likely hallucinated or unsupported.`;
|
|
6165
|
-
try {
|
|
6166
|
-
const raw = await llm.chat(
|
|
6167
|
-
[{ role: "user", content: prompt }],
|
|
6412
|
+
${answer}` }],
|
|
6168
6413
|
"",
|
|
6169
|
-
{
|
|
6414
|
+
{
|
|
6415
|
+
systemPrompt: 'You are an AI quality checker. Given the CONTEXT retrieved from a knowledge base and the ANSWER generated from it, rate how well-grounded the answer is. Return ONLY a valid JSON object with no markdown fences: {"score": <float 0-1>, "reason": "<one sentence>"} where score 0 = fully grounded in context, score 1 = likely hallucinated or unsupported.',
|
|
6416
|
+
temperature: 0,
|
|
6417
|
+
maxTokens: 120
|
|
6418
|
+
}
|
|
6170
6419
|
);
|
|
6171
6420
|
const jsonMatch = raw.match(/\{[\s\S]*\}/);
|
|
6172
6421
|
if (!jsonMatch) return void 0;
|
|
@@ -6226,7 +6475,10 @@ var Pipeline = class {
|
|
|
6226
6475
|
- For product descriptions, summarize customer-facing details only. Do NOT list internal catalog fields such as Handle, Body (HTML), Vendor, Type, Tags, Published, Option, Variant, SKU, or raw metadata labels.
|
|
6227
6476
|
- Do NOT try to format product lists as tables.
|
|
6228
6477
|
`;
|
|
6229
|
-
this.config.llm.systemPrompt
|
|
6478
|
+
const userPromptPrefix = this.config.llm.systemPrompt ? `${this.config.llm.systemPrompt}
|
|
6479
|
+
|
|
6480
|
+
` : "";
|
|
6481
|
+
this.config.llm.systemPrompt = `${userPromptPrefix}${chartInstruction}`;
|
|
6230
6482
|
this.vectorDB = await ProviderRegistry.createVectorProvider(this.config.vectorDb);
|
|
6231
6483
|
this.llmRouter = new LLMRouter(this.config);
|
|
6232
6484
|
const { llmProvider: resolvedLLM, embeddingProvider } = await EmbeddingStrategyResolver.resolve(
|
|
@@ -6306,7 +6558,7 @@ var Pipeline = class {
|
|
|
6306
6558
|
embedBatchOptions
|
|
6307
6559
|
);
|
|
6308
6560
|
if (vectors.length !== chunks.length) {
|
|
6309
|
-
throw new
|
|
6561
|
+
throw new EmbeddingFailedException(
|
|
6310
6562
|
`[Pipeline] Embedding mismatch: got ${vectors.length} vectors for ${chunks.length} chunks. Check embedding provider logs for individual chunk failures.`
|
|
6311
6563
|
);
|
|
6312
6564
|
}
|
|
@@ -6404,11 +6656,11 @@ var Pipeline = class {
|
|
|
6404
6656
|
*/
|
|
6405
6657
|
askStream(_0) {
|
|
6406
6658
|
return __asyncGenerator(this, arguments, function* (question, history = [], namespace) {
|
|
6407
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
|
|
6659
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v;
|
|
6408
6660
|
yield new __await(this.initialize());
|
|
6409
6661
|
const ns = namespace != null ? namespace : this.config.projectId;
|
|
6410
6662
|
const topK = (_b = (_a = this.config.rag) == null ? void 0 : _a.topK) != null ? _b : 5;
|
|
6411
|
-
const scoreThreshold = (_d = (_c = this.config.rag) == null ? void 0 : _c.scoreThreshold) != null ? _d : 0;
|
|
6663
|
+
const scoreThreshold = (_d = (_c = this.config.rag) == null ? void 0 : _c.scoreThreshold) != null ? _d : 0.3;
|
|
6412
6664
|
const requestId = `req_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
6413
6665
|
const requestStart = performance.now();
|
|
6414
6666
|
try {
|
|
@@ -6427,12 +6679,13 @@ var Pipeline = class {
|
|
|
6427
6679
|
const embedStart = performance.now();
|
|
6428
6680
|
const cacheKey = `${ns}::${searchQuery}`;
|
|
6429
6681
|
const cachedVector = this.embeddingCache.get(cacheKey);
|
|
6682
|
+
const useGraph = this.graphDB && ((_h = this.config.rag) == null ? void 0 : _h.useGraphRetrieval);
|
|
6430
6683
|
const [strategyResult, embeddedVector] = yield new __await(Promise.all([
|
|
6431
6684
|
QueryProcessor.determineRetrievalStrategy(
|
|
6432
6685
|
searchQuery,
|
|
6433
|
-
this.llmRouter.get("fast"),
|
|
6434
|
-
(
|
|
6435
|
-
(
|
|
6686
|
+
useGraph ? this.llmRouter.get("fast") : void 0,
|
|
6687
|
+
(_i = this.config.rag) == null ? void 0 : _i.graphKeywords,
|
|
6688
|
+
(_j = this.config.rag) == null ? void 0 : _j.vectorKeywords
|
|
6436
6689
|
),
|
|
6437
6690
|
// Embed immediately regardless of strategy — costs nothing if cached.
|
|
6438
6691
|
// If strategy turns out to be 'graph'-only we just won't use the vector.
|
|
@@ -6442,7 +6695,7 @@ var Pipeline = class {
|
|
|
6442
6695
|
if (!cachedVector && queryVector.length > 0) {
|
|
6443
6696
|
this.embeddingCache.set(cacheKey, queryVector);
|
|
6444
6697
|
}
|
|
6445
|
-
const graphData = (strategyResult === "graph" || strategyResult === "both") && this.graphDB && ((
|
|
6698
|
+
const graphData = (strategyResult === "graph" || strategyResult === "both") && this.graphDB && ((_k = this.config.rag) == null ? void 0 : _k.useGraphRetrieval) ? yield new __await(this.graphDB.query(searchQuery)) : void 0;
|
|
6446
6699
|
const hasMetadataFilter = filter.metadata && Object.keys(filter.metadata).length > 0;
|
|
6447
6700
|
const hasNumericPredicates = Array.isArray(filter.__numericPredicates) && filter.__numericPredicates.length > 0;
|
|
6448
6701
|
const wantsExhaustiveList = hasNumericPredicates || hasMetadataFilter || /\b(list|all|show|provide|give|get|browse|find|search|display)\b/i.test(question);
|
|
@@ -6455,7 +6708,7 @@ var Pipeline = class {
|
|
|
6455
6708
|
const structuredSources = this.applyStructuredFilters(rawSources, filter);
|
|
6456
6709
|
let fullSources = hasNumericPredicates ? structuredSources : structuredSources.filter((m) => m.score >= scoreThreshold);
|
|
6457
6710
|
const rerankLimit = wantsExhaustiveList ? retrievalLimit : topK;
|
|
6458
|
-
if (!hasNumericPredicates && ((
|
|
6711
|
+
if (!hasNumericPredicates && ((_l = this.config.rag) == null ? void 0 : _l.useReranking)) {
|
|
6459
6712
|
fullSources = yield new __await(this.reranker.rerank(fullSources, question, rerankLimit));
|
|
6460
6713
|
} else if (!wantsExhaustiveList) {
|
|
6461
6714
|
fullSources = fullSources.slice(0, topK);
|
|
@@ -6486,34 +6739,117 @@ VECTOR CONTEXT:
|
|
|
6486
6739
|
${context}`;
|
|
6487
6740
|
}
|
|
6488
6741
|
const allMetadataKeys = Array.from(new Set(sources.flatMap((s) => Object.keys(s.metadata || {}))));
|
|
6489
|
-
const
|
|
6490
|
-
|
|
6491
|
-
(
|
|
6742
|
+
const cachedSchema = allMetadataKeys.length > 0 ? SchemaMapper.getCached(ns, allMetadataKeys) : void 0;
|
|
6743
|
+
if (allMetadataKeys.length > 0 && !cachedSchema) {
|
|
6744
|
+
SchemaMapper.train(this.llmProvider, ns, allMetadataKeys).catch(() => {
|
|
6745
|
+
});
|
|
6746
|
+
}
|
|
6747
|
+
const isProductQ = UITransformer.isProductQueryPublic(question);
|
|
6748
|
+
const uiTransformationPromise = isProductQ ? Promise.resolve(
|
|
6749
|
+
UITransformer.transform(
|
|
6492
6750
|
question,
|
|
6493
6751
|
sources,
|
|
6494
|
-
|
|
6495
|
-
|
|
6752
|
+
this.config,
|
|
6753
|
+
cachedSchema,
|
|
6754
|
+
{ visualizationHint: "product_browse", recommendedChart: "text", filterInStockOnly: false, wantsExplicitTable: false, isTemporal: false, isComparison: false, language: "en" }
|
|
6496
6755
|
)
|
|
6756
|
+
) : this.generateUiTransformation(
|
|
6757
|
+
question,
|
|
6758
|
+
sources,
|
|
6759
|
+
cachedSchema,
|
|
6760
|
+
hasNumericPredicates
|
|
6497
6761
|
).catch((uiError) => {
|
|
6498
6762
|
console.warn("[Pipeline] UI transformation failed concurrently:", uiError);
|
|
6499
|
-
return UITransformer.transform(question, sources, this.config);
|
|
6763
|
+
return UITransformer.transform(question, sources, this.config, cachedSchema);
|
|
6500
6764
|
});
|
|
6765
|
+
let hallucinationScoringPromise = Promise.resolve(void 0);
|
|
6501
6766
|
const restrictionSuffix = "\n\n(IMPORTANT: Format your response beautifully using rich Markdown! Use bolding for emphasis, headings (##) for structure, bullet points for lists, and proper line breaks between paragraphs to make it highly readable. However, NEVER generate Markdown tables, HTML figures, or text charts (the UI renders requested charts separately, so NEVER say you cannot create, display, draw, render, or provide a chart/visualization). If listing products, use simple markdown bullet points or comma-separated names. NEVER use plus signs (+) to separate product names, category names, or list items. For product description/detail questions, provide customer-facing prose only and do NOT list internal catalog fields such as Handle, Body (HTML), Vendor, Type, Tags, Published, Option, Variant, SKU, or raw metadata labels. You CAN use numbers for years/counts like 2006 or 5800, but NEVER put a dollar sign ($) before them.)";
|
|
6767
|
+
const isClaude37 = this.config.llm.model.includes("claude-3-7-sonnet");
|
|
6768
|
+
const isNativeThinking = isClaude37 && (((_m = this.config.llm.options) == null ? void 0 : _m.thinking) === true || ((_n = this.config.llm.options) == null ? void 0 : _n.thinking) === "enabled" || ((_o = this.config.llm.options) == null ? void 0 : _o.thinking) !== false);
|
|
6769
|
+
const modelNameLower = this.config.llm.model.toLowerCase();
|
|
6770
|
+
const isReasoningModel = modelNameLower.includes("-r1") || modelNameLower.includes("deepseek-r1") || modelNameLower.includes("reasoning") || modelNameLower.includes("thinking");
|
|
6771
|
+
const isSimulatedThinking = !isNativeThinking && (((_p = this.config.llm.options) == null ? void 0 : _p.thinking) === true || ((_q = this.config.llm.options) == null ? void 0 : _q.thinking) === "enabled" || isReasoningModel && ((_r = this.config.llm.options) == null ? void 0 : _r.thinking) !== false);
|
|
6772
|
+
let finalRestrictionSuffix = restrictionSuffix;
|
|
6773
|
+
if (isSimulatedThinking) {
|
|
6774
|
+
finalRestrictionSuffix += "\n\n(IMPORTANT: You must think step-by-step before answering. Write your thinking process inside a `<think>...</think>` block. Write the `<think>` block first, then follow it with your final response. Keep the thinking process thorough and detailed. Example: `<think>Thinking details here...</think>Final answer text here.`)";
|
|
6775
|
+
}
|
|
6502
6776
|
const hardenedHistory = [...history];
|
|
6503
|
-
const userQuestion = { role: "user", content: question +
|
|
6777
|
+
const userQuestion = { role: "user", content: question + finalRestrictionSuffix };
|
|
6504
6778
|
const messages = [...hardenedHistory, userQuestion];
|
|
6505
|
-
const systemPrompt = (
|
|
6779
|
+
const systemPrompt = (_s = this.config.llm.systemPrompt) != null ? _s : "";
|
|
6506
6780
|
const userPrompt = messages.map((m) => `${m.role}: ${m.content}`).join("\n");
|
|
6507
6781
|
let fullReply = "";
|
|
6782
|
+
let thinkingText = "";
|
|
6783
|
+
let thinkingStartMs = performance.now();
|
|
6784
|
+
let thinkingDurationMs = 0;
|
|
6508
6785
|
const generateStart = performance.now();
|
|
6509
6786
|
if (this.llmProvider.chatStream) {
|
|
6510
6787
|
const stream = this.llmProvider.chatStream(messages, context);
|
|
6511
6788
|
if (!stream) throw new Error(`[Pipeline] ${this.config.llm.provider} chatStream returned undefined`);
|
|
6789
|
+
let inThinking = false;
|
|
6790
|
+
let textBuffer = "";
|
|
6512
6791
|
try {
|
|
6513
6792
|
for (var iter = __forAwait(stream), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
|
|
6514
6793
|
const chunk = temp.value;
|
|
6515
|
-
|
|
6516
|
-
|
|
6794
|
+
if (chunk.startsWith("\0THINKING\0")) {
|
|
6795
|
+
const thinkingDelta = chunk.slice("\0THINKING\0".length);
|
|
6796
|
+
thinkingText += thinkingDelta;
|
|
6797
|
+
thinkingDurationMs = performance.now() - thinkingStartMs;
|
|
6798
|
+
yield { type: "thinking", text: thinkingDelta };
|
|
6799
|
+
continue;
|
|
6800
|
+
}
|
|
6801
|
+
if (isSimulatedThinking) {
|
|
6802
|
+
textBuffer += chunk;
|
|
6803
|
+
while (textBuffer.length > 0) {
|
|
6804
|
+
if (!inThinking) {
|
|
6805
|
+
const thinkIndex = textBuffer.indexOf("<think>");
|
|
6806
|
+
if (thinkIndex !== -1) {
|
|
6807
|
+
const before = textBuffer.slice(0, thinkIndex);
|
|
6808
|
+
if (before) {
|
|
6809
|
+
fullReply += before;
|
|
6810
|
+
yield before;
|
|
6811
|
+
}
|
|
6812
|
+
inThinking = true;
|
|
6813
|
+
thinkingStartMs = performance.now();
|
|
6814
|
+
textBuffer = textBuffer.slice(thinkIndex + "<think>".length);
|
|
6815
|
+
} else {
|
|
6816
|
+
const maxSafeLength = textBuffer.length - "<think>".length;
|
|
6817
|
+
if (maxSafeLength > 0) {
|
|
6818
|
+
const safeText = textBuffer.slice(0, maxSafeLength);
|
|
6819
|
+
fullReply += safeText;
|
|
6820
|
+
yield safeText;
|
|
6821
|
+
textBuffer = textBuffer.slice(maxSafeLength);
|
|
6822
|
+
}
|
|
6823
|
+
break;
|
|
6824
|
+
}
|
|
6825
|
+
} else {
|
|
6826
|
+
const endThinkIndex = textBuffer.indexOf("</think>");
|
|
6827
|
+
if (endThinkIndex !== -1) {
|
|
6828
|
+
const thinkingDelta = textBuffer.slice(0, endThinkIndex);
|
|
6829
|
+
if (thinkingDelta) {
|
|
6830
|
+
thinkingText += thinkingDelta;
|
|
6831
|
+
thinkingDurationMs = performance.now() - thinkingStartMs;
|
|
6832
|
+
yield { type: "thinking", text: thinkingDelta };
|
|
6833
|
+
}
|
|
6834
|
+
inThinking = false;
|
|
6835
|
+
textBuffer = textBuffer.slice(endThinkIndex + "</think>".length);
|
|
6836
|
+
} else {
|
|
6837
|
+
const maxSafeLength = textBuffer.length - "</think>".length;
|
|
6838
|
+
if (maxSafeLength > 0) {
|
|
6839
|
+
const thinkingDelta = textBuffer.slice(0, maxSafeLength);
|
|
6840
|
+
thinkingText += thinkingDelta;
|
|
6841
|
+
thinkingDurationMs = performance.now() - thinkingStartMs;
|
|
6842
|
+
yield { type: "thinking", text: thinkingDelta };
|
|
6843
|
+
textBuffer = textBuffer.slice(maxSafeLength);
|
|
6844
|
+
}
|
|
6845
|
+
break;
|
|
6846
|
+
}
|
|
6847
|
+
}
|
|
6848
|
+
}
|
|
6849
|
+
} else {
|
|
6850
|
+
fullReply += chunk;
|
|
6851
|
+
yield chunk;
|
|
6852
|
+
}
|
|
6517
6853
|
}
|
|
6518
6854
|
} catch (temp) {
|
|
6519
6855
|
error = [temp];
|
|
@@ -6525,17 +6861,42 @@ ${context}`;
|
|
|
6525
6861
|
throw error[0];
|
|
6526
6862
|
}
|
|
6527
6863
|
}
|
|
6864
|
+
if (isSimulatedThinking && textBuffer.length > 0) {
|
|
6865
|
+
if (inThinking) {
|
|
6866
|
+
thinkingText += textBuffer;
|
|
6867
|
+
yield { type: "thinking", text: textBuffer };
|
|
6868
|
+
} else {
|
|
6869
|
+
fullReply += textBuffer;
|
|
6870
|
+
yield textBuffer;
|
|
6871
|
+
}
|
|
6872
|
+
}
|
|
6528
6873
|
} else {
|
|
6529
6874
|
const reply = yield new __await(this.llmProvider.chat(messages, context));
|
|
6530
|
-
|
|
6531
|
-
|
|
6875
|
+
if (isSimulatedThinking) {
|
|
6876
|
+
const thinkStart = reply.indexOf("<think>");
|
|
6877
|
+
const thinkEnd = reply.indexOf("</think>");
|
|
6878
|
+
if (thinkStart !== -1 && thinkEnd !== -1 && thinkEnd > thinkStart) {
|
|
6879
|
+
thinkingText = reply.slice(thinkStart + "<think>".length, thinkEnd);
|
|
6880
|
+
fullReply = reply.slice(0, thinkStart) + reply.slice(thinkEnd + "</think>".length);
|
|
6881
|
+
thinkingDurationMs = 100;
|
|
6882
|
+
} else {
|
|
6883
|
+
fullReply = reply;
|
|
6884
|
+
}
|
|
6885
|
+
} else {
|
|
6886
|
+
fullReply = reply;
|
|
6887
|
+
}
|
|
6888
|
+
yield fullReply;
|
|
6889
|
+
}
|
|
6890
|
+
const runHallucination = ((_t = this.config.llm.options) == null ? void 0 : _t.hallucinationScoring) === true || this.config.llm.provider !== "ollama" && ((_u = this.config.llm.options) == null ? void 0 : _u.hallucinationScoring) !== false;
|
|
6891
|
+
if (runHallucination) {
|
|
6892
|
+
hallucinationScoringPromise = scoreHallucination(this.llmProvider, fullReply, context).catch(() => void 0);
|
|
6532
6893
|
}
|
|
6533
6894
|
const generateMs = performance.now() - generateStart;
|
|
6534
6895
|
const totalMs = performance.now() - requestStart;
|
|
6535
6896
|
const latency = {
|
|
6536
6897
|
embedMs: Math.round(embedMs),
|
|
6537
6898
|
retrieveMs: Math.round(retrieveMs),
|
|
6538
|
-
rerankMs: ((
|
|
6899
|
+
rerankMs: ((_v = this.config.rag) == null ? void 0 : _v.useReranking) ? Math.round(rerankMs) : void 0,
|
|
6539
6900
|
generateMs: Math.round(generateMs),
|
|
6540
6901
|
totalMs: Math.round(totalMs)
|
|
6541
6902
|
};
|
|
@@ -6548,12 +6909,16 @@ ${context}`;
|
|
|
6548
6909
|
totalTokens: promptTokens + completionTokens,
|
|
6549
6910
|
estimatedCostUsd: estimateCostUsd(promptTokens, completionTokens, this.config.llm.model)
|
|
6550
6911
|
};
|
|
6551
|
-
const
|
|
6912
|
+
const [uiTransformation, hallucinationResult] = yield new __await(Promise.all([
|
|
6913
|
+
uiTransformationPromise,
|
|
6914
|
+
hallucinationScoringPromise
|
|
6915
|
+
]));
|
|
6916
|
+
const trace = __spreadValues({
|
|
6552
6917
|
requestId,
|
|
6553
6918
|
query: question,
|
|
6554
6919
|
rewrittenQuery,
|
|
6555
6920
|
systemPrompt,
|
|
6556
|
-
userPrompt: question +
|
|
6921
|
+
userPrompt: question + finalRestrictionSuffix,
|
|
6557
6922
|
chunks: sources.map((s) => {
|
|
6558
6923
|
var _a2;
|
|
6559
6924
|
return {
|
|
@@ -6567,22 +6932,19 @@ ${context}`;
|
|
|
6567
6932
|
latency,
|
|
6568
6933
|
tokens,
|
|
6569
6934
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
6570
|
-
}
|
|
6571
|
-
|
|
6935
|
+
}, hallucinationResult ? {
|
|
6936
|
+
hallucinationScore: hallucinationResult.score,
|
|
6937
|
+
hallucinationReason: hallucinationResult.reason
|
|
6938
|
+
} : {});
|
|
6572
6939
|
yield {
|
|
6573
6940
|
reply: "",
|
|
6574
6941
|
sources,
|
|
6575
6942
|
graphData,
|
|
6576
6943
|
ui_transformation: uiTransformation,
|
|
6577
|
-
trace
|
|
6944
|
+
trace,
|
|
6945
|
+
thinking: thinkingText || void 0,
|
|
6946
|
+
thinkingMs: thinkingDurationMs > 0 ? Math.round(thinkingDurationMs) : void 0
|
|
6578
6947
|
};
|
|
6579
|
-
scoreHallucination(this.llmProvider, fullReply, context).then((hallucinationResult) => {
|
|
6580
|
-
if (hallucinationResult) {
|
|
6581
|
-
trace.hallucinationScore = hallucinationResult.score;
|
|
6582
|
-
trace.hallucinationReason = hallucinationResult.reason;
|
|
6583
|
-
}
|
|
6584
|
-
}).catch(() => {
|
|
6585
|
-
});
|
|
6586
6948
|
} catch (error2) {
|
|
6587
6949
|
throw new Error(`[Pipeline] Stream failed: ${error2 instanceof Error ? error2.message : String(error2)}`);
|
|
6588
6950
|
}
|
|
@@ -6592,18 +6954,30 @@ ${context}`;
|
|
|
6592
6954
|
* Universal retrieval method combining all enabled providers.
|
|
6593
6955
|
* Uses an LRU-bounded embedding cache to avoid re-embedding the same query.
|
|
6594
6956
|
*/
|
|
6595
|
-
async generateUiTransformation(question, sources,
|
|
6957
|
+
async generateUiTransformation(question, sources, cachedSchema, forceDeterministic = false) {
|
|
6958
|
+
var _a;
|
|
6596
6959
|
if (!sources || sources.length === 0) {
|
|
6597
|
-
return UITransformer.transform(question, sources, this.config,
|
|
6960
|
+
return UITransformer.transform(question, sources, this.config, cachedSchema);
|
|
6961
|
+
}
|
|
6962
|
+
if (UITransformer.isProductQueryPublic(question)) {
|
|
6963
|
+
return UITransformer.transform(
|
|
6964
|
+
question,
|
|
6965
|
+
sources,
|
|
6966
|
+
this.config,
|
|
6967
|
+
cachedSchema,
|
|
6968
|
+
{ visualizationHint: "product_browse", recommendedChart: "text", filterInStockOnly: false, wantsExplicitTable: false, isTemporal: false, isComparison: false, language: "en" }
|
|
6969
|
+
);
|
|
6598
6970
|
}
|
|
6599
|
-
|
|
6600
|
-
|
|
6971
|
+
const isLocalProvider = this.config.llm.provider === "ollama";
|
|
6972
|
+
const disableLlmUiTransform = ((_a = this.config.llm.options) == null ? void 0 : _a.disableLlmUiTransform) === true;
|
|
6973
|
+
if (forceDeterministic || isLocalProvider || disableLlmUiTransform) {
|
|
6974
|
+
return UITransformer.transform(question, sources, this.config, cachedSchema);
|
|
6601
6975
|
}
|
|
6602
6976
|
try {
|
|
6603
6977
|
return await UITransformer.analyzeAndDecide(question, sources, this.llmRouter.get("fast"));
|
|
6604
6978
|
} catch (err) {
|
|
6605
6979
|
console.warn("[Pipeline] generateUiTransformation failed, using heuristic fallback:", err);
|
|
6606
|
-
return UITransformer.transform(question, sources, this.config,
|
|
6980
|
+
return UITransformer.transform(question, sources, this.config, cachedSchema);
|
|
6607
6981
|
}
|
|
6608
6982
|
}
|
|
6609
6983
|
applyStructuredFilters(sources, filter) {
|
|
@@ -6687,25 +7061,29 @@ ${context}`;
|
|
|
6687
7061
|
return Number.isFinite(numeric) ? numeric : null;
|
|
6688
7062
|
}
|
|
6689
7063
|
async retrieve(query, options) {
|
|
6690
|
-
var _a, _b, _c, _d, _e, _f;
|
|
7064
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
6691
7065
|
const ns = (_a = options.namespace) != null ? _a : this.config.projectId;
|
|
6692
7066
|
const topK = (_b = options.topK) != null ? _b : 5;
|
|
6693
7067
|
const cacheKey = `${ns}::${query}`;
|
|
6694
7068
|
let queryVector = this.embeddingCache.get(cacheKey);
|
|
6695
|
-
const
|
|
7069
|
+
const useGraph = this.graphDB && ((_c = this.config.rag) == null ? void 0 : _c.useGraphRetrieval);
|
|
7070
|
+
const strategy = await QueryProcessor.determineRetrievalStrategy(
|
|
7071
|
+
query,
|
|
7072
|
+
useGraph ? this.llmRouter.get("fast") : void 0
|
|
7073
|
+
);
|
|
6696
7074
|
console.debug(`[Pipeline] Determined retrieval strategy: ${strategy}`);
|
|
6697
7075
|
const [retrievedVector, graphData] = await Promise.all([
|
|
6698
7076
|
// Only embed if we need vector search (strategy is 'vector' or 'both')
|
|
6699
7077
|
strategy === "vector" || strategy === "both" ? queryVector ? Promise.resolve(queryVector) : this.embeddingProvider.embed(query, { taskType: "query" }) : Promise.resolve([]),
|
|
6700
7078
|
// Only query graph if we need graph search (strategy is 'graph' or 'both')
|
|
6701
|
-
(strategy === "graph" || strategy === "both") && this.graphDB && ((
|
|
7079
|
+
(strategy === "graph" || strategy === "both") && this.graphDB && ((_d = this.config.rag) == null ? void 0 : _d.useGraphRetrieval) ? this.graphDB.query(query) : Promise.resolve(void 0)
|
|
6702
7080
|
]);
|
|
6703
7081
|
if ((strategy === "vector" || strategy === "both") && !queryVector && retrievedVector && retrievedVector.length > 0) {
|
|
6704
7082
|
this.embeddingCache.set(cacheKey, retrievedVector);
|
|
6705
7083
|
queryVector = retrievedVector;
|
|
6706
7084
|
}
|
|
6707
|
-
const baseFilter = __spreadProps(__spreadValues({}, (
|
|
6708
|
-
const numericPredicates = QueryProcessor.extractNumericPredicates(query, (
|
|
7085
|
+
const baseFilter = __spreadProps(__spreadValues({}, (_e = options.filter) != null ? _e : {}), { queryText: query });
|
|
7086
|
+
const numericPredicates = QueryProcessor.extractNumericPredicates(query, (_f = this.config.rag) == null ? void 0 : _f.filterableFields);
|
|
6709
7087
|
if (numericPredicates.length > 0) {
|
|
6710
7088
|
baseFilter.__numericPredicates = numericPredicates;
|
|
6711
7089
|
}
|
|
@@ -6716,7 +7094,7 @@ ${context}`;
|
|
|
6716
7094
|
) : [];
|
|
6717
7095
|
const resolvedSources = [];
|
|
6718
7096
|
for (const source of sources) {
|
|
6719
|
-
const parentId = (
|
|
7097
|
+
const parentId = (_g = source.metadata) == null ? void 0 : _g.parent_id;
|
|
6720
7098
|
if (parentId) {
|
|
6721
7099
|
console.log(`[Pipeline] Multi-Vector: Found child chunk. Parent ID: ${parentId}`);
|
|
6722
7100
|
resolvedSources.push(source);
|
|
@@ -6739,10 +7117,13 @@ New Question: ${question}
|
|
|
6739
7117
|
Optimized Search Query:`;
|
|
6740
7118
|
const rewrite = await this.llmProvider.chat(
|
|
6741
7119
|
[
|
|
6742
|
-
{ role: "system", content: "You are an assistant that optimizes search queries for RAG systems." },
|
|
6743
7120
|
{ role: "user", content: prompt }
|
|
6744
7121
|
],
|
|
6745
|
-
""
|
|
7122
|
+
"",
|
|
7123
|
+
{
|
|
7124
|
+
systemPrompt: "You are an assistant that optimizes search queries for RAG systems. Focus on extracting the core intent and entities. Do not answer the question, just rewrite it.",
|
|
7125
|
+
temperature: 0
|
|
7126
|
+
}
|
|
6746
7127
|
);
|
|
6747
7128
|
return rewrite.trim() || question;
|
|
6748
7129
|
}
|
|
@@ -6766,10 +7147,13 @@ ${context}
|
|
|
6766
7147
|
Suggestions:`;
|
|
6767
7148
|
const response = await this.llmProvider.chat(
|
|
6768
7149
|
[
|
|
6769
|
-
{ role: "system", content: "You are a helpful assistant that generates search suggestions." },
|
|
6770
7150
|
{ role: "user", content: prompt }
|
|
6771
7151
|
],
|
|
6772
|
-
""
|
|
7152
|
+
"",
|
|
7153
|
+
{
|
|
7154
|
+
systemPrompt: "You are a helpful assistant that generates search suggestions based on the provided snippets. Focus on questions that can be answered by the context, keep each under 10 words, and return ONLY a JSON array of strings.",
|
|
7155
|
+
temperature: 0
|
|
7156
|
+
}
|
|
6773
7157
|
);
|
|
6774
7158
|
const match = response.match(/\[[\s\S]*\]/);
|
|
6775
7159
|
if (match) {
|
|
@@ -6785,6 +7169,82 @@ Suggestions:`;
|
|
|
6785
7169
|
}
|
|
6786
7170
|
};
|
|
6787
7171
|
|
|
7172
|
+
// src/core/Retrivora.ts
|
|
7173
|
+
var Retrivora = class {
|
|
7174
|
+
constructor(config) {
|
|
7175
|
+
this.config = ConfigResolver.resolveUniversal(config);
|
|
7176
|
+
this.pipeline = new Pipeline(this.config);
|
|
7177
|
+
}
|
|
7178
|
+
async initialize() {
|
|
7179
|
+
try {
|
|
7180
|
+
await ConfigValidator.validateAndThrow(this.config);
|
|
7181
|
+
} catch (err) {
|
|
7182
|
+
throw wrapError(err, "CONFIGURATION_ERROR");
|
|
7183
|
+
}
|
|
7184
|
+
try {
|
|
7185
|
+
await this.pipeline.initialize();
|
|
7186
|
+
} catch (err) {
|
|
7187
|
+
throw wrapError(err, "AUTHENTICATION_ERROR");
|
|
7188
|
+
}
|
|
7189
|
+
}
|
|
7190
|
+
async ingest(documents, namespace) {
|
|
7191
|
+
try {
|
|
7192
|
+
return await this.pipeline.ingest(documents, namespace);
|
|
7193
|
+
} catch (err) {
|
|
7194
|
+
const msg = String(err);
|
|
7195
|
+
let defaultCode = "RETRIEVAL_FAILED";
|
|
7196
|
+
if (msg.includes("Embed") || msg.includes("embed")) {
|
|
7197
|
+
defaultCode = "EMBEDDING_FAILED";
|
|
7198
|
+
}
|
|
7199
|
+
throw wrapError(err, defaultCode);
|
|
7200
|
+
}
|
|
7201
|
+
}
|
|
7202
|
+
async ask(question, history = [], namespace) {
|
|
7203
|
+
try {
|
|
7204
|
+
return await this.pipeline.ask(question, history, namespace);
|
|
7205
|
+
} catch (err) {
|
|
7206
|
+
const msg = String(err);
|
|
7207
|
+
let defaultCode = "RETRIEVAL_FAILED";
|
|
7208
|
+
if (msg.includes("Embed") || msg.includes("embed")) {
|
|
7209
|
+
defaultCode = "EMBEDDING_FAILED";
|
|
7210
|
+
}
|
|
7211
|
+
throw wrapError(err, defaultCode);
|
|
7212
|
+
}
|
|
7213
|
+
}
|
|
7214
|
+
askStream(_0) {
|
|
7215
|
+
return __asyncGenerator(this, arguments, function* (question, history = [], namespace) {
|
|
7216
|
+
try {
|
|
7217
|
+
const stream = this.pipeline.askStream(question, history, namespace);
|
|
7218
|
+
try {
|
|
7219
|
+
for (var iter = __forAwait(stream), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
|
|
7220
|
+
const chunk = temp.value;
|
|
7221
|
+
yield chunk;
|
|
7222
|
+
}
|
|
7223
|
+
} catch (temp) {
|
|
7224
|
+
error = [temp];
|
|
7225
|
+
} finally {
|
|
7226
|
+
try {
|
|
7227
|
+
more && (temp = iter.return) && (yield new __await(temp.call(iter)));
|
|
7228
|
+
} finally {
|
|
7229
|
+
if (error)
|
|
7230
|
+
throw error[0];
|
|
7231
|
+
}
|
|
7232
|
+
}
|
|
7233
|
+
} catch (err) {
|
|
7234
|
+
const msg = String(err);
|
|
7235
|
+
let defaultCode = "RETRIEVAL_FAILED";
|
|
7236
|
+
if (msg.includes("Embed") || msg.includes("embed")) {
|
|
7237
|
+
defaultCode = "EMBEDDING_FAILED";
|
|
7238
|
+
}
|
|
7239
|
+
throw wrapError(err, defaultCode);
|
|
7240
|
+
}
|
|
7241
|
+
});
|
|
7242
|
+
}
|
|
7243
|
+
getPipeline() {
|
|
7244
|
+
return this.pipeline;
|
|
7245
|
+
}
|
|
7246
|
+
};
|
|
7247
|
+
|
|
6788
7248
|
// src/core/ProviderHealthCheck.ts
|
|
6789
7249
|
var ProviderHealthCheck = class {
|
|
6790
7250
|
/**
|
|
@@ -6893,6 +7353,8 @@ var VectorPlugin = class {
|
|
|
6893
7353
|
constructor(hostConfig) {
|
|
6894
7354
|
this.config = ConfigResolver.resolve(hostConfig);
|
|
6895
7355
|
this.validationPromise = ConfigValidator.validateAndThrow(this.config);
|
|
7356
|
+
this.validationPromise.catch(() => {
|
|
7357
|
+
});
|
|
6896
7358
|
this.pipeline = new Pipeline(this.config);
|
|
6897
7359
|
}
|
|
6898
7360
|
/**
|
|
@@ -6926,31 +7388,93 @@ var VectorPlugin = class {
|
|
|
6926
7388
|
* Run a chat query.
|
|
6927
7389
|
*/
|
|
6928
7390
|
async chat(message, history = [], namespace) {
|
|
6929
|
-
|
|
6930
|
-
|
|
7391
|
+
try {
|
|
7392
|
+
await this.validationPromise;
|
|
7393
|
+
} catch (err) {
|
|
7394
|
+
throw wrapError(err, "CONFIGURATION_ERROR");
|
|
7395
|
+
}
|
|
7396
|
+
try {
|
|
7397
|
+
return await this.pipeline.ask(message, history, namespace);
|
|
7398
|
+
} catch (err) {
|
|
7399
|
+
const msg = String(err);
|
|
7400
|
+
let defaultCode = "RETRIEVAL_FAILED";
|
|
7401
|
+
if (msg.includes("Embed") || msg.includes("embed")) {
|
|
7402
|
+
defaultCode = "EMBEDDING_FAILED";
|
|
7403
|
+
}
|
|
7404
|
+
throw wrapError(err, defaultCode);
|
|
7405
|
+
}
|
|
6931
7406
|
}
|
|
6932
7407
|
/**
|
|
6933
7408
|
* Run a streaming chat query.
|
|
6934
7409
|
*/
|
|
6935
7410
|
chatStream(_0) {
|
|
6936
7411
|
return __asyncGenerator(this, arguments, function* (message, history = [], namespace) {
|
|
6937
|
-
|
|
6938
|
-
|
|
7412
|
+
try {
|
|
7413
|
+
yield new __await(this.validationPromise);
|
|
7414
|
+
} catch (err) {
|
|
7415
|
+
throw wrapError(err, "CONFIGURATION_ERROR");
|
|
7416
|
+
}
|
|
7417
|
+
try {
|
|
7418
|
+
const stream = this.pipeline.askStream(message, history, namespace);
|
|
7419
|
+
try {
|
|
7420
|
+
for (var iter = __forAwait(stream), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
|
|
7421
|
+
const chunk = temp.value;
|
|
7422
|
+
yield chunk;
|
|
7423
|
+
}
|
|
7424
|
+
} catch (temp) {
|
|
7425
|
+
error = [temp];
|
|
7426
|
+
} finally {
|
|
7427
|
+
try {
|
|
7428
|
+
more && (temp = iter.return) && (yield new __await(temp.call(iter)));
|
|
7429
|
+
} finally {
|
|
7430
|
+
if (error)
|
|
7431
|
+
throw error[0];
|
|
7432
|
+
}
|
|
7433
|
+
}
|
|
7434
|
+
} catch (err) {
|
|
7435
|
+
const msg = String(err);
|
|
7436
|
+
let defaultCode = "RETRIEVAL_FAILED";
|
|
7437
|
+
if (msg.includes("Embed") || msg.includes("embed")) {
|
|
7438
|
+
defaultCode = "EMBEDDING_FAILED";
|
|
7439
|
+
}
|
|
7440
|
+
throw wrapError(err, defaultCode);
|
|
7441
|
+
}
|
|
6939
7442
|
});
|
|
6940
7443
|
}
|
|
6941
7444
|
/**
|
|
6942
7445
|
* Ingest documents into the vector database.
|
|
6943
7446
|
*/
|
|
6944
7447
|
async ingest(documents, namespace) {
|
|
6945
|
-
|
|
6946
|
-
|
|
7448
|
+
try {
|
|
7449
|
+
await this.validationPromise;
|
|
7450
|
+
} catch (err) {
|
|
7451
|
+
throw wrapError(err, "CONFIGURATION_ERROR");
|
|
7452
|
+
}
|
|
7453
|
+
try {
|
|
7454
|
+
return await this.pipeline.ingest(documents, namespace);
|
|
7455
|
+
} catch (err) {
|
|
7456
|
+
const msg = String(err);
|
|
7457
|
+
let defaultCode = "RETRIEVAL_FAILED";
|
|
7458
|
+
if (msg.includes("Embed") || msg.includes("embed")) {
|
|
7459
|
+
defaultCode = "EMBEDDING_FAILED";
|
|
7460
|
+
}
|
|
7461
|
+
throw wrapError(err, defaultCode);
|
|
7462
|
+
}
|
|
6947
7463
|
}
|
|
6948
7464
|
/**
|
|
6949
7465
|
* Get auto-suggestions based on a query prefix.
|
|
6950
7466
|
*/
|
|
6951
7467
|
async getSuggestions(query, namespace) {
|
|
6952
|
-
|
|
6953
|
-
|
|
7468
|
+
try {
|
|
7469
|
+
await this.validationPromise;
|
|
7470
|
+
} catch (err) {
|
|
7471
|
+
throw wrapError(err, "CONFIGURATION_ERROR");
|
|
7472
|
+
}
|
|
7473
|
+
try {
|
|
7474
|
+
return await this.pipeline.getSuggestions(query, namespace);
|
|
7475
|
+
} catch (err) {
|
|
7476
|
+
throw wrapError(err, "RETRIEVAL_FAILED");
|
|
7477
|
+
}
|
|
6954
7478
|
}
|
|
6955
7479
|
};
|
|
6956
7480
|
|
|
@@ -7322,6 +7846,10 @@ function createStreamHandler(configOrPlugin) {
|
|
|
7322
7846
|
if (!isActive) break;
|
|
7323
7847
|
if (typeof chunk === "string") {
|
|
7324
7848
|
enqueue(sseTextFrame(chunk));
|
|
7849
|
+
} else if (chunk && typeof chunk === "object" && "type" in chunk && chunk.type === "thinking") {
|
|
7850
|
+
enqueue(`data: ${JSON.stringify(chunk)}
|
|
7851
|
+
|
|
7852
|
+
`);
|
|
7325
7853
|
} else {
|
|
7326
7854
|
enqueue(sseMetaFrame(chunk));
|
|
7327
7855
|
const responseChunk = chunk;
|
|
@@ -7493,17 +8021,93 @@ function createUploadHandler(configOrPlugin) {
|
|
|
7493
8021
|
}
|
|
7494
8022
|
};
|
|
7495
8023
|
}
|
|
8024
|
+
function createSuggestionsHandler(configOrPlugin) {
|
|
8025
|
+
const plugin = configOrPlugin instanceof VectorPlugin ? configOrPlugin : new VectorPlugin(configOrPlugin);
|
|
8026
|
+
return async function POST(req) {
|
|
8027
|
+
try {
|
|
8028
|
+
const body = await req.json();
|
|
8029
|
+
const { query, namespace } = body;
|
|
8030
|
+
if (typeof query !== "string") {
|
|
8031
|
+
return import_server.NextResponse.json({ error: "query is required" }, { status: 400 });
|
|
8032
|
+
}
|
|
8033
|
+
const suggestions = await plugin.getSuggestions(query, namespace);
|
|
8034
|
+
return import_server.NextResponse.json({ suggestions });
|
|
8035
|
+
} catch (err) {
|
|
8036
|
+
const message = err instanceof Error ? err.message : "Internal server error";
|
|
8037
|
+
return import_server.NextResponse.json({ error: message }, { status: 500 });
|
|
8038
|
+
}
|
|
8039
|
+
};
|
|
8040
|
+
}
|
|
8041
|
+
function createRagHandler(configOrPlugin) {
|
|
8042
|
+
const plugin = configOrPlugin instanceof VectorPlugin ? configOrPlugin : new VectorPlugin(configOrPlugin);
|
|
8043
|
+
const chatHandler = createChatHandler(plugin);
|
|
8044
|
+
const streamHandler = createStreamHandler(plugin);
|
|
8045
|
+
const uploadHandler = createUploadHandler(plugin);
|
|
8046
|
+
const healthHandler = createHealthHandler(plugin);
|
|
8047
|
+
const suggestionsHandler = createSuggestionsHandler(plugin);
|
|
8048
|
+
async function routePostRequest(req, segment) {
|
|
8049
|
+
switch (segment) {
|
|
8050
|
+
case "chat":
|
|
8051
|
+
return streamHandler(req);
|
|
8052
|
+
case "chat-sync":
|
|
8053
|
+
return chatHandler(req);
|
|
8054
|
+
case "upload":
|
|
8055
|
+
return uploadHandler(req);
|
|
8056
|
+
case "suggestions":
|
|
8057
|
+
return suggestionsHandler(req);
|
|
8058
|
+
case "health":
|
|
8059
|
+
return healthHandler();
|
|
8060
|
+
default:
|
|
8061
|
+
return import_server.NextResponse.json({ error: `Not Found: POST segment "${segment}" not supported.` }, { status: 404 });
|
|
8062
|
+
}
|
|
8063
|
+
}
|
|
8064
|
+
async function routeGetRequest(req, segment) {
|
|
8065
|
+
if (segment === "health") {
|
|
8066
|
+
return healthHandler();
|
|
8067
|
+
}
|
|
8068
|
+
return import_server.NextResponse.json({ error: `Method Not Allowed: GET is only supported for "health" segment.` }, { status: 405 });
|
|
8069
|
+
}
|
|
8070
|
+
async function getSegment(context) {
|
|
8071
|
+
var _a;
|
|
8072
|
+
const resolvedParams = typeof ((_a = context == null ? void 0 : context.params) == null ? void 0 : _a.then) === "function" ? await context.params : context == null ? void 0 : context.params;
|
|
8073
|
+
const segments = (resolvedParams == null ? void 0 : resolvedParams.retrivora) || [];
|
|
8074
|
+
return segments[0] || "chat";
|
|
8075
|
+
}
|
|
8076
|
+
return {
|
|
8077
|
+
GET: async (req, context) => {
|
|
8078
|
+
try {
|
|
8079
|
+
const segment = await getSegment(context);
|
|
8080
|
+
return await routeGetRequest(req, segment);
|
|
8081
|
+
} catch (err) {
|
|
8082
|
+
const msg = err instanceof Error ? err.message : "GET Routing failed";
|
|
8083
|
+
return import_server.NextResponse.json({ error: msg }, { status: 500 });
|
|
8084
|
+
}
|
|
8085
|
+
},
|
|
8086
|
+
POST: async (req, context) => {
|
|
8087
|
+
try {
|
|
8088
|
+
const segment = await getSegment(context);
|
|
8089
|
+
return await routePostRequest(req, segment);
|
|
8090
|
+
} catch (err) {
|
|
8091
|
+
const msg = err instanceof Error ? err.message : "POST Routing failed";
|
|
8092
|
+
return import_server.NextResponse.json({ error: msg }, { status: 500 });
|
|
8093
|
+
}
|
|
8094
|
+
}
|
|
8095
|
+
};
|
|
8096
|
+
}
|
|
7496
8097
|
// Annotate the CommonJS export names for ESM import in node:
|
|
7497
8098
|
0 && (module.exports = {
|
|
7498
8099
|
AnthropicProvider,
|
|
8100
|
+
AuthenticationException,
|
|
7499
8101
|
BaseVectorProvider,
|
|
7500
8102
|
BatchProcessor,
|
|
7501
8103
|
ChromaDBProvider,
|
|
7502
8104
|
ConfigBuilder,
|
|
7503
8105
|
ConfigResolver,
|
|
7504
8106
|
ConfigValidator,
|
|
8107
|
+
ConfigurationException,
|
|
7505
8108
|
DocumentChunker,
|
|
7506
8109
|
DocumentParser,
|
|
8110
|
+
EmbeddingFailedException,
|
|
7507
8111
|
EmbeddingStrategy,
|
|
7508
8112
|
EmbeddingStrategyResolver,
|
|
7509
8113
|
LLMFactory,
|
|
@@ -7518,9 +8122,14 @@ function createUploadHandler(configOrPlugin) {
|
|
|
7518
8122
|
Pipeline,
|
|
7519
8123
|
PostgreSQLProvider,
|
|
7520
8124
|
ProviderHealthCheck,
|
|
8125
|
+
ProviderNotFoundException,
|
|
7521
8126
|
ProviderRegistry,
|
|
7522
8127
|
QdrantProvider,
|
|
8128
|
+
RateLimitException,
|
|
7523
8129
|
RedisProvider,
|
|
8130
|
+
RetrievalException,
|
|
8131
|
+
Retrivora,
|
|
8132
|
+
RetrivoraError,
|
|
7524
8133
|
UniversalLLMAdapter,
|
|
7525
8134
|
UniversalVectorProvider,
|
|
7526
8135
|
VECTOR_PROFILES,
|
|
@@ -7530,11 +8139,13 @@ function createUploadHandler(configOrPlugin) {
|
|
|
7530
8139
|
createFromPreset,
|
|
7531
8140
|
createHealthHandler,
|
|
7532
8141
|
createIngestHandler,
|
|
8142
|
+
createRagHandler,
|
|
7533
8143
|
createStreamHandler,
|
|
7534
8144
|
createUploadHandler,
|
|
7535
8145
|
getRagConfig,
|
|
7536
8146
|
sseErrorFrame,
|
|
7537
8147
|
sseFrame,
|
|
7538
8148
|
sseMetaFrame,
|
|
7539
|
-
sseTextFrame
|
|
8149
|
+
sseTextFrame,
|
|
8150
|
+
wrapError
|
|
7540
8151
|
});
|