Skip to content

Add AI agent workflows to auto-comment on issues and PRs#95

Open
Copilot wants to merge 16 commits intomainfrom
copilot/add-agents-to-review-issues
Open

Add AI agent workflows to auto-comment on issues and PRs#95
Copilot wants to merge 16 commits intomainfrom
copilot/add-agents-to-review-issues

Conversation

Copy link
Contributor

Copilot AI commented Feb 27, 2026

The repo has 45+ open issues and active PRs with no automated triage or analysis. Two GitHub Actions workflows add AI-powered agents that post structured comments on every issue and PR event.

issue-agent.yml

  • Triggers on issues: opened, edited, reopened, labeled
  • Calls GitHub Models API (gpt-4o-mini) with the issue context (title, body, author, labels)
  • Posts a comment structured as: Summary → Key Points → Relevance to Simulation Theory → Suggested Actions

pr-agent.yml

  • Triggers on pull_request: opened, edited, synchronize, reopened
  • Collects changed files (up to 50, with overflow notice), diffs stats, branch info
  • Posts a comment structured as: Summary → Changed Files Analysis → Potential Concerns → Relevance to Project Goals → Suggested Actions

Both workflows

  • Use only GITHUB_TOKEN — no extra secrets required; models: read permission added
  • Validate data.choices shape before access; fall back to a structured templated comment if the Models API is unavailable or returns an unexpected response
  • max_tokens: 1500 to avoid truncated responses
Original prompt

I have lots of issues and pull requests can we add agents to rigorously dig into all and create comments on each issue and pr?


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Co-authored-by: blackboxprogramming <118287761+blackboxprogramming@users.noreply.github.com>
Copilot AI changed the title [WIP] Add agents to review and comment on issues and pull requests Add AI agent workflows to auto-comment on issues and PRs Feb 27, 2026
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds two GitHub Actions workflows that use the GitHub Models API to auto-generate and post structured, “agent-style” comments on issue and pull request activity to improve triage and review throughput.

Changes:

  • Introduces an Issue Agent workflow to comment on issue events with a structured analysis (and a non-AI fallback).
  • Introduces a PR Agent workflow to comment on PR events, including basic PR metadata and a changed-files summary (and a non-AI fallback).
  • Adds GitHub Models API usage (models: read) from within actions/github-script.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 8 comments.

File Description
.github/workflows/issue-agent.yml New workflow that calls Models API and posts a structured issue analysis comment (with fallback).
.github/workflows/pr-agent.yml New workflow that gathers changed files, calls Models API, and posts a structured PR review comment (with fallback).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +3 to +10
on:
pull_request:
types: [opened, edited, synchronize, reopened]

permissions:
pull-requests: write
contents: read
models: read
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

Using the pull_request event with pull-requests: write permissions will not be able to create comments for PRs opened from forks (the token is read-only in that case). If you need this to work for forked contributions, consider switching to pull_request_target with appropriate safeguards (avoid checking out/executing untrusted PR code), or document/accept that the agent only comments on same-repo branches.

Copilot uses AI. Check for mistakes.
Comment on lines +27 to +32
const response = await fetch('https://models.inference.ai.azure.com/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${process.env.GITHUB_TOKEN}`
},
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

The Authorization header for the Models API call is built from process.env.GITHUB_TOKEN, but this workflow never sets GITHUB_TOKEN in env:. As written, the bearer token can end up empty and the Models API request will fail (falling back every time). Set env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} (or ${{ github.token }}) for this step, or pass the token via an explicit env var and reference that instead of process.env.GITHUB_TOKEN.

