optimize msh layouts

This commit is contained in:
team2
2026-04-25 21:34:55 +02:00
parent 06aef93d24
commit c90675d17d
4 changed files with 181 additions and 9 deletions

View File

@@ -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 '<div class="retriex-meta-card retriex-shop-meta">'
. '<div class="retriex-meta-card__eyebrow">Live-Shopdaten</div>'
. '<div class="retriex-meta-card__title">Shopware-Suche wird ausgeführt</div>'
. '<div class="retriex-meta-card__body">'
. '<span class="retriex-meta-pill">' . htmlspecialchars($badge, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8') . '</span>'
. '<span class="retriex-meta-pill">Intent: ' . htmlspecialchars($intentLabel, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8') . '</span>'
. '</div>'
. '<div class="retriex-meta-query"><span>Gesendete Suchquery</span><code>'
. htmlspecialchars($query, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8')
. '</code></div>'
. '</div>';
}
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 '<div class="retriex-alert retriex-alert--warning">'
. '<div class="retriex-alert__icon">⚠️</div>'
. '<div class="retriex-alert__content">'
. '<div class="retriex-alert__title">Shopdaten konnten nicht geladen werden</div>'
. '<div class="retriex-alert__text">RetrieX antwortet ohne Live-Shopdaten weiter. Ursache: '
. htmlspecialchars($reason, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8')
. '. Ich antworte ohne Shopdaten weiter.';
. '</div>'
. '</div>'
. '</div>';
}
private function normalizeOneLine(string $value): string
{
$value = trim($value);
return preg_replace('/\s+/u', ' ', $value) ?? $value;
}
private function buildUserErrorMessage(Throwable $e): string
{
$message = trim($e->getMessage());
@@ -847,6 +904,7 @@ final readonly class AgentRunner
'err' => sprintf($this->agentRunnerConfig->getErrorHtmlTemplate(), $msg),
'think' => sprintf($this->agentRunnerConfig->getThinkHtmlTemplate(), $msg),
'info' => sprintf($this->agentRunnerConfig->getInfoHtmlTemplate(), $msg),
'meta' => $msg,
'debug' => sprintf(
$this->agentRunnerConfig->getDebugHtmlTemplate(),
htmlspecialchars($msg, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8')

View File

@@ -48,6 +48,18 @@ final class ShopSearchService
return $this->lastSearchFailureReason;
}
public function buildSearchQueryPreview(
string $originalPrompt,
string $commerceIntent,
string $commerceHistoryContext = ''
): CommerceSearchQuery {
return $this->queryParser->parse(
$originalPrompt,
$commerceIntent,
$commerceHistoryContext
);
}
/**
* @return ShopProductResult[]
*/

View File

@@ -150,7 +150,7 @@ final class AgentRunnerConfig
public function getErrorHtmlTemplate(): string
{
return '<span class="text-danger">%s</span>' . "\n<hr>\n";
return '<div class="retriex-alert retriex-alert--error"><div class="retriex-alert__icon">❌</div><div class="retriex-alert__content"><div class="retriex-alert__title">Hinweis</div><div class="retriex-alert__text">%s</div></div></div>' . "\n";
}
public function getThinkHtmlTemplate(): string