This commit is contained in:
team 1
2026-05-10 11:17:24 +02:00
parent fad07ce734
commit ee7930ce16
2 changed files with 207 additions and 0 deletions

View File

@@ -315,6 +315,26 @@ final readonly class AgentRunner
$optimizedShopQuery = '';
}
$mainDeviceAnchoredShopSearchQuery = $this->guardMainDeviceReferentialShopQueryWithHistoryModelAnchor(
prompt: $originalPrompt,
shopSearchQuery: $shopSearchQuery,
commerceHistoryContext: $shopQueryHistoryContext
);
if ($mainDeviceAnchoredShopSearchQuery !== $shopSearchQuery) {
$this->agentLogger->info('Enriched referential main-device shop query with history model anchor', [
'userId' => $userId,
'prompt' => $prompt,
'routingPrompt' => $routingPrompt,
'optimizedShopQuery' => $optimizedShopQuery,
'shopSearchQuery' => $shopSearchQuery,
'mainDeviceAnchoredShopSearchQuery' => $mainDeviceAnchoredShopSearchQuery,
]);
$shopSearchQuery = $mainDeviceAnchoredShopSearchQuery;
$optimizedShopQuery = '';
}
$ragAnchoredShopSearchQuery = $this->enrichShopSearchQueryWithRagAnchor(
prompt: $originalPrompt,
shopSearchQuery: $shopSearchQuery,
@@ -2907,6 +2927,149 @@ final readonly class AgentRunner
return $enriched !== '' ? $enriched : $shopSearchQuery;
}
private function guardMainDeviceReferentialShopQueryWithHistoryModelAnchor(
string $prompt,
string $shopSearchQuery,
string $commerceHistoryContext
): string {
$shopSearchQuery = trim($shopSearchQuery);
if (
$shopSearchQuery === ''
|| trim($commerceHistoryContext) === ''
|| $this->referenceAnchorExtractor->extractFirstProductModelAnchor($prompt) !== ''
|| $this->referenceAnchorExtractor->extractFirstProductModelAnchor($shopSearchQuery) !== ''
) {
return $shopSearchQuery;
}
if (!$this->isMainDeviceReferentialShopQueryPrompt($prompt)) {
return $shopSearchQuery;
}
if (!$this->isGenericMainDeviceReferentialShopQuery($shopSearchQuery)) {
return $shopSearchQuery;
}
$modelAnchor = $this->normalizeShopQueryAnchor(
$this->extractLatestHistoryProductModelAnchor($commerceHistoryContext)
);
if ($modelAnchor === '') {
return $shopSearchQuery;
}
return $this->queryAlreadyContainsAllAnchorTokens($shopSearchQuery, $modelAnchor)
? $shopSearchQuery
: $modelAnchor;
}
private function isMainDeviceReferentialShopQueryPrompt(string $prompt): bool
{
$tokens = $this->tokenizeShopQueryCandidate($prompt);
if ($tokens === []) {
return false;
}
$tokenSet = array_fill_keys($tokens, true);
$mainDeviceTokens = $this->buildShopQueryTokenSet(
$this->agentRunnerConfig->getNoLlmMainDeviceRequestRoleKeywords()
);
if (!$this->tokenSetIntersects($tokenSet, $mainDeviceTokens)) {
return false;
}
$accessoryTokens = $this->buildShopQueryTokenSet($this->mergeUniqueStrings(
$this->agentRunnerConfig->getNoLlmAccessoryProductRoleKeywords(),
$this->agentRunnerConfig->getRequestedAccessoryCodeTerms()
));
if ($this->tokenSetIntersects($tokenSet, $accessoryTokens)) {
return false;
}
$referenceTokens = $this->buildShopQueryTokenSet($this->mergeUniqueStrings(
$this->agentRunnerConfig->getShopQueryContextUsageReferentialTerms(),
$this->agentRunnerConfig->getShopQueryMetaOnlyTerms()
));
return $this->tokenSetIntersects($tokenSet, $referenceTokens);
}
private function isGenericMainDeviceReferentialShopQuery(string $shopSearchQuery): bool
{
$tokens = $this->tokenizeShopQueryCandidate($shopSearchQuery);
if ($tokens === []) {
return false;
}
foreach ($tokens as $token) {
if (preg_match('/\d/u', $token) === 1) {
return false;
}
}
$genericTerms = $this->mergeUniqueStrings(
$this->agentRunnerConfig->getNoLlmMainDeviceRequestRoleKeywords(),
$this->agentRunnerConfig->getShopQueryContextUsageReferentialTerms()
);
$genericTerms = $this->mergeUniqueStrings($genericTerms, $this->agentRunnerConfig->getShopQueryMetaOnlyTerms());
$genericTerms = $this->mergeUniqueStrings($genericTerms, $this->agentRunnerConfig->getShopQueryContextFallbackFilterTerms());
$genericTerms = $this->mergeUniqueStrings($genericTerms, $this->agentRunnerConfig->getShopQueryStopwordCleanupTerms());
$genericTokens = $this->buildShopQueryTokenSet($genericTerms);
if ($genericTokens === []) {
return false;
}
$hasMainDeviceToken = false;
$mainDeviceTokens = $this->buildShopQueryTokenSet(
$this->agentRunnerConfig->getNoLlmMainDeviceRequestRoleKeywords()
);
foreach ($tokens as $token) {
if (!isset($genericTokens[$token])) {
return false;
}
if (isset($mainDeviceTokens[$token])) {
$hasMainDeviceToken = true;
}
}
return $hasMainDeviceToken;
}
private function extractLatestHistoryProductModelAnchor(string $commerceHistoryContext): string
{
foreach ($this->extractHistoryTurnsNewestFirst($commerceHistoryContext) as $turn) {
$modelAnchor = $this->referenceAnchorExtractor->extractFirstProductModelAnchor($turn);
if ($modelAnchor !== '') {
return $modelAnchor;
}
}
return '';
}
/**
* @param array<string, true> $left
* @param array<string, true> $right
*/
private function tokenSetIntersects(array $left, array $right): bool
{
foreach ($left as $token => $_) {
if (isset($right[$token])) {
return true;
}
}
return false;
}
private function extractReferentialShopQueryTriggerTerms(string $text): string
{
$tokens = $this->tokenizeShopQueryCandidate($text);