@a.izzuddin/ai-chat 0.2.11 → 0.2.14

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.
@@ -74,11 +74,6 @@
74
74
  "kind": "variable",
75
75
  "name": "suggestedQuestions",
76
76
  "default": "void 0"
77
- },
78
- {
79
- "kind": "variable",
80
- "name": "faqs",
81
- "default": "void 0"
82
77
  }
83
78
  ],
84
79
  "exports": []
@@ -716,6 +711,26 @@
716
711
  "default": "''",
717
712
  "attribute": "initial-questions-url"
718
713
  },
714
+ {
715
+ "kind": "field",
716
+ "name": "language",
717
+ "privacy": "public",
718
+ "type": {
719
+ "text": "string"
720
+ },
721
+ "default": "'en'",
722
+ "attribute": "language"
723
+ },
724
+ {
725
+ "kind": "field",
726
+ "name": "showRelatedFaqs",
727
+ "privacy": "public",
728
+ "type": {
729
+ "text": "boolean"
730
+ },
731
+ "default": "false",
732
+ "attribute": "show-related-faqs"
733
+ },
719
734
  {
720
735
  "kind": "field",
721
736
  "name": "messages",
@@ -856,6 +871,25 @@
856
871
  "name": "scrollToBottom",
857
872
  "privacy": "private"
858
873
  },
874
+ {
875
+ "kind": "method",
876
+ "name": "normalizeSuggestedQuestions",
877
+ "privacy": "private",
878
+ "return": {
879
+ "type": {
880
+ "text": "SuggestedQuestion[] | undefined"
881
+ }
882
+ },
883
+ "parameters": [
884
+ {
885
+ "name": "questions",
886
+ "type": {
887
+ "text": "any"
888
+ }
889
+ }
890
+ ],
891
+ "description": "Normalize suggested questions - converts string arrays to SuggestedQuestion objects"
892
+ },
859
893
  {
860
894
  "kind": "method",
861
895
  "name": "handleInput",
@@ -877,7 +911,20 @@
877
911
  {
878
912
  "name": "question",
879
913
  "type": {
880
- "text": "string"
914
+ "text": "SuggestedQuestion"
915
+ }
916
+ }
917
+ ]
918
+ },
919
+ {
920
+ "kind": "method",
921
+ "name": "handleSuggestedQuestionClick",
922
+ "privacy": "private",
923
+ "parameters": [
924
+ {
925
+ "name": "question",
926
+ "type": {
927
+ "text": "SuggestedQuestion"
881
928
  }
882
929
  }
883
930
  ]
@@ -1068,6 +1115,22 @@
1068
1115
  },
1069
1116
  "default": "''",
1070
1117
  "fieldName": "initialQuestionsUrl"
1118
+ },
1119
+ {
1120
+ "name": "language",
1121
+ "type": {
1122
+ "text": "string"
1123
+ },
1124
+ "default": "'en'",
1125
+ "fieldName": "language"
1126
+ },
1127
+ {
1128
+ "name": "show-related-faqs",
1129
+ "type": {
1130
+ "text": "boolean"
1131
+ },
1132
+ "default": "false",
1133
+ "fieldName": "showRelatedFaqs"
1071
1134
  }
1072
1135
  ],
