Compare commits

...

1 Commits

Author SHA1 Message Date
openhands
6c250b0c39 Fix: Explicitly instruct agent to respect pre-commit hooks
This commit addresses issue #11409 where pre-commit hooks were not being
automatically executed when the agent creates commits for pull requests.

Changes made:
1. Updated microagents (github.md, gitlab.md, bitbucket.md) to explicitly
   instruct agents to NEVER use the --no-verify flag when making commits,
   ensuring pre-commit hooks configured in .openhands/pre-commit.sh are
   always executed.

2. Updated system_prompt.j2 for CodeActAgent to include explicit instruction
   against using --no-verify in the VERSION_CONTROL section.

3. Added comprehensive tests in test_pre_commit_instructions.py to verify
   that all git-related microagents and the system prompt contain proper
   instructions about respecting pre-commit hooks.

The fix ensures that:
- Pre-commit hooks are executed to enforce code quality standards
- Project-specific checks configured by users are always respected
- The agent's behavior aligns with standard git workflows

Fixes #11409

Co-authored-by: openhands <openhands@all-hands.dev>
2025-10-16 17:20:18 +00:00
5 changed files with 126 additions and 0 deletions

View File

@@ -27,6 +27,7 @@ Here are some instructions for pushing, but ONLY do this if the user asks you to
* Use the main branch as the base branch, unless the user requests otherwise
* After opening or updating a pull request, send the user a short message with a link to the pull request.
* Do NOT mark a pull request as ready to review unless the user explicitly says so
* IMPORTANT: When making commits, NEVER use the `--no-verify` flag. Pre-commit hooks (if configured in `.openhands/pre-commit.sh`) must be executed to ensure code quality and enforce project standards.
* Do all of the above in as few steps as possible. E.g. you could push changes with one step by running the following bash commands:
```bash
git remote -v && git branch # to find the current org, repo and branch

View File

@@ -28,6 +28,7 @@ Here are some instructions for pushing, but ONLY do this if the user asks you to
* Use the main branch as the base branch, unless the user requests otherwise
* After opening or updating a pull request, send the user a short message with a link to the pull request.
* Do NOT mark a pull request as ready to review unless the user explicitly says so
* IMPORTANT: When making commits, NEVER use the `--no-verify` flag. Pre-commit hooks (if configured in `.openhands/pre-commit.sh`) must be executed to ensure code quality and enforce project standards.
* Do all of the above in as few steps as possible. E.g. you could push changes with one step by running the following bash commands:
```bash
git remote -v && git branch # to find the current org, repo and branch

View File

