⚡ Issue AI Agent

May 21, 2026 · View on GitHub

⚡ Issue AI Agent

AI-powered GitHub Issue triage — classify, label, and reply automatically

GitHub Marketplace GitHub Action License: MIT PRs Welcome

Discuss on linux.do

What It Does

When someone opens an issue in your repository, Issue AI Agent:

  1. Classifies the issue into a category (bug, feature, question, docs, duplicate, invalid, security)
  2. Labels it with matching labels and a priority level (critical, high, medium, low)
  3. Detects duplicates by searching existing issues and linking potential matches
  4. Replies with a contextual comment — bugs get asked for reproduction steps, features get acknowledged, etc.
  5. Handles follow-up comments — replies to user comments with relevant information

All in ~8 seconds, powered by your LLM of choice.

Demo

Demo: Issue AI Agent classifying and replying to a new issue

  1. User opens an issue — describes a login page crash
  2. Bot classifies — labels it bug / priority: high in ~8 seconds
  3. Bot replies — asks for reproduction details
  4. Duplicate check — searches existing issues and links potential matches
  5. Follow-up comments — replies to user comments with relevant info

Quick Start

Step 1: Add a workflow file

Create .github/workflows/issue-ai.yml in your repository:

name: Issue AI Agent

on:
  issues:
    types: [opened]
  issue_comment:
    types: [created]

jobs:
  triage:
    runs-on: ubuntu-latest
    permissions:
      issues: write
      contents: read
    steps:
      - uses: alexyan0431/issue-ai-agent@v1
        with:
          anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}

Step 2: Add your API key

Go to Settings > Secrets and variables > Actions > New repository secret:

Step 3: Open an issue

That's it. The bot will automatically classify, label, and reply to new issues.

LLM Providers

The bot supports any Anthropic or OpenAI API. Use the three inputs — <provider>-api-key, llm-provider, and llm-base-url — to match your setup.

Anthropic

- uses: alexyan0431/issue-ai-agent@v1
  with:
    anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}
    llm-provider: anthropic

OpenAI

- uses: alexyan0431/issue-ai-agent@v1
  with:
    openai-api-key: ${{ secrets.OPENAI_API_KEY }}
    llm-provider: openai

Custom API endpoint

If your provider exposes an Anthropic or OpenAI compatible API, point llm-base-url to its address:

# Anthropic-compatible endpoint
- uses: alexyan0431/issue-ai-agent@v1
  with:
    anthropic-api-key: ${{ secrets.LLM_API_KEY }}
    llm-provider: anthropic
    llm-base-url: https://your-provider.example.com/api/anthropic
# OpenAI-compatible endpoint
- uses: alexyan0431/issue-ai-agent@v1
  with:
    openai-api-key: ${{ secrets.LLM_API_KEY }}
    llm-provider: openai
    llm-base-url: https://your-provider.example.com/v1

If you use a custom model, create .github/issue-ai.yml in your repo to specify it:

llm:
  model: your-model-name

Configuration

Create .github/issue-ai.yml in your repository to customize behavior. The bot works out of the box with sensible defaults — no config file required.

# .github/issue-ai.yml
enabled: true

features:
  classify: true        # Auto-classify issues
  reply: true           # Post AI-drafted replies
  duplicateSearch: true  # Detect duplicate issues
  commentReply: true     # Reply to follow-up comments

label_mapping:
  bug: ["bug"]
  feature: ["enhancement"]
  question: ["question"]
  docs: ["documentation"]
  duplicate: ["duplicate"]
  invalid: ["invalid"]
  security: ["security"]

security:
  max_issue_length: 10000    # Max chars of issue body to process

exclude:
  labels: ["wontfix", "skip-ai"]       # Skip issues with these labels
  users: ["dependabot[bot]"]           # Skip issues from these users

llm:
  provider: anthropic                   # "anthropic" or "openai"
  model: claude-haiku-4-5-20251001     # Model to use
  max_tokens: 2048                      # Max tokens per LLM response

Config Reference

KeyDefaultDescription
enabledtrueMaster on/off switch
features.classifytrueEnable issue classification + labeling
features.replytrueEnable AI-drafted reply comments
features.duplicateSearchtrueSearch for duplicate issues and link them
features.commentReplytrueReply to follow-up comments on issues
label_mapping(see defaults above)Maps AI categories to your repo's label names
security.max_issue_length10000Truncate issue body beyond this length
exclude.labels["wontfix", "skip-ai"]Skip issues carrying these labels
exclude.users["dependabot[bot]"]Skip issues opened by these users
llm.provider"anthropic"LLM provider: "anthropic" or "openai"
llm.modelclaude-haiku-4-5-20251001Model identifier
llm.max_tokens2048Max tokens for LLM responses

Action Inputs & Outputs

Inputs

InputRequiredDefaultDescription
github-tokenNo${{ github.token }}GitHub token for API access
anthropic-api-keyNoAnthropic API key
openai-api-keyNoOpenAI API key
llm-providerNoanthropicWhich LLM provider to use
llm-base-urlNoCustom base URL for LLM API (applies to selected provider)
config-pathNo.github/issue-ai.ymlPath to config file in repo

At least one API key is required. If neither is set, the bot runs in dev mode with mock responses.

Outputs

OutputDescription
categoryClassified issue category
priorityClassified issue priority
labels-appliedComma-separated list of applied labels
reply-postedWhether a reply comment was posted

Development

npm ci              # Install dependencies
npm run build       # Compile TypeScript
npm run bundle      # Bundle for GitHub Action (dist/index.js)
npm test            # Run tests (Vitest)
npm run test:watch  # Watch mode
npm run dev         # TypeScript watch mode

Architecture

GitHub Action (issues.opened / issue_comment.created)
  → loadConfig()    — Fetch .github/issue-ai.yml via GitHub API
  → shouldExclude() — Check exclude rules
  → classify        — LLM classifies the issue (category + priority)
  → label           — Maps classification to repo labels via GitHub API
  → duplicate       — Searches similar issues, LLM confirms duplicates
  → reply           — Drafts and posts a contextual comment via LLM

Key design decisions:

  • Stateless — no database; reads config from each repo's .github/issue-ai.yml
  • Error-resilient — each pipeline step catches its own errors, so a classification failure doesn't block the reply
  • Security-first — input sanitization (zero-width chars, control chars, length limits) + explicit untrusted-data markers in prompts

License

MIT