@retrivora-ai/rag-engine 2.1.9 → 2.2.1

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.
@@ -793,6 +793,86 @@ var init_BaseVectorProvider = __esm({
793
793
  }
794
794
  });
795
795
 
796
+ // src/core/ConfigFetcher.ts
797
+ var ConfigFetcher;
798
+ var init_ConfigFetcher = __esm({
799
+ "src/core/ConfigFetcher.ts"() {
800
+ "use strict";
801
+ ConfigFetcher = class {
802
+ // 5-minute in-memory session cache
803
+ /**
804
+ * Fetch full project configuration (vectorDb + embedding + llm) from Retrivora Control Plane.
805
+ */
806
+ static async fetchRemoteConfig(projectId, licenseKey) {
807
+ var _a2, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
808
+ const cacheKey = `${projectId}:${licenseKey || ""}`;
809
+ const now = Date.now();
810
+ const cached = this.cache.get(cacheKey);
811
+ if (cached && now - cached.cachedAt < this.TTL_MS) {
812
+ return cached.config;
813
+ }
814
+ const controlPlaneUrls = [
815
+ process.env.RETRIVORA_CONTROL_PLANE_URL,
816
+ process.env.NEXT_PUBLIC_RETRIVORA_CONTROL_PLANE_URL,
817
+ "https://www.retrivora.com",
818
+ "https://retrivora.com",
819
+ "http://localhost:3001",
820
+ "http://localhost:3000"
821
+ ].filter(Boolean);
822
+ for (const baseUrl of controlPlaneUrls) {
823
+ try {
824
+ const url = `${baseUrl.replace(/\/$/, "")}/api/v1/config?projectId=${encodeURIComponent(projectId)}${licenseKey ? `&licenseKey=${encodeURIComponent(licenseKey)}` : ""}`;
825
+ const res = await fetch(url, {
826
+ method: "GET",
827
+ headers: __spreadValues({
828
+ "Content-Type": "application/json"
829
+ }, licenseKey ? { "x-license-key": licenseKey } : {})
830
+ });
831
+ if (res.ok) {
832
+ const data = await res.json();
833
+ if ((data == null ? void 0 : data.success) && ((_a2 = data == null ? void 0 : data.vectorDb) == null ? void 0 : _a2.apiKey)) {
834
+ const config = {
835
+ vectorDb: {
836
+ apiKey: data.vectorDb.apiKey,
837
+ indexName: data.vectorDb.indexName || "retrivora-free",
838
+ provider: data.vectorDb.provider || "pinecone"
839
+ },
840
+ embedding: {
841
+ provider: ((_b = data.embedding) == null ? void 0 : _b.provider) || "universal_rest",
842
+ model: ((_c = data.embedding) == null ? void 0 : _c.model) || "text-embedding-004",
843
+ baseUrl: ((_d = data.embedding) == null ? void 0 : _d.baseUrl) || "https://llm.retrivora.com/api/v1",
844
+ apiKey: ((_e = data.embedding) == null ? void 0 : _e.apiKey) || licenseKey || "",
845
+ profile: ((_f = data.embedding) == null ? void 0 : _f.profile) || "litellm"
846
+ },
847
+ llm: {
848
+ provider: ((_g2 = data.llm) == null ? void 0 : _g2.provider) || "universal_rest",
849
+ model: ((_h = data.llm) == null ? void 0 : _h.model) || "llama-3.1-8b-instant",
850
+ baseUrl: ((_i = data.llm) == null ? void 0 : _i.baseUrl) || "https://llm.retrivora.com/api/v1",
851
+ apiKey: ((_j = data.llm) == null ? void 0 : _j.apiKey) || licenseKey || "",
852
+ profile: ((_k = data.llm) == null ? void 0 : _k.profile) || "litellm"
853
+ }
854
+ };
855
+ this.cache.set(cacheKey, { config, cachedAt: now });
856
+ return config;
857
+ }
858
+ }
859
+ } catch (e) {
860
+ }
861
+ }
862
+ return null;
863
+ }
864
+ /** Convenience: fetch only vector DB config (backwards compat). */
865
+ static async fetchRemoteVectorConfig(projectId, licenseKey) {
866
+ var _a2;
867
+ const config = await this.fetchRemoteConfig(projectId, licenseKey);
868
+ return (_a2 = config == null ? void 0 : config.vectorDb) != null ? _a2 : null;
869
+ }
870
+ };
871
+ ConfigFetcher.cache = /* @__PURE__ */ new Map();
872
+ ConfigFetcher.TTL_MS = 5 * 60 * 1e3;
873
+ }
874
+ });
875
+
796
876
  // src/providers/vectordb/PineconeProvider.ts
797
877
  var PineconeProvider_exports = {};
