@a.izzuddin/ai-chat 0.2.22 → 0.2.24
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/custom-elements.json +93 -6
- package/dist/index.d.mts +9 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +309 -12
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +309 -12
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/custom-elements.json
CHANGED
|
@@ -75,6 +75,10 @@
|
|
|
75
75
|
"name": "pos",
|
|
76
76
|
"default": "start"
|
|
77
77
|
},
|
|
78
|
+
{
|
|
79
|
+
"kind": "variable",
|
|
80
|
+
"name": "type"
|
|
81
|
+
},
|
|
78
82
|
{
|
|
79
83
|
"kind": "variable",
|
|
80
84
|
"name": "suggestedQuestions",
|
|
@@ -873,6 +877,68 @@
|
|
|
873
877
|
}
|
|
874
878
|
}
|
|
875
879
|
},
|
|
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
|
+
},
|
|
876
942
|
{
|
|
877
943
|
"kind": "method",
|
|
878
944
|
"name": "saveMessagesToStorage",
|
|
@@ -988,9 +1054,30 @@
|
|
|
988
1054
|
"type": {
|
|
989
1055
|
"text": "SuggestedQuestion"
|
|
990
1056
|
}
|
|
1057
|
+
},
|
|
1058
|
+
{
|
|
1059
|
+
"name": "event",
|
|
1060
|
+
"optional": true,
|
|
1061
|
+
"type": {
|
|
1062
|
+
"text": "Event"
|
|
1063
|
+
}
|
|
991
1064
|
}
|
|
992
1065
|
]
|
|
993
1066
|
},
|
|
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
|
+
},
|
|
994
1081
|
{
|
|
995
1082
|
"kind": "method",
|
|
996
1083
|
"name": "handleSuggestedQuestionClick",
|
|
@@ -1025,25 +1112,25 @@
|
|
|
1025
1112
|
],
|
|
1026
1113
|
"events": [
|
|
1027
1114
|
{
|
|
1028
|
-
"name": "
|
|
1115
|
+
"name": "response-received",
|
|
1029
1116
|
"type": {
|
|
1030
1117
|
"text": "CustomEvent"
|
|
1031
1118
|
},
|
|
1032
|
-
"description": "Fired when
|
|
1119
|
+
"description": "Fired when AI responds"
|
|
1033
1120
|
},
|
|
1034
1121
|
{
|
|
1035
|
-
"name": "
|
|
1122
|
+
"name": "error",
|
|
1036
1123
|
"type": {
|
|
1037
1124
|
"text": "CustomEvent"
|
|
1038
1125
|
},
|
|
1039
|
-
"description": "Fired when
|
|
1126
|
+
"description": "Fired when an error occurs"
|
|
1040
1127
|
},
|
|
1041
1128
|
{
|
|
1042
|
-
"name": "
|
|
1129
|
+
"name": "message-sent",
|
|
1043
1130
|
"type": {
|
|
1044
1131
|
"text": "CustomEvent"
|
|
1045
1132
|
},
|
|
1046
|
-
"description": "Fired when
|
|
1133
|
+
"description": "Fired when user sends a message"
|
|
1047
1134
|
}
|
|
1048
1135
|
],
|
|
1049
1136
|
"attributes": [
|
package/dist/index.d.mts
CHANGED
|
@@ -204,6 +204,10 @@ 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;
|
|
207
211
|
private saveMessagesToStorage;
|
|
208
212
|
private loadMessagesFromStorage;
|
|
209
213
|
private clearMessagesFromStorage;
|
|
@@ -227,6 +231,11 @@ declare class AIChat extends LitElement {
|
|
|
227
231
|
*/
|
|
228
232
|
private fetchQuestionTexts;
|
|
229
233
|
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;
|
|
230
239
|
private handleSuggestedQuestionClick;
|
|
231
240
|
private handleSubmit;
|
|
232
241
|
private renderChatUI;
|
package/dist/index.d.ts
CHANGED
|
@@ -204,6 +204,10 @@ 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;
|
|
207
211
|
private saveMessagesToStorage;
|
|
208
212
|
private loadMessagesFromStorage;
|
|
209
213
|
private clearMessagesFromStorage;
|
|
@@ -227,6 +231,11 @@ declare class AIChat extends LitElement {
|
|
|
227
231
|
*/
|
|
228
232
|
private fetchQuestionTexts;
|
|
229
233
|
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;
|
|
230
239
|
private handleSuggestedQuestionClick;
|
|
231
240
|
private handleSubmit;
|
|
232
241
|
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.
|
|
5376
|
+
console.log("Chatbot Ver = 0.2.24-beta.0");
|
|
5377
5377
|
var md = new lib_default({
|
|
5378
5378
|
html: false,
|
|
5379
5379
|
// Disable HTML tags in source for security
|
|
@@ -5450,6 +5450,43 @@ ${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
|
+
}
|
|
5453
5490
|
saveMessagesToStorage() {
|
|
5454
5491
|
try {
|
|
5455
5492
|
const storageKey = this.getStorageKey();
|
|
@@ -5547,6 +5584,19 @@ ${this.welcomeSubtitle}` : this.welcomeMessage;
|
|
|
5547
5584
|
}];
|
|
5548
5585
|
}
|
|
5549
5586
|
}
|
|
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
|
+
}
|
|
5550
5600
|
}
|
|
5551
5601
|
updated(changedProperties) {
|
|
5552
5602
|
super.updated(changedProperties);
|
|
@@ -5680,7 +5730,7 @@ ${this.welcomeSubtitle}` : this.welcomeMessage;
|
|
|
5680
5730
|
const results = await Promise.all(fetchPromises);
|
|
5681
5731
|
return results.filter((q) => q !== null);
|
|
5682
5732
|
}
|
|
5683
|
-
async handleFAQClick(question) {
|
|
5733
|
+
async handleFAQClick(question, event) {
|
|
5684
5734
|
if (this.isLoading) return;
|
|
5685
5735
|
if (question.Id && question.QuestionType || question.id && question.question_type) {
|
|
5686
5736
|
await this.handleSuggestedQuestionClick(question);
|
|
@@ -5690,6 +5740,233 @@ ${this.welcomeSubtitle}` : this.welcomeMessage;
|
|
|
5690
5740
|
this.handleSubmit(submitEvent);
|
|
5691
5741
|
}
|
|
5692
5742
|
}
|
|
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
|
+
}
|
|
5693
5970
|
async handleSuggestedQuestionClick(question) {
|
|
5694
5971
|
const questionId = question.Id || question.id;
|
|
5695
5972
|
const questionType = question.QuestionType || question.question_type;
|
|
@@ -5701,6 +5978,7 @@ ${this.welcomeSubtitle}` : this.welcomeMessage;
|
|
|
5701
5978
|
};
|
|
5702
5979
|
this.messages = [...this.messages, userMessage];
|
|
5703
5980
|
this.isLoading = true;
|
|
5981
|
+
this.savePendingRequest(question.question_text, "suggested", { questionId, questionType });
|
|
5704
5982
|
this.dispatchEvent(new CustomEvent("message-sent", {
|
|
5705
5983
|
detail: userMessage,
|
|
5706
5984
|
bubbles: true,
|
|
@@ -5752,6 +6030,7 @@ ${this.welcomeSubtitle}` : this.welcomeMessage;
|
|
|
5752
6030
|
suggestedQuestions
|
|
5753
6031
|
};
|
|
5754
6032
|
this.messages = [...this.messages, assistantMessage];
|
|
6033
|
+
this.clearPendingRequest();
|
|
5755
6034
|
this.dispatchEvent(new CustomEvent("response-received", {
|
|
5756
6035
|
detail: assistantMessage,
|
|
5757
6036
|
bubbles: true,
|
|
@@ -5786,6 +6065,7 @@ ${this.welcomeSubtitle}` : this.welcomeMessage;
|
|
|
5786
6065
|
const questionText = this.input.trim();
|
|
5787
6066
|
this.input = "";
|
|
5788
6067
|
this.isLoading = true;
|
|
6068
|
+
this.savePendingRequest(questionText, "ask");
|
|
5789
6069
|
this.dispatchEvent(new CustomEvent("message-sent", {
|
|
5790
6070
|
detail: userMessage,
|
|
5791
6071
|
bubbles: true,
|
|
@@ -5919,6 +6199,7 @@ ${this.welcomeSubtitle}` : this.welcomeMessage;
|
|
|
5919
6199
|
confidence
|
|
5920
6200
|
};
|
|
5921
6201
|
this.messages = [...this.messages, assistantMessage];
|
|
6202
|
+
this.clearPendingRequest();
|
|
5922
6203
|
this.dispatchEvent(new CustomEvent("response-received", {
|
|
5923
6204
|
detail: assistantMessage,
|
|
5924
6205
|
bubbles: true,
|
|
@@ -5992,7 +6273,7 @@ ${this.welcomeSubtitle}` : this.welcomeMessage;
|
|
|
5992
6273
|
<p class="faq-title">Cadangan Soalan:</p>
|
|
5993
6274
|
<ul class="faq-list">
|
|
5994
6275
|
${msg.suggestedQuestions.map((question) => lit.html`
|
|
5995
|
-
<li class="faq-item" @click=${() => this.handleFAQClick(question)}>
|
|
6276
|
+
<li class="faq-item" @click=${(e) => this.handleFAQClick(question, e)}>
|
|
5996
6277
|
${question.question_text}
|
|
5997
6278
|
</li>
|
|
5998
6279
|
`)}
|
|
@@ -6263,6 +6544,21 @@ exports.AIChat.styles = lit.css`
|
|
|
6263
6544
|
}
|
|
6264
6545
|
}
|
|
6265
6546
|
|
|
6547
|
+
/* Desktop responsive styles - reduce excessive margins on large screens */
|
|
6548
|
+
@media (min-width: 1025px) {
|
|
6549
|
+
.message.user {
|
|
6550
|
+
margin-left: 2rem;
|
|
6551
|
+
}
|
|
6552
|
+
|
|
6553
|
+
.message.assistant {
|
|
6554
|
+
margin-right: 1.5rem;
|
|
6555
|
+
}
|
|
6556
|
+
|
|
6557
|
+
.contact-support-wrapper {
|
|
6558
|
+
margin-left: 1.5rem;
|
|
6559
|
+
}
|
|
6560
|
+
}
|
|
6561
|
+
|
|
6266
6562
|
/* Mobile responsive styles for all modes */
|
|
6267
6563
|
@media (max-width: 768px) {
|
|
6268
6564
|
.contact-support-wrapper {
|
|
@@ -6306,7 +6602,7 @@ exports.AIChat.styles = lit.css`
|
|
|
6306
6602
|
|
|
6307
6603
|
.message-content {
|
|
6308
6604
|
max-width: 100%;
|
|
6309
|
-
font-size:
|
|
6605
|
+
font-size: 1.2rem;
|
|
6310
6606
|
padding: 0.875rem 1.25rem;
|
|
6311
6607
|
}
|
|
6312
6608
|
|
|
@@ -6462,8 +6758,8 @@ exports.AIChat.styles = lit.css`
|
|
|
6462
6758
|
}
|
|
6463
6759
|
|
|
6464
6760
|
.header-avatar {
|
|
6465
|
-
width:
|
|
6466
|
-
height:
|
|
6761
|
+
width: 3.5rem;
|
|
6762
|
+
height: 3.5rem;
|
|
6467
6763
|
border-radius: 50%;
|
|
6468
6764
|
background: #fff;
|
|
6469
6765
|
display: flex;
|
|
@@ -6612,8 +6908,8 @@ exports.AIChat.styles = lit.css`
|
|
|
6612
6908
|
}
|
|
6613
6909
|
|
|
6614
6910
|
.avatar {
|
|
6615
|
-
width:
|
|
6616
|
-
height:
|
|
6911
|
+
width: 3.5rem;
|
|
6912
|
+
height: 3.5rem;
|
|
6617
6913
|
border-radius: 9999px;
|
|
6618
6914
|
background: #E5E7EB;
|
|
6619
6915
|
display: flex;
|
|
@@ -6639,12 +6935,13 @@ exports.AIChat.styles = lit.css`
|
|
|
6639
6935
|
|
|
6640
6936
|
.message-content {
|
|
6641
6937
|
max-width: 36rem;
|
|
6642
|
-
padding: 1rem 1.5rem;
|
|
6643
6938
|
border-radius: 1.25rem;
|
|
6644
6939
|
line-height: 1.6;
|
|
6645
6940
|
overflow-wrap: break-word;
|
|
6646
6941
|
word-wrap: break-word;
|
|
6647
6942
|
min-width: 0;
|
|
6943
|
+
font-size: 1.2rem;
|
|
6944
|
+
padding: 1rem 1.5rem;
|
|
6648
6945
|
}
|
|
6649
6946
|
|
|
6650
6947
|
.message.user .message-content {
|
|
@@ -6786,7 +7083,7 @@ exports.AIChat.styles = lit.css`
|
|
|
6786
7083
|
}
|
|
6787
7084
|
|
|
6788
7085
|
.faq-title {
|
|
6789
|
-
font-size:
|
|
7086
|
+
font-size: 1.1rem;
|
|
6790
7087
|
font-weight: 600;
|
|
6791
7088
|
color: var(--primary-color, #3681D3);
|
|
6792
7089
|
margin: 0 0 0.375rem 0;
|
|
@@ -6806,7 +7103,7 @@ exports.AIChat.styles = lit.css`
|
|
|
6806
7103
|
}
|
|
6807
7104
|
|
|
6808
7105
|
.faq-item {
|
|
6809
|
-
font-size:
|
|
7106
|
+
font-size: 1.2rem;
|
|
6810
7107
|
color: var(--primary-color, #3681D3);
|
|
6811
7108
|
padding: 0;
|
|
6812
7109
|
border-radius: 0.5rem;
|
|
@@ -6962,7 +7259,7 @@ exports.AIChat.styles = lit.css`
|
|
|
6962
7259
|
padding: 0 1rem;
|
|
6963
7260
|
border: 1px solid #d1d5db;
|
|
6964
7261
|
border-radius: 1.5rem;
|
|
6965
|
-
font-size:
|
|
7262
|
+
font-size: 1.2rem;
|
|
6966
7263
|
font-family: inherit;
|
|
6967
7264
|
background: #fff;
|
|
6968
7265
|
color: #374151;
|