Protokoll #3309

ID3309
Zeitstempel2025-12-22 02:16:39.596828
Clientroot
IP145.224.96.190
Modellclaude-sonnet-4-20250514
Statuscompleted
Tokens1,943 (Input: 969, Output: 974)
Dauer85 ms
Request-Zeit2025-12-22 02:16:39.596828
Response-Zeit2025-12-22 02:16:39.682240

Request

{
    "event": "PreToolUse",
    "tool_name": "Write",
    "tool_input": {
        "file_path": "\/var\/www\/dev.campus.systemische-tools.de\/src\/UseCases\/Content\/GenerateContentUseCase.php",
        "content": "<?php\n\nnamespace UseCases\\Content;\n\n\/**\n * GenerateContentUseCase - Orchestrates content generation\n *\n * Wraps the Python pipeline for content generation, critique, and revision.\n *\/\nclass GenerateContentUseCase\n{\n    private string $pipelinePath;\n    private string $pythonPath;\n\n    \/** @var array<string> Allowed Python commands *\/\n    private const ALLOWED_COMMANDS = ['generate', 'critique', 'revise'];\n\n    public function __construct(\n        ?string $pipelinePath = null,\n        ?string $pythonPath = null\n    ) {\n        $this->pipelinePath = $pipelinePath ?? '\/opt\/scripts\/pipeline';\n        $this->pythonPath = $pythonPath ?? $this->pipelinePath . '\/venv\/bin\/python';\n    }\n\n    \/**\n     * Generate content for an order\n     *\/\n    public function generate(int $orderId, string $model, string $collection, int $contextLimit): ContentGenerationResult\n    {\n        $result = $this->callPython('generate', $orderId, [$model, $collection, $contextLimit]);\n\n        return ContentGenerationResult::fromPythonResult($result);\n    }\n\n    \/**\n     * Run critique on a version\n     *\/\n    public function critique(int $versionId, string $model): ContentGenerationResult\n    {\n        $result = $this->callPython('critique', $versionId, [$model]);\n\n        return ContentGenerationResult::fromPythonResult($result);\n    }\n\n    \/**\n     * Create revision of a version\n     *\/\n    public function revise(int $versionId, string $model): ContentGenerationResult\n    {\n        $result = $this->callPython('revise', $versionId, [$model]);\n\n        return ContentGenerationResult::fromPythonResult($result);\n    }\n\n    \/**\n     * Call Python script with command and arguments\n     *\n     * @param string $command Command to execute (generate, critique, revise)\n     * @param int $entityId Order or version ID\n     * @param array<mixed> $args Additional arguments\n     * @return array<string,mixed> Result from Python script\n     *\/\n    private function callPython(string $command, int $entityId, array $args = []): array\n    {\n        \/\/ Validate command against whitelist\n        if (!in_array($command, self::ALLOWED_COMMANDS, true)) {\n            return ['error' => 'Ungültiger Command: ' . $command];\n        }\n\n        $scriptPath = $this->pipelinePath . '\/web_generate.py';\n\n        \/\/ Build command array for proc_open (safer than shell_exec)\n        $cmdArray = [\n            $this->pythonPath,\n            $scriptPath,\n            $command,\n            (string) $entityId,\n            ...$args,\n        ];\n\n        $descriptors = [\n            0 => ['pipe', 'r'],\n            1 => ['pipe', 'w'],\n            2 => ['pipe', 'w'],\n        ];\n\n        $process = proc_open($cmdArray, $descriptors, $pipes); \/\/ nosemgrep: exec-use\n\n        if (!is_resource($process)) {\n            return ['error' => 'Script konnte nicht gestartet werden'];\n        }\n\n        fclose($pipes[0]);\n        $stdout = stream_get_contents($pipes[1]);\n        $stderr = stream_get_contents($pipes[2]);\n        fclose($pipes[1]);\n        fclose($pipes[2]);\n        $exitCode = proc_close($process);\n\n        $output = $stdout . $stderr;\n\n        if ($exitCode !== 0 && $output === '') {\n            return ['error' => 'Script fehlgeschlagen (Exit: ' . $exitCode . ')'];\n        }\n\n        if (preg_match('\/\\{[\\s\\S]*\\}\/', $output, $matches)) {\n            $result = json_decode($matches[0], true);\n            if (json_last_error() === JSON_ERROR_NONE) {\n                return $result;\n            }\n        }\n\n        return ['error' => 'Ungültige Antwort: ' . substr($output, 0, 500)];\n    }\n}\n"
    }
}