1073
1136
  "superclass": {
package/dist/index.d.mts CHANGED
@@ -6,12 +6,18 @@ interface FAQ {
6
6
  No: string;
7
7
  Question: string;
8
8
  }
9
+ interface SuggestedQuestion {
10
+ id?: number;
11
+ question_type?: string;
12
+ question_text: string;
13
+ category?: string;
14
+ }
9
15
  interface Message {
10
16
  id: string;
11
17
  role: 'user' | 'assistant';
12
18
  content: string;
13
19
  faqs?: FAQ[];
14
- suggestedQuestions?: string[];
20
+ suggestedQuestions?: SuggestedQuestion[];
15
21
  }
16
22
  /**
17
23
  * AI Chat Web Component
@@ -71,6 +77,8 @@ declare class AIChat extends LitElement {
71
77
  welcomeMessage: string;
72
78
  welcomeSubtitle: string;
73
79
  initialQuestionsUrl: string;
80
+ language: string;
81
+ showRelatedFaqs: boolean;
74
82
  private messages;
75
83
  private input;
76
84
  private isLoading;
@@ -146,6 +154,14 @@ declare class AIChat extends LitElement {
146
154
  type: StringConstructor;
147
155
  attribute: string;
148
156
  };
157
+ language: {
158
+ type: StringConstructor;
159
+ attribute: string;
160
+ };
161
+ showRelatedFaqs: {
162
+ type: BooleanConstructor;
163
+ attribute: string;
164
+ };
149
165
  };
150
166
  constructor();
151
167
  private toggleWidget;
@@ -163,8 +179,13 @@ declare class AIChat extends LitElement {
163
179
  connectedCallback(): Promise<void>;
164
180
  updated(changedProperties: PropertyValues): void;
165
181
  private scrollToBottom;
182
+ /**
183
+ * Normalize suggested questions - converts string arrays to SuggestedQuestion objects
184
+ */
185
+ private normalizeSuggestedQuestions;
166
186
  private handleInput;
167
187
  private handleFAQClick;
188
+ private handleSuggestedQuestionClick;
168
189
  private handleSubmit;
169
190
  private renderChatUI;
170
191
  render(): lit_html.TemplateResult<1>;
package/dist/index.d.ts CHANGED
@@ -6,12 +6,18 @@ interface FAQ {
6
6
  No: string;
7
7
  Question: string;
8
8
  }
9
+ interface SuggestedQuestion {
10
+ id?: number;
11
+ question_type?: string;
12
+ question_text: string;
13
+ category?: string;
14
+ }
9
15
  interface Message {
10
16
  id: string;
11
17
  role: 'user' | 'assistant';
12
18
  content: string;
13
19
  faqs?: FAQ[];
14
- suggestedQuestions?: string[];
20
+ suggestedQuestions?: SuggestedQuestion[];
15
21
  }
16
22
  /**
17
23
  * AI Chat Web Component
@@ -71,6 +77,8 @@ declare class AIChat extends LitElement {
71
77
  welcomeMessage: string;
72
78
  welcomeSubtitle: string;
73
79
  initialQuestionsUrl: string;
80
+ language: string;
81
+ showRelatedFaqs: boolean;
74
82
  private messages;
75
83
  private input;
76
84
  private isLoading;
@@ -146,6 +154,14 @@ declare class AIChat extends LitElement {
146
154
  type: StringConstructor;
147
155
  attribute: string;
148
156
  };
157
+ language: {
158
+ type: StringConstructor;
159
+ attribute: string;
160
+ };
161
+ showRelatedFaqs: {
162
+ type: BooleanConstructor;
163
+ attribute: string;
164
+ };
149
165
  };
150
166
  constructor();
151
167
  private toggleWidget;
@@ -163,8 +179,13 @@ declare class AIChat extends LitElement {
163
179
  connectedCallback(): Promise<void>;
164
180
  updated(changedProperties: PropertyValues): void;
165
181
  private scrollToBottom;
182
+ /**
183
+ * Normalize suggested questions - converts string arrays to SuggestedQuestion objects
184
+ */
185
+ private normalizeSuggestedQuestions;
166
186
  private handleInput;
167
187
  private handleFAQClick;
188
+ private handleSuggestedQuestionClick;
168
189
  private handleSubmit;
169
190
  private renderChatUI;
170
191
  render(): lit_html.TemplateResult<1>;
package/dist/index.js CHANGED
@@ -16,7 +16,7 @@ var __decorateClass = (decorators, target, key, kind) => {
16
16
  if (kind && result) __defProp(target, key, result);
17
17
  return result;
18
18
  };
19
- var VERSION = "0.2.11";
19
+ var VERSION = "0.2.14";
20
20
  exports.AIChat = class AIChat extends lit.LitElement {
21
21
  constructor() {
22
22
  super();
@@ -38,6 +38,8 @@ exports.AIChat = class AIChat extends lit.LitElement {
38
38
  this.welcomeMessage = "How can I help you today?";
39
39
  this.welcomeSubtitle = "";
40
40
  this.initialQuestionsUrl = "";
41
+ this.language = "en";
42
+ this.showRelatedFaqs = false;
41
43
  this.messages = [];
42
44
  this.input = "";
43
45
  this.isLoading = false;
@@ -207,16 +209,29 @@ ${this.welcomeSubtitle}` : this.welcomeMessage;
207
209
  let suggestedQuestions = void 0;
208
210
  if (this.initialQuestionsUrl) {
209
211
  try {
210
- const response = await fetch(this.initialQuestionsUrl);
212
+ let fetchUrl = this.initialQuestionsUrl;
213
+ if (this.language) {
214
+ const separator = fetchUrl.includes("?") ? "&" : "?";
215
+ fetchUrl = `${fetchUrl}${separator}language=${this.language}`;
216
+ }
217
+ console.log("\u{1F4E4} Fetching initial questions from:", fetchUrl);
218
+ const response = await fetch(fetchUrl);
211
219
  if (response.ok) {
212
220
  const data = await response.json();
213
221
  console.log("\u{1F4E5} Fetched initial questions:", data);
214
222
  let questionsArray = data.questions || data.suggested_questions || data;
215
223
  if (Array.isArray(questionsArray) && questionsArray.length > 0) {
216
224
  if (typeof questionsArray[0] === "object" && questionsArray[0].question_text) {
217
- suggestedQuestions = questionsArray.map((q) => q.question_text);
225
+ suggestedQuestions = questionsArray.map((q) => ({
226
+ id: q.id,
227
+ question_type: q.question_type,
228
+ question_text: q.question_text,
229
+ category: q.category
230
+ }));
218
231
  } else if (typeof questionsArray[0] === "string") {
219
- suggestedQuestions = questionsArray;
232
+ suggestedQuestions = questionsArray.map((q) => ({
233
+ question_text: q
234
+ }));
220
235
  }
221
236
  }
222
237
  console.log("\u2705 Processed suggested questions:", suggestedQuestions);
@@ -254,14 +269,121 @@ ${this.welcomeSubtitle}` : this.welcomeMessage;
254
269
  }
255
270
  }, 100);
256
271
  }
