local-deep-research 0.6.0__py3-none-any.whl → 0.6.4__py3-none-any.whl

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 (26) hide show
  1. local_deep_research/__init__.py +6 -0
  2. local_deep_research/__version__.py +1 -1
  3. local_deep_research/setup_data_dir.py +3 -2
  4. local_deep_research/utilities/db_utils.py +11 -9
  5. local_deep_research/utilities/log_utils.py +1 -1
  6. local_deep_research/utilities/threading_utils.py +17 -4
  7. local_deep_research/web/api.py +5 -3
  8. local_deep_research/web/app.py +0 -74
  9. local_deep_research/web/app_factory.py +1 -11
  10. local_deep_research/web/database/migrations.py +699 -28
  11. local_deep_research/web/database/uuid_migration.py +2 -247
  12. local_deep_research/web/models/database.py +0 -79
  13. local_deep_research/web/routes/settings_routes.py +70 -73
  14. local_deep_research/web/services/settings_manager.py +13 -28
  15. local_deep_research/web/services/settings_service.py +6 -40
  16. local_deep_research/web/services/socket_service.py +1 -1
  17. local_deep_research/web/templates/pages/benchmark_results.html +146 -8
  18. local_deep_research/web_search_engines/rate_limiting/tracker.py +1 -3
  19. {local_deep_research-0.6.0.dist-info → local_deep_research-0.6.4.dist-info}/METADATA +20 -5
  20. {local_deep_research-0.6.0.dist-info → local_deep_research-0.6.4.dist-info}/RECORD +23 -26
  21. local_deep_research/migrate_db.py +0 -149
  22. local_deep_research/web/database/migrate_to_ldr_db.py +0 -297
  23. local_deep_research/web/database/schema_upgrade.py +0 -519
  24. {local_deep_research-0.6.0.dist-info → local_deep_research-0.6.4.dist-info}/WHEEL +0 -0
  25. {local_deep_research-0.6.0.dist-info → local_deep_research-0.6.4.dist-info}/entry_points.txt +0 -0
  26. {local_deep_research-0.6.0.dist-info → local_deep_research-0.6.4.dist-info}/licenses/LICENSE +0 -0
@@ -66,11 +66,17 @@ class SettingsManager:
66
66
  self.db_session = db_session
67
67
  self.db_first = True # Always prioritize DB settings
68
68
 
69
- # Load default settings.
69
+ @property
70
+ def default_settings(self) -> Dict[str, Any]:
71
+ """
72
+ Returns:
73
+ The default settings, loaded from JSON.
74
+
75
+ """
70
76
  default_settings = pkg_resources.read_text(
71
77
  defaults, "default_settings.json"
72
78
  )
73
- self.default_settings = json.loads(default_settings)
79
+ return json.loads(default_settings)
74
80
 
75
81
  def __get_typed_setting_value(
76
82
  self,
@@ -462,27 +468,6 @@ class SettingsManager:
462
468
  self.db_session.add(version)
463
469
  self.db_session.commit()
464
470
 
465
- @classmethod
466
- def get_instance(
467
- cls, db_session: Optional[Session] = None
468
- ) -> "SettingsManager":
469
- """
470
- Get a singleton instance of the settings manager
471
-
472
- Args:
473
- db_session: Optional database session
474
-
475
- Returns:
476
- SettingsManager instance
477
- """
478
- if not hasattr(cls, "_instance"):
479
- cls._instance = cls(db_session)
480
- elif db_session and not cls._instance.db_session:
481
- # Update existing instance with a session
482
- cls._instance.db_session = db_session
483
-
484
- return cls._instance
485
-
486
471
  def import_settings(
487
472
  self,
488
473
  settings_data: Dict[str, Any],
@@ -517,6 +502,11 @@ class SettingsManager:
517
502
  setting = Setting(key=key, **setting_values)
518
503
  self.db_session.add(setting)
519
504
 
505
+ if commit or delete_extra:
506
+ self.db_session.commit()
507
+ # Emit WebSocket event for all imported settings
508
+ self._emit_settings_changed(list(settings_data.keys()))
509
+
520
510
  if delete_extra:
521
511
  all_settings = self.get_all_settings()
522
512
  for key in all_settings:
@@ -524,11 +514,6 @@ class SettingsManager:
524
514
  logger.debug(f"Deleting extraneous setting: {key}")
525
515
  self.delete_setting(key, commit=False)
526
516
 
527
- if commit:
528
- self.db_session.commit()
529
- # Emit WebSocket event for all imported settings
530
- self._emit_settings_changed(list(settings_data.keys()))
531
-
532
517
  def _create_setting(self, key, value, setting_type):
533
518
  """Create a setting with appropriate metadata"""
534
519
 
@@ -3,41 +3,10 @@ from typing import Any, Dict, Optional, Union
3
3
  from loguru import logger
4
4
 
5
5
  from ..database.models import Setting
6
- from .settings_manager import SettingsManager
6
+ from ...utilities.db_utils import get_settings_manager
7
7
 
8
8
 
9
- def get_settings_manager(db_session=None):
10
- """
11
- Get or create the settings manager instance.
12
-
13
- Args:
14
- db_session: Optional database session to use
15
-
16
- Returns:
17
- SettingsManager: The settings manager instance
18
- """
19
- return SettingsManager.get_instance(db_session)
20
-
21
-
22
- def get_setting(key: str, default: Any = None, db_session=None) -> Any:
23
- """
24
- Get a setting value by key
25
-
26
- Args:
27
- key: Setting key
28
- default: Default value if setting not found
29
- db_session: Optional database session to use
30
-
31
- Returns:
32
- Any: The setting value
33
- """
34
- manager = get_settings_manager(db_session)
35
- return manager.get_setting(key, default)
36
-
37
-
38
- def set_setting(
39
- key: str, value: Any, commit: bool = True, db_session=None
40
- ) -> bool:
9
+ def set_setting(key: str, value: Any, commit: bool = True) -> bool:
41
10
  """
42
11
  Set a setting value
43
12
 
@@ -45,26 +14,23 @@ def set_setting(
45
14
  key: Setting key
46
15
  value: Setting value
47
16
  commit: Whether to commit the change
48
- db_session: Optional database session
49
17
 
50
18
  Returns:
51
19
  bool: True if successful
52
20
  """
53
- manager = get_settings_manager(db_session)
21
+ manager = get_settings_manager()
54
22
  return manager.set_setting(key, value, commit)
55
23
 
56
24
 
57
- def get_all_settings(db_session=None) -> Dict[str, Any]:
25
+ def get_all_settings() -> Dict[str, Any]:
58
26
  """
59
27
  Get all settings, optionally filtered by type
60
28
 
61
- Args:
62
- db_session: Optional database session
63
-
64
29
  Returns:
65
30
  Dict[str, Any]: Dictionary of settings
31
+
66
32
  """
67
- manager = get_settings_manager(db_session)
33
+ manager = get_settings_manager()
68
34
  return manager.get_all_settings()
69
35
 
70
36
 
@@ -49,7 +49,7 @@ class SocketIOService:
49
49
  app,
50
50
  cors_allowed_origins="*",
51
51
  async_mode="threading",
52
- path="/research/socket.io",
52
+ path="/socket.io",
53
53
  logger=False,
54
54
  engineio_logger=False,
55
55
  ping_timeout=20,
@@ -6,6 +6,7 @@
6
6
 
7
7
  {% block extra_head %}
8
8
  <meta name="csrf-token" content="{{ csrf_token() }}">
9
+ <meta name="app-version" content="{{ version }}">
9
10
  <style>
10
11
  .benchmark-results-card {
11
12
  width: 100%;
@@ -769,14 +770,21 @@ function createRunCard(run) {
769
770
  <div class="summary-label">Avg Time/Question</div>
770
771
  </div>
771
772
  <div class="summary-item">
772
- ${status === 'in_progress' ?
773
- `<button class="btn btn-outline btn-sm delete-btn" onclick="event.stopPropagation(); cancelAndDeleteBenchmarkRun(${run.id})" style="background: #3a1e1e !important; border-color: #f44336 !important; color: #f44336 !important;">
774
- <i class="fas fa-stop"></i> Cancel & Delete
775
- </button>` :
776
- `<button class="btn btn-outline btn-sm delete-btn" onclick="event.stopPropagation(); deleteBenchmarkRun(${run.id})">
777
- <i class="fas fa-trash"></i> Delete
778
- </button>`
779
- }
773
+ <div style="display: flex; gap: 8px;">
774
+ ${status === 'completed' ?
775
+ `<button class="btn btn-outline btn-sm" onclick="event.stopPropagation(); downloadBenchmarkYAML(${run.id})" style="background: #1e3a1e !important; border-color: #4caf50 !important; color: #4caf50 !important;">
776
+ <i class="fas fa-download"></i> YAML
777
+ </button>` : ''
778
+ }
779
+ ${status === 'in_progress' ?
780
+ `<button class="btn btn-outline btn-sm delete-btn" onclick="event.stopPropagation(); cancelAndDeleteBenchmarkRun(${run.id})" style="background: #3a1e1e !important; border-color: #f44336 !important; color: #f44336 !important;">
781
+ <i class="fas fa-stop"></i> Cancel & Delete
782
+ </button>` :
783
+ `<button class="btn btn-outline btn-sm delete-btn" onclick="event.stopPropagation(); deleteBenchmarkRun(${run.id})">
784
+ <i class="fas fa-trash"></i> Delete
785
+ </button>`
786
+ }
787
+ </div>
780
788
  <div class="summary-label">Actions</div>
781
789
  </div>
782
790
  </div>
@@ -1061,6 +1069,136 @@ async function cancelAndDeleteBenchmarkRun(runId) {
1061
1069
  }
1062
1070
  }
1063
1071
 
1072
+ async function downloadBenchmarkYAML(runId) {
1073
+ try {
1074
+ // Find the run in our local data
1075
+ const run = benchmarkRuns.find(r => r.id === runId);
1076
+ if (!run) {
1077
+ showAlert('Benchmark run not found', 'error');
1078
+ return;
1079
+ }
1080
+
1081
+ // Get current date for filename
1082
+ const date = new Date().toISOString().split('T')[0];
1083
+
1084
+ // Get app version from meta tag
1085
+ const appVersion = document.querySelector('meta[name="app-version"]')?.content || 'Could not fetch version';
1086
+
1087
+ // Extract model name and clean it for filename
1088
+ const modelName = run.search_config?.model_name || 'unknown-model';
1089
+ const cleanModelName = modelName.replace(/[^a-zA-Z0-9.-]/g, '-').toLowerCase();
1090
+
1091
+ // Get all relevant settings from database
1092
+ let localContextWindow = 'Could not fetch';
1093
+ let maxTokens = 'Could not fetch';
1094
+ let contextWindowUnrestricted = 'Could not fetch';
1095
+ let contextWindowSize = 'Could not fetch';
1096
+ let supportsMaxTokens = 'Could not fetch';
1097
+
1098
+ try {
1099
+ const settingsResponse = await fetch('/settings/api');
1100
+ if (settingsResponse.ok) {
1101
+ const data = await settingsResponse.json();
1102
+ if (data.status === 'success' && data.settings) {
1103
+ const settings = data.settings;
1104
+ // LLM settings - extract the 'value' property from each setting object
1105
+ localContextWindow = settings['llm.local_context_window_size']?.value || 'Could not fetch';
1106
+ maxTokens = settings['llm.max_tokens']?.value || 'Could not fetch';
1107
+ contextWindowUnrestricted = settings['llm.context_window_unrestricted']?.value !== undefined ?
1108
+ (settings['llm.context_window_unrestricted'].value ? 'Yes' : 'No') : 'Could not fetch';
1109
+ contextWindowSize = settings['llm.context_window_size']?.value || 'Could not fetch';
1110
+ supportsMaxTokens = settings['llm.supports_max_tokens']?.value !== undefined ?
1111
+ (settings['llm.supports_max_tokens'].value ? 'Yes' : 'No') : 'Could not fetch';
1112
+ }
1113
+ }
1114
+ } catch (e) {
1115
+ console.error('Could not fetch current settings:', e);
1116
+ }
1117
+
1118
+ // Calculate average search results if available
1119
+ const avgSearchResults = formatAvgSearchResults(run).replace(' results', '');
1120
+ const searchResultsNum = avgSearchResults !== 'N/A' ? avgSearchResults : '# Please fill in';
1121
+
1122
+ // Generate YAML content
1123
+ const yamlContent = `# Benchmark Result
1124
+ # Generated from Local Deep Research v${appVersion}
1125
+ # Date: ${date}
1126
+
1127
+ # Model Information
1128
+ model: ${modelName}
1129
+ model_provider: ${run.search_config?.provider || 'unknown'}
1130
+ quantization: # Please fill in if applicable
1131
+
1132
+ # Search Engine (critical for benchmark reproducibility)
1133
+ search_engine: ${run.search_config?.search_tool || 'unknown'}
1134
+ search_provider_version: # if known, e.g., "latest", "2024.1.0"
1135
+ average_results_per_query: ${searchResultsNum}
1136
+
1137
+ # Hardware
1138
+ hardware:
1139
+ gpu: # Please fill in
1140
+ ram: # Please fill in
1141
+ cpu: # Please fill in
1142
+
1143
+ # Benchmark Results
1144
+ results:
1145
+ dataset: SimpleQA
1146
+ total_questions: ${run.total_examples}
1147
+
1148
+ ${run.search_config?.search_strategy === 'focused_iteration' ? 'focused_iteration' : 'source_based'}:
1149
+ accuracy: ${run.overall_accuracy ? run.overall_accuracy.toFixed(1) : 0}% (${Math.round(run.overall_accuracy * run.total_examples / 100)}/${run.total_examples})
1150
+ iterations: ${run.search_config?.iterations || 'N/A'}
1151
+ questions_per_iteration: ${run.search_config?.questions_per_iteration || 'N/A'}
1152
+ avg_time_per_question: ${formatAvgProcessingTime(run)}
1153
+ total_tokens_used: # if available
1154
+
1155
+ # Configuration
1156
+ configuration:
1157
+ context_window: ${localContextWindow} # Current setting at download time - may differ from benchmark run
1158
+ temperature: ${run.search_config?.temperature || 'N/A'}
1159
+ max_tokens: ${maxTokens} # Current setting at download time
1160
+ local_provider_context_window_size: ${localContextWindow} # Current setting at download time
1161
+ context_window_unrestricted: ${contextWindowUnrestricted} # Current setting at download time
1162
+
1163
+ # Versions
1164
+ versions:
1165
+ ldr_version: ${appVersion}
1166
+ ollama_version: # if applicable
1167
+
1168
+ # Test Details
1169
+ test_details:
1170
+ date_tested: ${date}
1171
+ rate_limiting_issues: # yes/no
1172
+ search_failures: # number of failed searches, if any
1173
+
1174
+ # Notes
1175
+ notes: |
1176
+ # Add any observations, errors, or insights here
1177
+ # Search strategy: ${run.search_config?.search_strategy || 'unknown'}
1178
+ # Provider: ${run.search_config?.provider || 'unknown'}
1179
+ # Note: Configuration values are from current settings at download time,
1180
+ # not necessarily the values used during the benchmark run
1181
+ `;
1182
+
1183
+ // Create blob and download
1184
+ const blob = new Blob([yamlContent], { type: 'text/yaml' });
1185
+ const url = window.URL.createObjectURL(blob);
1186
+ const a = document.createElement('a');
1187
+ a.style.display = 'none';
1188
+ a.href = url;
1189
+ a.download = `${cleanModelName}_${date}.yaml`;
1190
+ document.body.appendChild(a);
1191
+ a.click();
1192
+ window.URL.revokeObjectURL(url);
1193
+ document.body.removeChild(a);
1194
+
1195
+ showAlert('Benchmark YAML downloaded! Hardware details are optional but helpful for performance context.', 'success');
1196
+ } catch (error) {
1197
+ console.error('Error downloading YAML:', error);
1198
+ showAlert('Error downloading YAML: ' + error.message, 'error');
1199
+ }
1200
+ }
1201
+
1064
1202
  async function deleteBenchmarkRun(runId) {
1065
1203
  try {
1066
1204
  const response = await fetch(`/benchmark/api/delete/${runId}`, {
@@ -9,7 +9,7 @@ from collections import deque
9
9
  from typing import Dict, Optional, Tuple, List
10
10
 
11
11
 
12
- from ...utilities.db_utils import get_db_session
12
+ from ...utilities.db_utils import get_db_session, get_db_setting
13
13
  from ...web.database.models import RateLimitAttempt, RateLimitEstimate
14
14
 
15
15
  logger = logging.getLogger(__name__)
@@ -23,8 +23,6 @@ class AdaptiveRateLimitTracker:
23
23
 
24
24
  def __init__(self):
25
25
  # Load configuration from database settings
26
- from ...utilities.db_utils import get_db_setting
27
-
28
26
  self.memory_window = int(
29
27
  get_db_setting("rate_limiting.memory_window", 100)
30
28
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: local-deep-research
3
- Version: 0.6.0
3
+ Version: 0.6.4
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>, djpetti <djpetti@gmail.com>
6
6
  License: MIT License
@@ -99,6 +99,7 @@ Description-Content-Type: text/markdown
99
99
 
100
100
  *Performs deep, iterative research using multiple LLMs and search engines with proper citations*
101
101
  </div>
102
+
102
103
  ## 🚀 What is Local Deep Research?
103
104
 
104
105
  LDR is an AI research assistant that performs systematic research by:
@@ -118,6 +119,14 @@ It aims to help researchers, students, and professionals find accurate informati
118
119
  - **Transparent**: Track costs and performance with built-in analytics
119
120
  - **Open Source**: MIT licensed with an active community
120
121
 
122
+ ## 📊 Performance
123
+
124
+ **~95% accuracy on SimpleQA benchmark** (preliminary results)
125
+ - Tested with GPT-4.1-mini + SearXNG + focused-iteration strategy
126
+ - Comparable to state-of-the-art AI research systems
127
+ - Local models can achieve similar performance with proper configuration
128
+ - [Join our community benchmarking effort →](https://github.com/LearningCircuit/local-deep-research/tree/main/community_benchmark_results)
129
+
121
130
  ## ✨ Key Features
122
131
 
123
132
  ### 🔍 Research Modes
@@ -160,7 +169,7 @@ It aims to help researchers, students, and professionals find accurate informati
160
169
 
161
170
  ## ⚡ Quick Start
162
171
 
163
- ### Option 1: Docker (Quickstart no MAC/ARM)
172
+ ### Option 1: Docker (Quickstart on MAC/ARM)
164
173
 
165
174
  ```bash
166
175
  # Step 1: Pull and run SearXNG for optimal search results
@@ -175,7 +184,13 @@ docker run -d -p 5000:5000 --name local-deep-research --volume 'deep-research:/i
175
184
  LDR uses Docker compose to bundle the web app and all it's dependencies so
176
185
  you can get up and running quickly.
177
186
 
178
- #### Option 2a: DIY docker-compose
187
+ #### Option 2a: Quick Start (One Command)
188
+ ```bash
189
+ curl -O https://raw.githubusercontent.com/LearningCircuit/local-deep-research/main/docker-compose.yml && docker compose up -d
190
+ ```
191
+ Open http://localhost:5000 after ~30 seconds. This starts LDR with SearXNG and all dependencies.
192
+
193
+ #### Option 2b: DIY docker-compose
179
194
  See [docker-compose.yml](./docker-compose.yml) for a docker-compose file with reasonable defaults to get up and running with ollama, searxng, and local deep research all running locally.
180
195
 
181
196
  Things you may want/need to configure:
@@ -184,7 +199,7 @@ Things you may want/need to configure:
184
199
  * Ollama keep alive (duration model will stay loaded into VRAM and idle before getting unloaded automatically)
185
200
  * Deep Research model (depends on available VRAM and preference)
186
201
 
187
- #### Option 2b: Use Cookie Cutter to tailor a docker-compose to your needs:
202
+ #### Option 2c: Use Cookie Cutter to tailor a docker-compose to your needs:
188
203
 
189
204
  ##### Prerequisites
190
205
 
@@ -302,7 +317,7 @@ Early experiments on small SimpleQA dataset samples:
302
317
  | Configuration | Accuracy | Notes |
303
318
  |--------------|----------|--------|
304
319
  | gpt-4.1-mini + SearXNG + focused_iteration | 90-95% | Limited sample size |
305
- | gpt-4.1-mini + Tavily | Up to 95% | Limited sample size |
320
+ | gpt-4.1-mini + Tavily + focused_iteration | 90-95% | Limited sample size |
306
321
  | gemini-2.0-flash-001 + SearXNG | 82% | Single test run |
307
322
 
308
323
  Note: These are preliminary results from initial testing. Performance varies significantly based on query types, model versions, and configurations. [Run your own benchmarks →](docs/BENCHMARKING.md)
@@ -1,9 +1,9 @@
1
- local_deep_research-0.6.0.dist-info/METADATA,sha256=f1zxuIR6tmbB13f_PPbBBGvIyFiEAicvJDgwO9YOcPU,14505
2
- local_deep_research-0.6.0.dist-info/WHEEL,sha256=tSfRZzRHthuv7vxpI4aehrdN9scLjk-dCJkPLzkHxGg,90
3
- local_deep_research-0.6.0.dist-info/entry_points.txt,sha256=GcXS501Rjh-P80S8db7hnrQ23mS_Jg27PwpVQVO77as,113
4
- local_deep_research-0.6.0.dist-info/licenses/LICENSE,sha256=Qg2CaTdu6SWnSqk1_JtgBPp_Da-LdqJDhT1Vt1MUc5s,1072
5
- local_deep_research/__init__.py,sha256=j1ktf_e9HeXPe86NHibY5aINtZfTSGRTvLNtz9BJZa4,1071
6
- local_deep_research/__version__.py,sha256=cID1jLnC_vj48GgMN6Yb1FA3JsQ95zNmCHmRYE8TFhY,22
1
+ local_deep_research-0.6.4.dist-info/METADATA,sha256=TtghNU7ziPFS-HZL26QwIS_4EcR7JNL85H0e8BRBOCs,15218
2
+ local_deep_research-0.6.4.dist-info/WHEEL,sha256=tSfRZzRHthuv7vxpI4aehrdN9scLjk-dCJkPLzkHxGg,90
3
+ local_deep_research-0.6.4.dist-info/entry_points.txt,sha256=GcXS501Rjh-P80S8db7hnrQ23mS_Jg27PwpVQVO77as,113
4
+ local_deep_research-0.6.4.dist-info/licenses/LICENSE,sha256=Qg2CaTdu6SWnSqk1_JtgBPp_Da-LdqJDhT1Vt1MUc5s,1072
5
+ local_deep_research/__init__.py,sha256=_I_QZVYHUi9KSq78IVVNm_MKasj2RByOxBEo6w72PT8,1250
6
+ local_deep_research/__version__.py,sha256=WMmvm2Keb76yMz8OL_h4fKT34Xpi-1BVfCiTn2QGzz4,22
7
7
  local_deep_research/advanced_search_system/__init__.py,sha256=sGusMj4eFIrhXR6QbOM16UDKB6aI-iS4IFivKWpMlh0,234
8
8
  local_deep_research/advanced_search_system/answer_decoding/__init__.py,sha256=BmmbIPQnouYyboFD61CDq71fW5On555w7dbt42s9gV4,148
9
9
  local_deep_research/advanced_search_system/answer_decoding/browsecomp_answer_decoder.py,sha256=4FDMP4n_z5DOzVIisH3_kexRqNm1AO3MDe-Md3WtgE0,12856
@@ -166,35 +166,32 @@ local_deep_research/metrics/pricing/pricing_fetcher.py,sha256=YQThSQIZmy9VJp0TSo
166
166
  local_deep_research/metrics/query_utils.py,sha256=BDQk3F-nmI09mIGbelteCCWxq4oSKKKdHv4OO5Q_fGo,1522
167
167
  local_deep_research/metrics/search_tracker.py,sha256=sPC9hKq2X78Wlx4YUVxvneq0Ce1m0HebJAWO-226gd8,15862
168
168
  local_deep_research/metrics/token_counter.py,sha256=QmNvJhAKgpzxmBErCZ0pEAjCwgk8IBMt-gXaQRksXCs,43043
169
- local_deep_research/migrate_db.py,sha256=-Ql7bC2VmXlWtDOXj7CGVBvBlSk--wHyZCniWJnhC6c,4648
170
169
  local_deep_research/report_generator.py,sha256=8nBYTT5cO35B0b6NFsjdroBoBvzSJJa9OsUCtdQPAAg,9320
171
170
  local_deep_research/search_system.py,sha256=_JaOavJNo4q8t0Ir8KlvG6fFX3k7P6GkCOwYkCGYJ3E,27348
172
- local_deep_research/setup_data_dir.py,sha256=7MJa2MMdDUnktJVHwMpyNL2079-qylpIyyLpVbF5AUY,1134
171
+ local_deep_research/setup_data_dir.py,sha256=IMp9ndGUqY5XYIbCk0V_F4cEL3n7FWLbut5XeatqUuc,1172
173
172
  local_deep_research/utilities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
174
- local_deep_research/utilities/db_utils.py,sha256=BE3oP7WRbtlaqOxMrVFoAo11NpTk3RlC9w8tZUC_INU,1681
173
+ local_deep_research/utilities/db_utils.py,sha256=7FbN5LWiDqv7tLdcSr8cuGREBpOvIU8-f_S1Bnd3v_E,1872
175
174
  local_deep_research/utilities/enums.py,sha256=yFwmodt93uETdQd7qyW4vOUhiAzZF-BHBbVYHKN7scU,223
176
175
  local_deep_research/utilities/es_utils.py,sha256=5jT17BDR0bapHNIwMgezHmrbV4WQ7ZA1rY9CDF8ouAc,14747
177
176
  local_deep_research/utilities/llm_utils.py,sha256=svjDDto95myjtSIJyd6t6uaezBEdEtj_tH-wVGjAHV0,5046
178
- local_deep_research/utilities/log_utils.py,sha256=664m7Rc90Fna_UE8n50bPxvC7alLEYDi2EY3ZiHFQqk,5393
177
+ local_deep_research/utilities/log_utils.py,sha256=xFHsS7SJEdQhEdKoxVgcWMbY-wMEbvPD6Bey63pxh7s,5418
179
178
  local_deep_research/utilities/search_cache.py,sha256=BGHU3_1PhRc1gikiFtl-28ziqMMQLm8GBR46Hir1Y_U,13239
180
179
  local_deep_research/utilities/search_utilities.py,sha256=yyQYSBSS1IGGFwaRs0s27gEvSYgYqYRsVTK0v2jZ4GQ,9713
181
180
  local_deep_research/utilities/setup_utils.py,sha256=0Us6doQ6xQtKzgtnN1C4L7sSgxzFKJ35FpmZdj1tCDM,213
182
181
  local_deep_research/utilities/thread_context.py,sha256=M3NszCJD1xHa_9-GJpDrAi5qYmKVe55lj1Vq_Z_P8vw,3104
183
- local_deep_research/utilities/threading_utils.py,sha256=3dwErIOazT6V4HkUFo4BvjRNLe_I_PGi8Xtfl8LfmVY,2495
182
+ local_deep_research/utilities/threading_utils.py,sha256=j1YdqD0PvUuLrcaaI_itLUfWK7ki_B0F18xy0s9gtpo,2888
184
183
  local_deep_research/utilities/url_utils.py,sha256=-GjOVrJCglNCDRs9rePyP1T8d6TeIGwI_nzCA5USPd4,1909
185
184
  local_deep_research/web/__init__.py,sha256=CynnuRxCf9mB0AHeylhF5yVZwdj0H6bxVrZtniw3xmE,44
186
- local_deep_research/web/api.py,sha256=jtn6ndV-ghRYqBkxDTz2hR9woQ4yIAtwa13YXa2_d7g,11260
187
- local_deep_research/web/app.py,sha256=3bBUHXB35AE3-7oxSieF0ceYrQaq5LBTdJUSr8PpcCU,3376
188
- local_deep_research/web/app_factory.py,sha256=AjWReFfpUgpQHw70cik0MZeRmDxMwlx7VooIxWPiNnQ,10220
185
+ local_deep_research/web/api.py,sha256=JSc3mRrVVB4BHgeYLnUjtq0dxURbKKQNrS2HdRAct2o,11285
186
+ local_deep_research/web/app.py,sha256=cWiNJL-DExvg3bH6TBmL4C4fO-B-0wakdrn5qdCi-IY,798
187
+ local_deep_research/web/app_factory.py,sha256=41BwIgnHRz3KMFEp7KmAm6IydrfzIkrjO5OqV0D6CBo,9949
189
188
  local_deep_research/web/database/README.md,sha256=eEDLqLIfOBRvc0TFh3J1HrtFbZceYmVgpjS3-oyZ5nI,2861
190
189
  local_deep_research/web/database/benchmark_schema.py,sha256=nlqqG5o9XVRGtDlLzFS9XNinNntUhvl_JFUYyjMst-w,7629
191
190
  local_deep_research/web/database/convert_research_id_to_string.py,sha256=3xrVy0crCoM94N4TZfLZAEJTt7oYGX60zrDo0PZZrCQ,5619
192
- local_deep_research/web/database/migrate_to_ldr_db.py,sha256=RRzITerhjUjlHPTf6GoNgrwa4BpKuj_RAohzcS9ttG0,9919
193
- local_deep_research/web/database/migrations.py,sha256=BKUDckR98Yz8cMtd473lMxLcVqWTtFyHVFWFPs9PgfY,2468
191
+ local_deep_research/web/database/migrations.py,sha256=YLa78izXCdwY6YZokYUIPQl2Ryd-5v_jwQ79PJAI8R4,25101
194
192
  local_deep_research/web/database/models.py,sha256=eQN1Rqo_aCHjpefedoGi7zQ_HSbKKFhKTqF-6lOUvqc,7991
195
- local_deep_research/web/database/schema_upgrade.py,sha256=RamOIDMu9bTRzdG5jKK5a4h6mK3aTEPvehNwoSbQPyA,16904
196
- local_deep_research/web/database/uuid_migration.py,sha256=U9nJQyl1BszcP-4kBREKsivAk9fjQZ6BowIvjUstnT0,9041
197
- local_deep_research/web/models/database.py,sha256=uBecKQpZd9cXdt2ZPUr0FOpHFbDZd40kQNKYSZOxnEI,8422
193
+ local_deep_research/web/database/uuid_migration.py,sha256=12se2wvSLtHUNKctu_e0bfgDjfV-ykZwWCdiYcbXvv0,484
194
+ local_deep_research/web/models/database.py,sha256=w8A4ORA4jXBVdr0UK0THfLmWfbjNsA-reYv3jO6Vkaw,5915
198
195
  local_deep_research/web/models/settings.py,sha256=rXBI9vY5k3ndR8dPd3fZJy-6HwYltQihhSBRq-sZutw,2314
199
196
  local_deep_research/web/routes/api_routes.py,sha256=RlpM0cl9UKxYdezNtNvzbUQiZsTOyTnlvoRMeylUYK0,21167
200
197
  local_deep_research/web/routes/benchmark_routes.py,sha256=bXiURrmWoaGtbOQ3jhgXgxjs3Qa440Jqk1CPZ1QMyO0,15725
@@ -203,12 +200,12 @@ local_deep_research/web/routes/history_routes.py,sha256=h2AeFhpQ8H7uKulKTtddQAH8
203
200
  local_deep_research/web/routes/metrics_routes.py,sha256=HiiO_2N4_YZG0xmBaC9iny3yNwIK7lzqqRoC36SuWiE,51054
204
201
  local_deep_research/web/routes/research_routes.py,sha256=H4M_iWStNQUqmhGmMfsFBb-e9wetX6FJVH46J4d0ITE,29054
205
202
  local_deep_research/web/routes/route_registry.py,sha256=4-8hDPSoZme20kXGb3sXCfZR17mEarluhhHEF23MZ0E,10822
206
- local_deep_research/web/routes/settings_routes.py,sha256=0HncIt3upismRvZnxzbSzAF4RoxAnDJKbxYo6sdVzr8,73711
203
+ local_deep_research/web/routes/settings_routes.py,sha256=2oUCDlbLW-OKe49h59OAskNDgkZYRFdJhxVlBSijTQ0,73656
207
204
  local_deep_research/web/services/research_service.py,sha256=H-l37P61VkHENtk2iVdanf96_ocMVIFD6t9PV1XELL4,48166
208
205
  local_deep_research/web/services/resource_service.py,sha256=aU7SDADxcIAAuIymL_TOxUV_HvEMAfL8gZSB5gVSzFM,4674
209
- local_deep_research/web/services/settings_manager.py,sha256=goVcKMogPxYf7ey2dq3Cp6ULvfrQLiUJ-mOXAUsdrVY,21708
210
- local_deep_research/web/services/settings_service.py,sha256=s_JFXJTdMmZ1d-_FGWibfSKkYp6kCs5TqMVqNgBJrvQ,3666
211
- local_deep_research/web/services/socket_service.py,sha256=kKV9LbMvgMtuvX32nuZnrMWwS6IzSOM90FxL9nWsfCQ,11904
206
+ local_deep_research/web/services/settings_manager.py,sha256=EOdE8rtm4mFV3_4gLfupOtHGlQf6bBAn0m3Xz_t58sY,21235
207
+ local_deep_research/web/services/settings_service.py,sha256=OemPUMQtb8cfRjG7ZIWVDZ5ZZQTaxdQx4RNrwKgAyDQ,2821
208
+ local_deep_research/web/services/socket_service.py,sha256=oyO1_S-lFJRIHw06hepheBiz_xYanZ0Fd2gmyGV2hiI,11895
212
209
  local_deep_research/web/static/css/custom_dropdown.css,sha256=MFRm4HaMGM7X2Z-Yvb-_y20BE1NInSmN1cUJc_v5k4k,11542
213
210
  local_deep_research/web/static/css/settings.css,sha256=QZbjLz8zNQZvM_ROzQOH67ZHZHEQ8WohkIPJlsekqfk,24719
214
211
  local_deep_research/web/static/css/styles.css,sha256=u7ZjeXIk_aMwLKLyDAc5lpY6nz9J_I_SaUTZzk6Hk84,37088
@@ -244,7 +241,7 @@ local_deep_research/web/templates/components/mobile_nav.html,sha256=6wbqweC5DGEy
244
241
  local_deep_research/web/templates/components/settings_form.html,sha256=Z1eEQ_SFlioH24zrIDpjMQ-ajEJC2lLN4Tu8Y8uASLY,15987
245
242
  local_deep_research/web/templates/components/sidebar.html,sha256=yvdex0rFt9IFEhVu50MEyvpBIlMKg8x9hLZf-cugPaY,1698
246
243
  local_deep_research/web/templates/pages/benchmark.html,sha256=jeqe6koHeVmXKt0U8_JKWnSZEZouq5SuW_kEZMMKjRs,103838
247
- local_deep_research/web/templates/pages/benchmark_results.html,sha256=K9cs2-i_jUsGVrZaDO8NmCsVNo7fmbthpW9zKglnSb0,33639
244
+ local_deep_research/web/templates/pages/benchmark_results.html,sha256=ijQesleJN-pCNoyQGViRH5bCwb15fYY3vliH5hWjTfM,39771
248
245
  local_deep_research/web/templates/pages/benchmark_simple.html,sha256=mLvhzJqRj4rFRJPG9Jo-eHYSogeDVnpRgd5TwACZ1t8,14396
249
246
  local_deep_research/web/templates/pages/cost_analytics.html,sha256=mXHw-MSXztJMh6xvW2D_9KXW5EuyrpNnMFTpP7Ob2GQ,46194
250
247
  local_deep_research/web/templates/pages/details.html,sha256=Led51_cv97e_Z057_7QVWT7imVB4f71FWeL2q83CJrE,12413
@@ -284,9 +281,9 @@ local_deep_research/web_search_engines/rate_limiting/__init__.py,sha256=gWBaVMRY
284
281
  local_deep_research/web_search_engines/rate_limiting/__main__.py,sha256=9sWZ7ev3dZYPmgKK3K7fEaku2IAnjlrHPbaKV9VlllY,191
285
282
  local_deep_research/web_search_engines/rate_limiting/cli.py,sha256=xX5YD-fNXjdqCaDzx4_aEIoiZFX1AyuQV6Vfya-Wios,5683
286
283
  local_deep_research/web_search_engines/rate_limiting/exceptions.py,sha256=KIzjgVPMxx4sw1J4tjkxz0N9TgrFZGWXQxCemHnVXHI,396
287
- local_deep_research/web_search_engines/rate_limiting/tracker.py,sha256=Q36R2coA0kBE2XeRxb0Ebnq4P9DWbRsrc3DbAjS8GQU,17562
284
+ local_deep_research/web_search_engines/rate_limiting/tracker.py,sha256=vvZ0jvi9FbvqrNE0rvoncsXuEXjRwboRpPAcp03bGqk,17520
288
285
  local_deep_research/web_search_engines/retriever_registry.py,sha256=ZErfErn6s1LIQt1q9KjMu61-l7w_D_2jQceQT8kS3xo,3026
289
286
  local_deep_research/web_search_engines/search_engine_base.py,sha256=0ys6nqm4WLTvYqHLZk4x5ZKFTc4BcqhUBjT1m1Jibp0,17114
290
287
  local_deep_research/web_search_engines/search_engine_factory.py,sha256=jKvLkv6rHWSKTnqfLvyvA2WF4qu5qaelgd4IoGOcyVs,12588
291
288
  local_deep_research/web_search_engines/search_engines_config.py,sha256=aZ1Y5YMPWgZqRC-wCJ4JUQgliBNSbU0dOUlCvR_elws,6086
292
- local_deep_research-0.6.0.dist-info/RECORD,,
289
+ local_deep_research-0.6.4.dist-info/RECORD,,