agenticaichat 1.0.4 → 1.0.6
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 +60 -22
- package/bin/cli.js +9 -12
- package/dist/web-component/AgenticAIChatbot.js +219 -0
- package/dist/web-component/index.js +2 -0
- package/package.json +12 -6
- package/src/web-component/AgenticAIChatbot.js +219 -0
- package/src/web-component/index.js +2 -0
package/README.md
CHANGED
|
@@ -6,7 +6,8 @@ AI-powered chatbot for business analytics with natural language database queries
|
|
|
6
6
|
- Five-minute setup with an interactive CLI wizard
|
|
7
7
|
- Natural language questions in English or Hindi
|
|
8
8
|
- Works with PostgreSQL, MySQL, SQLite, Turso, and MongoDB
|
|
9
|
-
-
|
|
9
|
+
- Universal Web Component for any framework (React, Angular, Vue, Next.js, HTML)
|
|
10
|
+
- Ready-to-use React/Next.js widget for advanced dashboards
|
|
10
11
|
- Configuration files generated for you (`.env.chatbot`, `chatbot-config.json`)
|
|
11
12
|
- Fully typed TypeScript package
|
|
12
13
|
|
|
@@ -15,36 +16,41 @@ AI-powered chatbot for business analytics with natural language database queries
|
|
|
15
16
|
- Node.js 18+ and npm 9+
|
|
16
17
|
- React 18+ and Next.js 13+ (app router recommended) for the built-in widget
|
|
17
18
|
|
|
18
|
-
##
|
|
19
|
+
## Universal Web Component (Recommended for All Frameworks)
|
|
19
20
|
|
|
20
|
-
|
|
21
|
+
For the best compatibility across all frameworks and plain HTML, use our universal Web Component:
|
|
21
22
|
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
```html
|
|
24
|
+
<script src="https://cdn.jsdelivr.net/npm/agenticaichat/dist/web-component/index.js"></script>
|
|
25
|
+
<agentica-chatbot api="/api/chatbot/query"></agentica-chatbot>
|
|
26
|
+
```
|
|
25
27
|
|
|
26
|
-
|
|
27
|
-
yarn add agenticaichat
|
|
28
|
+
Or import in your framework:
|
|
28
29
|
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
```javascript
|
|
31
|
+
// React, Vue, Angular, etc.
|
|
32
|
+
import 'agenticaichat/web-component';
|
|
31
33
|
```
|
|
32
34
|
|
|
33
|
-
|
|
35
|
+
This works everywhere without framework-specific code.
|
|
34
36
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
37
|
+
## Widget vs Web Component — When to Use What?
|
|
38
|
+
|
|
39
|
+
AgenticAIChat offers two ways to integrate the chatbot:
|
|
38
40
|
|
|
39
|
-
|
|
41
|
+
1. **React/Next.js Widget (Advanced UI)**
|
|
42
|
+
- Fully designed UI with animations and chat history
|
|
43
|
+
- Best for dashboards and full-page experiences
|
|
44
|
+
- Uses React internally
|
|
45
|
+
- Ideal for Next.js apps
|
|
40
46
|
|
|
41
|
-
|
|
42
|
-
-
|
|
43
|
-
-
|
|
44
|
-
-
|
|
45
|
-
-
|
|
47
|
+
2. **Web Component (Universal) — Recommended**
|
|
48
|
+
- Works in React, Angular, Vue, Next.js, Svelte, plain HTML
|
|
49
|
+
- No framework dependencies
|
|
50
|
+
- Perfect for embedding on external websites
|
|
51
|
+
- Lightweight and self-contained
|
|
46
52
|
|
|
47
|
-
If
|
|
53
|
+
If unsure, use the Web Component for maximum compatibility.
|
|
48
54
|
|
|
49
55
|
## Quick Start (Next.js)
|
|
50
56
|
|
|
@@ -86,7 +92,7 @@ npm run dev
|
|
|
86
92
|
For all frameworks, you need a backend endpoint that handles chatbot queries. The setup wizard generates configuration files, but you must implement the API route yourself unless using Next.js.
|
|
87
93
|
|
|
88
94
|
1. Run the setup wizard to generate `.env.chatbot` and `chatbot-config.json`:
|
|
89
|
-
|
|
95
|
+
|
|
90
96
|
```bash
|
|
91
97
|
npx agenticai-setup
|
|
92
98
|
```
|
|
@@ -121,8 +127,19 @@ app.listen(3000);
|
|
|
121
127
|
|
|
122
128
|
For Next.js, the wizard generates this automatically.
|
|
123
129
|
|
|
130
|
+
**Important: Enable CORS**
|
|
131
|
+
If your frontend and backend are on different domains or ports, enable CORS in your backend:
|
|
132
|
+
```
|
|
133
|
+
Access-Control-Allow-Origin: *
|
|
134
|
+
```
|
|
135
|
+
Or restrict to your specific domain for security.
|
|
136
|
+
|
|
124
137
|
## Setup for Angular
|
|
125
138
|
|
|
139
|
+
**Recommended:** Use the universal Web Component for easiest integration. See the Web Component section above.
|
|
140
|
+
|
|
141
|
+
If you prefer a custom Angular component:
|
|
142
|
+
|
|
126
143
|
1. Install the package and run setup:
|
|
127
144
|
|
|
128
145
|
```bash
|
|
@@ -168,6 +185,10 @@ export class ChatbotComponent {
|
|
|
168
185
|
|
|
169
186
|
## Setup for Vue
|
|
170
187
|
|
|
188
|
+
**Recommended:** Use the universal Web Component for easiest integration. See the Web Component section above.
|
|
189
|
+
|
|
190
|
+
If you prefer a custom Vue component:
|
|
191
|
+
|
|
171
192
|
1. Install the package and run setup:
|
|
172
193
|
|
|
173
194
|
```bash
|
|
@@ -233,6 +254,23 @@ export default function Page() {
|
|
|
233
254
|
- `chatbot-config.json` stores non-secret metadata (database/LLM selection).
|
|
234
255
|
- `.gitignore` is updated automatically to keep generated secrets out of version control.
|
|
235
256
|
|
|
257
|
+
## Architecture Summary
|
|
258
|
+
|
|
259
|
+
```
|
|
260
|
+
[Browser: React/Angular/Vue/HTML/Next.js]
|
|
261
|
+
|
|
|
262
|
+
V
|
|
263
|
+
<agentica-chatbot web component>
|
|
264
|
+
|
|
|
265
|
+
V
|
|
266
|
+
Your Backend API (/api/chatbot/query)
|
|
267
|
+
|
|
|
268
|
+
V
|
|
269
|
+
ChatbotEngine → LLM / Database / Business Logic
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
The Web Component handles all frontend interactions and works universally across frameworks.
|
|
273
|
+
|
|
236
274
|
## Troubleshooting
|
|
237
275
|
|
|
238
276
|
- CI environments skip the wizard; run `npx agenticai-setup` locally after install.
|
package/bin/cli.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
const inquirer = require('inquirer')
|
|
3
|
+
const inquirer = require('inquirer');
|
|
4
4
|
const chalk = require('chalk');
|
|
5
5
|
const ora = require('ora');
|
|
6
6
|
const fs = require('fs');
|
|
@@ -481,19 +481,16 @@ CHATBOT_ENABLED=true
|
|
|
481
481
|
console.log(chalk.cyan(' npm run dev\n'));
|
|
482
482
|
} else if (frontendAnswers.framework === 'angular') {
|
|
483
483
|
console.log(chalk.yellow('1. Set up a backend API endpoint (see README for details).\n'));
|
|
484
|
-
console.log(chalk.yellow('2.
|
|
485
|
-
console.log(chalk.cyan('
|
|
486
|
-
console.log(chalk.cyan('
|
|
487
|
-
console.log(chalk.
|
|
488
|
-
console.log(chalk.yellow('3. See README.md for complete Angular setup example.\n'));
|
|
484
|
+
console.log(chalk.yellow('2. Use the universal Web Component:\n'));
|
|
485
|
+
console.log(chalk.cyan(' import "agenticaichat/web-component";'));
|
|
486
|
+
console.log(chalk.cyan(' <agentica-chatbot api="/api/chatbot/query"></agentica-chatbot>\n'));
|
|
487
|
+
console.log(chalk.yellow('3. Or create a custom Angular component (see README).\n'));
|
|
489
488
|
} else if (frontendAnswers.framework === 'vue') {
|
|
490
489
|
console.log(chalk.yellow('1. Set up a backend API endpoint (see README for details).\n'));
|
|
491
|
-
console.log(chalk.yellow('2.
|
|
492
|
-
console.log(chalk.cyan('
|
|
493
|
-
console.log(chalk.cyan(' <
|
|
494
|
-
console.log(chalk.
|
|
495
|
-
console.log(chalk.cyan(' </script>\n'));
|
|
496
|
-
console.log(chalk.yellow('3. See README.md for complete Vue setup example.\n'));
|
|
490
|
+
console.log(chalk.yellow('2. Use the universal Web Component:\n'));
|
|
491
|
+
console.log(chalk.cyan(' import "agenticaichat/web-component";'));
|
|
492
|
+
console.log(chalk.cyan(' <agentica-chatbot api="/api/chatbot/query"></agentica-chatbot>\n'));
|
|
493
|
+
console.log(chalk.yellow('3. Or create a custom Vue component (see README).\n'));
|
|
497
494
|
} else {
|
|
498
495
|
console.log(chalk.yellow('1. Implement a small adapter/component in your framework that calls:\n'));
|
|
499
496
|
console.log(chalk.cyan(' POST /api/chatbot/query { query: string }\n'));
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
class AgenticAIChatbot extends HTMLElement {
|
|
2
|
+
constructor() {
|
|
3
|
+
super();
|
|
4
|
+
this.attachShadow({ mode: 'open' });
|
|
5
|
+
this.apiUrl = this.getAttribute('api') || '/api/chatbot/query';
|
|
6
|
+
this.messages = [];
|
|
7
|
+
this.isOpen = false;
|
|
8
|
+
this.isTyping = false;
|
|
9
|
+
this.render();
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
connectedCallback() {
|
|
13
|
+
this.setupEventListeners();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
render() {
|
|
17
|
+
this.shadowRoot.innerHTML = `
|
|
18
|
+
<style>
|
|
19
|
+
:host {
|
|
20
|
+
position: fixed;
|
|
21
|
+
bottom: 20px;
|
|
22
|
+
right: 20px;
|
|
23
|
+
z-index: 9999;
|
|
24
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.chat-container {
|
|
28
|
+
display: ${this.isOpen ? 'block' : 'none'};
|
|
29
|
+
width: 350px;
|
|
30
|
+
height: 500px;
|
|
31
|
+
background: white;
|
|
32
|
+
border-radius: 12px;
|
|
33
|
+
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
|
|
34
|
+
overflow: hidden;
|
|
35
|
+
position: relative;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.chat-header {
|
|
39
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
40
|
+
color: white;
|
|
41
|
+
padding: 16px;
|
|
42
|
+
font-weight: 600;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.chat-messages {
|
|
46
|
+
height: 380px;
|
|
47
|
+
overflow-y: auto;
|
|
48
|
+
padding: 16px;
|
|
49
|
+
background: #f8f9fa;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.message {
|
|
53
|
+
margin-bottom: 12px;
|
|
54
|
+
padding: 8px 12px;
|
|
55
|
+
border-radius: 8px;
|
|
56
|
+
max-width: 80%;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.message.user {
|
|
60
|
+
background: #007bff;
|
|
61
|
+
color: white;
|
|
62
|
+
margin-left: auto;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.message.bot {
|
|
66
|
+
background: white;
|
|
67
|
+
color: #333;
|
|
68
|
+
border: 1px solid #e9ecef;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.typing {
|
|
72
|
+
display: ${this.isTyping ? 'block' : 'none'};
|
|
73
|
+
font-style: italic;
|
|
74
|
+
color: #666;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.chat-input {
|
|
78
|
+
padding: 16px;
|
|
79
|
+
background: white;
|
|
80
|
+
border-top: 1px solid #e9ecef;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.input-group {
|
|
84
|
+
display: flex;
|
|
85
|
+
gap: 8px;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
input {
|
|
89
|
+
flex: 1;
|
|
90
|
+
padding: 8px 12px;
|
|
91
|
+
border: 1px solid #ddd;
|
|
92
|
+
border-radius: 6px;
|
|
93
|
+
outline: none;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
button {
|
|
97
|
+
padding: 8px 16px;
|
|
98
|
+
background: #007bff;
|
|
99
|
+
color: white;
|
|
100
|
+
border: none;
|
|
101
|
+
border-radius: 6px;
|
|
102
|
+
cursor: pointer;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
button:hover {
|
|
106
|
+
background: #0056b3;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.chat-toggle {
|
|
110
|
+
width: 60px;
|
|
111
|
+
height: 60px;
|
|
112
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
113
|
+
border-radius: 50%;
|
|
114
|
+
border: none;
|
|
115
|
+
color: white;
|
|
116
|
+
font-size: 24px;
|
|
117
|
+
cursor: pointer;
|
|
118
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
|
|
119
|
+
display: flex;
|
|
120
|
+
align-items: center;
|
|
121
|
+
justify-content: center;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.chat-toggle:hover {
|
|
125
|
+
transform: scale(1.05);
|
|
126
|
+
}
|
|
127
|
+
</style>
|
|
128
|
+
|
|
129
|
+
<div class="chat-container">
|
|
130
|
+
<div class="chat-header">
|
|
131
|
+
🤖 AgenticAI Chatbot
|
|
132
|
+
</div>
|
|
133
|
+
<div class="chat-messages" id="messages">
|
|
134
|
+
${this.messages.map(msg => `
|
|
135
|
+
<div class="message ${msg.sender}">
|
|
136
|
+
${msg.text}
|
|
137
|
+
</div>
|
|
138
|
+
`).join('')}
|
|
139
|
+
<div class="message bot typing" id="typing">Typing...</div>
|
|
140
|
+
</div>
|
|
141
|
+
<div class="chat-input">
|
|
142
|
+
<div class="input-group">
|
|
143
|
+
<input type="text" id="messageInput" placeholder="Ask me anything..." />
|
|
144
|
+
<button id="sendButton">Send</button>
|
|
145
|
+
</div>
|
|
146
|
+
</div>
|
|
147
|
+
</div>
|
|
148
|
+
|
|
149
|
+
<button class="chat-toggle" id="toggleButton">
|
|
150
|
+
${this.isOpen ? '✕' : '💬'}
|
|
151
|
+
</button>
|
|
152
|
+
`;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
setupEventListeners() {
|
|
156
|
+
const toggleButton = this.shadowRoot.getElementById('toggleButton');
|
|
157
|
+
const sendButton = this.shadowRoot.getElementById('sendButton');
|
|
158
|
+
const messageInput = this.shadowRoot.getElementById('messageInput');
|
|
159
|
+
|
|
160
|
+
toggleButton.addEventListener('click', () => {
|
|
161
|
+
this.isOpen = !this.isOpen;
|
|
162
|
+
this.render();
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
sendButton.addEventListener('click', () => this.sendMessage());
|
|
166
|
+
messageInput.addEventListener('keypress', (e) => {
|
|
167
|
+
if (e.key === 'Enter') this.sendMessage();
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
async sendMessage() {
|
|
172
|
+
const messageInput = this.shadowRoot.getElementById('messageInput');
|
|
173
|
+
const query = messageInput.value.trim();
|
|
174
|
+
if (!query) return;
|
|
175
|
+
|
|
176
|
+
// Add user message
|
|
177
|
+
this.messages.push({ sender: 'user', text: query });
|
|
178
|
+
messageInput.value = '';
|
|
179
|
+
this.render();
|
|
180
|
+
|
|
181
|
+
// Show typing
|
|
182
|
+
this.isTyping = true;
|
|
183
|
+
this.render();
|
|
184
|
+
|
|
185
|
+
try {
|
|
186
|
+
const response = await fetch(this.apiUrl, {
|
|
187
|
+
method: 'POST',
|
|
188
|
+
headers: {
|
|
189
|
+
'Content-Type': 'application/json',
|
|
190
|
+
},
|
|
191
|
+
body: JSON.stringify({ query }),
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
const data = await response.json();
|
|
195
|
+
|
|
196
|
+
// Hide typing
|
|
197
|
+
this.isTyping = false;
|
|
198
|
+
|
|
199
|
+
if (data.error) {
|
|
200
|
+
this.messages.push({ sender: 'bot', text: `Error: ${data.error}` });
|
|
201
|
+
} else {
|
|
202
|
+
this.messages.push({ sender: 'bot', text: data.answer || data.reply || 'No response' });
|
|
203
|
+
}
|
|
204
|
+
} catch (error) {
|
|
205
|
+
this.isTyping = false;
|
|
206
|
+
this.messages.push({ sender: 'bot', text: 'Sorry, I encountered an error. Please try again.' });
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
this.render();
|
|
210
|
+
this.scrollToBottom();
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
scrollToBottom() {
|
|
214
|
+
const messages = this.shadowRoot.getElementById('messages');
|
|
215
|
+
messages.scrollTop = messages.scrollHeight;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
customElements.define('agentica-chatbot', AgenticAIChatbot);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agenticaichat",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
4
4
|
"description": "AI-powered chatbot for business analytics with natural language database queries",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -19,6 +19,10 @@
|
|
|
19
19
|
"types": "./dist/core/index.d.ts",
|
|
20
20
|
"import": "./dist/core/index.js",
|
|
21
21
|
"require": "./dist/core/index.js"
|
|
22
|
+
},
|
|
23
|
+
"./web-component": {
|
|
24
|
+
"import": "./dist/web-component/index.js",
|
|
25
|
+
"require": "./dist/web-component/index.js"
|
|
22
26
|
}
|
|
23
27
|
},
|
|
24
28
|
"bin": {
|
|
@@ -28,10 +32,12 @@
|
|
|
28
32
|
"dist",
|
|
29
33
|
"bin",
|
|
30
34
|
"templates",
|
|
31
|
-
"scripts"
|
|
35
|
+
"scripts",
|
|
36
|
+
"src/web-component"
|
|
32
37
|
],
|
|
33
38
|
"scripts": {
|
|
34
|
-
"build": "tsc",
|
|
39
|
+
"build": "tsc && npm run build:web-component",
|
|
40
|
+
"build:web-component": "if not exist dist\\web-component mkdir dist\\web-component && copy src\\web-component\\* dist\\web-component\\",
|
|
35
41
|
"dev": "tsc --watch",
|
|
36
42
|
"clean": "node -e \"require('fs').rmSync('dist', {recursive: true, force: true})\"",
|
|
37
43
|
"prebuild": "npm run clean",
|
|
@@ -67,11 +73,14 @@
|
|
|
67
73
|
"@google/generative-ai": "^0.24.1",
|
|
68
74
|
"axios": "^1.13.2",
|
|
69
75
|
"better-sqlite3": "^12.5.0",
|
|
76
|
+
"chalk": "^4.1.2",
|
|
70
77
|
"dotenv": "^17.2.3",
|
|
78
|
+
"inquirer": "^8.2.6",
|
|
71
79
|
"lucide-react": "^0.559.0",
|
|
72
80
|
"mongodb": "^7.0.0",
|
|
73
81
|
"mysql2": "^3.15.3",
|
|
74
82
|
"openai": "^6.10.0",
|
|
83
|
+
"ora": "^5.4.1",
|
|
75
84
|
"pg": "^8.16.3",
|
|
76
85
|
"react": ">=18.0.0",
|
|
77
86
|
"react-dom": ">=18.0.0"
|
|
@@ -83,10 +92,7 @@
|
|
|
83
92
|
"@types/pg": "^8.15.6",
|
|
84
93
|
"@types/react": "^18.2.0",
|
|
85
94
|
"@types/react-dom": "^18.2.0",
|
|
86
|
-
"chalk": "^4.1.2",
|
|
87
95
|
"commander": "^11.1.0",
|
|
88
|
-
"inquirer": "^8.2.6",
|
|
89
|
-
"ora": "^5.4.1",
|
|
90
96
|
"ts-node": "^10.9.2",
|
|
91
97
|
"typescript": "^5.3.0"
|
|
92
98
|
},
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
class AgenticAIChatbot extends HTMLElement {
|
|
2
|
+
constructor() {
|
|
3
|
+
super();
|
|
4
|
+
this.attachShadow({ mode: 'open' });
|
|
5
|
+
this.apiUrl = this.getAttribute('api') || '/api/chatbot/query';
|
|
6
|
+
this.messages = [];
|
|
7
|
+
this.isOpen = false;
|
|
8
|
+
this.isTyping = false;
|
|
9
|
+
this.render();
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
connectedCallback() {
|
|
13
|
+
this.setupEventListeners();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
render() {
|
|
17
|
+
this.shadowRoot.innerHTML = `
|
|
18
|
+
<style>
|
|
19
|
+
:host {
|
|
20
|
+
position: fixed;
|
|
21
|
+
bottom: 20px;
|
|
22
|
+
right: 20px;
|
|
23
|
+
z-index: 9999;
|
|
24
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.chat-container {
|
|
28
|
+
display: ${this.isOpen ? 'block' : 'none'};
|
|
29
|
+
width: 350px;
|
|
30
|
+
height: 500px;
|
|
31
|
+
background: white;
|
|
32
|
+
border-radius: 12px;
|
|
33
|
+
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
|
|
34
|
+
overflow: hidden;
|
|
35
|
+
position: relative;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.chat-header {
|
|
39
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
40
|
+
color: white;
|
|
41
|
+
padding: 16px;
|
|
42
|
+
font-weight: 600;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.chat-messages {
|
|
46
|
+
height: 380px;
|
|
47
|
+
overflow-y: auto;
|
|
48
|
+
padding: 16px;
|
|
49
|
+
background: #f8f9fa;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.message {
|
|
53
|
+
margin-bottom: 12px;
|
|
54
|
+
padding: 8px 12px;
|
|
55
|
+
border-radius: 8px;
|
|
56
|
+
max-width: 80%;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.message.user {
|
|
60
|
+
background: #007bff;
|
|
61
|
+
color: white;
|
|
62
|
+
margin-left: auto;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.message.bot {
|
|
66
|
+
background: white;
|
|
67
|
+
color: #333;
|
|
68
|
+
border: 1px solid #e9ecef;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.typing {
|
|
72
|
+
display: ${this.isTyping ? 'block' : 'none'};
|
|
73
|
+
font-style: italic;
|
|
74
|
+
color: #666;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.chat-input {
|
|
78
|
+
padding: 16px;
|
|
79
|
+
background: white;
|
|
80
|
+
border-top: 1px solid #e9ecef;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.input-group {
|
|
84
|
+
display: flex;
|
|
85
|
+
gap: 8px;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
input {
|
|
89
|
+
flex: 1;
|
|
90
|
+
padding: 8px 12px;
|
|
91
|
+
border: 1px solid #ddd;
|
|
92
|
+
border-radius: 6px;
|
|
93
|
+
outline: none;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
button {
|
|
97
|
+
padding: 8px 16px;
|
|
98
|
+
background: #007bff;
|
|
99
|
+
color: white;
|
|
100
|
+
border: none;
|
|
101
|
+
border-radius: 6px;
|
|
102
|
+
cursor: pointer;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
button:hover {
|
|
106
|
+
background: #0056b3;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.chat-toggle {
|
|
110
|
+
width: 60px;
|
|
111
|
+
height: 60px;
|
|
112
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
113
|
+
border-radius: 50%;
|
|
114
|
+
border: none;
|
|
115
|
+
color: white;
|
|
116
|
+
font-size: 24px;
|
|
117
|
+
cursor: pointer;
|
|
118
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
|
|
119
|
+
display: flex;
|
|
120
|
+
align-items: center;
|
|
121
|
+
justify-content: center;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.chat-toggle:hover {
|
|
125
|
+
transform: scale(1.05);
|
|
126
|
+
}
|
|
127
|
+
</style>
|
|
128
|
+
|
|
129
|
+
<div class="chat-container">
|
|
130
|
+
<div class="chat-header">
|
|
131
|
+
🤖 AgenticAI Chatbot
|
|
132
|
+
</div>
|
|
133
|
+
<div class="chat-messages" id="messages">
|
|
134
|
+
${this.messages.map(msg => `
|
|
135
|
+
<div class="message ${msg.sender}">
|
|
136
|
+
${msg.text}
|
|
137
|
+
</div>
|
|
138
|
+
`).join('')}
|
|
139
|
+
<div class="message bot typing" id="typing">Typing...</div>
|
|
140
|
+
</div>
|
|
141
|
+
<div class="chat-input">
|
|
142
|
+
<div class="input-group">
|
|
143
|
+
<input type="text" id="messageInput" placeholder="Ask me anything..." />
|
|
144
|
+
<button id="sendButton">Send</button>
|
|
145
|
+
</div>
|
|
146
|
+
</div>
|
|
147
|
+
</div>
|
|
148
|
+
|
|
149
|
+
<button class="chat-toggle" id="toggleButton">
|
|
150
|
+
${this.isOpen ? '✕' : '💬'}
|
|
151
|
+
</button>
|
|
152
|
+
`;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
setupEventListeners() {
|
|
156
|
+
const toggleButton = this.shadowRoot.getElementById('toggleButton');
|
|
157
|
+
const sendButton = this.shadowRoot.getElementById('sendButton');
|
|
158
|
+
const messageInput = this.shadowRoot.getElementById('messageInput');
|
|
159
|
+
|
|
160
|
+
toggleButton.addEventListener('click', () => {
|
|
161
|
+
this.isOpen = !this.isOpen;
|
|
162
|
+
this.render();
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
sendButton.addEventListener('click', () => this.sendMessage());
|
|
166
|
+
messageInput.addEventListener('keypress', (e) => {
|
|
167
|
+
if (e.key === 'Enter') this.sendMessage();
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
async sendMessage() {
|
|
172
|
+
const messageInput = this.shadowRoot.getElementById('messageInput');
|
|
173
|
+
const query = messageInput.value.trim();
|
|
174
|
+
if (!query) return;
|
|
175
|
+
|
|
176
|
+
// Add user message
|
|
177
|
+
this.messages.push({ sender: 'user', text: query });
|
|
178
|
+
messageInput.value = '';
|
|
179
|
+
this.render();
|
|
180
|
+
|
|
181
|
+
// Show typing
|
|
182
|
+
this.isTyping = true;
|
|
183
|
+
this.render();
|
|
184
|
+
|
|
185
|
+
try {
|
|
186
|
+
const response = await fetch(this.apiUrl, {
|
|
187
|
+
method: 'POST',
|
|
188
|
+
headers: {
|
|
189
|
+
'Content-Type': 'application/json',
|
|
190
|
+
},
|
|
191
|
+
body: JSON.stringify({ query }),
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
const data = await response.json();
|
|
195
|
+
|
|
196
|
+
// Hide typing
|
|
197
|
+
this.isTyping = false;
|
|
198
|
+
|
|
199
|
+
if (data.error) {
|
|
200
|
+
this.messages.push({ sender: 'bot', text: `Error: ${data.error}` });
|
|
201
|
+
} else {
|
|
202
|
+
this.messages.push({ sender: 'bot', text: data.answer || data.reply || 'No response' });
|
|
203
|
+
}
|
|
204
|
+
} catch (error) {
|
|
205
|
+
this.isTyping = false;
|
|
206
|
+
this.messages.push({ sender: 'bot', text: 'Sorry, I encountered an error. Please try again.' });
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
this.render();
|
|
210
|
+
this.scrollToBottom();
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
scrollToBottom() {
|
|
214
|
+
const messages = this.shadowRoot.getElementById('messages');
|
|
215
|
+
messages.scrollTop = messages.scrollHeight;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
customElements.define('agentica-chatbot', AgenticAIChatbot);
|