patch 20n

This commit is contained in:
team 1
2026-05-03 14:27:45 +02:00
parent a4903104b5
commit 8ec105686e
7 changed files with 6765 additions and 4 deletions

3242
AgentRunner.php Normal file

File diff suppressed because it is too large Load Diff

3199
AgentRunner.php.before_p20n Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,70 @@
# RetrieX Patch p20k - Final Standalone Shop Query Guard
## Ziel
Behebt den Fall, dass eine neue eigenständige Shop-Anfrage wie:
```text
zeige mir Anschlusskabel für pH/Redox
```
nach der Shop-Query-Optimierung fälschlich als alte Kontext-Query wie:
```text
testomat 808 indikator
```
an Shop-Suche und UI-Meta weitergegeben wird.
## Ursache
Der bisherige Guard prüfte den Optimizer-Ausgang zwar im Optimizer-/Resolve-Pfad, aber nicht final direkt vor Preview und Shop-Suche. Wenn später dennoch eine kontextfremde Query in `$shopSearchQuery` landete, wurde sie ungeprüft an `buildSearchQueryPreview()` und `searchShop()` weitergereicht.
## Änderung
Nur `src/Agent/AgentRunner.php` wurde geändert.
Neu:
- finale Validierung direkt nach `resolveShopSearchQuery()`
- vor `buildSearchQueryPreview()` und `searchShop()`
- Wiederverwendung der bestehenden Standalone-Guardlogik
- bei erkannter Kontextverschmutzung wird die Query auf den aktuellen Routing-Prompt zurückgesetzt
- `$optimizedShopQuery` wird geleert, damit UI/Meta nicht weiter „optimiert“ für eine verworfene Query anzeigen
## Erwartung
```text
zeige mir Anschlusskabel für pH/Redox
```
soll nicht mehr als `testomat 808 indikator` gesucht werden, sondern auf Basis des aktuellen Prompts, also sinngemäß:
```text
anschlusskabel ph redox
```
Referenzielle Follow-ups wie:
```text
die tabelle mit preisen
was kostet der indikator
```
dürfen weiterhin Kontext verwenden.
## Checks
Lokal möglich:
```bash
php -l src/Agent/AgentRunner.php
```
Pflichtchecks nach Einspielen:
```bash
bin/console cache:clear
bin/console mto:agent:config:validate
bin/console mto:agent:regression:test
bin/console mto:agent:config:audit-source --details
bin/console mto:agent:config:audit-patterns --details
```
Falls OPcache/PHP-FPM aktiv ist: PHP-FPM bzw. Container neu laden.

View File

@@ -0,0 +1,61 @@
# RetrieX Patch p20l - Original Prompt Shop History Guard
## Ziel
Fix fuer die Regression, bei der eine neue Standalone-Shopfrage wie:
```text
zeige mir Anschlusskabel fuer pH/Redox
```
faelschlich mit altem Verlaufskontext optimiert wurde und dadurch als Shop-Suchquery z. B. `testomat 808 indikator` erzeugte.
## Ursache
Der bisherige Guard pruefte die finale Shop-Suchquery gegen den `routingPrompt`. Dieser kann durch LLM-/Fuzzy-Normalisierung leicht vom Original abweichen. Dadurch konnte eine eigentlich neue Standalone-Anfrage intern wie eine referenzielle Anfrage behandelt werden, und alter Commerce-Verlauf durfte in Optimizer/Query einfliessen.
Besonders kritisch: Die Entscheidung, ob Verlauf fuer die Shop-Query benutzt werden darf, darf nicht von einer normalisierten Variante abhaengen, sondern vom originalen Nutzereingabetext.
## Aenderung
Nur `src/Agent/AgentRunner.php` wurde geaendert.
1. `resolveShopQueryHistoryContext()` verwendet jetzt den `originalPrompt` als Autoritaet fuer die Entscheidung, ob Commerce-History genutzt werden darf.
2. `guardFinalStandaloneShopSearchQuery()` prueft finale Shop-Suchqueries ebenfalls gegen den `originalPrompt`.
3. Wenn eine Standalone-Query fremden Kontext einfuehrt, faellt RetrieX auf den aktuellen `routingPrompt` zurueck, nicht auf alten Verlaufskontext.
## Erwartetes Verhalten
```text
zeige mir Anschlusskabel fuer pH/Redox
```
Erwartete Suchquery sinngemaess:
```text
anschlusskabel ph redox
```
Nicht mehr:
```text
testomat 808 indikator
```
Weiterhin erlaubt:
```text
welche grenzwerte kann der testomat 808 messen
die tabelle mit preisen
```
Dieser Follow-up bleibt referenziell und darf den Verlauf fuer `testomat 808 indikator` nutzen.
## Pflichtchecks nach Einspielen
```bash
bin/console cache:clear
bin/console mto:agent:config:validate
bin/console mto:agent:regression:test
bin/console mto:agent:config:audit-source --details
bin/console mto:agent:config:audit-patterns --details
```
Bei aktivem OPcache/PHP-FPM bitte PHP-FPM bzw. Container neu laden.

View File

@@ -0,0 +1,75 @@
# RetrieX Patch p20m Standalone Shop History Authority Fix
## Ziel
Dieser Patch behebt den Fall, dass eine neue eigenständige Shop-Anfrage wie:
```text
zeige mir Anschlusskabel für pH/Redox
```
trotz fehlender Ähnlichkeit zum aktuellen Prompt mit altem Verlaufskontext zu einer falschen Shop-Suchquery wie:
```text
testomat 808 indikator
```
optimiert wurde.
## Ursache
Die Entscheidung, ob Chatverlauf für die Shop-Query-Optimierung verwendet werden darf, wurde im aktiven Codepfad weiterhin anhand des normalisierten/routing-orientierten Prompts getroffen. Dieser Prompt ist für Intent-Erkennung hilfreich, darf aber nicht die Autorität für History-Carry-over sein.
Zusätzlich konnte der fallback-basierte Query-Resolver nach einer Optimierung nicht konsequent zwischen aktueller Standalone-Anfrage und referenzieller Folgefrage unterscheiden.
## Änderung
Geändert wurde nur:
- `src/Agent/AgentRunner.php`
Konkret:
1. `resolveShopQueryHistoryContext()` entscheidet jetzt anhand des unveränderten `originalPrompt`, ob Shop-History benutzt werden darf.
2. `resolveShopSearchQuery()` nutzt den `originalPrompt` als Autorität für referenzielle History-Fallbacks.
3. Der normalisierte `routingPrompt` bleibt als Current-Prompt-Fallback erhalten, damit Tippfehlerkorrektur/Normalisierung weiterhin für die aktuelle Suchanfrage genutzt werden kann.
4. Der finale Standalone-Guard prüft gegen den `originalPrompt`, nicht gegen den normalisierten Routing-Prompt.
## Erwartetes Verhalten
```text
zeige mir Anschlusskabel für pH/Redox
```
muss eine Query wie:
```text
anschlusskabel ph redox
```
erzeugen, nicht mehr:
```text
testomat 808 indikator
```
Referenzielle Follow-ups wie:
```text
die tabelle mit preisen
```
behalten weiterhin History-Nutzung.
## Prüfungen lokal
- `php -l src/Agent/AgentRunner.php` OK
Symfony-Console-Checks müssen in der Zielumgebung ausgeführt werden:
```bash
bin/console cache:clear
bin/console mto:agent:config:validate
bin/console mto:agent:regression:test
bin/console mto:agent:config:audit-source --details
bin/console mto:agent:config:audit-patterns --details
```
Bei OPcache/PHP-FPM bitte PHP-FPM bzw. Container neu laden.

View File

@@ -0,0 +1,70 @@
# RetrieX Patch 20n - Deterministic Standalone Shop Query Fix
## Purpose
Fixes the persistent context leak where a new standalone shop query such as:
`zeige mir Anschlusskabel für pH/Redox`
was incorrectly sent to the shop as:
`testomat 808 indikator`
## Root cause
The issue was not the shop router itself. The route was already commerce/shop. The unsafe part was that standalone shop queries could still pass through the LLM shop-query optimizer. If the optimizer or later query handling revived previous conversation context, an old Testomat/Indikator topic could become the sent Shopware query even though the current prompt had no overlap with it.
## Fix
For non-referential standalone shop queries with no allowed shop-query history context:
- Skip the LLM shop-query optimizer.
- Use the normalized/current prompt deterministically as the shop search source.
- Let `ShopSearchService` / `CommerceQueryParser` build the final Store API search text from the current prompt only.
- Keep LLM/history optimization enabled for referential follow-ups such as `die tabelle mit preisen` or `was kostet der indikator`.
## Changed file
- `src/Agent/AgentRunner.php`
## Expected behavior
### Standalone shop query
Input:
`zeige mir Anschlusskabel für pH/Redox`
Expected sent query:
`anschlusskabel ph redox` or equivalent current-prompt-only query.
Must not become:
`testomat 808 indikator`
### Explicit product query
Input:
`shop testomat 808`
Expected sent query:
`testomat 808`
### Referential follow-up
Input after a Testomat 808 indicator table:
`die tabelle mit preisen`
Expected behavior:
History is still allowed and may resolve to `testomat 808 indikator`.
## Checks to run after applying
```bash
bin/console cache:clear
bin/console mto:agent:config:validate
bin/console mto:agent:regression:test
bin/console mto:agent:config:audit-source --details
bin/console mto:agent:config:audit-patterns --details
```
If OPcache/PHP-FPM is active, reload PHP-FPM or the container after applying.