798
878
  __export(PineconeProvider_exports, {
@@ -804,6 +884,7 @@ var init_PineconeProvider = __esm({
804
884
  "use strict";
805
885
  import_pinecone = require("@pinecone-database/pinecone");
806
886
  init_BaseVectorProvider();
887
+ init_ConfigFetcher();
807
888
  PineconeProvider = class extends BaseVectorProvider {
808
889
  constructor(config) {
809
890
  super(config);
@@ -869,27 +950,49 @@ var init_PineconeProvider = __esm({
869
950
  }
870
951
  async initialize() {
871
952
  var _a2, _b;
872
- const key = this.apiKey || process.env.PINECONE_API_KEY || "";
953
+ if (this.client) return;
954
+ let key = this.apiKey || process.env.PINECONE_API_KEY || "";
955
+ if (!key) {
956
+ const projectId = process.env.RAG_PROJECT_ID || process.env.NEXT_PUBLIC_RAG_PROJECT_ID || "my-rag-app";
957
+ const licenseKey = process.env.RETRIVORA_LICENSE_KEY || process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY;
958
+ const remoteConfig = await ConfigFetcher.fetchRemoteVectorConfig(projectId, licenseKey);
959
+ if (remoteConfig == null ? void 0 : remoteConfig.apiKey) {
960
+ key = remoteConfig.apiKey;
961
+ this.apiKey = key;
962
+ if (remoteConfig.indexName) {
963
+ this.indexName = remoteConfig.indexName;
964
+ }
965
+ }
966
+ }
873
967
  if (!key) {
874
- console.log("[PineconeProvider] Keyless Mode active \u2014 Vector operations managed via Retrivora Cloud Gateway.");
968
+ console.warn("[PineconeProvider] Warning: No Pinecone API key available locally or remotely.");
875
969
  return;
876
970
  }
877
971
  this.client = new import_pinecone.Pinecone({ apiKey: key });
878
- const indexes = await this.client.listIndexes();
879
- const names = (_b = (_a2 = indexes.indexes) == null ? void 0 : _a2.map((i) => i.name)) != null ? _b : [];
880
- if (!names.includes(this.indexName)) {
881
- throw new Error(
882
- `[PineconeProvider] Index "${this.indexName}" not found. Available: ${names.join(", ")}`
883
- );
972
+ try {
973
+ const indexes = await this.client.listIndexes();
974
+ const names = (_b = (_a2 = indexes.indexes) == null ? void 0 : _a2.map((i) => i.name)) != null ? _b : [];
975
+ if (!names.includes(this.indexName)) {
976
+ console.warn(`[PineconeProvider] Target index "${this.indexName}" not listed. Proceeding with configured index name.`);
977
+ }
978
+ } catch (err) {
979
+ console.warn("[PineconeProvider] List index verification warning:", err instanceof Error ? err.message : String(err));
884
980
  }
885
981
  }
886
- index(namespace) {
982
+ async getActiveIndex(namespace) {
983
+ if (!this.client) {
984
+ await this.initialize();
985
+ }
986
+ if (!this.client) {
987
+ throw new Error("[PineconeProvider] Cannot execute vector operation: Pinecone client failed to initialize.");
988
+ }
887
989
  const idx = this.client.index(this.indexName);
888
990
  return namespace ? idx.namespace(namespace) : idx.namespace("");
889
991
  }
890
992
  async upsert(doc, namespace) {
891
993
  var _a2;
892
- await this.index(namespace).upsert({
994
+ const targetIdx = await this.getActiveIndex(namespace);
995
+ await targetIdx.upsert({
893
996
  records: [{
894
997
  id: String(doc.id),
895
998
  values: doc.vector,
@@ -898,6 +1001,7 @@ var init_PineconeProvider = __esm({
898
1001
  });
899
1002
  }
900
1003
  async batchUpsert(docs, namespace) {
1004
+ const targetIdx = await this.getActiveIndex(namespace);
901
1005
  const BATCH = 100;
902
1006
  for (let i = 0; i < docs.length; i += BATCH) {
903
1007
  const records = docs.slice(i, i + BATCH).map((d) => {
@@ -908,13 +1012,14 @@ var init_PineconeProvider = __esm({
908
1012
  metadata: __spreadValues({ content: d.content }, (_a2 = d.metadata) != null ? _a2 : {})
909
1013
  };
910
1014
  });
911
- await this.index(namespace).upsert({ records });
1015
+ await targetIdx.upsert({ records });
912
1016
  }
913
1017
  }
914
1018
  async query(vector, topK, namespace, filter) {
915
1019
  var _a2;
1020
+ const targetIdx = await this.getActiveIndex(namespace);
916
1021
  const pineconeFilter = this.sanitizeFilter(filter);
917
- const result = await this.index(namespace).query(__spreadValues({
1022
+ const result = await targetIdx.query(__spreadValues({
918
1023
  vector,
919
1024
  topK,
920
1025
  includeMetadata: true
@@ -930,13 +1035,17 @@ var init_PineconeProvider = __esm({
930
1035
  });
931
1036
  }
932
1037
  async delete(id, namespace) {
933
- await this.index(namespace).deleteOne({ id: String(id) });
1038
+ const targetIdx = await this.getActiveIndex(namespace);
1039
+ await targetIdx.deleteOne({ id: String(id) });
934
1040
  }
935
1041
  async deleteNamespace(namespace) {
936
- await this.client.index(this.indexName).namespace(namespace).deleteAll();
1042
+ const targetIdx = await this.getActiveIndex(namespace);
1043
+ await targetIdx.deleteAll();
937
1044
  }
938
1045
  async ping() {
939
1046
  try {
1047
+ if (!this.client) await this.initialize();
1048
+ if (!this.client) return false;
940
1049
  await this.client.listIndexes();
941
1050
  return true;
942
1051
  } catch (e) {
@@ -3167,7 +3276,7 @@ function getEnvConfig(env = process.env, base) {
3167
3276
  return true;
3168
3277
  }
3169
3278
  })();
3170
- const defaultGatewayUrl = (_pa = (_oa = readString(env, "LITELLM_BASE_URL")) != null ? _oa : readString(env, "LLM_BASE_URL")) != null ? _pa : "https://llm.retrivora.com/api/v1";
3279
+ const defaultGatewayUrl = (_pa = (_oa = readString(env, "LITELLM_BASE_URL")) != null ? _oa : readString(env, "LLM_BASE_URL")) != null ? _pa : "https://www.retrivora.com/api/v1";
3171
3280
  const defaultLlmProvider = isFreeTier ? "universal_rest" : "universal_rest";
3172
3281
  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;
3173
3282
  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;
@@ -5254,7 +5363,7 @@ var ConfigValidator = class {
5254
5363
  // package.json
5255
5364
  var package_default = {
5256
5365
  name: "@retrivora-ai/rag-engine",
5257
- version: "2.1.9",
5366
+ version: "2.2.1",
5258
5367
  description: "Retrivora AI is a plug-and-play AI engine for RAG chat experiences \u2014 generic vector DB + LLM provider, embeddable or standalone.",
5259
5368
  author: "Abhinav Alkuchi",
5260
5369
  license: "UNLICENSED",
@@ -778,6 +778,86 @@ 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://www.retrivora.com",
803
+ "https://retrivora.com",
804
+ "http://localhost:3001",
805
+ "http://localhost:3000"
806
+ ].filter(Boolean);
807
+ for (const baseUrl of controlPlaneUrls) {
808
+ try {
809
+ const url = `${baseUrl.replace(/\/$/, "")}/api/v1/config?projectId=${encodeURIComponent(projectId)}${licenseKey ? `&licenseKey=${encodeURIComponent(licenseKey)}` : ""}`;
810
+ const res = await fetch(url, {
811
+ method: "GET",
812
+ headers: __spreadValues({
813
+ "Content-Type": "application/json"
814
+ }, licenseKey ? { "x-license-key": licenseKey } : {})
815
+ });
816
+ if (res.ok) {
817
+ const data = await res.json();
818
+ if ((data == null ? void 0 : data.success) && ((_a2 = data == null ? void 0 : data.vectorDb) == null ? void 0 : _a2.apiKey)) {
819
+ const config = {
820
+ vectorDb: {
821
+ apiKey: data.vectorDb.apiKey,
822
+ indexName: data.vectorDb.indexName || "retrivora-free",
823
+ provider: data.vectorDb.provider || "pinecone"
824
+ },
825
+ embedding: {
826
+ provider: ((_b = data.embedding) == null ? void 0 : _b.provider) || "universal_rest",
827
+ model: ((_c = data.embedding) == null ? void 0 : _c.model) || "text-embedding-004",
828
+ baseUrl: ((_d = data.embedding) == null ? void 0 : _d.baseUrl) || "https://llm.retrivora.com/api/v1",
829
+ apiKey: ((_e = data.embedding) == null ? void 0 : _e.apiKey) || licenseKey || "",
830
+ profile: ((_f = data.embedding) == null ? void 0 : _f.profile) || "litellm"
831
+ },
832
+ llm: {
833
+ provider: ((_g2 = data.llm) == null ? void 0 : _g2.provider) || "universal_rest",
834
+ model: ((_h = data.llm) == null ? void 0 : _h.model) || "llama-3.1-8b-instant",
835
+ baseUrl: ((_i = data.llm) == null ? void 0 : _i.baseUrl) || "https://llm.retrivora.com/api/v1",
836
+ apiKey: ((_j = data.llm) == null ? void 0 : _j.apiKey) || licenseKey || "",
837
+ profile: ((_k = data.llm) == null ? void 0 : _k.profile) || "litellm"
838
+ }
839
+ };
840
+ this.cache.set(cacheKey, { config, cachedAt: now });
841
+ return config;
842
+ }
843
+ }
844
+ } catch (e) {
845
+ }
846
+ }
847
+ return null;
848
+ }
849
+ /** Convenience: fetch only vector DB config (backwards compat). */
850
+ static async fetchRemoteVectorConfig(projectId, licenseKey) {
851
+ var _a2;
852
+ const config = await this.fetchRemoteConfig(projectId, licenseKey);
853
+ return (_a2 = config == null ? void 0 : config.vectorDb) != null ? _a2 : null;
854
+ }
855
+ };
856
+ ConfigFetcher.cache = /* @__PURE__ */ new Map();
857
+ ConfigFetcher.TTL_MS = 5 * 60 * 1e3;
858
+ }
859
+ });
860
+
781
861
  // src/providers/vectordb/PineconeProvider.ts
782
862
  var PineconeProvider_exports = {};
783
863
  __export(PineconeProvider_exports, {
@@ -789,6 +869,7 @@ var init_PineconeProvider = __esm({
789
869
  "src/providers/vectordb/PineconeProvider.ts"() {
790
870
  "use strict";
791
871
  init_BaseVectorProvider();
872
+ init_ConfigFetcher();
792
873
  PineconeProvider = class extends BaseVectorProvider {
793
874
  constructor(config) {
794
875
  super(config);
@@ -854,27 +935,49 @@ var init_PineconeProvider = __esm({
854
935
  }
855
936
  async initialize() {
856
937
  var _a2, _b;
857
- const key = this.apiKey || process.env.PINECONE_API_KEY || "";
938
+ if (this.client) return;
939
+ let key = this.apiKey || process.env.PINECONE_API_KEY || "";
940
+ if (!key) {
941
+ const projectId = process.env.RAG_PROJECT_ID || process.env.NEXT_PUBLIC_RAG_PROJECT_ID || "my-rag-app";
942
+ const licenseKey = process.env.RETRIVORA_LICENSE_KEY || process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY;
943
+ const remoteConfig = await ConfigFetcher.fetchRemoteVectorConfig(projectId, licenseKey);
944
+ if (remoteConfig == null ? void 0 : remoteConfig.apiKey) {
945
+ key = remoteConfig.apiKey;
946
+ this.apiKey = key;
947
+ if (remoteConfig.indexName) {
948
+ this.indexName = remoteConfig.indexName;
949
+ }
950
+ }
951
+ }
858
952
  if (!key) {
859
- console.log("[PineconeProvider] Keyless Mode active \u2014 Vector operations managed via Retrivora Cloud Gateway.");
953
+ console.warn("[PineconeProvider] Warning: No Pinecone API key available locally or remotely.");
860
954
  return;
861
955
  }
862
956
  this.client = new Pinecone({ apiKey: key });
863
- const indexes = await this.client.listIndexes();
864
- const names = (_b = (_a2 = indexes.indexes) == null ? void 0 : _a2.map((i) => i.name)) != null ? _b : [];
865
- if (!names.includes(this.indexName)) {
866
- throw new Error(
867
- `[PineconeProvider] Index "${this.indexName}" not found. Available: ${names.join(", ")}`
868
- );
957
+ try {
958
+ const indexes = await this.client.listIndexes();
959
+ const names = (_b = (_a2 = indexes.indexes) == null ? void 0 : _a2.map((i) => i.name)) != null ? _b : [];
960
+ if (!names.includes(this.indexName)) {
961
+ console.warn(`[PineconeProvider] Target index "${this.indexName}" not listed. Proceeding with configured index name.`);
962
+ }
963
+ } catch (err) {
964
+ console.warn("[PineconeProvider] List index verification warning:", err instanceof Error ? err.message : String(err));
869
965
  }
870
966
  }
871
- index(namespace) {
967
+ async getActiveIndex(namespace) {
968
+ if (!this.client) {
969
+ await this.initialize();
970
+ }
971
+ if (!this.client) {
972
+ throw new Error("[PineconeProvider] Cannot execute vector operation: Pinecone client failed to initialize.");
973
+ }
872
974
  const idx = this.client.index(this.indexName);
873
975
  return namespace ? idx.namespace(namespace) : idx.namespace("");
874
976
  }
875
977
  async upsert(doc, namespace) {
876
978
  var _a2;
877
- await this.index(namespace).upsert({
979
+ const targetIdx = await this.getActiveIndex(namespace);
980
+ await targetIdx.upsert({
878
981
  records: [{
879
982
  id: String(doc.id),
880
983
  values: doc.vector,
@@ -883,6 +986,7 @@ var init_PineconeProvider = __esm({
883
986
  });
884
987
  }
885
988
  async batchUpsert(docs, namespace) {
989
+ const targetIdx = await this.getActiveIndex(namespace);
886
990
  const BATCH = 100;
887
991
  for (let i = 0; i < docs.length; i += BATCH) {
888
992
  const records = docs.slice(i, i + BATCH).map((d) => {
@@ -893,13 +997,14 @@ var init_PineconeProvider = __esm({
893
997
  metadata: __spreadValues({ content: d.content }, (_a2 = d.metadata) != null ? _a2 : {})
894
998
  };
895
999
  });
896
- await this.index(namespace).upsert({ records });
1000
+ await targetIdx.upsert({ records });
897
1001
  }
898
1002
  }
899
1003
  async query(vector, topK, namespace, filter) {
900
1004
  var _a2;
1005
+ const targetIdx = await this.getActiveIndex(namespace);
901
1006
  const pineconeFilter = this.sanitizeFilter(filter);
902
- const result = await this.index(namespace).query(__spreadValues({
1007
+ const result = await targetIdx.query(__spreadValues({
903
1008
  vector,
904
1009
  topK,
905
1010
  includeMetadata: true
@@ -915,13 +1020,17 @@ var init_PineconeProvider = __esm({
915
1020
  });
916
1021
  }
917
1022
  async delete(id, namespace) {
918
- await this.index(namespace).deleteOne({ id: String(id) });
1023
+ const targetIdx = await this.getActiveIndex(namespace);
1024
+ await targetIdx.deleteOne({ id: String(id) });
919
1025
  }
920
1026
  async deleteNamespace(namespace) {
921
- await this.client.index(this.indexName).namespace(namespace).deleteAll();
1027
+ const targetIdx = await this.getActiveIndex(namespace);
1028
+ await targetIdx.deleteAll();
922
1029
  }
923
1030
  async ping() {
924
1031
  try {
1032
+ if (!this.client) await this.initialize();
1033
+ if (!this.client) return false;
925
1034
  await this.client.listIndexes();
926
1035
  return true;
927
1036
  } catch (e) {
@@ -3132,7 +3241,7 @@ function getEnvConfig(env = process.env, base) {
3132
3241
  return true;
3133
3242
  }
3134
3243
  })();
3135
- const defaultGatewayUrl = (_pa = (_oa = readString(env, "LITELLM_BASE_URL")) != null ? _oa : readString(env, "LLM_BASE_URL")) != null ? _pa : "https://llm.retrivora.com/api/v1";
3244
+ const defaultGatewayUrl = (_pa = (_oa = readString(env, "LITELLM_BASE_URL")) != null ? _oa : readString(env, "LLM_BASE_URL")) != null ? _pa : "https://www.retrivora.com/api/v1";
3136
3245
  const defaultLlmProvider = isFreeTier ? "universal_rest" : "universal_rest";
3137
3246
  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;
3138
3247
  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;
@@ -5219,7 +5328,7 @@ var ConfigValidator = class {
5219
5328
  // package.json
5220
5329
  var package_default = {
5221
5330
  name: "@retrivora-ai/rag-engine",
5222
- version: "2.1.9",
5331
+ version: "2.2.1",
5223
5332
  description: "Retrivora AI is a plug-and-play AI engine for RAG chat experiences \u2014 generic vector DB + LLM provider, embeddable or standalone.",
5224
5333
  author: "Abhinav Alkuchi",
5225
5334
  license: "UNLICENSED",
package/dist/index.js CHANGED
@@ -3563,7 +3563,7 @@ function ChatWidget({ position = "bottom-right", onAddToCart, apiUrl, retrivoraA
3563
3563
  // package.json
3564
3564
  var package_default = {
3565
3565
  name: "@retrivora-ai/rag-engine",
3566
- version: "2.1.9",
3566
+ version: "2.2.1",
3567
3567
  description: "Retrivora AI is a plug-and-play AI engine for RAG chat experiences \u2014 generic vector DB + LLM provider, embeddable or standalone.",
3568
3568
  author: "Abhinav Alkuchi",
3569
3569
  license: "UNLICENSED",
package/dist/index.mjs CHANGED
@@ -3564,7 +3564,7 @@ function ChatWidget({ position = "bottom-right", onAddToCart, apiUrl, retrivoraA
3564
3564
  // package.json
3565
3565
  var package_default = {
3566
3566
  name: "@retrivora-ai/rag-engine",
3567
- version: "2.1.9",
3567
+ version: "2.2.1",
3568
3568
  description: "Retrivora AI is a plug-and-play AI engine for RAG chat experiences \u2014 generic vector DB + LLM provider, embeddable or standalone.",
3569
3569
  author: "Abhinav Alkuchi",
3570
3570
  license: "UNLICENSED",
package/dist/server.d.mts CHANGED
@@ -198,7 +198,7 @@ declare class ConfigResolver {
198
198
  */
199
199
  declare abstract class BaseVectorProvider {
200
200
  protected readonly config: VectorDBConfig;
201
- protected readonly indexName: string;
201
+ protected indexName: string;
202
202
  constructor(config: VectorDBConfig);
203
203
  /**
204
204
  * Initialise the connection (create tables, verify index, etc.)
@@ -615,12 +615,12 @@ declare class DocumentParser {
615
615
  */
616
616
  declare class PineconeProvider extends BaseVectorProvider {
617
617
  private client;
618
- private readonly apiKey;
618
+ private apiKey;
619
619
  constructor(config: VectorDBConfig);
620
620
  static getValidator(): IProviderValidator;
621
621
  static getHealthChecker(): IProviderHealthChecker;
622
622
  initialize(): Promise<void>;
623
- private index;
623
+ private getActiveIndex;
624
624
  upsert(doc: UpsertDocument, namespace?: string): Promise<void>;
625
625
  batchUpsert(docs: UpsertDocument[], namespace?: string): Promise<void>;
626
626
  query(vector: number[], topK: number, namespace?: string, filter?: Record<string, unknown>): Promise<VectorMatch[]>;
package/dist/server.d.ts CHANGED
@@ -198,7 +198,7 @@ declare class ConfigResolver {
198
198
  */
199
199
  declare abstract class BaseVectorProvider {
200
200
  protected readonly config: VectorDBConfig;
201
- protected readonly indexName: string;
201
+ protected indexName: string;
202
202
  constructor(config: VectorDBConfig);
203
203
  /**
204
204
  * Initialise the connection (create tables, verify index, etc.)
@@ -615,12 +615,12 @@ declare class DocumentParser {
615
615
  */
616
616
  declare class PineconeProvider extends BaseVectorProvider {
617
617
  private client;
618
- private readonly apiKey;
618
+ private apiKey;
619
619
  constructor(config: VectorDBConfig);
620
620
  static getValidator(): IProviderValidator;
621
621
  static getHealthChecker(): IProviderHealthChecker;
622
622
  initialize(): Promise<void>;
623
- private index;
623
+ private getActiveIndex;
624
624
  upsert(doc: UpsertDocument, namespace?: string): Promise<void>;
625
625
  batchUpsert(docs: UpsertDocument[], namespace?: string): Promise<void>;
626
626
  query(vector: number[], topK: number, namespace?: string, filter?: Record<string, unknown>): Promise<VectorMatch[]>;
package/dist/server.js CHANGED
@@ -793,6 +793,86 @@ var init_BaseVectorProvider = __esm({
793
793
  }
794
794
  });
795
795
 
796
+ // src/core/ConfigFetcher.ts
797
+ var ConfigFetcher;
798
+ var init_ConfigFetcher = __esm({
799
+ "src/core/ConfigFetcher.ts"() {
800
+ "use strict";
801
+ ConfigFetcher = class {
802
+ // 5-minute in-memory session cache
803
+ /**
804
+ * Fetch full project configuration (vectorDb + embedding + llm) from Retrivora Control Plane.
805
+ */
806
+ static async fetchRemoteConfig(projectId, licenseKey) {
807
+ var _a2, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
808
+ const cacheKey = `${projectId}:${licenseKey || ""}`;
809
+ const now = Date.now();
810
+ const cached = this.cache.get(cacheKey);
811
+ if (cached && now - cached.cachedAt < this.TTL_MS) {
812
+ return cached.config;
813
+ }
814
+ const controlPlaneUrls = [
815
+ process.env.RETRIVORA_CONTROL_PLANE_URL,
816
+ process.env.NEXT_PUBLIC_RETRIVORA_CONTROL_PLANE_URL,
817
+ "https://www.retrivora.com",
818
+ "https://retrivora.com",
819
+ "http://localhost:3001",
820
+ "http://localhost:3000"
821
+ ].filter(Boolean);
822
+ for (const baseUrl of controlPlaneUrls) {
823
+ try {
824
+ const url = `${baseUrl.replace(/\/$/, "")}/api/v1/config?projectId=${encodeURIComponent(projectId)}${licenseKey ? `&licenseKey=${encodeURIComponent(licenseKey)}` : ""}`;
825
+ const res = await fetch(url, {
826
+ method: "GET",
827
+ headers: __spreadValues({
828
+ "Content-Type": "application/json"
829
+ }, licenseKey ? { "x-license-key": licenseKey } : {})
830
+ });
831
+ if (res.ok) {
832
+ const data = await res.json();
833
+ if ((data == null ? void 0 : data.success) && ((_a2 = data == null ? void 0 : data.vectorDb) == null ? void 0 : _a2.apiKey)) {
834
+ const config = {
835
+ vectorDb: {
836
+ apiKey: data.vectorDb.apiKey,
837
+ indexName: data.vectorDb.indexName || "retrivora-free",
838
+ provider: data.vectorDb.provider || "pinecone"
839
+ },
840
+ embedding: {
841
+ provider: ((_b = data.embedding) == null ? void 0 : _b.provider) || "universal_rest",
842
+ model: ((_c = data.embedding) == null ? void 0 : _c.model) || "text-embedding-004",
843
+ baseUrl: ((_d = data.embedding) == null ? void 0 : _d.baseUrl) || "https://llm.retrivora.com/api/v1",
844
+ apiKey: ((_e = data.embedding) == null ? void 0 : _e.apiKey) || licenseKey || "",
845
+ profile: ((_f = data.embedding) == null ? void 0 : _f.profile) || "litellm"
846
+ },
847
+ llm: {
848
+ provider: ((_g2 = data.llm) == null ? void 0 : _g2.provider) || "universal_rest",
849
+ model: ((_h = data.llm) == null ? void 0 : _h.model) || "llama-3.1-8b-instant",
850
+ baseUrl: ((_i = data.llm) == null ? void 0 : _i.baseUrl) || "https://llm.retrivora.com/api/v1",
851
+ apiKey: ((_j = data.llm) == null ? void 0 : _j.apiKey) || licenseKey || "",
852
+ profile: ((_k = data.llm) == null ? void 0 : _k.profile) || "litellm"
853
+ }
854
+ };
855
+ this.cache.set(cacheKey, { config, cachedAt: now });
856
+ return config;
857
+ }
858
+ }
859
+ } catch (e) {
860
+ }
861
+ }
862
+ return null;
863
+ }
864
+ /** Convenience: fetch only vector DB config (backwards compat). */
865
+ static async fetchRemoteVectorConfig(projectId, licenseKey) {
866
+ var _a2;
867
+ const config = await this.fetchRemoteConfig(projectId, licenseKey);
868
+ return (_a2 = config == null ? void 0 : config.vectorDb) != null ? _a2 : null;
869
+ }
870
+ };
871
+ ConfigFetcher.cache = /* @__PURE__ */ new Map();
872
+ ConfigFetcher.TTL_MS = 5 * 60 * 1e3;
873
+ }
874
+ });
875
+
796
876
  // src/providers/vectordb/PineconeProvider.ts
797
877
  var PineconeProvider_exports = {};
798
878
  __export(PineconeProvider_exports, {
@@ -804,6 +884,7 @@ var init_PineconeProvider = __esm({
804
884
  "use strict";
805
885
  import_pinecone = require("@pinecone-database/pinecone");
806
886
  init_BaseVectorProvider();
887
+ init_ConfigFetcher();
807
888
  PineconeProvider = class extends BaseVectorProvider {
808
889
  constructor(config) {
809
890
  super(config);
@@ -869,27 +950,49 @@ var init_PineconeProvider = __esm({
869
950
  }
870
951
  async initialize() {
871
952
  var _a2, _b;
872
- const key = this.apiKey || process.env.PINECONE_API_KEY || "";
953
+ if (this.client) return;
954
+ let key = this.apiKey || process.env.PINECONE_API_KEY || "";
955
+ if (!key) {
956
+ const projectId = process.env.RAG_PROJECT_ID || process.env.NEXT_PUBLIC_RAG_PROJECT_ID || "my-rag-app";
957
+ const licenseKey = process.env.RETRIVORA_LICENSE_KEY || process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY;
958
+ const remoteConfig = await ConfigFetcher.fetchRemoteVectorConfig(projectId, licenseKey);
959
+ if (remoteConfig == null ? void 0 : remoteConfig.apiKey) {
960
+ key = remoteConfig.apiKey;
961
+ this.apiKey = key;
962
+ if (remoteConfig.indexName) {
963
+ this.indexName = remoteConfig.indexName;
964
+ }
965
+ }
966
+ }
873
967
  if (!key) {
874
- console.log("[PineconeProvider] Keyless Mode active \u2014 Vector operations managed via Retrivora Cloud Gateway.");
968
+ console.warn("[PineconeProvider] Warning: No Pinecone API key available locally or remotely.");
875
969
  return;
876
970
  }
877
971
  this.client = new import_pinecone.Pinecone({ apiKey: key });
878
- const indexes = await this.client.listIndexes();
879
- const names = (_b = (_a2 = indexes.indexes) == null ? void 0 : _a2.map((i) => i.name)) != null ? _b : [];
880
- if (!names.includes(this.indexName)) {
881
- throw new Error(
882
- `[PineconeProvider] Index "${this.indexName}" not found. Available: ${names.join(", ")}`
883
- );
972
+ try {
973
+ const indexes = await this.client.listIndexes();
974
+ const names = (_b = (_a2 = indexes.indexes) == null ? void 0 : _a2.map((i) => i.name)) != null ? _b : [];
975
+ if (!names.includes(this.indexName)) {
976
+ console.warn(`[PineconeProvider] Target index "${this.indexName}" not listed. Proceeding with configured index name.`);
977
+ }
978
+ } catch (err) {
979
+ console.warn("[PineconeProvider] List index verification warning:", err instanceof Error ? err.message : String(err));
884
980
  }
885
981
  }
886
- index(namespace) {
982
+ async getActiveIndex(namespace) {
983
+ if (!this.client) {
984
+ await this.initialize();
985
+ }
986
+ if (!this.client) {
987
+ throw new Error("[PineconeProvider] Cannot execute vector operation: Pinecone client failed to initialize.");
988
+ }
887
989
  const idx = this.client.index(this.indexName);
888
990
  return namespace ? idx.namespace(namespace) : idx.namespace("");
889
991
  }
890
992
  async upsert(doc, namespace) {
891
993
  var _a2;
892
- await this.index(namespace).upsert({
994
+ const targetIdx = await this.getActiveIndex(namespace);
995
+ await targetIdx.upsert({
893
996
  records: [{
894
997
  id: String(doc.id),
895
998
  values: doc.vector,
@@ -898,6 +1001,7 @@ var init_PineconeProvider = __esm({
898
1001
  });
899
1002
  }
900
1003
  async batchUpsert(docs, namespace) {
1004
+ const targetIdx = await this.getActiveIndex(namespace);
901
1005
  const BATCH = 100;
902
1006
  for (let i = 0; i < docs.length; i += BATCH) {
903
1007
  const records = docs.slice(i, i + BATCH).map((d) => {
@@ -908,13 +1012,14 @@ var init_PineconeProvider = __esm({
908
1012
  metadata: __spreadValues({ content: d.content }, (_a2 = d.metadata) != null ? _a2 : {})
909
1013
  };
910
1014
  });
911
- await this.index(namespace).upsert({ records });
1015
+ await targetIdx.upsert({ records });
912
1016
  }
913
1017
  }
914
1018
  async query(vector, topK, namespace, filter) {
915
1019
  var _a2;
1020
+ const targetIdx = await this.getActiveIndex(namespace);
916
1021
  const pineconeFilter = this.sanitizeFilter(filter);
917
- const result = await this.index(namespace).query(__spreadValues({
1022
+ const result = await targetIdx.query(__spreadValues({
918
1023
  vector,
919
1024
  topK,
920
1025
  includeMetadata: true
@@ -930,13 +1035,17 @@ var init_PineconeProvider = __esm({
930
1035
  });
931
1036
  }
932
1037
  async delete(id, namespace) {
933
- await this.index(namespace).deleteOne({ id: String(id) });
1038
+ const targetIdx = await this.getActiveIndex(namespace);
1039
+ await targetIdx.deleteOne({ id: String(id) });
934
1040
  }
935
1041
  async deleteNamespace(namespace) {
936
- await this.client.index(this.indexName).namespace(namespace).deleteAll();
1042
+ const targetIdx = await this.getActiveIndex(namespace);
1043
+ await targetIdx.deleteAll();
937
1044
  }
938
1045
  async ping() {
939
1046
  try {
1047
+ if (!this.client) await this.initialize();
1048
+ if (!this.client) return false;
940
1049
  await this.client.listIndexes();
941
1050
  return true;
942
1051
  } catch (e) {
@@ -3229,7 +3338,7 @@ function getEnvConfig(env = process.env, base) {
3229
3338
  return true;
3230
3339
  }
3231
3340
  })();
3232
- const defaultGatewayUrl = (_pa = (_oa = readString(env, "LITELLM_BASE_URL")) != null ? _oa : readString(env, "LLM_BASE_URL")) != null ? _pa : "https://llm.retrivora.com/api/v1";
3341
+ const defaultGatewayUrl = (_pa = (_oa = readString(env, "LITELLM_BASE_URL")) != null ? _oa : readString(env, "LLM_BASE_URL")) != null ? _pa : "https://www.retrivora.com/api/v1";
3233
3342
  const defaultLlmProvider = isFreeTier ? "universal_rest" : "universal_rest";
3234
3343
  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;
3235
3344
  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;
@@ -5355,7 +5464,7 @@ var ConfigValidator = class {
5355
5464
  // package.json
5356
5465
  var package_default = {
5357
5466
  name: "@retrivora-ai/rag-engine",
5358
- version: "2.1.9",
5467
+ version: "2.2.1",
5359
5468
  description: "Retrivora AI is a plug-and-play AI engine for RAG chat experiences \u2014 generic vector DB + LLM provider, embeddable or standalone.",
5360
5469
  author: "Abhinav Alkuchi",
5361
5470
  license: "UNLICENSED",
package/dist/server.mjs CHANGED
@@ -778,6 +778,86 @@ 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://www.retrivora.com",
803
+ "https://retrivora.com",
804
+ "http://localhost:3001",
805
+ "http://localhost:3000"
806
+ ].filter(Boolean);
807
+ for (const baseUrl of controlPlaneUrls) {
808
+ try {
809
+ const url = `${baseUrl.replace(/\/$/, "")}/api/v1/config?projectId=${encodeURIComponent(projectId)}${licenseKey ? `&licenseKey=${encodeURIComponent(licenseKey)}` : ""}`;
810
+ const res = await fetch(url, {
811
+ method: "GET",
812
+ headers: __spreadValues({
813
+ "Content-Type": "application/json"
814
+ }, licenseKey ? { "x-license-key": licenseKey } : {})
815
+ });
816
+ if (res.ok) {
817
+ const data = await res.json();
818
+ if ((data == null ? void 0 : data.success) && ((_a2 = data == null ? void 0 : data.vectorDb) == null ? void 0 : _a2.apiKey)) {
819
+ const config = {
820
+ vectorDb: {
821
+ apiKey: data.vectorDb.apiKey,
822
+ indexName: data.vectorDb.indexName || "retrivora-free",
823
+ provider: data.vectorDb.provider || "pinecone"
824
+ },
825
+ embedding: {
826
+ provider: ((_b = data.embedding) == null ? void 0 : _b.provider) || "universal_rest",
827
+ model: ((_c = data.embedding) == null ? void 0 : _c.model) || "text-embedding-004",
828
+ baseUrl: ((_d = data.embedding) == null ? void 0 : _d.baseUrl) || "https://llm.retrivora.com/api/v1",
829
+ apiKey: ((_e = data.embedding) == null ? void 0 : _e.apiKey) || licenseKey || "",
830
+ profile: ((_f = data.embedding) == null ? void 0 : _f.profile) || "litellm"
831
+ },
832
+ llm: {
833
+ provider: ((_g2 = data.llm) == null ? void 0 : _g2.provider) || "universal_rest",
834
+ model: ((_h = data.llm) == null ? void 0 : _h.model) || "llama-3.1-8b-instant",
835
+ baseUrl: ((_i = data.llm) == null ? void 0 : _i.baseUrl) || "https://llm.retrivora.com/api/v1",
836
+ apiKey: ((_j = data.llm) == null ? void 0 : _j.apiKey) || licenseKey || "",
837
+ profile: ((_k = data.llm) == null ? void 0 : _k.profile) || "litellm"
838
+ }
839
+ };
840
+ this.cache.set(cacheKey, { config, cachedAt: now });
841
+ return config;
842
+ }
843
+ }
844
+ } catch (e) {
845
+ }
846
+ }
847
+ return null;
848
+ }
849
+ /** Convenience: fetch only vector DB config (backwards compat). */
850
+ static async fetchRemoteVectorConfig(projectId, licenseKey) {
851
+ var _a2;
852
+ const config = await this.fetchRemoteConfig(projectId, licenseKey);
853
+ return (_a2 = config == null ? void 0 : config.vectorDb) != null ? _a2 : null;
854
+ }
855
+ };
856
+ ConfigFetcher.cache = /* @__PURE__ */ new Map();
857
+ ConfigFetcher.TTL_MS = 5 * 60 * 1e3;
858
+ }
859
+ });
860
+
781
861
  // src/providers/vectordb/PineconeProvider.ts
782
862
  var PineconeProvider_exports = {};
783
863
  __export(PineconeProvider_exports, {
@@ -789,6 +869,7 @@ var init_PineconeProvider = __esm({
789
869
  "src/providers/vectordb/PineconeProvider.ts"() {
790
870
  "use strict";
791
871
  init_BaseVectorProvider();
872
+ init_ConfigFetcher();
792
873
  PineconeProvider = class extends BaseVectorProvider {
793
874
  constructor(config) {
794
875
  super(config);
@@ -854,27 +935,49 @@ var init_PineconeProvider = __esm({
854
935
  }
855
936
  async initialize() {
856
937
  var _a2, _b;
857
- const key = this.apiKey || process.env.PINECONE_API_KEY || "";
938
+ if (this.client) return;
939
+ let key = this.apiKey || process.env.PINECONE_API_KEY || "";
940
+ if (!key) {
941
+ const projectId = process.env.RAG_PROJECT_ID || process.env.NEXT_PUBLIC_RAG_PROJECT_ID || "my-rag-app";
942
+ const licenseKey = process.env.RETRIVORA_LICENSE_KEY || process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY;
943
+ const remoteConfig = await ConfigFetcher.fetchRemoteVectorConfig(projectId, licenseKey);
944
+ if (remoteConfig == null ? void 0 : remoteConfig.apiKey) {
945
+ key = remoteConfig.apiKey;
946
+ this.apiKey = key;
947
+ if (remoteConfig.indexName) {
948
+ this.indexName = remoteConfig.indexName;
949
+ }
950
+ }
951
+ }
858
952
  if (!key) {
859
- console.log("[PineconeProvider] Keyless Mode active \u2014 Vector operations managed via Retrivora Cloud Gateway.");
953
+ console.warn("[PineconeProvider] Warning: No Pinecone API key available locally or remotely.");
860
954
  return;
861
955
  }
862
956
  this.client = new Pinecone({ apiKey: key });
863
- const indexes = await this.client.listIndexes();
864
- const names = (_b = (_a2 = indexes.indexes) == null ? void 0 : _a2.map((i) => i.name)) != null ? _b : [];
865
- if (!names.includes(this.indexName)) {
866
- throw new Error(
867
- `[PineconeProvider] Index "${this.indexName}" not found. Available: ${names.join(", ")}`
868
- );
957
+ try {
958
+ const indexes = await this.client.listIndexes();
959
+ const names = (_b = (_a2 = indexes.indexes) == null ? void 0 : _a2.map((i) => i.name)) != null ? _b : [];
960
+ if (!names.includes(this.indexName)) {
961
+ console.warn(`[PineconeProvider] Target index "${this.indexName}" not listed. Proceeding with configured index name.`);
962
+ }
963
+ } catch (err) {
964
+ console.warn("[PineconeProvider] List index verification warning:", err instanceof Error ? err.message : String(err));
869
965
  }
870
966
  }
871
- index(namespace) {
967
+ async getActiveIndex(namespace) {
968
+ if (!this.client) {
969
+ await this.initialize();
970
+ }
971
+ if (!this.client) {
972
+ throw new Error("[PineconeProvider] Cannot execute vector operation: Pinecone client failed to initialize.");
973
+ }
872
974
  const idx = this.client.index(this.indexName);
873
975
  return namespace ? idx.namespace(namespace) : idx.namespace("");
874
976
  }
875
977
  async upsert(doc, namespace) {
876
978
  var _a2;
877
- await this.index(namespace).upsert({
979
+ const targetIdx = await this.getActiveIndex(namespace);
980
+ await targetIdx.upsert({
878
981
  records: [{
879
982
  id: String(doc.id),
880
983
  values: doc.vector,
@@ -883,6 +986,7 @@ var init_PineconeProvider = __esm({
883
986
  });
884
987
  }
885
988
  async batchUpsert(docs, namespace) {
989
+ const targetIdx = await this.getActiveIndex(namespace);
886
990
  const BATCH = 100;
887
991
  for (let i = 0; i < docs.length; i += BATCH) {
888
992
  const records = docs.slice(i, i + BATCH).map((d) => {
@@ -893,13 +997,14 @@ var init_PineconeProvider = __esm({
893
997
  metadata: __spreadValues({ content: d.content }, (_a2 = d.metadata) != null ? _a2 : {})
894
998
  };
895
999
  });
896
- await this.index(namespace).upsert({ records });
1000
+ await targetIdx.upsert({ records });
897
1001
  }
898
1002
  }
899
1003
  async query(vector, topK, namespace, filter) {
900
1004
  var _a2;
1005
+ const targetIdx = await this.getActiveIndex(namespace);
901
1006
  const pineconeFilter = this.sanitizeFilter(filter);
902
- const result = await this.index(namespace).query(__spreadValues({
1007
+ const result = await targetIdx.query(__spreadValues({
903
1008
  vector,
904
1009
  topK,
905
1010
  includeMetadata: true
@@ -915,13 +1020,17 @@ var init_PineconeProvider = __esm({
915
1020
  });
916
1021
  }
917
1022
  async delete(id, namespace) {
918
- await this.index(namespace).deleteOne({ id: String(id) });
1023
+ const targetIdx = await this.getActiveIndex(namespace);
1024
+ await targetIdx.deleteOne({ id: String(id) });
919
1025
  }
920
1026
  async deleteNamespace(namespace) {
921
- await this.client.index(this.indexName).namespace(namespace).deleteAll();
1027
+ const targetIdx = await this.getActiveIndex(namespace);
1028
+ await targetIdx.deleteAll();
922
1029
  }
923
1030
  async ping() {
924
1031
  try {
1032
+ if (!this.client) await this.initialize();
1033
+ if (!this.client) return false;
925
1034
  await this.client.listIndexes();
926
1035
  return true;
927
1036
  } catch (e) {
@@ -3132,7 +3241,7 @@ function getEnvConfig(env = process.env, base) {
3132
3241
  return true;
3133
3242
  }
3134
3243
  })();
3135
- const defaultGatewayUrl = (_pa = (_oa = readString(env, "LITELLM_BASE_URL")) != null ? _oa : readString(env, "LLM_BASE_URL")) != null ? _pa : "https://llm.retrivora.com/api/v1";
3244
+ const defaultGatewayUrl = (_pa = (_oa = readString(env, "LITELLM_BASE_URL")) != null ? _oa : readString(env, "LLM_BASE_URL")) != null ? _pa : "https://www.retrivora.com/api/v1";
3136
3245
  const defaultLlmProvider = isFreeTier ? "universal_rest" : "universal_rest";
3137
3246
  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;
3138
3247
  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;
@@ -5258,7 +5367,7 @@ var ConfigValidator = class {
5258
5367
  // package.json
5259
5368
  var package_default = {
5260
5369
  name: "@retrivora-ai/rag-engine",
5261
- version: "2.1.9",
5370
+ version: "2.2.1",
5262
5371
  description: "Retrivora AI is a plug-and-play AI engine for RAG chat experiences \u2014 generic vector DB + LLM provider, embeddable or standalone.",
5263
5372
  author: "Abhinav Alkuchi",
5264
5373
  license: "UNLICENSED",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@retrivora-ai/rag-engine",
3
- "version": "2.1.9",
3
+ "version": "2.2.1",
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",
@@ -171,7 +171,10 @@ export function getEnvConfig(env: Record<string, string | undefined> = process.e
171
171
  }
172
172
  })();
173
173
 
174
- 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://www.retrivora.com/api/v1';
175
178
 
176
179
  const defaultLlmProvider = isFreeTier ? 'universal_rest' : 'universal_rest';
177
180
  const llmProvider = (readEnum(env, 'LLM_PROVIDER', defaultLlmProvider, LLM_PROVIDERS) ?? base?.llm?.provider ?? defaultLlmProvider) as LLMProvider;
@@ -0,0 +1,114 @@
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://www.retrivora.com',
57
+ 'https://retrivora.com',
58
+ 'http://localhost:3001',
59
+ 'http://localhost:3000',
60
+ ].filter(Boolean) as string[];
61
+
62
+ for (const baseUrl of controlPlaneUrls) {
63
+ try {
64
+ const url = `${baseUrl.replace(/\/$/, '')}/api/v1/config?projectId=${encodeURIComponent(projectId)}${licenseKey ? `&licenseKey=${encodeURIComponent(licenseKey)}` : ''}`;
65
+ const res = await fetch(url, {
66
+ method: 'GET',
67
+ headers: {
68
+ 'Content-Type': 'application/json',
69
+ ...(licenseKey ? { 'x-license-key': licenseKey } : {}),
70
+ },
71
+ });
72
+
73
+ if (res.ok) {
74
+ const data = await res.json();
75
+ if (data?.success && data?.vectorDb?.apiKey) {
76
+ const config: RemoteConfig = {
77
+ vectorDb: {
78
+ apiKey: data.vectorDb.apiKey,
79
+ indexName: data.vectorDb.indexName || 'retrivora-free',
80
+ provider: data.vectorDb.provider || 'pinecone',
81
+ },
82
+ embedding: {
83
+ provider: data.embedding?.provider || 'universal_rest',
84
+ model: data.embedding?.model || 'text-embedding-004',
85
+ baseUrl: data.embedding?.baseUrl || 'https://llm.retrivora.com/api/v1',
86
+ apiKey: data.embedding?.apiKey || licenseKey || '',
87
+ profile: data.embedding?.profile || 'litellm',
88
+ },
89
+ llm: {
90
+ provider: data.llm?.provider || 'universal_rest',
91
+ model: data.llm?.model || 'llama-3.1-8b-instant',
92
+ baseUrl: data.llm?.baseUrl || 'https://llm.retrivora.com/api/v1',
93
+ apiKey: data.llm?.apiKey || licenseKey || '',
94
+ profile: data.llm?.profile || 'litellm',
95
+ },
96
+ };
97
+ this.cache.set(cacheKey, { config, cachedAt: now });
98
+ return config;
99
+ }
100
+ }
101
+ } catch {
102
+ /* Try next fallback URL */
103
+ }
104
+ }
105
+
106
+ return null;
107
+ }
108
+
109
+ /** Convenience: fetch only vector DB config (backwards compat). */
110
+ static async fetchRemoteVectorConfig(projectId: string, licenseKey?: string): Promise<RemoteVectorConfig | null> {
111
+ const config = await this.fetchRemoteConfig(projectId, licenseKey);
112
+ return config?.vectorDb ?? null;
113
+ }
114
+ }
@@ -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;
@@ -4,13 +4,14 @@ import { BaseVectorProvider } from './BaseVectorProvider';
4
4
  import { VectorMatch, UpsertDocument } from '../../types';
5
5
  import { IProviderValidator, IProviderHealthChecker, HealthCheckResult } from '../../core/ProviderInterfaces';
6
6
  import { ValidationError } from '../../core/ConfigValidator';
7
+ import { ConfigFetcher } from '../../core/ConfigFetcher';
7
8
 
8
9
  /**
9
10
  * PineconeProvider — Pinecone vector database implementation.
10
11
  */
11
12
  export class PineconeProvider extends BaseVectorProvider {
12
13
  private client!: Pinecone;
13
- private readonly apiKey: string;
14
+ private apiKey: string;
14
15
 
15
16
  constructor(config: VectorDBConfig) {
16
17
  super(config);
@@ -82,28 +83,55 @@ export class PineconeProvider extends BaseVectorProvider {
82
83
  }
83
84
 
84
85
  async initialize(): Promise<void> {
85
- const key = this.apiKey || process.env.PINECONE_API_KEY || '';
86
+ if (this.client) return;
87
+
88
+ let key = this.apiKey || process.env.PINECONE_API_KEY || '';
89
+
90
+ if (!key) {
91
+ const projectId = process.env.RAG_PROJECT_ID || process.env.NEXT_PUBLIC_RAG_PROJECT_ID || 'my-rag-app';
92
+ const licenseKey = process.env.RETRIVORA_LICENSE_KEY || process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY;
93
+
94
+ const remoteConfig = await ConfigFetcher.fetchRemoteVectorConfig(projectId, licenseKey);
95
+ if (remoteConfig?.apiKey) {
96
+ key = remoteConfig.apiKey;
97
+ this.apiKey = key;
98
+ if (remoteConfig.indexName) {
99
+ this.indexName = remoteConfig.indexName;
100
+ }
101
+ }
102
+ }
103
+
86
104
  if (!key) {
87
- console.log('[PineconeProvider] Keyless Mode active Vector operations managed via Retrivora Cloud Gateway.');
105
+ console.warn('[PineconeProvider] Warning: No Pinecone API key available locally or remotely.');
88
106
  return;
89
107
  }
108
+
90
109
  this.client = new Pinecone({ apiKey: key });
91
- const indexes = await this.client.listIndexes();
92
- const names = indexes.indexes?.map((i) => i.name) ?? [];
93
- if (!names.includes(this.indexName)) {
94
- throw new Error(
95
- `[PineconeProvider] Index "${this.indexName}" not found. Available: ${names.join(', ')}`
96
- );
110
+ try {
111
+ const indexes = await this.client.listIndexes();
112
+ const names = indexes.indexes?.map((i) => i.name) ?? [];
113
+ if (!names.includes(this.indexName)) {
114
+ console.warn(`[PineconeProvider] Target index "${this.indexName}" not listed. Proceeding with configured index name.`);
115
+ }
116
+ } catch (err) {
117
+ console.warn('[PineconeProvider] List index verification warning:', err instanceof Error ? err.message : String(err));
97
118
  }
98
119
  }
99
120
 
100
- private index(namespace?: string) {
121
+ private async getActiveIndex(namespace?: string) {
122
+ if (!this.client) {
123
+ await this.initialize();
124
+ }
125
+ if (!this.client) {
126
+ throw new Error('[PineconeProvider] Cannot execute vector operation: Pinecone client failed to initialize.');
127
+ }
101
128
  const idx = this.client.index(this.indexName);
102
129
  return namespace ? idx.namespace(namespace) : idx.namespace('');
103
130
  }
104
131
 
105
132
  async upsert(doc: UpsertDocument, namespace?: string): Promise<void> {
106
- await this.index(namespace).upsert({
133
+ const targetIdx = await this.getActiveIndex(namespace);
134
+ await targetIdx.upsert({
107
135
  records: [{
108
136
  id: String(doc.id),
109
137
  values: doc.vector,
@@ -113,6 +141,7 @@ export class PineconeProvider extends BaseVectorProvider {
113
141
  }
114
142
 
115
143
  async batchUpsert(docs: UpsertDocument[], namespace?: string): Promise<void> {
144
+ const targetIdx = await this.getActiveIndex(namespace);
116
145
  const BATCH = 100;
117
146
  for (let i = 0; i < docs.length; i += BATCH) {
118
147
  const records = docs.slice(i, i + BATCH).map((d) => ({
@@ -120,7 +149,7 @@ export class PineconeProvider extends BaseVectorProvider {
120
149
  values: d.vector,
121
150
  metadata: { content: d.content, ...(d.metadata ?? {}) } as RecordMetadata,
122
151
  }));
123
- await this.index(namespace).upsert({ records });
152
+ await targetIdx.upsert({ records });
124
153
  }
125
154
  }
126
155
 
@@ -130,8 +159,9 @@ export class PineconeProvider extends BaseVectorProvider {
130
159
  namespace?: string,
131
160
  filter?: Record<string, unknown>
132
161
  ): Promise<VectorMatch[]> {
162
+ const targetIdx = await this.getActiveIndex(namespace);
133
163
  const pineconeFilter = this.sanitizeFilter(filter);
134
- const result = await this.index(namespace).query({
164
+ const result = await targetIdx.query({
135
165
  vector,
136
166
  topK,
137
167
  includeMetadata: true,
@@ -146,15 +176,19 @@ export class PineconeProvider extends BaseVectorProvider {
146
176
  }
147
177
 
148
178
  async delete(id: string | number, namespace?: string): Promise<void> {
149
- await this.index(namespace).deleteOne({ id: String(id) });
179
+ const targetIdx = await this.getActiveIndex(namespace);
180
+ await targetIdx.deleteOne({ id: String(id) });
150
181
  }
151
182
 
152
183
  async deleteNamespace(namespace: string): Promise<void> {
153
- await this.client.index(this.indexName).namespace(namespace).deleteAll();
184
+ const targetIdx = await this.getActiveIndex(namespace);
185
+ await targetIdx.deleteAll();
154
186
  }
155
187
 
156
188
  async ping(): Promise<boolean> {
157
189
  try {
190
+ if (!this.client) await this.initialize();
191
+ if (!this.client) return false;
158
192
  await this.client.listIndexes();
159
193
  return true;
160
194
  } catch {