feat: support multiple event proposals in single AI response

- Change proposedChange to proposedChanges array in ChatMessage type
- Add unique id and individual respondedAction to each ProposedEventChange
- Implement arrow navigation UI for multiple proposals with "Event X von Y" counter
- Add updateProposalResponse() method for per-proposal confirm/reject tracking
- GPTAdapter now collects multiple tool call results into proposals array
- Add RRULE documentation to system prompt (separate events for different times)
- Fix RRULE parsing to strip RRULE: prefix if present
- Add log summarization for large args (conversationHistory, existingEvents)
- Keep proposedChanges logged in full for debugging AI issues
This commit is contained in:
2026-01-10 23:30:32 +01:00
parent 8efe6c304e
commit e6b9dd9d34
18 changed files with 533 additions and 158 deletions

View File

@@ -28,10 +28,33 @@ Wichtige Regeln:
- Wenn der Benutzer einen Termin erstellen will, nutze proposeCreateEvent
- Wenn der Benutzer einen Termin ändern will, nutze proposeUpdateEvent mit der Event-ID
- Wenn der Benutzer einen Termin löschen will, nutze proposeDeleteEvent mit der Event-ID
- Du kannst NUR EINEN Event-Vorschlag pro Antwort machen
- Du kannst mehrere Event-Vorschläge in einer Antwort machen (z.B. für mehrere Termine auf einmal)
- Wenn der Benutzer nach seinen Terminen fragt, nutze die unten stehende Liste
- Nutze searchEvents um nach Terminen zu suchen, wenn du die genaue ID brauchst
WICHTIG - Tool-Verwendung:
- Du MUSST die proposeCreateEvent/proposeUpdateEvent/proposeDeleteEvent Tools verwenden, um Termine vorzuschlagen!
- Sage NIEMALS einfach nur "ich habe einen Termin erstellt" ohne das Tool zu verwenden
- Die Tools erzeugen Karten, die dem Benutzer angezeigt werden - ohne Tool-Aufruf sieht er nichts
WICHTIG - Wiederkehrende Termine (RRULE):
- Ein wiederkehrendes Event hat EINE FESTE Start- und Endzeit
- RRULE bestimmt NUR an welchen Tagen das Event wiederholt wird, NICHT unterschiedliche Uhrzeiten pro Tag!
- Wenn der Benutzer UNTERSCHIEDLICHE ZEITEN an verschiedenen Tagen will, MUSST du SEPARATE Events erstellen
- Beispiel: "Arbeit Mo+Do 9-17:30, Fr 9-13" → ZWEI Events:
1. "Arbeit" Mo+Do 9:00-17:30 (RRULE mit BYDAY=MO,TH)
2. "Arbeit" Fr 9:00-13:00 (RRULE mit BYDAY=FR)
- Nutze NIEMALS BYHOUR/BYMINUTE in RRULE - diese überschreiben die Startzeit nicht wie erwartet!
- Gültige RRULE-Optionen: FREQ (DAILY/WEEKLY/MONTHLY/YEARLY), BYDAY (MO,TU,WE,TH,FR,SA,SU), INTERVAL, COUNT, UNTIL
WICHTIG - Antwortformat:
- Halte deine Textantworten SEHR KURZ (1-2 Sätze maximal)
- Die Event-Details (Titel, Datum, Uhrzeit, Beschreibung) werden dem Benutzer automatisch in separaten Karten angezeigt
- Wiederhole NIEMALS die Event-Details im Text! Der Benutzer sieht sie bereits in den Karten
- Gute Beispiele: "Alles klar!" oder "Hier sind deine Termine:"
- Schlechte Beispiele: Lange Listen mit allen Terminen und ihren Details im Text
- Bei Rückfragen oder wenn keine Termine erstellt werden, kannst du ausführlicher antworten
Existierende Termine des Benutzers:
${eventsText}`;
}

View File

@@ -7,12 +7,17 @@ import {
import { AIContext } from "../../services/interfaces";
import { formatDate, formatTime, formatDateTime } from "./eventFormatter";
/**
* Proposed change without ID - ID is added by GPTAdapter when collecting proposals
*/
type ToolProposedChange = Omit<ProposedEventChange, "id" | "respondedAction">;
/**
* Result of executing a tool call.
*/
export interface ToolResult {
content: string;
proposedChange?: ProposedEventChange;
proposedChange?: ToolProposedChange;
}
/**