Fix: parseJson chat responses, force override for conflicts
- 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 <noreply@anthropic.com>
main
parent
7d50647f39
commit
89cb058e83
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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' => []];
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue