patch_review: Implement LLM-based CheckpatchFixer and SparseFixer with execution ordering#90
patch_review: Implement LLM-based CheckpatchFixer and SparseFixer with execution ordering#90ananghos-qti wants to merge 3 commits into
Conversation
| ──────────────────────────────────────── | ||
| OUTPUT FORMAT (STRICT) | ||
| ──────────────────────────────────────── | ||
| 1. Corrected git diff patch (valid unified diff) | ||
| 2. Corrected commit message (if modified) | ||
| 3. Safety checklist: | ||
| - [x] checkpatch issues addressed | ||
| - [x] No functional change | ||
| - [x] Patch structure preserved | ||
| - [x] Upstream-ready | ||
|
|
||
| DO NOT INCLUDE: | ||
| - Explanations | ||
| - Reasoning | ||
| - Analysis | ||
| - checkpatch logs | ||
| - Commentary | ||
|
|
||
| Only final results. |
There was a problem hiding this comment.
AI generated patches fail to apply with git am/git apply most of the time no matter what the prompt has. They are just bad at that.
A better design that actually works would be to let the AI do targeted edits to the files using a tool like write_file and then generate the patch using git diff HEAD~1. This patch is guaranteed to be git am-able on top of the commit being reviewed. Note that the tree in docker container is reset to the commit being reviewed.
I'd put this on hold until I upstream the AiPatchFix that fixes the issues reported by AiCodeReview. You can then use that as a reference.
|
|
||
| @register_llm_review | ||
| @register_long_review | ||
| class SparseFixer(AiReview): |
There was a problem hiding this comment.
AiReview has no tools!
Your fixer would be a single LLM call. There is no guarantee that the next sparse run will succeed.
AI should be given a tool to run sparse on the go so it can verify that the issues indeed have been fixed.
|
|
||
| @register_llm_review | ||
| @register_long_review | ||
| class CheckpatchFixer(AiReview): |
There was a problem hiding this comment.
Same here, AI should be given a tool to run checkpatch so that it can verify it passes.
| @register_llm_review | ||
| @register_long_review |
There was a problem hiding this comment.
We should do something like register_fixer(Checkpatch) that automatically routes the right review to each registered fixer.
Also run the fixers only when --fix is passed, just like checkpatch.
|
|
||
| # Sort reviews to ensure static analysis runs before fixers | ||
| # This ensures CheckpatchFixer gets Checkpatch output, SparseFixer gets Sparse output | ||
| def review_sort_key(review_class): |
There was a problem hiding this comment.
All reviews should run first, and only then should fixers run. This is to make sure we don't stall any reviews in the pipeline and ensure consistency in the code.
| # ============================================================================ | ||
| # Integration Tests | ||
| # ============================================================================ | ||
|
|
||
| class TestIntegration: | ||
| """Integration tests for fixers with PatchWise workflow.""" | ||
|
|
||
| def test_checkpatch_fixer_registration(self): | ||
| """Test that CheckpatchFixer is properly registered.""" | ||
| from patchwise.patch_review.decorators import AVAILABLE_PATCH_REVIEWS, LLM_REVIEWS | ||
|
|
||
| review_names = [cls.__name__ for cls in AVAILABLE_PATCH_REVIEWS] | ||
| assert 'CheckpatchFixer' in review_names | ||
|
|
||
| llm_review_names = [cls.__name__ for cls in LLM_REVIEWS] | ||
| assert 'CheckpatchFixer' in llm_review_names | ||
|
|
||
| def test_sparse_fixer_registration(self): | ||
| """Test that SparseFixer is properly registered.""" | ||
| from patchwise.patch_review.decorators import AVAILABLE_PATCH_REVIEWS, LLM_REVIEWS | ||
|
|
||
| review_names = [cls.__name__ for cls in AVAILABLE_PATCH_REVIEWS] | ||
| assert 'SparseFixer' in review_names | ||
|
|
||
| llm_review_names = [cls.__name__ for cls in LLM_REVIEWS] | ||
| assert 'SparseFixer' in llm_review_names | ||
|
|
||
| def test_fixers_extend_ai_review(self): | ||
| """Test that fixers properly extend AiReview base class.""" | ||
| from patchwise.patch_review.ai_review.ai_review import AiReview | ||
|
|
||
| assert issubclass(CheckpatchFixer, AiReview) | ||
| assert issubclass(SparseFixer, AiReview) | ||
|
|
||
| def test_fixers_have_required_methods(self): | ||
| """Test that fixers implement required methods.""" | ||
| # CheckpatchFixer | ||
| assert hasattr(CheckpatchFixer, 'setup') | ||
| assert hasattr(CheckpatchFixer, 'run') | ||
| assert hasattr(CheckpatchFixer, 'get_system_prompt') | ||
| assert hasattr(CheckpatchFixer, 'get_user_prompt') | ||
|
|
||
| # SparseFixer | ||
| assert hasattr(SparseFixer, 'setup') | ||
| assert hasattr(SparseFixer, 'run') | ||
| assert hasattr(SparseFixer, 'get_system_prompt') | ||
| assert hasattr(SparseFixer, 'get_user_prompt') |
There was a problem hiding this comment.
These tests are trivial and unnecessary. Please remove.
| assert hasattr(SparseFixer, 'get_user_prompt') | ||
|
|
||
|
|
||
| if __name__ == "__main__": |
There was a problem hiding this comment.
main() is not needed, The tests are run as:
pytest tests -v -s| # Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. | ||
| # SPDX-License-Identifier: BSD-3-Clause | ||
| """ | ||
| Unit tests for CheckpatchFixer and SparseFixer agents. |
There was a problem hiding this comment.
Unit tests are a burden to maintain when the project is in active development where refactors can happen frequently. Please write system tests instead.
Add something like:
tests/sparse/patches/p1.patch
tests/sparse/patches/p2.patch
tests/sparse/test_sparse_fixer.py
tests/checkpatch/patches/p1.patch
tests/checkpatch/test_checkpatch_fixer.py
Each fixer test should:
- Apply a patch
- Run the review
- Run the fixer
- Assert the fixer output
There was a problem hiding this comment.
Remove since this does not add anything over base,Dockerfile.
There was a problem hiding this comment.
Remove since this does not add anything over base,Dockerfile.
|
Thank you for this PR! Great idea to let patchwise fix the static analysis errors. We need a stronger "Fixer" framework that can be used across all the fixers. I'd put this on hold until I upstream the |
Probably need to move |
…gned to ai_patch_fix Signed-off-by: Ananya Ghosh <ananghos@qti.qualcomm.com>
20915c9 to
8dec548
Compare
Signed-off-by: ananghos-qti <ananghos@qti.qualcomm.com>
Signed-off-by: ananghos-qti <ananghos@qti.qualcomm.com>
Add two new AiReview-derived agents (CheckpatchFixer, SparseFixer) that consume static analysis output and apply LLM-powered fixes. Implement priority-based execution ordering in review_commit() to ensure static analyzers run before fixers, enabling proper data flow via kwargs.
Technical Implementation:
CheckpatchFixer Architecture:
SparseFixer Architecture:
Prompting Methodology:
Docker Integration:
Testing:
Execution Flow: