agenticaichat 1.0.0 → 1.0.3

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 (48) hide show
  1. package/README.md +83 -26
  2. package/bin/cli.js +301 -84
  3. package/dist/core/ChatbotEngine.d.ts +9 -1
  4. package/dist/core/ChatbotEngine.js +52 -19
  5. package/dist/core/EngineFactory.d.ts +45 -0
  6. package/dist/core/EngineFactory.js +126 -0
  7. package/dist/core/NLToSQLConverter.d.ts +6 -15
  8. package/dist/core/NLToSQLConverter.js +9 -114
  9. package/dist/engines/base/DatabaseEngine.d.ts +46 -0
  10. package/dist/engines/base/DatabaseEngine.js +42 -0
  11. package/dist/engines/nosql/MongoEngine.d.ts +13 -0
  12. package/dist/engines/nosql/MongoEngine.js +194 -0
  13. package/dist/engines/nosql/NoSqlEngine.d.ts +20 -0
  14. package/dist/engines/nosql/NoSqlEngine.js +29 -0
  15. package/dist/engines/sql/SqlEngine.d.ts +19 -0
  16. package/dist/engines/sql/SqlEngine.js +52 -0
  17. package/dist/engines/sql/dialects/MySQLDialect.d.ts +12 -0
  18. package/dist/engines/sql/dialects/MySQLDialect.js +109 -0
  19. package/dist/engines/sql/dialects/PostgresDialect.d.ts +11 -0
  20. package/dist/engines/sql/dialects/PostgresDialect.js +109 -0
  21. package/dist/engines/sql/dialects/SQLiteDialect.d.ts +10 -0
  22. package/dist/engines/sql/dialects/SQLiteDialect.js +101 -0
  23. package/dist/index.d.ts +17 -4
  24. package/dist/index.js +44 -8
  25. package/dist/llm/LLMFactory.d.ts +25 -0
  26. package/dist/llm/LLMFactory.js +137 -0
  27. package/dist/llm/providers/ClaudeProvider.d.ts +13 -0
  28. package/dist/llm/providers/ClaudeProvider.js +132 -0
  29. package/dist/llm/providers/DeepInfraProvider.d.ts +14 -0
  30. package/dist/llm/providers/DeepInfraProvider.js +144 -0
  31. package/dist/llm/providers/GeminiProvider.d.ts +13 -0
  32. package/dist/llm/providers/GeminiProvider.js +105 -0
  33. package/dist/llm/providers/GrokProvider.d.ts +14 -0
  34. package/dist/llm/providers/GrokProvider.js +144 -0
  35. package/dist/llm/providers/GroqProvider.d.ts +0 -0
  36. package/dist/llm/providers/GroqProvider.js +148 -0
  37. package/dist/llm/providers/OpenAIProvider.d.ts +13 -0
  38. package/dist/llm/providers/OpenAIProvider.js +136 -0
  39. package/dist/llm/providers/TogetherAIProvider.d.ts +14 -0
  40. package/dist/llm/providers/TogetherAIProvider.js +144 -0
  41. package/dist/llm/types.d.ts +34 -0
  42. package/dist/llm/types.js +2 -0
  43. package/dist/types/index.d.ts +23 -3
  44. package/dist/widget/ChatbotWidget.d.ts +1 -1
  45. package/dist/widget/ChatbotWidget.js +406 -125
  46. package/package.json +24 -5
  47. package/scripts/postinstall.js +126 -0
  48. package/templates/api-route.template.ts +24 -14
@@ -1,17 +1,34 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ChatbotEngine = void 0;
4
- const DatabaseConnector_1 = require("./DatabaseConnector");
4
+ const EngineFactory_1 = require("./EngineFactory");
5
5
  const NLToSQLConverter_1 = require("./NLToSQLConverter");
6
+ const LLMFactory_1 = require("../llm/LLMFactory");
6
7
  const logger_1 = require("../utils/logger");
