{
"tool_response": {
"type": "text",
"file": {
"filePath": "\/var\/www\/dev.campus.systemische-tools.de\/src\/Controller\/ChatController.php",
"content": " $content = $this->exportUseCase->exportAsMarkdown($uuid);\n\n if ($content === null) {\n $this->notFound('Session nicht gefunden');\n }\n\n $this->download($content, $filename, 'text\/markdown');\n }\n }\n\n \/**\n * Extract chat message parameters from POST and session.\n *\n * @return array{\n * question: string,\n * model: string,\n * collections: array<string>,\n * contextLimit: int,\n * authorProfileId: int,\n * systemPromptId: int,\n * structureId: int,\n * temperature: float,\n * maxTokens: int,\n * qualityCheck: bool\n * }\n *\/\n private function extractChatParams(\\Domain\\Entity\\ChatSession $session): array\n {\n $requestedModel = $_POST['model'] ?? $session->getModel();\n $model = $this->modelRegistry->isValid($requestedModel)\n ? $requestedModel\n : $this->modelRegistry->getDefaultChatModel();\n\n return [\n 'question' => trim($_POST['message'] ?? ''),\n 'model' => $model,\n 'collections' => $_POST['collections'] ?? $session->getCollections(),\n 'contextLimit' => (int) ($_POST['context_limit'] ?? $session->getContextLimit()),\n 'authorProfileId' => (int) ($_POST['author_profile_id'] ?? $session->getAuthorProfileId() ?? 0),\n 'systemPromptId' => (int) ($_POST['system_prompt_id'] ?? $session->getSystemPromptId() ?? 1),\n 'structureId' => (int) ($_POST['structure_id'] ?? 0),\n 'temperature' => (float) ($_POST['temperature'] ?? $session->getTemperature()),\n 'maxTokens' => (int) ($_POST['max_tokens'] ?? $session->getMaxTokens()),\n 'qualityCheck' => isset($_POST['quality_check']) && $_POST['quality_check'] === '1',\n ];\n }\n\n \/**\n * Update session settings if changed.\n *\n * @param array<string> $collections\n *\/\n private function updateSessionIfChanged(\n \\Domain\\Entity\\ChatSession $session,\n string $model,\n array $collections,\n int $contextLimit,\n int $authorProfileId,\n float $temperature,\n int $maxTokens\n ): void {\n if ($this->updateSessionUseCase->settingsHaveChanged($session, $model, $collections, $contextLimit, $authorProfileId, $temperature, $maxTokens)) {\n $this->updateSessionUseCase->updateSettings($session->getId() ?? 0, $model, $collections, $contextLimit, $authorProfileId, $temperature, $maxTokens);\n }\n }\n\n \/**\n * Validate collections compatibility.\n *\n * @param array<string> $collections\n * @return array{valid: bool, error: string|null}\n *\/\n private function validateCollections(array $collections): array\n {\n if (empty($collections)) {\n return ['valid' => true, 'error' => null];\n }\n\n $compatibility = $this->updateSessionUseCase->validateCollectionCompatibility($collections);\n\n return [\n 'valid' => $compatibility['valid'],\n 'error' => $compatibility['error'] ?? null,\n ];\n }\n\n \/**\n * Setup SSE stream headers and disable buffering.\n *\/\n private function setupSseStream(): void\n {\n header('Content-Type: text\/event-stream; charset=utf-8');\n header('Cache-Control: no-cache, no-store, must-revalidate');\n header('Pragma: no-cache');\n header('Connection: keep-alive');\n header('X-Accel-Buffering: no');\n header('Content-Encoding: none');\n\n if (function_exists('apache_setenv')) {\n apache_setenv('no-gzip', '1');\n }\n @ini_set('zlib.output_compression', '0');\n @ini_set('implicit_flush', '1');\n @ini_set('output_buffering', '0');\n\n while (ob_get_level()) {\n ob_end_clean();\n }\n ob_implicit_flush(true);\n\n \/\/ Send padding to force buffer flush\n echo ':' . str_repeat(' ', 4096) . \"\\n\\n\";\n flush();\n }\n\n \/**\n * Setup progress callback for SSE events.\n *\/\n private function setupProgressCallback(): void\n {\n $this->streamingUseCase->setProgressCallback(function (string $step, string $message, ?int $durationMs) {\n $timestamp = (new \\DateTime())->format('H:i:s.v');\n $data = [\n 'ts' => $timestamp,\n 'step' => $step,\n 'msg' => $message,\n 'ms' => $durationMs,\n ];\n echo \"event: progress\\n\";\n echo 'data: ' . json_encode($data, JSON_UNESCAPED_UNICODE) . \"\\n\\n\";\n echo ':' . str_repeat(' ', 4096) . \"\\n\";\n flush();\n });\n }\n\n \/**\n * Send streaming result as SSE event.\n *\/\n private function sendStreamResult(\\UseCases\\Chat\\ChatResponse $response, string $question, string $model): void\n {\n if ($response->hasError()) {\n $errorData = ['error' => $response->getError()];\n echo \"event: error\\n\";\n echo 'data: ' . json_encode($errorData, JSON_UNESCAPED_UNICODE) . \"\\n\\n\";\n } else {\n $result = $response->toArray();\n $formattedAnswer = $this->formatter->formatAnswer($result['answer'] ?? '');\n\n ob_start();\n $this->view('chat.partials.response', [\n 'question' => $question,\n 'result' => $result,\n 'model' => $model,\n 'formattedAnswer' => $formattedAnswer,\n ]);\n $html = ob_get_clean();\n\n $doneData = ['html' => $html];\n echo \"event: done\\n\";\n echo 'data: ' . json_encode($doneData, JSON_UNESCAPED_UNICODE) . \"\\n\\n\";\n }\n\n @ob_flush();\n flush();\n }\n}\n",
"numLines": 167,
"startLine": 300,
"totalLines": 466
}
}
}