@@ -27,6 +27,7 @@ Here are some instructions for pushing, but ONLY do this if the user asks you to
* Once you've created your own branch or a merge request, continue to update it. Do NOT create a new one unless you are explicitly asked to. Update the PR title and description as necessary, but don't change the branch name.
* Use the main branch as the base branch, unless the user requests otherwise
* After opening or updating a merge request, send the user a short message with a link to the merge request.
* IMPORTANT: When making commits, NEVER use the `--no-verify` flag. Pre-commit hooks (if configured in `.openhands/pre-commit.sh`) must be executed to ensure code quality and enforce project standards.
* Do all of the above in as few steps as possible. E.g. you could push changes with one step by running the following bash commands:
```bash
git remote -v && git branch # to find the current org, repo and branch

View File

@@ -35,6 +35,7 @@ Your primary role is to assist users by executing commands, modifying code, and
* If there are existing git user credentials already configured, use them and add Co-authored-by: openhands <openhands@all-hands.dev> to any commits messages you make. if a git config doesn't exist use "openhands" as the user.name and "openhands@all-hands.dev" as the user.email by default, unless explicitly instructed otherwise.
* Exercise caution with git operations. Do NOT make potentially dangerous changes (e.g., pushing to main, deleting repositories) unless explicitly asked to do so.
* When committing changes, use `git status` to see all modified files, and stage all files necessary for the commit. Use `git commit -a` whenever possible.
* NEVER use the `--no-verify` flag when making commits. Pre-commit hooks must be allowed to run to enforce code quality standards and project-specific checks configured in `.openhands/pre-commit.sh`.
* Do NOT commit files that typically shouldn't go into version control (e.g., node_modules/, .env files, build directories, cache files, large binaries) unless explicitly instructed by the user.
* If unsure about committing certain files, check for the presence of .gitignore files or ask the user for clarification.
</VERSION_CONTROL>

View File

@@ -0,0 +1,122 @@
"""Test that agent instructions properly address pre-commit hooks.
This test ensures that the agent's instructions (microagents and system prompts)
explicitly mention NOT using --no-verify flag to ensure pre-commit hooks are executed.
"""
from pathlib import Path
import pytest
class TestPreCommitInstructions:
"""Test that agent instructions properly guide the agent to respect pre-commit hooks."""
@pytest.fixture
def microagents_dir(self) -> Path:
"""Get the microagents directory."""
return Path(__file__).parent.parent.parent / 'microagents'
@pytest.fixture
def system_prompt_file(self) -> Path:
"""Get the system prompt file for CodeActAgent."""
return (
Path(__file__).parent.parent.parent
/ 'openhands'
/ 'agenthub'
/ 'codeact_agent'
/ 'prompts'
/ 'system_prompt.j2'
)
def test_github_microagent_mentions_no_verify(self, microagents_dir: Path):
"""Test that github.md microagent mentions not using --no-verify."""
github_md = microagents_dir / 'github.md'
assert github_md.exists(), 'github.md microagent file should exist'
content = github_md.read_text()
# Check that it mentions not using --no-verify
assert '--no-verify' in content.lower(), (
'github.md should mention --no-verify flag'
)
assert 'never' in content.lower() and '--no-verify' in content.lower(), (
'github.md should instruct to NEVER use --no-verify'
)
assert 'pre-commit' in content.lower(), (
'github.md should mention pre-commit hooks'
)
def test_gitlab_microagent_mentions_no_verify(self, microagents_dir: Path):
"""Test that gitlab.md microagent mentions not using --no-verify."""
gitlab_md = microagents_dir / 'gitlab.md'
assert gitlab_md.exists(), 'gitlab.md microagent file should exist'
content = gitlab_md.read_text()
# Check that it mentions not using --no-verify
assert '--no-verify' in content.lower(), (
'gitlab.md should mention --no-verify flag'
)
assert 'never' in content.lower() and '--no-verify' in content.lower(), (
'gitlab.md should instruct to NEVER use --no-verify'
)
assert 'pre-commit' in content.lower(), (
'gitlab.md should mention pre-commit hooks'
)
def test_bitbucket_microagent_mentions_no_verify(self, microagents_dir: Path):
"""Test that bitbucket.md microagent mentions not using --no-verify."""
bitbucket_md = microagents_dir / 'bitbucket.md'
assert bitbucket_md.exists(), 'bitbucket.md microagent file should exist'
content = bitbucket_md.read_text()
# Check that it mentions not using --no-verify
assert '--no-verify' in content.lower(), (
'bitbucket.md should mention --no-verify flag'
)
assert 'never' in content.lower() and '--no-verify' in content.lower(), (
'bitbucket.md should instruct to NEVER use --no-verify'
)
assert 'pre-commit' in content.lower(), (
'bitbucket.md should mention pre-commit hooks'
)
def test_system_prompt_mentions_no_verify(self, system_prompt_file: Path):
"""Test that system_prompt.j2 mentions not using --no-verify."""
assert system_prompt_file.exists(), (
'system_prompt.j2 file should exist for CodeActAgent'
)
content = system_prompt_file.read_text()
# Check that it mentions not using --no-verify in VERSION_CONTROL section
assert '--no-verify' in content.lower(), (
'system_prompt.j2 should mention --no-verify flag'
)
assert 'never' in content.lower() and '--no-verify' in content.lower(), (
'system_prompt.j2 should instruct to NEVER use --no-verify'
)
assert 'pre-commit' in content.lower(), (
'system_prompt.j2 should mention pre-commit hooks'
)
def test_git_microagents_show_correct_commit_examples(self, microagents_dir: Path):
"""Test that git-related microagents show commit examples without --no-verify."""
for microagent_file in ['github.md', 'gitlab.md', 'bitbucket.md']:
file_path = microagents_dir / microagent_file
content = file_path.read_text()
# Find all code examples with git commit
lines = content.split('\n')
in_code_block = False
for line in lines:
if line.strip().startswith('```'):
in_code_block = not in_code_block
elif in_code_block and 'git commit' in line:
# Ensure the example doesn't use --no-verify
assert '--no-verify' not in line.lower(), (
f'{microagent_file} should not show examples using '
f'--no-verify flag: {line}'
)