tts debug hinzugefügt
This commit is contained in:
parent
ccfbd5b8ec
commit
98c5190456
|
|
@ -650,9 +650,12 @@ Erst dann starten die automatischen TICKs mit Bildern!"""
|
||||||
if len(speech_text) > 200:
|
if len(speech_text) > 200:
|
||||||
console.print(f"[dim]...({len(speech_text)} Zeichen)[/dim]")
|
console.print(f"[dim]...({len(speech_text)} Zeichen)[/dim]")
|
||||||
|
|
||||||
|
# Mit "Claude sagt:" Prefix vorlesen (analog zu "Stefan sagt:")
|
||||||
|
tts_text = f"Claude sagt: {speech_text}"
|
||||||
|
|
||||||
# Vorlesen
|
# Vorlesen
|
||||||
logger.info(f"TTS: Spreche {len(speech_text)} Zeichen...")
|
logger.info(f"TTS: Spreche {len(tts_text)} Zeichen...")
|
||||||
self.tts.speak(speech_text)
|
self.tts.speak(tts_text)
|
||||||
self.stats.messages_spoken += 1
|
self.stats.messages_spoken += 1
|
||||||
logger.debug("TTS: Sprechen beendet")
|
logger.debug("TTS: Sprechen beendet")
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -533,56 +533,118 @@ class ClaudeChatInterface:
|
||||||
# Versuche verschiedene Selektoren
|
# Versuche verschiedene Selektoren
|
||||||
elements = []
|
elements = []
|
||||||
|
|
||||||
# Methode 1: Nach data-is-streaming Attribut
|
# Claude.ai spezifische Selektoren (2024/2025)
|
||||||
try:
|
message_selectors = [
|
||||||
elements = self.driver.find_elements(
|
# Neuere Claude.ai Versionen
|
||||||
By.CSS_SELECTOR,
|
"[data-testid='user-message']",
|
||||||
"div[data-is-streaming='false']"
|
"[data-testid='assistant-message']",
|
||||||
)
|
# Ältere Varianten
|
||||||
except:
|
"div[data-is-streaming='false']",
|
||||||
pass
|
# Container für Nachrichten-Inhalt
|
||||||
|
".font-claude-message",
|
||||||
|
".prose",
|
||||||
|
# Generische Fallbacks
|
||||||
|
"div[class*='message']",
|
||||||
|
"div[class*='Message']",
|
||||||
|
]
|
||||||
|
|
||||||
# Methode 2: Generischer Message-Selektor
|
for selector in message_selectors:
|
||||||
|
try:
|
||||||
|
found = self.driver.find_elements(By.CSS_SELECTOR, selector)
|
||||||
|
if found:
|
||||||
|
logger.debug(f"Selektor '{selector}' fand {len(found)} Elemente")
|
||||||
|
if not elements or len(found) > len(elements):
|
||||||
|
elements = found
|
||||||
|
except Exception as e:
|
||||||
|
logger.debug(f"Selektor '{selector}' fehlgeschlagen: {e}")
|
||||||
|
|
||||||
|
logger.debug(f"Gesamt gefundene Nachrichten-Elemente: {len(elements)}")
|
||||||
|
|
||||||
|
# Wenn immer noch nichts gefunden, versuche via JavaScript
|
||||||
if not elements:
|
if not elements:
|
||||||
try:
|
try:
|
||||||
elements = self.driver.find_elements(
|
elements = self.driver.execute_script("""
|
||||||
By.CSS_SELECTOR,
|
// Suche nach Nachrichten-Containern
|
||||||
self.SELECTORS["message_any"]
|
const msgs = [];
|
||||||
)
|
|
||||||
except:
|
// Methode 1: data-testid
|
||||||
pass
|
document.querySelectorAll('[data-testid*="message"]').forEach(e => msgs.push(e));
|
||||||
|
|
||||||
|
// Methode 2: Prose-Container (Markdown-Inhalt)
|
||||||
|
if (msgs.length === 0) {
|
||||||
|
document.querySelectorAll('.prose').forEach(e => msgs.push(e));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Methode 3: Alle großen Text-Container im Hauptbereich
|
||||||
|
if (msgs.length === 0) {
|
||||||
|
document.querySelectorAll('main div').forEach(e => {
|
||||||
|
if (e.innerText && e.innerText.length > 50 && e.children.length < 10) {
|
||||||
|
msgs.push(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return msgs;
|
||||||
|
""") or []
|
||||||
|
logger.debug(f"JavaScript fand {len(elements)} Nachrichten")
|
||||||
|
except Exception as e:
|
||||||
|
logger.debug(f"JavaScript-Suche fehlgeschlagen: {e}")
|
||||||
|
|
||||||
for i, elem in enumerate(elements):
|
for i, elem in enumerate(elements):
|
||||||
try:
|
try:
|
||||||
text = elem.text.strip()
|
text = elem.text.strip()
|
||||||
if not text:
|
if not text or len(text) < 5:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Bestimme ob Human oder Assistant
|
# Bestimme ob Human oder Assistant mit mehreren Methoden
|
||||||
# Mehrere Methoden probieren:
|
|
||||||
class_name = elem.get_attribute("class") or ""
|
class_name = elem.get_attribute("class") or ""
|
||||||
|
data_testid = elem.get_attribute("data-testid") or ""
|
||||||
data_role = elem.get_attribute("data-role") or ""
|
data_role = elem.get_attribute("data-role") or ""
|
||||||
outer_html = ""
|
|
||||||
|
# Prüfe Parent-Elemente auf Hinweise
|
||||||
|
parent_hints = ""
|
||||||
try:
|
try:
|
||||||
# Prüfe Parent-Element auf Hinweise
|
|
||||||
parent = elem.find_element(By.XPATH, "..")
|
parent = elem.find_element(By.XPATH, "..")
|
||||||
parent_class = parent.get_attribute("class") or ""
|
parent_class = parent.get_attribute("class") or ""
|
||||||
outer_html = parent_class
|
parent_testid = parent.get_attribute("data-testid") or ""
|
||||||
|
grandparent = parent.find_element(By.XPATH, "..")
|
||||||
|
grandparent_class = grandparent.get_attribute("class") or ""
|
||||||
|
parent_hints = f"{parent_class} {parent_testid} {grandparent_class}"
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# Kombiniere alle Hinweise
|
# Kombiniere alle Hinweise
|
||||||
all_hints = (class_name + " " + data_role + " " + outer_html).lower()
|
all_hints = (class_name + " " + data_testid + " " + data_role + " " + parent_hints).lower()
|
||||||
|
|
||||||
|
# Prüfe explizit auf "user" oder "human" für User-Nachrichten
|
||||||
|
is_human = (
|
||||||
|
"user" in all_hints or
|
||||||
|
"human" in all_hints or
|
||||||
|
"user-message" in data_testid
|
||||||
|
)
|
||||||
|
|
||||||
is_assistant = (
|
is_assistant = (
|
||||||
"assistant" in all_hints or
|
"assistant" in all_hints or
|
||||||
"claude" in all_hints or
|
"claude" in all_hints or
|
||||||
"ai-message" in all_hints or
|
"ai-message" in all_hints or
|
||||||
"response" in all_hints or
|
"assistant-message" in data_testid or
|
||||||
# Claude.ai spezifisch: Nachrichten ohne "human" sind von Claude
|
"response" in all_hints
|
||||||
("message" in all_hints and "human" not in all_hints and "user" not in all_hints)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Wenn weder user noch assistant explizit, nutze Heuristik
|
||||||
|
if not is_human and not is_assistant:
|
||||||
|
# Prüfe ob Text typische User-Marker hat
|
||||||
|
if text.startswith("[TICK]") or text.startswith("[START]") or "Stefan sagt:" in text:
|
||||||
|
is_human = True
|
||||||
|
else:
|
||||||
|
# Fallback: Nachrichten ohne User-Marker sind von Claude
|
||||||
|
is_assistant = True
|
||||||
|
|
||||||
|
# Final: is_assistant ist True wenn nicht explizit Human
|
||||||
|
final_is_assistant = is_assistant and not is_human
|
||||||
|
|
||||||
|
logger.debug(f"Nachricht {i}: is_human={is_human}, is_assistant={is_assistant}, final={final_is_assistant}, hints='{all_hints[:80]}...', text='{text[:40]}...'")
|
||||||
|
|
||||||
# Generiere ID
|
# Generiere ID
|
||||||
msg_id = elem.get_attribute("data-message-id")
|
msg_id = elem.get_attribute("data-message-id")
|
||||||
if not msg_id:
|
if not msg_id:
|
||||||
|
|
@ -591,7 +653,7 @@ class ClaudeChatInterface:
|
||||||
messages.append(ChatMessage(
|
messages.append(ChatMessage(
|
||||||
id=msg_id,
|
id=msg_id,
|
||||||
text=text,
|
text=text,
|
||||||
is_from_assistant=is_assistant,
|
is_from_assistant=final_is_assistant,
|
||||||
timestamp=time.time()
|
timestamp=time.time()
|
||||||
))
|
))
|
||||||
|
|
||||||
|
|
@ -599,6 +661,8 @@ class ClaudeChatInterface:
|
||||||
logger.debug(f"Fehler bei Nachricht {i}: {e}")
|
logger.debug(f"Fehler bei Nachricht {i}: {e}")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
logger.debug(f"Parsed {len(messages)} Nachrichten, davon {sum(1 for m in messages if m.is_from_assistant)} von Claude")
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Fehler beim Lesen der Nachrichten: {e}")
|
logger.error(f"Fehler beim Lesen der Nachrichten: {e}")
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue