Warten auf Eingabefeld (CAPTCHA/Login) , [READY] nur in letzter Nachrich suchen,at 90 pictures auto new chat, configureabel via config
This commit is contained in:
parent
b830388d9f
commit
72008cf97a
|
|
@ -620,6 +620,8 @@ Erst dann starten die automatischen TICKs mit Bildern!"""
|
||||||
check_interval = hb_config.get("check_interval", 1)
|
check_interval = hb_config.get("check_interval", 1)
|
||||||
min_pause = hb_config.get("min_pause", 2)
|
min_pause = hb_config.get("min_pause", 2)
|
||||||
max_pause = hb_config.get("max_pause", 4)
|
max_pause = hb_config.get("max_pause", 4)
|
||||||
|
auto_new_chat = hb_config.get("auto_new_chat", True) # Auto-Neuer-Chat bei Bilder-Limit?
|
||||||
|
auto_new_chat_threshold = hb_config.get("auto_new_chat_threshold", 90) # Ab wieviel Bildern?
|
||||||
|
|
||||||
# Debug-Modus: Keine automatischen TICKs
|
# Debug-Modus: Keine automatischen TICKs
|
||||||
if not auto_tick:
|
if not auto_tick:
|
||||||
|
|
@ -744,10 +746,26 @@ Erst dann starten die automatischen TICKs mit Bildern!"""
|
||||||
image_uploaded = True
|
image_uploaded = True
|
||||||
uploaded_count = self.chat.get_images_uploaded_count()
|
uploaded_count = self.chat.get_images_uploaded_count()
|
||||||
|
|
||||||
if uploaded_count >= 95:
|
# ════════════════════════════════════════════════════════════
|
||||||
console.print(f"[bold red]⚠️ {uploaded_count}/100 Bilder! Drücke 'N' für neuen Chat![/bold red]")
|
# AUTO-NEUER-CHAT: Bei X+ Bildern automatisch neuen Chat!
|
||||||
elif uploaded_count >= 90:
|
# Nur wenn in config aktiviert (auto_new_chat: true)
|
||||||
console.print(f"[yellow]⚠️ {uploaded_count}/100 Bilder - Limit fast erreicht![/yellow]")
|
# ════════════════════════════════════════════════════════════
|
||||||
|
if uploaded_count >= auto_new_chat_threshold:
|
||||||
|
if auto_new_chat:
|
||||||
|
console.print(f"\n[bold yellow]⚠️ {uploaded_count}/100 Bilder - Starte automatisch neuen Chat![/bold yellow]")
|
||||||
|
logger.info(f"Auto-Neuer-Chat bei {uploaded_count} Bildern (Threshold: {auto_new_chat_threshold})")
|
||||||
|
|
||||||
|
# Neuen Chat starten (wie bei 'N' Taste)
|
||||||
|
self._start_new_chat_with_instructions()
|
||||||
|
|
||||||
|
# Heartbeat-Loop neu starten (continue springt zum Anfang)
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
# Auto-New-Chat deaktiviert - nur warnen
|
||||||
|
if uploaded_count == auto_new_chat_threshold:
|
||||||
|
console.print(f"\n[bold yellow]⚠️ {uploaded_count}/100 Bilder - Drücke 'N' für neuen Chat![/bold yellow]")
|
||||||
|
logger.warning(f"Bilder-Limit erreicht ({uploaded_count}), auto_new_chat ist deaktiviert")
|
||||||
|
|
||||||
elif uploaded_count % 10 == 0:
|
elif uploaded_count % 10 == 0:
|
||||||
console.print(f"[dim]📷 {uploaded_count} Bilder hochgeladen (Limit: 100)[/dim]")
|
console.print(f"[dim]📷 {uploaded_count} Bilder hochgeladen (Limit: 100)[/dim]")
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -298,6 +298,35 @@ class ClaudeChatInterface:
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def wait_for_input_field(self, timeout: int = 60) -> bool:
|
||||||
|
"""
|
||||||
|
Wartet bis das Chat-Eingabefeld verfügbar ist.
|
||||||
|
|
||||||
|
Nützlich nach CAPTCHA/Login wenn das UI noch lädt.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
timeout: Maximale Wartezeit in Sekunden
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
True wenn Eingabefeld gefunden, False bei Timeout
|
||||||
|
"""
|
||||||
|
logger.info(f"Warte auf Chat-Eingabefeld (max {timeout}s)...")
|
||||||
|
start_time = time.time()
|
||||||
|
|
||||||
|
while time.time() - start_time < timeout:
|
||||||
|
input_field = self._find_input_field()
|
||||||
|
if input_field:
|
||||||
|
try:
|
||||||
|
if input_field.is_displayed() and input_field.is_enabled():
|
||||||
|
logger.info("Chat-Eingabefeld bereit!")
|
||||||
|
return True
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
logger.warning(f"Timeout: Eingabefeld nach {timeout}s nicht gefunden")
|
||||||
|
return False
|
||||||
|
|
||||||
def send_message_with_delay(self, text: str, delay_before_send: int = 15) -> bool:
|
def send_message_with_delay(self, text: str, delay_before_send: int = 15) -> bool:
|
||||||
"""
|
"""
|
||||||
Sendet eine Nachricht mit Verzögerung vor dem Absenden.
|
Sendet eine Nachricht mit Verzögerung vor dem Absenden.
|
||||||
|
|
@ -306,6 +335,7 @@ class ClaudeChatInterface:
|
||||||
Zwischenablage/das Eingabefeld Zeit braucht um den Text zu verarbeiten.
|
Zwischenablage/das Eingabefeld Zeit braucht um den Text zu verarbeiten.
|
||||||
|
|
||||||
Ablauf:
|
Ablauf:
|
||||||
|
0. Warte bis Eingabefeld verfügbar (für CAPTCHA/Login-Fälle)
|
||||||
1. Text via JavaScript ins Eingabefeld einfügen (vermeidet Tastaturlayout-Probleme!)
|
1. Text via JavaScript ins Eingabefeld einfügen (vermeidet Tastaturlayout-Probleme!)
|
||||||
2. Warte delay_before_send Sekunden
|
2. Warte delay_before_send Sekunden
|
||||||
3. Send-Button klicken (mit Retry)
|
3. Send-Button klicken (mit Retry)
|
||||||
|
|
@ -318,6 +348,11 @@ class ClaudeChatInterface:
|
||||||
True wenn erfolgreich gesendet
|
True wenn erfolgreich gesendet
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
|
# WICHTIG: Warte auf Eingabefeld (CAPTCHA/Login kann dauern!)
|
||||||
|
if not self.wait_for_input_field(timeout=120):
|
||||||
|
logger.error("Eingabefeld nicht verfügbar nach 120s!")
|
||||||
|
return False
|
||||||
|
|
||||||
# Finde Eingabefeld
|
# Finde Eingabefeld
|
||||||
input_field = self._find_input_field()
|
input_field = self._find_input_field()
|
||||||
|
|
||||||
|
|
@ -966,8 +1001,8 @@ class ClaudeChatInterface:
|
||||||
"""
|
"""
|
||||||
Wartet bis Claude [READY] sendet.
|
Wartet bis Claude [READY] sendet.
|
||||||
|
|
||||||
Sucht nach [READY] das NICHT Teil des Instruktions-Textes ist.
|
WICHTIG: Prüft nur die LETZTE Claude-Nachricht!
|
||||||
Wir zählen wie oft [READY] vorkommt - wenn mehr als 1x, hat Claude geantwortet.
|
So werden alte [READY] im Chat-Verlauf ignoriert.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
timeout: Maximale Wartezeit in Sekunden
|
timeout: Maximale Wartezeit in Sekunden
|
||||||
|
|
@ -975,9 +1010,13 @@ class ClaudeChatInterface:
|
||||||
Returns:
|
Returns:
|
||||||
True wenn [READY] empfangen, False bei Timeout
|
True wenn [READY] empfangen, False bei Timeout
|
||||||
"""
|
"""
|
||||||
logger.info(f"Warte auf [READY] Signal (max {timeout}s)...")
|
logger.info(f"Warte auf [READY] Signal in letzter Claude-Nachricht (max {timeout}s)...")
|
||||||
start_time = time.time()
|
start_time = time.time()
|
||||||
|
|
||||||
|
# Merke die Anzahl der Claude-Nachrichten VOR dem Senden
|
||||||
|
initial_count = self._count_claude_messages()
|
||||||
|
logger.debug(f"Initiale Claude-Nachrichten: {initial_count}")
|
||||||
|
|
||||||
while time.time() - start_time < timeout:
|
while time.time() - start_time < timeout:
|
||||||
# Warte bis Claude fertig ist mit Tippen
|
# Warte bis Claude fertig ist mit Tippen
|
||||||
typing_wait_start = time.time()
|
typing_wait_start = time.time()
|
||||||
|
|
@ -988,24 +1027,16 @@ class ClaudeChatInterface:
|
||||||
logger.debug("Typing-Wait Timeout, prüfe trotzdem...")
|
logger.debug("Typing-Wait Timeout, prüfe trotzdem...")
|
||||||
break
|
break
|
||||||
|
|
||||||
# Suche [READY] im Seitentext via JavaScript
|
# Prüfe ob es eine NEUE Claude-Nachricht gibt
|
||||||
# Zähle wie oft [READY] vorkommt - 1x ist unsere Instruktion, 2x+ bedeutet Claude hat geantwortet
|
current_count = self._count_claude_messages()
|
||||||
try:
|
if current_count > initial_count:
|
||||||
ready_count = self.driver.execute_script("""
|
# Hole die letzte Claude-Nachricht
|
||||||
const text = document.body.innerText.toUpperCase();
|
last_msg = self.get_last_assistant_message()
|
||||||
const matches = text.match(/\\[READY\\]/g);
|
if last_msg and '[READY]' in last_msg.text.upper():
|
||||||
return matches ? matches.length : 0;
|
logger.info(f"[READY] in letzter Claude-Nachricht gefunden!")
|
||||||
""")
|
|
||||||
|
|
||||||
logger.debug(f"[READY] gefunden: {ready_count}x")
|
|
||||||
|
|
||||||
# Mehr als 1x = Claude hat auch [READY] geschrieben
|
|
||||||
if ready_count and ready_count >= 2:
|
|
||||||
logger.info(f"[READY] Signal gefunden! ({ready_count}x im Text)")
|
|
||||||
return True
|
return True
|
||||||
|
else:
|
||||||
except Exception as e:
|
logger.debug(f"Neue Nachricht aber kein [READY]: {last_msg.text[:50] if last_msg else 'None'}...")
|
||||||
logger.debug(f"JavaScript [READY] Suche fehlgeschlagen: {e}")
|
|
||||||
|
|
||||||
# Kurz warten bevor nächster Check
|
# Kurz warten bevor nächster Check
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
@ -1013,6 +1044,15 @@ class ClaudeChatInterface:
|
||||||
logger.warning(f"Timeout: Kein [READY] nach {timeout}s")
|
logger.warning(f"Timeout: Kein [READY] nach {timeout}s")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def _count_claude_messages(self) -> int:
|
||||||
|
"""Zählt die Anzahl der Claude-Nachrichten im Chat"""
|
||||||
|
try:
|
||||||
|
messages = self._get_all_messages()
|
||||||
|
return sum(1 for m in messages if m.is_from_assistant)
|
||||||
|
except Exception as e:
|
||||||
|
logger.debug(f"Fehler beim Zählen: {e}")
|
||||||
|
return 0
|
||||||
|
|
||||||
def take_screenshot(self, path: str = "screenshot.png"):
|
def take_screenshot(self, path: str = "screenshot.png"):
|
||||||
"""Macht einen Screenshot (für Debugging)"""
|
"""Macht einen Screenshot (für Debugging)"""
|
||||||
self.driver.save_screenshot(path)
|
self.driver.save_screenshot(path)
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,14 @@ heartbeat:
|
||||||
# Nach wie vielen Fehlern in Folge stoppen?
|
# Nach wie vielen Fehlern in Folge stoppen?
|
||||||
max_consecutive_errors: 5
|
max_consecutive_errors: 5
|
||||||
|
|
||||||
|
# Automatisch neuen Chat starten wenn Bilder-Limit erreicht?
|
||||||
|
# true = Bei 90+ Bildern automatisch neuen Chat starten
|
||||||
|
# false = Nur Warnung anzeigen, manuell mit 'N' neuen Chat starten
|
||||||
|
auto_new_chat: true
|
||||||
|
|
||||||
|
# Ab wie vielen Bildern neuen Chat starten (nur wenn auto_new_chat: true)
|
||||||
|
auto_new_chat_threshold: 90
|
||||||
|
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
# Text-to-Speech (Claudes Stimme)
|
# Text-to-Speech (Claudes Stimme)
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue