import os from google.colab import userdata 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 = userdata.get("GOOGLE_API_KEY") os.environ['SERPER_API_KEY'] = userdata.get('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=( "As a CV Analyzer, you are skilled in identifying key information " "from resumes to aid in building effective portfolios." "You can add relevant skills and job responsibilities evaluating the whole cv." ), tools=[tool], llm=llm, allow_delegation=True ) # Create the Portfolio Generation Agent portfolio_generation_agent = Agent( role='Portfolio Generator', goal='Generate a beautiful static HTML/CSS/JS landing portfolio webpage based on CV analysis.', verbose=True, memory=True, backstory=( "As a Portfolio Generator, you craft engaging web pages with effective functionalities and color combinations " "to showcase individual talents and experiences with the best user experience." ), tools=[tool], llm=llm, allow_delegation=False ) # Research task for CV analysis cv_analysis_task = Task( description=( "Analyze the provided {cv} and identify key skills, experiences, " "and accomplishments. Highlight notable projects and educational background." ), expected_output='A summary of skills, experiences, and projects 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 static HTML/CSS/JS landing portfolio with a name as header in top, navbar for different sections, beautiful and responsive design. " "Ensure that the layout is clean, with sections for skills, projects, experiences, certifications, publications, and contact details if present in the CV. " "Include a footer that does not overlap with the content. " "Use a modern color palette and incorporate CSS frameworks if necessary, " "but provide everything embedded in the HTML file. " "The output should be a complete HTML document starting from to , ready to deploy." ), expected_output='A complete HTML/CSS/JS code content only for a portfolio website in a single .html file', tools=[tool], agent=portfolio_generation_agent, async_execution=False, output_file='portfolio.html' # Output as HTML file ) # 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 import re # 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}" # Gradio UI using Blocks with gr.Blocks() as iface: gr.Markdown("# CV-2-HTML AI Enhanced Portfolio Website Generation") gr.Markdown("Upload your CV in PDF or DOCX format to analyze its content and generate a portfolio.") # File input for uploading CV cv_input = gr.File(label="Upload your CV (.pdf or .docx)") # Output textbox for generated HTML output_textbox = gr.Textbox(label="Generated HTML", lines=20, placeholder="Your generated HTML will appear here...", interactive=True) # Process button process_button = gr.Button("Generate Portfolio") # Define the button actions process_button.click(fn=process_cv, inputs=cv_input, outputs=output_textbox) # Launch the Gradio interface iface.launch()