feat: Placeholder in der Auto-Generierung + Token-Leak-Fix
- Pair-Generierung markiert Nomen per [surface|lemma]-Markup und löst sie zu
{{label.o:objectId}} / {{label.w:wordId}} auf (Words werden auto-erstellt)
- Pipeline übersetzt + vertont Placeholder-Wörter aus den Sätzen mit
- translateText halluziniert keine ⟦PHn⟧-Tokens mehr (kein Token-Prompt ohne
Tokens, defensives Strippen); TTS/Review lösen geleakte Tokens auf
- POST /api/pipeline/repair-tokens repariert bestehende Sätze + Audios
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -5,14 +5,25 @@ const PLACEHOLDER_RE = /\{\{([^.{}]+)\.(w|o):([0-9a-f-]{36})\}\}/g;
|
||||
// Legacy-Form ohne Label: {{uuid}} — sollte migriert sein, defensiv trotzdem entfernen.
|
||||
const LEGACY_PLACEHOLDER_RE = /\{\{\s*[0-9a-f-]{36}\s*\}\}/g;
|
||||
|
||||
// Schutz-Token während Übersetzung/Review: ⟦PHn:label⟧. Darf nie in der DB landen —
|
||||
// falls doch (Claude-Halluzination), wird er überall defensiv zum Label aufgelöst.
|
||||
const TOKEN_RE = /⟦(PH\d+):([^⟧]*)⟧/g;
|
||||
|
||||
// Entfernt geleakte ⟦PHn:label⟧-Tokens aus einem Text → nur das Label bleibt.
|
||||
function stripLeakedTokens(text) {
|
||||
if (!text) return text;
|
||||
return String(text).replace(TOKEN_RE, (_, _key, label) => label.trim());
|
||||
}
|
||||
|
||||
// Macht aus "Ist das ein {{Apfel.w:1234-…}}?" → "Ist das ein Apfel?" (für TTS/Anzeige).
|
||||
function resolvePlaceholdersToLabels(text) {
|
||||
if (!text) return '';
|
||||
return String(text)
|
||||
.replace(PLACEHOLDER_RE, (_, label) => label)
|
||||
.replace(LEGACY_PLACEHOLDER_RE, '')
|
||||
.replace(TOKEN_RE, (_, _key, label) => label.trim())
|
||||
.replace(/\s{2,}/g, ' ')
|
||||
.trim();
|
||||
}
|
||||
|
||||
module.exports = { PLACEHOLDER_RE, resolvePlaceholdersToLabels };
|
||||
module.exports = { PLACEHOLDER_RE, TOKEN_RE, stripLeakedTokens, resolvePlaceholdersToLabels };
|
||||
|
||||
Reference in New Issue
Block a user