@a.izzuddin/ai-chat 0.2.16 → 0.2.18

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.
@@ -601,6 +601,16 @@
601
601
  "default": "''",
602
602
  "attribute": "bot-avatar-url"
603
603
  },
604
+ {
605
+ "kind": "field",
606
+ "name": "userAvatarUrl",
607
+ "privacy": "public",
608
+ "type": {
609
+ "text": "string"
610
+ },
611
+ "default": "''",
612
+ "attribute": "user-avatar-url"
613
+ },
604
614
  {
605
615
  "kind": "field",
606
616
  "name": "widgetIconUrl",
@@ -1038,6 +1048,14 @@
1038
1048
  "default": "''",
1039
1049
  "fieldName": "botAvatarUrl"
1040
1050
  },
1051
+ {
1052
+ "name": "user-avatar-url",
1053
+ "type": {
1054
+ "text": "string"
1055
+ },
1056
+ "default": "''",
1057
+ "fieldName": "userAvatarUrl"
1058
+ },
1041
1059
  {
1042
1060
  "name": "widget-icon-url",
1043
1061
  "type": {
package/dist/index.d.mts CHANGED
@@ -66,6 +66,7 @@ declare class AIChat extends LitElement {
66
66
  mode: 'fullscreen' | 'widget';
67
67
  initialMessages: Message[];
68
68
  botAvatarUrl: string;
69
+ userAvatarUrl: string;
69
70
  widgetIconUrl: string;
70
71
  backgroundImageUrl: string;
71
72
  widgetWidth: string;
@@ -111,6 +112,10 @@ declare class AIChat extends LitElement {
111
112
  type: StringConstructor;
112
113
  attribute: string;
113
114
  };
115
+ userAvatarUrl: {
116
+ type: StringConstructor;
117
+ attribute: string;
118
+ };
114
119
  widgetIconUrl: {
115
120
  type: StringConstructor;
116
121
  attribute: string;
package/dist/index.d.ts CHANGED
@@ -66,6 +66,7 @@ declare class AIChat extends LitElement {
66
66
  mode: 'fullscreen' | 'widget';
67
67
  initialMessages: Message[];
68
68
  botAvatarUrl: string;
69
+ userAvatarUrl: string;
69
70
  widgetIconUrl: string;
70
71
  backgroundImageUrl: string;
71
72
  widgetWidth: string;
@@ -111,6 +112,10 @@ declare class AIChat extends LitElement {
111
112
  type: StringConstructor;
112
113
  attribute: string;
113
114
  };
115
+ userAvatarUrl: {
116
+ type: StringConstructor;
117
+ attribute: string;
118
+ };
114
119
  widgetIconUrl: {
115
120
  type: StringConstructor;
116
121
  attribute: string;
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.16";
19
+ var VERSION = "0.2.18";
20
20
  exports.AIChat = class AIChat extends lit.LitElement {
21
21
  constructor() {
22
22
  super();
@@ -27,6 +27,7 @@ exports.AIChat = class AIChat extends lit.LitElement {
27
27
  this.mode = "fullscreen";
28
28
  this.initialMessages = [];
29
29
  this.botAvatarUrl = "";
30
+ this.userAvatarUrl = "";
30
31
  this.widgetIconUrl = "";
31
32
  this.backgroundImageUrl = "";
32
33
  this.widgetWidth = "380px";
@@ -94,7 +95,6 @@ ${this.welcomeSubtitle}` : this.welcomeMessage;
94
95
  try {
95
96
  const lastSessionId = sessionStorage.getItem("ai-chat-last-session-id");
96
97
  if (lastSessionId && lastSessionId !== this.sessionId) {
97
- console.log(`\u{1F504} Session changed from "${lastSessionId}" to "${this.sessionId}", clearing old messages`);
98
98
  const oldStorageKey = `ai-chat-messages-${lastSessionId}`;
99
99
  sessionStorage.removeItem(oldStorageKey);
100
100
  sessionStorage.setItem("ai-chat-last-session-id", this.sessionId);
@@ -208,6 +208,7 @@ ${this.welcomeSubtitle}` : this.welcomeMessage;
208
208
  this.messages = savedMessages;
209
209
  } else {
210
210
  let suggestedQuestions = void 0;
211
+ let fetchFailed = false;
211
212
  if (this.initialQuestionsUrl) {
212
213
  try {
213
214
  let fetchUrl = this.initialQuestionsUrl;
@@ -215,11 +216,9 @@ ${this.welcomeSubtitle}` : this.welcomeMessage;
215
216
  const separator = fetchUrl.includes("?") ? "&" : "?";
216
217
  fetchUrl = `${fetchUrl}${separator}language=${this.language}`;
217
218
  }
218
- console.log("\u{1F4E4} Fetching initial questions from:", fetchUrl);
219
219
  const response = await fetch(fetchUrl);
220
220
  if (response.ok) {
221
221
  const data = await response.json();
222
- console.log("\u{1F4E5} Fetched initial questions:", data);
223
222
  let questionsArray = data.questions || data.suggested_questions || data;
224
223
  if (Array.isArray(questionsArray) && questionsArray.length > 0) {
225
224
  if (typeof questionsArray[0] === "object" && questionsArray[0].question_text) {
@@ -235,12 +234,17 @@ ${this.welcomeSubtitle}` : this.welcomeMessage;
235
234
  }));
236
235
  }
237
236
  }
238
- console.log("\u2705 Processed suggested questions:", suggestedQuestions);
237
+ } else {
238
+ fetchFailed = true;
239
239
  }
240
240
  } catch (error) {
241
241
  console.warn("Failed to fetch initial questions:", error);
242
+ fetchFailed = true;
242
243
  }
243
244
  }
245
+ if (fetchFailed) {
246
+ this.clearMessagesFromStorage();
247
+ }
244
248
  if (this.welcomeMessage) {
245
249
  const welcomeText = this.welcomeSubtitle ? `${this.welcomeMessage}
246
250
 
@@ -327,7 +331,6 @@ ${this.welcomeSubtitle}` : this.welcomeMessage;
327
331
  baseUrl = "http://43.217.183.120:8080";
328
332
  }
329
333
  const url = `${baseUrl}/api/questions/${question.id}?question_type=${question.question_type}`;
330
- console.log("\u{1F4E4} Calling suggested question API:", url);
331
334
  const response = await fetch(url, {
332
335
  method: "GET",
333
336
  headers: { "Content-Type": "application/json" }
@@ -337,7 +340,6 @@ ${this.welcomeSubtitle}` : this.welcomeMessage;
337
340
  throw new Error(`Backend error: ${response.status} ${errorText}`);
338
341
  }
339
342
  const data = await response.json();
340
- console.log("\u{1F50D} Suggested question API response:", data);
341
343
  let responseText = "No response from agent";
342
344
  let suggestedQuestions = void 0;
343
345
  if (data && typeof data === "object") {
@@ -415,40 +417,29 @@ ${this.welcomeSubtitle}` : this.welcomeMessage;
415
417
  throw new Error(`Backend error: ${response.status} ${errorText}`);
416
418
  }
417
419
  const data = await response.json();
418
- console.log("\u{1F50D} Raw API response:", data);
419
420
  let responseText = "No response from agent";
420
421
  let faqs = void 0;
421
422
  let suggestedQuestions = void 0;
422
423
  if (data && typeof data === "object" && data.response && typeof data.response === "string") {
423
- console.log("\u{1F4DD} data.response type:", typeof data.response);
424
- console.log("\u{1F4DD} data.response preview:", data.response.substring(0, 100));
425
424
  const trimmedResponse = data.response.trim();
426
425
  if (trimmedResponse.startsWith("{") || trimmedResponse.startsWith("[")) {
427
- console.log("\u{1F504} Detected stringified JSON, parsing...");
428
426
  try {
429
427
  const innerData = JSON.parse(data.response);
430
- console.log("\u2705 Parsed inner data with JSON.parse");
431
428
  if (innerData && innerData.response && typeof innerData.response === "string") {
432
429
  responseText = innerData.response;
433
430
  faqs = innerData.faq_used || innerData.faqs_used || void 0;
434
431
  suggestedQuestions = this.normalizeSuggestedQuestions(innerData.suggested_follow_ups || innerData.suggested_questions);
435
- console.log("\u2705 Extracted text length:", responseText.length);
436
- console.log("\u2705 Extracted FAQs count:", faqs?.length || 0);
437
- console.log("\u2705 Extracted suggested questions count:", suggestedQuestions?.length || 0);
438
432
  } else {
439
433
  responseText = data.response;
440
434
  faqs = data.faq_used || data.faqs_used || void 0;
441
435
  suggestedQuestions = this.normalizeSuggestedQuestions(data.suggested_follow_ups || data.suggested_questions);
442
436
  }
443
437
  } catch (parseError) {
444
- console.warn("\u26A0\uFE0F JSON.parse failed, using regex extraction...", parseError);
445
438
  const responsePattern = /"response"\s*:\s*"([^"]*(?:\\.[^"]*)*)"/s;
446
439
  const responseMatch = data.response.match(responsePattern);
447
440
  if (responseMatch) {
448
441
  responseText = responseMatch[1].replace(/\\n/g, "\n").replace(/\\t/g, " ").replace(/\\r/g, "\r").replace(/\\"/g, '"').replace(/\\\\/g, "\\");
449
- console.log("\u2705 Extracted response text, length:", responseText.length);
450
442
  } else {
451
- console.error("\u274C Could not extract response");
452
443
  responseText = "Error: Could not parse response";
453
444
  }
454
445
  const faqsPattern = /"(?:faq_used|faqs_used)"\s*:\s*(\[[^\]]*\])/s;
@@ -456,15 +447,12 @@ ${this.welcomeSubtitle}` : this.welcomeMessage;
456
447
  if (faqsMatch) {
457
448
  try {
458
449
  faqs = JSON.parse(faqsMatch[1]);
459
- console.log("\u2705 Extracted FAQs, count:", faqs?.length || 0);
460
450
  } catch {
461
- console.log("\u26A0\uFE0F Could not parse FAQs, trying multiline...");
462
451
  const faqsMultiPattern = /"(?:faq_used|faqs_used)"\s*:\s*(\[[\s\S]*?\n\s*\])/;
463
452
  const faqsMultiMatch = data.response.match(faqsMultiPattern);
464
453
  if (faqsMultiMatch) {
465
454
  try {
466
455
  faqs = JSON.parse(faqsMultiMatch[1]);
467
- console.log("\u2705 Extracted multi-line FAQs, count:", faqs?.length || 0);
468
456
  } catch {
469
457
  faqs = void 0;
470
458
  }
@@ -477,16 +465,13 @@ ${this.welcomeSubtitle}` : this.welcomeMessage;
477
465
  try {
478
466
  const parsedQuestions = JSON.parse(suggestedMatch[1]);
479
467
  suggestedQuestions = this.normalizeSuggestedQuestions(parsedQuestions);
480
- console.log("\u2705 Extracted suggested questions, count:", suggestedQuestions?.length || 0);
481
468
  } catch {
482
- console.log("\u26A0\uFE0F Could not parse suggested questions, trying multiline...");
483
469
  const suggestedMultiPattern = /"(?:suggested_follow_ups|suggested_questions)"\s*:\s*(\[[\s\S]*?\n\s*\])/;
484
470
  const suggestedMultiMatch = data.response.match(suggestedMultiPattern);
485
471
  if (suggestedMultiMatch) {
486
472
  try {
487
473
  const parsedQuestions = JSON.parse(suggestedMultiMatch[1]);
488
474
  suggestedQuestions = this.normalizeSuggestedQuestions(parsedQuestions);
489
- console.log("\u2705 Extracted multi-line suggested questions, count:", suggestedQuestions?.length || 0);
490
475
  } catch {
491
476
  suggestedQuestions = void 0;
492
477
  }
@@ -495,24 +480,17 @@ ${this.welcomeSubtitle}` : this.welcomeMessage;
495
480
  }
496
481
  }
497
482
  } else {
498
- console.log("\u{1F4C4} Direct text response (not JSON)");
499
483
  responseText = data.response;
500
484
  faqs = data.faq_used || data.faqs_used || void 0;
501
485
  suggestedQuestions = this.normalizeSuggestedQuestions(data.suggested_follow_ups || data.suggested_questions);
502
486
  }
503
487
  } else if (typeof data === "string") {
504
- console.log("\u{1F4C4} Response is a plain string");
505
488
  responseText = data;
506
489
  } else if (data && typeof data === "object") {
507
- console.warn("\u26A0\uFE0F Unexpected format, using fallback");
508
490
  responseText = data.message || data.answer || "Error: Unexpected response format";
509
491
  faqs = data.faq_used || data.faqs_used || void 0;
510
492
  suggestedQuestions = this.normalizeSuggestedQuestions(data.suggested_follow_ups || data.suggested_questions);
511
493
  }
512
- console.log("\u{1F3AF} Final responseText length:", responseText.length);
513
- console.log("\u{1F3AF} Final responseText preview:", responseText.substring(0, 100));
514
- console.log("\u{1F3AF} Final FAQs:", faqs);
515
- console.log("\u{1F3AF} Final suggested questions:", suggestedQuestions);
516
494
  const assistantMessage = {
517
495
  id: (Date.now() + 1).toString(),
518
496
  role: "assistant",
@@ -570,7 +548,9 @@ ${this.welcomeSubtitle}` : this.welcomeMessage;
570
548
  })}
571
549
  >
572
550
  <div class="avatar">
573
- ${msg.role === "user" ? "U" : this.botAvatarUrl ? lit.html`<img src="${this.botAvatarUrl}" alt="AI" class="avatar-image" />` : "AI"}
551
+ ${msg.role === "user" ? this.userAvatarUrl ? lit.html`<img src="${this.userAvatarUrl}" alt="User" class="avatar-image" />` : lit.html`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" style="width: 20px; height: 20px;">
552
+ <path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/>
553
+ </svg>` : this.botAvatarUrl ? lit.html`<img src="${this.botAvatarUrl}" alt="AI" class="avatar-image" />` : "AI"}
574
554
  </div>
575
555
  <div class="message-content">
576
556
  <div class="message-text">${unsafeHtml_js.unsafeHTML(this.formatMessageContent(msg.content))}</div>
@@ -588,7 +568,7 @@ ${this.welcomeSubtitle}` : this.welcomeMessage;
588
568
  ` : ""}
589
569
  ${msg.role === "assistant" && msg.suggestedQuestions && msg.suggestedQuestions.length > 0 ? lit.html`
590
570
  <div class="faq-section">
591
- <p class="faq-title">Suggested Questions:</p>
571
+ <p class="faq-title">Cadangan Soalan:</p>
592
572
  <ul class="faq-list">
593
573
  ${msg.suggestedQuestions.map((question) => lit.html`
594
574
  <li class="faq-item" @click=${() => this.handleFAQClick(question)}>
@@ -1452,6 +1432,7 @@ exports.AIChat.properties = {
1452
1432
  mode: { type: String, reflect: true },
1453
1433
  initialMessages: { type: Array },
1454
1434
  botAvatarUrl: { type: String, attribute: "bot-avatar-url" },
1435
+ userAvatarUrl: { type: String, attribute: "user-avatar-url" },
1455
1436
  widgetIconUrl: { type: String, attribute: "widget-icon-url" },
1456
1437
  backgroundImageUrl: { type: String, attribute: "background-image-url" },
1457
1438
  widgetWidth: { type: String, attribute: "widget-width" },