Skip to content

Conversation

@tulga-bytes
Copy link

@tulga-bytes tulga-bytes commented Dec 5, 2025

Add AI-powered PR Assistant GitHub Action that automatically implements code changes based on PR comments using the Auggie SDK.

Key Features

  • AI-Powered Implementation: Integrates Auggie SDK to understand and implement requested changes from PR comments
  • Context-Aware Processing: Gathers full PR context including diff, changed files, and comment threads
  • Automatic Git Operations: Commits and pushes changes directly to the PR branch with descriptive commit messages
  • Visual Feedback: Adds emoji reactions to comments for immediate acknowledgment
  • Status Notifications: Posts success or failure comments to the PR with detailed information
  • Full TypeScript Implementation: Type-safe code with comprehensive error handling

Technical Implementation

  • Composite GitHub Action with Node.js 22 runtime
  • Supports both pull_request_review_comment and issue_comment events
  • Configurable reaction types (👀, 🚀, ❤️, 🎉, etc.)
  • Streams Auggie tool execution for detailed logging
  • Includes complete documentation and integration guide

Usage Example

- name: PR Assistant
  uses: augmentcode/augment-agent/assistant@feature/comment-reaction-action
  with:
    github_token: ${{ secrets.GITHUB_TOKEN }}
    comment_id: ${{ github.event.comment.id }}
    event_name: ${{ github.event_name }}
    augment_api_token: ${{ secrets.AUGMENT_API_KEY }}
    augment_api_url: ${{ secrets.AUGMENT_API_URL }}

Users can trigger the assistant by commenting @augment <instruction> on a PR, and the action will automatically implement the requested changes.


🤖 This description was generated automatically. Please react with 👍 if it's helpful or 👎 if it needs improvement.

Tulga Tsogtgerel added 18 commits December 4, 2025 14:35
- Create new composite action for adding emoji reactions to GitHub comments
- Support both PR review comments and issue comments
- Configurable reaction type with sensible default (eyes)
- Full TypeScript implementation with type safety
- Comprehensive error handling and logging
- Includes README with usage examples and documentation
- Rename directory from comment-reaction to pr-assistant
- Update parseInt to Number.parseInt for consistency
- Prepare for expanded functionality to implement PR changes based on comments
Simplify naming from pr-assistant to assistant
- Add augment_api_token and augment_api_url as optional inputs
- Forward credentials as environment variables to the action
- Enable Augment authentication for future functionality
Major enhancements:
- Add Auggie SDK integration to implement changes based on comments
- Gather comprehensive PR context (diff, files, comments, metadata)
- Automatically commit and push changes to PR branch
- Add success/failure comments to PR
- Configure git with GitHub Actions bot credentials
- Handle both issue_comment and pull_request_review_comment events

Dependencies:
- Add @augmentcode/auggie-sdk for AI-powered code changes
- Add @actions/exec for git operations

The action now:
1. Adds eyes reaction to show processing
2. Gathers PR context and comment thread
3. Invokes Auggie with full context
4. Commits and pushes implemented changes
5. Posts result comment to PR
- Update description to reflect AI-powered implementation
- Add comprehensive usage examples
- Document how the action works step-by-step
- Add setup instructions and troubleshooting guide
- Include example instructions for common use cases
Move the reaction step to happen right after Octokit initialization,
before any other processing or API calls. This ensures users get
immediate visual feedback that their comment is being processed.
Move the emoji reaction from TypeScript code to a separate github-script
step in action.yml. This provides even faster user feedback since:
- No need to wait for Node.js setup
- No need to wait for npm install
- Reaction happens immediately before any processing

Benefits:
- Reaction appears in ~1-2 seconds instead of ~10-15 seconds
- Cleaner separation of concerns
- Simpler TypeScript code (removed unused reaction logic)
- Better user experience with instant visual feedback
Add step to install @augmentcode/auggie globally before running the
assistant. The Auggie SDK spawns the auggie CLI binary, which needs
to be installed on the runner.

This fixes the 'spawn auggie ENOENT' error.
Change isAnswerOnly from true to false in auggie.prompt() call.
When isAnswerOnly is true, Auggie only provides a text description
of what it would do without actually making file changes.

With isAnswerOnly: false, Auggie will:
- Actually edit the files
- Make the requested changes
- Allow git to detect and commit the changes
After reviewing the Auggie SDK source code, isAnswerOnly only controls
which text is returned, NOT whether tools are executed. The real issue
was that the instruction wasn't explicit enough.

Changes:
- Add clear context that this is an AI assistant implementing changes
- Explicitly state 'You MUST actually implement the requested changes'
- Tell Auggie to use file editing tools (str-replace-editor, save-file)
- Clarify NOT to just describe what would be done
- Set isAnswerOnly back to true (correct setting for clean final answer)

This ensures Auggie understands it needs to actually edit files, not
just provide a description of what it would do.
Add onSessionUpdate callback to stream tool execution in real-time.
This provides visibility into what Auggie is doing during execution.

Logs include:
- 🔧 When a tool starts executing (with input parameters)
- ✅ When a tool completes (with output, truncated if long)
- Real-time progress updates during long-running operations

Benefits:
- Users can see what's happening in the workflow logs
- Easier to debug when things go wrong
- Better transparency into Auggie's actions
- Helps understand which tools are being used

Inspired by examples/dev.ts in the Auggie SDK.
The Auggie SDK uses SIGKILL to terminate the process immediately,
which may not give enough time for file writes to be flushed to disk.

Changes:
- Log the workspace root directory for debugging
- Add 2-second delay after prompt completes before closing
- This ensures all file operations have time to complete
- Prevents 'no changes to commit' issue

