rm CachedRetriever.php

add second shopsearch
This commit is contained in:
team 1
2026-04-19 14:20:23 +02:00
parent a71426c300
commit 4d944a5113
9 changed files with 1075 additions and 129 deletions

View File

@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace App\Agent;
use App\Commerce\SearchRepairService;
use App\Commerce\ShopSearchService;
use App\Config\AgentRunnerConfig;
use App\Context\ContextService;
@@ -28,6 +29,7 @@ final readonly class AgentRunner
private UrlAnalyzer $urlAnalyzer,
private RetrieverInterface $retriever,
private ShopSearchService $shopSearchService,
private SearchRepairService $searchRepairService,
private CommerceIntentLite $commerceIntentLite,
private OllamaClient $ollamaClient,
private LoggerInterface $agentLogger,
@@ -49,20 +51,21 @@ final readonly class AgentRunner
}
$shopResults = [];
$primaryShopResults = [];
$sources = [];
$optimizedShopQuery = '';
$shopSearchQuery = '';
$commerceIntent = CommerceIntentLite::NONE;
$commerceHistoryContext = '';
$attemptedShopRepair = false;
$usedShopRepair = false;
$shopRepairQueries = [];
$this->agentLogger->info('Agent run started', [
'userId' => $userId,
]);
try {
// ---------------------------------------------------------
// 1) Context strategy
// ---------------------------------------------------------
if ($includeFullContext) {
// Full context mode is already passed to PromptBuilder.
// Additional context strategies can be added here later.
@@ -70,9 +73,6 @@ final readonly class AgentRunner
yield $this->systemMsg('Ich analysiere deine Anfrage...', 'think');
// ---------------------------------------------------------
// 2) Extract URL content
// ---------------------------------------------------------
yield $this->systemMsg('Ich prüfe auf Internetquellen...', 'think');
$urlContent = $this->urlAnalyzer->extractContentFromPrompt($prompt);
@@ -80,9 +80,6 @@ final readonly class AgentRunner
$this->addSource($sources, 'Externe URL');
}
// ---------------------------------------------------------
// 3) Retrieve RAG knowledge
// ---------------------------------------------------------
yield $this->systemMsg('Ich hole relevante Daten aus meinem RAG-Wissen...', 'think');
$knowledgeChunks = $this->retriever->retrieve($prompt);
@@ -90,9 +87,6 @@ final readonly class AgentRunner
$this->addSource($sources, 'RAG Wissen');
}
// ---------------------------------------------------------
// 4) Optional commerce/shop search
// ---------------------------------------------------------
$commerceIntent = $this->detectCommerceIntent($prompt);
if ($this->isCommerceIntent($commerceIntent)) {
@@ -127,16 +121,35 @@ final readonly class AgentRunner
'think'
);
$shopResults = $this->searchShop(
$primaryShopResults = $this->searchShop(
$shopSearchQuery,
$commerceIntent,
$userId,
$commerceHistoryContext
);
$repairPayload = $this->repairShopResults(
prompt: $prompt,
userId: $userId,
commerceIntent: $commerceIntent,
commerceHistoryContext: $commerceHistoryContext,
primaryQuery: $shopSearchQuery,
primaryShopResults: $primaryShopResults,
knowledgeChunks: $knowledgeChunks
);
$shopResults = $repairPayload['results'];
$attemptedShopRepair = $repairPayload['attemptedRepair'];
$usedShopRepair = $repairPayload['usedRepair'];
$shopRepairQueries = $repairPayload['repairQueries'];
if ($shopResults !== []) {
$this->addSource($sources, 'Shopsystem');
}
if ($attemptedShopRepair) {
$this->addSource($sources, 'Erweiterte Shopsuche');
}
}
if ($shopResults !== []) {
@@ -145,9 +158,6 @@ final readonly class AgentRunner
yield $this->systemMsg('Ich analysiere alle Informationen...', 'think');
// ---------------------------------------------------------
// 5) Build final prompt
// ---------------------------------------------------------
$finalPrompt = $this->promptBuilder->build(
prompt: $prompt,
userId: $userId,
@@ -164,6 +174,11 @@ final readonly class AgentRunner
'finalPrompt' => $finalPrompt,
'optimizedShopQuery' => $optimizedShopQuery,
'shopSearchQuery' => $shopSearchQuery,
'primaryShopResultsCount' => count($primaryShopResults),
'shopResultsCount' => count($shopResults),
'attemptedShopRepair' => $attemptedShopRepair,
'usedShopRepair' => $usedShopRepair,
'shopRepairQueries' => $shopRepairQueries,
]);
}
@@ -181,9 +196,6 @@ final readonly class AgentRunner
yield $this->emitSources($sources, 'Genutzte Quellen: ');
}
// ---------------------------------------------------------
// 6) Stream final LLM answer
// ---------------------------------------------------------
$fullOutput = yield from $this->streamFinalAnswer($finalPrompt);
if ($sources !== []) {
@@ -194,9 +206,6 @@ final readonly class AgentRunner
yield $this->systemMsg($finalPrompt, 'debug');
}
// ---------------------------------------------------------
// 7) Persist conversation history
// ---------------------------------------------------------
if ($fullOutput !== '') {
$this->contextService->appendHistory(
$userId,
@@ -210,7 +219,11 @@ final readonly class AgentRunner
'outputLength' => mb_strlen($fullOutput),
'contextMode' => $includeFullContext ? 'full' : 'recent',
'commerceIntent' => $commerceIntent,
'primaryShopResultsCount' => count($primaryShopResults),
'shopResultsCount' => count($shopResults),
'attemptedShopRepair' => $attemptedShopRepair,
'usedShopRepair' => $usedShopRepair,
'shopRepairQueries' => $shopRepairQueries,
'knowledgeChunkCount' => count($knowledgeChunks),
'hasUrlContent' => $urlContent !== '',
'usedOptimizedShopQuery' => $optimizedShopQuery !== '',
@@ -282,7 +295,51 @@ final readonly class AgentRunner
return '';
}
return trim($optimizedQuery);
return $this->sanitizeOptimizedShopQuery($optimizedQuery);
}
/**
* @return array{
* results: array,
* attemptedRepair: bool,
* usedRepair: bool,
* repairQueries: string[]
* }
*/
private function repairShopResults(
string $prompt,
string $userId,
string $commerceIntent,
string $commerceHistoryContext,
string $primaryQuery,
array $primaryShopResults,
array $knowledgeChunks
): array {
try {
return $this->searchRepairService->repair(
prompt: $prompt,
commerceIntent: $commerceIntent,
commerceHistoryContext: $commerceHistoryContext,
primaryQuery: $primaryQuery,
primaryShopResults: $primaryShopResults,
knowledgeChunks: $knowledgeChunks
);
} catch (Throwable $e) {
$this->agentLogger->warning('Shop repair failed, continuing with primary shop results', [
'userId' => $userId,
'commerceIntent' => $commerceIntent,
'primaryQuery' => $primaryQuery,
'primaryShopResultsCount' => count($primaryShopResults),
'exception' => $e,
]);
return [
'results' => $primaryShopResults,
'attemptedRepair' => false,
'usedRepair' => false,
'repairQueries' => [],
];
}
}
private function searchShop(
@@ -328,6 +385,22 @@ final readonly class AgentRunner
};
}
private function sanitizeOptimizedShopQuery(string $query): string
{
$query = trim($query);
if ($query === '') {
return '';
}
$query = preg_split('/\R+/u', $query, 2)[0] ?? $query;
$query = preg_replace('/^(?:keywords?|suchquery|search\s*query|query)\s*:\s*/iu', '', $query) ?? $query;
$query = trim($query, " \t\n\r\0\x0B\"'`");
$query = preg_replace('/\s+/u', ' ', $query) ?? $query;
return trim($query);
}
/**
* @return Generator<int, string, mixed, string>
*/