@a.izzuddin/ai-chat 0.2.22-beta.2 → 0.2.22

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.
@@ -75,10 +75,6 @@
75
75
  "name": "pos",
76
76
  "default": "start"
77
77
  },
78
- {
79
- "kind": "variable",
80
- "name": "type"
81
- },
82
78
  {
83
79
  "kind": "variable",
84
80
  "name": "suggestedQuestions",
@@ -877,68 +873,6 @@
877
873
  }
878
874
  }
879
875
  },
880
- {
881
- "kind": "method",
882
- "name": "getPendingRequestKey",
883
- "privacy": "private",
884
- "return": {
885
- "type": {
886
- "text": "string"
887
- }
888
- }
889
- },
890
- {
891
- "kind": "method",
892
- "name": "savePendingRequest",
893
- "privacy": "private",
894
- "return": {
895
- "type": {
896
- "text": "void"
897
- }
898
- },
899
- "parameters": [
900
- {
901
- "name": "question",
902
- "type": {
903
- "text": "string"
904
- }
905
- },
906
- {
907
- "name": "type",
908
- "default": "'ask'",
909
- "type": {
910
- "text": "'ask' | 'suggested'"
911
- }
912
- },
913
- {
914
- "name": "questionData",
915
- "optional": true,
916
- "type": {
917
- "text": "any"
918
- }
919
- }
920
- ]
921
- },
922
- {
923
- "kind": "method",
924
- "name": "loadPendingRequest",
925
- "privacy": "private",
926
- "return": {
927
- "type": {
928
- "text": "{ question: string; type: 'ask' | 'suggested'; questionData?: any; timestamp: number } | null"
929
- }
930
- }
931
- },
932
- {
933
- "kind": "method",
934
- "name": "clearPendingRequest",
935
- "privacy": "private",
936
- "return": {
937
- "type": {
938
- "text": "void"
939
- }
940
- }
941
- },
942
876
  {
943
877
  "kind": "method",
944
878
  "name": "saveMessagesToStorage",
@@ -1054,30 +988,9 @@
1054
988
  "type": {
1055
989
  "text": "SuggestedQuestion"
1056
990
  }
1057
- },
1058
- {
1059
- "name": "event",
1060
- "optional": true,
1061
- "type": {
1062
- "text": "Event"
1063
- }
1064
991
  }
1065
992
  ]
1066
993
  },
1067
- {
1068
- "kind": "method",
1069
- "name": "retryPendingRequest",
1070
- "privacy": "private",
1071
- "parameters": [
1072
- {
1073
- "name": "pendingRequest",
1074
- "type": {
1075
- "text": "{ question: string; type: 'ask' | 'suggested'; questionData?: any; timestamp: number }"
1076
- }
1077
- }
1078
- ],
1079
- "description": "Retry a pending request without adding duplicate user messages\r\nThe user message is already in the chat history from before the interruption"
1080
- },
1081
994
  {
1082
995
  "kind": "method",
1083
996
  "name": "handleSuggestedQuestionClick",
@@ -1112,25 +1025,25 @@
1112
1025
  ],
1113
1026
  "events": [
1114
1027
  {
1115
- "name": "response-received",
1028
+ "name": "message-sent",
1116
1029
  "type": {
1117
1030
  "text": "CustomEvent"
1118
1031
  },
1119
- "description": "Fired when AI responds"
1032
+ "description": "Fired when user sends a message"
1120
1033
  },
1121
1034
  {
1122
- "name": "error",
1035
+ "name": "response-received",
1123
1036
  "type": {
1124
1037
  "text": "CustomEvent"
1125
1038
  },
1126
- "description": "Fired when an error occurs"
1039
+ "description": "Fired when AI responds"
1127
1040
  },
1128
1041
  {
1129
- "name": "message-sent",
1042
+ "name": "error",
1130
1043
  "type": {
1131
1044
  "text": "CustomEvent"
1132
1045
  },
1133
- "description": "Fired when user sends a message"
1046
+ "description": "Fired when an error occurs"
1134
1047
  }
1135
1048
  ],
