name: AI Moderator on: issues: types: [opened] issue_comment: types: [created] pull_request_review_comment: types: [created] permissions: issues: write pull-requests: write contents: read jobs: moderate: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/github-script@v9 env: GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }} with: script: | const fs = require('fs'); const content = context.payload.issue?.body || context.payload.comment?.body || ''; if (!content.trim()) { console.log('No content to analyze'); return; } const coc = fs.readFileSync('.github/CODE_OF_CONDUCT.md', 'utf8'); const prompt = `You are a community moderator for the Antergos NeXT project. Code of Conduct: ${coc} Analyze the following content for violations of this Code of Conduct. Respond with ONLY valid JSON — no markdown, no backticks, no explanation. { "violation": true/false, "reason": "short reason if violation else empty", "severity": 1-10 } Content: ${content}`; const model = 'llama-3.1-8b-instant'; let decision; try { const response = await fetch('https://api.groq.com/openai/v1/chat/completions', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${process.env.GROQ_API_KEY}` }, body: JSON.stringify({ model, messages: [ { role: 'system', content: 'You are a helpful community moderator. Respond only with valid JSON as instructed.' }, { role: 'user', content: prompt } ], temperature: 0.1, max_tokens: 150 }) }); const data = await response.json(); const raw = data.choices?.[0]?.message?.content || '{}'; decision = JSON.parse(raw.replace(/```json|```/g, '').trim()); console.log(`Decision: ${JSON.stringify(decision)}`); } catch (err) { console.log(`API error: ${err}`); return; } if (!decision.violation) { console.log('Content deemed acceptable'); return; } const issueNumber = context.payload.issue?.number || context.payload.pull_request?.number; if (!issueNumber) { console.log('No issue/PR number found'); return; } const warning = `**AI Moderator Notice** Your comment appears to violate the project's [Code of Conduct](${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/blob/master/.github/CODE_OF_CONDUCT.md). Reason: ${decision.reason} Please keep discussions respectful and constructive. Repeated violations may result in moderation actions.`; try { await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: issueNumber, body: warning }); await github.rest.issues.addLabels({ owner: context.repo.owner, repo: context.repo.repo, issue_number: issueNumber, labels: ['ai-moderated'] }); console.log('Warning posted and label added'); } catch (err) { console.log(`GitHub API error: ${err}`); }