Backup #41
| ID | 41 |
| Dateipfad | /var/www/dev.campus.systemische-tools.de/src/Controller/Api/ChatController.php |
| Version | 1 |
| Typ |
modified |
| Größe | 5.3 KB |
| Hash | e331c9c192c479aa0892463d1a0138d5a0035a5d255b626cbbb8b7343eab4346 |
| Datum | 2025-12-20 17:24:51 |
| Geändert von | claude-code-hook |
| Grund | Claude Code Pre-Hook Backup vor Edit-Operation |
| Datei existiert |
Ja
|
Dateiinhalt
<?php
namespace Controller\Api;
use Framework\Controller;
use Infrastructure\AI\AIConfig;
use Infrastructure\AI\ChatService;
use Infrastructure\AI\OllamaService;
use Infrastructure\AI\QdrantService;
class ChatController extends Controller
{
private ChatService $chatService;
private OllamaService $ollamaService;
private QdrantService $qdrantService;
public function __construct()
{
$config = AIConfig::fromCredentialsFile();
$this->chatService = $config->createChatService();
$this->ollamaService = $config->createOllamaService();
$this->qdrantService = $config->createQdrantService();
}
/**
* POST /api/v1/chat
* Handle chat message
*/
public function send(): void
{
$input = json_decode(file_get_contents('php://input'), true);
$question = trim($input['message'] ?? '');
if ($question === '') {
$this->json(['error' => 'Keine Frage angegeben'], 400);
return;
}
try {
$result = $this->askChat($question);
$this->json($result);
} catch (\Exception $e) {
$this->json(['error' => $e->getMessage()], 500);
}
}
/**
* GET /api/v1/chat/search
* Search for relevant chunks
*/
public function search(): void
{
$query = trim($_GET['q'] ?? '');
$limit = (int) ($_GET['limit'] ?? 5);
if ($query === '') {
$this->json(['error' => 'Keine Suchanfrage'], 400);
return;
}
try {
$results = $this->searchChunks($query, $limit);
$this->json(['results' => $results]);
} catch (\Exception $e) {
$this->json(['error' => $e->getMessage()], 500);
}
}
/**
* GET /api/v1/chat/stats
* Get chat/document statistics (Doc2Vector Pipeline)
*/
public function stats(): void
{
try {
$pdo = $this->getDatabase();
$stats = [
'dokumente' => (int) $pdo->query('SELECT COUNT(*) FROM dokumentation WHERE depth = 0')->fetchColumn(),
'seiten' => (int) $pdo->query('SELECT COUNT(*) FROM dokumentation WHERE depth > 0')->fetchColumn(),
'chunks' => (int) $pdo->query('SELECT COUNT(*) FROM dokumentation_chunks')->fetchColumn(),
'tokens' => (int) $pdo->query('SELECT COALESCE(SUM(token_count), 0) FROM dokumentation_chunks')->fetchColumn(),
'analyzed' => (int) $pdo->query("SELECT COUNT(*) FROM dokumentation_chunks WHERE analysis_status = 'completed'")->fetchColumn(),
'synced' => (int) $pdo->query('SELECT COUNT(*) FROM dokumentation_chunks WHERE qdrant_id IS NOT NULL')->fetchColumn(),
];
$this->json($stats);
} catch (\Exception $e) {
$this->json(['error' => $e->getMessage()], 500);
}
}
/**
* Ask chat question using ChatService
*
* @param string $question User's question
*
* @return array<string, mixed> Chat response with answer and sources
*
* @throws \RuntimeException If chat service fails
*/
private function askChat(string $question): array
{
try {
// Use dokumentation_chunks collection for RAG
return $this->chatService->chat($question, 'claude-opus-4-5-20251101', 'dokumentation_chunks', 5);
} catch (\RuntimeException $e) {
throw new \RuntimeException('Chat-Service konnte nicht ausgeführt werden: ' . $e->getMessage(), 0, $e);
}
}
/**
* Search for similar chunks using vector search
*
* @param string $query Search query
* @param int $limit Maximum number of results
*
* @return array<int, array{id: int|string, score: float, payload: array<string, mixed>}> Search results
*
* @throws \RuntimeException If search fails
*/
private function searchChunks(string $query, int $limit): array
{
try {
$queryEmbedding = $this->ollamaService->getEmbedding($query);
// Use dokumentation_chunks collection
return $this->qdrantService->search($queryEmbedding, 'dokumentation_chunks', $limit);
} catch (\RuntimeException $e) {
throw new \RuntimeException('Suche konnte nicht ausgeführt werden: ' . $e->getMessage(), 0, $e);
}
}
/**
* Get database connection
*/
private function getDatabase(): \PDO
{
$credentials = $this->loadCredentials();
return new \PDO(
'mysql:host=localhost;dbname=ki_content;charset=utf8mb4',
'root',
$credentials['db_password'],
[\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION]
);
}
/**
* Load credentials from file
*/
private function loadCredentials(): array
{
$file = '/var/www/docs/credentials/credentials.md';
$content = file_get_contents($file);
$password = '';
foreach (explode("\n", $content) as $line) {
if (str_contains($line, 'MariaDB') && str_contains($line, 'root')) {
$parts = explode('|', $line);
if (count($parts) >= 4) {
$password = trim($parts[3]);
break;
}
}
}
return ['db_password' => $password];
}
}
Vollständig herunterladen
Aktionen
Andere Versionen dieser Datei
| ID |
Version |
Typ |
Größe |
Datum |
| 2122 |
17 |
modified |
5.0 KB |
2025-12-29 09:18 |
| 2121 |
16 |
modified |
4.9 KB |
2025-12-29 09:18 |
| 2033 |
15 |
modified |
4.9 KB |
2025-12-28 23:24 |
| 2032 |
14 |
modified |
4.8 KB |
2025-12-28 23:24 |
| 2031 |
13 |
modified |
4.7 KB |
2025-12-28 23:23 |
| 1243 |
12 |
modified |
4.7 KB |
2025-12-25 12:34 |
| 1233 |
11 |
modified |
4.2 KB |
2025-12-25 12:33 |
| 704 |
10 |
modified |
4.1 KB |
2025-12-23 07:53 |
| 620 |
9 |
modified |
4.6 KB |
2025-12-23 04:43 |
| 593 |
8 |
modified |
4.1 KB |
2025-12-23 04:25 |
| 535 |
7 |
modified |
4.3 KB |
2025-12-22 22:19 |
| 534 |
6 |
modified |
4.7 KB |
2025-12-22 22:19 |
| 533 |
5 |
modified |
4.5 KB |
2025-12-22 22:19 |
| 300 |
4 |
modified |
4.5 KB |
2025-12-22 08:04 |
| 299 |
3 |
modified |
4.5 KB |
2025-12-22 08:04 |
| 199 |
2 |
modified |
4.5 KB |
2025-12-21 14:40 |
| 41 |
1 |
modified |
5.3 KB |
2025-12-20 17:24 |
← Zurück zur Übersicht