@retrivora-ai/rag-engine 1.8.0 → 1.8.2

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.
Files changed (71) hide show
  1. package/dist/DocumentChunker-Dh9TvmGG.d.mts +45 -0
  2. package/dist/DocumentChunker-Dh9TvmGG.d.ts +45 -0
  3. package/dist/{index-DPsQodME.d.mts → ILLMProvider-BOJFz3Na.d.mts} +104 -1
  4. package/dist/{index-DPsQodME.d.ts → ILLMProvider-BOJFz3Na.d.ts} +104 -1
  5. package/dist/MultiTablePostgresProvider-ZLGSKTJR.mjs +8 -0
  6. package/dist/chunk-ICKRMZQK.mjs +76 -0
  7. package/dist/{chunk-PV3MFHWU.mjs → chunk-LZVVLSDN.mjs} +977 -516
  8. package/dist/chunk-OZFBG4BA.mjs +291 -0
  9. package/dist/handlers/index.d.mts +2 -2
  10. package/dist/handlers/index.d.ts +2 -2
  11. package/dist/handlers/index.js +1269 -656
  12. package/dist/handlers/index.mjs +4 -1
  13. package/dist/{index-Bb2yEopi.d.mts → index-BwpcaziY.d.ts} +10 -2
  14. package/dist/{index-CkbTzj9J.d.ts → index-D3V9Et2M.d.mts} +10 -2
  15. package/dist/index.d.mts +24 -4
  16. package/dist/index.d.ts +24 -4
  17. package/dist/index.js +1354 -826
  18. package/dist/index.mjs +1284 -795
  19. package/dist/server.d.mts +47 -27
  20. package/dist/server.d.ts +47 -27
  21. package/dist/server.js +1417 -829
  22. package/dist/server.mjs +164 -176
  23. package/package.json +6 -2
  24. package/src/app/api/upload/route.ts +4 -0
  25. package/src/app/constants.tsx +2 -2
  26. package/src/app/page.tsx +12 -322
  27. package/src/components/AmbientBackground.tsx +29 -0
  28. package/src/components/ArchitectureCard.tsx +17 -0
  29. package/src/components/ArchitectureCardsSection.tsx +15 -0
  30. package/src/components/ChatWindow.tsx +32 -0
  31. package/src/components/CodeViewer.tsx +51 -0
  32. package/src/components/ConfigProvider.tsx +1 -0
  33. package/src/components/DocViewer.tsx +37 -0
  34. package/src/components/DocumentUpload.tsx +44 -1
  35. package/src/components/Documentation.tsx +58 -0
  36. package/src/components/DynamicChart.tsx +27 -2
  37. package/src/components/Hero.tsx +59 -0
  38. package/src/components/HourglassLoader.tsx +87 -0
  39. package/src/components/Lifecycle.tsx +37 -0
  40. package/src/components/MarkdownComponents.tsx +140 -0
  41. package/src/components/MessageBubble.tsx +124 -904
  42. package/src/components/Navbar.tsx +55 -0
  43. package/src/components/ObservabilityPanel.tsx +374 -0
  44. package/src/components/ProductCard.tsx +5 -3
  45. package/src/components/UIDispatcher.tsx +344 -0
  46. package/src/components/VisualizationRenderer.tsx +372 -250
  47. package/src/config/RagConfig.ts +5 -0
  48. package/src/config/serverConfig.ts +3 -1
  49. package/src/core/Pipeline.ts +240 -271
  50. package/src/core/ProviderRegistry.ts +2 -2
  51. package/src/core/VectorPlugin.ts +9 -0
  52. package/src/handlers/index.ts +91 -15
  53. package/src/hooks/useRagChat.ts +21 -11
  54. package/src/index.ts +9 -1
  55. package/src/llm/LLMFactory.ts +54 -2
  56. package/src/llm/providers/AnthropicProvider.ts +12 -8
  57. package/src/llm/providers/GeminiProvider.ts +188 -143
  58. package/src/llm/providers/OllamaProvider.ts +7 -3
  59. package/src/llm/providers/OpenAIProvider.ts +12 -8
  60. package/src/providers/vectordb/MultiTablePostgresProvider.ts +150 -64
  61. package/src/types/chat.ts +8 -0
  62. package/src/types/index.ts +132 -0
  63. package/src/types/props.ts +9 -1
  64. package/src/utils/ProductExtractor.ts +347 -0
  65. package/src/utils/SchemaMapper.ts +129 -0
  66. package/src/utils/UITransformer.ts +470 -209
  67. package/src/utils/synonyms.ts +78 -0
  68. package/dist/DocumentChunker-C1GEEosY.d.ts +0 -93
  69. package/dist/DocumentChunker-CFEiRopR.d.mts +0 -93
  70. package/dist/PostgreSQLProvider-BMOETDZA.mjs +0 -8
  71. package/dist/chunk-FLOSGE6A.mjs +0 -202
