tts message not read controlcodes

This commit is contained in:
duffyduck 2025-12-29 01:35:31 +01:00
parent 8db8a693b5
commit 2cf6ceae8e
2 changed files with 52 additions and 58 deletions

View File

@ -1239,6 +1239,7 @@ Erst wenn ich [READY] sehe, starten die TICKs mit Bildern!"""
# Marker entfernen # Marker entfernen
text = re.sub(r'\[TICK\]', '', text) text = re.sub(r'\[TICK\]', '', text)
text = re.sub(r'\[START\]', '', text) text = re.sub(r'\[START\]', '', text)
text = re.sub(r'\[READY\]', '', text) # [READY] nicht vorlesen
# Fahrbefehle entfernen # Fahrbefehle entfernen
text = re.sub(r'\[(FORWARD|BACKWARD|LEFT|RIGHT|STOP)\]', '', text) text = re.sub(r'\[(FORWARD|BACKWARD|LEFT|RIGHT|STOP)\]', '', text)

View File

@ -679,16 +679,16 @@ class ClaudeChatInterface:
if not claude_elements: if not claude_elements:
try: try:
# Claude.ai 2024/2025 nutzt oft conversation-turn Divs # Claude.ai 2024/2025 nutzt oft conversation-turn Divs
# WICHTIG: Wir suchen den CONTAINER der die gesamte Claude-Nachricht enthält, # WICHTIG: Wir suchen EINZELNE Nachrichten, nicht den ganzen Chat!
# nicht nur das Element mit "Claude sagt:" - denn [READY] kann in einem # Jede "Claude sagt:" Nachricht soll ein separates Element sein.
# separaten Child-Element stehen!
found = self.driver.execute_script(""" found = self.driver.execute_script("""
const msgs = []; const msgs = [];
// Strategie: Finde Elemente mit "Claude sagt:" und dann den // Strategie 1: Suche nach einzelnen Absätzen/Divs die MIT "Claude sagt:" beginnen
// ÜBERGEORDNETEN Container der die vollständige Nachricht enthält // NICHT nach Containern die den ganzen Chat enthalten!
const allDivs = document.querySelectorAll('div, p, span'); const allElements = document.querySelectorAll('p, div, span');
for (const elem of allDivs) {
for (const elem of allElements) {
// Überspringe wenn es ein user-message ist // Überspringe wenn es ein user-message ist
if (elem.getAttribute('data-testid') === 'user-message') continue; if (elem.getAttribute('data-testid') === 'user-message') continue;
if (elem.closest('[data-testid="user-message"]')) continue; if (elem.closest('[data-testid="user-message"]')) continue;
@ -702,55 +702,42 @@ class ClaudeChatInterface:
// Hole den direkten Text-Inhalt // Hole den direkten Text-Inhalt
const text = (elem.innerText || '').trim(); const text = (elem.innerText || '').trim();
// Text muss mit "Claude sagt:" BEGINNEN // STRENG: Text muss EXAKT mit "Claude sagt:" beginnen
if (text.startsWith('Claude sagt:') && text.length > 20 && text.length < 10000) { // UND darf nicht den ganzen Chat sein (max 3000 Zeichen für eine Nachricht)
// Suche nach dem übergeordneten Container (z.B. prose-Container) if (text.startsWith('Claude sagt:') && text.length > 20 && text.length < 3000) {
// der auch [READY] enthalten könnte // Prüfe ob dieses Element nicht schon in einem anderen enthalten ist
let container = elem; // (wir wollen das KLEINSTE passende Element)
let parent = elem.parentElement; let dominated = false;
// Gehe nach oben bis wir einen guten Container finden
// (max 5 Ebenen, um nicht die ganze Seite zu erfassen)
for (let i = 0; i < 5 && parent; i++) {
const parentText = (parent.innerText || '').trim();
// Stoppe wenn wir einen zu großen Container erreichen
if (parentText.length > 15000) break;
// Stoppe wenn wir in user-message oder Navigation sind
if (parent.getAttribute('data-testid') === 'user-message') break;
if (parent.closest('nav')) break;
// Prüfe ob der Parent-Container [READY] enthält und
// immer noch mit "Claude sagt:" beginnt
if (parentText.startsWith('Claude sagt:') ||
parentText.includes('[READY]') ||
parent.classList.contains('prose') ||
parent.classList.contains('markdown')) {
container = parent;
}
parent = parent.parentElement;
}
msgs.push(container);
}
}
// Dedupliziere: Behalte nur die ÄUSSERSTEN (größten) Container
// (aber nicht zu groß - max 10000 Zeichen)
const unique = [];
for (const div of msgs) {
// Prüfe ob dieses Element schon in einem anderen enthalten ist
let isDuplicate = false;
for (const other of msgs) { for (const other of msgs) {
if (other !== div && other.contains(div)) { if (other !== elem && elem.contains(other)) {
// Dieses Element ist in einem anderen enthalten // Dieses Element enthält ein anderes - überspringe es
isDuplicate = true; dominated = true;
break; break;
} }
} }
if (!isDuplicate && !unique.includes(div)) {
if (!dominated) {
// Entferne Elemente die DIESES Element enthalten
for (let i = msgs.length - 1; i >= 0; i--) {
if (msgs[i].contains(elem)) {
// Das alte Element enthält uns - entferne es
msgs.splice(i, 1);
}
}
msgs.push(elem);
}
}
}
// Dedupliziere basierend auf identischem Text (manchmal gibt es Duplikate)
const seen = new Set();
const unique = [];
for (const div of msgs) {
const text = (div.innerText || '').trim();
// Nutze die ersten 100 Zeichen als Schlüssel
const key = text.substring(0, 100);
if (!seen.has(key)) {
seen.add(key);
unique.push(div); unique.push(div);
} }
} }
@ -887,17 +874,23 @@ class ClaudeChatInterface:
logger.debug(f"Überspringe User-Befehl (normalized): {text}") logger.debug(f"Überspringe User-Befehl (normalized): {text}")
continue continue
# Prüfe ob es wirklich eine Claude-Nachricht ist (muss mit "Claude sagt:" BEGINNEN) # Prüfe ob es wirklich eine Claude-Nachricht ist (muss "Claude sagt:" enthalten)
# WICHTIG: Manchmal wird der Chat-Titel (z.B. "Claude steuert...") mit
# erfasst - in dem Fall müssen wir den Text ab "Claude sagt:" extrahieren
if not text.startswith("Claude sagt:"): if not text.startswith("Claude sagt:"):
# Fallback: Prüfe ob "Claude sagt:" irgendwo am Anfang einer Zeile steht # Fallback: Prüfe ob "Claude sagt:" irgendwo im Text steht
lines = text.split('\n') # und extrahiere den Text ab dort
found_claude_line = False if "Claude sagt:" in text:
for line in lines[:5]: # Nur erste 5 Zeilen prüfen # Finde alle Vorkommen von "Claude sagt:" und extrahiere die Nachrichten
if line.strip().startswith("Claude sagt:"): import re
found_claude_line = True # Finde den Index des ersten "Claude sagt:"
break claude_sagt_idx = text.find("Claude sagt:")
if not found_claude_line: if claude_sagt_idx > 0:
logger.debug(f"Claude-Element {i} übersprungen: Beginnt nicht mit 'Claude sagt:'") # Schneide alles vor "Claude sagt:" ab (z.B. Chat-Titel)
text = text[claude_sagt_idx:]
logger.debug(f"Claude-Element {i}: Text gekürzt ab 'Claude sagt:' (vorher {len(text) + claude_sagt_idx} Zeichen)")
else:
logger.debug(f"Claude-Element {i} übersprungen: Enthält kein 'Claude sagt:'")
continue continue
# Filtere Sidebar/Navigation Elemente (beginnen oft mit "Neuer Chat") # Filtere Sidebar/Navigation Elemente (beginnen oft mit "Neuer Chat")