addOption('summary', null, InputOption::VALUE_NONE, 'Render a compact summary instead of JSON.'); } protected function execute(InputInterface $input, OutputInterface $output): int { $config = $this->provider->dump(); if ((bool) $input->getOption('summary')) { $this->renderSummary(new SymfonyStyle($input, $output), $config); return Command::SUCCESS; } $json = json_encode($config, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); $output->writeln(is_string($json) ? $json : '{}'); return Command::SUCCESS; } /** * @param array $config */ private function renderSummary(SymfonyStyle $io, array $config): void { $io->title('RetrieX effective configuration'); $runtime = $this->section($config, 'runtime'); $model = $this->section($config, 'model_generation'); $index = $this->section($config, 'index'); $retrieval = $this->section($config, 'retrieval'); $vector = $this->section($config, 'vector'); $commerce = $this->section($config, 'commerce'); $prompt = $this->section($config, 'prompt'); $agent = $this->section($config, 'agent'); $intent = $this->section($config, 'intent'); $vocabulary = $this->section($config, 'vocabulary'); $searchRepair = $this->section($config, 'search_repair'); $commerceQuery = $this->section($config, 'commerce_query'); $shopMatching = $this->section($config, 'shop_matching'); $language = $this->section($config, 'language'); $queryEnrichment = $this->section($config, 'query_enrichment'); $io->section('Runtime'); $io->definitionList( ['root' => (string) ($runtime['root'] ?? '')], ['knowledge_root' => (string) ($runtime['knowledge_root'] ?? '')], ['index_ndjson' => (string) ($runtime['index_ndjson'] ?? '')] ); $io->section('Model'); $io->definitionList( ['model_name' => (string) ($model['model_name'] ?? $model['default_model_name'] ?? '')], ['num_ctx' => (string) ($model['num_ctx'] ?? $model['default_num_ctx'] ?? '')], ['retrieval_max_chunks' => (string) ($model['retrieval_max_chunks'] ?? $model['default_retrieval_max_chunks'] ?? '')], ['retrieval_vector_top_k' => (string) ($model['retrieval_vector_top_k'] ?? $model['default_retrieval_vector_top_k'] ?? '')] ); $io->section('Index'); $io->definitionList( ['chunk_size' => (string) ($index['chunk_size'] ?? $index['fallback_chunk_size'] ?? '')], ['chunk_overlap' => (string) ($index['chunk_overlap'] ?? $index['fallback_chunk_overlap'] ?? '')], ['embedding_model' => (string) ($index['embedding_model'] ?? $index['fallback_embedding_model'] ?? '')], ['embedding_dimension' => (string) ($index['embedding_dimension'] ?? $index['fallback_embedding_dimension'] ?? '')] ); $io->section('Retrieval'); $io->definitionList( ['hard_max_chunks' => (string) ($retrieval['hard_max_chunks'] ?? '')], ['hard_max_vectork' => (string) ($retrieval['hard_max_vectork'] ?? '')], ['vector_score_threshold' => (string) ($retrieval['vector_score_threshold'] ?? '')], ['retrieval_vocabulary_lists' => (string) $this->countMapEntries($retrieval['vocabulary'] ?? [])] ); $io->section('Vector'); $io->definitionList( ['service_url' => (string) ($vector['service_url'] ?? '')], ['port' => (string) ($vector['port'] ?? '')], ['timeout' => (string) ($vector['timeout'] ?? '')] ); $io->section('Commerce'); $io->definitionList( ['enabled' => $this->formatBool($commerce['enabled'] ?? false)], ['max_shop_results' => (string) ($commerce['max_shop_results'] ?? '')], ['store_api_base_url' => (string) ($commerce['store_api_base_url'] ?? '')], ['commerce_query_lists' => (string) $this->countMapEntries($commerceQuery)], ['shop_matching_lists' => (string) $this->countMapEntries($shopMatching)], ['search_repair_lists' => (string) $this->countMapEntries($searchRepair)] ); $io->section('Centralized YAML-backed configuration'); $io->definitionList( ['vocabulary_classes' => (string) $this->countMapEntries($this->section($vocabulary, 'classes'))], ['vocabulary_views' => (string) $this->countMapEntries($this->section($vocabulary, 'views'))], ['intent_sections' => (string) $this->countMapEntries($intent)], ['prompt_rule_groups' => (string) $this->countMapEntries($this->section($prompt, 'rules'))], ['agent_message_groups' => (string) $this->countMapEntries($this->section($agent, 'messages'))], ['stopwords' => (string) $this->countListEntries($language['stopwords'] ?? [])], ['query_enrichment_rules' => (string) $this->countMapEntries($queryEnrichment['rules'] ?? [])] ); } /** * @param array $data * @return array */ private function section(array $data, string $key): array { return isset($data[$key]) && is_array($data[$key]) ? $data[$key] : []; } private function formatBool(mixed $value): string { return filter_var($value, FILTER_VALIDATE_BOOLEAN) ? 'yes' : 'no'; } private function countMapEntries(mixed $value): int { return is_array($value) ? count($value) : 0; } private function countListEntries(mixed $value): int { return is_array($value) ? count($value) : 0; } }