Protokoll #898

ID898
Zeitstempel2025-12-20 17:40:01.120795
Clientroot
IP
Warning: Undefined array key "request_ip" in /var/www/dev.campus.systemische-tools.de/src/View/protokoll/show.php on line 13

Deprecated: htmlspecialchars(): Passing null to parameter #1 ($string) of type string is deprecated in /var/www/dev.campus.systemische-tools.de/src/View/protokoll/show.php on line 13
Modellclaude-sonnet-4-20250514
Statuscompleted
Tokens2,654 (Input: 0, Output: 0)
Dauer380 ms
Request-Zeit
Warning: Undefined array key "request_timestamp" in /var/www/dev.campus.systemische-tools.de/src/View/protokoll/show.php on line 18
Response-Zeit-

Warning: Undefined array key "error_message" in /var/www/dev.campus.systemische-tools.de/src/View/protokoll/show.php on line 22

Request

{
    "event": "PreToolUse",
    "tool_name": "mcp__mcp-db__db_select",
    "tool_input": {
        "query": "SELECT * FROM file_backup_history ORDER BY id DESC LIMIT 5",
        "database": "ki_dev"
    }
}

Response

{
    "tool_response": [
        {
            "type": "text",
            "text": "{\n  \"status\": \"success\",\n  \"data\": [\n    {\n      \"id\": 44,\n      \"file_path\": \"\/var\/www\/dev.campus.systemische-tools.de\/src\/Infrastructure\/AI\/AIConfig.php\",\n      \"file_content\": \"<?php\\n\\ndeclare(strict_types=1);\\n\\nnamespace Infrastructure\\\\AI;\\n\\nuse RuntimeException;\\n\\n\/**\\n * Zentralisierte AI-Service-Konfiguration.\\n *\\n * Verwaltet alle Konfigurationswerte für AI-Services (Ollama, Qdrant, Claude)\\n * und stellt Factory-Methoden zur Service-Erstellung bereit.\\n *\\n * Diese Klasse:\\n * - Lädt Credentials sicher aus der credentials.md Datei\\n * - Definiert Default-Werte für alle Service-URLs und Modelle\\n * - Erstellt konfigurierte Service-Instanzen\\n * - Verhindert doppeltes Laden von API-Keys\\n *\\n * @package Infrastructure\\\\AI\\n * @author  System Generated\\n * @version 1.0.0\\n *\/\\nfinal readonly class AIConfig\\n{\\n    \/**\\n     * Konstruiert eine neue AIConfig-Instanz.\\n     *\\n     * @param string $ollamaHost       Ollama API Host-URL\\n     * @param string $qdrantHost       Qdrant API Host-URL\\n     * @param string $anthropicApiKey  Anthropic API Key\\n     * @param string $embeddingModel   Embedding-Modell für Ollama\\n     * @param string $claudeModel      Claude-Modell für Anthropic\\n     * @param string $defaultCollection Standard-Collection für Qdrant\\n     *\/\\n    public function __construct(\\n        public string $ollamaHost,\\n        public string $qdrantHost,\\n        public string $anthropicApiKey,\\n        public string $embeddingModel,\\n        public string $claudeModel,\\n        public string $defaultCollection\\n    ) {\\n    }\\n\\n    \/**\\n     * Erstellt AIConfig aus Credentials-Datei mit Default-Werten.\\n     *\\n     * Lädt den Anthropic API Key aus der credentials.md Datei und\\n     * verwendet Default-Werte für alle anderen Konfigurationsparameter.\\n     *\\n     * @param string $credentialsPath Pfad zur credentials.md Datei (default: \/var\/www\/docs\/credentials\/credentials.md)\\n     *\\n     * @return self Konfigurierte AIConfig-Instanz\\n     *\\n     * @throws RuntimeException Wenn Credentials-Datei nicht existiert\\n     * @throws RuntimeException Wenn Credentials-Datei nicht gelesen werden kann\\n     * @throws RuntimeException Wenn Anthropic API Key nicht gefunden wird\\n     *\\n     * @example\\n     * $config = AIConfig::fromCredentialsFile();\\n     * $chatService = $config->createChatService();\\n     *\/\\n    public static function fromCredentialsFile(\\n        string $credentialsPath = '\/var\/www\/docs\/credentials\/credentials.md'\\n    ): self {\\n        $anthropicApiKey = self::loadAnthropicApiKey($credentialsPath);\\n\\n        return new self(\\n            ollamaHost: 'http:\/\/localhost:11434',\\n            qdrantHost: 'http:\/\/localhost:6333',\\n            anthropicApiKey: $anthropicApiKey,\\n            embeddingModel: 'mxbai-embed-large',\\n            claudeModel: 'claude-opus-4-5-20251101',\\n            defaultCollection: 'documents'\\n        );\\n    }\\n\\n    \/**\\n     * Erstellt einen konfigurierten ChatService.\\n     *\\n     * Erzeugt alle benötigten Dependencies (OllamaService, QdrantService, ClaudeService)\\n     * und liefert einen vollständig konfigurierten ChatService zurück.\\n     *\\n     * @return ChatService Konfigurierter ChatService\\n     *\\n     * @example\\n     * $config = AIConfig::fromCredentialsFile();\\n     * $chatService = $config->createChatService();\\n     * $result = $chatService->chat('Was ist systemisches Coaching?');\\n     *\/\\n    public function createChatService(): ChatService\\n    {\\n        return new ChatService(\\n            $this->createOllamaService(),\\n            $this->createQdrantService(),\\n            $this->createClaudeService()\\n        );\\n    }\\n\\n    \/**\\n     * Erstellt einen konfigurierten OllamaService.\\n     *\\n     * @return OllamaService Konfigurierter OllamaService\\n     *\\n     * @example\\n     * $config = AIConfig::fromCredentialsFile();\\n     * $ollama = $config->createOllamaService();\\n     * $embedding = $ollama->getEmbedding('Hello World');\\n     *\/\\n    public function createOllamaService(): OllamaService\\n    {\\n        return new OllamaService($this->ollamaHost);\\n    }\\n\\n    \/**\\n     * Erstellt einen konfigurierten QdrantService.\\n     *\\n     * @return QdrantService Konfigurierter QdrantService\\n     *\\n     * @example\\n     * $config = AIConfig::fromCredentialsFile();\\n     * $qdrant = $config->createQdrantService();\\n     * $results = $qdrant->search($vector, 'documents');\\n     *\/\\n    public function createQdrantService(): QdrantService\\n    {\\n        return new QdrantService($this->qdrantHost);\\n    }\\n\\n    \/**\\n     * Erstellt einen konfigurierten ClaudeService.\\n     *\\n     * @return ClaudeService Konfigurierter ClaudeService\\n     *\\n     * @example\\n     * $config = AIConfig::fromCredentialsFile();\\n     * $claude = $config->createClaudeService();\\n     * $result = $claude->ask('Explain quantum computing');\\n     *\/\\n    public function createClaudeService(): ClaudeService\\n    {\\n        return new ClaudeService($this->anthropicApiKey);\\n    }\\n\\n    \/**\\n     * Lädt den Anthropic API Key aus der Credentials-Datei.\\n     *\\n     * Sucht nach einer Zeile, die mit 'sk-ant-' beginnt und gibt diese zurück.\\n     * API Key wird niemals in Exception-Messages geloggt.\\n     *\\n     * @param string $credentialsPath Pfad zur credentials.md Datei\\n     *\\n     * @return string Der gefundene API Key\\n     *\\n     * @throws RuntimeException Wenn Credentials-Datei nicht existiert\\n     * @throws RuntimeException Wenn Credentials-Datei nicht gelesen werden kann\\n     * @throws RuntimeException Wenn API Key nicht gefunden wird\\n     *\/\\n    private static function loadAnthropicApiKey(string $credentialsPath): string\\n    {\\n        if (!file_exists($credentialsPath)) {\\n            throw new RuntimeException('Credentials file not found');\\n        }\\n\\n        $content = file_get_contents($credentialsPath);\\n\\n        if ($content === false) {\\n            throw new RuntimeException('Could not read credentials file');\\n        }\\n\\n        foreach (explode(\\\"\\\\n\\\", $content) as $line) {\\n            $trimmedLine = trim($line);\\n            if (str_starts_with($trimmedLine, 'sk-ant-')) {\\n                return $trimmedLine;\\n            }\\n        }\\n\\n        throw new RuntimeException('Anthropic API key not found in credentials file');\\n    }\\n}\\n\",\n      \"content_hash\": \"2ad822b274fadd54e6305f19e4f6dd7a321752eda0e0580f23c2e5e1e0237d8d\",\n      \"file_size\": 5997,\n      \"version\": 1,\n      \"change_type\": \"modified\",\n      \"changed_at\": \"2025-12-20T17:24:52\",\n      \"changed_by\": \"claude-code-hook\",\n      \"reason\": \"Claude Code Pre-Hook Backup vor Edit-Operation\",\n      \"diff_summary\": null,\n      \"affected_entities\": null\n    },\n    {\n      \"id\": 43,\n      \"file_path\": \"\/var\/www\/dev.campus.systemische-tools.de\/src\/Infrastructure\/AI\/AnthropicClient.php\",\n      \"file_content\": \"<?php\\n\\nnamespace Infrastructure\\\\AI;\\n\\nclass AnthropicClient implements AIClientInterface\\n{\\n    private string $apiKey;\\n    private string $model;\\n    private string $baseUrl;\\n    private int $timeout;\\n\\n    private const PRICING = [\\n        'claude-sonnet-4-20250514' => ['input' => 3.0, 'output' => 15.0],\\n        'claude-opus-4-20250514' => ['input' => 15.0, 'output' => 75.0],\\n        'claude-haiku-3-20250514' => ['input' => 0.25, 'output' => 1.25],\\n    ];\\n\\n    public function __construct(\\n        string $apiKey = '',\\n        string $model = 'claude-sonnet-4-20250514',\\n        int $timeout = 120\\n    ) {\\n        $this->apiKey = $apiKey !== '' ? $apiKey : $this->loadApiKey();\\n        $this->model = $model;\\n        $this->baseUrl = 'https:\/\/api.anthropic.com\/v1';\\n        $this->timeout = $timeout;\\n    }\\n\\n    private function loadApiKey(): string\\n    {\\n        if (defined('ANTHROPIC_API_KEY')) {\\n            return ANTHROPIC_API_KEY;\\n        }\\n\\n        $envFile = '\/var\/www\/docs\/credentials\/credentials.md';\\n        if (file_exists($envFile)) {\\n            $content = file_get_contents($envFile);\\n            if (preg_match('\/ANTHROPIC_API_KEY[:\\\\s]+([a-zA-Z0-9_-]+)\/', $content, $matches)) {\\n                return $matches[1];\\n            }\\n        }\\n\\n        return '';\\n    }\\n\\n    public function execute(string $prompt, array $options = []): AIResponse\\n    {\\n        if ($this->apiKey === '') {\\n            return AIResponse::error('Anthropic API Key not configured', $this->model);\\n        }\\n\\n        $model = $options['model'] ?? $this->model;\\n        $startTime = microtime(true);\\n\\n        try {\\n            $ch = curl_init($this->baseUrl . '\/messages');\\n\\n            $messages = [\\n                ['role' => 'user', 'content' => $prompt],\\n            ];\\n\\n            $payload = [\\n                'model' => $model,\\n                'max_tokens' => $options['max_tokens'] ?? 4096,\\n                'messages' => $messages,\\n            ];\\n\\n            if (isset($options['system'])) {\\n                $payload['system'] = $options['system'];\\n            }\\n\\n            if (isset($options['temperature'])) {\\n                $payload['temperature'] = $options['temperature'];\\n            }\\n\\n            curl_setopt_array($ch, [\\n                CURLOPT_POST => true,\\n                CURLOPT_POSTFIELDS => json_encode($payload),\\n                CURLOPT_RETURNTRANSFER => true,\\n                CURLOPT_HTTPHEADER => [\\n                    'Content-Type: application\/json',\\n                    'x-api-key: ' . $this->apiKey,\\n                    'anthropic-version: 2023-06-01',\\n                ],\\n                CURLOPT_TIMEOUT => $this->timeout,\\n            ]);\\n\\n            $response = curl_exec($ch);\\n            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);\\n            $error = curl_error($ch);\\n            curl_close($ch);\\n\\n            $durationMs = (int) ((microtime(true) - $startTime) * 1000);\\n\\n            if ($error !== '') {\\n                return AIResponse::error(\\\"cURL Error: {$error}\\\", $m... [TRUNCATED-7ff0c386f66fbad5]"
        }
    ]
}
← Vorheriger Zur Liste Nächster →