diff --git a/public/assets/styles/base.css b/public/assets/styles/base.css index 2a49e9d..2850829 100644 --- a/public/assets/styles/base.css +++ b/public/assets/styles/base.css @@ -463,3 +463,105 @@ span.think { transform: rotate(360deg); } } + +/* RetrieX chat meta/status cards */ +.retriex-meta-card, +.retriex-alert { + margin: 0.65rem 0; + border: 1px solid rgba(134, 183, 254, 0.26); + border-radius: 14px; + background: rgba(13, 17, 23, 0.72); + box-shadow: 0 10px 28px rgba(0, 0, 0, 0.18); +} + +.retriex-meta-card { + padding: 0.85rem 0.95rem; +} + +.retriex-meta-card__eyebrow { + color: #86b7fe; + font-size: 0.72rem; + font-weight: 700; + letter-spacing: 0.08em; + text-transform: uppercase; + margin-bottom: 0.2rem; +} + +.retriex-meta-card__title { + color: #f8f9fa; + font-weight: 700; + margin-bottom: 0.55rem; +} + +.retriex-meta-card__body { + display: flex; + flex-wrap: wrap; + gap: 0.35rem; + margin-bottom: 0.65rem; +} + +.retriex-meta-pill { + display: inline-flex; + align-items: center; + border-radius: 999px; + padding: 0.18rem 0.55rem; + background: rgba(134, 183, 254, 0.14); + color: #cfe2ff; + font-size: 0.78rem; + font-weight: 600; +} + +.retriex-meta-query { + display: grid; + gap: 0.25rem; +} + +.retriex-meta-query span { + color: rgba(248, 249, 250, 0.68); + font-size: 0.78rem; +} + +.retriex-meta-query code { + display: block; + width: 100%; + white-space: pre-wrap; + word-break: break-word; + border-radius: 10px; + padding: 0.45rem 0.55rem; + background: rgba(0, 0, 0, 0.28); + color: #f8f9fa; +} + +.retriex-alert { + display: flex; + gap: 0.75rem; + padding: 0.85rem 0.95rem; +} + +.retriex-alert--warning { + border-color: rgba(255, 193, 7, 0.32); + background: rgba(60, 44, 5, 0.56); +} + +.retriex-alert--error { + border-color: rgba(220, 53, 69, 0.34); + background: rgba(58, 12, 18, 0.56); +} + +.retriex-alert__icon { + flex: 0 0 auto; + font-size: 1.15rem; + line-height: 1.2; +} + +.retriex-alert__title { + color: #f8f9fa; + font-weight: 700; + margin-bottom: 0.15rem; +} + +.retriex-alert__text { + color: rgba(248, 249, 250, 0.82); + font-size: 0.92rem; + line-height: 1.45; +} diff --git a/src/Agent/AgentRunner.php b/src/Agent/AgentRunner.php index c685459..1a6868f 100644 --- a/src/Agent/AgentRunner.php +++ b/src/Agent/AgentRunner.php @@ -122,6 +122,22 @@ final readonly class AgentRunner $shopSearchQuery = $optimizedShopQuery !== '' ? $optimizedShopQuery : $prompt; + $shopQueryPreview = $this->shopSearchService->buildSearchQueryPreview( + $shopSearchQuery, + $commerceIntent, + $commerceHistoryContext + ); + + yield $this->systemMsg( + $this->buildShopSearchMetaMessage( + query: $shopQueryPreview->searchText !== '' ? $shopQueryPreview->searchText : $shopSearchQuery, + commerceIntent: $commerceIntent, + usedOptimizedQuery: $optimizedShopQuery !== '', + originalQuery: $shopSearchQuery + ), + 'meta' + ); + $this->agentLogger->info('Commerce search prepared', [ 'userId' => $userId, 'commerceIntent' => $commerceIntent, @@ -790,25 +806,66 @@ final readonly class AgentRunner } } + private function buildShopSearchMetaMessage( + string $query, + string $commerceIntent, + bool $usedOptimizedQuery, + string $originalQuery + ): string { + $query = $this->normalizeOneLine($query); + $originalQuery = $this->normalizeOneLine($originalQuery); + + if ($query === '') { + $query = $originalQuery !== '' ? $originalQuery : 'keine Suchquery ermittelt'; + } + + $badge = $usedOptimizedQuery ? 'optimiert' : 'direkt'; + $intentLabel = $commerceIntent !== '' ? $commerceIntent : 'commerce'; + + return '
'; + } + private function buildShopUnavailableMessage(?string $reason): string { - $reason = trim((string) $reason); + $reason = $this->normalizeOneLine((string) $reason); if ($reason === '') { - $reason = 'keine Detailmeldung vom Shopware-Server'; + $reason = 'Keine Detailmeldung vom Shopware-Server.'; } - $reason = preg_replace('/\s+/u', ' ', $reason) ?? $reason; - - if (mb_strlen($reason, 'UTF-8') > 260) { - $reason = rtrim(mb_substr($reason, 0, 257, 'UTF-8')) . '...'; + if (mb_strlen($reason, 'UTF-8') > 320) { + $reason = rtrim(mb_substr($reason, 0, 317, 'UTF-8')) . '...'; } - return '⚠️ Shopsystem aktuell nicht erreichbar oder fehlerhaft. Grund: ' + return '