local-deep-research 0.2.3__py3-none-any.whl → 0.3.1__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.
- local_deep_research/__init__.py +1 -1
- local_deep_research/__version__.py +1 -0
- local_deep_research/advanced_search_system/filters/cross_engine_filter.py +5 -1
- local_deep_research/advanced_search_system/strategies/base_strategy.py +5 -2
- local_deep_research/advanced_search_system/strategies/iterdrag_strategy.py +23 -16
- local_deep_research/advanced_search_system/strategies/parallel_search_strategy.py +13 -6
- local_deep_research/advanced_search_system/strategies/rapid_search_strategy.py +4 -3
- local_deep_research/advanced_search_system/strategies/source_based_strategy.py +57 -62
- local_deep_research/advanced_search_system/strategies/standard_strategy.py +8 -4
- local_deep_research/api/research_functions.py +0 -46
- local_deep_research/citation_handler.py +2 -5
- local_deep_research/config/llm_config.py +25 -68
- local_deep_research/config/search_config.py +8 -21
- local_deep_research/defaults/default_settings.json +3996 -0
- local_deep_research/search_system.py +34 -31
- local_deep_research/utilities/db_utils.py +22 -3
- local_deep_research/utilities/search_utilities.py +10 -7
- local_deep_research/web/app.py +3 -23
- local_deep_research/web/app_factory.py +1 -25
- local_deep_research/web/database/migrations.py +20 -418
- local_deep_research/web/routes/settings_routes.py +75 -364
- local_deep_research/web/services/research_service.py +43 -43
- local_deep_research/web/services/settings_manager.py +108 -315
- local_deep_research/web/services/settings_service.py +3 -56
- local_deep_research/web/static/js/components/research.js +1 -1
- local_deep_research/web/static/js/components/settings.js +16 -4
- local_deep_research/web/static/js/research_form.js +106 -0
- local_deep_research/web/templates/pages/research.html +3 -2
- local_deep_research/web_search_engines/engines/meta_search_engine.py +56 -21
- local_deep_research/web_search_engines/engines/search_engine_local.py +11 -2
- local_deep_research/web_search_engines/engines/search_engine_local_all.py +7 -11
- local_deep_research/web_search_engines/search_engine_factory.py +12 -64
- local_deep_research/web_search_engines/search_engines_config.py +123 -64
- {local_deep_research-0.2.3.dist-info → local_deep_research-0.3.1.dist-info}/METADATA +16 -1
- {local_deep_research-0.2.3.dist-info → local_deep_research-0.3.1.dist-info}/RECORD +38 -39
- local_deep_research/config/config_files.py +0 -245
- local_deep_research/defaults/local_collections.toml +0 -53
- local_deep_research/defaults/main.toml +0 -80
- local_deep_research/defaults/search_engines.toml +0 -291
- {local_deep_research-0.2.3.dist-info → local_deep_research-0.3.1.dist-info}/WHEEL +0 -0
- {local_deep_research-0.2.3.dist-info → local_deep_research-0.3.1.dist-info}/entry_points.txt +0 -0
- {local_deep_research-0.2.3.dist-info → local_deep_research-0.3.1.dist-info}/licenses/LICENSE +0 -0
@@ -3,35 +3,31 @@ import logging
|
|
3
3
|
from sqlalchemy import inspect
|
4
4
|
|
5
5
|
from ..services.settings_manager import SettingsManager
|
6
|
-
from .models import Base, Setting
|
6
|
+
from .models import Base, Setting
|
7
7
|
|
8
8
|
logger = logging.getLogger(__name__)
|
9
9
|
|
10
10
|
|
11
|
-
def
|
11
|
+
def import_default_settings_file(db_session):
|
12
12
|
"""
|
13
|
-
|
13
|
+
Imports all settings from the default settings file to the DB.
|
14
14
|
"""
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
else:
|
32
|
-
logger.info(
|
33
|
-
"Settings table already has %s rows, skipping import", settings_count
|
34
|
-
)
|
15
|
+
settings_mgr = SettingsManager(db_session)
|
16
|
+
if settings_mgr.db_version_matches_defaults():
|
17
|
+
# We probably shouldn't bother loading settings if the version didn't
|
18
|
+
# change.
|
19
|
+
return
|
20
|
+
logger.info("Detected a new version of default settings, upgrading DB.")
|
21
|
+
|
22
|
+
# Create settings manager and import settings
|
23
|
+
try:
|
24
|
+
# This will not overwrite existing settings, but will delete
|
25
|
+
# extraneous ones. This should be enough to update anyone with
|
26
|
+
# old versions of the settings.
|
27
|
+
settings_mgr.load_from_defaults_file(overwrite=False, delete_extra=True)
|
28
|
+
logger.info("Successfully imported settings from files")
|
29
|
+
except Exception as e:
|
30
|
+
logger.error("Error importing settings from files: %s", e)
|
35
31
|
|
36
32
|
|
37
33
|
def run_migrations(engine, db_session=None):
|
@@ -50,398 +46,4 @@ def run_migrations(engine, db_session=None):
|
|
50
46
|
|
51
47
|
# Import existing settings from files
|
52
48
|
if db_session:
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
def setup_predefined_settings(db_session):
|
57
|
-
"""
|
58
|
-
Set up predefined settings with UI metadata
|
59
|
-
|
60
|
-
Args:
|
61
|
-
db_session: SQLAlchemy session
|
62
|
-
"""
|
63
|
-
# Define standard UI settings for LLM
|
64
|
-
llm_settings = [
|
65
|
-
{
|
66
|
-
"key": "llm.model",
|
67
|
-
"name": "LLM Model",
|
68
|
-
"description": "Language model to use for research and analysis",
|
69
|
-
"category": "llm_general",
|
70
|
-
"ui_element": "select",
|
71
|
-
"options": [
|
72
|
-
{"value": "gpt-4o", "label": "GPT-4o (OpenAI)"},
|
73
|
-
{"value": "gpt-3.5-turbo", "label": "GPT-3.5 Turbo (OpenAI)"},
|
74
|
-
{
|
75
|
-
"value": "claude-3-5-sonnet-latest",
|
76
|
-
"label": "Claude 3.5 Sonnet (Anthropic)",
|
77
|
-
},
|
78
|
-
{
|
79
|
-
"value": "claude-3-opus-20240229",
|
80
|
-
"label": "Claude 3 Opus (Anthropic)",
|
81
|
-
},
|
82
|
-
{"value": "llama3", "label": "Llama 3 (Meta)"},
|
83
|
-
{"value": "mistral", "label": "Mistral (Mistral AI)"},
|
84
|
-
{"value": "mixtral", "label": "Mixtral (Mistral AI)"},
|
85
|
-
],
|
86
|
-
"value": "gpt-3.5-turbo",
|
87
|
-
},
|
88
|
-
{
|
89
|
-
"key": "llm.provider",
|
90
|
-
"name": "LLM Provider",
|
91
|
-
"description": "Service provider for the language model",
|
92
|
-
"category": "llm_general",
|
93
|
-
"ui_element": "select",
|
94
|
-
"options": [
|
95
|
-
{"value": "openai", "label": "OpenAI API"},
|
96
|
-
{"value": "anthropic", "label": "Anthropic API"},
|
97
|
-
{"value": "ollama", "label": "Ollama (Local)"},
|
98
|
-
{"value": "lmstudio", "label": "LM Studio (Local)"},
|
99
|
-
{"value": "vllm", "label": "vLLM (Local)"},
|
100
|
-
{"value": "openai_endpoint", "label": "Custom OpenAI-compatible API"},
|
101
|
-
],
|
102
|
-
"value": "openai",
|
103
|
-
},
|
104
|
-
{
|
105
|
-
"key": "llm.temperature",
|
106
|
-
"name": "Temperature",
|
107
|
-
"description": "Controls randomness in model outputs (0.0 - 1.0)",
|
108
|
-
"category": "llm_parameters",
|
109
|
-
"ui_element": "slider",
|
110
|
-
"min_value": 0.0,
|
111
|
-
"max_value": 1.0,
|
112
|
-
"step": 0.05,
|
113
|
-
"value": 0.7,
|
114
|
-
},
|
115
|
-
{
|
116
|
-
"key": "llm.max_tokens",
|
117
|
-
"name": "Max Tokens",
|
118
|
-
"description": "Maximum number of tokens in model responses",
|
119
|
-
"category": "llm_parameters",
|
120
|
-
"ui_element": "number",
|
121
|
-
"min_value": 100,
|
122
|
-
"max_value": 4096,
|
123
|
-
"value": 1024,
|
124
|
-
},
|
125
|
-
]
|
126
|
-
|
127
|
-
# Define standard UI settings for Search
|
128
|
-
search_settings = [
|
129
|
-
{
|
130
|
-
"key": "search.tool",
|
131
|
-
"name": "Search Engine",
|
132
|
-
"description": "Web search engine to use for research",
|
133
|
-
"category": "search_general",
|
134
|
-
"ui_element": "select",
|
135
|
-
"options": [
|
136
|
-
{"value": "auto", "label": "Auto (Default)"},
|
137
|
-
{"value": "arxiv", "label": "Arxiv"},
|
138
|
-
{"value": "wikipedia", "label": "Wikipedia"},
|
139
|
-
{"value": "pubmed", "label": "Pubmed"},
|
140
|
-
{"value": "github", "label": "Github"},
|
141
|
-
{"value": "serpapi", "label": "SerpAPI (Google)"},
|
142
|
-
{"value": "searxng", "label": "SearXNG (Self-hosted)"},
|
143
|
-
{"value": "google_pse", "label": "Google Programmable Search Engine"},
|
144
|
-
{"value": "duckduckgo", "label": "DuckDuckGo"},
|
145
|
-
{"value": "brave", "label": "Brave"},
|
146
|
-
{"value": "wayback", "label": "Wayback"},
|
147
|
-
{"value": "local_all", "label": "Local All"},
|
148
|
-
],
|
149
|
-
"value": "auto",
|
150
|
-
},
|
151
|
-
{
|
152
|
-
"key": "search.max_results",
|
153
|
-
"name": "Max Results",
|
154
|
-
"description": "Maximum number of search results to retrieve",
|
155
|
-
"category": "search_parameters",
|
156
|
-
"ui_element": "number",
|
157
|
-
"min_value": 3,
|
158
|
-
"max_value": 50,
|
159
|
-
"value": 10,
|
160
|
-
},
|
161
|
-
{
|
162
|
-
"key": "search.region",
|
163
|
-
"name": "Search Region",
|
164
|
-
"description": "Geographic region for search results",
|
165
|
-
"category": "search_parameters",
|
166
|
-
"ui_element": "select",
|
167
|
-
"options": [
|
168
|
-
{"value": "us", "label": "United States"},
|
169
|
-
{"value": "uk", "label": "United Kingdom"},
|
170
|
-
{"value": "fr", "label": "France"},
|
171
|
-
{"value": "de", "label": "Germany"},
|
172
|
-
{"value": "jp", "label": "Japan"},
|
173
|
-
{"value": "wt-wt", "label": "No Region (Worldwide)"},
|
174
|
-
],
|
175
|
-
"value": "us",
|
176
|
-
},
|
177
|
-
{
|
178
|
-
"key": "search.time_period",
|
179
|
-
"name": "Time Period",
|
180
|
-
"description": "Time period for search results",
|
181
|
-
"category": "search_parameters",
|
182
|
-
"ui_element": "select",
|
183
|
-
"options": [
|
184
|
-
{"value": "d", "label": "Past 24 hours"},
|
185
|
-
{"value": "w", "label": "Past week"},
|
186
|
-
{"value": "m", "label": "Past month"},
|
187
|
-
{"value": "y", "label": "Past year"},
|
188
|
-
{"value": "all", "label": "All time"},
|
189
|
-
],
|
190
|
-
"value": "all",
|
191
|
-
},
|
192
|
-
{
|
193
|
-
"key": "search.snippets_only",
|
194
|
-
"name": "Snippets Only",
|
195
|
-
"description": "Only retrieve snippets instead of full search results",
|
196
|
-
"category": "search_parameters",
|
197
|
-
"ui_element": "checkbox",
|
198
|
-
"value": True,
|
199
|
-
},
|
200
|
-
]
|
201
|
-
|
202
|
-
# Define standard UI settings for Report generation
|
203
|
-
report_settings = [
|
204
|
-
{
|
205
|
-
"key": "report.searches_per_section",
|
206
|
-
"name": "Searches Per Section",
|
207
|
-
"description": "Number of searches to run per report section",
|
208
|
-
"category": "report_parameters",
|
209
|
-
"ui_element": "number",
|
210
|
-
"min_value": 1,
|
211
|
-
"max_value": 5,
|
212
|
-
"value": 2,
|
213
|
-
},
|
214
|
-
{
|
215
|
-
"key": "report.enable_fact_checking",
|
216
|
-
"name": "Enable Fact Checking",
|
217
|
-
"description": "Enable fact checking for report contents",
|
218
|
-
"category": "report_parameters",
|
219
|
-
"ui_element": "checkbox",
|
220
|
-
"value": True,
|
221
|
-
},
|
222
|
-
{
|
223
|
-
"key": "report.detailed_citations",
|
224
|
-
"name": "Detailed Citations",
|
225
|
-
"description": "Include detailed citations in reports",
|
226
|
-
"category": "report_parameters",
|
227
|
-
"ui_element": "checkbox",
|
228
|
-
"value": True,
|
229
|
-
},
|
230
|
-
]
|
231
|
-
|
232
|
-
# Define standard UI settings for App
|
233
|
-
app_settings = [
|
234
|
-
{
|
235
|
-
"key": "app.debug",
|
236
|
-
"name": "Debug Mode",
|
237
|
-
"description": "Enable debug mode for the web application",
|
238
|
-
"category": "app_interface",
|
239
|
-
"ui_element": "checkbox",
|
240
|
-
"value": True,
|
241
|
-
},
|
242
|
-
{
|
243
|
-
"key": "app.host",
|
244
|
-
"name": "Web Host",
|
245
|
-
"description": "Host address to bind the web server",
|
246
|
-
"category": "app_interface",
|
247
|
-
"ui_element": "text",
|
248
|
-
"value": "0.0.0.0",
|
249
|
-
},
|
250
|
-
{
|
251
|
-
"key": "app.port",
|
252
|
-
"name": "Web Port",
|
253
|
-
"description": "Port for the web server",
|
254
|
-
"category": "app_interface",
|
255
|
-
"ui_element": "number",
|
256
|
-
"min_value": 1,
|
257
|
-
"max_value": 65535,
|
258
|
-
"value": 5000,
|
259
|
-
},
|
260
|
-
{
|
261
|
-
"key": "app.enable_notifications",
|
262
|
-
"name": "Enable Notifications",
|
263
|
-
"description": "Enable browser notifications for research events",
|
264
|
-
"category": "app_interface",
|
265
|
-
"ui_element": "checkbox",
|
266
|
-
"value": True,
|
267
|
-
},
|
268
|
-
{
|
269
|
-
"key": "app.theme",
|
270
|
-
"name": "UI Theme",
|
271
|
-
"description": "User interface theme",
|
272
|
-
"category": "app_interface",
|
273
|
-
"ui_element": "select",
|
274
|
-
"options": [
|
275
|
-
{"value": "dark", "label": "Dark"},
|
276
|
-
{"value": "light", "label": "Light"},
|
277
|
-
{"value": "system", "label": "System Default"},
|
278
|
-
],
|
279
|
-
"value": "dark",
|
280
|
-
},
|
281
|
-
{
|
282
|
-
"key": "app.web_interface",
|
283
|
-
"name": "Web Interface",
|
284
|
-
"description": "Enable the web interface",
|
285
|
-
"category": "app_interface",
|
286
|
-
"ui_element": "checkbox",
|
287
|
-
"value": True,
|
288
|
-
},
|
289
|
-
{
|
290
|
-
"key": "app.enable_web",
|
291
|
-
"name": "Enable Web Server",
|
292
|
-
"description": "Enable the web server",
|
293
|
-
"category": "app_interface",
|
294
|
-
"ui_element": "checkbox",
|
295
|
-
"value": True,
|
296
|
-
},
|
297
|
-
]
|
298
|
-
|
299
|
-
# Update search settings with research-specific settings
|
300
|
-
search_settings.extend(
|
301
|
-
[
|
302
|
-
{
|
303
|
-
"key": "search.research_iterations",
|
304
|
-
"name": "Research Iterations",
|
305
|
-
"description": "Number of research cycles to perform",
|
306
|
-
"category": "search_parameters",
|
307
|
-
"ui_element": "number",
|
308
|
-
"min_value": 1,
|
309
|
-
"max_value": 5,
|
310
|
-
"value": 2,
|
311
|
-
},
|
312
|
-
{
|
313
|
-
"key": "search.questions_per_iteration",
|
314
|
-
"name": "Questions Per Iteration",
|
315
|
-
"description": "Number of questions to generate per research cycle",
|
316
|
-
"category": "search_parameters",
|
317
|
-
"ui_element": "number",
|
318
|
-
"min_value": 1,
|
319
|
-
"max_value": 10,
|
320
|
-
"value": 3,
|
321
|
-
},
|
322
|
-
{
|
323
|
-
"key": "search.searches_per_section",
|
324
|
-
"name": "Searches Per Section",
|
325
|
-
"description": "Number of searches to run per report section",
|
326
|
-
"category": "search_parameters",
|
327
|
-
"ui_element": "number",
|
328
|
-
"min_value": 1,
|
329
|
-
"max_value": 5,
|
330
|
-
"value": 2,
|
331
|
-
},
|
332
|
-
{
|
333
|
-
"key": "search.skip_relevance_filter",
|
334
|
-
"name": "Skip Relevance Filter",
|
335
|
-
"description": "Skip filtering search results for relevance",
|
336
|
-
"category": "search_parameters",
|
337
|
-
"ui_element": "checkbox",
|
338
|
-
"value": False,
|
339
|
-
},
|
340
|
-
{
|
341
|
-
"key": "search.safe_search",
|
342
|
-
"name": "Safe Search",
|
343
|
-
"description": "Enable safe search filtering",
|
344
|
-
"category": "search_parameters",
|
345
|
-
"ui_element": "checkbox",
|
346
|
-
"value": True,
|
347
|
-
},
|
348
|
-
{
|
349
|
-
"key": "search.search_language",
|
350
|
-
"name": "Search Language",
|
351
|
-
"description": "Language for search results",
|
352
|
-
"category": "search_parameters",
|
353
|
-
"ui_element": "select",
|
354
|
-
"options": [
|
355
|
-
{"value": "English", "label": "English"},
|
356
|
-
{"value": "French", "label": "French"},
|
357
|
-
{"value": "German", "label": "German"},
|
358
|
-
{"value": "Spanish", "label": "Spanish"},
|
359
|
-
{"value": "Italian", "label": "Italian"},
|
360
|
-
{"value": "Japanese", "label": "Japanese"},
|
361
|
-
{"value": "Chinese", "label": "Chinese"},
|
362
|
-
],
|
363
|
-
"value": "English",
|
364
|
-
},
|
365
|
-
]
|
366
|
-
)
|
367
|
-
|
368
|
-
# Ensure these predefined settings exist in the database
|
369
|
-
# This will update existing settings with the same key
|
370
|
-
all_settings = llm_settings + search_settings + report_settings + app_settings
|
371
|
-
|
372
|
-
# Add/update each setting
|
373
|
-
for setting_dict in all_settings:
|
374
|
-
try:
|
375
|
-
# Convert to correct type based on key prefix
|
376
|
-
setting_type = None
|
377
|
-
key = setting_dict.get("key", "")
|
378
|
-
|
379
|
-
if key.startswith("llm."):
|
380
|
-
setting_type = SettingType.LLM
|
381
|
-
elif key.startswith("search."):
|
382
|
-
setting_type = SettingType.SEARCH
|
383
|
-
elif key.startswith("report."):
|
384
|
-
setting_type = SettingType.REPORT
|
385
|
-
elif key.startswith("app."):
|
386
|
-
setting_type = SettingType.APP
|
387
|
-
|
388
|
-
# Skip if no valid type
|
389
|
-
if not setting_type:
|
390
|
-
logger.warning("Skipping setting %s - unknown type", key)
|
391
|
-
continue
|
392
|
-
|
393
|
-
# Check if setting exists
|
394
|
-
existing = db_session.query(Setting).filter(Setting.key == key).first()
|
395
|
-
|
396
|
-
if existing:
|
397
|
-
# Update existing setting
|
398
|
-
logger.debug("Updating existing setting: %s", key)
|
399
|
-
|
400
|
-
# Only update metadata, not the value (to preserve user settings)
|
401
|
-
existing.name = setting_dict.get("name", existing.name)
|
402
|
-
existing.description = setting_dict.get(
|
403
|
-
"description", existing.description
|
404
|
-
)
|
405
|
-
existing.category = setting_dict.get("category", existing.category)
|
406
|
-
existing.ui_element = setting_dict.get(
|
407
|
-
"ui_element", existing.ui_element
|
408
|
-
)
|
409
|
-
existing.options = setting_dict.get("options", existing.options)
|
410
|
-
existing.min_value = setting_dict.get("min_value", existing.min_value)
|
411
|
-
existing.max_value = setting_dict.get("max_value", existing.max_value)
|
412
|
-
existing.step = setting_dict.get("step", existing.step)
|
413
|
-
|
414
|
-
# Only set value if it's not already set
|
415
|
-
if existing.value is None and "value" in setting_dict:
|
416
|
-
existing.value = setting_dict["value"]
|
417
|
-
else:
|
418
|
-
# Create new setting
|
419
|
-
logger.info("Creating new setting: %s", key)
|
420
|
-
setting = Setting(
|
421
|
-
key=key,
|
422
|
-
value=setting_dict.get("value"),
|
423
|
-
type=setting_type,
|
424
|
-
name=setting_dict.get(
|
425
|
-
"name", key.split(".")[-1].replace("_", " ").title()
|
426
|
-
),
|
427
|
-
description=setting_dict.get("description", f"Setting for {key}"),
|
428
|
-
category=setting_dict.get("category"),
|
429
|
-
ui_element=setting_dict.get("ui_element", "text"),
|
430
|
-
options=setting_dict.get("options"),
|
431
|
-
min_value=setting_dict.get("min_value"),
|
432
|
-
max_value=setting_dict.get("max_value"),
|
433
|
-
step=setting_dict.get("step"),
|
434
|
-
visible=setting_dict.get("visible", True),
|
435
|
-
editable=setting_dict.get("editable", True),
|
436
|
-
)
|
437
|
-
db_session.add(setting)
|
438
|
-
|
439
|
-
# Commit after each successful setting
|
440
|
-
db_session.commit()
|
441
|
-
|
442
|
-
except Exception as e:
|
443
|
-
logger.error("Error ensuring setting %s: %s", setting_dict.get("key"), e)
|
444
|
-
db_session.rollback()
|
445
|
-
|
446
|
-
# Log completion
|
447
|
-
logger.info("Predefined settings setup complete")
|
49
|
+
import_default_settings_file(db_session)
|