import gradio as gr import os import requests import json import time from typing import List, Dict, Tuple # Mistral API configuration MISTRAL_API_URL = "https://api.mistral.ai/v1/chat/completions" # Function to get API key from Hugging Face secrets or user input def get_mistral_api_key(user_key: str = None) -> str: """Get API key from HF secrets or user input""" # First try Hugging Face secrets hf_key = os.environ.get("MISTRAL_API_KEY", "") if hf_key: return hf_key elif user_key and user_key.strip(): return user_key.strip() else: return None # Function to call Mistral API def call_mistral_api( messages: List[Dict[str, str]], api_key: str, model: str = "mistral-small-latest", temperature: float = 0.7 ) -> str: """Call Mistral API for chat completion""" if not api_key: return "Error: API key not provided. Please enter your Mistral API key in the settings tab." headers = { "Authorization": f"Bearer {api_key}", "Content-Type": "application/json" } payload = { "model": model, "messages": messages, "temperature": temperature, "max_tokens": 500 } try: response = requests.post( MISTRAL_API_URL, headers=headers, data=json.dumps(payload), timeout=30 ) if response.status_code == 200: result = response.json() return result["choices"][0]["message"]["content"] else: return f"API Error {response.status_code}: {response.text}" except Exception as e: return f"Connection error: {str(e)}" # Role-based system prompts ROLE_PROMPTS = { "Software Engineer": """You are an AI interviewer for a Software Engineer position. Ask technical questions about programming, algorithms, system design, and problem-solving. Be professional but conversational. Ask one question at a time and wait for the candidate's response. If the candidate gives a short answer, ask follow-up questions to get more details. Assess their technical depth and communication skills.""", "Marketing Manager": """You are an AI interviewer for a Marketing Manager position. Ask questions about marketing strategies, campaign management, analytics, and team leadership. Focus on their experience with digital marketing, ROI measurement, and creative thinking. Ask one question at a time and evaluate their strategic approach.""", "Sales Executive": """You are an AI interviewer for a Sales Executive position. Ask about sales techniques, client relationship management, target achievement, and negotiation skills. Assess their persistence, communication style, and results-oriented mindset. Ask one question at a time and provide constructive feedback.""" } # Generate AI interview question def generate_ai_question(role: str, conversation_history: List[Tuple[str, str]], api_key: str) -> str: """Generate next interview question using Mistral API""" system_prompt = ROLE_PROMPTS.get(role, ROLE_PROMPTS["Software Engineer"]) # Format conversation history for Mistral messages = [{"role": "system", "content": system_prompt}] for speaker, text in conversation_history[-4:]: # Last 4 exchanges if speaker == "AI Interviewer": messages.append({"role": "assistant", "content": text}) else: messages.append({"role": "user", "content": text}) # Add prompt for next question if not conversation_history: prompt = "Start the interview with an opening greeting and first question." else: prompt = "Based on the conversation so far, ask the next appropriate interview question." messages.append({"role": "user", "content": prompt}) # Call Mistral API response = call_mistral_api(messages, api_key) return response # Main interview function def ai_interview(role, user_message, history, api_key_input): if not role: return "Please select a job role", history, "" api_key = get_mistral_api_key(api_key_input) if not api_key: return "Please enter your Mistral API key in the Settings tab", history, "" if user_message: # Add user's response to history history.append(("Candidate", user_message)) # Generate AI response using Mistral ai_response = generate_ai_question(role, history, api_key) # Add AI response to history history.append(("AI Interviewer", ai_response)) return "", history, ai_response # Start new interview def start_interview(role, api_key_input): if not role: return "Please select a job role", [], "" api_key = get_mistral_api_key(api_key_input) if not api_key: return "Please enter your Mistral API key", [], "" # Start with AI greeting initial_history = [] ai_response = generate_ai_question(role, initial_history, api_key) initial_history.append(("AI Interviewer", ai_response)) return ai_response, initial_history, "" # Analyze voice using Mistral def analyze_voice_with_ai(audio_path, api_key_input, transcript): if not audio_path: return "Please record your voice first", "", {}, "" api_key = get_mistral_api_key(api_key_input) if not api_key: return "API key required for analysis", "", {}, "" # Simulate processing time time.sleep(2) # Use Mistral to analyze communication skills based on transcript system_prompt = """You are an expert speech analyst. Analyze the candidate's communication skills based on their interview response. Provide assessment in these areas: 1. Clarity and Pronunciation 2. Confidence Level 3. Communication Effectiveness 4. Professional Tone 5. Areas for Improvement Format your response with clear sections and be constructive.""" user_prompt = f"Analyze this interview response for communication skills:\n\n{transcript}" messages = [ {"role": "system", "content": system_prompt}, {"role": "user", "content": user_prompt} ] analysis = call_mistral_api(messages, api_key) # Generate scores based on analysis (simulated for demo) scores = { "Clarity": 75 + int(len(transcript) / 10) % 20, "Confidence": 70 + int(len(transcript) / 15) % 25, "Communication": 80 + int(len(transcript) / 20) % 15, "Professionalism": 65 + int(len(transcript) / 12) % 30 } # Summary for display summary = "Voice analysis completed using AI. Check detailed feedback below." return summary, analysis, scores, "✅ Analysis ready! View results below." # Gradio Interface with gr.Blocks(title="🤖 AI-Powered ATS with Mistral", theme=gr.themes.Soft()) as demo: gr.Markdown(""" # 🤖 AI-Powered Applicant Tracking System ### Real AI Interviews using Mistral API **Features:** - Real AI-generated interview questions - Voice recording and analysis - Dynamic conversation with AI """) # Store API key in session state api_key_state = gr.State("") with gr.Tabs(): # Tab 1: Settings with gr.TabItem("⚙️ Settings"): gr.Markdown("### Configure Your API Keys") gr.Markdown(""" **For Hugging Face Deployment:** 1. Add `MISTRAL_API_KEY` in your Space's Secrets 2. Go to Settings → Repository secrets **OR enter your key manually below:** """) api_key_input = gr.Textbox( label="Mistral API Key", type="password", placeholder="Enter your Mistral API key here...", info="Get your key from: https://console.mistral.ai/api-keys/" ) save_key_btn = gr.Button("Save API Key", variant="primary") @save_key_btn.click(inputs=[api_key_input], outputs=[api_key_state]) def save_key(key): return key # Tab 2: AI Interview with gr.TabItem("💬 AI Chat Interview"): gr.Markdown("### AI-Powered Chat Interview") with gr.Row(): with gr.Column(scale=1): role_selection = gr.Dropdown( choices=list(ROLE_PROMPTS.keys()), label="Select Job Role", value="Software Engineer" ) status = gr.Textbox(label="Status", interactive=False) with gr.Column(scale=2): chatbot = gr.Chatbot( label="Interview Conversation", height=400, avatar_images=( "https://api.dicebear.com/7.x/avataaars/svg?seed=AI", "https://api.dicebear.com/7.x/avataaars/svg?seed=User" ) ) with gr.Row(): user_input = gr.Textbox( label="Your Answer", placeholder="Type your answer here...", scale=4 ) submit_btn = gr.Button("Submit", variant="primary", scale=1) start_btn = gr.Button("Start New", scale=1) # Response display ai_response_display = gr.Textbox( label="Current AI Question", interactive=False, lines=3 ) # Event handlers submit_event = submit_btn.click( ai_interview, inputs=[role_selection, user_input, chatbot, api_key_state], outputs=[user_input, chatbot, ai_response_display] ) start_event = start_btn.click( start_interview, inputs=[role_selection, api_key_state], outputs=[ai_response_display, chatbot, user_input] ) user_input.submit( ai_interview, inputs=[role_selection, user_input, chatbot, api_key_state], outputs=[user_input, chatbot, ai_response_display] ) # Tab 3: Voice Interview with gr.TabItem("🎤 Voice Assessment"): gr.Markdown("### Voice Interview Recording") gr.Markdown("Record your answer to assess communication skills") with gr.Row(): with gr.Column(): audio_input = gr.Audio( sources=["microphone"], type="filepath", label="Record Your Answer (30-60 seconds)", interactive=True ) transcript_input = gr.Textbox( label="What you said (or type manually)", placeholder="Describe what you said in the recording...", lines=3 ) analyze_btn = gr.Button("Analyze with AI", variant="primary") with gr.Column(): result_summary = gr.Textbox(label="Analysis Summary", interactive=False) detailed_analysis = gr.Textbox( label="Detailed AI Analysis", interactive=False, lines=8 ) scores_display = gr.Label(label="Assessment Scores") status_indicator = gr.Textbox(label="Status", interactive=False) analyze_btn.click( analyze_voice_with_ai, inputs=[audio_input, api_key_state, transcript_input], outputs=[result_summary, detailed_analysis, scores_display, status_indicator] ) # Tab 4: How to Use with gr.TabItem("📚 How to Use"): gr.Markdown(""" ## Getting Started ### 1. **API Setup** - Get Mistral API key from [Mistral Console](https://console.mistral.ai/api-keys/) - **Option A (Recommended):** Add to Hugging Face Secrets - Go to your Space → Settings → Repository secrets - Add `MISTRAL_API_KEY` with your key - **Option B:** Enter manually in Settings tab ### 2. **Conduct AI Interview** 1. Go to "AI Chat Interview" tab 2. Select job role 3. Click "Start New" 4. Respond to AI's questions 5. AI will ask relevant follow-up questions ### 3. **Voice Assessment** 1. Go to "Voice Assessment" tab 2. Record your voice (30-60 seconds recommended) 3. Describe what you said 4. Click "Analyze with AI" 5. Get detailed feedback on communication skills ### 4. **For Hugging Face Deployment** ```yaml # requirements.txt gradio>=4.0 requests python-dotenv ``` ### **Note:** - First response may take 10-15 seconds - Keep answers concise for best results - Voice analysis uses transcript for AI assessment """) # Launch app if __name__ == "__main__": demo.launch( debug=True, share=False, server_name="0.0.0.0", server_port=7860 )