Spaces:
Paused
Paused
File size: 5,424 Bytes
ba72f62 2ae57cb 22b00f2 2ae57cb 22b00f2 8e4e001 2ae57cb 22b00f2 2ae57cb 22b00f2 2ae57cb 22b00f2 2ae57cb 22b00f2 2ae57cb 22b00f2 2ae57cb 22b00f2 2ae57cb 8e4e001 22b00f2 8e4e001 22b00f2 8e4e001 2ae57cb 22b00f2 2ae57cb 22b00f2 2ae57cb 22b00f2 8e4e001 22b00f2 2ae57cb 22b00f2 2ae57cb 22b00f2 2ae57cb 22b00f2 2ae57cb 8e4e001 2ae57cb 22b00f2 2ae57cb 22b00f2 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
import os
import json
import asyncio
import edge_tts
from faster_whisper import WhisperModel
from langchain_groq import ChatGroq
import logging
# Initialize models
chat_groq_api = os.getenv("GROQ_API_KEY", "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")
groq_llm = ChatGroq(
temperature=0.7,
model_name="llama-3.3-70b-versatile",
api_key=chat_groq_api
)
# Initialize Whisper model
whisper_model = None
def load_whisper_model():
global whisper_model
if whisper_model is None:
device = "cuda" if os.system("nvidia-smi") == 0 else "cpu"
compute_type = "float16" if device == "cuda" else "int8"
whisper_model = WhisperModel("base", device=device, compute_type=compute_type)
return whisper_model
def generate_first_question(profile, job):
"""Generate the first interview question based on profile and job"""
try:
prompt = f"""
You are conducting an interview for a {job.role} position at {job.company}.
The candidate's profile shows:
- Skills: {profile.get('skills', [])}
- Experience: {profile.get('experience', [])}
- Education: {profile.get('education', [])}
Generate an appropriate opening interview question that is professional and relevant.
Keep it concise and clear.
"""
response = groq_llm.predict(prompt)
return response.strip()
except Exception as e:
logging.error(f"Error generating first question: {e}")
return "Tell me about yourself and why you're interested in this position."
def edge_tts_to_file_sync(text, output_path, voice="en-US-AriaNeural"):
"""Synchronous wrapper for edge-tts"""
try:
# Ensure the directory exists and is writable
directory = os.path.dirname(output_path)
if not directory:
directory = "/tmp" # Fallback to /tmp if no directory specified
output_path = os.path.join(directory, os.path.basename(output_path))
os.makedirs(directory, exist_ok=True)
# Test write permissions
test_file = os.path.join(directory, f"test_{os.getpid()}.tmp")
try:
with open(test_file, 'w') as f:
f.write("test")
os.remove(test_file)
except (PermissionError, OSError) as e:
logging.error(f"Directory {directory} is not writable: {e}")
# Fallback to /tmp
directory = "/tmp"
output_path = os.path.join(directory, os.path.basename(output_path))
os.makedirs(directory, exist_ok=True)
async def generate_audio():
communicate = edge_tts.Communicate(text, voice)
await communicate.save(output_path)
# Run async function in sync context
try:
loop = asyncio.get_event_loop()
except RuntimeError:
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.run_until_complete(generate_audio())
# Verify file was created and has content
if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
return output_path
else:
logging.error(f"Audio file was not created or is empty: {output_path}")
return None
except Exception as e:
logging.error(f"Error in TTS generation: {e}")
return None
def whisper_stt(audio_path):
"""Speech-to-text using Faster-Whisper"""
try:
if not audio_path or not os.path.exists(audio_path):
logging.error(f"Audio file does not exist: {audio_path}")
return ""
# Check if file has content
if os.path.getsize(audio_path) == 0:
logging.error(f"Audio file is empty: {audio_path}")
return ""
model = load_whisper_model()
segments, _ = model.transcribe(audio_path)
transcript = " ".join(segment.text for segment in segments)
return transcript.strip()
except Exception as e:
logging.error(f"Error in STT: {e}")
return ""
def evaluate_answer(question, answer, ref_answer, job_role, seniority):
"""Evaluate candidate's answer"""
try:
prompt = f"""
You are evaluating a candidate's answer for a {seniority} {job_role} position.
Question: {question}
Candidate Answer: {answer}
Reference Answer: {ref_answer}
Evaluate based on technical correctness, clarity, and relevance.
Respond with JSON format:
{{
"Score": "Poor|Medium|Good|Excellent",
"Reasoning": "brief explanation",
"Improvements": ["suggestion1", "suggestion2"]
}}
"""
response = groq_llm.predict(prompt)
# Extract JSON from response
start_idx = response.find("{")
end_idx = response.rfind("}") + 1
if start_idx >= 0 and end_idx > start_idx:
json_str = response[start_idx:end_idx]
return json.loads(json_str)
else:
raise ValueError("No valid JSON found in response")
except Exception as e:
logging.error(f"Error evaluating answer: {e}")
return {
"Score": "Medium",
"Reasoning": "Evaluation failed",
"Improvements": ["Please be more specific"]
} |