@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.mjs CHANGED
@@ -1239,7 +1239,7 @@ __export(QdrantProvider_exports, {
1239
1239
  QdrantProvider: () => QdrantProvider
1240
1240
  });
1241
1241
  import axios4 from "axios";
1242
- import crypto from "crypto";
1242
+ import crypto2 from "crypto";
1243
1243
  var QdrantProvider;
1244
1244
  var init_QdrantProvider = __esm({
1245
1245
  "src/providers/vectordb/QdrantProvider.ts"() {
@@ -1471,7 +1471,7 @@ var init_QdrantProvider = __esm({
1471
1471
  if (typeof id === "number") return id;
1472
1472
  const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
1473
1473
  if (uuidRegex.test(id)) return id.toLowerCase();
1474
- const hash = crypto.createHash("md5").update(id).digest("hex");
1474
+ const hash = crypto2.createHash("md5").update(id).digest("hex");
1475
1475
  return `${hash.slice(0, 8)}-${hash.slice(8, 12)}-${hash.slice(12, 16)}-${hash.slice(16, 20)}-${hash.slice(20, 32)}`;
1476
1476
  }
1477
1477
  async disconnect() {
@@ -2055,6 +2055,285 @@ var init_SimpleGraphProvider = __esm({
2055
2055
  // src/core/ConfigResolver.ts
2056
2056
  init_templateUtils();
2057
2057
 
2058
+ // src/core/LicenseVerifier.ts
2059
+ import * as crypto from "crypto";
2060
+
2061
+ // src/exceptions/index.ts
2062
+ var RetrivoraError = class extends Error {
2063
+ constructor(message, code, details) {
2064
+ super(message);
2065
+ this.name = new.target.name;
2066
+ this.code = code;
2067
+ this.details = details;
2068
+ }
2069
+ };
2070
+ var ProviderNotFoundException = class extends RetrivoraError {
2071
+ constructor(providerType, provider, details) {
2072
+ super(`Unsupported ${providerType} provider: ${provider}`, "PROVIDER_NOT_FOUND", details);
2073
+ }
2074
+ };
2075
+ var EmbeddingFailedException = class extends RetrivoraError {
2076
+ constructor(message = "Embedding generation failed", details) {
2077
+ super(message, "EMBEDDING_FAILED", details);
2078
+ }
2079
+ };
2080
+ var RetrievalException = class extends RetrivoraError {
2081
+ constructor(message = "Retrieval failed", details) {
2082
+ super(message, "RETRIEVAL_FAILED", details);
2083
+ }
2084
+ };
2085
+ var RateLimitException = class extends RetrivoraError {
2086
+ constructor(message = "Provider rate limit exceeded", details) {
2087
+ super(message, "RATE_LIMITED", details);
2088
+ }
2089
+ };
2090
+ var ConfigurationException = class extends RetrivoraError {
2091
+ constructor(message, details) {
2092
+ super(message, "CONFIGURATION_ERROR", details);
2093
+ }
2094
+ };
2095
+ var AuthenticationException = class extends RetrivoraError {
2096
+ constructor(message = "Provider authentication failed", details) {
2097
+ super(message, "AUTHENTICATION_ERROR", details);
2098
+ }
2099
+ };
2100
+ function wrapError(err, defaultCode, defaultMessage) {
2101
+ var _a2;
2102
+ if (err instanceof RetrivoraError) {
2103
+ return err;
2104
+ }
2105
+ const error = err;
2106
+ const message = (error == null ? void 0 : error.message) || defaultMessage || String(err);
2107
+ 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);
2108
+ const code = error == null ? void 0 : error.code;
2109
+ if (status === 429 || /rate[- ]?limit/i.test(message) || code === "RATE_LIMIT_EXCEEDED") {
2110
+ return new RateLimitException(message, err);
2111
+ }
2112
+ if (status === 401 || status === 403 || /unauthorized|auth|api[- ]?key/i.test(message) || code === "INVALID_API_KEY") {
2113
+ return new AuthenticationException(message, err);
2114
+ }
2115
+ switch (defaultCode) {
2116
+ case "PROVIDER_NOT_FOUND":
2117
+ return new ProviderNotFoundException("provider", message, err);
2118
+ case "EMBEDDING_FAILED":
2119
+ return new EmbeddingFailedException(message, err);
2120
+ case "RETRIEVAL_FAILED":
2121
+ return new RetrievalException(message, err);
2122
+ case "RATE_LIMITED":
2123
+ return new RateLimitException(message, err);
2124
+ case "CONFIGURATION_ERROR":
2125
+ return new ConfigurationException(message, err);
2126
+ case "AUTHENTICATION_ERROR":
2127
+ return new AuthenticationException(message, err);
2128
+ default:
2129
+ return new RetrivoraError(message, defaultCode, err);
2130
+ }
2131
+ }
2132
+
2133
+ // src/core/LicenseVerifier.ts
2134
+ var LicenseVerifier = class {
2135
+ /**
2136
+ * Decodes, verifies signature, and checks metadata of a license key.
2137
+ *
2138
+ * @param licenseKey - Base64url signed JWT license key.
2139
+ * @param currentProjectId - Project namespace ID.
2140
+ * @param publicKeyOverride - Optional override for unit/integration tests.
2141
+ */
2142
+ static verify(licenseKey, currentProjectId, provider, publicKeyOverride) {
2143
+ const isProduction = process.env.NODE_ENV === "production";
2144
+ const now = Date.now();
2145
+ if (licenseKey) {
2146
+ const cacheKey = `${licenseKey}:${currentProjectId}:${provider || ""}:${publicKeyOverride || ""}`;
2147
+ const cached = this.cache.get(cacheKey);
2148
+ if (cached && now - cached.cachedAt < this.CACHE_TTL_MS) {
2149
+ const currentTimestampSec = Math.floor(now / 1e3);
2150
+ if (cached.payload.expiresAt && currentTimestampSec > cached.payload.expiresAt) {
2151
+ this.cache.delete(cacheKey);
2152
+ } else {
2153
+ return cached.payload;
2154
+ }
2155
+ }
2156
+ }
2157
+ if (!licenseKey) {
2158
+ if (isProduction) {
2159
+ throw new ConfigurationException(
2160
+ "[Retrivora SDK] License key (licenseKey) is required in production environments."
2161
+ );
2162
+ }
2163
+ console.warn(
2164
+ `\x1B[33m[Retrivora SDK] WARNING: Running without a license key. This namespace (${currentProjectId}) is permitted for local development only.\x1B[0m`
2165
+ );
2166
+ return {
2167
+ projectId: currentProjectId,
2168
+ expiresAt: Math.floor(Date.now() / 1e3) + 86400,
2169
+ // Valid for 24h
2170
+ tier: "hobby"
2171
+ };
2172
+ }
2173
+ try {
2174
+ const parts = licenseKey.split(".");
2175
+ if (parts.length !== 3) {
2176
+ throw new Error("Malformed token structure (expected 3 parts).");
2177
+ }
2178
+ const [headerB64, payloadB64, signatureB64] = parts;
2179
+ const dataToVerify = `${headerB64}.${payloadB64}`;
2180
+ const publicKey = publicKeyOverride != null ? publicKeyOverride : this.PUBLIC_KEY;
2181
+ const signature = Buffer.from(signatureB64, "base64url");
2182
+ const data = Buffer.from(dataToVerify);
2183
+ const isValid = crypto.verify(
2184
+ "sha256",
2185
+ data,
2186
+ publicKey,
2187
+ signature
2188
+ );
2189
+ if (!isValid) {
2190
+ throw new Error("Signature verification failed.");
2191
+ }
2192
+ const payload = JSON.parse(
2193
+ Buffer.from(payloadB64, "base64url").toString("utf8")
2194
+ );
2195
+ if (!payload.projectId) {
2196
+ throw new Error('License payload is missing "projectId".');
2197
+ }
2198
+ if (payload.projectId !== currentProjectId) {
2199
+ throw new Error(
2200
+ `Project ID mismatch. License is bound to project namespace "${payload.projectId}" but configuration has "${currentProjectId}".`
2201
+ );
2202
+ }
2203
+ if (!payload.expiresAt) {
2204
+ throw new Error('License payload is missing expiration ("expiresAt").');
2205
+ }
2206
+ const currentTimestampSec = Math.floor(Date.now() / 1e3);
2207
+ if (currentTimestampSec > payload.expiresAt) {
2208
+ throw new Error(
2209
+ `License key has expired. Expiration: ${new Date(
2210
+ payload.expiresAt * 1e3
2211
+ ).toDateString()}`
2212
+ );
2213
+ }
2214
+ if (isProduction && provider) {
2215
+ const tier = (payload.tier || "").toLowerCase();
2216
+ const normalizedProvider = provider.toLowerCase();
2217
+ if (tier === "hobby") {
2218
+ const allowedHobby = ["postgresql", "pgvector", "supabase"];
2219
+ if (!allowedHobby.includes(normalizedProvider)) {
2220
+ throw new Error(
2221
+ `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.`
2222
+ );
2223
+ }
2224
+ } else if (tier === "pro" || tier === "developer_pro" || tier === "premium" || tier === "growth" || tier === "free_trial" || tier === "free_tier" || tier === "free") {
2225
+ const allowedPro = [
2226
+ "postgresql",
2227
+ "pgvector",
2228
+ "supabase",
2229
+ "pinecone",
2230
+ "qdrant",
2231
+ "mongodb",
2232
+ "milvus",
2233
+ "chroma",
2234
+ "chromadb"
2235
+ ];
2236
+ if (!allowedPro.includes(normalizedProvider)) {
2237
+ throw new Error(
2238
+ `The database provider "${provider}" is not allowed on the Developer Pro tier. Please upgrade to an Enterprise plan.`
2239
+ );
2240
+ }
2241
+ }
2242
+ }
2243
+ if (licenseKey) {
2244
+ const cacheKey = `${licenseKey}:${currentProjectId}:${provider || ""}:${publicKeyOverride || ""}`;
2245
+ this.cache.set(cacheKey, { payload, cachedAt: now });
2246
+ }
2247
+ return payload;
2248
+ } catch (err) {
2249
+ const message = err instanceof Error ? err.message : String(err);
2250
+ throw new ConfigurationException(
2251
+ `[Retrivora SDK] License key validation failed: ${message}`
2252
+ );
2253
+ }
2254
+ }
2255
+ static async verifyIP(licenseKey) {
2256
+ if (!licenseKey) return;
2257
+ try {
2258
+ const parts = licenseKey.split(".");
2259
+ if (parts.length !== 3) return;
2260
+ const [, payloadB64] = parts;
2261
+ const payload = JSON.parse(
2262
+ Buffer.from(payloadB64, "base64url").toString("utf8")
2263
+ );
2264
+ const tier = (payload.tier || "").toLowerCase();
2265
+ if (tier === "enterprise" || tier === "custom") {
2266
+ return;
2267
+ }
2268
+ if (payload.ipv4 || payload.ipv6) {
2269
+ let currentIpv4 = "";
2270
+ let currentIpv6 = "";
2271
+ try {
2272
+ const res = await fetch("https://api4.ipify.org?format=json", { signal: AbortSignal.timeout(3e3) });
2273
+ const data = await res.json();
2274
+ currentIpv4 = data.ip;
2275
+ } catch (e) {
2276
+ }
2277
+ try {
2278
+ const res = await fetch("https://api6.ipify.org?format=json", { signal: AbortSignal.timeout(3e3) });
2279
+ const data = await res.json();
2280
+ currentIpv6 = data.ip;
2281
+ } catch (e) {
2282
+ }
2283
+ const localIps = [];
2284
+ try {
2285
+ const osModule = __require("os");
2286
+ const interfaces = osModule.networkInterfaces();
2287
+ for (const name of Object.keys(interfaces)) {
2288
+ for (const iface of interfaces[name] || []) {
2289
+ if (!iface.internal) {
2290
+ localIps.push(iface.address);
2291
+ }
2292
+ }
2293
+ }
2294
+ } catch (e) {
2295
+ }
2296
+ const isIpv4Match = payload.ipv4 && (currentIpv4 === payload.ipv4 || localIps.includes(payload.ipv4));
2297
+ const isIpv6Match = payload.ipv6 && (currentIpv6 === payload.ipv6 || localIps.includes(payload.ipv6));
2298
+ if (payload.ipv4 && payload.ipv6) {
2299
+ if (!isIpv4Match && !isIpv6Match) {
2300
+ throw new Error(
2301
+ `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.`
2302
+ );
2303
+ }
2304
+ } else if (payload.ipv4 && !isIpv4Match) {
2305
+ throw new Error(
2306
+ `License key access restricted. This license key was created for a different system (authorized IPv4: ${payload.ipv4}) and cannot be used on this machine.`
2307
+ );
2308
+ } else if (payload.ipv6 && !isIpv6Match) {
2309
+ throw new Error(
2310
+ `License key access restricted. This license key was created for a different system (authorized IPv6: ${payload.ipv6}) and cannot be used on this machine.`
2311
+ );
2312
+ }
2313
+ }
2314
+ } catch (err) {
2315
+ if (err.message.includes("License key access restricted")) {
2316
+ throw new ConfigurationException(`[Retrivora SDK] ${err.message}`);
2317
+ }
2318
+ }
2319
+ }
2320
+ };
2321
+ // A simple in-memory cache to save CPU overhead of cryptographic signature checks.
2322
+ LicenseVerifier.cache = /* @__PURE__ */ new Map();
2323
+ LicenseVerifier.CACHE_TTL_MS = 60 * 1e3;
2324
+ // Cache verified license for 60 seconds
2325
+ // Retrivora's Public Key used to verify the license key signature.
2326
+ // In production, this matches the private key held by Retrivora SaaS.
2327
+ LicenseVerifier.PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----
2328
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArMieCkCBtTfByRNOserm
2329
+ XM4T0Am29JyNzB4XQPe+WJJ56CN73H1HLXx9n1ByFcxkEJ9po+SURj5DnvUXwEy+
2330
+ xstx33wDPpVmcMQe33j5CRYS0S4gICiNqIRN7XkTlJtrcXqrmh1/hdOAwfRbjO1T
2331
+ NVtORHwUwWfI/lBLyxUPGtKPed+0fQ7NtcW4o00JXxs3EjCB5BV9CbnXoTjQb/4h
2332
+ iwZof4l8rb7oaNzOsVg0RSyxsETX7Ex5sI0CjBz1p2mYp4oVhw/A/h8Ls7H0XzjC
2333
+ +Eb6BLtsytt5JHoSp0jExLlCpDmpys2L+kETcBVx+IqiXtdN1n6KbkksvEDUVzLI
2334
+ MwIDAQAB
2335
+ -----END PUBLIC KEY-----`;
2336
+
2058
2337
  // src/config/constants.ts
2059
2338
  var VECTOR_DB_PROVIDERS = [
2060
2339
  "pinecone",
@@ -2127,14 +2406,12 @@ function getRagConfig(baseConfig, env = process.env) {
2127
2406
  return getEnvConfig(env, baseConfig);
2128
2407
  }
2129
2408
  function getEnvConfig(env = process.env, base) {
2130
- 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;
2409
+ 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;
2131
2410
  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__";
2132
2411
  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;
2133
2412
  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);
2134
2413
  const vectorProvider = readEnum(env, "VECTOR_DB_PROVIDER", "pinecone", VECTOR_DB_PROVIDERS);
2135
- const llmProvider = readEnum(env, "LLM_PROVIDER", "openai", LLM_PROVIDERS);
2136
- const embeddingProvider = readEnum(env, "EMBEDDING_PROVIDER", "openai", EMBEDDING_PROVIDERS);
2137
- const embeddingDimensions = readNumber(env, "EMBEDDING_DIMENSIONS", 1536);
2414
+ const embeddingDimensions = readNumber(env, "EMBEDDING_DIMENSIONS", 768);
2138
2415
  const vectorDbOptions = {};
2139
2416
  if (vectorProvider === "pinecone") {
2140
2417
  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 : "";
@@ -2199,65 +2476,88 @@ function getEnvConfig(env = process.env, base) {
2199
2476
  rest: "default",
2200
2477
  custom: "default"
2201
2478
  };
2479
+ const isFreeTier = (() => {
2480
+ if (!licenseKey) return true;
2481
+ try {
2482
+ const payload = LicenseVerifier.verify(licenseKey, projectId);
2483
+ const tier = (payload.tier || "").toLowerCase();
2484
+ return tier === "free_trial" || tier === "free_tier" || tier === "free" || tier === "hobby";
2485
+ } catch (e) {
2486
+ return true;
2487
+ }
2488
+ })();
2489
+ const DEFAULT_FREE_GATEWAY = "https://llm.retrivora.com/api/v1";
2490
+ const defaultLlmProvider = isFreeTier ? "universal_rest" : "universal_rest";
2491
+ 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;
2492
+ 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;
2493
+ 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";
2494
+ 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";
2495
+ 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";
2496
+ const defaultEmbeddingProvider = isFreeTier ? "universal_rest" : "universal_rest";
2497
+ 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;
2498
+ 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;
2499
+ 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";
2500
+ 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";
2501
+ 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";
2202
2502
  return __spreadProps(__spreadValues({
2203
2503
  projectId,
2204
- licenseKey: (_ma = (_la = readString(env, "RETRIVORA_LICENSE_KEY")) != null ? _la : readString(env, "LICENSE_KEY")) != null ? _ma : base == null ? void 0 : base.licenseKey,
2504
+ licenseKey,
2205
2505
  vectorDb: {
2206
2506
  provider: vectorProvider,
2207
- indexName: (_oa = (_na = readString(env, "VECTOR_DB_INDEX")) != null ? _na : vectorDbOptions.indexName) != null ? _oa : "rag-index",
2507
+ indexName: (_Wa = (_Va = readString(env, "VECTOR_DB_INDEX")) != null ? _Va : vectorDbOptions.indexName) != null ? _Wa : "rag-index",
2208
2508
  options: vectorDbOptions
2209
2509
  },
2210
2510
  llm: {
2211
2511
  provider: llmProvider,
2212
- model: (_qa = (_pa = readString(env, "LLM_MODEL")) != null ? _pa : DEFAULT_MODEL_BY_PROVIDER[llmProvider]) != null ? _qa : "gpt-4o",
2213
- apiKey: (_ra = llmApiKeyByProvider[llmProvider]) != null ? _ra : "",
2214
- baseUrl: readString(env, "LLM_BASE_URL"),
2512
+ model: llmModel,
2513
+ apiKey: llmApiKey,
2514
+ baseUrl: llmBaseUrl,
2215
2515
  systemPrompt: readString(env, "LLM_SYSTEM_PROMPT"),
2216
2516
  maxTokens: readNumber(env, "LLM_MAX_TOKENS", 4096),
2217
2517
  temperature: readNumber(env, "LLM_TEMPERATURE", 0.7),
2218
2518
  options: {
2219
- profile: readString(env, "LLM_UNIVERSAL_PROFILE"),
2519
+ profile: llmProfile,
2220
2520
  thinking: readString(env, "LLM_THINKING") === "true" || readString(env, "LLM_THINKING") === "enabled" ? true : readString(env, "LLM_THINKING") === "false" ? false : void 0,
2221
2521
  thinkingBudget: env.LLM_THINKING_BUDGET ? parseInt(env.LLM_THINKING_BUDGET, 10) : void 0
2222
2522
  }
2223
2523
  },
2224
2524
  embedding: {
2225
2525
  provider: embeddingProvider,
2226
- model: (_sa = readString(env, "EMBEDDING_MODEL")) != null ? _sa : "text-embedding-3-small",
2227
- apiKey: embeddingApiKeyByProvider[embeddingProvider],
2228
- baseUrl: readString(env, "EMBEDDING_BASE_URL"),
2526
+ model: embeddingModel,
2527
+ apiKey: embeddingApiKey,
2528
+ baseUrl: embeddingBaseUrl,
2229
2529
  dimensions: embeddingDimensions,
2230
2530
  queryPrefix: readString(env, "EMBEDDING_QUERY_PREFIX"),
2231
2531
  documentPrefix: readString(env, "EMBEDDING_DOCUMENT_PREFIX"),
2232
2532
  options: {
2233
- profile: readString(env, "EMBEDDING_UNIVERSAL_PROFILE")
2533
+ profile: embeddingProfile
2234
2534
  }
2235
2535
  },
2236
2536
  ui: {
2237
- title: (_ua = (_ta = readString(env, "NEXT_PUBLIC_UI_TITLE")) != null ? _ta : readString(env, "UI_TITLE")) != null ? _ua : "AI Assistant",
2238
- subtitle: (_wa = (_va = readString(env, "NEXT_PUBLIC_UI_SUBTITLE")) != null ? _va : readString(env, "UI_SUBTITLE")) != null ? _wa : "Powered by RAG",
2239
- primaryColor: (_ya = (_xa = readString(env, "NEXT_PUBLIC_PRIMARY_COLOR")) != null ? _xa : readString(env, "UI_PRIMARY_COLOR")) != null ? _ya : "#10b981",
2240
- accentColor: (_Aa = (_za = readString(env, "NEXT_PUBLIC_ACCENT_COLOR")) != null ? _za : readString(env, "UI_ACCENT_COLOR")) != null ? _Aa : "#3b82f6",
2241
- logoUrl: (_Ba = readString(env, "NEXT_PUBLIC_LOGO_URL")) != null ? _Ba : readString(env, "UI_LOGO_URL"),
2242
- placeholder: (_Da = (_Ca = readString(env, "NEXT_PUBLIC_PLACEHOLDER")) != null ? _Ca : readString(env, "UI_PLACEHOLDER")) != null ? _Da : "Ask me anything\u2026",
2243
- showSources: ((_Fa = (_Ea = readString(env, "NEXT_PUBLIC_SHOW_SOURCES")) != null ? _Ea : readString(env, "UI_SHOW_SOURCES")) != null ? _Fa : "true") !== "false",
2244
- 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.",
2245
- visualStyle: (_Ja = (_Ia = readString(env, "NEXT_PUBLIC_UI_VISUAL_STYLE")) != null ? _Ia : readString(env, "UI_VISUAL_STYLE")) != null ? _Ja : "glass",
2246
- borderRadius: (_La = (_Ka = readString(env, "NEXT_PUBLIC_UI_BORDER_RADIUS")) != null ? _Ka : readString(env, "UI_BORDER_RADIUS")) != null ? _La : "xl",
2247
- allowUpload: ((_Na = (_Ma = readString(env, "NEXT_PUBLIC_ALLOW_UPLOAD")) != null ? _Ma : readString(env, "UI_ALLOW_UPLOAD")) != null ? _Na : "false") === "true"
2537
+ title: (_Ya = (_Xa = readString(env, "NEXT_PUBLIC_UI_TITLE")) != null ? _Xa : readString(env, "UI_TITLE")) != null ? _Ya : "AI Assistant",
2538
+ subtitle: (__a = (_Za = readString(env, "NEXT_PUBLIC_UI_SUBTITLE")) != null ? _Za : readString(env, "UI_SUBTITLE")) != null ? __a : "Powered by RAG",
2539
+ primaryColor: (_ab = (_$a = readString(env, "NEXT_PUBLIC_PRIMARY_COLOR")) != null ? _$a : readString(env, "UI_PRIMARY_COLOR")) != null ? _ab : "#10b981",
2540
+ accentColor: (_cb = (_bb = readString(env, "NEXT_PUBLIC_ACCENT_COLOR")) != null ? _bb : readString(env, "UI_ACCENT_COLOR")) != null ? _cb : "#3b82f6",
2541
+ logoUrl: (_db = readString(env, "NEXT_PUBLIC_LOGO_URL")) != null ? _db : readString(env, "UI_LOGO_URL"),
2542
+ placeholder: (_fb = (_eb = readString(env, "NEXT_PUBLIC_PLACEHOLDER")) != null ? _eb : readString(env, "UI_PLACEHOLDER")) != null ? _fb : "Ask me anything\u2026",
2543
+ showSources: ((_hb = (_gb = readString(env, "NEXT_PUBLIC_SHOW_SOURCES")) != null ? _gb : readString(env, "UI_SHOW_SOURCES")) != null ? _hb : "true") !== "false",
2544
+ 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.",
2545
+ visualStyle: (_lb = (_kb = readString(env, "NEXT_PUBLIC_UI_VISUAL_STYLE")) != null ? _kb : readString(env, "UI_VISUAL_STYLE")) != null ? _lb : "glass",
2546
+ borderRadius: (_nb = (_mb = readString(env, "NEXT_PUBLIC_UI_BORDER_RADIUS")) != null ? _mb : readString(env, "UI_BORDER_RADIUS")) != null ? _nb : "xl",
2547
+ allowUpload: ((_pb = (_ob = readString(env, "NEXT_PUBLIC_ALLOW_UPLOAD")) != null ? _ob : readString(env, "UI_ALLOW_UPLOAD")) != null ? _pb : "false") === "true"
2248
2548
  },
2249
2549
  rag: {
2250
2550
  topK: readNumber(env, "RAG_TOP_K", 5),
2251
2551
  scoreThreshold: readNumber(env, "RAG_SCORE_THRESHOLD", 0),
2252
2552
  chunkSize: readNumber(env, "RAG_CHUNK_SIZE", 1e3),
2253
2553
  chunkOverlap: readNumber(env, "RAG_CHUNK_OVERLAP", 200),
2254
- filterableFields: (_Oa = readString(env, "RAG_FILTERABLE_FIELDS")) == null ? void 0 : _Oa.split(",").map((f) => f.trim()),
2554
+ filterableFields: (_qb = readString(env, "RAG_FILTERABLE_FIELDS")) == null ? void 0 : _qb.split(",").map((f) => f.trim()),
2255
2555
  // Query pipeline toggles — read from .env.local
2256
2556
  useQueryTransformation: readString(env, "RAG_USE_QUERY_TRANSFORMATION") === "true",
2257
2557
  useReranking: readString(env, "RAG_USE_RERANKING") === "true",
2258
2558
  useGraphRetrieval: readString(env, "RAG_USE_GRAPH_RETRIEVAL") === "true",
2259
- architecture: (_Pa = readString(env, "RAG_ARCHITECTURE")) != null ? _Pa : "simple",
2260
- chunkingStrategy: (_Qa = readString(env, "RAG_CHUNKING_STRATEGY")) != null ? _Qa : "recursive",
2559
+ architecture: (_rb = readString(env, "RAG_ARCHITECTURE")) != null ? _rb : "simple",
2560
+ chunkingStrategy: (_sb = readString(env, "RAG_CHUNKING_STRATEGY")) != null ? _sb : "recursive",
2261
2561
  uiMapping: (() => {
2262
2562
  const raw = readString(env, "RAG_UI_MAPPING");
2263
2563
  if (!raw) return void 0;
@@ -2270,7 +2570,7 @@ function getEnvConfig(env = process.env, base) {
2270
2570
  },
2271
2571
  telemetry: {
2272
2572
  enabled: telemetryEnabled,
2273
- 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"
2573
+ 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"
2274
2574
  }
2275
2575
  }, readString(env, "GRAPH_DB_PROVIDER") ? {
2276
2576
  graphDb: {
@@ -2757,10 +3057,12 @@ var AnthropicProvider = class {
2757
3057
  import axios from "axios";
2758
3058
  var OllamaProvider = class {
2759
3059
  constructor(llmConfig, embeddingConfig) {
2760
- var _a2, _b;
2761
- const baseURL = (_a2 = llmConfig.baseUrl) != null ? _a2 : "http://localhost:11434";
3060
+ var _a2, _b, _c;
3061
+ const rawBaseURL = ((_a2 = llmConfig.baseUrl) != null ? _a2 : "http://localhost:11434").replace(/\/+$/, "");
3062
+ const baseURL = rawBaseURL.replace(/\/(?:api\/v1|v1|api)$/i, "");
2762
3063
  const timeout = Number((_b = llmConfig.options) == null ? void 0 : _b.timeout) || 3e5;
2763
- this.http = axios.create({ baseURL, timeout });
3064
+ const headers = ((_c = llmConfig.options) == null ? void 0 : _c.headers) || {};
3065
+ this.http = axios.create({ baseURL, timeout, headers });
2764
3066
  this.llmConfig = llmConfig;
2765
3067
  this.embeddingConfig = embeddingConfig;
2766
3068
  }
@@ -3736,112 +4038,40 @@ ${context != null ? context : "None"}` },
3736
4038
  payload = buildPayload(this.opts.embedPayloadTemplate, {
3737
4039
  model: this.model,
3738
4040
  input: text
3739
- });
3740
- } else {
3741
- payload = {
3742
- model: this.model,
3743
- input: text
3744
- };
3745
- }
3746
- const { data } = await this.http.post(path2, payload);
3747
- const extractPath = (_b = this.opts.embedExtractPath) != null ? _b : "data[0].embedding";
3748
- const vector = resolvePath(data, extractPath);
3749
- if (!Array.isArray(vector)) {
3750
- throw new Error(`[UniversalLLMAdapter] Expected a number array at '${extractPath}' for embeddings.`);
3751
- }
3752
- return vector;
3753
- }
3754
- async batchEmbed(texts) {
3755
- const vectors = [];
3756
- for (const text of texts) {
3757
- vectors.push(await this.embed(text));
3758
- }
3759
- return vectors;
3760
- }
3761
- async ping() {
3762
- try {
3763
- if (this.opts.pingPath) {
3764
- await this.http.get(this.opts.pingPath);
3765
- }
3766
- return true;
3767
- } catch (err) {
3768
- console.error("[UniversalLLMAdapter] Ping failed:", err);
3769
- return false;
3770
- }
3771
- }
3772
- };
3773
-
3774
- // src/exceptions/index.ts
3775
- var RetrivoraError = class extends Error {
3776
- constructor(message, code, details) {
3777
- super(message);
3778
- this.name = new.target.name;
3779
- this.code = code;
3780
- this.details = details;
3781
- }
3782
- };
3783
- var ProviderNotFoundException = class extends RetrivoraError {
3784
- constructor(providerType, provider, details) {
3785
- super(`Unsupported ${providerType} provider: ${provider}`, "PROVIDER_NOT_FOUND", details);
3786
- }
3787
- };
3788
- var EmbeddingFailedException = class extends RetrivoraError {
3789
- constructor(message = "Embedding generation failed", details) {
3790
- super(message, "EMBEDDING_FAILED", details);
3791
- }
3792
- };
3793
- var RetrievalException = class extends RetrivoraError {
3794
- constructor(message = "Retrieval failed", details) {
3795
- super(message, "RETRIEVAL_FAILED", details);
3796
- }
3797
- };
3798
- var RateLimitException = class extends RetrivoraError {
3799
- constructor(message = "Provider rate limit exceeded", details) {
3800
- super(message, "RATE_LIMITED", details);
3801
- }
3802
- };
3803
- var ConfigurationException = class extends RetrivoraError {
3804
- constructor(message, details) {
3805
- super(message, "CONFIGURATION_ERROR", details);
3806
- }
3807
- };
3808
- var AuthenticationException = class extends RetrivoraError {
3809
- constructor(message = "Provider authentication failed", details) {
3810
- super(message, "AUTHENTICATION_ERROR", details);
3811
- }
3812
- };
3813
- function wrapError(err, defaultCode, defaultMessage) {
3814
- var _a2;
3815
- if (err instanceof RetrivoraError) {
3816
- return err;
3817
- }
3818
- const error = err;
3819
- const message = (error == null ? void 0 : error.message) || defaultMessage || String(err);
3820
- 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);
3821
- const code = error == null ? void 0 : error.code;
3822
- if (status === 429 || /rate[- ]?limit/i.test(message) || code === "RATE_LIMIT_EXCEEDED") {
3823
- return new RateLimitException(message, err);
4041
+ });
4042
+ } else {
4043
+ payload = {
4044
+ model: this.model,
4045
+ input: text
4046
+ };
4047
+ }
4048
+ const { data } = await this.http.post(path2, payload);
4049
+ const extractPath = (_b = this.opts.embedExtractPath) != null ? _b : "data[0].embedding";
4050
+ const vector = resolvePath(data, extractPath);
4051
+ if (!Array.isArray(vector)) {
4052
+ throw new Error(`[UniversalLLMAdapter] Expected a number array at '${extractPath}' for embeddings.`);
4053
+ }
4054
+ return vector;
3824
4055
  }
