# Agent orchestration limits, user-visible status/source labels and Shopware query prompt wording.
# Values mirror the current stable defaults; PHP fallbacks remain in AgentRunnerConfig.
parameters:
  retriex.agent.config:
    commerce_history_budget_chars: 1000
    product_search_knowledge_chunk_limit: 6
    advisory_product_search_knowledge_chunk_limit: 9
    optimized_shop_query_prefix_pattern: '/^(?:keywords?|suchquery|search\s*query|query)\s*:\s*/iu'
    optimized_shop_query_trim_characters: " \t\n\r\0\x0B\"'`"

    input_normalization:
      enabled: true
      max_input_chars: 500
      max_output_chars: 700
      max_added_tokens: 2
      max_length_ratio_percent: 150
      heartbeat_message: 'Ich optimiere die Anfrage…'
      output_prefix_pattern: '/^(?:normalisiert|korrigiert|corrected|normalized)\s*:\s*/iu'
      placeholder_outputs:
        - 'normalized user input'
        - 'corrected user input'
        - 'user input'
        - 'normalisierte nutzereingabe'
        - 'korrigierte nutzereingabe'
      skip_patterns:
        - '/https?:\/\//iu'
        - '/\bwww\./iu'
        - '/```/u'
      prompt:
        intro: 'Normalize the following user input for RetrieX routing before intent detection.'
        output_format_block: |-
          Output format:
          Return exactly one line: the corrected user input.
        current_user_input_label: 'USER INPUT'
        rules:
          - '- Output only the corrected user input text itself, never the words "normalized user input".'
          - '- Correct only obvious typing mistakes, transposed letters, missing umlauts, spacing, and punctuation that clearly preserve the same meaning.'
          - '- Do not add product names, model numbers, article numbers, measurement values, parameters, brands, or application areas that are not already present in the input.'
          - '- Preserve product names, model numbers, article numbers, chemical symbols, units, pH, Redox, ORP, and measurement values exactly unless only letter casing is corrected.'
          - '- Preserve the input language; do not translate German into English or English into German.'
          - '- Preserve vague references such as "der indikator", "das gerät", "suche im shop", or "dazu" without resolving them from context.'
          - '- If the input is already clear or you are uncertain, return the original input unchanged.'
          - '- No introduction, no explanation, no quotation marks.'

      fuzzy_routing:
        enabled: true
        min_token_length: 4
        medium_token_length: 7
        long_token_length: 11
        max_distance_short: 1
        max_distance_medium: 2
        max_distance_long: 3
        min_similarity_percent: 72
        # Canonical routing terms only, not typo variants.
        # The code fuzzy-matches user tokens against these terms when the LLM leaves
        # an obvious routing typo unchanged.
        terms:
          - shop
          - suche
          - suchen
          - such
          - finde
          - finden
          - kostet
          - kosten
          - preis
          - preise
          - preisen
          - preiswert
          - preiswerte
          - günstig
          - guenstig
          - kaufen
          - bestellen
          - produkt
          - produkte
          - artikel
          - sku
          - online
          - analysegerät
          - analysegeraet
          - messgerät
          - messgeraet
          - handmessgerät
          - handmessgeraet
          - pockettester
          - analysator
          - analyzer
          - indikator
          - indikatoren
          - reagenz
          - reagenzien
          - verbrauchsmaterial
          - zubehör
          - zubehoer
          - ersatzteil
          - ersatzteile
          - anschlusskabel
          - kabel
          - sensorkabel
          - elektrode
          - elektrodenkabel
          - puffer
          - kalibrierpuffer
          - kalibrierlösung
          - kalibrierloesung
          - kalibrierung
          - lösung
          - loesung
          - messen
          - messung
          - überwachen
          - ueberwachen
          - kontrollieren
          - schwimmbad
          - pool
          - becken
          - wasseranalyse
          - geeignet
          - passend
          - empfehlung
          - empfehlen
          - empfiehl

    follow_up_context:
      strong_reference_patterns:
        - '/\bder\s+wert\b/u'
        - '/\bdieser\s+wert\b/u'
        - '/\bdiesen\s+wert\b/u'
        - '/\bdem\s+wert\b/u'
        - '/\bmit\s+welche(?:m|n|r)?\b/u'
        - '/\bwomit\b/u'
        - '/\bdamit\b/u'
        - '/\bdafuer\b/u'
        - '/\bdafür\b/u'
        - '/\bdazu\b/u'
        - '/\bdaraus\b/u'
        - '/\bwelche(?:r|s|m|n)?\s+indikator\b/u'
        - '/\bwelche(?:r|s|m|n)?\s+indikatortyp\b/u'
        - '/\bindikator\s+(?:dafuer|dafür|dazu|hierfuer|hierfür)\b/u'
        - '/\bwelche(?:r|s|m|n)?\s+bereich\b/u'
        - '/\bwelche(?:r|s|m|n)?\s+messbereich\b/u'
        - '/\bwelche(?:r|s|m|n)?\s+grenzwert\b/u'
      explicit_commercial_signal_terms:
        - shop
        - preis
        - preise
        - preisen
        - kostet
        - kosten
        - kaufen
        - bestellen
        - warenkorb
        - lieferzeit
        - verfuegbar
        - verfügbar
        - lager
        - url
        - link
        - artikelnummer
        - sku
        - produktnummer

      commercial_table_follow_up:
        enabled: true
        prompt_patterns:
          - '/\b(?:tabelle|tabellarisch|übersicht|uebersicht|liste|auflistung)\b.{0,80}\b(?:preis|preise|preisen|kosten|kostet|shop)\b/u'
          - '/\b(?:preis|preise|preisen|kosten|kostet|shop)\b.{0,80}\b(?:tabelle|tabellarisch|übersicht|uebersicht|liste|auflistung)\b/u'
          - '/\b(?:mit|inkl|inklusive|plus)\s+(?:preis|preise|preisen|kosten|shopdaten)\b/u'
        history_anchor_patterns:
          - '/\bTestomat(?:®)?\s+\d{3,4}\b/iu'
          - '/\b(?:Indikatortyp|Indikator|Indikatoren|Reagenz|Reagenzien|Zubehör|Zubehoer)\b/iu'
        table_terms:
          - tabelle
          - tabellarisch
          - übersicht
          - uebersicht
          - liste
          - auflistung
        commercial_terms:
          - preis
          - preise
          - preisen
          - kosten
          - kostet
          - shop
          - shoppreis
          - shoppreise
          - shopdaten
        indicator_marker_patterns:
          - '/\b(?:Indikatortyp|Indikator(?:en)?|indicator(?:\s+type)?|Reagenz(?:ien)?)\b/iu'
        query_template_with_model: '{model} indikator'
        query_template_without_model: 'indikator'
      history_question_pattern: '/^Question:\s*(.+)$/mi'
      history_turn_split_pattern: '/(?=^Question:\s)/m'
      history_question_strip_pattern: '/^Question:\s*.*(?:\R|$)/u'
      context_labels:
        previous_user_question_template: 'Vorherige Nutzerfrage: {question}'
        previous_reference_anchors_template: 'Vorherige technische Referenzanker (nur zur Referenzauflösung, keine Faktenquelle): {anchors}'
        current_follow_up_question_template: 'Aktuelle Folgefrage: {question}'
      reference_anchor:
        product_model_pattern: '/\bTestomat(?:®)?\s+(?:\d{3,4}(?:\s+[A-Z]{2,8})?|EVO(?:\s+[A-Z]{2,6})?|ECO(?:[-\s]?(?:PLUS|C))?|DUO(?:\s+\d{3,4})?|LAB(?:\s+[A-Z]{2,6})?)\b/iu'
        measurement_value_pattern: '/\b\d+(?:[,.]\d+)?\s*°\s*dH\b/iu'

    messages:
      empty_prompt: '❌ Empty prompt.'
      analyze_request: 'Ich analysiere deine Anfrage...'
      check_internet_sources: 'Ich prüfe auf Internetquellen...'
      retrieve_knowledge: 'Ich hole relevante Daten aus meinem RAG-Wissen...'
      optimize_search: 'Ich optimiere die Recherche...'
      no_concrete_shop_query: 'Ich kann die Shop-Suche noch nicht belastbar auflösen. Bitte nenne das Produkt, den Messparameter oder das Zubehör etwas konkreter.'
      fetch_search_data_template: 'Ich rufe Recherchedaten ab (type: %s)'
      analyze_all_information: 'Ich analysiere alle Informationen...'
      thinking_while_streaming: 'Denke nach...'
      no_llm_data_received: '❌ Es wurden keine Daten vom LLM empfangen.'
      shop_repair_check: 'Erweiterte Shopsuche wird geprüft…'
      shop_query_optimization_heartbeat: 'Shop-Suchanfrage wird optimiert…'
      generic_internal_error: '❌ Bei der Verarbeitung der Anfrage ist ein interner Fehler aufgetreten.'
      debug_internal_error_prefix: '❌ Interner Fehler: '

    rag_evidence_guard:
      cleanup_profile: rag_evidence
      # Legacy/domain override list. Generic German stopwords are provided by
      # language cleanup profile `rag_evidence`. Keep RAG/product-role terms here.
      stop_terms:
        - ohne
        - messen
        - messung
        - tester
        - testgerät
        - testgeraet
        - gerät
        - geraet
        - messgerät
        - messgeraet
        - produkt
        - produkte
        - artikel
        - shop
      aggregate_query_patterns:
        - '/\bwie\s+viele\b/u'
        - '/\bwieviele\b/u'
        - '/\banzahl\b/u'
        - '/\bcount\b/u'
        - '/\bgesamtzahl\b/u'
      aggregate_evidence_terms:
        - anzahl
        - gesamtzahl
        - stückzahl
        - stueckzahl
        - count
        - portfolio
        - sortiment
        - bestand
        - bestände
        - bestaende
        - lieferprogramm
      aggregate_answer_evidence_patterns:
        - '/\b(?:anzahl|gesamtzahl|stückzahl|stueckzahl|count)\b.{0,80}\b\d+\b/u'
        - '/\b\d+\s+(?:[a-z0-9+\-]+\s+){0,3}(?:produkte|artikel|geräte|geraete|messgeräte|messgeraete)\b/u'
        - '/\b(?:insgesamt|gesamt|total)\b.{0,80}\b\d+\b/u'
        - '/\b(?:sortiment|portfolio|lieferprogramm)\b.{0,120}\b(?:umfasst|enthält|enthaelt|besteht\s+aus|beinhaltet)\b.{0,80}\b\d+\b/u'
      synonyms:
        salinität:
          - salinität
          - salinitaet
          - salinity
          - salzgehalt
          - tds
          - leitfähigkeit
          - leitfaehigkeit
        salinitaet:
          - salinität
          - salinitaet
          - salinity
          - salzgehalt
          - tds
          - leitfähigkeit
          - leitfaehigkeit
        salinity:
          - salinität
          - salinitaet
          - salinity
          - salzgehalt
          - tds
          - leitfähigkeit
          - leitfaehigkeit
        redox:
          - redox
          - orp
          - oxidations-reduktionspotential
          - oxidations reduktionspotential
        orp:
          - redox
          - orp
          - oxidations-reduktionspotential
          - oxidations reduktionspotential
        ph:
          - ph
          - ph-wert
          - ph wert
        chlor:
          - chlor
          - freies chlor
          - gesamtchlor
          - chlorine

    no_llm_fallback:
      max_shop_results: 5
      messages:
        shop_only: 'Ich finde dazu im RAG-Wissen keine belastbare Fachinformation. Aus den Shopdaten ergeben sich folgende Treffer; technische Eignung bitte prüfen:'
        shop_with_knowledge: 'Es liegen RAG-/Kontexttreffer und Shopdaten vor. Ohne LLM leite ich daraus keine technische Eignung ab. Die Shopdaten zeigen folgende Treffer; technische Eignung bitte prüfen:'
        accessory_only_for_main_device: 'Die Shop-Treffer wirken wie Zubehör/Verbrauchsmaterial und nicht wie eine angefragte Messanlage oder ein Hauptgerät. Ich werte sie deshalb nicht als passende Hauptlösung.'
        escalation: 'Für eine verbindliche Produktauswahl sollte der konkrete Anwendungsfall durch Vertrieb oder Support geprüft werden.'
        knowledge_only: 'Ich habe Treffer im RAG-Wissen gefunden, aber ohne LLM kann ich daraus keine belastbare fachliche Antwort synthetisieren. Ich gebe deshalb keine sichere Produktaussage aus. Bitte aktiviere das LLM oder konkretisiere die Frage für eine gezielte Prüfung.'
        no_data: 'Ich finde dazu keine belastbaren Daten in den vorliegenden Quellen. Bitte nenne Produkt, Messparameter, Zubehör oder Anwendungsfall genauer.'
        no_shop_results_with_knowledge: 'Ich finde RAG-/Kontexttreffer, aber keine passenden Shop-Treffer zur aktuellen Suchanfrage. Das ist keine Aussage, dass es das Produkt nicht gibt. Ohne LLM gebe ich keine technische Negativaussage aus; bitte prüfe den Suchbegriff oder den Anwendungsfall gezielter.'
        no_shop_results_no_knowledge: 'Ich finde weder belastbares RAG-Wissen noch passende Shop-Treffer zur aktuellen Suchanfrage. Das ist keine sichere Negativaussage. Bitte nenne Produkt, Messparameter oder Zubehör konkreter.'
        shop_unavailable_with_knowledge: 'Live-Shopdaten konnten nicht geladen werden. Ich kann keine Aussage zu aktueller Verfügbarkeit, Preis oder Shop-Portfolio treffen. Wenn das RAG-Wissen einen direkten Fachbeleg enthält, wird die fachliche Antwort davon getrennt betrachtet.'
        shop_unavailable_no_knowledge: 'Live-Shopdaten konnten nicht geladen werden und die RAG-Treffer enthalten keinen direkten Fachbeleg zur Anfrage. Ich kann daraus keine verlässliche Produkt-, Verfügbarkeits- oder Portfolioaussage ableiten.'
      product_fields:
        unreadable_results_message: '- Es wurden Shop-Treffer übergeben, aber keine lesbaren Produktdaten gefunden.'
        unnamed_product: 'Unbenanntes Shop-Produkt'
        product_number_template: 'Art.-Nr. {value}'
        manufacturer_template: 'Hersteller: {value}'
        price_template: 'Preis: {value}'
        availability_template: 'Verfügbar: {value}'
        availability_yes: 'ja'
        availability_no: 'nein'
        url_template: 'URL: {value}'
        incompatible_role_note: 'Hinweis: Zubehör/Verbrauchsartikel; nicht als Messanlage/Gerät bestätigt'
        line_template: '{index}. {parts}'
        separator: ' | '
        unavailable_reason_template: '{message} Ursache: {reason}'

      product_roles:
        main_device_request_keywords:
          - anlage
          - messanlage
          - gerät
          - geraet
          - messgerät
          - messgeraet
          - analysegerät
          - analysegeraet
          - analysator
          - analyzer
          - system
          - testomat
          - testomaten
          - testoamt
          - testomate
          - pockettester
        accessory_product_keywords:
          - indikator
          - indicator
          - indikatortyp
          - reagenz
          - reagent
          - reagenzsatz
          - kalibrierlösung
          - kalibrierloesung
          - pufferlösung
          - pufferloesung
          - reinigungslösung
          - reinigungsloesung
          - kalibrier
          - puffer
          - zubehör
          - zubehor
          - accessory
          - ersatzteil
          - verbrauch
          - consumable
          - kit
          - set
          - flasche
          - bottle
          - 100 ml
          - 500 ml
          - 100ml
          - 500ml


    production_ui:
      stage_labels:
        preparing_answer: 'Antwort wird vorbereitet'
        shop_routing_detected: 'Shop-Routing erkannt'
        rag_searched: 'RAG-Wissen wurde durchsucht'
        shop_search_preparing: 'Shop-Suche wird vorbereitet'
        more_context_needed: 'Mehr Kontext nötig'
        shop_search_running: 'Shop wird durchsucht'
        shop_unavailable: 'Shopdaten nicht verfügbar'
        shop_completed: 'Shop-Suche abgeschlossen'
        answer_generating: 'Antwort wird generiert'
        completed: 'Abgeschlossen'
        interrupted: 'Antwort wurde unterbrochen'
      confidence_labels:
        checking_evidence: 'Beleglage wird geprüft'
        checking_shop_data: 'Shopdaten werden geprüft'
        more_context_needed: 'mehr Kontext nötig'
        interrupted: 'nicht abgeschlossen'
        direct: 'fachlich belegt'
        aggregate_missing: 'geprüfte Quellen, keine passende Zählinformation'
        weak: 'RAG-Näherungstreffer, kein direkter Fachbeleg'
        default: 'noch keine belastbaren Treffer'
        direct_shop_check: 'fachlich belegt; Shopdaten werden geprüft'
        aggregate_missing_shop_check: 'geprüfte Quellen ohne Zählinformation; Shopdaten werden geprüft'
        weak_shop_check: 'RAG-Näherungstreffer; Shopdaten werden geprüft'
        default_shop_check: 'Shopdaten werden geprüft'
        aggregate_missing_shop_unavailable: 'geprüfte Quellen ohne Zählinformation; Shopdaten nicht verfügbar'
        aggregate_missing_no_count: 'geprüfte Quellen, keine passende Zählinformation'
        shop_unavailable_with_knowledge: 'fachlich belegt; Shopdaten nicht verfügbar'
        shop_unavailable: 'Shopdaten nicht verfügbar'
        rag_and_shop: 'RAG + Shopdaten'
        shop_only: 'nur Shopdaten'
        rag_no_shop_hits: 'RAG-Wissen, keine Shop-Treffer'
        no_reliable_data: 'keine belastbaren Daten'
        no_reliable_hits: 'noch keine belastbaren Treffer'
      text:
        live_shop_source_plain_label: 'Live-Shopdaten'
        run_status_eyebrow: 'RetrieX-Status'
        evidence_prefix: 'Beleglage: '
        data_basis_label: 'Datenbasis'
        data_basis_empty_completed: 'keine belastbare Datenbasis'
        data_basis_empty_running: 'wird geprüft'
        rag_hits_checking: 'RAG-Treffer: wird geprüft'
        shop_hits_loading: 'Shop-Treffer: wird geladen'
        shop_hits_unavailable: 'Shop-Treffer: nicht verfügbar'
        shop_hits_no_query: 'Shop-Treffer: keine Suchquery'
        shop_hits_not_requested: 'Shop-Treffer: nicht angefragt'
        status_completed: 'Status: abgeschlossen'
        status_running: 'Status: läuft'
        shop_results_eyebrow: 'Shop-Ergebnisse'
        shop_results_title: 'Shop-Ergebnisse'
        evaluated_query_label: 'Ausgewertete Suchquery'
        unnamed_product: 'Unbenanntes Produkt'
        field_not_provided: 'nicht übermittelt'
        product_number_label: 'Artikelnummer'
        price_label: 'Preis'
        availability_label: 'Verfügbarkeit'
        manufacturer_label: 'Hersteller'
        relevance_label: 'Relevanz'
        availability_yes: 'verfügbar'
        availability_no: 'nicht verfügbar'
        availability_unknown: 'Shopstatus nicht übermittelt'
        followup_eyebrow: 'Folgeaktionen'
        followup_title: 'Was möchtest du als Nächstes tun?'
        shop_meta_fallback_query: 'keine Suchquery ermittelt'
        shop_meta_query_mode_optimized: 'optimiert'
        shop_meta_query_mode_direct: 'direkt'
        shop_meta_default_intent: 'commerce'
        shop_meta_title_unavailable: 'Shopdaten nicht verfügbar'
        shop_meta_title_completed: 'Shop-Suche abgeschlossen'
        shop_meta_title_running: 'Shop-Suche wird ausgeführt'
        shop_meta_status_completed: 'Status: abgeschlossen'
        shop_meta_status_running: 'Status: läuft'
        shop_meta_result_unavailable: 'Shoptreffer: nicht verfügbar'
        shop_meta_result_loading: 'Shoptreffer: wird geladen'
        shop_meta_repair_used: 'Erweiterte Suche: genutzt'
        shop_meta_repair_checked: 'Erweiterte Suche: geprüft'
        shop_meta_eyebrow: 'Shop-Suche'
        shop_meta_query_label: 'Gesendete Suchquery'
        shop_meta_query_prefix: 'Query: '
        shop_meta_intent_prefix: 'Intent: '
        shop_unavailable_default_reason: 'Keine Detailmeldung vom Shopware-Server.'
        shop_unavailable_title: 'Shopdaten konnten nicht geladen werden'
        shop_unavailable_text_prefix: 'RetrieX antwortet ohne Live-Shopdaten weiter. Ursache: '
        no_llm_history_default: 'Es wurden keine Daten vom LLM empfangen.'
        history_notice_default_title: 'Systemhinweis'
        history_notice_shop_unavailable_title: 'Shopdaten konnten nicht geladen werden'
        history_notice_answer_incomplete_title: 'Antwort konnte nicht abgeschlossen werden'
      templates:
        rag_hits_count: 'RAG-Treffer: {count}'
        shop_hits_count: 'Shop-Treffer: {count}'
        shop_results_summary: '{count} Shop-Treffer ausgewertet'
        shop_results_top_displayed_suffix: ' · Top {max} angezeigt'
        shop_results_repair_suffix: ' · erweiterte Shopsuche genutzt'
        relevance_matched_queries: 'Gefunden über: {queries}'
        relevance_highlight: 'Passender Shop-Hinweis: {highlight}'
        relevance_match_source: 'Trefferquelle: {source}'
        relevance_query: 'Passend zur Suchquery: {query}'
        relevance_default: 'Aus den Live-Shopdaten übernommen'
        shop_meta_result_count: 'Shoptreffer: {count}'
        history_notice_without_detail: 'Systemhinweis: {title}.'
        history_notice_with_detail: 'Systemhinweis: {title}. Ursache: {detail}'
      shop_results:
        max_cards: 5
      follow_up_actions:
        commerce:
          - label: 'Im Shop suchen'
            prompt: 'Suche die aktuelle Produktauswahl im Shop.'
          - label: 'Nur Zubehör anzeigen'
            prompt: 'Zeige aus der aktuellen Produktauswahl nur Zubehör.'
          - label: 'Nur Geräte anzeigen'
            prompt: 'Zeige aus der aktuellen Produktauswahl nur Geräte.'
          - label: 'Preis anzeigen'
            prompt: 'Zeige mir die Preise der aktuell relevanten Produkte.'
        knowledge:
          - label: 'Technische Details anzeigen'
            prompt: 'Zeige technische Details zur aktuellen Antwort.'

    source_labels:
      external_url: 'Externe URL'
      rag_knowledge: 'RAG Wissen'
      conversation_history: 'Chatverlauf'
      shop_system: 'Shopsystem'
      extended_shop_search: 'Erweiterte Shopsuche'
      used_sources_prefix: 'Genutzte Quellen: '
      sources_prefix: 'Quellen: '

    html:
      source_badge_template: '<span class="badge bg-info text-black">%s</span>'
      error_template: |
        <div class="retriex-alert retriex-alert--error"><div class="retriex-alert__icon">❌</div><div class="retriex-alert__content"><div class="retriex-alert__title">Hinweis</div><div class="retriex-alert__text">%s</div></div></div>
      think_template: |
        <span class="text-info think">%s</span>
      info_template: "\n\n<span class=\"text-info fw-bolder\">%s</span>\n"
      debug_template: "\n\nDEBUG: <code>%s</code>\n"

    shop_prompt:
      intro: 'Generate a short search query for Shopware 6 from the following user input text.'
      output_format_block: |-
        Output format:
        Keyword1 Keyword2 Keyword3
      recent_conversation_context_label: 'RECENT CONVERSATION CONTEXT'
      current_user_input_label: 'CURRENT USER INPUT'
      rules:
        - '- Output only the final search query.'
        - '- Always convert relevant search terms to their singular form.'
        - '- No introduction, no explanation, no quotation marks.'
        - '- Use only shop-relevant search terms from the user input for a shop search.'
        - '- Maximum 6 search terms, preferably fewer.'
        - '- Remove filler words, polite phrases, and irrelevant words.'
        - '- Preserve product names, brands, model numbers, and compound terms exactly if they are relevant.'
        - '- Preserve the language of the CURRENT USER INPUT for generic product/search terms; do not translate German search terms into English.'
        - '- For German user input, output German shop terms, for example "freies Chlor Messung" instead of "free chlorine measurement".'
        - '- Preserve domain terms from the current user input or resolved context in their original language.'
        - '- Numbers that belong to a product name or model must be preserved when they are present in the CURRENT USER INPUT or a clearly resolved reference.'
        - '- Separate terms using spaces only.'
        - '- If a relevant product name is present, it must be placed at the beginning of the final search query.'
        - '- Try to always identify all products mentioned in the user input text, even in long prompts.'
        - '- Look for terms such as Testomat, Horiba, Tritromat, Pockettester, Redox, ORP, or words like indicator/Indikator.'
        - '- If the current user input is vague or referential, use the recent conversation context only as support.'
        - '- Do not output words that only describe conversation flow, such as "same", "again", "also", or "like above".'
      conversation_context_rules:
        - '- The current user input has highest priority.'
        - '- Use the recent conversation context only to resolve omitted references.'
        - '- Use it only for product carry-over, brand carry-over, model carry-over, or variant follow-ups.'
        - '- Do not revive older products unless the current user input clearly refers to them.'
        - '- If the current input starts a new topic, ignore older product context.'
        - '- Prefer the most recent product reference over older ones.'
      current_input_preservation:
        enabled: true
        # Terms that must be preserved from the current user input in the final
        # Shopware search query. This prevents short domain terms from being
        # dropped by query optimization or generic cleanup. Adapt this list for
        # other domains/projects instead of changing PHP code.
        terms:
          - ph
          - rx
          - th
          - tc
          - redox
          - orp
          - '0,02'

      product_attribute_query_cleanup:
        enabled: true
        # For direct product/accessory lookups with comparative attribute
        # constraints, keep the concrete product type and application terms but
        # do not send range words/numeric thresholds to the plain text shop
        # search. Example: "Anschlusskabel pH/Redox länger 20m" becomes
        # "anschlusskabel redox" so the shop can return 25m/50m/100m cables.
        min_query_tokens_after_cleanup: 2
        product_type_terms:
          - anschlusskabel
          - kabel
          - sensorkabel
          - elektrodenkabel
          - elektrodenanschlusskabel
          - messkabel
          - verbindungskabel
          - steckerkabel
          - elektrode
          - sensor
          - puffer
          - kalibrierpuffer
        stop_terms:
          - zeige
          - zeig
          - suche
          - such
          - mir
          - bitte
          - für
          - fuer
          - nach
          - mit
          - ohne
          - von
          - zum
          - zur
          - der
          - die
          - das
          - ein
          - eine
          - einen
          - länger
          - laenger
          - lang
          - kürzer
          - kuerzer
          - größer
          - groesser
          - kleiner
          - über
          - ueber
          - unter
          - mindestens
          - maximal
          - maximum
          - minimum
          - ab
          - bis
          - mehr
          - weniger
          - als
        comparative_constraint_patterns:
          - '/\b(?:länger|laenger|kürzer|kuerzer|größer|groesser|kleiner|über|ueber|unter|mindestens|maximal|maximum|minimum|ab|bis|mehr\s+als|weniger\s+als)\s+(?P<value>\d+(?:[,.]\d+)?\s*[\p{L}µ°%]*)\b/iu'

      context_usage:
        referential_terms:
          - der
          - die
          - das
          - den
          - dem
          - dazu
          - davon
          - dafür
          - dafuer
          - dieser
          - diese
          - dieses
          - obige
          - obigen
          - oben
          - vorher
          - zuvor
          - gleiche
          - gleichen
          - selbe
          - selben
      context_anchor_enrichment:
        enabled: true
        max_query_terms: 2
        template: '{anchor} {query}'
        trigger_terms:
          - indikator
          - indikatortyp
          - indicator
          - reagenz
          - reagenzsatz
          - reagent
          - zubehör
          - zubehor
          - accessory
        anchor_patterns:
          - '/\b(?:indikator(?:typ)?|indicator(?:\s+type)?|reagenz(?:satz|typ)?|reagent(?:\s+set|\s+type)?|typ|type)\s+[A-Za-zÄÖÜäöüß]{0,8}\s*\d{1,5}(?:\s*[A-ZÄÖÜ]{1,4})?(?:\s*%)?\b/iu'
      meta_query_guard:
        enabled: true
        cleanup_profile: shop_context_fallback
        context_fallback_enabled: true
        context_fallback_question_limit: 12
        context_fallback_history_budget_chars: 20000
        context_fallback_use_full_history: true
        context_fallback_max_terms: 6
        # Legacy/domain override list. Generic stopwords, user-instruction
        # phrases and presentation terms are provided by profile
        # `shop_context_fallback`. Keep shop/price/domain terms here.
        context_fallback_filter_terms:
          - preis
          - preise
          - preisen
          - kosten
          - kostet
          - grenzwert
          - grenzwerte
          - grenzwerten
          - welche
          - gut
          - geeignet
          - messen
          - gemessen
        meta_only_terms:
          - shop
          - preis
          - preise
          - preisen
          - kosten
          - kostet
          - shopsuche
          - shop-suche
      rag_anchor_enrichment:
        enabled: true
        # Enriches overly narrow numeric shop queries with a product anchor from
        # retrieved RAG records when the same record explicitly contains the
        # requested numeric value/unit. This prevents queries such as "0,02"
        # when RAG already identified a concrete product such as a device model.
        min_score: 120
        max_query_terms: 6
        early_chunk_bonus_max: 10
        template: '{anchor} {query} {subject}'
        scores:
          exact_value_with_unit: 120
          exact_value_only: 40
          anchor_bonus: 50
        numeric_focus_patterns:
          - '/(?P<value>\d+(?:[,.]\d+)?)\s*(?P<unit>°?\s*d\s*h|dh|dH)/iu'
        product_title_patterns:
          - '/#\s*Produkt\s+Titel:\s*`(?P<title>[^`]+)`/iu'
          - '/\*\*Produktname:\*\*\s*(?P<title>[^\r\n]+)/iu'
        anchor_bonus_patterns:
          - '/\b[\p{L}][\p{L}\p{N}®+._-]*(?:\s+|[-_])\d{2,5}\b/u'
        subject_terms:
          - resthärte
          - resthaerte
          - wasserhärte
          - wasserhaerte
          - gesamthärte
          - gesamthaerte
          - härte
          - haerte
          - grenzwert
          - messung

      language_preservation:
        enabled: true
        language_markers:
          de:
            - ' ä '
            - ' ö '
            - ' ü '
            - ' ß '
            - ' der '
            - ' die '
            - ' das '
            - ' ein '
            - ' eine '
            - ' einer '
            - ' einen '
            - ' welchem '
            - ' welchen '
            - ' welche '
            - ' welcher '
            - ' kann '
            - ' nutzen '
            - ' zur '
            - ' für '
            - ' fuer '
            - ' messung '
            - ' indikator '
            - ' reagenz '
            - ' chlor '
        translation_replacements:
          de:
            free chlorine: 'freies chlor'
            free chlor: 'freies chlor'
            total chlorine: 'gesamtchlor'
            chlorine measurement: 'chlor messung'
            water hardness: 'wasserhärte'
            measurement: 'messung'
            measuring: 'messung'
            chlorine: 'chlor'
            indicator: 'indikator'
            indicators: 'indikatoren'
            reagent: 'reagenz'
            reagents: 'reagenzien'
            accessory: 'zubehör'
            accessories: 'zubehör'
