local-deep-research 0.4.1__tar.gz → 0.4.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 (194) hide show
  1. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/PKG-INFO +1 -1
  2. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/pyproject.toml +1 -1
  3. local_deep_research-0.4.2/src/local_deep_research/__version__.py +1 -0
  4. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/config/llm_config.py +1 -1
  5. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/defaults/default_settings.json +1 -1
  6. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/services/settings_manager.py +68 -17
  7. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web_search_engines/engines/search_engine_searxng.py +1 -1
  8. local_deep_research-0.4.2/tests/test_settings_manager.py +208 -0
  9. local_deep_research-0.4.1/src/local_deep_research/__version__.py +0 -1
  10. local_deep_research-0.4.1/tests/test_settings_manager.py +0 -98
  11. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/LICENSE +0 -0
  12. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/README.md +0 -0
  13. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/__init__.py +0 -0
  14. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/advanced_search_system/__init__.py +0 -0
  15. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/advanced_search_system/filters/__init__.py +0 -0
  16. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/advanced_search_system/filters/base_filter.py +0 -0
  17. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/advanced_search_system/filters/cross_engine_filter.py +0 -0
  18. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/advanced_search_system/filters/journal_reputation_filter.py +0 -0
  19. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/advanced_search_system/findings/base_findings.py +0 -0
  20. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/advanced_search_system/findings/repository.py +0 -0
  21. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/advanced_search_system/knowledge/__init__.py +0 -0
  22. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/advanced_search_system/knowledge/base_knowledge.py +0 -0
  23. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/advanced_search_system/knowledge/standard_knowledge.py +0 -0
  24. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/advanced_search_system/questions/__init__.py +0 -0
  25. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/advanced_search_system/questions/base_question.py +0 -0
  26. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/advanced_search_system/questions/decomposition_question.py +0 -0
  27. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/advanced_search_system/questions/standard_question.py +0 -0
  28. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/advanced_search_system/repositories/__init__.py +0 -0
  29. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/advanced_search_system/strategies/__init__.py +0 -0
  30. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/advanced_search_system/strategies/base_strategy.py +0 -0
  31. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/advanced_search_system/strategies/iterdrag_strategy.py +0 -0
  32. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/advanced_search_system/strategies/parallel_search_strategy.py +0 -0
  33. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/advanced_search_system/strategies/rapid_search_strategy.py +0 -0
  34. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/advanced_search_system/strategies/source_based_strategy.py +0 -0
  35. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/advanced_search_system/strategies/standard_strategy.py +0 -0
  36. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/advanced_search_system/tools/__init__.py +0 -0
  37. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/advanced_search_system/tools/base_tool.py +0 -0
  38. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/advanced_search_system/tools/knowledge_tools/__init__.py +0 -0
  39. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/advanced_search_system/tools/question_tools/__init__.py +0 -0
  40. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/advanced_search_system/tools/search_tools/__init__.py +0 -0
  41. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/api/__init__.py +0 -0
  42. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/api/benchmark_functions.py +0 -0
  43. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/api/research_functions.py +0 -0
  44. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/benchmarks/README.md +0 -0
  45. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/benchmarks/__init__.py +0 -0
  46. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/benchmarks/benchmark_functions.py +0 -0
  47. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/benchmarks/cli/__init__.py +0 -0
  48. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/benchmarks/cli/benchmark_commands.py +0 -0
  49. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/benchmarks/cli.py +0 -0
  50. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/benchmarks/comparison/__init__.py +0 -0
  51. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/benchmarks/comparison/evaluator.py +0 -0
  52. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/benchmarks/datasets/__init__.py +0 -0
  53. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/benchmarks/datasets/base.py +0 -0
  54. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/benchmarks/datasets/browsecomp.py +0 -0
  55. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/benchmarks/datasets/custom_dataset_template.py +0 -0
  56. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/benchmarks/datasets/simpleqa.py +0 -0
  57. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/benchmarks/datasets/utils.py +0 -0
  58. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/benchmarks/datasets.py +0 -0
  59. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/benchmarks/efficiency/__init__.py +0 -0
  60. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/benchmarks/efficiency/resource_monitor.py +0 -0
  61. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/benchmarks/efficiency/speed_profiler.py +0 -0
  62. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/benchmarks/evaluators/__init__.py +0 -0
  63. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/benchmarks/evaluators/base.py +0 -0
  64. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/benchmarks/evaluators/browsecomp.py +0 -0
  65. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/benchmarks/evaluators/composite.py +0 -0
  66. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/benchmarks/evaluators/simpleqa.py +0 -0
  67. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/benchmarks/graders.py +0 -0
  68. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/benchmarks/metrics/README.md +0 -0
  69. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/benchmarks/metrics/__init__.py +0 -0
  70. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/benchmarks/metrics/calculation.py +0 -0
  71. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/benchmarks/metrics/reporting.py +0 -0
  72. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/benchmarks/metrics/visualization.py +0 -0
  73. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/benchmarks/metrics.py +0 -0
  74. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/benchmarks/optimization/__init__.py +0 -0
  75. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/benchmarks/optimization/api.py +0 -0
  76. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/benchmarks/optimization/metrics.py +0 -0
  77. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/benchmarks/optimization/optuna_optimizer.py +0 -0
  78. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/benchmarks/runners.py +0 -0
  79. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/benchmarks/templates.py +0 -0
  80. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/citation_handler.py +0 -0
  81. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/config/__init__.py +0 -0
  82. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/config/search_config.py +0 -0
  83. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/defaults/.env.template +0 -0
  84. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/defaults/__init__.py +0 -0
  85. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/migrate_db.py +0 -0
  86. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/report_generator.py +0 -0
  87. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/search_system.py +0 -0
  88. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/setup_data_dir.py +0 -0
  89. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/test_migration.py +0 -0
  90. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/utilities/__init__.py +0 -0
  91. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/utilities/db_utils.py +0 -0
  92. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/utilities/enums.py +0 -0
  93. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/utilities/es_utils.py +0 -0
  94. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/utilities/llm_utils.py +0 -0
  95. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/utilities/log_utils.py +0 -0
  96. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/utilities/search_utilities.py +0 -0
  97. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/utilities/setup_utils.py +0 -0
  98. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/utilities/url_utils.py +0 -0
  99. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/__init__.py +0 -0
  100. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/app.py +0 -0
  101. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/app_factory.py +0 -0
  102. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/database/README.md +0 -0
  103. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/database/migrate_to_ldr_db.py +0 -0
  104. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/database/migrations.py +0 -0
  105. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/database/models.py +0 -0
  106. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/database/schema_upgrade.py +0 -0
  107. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/models/database.py +0 -0
  108. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/models/settings.py +0 -0
  109. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/routes/api_routes.py +0 -0
  110. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/routes/benchmark_routes.py +0 -0
  111. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/routes/history_routes.py +0 -0
  112. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/routes/research_routes.py +0 -0
  113. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/routes/settings_routes.py +0 -0
  114. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/services/research_service.py +0 -0
  115. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/services/resource_service.py +0 -0
  116. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/services/settings_service.py +0 -0
  117. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/services/socket_service.py +0 -0
  118. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/static/css/custom_dropdown.css +0 -0
  119. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/static/css/settings.css +0 -0
  120. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/static/css/styles.css +0 -0
  121. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/static/js/components/custom_dropdown.js +0 -0
  122. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/static/js/components/detail.js +0 -0
  123. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/static/js/components/fallback/formatting.js +0 -0
  124. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/static/js/components/fallback/ui.js +0 -0
  125. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/static/js/components/history.js +0 -0
  126. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/static/js/components/logpanel.js +0 -0
  127. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/static/js/components/progress.js +0 -0
  128. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/static/js/components/research.js +0 -0
  129. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/static/js/components/results.js +0 -0
  130. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/static/js/components/settings.js +0 -0
  131. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/static/js/components/settings_sync.js +0 -0
  132. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/static/js/main.js +0 -0
  133. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/static/js/research_form.js +0 -0
  134. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/static/js/services/api.js +0 -0
  135. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/static/js/services/audio.js +0 -0
  136. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/static/js/services/formatting.js +0 -0
  137. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/static/js/services/pdf.js +0 -0
  138. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/static/js/services/socket.js +0 -0
  139. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/static/js/services/ui.js +0 -0
  140. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/static/sounds/README.md +0 -0
  141. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/static/sounds/error.mp3 +0 -0
  142. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/static/sounds/success.mp3 +0 -0
  143. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/templates/base.html +0 -0
  144. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/templates/components/custom_dropdown.html +0 -0
  145. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/templates/components/log_panel.html +0 -0
  146. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/templates/components/mobile_nav.html +0 -0
  147. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/templates/components/settings_form.html +0 -0
  148. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/templates/components/sidebar.html +0 -0
  149. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/templates/pages/details.html +0 -0
  150. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/templates/pages/history.html +0 -0
  151. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/templates/pages/progress.html +0 -0
  152. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/templates/pages/research.html +0 -0
  153. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/templates/pages/results.html +0 -0
  154. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/templates/settings_dashboard.html +0 -0
  155. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/utils/__init__.py +0 -0
  156. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/utils/formatters.py +0 -0
  157. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web/utils/templates.py +0 -0
  158. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web_search_engines/__init__.py +0 -0
  159. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web_search_engines/default_search_engines.py +0 -0
  160. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web_search_engines/engines/__init__.py +0 -0
  161. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web_search_engines/engines/full_search.py +0 -0
  162. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web_search_engines/engines/meta_search_engine.py +0 -0
  163. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web_search_engines/engines/search_engine_arxiv.py +0 -0
  164. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web_search_engines/engines/search_engine_brave.py +0 -0
  165. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web_search_engines/engines/search_engine_ddg.py +0 -0
  166. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web_search_engines/engines/search_engine_elasticsearch.py +0 -0
  167. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web_search_engines/engines/search_engine_github.py +0 -0
  168. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web_search_engines/engines/search_engine_google_pse.py +0 -0
  169. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web_search_engines/engines/search_engine_guardian.py +0 -0
  170. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web_search_engines/engines/search_engine_local.py +0 -0
  171. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web_search_engines/engines/search_engine_local_all.py +0 -0
  172. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web_search_engines/engines/search_engine_pubmed.py +0 -0
  173. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web_search_engines/engines/search_engine_semantic_scholar.py +0 -0
  174. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web_search_engines/engines/search_engine_serpapi.py +0 -0
  175. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web_search_engines/engines/search_engine_wayback.py +0 -0
  176. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web_search_engines/engines/search_engine_wikipedia.py +0 -0
  177. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web_search_engines/search_engine_base.py +0 -0
  178. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web_search_engines/search_engine_factory.py +0 -0
  179. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/src/local_deep_research/web_search_engines/search_engines_config.py +0 -0
  180. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/tests/TESTING_PROPOSAL.md +0 -0
  181. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/tests/__init__.py +0 -0
  182. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/tests/download_stuff_for_local_test.py +0 -0
  183. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/tests/feature_tests/IMPLEMENTATION_GUIDE_241.md +0 -0
  184. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/tests/feature_tests/README.md +0 -0
  185. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/tests/feature_tests/__init__.py +0 -0
  186. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/tests/feature_tests/test_custom_context.py +0 -0
  187. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/tests/fix_tests/README.md +0 -0
  188. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/tests/fix_tests/test_duplicate_links_fix.py +0 -0
  189. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/tests/searxng/test_searxng_instance.py +0 -0
  190. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/tests/searxng/test_searxng_integration.py +0 -0
  191. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/tests/test_google_pse.py +0 -0
  192. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/tests/test_url_utils.py +0 -0
  193. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/tests/test_url_utils_debug.py +0 -0
  194. {local_deep_research-0.4.1 → local_deep_research-0.4.2}/tests/test_url_utils_simple.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: local-deep-research
3
- Version: 0.4.1
3
+ Version: 0.4.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
@@ -65,7 +65,7 @@ dependencies = [
65
65
  "plotly>=6.0.1",
66
66
  "kaleido==0.1.0",
67
67
  ]
68
- version = "0.4.1"
68
+ version = "0.4.2"
69
69
 
70
70
  [project.license]
71
71
  file = "LICENSE"
@@ -0,0 +1 @@
1
+ __version__ = "0.4.2"
@@ -79,7 +79,7 @@ def get_llm(model_name=None, temperature=None, provider=None, openai_endpoint_ur
79
79
  if get_db_setting("llm.supports_max_tokens", True):
80
80
  # Use 80% of context window to leave room for prompts
81
81
  max_tokens = min(
82
- get_db_setting("llm.max_tokens", 30000), int(context_window_size * 0.8)
82
+ int(get_db_setting("llm.max_tokens", 30000)), int(context_window_size * 0.8)
83
83
  )
84
84
  common_params["max_tokens"] = max_tokens
85
85
 
@@ -342,7 +342,7 @@
342
342
  "options": null,
343
343
  "step": 0.05,
344
344
  "type": "LLM",
345
- "ui_element": "slider",
345
+ "ui_element": "range",
346
346
  "value": 0.7,
347
347
  "visible": true
348
348
  },
@@ -1,7 +1,7 @@
1
1
  import importlib.resources as pkg_resources
2
2
  import json
3
3
  import os
4
- from typing import Any, Dict, Optional, Union
4
+ from typing import Any, Dict, Optional, Type, Union
5
5
 
6
6
  from loguru import logger
7
7
  from sqlalchemy import func
@@ -45,6 +45,15 @@ class SettingsManager:
45
45
  Provides methods to get and set settings, with the ability to override settings in memory.
46
46
  """
47
47
 
48
+ _UI_ELEMENT_TO_SETTING_TYPE = {
49
+ "text": str,
50
+ "password": str,
51
+ "select": str,
52
+ "number": float,
53
+ "range": float,
54
+ "checkbox": bool,
55
+ }
56
+
48
57
  def __init__(self, db_session: Session):
49
58
  """
50
59
  Initialize the settings manager
@@ -59,6 +68,57 @@ class SettingsManager:
59
68
  default_settings = pkg_resources.read_text(defaults, "default_settings.json")
60
69
  self.default_settings = json.loads(default_settings)
61
70
 
71
+ def __get_typed_setting_value(
72
+ self, setting: Type[Setting], default: Any = None, check_env: bool = True
73
+ ) -> str | float | bool | None:
74
+ """
75
+ Extracts the value for a particular setting, ensuring that it has the
76
+ correct type.
77
+
78
+ Args:
79
+ setting: The setting to get the value for.
80
+ default: Default value to return if the value of the setting is
81
+ invalid.
82
+ check_env: If true, it will check the environment variable for
83
+ this setting before reading from the DB.
84
+
85
+ Returns:
86
+ The value of the setting.
87
+
88
+ """
89
+ setting_type = self._UI_ELEMENT_TO_SETTING_TYPE.get(setting.ui_element, None)
90
+ if setting_type is None:
91
+ logger.warning(
92
+ "Got unknown type {} for setting {}, returning default value.",
93
+ setting.ui_element,
94
+ setting.key,
95
+ )
96
+ return default
97
+
98
+ # Check environment variable first, then database.
99
+ if check_env:
100
+ env_value = check_env_setting(setting.key)
101
+ if env_value is not None:
102
+ try:
103
+ return setting_type(env_value)
104
+ except ValueError:
105
+ logger.warning(
106
+ "Setting {} has invalid value {}. Falling back to DB.",
107
+ setting.key,
108
+ env_value,
109
+ )
110
+
111
+ # If environment variable does not exist, read from the database.
112
+ try:
113
+ return setting_type(setting.value)
114
+ except ValueError:
115
+ logger.warning(
116
+ "Setting {} has invalid value {}. Returning default.",
117
+ setting.key,
118
+ setting.value,
119
+ )
120
+ return default
121
+
62
122
  def get_setting(self, key: str, default: Any = None, check_env: bool = True) -> Any:
63
123
  """
64
124
  Get a setting value
@@ -72,11 +132,6 @@ class SettingsManager:
72
132
  Returns:
73
133
  Setting value or default if not found
74
134
  """
75
- if check_env:
76
- env_value = check_env_setting(key)
77
- if env_value is not None:
78
- return env_value
79
-
80
135
  # If using database first approach and session available, check database
81
136
  if self.db_first and self.db_session:
82
137
  try:
@@ -87,22 +142,17 @@ class SettingsManager:
87
142
  )
88
143
  if len(settings) == 1:
89
144
  # This is a bottom-level key.
90
- value = settings[0].value
91
- return value
145
+ return self.__get_typed_setting_value(
146
+ settings[0], default, check_env
147
+ )
92
148
  elif len(settings) > 1:
93
149
  # This is a higher-level key.
94
150
  settings_map = {}
95
151
  for setting in settings:
96
152
  output_key = setting.key.removeprefix(f"{key}.")
97
- value = setting.value
98
-
99
- if check_env:
100
- # Handle possible replacements from environment variables.
101
- env_value = check_env_setting(setting.key)
102
- if env_value is not None:
103
- value = env_value
104
-
105
- settings_map[output_key] = value
153
+ settings_map[output_key] = self.__get_typed_setting_value(
154
+ setting, default, check_env
155
+ )
106
156
  return settings_map
107
157
  except SQLAlchemyError as e:
108
158
  logger.error(f"Error retrieving setting {key} from database: {e}")
@@ -149,6 +199,7 @@ class SettingsManager:
149
199
  value=value,
150
200
  type=setting_type,
151
201
  name=key.split(".")[-1].replace("_", " ").title(),
202
+ ui_element="text",
152
203
  description=f"Setting for {key}",
153
204
  )
154
205
  self.db_session.add(new_setting)
@@ -98,7 +98,7 @@ class SearXNGSearchEngine(BaseSearchEngine):
98
98
  self.language = language
99
99
  try:
100
100
  self.safe_search = SafeSearchSetting[safe_search]
101
- except ValueError:
101
+ except KeyError:
102
102
  logger.error(
103
103
  "'{}' is not a valid safe search setting. Disabling safe search",
104
104
  safe_search,
@@ -0,0 +1,208 @@
1
+ import os
2
+ from typing import Any
3
+
4
+ import pytest
5
+ from sqlalchemy.exc import SQLAlchemyError
6
+
7
+ from src.local_deep_research.web.services.settings_manager import (
8
+ Setting,
9
+ SettingsManager,
10
+ SettingType,
11
+ check_env_setting,
12
+ )
13
+
14
+
15
+ def test_check_env_setting_exists(monkeypatch):
16
+ monkeypatch.setenv("LDR_APP_VERSION", "1.0.0")
17
+ assert check_env_setting("app.version") == "1.0.0"
18
+
19
+
20
+ def test_check_env_setting_not_exists():
21
+ # Ensure the environment variable is not set
22
+ if "LDR_APP_VERSION" in os.environ:
23
+ del os.environ["LDR_APP_VERSION"]
24
+ assert check_env_setting("app.version") is None
25
+
26
+
27
+ @pytest.mark.parametrize(
28
+ "ui_element, setting_value, expected",
29
+ [
30
+ ("text", "hello", "hello"),
31
+ ("select", "option_a", "option_a"),
32
+ ("password", "secret", "secret"),
33
+ ("number", "3.14", 3.14),
34
+ ("range", "3.14", 3.14),
35
+ ("checkbox", "true", True),
36
+ ],
37
+ )
38
+ def test_get_setting_from_db(
39
+ mocker, ui_element: str, setting_value: str, expected: Any
40
+ ):
41
+ """
42
+ Tests that we can successfully read settings from the DB.
43
+
44
+ Args:
45
+ mocker: The fixture to use for mocking.
46
+ ui_element: The value of the `ui_element` parameter, which controls the return type.
47
+ setting_value: The value to use for the setting in the DB.
48
+ expected: The expected typed value of the setting.
49
+ """
50
+ # Arrange: Set up the mock database session and a sample setting
51
+ mock_db_session = mocker.MagicMock()
52
+ mock_setting = Setting(
53
+ key="test.setting", value=setting_value, ui_element=ui_element
54
+ )
55
+ mock_db_session.query.return_value.filter.return_value.all.return_value = [
56
+ mock_setting
57
+ ]
58
+
59
+ # Act: Call the get_setting method with the test key
60
+ settings_manager = SettingsManager(db_session=mock_db_session)
61
+ result = settings_manager.get_setting("test.setting")
62
+
63
+ # Assert: Verify that the result matches the expected value
64
+ assert result == expected, f"Expected {expected}, but got {result}"
65
+
66
+
67
+ @pytest.mark.parametrize(
68
+ "ui_element, env_value, expected",
69
+ [
70
+ ("text", "hello", "hello"),
71
+ ("select", "option_a", "option_a"),
72
+ ("password", "secret", "secret"),
73
+ ("number", "3.14", 3.14),
74
+ ("range", "3.14", 3.14),
75
+ ("checkbox", "true", True),
76
+ ],
77
+ )
78
+ def test_get_setting_from_env(
79
+ mocker, monkeypatch, ui_element: str, env_value: str, expected: Any
80
+ ):
81
+ """
82
+ Tests that we can successfully override DB settings with environment
83
+ variables.
84
+
85
+ Args:
86
+ mocker: The fixture to use for mocking.
87
+ ui_element: The value of the `ui_element` parameter, which controls the return type.
88
+ env_value: The value to use for the setting in the environment variable.
89
+ expected: The expected typed value of the setting.
90
+ """
91
+ # Arrange: Set up the mock database session and ensure an environment variable is set
92
+ mock_db_session = mocker.MagicMock()
93
+ monkeypatch.setenv("LDR_TEST_SETTING", env_value)
94
+ # Ensure DB query returns an old version to verify environment variable is prioritized
95
+ mock_setting = Setting(key="test.setting", value="db_value", ui_element=ui_element)
96
+ mock_db_session.query.return_value.filter.return_value.all.return_value = [
97
+ mock_setting
98
+ ]
99
+
100
+ # Act: Call the get_setting method with the test key
101
+ settings_manager = SettingsManager(db_session=mock_db_session)
102
+ result = settings_manager.get_setting("test.setting")
103
+
104
+ # Assert: Verify that the result matches the expected value
105
+ assert result == expected, f"Expected {expected}, but got {result}"
106
+
107
+
108
+ def test_get_setting_default(mocker):
109
+ mock_db_session = mocker.MagicMock()
110
+ # Ensure DB query returns nothing
111
+ mock_db_session.query.return_value.filter.return_value.all.return_value = []
112
+
113
+ settings_manager = SettingsManager(db_session=mock_db_session)
114
+ assert (
115
+ settings_manager.get_setting("non_existent_setting", default="default_value")
116
+ == "default_value"
117
+ )
118
+
119
+
120
+ def test_get_setting_invalid_type(mocker):
121
+ """
122
+ Tests that when a setting's value cannot be converted to the type
123
+ specified by the `ui_element`, it will always return the default value.
124
+
125
+ Args:
126
+ mocker: The fixture to use for mocking.
127
+
128
+ """
129
+ # Arrange: Set up a mock DB session and setting with an invalid type
130
+ mock_db_session = mocker.MagicMock()
131
+ mock_setting = Setting(
132
+ key="test.invalid_type", value="not_a_number", ui_element="number"
133
+ )
134
+ mock_db_session.query.return_value.filter.return_value.all.return_value = [
135
+ mock_setting
136
+ ]
137
+
138
+ # Act: Call get_setting with a default value and an invalid type
139
+ settings_manager = SettingsManager(db_session=mock_db_session)
140
+ result = settings_manager.get_setting("test.invalid_type", default=10)
141
+
142
+ # Assert: Check that the default value is returned and not the invalid string
143
+ assert result == 10
144
+
145
+
146
+ # The mocker fixture is automatically available
147
+ def test_set_setting_update_existing(mocker):
148
+ mock_db_session = mocker.MagicMock()
149
+ mock_setting = Setting(key="app.version", value="1.0.0")
150
+ mock_db_session.query.return_value.filter.return_value.first.return_value = (
151
+ mock_setting
152
+ )
153
+ mocker.patch(
154
+ "src.local_deep_research.web.services.settings_manager.func.now"
155
+ ) # Patching the func.now call
156
+
157
+ settings_manager = SettingsManager(db_session=mock_db_session)
158
+ result = settings_manager.set_setting("app.version", "2.0.0")
159
+
160
+ assert result is True
161
+ assert mock_setting.value == "2.0.0"
162
+ mock_db_session.commit.assert_called_once()
163
+ mock_db_session.rollback.assert_not_called()
164
+
165
+
166
+ def test_set_setting_create_new(mocker):
167
+ mock_db_session = mocker.MagicMock()
168
+ mock_db_session.query.return_value.filter.return_value.first.return_value = None
169
+ mocker.patch(
170
+ "src.local_deep_research.web.services.settings_manager.func.now"
171
+ ) # Patching the func.now call
172
+
173
+ settings_manager = SettingsManager(db_session=mock_db_session)
174
+ result = settings_manager.set_setting("new.setting", "new_value")
175
+
176
+ assert result is True
177
+ mock_db_session.add.assert_called_once()
178
+ new_setting = mock_db_session.add.call_args[0][0]
179
+ assert isinstance(new_setting, Setting)
180
+ assert new_setting.key == "new.setting"
181
+ assert new_setting.value == "new_value"
182
+ assert new_setting.type == SettingType.APP # Assuming 'app' type for this key
183
+ mock_db_session.commit.assert_called_once()
184
+ mock_db_session.rollback.assert_not_called()
185
+
186
+
187
+ def test_set_setting_db_error(mocker):
188
+ mock_db_session = mocker.MagicMock()
189
+ # Set the side_effect to an instance of SQLAlchemyError
190
+ mock_db_session.query.return_value.filter.return_value.first.side_effect = (
191
+ SQLAlchemyError("Simulated DB Error")
192
+ )
193
+
194
+ # Mock the logger to check if error is logged
195
+ mock_logger = mocker.patch(
196
+ "src.local_deep_research.web.services.settings_manager.logger"
197
+ )
198
+
199
+ settings_manager = SettingsManager(db_session=mock_db_session)
200
+ result = settings_manager.set_setting("app.version", "2.0.0")
201
+
202
+ # Assert that the method returned False
203
+ assert result is False
204
+
205
+ mock_db_session.rollback.assert_called_once()
206
+ mock_db_session.commit.assert_not_called()
207
+ mock_logger.error.assert_called_once()
208
+ # mock_logger.error.assert_called_once_with("Error setting value for app.version: Simulated DB Error")
@@ -1 +0,0 @@
1
- __version__ = "0.4.1"
@@ -1,98 +0,0 @@
1
- import os
2
- import pytest
3
- import sys
4
- from pathlib import Path
5
- from sqlalchemy.exc import SQLAlchemyError
6
-
7
- # Add the src directory to the path before importing project modules
8
- sys.path.append(str(Path(__file__).parent.parent))
9
-
10
- from src.local_deep_research.web.services.settings_manager import check_env_setting, SettingsManager, Setting, SettingType
11
-
12
- def test_check_env_setting_exists(monkeypatch):
13
- monkeypatch.setenv("LDR_APP_VERSION", "1.0.0")
14
- assert check_env_setting("app.version") == "1.0.0"
15
-
16
- def test_check_env_setting_not_exists():
17
- # Ensure the environment variable is not set
18
- if "LDR_APP_VERSION" in os.environ:
19
- del os.environ["LDR_APP_VERSION"]
20
- assert check_env_setting("app.version") is None
21
-
22
- def test_get_setting_from_db(mocker):
23
- mock_db_session = mocker.MagicMock()
24
- mock_setting = Setting(key="app.version", value="1.0.0")
25
- # Use mocker.patch.object for patching instances
26
- mock_db_session.query.return_value.filter.return_value.all.return_value = [mock_setting]
27
-
28
- settings_manager = SettingsManager(db_session=mock_db_session)
29
- assert settings_manager.get_setting("app.version") == "1.0.0"
30
-
31
- def test_get_setting_from_env(mocker, monkeypatch):
32
- mock_db_session = mocker.MagicMock()
33
- monkeypatch.setenv("LDR_APP_VERSION", "2.0.0")
34
- # Ensure DB query returns nothing to verify environment variable is prioritized
35
- mock_db_session.query.return_value.filter.return_value.all.return_value = []
36
-
37
- settings_manager = SettingsManager(db_session=mock_db_session)
38
- assert settings_manager.get_setting("app.version") == "2.0.0"
39
-
40
- def test_get_setting_default(mocker):
41
- mock_db_session = mocker.MagicMock()
42
- # Ensure DB query returns nothing
43
- mock_db_session.query.return_value.filter.return_value.all.return_value = []
44
-
45
- settings_manager = SettingsManager(db_session=mock_db_session)
46
- assert settings_manager.get_setting("non_existent_setting", default="default_value") == "default_value"
47
-
48
- # The mocker fixture is automatically available
49
- def test_set_setting_update_existing(mocker):
50
- mock_db_session = mocker.MagicMock()
51
- mock_setting = Setting(key="app.version", value="1.0.0")
52
- mock_db_session.query.return_value.filter.return_value.first.return_value = mock_setting
53
- mocker.patch("src.local_deep_research.web.services.settings_manager.func.now") # Patching the func.now call
54
-
55
- settings_manager = SettingsManager(db_session=mock_db_session)
56
- result = settings_manager.set_setting("app.version", "2.0.0")
57
-
58
- assert result is True
59
- assert mock_setting.value == "2.0.0"
60
- mock_db_session.commit.assert_called_once()
61
- mock_db_session.rollback.assert_not_called()
62
-
63
- def test_set_setting_create_new(mocker):
64
- mock_db_session = mocker.MagicMock()
65
- mock_db_session.query.return_value.filter.return_value.first.return_value = None
66
- mocker.patch("src.local_deep_research.web.services.settings_manager.func.now") # Patching the func.now call
67
-
68
- settings_manager = SettingsManager(db_session=mock_db_session)
69
- result = settings_manager.set_setting("new.setting", "new_value")
70
-
71
- assert result is True
72
- mock_db_session.add.assert_called_once()
73
- new_setting = mock_db_session.add.call_args[0][0]
74
- assert isinstance(new_setting, Setting)
75
- assert new_setting.key == "new.setting"
76
- assert new_setting.value == "new_value"
77
- assert new_setting.type == SettingType.APP # Assuming 'app' type for this key
78
- mock_db_session.commit.assert_called_once()
79
- mock_db_session.rollback.assert_not_called()
80
-
81
- def test_set_setting_db_error(mocker):
82
- mock_db_session = mocker.MagicMock()
83
- # Set the side_effect to an instance of SQLAlchemyError
84
- mock_db_session.query.return_value.filter.return_value.first.side_effect = SQLAlchemyError("Simulated DB Error")
85
-
86
- # Mock the logger to check if error is logged
87
- mock_logger = mocker.patch("src.local_deep_research.web.services.settings_manager.logger")
88
-
89
- settings_manager = SettingsManager(db_session=mock_db_session)
90
- result = settings_manager.set_setting("app.version", "2.0.0")
91
-
92
- # Assert that the method returned False
93
- assert result is False
94
-
95
- mock_db_session.rollback.assert_called_once()
96
- mock_db_session.commit.assert_not_called()
97
- mock_logger.error.assert_called_once()
98
- # mock_logger.error.assert_called_once_with("Error setting value for app.version: Simulated DB Error")