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
text = re.sub(r'\[TICK\]', '', text)
text = re.sub(r'\[START\]', '', text)
text = re.sub(r'\[READY\]', '', text) # [READY] nicht vorlesen
# Fahrbefehle entfernen
text = re.sub(r'\[(FORWARD|BACKWARD|LEFT|RIGHT|STOP)\]', '', text)

View File

@ -679,16 +679,16 @@ class ClaudeChatInterface:
if not claude_elements:
try:
# Claude.ai 2024/2025 nutzt oft conversation-turn Divs
# WICHTIG: Wir suchen den CONTAINER der die gesamte Claude-Nachricht enthält,
# nicht nur das Element mit "Claude sagt:" - denn [READY] kann in einem
# separaten Child-Element stehen!
# WICHTIG: Wir suchen EINZELNE Nachrichten, nicht den ganzen Chat!
# Jede "Claude sagt:" Nachricht soll ein separates Element sein.
found = self.driver.execute_script("""
const msgs = [];
// Strategie: Finde Elemente mit "Claude sagt:" und dann den
// ÜBERGEORDNETEN Container der die vollständige Nachricht enthält
const allDivs = document.querySelectorAll('div, p, span');
for (const elem of allDivs) {
// Strategie 1: Suche nach einzelnen Absätzen/Divs die MIT "Claude sagt:" beginnen
// NICHT nach Containern die den ganzen Chat enthalten!
const allElements = document.querySelectorAll('p, div, span');
for (const elem of allElements) {
// Überspringe wenn es ein user-message ist
if (elem.getAttribute('data-testid') === 'user-message') continue;
if (elem.closest('[data-testid="user-message"]')) continue;
@ -702,55 +702,42 @@ class ClaudeChatInterface:
// Hole den direkten Text-Inhalt
const text = (elem.innerText || '').trim();
// Text muss mit "Claude sagt:" BEGINNEN
if (text.startsWith('Claude sagt:') && text.length > 20 && text.length < 10000) {
// Suche nach dem übergeordneten Container (z.B. prose-Container)
// der auch [READY] enthalten könnte
let container = elem;
let parent = elem.parentElement;
// 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;
// STRENG: Text muss EXAKT mit "Claude sagt:" beginnen
// UND darf nicht den ganzen Chat sein (max 3000 Zeichen für eine Nachricht)
if (text.startsWith('Claude sagt:') && text.length > 20 && text.length < 3000) {
// Prüfe ob dieses Element nicht schon in einem anderen enthalten ist
// (wir wollen das KLEINSTE passende Element)
let dominated = false;
for (const other of msgs) {
if (other !== elem && elem.contains(other)) {
// Dieses Element enthält ein anderes - überspringe es
dominated = true;
break;
}
parent = parent.parentElement;
}
msgs.push(container);
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: Behalte nur die ÄUSSERSTEN (größten) Container
// (aber nicht zu groß - max 10000 Zeichen)
// Dedupliziere basierend auf identischem Text (manchmal gibt es Duplikate)
const seen = new Set();
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) {
if (other !== div && other.contains(div)) {
// Dieses Element ist in einem anderen enthalten
isDuplicate = true;
break;
}
}
if (!isDuplicate && !unique.includes(div)) {
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);
}
}
@ -887,17 +874,23 @@ class ClaudeChatInterface:
logger.debug(f"Überspringe User-Befehl (normalized): {text}")
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:"):
# Fallback: Prüfe ob "Claude sagt:" irgendwo am Anfang einer Zeile steht
lines = text.split('\n')
found_claude_line = False
for line in lines[:5]: # Nur erste 5 Zeilen prüfen
if line.strip().startswith("Claude sagt:"):
found_claude_line = True
break
if not found_claude_line:
logger.debug(f"Claude-Element {i} übersprungen: Beginnt nicht mit 'Claude sagt:'")
# Fallback: Prüfe ob "Claude sagt:" irgendwo im Text steht
# und extrahiere den Text ab dort
if "Claude sagt:" in text:
# Finde alle Vorkommen von "Claude sagt:" und extrahiere die Nachrichten
import re
# Finde den Index des ersten "Claude sagt:"
claude_sagt_idx = text.find("Claude sagt:")
if claude_sagt_idx > 0:
# 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
# Filtere Sidebar/Navigation Elemente (beginnen oft mit "Neuer Chat")