dify/web/hooks/use-moderate.ts
2024-09-08 13:14:11 +08:00

50 lines
1.5 KiB
TypeScript

import { useEffect, useRef, useState } from 'react'
import type { ModerationService } from '@/models/common'
function splitStringByLength(inputString: string, chunkLength: number) {
const resultArray = []
for (let i = 0; i < inputString.length; i += chunkLength)
resultArray.push(inputString.substring(i, i + chunkLength))
return resultArray
}
export const useModerate = (
content: string,
stop: boolean,
moderationService: (text: string) => ReturnType<ModerationService>,
separateLength = 50,
) => {
const moderatedContentMap = useRef<Map<number, string>>(new Map())
const moderatingIndex = useRef<number[]>([])
const [contentArr, setContentArr] = useState<string[]>([])
const handleModerate = () => {
const stringArr = splitStringByLength(content, separateLength)
const lastIndex = stringArr.length - 1
stringArr.forEach((item, index) => {
if (!(index in moderatingIndex.current) && !moderatedContentMap.current.get(index)) {
if (index === lastIndex && !stop)
return
moderatingIndex.current.push(index)
moderationService(item).then((res) => {
if (res.flagged) {
moderatedContentMap.current.set(index, res.text)
setContentArr([...stringArr.slice(0, index), res.text, ...stringArr.slice(index + 1)])
}
})
}
})
setContentArr(stringArr)
}
useEffect(() => {
if (content)
handleModerate()
}, [content, stop])
return contentArr.map((item, index) => moderatedContentMap.current.get(index) || item).join('')
}