fix: traduccion con rotacion de modelos + filtro anti-basura + benchmark de modelos

This commit is contained in:
Renato
2026-08-05 05:57:55 +08:00
parent 13e507fbb9
commit 636d629034
3 changed files with 159 additions and 40 deletions
+40 -3
View File
@@ -27,7 +27,26 @@ export async function translateTitle(title: string): Promise<string | null> {
// Si ya parece estar en español, no traducir (heurística ligera).
if (isProbablySpanish(clean)) return clean
const models = ["deepseek-v4-flash-free", "big-pickle"]
// Modelos en orden de preferencia (benchmark real 2026-08):
// nemotron-3-nano-omni y openrouter/free traducen bien.
const models = [
"nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free",
"openrouter/free",
"deepseek-v4-flash-free",
"big-pickle",
"tencent/hy3:free",
"nvidia/nemotron-3-ultra-550b-a55b:free",
"mimo-v2.5-free",
"cohere/north-mini-code:free",
"inclusionai/ling-3.0-flash:free",
"nvidia/nemotron-3-super-120b-a12b:free",
"nemotron-3-ultra-free",
"north-mini-code-free",
"poolside/laguna-s-2.1:free",
"poolside/laguna-xs-2.1:free",
"kilo-auto/free",
"forever_free",
]
for (const model of models) {
try {
@@ -51,8 +70,11 @@ export async function translateTitle(title: string): Promise<string | null> {
if (!res.ok) continue
const data = await res.json()
const content: string | undefined = data?.choices?.[0]?.message?.content
if (!content || !content.trim()) continue
return content.trim().replace(/^["']|["']$/g, "")
const text = (content || "").trim().replace(/^["']|["']$/g, "")
if (!text) continue
// Rechazar respuestas que NO son traducción (repiten el prompt).
if (!isValidTranslation(text)) continue
return text
} catch {
continue
}
@@ -60,6 +82,21 @@ export async function translateTitle(title: string): Promise<string | null> {
return null
}
// Filtra respuestas basura: si el modelo razona en voz alta ("The user
// wants...") o entrega explicaciones, no es una traducción válida.
function isValidTranslation(text: string): boolean {
const t = text.toLowerCase()
const junk = [
"the user wants", "the task", "i need to", "i'll", "the manga title",
"esta es una traducción", "aquí tienes", "la traducción es", "claro que",
"por supuesto", "the translation", "here is", "the title", "sure",
"voy a traducir", "the user asked", "the user is",
]
if (text.length > 120) return false
for (const j of junk) if (t.includes(j)) return false
return true
}
// Heurística: detecta si el título ya está mayormente en español (para no
// re-traducir nombres propios o títulos ya en español).
function isProbablySpanish(t: string): boolean {