Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
93415ce
Add geothermal extraction integration artifacts
bpulluta Mar 17, 2026
d9e868d
Add COMPASS workflow skills
bpulluta Mar 17, 2026
54b8d29
Added one-shot skills
bpulluta Mar 17, 2026
a71447f
update one-shot SKILL.md structure and trigger contracts
bpulluta Mar 17, 2026
74495a6
Initial plan (#398)
Copilot Mar 17, 2026
81fcbff
Fix skills documentation: correct paths, caching behavior, and tab fo…
Copilot Mar 17, 2026
1b8571f
renamed skills and fixed minor comments
bpulluta Mar 19, 2026
bc1a516
Merge branch 'feature/skills-pr' into feature/geothermal-extraction-pr
bpulluta Mar 20, 2026
61f9b2e
fix URL space encoding and anchor text scoring in website crawl retri…
bpulluta Mar 20, 2026
bac918c
remove testing skills
bpulluta Mar 20, 2026
dab97ff
fixed schema
bpulluta Mar 21, 2026
c6eb335
Refactor URL sanitization: shared helper, space-only encoding, robust…
Copilot Mar 21, 2026
93ad791
Bump release-drafter/release-drafter from 7.0.0 to 7.1.1 (#402)
dependabot[bot] Mar 24, 2026
a0fbd55
Add One-Shot Skills Reliability and Guardrails (#397)
bpulluta Mar 26, 2026
56fe389
updated schema, added cli overwrite option, and added optional post p…
bpulluta Mar 30, 2026
87e72d3
fix ruff error in components.py
bpulluta Mar 31, 2026
eaaab54
ruff check on components.py
bpulluta Mar 31, 2026
ca3aaac
fix ruff errors in process.py
bpulluta Mar 31, 2026
7ea2627
ruff check on updated files
bpulluta Mar 31, 2026
197a98c
Bump codecov/codecov-action from 5 to 6 (#403)
dependabot[bot] Mar 30, 2026
633ecdf
Merge remote-tracking branch 'origin/main' into feature/geothermal-ex…
ppinchuk Mar 31, 2026
a9c8929
Update tox file
ppinchuk Mar 31, 2026
314af43
Update tox file
ppinchuk Mar 31, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 105 additions & 2 deletions compass/_cli/process.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@

import asyncio
import logging
import shutil
import sys
import warnings
import multiprocessing
from pathlib import Path

import click
from rich.live import Live
Expand All @@ -14,8 +17,11 @@
from compass.pb import COMPASS_PB
from compass.plugin import create_schema_based_one_shot_extraction_plugin
from compass.scripts.process import process_jurisdictions_with_openai
from compass.utilities.logs import AddLocationFilter
from compass.utilities.io import load_config
from compass.utilities.logs import AddLocationFilter


OUT_DIR_POLICY_CHOICES = ["fail", "increment", "overwrite", "prompt"]


@click.command
Expand Down Expand Up @@ -49,10 +55,30 @@
default=None,
help="One-shot plugin configuration to add to COMPASS before processing",
)
def process(config, verbose, no_progress, plugin):
@click.option(
"--out_dir_exists",
required=False,
default=None,
type=click.Choice(OUT_DIR_POLICY_CHOICES, case_sensitive=False),
help="How to handle an existing output directory."
" Choices: fail, increment, overwrite, prompt."
" If omitted, prompts interactively when running in a terminal,"
" or fails when running non-interactively (e.g. CI).",
)
def process(config, verbose, no_progress, plugin, out_dir_exists):
"""Download and extract ordinances for a list of jurisdictions"""
config = load_config(config)

if out_dir_exists is not None:
out_dir_policy = out_dir_exists
elif sys.stdin.isatty():
out_dir_policy = "prompt"
else:
out_dir_policy = "fail"
Comment on lines +72 to +77
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move this to be inside of _resolve_out_dir_conflict. This helps keep things organized

config["out_dir"] = _resolve_out_dir_conflict(
config["out_dir"], out_dir_policy
)

if plugin is not None:
create_schema_based_one_shot_extraction_plugin(
config=plugin, tech=config["tech"]
Expand Down Expand Up @@ -128,3 +154,80 @@ def _setup_cli_logging(console, verbosity_level, log_level="INFO"):
handler.addFilter(AddLocationFilter())
logger.addHandler(handler)
logger.setLevel(log_level)


def _resolve_out_dir_conflict(out_dir, policy):
"""Handle existing output directory using the selected policy"""
out_dir = Path(out_dir)
policy = policy.lower()

if not out_dir.exists():
return out_dir

if policy == "fail":
return out_dir
Comment on lines +164 to +168
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please combine these into if not out_dir.exists() or policy == "fail"


if policy == "increment":
new_out_dir = _next_versioned_directory(out_dir)
click.echo(
"Output directory exists. "
f"Using incremented directory: {new_out_dir!s}"
)
return new_out_dir

if policy == "overwrite":
click.echo(f"Overwriting existing output directory: {out_dir!s}")
shutil.rmtree(out_dir)
return out_dir

if policy == "prompt":
if not sys.stdin.isatty():
msg = (
"Cannot use out_dir_exists='prompt' in non-interactive mode. "
"Use one of: fail, increment, overwrite."
)
raise click.ClickException(msg)

create_incremented = click.confirm(
f"Output directory '{out_dir!s}' already exists. "
"Create a new incremented directory automatically?",
default=True,
)
if create_incremented:
new_out_dir = _next_versioned_directory(out_dir)
click.echo(f"Using incremented directory: {new_out_dir!s}")
return new_out_dir

overwrite = click.confirm(
f"Overwrite '{out_dir!s}' by deleting it and continuing?",
default=False,
)
if overwrite:
click.echo(f"Overwriting existing output directory: {out_dir!s}")
shutil.rmtree(out_dir)
return out_dir

msg = (
"Run cancelled. Please update out_dir in config, or rerun with "
"--out_dir_exists increment/overwrite."
)
raise click.ClickException(msg)
Comment on lines +184 to +214
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please move this logic into a separate function for code clarity


msg = (
f"Unknown out_dir_exists policy '{policy}'. "
f"Supported values: {OUT_DIR_POLICY_CHOICES}."
)
raise click.ClickException(msg)


def _next_versioned_directory(out_dir):
"""
Create the next available output directory suffix with
versioning
"""
idx = 2
while True:
candidate = out_dir.parent / f"{out_dir.name}_v{idx}"
if not candidate.exists():
return candidate
idx += 1
Comment on lines +229 to +233
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a guard (e.g. if index goes over 1k or even 1M) to prevent infinite loops

Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
schema: ./geothermal_schema.json

data_type_short_desc: utility-scale geothermal electricity ordinance

cache_llm_generated_content: true

query_templates:
- "filetype:pdf {jurisdiction} geothermal power plant ordinance"
- "geothermal electricity generation ordinance {jurisdiction}"
- "{jurisdiction} geothermal energy facility zoning ordinance"
- "{jurisdiction} geothermal power plant land use code"
- "{jurisdiction} geothermal code of ordinances"
- "{jurisdiction} geothermal conditional use permit"
- "{jurisdiction} geothermal special use permit"
- "{jurisdiction} geothermal drilling permit regulations"
- "{jurisdiction} geothermal resource development statute"
- "Where can I find the legal text for geothermal power plant zoning ordinances in {jurisdiction}?"
- "What is the specific legal information regarding zoning ordinances for geothermal electricity generation facilities in {jurisdiction}?"

website_keywords:
pdf: 92160
geothermal: 46080
ordinance: 23040
zoning: 11520
regulation: 5760
code: 2880
power: 1440
electricity: 1440
planning: 720
permit: 720
land use: 720
municipal: 720
county: 360
ordinance code: 360
code of ordinances: 360
land use code: 360
use table: 360
chapter: 180
article: 180
title: 180
statute: 180
administrative code: 180
conditional use permit: 180
special use permit: 180
drilling permit: 180
resource development: 180
government: 180

heuristic_keywords:
good_tech_keywords:
- "wellfield"
- "well field"
- "production well"
- "geothermal exploration"
- "geothermal generating"
- "geothermal generation"
- "geothermal power"
- "geothermal production"
- "geothermal project"
- "geothermal overlay zone"
- "geothermal power plant"
- "geothermal facility"
- "geothermal electric"
- "geothermal energy facility"
- "steam turbine"
- "binary cycle"
- "flash steam"
- "dry steam"
- "enhanced geothermal"
- "reservoir temperature"
- "brine"
- "reinjection well"
- "production zone"
- "geothermal resource"
- "geothermal production project"
- "geothermal drilling"
- "exploratory well"
- "injection well"
- "geothermal lease"
- "drilling permit"
- "plan of utilization"
- "known geothermal resource"
- "geothermal development"
- "geothermal well"
- "geothermal reservoir"
- "geothermal permit"
- "geothermal ordinance"
- "geothermal zoning"
- "code of ordinances"
- "land use code"
- "use table"
- "zoning ordinance"
- "special use permit"
- "conditional use permit"
good_tech_acronyms:
- "egs"
- "kgra"
good_tech_phrases:
- "geothermal power plant"
- "geothermal electricity generation"
- "geothermal energy facility"
- "geothermal resource development"
- "known geothermal resource area"
- "binary cycle"
- "flash steam"
- "dry steam"
- "steam turbine"
- "plan of utilization"
- "land use code"
- "code of ordinances"
- "zoning ordinance"
- "special use permit"
- "conditional use permit"
not_tech_words:
- "geothermal heat pump"
- "ground source heat pump"
- "ground-source heat pump"
- "ghp"
- "ground heat pump"
- "gshp"
- "ground-coupled heat pump"
- "ground coupled heat pump"
- "earth-coupled heat pump"
- "earth-source heat pump"
- "geoexchange"
- "geo-exchange"
- "closed loop"
- "closed-loop"
- "open loop"
- "vertical loop"
- "horizontal loop"
- "heating and cooling"
- "hvac"
- "space heating"
- "water heating"
- "direct use"
- "direct-use"
- "district heating"
- "greenhouse heating"
- "residential geothermal"
- "accessory use"
- "energy star"
- "solar panel"
- "solar array"
- "solar farm"
- "solar energy system"
- "solar energy facility"
- "photovoltaic"
- "net metering"
- "solar collector"
- "solar ordinance"
- "wind energy"
- "wind farm"
- "wind turbine"
- "wind energy system"
- "wind energy facility"
- "wind energy conversion"
- "wind ordinance"
- "anemometer tower"
- "meteorological tower"
- "rotor diameter"
- "tip height"
- "nacelle"
- "battery storage"
- "energy storage system"
- "hydroelectric"
- "biomass"
- "cannabis"
- "cannabis cultivation"
- "commercial cannabis"
Loading
Loading