Skip to content

Pi: #533 @mcowger

Pi: #533 @mcowger #236

Workflow file for this run

name: Pi Assistant
run-name: "Pi: #${{ github.event.issue.number }} @${{ github.event.comment.user.login }}"
on:
issue_comment:
types: [created]
jobs:
pi-agent:
if: contains(github.event.comment.body, '/pi')
runs-on: ubuntu-latest
env:
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}:${{ github.repository }}|${{ github.workflow }}|${{ github.job }}
permissions:
contents: write
issues: write
pull-requests: write
actions: read
steps:
- name: Mask API key
run: echo "::add-mask::$LLM_API_KEY"
- name: Check commenter permission
id: permission
uses: actions/github-script@v9
with:
script: |
const { data: perm } = await github.rest.repos.getCollaboratorPermissionLevel({
owner: context.repo.owner,
repo: context.repo.repo,
username: context.payload.comment.user.login,
});
const level = perm.permission;
core.info(`Commenter ${context.payload.comment.user.login} has permission: ${level}`);
if (!['admin', 'write', 'maintain'].includes(level)) {
core.setFailed(`User ${context.payload.comment.user.login} is not a collaborator or owner — ignoring /pi trigger`);
}
- name: Post initial progress comment
id: initial_comment
uses: actions/github-script@v9
with:
script: |
const { data: comment } = await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.issue.number,
body: '🤖 **Pi is working on it...**\n\nAnalyzing your request and planning next steps.',
});
core.setOutput('comment_id', comment.id);
core.info(`Posted progress comment: ${comment.id}`);
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Create working branch
run: |
BRANCH="pi-agent/$(date +%Y%m%d-%H%M%S)"
git checkout -b "$BRANCH"
echo "WORKING_BRANCH=$BRANCH" >> "$GITHUB_ENV"
- name: Configure Git identity
run: |
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git config user.name "github-actions[bot]"
- uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Install dependencies
run: bun install
- name: Build frontend
run: bun run build:frontend
- name: Run Pi agent
id: pi
uses: mcowger/pi-action@main
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
provider: openrouter
model: ${{ vars.LLM_MODEL_ID }}
token: ${{ env.LLM_API_KEY }}
base_url: ${{ secrets.LLM_API_HOST }}
trigger: /pi
load_builtin_extensions: true
suppress_final_comment: true
suppress_bun_install: true
export_session_html: true
prompt_file: .github/prompts/pi-assistant.md
env:
INITIAL_COMMENT_ID: ${{ steps.initial_comment.outputs.comment_id }}
- name: Post failure comment if agent did not complete
if: always() && (steps.pi.outputs.success != 'true' || steps.pi.outputs.response == '')
uses: actions/github-script@v9
with:
script: |
const runUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`;
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: ${{ steps.initial_comment.outputs.comment_id }},
body: [
'❌ **Pi did not complete successfully.**',
'',
'| | |',
'|---|---|',
`| Success | \`${{ steps.pi.outputs.success }}\` |`,
`| Duration | ${{ steps.pi.outputs.duration_seconds }}s |`,
`| Input tokens | ${{ steps.pi.outputs.input_tokens }} |`,
`| Output tokens | ${{ steps.pi.outputs.output_tokens }} |`,
'',
`[View Actions run](${runUrl}) for details.`,
'',
'Reply with `/pi` to try again.',
].join('\n'),
});
- name: Log agent summary
if: always()
env:
PI_RESPONSE: ${{ steps.pi.outputs.response }}
run: |
{
echo "### Pi Agent Summary"
echo "- **Success:** ${{ steps.pi.outputs.success }}"
echo "- **Duration:** ${{ steps.pi.outputs.duration_seconds }}s"
echo "- **Input tokens:** ${{ steps.pi.outputs.input_tokens }}"
echo "- **Output tokens:** ${{ steps.pi.outputs.output_tokens }}"
echo "- **Cost:** \$${{ steps.pi.outputs.cost }}"
echo ""
echo "#### Response"
printf '%s\n' "$PI_RESPONSE"
} >> "$GITHUB_STEP_SUMMARY"
- name: Upload session HTML
if: always() && steps.pi.outputs.session_html_path != ''
uses: actions/upload-artifact@v7
with:
name: pi-session
path: ${{ steps.pi.outputs.session_html_path }}
retention-days: 7
archive: false