# RetrieX Shop-Meta-Context + SSE-Reconnect-Replay Fix

## Problem

Kurze referenzielle Shop-Befehle wie:

```text
suche im shop
```

konnten trotz vorheriger Antwort scheitern mit:

```text
Ich habe keine konkrete Shop-Suchanfrage erkannt.
```

Das passierte besonders nach langen oder reconnect-anfälligen SSE-Antworten, weil der Shop-Fallback vollständig von der serverseitig bereits geschriebenen History und einer stabilen Client-ID abhängig war.

Zusätzlich war das Job-ID-/SSE-Verhalten fragil: ein automatischer `EventSource`-Reconnect auf einen bereits laufenden Job konnte weiterhin als Duplicate-Stream behandelt werden.

## Lösung

### 1. SSE-Reconnect-Replay

- Antwort-Chunks werden pro Job mit fortlaufender SSE-`id` gesendet.
- Chunks werden zusätzlich in `var/stream_jobs/*.stream.ndjson` gepuffert.
- Reconnects mit `Last-Event-ID` replayen fehlende Chunks und tailen den laufenden Job.
- Doppelte Events werden im Frontend defensiv ignoriert.
- Completed/failed/interrupted Jobs werden sauber beendet.

### 2. Ephemeral Client Context Hint

- Das Frontend merkt sich den zuletzt vollständig abgeschlossenen Turn.
- `/ask-jobs` sendet diesen Turn als `contextHint` mit.
- Der Server speichert diesen Hint im Stream-Job und reicht ihn an `AgentRunner` weiter.
- `AgentRunner` hängt den Hint nur temporär an den Commerce-History-Kontext an.
- Der Hint wird nicht als eigener History-Eintrag persistiert.

Damit kann `suche im shop` auch dann auf die letzte Nutzerfrage/Antwort zurückfallen, wenn die serverseitige History gerade noch nicht zuverlässig greift oder die Client-ID-/Cookie-Situation im Browser wackelt.

### 3. Shop-Fallback-Tokenfilter geschärft

- `messung` wird im Shop-Context-Fallback nicht mehr entfernt, weil Begriffe wie `redox messung` fachlich relevant sind.
- Zusätzliche Füllwörter wie `ist`, `sind`, `gut`, `geeignet` werden entfernt.

Beispiel aus dem Fehlerfall:

```text
welcher pockettester ist für Redox messung gut
suche im shop
```

Der zweite Befehl kann nun aus dem Kontext wieder auf `pockettester redox messung` bzw. eine vergleichbare Shop-Query kommen, statt ohne konkrete Shop-Suchanfrage abzubrechen.

## Geänderte Dateien

```text
src/Controller/AskSseController.php
src/Agent/AgentRunner.php
src/Config/AgentRunnerConfig.php
config/retriex/agent.yaml
public/assets/js/base.js
```

## Prüfung

```bash
php -n -l src/Controller/AskSseController.php
php -n -l src/Agent/AgentRunner.php
php -n -l src/Config/AgentRunnerConfig.php
node --check public/assets/js/base.js
```

`vendor/autoload.php` war in der ZIP-Arbeitskopie nicht enthalten, daher wurde `bin/console mto:agent:config:validate` hier nicht ausgeführt.

## Nach dem Einspielen

```bash
php bin/console cache:clear
php bin/console mto:agent:config:validate
php bin/console mto:agent:regression:test
```

Danach den Browser hart neu laden, weil `public/assets/js/base.js` geändert wurde.
