AI Features

AI Code Review

Chain the github module (or git.diff) and ai.generate to produce automated code reviews on every pull request — and post inline comments, PR summaries, Slack notifications, or Jira tickets.

How It Works

1
Fetch the diff
github.get_diff fetches the PR diff via the GitHub API.
2
Analyze with AI
ai.generate sends the diff to your model with a review prompt.
3
Post inline comments
github.post_inline_comments posts line-by-line feedback on the PR.
4
Summarize
github.post_comment posts an overall review summary to the PR.

GitHub PR Review with Inline Comments

Full workflow: fetch diff → AI analysis → inline PR comments → summary comment.

json
{
  "name": "github-code-review",
  "steps": [
    {
      "id": "get-diff",
      "type": "github",
      "config": {
        "operation": "get_diff"
      }
    },
    {
      "id": "ai-review",
      "type": "ai.generate",
      "depends_on": ["get-diff"],
      "config": {
        "prompt": "Review this code diff:\n\n{{steps.get-diff.diff}}\n\nList issues with file path and line number. Format: 'path/to/file.go:42 - issue description'"
      }
    },
    {
      "id": "post-inline-comments",
      "type": "github",
      "depends_on": ["ai-review"],
      "config": {
        "operation": "post_inline_comments",
        "body": "{{steps.ai-review.content}}",
        "output_format": "text",
        "dedup": true
      }
    },
    {
      "id": "post-summary",
      "type": "github",
      "depends_on": ["ai-review"],
      "config": {
        "operation": "post_comment",
        "body": "🤖 AI Review Complete\n\n{{steps.ai-review.content}}"
      }
    }
  ]
}

Required environment variables

GITHUB_TOKENGitHub personal access token with repo and pull-requests write scope
GITHUB_REPOSITORY_OWNERRepository owner (e.g. myorg)
GITHUB_REPOSITORYRepository name (e.g. myorg/myrepo)
GITHUB_PR_NUMBERPull request number
GITHUB_SHACommit SHA to attach inline comments to

In GitHub Actions these are available automatically — pass them via the env: block.

Inline Comments: Text vs JSON Format

The post_inline_comments operation supports two input formats controlled by output_format.

Text format (default)

AI returns free-text. Shiro parses file:line - comment patterns automatically.

json
{
  "id": "post-inline-comments",
  "type": "github",
  "config": {
    "operation": "post_inline_comments",
    "body": "{{steps.ai-review.content}}",
    "output_format": "text"
  }
}

Prompt the AI like: "Format each issue as: path/to/file.go:42 - description"

JSON format

AI returns a JSON array. Use output_format: json and pass structured output via comments.

json
{
  "id": "post-inline-comments",
  "type": "github",
  "config": {
    "operation": "post_inline_comments",
    "output_format": "json",
    "comments": "{{steps.ai-review.json}}"
  }
}

Each comment object must have: file, line, comment.

ai.generate Configuration Reference

FieldTypeRequiredDescription
promptstringYesThe user prompt sent to the model. Supports variable interpolation.
modelstringNoModel name. Must match a key in .shiro/config.yaml. Defaults to the only configured model.
providerstringNoProvider key from config.yaml. Auto-resolved if only one is configured.
systemstringNoSystem prompt to set the model's persona or behavior.
temperaturefloatNoSampling temperature (0.0–1.0). Lower = more deterministic. Default: model default.
max_tokensintegerNoMaximum tokens in the response.

ai.generate output variables

{{steps.STEP_ID.content}}Raw text content from the model response
{{steps.STEP_ID.usage.prompt_tokens}}Number of prompt tokens used
{{steps.STEP_ID.usage.completion_tokens}}Number of completion tokens used
{{steps.STEP_ID.usage.total_tokens}}Total tokens used

Review + Slack Notification

json
{
  "name": "review-and-notify",
  "steps": [
    {
      "id": "get-diff",
      "type": "github",
      "config": { "operation": "get_diff" }
    },
    {
      "id": "ai-review",
      "type": "ai.generate",
      "depends_on": ["get-diff"],
      "config": {
        "system": "You are a senior engineer. Review for bugs and security issues. Output a brief summary with severity: LOW, MEDIUM, or HIGH.",
        "prompt": "Diff to review:\n{{steps.get-diff.diff}}",
        "temperature": 0.1
      }
    },
    {
      "id": "notify",
      "type": "slack.notify",
      "depends_on": ["ai-review"],
      "config": {
        "webhook_url": "{{env.SLACK_WEBHOOK_URL}}",
        "message": ":robot_face: *AI Code Review*\n{{steps.ai-review.content}}"
      }
    }
  ]
}

GitHub Actions Setup

yaml
name: AI Code Review

on:
  pull_request:
    types: [opened, synchronize, reopened]

permissions:
  contents: read
  pull-requests: write

jobs:
  code-review:
    runs-on: ubuntu-latest
    container:
      image: ghcr.io/rajitk13/shiro-automation:latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Run Shiro Code Review
        run: shiro run
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
          GITHUB_REPOSITORY: ${{ github.repository }}
          GITHUB_REPOSITORY_OWNER: ${{ github.repository_owner }}
          GITHUB_PR_NUMBER: ${{ github.event.pull_request.number }}
          GITHUB_SHA: ${{ github.sha }}

GitLab CI Setup

yaml
ai-review:
  stage: review
  image: ghcr.io/rajitk13/shiro-automation:latest
  script:
    - shiro run
  variables:
    GITLAB_TOKEN: $GL_TOKEN
    OPENAI_API_KEY: $OPENAI_API_KEY
  only:
    - merge_requests

Prompting Tips

Use a strong system prompt
Define the reviewer persona: "You are a senior security engineer..." gives much more focused output than a generic prompt.
Keep temperature low
Use temperature: 0.1–0.3 for code review. Higher values produce creative but inconsistent feedback.
Use the file:line format for inline comments
Ask the model to format each issue as: "path/to/file.go:42 - description". Shiro's text parser extracts these automatically.
Use JSON format for structured downstream steps
If you need to pass review data to another step (e.g. Jira ticket creation), use output_format: json and json_schema to enforce structure.
Enable deduplication
Set dedup: true on post_inline_comments to avoid re-posting the same comment on every push.