View File

@@ -214,7 +214,7 @@ final readonly class AgentRunner
$commerceHistoryContext = $this->buildCommerceHistoryContext($userId, $requestContextHint);
$shopQueryHistoryContext = $this->resolveShopQueryHistoryContext(
prompt: $routingPrompt,
prompt: $originalPrompt,
commerceHistoryContext: $commerceHistoryContext
);
@@ -227,6 +227,7 @@ final readonly class AgentRunner
'userId' => $userId,
'prompt' => $prompt,
'routingPrompt' => $routingPrompt,
'originalPrompt' => $originalPrompt,
'commerceHistoryContextLength' => mb_strlen($commerceHistoryContext),
]);
}
@@ -238,12 +239,32 @@ final readonly class AgentRunner
);
$shopSearchQuery = $this->resolveShopSearchQuery(
prompt: $routingPrompt,
prompt: $originalPrompt,
optimizedShopQuery: $optimizedShopQuery,
commerceHistoryContext: $shopQueryHistoryContext,
userId: $userId
userId: $userId,
currentPromptFallback: $routingPrompt
);
$guardedShopSearchQuery = $this->guardFinalStandaloneShopSearchQuery(
prompt: $originalPrompt,
shopSearchQuery: $shopSearchQuery
);
if ($guardedShopSearchQuery !== $shopSearchQuery) {
$this->agentLogger->info('Replaced standalone shop search query after final guard', [
'userId' => $userId,
'prompt' => $prompt,
'routingPrompt' => $routingPrompt,
'optimizedShopQuery' => $optimizedShopQuery,
'unsafeShopSearchQuery' => $shopSearchQuery,
'guardedShopSearchQuery' => $guardedShopSearchQuery,
]);
$shopSearchQuery = $guardedShopSearchQuery;
$optimizedShopQuery = '';
}
if ($shopSearchQuery === '') {
$this->agentLogger->info('Commerce search skipped because no concrete shop query could be resolved', [
'userId' => $userId,
@@ -1498,6 +1519,23 @@ final readonly class AgentRunner
return $prompt;
}
private function guardFinalStandaloneShopSearchQuery(string $prompt, string $shopSearchQuery): string
{
$shopSearchQuery = trim($shopSearchQuery);
if ($shopSearchQuery === '') {
return '';
}
$guardedQuery = $this->guardStandaloneOptimizedShopQuery($prompt, $shopSearchQuery);
if ($guardedQuery !== $shopSearchQuery) {
return $guardedQuery;
}
return $shopSearchQuery;
}
private function standaloneOptimizedShopQueryIntroducesUnsupportedContext(
string $prompt,
string $optimizedShopQuery
@@ -1535,7 +1573,8 @@ final readonly class AgentRunner
string $prompt,
string $optimizedShopQuery,
string $commerceHistoryContext,
string $userId
string $userId,
string $currentPromptFallback = ''
): string {
if ($this->isCommercialTableFollowUpPrompt($prompt)) {
foreach ($this->buildCommercialTableFollowUpContextCandidates($commerceHistoryContext, $userId) as $contextCandidate) {
@@ -1551,6 +1590,11 @@ final readonly class AgentRunner
return $this->guardStandaloneOptimizedShopQuery($prompt, $optimizedShopQuery);
}
$currentPromptFallback = trim($currentPromptFallback);
if ($currentPromptFallback !== '' && !$this->isMetaOnlyShopQuery($currentPromptFallback)) {
return $currentPromptFallback;
}
if (!$this->isMetaOnlyShopQuery($prompt)) {
return $prompt;
}