feat: LGBTQIA+ focus + Phase 2/3 audit fixes
LGBTQIA+ inclusion section in research briefs: - user_profile.py: add candidate_lgbtq_focus bool accessor - user.yaml.example: add candidate_lgbtq_focus flag (default false) - company_research.py: gate new LGBTQIA+ section behind flag; section count now dynamic (7 base + 1 per opt-in section, max 9) - 2_Settings.py: add "Research Brief Preferences" expander with checkboxes for both accessibility and LGBTQIA+ focus flags; mission_preferences now round-trips through save (no silent drop) Phase 2 fixes: - manage-vllm.sh: MODEL_DIR and VLLM_BIN now read from env vars (VLLM_MODELS_DIR, VLLM_BIN) with portable defaults - search_profiles.yaml: replace personal CS/TAM/Bay Area profiles with a documented generic starter profile Phase 3 fix: - llm.yaml: rename alex-cover-writer:latest → llama3.2:3b with inline comment for users to substitute their fine-tuned model; fix model-exclusion comment
This commit is contained in:
parent
7d6ce555f0
commit
2d1c48e7af
7 changed files with 67 additions and 117 deletions
|
|
@ -121,6 +121,19 @@ with tab_profile:
|
||||||
if nb.button("+ Add", key="add_nda") and new_nda.strip():
|
if nb.button("+ Add", key="add_nda") and new_nda.strip():
|
||||||
nda_list.append(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"):
|
with st.expander("📁 File Paths"):
|
||||||
u_docs = st.text_input("Documents directory", _u.get("docs_dir", "~/Documents/JobSearch"))
|
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"))
|
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,
|
"nda_companies": nda_list,
|
||||||
"docs_dir": u_docs, "ollama_models_dir": u_ollama, "vllm_models_dir": u_vllm,
|
"docs_dir": u_docs, "ollama_models_dir": u_ollama, "vllm_models_dir": u_vllm,
|
||||||
"inference_profile": u_inf_profile,
|
"inference_profile": u_inf_profile,
|
||||||
|
"mission_preferences": _u.get("mission_preferences", {}),
|
||||||
|
"candidate_accessibility_focus": u_access_focus,
|
||||||
|
"candidate_lgbtq_focus": u_lgbtq_focus,
|
||||||
"services": {
|
"services": {
|
||||||
"streamlit_port": _svc["streamlit_port"],
|
"streamlit_port": _svc["streamlit_port"],
|
||||||
"ollama_host": svc_ollama_host, "ollama_port": int(svc_ollama_port),
|
"ollama_host": svc_ollama_host, "ollama_port": int(svc_ollama_port),
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ backends:
|
||||||
api_key: ollama
|
api_key: ollama
|
||||||
base_url: http://localhost:11434/v1
|
base_url: http://localhost:11434/v1
|
||||||
enabled: true
|
enabled: true
|
||||||
model: alex-cover-writer:latest
|
model: llama3.2:3b # replace with your fine-tuned cover letter model if you have one
|
||||||
type: openai_compat
|
type: openai_compat
|
||||||
supports_images: false
|
supports_images: false
|
||||||
ollama_research:
|
ollama_research:
|
||||||
|
|
@ -61,6 +61,6 @@ vision_fallback_order:
|
||||||
- vision_service
|
- vision_service
|
||||||
- claude_code
|
- claude_code
|
||||||
- anthropic
|
- anthropic
|
||||||
# Note: 'ollama' (alex-cover-writer) intentionally excluded — research
|
# Note: 'ollama' intentionally excluded from research order — research
|
||||||
# must never use the fine-tuned writer model, and this also avoids evicting
|
# 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.
|
# the writer from GPU memory while a cover letter task is in flight.
|
||||||
|
|
|
||||||
|
|
@ -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:
|
profiles:
|
||||||
- boards:
|
- name: primary
|
||||||
|
boards:
|
||||||
- linkedin
|
- linkedin
|
||||||
- indeed
|
- indeed
|
||||||
- glassdoor
|
- glassdoor
|
||||||
|
|
@ -7,117 +24,16 @@ profiles:
|
||||||
- google
|
- google
|
||||||
custom_boards:
|
custom_boards:
|
||||||
- adzuna
|
- adzuna
|
||||||
- theladders
|
|
||||||
- craigslist
|
- craigslist
|
||||||
|
titles:
|
||||||
|
- "Your Target Title"
|
||||||
|
- "Alternative Title"
|
||||||
|
locations:
|
||||||
|
- Remote
|
||||||
exclude_keywords:
|
exclude_keywords:
|
||||||
- sales
|
- sales
|
||||||
- account executive
|
- account executive
|
||||||
- sales engineer
|
|
||||||
- SDR
|
- SDR
|
||||||
- BDR
|
- BDR
|
||||||
- business development
|
|
||||||
- sales development
|
|
||||||
- sales manager
|
|
||||||
- sales representative
|
|
||||||
- sales rep
|
|
||||||
hours_old: 240
|
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
|
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
|
|
||||||
|
|
|
||||||
|
|
@ -21,11 +21,15 @@ mission_preferences:
|
||||||
animal_welfare: "" # e.g. "I volunteer at my local shelter every weekend"
|
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"
|
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.
|
# Set to true to include optional identity-related sections in research briefs.
|
||||||
# When true, each company brief will assess disability/ADA accommodation signals,
|
# Both are for your personal decision-making only — never included in applications.
|
||||||
# ERGs, and accessibility culture. Useful if this is a personal factor in your decisions.
|
|
||||||
|
# Adds a disability inclusion & accessibility section (ADA, ERGs, WCAG signals).
|
||||||
candidate_accessibility_focus: false
|
candidate_accessibility_focus: false
|
||||||
|
|
||||||
|
# Adds an LGBTQIA+ inclusion section (ERGs, non-discrimination policies, culture signals).
|
||||||
|
candidate_lgbtq_focus: false
|
||||||
|
|
||||||
docs_dir: "~/Documents/JobSearch"
|
docs_dir: "~/Documents/JobSearch"
|
||||||
ollama_models_dir: "~/models/ollama"
|
ollama_models_dir: "~/models/ollama"
|
||||||
vllm_models_dir: "~/models/vllm"
|
vllm_models_dir: "~/models/vllm"
|
||||||
|
|
|
||||||
|
|
@ -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"
|
name = _profile.name if _profile else "the candidate"
|
||||||
career_summary = _profile.career_summary if _profile else ""
|
career_summary = _profile.career_summary if _profile else ""
|
||||||
accessibility_focus = _profile.candidate_accessibility_focus if _profile else False
|
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 = """
|
_accessibility_section = """
|
||||||
## Inclusion & Accessibility
|
## Inclusion & Accessibility
|
||||||
Assess {company}'s commitment to disability inclusion and accessibility. Cover:
|
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.
|
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.
|
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 ""
|
""".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.
|
prompt = f"""You are preparing {name} for a job interview.
|
||||||
{f"Candidate background: {career_summary}" if career_summary else ""}
|
{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.
|
Culture issues, layoffs, exec departures, financial stress, or Glassdoor concerns worth knowing before the call.
|
||||||
If nothing notable, write "No significant red flags identified."
|
If nothing notable, write "No significant red flags identified."
|
||||||
|
|
||||||
{_accessibility_section}
|
{_lgbtq_section}{_accessibility_section}
|
||||||
## Talking Points for {name}
|
## Talking Points for {name}
|
||||||
Five specific talking points for the phone screen. Each must:
|
Five specific talking points for the phone screen. Each must:
|
||||||
- Reference a concrete experience from {name}'s matched background by name
|
- Reference a concrete experience from {name}'s matched background by name
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@
|
||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
VLLM_BIN="/devl/miniconda3/envs/vllm/bin/python"
|
VLLM_BIN="${VLLM_BIN:-python3}"
|
||||||
MODEL_DIR="/Library/Assets/LLM/vllm/models"
|
MODEL_DIR="${VLLM_MODELS_DIR:-${HOME}/models/vllm}"
|
||||||
PID_FILE="/tmp/vllm-server.pid"
|
PID_FILE="/tmp/vllm-server.pid"
|
||||||
LOG_FILE="/tmp/vllm-server.log"
|
LOG_FILE="/tmp/vllm-server.log"
|
||||||
MODEL_FILE="/tmp/vllm-server.model"
|
MODEL_FILE="/tmp/vllm-server.model"
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ _DEFAULTS = {
|
||||||
"inference_profile": "remote",
|
"inference_profile": "remote",
|
||||||
"mission_preferences": {},
|
"mission_preferences": {},
|
||||||
"candidate_accessibility_focus": False,
|
"candidate_accessibility_focus": False,
|
||||||
|
"candidate_lgbtq_focus": False,
|
||||||
"services": {
|
"services": {
|
||||||
"streamlit_port": 8501,
|
"streamlit_port": 8501,
|
||||||
"ollama_host": "localhost",
|
"ollama_host": "localhost",
|
||||||
|
|
@ -62,6 +63,7 @@ class UserProfile:
|
||||||
self.inference_profile: str = data["inference_profile"]
|
self.inference_profile: str = data["inference_profile"]
|
||||||
self.mission_preferences: dict[str, str] = data.get("mission_preferences", {})
|
self.mission_preferences: dict[str, str] = data.get("mission_preferences", {})
|
||||||
self.candidate_accessibility_focus: bool = bool(data.get("candidate_accessibility_focus", False))
|
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"]
|
self._svc = data["services"]
|
||||||
|
|
||||||
# ── Service URLs ──────────────────────────────────────────────────────────
|
# ── Service URLs ──────────────────────────────────────────────────────────
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue