Download config.py from codegood/job-chat: direct link, hf CLI and curl.
- Browser
- Download file 4.34 kB
-
https://huggingface.co/spaces/codegood/job-chat/resolve/main/config.py
- Command line
-
hf download hf://spaces/codegood/job-chat/config.py
-
curl -L -o config.py https://huggingface.co/spaces/codegood/job-chat/resolve/main/config.py
4.34 kB
| """Application configuration, loaded once from the environment.""" | |
| import os | |
| from dataclasses import dataclass | |
| from functools import lru_cache | |
| from pathlib import Path | |
| from dotenv import load_dotenv | |
| load_dotenv() | |
| PROJECT_ROOT = Path(__file__).parent | |
| DEFAULT_MODEL = "openrouter/free" | |
| OPENROUTER_BASE_URL = "https://openrouter.ai/api/v1" | |
| DEFAULT_TEMPERATURE = 0.0 | |
| # Drafting a cover letter is writing, not analysis: a little sampling gives | |
| # natural prose. Kept low so it does not start inventing detail. | |
| DEFAULT_DRAFTING_TEMPERATURE = 0.4 | |
| # The preset actions (ATS keyword tables, detailed reviews) run long, so 2048 | |
| # truncated them mid-answer. This leaves room for the profile, job description, | |
| # and conversation history while avoiding an unnecessarily large response cap. | |
| DEFAULT_MAX_TOKENS = 20000 | |
| # Prose skill output gets its own response cap. | |
| DEFAULT_SKILL_MAX_TOKENS = 6500 | |
| # ATS returns a structured classification for every keyword, so it needs more | |
| # output room than the prose skills. | |
| DEFAULT_ATS_MAX_TOKENS = 12000 | |
| DEFAULT_LANGFUSE_HOST = "https://cloud.langfuse.com" | |
| DEFAULT_CHECKPOINT_DB = "checkpoints.sqlite" | |
| # Turns of conversation replayed to the model. Older turns stay in the | |
| # checkpoint (nothing is deleted) but are not resent. | |
| DEFAULT_MAX_HISTORY_TURNS = 10 | |
| # Routing and retrieval. ONNX runtime, so no torch dependency. | |
| DEFAULT_EMBEDDING_MODEL = "sentence-transformers/all-MiniLM-L6-v2" | |
| DEFAULT_RETRIEVAL_TOP_K = 10 | |
| class ConfigError(RuntimeError): | |
| """Raised when the environment is missing or misconfigured.""" | |
| class Settings: | |
| openrouter_api_key: str | |
| candidate_name: str | |
| model: str | |
| temperature: float | |
| drafting_temperature: float | |
| max_tokens: int | |
| skill_max_tokens: int | |
| ats_max_tokens: int | |
| max_history_turns: int | |
| embedding_model: str | |
| retrieval_top_k: int | |
| checkpoint_db: Path | |
| langfuse_public_key: str | |
| langfuse_secret_key: str | |
| langfuse_host: str | |
| def tracing_enabled(self) -> bool: | |
| """Tracing turns itself on only when both Langfuse keys are present.""" | |
| return bool(self.langfuse_public_key and self.langfuse_secret_key) | |
| def _get_float(name, default): | |
| raw = os.getenv(name) | |
| if raw is None or not raw.strip(): | |
| return default | |
| try: | |
| return float(raw) | |
| except ValueError: | |
| raise ConfigError(f"{name} must be a number, got {raw!r}") | |
| def _get_int(name, default): | |
| raw = os.getenv(name) | |
| if raw is None or not raw.strip(): | |
| return default | |
| try: | |
| return int(raw) | |
| except ValueError: | |
| raise ConfigError(f"{name} must be an integer, got {raw!r}") | |
| def get_settings(require_api_key=True) -> Settings: | |
| api_key = os.getenv("OPENROUTER_API_KEY", "").strip() | |
| if require_api_key and not api_key: | |
| raise ConfigError("OPENROUTER_API_KEY is not set. Add it to your .env file.") | |
| return Settings( | |
| openrouter_api_key=api_key, | |
| candidate_name=os.getenv("CANDIDATE_NAME", "").strip() or "the candidate", | |
| model=os.getenv("OPENROUTER_MODEL", "").strip() or DEFAULT_MODEL, | |
| temperature=_get_float("LLM_TEMPERATURE", DEFAULT_TEMPERATURE), | |
| drafting_temperature=_get_float("LLM_DRAFTING_TEMPERATURE", DEFAULT_DRAFTING_TEMPERATURE), | |
| max_tokens=_get_int("LLM_MAX_TOKENS", DEFAULT_MAX_TOKENS), | |
| skill_max_tokens=_get_int("SKILL_MAX_TOKENS", DEFAULT_SKILL_MAX_TOKENS), | |
| ats_max_tokens=_get_int("ATS_MAX_TOKENS", DEFAULT_ATS_MAX_TOKENS), | |
| max_history_turns=_get_int("MAX_HISTORY_TURNS", DEFAULT_MAX_HISTORY_TURNS), | |
| embedding_model=os.getenv("EMBEDDING_MODEL", "").strip() or DEFAULT_EMBEDDING_MODEL, | |
| retrieval_top_k=_get_int("RETRIEVAL_TOP_K", DEFAULT_RETRIEVAL_TOP_K), | |
| checkpoint_db=PROJECT_ROOT / ( | |
| os.getenv("CHECKPOINT_DB", "").strip() or DEFAULT_CHECKPOINT_DB | |
| ), | |
| langfuse_public_key=os.getenv("LANGFUSE_PUBLIC_KEY", "").strip(), | |
| langfuse_secret_key=os.getenv("LANGFUSE_SECRET_KEY", "").strip(), | |
| # LANGFUSE_HOST is the SDK's own name; LANGFUSE_BASE_URL is accepted as an alias. | |
| langfuse_host=( | |
| os.getenv("LANGFUSE_HOST", "").strip() | |
| or os.getenv("LANGFUSE_BASE_URL", "").strip() | |
| or DEFAULT_LANGFUSE_HOST | |
| ), | |
| ) | |