Buttons still don’t work. I still can’t train. Fix make everything functional - Follow Up Deployment
Browse files- index.html +267 -64
- prompts.txt +3 -1
index.html
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
<!DOCTYPE html>
|
2 |
<html lang="en">
|
3 |
<head>
|
4 |
<meta charset="UTF-8">
|
@@ -627,16 +627,43 @@
|
|
627 |
// Initialize Natural Language Processing
|
628 |
const nlp = {
|
629 |
processInput: function(text) {
|
630 |
-
//
|
631 |
text = text.toLowerCase().trim();
|
632 |
-
|
633 |
-
|
634 |
-
|
635 |
-
|
636 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
637 |
};
|
638 |
|
639 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
640 |
},
|
641 |
learnResponse: function(inputText, preferredResponse) {
|
642 |
// Tokenize input and learn patterns
|
@@ -794,96 +821,272 @@
|
|
794 |
chatContainer.appendChild(userBubble);
|
795 |
|
796 |
// Process user input and generate AI response
|
797 |
-
setTimeout(
|
798 |
-
const isTeachingExample = userMessage.includes("should respond");
|
799 |
let aiResponse;
|
|
|
800 |
|
801 |
if (isTeachingExample) {
|
802 |
-
|
803 |
-
|
804 |
-
|
805 |
-
|
806 |
-
|
807 |
-
|
808 |
-
|
809 |
-
|
810 |
-
|
811 |
-
|
812 |
-
|
813 |
-
|
814 |
-
<p
|
815 |
-
|
816 |
-
|
817 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
818 |
} else {
|
819 |
-
// Get smart response based on learned data
|
820 |
const response = nlp.getBestResponse(userMessage);
|
821 |
aiResponse = `
|
822 |
-
<p>Based on
|
823 |
<div class="mt-2 bg-blue-50 dark:bg-blue-900 rounded-lg p-3">
|
824 |
<p>${response}</p>
|
825 |
</div>
|
|
|
826 |
`;
|
827 |
}
|
828 |
|
829 |
const aiBubble = document.createElement('div');
|
830 |
aiBubble.className = 'ai-bubble mt-4 animate-fadeIn';
|
831 |
-
aiBubble.innerHTML = aiResponse
|
832 |
-
|
833 |
-
|
834 |
-
|
835 |
-
|
836 |
-
|
837 |
-
|
838 |
-
|
839 |
-
|
840 |
-
<
|
841 |
-
|
842 |
-
|
843 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
844 |
chatContainer.appendChild(aiBubble);
|
845 |
chatContainer.scrollTop = chatContainer.scrollHeight;
|
846 |
-
},
|
847 |
|
848 |
input.value = '';
|
849 |
}
|
850 |
}
|
851 |
|
852 |
function acceptResponse(button) {
|
853 |
-
|
854 |
-
|
855 |
-
|
856 |
-
|
857 |
-
|
858 |
-
|
859 |
-
|
860 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
861 |
}
|
862 |
|
863 |
function editResponse(button) {
|
864 |
const bubble = button.closest('.ai-bubble');
|
865 |
const responseDiv = bubble.querySelector('div.bg-blue-50');
|
866 |
-
const
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
867 |
|
868 |
responseDiv.innerHTML = `
|
869 |
-
<textarea class="w-full p-2 rounded border border-gray-300"
|
870 |
-
|
871 |
-
|
872 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
873 |
`;
|
874 |
}
|
875 |
|
876 |
-
function
|
877 |
-
const newText = button.parentElement.querySelector('textarea').value;
|
878 |
const bubble = button.closest('.ai-bubble');
|
879 |
-
const responseDiv = button.
|
880 |
-
|
881 |
-
responseDiv.innerHTML = `<p>${newText}</p>`;
|
882 |
|
883 |
-
//
|
884 |
-
|
885 |
-
|
886 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
887 |
}
|
888 |
|
889 |
function handleTrainingKeyPress(e) {
|
|
|
1 |
+
d mm<!DOCTYPE html>
|
2 |
<html lang="en">
|
3 |
<head>
|
4 |
<meta charset="UTF-8">
|
|
|
627 |
// Initialize Natural Language Processing
|
628 |
const nlp = {
|
629 |
processInput: function(text) {
|
630 |
+
// Enhanced NLP processing
|
631 |
text = text.toLowerCase().trim();
|
632 |
+
|
633 |
+
// Tokenize and clean input
|
634 |
+
const tokens = text
|
635 |
+
.replace(/[^\w\s]/g, '')
|
636 |
+
.split(/\s+/)
|
637 |
+
.filter(token => token.length > 2);
|
638 |
+
|
639 |
+
// Context detection with weights
|
640 |
+
const contextScores = {
|
641 |
+
business: ['work', 'job', 'meeting', 'service', 'price', 'appointment', 'business', 'company']
|
642 |
+
.filter(word => text.includes(word)).length,
|
643 |
+
personal: ['family', 'friend', 'mom', 'dad', 'home', 'personal']
|
644 |
+
.filter(word => text.includes(word)).length,
|
645 |
+
spam: ['spam', 'block', 'unwanted', 'telemarketer', 'sales', 'offer']
|
646 |
+
.filter(word => text.includes(word)).length * 2, // Higher weight
|
647 |
+
question: ['what', 'when', 'where', 'how', 'why', 'can you', 'would you', '?']
|
648 |
+
.filter(word => text.includes(word)).length
|
649 |
};
|
650 |
|
651 |
+
// Determine primary context
|
652 |
+
let primaryContext = 'general';
|
653 |
+
let maxScore = 0;
|
654 |
+
for (const [context, score] of Object.entries(contextScores)) {
|
655 |
+
if (score > maxScore) {
|
656 |
+
maxScore = score;
|
657 |
+
primaryContext = context;
|
658 |
+
}
|
659 |
+
}
|
660 |
+
|
661 |
+
return {
|
662 |
+
text,
|
663 |
+
tokens,
|
664 |
+
context: primaryContext,
|
665 |
+
isQuestion: contextScores.question > 0
|
666 |
+
};
|
667 |
},
|
668 |
learnResponse: function(inputText, preferredResponse) {
|
669 |
// Tokenize input and learn patterns
|
|
|
821 |
chatContainer.appendChild(userBubble);
|
822 |
|
823 |
// Process user input and generate AI response
|
824 |
+
setTimeout(() => {
|
|
|
825 |
let aiResponse;
|
826 |
+
const isTeachingExample = /how should i respond|please reply with|respond with/i.test(userMessage);
|
827 |
|
828 |
if (isTeachingExample) {
|
829 |
+
const teachingMatch = userMessage.match(/(how should i respond to|please reply to|respond to) (.*?) (with|by saying) (.*)/i);
|
830 |
+
if (teachingMatch) {
|
831 |
+
const question = teachingMatch[2];
|
832 |
+
const answer = teachingMatch[4];
|
833 |
+
nlp.learnResponse(question, answer);
|
834 |
+
|
835 |
+
aiResponse = `
|
836 |
+
<p>Got it! I've learned this response:</p>
|
837 |
+
<div class="mt-2 bg-blue-50 dark:bg-blue-900 rounded-lg p-3">
|
838 |
+
<p><strong>When asked:</strong> ${question}</p>
|
839 |
+
<p><strong>I'll respond:</strong> ${answer}</p>
|
840 |
+
</div>
|
841 |
+
<p class="mt-2">I'll use this response pattern for similar questions.</p>
|
842 |
+
`;
|
843 |
+
} else {
|
844 |
+
aiResponse = `
|
845 |
+
<div class="ai-bubble mt-4 animate-fadeIn">
|
846 |
+
<p>I can learn how to respond! Try phrasing like:</p>
|
847 |
+
<div class="mt-2 bg-blue-50 dark:bg-blue-900 rounded-lg p-3">
|
848 |
+
<p>"How should I respond to questions about pricing?"</p>
|
849 |
+
<p>"Please reply to appointment requests with: 'Would you like morning or afternoon?'"</p>
|
850 |
+
</div>
|
851 |
+
</div>
|
852 |
+
`;
|
853 |
+
}
|
854 |
} else {
|
|
|
855 |
const response = nlp.getBestResponse(userMessage);
|
856 |
aiResponse = `
|
857 |
+
<p>Based on my training, here's how I would respond:</p>
|
858 |
<div class="mt-2 bg-blue-50 dark:bg-blue-900 rounded-lg p-3">
|
859 |
<p>${response}</p>
|
860 |
</div>
|
861 |
+
<p class="mt-2">Would you like to:</p>
|
862 |
`;
|
863 |
}
|
864 |
|
865 |
const aiBubble = document.createElement('div');
|
866 |
aiBubble.className = 'ai-bubble mt-4 animate-fadeIn';
|
867 |
+
aiBubble.innerHTML = aiResponse;
|
868 |
+
|
869 |
+
if (!aiResponse.includes('Try phrasing')) {
|
870 |
+
aiBubble.innerHTML += `
|
871 |
+
<div class="mt-3 flex gap-2">
|
872 |
+
<button class="flex-1 py-2 bg-green-500 text-white rounded-lg hover:bg-green-600 transition"
|
873 |
+
onclick="acceptResponse(this)">
|
874 |
+
Accept <i class="fas fa-check ml-1"></i>
|
875 |
+
</button>
|
876 |
+
<button class="flex-1 py-2 bg-red-500 text-white rounded-lg hover:bg-red-600 transition"
|
877 |
+
onclick="editResponse(this)">
|
878 |
+
Edit <i class="fas fa-edit ml-1"></i>
|
879 |
+
</button>
|
880 |
+
<button class="px-3 py-2 bg-accent text-white rounded-lg hover:bg-blue-600 transition"
|
881 |
+
onclick="playResponse(this)">
|
882 |
+
<i class="fas fa-volume-up"></i>
|
883 |
+
</button>
|
884 |
+
</div>
|
885 |
+
`;
|
886 |
+
}
|
887 |
+
|
888 |
chatContainer.appendChild(aiBubble);
|
889 |
chatContainer.scrollTop = chatContainer.scrollHeight;
|
890 |
+
}, 500);
|
891 |
|
892 |
input.value = '';
|
893 |
}
|
894 |
}
|
895 |
|
896 |
function acceptResponse(button) {
|
897 |
+
try {
|
898 |
+
const responseDiv = button.closest('.ai-bubble').querySelector('div.bg-blue-50');
|
899 |
+
if (!responseDiv) throw new Error('Response not found');
|
900 |
+
|
901 |
+
let responseText = '';
|
902 |
+
// Handle both single p and multi-line responses
|
903 |
+
const pTags = responseDiv.querySelectorAll('p');
|
904 |
+
if (pTags.length > 1) {
|
905 |
+
responseText = Array.from(pTags)
|
906 |
+
.filter(p => !p.innerHTML.includes('<strong>'))
|
907 |
+
.map(p => p.textContent)
|
908 |
+
.join('\n');
|
909 |
+
} else {
|
910 |
+
responseText = pTags[0].textContent;
|
911 |
+
}
|
912 |
+
|
913 |
+
const context = nlp.determineContext(responseText);
|
914 |
+
|
915 |
+
// If it's a teaching example, find the question too
|
916 |
+
const strongTags = responseDiv.querySelectorAll('strong');
|
917 |
+
if (strongTags.length >= 2) {
|
918 |
+
const question = strongTags[0].nextSibling.textContent.trim();
|
919 |
+
const answer = strongTags[1].nextSibling.textContent.trim();
|
920 |
+
nlp.learnResponse(question, answer);
|
921 |
+
} else {
|
922 |
+
trainingData.customResponses[context] = responseText;
|
923 |
+
}
|
924 |
+
|
925 |
+
nlp.saveToLocalStorage();
|
926 |
+
|
927 |
+
button.innerHTML = '<i class="fas fa-check-circle"></i> Saved';
|
928 |
+
button.classList.remove('bg-green-500');
|
929 |
+
button.classList.add('bg-emerald-600');
|
930 |
+
button.disabled = true;
|
931 |
+
|
932 |
+
// Disable other buttons
|
933 |
+
const buttons = button.closest('.flex').querySelectorAll('button');
|
934 |
+
buttons.forEach(btn => {
|
935 |
+
if (btn !== button) {
|
936 |
+
btn.classList.add('opacity-50', 'cursor-not-allowed');
|
937 |
+
btn.disabled = true;
|
938 |
+
}
|
939 |
+
});
|
940 |
+
} catch (error) {
|
941 |
+
console.error('Error accepting response:', error);
|
942 |
+
alert('There was an error saving this response. Please try again.');
|
943 |
+
}
|
944 |
}
|
945 |
|
946 |
function editResponse(button) {
|
947 |
const bubble = button.closest('.ai-bubble');
|
948 |
const responseDiv = bubble.querySelector('div.bg-blue-50');
|
949 |
+
const pTags = responseDiv.querySelectorAll('p');
|
950 |
+
|
951 |
+
let currentText = '';
|
952 |
+
if (pTags.length > 1) {
|
953 |
+
// For teaching examples, combine response
|
954 |
+
currentText = Array.from(pTags)
|
955 |
+
.filter(p => !p.innerHTML.includes('<strong>'))
|
956 |
+
.map(p => p.textContent)
|
957 |
+
.join('\n\n');
|
958 |
+
} else {
|
959 |
+
currentText = pTags[0].textContent;
|
960 |
+
}
|
961 |
|
962 |
responseDiv.innerHTML = `
|
963 |
+
<textarea class="w-full p-2 rounded border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700"
|
964 |
+
rows="4">${currentText}</textarea>
|
965 |
+
<div class="mt-2 flex justify-end gap-2">
|
966 |
+
<button onclick="cancelEdit(this)"
|
967 |
+
class="px-4 py-1 bg-gray-300 dark:bg-gray-600 text-gray-800 dark:text-gray-200 rounded">
|
968 |
+
Cancel
|
969 |
+
</button>
|
970 |
+
<button onclick="saveEditedResponse(this)"
|
971 |
+
class="px-4 py-1 bg-accent text-white rounded hover:bg-blue-600 transition">
|
972 |
+
Save Changes
|
973 |
+
</button>
|
974 |
+
</div>
|
975 |
`;
|
976 |
}
|
977 |
|
978 |
+
function cancelEdit(button) {
|
|
|
979 |
const bubble = button.closest('.ai-bubble');
|
980 |
+
const responseDiv = button.closest('.bg-blue-50');
|
981 |
+
const originalText = responseDiv.querySelector('textarea').value;
|
|
|
982 |
|
983 |
+
// Re-create the original response display
|
984 |
+
if (originalText.includes('\n\n')) {
|
985 |
+
responseDiv.innerHTML = originalText.split('\n\n')
|
986 |
+
.map(text => `<p>${text}</p>`)
|
987 |
+
.join('');
|
988 |
+
} else {
|
989 |
+
responseDiv.innerHTML = `<p>${originalText}</p>`;
|
990 |
+
}
|
991 |
+
}
|
992 |
+
|
993 |
+
function saveEditedResponse(button) {
|
994 |
+
try {
|
995 |
+
const newText = button.closest('.bg-blue-50').querySelector('textarea').value;
|
996 |
+
const bubble = button.closest('.ai-bubble');
|
997 |
+
const responseDiv = button.closest('.bg-blue-50');
|
998 |
+
|
999 |
+
// Determine if this was a teaching example
|
1000 |
+
const wasTeachingExample = bubble.innerHTML.includes('<strong>When asked:</strong>');
|
1001 |
+
|
1002 |
+
if (wasTeachingExample) {
|
1003 |
+
// Parse the edited teaching example
|
1004 |
+
const lines = newText.split('\n');
|
1005 |
+
if (lines.length >= 2) {
|
1006 |
+
const question = lines[0].replace('When asked:', '').trim();
|
1007 |
+
const answer = lines[1].replace('I\'ll respond:', '').trim();
|
1008 |
+
nlp.learnResponse(question, answer);
|
1009 |
+
}
|
1010 |
+
} else {
|
1011 |
+
// Update regular response
|
1012 |
+
const context = nlp.determineContext(newText);
|
1013 |
+
trainingData.customResponses[context] = newText;
|
1014 |
+
}
|
1015 |
+
|
1016 |
+
nlp.saveToLocalStorage();
|
1017 |
+
|
1018 |
+
// Update display
|
1019 |
+
if (newText.includes('\n')) {
|
1020 |
+
responseDiv.innerHTML = newText.split('\n')
|
1021 |
+
.map(text => `<p>${text}</p>`)
|
1022 |
+
.join('');
|
1023 |
+
} else {
|
1024 |
+
responseDiv.innerHTML = `<p>${newText}</p>`;
|
1025 |
+
}
|
1026 |
+
|
1027 |
+
// Reset action buttons
|
1028 |
+
const actionDiv = document.createElement('div');
|
1029 |
+
actionDiv.className = 'mt-3 flex gap-2';
|
1030 |
+
actionDiv.innerHTML = `
|
1031 |
+
<button class="flex-1 py-2 bg-green-500 text-white rounded-lg hover:bg-green-600 transition"
|
1032 |
+
onclick="acceptResponse(this)">
|
1033 |
+
Accept <i class="fas fa-check ml-1"></i>
|
1034 |
+
</button>
|
1035 |
+
<button class="flex-1 py-2 bg-red-500 text-white rounded-lg hover:bg-red-600 transition"
|
1036 |
+
onclick="editResponse(this)">
|
1037 |
+
Edit <i class="fas fa-edit ml-1"></i>
|
1038 |
+
</button>
|
1039 |
+
<button class="px-3 py-2 bg-accent text-white rounded-lg hover:bg-blue-600 transition"
|
1040 |
+
onclick="playResponse(this)">
|
1041 |
+
<i class="fas fa-volume-up"></i>
|
1042 |
+
</button>
|
1043 |
+
`;
|
1044 |
+
responseDiv.insertAdjacentElement('afterend', actionDiv);
|
1045 |
+
} catch (error) {
|
1046 |
+
console.error('Error saving edits:', error);
|
1047 |
+
alert('There was an error saving your changes. Please try again.');
|
1048 |
+
}
|
1049 |
+
}
|
1050 |
+
|
1051 |
+
function playResponse(button) {
|
1052 |
+
try {
|
1053 |
+
const responseDiv = button.closest('.ai-bubble').querySelector('div.bg-blue-50');
|
1054 |
+
let responseText = '';
|
1055 |
+
|
1056 |
+
if (responseDiv.querySelector('strong')) {
|
1057 |
+
// For teaching examples
|
1058 |
+
const pTags = responseDiv.querySelectorAll('p');
|
1059 |
+
responseText = Array.from(pTags)
|
1060 |
+
.filter(p => !p.innerHTML.includes('<strong>'))
|
1061 |
+
.map(p => p.textContent)
|
1062 |
+
.join(' ');
|
1063 |
+
} else {
|
1064 |
+
// For regular responses
|
1065 |
+
responseText = responseDiv.textContent;
|
1066 |
+
}
|
1067 |
+
|
1068 |
+
// Simulate voice playback
|
1069 |
+
button.innerHTML = '<i class="fas fa-spinner fa-spin"></i>';
|
1070 |
+
button.disabled = true;
|
1071 |
+
|
1072 |
+
setTimeout(() => {
|
1073 |
+
button.innerHTML = '<i class="fas fa-volume-up"></i>';
|
1074 |
+
button.disabled = false;
|
1075 |
+
console.log('Would play:', responseText);
|
1076 |
+
// In a real app: voiceProcessor.speak(responseText).play();
|
1077 |
+
|
1078 |
+
// Show visual feedback
|
1079 |
+
const bubble = button.closest('.ai-bubble');
|
1080 |
+
bubble.classList.add('ring-2', 'ring-accent');
|
1081 |
+
setTimeout(() => {
|
1082 |
+
bubble.classList.remove('ring-2', 'ring-accent');
|
1083 |
+
}, 1000);
|
1084 |
+
}, 1500);
|
1085 |
+
} catch (error) {
|
1086 |
+
console.error('Error playing response:', error);
|
1087 |
+
button.innerHTML = '<i class="fas fa-volume-up"></i>';
|
1088 |
+
button.disabled = false;
|
1089 |
+
}
|
1090 |
}
|
1091 |
|
1092 |
function handleTrainingKeyPress(e) {
|
prompts.txt
CHANGED
@@ -1,3 +1,5 @@
|
|
1 |
Make voice humanistic . Add rvc technology and okada tts
|
2 |
Please make the training work. Currently doesn’t . Add intelligence and smart learning. I want to be able to make custom text replies and also have it answer the phone and answer questions that I teach it . Have it learn diction. Make everything work and insure that this can and is used whenever someone callls my phone number 5622289429
|
3 |
-
I own a car detailing business. Teach ai about it
|
|
|
|
|
|
1 |
Make voice humanistic . Add rvc technology and okada tts
|
2 |
Please make the training work. Currently doesn’t . Add intelligence and smart learning. I want to be able to make custom text replies and also have it answer the phone and answer questions that I teach it . Have it learn diction. Make everything work and insure that this can and is used whenever someone callls my phone number 5622289429
|
3 |
+
I own a car detailing business. Teach ai about it
|
4 |
+
Buttons still don’t work. I still can’t train. Fix make everything functional
|
5 |
+
Buttons still don’t work. I still can’t train. Fix make everything functional
|