feat(ai): finalize AI magic edits epic rollout and operations
This commit is contained in:
64
app/Services/AiEditing/Safety/AiAbuseEscalationService.php
Normal file
64
app/Services/AiEditing/Safety/AiAbuseEscalationService.php
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\AiEditing\Safety;
|
||||
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class AiAbuseEscalationService
|
||||
{
|
||||
public const REASON_CODE = 'abuse_escalation_threshold_reached';
|
||||
|
||||
/**
|
||||
* @return array{type:string,count:int,threshold:int,escalated:bool,reason_code:?string}
|
||||
*/
|
||||
public function recordPromptBlock(int $tenantId, int $eventId, string $scope): array
|
||||
{
|
||||
return $this->record('prompt_block', $tenantId, $eventId, $scope);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{type:string,count:int,threshold:int,escalated:bool,reason_code:?string}
|
||||
*/
|
||||
public function recordOutputBlock(int $tenantId, int $eventId, string $scope): array
|
||||
{
|
||||
return $this->record('output_block', $tenantId, $eventId, $scope);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{type:string,count:int,threshold:int,escalated:bool,reason_code:?string}
|
||||
*/
|
||||
private function record(string $type, int $tenantId, int $eventId, string $scope): array
|
||||
{
|
||||
$threshold = max(1, (int) config('ai-editing.abuse.escalation_threshold_per_hour', 25));
|
||||
$cooldownMinutes = max(1, (int) config('ai-editing.abuse.escalation_cooldown_minutes', 30));
|
||||
$bucket = now()->format('YmdH');
|
||||
|
||||
$counterKey = sprintf('ai-editing:abuse:%s:tenant:%d:event:%d:hour:%s', $type, $tenantId, $eventId, $bucket);
|
||||
Cache::add($counterKey, 0, now()->addHours(2));
|
||||
$count = (int) Cache::increment($counterKey);
|
||||
|
||||
$escalated = $count >= $threshold;
|
||||
if ($escalated) {
|
||||
$cooldownKey = sprintf('ai-editing:abuse:%s:tenant:%d:event:%d:cooldown', $type, $tenantId, $eventId);
|
||||
if (Cache::add($cooldownKey, 1, now()->addMinutes($cooldownMinutes))) {
|
||||
Log::warning('AI abuse escalation threshold reached', [
|
||||
'tenant_id' => $tenantId,
|
||||
'event_id' => $eventId,
|
||||
'type' => $type,
|
||||
'count' => $count,
|
||||
'threshold' => $threshold,
|
||||
'scope_hash' => hash('sha256', $scope),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'type' => $type,
|
||||
'count' => $count,
|
||||
'threshold' => $threshold,
|
||||
'escalated' => $escalated,
|
||||
'reason_code' => $escalated ? self::REASON_CODE : null,
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user