import os from pathlib import Path from dotenv import load_dotenv load_dotenv() BASE_DIR = Path(__file__).resolve().parent HF_TOKEN = os.getenv("HF_TOKEN") or os.getenv("HF_API_TOKEN") if HF_TOKEN is None: raise RuntimeError( "HF_TOKEN or HF_API_TOKEN is not set. " "Go to Space → Settings → Variables & secrets and add one." ) DEV = os.getenv("ENV") == "dev" OPENAI_MODEL = ( "gpt-5.6-luna" # luna is very cheap, we can keep it for both dev and prod ) GEMINI_MODEL = "gemini-2.5-flash-lite" if DEV else "gemini-3.6-flash" # Reasoning effort for gpt-oss-20b calls: "none" | "low" | "medium" | "high". # Each pipeline stage is independently tunable — e.g. the judge/attribution # checks may not need the same effort as the main answering loop. AGENT_REASONING_EFFORT = os.getenv("AGENT_REASONING_EFFORT", "medium") WIKI_SUBAGENT_REASONING_EFFORT = os.getenv("WIKI_SUBAGENT_REASONING_EFFORT", "medium") JUDGE_REASONING_EFFORT = os.getenv("JUDGE_REASONING_EFFORT", "medium") ATTRIBUTION_REASONING_EFFORT = os.getenv("ATTRIBUTION_REASONING_EFFORT", "medium") # pediatry_wiki_self_judge: one high-effort call judges its own draft, so no # external judge/attribution calls run — high by default on purpose. WIKI_SELF_JUDGE_REASONING_EFFORT = os.getenv("WIKI_SELF_JUDGE_REASONING_EFFORT", "high") FOUR_HOURS = 4 * 60 * 60 # 4 hours * 60 minutes * 60 seconds MAX_RAM_USAGE_PERCENT = 90 # Max history messages to keep for context MAX_HISTORY = 20 MAX_MESSAGE_LENGTH = 2500 MAX_COMMENT_LENGTH = 2500 MAX_RESPONSE_LENGTH = 5000 MAX_ID_LENGTH = 50 MAX_FILE_NAME_LENGTH = 200 MAX_FILE_SIZE = 10 * 1024 * 1024 # 10 MB FILE_CHUNK_SIZE = 1024 * 1024 # 1 MB MAX_FILE_SIZES_PER_SESSION = 30 * 1024 * 1024 # 30 MB TEXT_EXTRACTION_TIMEOUT = 10 # 10 seconds MAX_DOCUMENT_TOKENS = 30_000 SUPPORTED_FILE_EXTENSIONS = {".txt", ".pdf", ".docx", ".jpg", ".jpeg", ".png", ".heic"} SUPPORTED_FILE_TYPES = { "text/plain", # .txt "application/pdf", # .pdf "application/vnd.openxmlformats-officedocument.wordprocessingml.document", # .docx # TODO: magic can detect docx files as zip files, but not always. Under which conditions? # "application/zip", "image/jpeg", # .jpeg and .jpg "image/png", # .png "image/heic", # .heic } GENERIC_ERROR_REPLY = ( "Sorry, something went wrong while processing your message. " "It has been flagged and saved for our team to review." ) STATUS_CODE_BAD_REQUEST = 400 STATUS_CODE_CONFLICT = 409 STATUS_CODE_LENGTH_REQUIRED = 411 STATUS_CODE_CONTENT_TOO_LARGE = 413 STATUS_CODE_UNSUPPORTED_MEDIA_TYPE = 415 # Custom status code. Used when the user sends a file that would exceed the MAX_FILE_SIZES_PER_SESSION limit STATUS_CODE_EXCEED_SIZE_LIMIT = 419 STATUS_CODE_UNPROCESSABLE_CONTENT = 422 STATUS_CODE_INTERNAL_SERVER_ERROR = 500