@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.
@@ -2093,6 +2093,285 @@ var import_server = require("next/server");
2093
2093
  // src/core/ConfigResolver.ts
2094
2094
  init_templateUtils();
2095
2095
 
2096
+ // src/core/LicenseVerifier.ts
2097
+ var crypto = __toESM(require("crypto"));
2098
+
2099
+ // src/exceptions/index.ts
2100
+ var RetrivoraError = class extends Error {
2101
+ constructor(message, code, details) {
2102
+ super(message);
2103
+ this.name = new.target.name;
2104
+ this.code = code;
2105
+ this.details = details;
2106
+ }
2107
+ };
2108
+ var ProviderNotFoundException = class extends RetrivoraError {
2109
+ constructor(providerType, provider, details) {
2110
+ super(`Unsupported ${providerType} provider: ${provider}`, "PROVIDER_NOT_FOUND", details);
2111
+ }
2112
+ };
2113
+ var EmbeddingFailedException = class extends RetrivoraError {
2114
+ constructor(message = "Embedding generation failed", details) {
2115
+ super(message, "EMBEDDING_FAILED", details);
2116
+ }
2117
+ };
2118
+ var RetrievalException = class extends RetrivoraError {
2119
+ constructor(message = "Retrieval failed", details) {
2120
+ super(message, "RETRIEVAL_FAILED", details);
2121
+ }
2122
+ };
2123
+ var RateLimitException = class extends RetrivoraError {
2124
+ constructor(message = "Provider rate limit exceeded", details) {
2125
+ super(message, "RATE_LIMITED", details);
2126
+ }
2127
+ };
2128
+ var ConfigurationException = class extends RetrivoraError {
2129
+ constructor(message, details) {
2130
+ super(message, "CONFIGURATION_ERROR", details);
2131
+ }
2132
+ };
2133
+ var AuthenticationException = class extends RetrivoraError {
2134
+ constructor(message = "Provider authentication failed", details) {
2135
+ super(message, "AUTHENTICATION_ERROR", details);
2136
+ }
2137
+ };
2138
+ function wrapError(err, defaultCode, defaultMessage) {
2139
+ var _a2;
2140
+ if (err instanceof RetrivoraError) {
2141
+ return err;
2142
+ }
2143
+ const error = err;
2144
+ const message = (error == null ? void 0 : error.message) || defaultMessage || String(err);
2145
+ const status = (error == null ? void 0 : error.status) || (error == null ? void 0 : error.statusCode) || ((_a2 = error == null ? void 0 : error.response) == null ? void 0 : _a2.status);
2146
+ const code = error == null ? void 0 : error.code;
2147
+ if (status === 429 || /rate[- ]?limit/i.test(message) || code === "RATE_LIMIT_EXCEEDED") {
2148
+ return new RateLimitException(message, err);
2149
+ }
2150
+ if (status === 401 || status === 403 || /unauthorized|auth|api[- ]?key/i.test(message) || code === "INVALID_API_KEY") {
2151
+ return new AuthenticationException(message, err);
2152
+ }
2153
+ switch (defaultCode) {
2154
+ case "PROVIDER_NOT_FOUND":
2155
+ return new ProviderNotFoundException("provider", message, err);
2156
+ case "EMBEDDING_FAILED":
2157
+ return new EmbeddingFailedException(message, err);
2158
+ case "RETRIEVAL_FAILED":
2159
+ return new RetrievalException(message, err);
2160
+ case "RATE_LIMITED":
2161
+ return new RateLimitException(message, err);
2162
+ case "CONFIGURATION_ERROR":
2163
+ return new ConfigurationException(message, err);
2164
+ case "AUTHENTICATION_ERROR":
2165
+ return new AuthenticationException(message, err);
2166
+ default:
2167
+ return new RetrivoraError(message, defaultCode, err);
2168
+ }
2169
+ }
2170
+
2171
+ // src/core/LicenseVerifier.ts
2172
+ var LicenseVerifier = class {
2173
+ /**
2174
+ * Decodes, verifies signature, and checks metadata of a license key.
2175
+ *
2176
+ * @param licenseKey - Base64url signed JWT license key.
2177
+ * @param currentProjectId - Project namespace ID.
2178
+ * @param publicKeyOverride - Optional override for unit/integration tests.
2179
+ */
2180
+ static verify(licenseKey, currentProjectId, provider, publicKeyOverride) {
2181
+ const isProduction = process.env.NODE_ENV === "production";
2182
+ const now = Date.now();
2183
+ if (licenseKey) {
2184
+ const cacheKey = `${licenseKey}:${currentProjectId}:${provider || ""}:${publicKeyOverride || ""}`;
2185
+ const cached = this.cache.get(cacheKey);
2186
+ if (cached && now - cached.cachedAt < this.CACHE_TTL_MS) {
2187
+ const currentTimestampSec = Math.floor(now / 1e3);
2188
+ if (cached.payload.expiresAt && currentTimestampSec > cached.payload.expiresAt) {
2189
+ this.cache.delete(cacheKey);
2190
+ } else {
2191
+ return cached.payload;
2192
+ }
2193
+ }
2194
+ }
2195
+ if (!licenseKey) {
2196
+ if (isProduction) {
2197
+ throw new ConfigurationException(
2198
+ "[Retrivora SDK] License key (licenseKey) is required in production environments."
2199
+ );
2200
+ }
2201
+ console.warn(
2202
+ `\x1B[33m[Retrivora SDK] WARNING: Running without a license key. This namespace (${currentProjectId}) is permitted for local development only.\x1B[0m`
2203
+ );
2204
+ return {
2205
+ projectId: currentProjectId,
2206
+ expiresAt: Math.floor(Date.now() / 1e3) + 86400,
2207
+ // Valid for 24h
2208
+ tier: "hobby"
2209
+ };
2210
+ }
2211
+ try {
2212
+ const parts = licenseKey.split(".");
2213
+ if (parts.length !== 3) {
2214
+ throw new Error("Malformed token structure (expected 3 parts).");
2215
+ }
2216
+ const [headerB64, payloadB64, signatureB64] = parts;
2217
+ const dataToVerify = `${headerB64}.${payloadB64}`;
2218
+ const publicKey = publicKeyOverride != null ? publicKeyOverride : this.PUBLIC_KEY;
2219
+ const signature = Buffer.from(signatureB64, "base64url");
2220
+ const data = Buffer.from(dataToVerify);
2221
+ const isValid = crypto.verify(
2222
+ "sha256",
2223
+ data,
2224
+ publicKey,
2225
+ signature
2226
+ );
2227
+ if (!isValid) {
2228
+ throw new Error("Signature verification failed.");
2229
+ }
2230
+ const payload = JSON.parse(
2231
+ Buffer.from(payloadB64, "base64url").toString("utf8")
2232
+ );
2233
+ if (!payload.projectId) {
2234
+ throw new Error('License payload is missing "projectId".');
2235
+ }
2236
+ if (payload.projectId !== currentProjectId) {
2237
+ throw new Error(
2238
+ `Project ID mismatch. License is bound to project namespace "${payload.projectId}" but configuration has "${currentProjectId}".`
2239
+ );
2240
+ }
2241
+ if (!payload.expiresAt) {
2242
+ throw new Error('License payload is missing expiration ("expiresAt").');
2243
+ }
2244
+ const currentTimestampSec = Math.floor(Date.now() / 1e3);
2245
+ if (currentTimestampSec > payload.expiresAt) {
2246
+ throw new Error(
2247
+ `License key has expired. Expiration: ${new Date(
2248
+ payload.expiresAt * 1e3
2249
+ ).toDateString()}`
2250
+ );
2251
+ }
2252
+ if (isProduction && provider) {
2253
+ const tier = (payload.tier || "").toLowerCase();
2254
+ const normalizedProvider = provider.toLowerCase();
2255
+ if (tier === "hobby") {
2256
+ const allowedHobby = ["postgresql", "pgvector", "supabase"];
2257
+ if (!allowedHobby.includes(normalizedProvider)) {
2258
+ throw new Error(
2259
+ `The database provider "${provider}" is not allowed on the Hobby tier. Hobby tier is restricted to PostgreSQL and Supabase. Please upgrade to a Developer Pro or Enterprise plan.`
2260
+ );
2261
+ }
2262
+ } else if (tier === "pro" || tier === "developer_pro" || tier === "premium" || tier === "growth" || tier === "free_trial" || tier === "free_tier" || tier === "free") {
2263
+ const allowedPro = [
2264
+ "postgresql",
2265
+ "pgvector",
2266
+ "supabase",
2267
+ "pinecone",
2268
+ "qdrant",
2269
+ "mongodb",
2270
+ "milvus",
2271
+ "chroma",
2272
+ "chromadb"
2273
+ ];
2274
+ if (!allowedPro.includes(normalizedProvider)) {
2275
+ throw new Error(
2276
+ `The database provider "${provider}" is not allowed on the Developer Pro tier. Please upgrade to an Enterprise plan.`
2277
+ );
2278
+ }
2279
+ }
2280
+ }
2281
+ if (licenseKey) {
2282
+ const cacheKey = `${licenseKey}:${currentProjectId}:${provider || ""}:${publicKeyOverride || ""}`;
2283
+ this.cache.set(cacheKey, { payload, cachedAt: now });
2284
+ }
2285
+ return payload;
2286
+ } catch (err) {
2287
+ const message = err instanceof Error ? err.message : String(err);
2288
+ throw new ConfigurationException(
2289
+ `[Retrivora SDK] License key validation failed: ${message}`
2290
+ );
2291
+ }
2292
+ }
2293
+ static async verifyIP(licenseKey) {
2294
+ if (!licenseKey) return;
2295
+ try {
2296
+ const parts = licenseKey.split(".");
2297
+ if (parts.length !== 3) return;
2298
+ const [, payloadB64] = parts;
2299
+ const payload = JSON.parse(
2300
+ Buffer.from(payloadB64, "base64url").toString("utf8")
2301
+ );
2302
+ const tier = (payload.tier || "").toLowerCase();
2303
+ if (tier === "enterprise" || tier === "custom") {
2304
+ return;
2305
+ }
2306
+ if (payload.ipv4 || payload.ipv6) {
2307
+ let currentIpv4 = "";
2308
+ let currentIpv6 = "";
2309
+ try {
2310
+ const res = await fetch("https://api4.ipify.org?format=json", { signal: AbortSignal.timeout(3e3) });
2311
+ const data = await res.json();
2312
+ currentIpv4 = data.ip;
2313
+ } catch (e) {
2314
+ }
2315
+ try {
2316
+ const res = await fetch("https://api6.ipify.org?format=json", { signal: AbortSignal.timeout(3e3) });
2317
+ const data = await res.json();
2318
+ currentIpv6 = data.ip;
2319
+ } catch (e) {
2320
+ }
2321
+ const localIps = [];
2322
+ try {
2323
+ const osModule = require("os");
2324
+ const interfaces = osModule.networkInterfaces();
2325
+ for (const name of Object.keys(interfaces)) {
2326
+ for (const iface of interfaces[name] || []) {
2327
+ if (!iface.internal) {
2328
+ localIps.push(iface.address);
2329
+ }
2330
+ }
2331
+ }
2332
+ } catch (e) {
2333
+ }
2334
+ const isIpv4Match = payload.ipv4 && (currentIpv4 === payload.ipv4 || localIps.includes(payload.ipv4));
2335
+ const isIpv6Match = payload.ipv6 && (currentIpv6 === payload.ipv6 || localIps.includes(payload.ipv6));
2336
+ if (payload.ipv4 && payload.ipv6) {
2337
+ if (!isIpv4Match && !isIpv6Match) {
2338
+ throw new Error(
2339
+ `License key access restricted. This license key was created for a different system (authorized IPv4: ${payload.ipv4}, IPv6: ${payload.ipv6}) and cannot be used on this machine.`
2340
+ );
2341
+ }
2342
+ } else if (payload.ipv4 && !isIpv4Match) {
2343
+ throw new Error(
2344
+ `License key access restricted. This license key was created for a different system (authorized IPv4: ${payload.ipv4}) and cannot be used on this machine.`
2345
+ );
2346
+ } else if (payload.ipv6 && !isIpv6Match) {
2347
+ throw new Error(
2348
+ `License key access restricted. This license key was created for a different system (authorized IPv6: ${payload.ipv6}) and cannot be used on this machine.`
2349
+ );
2350
+ }
2351
+ }
2352
+ } catch (err) {
2353
+ if (err.message.includes("License key access restricted")) {
2354
+ throw new ConfigurationException(`[Retrivora SDK] ${err.message}`);
2355
+ }
2356
+ }
2357
+ }
2358
+ };
2359
+ // A simple in-memory cache to save CPU overhead of cryptographic signature checks.
2360
+ LicenseVerifier.cache = /* @__PURE__ */ new Map();
2361
+ LicenseVerifier.CACHE_TTL_MS = 60 * 1e3;
2362
+ // Cache verified license for 60 seconds
2363
+ // Retrivora's Public Key used to verify the license key signature.
2364
+ // In production, this matches the private key held by Retrivora SaaS.
2365
+ LicenseVerifier.PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----
2366
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArMieCkCBtTfByRNOserm
2367
+ XM4T0Am29JyNzB4XQPe+WJJ56CN73H1HLXx9n1ByFcxkEJ9po+SURj5DnvUXwEy+
2368
+ xstx33wDPpVmcMQe33j5CRYS0S4gICiNqIRN7XkTlJtrcXqrmh1/hdOAwfRbjO1T
2369
+ NVtORHwUwWfI/lBLyxUPGtKPed+0fQ7NtcW4o00JXxs3EjCB5BV9CbnXoTjQb/4h
2370
+ iwZof4l8rb7oaNzOsVg0RSyxsETX7Ex5sI0CjBz1p2mYp4oVhw/A/h8Ls7H0XzjC
2371
+ +Eb6BLtsytt5JHoSp0jExLlCpDmpys2L+kETcBVx+IqiXtdN1n6KbkksvEDUVzLI
2372
+ MwIDAQAB
2373
+ -----END PUBLIC KEY-----`;
2374
+
2096
2375
  // src/config/constants.ts
2097
2376
  var VECTOR_DB_PROVIDERS = [
2098
2377
  "pinecone",
@@ -2162,14 +2441,12 @@ function readEnum(env, name, fallback, allowed) {
2162
2441
  throw new Error(`[getRagConfig] ${name} must be one of: ${allowed.join(", ")}`);
2163
2442
  }
2164
2443
  function getEnvConfig(env = process.env, base) {
2165
- var _a2, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X, _Y, _Z, __, _$, _aa, _ba, _ca, _da, _ea, _fa, _ga, _ha, _ia, _ja, _ka, _la, _ma, _na, _oa, _pa, _qa, _ra, _sa, _ta, _ua, _va, _wa, _xa, _ya, _za, _Aa, _Ba, _Ca, _Da, _Ea, _Fa, _Ga, _Ha, _Ia, _Ja, _Ka, _La, _Ma, _Na, _Oa, _Pa, _Qa, _Ra, _Sa, _Ta, _Ua;
2444
+ var _a2, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X, _Y, _Z, __, _$, _aa, _ba, _ca, _da, _ea, _fa, _ga, _ha, _ia, _ja, _ka, _la, _ma, _na, _oa, _pa, _qa, _ra, _sa, _ta, _ua, _va, _wa, _xa, _ya, _za, _Aa, _Ba, _Ca, _Da, _Ea, _Fa, _Ga, _Ha, _Ia, _Ja, _Ka, _La, _Ma, _Na, _Oa, _Pa, _Qa, _Ra, _Sa, _Ta, _Ua, _Va, _Wa, _Xa, _Ya, _Za, __a, _$a, _ab, _bb, _cb, _db, _eb, _fb, _gb, _hb, _ib, _jb, _kb, _lb, _mb, _nb, _ob, _pb, _qb, _rb, _sb, _tb, _ub, _vb, _wb;
2166
2445
  const projectId = (_c = (_b = (_a2 = readString(env, "RAG_PROJECT_ID")) != null ? _a2 : readString(env, "NEXT_PUBLIC_PROJECT_ID")) != null ? _b : base == null ? void 0 : base.projectId) != null ? _c : "__default__";
2167
2446
  const licenseKey = (_g2 = (_f = (_e = (_d = readString(env, "RAG_LICENSE_KEY")) != null ? _d : readString(env, "RETRIVORA_LICENSE_KEY")) != null ? _e : readString(env, "NEXT_PUBLIC_RETRIVORA_LICENSE_KEY")) != null ? _f : readString(env, "LICENSE_KEY")) != null ? _g2 : base == null ? void 0 : base.licenseKey;
2168
2447
  const telemetryEnabled = readString(env, "TELEMETRY_ENABLED") === "true" || readString(env, "NEXT_PUBLIC_TELEMETRY_ENABLED") === "true" || ((_h = base == null ? void 0 : base.telemetry) == null ? void 0 : _h.enabled) || Boolean(licenseKey);
2169
2448
  const vectorProvider = readEnum(env, "VECTOR_DB_PROVIDER", "pinecone", VECTOR_DB_PROVIDERS);
2170
- const llmProvider = readEnum(env, "LLM_PROVIDER", "openai", LLM_PROVIDERS);
2171
- const embeddingProvider = readEnum(env, "EMBEDDING_PROVIDER", "openai", EMBEDDING_PROVIDERS);
2172
- const embeddingDimensions = readNumber(env, "EMBEDDING_DIMENSIONS", 1536);
2449
+ const embeddingDimensions = readNumber(env, "EMBEDDING_DIMENSIONS", 768);
2173
2450
  const vectorDbOptions = {};
2174
2451
  if (vectorProvider === "pinecone") {
2175
2452
  vectorDbOptions.apiKey = (_l = (_k = readString(env, "PINECONE_API_KEY")) != null ? _k : (_j = (_i = base == null ? void 0 : base.vectorDb) == null ? void 0 : _i.options) == null ? void 0 : _j.apiKey) != null ? _l : "";
@@ -2234,65 +2511,88 @@ function getEnvConfig(env = process.env, base) {
2234
2511
  rest: "default",
2235
2512
  custom: "default"
2236
2513
  };
2514
+ const isFreeTier = (() => {
2515
+ if (!licenseKey) return true;
2516
+ try {
2517
+ const payload = LicenseVerifier.verify(licenseKey, projectId);
2518
+ const tier = (payload.tier || "").toLowerCase();
2519
+ return tier === "free_trial" || tier === "free_tier" || tier === "free" || tier === "hobby";
2520
+ } catch (e) {
2521
+ return true;
2522
+ }
2523
+ })();
2524
+ const DEFAULT_FREE_GATEWAY = "https://llm.retrivora.com/api/v1";
2525
+ const defaultLlmProvider = isFreeTier ? "universal_rest" : "universal_rest";
2526
+ const llmProvider = (_na = (_ma = readEnum(env, "LLM_PROVIDER", defaultLlmProvider, LLM_PROVIDERS)) != null ? _ma : (_la = base == null ? void 0 : base.llm) == null ? void 0 : _la.provider) != null ? _na : defaultLlmProvider;
2527
+ const llmBaseUrl = (_qa = (_pa = readString(env, "LLM_BASE_URL")) != null ? _pa : (_oa = base == null ? void 0 : base.llm) == null ? void 0 : _oa.baseUrl) != null ? _qa : DEFAULT_FREE_GATEWAY;
2528
+ const llmModel = (_ua = (_sa = readString(env, "LLM_MODEL")) != null ? _sa : (_ra = base == null ? void 0 : base.llm) == null ? void 0 : _ra.model) != null ? _ua : isFreeTier ? "llama-3.1-8b-instant" : (_ta = DEFAULT_MODEL_BY_PROVIDER[llmProvider]) != null ? _ta : "gpt-4o";
2529
+ const llmApiKey = (_ya = (_xa = (_va = llmApiKeyByProvider[llmProvider]) != null ? _va : readString(env, "LLM_API_KEY")) != null ? _xa : (_wa = base == null ? void 0 : base.llm) == null ? void 0 : _wa.apiKey) != null ? _ya : "sk-retrivora-cancer-280590";
2530
+ const llmProfile = (_Ca = (_Ba = readString(env, "LLM_UNIVERSAL_PROFILE")) != null ? _Ba : (_Aa = (_za = base == null ? void 0 : base.llm) == null ? void 0 : _za.options) == null ? void 0 : _Aa.profile) != null ? _Ca : "litellm";
2531
+ const defaultEmbeddingProvider = isFreeTier ? "universal_rest" : "universal_rest";
2532
+ const embeddingProvider = (_Fa = (_Ea = readEnum(env, "EMBEDDING_PROVIDER", defaultEmbeddingProvider, EMBEDDING_PROVIDERS)) != null ? _Ea : (_Da = base == null ? void 0 : base.embedding) == null ? void 0 : _Da.provider) != null ? _Fa : defaultEmbeddingProvider;
2533
+ const embeddingBaseUrl = (_Ia = (_Ha = readString(env, "EMBEDDING_BASE_URL")) != null ? _Ha : (_Ga = base == null ? void 0 : base.embedding) == null ? void 0 : _Ga.baseUrl) != null ? _Ia : DEFAULT_FREE_GATEWAY;
2534
+ const embeddingModel = (_La = (_Ka = readString(env, "EMBEDDING_MODEL")) != null ? _Ka : (_Ja = base == null ? void 0 : base.embedding) == null ? void 0 : _Ja.model) != null ? _La : "text-embedding-004";
2535
+ const embeddingApiKey = (_Qa = (_Pa = (_Na = (_Ma = embeddingApiKeyByProvider[embeddingProvider]) != null ? _Ma : readString(env, "EMBEDDING_API_KEY")) != null ? _Na : readString(env, "LLM_API_KEY")) != null ? _Pa : (_Oa = base == null ? void 0 : base.embedding) == null ? void 0 : _Oa.apiKey) != null ? _Qa : "sk-retrivora-cancer-280590";
2536
+ const embeddingProfile = (_Ua = (_Ta = readString(env, "EMBEDDING_UNIVERSAL_PROFILE")) != null ? _Ta : (_Sa = (_Ra = base == null ? void 0 : base.embedding) == null ? void 0 : _Ra.options) == null ? void 0 : _Sa.profile) != null ? _Ua : "litellm";
2237
2537
  return __spreadProps(__spreadValues({
2238
2538
  projectId,
2239
- licenseKey: (_ma = (_la = readString(env, "RETRIVORA_LICENSE_KEY")) != null ? _la : readString(env, "LICENSE_KEY")) != null ? _ma : base == null ? void 0 : base.licenseKey,
2539
+ licenseKey,
2240
2540
  vectorDb: {
2241
2541
  provider: vectorProvider,
2242
- indexName: (_oa = (_na = readString(env, "VECTOR_DB_INDEX")) != null ? _na : vectorDbOptions.indexName) != null ? _oa : "rag-index",
2542
+ indexName: (_Wa = (_Va = readString(env, "VECTOR_DB_INDEX")) != null ? _Va : vectorDbOptions.indexName) != null ? _Wa : "rag-index",
2243
2543
  options: vectorDbOptions
2244
2544
  },
2245
2545
  llm: {
2246
2546
  provider: llmProvider,
2247
- model: (_qa = (_pa = readString(env, "LLM_MODEL")) != null ? _pa : DEFAULT_MODEL_BY_PROVIDER[llmProvider]) != null ? _qa : "gpt-4o",
2248
- apiKey: (_ra = llmApiKeyByProvider[llmProvider]) != null ? _ra : "",
2249
- baseUrl: readString(env, "LLM_BASE_URL"),
2547
+ model: llmModel,
2548
+ apiKey: llmApiKey,
2549
+ baseUrl: llmBaseUrl,
2250
2550
  systemPrompt: readString(env, "LLM_SYSTEM_PROMPT"),
2251
2551
  maxTokens: readNumber(env, "LLM_MAX_TOKENS", 4096),
2252
2552
  temperature: readNumber(env, "LLM_TEMPERATURE", 0.7),
2253
2553
  options: {
2254
- profile: readString(env, "LLM_UNIVERSAL_PROFILE"),
2554
+ profile: llmProfile,
2255
2555
  thinking: readString(env, "LLM_THINKING") === "true" || readString(env, "LLM_THINKING") === "enabled" ? true : readString(env, "LLM_THINKING") === "false" ? false : void 0,
2256
2556
  thinkingBudget: env.LLM_THINKING_BUDGET ? parseInt(env.LLM_THINKING_BUDGET, 10) : void 0
2257
2557
  }
2258
2558
  },
2259
2559
  embedding: {
2260
2560
  provider: embeddingProvider,
2261
- model: (_sa = readString(env, "EMBEDDING_MODEL")) != null ? _sa : "text-embedding-3-small",
2262
- apiKey: embeddingApiKeyByProvider[embeddingProvider],
2263
- baseUrl: readString(env, "EMBEDDING_BASE_URL"),
2561
+ model: embeddingModel,
2562
+ apiKey: embeddingApiKey,
2563
+ baseUrl: embeddingBaseUrl,
2264
2564
  dimensions: embeddingDimensions,
2265
2565
  queryPrefix: readString(env, "EMBEDDING_QUERY_PREFIX"),
2266
2566
  documentPrefix: readString(env, "EMBEDDING_DOCUMENT_PREFIX"),
2267
2567
  options: {
2268
- profile: readString(env, "EMBEDDING_UNIVERSAL_PROFILE")
2568
+ profile: embeddingProfile
2269
2569
  }
2270
2570
  },
2271
2571
  ui: {
2272
- title: (_ua = (_ta = readString(env, "NEXT_PUBLIC_UI_TITLE")) != null ? _ta : readString(env, "UI_TITLE")) != null ? _ua : "AI Assistant",
2273
- subtitle: (_wa = (_va = readString(env, "NEXT_PUBLIC_UI_SUBTITLE")) != null ? _va : readString(env, "UI_SUBTITLE")) != null ? _wa : "Powered by RAG",
2274
- primaryColor: (_ya = (_xa = readString(env, "NEXT_PUBLIC_PRIMARY_COLOR")) != null ? _xa : readString(env, "UI_PRIMARY_COLOR")) != null ? _ya : "#10b981",
2275
- accentColor: (_Aa = (_za = readString(env, "NEXT_PUBLIC_ACCENT_COLOR")) != null ? _za : readString(env, "UI_ACCENT_COLOR")) != null ? _Aa : "#3b82f6",
2276
- logoUrl: (_Ba = readString(env, "NEXT_PUBLIC_LOGO_URL")) != null ? _Ba : readString(env, "UI_LOGO_URL"),
2277
- placeholder: (_Da = (_Ca = readString(env, "NEXT_PUBLIC_PLACEHOLDER")) != null ? _Ca : readString(env, "UI_PLACEHOLDER")) != null ? _Da : "Ask me anything\u2026",
2278
- showSources: ((_Fa = (_Ea = readString(env, "NEXT_PUBLIC_SHOW_SOURCES")) != null ? _Ea : readString(env, "UI_SHOW_SOURCES")) != null ? _Fa : "true") !== "false",
2279
- 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.",
2280
- visualStyle: (_Ja = (_Ia = readString(env, "NEXT_PUBLIC_UI_VISUAL_STYLE")) != null ? _Ia : readString(env, "UI_VISUAL_STYLE")) != null ? _Ja : "glass",
2281
- borderRadius: (_La = (_Ka = readString(env, "NEXT_PUBLIC_UI_BORDER_RADIUS")) != null ? _Ka : readString(env, "UI_BORDER_RADIUS")) != null ? _La : "xl",
2282
- allowUpload: ((_Na = (_Ma = readString(env, "NEXT_PUBLIC_ALLOW_UPLOAD")) != null ? _Ma : readString(env, "UI_ALLOW_UPLOAD")) != null ? _Na : "false") === "true"
2572
+ title: (_Ya = (_Xa = readString(env, "NEXT_PUBLIC_UI_TITLE")) != null ? _Xa : readString(env, "UI_TITLE")) != null ? _Ya : "AI Assistant",
2573
+ subtitle: (__a = (_Za = readString(env, "NEXT_PUBLIC_UI_SUBTITLE")) != null ? _Za : readString(env, "UI_SUBTITLE")) != null ? __a : "Powered by RAG",
2574
+ primaryColor: (_ab = (_$a = readString(env, "NEXT_PUBLIC_PRIMARY_COLOR")) != null ? _$a : readString(env, "UI_PRIMARY_COLOR")) != null ? _ab : "#10b981",
2575
+ accentColor: (_cb = (_bb = readString(env, "NEXT_PUBLIC_ACCENT_COLOR")) != null ? _bb : readString(env, "UI_ACCENT_COLOR")) != null ? _cb : "#3b82f6",
2576
+ logoUrl: (_db = readString(env, "NEXT_PUBLIC_LOGO_URL")) != null ? _db : readString(env, "UI_LOGO_URL"),
2577
+ placeholder: (_fb = (_eb = readString(env, "NEXT_PUBLIC_PLACEHOLDER")) != null ? _eb : readString(env, "UI_PLACEHOLDER")) != null ? _fb : "Ask me anything\u2026",
2578
+ showSources: ((_hb = (_gb = readString(env, "NEXT_PUBLIC_SHOW_SOURCES")) != null ? _gb : readString(env, "UI_SHOW_SOURCES")) != null ? _hb : "true") !== "false",
2579
+ welcomeMessage: (_jb = (_ib = readString(env, "NEXT_PUBLIC_WELCOME_MESSAGE")) != null ? _ib : readString(env, "UI_WELCOME_MESSAGE")) != null ? _jb : "Hello! I'm your AI assistant. Ask me anything about your documents.",
2580
+ visualStyle: (_lb = (_kb = readString(env, "NEXT_PUBLIC_UI_VISUAL_STYLE")) != null ? _kb : readString(env, "UI_VISUAL_STYLE")) != null ? _lb : "glass",
2581
+ borderRadius: (_nb = (_mb = readString(env, "NEXT_PUBLIC_UI_BORDER_RADIUS")) != null ? _mb : readString(env, "UI_BORDER_RADIUS")) != null ? _nb : "xl",
2582
+ allowUpload: ((_pb = (_ob = readString(env, "NEXT_PUBLIC_ALLOW_UPLOAD")) != null ? _ob : readString(env, "UI_ALLOW_UPLOAD")) != null ? _pb : "false") === "true"
2283
2583
  },
2284
2584
  rag: {
2285
2585
  topK: readNumber(env, "RAG_TOP_K", 5),
2286
2586
  scoreThreshold: readNumber(env, "RAG_SCORE_THRESHOLD", 0),
2287
2587
  chunkSize: readNumber(env, "RAG_CHUNK_SIZE", 1e3),
2288
2588
  chunkOverlap: readNumber(env, "RAG_CHUNK_OVERLAP", 200),
2289
- filterableFields: (_Oa = readString(env, "RAG_FILTERABLE_FIELDS")) == null ? void 0 : _Oa.split(",").map((f) => f.trim()),
2589
+ filterableFields: (_qb = readString(env, "RAG_FILTERABLE_FIELDS")) == null ? void 0 : _qb.split(",").map((f) => f.trim()),
2290
2590
  // Query pipeline toggles — read from .env.local
2291
2591
  useQueryTransformation: readString(env, "RAG_USE_QUERY_TRANSFORMATION") === "true",
2292
2592
  useReranking: readString(env, "RAG_USE_RERANKING") === "true",
2293
2593
  useGraphRetrieval: readString(env, "RAG_USE_GRAPH_RETRIEVAL") === "true",
2294
- architecture: (_Pa = readString(env, "RAG_ARCHITECTURE")) != null ? _Pa : "simple",
2295
- chunkingStrategy: (_Qa = readString(env, "RAG_CHUNKING_STRATEGY")) != null ? _Qa : "recursive",
2594
+ architecture: (_rb = readString(env, "RAG_ARCHITECTURE")) != null ? _rb : "simple",
2595
+ chunkingStrategy: (_sb = readString(env, "RAG_CHUNKING_STRATEGY")) != null ? _sb : "recursive",
2296
2596
  uiMapping: (() => {
2297
2597
  const raw = readString(env, "RAG_UI_MAPPING");
2298
2598
  if (!raw) return void 0;
@@ -2305,7 +2605,7 @@ function getEnvConfig(env = process.env, base) {
2305
2605
  },
2306
2606
  telemetry: {
2307
2607
  enabled: telemetryEnabled,
2308
- url: (_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"
2608
+ url: (_wb = (_vb = (_tb = readString(env, "TELEMETRY_URL")) != null ? _tb : readString(env, "NEXT_PUBLIC_TELEMETRY_URL")) != null ? _vb : (_ub = base == null ? void 0 : base.telemetry) == null ? void 0 : _ub.url) != null ? _wb : process.env.NODE_ENV === "development" ? "http://localhost:3001/api/telemetry" : "https://retrivora.com/api/telemetry"
2309
2609
  }
2310
2610
  }, readString(env, "GRAPH_DB_PROVIDER") ? {
2311
2611
  graphDb: {
@@ -2792,10 +3092,12 @@ var AnthropicProvider = class {
2792
3092
  var import_axios = __toESM(require("axios"));
2793
3093
  var OllamaProvider = class {
2794
3094
  constructor(llmConfig, embeddingConfig) {
2795
- var _a2, _b;
2796
- const baseURL = (_a2 = llmConfig.baseUrl) != null ? _a2 : "http://localhost:11434";
3095
+ var _a2, _b, _c;
3096
+ const rawBaseURL = ((_a2 = llmConfig.baseUrl) != null ? _a2 : "http://localhost:11434").replace(/\/+$/, "");
3097
+ const baseURL = rawBaseURL.replace(/\/(?:api\/v1|v1|api)$/i, "");
2797
3098
  const timeout = Number((_b = llmConfig.options) == null ? void 0 : _b.timeout) || 3e5;
2798
- this.http = import_axios.default.create({ baseURL, timeout });
3099
+ const headers = ((_c = llmConfig.options) == null ? void 0 : _c.headers) || {};
3100
+ this.http = import_axios.default.create({ baseURL, timeout, headers });
2799
3101
  this.llmConfig = llmConfig;
2800
3102
  this.embeddingConfig = embeddingConfig;
2801
3103
  }
@@ -3732,112 +4034,40 @@ ${context != null ? context : "None"}` },
3732
4034
  payload = buildPayload(this.opts.embedPayloadTemplate, {
3733
4035
  model: this.model,
3734
4036
  input: text
3735
- });
3736
- } else {
3737
- payload = {
3738
- model: this.model,
3739
- input: text
3740
- };
3741
- }
3742
- const { data } = await this.http.post(path2, payload);
3743
- const extractPath = (_b = this.opts.embedExtractPath) != null ? _b : "data[0].embedding";
3744
- const vector = resolvePath(data, extractPath);
3745
- if (!Array.isArray(vector)) {
3746
- throw new Error(`[UniversalLLMAdapter] Expected a number array at '${extractPath}' for embeddings.`);
3747
- }
3748
- return vector;
3749
- }
3750
- async batchEmbed(texts) {
3751
- const vectors = [];
3752
- for (const text of texts) {
3753
- vectors.push(await this.embed(text));
3754
- }
3755
- return vectors;
3756
- }
3757
- async ping() {
3758
- try {
3759
- if (this.opts.pingPath) {
3760
- await this.http.get(this.opts.pingPath);
3761
- }
3762
- return true;
3763
- } catch (err) {
3764
- console.error("[UniversalLLMAdapter] Ping failed:", err);
3765
- return false;
3766
- }
3767
- }
3768
- };
3769
-
3770
- // src/exceptions/index.ts
3771
- var RetrivoraError = class extends Error {
3772
- constructor(message, code, details) {
3773
- super(message);
3774
- this.name = new.target.name;
3775
- this.code = code;
3776
- this.details = details;
3777
- }
3778
- };
3779
- var ProviderNotFoundException = class extends RetrivoraError {
3780
- constructor(providerType, provider, details) {
3781
- super(`Unsupported ${providerType} provider: ${provider}`, "PROVIDER_NOT_FOUND", details);
3782
- }
3783
- };
3784
- var EmbeddingFailedException = class extends RetrivoraError {
3785
- constructor(message = "Embedding generation failed", details) {
3786
- super(message, "EMBEDDING_FAILED", details);
3787
- }
3788
- };
3789
- var RetrievalException = class extends RetrivoraError {
3790
- constructor(message = "Retrieval failed", details) {
3791
- super(message, "RETRIEVAL_FAILED", details);
3792
- }
3793
- };
3794
- var RateLimitException = class extends RetrivoraError {
3795
- constructor(message = "Provider rate limit exceeded", details) {
3796
- super(message, "RATE_LIMITED", details);
3797
- }
3798
- };
3799
- var ConfigurationException = class extends RetrivoraError {
3800
- constructor(message, details) {
3801
- super(message, "CONFIGURATION_ERROR", details);
3802
- }
3803
- };
3804
- var AuthenticationException = class extends RetrivoraError {
3805
- constructor(message = "Provider authentication failed", details) {
3806
- super(message, "AUTHENTICATION_ERROR", details);
3807
- }
3808
- };
3809
- function wrapError(err, defaultCode, defaultMessage) {
3810
- var _a2;
3811
- if (err instanceof RetrivoraError) {
3812
- return err;
3813
- }
3814
- const error = err;
3815
- const message = (error == null ? void 0 : error.message) || defaultMessage || String(err);
3816
- const status = (error == null ? void 0 : error.status) || (error == null ? void 0 : error.statusCode) || ((_a2 = error == null ? void 0 : error.response) == null ? void 0 : _a2.status);
3817
- const code = error == null ? void 0 : error.code;
3818
- if (status === 429 || /rate[- ]?limit/i.test(message) || code === "RATE_LIMIT_EXCEEDED") {
3819
- return new RateLimitException(message, err);
4037
+ });
4038
+ } else {
4039
+ payload = {
4040
+ model: this.model,
4041
+ input: text
4042
+ };
4043
+ }
4044
+ const { data } = await this.http.post(path2, payload);
4045
+ const extractPath = (_b = this.opts.embedExtractPath) != null ? _b : "data[0].embedding";
4046
+ const vector = resolvePath(data, extractPath);
4047
+ if (!Array.isArray(vector)) {
4048
+ throw new Error(`[UniversalLLMAdapter] Expected a number array at '${extractPath}' for embeddings.`);
4049
+ }
4050
+ return vector;
3820
4051
  }
3821
- if (status === 401 || status === 403 || /unauthorized|auth|api[- ]?key/i.test(message) || code === "INVALID_API_KEY") {
3822
- return new AuthenticationException(message, err);
4052
+ async batchEmbed(texts) {
4053
+ const vectors = [];
4054
+ for (const text of texts) {
4055
+ vectors.push(await this.embed(text));
4056
+ }
4057
+ return vectors;
3823
4058
  }
3824
- switch (defaultCode) {
3825
- case "PROVIDER_NOT_FOUND":
3826
- return new ProviderNotFoundException("provider", message, err);
3827
- case "EMBEDDING_FAILED":
3828
- return new EmbeddingFailedException(message, err);
3829
- case "RETRIEVAL_FAILED":
3830
- return new RetrievalException(message, err);
3831
- case "RATE_LIMITED":
3832
- return new RateLimitException(message, err);
3833
- case "CONFIGURATION_ERROR":
3834
- return new ConfigurationException(message, err);
3835
- case "AUTHENTICATION_ERROR":
3836
- return new AuthenticationException(message, err);
3837
- default:
3838
- return new RetrivoraError(message, defaultCode, err);
4059
+ async ping() {
4060
+ try {
4061
+ if (this.opts.pingPath) {
4062
+ await this.http.get(this.opts.pingPath);
4063
+ }
4064
+ return true;
4065
+ } catch (err) {
4066
+ console.error("[UniversalLLMAdapter] Ping failed:", err);
4067
+ return false;
4068
+ }
3839
4069
  }
3840
- }
4070
+ };
3841
4071
 
