mirror of
https://github.com/wassname/talk.git
synced 2026-07-15 11:26:58 +08:00
[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:
@@ -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>
|
||||
|
||||
+1
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user