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

@@ -11,12 +11,17 @@ import {
import { ApiClient } from "./ApiClient";
interface ConfirmEventRequest {
proposalId: string;
action: EventAction;
event?: CreateEventDTO;
eventId?: string;
updates?: UpdateEventDTO;
}
interface RejectEventRequest {
proposalId: string;
}
export const ChatService = {
sendMessage: async (data: SendMessageDTO): Promise<ChatResponse> => {
return ApiClient.post<ChatResponse>("/chat/message", data);
@@ -25,12 +30,19 @@ export const ChatService = {
confirmEvent: async (
conversationId: string,
messageId: string,
proposalId: string,
action: EventAction,
event?: CreateEventDTO,
eventId?: string,
updates?: UpdateEventDTO,
): Promise<ChatResponse> => {
const body: ConfirmEventRequest = { action, event, eventId, updates };
const body: ConfirmEventRequest = {
proposalId,
action,
event,
eventId,
updates,
};
return ApiClient.post<ChatResponse>(
`/chat/confirm/${conversationId}/${messageId}`,
body,
@@ -40,9 +52,12 @@ export const ChatService = {
rejectEvent: async (
conversationId: string,
messageId: string,
proposalId: string,
): Promise<ChatResponse> => {
const body: RejectEventRequest = { proposalId };
return ApiClient.post<ChatResponse>(
`/chat/reject/${conversationId}/${messageId}`,
body,
);
},