{
"event": "PreToolUse",
"tool_name": "Edit",
"tool_input": {
"file_path": "\/opt\/scripts\/pipeline\/analyze.py",
"old_string": " return {\n \"entities\": len(entities),\n \"relations\": len(relations) if entities else 0,\n \"categories\": taxonomy.get(\"categories\", []),\n }\n\n\nif __name__ == \"__main__\":",
"new_string": " return {\n \"entities\": len(entities),\n \"relations\": len(relations) if entities else 0,\n \"categories\": taxonomy.get(\"categories\", []),\n }\n\n\ndef analyze_chunk_semantics(chunk_id, content, client=None):\n \"\"\"\n Analyze a single chunk for semantics (summary, keywords, sentiment, topics).\n Stores result in chunk_semantics table.\n \"\"\"\n prompt_template = db.get_prompt(\"chunk_semantics\")\n\n if not prompt_template:\n prompt_template = \"\"\"Analysiere diesen Textabschnitt und extrahiere:\n\n1. **summary**: Eine kurze Zusammenfassung (1-2 Sätze)\n2. **keywords**: 3-5 wichtige Schlüsselwörter\n3. **sentiment**: Stimmung (positive, negative, neutral, mixed)\n4. **topics**: 2-3 Hauptthemen\n\nAntworte NUR im JSON-Format:\n{\"summary\": \"...\", \"keywords\": [\"...\", \"...\"], \"sentiment\": \"neutral\", \"topics\": [\"...\", \"...\"]}\n\nText:\n{{TEXT}}\"\"\"\n\n prompt = prompt_template.replace(\"{{TEXT}}\", content[:2000])\n\n try:\n start_time = time.time()\n tokens_in, tokens_out = 0, 0\n model_name = \"\"\n\n if client:\n message = client.messages.create(\n model=ANTHROPIC_MODEL, max_tokens=500, messages=[{\"role\": \"user\", \"content\": prompt}]\n )\n response_text = message.content[0].text\n tokens_in = message.usage.input_tokens\n tokens_out = message.usage.output_tokens\n model_name = ANTHROPIC_MODEL\n else:\n response = requests.post(\n f\"{OLLAMA_HOST}\/api\/generate\",\n json={\"model\": OLLAMA_CHAT_MODEL, \"prompt\": prompt, \"stream\": False, \"format\": \"json\"},\n timeout=60,\n )\n response.raise_for_status()\n data = response.json()\n response_text = data.get(\"response\", \"{}\")\n tokens_in = data.get(\"prompt_eval_count\", 0)\n tokens_out = data.get(\"eval_count\", 0)\n model_name = f\"ollama:{OLLAMA_CHAT_MODEL}\"\n\n duration_ms = int((time.time() - start_time) * 1000)\n\n # Log to ki-protokoll\n protokoll.log_llm_call(\n request=f\"[chunk_semantics] chunk_id={chunk_id}\",\n response=response_text[:1000],\n model_name=model_name,\n tokens_input=tokens_in,\n tokens_output=tokens_out,\n duration_ms=duration_ms,\n status=\"completed\",\n )\n\n # Parse JSON\n import re\n json_match = re.search(r\"\\{[\\s\\S]*\\}\", response_text)\n if json_match:\n result = json.loads(json_match.group())\n\n # Store in chunk_semantics\n cursor = db.execute(\n \"\"\"INSERT INTO chunk_semantics\n (chunk_id, summary, keywords, sentiment, topics, language, analyzed_at, analysis_model)\n VALUES (%s, %s, %s, %s, %s, 'de', NOW(), %s)\n ON DUPLICATE KEY UPDATE\n summary = VALUES(summary), keywords = VALUES(keywords),\n sentiment = VALUES(sentiment), topics = VALUES(topics),\n analyzed_at = NOW(), analysis_model = VALUES(analysis_model)\"\"\",\n (\n chunk_id,\n result.get(\"summary\", \"\"),\n json.dumps(result.get(\"keywords\", []), ensure_ascii=False),\n result.get(\"sentiment\", \"neutral\"),\n json.dumps(result.get(\"topics\", []), ensure_ascii=False),\n model_name,\n ),\n )\n db.commit()\n cursor.close()\n return result\n\n return None\n\n except Exception as e:\n db.log(\"ERROR\", f\"Chunk semantics analysis failed: {e}\")\n return None\n\n\ndef analyze_chunks_semantics(document_id, client=None):\n \"\"\"Analyze all chunks of a document for semantics.\"\"\"\n cursor = db.execute(\n \"SELECT id, content FROM chunks WHERE document_id = %s ORDER BY chunk_index\",\n (document_id,)\n )\n chunks = cursor.fetchall()\n cursor.close()\n\n db.log(\"INFO\", f\"Analyzing semantics for {len(chunks)} chunks\")\n\n analyzed = 0\n for chunk in chunks:\n result = analyze_chunk_semantics(chunk[\"id\"], chunk[\"content\"], client)\n if result:\n analyzed += 1\n\n db.log(\"INFO\", f\"Analyzed {analyzed}\/{len(chunks)} chunks for semantics\")\n return analyzed\n\n\nif __name__ == \"__main__\":"
}
}
{
"tool_response": {
"filePath": "\/opt\/scripts\/pipeline\/analyze.py",
"oldString": " return {\n \"entities\": len(entities),\n \"relations\": len(relations) if entities else 0,\n \"categories\": taxonomy.get(\"categories\", []),\n }\n\n\nif __name__ == \"__main__\":",
"newString": " return {\n \"entities\": len(entities),\n \"relations\": len(relations) if entities else 0,\n \"categories\": taxonomy.get(\"categories\", []),\n }\n\n\ndef analyze_chunk_semantics(chunk_id, content, client=None):\n \"\"\"\n Analyze a single chunk for semantics (summary, keywords, sentiment, topics).\n Stores result in chunk_semantics table.\n \"\"\"\n prompt_template = db.get_prompt(\"chunk_semantics\")\n\n if not prompt_template:\n prompt_template = \"\"\"Analysiere diesen Textabschnitt und extrahiere:\n\n1. **summary**: Eine kurze Zusammenfassung (1-2 Sätze)\n2. **keywords**: 3-5 wichtige Schlüsselwörter\n3. **sentiment**: Stimmung (positive, negative, neutral, mixed)\n4. **topics**: 2-3 Hauptthemen\n\nAntworte NUR im JSON-Format:\n{\"summary\": \"...\", \"keywords\": [\"...\", \"...\"], \"sentiment\": \"neutral\", \"topics\": [\"...\", \"...\"]}\n\nText:\n{{TEXT}}\"\"\"\n\n prompt = prompt_template.replace(\"{{TEXT}}\", content[:2000])\n\n try:\n start_time = time.time()\n tokens_in, tokens_out = 0, 0\n model_name = \"\"\n\n if client:\n message = client.messages.create(\n model=ANTHROPIC_MODEL, max_tokens=500, messages=[{\"role\": \"user\", \"content\": prompt}]\n )\n response_text = message.content[0].text\n tokens_in = message.usage.input_tokens\n tokens_out = message.usage.output_tokens\n model_name = ANTHROPIC_MODEL\n else:\n response = requests.post(\n f\"{OLLAMA_HOST}\/api\/generate\",\n json={\"model\": OLLAMA_CHAT_MODEL, \"prompt\": prompt, \"stream\": False, \"format\": \"json\"},\n timeout=60,\n )\n response.raise_for_status()\n data = response.json()\n response_text = data.get(\"response\", \"{}\")\n tokens_in = data.get(\"prompt_eval_count\", 0)\n tokens_out = data.get(\"eval_count\", 0)\n model_name = f\"ollama:{OLLAMA_CHAT_MODEL}\"\n\n duration_ms = int((time.time() - start_time) * 1000)\n\n # Log to ki-protokoll\n protokoll.log_llm_call(\n request=f\"[chunk_semantics] chunk_id={chunk_id}\",\n response=response_text[:1000],\n model_name=model_name,\n tokens_input=tokens_in,\n tokens_output=tokens_out,\n duration_ms=duration_ms,\n status=\"completed\",\n )\n\n # Parse JSON\n import re\n json_match = re.search(r\"\\{[\\s\\S]*\\}\", response_text)\n if json_match:\n result = json.loads(json_match.group())\n\n # Store in chunk_semantics\n cursor = db.execute(\n \"\"\"INSERT INTO chunk_semantics\n (chunk_id, summary, keywords, sentiment, topics, language, analyzed_at, analysis_model)\n VALUES (%s, %s, %s, %s, %s, 'de', NOW(), %s)\n ON DUPLICATE KEY UPDATE\n summary = VALUES(summary), keywords = VALUES(keywords),\n sentiment = VALUES(sentiment), topics = VALUES(topics),\n analyzed_at = NOW(), analysis_model = VALUES(analysis_model)\"\"\",\n (\n chunk_id,\n result.get(\"summary\", \"\"),\n json.dumps(result.get(\"keywords\", []), ensure_ascii=False),\n result.get(\"sentiment\", \"neutral\"),\n json.dumps(result.get(\"topics\", []), ensure_ascii=False),\n model_name,\n ),\n )\n db.commit()\n cursor.close()\n return result\n\n return None\n\n except Exception as e:\n db.log(\"ERROR\", f\"Chunk semantics analysis failed: {e}\")\n return None\n\n\ndef analyze_chunks_semantics(document_id, client=None):\n \"\"\"Analyze all chunks of a document for semantics.\"\"\"\n cursor = db.execute(\n \"SELECT id, content FROM chunks WHERE document_id = %s ORDER BY chunk_index\",\n (document_id,)\n )\n chunks = cursor.fetchall()\n cursor.close()\n\n db.log(\"INFO\", f\"Analyzing semantics for {len(chunks)} chunks\")\n\n analyzed = 0\n for chunk in chunks:\n result = analyze_chunk_semantics(chunk[\"id\"], chunk[\"content\"], client)\n if result:\n analyzed += 1\n\n db.log(\"INFO\", f\"Analyzed {analyzed}\/{len(chunks)} chunks for semantics\")\n return analyzed\n\n\nif __name__ == \"__main__\":",
"originalFile": "\"\"\"\nSemantic analysis for KI-System Pipeline\nEntity extraction, taxonomy classification, ontology mapping.\n\"\"\"\n\nimport json\nimport os\nimport time\n\nimport requests\n\nfrom config import ANTHROPIC_API_KEY, ANTHROPIC_MODEL, OLLAMA_CHAT_MODEL, OLLAMA_HOST\nfrom db import db\nfrom protokoll import protokoll\n\n\ndef get_anthropic_client():\n \"\"\"Get Anthropic API client.\"\"\"\n try:\n import anthropic\n\n if ANTHROPIC_API_KEY:\n db.log(\"INFO\", \"Using Anthropic API (Claude)\")\n return anthropic.Anthropic(api_key=ANTHROPIC_API_KEY)\n else:\n db.log(\"WARNING\", \"No Anthropic API key found, falling back to Ollama\")\n except ImportError:\n db.log(\"WARNING\", \"anthropic package not installed, falling back to Ollama\")\n return None\n\n\ndef extract_entities_ollama(text, model=\"gemma3:27b-it-qat\"):\n \"\"\"Extract entities using Ollama.\"\"\"\n # Load prompt from database\n prompt_template = db.get_prompt(\"entity_extraction\")\n\n if not prompt_template:\n db.log(\"WARNING\", \"entity_extraction prompt not found in DB, using fallback\")\n prompt_template = \"\"\"Analysiere den Text und extrahiere wichtige Entitäten.\nKategorisiere als: PERSON, ORGANIZATION, CONCEPT, LOCATION\nAntworte NUR im JSON-Format:\n{\"entities\": [{\"name\": \"...\", \"type\": \"...\", \"description\": \"...\"}]}\n\nText:\n{{TEXT}}\"\"\"\n\n prompt = prompt_template.replace(\"{{TEXT}}\", text[:3000])\n\n try:\n start_time = time.time()\n response = requests.post(\n f\"{OLLAMA_HOST}\/api\/generate\",\n json={\"model\": model, \"prompt\": prompt, \"stream\": False, \"format\": \"json\"},\n timeout=120,\n )\n response.raise_for_status()\n data = response.json()\n duration_ms = int((time.time() - start_time) * 1000)\n\n # Parse JSON from response\n response_text = data.get(\"response\", \"{}\")\n\n # Log to ki-protokoll\n protokoll.log_llm_call(\n request=f\"[entity_extraction] {prompt[:500]}...\",\n response=response_text[:2000],\n model_name=f\"ollama:{model}\",\n tokens_input=data.get(\"prompt_eval_count\", 0),\n tokens_output=data.get(\"eval_count\", 0),\n duration_ms=duration_ms,\n status=\"completed\",\n )\n\n try:\n entities = json.loads(response_text)\n return entities.get(\"entities\", [])\n except json.JSONDecodeError:\n db.log(\"WARNING\", \"Failed to parse entity JSON from Ollama\")\n return []\n except Exception as e:\n db.log(\"ERROR\", f\"Ollama entity extraction failed: {e}\")\n protokoll.log_llm_call(\n request=f\"[entity_extraction] {prompt[:500]}...\",\n model_name=f\"ollama:{model}\",\n status=\"error\",\n error_message=str(e),\n )\n return []\n\n\ndef extract_entities_anthropic(text, client):\n \"\"\"Extract entities using Anthropic Claude.\"\"\"\n # Get prompt from database\n prompt_template = db.get_prompt(\"entity_extraction\")\n\n if not prompt_template:\n prompt_template = \"\"\"Analysiere den folgenden deutschen Text und extrahiere alle wichtigen Entitäten.\n\nKategorisiere jede Entität als:\n- PERSON (Namen von Personen)\n- ORGANIZATION (Firmen, Institutionen, Gruppen)\n- CONCEPT (Fachbegriffe, Methoden, Theorien)\n- LOCATION (Orte, Länder)\n- DATE (Zeitangaben)\n- OTHER (Sonstiges)\n\nAntworte NUR im JSON-Format:\n{\"entities\": [{\"name\": \"...\", \"type\": \"...\", \"context\": \"kurzer Kontext der Erwähnung\"}]}\n\nText:\n{{TEXT}}\"\"\"\n\n prompt = prompt_template.replace(\"{{TEXT}}\", text[:4000])\n\n try:\n start_time = time.time()\n message = client.messages.create(\n model=ANTHROPIC_MODEL, max_tokens=2000, messages=[{\"role\": \"user\", \"content\": prompt}]\n )\n duration_ms = int((time.time() - start_time) * 1000)\n\n response_text = message.content[0].text\n\n # Log to ki-protokoll\n protokoll.log_llm_call(\n request=f\"[entity_extraction] {prompt[:500]}...\",\n response=response_text[:2000],\n model_name=ANTHROPIC_MODEL,\n tokens_input=message.usage.input_tokens,\n tokens_output=message.usage.output_tokens,\n duration_ms=duration_ms,\n status=\"completed\",\n )\n\n # Extract JSON from response\n import re\n\n json_match = re.search(r\"\\{[\\s\\S]*\\}\", response_text)\n if json_match:\n entities = json.loads(json_match.group())\n return entities.get(\"entities\", [])\n return []\n except Exception as e:\n db.log(\"ERROR\", f\"Anthropic entity extraction failed: {e}\")\n protokoll.log_llm_call(\n request=f\"[entity_extraction] {prompt[:500]}...\",\n model_name=ANTHROPIC_MODEL,\n status=\"error\",\n error_message=str(e),\n )\n return []\n\n\ndef extract_relations(text, entities, client=None):\n \"\"\"Extract relations between entities.\"\"\"\n if not entities or len(entities) < 2:\n return []\n\n entity_names = [e[\"name\"] for e in entities[:20]]\n\n # Load prompt from database\n prompt_template = db.get_prompt(\"relation_extraction\")\n\n if not prompt_template:\n db.log(\"WARNING\", \"relation_extraction prompt not found in DB, using fallback\")\n prompt_template = \"\"\"Identifiziere Beziehungen zwischen Entitäten.\nEntitäten: {{ENTITIES}}\nBeziehungstypen: DEVELOPED_BY, RELATED_TO, PART_OF, USED_IN, BASED_ON\nAntworte NUR im JSON-Format:\n{\"relations\": [{\"source\": \"...\", \"relation\": \"...\", \"target\": \"...\"}]}\n\nText:\n{{TEXT}}\"\"\"\n\n prompt = prompt_template.replace(\"{{ENTITIES}}\", \", \".join(entity_names))\n prompt = prompt.replace(\"{{TEXT}}\", text[:3000])\n\n try:\n start_time = time.time()\n tokens_in, tokens_out = 0, 0\n model_name = \"\"\n\n if client:\n message = client.messages.create(\n model=ANTHROPIC_MODEL, max_tokens=1000, messages=[{\"role\": \"user\", \"content\": prompt}]\n )\n response_text = message.content[0].text\n tokens_in = message.usage.input_tokens\n tokens_out = message.usage.output_tokens\n model_name = ANTHROPIC_MODEL\n else:\n response = requests.post(\n f\"{OLLAMA_HOST}\/api\/generate\",\n json={\"model\": OLLAMA_CHAT_MODEL, \"prompt\": prompt, \"stream\": False, \"format\": \"json\"},\n timeout=120,\n )\n response.raise_for_status()\n data = response.json()\n response_text = data.get(\"response\", \"{}\")\n tokens_in = data.get(\"prompt_eval_count\", 0)\n tokens_out = data.get(\"eval_count\", 0)\n model_name = f\"ollama:{OLLAMA_CHAT_MODEL}\"\n\n duration_ms = int((time.time() - start_time) * 1000)\n\n # Log to ki-protokoll\n protokoll.log_llm_call(\n request=f\"[relation_extraction] {prompt[:500]}...\",\n response=response_text[:2000],\n model_name=model_name,\n tokens_input=tokens_in,\n tokens_output=tokens_out,\n duration_ms=duration_ms,\n status=\"completed\",\n )\n\n import re\n\n json_match = re.search(r\"\\{[\\s\\S]*\\}\", response_text)\n if json_match:\n data = json.loads(json_match.group())\n return data.get(\"relations\", [])\n return []\n except Exception as e:\n db.log(\"ERROR\", f\"Relation extraction failed: {e}\")\n protokoll.log_llm_call(\n request=f\"[relation_extraction] {prompt[:500]}...\",\n model_name=ANTHROPIC_MODEL if client else f\"ollama:{OLLAMA_CHAT_MODEL}\",\n status=\"error\",\n error_message=str(e),\n )\n return []\n\n\ndef classify_taxonomy(text, client=None):\n \"\"\"Classify text into taxonomy categories.\"\"\"\n prompt_template = db.get_prompt(\"taxonomy_classification\")\n\n if not prompt_template:\n prompt_template = \"\"\"Klassifiziere den folgenden Text in passende Kategorien.\n\nWähle aus diesen Hauptkategorien:\n- Methoden (Therapiemethoden, Techniken)\n- Theorie (Konzepte, Modelle, Grundlagen)\n- Praxis (Anwendung, Fallbeispiele)\n- Organisation (Strukturen, Prozesse)\n- Kommunikation (Gesprächsführung, Interaktion)\n- Entwicklung (Persönliche Entwicklung, Veränderung)\n\nAntworte NUR im JSON-Format:\n{\"categories\": [\"...\", \"...\"], \"confidence\": 0.0-1.0}\n\nText:\n{{TEXT}}\"\"\"\n\n prompt = prompt_template.replace(\"{{TEXT}}\", text[:2000])\n\n try:\n start_time = time.time()\n tokens_in, tokens_out = 0, 0\n model_name = \"\"\n\n if client:\n message = client.messages.create(\n model=ANTHROPIC_MODEL, max_tokens=500, messages=[{\"role\": \"user\", \"content\": prompt}]\n )\n response_text = message.content[0].text\n tokens_in = message.usage.input_tokens\n tokens_out = message.usage.output_tokens\n model_name = ANTHROPIC_MODEL\n else:\n response = requests.post(\n f\"{OLLAMA_HOST}\/api\/generate\",\n json={\"model\": OLLAMA_CHAT_MODEL, \"prompt\": prompt, \"stream\": False, \"format\": \"json\"},\n timeout=60,\n )\n response.raise_for_status()\n data = response.json()\n response_text = data.get(\"response\", \"{}\")\n tokens_in = data.get(\"prompt_eval_count\", 0)\n tokens_out = data.get(\"eval_count\", 0)\n model_name = f\"ollama:{OLLAMA_CHAT_MODEL}\"\n\n duration_ms = int((time.time() - start_time) * 1000)\n\n # Log to ki-protokoll\n protokoll.log_llm_call(\n request=f\"[taxonomy_classification] {prompt[:500]}...\",\n response=response_text[:2000],\n model_name=model_name,\n tokens_input=tokens_in,\n tokens_output=tokens_out,\n duration_ms=duration_ms,\n status=\"completed\",\n )\n\n import re\n\n json_match = re.search(r\"\\{[\\s\\S]*\\}\", response_text)\n if json_m... [TRUNCATED-fe2b63187fee0b31]",
"structuredPatch": [
{
"oldStart": 456,
"oldLines": 6,
"newStart": 456,
"newLines": 124,
"lines": [
" }",
" ",
" ",
"+def analyze_chunk_semantics(chunk_id, content, client=None):",
"+ \"\"\"",
"+ Analyze a single chunk for semantics (summary, keywords, sentiment, topics).",
"+ Stores result in chunk_semantics table.",
"+ \"\"\"",
"+ prompt_template = db.get_prompt(\"chunk_semantics\")",
"+",
"+ if not prompt_template:",
"+ prompt_template = \"\"\"Analysiere diesen Textabschnitt und extrahiere:",
"+",
"+1. **summary**: Eine kurze Zusammenfassung (1-2 Sätze)",
"+2. **keywords**: 3-5 wichtige Schlüsselwörter",
"+3. **sentiment**: Stimmung (positive, negative, neutral, mixed)",
"+4. **topics**: 2-3 Hauptthemen",
"+",
"+Antworte NUR im JSON-Format:",
"+{\"summary\": \"...\", \"keywords\": [\"...\", \"...\"], \"sentiment\": \"neutral\", \"topics\": [\"...\", \"...\"]}",
"+",
"+Text:",
"+{{TEXT}}\"\"\"",
"+",
"+ prompt = prompt_template.replace(\"{{TEXT}}\", content[:2000])",
"+",
"+ try:",
"+ start_time = time.time()",
"+ tokens_in, tokens_out = 0, 0",
"+ model_name = \"\"",
"+",
"+ if client:",
"+ message = client.messages.create(",
"+ model=ANTHROPIC_MODEL, max_tokens=500, messages=[{\"role\": \"user\", \"content\": prompt}]",
"+ )",
"+ response_text = message.content[0].text",
"+ tokens_in = message.usage.input_tokens",
"+ tokens_out = message.usage.output_tokens",
"+ model_name = ANTHROPIC_MODEL",
"+ else:",
"+ response = requests.post(",
"+ f\"{OLLAMA_HOST}\/api\/generate\",",
"+ json={\"model\": OLLAMA_CHAT_MODEL, \"prompt\": prompt, \"stream\": False, \"format\": \"json\"},",
"+ timeout=60,",
"+ )",
"+ response.raise_for_status()",
"+ data = response.json()",
"+ response_text = data.get(\"response\", \"{}\")",
"+ tokens_in = data.get(\"prompt_eval_count\", 0)",
"+ tokens_out = data.get(\"eval_count\", 0)",
"+ model_name = f\"ollama:{OLLAMA_CHAT_MODEL}\"",
"+",
"+ duration_ms = int((time.time() - start_time) * 1000)",
"+",
"+ # Log to ki-protokoll",
"+ protokoll.log_llm_call(",
"+ request=f\"[chunk_semantics] chunk_id={chunk_id}\",",
"+ response=response_text[:1000],",
"+ model_name=model_name,",
"+ tokens_input=tokens_in,",
"+ tokens_output=tokens_out,",
"+ duration_ms=duration_ms,",
"+ status=\"completed\",",
"+ )",
"+",
"+ # Parse JSON",
"+ import re",
"+ json_match = re.search(r\"\\{[\\s\\S]*\\}\", response_text)",
"+ if json_match:",
"+ result = json.loads(json_match.group())",
"+",
"+ # Store in chunk_semantics",
"+ cursor = db.execute(",
"+ \"\"\"INSERT INTO chunk_semantics",
"+ (chunk_id, summary, keywords, sentiment, topics, language, analyzed_at, analysis_model)",
"+ VALUES (%s, %s, %s, %s, %s, 'de', NOW(), %s)",
"+ ON DUPLICATE KEY UPDATE",
"+ summary = VALUES(summary), keywords = VALUES(keywords),",
"+ sentiment = VALUES(sentiment), topics = VALUES(topics),",
"+ analyzed_at = NOW(), analysis_model = VALUES(analysis_model)\"\"\",",
"+ (",
"+ chunk_id,",
"+ result.get(\"summary\", \"\"),",
"+ json.dumps(result.get(\"keywords\", []), ensure_ascii=False),",
"+ result.get(\"sentiment\", \"neutral\"),",
"+ json.dumps(result.get(\"topics\", []), ensure_ascii=False),",
"+ model_name,",
"+ ),",
"+ )",
"+ db.commit()",
"+ cursor.close()",
"+ return result",
"+",
"+ return None",
"+",
"+ except Exception as e:",
"+ db.log(\"ERROR\", f\"Chunk semantics analysis failed: {e}\")",
"+ return None",
"+",
"+",
"+def analyze_chunks_semantics(document_id, client=None):",
"+ \"\"\"Analyze all chunks of a document for semantics.\"\"\"",
"+ cursor = db.execute(",
"+ \"SELECT id, content FROM chunks WHERE document_id = %s ORDER BY chunk_index\",",
"+ (document_id,)",
"+ )",
"+ chunks = cursor.fetchall()",
"+ cursor.close()",
"+",
"+ db.log(\"INFO\", f\"Analyzing semantics for {len(chunks)} chunks\")",
"+",
"+ analyzed = 0",
"+ for chunk in chunks:",
"+ result = analyze_chunk_semantics(chunk[\"id\"], chunk[\"content\"], client)",
"+ if result:",
"+ analyzed += 1",
"+",
"+ db.log(\"INFO\", f\"Analyzed {analyzed}\/{len(chunks)} chunks for semantics\")",
"+ return analyzed",
"+",
"+",
" if __name__ == \"__main__\":",
" test_text = \"\"\"",
" Carl Rogers entwickelte die klientenzentrierte Gesprächstherapie."
]
}
],
"userModified": false,
"replaceAll": false
}
}