interview-coach / config.py
ishan-25's picture
Back to 7B
d88114a verified
Raw
History Blame Contribute Delete
21.6 kB
# Set to a globally maintained, high-throughput serverless instruction model
# ── LLM Backend ──────────────────────────────────────────────────────────────
# Set to the high-availability 14B Qwen cluster for context-aware grading
HF_MODEL = "Qwen/Qwen2.5-7B-Instruct"
# ── Persistence ──────────────────────────────────────────────────────────────
# Session is runtime-only. History JSON is written per-session and read for PDF.
HISTORY_FILE = "interview_history.json"
# ── Interview Modes ───────────────────────────────────────────────────────────
INTERVIEW_MODES = {
"⚡ Quick (3 Questions)": 3,
"📋 Standard (5 Questions)": 5,
"🔬 Deep Dive (7 Questions) ": 7,
}
# ── Question Prompt Templates ─────────────────────────────────────────────────
# These are injected into the QuestionGenAgent with the job profile context.
# The agent fills in {industry}, {role_level}, {keywords} dynamically.
QUESTION_PROMPT_TEMPLATES = [
"Generate ONE interview question asking the candidate to describe their most relevant project experience for a {role_level} {industry} role. Focus on: {keywords}. Question:",
"Generate ONE behavioral interview question about how the candidate handles challenges, relevant to {industry}. Question:",
"Generate ONE technical or domain-specific question that tests knowledge of {keywords} in a {industry} context. Question:",
"Generate ONE question asking the candidate about their approach to collaboration, communication, or leadership relevant to a {role_level} role. Question:",
"Generate ONE situational interview question: 'What would you do if...' relevant to {industry} and {keywords}. Question:",
"Generate ONE question about the candidate's long-term career goals and how this {industry} role aligns with them. Question:",
"Generate ONE challenging follow-up question that digs deeper into technical expertise or past achievements relevant to {keywords}. Question:",
]
# ── Default Tips (fallback only — AI-generated tips take priority) ─────────────
TIPS_DB = {
"python": {
"label": "Python / Backend",
"leetcode": [
("Two Sum", "https://leetcode.com/problems/two-sum/", "Easy"),
("LRU Cache", "https://leetcode.com/problems/lru-cache/", "Medium"),
("Word Search II", "https://leetcode.com/problems/word-search-ii/", "Hard"),
],
"concepts": ["OOP principles", "Decorators & generators", "Async / await", "REST API design"],
},
"react": {
"label": "React / Frontend",
"leetcode": [
("Valid Parentheses", "https://leetcode.com/problems/valid-parentheses/", "Easy"),
("Flatten Nested List", "https://leetcode.com/problems/flatten-nested-list-iterator/", "Medium"),
],
"concepts": ["Virtual DOM", "Hooks & state management", "Component lifecycle", "Web performance"],
},
"machine learning": {
"label": "Machine Learning",
"leetcode": [
("Find Peak Element", "https://leetcode.com/problems/find-peak-element/", "Medium"),
("Kth Largest Element", "https://leetcode.com/problems/kth-largest-element-in-an-array/", "Medium"),
],
"concepts": ["Bias-variance tradeoff", "Overfitting & regularisation", "Gradient descent", "Model evaluation metrics"],
},
"sql": {
"label": "SQL / Databases",
"leetcode": [
("Employees Earning More Than Manager", "https://leetcode.com/problems/employees-earning-more-than-their-managers/", "Easy"),
("Department Top 3 Salaries", "https://leetcode.com/problems/department-top-three-salaries/", "Hard"),
],
"concepts": ["JOINs & subqueries", "Indexing strategies", "Transactions & ACID", "Query optimisation"],
},
}
DEFAULT_TIPS = {
"label": "General / Professional",
"leetcode": [
("Two Sum", "https://leetcode.com/problems/two-sum/", "Easy"),
("Merge Intervals", "https://leetcode.com/problems/merge-intervals/", "Medium"),
("Trapping Rain Water", "https://leetcode.com/problems/trapping-rain-water/", "Hard"),
],
"concepts": ["STAR answer format", "System design basics", "Time & space complexity", "Behavioural questions"],
}
# ── CSS Design System ─────────────────────────────────────────────────────────
CUSTOM_CSS = """
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap');
/* ── Reset & Base ── */
* { font-family: 'Inter', ui-sans-serif, system-ui, sans-serif !important; box-sizing: border-box; }
/* ── Root color tokens (our design system) ── */
/* ── ALSO overrides Gradio's internal CSS variables so the loading overlay ── */
/* ── stays dark. The white box during processing comes from ── */
/* ── var(--block-background-fill) defaulting to white in the Soft theme. ── */
:root {
/* Our tokens */
--indigo: #6366f1;
--violet: #8b5cf6;
--indigo-glow: rgba(99,102,241,0.35);
--violet-glow: rgba(139,92,246,0.25);
--surface: rgba(15,15,35,0.6);
--border: rgba(99,102,241,0.18);
--text-muted: #94a3b8;
--text-dim: #64748b;
/* Gradio's internal variables — override to prevent white loading overlay */
--block-background-fill: rgba(8,8,28,0.85);
--input-background-fill: rgba(8,8,28,0.85);
--background-fill-primary: #080818;
--background-fill-secondary: rgba(15,15,35,0.7);
--body-background-fill: #080818;
--border-color-primary: rgba(99,102,241,0.18);
--body-text-color: #e2e8f0;
--body-text-color-subdued: #94a3b8;
--loader-color: #6366f1;
--block-border-color: rgba(99,102,241,0.18);
--input-border-color: rgba(99,102,241,0.18);
}
/* ── Background ── */
body { background: #080818 !important; }
gradio-app { background: transparent !important; }
.gradio-container { background: transparent !important; width: 100% !important; max-width: none !important; margin: 0 auto !important; padding: 0 20px !important; }
/* ── Make the blob background wrapper invisible (blobs are position:fixed, they float fine) ── */
#bg-blobs {
background: none !important;
border: none !important;
backdrop-filter: none !important;
padding: 0 !important;
margin: 0 !important;
overflow: visible !important;
min-height: 0 !important;
height: 0 !important;
pointer-events: none !important;
}
/* ── Make the header wrapper borderless/transparent ── */
#app-header {
background: none !important;
border: none !important;
backdrop-filter: none !important;
padding: 0 !important;
margin: 0 !important;
}
/* ── Glass panels ── */
.gr-panel, .gr-box, .svelte-panel, .block, .form {
background: var(--surface) !important;
border: 1px solid var(--border) !important;
backdrop-filter: blur(12px) !important;
border-radius: 14px !important;
}
/* ── Tab nav ── */
.tab-nav { border-bottom: 1px solid var(--border) !important; }
.tab-nav button {
font-weight: 600 !important;
color: var(--text-muted) !important;
padding: 0.6rem 1.2rem !important;
border-radius: 8px 8px 0 0 !important;
transition: all 0.2s !important;
}
.tab-nav button.selected {
color: var(--indigo) !important;
border-bottom: 2px solid var(--indigo) !important;
background: rgba(99,102,241,0.08) !important;
}
/* ── Primary buttons ── */
.gr-button-primary, button[variant="primary"], .primary-btn {
background: linear-gradient(135deg, #6366f1, #8b5cf6) !important;
border: none !important;
color: white !important;
font-weight: 600 !important;
font-size: 0.9rem !important;
padding: 0.6rem 1.4rem !important;
border-radius: 10px !important;
cursor: pointer !important;
transition: transform 0.15s ease, box-shadow 0.15s ease !important;
box-shadow: 0 0 0 rgba(99,102,241,0) !important;
}
.gr-button-primary:hover, button[variant="primary"]:hover {
transform: translateY(-2px) !important;
box-shadow: 0 8px 24px rgba(99,102,241,0.45) !important;
}
.gr-button-primary:active, button[variant="primary"]:active {
transform: translateY(0px) !important;
}
/* ── Secondary buttons ── */
.gr-button-secondary, button[variant="secondary"] {
border: 1.5px solid var(--indigo) !important;
color: var(--indigo) !important;
font-weight: 600 !important;
border-radius: 10px !important;
background: transparent !important;
transition: all 0.15s !important;
}
.gr-button-secondary:hover, button[variant="secondary"]:hover {
background: var(--indigo) !important;
color: white !important;
}
/* ── Textbox inputs — idle & focus ── */
.gr-textbox textarea, input[type="text"], textarea {
background: rgba(8,8,28,0.7) !important;
border: 1px solid var(--border) !important;
border-radius: 10px !important;
color: #e2e8f0 !important;
font-size: 0.92rem !important;
padding: 0.65rem 0.9rem !important;
transition: border-color 0.2s !important;
}
.gr-textbox textarea:focus, textarea:focus {
border-color: var(--indigo) !important;
outline: none !important;
box-shadow: 0 0 0 3px rgba(99,102,241,0.15) !important;
}
/* ── Textbox inputs — Gradio loading/processing states ── */
/* Gradio adds .generating / .pending to the .wrap container during LLM calls.
Without these, the dark textarea flips to white during processing. */
/* Target the wrapper container in every loading state */
.wrap.generating, .wrap.pending, .wrap.processing,
.generating .wrap, .pending .wrap, .processing .wrap {
background: rgba(8,8,28,0.7) !important;
border-color: var(--indigo) !important;
}
/* Target the textarea itself inside any loading-state wrapper */
.generating textarea, .pending textarea, .processing textarea,
.wrap.generating textarea, .wrap.pending textarea, .wrap.processing textarea,
textarea.generating, textarea.pending {
background: rgba(8,8,28,0.7) !important;
color: #e2e8f0 !important;
}
/* The loading overlay div Gradio injects on top of the textarea */
.generating .eta-bar, .generating .progress-bar,
.pending .eta-bar, .pending .progress-bar {
background: rgba(99,102,241,0.12) !important;
}
/* The small "processing | X.Xs" status text Gradio adds */
.wrap .eta-bar, .eta-bar {
color: var(--text-muted) !important;
font-size: 0.78rem !important;
background: transparent !important;
}
/* The loading spinner icon — keep it indigo, not default grey */
.loader, .generating .loader {
border-top-color: var(--indigo) !important;
}
/* Gradio 4/5/6 Svelte-generated loading shimmer overlay */
.generating::after, .pending::after {
background: rgba(8,8,28,0.4) !important;
}
/* ── Labels ── */
/* Custom styling for the textbox label capsules */
#step-1-group label span,
#step-3-group label span,
#step-4-group label span {
background: #322b48 !important; /* Change this to edit the capsule background color */
color: #e2e8f0 !important; /* Change this to edit the text color inside the label */
border: 1px solid #6366f1 !important; /* Optional: adds a border to match the input boxes */
width: 150px !important;
text-align: center !important;
display: inline-block !important;
}
/* ── Progress box ── */
#progress_box textarea {
font-weight: 700 !important;
font-size: 1rem !important;
color: var(--indigo) !important;
text-align: center !important;
background: rgba(99,102,241,0.08) !important;
border-color: var(--indigo) !important;
}
/* ── Feedback box ── */
#feedback_box textarea {
font-size: 0.93rem !important;
line-height: 1.65 !important;
color: #cbd5e1 !important;
}
/* ── Markdown text ── */
.gr-markdown, .prose {
color: #cbd5e1 !important;
}
.padded-markdown{
padding: 16px 20px !important;
}
.gr-markdown h1, .gr-markdown h2, .gr-markdown h3 {
color: #e2e8f0 !important;
}
.gr-markdown code {
background: rgba(99,102,241,0.15) !important;
color: #a5b4fc !important;
border-radius: 4px !important;
padding: 2px 6px !important;
}
.gr-markdown table {
border-collapse: collapse !important;
width: 100% !important;
}
.gr-markdown th {
background: rgba(99,102,241,0.15) !important;
color: #a5b4fc !important;
padding: 8px 12px !important;
font-weight: 600 !important;
}
.gr-markdown td {
border: 1px solid var(--border) !important;
padding: 7px 12px !important;
color: #cbd5e1 !important;
}
/* ── Accordion ── */
.gr-accordion summary {
color: #a5b4fc !important;
font-weight: 600 !important;
}
/* ── Radio group (mode selector) ── */
.gr-radio-group label {
background: rgba(99,102,241,0.06) !important;
border: 1px solid var(--border) !important;
border-radius: 8px !important;
padding: 0.5rem 1rem !important;
cursor: pointer !important;
transition: all 0.15s !important;
color: #94a3b8 !important;
}
.gr-radio-group label:has(input:checked) {
background: rgba(99,102,241,0.2) !important;
border-color: var(--indigo) !important;
color: #a5b4fc !important;
}
/* ── File upload ── */
.gr-file { border: 1px dashed var(--border) !important; border-radius: 10px !important; }
/* ── Scrollbars ── */
::-webkit-scrollbar { width: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--indigo); border-radius: 3px; }
/* ── Fix for White File Download Row ── */
.gr-file .file-preview,
.gr-file .file-preview-holder,
.gr-file .file-preview-wrap,
.gr-file tbody tr,
.gr-file table td,
.gr-file .download-link {
background-color: transparent !important;
background: transparent !important;
color: #e2e8f0 !important;
}
/* Add a subtle hover effect for the file row */
.gr-file tbody tr:hover {
background-color: rgba(99,102,241,0.1) !important;
}
/* Ensure the file name text and size information are readable */
.gr-file tbody td {
color: #cbd5e1 !important;
border-color: rgba(99,102,241,0.18) !important;
}
/* Color the download icon to match your purple theme */
.gr-file svg {
stroke: #8b5cf6 !important;
}
/* ── Gradio footer (settings cog, "Built with Gradio" link) ── */
footer, .gradio-container > footer, .built-with {
color: var(--text-dim) !important;
}
footer a, .built-with a {
color: var(--text-muted) !important;
}
footer svg, .built-with svg {
fill: var(--text-dim) !important;
stroke: var(--text-dim) !important;
}
/* Remove default borders and backgrounds from columns, rows, and forms to prevent nested double borders */
.gradio-container .vertical,
.gradio-container .row,
.gradio-container .gr-form {
background: transparent !important;
border: none !important;
backdrop-filter: none !important;
box-shadow: none !important;
padding: 0 !important;
}
/* Style all step group containers as unified glass panels */
#step-1-group, #step-2-group, #step-3-group, #step-4-group {
background: var(--surface) !important;
border: 1px solid var(--border) !important;
backdrop-filter: blur(10px) !important;
border-radius: 15px !important;
padding: 2px !important;
display: flex !important;
flex-direction: column !important;
gap: 1px !important;
margin-bottom: 5px !important;
box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.2) !important;
}
/* Remove borders, backgrounds, shadows, and extra padding from all nested elements inside the groups to eliminate double-bordering */
#step-1-group div, #step-1-group label,
#step-2-group div,
#step-3-group div, #step-3-group label,
#step-4-group div, #step-4-group label {
background: transparent !important;
border: none !important;
backdrop-filter: none !important;
box-shadow: none !important;
}
/* Format the inner textareas (Step 1, Step 3, Step 4) to be clean, integrated, and borderless */
#step-1-group textarea,
#step-3-group textarea,
#step-4-group textarea {
background: rgba(8, 8, 28, 0.7) !important;
border: 3px solid steelblue !important;
border-radius: 5px !important;
padding: 10px !important;
box-shadow: 0 0 3px dodgerblue !important;
}
#step-1-group textarea:focus,
#step-3-group textarea:focus,
#step-4-group textarea:focus {
outline: none !important;
box-shadow: 0 0 5px dodgerblue !important;
}
/*------------------------------------------------------*/
/* Step-2 Normal (unselected) radio button choices */
#step-2-group label {
border: 2px solid rgba(99, 102, 241, 0.2) !important; /* Edit normal border width/color here */
border-radius: 30px !important;
background: #475569 !important;
width: 60%;
}
/*Step-2 label Hover settings*/
#step-2-group label:hover {
border: 2px solid rgba(99, 102, 241, 0.8) !important; /* Edit selected border width/color here */
background: rgba(99, 102, 241, 0.1) !important; /* Edit selected background here */
width: 60%;
border-radius: 30px !important;
}
/* Step-2 Selected/active radio button choice */
#step-2-group label.selected {
border: 2px solid rgba(99, 102, 241, 0.8) !important; /* Edit selected border width/color here */
background: #9333EA !important; /* Edit selected background here */
width: 60%;
border-radius: 30px !important;
}
/*Step-2 Radio button container's border editing.*/
#step-2-group fieldset{
border: none !important;
background: tranparent !important;
box-shadow: none !important;
backdrop-filter: none !important;
}
/*TIPS SECTION FORMATTING*/
/*Since we use class tag, we will call this via (.)*/
.session-tips {
background: rgba(15,15,40,0.6);
border: 2px solid rgba(99,102,241,0.2);
border-radius:12px;
padding:14px 14px;
box-shadow: 0 0 10px deepskyblue !important;
}
.session-tips:hover{
border-color: blue !important;
box-shadow: 0 0 20px blue !important;
}
/*Step-3 button formartting*/
/*we edit the row settings as the button render inside a row within the right column*/
#step-3-group .row {
display: flex !important;
flex-direction: row !important; /* Force horizontal layout */
flex-wrap: nowrap !important; /* Prevent wrapping/stacking */
justify-content: center !important; /* Center both buttons */
margin: 0px auto !important;
padding: 0px !important;
gap: 10px !important;
width: 95% !important;
}
/*Now we get into the button formatting directly*/
/*this is for the Primary button: the Get Feedback button*/
#step-3-group button{
border-radius: 30px !important;
border: 1px solid rgba(99, 102, 241, 0.2) !important;
padding: 5px !important;
width: 49.5% !important;
flex: none !important;
}
/* Hover (mouse-over) effect: make the button darker with a minor border change*/
#step-3-group button:hover {
padding: 5px !important;
background: #191836 !important; /* Slightly stronger purple */
border: 1px solid rgba(99, 102, 241, 0.8) !important; /* Edit selected border width/color here */
}
/*------------------------------------------------------*/
/*this is for the secondary button of the gr.Row(), the Next Question button*/
#step-3-group button.secondary{
background: #475569 !important;
color: white !important;
border-radius: 30px !important;
border: 1px solid rgba(99, 102, 241, 0.2) !important;
opacity: 1 !important;
}
#step-3-group button.secondary:hover{
padding: 5px !important;
background: #191836 !important;
border: 1px solid rgba(99, 102, 241, 0.8) !important;
color: white !important;
}
/* ── Tab 2 (History & Report) Button Styling ── */
/* Primary Button (Generate PDF Report) */
#report-actions button.primary {
background: #8b5cf6 !important;
color: white !important;
border: 1px solid #a5b4fc !important;
}
#report-actions button.primary:hover {
background: #7c3aed !important;
}
/* Secondary Buttons (Refresh Preview & Clear Session) */
#report-actions button.secondary {
background: #322b48 !important;
color: #ffffff !important;
border: 1px solid #6366f1 !important;
}
#report-actions button.secondary:hover {
background: #191836 !important;
border-color: rgba(99, 102, 241, 0.8) !important;
}
"""