{"_id":"peertube-plugin-german-ai-mod","_rev":"103-37cf7878af840625aef33c7800218f88","name":"peertube-plugin-german-ai-mod","dist-tags":{"latest":"0.3.7"},"versions":{"0.3.3":{"name":"peertube-plugin-german-ai-mod","version":"0.3.3","keywords":["peertube","plugin","moderation","ai","german","hate-speech","toxicity","bert"],"author":{"name":"yarkolife"},"license":"AGPL-3.0","_id":"peertube-plugin-german-ai-mod@0.3.3","maintainers":[{"name":"yarkolife","email":"yarkolife@gmail.com"}],"homepage":"https://github.com/yarkolife/peertube-plugin-german-ai-mod","bugs":{"url":"https://github.com/yarkolife/peertube-plugin-german-ai-mod/issues"},"dist":{"shasum":"cd29dc763580cef17a98d7aa2d8e1a790272ddaa","tarball":"https://registry.npmjs.org/peertube-plugin-german-ai-mod/-/peertube-plugin-german-ai-mod-0.3.3.tgz","fileCount":4,"integrity":"sha512-f+qN8vgePiMvJ3c1p4Zod48zBy4n4b6udgspD5dq/rzykHC5knP+1R2gCwxbwHSaLVMCt+kM4nNbH2+aDKBlGA==","signatures":[{"sig":"MEUCIQCrIaxK8P8wu8+s6X+L/9097sCQmXBKt9fFCUcCUAWzAgIgDHVMSKDkySf6QPnZ2XKdLwvfPTdVWNOKWbaeM4nqmn8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":51613},"main":"./main.js","engine":{"peertube":">=7.0.0"},"gitHead":"964efbc7c52d2f6e48455e176226b5a607a3069c","library":"./main.js","scripts":{"build":"node ./scripts/build.js","prepublishOnly":"npm run build"},"_npmUser":{"name":"yarkolife","email":"yarkolife@gmail.com"},"repository":{"url":"git+https://github.com/yarkolife/peertube-plugin-german-ai-mod.git","type":"git"},"_npmVersion":"11.6.0","description":"Local AI moderation for German comments using ml6team DistilBERT and deepset BERT models","directories":{},"_nodeVersion":"24.10.0","clientScripts":[{"scopes":["common"],"script":"dist/client-plugin.js"}],"_hasShrinkwrap":false,"peertubeUpdatePolicy":"automatic","_npmOperationalInternal":{"tmp":"tmp/peertube-plugin-german-ai-mod_0.3.3_1763942097403_0.5672872967731872","host":"s3://npm-registry-packages-npm-production"}},"0.3.5":{"name":"peertube-plugin-german-ai-mod","version":"0.3.5","keywords":["peertube","plugin","moderation","ai","german","hate-speech","toxicity","bert"],"author":{"name":"yarkolife"},"license":"AGPL-3.0","_id":"peertube-plugin-german-ai-mod@0.3.5","maintainers":[{"name":"yarkolife","email":"yarkolife@gmail.com"}],"homepage":"https://github.com/yarkolife/peertube-plugin-german-ai-mod","bugs":{"url":"https://github.com/yarkolife/peertube-plugin-german-ai-mod/issues"},"dist":{"shasum":"7d8deef998fef76090e8ccd35d1b29bd5dd9c7f8","tarball":"https://registry.npmjs.org/peertube-plugin-german-ai-mod/-/peertube-plugin-german-ai-mod-0.3.5.tgz","fileCount":4,"integrity":"sha512-c6XzeAOFe+ARZd2dpD/k2uqWA/EKMAn9ugoAEU7mQkjHYVWv7z7YWlgRPD+3d/t2+WgwO3sXFYEjTCkHVrbdXA==","signatures":[{"sig":"MEQCIBtaOMGb/xGUrSVcTN96zY4RAwROEQu3CUot/t4E8VflAiA6XWAhppCZGyXY5a5bXimPF8rR7Mu23OCFHEKGGX8cYg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":52354},"main":"./main.js","engine":{"peertube":">=7.0.0"},"gitHead":"964efbc7c52d2f6e48455e176226b5a607a3069c","library":"./main.js","scripts":{"build":"node ./scripts/build.js","prepublishOnly":"npm run build"},"_npmUser":{"name":"yarkolife","email":"yarkolife@gmail.com"},"repository":{"url":"git+https://github.com/yarkolife/peertube-plugin-german-ai-mod.git","type":"git"},"_npmVersion":"11.6.0","description":"Local AI moderation for German comments using ml6team DistilBERT and deepset BERT models","directories":{},"_nodeVersion":"24.10.0","clientScripts":[{"scopes":["common"],"script":"dist/client-plugin.js"}],"_hasShrinkwrap":false,"peertubeUpdatePolicy":"automatic","_npmOperationalInternal":{"tmp":"tmp/peertube-plugin-german-ai-mod_0.3.5_1763945917628_0.0742797538277582","host":"s3://npm-registry-packages-npm-production"}},"0.3.6":{"name":"peertube-plugin-german-ai-mod","version":"0.3.6","keywords":["peertube","plugin","moderation","ai","german","hate-speech","toxicity","bert"],"author":{"name":"yarkolife"},"license":"AGPL-3.0","_id":"peertube-plugin-german-ai-mod@0.3.6","maintainers":[{"name":"yarkolife","email":"yarkolife@gmail.com"}],"homepage":"https://github.com/yarkolife/peertube-plugin-german-ai-mod","bugs":{"url":"https://github.com/yarkolife/peertube-plugin-german-ai-mod/issues"},"dist":{"shasum":"7fae8470eba23db316be8da9c20c0cd3ae9f3618","tarball":"https://registry.npmjs.org/peertube-plugin-german-ai-mod/-/peertube-plugin-german-ai-mod-0.3.6.tgz","fileCount":4,"integrity":"sha512-KDKkdLuDkoB7LnIw5AnDjtTPbFQAs0ZfYGVMAoXMT5i4QlkRFTQn1UtpGgtPXyLA1/1ViF2DK2ks5Xgi+7x/sg==","signatures":[{"sig":"MEQCIHv7ag3k9Iu9eY2e924HyTH7CbwdncFCA4QuarUKEei0AiB66nLtvh4vU+ur+XoBrzuVSQgQWqZzgVQT3r3oHdNpGA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":52353},"main":"./main.js","engine":{"peertube":">=7.0.0"},"gitHead":"964efbc7c52d2f6e48455e176226b5a607a3069c","library":"./main.js","scripts":{"build":"node ./scripts/build.js","prepublishOnly":"npm run build"},"_npmUser":{"name":"yarkolife","email":"yarkolife@gmail.com"},"repository":{"url":"git+https://github.com/yarkolife/peertube-plugin-german-ai-mod.git","type":"git"},"_npmVersion":"11.6.0","description":"Local AI moderation for German comments using ml6team DistilBERT and deepset BERT models","directories":{},"_nodeVersion":"24.10.0","clientScripts":[{"scopes":["common"],"script":"dist/client-plugin.js"}],"_hasShrinkwrap":false,"peertubeUpdatePolicy":"automatic","_npmOperationalInternal":{"tmp":"tmp/peertube-plugin-german-ai-mod_0.3.6_1763946317511_0.6899785608468074","host":"s3://npm-registry-packages-npm-production"}},"0.3.7":{"name":"peertube-plugin-german-ai-mod","description":"Local AI moderation for German comments using ml6team DistilBERT and deepset BERT models","version":"0.3.7","author":{"name":"yarkolife"},"repository":{"type":"git","url":"git+https://github.com/yarkolife/peertube-plugin-german-ai-mod.git"},"license":"AGPL-3.0","bugs":{"url":"https://github.com/yarkolife/peertube-plugin-german-ai-mod/issues"},"peertubeUpdatePolicy":"automatic","engine":{"peertube":">=7.0.0"},"main":"./main.js","clientScripts":[{"script":"dist/client-plugin.js","scopes":["common"]}],"scripts":{"build":"node ./scripts/build.js","prepublishOnly":"npm run build"},"homepage":"https://github.com/yarkolife/peertube-plugin-german-ai-mod","keywords":["peertube","plugin","moderation","ai","german","hate-speech","toxicity","bert"],"library":"./main.js","_id":"peertube-plugin-german-ai-mod@0.3.7","gitHead":"964efbc7c52d2f6e48455e176226b5a607a3069c","_nodeVersion":"24.10.0","_npmVersion":"11.6.0","dist":{"integrity":"sha512-lzUaDzI2EUSzzeZ26Ozy7LgkVs2Bm1eTJ0xPbLDQefsGMfMnWOXTYbwGCMylsmAceDjJEVHYHPPZZujfM/pSWQ==","shasum":"f0444af8cb6dbce91621603d26444237a3a06d47","tarball":"https://registry.npmjs.org/peertube-plugin-german-ai-mod/-/peertube-plugin-german-ai-mod-0.3.7.tgz","fileCount":4,"unpackedSize":52890,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQC2Kd4c5wYwJTWXhWIGf8xT8QD577TlnRKq7TtuU+p95AIgPIuX+4pJRtZJzezINXm4aau1oaXNTyZDFCDohGBCgtk="}]},"_npmUser":{"name":"yarkolife","email":"yarkolife@gmail.com"},"directories":{},"maintainers":[{"name":"yarkolife","email":"yarkolife@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/peertube-plugin-german-ai-mod_0.3.7_1763946447474_0.8417413845519552"},"_hasShrinkwrap":false}},"time":{"created":"2025-11-21T22:16:33.822Z","modified":"2025-11-24T01:07:27.890Z","0.0.1":"2025-11-21T22:16:34.027Z","0.0.2":"2025-11-21T23:06:03.592Z","0.0.3":"2025-11-21T23:19:03.898Z","0.0.4":"2025-11-21T23:30:34.286Z","0.0.5":"2025-11-21T23:58:25.821Z","0.0.6":"2025-11-22T00:02:51.316Z","0.0.7":"2025-11-22T01:12:51.544Z","0.0.8":"2025-11-22T01:46:32.961Z","0.0.9":"2025-11-22T03:06:56.149Z","0.0.10":"2025-11-22T09:34:28.767Z","0.0.11":"2025-11-22T09:48:14.555Z","0.0.12":"2025-11-22T11:17:03.855Z","0.0.13":"2025-11-22T12:00:56.170Z","0.0.14":"2025-11-22T12:04:22.647Z","0.0.15":"2025-11-22T21:51:36.067Z","0.0.16":"2025-11-22T21:58:26.533Z","0.0.17":"2025-11-22T22:01:56.831Z","0.0.18":"2025-11-22T22:04:56.001Z","0.0.19":"2025-11-23T10:14:01.847Z","0.0.20":"2025-11-23T10:38:11.293Z","0.0.21":"2025-11-23T10:38:43.077Z","0.0.22":"2025-11-23T10:41:10.375Z","0.0.23":"2025-11-23T10:59:08.911Z","0.1.0":"2025-11-23T12:16:40.587Z","0.1.1":"2025-11-23T12:20:39.583Z","0.1.2":"2025-11-23T12:38:41.301Z","0.1.3":"2025-11-23T12:42:34.298Z","0.1.4":"2025-11-23T13:49:14.304Z","0.1.5":"2025-11-23T13:49:45.067Z","0.1.6":"2025-11-23T14:02:01.639Z","0.1.7":"2025-11-23T14:04:07.658Z","0.1.8":"2025-11-23T14:44:55.952Z","0.1.9":"2025-11-23T14:45:15.215Z","0.2.0":"2025-11-23T14:49:54.674Z","0.2.1":"2025-11-23T15:55:51.366Z","0.2.2":"2025-11-23T20:05:20.497Z","0.2.3":"2025-11-23T20:51:48.581Z","0.2.4":"2025-11-23T20:54:21.679Z","0.2.5":"2025-11-23T21:41:48.375Z","0.2.6":"2025-11-23T22:48:21.714Z","0.2.7":"2025-11-23T22:51:50.455Z","0.2.8":"2025-11-23T22:53:16.370Z","0.2.9":"2025-11-23T23:00:16.335Z","0.3.0":"2025-11-23T23:05:51.040Z","0.3.1":"2025-11-23T23:41:06.716Z","0.3.2":"2025-11-23T23:49:22.789Z","0.3.3":"2025-11-23T23:54:57.574Z","0.3.4":"2025-11-24T00:39:23.624Z","0.3.5":"2025-11-24T00:58:37.840Z","0.3.6":"2025-11-24T01:05:17.719Z","0.3.7":"2025-11-24T01:07:27.697Z"},"bugs":{"url":"https://github.com/yarkolife/peertube-plugin-german-ai-mod/issues"},"author":{"name":"yarkolife"},"license":"AGPL-3.0","homepage":"https://github.com/yarkolife/peertube-plugin-german-ai-mod","keywords":["peertube","plugin","moderation","ai","german","hate-speech","toxicity","bert"],"repository":{"type":"git","url":"git+https://github.com/yarkolife/peertube-plugin-german-ai-mod.git"},"description":"Local AI moderation for German comments using ml6team DistilBERT and deepset BERT models","maintainers":[{"name":"yarkolife","email":"yarkolife@gmail.com"}],"readme":"# PeerTube Plugin: German AI Moderation\n\nAI-powered comment moderation plugin for PeerTube using two-stage German toxicity detection with ml6team DistilBERT and deepset BERT models.\n\n## Features\n\n- **Dual-Model System**: \n  - Primary: `ml6team/distilbert-base-german-cased-toxic-comments` - Fast general toxicity detection (67M, optimized for comments)\n  - Secondary: `deepset/bert-base-german-cased-hatespeech-GermEval18Coarse` - Specialized hate speech detection\n- **German Language Detection**: Automatically detects comment language using `langdetect`\n- **Two-Level Filtering**: \n  - General toxicity threshold (configurable, default: 0.7)\n  - Hate speech threshold (configurable, default: 0.5)\n- **Non-German Comments**: Configurable action for comments in other languages (moderation queue or block)\n- **Fail-Open Strategy**: Comments are allowed if AI service is unavailable (prevents site breakage)\n\n## Requirements\n\n- PeerTube >= 7.0.0\n- AI moderation service (FastAPI) running in Docker network\n- Docker container with AI service accessible at `http://ai-moderator:8000/analyze`\n\n## Installation\n\n1. Install via PeerTube admin panel:\n   - Go to **Administration → Plugins/Themes**\n   - Click **Install a plugin/the theme**\n   - Enter package name: `peertube-plugin-german-ai-mod`\n   - Or upload ZIP file\n\n2. Or install via npm:\n   ```bash\n   npm install peertube-plugin-german-ai-mod\n   ```\n\n## Configuration\n\nAfter installation, configure the plugin in PeerTube admin panel:\n\n- **AI Endpoint URL**: URL of the AI moderation service (default: `http://ai-moderator:8000/analyze`)\n- **Toxizitäts-Schwelle (0–1)**: Threshold for general toxicity detection (default: `0.7`)\n- **Hate Speech Schwelle (0–1)**: Threshold for hate speech detection (default: `0.5`)\n- **Aktion für nicht-deutsche Kommentare**: \n  - `Zur Moderation zurückhalten` - Send to moderation queue (default)\n  - `Blockieren` - Block immediately\n\n### Recommended Thresholds\n\n- **Moderate (default)**: Toxicity 0.7, Hate Speech 0.5 - Blocks only explicit insults\n- **Strict**: Toxicity 0.5, Hate Speech 0.4 - Blocks more aggressive comments\n- **Soft**: Toxicity 0.8, Hate Speech 0.6 - Blocks only very explicit insults\n\n## AI Service Setup\n\nThis plugin requires a separate AI moderation service. See the `ai-moderation` directory for FastAPI service setup with Docker.\n\nThe AI service should provide a POST endpoint `/analyze` that accepts:\n```json\n{\n  \"text\": \"comment text here\"\n}\n```\n\nAnd returns:\n```json\n{\n  \"toxic\": false,\n  \"score\": 0.15,\n  \"language\": \"de\",\n  \"is_german\": true,\n  \"requires_moderation\": false,\n  \"hate_score\": 0.05\n}\n```\n\nWhere:\n- `toxic`: boolean - whether comment should be blocked (based on thresholds)\n- `score`: float (0-1) - general toxicity score from primary model\n- `hate_score`: float (0-1) - hate speech score from secondary model\n- `language`: string - detected language code\n- `is_german`: boolean - whether comment is in German\n- `requires_moderation`: boolean - whether comment requires manual review\n\n## How It Works\n\n1. When a comment is created, the plugin sends it to the AI service\n2. AI service detects the language using `langdetect`\n3. For non-German comments: sends to moderation or blocks (based on settings)\n4. For German comments:\n   - Primary model checks general toxicity\n   - Secondary model checks for hate speech\n   - Comment is blocked if `score >= toxicity_threshold` OR `hate_score >= hate_threshold`\n5. Toxic/hate speech comments are automatically blocked\n\n## Hooks Used\n\n- `filter:api.video-thread.create.accept.result` - Main comments\n- `filter:api.video-comment-reply.create.accept.result` - Replies\n- `filter:activity-pub.remote-video-comment.create.accept.result` - Federated comments\n\n## Models Used\n\n- **Primary**: `ml6team/distilbert-base-german-cased-toxic-comments`\n  - Lightweight (67M parameters)\n  - Trained on 5 German toxicity datasets\n  - Optimized for comment toxicity detection\n  \n- **Secondary**: `deepset/bert-base-german-cased-hatespeech-GermEval18Coarse`\n  - Specialized for hate speech detection\n  - Trained on GermEval18 dataset\n  - Coarse-grained classification\n\n## License\n\nAGPL-3.0\n\n## Author\n\nyarkolife\n","readmeFilename":"README.md"}