diff --git a/.env.example b/.env.example index b1c4cd4..9c01e61 100644 --- a/.env.example +++ b/.env.example @@ -1,9 +1,18 @@ # OpenRouter API key (required — used for all LLM calls) OPENROUTER_API_KEY= -# GitHub token (required for PR fetching and review posting) +# GitHub token (required for PR fetching and review posting). +# Use either a fine-grained PAT here, OR the GitHub App auth path below +# (PR-AF prefers the App auth when both are present). GH_TOKEN= +# GitHub App auth (alternative to GH_TOKEN — higher rate limits and +# per-installation access scopes). Set both to enable. The private key +# should be the full PEM contents on a single line with \n separators, +# or use a multi-line .env reader. +# GITHUB_APP_ID= +# GITHUB_APP_PRIVATE_KEY= + # Model configuration (optional — defaults shown) # PR_AF_MODEL=openrouter/moonshotai/kimi-k2.6 # PR_AF_AI_MODEL=openrouter/moonshotai/kimi-k2.6 diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..a6644d5 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,65 @@ +name: Bug Report +description: Report a reproducible bug in PR-AF +labels: ["bug"] +body: + - type: markdown + attributes: + value: | + Thanks for reporting a bug. Please include enough detail to reproduce quickly. + + - type: textarea + id: summary + attributes: + label: Summary + description: What is broken? + placeholder: Briefly describe the bug. + validations: + required: true + + - type: textarea + id: steps + attributes: + label: Steps to Reproduce + description: Exact steps, commands, and inputs. If a specific PR triggered the bug, include the URL (or a redacted diff). + placeholder: | + 1. ... + 2. ... + 3. ... + validations: + required: true + + - type: textarea + id: expected + attributes: + label: Expected Behavior + placeholder: What should have happened? + validations: + required: true + + - type: textarea + id: actual + attributes: + label: Actual Behavior + placeholder: What happened instead? + validations: + required: true + + - type: textarea + id: env + attributes: + label: Environment + description: Include OS, Python version, model, and deployment mode. + placeholder: | + - OS: + - Python: + - PR_AF_MODEL / HARNESS_MODEL: + - Docker / from source / Railway: + validations: + required: true + + - type: textarea + id: logs + attributes: + label: Logs or Trace + description: Paste relevant logs or stack traces. Redact tokens before pasting. + render: shell diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..2966fad --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: false +contact_links: + - name: Security report + url: https://github.com/Agent-Field/pr-af/security/advisories/new + about: Please report vulnerabilities privately through GitHub security advisories. diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..adc6b2b --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,41 @@ +name: Feature Request +description: Propose an improvement to PR-AF +labels: ["enhancement"] +body: + - type: markdown + attributes: + value: | + Proposals with concrete use-cases and acceptance criteria are easier to prioritize. + + - type: textarea + id: problem + attributes: + label: Problem + description: What user problem does this solve? + placeholder: Describe the pain point. + validations: + required: true + + - type: textarea + id: proposal + attributes: + label: Proposed Solution + description: Describe your preferred approach. + placeholder: Explain behavior, API, and expected outcomes. + validations: + required: true + + - type: textarea + id: alternatives + attributes: + label: Alternatives Considered + description: Any alternatives you evaluated. + + - type: textarea + id: acceptance + attributes: + label: Acceptance Criteria + description: Clear criteria to mark this as done. + placeholder: | + - [ ] ... + - [ ] ... diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..7993012 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,19 @@ +## Summary + +- What changed +- Why it changed + +## Validation + +- [ ] `make check` +- [ ] Relevant manual test performed (if needed) + +## Behavior Impact + +- [ ] No behavior change +- [ ] Backward compatible behavior change +- [ ] Breaking change (explain below) + +## Notes + +Any rollout notes, migration notes, or follow-ups. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0be2c04..bc4ea93 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -27,7 +27,7 @@ make check # tests + bytecode compile + ruff make clean # remove caches and build artifacts ``` -CI runs ruff and pytest on every push. PRs that fail CI will not be merged until green. +CI runs ruff against `src/` and `scripts/` and validates the Docker build on every push. The test suite runs locally via `make test` (not in CI yet — see the issue tracker if you want to help wire it up). PRs that fail CI will not be merged until green. ## What makes a good PR diff --git a/Dockerfile b/Dockerfile index 27a2331..8726e1d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -31,8 +31,8 @@ ENV PYTHONDONTWRITEBYTECODE=1 \ PYTHONUNBUFFERED=1 \ AGENTFIELD_SERVER=http://agentfield:8080 \ HARNESS_PROVIDER=opencode \ - HARNESS_MODEL=openrouter/moonshotai/kimi-k2.5 \ - AI_MODEL=openrouter/moonshotai/kimi-k2.5 \ + HARNESS_MODEL=openrouter/moonshotai/kimi-k2.6 \ + AI_MODEL=openrouter/moonshotai/kimi-k2.6 \ PORT=8004 \ HOME=/home/praf \ PYTHONPATH=/app/src \ diff --git a/Makefile b/Makefile index bf36991..46fa497 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ test: $(PYTHON) -m pytest tests/ -x -q lint: - $(PYTHON) -m ruff check src/ tests/ + $(PYTHON) -m ruff check src/ scripts/ check: lint test $(PYTHON) -m compileall -q src/pr_af/ diff --git a/README.md b/README.md index b54f814..e85be88 100644 --- a/README.md +++ b/README.md @@ -10,10 +10,11 @@ [![More from Agent-Field](https://img.shields.io/badge/More_from-Agent--Field-111827?style=for-the-badge&logo=github)](https://github.com/Agent-Field)

