@retrivora-ai/rag-engine 1.7.9 → 1.8.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.
- package/dist/DocumentChunker-Dh9TvmGG.d.mts +45 -0
- package/dist/DocumentChunker-Dh9TvmGG.d.ts +45 -0
- package/dist/{index-wCRqMtdX.d.mts → ILLMProvider-BfRgI1Xh.d.mts} +59 -1
- package/dist/{index-wCRqMtdX.d.ts → ILLMProvider-BfRgI1Xh.d.ts} +59 -1
- package/dist/MultiTablePostgresProvider-YY7LPNJK.mjs +8 -0
- package/dist/{chunk-UHGYLTTY.mjs → chunk-BFYLQYQU.mjs} +846 -458
- package/dist/chunk-R3RGUMHE.mjs +218 -0
- package/dist/handlers/index.d.mts +2 -2
- package/dist/handlers/index.d.ts +2 -2
- package/dist/handlers/index.js +1033 -622
- package/dist/handlers/index.mjs +1 -1
- package/dist/{index-BDqz2_Yu.d.ts → index-1Z4GuYBi.d.ts} +7 -1
- package/dist/{index-DhsG2o5q.d.mts → index-BV0z5mb6.d.mts} +7 -1
- package/dist/index.d.mts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +507 -352
- package/dist/index.mjs +427 -253
- package/dist/server.d.mts +35 -5
- package/dist/server.d.ts +35 -5
- package/dist/server.js +1183 -795
- package/dist/server.mjs +163 -176
- package/package.json +4 -2
- package/src/app/page.tsx +1 -2
- package/src/components/DynamicChart.tsx +10 -35
- package/src/components/MessageBubble.tsx +223 -74
- package/src/components/ProductCard.tsx +2 -2
- package/src/components/VisualizationRenderer.tsx +347 -247
- package/src/config/RagConfig.ts +5 -0
- package/src/config/serverConfig.ts +3 -1
- package/src/core/Pipeline.ts +70 -209
- package/src/core/ProviderRegistry.ts +2 -2
- package/src/core/VectorPlugin.ts +9 -0
- package/src/handlers/index.ts +23 -7
- package/src/hooks/useRagChat.ts +2 -2
- package/src/llm/LLMFactory.ts +54 -2
- package/src/llm/providers/AnthropicProvider.ts +12 -8
- package/src/llm/providers/GeminiProvider.ts +188 -143
- package/src/llm/providers/OllamaProvider.ts +7 -3
- package/src/llm/providers/OpenAIProvider.ts +12 -8
- package/src/types/chat.ts +6 -0
- package/src/types/index.ts +81 -0
- package/src/utils/SchemaMapper.ts +129 -0
- package/src/utils/UITransformer.ts +524 -194
- package/dist/DocumentChunker-Bmscbh-X.d.ts +0 -93
- package/dist/DocumentChunker-DCuxrOdM.d.mts +0 -93
- package/dist/PostgreSQLProvider-BMOETDZA.mjs +0 -8
- package/dist/chunk-FLOSGE6A.mjs +0 -202
package/dist/server.mjs
CHANGED
|
@@ -39,14 +39,14 @@ import {
|
|
|
39
39
|
sseFrame,
|
|
40
40
|
sseMetaFrame,
|
|
41
41
|
sseTextFrame
|
|
42
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-BFYLQYQU.mjs";
|
|
43
43
|
import "./chunk-YLTMFW4M.mjs";
|
|
44
44
|
import {
|
|
45
45
|
PineconeProvider
|
|
46
46
|
} from "./chunk-VUQJVIJT.mjs";
|
|
47
47
|
import {
|
|
48
|
-
|
|
49
|
-
} from "./chunk-
|
|
48
|
+
MultiTablePostgresProvider
|
|
49
|
+
} from "./chunk-R3RGUMHE.mjs";
|
|
50
50
|
import {
|
|
51
51
|
MongoDBProvider
|
|
52
52
|
} from "./chunk-5AJ4XHLW.mjs";
|
|
@@ -60,8 +60,6 @@ import {
|
|
|
60
60
|
BaseVectorProvider
|
|
61
61
|
} from "./chunk-IMP6FUCY.mjs";
|
|
62
62
|
import {
|
|
63
|
-
__objRest,
|
|
64
|
-
__spreadProps,
|
|
65
63
|
__spreadValues
|
|
66
64
|
} from "./chunk-X4TOT24V.mjs";
|
|
67
65
|
|
|
@@ -237,196 +235,187 @@ function createFromPreset(presetName) {
|
|
|
237
235
|
return new ConfigBuilder().vectorDb(preset.vectorDb, { apiKey: process.env[`${preset.vectorDb.toUpperCase()}_API_KEY`] }).llm(preset.llm, void 0, process.env[`${preset.llm.toUpperCase()}_API_KEY`]).embedding(preset.embedding, void 0, process.env[`${preset.embedding.toUpperCase()}_API_KEY`]);
|
|
238
236
|
}
|
|
239
237
|
|
|
240
|
-
// src/providers/vectordb/
|
|
238
|
+
// src/providers/vectordb/PostgreSQLProvider.ts
|
|
241
239
|
import { Pool } from "pg";
|
|
242
|
-
var
|
|
240
|
+
var PostgreSQLProvider = class extends BaseVectorProvider {
|
|
243
241
|
constructor(config) {
|
|
244
|
-
var _a
|
|
242
|
+
var _a;
|
|
245
243
|
super(config);
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
}
|
|
244
|
+
this.tableName = this.indexName.replace(/[^a-z0-9_]/gi, "_");
|
|
245
|
+
const opts = config.options;
|
|
246
|
+
if (!opts.connectionString) throw new Error("[PostgreSQLProvider] options.connectionString is required");
|
|
250
247
|
this.connectionString = opts.connectionString;
|
|
251
|
-
this.dimensions = (_a = opts.dimensions) != null ? _a :
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
248
|
+
this.dimensions = (_a = opts.dimensions) != null ? _a : 1536;
|
|
249
|
+
}
|
|
250
|
+
static getValidator() {
|
|
251
|
+
return {
|
|
252
|
+
validate(config) {
|
|
253
|
+
const errors = [];
|
|
254
|
+
const opts = config.options || {};
|
|
255
|
+
if (!opts.connectionString) {
|
|
256
|
+
errors.push({
|
|
257
|
+
field: "vectorDb.options.connectionString",
|
|
258
|
+
message: "PostgreSQL connection string is required",
|
|
259
|
+
suggestion: "Set PGVECTOR_CONNECTION_STRING environment variable",
|
|
260
|
+
severity: "error"
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
if (opts.tables && typeof opts.tables !== "string" && !Array.isArray(opts.tables)) {
|
|
264
|
+
errors.push({
|
|
265
|
+
field: "vectorDb.options.tables",
|
|
266
|
+
message: "PostgreSQL tables must be a string or a string array",
|
|
267
|
+
severity: "error"
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
return errors;
|
|
271
|
+
}
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
static getHealthChecker() {
|
|
275
|
+
return {
|
|
276
|
+
async check(config) {
|
|
277
|
+
const opts = config.options || {};
|
|
278
|
+
const timestamp = Date.now();
|
|
279
|
+
try {
|
|
280
|
+
const { Client } = await import("pg");
|
|
281
|
+
const client = new Client({ connectionString: opts.connectionString });
|
|
282
|
+
await client.connect();
|
|
283
|
+
const result = await client.query(`
|
|
284
|
+
SELECT EXISTS(SELECT 1 FROM pg_extension WHERE extname = 'vector');
|
|
285
|
+
`);
|
|
286
|
+
const hasVector = result.rows[0].exists;
|
|
287
|
+
await client.end();
|
|
288
|
+
return {
|
|
289
|
+
healthy: true,
|
|
290
|
+
provider: "postgresql",
|
|
291
|
+
capabilities: { pgvectorInstalled: hasVector },
|
|
292
|
+
timestamp
|
|
293
|
+
};
|
|
294
|
+
} catch (error) {
|
|
295
|
+
return {
|
|
296
|
+
healthy: false,
|
|
297
|
+
provider: "postgresql",
|
|
298
|
+
error: `Connection failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
299
|
+
timestamp
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
};
|
|
261
304
|
}
|
|
262
305
|
async initialize() {
|
|
263
306
|
this.pool = new Pool({ connectionString: this.connectionString });
|
|
264
307
|
const client = await this.pool.connect();
|
|
265
308
|
try {
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
309
|
+
await client.query("CREATE EXTENSION IF NOT EXISTS vector");
|
|
310
|
+
await client.query(`
|
|
311
|
+
CREATE TABLE IF NOT EXISTS ${this.tableName} (
|
|
312
|
+
id TEXT PRIMARY KEY,
|
|
313
|
+
namespace TEXT NOT NULL DEFAULT '',
|
|
314
|
+
content TEXT NOT NULL,
|
|
315
|
+
metadata JSONB,
|
|
316
|
+
embedding VECTOR(${this.dimensions})
|
|
317
|
+
)
|
|
318
|
+
`);
|
|
319
|
+
await client.query(`
|
|
320
|
+
CREATE INDEX IF NOT EXISTS ${this.tableName}_embedding_idx
|
|
321
|
+
ON ${this.tableName}
|
|
322
|
+
USING hnsw (embedding vector_cosine_ops)
|
|
271
323
|
`);
|
|
272
|
-
const discoveredTables = res.rows.map((r) => r.table_name);
|
|
273
|
-
if (this.tables.length === 0) {
|
|
274
|
-
this.tables = discoveredTables;
|
|
275
|
-
} else {
|
|
276
|
-
const staticTables = [...this.tables];
|
|
277
|
-
this.tables = staticTables.filter((t) => discoveredTables.includes(t));
|
|
278
|
-
if (this.tables.length < staticTables.length) {
|
|
279
|
-
const missing = staticTables.filter((t) => !discoveredTables.includes(t));
|
|
280
|
-
console.warn(`[MultiTablePostgresProvider] Some configured tables were skipped (missing 'embedding' column): ${missing.join(", ")}`);
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
if (this.tables.length === 0) {
|
|
284
|
-
console.warn('[MultiTablePostgresProvider] No tables with "embedding" columns found in the database.');
|
|
285
|
-
} else {
|
|
286
|
-
console.log(
|
|
287
|
-
`[MultiTablePostgresProvider] Connected. Searching across ${this.tables.length} table(s): ${this.tables.join(", ")}`
|
|
288
|
-
);
|
|
289
|
-
}
|
|
290
324
|
} finally {
|
|
291
325
|
client.release();
|
|
292
326
|
}
|
|
293
327
|
}
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
async batchUpsert(_docs, _namespace) {
|
|
307
|
-
throw new Error(
|
|
308
|
-
"[MultiTablePostgresProvider] batchUpsert() is not supported in multi-table mode."
|
|
328
|
+
async upsert(doc, namespace = "") {
|
|
329
|
+
var _a;
|
|
330
|
+
const vectorLiteral = `[${doc.vector.join(",")}]`;
|
|
331
|
+
await this.pool.query(
|
|
332
|
+
`INSERT INTO ${this.tableName} (id, namespace, content, metadata, embedding)
|
|
333
|
+
VALUES ($1, $2, $3, $4, $5::vector)
|
|
334
|
+
ON CONFLICT (id) DO UPDATE
|
|
335
|
+
SET namespace = EXCLUDED.namespace,
|
|
336
|
+
content = EXCLUDED.content,
|
|
337
|
+
metadata = EXCLUDED.metadata,
|
|
338
|
+
embedding = EXCLUDED.embedding`,
|
|
339
|
+
[doc.id, namespace, doc.content, JSON.stringify((_a = doc.metadata) != null ? _a : {}), vectorLiteral]
|
|
309
340
|
);
|
|
310
341
|
}
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
};
|
|
337
|
-
const dynamicKeywordQuery = getDynamicKeywordQuery();
|
|
338
|
-
const queryPromises = this.tables.map(async (table) => {
|
|
339
|
-
try {
|
|
340
|
-
let sqlQuery = "";
|
|
341
|
-
let params = [];
|
|
342
|
-
if (queryText) {
|
|
343
|
-
const hasEntityHints = entityHints.length > 0;
|
|
344
|
-
const exactNameScoreExpr = hasEntityHints ? `+ (
|
|
345
|
-
SELECT COALESCE(MAX(
|
|
346
|
-
CASE WHEN LOWER(val) IN (${entityHints.map((h) => `'${h.replace(/'/g, "''")}'`).join(", ")})
|
|
347
|
-
THEN 1.0 ELSE 0.0 END
|
|
348
|
-
), 0)
|
|
349
|
-
FROM jsonb_each_text(to_jsonb(t)) AS kv(key, val)
|
|
350
|
-
WHERE key IN (${this.searchFields.map((f) => `'${f}'`).join(", ")})
|
|
351
|
-
) * 3.0` : "";
|
|
352
|
-
sqlQuery = `
|
|
353
|
-
SELECT *,
|
|
354
|
-
(1 - (embedding <=> $1::vector)) AS vector_score,
|
|
355
|
-
COALESCE(ts_rank(to_tsvector('english', (to_jsonb(t) - 'embedding')::text), to_tsquery('english', $2)), 0) AS keyword_score,
|
|
356
|
-
((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
|
|
357
|
-
FROM "${table}" t
|
|
358
|
-
ORDER BY hybrid_score DESC
|
|
359
|
-
LIMIT 50
|
|
360
|
-
`;
|
|
361
|
-
params = [vectorLiteral, dynamicKeywordQuery];
|
|
362
|
-
} else {
|
|
363
|
-
sqlQuery = `
|
|
364
|
-
SELECT *,
|
|
365
|
-
(1 - (embedding <=> $1::vector)) AS hybrid_score
|
|
366
|
-
FROM "${table}" t
|
|
367
|
-
ORDER BY hybrid_score DESC
|
|
368
|
-
LIMIT 50
|
|
369
|
-
`;
|
|
370
|
-
params = [vectorLiteral];
|
|
371
|
-
}
|
|
372
|
-
const result = await this.pool.query(sqlQuery, params);
|
|
373
|
-
if (result.rowCount && result.rowCount > 0) {
|
|
374
|
-
console.log(` \u2705 Table "${table}": Found ${result.rowCount} potential matches. Top score: ${result.rows[0].hybrid_score.toFixed(4)}`);
|
|
375
|
-
} else {
|
|
376
|
-
console.log(` \u26AA Table "${table}": No relevant matches found.`);
|
|
377
|
-
}
|
|
378
|
-
const tableResults = [];
|
|
379
|
-
for (const row of result.rows) {
|
|
380
|
-
const _a2 = row, { hybrid_score, id } = _a2, rest = __objRest(_a2, ["hybrid_score", "id"]);
|
|
381
|
-
delete rest.embedding;
|
|
382
|
-
delete rest.vector_score;
|
|
383
|
-
delete rest.keyword_score;
|
|
384
|
-
delete rest.exact_name_score;
|
|
385
|
-
const content = `[TYPE: ${table.replace(/s$/, "").toUpperCase()}]
|
|
386
|
-
` + Object.entries(rest).filter(([k, v]) => v !== null && typeof v !== "object" && k !== "id").map(([k, v]) => `${k}: ${v}`).join("\n");
|
|
387
|
-
tableResults.push({
|
|
388
|
-
id: `${table}-${id}`,
|
|
389
|
-
score: parseFloat(String(hybrid_score)),
|
|
390
|
-
content,
|
|
391
|
-
metadata: __spreadProps(__spreadValues({}, rest), { source_table: table })
|
|
392
|
-
});
|
|
393
|
-
}
|
|
394
|
-
return tableResults;
|
|
395
|
-
} catch (err) {
|
|
396
|
-
console.error(
|
|
397
|
-
`[MultiTablePostgresProvider] Error querying table "${table}":`,
|
|
398
|
-
err.message
|
|
399
|
-
);
|
|
400
|
-
return [];
|
|
342
|
+
async batchUpsert(docs, namespace = "") {
|
|
343
|
+
if (docs.length === 0) return;
|
|
344
|
+
const client = await this.pool.connect();
|
|
345
|
+
try {
|
|
346
|
+
await client.query("BEGIN");
|
|
347
|
+
const BATCH_SIZE = 50;
|
|
348
|
+
for (let i = 0; i < docs.length; i += BATCH_SIZE) {
|
|
349
|
+
const batch = docs.slice(i, i + BATCH_SIZE);
|
|
350
|
+
const values = [];
|
|
351
|
+
const valuePlaceholders = batch.map((doc, idx) => {
|
|
352
|
+
var _a;
|
|
353
|
+
const offset = idx * 5;
|
|
354
|
+
values.push(doc.id, namespace, doc.content, JSON.stringify((_a = doc.metadata) != null ? _a : {}), `[${doc.vector.join(",")}]`);
|
|
355
|
+
return `($${offset + 1}, $${offset + 2}, $${offset + 3}, $${offset + 4}, $${offset + 5}::vector)`;
|
|
356
|
+
}).join(", ");
|
|
357
|
+
const query = `
|
|
358
|
+
INSERT INTO ${this.tableName} (id, namespace, content, metadata, embedding)
|
|
359
|
+
VALUES ${valuePlaceholders}
|
|
360
|
+
ON CONFLICT (id) DO UPDATE
|
|
361
|
+
SET namespace = EXCLUDED.namespace,
|
|
362
|
+
content = EXCLUDED.content,
|
|
363
|
+
metadata = EXCLUDED.metadata,
|
|
364
|
+
embedding = EXCLUDED.embedding
|
|
365
|
+
`;
|
|
366
|
+
await client.query(query, values);
|
|
401
367
|
}
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
for (const res of allResults) {
|
|
409
|
-
const table = (_a = res.metadata) == null ? void 0 : _a.source_table;
|
|
410
|
-
if (!resultsByTable[table]) resultsByTable[table] = [];
|
|
411
|
-
resultsByTable[table].push(res);
|
|
368
|
+
await client.query("COMMIT");
|
|
369
|
+
} catch (error) {
|
|
370
|
+
await client.query("ROLLBACK");
|
|
371
|
+
throw error;
|
|
372
|
+
} finally {
|
|
373
|
+
client.release();
|
|
412
374
|
}
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
375
|
+
}
|
|
376
|
+
async query(vector, topK, namespace, filter) {
|
|
377
|
+
const vectorLiteral = `[${vector.join(",")}]`;
|
|
378
|
+
let whereClause = namespace ? `WHERE namespace = $3` : "";
|
|
379
|
+
const params = [vectorLiteral, topK];
|
|
380
|
+
if (namespace) params.push(namespace);
|
|
381
|
+
const publicFilter = this.sanitizeFilter(filter);
|
|
382
|
+
if (Object.keys(publicFilter).length > 0) {
|
|
383
|
+
const filterConditions = Object.entries(publicFilter).map(([key, val]) => {
|
|
384
|
+
const paramIdx = params.length + 1;
|
|
385
|
+
params.push(JSON.stringify(val));
|
|
386
|
+
return `metadata->>'${key}' = $${paramIdx}`;
|
|
387
|
+
}).join(" AND ");
|
|
388
|
+
whereClause = whereClause ? `${whereClause} AND ${filterConditions}` : `WHERE ${filterConditions}`;
|
|
417
389
|
}
|
|
418
|
-
const
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
390
|
+
const client = await this.pool.connect();
|
|
391
|
+
try {
|
|
392
|
+
const efSearch = this.config.options.efSearch || Math.max(topK * 10, 40);
|
|
393
|
+
await client.query(`SET LOCAL hnsw.ef_search = ${efSearch}`);
|
|
394
|
+
const result = await client.query(
|
|
395
|
+
`SELECT id, content, metadata, 1 - (embedding <=> $1::vector) AS score
|
|
396
|
+
FROM ${this.tableName}
|
|
397
|
+
${whereClause}
|
|
398
|
+
ORDER BY embedding <=> $1::vector
|
|
399
|
+
LIMIT $2`,
|
|
400
|
+
params
|
|
401
|
+
);
|
|
402
|
+
return result.rows.map((row) => ({
|
|
403
|
+
id: String(row["id"]),
|
|
404
|
+
score: parseFloat(String(row["score"])),
|
|
405
|
+
content: String(row["content"]),
|
|
406
|
+
metadata: row["metadata"]
|
|
407
|
+
}));
|
|
408
|
+
} finally {
|
|
409
|
+
client.release();
|
|
422
410
|
}
|
|
423
|
-
return finalSorted.slice(0, Math.max(topK, 15));
|
|
424
411
|
}
|
|
425
|
-
async delete(
|
|
426
|
-
|
|
412
|
+
async delete(id, namespace) {
|
|
413
|
+
const where = namespace ? "WHERE id = $1 AND namespace = $2" : "WHERE id = $1";
|
|
414
|
+
const params = namespace ? [id, namespace] : [id];
|
|
415
|
+
await this.pool.query(`DELETE FROM ${this.tableName} ${where}`, params);
|
|
427
416
|
}
|
|
428
|
-
async deleteNamespace(
|
|
429
|
-
|
|
417
|
+
async deleteNamespace(namespace) {
|
|
418
|
+
await this.pool.query(`DELETE FROM ${this.tableName} WHERE namespace = $1`, [namespace]);
|
|
430
419
|
}
|
|
431
420
|
async ping() {
|
|
432
421
|
try {
|
|
@@ -437,9 +426,7 @@ var MultiTablePostgresProvider = class extends BaseVectorProvider {
|
|
|
437
426
|
}
|
|
438
427
|
}
|
|
439
428
|
async disconnect() {
|
|
440
|
-
|
|
441
|
-
await this.pool.end();
|
|
442
|
-
}
|
|
429
|
+
await this.pool.end();
|
|
443
430
|
}
|
|
444
431
|
};
|
|
445
432
|
export {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@retrivora-ai/rag-engine",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.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": "MIT",
|
|
@@ -85,7 +85,7 @@
|
|
|
85
85
|
},
|
|
86
86
|
"dependencies": {
|
|
87
87
|
"@anthropic-ai/sdk": "^0.90.0",
|
|
88
|
-
"@google/
|
|
88
|
+
"@google/generative-ai": "^0.24.1",
|
|
89
89
|
"@pinecone-database/pinecone": "^7.2.0",
|
|
90
90
|
"axios": "^1.15.0",
|
|
91
91
|
"lucide-react": "^1.8.0",
|
|
@@ -94,6 +94,8 @@
|
|
|
94
94
|
"openai": "^6.34.0",
|
|
95
95
|
"react": ">=18.0.0",
|
|
96
96
|
"react-dom": ">=18.0.0",
|
|
97
|
+
"react-is": "^18.3.1",
|
|
98
|
+
"@google/genai": "^0.8.0",
|
|
97
99
|
"react-markdown": "^10.1.0",
|
|
98
100
|
"recharts": "^3.8.1",
|
|
99
101
|
"remark-gfm": "^4.0.1"
|
package/src/app/page.tsx
CHANGED
|
@@ -15,7 +15,6 @@ import { ChatWindow } from '@/components/ChatWindow';
|
|
|
15
15
|
import { ChatWidget } from '@/components/ChatWidget';
|
|
16
16
|
import { useConfig } from '@/components/ConfigProvider';
|
|
17
17
|
import { ThemeToggle } from '@/components/ThemeToggle';
|
|
18
|
-
import pkg from '../../package.json';
|
|
19
18
|
import { Snippet, ArchitectureCardProps } from './types';
|
|
20
19
|
import {
|
|
21
20
|
LANDING_PAGE_CONTENT,
|
|
@@ -178,7 +177,7 @@ export default function HomePage() {
|
|
|
178
177
|
</span>
|
|
179
178
|
<div className="flex items-center gap-1.5">
|
|
180
179
|
<span className="font-bold text-slate-900 dark:text-white text-[10px] tracking-[0.15em] uppercase opacity-70">Accelerator</span>
|
|
181
|
-
<span className="text-[9px] px-1.5 py-0.5 rounded-full bg-slate-100 dark:bg-white/5 text-slate-500 dark:text-white/40 font-mono border border-slate-200/50 dark:border-white/10">
|
|
180
|
+
<span className="text-[9px] px-1.5 py-0.5 rounded-full bg-slate-100 dark:bg-white/5 text-slate-500 dark:text-white/40 font-mono border border-slate-200/50 dark:border-white/10">v1.8.0</span>
|
|
182
181
|
</div>
|
|
183
182
|
</div>
|
|
184
183
|
</div>
|
|
@@ -143,42 +143,13 @@ export function DynamicChart({
|
|
|
143
143
|
const finalDataKeys = resolvedDataKeys.map(String).filter(k => k !== 'undefined');
|
|
144
144
|
const pieDataKey = finalDataKeys[0] || 'value';
|
|
145
145
|
|
|
146
|
-
const stockAwareColor = (entry: Record<string, string | number | null>, index: number) => {
|
|
147
|
-
const stockStatus = String(
|
|
148
|
-
entry.stockStatus ??
|
|
149
|
-
entry.status ??
|
|
150
|
-
entry.availability ??
|
|
151
|
-
'',
|
|
152
|
-
).toLowerCase();
|
|
153
|
-
const inStockCount = typeof entry.inStockCount === 'number' ? entry.inStockCount : undefined;
|
|
154
|
-
const outOfStockCount = typeof entry.outOfStockCount === 'number' ? entry.outOfStockCount : undefined;
|
|
155
|
-
const inStockFlag = entry.inStock;
|
|
156
|
-
|
|
157
|
-
if (stockStatus.includes('in stock')) return '#10b981';
|
|
158
|
-
if (stockStatus.includes('out of stock')) return '#f97316';
|
|
159
|
-
if (typeof inStockFlag === 'string' && inStockFlag.toLowerCase() === 'true') return '#10b981';
|
|
160
|
-
if (inStockFlag === 1) return '#10b981';
|
|
161
|
-
if (inStockFlag === 0) return '#f97316';
|
|
162
|
-
if (typeof inStockCount === 'number' || typeof outOfStockCount === 'number') {
|
|
163
|
-
const inCount = inStockCount ?? 0;
|
|
164
|
-
const outCount = outOfStockCount ?? 0;
|
|
165
|
-
if (inCount > outCount) return '#10b981';
|
|
166
|
-
if (outCount > inCount) return '#f97316';
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
return colors[index % colors.length];
|
|
170
|
-
};
|
|
171
146
|
|
|
172
147
|
const tooltipLabelMap: Record<string, string> = {
|
|
173
|
-
value: '
|
|
148
|
+
value: 'Total Items',
|
|
174
149
|
count: 'Count',
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
stockStatus: 'Stock status',
|
|
179
|
-
category: 'Category',
|
|
180
|
-
label: 'Label',
|
|
181
|
-
name: 'Name',
|
|
150
|
+
inStockCount: 'In Stock',
|
|
151
|
+
outOfStockCount: 'Out of Stock',
|
|
152
|
+
stockStatus: 'Status',
|
|
182
153
|
};
|
|
183
154
|
|
|
184
155
|
const renderTooltip = (
|
|
@@ -196,6 +167,10 @@ export function DynamicChart({
|
|
|
196
167
|
if (value === null || value === undefined || key === finalXKey) return null;
|
|
197
168
|
if (typeof value === 'object') return null;
|
|
198
169
|
|
|
170
|
+
// Filter out technical Recharts/internal keys
|
|
171
|
+
const forbiddenKeys = ['fill', 'color', 'payload', 'percent', 'stroke', 'inStock'];
|
|
172
|
+
if (forbiddenKeys.includes(key)) return null;
|
|
173
|
+
|
|
199
174
|
return (
|
|
200
175
|
<div key={key} className="flex items-center justify-between gap-3 text-slate-600 dark:text-white/70">
|
|
201
176
|
<span>{tooltipLabelMap[key] ?? key}</span>
|
|
@@ -235,8 +210,8 @@ export function DynamicChart({
|
|
|
235
210
|
label={false}
|
|
236
211
|
labelLine={false}
|
|
237
212
|
>
|
|
238
|
-
{sanitizedData.map((
|
|
239
|
-
<Cell key={`cell-${index}`} fill={
|
|
213
|
+
{sanitizedData.map((_entry, index) => (
|
|
214
|
+
<Cell key={`cell-${index}`} fill={colors[index % colors.length]} />
|
|
240
215
|
))}
|
|
241
216
|
</Pie>
|
|
242
217
|
<Tooltip content={(props) => renderTooltip(getTooltipRow(props.payload), typeof props.label === 'string' ? props.label : undefined)} />
|