@retrivora-ai/rag-engine 2.1.3 → 2.1.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/dist/{ILLMProvider-0rRBYbVW.d.mts → ILLMProvider-BWa68XX5.d.mts} +2 -0
- package/dist/{ILLMProvider-0rRBYbVW.d.ts → ILLMProvider-BWa68XX5.d.ts} +2 -0
- package/dist/handlers/index.d.mts +2 -2
- package/dist/handlers/index.d.ts +2 -2
- package/dist/handlers/index.js +271 -67
- package/dist/handlers/index.mjs +271 -67
- package/dist/{index-B1wGUlSL.d.mts → index-BCbeeh74.d.ts} +11 -2
- package/dist/{index-DcklhThn.d.ts → index-BbJGyNmW.d.mts} +11 -2
- package/dist/{index-BIHHp_f6.d.ts → index-C6ehmP0b.d.ts} +1 -1
- package/dist/{index-BvODr57d.d.mts → index-DFc_Ll9z.d.mts} +1 -1
- package/dist/index.css +23 -0
- package/dist/index.d.mts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.js +191 -21
- package/dist/index.mjs +190 -21
- package/dist/server.d.mts +6 -6
- package/dist/server.d.ts +6 -6
- package/dist/server.js +273 -67
- package/dist/server.mjs +272 -67
- package/package.json +1 -1
- package/src/components/DocumentUpload.tsx +50 -18
- package/src/config/serverConfig.ts +2 -2
- package/src/core/Pipeline.ts +23 -1
- package/src/handlers/index.ts +65 -15
- package/src/index.css +23 -0
- package/src/index.ts +1 -0
- package/src/server.ts +1 -0
- package/src/types/index.ts +2 -0
- package/src/types/props.ts +4 -0
- package/src/version.ts +6 -0
|
@@ -12,12 +12,14 @@ interface FileState {
|
|
|
12
12
|
error?: string;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
export function DocumentUpload({ namespace, onUploadComplete, className = '' }: DocumentUploadProps) {
|
|
15
|
+
export function DocumentUpload({ namespace, uploadUrl, retrivoraApiBase, onUploadComplete, className = '' }: DocumentUploadProps) {
|
|
16
16
|
const { ui, embedding, projectId } = useConfig();
|
|
17
17
|
const [fileStates, setFileStates] = useState<FileState[]>([]);
|
|
18
18
|
const [isDragging, setIsDragging] = useState(false);
|
|
19
19
|
const fileInputRef = useRef<HTMLInputElement>(null);
|
|
20
20
|
|
|
21
|
+
const isFreeTier = !projectId || projectId.includes('free') || projectId.includes('demo');
|
|
22
|
+
|
|
21
23
|
const MULTI_DIMENSION_MODELS: Record<string, number[]> = {
|
|
22
24
|
'text-embedding-3-small': [512, 1536],
|
|
23
25
|
'text-embedding-3-large': [256, 1024, 3072],
|
|
@@ -26,18 +28,20 @@ export function DocumentUpload({ namespace, onUploadComplete, className = '' }:
|
|
|
26
28
|
|
|
27
29
|
const COMMON_DIMENSIONS = [64, 128, 256, 384, 512, 768, 1024, 1536, 3072];
|
|
28
30
|
const currentModel = embedding?.model || 'unknown';
|
|
29
|
-
const defaultDimension = embedding?.dimensions || 1536;
|
|
31
|
+
const defaultDimension = isFreeTier ? 768 : (embedding?.dimensions || 1536);
|
|
30
32
|
|
|
31
33
|
// Provide specific dimensions for known models, otherwise provide common ones
|
|
32
|
-
let availableDimensions =
|
|
34
|
+
let availableDimensions = isFreeTier
|
|
35
|
+
? [768]
|
|
36
|
+
: Object.entries(MULTI_DIMENSION_MODELS).find(([k]) => currentModel.includes(k))?.[1];
|
|
37
|
+
|
|
33
38
|
if (!availableDimensions) {
|
|
34
39
|
availableDimensions = COMMON_DIMENSIONS.includes(defaultDimension)
|
|
35
40
|
? COMMON_DIMENSIONS
|
|
36
41
|
: [...COMMON_DIMENSIONS, defaultDimension].sort((a, b) => a - b);
|
|
37
42
|
}
|
|
38
|
-
|
|
39
|
-
const isChangeable = true; // Always allow the user to select the dimension
|
|
40
43
|
|
|
44
|
+
const isChangeable = !isFreeTier;
|
|
41
45
|
const [dimension, setDimension] = useState(defaultDimension);
|
|
42
46
|
|
|
43
47
|
const addFiles = (files: File[]) => {
|
|
@@ -85,20 +89,37 @@ export function DocumentUpload({ namespace, onUploadComplete, className = '' }:
|
|
|
85
89
|
if (targetNs) formData.append('namespace', targetNs);
|
|
86
90
|
formData.append('dimension', dimension.toString());
|
|
87
91
|
|
|
92
|
+
const apiBase = retrivoraApiBase || '/api/retrivora';
|
|
93
|
+
const primaryUrl = uploadUrl || `${apiBase.replace(/\/$/, '')}/upload`;
|
|
94
|
+
|
|
95
|
+
console.log(`[Retrivora SDK] 📤 Initiating upload request to "${primaryUrl}" (Files: ${idleFiles.length}, Namespace: "${targetNs}", Dimension: ${dimension})`);
|
|
96
|
+
|
|
88
97
|
try {
|
|
89
|
-
|
|
98
|
+
let response = await fetch(primaryUrl, {
|
|
90
99
|
method: 'POST',
|
|
91
100
|
body: formData,
|
|
92
101
|
});
|
|
93
102
|
|
|
103
|
+
// Fallback resolution: if primaryUrl returns 404 and is not '/api/upload', try '/api/upload'
|
|
104
|
+
if (response.status === 404 && primaryUrl !== '/api/upload') {
|
|
105
|
+
console.warn(`[Retrivora SDK] ⚠️ Upload endpoint "${primaryUrl}" returned 404. Retrying fallback to "/api/upload"...`);
|
|
106
|
+
response = await fetch('/api/upload', {
|
|
107
|
+
method: 'POST',
|
|
108
|
+
body: formData,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
94
112
|
const result = await response.json();
|
|
95
113
|
|
|
96
|
-
if (!response.ok) throw new Error(result.error ||
|
|
114
|
+
if (!response.ok) throw new Error(result.error || `Upload failed with HTTP status ${response.status}`);
|
|
115
|
+
|
|
116
|
+
console.log(`[Retrivora SDK] ✅ Upload response success:`, result);
|
|
97
117
|
|
|
98
118
|
setFileStates(prev => prev.map(s => s.status === 'uploading' ? { ...s, status: 'success' } : s));
|
|
99
119
|
if (onUploadComplete) onUploadComplete(result);
|
|
100
|
-
} catch (err) {
|
|
120
|
+
} catch (err: any) {
|
|
101
121
|
const message = err instanceof Error ? err.message : 'Upload failed';
|
|
122
|
+
console.error(`[Retrivora SDK] ❌ Document upload failed:`, message);
|
|
102
123
|
setFileStates(prev => prev.map(s => s.status === 'uploading' ? { ...s, status: 'error', error: message } : s));
|
|
103
124
|
}
|
|
104
125
|
};
|
|
@@ -152,22 +173,33 @@ export function DocumentUpload({ namespace, onUploadComplete, className = '' }:
|
|
|
152
173
|
|
|
153
174
|
<div className="mt-6 flex flex-col items-center gap-2 text-sm">
|
|
154
175
|
<label className="text-slate-600 dark:text-white/60 font-medium">Embedding Dimension</label>
|
|
155
|
-
|
|
176
|
+
<div className="flex flex-col items-center gap-1.5">
|
|
156
177
|
<select
|
|
157
178
|
value={dimension}
|
|
158
179
|
onChange={(e) => setDimension(Number(e.target.value))}
|
|
159
180
|
disabled={isUploading}
|
|
160
|
-
className="px-3 py-1.5 rounded-lg bg-slate-50 dark:bg-white/5 border border-slate-200 dark:border-white/10 text-slate-800 dark:text-white/90 outline-none focus:border-emerald-500 transition-colors"
|
|
181
|
+
className="px-3 py-1.5 rounded-lg bg-slate-50 dark:bg-white/5 border border-slate-200 dark:border-white/10 text-slate-800 dark:text-white/90 outline-none focus:border-emerald-500 transition-colors text-sm font-medium cursor-pointer"
|
|
161
182
|
>
|
|
162
|
-
{
|
|
163
|
-
|
|
164
|
-
|
|
183
|
+
{COMMON_DIMENSIONS.map(dim => {
|
|
184
|
+
const isDisabled = isFreeTier && dim !== 768;
|
|
185
|
+
return (
|
|
186
|
+
<option
|
|
187
|
+
key={dim}
|
|
188
|
+
value={dim}
|
|
189
|
+
disabled={isDisabled}
|
|
190
|
+
className="bg-white dark:bg-slate-900 text-slate-800 dark:text-white disabled:text-slate-400 dark:disabled:text-white/30"
|
|
191
|
+
>
|
|
192
|
+
{dim} {dim === 768 ? '(Free Tier Fixed)' : isDisabled ? '(Pro/Enterprise Only)' : ''}
|
|
193
|
+
</option>
|
|
194
|
+
);
|
|
195
|
+
})}
|
|
165
196
|
</select>
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
197
|
+
{isFreeTier && (
|
|
198
|
+
<span className="text-[11px] text-amber-600 dark:text-amber-400/90 font-medium">
|
|
199
|
+
⚡ 768 Dimension active for Free Tier (Upgrade for 1536 / 3072)
|
|
200
|
+
</span>
|
|
201
|
+
)}
|
|
202
|
+
</div>
|
|
171
203
|
</div>
|
|
172
204
|
</div>
|
|
173
205
|
|
|
@@ -85,8 +85,8 @@ 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
|
-
vectorDbOptions.apiKey = readString(env, 'PINECONE_API_KEY') ?? (base?.vectorDb?.options?.apiKey as string) ?? '';
|
|
89
|
-
vectorDbOptions.indexName = readString(env, 'PINECONE_INDEX') ?? (base?.vectorDb?.indexName as string) ?? (base?.vectorDb?.options?.indexName as string);
|
|
88
|
+
vectorDbOptions.apiKey = readString(env, 'PINECONE_API_KEY') ?? (base?.vectorDb?.options?.apiKey as string) ?? process.env.PINECONE_API_KEY ?? '';
|
|
89
|
+
vectorDbOptions.indexName = readString(env, 'PINECONE_INDEX') ?? (base?.vectorDb?.indexName as string) ?? (base?.vectorDb?.options?.indexName as string) ?? process.env.PINECONE_INDEX ?? 'retrivora-free';
|
|
90
90
|
} else if (vectorProvider === 'pgvector' || vectorProvider === 'postgresql') {
|
|
91
91
|
vectorDbOptions.connectionString = readString(env, 'PGVECTOR_CONNECTION_STRING') ?? readString(env, 'POSTGRES_URL') ?? (base?.vectorDb?.options?.connectionString as string) ?? '';
|
|
92
92
|
vectorDbOptions.tables = (readString(env, 'VECTOR_DB_TABLES') ?? readString(env, 'POSTGRES_TABLES'))?.split(',').map(t => t.trim()) ?? (base?.vectorDb?.options?.tables as string[]);
|
package/src/core/Pipeline.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { BaseVectorProvider } from '../providers/vectordb/BaseVectorProvider';
|
|
2
|
+
import { SDK_VERSION } from '../version';
|
|
2
3
|
import { BaseGraphProvider } from '../providers/graphdb/BaseGraphProvider';
|
|
3
4
|
import { ILLMProvider } from '../llm/ILLMProvider';
|
|
4
5
|
import { ChatMessage } from '../types';
|
|
@@ -933,6 +934,14 @@ You are a helpful assistant. Use the provided context to answer questions accura
|
|
|
933
934
|
}
|
|
934
935
|
}
|
|
935
936
|
|
|
937
|
+
const modelName = finalTrace?.model || this.config.llm?.model || 'llama-3.1-8b-instant';
|
|
938
|
+
const providerName = finalTrace?.provider || this.config.llm?.provider || 'groq';
|
|
939
|
+
const tokenCount = Number(finalTrace?.tokens?.totalTokens || 0);
|
|
940
|
+
const costEst = Number(finalTrace?.tokens?.estimatedCostUsd || 0);
|
|
941
|
+
const latencyDuration = Number(finalTrace?.latency?.totalMs || 0);
|
|
942
|
+
|
|
943
|
+
console.log(`[Retrivora Pipeline Telemetry] 📊 Dispatching RAG telemetry -> Project: "${ns}", Model: "${providerName}/${modelName}", Tokens: ${tokenCount}, Latency: ${latencyDuration}ms`);
|
|
944
|
+
|
|
936
945
|
await fetch(absoluteUrl, {
|
|
937
946
|
method: 'POST',
|
|
938
947
|
headers: {
|
|
@@ -941,7 +950,20 @@ You are a helpful assistant. Use the provided context to answer questions accura
|
|
|
941
950
|
body: JSON.stringify({
|
|
942
951
|
trace: finalTrace,
|
|
943
952
|
licenseKey: this.config.licenseKey,
|
|
944
|
-
projectId: ns
|
|
953
|
+
projectId: ns,
|
|
954
|
+
organization: process.env.RETRIVORA_ORGANIZATION || 'default-org',
|
|
955
|
+
sdkVersion: SDK_VERSION,
|
|
956
|
+
model: modelName,
|
|
957
|
+
provider: providerName,
|
|
958
|
+
tokens: tokenCount,
|
|
959
|
+
cost: costEst,
|
|
960
|
+
costUsd: costEst,
|
|
961
|
+
latencyMs: latencyDuration,
|
|
962
|
+
status: 'success',
|
|
963
|
+
action: 'RAG_QUERY',
|
|
964
|
+
feature: 'RAG',
|
|
965
|
+
timestamp: new Date().toISOString(),
|
|
966
|
+
details: `Org: default-org | Model: ${providerName}/${modelName} | Tokens: ${tokenCount} | Latency: ${latencyDuration}ms | Cost: $${costEst} | SDK: v${SDK_VERSION} | Feature: RAG`
|
|
945
967
|
})
|
|
946
968
|
});
|
|
947
969
|
} catch (err: any) {
|
package/src/handlers/index.ts
CHANGED
|
@@ -147,6 +147,8 @@ function getOrCreatePlugin(configOrPlugin: Partial<RagConfig> | VectorPlugin | u
|
|
|
147
147
|
|
|
148
148
|
// ─── Telemetry Reporter Helper ───────────────────────────────────────────────
|
|
149
149
|
|
|
150
|
+
import { SDK_VERSION } from '../version';
|
|
151
|
+
|
|
150
152
|
/**
|
|
151
153
|
* Asynchronously sends telemetry payload to telemetryUrl when telemetry is enabled
|
|
152
154
|
* or when a licenseKey is set. Non-blocking.
|
|
@@ -157,7 +159,7 @@ function reportTelemetry(
|
|
|
157
159
|
action: string,
|
|
158
160
|
status: 'success' | 'error',
|
|
159
161
|
details: string,
|
|
160
|
-
trace?:
|
|
162
|
+
trace?: any
|
|
161
163
|
) {
|
|
162
164
|
try {
|
|
163
165
|
const config = plugin.getConfig();
|
|
@@ -171,6 +173,7 @@ function reportTelemetry(
|
|
|
171
173
|
|
|
172
174
|
const telemetryUrl = telemetryConfig?.url || process.env.TELEMETRY_URL || process.env.NEXT_PUBLIC_TELEMETRY_URL || defaultUrl;
|
|
173
175
|
const host = req.headers.get('host') || 'localhost';
|
|
176
|
+
const userAgent = req.headers.get('user-agent') || `Retrivora-SDK/${SDK_VERSION}`;
|
|
174
177
|
|
|
175
178
|
let absoluteUrl = telemetryUrl;
|
|
176
179
|
if (!telemetryUrl.startsWith('http')) {
|
|
@@ -179,6 +182,33 @@ function reportTelemetry(
|
|
|
179
182
|
}
|
|
180
183
|
|
|
181
184
|
const projectId = config.projectId || 'default';
|
|
185
|
+
const model = trace?.model || config.llm?.model || config.embedding?.model || 'llama-3.1-8b-instant';
|
|
186
|
+
const provider = trace?.provider || config.llm?.provider || config.embedding?.provider || 'groq';
|
|
187
|
+
const tokens = Number(trace?.tokens?.totalTokens || trace?.totalTokens || 0);
|
|
188
|
+
const costUsd = Number(trace?.tokens?.estimatedCostUsd || trace?.costUsd || 0);
|
|
189
|
+
const latencyMs = Number(trace?.latency?.totalMs || trace?.latencyMs || 0);
|
|
190
|
+
|
|
191
|
+
const payload = {
|
|
192
|
+
trace,
|
|
193
|
+
licenseKey,
|
|
194
|
+
projectId,
|
|
195
|
+
organization: process.env.RETRIVORA_ORGANIZATION || 'default-org',
|
|
196
|
+
sdkVersion: SDK_VERSION,
|
|
197
|
+
model,
|
|
198
|
+
provider,
|
|
199
|
+
tokens,
|
|
200
|
+
cost: costUsd,
|
|
201
|
+
costUsd,
|
|
202
|
+
latencyMs,
|
|
203
|
+
status,
|
|
204
|
+
action,
|
|
205
|
+
feature: action,
|
|
206
|
+
userAgent,
|
|
207
|
+
timestamp: new Date().toISOString(),
|
|
208
|
+
details,
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
console.log(`[Retrivora SDK Telemetry] 📊 Dispatching telemetry -> Feature: "${action}", Status: "${status}", Project: "${projectId}", Model: "${provider}/${model}", Latency: ${latencyMs}ms`);
|
|
182
212
|
|
|
183
213
|
fetch(absoluteUrl, {
|
|
184
214
|
method: 'POST',
|
|
@@ -186,17 +216,11 @@ function reportTelemetry(
|
|
|
186
216
|
'Content-Type': 'application/json',
|
|
187
217
|
'x-forwarded-for': req.headers.get('x-forwarded-for') || '',
|
|
188
218
|
'x-real-ip': req.headers.get('x-real-ip') || '',
|
|
219
|
+
'user-agent': userAgent,
|
|
189
220
|
},
|
|
190
|
-
body: JSON.stringify(
|
|
191
|
-
trace,
|
|
192
|
-
licenseKey,
|
|
193
|
-
projectId,
|
|
194
|
-
action,
|
|
195
|
-
status,
|
|
196
|
-
details,
|
|
197
|
-
}),
|
|
221
|
+
body: JSON.stringify(payload),
|
|
198
222
|
}).catch(err => {
|
|
199
|
-
console.warn('[Retrivora Telemetry] Async report warning:', err.message);
|
|
223
|
+
console.warn('[Retrivora SDK Telemetry] Async report warning:', err.message);
|
|
200
224
|
});
|
|
201
225
|
} catch {
|
|
202
226
|
/* non-blocking */
|
|
@@ -354,6 +378,12 @@ export function createStreamHandler(
|
|
|
354
378
|
userMessageId?: string;
|
|
355
379
|
};
|
|
356
380
|
try {
|
|
381
|
+
if (req.headers.get('content-type')?.includes('multipart/form-data')) {
|
|
382
|
+
return new Response(JSON.stringify({ error: { code: 'INVALID_ENDPOINT', message: 'Multipart file upload requests must be sent to the /upload endpoint.' } }), {
|
|
383
|
+
status: 400,
|
|
384
|
+
headers: { 'Content-Type': 'application/json' },
|
|
385
|
+
});
|
|
386
|
+
}
|
|
357
387
|
body = await req.json();
|
|
358
388
|
} catch {
|
|
359
389
|
return new Response(JSON.stringify({ error: { code: 'INVALID_JSON', message: 'Invalid JSON body' } }), {
|
|
@@ -937,19 +967,39 @@ export function createRagHandler(
|
|
|
937
967
|
}
|
|
938
968
|
}
|
|
939
969
|
|
|
940
|
-
async function getSegment(context: any): Promise<string> {
|
|
970
|
+
async function getSegment(req: NextRequest, context: any): Promise<string> {
|
|
971
|
+
// 1. If content-type is multipart/form-data, it MUST be an upload request!
|
|
972
|
+
const contentType = req.headers.get('content-type') || '';
|
|
973
|
+
if (contentType.includes('multipart/form-data')) {
|
|
974
|
+
return 'upload';
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
// 2. Check path directly from request URL
|
|
978
|
+
try {
|
|
979
|
+
const url = new URL(req.url);
|
|
980
|
+
const pathname = url.pathname;
|
|
981
|
+
if (pathname.endsWith('/upload')) return 'upload';
|
|
982
|
+
if (pathname.endsWith('/chat') || pathname.endsWith('/chat-sync')) return 'chat';
|
|
983
|
+
if (pathname.endsWith('/health')) return 'health';
|
|
984
|
+
if (pathname.endsWith('/suggestions')) return 'suggestions';
|
|
985
|
+
if (pathname.endsWith('/feedback')) return 'feedback';
|
|
986
|
+
if (pathname.endsWith('/history')) return 'history';
|
|
987
|
+
} catch { /* silent */ }
|
|
988
|
+
|
|
989
|
+
// 3. Fall back to resolved context params
|
|
941
990
|
const resolvedParams = typeof context?.params?.then === 'function'
|
|
942
991
|
? await context.params
|
|
943
992
|
: context?.params;
|
|
944
993
|
|
|
945
|
-
const segments: string[] = resolvedParams?.retrivora || [];
|
|
946
|
-
|
|
994
|
+
const segments: string[] = resolvedParams?.retrivora || resolvedParams?.params?.retrivora || [];
|
|
995
|
+
const joined = segments.join('/');
|
|
996
|
+
return joined || 'chat';
|
|
947
997
|
}
|
|
948
998
|
|
|
949
999
|
return {
|
|
950
1000
|
GET: async (req: NextRequest, context: any) => {
|
|
951
1001
|
try {
|
|
952
|
-
const segment = await getSegment(context);
|
|
1002
|
+
const segment = await getSegment(req, context);
|
|
953
1003
|
return await routeGetRequest(req, segment);
|
|
954
1004
|
} catch (err) {
|
|
955
1005
|
const msg = err instanceof Error ? err.message : 'GET Routing failed';
|
|
@@ -958,7 +1008,7 @@ export function createRagHandler(
|
|
|
958
1008
|
},
|
|
959
1009
|
POST: async (req: NextRequest, context: any) => {
|
|
960
1010
|
try {
|
|
961
|
-
const segment = await getSegment(context);
|
|
1011
|
+
const segment = await getSegment(req, context);
|
|
962
1012
|
return await routePostRequest(req, segment);
|
|
963
1013
|
} catch (err) {
|
|
964
1014
|
const msg = err instanceof Error ? err.message : 'POST Routing failed';
|
package/src/index.css
CHANGED
|
@@ -2259,6 +2259,11 @@
|
|
|
2259
2259
|
cursor: not-allowed;
|
|
2260
2260
|
}
|
|
2261
2261
|
}
|
|
2262
|
+
.disabled\:text-slate-400 {
|
|
2263
|
+
&:disabled {
|
|
2264
|
+
color: var(--color-slate-400);
|
|
2265
|
+
}
|
|
2266
|
+
}
|
|
2262
2267
|
.disabled\:opacity-30 {
|
|
2263
2268
|
&:disabled {
|
|
2264
2269
|
opacity: 30%;
|
|
@@ -2912,6 +2917,14 @@
|
|
|
2912
2917
|
color: var(--color-amber-400);
|
|
2913
2918
|
}
|
|
2914
2919
|
}
|
|
2920
|
+
.dark\:text-amber-400\/90 {
|
|
2921
|
+
@media (prefers-color-scheme: dark) {
|
|
2922
|
+
color: color-mix(in srgb, oklch(82.8% 0.189 84.429) 90%, transparent);
|
|
2923
|
+
@supports (color: color-mix(in lab, red, red)) {
|
|
2924
|
+
color: color-mix(in oklab, var(--color-amber-400) 90%, transparent);
|
|
2925
|
+
}
|
|
2926
|
+
}
|
|
2927
|
+
}
|
|
2915
2928
|
.dark\:text-blue-100 {
|
|
2916
2929
|
@media (prefers-color-scheme: dark) {
|
|
2917
2930
|
color: var(--color-blue-100);
|
|
@@ -3371,6 +3384,16 @@
|
|
|
3371
3384
|
}
|
|
3372
3385
|
}
|
|
3373
3386
|
}
|
|
3387
|
+
.dark\:disabled\:text-white\/30 {
|
|
3388
|
+
@media (prefers-color-scheme: dark) {
|
|
3389
|
+
&:disabled {
|
|
3390
|
+
color: color-mix(in srgb, #fff 30%, transparent);
|
|
3391
|
+
@supports (color: color-mix(in lab, red, red)) {
|
|
3392
|
+
color: color-mix(in oklab, var(--color-white) 30%, transparent);
|
|
3393
|
+
}
|
|
3394
|
+
}
|
|
3395
|
+
}
|
|
3396
|
+
}
|
|
3374
3397
|
}
|
|
3375
3398
|
@layer base {
|
|
3376
3399
|
:root {
|
package/src/index.ts
CHANGED
|
@@ -15,6 +15,7 @@ export { MessageBubble } from './components/MessageBubble';
|
|
|
15
15
|
export { SourceCard } from './components/SourceCard';
|
|
16
16
|
export { ObservabilityPanel } from './components/ObservabilityPanel';
|
|
17
17
|
export { ConfigProvider, useConfig } from './components/ConfigProvider';
|
|
18
|
+
export { SDK_VERSION } from './version';
|
|
18
19
|
export { CodeViewer } from './components/CodeViewer';
|
|
19
20
|
export { ProductCard } from './components/ProductCard';
|
|
20
21
|
export { ProductCarousel } from './components/ProductCarousel';
|
package/src/server.ts
CHANGED
|
@@ -36,6 +36,7 @@ export { ConfigResolver } from './core/ConfigResolver';
|
|
|
36
36
|
export { ProviderRegistry } from './core/ProviderRegistry';
|
|
37
37
|
export { ConfigValidator } from './core/ConfigValidator';
|
|
38
38
|
export { LicenseVerifier } from './core/LicenseVerifier';
|
|
39
|
+
export { SDK_VERSION } from './version';
|
|
39
40
|
export { ProviderHealthCheck } from './core/ProviderHealthCheck';
|
|
40
41
|
export { BatchProcessor } from './core/BatchProcessor';
|
|
41
42
|
|
package/src/types/index.ts
CHANGED
|
@@ -40,6 +40,8 @@ export interface ObservabilityTrace {
|
|
|
40
40
|
chunks: RetrievedChunk[];
|
|
41
41
|
latency: LatencyBreakdown;
|
|
42
42
|
tokens?: TokenUsage;
|
|
43
|
+
model?: string;
|
|
44
|
+
provider?: string;
|
|
43
45
|
/** 0 = fully grounded, 1 = likely hallucinated. */
|
|
44
46
|
hallucinationScore?: number;
|
|
45
47
|
hallucinationReason?: string;
|
package/src/types/props.ts
CHANGED
|
@@ -109,6 +109,10 @@ export interface ProductCarouselProps {
|
|
|
109
109
|
export interface DocumentUploadProps {
|
|
110
110
|
/** Optional namespace for the upload */
|
|
111
111
|
namespace?: string;
|
|
112
|
+
/** Custom upload API endpoint URL (defaults to /api/retrivora/upload or /api/upload) */
|
|
113
|
+
uploadUrl?: string;
|
|
114
|
+
/** Base URL for Retrivora SDK endpoints (defaults to /api/retrivora) */
|
|
115
|
+
retrivoraApiBase?: string;
|
|
112
116
|
/** Callback when upload completes */
|
|
113
117
|
onUploadComplete?: (results: unknown) => void;
|
|
114
118
|
/** Additional className */
|