mirror of
https://github.com/codeflash-ai/codeflash-agent.git
synced 2026-05-04 18:25:19 +00:00
* Fix mypy errors and apply ruff formatting across packages Fix ast.FunctionDef calls missing type_params for Python 3.12+, correct type: ignore error codes in _comparator and _plugin, and run ruff format on all package source and test files. * Switch CI to prek for lint/typecheck checks Use j178/prek-action for consistent lint+typecheck (ruff check, ruff format, interrogate, mypy) matching local pre-commit config. Keep test as a separate parallel job for test-env support.
94 lines
2.7 KiB
Python
94 lines
2.7 KiB
Python
"""Environment-based configuration for the service."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
from dataclasses import dataclass, field
|
|
from pathlib import Path
|
|
|
|
|
|
def load_private_key() -> str:
|
|
"""Load private key from env var (raw PEM) or file path."""
|
|
if raw := os.environ.get("GITHUB_PRIVATE_KEY"):
|
|
return raw
|
|
key_path = os.environ.get("GITHUB_PRIVATE_KEY_PATH", "")
|
|
if key_path:
|
|
return Path(key_path).read_text()
|
|
msg = "Set GITHUB_PRIVATE_KEY or GITHUB_PRIVATE_KEY_PATH"
|
|
raise ValueError(msg)
|
|
|
|
|
|
def default_plugin_dir() -> Path:
|
|
"""Default plugin dir is dist/ (assembled plugin) at the repo root."""
|
|
env = os.environ.get("PLUGIN_DIR")
|
|
if env:
|
|
return Path(env)
|
|
return Path(__file__).resolve().parents[3] / "dist"
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class Config:
|
|
"""Immutable configuration loaded from environment variables."""
|
|
|
|
# GitHub App credentials
|
|
app_id: int = field(
|
|
default_factory=lambda: int(os.environ["GITHUB_APP_ID"]),
|
|
)
|
|
private_key: str = field(default_factory=load_private_key)
|
|
webhook_secret: str = field(
|
|
default_factory=lambda: os.environ["GITHUB_WEBHOOK_SECRET"],
|
|
)
|
|
|
|
# Claude CLI
|
|
claude_cli: str = field(
|
|
default_factory=lambda: os.environ.get("CLAUDE_CLI", "claude"),
|
|
)
|
|
claude_model: str = field(
|
|
default_factory=lambda: os.environ.get(
|
|
"CLAUDE_MODEL",
|
|
"us.anthropic.claude-sonnet-4-5-20250929-v1:0",
|
|
),
|
|
)
|
|
plugin_dir: Path = field(default_factory=default_plugin_dir)
|
|
|
|
# Codex CLI
|
|
codex_cli: str = field(
|
|
default_factory=lambda: os.environ.get("CODEX_CLI", "codex"),
|
|
)
|
|
codex_model: str = field(
|
|
default_factory=lambda: os.environ.get(
|
|
"CODEX_MODEL",
|
|
"gpt-5.4",
|
|
),
|
|
)
|
|
|
|
# Backend selection
|
|
lead_backend: str = field(
|
|
default_factory=lambda: os.environ.get("LEAD_BACKEND", "claude"),
|
|
)
|
|
|
|
# Server
|
|
host: str = field(
|
|
default_factory=lambda: os.environ.get("HOST", "0.0.0.0"),
|
|
)
|
|
port: int = field(
|
|
default_factory=lambda: int(os.environ.get("PORT", "8000")),
|
|
)
|
|
|
|
# Repo workspace
|
|
workspace_dir: Path = field(
|
|
default_factory=lambda: Path(
|
|
os.environ.get(
|
|
"WORKSPACE_DIR",
|
|
"/tmp/codeflash-workspaces",
|
|
),
|
|
),
|
|
)
|
|
|
|
def cli_for_backend(self, name: str) -> str:
|
|
"""Return the CLI binary path for a backend name."""
|
|
return {"claude": self.claude_cli, "codex": self.codex_cli}[name]
|
|
|
|
def model_for_backend(self, name: str) -> str:
|
|
"""Return the model name for a backend name."""
|
|
return {"claude": self.claude_model, "codex": self.codex_model}[name]
|