@retrivora-ai/rag-engine 2.0.4 → 2.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@retrivora-ai/rag-engine",
3
- "version": "2.0.4",
3
+ "version": "2.0.5",
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",
@@ -75,7 +75,7 @@
75
75
  "scripts": {
76
76
  "dev": "npx @tailwindcss/cli -i src/tailwind.css -o src/index.css && tsup src/index.ts src/handlers/index.ts src/server.ts --format cjs,esm --watch --tsconfig tsconfig.build.json --external react,react-dom,next,mongodb,pg,openai,@anthropic-ai/sdk,@pinecone-database/pinecone,axios,lucide-react,mammoth,pdf-parse,xlsx,react-markdown,remark-gfm,next-themes,langchain,@langchain/core,@langchain/openai,llamaindex --inject-style",
77
77
  "build": "npm run build:pkg",
78
- "build:pkg": "npx @tailwindcss/cli -i src/tailwind.css -o src/index.css && tsup src/index.ts src/handlers/index.ts src/server.ts --format cjs,esm --dts --clean --no-splitting --tsconfig tsconfig.build.json --external react,react-dom,next,mongodb,pg,openai,@anthropic-ai/sdk,@pinecone-database/pinecone,axios,lucide-react,mammoth,pdf-parse,xlsx,react-markdown,remark-gfm,next-themes,langchain,@langchain/core,@langchain/openai,llamaindex --inject-style && npx @tailwindcss/cli -i src/tailwind.css -o dist/index.css && rm src/index.css",
78
+ "build:pkg": "npx @tailwindcss/cli -i src/tailwind.css -o src/index.css && tsup src/index.ts src/handlers/index.ts src/server.ts --format cjs,esm --dts --clean --no-splitting --tsconfig tsconfig.build.json --external react,react-dom,next,mongodb,pg,openai,@anthropic-ai/sdk,@pinecone-database/pinecone,axios,lucide-react,mammoth,pdf-parse,xlsx,react-markdown,remark-gfm,next-themes,langchain,@langchain/core,@langchain/openai,llamaindex --inject-style && npx @tailwindcss/cli -i src/tailwind.css -o dist/index.css",
79
79
  "lint": "eslint",
80
80
  "clean": "rm -rf dist"
81
81
  },
@@ -18,7 +18,8 @@
18
18
  * universal_rest→ VECTOR_BASE_URL, VECTOR_DB_REST_API_KEY
19
19
  */
20
20
 
21
- import { RagConfig } from './RagConfig';
21
+ import { RagConfig, LLMProvider, EmbeddingProvider } from './RagConfig';
22
+ import { LicenseVerifier } from '../core/LicenseVerifier';
22
23
  import {
23
24
  VECTOR_DB_PROVIDERS,
24
25
  LLM_PROVIDERS,
@@ -78,9 +79,7 @@ export function getEnvConfig(env: Record<string, string | undefined> = process.e
78
79
  Boolean(licenseKey);
79
80
 
80
81
  const vectorProvider = readEnum(env, 'VECTOR_DB_PROVIDER', 'pinecone', VECTOR_DB_PROVIDERS);
81
- const llmProvider = readEnum(env, 'LLM_PROVIDER', 'openai', LLM_PROVIDERS);
82
- const embeddingProvider = readEnum(env, 'EMBEDDING_PROVIDER', 'openai', EMBEDDING_PROVIDERS);
83
- const embeddingDimensions = readNumber(env, 'EMBEDDING_DIMENSIONS', 1536);
82
+ const embeddingDimensions = readNumber(env, 'EMBEDDING_DIMENSIONS', 768);
84
83
 
85
84
  // Build provider-specific vectorDb options
86
85
  const vectorDbOptions: Record<string, unknown> = {};
@@ -160,9 +159,37 @@ export function getEnvConfig(env: Record<string, string | undefined> = process.e
160
159
  custom: 'default',
161
160
  };
162
161
 
162
+ // Check if the license key belongs to a Free / Trial tier
163
+ const isFreeTier = (() => {
164
+ if (!licenseKey) return true;
165
+ try {
166
+ const payload = LicenseVerifier.verify(licenseKey, projectId);
167
+ const tier = (payload.tier || '').toLowerCase();
168
+ return tier === 'free_trial' || tier === 'free_tier' || tier === 'free' || tier === 'hobby';
169
+ } catch {
170
+ return true;
171
+ }
172
+ })();
173
+
174
+ const DEFAULT_FREE_GATEWAY = 'https://llm.retrivora.com/api/v1';
175
+
176
+ const defaultLlmProvider = isFreeTier ? 'universal_rest' : 'universal_rest';
177
+ const llmProvider = (readEnum(env, 'LLM_PROVIDER', defaultLlmProvider, LLM_PROVIDERS) ?? base?.llm?.provider ?? defaultLlmProvider) as LLMProvider;
178
+ const llmBaseUrl = readString(env, 'LLM_BASE_URL') ?? base?.llm?.baseUrl ?? DEFAULT_FREE_GATEWAY;
179
+ const llmModel = readString(env, 'LLM_MODEL') ?? base?.llm?.model ?? (isFreeTier ? 'llama-3.1-8b-instant' : (DEFAULT_MODEL_BY_PROVIDER[llmProvider] ?? 'gpt-4o'));
180
+ const llmApiKey = llmApiKeyByProvider[llmProvider] ?? readString(env, 'LLM_API_KEY') ?? base?.llm?.apiKey ?? 'sk-retrivora-cancer-280590';
181
+ const llmProfile = readString(env, 'LLM_UNIVERSAL_PROFILE') ?? (base?.llm?.options?.profile as string) ?? 'litellm';
182
+
183
+ const defaultEmbeddingProvider = isFreeTier ? 'universal_rest' : 'universal_rest';
184
+ const embeddingProvider = (readEnum(env, 'EMBEDDING_PROVIDER', defaultEmbeddingProvider, EMBEDDING_PROVIDERS) ?? base?.embedding?.provider ?? defaultEmbeddingProvider) as EmbeddingProvider;
185
+ const embeddingBaseUrl = readString(env, 'EMBEDDING_BASE_URL') ?? base?.embedding?.baseUrl ?? DEFAULT_FREE_GATEWAY;
186
+ const embeddingModel = readString(env, 'EMBEDDING_MODEL') ?? base?.embedding?.model ?? 'text-embedding-004';
187
+ const embeddingApiKey = embeddingApiKeyByProvider[embeddingProvider] ?? readString(env, 'EMBEDDING_API_KEY') ?? readString(env, 'LLM_API_KEY') ?? base?.embedding?.apiKey ?? 'sk-retrivora-cancer-280590';
188
+ const embeddingProfile = readString(env, 'EMBEDDING_UNIVERSAL_PROFILE') ?? (base?.embedding?.options?.profile as string) ?? 'litellm';
189
+
163
190
  return {
164
191
  projectId,
165
- licenseKey: readString(env, 'RETRIVORA_LICENSE_KEY') ?? readString(env, 'LICENSE_KEY') ?? base?.licenseKey,
192
+ licenseKey,
166
193
  vectorDb: {
167
194
  provider: vectorProvider,
168
195
  indexName:
@@ -173,28 +200,28 @@ export function getEnvConfig(env: Record<string, string | undefined> = process.e
173
200
  },
174
201
  llm: {
175
202
  provider: llmProvider,
176
- model: readString(env, 'LLM_MODEL') ?? DEFAULT_MODEL_BY_PROVIDER[llmProvider] ?? 'gpt-4o',
177
- apiKey: llmApiKeyByProvider[llmProvider] ?? '',
178
- baseUrl: readString(env, 'LLM_BASE_URL'),
203
+ model: llmModel,
204
+ apiKey: llmApiKey,
205
+ baseUrl: llmBaseUrl,
179
206
  systemPrompt: readString(env, 'LLM_SYSTEM_PROMPT'),
180
207
  maxTokens: readNumber(env, 'LLM_MAX_TOKENS', 4096),
181
208
  temperature: readNumber(env, 'LLM_TEMPERATURE', 0.7),
182
209
  options: {
183
- profile: readString(env, 'LLM_UNIVERSAL_PROFILE'),
210
+ profile: llmProfile,
184
211
  thinking: readString(env, 'LLM_THINKING') === 'true' || readString(env, 'LLM_THINKING') === 'enabled' ? true : (readString(env, 'LLM_THINKING') === 'false' ? false : undefined),
185
212
  thinkingBudget: env.LLM_THINKING_BUDGET ? parseInt(env.LLM_THINKING_BUDGET, 10) : undefined,
186
213
  },
187
214
  },
188
215
  embedding: {
189
216
  provider: embeddingProvider,
190
- model: readString(env, 'EMBEDDING_MODEL') ?? 'text-embedding-3-small',
191
- apiKey: embeddingApiKeyByProvider[embeddingProvider],
192
- baseUrl: readString(env, 'EMBEDDING_BASE_URL'),
217
+ model: embeddingModel,
218
+ apiKey: embeddingApiKey,
219
+ baseUrl: embeddingBaseUrl,
193
220
  dimensions: embeddingDimensions,
194
221
  queryPrefix: readString(env, 'EMBEDDING_QUERY_PREFIX'),
195
222
  documentPrefix: readString(env, 'EMBEDDING_DOCUMENT_PREFIX'),
196
223
  options: {
197
- profile: readString(env, 'EMBEDDING_UNIVERSAL_PROFILE'),
224
+ profile: embeddingProfile,
198
225
  },
199
226
  },
200
227
  ui: {
@@ -271,14 +271,17 @@ export function createChatHandler(
271
271
 
272
272
  try {
273
273
  const body = await req.json();
274
- const { message: rawMessage, history = [], namespace, sessionId = 'default', messageId, userMessageId } = body as {
275
- message: string;
276
- history?: ChatMessage[];
277
- namespace?: string;
278
- sessionId?: string;
279
- messageId?: string;
280
- userMessageId?: string;
281
- };
274
+ const bodyObj = (body ?? {}) as any;
275
+ let rawMessage = bodyObj.message;
276
+ if (!rawMessage && Array.isArray(bodyObj.messages) && bodyObj.messages.length > 0) {
277
+ const lastMsg = bodyObj.messages[bodyObj.messages.length - 1];
278
+ rawMessage = typeof lastMsg === 'string' ? lastMsg : (lastMsg?.content || lastMsg?.text);
279
+ }
280
+ if (!rawMessage && typeof bodyObj.prompt === 'string') {
281
+ rawMessage = bodyObj.prompt;
282
+ }
283
+ const history = bodyObj.history || (Array.isArray(bodyObj.messages) ? bodyObj.messages.slice(0, -1) : []);
284
+ const { namespace, sessionId = 'default', messageId, userMessageId } = bodyObj;
282
285
 
283
286
  // 2. Input sanitization
284
287
  const sanitized = sanitizeInput(rawMessage ?? '');
@@ -359,7 +362,17 @@ export function createStreamHandler(
359
362
  });
360
363
  }
361
364
 
362
- const { message: rawMessage, history = [], namespace, sessionId = 'default', messageId, userMessageId } = body;
365
+ const bodyObj = (body ?? {}) as any;
366
+ let rawMessage = bodyObj.message;
367
+ if (!rawMessage && Array.isArray(bodyObj.messages) && bodyObj.messages.length > 0) {
368
+ const lastMsg = bodyObj.messages[bodyObj.messages.length - 1];
369
+ rawMessage = typeof lastMsg === 'string' ? lastMsg : (lastMsg?.content || lastMsg?.text);
370
+ }
371
+ if (!rawMessage && typeof bodyObj.prompt === 'string') {
372
+ rawMessage = bodyObj.prompt;
373
+ }
374
+ const history = bodyObj.history || (Array.isArray(bodyObj.messages) ? bodyObj.messages.slice(0, -1) : []);
375
+ const { namespace, sessionId = 'default', messageId, userMessageId } = bodyObj;
363
376
 
364
377
  // 2. Input sanitization
365
378
  const sanitized = sanitizeInput(rawMessage ?? '');