@retrivora-ai/rag-engine 2.1.7 → 2.2.0

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
@@ -778,6 +778,84 @@ var init_BaseVectorProvider = __esm({
778
778
  }
779
779
  });
780
780
 
781
+ // src/core/ConfigFetcher.ts
782
+ var ConfigFetcher;
783
+ var init_ConfigFetcher = __esm({
784
+ "src/core/ConfigFetcher.ts"() {
785
+ "use strict";
786
+ ConfigFetcher = class {
787
+ // 5-minute in-memory session cache
788
+ /**
789
+ * Fetch full project configuration (vectorDb + embedding + llm) from Retrivora Control Plane.
790
+ */
791
+ static async fetchRemoteConfig(projectId, licenseKey) {
792
+ var _a2, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
793
+ const cacheKey = `${projectId}:${licenseKey || ""}`;
794
+ const now = Date.now();
795
+ const cached = this.cache.get(cacheKey);
796
+ if (cached && now - cached.cachedAt < this.TTL_MS) {
797
+ return cached.config;
798
+ }
799
+ const controlPlaneUrls = [
800
+ process.env.RETRIVORA_CONTROL_PLANE_URL,
801
+ process.env.NEXT_PUBLIC_RETRIVORA_CONTROL_PLANE_URL,
802
+ "https://retrivora.com",
803
+ "http://localhost:3000"
804
+ ].filter(Boolean);
805
+ for (const baseUrl of controlPlaneUrls) {
806
+ try {
807
+ const url = `${baseUrl.replace(/\/$/, "")}/api/v1/config?projectId=${encodeURIComponent(projectId)}${licenseKey ? `&licenseKey=${encodeURIComponent(licenseKey)}` : ""}`;
808
+ const res = await fetch(url, {
809
+ method: "GET",
810
+ headers: __spreadValues({
811
+ "Content-Type": "application/json"
812
+ }, licenseKey ? { "x-license-key": licenseKey } : {})
813
+ });
814
+ if (res.ok) {
815
+ const data = await res.json();
816
+ if ((data == null ? void 0 : data.success) && ((_a2 = data == null ? void 0 : data.vectorDb) == null ? void 0 : _a2.apiKey)) {
817
+ const config = {
818
+ vectorDb: {
819
+ apiKey: data.vectorDb.apiKey,
820
+ indexName: data.vectorDb.indexName || "retrivora-free",
821
+ provider: data.vectorDb.provider || "pinecone"
822
+ },
823
+ embedding: {
824
+ provider: ((_b = data.embedding) == null ? void 0 : _b.provider) || "universal_rest",
825
+ model: ((_c = data.embedding) == null ? void 0 : _c.model) || "text-embedding-004",
826
+ baseUrl: ((_d = data.embedding) == null ? void 0 : _d.baseUrl) || "https://llm.retrivora.com/api/v1",
827
+ apiKey: ((_e = data.embedding) == null ? void 0 : _e.apiKey) || licenseKey || "",
828
+ profile: ((_f = data.embedding) == null ? void 0 : _f.profile) || "litellm"
829
+ },
830
+ llm: {
831
+ provider: ((_g2 = data.llm) == null ? void 0 : _g2.provider) || "universal_rest",
832
+ model: ((_h = data.llm) == null ? void 0 : _h.model) || "llama-3.1-8b-instant",
833
+ baseUrl: ((_i = data.llm) == null ? void 0 : _i.baseUrl) || "https://llm.retrivora.com/api/v1",
834
+ apiKey: ((_j = data.llm) == null ? void 0 : _j.apiKey) || licenseKey || "",
835
+ profile: ((_k = data.llm) == null ? void 0 : _k.profile) || "litellm"
836
+ }
837
+ };
838
+ this.cache.set(cacheKey, { config, cachedAt: now });
839
+ return config;
840
+ }
841
+ }
842
+ } catch (e) {
843
+ }
844
+ }
845
+ return null;
846
+ }
847
+ /** Convenience: fetch only vector DB config (backwards compat). */
848
+ static async fetchRemoteVectorConfig(projectId, licenseKey) {
849
+ var _a2;
850
+ const config = await this.fetchRemoteConfig(projectId, licenseKey);
851
+ return (_a2 = config == null ? void 0 : config.vectorDb) != null ? _a2 : null;
852
+ }
853
+ };
854
+ ConfigFetcher.cache = /* @__PURE__ */ new Map();
855
+ ConfigFetcher.TTL_MS = 5 * 60 * 1e3;
856
+ }
857
+ });
858
+
781
859
  // src/providers/vectordb/PineconeProvider.ts
782
860
  var PineconeProvider_exports = {};