@@ -0,0 +1,45 @@
1
+ /**
2
+ * DocumentChunker — splits long text into overlapping chunks
3
+ * suitable for vector embedding and retrieval.
4
+ *
5
+ * Strategy: sentence-aware sliding window
6
+ * 1. Split on sentence boundaries
7
+ * 2. Accumulate sentences into chunks up to `chunkSize` characters
8
+ * 3. Carry over `chunkOverlap` characters from the previous chunk
9
+ */
10
+ interface Chunk {
11
+ id: string;
12
+ content: string;
13
+ metadata?: Record<string, unknown>;
14
+ }
15
+ interface ChunkOptions {
16
+ /** Target chunk size in characters (default 1000) */
17
+ chunkSize?: number;
18
+ /** Overlap between consecutive chunks in characters (default 200) */
19
+ chunkOverlap?: number;
20
+ /** Source document identifier used as ID prefix */
21
+ docId?: string | number;
22
+ /** Extra metadata to attach to every chunk */
23
+ metadata?: Record<string, unknown>;
24
+ /** Characters used to split text, in order of priority */
25
+ separators?: string[];
26
+ }
27
+ declare class DocumentChunker {
28
+ private readonly chunkSize;
29
+ private readonly chunkOverlap;
30
+ private readonly separators;
31
+ constructor(chunkSize?: number, chunkOverlap?: number, separators?: string[]);
32
+ /**
33
+ * Split a single text string into overlapping chunks using a recursive strategy.
34
+ * Preserves structural boundaries (Markdown headers) where possible.
35
+ */
36
+ chunk(text: string, options?: ChunkOptions): Chunk[];
37
+ private recursiveSplit;
38
+ chunkMany(documents: Array<{
39
+ content: string;
40
+ docId?: string | number;
41
+ metadata?: Record<string, unknown>;
42
+ }>): Chunk[];
43
+ }
44
+
45
+ export { type Chunk as C, DocumentChunker as D, type ChunkOptions as a };
@@ -0,0 +1,45 @@
1
+ /**
2
+ * DocumentChunker — splits long text into overlapping chunks
3
+ * suitable for vector embedding and retrieval.
4
+ *
5
+ * Strategy: sentence-aware sliding window
6
+ * 1. Split on sentence boundaries
7
+ * 2. Accumulate sentences into chunks up to `chunkSize` characters
8
+ * 3. Carry over `chunkOverlap` characters from the previous chunk
9
+ */
10
+ interface Chunk {
11
+ id: string;
12
+ content: string;
13
+ metadata?: Record<string, unknown>;
14
+ }
15
+ interface ChunkOptions {
16
+ /** Target chunk size in characters (default 1000) */
17
+ chunkSize?: number;
18
+ /** Overlap between consecutive chunks in characters (default 200) */
19
+ chunkOverlap?: number;
20
+ /** Source document identifier used as ID prefix */
21
+ docId?: string | number;
22
+ /** Extra metadata to attach to every chunk */
23
+ metadata?: Record<string, unknown>;
24
+ /** Characters used to split text, in order of priority */
25
+ separators?: string[];
26
+ }
27
+ declare class DocumentChunker {
28
+ private readonly chunkSize;
29
+ private readonly chunkOverlap;
30
+ private readonly separators;
31
+ constructor(chunkSize?: number, chunkOverlap?: number, separators?: string[]);
32
+ /**
33
+ * Split a single text string into overlapping chunks using a recursive strategy.
34
+ * Preserves structural boundaries (Markdown headers) where possible.
35
+ */
36
+ chunk(text: string, options?: ChunkOptions): Chunk[];
37
+ private recursiveSplit;
38
+ chunkMany(documents: Array<{
39
+ content: string;
40
+ docId?: string | number;
41
+ metadata?: Record<string, unknown>;
42
+ }>): Chunk[];
43
+ }
44
+
45
+ export { type Chunk as C, DocumentChunker as D, type ChunkOptions as a };
@@ -7,6 +7,8 @@ interface RagMessage extends ChatMessage {
7
7
  id: string;
8
8
  sources?: VectorMatch[];
9
9
  uiTransformation?: unknown;
10
+ /** Full observability trace emitted by the backend. Only present on assistant messages. */
11
+ trace?: ObservabilityTrace;
10
12
  createdAt: string;
11
13
  }
