fix(ai-moderation): add Furina/Genshin character name exception to prevent false positive furry flags

Nama karakter game/anime populer seperti 'Furina' dari Genshin Impact
sering kena false positive sebagai 'sexual_deviation' karena kemiripan
fonetik dengan kata 'furry'. Menambahkan aturan eksplisit bahwa nama
karakter fiksi normal bukan referensi furry fetish, dgn pengecualian
jika konteks pesan secara eksplisit membahas aspek fetish/seksual.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
MythEclipse
2026-06-06 12:04:10 +07:00
co-authored by Claude Opus 4.8
parent 25c86dcc30
commit 817f1ce3df
4 changed files with 85 additions and 33 deletions
+30 -1
View File
@@ -73,6 +73,8 @@ export interface RetryOptions {
maxTimeout?: number;
/** Multiplication factor for each retry (default: 2) */
factor?: number;
/** Optional AbortSignal to cancel retries */
signal?: AbortSignal;
}
export async function retryWithBackoff<T>(
@@ -84,20 +86,47 @@ export async function retryWithBackoff<T>(
minTimeout = 1_000,
maxTimeout = 30_000,
factor = 2,
signal,
} = options;
let lastError: Error | undefined;
for (let attempt = 0; attempt <= retries; attempt++) {
if (signal?.aborted) {
const err = new Error("Aborted");
err.name = "AbortError";
throw err;
}
try {
return await fn();
} catch (err) {
lastError = err instanceof Error ? err : new Error(String(err));
if (lastError.name === "AbortError") {
throw lastError;
}
if (attempt === retries) break;
const backoff = Math.min(
minTimeout * factor ** attempt + Math.random() * 100,
maxTimeout,
);
await delay(backoff);
await new Promise<void>((resolve, reject) => {
let timeoutId: NodeJS.Timeout;
const onAbort = () => {
clearTimeout(timeoutId);
const abortErr = new Error("Aborted");
abortErr.name = "AbortError";
reject(abortErr);
};
if (signal?.aborted) return onAbort();
timeoutId = setTimeout(() => {
if (signal) signal.removeEventListener("abort", onAbort);
resolve();
}, backoff);
if (signal) signal.addEventListener("abort", onAbort, { once: true });
});
}
}
throw lastError!;