@retrivora-ai/rag-engine 2.0.3 → 2.0.5
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 +389 -344
- package/dist/handlers/index.mjs +391 -346
- package/dist/server.js +389 -344
- package/dist/server.mjs +391 -346
- package/package.json +2 -2
- package/src/config/serverConfig.ts +40 -13
- package/src/core/DatabaseStorage.ts +5 -1
- package/src/core/LicenseVerifier.ts +1 -1
- package/src/handlers/index.ts +22 -9
- package/src/index.css +3956 -0
- package/src/llm/providers/OllamaProvider.ts +4 -2
package/dist/server.js
CHANGED
|
@@ -2151,6 +2151,285 @@ module.exports = __toCommonJS(server_exports);
|
|
|
2151
2151
|
// src/core/ConfigResolver.ts
|
|
2152
2152
|
init_templateUtils();
|
|
2153
2153
|
|
|
2154
|
+
// src/core/LicenseVerifier.ts
|
|
2155
|
+
var crypto = __toESM(require("crypto"));
|
|
2156
|
+
|
|
2157
|
+
// src/exceptions/index.ts
|
|
2158
|
+
var RetrivoraError = class extends Error {
|
|
2159
|
+
constructor(message, code, details) {
|
|
2160
|
+
super(message);
|
|
2161
|
+
this.name = new.target.name;
|
|
2162
|
+
this.code = code;
|
|
2163
|
+
this.details = details;
|
|
2164
|
+
}
|
|
2165
|
+
};
|
|
2166
|
+
var ProviderNotFoundException = class extends RetrivoraError {
|
|
2167
|
+
constructor(providerType, provider, details) {
|
|
2168
|
+
super(`Unsupported ${providerType} provider: ${provider}`, "PROVIDER_NOT_FOUND", details);
|
|
2169
|
+
}
|
|
2170
|
+
};
|
|
2171
|
+
var EmbeddingFailedException = class extends RetrivoraError {
|
|
2172
|
+
constructor(message = "Embedding generation failed", details) {
|
|
2173
|
+
super(message, "EMBEDDING_FAILED", details);
|
|
2174
|
+
}
|
|
2175
|
+
};
|
|
2176
|
+
var RetrievalException = class extends RetrivoraError {
|
|
2177
|
+
constructor(message = "Retrieval failed", details) {
|
|
2178
|
+
super(message, "RETRIEVAL_FAILED", details);
|
|
2179
|
+
}
|
|
2180
|
+
};
|
|
2181
|
+
var RateLimitException = class extends RetrivoraError {
|
|
2182
|
+
constructor(message = "Provider rate limit exceeded", details) {
|
|
2183
|
+
super(message, "RATE_LIMITED", details);
|
|
2184
|
+
}
|
|
2185
|
+
};
|
|
2186
|
+
var ConfigurationException = class extends RetrivoraError {
|
|
2187
|
+
constructor(message, details) {
|
|
2188
|
+
super(message, "CONFIGURATION_ERROR", details);
|
|
2189
|
+
}
|
|
2190
|
+
};
|
|
2191
|
+
var AuthenticationException = class extends RetrivoraError {
|
|
2192
|
+
constructor(message = "Provider authentication failed", details) {
|
|
2193
|
+
super(message, "AUTHENTICATION_ERROR", details);
|
|
2194
|
+
}
|
|
2195
|
+
};
|
|
2196
|
+
function wrapError(err, defaultCode, defaultMessage) {
|
|
2197
|
+
var _a2;
|
|
2198
|
+
if (err instanceof RetrivoraError) {
|
|
2199
|
+
return err;
|
|
2200
|
+
}
|
|
2201
|
+
const error = err;
|
|
2202
|
+
const message = (error == null ? void 0 : error.message) || defaultMessage || String(err);
|
|
2203
|
+
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);
|
|
2204
|
+
const code = error == null ? void 0 : error.code;
|
|
2205
|
+
if (status === 429 || /rate[- ]?limit/i.test(message) || code === "RATE_LIMIT_EXCEEDED") {
|
|
2206
|
+
return new RateLimitException(message, err);
|
|
2207
|
+
}
|
|
2208
|
+
if (status === 401 || status === 403 || /unauthorized|auth|api[- ]?key/i.test(message) || code === "INVALID_API_KEY") {
|
|
2209
|
+
return new AuthenticationException(message, err);
|
|
2210
|
+
}
|
|
2211
|
+
switch (defaultCode) {
|
|
2212
|
+
case "PROVIDER_NOT_FOUND":
|
|
2213
|
+
return new ProviderNotFoundException("provider", message, err);
|
|
2214
|
+
case "EMBEDDING_FAILED":
|
|
2215
|
+
return new EmbeddingFailedException(message, err);
|
|
2216
|
+
case "RETRIEVAL_FAILED":
|
|
2217
|
+
return new RetrievalException(message, err);
|
|
2218
|
+
case "RATE_LIMITED":
|
|
2219
|
+
return new RateLimitException(message, err);
|
|
2220
|
+
case "CONFIGURATION_ERROR":
|
|
2221
|
+
return new ConfigurationException(message, err);
|
|
2222
|
+
case "AUTHENTICATION_ERROR":
|
|
2223
|
+
return new AuthenticationException(message, err);
|
|
2224
|
+
default:
|
|
2225
|
+
return new RetrivoraError(message, defaultCode, err);
|
|
2226
|
+
}
|
|
2227
|
+
}
|
|
2228
|
+
|
|
2229
|
+
// src/core/LicenseVerifier.ts
|
|
2230
|
+
var LicenseVerifier = class {
|
|
2231
|
+
/**
|
|
2232
|
+
* Decodes, verifies signature, and checks metadata of a license key.
|
|
2233
|
+
*
|
|
2234
|
+
* @param licenseKey - Base64url signed JWT license key.
|
|
2235
|
+
* @param currentProjectId - Project namespace ID.
|
|
2236
|
+
* @param publicKeyOverride - Optional override for unit/integration tests.
|
|
2237
|
+
*/
|
|
2238
|
+
static verify(licenseKey, currentProjectId, provider, publicKeyOverride) {
|
|
2239
|
+
const isProduction = process.env.NODE_ENV === "production";
|
|
2240
|
+
const now = Date.now();
|
|
2241
|
+
if (licenseKey) {
|
|
2242
|
+
const cacheKey = `${licenseKey}:${currentProjectId}:${provider || ""}:${publicKeyOverride || ""}`;
|
|
2243
|
+
const cached = this.cache.get(cacheKey);
|
|
2244
|
+
if (cached && now - cached.cachedAt < this.CACHE_TTL_MS) {
|
|
2245
|
+
const currentTimestampSec = Math.floor(now / 1e3);
|
|
2246
|
+
if (cached.payload.expiresAt && currentTimestampSec > cached.payload.expiresAt) {
|
|
2247
|
+
this.cache.delete(cacheKey);
|
|
2248
|
+
} else {
|
|
2249
|
+
return cached.payload;
|
|
2250
|
+
}
|
|
2251
|
+
}
|
|
2252
|
+
}
|
|
2253
|
+
if (!licenseKey) {
|
|
2254
|
+
if (isProduction) {
|
|
2255
|
+
throw new ConfigurationException(
|
|
2256
|
+
"[Retrivora SDK] License key (licenseKey) is required in production environments."
|
|
2257
|
+
);
|
|
2258
|
+
}
|
|
2259
|
+
console.warn(
|
|
2260
|
+
`\x1B[33m[Retrivora SDK] WARNING: Running without a license key. This namespace (${currentProjectId}) is permitted for local development only.\x1B[0m`
|
|
2261
|
+
);
|
|
2262
|
+
return {
|
|
2263
|
+
projectId: currentProjectId,
|
|
2264
|
+
expiresAt: Math.floor(Date.now() / 1e3) + 86400,
|
|
2265
|
+
// Valid for 24h
|
|
2266
|
+
tier: "hobby"
|
|
2267
|
+
};
|
|
2268
|
+
}
|
|
2269
|
+
try {
|
|
2270
|
+
const parts = licenseKey.split(".");
|
|
2271
|
+
if (parts.length !== 3) {
|
|
2272
|
+
throw new Error("Malformed token structure (expected 3 parts).");
|
|
2273
|
+
}
|
|
2274
|
+
const [headerB64, payloadB64, signatureB64] = parts;
|
|
2275
|
+
const dataToVerify = `${headerB64}.${payloadB64}`;
|
|
2276
|
+
const publicKey = publicKeyOverride != null ? publicKeyOverride : this.PUBLIC_KEY;
|
|
2277
|
+
const signature = Buffer.from(signatureB64, "base64url");
|
|
2278
|
+
const data = Buffer.from(dataToVerify);
|
|
2279
|
+
const isValid = crypto.verify(
|
|
2280
|
+
"sha256",
|
|
2281
|
+
data,
|
|
2282
|
+
publicKey,
|
|
2283
|
+
signature
|
|
2284
|
+
);
|
|
2285
|
+
if (!isValid) {
|
|
2286
|
+
throw new Error("Signature verification failed.");
|
|
2287
|
+
}
|
|
2288
|
+
const payload = JSON.parse(
|
|
2289
|
+
Buffer.from(payloadB64, "base64url").toString("utf8")
|
|
2290
|
+
);
|
|
2291
|
+
if (!payload.projectId) {
|
|
2292
|
+
throw new Error('License payload is missing "projectId".');
|
|
2293
|
+
}
|
|
2294
|
+
if (payload.projectId !== currentProjectId) {
|
|
2295
|
+
throw new Error(
|
|
2296
|
+
`Project ID mismatch. License is bound to project namespace "${payload.projectId}" but configuration has "${currentProjectId}".`
|
|
2297
|
+
);
|
|
2298
|
+
}
|
|
2299
|
+
if (!payload.expiresAt) {
|
|
2300
|
+
throw new Error('License payload is missing expiration ("expiresAt").');
|
|
2301
|
+
}
|
|
2302
|
+
const currentTimestampSec = Math.floor(Date.now() / 1e3);
|
|
2303
|
+
if (currentTimestampSec > payload.expiresAt) {
|
|
2304
|
+
throw new Error(
|
|
2305
|
+
`License key has expired. Expiration: ${new Date(
|
|
2306
|
+
payload.expiresAt * 1e3
|
|
2307
|
+
).toDateString()}`
|
|
2308
|
+
);
|
|
2309
|
+
}
|
|
2310
|
+
if (isProduction && provider) {
|
|
2311
|
+
const tier = (payload.tier || "").toLowerCase();
|
|
2312
|
+
const normalizedProvider = provider.toLowerCase();
|
|
2313
|
+
if (tier === "hobby") {
|
|
2314
|
+
const allowedHobby = ["postgresql", "pgvector", "supabase"];
|
|
2315
|
+
if (!allowedHobby.includes(normalizedProvider)) {
|
|
2316
|
+
throw new Error(
|
|
2317
|
+
`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.`
|
|
2318
|
+
);
|
|
2319
|
+
}
|
|
2320
|
+
} else if (tier === "pro" || tier === "developer_pro" || tier === "premium" || tier === "growth" || tier === "free_trial" || tier === "free_tier" || tier === "free") {
|
|
2321
|
+
const allowedPro = [
|
|
2322
|
+
"postgresql",
|
|
2323
|
+
"pgvector",
|
|
2324
|
+
"supabase",
|
|
2325
|
+
"pinecone",
|
|
2326
|
+
"qdrant",
|
|
2327
|
+
"mongodb",
|
|
2328
|
+
"milvus",
|
|
2329
|
+
"chroma",
|
|
2330
|
+
"chromadb"
|
|
2331
|
+
];
|
|
2332
|
+
if (!allowedPro.includes(normalizedProvider)) {
|
|
2333
|
+
throw new Error(
|
|
2334
|
+
`The database provider "${provider}" is not allowed on the Developer Pro tier. Please upgrade to an Enterprise plan.`
|
|
2335
|
+
);
|
|
2336
|
+
}
|
|
2337
|
+
}
|
|
2338
|
+
}
|
|
2339
|
+
if (licenseKey) {
|
|
2340
|
+
const cacheKey = `${licenseKey}:${currentProjectId}:${provider || ""}:${publicKeyOverride || ""}`;
|
|
2341
|
+
this.cache.set(cacheKey, { payload, cachedAt: now });
|
|
2342
|
+
}
|
|
2343
|
+
return payload;
|
|
2344
|
+
} catch (err) {
|
|
2345
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
2346
|
+
throw new ConfigurationException(
|
|
2347
|
+
`[Retrivora SDK] License key validation failed: ${message}`
|
|
2348
|
+
);
|
|
2349
|
+
}
|
|
2350
|
+
}
|
|
2351
|
+
static async verifyIP(licenseKey) {
|
|
2352
|
+
if (!licenseKey) return;
|
|
2353
|
+
try {
|
|
2354
|
+
const parts = licenseKey.split(".");
|
|
2355
|
+
if (parts.length !== 3) return;
|
|
2356
|
+
const [, payloadB64] = parts;
|
|
2357
|
+
const payload = JSON.parse(
|
|
2358
|
+
Buffer.from(payloadB64, "base64url").toString("utf8")
|
|
2359
|
+
);
|
|
2360
|
+
const tier = (payload.tier || "").toLowerCase();
|
|
2361
|
+
if (tier === "enterprise" || tier === "custom") {
|
|
2362
|
+
return;
|
|
2363
|
+
}
|
|
2364
|
+
if (payload.ipv4 || payload.ipv6) {
|
|
2365
|
+
let currentIpv4 = "";
|
|
2366
|
+
let currentIpv6 = "";
|
|
2367
|
+
try {
|
|
2368
|
+
const res = await fetch("https://api4.ipify.org?format=json", { signal: AbortSignal.timeout(3e3) });
|
|
2369
|
+
const data = await res.json();
|
|
2370
|
+
currentIpv4 = data.ip;
|
|
2371
|
+
} catch (e) {
|
|
2372
|
+
}
|
|
2373
|
+
try {
|
|
2374
|
+
const res = await fetch("https://api6.ipify.org?format=json", { signal: AbortSignal.timeout(3e3) });
|
|
2375
|
+
const data = await res.json();
|
|
2376
|
+
currentIpv6 = data.ip;
|
|
2377
|
+
} catch (e) {
|
|
2378
|
+
}
|
|
2379
|
+
const localIps = [];
|
|
2380
|
+
try {
|
|
2381
|
+
const osModule = require("os");
|
|
2382
|
+
const interfaces = osModule.networkInterfaces();
|
|
2383
|
+
for (const name of Object.keys(interfaces)) {
|
|
2384
|
+
for (const iface of interfaces[name] || []) {
|
|
2385
|
+
if (!iface.internal) {
|
|
2386
|
+
localIps.push(iface.address);
|
|
2387
|
+
}
|
|
2388
|
+
}
|
|
2389
|
+
}
|
|
2390
|
+
} catch (e) {
|
|
2391
|
+
}
|
|
2392
|
+
const isIpv4Match = payload.ipv4 && (currentIpv4 === payload.ipv4 || localIps.includes(payload.ipv4));
|
|
2393
|
+
const isIpv6Match = payload.ipv6 && (currentIpv6 === payload.ipv6 || localIps.includes(payload.ipv6));
|
|
2394
|
+
if (payload.ipv4 && payload.ipv6) {
|
|
2395
|
+
if (!isIpv4Match && !isIpv6Match) {
|
|
2396
|
+
throw new Error(
|
|
2397
|
+
`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.`
|
|
2398
|
+
);
|
|
2399
|
+
}
|
|
2400
|
+
} else if (payload.ipv4 && !isIpv4Match) {
|
|
2401
|
+
throw new Error(
|
|
2402
|
+
`License key access restricted. This license key was created for a different system (authorized IPv4: ${payload.ipv4}) and cannot be used on this machine.`
|
|
2403
|
+
);
|
|
2404
|
+
} else if (payload.ipv6 && !isIpv6Match) {
|
|
2405
|
+
throw new Error(
|
|
2406
|
+
`License key access restricted. This license key was created for a different system (authorized IPv6: ${payload.ipv6}) and cannot be used on this machine.`
|
|
2407
|
+
);
|
|
2408
|
+
}
|
|
2409
|
+
}
|
|
2410
|
+
} catch (err) {
|
|
2411
|
+
if (err.message.includes("License key access restricted")) {
|
|
2412
|
+
throw new ConfigurationException(`[Retrivora SDK] ${err.message}`);
|
|
2413
|
+
}
|
|
2414
|
+
}
|
|
2415
|
+
}
|
|
2416
|
+
};
|
|
2417
|
+
// A simple in-memory cache to save CPU overhead of cryptographic signature checks.
|
|
2418
|
+
LicenseVerifier.cache = /* @__PURE__ */ new Map();
|
|
2419
|
+
LicenseVerifier.CACHE_TTL_MS = 60 * 1e3;
|
|
2420
|
+
// Cache verified license for 60 seconds
|
|
2421
|
+
// Retrivora's Public Key used to verify the license key signature.
|
|
2422
|
+
// In production, this matches the private key held by Retrivora SaaS.
|
|
2423
|
+
LicenseVerifier.PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----
|
|
2424
|
+
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArMieCkCBtTfByRNOserm
|
|
2425
|
+
XM4T0Am29JyNzB4XQPe+WJJ56CN73H1HLXx9n1ByFcxkEJ9po+SURj5DnvUXwEy+
|
|
2426
|
+
xstx33wDPpVmcMQe33j5CRYS0S4gICiNqIRN7XkTlJtrcXqrmh1/hdOAwfRbjO1T
|
|
2427
|
+
NVtORHwUwWfI/lBLyxUPGtKPed+0fQ7NtcW4o00JXxs3EjCB5BV9CbnXoTjQb/4h
|
|
2428
|
+
iwZof4l8rb7oaNzOsVg0RSyxsETX7Ex5sI0CjBz1p2mYp4oVhw/A/h8Ls7H0XzjC
|
|
2429
|
+
+Eb6BLtsytt5JHoSp0jExLlCpDmpys2L+kETcBVx+IqiXtdN1n6KbkksvEDUVzLI
|
|
2430
|
+
MwIDAQAB
|
|
2431
|
+
-----END PUBLIC KEY-----`;
|
|
2432
|
+
|
|
2154
2433
|
// src/config/constants.ts
|
|
2155
2434
|
var VECTOR_DB_PROVIDERS = [
|
|
2156
2435
|
"pinecone",
|
|
@@ -2223,14 +2502,12 @@ function getRagConfig(baseConfig, env = process.env) {
|
|
|
2223
2502
|
return getEnvConfig(env, baseConfig);
|
|
2224
2503
|
}
|
|
2225
2504
|
function getEnvConfig(env = process.env, base) {
|
|
2226
|
-
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;
|
|
2505
|
+
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;
|
|
2227
2506
|
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__";
|
|
2228
2507
|
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;
|
|
2229
2508
|
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);
|
|
2230
2509
|
const vectorProvider = readEnum(env, "VECTOR_DB_PROVIDER", "pinecone", VECTOR_DB_PROVIDERS);
|
|
2231
|
-
const
|
|
2232
|
-
const embeddingProvider = readEnum(env, "EMBEDDING_PROVIDER", "openai", EMBEDDING_PROVIDERS);
|
|
2233
|
-
const embeddingDimensions = readNumber(env, "EMBEDDING_DIMENSIONS", 1536);
|
|
2510
|
+
const embeddingDimensions = readNumber(env, "EMBEDDING_DIMENSIONS", 768);
|
|
2234
2511
|
const vectorDbOptions = {};
|
|
2235
2512
|
if (vectorProvider === "pinecone") {
|
|
2236
2513
|
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 : "";
|
|
@@ -2295,65 +2572,88 @@ function getEnvConfig(env = process.env, base) {
|
|
|
2295
2572
|
rest: "default",
|
|
2296
2573
|
custom: "default"
|
|
2297
2574
|
};
|
|
2575
|
+
const isFreeTier = (() => {
|
|
2576
|
+
if (!licenseKey) return true;
|
|
2577
|
+
try {
|
|
2578
|
+
const payload = LicenseVerifier.verify(licenseKey, projectId);
|
|
2579
|
+
const tier = (payload.tier || "").toLowerCase();
|
|
2580
|
+
return tier === "free_trial" || tier === "free_tier" || tier === "free" || tier === "hobby";
|
|
2581
|
+
} catch (e) {
|
|
2582
|
+
return true;
|
|
2583
|
+
}
|
|
2584
|
+
})();
|
|
2585
|
+
const DEFAULT_FREE_GATEWAY = "https://llm.retrivora.com/api/v1";
|
|
2586
|
+
const defaultLlmProvider = isFreeTier ? "universal_rest" : "universal_rest";
|
|
2587
|
+
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;
|
|
2588
|
+
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;
|
|
2589
|
+
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";
|
|
2590
|
+
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";
|
|
2591
|
+
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";
|
|
2592
|
+
const defaultEmbeddingProvider = isFreeTier ? "universal_rest" : "universal_rest";
|
|
2593
|
+
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;
|
|
2594
|
+
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;
|
|
2595
|
+
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";
|
|
2596
|
+
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";
|
|
2597
|
+
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";
|
|
2298
2598
|
return __spreadProps(__spreadValues({
|
|
2299
2599
|
projectId,
|
|
2300
|
-
licenseKey
|
|
2600
|
+
licenseKey,
|
|
2301
2601
|
vectorDb: {
|
|
2302
2602
|
provider: vectorProvider,
|
|
2303
|
-
indexName: (
|
|
2603
|
+
indexName: (_Wa = (_Va = readString(env, "VECTOR_DB_INDEX")) != null ? _Va : vectorDbOptions.indexName) != null ? _Wa : "rag-index",
|
|
2304
2604
|
options: vectorDbOptions
|
|
2305
2605
|
},
|
|
2306
2606
|
llm: {
|
|
2307
2607
|
provider: llmProvider,
|
|
2308
|
-
model:
|
|
2309
|
-
apiKey:
|
|
2310
|
-
baseUrl:
|
|
2608
|
+
model: llmModel,
|
|
2609
|
+
apiKey: llmApiKey,
|
|
2610
|
+
baseUrl: llmBaseUrl,
|
|
2311
2611
|
systemPrompt: readString(env, "LLM_SYSTEM_PROMPT"),
|
|
2312
2612
|
maxTokens: readNumber(env, "LLM_MAX_TOKENS", 4096),
|
|
2313
2613
|
temperature: readNumber(env, "LLM_TEMPERATURE", 0.7),
|
|
2314
2614
|
options: {
|
|
2315
|
-
profile:
|
|
2615
|
+
profile: llmProfile,
|
|
2316
2616
|
thinking: readString(env, "LLM_THINKING") === "true" || readString(env, "LLM_THINKING") === "enabled" ? true : readString(env, "LLM_THINKING") === "false" ? false : void 0,
|
|
2317
2617
|
thinkingBudget: env.LLM_THINKING_BUDGET ? parseInt(env.LLM_THINKING_BUDGET, 10) : void 0
|
|
2318
2618
|
}
|
|
2319
2619
|
},
|
|
2320
2620
|
embedding: {
|
|
2321
2621
|
provider: embeddingProvider,
|
|
2322
|
-
model:
|
|
2323
|
-
apiKey:
|
|
2324
|
-
baseUrl:
|
|
2622
|
+
model: embeddingModel,
|
|
2623
|
+
apiKey: embeddingApiKey,
|
|
2624
|
+
baseUrl: embeddingBaseUrl,
|
|
2325
2625
|
dimensions: embeddingDimensions,
|
|
2326
2626
|
queryPrefix: readString(env, "EMBEDDING_QUERY_PREFIX"),
|
|
2327
2627
|
documentPrefix: readString(env, "EMBEDDING_DOCUMENT_PREFIX"),
|
|
2328
2628
|
options: {
|
|
2329
|
-
profile:
|
|
2629
|
+
profile: embeddingProfile
|
|
2330
2630
|
}
|
|
2331
2631
|
},
|
|
2332
2632
|
ui: {
|
|
2333
|
-
title: (
|
|
2334
|
-
subtitle: (
|
|
2335
|
-
primaryColor: (
|
|
2336
|
-
accentColor: (
|
|
2337
|
-
logoUrl: (
|
|
2338
|
-
placeholder: (
|
|
2339
|
-
showSources: ((
|
|
2340
|
-
welcomeMessage: (
|
|
2341
|
-
visualStyle: (
|
|
2342
|
-
borderRadius: (
|
|
2343
|
-
allowUpload: ((
|
|
2633
|
+
title: (_Ya = (_Xa = readString(env, "NEXT_PUBLIC_UI_TITLE")) != null ? _Xa : readString(env, "UI_TITLE")) != null ? _Ya : "AI Assistant",
|
|
2634
|
+
subtitle: (__a = (_Za = readString(env, "NEXT_PUBLIC_UI_SUBTITLE")) != null ? _Za : readString(env, "UI_SUBTITLE")) != null ? __a : "Powered by RAG",
|
|
2635
|
+
primaryColor: (_ab = (_$a = readString(env, "NEXT_PUBLIC_PRIMARY_COLOR")) != null ? _$a : readString(env, "UI_PRIMARY_COLOR")) != null ? _ab : "#10b981",
|
|
2636
|
+
accentColor: (_cb = (_bb = readString(env, "NEXT_PUBLIC_ACCENT_COLOR")) != null ? _bb : readString(env, "UI_ACCENT_COLOR")) != null ? _cb : "#3b82f6",
|
|
2637
|
+
logoUrl: (_db = readString(env, "NEXT_PUBLIC_LOGO_URL")) != null ? _db : readString(env, "UI_LOGO_URL"),
|
|
2638
|
+
placeholder: (_fb = (_eb = readString(env, "NEXT_PUBLIC_PLACEHOLDER")) != null ? _eb : readString(env, "UI_PLACEHOLDER")) != null ? _fb : "Ask me anything\u2026",
|
|
2639
|
+
showSources: ((_hb = (_gb = readString(env, "NEXT_PUBLIC_SHOW_SOURCES")) != null ? _gb : readString(env, "UI_SHOW_SOURCES")) != null ? _hb : "true") !== "false",
|
|
2640
|
+
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.",
|
|
2641
|
+
visualStyle: (_lb = (_kb = readString(env, "NEXT_PUBLIC_UI_VISUAL_STYLE")) != null ? _kb : readString(env, "UI_VISUAL_STYLE")) != null ? _lb : "glass",
|
|
2642
|
+
borderRadius: (_nb = (_mb = readString(env, "NEXT_PUBLIC_UI_BORDER_RADIUS")) != null ? _mb : readString(env, "UI_BORDER_RADIUS")) != null ? _nb : "xl",
|
|
2643
|
+
allowUpload: ((_pb = (_ob = readString(env, "NEXT_PUBLIC_ALLOW_UPLOAD")) != null ? _ob : readString(env, "UI_ALLOW_UPLOAD")) != null ? _pb : "false") === "true"
|
|
2344
2644
|
},
|
|
2345
2645
|
rag: {
|
|
2346
2646
|
topK: readNumber(env, "RAG_TOP_K", 5),
|
|
2347
2647
|
scoreThreshold: readNumber(env, "RAG_SCORE_THRESHOLD", 0),
|
|
2348
2648
|
chunkSize: readNumber(env, "RAG_CHUNK_SIZE", 1e3),
|
|
2349
2649
|
chunkOverlap: readNumber(env, "RAG_CHUNK_OVERLAP", 200),
|
|
2350
|
-
filterableFields: (
|
|
2650
|
+
filterableFields: (_qb = readString(env, "RAG_FILTERABLE_FIELDS")) == null ? void 0 : _qb.split(",").map((f) => f.trim()),
|
|
2351
2651
|
// Query pipeline toggles — read from .env.local
|
|
2352
2652
|
useQueryTransformation: readString(env, "RAG_USE_QUERY_TRANSFORMATION") === "true",
|
|
2353
2653
|
useReranking: readString(env, "RAG_USE_RERANKING") === "true",
|
|
2354
2654
|
useGraphRetrieval: readString(env, "RAG_USE_GRAPH_RETRIEVAL") === "true",
|
|
2355
|
-
architecture: (
|
|
2356
|
-
chunkingStrategy: (
|
|
2655
|
+
architecture: (_rb = readString(env, "RAG_ARCHITECTURE")) != null ? _rb : "simple",
|
|
2656
|
+
chunkingStrategy: (_sb = readString(env, "RAG_CHUNKING_STRATEGY")) != null ? _sb : "recursive",
|
|
2357
2657
|
uiMapping: (() => {
|
|
2358
2658
|
const raw = readString(env, "RAG_UI_MAPPING");
|
|
2359
2659
|
if (!raw) return void 0;
|
|
@@ -2366,7 +2666,7 @@ function getEnvConfig(env = process.env, base) {
|
|
|
2366
2666
|
},
|
|
2367
2667
|
telemetry: {
|
|
2368
2668
|
enabled: telemetryEnabled,
|
|
2369
|
-
url: (
|
|
2669
|
+
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"
|
|
2370
2670
|
}
|
|
2371
2671
|
}, readString(env, "GRAPH_DB_PROVIDER") ? {
|
|
2372
2672
|
graphDb: {
|
|
@@ -2853,10 +3153,12 @@ var AnthropicProvider = class {
|
|
|
2853
3153
|
var import_axios = __toESM(require("axios"));
|
|
2854
3154
|
var OllamaProvider = class {
|
|
2855
3155
|
constructor(llmConfig, embeddingConfig) {
|
|
2856
|
-
var _a2, _b;
|
|
2857
|
-
const
|
|
3156
|
+
var _a2, _b, _c;
|
|
3157
|
+
const rawBaseURL = ((_a2 = llmConfig.baseUrl) != null ? _a2 : "http://localhost:11434").replace(/\/+$/, "");
|
|
3158
|
+
const baseURL = rawBaseURL.replace(/\/(?:api\/v1|v1|api)$/i, "");
|
|
2858
3159
|
const timeout = Number((_b = llmConfig.options) == null ? void 0 : _b.timeout) || 3e5;
|
|
2859
|
-
|
|
3160
|
+
const headers = ((_c = llmConfig.options) == null ? void 0 : _c.headers) || {};
|
|
3161
|
+
this.http = import_axios.default.create({ baseURL, timeout, headers });
|
|
2860
3162
|
this.llmConfig = llmConfig;
|
|
2861
3163
|
this.embeddingConfig = embeddingConfig;
|
|
2862
3164
|
}
|
|
@@ -3831,113 +4133,41 @@ ${context != null ? context : "None"}` },
|
|
|
3831
4133
|
if (this.opts.embedPayloadTemplate) {
|
|
3832
4134
|
payload = buildPayload(this.opts.embedPayloadTemplate, {
|
|
3833
4135
|
model: this.model,
|
|
3834
|
-
input: text
|
|
3835
|
-
});
|
|
3836
|
-
} else {
|
|
3837
|
-
payload = {
|
|
3838
|
-
model: this.model,
|
|
3839
|
-
input: text
|
|
3840
|
-
};
|
|
3841
|
-
}
|
|
3842
|
-
const { data } = await this.http.post(path2, payload);
|
|
3843
|
-
const extractPath = (_b = this.opts.embedExtractPath) != null ? _b : "data[0].embedding";
|
|
3844
|
-
const vector = resolvePath(data, extractPath);
|
|
3845
|
-
if (!Array.isArray(vector)) {
|
|
3846
|
-
throw new Error(`[UniversalLLMAdapter] Expected a number array at '${extractPath}' for embeddings.`);
|
|
3847
|
-
}
|
|
3848
|
-
return vector;
|
|
3849
|
-
}
|
|
3850
|
-
async batchEmbed(texts) {
|
|
3851
|
-
const vectors = [];
|
|
3852
|
-
for (const text of texts) {
|
|
3853
|
-
vectors.push(await this.embed(text));
|
|
3854
|
-
}
|
|
3855
|
-
return vectors;
|
|
3856
|
-
}
|
|
3857
|
-
async ping() {
|
|
3858
|
-
try {
|
|
3859
|
-
if (this.opts.pingPath) {
|
|
3860
|
-
await this.http.get(this.opts.pingPath);
|
|
3861
|
-
}
|
|
3862
|
-
return true;
|
|
3863
|
-
} catch (err) {
|
|
3864
|
-
console.error("[UniversalLLMAdapter] Ping failed:", err);
|
|
3865
|
-
return false;
|
|
3866
|
-
}
|
|
3867
|
-
}
|
|
3868
|
-
};
|
|
3869
|
-
|
|
3870
|
-
// src/exceptions/index.ts
|
|
3871
|
-
var RetrivoraError = class extends Error {
|
|
3872
|
-
constructor(message, code, details) {
|
|
3873
|
-
super(message);
|
|
3874
|
-
this.name = new.target.name;
|
|
3875
|
-
this.code = code;
|
|
3876
|
-
this.details = details;
|
|
3877
|
-
}
|
|
3878
|
-
};
|
|
3879
|
-
var ProviderNotFoundException = class extends RetrivoraError {
|
|
3880
|
-
constructor(providerType, provider, details) {
|
|
3881
|
-
super(`Unsupported ${providerType} provider: ${provider}`, "PROVIDER_NOT_FOUND", details);
|
|
3882
|
-
}
|
|
3883
|
-
};
|
|
3884
|
-
var EmbeddingFailedException = class extends RetrivoraError {
|
|
3885
|
-
constructor(message = "Embedding generation failed", details) {
|
|
3886
|
-
super(message, "EMBEDDING_FAILED", details);
|
|
3887
|
-
}
|
|
3888
|
-
};
|
|
3889
|
-
var RetrievalException = class extends RetrivoraError {
|
|
3890
|
-
constructor(message = "Retrieval failed", details) {
|
|
3891
|
-
super(message, "RETRIEVAL_FAILED", details);
|
|
3892
|
-
}
|
|
3893
|
-
};
|
|
3894
|
-
var RateLimitException = class extends RetrivoraError {
|
|
3895
|
-
constructor(message = "Provider rate limit exceeded", details) {
|
|
3896
|
-
super(message, "RATE_LIMITED", details);
|
|
3897
|
-
}
|
|
3898
|
-
};
|
|
3899
|
-
var ConfigurationException = class extends RetrivoraError {
|
|
3900
|
-
constructor(message, details) {
|
|
3901
|
-
super(message, "CONFIGURATION_ERROR", details);
|
|
3902
|
-
}
|
|
3903
|
-
};
|
|
3904
|
-
var AuthenticationException = class extends RetrivoraError {
|
|
3905
|
-
constructor(message = "Provider authentication failed", details) {
|
|
3906
|
-
super(message, "AUTHENTICATION_ERROR", details);
|
|
3907
|
-
}
|
|
3908
|
-
};
|
|
3909
|
-
function wrapError(err, defaultCode, defaultMessage) {
|
|
3910
|
-
var _a2;
|
|
3911
|
-
if (err instanceof RetrivoraError) {
|
|
3912
|
-
return err;
|
|
3913
|
-
}
|
|
3914
|
-
const error = err;
|
|
3915
|
-
const message = (error == null ? void 0 : error.message) || defaultMessage || String(err);
|
|
3916
|
-
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);
|
|
3917
|
-
const code = error == null ? void 0 : error.code;
|
|
3918
|
-
if (status === 429 || /rate[- ]?limit/i.test(message) || code === "RATE_LIMIT_EXCEEDED") {
|
|
3919
|
-
return new RateLimitException(message, err);
|
|
4136
|
+
input: text
|
|
4137
|
+
});
|
|
4138
|
+
} else {
|
|
4139
|
+
payload = {
|
|
4140
|
+
model: this.model,
|
|
4141
|
+
input: text
|
|
4142
|
+
};
|
|
4143
|
+
}
|
|
4144
|
+
const { data } = await this.http.post(path2, payload);
|
|
4145
|
+
const extractPath = (_b = this.opts.embedExtractPath) != null ? _b : "data[0].embedding";
|
|
4146
|
+
const vector = resolvePath(data, extractPath);
|
|
4147
|
+
if (!Array.isArray(vector)) {
|
|
4148
|
+
throw new Error(`[UniversalLLMAdapter] Expected a number array at '${extractPath}' for embeddings.`);
|
|
4149
|
+
}
|
|
4150
|
+
return vector;
|
|
3920
4151
|
}
|
|
3921
|
-
|
|
3922
|
-
|
|
4152
|
+
async batchEmbed(texts) {
|
|
4153
|
+
const vectors = [];
|
|
4154
|
+
for (const text of texts) {
|
|
4155
|
+
vectors.push(await this.embed(text));
|
|
4156
|
+
}
|
|
4157
|
+
return vectors;
|
|
3923
4158
|
}
|
|
3924
|
-
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
|
|
3932
|
-
return
|
|
3933
|
-
|
|
3934
|
-
return new ConfigurationException(message, err);
|
|
3935
|
-
case "AUTHENTICATION_ERROR":
|
|
3936
|
-
return new AuthenticationException(message, err);
|
|
3937
|
-
default:
|
|
3938
|
-
return new RetrivoraError(message, defaultCode, err);
|
|
4159
|
+
async ping() {
|
|
4160
|
+
try {
|
|
4161
|
+
if (this.opts.pingPath) {
|
|
4162
|
+
await this.http.get(this.opts.pingPath);
|
|
4163
|
+
}
|
|
4164
|
+
return true;
|
|
4165
|
+
} catch (err) {
|
|
4166
|
+
console.error("[UniversalLLMAdapter] Ping failed:", err);
|
|
4167
|
+
return false;
|
|
4168
|
+
}
|
|
3939
4169
|
}
|
|
3940
|
-
}
|
|
4170
|
+
};
|
|
3941
4171
|
|
|
3942
4172
|
// src/llm/LLMFactory.ts
|
|
3943
4173
|
var customProviders = /* @__PURE__ */ new Map();
|
|
@@ -4336,211 +4566,6 @@ var ConfigValidator = class {
|
|
|
4336
4566
|
}
|
|
4337
4567
|
};
|
|
4338
4568
|
|
|
4339
|
-
// src/core/LicenseVerifier.ts
|
|
4340
|
-
var crypto2 = __toESM(require("crypto"));
|
|
4341
|
-
var LicenseVerifier = class {
|
|
4342
|
-
/**
|
|
4343
|
-
* Decodes, verifies signature, and checks metadata of a license key.
|
|
4344
|
-
*
|
|
4345
|
-
* @param licenseKey - Base64url signed JWT license key.
|
|
4346
|
-
* @param currentProjectId - Project namespace ID.
|
|
4347
|
-
* @param publicKeyOverride - Optional override for unit/integration tests.
|
|
4348
|
-
*/
|
|
4349
|
-
static verify(licenseKey, currentProjectId, provider, publicKeyOverride) {
|
|
4350
|
-
const isProduction = process.env.NODE_ENV === "production";
|
|
4351
|
-
const now = Date.now();
|
|
4352
|
-
if (licenseKey) {
|
|
4353
|
-
const cacheKey = `${licenseKey}:${currentProjectId}:${provider || ""}:${publicKeyOverride || ""}`;
|
|
4354
|
-
const cached = this.cache.get(cacheKey);
|
|
4355
|
-
if (cached && now - cached.cachedAt < this.CACHE_TTL_MS) {
|
|
4356
|
-
const currentTimestampSec = Math.floor(now / 1e3);
|
|
4357
|
-
if (cached.payload.expiresAt && currentTimestampSec > cached.payload.expiresAt) {
|
|
4358
|
-
this.cache.delete(cacheKey);
|
|
4359
|
-
} else {
|
|
4360
|
-
return cached.payload;
|
|
4361
|
-
}
|
|
4362
|
-
}
|
|
4363
|
-
}
|
|
4364
|
-
if (!licenseKey) {
|
|
4365
|
-
if (isProduction) {
|
|
4366
|
-
throw new ConfigurationException(
|
|
4367
|
-
"[Retrivora SDK] License key (licenseKey) is required in production environments."
|
|
4368
|
-
);
|
|
4369
|
-
}
|
|
4370
|
-
console.warn(
|
|
4371
|
-
`\x1B[33m[Retrivora SDK] WARNING: Running without a license key. This namespace (${currentProjectId}) is permitted for local development only.\x1B[0m`
|
|
4372
|
-
);
|
|
4373
|
-
return {
|
|
4374
|
-
projectId: currentProjectId,
|
|
4375
|
-
expiresAt: Math.floor(Date.now() / 1e3) + 86400,
|
|
4376
|
-
// Valid for 24h
|
|
4377
|
-
tier: "hobby"
|
|
4378
|
-
};
|
|
4379
|
-
}
|
|
4380
|
-
try {
|
|
4381
|
-
const parts = licenseKey.split(".");
|
|
4382
|
-
if (parts.length !== 3) {
|
|
4383
|
-
throw new Error("Malformed token structure (expected 3 parts).");
|
|
4384
|
-
}
|
|
4385
|
-
const [headerB64, payloadB64, signatureB64] = parts;
|
|
4386
|
-
const dataToVerify = `${headerB64}.${payloadB64}`;
|
|
4387
|
-
const publicKey = publicKeyOverride != null ? publicKeyOverride : this.PUBLIC_KEY;
|
|
4388
|
-
const signature = Buffer.from(signatureB64, "base64url");
|
|
4389
|
-
const data = Buffer.from(dataToVerify);
|
|
4390
|
-
const isValid = crypto2.verify(
|
|
4391
|
-
"sha256",
|
|
4392
|
-
data,
|
|
4393
|
-
publicKey,
|
|
4394
|
-
signature
|
|
4395
|
-
);
|
|
4396
|
-
if (!isValid) {
|
|
4397
|
-
throw new Error("Signature verification failed.");
|
|
4398
|
-
}
|
|
4399
|
-
const payload = JSON.parse(
|
|
4400
|
-
Buffer.from(payloadB64, "base64url").toString("utf8")
|
|
4401
|
-
);
|
|
4402
|
-
if (!payload.projectId) {
|
|
4403
|
-
throw new Error('License payload is missing "projectId".');
|
|
4404
|
-
}
|
|
4405
|
-
if (payload.projectId !== currentProjectId) {
|
|
4406
|
-
throw new Error(
|
|
4407
|
-
`Project ID mismatch. License is bound to project namespace "${payload.projectId}" but configuration has "${currentProjectId}".`
|
|
4408
|
-
);
|
|
4409
|
-
}
|
|
4410
|
-
if (!payload.expiresAt) {
|
|
4411
|
-
throw new Error('License payload is missing expiration ("expiresAt").');
|
|
4412
|
-
}
|
|
4413
|
-
const currentTimestampSec = Math.floor(Date.now() / 1e3);
|
|
4414
|
-
if (currentTimestampSec > payload.expiresAt) {
|
|
4415
|
-
throw new Error(
|
|
4416
|
-
`License key has expired. Expiration: ${new Date(
|
|
4417
|
-
payload.expiresAt * 1e3
|
|
4418
|
-
).toDateString()}`
|
|
4419
|
-
);
|
|
4420
|
-
}
|
|
4421
|
-
if (isProduction && provider) {
|
|
4422
|
-
const tier = (payload.tier || "").toLowerCase();
|
|
4423
|
-
const normalizedProvider = provider.toLowerCase();
|
|
4424
|
-
if (tier === "hobby") {
|
|
4425
|
-
const allowedHobby = ["postgresql", "pgvector", "supabase"];
|
|
4426
|
-
if (!allowedHobby.includes(normalizedProvider)) {
|
|
4427
|
-
throw new Error(
|
|
4428
|
-
`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.`
|
|
4429
|
-
);
|
|
4430
|
-
}
|
|
4431
|
-
} else if (tier === "pro" || tier === "developer_pro" || tier === "premium" || tier === "growth") {
|
|
4432
|
-
const allowedPro = [
|
|
4433
|
-
"postgresql",
|
|
4434
|
-
"pgvector",
|
|
4435
|
-
"supabase",
|
|
4436
|
-
"pinecone",
|
|
4437
|
-
"qdrant",
|
|
4438
|
-
"mongodb",
|
|
4439
|
-
"milvus",
|
|
4440
|
-
"chroma",
|
|
4441
|
-
"chromadb"
|
|
4442
|
-
];
|
|
4443
|
-
if (!allowedPro.includes(normalizedProvider)) {
|
|
4444
|
-
throw new Error(
|
|
4445
|
-
`The database provider "${provider}" is not allowed on the Developer Pro tier. Please upgrade to an Enterprise plan.`
|
|
4446
|
-
);
|
|
4447
|
-
}
|
|
4448
|
-
}
|
|
4449
|
-
}
|
|
4450
|
-
if (licenseKey) {
|
|
4451
|
-
const cacheKey = `${licenseKey}:${currentProjectId}:${provider || ""}:${publicKeyOverride || ""}`;
|
|
4452
|
-
this.cache.set(cacheKey, { payload, cachedAt: now });
|
|
4453
|
-
}
|
|
4454
|
-
return payload;
|
|
4455
|
-
} catch (err) {
|
|
4456
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
4457
|
-
throw new ConfigurationException(
|
|
4458
|
-
`[Retrivora SDK] License key validation failed: ${message}`
|
|
4459
|
-
);
|
|
4460
|
-
}
|
|
4461
|
-
}
|
|
4462
|
-
static async verifyIP(licenseKey) {
|
|
4463
|
-
if (!licenseKey) return;
|
|
4464
|
-
try {
|
|
4465
|
-
const parts = licenseKey.split(".");
|
|
4466
|
-
if (parts.length !== 3) return;
|
|
4467
|
-
const [, payloadB64] = parts;
|
|
4468
|
-
const payload = JSON.parse(
|
|
4469
|
-
Buffer.from(payloadB64, "base64url").toString("utf8")
|
|
4470
|
-
);
|
|
4471
|
-
const tier = (payload.tier || "").toLowerCase();
|
|
4472
|
-
if (tier === "enterprise" || tier === "custom") {
|
|
4473
|
-
return;
|
|
4474
|
-
}
|
|
4475
|
-
if (payload.ipv4 || payload.ipv6) {
|
|
4476
|
-
let currentIpv4 = "";
|
|
4477
|
-
let currentIpv6 = "";
|
|
4478
|
-
try {
|
|
4479
|
-
const res = await fetch("https://api4.ipify.org?format=json", { signal: AbortSignal.timeout(3e3) });
|
|
4480
|
-
const data = await res.json();
|
|
4481
|
-
currentIpv4 = data.ip;
|
|
4482
|
-
} catch (e) {
|
|
4483
|
-
}
|
|
4484
|
-
try {
|
|
4485
|
-
const res = await fetch("https://api6.ipify.org?format=json", { signal: AbortSignal.timeout(3e3) });
|
|
4486
|
-
const data = await res.json();
|
|
4487
|
-
currentIpv6 = data.ip;
|
|
4488
|
-
} catch (e) {
|
|
4489
|
-
}
|
|
4490
|
-
const localIps = [];
|
|
4491
|
-
try {
|
|
4492
|
-
const osModule = require("os");
|
|
4493
|
-
const interfaces = osModule.networkInterfaces();
|
|
4494
|
-
for (const name of Object.keys(interfaces)) {
|
|
4495
|
-
for (const iface of interfaces[name] || []) {
|
|
4496
|
-
if (!iface.internal) {
|
|
4497
|
-
localIps.push(iface.address);
|
|
4498
|
-
}
|
|
4499
|
-
}
|
|
4500
|
-
}
|
|
4501
|
-
} catch (e) {
|
|
4502
|
-
}
|
|
4503
|
-
const isIpv4Match = payload.ipv4 && (currentIpv4 === payload.ipv4 || localIps.includes(payload.ipv4));
|
|
4504
|
-
const isIpv6Match = payload.ipv6 && (currentIpv6 === payload.ipv6 || localIps.includes(payload.ipv6));
|
|
4505
|
-
if (payload.ipv4 && payload.ipv6) {
|
|
4506
|
-
if (!isIpv4Match && !isIpv6Match) {
|
|
4507
|
-
throw new Error(
|
|
4508
|
-
`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.`
|
|
4509
|
-
);
|
|
4510
|
-
}
|
|
4511
|
-
} else if (payload.ipv4 && !isIpv4Match) {
|
|
4512
|
-
throw new Error(
|
|
4513
|
-
`License key access restricted. This license key was created for a different system (authorized IPv4: ${payload.ipv4}) and cannot be used on this machine.`
|
|
4514
|
-
);
|
|
4515
|
-
} else if (payload.ipv6 && !isIpv6Match) {
|
|
4516
|
-
throw new Error(
|
|
4517
|
-
`License key access restricted. This license key was created for a different system (authorized IPv6: ${payload.ipv6}) and cannot be used on this machine.`
|
|
4518
|
-
);
|
|
4519
|
-
}
|
|
4520
|
-
}
|
|
4521
|
-
} catch (err) {
|
|
4522
|
-
if (err.message.includes("License key access restricted")) {
|
|
4523
|
-
throw new ConfigurationException(`[Retrivora SDK] ${err.message}`);
|
|
4524
|
-
}
|
|
4525
|
-
}
|
|
4526
|
-
}
|
|
4527
|
-
};
|
|
4528
|
-
// A simple in-memory cache to save CPU overhead of cryptographic signature checks.
|
|
4529
|
-
LicenseVerifier.cache = /* @__PURE__ */ new Map();
|
|
4530
|
-
LicenseVerifier.CACHE_TTL_MS = 60 * 1e3;
|
|
4531
|
-
// Cache verified license for 60 seconds
|
|
4532
|
-
// Retrivora's Public Key used to verify the license key signature.
|
|
4533
|
-
// In production, this matches the private key held by Retrivora SaaS.
|
|
4534
|
-
LicenseVerifier.PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----
|
|
4535
|
-
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArMieCkCBtTfByRNOserm
|
|
4536
|
-
XM4T0Am29JyNzB4XQPe+WJJ56CN73H1HLXx9n1ByFcxkEJ9po+SURj5DnvUXwEy+
|
|
4537
|
-
xstx33wDPpVmcMQe33j5CRYS0S4gICiNqIRN7XkTlJtrcXqrmh1/hdOAwfRbjO1T
|
|
4538
|
-
NVtORHwUwWfI/lBLyxUPGtKPed+0fQ7NtcW4o00JXxs3EjCB5BV9CbnXoTjQb/4h
|
|
4539
|
-
iwZof4l8rb7oaNzOsVg0RSyxsETX7Ex5sI0CjBz1p2mYp4oVhw/A/h8Ls7H0XzjC
|
|
4540
|
-
+Eb6BLtsytt5JHoSp0jExLlCpDmpys2L+kETcBVx+IqiXtdN1n6KbkksvEDUVzLI
|
|
4541
|
-
MwIDAQAB
|
|
4542
|
-
-----END PUBLIC KEY-----`;
|
|
4543
|
-
|
|
4544
4569
|
// src/rag/DocumentChunker.ts
|
|
4545
4570
|
var DocumentChunker = class {
|
|
4546
4571
|
constructor(chunkSize = 1e3, chunkOverlap = 200, separators = ["\n# ", "\n## ", "\n### ", "\n#### ", "\n\n", "\n", " ", ""]) {
|
|
@@ -9642,7 +9667,7 @@ var DatabaseStorage = class {
|
|
|
9642
9667
|
try {
|
|
9643
9668
|
const payload = LicenseVerifier.verify(this.config.licenseKey, this.config.projectId);
|
|
9644
9669
|
const tier = (payload.tier || "").toLowerCase();
|
|
9645
|
-
if (tier !== "premium" && tier !== "enterprise" && tier !== "growth" && tier !== "pro" && tier !== "developer_pro") {
|
|
9670
|
+
if (tier !== "premium" && tier !== "enterprise" && tier !== "growth" && tier !== "pro" && tier !== "developer_pro" && tier !== "free_trial" && tier !== "free_tier" && tier !== "free" && tier !== "hobby") {
|
|
9646
9671
|
throw new Error(
|
|
9647
9672
|
`[Retrivora SDK] Chat History and Feedback features are not available on the "${tier}" tier. Please upgrade to a Developer Pro or Enterprise plan.`
|
|
9648
9673
|
);
|
|
@@ -10179,7 +10204,17 @@ function createChatHandler(configOrPlugin, options) {
|
|
|
10179
10204
|
if (rateLimited) return rateLimited;
|
|
10180
10205
|
try {
|
|
10181
10206
|
const body = await req.json();
|
|
10182
|
-
const
|
|
10207
|
+
const bodyObj = body != null ? body : {};
|
|
10208
|
+
let rawMessage = bodyObj.message;
|
|
10209
|
+
if (!rawMessage && Array.isArray(bodyObj.messages) && bodyObj.messages.length > 0) {
|
|
10210
|
+
const lastMsg = bodyObj.messages[bodyObj.messages.length - 1];
|
|
10211
|
+
rawMessage = typeof lastMsg === "string" ? lastMsg : (lastMsg == null ? void 0 : lastMsg.content) || (lastMsg == null ? void 0 : lastMsg.text);
|
|
10212
|
+
}
|
|
10213
|
+
if (!rawMessage && typeof bodyObj.prompt === "string") {
|
|
10214
|
+
rawMessage = bodyObj.prompt;
|
|
10215
|
+
}
|
|
10216
|
+
const history = bodyObj.history || (Array.isArray(bodyObj.messages) ? bodyObj.messages.slice(0, -1) : []);
|
|
10217
|
+
const { namespace, sessionId = "default", messageId, userMessageId } = bodyObj;
|
|
10183
10218
|
const sanitized = sanitizeInput(rawMessage != null ? rawMessage : "");
|
|
10184
10219
|
if (!sanitized.ok) {
|
|
10185
10220
|
return import_server.NextResponse.json({ error: { code: "INVALID_INPUT", message: sanitized.error } }, { status: 400 });
|
|
@@ -10231,7 +10266,17 @@ function createStreamHandler(configOrPlugin, options) {
|
|
|
10231
10266
|
headers: { "Content-Type": "application/json" }
|
|
10232
10267
|
});
|
|
10233
10268
|
}
|
|
10234
|
-
const
|
|
10269
|
+
const bodyObj = body != null ? body : {};
|
|
10270
|
+
let rawMessage = bodyObj.message;
|
|
10271
|
+
if (!rawMessage && Array.isArray(bodyObj.messages) && bodyObj.messages.length > 0) {
|
|
10272
|
+
const lastMsg = bodyObj.messages[bodyObj.messages.length - 1];
|
|
10273
|
+
rawMessage = typeof lastMsg === "string" ? lastMsg : (lastMsg == null ? void 0 : lastMsg.content) || (lastMsg == null ? void 0 : lastMsg.text);
|
|
10274
|
+
}
|
|
10275
|
+
if (!rawMessage && typeof bodyObj.prompt === "string") {
|
|
10276
|
+
rawMessage = bodyObj.prompt;
|
|
10277
|
+
}
|
|
10278
|
+
const history = bodyObj.history || (Array.isArray(bodyObj.messages) ? bodyObj.messages.slice(0, -1) : []);
|
|
10279
|
+
const { namespace, sessionId = "default", messageId, userMessageId } = bodyObj;
|
|
10235
10280
|
const sanitized = sanitizeInput(rawMessage != null ? rawMessage : "");
|
|
10236
10281
|
if (!sanitized.ok) {
|
|
10237
10282
|
return new Response(
|