3825
- if (status === 401 || status === 403 || /unauthorized|auth|api[- ]?key/i.test(message) || code === "INVALID_API_KEY") {
3826
- return new AuthenticationException(message, err);
4056
+ async batchEmbed(texts) {
4057
+ const vectors = [];
4058
+ for (const text of texts) {
4059
+ vectors.push(await this.embed(text));
4060
+ }
4061
+ return vectors;
3827
4062
  }
3828
- switch (defaultCode) {
3829
- case "PROVIDER_NOT_FOUND":
3830
- return new ProviderNotFoundException("provider", message, err);
3831
- case "EMBEDDING_FAILED":
3832
- return new EmbeddingFailedException(message, err);
3833
- case "RETRIEVAL_FAILED":
3834
- return new RetrievalException(message, err);
3835
- case "RATE_LIMITED":
3836
- return new RateLimitException(message, err);
3837
- case "CONFIGURATION_ERROR":
3838
- return new ConfigurationException(message, err);
3839
- case "AUTHENTICATION_ERROR":
3840
- return new AuthenticationException(message, err);
3841
- default:
3842
- return new RetrivoraError(message, defaultCode, err);
4063
+ async ping() {
4064
+ try {
4065
+ if (this.opts.pingPath) {
4066
+ await this.http.get(this.opts.pingPath);
4067
+ }
4068
+ return true;
4069
+ } catch (err) {
4070
+ console.error("[UniversalLLMAdapter] Ping failed:", err);
4071
+ return false;
4072
+ }
3843
4073
  }
3844
- }
4074
+ };
3845
4075
 
