sessionRepo->findByUuid($uuid); if ($session === null) { return null; } $messages = $this->messageRepo->findBySessionId($session->getId() ?? 0); $title = $session->getTitle() ?? 'Chat'; $date = date('d.m.Y H:i'); $model = $session->getModel(); $md = "# {$title}\n"; $md .= "*Exportiert am {$date}*\n"; $md .= "*Modell: {$model}*\n\n"; $md .= "---\n\n"; $questionNum = 0; foreach ($messages as $msg) { if ($msg->role()->isUser()) { $questionNum++; $md .= "## Frage {$questionNum}\n\n"; $md .= $msg->content()->value() . "\n\n"; } else { $md .= "## Antwort {$questionNum}\n\n"; $md .= $msg->content()->value() . "\n\n"; $sources = $msg->metadata()->sources() ?? []; if (!empty($sources)) { $md .= "**Quellen:**\n"; foreach ($sources as $source) { $sourceData = is_string($source) ? json_decode($source, true) : $source; if (!is_array($sourceData)) { continue; } $sourceTitle = $sourceData['title'] ?? 'Unbekannt'; $score = isset($sourceData['score']) ? round((float) $sourceData['score'] * 100) . '%' : ''; $collection = isset($sourceData['collection']) ? "[{$sourceData['collection']}] " : ''; $md .= "- {$collection}{$sourceTitle} ({$score})\n"; } $md .= "\n"; } $md .= "---\n\n"; } } return $md; } /** * Export session as JSON. * * @return array|null */ public function exportAsJson(string $uuid): ?array { $session = $this->sessionRepo->findByUuid($uuid); if ($session === null) { return null; } $messages = $this->messageRepo->findBySessionId($session->getId() ?? 0); $exportMessages = []; foreach ($messages as $msg) { $exportMsg = [ 'role' => $msg->getRole()->value, 'content' => $msg->getContent(), 'created_at' => $msg->getCreatedAt()->format('Y-m-d H:i:s'), ]; if ($msg->getRole()->isAssistant()) { $sources = $msg->getSources() ?? []; $parsedSources = []; foreach ($sources as $source) { $parsedSources[] = is_string($source) ? json_decode($source, true) : $source; } $exportMsg['sources'] = $parsedSources; $exportMsg['tokens'] = [ 'input' => $msg->getTokensInput() ?? 0, 'output' => $msg->getTokensOutput() ?? 0, ]; $exportMsg['model'] = $msg->getModel(); } $exportMessages[] = $exportMsg; } return [ 'session' => [ 'uuid' => $session->getUuid(), 'title' => $session->getTitle() ?? 'Chat', 'created_at' => $session->getCreatedAt()->format('Y-m-d H:i:s'), 'model' => $session->getModel(), 'collections' => $session->getCollections(), ], 'messages' => $exportMessages, 'exported_at' => date('c'), ]; } /** * Generate filename for export. */ public function generateFilename(string $uuid, string $format): string { $session = $this->sessionRepo->findByUuid($uuid); $title = $session?->getTitle() ?? 'chat'; // Sanitize title for filename $title = preg_replace('/[^a-zA-Z0-9äöüÄÖÜß\-_\s]/u', '', $title) ?? ''; $title = preg_replace('/\s+/', '-', trim($title)) ?? ''; $title = mb_substr($title, 0, 50); if ($title === '') { $title = 'chat'; } $date = date('Y-m-d'); $ext = $format === 'json' ? 'json' : 'md'; return "chat-{$title}-{$date}.{$ext}"; } }