The delay allows the Auggie process to finish writing all file
changes to disk before being terminated.
- Replace unreliable git diff --cached --quiet check with git status --porcelain
- Add better logging to show detected changes
- Fixes issue where changes were made but not committed due to incorrect detection
- Add git pull --rebase before push to sync with remote branch
- Prevents non-fast-forward errors when remote has new commits
- Gracefully handles rebase failures and attempts push anyway
- Remove git pull --rebase step from commitAndPush
- Workflow now ensures latest PR state is checked out
- Simpler and more reliable approach
- Format original comment as quoted text in reply
- Makes it clear which request was fulfilled or failed
- Improves conversation flow in PR comments
Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review completed. I've identified a few potential issues that should be addressed.


🤖 Automated review complete. Please react with 👍 or 👎 on the individual review comments to provide feedback on their usefulness.


// Push changes
core.info(`🚀 Pushing to ${headBranch}...`);
const remoteUrl = `https://x-access-token:${githubToken}@github.com/${owner}/${repo}.git`;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security Concern: GitHub Token Exposure in Logs

The GitHub token is embedded directly in the remote URL, which could potentially be exposed in error messages or logs if the git push command fails.

Current code:

const remoteUrl = `https://x-access-token:${githubToken}@github.com/${owner}/${repo}.git`;
await exec.exec('git', ['push', remoteUrl, `HEAD:${headBranch}`]);

Suggested improvement:

// Use git credential helper or configure the remote separately
await exec.exec('git', ['config', '--local', 'credential.helper', '']);
await exec.exec('git', ['config', '--local', `credential.https://github.com.username`, 'x-access-token']);
// Set token via environment or use GIT_ASKPASS
const env = { ...process.env, GIT_PASSWORD: githubToken };
await exec.exec('git', ['push', 'origin', `HEAD:${headBranch}`], { env });

Alternatively, configure the remote URL with the token in a way that won't be logged:

await exec.exec('git', ['remote', 'set-url', 'origin', `https://x-access-token:${githubToken}@github.com/${owner}/${repo}.git`]);
await exec.exec('git', ['push', 'origin', `HEAD:${headBranch}`]);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably fine, but probably an easy change to implement here

comment_id: commentId,
});
return comment.pull_request_url.split('/').pop()
? Number.parseInt(comment.pull_request_url.split('/').pop()!, 10)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potential Bug: Redundant Null Check Pattern

The pattern used here is unnecessarily complex. The ternary operator checks if .pop() returns a truthy value, but this could fail silently if the URL is malformed.

Current code:

return comment.pull_request_url.split('/').pop()
  ? Number.parseInt(comment.pull_request_url.split('/').pop()!, 10)
  : null;

Suggested improvement:

const parts = comment.pull_request_url.split('/');
const prNumberStr = parts[parts.length - 1];
if (!prNumberStr) return null;

const prNumber = Number.parseInt(prNumberStr, 10);
return Number.isNaN(prNumber) ? null : prNumber;

This approach:

  • Avoids calling .split('/') twice
  • Validates that the parsed number is actually a valid number
  • Is more readable and maintainable

- Run prettier to fix formatting in assistant files
- Fixes format-check CI failure
Copy link
Contributor

@justinxu421 justinxu421 Dec 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's probably fine for this to live here for now, but to host it on marketplace, I believe the 1 click install will only link to the mainline action https://github.com/marketplace/actions/augment-agent i.e. augmentcode/augment-agent@v0.1.3, so this nested one might not be as discoverable.

Image

We've opted to maintain several repos and thus publish separate marketplaces to get around this the code review action:

But it's also more work to maintain all the repos and version them. Doing it this way could also be a way to host it without fully publicizing it, so it could be a good middleground.

Just food for thought.

Comment on lines +22 to +26
augment_api_token:
description: "API token for Augment services. Store as repository secret for security."
required: false
augment_api_url:
description: "URL endpoint for Augment API requests. Store as repository variable."
Copy link
Contributor

@justinxu421 justinxu421 Dec 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to add support for rules/mcp? Or just keep it simple for now

Comment on lines +438 to +440
// Step 6: Commit and push changes
await commitAndPush(commentId, context.headBranch, githubToken, owner, repo);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if directly committing to the repo is potentially too disruptive to some workflows and if we should make this configurable as an option.

Another option is to create a PR on top of the existing one and allow the user to merge it in if it's useful?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This kind of thing came up in a discussion with @akshayutture-augment on suggested auggie fixes

import * as core from '@actions/core';
import * as exec from '@actions/exec';
import { Octokit } from '@octokit/rest';
import { Auggie } from '@augmentcode/auggie-sdk';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Being able to use the auggie-sdk here is pretty neat

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need this / agent generated?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we add test so some of these functions? (we probably also need to add some CI to this repo if so)

@justinxu421
Copy link
Contributor

auggie review

Copy link

@augment-app-staging augment-app-staging bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review completed. 3 suggestions posted.

Fix All in Augment

Comment augment review to trigger a new review at any time.

});

// Get the triggering comment
const { data: triggeringComment } = await octokit.rest.issues.getComment({

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For PR review comment events, comment_id refers to a review comment, so calling issues.getComment here will 404; consider passing event_name into gatherPRContext and using pulls.getReviewComment when appropriate.

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

});

// Get PR files
const { data: files } = await octokit.rest.pulls.listFiles({

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pulls.listFiles is not paginated here (default 30 items); PRs with >30 files will yield incomplete context. Consider using octokit.paginate or explicit pagination.

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

});

// Get all comments on the PR
const { data: allComments } = await octokit.rest.issues.listComments({

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issues.listComments is not paginated (default 30 items), so long threads will be truncated and context incomplete. Consider paginating here as well. (Related to the pagination suggestion on listFiles.)

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants