Spaces:
Sleeping
Sleeping
import gradio as gr | |
import pandas as pd | |
from database import Database | |
from voice_handler import VoiceHandler | |
from gemini_processor import GeminiProcessor | |
from memory_handler import MemoryHandler | |
from gtts import gTTS | |
import io | |
import os | |
from dotenv import load_dotenv | |
load_dotenv() | |
# Initialize components | |
db = Database() | |
voice_handler = VoiceHandler() | |
gemini_processor = GeminiProcessor() | |
memory_handler = MemoryHandler() | |
def validate_request(project_number, project_name, amount, reason): | |
if not project_number or not project_name or not amount or not reason: | |
missing_fields = [] | |
if not project_number: missing_fields.append("project number") | |
if not project_name: missing_fields.append("project name") | |
if not amount: missing_fields.append("amount") | |
if not reason: missing_fields.append("reason") | |
return False, f"Please provide: {', '.join(missing_fields)}" | |
return True, "" | |
def process_text_input(text, language): | |
if not text: | |
return "Please enter some text first.", None, None, None, None | |
context = memory_handler.get_context() | |
details = gemini_processor.extract_request_details(text, context) | |
if not details: | |
return "Could not extract request details. Please try again.", None, None, None, None | |
memory_handler.add_interaction(text, details) | |
# Get any previously captured information | |
partial_info = memory_handler.get_partial_info() | |
return ( | |
f"Text processed! {memory_handler.get_prompt_for_missing_info()}", | |
partial_info.get('project_number', ''), | |
partial_info.get('project_name', ''), | |
partial_info.get('amount', 0), | |
partial_info.get('reason', '') | |
) | |
def process_voice_input(audio_path, language): | |
if not audio_path: | |
return "No audio detected.", None, None, None, None | |
voice_text = voice_handler.process_audio_file(audio_path, language) | |
if voice_text.startswith("Error:"): | |
return voice_text, None, None, None, None | |
context = memory_handler.get_context() | |
details = gemini_processor.extract_request_details(voice_text, context) | |
if not details: | |
return "Could not extract request details. Please try again.", None, None, None, None | |
memory_handler.add_interaction(voice_text, details) | |
# Get any previously captured information | |
partial_info = memory_handler.get_partial_info() | |
return ( | |
f"Voice processed! You said: {voice_text}\n\n{memory_handler.get_prompt_for_missing_info()}", | |
partial_info.get('project_number', ''), | |
partial_info.get('project_name', ''), | |
partial_info.get('amount', 0), | |
partial_info.get('reason', '') | |
) | |
def submit_request(project_number, project_name, amount, reason): | |
is_valid, message = validate_request(project_number, project_name, amount, reason) | |
if not is_valid: | |
return message, None | |
try: | |
db.add_request(project_number, project_name, float(amount), reason) | |
memory_handler.clear_memory() | |
return "Request successfully added!", get_requests_df() | |
except Exception as e: | |
return f"Error saving request: {str(e)}", None | |
def get_requests_df(): | |
try: | |
requests = db.get_all_requests() | |
if requests: | |
df = pd.DataFrame(requests) | |
columns = ['timestamp', 'project_number', 'project_name', 'amount', 'reason'] | |
df = df[columns] | |
# Convert DataFrame to list of lists format required by Gradio | |
headers = df.columns.tolist() | |
data = df.values.tolist() | |
return {"headers": headers, "data": data} | |
return {"headers": ['timestamp', 'project_number', 'project_name', 'amount', 'reason'], "data": []} | |
except Exception as e: | |
print(f"Error getting requests: {str(e)}") | |
return {"headers": ['timestamp', 'project_number', 'project_name', 'amount', 'reason'], "data": []} | |
def create_ui(): | |
with gr.Blocks(title="AI Agent Money Request System") as app: | |
gr.Markdown("# AI Agent Money Request System") | |
with gr.Tab("Input"): | |
language = gr.Dropdown( | |
choices=["English", "Arabic", "Mixed (Arabic/English)"], | |
value="English", | |
label="Select Language" | |
) | |
with gr.Tab("Voice Input"): | |
audio_input = gr.Audio( | |
label="Voice Input", | |
type="filepath", | |
sources=["microphone"] | |
) | |
voice_process_btn = gr.Button("Process Voice") | |
with gr.Tab("Text Input"): | |
text_input = gr.Textbox( | |
lines=3, | |
placeholder="Enter your request here...", | |
label="Text Input" | |
) | |
text_process_btn = gr.Button("Process Text") | |
process_output = gr.Textbox(label="Processing Result") | |
with gr.Group(): | |
project_number = gr.Textbox(label="Project Number") | |
project_name = gr.Textbox(label="Project Name") | |
amount = gr.Number(label="Amount (in riyals)") | |
reason = gr.Textbox(label="Reason for Request") | |
submit_btn = gr.Button("Submit Request") | |
result_text = gr.Textbox(label="Submission Result") | |
with gr.Tab("Existing Requests"): | |
requests_table = gr.DataFrame( | |
headers=["Timestamp", "Project Number", "Project Name", "Amount", "Reason"], | |
label="Existing Requests" | |
) | |
refresh_btn = gr.Button("Refresh") | |
# Event handlers | |
text_process_btn.click( | |
process_text_input, | |
inputs=[text_input, language], | |
outputs=[process_output, project_number, project_name, amount, reason] | |
) | |
voice_process_btn.click( | |
process_voice_input, | |
inputs=[audio_input, language], | |
outputs=[process_output, project_number, project_name, amount, reason] | |
) | |
submit_btn.click( | |
submit_request, | |
inputs=[project_number, project_name, amount, reason], | |
outputs=[result_text, requests_table] | |
) | |
refresh_btn.click( | |
lambda: get_requests_df(), | |
outputs=[requests_table] | |
) | |
# Initialize requests table | |
requests_table.value = get_requests_df() | |
return app | |
if __name__ == "__main__": | |
app = create_ui() | |
app.launch() |