Generate knowledge suggestions from GitHub pull requests
The Brainfish Knowledge Suggestions GitHub Action turns your code changes into article suggestions. Each time a pull request is opened, merged, or run manually, the action sends the PR title, description, commits, and the code changes to Brainfish. Large changes are summarized first. Brainfish then analyses the change and suggests updates to your help content, so your documentation keeps pace with your product.
Action repository: github.com/brainfish-ai/knowledge-suggestions
Latest release: v1.0.0. Use it in your workflows as brainfish-ai/knowledge-suggestions@v1.
How it works
- A GitHub workflow runs the action, either on a pull request event, on a push, or manually for a specific PR number.
- The action collects the PR title and description, labels, commit messages, and the code diff.
- It drops lock files, generated files, and binary files from the diff. If the remaining diff is small, it is kept in full. If it is large, it is replaced by a summary of the changed files and functions.
- The action sends the result to Brainfish, optionally targeting a specific collection.
- The Brainfish Knowledge Discovery Agent analyses the change asynchronously and generates article suggestions.
- Suggestions go to a review queue, so you can check them before anything changes in your knowledge base.
The action only triggers the suggestion pipeline. It returns a
task_idand does not wait for the suggestions to be generated.
Before you begin
You need:
- A Brainfish API token. Open the Brainfish Dashboard, go to Settings → API Tokens, and click Create token. The token starts with
bf_api_. - A GitHub repository where you can add workflows and secrets.
- (Optional) The ID of the Brainfish collection you want suggestions to target.
Store your API token as a GitHub secret
- In your GitHub repository, go to Settings → Secrets and variables → Actions.
- Click New repository secret.
- Name it
BRAINFISH_API_KEYand paste your token as the value.
Never put the token directly in a workflow file.
Find a collection ID (optional)
Open the collection in the Brainfish Dashboard. The collection ID is a UUID, for example c8b2e30c-d3a7-4314-9dec-d55dcb53b8f5. If you leave collection_id out, Brainfish chooses where suggestions go.
Option 1: Suggest on every pull request
Add this workflow at .github/workflows/suggest-articles.yml:
name: Suggest articles
on:
pull_request:
types: [opened, synchronize]
jobs:
suggest:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: brainfish-ai/knowledge-suggestions@v1
with:
api_key: ${{ secrets.BRAINFISH_API_KEY }}
collection_id: "your-collection-uuid" # optional
fetch-depth: 0 is required in this mode. The action compares your changes against the PR's base commit, so it needs the full git history.
Option 2: Suggest when a pull request is merged
Use the pr_number input to fetch a pull request directly from the GitHub API. In this mode you don't need a checkout step, and the action can run on any event.
name: Suggest articles from merged PR
on:
pull_request:
types: [closed]
permissions:
pull-requests: read
jobs:
suggest:
if: github.event.pull_request.merged == true
runs-on: ubuntu-latest
steps:
- uses: brainfish-ai/knowledge-suggestions@v1
with:
api_key: ${{ secrets.BRAINFISH_API_KEY }}
pr_number: ${{ github.event.pull_request.number }}
Suggesting only on merge is a good way to avoid suggestions for work that never ships.
Option 3: Run manually for any pull request
This workflow adds a Run workflow button in GitHub. Enter a PR number and the action generates suggestions for it. It's useful for back-filling suggestions from older PRs.
name: Suggest articles for a PR
on:
workflow_dispatch:
inputs:
pr_number:
description: "Pull request number"
required: true
jobs:
suggest:
runs-on: ubuntu-latest
permissions:
pull-requests: read
steps:
- uses: brainfish-ai/knowledge-suggestions@v1
with:
api_key: ${{ secrets.BRAINFISH_API_KEY }}
pr_number: ${{ inputs.pr_number }}
Option 4: Suggest on every push to main
name: Suggest articles
on:
push:
branches: [main]
jobs:
suggest:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: brainfish-ai/knowledge-suggestions@v1
with:
api_key: ${{ secrets.BRAINFISH_API_KEY }}
What gets sent to Brainfish
The action sends a single Markdown document with this structure:
# Changes
## <Pull request title>
Pull request: <link>
Labels: <labels>
<Pull request description>
## Commits
### <Commit subject>
<Commit body>
## Diff (or "## Diff summary" for large changes)
<code diff or summary>
The PR title, description, and labels give Brainfish the why behind a change, while the commits and diff show what changed. Write clear PR descriptions. They directly improve the quality of the suggestions, especially for large changes where only a summary of the code is sent.
Lock files and generated files are never sent
These files are dropped from the diff before anything is sent:
- Lock files:
package-lock.json,npm-shrinkwrap.json,pnpm-lock.yaml,go.sum, and any*.lockfile such asyarn.lock,Cargo.lock,poetry.lock,uv.lock,Gemfile.lock,composer.lock, orPodfile.lock - Generated or minified files:
*.min.js,*.min.css,*.map,*.snap - Build output and dependencies: anything under
dist/,build/,node_modules/, orvendor/ - Binary files such as images
The names of dropped files are still listed, so Brainfish knows they changed. If a pull request only changes these files, for example an automated dependency update, nothing is sent.
Large pull requests are summarized
After noise files are dropped, the action counts the lines in the remaining diff:
- 1,000 lines or fewer: the full diff is sent.
- More than 1,000 lines: the raw code is left out and a summary is sent instead.
The summary is built directly from the diff, without AI, and contains:
- The total number of files changed and lines added and removed
- A table of changed files with their status (added, modified, deleted, or renamed) and line counts, largest changes first
- The functions, classes, or sections touched in each file
For example:
## Diff summary
The full diff is 6004 lines, which is over the 1000-line limit, so only a summary is included.
Excluded 1 lock, generated or binary file(s): `go.sum`
Files changed: 70 (+3792 / -575)
### Files
| Status | File | Lines |
|----------|-----------------|-------------|
| added | `api/request.go` | +443 / -0 |
| modified | `api/client.go` | +163 / -4 |
### Changed areas
#### `api/client.go`
- `func HandleHTTPError(resp *http.Response) error {`
To change the limit, set the max_diff_lines input. For example, max_diff_lines: 3000 sends more diffs in full, and max_diff_lines: 0 always sends a summary instead of code.
For small changes, the code diff is sent to Brainfish. Don't run the action on repositories where that content shouldn't leave GitHub, or set
max_diff_lines: 0so only file names and function names are sent.
Inputs
| Input | Required | Description |
|---|---|---|
api_key | Yes | Brainfish API token used for authentication |
collection_id | No | Collection ID to target for suggestions |
pr_number | No | Pull request number to generate suggestions from. Fetched via the GitHub API, so no checkout is needed |
repository | No | Repository (owner/name) that contains the PR. Only used with pr_number. Defaults to the current repository |
github_token | No | Token used to read the PR. Only used with pr_number. Defaults to the workflow's github.token |
base | No | Base commit SHA to generate the diff from |
max_diff_lines | No | Diffs up to this many lines are sent in full; larger diffs are replaced by a summary. Defaults to 1000 |
api_url | No | Brainfish API base URL. Defaults to https://api.brainfi.sh |
Outputs
| Output | Description |
|---|---|
task_id | The task ID of the triggered suggestion pipeline |
status | The status of the suggestion request |
How the action decides what to compare
The action picks the source of the change in this order:
pr_numberis set: the PR's content and diff are fetched from the GitHub API.baseis set: the diff betweenbaseand the current commit.- The workflow runs on a pull request: the diff against the PR's base branch.
- The workflow runs on a push: the diff against the commit before the push.
- Otherwise: the diff against the previous commit.
If there are no relevant changes to send, the action skips the request and prints a warning. It does not fail the workflow.
Versions and updates
The action follows semantic versioning. Choose how you reference it in your workflow:
| Reference | What you get | Use it when |
|---|---|---|
brainfish-ai/knowledge-suggestions@v1 | The latest v1.x release. You receive fixes and new features automatically, with no breaking changes | Recommended for most teams |
brainfish-ai/knowledge-suggestions@v1.0.0 | Exactly version 1.0.0. Nothing changes until you update the reference | Your organization requires pinned versions |
See the release notes for what changed in each version.
Limits and good to know
- Very large pull requests: With
pr_number, GitHub's API does not return diffs larger than 300 files or 20,000 lines, so the action can't summarize them. For PRs that size, use a checkout withfetch-depth: 0and thebaseinput instead. - Duplicate requests: Submitting the same content again within 5 minutes can return a
409 conflict. Wait a few minutes and re-run. - Rate limit: The Brainfish API allows 25 requests per minute.
- Pull requests from forks: GitHub does not give repository secrets to workflows triggered by forks, so
BRAINFISH_API_KEYis empty and the request fails. Use the merged-PR trigger (Option 2) so the workflow runs in your repository after you merge.
Troubleshooting
| Problem | Likely cause | What to do |
|---|---|---|
Unable to resolve action brainfish-ai/knowledge-suggestions@... | The version reference is misspelled | Use @v1 or an exact release tag such as @v1.0.0 |
Base ref ... does not exist | The checkout is shallow | Add fetch-depth: 0 to actions/checkout |
pr_number must be a number | The value isn't a plain integer | Pass only the PR number, such as 42 |
Failed to fetch the diff for PR | The PR is over GitHub's diff size limit, or the token can't read it | Use base with a full checkout, or grant pull-requests: read |
API request failed (401) | Missing or invalid Brainfish token | Check the BRAINFISH_API_KEY secret and create a new token if needed |
API request failed (409) | Duplicate request within 5 minutes | Wait 5 minutes and run again |
API request failed (429) | Rate limit reached | Wait a moment and retry |
No relevant changes ... after excluding lock, generated and binary files warning | The change only touched lock, generated, or binary files, or there was no change at all | Nothing to do. No request was sent |
If an error includes a requestId, share it with Brainfish support for faster debugging.
FAQ
Do suggestions change my published articles automatically? No. Suggestions go to a review queue so you can approve or reject them first.
Can I target a specific collection? Yes. Set collection_id to the collection's UUID.
Do I need a checkout step? Only when you don't use pr_number. With pr_number the action reads the PR directly from GitHub.
Which version should I use? Use @v1 to get fixes automatically. Pin to an exact release such as @v1.0.0 only if your organization requires it.
Are lock files sent to Brainfish? No. Lock files, generated files, build output, and binary files are always dropped. Only their names are listed.
What happens with a very large pull request? If the diff is over 1,000 lines after dropping lock and generated files, only a summary of the changed files and functions is sent. Change the limit with max_diff_lines.
Can I use this with private repositories? Yes. The default github.token can read PRs in the same repository. To read a PR from a different private repository, set repository and pass a github_token that has access to it.
How do I see the result of a run? Use the task_id output to track the request. Suggestions appear in Brainfish once the Knowledge Discovery Agent finishes.
Related articles
- Brainfish MCP Server: generate suggestions from AI assistants such as Cursor and Claude
- Using Import, Export, and API Tokens
- How to Review and Approve Generated Answers