Copilot uses AI. Check for mistakes.
Comment on lines +27 to +68
const response = await fetch('https://models.inference.ai.azure.com/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${process.env.GITHUB_TOKEN}`
},
body: JSON.stringify({
model: 'gpt-4o-mini',
messages: [
{
role: 'system',
content: `You are a rigorous technical agent reviewing GitHub issues for the "simulation-theory" repository — a research project on simulation theory, mathematics, quantum mechanics, and philosophy. Your job is to carefully read each issue and provide a thorough, structured analysis.

For each issue produce:
1. **Summary** — a concise one-paragraph summary of what the issue is about.
2. **Key Points** — bullet list of the most important observations or questions raised.
3. **Relevance to Simulation Theory** — how this issue connects to the project's themes.
4. **Suggested Actions** — concrete next steps or questions for the author.

Be rigorous, thoughtful, and constructive. Keep the tone academic and helpful.`
},
{
role: 'user',
content: `Please analyze this GitHub issue:\n\n**Title:** ${issueTitle}\n**Author:** ${issueUser}\n**Labels:** ${labels}\n\n**Description:**\n${issueBody}`
}
],
max_tokens: 1500,
temperature: 0.4
})
});

let analysisText;
if (response.ok) {
const data = await response.json();
if (data.choices && data.choices.length > 0 && data.choices[0].message) {
analysisText = data.choices[0].message.content;
} else {
console.log('Unexpected response structure from GitHub Models API:', JSON.stringify(data));
}
} else {
console.log(`GitHub Models API returned ${response.status}: ${await response.text()}`);
}
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

The Models API call / JSON parsing is not wrapped in try/catch. If fetch() throws (network/DNS) or response.json() throws (non-JSON error body), the action will fail and no fallback comment will be posted. Wrap the request + parsing in a try/catch and fall back to the templated analysis on any exception; also consider adding a request timeout via AbortController so the job can't hang on a stalled API call.

Copilot uses AI. Check for mistakes.
Comment on lines +53 to +58
const response = await fetch('https://models.inference.ai.azure.com/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${process.env.GITHUB_TOKEN}`
},
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

The Authorization header for the Models API call is built from process.env.GITHUB_TOKEN, but this workflow never sets GITHUB_TOKEN in env:. As written, the bearer token can end up empty and the Models API request will fail (falling back every time). Set env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} (or ${{ github.token }}) for this step, or pass the token via an explicit env var and reference that instead of process.env.GITHUB_TOKEN.

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 11 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

analysisText = `**Summary**\nIssue #${issueNumber} titled *"${issueTitle}"* was submitted by @${issueUser}. ${issueBody.length > 0 ? 'It contains a description that may include images or text.' : 'No description was provided.'}\n\n**Labels:** ${labels}\n\n**Suggested Actions**\n- Review the content of this issue and add appropriate labels if missing.\n- Respond to the author with any clarifying questions.\n- Link related issues or pull requests if applicable.`;
}

const comment = `## 🤖 Agent Analysis\n\n${analysisText}\n\n---\n*This comment was generated automatically by the Issue Agent workflow.*`;
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

The AI-generated response is directly interpolated into the GitHub comment without any sanitization or validation of the content. While GitHub's comment system handles markdown safely, a malicious or malformed AI response could:

  1. Include excessive content that makes the comment unusable
  2. Include markdown that creates broken formatting
  3. Potentially include HTML/JavaScript if the AI is manipulated via prompt injection

Consider:

  1. Adding a maximum length check on the AI response before posting (e.g., truncate if > 5000 characters)
  2. Stripping or escaping potentially dangerous content
  3. Validating that the response is structured as expected before posting

This is a defense-in-depth measure to handle cases where the AI model behaves unexpectedly or is manipulated through prompt injection (see related security comment).

Copilot uses AI. Check for mistakes.
Comment on lines +76 to +77
role: 'user',
content: `Please analyze this pull request:\n\n**Title:** ${prTitle}\n**Author:** ${prUser}\n**Base branch:** ${baseBranch} ← **Head branch:** ${headBranch}\n**Changes:** +${additions} / -${deletions} lines\n**Changed files:** ${changedFiles}\n\n**Description:**\n${prBody}`
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