3842
4072
  // src/llm/LLMFactory.ts
3843
4073
  var customProviders = /* @__PURE__ */ new Map();
@@ -8764,211 +8994,6 @@ var ProviderHealthCheck = class {
8764
8994
  }
8765
8995
  };
8766
8996
 
8767
- // src/core/LicenseVerifier.ts
8768
- var crypto2 = __toESM(require("crypto"));
8769
- var LicenseVerifier = class {
8770
- /**
8771
- * Decodes, verifies signature, and checks metadata of a license key.
8772
- *
8773
- * @param licenseKey - Base64url signed JWT license key.
8774
- * @param currentProjectId - Project namespace ID.
8775
- * @param publicKeyOverride - Optional override for unit/integration tests.
8776
- */
8777
- static verify(licenseKey, currentProjectId, provider, publicKeyOverride) {
8778
- const isProduction = process.env.NODE_ENV === "production";
8779
- const now = Date.now();
8780
- if (licenseKey) {
8781
- const cacheKey = `${licenseKey}:${currentProjectId}:${provider || ""}:${publicKeyOverride || ""}`;
8782
- const cached = this.cache.get(cacheKey);
8783
- if (cached && now - cached.cachedAt < this.CACHE_TTL_MS) {
8784
- const currentTimestampSec = Math.floor(now / 1e3);
8785
- if (cached.payload.expiresAt && currentTimestampSec > cached.payload.expiresAt) {
8786
- this.cache.delete(cacheKey);
8787
- } else {
8788
- return cached.payload;
8789
- }
8790
- }
8791
- }
8792
- if (!licenseKey) {
8793
- if (isProduction) {
8794
- throw new ConfigurationException(
8795
- "[Retrivora SDK] License key (licenseKey) is required in production environments."
8796
- );
8797
- }
8798
- console.warn(
8799
- `\x1B[33m[Retrivora SDK] WARNING: Running without a license key. This namespace (${currentProjectId}) is permitted for local development only.\x1B[0m`
8800
- );
8801
- return {
8802
- projectId: currentProjectId,
8803
- expiresAt: Math.floor(Date.now() / 1e3) + 86400,
8804
- // Valid for 24h
8805
- tier: "hobby"
8806
- };
8807
- }
8808
- try {
8809
- const parts = licenseKey.split(".");
8810
- if (parts.length !== 3) {
8811
- throw new Error("Malformed token structure (expected 3 parts).");
8812
- }
8813
- const [headerB64, payloadB64, signatureB64] = parts;
8814
- const dataToVerify = `${headerB64}.${payloadB64}`;
8815
- const publicKey = publicKeyOverride != null ? publicKeyOverride : this.PUBLIC_KEY;
8816
- const signature = Buffer.from(signatureB64, "base64url");
8817
- const data = Buffer.from(dataToVerify);
8818
- const isValid = crypto2.verify(
8819
- "sha256",
8820
- data,
8821
- publicKey,
8822
- signature
8823
- );
8824
- if (!isValid) {
8825
- throw new Error("Signature verification failed.");
8826
- }
8827
- const payload = JSON.parse(
8828
- Buffer.from(payloadB64, "base64url").toString("utf8")
8829
- );
8830
- if (!payload.projectId) {
8831
- throw new Error('License payload is missing "projectId".');
8832
- }
8833
- if (payload.projectId !== currentProjectId) {
8834
- throw new Error(
8835
- `Project ID mismatch. License is bound to project namespace "${payload.projectId}" but configuration has "${currentProjectId}".`
8836
- );
8837
- }
8838
- if (!payload.expiresAt) {
8839
- throw new Error('License payload is missing expiration ("expiresAt").');
8840
- }
8841
- const currentTimestampSec = Math.floor(Date.now() / 1e3);
8842
- if (currentTimestampSec > payload.expiresAt) {
8843
- throw new Error(
8844
- `License key has expired. Expiration: ${new Date(
8845
- payload.expiresAt * 1e3
8846
- ).toDateString()}`
8847
- );
8848
- }
8849
- if (isProduction && provider) {
8850
- const tier = (payload.tier || "").toLowerCase();
8851
- const normalizedProvider = provider.toLowerCase();
8852
- if (tier === "hobby") {
8853
- const allowedHobby = ["postgresql", "pgvector", "supabase"];
8854
- if (!allowedHobby.includes(normalizedProvider)) {
8855
- throw new Error(
8856
- `The database provider "${provider}" is not allowed on the Hobby tier. Hobby tier is restricted to PostgreSQL and Supabase. Please upgrade to a Developer Pro or Enterprise plan.`
8857
- );
8858
- }
8859
- } else if (tier === "pro" || tier === "developer_pro" || tier === "premium" || tier === "growth" || tier === "free_trial" || tier === "free_tier" || tier === "free") {
8860
- const allowedPro = [
8861
- "postgresql",
8862
- "pgvector",
8863
- "supabase",
8864
- "pinecone",
8865
- "qdrant",
8866
- "mongodb",
8867
- "milvus",
8868
- "chroma",
8869
- "chromadb"
8870
- ];
8871
- if (!allowedPro.includes(normalizedProvider)) {
8872
- throw new Error(
8873
- `The database provider "${provider}" is not allowed on the Developer Pro tier. Please upgrade to an Enterprise plan.`
8874
- );
8875
- }
8876
- }
8877
- }
8878
- if (licenseKey) {
8879
- const cacheKey = `${licenseKey}:${currentProjectId}:${provider || ""}:${publicKeyOverride || ""}`;
8880
- this.cache.set(cacheKey, { payload, cachedAt: now });
8881
- }
8882
- return payload;
8883
- } catch (err) {
8884
- const message = err instanceof Error ? err.message : String(err);
8885
- throw new ConfigurationException(
8886
- `[Retrivora SDK] License key validation failed: ${message}`
8887
- );
8888
- }
8889
- }
8890
- static async verifyIP(licenseKey) {
8891
- if (!licenseKey) return;
8892
- try {
8893
- const parts = licenseKey.split(".");
8894
- if (parts.length !== 3) return;
8895
- const [, payloadB64] = parts;
8896
- const payload = JSON.parse(
8897
- Buffer.from(payloadB64, "base64url").toString("utf8")
8898
- );
8899
- const tier = (payload.tier || "").toLowerCase();
8900
- if (tier === "enterprise" || tier === "custom") {
8901
- return;
8902
- }
8903
- if (payload.ipv4 || payload.ipv6) {
8904
- let currentIpv4 = "";
8905
- let currentIpv6 = "";
8906
- try {
8907
- const res = await fetch("https://api4.ipify.org?format=json", { signal: AbortSignal.timeout(3e3) });
8908
- const data = await res.json();
8909
- currentIpv4 = data.ip;
8910
- } catch (e) {
8911
- }
8912
- try {
8913
- const res = await fetch("https://api6.ipify.org?format=json", { signal: AbortSignal.timeout(3e3) });
8914
- const data = await res.json();
8915
- currentIpv6 = data.ip;
8916
- } catch (e) {
8917
- }
8918
- const localIps = [];
8919
- try {
8920
- const osModule = require("os");
8921
- const interfaces = osModule.networkInterfaces();
8922
- for (const name of Object.keys(interfaces)) {
8923
- for (const iface of interfaces[name] || []) {
8924
- if (!iface.internal) {
8925
- localIps.push(iface.address);
8926
- }
8927
- }
8928
- }
8929
- } catch (e) {
8930
- }
8931
- const isIpv4Match = payload.ipv4 && (currentIpv4 === payload.ipv4 || localIps.includes(payload.ipv4));
8932
- const isIpv6Match = payload.ipv6 && (currentIpv6 === payload.ipv6 || localIps.includes(payload.ipv6));
8933
- if (payload.ipv4 && payload.ipv6) {
8934
- if (!isIpv4Match && !isIpv6Match) {
8935
- throw new Error(
8936
- `License key access restricted. This license key was created for a different system (authorized IPv4: ${payload.ipv4}, IPv6: ${payload.ipv6}) and cannot be used on this machine.`
8937
- );
8938
- }
8939
- } else if (payload.ipv4 && !isIpv4Match) {
8940
- throw new Error(
8941
- `License key access restricted. This license key was created for a different system (authorized IPv4: ${payload.ipv4}) and cannot be used on this machine.`
8942
- );
8943
- } else if (payload.ipv6 && !isIpv6Match) {
8944
- throw new Error(
8945
- `License key access restricted. This license key was created for a different system (authorized IPv6: ${payload.ipv6}) and cannot be used on this machine.`
8946
- );
8947
- }
8948
- }
8949
- } catch (err) {
8950
- if (err.message.includes("License key access restricted")) {
8951
- throw new ConfigurationException(`[Retrivora SDK] ${err.message}`);
8952
- }
8953
- }
8954
- }
8955
- };
8956
- // A simple in-memory cache to save CPU overhead of cryptographic signature checks.
8957
- LicenseVerifier.cache = /* @__PURE__ */ new Map();
8958
- LicenseVerifier.CACHE_TTL_MS = 60 * 1e3;
8959
- // Cache verified license for 60 seconds
8960
- // Retrivora's Public Key used to verify the license key signature.
8961
- // In production, this matches the private key held by Retrivora SaaS.
8962
- LicenseVerifier.PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----
8963
- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArMieCkCBtTfByRNOserm
8964
- XM4T0Am29JyNzB4XQPe+WJJ56CN73H1HLXx9n1ByFcxkEJ9po+SURj5DnvUXwEy+
8965
- xstx33wDPpVmcMQe33j5CRYS0S4gICiNqIRN7XkTlJtrcXqrmh1/hdOAwfRbjO1T
8966
- NVtORHwUwWfI/lBLyxUPGtKPed+0fQ7NtcW4o00JXxs3EjCB5BV9CbnXoTjQb/4h
8967
- iwZof4l8rb7oaNzOsVg0RSyxsETX7Ex5sI0CjBz1p2mYp4oVhw/A/h8Ls7H0XzjC
8968
- +Eb6BLtsytt5JHoSp0jExLlCpDmpys2L+kETcBVx+IqiXtdN1n6KbkksvEDUVzLI
8969
- MwIDAQAB
8970
- -----END PUBLIC KEY-----`;
8971
-
8972
8997
  // src/core/VectorPlugin.ts
8973
8998
  var VectorPlugin = class {
8974
8999
  constructor(hostConfig) {
@@ -9766,7 +9791,17 @@ function createChatHandler(configOrPlugin, options) {
9766
9791
  if (rateLimited) return rateLimited;
9767
9792
  try {
9768
9793
  const body = await req.json();
9769
- const { message: rawMessage, history = [], namespace, sessionId = "default", messageId, userMessageId } = body;
9794
+ const bodyObj = body != null ? body : {};
9795
+ let rawMessage = bodyObj.message;
9796
+ if (!rawMessage && Array.isArray(bodyObj.messages) && bodyObj.messages.length > 0) {
9797
+ const lastMsg = bodyObj.messages[bodyObj.messages.length - 1];
9798
+ rawMessage = typeof lastMsg === "string" ? lastMsg : (lastMsg == null ? void 0 : lastMsg.content) || (lastMsg == null ? void 0 : lastMsg.text);
9799
+ }
9800
+ if (!rawMessage && typeof bodyObj.prompt === "string") {
9801
+ rawMessage = bodyObj.prompt;
9802
+ }
9803
+ const history = bodyObj.history || (Array.isArray(bodyObj.messages) ? bodyObj.messages.slice(0, -1) : []);
9804
+ const { namespace, sessionId = "default", messageId, userMessageId } = bodyObj;
9770
9805
  const sanitized = sanitizeInput(rawMessage != null ? rawMessage : "");
9771
9806
  if (!sanitized.ok) {
9772
9807
  return import_server.NextResponse.json({ error: { code: "INVALID_INPUT", message: sanitized.error } }, { status: 400 });
@@ -9818,7 +9853,17 @@ function createStreamHandler(configOrPlugin, options) {
9818
9853
  headers: { "Content-Type": "application/json" }
9819
9854
  });
9820
9855
  }
9821
- const { message: rawMessage, history = [], namespace, sessionId = "default", messageId, userMessageId } = body;
9856
+ const bodyObj = body != null ? body : {};
9857
+ let rawMessage = bodyObj.message;
9858
+ if (!rawMessage && Array.isArray(bodyObj.messages) && bodyObj.messages.length > 0) {
9859
+ const lastMsg = bodyObj.messages[bodyObj.messages.length - 1];
9860
+ rawMessage = typeof lastMsg === "string" ? lastMsg : (lastMsg == null ? void 0 : lastMsg.content) || (lastMsg == null ? void 0 : lastMsg.text);
9861
+ }
9862
+ if (!rawMessage && typeof bodyObj.prompt === "string") {
9863
+ rawMessage = bodyObj.prompt;
9864
+ }
9865
+ const history = bodyObj.history || (Array.isArray(bodyObj.messages) ? bodyObj.messages.slice(0, -1) : []);
9866
+ const { namespace, sessionId = "default", messageId, userMessageId } = bodyObj;
9822
9867
  const sanitized = sanitizeInput(rawMessage != null ? rawMessage : "");
9823
9868
  if (!sanitized.ok) {
9824
9869
  return new Response(