@openhands/extensions 0.0.1-alpha → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/skills/custom-codereview-guide.md +25 -0
- package/.github/pull_request_template.md +38 -0
- package/.github/release.yml +14 -0
- package/.github/workflows/check-extensions.yml +72 -0
- package/.github/workflows/npm-publish.yml +89 -0
- package/.github/workflows/pr.yml +30 -0
- package/.github/workflows/release.yml +24 -0
- package/.github/workflows/tests.yml +25 -0
- package/.github/workflows/vulnerability-scan.yml +87 -0
- package/.release-please-manifest.json +3 -0
- package/AGENTS.md +132 -0
- package/README.md +10 -0
- package/analysis_results.md +162 -0
- package/marketplaces/large-codebase.json +66 -0
- package/marketplaces/openhands-extensions.json +682 -0
- package/package.json +4 -10
- package/plugins/README.md +30 -0
- package/plugins/city-weather/.plugin/plugin.json +13 -0
- package/plugins/city-weather/README.md +145 -0
- package/plugins/city-weather/commands/now.md +56 -0
- package/plugins/cobol-modernization/.plugin/plugin.json +19 -0
- package/plugins/cobol-modernization/README.md +201 -0
- package/plugins/cobol-modernization/references/troubleshooting.md +18 -0
- package/plugins/cobol-modernization/skills/build-setup/SKILL.md +78 -0
- package/plugins/cobol-modernization/skills/build-setup/scripts/install-gnucobol.sh +32 -0
- package/plugins/cobol-modernization/skills/cobol-modernization-overview/SKILL.md +113 -0
- package/plugins/cobol-modernization/skills/mainfraime-removal/SKILL.md +62 -0
- package/plugins/cobol-modernization/skills/mainfraime-removal/references/cics-transformation-examples.md +45 -0
- package/plugins/cobol-modernization/skills/mainframe-planning/SKILL.md +78 -0
- package/plugins/cobol-modernization/skills/to-java-migration/SKILL.md +59 -0
- package/plugins/cobol-modernization/skills/to-java-migration/references/cobol-to-java-example.md +58 -0
- package/plugins/cobol-modernization/skills/to-java-migration/references/datatype-mappings.md +19 -0
- package/plugins/issue-duplicate-checker/.plugin/plugin.json +13 -0
- package/plugins/issue-duplicate-checker/README.md +51 -0
- package/plugins/issue-duplicate-checker/action.yml +349 -0
- package/plugins/issue-duplicate-checker/scripts/auto_close_duplicate_issues.py +569 -0
- package/plugins/issue-duplicate-checker/scripts/issue_duplicate_check_openhands.py +681 -0
- package/plugins/issue-duplicate-checker/scripts/post_duplicate_notice.js +220 -0
- package/plugins/issue-duplicate-checker/scripts/remove_duplicate_candidate_label.js +27 -0
- package/plugins/magic-test/.plugin/plugin.json +13 -0
- package/plugins/magic-test/skills/magic-word/SKILL.md +33 -0
- package/plugins/migration-scoring/.plugin/plugin.json +19 -0
- package/plugins/migration-scoring/README.md +244 -0
- package/plugins/migration-scoring/skills/migration-mapping/SKILL.md +72 -0
- package/plugins/migration-scoring/skills/migration-report/SKILL.md +118 -0
- package/plugins/migration-scoring/skills/migration-scoring-overview/SKILL.md +126 -0
- package/plugins/migration-scoring/skills/score-quality/SKILL.md +54 -0
- package/plugins/migration-scoring/skills/score-quality/references/scoring-criteria.md +30 -0
- package/plugins/migration-scoring/skills/score-style/SKILL.md +106 -0
- package/plugins/onboarding/.plugin/plugin.json +20 -0
- package/plugins/onboarding/README.md +30 -0
- package/plugins/onboarding/references/criteria.md +144 -0
- package/plugins/onboarding/skills/agent-readiness-report/README.md +23 -0
- package/plugins/onboarding/skills/agent-readiness-report/SKILL.md +122 -0
- package/plugins/onboarding/skills/agent-readiness-report/scripts/scan_agent_instructions.sh +88 -0
- package/plugins/onboarding/skills/agent-readiness-report/scripts/scan_build_env.sh +114 -0
- package/plugins/onboarding/skills/agent-readiness-report/scripts/scan_feedback_loops.sh +133 -0
- package/plugins/onboarding/skills/agent-readiness-report/scripts/scan_policy.sh +113 -0
- package/plugins/onboarding/skills/agent-readiness-report/scripts/scan_workflows.sh +127 -0
- package/plugins/onboarding/skills/improve-agent-readiness/README.md +19 -0
- package/plugins/onboarding/skills/improve-agent-readiness/SKILL.md +167 -0
- package/plugins/onboarding/skills/setup-agents-md/README.md +15 -0
- package/plugins/onboarding/skills/setup-agents-md/SKILL.md +150 -0
- package/plugins/onboarding/skills/setup-openhands/README.md +20 -0
- package/plugins/onboarding/skills/setup-openhands/SKILL.md +56 -0
- package/plugins/onboarding/skills/setup-pr-review/README.md +23 -0
- package/plugins/onboarding/skills/setup-pr-review/SKILL.md +72 -0
- package/plugins/openhands/.plugin/plugin.json +13 -0
- package/plugins/openhands/README.md +52 -0
- package/plugins/openhands/SKILL.md +61 -0
- package/plugins/openhands/commands/create.md +55 -0
- package/plugins/openhands/commands/openhands-cloud.md +8 -0
- package/plugins/openhands/scripts/run.sh +69 -0
- package/plugins/pr-review/.plugin/plugin.json +13 -0
- package/plugins/pr-review/README.md +393 -0
- package/plugins/pr-review/action.yml +298 -0
- package/plugins/pr-review/scripts/agent_script.py +1282 -0
- package/plugins/pr-review/scripts/evaluate_review.py +655 -0
- package/plugins/pr-review/scripts/prompt.py +260 -0
- package/plugins/pr-review/workflows/pr-review-by-openhands.yml +51 -0
- package/plugins/pr-review/workflows/pr-review-evaluation.yml +85 -0
- package/plugins/qa-changes/.plugin/plugin.json +11 -0
- package/plugins/qa-changes/README.md +185 -0
- package/plugins/qa-changes/action.yml +181 -0
- package/plugins/qa-changes/scripts/agent_script.py +406 -0
- package/plugins/qa-changes/scripts/evaluate_qa_changes.py +385 -0
- package/plugins/qa-changes/scripts/prompt.py +174 -0
- package/plugins/qa-changes/workflows/qa-changes-by-openhands.yml +50 -0
- package/plugins/qa-changes/workflows/qa-changes-evaluation.yml +85 -0
- package/plugins/release-notes/.plugin/plugin.json +19 -0
- package/plugins/release-notes/README.md +283 -0
- package/plugins/release-notes/SKILL.md +83 -0
- package/plugins/release-notes/action.yml +117 -0
- package/plugins/release-notes/commands/release-notes.md +8 -0
- package/plugins/release-notes/scripts/agent_script.py +292 -0
- package/plugins/release-notes/scripts/generate_release_notes.py +733 -0
- package/plugins/release-notes/scripts/prompt.py +90 -0
- package/plugins/release-notes/scripts/validate_release_notes.py +328 -0
- package/plugins/release-notes/workflows/release-notes.yml +76 -0
- package/plugins/vulnerability-remediation/.plugin/plugin.json +19 -0
- package/plugins/vulnerability-remediation/README.md +217 -0
- package/plugins/vulnerability-remediation/action.yml +187 -0
- package/plugins/vulnerability-remediation/scripts/scan_and_remediate.py +561 -0
- package/plugins/vulnerability-remediation/workflows/vulnerability-scan.yml +87 -0
- package/pyproject.toml +12 -0
- package/release-please-config.json +16 -0
- package/scripts/sync_extensions.py +494 -0
- package/scripts/sync_openhands_sdk_skill.py +264 -0
- package/skills/README.md +159 -0
- package/skills/add-javadoc/.plugin/plugin.json +18 -0
- package/skills/add-javadoc/README.md +40 -0
- package/skills/add-javadoc/SKILL.md +35 -0
- package/skills/add-javadoc/references/example.md +32 -0
- package/skills/add-skill/.plugin/plugin.json +18 -0
- package/skills/add-skill/README.md +67 -0
- package/skills/add-skill/SKILL.md +47 -0
- package/skills/add-skill/scripts/fetch_skill.py +259 -0
- package/skills/agent-creator/.plugin/plugin.json +20 -0
- package/skills/agent-creator/README.md +104 -0
- package/skills/agent-creator/SKILL.md +190 -0
- package/skills/agent-creator/commands/agent-creator.md +8 -0
- package/skills/agent-creator/references/fallback.md +117 -0
- package/skills/agent-memory/.plugin/plugin.json +18 -0
- package/skills/agent-memory/README.md +35 -0
- package/skills/agent-memory/SKILL.md +30 -0
- package/skills/agent-memory/commands/remember.md +8 -0
- package/skills/agent-sdk-builder/.plugin/plugin.json +18 -0
- package/skills/agent-sdk-builder/README.md +40 -0
- package/skills/agent-sdk-builder/SKILL.md +37 -0
- package/skills/agent-sdk-builder/commands/agent-builder.md +8 -0
- package/skills/azure-devops/.plugin/plugin.json +18 -0
- package/skills/azure-devops/README.md +55 -0
- package/skills/azure-devops/SKILL.md +50 -0
- package/skills/bitbucket/.plugin/plugin.json +17 -0
- package/skills/bitbucket/README.md +50 -0
- package/skills/bitbucket/SKILL.md +45 -0
- package/skills/code-review/.plugin/plugin.json +19 -0
- package/skills/code-review/README.md +18 -0
- package/skills/code-review/SKILL.md +208 -0
- package/skills/code-review/commands/codereview-roasted.md +8 -0
- package/skills/code-review/commands/codereview.md +8 -0
- package/skills/code-review/references/risk-evaluation.md +41 -0
- package/skills/code-review/references/supply-chain-security.md +31 -0
- package/skills/code-simplifier/.plugin/plugin.json +21 -0
- package/skills/code-simplifier/README.md +30 -0
- package/skills/code-simplifier/SKILL.md +91 -0
- package/skills/code-simplifier/commands/simplify.md +8 -0
- package/skills/code-simplifier/references/code-quality-review.md +86 -0
- package/skills/code-simplifier/references/code-reuse-review.md +63 -0
- package/skills/code-simplifier/references/efficiency-review.md +81 -0
- package/skills/datadog/.plugin/plugin.json +19 -0
- package/skills/datadog/README.md +100 -0
- package/skills/datadog/SKILL.md +95 -0
- package/skills/deno/.plugin/plugin.json +18 -0
- package/skills/deno/README.md +5 -0
- package/skills/deno/SKILL.md +99 -0
- package/skills/deno/references/README.md +6 -0
- package/skills/discord/.plugin/plugin.json +18 -0
- package/skills/discord/README.md +31 -0
- package/skills/discord/SKILL.md +109 -0
- package/skills/discord/__init__.py +0 -0
- package/skills/discord/references/REFERENCE.md +78 -0
- package/skills/discord/scripts/__init__.py +0 -0
- package/skills/discord/scripts/_http.py +127 -0
- package/skills/discord/scripts/post_webhook.py +106 -0
- package/skills/discord/scripts/send_message.py +102 -0
- package/skills/docker/.plugin/plugin.json +17 -0
- package/skills/docker/README.md +34 -0
- package/skills/docker/SKILL.md +29 -0
- package/skills/evidence-based-citations/.plugin/plugin.json +20 -0
- package/skills/evidence-based-citations/README.md +31 -0
- package/skills/evidence-based-citations/SKILL.md +59 -0
- package/skills/flarglebargle/.plugin/plugin.json +16 -0
- package/skills/flarglebargle/README.md +14 -0
- package/skills/flarglebargle/SKILL.md +9 -0
- package/skills/frontend-design/.plugin/plugin.json +21 -0
- package/skills/frontend-design/LICENSE.txt +177 -0
- package/skills/frontend-design/README.md +42 -0
- package/skills/frontend-design/SKILL.md +42 -0
- package/skills/github/.plugin/plugin.json +19 -0
- package/skills/github/README.md +42 -0
- package/skills/github/SKILL.md +106 -0
- package/skills/github-pr-review/.plugin/plugin.json +18 -0
- package/skills/github-pr-review/README.md +145 -0
- package/skills/github-pr-review/SKILL.md +148 -0
- package/skills/github-pr-review/commands/github-pr-review.md +8 -0
- package/skills/github-pr-reviewer/.plugin/plugin.json +20 -0
- package/skills/github-pr-reviewer/README.md +34 -0
- package/skills/github-pr-reviewer/SKILL.md +89 -0
- package/skills/github-pr-reviewer/commands/pr-reviewer:setup.md +8 -0
- package/skills/github-repo-monitor/.plugin/plugin.json +22 -0
- package/skills/github-repo-monitor/README.md +70 -0
- package/skills/github-repo-monitor/SKILL.md +316 -0
- package/skills/github-repo-monitor/commands/github-monitor:poll.md +8 -0
- package/skills/github-repo-monitor/references/github-api.md +241 -0
- package/skills/github-repo-monitor/references/state-schema.md +160 -0
- package/skills/github-repo-monitor/scripts/main.py +915 -0
- package/skills/github-repo-monitor/tests/test_main.py +400 -0
- package/skills/gitlab/.plugin/plugin.json +17 -0
- package/skills/gitlab/README.md +37 -0
- package/skills/gitlab/SKILL.md +32 -0
- package/skills/incident-retrospective/.plugin/plugin.json +21 -0
- package/skills/incident-retrospective/README.md +34 -0
- package/skills/incident-retrospective/SKILL.md +98 -0
- package/skills/incident-retrospective/commands/incident-retro:setup.md +8 -0
- package/skills/iterate/.plugin/plugin.json +13 -0
- package/skills/iterate/README.md +25 -0
- package/skills/iterate/SKILL.md +399 -0
- package/skills/iterate/commands/babysit.md +8 -0
- package/skills/iterate/commands/iterate.md +8 -0
- package/skills/iterate/commands/verify.md +8 -0
- package/skills/iterate/references/heuristics.md +58 -0
- package/skills/iterate/references/verification.md +96 -0
- package/skills/jupyter/.plugin/plugin.json +18 -0
- package/skills/jupyter/README.md +55 -0
- package/skills/jupyter/SKILL.md +50 -0
- package/skills/kubernetes/.plugin/plugin.json +18 -0
- package/skills/kubernetes/README.md +53 -0
- package/skills/kubernetes/SKILL.md +48 -0
- package/skills/learn-from-code-review/.plugin/plugin.json +19 -0
- package/skills/learn-from-code-review/README.md +64 -0
- package/skills/learn-from-code-review/SKILL.md +186 -0
- package/skills/learn-from-code-review/commands/learn-from-reviews.md +8 -0
- package/skills/linear/.plugin/plugin.json +19 -0
- package/skills/linear/README.md +58 -0
- package/skills/linear/SKILL.md +213 -0
- package/skills/linear-triage/.plugin/plugin.json +21 -0
- package/skills/linear-triage/README.md +34 -0
- package/skills/linear-triage/SKILL.md +91 -0
- package/skills/linear-triage/commands/linear-triage:setup.md +8 -0
- package/skills/notion/.plugin/plugin.json +17 -0
- package/skills/notion/README.md +114 -0
- package/skills/notion/SKILL.md +109 -0
- package/skills/npm/.plugin/plugin.json +17 -0
- package/skills/npm/README.md +14 -0
- package/skills/npm/SKILL.md +9 -0
- package/skills/openhands-api/.plugin/plugin.json +22 -0
- package/skills/openhands-api/README.md +48 -0
- package/skills/openhands-api/SKILL.md +399 -0
- package/skills/openhands-api/references/README.md +33 -0
- package/skills/openhands-api/references/TROUBLESHOOTING.md +81 -0
- package/skills/openhands-api/references/example_prompt.md +12 -0
- package/skills/openhands-api/scripts/openhands_api.py +606 -0
- package/skills/openhands-api/scripts/openhands_api.ts +252 -0
- package/skills/openhands-automation/.plugin/plugin.json +19 -0
- package/skills/openhands-automation/README.md +89 -0
- package/skills/openhands-automation/SKILL.md +875 -0
- package/skills/openhands-automation/commands/automation:create.md +8 -0
- package/skills/openhands-automation/references/ab-testing.md +185 -0
- package/skills/openhands-automation/references/custom-automation.md +644 -0
- package/skills/openhands-sdk/.plugin/plugin.json +20 -0
- package/skills/openhands-sdk/README.md +22 -0
- package/skills/openhands-sdk/SKILL.md +229 -0
- package/skills/openhands-sdk/commands/sdk.md +8 -0
- package/skills/pdflatex/.plugin/plugin.json +18 -0
- package/skills/pdflatex/README.md +39 -0
- package/skills/pdflatex/SKILL.md +34 -0
- package/skills/prd/.plugin/plugin.json +19 -0
- package/skills/prd/README.md +28 -0
- package/skills/prd/SKILL.md +237 -0
- package/skills/prd/commands/prd.md +8 -0
- package/skills/qa-changes/README.md +18 -0
- package/skills/qa-changes/SKILL.md +229 -0
- package/skills/qa-changes/commands/qa-changes.md +8 -0
- package/skills/release-notes/README.md +24 -0
- package/skills/release-notes/SKILL.md +19 -0
- package/skills/release-notes/commands/release-notes.md +8 -0
- package/skills/research-brief/.plugin/plugin.json +20 -0
- package/skills/research-brief/README.md +34 -0
- package/skills/research-brief/SKILL.md +99 -0
- package/skills/research-brief/commands/research-brief:setup.md +8 -0
- package/skills/security/.plugin/plugin.json +18 -0
- package/skills/security/README.md +38 -0
- package/skills/security/SKILL.md +33 -0
- package/skills/skill-creator/.plugin/plugin.json +17 -0
- package/skills/skill-creator/LICENSE.txt +202 -0
- package/skills/skill-creator/README.md +182 -0
- package/skills/skill-creator/SKILL.md +545 -0
- package/skills/skill-creator/references/output-patterns.md +82 -0
- package/skills/skill-creator/references/workflows.md +28 -0
- package/skills/skill-creator/scripts/init_skill.py +303 -0
- package/skills/skill-creator/scripts/quick_validate.py +95 -0
- package/skills/slack-channel-monitor/.plugin/plugin.json +21 -0
- package/skills/slack-channel-monitor/README.md +91 -0
- package/skills/slack-channel-monitor/SKILL.md +276 -0
- package/skills/slack-channel-monitor/commands/slack-monitor:poll.md +8 -0
- package/skills/slack-channel-monitor/references/slack-api.md +207 -0
- package/skills/slack-channel-monitor/references/state-schema.md +180 -0
- package/skills/slack-channel-monitor/scripts/main.py +962 -0
- package/skills/slack-standup-digest/.plugin/plugin.json +21 -0
- package/skills/slack-standup-digest/README.md +34 -0
- package/skills/slack-standup-digest/SKILL.md +92 -0
- package/skills/slack-standup-digest/commands/standup-digest:setup.md +8 -0
- package/skills/spark-version-upgrade/.plugin/plugin.json +20 -0
- package/skills/spark-version-upgrade/README.md +54 -0
- package/skills/spark-version-upgrade/SKILL.md +233 -0
- package/skills/ssh/.plugin/plugin.json +18 -0
- package/skills/ssh/README.md +140 -0
- package/skills/ssh/SKILL.md +135 -0
- package/skills/swift-linux/.plugin/plugin.json +17 -0
- package/skills/swift-linux/README.md +86 -0
- package/skills/swift-linux/SKILL.md +81 -0
- package/skills/theme-factory/.plugin/plugin.json +19 -0
- package/skills/theme-factory/LICENSE.txt +202 -0
- package/skills/theme-factory/README.md +58 -0
- package/skills/theme-factory/SKILL.md +59 -0
- package/skills/theme-factory/theme-showcase.pdf +0 -0
- package/skills/theme-factory/themes/arctic-frost.md +19 -0
- package/skills/theme-factory/themes/botanical-garden.md +19 -0
- package/skills/theme-factory/themes/desert-rose.md +19 -0
- package/skills/theme-factory/themes/forest-canopy.md +19 -0
- package/skills/theme-factory/themes/golden-hour.md +19 -0
- package/skills/theme-factory/themes/midnight-galaxy.md +19 -0
- package/skills/theme-factory/themes/modern-minimalist.md +19 -0
- package/skills/theme-factory/themes/ocean-depths.md +19 -0
- package/skills/theme-factory/themes/sunset-boulevard.md +19 -0
- package/skills/theme-factory/themes/tech-innovation.md +19 -0
- package/skills/uv/.plugin/plugin.json +18 -0
- package/skills/uv/README.md +5 -0
- package/skills/uv/SKILL.md +95 -0
- package/skills/uv/references/README.md +5 -0
- package/skills/vercel/.plugin/plugin.json +18 -0
- package/skills/vercel/README.md +108 -0
- package/skills/vercel/SKILL.md +103 -0
- package/tests/test_add_skill_installs_to_agents_dir.py +42 -0
- package/tests/test_catalogs.py +109 -0
- package/tests/test_code_review_risk_evaluation.py +94 -0
- package/tests/test_issue_duplicate_checker.py +240 -0
- package/tests/test_openhands_api_python.py +152 -0
- package/tests/test_plugin_manifest.py +83 -0
- package/tests/test_pr_review_diff_payload.py +202 -0
- package/tests/test_pr_review_feedback.py +263 -0
- package/tests/test_pr_review_prompt.py +152 -0
- package/tests/test_pr_review_review_context.py +253 -0
- package/tests/test_qa_changes.py +232 -0
- package/tests/test_qa_changes_evaluation.py +259 -0
- package/tests/test_release_notes_generator.py +990 -0
- package/tests/test_sdk_loading.py +150 -0
- package/tests/test_skill_plugin_loading.py +149 -0
- package/tests/test_skills_have_readme.py +66 -0
- package/tests/test_sync_extensions.py +292 -0
- package/tests/test_workflow_sync.py +46 -0
- package/utils/analysis/README.md +7 -0
- package/utils/analysis/laminar_signals/README.md +211 -0
- package/utils/analysis/laminar_signals/analyze.py +780 -0
- package/utils/analysis/laminar_signals/templates/default.j2 +49 -0
- package/utils/analysis/laminar_signals/templates/pr_review.j2 +61 -0
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
"""
|
|
2
|
+
PR Review Prompt Template
|
|
3
|
+
|
|
4
|
+
This module contains the prompt template used by the OpenHands agent
|
|
5
|
+
for conducting pull request reviews. The template uses skill triggers:
|
|
6
|
+
- {skill_trigger} will be replaced with '/codereview'
|
|
7
|
+
- /github-pr-review provides instructions for posting review comments via GitHub API
|
|
8
|
+
|
|
9
|
+
The template includes:
|
|
10
|
+
- {diff} - The complete git diff for the PR (may be truncated for large files)
|
|
11
|
+
- {pr_number} - The PR number
|
|
12
|
+
- {commit_id} - The HEAD commit SHA
|
|
13
|
+
- {review_context} - Previous review comments and thread resolution status
|
|
14
|
+
|
|
15
|
+
When sub-agent delegation is enabled (``use_sub_agents=True``), a short
|
|
16
|
+
delegation suffix is appended to the base prompt giving the agent the
|
|
17
|
+
option to delegate file-level reviews via the TaskToolSet.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
# Template for when there is review context available
|
|
21
|
+
_REVIEW_CONTEXT_SECTION = """
|
|
22
|
+
## Previous Review History
|
|
23
|
+
|
|
24
|
+
The following shows previous reviews and review threads on this PR.
|
|
25
|
+
Pay attention to:
|
|
26
|
+
- **Unresolved threads**: These issues may still need to be addressed
|
|
27
|
+
- **Resolved threads**: These provide context on what was already discussed
|
|
28
|
+
- **Previous review decisions**: See what other reviewers have said
|
|
29
|
+
|
|
30
|
+
{review_context}
|
|
31
|
+
|
|
32
|
+
When reviewing, consider:
|
|
33
|
+
1. Don't repeat comments that have already been made and are still relevant
|
|
34
|
+
2. If an issue is still unresolved in the code, you may reference it
|
|
35
|
+
3. If resolved, don't bring it up unless the fix introduced new problems
|
|
36
|
+
4. Focus on NEW issues in the current diff that haven't been discussed yet
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
_EVIDENCE_REQUIREMENT_SECTION = """
|
|
40
|
+
## PR Description Evidence Requirement
|
|
41
|
+
|
|
42
|
+
Require the PR description to include an `Evidence` section (or similarly labeled section) showing that the code actually works.
|
|
43
|
+
|
|
44
|
+
When checking the PR description:
|
|
45
|
+
- For frontend or UI changes, require a screenshot or video that demonstrates the implemented behavior in the actual product.
|
|
46
|
+
- For backend, API, CLI, or script changes, require the command(s) used to run or exercise the real code path end-to-end and the resulting output.
|
|
47
|
+
- Unit tests alone do **not** count as evidence. Do not accept `pytest`, unit test output, or similar test runs as the only proof that the change works.
|
|
48
|
+
- If the change appears to come from an agent conversation or AI-assisted workflow, prefer a conversation link such as `https://app.all-hands.dev/conversations/{conversation_id}` so reviewers can trace the work.
|
|
49
|
+
- Do not accept vague claims like "tested locally" without concrete runtime artifacts, commands, or output.
|
|
50
|
+
|
|
51
|
+
If the change is substantive and this evidence is missing or weak, call it out as a must-fix issue in your review. Do not invent evidence that is not present in the PR description.
|
|
52
|
+
"""
|
|
53
|
+
|
|
54
|
+
FEEDBACK_COMMENT_MARKER = "<!-- openhands-pr-review-feedback -->"
|
|
55
|
+
|
|
56
|
+
_FEEDBACK_FOOTER_SECTION = """
|
|
57
|
+
## Review Feedback Footer
|
|
58
|
+
|
|
59
|
+
When you submit the top-level GitHub review body, append this exact footer at the end of that same review body so maintainers can react without creating a separate PR comment:
|
|
60
|
+
|
|
61
|
+
```md
|
|
62
|
+
---
|
|
63
|
+
Was this automated review useful? React with 👍 or 👎 to this review to help us measure review quality.
|
|
64
|
+
Workflow run: {review_run_url}
|
|
65
|
+
{feedback_comment_marker}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Requirements:
|
|
69
|
+
- Put this footer in the main review body, not in a separate issue comment.
|
|
70
|
+
- Keep the rest of the review body concise.
|
|
71
|
+
- If you would otherwise post only inline comments, still include a short top-level review body so this footer has somewhere to live.
|
|
72
|
+
"""
|
|
73
|
+
|
|
74
|
+
PROMPT = """{skill_trigger}
|
|
75
|
+
/github-pr-review
|
|
76
|
+
|
|
77
|
+
When posting a review, keep the review body brief unless your active review instructions require a longer structured format.
|
|
78
|
+
|
|
79
|
+
For dependency update PRs, do **NOT** approve a target version that was published less than 7 days ago.
|
|
80
|
+
|
|
81
|
+
Review the PR changes below and identify issues that need to be addressed.
|
|
82
|
+
|
|
83
|
+
## Pull Request Information
|
|
84
|
+
|
|
85
|
+
- **Title**: {title}
|
|
86
|
+
- **Description**: {body}
|
|
87
|
+
- **Repository**: {repo_name}
|
|
88
|
+
- **Base Branch**: {base_branch}
|
|
89
|
+
- **Head Branch**: {head_branch}
|
|
90
|
+
- **PR Number**: {pr_number}
|
|
91
|
+
- **Commit ID**: {commit_id}
|
|
92
|
+
|
|
93
|
+
{review_context_section}{evidence_requirements_section}{feedback_footer_section}
|
|
94
|
+
{files_manifest}
|
|
95
|
+
## Patches
|
|
96
|
+
|
|
97
|
+
The fenced block below contains the per-file patches. Individual patches may be **abbreviated** (look for `[patch abbreviated: ...]`) or **omitted** (look for `[patch omitted: ...]`) when they exceed the per-file or total budget. Files that appear in the manifest above but whose patch is missing or short here are still present in the PR — read the file from the workspace to inspect them. Do not flag them as missing from the PR.
|
|
98
|
+
|
|
99
|
+
```diff
|
|
100
|
+
{diff}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Analyze the changes and post your review using the GitHub API.
|
|
104
|
+
"""
|
|
105
|
+
|
|
106
|
+
# Appended to PROMPT when use_sub_agents=True. Gives the main agent the
|
|
107
|
+
# option to delegate via the TaskToolSet without duplicating the base prompt.
|
|
108
|
+
_DELEGATION_SUFFIX = """
|
|
109
|
+
## Sub-agent Delegation
|
|
110
|
+
|
|
111
|
+
You have access to the **task** tool for delegating file-level reviews to
|
|
112
|
+
`file_reviewer` sub-agents. Use it when the diff is large — roughly 4+ files
|
|
113
|
+
or 500+ changed lines. For smaller diffs, just review directly.
|
|
114
|
+
|
|
115
|
+
When delegating, split the diff by file (or small group of related files) and
|
|
116
|
+
call the task tool with `subagent_type: "file_reviewer"`. Each sub-agent will
|
|
117
|
+
return a JSON array of findings. Merge them, de-duplicate, drop noise, and
|
|
118
|
+
post a single consolidated review via the GitHub API.
|
|
119
|
+
"""
|
|
120
|
+
|
|
121
|
+
# Skill content injected into each file_reviewer sub-agent.
|
|
122
|
+
# Defines the review persona, available tools, and — most importantly — the
|
|
123
|
+
# exact JSON schema the sub-agent must return.
|
|
124
|
+
FILE_REVIEWER_SKILL = """\
|
|
125
|
+
You are a **file-level code reviewer** sub-agent.
|
|
126
|
+
|
|
127
|
+
## Your Task
|
|
128
|
+
|
|
129
|
+
You will receive a diff for one or more files from a pull request.
|
|
130
|
+
Review the changes and return structured findings.
|
|
131
|
+
|
|
132
|
+
## Tools
|
|
133
|
+
|
|
134
|
+
You have `terminal` and `file_editor` so you can inspect the full source
|
|
135
|
+
files for surrounding context — use `cat`, `grep`, or `file_editor view`
|
|
136
|
+
when the diff alone is not enough to judge an issue.
|
|
137
|
+
|
|
138
|
+
## Review Style
|
|
139
|
+
|
|
140
|
+
Be direct, pragmatic, and thorough. Focus on correctness, security,
|
|
141
|
+
simplicity, and maintainability. Call out real problems; skip trivial noise.
|
|
142
|
+
|
|
143
|
+
## Output Format
|
|
144
|
+
|
|
145
|
+
Return a JSON array wrapped in a ```json fenced code block.
|
|
146
|
+
Each element must have exactly these fields:
|
|
147
|
+
|
|
148
|
+
| Field | Type | Description |
|
|
149
|
+
|------------|--------|-------------|
|
|
150
|
+
| `path` | string | File path exactly as shown in the diff header (e.g. `src/utils.py`) |
|
|
151
|
+
| `line` | int | Line number in the **new** file where the issue occurs |
|
|
152
|
+
| `severity` | string | One of: `"critical"`, `"major"`, `"minor"`, `"nit"` |
|
|
153
|
+
| `body` | string | Concise description of the issue, including a suggested fix |
|
|
154
|
+
|
|
155
|
+
### Severity guide
|
|
156
|
+
- **critical** — bug, security vulnerability, or data loss
|
|
157
|
+
- **major** — incorrect logic, missing error handling, performance issue
|
|
158
|
+
- **minor** — style, readability, or minor correctness concern
|
|
159
|
+
- **nit** — cosmetic or trivial preference
|
|
160
|
+
|
|
161
|
+
### Example
|
|
162
|
+
|
|
163
|
+
```json
|
|
164
|
+
[
|
|
165
|
+
{{"path": "src/utils.py", "line": 42, "severity": "major", "body": "Unchecked `None` return — add a guard before accessing `.value`."}},
|
|
166
|
+
{{"path": "src/utils.py", "line": 78, "severity": "nit", "body": "Unused import `os`."}}
|
|
167
|
+
]
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
If you find no issues, return:
|
|
171
|
+
```json
|
|
172
|
+
[]
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
When you are done, call the `finish` tool with the JSON array as the message.
|
|
176
|
+
"""
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
def format_prompt(
|
|
180
|
+
skill_trigger: str,
|
|
181
|
+
title: str,
|
|
182
|
+
body: str,
|
|
183
|
+
repo_name: str,
|
|
184
|
+
base_branch: str,
|
|
185
|
+
head_branch: str,
|
|
186
|
+
pr_number: str,
|
|
187
|
+
commit_id: str,
|
|
188
|
+
diff: str,
|
|
189
|
+
files_manifest: str = "",
|
|
190
|
+
review_context: str = "",
|
|
191
|
+
require_evidence: bool = False,
|
|
192
|
+
collect_feedback: bool = False,
|
|
193
|
+
review_run_url: str = "",
|
|
194
|
+
use_sub_agents: bool = False,
|
|
195
|
+
) -> str:
|
|
196
|
+
"""Format the PR review prompt with all parameters.
|
|
197
|
+
|
|
198
|
+
Args:
|
|
199
|
+
skill_trigger: The skill trigger (e.g., '/codereview')
|
|
200
|
+
title: PR title
|
|
201
|
+
body: PR description
|
|
202
|
+
repo_name: Repository name (owner/repo)
|
|
203
|
+
base_branch: Base branch name
|
|
204
|
+
head_branch: Head branch name
|
|
205
|
+
pr_number: PR number
|
|
206
|
+
commit_id: HEAD commit SHA
|
|
207
|
+
diff: Git diff content
|
|
208
|
+
review_context: Formatted previous review context. If empty or whitespace-only,
|
|
209
|
+
the review context section is omitted from the prompt.
|
|
210
|
+
require_evidence: Whether to instruct the reviewer to enforce PR description
|
|
211
|
+
evidence showing the code works.
|
|
212
|
+
collect_feedback: Whether to instruct the reviewer to append the feedback
|
|
213
|
+
footer to the main review body.
|
|
214
|
+
review_run_url: Workflow run URL to embed in the feedback footer.
|
|
215
|
+
use_sub_agents: When True, the agent gets the TaskToolSet and decides
|
|
216
|
+
at runtime whether to delegate file-level reviews to
|
|
217
|
+
sub-agents based on diff size and complexity.
|
|
218
|
+
|
|
219
|
+
Returns:
|
|
220
|
+
Formatted prompt string
|
|
221
|
+
"""
|
|
222
|
+
# Only include the review context section if there is actual context
|
|
223
|
+
if review_context and review_context.strip():
|
|
224
|
+
review_context_section = _REVIEW_CONTEXT_SECTION.format(
|
|
225
|
+
review_context=review_context
|
|
226
|
+
)
|
|
227
|
+
else:
|
|
228
|
+
review_context_section = ""
|
|
229
|
+
|
|
230
|
+
evidence_requirements_section = (
|
|
231
|
+
_EVIDENCE_REQUIREMENT_SECTION if require_evidence else ""
|
|
232
|
+
)
|
|
233
|
+
|
|
234
|
+
feedback_footer_section = ""
|
|
235
|
+
if collect_feedback:
|
|
236
|
+
feedback_footer_section = _FEEDBACK_FOOTER_SECTION.format(
|
|
237
|
+
review_run_url=review_run_url or "unavailable",
|
|
238
|
+
feedback_comment_marker=FEEDBACK_COMMENT_MARKER,
|
|
239
|
+
)
|
|
240
|
+
|
|
241
|
+
prompt = PROMPT.format(
|
|
242
|
+
skill_trigger=skill_trigger,
|
|
243
|
+
title=title,
|
|
244
|
+
body=body,
|
|
245
|
+
repo_name=repo_name,
|
|
246
|
+
base_branch=base_branch,
|
|
247
|
+
head_branch=head_branch,
|
|
248
|
+
pr_number=pr_number,
|
|
249
|
+
commit_id=commit_id,
|
|
250
|
+
review_context_section=review_context_section,
|
|
251
|
+
evidence_requirements_section=evidence_requirements_section,
|
|
252
|
+
feedback_footer_section=feedback_footer_section,
|
|
253
|
+
files_manifest=files_manifest,
|
|
254
|
+
diff=diff,
|
|
255
|
+
)
|
|
256
|
+
|
|
257
|
+
if use_sub_agents:
|
|
258
|
+
prompt += _DELEGATION_SUFFIX
|
|
259
|
+
|
|
260
|
+
return prompt
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: PR Review by OpenHands
|
|
3
|
+
|
|
4
|
+
on:
|
|
5
|
+
# Use pull_request_target to allow fork PRs to access secrets when triggered by maintainers
|
|
6
|
+
# Security: This workflow runs when:
|
|
7
|
+
# 1. A new PR is opened (non-draft), OR
|
|
8
|
+
# 2. A draft PR is marked as ready for review, OR
|
|
9
|
+
# 3. A maintainer adds the 'review-this' label, OR
|
|
10
|
+
# 4. A maintainer requests openhands-agent or all-hands-bot as a reviewer
|
|
11
|
+
# Adding labels and requesting reviewers requires write access.
|
|
12
|
+
# The PR code is explicitly checked out for review, but secrets are only accessible
|
|
13
|
+
# because the workflow runs in the base repository context.
|
|
14
|
+
pull_request_target:
|
|
15
|
+
types: [opened, ready_for_review, labeled, review_requested]
|
|
16
|
+
|
|
17
|
+
permissions:
|
|
18
|
+
contents: read
|
|
19
|
+
pull-requests: write
|
|
20
|
+
issues: write
|
|
21
|
+
|
|
22
|
+
jobs:
|
|
23
|
+
pr-review:
|
|
24
|
+
# Run when one of the following conditions is met:
|
|
25
|
+
# 1. A new non-draft PR is opened by a non-first-time contributor, OR
|
|
26
|
+
# 2. A draft PR is converted to ready for review by a non-first-time contributor, OR
|
|
27
|
+
# 3. 'review-this' label is added, OR
|
|
28
|
+
# 4. openhands-agent or all-hands-bot is requested as a reviewer
|
|
29
|
+
# Note: FIRST_TIME_CONTRIBUTOR and NONE PRs require manual trigger via label/reviewer request.
|
|
30
|
+
if: |
|
|
31
|
+
(github.event.action == 'opened' && github.event.pull_request.draft == false && github.event.pull_request.author_association != 'FIRST_TIME_CONTRIBUTOR' && github.event.pull_request.author_association != 'NONE') ||
|
|
32
|
+
(github.event.action == 'ready_for_review' && github.event.pull_request.author_association != 'FIRST_TIME_CONTRIBUTOR' && github.event.pull_request.author_association != 'NONE') ||
|
|
33
|
+
github.event.label.name == 'review-this' ||
|
|
34
|
+
github.event.requested_reviewer.login == 'openhands-agent' ||
|
|
35
|
+
github.event.requested_reviewer.login == 'all-hands-bot'
|
|
36
|
+
concurrency:
|
|
37
|
+
group: pr-review-${{ github.event.pull_request.number }}
|
|
38
|
+
cancel-in-progress: true
|
|
39
|
+
runs-on: ubuntu-24.04
|
|
40
|
+
steps:
|
|
41
|
+
- name: Run PR Review
|
|
42
|
+
uses: OpenHands/extensions/plugins/pr-review@main
|
|
43
|
+
with:
|
|
44
|
+
llm-model: litellm_proxy/claude-sonnet-4-5-20250929
|
|
45
|
+
llm-base-url: https://llm-proxy.app.all-hands.dev
|
|
46
|
+
# [DEPRECATED] review-style is no longer used; standard and roasted are merged
|
|
47
|
+
# review-style: roasted
|
|
48
|
+
use-sub-agents: 'false' # Disabled by default (issue #208: high cost / timeouts)
|
|
49
|
+
llm-api-key: ${{ secrets.LLM_API_KEY }}
|
|
50
|
+
github-token: ${{ secrets.OPENHANDS_BOT_GITHUB_PAT_PUBLIC }}
|
|
51
|
+
lmnr-api-key: ${{ secrets.LMNR_SKILLS_API_KEY }}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: PR Review Evaluation
|
|
3
|
+
|
|
4
|
+
# This workflow evaluates how well PR review comments were addressed.
|
|
5
|
+
# It runs when a PR is closed to assess review effectiveness.
|
|
6
|
+
#
|
|
7
|
+
# Security note: pull_request_target is safe here because:
|
|
8
|
+
# 1. Only triggers on PR close (not on code changes)
|
|
9
|
+
# 2. Does not checkout PR code - only downloads artifacts from trusted workflow runs
|
|
10
|
+
# 3. Runs evaluation scripts from the extensions repo, not from the PR
|
|
11
|
+
|
|
12
|
+
on:
|
|
13
|
+
pull_request_target:
|
|
14
|
+
types: [closed]
|
|
15
|
+
|
|
16
|
+
permissions:
|
|
17
|
+
contents: read
|
|
18
|
+
pull-requests: read
|
|
19
|
+
|
|
20
|
+
jobs:
|
|
21
|
+
evaluate:
|
|
22
|
+
runs-on: ubuntu-24.04
|
|
23
|
+
env:
|
|
24
|
+
PR_NUMBER: ${{ github.event.pull_request.number }}
|
|
25
|
+
REPO_NAME: ${{ github.repository }}
|
|
26
|
+
PR_MERGED: ${{ github.event.pull_request.merged }}
|
|
27
|
+
|
|
28
|
+
steps:
|
|
29
|
+
- name: Download review trace artifact
|
|
30
|
+
id: download-trace
|
|
31
|
+
uses: dawidd6/action-download-artifact@v6
|
|
32
|
+
continue-on-error: true
|
|
33
|
+
with:
|
|
34
|
+
workflow: pr-review-by-openhands.yml
|
|
35
|
+
name: pr-review-trace-${{ github.event.pull_request.number }}
|
|
36
|
+
path: trace-info
|
|
37
|
+
search_artifacts: true
|
|
38
|
+
if_no_artifact_found: warn
|
|
39
|
+
|
|
40
|
+
- name: Check if trace file exists
|
|
41
|
+
id: check-trace
|
|
42
|
+
run: |
|
|
43
|
+
if [ -f "trace-info/laminar_trace_info.json" ]; then
|
|
44
|
+
echo "trace_exists=true" >> $GITHUB_OUTPUT
|
|
45
|
+
echo "Found trace file for PR #$PR_NUMBER"
|
|
46
|
+
else
|
|
47
|
+
echo "trace_exists=false" >> $GITHUB_OUTPUT
|
|
48
|
+
echo "No trace file found for PR #$PR_NUMBER - skipping evaluation"
|
|
49
|
+
fi
|
|
50
|
+
|
|
51
|
+
# Always checkout main branch for security - cannot test script changes in PRs
|
|
52
|
+
- name: Checkout extensions repository
|
|
53
|
+
if: steps.check-trace.outputs.trace_exists == 'true'
|
|
54
|
+
uses: actions/checkout@v5
|
|
55
|
+
with:
|
|
56
|
+
repository: OpenHands/extensions
|
|
57
|
+
path: extensions
|
|
58
|
+
|
|
59
|
+
- name: Set up Python
|
|
60
|
+
if: steps.check-trace.outputs.trace_exists == 'true'
|
|
61
|
+
uses: actions/setup-python@v6
|
|
62
|
+
with:
|
|
63
|
+
python-version: '3.12'
|
|
64
|
+
|
|
65
|
+
- name: Install dependencies
|
|
66
|
+
if: steps.check-trace.outputs.trace_exists == 'true'
|
|
67
|
+
run: pip install lmnr
|
|
68
|
+
|
|
69
|
+
- name: Run evaluation
|
|
70
|
+
if: steps.check-trace.outputs.trace_exists == 'true'
|
|
71
|
+
env:
|
|
72
|
+
# Script expects LMNR_PROJECT_API_KEY; org secret is named LMNR_SKILLS_API_KEY
|
|
73
|
+
LMNR_PROJECT_API_KEY: ${{ secrets.LMNR_SKILLS_API_KEY }}
|
|
74
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
75
|
+
run: |
|
|
76
|
+
python extensions/plugins/pr-review/scripts/evaluate_review.py \
|
|
77
|
+
--trace-file trace-info/laminar_trace_info.json
|
|
78
|
+
|
|
79
|
+
- name: Upload evaluation logs
|
|
80
|
+
uses: actions/upload-artifact@v5
|
|
81
|
+
if: always() && steps.check-trace.outputs.trace_exists == 'true'
|
|
82
|
+
with:
|
|
83
|
+
name: pr-review-evaluation-${{ github.event.pull_request.number }}
|
|
84
|
+
path: '*.log'
|
|
85
|
+
retention-days: 30
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "qa-changes",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Automated QA validation of PR changes — sets up the environment, runs tests, exercises changed behavior, and reports results",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "OpenHands",
|
|
7
|
+
"email": "contact@all-hands.dev"
|
|
8
|
+
},
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"repository": "https://github.com/OpenHands/extensions"
|
|
11
|
+
}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
# QA Changes Plugin
|
|
2
|
+
|
|
3
|
+
Automated pull request QA validation using OpenHands agents. Unlike the [PR Review plugin](../pr-review/) which reads diffs and posts code review comments, this plugin **actually runs the software** — setting up the environment, exercising changed behavior as a real user would, and posting a structured QA report. It does not re-run the test suite (that's CI's job) or analyze code style/logic (that's code review's job).
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
Copy the workflow file to your repository:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
cp plugins/qa-changes/workflows/qa-changes-by-openhands.yml \
|
|
11
|
+
.github/workflows/qa-changes-by-openhands.yml
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Then configure the required secrets (see [Installation](#installation) below).
|
|
15
|
+
|
|
16
|
+
## How It Works
|
|
17
|
+
|
|
18
|
+
The QA agent follows a four-phase methodology:
|
|
19
|
+
|
|
20
|
+
1. **Understand** — Reads the PR diff, title, and description. Classifies changes and identifies entry points (CLI commands, API endpoints, UI pages).
|
|
21
|
+
2. **Setup** — Bootstraps the repo: installs dependencies, builds the project. Notes CI status but does not re-run tests.
|
|
22
|
+
3. **Exercise** — The core phase. Actually uses the software the way a human would: spins up servers, opens browsers, runs CLI commands, makes HTTP requests. Focuses on functional verification that CI and code review cannot do.
|
|
23
|
+
4. **Report** — Posts a structured QA report as a PR review with evidence (commands, outputs, screenshots) and a verdict.
|
|
24
|
+
|
|
25
|
+
The agent knows when to give up: if a verification approach fails after three materially different attempts, it switches to a different approach. If two fundamentally different approaches fail, it reports honestly what could not be verified and suggests `AGENTS.md` guidance for future runs.
|
|
26
|
+
|
|
27
|
+
## Plugin Contents
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
plugins/qa-changes/
|
|
31
|
+
├── README.md # This file
|
|
32
|
+
├── action.yml # Composite GitHub Action
|
|
33
|
+
├── skills/ # Symbolic links to QA skills
|
|
34
|
+
│ └── qa-changes -> ../../../skills/qa-changes
|
|
35
|
+
├── workflows/ # Example GitHub workflow files
|
|
36
|
+
│ └── qa-changes-by-openhands.yml
|
|
37
|
+
└── scripts/ # Python scripts for QA execution
|
|
38
|
+
├── agent_script.py # Main QA agent script
|
|
39
|
+
└── prompt.py # Prompt template
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Installation
|
|
43
|
+
|
|
44
|
+
### 1. Copy the Workflow File
|
|
45
|
+
|
|
46
|
+
Copy the workflow file to your repository's `.github/workflows/` directory:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
mkdir -p .github/workflows
|
|
50
|
+
cp plugins/qa-changes/workflows/qa-changes-by-openhands.yml \
|
|
51
|
+
.github/workflows/qa-changes-by-openhands.yml
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### 2. Configure Secrets
|
|
55
|
+
|
|
56
|
+
Add the following secrets in your repository settings (**Settings → Secrets and variables → Actions**):
|
|
57
|
+
|
|
58
|
+
| Secret | Required | Description |
|
|
59
|
+
|--------|----------|-------------|
|
|
60
|
+
| `LLM_API_KEY` | Yes | API key for your LLM provider |
|
|
61
|
+
| `GITHUB_TOKEN` | Auto | Provided automatically by GitHub Actions |
|
|
62
|
+
|
|
63
|
+
### 3. Create the QA Label (Optional)
|
|
64
|
+
|
|
65
|
+
Create a `qa-this` label for manual QA triggers:
|
|
66
|
+
|
|
67
|
+
1. Go to **Issues → Labels**
|
|
68
|
+
2. Click **New label**
|
|
69
|
+
3. Name: `qa-this`
|
|
70
|
+
4. Description: `Trigger OpenHands QA validation`
|
|
71
|
+
|
|
72
|
+
## Usage
|
|
73
|
+
|
|
74
|
+
### Automatic Triggers
|
|
75
|
+
|
|
76
|
+
QA validation is automatically triggered when:
|
|
77
|
+
- A new non-draft PR is opened (by trusted contributors)
|
|
78
|
+
- A draft PR is marked as ready for review
|
|
79
|
+
- The `qa-this` label is added
|
|
80
|
+
- `openhands-agent` is requested as a reviewer
|
|
81
|
+
|
|
82
|
+
### Requesting QA
|
|
83
|
+
|
|
84
|
+
**Option 1: Add Label**
|
|
85
|
+
|
|
86
|
+
Add the `qa-this` label to any PR.
|
|
87
|
+
|
|
88
|
+
**Option 2: Request as Reviewer**
|
|
89
|
+
|
|
90
|
+
Request `openhands-agent` as a reviewer on the PR.
|
|
91
|
+
|
|
92
|
+
## Action Inputs
|
|
93
|
+
|
|
94
|
+
| Input | Required | Default | Description |
|
|
95
|
+
|-------|----------|---------|-------------|
|
|
96
|
+
| `llm-model` | No | `anthropic/claude-sonnet-4-5-20250929` | LLM model to use |
|
|
97
|
+
| `llm-base-url` | No | `''` | Custom LLM endpoint URL |
|
|
98
|
+
| `extensions-repo` | No | `OpenHands/extensions` | Extensions repository |
|
|
99
|
+
| `extensions-version` | No | `main` | Git ref (tag, branch, or SHA) |
|
|
100
|
+
| `max-budget` | No | `10.0` | Maximum LLM cost in dollars — agent stops when exceeded |
|
|
101
|
+
| `timeout-minutes` | No | `30` | Wall-clock timeout for the QA step |
|
|
102
|
+
| `max-iterations` | No | `500` | Maximum agent iterations (each is one LLM call + action) |
|
|
103
|
+
| `llm-api-key` | Yes | - | LLM API key |
|
|
104
|
+
| `github-token` | Yes | - | GitHub token for API access |
|
|
105
|
+
|
|
106
|
+
## QA Report Format
|
|
107
|
+
|
|
108
|
+
The agent posts a PR comment with this structure:
|
|
109
|
+
|
|
110
|
+
```
|
|
111
|
+
## QA Report
|
|
112
|
+
|
|
113
|
+
**Summary**: [One-sentence verdict]
|
|
114
|
+
|
|
115
|
+
### Environment Setup
|
|
116
|
+
[Build/install results]
|
|
117
|
+
|
|
118
|
+
### CI Status
|
|
119
|
+
[Note whether CI checks pass or fail — do not re-run tests]
|
|
120
|
+
|
|
121
|
+
### Functional Verification
|
|
122
|
+
[Commands run, outputs observed, screenshots, behavior verified]
|
|
123
|
+
|
|
124
|
+
### Unable to Verify (if applicable)
|
|
125
|
+
[What could not be verified, what was attempted, suggested AGENTS.md guidance]
|
|
126
|
+
|
|
127
|
+
### Issues Found
|
|
128
|
+
- 🔴 **Blocker**: [Description]
|
|
129
|
+
- 🟠 **Issue**: [Description]
|
|
130
|
+
- 🟡 **Minor**: [Description]
|
|
131
|
+
|
|
132
|
+
### Verdict
|
|
133
|
+
✅ PASS / ⚠️ PASS WITH ISSUES / ❌ FAIL / 🟡 PARTIAL
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Customizing QA Guidelines
|
|
137
|
+
|
|
138
|
+
Add project-specific QA guidelines to your repository:
|
|
139
|
+
|
|
140
|
+
### Option 1: Custom QA Skill
|
|
141
|
+
|
|
142
|
+
Create `.agents/skills/qa-guide.md`:
|
|
143
|
+
|
|
144
|
+
```markdown
|
|
145
|
+
---
|
|
146
|
+
name: qa-guide
|
|
147
|
+
description: Project-specific QA guidelines
|
|
148
|
+
triggers:
|
|
149
|
+
- /qa-changes
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
# Project QA Guidelines
|
|
153
|
+
|
|
154
|
+
## Setup Commands
|
|
155
|
+
- `make install` to install dependencies
|
|
156
|
+
- `make build` to build the project
|
|
157
|
+
|
|
158
|
+
## How to Run the App
|
|
159
|
+
- `make serve` to start the dev server on port 8080
|
|
160
|
+
- `python -m myapp --help` for CLI usage
|
|
161
|
+
|
|
162
|
+
## Key Behaviors to Verify
|
|
163
|
+
- [List critical user flows]
|
|
164
|
+
- [List known fragile areas]
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Option 2: Repository AGENTS.md
|
|
168
|
+
|
|
169
|
+
Add setup and test commands to `AGENTS.md` at your repository root. The agent reads this file automatically.
|
|
170
|
+
|
|
171
|
+
## Security
|
|
172
|
+
|
|
173
|
+
The workflow uses `pull_request` (not `pull_request_target`) so that fork PRs do **not** get access to the base repository's secrets. Since the QA agent *executes* code from the PR (unlike a code-review agent which only reads diffs), using `pull_request_target` would allow untrusted fork code to run with the repo's `GITHUB_TOKEN` and `LLM_API_KEY`.
|
|
174
|
+
|
|
175
|
+
The trade-off is that fork PRs won't have access to repository secrets. In the example `pull_request` workflow, the action now detects that case and exits successfully with a clear skip notice instead of failing. Maintainers can run QA locally or set up a separate trusted workflow for those cases.
|
|
176
|
+
|
|
177
|
+
**Note**: The `FIRST_TIME_CONTRIBUTOR` and `NONE` author associations are excluded from automatic triggers as an additional safety layer.
|
|
178
|
+
|
|
179
|
+
## Contributing
|
|
180
|
+
|
|
181
|
+
See the main [extensions repository](https://github.com/OpenHands/extensions) for contribution guidelines.
|
|
182
|
+
|
|
183
|
+
## License
|
|
184
|
+
|
|
185
|
+
This plugin is part of the OpenHands extensions repository. See [LICENSE](/LICENSE) for details.
|