This commit is contained in:
team 1
2026-05-06 16:40:20 +02:00
parent abe929bd20
commit 9731880cd3
6 changed files with 558 additions and 0 deletions

View File

@@ -28,6 +28,7 @@ final readonly class RetriexEffectiveConfigProvider
private LanguageCleanupConfig $languageCleanupConfig,
private QueryEnricherConfig $queryEnricherConfig,
private GovernanceConfig $governanceConfig,
private GenreConfig $genreConfig,
private CatalogIntentConfig $catalogIntentConfig,
private ContextServiceConfig $contextServiceConfig,
) {
@@ -39,6 +40,7 @@ final readonly class RetriexEffectiveConfigProvider
public function dump(): array
{
return [
'genre' => $this->genreConfig(),
'runtime' => $this->runtimeConfig(),
'index' => $this->indexConfig(),
'model_generation' => $this->modelConfig(),
@@ -73,6 +75,7 @@ final readonly class RetriexEffectiveConfigProvider
$warnings = [];
$config = $this->dump();
$this->validateGenre($config['genre'], $config, $errors, $warnings);
$this->validateRuntime($config['runtime'], $errors, $warnings);
$this->validateIndex($config['index'], $errors, $warnings);
$this->validateModel($config['model_generation'], $errors, $warnings);
@@ -435,6 +438,19 @@ final readonly class RetriexEffectiveConfigProvider
return $key !== '' ? $key : 'value';
}
/** @return array<string, mixed> */
private function genreConfig(): array
{
return [
'id' => $this->genreConfig->getId(),
'label' => $this->genreConfig->getLabel(),
'mode' => $this->genreConfig->getMode(),
'description' => $this->genreConfig->getDescription(),
'adaptation_surface' => $this->genreConfig->getAdaptationSurface(),
];
}
/** @return array<string, mixed> */
private function runtimeConfig(): array
{
@@ -1084,6 +1100,137 @@ final readonly class RetriexEffectiveConfigProvider
];
}
/**
* @param array<string, mixed> $genre
* @param array<string, mixed> $effectiveConfig
* @param list<string> $errors
* @param list<string> $warnings
*/
private function validateGenre(array $genre, array $effectiveConfig, array &$errors, array &$warnings): void
{
if (trim((string) ($genre['id'] ?? '')) === '') {
$errors[] = 'genre.id must not be empty.';
}
if (trim((string) ($genre['mode'] ?? '')) === '') {
$errors[] = 'genre.mode must not be empty.';
}
$surface = $genre['adaptation_surface'] ?? null;
if (!is_array($surface) || $surface === []) {
$errors[] = 'genre.adaptation_surface must be a non-empty map.';
return;
}
$flattened = [];
$this->flattenGenreParameterPaths($flattened);
foreach ($effectiveConfig as $root => $value) {
if ($root === 'genre') {
continue;
}
$this->flattenEffectiveConfigPath((string) $root, $value, $flattened);
}
foreach ($surface as $group => $definition) {
if (!is_string($group) || trim($group) === '') {
$errors[] = 'genre.adaptation_surface keys must be non-empty strings.';
continue;
}
if (!is_array($definition)) {
$errors[] = sprintf('genre.adaptation_surface.%s must be a map.', $group);
continue;
}
$paths = $definition['paths'] ?? null;
if (!is_array($paths) || $paths === []) {
$errors[] = sprintf('genre.adaptation_surface.%s.paths must be a non-empty list.', $group);
continue;
}
foreach ($paths as $path) {
if (!is_string($path) || trim($path) === '') {
$errors[] = sprintf('genre.adaptation_surface.%s.paths must contain non-empty strings.', $group);
continue;
}
if (!isset($flattened[$path])) {
$warnings[] = sprintf('genre.adaptation_surface.%s references unknown config path: %s.', $group, $path);
}
}
}
}
/**
* @param array<string, true> $paths
*/
private function flattenGenreParameterPaths(array &$paths): void
{
$configRoots = [
'retriex.agent.config' => 'agent',
'retriex.commerce_query.config' => 'commerce_query',
'retriex.governance.config' => 'governance',
'retriex.intent.commerce.config' => 'intent.commerce',
'retriex.intent.light.config' => 'intent.light',
'retriex.intent.sales.config' => 'intent.sales',
'retriex.prompt.config' => 'prompt',
'retriex.query_enrichment.config' => 'query_enrichment',
'retriex.retrieval.config' => 'retrieval',
'retriex.search_repair.config' => 'search_repair',
'retriex.shop_matching.config' => 'shop_matching',
'retriex.stopwords.config' => 'stopwords',
'retriex.vocabulary.config' => 'vocabulary',
];
$allParameters = $this->parameters->all();
foreach ($configRoots as $parameterName => $rootPath) {
if (!array_key_exists($parameterName, $allParameters)) {
continue;
}
$this->flattenEffectiveConfigPath($rootPath, $allParameters[$parameterName], $paths);
}
foreach ($allParameters as $parameterName => $value) {
if (!is_string($parameterName) || !str_starts_with($parameterName, 'retriex.')) {
continue;
}
foreach (array_keys($configRoots) as $configRoot) {
if ($parameterName === $configRoot || str_starts_with($parameterName, $configRoot . '.')) {
continue 2;
}
}
$this->flattenEffectiveConfigPath(substr($parameterName, strlen('retriex.')), $value, $paths);
}
}
/**
* @param array<string, true> $paths
*/
private function flattenEffectiveConfigPath(string $path, mixed $value, array &$paths): void
{
$paths[$path] = true;
if (!is_array($value)) {
return;
}
foreach ($value as $key => $child) {
if (!is_string($key) && !is_int($key)) {
continue;
}
if (is_int($key)) {
continue;
}
$this->flattenEffectiveConfigPath($path . '.' . $key, $child, $paths);
}
}
/**
* @param array<string, mixed> $governance
* @param list<string> $errors