createSessionUseCase->createSession(); header('Location: /chat/' . $uuid); exit; } public function show(string $uuid): void { $session = $this->getSessionUseCase->getSession($uuid); if ($session === null) { header('Location: /chat'); exit; } // Convert entities to arrays for views $messages = $this->getSessionUseCase->getMessages($session->getId() ?? 0); $messagesArray = array_map(fn ($m) => $m->toArray(), $messages); $this->view('chat.index', [ 'title' => $session->getTitle() ?? 'KI-Chat', 'session' => ChatSessionFactory::toArray($session), 'messages' => $messagesArray, 'sessions' => $this->getSessionUseCase->getAllSessionsWithStats(), 'authorProfiles' => $this->getSessionUseCase->getAuthorProfiles(), 'systemPrompts' => $this->getSessionUseCase->getSystemPrompts(), 'outputStructures' => $this->getSessionUseCase->getOutputStructures(), 'collections' => $this->getSessionUseCase->getAvailableCollections(), 'models' => $this->modelRegistry->getChatModels(), 'defaultModel' => $this->modelRegistry->getDefaultChatModel(), ]); } public function sessionList(): void { $this->view('chat.partials.session-list', [ 'sessions' => $this->getSessionUseCase->getAllSessionsWithStats(), 'currentUuid' => $this->getString('current') ?: null, ]); } public function message(string $uuid): void { $session = $this->getSessionUseCase->getSession($uuid); if ($session === null) { $this->view('chat.partials.error', ['error' => 'Session nicht gefunden.']); return; } $sessionId = $session->getId() ?? 0; $question = trim($_POST['message'] ?? ''); $requestedModel = $_POST['model'] ?? $session->getModel(); $model = $this->modelRegistry->isValid($requestedModel) ? $requestedModel : $this->modelRegistry->getDefaultChatModel(); $sessionCollections = $session->getCollections(); $collections = $_POST['collections'] ?? $sessionCollections; $contextLimit = (int) ($_POST['context_limit'] ?? $session->getContextLimit()); $authorProfileId = (int) ($_POST['author_profile_id'] ?? $session->getAuthorProfileId() ?? 0); $systemPromptId = (int) ($_POST['system_prompt_id'] ?? $session->getSystemPromptId() ?? 1); $structureId = (int) ($_POST['structure_id'] ?? 0); $temperature = (float) ($_POST['temperature'] ?? $session->getTemperature()); $maxTokens = (int) ($_POST['max_tokens'] ?? $session->getMaxTokens()); if ($this->updateSessionUseCase->settingsHaveChanged($session, $model, $collections, $contextLimit, $authorProfileId, $temperature, $maxTokens)) { $this->updateSessionUseCase->updateSettings($sessionId, $model, $collections, $contextLimit, $authorProfileId, $temperature, $maxTokens); } if ($question === '') { $this->view('chat.partials.error', ['error' => 'Bitte gib eine Frage ein.']); return; } if (!empty($collections)) { $compatibility = $this->updateSessionUseCase->validateCollectionCompatibility($collections); if (!$compatibility['valid']) { $this->view('chat.partials.error', [ 'error' => 'Collection-Fehler: ' . $compatibility['error'], 'details' => 'Bitte wähle nur Collections mit gleichem Embedding-Modell.', ]); return; } } $qualityCheck = isset($_POST['quality_check']) && $_POST['quality_check'] === '1'; $response = $this->messageUseCase->execute( sessionUuid: $uuid, message: $question, model: $model, collections: $collections, contextLimit: $contextLimit, authorProfileId: $authorProfileId, systemPromptId: $systemPromptId, temperature: $temperature, maxTokens: $maxTokens, structureId: $structureId, qualityCheck: $qualityCheck ); if ($response->hasError()) { $this->view('chat.partials.error', ['error' => $response->getError()]); return; } $result = $response->toArray(); $this->view('chat.partials.response', [ 'question' => $question, 'result' => $result, 'model' => $model, 'formattedAnswer' => $this->formatter->formatAnswer($result['answer'] ?? ''), ]); } public function updateTitle(string $uuid): void { $session = $this->sessionsUseCase->getSession($uuid); if ($session === null) { $this->notFound('Session nicht gefunden'); } $title = $this->sessionsUseCase->updateTitle($session->getId() ?? 0, $_POST['title'] ?? ''); $this->html(htmlspecialchars($title)); } public function systemPrompt(string $uuid): void { $session = $this->sessionsUseCase->getSession($uuid); if ($session === null) { $this->notFound('Session nicht gefunden'); } $result = $this->sessionsUseCase->updateSystemPrompt($session->getId() ?? 0, $_POST['system_prompt'] ?? ''); $this->view('chat.partials.success', ['message' => $result->message]); } public function getSystemPrompt(string $uuid): void { $session = $this->sessionsUseCase->getSession($uuid); if ($session === null) { $this->notFound('Session nicht gefunden'); } $this->view('chat.partials.system-prompt-modal', [ 'session' => ChatSessionFactory::toArray($session), 'currentPrompt' => $session->getSystemPrompt() ?? '', 'defaultPrompt' => $this->sessionsUseCase->getDefaultSystemPrompt(), ]); } public function delete(string $uuid): void { $session = $this->sessionsUseCase->getSession($uuid); if ($session !== null) { $this->sessionsUseCase->deleteSession($session->getId() ?? 0); } $this->htmxRedirect('/chat'); } public function export(string $uuid): void { $format = $this->getString('format') ?: 'markdown'; $filename = $this->exportUseCase->generateFilename($uuid, $format); if ($format === 'json') { $data = $this->exportUseCase->exportAsJson($uuid); if ($data === null) { $this->notFound('Session nicht gefunden'); } $content = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); $this->download($content, $filename, 'application/json'); } else { $content = $this->exportUseCase->exportAsMarkdown($uuid); if ($content === null) { $this->notFound('Session nicht gefunden'); } $this->download($content, $filename, 'text/markdown'); } } }