BOUNTY
A command-line agent that tries to fix GitHub issues for you.
You point it at a repository. It fetches open issues, skips the ones that
look too hard, finds the relevant files, writes a small patch and a test,
and runs that change in an isolated sandbox. If the checks pass, it shows
you the diff. A pull request is opened only if you type approve.
Start on a repo you own. Do not fire it at a popular project whose contributing guide forbids unsolicited AI PRs.
Install
You need Python 3.11+, Git, and three API keys:
GITHUB_TOKEN— a personal access token withreposcope (fork + PR)OPENAI_API_KEY— chat and embeddingsE2B_API_KEY— remote sandbox (e2b.dev)
You do not need to clone this repository. Install the command, then add your keys, then run it from any folder:
python -m pip install --user pipx
pipx install git+https://github.com/Mehaksaluja/Bounty.git
bounty --init-global
That writes %USERPROFILE%\.bounty.env on Windows, or ~/.bounty.env on
macOS and Linux. Open the file, paste the three keys, save. You only do
this once.
GITHUB_TOKEN=github_pat_...
OPENAI_API_KEY=sk-...
E2B_API_KEY=e2b_...
bounty --init does the same thing but as .env in the folder you are in,
if you would rather keep keys per-project.
Keys already in the environment (setx on Windows, export on Unix) are
used as-is and win over both files.
If you already use a virtualenv and prefer pip:
pip install git+https://github.com/Mehaksaluja/Bounty.git
Cloning the repo is only for people who want to change the code.
Use it
bounty
That is the normal path. It asks for owner/repo, fetches open issues,
triages them, prints a table, then asks which issue number to fix. Press
Enter to stop after the table.
bounty --repo yourname/your-repo
Same flow, but skips typing the repo name. After the table it still asks
which issue to fix. --fix 12 is only if you already know the number and
want to skip the table.
Run it from a folder you are happy to keep cache in. Clones, the search
index, patches, and the SQLite database are written into the current
directory (workspace/, chroma_db/, output/, bounty.db).
Useful flags:
bounty --repo yourname/your-repo --fix 12 --no-submit
bounty --repo yourname/your-repo --submit 12
bounty --repo yourname/your-repo --no-fetch
bounty --repo yourname/your-repo --pr-status
bounty --metrics
--no-submit stops after the sandbox and does not ask about a PR.
--submit 12 reviews a patch already saved from a previous --fix 12.
--no-fetch reuses issues already in the local database.
Models default to gpt-4o-mini. Set BOUNTY_MODEL or
BOUNTY_<ROLE>_MODEL in .env to change that (triage, locator,
planner, coder, test_writer, reviewer).
What it spends
Every --fix uses OpenAI tokens and an E2B sandbox. Fetch and triage use
OpenAI too. Opening a PR uses GitHub. There is no free full run.
What it checks before asking you
- The new test passes with the patch
- The same test fails without the patch
- The project's existing tests still pass
- The linter is clean on the changed files
If check 2 fails, the issue is probably already fixed on main, or the
test does not actually hit the bug. BOUNTY will not open a PR for that
unless you type force.
Metrics
After you have used it for a while:
bounty --metrics
bounty --repo yourname/your-repo --grade 12 --actually yes
--grade is how you tell it whether triage was right. Precision is n/a
until you label at least one issue.
What fails and why
These are failures from real runs, mostly against pallets/click.
The bug is already gone on main. Check 2 catches this: the new test
passes with and without the patch. Click #2402 failed this way. The code
already handled cmd is None; the leftover work was documentation.
A passing test is not a valid test. Check 1 can succeed while the test never exercises the bug. Check 2 exists to catch that.
The model quotes its previous patch as old_code. Patches always apply
against the original files. A retry that copies the last new_code will
not match.
Large files cannot be rewritten whole. The coder emits small
old_code / new_code hunks. Full-file rewrites blow the model limit on
modules like Click's core.py.
Windows paths break the Linux sandbox. Paths are converted to posix before any sandbox command. Tests that import packages the project does not depend on fail at collection, before the fix is tested.
E2B, not Docker. The sandbox is a remote VM. A hang there still costs money; commands are timed out.
Do not send drive-by AI PRs at unwilling maintainers. Use a repo you own first.
Proof
No pull request opened by this agent has been merged yet.
- repo / issue:
- PR URL:
- merged at:
Contributing
Clone the repo only if you are changing it:
git clone https://github.com/Mehaksaluja/Bounty.git
cd Bounty
python -m venv venv
.\venv\Scripts\activate
pip install -e .
python tests/test_offline.py
tests/test_offline.py does not call OpenAI, GitHub, or E2B.
bounty and python -m bounty are the same program.
src/bounty/ the package
tests/ offline and pipeline checks
README.md
LICENSE
pyproject.toml
.env.example
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file bounty_agent-0.1.0.tar.gz.
File metadata
- Download URL: bounty_agent-0.1.0.tar.gz
- Upload date:
- Size: 91.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.12.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d009a8024af594cf9588653fb61d01302e537a97325c7f24d84df46ab96ef203
|
|
| MD5 |
2a4f5c343eef99e5f35d1a4b870d76dc
|
|
| BLAKE2b-256 |
45b891d0bfbff7360457386f74d0ae2b19d038a0bad40d8cd3ed753c17788369
|
File details
Details for the file bounty_agent-0.1.0-py3-none-any.whl.
File metadata
- Download URL: bounty_agent-0.1.0-py3-none-any.whl
- Upload date:
- Size: 86.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.12.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fcceda07ea06491863e44279f007e28ad07d8cb0cf8ca7e45a8559971f008447
|
|
| MD5 |
31d863f3a78028f056055974394cda29
|
|
| BLAKE2b-256 |
9bf71ceaf38e6f7832611f82688fd29dec8f09efbd7922b26b4ed47f6a61e9bd
|