1136
1049
  "attributes": [
package/dist/index.d.mts CHANGED
@@ -204,10 +204,6 @@ declare class AIChat extends LitElement {
204
204
  clearChat(): void;
205
205
  private lightenColor;
206
206
  private getStorageKey;
207
- private getPendingRequestKey;
208
- private savePendingRequest;
209
- private loadPendingRequest;
210
- private clearPendingRequest;
211
207
  private saveMessagesToStorage;
212
208
  private loadMessagesFromStorage;
213
209
  private clearMessagesFromStorage;
@@ -231,11 +227,6 @@ declare class AIChat extends LitElement {
231
227
  */
232
228
  private fetchQuestionTexts;
233
229
  private handleFAQClick;
234
- /**
235
- * Retry a pending request without adding duplicate user messages
236
- * The user message is already in the chat history from before the interruption
237
- */
238
- private retryPendingRequest;
239
230
  private handleSuggestedQuestionClick;
240
231
  private handleSubmit;
241
232
  private renderChatUI;
package/dist/index.d.ts CHANGED
@@ -204,10 +204,6 @@ declare class AIChat extends LitElement {
204
204
  clearChat(): void;
205
205
  private lightenColor;
206
206
  private getStorageKey;
207
- private getPendingRequestKey;
208
- private savePendingRequest;
209
- private loadPendingRequest;
210
- private clearPendingRequest;
211
207
  private saveMessagesToStorage;
212
208
  private loadMessagesFromStorage;
213
209
  private clearMessagesFromStorage;
@@ -231,11 +227,6 @@ declare class AIChat extends LitElement {
231
227
  */
232
228
  private fetchQuestionTexts;
233
229
  private handleFAQClick;
234
- /**
235
- * Retry a pending request without adding duplicate user messages
236
- * The user message is already in the chat history from before the interruption
237
- */
238
- private retryPendingRequest;
239
230
  private handleSuggestedQuestionClick;
240
231
  private handleSubmit;
241
232
  private renderChatUI;
package/dist/index.js CHANGED
@@ -5373,7 +5373,7 @@ MarkdownIt.prototype.renderInline = function(src, env) {
5373
5373
  var lib_default = MarkdownIt;
5374
5374
 
5375
5375
  // src/components/ai-chat.ts
5376
- console.log("Chatbot Ver = 0.2.24-beta.0");
5376
+ console.log("Chatbot Ver = 0.2.22-beta.0");
5377
5377
  var md = new lib_default({
5378
5378
  html: false,
5379
5379
  // Disable HTML tags in source for security
@@ -5450,43 +5450,6 @@ ${this.welcomeSubtitle}` : this.welcomeMessage;
5450
5450
  getStorageKey() {
5451
5451
  return `ai-chat-messages-${this.sessionId}`;
5452
5452
  }
5453
- getPendingRequestKey() {
5454
- return `ai-chat-pending-${this.sessionId}`;
5455
- }
5456
- savePendingRequest(question, type = "ask", questionData) {
5457
- try {
5458
- const pendingRequest = {
5459
- question,
5460
- type,
5461
- questionData,
5462
- timestamp: Date.now()
5463
- };
5464
- const key = this.getPendingRequestKey();
5465
- localStorage.setItem(key, JSON.stringify(pendingRequest));
5466
- } catch (error2) {
5467
- console.warn("Failed to save pending request to localStorage:", error2);
5468
- }
5469
- }
5470
- loadPendingRequest() {
5471
- try {
5472
- const key = this.getPendingRequestKey();
5473
- const saved = localStorage.getItem(key);
5474
- if (saved) {
5475
- return JSON.parse(saved);
5476
- }
5477
- } catch (error2) {
5478
- console.warn("Failed to load pending request from localStorage:", error2);
5479
- }
5480
- return null;
5481
- }
5482
- clearPendingRequest() {
5483
- try {
5484
- const key = this.getPendingRequestKey();
5485
- localStorage.removeItem(key);
5486
- } catch (error2) {
5487
- console.warn("Failed to clear pending request from localStorage:", error2);
5488
- }
5489
- }
5490
5453
  saveMessagesToStorage() {
5491
5454
  try {
5492
5455
  const storageKey = this.getStorageKey();
@@ -5584,19 +5547,6 @@ ${this.welcomeSubtitle}` : this.welcomeMessage;
5584
5547
  }];
5585
5548
  }
5586
5549
  }
5587
- const pendingRequest = this.loadPendingRequest();
5588
- if (pendingRequest) {
5589
- const messagesWithoutErrors = this.messages.filter((msg) => {
5590
- if (msg.role === "assistant" && msg.content === this.errorMessage) {
5591
- return false;
5592
- }
5593
- return true;
5594
- });
5595
- this.messages = messagesWithoutErrors;
5596
- setTimeout(() => {
5597
- this.retryPendingRequest(pendingRequest);
5598
- }, 500);
5599
- }
5600
5550
  }
5601
5551
  updated(changedProperties) {
5602
5552
  super.updated(changedProperties);
@@ -5730,7 +5680,7 @@ ${this.welcomeSubtitle}` : this.welcomeMessage;
5730
5680
  const results = await Promise.all(fetchPromises);
5731
5681
  return results.filter((q) => q !== null);
5732
5682
  }
5733
- async handleFAQClick(question, event) {
5683
+ async handleFAQClick(question) {
5734
5684
  if (this.isLoading) return;
5735
5685
  if (question.Id && question.QuestionType || question.id && question.question_type) {
5736
5686
  await this.handleSuggestedQuestionClick(question);
@@ -5740,233 +5690,6 @@ ${this.welcomeSubtitle}` : this.welcomeMessage;
5740
5690
  this.handleSubmit(submitEvent);
5741
5691
  }
5742
5692
  }
5743
- /**
5744
- * Retry a pending request without adding duplicate user messages
5745
- * The user message is already in the chat history from before the interruption
5746
- */
5747
- async retryPendingRequest(pendingRequest) {
5748
- this.isLoading = true;
5749
- if (pendingRequest.type === "suggested" && pendingRequest.questionData) {
5750
- try {
5751
- const { questionId, questionType } = pendingRequest.questionData;
5752
- let baseUrl = "";
5753
- if (this.initialQuestionsUrl) {
5754
- try {
5755
- const urlObj = new URL(this.initialQuestionsUrl);
5756
- baseUrl = `${urlObj.protocol}//${urlObj.host}`;
5757
- } catch {
5758
- baseUrl = "http://43.217.183.120:8080";
5759
- }
5760
- } else {
5761
- baseUrl = "http://43.217.183.120:8080";
5762
- }
5763
- const url = `${baseUrl}/api/questions/${questionId}?question_type=${questionType}&language=${this.language}`;
5764
- const response = await fetch(url, {
5765
- method: "GET",
5766
- headers: { "Content-Type": "application/json" }
5767
- });
5768
- if (!response.ok) {
5769
- const errorText = await response.text();
5770
- throw new Error(`Backend error: ${response.status} ${errorText}`);
5771
- }
5772
- const data = await response.json();
5773
- let responseText = "No response from agent";
5774
- let suggestedQuestions = void 0;
5775
- if (data && typeof data === "object") {
5776
- if (data.question && data.question.answer_text) {
5777
- responseText = data.question.answer_text;
5778
- }
5779
- if (data.related_questions && Array.isArray(data.related_questions) && data.related_questions.length > 0) {
5780
- if (typeof data.related_questions[0] === "object" && data.related_questions[0].question_text) {
5781
- suggestedQuestions = data.related_questions.map((q) => ({
5782
- id: q.id,
5783
- question_type: q.question_type,
5784
- question_text: q.question_text,
5785
- category: q.category
5786
- }));
5787
- }
5788
- }
5789
- }
5790
- const assistantMessage = {
5791
- id: (Date.now() + 1).toString(),
5792
- role: "assistant",
5793
- content: responseText,
5794
- suggestedQuestions
5795
- };
5796
- this.messages = [...this.messages, assistantMessage];
5797
- this.clearPendingRequest();
5798
- this.dispatchEvent(new CustomEvent("response-received", {
5799
- detail: assistantMessage,
5800
- bubbles: true,
5801
- composed: true
5802
- }));
5803
- } catch (err) {
5804
- console.error("Retry suggested question API failed:", err);
5805
- const errorMessage = {
5806
- id: (Date.now() + 1).toString(),
5807
- role: "assistant",
5808
- content: this.errorMessage
5809
- };
5810
- this.messages = [...this.messages, errorMessage];
5811
- this.dispatchEvent(new CustomEvent("error", {
5812
- detail: err,
5813
- bubbles: true,
5814
- composed: true
5815
- }));
5816
- } finally {
5817
- this.isLoading = false;
5818
- }
5819
- } else {
5820
- try {
5821
- const response = await fetch(`${this.apiUrl}/ask`, {
5822
- method: "POST",
5823
- headers: { "Content-Type": "application/json" },
5824
- body: JSON.stringify({
5825
- session_id: this.sessionId,
5826
- question: pendingRequest.question
5827
- })
5828
- });
5829
- if (!response.ok) {
5830
- const errorText = await response.text();
5831
- throw new Error(`Backend error: ${response.status} ${errorText}`);
5832
- }
5833
- const data = await response.json();
5834
- let responseText = "No response from agent";
5835
- let faqs = void 0;
5836
- let suggestedQuestions = void 0;
5837
- let confidence = void 0;
5838
- let responseLanguage = void 0;
5839
- if (data && typeof data === "object" && data.response && typeof data.response === "string") {
5840
- const trimmedResponse = data.response.trim();
5841
- if (trimmedResponse.startsWith("{") || trimmedResponse.startsWith("[")) {
5842
- try {
5843
- const innerData = JSON.parse(data.response);
5844
- if (innerData && innerData.response && typeof innerData.response === "string") {
5845
- responseText = innerData.response;
5846
- faqs = innerData.faq_used || innerData.faqs_used || void 0;
5847
- suggestedQuestions = this.normalizeSuggestedQuestions(innerData.suggested_follow_ups || innerData.suggested_questions);
5848
- confidence = innerData.confident || innerData.confidence || "true";
5849
- responseLanguage = innerData.language || void 0;
5850
- } else {
5851
- responseText = data.response;
5852
- faqs = data.faq_used || data.faqs_used || void 0;
5853
- suggestedQuestions = this.normalizeSuggestedQuestions(data.suggested_follow_ups || data.suggested_questions);
5854
- confidence = data.confident || data.confidence || void 0;
5855
- responseLanguage = data.language || void 0;
5856
- }
5857
- } catch (parseError) {
5858
- const responsePattern = /"response"\s*:\s*"([^"]*(?:\\.[^"]*)*)"/s;
5859
- const responseMatch = data.response.match(responsePattern);
5860
- if (responseMatch) {
5861
- responseText = responseMatch[1].replace(/\\n/g, "\n").replace(/\\t/g, " ").replace(/\\r/g, "\r").replace(/\\"/g, '"').replace(/\\\\/g, "\\");
5862
- } else {
5863
- responseText = "Error: Could not parse response";
5864
- }
5865
- const faqsPattern = /"(?:faq_used|faqs_used)"\s*:\s*(\[[^\]]*\])/s;
5866
- const faqsMatch = data.response.match(faqsPattern);
5867
- if (faqsMatch) {
5868
- try {
5869
- faqs = JSON.parse(faqsMatch[1]);
5870
- } catch {
5871
- const faqsMultiPattern = /"(?:faq_used|faqs_used)"\s*:\s*(\[[\s\S]*?\n\s*\])/;
5872
- const faqsMultiMatch = data.response.match(faqsMultiPattern);
5873
- if (faqsMultiMatch) {
5874
- try {
5875
- faqs = JSON.parse(faqsMultiMatch[1]);
5876
- } catch {
5877
- faqs = void 0;
5878
- }
5879
- }
5880
- }
5881
- }
5882
- const suggestedPattern = /"(?:suggested_follow_ups|suggested_questions)"\s*:\s*(\[[^\]]*\])/s;
5883
- const suggestedMatch = data.response.match(suggestedPattern);
5884
- if (suggestedMatch) {
5885
- try {
5886
- const parsedQuestions = JSON.parse(suggestedMatch[1]);
5887
- suggestedQuestions = this.normalizeSuggestedQuestions(parsedQuestions);
5888
- } catch {
5889
- const suggestedMultiPattern = /"(?:suggested_follow_ups|suggested_questions)"\s*:\s*(\[[\s\S]*?\n\s*\])/;
5890
- const suggestedMultiMatch = data.response.match(suggestedMultiPattern);
5891
- if (suggestedMultiMatch) {
5892
- try {
5893
- const parsedQuestions = JSON.parse(suggestedMultiMatch[1]);
5894
- suggestedQuestions = this.normalizeSuggestedQuestions(parsedQuestions);
5895
- } catch {
5896
- suggestedQuestions = void 0;
5897
- }
5898
- }
5899
- }
5900
- }
5901
- }
5902
- } else {
5903
- responseText = data.response;
5904
- faqs = data.faq_used || data.faqs_used || void 0;
5905
- suggestedQuestions = this.normalizeSuggestedQuestions(data.suggested_follow_ups || data.suggested_questions);
5906
- confidence = data.confident || data.confidence || void 0;
5907
- responseLanguage = data.language || void 0;
5908
- }
5909
- } else if (typeof data === "string") {
5910
- responseText = data;
5911
- } else if (data && typeof data === "object") {
5912
- responseText = data.message || data.answer || "Error: Unexpected response format";
5913
- faqs = data.faq_used || data.faqs_used || void 0;
5914
- suggestedQuestions = this.normalizeSuggestedQuestions(data.suggested_follow_ups || data.suggested_questions);
5915
- confidence = data.confident || data.confidence || void 0;
5916
- responseLanguage = data.language || void 0;
5917
- }
5918
- if (suggestedQuestions && suggestedQuestions.length > 0) {
5919
- const questionsNeedingText = suggestedQuestions.filter(
5920
- (q) => (q.Id || q.id) && (q.QuestionType || q.question_type) && !q.question_text
5921
- );
5922
- if (questionsNeedingText.length > 0) {
5923
- const questionsToFetch = questionsNeedingText.map((q) => ({
5924
- Id: q.Id || q.id?.toString(),
5925
- QuestionType: q.QuestionType || q.question_type
5926
- }));
5927
- const fetchedQuestions = await this.fetchQuestionTexts(questionsToFetch);
5928
- suggestedQuestions = [
5929
- ...suggestedQuestions.filter((q) => q.question_text),
5930
- ...fetchedQuestions
5931
- ];
5932
- }
5933
- }
5934
- if (responseLanguage) {
5935
- this.language = responseLanguage;
5936
- }
5937
- const assistantMessage = {
5938
- id: (Date.now() + 1).toString(),
5939
- role: "assistant",
5940
- content: responseText,
5941
- faqs,
5942
- suggestedQuestions,
5943
- confidence
5944
- };
5945
- this.messages = [...this.messages, assistantMessage];
5946
- this.clearPendingRequest();
5947
- this.dispatchEvent(new CustomEvent("response-received", {
5948
- detail: assistantMessage,
5949
- bubbles: true,
5950
- composed: true
5951
- }));
5952
- } catch (err) {
5953
- console.error("Retry backend connection failed:", err);
5954
- const errorMessage = {
5955
- id: (Date.now() + 1).toString(),
5956
- role: "assistant",
5957
- content: this.errorMessage
5958
- };
5959
- this.messages = [...this.messages, errorMessage];
5960
- this.dispatchEvent(new CustomEvent("error", {
5961
- detail: err,
5962
- bubbles: true,
5963
- composed: true
5964
- }));
5965
- } finally {
5966
- this.isLoading = false;
5967
- }
5968
- }
5969
- }
5970
5693
  async handleSuggestedQuestionClick(question) {
5971
5694
  const questionId = question.Id || question.id;
5972
5695
  const questionType = question.QuestionType || question.question_type;
@@ -5978,7 +5701,6 @@ ${this.welcomeSubtitle}` : this.welcomeMessage;
5978
5701
  };
5979
5702
  this.messages = [...this.messages, userMessage];
5980
5703
  this.isLoading = true;
5981
- this.savePendingRequest(question.question_text, "suggested", { questionId, questionType });
5982
5704
  this.dispatchEvent(new CustomEvent("message-sent", {
5983
5705
  detail: userMessage,
5984
5706
  bubbles: true,
@@ -6030,7 +5752,6 @@ ${this.welcomeSubtitle}` : this.welcomeMessage;
6030
5752
  suggestedQuestions
6031
5753
  };
6032
5754
  this.messages = [...this.messages, assistantMessage];
6033
- this.clearPendingRequest();
6034
5755
  this.dispatchEvent(new CustomEvent("response-received", {
6035
5756
  detail: assistantMessage,
6036
5757
  bubbles: true,
@@ -6065,7 +5786,6 @@ ${this.welcomeSubtitle}` : this.welcomeMessage;
6065
5786
  const questionText = this.input.trim();
6066
5787
  this.input = "";
6067
5788
  this.isLoading = true;
6068
- this.savePendingRequest(questionText, "ask");
6069
5789
  this.dispatchEvent(new CustomEvent("message-sent", {
6070
5790
  detail: userMessage,
6071
5791
  bubbles: true,
@@ -6199,7 +5919,6 @@ ${this.welcomeSubtitle}` : this.welcomeMessage;
6199
5919
  confidence
6200
5920
  };
6201
5921
  this.messages = [...this.messages, assistantMessage];
6202
- this.clearPendingRequest();
6203
5922
  this.dispatchEvent(new CustomEvent("response-received", {
6204
5923
  detail: assistantMessage,
6205
5924
  bubbles: true,
@@ -6273,7 +5992,7 @@ ${this.welcomeSubtitle}` : this.welcomeMessage;
6273
5992
  <p class="faq-title">Cadangan Soalan:</p>
6274
5993
  <ul class="faq-list">
6275
5994
  ${msg.suggestedQuestions.map((question) => lit.html`
6276
- <li class="faq-item" @click=${(e) => this.handleFAQClick(question, e)}>
5995
+ <li class="faq-item" @click=${() => this.handleFAQClick(question)}>
6277
5996
  ${question.question_text}
6278
5997
  </li>
6279
5998
  `)}