jjmandog's picture
Update app.py
e5d8b01 verified
import os
import gradio as gr
from datetime import datetime
from threading import Lock
import requests
import logging
# Simple configuration
BUSINESS_NAME = "Jay's Mobile Wash"
JAY_PHONE = os.environ.get('JAY_PHONE_NUMBER', '+15622289429')
AI_PHONE = os.environ.get('AI_PHONE_NUMBER', '+17149278841')
DEEPSEEK_KEY = os.environ.get('DEEPSEEK_API_KEY', '')
# Simple state management
class SimpleState:
def __init__(self):
self.lock = Lock()
self.data = {
'calls': 0, 'sms': 0, 'ai_responses': 0,
'start_time': datetime.now(), 'log': []
}
def increment(self, key):
with self.lock:
self.data[key] += 1
def add_log(self, entry):
with self.lock:
self.data['log'].insert(0, entry)
if len(self.data['log']) > 20:
self.data['log'] = self.data['log'][:20]
def get_all(self):
with self.lock:
return self.data.copy()
state = SimpleState()
# Simple AI
class SimpleAI:
def detect_intent(self, text):
text = text.lower()
if any(word in text for word in ['price', 'cost', 'much']):
return 'pricing'
elif any(word in text for word in ['book', 'schedule', 'appointment']):
return 'booking'
elif any(word in text for word in ['urgent', 'emergency']):
return 'urgent'
elif any(word in text for word in ['jay', 'human', 'person']):
return 'human'
return 'general'
def generate_response(self, text, forwarded=False):
intent = self.detect_intent(text)
prefix = "Thanks for your patience. " if forwarded else ""
responses = {
'pricing': f"{prefix}Our services: Basic wash $25, Premium $45, Full detail $85. Which interests you?",
'booking': f"{prefix}We're available Mon-Sat 8AM-6PM, Sun 10AM-4PM. What day works for you?",
'urgent': f"{prefix}I understand this is urgent. Let me connect you with Jay right away.",
'human': f"{prefix}Let me connect you with Jay personally.",
'general': f"{prefix}Hi! I'm Jay's AI assistant. I can help with pricing, scheduling, or questions about our mobile car wash services."
}
response = responses.get(intent, responses['general'])
# Try DeepSeek if available
if DEEPSEEK_KEY and intent not in ['urgent', 'human']:
try:
enhanced = self.get_deepseek_response(text)
if enhanced:
response = enhanced
except:
pass
return response
def get_deepseek_response(self, prompt):
try:
headers = {"Authorization": f"Bearer {DEEPSEEK_KEY}", "Content-Type": "application/json"}
data = {
"model": "deepseek-chat",
"messages": [
{"role": "system", "content": f"You are {BUSINESS_NAME} AI assistant. Be friendly and professional. Services: Basic wash ($25), Premium ($45), Full detail ($85), Ceramic coating ($150). Hours: Mon-Sat 8AM-6PM, Sun 10AM-4PM. Phone: {JAY_PHONE}"},
{"role": "user", "content": prompt}
],
"max_tokens": 150
}
response = requests.post("https://api.deepseek.com/v1/chat/completions",
headers=headers, json=data, timeout=10)
if response.status_code == 200:
return response.json()['choices'][0]['message']['content'].strip()
except:
pass
return None
ai = SimpleAI()
# Dashboard function
def get_dashboard():
stats = state.get_all()
uptime = datetime.now() - stats['start_time']
return f"""
<div style="font-family: Arial; padding: 20px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border-radius: 15px; color: white;">
<h1 style="text-align: center;">๐Ÿš— {BUSINESS_NAME} - AI Dashboard</h1>
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 15px; margin: 20px 0;">
<div style="background: rgba(255,255,255,0.15); padding: 15px; border-radius: 10px; text-align: center;">
<h2 style="color: #4facfe; font-size: 2em; margin: 0;">{stats['calls']}</h2>
<p style="margin: 5px 0;">๐Ÿ“ž Calls</p>
</div>
<div style="background: rgba(255,255,255,0.15); padding: 15px; border-radius: 10px; text-align: center;">
<h2 style="color: #4facfe; font-size: 2em; margin: 0;">{stats['sms']}</h2>
<p style="margin: 5px 0;">๐Ÿ“ฑ SMS</p>
</div>
<div style="background: rgba(255,255,255,0.15); padding: 15px; border-radius: 10px; text-align: center;">
<h2 style="color: #4facfe; font-size: 2em; margin: 0;">{stats['ai_responses']}</h2>
<p style="margin: 5px 0;">๐Ÿค– AI Responses</p>
</div>
</div>
<div style="background: rgba(255,255,255,0.1); padding: 15px; border-radius: 10px; margin: 20px 0;">
<h3 style="color: #4facfe;">๐Ÿ“ž iPhone Forwarding Status</h3>
<p><strong>Jay's iPhone:</strong> {JAY_PHONE}</p>
<p><strong>AI Number:</strong> {AI_PHONE}</p>
<p><strong>DeepSeek AI:</strong> {'โœ… Connected' if DEEPSEEK_KEY else 'โš ๏ธ Not configured'}</p>
<p><strong>Uptime:</strong> {int(uptime.total_seconds() / 3600)} hours</p>
</div>
<div style="background: rgba(255,255,255,0.1); padding: 15px; border-radius: 10px;">
<h3 style="color: #4facfe;">๐Ÿ’ผ Services</h3>
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 10px;">
<div style="background: rgba(79,172,254,0.2); padding: 10px; border-radius: 8px; text-align: center;">
<h4 style="margin: 0; color: white;">Basic Wash</h4>
<p style="margin: 5px 0; color: #00ff88; font-size: 1.2em;">$25</p>
</div>
<div style="background: rgba(79,172,254,0.2); padding: 10px; border-radius: 8px; text-align: center;">
<h4 style="margin: 0; color: white;">Premium</h4>
<p style="margin: 5px 0; color: #00ff88; font-size: 1.2em;">$45</p>
</div>
<div style="background: rgba(79,172,254,0.2); padding: 10px; border-radius: 8px; text-align: center;">
<h4 style="margin: 0; color: white;">Full Detail</h4>
<p style="margin: 5px 0; color: #00ff88; font-size: 1.2em;">$85</p>
</div>
<div style="background: rgba(79,172,254,0.2); padding: 10px; border-radius: 8px; text-align: center;">
<h4 style="margin: 0; color: white;">Ceramic</h4>
<p style="margin: 5px 0; color: #00ff88; font-size: 1.2em;">$150</p>
</div>
</div>
</div>
</div>
"""
# Test AI function
def test_ai(message):
if not message.strip():
return "Please enter a message to test."
try:
intent = ai.detect_intent(message)
response = ai.generate_response(message)
state.increment('ai_responses')
return f"""
<div style="font-family: Arial; padding: 15px; background: #f9f9f9; border-radius: 10px;">
<h3>๐Ÿค– AI Response Test</h3>
<p><strong>Your Message:</strong> {message}</p>
<p><strong>Detected Intent:</strong> {intent}</p>
<div style="background: #e3f2fd; padding: 10px; border-radius: 5px; margin-top: 10px;">
<strong>AI Response:</strong><br>{response}
</div>
</div>
"""
except Exception as e:
return f"Error: {e}"
# Simulate functions
def simulate_call(phone, forwarded):
entry = {
'time': datetime.now().strftime('%H:%M:%S'),
'type': 'Call',
'from': phone or '+1555123456',
'forwarded': forwarded
}
state.add_log(entry)
state.increment('calls')
return f"โœ… Simulated {'forwarded' if forwarded else 'direct'} call from {entry['from']}"
def simulate_sms(phone, message):
if not message.strip():
return "Please enter a message."
# Log incoming SMS
entry = {
'time': datetime.now().strftime('%H:%M:%S'),
'type': 'SMS',
'from': phone or '+1555123456',
'message': message
}
state.add_log(entry)
state.increment('sms')
# Generate AI response
response = ai.generate_response(message)
state.increment('ai_responses')
# Log AI response
response_entry = {
'time': datetime.now().strftime('%H:%M:%S'),
'type': 'AI Response',
'from': 'AI Assistant',
'message': response
}
state.add_log(response_entry)
return f"โœ… SMS processed!\n\n**Customer:** {message}\n\n**AI Response:** {response}"
# Activity log
def get_activity():
stats = state.get_all()
log = stats.get('log', [])
if not log:
return "No activity yet. Try the demo!"
html = "<div style='font-family: Arial;'><h3>๐Ÿ“‹ Recent Activity</h3>"
for entry in log[:10]:
color = "#4facfe" if entry['type'] == 'Call' else "#00ff88" if entry['type'] == 'SMS' else "#ff6b6b"
html += f"""
<div style="background: #f5f5f5; padding: 10px; margin: 5px 0; border-radius: 5px; border-left: 4px solid {color};">
<strong>{entry['time']}</strong> | {entry['type']} | {entry['from']}<br>
{entry.get('message', entry.get('forwarded', ''))}
</div>
"""
html += "</div>"
return html
# Create Gradio interface
with gr.Blocks(title=f"{BUSINESS_NAME} - AI Dashboard", theme=gr.themes.Soft()) as demo:
gr.Markdown(f"""
# ๐Ÿš— {BUSINESS_NAME} - iPhone Forwarding AI System
**Jay's iPhone:** {JAY_PHONE} โ†’ **AI Assistant:** {AI_PHONE}
""")
with gr.Tabs():
with gr.Tab("๐Ÿ“Š Dashboard"):
dashboard = gr.HTML(value=get_dashboard())
gr.Button("๐Ÿ”„ Refresh").click(fn=get_dashboard, outputs=dashboard)
with gr.Tab("๐Ÿงช Test AI"):
with gr.Row():
with gr.Column():
test_input = gr.Textbox(label="Test Message", placeholder="How much for a car wash?", lines=2)
test_btn = gr.Button("๐Ÿค– Test AI", variant="primary")
with gr.Column():
test_output = gr.HTML()
test_btn.click(fn=test_ai, inputs=test_input, outputs=test_output)
with gr.Tab("๐ŸŽฎ Demo"):
with gr.Row():
with gr.Column():
gr.Markdown("#### ๐Ÿ“ž Simulate Call")
call_phone = gr.Textbox(label="Phone", value="+1555123456")
call_forwarded = gr.Checkbox(label="Forwarded Call", value=True)
call_btn = gr.Button("๐Ÿ“ž Simulate")
call_result = gr.Textbox(label