agenticaichat 1.0.1 ā 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.
- package/README.md +83 -26
- package/bin/cli.js +301 -84
- package/dist/core/ChatbotEngine.d.ts +9 -1
- package/dist/core/ChatbotEngine.js +52 -19
- package/dist/core/EngineFactory.d.ts +45 -0
- package/dist/core/EngineFactory.js +126 -0
- package/dist/core/NLToSQLConverter.d.ts +6 -15
- package/dist/core/NLToSQLConverter.js +9 -114
- package/dist/engines/base/DatabaseEngine.d.ts +46 -0
- package/dist/engines/base/DatabaseEngine.js +42 -0
- package/dist/engines/nosql/MongoEngine.d.ts +13 -0
- package/dist/engines/nosql/MongoEngine.js +194 -0
- package/dist/engines/nosql/NoSqlEngine.d.ts +20 -0
- package/dist/engines/nosql/NoSqlEngine.js +29 -0
- package/dist/engines/sql/SqlEngine.d.ts +19 -0
- package/dist/engines/sql/SqlEngine.js +52 -0
- package/dist/engines/sql/dialects/MySQLDialect.d.ts +12 -0
- package/dist/engines/sql/dialects/MySQLDialect.js +109 -0
- package/dist/engines/sql/dialects/PostgresDialect.d.ts +11 -0
- package/dist/engines/sql/dialects/PostgresDialect.js +109 -0
- package/dist/engines/sql/dialects/SQLiteDialect.d.ts +10 -0
- package/dist/engines/sql/dialects/SQLiteDialect.js +101 -0
- package/dist/index.d.ts +17 -4
- package/dist/index.js +44 -8
- package/dist/llm/LLMFactory.d.ts +25 -0
- package/dist/llm/LLMFactory.js +137 -0
- package/dist/llm/providers/ClaudeProvider.d.ts +13 -0
- package/dist/llm/providers/ClaudeProvider.js +132 -0
- package/dist/llm/providers/DeepInfraProvider.d.ts +14 -0
- package/dist/llm/providers/DeepInfraProvider.js +144 -0
- package/dist/llm/providers/GeminiProvider.d.ts +13 -0
- package/dist/llm/providers/GeminiProvider.js +105 -0
- package/dist/llm/providers/GrokProvider.d.ts +14 -0
- package/dist/llm/providers/GrokProvider.js +144 -0
- package/dist/llm/providers/GroqProvider.d.ts +0 -0
- package/dist/llm/providers/GroqProvider.js +148 -0
- package/dist/llm/providers/OpenAIProvider.d.ts +13 -0
- package/dist/llm/providers/OpenAIProvider.js +136 -0
- package/dist/llm/providers/TogetherAIProvider.d.ts +14 -0
- package/dist/llm/providers/TogetherAIProvider.js +144 -0
- package/dist/llm/types.d.ts +34 -0
- package/dist/llm/types.js +2 -0
- package/dist/types/index.d.ts +23 -3
- package/dist/widget/ChatbotWidget.d.ts +1 -1
- package/dist/widget/ChatbotWidget.js +406 -125
- package/package.json +19 -4
- package/scripts/postinstall.js +126 -0
- package/templates/api-route.template.ts +24 -14
package/README.md
CHANGED
|
@@ -1,30 +1,55 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
1
|
+
# AgenticAIChat
|
|
3
2
|
AI-powered chatbot for business analytics with natural language database queries.
|
|
4
3
|
|
|
5
|
-
##
|
|
4
|
+
## Highlights
|
|
5
|
+
|
|
6
|
+
- Five-minute setup with an interactive CLI wizard
|
|
7
|
+
- Natural language questions in English or Hindi
|
|
8
|
+
- Works with PostgreSQL, MySQL, SQLite, Turso, and MongoDB
|
|
9
|
+
- Ready-to-use React/Next.js widget for dashboards and full pages
|
|
10
|
+
- Configuration files generated for you (`.env.chatbot`, `chatbot-config.json`)
|
|
11
|
+
- Fully typed TypeScript package
|
|
12
|
+
|
|
13
|
+
## Requirements
|
|
14
|
+
|
|
15
|
+
- Node.js 18+ and npm 9+
|
|
16
|
+
- React 18+ and Next.js 13+ (app router recommended)
|
|
6
17
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
- šØ **Beautiful Widget**: Pre-built React component
|
|
11
|
-
- š **Secure**: Encrypted API keys
|
|
12
|
-
- š° **Free**: User pays OpenAI API only
|
|
13
|
-
- š¦ **TypeScript**: Full type safety
|
|
18
|
+
## Installation and Setup
|
|
19
|
+
|
|
20
|
+
The setup wizard now launches automatically right after installation. Choose your preferred package manager:
|
|
14
21
|
|
|
15
|
-
## š¦ Installation
|
|
16
22
|
```bash
|
|
23
|
+
# npm
|
|
17
24
|
npm install agenticaichat
|
|
25
|
+
|
|
26
|
+
# yarn
|
|
27
|
+
yarn add agenticaichat
|
|
28
|
+
|
|
29
|
+
# pnpm
|
|
30
|
+
pnpm add agenticaichat
|
|
18
31
|
```
|
|
19
32
|
|
|
20
|
-
|
|
33
|
+
During install, the wizard will:
|
|
34
|
+
|
|
35
|
+
- Ask for your database type and connection details
|
|
36
|
+
- Collect your AI provider, model, and API key
|
|
37
|
+
- Generate `.env.chatbot` and `chatbot-config.json`
|
|
38
|
+
- Create starter files if they are missing (Next.js defaults):
|
|
39
|
+
- `app/api/chatbot/query/route.ts`
|
|
40
|
+
- `app/chat/page.tsx`
|
|
41
|
+
- Updates `.gitignore` to exclude generated secrets
|
|
42
|
+
|
|
43
|
+
If you need to rerun the wizard later:
|
|
21
44
|
|
|
22
|
-
### Step 1: Run Setup Wizard
|
|
23
45
|
```bash
|
|
24
46
|
npx agenticai-setup
|
|
25
47
|
```
|
|
26
48
|
|
|
27
|
-
|
|
49
|
+
## Quick Start (Next.js)
|
|
50
|
+
|
|
51
|
+
Add the widget to any page or component:
|
|
52
|
+
|
|
28
53
|
```tsx
|
|
29
54
|
// app/dashboard/page.tsx
|
|
30
55
|
import { ChatbotWidget } from 'agenticaichat';
|
|
@@ -39,7 +64,8 @@ export default function Dashboard() {
|
|
|
39
64
|
}
|
|
40
65
|
```
|
|
41
66
|
|
|
42
|
-
|
|
67
|
+
Create a full-page chat experience:
|
|
68
|
+
|
|
43
69
|
```tsx
|
|
44
70
|
// app/chat/page.tsx
|
|
45
71
|
import { ChatbotWidget } from 'agenticaichat';
|
|
@@ -49,23 +75,54 @@ export default function ChatPage() {
|
|
|
49
75
|
}
|
|
50
76
|
```
|
|
51
77
|
|
|
52
|
-
|
|
78
|
+
Start your Next.js app:
|
|
53
79
|
|
|
54
|
-
|
|
80
|
+
```bash
|
|
81
|
+
npm run dev
|
|
82
|
+
```
|
|
55
83
|
|
|
56
|
-
##
|
|
84
|
+
## Using with Other React Frameworks
|
|
57
85
|
|
|
58
|
-
|
|
86
|
+
The widget renders in any React 18+ app (CRA, Vite, Remix, etc.). You only need to supply a compatible backend endpoint.
|
|
59
87
|
|
|
60
|
-
|
|
88
|
+
Backend requirements:
|
|
61
89
|
|
|
62
|
-
|
|
90
|
+
- Create an HTTP POST endpoint (e.g., `/api/chatbot/query`) that follows `templates/api-route.template.ts`.
|
|
91
|
+
- Load `.env.chatbot` on the server and wire `DATABASE_URL`, `DB_TYPE`, `LLM_PROVIDER`, `LLM_MODEL`, and `LLM_API_KEY` into the handler.
|
|
92
|
+
- Return JSON responses in the same shape as the template handler.
|
|
93
|
+
- Configure CORS/auth so the widget can call your endpoint from the browser.
|
|
63
94
|
|
|
64
|
-
|
|
95
|
+
Frontend usage stays the same:
|
|
65
96
|
|
|
66
|
-
|
|
67
|
-
|
|
97
|
+
```tsx
|
|
98
|
+
import { ChatbotWidget } from 'agenticaichat';
|
|
99
|
+
|
|
100
|
+
export default function Page() {
|
|
101
|
+
return <ChatbotWidget apiPath="/api/chatbot/query" />;
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Configuration Files
|
|
106
|
+
|
|
107
|
+
- `.env.chatbot` holds database connection, LLM provider, model, and API key.
|
|
108
|
+
- `chatbot-config.json` stores non-secret metadata (database/LLM selection).
|
|
109
|
+
- `.gitignore` is updated automatically to keep generated secrets out of version control.
|
|
110
|
+
|
|
111
|
+
## Troubleshooting
|
|
68
112
|
|
|
69
|
-
|
|
113
|
+
- CI environments skip the wizard; run `npx agenticai-setup` locally after install.
|
|
114
|
+
- If the wizard cannot run (non-interactive terminal), rerun manually with the command above.
|
|
115
|
+
- To switch databases or AI providers, rerun the wizard; existing files will be replaced.
|
|
70
116
|
|
|
71
|
-
|
|
117
|
+
## Contributing
|
|
118
|
+
|
|
119
|
+
Contributions are welcome. Please open an issue or pull request with details and reproduction steps.
|
|
120
|
+
|
|
121
|
+
## License
|
|
122
|
+
|
|
123
|
+
MIT License
|
|
124
|
+
|
|
125
|
+
## Support
|
|
126
|
+
|
|
127
|
+
- GitHub: [Issues](https://github.com/Bhaviraj2004/agenticaichat/issues)
|
|
128
|
+
- Email: bhaviraj001@gmail.com
|
package/bin/cli.js
CHANGED
|
@@ -17,68 +17,266 @@ async function main() {
|
|
|
17
17
|
|
|
18
18
|
console.log(chalk.white('Let\'s set up your AI chatbot!\n'));
|
|
19
19
|
|
|
20
|
-
// Step 1: Database
|
|
20
|
+
// Step 1: Database Category
|
|
21
21
|
console.log(chalk.bold.blue('š¦ Step 1: Database Configuration\n'));
|
|
22
22
|
|
|
23
|
-
const
|
|
23
|
+
const dbCategoryAnswer = await inquirer.prompt([
|
|
24
24
|
{
|
|
25
25
|
type: 'list',
|
|
26
|
-
name: '
|
|
27
|
-
message: 'Select
|
|
28
|
-
choices: [
|
|
29
|
-
|
|
26
|
+
name: 'category',
|
|
27
|
+
message: 'Select database category:',
|
|
28
|
+
choices: [
|
|
29
|
+
{
|
|
30
|
+
name: 'SQL Database (PostgreSQL, MySQL, SQLite, etc.)',
|
|
31
|
+
value: 'sql',
|
|
32
|
+
short: 'SQL'
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
name: 'NoSQL Database (MongoDB)',
|
|
36
|
+
value: 'nosql',
|
|
37
|
+
short: 'NoSQL'
|
|
38
|
+
}
|
|
39
|
+
]
|
|
40
|
+
}
|
|
41
|
+
]);
|
|
42
|
+
|
|
43
|
+
let dbType, databaseUrl;
|
|
44
|
+
|
|
45
|
+
// SQL Database Flow
|
|
46
|
+
if (dbCategoryAnswer.category === 'sql') {
|
|
47
|
+
const sqlAnswers = await inquirer.prompt([
|
|
48
|
+
{
|
|
49
|
+
type: 'list',
|
|
50
|
+
name: 'type',
|
|
51
|
+
message: 'Select SQL database:',
|
|
52
|
+
choices: [
|
|
53
|
+
{
|
|
54
|
+
name: 'PostgreSQL\n ' + chalk.gray('Most popular, production-ready'),
|
|
55
|
+
value: 'postgresql',
|
|
56
|
+
short: 'PostgreSQL'
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
name: 'MySQL\n ' + chalk.gray('Web standard, widely used'),
|
|
60
|
+
value: 'mysql',
|
|
61
|
+
short: 'MySQL'
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
name: 'SQLite\n ' + chalk.gray('Local file, perfect for testing'),
|
|
65
|
+
value: 'sqlite',
|
|
66
|
+
short: 'SQLite'
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
name: 'Turso (LibSQL)\n ' + chalk.gray('Modern SQLite, edge-ready'),
|
|
70
|
+
value: 'turso',
|
|
71
|
+
short: 'Turso'
|
|
72
|
+
}
|
|
73
|
+
]
|
|
74
|
+
}
|
|
75
|
+
]);
|
|
76
|
+
|
|
77
|
+
dbType = sqlAnswers.type;
|
|
78
|
+
|
|
79
|
+
// SQLite/Turso - File path based
|
|
80
|
+
if (dbType === 'sqlite' || dbType === 'turso') {
|
|
81
|
+
const fileAnswers = await inquirer.prompt([
|
|
82
|
+
{
|
|
83
|
+
type: 'input',
|
|
84
|
+
name: 'filepath',
|
|
85
|
+
message: 'Database file path:',
|
|
86
|
+
default: './database.db',
|
|
87
|
+
validate: (input) => {
|
|
88
|
+
if (!input || input.trim() === '') {
|
|
89
|
+
return 'File path is required!';
|
|
90
|
+
}
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
]);
|
|
95
|
+
|
|
96
|
+
if (dbType === 'turso') {
|
|
97
|
+
const tursoAnswers = await inquirer.prompt([
|
|
98
|
+
{
|
|
99
|
+
type: 'input',
|
|
100
|
+
name: 'url',
|
|
101
|
+
message: 'Turso database URL (or leave empty for local):',
|
|
102
|
+
default: ''
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
type: 'password',
|
|
106
|
+
name: 'token',
|
|
107
|
+
message: 'Turso auth token (if using cloud):',
|
|
108
|
+
mask: '*',
|
|
109
|
+
when: (answers) => answers.url && answers.url.trim() !== ''
|
|
110
|
+
}
|
|
111
|
+
]);
|
|
112
|
+
|
|
113
|
+
if (tursoAnswers.url && tursoAnswers.url.trim() !== '') {
|
|
114
|
+
databaseUrl = `${tursoAnswers.url}?authToken=${tursoAnswers.token || ''}`;
|
|
115
|
+
} else {
|
|
116
|
+
databaseUrl = `sqlite:///${fileAnswers.filepath}`;
|
|
117
|
+
}
|
|
118
|
+
} else {
|
|
119
|
+
databaseUrl = `sqlite:///${fileAnswers.filepath}`;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
// PostgreSQL/MySQL - Server based
|
|
123
|
+
else {
|
|
124
|
+
const serverAnswers = await inquirer.prompt([
|
|
125
|
+
{
|
|
126
|
+
type: 'input',
|
|
127
|
+
name: 'host',
|
|
128
|
+
message: 'Database host:',
|
|
129
|
+
default: 'localhost'
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
type: 'input',
|
|
133
|
+
name: 'port',
|
|
134
|
+
message: 'Port:',
|
|
135
|
+
default: dbType === 'postgresql' ? '5432' : '3306'
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
type: 'input',
|
|
139
|
+
name: 'user',
|
|
140
|
+
message: 'Username:',
|
|
141
|
+
default: dbType === 'postgresql' ? 'postgres' : 'root'
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
type: 'password',
|
|
145
|
+
name: 'password',
|
|
146
|
+
message: 'Password:',
|
|
147
|
+
mask: '*'
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
type: 'input',
|
|
151
|
+
name: 'database',
|
|
152
|
+
message: 'Database name:',
|
|
153
|
+
default: 'mydb'
|
|
154
|
+
}
|
|
155
|
+
]);
|
|
156
|
+
|
|
157
|
+
if (dbType === 'postgresql') {
|
|
158
|
+
databaseUrl = `postgresql://${serverAnswers.user}:${serverAnswers.password}@${serverAnswers.host}:${serverAnswers.port}/${serverAnswers.database}`;
|
|
159
|
+
} else if (dbType === 'mysql') {
|
|
160
|
+
databaseUrl = `mysql://${serverAnswers.user}:${serverAnswers.password}@${serverAnswers.host}:${serverAnswers.port}/${serverAnswers.database}`;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
console.log(chalk.green(`\nā
${dbType.toUpperCase()} configured!\n`));
|
|
165
|
+
}
|
|
166
|
+
// NoSQL Database Flow
|
|
167
|
+
else {
|
|
168
|
+
const nosqlAnswers = await inquirer.prompt([
|
|
169
|
+
{
|
|
170
|
+
type: 'list',
|
|
171
|
+
name: 'type',
|
|
172
|
+
message: 'Select NoSQL database:',
|
|
173
|
+
choices: [
|
|
174
|
+
{
|
|
175
|
+
name: 'MongoDB\n ' + chalk.gray('Document store, flexible schema'),
|
|
176
|
+
value: 'mongodb',
|
|
177
|
+
short: 'MongoDB'
|
|
178
|
+
}
|
|
179
|
+
]
|
|
180
|
+
}
|
|
181
|
+
]);
|
|
182
|
+
|
|
183
|
+
dbType = nosqlAnswers.type;
|
|
184
|
+
|
|
185
|
+
const mongoAnswers = await inquirer.prompt([
|
|
186
|
+
{
|
|
187
|
+
type: 'input',
|
|
188
|
+
name: 'url',
|
|
189
|
+
message: 'MongoDB connection URL:',
|
|
190
|
+
default: 'mongodb://localhost:27017',
|
|
191
|
+
validate: (input) => {
|
|
192
|
+
if (!input.startsWith('mongodb://') && !input.startsWith('mongodb+srv://')) {
|
|
193
|
+
return 'Invalid MongoDB URL format!';
|
|
194
|
+
}
|
|
195
|
+
return true;
|
|
196
|
+
}
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
type: 'input',
|
|
200
|
+
name: 'database',
|
|
201
|
+
message: 'Database name:',
|
|
202
|
+
default: 'mydb'
|
|
203
|
+
}
|
|
204
|
+
]);
|
|
205
|
+
|
|
206
|
+
databaseUrl = `${mongoAnswers.url}/${mongoAnswers.database}`;
|
|
207
|
+
console.log(chalk.green(`\nā
MongoDB configured!\n`));
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Step 2: AI Provider Configuration
|
|
211
|
+
console.log(chalk.bold.blue('š¤ Step 2: AI Provider Configuration\n'));
|
|
212
|
+
|
|
213
|
+
const llmProviders = [
|
|
214
|
+
{
|
|
215
|
+
name: 'OpenAI (GPT-3.5/GPT-4)',
|
|
216
|
+
value: 'openai',
|
|
217
|
+
description: 'Most popular, reliable, high quality',
|
|
218
|
+
models: ['gpt-3.5-turbo', 'gpt-4', 'gpt-4-turbo']
|
|
30
219
|
},
|
|
31
220
|
{
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
221
|
+
name: 'Google Gemini (1.5 Pro/Flash)',
|
|
222
|
+
value: 'gemini',
|
|
223
|
+
description: 'Fast, affordable, multimodal',
|
|
224
|
+
models: ['gemini-1.5-pro', 'gemini-1.5-flash']
|
|
36
225
|
},
|
|
37
226
|
{
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
if (answers.dbType === 'PostgreSQL') return '5432';
|
|
43
|
-
if (answers.dbType === 'MySQL') return '3306';
|
|
44
|
-
return '27017';
|
|
45
|
-
}
|
|
227
|
+
name: 'Anthropic Claude (Sonnet/Opus/Haiku)',
|
|
228
|
+
value: 'claude',
|
|
229
|
+
description: 'Best reasoning, longest context',
|
|
230
|
+
models: ['claude-3-sonnet-20240229', 'claude-3-opus-20240229', 'claude-3-haiku-20240307']
|
|
46
231
|
},
|
|
47
232
|
{
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
233
|
+
name: 'xAI Grok',
|
|
234
|
+
value: 'grok',
|
|
235
|
+
description: 'Real-time data, Twitter integration',
|
|
236
|
+
models: ['grok-beta']
|
|
52
237
|
},
|
|
53
238
|
{
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
239
|
+
name: 'Together AI',
|
|
240
|
+
value: 'together',
|
|
241
|
+
description: 'Open-source models, cost-effective',
|
|
242
|
+
models: ['mistralai/Mixtral-8x7B-Instruct-v0.1', 'meta-llama/Llama-3-70b-chat-hf']
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
name: 'DeepInfra',
|
|
246
|
+
value: 'deepinfra',
|
|
247
|
+
description: 'Multiple models, serverless',
|
|
248
|
+
models: ['meta-llama/Meta-Llama-3-70B-Instruct', 'mistralai/Mixtral-8x7B-Instruct-v0.1']
|
|
58
249
|
},
|
|
59
250
|
{
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
251
|
+
name: 'Groq',
|
|
252
|
+
value: 'groq',
|
|
253
|
+
description: 'Ultra-fast inference',
|
|
254
|
+
models: ['llama3-70b-8192', 'mixtral-8x7b-32768']
|
|
64
255
|
}
|
|
65
|
-
]
|
|
66
|
-
|
|
67
|
-
// Step 2: OpenAI Configuration
|
|
68
|
-
console.log(chalk.bold.blue('\nš Step 2: OpenAI Configuration\n'));
|
|
256
|
+
];
|
|
69
257
|
|
|
70
|
-
const
|
|
258
|
+
const llmAnswers = await inquirer.prompt([
|
|
259
|
+
{
|
|
260
|
+
type: 'list',
|
|
261
|
+
name: 'provider',
|
|
262
|
+
message: 'Select AI Provider:',
|
|
263
|
+
choices: llmProviders.map(p => ({
|
|
264
|
+
name: `${p.name}\n ${chalk.gray(p.description)}`,
|
|
265
|
+
value: p.value,
|
|
266
|
+
short: p.name
|
|
267
|
+
}))
|
|
268
|
+
},
|
|
71
269
|
{
|
|
72
270
|
type: 'password',
|
|
73
271
|
name: 'apiKey',
|
|
74
|
-
message:
|
|
272
|
+
message: (answers) => {
|
|
273
|
+
const provider = llmProviders.find(p => p.value === answers.provider);
|
|
274
|
+
return `Enter ${provider.name} API Key:`;
|
|
275
|
+
},
|
|
75
276
|
mask: '*',
|
|
76
277
|
validate: (input) => {
|
|
77
|
-
if (!input.
|
|
78
|
-
return '
|
|
79
|
-
}
|
|
80
|
-
if (input.length < 20) {
|
|
81
|
-
return 'API key too short!';
|
|
278
|
+
if (!input || input.trim() === '') {
|
|
279
|
+
return 'API key is required!';
|
|
82
280
|
}
|
|
83
281
|
return true;
|
|
84
282
|
}
|
|
@@ -86,40 +284,43 @@ async function main() {
|
|
|
86
284
|
{
|
|
87
285
|
type: 'list',
|
|
88
286
|
name: 'model',
|
|
89
|
-
message: 'Select
|
|
90
|
-
choices:
|
|
91
|
-
|
|
287
|
+
message: 'Select Model:',
|
|
288
|
+
choices: (answers) => {
|
|
289
|
+
const provider = llmProviders.find(p => p.value === answers.provider);
|
|
290
|
+
return provider.models.map(m => ({
|
|
291
|
+
name: m,
|
|
292
|
+
value: m
|
|
293
|
+
}));
|
|
294
|
+
}
|
|
92
295
|
}
|
|
93
296
|
]);
|
|
94
297
|
|
|
95
|
-
|
|
96
|
-
console.log(chalk.
|
|
97
|
-
|
|
98
|
-
const spinner = ora('Creating files...').start();
|
|
298
|
+
const selectedProvider = llmProviders.find(p => p.value === llmAnswers.provider);
|
|
299
|
+
console.log(chalk.green(`\nā
${selectedProvider.name} configured!\n`));
|
|
99
300
|
|
|
100
|
-
//
|
|
101
|
-
|
|
102
|
-
const dbType = dbAnswers.dbType.toLowerCase();
|
|
301
|
+
// Step 3: Generate configuration files
|
|
302
|
+
console.log(chalk.bold.blue('š Step 3: Generating Configuration Files\n'));
|
|
103
303
|
|
|
104
|
-
|
|
105
|
-
databaseUrl = `postgresql://${dbAnswers.user}:${dbAnswers.password}@${dbAnswers.host}:${dbAnswers.port}/${dbAnswers.database}`;
|
|
106
|
-
} else if (dbType === 'mysql') {
|
|
107
|
-
databaseUrl = `mysql://${dbAnswers.user}:${dbAnswers.password}@${dbAnswers.host}:${dbAnswers.port}/${dbAnswers.database}`;
|
|
108
|
-
} else {
|
|
109
|
-
databaseUrl = `mongodb://${dbAnswers.user}:${dbAnswers.password}@${dbAnswers.host}:${dbAnswers.port}/${dbAnswers.database}`;
|
|
110
|
-
}
|
|
304
|
+
const spinner = ora('Creating files...').start();
|
|
111
305
|
|
|
112
|
-
// Create .env.chatbot
|
|
306
|
+
// Create .env.chatbot file
|
|
113
307
|
const envContent = `# AgenticAIChat Configuration
|
|
114
308
|
# Generated on ${new Date().toISOString()}
|
|
115
309
|
|
|
116
|
-
|
|
117
|
-
|
|
310
|
+
# Database Configuration
|
|
311
|
+
DB_CATEGORY=${dbCategoryAnswer.category}
|
|
118
312
|
DB_TYPE=${dbType}
|
|
119
|
-
|
|
313
|
+
DATABASE_URL=${databaseUrl}
|
|
314
|
+
|
|
315
|
+
# LLM Provider Configuration
|
|
316
|
+
LLM_PROVIDER=${llmAnswers.provider}
|
|
317
|
+
LLM_API_KEY=${llmAnswers.apiKey}
|
|
318
|
+
LLM_MODEL=${llmAnswers.model}
|
|
319
|
+
|
|
320
|
+
# Other
|
|
120
321
|
SECRET_KEY=${crypto.randomBytes(32).toString('hex')}
|
|
121
322
|
CHATBOT_ENABLED=true
|
|
122
|
-
|
|
323
|
+
`.trim();
|
|
123
324
|
|
|
124
325
|
const envPath = path.join(process.cwd(), '.env.chatbot');
|
|
125
326
|
fs.writeFileSync(envPath, envContent);
|
|
@@ -127,32 +328,22 @@ CHATBOT_ENABLED=true
|
|
|
127
328
|
|
|
128
329
|
// Create chatbot-config.json
|
|
129
330
|
const configContent = {
|
|
130
|
-
|
|
131
|
-
|
|
331
|
+
database: {
|
|
332
|
+
category: dbCategoryAnswer.category,
|
|
333
|
+
type: dbType
|
|
334
|
+
},
|
|
335
|
+
llm: {
|
|
336
|
+
provider: llmAnswers.provider,
|
|
337
|
+
model: llmAnswers.model
|
|
338
|
+
},
|
|
132
339
|
setupDate: new Date().toISOString(),
|
|
133
|
-
version: '
|
|
340
|
+
version: '2.0.0'
|
|
134
341
|
};
|
|
135
342
|
|
|
136
343
|
const configPath = path.join(process.cwd(), 'chatbot-config.json');
|
|
137
344
|
fs.writeFileSync(configPath, JSON.stringify(configContent, null, 2));
|
|
138
345
|
spinner.text = 'Created chatbot-config.json';
|
|
139
346
|
|
|
140
|
-
// Update .gitignore
|
|
141
|
-
const gitignorePath = path.join(process.cwd(), '.gitignore');
|
|
142
|
-
let gitignoreContent = '';
|
|
143
|
-
|
|
144
|
-
if (fs.existsSync(gitignorePath)) {
|
|
145
|
-
gitignoreContent = fs.readFileSync(gitignorePath, 'utf8');
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
if (!gitignoreContent.includes('.env.chatbot')) {
|
|
149
|
-
gitignoreContent += '\n# AgenticAIChat\n.env.chatbot\nchatbot-config.json\n';
|
|
150
|
-
fs.writeFileSync(gitignorePath, gitignoreContent);
|
|
151
|
-
spinner.text = 'Updated .gitignore';
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
spinner.succeed('Configuration files created successfully!');
|
|
155
|
-
|
|
156
347
|
// Create API route file
|
|
157
348
|
try {
|
|
158
349
|
const apiDir = path.join(process.cwd(), 'app', 'api', 'chatbot', 'query');
|
|
@@ -161,7 +352,7 @@ CHATBOT_ENABLED=true
|
|
|
161
352
|
}
|
|
162
353
|
|
|
163
354
|
const apiTemplate = fs.readFileSync(
|
|
164
|
-
path.join(__dirname, '..', 'templates', 'api-route.
|
|
355
|
+
path.join(__dirname, '..', 'templates', 'api-route.txt'),
|
|
165
356
|
'utf8'
|
|
166
357
|
);
|
|
167
358
|
|
|
@@ -181,7 +372,7 @@ CHATBOT_ENABLED=true
|
|
|
181
372
|
}
|
|
182
373
|
|
|
183
374
|
const chatTemplate = fs.readFileSync(
|
|
184
|
-
path.join(__dirname, '..', 'templates', 'chat-page.
|
|
375
|
+
path.join(__dirname, '..', 'templates', 'chat-page.txt'),
|
|
185
376
|
'utf8'
|
|
186
377
|
);
|
|
187
378
|
|
|
@@ -193,6 +384,22 @@ CHATBOT_ENABLED=true
|
|
|
193
384
|
console.log(chalk.yellow('\nā¹ļø You can manually create the chat page later'));
|
|
194
385
|
}
|
|
195
386
|
|
|
387
|
+
// Update .gitignore
|
|
388
|
+
const gitignorePath = path.join(process.cwd(), '.gitignore');
|
|
389
|
+
let gitignoreContent = '';
|
|
390
|
+
|
|
391
|
+
if (fs.existsSync(gitignorePath)) {
|
|
392
|
+
gitignoreContent = fs.readFileSync(gitignorePath, 'utf8');
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
if (!gitignoreContent.includes('.env.chatbot')) {
|
|
396
|
+
gitignoreContent += '\n# AgenticAIChat\n.env.chatbot\nchatbot-config.json\n';
|
|
397
|
+
fs.writeFileSync(gitignorePath, gitignoreContent);
|
|
398
|
+
spinner.text = 'Updated .gitignore';
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
spinner.succeed('Configuration files created successfully!');
|
|
402
|
+
|
|
196
403
|
// Success message
|
|
197
404
|
console.log(chalk.green.bold('\nā
Setup Complete!\n'));
|
|
198
405
|
console.log(chalk.white('Files created:'));
|
|
@@ -200,6 +407,16 @@ CHATBOT_ENABLED=true
|
|
|
200
407
|
console.log(chalk.gray(' ⢠chatbot-config.json (settings)'));
|
|
201
408
|
console.log(chalk.gray(' ⢠.gitignore (updated)\n'));
|
|
202
409
|
|
|
410
|
+
console.log(chalk.white('Database Configuration:'));
|
|
411
|
+
console.log(chalk.cyan(` ⢠Category: ${dbCategoryAnswer.category.toUpperCase()}`));
|
|
412
|
+
console.log(chalk.cyan(` ⢠Type: ${dbType}`));
|
|
413
|
+
console.log(chalk.gray(` ⢠URL: ${databaseUrl.substring(0, 50)}...\n`));
|
|
414
|
+
|
|
415
|
+
console.log(chalk.white('AI Provider Configuration:'));
|
|
416
|
+
console.log(chalk.cyan(` ⢠Provider: ${selectedProvider.name}`));
|
|
417
|
+
console.log(chalk.cyan(` ⢠Model: ${llmAnswers.model}`));
|
|
418
|
+
console.log(chalk.gray(` ⢠API Key: ${'*'.repeat(20)}\n`));
|
|
419
|
+
|
|
203
420
|
console.log(chalk.white('Next steps:\n'));
|
|
204
421
|
console.log(chalk.yellow('1. Add the widget to your Next.js app:\n'));
|
|
205
422
|
console.log(chalk.cyan(' import { ChatbotWidget } from "agenticaichat";'));
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ChatbotConfig, QueryRequest, QueryResponse, DatabaseSchema } from '../types';
|
|
2
2
|
export declare class ChatbotEngine {
|
|
3
|
-
private
|
|
3
|
+
private dbEngine;
|
|
4
4
|
private nlConverter;
|
|
5
5
|
private schema;
|
|
6
6
|
private initialized;
|
|
@@ -25,4 +25,12 @@ export declare class ChatbotEngine {
|
|
|
25
25
|
* Get current schema
|
|
26
26
|
*/
|
|
27
27
|
getSchema(): DatabaseSchema | null;
|
|
28
|
+
/**
|
|
29
|
+
* Get database engine status
|
|
30
|
+
*/
|
|
31
|
+
getStatus(): {
|
|
32
|
+
initialized: boolean;
|
|
33
|
+
engine: import("../types").EngineStatus;
|
|
34
|
+
schema: string;
|
|
35
|
+
};
|
|
28
36
|
}
|