@retrivora-ai/rag-engine 2.0.4 → 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/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 llmProvider = readEnum(env, "LLM_PROVIDER", "openai", LLM_PROVIDERS);
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: (_ma = (_la = readString(env, "RETRIVORA_LICENSE_KEY")) != null ? _la : readString(env, "LICENSE_KEY")) != null ? _ma : base == null ? void 0 : base.licenseKey,
2600
+ licenseKey,
2301
2601
  vectorDb: {
2302
2602
  provider: vectorProvider,
2303
- indexName: (_oa = (_na = readString(env, "VECTOR_DB_INDEX")) != null ? _na : vectorDbOptions.indexName) != null ? _oa : "rag-index",
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: (_qa = (_pa = readString(env, "LLM_MODEL")) != null ? _pa : DEFAULT_MODEL_BY_PROVIDER[llmProvider]) != null ? _qa : "gpt-4o",
2309
- apiKey: (_ra = llmApiKeyByProvider[llmProvider]) != null ? _ra : "",
2310
- baseUrl: readString(env, "LLM_BASE_URL"),
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: readString(env, "LLM_UNIVERSAL_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: (_sa = readString(env, "EMBEDDING_MODEL")) != null ? _sa : "text-embedding-3-small",
2323
- apiKey: embeddingApiKeyByProvider[embeddingProvider],
2324
- baseUrl: readString(env, "EMBEDDING_BASE_URL"),
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: readString(env, "EMBEDDING_UNIVERSAL_PROFILE")
2629
+ profile: embeddingProfile
2330
2630
  }
2331
2631
  },
2332
2632
  ui: {
2333
- title: (_ua = (_ta = readString(env, "NEXT_PUBLIC_UI_TITLE")) != null ? _ta : readString(env, "UI_TITLE")) != null ? _ua : "AI Assistant",
2334
- subtitle: (_wa = (_va = readString(env, "NEXT_PUBLIC_UI_SUBTITLE")) != null ? _va : readString(env, "UI_SUBTITLE")) != null ? _wa : "Powered by RAG",
2335
- primaryColor: (_ya = (_xa = readString(env, "NEXT_PUBLIC_PRIMARY_COLOR")) != null ? _xa : readString(env, "UI_PRIMARY_COLOR")) != null ? _ya : "#10b981",
2336
- accentColor: (_Aa = (_za = readString(env, "NEXT_PUBLIC_ACCENT_COLOR")) != null ? _za : readString(env, "UI_ACCENT_COLOR")) != null ? _Aa : "#3b82f6",
2337
- logoUrl: (_Ba = readString(env, "NEXT_PUBLIC_LOGO_URL")) != null ? _Ba : readString(env, "UI_LOGO_URL"),
2338
- placeholder: (_Da = (_Ca = readString(env, "NEXT_PUBLIC_PLACEHOLDER")) != null ? _Ca : readString(env, "UI_PLACEHOLDER")) != null ? _Da : "Ask me anything\u2026",
2339
- showSources: ((_Fa = (_Ea = readString(env, "NEXT_PUBLIC_SHOW_SOURCES")) != null ? _Ea : readString(env, "UI_SHOW_SOURCES")) != null ? _Fa : "true") !== "false",
2340
- welcomeMessage: (_Ha = (_Ga = readString(env, "NEXT_PUBLIC_WELCOME_MESSAGE")) != null ? _Ga : readString(env, "UI_WELCOME_MESSAGE")) != null ? _Ha : "Hello! I'm your AI assistant. Ask me anything about your documents.",
2341
- visualStyle: (_Ja = (_Ia = readString(env, "NEXT_PUBLIC_UI_VISUAL_STYLE")) != null ? _Ia : readString(env, "UI_VISUAL_STYLE")) != null ? _Ja : "glass",
2342
- borderRadius: (_La = (_Ka = readString(env, "NEXT_PUBLIC_UI_BORDER_RADIUS")) != null ? _Ka : readString(env, "UI_BORDER_RADIUS")) != null ? _La : "xl",
2343
- allowUpload: ((_Na = (_Ma = readString(env, "NEXT_PUBLIC_ALLOW_UPLOAD")) != null ? _Ma : readString(env, "UI_ALLOW_UPLOAD")) != null ? _Na : "false") === "true"
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: (_Oa = readString(env, "RAG_FILTERABLE_FIELDS")) == null ? void 0 : _Oa.split(",").map((f) => f.trim()),
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: (_Pa = readString(env, "RAG_ARCHITECTURE")) != null ? _Pa : "simple",
2356
- chunkingStrategy: (_Qa = readString(env, "RAG_CHUNKING_STRATEGY")) != null ? _Qa : "recursive",
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: (_Ua = (_Ta = (_Ra = readString(env, "TELEMETRY_URL")) != null ? _Ra : readString(env, "NEXT_PUBLIC_TELEMETRY_URL")) != null ? _Ta : (_Sa = base == null ? void 0 : base.telemetry) == null ? void 0 : _Sa.url) != null ? _Ua : process.env.NODE_ENV === "development" ? "http://localhost:3001/api/telemetry" : "https://retrivora.com/api/telemetry"
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 baseURL = (_a2 = llmConfig.baseUrl) != null ? _a2 : "http://localhost:11434";
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
- this.http = import_axios.default.create({ baseURL, timeout });
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
  }
@@ -3832,112 +4134,40 @@ ${context != null ? context : "None"}` },
3832
4134
  payload = buildPayload(this.opts.embedPayloadTemplate, {
3833
4135
  model: this.model,
3834
4136
  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);
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
- if (status === 401 || status === 403 || /unauthorized|auth|api[- ]?key/i.test(message) || code === "INVALID_API_KEY") {
3922
- return new AuthenticationException(message, err);
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
- switch (defaultCode) {
3925
- case "PROVIDER_NOT_FOUND":
3926
- return new ProviderNotFoundException("provider", message, err);
3927
- case "EMBEDDING_FAILED":
3928
- return new EmbeddingFailedException(message, err);
3929
- case "RETRIEVAL_FAILED":
3930
- return new RetrievalException(message, err);
3931
- case "RATE_LIMITED":
3932
- return new RateLimitException(message, err);
3933
- case "CONFIGURATION_ERROR":
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" || tier === "free_trial" || tier === "free_tier" || tier === "free") {
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", " ", ""]) {
@@ -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 { message: rawMessage, history = [], namespace, sessionId = "default", messageId, userMessageId } = body;
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 { message: rawMessage, history = [], namespace, sessionId = "default", messageId, userMessageId } = body;
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(