- Output • + OutputHow It Works • - Comparison • + ComparisonQuick Start • + ConfigurationArchitecture

diff --git a/docker-compose.yml b/docker-compose.yml index f2db403..0e8e723 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -23,13 +23,23 @@ services: - AGENTFIELD_API_KEY=${AGENTFIELD_API_KEY:-} - AGENT_CALLBACK_URL=http://pr-af:8004 - HARNESS_PROVIDER=opencode - - HARNESS_MODEL=${HARNESS_MODEL:-openrouter/moonshotai/kimi-k2.5} - - AI_MODEL=${AI_MODEL:-openrouter/moonshotai/kimi-k2.5} + - HARNESS_MODEL=${HARNESS_MODEL:-openrouter/moonshotai/kimi-k2.6} + - AI_MODEL=${AI_MODEL:-openrouter/moonshotai/kimi-k2.6} - OPENROUTER_API_KEY=${OPENROUTER_API_KEY} - GITHUB_TOKEN=${GITHUB_TOKEN:-} - GH_TOKEN=${GH_TOKEN:-} + - GITHUB_APP_ID=${GITHUB_APP_ID:-} + - GITHUB_APP_PRIVATE_KEY=${GITHUB_APP_PRIVATE_KEY:-} - XDG_DATA_HOME=/home/praf/.local/share - PR_AF_WORKDIR=/workspaces + # Default budget (300s wall-clock, $2 cost) is for smoke tests, not + # real reviews; real reviews need 35-50min and routinely exceed $2. + # Set PR_AF_NO_BUDGET=true (or raise the caps individually) for any + # deployment that should run reviews to completion. + - PR_AF_NO_BUDGET=${PR_AF_NO_BUDGET:-} + - PR_AF_MAX_DURATION_SECONDS=${PR_AF_MAX_DURATION_SECONDS:-} + - PR_AF_MAX_COST_USD=${PR_AF_MAX_COST_USD:-} + - PR_AF_MAX_CONCURRENT_REVIEWERS=${PR_AF_MAX_CONCURRENT_REVIEWERS:-} volumes: - pr-af-workspaces:/workspaces - opencode-data:/home/praf/.local/share