{
"event": "PreToolUse",
"tool_name": "Edit",
"tool_input": {
"file_path": "\/var\/www\/scripts\/pipeline\/pipeline_config.py",
"old_string": " except json.JSONDecodeError as e:\n raise PipelineConfigError(f\"Ungültiges JSON in config für step_type='{step_type}': {e}\")",
"new_string": " except json.JSONDecodeError as e:\n raise PipelineConfigError(f\"Ungültiges JSON in config für step_type='{step_type}': {e}\") from e"
}
}
{
"tool_response": {
"filePath": "\/var\/www\/scripts\/pipeline\/pipeline_config.py",
"oldString": " except json.JSONDecodeError as e:\n raise PipelineConfigError(f\"Ungültiges JSON in config für step_type='{step_type}': {e}\")",
"newString": " except json.JSONDecodeError as e:\n raise PipelineConfigError(f\"Ungültiges JSON in config für step_type='{step_type}': {e}\") from e",
"originalFile": "#!\/usr\/bin\/env python3\n\"\"\"\nZentrale Pipeline-Konfiguration aus DB.\n\nSingle Source of Truth: ki_content.pipeline_steps.config\n\nErstellt: 2025-12-28 (Task #516)\nSupervision: Genehmigt mit Auflagen\n\"\"\"\n\nimport os\n\nfrom db import db\n\n# Default Pipeline-ID als Konstante (nicht inline hardcoded)\nDEFAULT_PIPELINE_ID = 5\n\n\nclass PipelineConfigError(Exception):\n \"\"\"\n Fehler wenn Config fehlt - KEIN stilles Fallback!\n\n Diese Exception soll Pipeline-Läufe stoppen wenn\n die Konfiguration unvollständig ist.\n \"\"\"\n\n pass\n\n\ndef get_step_model(step_type: str, pipeline_id: int = None) -> str:\n \"\"\"\n Liest Model aus pipeline_steps.config.\n\n Args:\n step_type: Step-Typ (z.B. 'text_semantic_analyze')\n pipeline_id: Pipeline-ID (Default aus ENV PIPELINE_ID oder DEFAULT_PIPELINE_ID)\n\n Returns:\n Model-Name als String (z.B. 'mistral', 'gemma3:27b-it-qat')\n\n Raises:\n PipelineConfigError: Bei fehlendem\/ungültigem Config\n\n WICHTIG:\n - Wirft Exception wenn nicht konfiguriert!\n - Kein stilles Fallback auf hardcodierte Werte.\n - Mehrfachzeilen sind ein Datenfehler.\n\n Beispiel:\n model = get_step_model(\"text_semantic_analyze\")\n \"\"\"\n # Pipeline-ID aus Parameter, ENV oder Default-Konstante\n if pipeline_id is None:\n env_id = os.environ.get(\"PIPELINE_ID\")\n pipeline_id = int(env_id) if env_id else DEFAULT_PIPELINE_ID\n\n cursor = db.execute(\n \"\"\"SELECT JSON_UNQUOTE(JSON_EXTRACT(config, '$.model')) as model\n FROM pipeline_steps\n WHERE pipeline_id = %s AND step_type = %s AND enabled = 1\"\"\",\n (pipeline_id, step_type),\n )\n rows = cursor.fetchall()\n cursor.close()\n\n # Mehrfachzeilen = Datenfehler (UNIQUE Constraint sollte das verhindern)\n if len(rows) > 1:\n raise PipelineConfigError(\n f\"DATENFEHLER: {len(rows)} Einträge für \"\n f\"pipeline_id={pipeline_id}, step_type='{step_type}'. \"\n f\"Erwarte genau 1. UNIQUE Constraint prüfen!\"\n )\n\n # Keine Zeile = Config fehlt\n if len(rows) == 0:\n raise PipelineConfigError(\n f\"Kein Model konfiguriert für step_type='{step_type}' \"\n f\"in pipeline_id={pipeline_id}. \"\n f\"Bitte in pipeline_steps.config setzen!\"\n )\n\n model = rows[0].get(\"model\")\n\n # Leerer String oder NULL = ungültig\n if not model or model.strip() == \"\":\n raise PipelineConfigError(\n f\"Model ist leer für step_type='{step_type}' \"\n f\"in pipeline_id={pipeline_id}. \"\n f\"Bitte in pipeline_steps.config setzen!\"\n )\n\n return model.strip()\n\n\ndef get_step_config(step_type: str, pipeline_id: int = None) -> dict:\n \"\"\"\n Liest komplette Step-Config aus pipeline_steps.\n\n Args:\n step_type: Step-Typ (z.B. 'text_semantic_analyze')\n pipeline_id: Pipeline-ID (Default aus ENV PIPELINE_ID oder DEFAULT_PIPELINE_ID)\n\n Returns:\n Config als dict\n\n Raises:\n PipelineConfigError: Bei fehlendem Config\n \"\"\"\n import json\n\n if pipeline_id is None:\n env_id = os.environ.get(\"PIPELINE_ID\")\n pipeline_id = int(env_id) if env_id else DEFAULT_PIPELINE_ID\n\n cursor = db.execute(\n \"\"\"SELECT config FROM pipeline_steps\n WHERE pipeline_id = %s AND step_type = %s AND enabled = 1\"\"\",\n (pipeline_id, step_type),\n )\n rows = cursor.fetchall()\n cursor.close()\n\n if len(rows) != 1:\n raise PipelineConfigError(f\"Config nicht gefunden für step_type='{step_type}' in pipeline_id={pipeline_id}.\")\n\n config_str = rows[0].get(\"config\")\n if not config_str:\n return {}\n\n try:\n return json.loads(config_str)\n except json.JSONDecodeError as e:\n raise PipelineConfigError(f\"Ungültiges JSON in config für step_type='{step_type}': {e}\")\n",
"structuredPatch": [
{
"oldStart": 130,
"oldLines": 4,
"newStart": 130,
"newLines": 4,
"lines": [
" try:",
" return json.loads(config_str)",
" except json.JSONDecodeError as e:",
"- raise PipelineConfigError(f\"Ungültiges JSON in config für step_type='{step_type}': {e}\")",
"+ raise PipelineConfigError(f\"Ungültiges JSON in config für step_type='{step_type}': {e}\") from e"
]
}
],
"userModified": false,
"replaceAll": false
}
}