Protokoll #29128

ID29128
Zeitstempel2025-12-29 00:13:01.175337
Clientroot
IP145.224.72.140
Modellclaude-sonnet-4-20250514
Statuscompleted
Tokens6,548 (Input: 1,437, Output: 5,111)
Dauer116 ms
Request-Zeit2025-12-29 00:13:01.175337
Response-Zeit2025-12-29 00:13:01.291059

Request

{
    "event": "PreToolUse",
    "tool_name": "Edit",
    "tool_input": {
        "file_path": "\/var\/www\/dev.campus.systemische-tools.de\/src\/Controller\/ChatController.php",
        "old_string": "    public function export(string $uuid): void\n    {\n        $format = $this->getString('format') ?: 'markdown';\n        $filename = $this->exportUseCase->generateFilename($uuid, $format);\n\n        if ($format === 'json') {\n            $data = $this->exportUseCase->exportAsJson($uuid);\n\n            if ($data === null) {\n                $this->notFound('Session nicht gefunden');\n            }\n\n            $content = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);\n            $this->download($content, $filename, 'application\/json');\n        } else {\n            $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}",
        "new_string": "    public function export(string $uuid): void\n    {\n        $format = $this->getString('format') ?: 'markdown';\n        $filename = $this->exportUseCase->generateFilename($uuid, $format);\n\n        if ($format === 'json') {\n            $data = $this->exportUseCase->exportAsJson($uuid);\n\n            if ($data === null) {\n                $this->notFound('Session nicht gefunden');\n            }\n\n            $content = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);\n            $this->download($content, $filename, 'application\/json');\n        } else {\n            $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}"
    }
}

Response

{
    "tool_response": {
        "filePath": "\/var\/www\/dev.campus.systemische-tools.de\/src\/Controller\/ChatController.php",
        "oldString": "    public function export(string $uuid): void\n    {\n        $format = $this->getString('format') ?: 'markdown';\n        $filename = $this->exportUseCase->generateFilename($uuid, $format);\n\n        if ($format === 'json') {\n            $data = $this->exportUseCase->exportAsJson($uuid);\n\n            if ($data === null) {\n                $this->notFound('Session nicht gefunden');\n            }\n\n            $content = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);\n            $this->download($content, $filename, 'application\/json');\n        } else {\n            $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}",
        "newString": "    public function export(string $uuid): void\n    {\n        $format = $this->getString('format') ?: 'markdown';\n        $filename = $this->exportUseCase->generateFilename($uuid, $format);\n\n        if ($format === 'json') {\n            $data = $this->exportUseCase->exportAsJson($uuid);\n\n            if ($data === null) {\n                $this->notFound('Session nicht gefunden');\n            }\n\n            $content = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);\n            $this->download($content, $filename, 'application\/json');\n        } else {\n            $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}",
        "originalFile": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Controller;\n\n\/\/ @responsibility: HTTP-Endpunkte für KI-Chat (Sessions, Nachrichten, Export)\n\nuse Domain\\Factory\\ChatSessionFactory;\nuse Domain\\Service\\ModelRegistryInterface;\nuse Framework\\Controller;\nuse Infrastructure\\Formatting\\ChatMessageFormatter;\nuse UseCases\\Chat\\CreateChatSessionUseCaseInterface;\nuse UseCases\\Chat\\DeleteChatSessionUseCaseInterface;\nuse UseCases\\Chat\\ExportChatSessionUseCase;\nuse UseCases\\Chat\\GetChatSessionUseCaseInterface;\nuse UseCases\\Chat\\SendChatMessageUseCase;\nuse UseCases\\Chat\\StreamingChatMessageUseCase;\nuse UseCases\\Chat\\UpdateChatSessionUseCaseInterface;\n\nclass ChatController extends Controller\n{\n    public function __construct(\n        private CreateChatSessionUseCaseInterface $createSessionUseCase,\n        private GetChatSessionUseCaseInterface $getSessionUseCase,\n        private UpdateChatSessionUseCaseInterface $updateSessionUseCase,\n        private DeleteChatSessionUseCaseInterface $deleteSessionUseCase,\n        private SendChatMessageUseCase $messageUseCase,\n        private StreamingChatMessageUseCase $streamingUseCase,\n        private ChatMessageFormatter $formatter,\n        private ExportChatSessionUseCase $exportUseCase,\n        private ModelRegistryInterface $modelRegistry\n    ) {\n    }\n\n    public function index(): void\n    {\n        $uuid = $this->createSessionUseCase->createSession();\n        header('Location: \/chat\/' . $uuid);\n        exit;\n    }\n\n    public function show(string $uuid): void\n    {\n        $session = $this->getSessionUseCase->getSession($uuid);\n\n        if ($session === null) {\n            header('Location: \/chat');\n            exit;\n        }\n\n        \/\/ Convert entities to arrays for views\n        $messages = $this->getSessionUseCase->getMessages($session->getId() ?? 0);\n        $messagesArray = array_map(fn ($m) => $m->toArray(), $messages);\n\n        $this->view('chat.index', [\n            'title' => $session->getTitle() ?? 'KI-Chat',\n            'session' => ChatSessionFactory::toArray($session),\n            'messages' => $messagesArray,\n            'sessions' => $this->getSessionUseCase->getAllSessionsWithStats(),\n            'authorProfiles' => $this->getSessionUseCase->getAuthorProfiles(),\n            'systemPrompts' => $this->getSessionUseCase->getSystemPrompts(),\n            'outputStructures' => $this->getSessionUseCase->getOutputStructures(),\n            'collections' => $this->getSessionUseCase->getAvailableCollections(),\n            'models' => $this->modelRegistry->getChatModels(),\n            'defaultModel' => $this->modelRegistry->getDefaultChatModel(),\n        ]);\n    }\n\n    public function sessionList(): void\n    {\n        $this->view('chat.partials.session-list', [\n            'sessions' => $this->getSessionUseCase->getAllSessionsWithStats(),\n            'currentUuid' => $this->getString('current') ?: null,\n        ]);\n    }\n\n    public function message(string $uuid): void\n    {\n        $session = $this->getSessionUseCase->getSession($uuid);\n\n        if ($session === null) {\n            $this->view('chat.partials.error', ['error' => 'Session nicht gefunden.']);\n\n            return;\n        }\n\n        $sessionId = $session->getId() ?? 0;\n        $question = trim($_POST['message'] ?? '');\n        $requestedModel = $_POST['model'] ?? $session->getModel();\n        $model = $this->modelRegistry->isValid($requestedModel)\n            ? $requestedModel\n            : $this->modelRegistry->getDefaultChatModel();\n        $sessionCollections = $session->getCollections();\n        $collections = $_POST['collections'] ?? $sessionCollections;\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\n        if ($this->updateSessionUseCase->settingsHaveChanged($session, $model, $collections, $contextLimit, $authorProfileId, $temperature, $maxTokens)) {\n            $this->updateSessionUseCase->updateSettings($sessionId, $model, $collections, $contextLimit, $authorProfileId, $temperature, $maxTokens);\n        }\n\n        if ($question === '') {\n            $this->view('chat.partials.error', ['error' => 'Bitte gib eine Frage ein.']);\n\n            return;\n        }\n\n        if (!empty($collections)) {\n            $compatibility = $this->updateSessionUseCase->validateCollectionCompatibility($collections);\n            if (!$compatibility['valid']) {\n                $this->view('chat.partials.error', [\n                    'error' => 'Collection-Fehler: ' . $compatibility['error'],\n                    'details' => 'Bitte wähle nur Collections mit gleichem Embedding-Modell.',\n                ]);\n\n                return;\n            }\n        }\n\n        $qualityCheck = isset($_POST['quality_check']) && $_POST['quality_check'] === '1';\n\n        $response = $this->messageUseCase->execute(\n            sessionUuid: $uuid,\n            message: $question,\n            model: $model,\n            collections: $collections,\n            contextLimit: $contextLimit,\n            authorProfileId: $authorProfileId,\n            systemPromptId: $systemPromptId,\n            temperature: $temperature,\n            maxTokens: $maxTokens,\n            structureId: $structureId,\n            qualityCheck: $qualityCheck\n        );\n\n        if ($response->hasError()) {\n            $this->view('chat.partials.error', ['error' => $response->getError()]);\n\n            return;\n        }\n\n        $result = $response->toArray();\n        $this->view('chat.partials.response', [\n            'question' => $question,\n            'result' => $result,\n            'model' => $model,\n            'formattedAnswer' => $this->formatter->formatAnswer($result['answer'] ?? ''),\n        ]);\n    }\n\n    \/**\n     * Streaming message endpoint with SSE progress events\n     *\/\n    public function messageStream(string $uuid): void\n    {\n        $session = $this->getSessionUseCase->getSession($uuid);\n\n        if ($session === null) {\n            $this->sseError('Session nicht gefunden.');\n\n            return;\n        }\n\n        $sessionId = $session->getId() ?? 0;\n        $question = trim($_POST['message'] ?? '');\n        $requestedModel = $_POST['model'] ?? $session->getModel();\n        $model = $this->modelRegistry->isValid($requestedModel)\n            ? $requestedModel\n            : $this->modelRegistry->getDefaultChatModel();\n        $sessionCollections = $session->getCollections();\n        $collections = $_POST['collections'] ?? $sessionCollections;\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\n        if ($this->updateSessionUseCase->settingsHaveChanged($session, $model, $collections, $contextLimit, $authorProfileId, $temperature, $maxTokens)) {\n            $this->updateSessionUseCase->updateSettings($sessionId, $model, $collections, $contextLimit, $authorProfileId, $temperature, $maxTokens);\n        }\n\n        if ($question === '') {\n            $this->sseError('Bitte gib eine Frage ein.');\n\n            return;\n        }\n\n        if (!empty($collections)) {\n            $compatibility = $this->updateSessionUseCase->validateCollectionCompatibility($collections);\n            if (!$compatibility['valid']) {\n                $this->sseError('Collection-Fehler: ' . $compatibility['error']);\n\n                return;\n            }\n        }\n\n        $qualityCheck = isset($_POST['quality_check']) && $_POST['quality_check'] === '1';\n\n        \/\/ Setup SSE headers - critical for streaming\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        \/\/ Disable ALL output buffering\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        while (ob_get_level()) {\n            ob_end_clean();\n        }\n        ob_implicit_flush(true);\n\n        \/\/ Send 4KB padding to force buffer flush (browsers need minimum bytes)\n        echo ':' . str_repeat(' ', 4096) . \"\\n\\n\";\n        flush();\n\n        \/\/ Set progress callback - send padding after each event to force flush\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            \/\/ Force buffer flush with padding (Apache\/proxy buffering workaround)\n            echo ':' . str_repeat(' ', 4096) . \"\\n\";\n            flush();\n        });\n\n        \/\/ Execute with streaming\n        $response = $this->streamingUseCase->execute(\n            sessionUuid: $uuid,\n            message: $question,\n     ... [TRUNCATED-8f4824802cb4ef46]",
        "structuredPatch": [
            {
                "oldStart": 381,
                "oldLines": 4,
                "newStart": 381,
                "newLines": 109,
                "lines": [
                    "             $this->download($content, $filename, 'text\/markdown');",
                    "         }",
                    "     }",
                    "+",
                    "+    \/**",
                    "+     * Extract chat message parameters from POST and session.",
                    "+     *",
                    "+     * @return array{",
                    "+     *   question: string,",
                    "+     *   model: string,",
                    "+     *   collections: array<string>,",
                    "+     *   contextLimit: int,",
                    "+     *   authorProfileId: int,",
                    "+     *   systemPromptId: int,",
                    "+     *   structureId: int,",
                    "+     *   temperature: float,",
                    "+     *   maxTokens: int,",
                    "+     *   qualityCheck: bool",
                    "+     * }",
                    "+     *\/",
                    "+    private function extractChatParams(\\Domain\\Entity\\ChatSession $session): array",
                    "+    {",
                    "+        $requestedModel = $_POST['model'] ?? $session->getModel();",
                    "+        $model = $this->modelRegistry->isValid($requestedModel)",
                    "+            ? $requestedModel",
                    "+            : $this->modelRegistry->getDefaultChatModel();",
                    "+",
                    "+        return [",
                    "+            'question' => trim($_POST['message'] ?? ''),",
                    "+            'model' => $model,",
                    "+            'collections' => $_POST['collections'] ?? $session->getCollections(),",
                    "+            '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()),",
                    "+            'qualityCheck' => isset($_POST['quality_check']) && $_POST['quality_check'] === '1',",
                    "+        ];",
                    "+    }",
                    "+",
                    "+    \/**",
                    "+     * Update session settings if changed.",
                    "+     *",
                    "+     * @param array<string> $collections",
                    "+     *\/",
                    "+    private function updateSessionIfChanged(",
                    "+        \\Domain\\Entity\\ChatSession $session,",
                    "+        string $model,",
                    "+        array $collections,",
                    "+        int $contextLimit,",
                    "+        int $authorProfileId,",
                    "+        float $temperature,",
                    "+        int $maxTokens",
                    "+    ): void {",
                    "+        if ($this->updateSessionUseCase->settingsHaveChanged($session, $model, $collections, $contextLimit, $authorProfileId, $temperature, $maxTokens)) {",
                    "+            $this->updateSessionUseCase->updateSettings($session->getId() ?? 0, $model, $collections, $contextLimit, $authorProfileId, $temperature, $maxTokens);",
                    "+        }",
                    "+    }",
                    "+",
                    "+    \/**",
                    "+     * Validate collections compatibility.",
                    "+     *",
                    "+     * @param array<string> $collections",
                    "+     * @return array{valid: bool, error: string|null}",
                    "+     *\/",
                    "+    private function validateCollections(array $collections): array",
                    "+    {",
                    "+        if (empty($collections)) {",
                    "+            return ['valid' => true, 'error' => null];",
                    "+        }",
                    "+",
                    "+        $compatibility = $this->updateSessionUseCase->validateCollectionCompatibility($collections);",
                    "+",
                    "+        return [",
                    "+            'valid' => $compatibility['valid'],",
                    "+            'error' => $compatibility['error'] ?? null,",
                    "+        ];",
                    "+    }",
                    "+",
                    "+    \/**",
                    "+     * Setup SSE stream headers and disable buffering.",
                    "+     *\/",
                    "+    private function setupSseStream(): void",
                    "+    {",
                    "+        header('Content-Type: text\/event-stream; charset=utf-8');",
                    "+        header('Cache-Control: no-cache, no-store, must-revalidate');",
                    "+        header('Pragma: no-cache');",
                    "+        header('Connection: keep-alive');",
                    "+        header('X-Accel-Buffering: no');",
                    "+        header('Content-Encoding: none');",
                    "+",
                    "+        if (function_exists('apache_setenv')) {",
                    "+            apache_setenv('no-gzip', '1');",
                    "+        }",
                    "+        @ini_set('zlib.output_compression', '0');",
                    "+        @ini_set('implicit_flush', '1');",
                    "+        @ini_set('output_buffering', '0');",
                    "+",
                    "+        while (ob_get_level()) {",
                    "+            ob_end_clean();",
                    "+        }",
                    "+        ob_implicit_flush(true);",
                    "+",
                    "+        \/\/ Send padding to force buffer flush",
                    "+        echo ':' . str_repeat(' ', 4096) . \"\\n\\n\";",
                    "+        flush();",
                    "+    }",
                    " }"
                ]
            }
        ],
        "userModified": false,
        "replaceAll": false
    }
}
← Vorheriger Zur Liste Nächster →