1#![allow(clippy::needless_borrow, clippy::manual_clamp)]
9
10use super::*;
11use crate::Result;
12use std::fs;
13
14impl Config {
15 pub fn from_file(path: &str) -> Result<Self> {
17 let content = fs::read_to_string(path)?;
18 let parsed = json::parse(&content)?;
19
20 let config = Config {
21 output_dir: parsed["output_dir"]
22 .as_str()
23 .unwrap_or("./output")
24 .to_string(),
25 suppress_progress_bars: parsed["suppress_progress_bars"].as_bool().unwrap_or(false),
26 chunk_size: parsed["chunk_size"]
27 .as_usize()
28 .unwrap_or(default_chunk_size()),
29 chunk_overlap: parsed["chunk_overlap"]
30 .as_usize()
31 .unwrap_or(default_chunk_overlap()),
32 max_entities_per_chunk: parsed["max_entities_per_chunk"].as_usize(),
33 top_k_results: parsed["top_k_results"].as_usize(),
34 similarity_threshold: parsed["similarity_threshold"].as_f32(),
35 approach: parsed["approach"]
36 .as_str()
37 .unwrap_or(&default_approach())
38 .to_string(),
39 embeddings: EmbeddingConfig {
40 dimension: parsed["embeddings"]["dimension"]
41 .as_usize()
42 .unwrap_or(default_embedding_dim()),
43 backend: parsed["embeddings"]["backend"]
44 .as_str()
45 .unwrap_or(&default_embedding_backend())
46 .to_string(),
47 model: parsed["embeddings"]["model"]
48 .as_str()
49 .map(|s| s.to_string()),
50 fallback_to_hash: parsed["embeddings"]["fallback_to_hash"]
51 .as_bool()
52 .unwrap_or(true),
53 api_endpoint: parsed["embeddings"]["api_endpoint"]
54 .as_str()
55 .map(|s| s.to_string()),
56 api_key: parsed["embeddings"]["api_key"]
57 .as_str()
58 .map(|s| s.to_string()),
59 cache_dir: parsed["embeddings"]["cache_dir"]
60 .as_str()
61 .map(|s| s.to_string()),
62 batch_size: parsed["embeddings"]["batch_size"]
63 .as_usize()
64 .unwrap_or(default_batch_size()),
65 },
66 graph: GraphConfig {
67 max_connections: parsed["graph"]["max_connections"]
68 .as_usize()
69 .unwrap_or(default_max_connections()),
70 similarity_threshold: parsed["graph"]["similarity_threshold"]
71 .as_f32()
72 .unwrap_or(default_similarity_threshold()),
73 extract_relationships: parsed["graph"]["extract_relationships"]
74 .as_bool()
75 .unwrap_or(default_true()),
76 relationship_confidence_threshold: parsed["graph"]
77 ["relationship_confidence_threshold"]
78 .as_f32()
79 .unwrap_or(default_relationship_confidence()),
80 traversal: TraversalConfigParams {
81 max_depth: parsed["graph"]["traversal"]["max_depth"]
82 .as_usize()
83 .unwrap_or(default_max_traversal_depth()),
84 max_paths: parsed["graph"]["traversal"]["max_paths"]
85 .as_usize()
86 .unwrap_or(default_max_paths()),
87 use_edge_weights: parsed["graph"]["traversal"]["use_edge_weights"]
88 .as_bool()
89 .unwrap_or(default_true()),
90 min_relationship_strength: parsed["graph"]["traversal"]
91 ["min_relationship_strength"]
92 .as_f32()
93 .unwrap_or(default_min_relationship_strength()),
94 },
95 },
96 text: TextConfig {
97 chunk_size: parsed["text"]["chunk_size"]
98 .as_usize()
99 .unwrap_or(default_chunk_size()),
100 chunk_overlap: parsed["text"]["chunk_overlap"]
101 .as_usize()
102 .unwrap_or(default_chunk_overlap()),
103 languages: if parsed["text"]["languages"].is_array() {
104 parsed["text"]["languages"]
105 .members()
106 .map(|v| v.as_str().unwrap_or("en").to_string())
107 .collect()
108 } else {
109 default_languages()
110 },
111 },
112 entities: EntityConfig {
113 min_confidence: parsed["entities"]["min_confidence"]
114 .as_f32()
115 .unwrap_or(default_min_confidence()),
116 entity_types: if parsed["entities"]["entity_types"].is_array() {
117 parsed["entities"]["entity_types"]
118 .members()
119 .map(|v| v.as_str().unwrap_or("PERSON").to_string())
120 .collect()
121 } else {
122 default_entity_types()
123 },
124 use_gleaning: parsed["entities"]["use_gleaning"]
125 .as_bool()
126 .unwrap_or(false),
127 max_gleaning_rounds: parsed["entities"]["max_gleaning_rounds"]
128 .as_usize()
129 .unwrap_or(default_max_gleaning_rounds()),
130 enable_triple_reflection: parsed["entities"]["enable_triple_reflection"]
131 .as_bool()
132 .unwrap_or(false),
133 validation_min_confidence: parsed["entities"]["validation_min_confidence"]
134 .as_f32()
135 .unwrap_or(default_validation_confidence()),
136 use_atomic_facts: parsed["entities"]["use_atomic_facts"]
137 .as_bool()
138 .unwrap_or(false),
139 max_fact_tokens: parsed["entities"]["max_fact_tokens"]
140 .as_usize()
141 .unwrap_or(default_max_fact_tokens()),
142 },
143 retrieval: RetrievalConfig {
144 top_k: parsed["retrieval"]["top_k"]
145 .as_usize()
146 .unwrap_or(default_top_k()),
147 search_algorithm: parsed["retrieval"]["search_algorithm"]
148 .as_str()
149 .unwrap_or(&default_search_algorithm())
150 .to_string(),
151 },
152 parallel: ParallelConfig {
153 num_threads: parsed["parallel"]["num_threads"]
154 .as_usize()
155 .unwrap_or(default_num_threads()),
156 enabled: parsed["parallel"]["enabled"].as_bool().unwrap_or(true),
157 min_batch_size: parsed["parallel"]["min_batch_size"]
158 .as_usize()
159 .unwrap_or(default_min_batch_size()),
160 chunk_batch_size: parsed["parallel"]["chunk_batch_size"]
161 .as_usize()
162 .unwrap_or(default_chunk_batch_size()),
163 parallel_embeddings: parsed["parallel"]["parallel_embeddings"]
164 .as_bool()
165 .unwrap_or(true),
166 parallel_graph_ops: parsed["parallel"]["parallel_graph_ops"]
167 .as_bool()
168 .unwrap_or(true),
169 parallel_vector_ops: parsed["parallel"]["parallel_vector_ops"]
170 .as_bool()
171 .unwrap_or(true),
172 },
173 ollama: crate::ollama::OllamaConfig {
174 enabled: parsed["ollama"]["enabled"].as_bool().unwrap_or(false),
175 host: parsed["ollama"]["host"]
176 .as_str()
177 .unwrap_or("http://localhost")
178 .to_string(),
179 port: parsed["ollama"]["port"].as_u16().unwrap_or(11434),
180 embedding_model: parsed["ollama"]["embedding_model"]
181 .as_str()
182 .unwrap_or("nomic-embed-text")
183 .to_string(),
184 chat_model: parsed["ollama"]["chat_model"]
185 .as_str()
186 .unwrap_or("llama3.2:3b")
187 .to_string(),
188 timeout_seconds: parsed["ollama"]["timeout_seconds"].as_u64().unwrap_or(30),
189 max_retries: parsed["ollama"]["max_retries"].as_u32().unwrap_or(3),
190 fallback_to_hash: parsed["ollama"]["fallback_to_hash"]
191 .as_bool()
192 .unwrap_or(true),
193 max_tokens: parsed["ollama"]["max_tokens"].as_u32(),
194 temperature: parsed["ollama"]["temperature"].as_f32(),
195 enable_caching: parsed["ollama"]["enable_caching"].as_bool().unwrap_or(true),
196 keep_alive: parsed["ollama"]["keep_alive"]
197 .as_str()
198 .map(|s| s.to_string()),
199 num_ctx: parsed["ollama"]["num_ctx"].as_u32(),
200 },
201 gliner: GlinerConfig {
202 enabled: parsed["gliner"]["enabled"].as_bool().unwrap_or(false),
203 model_path: parsed["gliner"]["model_path"]
204 .as_str()
205 .unwrap_or("")
206 .to_string(),
207 tokenizer_path: parsed["gliner"]["tokenizer_path"]
208 .as_str()
209 .unwrap_or("")
210 .to_string(),
211 mode: parsed["gliner"]["mode"]
212 .as_str()
213 .unwrap_or("span")
214 .to_string(),
215 entity_labels: if parsed["gliner"]["entity_labels"].is_array() {
216 parsed["gliner"]["entity_labels"]
217 .members()
218 .filter_map(|v| v.as_str().map(|s| s.to_string()))
219 .collect()
220 } else {
221 vec!["person".into(), "organization".into(), "location".into()]
222 },
223 relation_labels: if parsed["gliner"]["relation_labels"].is_array() {
224 parsed["gliner"]["relation_labels"]
225 .members()
226 .filter_map(|v| v.as_str().map(|s| s.to_string()))
227 .collect()
228 } else {
229 vec!["related to".into(), "part of".into()]
230 },
231 entity_threshold: parsed["gliner"]["entity_threshold"].as_f32().unwrap_or(0.4),
232 relation_threshold: parsed["gliner"]["relation_threshold"]
233 .as_f32()
234 .unwrap_or(0.5),
235 use_gpu: parsed["gliner"]["use_gpu"].as_bool().unwrap_or(false),
236 max_concurrent_chunks: parsed["gliner"]["max_concurrent_chunks"].as_usize(),
237 },
238 enhancements: enhancements::EnhancementsConfig {
239 enabled: parsed["enhancements"]["enabled"].as_bool().unwrap_or(true),
240 query_analysis: enhancements::QueryAnalysisConfig {
241 enabled: parsed["enhancements"]["query_analysis"]["enabled"]
242 .as_bool()
243 .unwrap_or(true),
244 min_confidence: parsed["enhancements"]["query_analysis"]["min_confidence"]
245 .as_f32()
246 .unwrap_or(0.6),
247 enable_strategy_suggestion: parsed["enhancements"]["query_analysis"]
248 ["enable_strategy_suggestion"]
249 .as_bool()
250 .unwrap_or(true),
251 enable_keyword_analysis: parsed["enhancements"]["query_analysis"]
252 ["enable_keyword_analysis"]
253 .as_bool()
254 .unwrap_or(true),
255 enable_complexity_scoring: parsed["enhancements"]["query_analysis"]
256 ["enable_complexity_scoring"]
257 .as_bool()
258 .unwrap_or(true),
259 },
260 adaptive_retrieval: enhancements::AdaptiveRetrievalConfig {
261 enabled: parsed["enhancements"]["adaptive_retrieval"]["enabled"]
262 .as_bool()
263 .unwrap_or(true),
264 use_query_analysis: parsed["enhancements"]["adaptive_retrieval"]
265 ["use_query_analysis"]
266 .as_bool()
267 .unwrap_or(true),
268 enable_cross_strategy_fusion: parsed["enhancements"]["adaptive_retrieval"]
269 ["enable_cross_strategy_fusion"]
270 .as_bool()
271 .unwrap_or(true),
272 diversity_threshold: parsed["enhancements"]["adaptive_retrieval"]
273 ["diversity_threshold"]
274 .as_f32()
275 .unwrap_or(0.8),
276 enable_diversity_selection: parsed["enhancements"]["adaptive_retrieval"]
277 ["enable_diversity_selection"]
278 .as_bool()
279 .unwrap_or(true),
280 enable_confidence_weighting: parsed["enhancements"]["adaptive_retrieval"]
281 ["enable_confidence_weighting"]
282 .as_bool()
283 .unwrap_or(true),
284 },
285 performance_benchmarking: enhancements::BenchmarkingConfig {
286 enabled: parsed["enhancements"]["performance_benchmarking"]["enabled"]
287 .as_bool()
288 .unwrap_or(false),
289 auto_recommendations: parsed["enhancements"]["performance_benchmarking"]
290 ["auto_recommendations"]
291 .as_bool()
292 .unwrap_or(true),
293 comprehensive_testing: parsed["enhancements"]["performance_benchmarking"]
294 ["comprehensive_testing"]
295 .as_bool()
296 .unwrap_or(false),
297 iterations: parsed["enhancements"]["performance_benchmarking"]["iterations"]
298 .as_usize()
299 .unwrap_or(3),
300 include_parallel: parsed["enhancements"]["performance_benchmarking"]
301 ["include_parallel"]
302 .as_bool()
303 .unwrap_or(true),
304 enable_memory_profiling: parsed["enhancements"]["performance_benchmarking"]
305 ["enable_memory_profiling"]
306 .as_bool()
307 .unwrap_or(false),
308 },
309 enhanced_function_registry: enhancements::FunctionRegistryConfig {
310 enabled: parsed["enhancements"]["enhanced_function_registry"]["enabled"]
311 .as_bool()
312 .unwrap_or(true),
313 categorization: parsed["enhancements"]["enhanced_function_registry"]
314 ["categorization"]
315 .as_bool()
316 .unwrap_or(true),
317 usage_statistics: parsed["enhancements"]["enhanced_function_registry"]
318 ["usage_statistics"]
319 .as_bool()
320 .unwrap_or(true),
321 dynamic_registration: parsed["enhancements"]["enhanced_function_registry"]
322 ["dynamic_registration"]
323 .as_bool()
324 .unwrap_or(true),
325 performance_monitoring: parsed["enhancements"]["enhanced_function_registry"]
326 ["performance_monitoring"]
327 .as_bool()
328 .unwrap_or(false),
329 recommendation_system: parsed["enhancements"]["enhanced_function_registry"]
330 ["recommendation_system"]
331 .as_bool()
332 .unwrap_or(true),
333 },
334 #[cfg(feature = "lightrag")]
335 lightrag: enhancements::LightRAGConfig {
336 enabled: parsed["enhancements"]["lightrag"]["enabled"]
337 .as_bool()
338 .unwrap_or(true),
339 max_keywords: parsed["enhancements"]["lightrag"]["max_keywords"]
340 .as_usize()
341 .unwrap_or(20),
342 high_level_weight: parsed["enhancements"]["lightrag"]["high_level_weight"]
343 .as_f32()
344 .unwrap_or(0.6),
345 low_level_weight: parsed["enhancements"]["lightrag"]["low_level_weight"]
346 .as_f32()
347 .unwrap_or(0.4),
348 merge_strategy: parsed["enhancements"]["lightrag"]["merge_strategy"]
349 .as_str()
350 .unwrap_or("weighted")
351 .to_string(),
352 language: parsed["enhancements"]["lightrag"]["language"]
353 .as_str()
354 .unwrap_or("English")
355 .to_string(),
356 enable_cache: parsed["enhancements"]["lightrag"]["enable_cache"]
357 .as_bool()
358 .unwrap_or(true),
359 },
360 #[cfg(feature = "leiden")]
361 leiden: enhancements::LeidenCommunitiesConfig {
362 enabled: parsed["enhancements"]["leiden"]["enabled"]
363 .as_bool()
364 .unwrap_or(true),
365 max_cluster_size: parsed["enhancements"]["leiden"]["max_cluster_size"]
366 .as_usize()
367 .unwrap_or(10),
368 use_lcc: parsed["enhancements"]["leiden"]["use_lcc"]
369 .as_bool()
370 .unwrap_or(true),
371 seed: parsed["enhancements"]["leiden"]["seed"].as_u64(),
372 resolution: parsed["enhancements"]["leiden"]["resolution"]
373 .as_f32()
374 .unwrap_or(1.0),
375 max_levels: parsed["enhancements"]["leiden"]["max_levels"]
376 .as_usize()
377 .unwrap_or(5),
378 min_improvement: parsed["enhancements"]["leiden"]["min_improvement"]
379 .as_f32()
380 .unwrap_or(0.001),
381 enable_hierarchical: parsed["enhancements"]["leiden"]["enable_hierarchical"]
382 .as_bool()
383 .unwrap_or(true),
384 generate_summaries: parsed["enhancements"]["leiden"]["generate_summaries"]
385 .as_bool()
386 .unwrap_or(true),
387 max_summary_length: parsed["enhancements"]["leiden"]["max_summary_length"]
388 .as_usize()
389 .unwrap_or(5),
390 use_extractive_summary: parsed["enhancements"]["leiden"]
391 ["use_extractive_summary"]
392 .as_bool()
393 .unwrap_or(true),
394 adaptive_routing: enhancements::AdaptiveRoutingConfig {
395 enabled: parsed["enhancements"]["leiden"]["adaptive_routing"]["enabled"]
396 .as_bool()
397 .unwrap_or(true),
398 default_level: parsed["enhancements"]["leiden"]["adaptive_routing"]
399 ["default_level"]
400 .as_usize()
401 .unwrap_or(1),
402 keyword_weight: parsed["enhancements"]["leiden"]["adaptive_routing"]
403 ["keyword_weight"]
404 .as_f32()
405 .unwrap_or(0.5),
406 length_weight: parsed["enhancements"]["leiden"]["adaptive_routing"]
407 ["length_weight"]
408 .as_f32()
409 .unwrap_or(0.3),
410 entity_weight: parsed["enhancements"]["leiden"]["adaptive_routing"]
411 ["entity_weight"]
412 .as_f32()
413 .unwrap_or(0.2),
414 },
415 },
416 #[cfg(feature = "cross-encoder")]
417 cross_encoder: enhancements::CrossEncoderConfig {
418 enabled: parsed["enhancements"]["cross_encoder"]["enabled"]
419 .as_bool()
420 .unwrap_or(true),
421 model_name: parsed["enhancements"]["cross_encoder"]["model_name"]
422 .as_str()
423 .unwrap_or("cross-encoder/ms-marco-MiniLM-L-6-v2")
424 .to_string(),
425 max_length: parsed["enhancements"]["cross_encoder"]["max_length"]
426 .as_usize()
427 .unwrap_or(512),
428 batch_size: parsed["enhancements"]["cross_encoder"]["batch_size"]
429 .as_usize()
430 .unwrap_or(32),
431 top_k: parsed["enhancements"]["cross_encoder"]["top_k"]
432 .as_usize()
433 .unwrap_or(10),
434 min_confidence: parsed["enhancements"]["cross_encoder"]["min_confidence"]
435 .as_f32()
436 .unwrap_or(0.0),
437 normalize_scores: parsed["enhancements"]["cross_encoder"]["normalize_scores"]
438 .as_bool()
439 .unwrap_or(true),
440 },
441 #[cfg(feature = "lazygraphrag")]
442 concept_selection: enhancements::ConceptSelectionConfig {
443 enabled: parsed["enhancements"]["concept_selection"]["enabled"]
444 .as_bool()
445 .unwrap_or(true),
446 top_k: parsed["enhancements"]["concept_selection"]["top_k"]
447 .as_usize()
448 .unwrap_or(20),
449 min_score: parsed["enhancements"]["concept_selection"]["min_score"]
450 .as_f32()
451 .unwrap_or(0.1),
452 degree_weight: parsed["enhancements"]["concept_selection"]["degree_weight"]
453 .as_f32()
454 .unwrap_or(0.4),
455 pagerank_weight: parsed["enhancements"]["concept_selection"]["pagerank_weight"]
456 .as_f32()
457 .unwrap_or(0.4),
458 idf_weight: parsed["enhancements"]["concept_selection"]["idf_weight"]
459 .as_f32()
460 .unwrap_or(0.2),
461 use_semantic_matching: parsed["enhancements"]["concept_selection"]
462 ["use_semantic_matching"]
463 .as_bool()
464 .unwrap_or(true),
465 max_query_concepts: parsed["enhancements"]["concept_selection"]
466 ["max_query_concepts"]
467 .as_usize()
468 .unwrap_or(10),
469 },
470 },
471 auto_save: AutoSaveConfig {
472 enabled: parsed["auto_save"]["enabled"].as_bool().unwrap_or(false),
473 base_dir: parsed["auto_save"]["base_dir"]
474 .as_str()
475 .map(|s| s.to_string()),
476 interval_seconds: parsed["auto_save"]["interval_seconds"]
477 .as_u64()
478 .unwrap_or(default_auto_save_interval()),
479 workspace_name: parsed["auto_save"]["workspace_name"]
480 .as_str()
481 .map(|s| s.to_string()),
482 max_versions: parsed["auto_save"]["max_versions"]
483 .as_usize()
484 .unwrap_or(default_max_versions()),
485 },
486 summarization: if parsed["summarization"].is_object() {
487 crate::summarization::HierarchicalConfig {
488 merge_size: parsed["summarization"]["merge_size"]
489 .as_usize()
490 .unwrap_or(3),
491 max_summary_length: parsed["summarization"]["max_summary_length"]
492 .as_usize()
493 .unwrap_or(250),
494 min_node_size: parsed["summarization"]["min_node_size"]
495 .as_usize()
496 .unwrap_or(50),
497 overlap_sentences: parsed["summarization"]["overlap_sentences"]
498 .as_usize()
499 .unwrap_or(2),
500 llm_config: if parsed["summarization"]["llm_config"].is_object() {
501 crate::summarization::LLMConfig {
502 enabled: parsed["summarization"]["llm_config"]["enabled"]
503 .as_bool()
504 .unwrap_or(false),
505 model_name: parsed["summarization"]["llm_config"]["model_name"]
506 .as_str()
507 .unwrap_or("llama3.1:8b")
508 .to_string(),
509 temperature: parsed["summarization"]["llm_config"]["temperature"]
510 .as_f32()
511 .unwrap_or(0.3),
512 max_tokens: parsed["summarization"]["llm_config"]["max_tokens"]
513 .as_usize()
514 .unwrap_or(180),
515 strategy: match parsed["summarization"]["llm_config"]["strategy"]
516 .as_str()
517 .unwrap_or("progressive")
518 {
519 "uniform" => crate::summarization::LLMStrategy::Uniform,
520 "adaptive" => crate::summarization::LLMStrategy::Adaptive,
521 "progressive" => crate::summarization::LLMStrategy::Progressive,
522 _ => crate::summarization::LLMStrategy::Progressive,
523 },
524 level_configs: std::collections::HashMap::new(), }
526 } else {
527 crate::summarization::LLMConfig::default()
528 },
529 }
530 } else {
531 crate::summarization::HierarchicalConfig::default()
532 },
533 zero_cost_approach: if parsed["zero_cost_approach"].is_object() {
534 ZeroCostApproachConfig {
535 approach: parsed["zero_cost_approach"]["approach"]
536 .as_str()
537 .unwrap_or("pure_algorithmic")
538 .to_string(),
539 lazy_graphrag: if parsed["zero_cost_approach"]["lazy_graphrag"].is_object() {
540 LazyGraphRAGConfig {
541 enabled: parsed["zero_cost_approach"]["lazy_graphrag"]["enabled"]
542 .as_bool()
543 .unwrap_or(false),
544 concept_extraction: ConceptExtractionConfig::default(),
545 co_occurrence: CoOccurrenceConfig::default(),
546 indexing: LazyIndexingConfig::default(),
547 query_expansion: LazyQueryExpansionConfig::default(),
548 relevance_scoring: LazyRelevanceScoringConfig::default(),
549 }
550 } else {
551 LazyGraphRAGConfig::default()
552 },
553 e2_graphrag: E2GraphRAGConfig::default(),
554 pure_algorithmic: PureAlgorithmicConfig::default(),
555 hybrid_strategy: HybridStrategyConfig::default(),
556 }
557 } else {
558 ZeroCostApproachConfig::default()
559 },
560 advanced_features: AdvancedFeaturesConfig::default(),
561 };
562
563 Ok(config)
564 }
565
566 pub fn to_file(&self, path: &str) -> Result<()> {
568 let mut config_json = json::JsonValue::new_object();
569
570 let mut embeddings = json::JsonValue::new_object();
572 embeddings["dimension"] = json::JsonValue::from(self.embeddings.dimension);
573 if let Some(endpoint) = &self.embeddings.api_endpoint {
574 embeddings["api_endpoint"] = json::JsonValue::from(endpoint.as_str());
575 }
576 if let Some(key) = &self.embeddings.api_key {
577 embeddings["api_key"] = json::JsonValue::from(key.as_str());
578 }
579 config_json["embeddings"] = embeddings;
580
581 let mut graph = json::JsonValue::new_object();
583 graph["max_connections"] = json::JsonValue::from(self.graph.max_connections);
584 graph["similarity_threshold"] = json::JsonValue::from(self.graph.similarity_threshold);
585 graph["extract_relationships"] = json::JsonValue::from(self.graph.extract_relationships);
586 graph["relationship_confidence_threshold"] =
587 json::JsonValue::from(self.graph.relationship_confidence_threshold);
588
589 let mut traversal = json::JsonValue::new_object();
590 traversal["max_depth"] = json::JsonValue::from(self.graph.traversal.max_depth);
591 traversal["max_paths"] = json::JsonValue::from(self.graph.traversal.max_paths);
592 traversal["use_edge_weights"] =
593 json::JsonValue::from(self.graph.traversal.use_edge_weights);
594 traversal["min_relationship_strength"] =
595 json::JsonValue::from(self.graph.traversal.min_relationship_strength);
596 graph["traversal"] = traversal;
597
598 config_json["graph"] = graph;
599
600 let mut text = json::JsonValue::new_object();
602 text["chunk_size"] = json::JsonValue::from(self.text.chunk_size);
603 text["chunk_overlap"] = json::JsonValue::from(self.text.chunk_overlap);
604 let languages_array: Vec<json::JsonValue> = self
605 .text
606 .languages
607 .iter()
608 .map(|s| json::JsonValue::from(s.as_str()))
609 .collect();
610 text["languages"] = json::JsonValue::from(languages_array);
611 config_json["text"] = text;
612
613 let mut entities = json::JsonValue::new_object();
615 entities["min_confidence"] = json::JsonValue::from(self.entities.min_confidence);
616 let entity_types_array: Vec<json::JsonValue> = self
617 .entities
618 .entity_types
619 .iter()
620 .map(|s| json::JsonValue::from(s.as_str()))
621 .collect();
622 entities["entity_types"] = json::JsonValue::from(entity_types_array);
623 entities["use_gleaning"] = json::JsonValue::from(self.entities.use_gleaning);
624 entities["max_gleaning_rounds"] = json::JsonValue::from(self.entities.max_gleaning_rounds);
625 config_json["entities"] = entities;
626
627 let mut retrieval = json::JsonValue::new_object();
629 retrieval["top_k"] = json::JsonValue::from(self.retrieval.top_k);
630 retrieval["search_algorithm"] =
631 json::JsonValue::from(self.retrieval.search_algorithm.as_str());
632 config_json["retrieval"] = retrieval;
633
634 let mut parallel = json::JsonValue::new_object();
636 parallel["num_threads"] = json::JsonValue::from(self.parallel.num_threads);
637 parallel["enabled"] = json::JsonValue::from(self.parallel.enabled);
638 parallel["min_batch_size"] = json::JsonValue::from(self.parallel.min_batch_size);
639 parallel["chunk_batch_size"] = json::JsonValue::from(self.parallel.chunk_batch_size);
640 parallel["parallel_embeddings"] = json::JsonValue::from(self.parallel.parallel_embeddings);
641 parallel["parallel_graph_ops"] = json::JsonValue::from(self.parallel.parallel_graph_ops);
642 parallel["parallel_vector_ops"] = json::JsonValue::from(self.parallel.parallel_vector_ops);
643 config_json["parallel"] = parallel;
644
645 let mut enhancements = json::JsonValue::new_object();
647 enhancements["enabled"] = json::JsonValue::from(self.enhancements.enabled);
648
649 let mut query_analysis = json::JsonValue::new_object();
650 query_analysis["enabled"] = json::JsonValue::from(self.enhancements.query_analysis.enabled);
651 query_analysis["min_confidence"] =
652 json::JsonValue::from(self.enhancements.query_analysis.min_confidence);
653 query_analysis["enable_strategy_suggestion"] =
654 json::JsonValue::from(self.enhancements.query_analysis.enable_strategy_suggestion);
655 query_analysis["enable_keyword_analysis"] =
656 json::JsonValue::from(self.enhancements.query_analysis.enable_keyword_analysis);
657 query_analysis["enable_complexity_scoring"] =
658 json::JsonValue::from(self.enhancements.query_analysis.enable_complexity_scoring);
659 enhancements["query_analysis"] = query_analysis;
660
661 let mut adaptive_retrieval = json::JsonValue::new_object();
662 adaptive_retrieval["enabled"] =
663 json::JsonValue::from(self.enhancements.adaptive_retrieval.enabled);
664 adaptive_retrieval["use_query_analysis"] =
665 json::JsonValue::from(self.enhancements.adaptive_retrieval.use_query_analysis);
666 adaptive_retrieval["enable_cross_strategy_fusion"] = json::JsonValue::from(
667 self.enhancements
668 .adaptive_retrieval
669 .enable_cross_strategy_fusion,
670 );
671 adaptive_retrieval["diversity_threshold"] =
672 json::JsonValue::from(self.enhancements.adaptive_retrieval.diversity_threshold);
673 adaptive_retrieval["enable_diversity_selection"] = json::JsonValue::from(
674 self.enhancements
675 .adaptive_retrieval
676 .enable_diversity_selection,
677 );
678 adaptive_retrieval["enable_confidence_weighting"] = json::JsonValue::from(
679 self.enhancements
680 .adaptive_retrieval
681 .enable_confidence_weighting,
682 );
683 enhancements["adaptive_retrieval"] = adaptive_retrieval;
684
685 let mut performance_benchmarking = json::JsonValue::new_object();
686 performance_benchmarking["enabled"] =
687 json::JsonValue::from(self.enhancements.performance_benchmarking.enabled);
688 performance_benchmarking["auto_recommendations"] = json::JsonValue::from(
689 self.enhancements
690 .performance_benchmarking
691 .auto_recommendations,
692 );
693 performance_benchmarking["comprehensive_testing"] = json::JsonValue::from(
694 self.enhancements
695 .performance_benchmarking
696 .comprehensive_testing,
697 );
698 performance_benchmarking["iterations"] =
699 json::JsonValue::from(self.enhancements.performance_benchmarking.iterations);
700 performance_benchmarking["include_parallel"] =
701 json::JsonValue::from(self.enhancements.performance_benchmarking.include_parallel);
702 performance_benchmarking["enable_memory_profiling"] = json::JsonValue::from(
703 self.enhancements
704 .performance_benchmarking
705 .enable_memory_profiling,
706 );
707 enhancements["performance_benchmarking"] = performance_benchmarking;
708
709 let mut enhanced_function_registry = json::JsonValue::new_object();
710 enhanced_function_registry["enabled"] =
711 json::JsonValue::from(self.enhancements.enhanced_function_registry.enabled);
712 enhanced_function_registry["categorization"] =
713 json::JsonValue::from(self.enhancements.enhanced_function_registry.categorization);
714 enhanced_function_registry["usage_statistics"] = json::JsonValue::from(
715 self.enhancements
716 .enhanced_function_registry
717 .usage_statistics,
718 );
719 enhanced_function_registry["dynamic_registration"] = json::JsonValue::from(
720 self.enhancements
721 .enhanced_function_registry
722 .dynamic_registration,
723 );
724 enhanced_function_registry["performance_monitoring"] = json::JsonValue::from(
725 self.enhancements
726 .enhanced_function_registry
727 .performance_monitoring,
728 );
729 enhanced_function_registry["recommendation_system"] = json::JsonValue::from(
730 self.enhancements
731 .enhanced_function_registry
732 .recommendation_system,
733 );
734 enhancements["enhanced_function_registry"] = enhanced_function_registry;
735
736 config_json["enhancements"] = enhancements;
737
738 let mut summarization = json::JsonValue::new_object();
740 summarization["merge_size"] = json::JsonValue::from(self.summarization.merge_size);
741 summarization["max_summary_length"] =
742 json::JsonValue::from(self.summarization.max_summary_length);
743 summarization["min_node_size"] = json::JsonValue::from(self.summarization.min_node_size);
744 summarization["overlap_sentences"] =
745 json::JsonValue::from(self.summarization.overlap_sentences);
746
747 let mut llm_config = json::JsonValue::new_object();
748 llm_config["enabled"] = json::JsonValue::from(self.summarization.llm_config.enabled);
749 llm_config["model_name"] =
750 json::JsonValue::from(self.summarization.llm_config.model_name.as_str());
751 llm_config["temperature"] =
752 json::JsonValue::from(self.summarization.llm_config.temperature);
753 llm_config["max_tokens"] = json::JsonValue::from(self.summarization.llm_config.max_tokens);
754 let strategy_str = match self.summarization.llm_config.strategy {
755 crate::summarization::LLMStrategy::Uniform => "uniform",
756 crate::summarization::LLMStrategy::Adaptive => "adaptive",
757 crate::summarization::LLMStrategy::Progressive => "progressive",
758 };
759 llm_config["strategy"] = json::JsonValue::from(strategy_str);
760
761 summarization["llm_config"] = llm_config;
762 config_json["summarization"] = summarization;
763
764 let content = json::stringify_pretty(config_json, 2);
765 fs::write(path, content)?;
766 Ok(())
767 }
768}