This commit is contained in:
team 1
2026-05-01 17:40:48 +02:00
parent 17cb098235
commit ad7cac72be
19 changed files with 1084 additions and 157 deletions

View File

@@ -136,6 +136,72 @@ final class NdjsonHybridRetrieverConfig
return $this->requiredInt('focused_product_max_chunks', 1);
}
/** @return string[] */
public function catalogListShortcutPatterns(): array
{
return $this->requiredStringList('catalog_list_shortcut_patterns');
}
/** @return array<string, string[]> */
public function exactSelectionTokenVariantPrefixes(): array
{
return $this->requiredStringListMap('exact_selection_token_variant_prefixes');
}
/** @return string[] */
public function exactSelectionIndicatorQuestionTokens(): array
{
return $this->requiredStringList('exact_selection_indicator_question_tokens');
}
/** @return string[] */
public function exactSelectionIndicatorQuestionPhrases(): array
{
return $this->requiredStringList('exact_selection_indicator_question_phrases');
}
/** @return string[] */
public function exactSelectionIndicatorTableHeadingPatterns(): array
{
return $this->requiredStringList('exact_selection_indicator_table_heading_patterns');
}
/** @return string[] */
public function exactSelectionIndicatorTableHeaderPatterns(): array
{
return $this->requiredStringList('exact_selection_indicator_table_header_patterns');
}
/** @return string[] */
public function exactSelectionIndicatorTableRowPatterns(): array
{
return $this->requiredStringList('exact_selection_indicator_table_row_patterns');
}
/** @return string[] */
public function exactSelectionIndicatorTableRequiredPrimaryTerms(): array
{
return $this->requiredStringList('exact_selection_indicator_table_required_primary_terms');
}
/** @return string[] */
public function exactSelectionIndicatorTableRequiredContextTerms(): array
{
return $this->requiredStringList('exact_selection_indicator_table_required_context_terms');
}
/** @return string[] */
public function exactDetailTokens(): array
{
return $this->requiredStringList('exact_detail_tokens');
}
/** @return string[] */
public function genericExactSelectionTokens(): array
{
return $this->requiredStringList('generic_exact_selection_tokens');
}
/** @return string[] */
public function genericProductTokens(): array
{
@@ -240,6 +306,17 @@ final class NdjsonHybridRetrieverConfig
'focused_product_min_score' => $this->focusedProductMinScore(),
'focused_product_min_gap' => $this->focusedProductMinGap(),
'focused_product_max_chunks' => $this->focusedProductMaxChunks(),
'catalog_list_shortcut_patterns' => $this->catalogListShortcutPatterns(),
'exact_selection_token_variant_prefixes' => $this->exactSelectionTokenVariantPrefixes(),
'exact_selection_indicator_question_tokens' => $this->exactSelectionIndicatorQuestionTokens(),
'exact_selection_indicator_question_phrases' => $this->exactSelectionIndicatorQuestionPhrases(),
'exact_selection_indicator_table_heading_patterns' => $this->exactSelectionIndicatorTableHeadingPatterns(),
'exact_selection_indicator_table_header_patterns' => $this->exactSelectionIndicatorTableHeaderPatterns(),
'exact_selection_indicator_table_row_patterns' => $this->exactSelectionIndicatorTableRowPatterns(),
'exact_selection_indicator_table_required_primary_terms' => $this->exactSelectionIndicatorTableRequiredPrimaryTerms(),
'exact_selection_indicator_table_required_context_terms' => $this->exactSelectionIndicatorTableRequiredContextTerms(),
'exact_detail_tokens' => $this->exactDetailTokens(),
'generic_exact_selection_tokens' => $this->genericExactSelectionTokens(),
'generic_product_tokens' => $this->genericProductTokens(),
'important_short_model_tokens' => $this->importantShortModelTokens(),
'family_descriptor_tokens' => $this->familyDescriptorTokens(),
@@ -324,6 +401,47 @@ final class NdjsonHybridRetrieverConfig
return $out;
}
/**
* @return array<string, string[]>
*/
private function requiredStringListMap(string $key): array
{
$value = $this->requiredValue($key);
if (!is_array($value)) {
throw $this->invalid($key, 'must be a map of string lists');
}
$out = [];
foreach ($value as $mapKey => $items) {
if (!is_string($mapKey) || trim($mapKey) === '' || !is_array($items)) {
continue;
}
$cleanItems = [];
foreach ($items as $item) {
if (!is_scalar($item)) {
continue;
}
$item = trim((string) $item);
if ($item !== '' && !in_array($item, $cleanItems, true)) {
$cleanItems[] = $item;
}
}
if ($cleanItems !== []) {
$out[trim($mapKey)] = $cleanItems;
}
}
if ($out === []) {
throw $this->invalid($key, 'must contain at least one non-empty map entry');
}
return $out;
}
private function requiredValue(string $key): mixed
{
if (!array_key_exists($key, $this->config)) {