Str::lower(trim((string) $term)), $this->runtimeConfig->blockedTerms() )); if ($blockedTerms === []) { return AiSafetyDecision::passed(); } $fullPrompt = Str::lower(trim(sprintf('%s %s', (string) $prompt, (string) $negativePrompt))); if ($fullPrompt === '') { return AiSafetyDecision::passed(); } $matched = []; foreach ($blockedTerms as $term) { if ($term !== '' && str_contains($fullPrompt, $term)) { $matched[] = 'prompt_blocked_term'; } } if ($matched === []) { return AiSafetyDecision::passed(); } return AiSafetyDecision::blocked( reasonCodes: $matched, failureCode: 'prompt_policy_blocked', failureMessage: 'The provided prompt violates the AI editing safety policy.' ); } public function evaluateProviderOutput(AiProviderResult $result): AiSafetyDecision { if ($result->status === 'blocked') { return AiSafetyDecision::blocked( reasonCodes: $result->safetyReasons !== [] ? $result->safetyReasons : ['provider_blocked'], failureCode: $result->failureCode ?: 'output_policy_blocked', failureMessage: $result->failureMessage ?: 'The generated output was blocked by safety policy.' ); } if ($result->safetyState === 'blocked') { return AiSafetyDecision::blocked( reasonCodes: $result->safetyReasons !== [] ? $result->safetyReasons : ['provider_nsfw_content'], failureCode: 'output_policy_blocked', failureMessage: 'The generated output was blocked by safety policy.' ); } $payloadItems = (array) Arr::get($result->responsePayload, 'data', []); foreach ($payloadItems as $item) { if (! is_array($item)) { continue; } if ($this->toBool(Arr::get($item, 'NSFWContent')) || $this->toBool(Arr::get($item, 'nsfwContent'))) { return AiSafetyDecision::blocked( reasonCodes: ['provider_nsfw_content'], failureCode: 'output_policy_blocked', failureMessage: 'The generated output was blocked by safety policy.' ); } } return AiSafetyDecision::passed(); } private function toBool(mixed $value): bool { if (is_bool($value)) { return $value; } if (is_numeric($value)) { return (int) $value === 1; } if (is_string($value)) { return in_array(Str::lower(trim($value)), ['1', 'true', 'yes'], true); } return false; } }