import { useState, useEffect, useMemo } from 'react'; import { Switch } from '../../ui/switch'; import { useConfig } from '../../ConfigContext'; import { trackSettingToggled } from '../../../utils/analytics'; import { defineMessages, useIntl } from '../../../i18n'; const i18n = defineMessages({ enablePromptInjection: { id: 'securityToggle.enablePromptInjection', defaultMessage: 'Enable Prompt Injection Detection', }, promptInjectionDescription: { id: 'securityToggle.promptInjectionDescription', defaultMessage: 'Detect and prevent potential prompt injection attacks', }, detectionThreshold: { id: 'securityToggle.detectionThreshold', defaultMessage: 'Detection Threshold', }, thresholdDescription: { id: 'securityToggle.thresholdDescription', defaultMessage: 'Higher values are more strict (0.01 = very lenient, 1.0 = maximum strict)', }, enableCommandInjection: { id: 'securityToggle.enableCommandInjection', defaultMessage: 'Enable Command Injection ML Detection', }, commandInjectionDescription: { id: 'securityToggle.commandInjectionDescription', defaultMessage: 'Use ML models to detect malicious shell commands', }, commandClassifierActive: { id: 'securityToggle.commandClassifierActive', defaultMessage: 'Command classifier active (auto-configured from environment)', }, enablePromptInjectionMl: { id: 'securityToggle.enablePromptInjectionMl', defaultMessage: 'Enable Prompt Injection ML Detection', }, promptInjectionMlDescription: { id: 'securityToggle.promptInjectionMlDescription', defaultMessage: 'Use ML models to detect potential prompt injection in your chat', }, detectionModel: { id: 'securityToggle.detectionModel', defaultMessage: 'Detection Model', }, detectionModelDescription: { id: 'securityToggle.detectionModelDescription', defaultMessage: 'Select which ML model to use for prompt injection detection', }, classificationEndpoint: { id: 'securityToggle.classificationEndpoint', defaultMessage: 'Classification Endpoint', }, classificationEndpointDescription: { id: 'securityToggle.classificationEndpointDescription', defaultMessage: 'Enter the full URL for your classification service', }, apiTokenOptional: { id: 'securityToggle.apiTokenOptional', defaultMessage: 'API Token (Optional)', }, apiTokenDescription: { id: 'securityToggle.apiTokenDescription', defaultMessage: 'Authentication token for the classification service', }, commandEndpointDescription: { id: 'securityToggle.commandEndpointDescription', defaultMessage: 'Enter the full URL for your command injection classification service', }, mlEndpointDescription: { id: 'securityToggle.mlEndpointDescription', defaultMessage: 'Enter the full URL for your ML classification service (including model identifier)', }, mlTokenDescription: { id: 'securityToggle.mlTokenDescription', defaultMessage: 'Authentication token for the ML service (e.g., HuggingFace token)', }, }); interface SecurityConfig { SECURITY_PROMPT_ENABLED?: boolean; SECURITY_PROMPT_THRESHOLD?: number; SECURITY_PROMPT_CLASSIFIER_ENABLED?: boolean; SECURITY_PROMPT_CLASSIFIER_MODEL?: string; SECURITY_PROMPT_CLASSIFIER_ENDPOINT?: string; SECURITY_PROMPT_CLASSIFIER_TOKEN?: string; SECURITY_COMMAND_CLASSIFIER_ENABLED?: boolean; SECURITY_COMMAND_CLASSIFIER_ENDPOINT?: string; SECURITY_COMMAND_CLASSIFIER_TOKEN?: string; } interface ClassifierEndpointInputsProps { endpointValue: string; tokenValue: string; onEndpointChange: (value: string) => void; onTokenChange: (value: string) => void; onEndpointBlur: (value: string) => void; onTokenBlur: (value: string) => void; disabled: boolean; endpointPlaceholder: string; tokenPlaceholder: string; endpointLabel?: string; endpointDescription?: string; tokenLabel?: string; tokenDescription?: string; } const ClassifierEndpointInputs = ({ endpointValue, tokenValue, onEndpointChange, onTokenChange, onEndpointBlur, onTokenBlur, disabled, endpointPlaceholder, tokenPlaceholder, endpointLabel, endpointDescription, tokenLabel, tokenDescription, }: ClassifierEndpointInputsProps) => { return (
{endpointDescription}
onEndpointChange(e.target.value)} onBlur={(e) => onEndpointBlur(e.target.value)} disabled={disabled} placeholder={endpointPlaceholder} className={`w-full px-3 py-2 text-sm border rounded placeholder:text-text-secondary ${ disabled ? 'border-border-primary bg-background-secondary text-text-secondary cursor-not-allowed' : 'border-border-primary bg-background-primary text-text-primary' }`} />{tokenDescription}
onTokenChange(e.target.value)} onBlur={(e) => onTokenBlur(e.target.value)} disabled={disabled} placeholder={tokenPlaceholder} className={`w-full px-3 py-2 text-sm border rounded placeholder:text-text-secondary ${ disabled ? 'border-border-primary bg-background-secondary text-text-secondary cursor-not-allowed' : 'border-border-primary bg-background-primary text-text-primary' }`} />{intl.formatMessage(i18n.promptInjectionDescription)}
{intl.formatMessage(i18n.thresholdDescription)}
{ setThresholdInput(e.target.value); }} onBlur={(e) => { const value = parseFloat(e.target.value); if (isNaN(value) || value < 0.01 || value > 1.0) { // Revert to previous valid value setThresholdInput(configThreshold.toString()); } else { handleThresholdChange(value); } }} disabled={!enabled} className={`w-24 px-2 py-1 text-sm border rounded ${ enabled ? 'border-border-primary bg-background-primary text-text-primary' : 'border-border-primary bg-background-secondary text-text-secondary cursor-not-allowed' }`} placeholder="0.80" />{intl.formatMessage(i18n.commandInjectionDescription)}
{intl.formatMessage(i18n.promptInjectionMlDescription)}
{intl.formatMessage(i18n.detectionModelDescription)}