7
8
  class ChatbotEngine {
8
9
  constructor(config) {
9
10
  this.schema = null;
10
11
  this.initialized = false;
11
- this.dbConnector = new DatabaseConnector_1.DatabaseConnector(config.database);
12
- this.nlConverter = new NLToSQLConverter_1.NLToSQLConverter(config.openai);
12
+ // Validate database config
13
+ const dbValidation = EngineFactory_1.EngineFactory.validateConfig(config.database);
14
+ if (!dbValidation.valid) {
15
+ throw new Error(`Database configuration invalid: ${dbValidation.error}`);
16
+ }
17
+ // Validate LLM config
18
+ const llmValidation = LLMFactory_1.LLMFactory.validateConfig(config.llm);
19
+ if (!llmValidation.valid) {
20
+ throw new Error(`LLM configuration invalid: ${llmValidation.error}`);
21
+ }
22
+ // Create database engine
23
+ this.dbEngine = EngineFactory_1.EngineFactory.createEngine(config.database);
24
+ // Create LLM provider
25
+ const llmProvider = LLMFactory_1.LLMFactory.createProvider(config.llm);
26
+ // Initialize NL converter
27
+ this.nlConverter = new NLToSQLConverter_1.NLToSQLConverter(llmProvider);
13
28
  if (config.debug) {
14
29
  logger_1.logger.info('ChatbotEngine initialized in DEBUG mode');
30
+ logger_1.logger.info(`Database: ${config.database.type} (${config.database.category})`);
31
+ logger_1.logger.info(`LLM Provider: ${config.llm.provider}`);
15
32
  }
16
33
  }
17
34
  /**
@@ -21,12 +38,12 @@ class ChatbotEngine {
21
38
  try {
22
39
  logger_1.logger.info('Initializing ChatbotEngine...');
23
40
  // Connect to database
24
- await this.dbConnector.connect();
41
+ await this.dbEngine.connect();
25
42
  // Load schema
26
- this.schema = await this.dbConnector.getSchema();
27
- logger_1.logger.info(`Schema loaded: ${this.schema.tables.length} tables found`);
43
+ this.schema = await this.dbEngine.getSchema();
44
+ logger_1.logger.info(`Schema loaded: ${this.schema.tables.length} tables/collections found`);
28
45
  this.initialized = true;
29
- logger_1.logger.info('ChatbotEngine initialized successfully');
46
+ logger_1.logger.info('ChatbotEngine initialized successfully');
30
47
  }
31
48
  catch (error) {
32
49
  logger_1.logger.error('Initialization failed', error);
@@ -42,23 +59,29 @@ class ChatbotEngine {
42
59
  }
43
60
  try {
44
61
  logger_1.logger.info(`Processing query: "${request.query}"`);
45
- // Step 1: Convert NL to SQL
46
- const sqlQuery = await this.nlConverter.convertToSQL(request.query, this.schema);
47
- // Step 2: Validate SQL
48
- if (!this.nlConverter.validateSQL(sqlQuery)) {
62
+ // Get database type for context
63
+ const dbType = this.dbEngine.getDatabaseType();
64
+ const dbCategory = this.dbEngine.getDatabaseCategory();
65
+ logger_1.logger.debug_log(`Database type: ${dbType}, Category: ${dbCategory}`);
66
+ // Step 1: Convert NL to Query (SQL or NoSQL)
67
+ const query = await this.nlConverter.convertToSQL(request.query, this.schema);
68
+ logger_1.logger.debug_log('Generated query:', query);
69
+ // Step 2: Validate query
70
+ if (!this.dbEngine.validateQuery(query)) {
49
71
  return {
50
72
  answer: 'Sorry, I cannot execute this query for security reasons.',
51
- error: 'SQL validation failed'
73
+ error: 'Query validation failed'
52
74
  };
53
75
  }
54
- // Step 3: Execute SQL
55
- const queryResult = await this.dbConnector.executeQuery(sqlQuery);
76
+ // Step 3: Execute query
77
+ const queryResult = await this.dbEngine.executeQuery(query);
78
+ logger_1.logger.debug_log('Query result:', queryResult);
56
79
  // Step 4: Generate human response
57
- const humanAnswer = await this.nlConverter.generateHumanResponse(request.query, queryResult);
80
+ const humanAnswer = await this.nlConverter.generateHumanResponse(request.query, queryResult.rows);
58
81
  return {
59
82
  answer: humanAnswer,
60
- sql: sqlQuery,
61
- data: queryResult
83
+ sql: typeof query === 'string' ? query : JSON.stringify(query),
84
+ data: queryResult.rows
62
85
  };
63
86
  }
64
87
  catch (error) {
@@ -73,8 +96,8 @@ class ChatbotEngine {
73
96
  * Disconnect from database
74
97
  */
75
98
  async shutdown() {
76
- if (this.dbConnector.isConnected()) {
77
- await this.dbConnector.disconnect();
99
+ if (this.dbEngine.isConnected()) {
100
+ await this.dbEngine.disconnect();
78
101
  }
79
102
  this.initialized = false;
80
103
  logger_1.logger.info('ChatbotEngine shut down');
@@ -91,5 +114,15 @@ class ChatbotEngine {
91
114
  getSchema() {
92
115
  return this.schema;
93
116
  }
117
+ /**
118
+ * Get database engine status
119
+ */
120
+ getStatus() {
121
+ return {
122
+ initialized: this.initialized,
123
+ engine: this.dbEngine.getStatus(),
124
+ schema: this.schema ? `${this.schema.tables.length} tables` : 'Not loaded'
125
+ };
126
+ }
94
127
  }
95
128
  exports.ChatbotEngine = ChatbotEngine;
@@ -0,0 +1,45 @@
1
+ import { DatabaseEngine } from '../engines/base/DatabaseEngine';
2
+ import { DatabaseConfig, SupportedDatabaseType } from '../types';
3
+ export declare class EngineFactory {
4
+ /**
5
+ * Create appropriate database engine based on config
6
+ */
7
+ static createEngine(config: DatabaseConfig): DatabaseEngine;
8
+ /**
9
+ * Get list of supported databases with metadata
10
+ */
11
+ static getSupportedDatabases(): {
12
+ sql: ({
13
+ name: string;
14
+ value: string;
15
+ description: string;
16
+ category: string;
17
+ defaultPort: number;
18
+ } | {
19
+ name: string;
20
+ value: string;
21
+ description: string;
22
+ category: string;
23
+ defaultPort: null;
24
+ })[];
25
+ nosql: {
26
+ name: string;
27
+ value: string;
28
+ description: string;
29
+ category: string;
30
+ defaultPort: number;
31
+ }[];
32
+ };
33
+ /**
34
+ * Validate database configuration
35
+ */
36
+ static validateConfig(config: DatabaseConfig): {
37
+ valid: boolean;
38
+ error?: string;
39
+ };
40
+ /**
41
+ * Check if database type is SQL or NoSQL
42
+ */
43
+ static isSqlDatabase(type: SupportedDatabaseType): boolean;
44
+ static isNoSqlDatabase(type: SupportedDatabaseType): boolean;
45
+ }
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EngineFactory = void 0;
4
+ const PostgresDialect_1 = require("../engines/sql/dialects/PostgresDialect");
5
+ const MySQLDialect_1 = require("../engines/sql/dialects/MySQLDialect");
6
+ const SQLiteDialect_1 = require("../engines/sql/dialects/SQLiteDialect");
7
+ const MongoEngine_1 = require("../engines/nosql/MongoEngine");
8
+ const logger_1 = require("../utils/logger");
9
+ class EngineFactory {
10
+ /**
11
+ * Create appropriate database engine based on config
12
+ */
13
+ static createEngine(config) {
14
+ logger_1.logger.info(`Creating engine for: ${config.type} (${config.category})`);
15
+ switch (config.type) {
16
+ // SQL Databases
17
+ case 'postgresql':
18
+ return new PostgresDialect_1.PostgresDialect(config);
19
+ case 'mysql':
20
+ return new MySQLDialect_1.MySQLDialect(config);
21
+ case 'sqlite':
22
+ case 'turso': // Turso is SQLite-compatible
23
+ return new SQLiteDialect_1.SQLiteDialect(config);
24
+ // NoSQL Databases
25
+ case 'mongodb':
26
+ return new MongoEngine_1.MongoEngine(config);
27
+ default:
28
+ throw new Error(`Unsupported database type: ${config.type}`);
29
+ }
30
+ }
31
+ /**
32
+ * Get list of supported databases with metadata
33
+ */
34
+ static getSupportedDatabases() {
35
+ return {
36
+ sql: [
37
+ {
38
+ name: 'PostgreSQL',
39
+ value: 'postgresql',
40
+ description: 'Most popular, production-ready',
41
+ category: 'sql',
42
+ defaultPort: 5432
43
+ },
44
+ {
45
+ name: 'MySQL',
46
+ value: 'mysql',
47
+ description: 'Web standard, widely used',
48
+ category: 'sql',
49
+ defaultPort: 3306
50
+ },
51
+ {
52
+ name: 'SQLite',
53
+ value: 'sqlite',
54
+ description: 'Local file, perfect for testing',
55
+ category: 'sql',
56
+ defaultPort: null
57
+ },
58
+ {
59
+ name: 'Turso (LibSQL)',
60
+ value: 'turso',
61
+ description: 'Modern SQLite, edge-ready',
62
+ category: 'sql',
63
+ defaultPort: null
64
+ },
65
+ {
66
+ name: 'Microsoft SQL Server',
67
+ value: 'mssql',
68
+ description: 'Enterprise standard',
69
+ category: 'sql',
70
+ defaultPort: 1433
71
+ }
72
+ ],
73
+ nosql: [
74
+ {
75
+ name: 'MongoDB',
76
+ value: 'mongodb',
77
+ description: 'Document store, flexible schema',
78
+ category: 'nosql',
79
+ defaultPort: 27017
80
+ }
81
+ ]
82
+ };
83
+ }
84
+ /**
85
+ * Validate database configuration
86
+ */
87
+ static validateConfig(config) {
88
+ // Check category
89
+ if (!config.category || !['sql', 'nosql'].includes(config.category)) {
90
+ return {
91
+ valid: false,
92
+ error: 'Database category must be "sql" or "nosql"'
93
+ };
94
+ }
95
+ // Check type is supported
96
+ const supportedDbs = this.getSupportedDatabases();
97
+ const allDbs = [...supportedDbs.sql, ...supportedDbs.nosql];
98
+ const dbExists = allDbs.some(db => db.value === config.type);
99
+ if (!dbExists) {
100
+ return {
101
+ valid: false,
102
+ error: `Unsupported database type: ${config.type}`
103
+ };
104
+ }
105
+ // Check URL
106
+ if (!config.url || config.url.trim() === '') {
107
+ return {
108
+ valid: false,
109
+ error: 'Database URL is required'
110
+ };
111
+ }
112
+ return { valid: true };
113
+ }
114
+ /**
115
+ * Check if database type is SQL or NoSQL
116
+ */
117
+ static isSqlDatabase(type) {
118
+ const sqlTypes = ['postgresql', 'mysql', 'sqlite', 'turso', 'mssql'];
119
+ return sqlTypes.includes(type);
120
+ }
121
+ static isNoSqlDatabase(type) {
122
+ const nosqlTypes = ['mongodb'];
123
+ return nosqlTypes.includes(type);
124
+ }
125
+ }
126
+ exports.EngineFactory = EngineFactory;
@@ -1,24 +1,15 @@
1
- import { OpenAIConfig, DatabaseSchema } from '../types';
1
+ import { ILLMProvider } from '../llm/types';
2
2
  export declare class NLToSQLConverter {
3
- private openai;
4
- private model;
5
- constructor(config: OpenAIConfig);
3
+ private provider;
4
+ constructor(provider: ILLMProvider);
6
5
  /**
7
- * Convert natural language to SQL
6
+ * Convert natural language to SQL using configured provider
8
7
  */
9
- convertToSQL(userQuery: string, schema: DatabaseSchema): Promise<string>;
8
+ convertToSQL(userQuery: string, schema: any): Promise<string>;
10
9
  /**
11
- * Generate human-readable response
10
+ * Generate human-readable response using configured provider
12
11
  */
13
12
  generateHumanResponse(userQuery: string, queryResult: any): Promise<string>;
14
- /**
15
- * Build SQL generation prompt
16
- */
17
- private buildPrompt;
18
- /**
19
- * Format schema for prompt
20
- */
21
- private formatSchemaForPrompt;
22
13
  /**
23
14
  * Validate SQL query for security
24
15
  */
@@ -1,130 +1,25 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.NLToSQLConverter = void 0;
7
- const openai_1 = __importDefault(require("openai"));
8
4
  const logger_1 = require("../utils/logger");
9
5
  class NLToSQLConverter {
10
- constructor(config) {
11
- this.openai = new openai_1.default({
12
- apiKey: config.apiKey
13
- });
14
- this.model = config.model;
6
+ constructor(provider) {
7
+ if (!provider.isConfigured()) {
8
+ throw new Error('LLM Provider is not properly configured');
9
+ }
10
+ this.provider = provider;
15
11
  }
16
12
  /**
17
- * Convert natural language to SQL
13
+ * Convert natural language to SQL using configured provider
18
14
  */
19
15
  async convertToSQL(userQuery, schema) {
20
- try {
21
- logger_1.logger.info('Converting NL to SQL...');
22
- const schemaDescription = this.formatSchemaForPrompt(schema);
23
- const prompt = this.buildPrompt(userQuery, schemaDescription);
24
- const response = await this.openai.chat.completions.create({
25
- model: this.model,
26
- messages: [
27
- {
28
- role: 'system',
29
- content: 'You are an expert SQL query generator. Generate ONLY valid SQL queries without any explanation or markdown.'
30
- },
31
- {
32
- role: 'user',
33
- content: prompt
34
- }
35
- ],
36
- temperature: 0.2,
37
- max_tokens: 500
38
- });
39
- const sqlQuery = response.choices[0]?.message?.content?.trim() || '';
40
- // Remove markdown code blocks if present
41
- const cleanedSQL = sqlQuery
42
- .replace(/```sql\n?/g, '')
43
- .replace(/```\n?/g, '')
44
- .trim();
45
- logger_1.logger.debug_log('Generated SQL:', cleanedSQL);
46
- return cleanedSQL;
47
- }
48
- catch (error) {
49
- logger_1.logger.error('NL to SQL conversion failed', error);
50
- throw error;
51
- }
16
+ return await this.provider.generateSQL(userQuery, schema);
52
17
  }
53
18
  /**
54
- * Generate human-readable response
19
+ * Generate human-readable response using configured provider
55
20
  */
56
21
  async generateHumanResponse(userQuery, queryResult) {
57
- try {
58
- logger_1.logger.info('Generating human response...');
59
- const prompt = `
60
- User asked: "${userQuery}"
61
-
62
- Database returned this result:
63
- ${JSON.stringify(queryResult, null, 2)}
64
-
65
- Please provide a clear, conversational answer in Hindi/English mix (Hinglish) that explains this data to a business owner. Be specific with numbers.
66
- `;
67
- const response = await this.openai.chat.completions.create({
68
- model: this.model,
69
- messages: [
70
- {
71
- role: 'system',
72
- content: 'You are a helpful business analytics assistant. Explain data clearly in Hinglish (Hindi-English mix).'
73
- },
74
- {
75
- role: 'user',
76
- content: prompt
77
- }
78
- ],
79
- temperature: 0.7,
80
- max_tokens: 300
81
- });
82
- const answer = response.choices[0]?.message?.content?.trim() || 'Sorry, I could not generate a response.';
83
- logger_1.logger.debug_log('Generated response:', answer);
84
- return answer;
85
- }
86
- catch (error) {
87
- logger_1.logger.error('Response generation failed', error);
88
- throw error;
89
- }
90
- }
91
- /**
92
- * Build SQL generation prompt
93
- */
94
- buildPrompt(userQuery, schemaDescription) {
95
- return `
96
- You are a SQL expert. Generate a SQL query based on the user's question.
97
-
98
- Database Schema:
99
- ${schemaDescription}
100
-
101
- User Question: "${userQuery}"
102
-
103
- Rules:
104
- 1. Return ONLY the SQL query, nothing else
105
- 2. Use correct table and column names from the schema
106
- 3. Add WHERE clauses for date filtering when needed
107
- 4. Use SUM, COUNT, AVG for aggregations
108
- 5. Handle both singular and plural forms (sales/sale, orders/order)
109
- 6. Use CURRENT_DATE, CURRENT_MONTH for time-based queries
110
- 7. Make sure the query is syntactically correct
111
-
112
- SQL Query:
113
- `;
114
- }
115
- /**
116
- * Format schema for prompt
117
- */
118
- formatSchemaForPrompt(schema) {
119
- let description = '';
120
- for (const table of schema.tables) {
121
- description += `\nTable: ${table.name}\n`;
122
- description += 'Columns:\n';
123
- for (const column of table.columns) {
124
- description += ` - ${column.name} (${column.type})${column.nullable ? ' [nullable]' : ''}\n`;
125
- }
126
- }
127
- return description;
22
+ return await this.provider.generateHumanResponse(userQuery, queryResult);
128
23
  }
129
24
  /**
130
25
  * Validate SQL query for security
@@ -0,0 +1,46 @@
1
+ import { DatabaseConfig, DatabaseSchema, QueryResult, EngineStatus } from '../../types';
2
+ /**
3
+ * Base interface for all database engines
4
+ */
5
+ export declare abstract class DatabaseEngine {
6
+ protected config: DatabaseConfig;
7
+ protected connection: any;
8
+ protected connected: boolean;
9
+ constructor(config: DatabaseConfig);
10
+ /**
11
+ * Connect to database
12
+ */
13
+ abstract connect(): Promise<void>;
14
+ /**
15
+ * Disconnect from database
16
+ */
17
+ abstract disconnect(): Promise<void>;
18
+ /**
19
+ * Get database schema
20
+ */
21
+ abstract getSchema(): Promise<DatabaseSchema>;
22
+ /**
23
+ * Execute query (SQL or NoSQL)
24
+ */
25
+ abstract executeQuery(query: string | object): Promise<QueryResult>;
26
+ /**
27
+ * Validate query before execution
28
+ */
29
+ abstract validateQuery(query: string | object): boolean;
30
+ /**
31
+ * Check if connected
32
+ */
33
+ isConnected(): boolean;
34
+ /**
35
+ * Get engine status
36
+ */
37
+ getStatus(): EngineStatus;
38
+ /**
39
+ * Get database type
40
+ */
41
+ getDatabaseType(): string;
42
+ /**
43
+ * Get database category
44
+ */
45
+ getDatabaseCategory(): string;
46
+ }
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DatabaseEngine = void 0;
4
+ /**
5
+ * Base interface for all database engines
6
+ */
7
+ class DatabaseEngine {
8
+ constructor(config) {
9
+ this.connection = null;
10
+ this.connected = false;
11
+ this.config = config;
12
+ }
13
+ /**
14
+ * Check if connected
15
+ */
16
+ isConnected() {
17
+ return this.connected;
18
+ }
19
+ /**
20
+ * Get engine status
21
+ */
22
+ getStatus() {
23
+ return {
24
+ connected: this.connected,
25
+ type: this.config.type,
26
+ category: this.config.category
27
+ };
28
+ }
29
+ /**
30
+ * Get database type
31
+ */
32
+ getDatabaseType() {
33
+ return this.config.type;
34
+ }
35
+ /**
36
+ * Get database category
37
+ */
38
+ getDatabaseCategory() {
39
+ return this.config.category;
40
+ }
41
+ }
42
+ exports.DatabaseEngine = DatabaseEngine;
@@ -0,0 +1,13 @@
1
+ import { NoSqlEngine } from './NoSqlEngine';
2
+ import { DatabaseConfig, DatabaseSchema, QueryResult } from '../../types';
3
+ export declare class MongoEngine extends NoSqlEngine {
4
+ private client;
5
+ private db;
6
+ constructor(config: DatabaseConfig);
7
+ connect(): Promise<void>;
8
+ disconnect(): Promise<void>;
9
+ getSchema(): Promise<DatabaseSchema>;
10
+ executeQuery(query: object | string): Promise<QueryResult>;
11
+ validateQuery(query: string | object): boolean;
12
+ private inferMongoType;
13
+ }