local-deep-research 0.4.4__tar.gz → 0.5.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (345) hide show
  1. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/PKG-INFO +7 -1
  2. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/README.md +4 -0
  3. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/pyproject.toml +68 -4
  4. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/__init__.py +7 -0
  5. local_deep_research-0.5.2/src/local_deep_research/__version__.py +1 -0
  6. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/answer_decoding/__init__.py +5 -0
  7. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/answer_decoding/browsecomp_answer_decoder.py +421 -0
  8. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/candidate_exploration/README.md +219 -0
  9. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/candidate_exploration/__init__.py +25 -0
  10. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/candidate_exploration/adaptive_explorer.py +329 -0
  11. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/candidate_exploration/base_explorer.py +341 -0
  12. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/candidate_exploration/constraint_guided_explorer.py +436 -0
  13. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/candidate_exploration/diversity_explorer.py +457 -0
  14. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/candidate_exploration/parallel_explorer.py +250 -0
  15. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/candidate_exploration/progressive_explorer.py +255 -0
  16. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/candidates/__init__.py +5 -0
  17. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/candidates/base_candidate.py +59 -0
  18. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/constraint_checking/README.md +150 -0
  19. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/constraint_checking/__init__.py +35 -0
  20. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/constraint_checking/base_constraint_checker.py +122 -0
  21. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/constraint_checking/constraint_checker.py +223 -0
  22. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/constraint_checking/constraint_satisfaction_tracker.py +387 -0
  23. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/constraint_checking/dual_confidence_checker.py +424 -0
  24. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/constraint_checking/evidence_analyzer.py +174 -0
  25. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/constraint_checking/intelligent_constraint_relaxer.py +503 -0
  26. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/constraint_checking/rejection_engine.py +143 -0
  27. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/constraint_checking/strict_checker.py +259 -0
  28. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/constraint_checking/threshold_checker.py +213 -0
  29. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/constraints/__init__.py +6 -0
  30. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/constraints/base_constraint.py +58 -0
  31. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/constraints/constraint_analyzer.py +143 -0
  32. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/evidence/__init__.py +12 -0
  33. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/evidence/base_evidence.py +57 -0
  34. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/evidence/evaluator.py +159 -0
  35. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/evidence/requirements.py +122 -0
  36. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/advanced_search_system/filters/base_filter.py +3 -1
  37. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/advanced_search_system/filters/cross_engine_filter.py +8 -2
  38. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/advanced_search_system/filters/journal_reputation_filter.py +43 -29
  39. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/advanced_search_system/findings/repository.py +54 -17
  40. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/advanced_search_system/knowledge/standard_knowledge.py +3 -1
  41. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/query_generation/adaptive_query_generator.py +405 -0
  42. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/questions/__init__.py +17 -0
  43. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/questions/atomic_fact_question.py +171 -0
  44. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/questions/browsecomp_question.py +287 -0
  45. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/advanced_search_system/questions/decomposition_question.py +13 -4
  46. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/questions/entity_aware_question.py +184 -0
  47. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/advanced_search_system/questions/standard_question.py +9 -3
  48. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/search_optimization/cross_constraint_manager.py +624 -0
  49. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/source_management/diversity_manager.py +613 -0
  50. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/strategies/__init__.py +43 -0
  51. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/strategies/adaptive_decomposition_strategy.py +564 -0
  52. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/advanced_search_system/strategies/base_strategy.py +4 -4
  53. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/strategies/browsecomp_entity_strategy.py +1031 -0
  54. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/strategies/browsecomp_optimized_strategy.py +778 -0
  55. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/strategies/concurrent_dual_confidence_strategy.py +446 -0
  56. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/strategies/constrained_search_strategy.py +1348 -0
  57. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/strategies/constraint_parallel_strategy.py +522 -0
  58. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/strategies/direct_search_strategy.py +217 -0
  59. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/strategies/dual_confidence_strategy.py +320 -0
  60. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/strategies/dual_confidence_with_rejection.py +219 -0
  61. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/strategies/early_stop_constrained_strategy.py +369 -0
  62. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/strategies/entity_aware_source_strategy.py +140 -0
  63. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/strategies/evidence_based_strategy.py +1248 -0
  64. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/strategies/evidence_based_strategy_v2.py +1337 -0
  65. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/strategies/focused_iteration_strategy.py +537 -0
  66. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/strategies/improved_evidence_based_strategy.py +782 -0
  67. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/strategies/iterative_reasoning_strategy.py +760 -0
  68. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/advanced_search_system/strategies/iterdrag_strategy.py +55 -21
  69. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/strategies/llm_driven_modular_strategy.py +865 -0
  70. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/strategies/modular_strategy.py +1142 -0
  71. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/strategies/parallel_constrained_strategy.py +506 -0
  72. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/advanced_search_system/strategies/parallel_search_strategy.py +34 -16
  73. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/advanced_search_system/strategies/rapid_search_strategy.py +29 -9
  74. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/strategies/recursive_decomposition_strategy.py +492 -0
  75. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/strategies/smart_decomposition_strategy.py +284 -0
  76. local_deep_research-0.5.2/src/local_deep_research/advanced_search_system/strategies/smart_query_strategy.py +515 -0
  77. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/advanced_search_system/strategies/source_based_strategy.py +48 -24
  78. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/advanced_search_system/strategies/standard_strategy.py +34 -14
  79. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/advanced_search_system/tools/base_tool.py +7 -2
  80. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/api/benchmark_functions.py +6 -2
  81. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/api/research_functions.py +10 -4
  82. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/benchmarks/__init__.py +9 -7
  83. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/benchmarks/benchmark_functions.py +6 -2
  84. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/benchmarks/cli/benchmark_commands.py +27 -10
  85. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/benchmarks/cli.py +38 -13
  86. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/benchmarks/comparison/__init__.py +4 -2
  87. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/benchmarks/comparison/evaluator.py +316 -239
  88. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/benchmarks/datasets/__init__.py +1 -1
  89. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/benchmarks/datasets/base.py +91 -72
  90. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/benchmarks/datasets/browsecomp.py +54 -33
  91. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/benchmarks/datasets/custom_dataset_template.py +19 -19
  92. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/benchmarks/datasets/simpleqa.py +14 -14
  93. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/benchmarks/datasets/utils.py +48 -29
  94. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/benchmarks/datasets.py +4 -11
  95. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/benchmarks/efficiency/__init__.py +8 -4
  96. local_deep_research-0.5.2/src/local_deep_research/benchmarks/efficiency/resource_monitor.py +419 -0
  97. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/benchmarks/efficiency/speed_profiler.py +62 -48
  98. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/benchmarks/evaluators/browsecomp.py +3 -1
  99. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/benchmarks/evaluators/composite.py +6 -2
  100. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/benchmarks/evaluators/simpleqa.py +36 -13
  101. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/benchmarks/graders.py +32 -10
  102. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/benchmarks/metrics/README.md +1 -1
  103. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/benchmarks/metrics/calculation.py +25 -10
  104. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/benchmarks/metrics/reporting.py +7 -3
  105. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/benchmarks/metrics/visualization.py +42 -23
  106. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/benchmarks/metrics.py +1 -1
  107. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/benchmarks/optimization/__init__.py +3 -1
  108. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/benchmarks/optimization/api.py +7 -1
  109. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/benchmarks/optimization/optuna_optimizer.py +75 -26
  110. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/benchmarks/runners.py +48 -15
  111. local_deep_research-0.5.2/src/local_deep_research/citation_handler.py +89 -0
  112. local_deep_research-0.5.2/src/local_deep_research/citation_handlers/__init__.py +15 -0
  113. local_deep_research-0.5.2/src/local_deep_research/citation_handlers/base_citation_handler.py +70 -0
  114. local_deep_research-0.5.2/src/local_deep_research/citation_handlers/forced_answer_citation_handler.py +179 -0
  115. local_deep_research-0.5.2/src/local_deep_research/citation_handlers/precision_extraction_handler.py +550 -0
  116. local_deep_research-0.4.4/src/local_deep_research/citation_handler.py → local_deep_research-0.5.2/src/local_deep_research/citation_handlers/standard_citation_handler.py +12 -48
  117. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/config/llm_config.py +271 -169
  118. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/config/search_config.py +14 -5
  119. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/defaults/__init__.py +0 -1
  120. local_deep_research-0.5.2/src/local_deep_research/metrics/__init__.py +13 -0
  121. local_deep_research-0.5.2/src/local_deep_research/metrics/database.py +58 -0
  122. local_deep_research-0.5.2/src/local_deep_research/metrics/db_models.py +115 -0
  123. local_deep_research-0.5.2/src/local_deep_research/metrics/migrate_add_provider_to_token_usage.py +148 -0
  124. local_deep_research-0.5.2/src/local_deep_research/metrics/migrate_call_stack_tracking.py +105 -0
  125. local_deep_research-0.5.2/src/local_deep_research/metrics/migrate_enhanced_tracking.py +75 -0
  126. local_deep_research-0.5.2/src/local_deep_research/metrics/migrate_research_ratings.py +31 -0
  127. local_deep_research-0.5.2/src/local_deep_research/metrics/models.py +61 -0
  128. local_deep_research-0.5.2/src/local_deep_research/metrics/pricing/__init__.py +12 -0
  129. local_deep_research-0.5.2/src/local_deep_research/metrics/pricing/cost_calculator.py +237 -0
  130. local_deep_research-0.5.2/src/local_deep_research/metrics/pricing/pricing_cache.py +143 -0
  131. local_deep_research-0.5.2/src/local_deep_research/metrics/pricing/pricing_fetcher.py +240 -0
  132. local_deep_research-0.5.2/src/local_deep_research/metrics/query_utils.py +51 -0
  133. local_deep_research-0.5.2/src/local_deep_research/metrics/search_tracker.py +380 -0
  134. local_deep_research-0.5.2/src/local_deep_research/metrics/token_counter.py +1078 -0
  135. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/migrate_db.py +3 -1
  136. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/report_generator.py +22 -8
  137. local_deep_research-0.5.2/src/local_deep_research/search_system.py +582 -0
  138. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/test_migration.py +15 -5
  139. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/utilities/db_utils.py +7 -4
  140. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/utilities/es_utils.py +115 -104
  141. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/utilities/llm_utils.py +15 -5
  142. local_deep_research-0.5.2/src/local_deep_research/utilities/log_utils.py +187 -0
  143. local_deep_research-0.5.2/src/local_deep_research/utilities/search_cache.py +387 -0
  144. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/utilities/search_utilities.py +14 -6
  145. local_deep_research-0.5.2/src/local_deep_research/utilities/threading_utils.py +92 -0
  146. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/utilities/url_utils.py +6 -0
  147. local_deep_research-0.5.2/src/local_deep_research/web/api.py +347 -0
  148. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/app.py +13 -17
  149. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/app_factory.py +71 -66
  150. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/database/migrate_to_ldr_db.py +12 -4
  151. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/database/migrations.py +20 -3
  152. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/database/models.py +74 -25
  153. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/database/schema_upgrade.py +49 -29
  154. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/models/database.py +63 -83
  155. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/routes/api_routes.py +56 -22
  156. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/routes/benchmark_routes.py +4 -1
  157. local_deep_research-0.5.2/src/local_deep_research/web/routes/globals.py +22 -0
  158. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/routes/history_routes.py +71 -46
  159. local_deep_research-0.5.2/src/local_deep_research/web/routes/metrics_routes.py +1155 -0
  160. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/routes/research_routes.py +192 -54
  161. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/routes/settings_routes.py +156 -55
  162. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/services/research_service.py +412 -251
  163. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/services/resource_service.py +36 -11
  164. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/services/settings_manager.py +55 -17
  165. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/services/settings_service.py +12 -4
  166. local_deep_research-0.5.2/src/local_deep_research/web/services/socket_service.py +317 -0
  167. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/static/css/custom_dropdown.css +180 -0
  168. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/static/css/styles.css +39 -1
  169. local_deep_research-0.5.2/src/local_deep_research/web/static/js/components/detail.js +714 -0
  170. local_deep_research-0.5.2/src/local_deep_research/web/static/js/components/details.js +751 -0
  171. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/static/js/components/fallback/formatting.js +11 -11
  172. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/static/js/components/fallback/ui.js +23 -23
  173. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/static/js/components/history.js +76 -76
  174. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/static/js/components/logpanel.js +61 -13
  175. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/static/js/components/progress.js +13 -2
  176. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/static/js/components/research.js +99 -12
  177. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/static/js/components/results.js +239 -106
  178. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/static/js/main.js +40 -40
  179. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/static/js/services/audio.js +1 -1
  180. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/static/js/services/formatting.js +11 -11
  181. local_deep_research-0.5.2/src/local_deep_research/web/static/js/services/keyboard.js +157 -0
  182. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/static/js/services/pdf.js +80 -80
  183. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/static/sounds/README.md +1 -1
  184. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/templates/base.html +1 -0
  185. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/templates/components/log_panel.html +7 -1
  186. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/templates/components/mobile_nav.html +1 -1
  187. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/templates/components/sidebar.html +3 -0
  188. local_deep_research-0.5.2/src/local_deep_research/web/templates/pages/cost_analytics.html +1245 -0
  189. local_deep_research-0.5.2/src/local_deep_research/web/templates/pages/details.html +374 -0
  190. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/templates/pages/history.html +1 -1
  191. local_deep_research-0.5.2/src/local_deep_research/web/templates/pages/metrics.html +1929 -0
  192. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/templates/pages/progress.html +2 -2
  193. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/templates/pages/research.html +53 -17
  194. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/templates/pages/results.html +12 -1
  195. local_deep_research-0.5.2/src/local_deep_research/web/templates/pages/star_reviews.html +803 -0
  196. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/utils/formatters.py +9 -3
  197. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web_search_engines/default_search_engines.py +5 -3
  198. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web_search_engines/engines/full_search.py +8 -2
  199. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web_search_engines/engines/meta_search_engine.py +59 -20
  200. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web_search_engines/engines/search_engine_arxiv.py +19 -6
  201. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web_search_engines/engines/search_engine_brave.py +6 -2
  202. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web_search_engines/engines/search_engine_ddg.py +3 -1
  203. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web_search_engines/engines/search_engine_elasticsearch.py +81 -58
  204. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web_search_engines/engines/search_engine_github.py +46 -15
  205. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web_search_engines/engines/search_engine_google_pse.py +16 -6
  206. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web_search_engines/engines/search_engine_guardian.py +39 -15
  207. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web_search_engines/engines/search_engine_local.py +58 -25
  208. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web_search_engines/engines/search_engine_local_all.py +15 -5
  209. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web_search_engines/engines/search_engine_pubmed.py +63 -21
  210. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web_search_engines/engines/search_engine_searxng.py +37 -11
  211. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web_search_engines/engines/search_engine_semantic_scholar.py +27 -9
  212. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web_search_engines/engines/search_engine_serpapi.py +12 -4
  213. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web_search_engines/engines/search_engine_wayback.py +31 -10
  214. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web_search_engines/engines/search_engine_wikipedia.py +12 -3
  215. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web_search_engines/search_engine_base.py +83 -35
  216. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web_search_engines/search_engine_factory.py +25 -8
  217. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web_search_engines/search_engines_config.py +9 -3
  218. local_deep_research-0.5.2/tests/CI_INTEGRATION.md +81 -0
  219. local_deep_research-0.5.2/tests/README.md +368 -0
  220. local_deep_research-0.5.2/tests/TESTING_COMPARISON.md +148 -0
  221. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/tests/TESTING_PROPOSAL.md +6 -6
  222. local_deep_research-0.5.2/tests/api_tests/README.md +75 -0
  223. local_deep_research-0.5.2/tests/api_tests/__init__.py +1 -0
  224. local_deep_research-0.5.2/tests/api_tests/test_api_basic.py +93 -0
  225. local_deep_research-0.5.2/tests/api_tests/test_api_pytest.py +131 -0
  226. local_deep_research-0.5.2/tests/api_tests/test_rest_api.py +123 -0
  227. local_deep_research-0.5.2/tests/api_tests/test_rest_api_simple.py +139 -0
  228. local_deep_research-0.5.2/tests/conftest.py +318 -0
  229. local_deep_research-0.4.4/tests/download_stuff_for_local_test.py → local_deep_research-0.5.2/tests/download_stuff_for_local.py +4 -1
  230. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/tests/feature_tests/test_custom_context.py +11 -5
  231. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/tests/fix_tests/README.md +1 -1
  232. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/tests/fix_tests/test_duplicate_links_fix.py +51 -31
  233. local_deep_research-0.5.2/tests/fixtures/README.md +53 -0
  234. local_deep_research-0.5.2/tests/fixtures/search_engine_mocks.py +251 -0
  235. local_deep_research-0.5.2/tests/health_check/README.md +271 -0
  236. local_deep_research-0.5.2/tests/health_check/run_quick_health_check.py +88 -0
  237. local_deep_research-0.5.2/tests/health_check/test_endpoints_health.py +201 -0
  238. local_deep_research-0.5.2/tests/health_check/test_endpoints_health.sh +119 -0
  239. local_deep_research-0.5.2/tests/mock_fixtures.py +248 -0
  240. local_deep_research-0.5.2/tests/mock_llm_config.py +58 -0
  241. local_deep_research-0.5.2/tests/mock_modules.py +188 -0
  242. local_deep_research-0.5.2/tests/run_all_tests.py +572 -0
  243. local_deep_research-0.5.2/tests/search_engines/test_wikipedia_search.py +205 -0
  244. local_deep_research-0.5.2/tests/searxng/__init__.py +1 -0
  245. local_deep_research-0.5.2/tests/searxng/test_searxng.py +147 -0
  246. local_deep_research-0.5.2/tests/strategies/__init__.py +1 -0
  247. local_deep_research-0.5.2/tests/strategies/compare_strategies_visual.py +382 -0
  248. local_deep_research-0.5.2/tests/strategies/test_adaptive_strategy.py +137 -0
  249. local_deep_research-0.5.2/tests/strategies/test_iterative_reasoning.py +230 -0
  250. local_deep_research-0.5.2/tests/strategies/test_search_system_iterative.py +104 -0
  251. local_deep_research-0.5.2/tests/test_ci_config.py +19 -0
  252. local_deep_research-0.5.2/tests/test_citation_handler.py +202 -0
  253. local_deep_research-0.5.2/tests/test_google_pse.py +159 -0
  254. local_deep_research-0.5.2/tests/test_report_generator.py +319 -0
  255. local_deep_research-0.5.2/tests/test_research_strategy_orm.py +224 -0
  256. local_deep_research-0.5.2/tests/test_search_engines_enhanced.py +359 -0
  257. local_deep_research-0.5.2/tests/test_search_system.py +313 -0
  258. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/tests/test_settings_manager.py +127 -6
  259. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/tests/test_url_utils.py +22 -7
  260. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/tests/test_url_utils_simple.py +7 -2
  261. local_deep_research-0.5.2/tests/test_utils.py +212 -0
  262. local_deep_research-0.5.2/tests/test_wikipedia_url_security.py +165 -0
  263. local_deep_research-0.5.2/tests/ui_tests/README.md +230 -0
  264. local_deep_research-0.5.2/tests/ui_tests/__init__.py +1 -0
  265. local_deep_research-0.5.2/tests/ui_tests/run_all_tests.js +135 -0
  266. local_deep_research-0.5.2/tests/ui_tests/test_charts.js +76 -0
  267. local_deep_research-0.5.2/tests/ui_tests/test_cost_analytics.js +229 -0
  268. local_deep_research-0.5.2/tests/ui_tests/test_metrics.js +70 -0
  269. local_deep_research-0.5.2/tests/ui_tests/test_metrics_browser.js +89 -0
  270. local_deep_research-0.5.2/tests/ui_tests/test_metrics_chart.js +15 -0
  271. local_deep_research-0.5.2/tests/ui_tests/test_metrics_charts.js +80 -0
  272. local_deep_research-0.5.2/tests/ui_tests/test_metrics_only.js +96 -0
  273. local_deep_research-0.5.2/tests/ui_tests/test_network_requests.js +92 -0
  274. local_deep_research-0.5.2/tests/ui_tests/test_pages_browser.js +284 -0
  275. local_deep_research-0.5.2/tests/ui_tests/test_research_results.js +149 -0
  276. local_deep_research-0.5.2/tests/ui_tests/test_settings_errors.js +107 -0
  277. local_deep_research-0.5.2/tests/ui_tests/test_settings_page.js +62 -0
  278. local_deep_research-0.5.2/tests/ui_tests/test_settings_save.js +100 -0
  279. local_deep_research-0.5.2/tests/ui_tests/test_star_reviews.js +156 -0
  280. local_deep_research-0.5.2/tests/ui_tests/test_star_reviews_debug.js +202 -0
  281. local_deep_research-0.4.4/src/local_deep_research/__version__.py +0 -1
  282. local_deep_research-0.4.4/src/local_deep_research/advanced_search_system/questions/__init__.py +0 -1
  283. local_deep_research-0.4.4/src/local_deep_research/advanced_search_system/strategies/__init__.py +0 -1
  284. local_deep_research-0.4.4/src/local_deep_research/benchmarks/efficiency/resource_monitor.py +0 -367
  285. local_deep_research-0.4.4/src/local_deep_research/search_system.py +0 -201
  286. local_deep_research-0.4.4/src/local_deep_research/utilities/log_utils.py +0 -36
  287. local_deep_research-0.4.4/src/local_deep_research/web/services/socket_service.py +0 -210
  288. local_deep_research-0.4.4/src/local_deep_research/web/static/js/components/detail.js +0 -348
  289. local_deep_research-0.4.4/src/local_deep_research/web/templates/pages/details.html +0 -73
  290. local_deep_research-0.4.4/tests/conftest.py +0 -119
  291. local_deep_research-0.4.4/tests/searxng/test_searxng_instance.py +0 -39
  292. local_deep_research-0.4.4/tests/searxng/test_searxng_integration.py +0 -16
  293. local_deep_research-0.4.4/tests/test_google_pse.py +0 -233
  294. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/LICENSE +0 -0
  295. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/advanced_search_system/__init__.py +0 -0
  296. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/advanced_search_system/filters/__init__.py +0 -0
  297. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/advanced_search_system/findings/base_findings.py +0 -0
  298. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/advanced_search_system/knowledge/__init__.py +0 -0
  299. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/advanced_search_system/knowledge/base_knowledge.py +0 -0
  300. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/advanced_search_system/questions/base_question.py +0 -0
  301. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/advanced_search_system/repositories/__init__.py +0 -0
  302. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/advanced_search_system/tools/__init__.py +0 -0
  303. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/advanced_search_system/tools/knowledge_tools/__init__.py +0 -0
  304. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/advanced_search_system/tools/question_tools/__init__.py +0 -0
  305. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/advanced_search_system/tools/search_tools/__init__.py +0 -0
  306. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/api/__init__.py +0 -0
  307. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/benchmarks/README.md +0 -0
  308. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/benchmarks/cli/__init__.py +0 -0
  309. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/benchmarks/evaluators/__init__.py +0 -0
  310. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/benchmarks/evaluators/base.py +0 -0
  311. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/benchmarks/metrics/__init__.py +0 -0
  312. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/benchmarks/optimization/metrics.py +0 -0
  313. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/benchmarks/templates.py +0 -0
  314. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/config/__init__.py +0 -0
  315. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/defaults/.env.template +0 -0
  316. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/defaults/default_settings.json +0 -0
  317. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/setup_data_dir.py +0 -0
  318. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/utilities/__init__.py +0 -0
  319. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/utilities/enums.py +0 -0
  320. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/utilities/setup_utils.py +0 -0
  321. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/__init__.py +0 -0
  322. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/database/README.md +0 -0
  323. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/models/settings.py +0 -0
  324. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/static/css/settings.css +0 -0
  325. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/static/js/components/custom_dropdown.js +0 -0
  326. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/static/js/components/settings.js +0 -0
  327. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/static/js/components/settings_sync.js +0 -0
  328. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/static/js/research_form.js +0 -0
  329. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/static/js/services/api.js +0 -0
  330. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/static/js/services/socket.js +0 -0
  331. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/static/js/services/ui.js +0 -0
  332. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/static/sounds/error.mp3 +0 -0
  333. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/static/sounds/success.mp3 +0 -0
  334. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/templates/components/custom_dropdown.html +0 -0
  335. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/templates/components/settings_form.html +0 -0
  336. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/templates/settings_dashboard.html +0 -0
  337. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/utils/__init__.py +0 -0
  338. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web/utils/templates.py +0 -0
  339. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web_search_engines/__init__.py +0 -0
  340. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/src/local_deep_research/web_search_engines/engines/__init__.py +0 -0
  341. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/tests/__init__.py +0 -0
  342. /local_deep_research-0.4.4/tests/test_url_utils_debug.py → /local_deep_research-0.5.2/tests/debug_url_utils.py +0 -0
  343. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/tests/feature_tests/IMPLEMENTATION_GUIDE_241.md +0 -0
  344. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/tests/feature_tests/README.md +0 -0
  345. {local_deep_research-0.4.4 → local_deep_research-0.5.2}/tests/feature_tests/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: local-deep-research
