UnivAI-agents / main_app.py
UnivAI001
initial commit - AI automation agents
6798e8f
Raw
History Blame Contribute Delete
6.52 kB
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()