Protokoll #3289

ID3289
Zeitstempel2025-12-22 02:14:13.712328
Clientroot
IP145.224.96.190
Modellclaude-sonnet-4-20250514
Statuscompleted
Tokens1,261 (Input: 45, Output: 1,216)
Dauer85 ms
Request-Zeit2025-12-22 02:14:13.712328
Response-Zeit2025-12-22 02:14:13.797381

Request

{
    "event": "PreToolUse",
    "tool_name": "Read",
    "tool_input": {
        "file_path": "\/var\/www\/dev.campus.systemische-tools.de\/src\/Controller\/ChatController.php",
        "offset": 530,
        "limit": 120
    }
}

Response

{
    "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
        }
    }
}
← Vorheriger Zur Liste Nächster →