diff --git a/app/pages/2_Settings.py b/app/pages/2_Settings.py index 935ba3e..b16819d 100644 --- a/app/pages/2_Settings.py +++ b/app/pages/2_Settings.py @@ -121,6 +121,19 @@ with tab_profile: if nb.button("+ Add", key="add_nda") and new_nda.strip(): nda_list.append(new_nda.strip()) + with st.expander("🔍 Research Brief Preferences"): + st.caption("Optional identity-related sections added to pre-interview research briefs. For your personal decision-making only — never included in applications.") + u_access_focus = st.checkbox( + "Include disability & accessibility section", + value=_u.get("candidate_accessibility_focus", False), + help="Adds an ADA accommodation, ERG, and WCAG assessment to each company brief.", + ) + u_lgbtq_focus = st.checkbox( + "Include LGBTQIA+ inclusion section", + value=_u.get("candidate_lgbtq_focus", False), + help="Adds an assessment of the company's LGBTQIA+ ERGs, policies, and culture signals.", + ) + with st.expander("📁 File Paths"): u_docs = st.text_input("Documents directory", _u.get("docs_dir", "~/Documents/JobSearch")) u_ollama = st.text_input("Ollama models directory", _u.get("ollama_models_dir", "~/models/ollama")) @@ -160,6 +173,9 @@ with tab_profile: "nda_companies": nda_list, "docs_dir": u_docs, "ollama_models_dir": u_ollama, "vllm_models_dir": u_vllm, "inference_profile": u_inf_profile, + "mission_preferences": _u.get("mission_preferences", {}), + "candidate_accessibility_focus": u_access_focus, + "candidate_lgbtq_focus": u_lgbtq_focus, "services": { "streamlit_port": _svc["streamlit_port"], "ollama_host": svc_ollama_host, "ollama_port": int(svc_ollama_port), diff --git a/config/llm.yaml b/config/llm.yaml index 75c4d67..45f0f44 100644 --- a/config/llm.yaml +++ b/config/llm.yaml @@ -23,7 +23,7 @@ backends: api_key: ollama base_url: http://localhost:11434/v1 enabled: true - model: meghan-cover-writer:latest + model: llama3.2:3b # replace with your fine-tuned cover letter model if you have one type: openai_compat supports_images: false ollama_research: @@ -61,6 +61,6 @@ vision_fallback_order: - vision_service - claude_code - anthropic -# Note: 'ollama' (meghan-cover-writer) intentionally excluded — research -# must never use the fine-tuned writer model, and this also avoids evicting +# Note: 'ollama' intentionally excluded from research order — research +# must never use the cover letter model, and this also avoids evicting # the writer from GPU memory while a cover letter task is in flight. diff --git a/config/search_profiles.yaml b/config/search_profiles.yaml index bada59a..252223d 100644 --- a/config/search_profiles.yaml +++ b/config/search_profiles.yaml @@ -1,5 +1,22 @@ +# Search profiles — define one or more named profiles with different +# job titles, locations, boards, and keyword filters. +# The first profile is used by default in the Job Review and Discovery pages. +# +# Each profile supports: +# name — identifier shown in the UI +# titles — job titles to search (exact phrases) +# locations — "Remote" or city/metro strings +# boards — standard boards: linkedin, indeed, glassdoor, zip_recruiter, google +# custom_boards — extra boards: adzuna, theladders, craigslist +# exclude_keywords — filter out postings containing these phrases +# hours_old — only return jobs posted within this many hours +# results_per_board — max results per board per run +# mission_tags — optional tags that influence cover-letter mission alignment +# (must match a key in mission_preferences in user.yaml) + profiles: -- boards: +- name: primary + boards: - linkedin - indeed - glassdoor @@ -7,117 +24,16 @@ profiles: - google custom_boards: - adzuna - - theladders - craigslist + titles: + - "Your Target Title" + - "Alternative Title" + locations: + - Remote exclude_keywords: - sales - account executive - - sales engineer - SDR - BDR - - business development - - sales development - - sales manager - - sales representative - - sales rep hours_old: 240 - locations: - - Remote - - San Francisco Bay Area, CA - name: cs_leadership - results_per_board: 75 - titles: - - Customer Success Manager - - Customer Engagement Manager - - Director of Customer Success - - VP Customer Success - - Head of Customer Success - - Technical Account Manager - - TAM - - Customer Experience Lead - - CSM - - CX - - Customer Success Consultant -- boards: - - linkedin - - indeed - custom_boards: - - adzuna - - craigslist - exclude_keywords: - - sales - - account executive - - SDR - - BDR - - sales development - hours_old: 336 - locations: - - Remote - - San Francisco Bay Area, CA - mission_tags: - - music - name: music_industry results_per_board: 50 - titles: - - Customer Success Manager - - Partner Success Manager - - Artist Success Manager - - Creator Success Manager - - Technical Account Manager - - Community Manager - - Account Manager - - Label Relations Manager -- boards: - - linkedin - - indeed - custom_boards: - - adzuna - - craigslist - exclude_keywords: - - sales - - account executive - - SDR - - BDR - hours_old: 336 - locations: - - Remote - - San Francisco Bay Area, CA - mission_tags: - - animal_welfare - name: animal_welfare - results_per_board: 50 - titles: - - Customer Success Manager - - Program Manager - - Community Engagement Manager - - Operations Manager - - Partner Success Manager - - Account Manager - - Development Manager -- boards: - - linkedin - - indeed - custom_boards: - - adzuna - - craigslist - exclude_keywords: - - sales - - account executive - - SDR - - BDR - hours_old: 336 - locations: - - Remote - - San Francisco Bay Area, CA - mission_tags: - - education - name: education - results_per_board: 50 - titles: - - Customer Success Manager - - District Success Manager - - Implementation Specialist - - Partner Success Manager - - Account Manager - - School Success Manager - - Customer Experience Manager diff --git a/config/user.yaml.example b/config/user.yaml.example index ef7c90a..c015a98 100644 --- a/config/user.yaml.example +++ b/config/user.yaml.example @@ -21,11 +21,15 @@ mission_preferences: animal_welfare: "" # e.g. "I volunteer at my local shelter every weekend" education: "" # e.g. "I tutored underserved kids for 3 years and care deeply about literacy" -# Set to true to include an Inclusion & Accessibility section in research briefs. -# When true, each company brief will assess disability/ADA accommodation signals, -# ERGs, and accessibility culture. Useful if this is a personal factor in your decisions. +# Set to true to include optional identity-related sections in research briefs. +# Both are for your personal decision-making only — never included in applications. + +# Adds a disability inclusion & accessibility section (ADA, ERGs, WCAG signals). candidate_accessibility_focus: false +# Adds an LGBTQIA+ inclusion section (ERGs, non-discrimination policies, culture signals). +candidate_lgbtq_focus: false + docs_dir: "~/Documents/JobSearch" ollama_models_dir: "~/models/ollama" vllm_models_dir: "~/models/vllm" diff --git a/scripts/company_research.py b/scripts/company_research.py index 1fd6a3a..bdab12b 100644 --- a/scripts/company_research.py +++ b/scripts/company_research.py @@ -371,7 +371,8 @@ def research_company(job: dict, use_scraper: bool = True, on_stage=None) -> dict name = _profile.name if _profile else "the candidate" career_summary = _profile.career_summary if _profile else "" accessibility_focus = _profile.candidate_accessibility_focus if _profile else False - _section_count = 8 if accessibility_focus else 7 + lgbtq_focus = _profile.candidate_lgbtq_focus if _profile else False + _section_count = 7 + (1 if accessibility_focus else 0) + (1 if lgbtq_focus else 0) _accessibility_section = """ ## Inclusion & Accessibility Assess {company}'s commitment to disability inclusion and accessibility. Cover: @@ -383,6 +384,17 @@ Assess {company}'s commitment to disability inclusion and accessibility. Cover: If no specific signals are found, say so clearly — absence of public commitment is itself signal. This section is for the candidate's personal decision-making only and will not appear in any application. """.format(company=company) if accessibility_focus else "" + _lgbtq_section = """ +## LGBTQIA+ Inclusion +Assess {company}'s culture and policies around LGBTQIA+ inclusion. Cover: +- Non-discrimination policies that explicitly include sexual orientation and gender identity +- LGBTQIA+ Employee Resource Group (ERG) or Pride Network +- Benefits that support LGBTQIA+ employees (gender-affirming care, domestic partner benefits) +- Public statements, donations, or advocacy (Pride sponsorships, HRC Corporate Equality Index rating) +- Glassdoor or press signals about how LGBTQIA+ employees experience the company day-to-day +If no specific signals are found, say so clearly — absence of public commitment is itself signal. +This section is for the candidate's personal decision-making only and will not appear in any application. +""".format(company=company) if lgbtq_focus else "" prompt = f"""You are preparing {name} for a job interview. {f"Candidate background: {career_summary}" if career_summary else ""} @@ -421,7 +433,7 @@ Draw on the live snippets above; if none available, note what is publicly known. Culture issues, layoffs, exec departures, financial stress, or Glassdoor concerns worth knowing before the call. If nothing notable, write "No significant red flags identified." -{_accessibility_section} +{_lgbtq_section}{_accessibility_section} ## Talking Points for {name} Five specific talking points for the phone screen. Each must: - Reference a concrete experience from {name}'s matched background by name diff --git a/scripts/manage-vllm.sh b/scripts/manage-vllm.sh index 8386e20..b16bffc 100755 --- a/scripts/manage-vllm.sh +++ b/scripts/manage-vllm.sh @@ -4,8 +4,8 @@ set -euo pipefail -VLLM_BIN="/devl/miniconda3/envs/vllm/bin/python" -MODEL_DIR="/Library/Assets/LLM/vllm/models" +VLLM_BIN="${VLLM_BIN:-python3}" +MODEL_DIR="${VLLM_MODELS_DIR:-${HOME}/models/vllm}" PID_FILE="/tmp/vllm-server.pid" LOG_FILE="/tmp/vllm-server.log" MODEL_FILE="/tmp/vllm-server.model" diff --git a/scripts/user_profile.py b/scripts/user_profile.py index 72437d4..a7b340f 100644 --- a/scripts/user_profile.py +++ b/scripts/user_profile.py @@ -22,6 +22,7 @@ _DEFAULTS = { "inference_profile": "remote", "mission_preferences": {}, "candidate_accessibility_focus": False, + "candidate_lgbtq_focus": False, "services": { "streamlit_port": 8501, "ollama_host": "localhost", @@ -62,6 +63,7 @@ class UserProfile: self.inference_profile: str = data["inference_profile"] self.mission_preferences: dict[str, str] = data.get("mission_preferences", {}) self.candidate_accessibility_focus: bool = bool(data.get("candidate_accessibility_focus", False)) + self.candidate_lgbtq_focus: bool = bool(data.get("candidate_lgbtq_focus", False)) self._svc = data["services"] # ── Service URLs ──────────────────────────────────────────────────────────