Backup #396
| ID | 396 |
| Dateipfad | /var/www/dev.campus.systemische-tools.de/src/UseCases/Chat/SendChatMessageUseCase.php |
| Version | 1 |
| Typ |
modified |
| Größe | 7.1 KB |
| Hash | 366c831a036390e8249f00cec68bcccaffab0f42d6ef417ffcfb592de2e7c969 |
| Datum | 2025-12-22 08:47:03 |
| Geändert von | claude-code-hook |
| Grund | Claude Code Pre-Hook Backup vor Edit-Operation |
| Datei existiert |
Ja
|
Dateiinhalt
<?php
namespace UseCases\Chat;
use Infrastructure\AI\ChatService;
use Infrastructure\Persistence\ChatMessageRepository;
use Infrastructure\Persistence\ChatSessionRepository;
use Infrastructure\Persistence\ContentConfigRepository;
/**
* SendChatMessageUseCase - Orchestrates sending a chat message
*
* Handles:
* - Validating session exists
* - Saving user message
* - Auto-setting session title from first message
* - Getting AI response with context
* - Saving assistant message with tracking data
*/
class SendChatMessageUseCase
{
private ChatService $chatService;
private ChatSessionRepository $sessionRepo;
private ChatMessageRepository $messageRepo;
private ContentConfigRepository $configRepo;
public function __construct(
?ChatService $chatService = null,
?ChatSessionRepository $sessionRepo = null,
?ChatMessageRepository $messageRepo = null,
?ContentConfigRepository $configRepo = null
) {
$this->chatService = $chatService ?? $this->createDefaultChatService();
$this->sessionRepo = $sessionRepo ?? new ChatSessionRepository();
$this->messageRepo = $messageRepo ?? new ChatMessageRepository();
$this->configRepo = $configRepo ?? new ContentConfigRepository();
}
/**
* Execute the use case
*
* @param string $sessionUuid Session UUID
* @param string $message User message text
* @param string $model AI model identifier
* @param array<string> $collections Qdrant collections to search
* @param int $contextLimit Number of context chunks
* @param int $authorProfileId Author profile ID (0 = none)
* @param int $systemPromptId System prompt config ID
* @param float $temperature AI temperature setting
* @param int $maxTokens Max tokens for response
* @return ChatResponse
*/
public function execute(
string $sessionUuid,
string $message,
string $model,
array $collections = ['documents'],
int $contextLimit = 5,
int $authorProfileId = 0,
int $systemPromptId = 1,
float $temperature = 0.7,
int $maxTokens = 4096
): ChatResponse {
// 1. Validate session
$session = $this->sessionRepo->findByUuid($sessionUuid);
if ($session === null) {
return ChatResponse::error('Session nicht gefunden.');
}
// 2. Validate message
$message = trim($message);
if ($message === '') {
return ChatResponse::error('Bitte gib eine Frage ein.');
}
// 3. Save user message
$this->messageRepo->save(
sessionId: $session['id'],
role: 'user',
content: $message,
model: $model
);
// 4. Auto-set title from first message
if ($session['title'] === null) {
$title = mb_substr($message, 0, 50) . (mb_strlen($message) > 50 ? '...' : '');
$this->sessionRepo->updateTitle($session['id'], $title);
}
// 5. Get style prompt from author profile
$stylePrompt = $this->getStylePromptFromProfile($authorProfileId);
// 6. Get system prompt
$systemPrompt = $this->getSystemPromptById($systemPromptId);
// 7. Track timing and get AI response
$startTime = microtime(true);
try {
$result = $this->chatService->chat(
question: $message,
model: $model,
collections: $collections,
limit: $contextLimit,
stylePrompt: $stylePrompt,
customSystemPrompt: $systemPrompt,
temperature: $temperature,
maxTokens: $maxTokens
);
} catch (\Exception $e) {
return ChatResponse::error('Chat-Service Fehler: ' . $e->getMessage());
}
$endTime = microtime(true);
// 8. Check for error in response
if (isset($result['error'])) {
return ChatResponse::error($result['error']);
}
// 9. Save assistant message with tracking
$collectionsJson = json_encode($collections);
$this->messageRepo->save(
sessionId: $session['id'],
role: 'assistant',
content: $result['answer'] ?? '',
model: $model,
tokensInput: $result['usage']['input_tokens'] ?? null,
tokensOutput: $result['usage']['output_tokens'] ?? null,
sources: $result['sources'] ?? null,
startMicrotime: $startTime,
endMicrotime: $endTime,
authorProfileId: $authorProfileId > 0 ? $authorProfileId : null,
systemPromptId: $systemPromptId > 0 ? $systemPromptId : null,
collectionsJson: $collectionsJson,
contextLimit: $contextLimit
);
// 10. Return response
return ChatResponse::fromServiceResponse($result, $endTime - $startTime);
}
/**
* Create default ChatService from credentials
*/
private function createDefaultChatService(): ChatService
{
$config = \Infrastructure\AI\AIConfig::fromCredentialsFile();
return $config->createChatService();
}
/**
* Get style prompt from author profile
*/
private function getStylePromptFromProfile(int $profileId): ?string
{
if ($profileId === 0) {
return null;
}
$profile = $this->configRepo->findByIdAndType($profileId, 'author_profile');
if ($profile === null) {
return null;
}
$config = json_decode($profile['content'] ?? '{}', true);
if ($config === null) {
return null;
}
$parts = [];
if (isset($config['stimme']['ton'])) {
$parts[] = 'Ton: ' . $config['stimme']['ton'];
}
if (isset($config['stimme']['perspektive'])) {
$parts[] = 'Perspektive: ' . $config['stimme']['perspektive'];
}
if (isset($config['stil']['fachsprache']) && $config['stil']['fachsprache']) {
$parts[] = 'Verwende Fachsprache';
}
if (isset($config['stil']['beispiele']) && $config['stil']['beispiele'] === 'häufig') {
$parts[] = 'Nutze häufig Beispiele';
}
if (isset($config['stil']['listen']) && $config['stil']['listen'] === 'bevorzugt') {
$parts[] = 'Bevorzuge Listen und Bullet-Points';
}
if (isset($config['tabus']) && is_array($config['tabus'])) {
$parts[] = 'Vermeide: ' . implode(', ', $config['tabus']);
}
if ($parts === []) {
return null;
}
return 'Schreibstil (' . ($profile['name'] ?? 'Profil') . '): ' . implode('. ', $parts) . '.';
}
/**
* Get system prompt by ID
*/
private function getSystemPromptById(int $promptId): ?string
{
if ($promptId === 0) {
return null;
}
$prompt = $this->configRepo->findByIdAndType($promptId, 'system_prompt');
if ($prompt === null) {
return null;
}
$content = json_decode($prompt['content'] ?? '{}', true);
return $content['prompt'] ?? null;
}
}
Vollständig herunterladen
Aktionen
Andere Versionen dieser Datei
| ID |
Version |
Typ |
Größe |
Datum |
| 2084 |
27 |
modified |
11.4 KB |
2025-12-29 00:09 |
| 2083 |
26 |
modified |
11.4 KB |
2025-12-29 00:09 |
| 2082 |
25 |
modified |
11.4 KB |
2025-12-29 00:08 |
| 2081 |
24 |
modified |
11.5 KB |
2025-12-29 00:08 |
| 1947 |
23 |
modified |
11.5 KB |
2025-12-28 02:21 |
| 1946 |
22 |
modified |
11.5 KB |
2025-12-28 02:21 |
| 1945 |
21 |
modified |
11.5 KB |
2025-12-28 02:21 |
| 1944 |
20 |
modified |
11.5 KB |
2025-12-28 02:21 |
| 1943 |
19 |
modified |
11.5 KB |
2025-12-28 02:21 |
| 1942 |
18 |
modified |
11.5 KB |
2025-12-28 02:20 |
| 1941 |
17 |
modified |
11.5 KB |
2025-12-28 02:20 |
| 1614 |
16 |
modified |
9.7 KB |
2025-12-27 01:34 |
| 1131 |
15 |
modified |
9.7 KB |
2025-12-25 09:41 |
| 1130 |
14 |
modified |
9.6 KB |
2025-12-25 09:41 |
| 842 |
13 |
modified |
10.2 KB |
2025-12-23 08:17 |
| 708 |
12 |
modified |
10.4 KB |
2025-12-23 07:54 |
| 568 |
11 |
modified |
10.4 KB |
2025-12-23 03:37 |
| 563 |
10 |
modified |
9.6 KB |
2025-12-23 03:35 |
| 562 |
9 |
modified |
9.4 KB |
2025-12-23 03:35 |
| 561 |
8 |
modified |
9.4 KB |
2025-12-23 03:35 |
| 555 |
7 |
modified |
9.3 KB |
2025-12-23 03:33 |
| 554 |
6 |
modified |
9.2 KB |
2025-12-23 03:33 |
| 549 |
5 |
modified |
7.6 KB |
2025-12-23 02:38 |
| 548 |
4 |
modified |
7.3 KB |
2025-12-23 02:38 |
| 547 |
3 |
modified |
7.2 KB |
2025-12-23 02:38 |
| 471 |
2 |
modified |
7.2 KB |
2025-12-22 14:43 |
| 396 |
1 |
modified |
7.1 KB |
2025-12-22 08:47 |
← Zurück zur Übersicht