@retrivora-ai/rag-engine 1.7.4 → 1.7.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/{chunk-PKK7EEVP.mjs → chunk-QOO37S2Z.mjs} +7 -3
- package/dist/handlers/index.js +7 -3
- package/dist/handlers/index.mjs +1 -1
- package/dist/index.js +13 -0
- package/dist/index.mjs +13 -0
- package/dist/server.js +14 -6
- package/dist/server.mjs +8 -4
- package/package.json +1 -1
- package/src/components/MessageBubble.tsx +51 -1
- package/src/core/Pipeline.ts +6 -1
- package/src/llm/providers/GeminiProvider.ts +7 -2
- package/src/providers/vectordb/MultiTablePostgresProvider.ts +13 -3
|
@@ -829,7 +829,8 @@ ${context}`;
|
|
|
829
829
|
stopSequences: options == null ? void 0 : options.stop
|
|
830
830
|
}
|
|
831
831
|
});
|
|
832
|
-
|
|
832
|
+
const text = typeof response.text === "function" ? response.text() : (_f = response.text) != null ? _f : "";
|
|
833
|
+
return text;
|
|
833
834
|
}
|
|
834
835
|
chatStream(messages, context, options) {
|
|
835
836
|
return __asyncGenerator(this, null, function* () {
|
|
@@ -863,7 +864,7 @@ ${context}`;
|
|
|
863
864
|
try {
|
|
864
865
|
for (var iter = __forAwait(stream), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
|
|
865
866
|
const chunk = temp.value;
|
|
866
|
-
const text = chunk.text;
|
|
867
|
+
const text = typeof chunk.text === "function" ? chunk.text() : chunk.text;
|
|
867
868
|
if (text) yield text;
|
|
868
869
|
}
|
|
869
870
|
} catch (temp) {
|
|
@@ -2445,7 +2446,10 @@ User: "distribution of products across categories"
|
|
|
2445
2446
|
\`\`\`
|
|
2446
2447
|
`;
|
|
2447
2448
|
if (!((_a = this.config.llm.systemPrompt) == null ? void 0 : _a.includes(CHART_MARKER))) {
|
|
2448
|
-
|
|
2449
|
+
let cleanPrompt = this.config.llm.systemPrompt || "";
|
|
2450
|
+
cleanPrompt = cleanPrompt.replace(/\n\n### UNIVERSAL UI PROTOCOL[\s\S]*?(?=\n\n|$)/g, "");
|
|
2451
|
+
cleanPrompt = cleanPrompt.replace(/<!-- UI_PROTOCOL_V\d+ -->[\s\S]*?(?=\n\n|$)/g, "");
|
|
2452
|
+
this.config.llm.systemPrompt = cleanPrompt.trim() + chartInstruction;
|
|
2449
2453
|
}
|
|
2450
2454
|
console.log(`[Pipeline] Initializing with provider: ${this.config.vectorDb.provider}...`);
|
|
2451
2455
|
this.vectorDB = await ProviderRegistry.createVectorProvider(this.config.vectorDb);
|
package/dist/handlers/index.js
CHANGED
|
@@ -2437,7 +2437,8 @@ ${context}`;
|
|
|
2437
2437
|
stopSequences: options == null ? void 0 : options.stop
|
|
2438
2438
|
}
|
|
2439
2439
|
});
|
|
2440
|
-
|
|
2440
|
+
const text = typeof response.text === "function" ? response.text() : (_f = response.text) != null ? _f : "";
|
|
2441
|
+
return text;
|
|
2441
2442
|
}
|
|
2442
2443
|
chatStream(messages, context, options) {
|
|
2443
2444
|
return __asyncGenerator(this, null, function* () {
|
|
@@ -2471,7 +2472,7 @@ ${context}`;
|
|
|
2471
2472
|
try {
|
|
2472
2473
|
for (var iter = __forAwait(stream), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
|
|
2473
2474
|
const chunk = temp.value;
|
|
2474
|
-
const text = chunk.text;
|
|
2475
|
+
const text = typeof chunk.text === "function" ? chunk.text() : chunk.text;
|
|
2475
2476
|
if (text) yield text;
|
|
2476
2477
|
}
|
|
2477
2478
|
} catch (temp) {
|
|
@@ -4009,7 +4010,10 @@ User: "distribution of products across categories"
|
|
|
4009
4010
|
\`\`\`
|
|
4010
4011
|
`;
|
|
4011
4012
|
if (!((_a = this.config.llm.systemPrompt) == null ? void 0 : _a.includes(CHART_MARKER))) {
|
|
4012
|
-
|
|
4013
|
+
let cleanPrompt = this.config.llm.systemPrompt || "";
|
|
4014
|
+
cleanPrompt = cleanPrompt.replace(/\n\n### UNIVERSAL UI PROTOCOL[\s\S]*?(?=\n\n|$)/g, "");
|
|
4015
|
+
cleanPrompt = cleanPrompt.replace(/<!-- UI_PROTOCOL_V\d+ -->[\s\S]*?(?=\n\n|$)/g, "");
|
|
4016
|
+
this.config.llm.systemPrompt = cleanPrompt.trim() + chartInstruction;
|
|
4013
4017
|
}
|
|
4014
4018
|
console.log(`[Pipeline] Initializing with provider: ${this.config.vectorDb.provider}...`);
|
|
4015
4019
|
this.vectorDB = await ProviderRegistry.createVectorProvider(this.config.vectorDb);
|
package/dist/handlers/index.mjs
CHANGED
package/dist/index.js
CHANGED
|
@@ -637,6 +637,11 @@ function normalizeTabularRows(rows, columns) {
|
|
|
637
637
|
}).filter((row) => Object.keys(row).length > 0);
|
|
638
638
|
}
|
|
639
639
|
function resolveStructuredRows(config) {
|
|
640
|
+
var _a, _b, _c, _d;
|
|
641
|
+
if (((_a = config.carousel) == null ? void 0 : _a.items) && Array.isArray(config.carousel.items)) return config.carousel.items;
|
|
642
|
+
if (((_b = config.chart) == null ? void 0 : _b.data) && Array.isArray(config.chart.data)) return config.chart.data;
|
|
643
|
+
if (((_c = config.table) == null ? void 0 : _c.rows) && Array.isArray(config.table.rows)) return config.table.rows;
|
|
644
|
+
if (((_d = config.table) == null ? void 0 : _d.data) && Array.isArray(config.table.data)) return config.table.data;
|
|
640
645
|
if (Array.isArray(config.data) && config.data.length > 0) return config.data;
|
|
641
646
|
if (Array.isArray(config.items) && config.items.length > 0) return config.items;
|
|
642
647
|
if (Array.isArray(config.products) && config.products.length > 0) return config.products;
|
|
@@ -652,6 +657,14 @@ function UIDispatcher({ rawContent, primaryColor, accentColor, isStreaming, onAd
|
|
|
652
657
|
const clean = rawContent.replace(/^```[a-z]*\s*/i, "").replace(/```\s*$/, "").trim();
|
|
653
658
|
const parsed = JSON.parse(sanitizeJson(extractLikelyJsonBlock(clean)));
|
|
654
659
|
const config2 = __spreadValues({}, parsed);
|
|
660
|
+
if (config2.chart) {
|
|
661
|
+
if (!config2.chartType) config2.chartType = config2.chart.type;
|
|
662
|
+
if (!config2.xAxisKey) config2.xAxisKey = config2.chart.xKey;
|
|
663
|
+
if (!config2.dataKeys) config2.dataKeys = config2.chart.yKeys;
|
|
664
|
+
}
|
|
665
|
+
if (config2.table) {
|
|
666
|
+
if (!config2.columns) config2.columns = config2.table.columns;
|
|
667
|
+
}
|
|
655
668
|
const resolvedRows = resolveStructuredRows(config2);
|
|
656
669
|
const hasProductLikeData = resolvedRows.length > 0 && typeof resolvedRows[0] === "object" && resolvedRows[0] !== null && !Array.isArray(resolvedRows[0]) && (["price", "brand", "image", "link", "thumbnail"].some((key) => key in resolvedRows[0]) || Object.keys(resolvedRows[0]).length >= 4);
|
|
657
670
|
const hasAggregationLikeData = resolvedRows.length > 0 && typeof resolvedRows[0] === "object" && resolvedRows[0] !== null && !Array.isArray(resolvedRows[0]) && (["value", "count", "total", "percentage"].some((key) => key in resolvedRows[0]) || Object.keys(resolvedRows[0]).length <= 3 && Object.values(resolvedRows[0]).some((v) => typeof v === "number"));
|
package/dist/index.mjs
CHANGED
|
@@ -600,6 +600,11 @@ function normalizeTabularRows(rows, columns) {
|
|
|
600
600
|
}).filter((row) => Object.keys(row).length > 0);
|
|
601
601
|
}
|
|
602
602
|
function resolveStructuredRows(config) {
|
|
603
|
+
var _a, _b, _c, _d;
|
|
604
|
+
if (((_a = config.carousel) == null ? void 0 : _a.items) && Array.isArray(config.carousel.items)) return config.carousel.items;
|
|
605
|
+
if (((_b = config.chart) == null ? void 0 : _b.data) && Array.isArray(config.chart.data)) return config.chart.data;
|
|
606
|
+
if (((_c = config.table) == null ? void 0 : _c.rows) && Array.isArray(config.table.rows)) return config.table.rows;
|
|
607
|
+
if (((_d = config.table) == null ? void 0 : _d.data) && Array.isArray(config.table.data)) return config.table.data;
|
|
603
608
|
if (Array.isArray(config.data) && config.data.length > 0) return config.data;
|
|
604
609
|
if (Array.isArray(config.items) && config.items.length > 0) return config.items;
|
|
605
610
|
if (Array.isArray(config.products) && config.products.length > 0) return config.products;
|
|
@@ -615,6 +620,14 @@ function UIDispatcher({ rawContent, primaryColor, accentColor, isStreaming, onAd
|
|
|
615
620
|
const clean = rawContent.replace(/^```[a-z]*\s*/i, "").replace(/```\s*$/, "").trim();
|
|
616
621
|
const parsed = JSON.parse(sanitizeJson(extractLikelyJsonBlock(clean)));
|
|
617
622
|
const config2 = __spreadValues({}, parsed);
|
|
623
|
+
if (config2.chart) {
|
|
624
|
+
if (!config2.chartType) config2.chartType = config2.chart.type;
|
|
625
|
+
if (!config2.xAxisKey) config2.xAxisKey = config2.chart.xKey;
|
|
626
|
+
if (!config2.dataKeys) config2.dataKeys = config2.chart.yKeys;
|
|
627
|
+
}
|
|
628
|
+
if (config2.table) {
|
|
629
|
+
if (!config2.columns) config2.columns = config2.table.columns;
|
|
630
|
+
}
|
|
618
631
|
const resolvedRows = resolveStructuredRows(config2);
|
|
619
632
|
const hasProductLikeData = resolvedRows.length > 0 && typeof resolvedRows[0] === "object" && resolvedRows[0] !== null && !Array.isArray(resolvedRows[0]) && (["price", "brand", "image", "link", "thumbnail"].some((key) => key in resolvedRows[0]) || Object.keys(resolvedRows[0]).length >= 4);
|
|
620
633
|
const hasAggregationLikeData = resolvedRows.length > 0 && typeof resolvedRows[0] === "object" && resolvedRows[0] !== null && !Array.isArray(resolvedRows[0]) && (["value", "count", "total", "percentage"].some((key) => key in resolvedRows[0]) || Object.keys(resolvedRows[0]).length <= 3 && Object.values(resolvedRows[0]).some((v) => typeof v === "number"));
|
package/dist/server.js
CHANGED
|
@@ -2482,7 +2482,8 @@ ${context}`;
|
|
|
2482
2482
|
stopSequences: options == null ? void 0 : options.stop
|
|
2483
2483
|
}
|
|
2484
2484
|
});
|
|
2485
|
-
|
|
2485
|
+
const text = typeof response.text === "function" ? response.text() : (_f = response.text) != null ? _f : "";
|
|
2486
|
+
return text;
|
|
2486
2487
|
}
|
|
2487
2488
|
chatStream(messages, context, options) {
|
|
2488
2489
|
return __asyncGenerator(this, null, function* () {
|
|
@@ -2516,7 +2517,7 @@ ${context}`;
|
|
|
2516
2517
|
try {
|
|
2517
2518
|
for (var iter = __forAwait(stream), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {
|
|
2518
2519
|
const chunk = temp.value;
|
|
2519
|
-
const text = chunk.text;
|
|
2520
|
+
const text = typeof chunk.text === "function" ? chunk.text() : chunk.text;
|
|
2520
2521
|
if (text) yield text;
|
|
2521
2522
|
}
|
|
2522
2523
|
} catch (temp) {
|
|
@@ -4099,7 +4100,10 @@ User: "distribution of products across categories"
|
|
|
4099
4100
|
\`\`\`
|
|
4100
4101
|
`;
|
|
4101
4102
|
if (!((_a = this.config.llm.systemPrompt) == null ? void 0 : _a.includes(CHART_MARKER))) {
|
|
4102
|
-
|
|
4103
|
+
let cleanPrompt = this.config.llm.systemPrompt || "";
|
|
4104
|
+
cleanPrompt = cleanPrompt.replace(/\n\n### UNIVERSAL UI PROTOCOL[\s\S]*?(?=\n\n|$)/g, "");
|
|
4105
|
+
cleanPrompt = cleanPrompt.replace(/<!-- UI_PROTOCOL_V\d+ -->[\s\S]*?(?=\n\n|$)/g, "");
|
|
4106
|
+
this.config.llm.systemPrompt = cleanPrompt.trim() + chartInstruction;
|
|
4103
4107
|
}
|
|
4104
4108
|
console.log(`[Pipeline] Initializing with provider: ${this.config.vectorDb.provider}...`);
|
|
4105
4109
|
this.vectorDB = await ProviderRegistry.createVectorProvider(this.config.vectorDb);
|
|
@@ -4923,11 +4927,15 @@ var MultiTablePostgresProvider = class extends BaseVectorProvider {
|
|
|
4923
4927
|
).map((hint) => hint.value.trim().toLowerCase()).filter(Boolean) : [];
|
|
4924
4928
|
console.log(`[MultiTablePostgresProvider] queryText: "${queryText}"`);
|
|
4925
4929
|
console.log(`[MultiTablePostgresProvider] entityHints: [${entityHints.join(", ")}]`);
|
|
4930
|
+
const cleanKeywordQuery = (text) => {
|
|
4931
|
+
return text.toLowerCase().replace(/\b(show|me|the|product|cards|of|category|find|list|browse|what|are|display)\b/g, "").trim().replace(/\s+/g, " & ");
|
|
4932
|
+
};
|
|
4926
4933
|
const queryPromises = this.tables.map(async (table) => {
|
|
4927
4934
|
try {
|
|
4928
4935
|
let sqlQuery = "";
|
|
4929
4936
|
let params = [];
|
|
4930
4937
|
if (queryText) {
|
|
4938
|
+
const cleanedText = cleanKeywordQuery(queryText) || queryText;
|
|
4931
4939
|
const hasEntityHints = entityHints.length > 0;
|
|
4932
4940
|
const exactNameScoreExpr = hasEntityHints ? `+ (
|
|
4933
4941
|
SELECT COALESCE(MAX(
|
|
@@ -4940,13 +4948,13 @@ var MultiTablePostgresProvider = class extends BaseVectorProvider {
|
|
|
4940
4948
|
sqlQuery = `
|
|
4941
4949
|
SELECT *,
|
|
4942
4950
|
(1 - (embedding <=> $1::vector)) AS vector_score,
|
|
4943
|
-
COALESCE(ts_rank(to_tsvector('english', (to_jsonb(t) - 'embedding')::text),
|
|
4944
|
-
((1 - (embedding <=> $1::vector)) + (COALESCE(ts_rank(to_tsvector('english', (to_jsonb(t) - 'embedding')::text),
|
|
4951
|
+
COALESCE(ts_rank(to_tsvector('english', (to_jsonb(t) - 'embedding')::text), to_tsquery('english', $2)), 0) AS keyword_score,
|
|
4952
|
+
((1 - (embedding <=> $1::vector)) + (COALESCE(ts_rank(to_tsvector('english', (to_jsonb(t) - 'embedding')::text), to_tsquery('english', $2)), 0) * 2.0) ${exactNameScoreExpr}) AS hybrid_score
|
|
4945
4953
|
FROM "${table}" t
|
|
4946
4954
|
ORDER BY hybrid_score DESC
|
|
4947
4955
|
LIMIT 50
|
|
4948
4956
|
`;
|
|
4949
|
-
params = [vectorLiteral,
|
|
4957
|
+
params = [vectorLiteral, cleanedText];
|
|
4950
4958
|
} else {
|
|
4951
4959
|
sqlQuery = `
|
|
4952
4960
|
SELECT *,
|
package/dist/server.mjs
CHANGED
|
@@ -39,7 +39,7 @@ import {
|
|
|
39
39
|
sseFrame,
|
|
40
40
|
sseMetaFrame,
|
|
41
41
|
sseTextFrame
|
|
42
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-QOO37S2Z.mjs";
|
|
43
43
|
import "./chunk-YLTMFW4M.mjs";
|
|
44
44
|
import {
|
|
45
45
|
PineconeProvider
|
|
@@ -325,11 +325,15 @@ var MultiTablePostgresProvider = class extends BaseVectorProvider {
|
|
|
325
325
|
).map((hint) => hint.value.trim().toLowerCase()).filter(Boolean) : [];
|
|
326
326
|
console.log(`[MultiTablePostgresProvider] queryText: "${queryText}"`);
|
|
327
327
|
console.log(`[MultiTablePostgresProvider] entityHints: [${entityHints.join(", ")}]`);
|
|
328
|
+
const cleanKeywordQuery = (text) => {
|
|
329
|
+
return text.toLowerCase().replace(/\b(show|me|the|product|cards|of|category|find|list|browse|what|are|display)\b/g, "").trim().replace(/\s+/g, " & ");
|
|
330
|
+
};
|
|
328
331
|
const queryPromises = this.tables.map(async (table) => {
|
|
329
332
|
try {
|
|
330
333
|
let sqlQuery = "";
|
|
331
334
|
let params = [];
|
|
332
335
|
if (queryText) {
|
|
336
|
+
const cleanedText = cleanKeywordQuery(queryText) || queryText;
|
|
333
337
|
const hasEntityHints = entityHints.length > 0;
|
|
334
338
|
const exactNameScoreExpr = hasEntityHints ? `+ (
|
|
335
339
|
SELECT COALESCE(MAX(
|
|
@@ -342,13 +346,13 @@ var MultiTablePostgresProvider = class extends BaseVectorProvider {
|
|
|
342
346
|
sqlQuery = `
|
|
343
347
|
SELECT *,
|
|
344
348
|
(1 - (embedding <=> $1::vector)) AS vector_score,
|
|
345
|
-
COALESCE(ts_rank(to_tsvector('english', (to_jsonb(t) - 'embedding')::text),
|
|
346
|
-
((1 - (embedding <=> $1::vector)) + (COALESCE(ts_rank(to_tsvector('english', (to_jsonb(t) - 'embedding')::text),
|
|
349
|
+
COALESCE(ts_rank(to_tsvector('english', (to_jsonb(t) - 'embedding')::text), to_tsquery('english', $2)), 0) AS keyword_score,
|
|
350
|
+
((1 - (embedding <=> $1::vector)) + (COALESCE(ts_rank(to_tsvector('english', (to_jsonb(t) - 'embedding')::text), to_tsquery('english', $2)), 0) * 2.0) ${exactNameScoreExpr}) AS hybrid_score
|
|
347
351
|
FROM "${table}" t
|
|
348
352
|
ORDER BY hybrid_score DESC
|
|
349
353
|
LIMIT 50
|
|
350
354
|
`;
|
|
351
|
-
params = [vectorLiteral,
|
|
355
|
+
params = [vectorLiteral, cleanedText];
|
|
352
356
|
} else {
|
|
353
357
|
sqlQuery = `
|
|
354
358
|
SELECT *,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@retrivora-ai/rag-engine",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.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": "MIT",
|
|
@@ -381,14 +381,46 @@ interface UIConfig {
|
|
|
381
381
|
rows?: Record<string, unknown>[];
|
|
382
382
|
products?: Record<string, unknown>[];
|
|
383
383
|
results?: Record<string, unknown>[];
|
|
384
|
+
|
|
385
|
+
// V7 Protocol Fields
|
|
386
|
+
carousel?: {
|
|
387
|
+
items: Record<string, unknown>[];
|
|
388
|
+
};
|
|
389
|
+
chart?: {
|
|
390
|
+
type: 'pie' | 'bar' | 'line';
|
|
391
|
+
xKey: string;
|
|
392
|
+
yKeys: string[];
|
|
393
|
+
data: Record<string, unknown>[];
|
|
394
|
+
};
|
|
395
|
+
table?: {
|
|
396
|
+
columns: string[];
|
|
397
|
+
rows?: Record<string, unknown>[];
|
|
398
|
+
data?: Record<string, unknown>[];
|
|
399
|
+
};
|
|
384
400
|
}
|
|
385
401
|
|
|
386
|
-
interface RawUIConfig extends Omit<UIConfig, 'data' | 'items' | 'rows' | 'products' | 'results'> {
|
|
402
|
+
interface RawUIConfig extends Omit<UIConfig, 'data' | 'items' | 'rows' | 'products' | 'results' | 'carousel' | 'chart' | 'table'> {
|
|
387
403
|
data: Array<Record<string, unknown> | unknown[]>;
|
|
388
404
|
items?: Array<Record<string, unknown> | unknown[]>;
|
|
389
405
|
rows?: Array<Record<string, unknown> | unknown[]>;
|
|
390
406
|
products?: Array<Record<string, unknown> | unknown[]>;
|
|
391
407
|
results?: Array<Record<string, unknown> | unknown[]>;
|
|
408
|
+
|
|
409
|
+
// V7 Protocol Fields (Raw)
|
|
410
|
+
carousel?: {
|
|
411
|
+
items: Array<Record<string, unknown> | unknown[]>;
|
|
412
|
+
};
|
|
413
|
+
chart?: {
|
|
414
|
+
type: 'pie' | 'bar' | 'line';
|
|
415
|
+
xKey: string;
|
|
416
|
+
yKeys: string[];
|
|
417
|
+
data: Array<Record<string, unknown> | unknown[]>;
|
|
418
|
+
};
|
|
419
|
+
table?: {
|
|
420
|
+
columns: string[];
|
|
421
|
+
rows?: Array<Record<string, unknown> | unknown[]>;
|
|
422
|
+
data?: Array<Record<string, unknown> | unknown[]>;
|
|
423
|
+
};
|
|
392
424
|
}
|
|
393
425
|
|
|
394
426
|
function normalizeTabularRows(
|
|
@@ -420,6 +452,13 @@ function normalizeTabularRows(
|
|
|
420
452
|
}
|
|
421
453
|
|
|
422
454
|
function resolveStructuredRows(config: Partial<RawUIConfig> & Record<string, unknown>) {
|
|
455
|
+
// V7 Nested Structures
|
|
456
|
+
if (config.carousel?.items && Array.isArray(config.carousel.items)) return config.carousel.items;
|
|
457
|
+
if (config.chart?.data && Array.isArray(config.chart.data)) return config.chart.data;
|
|
458
|
+
if (config.table?.rows && Array.isArray(config.table.rows)) return config.table.rows;
|
|
459
|
+
if (config.table?.data && Array.isArray(config.table.data)) return config.table.data;
|
|
460
|
+
|
|
461
|
+
// V6 Flat Structures
|
|
423
462
|
if (Array.isArray(config.data) && config.data.length > 0) return config.data;
|
|
424
463
|
if (Array.isArray(config.items) && config.items.length > 0) return config.items;
|
|
425
464
|
if (Array.isArray(config.products) && config.products.length > 0) return config.products;
|
|
@@ -445,6 +484,17 @@ function UIDispatcher({ rawContent, primaryColor, accentColor, isStreaming, onAd
|
|
|
445
484
|
.trim();
|
|
446
485
|
const parsed = JSON.parse(sanitizeJson(extractLikelyJsonBlock(clean)));
|
|
447
486
|
const config = { ...parsed } as Partial<RawUIConfig> & Record<string, unknown>;
|
|
487
|
+
|
|
488
|
+
// V7 Field Mapping
|
|
489
|
+
if (config.chart) {
|
|
490
|
+
if (!config.chartType) config.chartType = config.chart.type;
|
|
491
|
+
if (!config.xAxisKey) config.xAxisKey = config.chart.xKey;
|
|
492
|
+
if (!config.dataKeys) config.dataKeys = config.chart.yKeys;
|
|
493
|
+
}
|
|
494
|
+
if (config.table) {
|
|
495
|
+
if (!config.columns) config.columns = config.table.columns;
|
|
496
|
+
}
|
|
497
|
+
|
|
448
498
|
const resolvedRows = resolveStructuredRows(config);
|
|
449
499
|
|
|
450
500
|
// ─── Intent Healing & Auto-Detection ───────────────────────────────────
|
package/src/core/Pipeline.ts
CHANGED
|
@@ -287,7 +287,12 @@ User: "distribution of products across categories"
|
|
|
287
287
|
\`\`\`
|
|
288
288
|
`;
|
|
289
289
|
if (!this.config.llm.systemPrompt?.includes(CHART_MARKER)) {
|
|
290
|
-
|
|
290
|
+
// Clean up ANY existing protocol markers (V1-V7) to avoid prompt bloat
|
|
291
|
+
let cleanPrompt = this.config.llm.systemPrompt || '';
|
|
292
|
+
cleanPrompt = cleanPrompt.replace(/\n\n### UNIVERSAL UI PROTOCOL[\s\S]*?(?=\n\n|$)/g, '');
|
|
293
|
+
cleanPrompt = cleanPrompt.replace(/<!-- UI_PROTOCOL_V\d+ -->[\s\S]*?(?=\n\n|$)/g, '');
|
|
294
|
+
|
|
295
|
+
this.config.llm.systemPrompt = cleanPrompt.trim() + chartInstruction;
|
|
291
296
|
}
|
|
292
297
|
|
|
293
298
|
console.log(`[Pipeline] Initializing with provider: ${this.config.vectorDb.provider}...`);
|
|
@@ -128,7 +128,10 @@ export class GeminiProvider implements ILLMProvider {
|
|
|
128
128
|
},
|
|
129
129
|
});
|
|
130
130
|
|
|
131
|
-
|
|
131
|
+
const text = typeof (response as { text: unknown }).text === 'function'
|
|
132
|
+
? (response as { text: () => string }).text()
|
|
133
|
+
: (response.text ?? '');
|
|
134
|
+
return text;
|
|
132
135
|
}
|
|
133
136
|
|
|
134
137
|
async *chatStream(messages: ChatMessage[], context: string, options?: ChatOptions): AsyncIterable<string> {
|
|
@@ -162,7 +165,9 @@ export class GeminiProvider implements ILLMProvider {
|
|
|
162
165
|
}
|
|
163
166
|
|
|
164
167
|
for await (const chunk of stream) {
|
|
165
|
-
const text = chunk.text
|
|
168
|
+
const text = typeof (chunk as { text: unknown }).text === 'function'
|
|
169
|
+
? (chunk as { text: () => string }).text()
|
|
170
|
+
: (chunk as { text?: string }).text;
|
|
166
171
|
if (text) yield text;
|
|
167
172
|
}
|
|
168
173
|
}
|
|
@@ -151,12 +151,22 @@ export class MultiTablePostgresProvider extends BaseVectorProvider {
|
|
|
151
151
|
console.log(`[MultiTablePostgresProvider] queryText: "${queryText}"`);
|
|
152
152
|
console.log(`[MultiTablePostgresProvider] entityHints: [${entityHints.join(', ')}]`);
|
|
153
153
|
|
|
154
|
+
// Helper to clean conversational filler for better keyword matching
|
|
155
|
+
const cleanKeywordQuery = (text: string) => {
|
|
156
|
+
return text
|
|
157
|
+
.toLowerCase()
|
|
158
|
+
.replace(/\b(show|me|the|product|cards|of|category|find|list|browse|what|are|display)\b/g, '')
|
|
159
|
+
.trim()
|
|
160
|
+
.replace(/\s+/g, ' & '); // Join remaining words with AND for tsquery
|
|
161
|
+
};
|
|
162
|
+
|
|
154
163
|
const queryPromises = this.tables.map(async (table) => {
|
|
155
164
|
try {
|
|
156
165
|
let sqlQuery = '';
|
|
157
166
|
let params: unknown[] = [];
|
|
158
167
|
|
|
159
168
|
if (queryText) {
|
|
169
|
+
const cleanedText = cleanKeywordQuery(queryText) || queryText;
|
|
160
170
|
const hasEntityHints = entityHints.length > 0;
|
|
161
171
|
const exactNameScoreExpr = hasEntityHints
|
|
162
172
|
? `+ (
|
|
@@ -173,13 +183,13 @@ export class MultiTablePostgresProvider extends BaseVectorProvider {
|
|
|
173
183
|
sqlQuery = `
|
|
174
184
|
SELECT *,
|
|
175
185
|
(1 - (embedding <=> $1::vector)) AS vector_score,
|
|
176
|
-
COALESCE(ts_rank(to_tsvector('english', (to_jsonb(t) - 'embedding')::text),
|
|
177
|
-
((1 - (embedding <=> $1::vector)) + (COALESCE(ts_rank(to_tsvector('english', (to_jsonb(t) - 'embedding')::text),
|
|
186
|
+
COALESCE(ts_rank(to_tsvector('english', (to_jsonb(t) - 'embedding')::text), to_tsquery('english', $2)), 0) AS keyword_score,
|
|
187
|
+
((1 - (embedding <=> $1::vector)) + (COALESCE(ts_rank(to_tsvector('english', (to_jsonb(t) - 'embedding')::text), to_tsquery('english', $2)), 0) * 2.0) ${exactNameScoreExpr}) AS hybrid_score
|
|
178
188
|
FROM "${table}" t
|
|
179
189
|
ORDER BY hybrid_score DESC
|
|
180
190
|
LIMIT 50
|
|
181
191
|
`;
|
|
182
|
-
params = [vectorLiteral,
|
|
192
|
+
params = [vectorLiteral, cleanedText];
|
|
183
193
|
} else {
|
|
184
194
|
// Fallback to Vector-only Search
|
|
185
195
|
sqlQuery = `
|