3846
4076
  // src/llm/LLMFactory.ts
3847
4077
  var customProviders = /* @__PURE__ */ new Map();
@@ -4240,211 +4470,6 @@ var ConfigValidator = class {
4240
4470
  }
4241
4471
  };
4242
4472
 
4243
- // src/core/LicenseVerifier.ts
4244
- import * as crypto2 from "crypto";
4245
- var LicenseVerifier = class {
4246
- /**
4247
- * Decodes, verifies signature, and checks metadata of a license key.
4248
- *
4249
- * @param licenseKey - Base64url signed JWT license key.
4250
- * @param currentProjectId - Project namespace ID.
4251
- * @param publicKeyOverride - Optional override for unit/integration tests.
4252
- */
4253
- static verify(licenseKey, currentProjectId, provider, publicKeyOverride) {
4254
- const isProduction = process.env.NODE_ENV === "production";
4255
- const now = Date.now();
4256
- if (licenseKey) {
4257
- const cacheKey = `${licenseKey}:${currentProjectId}:${provider || ""}:${publicKeyOverride || ""}`;
4258
- const cached = this.cache.get(cacheKey);
4259
- if (cached && now - cached.cachedAt < this.CACHE_TTL_MS) {
4260
- const currentTimestampSec = Math.floor(now / 1e3);
4261
- if (cached.payload.expiresAt && currentTimestampSec > cached.payload.expiresAt) {
4262
- this.cache.delete(cacheKey);
4263
- } else {
4264
- return cached.payload;
4265
- }
4266
- }
4267
- }
4268
- if (!licenseKey) {
4269
- if (isProduction) {
4270
- throw new ConfigurationException(
4271
- "[Retrivora SDK] License key (licenseKey) is required in production environments."
4272
- );
4273
- }
4274
- console.warn(
4275
- `\x1B[33m[Retrivora SDK] WARNING: Running without a license key. This namespace (${currentProjectId}) is permitted for local development only.\x1B[0m`
4276
- );
4277
- return {
4278
- projectId: currentProjectId,
4279
- expiresAt: Math.floor(Date.now() / 1e3) + 86400,
4280
- // Valid for 24h
4281
- tier: "hobby"
4282
- };
4283
- }
4284
- try {
4285
- const parts = licenseKey.split(".");
4286
- if (parts.length !== 3) {
4287
- throw new Error("Malformed token structure (expected 3 parts).");
4288
- }
4289
- const [headerB64, payloadB64, signatureB64] = parts;
4290
- const dataToVerify = `${headerB64}.${payloadB64}`;
4291
- const publicKey = publicKeyOverride != null ? publicKeyOverride : this.PUBLIC_KEY;
4292
- const signature = Buffer.from(signatureB64, "base64url");
4293
- const data = Buffer.from(dataToVerify);
4294
- const isValid = crypto2.verify(
4295
- "sha256",
4296
- data,
4297
- publicKey,
4298
- signature
4299
- );
4300
- if (!isValid) {
4301
- throw new Error("Signature verification failed.");
4302
- }
4303
- const payload = JSON.parse(
4304
- Buffer.from(payloadB64, "base64url").toString("utf8")
4305
- );
4306
- if (!payload.projectId) {
4307
- throw new Error('License payload is missing "projectId".');
4308
- }
4309
- if (payload.projectId !== currentProjectId) {
4310
- throw new Error(
4311
- `Project ID mismatch. License is bound to project namespace "${payload.projectId}" but configuration has "${currentProjectId}".`
4312
- );
4313
- }
4314
- if (!payload.expiresAt) {
4315
- throw new Error('License payload is missing expiration ("expiresAt").');
4316
- }
4317
- const currentTimestampSec = Math.floor(Date.now() / 1e3);
4318
- if (currentTimestampSec > payload.expiresAt) {
4319
- throw new Error(
4320
- `License key has expired. Expiration: ${new Date(
4321
- payload.expiresAt * 1e3
4322
- ).toDateString()}`
4323
- );
4324
- }
4325
- if (isProduction && provider) {
4326
- const tier = (payload.tier || "").toLowerCase();
4327
- const normalizedProvider = provider.toLowerCase();
4328
- if (tier === "hobby") {
4329
- const allowedHobby = ["postgresql", "pgvector", "supabase"];
4330
- if (!allowedHobby.includes(normalizedProvider)) {
4331
- throw new Error(
4332
- `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.`
4333
- );
4334
- }
4335
- } else if (tier === "pro" || tier === "developer_pro" || tier === "premium" || tier === "growth" || tier === "free_trial" || tier === "free_tier" || tier === "free") {
4336
- const allowedPro = [
4337
- "postgresql",
4338
- "pgvector",
4339
- "supabase",
4340
- "pinecone",
4341
- "qdrant",
4342
- "mongodb",
4343
- "milvus",
4344
- "chroma",
4345
- "chromadb"
4346
- ];
4347
- if (!allowedPro.includes(normalizedProvider)) {
4348
- throw new Error(
4349
- `The database provider "${provider}" is not allowed on the Developer Pro tier. Please upgrade to an Enterprise plan.`
4350
- );
4351
- }
4352
- }
4353
- }
4354
- if (licenseKey) {
4355
- const cacheKey = `${licenseKey}:${currentProjectId}:${provider || ""}:${publicKeyOverride || ""}`;
4356
- this.cache.set(cacheKey, { payload, cachedAt: now });
4357
- }
4358
- return payload;
4359
- } catch (err) {
4360
- const message = err instanceof Error ? err.message : String(err);
4361
- throw new ConfigurationException(
4362
- `[Retrivora SDK] License key validation failed: ${message}`
4363
- );
4364
- }
4365
- }
4366
- static async verifyIP(licenseKey) {
4367
- if (!licenseKey) return;
4368
- try {
4369
- const parts = licenseKey.split(".");
4370
- if (parts.length !== 3) return;
4371
- const [, payloadB64] = parts;
4372
- const payload = JSON.parse(
4373
- Buffer.from(payloadB64, "base64url").toString("utf8")
4374
- );
4375
- const tier = (payload.tier || "").toLowerCase();
4376
- if (tier === "enterprise" || tier === "custom") {
4377
- return;
4378
- }
4379
- if (payload.ipv4 || payload.ipv6) {
4380
- let currentIpv4 = "";
4381
- let currentIpv6 = "";
4382
- try {
4383
- const res = await fetch("https://api4.ipify.org?format=json", { signal: AbortSignal.timeout(3e3) });
4384
- const data = await res.json();
4385
- currentIpv4 = data.ip;
4386
- } catch (e) {
4387
- }
4388
- try {
4389
- const res = await fetch("https://api6.ipify.org?format=json", { signal: AbortSignal.timeout(3e3) });
4390
- const data = await res.json();
4391
- currentIpv6 = data.ip;
4392
- } catch (e) {
4393
- }
4394
- const localIps = [];
4395
- try {
4396
- const osModule = __require("os");
4397
- const interfaces = osModule.networkInterfaces();
4398
- for (const name of Object.keys(interfaces)) {
4399
- for (const iface of interfaces[name] || []) {
4400
- if (!iface.internal) {
4401
- localIps.push(iface.address);
4402
- }
4403
- }
4404
- }
4405
- } catch (e) {
4406
- }
4407
- const isIpv4Match = payload.ipv4 && (currentIpv4 === payload.ipv4 || localIps.includes(payload.ipv4));
4408
- const isIpv6Match = payload.ipv6 && (currentIpv6 === payload.ipv6 || localIps.includes(payload.ipv6));
4409
- if (payload.ipv4 && payload.ipv6) {
4410
- if (!isIpv4Match && !isIpv6Match) {
4411
- throw new Error(
4412
- `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.`
4413
- );
4414
- }
4415
- } else if (payload.ipv4 && !isIpv4Match) {
4416
- throw new Error(
4417
- `License key access restricted. This license key was created for a different system (authorized IPv4: ${payload.ipv4}) and cannot be used on this machine.`
4418
- );
4419
- } else if (payload.ipv6 && !isIpv6Match) {
4420
- throw new Error(
4421
- `License key access restricted. This license key was created for a different system (authorized IPv6: ${payload.ipv6}) and cannot be used on this machine.`
4422
- );
4423
- }
4424
- }
4425
- } catch (err) {
4426
- if (err.message.includes("License key access restricted")) {
4427
- throw new ConfigurationException(`[Retrivora SDK] ${err.message}`);
4428
- }
4429
- }
4430
- }
4431
- };
4432
- // A simple in-memory cache to save CPU overhead of cryptographic signature checks.
4433
- LicenseVerifier.cache = /* @__PURE__ */ new Map();
4434
- LicenseVerifier.CACHE_TTL_MS = 60 * 1e3;
4435
- // Cache verified license for 60 seconds
4436
- // Retrivora's Public Key used to verify the license key signature.
4437
- // In production, this matches the private key held by Retrivora SaaS.
4438
- LicenseVerifier.PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----
4439
- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArMieCkCBtTfByRNOserm
4440
- XM4T0Am29JyNzB4XQPe+WJJ56CN73H1HLXx9n1ByFcxkEJ9po+SURj5DnvUXwEy+
4441
- xstx33wDPpVmcMQe33j5CRYS0S4gICiNqIRN7XkTlJtrcXqrmh1/hdOAwfRbjO1T
4442
- NVtORHwUwWfI/lBLyxUPGtKPed+0fQ7NtcW4o00JXxs3EjCB5BV9CbnXoTjQb/4h
4443
- iwZof4l8rb7oaNzOsVg0RSyxsETX7Ex5sI0CjBz1p2mYp4oVhw/A/h8Ls7H0XzjC
4444
- +Eb6BLtsytt5JHoSp0jExLlCpDmpys2L+kETcBVx+IqiXtdN1n6KbkksvEDUVzLI
4445
- MwIDAQAB
4446
- -----END PUBLIC KEY-----`;
4447
-
4448
4473
  // src/rag/DocumentChunker.ts
4449
4474
  var DocumentChunker = class {
4450
4475
  constructor(chunkSize = 1e3, chunkOverlap = 200, separators = ["\n# ", "\n## ", "\n### ", "\n#### ", "\n\n", "\n", " ", ""]) {
@@ -10083,7 +10108,17 @@ function createChatHandler(configOrPlugin, options) {
10083
10108
  if (rateLimited) return rateLimited;
10084
10109
  try {
10085
10110
  const body = await req.json();
10086
- const { message: rawMessage, history = [], namespace, sessionId = "default", messageId, userMessageId } = body;
10111
+ const bodyObj = body != null ? body : {};
10112
+ let rawMessage = bodyObj.message;
10113
+ if (!rawMessage && Array.isArray(bodyObj.messages) && bodyObj.messages.length > 0) {
10114
+ const lastMsg = bodyObj.messages[bodyObj.messages.length - 1];
10115
+ rawMessage = typeof lastMsg === "string" ? lastMsg : (lastMsg == null ? void 0 : lastMsg.content) || (lastMsg == null ? void 0 : lastMsg.text);
10116
+ }
10117
+ if (!rawMessage && typeof bodyObj.prompt === "string") {
10118
+ rawMessage = bodyObj.prompt;
10119
+ }
10120
+ const history = bodyObj.history || (Array.isArray(bodyObj.messages) ? bodyObj.messages.slice(0, -1) : []);
10121
+ const { namespace, sessionId = "default", messageId, userMessageId } = bodyObj;
10087
10122
  const sanitized = sanitizeInput(rawMessage != null ? rawMessage : "");
10088
10123
  if (!sanitized.ok) {
10089
10124
  return NextResponse.json({ error: { code: "INVALID_INPUT", message: sanitized.error } }, { status: 400 });
@@ -10135,7 +10170,17 @@ function createStreamHandler(configOrPlugin, options) {
10135
10170
  headers: { "Content-Type": "application/json" }
10136
10171
  });
10137
10172
  }
10138
- const { message: rawMessage, history = [], namespace, sessionId = "default", messageId, userMessageId } = body;
10173
+ const bodyObj = body != null ? body : {};
10174
+ let rawMessage = bodyObj.message;
10175
+ if (!rawMessage && Array.isArray(bodyObj.messages) && bodyObj.messages.length > 0) {
10176
+ const lastMsg = bodyObj.messages[bodyObj.messages.length - 1];
10177
+ rawMessage = typeof lastMsg === "string" ? lastMsg : (lastMsg == null ? void 0 : lastMsg.content) || (lastMsg == null ? void 0 : lastMsg.text);
10178
+ }
10179
+ if (!rawMessage && typeof bodyObj.prompt === "string") {
10180
+ rawMessage = bodyObj.prompt;
10181
+ }
10182
+ const history = bodyObj.history || (Array.isArray(bodyObj.messages) ? bodyObj.messages.slice(0, -1) : []);
10183
+ const { namespace, sessionId = "default", messageId, userMessageId } = bodyObj;
10139
10184
  const sanitized = sanitizeInput(rawMessage != null ? rawMessage : "");
10140
10185
  if (!sanitized.ok) {
10141
10186
  return new Response(