diff --git a/src/app/Http/Controllers/Api/AgentChatController.php b/src/app/Http/Controllers/Api/AgentChatController.php index 90e2e4a..b5509b9 100644 --- a/src/app/Http/Controllers/Api/AgentChatController.php +++ b/src/app/Http/Controllers/Api/AgentChatController.php @@ -175,10 +175,12 @@ class AgentChatController extends Controller } // Credits berechnen — Flat-Rate-Logik - // - Aktionen: tokenbasiert, nur bei Erfolg + // - Aktionen (inkl. _multi): tokenbasiert, nur bei Erfolg // - Chat (type = 'chat'): immer pauschal 5 Credits + // _multi hat kein 'type'-Key → würde sonst fälschlich als 'chat' gewertet $type = $parsed['type'] ?? 'chat'; - $isAction = $type !== 'chat'; + $isAction = ($type !== 'chat') || isset($parsed['_multi']); + $logType = isset($parsed['_multi']) ? 'multi' : $type; $shouldLog = true; if ($isAction) { @@ -199,7 +201,7 @@ class AgentChatController extends Controller if ($shouldLog) { // Input für Log bestimmen (wie im Web) - $logInput = match ($type) { + $logInput = match ($logType) { 'chat' => 'Konversation', 'event', 'event_update' => $parsed['data']['title'] ?? $request->message, 'note', 'note_update' => mb_substr($parsed['data']['content'] ?? $request->message, 0, 100), @@ -214,7 +216,7 @@ class AgentChatController extends Controller AgentLog::create([ 'user_id' => $user->id, - 'type' => $type, + 'type' => $logType, 'input' => $logInput, 'status' => $logStatus, 'output' => $actionResult['meta'] ?? $actionResult ?? null, @@ -245,7 +247,7 @@ class AgentChatController extends Controller $responseData = [ 'message' => $assistantMessage, 'action' => $actionResult, - 'type' => $parsed['type'] ?? 'chat', + 'type' => $logType, 'credits_used' => $credits, 'usage' => [ 'credits_used' => $user->monthly_usage, diff --git a/src/app/Models/Event.php b/src/app/Models/Event.php index 1280d32..cedc8ef 100644 --- a/src/app/Models/Event.php +++ b/src/app/Models/Event.php @@ -26,6 +26,8 @@ class Event extends Model 'google_event_id', 'recurrence', 'recurrence_end_date', + 'reminder_at', + 'reminder_sent', ]; protected $casts = [ @@ -38,6 +40,8 @@ class Event extends Model 'exceptions' => 'array', 'participants' => 'array', 'recurrence_end_date' => 'date:Y-m-d', + 'reminder_at' => 'datetime', + 'reminder_sent' => 'boolean', ]; protected static function boot() diff --git a/src/app/Services/AgentAIService.php b/src/app/Services/AgentAIService.php index 0add96e..0c23ab6 100644 --- a/src/app/Services/AgentAIService.php +++ b/src/app/Services/AgentAIService.php @@ -552,9 +552,16 @@ WICHTIG bei Terminabfragen: JSON-FORMATE: +EVENT vs TASK — ENTSCHEIDUNGSREGEL (SEHR WICHTIG): +→ EVENT: Termin, Meeting, Arzt, Zahnarzt, Friseur, Reifenwechsel, Sport, Treffen, "um X Uhr", externe Aktivität +→ TASK: "ich muss", "erledigen", "kaufen", "nicht vergessen", "To-Do", interne Aufgaben ohne konkreten externen Termin +→ Event MIT Erinnerung: IMMER event + reminder_at — NIEMALS als Task anlegen! + Beispiel: "Reifenwechsel 17 Uhr, erinnere mich morgen früh" → event mit datetime + reminder_at, kein task + EVENT: {"type": "event", "data": {"title": "str", "datetime": "YYYY-MM-DD HH:mm"}} {"type": "event", "data": {"title": "str", "datetime": "YYYY-MM-DD HH:mm", "notes": "str"}} +{"type": "event", "data": {"title": "str", "datetime": "YYYY-MM-DD HH:mm", "reminder_at": "YYYY-MM-DD HH:mm:ss"}} {"type": "event", "data": {"title": "str", "start": "YYYY-MM-DD HH:mm", "end": "YYYY-MM-DD HH:mm", "is_all_day": bool}} NOTE: @@ -583,8 +590,12 @@ Beispiele: Setze priority NUR auf "medium" wenn keine Dringlichkeit erkennbar ist. -TASK REMINDER — PFLICHT wenn User Zeitangabe macht: -Wenn User "erinnere mich in X Min/Std" oder "um HH:MM" oder "morgen früh" sagt: +EVENT REMINDER — für Termine mit Erinnerungswunsch: +Wenn User einen Termin + Erinnerung möchte → event mit reminder_at (UTC): +{"type": "event", "data": {"title": "Reifenwechsel", "datetime": "{{ now('Europe/Vienna')->setTime(17,0)->utc()->format('Y-m-d H:i') }}", "reminder_at": "{{ now('Europe/Vienna')->addDay()->setTime(7,0)->utc()->format('Y-m-d H:i:s') }}"}} + +TASK REMINDER — NUR für reine Aufgaben (kein externer Termin): +Wenn User "erinnere mich in X Min/Std" oder "um HH:MM" oder "morgen früh" sagt UND es ein internes To-Do ist: - reminder_at UND due_at MÜSSEN gesetzt werden - Zeiten IMMER in UTC (Format: YYYY-MM-DD HH:mm:ss) - due_at = reminder_at wenn kein anderes Datum diff --git a/src/app/Services/EventPlannerService.php b/src/app/Services/EventPlannerService.php index 3fee5b1..3262a91 100644 --- a/src/app/Services/EventPlannerService.php +++ b/src/app/Services/EventPlannerService.php @@ -134,6 +134,13 @@ class EventPlannerService $eventData['notes'] = $data['notes']; } + if (!empty($data['reminder_at'])) { + try { + $eventData['reminder_at'] = Carbon::parse($data['reminder_at'])->utc(); + $eventData['reminder_sent'] = false; + } catch (\Throwable) {} + } + $event = Event::create($eventData); #TODO Das mich später freischalten diff --git a/src/database/migrations/2026_04_19_054730_add_reminder_at_to_events_table.php b/src/database/migrations/2026_04_19_054730_add_reminder_at_to_events_table.php new file mode 100644 index 0000000..9a9c528 --- /dev/null +++ b/src/database/migrations/2026_04_19_054730_add_reminder_at_to_events_table.php @@ -0,0 +1,26 @@ +timestamp('reminder_at')->nullable()->after('reminders'); + $table->boolean('reminder_sent')->default(false)->after('reminder_at'); + }); + } + + public function down(): void + { + Schema::table('events', function (Blueprint $table) { + $table->dropColumn(['reminder_at', 'reminder_sent']); + }); + } +};