Update app.py
Browse files
app.py
CHANGED
|
@@ -15,13 +15,10 @@ from google.oauth2 import service_account
|
|
| 15 |
from googleapiclient.discovery import build
|
| 16 |
from datetime import datetime
|
| 17 |
from google.oauth2.service_account import Credentials
|
| 18 |
-
from gtts import gTTS
|
| 19 |
-
import speech_recognition as sr # Speech-to-text
|
| 20 |
import tempfile
|
| 21 |
import base64
|
| 22 |
-
from io import BytesIO
|
| 23 |
-
|
| 24 |
-
|
| 25 |
|
| 26 |
|
| 27 |
|
|
@@ -138,21 +135,6 @@ BATTERY_COLORS = {
|
|
| 138 |
SPONSOR = "default" # Set this to the sponsor name or leave as "default" for default branding
|
| 139 |
TRAINER_SHEET_ID = "1GiA8pxZn04aUA-OKwcANvfJ_CpChooF2mUQxiJ_i2-s"
|
| 140 |
|
| 141 |
-
def text_to_speech(text):
|
| 142 |
-
"""Convert text to speech and return base64 encoded audio data"""
|
| 143 |
-
try:
|
| 144 |
-
# Create speech from text
|
| 145 |
-
tts = gTTS(text=text, lang='en')
|
| 146 |
-
|
| 147 |
-
# Save to temporary file
|
| 148 |
-
with tempfile.NamedTemporaryFile(delete=False, suffix=".mp3") as fp:
|
| 149 |
-
tts.save(fp.name)
|
| 150 |
-
return fp.name
|
| 151 |
-
|
| 152 |
-
except Exception as e:
|
| 153 |
-
print(f"Error in text-to-speech: {str(e)}")
|
| 154 |
-
return None
|
| 155 |
-
|
| 156 |
def record_trainer_info(email, client_email, freelancer_email, freelancer_link, seal):
|
| 157 |
"""Record trainer information to Google Sheet"""
|
| 158 |
try:
|
|
@@ -2889,43 +2871,70 @@ button:active {
|
|
| 2889 |
.progress-bar {
|
| 2890 |
display: none !important;
|
| 2891 |
}
|
| 2892 |
-
|
| 2893 |
-
|
| 2894 |
-
|
| 2895 |
-
|
| 2896 |
-
|
| 2897 |
-
|
| 2898 |
-
margin-left: 5px
|
| 2899 |
-
background: linear-gradient(135deg, #6e8efb, #a777e3) !important;
|
| 2900 |
-
color: white !important;
|
| 2901 |
}
|
| 2902 |
-
.
|
| 2903 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2904 |
}
|
| 2905 |
-
|
| 2906 |
-
|
| 2907 |
-
margin-top: 10px;
|
| 2908 |
-
background: rgba(255, 255, 255, 0.7) !important;
|
| 2909 |
-
border-radius: 8px !important;
|
| 2910 |
-
padding: 10px !important;
|
| 2911 |
}
|
| 2912 |
-
|
| 2913 |
-
|
| 2914 |
-
|
| 2915 |
-
|
| 2916 |
-
|
| 2917 |
-
|
| 2918 |
-
|
| 2919 |
-
margin-left: 5px !important;
|
| 2920 |
-
background: linear-gradient(135deg, #6e8efb, #a777e3) !important;
|
| 2921 |
-
color: white !important;
|
| 2922 |
}
|
| 2923 |
-
.
|
| 2924 |
-
|
| 2925 |
}
|
|
|
|
| 2926 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2927 |
"""
|
| 2928 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2929 |
def respond(message, history, max_tokens, temperature, top_p):
|
| 2930 |
email = OWNER_EMAIL
|
| 2931 |
|
|
@@ -2933,12 +2942,10 @@ def respond(message, history, max_tokens, temperature, top_p):
|
|
| 2933 |
save_chat_history(email, message, "")
|
| 2934 |
|
| 2935 |
try:
|
| 2936 |
-
# Save to BATTERY_SHEET_ID
|
| 2937 |
sheet = get_or_create_sheet(BATTERY_SHEET_ID, "ChatHistory")
|
| 2938 |
-
|
| 2939 |
now_str = datetime.now().strftime("%m/%d/%Y %H:%M:%S")
|
| 2940 |
sheet.append_row([now_str, email, message, ""])
|
| 2941 |
-
|
| 2942 |
except Exception as e:
|
| 2943 |
print(f"Error saving to battery sheet: {str(e)}")
|
| 2944 |
|
|
@@ -2946,7 +2953,7 @@ def respond(message, history, max_tokens, temperature, top_p):
|
|
| 2946 |
temp_response = f"""<a href="https://flutterwave.com/pay/gossapp" target="_blank">
|
| 2947 |
<img src='https://i.imgur.com/PznT4qo.png' width='20'>
|
| 2948 |
</a>"""
|
| 2949 |
-
yield [(message, temp_response)], None #
|
| 2950 |
|
| 2951 |
try:
|
| 2952 |
# Build prompt
|
|
@@ -2955,13 +2962,12 @@ def respond(message, history, max_tokens, temperature, top_p):
|
|
| 2955 |
for user_msg, bot_msg in history:
|
| 2956 |
if user_msg:
|
| 2957 |
messages.append({"role": "user", "content": user_msg})
|
| 2958 |
-
if bot_msg and not str(bot_msg).startswith("<img"):
|
| 2959 |
messages.append({"role": "assistant", "content": str(bot_msg)})
|
| 2960 |
messages.append({"role": "user", "content": message})
|
| 2961 |
|
| 2962 |
-
# Get
|
| 2963 |
inference_client = get_inference_client()
|
| 2964 |
-
|
| 2965 |
response = ""
|
| 2966 |
for chunk in inference_client.chat_completion(
|
| 2967 |
messages,
|
|
@@ -2974,36 +2980,33 @@ def respond(message, history, max_tokens, temperature, top_p):
|
|
| 2974 |
if token:
|
| 2975 |
response += token
|
| 2976 |
clean_response = response.split("(Note:")[0].strip()
|
| 2977 |
-
yield [(message, clean_response)], None #
|
| 2978 |
|
| 2979 |
clean_response = response.split("(Note:")[0].strip()
|
| 2980 |
-
|
| 2981 |
-
# Generate audio for the response
|
| 2982 |
-
audio_file = text_to_speech(clean_response)
|
| 2983 |
|
| 2984 |
-
#
|
|
|
|
|
|
|
|
|
|
| 2985 |
save_chat_history(email, message, clean_response)
|
| 2986 |
|
| 2987 |
-
# Update
|
| 2988 |
try:
|
| 2989 |
scope = ['https://www.googleapis.com/auth/spreadsheets',
|
| 2990 |
'https://www.googleapis.com/auth/drive']
|
| 2991 |
creds = ServiceAccountCredentials.from_json_keyfile_name('credentials.json', scope)
|
| 2992 |
-
gspread_client = gspread.authorize(creds)
|
| 2993 |
|
| 2994 |
spreadsheet = gspread_client.open_by_key(BATTERY_SHEET_ID)
|
| 2995 |
|
| 2996 |
-
# Search all sheets for our record to update
|
| 2997 |
for worksheet in spreadsheet.worksheets():
|
| 2998 |
try:
|
| 2999 |
records = worksheet.get_all_records()
|
| 3000 |
-
for i, record in enumerate(records, start=2):
|
| 3001 |
if (str(record.get('Email', '')).lower() == email.lower() and
|
| 3002 |
str(record.get('User Message', '')).strip() == message.strip() and
|
| 3003 |
(not record.get('Bot Message') or str(record.get('Bot Message', '')).strip() == "")):
|
| 3004 |
-
|
| 3005 |
-
# Update the bot response
|
| 3006 |
-
worksheet.update_cell(i, 4, clean_response) # Column D is index 4
|
| 3007 |
break
|
| 3008 |
except Exception as e:
|
| 3009 |
print(f"Error searching sheet {worksheet.title}: {str(e)}")
|
|
@@ -3012,7 +3015,7 @@ def respond(message, history, max_tokens, temperature, top_p):
|
|
| 3012 |
except Exception as e:
|
| 3013 |
print(f"Error updating battery sheet with response: {str(e)}")
|
| 3014 |
|
| 3015 |
-
yield [(message, clean_response)],
|
| 3016 |
|
| 3017 |
except Exception as e:
|
| 3018 |
if "402" in str(e):
|
|
@@ -3022,8 +3025,8 @@ def respond(message, history, max_tokens, temperature, top_p):
|
|
| 3022 |
Please:<br>
|
| 3023 |
1. <a href="https://flutterwave.com/pay/gossapp" target="_blank">Reload AI-time</a><br>
|
| 3024 |
2. Try again later,or<br>
|
| 3025 |
-
3. Contact <a href="https://wa.link/x2wdpl" target="_blank">Support </a> if this persists.
|
| 3026 |
-
Tired of Manual Chatbot reset delays? Consider a Subscription to have your chatbot last upto 20 times longer and fewer/ zero reset delays (Auto-reset)</div>
|
| 3027 |
""")
|
| 3028 |
else:
|
| 3029 |
custom_error = gr.HTML(f"""
|
|
@@ -3316,52 +3319,34 @@ with gr.Blocks(
|
|
| 3316 |
|
| 3317 |
|
| 3318 |
|
| 3319 |
-
|
| 3320 |
-
|
| 3321 |
-
|
| 3322 |
-
|
| 3323 |
-
|
| 3324 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3325 |
show_label=False,
|
| 3326 |
-
|
| 3327 |
-
|
| 3328 |
-
|
| 3329 |
-
|
| 3330 |
-
value=[(None, greeting_html)],
|
| 3331 |
-
height=600,
|
| 3332 |
)
|
| 3333 |
-
|
| 3334 |
-
|
| 3335 |
-
with gr.Column(scale=6):
|
| 3336 |
-
msg = gr.Textbox(
|
| 3337 |
-
show_label=False,
|
| 3338 |
-
placeholder="Let's GossApp! Type or say something...",
|
| 3339 |
-
container=False,
|
| 3340 |
-
autofocus=True
|
| 3341 |
-
)
|
| 3342 |
-
|
| 3343 |
-
with gr.Column(scale=1, min_width=50):
|
| 3344 |
-
voice_btn = gr.Button("🎤", elem_classes="voice-btn")
|
| 3345 |
-
|
| 3346 |
-
submit = gr.Button("", elem_classes="send-btn")
|
| 3347 |
-
|
| 3348 |
-
# Audio output for TTS responses
|
| 3349 |
-
audio_output = gr.Audio(visible=True, label="Chatbot Response", autoplay=True)
|
| 3350 |
-
|
| 3351 |
-
clear = gr.ClearButton([msg, chatbot], variant="secondary")
|
| 3352 |
-
|
| 3353 |
-
with gr.Accordion("🔊 Alternative: Upload Audio", open=False):
|
| 3354 |
-
audio_upload = gr.Audio(
|
| 3355 |
-
sources=["upload"], # Allow file upload
|
| 3356 |
-
type="filepath",
|
| 3357 |
-
label="Or upload an audio file"
|
| 3358 |
-
)
|
| 3359 |
-
|
| 3360 |
-
# Process uploaded audio
|
| 3361 |
-
audio_upload.change(
|
| 3362 |
-
fn=lambda audio: listen_microphone(audio), # Reuse speech-to-text
|
| 3363 |
-
outputs=msg
|
| 3364 |
-
)
|
| 3365 |
|
| 3366 |
# Add Business, Family, Friends chatbots right below the button row
|
| 3367 |
business_html_display = gr.HTML(f"""
|
|
@@ -5347,17 +5332,30 @@ with gr.Blocks(
|
|
| 5347 |
outputs=[save_status, bio_display, chatbot]
|
| 5348 |
)
|
| 5349 |
|
| 5350 |
-
submit
|
|
|
|
| 5351 |
respond,
|
| 5352 |
-
inputs=[msg, chatbot, max_tokens, temperature],
|
| 5353 |
-
outputs=[chatbot, audio_output]
|
| 5354 |
-
).then(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5355 |
|
| 5356 |
-
|
| 5357 |
respond,
|
| 5358 |
-
inputs=[msg, chatbot, max_tokens, temperature],
|
| 5359 |
-
outputs=[chatbot, audio_output]
|
| 5360 |
-
).then(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5361 |
|
| 5362 |
# Add these at the end of your existing event handlers
|
| 5363 |
submit_complaint_btn.click(
|
|
@@ -5372,7 +5370,24 @@ with gr.Blocks(
|
|
| 5372 |
outputs=[status_display]
|
| 5373 |
)
|
| 5374 |
|
| 5375 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5376 |
def generate_certificate(name, email):
|
| 5377 |
"""Generate certificate HTML with centered name on background image"""
|
| 5378 |
|
|
@@ -5415,28 +5430,6 @@ with gr.Blocks(
|
|
| 5415 |
outputs=[cert_display]
|
| 5416 |
)
|
| 5417 |
|
| 5418 |
-
def listen_microphone():
|
| 5419 |
-
r = sr.Recognizer()
|
| 5420 |
-
try:
|
| 5421 |
-
with sr.Microphone() as source:
|
| 5422 |
-
print("Listening...")
|
| 5423 |
-
audio = r.listen(source, timeout=5)
|
| 5424 |
-
user_text = r.recognize_google(audio)
|
| 5425 |
-
return user_text
|
| 5426 |
-
except Exception as e:
|
| 5427 |
-
raise gr.Error(f"Error: {str(e)}. Try typing instead.")
|
| 5428 |
-
|
| 5429 |
-
voice_btn.click(
|
| 5430 |
-
listen_microphone,
|
| 5431 |
-
outputs=[msg]
|
| 5432 |
-
)
|
| 5433 |
-
|
| 5434 |
-
def speak_response(text):
|
| 5435 |
-
with tempfile.NamedTemporaryFile(suffix=".mp3", delete=False) as fp:
|
| 5436 |
-
tts = gTTS(text=text, lang="en")
|
| 5437 |
-
tts.save(fp.name)
|
| 5438 |
-
return fp.name
|
| 5439 |
-
|
| 5440 |
def auto_refresh():
|
| 5441 |
while True:
|
| 5442 |
# Check for inactive accounts once per day
|
|
|
|
| 15 |
from googleapiclient.discovery import build
|
| 16 |
from datetime import datetime
|
| 17 |
from google.oauth2.service_account import Credentials
|
| 18 |
+
from gtts import gTTS
|
|
|
|
| 19 |
import tempfile
|
| 20 |
import base64
|
| 21 |
+
from io import BytesIO
|
|
|
|
|
|
|
| 22 |
|
| 23 |
|
| 24 |
|
|
|
|
| 135 |
SPONSOR = "default" # Set this to the sponsor name or leave as "default" for default branding
|
| 136 |
TRAINER_SHEET_ID = "1GiA8pxZn04aUA-OKwcANvfJ_CpChooF2mUQxiJ_i2-s"
|
| 137 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 138 |
def record_trainer_info(email, client_email, freelancer_email, freelancer_link, seal):
|
| 139 |
"""Record trainer information to Google Sheet"""
|
| 140 |
try:
|
|
|
|
| 2871 |
.progress-bar {
|
| 2872 |
display: none !important;
|
| 2873 |
}
|
| 2874 |
+
"""
|
| 2875 |
+
audio_player_css = """
|
| 2876 |
+
.audio-player-container {
|
| 2877 |
+
display: flex;
|
| 2878 |
+
align-items: center;
|
| 2879 |
+
gap: 5px;
|
| 2880 |
+
margin-left: 5px;
|
|
|
|
|
|
|
| 2881 |
}
|
| 2882 |
+
.audio-player-btn {
|
| 2883 |
+
background: none;
|
| 2884 |
+
border: none;
|
| 2885 |
+
cursor: pointer;
|
| 2886 |
+
font-size: 16px;
|
| 2887 |
+
padding: 5px;
|
| 2888 |
}
|
| 2889 |
+
.audio-player-btn:hover {
|
| 2890 |
+
color: #4CAF50;
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2891 |
}
|
| 2892 |
+
.download-btn {
|
| 2893 |
+
background: none;
|
| 2894 |
+
border: none;
|
| 2895 |
+
cursor: pointer;
|
| 2896 |
+
font-size: 16px;
|
| 2897 |
+
padding: 5px;
|
| 2898 |
+
color: #666;
|
|
|
|
|
|
|
|
|
|
| 2899 |
}
|
| 2900 |
+
.download-btn:hover {
|
| 2901 |
+
color: #4CAF50;
|
| 2902 |
}
|
| 2903 |
+
"""
|
| 2904 |
|
| 2905 |
+
# Add this JavaScript for audio control
|
| 2906 |
+
audio_player_js = """
|
| 2907 |
+
function createAudioPlayer(audioData) {
|
| 2908 |
+
if (!audioData) return '';
|
| 2909 |
+
|
| 2910 |
+
const audioId = 'audio-' + Math.random().toString(36).substr(2, 9);
|
| 2911 |
+
const downloadUrl = 'data:audio/mp3;base64,' + audioData;
|
| 2912 |
+
|
| 2913 |
+
return `
|
| 2914 |
+
<div class="audio-player-container">
|
| 2915 |
+
<audio id="${audioId}" src="${downloadUrl}"></audio>
|
| 2916 |
+
<button class="audio-player-btn" onclick="document.getElementById('${audioId}').play()">▶️</button>
|
| 2917 |
+
<button class="audio-player-btn" onclick="document.getElementById('${audioId}').pause()">⏸️</button>
|
| 2918 |
+
<button class="audio-player-btn" onclick="document.getElementById('${audioId}').currentTime = 0; document.getElementById('${audioId}').pause()">⏹️</button>
|
| 2919 |
+
<a class="download-btn" href="${downloadUrl}" download="response.mp3">💾</a>
|
| 2920 |
+
</div>
|
| 2921 |
+
`;
|
| 2922 |
+
}
|
| 2923 |
"""
|
| 2924 |
+
|
| 2925 |
+
def text_to_speech(text):
|
| 2926 |
+
"""Convert text to speech and return base64 encoded audio"""
|
| 2927 |
+
try:
|
| 2928 |
+
tts = gTTS(text=text, lang='en', slow=False)
|
| 2929 |
+
with tempfile.NamedTemporaryFile(delete=True, suffix='.mp3') as fp:
|
| 2930 |
+
tts.save(fp.name)
|
| 2931 |
+
with open(fp.name, 'rb') as audio_file:
|
| 2932 |
+
audio_bytes = audio_file.read()
|
| 2933 |
+
return base64.b64encode(audio_bytes).decode('utf-8')
|
| 2934 |
+
except Exception as e:
|
| 2935 |
+
print(f"Error in text-to-speech: {str(e)}")
|
| 2936 |
+
return None
|
| 2937 |
+
|
| 2938 |
def respond(message, history, max_tokens, temperature, top_p):
|
| 2939 |
email = OWNER_EMAIL
|
| 2940 |
|
|
|
|
| 2942 |
save_chat_history(email, message, "")
|
| 2943 |
|
| 2944 |
try:
|
| 2945 |
+
# Save to BATTERY_SHEET_ID
|
| 2946 |
sheet = get_or_create_sheet(BATTERY_SHEET_ID, "ChatHistory")
|
|
|
|
| 2947 |
now_str = datetime.now().strftime("%m/%d/%Y %H:%M:%S")
|
| 2948 |
sheet.append_row([now_str, email, message, ""])
|
|
|
|
| 2949 |
except Exception as e:
|
| 2950 |
print(f"Error saving to battery sheet: {str(e)}")
|
| 2951 |
|
|
|
|
| 2953 |
temp_response = f"""<a href="https://flutterwave.com/pay/gossapp" target="_blank">
|
| 2954 |
<img src='https://i.imgur.com/PznT4qo.png' width='20'>
|
| 2955 |
</a>"""
|
| 2956 |
+
yield [(message, temp_response)], None # None for initial audio
|
| 2957 |
|
| 2958 |
try:
|
| 2959 |
# Build prompt
|
|
|
|
| 2962 |
for user_msg, bot_msg in history:
|
| 2963 |
if user_msg:
|
| 2964 |
messages.append({"role": "user", "content": user_msg})
|
| 2965 |
+
if bot_msg and not str(bot_msg).startswith("<img"):
|
| 2966 |
messages.append({"role": "assistant", "content": str(bot_msg)})
|
| 2967 |
messages.append({"role": "user", "content": message})
|
| 2968 |
|
| 2969 |
+
# Get response
|
| 2970 |
inference_client = get_inference_client()
|
|
|
|
| 2971 |
response = ""
|
| 2972 |
for chunk in inference_client.chat_completion(
|
| 2973 |
messages,
|
|
|
|
| 2980 |
if token:
|
| 2981 |
response += token
|
| 2982 |
clean_response = response.split("(Note:")[0].strip()
|
| 2983 |
+
yield [(message, clean_response)], None # No audio during streaming
|
| 2984 |
|
| 2985 |
clean_response = response.split("(Note:")[0].strip()
|
|
|
|
|
|
|
|
|
|
| 2986 |
|
| 2987 |
+
# Generate audio
|
| 2988 |
+
audio_data = text_to_speech(clean_response)
|
| 2989 |
+
|
| 2990 |
+
# Save to chat history
|
| 2991 |
save_chat_history(email, message, clean_response)
|
| 2992 |
|
| 2993 |
+
# Update battery sheet
|
| 2994 |
try:
|
| 2995 |
scope = ['https://www.googleapis.com/auth/spreadsheets',
|
| 2996 |
'https://www.googleapis.com/auth/drive']
|
| 2997 |
creds = ServiceAccountCredentials.from_json_keyfile_name('credentials.json', scope)
|
| 2998 |
+
gspread_client = gspread.authorize(creds)
|
| 2999 |
|
| 3000 |
spreadsheet = gspread_client.open_by_key(BATTERY_SHEET_ID)
|
| 3001 |
|
|
|
|
| 3002 |
for worksheet in spreadsheet.worksheets():
|
| 3003 |
try:
|
| 3004 |
records = worksheet.get_all_records()
|
| 3005 |
+
for i, record in enumerate(records, start=2):
|
| 3006 |
if (str(record.get('Email', '')).lower() == email.lower() and
|
| 3007 |
str(record.get('User Message', '')).strip() == message.strip() and
|
| 3008 |
(not record.get('Bot Message') or str(record.get('Bot Message', '')).strip() == "")):
|
| 3009 |
+
worksheet.update_cell(i, 4, clean_response)
|
|
|
|
|
|
|
| 3010 |
break
|
| 3011 |
except Exception as e:
|
| 3012 |
print(f"Error searching sheet {worksheet.title}: {str(e)}")
|
|
|
|
| 3015 |
except Exception as e:
|
| 3016 |
print(f"Error updating battery sheet with response: {str(e)}")
|
| 3017 |
|
| 3018 |
+
yield [(message, clean_response)], audio_data if audio_data else None
|
| 3019 |
|
| 3020 |
except Exception as e:
|
| 3021 |
if "402" in str(e):
|
|
|
|
| 3025 |
Please:<br>
|
| 3026 |
1. <a href="https://flutterwave.com/pay/gossapp" target="_blank">Reload AI-time</a><br>
|
| 3027 |
2. Try again later,or<br>
|
| 3028 |
+
3. Contact <a href="https://wa.link/x2wdpl" target="_blank">Support </a> if this persists.<br><br>
|
| 3029 |
+
Tired of Manual Chatbot reset delays? <br>Consider a Subscription to have your chatbot last upto 20 times longer and fewer/ zero reset delays (Auto-reset)</div>
|
| 3030 |
""")
|
| 3031 |
else:
|
| 3032 |
custom_error = gr.HTML(f"""
|
|
|
|
| 3319 |
|
| 3320 |
|
| 3321 |
|
| 3322 |
+
with gr.Column(scale=3, elem_classes="chat-container"):
|
| 3323 |
+
# Create the HTML component separately
|
| 3324 |
+
greeting_html = gr.HTML(get_chatbot_greeting())
|
| 3325 |
+
|
| 3326 |
+
chatbot = gr.Chatbot(
|
| 3327 |
+
elem_id="chatbot",
|
| 3328 |
+
show_label=False,
|
| 3329 |
+
avatar_images=(None, user_data['avatar_url']),
|
| 3330 |
+
show_copy_button=False,
|
| 3331 |
+
show_share_button=False,
|
| 3332 |
+
layout="panel",
|
| 3333 |
+
value=[(None, greeting_html)],
|
| 3334 |
+
height=600,
|
| 3335 |
+
# Add these to ensure proper centering in the container
|
| 3336 |
+
elem_classes=["centered-chatbot"]
|
| 3337 |
+
)
|
| 3338 |
+
|
| 3339 |
+
# Replace the existing button row and clear button code with this:
|
| 3340 |
+
with gr.Row():
|
| 3341 |
+
msg = gr.Textbox(
|
| 3342 |
show_label=False,
|
| 3343 |
+
placeholder="Let's GossApp...",
|
| 3344 |
+
container=False,
|
| 3345 |
+
autofocus=True,
|
| 3346 |
+
scale=6
|
|
|
|
|
|
|
| 3347 |
)
|
| 3348 |
+
submit = gr.Button("", elem_classes="send-btn")
|
| 3349 |
+
audio_output = gr.HTML(visible=False)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3350 |
|
| 3351 |
# Add Business, Family, Friends chatbots right below the button row
|
| 3352 |
business_html_display = gr.HTML(f"""
|
|
|
|
| 5332 |
outputs=[save_status, bio_display, chatbot]
|
| 5333 |
)
|
| 5334 |
|
| 5335 |
+
# Update your submit/msg handlers
|
| 5336 |
+
msg.submit(
|
| 5337 |
respond,
|
| 5338 |
+
inputs=[msg, chatbot, max_tokens, temperature, top_p],
|
| 5339 |
+
outputs=[chatbot, audio_output]
|
| 5340 |
+
).then(
|
| 5341 |
+
lambda: gr.HTML(visible=True),
|
| 5342 |
+
outputs=[audio_output]
|
| 5343 |
+
).then(
|
| 5344 |
+
clear_input,
|
| 5345 |
+
outputs=[msg]
|
| 5346 |
+
)
|
| 5347 |
|
| 5348 |
+
submit.click(
|
| 5349 |
respond,
|
| 5350 |
+
inputs=[msg, chatbot, max_tokens, temperature, top_p],
|
| 5351 |
+
outputs=[chatbot, audio_output]
|
| 5352 |
+
).then(
|
| 5353 |
+
lambda: gr.HTML(visible=True),
|
| 5354 |
+
outputs=[audio_output]
|
| 5355 |
+
).then(
|
| 5356 |
+
clear_input,
|
| 5357 |
+
outputs=[msg]
|
| 5358 |
+
)
|
| 5359 |
|
| 5360 |
# Add these at the end of your existing event handlers
|
| 5361 |
submit_complaint_btn.click(
|
|
|
|
| 5370 |
outputs=[status_display]
|
| 5371 |
)
|
| 5372 |
|
| 5373 |
+
# Add the audio player update function
|
| 5374 |
+
def update_audio_player(audio_data):
|
| 5375 |
+
if audio_data:
|
| 5376 |
+
return f"""
|
| 5377 |
+
<script>
|
| 5378 |
+
{audio_player_js}
|
| 5379 |
+
document.currentScript.parentNode.innerHTML = createAudioPlayer('{audio_data}');
|
| 5380 |
+
</script>
|
| 5381 |
+
"""
|
| 5382 |
+
return ""
|
| 5383 |
+
|
| 5384 |
+
audio_output.change(
|
| 5385 |
+
update_audio_player,
|
| 5386 |
+
inputs=[audio_output],
|
| 5387 |
+
outputs=[audio_output]
|
| 5388 |
+
)
|
| 5389 |
+
|
| 5390 |
+
# Certificate generation
|
| 5391 |
def generate_certificate(name, email):
|
| 5392 |
"""Generate certificate HTML with centered name on background image"""
|
| 5393 |
|
|
|
|
| 5430 |
outputs=[cert_display]
|
| 5431 |
)
|
| 5432 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5433 |
def auto_refresh():
|
| 5434 |
while True:
|
| 5435 |
# Check for inactive accounts once per day
|