fix p49
This commit is contained in:
@@ -500,6 +500,14 @@ parameters:
|
||||
|
||||
direct_result_guard:
|
||||
enabled: true
|
||||
compound_prefix_match:
|
||||
enabled: true
|
||||
# Some Shopware product names combine the requested product type with
|
||||
# a noun suffix, for example "pH-Pufferlösung". Keep this list small
|
||||
# and explicit so broad direct-result filtering remains safe.
|
||||
terms:
|
||||
- puffer
|
||||
- kalibrierpuffer
|
||||
|
||||
length_sort:
|
||||
enabled: true
|
||||
|
||||
@@ -292,26 +292,6 @@ final readonly class AgentRunner
|
||||
$optimizedShopQuery = '';
|
||||
}
|
||||
|
||||
$referentialAnchoredShopSearchQuery = $this->guardReferentialShopQueryFallbackWithHistoryAnchor(
|
||||
prompt: $originalPrompt,
|
||||
shopSearchQuery: $shopSearchQuery,
|
||||
commerceHistoryContext: $shopQueryHistoryContext
|
||||
);
|
||||
|
||||
if ($referentialAnchoredShopSearchQuery !== $shopSearchQuery) {
|
||||
$this->agentLogger->info('Enriched referential shop fallback query with history anchor', [
|
||||
'userId' => $userId,
|
||||
'prompt' => $prompt,
|
||||
'routingPrompt' => $routingPrompt,
|
||||
'optimizedShopQuery' => $optimizedShopQuery,
|
||||
'shopSearchQuery' => $shopSearchQuery,
|
||||
'referentialAnchoredShopSearchQuery' => $referentialAnchoredShopSearchQuery,
|
||||
]);
|
||||
|
||||
$shopSearchQuery = $referentialAnchoredShopSearchQuery;
|
||||
$optimizedShopQuery = '';
|
||||
}
|
||||
|
||||
$ragAnchoredShopSearchQuery = $this->enrichShopSearchQueryWithRagAnchor(
|
||||
prompt: $originalPrompt,
|
||||
shopSearchQuery: $shopSearchQuery,
|
||||
@@ -2601,83 +2581,6 @@ final readonly class AgentRunner
|
||||
return trim($query);
|
||||
}
|
||||
|
||||
private function guardReferentialShopQueryFallbackWithHistoryAnchor(
|
||||
string $prompt,
|
||||
string $shopSearchQuery,
|
||||
string $commerceHistoryContext
|
||||
): string {
|
||||
if (!$this->agentRunnerConfig->isShopQueryContextAnchorEnrichmentEnabled()) {
|
||||
return $shopSearchQuery;
|
||||
}
|
||||
|
||||
if (trim($commerceHistoryContext) === '') {
|
||||
return $shopSearchQuery;
|
||||
}
|
||||
|
||||
if (!$this->shouldUseCommerceHistoryForShopQuery($prompt)) {
|
||||
return $shopSearchQuery;
|
||||
}
|
||||
|
||||
$combined = trim($shopSearchQuery . ' ' . $prompt);
|
||||
if (!$this->containsConfiguredShopQueryAnchorTrigger($combined)) {
|
||||
return $shopSearchQuery;
|
||||
}
|
||||
|
||||
$anchor = $this->normalizeShopQueryAnchor(
|
||||
$this->extractLatestConfiguredShopQueryContextAnchor($commerceHistoryContext)
|
||||
);
|
||||
|
||||
if ($anchor === '' || $this->queryAlreadyContainsAllAnchorTokens($shopSearchQuery, $anchor)) {
|
||||
return $shopSearchQuery;
|
||||
}
|
||||
|
||||
$referentialQuery = $this->extractReferentialShopQueryTriggerTerms($combined);
|
||||
if ($referentialQuery === '') {
|
||||
return $shopSearchQuery;
|
||||
}
|
||||
|
||||
$template = $this->agentRunnerConfig->getShopQueryContextAnchorEnrichmentTemplate();
|
||||
$enriched = $this->renderAgentTemplate($template, [
|
||||
'anchor' => $anchor,
|
||||
'query' => $referentialQuery,
|
||||
]);
|
||||
$enriched = preg_replace('/\s+/u', ' ', $enriched) ?? $enriched;
|
||||
$enriched = trim($enriched);
|
||||
|
||||
return $enriched !== '' ? $enriched : $shopSearchQuery;
|
||||
}
|
||||
|
||||
private function extractReferentialShopQueryTriggerTerms(string $text): string
|
||||
{
|
||||
$tokens = $this->tokenizeShopQueryCandidate($text);
|
||||
|
||||
if ($tokens === []) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$triggerTokens = [];
|
||||
foreach ($this->agentRunnerConfig->getShopQueryContextAnchorEnrichmentTriggerTerms() as $term) {
|
||||
foreach ($this->tokenizeShopQueryCandidate($term) as $termToken) {
|
||||
$triggerTokens[$termToken] = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($triggerTokens === []) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$out = [];
|
||||
foreach ($tokens as $token) {
|
||||
if (!isset($triggerTokens[$token]) || isset($out[$token])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$out[$token] = $token;
|
||||
}
|
||||
|
||||
return implode(' ', array_values($out));
|
||||
}
|
||||
|
||||
private function enrichReferentialShopQueryFromHistory(
|
||||
string $query,
|
||||
string $sourcePrompt,
|
||||
@@ -3339,6 +3242,69 @@ final readonly class AgentRunner
|
||||
if ($this->containsAllShopQueryTokens($productText, $term)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->containsAllShopQueryTokensWithCompoundPrefixes($productText, $term)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function containsAllShopQueryTokensWithCompoundPrefixes(string $text, string $term): bool
|
||||
{
|
||||
if (!$this->agentRunnerConfig->isDirectShopResultGuardCompoundPrefixMatchEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$tokens = $this->tokenizeShopQueryCandidate($text);
|
||||
$termTokens = $this->tokenizeShopQueryCandidate($term);
|
||||
|
||||
if ($tokens === [] || $termTokens === []) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$exactTokens = array_fill_keys($tokens, true);
|
||||
|
||||
foreach ($termTokens as $termToken) {
|
||||
if (isset($exactTokens[$termToken])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!$this->directProductTermAllowsCompoundPrefixMatch($termToken)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$matchedPrefix = false;
|
||||
$termTokenLength = mb_strlen($termToken, 'UTF-8');
|
||||
|
||||
foreach ($tokens as $token) {
|
||||
if (mb_strlen($token, 'UTF-8') <= $termTokenLength) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mb_substr($token, 0, $termTokenLength, 'UTF-8') === $termToken) {
|
||||
$matchedPrefix = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$matchedPrefix) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function directProductTermAllowsCompoundPrefixMatch(string $termToken): bool
|
||||
{
|
||||
foreach ($this->agentRunnerConfig->getDirectShopResultGuardCompoundPrefixTerms() as $configuredTerm) {
|
||||
foreach ($this->tokenizeShopQueryCandidate($configuredTerm) as $configuredToken) {
|
||||
if ($termToken === $configuredToken) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -1140,6 +1140,19 @@ final class AgentRunnerConfig
|
||||
return $this->getRequiredBool('shop_prompt.direct_result_guard.enabled');
|
||||
}
|
||||
|
||||
public function isDirectShopResultGuardCompoundPrefixMatchEnabled(): bool
|
||||
{
|
||||
return $this->getOptionalBool('shop_prompt.direct_result_guard.compound_prefix_match.enabled', false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getDirectShopResultGuardCompoundPrefixTerms(): array
|
||||
{
|
||||
return $this->getOptionalStringList('shop_prompt.direct_result_guard.compound_prefix_match.terms');
|
||||
}
|
||||
|
||||
public function isShopResultLengthSortEnabled(): bool
|
||||
{
|
||||
return $this->getRequiredBool('shop_prompt.length_sort.enabled');
|
||||
|
||||
Reference in New Issue
Block a user