3
- Version: 0.4.4
3
+ Version: 0.5.2
4
4
  Summary: AI-powered research assistant with deep, iterative analysis using LLMs and web searches
5
5
  Author-Email: LearningCircuit <185559241+LearningCircuit@users.noreply.github.com>, HashedViking <6432677+HashedViking@users.noreply.github.com>
6
6
  License: MIT License
@@ -71,10 +71,12 @@ Requires-Dist: optuna>=4.3.0
71
71
  Requires-Dist: elasticsearch==8.14.0
72
72
  Requires-Dist: methodtools>=0.4.7
73
73
  Requires-Dist: loguru>=0.7.3
74
+ Requires-Dist: cachetools>=5.5.2
74
75
  Requires-Dist: matplotlib>=3.10.3
75
76
  Requires-Dist: pandas>=2.2.3
76
77
  Requires-Dist: plotly>=6.0.1
77
78
  Requires-Dist: kaleido==0.2.1
79
+ Requires-Dist: aiohttp>=3.9.0
78
80
  Description-Content-Type: text/markdown
79
81
 
80
82
  # Local Deep Research
@@ -400,6 +402,10 @@ For more information and examples of what Local Deep Research can produce:
400
402
  - [Reddit](https://www.reddit.com/r/LocalDeepResearch/): Announcements, updates, and community showcase
401
403
  - [GitHub Issues](https://github.com/LearningCircuit/local-deep-research/issues): Bug reports and feature requests
402
404
 
405
+ ## 🚀 Contributing
406
+
407
+ We welcome contributions! Whether you're fixing bugs, adding features, or improving documentation, we'd love to have you as part of our community. Please see our [Contributing Guide](CONTRIBUTING.md) for guidelines on how to get started.
408
+
403
409
  ## 📄 License & Acknowledgments
404
410
 
405
411
  This project is licensed under the MIT License.
@@ -321,6 +321,10 @@ For more information and examples of what Local Deep Research can produce:
321
321
  - [Reddit](https://www.reddit.com/r/LocalDeepResearch/): Announcements, updates, and community showcase
322
322
  - [GitHub Issues](https://github.com/LearningCircuit/local-deep-research/issues): Bug reports and feature requests
323
323
 
324
+ ## 🚀 Contributing
325
+
326
+ We welcome contributions! Whether you're fixing bugs, adding features, or improving documentation, we'd love to have you as part of our community. Please see our [Contributing Guide](CONTRIBUTING.md) for guidelines on how to get started.
327
+
324
328
  ## 📄 License & Acknowledgments
325
329
 
326
330
  This project is licensed under the MIT License.
@@ -60,12 +60,14 @@ dependencies = [
60
60
  "elasticsearch==8.14.0",
61
61
  "methodtools>=0.4.7",
62
62
  "loguru>=0.7.3",
63
+ "cachetools>=5.5.2",
63
64
  "matplotlib>=3.10.3",
64
65
  "pandas>=2.2.3",
65
66
  "plotly>=6.0.1",
66
67
  "kaleido==0.2.1",
68
+ "aiohttp>=3.9.0",
67
69
  ]
68
- version = "0.4.4"
70
+ version = "0.5.2"
69
71
 
70
72
  [project.license]
71
73
  file = "LICENSE"
@@ -109,15 +111,77 @@ include_packages = [
109
111
  "torch*",
110
112
  ]
111
113
 
114
+ [tool.pytest.ini_options]
115
+ markers = [
116
+ "requires_llm: marks tests that require a real LLM (not fallback)",
117
+ "integration: marks integration tests",
118
+ "slow: marks slow tests",
119
+ ]
120
+
121
+ [tool.ruff]
122
+ exclude = [
123
+ ".bzr",
124
+ ".direnv",
125
+ ".eggs",
126
+ ".git",
127
+ ".git-rewrite",
128
+ ".hg",
129
+ ".ipynb_checkpoints",
130
+ ".mypy_cache",
131
+ ".nox",
132
+ ".pants.d",
133
+ ".pyenv",
134
+ ".pytest_cache",
135
+ ".pytype",
136
+ ".ruff_cache",
137
+ ".svn",
138
+ ".tox",
139
+ ".venv",
140
+ ".vscode",
141
+ "__pypackages__",
142
+ "_build",
143
+ "buck-out",
144
+ "build",
145
+ "dist",
146
+ "node_modules",
147
+ "site-packages",
148
+ "venv",
149
+ ]
150
+ line-length = 80
151
+ indent-width = 4
152
+
153
+ [tool.ruff.lint]
154
+ select = [
155
+ "E4",
156
+ "E7",
157
+ "E9",
158
+ "F",
159
+ ]
160
+ ignore = [
161
+ "E722",
162
+ ]
163
+ fixable = [
164
+ "ALL",
165
+ ]
166
+ unfixable = []
167
+ dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
168
+
169
+ [tool.ruff.format]
170
+ quote-style = "double"
171
+ indent-style = "space"
172
+ skip-magic-trailing-comma = false
173
+ line-ending = "auto"
174
+
112
175
  [dependency-groups]
113
176
  dev = [
114
- "isort>=6.0.1",
115
- "black>=25.1.0",
116
177
  "pre-commit>=4.2.0",
117
- "flake8>=7.1.2",
118
178
  "jupyter>=1.1.1",
119
179
  "cookiecutter>=2.6.0",
120
180
  "pandas>=2.2.3",
121
181
  "optuna>=4.3.0",
122
182
  "pytest-mock>=3.14.0",
183
+ "pytest>=8.3.5",
184
+ "pytest-cov>=6.1.1",
185
+ "pytest-timeout>=2.3.1",
186
+ "ruff>=0.11.12",
123
187
  ]
@@ -5,12 +5,17 @@ Local Deep Research - A tool for conducting deep research using AI.
5
5
  __author__ = "Your Name"
6
6
  __description__ = "A tool for conducting deep research using AI"
7
7
 
8
+ from loguru import logger
9
+
8
10
  from .__version__ import __version__
9
11
  from .config.llm_config import get_llm
10
12
  from .config.search_config import get_search
11
13
  from .report_generator import get_report_generator
12
14
  from .web.app import main
13
15
 
16
+ # Disable logging by default to not interfere with user setup.
17
+ logger.disable("local_deep_research")
18
+
14
19
 
15
20
  def get_advanced_search_system(strategy_name: str = "iterdrag"):
16
21
  """
@@ -32,4 +37,6 @@ __all__ = [
32
37
  "get_search",
33
38
  "get_report_generator",
34
39
  "get_advanced_search_system",
40
+ "main",
41
+ "__version__",
35
42
  ]
@@ -0,0 +1 @@
1
+ __version__ = "0.5.2"
@@ -0,0 +1,5 @@
1
+ """Answer decoding module for BrowseComp."""
2
+
3
+ from .browsecomp_answer_decoder import BrowseCompAnswerDecoder
4
+
5
+ __all__ = ["BrowseCompAnswerDecoder"]
@@ -0,0 +1,421 @@
1
+ """
2
+ BrowseComp Answer Decoding Pipeline
3
+
4
+ This module handles encoded answers found in BrowseComp datasets.
5
+ Some BrowseComp answers appear to be encoded (e.g., "Y00Qh+ep") and need
6
+ decoding to extract the actual answer.
7
+
8
+ Based on BROWSECOMP_IMPROVEMENT_STRATEGY.md recommendations.
9
+ """
10
+
11
+ import base64
12
+ import logging
13
+ import re
14
+ import urllib.parse
15
+ from typing import Optional, Tuple
16
+
17
+ logger = logging.getLogger(__name__)
18
+
19
+
20
+ class BrowseCompAnswerDecoder:
21
+ """
22
+ Handle encoded BrowseComp answers with multiple decoding schemes.
23
+
24
+ Features:
25
+ 1. Automatic encoding detection
26
+ 2. Multiple decoding scheme support
27
+ 3. Answer validation
28
+ 4. Fallback to original if decoding fails
29
+ """
30
+
31
+ def __init__(self):
32
+ self.encoding_schemes = [
33
+ "base64",
34
+ "hex",
35
+ "url_encoding",
36
+ "rot13",
37
+ "caesar_cipher",
38
+ ]
39
+
40
+ # Patterns that suggest encoded content
41
+ self.encoded_patterns = [
42
+ r"^[A-Za-z0-9+/]+=*$", # Base64 pattern
43
+ r"^[0-9A-Fa-f]+$", # Hex pattern
44
+ r"%[0-9A-Fa-f]{2}", # URL encoded
45
+ r"^[A-Za-z0-9]{8,}$", # Random string pattern
46
+ ]
47
+
48
+ def decode_answer(self, raw_answer: str) -> Tuple[str, Optional[str]]:
49
+ """
50
+ Attempt to decode a potentially encoded answer.
51
+
52
+ Args:
53
+ raw_answer: The raw answer string that may be encoded
54
+
55
+ Returns:
56
+ Tuple of (decoded_answer, encoding_scheme_used)
57
+ If no decoding works, returns (original_answer, None)
58
+ """
59
+ if not raw_answer or len(raw_answer.strip()) == 0:
60
+ return raw_answer, None
61
+
62
+ # Clean the input
63
+ clean_answer = raw_answer.strip()
64
+
65
+ # Check if answer looks like plaintext first
66
+ if self.is_likely_direct_answer(clean_answer):
67
+ logger.debug(f"Answer appears to be plaintext: {clean_answer}")
68
+ return clean_answer, None
69
+
70
+ logger.info(
71
+ f"Attempting to decode potentially encoded answer: {clean_answer}"
72
+ )
73
+
74
+ # Try each encoding scheme
75
+ for scheme in self.encoding_schemes:
76
+ try:
77
+ decoded = self.apply_decoding_scheme(clean_answer, scheme)
78
+ if decoded and self.validate_decoded_answer(decoded):
79
+ logger.info(
80
+ f"Successfully decoded using {scheme}: {clean_answer} -> {decoded}"
81
+ )
82
+ return decoded, scheme
83
+
84
+ except Exception as e:
85
+ logger.debug(f"Failed to decode with {scheme}: {e}")
86
+ continue
87
+
88
+ # No successful decoding
89
+ logger.warning(
90
+ f"Could not decode answer, returning original: {clean_answer}"
91
+ )
92
+ return clean_answer, None
93
+
94
+ def is_likely_direct_answer(self, answer: str) -> bool:
95
+ """
96
+ Check if answer looks like plaintext rather than encoded.
97
+
98
+ Args:
99
+ answer: The answer string to check
100
+
101
+ Returns:
102
+ True if answer appears to be plaintext
103
+ """
104
+ # Very short answers are likely plaintext
105
+ if len(answer) < 4:
106
+ return True
107
+
108
+ # Check for common English words
109
+ english_indicators = [
110
+ "the",
111
+ "and",
112
+ "or",
113
+ "of",
114
+ "in",
115
+ "to",
116
+ "a",
117
+ "an",
118
+ "company",
119
+ "group",
120
+ "inc",
121
+ "ltd",
122
+ "corp",
123
+ "corporation",
124
+ "person",
125
+ "people",
126
+ "event",
127
+ "year",
128
+ "years",
129
+ "million",
130
+ "billion",
131
+ "thousand",
132
+ ]
133
+
134
+ answer_lower = answer.lower()
135
+ if any(word in answer_lower for word in english_indicators):
136
+ return True
137
+
138
+ # Check for sentence-like structure
139
+ if " " in answer and len(answer.split()) > 1:
140
+ # Has spaces and multiple words - likely plaintext
141
+ return True
142
+
143
+ # Check if it matches common answer patterns
144
+ common_patterns = [
145
+ r"^\d{4}$", # Year
146
+ r"^\$?\d+\.?\d*[KMB]?$", # Number/money
147
+ r"^[A-Z][a-z]+ [A-Z][a-z]+$", # Name format
148
+ r"^\d+%$", # Percentage
149
+ ]
150
+
151
+ for pattern in common_patterns:
152
+ if re.match(pattern, answer):
153
+ return True
154
+
155
+ # Check character distribution - encoded text often has unusual distribution
156
+ char_diversity = (
157
+ len(set(answer)) / len(answer) if len(answer) > 0 else 0
158
+ )
159
+ if char_diversity < 0.3: # Low diversity suggests repetitive/encoded
160
+ return False
161
+
162
+ # If none of the encoded patterns match, probably plaintext
163
+ is_encoded = any(
164
+ re.search(pattern, answer) for pattern in self.encoded_patterns
165
+ )
166
+ return not is_encoded
167
+
168
+ def apply_decoding_scheme(self, text: str, scheme: str) -> Optional[str]:
169
+ """
170
+ Apply a specific decoding scheme to text.
171
+
172
+ Args:
173
+ text: Text to decode
174
+ scheme: Decoding scheme to use
175
+
176
+ Returns:
177
+ Decoded text or None if decoding fails
178
+ """
179
+ try:
180
+ if scheme == "base64":
181
+ return self._decode_base64(text)
182
+ elif scheme == "hex":
183
+ return self._decode_hex(text)
184
+ elif scheme == "url_encoding":
185
+ return self._decode_url(text)
186
+ elif scheme == "rot13":
187
+ return self._decode_rot13(text)
188
+ elif scheme == "caesar_cipher":
189
+ return self._decode_caesar(text)
190
+ else:
191
+ logger.warning(f"Unknown decoding scheme: {scheme}")
192
+ return None
193
+
194
+ except Exception as e:
195
+ logger.debug(f"Failed to apply {scheme} decoding: {e}")
196
+ return None
197
+
198
+ def _decode_base64(self, text: str) -> Optional[str]:
199
+ """Decode base64 encoded text."""
200
+ try:
201
+ # Add padding if needed
202
+ missing_padding = len(text) % 4
203
+ if missing_padding:
204
+ text += "=" * (4 - missing_padding)
205
+
206
+ decoded_bytes = base64.b64decode(text)
207
+ return decoded_bytes.decode("utf-8")
208
+
209
+ except Exception:
210
+ return None
211
+
212
+ def _decode_hex(self, text: str) -> Optional[str]:
213
+ """Decode hexadecimal encoded text."""
214
+ try:
215
+ # Remove any whitespace or non-hex characters
216
+ clean_hex = re.sub(r"[^0-9A-Fa-f]", "", text)
217
+
218
+ # Must have even length
219
+ if len(clean_hex) % 2 != 0:
220
+ return None
221
+
222
+ decoded_bytes = bytes.fromhex(clean_hex)
223
+ return decoded_bytes.decode("utf-8")
224
+
225
+ except Exception:
226
+ return None
227
+
228
+ def _decode_url(self, text: str) -> Optional[str]:
229
+ """Decode URL encoded text."""
230
+ try:
231
+ return urllib.parse.unquote(text)
232
+ except Exception:
233
+ return None
234
+
235
+ def _decode_rot13(self, text: str) -> Optional[str]:
236
+ """Decode ROT13 encoded text."""
237
+ try:
238
+ import codecs
239
+
240
+ return codecs.decode(text, "rot13")
241
+ except Exception:
242
+ return None
243
+
244
+ def _decode_caesar(self, text: str) -> Optional[str]:
245
+ """
246
+ Try different Caesar cipher shifts.
247
+ Returns the most English-like result.
248
+ """
249
+ best_result = None
250
+ best_score = 0
251
+
252
+ # Try shifts 1-25
253
+ for shift in range(1, 26):
254
+ try:
255
+ decoded = self._caesar_shift(text, shift)
256
+ score = self._english_score(decoded)
257
+
258
+ if score > best_score:
259
+ best_score = score
260
+ best_result = decoded
261
+
262
+ except Exception:
263
+ continue
264
+
265
+ # Only return if it looks reasonably English-like
266
+ return best_result if best_score > 0.3 else None
267
+
268
+ def _caesar_shift(self, text: str, shift: int) -> str:
269
+ """Apply Caesar cipher shift."""
270
+ result = []
271
+
272
+ for char in text:
273
+ if char.isalpha():
274
+ # Determine if uppercase or lowercase
275
+ start = ord("A") if char.isupper() else ord("a")
276
+ # Apply shift with wraparound
277
+ shifted = (ord(char) - start + shift) % 26 + start
278
+ result.append(chr(shifted))
279
+ else:
280
+ result.append(char)
281
+
282
+ return "".join(result)
283
+
284
+ def _english_score(self, text: str) -> float:
285
+ """
286
+ Score how English-like a text appears.
287
+ Simple heuristic based on common letters and words.
288
+ """
289
+ if not text:
290
+ return 0.0
291
+
292
+ text_lower = text.lower()
293
+
294
+ # Common English letter frequencies (approximate)
295
+ common_letters = "etaoinshrdlcumwfgypbvkjxqz"
296
+ letter_score = 0
297
+ letter_count = 0
298
+
299
+ for char in text_lower:
300
+ if char.isalpha():
301
+ letter_count += 1
302
+ # More common letters get higher scores
303
+ if char in common_letters[:10]: # Top 10 most common
304
+ letter_score += 2
305
+ elif char in common_letters[:20]: # Top 20
306
+ letter_score += 1
307
+
308
+ if letter_count == 0:
309
+ return 0.0
310
+
311
+ base_score = letter_score / letter_count
312
+
313
+ # Bonus for common English words
314
+ common_words = [
315
+ "the",
316
+ "and",
317
+ "of",
318
+ "to",
319
+ "a",
320
+ "in",
321
+ "is",
322
+ "it",
323
+ "you",
324
+ "that",
325
+ ]
326
+ word_bonus = sum(1 for word in common_words if word in text_lower)
327
+
328
+ return min(1.0, base_score + word_bonus * 0.1)
329
+
330
+ def validate_decoded_answer(self, decoded: str) -> bool:
331
+ """
332
+ Validate that decoded text looks like a reasonable answer.
333
+
334
+ Args:
335
+ decoded: The decoded text to validate
336
+
337
+ Returns:
338
+ True if decoded text appears valid
339
+ """
340
+ if not decoded or len(decoded.strip()) == 0:
341
+ return False
342
+
343
+ # Remove leading/trailing whitespace
344
+ decoded = decoded.strip()
345
+
346
+ # Check length - should be reasonable
347
+ if len(decoded) < 1 or len(decoded) > 1000:
348
+ return False
349
+
350
+ # Check for readable characters
351
+ printable_count = sum(1 for c in decoded if c.isprintable())
352
+ if printable_count / len(decoded) < 0.8: # At least 80% printable
353
+ return False
354
+
355
+ # Check for control characters (bad sign)
356
+ if any(ord(c) < 32 and c not in "\t\n\r" for c in decoded):
357
+ return False
358
+
359
+ # Check character distribution
360
+ char_types = {
361
+ "alpha": sum(1 for c in decoded if c.isalpha()),
362
+ "digit": sum(1 for c in decoded if c.isdigit()),
363
+ "space": sum(1 for c in decoded if c.isspace()),
364
+ "punct": sum(
365
+ 1 for c in decoded if not c.isalnum() and not c.isspace()
366
+ ),
367
+ }
368
+
369
+ total_chars = len(decoded)
370
+
371
+ # Should have some letters
372
+ if char_types["alpha"] / total_chars < 0.3:
373
+ return False
374
+
375
+ # Shouldn't be mostly punctuation
376
+ if char_types["punct"] / total_chars > 0.5:
377
+ return False
378
+
379
+ return True
380
+
381
+ def analyze_answer_encoding(self, answer: str) -> dict:
382
+ """
383
+ Analyze an answer to determine likely encoding type.
384
+
385
+ Returns analysis results for debugging/logging.
386
+ """
387
+ analysis = {
388
+ "original": answer,
389
+ "length": len(answer),
390
+ "likely_plaintext": self.is_likely_direct_answer(answer),
391
+ "pattern_matches": [],
392
+ "attempted_decodings": {},
393
+ }
394
+
395
+ # Check which patterns match
396
+ for i, pattern in enumerate(self.encoded_patterns):
397
+ if re.search(pattern, answer):
398
+ analysis["pattern_matches"].append(
399
+ {
400
+ "pattern": pattern,
401
+ "type": ["base64", "hex", "url", "random"][i],
402
+ }
403
+ )
404
+
405
+ # Try each decoding scheme
406
+ for scheme in self.encoding_schemes:
407
+ try:
408
+ decoded = self.apply_decoding_scheme(answer, scheme)
409
+ is_valid = (
410
+ self.validate_decoded_answer(decoded) if decoded else False
411
+ )
412
+
413
+ analysis["attempted_decodings"][scheme] = {
414
+ "decoded": decoded,
415
+ "valid": is_valid,
416
+ "length": len(decoded) if decoded else 0,
417
+ }
418
+ except Exception as e:
419
+ analysis["attempted_decodings"][scheme] = {"error": str(e)}
420
+
421
+ return analysis