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.
## 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`pip install issuesortRequires Python 3.8+.
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| 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. |
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/[email protected]
with:
api-key: ${{ secrets.OPENAI_API_KEY }}
apply-labels: "false"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.
Issue text is sent to whichever provider you configure. Prefer a self-hosted
model via --base-url for private repositories.
pip install -e ".[test]"
python -m pytestTests run offline; the network layers accept injectable fakes.
MIT — see LICENSE.