agenticaichat 1.0.1 ā 1.0.4
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 +208 -26
- package/bin/cli.js +406 -118
- package/dist/adapters/angular.d.ts +9 -0
- package/dist/adapters/angular.js +6 -0
- package/dist/adapters/react.d.ts +1 -0
- package/dist/adapters/react.js +8 -0
- package/dist/adapters/vue.d.ts +9 -0
- package/dist/adapters/vue.js +6 -0
- 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 +20 -4
- package/dist/index.js +63 -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/bin/cli.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
1
|
+
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
const inquirer = require('inquirer').default;
|
|
4
4
|
const chalk = require('chalk');
|
|
@@ -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']
|
|
58
243
|
},
|
|
59
244
|
{
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
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']
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
name: 'Groq',
|
|
252
|
+
value: 'groq',
|
|
253
|
+
description: 'Ultra-fast inference',
|
|
254
|
+
models: ['llama3-70b-8192', 'mixtral-8x7b-32768']
|
|
64
255
|
}
|
|
65
|
-
]
|
|
256
|
+
];
|
|
66
257
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
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,79 @@ 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
|
-
|
|
301
|
+
// Step 3: Frontend Framework / Adapter
|
|
302
|
+
console.log(chalk.bold.blue('\nš§© Step 3: Frontend Framework\n'));
|
|
303
|
+
|
|
304
|
+
const frontendAnswers = await inquirer.prompt([
|
|
305
|
+
{
|
|
306
|
+
type: 'list',
|
|
307
|
+
name: 'framework',
|
|
308
|
+
message: 'Which frontend framework will you use for the chat UI?',
|
|
309
|
+
choices: [
|
|
310
|
+
{
|
|
311
|
+
name: 'Next.js / React (recommended, uses built-in ChatbotWidget)',
|
|
312
|
+
value: 'react',
|
|
313
|
+
short: 'React'
|
|
314
|
+
},
|
|
315
|
+
{
|
|
316
|
+
name: 'Angular (use HTTP API from your Angular component)',
|
|
317
|
+
value: 'angular',
|
|
318
|
+
short: 'Angular'
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
name: 'Vue (use HTTP API from your Vue component)',
|
|
322
|
+
value: 'vue',
|
|
323
|
+
short: 'Vue'
|
|
324
|
+
},
|
|
325
|
+
{
|
|
326
|
+
name: 'Other / Backend-only (no bundled UI, HTTP API only)',
|
|
327
|
+
value: 'other',
|
|
328
|
+
short: 'Other'
|
|
329
|
+
}
|
|
330
|
+
]
|
|
331
|
+
}
|
|
332
|
+
]);
|
|
333
|
+
|
|
334
|
+
// Step 4: Generate configuration files
|
|
335
|
+
console.log(chalk.bold.blue('š Step 4: Generating Configuration Files\n'));
|
|
103
336
|
|
|
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
|
-
}
|
|
337
|
+
const spinner = ora('Creating files...').start();
|
|
111
338
|
|
|
112
|
-
// Create .env.chatbot
|
|
339
|
+
// Create .env.chatbot file
|
|
113
340
|
const envContent = `# AgenticAIChat Configuration
|
|
114
341
|
# Generated on ${new Date().toISOString()}
|
|
115
342
|
|
|
116
|
-
|
|
117
|
-
|
|
343
|
+
# Database Configuration
|
|
344
|
+
DB_CATEGORY=${dbCategoryAnswer.category}
|
|
118
345
|
DB_TYPE=${dbType}
|
|
119
|
-
|
|
346
|
+
DATABASE_URL=${databaseUrl}
|
|
347
|
+
|
|
348
|
+
# LLM Provider Configuration
|
|
349
|
+
LLM_PROVIDER=${llmAnswers.provider}
|
|
350
|
+
LLM_API_KEY=${llmAnswers.apiKey}
|
|
351
|
+
LLM_MODEL=${llmAnswers.model}
|
|
352
|
+
|
|
353
|
+
# Frontend Adapter
|
|
354
|
+
FRONTEND_FRAMEWORK=${frontendAnswers.framework}
|
|
355
|
+
|
|
356
|
+
# Other
|
|
120
357
|
SECRET_KEY=${crypto.randomBytes(32).toString('hex')}
|
|
121
358
|
CHATBOT_ENABLED=true
|
|
122
|
-
|
|
359
|
+
`.trim();
|
|
123
360
|
|
|
124
361
|
const envPath = path.join(process.cwd(), '.env.chatbot');
|
|
125
362
|
fs.writeFileSync(envPath, envContent);
|
|
@@ -127,16 +364,73 @@ CHATBOT_ENABLED=true
|
|
|
127
364
|
|
|
128
365
|
// Create chatbot-config.json
|
|
129
366
|
const configContent = {
|
|
130
|
-
|
|
131
|
-
|
|
367
|
+
database: {
|
|
368
|
+
category: dbCategoryAnswer.category,
|
|
369
|
+
type: dbType
|
|
370
|
+
},
|
|
371
|
+
llm: {
|
|
372
|
+
provider: llmAnswers.provider,
|
|
373
|
+
model: llmAnswers.model
|
|
374
|
+
},
|
|
375
|
+
frontend: {
|
|
376
|
+
framework: frontendAnswers.framework
|
|
377
|
+
},
|
|
132
378
|
setupDate: new Date().toISOString(),
|
|
133
|
-
version: '
|
|
379
|
+
version: '2.0.0'
|
|
134
380
|
};
|
|
135
381
|
|
|
136
382
|
const configPath = path.join(process.cwd(), 'chatbot-config.json');
|
|
137
383
|
fs.writeFileSync(configPath, JSON.stringify(configContent, null, 2));
|
|
138
384
|
spinner.text = 'Created chatbot-config.json';
|
|
139
385
|
|
|
386
|
+
// Create frontend scaffolding based on selected framework
|
|
387
|
+
if (frontendAnswers.framework === 'react') {
|
|
388
|
+
// Next.js / React: generate app router files
|
|
389
|
+
try {
|
|
390
|
+
const apiDir = path.join(process.cwd(), 'app', 'api', 'chatbot', 'query');
|
|
391
|
+
if (!fs.existsSync(apiDir)) {
|
|
392
|
+
fs.mkdirSync(apiDir, { recursive: true });
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
const apiTemplate = fs.readFileSync(
|
|
396
|
+
path.join(__dirname, '..', 'templates', 'api-route.txt'),
|
|
397
|
+
'utf8'
|
|
398
|
+
);
|
|
399
|
+
|
|
400
|
+
const apiPath = path.join(apiDir, 'route.ts');
|
|
401
|
+
fs.writeFileSync(apiPath, apiTemplate);
|
|
402
|
+
spinner.text = 'Created API route: app/api/chatbot/query/route.ts';
|
|
403
|
+
} catch (error) {
|
|
404
|
+
spinner.warn('Could not create API route automatically');
|
|
405
|
+
console.log(chalk.yellow('\nā¹ļø You can manually create the API route later'));
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
try {
|
|
409
|
+
const chatDir = path.join(process.cwd(), 'app', 'chat');
|
|
410
|
+
if (!fs.existsSync(chatDir)) {
|
|
411
|
+
fs.mkdirSync(chatDir, { recursive: true });
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
const chatTemplate = fs.readFileSync(
|
|
415
|
+
path.join(__dirname, '..', 'templates', 'chat-page.txt'),
|
|
416
|
+
'utf8'
|
|
417
|
+
);
|
|
418
|
+
|
|
419
|
+
const chatPath = path.join(chatDir, 'page.tsx');
|
|
420
|
+
fs.writeFileSync(chatPath, chatTemplate);
|
|
421
|
+
spinner.text = 'Created chat page: app/chat/page.tsx';
|
|
422
|
+
} catch (error) {
|
|
423
|
+
spinner.warn('Could not create chat page automatically');
|
|
424
|
+
console.log(chalk.yellow('\nā¹ļø You can manually create the chat page later'));
|
|
425
|
+
}
|
|
426
|
+
} else {
|
|
427
|
+
// Non-React frameworks: keep backend-only scaffolding, user builds UI
|
|
428
|
+
spinner.text = 'Backend configured (HTTP API). Frontend adapter to be implemented in your framework.';
|
|
429
|
+
console.log(chalk.yellow('\nā¹ļø Frontend note:'));
|
|
430
|
+
console.log(chalk.gray(' - Use the /api/chatbot/query HTTP endpoint from your Angular/Vue/other component.'));
|
|
431
|
+
console.log(chalk.gray(' - See README for framework-specific adapter guidance.\n'));
|
|
432
|
+
}
|
|
433
|
+
|
|
140
434
|
// Update .gitignore
|
|
141
435
|
const gitignorePath = path.join(process.cwd(), '.gitignore');
|
|
142
436
|
let gitignoreContent = '';
|
|
@@ -153,64 +447,58 @@ CHATBOT_ENABLED=true
|
|
|
153
447
|
|
|
154
448
|
spinner.succeed('Configuration files created successfully!');
|
|
155
449
|
|
|
156
|
-
// Create API route file
|
|
157
|
-
try {
|
|
158
|
-
const apiDir = path.join(process.cwd(), 'app', 'api', 'chatbot', 'query');
|
|
159
|
-
if (!fs.existsSync(apiDir)) {
|
|
160
|
-
fs.mkdirSync(apiDir, { recursive: true });
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
const apiTemplate = fs.readFileSync(
|
|
164
|
-
path.join(__dirname, '..', 'templates', 'api-route.template.ts'),
|
|
165
|
-
'utf8'
|
|
166
|
-
);
|
|
167
|
-
|
|
168
|
-
const apiPath = path.join(apiDir, 'route.ts');
|
|
169
|
-
fs.writeFileSync(apiPath, apiTemplate);
|
|
170
|
-
spinner.text = 'Created API route: app/api/chatbot/query/route.ts';
|
|
171
|
-
} catch (error) {
|
|
172
|
-
spinner.warn('Could not create API route automatically');
|
|
173
|
-
console.log(chalk.yellow('\nā¹ļø You can manually create the API route later'));
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
// Create chat page
|
|
177
|
-
try {
|
|
178
|
-
const chatDir = path.join(process.cwd(), 'app', 'chat');
|
|
179
|
-
if (!fs.existsSync(chatDir)) {
|
|
180
|
-
fs.mkdirSync(chatDir, { recursive: true });
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
const chatTemplate = fs.readFileSync(
|
|
184
|
-
path.join(__dirname, '..', 'templates', 'chat-page.template.tsx'),
|
|
185
|
-
'utf8'
|
|
186
|
-
);
|
|
187
|
-
|
|
188
|
-
const chatPath = path.join(chatDir, 'page.tsx');
|
|
189
|
-
fs.writeFileSync(chatPath, chatTemplate);
|
|
190
|
-
spinner.text = 'Created chat page: app/chat/page.tsx';
|
|
191
|
-
} catch (error) {
|
|
192
|
-
spinner.warn('Could not create chat page automatically');
|
|
193
|
-
console.log(chalk.yellow('\nā¹ļø You can manually create the chat page later'));
|
|
194
|
-
}
|
|
195
|
-
|
|
196
450
|
// Success message
|
|
197
451
|
console.log(chalk.green.bold('\nā
Setup Complete!\n'));
|
|
198
452
|
console.log(chalk.white('Files created:'));
|
|
199
|
-
console.log(chalk.gray(' ⢠.env.chatbot (API keys
|
|
200
|
-
console.log(chalk.gray(' ⢠chatbot-config.json (settings)'));
|
|
453
|
+
console.log(chalk.gray(' ⢠.env.chatbot (API keys, database, LLM, frontend framework)'));
|
|
454
|
+
console.log(chalk.gray(' ⢠chatbot-config.json (settings, including frontend framework)'));
|
|
201
455
|
console.log(chalk.gray(' ⢠.gitignore (updated)\n'));
|
|
202
456
|
|
|
457
|
+
console.log(chalk.white('Database Configuration:'));
|
|
458
|
+
console.log(chalk.cyan(` ⢠Category: ${dbCategoryAnswer.category.toUpperCase()}`));
|
|
459
|
+
console.log(chalk.cyan(` ⢠Type: ${dbType}`));
|
|
460
|
+
console.log(chalk.gray(` ⢠URL: ${databaseUrl.substring(0, 50)}...\n`));
|
|
461
|
+
|
|
462
|
+
console.log(chalk.white('AI Provider Configuration:'));
|
|
463
|
+
console.log(chalk.cyan(` ⢠Provider: ${selectedProvider.name}`));
|
|
464
|
+
console.log(chalk.cyan(` ⢠Model: ${llmAnswers.model}`));
|
|
465
|
+
console.log(chalk.gray(` ⢠API Key: ${'*'.repeat(20)}\n`));
|
|
466
|
+
|
|
467
|
+
console.log(chalk.white('Frontend Framework:'));
|
|
468
|
+
console.log(chalk.cyan(` ⢠Framework: ${frontendAnswers.framework}\n`));
|
|
469
|
+
|
|
203
470
|
console.log(chalk.white('Next steps:\n'));
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
471
|
+
if (frontendAnswers.framework === 'react') {
|
|
472
|
+
console.log(chalk.yellow('1. Add the widget to your Next.js/React app:\n'));
|
|
473
|
+
console.log(chalk.cyan(' import { ChatbotWidget } from "agenticaichat";'));
|
|
474
|
+
console.log(chalk.cyan(' \n <ChatbotWidget />\n'));
|
|
475
|
+
|
|
476
|
+
console.log(chalk.yellow('2. Or create a full-page chat route:\n'));
|
|
477
|
+
console.log(chalk.cyan(' // app/chat/page.tsx'));
|
|
478
|
+
console.log(chalk.cyan(' <ChatbotWidget fullScreen />\n'));
|
|
211
479
|
|
|
212
|
-
|
|
213
|
-
|
|
480
|
+
console.log(chalk.yellow('3. Start your development server:\n'));
|
|
481
|
+
console.log(chalk.cyan(' npm run dev\n'));
|
|
482
|
+
} else if (frontendAnswers.framework === 'angular') {
|
|
483
|
+
console.log(chalk.yellow('1. Set up a backend API endpoint (see README for details).\n'));
|
|
484
|
+
console.log(chalk.yellow('2. Create an Angular component like this:\n'));
|
|
485
|
+
console.log(chalk.cyan(' // chatbot.component.ts'));
|
|
486
|
+
console.log(chalk.cyan(' import { HttpClient } from "@angular/common/http";'));
|
|
487
|
+
console.log(chalk.cyan(' // ... component code to POST to /api/chatbot/query\n'));
|
|
488
|
+
console.log(chalk.yellow('3. See README.md for complete Angular setup example.\n'));
|
|
489
|
+
} else if (frontendAnswers.framework === 'vue') {
|
|
490
|
+
console.log(chalk.yellow('1. Set up a backend API endpoint (see README for details).\n'));
|
|
491
|
+
console.log(chalk.yellow('2. Create a Vue component like this:\n'));
|
|
492
|
+
console.log(chalk.cyan(' // Chatbot.vue'));
|
|
493
|
+
console.log(chalk.cyan(' <script setup>'));
|
|
494
|
+
console.log(chalk.cyan(' const response = await fetch("/api/chatbot/query", { ... });'));
|
|
495
|
+
console.log(chalk.cyan(' </script>\n'));
|
|
496
|
+
console.log(chalk.yellow('3. See README.md for complete Vue setup example.\n'));
|
|
497
|
+
} else {
|
|
498
|
+
console.log(chalk.yellow('1. Implement a small adapter/component in your framework that calls:\n'));
|
|
499
|
+
console.log(chalk.cyan(' POST /api/chatbot/query { query: string }\n'));
|
|
500
|
+
console.log(chalk.yellow('2. Use the response to render messages in your UI.\n'));
|
|
501
|
+
}
|
|
214
502
|
|
|
215
503
|
console.log(chalk.white('Need help? Visit: ') + chalk.blue('https://github.com/yourusername/agenticaichat\n'));
|
|
216
504
|
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Placeholder types and helper for Angular adapters.
|
|
3
|
+
// Angular users should create their own component/service that calls the HTTP API:
|
|
4
|
+
// POST /api/chatbot/query { query: string }
|
|
5
|
+
// and handles the JSON response.
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ChatbotWidget as ReactChatbotWidget } from '../widget';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ReactChatbotWidget = void 0;
|
|
4
|
+
// Thin alias so future adapters can share a consistent naming scheme.
|
|
5
|
+
// React users should continue to import from "agenticaichat" directly,
|
|
6
|
+
// but this adapter is exposed for symmetry with Angular/Vue.
|
|
7
|
+
var widget_1 = require("../widget");
|
|
8
|
+
Object.defineProperty(exports, "ReactChatbotWidget", { enumerable: true, get: function () { return widget_1.ChatbotWidget; } });
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Placeholder types and helper for Vue adapters.
|
|
3
|
+
// Vue users should create their own component/composable that calls the HTTP API:
|
|
4
|
+
// POST /api/chatbot/query { query: string }
|
|
5
|
+
// and handles the JSON response.
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -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
|
}
|