783
861
  __export(PineconeProvider_exports, {
@@ -789,23 +867,26 @@ var init_PineconeProvider = __esm({
789
867
  "src/providers/vectordb/PineconeProvider.ts"() {
790
868
  "use strict";
791
869
  init_BaseVectorProvider();
870
+ init_ConfigFetcher();
792
871
  PineconeProvider = class extends BaseVectorProvider {
793
872
  constructor(config) {
794
873
  super(config);
795
- const opts = config.options;
796
- if (!opts.apiKey) throw new Error("[PineconeProvider] options.apiKey is required");
797
- this.apiKey = opts.apiKey;
874
+ const opts = config.options || {};
875
+ this.apiKey = opts.apiKey || process.env.PINECONE_API_KEY || "";
798
876
  }
799
877
  static getValidator() {
800
878
  return {
801
879
  validate(config) {
802
880
  const errors = [];
803
881
  const opts = config.options || {};
804
- if (!opts.apiKey) {
882
+ const hasLicenseKey = Boolean(
883
+ config.licenseKey || process.env.RETRIVORA_LICENSE_KEY || process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY
884
+ );
885
+ if (!opts.apiKey && !hasLicenseKey) {
805
886
  errors.push({
806
887
  field: "vectorDb.options.apiKey",
807
- message: "Pinecone API key is required",
808
- suggestion: "Set PINECONE_API_KEY environment variable",
888
+ message: "Pinecone API key is required when RETRIVORA_LICENSE_KEY is not set",
889
+ suggestion: "Set PINECONE_API_KEY environment variable or supply RETRIVORA_LICENSE_KEY for keyless vector storage",
809
890
  severity: "error"
810
891
  });
811
892
  }
@@ -852,22 +933,49 @@ var init_PineconeProvider = __esm({
852
933
  }
853
934
  async initialize() {
854
935
  var _a2, _b;
855
- this.client = new Pinecone({ apiKey: this.apiKey });
856
- const indexes = await this.client.listIndexes();
857
- const names = (_b = (_a2 = indexes.indexes) == null ? void 0 : _a2.map((i) => i.name)) != null ? _b : [];
858
- if (!names.includes(this.indexName)) {
859
- throw new Error(
860
- `[PineconeProvider] Index "${this.indexName}" not found. Available: ${names.join(", ")}`
861
- );
936
+ if (this.client) return;
937
+ let key = this.apiKey || process.env.PINECONE_API_KEY || "";
938
+ if (!key) {
939
+ const projectId = process.env.RAG_PROJECT_ID || process.env.NEXT_PUBLIC_RAG_PROJECT_ID || "my-rag-app";
940
+ const licenseKey = process.env.RETRIVORA_LICENSE_KEY || process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY;
941
+ const remoteConfig = await ConfigFetcher.fetchRemoteVectorConfig(projectId, licenseKey);
942
+ if (remoteConfig == null ? void 0 : remoteConfig.apiKey) {
943
+ key = remoteConfig.apiKey;
944
+ this.apiKey = key;
945
+ if (remoteConfig.indexName) {
946
+ this.indexName = remoteConfig.indexName;
947
+ }
948
+ }
949
+ }
950
+ if (!key) {
951
+ console.warn("[PineconeProvider] Warning: No Pinecone API key available locally or remotely.");
952
+ return;
953
+ }
954
+ this.client = new Pinecone({ apiKey: key });
955
+ try {
956
+ const indexes = await this.client.listIndexes();
957
+ const names = (_b = (_a2 = indexes.indexes) == null ? void 0 : _a2.map((i) => i.name)) != null ? _b : [];
958
+ if (!names.includes(this.indexName)) {
959
+ console.warn(`[PineconeProvider] Target index "${this.indexName}" not listed. Proceeding with configured index name.`);
960
+ }
961
+ } catch (err) {
962
+ console.warn("[PineconeProvider] List index verification warning:", err instanceof Error ? err.message : String(err));
862
963
  }
863
964
  }
864
- index(namespace) {
965
+ async getActiveIndex(namespace) {
966
+ if (!this.client) {
967
+ await this.initialize();
968
+ }
969
+ if (!this.client) {
970
+ throw new Error("[PineconeProvider] Cannot execute vector operation: Pinecone client failed to initialize.");
971
+ }
865
972
  const idx = this.client.index(this.indexName);
866
973
  return namespace ? idx.namespace(namespace) : idx.namespace("");
867
974
  }
868
975
  async upsert(doc, namespace) {
869
976
  var _a2;
870
- await this.index(namespace).upsert({
977
+ const targetIdx = await this.getActiveIndex(namespace);
978
+ await targetIdx.upsert({
871
979
  records: [{
872
980
  id: String(doc.id),
873
981
  values: doc.vector,
@@ -876,6 +984,7 @@ var init_PineconeProvider = __esm({
876
984
  });
877
985
  }
878
986
  async batchUpsert(docs, namespace) {
987
+ const targetIdx = await this.getActiveIndex(namespace);
879
988
  const BATCH = 100;
880
989
  for (let i = 0; i < docs.length; i += BATCH) {
881
990
  const records = docs.slice(i, i + BATCH).map((d) => {
@@ -886,13 +995,14 @@ var init_PineconeProvider = __esm({
886
995
  metadata: __spreadValues({ content: d.content }, (_a2 = d.metadata) != null ? _a2 : {})
887
996
  };
888
997
  });
889
- await this.index(namespace).upsert({ records });
998
+ await targetIdx.upsert({ records });
890
999
  }
891
1000
  }
892
1001
  async query(vector, topK, namespace, filter) {
893
1002
  var _a2;
1003
+ const targetIdx = await this.getActiveIndex(namespace);
894
1004
  const pineconeFilter = this.sanitizeFilter(filter);
895
- const result = await this.index(namespace).query(__spreadValues({
1005
+ const result = await targetIdx.query(__spreadValues({
896
1006
  vector,
897
1007
  topK,
898
1008
  includeMetadata: true
@@ -908,13 +1018,17 @@ var init_PineconeProvider = __esm({
908
1018
  });
909
1019
  }
910
1020
  async delete(id, namespace) {
911
- await this.index(namespace).deleteOne({ id: String(id) });
1021
+ const targetIdx = await this.getActiveIndex(namespace);
1022
+ await targetIdx.deleteOne({ id: String(id) });
912
1023
  }
913
1024
  async deleteNamespace(namespace) {
914
- await this.client.index(this.indexName).namespace(namespace).deleteAll();
1025
+ const targetIdx = await this.getActiveIndex(namespace);
1026
+ await targetIdx.deleteAll();
915
1027
  }
916
1028
  async ping() {
917
1029
  try {
1030
+ if (!this.client) await this.initialize();
1031
+ if (!this.client) return false;
918
1032
  await this.client.listIndexes();
919
1033
  return true;
920
1034
  } catch (e) {
@@ -3045,7 +3159,7 @@ function getRagConfig(baseConfig, env = process.env) {
3045
3159
  return getEnvConfig(env, baseConfig);
3046
3160
  }
3047
3161
  function getEnvConfig(env = process.env, base) {
3048
- 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, _xb, _yb, _zb, _Ab, _Bb, _Cb, _Db, _Eb, _Fb, _Gb, _Hb;
3162
+ 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, _xb, _yb, _zb, _Ab, _Bb, _Cb, _Db, _Eb, _Fb, _Gb, _Hb, _Ib;
3049
3163
  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__";
3050
3164
  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;
3051
3165
  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);
@@ -3053,39 +3167,38 @@ function getEnvConfig(env = process.env, base) {
3053
3167
  const embeddingDimensions = readNumber(env, "EMBEDDING_DIMENSIONS", 768);
3054
3168
  const vectorDbOptions = {};
3055
3169
  if (vectorProvider === "pinecone") {
3056
- const rawApiKey = (_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 : process.env.PINECONE_API_KEY;
3057
- vectorDbOptions.apiKey = rawApiKey || (licenseKey ? "retrivora-keyless-gateway" : "keyless-free-tier");
3058
- vectorDbOptions.indexName = (_s = (_r = (_q = (_n = readString(env, "PINECONE_INDEX")) != null ? _n : (_m = base == null ? void 0 : base.vectorDb) == null ? void 0 : _m.indexName) != null ? _q : (_p = (_o = base == null ? void 0 : base.vectorDb) == null ? void 0 : _o.options) == null ? void 0 : _p.indexName) != null ? _r : process.env.PINECONE_INDEX) != null ? _s : "retrivora-free";
3170
+ vectorDbOptions.apiKey = (_m = (_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 : process.env.PINECONE_API_KEY) != null ? _m : "";
3171
+ vectorDbOptions.indexName = (_t = (_s = (_r = (_o = readString(env, "PINECONE_INDEX")) != null ? _o : (_n = base == null ? void 0 : base.vectorDb) == null ? void 0 : _n.indexName) != null ? _r : (_q = (_p = base == null ? void 0 : base.vectorDb) == null ? void 0 : _p.options) == null ? void 0 : _q.indexName) != null ? _s : process.env.PINECONE_INDEX) != null ? _t : "retrivora-free";
3059
3172
  } else if (vectorProvider === "pgvector" || vectorProvider === "postgresql") {
3060
- vectorDbOptions.connectionString = (_x = (_w = (_t = readString(env, "PGVECTOR_CONNECTION_STRING")) != null ? _t : readString(env, "POSTGRES_URL")) != null ? _w : (_v = (_u = base == null ? void 0 : base.vectorDb) == null ? void 0 : _u.options) == null ? void 0 : _v.connectionString) != null ? _x : "";
3061
- vectorDbOptions.tables = (_C = (_z = (_y = readString(env, "VECTOR_DB_TABLES")) != null ? _y : readString(env, "POSTGRES_TABLES")) == null ? void 0 : _z.split(",").map((t) => t.trim())) != null ? _C : (_B = (_A = base == null ? void 0 : base.vectorDb) == null ? void 0 : _A.options) == null ? void 0 : _B.tables;
3062
- vectorDbOptions.searchFields = (_G = (_D = readString(env, "POSTGRES_SEARCH_FIELDS")) == null ? void 0 : _D.split(",").map((f) => f.trim())) != null ? _G : (_F = (_E = base == null ? void 0 : base.vectorDb) == null ? void 0 : _E.options) == null ? void 0 : _F.searchFields;
3173
+ vectorDbOptions.connectionString = (_y = (_x = (_u = readString(env, "PGVECTOR_CONNECTION_STRING")) != null ? _u : readString(env, "POSTGRES_URL")) != null ? _x : (_w = (_v = base == null ? void 0 : base.vectorDb) == null ? void 0 : _v.options) == null ? void 0 : _w.connectionString) != null ? _y : "";
3174
+ vectorDbOptions.tables = (_D = (_A = (_z = readString(env, "VECTOR_DB_TABLES")) != null ? _z : readString(env, "POSTGRES_TABLES")) == null ? void 0 : _A.split(",").map((t) => t.trim())) != null ? _D : (_C = (_B = base == null ? void 0 : base.vectorDb) == null ? void 0 : _B.options) == null ? void 0 : _C.tables;
3175
+ vectorDbOptions.searchFields = (_H = (_E = readString(env, "POSTGRES_SEARCH_FIELDS")) == null ? void 0 : _E.split(",").map((f) => f.trim())) != null ? _H : (_G = (_F = base == null ? void 0 : base.vectorDb) == null ? void 0 : _F.options) == null ? void 0 : _G.searchFields;
3063
3176
  vectorDbOptions.dimensions = embeddingDimensions;
3064
3177
  } else if (vectorProvider === "mongodb") {
3065
- vectorDbOptions.uri = (_K = (_J = readString(env, "MONGODB_URI")) != null ? _J : (_I = (_H = base == null ? void 0 : base.vectorDb) == null ? void 0 : _H.options) == null ? void 0 : _I.uri) != null ? _K : "";
3066
- vectorDbOptions.database = (_O = (_N = readString(env, "MONGODB_DB")) != null ? _N : (_M = (_L = base == null ? void 0 : base.vectorDb) == null ? void 0 : _L.options) == null ? void 0 : _M.database) != null ? _O : "";
3067
- vectorDbOptions.collection = (_S = (_R = readString(env, "MONGODB_COLLECTION")) != null ? _R : (_Q = (_P = base == null ? void 0 : base.vectorDb) == null ? void 0 : _P.options) == null ? void 0 : _Q.collection) != null ? _S : "";
3068
- vectorDbOptions.indexName = (_Y = (_X = (_U = readString(env, "MONGODB_INDEX_NAME")) != null ? _U : (_T = base == null ? void 0 : base.vectorDb) == null ? void 0 : _T.indexName) != null ? _X : (_W = (_V = base == null ? void 0 : base.vectorDb) == null ? void 0 : _V.options) == null ? void 0 : _W.indexName) != null ? _Y : "vector_index";
3178
+ vectorDbOptions.uri = (_L = (_K = readString(env, "MONGODB_URI")) != null ? _K : (_J = (_I = base == null ? void 0 : base.vectorDb) == null ? void 0 : _I.options) == null ? void 0 : _J.uri) != null ? _L : "";
3179
+ vectorDbOptions.database = (_P = (_O = readString(env, "MONGODB_DB")) != null ? _O : (_N = (_M = base == null ? void 0 : base.vectorDb) == null ? void 0 : _M.options) == null ? void 0 : _N.database) != null ? _P : "";
3180
+ vectorDbOptions.collection = (_T = (_S = readString(env, "MONGODB_COLLECTION")) != null ? _S : (_R = (_Q = base == null ? void 0 : base.vectorDb) == null ? void 0 : _Q.options) == null ? void 0 : _R.collection) != null ? _T : "";
3181
+ vectorDbOptions.indexName = (_Z = (_Y = (_V = readString(env, "MONGODB_INDEX_NAME")) != null ? _V : (_U = base == null ? void 0 : base.vectorDb) == null ? void 0 : _U.indexName) != null ? _Y : (_X = (_W = base == null ? void 0 : base.vectorDb) == null ? void 0 : _W.options) == null ? void 0 : _X.indexName) != null ? _Z : "vector_index";
3069
3182
  } else if (vectorProvider === "qdrant") {
3070
- vectorDbOptions.baseUrl = (_aa = (_$ = readString(env, "QDRANT_URL")) != null ? _$ : (__ = (_Z = base == null ? void 0 : base.vectorDb) == null ? void 0 : _Z.options) == null ? void 0 : __.baseUrl) != null ? _aa : "http://localhost:6333";
3071
- vectorDbOptions.apiKey = (_da = readString(env, "QDRANT_API_KEY")) != null ? _da : (_ca = (_ba = base == null ? void 0 : base.vectorDb) == null ? void 0 : _ba.options) == null ? void 0 : _ca.apiKey;
3183
+ vectorDbOptions.baseUrl = (_ba = (_aa = readString(env, "QDRANT_URL")) != null ? _aa : (_$ = (__ = base == null ? void 0 : base.vectorDb) == null ? void 0 : __.options) == null ? void 0 : _$.baseUrl) != null ? _ba : "http://localhost:6333";
3184
+ vectorDbOptions.apiKey = (_ea = readString(env, "QDRANT_API_KEY")) != null ? _ea : (_da = (_ca = base == null ? void 0 : base.vectorDb) == null ? void 0 : _ca.options) == null ? void 0 : _da.apiKey;
3072
3185
  vectorDbOptions.dimensions = embeddingDimensions;
3073
3186
  } else if (vectorProvider === "milvus") {
3074
- vectorDbOptions.baseUrl = (_ea = readString(env, "MILVUS_URL")) != null ? _ea : "http://localhost:19530";
3187
+ vectorDbOptions.baseUrl = (_fa = readString(env, "MILVUS_URL")) != null ? _fa : "http://localhost:19530";
3075
3188
  vectorDbOptions.apiKey = readString(env, "MILVUS_API_KEY");
3076
3189
  } else if (vectorProvider === "chromadb") {
3077
- vectorDbOptions.baseUrl = (_fa = readString(env, "CHROMADB_URL")) != null ? _fa : "http://localhost:8000";
3190
+ vectorDbOptions.baseUrl = (_ga = readString(env, "CHROMADB_URL")) != null ? _ga : "http://localhost:8000";
3078
3191
  } else if (vectorProvider === "weaviate") {
3079
- vectorDbOptions.baseUrl = (_ga = readString(env, "WEAVIATE_URL")) != null ? _ga : "http://localhost:8080";
3192
+ vectorDbOptions.baseUrl = (_ha = readString(env, "WEAVIATE_URL")) != null ? _ha : "http://localhost:8080";
3080
3193
  vectorDbOptions.apiKey = readString(env, "WEAVIATE_API_KEY");
3081
3194
  } else if (vectorProvider === "redis") {
3082
- vectorDbOptions.baseUrl = (_ha = readString(env, "REDIS_URL")) != null ? _ha : "";
3195
+ vectorDbOptions.baseUrl = (_ia = readString(env, "REDIS_URL")) != null ? _ia : "";
3083
3196
  vectorDbOptions.apiKey = readString(env, "REDIS_API_KEY");
3084
3197
  } else if (vectorProvider === "rest") {
3085
- vectorDbOptions.baseUrl = (_ia = readString(env, "VECTOR_DB_REST_URL")) != null ? _ia : "";
3198
+ vectorDbOptions.baseUrl = (_ja = readString(env, "VECTOR_DB_REST_URL")) != null ? _ja : "";
3086
3199
  vectorDbOptions.headers = readString(env, "VECTOR_DB_REST_API_KEY") ? { "api-key": readString(env, "VECTOR_DB_REST_API_KEY") } : {};
3087
3200
  } else if (vectorProvider === "universal_rest") {
3088
- vectorDbOptions.baseUrl = (_ka = (_ja = readString(env, "VECTOR_BASE_URL")) != null ? _ja : readString(env, "VECTOR_DB_REST_URL")) != null ? _ka : "";
3201
+ vectorDbOptions.baseUrl = (_la = (_ka = readString(env, "VECTOR_BASE_URL")) != null ? _ka : readString(env, "VECTOR_DB_REST_URL")) != null ? _la : "";
3089
3202
  vectorDbOptions.profile = readString(env, "VECTOR_UNIVERSAL_PROFILE");
3090
3203
  vectorDbOptions.headers = readString(env, "VECTOR_DB_REST_API_KEY") ? { Authorization: `Bearer ${readString(env, "VECTOR_DB_REST_API_KEY")}` } : {};
3091
3204
  }
@@ -3104,8 +3217,8 @@ function getEnvConfig(env = process.env, base) {
3104
3217
  // Anthropic needs a separate embedding provider; key kept for completeness
3105
3218
  gemini: readString(env, "GEMINI_API_KEY"),
3106
3219
  ollama: void 0,
3107
- universal_rest: (_la = readString(env, "EMBEDDING_API_KEY")) != null ? _la : readString(env, "OPENAI_API_KEY"),
3108
- custom: (_ma = readString(env, "EMBEDDING_API_KEY")) != null ? _ma : readString(env, "OPENAI_API_KEY")
3220
+ universal_rest: (_ma = readString(env, "EMBEDDING_API_KEY")) != null ? _ma : readString(env, "OPENAI_API_KEY"),
3221
+ custom: (_na = readString(env, "EMBEDDING_API_KEY")) != null ? _na : readString(env, "OPENAI_API_KEY")
3109
3222
  };
3110
3223
  const DEFAULT_MODEL_BY_PROVIDER = {
3111
3224
  openai: "gpt-4o",
@@ -3126,25 +3239,25 @@ function getEnvConfig(env = process.env, base) {
3126
3239
  return true;
3127
3240
  }
3128
3241
  })();
3129
- const defaultGatewayUrl = (_oa = (_na = readString(env, "LITELLM_BASE_URL")) != null ? _na : readString(env, "LLM_BASE_URL")) != null ? _oa : "https://llm.retrivora.com/api/v1";
3242
+ const defaultGatewayUrl = (_pa = (_oa = readString(env, "LITELLM_BASE_URL")) != null ? _oa : readString(env, "LLM_BASE_URL")) != null ? _pa : "https://retrivora.com/api/v1";
3130
3243
  const defaultLlmProvider = isFreeTier ? "universal_rest" : "universal_rest";
3131
- const llmProvider = (_ra = (_qa = readEnum(env, "LLM_PROVIDER", defaultLlmProvider, LLM_PROVIDERS)) != null ? _qa : (_pa = base == null ? void 0 : base.llm) == null ? void 0 : _pa.provider) != null ? _ra : defaultLlmProvider;
3132
- const llmBaseUrl = (_va = (_ua = (_sa = readString(env, "LITELLM_BASE_URL")) != null ? _sa : readString(env, "LLM_BASE_URL")) != null ? _ua : (_ta = base == null ? void 0 : base.llm) == null ? void 0 : _ta.baseUrl) != null ? _va : defaultGatewayUrl;
3133
- const llmModel = (_za = (_xa = readString(env, "LLM_MODEL")) != null ? _xa : (_wa = base == null ? void 0 : base.llm) == null ? void 0 : _wa.model) != null ? _za : isFreeTier ? "llama-3.1-8b-instant" : (_ya = DEFAULT_MODEL_BY_PROVIDER[llmProvider]) != null ? _ya : "gpt-4o";
3134
- const llmApiKey = (_Fa = (_Ea = (_Ca = (_Ba = (_Aa = llmApiKeyByProvider[llmProvider]) != null ? _Aa : readString(env, "LLM_API_KEY")) != null ? _Ba : readString(env, "LITELLM_MASTER_KEY")) != null ? _Ca : readString(env, "LITELLM_API_KEY")) != null ? _Ea : (_Da = base == null ? void 0 : base.llm) == null ? void 0 : _Da.apiKey) != null ? _Fa : licenseKey;
3135
- const llmProfile = (_Ja = (_Ia = readString(env, "LLM_UNIVERSAL_PROFILE")) != null ? _Ia : (_Ha = (_Ga = base == null ? void 0 : base.llm) == null ? void 0 : _Ga.options) == null ? void 0 : _Ha.profile) != null ? _Ja : "litellm";
3244
+ const llmProvider = (_sa = (_ra = readEnum(env, "LLM_PROVIDER", defaultLlmProvider, LLM_PROVIDERS)) != null ? _ra : (_qa = base == null ? void 0 : base.llm) == null ? void 0 : _qa.provider) != null ? _sa : defaultLlmProvider;
3245
+ const llmBaseUrl = (_wa = (_va = (_ta = readString(env, "LITELLM_BASE_URL")) != null ? _ta : readString(env, "LLM_BASE_URL")) != null ? _va : (_ua = base == null ? void 0 : base.llm) == null ? void 0 : _ua.baseUrl) != null ? _wa : defaultGatewayUrl;
3246
+ const llmModel = (_Aa = (_ya = readString(env, "LLM_MODEL")) != null ? _ya : (_xa = base == null ? void 0 : base.llm) == null ? void 0 : _xa.model) != null ? _Aa : isFreeTier ? "llama-3.1-8b-instant" : (_za = DEFAULT_MODEL_BY_PROVIDER[llmProvider]) != null ? _za : "gpt-4o";
3247
+ const llmApiKey = (_Ga = (_Fa = (_Da = (_Ca = (_Ba = llmApiKeyByProvider[llmProvider]) != null ? _Ba : readString(env, "LLM_API_KEY")) != null ? _Ca : readString(env, "LITELLM_MASTER_KEY")) != null ? _Da : readString(env, "LITELLM_API_KEY")) != null ? _Fa : (_Ea = base == null ? void 0 : base.llm) == null ? void 0 : _Ea.apiKey) != null ? _Ga : licenseKey;
3248
+ const llmProfile = (_Ka = (_Ja = readString(env, "LLM_UNIVERSAL_PROFILE")) != null ? _Ja : (_Ia = (_Ha = base == null ? void 0 : base.llm) == null ? void 0 : _Ha.options) == null ? void 0 : _Ia.profile) != null ? _Ka : "litellm";
3136
3249
  const defaultEmbeddingProvider = isFreeTier ? "universal_rest" : "universal_rest";
3137
- const embeddingProvider = (_Ma = (_La = readEnum(env, "EMBEDDING_PROVIDER", defaultEmbeddingProvider, EMBEDDING_PROVIDERS)) != null ? _La : (_Ka = base == null ? void 0 : base.embedding) == null ? void 0 : _Ka.provider) != null ? _Ma : defaultEmbeddingProvider;
3138
- const embeddingBaseUrl = (_Ra = (_Qa = (_Oa = (_Na = readString(env, "LITELLM_BASE_URL")) != null ? _Na : readString(env, "EMBEDDING_BASE_URL")) != null ? _Oa : readString(env, "LLM_BASE_URL")) != null ? _Qa : (_Pa = base == null ? void 0 : base.embedding) == null ? void 0 : _Pa.baseUrl) != null ? _Ra : defaultGatewayUrl;
3139
- const embeddingModel = (_Ua = (_Ta = readString(env, "EMBEDDING_MODEL")) != null ? _Ta : (_Sa = base == null ? void 0 : base.embedding) == null ? void 0 : _Sa.model) != null ? _Ua : "text-embedding-004";
3140
- const embeddingApiKey = (_$a = (__a = (_Ya = (_Xa = (_Wa = (_Va = embeddingApiKeyByProvider[embeddingProvider]) != null ? _Va : readString(env, "EMBEDDING_API_KEY")) != null ? _Wa : readString(env, "LLM_API_KEY")) != null ? _Xa : readString(env, "LITELLM_MASTER_KEY")) != null ? _Ya : readString(env, "LITELLM_API_KEY")) != null ? __a : (_Za = base == null ? void 0 : base.embedding) == null ? void 0 : _Za.apiKey) != null ? _$a : licenseKey;
3141
- const embeddingProfile = (_db = (_cb = readString(env, "EMBEDDING_UNIVERSAL_PROFILE")) != null ? _cb : (_bb = (_ab = base == null ? void 0 : base.embedding) == null ? void 0 : _ab.options) == null ? void 0 : _bb.profile) != null ? _db : "litellm";
3250
+ const embeddingProvider = (_Na = (_Ma = readEnum(env, "EMBEDDING_PROVIDER", defaultEmbeddingProvider, EMBEDDING_PROVIDERS)) != null ? _Ma : (_La = base == null ? void 0 : base.embedding) == null ? void 0 : _La.provider) != null ? _Na : defaultEmbeddingProvider;
3251
+ const embeddingBaseUrl = (_Sa = (_Ra = (_Pa = (_Oa = readString(env, "LITELLM_BASE_URL")) != null ? _Oa : readString(env, "EMBEDDING_BASE_URL")) != null ? _Pa : readString(env, "LLM_BASE_URL")) != null ? _Ra : (_Qa = base == null ? void 0 : base.embedding) == null ? void 0 : _Qa.baseUrl) != null ? _Sa : defaultGatewayUrl;
3252
+ const embeddingModel = (_Va = (_Ua = readString(env, "EMBEDDING_MODEL")) != null ? _Ua : (_Ta = base == null ? void 0 : base.embedding) == null ? void 0 : _Ta.model) != null ? _Va : "text-embedding-004";
3253
+ const embeddingApiKey = (_ab = (_$a = (_Za = (_Ya = (_Xa = (_Wa = embeddingApiKeyByProvider[embeddingProvider]) != null ? _Wa : readString(env, "EMBEDDING_API_KEY")) != null ? _Xa : readString(env, "LLM_API_KEY")) != null ? _Ya : readString(env, "LITELLM_MASTER_KEY")) != null ? _Za : readString(env, "LITELLM_API_KEY")) != null ? _$a : (__a = base == null ? void 0 : base.embedding) == null ? void 0 : __a.apiKey) != null ? _ab : licenseKey;
3254
+ const embeddingProfile = (_eb = (_db = readString(env, "EMBEDDING_UNIVERSAL_PROFILE")) != null ? _db : (_cb = (_bb = base == null ? void 0 : base.embedding) == null ? void 0 : _bb.options) == null ? void 0 : _cb.profile) != null ? _eb : "litellm";
3142
3255
  return __spreadProps(__spreadValues({
3143
3256
  projectId,
3144
3257
  licenseKey,
3145
3258
  vectorDb: {
3146
3259
  provider: vectorProvider,
3147
- indexName: (_fb = (_eb = readString(env, "VECTOR_DB_INDEX")) != null ? _eb : vectorDbOptions.indexName) != null ? _fb : "rag-index",
3260
+ indexName: (_gb = (_fb = readString(env, "VECTOR_DB_INDEX")) != null ? _fb : vectorDbOptions.indexName) != null ? _gb : "rag-index",
3148
3261
  options: vectorDbOptions
3149
3262
  },
3150
3263
  llm: {
@@ -3174,30 +3287,30 @@ function getEnvConfig(env = process.env, base) {
3174
3287
  }
3175
3288
  },
3176
3289
  ui: {
3177
- title: (_hb = (_gb = readString(env, "NEXT_PUBLIC_UI_TITLE")) != null ? _gb : readString(env, "UI_TITLE")) != null ? _hb : "AI Assistant",
3178
- subtitle: (_jb = (_ib = readString(env, "NEXT_PUBLIC_UI_SUBTITLE")) != null ? _ib : readString(env, "UI_SUBTITLE")) != null ? _jb : "Powered by RAG",
3179
- primaryColor: (_lb = (_kb = readString(env, "NEXT_PUBLIC_PRIMARY_COLOR")) != null ? _kb : readString(env, "UI_PRIMARY_COLOR")) != null ? _lb : "#10b981",
3180
- accentColor: (_nb = (_mb = readString(env, "NEXT_PUBLIC_ACCENT_COLOR")) != null ? _mb : readString(env, "UI_ACCENT_COLOR")) != null ? _nb : "#3b82f6",
3181
- logoUrl: (_ob = readString(env, "NEXT_PUBLIC_LOGO_URL")) != null ? _ob : readString(env, "UI_LOGO_URL"),
3182
- placeholder: (_qb = (_pb = readString(env, "NEXT_PUBLIC_PLACEHOLDER")) != null ? _pb : readString(env, "UI_PLACEHOLDER")) != null ? _qb : "Ask me anything\u2026",
3183
- showSources: ((_sb = (_rb = readString(env, "NEXT_PUBLIC_SHOW_SOURCES")) != null ? _rb : readString(env, "UI_SHOW_SOURCES")) != null ? _sb : "true") !== "false",
3184
- welcomeMessage: (_ub = (_tb = readString(env, "NEXT_PUBLIC_WELCOME_MESSAGE")) != null ? _tb : readString(env, "UI_WELCOME_MESSAGE")) != null ? _ub : "Hello! I'm your AI assistant. Ask me anything about your documents.",
3185
- visualStyle: (_wb = (_vb = readString(env, "NEXT_PUBLIC_UI_VISUAL_STYLE")) != null ? _vb : readString(env, "UI_VISUAL_STYLE")) != null ? _wb : "glass",
3186
- borderRadius: (_yb = (_xb = readString(env, "NEXT_PUBLIC_UI_BORDER_RADIUS")) != null ? _xb : readString(env, "UI_BORDER_RADIUS")) != null ? _yb : "xl",
3187
- allowUpload: ((_Ab = (_zb = readString(env, "NEXT_PUBLIC_ALLOW_UPLOAD")) != null ? _zb : readString(env, "UI_ALLOW_UPLOAD")) != null ? _Ab : "false") === "true"
3290
+ title: (_ib = (_hb = readString(env, "NEXT_PUBLIC_UI_TITLE")) != null ? _hb : readString(env, "UI_TITLE")) != null ? _ib : "AI Assistant",
3291
+ subtitle: (_kb = (_jb = readString(env, "NEXT_PUBLIC_UI_SUBTITLE")) != null ? _jb : readString(env, "UI_SUBTITLE")) != null ? _kb : "Powered by RAG",
3292
+ primaryColor: (_mb = (_lb = readString(env, "NEXT_PUBLIC_PRIMARY_COLOR")) != null ? _lb : readString(env, "UI_PRIMARY_COLOR")) != null ? _mb : "#10b981",
3293
+ accentColor: (_ob = (_nb = readString(env, "NEXT_PUBLIC_ACCENT_COLOR")) != null ? _nb : readString(env, "UI_ACCENT_COLOR")) != null ? _ob : "#3b82f6",
3294
+ logoUrl: (_pb = readString(env, "NEXT_PUBLIC_LOGO_URL")) != null ? _pb : readString(env, "UI_LOGO_URL"),
3295
+ placeholder: (_rb = (_qb = readString(env, "NEXT_PUBLIC_PLACEHOLDER")) != null ? _qb : readString(env, "UI_PLACEHOLDER")) != null ? _rb : "Ask me anything\u2026",
3296
+ showSources: ((_tb = (_sb = readString(env, "NEXT_PUBLIC_SHOW_SOURCES")) != null ? _sb : readString(env, "UI_SHOW_SOURCES")) != null ? _tb : "true") !== "false",
3297
+ welcomeMessage: (_vb = (_ub = readString(env, "NEXT_PUBLIC_WELCOME_MESSAGE")) != null ? _ub : readString(env, "UI_WELCOME_MESSAGE")) != null ? _vb : "Hello! I'm your AI assistant. Ask me anything about your documents.",
3298
+ visualStyle: (_xb = (_wb = readString(env, "NEXT_PUBLIC_UI_VISUAL_STYLE")) != null ? _wb : readString(env, "UI_VISUAL_STYLE")) != null ? _xb : "glass",
3299
+ borderRadius: (_zb = (_yb = readString(env, "NEXT_PUBLIC_UI_BORDER_RADIUS")) != null ? _yb : readString(env, "UI_BORDER_RADIUS")) != null ? _zb : "xl",
3300
+ allowUpload: ((_Bb = (_Ab = readString(env, "NEXT_PUBLIC_ALLOW_UPLOAD")) != null ? _Ab : readString(env, "UI_ALLOW_UPLOAD")) != null ? _Bb : "false") === "true"
3188
3301
  },
3189
3302
  rag: {
3190
3303
  topK: readNumber(env, "RAG_TOP_K", 5),
3191
3304
  scoreThreshold: readNumber(env, "RAG_SCORE_THRESHOLD", 0),
3192
3305
  chunkSize: readNumber(env, "RAG_CHUNK_SIZE", 1e3),
3193
3306
  chunkOverlap: readNumber(env, "RAG_CHUNK_OVERLAP", 200),
3194
- filterableFields: (_Bb = readString(env, "RAG_FILTERABLE_FIELDS")) == null ? void 0 : _Bb.split(",").map((f) => f.trim()),
3307
+ filterableFields: (_Cb = readString(env, "RAG_FILTERABLE_FIELDS")) == null ? void 0 : _Cb.split(",").map((f) => f.trim()),
3195
3308
  // Query pipeline toggles — read from .env.local
3196
3309
  useQueryTransformation: readString(env, "RAG_USE_QUERY_TRANSFORMATION") === "true",
3197
3310
  useReranking: readString(env, "RAG_USE_RERANKING") === "true",
3198
3311
  useGraphRetrieval: readString(env, "RAG_USE_GRAPH_RETRIEVAL") === "true",
3199
- architecture: (_Cb = readString(env, "RAG_ARCHITECTURE")) != null ? _Cb : "simple",
3200
- chunkingStrategy: (_Db = readString(env, "RAG_CHUNKING_STRATEGY")) != null ? _Db : "recursive",
3312
+ architecture: (_Db = readString(env, "RAG_ARCHITECTURE")) != null ? _Db : "simple",
3313
+ chunkingStrategy: (_Eb = readString(env, "RAG_CHUNKING_STRATEGY")) != null ? _Eb : "recursive",
3201
3314
  uiMapping: (() => {
3202
3315
  const raw = readString(env, "RAG_UI_MAPPING");
3203
3316
  if (!raw) return void 0;
@@ -3210,7 +3323,7 @@ function getEnvConfig(env = process.env, base) {
3210
3323
  },
3211
3324
  telemetry: {
3212
3325
  enabled: telemetryEnabled,
3213
- url: (_Hb = (_Gb = (_Eb = readString(env, "TELEMETRY_URL")) != null ? _Eb : readString(env, "NEXT_PUBLIC_TELEMETRY_URL")) != null ? _Gb : (_Fb = base == null ? void 0 : base.telemetry) == null ? void 0 : _Fb.url) != null ? _Hb : process.env.NODE_ENV === "development" ? "http://localhost:3001/api/telemetry" : "https://retrivora.com/api/telemetry"
3326
+ url: (_Ib = (_Hb = (_Fb = readString(env, "TELEMETRY_URL")) != null ? _Fb : readString(env, "NEXT_PUBLIC_TELEMETRY_URL")) != null ? _Hb : (_Gb = base == null ? void 0 : base.telemetry) == null ? void 0 : _Gb.url) != null ? _Ib : process.env.NODE_ENV === "development" ? "http://localhost:3001/api/telemetry" : "https://retrivora.com/api/telemetry"
3214
3327
  }
3215
3328
  }, readString(env, "GRAPH_DB_PROVIDER") ? {
3216
3329
  graphDb: {
@@ -5252,7 +5365,7 @@ var ConfigValidator = class {
5252
5365
  // package.json
5253
5366
  var package_default = {
5254
5367
  name: "@retrivora-ai/rag-engine",
5255
- version: "2.1.7",
5368
+ version: "2.1.9",
5256
5369
  description: "Retrivora AI is a plug-and-play AI engine for RAG chat experiences \u2014 generic vector DB + LLM provider, embeddable or standalone.",
5257
5370
  author: "Abhinav Alkuchi",
5258
5371
  license: "UNLICENSED",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@retrivora-ai/rag-engine",
3
- "version": "2.1.7",
3
+ "version": "2.2.0",
4
4
  "description": "Retrivora AI is a plug-and-play AI engine for RAG chat experiences — generic vector DB + LLM provider, embeddable or standalone.",
5
5
  "author": "Abhinav Alkuchi",
6
6
  "license": "UNLICENSED",
@@ -85,8 +85,7 @@ export function getEnvConfig(env: Record<string, string | undefined> = process.e
85
85
  const vectorDbOptions: Record<string, unknown> = {};
86
86
 
87
87
  if (vectorProvider === 'pinecone') {
88
- const rawApiKey = readString(env, 'PINECONE_API_KEY') ?? (base?.vectorDb?.options?.apiKey as string) ?? process.env.PINECONE_API_KEY;
89
- vectorDbOptions.apiKey = rawApiKey || (licenseKey ? 'retrivora-keyless-gateway' : 'keyless-free-tier');
88
+ vectorDbOptions.apiKey = readString(env, 'PINECONE_API_KEY') ?? (base?.vectorDb?.options?.apiKey as string) ?? process.env.PINECONE_API_KEY ?? '';
90
89
  vectorDbOptions.indexName = readString(env, 'PINECONE_INDEX') ?? (base?.vectorDb?.indexName as string) ?? (base?.vectorDb?.options?.indexName as string) ?? process.env.PINECONE_INDEX ?? 'retrivora-free';
91
90
  } else if (vectorProvider === 'pgvector' || vectorProvider === 'postgresql') {
92
91
  vectorDbOptions.connectionString = readString(env, 'PGVECTOR_CONNECTION_STRING') ?? readString(env, 'POSTGRES_URL') ?? (base?.vectorDb?.options?.connectionString as string) ?? '';
@@ -172,7 +171,10 @@ export function getEnvConfig(env: Record<string, string | undefined> = process.e
172
171
  }
173
172
  })();
174
173
 
175
- const defaultGatewayUrl = readString(env, 'LITELLM_BASE_URL') ?? readString(env, 'LLM_BASE_URL') ?? 'https://llm.retrivora.com/api/v1';
174
+ // Default gateway: retrivora.com/api/v1 acts as a secure proxy that validates the license key
175
+ // and forwards to llm.retrivora.com with LITELLM_MASTER_KEY (which end-users never need to know).
176
+ // Developers who self-host can override with LITELLM_BASE_URL.
177
+ const defaultGatewayUrl = readString(env, 'LITELLM_BASE_URL') ?? readString(env, 'LLM_BASE_URL') ?? 'https://retrivora.com/api/v1';
176
178
 
177
179
  const defaultLlmProvider = isFreeTier ? 'universal_rest' : 'universal_rest';
178
180
  const llmProvider = (readEnum(env, 'LLM_PROVIDER', defaultLlmProvider, LLM_PROVIDERS) ?? base?.llm?.provider ?? defaultLlmProvider) as LLMProvider;
@@ -0,0 +1,112 @@
1
+ /**
2
+ * ConfigFetcher.ts — Dynamically fetches project credentials from Retrivora Control Plane
3
+ * without hardcoding plain-text master keys in NPM package binaries.
4
+ */
5
+
6
+ export interface RemoteVectorConfig {
7
+ apiKey: string;
8
+ indexName: string;
9
+ provider: string;
10
+ }
11
+
12
+ export interface RemoteEmbeddingConfig {
13
+ provider: string;
14
+ model: string;
15
+ baseUrl: string;
16
+ apiKey: string;
17
+ profile?: string;
18
+ }
19
+
20
+ export interface RemoteLLMConfig {
21
+ provider: string;
22
+ model: string;
23
+ baseUrl: string;
24
+ apiKey: string;
25
+ profile?: string;
26
+ }
27
+
28
+ export interface RemoteConfig {
29
+ vectorDb: RemoteVectorConfig;
30
+ embedding: RemoteEmbeddingConfig;
31
+ llm: RemoteLLMConfig;
32
+ }
33
+
34
+ // Legacy alias
35
+ export type { RemoteVectorConfig as RemoteConfig_ };
36
+
37
+ export class ConfigFetcher {
38
+ private static cache = new Map<string, { config: RemoteConfig; cachedAt: number }>();
39
+ private static readonly TTL_MS = 5 * 60 * 1000; // 5-minute in-memory session cache
40
+
41
+ /**
42
+ * Fetch full project configuration (vectorDb + embedding + llm) from Retrivora Control Plane.
43
+ */
44
+ static async fetchRemoteConfig(projectId: string, licenseKey?: string): Promise<RemoteConfig | null> {
45
+ const cacheKey = `${projectId}:${licenseKey || ''}`;
46
+ const now = Date.now();
47
+ const cached = this.cache.get(cacheKey);
48
+
49
+ if (cached && now - cached.cachedAt < this.TTL_MS) {
50
+ return cached.config;
51
+ }
52
+
53
+ const controlPlaneUrls = [
54
+ process.env.RETRIVORA_CONTROL_PLANE_URL,
55
+ process.env.NEXT_PUBLIC_RETRIVORA_CONTROL_PLANE_URL,
56
+ 'https://retrivora.com',
57
+ 'http://localhost:3000',
58
+ ].filter(Boolean) as string[];
59
+
60
+ for (const baseUrl of controlPlaneUrls) {
61
+ try {
62
+ const url = `${baseUrl.replace(/\/$/, '')}/api/v1/config?projectId=${encodeURIComponent(projectId)}${licenseKey ? `&licenseKey=${encodeURIComponent(licenseKey)}` : ''}`;
63
+ const res = await fetch(url, {
64
+ method: 'GET',
65
+ headers: {
66
+ 'Content-Type': 'application/json',
67
+ ...(licenseKey ? { 'x-license-key': licenseKey } : {}),
68
+ },
69
+ });
70
+
71
+ if (res.ok) {
72
+ const data = await res.json();
73
+ if (data?.success && data?.vectorDb?.apiKey) {
74
+ const config: RemoteConfig = {
75
+ vectorDb: {
76
+ apiKey: data.vectorDb.apiKey,
77
+ indexName: data.vectorDb.indexName || 'retrivora-free',
78
+ provider: data.vectorDb.provider || 'pinecone',
79
+ },
80
+ embedding: {
81
+ provider: data.embedding?.provider || 'universal_rest',
82
+ model: data.embedding?.model || 'text-embedding-004',
83
+ baseUrl: data.embedding?.baseUrl || 'https://llm.retrivora.com/api/v1',
84
+ apiKey: data.embedding?.apiKey || licenseKey || '',
85
+ profile: data.embedding?.profile || 'litellm',
86
+ },
87
+ llm: {
88
+ provider: data.llm?.provider || 'universal_rest',
89
+ model: data.llm?.model || 'llama-3.1-8b-instant',
90
+ baseUrl: data.llm?.baseUrl || 'https://llm.retrivora.com/api/v1',
91
+ apiKey: data.llm?.apiKey || licenseKey || '',
92
+ profile: data.llm?.profile || 'litellm',
93
+ },
94
+ };
95
+ this.cache.set(cacheKey, { config, cachedAt: now });
96
+ return config;
97
+ }
98
+ }
99
+ } catch {
100
+ /* Try next fallback URL */
101
+ }
102
+ }
103
+
104
+ return null;
105
+ }
106
+
107
+ /** Convenience: fetch only vector DB config (backwards compat). */
108
+ static async fetchRemoteVectorConfig(projectId: string, licenseKey?: string): Promise<RemoteVectorConfig | null> {
109
+ const config = await this.fetchRemoteConfig(projectId, licenseKey);
110
+ return config?.vectorDb ?? null;
111
+ }
112
+ }
@@ -8,7 +8,7 @@ import { IProviderValidator, IProviderHealthChecker } from '../../core/ProviderI
8
8
  */
9
9
  export abstract class BaseVectorProvider {
10
10
  protected readonly config: VectorDBConfig;
11
- protected readonly indexName: string;
11
+ protected indexName: string;
12
12
 
13
13
  constructor(config: VectorDBConfig) {
14
14
  this.config = config;