Triage GitHub issues with AI: detect duplicates by meaning and suggest labels. CLI + GitHub Action. Zero dependencies.
Project description
issuesort
Triage GitHub issues with AI — find duplicates and suggest labels. Zero dependencies.
When a new issue lands, issuesort compares it against the open issues by
meaning (embedding similarity) to surface likely duplicates, and asks a model
to pick fitting labels from your repository's own label set. It posts the result
as a comment, and can apply the labels for you.
Run it as a GitHub Action on every new issue, or invoke the CLI by hand. It uses any OpenAI-compatible API — including a local server — and nothing but the Python standard library.
Example comment
## issuesort triage
**Possible duplicates:**
- #128 App crashes when saving an empty file _(similarity 0.91)_
- #97 Save dialog throws on empty path _(similarity 0.86)_
**Suggested labels:** `bug`, `needs-repro`
Install
pip install issuesort
Requires Python 3.8+.
CLI usage
export OPENAI_API_KEY=sk-...
export GITHUB_TOKEN=ghp_...
# Print a triage for issue #42
issuesort --repo octocat/hello-world --issue 42
# Post it as a comment and apply the suggested labels
issuesort --repo octocat/hello-world --issue 42 --post --apply-labels
Options
| Flag | Description |
|---|---|
--repo OWNER/NAME |
Repository (required). |
--issue N |
Issue number (required). |
--threshold X |
Duplicate similarity cutoff, 0-1 (default 0.83). |
--top N |
Max duplicates to report (default 5). |
--no-labels |
Skip LLM label suggestion (duplicates only). |
--post |
Post the triage as an issue comment. |
--apply-labels |
Apply the suggested labels. |
--model / --embed-model |
Chat and embedding models. |
--base-url / --api-key |
Provider configuration. |
GitHub Action
Triage every newly opened issue. Store your provider key as a secret:
name: issuesort
on:
issues:
types: [opened]
permissions:
contents: read
issues: write
jobs:
triage:
runs-on: ubuntu-latest
steps:
- uses: Sev7nOfNine/issuesort@v0.1.0
with:
api-key: ${{ secrets.OPENAI_API_KEY }}
apply-labels: "false"
How duplicate detection works
The issue's title and body are embedded and compared against every open issue by
cosine similarity. Anything at or above --threshold is reported, best match
first. Tune the threshold to taste: higher is stricter.
Privacy note
Issue text is sent to whichever provider you configure. Prefer a self-hosted
model via --base-url for private repositories.
Development
pip install -e ".[test]"
python -m pytest
Tests run offline; the network layers accept injectable fakes.
License
MIT — see LICENSE.
Project details
Release history Release notifications | RSS feed
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 issuesort-0.1.0.tar.gz.
File metadata
- Download URL: issuesort-0.1.0.tar.gz
- Upload date:
- Size: 10.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fa07f0d9e4b6ff3e8f7d4a5606e17839b8e7ea98b8c4218d0825e349997929ff
|
|
| MD5 |
aa75f40ce49e6a10ee3b25e156a5e80a
|
|
| BLAKE2b-256 |
28469535b794ebca915e2803591a30fe71551f369fd887cf320e0c9bba2f6294
|
File details
Details for the file issuesort-0.1.0-py3-none-any.whl.
File metadata
- Download URL: issuesort-0.1.0-py3-none-any.whl
- Upload date:
- Size: 11.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3919d07d1e95e06303099a7476088eea0f2bc82869ba2d1ae5e4451bafcbe00f
|
|
| MD5 |
d89e26c383c9efa5241c257450637f34
|
|
| BLAKE2b-256 |
c3ed574a8a5c54a9ba9bb03b66a0bbc65b912d345300bfe39f6b023f916c976e
|