Manages running a specific git version of the Hindsight API. For "HEAD" or "current", uses the current working directory. For git tags (e.g., "v0.3.0"), clones the repo at that tag to a temp directory.
| 29 | |
| 30 | |
| 31 | class VersionRunner: |
| 32 | """ |
| 33 | Manages running a specific git version of the Hindsight API. |
| 34 | |
| 35 | For "HEAD" or "current", uses the current working directory. |
| 36 | For git tags (e.g., "v0.3.0"), clones the repo at that tag to a temp directory. |
| 37 | """ |
| 38 | |
| 39 | def __init__( |
| 40 | self, |
| 41 | version: str, |
| 42 | db_url: str, |
| 43 | port: int = 8890, |
| 44 | llm_provider: str | None = None, |
| 45 | llm_api_key: str | None = None, |
| 46 | llm_model: str | None = None, |
| 47 | ): |
| 48 | """ |
| 49 | Initialize a version runner. |
| 50 | |
| 51 | Args: |
| 52 | version: Git tag (e.g., "v0.3.0") or "HEAD"/"current" for current code |
| 53 | db_url: PostgreSQL connection URL |
| 54 | port: Port to run the API on |
| 55 | llm_provider: LLM provider (defaults to env var) |
| 56 | llm_api_key: LLM API key (defaults to env var) |
| 57 | llm_model: LLM model (defaults to env var) |
| 58 | """ |
| 59 | self.version = version |
| 60 | self.db_url = db_url |
| 61 | self.port = port |
| 62 | self.llm_provider = llm_provider or os.getenv("HINDSIGHT_API_LLM_PROVIDER", "groq") |
| 63 | self.llm_api_key = llm_api_key or os.getenv("HINDSIGHT_API_LLM_API_KEY") or os.getenv("GROQ_API_KEY") |
| 64 | self.llm_model = llm_model or os.getenv("HINDSIGHT_API_LLM_MODEL", "llama-3.3-70b-versatile") |
| 65 | |
| 66 | self.work_dir: Path | None = None |
| 67 | self.process: subprocess.Popen | None = None |
| 68 | self._temp_dir: str | None = None |
| 69 | self._is_current = version.lower() in ("head", "current") |
| 70 | self.log_file: Path | None = None |
| 71 | self._log_handle = None |
| 72 | |
| 73 | def _find_repo_root(self) -> Path: |
| 74 | """Find the git repository root.""" |
| 75 | result = subprocess.run( |
| 76 | ["git", "rev-parse", "--show-toplevel"], |
| 77 | capture_output=True, |
| 78 | text=True, |
| 79 | check=True, |
| 80 | ) |
| 81 | return Path(result.stdout.strip()) |
| 82 | |
| 83 | def setup(self) -> None: |
| 84 | """Checkout version and install dependencies.""" |
| 85 | if self._is_current: |
| 86 | # Use current working directory |
| 87 | self.work_dir = self._find_repo_root() |
| 88 | logger.info(f"Using current code at {self.work_dir}") |
no outgoing calls