User-provided content (PR title, description, branch names) is directly interpolated into the AI prompt without sanitization. While the content is only sent to the GitHub Models API and not rendered directly in the comment, this could still lead to prompt injection attacks where malicious users craft PR content designed to manipulate the AI's response.

Consider:

  1. Adding a content length limit before sending to the API (especially for PR body which can be very long)
  2. Sanitizing or escaping special characters that could be used for prompt injection
  3. Adding a disclaimer in the workflow documentation about the risks of AI-generated content

Note: This is partially mitigated by the fact that the AI's response is wrapped in a clearly marked bot comment, but prompt injection could still cause the bot to generate misleading or inappropriate analysis.

Copilot uses AI. Check for mistakes.
Comment on lines +12 to +14
jobs:
analyze-pr:
runs-on: ubuntu-latest
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

There's no rate limiting or concurrency control for the GitHub Models API calls. If multiple PRs are opened/synchronized rapidly (e.g., during batch updates or automated dependency PRs), this could:

  1. Exceed GitHub Models API rate limits, causing failures
  2. Incur unexpected costs if the API has usage-based pricing
  3. Create a spam flood of bot comments (especially with synchronize trigger firing on every push)

Consider adding:

  1. A concurrency limit in the workflow (e.g., concurrency: group: "pr-agent" with cancel-in-progress: true or group: ${{ github.event.pull_request.number }})
  2. Rate limiting checks before making API calls
  3. A filter to skip bot-created PRs (check if context.payload.pull_request.user.type === 'Bot')

Copilot uses AI. Check for mistakes.
Comment on lines +11 to +14
jobs:
analyze-issue:
runs-on: ubuntu-latest
steps:
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

There's no rate limiting or concurrency control for the GitHub Models API calls. If multiple issues are opened/edited rapidly (e.g., during a bulk import or bot activity), this could:

  1. Exceed GitHub Models API rate limits, causing failures
  2. Incur unexpected costs if the API has usage-based pricing
  3. Create a spam flood of bot comments

Consider adding:

  1. A concurrency limit in the workflow (e.g., concurrency: group: "issue-agent" with cancel-in-progress: true)
  2. Rate limiting checks before making API calls
  3. A filter to skip bot-created issues (check if context.payload.issue.user.type === 'Bot')

Copilot uses AI. Check for mistakes.
Comment on lines +3 to +5
on:
issues:
types: [opened, edited, reopened, labeled]
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

The workflow will post a new comment every time it's triggered, which could lead to spam on issues that are edited multiple times. For the edited trigger, consider either:

  1. Editing the existing bot comment instead of creating a new one (find the previous comment by filtering comments where the author is the GitHub Actions bot)
  2. Adding a check to only comment once per issue
  3. Removing the edited trigger if re-analysis on edits isn't necessary

The same pattern applies to issues that are repeatedly labeled/unlabeled.

Copilot uses AI. Check for mistakes.
Comment on lines +48 to +50
{
role: 'user',
content: `Please analyze this GitHub issue:\n\n**Title:** ${issueTitle}\n**Author:** ${issueUser}\n**Labels:** ${labels}\n\n**Description:**\n${issueBody}`
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

User-provided content (issue title, body, labels) is directly interpolated into the AI prompt without sanitization. While the content is only sent to the GitHub Models API and not rendered directly in the comment, this could still lead to prompt injection attacks where malicious users craft issue content designed to manipulate the AI's response.

Consider:

  1. Adding a content length limit before sending to the API
  2. Sanitizing or escaping special characters that could be used for prompt injection
  3. Adding a disclaimer in the workflow documentation about the risks of AI-generated content

Note: This is partially mitigated by the fact that the AI's response is wrapped in a clearly marked bot comment, but prompt injection could still cause the bot to generate misleading or inappropriate analysis.

Copilot uses AI. Check for mistakes.
@blackboxprogramming blackboxprogramming marked this pull request as ready for review February 27, 2026 05:45
@chatgpt-codex-connector
Copy link

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 7 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +80 to +82
max_tokens: 1500,
temperature: 0.4
})
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

