@retrivora-ai/rag-engine 2.0.4 → 2.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/handlers/index.js +486 -356
- package/dist/handlers/index.mjs +488 -358
- package/dist/server.js +486 -356
- package/dist/server.mjs +488 -358
- package/package.json +2 -2
- package/src/config/serverConfig.ts +40 -13
- package/src/core/DatabaseStorage.ts +26 -4
- package/src/core/Pipeline.ts +10 -5
- package/src/handlers/index.ts +22 -9
- package/src/index.css +3956 -0
- package/src/llm/providers/OllamaProvider.ts +4 -2
- package/src/llm/providers/UniversalLLMAdapter.ts +82 -12
package/dist/handlers/index.js
CHANGED
|
@@ -2093,6 +2093,285 @@ var import_server = require("next/server");
|
|
|
2093
2093
|
// src/core/ConfigResolver.ts
|
|
2094
2094
|
init_templateUtils();
|
|
2095
2095
|
|
|
2096
|
+
// src/core/LicenseVerifier.ts
|
|
2097
|
+
var crypto = __toESM(require("crypto"));
|
|
2098
|
+
|
|
2099
|
+
// src/exceptions/index.ts
|
|
2100
|
+
var RetrivoraError = class extends Error {
|
|
2101
|
+
constructor(message, code, details) {
|
|
2102
|
+
super(message);
|
|
2103
|
+
this.name = new.target.name;
|
|
2104
|
+
this.code = code;
|
|
2105
|
+
this.details = details;
|
|
2106
|
+
}
|
|
2107
|
+
};
|
|
2108
|
+
var ProviderNotFoundException = class extends RetrivoraError {
|
|
2109
|
+
constructor(providerType, provider, details) {
|
|
2110
|
+
super(`Unsupported ${providerType} provider: ${provider}`, "PROVIDER_NOT_FOUND", details);
|
|
2111
|
+
}
|
|
2112
|
+
};
|
|
2113
|
+
var EmbeddingFailedException = class extends RetrivoraError {
|
|
2114
|
+
constructor(message = "Embedding generation failed", details) {
|
|
2115
|
+
super(message, "EMBEDDING_FAILED", details);
|
|
2116
|
+
}
|
|
2117
|
+
};
|
|
2118
|
+
var RetrievalException = class extends RetrivoraError {
|
|
2119
|
+
constructor(message = "Retrieval failed", details) {
|
|
2120
|
+
super(message, "RETRIEVAL_FAILED", details);
|
|
2121
|
+
}
|
|
2122
|
+
};
|
|
2123
|
+
var RateLimitException = class extends RetrivoraError {
|
|
2124
|
+
constructor(message = "Provider rate limit exceeded", details) {
|
|
2125
|
+
super(message, "RATE_LIMITED", details);
|
|
2126
|
+
}
|
|
2127
|
+
};
|
|
2128
|
+
var ConfigurationException = class extends RetrivoraError {
|
|
2129
|
+
constructor(message, details) {
|
|
2130
|
+
super(message, "CONFIGURATION_ERROR", details);
|
|
2131
|
+
}
|
|
2132
|
+
};
|
|
2133
|
+
var AuthenticationException = class extends RetrivoraError {
|
|
2134
|
+
constructor(message = "Provider authentication failed", details) {
|
|
2135
|
+
super(message, "AUTHENTICATION_ERROR", details);
|
|
2136
|
+
}
|
|
2137
|
+
};
|
|
2138
|
+
function wrapError(err, defaultCode, defaultMessage) {
|
|
2139
|
+
var _a2;
|
|
2140
|
+
if (err instanceof RetrivoraError) {
|
|
2141
|
+
return err;
|
|
2142
|
+
}
|
|
2143
|
+
const error = err;
|
|
2144
|
+
const message = (error == null ? void 0 : error.message) || defaultMessage || String(err);
|
|
2145
|
+
const status = (error == null ? void 0 : error.status) || (error == null ? void 0 : error.statusCode) || ((_a2 = error == null ? void 0 : error.response) == null ? void 0 : _a2.status);
|
|
2146
|
+
const code = error == null ? void 0 : error.code;
|
|
2147
|
+
if (status === 429 || /rate[- ]?limit/i.test(message) || code === "RATE_LIMIT_EXCEEDED") {
|
|
2148
|
+
return new RateLimitException(message, err);
|
|
2149
|
+
}
|
|
2150
|
+
if (status === 401 || status === 403 || /unauthorized|auth|api[- ]?key/i.test(message) || code === "INVALID_API_KEY") {
|
|
2151
|
+
return new AuthenticationException(message, err);
|
|
2152
|
+
}
|
|
2153
|
+
switch (defaultCode) {
|
|
2154
|
+
case "PROVIDER_NOT_FOUND":
|
|
2155
|
+
return new ProviderNotFoundException("provider", message, err);
|
|
2156
|
+
case "EMBEDDING_FAILED":
|
|
2157
|
+
return new EmbeddingFailedException(message, err);
|
|
2158
|
+
case "RETRIEVAL_FAILED":
|
|
2159
|
+
return new RetrievalException(message, err);
|
|
2160
|
+
case "RATE_LIMITED":
|
|
2161
|
+
return new RateLimitException(message, err);
|
|
2162
|
+
case "CONFIGURATION_ERROR":
|
|
2163
|
+
return new ConfigurationException(message, err);
|
|
2164
|
+
case "AUTHENTICATION_ERROR":
|
|
2165
|
+
return new AuthenticationException(message, err);
|
|
2166
|
+
default:
|
|
2167
|
+
return new RetrivoraError(message, defaultCode, err);
|
|
2168
|
+
}
|
|
2169
|
+
}
|
|
2170
|
+
|
|
2171
|
+
// src/core/LicenseVerifier.ts
|
|
2172
|
+
var LicenseVerifier = class {
|
|
2173
|
+
/**
|
|
2174
|
+
* Decodes, verifies signature, and checks metadata of a license key.
|
|
2175
|
+
*
|
|
2176
|
+
* @param licenseKey - Base64url signed JWT license key.
|
|
2177
|
+
* @param currentProjectId - Project namespace ID.
|
|
2178
|
+
* @param publicKeyOverride - Optional override for unit/integration tests.
|
|
2179
|
+
*/
|
|
2180
|
+
static verify(licenseKey, currentProjectId, provider, publicKeyOverride) {
|
|
2181
|
+
const isProduction = process.env.NODE_ENV === "production";
|
|
2182
|
+
const now = Date.now();
|
|
2183
|
+
if (licenseKey) {
|
|
2184
|
+
const cacheKey = `${licenseKey}:${currentProjectId}:${provider || ""}:${publicKeyOverride || ""}`;
|
|
2185
|
+
const cached = this.cache.get(cacheKey);
|
|
2186
|
+
if (cached && now - cached.cachedAt < this.CACHE_TTL_MS) {
|
|
2187
|
+
const currentTimestampSec = Math.floor(now / 1e3);
|
|
2188
|
+
if (cached.payload.expiresAt && currentTimestampSec > cached.payload.expiresAt) {
|
|
2189
|
+
this.cache.delete(cacheKey);
|
|
2190
|
+
} else {
|
|
2191
|
+
return cached.payload;
|
|
2192
|
+
}
|
|
2193
|
+
}
|
|
2194
|
+
}
|
|
2195
|
+
if (!licenseKey) {
|
|
2196
|
+
if (isProduction) {
|
|
2197
|
+
throw new ConfigurationException(
|
|
2198
|
+
"[Retrivora SDK] License key (licenseKey) is required in production environments."
|
|
2199
|
+
);
|
|
2200
|
+
}
|
|
2201
|
+
console.warn(
|
|
2202
|
+
`\x1B[33m[Retrivora SDK] WARNING: Running without a license key. This namespace (${currentProjectId}) is permitted for local development only.\x1B[0m`
|
|
2203
|
+
);
|
|
2204
|
+
return {
|
|
2205
|
+
projectId: currentProjectId,
|
|
2206
|
+
expiresAt: Math.floor(Date.now() / 1e3) + 86400,
|
|
2207
|
+
// Valid for 24h
|
|
2208
|
+
tier: "hobby"
|
|
2209
|
+
};
|
|
2210
|
+
}
|
|
2211
|
+
try {
|
|
2212
|
+
const parts = licenseKey.split(".");
|
|
2213
|
+
if (parts.length !== 3) {
|
|
2214
|
+
throw new Error("Malformed token structure (expected 3 parts).");
|
|
2215
|
+
}
|
|
2216
|
+
const [headerB64, payloadB64, signatureB64] = parts;
|
|
2217
|
+
const dataToVerify = `${headerB64}.${payloadB64}`;
|
|
2218
|
+
const publicKey = publicKeyOverride != null ? publicKeyOverride : this.PUBLIC_KEY;
|
|
2219
|
+
const signature = Buffer.from(signatureB64, "base64url");
|
|
2220
|
+
const data = Buffer.from(dataToVerify);
|
|
2221
|
+
const isValid = crypto.verify(
|
|
2222
|
+
"sha256",
|
|
2223
|
+
data,
|
|
2224
|
+
publicKey,
|
|
2225
|
+
signature
|
|
2226
|
+
);
|
|
2227
|
+
if (!isValid) {
|
|
2228
|
+
throw new Error("Signature verification failed.");
|
|
2229
|
+
}
|
|
2230
|
+
const payload = JSON.parse(
|
|
2231
|
+
Buffer.from(payloadB64, "base64url").toString("utf8")
|
|
2232
|
+
);
|
|
2233
|
+
if (!payload.projectId) {
|
|
2234
|
+
throw new Error('License payload is missing "projectId".');
|
|
2235
|
+
}
|
|
2236
|
+
if (payload.projectId !== currentProjectId) {
|
|
2237
|
+
throw new Error(
|
|
2238
|
+
`Project ID mismatch. License is bound to project namespace "${payload.projectId}" but configuration has "${currentProjectId}".`
|
|
2239
|
+
);
|
|
2240
|
+
}
|
|
2241
|
+
if (!payload.expiresAt) {
|
|
2242
|
+
throw new Error('License payload is missing expiration ("expiresAt").');
|
|
2243
|
+
}
|
|
2244
|
+
const currentTimestampSec = Math.floor(Date.now() / 1e3);
|
|
2245
|
+
if (currentTimestampSec > payload.expiresAt) {
|
|
2246
|
+
throw new Error(
|
|
2247
|
+
`License key has expired. Expiration: ${new Date(
|
|
2248
|
+
payload.expiresAt * 1e3
|
|
2249
|
+
).toDateString()}`
|
|
2250
|
+
);
|
|
2251
|
+
}
|
|
2252
|
+
if (isProduction && provider) {
|
|
2253
|
+
const tier = (payload.tier || "").toLowerCase();
|
|
2254
|
+
const normalizedProvider = provider.toLowerCase();
|
|
2255
|
+
if (tier === "hobby") {
|
|
2256
|
+
const allowedHobby = ["postgresql", "pgvector", "supabase"];
|
|
2257
|
+
if (!allowedHobby.includes(normalizedProvider)) {
|
|
2258
|
+
throw new Error(
|
|
2259
|
+
`The database provider "${provider}" is not allowed on the Hobby tier. Hobby tier is restricted to PostgreSQL and Supabase. Please upgrade to a Developer Pro or Enterprise plan.`
|
|
2260
|
+
);
|
|
2261
|
+
}
|
|
2262
|
+
} else if (tier === "pro" || tier === "developer_pro" || tier === "premium" || tier === "growth" || tier === "free_trial" || tier === "free_tier" || tier === "free") {
|
|
2263
|
+
const allowedPro = [
|
|
2264
|
+
"postgresql",
|
|
2265
|
+
"pgvector",
|
|
2266
|
+
"supabase",
|
|
2267
|
+
"pinecone",
|
|
2268
|
+
"qdrant",
|
|
2269
|
+
"mongodb",
|
|
2270
|
+
"milvus",
|
|
2271
|
+
"chroma",
|
|
2272
|
+
"chromadb"
|
|
2273
|
+
];
|
|
2274
|
+
if (!allowedPro.includes(normalizedProvider)) {
|
|
2275
|
+
throw new Error(
|
|
2276
|
+
`The database provider "${provider}" is not allowed on the Developer Pro tier. Please upgrade to an Enterprise plan.`
|
|
2277
|
+
);
|
|
2278
|
+
}
|
|
2279
|
+
}
|
|
2280
|
+
}
|
|
2281
|
+
if (licenseKey) {
|
|
2282
|
+
const cacheKey = `${licenseKey}:${currentProjectId}:${provider || ""}:${publicKeyOverride || ""}`;
|
|
2283
|
+
this.cache.set(cacheKey, { payload, cachedAt: now });
|
|
2284
|
+
}
|
|
2285
|
+
return payload;
|
|
2286
|
+
} catch (err) {
|
|
2287
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
2288
|
+
throw new ConfigurationException(
|
|
2289
|
+
`[Retrivora SDK] License key validation failed: ${message}`
|
|
2290
|
+
);
|
|
2291
|
+
}
|
|
2292
|
+
}
|
|
2293
|
+
static async verifyIP(licenseKey) {
|
|
2294
|
+
if (!licenseKey) return;
|
|
2295
|
+
try {
|
|
2296
|
+
const parts = licenseKey.split(".");
|
|
2297
|
+
if (parts.length !== 3) return;
|
|
2298
|
+
const [, payloadB64] = parts;
|
|
2299
|
+
const payload = JSON.parse(
|
|
2300
|
+
Buffer.from(payloadB64, "base64url").toString("utf8")
|
|
2301
|
+
);
|
|
2302
|
+
const tier = (payload.tier || "").toLowerCase();
|
|
2303
|
+
if (tier === "enterprise" || tier === "custom") {
|
|
2304
|
+
return;
|
|
2305
|
+
}
|
|
2306
|
+
if (payload.ipv4 || payload.ipv6) {
|
|
2307
|
+
let currentIpv4 = "";
|
|
2308
|
+
let currentIpv6 = "";
|
|
2309
|
+
try {
|
|
2310
|
+
const res = await fetch("https://api4.ipify.org?format=json", { signal: AbortSignal.timeout(3e3) });
|
|
2311
|
+
const data = await res.json();
|
|
2312
|
+
currentIpv4 = data.ip;
|
|
2313
|
+
} catch (e) {
|
|
2314
|
+
}
|
|
2315
|
+
try {
|
|
2316
|
+
const res = await fetch("https://api6.ipify.org?format=json", { signal: AbortSignal.timeout(3e3) });
|
|
2317
|
+
const data = await res.json();
|
|
2318
|
+
currentIpv6 = data.ip;
|
|
2319
|
+
} catch (e) {
|
|
2320
|
+
}
|
|
2321
|
+
const localIps = [];
|
|
2322
|
+
try {
|
|
2323
|
+
const osModule = require("os");
|
|
2324
|
+
const interfaces = osModule.networkInterfaces();
|
|
2325
|
+
for (const name of Object.keys(interfaces)) {
|
|
2326
|
+
for (const iface of interfaces[name] || []) {
|
|
2327
|
+
if (!iface.internal) {
|
|
2328
|
+
localIps.push(iface.address);
|
|
2329
|
+
}
|
|
2330
|
+
}
|
|
2331
|
+
}
|
|
2332
|
+
} catch (e) {
|
|
2333
|
+
}
|
|
2334
|
+
const isIpv4Match = payload.ipv4 && (currentIpv4 === payload.ipv4 || localIps.includes(payload.ipv4));
|
|
2335
|
+
const isIpv6Match = payload.ipv6 && (currentIpv6 === payload.ipv6 || localIps.includes(payload.ipv6));
|
|
2336
|
+
if (payload.ipv4 && payload.ipv6) {
|
|
2337
|
+
if (!isIpv4Match && !isIpv6Match) {
|
|
2338
|
+
throw new Error(
|
|
2339
|
+
`License key access restricted. This license key was created for a different system (authorized IPv4: ${payload.ipv4}, IPv6: ${payload.ipv6}) and cannot be used on this machine.`
|
|
2340
|
+
);
|
|
2341
|
+
}
|
|
2342
|
+
} else if (payload.ipv4 && !isIpv4Match) {
|
|
2343
|
+
throw new Error(
|
|
2344
|
+
`License key access restricted. This license key was created for a different system (authorized IPv4: ${payload.ipv4}) and cannot be used on this machine.`
|
|
2345
|
+
);
|
|
2346
|
+
} else if (payload.ipv6 && !isIpv6Match) {
|
|
2347
|
+
throw new Error(
|
|
2348
|
+
`License key access restricted. This license key was created for a different system (authorized IPv6: ${payload.ipv6}) and cannot be used on this machine.`
|
|
2349
|
+
);
|
|
2350
|
+
}
|
|
2351
|
+
}
|
|
2352
|
+
} catch (err) {
|
|
2353
|
+
if (err.message.includes("License key access restricted")) {
|
|
2354
|
+
throw new ConfigurationException(`[Retrivora SDK] ${err.message}`);
|
|
2355
|
+
}
|
|
2356
|
+
}
|
|
2357
|
+
}
|
|
2358
|
+
};
|
|
2359
|
+
// A simple in-memory cache to save CPU overhead of cryptographic signature checks.
|
|
2360
|
+
LicenseVerifier.cache = /* @__PURE__ */ new Map();
|
|
2361
|
+
LicenseVerifier.CACHE_TTL_MS = 60 * 1e3;
|
|
2362
|
+
// Cache verified license for 60 seconds
|
|
2363
|
+
// Retrivora's Public Key used to verify the license key signature.
|
|
2364
|
+
// In production, this matches the private key held by Retrivora SaaS.
|
|
2365
|
+
LicenseVerifier.PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----
|
|
2366
|
+
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArMieCkCBtTfByRNOserm
|
|
2367
|
+
XM4T0Am29JyNzB4XQPe+WJJ56CN73H1HLXx9n1ByFcxkEJ9po+SURj5DnvUXwEy+
|
|
2368
|
+
xstx33wDPpVmcMQe33j5CRYS0S4gICiNqIRN7XkTlJtrcXqrmh1/hdOAwfRbjO1T
|
|
2369
|
+
NVtORHwUwWfI/lBLyxUPGtKPed+0fQ7NtcW4o00JXxs3EjCB5BV9CbnXoTjQb/4h
|
|
2370
|
+
iwZof4l8rb7oaNzOsVg0RSyxsETX7Ex5sI0CjBz1p2mYp4oVhw/A/h8Ls7H0XzjC
|
|
2371
|
+
+Eb6BLtsytt5JHoSp0jExLlCpDmpys2L+kETcBVx+IqiXtdN1n6KbkksvEDUVzLI
|
|
2372
|
+
MwIDAQAB
|
|
2373
|
+
-----END PUBLIC KEY-----`;
|
|
2374
|
+
|
|
2096
2375
|
// src/config/constants.ts
|
|
2097
2376
|
var VECTOR_DB_PROVIDERS = [
|
|
2098
2377
|
"pinecone",
|
|
@@ -2162,14 +2441,12 @@ function readEnum(env, name, fallback, allowed) {
|
|
|
2162
2441
|
throw new Error(`[getRagConfig] ${name} must be one of: ${allowed.join(", ")}`);
|
|
2163
2442
|
}
|
|
2164
2443
|
function getEnvConfig(env = process.env, base) {
|
|
2165
|
-
var _a2, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X, _Y, _Z, __, _$, _aa, _ba, _ca, _da, _ea, _fa, _ga, _ha, _ia, _ja, _ka, _la, _ma, _na, _oa, _pa, _qa, _ra, _sa, _ta, _ua, _va, _wa, _xa, _ya, _za, _Aa, _Ba, _Ca, _Da, _Ea, _Fa, _Ga, _Ha, _Ia, _Ja, _Ka, _La, _Ma, _Na, _Oa, _Pa, _Qa, _Ra, _Sa, _Ta, _Ua;
|
|
2444
|
+
var _a2, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X, _Y, _Z, __, _$, _aa, _ba, _ca, _da, _ea, _fa, _ga, _ha, _ia, _ja, _ka, _la, _ma, _na, _oa, _pa, _qa, _ra, _sa, _ta, _ua, _va, _wa, _xa, _ya, _za, _Aa, _Ba, _Ca, _Da, _Ea, _Fa, _Ga, _Ha, _Ia, _Ja, _Ka, _La, _Ma, _Na, _Oa, _Pa, _Qa, _Ra, _Sa, _Ta, _Ua, _Va, _Wa, _Xa, _Ya, _Za, __a, _$a, _ab, _bb, _cb, _db, _eb, _fb, _gb, _hb, _ib, _jb, _kb, _lb, _mb, _nb, _ob, _pb, _qb, _rb, _sb, _tb, _ub, _vb, _wb;
|
|
2166
2445
|
const projectId = (_c = (_b = (_a2 = readString(env, "RAG_PROJECT_ID")) != null ? _a2 : readString(env, "NEXT_PUBLIC_PROJECT_ID")) != null ? _b : base == null ? void 0 : base.projectId) != null ? _c : "__default__";
|
|
2167
2446
|
const licenseKey = (_g2 = (_f = (_e = (_d = readString(env, "RAG_LICENSE_KEY")) != null ? _d : readString(env, "RETRIVORA_LICENSE_KEY")) != null ? _e : readString(env, "NEXT_PUBLIC_RETRIVORA_LICENSE_KEY")) != null ? _f : readString(env, "LICENSE_KEY")) != null ? _g2 : base == null ? void 0 : base.licenseKey;
|
|
2168
2447
|
const telemetryEnabled = readString(env, "TELEMETRY_ENABLED") === "true" || readString(env, "NEXT_PUBLIC_TELEMETRY_ENABLED") === "true" || ((_h = base == null ? void 0 : base.telemetry) == null ? void 0 : _h.enabled) || Boolean(licenseKey);
|
|
2169
2448
|
const vectorProvider = readEnum(env, "VECTOR_DB_PROVIDER", "pinecone", VECTOR_DB_PROVIDERS);
|
|
2170
|
-
const
|
|
2171
|
-
const embeddingProvider = readEnum(env, "EMBEDDING_PROVIDER", "openai", EMBEDDING_PROVIDERS);
|
|
2172
|
-
const embeddingDimensions = readNumber(env, "EMBEDDING_DIMENSIONS", 1536);
|
|
2449
|
+
const embeddingDimensions = readNumber(env, "EMBEDDING_DIMENSIONS", 768);
|
|
2173
2450
|
const vectorDbOptions = {};
|
|
2174
2451
|
if (vectorProvider === "pinecone") {
|
|
2175
2452
|
vectorDbOptions.apiKey = (_l = (_k = readString(env, "PINECONE_API_KEY")) != null ? _k : (_j = (_i = base == null ? void 0 : base.vectorDb) == null ? void 0 : _i.options) == null ? void 0 : _j.apiKey) != null ? _l : "";
|
|
@@ -2234,65 +2511,88 @@ function getEnvConfig(env = process.env, base) {
|
|
|
2234
2511
|
rest: "default",
|
|
2235
2512
|
custom: "default"
|
|
2236
2513
|
};
|
|
2514
|
+
const isFreeTier = (() => {
|
|
2515
|
+
if (!licenseKey) return true;
|
|
2516
|
+
try {
|
|
2517
|
+
const payload = LicenseVerifier.verify(licenseKey, projectId);
|
|
2518
|
+
const tier = (payload.tier || "").toLowerCase();
|
|
2519
|
+
return tier === "free_trial" || tier === "free_tier" || tier === "free" || tier === "hobby";
|
|
2520
|
+
} catch (e) {
|
|
2521
|
+
return true;
|
|
2522
|
+
}
|
|
2523
|
+
})();
|
|
2524
|
+
const DEFAULT_FREE_GATEWAY = "https://llm.retrivora.com/api/v1";
|
|
2525
|
+
const defaultLlmProvider = isFreeTier ? "universal_rest" : "universal_rest";
|
|
2526
|
+
const llmProvider = (_na = (_ma = readEnum(env, "LLM_PROVIDER", defaultLlmProvider, LLM_PROVIDERS)) != null ? _ma : (_la = base == null ? void 0 : base.llm) == null ? void 0 : _la.provider) != null ? _na : defaultLlmProvider;
|
|
2527
|
+
const llmBaseUrl = (_qa = (_pa = readString(env, "LLM_BASE_URL")) != null ? _pa : (_oa = base == null ? void 0 : base.llm) == null ? void 0 : _oa.baseUrl) != null ? _qa : DEFAULT_FREE_GATEWAY;
|
|
2528
|
+
const llmModel = (_ua = (_sa = readString(env, "LLM_MODEL")) != null ? _sa : (_ra = base == null ? void 0 : base.llm) == null ? void 0 : _ra.model) != null ? _ua : isFreeTier ? "llama-3.1-8b-instant" : (_ta = DEFAULT_MODEL_BY_PROVIDER[llmProvider]) != null ? _ta : "gpt-4o";
|
|
2529
|
+
const llmApiKey = (_ya = (_xa = (_va = llmApiKeyByProvider[llmProvider]) != null ? _va : readString(env, "LLM_API_KEY")) != null ? _xa : (_wa = base == null ? void 0 : base.llm) == null ? void 0 : _wa.apiKey) != null ? _ya : "sk-retrivora-cancer-280590";
|
|
2530
|
+
const llmProfile = (_Ca = (_Ba = readString(env, "LLM_UNIVERSAL_PROFILE")) != null ? _Ba : (_Aa = (_za = base == null ? void 0 : base.llm) == null ? void 0 : _za.options) == null ? void 0 : _Aa.profile) != null ? _Ca : "litellm";
|
|
2531
|
+
const defaultEmbeddingProvider = isFreeTier ? "universal_rest" : "universal_rest";
|
|
2532
|
+
const embeddingProvider = (_Fa = (_Ea = readEnum(env, "EMBEDDING_PROVIDER", defaultEmbeddingProvider, EMBEDDING_PROVIDERS)) != null ? _Ea : (_Da = base == null ? void 0 : base.embedding) == null ? void 0 : _Da.provider) != null ? _Fa : defaultEmbeddingProvider;
|
|
2533
|
+
const embeddingBaseUrl = (_Ia = (_Ha = readString(env, "EMBEDDING_BASE_URL")) != null ? _Ha : (_Ga = base == null ? void 0 : base.embedding) == null ? void 0 : _Ga.baseUrl) != null ? _Ia : DEFAULT_FREE_GATEWAY;
|
|
2534
|
+
const embeddingModel = (_La = (_Ka = readString(env, "EMBEDDING_MODEL")) != null ? _Ka : (_Ja = base == null ? void 0 : base.embedding) == null ? void 0 : _Ja.model) != null ? _La : "text-embedding-004";
|
|
2535
|
+
const embeddingApiKey = (_Qa = (_Pa = (_Na = (_Ma = embeddingApiKeyByProvider[embeddingProvider]) != null ? _Ma : readString(env, "EMBEDDING_API_KEY")) != null ? _Na : readString(env, "LLM_API_KEY")) != null ? _Pa : (_Oa = base == null ? void 0 : base.embedding) == null ? void 0 : _Oa.apiKey) != null ? _Qa : "sk-retrivora-cancer-280590";
|
|
2536
|
+
const embeddingProfile = (_Ua = (_Ta = readString(env, "EMBEDDING_UNIVERSAL_PROFILE")) != null ? _Ta : (_Sa = (_Ra = base == null ? void 0 : base.embedding) == null ? void 0 : _Ra.options) == null ? void 0 : _Sa.profile) != null ? _Ua : "litellm";
|
|
2237
2537
|
return __spreadProps(__spreadValues({
|
|
2238
2538
|
projectId,
|
|
2239
|
-
licenseKey
|
|
2539
|
+
licenseKey,
|
|
2240
2540
|
vectorDb: {
|
|
2241
2541
|
provider: vectorProvider,
|
|
2242
|
-
indexName: (
|
|
2542
|
+
indexName: (_Wa = (_Va = readString(env, "VECTOR_DB_INDEX")) != null ? _Va : vectorDbOptions.indexName) != null ? _Wa : "rag-index",
|
|
2243
2543
|
options: vectorDbOptions
|
|
2244
2544
|
},
|
|
2245
2545
|
llm: {
|
|
2246
2546
|
provider: llmProvider,
|
|
2247
|
-
model:
|
|
2248
|
-
apiKey:
|
|
2249
|
-
baseUrl:
|
|
2547
|
+
model: llmModel,
|
|
2548
|
+
apiKey: llmApiKey,
|
|
2549
|
+
baseUrl: llmBaseUrl,
|
|
2250
2550
|
systemPrompt: readString(env, "LLM_SYSTEM_PROMPT"),
|
|
2251
2551
|
maxTokens: readNumber(env, "LLM_MAX_TOKENS", 4096),
|
|
2252
2552
|
temperature: readNumber(env, "LLM_TEMPERATURE", 0.7),
|
|
2253
2553
|
options: {
|
|
2254
|
-
profile:
|
|
2554
|
+
profile: llmProfile,
|
|
2255
2555
|
thinking: readString(env, "LLM_THINKING") === "true" || readString(env, "LLM_THINKING") === "enabled" ? true : readString(env, "LLM_THINKING") === "false" ? false : void 0,
|
|
2256
2556
|
thinkingBudget: env.LLM_THINKING_BUDGET ? parseInt(env.LLM_THINKING_BUDGET, 10) : void 0
|
|
2257
2557
|
}
|
|
2258
2558
|
},
|
|
2259
2559
|
embedding: {
|
|
2260
2560
|
provider: embeddingProvider,
|
|
2261
|
-
model:
|
|
2262
|
-
apiKey:
|
|
2263
|
-
baseUrl:
|
|
2561
|
+
model: embeddingModel,
|
|
2562
|
+
apiKey: embeddingApiKey,
|
|
2563
|
+
baseUrl: embeddingBaseUrl,
|
|
2264
2564
|
dimensions: embeddingDimensions,
|
|
2265
2565
|
queryPrefix: readString(env, "EMBEDDING_QUERY_PREFIX"),
|
|
2266
2566
|
documentPrefix: readString(env, "EMBEDDING_DOCUMENT_PREFIX"),
|
|
2267
2567
|
options: {
|
|
2268
|
-
profile:
|
|
2568
|
+
profile: embeddingProfile
|
|
2269
2569
|
}
|
|
2270
2570
|
},
|
|
2271
2571
|
ui: {
|
|
2272
|
-
title: (
|
|
2273
|
-
subtitle: (
|
|
2274
|
-
primaryColor: (
|
|
2275
|
-
accentColor: (
|
|
2276
|
-
logoUrl: (
|
|
2277
|
-
placeholder: (
|
|
2278
|
-
showSources: ((
|
|
2279
|
-
welcomeMessage: (
|
|
2280
|
-
visualStyle: (
|
|
2281
|
-
borderRadius: (
|
|
2282
|
-
allowUpload: ((
|
|
2572
|
+
title: (_Ya = (_Xa = readString(env, "NEXT_PUBLIC_UI_TITLE")) != null ? _Xa : readString(env, "UI_TITLE")) != null ? _Ya : "AI Assistant",
|
|
2573
|
+
subtitle: (__a = (_Za = readString(env, "NEXT_PUBLIC_UI_SUBTITLE")) != null ? _Za : readString(env, "UI_SUBTITLE")) != null ? __a : "Powered by RAG",
|
|
2574
|
+
primaryColor: (_ab = (_$a = readString(env, "NEXT_PUBLIC_PRIMARY_COLOR")) != null ? _$a : readString(env, "UI_PRIMARY_COLOR")) != null ? _ab : "#10b981",
|
|
2575
|
+
accentColor: (_cb = (_bb = readString(env, "NEXT_PUBLIC_ACCENT_COLOR")) != null ? _bb : readString(env, "UI_ACCENT_COLOR")) != null ? _cb : "#3b82f6",
|
|
2576
|
+
logoUrl: (_db = readString(env, "NEXT_PUBLIC_LOGO_URL")) != null ? _db : readString(env, "UI_LOGO_URL"),
|
|
2577
|
+
placeholder: (_fb = (_eb = readString(env, "NEXT_PUBLIC_PLACEHOLDER")) != null ? _eb : readString(env, "UI_PLACEHOLDER")) != null ? _fb : "Ask me anything\u2026",
|
|
2578
|
+
showSources: ((_hb = (_gb = readString(env, "NEXT_PUBLIC_SHOW_SOURCES")) != null ? _gb : readString(env, "UI_SHOW_SOURCES")) != null ? _hb : "true") !== "false",
|
|
2579
|
+
welcomeMessage: (_jb = (_ib = readString(env, "NEXT_PUBLIC_WELCOME_MESSAGE")) != null ? _ib : readString(env, "UI_WELCOME_MESSAGE")) != null ? _jb : "Hello! I'm your AI assistant. Ask me anything about your documents.",
|
|
2580
|
+
visualStyle: (_lb = (_kb = readString(env, "NEXT_PUBLIC_UI_VISUAL_STYLE")) != null ? _kb : readString(env, "UI_VISUAL_STYLE")) != null ? _lb : "glass",
|
|
2581
|
+
borderRadius: (_nb = (_mb = readString(env, "NEXT_PUBLIC_UI_BORDER_RADIUS")) != null ? _mb : readString(env, "UI_BORDER_RADIUS")) != null ? _nb : "xl",
|
|
2582
|
+
allowUpload: ((_pb = (_ob = readString(env, "NEXT_PUBLIC_ALLOW_UPLOAD")) != null ? _ob : readString(env, "UI_ALLOW_UPLOAD")) != null ? _pb : "false") === "true"
|
|
2283
2583
|
},
|
|
2284
2584
|
rag: {
|
|
2285
2585
|
topK: readNumber(env, "RAG_TOP_K", 5),
|
|
2286
2586
|
scoreThreshold: readNumber(env, "RAG_SCORE_THRESHOLD", 0),
|
|
2287
2587
|
chunkSize: readNumber(env, "RAG_CHUNK_SIZE", 1e3),
|
|
2288
2588
|
chunkOverlap: readNumber(env, "RAG_CHUNK_OVERLAP", 200),
|
|
2289
|
-
filterableFields: (
|
|
2589
|
+
filterableFields: (_qb = readString(env, "RAG_FILTERABLE_FIELDS")) == null ? void 0 : _qb.split(",").map((f) => f.trim()),
|
|
2290
2590
|
// Query pipeline toggles — read from .env.local
|
|
2291
2591
|
useQueryTransformation: readString(env, "RAG_USE_QUERY_TRANSFORMATION") === "true",
|
|
2292
2592
|
useReranking: readString(env, "RAG_USE_RERANKING") === "true",
|
|
2293
2593
|
useGraphRetrieval: readString(env, "RAG_USE_GRAPH_RETRIEVAL") === "true",
|
|
2294
|
-
architecture: (
|
|
2295
|
-
chunkingStrategy: (
|
|
2594
|
+
architecture: (_rb = readString(env, "RAG_ARCHITECTURE")) != null ? _rb : "simple",
|
|
2595
|
+
chunkingStrategy: (_sb = readString(env, "RAG_CHUNKING_STRATEGY")) != null ? _sb : "recursive",
|
|
2296
2596
|
uiMapping: (() => {
|
|
2297
2597
|
const raw = readString(env, "RAG_UI_MAPPING");
|
|
2298
2598
|
if (!raw) return void 0;
|
|
@@ -2305,7 +2605,7 @@ function getEnvConfig(env = process.env, base) {
|
|
|
2305
2605
|
},
|
|
2306
2606
|
telemetry: {
|
|
2307
2607
|
enabled: telemetryEnabled,
|
|
2308
|
-
url: (
|
|
2608
|
+
url: (_wb = (_vb = (_tb = readString(env, "TELEMETRY_URL")) != null ? _tb : readString(env, "NEXT_PUBLIC_TELEMETRY_URL")) != null ? _vb : (_ub = base == null ? void 0 : base.telemetry) == null ? void 0 : _ub.url) != null ? _wb : process.env.NODE_ENV === "development" ? "http://localhost:3001/api/telemetry" : "https://retrivora.com/api/telemetry"
|
|
2309
2609
|
}
|
|
2310
2610
|
}, readString(env, "GRAPH_DB_PROVIDER") ? {
|
|
2311
2611
|
graphDb: {
|
|
@@ -2792,10 +3092,12 @@ var AnthropicProvider = class {
|
|
|
2792
3092
|
var import_axios = __toESM(require("axios"));
|
|
2793
3093
|
var OllamaProvider = class {
|
|
2794
3094
|
constructor(llmConfig, embeddingConfig) {
|
|
2795
|
-
var _a2, _b;
|
|
2796
|
-
const
|
|
3095
|
+
var _a2, _b, _c;
|
|
3096
|
+
const rawBaseURL = ((_a2 = llmConfig.baseUrl) != null ? _a2 : "http://localhost:11434").replace(/\/+$/, "");
|
|
3097
|
+
const baseURL = rawBaseURL.replace(/\/(?:api\/v1|v1|api)$/i, "");
|
|
2797
3098
|
const timeout = Number((_b = llmConfig.options) == null ? void 0 : _b.timeout) || 3e5;
|
|
2798
|
-
|
|
3099
|
+
const headers = ((_c = llmConfig.options) == null ? void 0 : _c.headers) || {};
|
|
3100
|
+
this.http = import_axios.default.create({ baseURL, timeout, headers });
|
|
2799
3101
|
this.llmConfig = llmConfig;
|
|
2800
3102
|
this.embeddingConfig = embeddingConfig;
|
|
2801
3103
|
}
|
|
@@ -3605,7 +3907,7 @@ var UniversalLLMAdapter = class {
|
|
|
3605
3907
|
});
|
|
3606
3908
|
}
|
|
3607
3909
|
async chat(messages, context) {
|
|
3608
|
-
var _a2, _b;
|
|
3910
|
+
var _a2, _b, _c, _d, _e, _f;
|
|
3609
3911
|
const path2 = (_a2 = this.opts.chatPath) != null ? _a2 : "/chat/completions";
|
|
3610
3912
|
const formattedMessages = [
|
|
3611
3913
|
{ role: "system", content: `${this.systemPrompt}
|
|
@@ -3630,8 +3932,26 @@ ${context != null ? context : "None"}` },
|
|
|
3630
3932
|
temperature: this.temperature
|
|
3631
3933
|
};
|
|
3632
3934
|
}
|
|
3935
|
+
const isSelfHost = this.baseUrl.includes("retrivora.com") || this.baseUrl.includes("localhost");
|
|
3936
|
+
if (isSelfHost || Boolean(process.env.VERCEL)) {
|
|
3937
|
+
try {
|
|
3938
|
+
const _g2 = globalThis;
|
|
3939
|
+
if (typeof _g2.__retrivoraDispatchChat === "function") {
|
|
3940
|
+
const res = await _g2.__retrivoraDispatchChat({
|
|
3941
|
+
model: this.model,
|
|
3942
|
+
messages: formattedMessages,
|
|
3943
|
+
max_tokens: this.maxTokens,
|
|
3944
|
+
temperature: this.temperature
|
|
3945
|
+
}, this.apiKey);
|
|
3946
|
+
if ((_e = (_d = (_c = (_b = res == null ? void 0 : res.response) == null ? void 0 : _b.choices) == null ? void 0 : _c[0]) == null ? void 0 : _d.message) == null ? void 0 : _e.content) {
|
|
3947
|
+
return res.response.choices[0].message.content;
|
|
3948
|
+
}
|
|
3949
|
+
}
|
|
3950
|
+
} catch (e) {
|
|
3951
|
+
}
|
|
3952
|
+
}
|
|
3633
3953
|
const { data } = await this.http.post(path2, payload);
|
|
3634
|
-
const extractPath = (
|
|
3954
|
+
const extractPath = (_f = this.opts.responseExtractPath) != null ? _f : "choices[0].message.content";
|
|
3635
3955
|
const result = resolvePath(data, extractPath);
|
|
3636
3956
|
if (result === void 0) {
|
|
3637
3957
|
throw new Error(`[UniversalLLMAdapter] Could not extract text from path '${extractPath}' in response.`);
|
|
@@ -3645,7 +3965,7 @@ ${context != null ? context : "None"}` },
|
|
|
3645
3965
|
*/
|
|
3646
3966
|
chatStream(messages, context) {
|
|
3647
3967
|
return __asyncGenerator(this, null, function* () {
|
|
3648
|
-
var _a2, _b, _c;
|
|
3968
|
+
var _a2, _b, _c, _d, _e, _f, _g2;
|
|
3649
3969
|
const path2 = (_a2 = this.opts.chatPath) != null ? _a2 : "/chat/completions";
|
|
3650
3970
|
const url = `${this.baseUrl.replace(/\/$/, "")}${path2}`;
|
|
3651
3971
|
const extractPath = ((_b = this.opts.responseExtractPath) != null ? _b : "choices[0].message.content").replace("message.content", "delta.content");
|
|
@@ -3676,19 +3996,45 @@ ${context != null ? context : "None"}` },
|
|
|
3676
3996
|
stream: true
|
|
3677
3997
|
};
|
|
3678
3998
|
}
|
|
3679
|
-
const
|
|
3680
|
-
|
|
3681
|
-
|
|
3682
|
-
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
-
|
|
3686
|
-
|
|
3999
|
+
const isSelfHost = this.baseUrl.includes("retrivora.com") || this.baseUrl.includes("localhost");
|
|
4000
|
+
let streamBody = null;
|
|
4001
|
+
if (isSelfHost || Boolean(process.env.VERCEL)) {
|
|
4002
|
+
try {
|
|
4003
|
+
const _g3 = globalThis;
|
|
4004
|
+
if (typeof _g3.__retrivoraDispatchChat === "function") {
|
|
4005
|
+
const res = yield new __await(_g3.__retrivoraDispatchChat({
|
|
4006
|
+
model: this.model,
|
|
4007
|
+
messages: formattedMessages,
|
|
4008
|
+
max_tokens: this.maxTokens,
|
|
4009
|
+
temperature: this.temperature,
|
|
4010
|
+
stream: true
|
|
4011
|
+
}, this.apiKey));
|
|
4012
|
+
if (res == null ? void 0 : res.stream) {
|
|
4013
|
+
streamBody = res.stream;
|
|
4014
|
+
} else if ((_f = (_e = (_d = (_c = res == null ? void 0 : res.response) == null ? void 0 : _c.choices) == null ? void 0 : _d[0]) == null ? void 0 : _e.message) == null ? void 0 : _f.content) {
|
|
4015
|
+
yield res.response.choices[0].message.content;
|
|
4016
|
+
return;
|
|
4017
|
+
}
|
|
4018
|
+
}
|
|
4019
|
+
} catch (e) {
|
|
4020
|
+
}
|
|
3687
4021
|
}
|
|
3688
|
-
if (!
|
|
3689
|
-
|
|
4022
|
+
if (!streamBody) {
|
|
4023
|
+
const response = yield new __await(fetch(url, {
|
|
4024
|
+
method: "POST",
|
|
4025
|
+
headers: this.resolvedHeaders,
|
|
4026
|
+
body: JSON.stringify(payload)
|
|
4027
|
+
}));
|
|
4028
|
+
if (!response.ok) {
|
|
4029
|
+
const errorText = yield new __await(response.text().catch(() => response.statusText));
|
|
4030
|
+
throw new Error(`[UniversalLLMAdapter] Streaming request failed (${response.status}): ${errorText}`);
|
|
4031
|
+
}
|
|
4032
|
+
if (!response.body) {
|
|
4033
|
+
throw new Error("[UniversalLLMAdapter] Response body is null \u2014 server did not send a streaming response.");
|
|
4034
|
+
}
|
|
4035
|
+
streamBody = response.body;
|
|
3690
4036
|
}
|
|
3691
|
-
const reader =
|
|
4037
|
+
const reader = streamBody.getReader();
|
|
3692
4038
|
const decoder = new TextDecoder("utf-8");
|
|
3693
4039
|
let buffer = "";
|
|
3694
4040
|
try {
|
|
@@ -3697,7 +4043,7 @@ ${context != null ? context : "None"}` },
|
|
|
3697
4043
|
if (done) break;
|
|
3698
4044
|
buffer += decoder.decode(value, { stream: true });
|
|
3699
4045
|
const lines = buffer.split("\n");
|
|
3700
|
-
buffer = (
|
|
4046
|
+
buffer = (_g2 = lines.pop()) != null ? _g2 : "";
|
|
3701
4047
|
for (const line of lines) {
|
|
3702
4048
|
const trimmed = line.trim();
|
|
3703
4049
|
if (!trimmed || trimmed === "data: [DONE]") continue;
|
|
@@ -3725,7 +4071,7 @@ ${context != null ? context : "None"}` },
|
|
|
3725
4071
|
});
|
|
3726
4072
|
}
|
|
3727
4073
|
async embed(text) {
|
|
3728
|
-
var _a2, _b;
|
|
4074
|
+
var _a2, _b, _c, _d;
|
|
3729
4075
|
const path2 = (_a2 = this.opts.embedPath) != null ? _a2 : "/embeddings";
|
|
3730
4076
|
let payload;
|
|
3731
4077
|
if (this.opts.embedPayloadTemplate) {
|
|
@@ -3739,105 +4085,49 @@ ${context != null ? context : "None"}` },
|
|
|
3739
4085
|
input: text
|
|
3740
4086
|
};
|
|
3741
4087
|
}
|
|
4088
|
+
const isSelfHost = this.baseUrl.includes("retrivora.com") || this.baseUrl.includes("localhost");
|
|
4089
|
+
if (isSelfHost || Boolean(process.env.VERCEL)) {
|
|
4090
|
+
try {
|
|
4091
|
+
const _g2 = globalThis;
|
|
4092
|
+
if (typeof _g2.__retrivoraDispatchEmbedding === "function") {
|
|
4093
|
+
const res = await _g2.__retrivoraDispatchEmbedding({
|
|
4094
|
+
model: this.model,
|
|
4095
|
+
input: text
|
|
4096
|
+
}, this.apiKey);
|
|
4097
|
+
if ((_c = (_b = res == null ? void 0 : res.data) == null ? void 0 : _b[0]) == null ? void 0 : _c.embedding) {
|
|
4098
|
+
return res.data[0].embedding;
|
|
4099
|
+
}
|
|
4100
|
+
}
|
|
4101
|
+
} catch (e) {
|
|
4102
|
+
}
|
|
4103
|
+
}
|
|
3742
4104
|
const { data } = await this.http.post(path2, payload);
|
|
3743
|
-
const extractPath = (
|
|
4105
|
+
const extractPath = (_d = this.opts.embedExtractPath) != null ? _d : "data[0].embedding";
|
|
3744
4106
|
const vector = resolvePath(data, extractPath);
|
|
3745
4107
|
if (!Array.isArray(vector)) {
|
|
3746
4108
|
throw new Error(`[UniversalLLMAdapter] Expected a number array at '${extractPath}' for embeddings.`);
|
|
3747
4109
|
}
|
|
3748
4110
|
return vector;
|
|
3749
4111
|
}
|
|
3750
|
-
async batchEmbed(texts) {
|
|
3751
|
-
const vectors = [];
|
|
3752
|
-
for (const text of texts) {
|
|
3753
|
-
vectors.push(await this.embed(text));
|
|
3754
|
-
}
|
|
3755
|
-
return vectors;
|
|
3756
|
-
}
|
|
3757
|
-
async ping() {
|
|
3758
|
-
try {
|
|
3759
|
-
if (this.opts.pingPath) {
|
|
3760
|
-
await this.http.get(this.opts.pingPath);
|
|
3761
|
-
}
|
|
3762
|
-
return true;
|
|
3763
|
-
} catch (err) {
|
|
3764
|
-
console.error("[UniversalLLMAdapter] Ping failed:", err);
|
|
3765
|
-
return false;
|
|
3766
|
-
}
|
|
3767
|
-
}
|
|
3768
|
-
};
|
|
3769
|
-
|
|
3770
|
-
// src/exceptions/index.ts
|
|
3771
|
-
var RetrivoraError = class extends Error {
|
|
3772
|
-
constructor(message, code, details) {
|
|
3773
|
-
super(message);
|
|
3774
|
-
this.name = new.target.name;
|
|
3775
|
-
this.code = code;
|
|
3776
|
-
this.details = details;
|
|
3777
|
-
}
|
|
3778
|
-
};
|
|
3779
|
-
var ProviderNotFoundException = class extends RetrivoraError {
|
|
3780
|
-
constructor(providerType, provider, details) {
|
|
3781
|
-
super(`Unsupported ${providerType} provider: ${provider}`, "PROVIDER_NOT_FOUND", details);
|
|
3782
|
-
}
|
|
3783
|
-
};
|
|
3784
|
-
var EmbeddingFailedException = class extends RetrivoraError {
|
|
3785
|
-
constructor(message = "Embedding generation failed", details) {
|
|
3786
|
-
super(message, "EMBEDDING_FAILED", details);
|
|
3787
|
-
}
|
|
3788
|
-
};
|
|
3789
|
-
var RetrievalException = class extends RetrivoraError {
|
|
3790
|
-
constructor(message = "Retrieval failed", details) {
|
|
3791
|
-
super(message, "RETRIEVAL_FAILED", details);
|
|
3792
|
-
}
|
|
3793
|
-
};
|
|
3794
|
-
var RateLimitException = class extends RetrivoraError {
|
|
3795
|
-
constructor(message = "Provider rate limit exceeded", details) {
|
|
3796
|
-
super(message, "RATE_LIMITED", details);
|
|
3797
|
-
}
|
|
3798
|
-
};
|
|
3799
|
-
var ConfigurationException = class extends RetrivoraError {
|
|
3800
|
-
constructor(message, details) {
|
|
3801
|
-
super(message, "CONFIGURATION_ERROR", details);
|
|
3802
|
-
}
|
|
3803
|
-
};
|
|
3804
|
-
var AuthenticationException = class extends RetrivoraError {
|
|
3805
|
-
constructor(message = "Provider authentication failed", details) {
|
|
3806
|
-
super(message, "AUTHENTICATION_ERROR", details);
|
|
3807
|
-
}
|
|
3808
|
-
};
|
|
3809
|
-
function wrapError(err, defaultCode, defaultMessage) {
|
|
3810
|
-
var _a2;
|
|
3811
|
-
if (err instanceof RetrivoraError) {
|
|
3812
|
-
return err;
|
|
3813
|
-
}
|
|
3814
|
-
const error = err;
|
|
3815
|
-
const message = (error == null ? void 0 : error.message) || defaultMessage || String(err);
|
|
3816
|
-
const status = (error == null ? void 0 : error.status) || (error == null ? void 0 : error.statusCode) || ((_a2 = error == null ? void 0 : error.response) == null ? void 0 : _a2.status);
|
|
3817
|
-
const code = error == null ? void 0 : error.code;
|
|
3818
|
-
if (status === 429 || /rate[- ]?limit/i.test(message) || code === "RATE_LIMIT_EXCEEDED") {
|
|
3819
|
-
return new RateLimitException(message, err);
|
|
3820
|
-
}
|
|
3821
|
-
if (status === 401 || status === 403 || /unauthorized|auth|api[- ]?key/i.test(message) || code === "INVALID_API_KEY") {
|
|
3822
|
-
return new AuthenticationException(message, err);
|
|
4112
|
+
async batchEmbed(texts) {
|
|
4113
|
+
const vectors = [];
|
|
4114
|
+
for (const text of texts) {
|
|
4115
|
+
vectors.push(await this.embed(text));
|
|
4116
|
+
}
|
|
4117
|
+
return vectors;
|
|
3823
4118
|
}
|
|
3824
|
-
|
|
3825
|
-
|
|
3826
|
-
|
|
3827
|
-
|
|
3828
|
-
|
|
3829
|
-
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
return
|
|
3833
|
-
|
|
3834
|
-
return new ConfigurationException(message, err);
|
|
3835
|
-
case "AUTHENTICATION_ERROR":
|
|
3836
|
-
return new AuthenticationException(message, err);
|
|
3837
|
-
default:
|
|
3838
|
-
return new RetrivoraError(message, defaultCode, err);
|
|
4119
|
+
async ping() {
|
|
4120
|
+
try {
|
|
4121
|
+
if (this.opts.pingPath) {
|
|
4122
|
+
await this.http.get(this.opts.pingPath);
|
|
4123
|
+
}
|
|
4124
|
+
return true;
|
|
4125
|
+
} catch (err) {
|
|
4126
|
+
console.error("[UniversalLLMAdapter] Ping failed:", err);
|
|
4127
|
+
return false;
|
|
4128
|
+
}
|
|
3839
4129
|
}
|
|
3840
|
-
}
|
|
4130
|
+
};
|
|
3841
4131
|
|
|
3842
4132
|
// src/llm/LLMFactory.ts
|
|
3843
4133
|
var customProviders = /* @__PURE__ */ new Map();
|
|
@@ -8148,8 +8438,11 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8148
8438
|
fullSources = fullSources.slice(0, topK);
|
|
8149
8439
|
}
|
|
8150
8440
|
const rerankMs = performance.now() - rerankStart;
|
|
8151
|
-
let context = fullSources.length ? fullSources.map((m, i) =>
|
|
8152
|
-
|
|
8441
|
+
let context = fullSources.length ? fullSources.map((m, i) => {
|
|
8442
|
+
var _a3;
|
|
8443
|
+
return `[Source ${i + 1}]
|
|
8444
|
+
${(_a3 = m == null ? void 0 : m.content) != null ? _a3 : ""}`;
|
|
8445
|
+
}).join("\n\n---\n\n") : "No relevant context found.";
|
|
8153
8446
|
let displayCount = 15;
|
|
8154
8447
|
if (hasMetadataFilter) {
|
|
8155
8448
|
displayCount = fullSources.length;
|
|
@@ -8233,7 +8526,10 @@ ${context}`;
|
|
|
8233
8526
|
if (isSimulatedThinking) {
|
|
8234
8527
|
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.`)";
|
|
8235
8528
|
}
|
|
8236
|
-
const hardenedHistory = [
|
|
8529
|
+
const hardenedHistory = (Array.isArray(history) ? history : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
|
|
8530
|
+
role: m.role || "user",
|
|
8531
|
+
content: typeof m.content === "string" ? m.content : m.content != null ? String(m.content) : ""
|
|
8532
|
+
}));
|
|
8237
8533
|
const userQuestion = { role: "user", content: question + finalRestrictionSuffix };
|
|
8238
8534
|
const messages = [...hardenedHistory, userQuestion];
|
|
8239
8535
|
const systemPrompt = (_v = this.config.llm.systemPrompt) != null ? _v : "";
|
|
@@ -8380,13 +8676,13 @@ ${context}`;
|
|
|
8380
8676
|
rewrittenQuery,
|
|
8381
8677
|
systemPrompt,
|
|
8382
8678
|
userPrompt: question + finalRestrictionSuffix,
|
|
8383
|
-
chunks: sources.map((s) => {
|
|
8384
|
-
var _a3;
|
|
8679
|
+
chunks: (sources || []).filter(Boolean).map((s) => {
|
|
8680
|
+
var _a3, _b2;
|
|
8385
8681
|
return {
|
|
8386
8682
|
id: s.id,
|
|
8387
8683
|
score: s.score,
|
|
8388
|
-
content: s.content,
|
|
8389
|
-
metadata: (
|
|
8684
|
+
content: (_a3 = s == null ? void 0 : s.content) != null ? _a3 : "",
|
|
8685
|
+
metadata: (_b2 = s == null ? void 0 : s.metadata) != null ? _b2 : {},
|
|
8390
8686
|
namespace: ns
|
|
8391
8687
|
};
|
|
8392
8688
|
}),
|
|
@@ -8764,211 +9060,6 @@ var ProviderHealthCheck = class {
|
|
|
8764
9060
|
}
|
|
8765
9061
|
};
|
|
8766
9062
|
|
|
8767
|
-
// src/core/LicenseVerifier.ts
|
|
8768
|
-
var crypto2 = __toESM(require("crypto"));
|
|
8769
|
-
var LicenseVerifier = class {
|
|
8770
|
-
/**
|
|
8771
|
-
* Decodes, verifies signature, and checks metadata of a license key.
|
|
8772
|
-
*
|
|
8773
|
-
* @param licenseKey - Base64url signed JWT license key.
|
|
8774
|
-
* @param currentProjectId - Project namespace ID.
|
|
8775
|
-
* @param publicKeyOverride - Optional override for unit/integration tests.
|
|
8776
|
-
*/
|
|
8777
|
-
static verify(licenseKey, currentProjectId, provider, publicKeyOverride) {
|
|
8778
|
-
const isProduction = process.env.NODE_ENV === "production";
|
|
8779
|
-
const now = Date.now();
|
|
8780
|
-
if (licenseKey) {
|
|
8781
|
-
const cacheKey = `${licenseKey}:${currentProjectId}:${provider || ""}:${publicKeyOverride || ""}`;
|
|
8782
|
-
const cached = this.cache.get(cacheKey);
|
|
8783
|
-
if (cached && now - cached.cachedAt < this.CACHE_TTL_MS) {
|
|
8784
|
-
const currentTimestampSec = Math.floor(now / 1e3);
|
|
8785
|
-
if (cached.payload.expiresAt && currentTimestampSec > cached.payload.expiresAt) {
|
|
8786
|
-
this.cache.delete(cacheKey);
|
|
8787
|
-
} else {
|
|
8788
|
-
return cached.payload;
|
|
8789
|
-
}
|
|
8790
|
-
}
|
|
8791
|
-
}
|
|
8792
|
-
if (!licenseKey) {
|
|
8793
|
-
if (isProduction) {
|
|
8794
|
-
throw new ConfigurationException(
|
|
8795
|
-
"[Retrivora SDK] License key (licenseKey) is required in production environments."
|
|
8796
|
-
);
|
|
8797
|
-
}
|
|
8798
|
-
console.warn(
|
|
8799
|
-
`\x1B[33m[Retrivora SDK] WARNING: Running without a license key. This namespace (${currentProjectId}) is permitted for local development only.\x1B[0m`
|
|
8800
|
-
);
|
|
8801
|
-
return {
|
|
8802
|
-
projectId: currentProjectId,
|
|
8803
|
-
expiresAt: Math.floor(Date.now() / 1e3) + 86400,
|
|
8804
|
-
// Valid for 24h
|
|
8805
|
-
tier: "hobby"
|
|
8806
|
-
};
|
|
8807
|
-
}
|
|
8808
|
-
try {
|
|
8809
|
-
const parts = licenseKey.split(".");
|
|
8810
|
-
if (parts.length !== 3) {
|
|
8811
|
-
throw new Error("Malformed token structure (expected 3 parts).");
|
|
8812
|
-
}
|
|
8813
|
-
const [headerB64, payloadB64, signatureB64] = parts;
|
|
8814
|
-
const dataToVerify = `${headerB64}.${payloadB64}`;
|
|
8815
|
-
const publicKey = publicKeyOverride != null ? publicKeyOverride : this.PUBLIC_KEY;
|
|
8816
|
-
const signature = Buffer.from(signatureB64, "base64url");
|
|
8817
|
-
const data = Buffer.from(dataToVerify);
|
|
8818
|
-
const isValid = crypto2.verify(
|
|
8819
|
-
"sha256",
|
|
8820
|
-
data,
|
|
8821
|
-
publicKey,
|
|
8822
|
-
signature
|
|
8823
|
-
);
|
|
8824
|
-
if (!isValid) {
|
|
8825
|
-
throw new Error("Signature verification failed.");
|
|
8826
|
-
}
|
|
8827
|
-
const payload = JSON.parse(
|
|
8828
|
-
Buffer.from(payloadB64, "base64url").toString("utf8")
|
|
8829
|
-
);
|
|
8830
|
-
if (!payload.projectId) {
|
|
8831
|
-
throw new Error('License payload is missing "projectId".');
|
|
8832
|
-
}
|
|
8833
|
-
if (payload.projectId !== currentProjectId) {
|
|
8834
|
-
throw new Error(
|
|
8835
|
-
`Project ID mismatch. License is bound to project namespace "${payload.projectId}" but configuration has "${currentProjectId}".`
|
|
8836
|
-
);
|
|
8837
|
-
}
|
|
8838
|
-
if (!payload.expiresAt) {
|
|
8839
|
-
throw new Error('License payload is missing expiration ("expiresAt").');
|
|
8840
|
-
}
|
|
8841
|
-
const currentTimestampSec = Math.floor(Date.now() / 1e3);
|
|
8842
|
-
if (currentTimestampSec > payload.expiresAt) {
|
|
8843
|
-
throw new Error(
|
|
8844
|
-
`License key has expired. Expiration: ${new Date(
|
|
8845
|
-
payload.expiresAt * 1e3
|
|
8846
|
-
).toDateString()}`
|
|
8847
|
-
);
|
|
8848
|
-
}
|
|
8849
|
-
if (isProduction && provider) {
|
|
8850
|
-
const tier = (payload.tier || "").toLowerCase();
|
|
8851
|
-
const normalizedProvider = provider.toLowerCase();
|
|
8852
|
-
if (tier === "hobby") {
|
|
8853
|
-
const allowedHobby = ["postgresql", "pgvector", "supabase"];
|
|
8854
|
-
if (!allowedHobby.includes(normalizedProvider)) {
|
|
8855
|
-
throw new Error(
|
|
8856
|
-
`The database provider "${provider}" is not allowed on the Hobby tier. Hobby tier is restricted to PostgreSQL and Supabase. Please upgrade to a Developer Pro or Enterprise plan.`
|
|
8857
|
-
);
|
|
8858
|
-
}
|
|
8859
|
-
} else if (tier === "pro" || tier === "developer_pro" || tier === "premium" || tier === "growth" || tier === "free_trial" || tier === "free_tier" || tier === "free") {
|
|
8860
|
-
const allowedPro = [
|
|
8861
|
-
"postgresql",
|
|
8862
|
-
"pgvector",
|
|
8863
|
-
"supabase",
|
|
8864
|
-
"pinecone",
|
|
8865
|
-
"qdrant",
|
|
8866
|
-
"mongodb",
|
|
8867
|
-
"milvus",
|
|
8868
|
-
"chroma",
|
|
8869
|
-
"chromadb"
|
|
8870
|
-
];
|
|
8871
|
-
if (!allowedPro.includes(normalizedProvider)) {
|
|
8872
|
-
throw new Error(
|
|
8873
|
-
`The database provider "${provider}" is not allowed on the Developer Pro tier. Please upgrade to an Enterprise plan.`
|
|
8874
|
-
);
|
|
8875
|
-
}
|
|
8876
|
-
}
|
|
8877
|
-
}
|
|
8878
|
-
if (licenseKey) {
|
|
8879
|
-
const cacheKey = `${licenseKey}:${currentProjectId}:${provider || ""}:${publicKeyOverride || ""}`;
|
|
8880
|
-
this.cache.set(cacheKey, { payload, cachedAt: now });
|
|
8881
|
-
}
|
|
8882
|
-
return payload;
|
|
8883
|
-
} catch (err) {
|
|
8884
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
8885
|
-
throw new ConfigurationException(
|
|
8886
|
-
`[Retrivora SDK] License key validation failed: ${message}`
|
|
8887
|
-
);
|
|
8888
|
-
}
|
|
8889
|
-
}
|
|
8890
|
-
static async verifyIP(licenseKey) {
|
|
8891
|
-
if (!licenseKey) return;
|
|
8892
|
-
try {
|
|
8893
|
-
const parts = licenseKey.split(".");
|
|
8894
|
-
if (parts.length !== 3) return;
|
|
8895
|
-
const [, payloadB64] = parts;
|
|
8896
|
-
const payload = JSON.parse(
|
|
8897
|
-
Buffer.from(payloadB64, "base64url").toString("utf8")
|
|
8898
|
-
);
|
|
8899
|
-
const tier = (payload.tier || "").toLowerCase();
|
|
8900
|
-
if (tier === "enterprise" || tier === "custom") {
|
|
8901
|
-
return;
|
|
8902
|
-
}
|
|
8903
|
-
if (payload.ipv4 || payload.ipv6) {
|
|
8904
|
-
let currentIpv4 = "";
|
|
8905
|
-
let currentIpv6 = "";
|
|
8906
|
-
try {
|
|
8907
|
-
const res = await fetch("https://api4.ipify.org?format=json", { signal: AbortSignal.timeout(3e3) });
|
|
8908
|
-
const data = await res.json();
|
|
8909
|
-
currentIpv4 = data.ip;
|
|
8910
|
-
} catch (e) {
|
|
8911
|
-
}
|
|
8912
|
-
try {
|
|
8913
|
-
const res = await fetch("https://api6.ipify.org?format=json", { signal: AbortSignal.timeout(3e3) });
|
|
8914
|
-
const data = await res.json();
|
|
8915
|
-
currentIpv6 = data.ip;
|
|
8916
|
-
} catch (e) {
|
|
8917
|
-
}
|
|
8918
|
-
const localIps = [];
|
|
8919
|
-
try {
|
|
8920
|
-
const osModule = require("os");
|
|
8921
|
-
const interfaces = osModule.networkInterfaces();
|
|
8922
|
-
for (const name of Object.keys(interfaces)) {
|
|
8923
|
-
for (const iface of interfaces[name] || []) {
|
|
8924
|
-
if (!iface.internal) {
|
|
8925
|
-
localIps.push(iface.address);
|
|
8926
|
-
}
|
|
8927
|
-
}
|
|
8928
|
-
}
|
|
8929
|
-
} catch (e) {
|
|
8930
|
-
}
|
|
8931
|
-
const isIpv4Match = payload.ipv4 && (currentIpv4 === payload.ipv4 || localIps.includes(payload.ipv4));
|
|
8932
|
-
const isIpv6Match = payload.ipv6 && (currentIpv6 === payload.ipv6 || localIps.includes(payload.ipv6));
|
|
8933
|
-
if (payload.ipv4 && payload.ipv6) {
|
|
8934
|
-
if (!isIpv4Match && !isIpv6Match) {
|
|
8935
|
-
throw new Error(
|
|
8936
|
-
`License key access restricted. This license key was created for a different system (authorized IPv4: ${payload.ipv4}, IPv6: ${payload.ipv6}) and cannot be used on this machine.`
|
|
8937
|
-
);
|
|
8938
|
-
}
|
|
8939
|
-
} else if (payload.ipv4 && !isIpv4Match) {
|
|
8940
|
-
throw new Error(
|
|
8941
|
-
`License key access restricted. This license key was created for a different system (authorized IPv4: ${payload.ipv4}) and cannot be used on this machine.`
|
|
8942
|
-
);
|
|
8943
|
-
} else if (payload.ipv6 && !isIpv6Match) {
|
|
8944
|
-
throw new Error(
|
|
8945
|
-
`License key access restricted. This license key was created for a different system (authorized IPv6: ${payload.ipv6}) and cannot be used on this machine.`
|
|
8946
|
-
);
|
|
8947
|
-
}
|
|
8948
|
-
}
|
|
8949
|
-
} catch (err) {
|
|
8950
|
-
if (err.message.includes("License key access restricted")) {
|
|
8951
|
-
throw new ConfigurationException(`[Retrivora SDK] ${err.message}`);
|
|
8952
|
-
}
|
|
8953
|
-
}
|
|
8954
|
-
}
|
|
8955
|
-
};
|
|
8956
|
-
// A simple in-memory cache to save CPU overhead of cryptographic signature checks.
|
|
8957
|
-
LicenseVerifier.cache = /* @__PURE__ */ new Map();
|
|
8958
|
-
LicenseVerifier.CACHE_TTL_MS = 60 * 1e3;
|
|
8959
|
-
// Cache verified license for 60 seconds
|
|
8960
|
-
// Retrivora's Public Key used to verify the license key signature.
|
|
8961
|
-
// In production, this matches the private key held by Retrivora SaaS.
|
|
8962
|
-
LicenseVerifier.PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----
|
|
8963
|
-
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArMieCkCBtTfByRNOserm
|
|
8964
|
-
XM4T0Am29JyNzB4XQPe+WJJ56CN73H1HLXx9n1ByFcxkEJ9po+SURj5DnvUXwEy+
|
|
8965
|
-
xstx33wDPpVmcMQe33j5CRYS0S4gICiNqIRN7XkTlJtrcXqrmh1/hdOAwfRbjO1T
|
|
8966
|
-
NVtORHwUwWfI/lBLyxUPGtKPed+0fQ7NtcW4o00JXxs3EjCB5BV9CbnXoTjQb/4h
|
|
8967
|
-
iwZof4l8rb7oaNzOsVg0RSyxsETX7Ex5sI0CjBz1p2mYp4oVhw/A/h8Ls7H0XzjC
|
|
8968
|
-
+Eb6BLtsytt5JHoSp0jExLlCpDmpys2L+kETcBVx+IqiXtdN1n6KbkksvEDUVzLI
|
|
8969
|
-
MwIDAQAB
|
|
8970
|
-
-----END PUBLIC KEY-----`;
|
|
8971
|
-
|
|
8972
9063
|
// src/core/VectorPlugin.ts
|
|
8973
9064
|
var VectorPlugin = class {
|
|
8974
9065
|
constructor(hostConfig) {
|
|
@@ -9193,6 +9284,7 @@ ${csv.trim()}`);
|
|
|
9193
9284
|
// src/core/DatabaseStorage.ts
|
|
9194
9285
|
var fs = __toESM(require("fs"));
|
|
9195
9286
|
var path = __toESM(require("path"));
|
|
9287
|
+
var os = __toESM(require("os"));
|
|
9196
9288
|
var DatabaseStorage = class {
|
|
9197
9289
|
constructor(config) {
|
|
9198
9290
|
// Dynamic PG Pool
|
|
@@ -9201,7 +9293,8 @@ var DatabaseStorage = class {
|
|
|
9201
9293
|
this.mongoClient = null;
|
|
9202
9294
|
this.mongoDbName = "";
|
|
9203
9295
|
// Filesystem fallback configuration
|
|
9204
|
-
this.
|
|
9296
|
+
this.isServerless = Boolean(process.env.VERCEL || process.env.AWS_LAMBDA_FUNCTION_NAME || process.env.LAMBDA_TASK_ROOT);
|
|
9297
|
+
this.fallbackDir = this.isServerless ? path.join(os.tmpdir(), ".retrivora") : path.join(process.cwd(), ".retrivora");
|
|
9205
9298
|
this.historyFile = path.join(this.fallbackDir, "history.json");
|
|
9206
9299
|
this.feedbackFile = path.join(this.fallbackDir, "feedback.json");
|
|
9207
9300
|
var _a2, _b, _c, _d, _e;
|
|
@@ -9331,10 +9424,27 @@ var DatabaseStorage = class {
|
|
|
9331
9424
|
}
|
|
9332
9425
|
// Helper for FS fallback writes
|
|
9333
9426
|
writeLocalFile(filePath, data) {
|
|
9334
|
-
|
|
9335
|
-
|
|
9427
|
+
try {
|
|
9428
|
+
const dir = path.dirname(filePath);
|
|
9429
|
+
if (!fs.existsSync(dir)) {
|
|
9430
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
9431
|
+
}
|
|
9432
|
+
fs.writeFileSync(filePath, JSON.stringify(data, null, 2), "utf-8");
|
|
9433
|
+
} catch (err) {
|
|
9434
|
+
if (err.code === "EROFS") {
|
|
9435
|
+
try {
|
|
9436
|
+
const tmpDir = path.join(os.tmpdir(), ".retrivora");
|
|
9437
|
+
if (!fs.existsSync(tmpDir)) {
|
|
9438
|
+
fs.mkdirSync(tmpDir, { recursive: true });
|
|
9439
|
+
}
|
|
9440
|
+
const tmpFilePath = path.join(tmpDir, path.basename(filePath));
|
|
9441
|
+
fs.writeFileSync(tmpFilePath, JSON.stringify(data, null, 2), "utf-8");
|
|
9442
|
+
} catch (e) {
|
|
9443
|
+
}
|
|
9444
|
+
} else {
|
|
9445
|
+
console.warn(`[DatabaseStorage] Failed to write local fallback file: ${err.message}`);
|
|
9446
|
+
}
|
|
9336
9447
|
}
|
|
9337
|
-
fs.writeFileSync(filePath, JSON.stringify(data, null, 2), "utf-8");
|
|
9338
9448
|
}
|
|
9339
9449
|
// ─── Message History Operations ──────────────────────────────────────────
|
|
9340
9450
|
async saveMessage(sessionId, message) {
|
|
@@ -9766,7 +9876,17 @@ function createChatHandler(configOrPlugin, options) {
|
|
|
9766
9876
|
if (rateLimited) return rateLimited;
|
|
9767
9877
|
try {
|
|
9768
9878
|
const body = await req.json();
|
|
9769
|
-
const
|
|
9879
|
+
const bodyObj = body != null ? body : {};
|
|
9880
|
+
let rawMessage = bodyObj.message;
|
|
9881
|
+
if (!rawMessage && Array.isArray(bodyObj.messages) && bodyObj.messages.length > 0) {
|
|
9882
|
+
const lastMsg = bodyObj.messages[bodyObj.messages.length - 1];
|
|
9883
|
+
rawMessage = typeof lastMsg === "string" ? lastMsg : (lastMsg == null ? void 0 : lastMsg.content) || (lastMsg == null ? void 0 : lastMsg.text);
|
|
9884
|
+
}
|
|
9885
|
+
if (!rawMessage && typeof bodyObj.prompt === "string") {
|
|
9886
|
+
rawMessage = bodyObj.prompt;
|
|
9887
|
+
}
|
|
9888
|
+
const history = bodyObj.history || (Array.isArray(bodyObj.messages) ? bodyObj.messages.slice(0, -1) : []);
|
|
9889
|
+
const { namespace, sessionId = "default", messageId, userMessageId } = bodyObj;
|
|
9770
9890
|
const sanitized = sanitizeInput(rawMessage != null ? rawMessage : "");
|
|
9771
9891
|
if (!sanitized.ok) {
|
|
9772
9892
|
return import_server.NextResponse.json({ error: { code: "INVALID_INPUT", message: sanitized.error } }, { status: 400 });
|
|
@@ -9818,7 +9938,17 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
9818
9938
|
headers: { "Content-Type": "application/json" }
|
|
9819
9939
|
});
|
|
9820
9940
|
}
|
|
9821
|
-
const
|
|
9941
|
+
const bodyObj = body != null ? body : {};
|
|
9942
|
+
let rawMessage = bodyObj.message;
|
|
9943
|
+
if (!rawMessage && Array.isArray(bodyObj.messages) && bodyObj.messages.length > 0) {
|
|
9944
|
+
const lastMsg = bodyObj.messages[bodyObj.messages.length - 1];
|
|
9945
|
+
rawMessage = typeof lastMsg === "string" ? lastMsg : (lastMsg == null ? void 0 : lastMsg.content) || (lastMsg == null ? void 0 : lastMsg.text);
|
|
9946
|
+
}
|
|
9947
|
+
if (!rawMessage && typeof bodyObj.prompt === "string") {
|
|
9948
|
+
rawMessage = bodyObj.prompt;
|
|
9949
|
+
}
|
|
9950
|
+
const history = bodyObj.history || (Array.isArray(bodyObj.messages) ? bodyObj.messages.slice(0, -1) : []);
|
|
9951
|
+
const { namespace, sessionId = "default", messageId, userMessageId } = bodyObj;
|
|
9822
9952
|
const sanitized = sanitizeInput(rawMessage != null ? rawMessage : "");
|
|
9823
9953
|
if (!sanitized.ok) {
|
|
9824
9954
|
return new Response(
|