first commit
This commit is contained in:
commit
7a72438fd1
74 changed files with 7548 additions and 0 deletions
104
backend/app/services/gemini_service.py
Normal file
104
backend/app/services/gemini_service.py
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
import logging
|
||||
import json
|
||||
from google import genai
|
||||
from google.genai import types
|
||||
from app.config import get_settings
|
||||
from app.models.question import QuestionItem
|
||||
from app.models.pronunciation import PronunciationItem
|
||||
|
||||
settings = get_settings()
|
||||
|
||||
client = None
|
||||
if settings.gemini_api_key:
|
||||
client = genai.Client(api_key=settings.gemini_api_key)
|
||||
|
||||
async def generate_interview_questions(resume_text: str, role_name: str, skills: list[str], experience: int, projects: list[dict] = None) -> list[dict]:
|
||||
if not client:
|
||||
logging.error("Gemini API key not configured.")
|
||||
raise ValueError("Gemini API key not configured")
|
||||
|
||||
# Format projects for the prompt
|
||||
projects_section = ""
|
||||
if projects:
|
||||
projects_section = "\n Candidate's Projects (PRIORITIZE these in your questions):\n"
|
||||
for p in projects[:5]:
|
||||
tech_str = ", ".join(p.get("tech", []))
|
||||
projects_section += f" - {p['name']}: {p.get('description', '')[:300]} (Tech: {tech_str})\n"
|
||||
else:
|
||||
projects_section = " No projects listed."
|
||||
|
||||
prompt = f"""
|
||||
You are an expert technical interviewer.
|
||||
|
||||
Job Requirement:
|
||||
- Role: {role_name}
|
||||
- Required Experience: {experience} years
|
||||
- Target Skills: {', '.join(skills)}
|
||||
|
||||
{projects_section}
|
||||
|
||||
Full Candidate Resume Text:
|
||||
{resume_text}
|
||||
|
||||
Generate exactly 5 interview questions following this distribution:
|
||||
- Questions 1, 2, 3: MUST be directly about the candidate's specific PROJECTS listed above.
|
||||
Ask about technical decisions made, challenges faced, architecture, or improvements they would make.
|
||||
- Questions 4, 5: Should cover general skills from the job requirement.
|
||||
|
||||
For each question, provide:
|
||||
1. question: The question itself.
|
||||
2. expected_answer: Key points an ideal answer should cover.
|
||||
3. hint: A short hint if the candidate gets stuck.
|
||||
4. difficulty: Easy, Medium, or Hard.
|
||||
5. category: Technical, Behavioral, or System Design.
|
||||
"""
|
||||
|
||||
try:
|
||||
response = client.models.generate_content(
|
||||
model='gemini-2.5-flash',
|
||||
contents=prompt,
|
||||
config=types.GenerateContentConfig(
|
||||
response_mime_type="application/json",
|
||||
response_schema=list[QuestionItem],
|
||||
temperature=0.7,
|
||||
),
|
||||
)
|
||||
questions = json.loads(response.text)
|
||||
return questions
|
||||
except Exception as e:
|
||||
logging.error(f"Failed to generate questions: {e}")
|
||||
raise ValueError(f"Failed to generate questions: {e}")
|
||||
|
||||
async def get_word_pronunciation(word: str) -> dict:
|
||||
if not client:
|
||||
logging.error("Gemini API key not configured.")
|
||||
raise ValueError("Gemini API key not configured")
|
||||
|
||||
prompt = f"""
|
||||
You are an expert linguist and technical dictionary.
|
||||
Analyze the technical term: "{word}"
|
||||
|
||||
Provide the following structured information:
|
||||
1. word: The correctly spelled word.
|
||||
2. phonetic: The exact IPA (International Phonetic Alphabet) pronunciation (e.g., /ˌpɒlɪˈmɔːfɪzəm/).
|
||||
3. syllables: An array of strings representing the syllable breakdown (e.g., ["pol", "y", "mor", "phism"]).
|
||||
4. definition: A concise definition of the word, specifically in a computer science or tech context (max 2 sentences).
|
||||
"""
|
||||
|
||||
try:
|
||||
response = client.models.generate_content(
|
||||
model='gemini-2.5-flash',
|
||||
contents=prompt,
|
||||
config=types.GenerateContentConfig(
|
||||
response_mime_type="application/json",
|
||||
response_schema=PronunciationItem,
|
||||
temperature=0.1,
|
||||
),
|
||||
)
|
||||
|
||||
# Parse the JSON response
|
||||
data = json.loads(response.text)
|
||||
return data
|
||||
except Exception as e:
|
||||
logging.error(f"Failed to get pronunciation: {e}")
|
||||
raise ValueError(f"Failed to get pronunciation: {e}")
|
||||
Loading…
Add table
Add a link
Reference in a new issue