Spaces:
Build error
Build error
| import os | |
| import sys | |
| import importlib.util | |
| BASE_DIR = os.path.dirname(os.path.abspath(__file__)) | |
| # Add structural paths for submodules | |
| if BASE_DIR not in sys.path: | |
| sys.path.insert(0, BASE_DIR) | |
| JOB_FINDER_DIR = os.path.join(BASE_DIR, "Job Finder") | |
| LEAD_AGENT_DIR = os.path.join(BASE_DIR, "Lead Agent") | |
| if JOB_FINDER_DIR not in sys.path: | |
| sys.path.insert(0, JOB_FINDER_DIR) | |
| if LEAD_AGENT_DIR not in sys.path: | |
| sys.path.insert(0, LEAD_AGENT_DIR) | |
| import gradio as gr | |
| from agent import generate_report | |
| # Dynamic loader helper | |
| def load_module_from_path(name, path): | |
| spec = importlib.util.spec_from_file_location(name, path) | |
| module = importlib.util.module_from_spec(spec) | |
| spec.loader.exec_module(module) | |
| return module | |
| # Lazy module caches: each tab can fail independently without crashing the whole app. | |
| job_fetcher = None | |
| job_formatter = None | |
| job_cover_letter = None | |
| lead_crew = None | |
| def ensure_job_modules_loaded(): | |
| global job_fetcher, job_formatter, job_cover_letter | |
| if job_fetcher and job_formatter and job_cover_letter: | |
| return | |
| job_fetcher = load_module_from_path("job_fetcher", os.path.join(JOB_FINDER_DIR, "fetcher.py")) | |
| job_formatter = load_module_from_path("job_formatter", os.path.join(JOB_FINDER_DIR, "formatter.py")) | |
| job_cover_letter = load_module_from_path("job_cover_letter", os.path.join(JOB_FINDER_DIR, "cover_letter.py")) | |
| def ensure_lead_module_loaded(): | |
| global lead_crew | |
| if lead_crew: | |
| return | |
| lead_crew = load_module_from_path("lead_crew", os.path.join(LEAD_AGENT_DIR, "crew.py")) | |
| # Job Finder state | |
| job_store = [] | |
| def search_jobs_wrapper(job_title): | |
| global job_store | |
| if not job_title or not job_title.strip(): | |
| return "Please enter a job title." | |
| try: | |
| ensure_job_modules_loaded() | |
| jobs = job_fetcher.fetch_jobs(job_title) | |
| except Exception as e: | |
| return f"Job Finder failed to load: {e}" | |
| job_store = jobs | |
| if not jobs: | |
| return "No jobs found. Try a broader search term." | |
| try: | |
| return job_formatter.format_jobs(jobs, job_title, "") | |
| except Exception as e: | |
| return f"Job formatting failed: {e}" | |
| def search_jobs_with_status(job_title): | |
| return search_jobs_wrapper(job_title), "Completed" | |
| def create_cover_letter_wrapper(job_number, cv_file): | |
| global job_store | |
| try: | |
| ensure_job_modules_loaded() | |
| except Exception as e: | |
| return f"Job Finder failed to load: {e}" | |
| if cv_file is None: | |
| return "Please upload your CV first." | |
| cv_text = "" | |
| try: | |
| import pdfplumber | |
| with pdfplumber.open(cv_file.name) as pdf: | |
| for page in pdf.pages: | |
| cv_text += page.extract_text() or "" | |
| except Exception as e: | |
| return f"Could not read CV: {e}" | |
| if not job_store: | |
| return "Please search for jobs first." | |
| try: | |
| index = int(job_number) - 1 | |
| job = job_store[index] | |
| except Exception: | |
| return "Invalid job number. Please enter a number from the job results." | |
| try: | |
| return job_cover_letter.generate_cover_letter( | |
| job["title"], job["company"], job["description"], cv_text | |
| ) | |
| except Exception as e: | |
| return f"Cover letter generation failed: {e}" | |
| def create_cover_letter_with_status(job_number, cv_file): | |
| return create_cover_letter_wrapper(job_number, cv_file), "Completed" | |
| def generate_report_with_status(topic): | |
| if not topic or not topic.strip(): | |
| return "Please enter a topic.", "Idle" | |
| try: | |
| return generate_report(topic), "Completed" | |
| except Exception as e: | |
| return f"Research agent failed: {e}", "Failed" | |
| def generate_leads_wrapper(target_audience, service, sender_name): | |
| if not target_audience or not service or not sender_name: | |
| return "Please fill in all fields.", "Idle" | |
| try: | |
| ensure_lead_module_loaded() | |
| result = lead_crew.run_lead_gen(target_audience, service, sender_name) | |
| return result, "Completed" | |
| except Exception as e: | |
| return f"Lead Agent failed: {e}", "Failed" | |
| with gr.Blocks(title="AI All-in-One Agents") as ui: | |
| gr.Markdown("# AI All-in-One Agents\nUse the tabs to switch between Research, Job Finder, and Lead Gen agents.") | |
| with gr.Tab("Research & Report"): | |
| topic_input = gr.Textbox(label="Topic", placeholder="Enter research topic...", lines=1) | |
| topic_btn = gr.Button("Generate Report") | |
| topic_output = gr.Markdown() | |
| topic_status = gr.Textbox(label="Status", interactive=False, value="Idle") | |
| topic_btn.click( | |
| fn=generate_report_with_status, | |
| inputs=[topic_input], | |
| outputs=[topic_output, topic_status], | |
| show_progress=True, | |
| ) | |
| with gr.Tab("Job Finder"): | |
| job_input = gr.Textbox(label="Job title", placeholder="e.g. Python Developer") | |
| job_btn = gr.Button("Find Jobs") | |
| jobs_output = gr.Markdown() | |
| jobs_status = gr.Textbox(label="Status", interactive=False, value="Idle") | |
| job_btn.click( | |
| fn=search_jobs_with_status, | |
| inputs=[job_input], | |
| outputs=[jobs_output, jobs_status], | |
| show_progress=True, | |
| ) | |
| gr.Markdown("---") | |
| cv_upload = gr.File(label="Upload CV (PDF)", file_types=[".pdf"]) | |
| job_number = gr.Textbox(label="Job number", placeholder="e.g. 1") | |
| cover_btn = gr.Button("Generate Cover Letter") | |
| cover_output = gr.Markdown() | |
| cover_status = gr.Textbox(label="Status", interactive=False, value="Idle") | |
| cover_btn.click( | |
| fn=create_cover_letter_with_status, | |
| inputs=[job_number, cv_upload], | |
| outputs=[cover_output, cover_status], | |
| show_progress=True, | |
| ) | |
| with gr.Tab("Lead Gen & Outreach"): | |
| target_input = gr.Textbox(label="Target Audience", placeholder="e.g. digital marketing agencies") | |
| service_input = gr.Textbox(label="Your Service", placeholder="e.g. AI automation consulting") | |
| name_input = gr.Textbox(label="Your Name", placeholder="e.g. Uche") | |
| lead_btn = gr.Button("Generate Leads") | |
| lead_output = gr.Markdown() | |
| status_output = gr.Textbox(label="Status", interactive=False, value="Idle") | |
| lead_btn.click( | |
| fn=generate_leads_wrapper, | |
| inputs=[target_input, service_input, name_input], | |
| outputs=[lead_output, status_output], | |
| show_progress=True, | |
| ) | |
| ui.launch() | |