@a.izzuddin/ai-chat 0.2.22 → 0.2.23
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 +293 -12
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +293 -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
|
`)}
|
|
@@ -6306,7 +6587,7 @@ exports.AIChat.styles = lit.css`
|
|
|
6306
6587
|
|
|
6307
6588
|
.message-content {
|
|
6308
6589
|
max-width: 100%;
|
|
6309
|
-
font-size:
|
|
6590
|
+
font-size: 1.2rem;
|
|
6310
6591
|
padding: 0.875rem 1.25rem;
|
|
6311
6592
|
}
|
|
6312
6593
|
|
|
@@ -6462,8 +6743,8 @@ exports.AIChat.styles = lit.css`
|
|
|
6462
6743
|
}
|
|
6463
6744
|
|
|
6464
6745
|
.header-avatar {
|
|
6465
|
-
width:
|
|
6466
|
-
height:
|
|
6746
|
+
width: 3.5rem;
|
|
6747
|
+
height: 3.5rem;
|
|
6467
6748
|
border-radius: 50%;
|
|
6468
6749
|
background: #fff;
|
|
6469
6750
|
display: flex;
|
|
@@ -6612,8 +6893,8 @@ exports.AIChat.styles = lit.css`
|
|
|
6612
6893
|
}
|
|
6613
6894
|
|
|
6614
6895
|
.avatar {
|
|
6615
|
-
width:
|
|
6616
|
-
height:
|
|
6896
|
+
width: 3.5rem;
|
|
6897
|
+
height: 3.5rem;
|
|
6617
6898
|
border-radius: 9999px;
|
|
6618
6899
|
background: #E5E7EB;
|
|
6619
6900
|
display: flex;
|
|
@@ -6639,12 +6920,12 @@ exports.AIChat.styles = lit.css`
|
|
|
6639
6920
|
|
|
6640
6921
|
.message-content {
|
|
6641
6922
|
max-width: 36rem;
|
|
6642
|
-
padding: 1rem 1.5rem;
|
|
6643
6923
|
border-radius: 1.25rem;
|
|
6644
6924
|
line-height: 1.6;
|
|
6645
6925
|
overflow-wrap: break-word;
|
|
6646
6926
|
word-wrap: break-word;
|
|
6647
6927
|
min-width: 0;
|
|
6928
|
+
font-size: 1.2rem;
|
|
6648
6929
|
}
|
|
6649
6930
|
|
|
6650
6931
|
.message.user .message-content {
|
|
@@ -6786,7 +7067,7 @@ exports.AIChat.styles = lit.css`
|
|
|
6786
7067
|
}
|
|
6787
7068
|
|
|
6788
7069
|
.faq-title {
|
|
6789
|
-
font-size:
|
|
7070
|
+
font-size: 1.1rem;
|
|
6790
7071
|
font-weight: 600;
|
|
6791
7072
|
color: var(--primary-color, #3681D3);
|
|
6792
7073
|
margin: 0 0 0.375rem 0;
|
|
@@ -6806,7 +7087,7 @@ exports.AIChat.styles = lit.css`
|
|
|
6806
7087
|
}
|
|
6807
7088
|
|
|
6808
7089
|
.faq-item {
|
|
6809
|
-
font-size:
|
|
7090
|
+
font-size: 1.2rem;
|
|
6810
7091
|
color: var(--primary-color, #3681D3);
|
|
6811
7092
|
padding: 0;
|
|
6812
7093
|
border-radius: 0.5rem;
|
|
@@ -6962,7 +7243,7 @@ exports.AIChat.styles = lit.css`
|
|
|
6962
7243
|
padding: 0 1rem;
|
|
6963
7244
|
border: 1px solid #d1d5db;
|
|
6964
7245
|
border-radius: 1.5rem;
|
|
6965
|
-
font-size:
|
|
7246
|
+
font-size: 1.2rem;
|
|
6966
7247
|
font-family: inherit;
|
|
6967
7248
|
background: #fff;
|
|
6968
7249
|
color: #374151;
|