Response

{
    "tool_response": {
        "type": "create",
        "filePath": "\/var\/www\/dev.campus.systemische-tools.de\/src\/UseCases\/Content\/GenerateContentUseCase.php",
        "content": "<?php\n\nnamespace UseCases\\Content;\n\n\/**\n * GenerateContentUseCase - Orchestrates content generation\n *\n * Wraps the Python pipeline for content generation, critique, and revision.\n *\/\nclass GenerateContentUseCase\n{\n    private string $pipelinePath;\n    private string $pythonPath;\n\n    \/** @var array<string> Allowed Python commands *\/\n    private const ALLOWED_COMMANDS = ['generate', 'critique', 'revise'];\n\n    public function __construct(\n        ?string $pipelinePath = null,\n        ?string $pythonPath = null\n    ) {\n        $this->pipelinePath = $pipelinePath ?? '\/opt\/scripts\/pipeline';\n        $this->pythonPath = $pythonPath ?? $this->pipelinePath . '\/venv\/bin\/python';\n    }\n\n    \/**\n     * Generate content for an order\n     *\/\n    public function generate(int $orderId, string $model, string $collection, int $contextLimit): ContentGenerationResult\n    {\n        $result = $this->callPython('generate', $orderId, [$model, $collection, $contextLimit]);\n\n        return ContentGenerationResult::fromPythonResult($result);\n    }\n\n    \/**\n     * Run critique on a version\n     *\/\n    public function critique(int $versionId, string $model): ContentGenerationResult\n    {\n        $result = $this->callPython('critique', $versionId, [$model]);\n\n        return ContentGenerationResult::fromPythonResult($result);\n    }\n\n    \/**\n     * Create revision of a version\n     *\/\n    public function revise(int $versionId, string $model): ContentGenerationResult\n    {\n        $result = $this->callPython('revise', $versionId, [$model]);\n\n        return ContentGenerationResult::fromPythonResult($result);\n    }\n\n    \/**\n     * Call Python script with command and arguments\n     *\n     * @param string $command Command to execute (generate, critique, revise)\n     * @param int $entityId Order or version ID\n     * @param array<mixed> $args Additional arguments\n     * @return array<string,mixed> Result from Python script\n     *\/\n    private function callPython(string $command, int $entityId, array $args = []): array\n    {\n        \/\/ Validate command against whitelist\n        if (!in_array($command, self::ALLOWED_COMMANDS, true)) {\n            return ['error' => 'Ungültiger Command: ' . $command];\n        }\n\n        $scriptPath = $this->pipelinePath . '\/web_generate.py';\n\n        \/\/ Build command array for proc_open (safer than shell_exec)\n        $cmdArray = [\n            $this->pythonPath,\n            $scriptPath,\n            $command,\n            (string) $entityId,\n            ...$args,\n        ];\n\n        $descriptors = [\n            0 => ['pipe', 'r'],\n            1 => ['pipe', 'w'],\n            2 => ['pipe', 'w'],\n        ];\n\n        $process = proc_open($cmdArray, $descriptors, $pipes); \/\/ nosemgrep: exec-use\n\n        if (!is_resource($process)) {\n            return ['error' => 'Script konnte nicht gestartet werden'];\n        }\n\n        fclose($pipes[0]);\n        $stdout = stream_get_contents($pipes[1]);\n        $stderr = stream_get_contents($pipes[2]);\n        fclose($pipes[1]);\n        fclose($pipes[2]);\n        $exitCode = proc_close($process);\n\n        $output = $stdout . $stderr;\n\n        if ($exitCode !== 0 && $output === '') {\n            return ['error' => 'Script fehlgeschlagen (Exit: ' . $exitCode . ')'];\n        }\n\n        if (preg_match('\/\\{[\\s\\S]*\\}\/', $output, $matches)) {\n            $result = json_decode($matches[0], true);\n            if (json_last_error() === JSON_ERROR_NONE) {\n                return $result;\n            }\n        }\n\n        return ['error' => 'Ungültige Antwort: ' . substr($output, 0, 500)];\n    }\n}\n",
        "structuredPatch": [],
        "originalFile": null
    }
}
← Vorheriger Zur Liste Nächster →