From 89cb058e839bad1aa67ff8ee5022296dbdda2d05 Mon Sep 17 00:00:00 2001 From: boban Date: Sun, 19 Apr 2026 08:22:52 +0200 Subject: [PATCH] Fix: parseJson chat responses, force override for conflicts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - parseJson: plain text (kein { oder [) → type=chat statt type=unknown Behebt WARNING für normale Chat-Antworten wie "Alles klar! [END]" - AgentAIService Prompt: Regel 12 — Konflikt-Handling mit force:true erklärt AI fragt nach Überschneidung und sendet force:true wenn User bestätigt - AgentActionService: Duplikat-Check bei force=true überspringen damit erzwungene Events auch bei gleichem Titel+Datum gespeichert werden Co-Authored-By: Claude Sonnet 4.6 --- src/app/Services/AgentAIService.php | 10 ++++++++++ src/app/Services/AgentActionService.php | 6 ++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/app/Services/AgentAIService.php b/src/app/Services/AgentAIService.php index c5c3bd6..7444ae1 100644 --- a/src/app/Services/AgentAIService.php +++ b/src/app/Services/AgentAIService.php @@ -549,6 +549,8 @@ REGELN: 9. Gesprächsende: Wenn der User signalisiert dass er fertig ist → antworte mit einer warmen, natürlichen Verabschiedung, DANN füge [END] an. Beispiele: "Super, dann bis später! Meld dich einfach wenn du was brauchst. [END]", "Alles klar, schönen Tag noch! [END]", "Passt, viel Spaß heute! [END]". NICHT: "Okay, [END]" oder nur "Bis dann, [END]" 10. Unsicher → nachfragen. Nichts erstellen ohne klare Absicht. 11. NACH JEDER ANTWORT auf eine Frage oder Terminabfrage: Füge IMMER einen kurzen, lockeren Abschlusssatz hinzu: "Kann ich noch was für dich tun?", "Sonst noch was?", "Brauchst du noch was?". Ausnahme: Wenn der User fertig ist → [END] verwenden (Regel 9). Jede Antwort endet entweder mit einer Folgefrage ODER mit [END]. +12. KONFLIKT-HANDLING: Wenn das Backend meldet dass ein Termin sich mit einem anderen überschneidet, frage den User: "Der Termin überschneidet sich mit [Termintitel]. Soll ich ihn trotzdem eintragen?" Wenn der User ja/trotzdem/egal/bitte/genau sagt → sende dasselbe Event nochmal MIT "force": true im data-Objekt: +{"type": "event", "data": {"title": "Volleyball", "datetime": "2026-04-19 14:00", "force": true}} Datum: TT.MM(.JJJJ), "heute"=heute, "morgen"=+1. Kein Datum→heute. Titel: max 5-7 Wörter, kein Datum. WICHTIG bei Terminabfragen: @@ -686,6 +688,14 @@ PROMPT; $json = json_decode($cleaned, true); if ($json === null) { + // Kein gültiges JSON — wenn kein { oder [ am Anfang → plain-text Chat-Antwort + $isJson = str_starts_with($cleaned, '{') || str_starts_with($cleaned, '['); + if (!$isJson) { + return [ + 'type' => 'chat', + 'data' => ['message' => $cleaned], + ]; + } return self::fallback(); } diff --git a/src/app/Services/AgentActionService.php b/src/app/Services/AgentActionService.php index 53fa7e8..7baf8a5 100644 --- a/src/app/Services/AgentActionService.php +++ b/src/app/Services/AgentActionService.php @@ -50,7 +50,8 @@ class AgentActionService if (!empty($data['start']) && !empty($data['end'])) { $title = $data['title'] ?? 'Termin'; $dateStr = Carbon::parse($data['start'])->toDateString(); - if (Event::where('user_id', $user->id)->where('title', $title)->whereDate('starts_at', $dateStr)->exists()) { + $force = !empty($data['force']); + if (!$force && Event::where('user_id', $user->id)->where('title', $title)->whereDate('starts_at', $dateStr)->exists()) { return ['status' => 'failed', 'message' => "Termin \"{$title}\" existiert an diesem Tag bereits.", 'meta' => []]; } @@ -74,7 +75,8 @@ class AgentActionService if (!empty($data['datetime'])) { $title = $data['title'] ?? 'Termin'; $dateStr = Carbon::parse($data['datetime'])->toDateString(); - if (Event::where('user_id', $user->id)->where('title', $title)->whereDate('starts_at', $dateStr)->exists()) { + $force = !empty($data['force']); + if (!$force && Event::where('user_id', $user->id)->where('title', $title)->whereDate('starts_at', $dateStr)->exists()) { return ['status' => 'failed', 'message' => "Termin \"{$title}\" existiert an diesem Tag bereits.", 'meta' => []]; }