fix: swap AI moderator from GitHub Models to Groq (free tier)
This commit is contained in:
@@ -1,31 +1,123 @@
|
|||||||
name: AI Community Moderator
|
name: AI Moderator
|
||||||
|
|
||||||
on:
|
on:
|
||||||
issues:
|
issues:
|
||||||
types: [opened]
|
types: [opened]
|
||||||
pull_request:
|
|
||||||
types: [opened]
|
|
||||||
issue_comment:
|
issue_comment:
|
||||||
types: [created]
|
types: [created]
|
||||||
pull_request_review_comment:
|
pull_request_review_comment:
|
||||||
types: [created]
|
types: [created]
|
||||||
discussion:
|
|
||||||
types: [created]
|
|
||||||
discussion_comment:
|
|
||||||
types: [created]
|
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
|
||||||
issues: write
|
issues: write
|
||||||
pull-requests: write
|
pull-requests: write
|
||||||
discussions: write
|
contents: read
|
||||||
models: read
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
moderate:
|
moderate:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: benbalter/ai-community-moderator@main
|
- uses: actions/checkout@v4
|
||||||
|
- uses: actions/github-script@v9
|
||||||
|
env:
|
||||||
|
GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}
|
||||||
with:
|
with:
|
||||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
script: |
|
||||||
severity-threshold: 5
|
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}`);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user