import os from pathlib import Path import litellm from crewai import Agent, Task, Crew, Process from crewai_tools import SerperDevTool import pdfplumber from docx import Document import gradio as gr # Set up API keys litellm.api_key = os.getenv('GOOGLE_API_KEY') os.environ['SERPER_API_KEY'] = os.getenv('SERPER_API_KEY') # Define the LLM llm = "gemini/gemini-1.5-flash-exp-0827" # Your LLM model # Initialize the tool for internet searching capabilities tool = SerperDevTool() # Create the CV Analysis Agent cv_analysis_agent = Agent( role="CV Analyzer", goal='Analyze the given CV and extract key skills and experiences and make improvements if needed for portfolio creation.', verbose=True, memory=True, backstory=( "You are an expert CV Analyzer with a keen eye for detail. Your role is to meticulously examine the provided CV, " "identifying and extracting key skills, experiences, accomplishments, and areas for improvement. " "Your analysis should highlight strengths and suggest enhancements that would make the portfolio more competitive." ), tools=[tool], llm=llm, allow_delegation=True ) # Create the Portfolio Generation Agent portfolio_generation_agent = Agent( role='Portfolio Generator', goal='Generate a professional HTML/CSS/JS responsive landing portfolio webpage based on {cv} analysis.', verbose=True, memory=True, backstory=( "As a Responsive Portfolio Generator, your expertise lies in creating visually appealing and user-friendly web pages. " "Based on the CV analysis, you will generate a professional HTML/CSS/JS portfolio. " "Ensure the design reflects the individual's strengths and experiences while incorporating effective functionality. " "Consider responsiveness, color schemes, and navigation for an optimal user experience." ), tools=[tool], llm=llm, allow_delegation=False ) # Research task for CV analysis cv_analysis_task = Task( description=( "Analyze the provided {cv} in detail. Identify and summarize key skills, experiences, and notable accomplishments. " "Highlight educational background and suggest potential enhancements to improve the overall presentation and competitiveness of the CV." ), expected_output='A detailed summary of skills, experiences, accomplishments, and improvement suggestions formatted for a portfolio.', tools=[tool], agent=cv_analysis_agent, ) # Writing task for portfolio generation with enhanced UI requirements portfolio_task = Task( description=( "Generate a responsive HTML/CSS portfolio webpage based on the given CV analysis. " "Include a navbar with the individual's name, and sections for skills, projects, experiences, certifications, and contact information. " "Ensure the layout is clean and visually appealing with a light/dark theme toggle option. " "Embed CSS/JS directly into the HTML for easy deployment, and optimize for both desktop and mobile viewing." ), expected_output='A complete and responsive HTML document ready for deployment, showcasing the individual’s strengths.', tools=[tool], agent=portfolio_generation_agent, async_execution=True, ) # Function to read CV from PDF or DOCX file def read_cv_file(file_path): ext = os.path.splitext(file_path)[1].lower() cv_content = "" if ext == '.pdf': with pdfplumber.open(file_path) as pdf: for page in pdf.pages: cv_content += page.extract_text() elif ext == '.docx': doc = Document(file_path) for para in doc.paragraphs: cv_content += para.text + "\n" else: raise ValueError("Unsupported file format. Please use .pdf or .docx.") return cv_content.strip() # Create a Crew for processing crew = Crew( agents=[cv_analysis_agent, portfolio_generation_agent], tasks=[cv_analysis_task, portfolio_task], process=Process.sequential, ) # Function to process CV and generate portfolio def process_cv(file): try: cv_file_content = read_cv_file(file.name) result = crew.kickoff(inputs={'cv': cv_file_content}) # Print the entire result object to explore its contents (for debugging) print(result) # Convert the result to string html_output = str(result) # Use replace to remove '''html''' and ''' from the output clean_html_output = html_output.replace("```html", '').replace("```", '').strip() return clean_html_output # Return the cleaned HTML except Exception as e: return f"Error: {e}" def save_html_to_file(html_content): output_file_path = "Portfolio_generated_by_FiftyBit.html" with open(output_file_path, "w") as f: f.write(html_content) return output_file_path import html def upload_file(filepath): name = Path(filepath).name html_content = process_cv(filepath) # Get HTML content from the CV # Clean the HTML content and escape it for proper iframe embedding clean_html_output = html_content.replace("```html", '').replace("```", '').strip() escaped_html_content = html.escape(clean_html_output) # Escape HTML content # Debugging print to check the escaped HTML content #print("Escaped HTML content:", escaped_html_content) # Save the cleaned HTML content to a file (if you still want this feature) file_path = save_html_to_file(clean_html_output) # Return a full HTML string with embedded iframe for preview iframe_html = f""" """ return iframe_html, gr.UploadButton(visible=False), gr.DownloadButton(label=f"Download Code", value=file_path, visible=True) def download_file(): return [gr.UploadButton(label=f"Regenerate", visible=True), gr.DownloadButton(visible=False)] # Gradio App with gr.Blocks() as demo: gr.Markdown("