Fix: event vs task distinction, event reminder support, correct credit calculation

- AgentChatController: _multi hatte kein type-Key → wurde als 'chat' gewertet
  → nur 5 Credits statt Action-Credits. Fix: isset(_multi) erkennt Multi-Actions
- AgentAIService: EVENT vs TASK Entscheidungsregel + reminder_at für Events
  Event mit Erinnerung → immer event+reminder_at, niemals als Task anlegen
- EventPlannerService: reminder_at beim Event-Erstellen speichern (UTC)
- Event Model + Migration: reminder_at + reminder_sent Felder ergänzt

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
main
boban 2026-04-19 07:49:39 +02:00
parent e205186465
commit bcc1c0aac2
5 changed files with 57 additions and 7 deletions

View File

@ -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,

View File

@ -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()

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,26 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('events', function (Blueprint $table) {
$table->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']);
});
}
};