12
14
  interface ChatOptions {
@@ -16,6 +18,12 @@ interface ChatOptions {
16
18
  temperature?: number;
17
19
  /** Stop sequences */
18
20
  stop?: string[];
21
+ /**
22
+ * Per-call system prompt override. When provided, providers should use this
23
+ * instead of (or in addition to) their configured llmConfig.systemPrompt.
24
+ * Useful for one-off analytical calls (e.g. UITransformer.analyzeAndDecide).
25
+ */
26
+ systemPrompt?: string;
19
27
  }
20
28
  interface UseRagChatOptions {
21
29
  /** Override the chat API endpoint (default: /api/chat) */
@@ -201,6 +209,11 @@ interface RAGConfig {
201
209
  * Used to dynamically extract hints from natural language queries.
202
210
  */
203
211
  filterableFields?: string[];
212
+ /** Optional mapping from database metadata fields to standard UI properties.
213
+ * Useful for databases with custom schemas.
214
+ * e.g., { "name": "ProductName", "price": "SalesPrice", "image": "ThumbnailUrl" }
215
+ */
216
+ uiMapping?: Record<string, string>;
204
217
  }
205
218
  interface RagConfig {
206
219
  /**
@@ -222,6 +235,48 @@ interface RagConfig {
222
235
  graphDb?: GraphDBConfig;
223
236
  }
224
237
 
238
+ /** Per-stage latency breakdown for a single RAG request. */
239
+ interface LatencyBreakdown {
240
+ embedMs: number;
241
+ retrieveMs: number;
242
+ rerankMs?: number;
243
+ generateMs: number;
244
+ totalMs: number;
245
+ }
246
+ /** Token usage reported by the LLM (or estimated when the provider doesn't expose it). */
247
+ interface TokenUsage {
248
+ promptTokens: number;
249
+ completionTokens: number;
250
+ totalTokens: number;
251
+ /** Rough cost in USD — estimated from token counts and model pricing. */
252
+ estimatedCostUsd?: number;
253
+ }
254
+ /** A single retrieved chunk annotated with its retrieval context. */
255
+ interface RetrievedChunk {
256
+ id: string | number;
257
+ score: number;
258
+ content: string;
259
+ metadata: Record<string, unknown>;
260
+ namespace: string;
261
+ }
262
+ /**
263
+ * Full observability trace for one RAG request.
264
+ * Emitted by the backend as an SSE frame and stored on each RagMessage.
265
+ */
266
+ interface ObservabilityTrace {
267
+ requestId: string;
268
+ query: string;
269
+ rewrittenQuery?: string;
270
+ systemPrompt: string;
271
+ userPrompt: string;
272
+ chunks: RetrievedChunk[];
273
+ latency: LatencyBreakdown;
274
+ tokens?: TokenUsage;
275
+ /** 0 = fully grounded, 1 = likely hallucinated. */
276
+ hallucinationScore?: number;
277
+ hallucinationReason?: string;
278
+ timestamp: string;
279
+ }
225
280
  interface VectorMatch {
226
281
  id: string | number;
227
282
  score: number;
@@ -244,6 +299,8 @@ interface ChatResponse {
244
299
  sources: VectorMatch[];
245
300
  graphData?: GraphSearchResult;
246
301
  ui_transformation?: unknown;
302
+ /** Observability trace — populated by the instrumented Pipeline. */
303
+ trace?: ObservabilityTrace;
247
304
  }
248
305
  interface GraphNode {
249
306
  id: string;
@@ -274,4 +331,50 @@ interface Product {
274
331
  description?: string;
275
332
  }
276
333
 
277
- export type { ChatMessage as C, EmbeddingConfig as E, GraphDBConfig as G, IngestDocument as I, LLMConfig as L, Product as P, RagMessage as R, UIConfig as U, VectorMatch as V, UseRagChatOptions as a, UseRagChatReturn as b, ChatOptions as c, ChatResponse as d, EmbeddingProvider as e, LLMProvider as f, RAGConfig as g, RagConfig as h, UpsertDocument as i, VectorDBConfig as j, VectorDBProvider as k, RetrievalResult as l, GraphNode as m, Edge as n, GraphSearchResult as o };
334
+ /**
335
+ * Generic LLM Provider interface.
336
+ * Covers both chat completion and embedding generation so a single
337
+ * provider can handle both responsibilities when appropriate.
338
+ */
339
+
340
+ interface EmbedOptions {
341
+ /** Override model for this specific embed call */
342
+ model?: string;
343
+ /** Specify the task type for models that require prefixes (e.g. nomic-embed-text) */
344
+ taskType?: 'query' | 'document';
345
+ }
346
+ interface ILLMProvider {
347
+ /**
348
+ * Send a chat completion request.
349
+ * @param messages – the full conversation history
350
+ * @param context – retrieved RAG context to inject
351
+ * @param options – optional per-call overrides
352
+ * @returns – the assistant's reply text
353
+ */
354
+ chat(messages: ChatMessage[], context: string, options?: ChatOptions): Promise<string>;
355
+ /**
356
+ * Send a streaming chat completion request.
357
+ * @returns – an async iterable of text chunks
358
+ */
359
+ chatStream?(messages: ChatMessage[], context: string, options?: ChatOptions): AsyncIterable<string>;
360
+ /**
361
+ * Generate an embedding vector for the given text.
362
+ * @param text – text to embed
363
+ * @param options – optional overrides
364
+ * @returns – float array (the embedding)
365
+ */
366
+ embed(text: string, options?: EmbedOptions): Promise<number[]>;
367
+ /**
368
+ * Generate embedding vectors for multiple texts in a single batch.
369
+ * @param texts – array of texts to embed
370
+ * @param options – optional overrides
371
+ * @returns – array of float arrays
372
+ */
373
+ batchEmbed(texts: string[], options?: EmbedOptions): Promise<number[][]>;
374
+ /**
375
+ * Check if the provider endpoint is reachable.
376
+ */
377
+ ping(): Promise<boolean>;
378
+ }
379
+
380
+ export type { ChatMessage as C, EmbedOptions as E, GraphDBConfig as G, ILLMProvider as I, LLMConfig as L, ObservabilityTrace as O, Product as P, RagMessage as R, TokenUsage as T, UIConfig as U, VectorMatch as V, UseRagChatOptions as a, UseRagChatReturn as b, ChatOptions as c, ChatResponse as d, EmbeddingConfig as e, EmbeddingProvider as f, IngestDocument as g, LLMProvider as h, LatencyBreakdown as i, RAGConfig as j, RagConfig as k, RetrievedChunk as l, UpsertDocument as m, VectorDBConfig as n, VectorDBProvider as o, RetrievalResult as p, GraphNode as q, Edge as r, GraphSearchResult as s };
@@ -7,6 +7,8 @@ interface RagMessage extends ChatMessage {
7
7
  id: string;
8
8
  sources?: VectorMatch[];
9
9
  uiTransformation?: unknown;
10
+ /** Full observability trace emitted by the backend. Only present on assistant messages. */
11
+ trace?: ObservabilityTrace;
10
12
  createdAt: string;
11
13
  }
12
14
  interface ChatOptions {
@@ -16,6 +18,12 @@ interface ChatOptions {
16
18
  temperature?: number;
17
19
  /** Stop sequences */
18
20
  stop?: string[];
21
+ /**
22
+ * Per-call system prompt override. When provided, providers should use this
23
+ * instead of (or in addition to) their configured llmConfig.systemPrompt.
24
+ * Useful for one-off analytical calls (e.g. UITransformer.analyzeAndDecide).
25
+ */
26
+ systemPrompt?: string;
19
27
  }
20
28
  interface UseRagChatOptions {
21
29
  /** Override the chat API endpoint (default: /api/chat) */
@@ -201,6 +209,11 @@ interface RAGConfig {
201
209
  * Used to dynamically extract hints from natural language queries.
202
210
  */
203
211
  filterableFields?: string[];
212
+ /** Optional mapping from database metadata fields to standard UI properties.
213
+ * Useful for databases with custom schemas.
214
+ * e.g., { "name": "ProductName", "price": "SalesPrice", "image": "ThumbnailUrl" }
215
+ */
216
+ uiMapping?: Record<string, string>;
204
217
  }
205
218
  interface RagConfig {
206
219
  /**
@@ -222,6 +235,48 @@ interface RagConfig {
222
235
  graphDb?: GraphDBConfig;
223
236
  }
224
237
 
238
+ /** Per-stage latency breakdown for a single RAG request. */
239
+ interface LatencyBreakdown {
240
+ embedMs: number;
241
+ retrieveMs: number;
242
+ rerankMs?: number;
243
+ generateMs: number;
244
+ totalMs: number;
245
+ }
246
+ /** Token usage reported by the LLM (or estimated when the provider doesn't expose it). */
247
+ interface TokenUsage {
248
+ promptTokens: number;
249
+ completionTokens: number;
250
+ totalTokens: number;
251
+ /** Rough cost in USD — estimated from token counts and model pricing. */
252
+ estimatedCostUsd?: number;
253
+ }
254
+ /** A single retrieved chunk annotated with its retrieval context. */
255
+ interface RetrievedChunk {
256
+ id: string | number;
257
+ score: number;
258
+ content: string;
259
+ metadata: Record<string, unknown>;
260
+ namespace: string;
261
+ }
262
+ /**
263
+ * Full observability trace for one RAG request.
264
+ * Emitted by the backend as an SSE frame and stored on each RagMessage.
265
+ */
266
+ interface ObservabilityTrace {
267
+ requestId: string;
268
+ query: string;
269
+ rewrittenQuery?: string;
270
+ systemPrompt: string;
271
+ userPrompt: string;
272
+ chunks: RetrievedChunk[];
273
+ latency: LatencyBreakdown;
274
+ tokens?: TokenUsage;
275
+ /** 0 = fully grounded, 1 = likely hallucinated. */
276
+ hallucinationScore?: number;
277
+ hallucinationReason?: string;
278
+ timestamp: string;
279
+ }
225
280
  interface VectorMatch {
226
281
  id: string | number;
227
282
  score: number;
@@ -244,6 +299,8 @@ interface ChatResponse {
244
299
  sources: VectorMatch[];
245
300
  graphData?: GraphSearchResult;
246
301
  ui_transformation?: unknown;
302
+ /** Observability trace — populated by the instrumented Pipeline. */
303
+ trace?: ObservabilityTrace;
247
304
  }
248
305
  interface GraphNode {
249
306
  id: string;
@@ -274,4 +331,50 @@ interface Product {
274
331
  description?: string;
275
332
  }
276
333
 
277
- export type { ChatMessage as C, EmbeddingConfig as E, GraphDBConfig as G, IngestDocument as I, LLMConfig as L, Product as P, RagMessage as R, UIConfig as U, VectorMatch as V, UseRagChatOptions as a, UseRagChatReturn as b, ChatOptions as c, ChatResponse as d, EmbeddingProvider as e, LLMProvider as f, RAGConfig as g, RagConfig as h, UpsertDocument as i, VectorDBConfig as j, VectorDBProvider as k, RetrievalResult as l, GraphNode as m, Edge as n, GraphSearchResult as o };
334
+ /**
335
+ * Generic LLM Provider interface.
336
+ * Covers both chat completion and embedding generation so a single
337
+ * provider can handle both responsibilities when appropriate.
338
+ */
339
+
340
+ interface EmbedOptions {
341
+ /** Override model for this specific embed call */
342
+ model?: string;
343
+ /** Specify the task type for models that require prefixes (e.g. nomic-embed-text) */
344
+ taskType?: 'query' | 'document';
345
+ }
346
+ interface ILLMProvider {
347
+ /**
348
+ * Send a chat completion request.
349
+ * @param messages – the full conversation history
350
+ * @param context – retrieved RAG context to inject
351
+ * @param options – optional per-call overrides
352
+ * @returns – the assistant's reply text
353
+ */
354
+ chat(messages: ChatMessage[], context: string, options?: ChatOptions): Promise<string>;
355
+ /**
356
+ * Send a streaming chat completion request.
357
+ * @returns – an async iterable of text chunks
358
+ */
359
+ chatStream?(messages: ChatMessage[], context: string, options?: ChatOptions): AsyncIterable<string>;
360
+ /**
361
+ * Generate an embedding vector for the given text.
362
+ * @param text – text to embed
363
+ * @param options – optional overrides
364
+ * @returns – float array (the embedding)
365
+ */
366
+ embed(text: string, options?: EmbedOptions): Promise<number[]>;
367
+ /**
368
+ * Generate embedding vectors for multiple texts in a single batch.
369
+ * @param texts – array of texts to embed
370
+ * @param options – optional overrides
371
+ * @returns – array of float arrays
372
+ */
373
+ batchEmbed(texts: string[], options?: EmbedOptions): Promise<number[][]>;
374
+ /**
375
+ * Check if the provider endpoint is reachable.
376
+ */
377
+ ping(): Promise<boolean>;
378
+ }
379
+
380
+ export type { ChatMessage as C, EmbedOptions as E, GraphDBConfig as G, ILLMProvider as I, LLMConfig as L, ObservabilityTrace as O, Product as P, RagMessage as R, TokenUsage as T, UIConfig as U, VectorMatch as V, UseRagChatOptions as a, UseRagChatReturn as b, ChatOptions as c, ChatResponse as d, EmbeddingConfig as e, EmbeddingProvider as f, IngestDocument as g, LLMProvider as h, LatencyBreakdown as i, RAGConfig as j, RagConfig as k, RetrievedChunk as l, UpsertDocument as m, VectorDBConfig as n, VectorDBProvider as o, RetrievalResult as p, GraphNode as q, Edge as r, GraphSearchResult as s };
@@ -0,0 +1,8 @@
1
+ import {
2
+ MultiTablePostgresProvider
3
+ } from "./chunk-OZFBG4BA.mjs";
4
+ import "./chunk-IMP6FUCY.mjs";
5
+ import "./chunk-X4TOT24V.mjs";
6
+ export {
7
+ MultiTablePostgresProvider
8
+ };
@@ -0,0 +1,76 @@
1
+ // src/utils/synonyms.ts
2
+ var FIELD_SYNONYMS = {
3
+ name: ["product", "item", "title", "label", "heading", "subject", "product name", "item name"],
4
+ price: ["cost", "amount", "msrp", "price", "rate", "value", "price_usd"],
5
+ brand: ["manufacturer", "vendor", "make", "company", "brand_name", "supplier"],
6
+ image: [
7
+ "imageUrl",
8
+ "thumbnail",
9
+ "img",
10
+ "url",
11
+ "photo",
12
+ "picture",
13
+ "media",
14
+ "image_url",
15
+ "main_image",
16
+ "product_image",
17
+ "thumb"
18
+ ],
19
+ stock: [
20
+ "inventory",
21
+ "quantity",
22
+ "count",
23
+ "availability",
24
+ "stock_level",
25
+ "inStock",
26
+ "is_available",
27
+ "in stock",
28
+ "status"
29
+ ],
30
+ description: ["summary", "content", "body", "text", "info", "details"],
31
+ link: ["url", "href", "product_url", "page_url", "link"]
32
+ };
33
+ function addSynonyms(customSynonyms) {
34
+ for (const [key, aliases] of Object.entries(customSynonyms)) {
35
+ if (!FIELD_SYNONYMS[key]) {
36
+ FIELD_SYNONYMS[key] = [];
37
+ }
38
+ const existing = new Set(FIELD_SYNONYMS[key].map((s) => s.toLowerCase()));
39
+ for (const alias of aliases) {
40
+ if (!existing.has(alias.toLowerCase())) {
41
+ FIELD_SYNONYMS[key].push(alias);
42
+ existing.add(alias.toLowerCase());
43
+ }
44
+ }
45
+ }
46
+ }
47
+ function resolveMetadataValue(meta, uiKey) {
48
+ var _a;
49
+ const synonyms = (_a = FIELD_SYNONYMS[uiKey]) != null ? _a : [];
50
+ const keys = Object.keys(meta);
51
+ const systemKeys = ["namespace", "filename", "filesize", "filetype", "docid", "uploadedat", "dimension", "chunkindex"];
52
+ let match = keys.find((k) => k.toLowerCase() === uiKey.toLowerCase());
53
+ if (match !== void 0) return meta[match];
54
+ match = keys.find((k) => synonyms.map((s) => s.toLowerCase()).includes(k.toLowerCase()));
55
+ if (match !== void 0) return meta[match];
56
+ const isBlacklisted = (kl) => {
57
+ return systemKeys.includes(kl) || kl.startsWith("option1") || kl.startsWith("option2") || kl.startsWith("option3");
58
+ };
59
+ match = keys.find((k) => {
60
+ const kl = k.toLowerCase();
61
+ if (isBlacklisted(kl)) return false;
62
+ return kl.includes(uiKey.toLowerCase());
63
+ });
64
+ if (match !== void 0) return meta[match];
65
+ match = keys.find((k) => {
66
+ const kl = k.toLowerCase();
67
+ if (isBlacklisted(kl)) return false;
68
+ return synonyms.some((sk) => kl.includes(sk.toLowerCase()) || sk.toLowerCase().includes(kl));
69
+ });
70
+ return match !== void 0 ? meta[match] : void 0;
71
+ }
72
+
73
+ export {
74
+ addSynonyms,
75
+ resolveMetadataValue
76
+ };