[+] Safety moderation

tmp
Azalea 2024-04-18 11:29:02 +09:00
parent 5ba64483fb
commit 60661757c6
2 changed files with 79 additions and 0 deletions

View File

@ -0,0 +1,71 @@
package icu.samnyan.aqua.net
import ext.HTTP
import ext.async
import ext.toJson
import icu.samnyan.aqua.net.games.BaseEntity
import io.ktor.client.call.*
import io.ktor.client.request.*
import io.ktor.http.*
import jakarta.persistence.Entity
import kotlinx.serialization.Serializable
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.context.annotation.Configuration
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.stereotype.Service
@Configuration
@ConfigurationProperties(prefix = "aqua-net.openai")
class OpenAIConfig {
var apiKey: String = ""
}
@Entity
class AquaNetSafety : BaseEntity() {
var content: String = ""
var safe: Boolean = false
}
interface AquaNetSafetyRepo : JpaRepository<AquaNetSafety, Long> {
fun findByContent(content: String): AquaNetSafety?
}
@Serializable
data class OpenAIResp<T>(
val id: String,
val model: String,
val results: List<T>
)
@Serializable
data class OpenAIMod(
val flagged: Boolean,
val categories: Map<String, Boolean>,
val categoryScores: Map<String, Double>,
)
@Service
class AquaNetSafetyService(
val safety: AquaNetSafetyRepo,
val openAIConfig: OpenAIConfig
) {
suspend fun isSafe(content: String): Boolean {
if (content.isBlank()) return true
async { safety.findByContent(content) }?.let { return it.safe }
// Query OpenAI
HTTP.post("https://api.openai.com/v1/moderations") {
header("Authorization", "Bearer ${openAIConfig.apiKey}")
header("Content-Type", "application/json")
setBody(mapOf("input" to content).toJson())
}.let {
if (!it.status.isSuccess()) return true
val body = it.body<OpenAIResp<OpenAIMod>>()
return AquaNetSafety().apply {
this.content = content
this.safe = !body.results.first().flagged
}.also { safety.save(it) }.safe
}
}
}

View File

@ -0,0 +1,8 @@
CREATE TABLE aqua_net_safety
(
id BIGINT AUTO_INCREMENT NOT NULL,
content VARCHAR(255) NOT NULL,
safe BIT(1) NOT NULL,
CONSTRAINT pk_aqua_net_safety PRIMARY KEY (id),
CONSTRAINT uq_aqua_net_safety_content UNIQUE (content)
);