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()