272
+ /**
273
+ * Normalize suggested questions - converts string arrays to SuggestedQuestion objects
274
+ */
275
+ normalizeSuggestedQuestions(questions) {
276
+ if (!questions || !Array.isArray(questions) || questions.length === 0) {
277
+ return void 0;
278
+ }
279
+ if (typeof questions[0] === "object" && questions[0].question_text) {
280
+ return questions;
281
+ }
282
+ if (typeof questions[0] === "string") {
283
+ return questions.map((q) => ({
284
+ question_text: q
285
+ }));
286
+ }
287
+ return void 0;
288
+ }
257
289
  handleInput(e) {
258
290
  this.input = e.target.value;
259
291
  }
260
- handleFAQClick(question) {
292
+ async handleFAQClick(question) {
261
293
  if (this.isLoading) return;
262
- this.input = question;
263
- const submitEvent = new Event("submit", { cancelable: true });
264
- this.handleSubmit(submitEvent);
294
+ if (question.id && question.question_type) {
295
+ await this.handleSuggestedQuestionClick(question);
296
+ } else {
297
+ this.input = question.question_text;
298
+ const submitEvent = new Event("submit", { cancelable: true });
299
+ this.handleSubmit(submitEvent);
300
+ }
301
+ }
302
+ async handleSuggestedQuestionClick(question) {
303
+ if (!question.id || !question.question_type) return;
304
+ const userMessage = {
305
+ id: Date.now().toString(),
306
+ role: "user",
307
+ content: question.question_text
308
+ };
309
+ this.messages = [...this.messages, userMessage];
310
+ this.isLoading = true;
311
+ this.dispatchEvent(new CustomEvent("message-sent", {
312
+ detail: userMessage,
313
+ bubbles: true,
314
+ composed: true
315
+ }));
316
+ try {
317
+ let baseUrl = "";
318
+ if (this.initialQuestionsUrl) {
319
+ try {
320
+ const urlObj = new URL(this.initialQuestionsUrl);
321
+ baseUrl = `${urlObj.protocol}//${urlObj.host}`;
322
+ } catch {
323
+ baseUrl = "http://43.217.183.120:8080";
324
+ }
325
+ } else {
326
+ baseUrl = "http://43.217.183.120:8080";
327
+ }
328
+ const url = `${baseUrl}/api/questions/${question.id}?question_type=${question.question_type}`;
329
+ console.log("\u{1F4E4} Calling suggested question API:", url);
330
+ const response = await fetch(url, {
331
+ method: "GET",
332
+ headers: { "Content-Type": "application/json" }
333
+ });
334
+ if (!response.ok) {
335
+ const errorText = await response.text();
336
+ throw new Error(`Backend error: ${response.status} ${errorText}`);
337
+ }
338
+ const data = await response.json();
339
+ console.log("\u{1F50D} Suggested question API response:", data);
340
+ let responseText = "No response from agent";
341
+ let suggestedQuestions = void 0;
342
+ if (data && typeof data === "object") {
343
+ if (data.question && data.question.answer_text) {
344
+ responseText = data.question.answer_text;
345
+ }
346
+ if (data.related_questions && Array.isArray(data.related_questions) && data.related_questions.length > 0) {
347
+ if (typeof data.related_questions[0] === "object" && data.related_questions[0].question_text) {
348
+ suggestedQuestions = data.related_questions.map((q) => ({
349
+ id: q.id,
350
+ question_type: q.question_type,
351
+ question_text: q.question_text,
352
+ category: q.category
353
+ }));
354
+ }
355
+ }
356
+ }
357
+ const assistantMessage = {
358
+ id: (Date.now() + 1).toString(),
359
+ role: "assistant",
360
+ content: responseText,
361
+ suggestedQuestions
362
+ };
363
+ this.messages = [...this.messages, assistantMessage];
364
+ this.dispatchEvent(new CustomEvent("response-received", {
365
+ detail: assistantMessage,
366
+ bubbles: true,
367
+ composed: true
368
+ }));
369
+ } catch (err) {
370
+ console.error("Suggested question API failed:", err);
371
+ const errorMessage = {
372
+ id: (Date.now() + 1).toString(),
373
+ role: "assistant",
374
+ content: `Error: ${err instanceof Error ? err.message : "Unknown error"}
375
+
376
+ Please check your API endpoint configuration.`
377
+ };
378
+ this.messages = [...this.messages, errorMessage];
379
+ this.dispatchEvent(new CustomEvent("error", {
380
+ detail: err,
381
+ bubbles: true,
382
+ composed: true
383
+ }));
384
+ } finally {
385
+ this.isLoading = false;
386
+ }
265
387
  }
266
388
  async handleSubmit(e) {
267
389
  e.preventDefault();
@@ -310,14 +432,14 @@ ${this.welcomeSubtitle}` : this.welcomeMessage;
310
432
  if (innerData && innerData.response && typeof innerData.response === "string") {
311
433
  responseText = innerData.response;
312
434
  faqs = innerData.faq_used || innerData.faqs_used || void 0;
313
- suggestedQuestions = innerData.suggested_follow_ups || innerData.suggested_questions || void 0;
435
+ suggestedQuestions = this.normalizeSuggestedQuestions(innerData.suggested_follow_ups || innerData.suggested_questions);
314
436
  console.log("\u2705 Extracted text length:", responseText.length);
315
437
  console.log("\u2705 Extracted FAQs count:", faqs?.length || 0);
316
438
  console.log("\u2705 Extracted suggested questions count:", suggestedQuestions?.length || 0);
317
439
  } else {
318
440
  responseText = data.response;
319
441
  faqs = data.faq_used || data.faqs_used || void 0;
320
- suggestedQuestions = data.suggested_follow_ups || data.suggested_questions || void 0;
442
+ suggestedQuestions = this.normalizeSuggestedQuestions(data.suggested_follow_ups || data.suggested_questions);
321
443
  }
322
444
  } catch (parseError) {
323
445
  console.warn("\u26A0\uFE0F JSON.parse failed, using regex extraction...", parseError);
@@ -354,7 +476,8 @@ ${this.welcomeSubtitle}` : this.welcomeMessage;
354
476
  const suggestedMatch = data.response.match(suggestedPattern);
355
477
  if (suggestedMatch) {
356
478
  try {
357
- suggestedQuestions = JSON.parse(suggestedMatch[1]);
479
+ const parsedQuestions = JSON.parse(suggestedMatch[1]);
480
+ suggestedQuestions = this.normalizeSuggestedQuestions(parsedQuestions);
358
481
  console.log("\u2705 Extracted suggested questions, count:", suggestedQuestions?.length || 0);
359
482
  } catch {
360
483
  console.log("\u26A0\uFE0F Could not parse suggested questions, trying multiline...");
@@ -362,7 +485,8 @@ ${this.welcomeSubtitle}` : this.welcomeMessage;
362
485
  const suggestedMultiMatch = data.response.match(suggestedMultiPattern);
363
486
  if (suggestedMultiMatch) {
364
487
  try {
365
- suggestedQuestions = JSON.parse(suggestedMultiMatch[1]);
488
+ const parsedQuestions = JSON.parse(suggestedMultiMatch[1]);
489
+ suggestedQuestions = this.normalizeSuggestedQuestions(parsedQuestions);
366
490
  console.log("\u2705 Extracted multi-line suggested questions, count:", suggestedQuestions?.length || 0);
367
491
  } catch {
368
492
  suggestedQuestions = void 0;
@@ -375,7 +499,7 @@ ${this.welcomeSubtitle}` : this.welcomeMessage;
375
499
  console.log("\u{1F4C4} Direct text response (not JSON)");
376
500
  responseText = data.response;
377
501
  faqs = data.faq_used || data.faqs_used || void 0;
378
- suggestedQuestions = data.suggested_follow_ups || data.suggested_questions || void 0;
502
+ suggestedQuestions = this.normalizeSuggestedQuestions(data.suggested_follow_ups || data.suggested_questions);
379
503
  }
380
504
  } else if (typeof data === "string") {
381
505
  console.log("\u{1F4C4} Response is a plain string");
@@ -384,7 +508,7 @@ ${this.welcomeSubtitle}` : this.welcomeMessage;
384
508
  console.warn("\u26A0\uFE0F Unexpected format, using fallback");
385
509
  responseText = data.message || data.answer || "Error: Unexpected response format";
386
510
  faqs = data.faq_used || data.faqs_used || void 0;
387
- suggestedQuestions = data.suggested_follow_ups || data.suggested_questions || void 0;
511
+ suggestedQuestions = this.normalizeSuggestedQuestions(data.suggested_follow_ups || data.suggested_questions);
388
512
  }
389
513
  console.log("\u{1F3AF} Final responseText length:", responseText.length);
390
514
  console.log("\u{1F3AF} Final responseText preview:", responseText.substring(0, 100));
@@ -453,7 +577,7 @@ Please check your API endpoint configuration.`
453
577
  </div>
454
578
  <div class="message-content">
455
579
  <div class="message-text">${unsafeHtml_js.unsafeHTML(this.formatMessageContent(msg.content))}</div>
456
- ${msg.role === "assistant" && msg.faqs && msg.faqs.length > 0 ? lit.html`
580
+ ${msg.role === "assistant" && this.showRelatedFaqs && msg.faqs && msg.faqs.length > 0 ? lit.html`
457
581
  <div class="faq-section">
458
582
  <p class="faq-title">Related FAQs:</p>
459
583
  <ul class="faq-list">
@@ -471,7 +595,7 @@ Please check your API endpoint configuration.`
471
595
  <ul class="faq-list">
472
596
  ${msg.suggestedQuestions.map((question) => lit.html`
473
597
  <li class="faq-item" @click=${() => this.handleFAQClick(question)}>
474
- ${question}
598
+ ${question.question_text}
475
599
  </li>
476
600
  `)}
477
601
  </ul>
@@ -637,9 +761,12 @@ exports.AIChat.styles = lit.css`
637
761
  }
638
762
 
639
763
  .widget-button-icon {
640
- width: auto;
641
- height: auto;
642
- object-fit: cover;
764
+ width: 100%;
765
+ height: 100%;
766
+ max-width: 60px;
767
+ max-height: 60px;
768
+ object-fit: contain;
769
+ border-radius: 50%;
643
770
  }
644
771
 
645
772
  .widget-window {
@@ -1333,7 +1460,9 @@ exports.AIChat.properties = {
1333
1460
  botMessageBg: { type: String, attribute: "bot-message-bg" },
1334
1461
  welcomeMessage: { type: String, attribute: "welcome-message" },
1335
1462
  welcomeSubtitle: { type: String, attribute: "welcome-subtitle" },
1336
- initialQuestionsUrl: { type: String, attribute: "initial-questions-url" }
1463
+ initialQuestionsUrl: { type: String, attribute: "initial-questions-url" },
1464
+ language: { type: String, attribute: "language" },
1465
+ showRelatedFaqs: { type: Boolean, attribute: "show-related-faqs" }
1337
1466
  };
1338
1467
  __decorateClass([
1339
1468
  decorators_js.state()