With active PRs mentioned in the description, triggering this workflow on 'opened', 'edited', 'synchronize', and 'reopened' events could result in significant API usage costs. Each workflow run makes an API call to the GitHub Models service with max_tokens set to 1500. The 'synchronize' event in particular fires on every new commit, which could lead to many API calls for actively developed PRs. Consider implementing rate limiting, cooldown periods, or restricting which events trigger the workflow to control costs and avoid hitting potential API rate limits.

Copilot uses AI. Check for mistakes.
Comment on lines +27 to +56
const response = await fetch('https://models.inference.ai.azure.com/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${process.env.GITHUB_TOKEN}`
},
body: JSON.stringify({
model: 'gpt-4o-mini',
messages: [
{
role: 'system',
content: `You are a rigorous technical agent reviewing GitHub issues for the "simulation-theory" repository — a research project on simulation theory, mathematics, quantum mechanics, and philosophy. Your job is to carefully read each issue and provide a thorough, structured analysis.

For each issue produce:
1. **Summary** — a concise one-paragraph summary of what the issue is about.
2. **Key Points** — bullet list of the most important observations or questions raised.
3. **Relevance to Simulation Theory** — how this issue connects to the project's themes.
4. **Suggested Actions** — concrete next steps or questions for the author.

Be rigorous, thoughtful, and constructive. Keep the tone academic and helpful.`
},
{
role: 'user',
content: `Please analyze this GitHub issue:\n\n**Title:** ${issueTitle}\n**Author:** ${issueUser}\n**Labels:** ${labels}\n\n**Description:**\n${issueBody}`
}
],
max_tokens: 1500,
temperature: 0.4
})
});
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

The API call to GitHub Models does not include timeout configuration. If the API becomes unresponsive, the workflow could hang for an extended period before timing out with the default GitHub Actions job timeout (360 minutes). Consider adding a timeout to the fetch call or implementing a reasonable timeout mechanism to fail fast if the API doesn't respond promptly.

Copilot uses AI. Check for mistakes.
Comment on lines +52 to +83
// Call GitHub Models API for AI-powered analysis
const response = await fetch('https://models.inference.ai.azure.com/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${process.env.GITHUB_TOKEN}`
},
body: JSON.stringify({
model: 'gpt-4o-mini',
messages: [
{
role: 'system',
content: `You are a rigorous code and content review agent for the "simulation-theory" repository — a research project on simulation theory, mathematics, quantum mechanics, and philosophy. Your job is to carefully examine each pull request and provide a thorough, structured review.

For each PR produce:
1. **Summary** — a concise one-paragraph summary of the proposed changes.
2. **Changed Files Analysis** — observations about the files being modified and why they matter.
3. **Potential Concerns** — any risks, conflicts, or issues the reviewer should check.
4. **Relevance to Project Goals** — how these changes align with (or diverge from) simulation-theory research.
5. **Suggested Actions** — specific things the PR author or reviewers should do before merging.

Be rigorous, constructive, and precise. Keep the tone academic and professional.`
},
{
role: 'user',
content: `Please analyze this pull request:\n\n**Title:** ${prTitle}\n**Author:** ${prUser}\n**Base branch:** ${baseBranch} ← **Head branch:** ${headBranch}\n**Changes:** +${additions} / -${deletions} lines\n**Changed files:** ${changedFiles}\n\n**Description:**\n${prBody}`
}
],
max_tokens: 1500,
temperature: 0.4
})
});
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

The GITHUB_TOKEN is being exposed in the workflow script environment and used directly in the API call. While this is the intended use for GitHub Models API, there's a risk that the token could be logged or exposed in error messages. The current error handling at lines 91 and 94 uses console.log which could potentially expose sensitive information. Consider sanitizing error messages to ensure tokens are not leaked in logs.

Copilot uses AI. Check for mistakes.

// Fallback: structured analysis without AI
if (!analysisText) {
analysisText = `**Summary**\nIssue #${issueNumber} titled *"${issueTitle}"* was submitted by @${issueUser}. ${issueBody.length > 0 ? 'It contains a description that may include images or text.' : 'No description was provided.'}\n\n**Labels:** ${labels}\n\n**Suggested Actions**\n- Review the content of this issue and add appropriate labels if missing.\n- Respond to the author with any clarifying questions.\n- Link related issues or pull requests if applicable.`;
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

The fallback message construction uses issueBody.length to check if a description exists, but issueBody is already defined as an empty string fallback at line 22 when body is null/undefined. This means issueBody.length will always be greater than 0 (even if it's just the fallback text), making the conditional logic misleading. The condition should check the original body value or compare against the fallback string, not just the length.

Copilot uses AI. Check for mistakes.
Comment on lines +53 to +83
const response = await fetch('https://models.inference.ai.azure.com/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${process.env.GITHUB_TOKEN}`
},
body: JSON.stringify({
model: 'gpt-4o-mini',
messages: [
{
role: 'system',
content: `You are a rigorous code and content review agent for the "simulation-theory" repository — a research project on simulation theory, mathematics, quantum mechanics, and philosophy. Your job is to carefully examine each pull request and provide a thorough, structured review.

For each PR produce:
1. **Summary** — a concise one-paragraph summary of the proposed changes.
2. **Changed Files Analysis** — observations about the files being modified and why they matter.
3. **Potential Concerns** — any risks, conflicts, or issues the reviewer should check.
4. **Relevance to Project Goals** — how these changes align with (or diverge from) simulation-theory research.
5. **Suggested Actions** — specific things the PR author or reviewers should do before merging.

Be rigorous, constructive, and precise. Keep the tone academic and professional.`
},
{
role: 'user',
content: `Please analyze this pull request:\n\n**Title:** ${prTitle}\n**Author:** ${prUser}\n**Base branch:** ${baseBranch} ← **Head branch:** ${headBranch}\n**Changes:** +${additions} / -${deletions} lines\n**Changed files:** ${changedFiles}\n\n**Description:**\n${prBody}`
}
],
max_tokens: 1500,
temperature: 0.4
})
});
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

The API call to GitHub Models does not include timeout configuration. If the API becomes unresponsive, the workflow could hang for an extended period before timing out with the default GitHub Actions job timeout (360 minutes). Consider adding a timeout to the fetch call or implementing a reasonable timeout mechanism to fail fast if the API doesn't respond promptly.

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 7 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +3 to +6
on:
issues:
types: [opened, edited, reopened, labeled]

Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

Triggering on edited and labeled will post a new agent comment every time an issue is tweaked or labels change, which can quickly flood threads. Consider updating an existing bot comment instead of always creating a new one, or restrict triggers to fewer event types.

