{
"event": "PreToolUse",
"tool_name": "Read",
"tool_input": {
"file_path": "\/var\/www\/dev.campus.systemische-tools.de\/src\/Controller\/ChatController.php",
"offset": 530,
"limit": 120
}
}
{
"tool_response": {
"type": "text",
"file": {
"filePath": "\/var\/www\/dev.campus.systemische-tools.de\/src\/Controller\/ChatController.php",
"content": " *\/\n private function validateMaxTokens(int $maxTokens): int\n {\n $allowedValues = [1024, 2048, 4096, 8192];\n\n return in_array($maxTokens, $allowedValues, true) ? $maxTokens : 4096;\n }\n\n \/**\n * Generate style prompt from author profile config\n *\/\n private function getStylePromptFromProfile(int $profileId): ?string\n {\n if ($profileId === 0) {\n return null;\n }\n\n $profile = $this->getAuthorProfile($profileId);\n if ($profile === null) {\n return null;\n }\n\n $config = json_decode($profile['config'], true);\n if ($config === null) {\n return null;\n }\n\n $parts = [];\n\n \/\/ Build style instructions from config\n if (isset($config['stimme']['ton'])) {\n $parts[] = 'Ton: ' . $config['stimme']['ton'];\n }\n if (isset($config['stimme']['perspektive'])) {\n $parts[] = 'Perspektive: ' . $config['stimme']['perspektive'];\n }\n if (isset($config['stil']['fachsprache']) && $config['stil']['fachsprache']) {\n $parts[] = 'Verwende Fachsprache';\n }\n if (isset($config['stil']['beispiele']) && $config['stil']['beispiele'] === 'häufig') {\n $parts[] = 'Nutze häufig Beispiele';\n }\n if (isset($config['stil']['listen']) && $config['stil']['listen'] === 'bevorzugt') {\n $parts[] = 'Bevorzuge Listen und Bullet-Points';\n }\n if (isset($config['tabus']) && is_array($config['tabus'])) {\n $parts[] = 'Vermeide: ' . implode(', ', $config['tabus']);\n }\n\n if ($parts === []) {\n return null;\n }\n\n return 'Schreibstil (' . $profile['name'] . '): ' . implode('. ', $parts) . '.';\n }\n\n \/**\n * Update session model, collections, context limit, author profile, temperature and max_tokens settings\n *\n * @param array<string> $collections Array of collection names\n *\/\n private function updateSessionSettings(int $sessionId, string $model, array $collections, int $contextLimit = 5, int $authorProfileId = 0, float $temperature = 0.7, int $maxTokens = 4096): void\n {\n $collectionsJson = json_encode($collections);\n $stmt = $this->db->prepare('UPDATE chat_sessions SET model = ?, collections = ?, context_limit = ?, author_profile_id = ?, temperature = ?, max_tokens = ? WHERE id = ?');\n $stmt->execute([$model, $collectionsJson, $contextLimit, $authorProfileId > 0 ? $authorProfileId : null, $temperature, $maxTokens, $sessionId]);\n }\n\n \/**\n * Validate system prompt input.\n *\n * NOTE: Pattern-based prompt injection filtering was intentionally removed.\n * Such filtering provides false security since attackers can easily rephrase\n * malicious instructions. LLM prompt injection cannot be reliably prevented\n * through input sanitization alone.\n *\n * Instead, we apply:\n * - Length limits (to prevent resource abuse)\n * - Logging (for monitoring and incident response)\n *\n * True prompt injection mitigation requires architectural measures like\n * sandboxing LLM outputs and limiting LLM capabilities.\n *\/\n private function validateSystemPrompt(string $prompt): string\n {\n \/\/ Length limit: prevent resource abuse\n $maxLength = 2000;\n $wasTruncated = mb_strlen($prompt) > $maxLength;\n $prompt = mb_substr($prompt, 0, $maxLength);\n\n \/\/ Log custom system prompts for monitoring\n $this->logSystemPromptChange($prompt, $wasTruncated);\n\n return trim($prompt);\n }\n\n \/**\n * Log system prompt changes for security monitoring.\n *\/\n private function logSystemPromptChange(string $prompt, bool $wasTruncated): void\n {\n $logData = [\n 'prompt_length' => mb_strlen($prompt),\n 'truncated' => $wasTruncated,\n 'ip' => $_SERVER['REMOTE_ADDR'] ?? 'unknown',\n 'timestamp' => date('c'),\n ];\n\n \/\/ Log to database via ki_dev.mcp_log\n try {\n $devDb = \\Infrastructure\\Config\\DatabaseFactory::dev();\n $stmt = $devDb->prepare(\n \"INSERT INTO mcp_log (tool, operation, parameters, result, logged_at)\n VALUES ('chat', 'system_prompt_change', :params, 'logged', NOW())\"\n );\n $stmt->execute(['params' => json_encode($logData)]);\n } catch (\\Exception $e) {\n \/\/ Silently fail - logging should not break functionality\n }\n }",
"numLines": 120,
"startLine": 530,
"totalLines": 793
}
}
}