File size: 9,574 Bytes
5b532b5
de01ccf
5b532b5
 
 
 
56a5b15
5b532b5
 
 
 
 
 
 
 
 
 
 
 
 
 
56a5b15
5b532b5
 
 
 
 
 
 
 
 
 
56a5b15
 
 
5b532b5
d7bd3d3
 
 
5b532b5
d7bd3d3
 
 
 
 
 
 
 
 
 
 
 
 
 
5b532b5
 
56a5b15
5b532b5
 
 
 
 
 
 
 
 
 
 
 
 
 
56a5b15
 
 
5b532b5
56a5b15
de01ccf
5b532b5
 
 
 
56a5b15
5b532b5
56a5b15
 
 
5b532b5
 
 
 
 
56a5b15
de01ccf
5b532b5
 
 
 
 
 
 
 
de01ccf
56a5b15
 
 
de01ccf
5b532b5
 
 
de01ccf
5b532b5
 
 
 
 
 
de01ccf
5b532b5
 
 
 
 
56a5b15
d7bd3d3
56a5b15
 
 
 
d7bd3d3
56a5b15
 
 
 
5b532b5
d7bd3d3
56a5b15
d7bd3d3
 
 
 
56a5b15
 
de01ccf
5b532b5
 
 
 
 
d7bd3d3
5b532b5
 
 
 
de01ccf
5b532b5
56a5b15
 
5b532b5
de01ccf
5b532b5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
de01ccf
5b532b5
 
 
de01ccf
5b532b5
 
 
 
 
 
 
 
 
 
 
 
 
 
de01ccf
5b532b5
 
de01ccf
5b532b5
 
 
 
 
de01ccf
5b532b5
 
 
 
d7bd3d3
5b532b5
 
 
 
d7bd3d3
 
 
 
 
 
 
 
 
5b532b5
56a5b15
d7bd3d3
5b532b5
 
 
 
d7bd3d3
 
 
 
 
 
 
 
 
 
de01ccf
d7bd3d3
5b532b5
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
import gradio as gr
import os
import tempfile
import requests
from pathlib import Path

# Create necessary directories
DOCUMENTS_DIR = Path("documents")
DOCUMENTS_DIR.mkdir(exist_ok=True)

# Define possible intents
POSSIBLE_INTENTS = [
    "product_inquiry", 
    "technical_support", 
    "billing_question", 
    "general_information",
    "appointment_scheduling",
    "complaint",
    "other"
]

# Default responses
DEFAULT_RESPONSES = {
    "product_inquiry": "Thank you for your interest in our products. I'll gather the information and have someone contact you with more details.",
    "technical_support": "I understand you're experiencing technical issues. Let me find the right person to help you resolve this.",
    "billing_question": "Thank you for your billing inquiry. I'll connect you with our billing department for assistance.",
    "general_information": "Thank you for reaching out. I'll make sure you get the information you need.",
    "appointment_scheduling": "I'd be happy to help schedule an appointment for you. Let me find the next available slot.",
    "complaint": "I'm sorry to hear about your experience. Your feedback is important to us, and we'll address this promptly.",
    "other": "Thank you for your call. I'll make sure your message gets to the right person."
}

# Simple document storage (in-memory for this example)
knowledge_base = []

def classify_intent(text):
    """Simple keyword-based intent classification"""
    if not text:
        return "other", 0.6
        
    text = text.lower()
    
    if any(word in text for word in ["buy", "purchase", "product", "price", "cost"]):
        return "product_inquiry", 0.8
    elif any(word in text for word in ["help", "issue", "problem", "fix", "broken"]):
        return "technical_support", 0.8
    elif any(word in text for word in ["bill", "payment", "charge", "invoice"]):
        return "billing_question", 0.8
    elif any(word in text for word in ["appointment", "schedule", "book", "meeting"]):
        return "appointment_scheduling", 0.8
    elif any(word in text for word in ["unhappy", "disappointed", "complaint", "bad"]):
        return "complaint", 0.8
    else:
        return "general_information", 0.6

def load_pdf(file):
    """Load a PDF document into the knowledge base"""
    try:
        # Save the uploaded file temporarily
        temp_dir = tempfile.mkdtemp()
        temp_path = os.path.join(temp_dir, file.name)
        
        with open(temp_path, "wb") as f:
            f.write(file.read())
        
        # Save a copy to the documents directory
        target_path = os.path.join(DOCUMENTS_DIR, file.name)
        with open(target_path, "wb") as f:
            with open(temp_path, "rb") as src:
                f.write(src.read())
        
        # In a real implementation, we would extract text and add to vector store
        # For this simplified version, we'll just store the file name
        knowledge_base.append({"type": "pdf", "name": file.name, "path": target_path})
        
        return f"Successfully added {file.name} to the knowledge base."
    
    except Exception as e:
        return f"Error processing PDF: {str(e)}"

def load_website(url):
    """Load a website into the knowledge base"""
    try:
        # In a real implementation, we would fetch and process the website
        # For this simplified version, we'll just store the URL
        knowledge_base.append({"type": "website", "url": url})
        
        # Save the URL reference
        with open(os.path.join(DOCUMENTS_DIR, "websites.txt"), "a") as f:
            f.write(f"{url}\n")
        
        return f"Successfully added {url} to the knowledge base."
    
    except Exception as e:
        return f"Error processing website: {str(e)}"

def generate_response(query, intent=None):
    """Generate a response based on the query and intent"""
    # If no intent provided, use a default
    if not intent or intent not in POSSIBLE_INTENTS:
        intent = "general_information"
    
    # For this simplified version, we'll just use the default responses
    # In a real implementation, we would search the knowledge base
    return DEFAULT_RESPONSES.get(intent, DEFAULT_RESPONSES["other"])

def list_documents():
    """List all documents in the knowledge base"""
    files = list(DOCUMENTS_DIR.glob("*.pdf"))
    
    # Add websites if available
    website_file = DOCUMENTS_DIR / "websites.txt"
    websites = []
    if website_file.exists():
        with open(website_file, "r") as f:
            websites = [line.strip() for line in f if line.strip()]
    
    return {
        "PDFs": [f.name for f in files],
        "Websites": websites
    }

# Twilio voice handlers
def twilio_call_handler(data=None):
    """Handle incoming Twilio calls"""
    twiml = """<?xml version="1.0" encoding="UTF-8"?>
    <Response>
        <Say>Hello! Thank you for calling. How can I help you today?</Say>
        <Gather input="speech" action="https://huggingface.co/spaces/iajitpanday/vBot-1.5/api/predict" method="POST" speechTimeout="auto" speechModel="phone_call"/>
        <Say>I didn't hear anything. Please call back when you're ready.</Say>
    </Response>
    """
    return twiml

def twilio_speech_handler(data):
    """Process speech from Twilio"""
    # Extract speech from Twilio request
    speech_result = data.get("SpeechResult", "")
    
    # Process the speech
    intent, _ = classify_intent(speech_result)
    response = generate_response(speech_result, intent)
    
    twiml = f"""<?xml version="1.0" encoding="UTF-8"?>
    <Response>
        <Say>{response}</Say>
        <Pause length="1"/>
        <Say>Is there anything else I can help you with today?</Say>
        <Gather input="speech" action="https://huggingface.co/spaces/iajitpanday/vBot-1.5/api/predict" method="POST" speechTimeout="auto" speechModel="phone_call"/>
        <Say>Thank you for calling. Have a great day!</Say>
    </Response>
    """
    return twiml

# Create Gradio interface
with gr.Blocks(title="Call Assistant System") as demo:
    gr.Markdown("# Call Assistant System")
    gr.Markdown("Add documents and websites to the knowledge base, and test the response generation.")
    
    with gr.Tab("Add Knowledge"):
        with gr.Row():
            with gr.Column():
                pdf_input = gr.File(label="Upload PDF Document")
                pdf_button = gr.Button("Add PDF to Knowledge Base")
                pdf_output = gr.Textbox(label="PDF Upload Status")
                
                pdf_button.click(
                    load_pdf,
                    inputs=[pdf_input],
                    outputs=[pdf_output]
                )
            
            with gr.Column():
                url_input = gr.Textbox(label="Website URL")
                url_button = gr.Button("Add Website to Knowledge Base")
                url_output = gr.Textbox(label="Website Status")
                
                url_button.click(
                    load_website,
                    inputs=[url_input],
                    outputs=[url_output]
                )
    
    with gr.Tab("Knowledge Base"):
        list_button = gr.Button("List Documents in Knowledge Base")
        knowledge_output = gr.JSON(label="Documents")
        
        list_button.click(
            list_documents,
            inputs=[],
            outputs=[knowledge_output]
        )
    
    with gr.Tab("Test Response Generation"):
        with gr.Row():
            query_input = gr.Textbox(label="Query / Transcription")
            intent_input = gr.Dropdown(
                choices=POSSIBLE_INTENTS,
                label="Intent",
                value="general_information"
            )
        
        test_button = gr.Button("Generate Response")
        response_output = gr.Textbox(label="Generated Response")
        
        test_button.click(
            generate_response,
            inputs=[query_input, intent_input],
            outputs=[response_output]
        )
    
    with gr.Tab("Twilio Integration"):
        gr.Markdown("""
        ## Twilio Integration Instructions
        
        This app provides an API endpoint for Twilio voice integration. Follow these steps to set up:
        
        1. Log into your Twilio account
        2. Go to Phone Numbers → Manage → Active numbers
        3. Select your number (+19704064410)
        4. For "A Call Comes In", create a TwiML bin with:
           ```xml
           <?xml version="1.0" encoding="UTF-8"?>
           <Response>
               <Say>Hello! Thank you for calling. How can I help you today?</Say>
               <Gather input="speech" action="https://huggingface.co/spaces/iajitpanday/vBot-1.5/api/predict" method="POST" speechTimeout="auto" speechModel="phone_call"/>
               <Say>I didn't hear anything. Please call back when you're ready.</Say>
           </Response>
           ```
        
        The system will:
        - Process speech input through the /api/predict endpoint
        - Generate responses using your knowledge base
        - Handle follow-up questions
        """)

# Define API prediction function for Twilio
def predict_api(data):
    """API endpoint for Twilio integration"""
    # Check if this is a speech result from Twilio
    if isinstance(data, dict) and "SpeechResult" in data:
        return twilio_speech_handler(data)
    
    # If it's a call initial request or other Twilio request
    # Just return the call handler response
    return twilio_call_handler(data)

# Launch the interface with API
demo.queue()
demo.launch()