Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

👮feat: moderation text #1388

Merged
merged 10 commits into from
Jan 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,10 @@ MEILI_MASTER_KEY=DrhYf7zENyR6AlUCKmnz0eYASOQdl6zxH7s7MKFSfFCt
# Moderation #
#========================#

OPENAI_MODERATION=false
OPENAI_MODERATION_API_KEY=
# OPENAI_MODERATION_REVERSE_PROXY=not working with some reverse proxys

BAN_VIOLATIONS=true
BAN_DURATION=1000 * 60 * 60 * 2
BAN_INTERVAL=20
Expand Down
2 changes: 2 additions & 0 deletions api/server/middleware/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const concurrentLimiter = require('./concurrentLimiter');
const validateMessageReq = require('./validateMessageReq');
const buildEndpointOption = require('./buildEndpointOption');
const validateRegistration = require('./validateRegistration');
const moderateText = require('./moderateText');
const noIndex = require('./noIndex');

module.exports = {
Expand All @@ -29,5 +30,6 @@ module.exports = {
validateMessageReq,
buildEndpointOption,
validateRegistration,
moderateText,
noIndex,
};
39 changes: 39 additions & 0 deletions api/server/middleware/moderateText.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
const axios = require('axios');
const denyRequest = require('./denyRequest');

async function moderateText(req, res, next) {
if (process.env.OPENAI_MODERATION === 'true') {
try {
const { text } = req.body;

const response = await axios.post(
process.env.OPENAI_MODERATION_REVERSE_PROXY || 'https://api.openai.com/v1/moderations',
{
input: text,
},
{
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${process.env.OPENAI_MODERATION_API_KEY}`,
},
},
);

const results = response.data.results;
const flagged = results.some((result) => result.flagged);

if (flagged) {
const type = 'moderation';
const errorMessage = { type };
return await denyRequest(req, res, errorMessage);
}
} catch (error) {
console.error('Error in moderateText:', error);
const errorMessage = 'error in moderation check';
return await denyRequest(req, res, errorMessage);
}
}
next();
}

module.exports = moderateText;
2 changes: 2 additions & 0 deletions api/server/routes/ask/gptPlugins.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@ const {
setHeaders,
validateEndpoint,
buildEndpointOption,
moderateText,
} = require('~/server/middleware');
const { logger } = require('~/config');

router.use(moderateText);
router.post('/abort', handleAbort());

router.post('/', validateEndpoint, buildEndpointOption, setHeaders, async (req, res) => {
Expand Down
3 changes: 2 additions & 1 deletion api/server/routes/ask/openAI.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ const {
setHeaders,
validateEndpoint,
buildEndpointOption,
moderateText,
} = require('~/server/middleware');

const router = express.Router();

router.use(moderateText);
router.post('/abort', handleAbort());

router.post('/', validateEndpoint, buildEndpointOption, setHeaders, async (req, res, next) => {
Expand Down
2 changes: 2 additions & 0 deletions api/server/routes/edit/gptPlugins.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ const {
setHeaders,
validateEndpoint,
buildEndpointOption,
moderateText,
} = require('~/server/middleware');
const { logger } = require('~/config');

router.use(moderateText);
router.post('/abort', handleAbort());

router.post('/', validateEndpoint, buildEndpointOption, setHeaders, async (req, res) => {
Expand Down
3 changes: 2 additions & 1 deletion api/server/routes/edit/openAI.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ const {
setHeaders,
validateEndpoint,
buildEndpointOption,
moderateText,
} = require('~/server/middleware');

const router = express.Router();

router.use(moderateText);
router.post('/abort', handleAbort());

router.post('/', validateEndpoint, buildEndpointOption, setHeaders, async (req, res, next) => {
Expand Down
2 changes: 2 additions & 0 deletions client/src/components/Messages/Content/Error.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ const errorMessages = {
'Invalid API key. Please check your API key and try again. You can do this by clicking on the model logo in the left corner of the textbox and selecting "Set Token" for the current selected endpoint. Thank you for your understanding.',
insufficient_quota:
'We apologize for any inconvenience caused. The default API key has reached its limit. To continue using this service, please set up your own API key. You can do this by clicking on the model logo in the left corner of the textbox and selecting "Set Token" for the current selected endpoint. Thank you for your understanding.',
moderation:
'It appears that the content submitted has been flagged by our moderation system for not aligning with our community guidelines. We\'re unable to proceed with this specific topic. If you have any other questions or topics you\'d like to explore, please edit your message, or create a new conversation.',
concurrent: (json: TConcurrent) => {
const { limit } = json;
const plural = limit > 1 ? 's' : '';
Expand Down
27 changes: 26 additions & 1 deletion docs/features/mod_system.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,29 @@ MESSAGE_IP_WINDOW=1 # in minutes, determines the window of time for MESSAGE_IP_M
LIMIT_MESSAGE_USER=false # Whether to limit the amount of messages an IP can send per MESSAGE_USER_WINDOW
MESSAGE_USER_MAX=40 # The max amount of messages an IP can send per MESSAGE_USER_WINDOW
MESSAGE_USER_WINDOW=1 # in minutes, determines the window of time for MESSAGE_USER_MAX messages
```
```

## OpenAI moderation text

### OPENAI_MODERATION
enable or disable OpenAI moderation

Values:
`true`: OpenAI moderation is enabled
`false`: OpenAI moderation is disabled

### OPENAI_MODERATION_API_KEY
Specify your OpenAI moderation API key here

### OPENAI_MODERATION_REVERSE_PROXY
enable or disable reverse proxy compatibility for OpenAI moderation. Note that it may not work with some reverse proxies

Values:
`true`: Enable reverse proxy compatibility
`false`: Disable reverse proxy compatibility

```bash
OPENAI_MODERATION=true
OPENAI_MODERATION_API_KEY=sk-1234
# OPENAI_MODERATION_REVERSE_PROXY=false
```