Copilot uses AI. Check for mistakes.
Comment on lines +27 to +31
const response = await fetch('https://models.inference.ai.azure.com/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${process.env.GITHUB_TOKEN}`
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

The Models API call isn’t protected against network/transport failures. If fetch(...) throws (DNS/timeout/etc.), the script will error out before reaching the fallback comment. Wrap the request in try/catch and proceed with the non-AI fallback on any exception.

Copilot uses AI. Check for mistakes.

on:
pull_request:
types: [opened, edited, synchronize, reopened]
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

Triggering on edited and synchronize will post a new agent comment on every title/body edit and every push, which can quickly flood PR threads. Consider updating an existing bot comment (find by marker text) instead of always creating a new one, or restrict triggers to fewer event types.

Suggested change
types: [opened, edited, synchronize, reopened]
types: [opened, reopened]

Copilot uses AI. Check for mistakes.
blackboxprogramming and others added 4 commits February 27, 2026 01:43
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
blackboxprogramming and others added 10 commits February 27, 2026 01:44
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 6 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +107 to +119
try {
if (response.ok) {
const data = await response.json();
if (data.choices && data.choices.length > 0 && data.choices[0].message) {
analysisText = data.choices[0].message.content;
} else {
console.log('Unexpected response structure from GitHub Models API:', JSON.stringify(data));
}
} else {
console.log(`GitHub Models API returned ${response.status}: ${await response.text()}`);
}
} catch (error) {
console.log('Error while calling or parsing response from GitHub Models API, falling back to templated analysis:', error);
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

Duplicate code block detected. Lines 106-120 duplicate the logic from lines 102-120, creating a nested try-catch structure that will never work correctly. The outer try block (starting at line 104) is opened but never closed, and the inner try block (starting at line 107) creates duplicate logic. This will cause the workflow to fail with a syntax error when executed. The duplicate try-catch block starting at line 107 should be removed entirely.

Suggested change
try {
if (response.ok) {
const data = await response.json();
if (data.choices && data.choices.length > 0 && data.choices[0].message) {
analysisText = data.choices[0].message.content;
} else {
console.log('Unexpected response structure from GitHub Models API:', JSON.stringify(data));
}
} else {
console.log(`GitHub Models API returned ${response.status}: ${await response.text()}`);
}
} catch (error) {
console.log('Error while calling or parsing response from GitHub Models API, falling back to templated analysis:', error);
analysisText = data.choices[0].message.content;
} else {
console.log('Unexpected response structure from GitHub Models API:', JSON.stringify(data));
}
} catch (error) {
console.log('Error while calling or parsing response from GitHub Models API, falling back to templated analysis:', error);
}
} else {
console.log(`GitHub Models API returned ${response.status}: ${await response.text()}`);

Copilot uses AI. Check for mistakes.
Comment on lines +4 to +19
pull_request_target:
types: [opened, reopened]

permissions:
pull-requests: write
contents: read
models: read

jobs:
analyze-pr:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

Using 'pull_request_target' trigger introduces security risks when combined with code checkout. This trigger runs in the context of the base repository with write permissions, even for PRs from forks. When combined with checking out code at line 17 (especially from untrusted forks), this creates a potential security vulnerability where malicious code from a fork could be executed with write permissions to the repository. Consider using the standard 'pull_request' trigger instead, or if 'pull_request_target' is necessary for API access, remove the checkout step since it's not being used for any file operations in this workflow.

Copilot uses AI. Check for mistakes.
Comment on lines +76 to +77
if (!analysisText) {
analysisText = `**Summary**\nIssue #${issueNumber} titled *"${issueTitle}"* was submitted by @${issueUser}. ${issueBody.length > 0 ? 'It contains a description that may include images or text.' : 'No description was provided.'}\n\n**Labels:** ${labels}\n\n**Suggested Actions**\n- Review the content of this issue and add appropriate labels if missing.\n- Respond to the author with any clarifying questions.\n- Link related issues or pull requests if applicable.`;
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

Fallback comment may expose sensitive information. The fallback analysis at line 76 includes the full issue body in the comment without any filtering or sanitization. If the issue body contains sensitive information (tokens, credentials, personal data), this will be publicly exposed in the agent's comment. Consider truncating or summarizing the issue body reference, or at minimum applying the same sanitization that should be used for AI-generated content.

Copilot uses AI. Check for mistakes.
Comment on lines +102 to +120
let analysisText;
if (response.ok) {
try {
const data = await response.json();
if (data.choices && data.choices.length > 0 && data.choices[0].message) {
try {
if (response.ok) {
const data = await response.json();
if (data.choices && data.choices.length > 0 && data.choices[0].message) {
analysisText = data.choices[0].message.content;
} else {
console.log('Unexpected response structure from GitHub Models API:', JSON.stringify(data));
}
} else {
console.log(`GitHub Models API returned ${response.status}: ${await response.text()}`);
}
} catch (error) {
console.log('Error while calling or parsing response from GitHub Models API, falling back to templated analysis:', error);
}
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

Missing closing brace for the try block that starts at line 104. The code has a try statement at line 104 but no corresponding closing brace, which will cause a JavaScript syntax error when the workflow runs. After the duplicate code block is removed, ensure there's a proper closing brace for the try block and a corresponding catch block to handle any exceptions.

Copilot uses AI. Check for mistakes.
Comment on lines +16 to +49
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Collect changed files
id: changed
run: |
# Ensure the base branch ref is available locally (important for fork-based PRs)
git fetch origin "${{ github.event.pull_request.base.ref }}" --no-tags --prune --depth=1

BASE="${{ github.event.pull_request.base.sha }}"
HEAD="${{ github.event.pull_request.head.sha }}"

# Compute the list of changed files between base and head; fail explicitly on error
if ! ALL_FILES=$(git diff --name-only "$BASE" "$HEAD"); then
echo "Error: failed to compute git diff between $BASE and $HEAD" >&2
exit 1
fi

# Count total changed files robustly, even when there are zero files
TOTAL=$(printf '%s\n' "$ALL_FILES" | sed '/^$/d' | wc -l | tr -d ' ')
FILES=$(echo "$ALL_FILES" | head -50 | tr '\n' ', ')
FILES="${FILES%, }"
if [ "$TOTAL" -gt 50 ]; then
REMAINING=$(( TOTAL - 50 ))
FILES="${FILES} (and ${REMAINING} more files)"
fi
{
echo 'files<<EOF'
echo "$FILES"
echo 'EOF'
} >> "$GITHUB_OUTPUT"

Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

The checkout step is unnecessary and wasteful. The workflow checks out the entire repository with full history (fetch-depth: 0) but only uses git commands to compute file diffs, which could be obtained more efficiently through the GitHub API. The checkout step also introduces security risks when combined with pull_request_target. Consider removing the checkout step entirely and using github.rest.pulls.listFiles() API to get the list of changed files, which would be safer, faster, and more efficient.

Suggested change
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Collect changed files
id: changed
run: |
# Ensure the base branch ref is available locally (important for fork-based PRs)
git fetch origin "${{ github.event.pull_request.base.ref }}" --no-tags --prune --depth=1
BASE="${{ github.event.pull_request.base.sha }}"
HEAD="${{ github.event.pull_request.head.sha }}"
# Compute the list of changed files between base and head; fail explicitly on error
if ! ALL_FILES=$(git diff --name-only "$BASE" "$HEAD"); then
echo "Error: failed to compute git diff between $BASE and $HEAD" >&2
exit 1
fi
# Count total changed files robustly, even when there are zero files
TOTAL=$(printf '%s\n' "$ALL_FILES" | sed '/^$/d' | wc -l | tr -d ' ')
FILES=$(echo "$ALL_FILES" | head -50 | tr '\n' ', ')
FILES="${FILES%, }"
if [ "$TOTAL" -gt 50 ]; then
REMAINING=$(( TOTAL - 50 ))
FILES="${FILES} (and ${REMAINING} more files)"
fi
{
echo 'files<<EOF'
echo "$FILES"
echo 'EOF'
} >> "$GITHUB_OUTPUT"
- name: Collect changed files
id: changed
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
result-encoding: string
script: |
const prNumber = context.payload.pull_request.number;
const perPage = 100;
let page = 1;
const files = [];
while (true) {
const { data } = await github.rest.pulls.listFiles({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: prNumber,
per_page: perPage,
page,
});
if (!data.length) {
break;
}
for (const file of data) {
files.push(file.filename);
}
if (data.length < perPage) {
break;
}
page += 1;
}
const total = files.length;
const limited = files.slice(0, 50);
let summary = limited.join(', ');
if (total > 50) {
const remaining = total - 50;
summary += ` (and ${remaining} more files)`;
}
core.setOutput('files', summary);

Copilot uses AI. Check for mistakes.
Comment on lines +14 to +112
- name: Analyze issue and post comment
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const issueNumber = context.issue.number;
const issueTitle = context.payload.issue.title;
const issueBody = context.payload.issue.body || '(no description provided)';
const issueUser = context.payload.issue.user.login;
const labels = (context.payload.issue.labels || []).map(l => l.name).join(', ') || 'none';

// Call GitHub Models API for AI-powered analysis
const response = await fetch('https://models.inference.ai.azure.com/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${process.env.GITHUB_TOKEN}`
},
body: JSON.stringify({
model: 'gpt-4o-mini',
messages: [
{
role: 'system',
content: `You are a rigorous technical agent reviewing GitHub issues for the "simulation-theory" repository — a research project on simulation theory, mathematics, quantum mechanics, and philosophy. Your job is to carefully read each issue and provide a thorough, structured analysis.

For each issue produce:
1. **Summary** — a concise one-paragraph summary of what the issue is about.
2. **Key Points** — bullet list of the most important observations or questions raised.
3. **Relevance to Simulation Theory** — how this issue connects to the project's themes.
4. **Suggested Actions** — concrete next steps or questions for the author.

Be rigorous, thoughtful, and constructive. Keep the tone academic and helpful.`
},
{
role: 'user',
content: `Please analyze this GitHub issue:\n\n**Title:** ${issueTitle}\n**Author:** ${issueUser}\n**Labels:** ${labels}\n\n**Description:**\n${issueBody}`
}
],
max_tokens: 1500,
temperature: 0.4
})
});

let analysisText;
if (response.ok) {
let data;
try {
data = await response.json();
} catch (error) {
console.log('Failed to parse JSON from GitHub Models API response:', error);
}

if (data && data.choices && data.choices.length > 0 && data.choices[0].message) {
analysisText = data.choices[0].message.content;
} else if (data) {
console.log('Unexpected response structure from GitHub Models API:', JSON.stringify(data));
}
} else {
console.log(`GitHub Models API returned ${response.status}: ${await response.text()}`);
}

// Fallback: structured analysis without AI
if (!analysisText) {
analysisText = `**Summary**\nIssue #${issueNumber} titled *"${issueTitle}"* was submitted by @${issueUser}. ${issueBody.length > 0 ? 'It contains a description that may include images or text.' : 'No description was provided.'}\n\n**Labels:** ${labels}\n\n**Suggested Actions**\n- Review the content of this issue and add appropriate labels if missing.\n- Respond to the author with any clarifying questions.\n- Link related issues or pull requests if applicable.`;
}

const marker = '*This comment was generated automatically by the Issue Agent workflow.*';
const commentBody = `## 🤖 Agent Analysis\n\n${analysisText}\n\n---\n${marker}`;

// Look for an existing Issue Agent comment and update it if found to avoid spamming
const { data: existingComments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueNumber,
per_page: 100
});

const existingAgentComment = existingComments.find(c =>
c.user &&
c.user.type === 'Bot' &&
typeof c.body === 'string' &&
c.body.includes(marker)
);

if (existingAgentComment) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: existingAgentComment.id,
body: commentBody
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueNumber,
body: commentBody
});
}
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

Code duplication between workflows. Both pr-agent.yml and issue-agent.yml contain similar logic for calling the GitHub Models API, handling responses, and posting comments. This duplication makes maintenance harder and could lead to inconsistencies (as evidenced by the missing sanitization in issue-agent.yml). Consider extracting the common logic into a reusable composite action or a shared script that both workflows can call, which would improve maintainability and ensure consistent behavior.

Copilot uses AI. Check for mistakes.
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