add agent
This commit is contained in:
280
.github/workflows/sisyphus-agent.yml
vendored
Normal file
280
.github/workflows/sisyphus-agent.yml
vendored
Normal file
@@ -0,0 +1,280 @@
|
||||
name: Sisyphus Agent
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
prompt:
|
||||
description: "Custom prompt"
|
||||
required: false
|
||||
issue_comment:
|
||||
types: [created]
|
||||
pull_request_review:
|
||||
types: [submitted]
|
||||
pull_request_review_comment:
|
||||
types: [created]
|
||||
|
||||
jobs:
|
||||
agent:
|
||||
runs-on: ubuntu-latest
|
||||
# @sisyphus-dev-ai mention only (maintainers, exclude self)
|
||||
if: |
|
||||
github.event_name == 'workflow_dispatch' ||
|
||||
(contains(github.event.comment.body || github.event.review.body, '@sisyphus-dev-ai') &&
|
||||
(github.event.comment.user.login || github.event.review.user.login) != 'sisyphus-dev-ai' &&
|
||||
contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association || github.event.review.author_association))
|
||||
|
||||
# Minimal default GITHUB_TOKEN permissions
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
steps:
|
||||
# Checkout with sisyphus-dev-ai's PAT
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
token: ${{ secrets.GH_PAT }}
|
||||
fetch-depth: 0
|
||||
|
||||
# Git config - commits as sisyphus-dev-ai
|
||||
- name: Configure Git as sisyphus-dev-ai
|
||||
run: |
|
||||
git config user.name "sisyphus-dev-ai"
|
||||
git config user.email "sisyphus-dev-ai@users.noreply.github.com"
|
||||
|
||||
# gh CLI auth as sisyphus-dev-ai
|
||||
- name: Authenticate gh CLI as sisyphus-dev-ai
|
||||
run: |
|
||||
echo "${{ secrets.GH_PAT }}" | gh auth login --with-token
|
||||
gh auth status
|
||||
|
||||
- name: Ensure tmux is available (Linux)
|
||||
if: runner.os == 'Linux'
|
||||
run: |
|
||||
set -euo pipefail
|
||||
if ! command -v tmux >/dev/null 2>&1; then
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y --no-install-recommends tmux
|
||||
fi
|
||||
tmux -V
|
||||
|
||||
- name: Setup Bun
|
||||
uses: oven-sh/setup-bun@v2
|
||||
with:
|
||||
bun-version: latest
|
||||
|
||||
- name: Cache Bun dependencies
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.bun/install/cache
|
||||
node_modules
|
||||
key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-bun-
|
||||
|
||||
# Install OpenCode + oh-my-opencode + auth in single step
|
||||
- name: Setup OpenCode with oh-my-opencode
|
||||
env:
|
||||
OPENCODE_AUTH_JSON: ${{ secrets.OPENCODE_AUTH_JSON }}
|
||||
ANTHROPIC_BASE_URL: ${{ secrets.ANTHROPIC_BASE_URL }}
|
||||
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
||||
run: |
|
||||
export PATH="$HOME/.opencode/bin:$PATH"
|
||||
|
||||
# Install OpenCode (skip if cached)
|
||||
if ! command -v opencode &>/dev/null; then
|
||||
for i in 1 2 3; do
|
||||
echo "Attempt $i: Installing OpenCode..."
|
||||
curl -fsSL https://opencode.ai/install -o /tmp/opencode-install.sh
|
||||
if file /tmp/opencode-install.sh | grep -q "shell script\|text"; then
|
||||
bash /tmp/opencode-install.sh && break
|
||||
fi
|
||||
echo "Download corrupted, retrying in 5s..."
|
||||
sleep 5
|
||||
done
|
||||
fi
|
||||
opencode --version
|
||||
|
||||
bunx oh-my-opencode install --no-tui --claude=max20 --chatgpt=no --gemini=no
|
||||
|
||||
OPENCODE_JSON=~/.config/opencode/opencode.json
|
||||
jq --arg baseURL "$ANTHROPIC_BASE_URL" --arg apiKey "$ANTHROPIC_API_KEY" '
|
||||
.provider.anthropic = {
|
||||
"name": "Anthropic",
|
||||
"npm": "@ai-sdk/anthropic",
|
||||
"options": {
|
||||
"baseURL": $baseURL,
|
||||
"apiKey": $apiKey
|
||||
},
|
||||
"models": {
|
||||
"claude-opus-4-5": {
|
||||
"id": "claude-opus-4-5-20251101",
|
||||
"name": "Opus 4.5",
|
||||
"limit": { "context": 200000, "output": 64000 },
|
||||
"options": { "effort": "high" }
|
||||
},
|
||||
"claude-opus-4-5-high": {
|
||||
"id": "claude-opus-4-5-20251101",
|
||||
"name": "Opus 4.5 High",
|
||||
"limit": { "context": 200000, "output": 128000 },
|
||||
"options": { "effort": "high", "thinking": { "type": "enabled", "budgetTokens": 64000 } }
|
||||
},
|
||||
"claude-sonnet-4-5": {
|
||||
"id": "claude-sonnet-4-5-20250929",
|
||||
"name": "Sonnet 4.5",
|
||||
"limit": { "context": 200000, "output": 64000 }
|
||||
},
|
||||
"claude-sonnet-4-5-high": {
|
||||
"id": "claude-sonnet-4-5-20250929",
|
||||
"name": "Sonnet 4.5 High",
|
||||
"limit": { "context": 200000, "output": 128000 },
|
||||
"options": { "thinking": { "type": "enabled", "budgetTokens": 64000 } }
|
||||
},
|
||||
"claude-haiku-4-5": {
|
||||
"id": "claude-haiku-4-5-20251001",
|
||||
"name": "Haiku 4.5",
|
||||
"limit": { "context": 200000, "output": 64000 }
|
||||
}
|
||||
}
|
||||
}
|
||||
' "$OPENCODE_JSON" > /tmp/oc.json && mv /tmp/oc.json "$OPENCODE_JSON"
|
||||
|
||||
OMO_JSON=~/.config/opencode/oh-my-opencode.json
|
||||
PROMPT_APPEND=$(cat << 'PROMPT_EOF'
|
||||
|
||||
## GitHub Actions Environment
|
||||
|
||||
You are `sisyphus-dev-ai` in GitHub Actions.
|
||||
|
||||
### CRITICAL: GitHub Comments = Your ONLY Output
|
||||
|
||||
User CANNOT see console. Post everything via `gh issue comment` or `gh pr comment`.
|
||||
|
||||
### Rules
|
||||
- EVERY response = GitHub comment
|
||||
- Code changes = PR (never push main/master)
|
||||
- Setup: bun install first
|
||||
- Acknowledge immediately, report when done
|
||||
|
||||
### Git Config
|
||||
- user.name: sisyphus-dev-ai
|
||||
- user.email: sisyphus-dev-ai@users.noreply.github.com
|
||||
PROMPT_EOF
|
||||
)
|
||||
jq --arg append "$PROMPT_APPEND" '.agents.Sisyphus.prompt_append = $append' "$OMO_JSON" > /tmp/omo.json && mv /tmp/omo.json "$OMO_JSON"
|
||||
|
||||
mkdir -p ~/.local/share/opencode
|
||||
echo "$OPENCODE_AUTH_JSON" > ~/.local/share/opencode/auth.json
|
||||
chmod 600 ~/.local/share/opencode/auth.json
|
||||
|
||||
cat "$OPENCODE_JSON"
|
||||
|
||||
# Collect context
|
||||
- name: Collect Context
|
||||
id: context
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GH_PAT }}
|
||||
run: |
|
||||
EVENT="${{ github.event_name }}"
|
||||
|
||||
if [[ "$EVENT" == "issue_comment" ]]; then
|
||||
ISSUE_NUM="${{ github.event.issue.number }}"
|
||||
COMMENT="${{ github.event.comment.body }}"
|
||||
AUTHOR="${{ github.event.comment.user.login }}"
|
||||
COMMENT_ID="${{ github.event.comment.id }}"
|
||||
|
||||
# Check if PR or Issue
|
||||
if gh api "repos/${{ github.repository }}/issues/${ISSUE_NUM}" | jq -e '.pull_request' > /dev/null; then
|
||||
echo "type=pr" >> $GITHUB_OUTPUT
|
||||
echo "number=${ISSUE_NUM}" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "type=issue" >> $GITHUB_OUTPUT
|
||||
echo "number=${ISSUE_NUM}" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
elif [[ "$EVENT" == "pull_request_review_comment" ]]; then
|
||||
echo "type=pr" >> $GITHUB_OUTPUT
|
||||
echo "number=${{ github.event.pull_request.number }}" >> $GITHUB_OUTPUT
|
||||
COMMENT="${{ github.event.comment.body }}"
|
||||
AUTHOR="${{ github.event.comment.user.login }}"
|
||||
COMMENT_ID="${{ github.event.comment.id }}"
|
||||
elif [[ "$EVENT" == "pull_request_review" ]]; then
|
||||
echo "type=pr" >> $GITHUB_OUTPUT
|
||||
echo "number=${{ github.event.pull_request.number }}" >> $GITHUB_OUTPUT
|
||||
COMMENT="${{ github.event.review.body }}"
|
||||
AUTHOR="${{ github.event.review.user.login }}"
|
||||
COMMENT_ID=""
|
||||
fi
|
||||
|
||||
echo "comment<<EOF" >> $GITHUB_OUTPUT
|
||||
echo "$COMMENT" >> $GITHUB_OUTPUT
|
||||
echo "EOF" >> $GITHUB_OUTPUT
|
||||
echo "author=$AUTHOR" >> $GITHUB_OUTPUT
|
||||
echo "comment_id=$COMMENT_ID" >> $GITHUB_OUTPUT
|
||||
|
||||
# Add :eyes: reaction (as sisyphus-dev-ai)
|
||||
- name: Add eyes reaction
|
||||
if: steps.context.outputs.comment_id != ''
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GH_PAT }}
|
||||
run: |
|
||||
gh api "/repos/${{ github.repository }}/issues/comments/${{ steps.context.outputs.comment_id }}/reactions" \
|
||||
-X POST -f content="eyes" || true
|
||||
|
||||
- name: Run OpenCode
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GH_PAT }}
|
||||
run: |
|
||||
export PATH="$HOME/.opencode/bin:$PATH"
|
||||
|
||||
PROMPT="
|
||||
Your username is @sisyphus-dev-ai, mentioned by @${{ steps.context.outputs.author }} in ${{ github.repository }}.
|
||||
|
||||
## Context
|
||||
- Type: ${{ steps.context.outputs.type }}
|
||||
- Number: #${{ steps.context.outputs.number }}
|
||||
- Repository: ${{ github.repository }}
|
||||
- Default Branch: ${{ github.event.repository.default_branch }}
|
||||
|
||||
## User's Request
|
||||
${{ steps.context.outputs.comment }}
|
||||
|
||||
---
|
||||
|
||||
First, acknowledge with \`gh issue comment ${{ steps.context.outputs.number }} --body \"👋 Hey @${{ steps.context.outputs.author }}! I'm on it...\"\`
|
||||
|
||||
Then write everything using the todo tools.
|
||||
Then investigate and satisfy the request. Only if user requested to you to work explicitely, then use plan agent to plan, todo obsessivley then create a PR to \`${{ github.event.repository.default_branch }}\` branch."
|
||||
|
||||
opencode run "$PROMPT"
|
||||
|
||||
# Push changes (as sisyphus-dev-ai)
|
||||
- name: Push changes
|
||||
if: always()
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GH_PAT }}
|
||||
run: |
|
||||
if [[ -n "$(git status --porcelain)" ]]; then
|
||||
git add -A
|
||||
git commit -m "chore: changes by sisyphus-dev-ai" || true
|
||||
fi
|
||||
|
||||
BRANCH=$(git branch --show-current)
|
||||
if [[ "$BRANCH" != "main" && "$BRANCH" != "master" ]]; then
|
||||
git push origin "$BRANCH" || true
|
||||
fi
|
||||
|
||||
# Remove :eyes:, add :+1:
|
||||
- name: Update reaction
|
||||
if: always() && steps.context.outputs.comment_id != ''
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GH_PAT }}
|
||||
run: |
|
||||
# Remove eyes
|
||||
REACTION_ID=$(gh api "/repos/${{ github.repository }}/issues/comments/${{ steps.context.outputs.comment_id }}/reactions" \
|
||||
--jq '.[] | select(.content == "eyes" and .user.login == "sisyphus-dev-ai") | .id' | head -1)
|
||||
if [[ -n "$REACTION_ID" ]]; then
|
||||
gh api -X DELETE "/repos/${{ github.repository }}/reactions/${REACTION_ID}" || true
|
||||
fi
|
||||
|
||||
# Add thumbs up
|
||||
gh api "/repos/${{ github.repository }}/issues/comments/${{ steps.context.outputs.comment_id }}/reactions" \
|
||||
-X POST -f content="+1" || true
|
||||
Reference in New Issue
Block a user