# Copy to backend/.env and fill in your OpenRouter key. AI_BASE_URL=https://openrouter.ai/api/v1 AI_API_KEY=sk-or-... MODEL=google/gemini-2.5-pro # Optional Agent-mode OpenRouter model overrides (inherit MODEL/TEXT_MODEL when blank) AGENT_EXTRACT_MODEL= AGENT_INDEX_MODEL= AGENT_JURISDICTION_MODEL= AGENT_LINKER_MODEL= AGENT_CONFLICT_MODEL= AGENT_CODE_MODEL= AGENT_CONSTRUCT_MODEL= AGENT_COMPLETENESS_MODEL= AGENT_BRAIN_MODEL= AGENT_RFI_MODEL= # Agent-mode hard scope limits / concurrency AGENT_LINK_MAX_ASSERTIONS=60 AGENT_CLUSTER_MAX_ASSERTIONS=24 AGENT_CONFLICT_MAX_IMAGES=6 AGENT_CODE_BATCH_SIZE=60 AGENT_BRAIN_MAX_TOKENS=16384 AGENT_LINK_CONCURRENCY=4 AGENT_CONFLICT_CONCURRENCY=4 AGENT_SPECIALIST_CONCURRENCY=4 AGENT_RFI_CONCURRENCY=4 # -- Review focus toggles ------------------------------------------- # ENABLE_CODE_REVIEW: run the code/ADA/jurisdiction review path (both pipelines). # Default OFF - the product focuses on drawing integrity and cross-discipline # coordination, not code/accessibility compliance. Set to 1 to restore it. ENABLE_CODE_REVIEW=false # ENABLE_DRAWING_INTEGRITY: per-sheet Drawing Integrity QA wave (both pipelines). # The drawing-focused pass - dangling references, on-sheet contradictions, # dimension sanity, missing sheet essentials, tag hygiene. Default ON. ENABLE_DRAWING_INTEGRITY=true AGENT_INTEGRITY_MODEL= AGENT_INTEGRITY_CONCURRENCY=4 AGENT_INTEGRITY_MAX_IMAGES=1 AGENT_INTEGRITY_MAX_ASSERTIONS=80 INTEGRITY_MAX_TOKENS=16384 # Skip sheets with fewer than this many extracted objects (too sparse to check) INTEGRITY_MIN_ASSERTIONS=3 # Agent-mode human-review gate (pipeline stops after Brain until a human reviews) AGENT_REQUIRE_REVIEW=true # Max clean clusters added to the review queue as non-blocking spot-checks AGENT_REVIEW_AUDIT_SAMPLE=5 # Allow future cross-job review-feedback aggregation to include source_text/images/comments REVIEW_AGGREGATE_INCLUDE_TEXT=false # Pipeline tuning PDF_DPI=100 MAX_PAGES=60 MAX_DIMENSION=2400 LLM_TIMEOUT=180 EXTRACT_MAX_TOKENS=65536 # Reasoning effort for per-sheet extraction (low keeps Gemini thinking tokens # from eating the output budget). Blank = don't send the parameter. EXTRACT_REASONING_EFFORT=low # Hard thinking-token budget for extraction (OpenRouter reasoning max_tokens / # Gemini thinking_budget). Stronger than effort; 0 = fall back to effort only. EXTRACT_REASONING_MAX_TOKENS=2048 REASON_MAX_TOKENS=4096 EXTRACT_CONCURRENCY=4 REASON_CONCURRENCY=4 # Public URL users reach this server on (used for the link in result emails) APP_BASE_URL=https://conchecker.scoutitsystems.com # APP_BUILD is set by CI at image build time (sha-) - do not set manually. # LLM observability (job-log verbosity + raw request/response dumps) # LLM_VERBOSE: one line per LLM call in job.log (model, sizes, item counts, cost) # LLM_RAW_DUMP: full prompt+response per call in outputs//llm_raw/ # (base64 images excluded). Both default on; set false to quiet down. LLM_VERBOSE=true LLM_RAW_DUMP=true # Email notifications (optional). Leave SMTP_HOST blank to disable. # Examples: # Gmail: SMTP_HOST=smtp.gmail.com SMTP_PORT=587 (use an App Password) # M365: SMTP_HOST=smtp.office365.com SMTP_PORT=587 SMTP_HOST= SMTP_PORT=587 SMTP_USER= SMTP_PASSWORD= SMTP_FROM= SMTP_USE_TLS=true SMTP_USE_SSL=false # Wave 5b evidence verification (vision fact-check of cited sheet text) AGENT_VERIFY_MAX_CHECKS=20 AGENT_VERIFY_SEVERITIES=critical,high AGENT_VERIFY_REASONING_EFFORT=low VERIFY_MAX_TOKENS=8192 # Wave 6.5 Brain-directed clarification (bounded hub-and-spoke). After the Brain # merge, the Brain names findings it is unsure about; verify_evidence requests # route back through the wave-5b verifier. One planning call + at most # BRAIN_CLARIFY_MAX_REQUESTS verifications, single iteration. Default ON. ENABLE_BRAIN_CLARIFY=true BRAIN_CLARIFY_MAX_REQUESTS=8 BRAIN_CLARIFY_MAX_TOKENS=4096 # Text-layer grounding (deterministic PDF text layer via PyMuPDF) # TEXT_LAYER_ENABLED: master switch for text-layer extraction/grounding # TEXT_LAYER_MIN_CHARS: below this per page the sheet stays vision-only # TEXT_LAYER_MAX_CHARS: cap of text layer injected into the extractor prompt # VERIFY_TEXT_MAX_CHARS: cap of the text-layer excerpt in verify scopes # VERIFY_HI_DPI_CROPS: evidence-located high-DPI crops in the verifier # VERIFY_CROP_DPI / VERIFY_CROP_MARGIN_PTS: crop render DPI / padding (PDF points) TEXT_LAYER_ENABLED=true TEXT_LAYER_MIN_CHARS=20 TEXT_LAYER_MAX_CHARS=12000 VERIFY_TEXT_MAX_CHARS=8000 VERIFY_HI_DPI_CROPS=true VERIFY_CROP_DPI=300 VERIFY_CROP_MARGIN_PTS=36