@retrivora-ai/rag-engine 2.2.6 → 2.2.8
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/{ILLMProvider-BWa68XX5.d.mts → ILLMProvider-teTNQ1lh.d.mts} +2 -0
- package/dist/{ILLMProvider-BWa68XX5.d.ts → ILLMProvider-teTNQ1lh.d.ts} +2 -0
- package/dist/{index-BCbeeh74.d.ts → LicenseValidator-CENvo9o2.d.mts} +48 -5
- package/dist/{index-BbJGyNmW.d.mts → LicenseValidator-CsjJp2PP.d.ts} +48 -5
- package/dist/handlers/index.d.mts +2 -2
- package/dist/handlers/index.d.ts +2 -2
- package/dist/handlers/index.js +56 -4
- package/dist/handlers/index.mjs +55 -4
- package/dist/{index-DvbtNz7m.d.mts → index-BPJ3KDYI.d.ts} +6 -2
- package/dist/{index-B5TTZWkx.d.ts → index-Dmq5lH0j.d.mts} +6 -2
- package/dist/index.d.mts +6 -6
- package/dist/index.d.ts +6 -6
- package/dist/index.js +475 -104
- package/dist/index.mjs +478 -104
- package/dist/server.d.mts +6 -6
- package/dist/server.d.ts +6 -6
- package/dist/server.js +214 -4
- package/dist/server.mjs +211 -4
- package/package.json +1 -1
- package/src/components/ChatWidget.tsx +30 -35
- package/src/components/ChatWindow.tsx +37 -33
- package/src/core/LicenseValidator.ts +198 -0
- package/src/exceptions/index.ts +25 -5
- package/src/handlers/index.ts +76 -3
- package/src/hooks/useRagChat.ts +29 -2
- package/src/index.ts +4 -0
- package/src/server.ts +6 -0
- package/src/types/chat.ts +2 -0
- package/src/types/props.ts +5 -2
package/dist/index.mjs
CHANGED
|
@@ -18,6 +18,12 @@ var __spreadValues = (a, b) => {
|
|
|
18
18
|
return a;
|
|
19
19
|
};
|
|
20
20
|
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
21
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
22
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
23
|
+
}) : x)(function(x) {
|
|
24
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
25
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
26
|
+
});
|
|
21
27
|
var __objRest = (source, exclude) => {
|
|
22
28
|
var target = {};
|
|
23
29
|
for (var prop in source)
|
|
@@ -2759,7 +2765,7 @@ function useRagChat(projectId, options = {}) {
|
|
|
2759
2765
|
}, [messages]);
|
|
2760
2766
|
const sendMessage = useCallback(
|
|
2761
2767
|
async (text, opts) => {
|
|
2762
|
-
var _a, _b, _c, _d, _e;
|
|
2768
|
+
var _a, _b, _c, _d, _e, _f;
|
|
2763
2769
|
const trimmed = text.trim();
|
|
2764
2770
|
if (!trimmed || isLoading) return;
|
|
2765
2771
|
lastInputRef.current = trimmed;
|
|
@@ -2791,9 +2797,18 @@ function useRagChat(projectId, options = {}) {
|
|
|
2791
2797
|
messageId: assistantMessageId,
|
|
2792
2798
|
userMessageId: userMsgId
|
|
2793
2799
|
});
|
|
2794
|
-
const
|
|
2800
|
+
const getHeader = (headersObj, name) => {
|
|
2801
|
+
if (!headersObj) return void 0;
|
|
2802
|
+
const target = name.toLowerCase();
|
|
2803
|
+
for (const [k, v] of Object.entries(headersObj)) {
|
|
2804
|
+
if (k.toLowerCase() === target) return v;
|
|
2805
|
+
}
|
|
2806
|
+
return void 0;
|
|
2807
|
+
};
|
|
2808
|
+
const resolvedLicenseKey = options.licenseKey || getHeader(options.headers, "x-license-key") || ((_b = getHeader(options.headers, "authorization")) == null ? void 0 : _b.replace(/^Bearer\s+/i, "")) || (typeof process !== "undefined" ? process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY || process.env.RETRIVORA_LICENSE_KEY : "") || "";
|
|
2809
|
+
const fetchHeaders = __spreadValues(__spreadValues({
|
|
2795
2810
|
"Content-Type": "application/json"
|
|
2796
|
-
}, options.headers || {});
|
|
2811
|
+
}, resolvedLicenseKey ? { "x-license-key": resolvedLicenseKey } : {}), options.headers || {});
|
|
2797
2812
|
let response = await fetch(primaryUrl, {
|
|
2798
2813
|
method: "POST",
|
|
2799
2814
|
headers: fetchHeaders,
|
|
@@ -2811,10 +2826,10 @@ function useRagChat(projectId, options = {}) {
|
|
|
2811
2826
|
}
|
|
2812
2827
|
if (!response.ok) {
|
|
2813
2828
|
const errorData = await response.json().catch(() => ({}));
|
|
2814
|
-
if (response.status === 403 || response.status === 401 || typeof errorData.error === "string" && errorData.error.toLowerCase().includes("license") || ((
|
|
2829
|
+
if (response.status === 403 || response.status === 401 || typeof errorData.error === "string" && errorData.error.toLowerCase().includes("license") || ((_c = errorData.error) == null ? void 0 : _c.type) === "license_revoked") {
|
|
2815
2830
|
throw new Error("Your Retrivora license is no longer valid. Please contact your administrator or obtain a valid license key.");
|
|
2816
2831
|
}
|
|
2817
|
-
throw new Error(((
|
|
2832
|
+
throw new Error(((_d = errorData.error) == null ? void 0 : _d.message) || errorData.error || `Server returned ${response.status}`);
|
|
2818
2833
|
}
|
|
2819
2834
|
if (!response.body) {
|
|
2820
2835
|
throw new Error("No response body received from server");
|
|
@@ -2878,7 +2893,7 @@ function useRagChat(projectId, options = {}) {
|
|
|
2878
2893
|
pendingThinkingRef.current = thinkingContent;
|
|
2879
2894
|
scheduleFlush(assistantMessageId);
|
|
2880
2895
|
} else if (frame.type === "metadata") {
|
|
2881
|
-
sources = (
|
|
2896
|
+
sources = (_e = frame.sources) != null ? _e : [];
|
|
2882
2897
|
thinkingMs = frame.thinkingMs;
|
|
2883
2898
|
} else if (frame.type === "ui_transformation") {
|
|
2884
2899
|
uiTransformation = frame.data;
|
|
@@ -2894,7 +2909,7 @@ function useRagChat(projectId, options = {}) {
|
|
|
2894
2909
|
if (frame.type === "text" && frame.text) assistantContent += frame.text;
|
|
2895
2910
|
else if (frame.type === "thinking" && frame.text) thinkingContent += frame.text;
|
|
2896
2911
|
else if (frame.type === "metadata") {
|
|
2897
|
-
sources = (
|
|
2912
|
+
sources = (_f = frame.sources) != null ? _f : [];
|
|
2898
2913
|
thinkingMs = frame.thinkingMs;
|
|
2899
2914
|
} else if (frame.type === "observability") trace = frame.data;
|
|
2900
2915
|
}
|
|
@@ -2919,7 +2934,10 @@ function useRagChat(projectId, options = {}) {
|
|
|
2919
2934
|
console.log("[useRagChat] Streaming stopped by user.");
|
|
2920
2935
|
return;
|
|
2921
2936
|
}
|
|
2922
|
-
|
|
2937
|
+
let msg = err instanceof Error ? err.message : "Something went wrong. Please try again.";
|
|
2938
|
+
if (msg.includes("403") || msg.toLowerCase().includes("license") || msg.toLowerCase().includes("revoked") || msg.toLowerCase().includes("terminated")) {
|
|
2939
|
+
msg = "Your Retrivora license key has been terminated, suspended, or revoked. Access denied.";
|
|
2940
|
+
}
|
|
2923
2941
|
setError(msg);
|
|
2924
2942
|
onError == null ? void 0 : onError(msg);
|
|
2925
2943
|
} finally {
|
|
@@ -3031,7 +3049,7 @@ function useRagChat(projectId, options = {}) {
|
|
|
3031
3049
|
// package.json
|
|
3032
3050
|
var package_default = {
|
|
3033
3051
|
name: "@retrivora-ai/rag-engine",
|
|
3034
|
-
version: "2.2.
|
|
3052
|
+
version: "2.2.8",
|
|
3035
3053
|
description: "Retrivora AI is a plug-and-play AI engine for RAG chat experiences \u2014 generic vector DB + LLM provider, embeddable or standalone.",
|
|
3036
3054
|
author: "Abhinav Alkuchi",
|
|
3037
3055
|
license: "UNLICENSED",
|
|
@@ -3171,6 +3189,407 @@ var package_default = {
|
|
|
3171
3189
|
// src/version.ts
|
|
3172
3190
|
var SDK_VERSION = package_default.version || "2.1.3";
|
|
3173
3191
|
|
|
3192
|
+
// src/exceptions/index.ts
|
|
3193
|
+
var RetrivoraError = class extends Error {
|
|
3194
|
+
constructor(message, code, details) {
|
|
3195
|
+
super(message);
|
|
3196
|
+
this.name = new.target.name;
|
|
3197
|
+
this.code = code;
|
|
3198
|
+
this.details = details;
|
|
3199
|
+
}
|
|
3200
|
+
};
|
|
3201
|
+
var ProviderNotFoundException = class extends RetrivoraError {
|
|
3202
|
+
constructor(providerType, provider, details) {
|
|
3203
|
+
super(`Unsupported ${providerType} provider: ${provider}`, "PROVIDER_NOT_FOUND", details);
|
|
3204
|
+
}
|
|
3205
|
+
};
|
|
3206
|
+
var EmbeddingFailedException = class extends RetrivoraError {
|
|
3207
|
+
constructor(message = "Embedding generation failed", details) {
|
|
3208
|
+
super(message, "EMBEDDING_FAILED", details);
|
|
3209
|
+
}
|
|
3210
|
+
};
|
|
3211
|
+
var RetrievalException = class extends RetrivoraError {
|
|
3212
|
+
constructor(message = "Retrieval failed", details) {
|
|
3213
|
+
super(message, "RETRIEVAL_FAILED", details);
|
|
3214
|
+
}
|
|
3215
|
+
};
|
|
3216
|
+
var RateLimitException = class extends RetrivoraError {
|
|
3217
|
+
constructor(message = "Provider rate limit exceeded", details) {
|
|
3218
|
+
super(message, "RATE_LIMITED", details);
|
|
3219
|
+
}
|
|
3220
|
+
};
|
|
3221
|
+
var ConfigurationException = class extends RetrivoraError {
|
|
3222
|
+
constructor(message, details) {
|
|
3223
|
+
super(message, "CONFIGURATION_ERROR", details);
|
|
3224
|
+
}
|
|
3225
|
+
};
|
|
3226
|
+
var AuthenticationException = class extends RetrivoraError {
|
|
3227
|
+
constructor(message = "Provider authentication failed", details) {
|
|
3228
|
+
super(message, "AUTHENTICATION_ERROR", details);
|
|
3229
|
+
}
|
|
3230
|
+
};
|
|
3231
|
+
var SDKVersionUnsupportedError = class extends RetrivoraError {
|
|
3232
|
+
constructor(message = "This SDK version is no longer supported.", details) {
|
|
3233
|
+
super(message, "SDK_VERSION_UNSUPPORTED", details);
|
|
3234
|
+
}
|
|
3235
|
+
};
|
|
3236
|
+
var LicenseValidationError = class extends RetrivoraError {
|
|
3237
|
+
constructor(message = "License validation failed.", details) {
|
|
3238
|
+
super(message, "LICENSE_VALIDATION_ERROR", details);
|
|
3239
|
+
}
|
|
3240
|
+
};
|
|
3241
|
+
|
|
3242
|
+
// src/core/LicenseVerifier.ts
|
|
3243
|
+
import * as crypto from "crypto";
|
|
3244
|
+
var LicenseVerifier = class {
|
|
3245
|
+
/**
|
|
3246
|
+
* Decodes, verifies signature, and checks metadata of a license key.
|
|
3247
|
+
*
|
|
3248
|
+
* @param licenseKey - Base64url signed JWT license key.
|
|
3249
|
+
* @param currentProjectId - Project namespace ID.
|
|
3250
|
+
* @param publicKeyOverride - Optional override for unit/integration tests.
|
|
3251
|
+
*/
|
|
3252
|
+
static verify(licenseKey, currentProjectId, provider, publicKeyOverride) {
|
|
3253
|
+
const isProduction = process.env.NODE_ENV === "production";
|
|
3254
|
+
const now = Date.now();
|
|
3255
|
+
if (licenseKey) {
|
|
3256
|
+
const cacheKey = `${licenseKey}:${currentProjectId}:${provider || ""}:${publicKeyOverride || ""}`;
|
|
3257
|
+
const cached = this.cache.get(cacheKey);
|
|
3258
|
+
if (cached && now - cached.cachedAt < this.CACHE_TTL_MS) {
|
|
3259
|
+
const currentTimestampSec = Math.floor(now / 1e3);
|
|
3260
|
+
if (cached.payload.expiresAt && currentTimestampSec > cached.payload.expiresAt) {
|
|
3261
|
+
this.cache.delete(cacheKey);
|
|
3262
|
+
} else {
|
|
3263
|
+
return cached.payload;
|
|
3264
|
+
}
|
|
3265
|
+
}
|
|
3266
|
+
}
|
|
3267
|
+
if (!licenseKey) {
|
|
3268
|
+
if (isProduction) {
|
|
3269
|
+
throw new ConfigurationException(
|
|
3270
|
+
"[Retrivora SDK] License key (licenseKey) is required in production environments."
|
|
3271
|
+
);
|
|
3272
|
+
}
|
|
3273
|
+
console.warn(
|
|
3274
|
+
`\x1B[33m[Retrivora SDK] WARNING: Running without a license key. This namespace (${currentProjectId}) is permitted for local development only.\x1B[0m`
|
|
3275
|
+
);
|
|
3276
|
+
return {
|
|
3277
|
+
projectId: currentProjectId,
|
|
3278
|
+
expiresAt: Math.floor(Date.now() / 1e3) + 86400,
|
|
3279
|
+
// Valid for 24h
|
|
3280
|
+
tier: "hobby"
|
|
3281
|
+
};
|
|
3282
|
+
}
|
|
3283
|
+
try {
|
|
3284
|
+
const rawToken = licenseKey.replace(/^rtv_/i, "").trim();
|
|
3285
|
+
const parts = rawToken.split(".");
|
|
3286
|
+
if (parts.length !== 3) {
|
|
3287
|
+
throw new Error("Malformed token structure (expected 3 parts).");
|
|
3288
|
+
}
|
|
3289
|
+
const [headerB64, payloadB64, signatureB64] = parts;
|
|
3290
|
+
const dataToVerify = `${headerB64}.${payloadB64}`;
|
|
3291
|
+
const publicKey = publicKeyOverride != null ? publicKeyOverride : this.PUBLIC_KEY;
|
|
3292
|
+
const signature = Buffer.from(signatureB64, "base64url");
|
|
3293
|
+
const data = Buffer.from(dataToVerify);
|
|
3294
|
+
const isValid = crypto.verify(
|
|
3295
|
+
"sha256",
|
|
3296
|
+
data,
|
|
3297
|
+
publicKey,
|
|
3298
|
+
signature
|
|
3299
|
+
);
|
|
3300
|
+
if (!isValid) {
|
|
3301
|
+
throw new Error("Signature verification failed.");
|
|
3302
|
+
}
|
|
3303
|
+
const payload = JSON.parse(
|
|
3304
|
+
Buffer.from(payloadB64, "base64url").toString("utf8")
|
|
3305
|
+
);
|
|
3306
|
+
if (!payload.projectId) {
|
|
3307
|
+
throw new Error('License payload is missing "projectId".');
|
|
3308
|
+
}
|
|
3309
|
+
const isProjectMatch = payload.projectId === currentProjectId || payload.projectId === `retrivora-${currentProjectId}` || `retrivora-${payload.projectId}` === currentProjectId;
|
|
3310
|
+
if (!isProjectMatch) {
|
|
3311
|
+
throw new Error(
|
|
3312
|
+
`Project ID mismatch. License is bound to project namespace "${payload.projectId}" but configuration has "${currentProjectId}".`
|
|
3313
|
+
);
|
|
3314
|
+
}
|
|
3315
|
+
if (!payload.expiresAt) {
|
|
3316
|
+
throw new Error('License payload is missing expiration ("expiresAt").');
|
|
3317
|
+
}
|
|
3318
|
+
const currentTimestampSec = Math.floor(Date.now() / 1e3);
|
|
3319
|
+
if (currentTimestampSec > payload.expiresAt) {
|
|
3320
|
+
throw new Error(
|
|
3321
|
+
`License key has expired. Expiration: ${new Date(
|
|
3322
|
+
payload.expiresAt * 1e3
|
|
3323
|
+
).toDateString()}`
|
|
3324
|
+
);
|
|
3325
|
+
}
|
|
3326
|
+
if (isProduction && provider) {
|
|
3327
|
+
const tier = (payload.tier || "").toLowerCase();
|
|
3328
|
+
const normalizedProvider = provider.toLowerCase();
|
|
3329
|
+
if (tier === "hobby") {
|
|
3330
|
+
const allowedHobby = ["postgresql", "pgvector", "supabase"];
|
|
3331
|
+
if (!allowedHobby.includes(normalizedProvider)) {
|
|
3332
|
+
throw new Error(
|
|
3333
|
+
`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.`
|
|
3334
|
+
);
|
|
3335
|
+
}
|
|
3336
|
+
} else if (tier === "pro" || tier === "developer_pro" || tier === "premium" || tier === "growth" || tier === "free_trial" || tier === "free_tier" || tier === "free") {
|
|
3337
|
+
const allowedPro = [
|
|
3338
|
+
"postgresql",
|
|
3339
|
+
"pgvector",
|
|
3340
|
+
"supabase",
|
|
3341
|
+
"pinecone",
|
|
3342
|
+
"qdrant",
|
|
3343
|
+
"mongodb",
|
|
3344
|
+
"milvus",
|
|
3345
|
+
"chroma",
|
|
3346
|
+
"chromadb"
|
|
3347
|
+
];
|
|
3348
|
+
if (!allowedPro.includes(normalizedProvider)) {
|
|
3349
|
+
throw new Error(
|
|
3350
|
+
`The database provider "${provider}" is not allowed on the Developer Pro tier. Please upgrade to an Enterprise plan.`
|
|
3351
|
+
);
|
|
3352
|
+
}
|
|
3353
|
+
}
|
|
3354
|
+
}
|
|
3355
|
+
if (licenseKey) {
|
|
3356
|
+
const cacheKey = `${licenseKey}:${currentProjectId}:${provider || ""}:${publicKeyOverride || ""}`;
|
|
3357
|
+
this.cache.set(cacheKey, { payload, cachedAt: now });
|
|
3358
|
+
}
|
|
3359
|
+
return payload;
|
|
3360
|
+
} catch (err) {
|
|
3361
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
3362
|
+
throw new ConfigurationException(
|
|
3363
|
+
`[Retrivora SDK] License key validation failed: ${message}`
|
|
3364
|
+
);
|
|
3365
|
+
}
|
|
3366
|
+
}
|
|
3367
|
+
static async verifyIP(licenseKey) {
|
|
3368
|
+
if (!licenseKey) return;
|
|
3369
|
+
try {
|
|
3370
|
+
const parts = licenseKey.split(".");
|
|
3371
|
+
if (parts.length !== 3) return;
|
|
3372
|
+
const [, payloadB64] = parts;
|
|
3373
|
+
const payload = JSON.parse(
|
|
3374
|
+
Buffer.from(payloadB64, "base64url").toString("utf8")
|
|
3375
|
+
);
|
|
3376
|
+
const tier = (payload.tier || "").toLowerCase();
|
|
3377
|
+
if (tier === "enterprise" || tier === "custom") {
|
|
3378
|
+
return;
|
|
3379
|
+
}
|
|
3380
|
+
if (payload.ipv4 || payload.ipv6) {
|
|
3381
|
+
let currentIpv4 = "";
|
|
3382
|
+
let currentIpv6 = "";
|
|
3383
|
+
try {
|
|
3384
|
+
const res = await fetch("https://api4.ipify.org?format=json", { signal: AbortSignal.timeout(3e3) });
|
|
3385
|
+
const data = await res.json();
|
|
3386
|
+
currentIpv4 = data.ip;
|
|
3387
|
+
} catch (e) {
|
|
3388
|
+
}
|
|
3389
|
+
try {
|
|
3390
|
+
const res = await fetch("https://api6.ipify.org?format=json", { signal: AbortSignal.timeout(3e3) });
|
|
3391
|
+
const data = await res.json();
|
|
3392
|
+
currentIpv6 = data.ip;
|
|
3393
|
+
} catch (e) {
|
|
3394
|
+
}
|
|
3395
|
+
const localIps = [];
|
|
3396
|
+
try {
|
|
3397
|
+
const osModule = __require("os");
|
|
3398
|
+
const interfaces = osModule.networkInterfaces();
|
|
3399
|
+
for (const name of Object.keys(interfaces)) {
|
|
3400
|
+
for (const iface of interfaces[name] || []) {
|
|
3401
|
+
if (!iface.internal) {
|
|
3402
|
+
localIps.push(iface.address);
|
|
3403
|
+
}
|
|
3404
|
+
}
|
|
3405
|
+
}
|
|
3406
|
+
} catch (e) {
|
|
3407
|
+
}
|
|
3408
|
+
const isIpv4Match = payload.ipv4 && (currentIpv4 === payload.ipv4 || localIps.includes(payload.ipv4));
|
|
3409
|
+
const isIpv6Match = payload.ipv6 && (currentIpv6 === payload.ipv6 || localIps.includes(payload.ipv6));
|
|
3410
|
+
if (payload.ipv4 && payload.ipv6) {
|
|
3411
|
+
if (!isIpv4Match && !isIpv6Match) {
|
|
3412
|
+
throw new Error(
|
|
3413
|
+
`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.`
|
|
3414
|
+
);
|
|
3415
|
+
}
|
|
3416
|
+
} else if (payload.ipv4 && !isIpv4Match) {
|
|
3417
|
+
throw new Error(
|
|
3418
|
+
`License key access restricted. This license key was created for a different system (authorized IPv4: ${payload.ipv4}) and cannot be used on this machine.`
|
|
3419
|
+
);
|
|
3420
|
+
} else if (payload.ipv6 && !isIpv6Match) {
|
|
3421
|
+
throw new Error(
|
|
3422
|
+
`License key access restricted. This license key was created for a different system (authorized IPv6: ${payload.ipv6}) and cannot be used on this machine.`
|
|
3423
|
+
);
|
|
3424
|
+
}
|
|
3425
|
+
}
|
|
3426
|
+
} catch (err) {
|
|
3427
|
+
if (err.message.includes("License key access restricted")) {
|
|
3428
|
+
throw new ConfigurationException(`[Retrivora SDK] ${err.message}`);
|
|
3429
|
+
}
|
|
3430
|
+
}
|
|
3431
|
+
}
|
|
3432
|
+
};
|
|
3433
|
+
// A simple in-memory cache to save CPU overhead of cryptographic signature checks.
|
|
3434
|
+
LicenseVerifier.cache = /* @__PURE__ */ new Map();
|
|
3435
|
+
LicenseVerifier.CACHE_TTL_MS = 60 * 1e3;
|
|
3436
|
+
// Cache verified license for 60 seconds
|
|
3437
|
+
// Retrivora's Public Key used to verify the license key signature.
|
|
3438
|
+
// In production, this matches the private key held by Retrivora SaaS.
|
|
3439
|
+
LicenseVerifier.PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----
|
|
3440
|
+
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArMieCkCBtTfByRNOserm
|
|
3441
|
+
XM4T0Am29JyNzB4XQPe+WJJ56CN73H1HLXx9n1ByFcxkEJ9po+SURj5DnvUXwEy+
|
|
3442
|
+
xstx33wDPpVmcMQe33j5CRYS0S4gICiNqIRN7XkTlJtrcXqrmh1/hdOAwfRbjO1T
|
|
3443
|
+
NVtORHwUwWfI/lBLyxUPGtKPed+0fQ7NtcW4o00JXxs3EjCB5BV9CbnXoTjQb/4h
|
|
3444
|
+
iwZof4l8rb7oaNzOsVg0RSyxsETX7Ex5sI0CjBz1p2mYp4oVhw/A/h8Ls7H0XzjC
|
|
3445
|
+
+Eb6BLtsytt5JHoSp0jExLlCpDmpys2L+kETcBVx+IqiXtdN1n6KbkksvEDUVzLI
|
|
3446
|
+
MwIDAQAB
|
|
3447
|
+
-----END PUBLIC KEY-----`;
|
|
3448
|
+
|
|
3449
|
+
// src/core/LicenseValidator.ts
|
|
3450
|
+
var _LicenseValidator = class _LicenseValidator {
|
|
3451
|
+
// 5-minute TTL for successful validation only
|
|
3452
|
+
constructor() {
|
|
3453
|
+
this.cache = /* @__PURE__ */ new Map();
|
|
3454
|
+
}
|
|
3455
|
+
static getInstance() {
|
|
3456
|
+
if (!_LicenseValidator.instance) {
|
|
3457
|
+
_LicenseValidator.instance = new _LicenseValidator();
|
|
3458
|
+
}
|
|
3459
|
+
return _LicenseValidator.instance;
|
|
3460
|
+
}
|
|
3461
|
+
/**
|
|
3462
|
+
* Invalidate local validation cache for a license key
|
|
3463
|
+
*/
|
|
3464
|
+
purgeCache(licenseKey) {
|
|
3465
|
+
if (licenseKey) {
|
|
3466
|
+
this.cache.delete(licenseKey);
|
|
3467
|
+
} else {
|
|
3468
|
+
this.cache.clear();
|
|
3469
|
+
}
|
|
3470
|
+
}
|
|
3471
|
+
/**
|
|
3472
|
+
* Validate license status and SDK version against Retrivora License Service
|
|
3473
|
+
*/
|
|
3474
|
+
async validate(request) {
|
|
3475
|
+
var _a;
|
|
3476
|
+
const {
|
|
3477
|
+
licenseKey,
|
|
3478
|
+
projectId,
|
|
3479
|
+
sdkVersion = SDK_VERSION,
|
|
3480
|
+
sdk = "@retrivora-ai/rag-engine",
|
|
3481
|
+
platform = typeof window !== "undefined" ? "browser" : "node",
|
|
3482
|
+
retrivoraApiBase,
|
|
3483
|
+
headers: customHeaders
|
|
3484
|
+
} = request;
|
|
3485
|
+
const getHeader = (name) => {
|
|
3486
|
+
if (!customHeaders) return void 0;
|
|
3487
|
+
const target = name.toLowerCase();
|
|
3488
|
+
for (const [k, v] of Object.entries(customHeaders)) {
|
|
3489
|
+
if (k.toLowerCase() === target) return v;
|
|
3490
|
+
}
|
|
3491
|
+
return void 0;
|
|
3492
|
+
};
|
|
3493
|
+
const effectiveLicenseKey = licenseKey || getHeader("x-license-key") || ((_a = getHeader("authorization")) == null ? void 0 : _a.replace(/^Bearer\s+/i, "")) || (typeof process !== "undefined" ? process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY || process.env.RETRIVORA_LICENSE_KEY : "") || "";
|
|
3494
|
+
if (!effectiveLicenseKey) {
|
|
3495
|
+
this.purgeCache(effectiveLicenseKey);
|
|
3496
|
+
throw new LicenseValidationError("Missing RETRIVORA_LICENSE_KEY in request.");
|
|
3497
|
+
}
|
|
3498
|
+
const cached = this.cache.get(effectiveLicenseKey);
|
|
3499
|
+
if (cached) {
|
|
3500
|
+
const isFresh = Date.now() - cached.timestamp < _LicenseValidator.SUCCESS_CACHE_TTL_MS;
|
|
3501
|
+
if (isFresh && cached.response.valid && cached.response.licenseStatus === "ACTIVE" && !cached.response.forceUpgrade) {
|
|
3502
|
+
return cached.response;
|
|
3503
|
+
} else {
|
|
3504
|
+
this.cache.delete(effectiveLicenseKey);
|
|
3505
|
+
}
|
|
3506
|
+
}
|
|
3507
|
+
const base = retrivoraApiBase || (typeof process !== "undefined" ? process.env.NEXT_PUBLIC_RETRIVORA_API_BASE || process.env.RETRIVORA_API_BASE : "") || "/api/retrivora";
|
|
3508
|
+
const validateUrl = `${base.replace(/\/$/, "")}/v1/license/validate`;
|
|
3509
|
+
let res = null;
|
|
3510
|
+
try {
|
|
3511
|
+
res = await fetch(validateUrl, {
|
|
3512
|
+
method: "POST",
|
|
3513
|
+
cache: "no-store",
|
|
3514
|
+
headers: __spreadValues({
|
|
3515
|
+
"Content-Type": "application/json",
|
|
3516
|
+
"x-license-key": effectiveLicenseKey,
|
|
3517
|
+
"x-sdk-version": sdkVersion
|
|
3518
|
+
}, customHeaders || {}),
|
|
3519
|
+
body: JSON.stringify({
|
|
3520
|
+
licenseKey,
|
|
3521
|
+
projectId,
|
|
3522
|
+
sdkVersion,
|
|
3523
|
+
sdk,
|
|
3524
|
+
platform
|
|
3525
|
+
})
|
|
3526
|
+
});
|
|
3527
|
+
} catch (err) {
|
|
3528
|
+
try {
|
|
3529
|
+
const payload = LicenseVerifier.verify(licenseKey, projectId || "my-rag-app");
|
|
3530
|
+
const fallbackResp = {
|
|
3531
|
+
valid: true,
|
|
3532
|
+
licenseStatus: "ACTIVE",
|
|
3533
|
+
minimumSupportedVersion: "2.1.0",
|
|
3534
|
+
latestVersion: SDK_VERSION,
|
|
3535
|
+
forceUpgrade: false,
|
|
3536
|
+
expiresAt: payload.expiresAt ? new Date(payload.expiresAt * 1e3).toISOString() : null,
|
|
3537
|
+
message: "Local license verification active."
|
|
3538
|
+
};
|
|
3539
|
+
this.cache.set(licenseKey, { response: fallbackResp, timestamp: Date.now() });
|
|
3540
|
+
return fallbackResp;
|
|
3541
|
+
} catch (e) {
|
|
3542
|
+
this.purgeCache(licenseKey);
|
|
3543
|
+
throw new LicenseValidationError(`License validation request failed: ${(err == null ? void 0 : err.message) || "Network error"}`);
|
|
3544
|
+
}
|
|
3545
|
+
}
|
|
3546
|
+
if (res && !res.ok) {
|
|
3547
|
+
try {
|
|
3548
|
+
const payload = LicenseVerifier.verify(licenseKey, projectId || "my-rag-app");
|
|
3549
|
+
const fallbackResp = {
|
|
3550
|
+
valid: true,
|
|
3551
|
+
licenseStatus: "ACTIVE",
|
|
3552
|
+
minimumSupportedVersion: "2.1.0",
|
|
3553
|
+
latestVersion: SDK_VERSION,
|
|
3554
|
+
forceUpgrade: false,
|
|
3555
|
+
expiresAt: payload.expiresAt ? new Date(payload.expiresAt * 1e3).toISOString() : null,
|
|
3556
|
+
message: "Local license verification active."
|
|
3557
|
+
};
|
|
3558
|
+
this.cache.set(licenseKey, { response: fallbackResp, timestamp: Date.now() });
|
|
3559
|
+
return fallbackResp;
|
|
3560
|
+
} catch (e) {
|
|
3561
|
+
}
|
|
3562
|
+
}
|
|
3563
|
+
const data = await res.json().catch(() => ({
|
|
3564
|
+
valid: false,
|
|
3565
|
+
licenseStatus: "REVOKED",
|
|
3566
|
+
minimumSupportedVersion: "2.1.0",
|
|
3567
|
+
latestVersion: SDK_VERSION,
|
|
3568
|
+
forceUpgrade: false,
|
|
3569
|
+
expiresAt: null,
|
|
3570
|
+
message: "Failed to parse license validation response."
|
|
3571
|
+
}));
|
|
3572
|
+
if (!res.ok || !data.valid || data.licenseStatus !== "ACTIVE" || data.forceUpgrade) {
|
|
3573
|
+
this.purgeCache(licenseKey);
|
|
3574
|
+
if (data.forceUpgrade || res.status === 426) {
|
|
3575
|
+
throw new SDKVersionUnsupportedError(
|
|
3576
|
+
data.message || `This SDK version (${sdkVersion}) is no longer supported. Upgrade to version ${data.latestVersion || "2.2.6"} or later.`,
|
|
3577
|
+
data
|
|
3578
|
+
);
|
|
3579
|
+
}
|
|
3580
|
+
const errMsg = data.message || `License validation failed with status: ${data.licenseStatus}. Access denied.`;
|
|
3581
|
+
throw new LicenseValidationError(errMsg, data);
|
|
3582
|
+
}
|
|
3583
|
+
this.cache.set(licenseKey, {
|
|
3584
|
+
response: data,
|
|
3585
|
+
timestamp: Date.now()
|
|
3586
|
+
});
|
|
3587
|
+
return data;
|
|
3588
|
+
}
|
|
3589
|
+
};
|
|
3590
|
+
_LicenseValidator.SUCCESS_CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
3591
|
+
var LicenseValidator = _LicenseValidator;
|
|
3592
|
+
|
|
3174
3593
|
// src/components/ChatWindow.tsx
|
|
3175
3594
|
import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
3176
3595
|
function ChatWindow({
|
|
@@ -3186,6 +3605,7 @@ function ChatWindow({
|
|
|
3186
3605
|
onAddToCart,
|
|
3187
3606
|
apiUrl,
|
|
3188
3607
|
retrivoraApiBase,
|
|
3608
|
+
licenseKey: licenseKeyProp,
|
|
3189
3609
|
headers
|
|
3190
3610
|
}) {
|
|
3191
3611
|
var _a;
|
|
@@ -3200,6 +3620,7 @@ function ChatWindow({
|
|
|
3200
3620
|
namespace: projectId,
|
|
3201
3621
|
apiUrl,
|
|
3202
3622
|
retrivoraApiBase,
|
|
3623
|
+
licenseKey: licenseKeyProp,
|
|
3203
3624
|
headers
|
|
3204
3625
|
});
|
|
3205
3626
|
const [suggestions, setSuggestions] = useState6([]);
|
|
@@ -3214,42 +3635,40 @@ function ChatWindow({
|
|
|
3214
3635
|
async function validateSessionLicense() {
|
|
3215
3636
|
var _a2;
|
|
3216
3637
|
try {
|
|
3217
|
-
const
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
headers: __spreadValues({
|
|
3223
|
-
"Content-Type": "application/json",
|
|
3224
|
-
"x-sdk-version": SDK_VERSION
|
|
3225
|
-
}, headers || {})
|
|
3226
|
-
});
|
|
3227
|
-
if (!res.ok) {
|
|
3228
|
-
const data = await res.json().catch(() => ({}));
|
|
3229
|
-
if (res.status === 426 || data.code === "SDK_VERSION_OUTDATED") {
|
|
3230
|
-
if (isMounted) {
|
|
3231
|
-
setVersionError(data.error || "Your Retrivora SDK package is outdated. Please update your package to the latest version to continue.");
|
|
3232
|
-
}
|
|
3233
|
-
} else if (res.status === 403 || res.status === 401 || typeof data.error === "string" && data.error.toLowerCase().includes("license")) {
|
|
3234
|
-
if (isMounted) {
|
|
3235
|
-
const errMsg = typeof data.error === "string" ? data.error : ((_a2 = data.error) == null ? void 0 : _a2.message) || "Your Retrivora license is no longer valid. Please contact your administrator or obtain a valid license key.";
|
|
3236
|
-
setLicenseError(errMsg);
|
|
3237
|
-
}
|
|
3638
|
+
const getHeader = (name) => {
|
|
3639
|
+
if (!headers) return void 0;
|
|
3640
|
+
const target = name.toLowerCase();
|
|
3641
|
+
for (const [k, v] of Object.entries(headers)) {
|
|
3642
|
+
if (k.toLowerCase() === target) return v;
|
|
3238
3643
|
}
|
|
3239
|
-
|
|
3240
|
-
|
|
3241
|
-
|
|
3242
|
-
|
|
3644
|
+
return void 0;
|
|
3645
|
+
};
|
|
3646
|
+
const resolvedLicenseKey = licenseKeyProp || getHeader("x-license-key") || ((_a2 = getHeader("authorization")) == null ? void 0 : _a2.replace(/^Bearer\s+/i, "")) || (typeof process !== "undefined" ? process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY || process.env.RETRIVORA_LICENSE_KEY : "") || "";
|
|
3647
|
+
await LicenseValidator.getInstance().validate({
|
|
3648
|
+
licenseKey: resolvedLicenseKey,
|
|
3649
|
+
projectId,
|
|
3650
|
+
retrivoraApiBase,
|
|
3651
|
+
headers
|
|
3652
|
+
});
|
|
3653
|
+
if (isMounted) {
|
|
3654
|
+
setLicenseError(null);
|
|
3655
|
+
setVersionError(null);
|
|
3656
|
+
}
|
|
3657
|
+
} catch (err) {
|
|
3658
|
+
if (isMounted) {
|
|
3659
|
+
if ((err == null ? void 0 : err.code) === "SDK_VERSION_UNSUPPORTED") {
|
|
3660
|
+
setVersionError((err == null ? void 0 : err.message) || "SDK version unsupported.");
|
|
3661
|
+
} else {
|
|
3662
|
+
setLicenseError((err == null ? void 0 : err.message) || "License validation failed.");
|
|
3243
3663
|
}
|
|
3244
3664
|
}
|
|
3245
|
-
} catch (e) {
|
|
3246
3665
|
}
|
|
3247
3666
|
}
|
|
3248
3667
|
validateSessionLicense();
|
|
3249
3668
|
return () => {
|
|
3250
3669
|
isMounted = false;
|
|
3251
3670
|
};
|
|
3252
|
-
}, [retrivoraApiBase, headers]);
|
|
3671
|
+
}, [retrivoraApiBase, headers, projectId]);
|
|
3253
3672
|
useEffect5(() => {
|
|
3254
3673
|
if (typeof window !== "undefined") {
|
|
3255
3674
|
const win = window;
|
|
@@ -3697,8 +4116,8 @@ var GEMINI_STYLES = `
|
|
|
3697
4116
|
--circle: shape(evenodd from 13.482% 79.505%, curve by -7.1945% -12.47% with -1.4985% -1.8575% / -6.328% -10.225%, curve by 0.0985% -33.8965% with -4.1645% -10.7945% / -4.1685% -23.0235%, curve by 6.9955% -12.101% with 1.72% -4.3825% / 4.0845% -8.458%, curve by 30.125% -17.119% with 7.339% -9.1825% / 18.4775% -15.5135%, curve by 13.4165% 0.095% with 4.432% -0.6105% / 8.9505% -0.5855%, curve by 29.364% 16.9% with 11.6215% 1.77% / 22.102% 7.9015%, curve by 7.176% 12.4145% with 3.002% 3.7195% / 5.453% 7.968%, curve by -0.0475% 33.8925% with 4.168% 10.756% / 4.2305% 22.942%, curve by -7.1135% 12.2825% with -1.74% 4.4535% / -4.1455% 8.592%, curve by -29.404% 16.9075% with -7.202% 8.954% / -18.019% 15.137%, curve by -14.19% -0.018% with -4.6635% 0.7255% / -9.4575% 0.7205%, curve by -29.226% -16.8875% with -11.573% -1.8065% / -21.9955% -7.9235%, close);
|
|
3698
4117
|
}
|
|
3699
4118
|
`;
|
|
3700
|
-
function ChatWidget({ position = "bottom-right", onAddToCart, apiUrl, retrivoraApiBase, headers }) {
|
|
3701
|
-
const { ui } = useConfig();
|
|
4119
|
+
function ChatWidget({ position = "bottom-right", onAddToCart, apiUrl, retrivoraApiBase, licenseKey: licenseKeyProp, headers }) {
|
|
4120
|
+
const { ui, projectId } = useConfig();
|
|
3702
4121
|
const [isOpen, setIsOpen] = useState7(false);
|
|
3703
4122
|
const [hasUnread, setHasUnread] = useState7(false);
|
|
3704
4123
|
const [dimensions, setDimensions] = useState7(DEFAULT_DIMENSIONS);
|
|
@@ -3714,36 +4133,27 @@ function ChatWidget({ position = "bottom-right", onAddToCart, apiUrl, retrivoraA
|
|
|
3714
4133
|
var _a;
|
|
3715
4134
|
setIsValidating(true);
|
|
3716
4135
|
try {
|
|
3717
|
-
const
|
|
3718
|
-
|
|
3719
|
-
|
|
3720
|
-
|
|
3721
|
-
|
|
3722
|
-
headers: __spreadValues({
|
|
3723
|
-
"Content-Type": "application/json",
|
|
3724
|
-
"x-sdk-version": SDK_VERSION
|
|
3725
|
-
}, headers || {})
|
|
3726
|
-
});
|
|
3727
|
-
if (!res.ok) {
|
|
3728
|
-
const data = await res.json().catch(() => ({}));
|
|
3729
|
-
if (res.status === 426 || data.code === "SDK_VERSION_OUTDATED") {
|
|
3730
|
-
const msg = data.error || "Your Retrivora SDK package version is outdated. Please update your package to the latest version to continue.";
|
|
3731
|
-
setWidgetError(msg);
|
|
3732
|
-
setIsOpen(false);
|
|
3733
|
-
return;
|
|
3734
|
-
}
|
|
3735
|
-
if (res.status === 403 || res.status === 401 || typeof data.error === "string" && data.error.toLowerCase().includes("license")) {
|
|
3736
|
-
const msg = (typeof data.error === "string" ? data.error : (_a = data.error) == null ? void 0 : _a.message) || "Your Retrivora license is no longer valid. Please contact your administrator or obtain a valid license key.";
|
|
3737
|
-
setWidgetError(msg);
|
|
3738
|
-
setIsOpen(false);
|
|
3739
|
-
return;
|
|
4136
|
+
const getHeader = (name) => {
|
|
4137
|
+
if (!headers) return void 0;
|
|
4138
|
+
const target = name.toLowerCase();
|
|
4139
|
+
for (const [k, v] of Object.entries(headers)) {
|
|
4140
|
+
if (k.toLowerCase() === target) return v;
|
|
3740
4141
|
}
|
|
3741
|
-
|
|
4142
|
+
return void 0;
|
|
4143
|
+
};
|
|
4144
|
+
const resolvedLicenseKey = licenseKeyProp || getHeader("x-license-key") || ((_a = getHeader("authorization")) == null ? void 0 : _a.replace(/^Bearer\s+/i, "")) || (typeof process !== "undefined" ? process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY || process.env.RETRIVORA_LICENSE_KEY : "") || "";
|
|
4145
|
+
await LicenseValidator.getInstance().validate({
|
|
4146
|
+
licenseKey: resolvedLicenseKey,
|
|
4147
|
+
projectId,
|
|
4148
|
+
retrivoraApiBase,
|
|
4149
|
+
headers
|
|
4150
|
+
});
|
|
3742
4151
|
setWidgetError(null);
|
|
3743
4152
|
setIsOpen(true);
|
|
3744
4153
|
setHasUnread(false);
|
|
3745
|
-
} catch (
|
|
3746
|
-
|
|
4154
|
+
} catch (err) {
|
|
4155
|
+
setWidgetError((err == null ? void 0 : err.message) || "Access denied.");
|
|
4156
|
+
setIsOpen(false);
|
|
3747
4157
|
} finally {
|
|
3748
4158
|
setIsValidating(false);
|
|
3749
4159
|
}
|
|
@@ -3815,6 +4225,7 @@ function ChatWidget({ position = "bottom-right", onAddToCart, apiUrl, retrivoraA
|
|
|
3815
4225
|
onAddToCart,
|
|
3816
4226
|
apiUrl,
|
|
3817
4227
|
retrivoraApiBase,
|
|
4228
|
+
licenseKey: licenseKeyProp,
|
|
3818
4229
|
headers
|
|
3819
4230
|
}
|
|
3820
4231
|
),
|
|
@@ -5882,46 +6293,6 @@ _RendererRegistry.registerStrategy(new CarouselRendererStrategy());
|
|
|
5882
6293
|
_RendererRegistry.registerStrategy(new ChartRendererStrategy());
|
|
5883
6294
|
_RendererRegistry.registerStrategy(new MixedRendererStrategy());
|
|
5884
6295
|
var RendererRegistry = _RendererRegistry;
|
|
5885
|
-
|
|
5886
|
-
// src/exceptions/index.ts
|
|
5887
|
-
var RetrivoraError = class extends Error {
|
|
5888
|
-
constructor(message, code, details) {
|
|
5889
|
-
super(message);
|
|
5890
|
-
this.name = new.target.name;
|
|
5891
|
-
this.code = code;
|
|
5892
|
-
this.details = details;
|
|
5893
|
-
}
|
|
5894
|
-
};
|
|
5895
|
-
var ProviderNotFoundException = class extends RetrivoraError {
|
|
5896
|
-
constructor(providerType, provider, details) {
|
|
5897
|
-
super(`Unsupported ${providerType} provider: ${provider}`, "PROVIDER_NOT_FOUND", details);
|
|
5898
|
-
}
|
|
5899
|
-
};
|
|
5900
|
-
var EmbeddingFailedException = class extends RetrivoraError {
|
|
5901
|
-
constructor(message = "Embedding generation failed", details) {
|
|
5902
|
-
super(message, "EMBEDDING_FAILED", details);
|
|
5903
|
-
}
|
|
5904
|
-
};
|
|
5905
|
-
var RetrievalException = class extends RetrivoraError {
|
|
5906
|
-
constructor(message = "Retrieval failed", details) {
|
|
5907
|
-
super(message, "RETRIEVAL_FAILED", details);
|
|
5908
|
-
}
|
|
5909
|
-
};
|
|
5910
|
-
var RateLimitException = class extends RetrivoraError {
|
|
5911
|
-
constructor(message = "Provider rate limit exceeded", details) {
|
|
5912
|
-
super(message, "RATE_LIMITED", details);
|
|
5913
|
-
}
|
|
5914
|
-
};
|
|
5915
|
-
var ConfigurationException = class extends RetrivoraError {
|
|
5916
|
-
constructor(message, details) {
|
|
5917
|
-
super(message, "CONFIGURATION_ERROR", details);
|
|
5918
|
-
}
|
|
5919
|
-
};
|
|
5920
|
-
var AuthenticationException = class extends RetrivoraError {
|
|
5921
|
-
constructor(message = "Provider authentication failed", details) {
|
|
5922
|
-
super(message, "AUTHENTICATION_ERROR", details);
|
|
5923
|
-
}
|
|
5924
|
-
};
|
|
5925
6296
|
export {
|
|
5926
6297
|
AuthenticationException,
|
|
5927
6298
|
ChatWidget,
|
|
@@ -5932,6 +6303,8 @@ export {
|
|
|
5932
6303
|
DocumentUpload,
|
|
5933
6304
|
EmbeddingFailedException,
|
|
5934
6305
|
IntentClassifier,
|
|
6306
|
+
LicenseValidationError,
|
|
6307
|
+
LicenseValidator,
|
|
5935
6308
|
MessageBubble,
|
|
5936
6309
|
ObservabilityPanel,
|
|
5937
6310
|
ProductCard,
|
|
@@ -5942,6 +6315,7 @@ export {
|
|
|
5942
6315
|
RetrievalException,
|
|
5943
6316
|
RetrivoraError,
|
|
5944
6317
|
RuleEngine,
|
|
6318
|
+
SDKVersionUnsupportedError,
|
|
5945
6319
|
SDK_VERSION,
|
|
5946
6320
|
SourceCard,
|
|
5947
6321
|
VisualizationDecisionEngine,
|