[CORl-278] Perspective Model (#2337)

* feat: support switching the perspective model

* feat: support changing the model on admin

* fix: linting

* fix: removed defaulted value
This commit is contained in:
Wyatt Johnson
2019-06-28 22:10:32 +00:00
committed by GitHub
parent e72b15c505
commit 76033118e5
12 changed files with 154 additions and 19 deletions
@@ -5,6 +5,10 @@ import { Field } from "react-final-form";
import { formatPercentage, parsePercentage } from "coral-framework/lib/form";
import {
TOXICITY_MODEL_DEFAULT,
TOXICITY_THRESHOLD_DEFAULT,
} from "coral-common/constants";
import { ExternalLink } from "coral-framework/lib/i18n/components";
import {
composeValidators,
@@ -32,9 +36,6 @@ import APIKeyField from "./APIKeyField";
import styles from "./PerspectiveConfig.css";
/* TODO: use a common constants for both client and server. */
const TOXICITY_DEFAULT = 80;
interface Props {
disabled: boolean;
}
@@ -69,7 +70,7 @@ const PerspectiveConfig: FunctionComponent<Props> = ({ disabled }) => {
<FormField container={<FieldSet />}>
<Localized id="configure-moderation-perspective-filter">
<InputLabel container="legend">Spam Detection Filter</InputLabel>
<InputLabel container="legend">Toxic Comment Filter</InputLabel>
</Localized>
<OnOffField
name="integrations.perspective.enabled"
@@ -85,12 +86,12 @@ const PerspectiveConfig: FunctionComponent<Props> = ({ disabled }) => {
</Localized>
<Localized
id="configure-moderation-perspective-toxicityThresholdDescription"
$default={TOXICITY_DEFAULT}
$default={TOXICITY_THRESHOLD_DEFAULT + "%"}
>
<InputDescription>
This value can be set a percentage between 0 and 100. This number
represents the likelihood that a comment is toxic, according to
Perspective API. Defaults to $default.
Perspective API. By default the threshold is set to $default.
</InputDescription>
</Localized>
<Field
@@ -113,7 +114,7 @@ const PerspectiveConfig: FunctionComponent<Props> = ({ disabled }) => {
autoCapitalize="off"
spellCheck={false}
adornment={<Typography variant="bodyCopy">%</Typography>}
placeholder={TOXICITY_DEFAULT.toString()}
placeholder={TOXICITY_THRESHOLD_DEFAULT.toString()}
textAlignCenter
/>
{meta.touched && (meta.error || meta.submitError) && (
@@ -126,6 +127,53 @@ const PerspectiveConfig: FunctionComponent<Props> = ({ disabled }) => {
</Field>
</FormField>
<FormField>
<Localized id="configure-moderation-perspective-toxicityModel">
<InputLabel htmlFor="configure-moderation-perspective-model">
Toxicity Model
</InputLabel>
</Localized>
<Localized
id="configure-moderation-perspective-toxicityModelDescription"
externalLink={
<ExternalLink
href={
"https://github.com/conversationai/perspectiveapi/blob/master/api_reference.md#models"
}
/>
}
$default={TOXICITY_MODEL_DEFAULT}
>
<InputDescription>
Choose your Perspective Model. The default is $default. You can find
out more about model choices here.
</InputDescription>
</Localized>
<Field name="integrations.perspective.model">
{({ input, meta }) => (
<>
<TextField
id="configure-moderation-perspective-model"
name={input.name}
onChange={input.onChange}
value={input.value}
disabled={disabled}
autoComplete="off"
autoCorrect="off"
autoCapitalize="off"
placeholder={TOXICITY_MODEL_DEFAULT}
spellCheck={false}
/>
{meta.touched && (meta.error || meta.submitError) && (
<ValidationMessage>
{meta.error || meta.submitError}
</ValidationMessage>
)}
</>
)}
</Field>
</FormField>
<FormField container={<FieldSet />}>
<Localized id="configure-moderation-perspective-allowStoreCommentData">
<InputLabel container="legend">
@@ -135,7 +183,7 @@ const PerspectiveConfig: FunctionComponent<Props> = ({ disabled }) => {
<Localized id="configure-moderation-perspective-allowStoreCommentDataDescription">
<InputDescription>
Stored comments will be used for future research and community model
building purposes to improve the API over time
building purposes to improve the API over time.
</InputDescription>
</Localized>
<div>
@@ -32,6 +32,7 @@ const enhanced = withFragmentContainer<Props>({
enabled
endpoint
key
model
threshold
doNotStore
}
@@ -294,6 +294,7 @@ Markdown can be found
<a
className="ExternalLink-root"
href="#"
rel="noopener noreferrer"
target="_blank"
>
here
@@ -202,7 +202,7 @@ the
className="Box-root Typography-root Typography-detail Typography-colorTextSecondary"
>
This value can be set a percentage between 0 and 100. This number represents the likelihood that a
comment is toxic, according to Perspective API. By default the treshold is set to 80.
comment is toxic, according to Perspective API. By default the threshold is set to 80%.
</p>
<div
className="TextField-root PerspectiveConfig-thresholdTextField"
@@ -232,6 +232,48 @@ comment is toxic, according to Perspective API. By default the treshold is set t
</div>
</div>
</div>
<div
className="Box-root HorizontalGutter-root FormField-root HorizontalGutter-half"
>
<label
className="Box-root Typography-root Typography-inputLabel Typography-colorTextPrimary InputLabel-root"
htmlFor="configure-moderation-perspective-model"
>
Toxicity Model
</label>
<p
className="Box-root Typography-root Typography-detail Typography-colorTextSecondary"
>
Choose your Perspective Model. The default is TOXICITY. You can find out more about model choices
<a
className="ExternalLink-root"
href="https://github.com/conversationai/perspectiveapi/blob/master/api_reference.md#models"
rel="noopener noreferrer"
target="_blank"
>
here
</a>
.
</p>
<div
className="TextField-root"
>
<input
autoCapitalize="off"
autoComplete="off"
autoCorrect="off"
className="TextField-input TextField-colorRegular"
disabled={false}
id="configure-moderation-perspective-model"
name="integrations.perspective.model"
onChange={[Function]}
placeholder="TOXICITY"
spellCheck={false}
type="text"
value=""
/>
</div>
</div>
<fieldset
className="FieldSet-root Box-root HorizontalGutter-root FormField-root HorizontalGutter-half"
>
@@ -244,7 +286,7 @@ comment is toxic, according to Perspective API. By default the treshold is set t
className="Box-root Typography-root Typography-detail Typography-colorTextSecondary"
>
Stored comments will be used for future research and community model building purposes to
improve the API over time
improve the API over time.
</p>
<div>
<div>
@@ -309,6 +351,7 @@ improve the API over time
<a
className="ExternalLink-root"
href="https://github.com/conversationai/perspectiveapi/blob/master/quickstart.md"
rel="noopener noreferrer"
target="_blank"
>
https://github.com/conversationai/perspectiveapi/blob/master/quickstart.md
@@ -477,6 +520,7 @@ in your Akismet account:
<a
className="ExternalLink-root"
href="https://akismet.com/account/"
rel="noopener noreferrer"
target="_blank"
>
https://akismet.com/account/
@@ -141,6 +141,7 @@ and paste a comma separated list?
<a
className="ExternalLink-root"
href="#"
rel="noopener noreferrer"
target="_blank"
>
Learn how to convert your list
@@ -198,6 +199,7 @@ and paste a comma separated list?
<a
className="ExternalLink-root"
href="#"
rel="noopener noreferrer"
target="_blank"
>
Learn how to convert your list
@@ -150,6 +150,7 @@ it("change perspective settings", async () => {
enabled: true,
endpoint: "https://custom-endpoint.net",
key: "my api key",
model: null,
threshold: 0.1,
}
);
@@ -6,7 +6,17 @@ const ExternalLink: FunctionComponent<{
href?: string;
children?: string;
}> = ({ href, children }) => (
<a href={href || children} target="_blank" className={styles.root}>
<a
href={href || children}
target="_blank"
/**
* Added as a security workaround as per:
*
* https://www.jitbit.com/alexblog/256-targetblank---the-most-underestimated-vulnerability-ever/
*/
rel="noopener noreferrer"
className={styles.root}
>
{children}
</a>
);
@@ -4,6 +4,7 @@ exports[`renders correctly 1`] = `
<a
className="ExternalLink-root"
href="http://test.com"
rel="noopener noreferrer"
target="_blank"
>
http://test.com
+11
View File
@@ -16,3 +16,14 @@ export const CLIENT_ID_PARAM = "clientID";
* token in connectionParams when authenticating a websocket connection.
*/
export const ACCESS_TOKEN_PARAM = "accessToken";
/**
* TOXICITY_THRESHOLD_DEFAULT is the default value used when the threshold is
* not set.
*/
export const TOXICITY_THRESHOLD_DEFAULT = 80;
/**
* TOXICITY_MODEL_DEFAULT is the default value used for the toxicity model.
*/
export const TOXICITY_MODEL_DEFAULT = "TOXICITY";
@@ -763,6 +763,11 @@ type PerspectiveExternalIntegration {
"""
threshold: Float
"""
model is the Perspective model to use.
"""
model: String
"""
When True, comments sent will not be stored by the Google Perspective API.
"""
@@ -2693,6 +2698,11 @@ input SettingsPerspectiveExternalIntegrationInput {
"""
key: String
"""
model is the name of the Perspective model to use.
"""
model: String
"""
The threshold that given a specific toxic comment score, the comment will
be marked by Coral as toxic.
@@ -2,6 +2,10 @@ import { isNil } from "lodash";
import ms from "ms";
import fetch from "node-fetch";
import {
TOXICITY_MODEL_DEFAULT,
TOXICITY_THRESHOLD_DEFAULT,
} from "coral-common/constants";
import { Omit } from "coral-common/types";
import { ToxicCommentError } from "coral-server/errors";
import {
@@ -56,8 +60,7 @@ export const toxic: IntermediateModerationPhase = async ({
let threshold = integration.threshold;
if (isNil(threshold)) {
// TODO: (wyattjoh) replace hardcoded default with config.
threshold = 0.8;
threshold = TOXICITY_THRESHOLD_DEFAULT / 100;
log.trace(
{ threshold },
@@ -81,17 +84,17 @@ export const toxic: IntermediateModerationPhase = async ({
try {
logger.trace("checking comment toxicity");
// TODO: (wyattjoh) support custom toxicity model.
const model = "TOXICITY";
// Pull the custom model out.
const model = integration.model || TOXICITY_MODEL_DEFAULT;
// Call into the Toxic comment API.
const score = await getScore(
comment.body,
model,
{
endpoint,
key: integration.key,
doNotStore,
model,
},
timeout
);
@@ -142,10 +145,10 @@ export const toxic: IntermediateModerationPhase = async ({
*/
async function getScore(
text: string,
model: string,
{
key,
endpoint,
model,
doNotStore,
}: Required<Omit<GQLPerspectiveExternalIntegration, "enabled" | "threshold">>,
timeout: number
+5 -2
View File
@@ -245,11 +245,14 @@ configure-moderation-perspective-filter = Toxic Comment Filter
configure-moderation-perspective-toxicityThreshold = Toxicity Threshold
configure-moderation-perspective-toxicityThresholdDescription =
This value can be set a percentage between 0 and 100. This number represents the likelihood that a
comment is toxic, according to Perspective API. By default the treshold is set to { $default }.
comment is toxic, according to Perspective API. By default the threshold is set to { $default }.
configure-moderation-perspective-toxicityModel = Toxicity Model
configure-moderation-perspective-toxicityModelDescription =
Choose your Perspective Model. The default is { $default }. You can find out more about model choices <externalLink>here</externalLink>.
configure-moderation-perspective-allowStoreCommentData = Allow Google to Store Comment Data
configure-moderation-perspective-allowStoreCommentDataDescription =
Stored comments will be used for future research and community model building purposes to
improve the API over time
improve the API over time.
configure-moderation-perspective-customEndpoint = Custom Endpoint
configure-moderation-perspective-defaultEndpoint =
By default the endpoint is set to { $default }. You may override this here.