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,76 +3,135 @@ Configuration file for search engines.
|
|
3
3
|
Loads search engine definitions from the user's configuration.
|
4
4
|
"""
|
5
5
|
|
6
|
+
import json
|
6
7
|
import logging
|
7
|
-
import
|
8
|
+
from functools import cache
|
9
|
+
from typing import Any, Dict, List
|
8
10
|
|
9
|
-
import
|
10
|
-
|
11
|
-
from ..config.config_files import CONFIG_DIR, LOCAL_COLLECTIONS_FILE
|
11
|
+
from ..utilities.db_utils import get_db_setting
|
12
12
|
|
13
13
|
logger = logging.getLogger(__name__)
|
14
14
|
|
15
|
-
# Get search engines configuration directly from TOML file
|
16
|
-
SEARCH_ENGINES = {}
|
17
|
-
DEFAULT_SEARCH_ENGINE = "wikipedia" # Default fallback if not specified in config
|
18
15
|
|
19
|
-
|
20
|
-
|
16
|
+
def _extract_per_engine_config(raw_config: Dict[str, Any]) -> Dict[str, Dict[str, Any]]:
|
17
|
+
"""
|
18
|
+
Converts the "flat" configuration loaded from the settings database into
|
19
|
+
individual settings dictionaries for each engine.
|
20
|
+
|
21
|
+
Args:
|
22
|
+
raw_config: The raw "flat" configuration.
|
23
|
+
|
24
|
+
Returns:
|
25
|
+
Configuration dictionaries indexed by engine name.
|
26
|
+
|
27
|
+
"""
|
28
|
+
engine_config = {}
|
29
|
+
for key, value in raw_config.items():
|
30
|
+
engine_name = key.split(".")[0]
|
31
|
+
setting_name = ".".join(key.split(".")[1:])
|
32
|
+
engine_config.setdefault(engine_name, {})[setting_name] = value
|
33
|
+
|
34
|
+
return engine_config
|
35
|
+
|
36
|
+
|
37
|
+
@cache
|
38
|
+
def search_config() -> Dict[str, Any]:
|
39
|
+
"""
|
40
|
+
Returns:
|
41
|
+
The search engine configuration loaded from the database.
|
42
|
+
|
43
|
+
"""
|
44
|
+
# Extract search engine definitions
|
45
|
+
config_data = get_db_setting("search.engine.web", {})
|
46
|
+
search_engines = _extract_per_engine_config(config_data)
|
47
|
+
search_engines["auto"] = get_db_setting("search.engine.auto", {})
|
48
|
+
|
49
|
+
logger.info(f"Loaded {len(search_engines)} search engines from configuration file")
|
50
|
+
logger.info(f"\n {', '.join(sorted(search_engines.keys()))} \n")
|
51
|
+
|
52
|
+
# Add alias for 'auto' if it exists
|
53
|
+
if "auto" in search_engines and "meta" not in search_engines:
|
54
|
+
search_engines["meta"] = search_engines["auto"]
|
55
|
+
|
56
|
+
# Register local document collections
|
57
|
+
local_collections_data = get_db_setting("search.engine.local", {})
|
58
|
+
local_collections_data = _extract_per_engine_config(local_collections_data)
|
59
|
+
|
60
|
+
for collection, config in local_collections_data.items():
|
61
|
+
if not config.get("enabled", True):
|
62
|
+
# Search engine is not enabled. Ignore.
|
63
|
+
logger.info(f"Ignoring disabled local collection '{collection}'.")
|
64
|
+
continue
|
65
|
+
|
66
|
+
if "paths" in config and isinstance(config["paths"], str):
|
67
|
+
# This will be saved as a json array.
|
68
|
+
try:
|
69
|
+
config["paths"] = json.loads(config["paths"])
|
70
|
+
except json.decoder.JSONDecodeError:
|
71
|
+
logger.error(
|
72
|
+
f"Invalid paths specified for local collection: "
|
73
|
+
f"{config['paths']}"
|
74
|
+
)
|
75
|
+
config["paths"] = []
|
76
|
+
|
77
|
+
# Create a new dictionary with required search engine fields
|
78
|
+
engine_config = {
|
79
|
+
"default_params": config,
|
80
|
+
"requires_llm": True,
|
81
|
+
}
|
82
|
+
engine_config_prefix = f"search.engine.local.{collection}"
|
83
|
+
engine_config["module_path"] = get_db_setting(
|
84
|
+
f"{engine_config_prefix}.module_path",
|
85
|
+
"local_deep_research.web_search_engines.engines.search_engine_local",
|
86
|
+
)
|
87
|
+
engine_config["class_name"] = get_db_setting(
|
88
|
+
f"{engine_config_prefix}.class_name",
|
89
|
+
"LocalSearchEngine",
|
90
|
+
)
|
21
91
|
|
22
|
-
#
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
config_data = toml.load(SEARCH_ENGINES_FILE)
|
92
|
+
# Copy these specific fields to the top level if they exist
|
93
|
+
for field in ["strengths", "weaknesses", "reliability", "description"]:
|
94
|
+
if field in config:
|
95
|
+
engine_config[field] = config[field]
|
27
96
|
|
28
|
-
|
29
|
-
for key, value in config_data.items():
|
30
|
-
if key == "DEFAULT_SEARCH_ENGINE":
|
31
|
-
DEFAULT_SEARCH_ENGINE = value
|
32
|
-
elif isinstance(value, dict):
|
33
|
-
SEARCH_ENGINES[key] = value
|
97
|
+
search_engines[collection] = engine_config
|
34
98
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
logger.error(f"Error loading local collections from TOML file: {e}")
|
75
|
-
# Ensure the meta search engine is still available at the end if it exists
|
76
|
-
if "auto" in SEARCH_ENGINES:
|
77
|
-
meta_config = SEARCH_ENGINES["auto"]
|
78
|
-
SEARCH_ENGINES["auto"] = meta_config
|
99
|
+
logger.info("Registered local document collections as search engines")
|
100
|
+
# Ensure the meta search engine is still available at the end if it exists
|
101
|
+
if "auto" in search_engines:
|
102
|
+
meta_config = search_engines["auto"]
|
103
|
+
search_engines["auto"] = meta_config
|
104
|
+
|
105
|
+
return search_engines
|
106
|
+
|
107
|
+
|
108
|
+
@cache
|
109
|
+
def default_search_engine() -> str:
|
110
|
+
"""
|
111
|
+
Returns:
|
112
|
+
The configured default search engine.
|
113
|
+
|
114
|
+
"""
|
115
|
+
return get_db_setting("search.engine.DEFAULT_SEARCH_ENGINE", "wikipedia")
|
116
|
+
|
117
|
+
|
118
|
+
@cache
|
119
|
+
def local_search_engines() -> List[str]:
|
120
|
+
"""
|
121
|
+
Returns:
|
122
|
+
A list of the enabled local search engines.
|
123
|
+
|
124
|
+
"""
|
125
|
+
local_collections_data = get_db_setting("search.engine.local", {})
|
126
|
+
local_collections_data = _extract_per_engine_config(local_collections_data)
|
127
|
+
|
128
|
+
# Don't include the `local_all` collection.
|
129
|
+
local_collections_data.pop("local_all", None)
|
130
|
+
# Remove disabled collections.
|
131
|
+
local_collections_data = {
|
132
|
+
k: v for k, v in local_collections_data.items() if v.get("enabled", True)
|
133
|
+
}
|
134
|
+
|
135
|
+
enabled_collections = list(local_collections_data.keys())
|
136
|
+
logger.debug(f"Using local collections: {enabled_collections}")
|
137
|
+
return enabled_collections
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: local-deep-research
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.3.1
|
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
|
@@ -122,6 +122,21 @@ A powerful AI-powered research assistant that performs deep, iterative analysis
|
|
122
122
|
|
123
123
|
**Important for non-academic searches:** For normal web searches you will need SearXNG or an API key to a search provider like brave search or SerpAPI. The free searches are mostly academic search engines and will not help you for most normal searches.
|
124
124
|
|
125
|
+
## Quick SearXNG Setup (Recommended)
|
126
|
+
|
127
|
+
```bash
|
128
|
+
# Pull the SearXNG Docker image
|
129
|
+
docker pull searxng/searxng
|
130
|
+
|
131
|
+
# Run SearXNG (will be available at http://localhost:8080)
|
132
|
+
docker run -d -p 8080:8080 --name searxng searxng/searxng
|
133
|
+
|
134
|
+
# Start SearXNG (Required after system restart)
|
135
|
+
docker start searxng
|
136
|
+
```
|
137
|
+
|
138
|
+
Once these commands are executed, SearXNG will be automatically activated and ready to use. The tool will automatically detect and use your local SearXNG instance for searches.
|
139
|
+
|
125
140
|
## Windows Installation
|
126
141
|
|
127
142
|
Download the [Windows Installer](https://github.com/LearningCircuit/local-deep-research/releases/download/v0.1.0/LocalDeepResearch_Setup.exe) for easy one-click installation.
|
@@ -1,13 +1,14 @@
|
|
1
|
-
local_deep_research-0.
|
2
|
-
local_deep_research-0.
|
3
|
-
local_deep_research-0.
|
4
|
-
local_deep_research-0.
|
5
|
-
local_deep_research/__init__.py,sha256=
|
1
|
+
local_deep_research-0.3.1.dist-info/METADATA,sha256=hm0xOekqqqLIN0jglNZfEIsEZXrlg29PaAPgav3jFd4,20274
|
2
|
+
local_deep_research-0.3.1.dist-info/WHEEL,sha256=tSfRZzRHthuv7vxpI4aehrdN9scLjk-dCJkPLzkHxGg,90
|
3
|
+
local_deep_research-0.3.1.dist-info/entry_points.txt,sha256=GcXS501Rjh-P80S8db7hnrQ23mS_Jg27PwpVQVO77as,113
|
4
|
+
local_deep_research-0.3.1.dist-info/licenses/LICENSE,sha256=Qg2CaTdu6SWnSqk1_JtgBPp_Da-LdqJDhT1Vt1MUc5s,1072
|
5
|
+
local_deep_research/__init__.py,sha256=9wV3oonZMEHsE_JhyZU9P0hW2Uwv47zotGlbAB_gQiA,885
|
6
6
|
local_deep_research/__main__.py,sha256=LIxK5iS6aLAKMFBDpUS3V-jDcxchqi3eSUsI2jAZUXk,371
|
7
|
+
local_deep_research/__version__.py,sha256=r4xAFihOf72W9TD-lpMi6ntWSTKTP2SlzKP1ytkjRbI,22
|
7
8
|
local_deep_research/advanced_search_system/__init__.py,sha256=sGusMj4eFIrhXR6QbOM16UDKB6aI-iS4IFivKWpMlh0,234
|
8
9
|
local_deep_research/advanced_search_system/filters/__init__.py,sha256=2dXrV4skcVHI2Lb3BSL2Ajq0rnLeSw7kc1MbIynMxa4,190
|
9
10
|
local_deep_research/advanced_search_system/filters/base_filter.py,sha256=dFNQ7U2dj4bf3voT73YhcG-w9eW-BTlc4F9kstFcETY,969
|
10
|
-
local_deep_research/advanced_search_system/filters/cross_engine_filter.py,sha256=
|
11
|
+
local_deep_research/advanced_search_system/filters/cross_engine_filter.py,sha256=R2pM5p06gXLwOvXexGcUe5h4OQpxmlft-DXC217CiOo,8004
|
11
12
|
local_deep_research/advanced_search_system/findings/base_findings.py,sha256=tTVEQZeGuTdJ1tDF8QAkiS5pWest8_lmbq3Oq5EPGeY,2052
|
12
13
|
local_deep_research/advanced_search_system/findings/repository.py,sha256=nIdF114IaSNLjnjetbXE8s8C69djik3lywOiFvFI4Lk,19804
|
13
14
|
local_deep_research/advanced_search_system/knowledge/__init__.py,sha256=9zjQkdmomZCgZZP45fqw0E8UVpBjkzkyW7RpY0f8gY8,34
|
@@ -19,48 +20,45 @@ local_deep_research/advanced_search_system/questions/decomposition_question.py,s
|
|
19
20
|
local_deep_research/advanced_search_system/questions/standard_question.py,sha256=SRT5f8pFlcI-AT88CgmQZEnU6-XKpN2cppvMxO6mWXc,4561
|
20
21
|
local_deep_research/advanced_search_system/repositories/__init__.py,sha256=cCjAR9Z3BFZaN6_OYN9zJPvwcxCxgfp9oOeMqUmLX2c,145
|
21
22
|
local_deep_research/advanced_search_system/strategies/__init__.py,sha256=upbslnB6Ns8RJ0-b1bH74-f5gZbo7evpx1dRrKEkzHA,35
|
22
|
-
local_deep_research/advanced_search_system/strategies/base_strategy.py,sha256=
|
23
|
-
local_deep_research/advanced_search_system/strategies/iterdrag_strategy.py,sha256=
|
24
|
-
local_deep_research/advanced_search_system/strategies/parallel_search_strategy.py,sha256=
|
25
|
-
local_deep_research/advanced_search_system/strategies/rapid_search_strategy.py,sha256=
|
26
|
-
local_deep_research/advanced_search_system/strategies/source_based_strategy.py,sha256=
|
27
|
-
local_deep_research/advanced_search_system/strategies/standard_strategy.py,sha256=
|
23
|
+
local_deep_research/advanced_search_system/strategies/base_strategy.py,sha256=NVowhf36DLeES302v0U6cWDCmQvNuV0cVj4glSculfQ,3975
|
24
|
+
local_deep_research/advanced_search_system/strategies/iterdrag_strategy.py,sha256=dKTgwXaXFxBqzUw_S434LdEvV4HL2CrR9K9KBaMYxOg,18473
|
25
|
+
local_deep_research/advanced_search_system/strategies/parallel_search_strategy.py,sha256=iOWxbfKQZAt-Ua8NDqKaMZugete0YMCk9wfQfKkQHVE,19385
|
26
|
+
local_deep_research/advanced_search_system/strategies/rapid_search_strategy.py,sha256=giuBMkkxUkdI4J9711bjM3ReMLTFfyt6irT4v-3ef_Q,10426
|
27
|
+
local_deep_research/advanced_search_system/strategies/source_based_strategy.py,sha256=QmdwUV56ZGCHMLti91hEFQ6As9Yp0C_rvC6aJsnfI0U,17288
|
28
|
+
local_deep_research/advanced_search_system/strategies/standard_strategy.py,sha256=Yqe5N3bUCDXjeSlP8__AORPYyHVY5sEb82zvpTU34r8,12774
|
28
29
|
local_deep_research/advanced_search_system/tools/__init__.py,sha256=73jLuCKigwc9lJQ0uD3_F16dgCg4pL-F2cwC6tk9-oc,30
|
29
30
|
local_deep_research/advanced_search_system/tools/base_tool.py,sha256=jEs4eroCvo0dHP_uF-5kLiQP7OfkD1YzNAD650a8Ktk,2865
|
30
31
|
local_deep_research/advanced_search_system/tools/knowledge_tools/__init__.py,sha256=73jLuCKigwc9lJQ0uD3_F16dgCg4pL-F2cwC6tk9-oc,30
|
31
32
|
local_deep_research/advanced_search_system/tools/question_tools/__init__.py,sha256=73jLuCKigwc9lJQ0uD3_F16dgCg4pL-F2cwC6tk9-oc,30
|
32
33
|
local_deep_research/advanced_search_system/tools/search_tools/__init__.py,sha256=73jLuCKigwc9lJQ0uD3_F16dgCg4pL-F2cwC6tk9-oc,30
|
33
34
|
local_deep_research/api/__init__.py,sha256=-tJQp7Qm1aPg6fgfuw-w9dfNo8GzrJLOy2i3dG8Drl8,441
|
34
|
-
local_deep_research/api/research_functions.py,sha256=
|
35
|
+
local_deep_research/api/research_functions.py,sha256=SItLEuib94AXrhMsgmYDtykGrVmBPDKYHzzeDPhH688,9563
|
35
36
|
local_deep_research/app.py,sha256=U_92UX0dpVAQoaXciVNy_By_AyDEWGlXSeTwFpohALQ,155
|
36
|
-
local_deep_research/citation_handler.py,sha256=
|
37
|
+
local_deep_research/citation_handler.py,sha256=MZVd6xl7g3xrWauFBPuVIC36z8onc-zQb8xI4dQXxsU,4307
|
37
38
|
local_deep_research/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
38
|
-
local_deep_research/config/
|
39
|
-
local_deep_research/config/
|
40
|
-
local_deep_research/config/search_config.py,sha256=-qacGuPOuOgPzSS0j2Nt7dBBah2cx4syIlm5KMrGzRo,2503
|
39
|
+
local_deep_research/config/llm_config.py,sha256=Ot61pHJVAjgX9l3SmaoyxcaQg1pd2dmK24XYL8JyTs8,14743
|
40
|
+
local_deep_research/config/search_config.py,sha256=ruryPSS4Wy9-xi_02c-98KLKaELeLnZ10pnCpc0-ogg,2171
|
41
41
|
local_deep_research/defaults/.env.template,sha256=_eVCy4d_XwpGXy8n50CG3wH9xx2oqJCFKS7IbqgInDk,491
|
42
42
|
local_deep_research/defaults/__init__.py,sha256=C_0t0uZmtrVB4rM9NM9Wx8PJU5kFcT-qOHvws5W2iOg,1352
|
43
|
-
local_deep_research/defaults/
|
44
|
-
local_deep_research/defaults/main.toml,sha256=4PfSKHXzPjesdh7IzLprJ_oaCxqum9PvuKEaxr_-iJI,1940
|
45
|
-
local_deep_research/defaults/search_engines.toml,sha256=XBnqCxzFvXa1HoKLcb_Jg4EGXMlgYOw1sm_CicSdYDM,8285
|
43
|
+
local_deep_research/defaults/default_settings.json,sha256=J9vhJHu2lMYMJnw68kO4e0So3SrMrHUwbjPW7i4LAPc,119769
|
46
44
|
local_deep_research/main.py,sha256=umGmaQmW7bpx27wUAgSNjNr4oSHV6mDX5hoyfb22HEY,7033
|
47
45
|
local_deep_research/migrate_db.py,sha256=S1h6Bv0OJdRW4BaH7MIMrUXBRV_yqgH2T6LVOZKTQjI,4634
|
48
46
|
local_deep_research/report_generator.py,sha256=-G3KDEbsuU3PdxDfuo5v28DIX7RE1yJCCBU2KgRbNzI,9084
|
49
|
-
local_deep_research/search_system.py,sha256=
|
47
|
+
local_deep_research/search_system.py,sha256=hzJRsT5iX_D65Su4Q8v6Dd9ElH-oG0E7RhqulgEqXSY,7567
|
50
48
|
local_deep_research/setup_data_dir.py,sha256=7MJa2MMdDUnktJVHwMpyNL2079-qylpIyyLpVbF5AUY,1134
|
51
49
|
local_deep_research/test_migration.py,sha256=cXY9WbpxLslNEa1vFwLMvcvKBbUe7Wosm--AqmPIPYM,6459
|
52
50
|
local_deep_research/utilities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
53
|
-
local_deep_research/utilities/db_utils.py,sha256=
|
51
|
+
local_deep_research/utilities/db_utils.py,sha256=27RTIWrzyNC0oDmJAOc6raTmmgrc8jqJLxH7jQbCt0g,1830
|
54
52
|
local_deep_research/utilities/enums.py,sha256=yFwmodt93uETdQd7qyW4vOUhiAzZF-BHBbVYHKN7scU,223
|
55
53
|
local_deep_research/utilities/llm_utils.py,sha256=1O8faskPSnyave15cxOVXQcdcFrDybQA445m0OjnD9g,4877
|
56
|
-
local_deep_research/utilities/search_utilities.py,sha256=
|
54
|
+
local_deep_research/utilities/search_utilities.py,sha256=k4Eag-XJOZl4cRd4GO1z2WpvVPLLhZ-HuBD7RswhaQM,9604
|
57
55
|
local_deep_research/utilities/setup_utils.py,sha256=0Us6doQ6xQtKzgtnN1C4L7sSgxzFKJ35FpmZdj1tCDM,213
|
58
56
|
local_deep_research/web/__init__.py,sha256=CynnuRxCf9mB0AHeylhF5yVZwdj0H6bxVrZtniw3xmE,44
|
59
|
-
local_deep_research/web/app.py,sha256=
|
60
|
-
local_deep_research/web/app_factory.py,sha256=
|
57
|
+
local_deep_research/web/app.py,sha256=tl3PAf41NBYYGq0oeIKAZw_hVSB8JmjyF8jzvYPeAU0,3414
|
58
|
+
local_deep_research/web/app_factory.py,sha256=rk5QCwpxrub6ptKsvjSDTNtq8d2RWbKo2LZLvL__fPo,8107
|
61
59
|
local_deep_research/web/database/README.md,sha256=eEDLqLIfOBRvc0TFh3J1HrtFbZceYmVgpjS3-oyZ5nI,2861
|
62
60
|
local_deep_research/web/database/migrate_to_ldr_db.py,sha256=-ltKuhgosPhybDsJ13BuvvHEDJTN4Jx6SiO6XvW0SKA,9823
|
63
|
-
local_deep_research/web/database/migrations.py,sha256=
|
61
|
+
local_deep_research/web/database/migrations.py,sha256=ylfHrPGs0xWwUAAratsXGJ2aoS_C0ysHd92EwniLz44,1618
|
64
62
|
local_deep_research/web/database/models.py,sha256=MIxYWIQIovkrR65rFMxlDXn2iZXf5SIePIE_-vSmLXg,3489
|
65
63
|
local_deep_research/web/database/schema_upgrade.py,sha256=u3tx_tlsuzJw-NhvhKvQG6dqzwUckQkic0D3taZAt-k,2924
|
66
64
|
local_deep_research/web/models/database.py,sha256=NV4h0RU0ta408SkI_ZmquCplMTNH1Q4zxYJ4SHwmiGY,9489
|
@@ -68,11 +66,11 @@ local_deep_research/web/models/settings.py,sha256=rXBI9vY5k3ndR8dPd3fZJy-6HwYltQ
|
|
68
66
|
local_deep_research/web/routes/api_routes.py,sha256=S0UdCmfm0v1GEM4UiSbI0PE3xUOxiGaYFR2ZOE0256U,19075
|
69
67
|
local_deep_research/web/routes/history_routes.py,sha256=6a_8nX349viuvi1zP5S7BaPPpAh133eTi1NVWO545A8,12622
|
70
68
|
local_deep_research/web/routes/research_routes.py,sha256=JlzaP1z-7XAP3E0nkEjLIfYj_NKf5qDcrjxBmUouAhM,23492
|
71
|
-
local_deep_research/web/routes/settings_routes.py,sha256=
|
72
|
-
local_deep_research/web/services/research_service.py,sha256=
|
69
|
+
local_deep_research/web/routes/settings_routes.py,sha256=r9RbCCD37rqPsQPFyzlku6OElzQP-nuLbL4AH6e6Fgo,49233
|
70
|
+
local_deep_research/web/services/research_service.py,sha256=vs_pWuv56rG2atgSamlDK4MdxpWTxbBVf3rHztr6y2A,39488
|
73
71
|
local_deep_research/web/services/resource_service.py,sha256=yKgOC6GEOmHqRoGzwf52e19UaGCCS1DbDbOIXgWGvGc,4378
|
74
|
-
local_deep_research/web/services/settings_manager.py,sha256=
|
75
|
-
local_deep_research/web/services/settings_service.py,sha256=
|
72
|
+
local_deep_research/web/services/settings_manager.py,sha256=lHc0Arh9RR4D_Dubj6OxtlZw7MvHtdY8Db9p5LnX_ac,16376
|
73
|
+
local_deep_research/web/services/settings_service.py,sha256=SgmjhMvGZjJE63hKKaqY7kPGphnUyXcQG8NFN5rTizs,3550
|
76
74
|
local_deep_research/web/services/socket_service.py,sha256=jZGXk6kesBOf4bAdLiT3V4Ofod12pGKTsvxr3ml8ydY,7272
|
77
75
|
local_deep_research/web/static/css/custom_dropdown.css,sha256=-pCx6oazWVgwqFAGq_eZ8OrTKMVQlgkKYCM6w-bACLs,7949
|
78
76
|
local_deep_research/web/static/css/settings.css,sha256=QZbjLz8zNQZvM_ROzQOH67ZHZHEQ8WohkIPJlsekqfk,24719
|
@@ -84,11 +82,12 @@ local_deep_research/web/static/js/components/fallback/ui.js,sha256=b2mbTrUGMdH6p
|
|
84
82
|
local_deep_research/web/static/js/components/history.js,sha256=Tqn6tdFcj5QMZd_eW8YTIHPVQMEMFUQJlRaFv0waQFA,16100
|
85
83
|
local_deep_research/web/static/js/components/logpanel.js,sha256=bRYkOf-BRTAHrHx9cnF8wYMWVoCbyA7XevcJzTujQjg,42115
|
86
84
|
local_deep_research/web/static/js/components/progress.js,sha256=aTvtyZDQMkjyhqy62icuZuJ7Khyujgust6fpQFcRABk,41570
|
87
|
-
local_deep_research/web/static/js/components/research.js,sha256=
|
85
|
+
local_deep_research/web/static/js/components/research.js,sha256=LQmZNqRrxkqa61pGaXHLiHGh7SNiq5XNMqfGMKCRDzM,81074
|
88
86
|
local_deep_research/web/static/js/components/results.js,sha256=7fL18Yn0DwAjuelXvz-UlbDiLCFk-_UEEeqEjaDEVBA,32314
|
89
|
-
local_deep_research/web/static/js/components/settings.js,sha256=
|
87
|
+
local_deep_research/web/static/js/components/settings.js,sha256=0i8bwvgVrgyAeRus29txodBY5MeAVSpZ0byL5h_VRgY,168278
|
90
88
|
local_deep_research/web/static/js/components/settings_sync.js,sha256=LWDZ2EE8ChCxI5TPmPm9F4rOiYIEzEJxSCE1GLXk-2w,3925
|
91
89
|
local_deep_research/web/static/js/main.js,sha256=NHOcEVytPCvF5tz3yPWg8Qu5ghVs5-GWKmpaKB87oi4,8440
|
90
|
+
local_deep_research/web/static/js/research_form.js,sha256=qOZK0z_BE_xx2a1sx5vTjsCTW-ggHES_uj5eunO9Bo8,3632
|
92
91
|
local_deep_research/web/static/js/services/api.js,sha256=AP24hrw6VBrEjQxIMnxrZuGFmrdm9MReSjjZ-AIKqr0,6776
|
93
92
|
local_deep_research/web/static/js/services/audio.js,sha256=-Sdjuq8U-isBEK4aLc-QMDedfGtEvsQc7FBJTEoAueM,857
|
94
93
|
local_deep_research/web/static/js/services/formatting.js,sha256=wBAVHls_TTzGLreqi7lHcm0dXPm7F0Itttpn8NEtzfg,3345
|
@@ -107,7 +106,7 @@ local_deep_research/web/templates/components/sidebar.html,sha256=FLjlpwlXPoNd-Nc
|
|
107
106
|
local_deep_research/web/templates/pages/details.html,sha256=OYvSNfi8uFD1wNeHxWza1-xWMrT9c4V7U0ZEZnISlCU,2768
|
108
107
|
local_deep_research/web/templates/pages/history.html,sha256=ZS3QufL2beUVB9P_LvqIixvYfCT-EjtokQa9LRp5sUs,1982
|
109
108
|
local_deep_research/web/templates/pages/progress.html,sha256=tq9XRRZBm2KnnBxPlAa7cWWDAP-pqJeHGgtlul7UVSs,2550
|
110
|
-
local_deep_research/web/templates/pages/research.html,sha256=
|
109
|
+
local_deep_research/web/templates/pages/research.html,sha256=b1NnqsrGvSJdt3FMHlEr3C7zbgCwVdBgoV8qOE0LNU0,7052
|
111
110
|
local_deep_research/web/templates/pages/results.html,sha256=XKZVWo1CfbyjxMOntFO7IiF0_xX5r-JaJf7HDUSZTEY,2721
|
112
111
|
local_deep_research/web/templates/settings_dashboard.html,sha256=A1fBe1D29v8G3ys94_rIiBP6Ky-rtYL6TRbDluoBMPI,4342
|
113
112
|
local_deep_research/web/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -115,15 +114,15 @@ local_deep_research/web/utils/formatters.py,sha256=Gj_a0oFveNXHtvkiFe1rwlEtzYerM
|
|
115
114
|
local_deep_research/web_search_engines/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
116
115
|
local_deep_research/web_search_engines/engines/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
117
116
|
local_deep_research/web_search_engines/engines/full_search.py,sha256=6Pi_wj9oAtDHAyLsIbWGBeS8QBv6yCJEJ87LN68Cp-k,4703
|
118
|
-
local_deep_research/web_search_engines/engines/meta_search_engine.py,sha256=
|
117
|
+
local_deep_research/web_search_engines/engines/meta_search_engine.py,sha256=qUFl8yw5l7sfH-BRpXXrNQ2KrQ9LsaslhG1glb2AOIM,14715
|
119
118
|
local_deep_research/web_search_engines/engines/search_engine_arxiv.py,sha256=3k8R4pyqIZf0RDMqXDw08xIGsfkp4ZR9kePDbmeuaH0,16603
|
120
119
|
local_deep_research/web_search_engines/engines/search_engine_brave.py,sha256=y1j4CSLM0Ujw1LSBiWg1ZBnc2BvrkhDCorrQLnUBVtM,9149
|
121
120
|
local_deep_research/web_search_engines/engines/search_engine_ddg.py,sha256=w9vRDpt_L0h5J-PWiNO_3J5uuRsfk5smlcIQjRofwB4,4649
|
122
121
|
local_deep_research/web_search_engines/engines/search_engine_github.py,sha256=bojmx-R36eT_s20DGspAopkwqt6vKy4q_jH4foBt3Kk,31934
|
123
122
|
local_deep_research/web_search_engines/engines/search_engine_google_pse.py,sha256=DuFtSUZgBR7nFBLZrbFMEuG-Rnv0cb-upHeGSDo7xRY,11177
|
124
123
|
local_deep_research/web_search_engines/engines/search_engine_guardian.py,sha256=bNCppKJNNvkmw-LR5vfpRABhdhsUwOJqpcRHVjcziNU,23390
|
125
|
-
local_deep_research/web_search_engines/engines/search_engine_local.py,sha256=
|
126
|
-
local_deep_research/web_search_engines/engines/search_engine_local_all.py,sha256=
|
124
|
+
local_deep_research/web_search_engines/engines/search_engine_local.py,sha256=ephjkDrQbvil6GnceW31qSt70k11REOJ9o7y-bl69-A,40857
|
125
|
+
local_deep_research/web_search_engines/engines/search_engine_local_all.py,sha256=vznpusmCBY9bLjD8EPrVhCb_8RZ8e9Wa8x386zv0pcM,5681
|
127
126
|
local_deep_research/web_search_engines/engines/search_engine_pubmed.py,sha256=O99qfbSz7RHqinAP_C0iod-ZaEGE5tyBbh1DJi2-VhQ,38495
|
128
127
|
local_deep_research/web_search_engines/engines/search_engine_searxng.py,sha256=wPYIl22SgXjIDYzcq62glGH2JZywCnZR31he1i7U1cE,18053
|
129
128
|
local_deep_research/web_search_engines/engines/search_engine_semantic_scholar.py,sha256=jYs_TRM0izMfldsZ8NkCQsP-o6vCPXUjyxt0nIsxOVI,22799
|
@@ -131,6 +130,6 @@ local_deep_research/web_search_engines/engines/search_engine_serpapi.py,sha256=O
|
|
131
130
|
local_deep_research/web_search_engines/engines/search_engine_wayback.py,sha256=rfRs7WJxa-H1DXSyduFHBMfpFwWEVRXLd8s_78iU8gU,17894
|
132
131
|
local_deep_research/web_search_engines/engines/search_engine_wikipedia.py,sha256=UxYBSGD-XZGQantq_AdgtBA8FCKV0C6mEr6GS_vleQQ,10092
|
133
132
|
local_deep_research/web_search_engines/search_engine_base.py,sha256=PLU_sAWhWKTOQWcv32GINuhLdIwB0sEQy-pp9oG9Ggo,9835
|
134
|
-
local_deep_research/web_search_engines/search_engine_factory.py,sha256=
|
135
|
-
local_deep_research/web_search_engines/search_engines_config.py,sha256=
|
136
|
-
local_deep_research-0.
|
133
|
+
local_deep_research/web_search_engines/search_engine_factory.py,sha256=DghAkQvLKRJYl5xb9AUjUv7ydAQ4rPi-TvzrmqdyGxE,10890
|
134
|
+
local_deep_research/web_search_engines/search_engines_config.py,sha256=rgKo3UQhXov_4QxPcdzMqnAfJc5a6tGXtfnjIzKeHdQ,4584
|
135
|
+
local_deep_research-0.3.1.dist-info/RECORD,,
|
@@ -1,245 +0,0 @@
|
|
1
|
-
import logging
|
2
|
-
import os
|
3
|
-
import platform
|
4
|
-
from pathlib import Path
|
5
|
-
|
6
|
-
from dotenv import load_dotenv
|
7
|
-
from dynaconf import Dynaconf
|
8
|
-
from platformdirs import user_documents_dir
|
9
|
-
|
10
|
-
# Setup logging
|
11
|
-
logger = logging.getLogger(__name__)
|
12
|
-
|
13
|
-
|
14
|
-
def get_config_dir():
|
15
|
-
|
16
|
-
if platform.system() == "Windows":
|
17
|
-
# Windows: Use Documents directory
|
18
|
-
from platformdirs import user_documents_dir
|
19
|
-
|
20
|
-
config_dir = (
|
21
|
-
Path(user_documents_dir()) / "LearningCircuit" / "local-deep-research"
|
22
|
-
)
|
23
|
-
else:
|
24
|
-
# Linux/Mac: Use standard config directory
|
25
|
-
from platformdirs import user_config_dir
|
26
|
-
|
27
|
-
config_dir = Path(user_config_dir("local_deep_research", "LearningCircuit"))
|
28
|
-
|
29
|
-
logger.info(f"Looking for config in: {config_dir}")
|
30
|
-
return config_dir
|
31
|
-
|
32
|
-
|
33
|
-
# Define config paths
|
34
|
-
CONFIG_DIR = get_config_dir() / "config"
|
35
|
-
CONFIG_DIR.mkdir(parents=True, exist_ok=True)
|
36
|
-
SETTINGS_FILE = CONFIG_DIR / "settings.toml"
|
37
|
-
SECRETS_FILE = CONFIG_DIR / ".secrets.toml"
|
38
|
-
SEARCH_ENGINES_FILE = CONFIG_DIR / "search_engines.toml"
|
39
|
-
|
40
|
-
LOCAL_COLLECTIONS_FILE = CONFIG_DIR / "local_collections.toml"
|
41
|
-
|
42
|
-
# Define data directory for database
|
43
|
-
DATA_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "data"))
|
44
|
-
os.makedirs(DATA_DIR, exist_ok=True)
|
45
|
-
DB_PATH = os.path.join(DATA_DIR, "ldr.db")
|
46
|
-
|
47
|
-
env_file = CONFIG_DIR / ".env"
|
48
|
-
|
49
|
-
if env_file.exists():
|
50
|
-
logger.info(f"Loading environment variables from: {env_file}")
|
51
|
-
load_dotenv(dotenv_path=env_file)
|
52
|
-
else:
|
53
|
-
logger.warning(
|
54
|
-
f"Warning: .env file not found at {env_file}. Trying secondary location."
|
55
|
-
)
|
56
|
-
env_file_secondary = get_config_dir() / ".env"
|
57
|
-
if env_file_secondary.exists():
|
58
|
-
get_config_dir() / "config"
|
59
|
-
logger.info(f"Loading environment variables from: {env_file_secondary}")
|
60
|
-
load_dotenv(dotenv_path=env_file_secondary)
|
61
|
-
else:
|
62
|
-
logger.warning(f"Warning: .env file also not found at {env_file_secondary}.")
|
63
|
-
|
64
|
-
|
65
|
-
# Set environment variable for Dynaconf to use
|
66
|
-
docs_base = Path(user_documents_dir()) / "local_deep_research"
|
67
|
-
os.environ["DOCS_DIR"] = str(docs_base)
|
68
|
-
|
69
|
-
|
70
|
-
def init_config_files():
|
71
|
-
"""Initialize config files if they don't exist"""
|
72
|
-
import os
|
73
|
-
import platform
|
74
|
-
import shutil
|
75
|
-
|
76
|
-
# Ensure CONFIG_DIR exists with explicit creation
|
77
|
-
os.makedirs(CONFIG_DIR, exist_ok=True)
|
78
|
-
|
79
|
-
# Get default files path with more reliable approach for Windows
|
80
|
-
if platform.system() == "Windows":
|
81
|
-
# Use a more reliable method on Windows
|
82
|
-
from pkg_resources import resource_filename
|
83
|
-
|
84
|
-
try:
|
85
|
-
defaults_dir = Path(resource_filename("local_deep_research", "defaults"))
|
86
|
-
logger.info(f"Using pkg_resources for Windows: {defaults_dir}")
|
87
|
-
|
88
|
-
# Create settings.toml if it doesn't exist (with explicit Windows paths)
|
89
|
-
settings_file = os.path.join(CONFIG_DIR, "settings.toml")
|
90
|
-
default_settings = os.path.join(defaults_dir, "main.toml")
|
91
|
-
if not os.path.exists(settings_file) and os.path.exists(default_settings):
|
92
|
-
shutil.copyfile(default_settings, settings_file)
|
93
|
-
logger.info(f"Created settings.toml at {settings_file}")
|
94
|
-
# Add note about database-first settings
|
95
|
-
with open(settings_file, "a") as f:
|
96
|
-
f.write(
|
97
|
-
"\n\n# NOTE: Settings in this file are used as fallback only.\n"
|
98
|
-
)
|
99
|
-
f.write(
|
100
|
-
"# Settings stored in the database (ldr.db) take precedence.\n"
|
101
|
-
)
|
102
|
-
f.write(
|
103
|
-
"# To modify settings permanently, use the web interface settings page.\n"
|
104
|
-
)
|
105
|
-
|
106
|
-
# Create local_collections.toml if it doesn't exist
|
107
|
-
collections_file = os.path.join(CONFIG_DIR, "local_collections.toml")
|
108
|
-
default_collections = os.path.join(defaults_dir, "local_collections.toml")
|
109
|
-
if not os.path.exists(collections_file) and os.path.exists(
|
110
|
-
default_collections
|
111
|
-
):
|
112
|
-
shutil.copyfile(default_collections, collections_file)
|
113
|
-
logger.info(f"Created local_collections.toml at {collections_file}")
|
114
|
-
|
115
|
-
# Create search_engines.toml if it doesn't exist
|
116
|
-
search_engines_file = os.path.join(CONFIG_DIR, "search_engines.toml")
|
117
|
-
default_engines = os.path.join(defaults_dir, "search_engines.toml")
|
118
|
-
if not os.path.exists(search_engines_file) and os.path.exists(
|
119
|
-
default_engines
|
120
|
-
):
|
121
|
-
shutil.copyfile(default_engines, search_engines_file)
|
122
|
-
logger.info(f"Created search_engines.toml at {search_engines_file}")
|
123
|
-
# Add note about database-first settings
|
124
|
-
with open(search_engines_file, "a") as f:
|
125
|
-
f.write(
|
126
|
-
"\n\n# NOTE: Settings in this file are used as fallback only.\n"
|
127
|
-
)
|
128
|
-
f.write(
|
129
|
-
"# Settings stored in the database (ldr.db) take precedence.\n"
|
130
|
-
)
|
131
|
-
f.write(
|
132
|
-
"# To modify search settings permanently, use the web interface settings page.\n"
|
133
|
-
)
|
134
|
-
|
135
|
-
# Create .env.template if it doesn't exist
|
136
|
-
env_template_file = CONFIG_DIR / ".env.template"
|
137
|
-
if not env_template_file.exists():
|
138
|
-
shutil.copy(defaults_dir / ".env.template", env_template_file)
|
139
|
-
logger.info(f"Created .env.template at {env_template_file}")
|
140
|
-
|
141
|
-
# Optionally create an empty .env file if it doesn't exist
|
142
|
-
env_file = CONFIG_DIR / ".env"
|
143
|
-
if not env_file.exists():
|
144
|
-
with open(env_file, "w") as f:
|
145
|
-
f.write("# Add your environment variables here\n")
|
146
|
-
logger.info(f"Created empty .env file at {env_file}")
|
147
|
-
except Exception as e:
|
148
|
-
logger.error(f"Error initializing Windows config files: {e}")
|
149
|
-
else:
|
150
|
-
"""Initialize config files if they don't exist"""
|
151
|
-
import shutil
|
152
|
-
from importlib.resources import files
|
153
|
-
|
154
|
-
# Get default files path
|
155
|
-
try:
|
156
|
-
defaults_dir = files("local_deep_research.defaults")
|
157
|
-
except ImportError:
|
158
|
-
# Fallback for older Python versions
|
159
|
-
from pkg_resources import resource_filename
|
160
|
-
|
161
|
-
defaults_dir = Path(resource_filename("local_deep_research", "defaults"))
|
162
|
-
|
163
|
-
# Create settings.toml if it doesn't exist
|
164
|
-
settings_file = CONFIG_DIR / "settings.toml"
|
165
|
-
if not settings_file.exists():
|
166
|
-
shutil.copy(defaults_dir / "main.toml", settings_file)
|
167
|
-
logger.info(f"Created settings.toml at {settings_file}")
|
168
|
-
# Add note about database-first settings
|
169
|
-
with open(settings_file, "a") as f:
|
170
|
-
f.write(
|
171
|
-
"\n\n# NOTE: Settings in this file are used as fallback only.\n"
|
172
|
-
)
|
173
|
-
f.write("# Settings stored in the database (ldr.db) take precedence.\n")
|
174
|
-
f.write(
|
175
|
-
"# To modify settings permanently, use the web interface settings page.\n"
|
176
|
-
)
|
177
|
-
|
178
|
-
# Create local_collections.toml if it doesn't exist
|
179
|
-
collections_file = CONFIG_DIR / "local_collections.toml"
|
180
|
-
if not collections_file.exists():
|
181
|
-
shutil.copy(defaults_dir / "local_collections.toml", collections_file)
|
182
|
-
logger.info(f"Created local_collections.toml at {collections_file}")
|
183
|
-
|
184
|
-
# Create search_engines.toml if it doesn't exist
|
185
|
-
search_engines_file = CONFIG_DIR / "search_engines.toml"
|
186
|
-
if not search_engines_file.exists():
|
187
|
-
shutil.copy(defaults_dir / "search_engines.toml", search_engines_file)
|
188
|
-
logger.info(f"Created search_engines.toml at {search_engines_file}")
|
189
|
-
# Add note about database-first settings
|
190
|
-
with open(search_engines_file, "a") as f:
|
191
|
-
f.write(
|
192
|
-
"\n\n# NOTE: Settings in this file are used as fallback only.\n"
|
193
|
-
)
|
194
|
-
f.write("# Settings stored in the database (ldr.db) take precedence.\n")
|
195
|
-
f.write(
|
196
|
-
"# To modify search settings permanently, use the web interface settings page.\n"
|
197
|
-
)
|
198
|
-
|
199
|
-
env_template_file = CONFIG_DIR / ".env.template"
|
200
|
-
if not env_template_file.exists():
|
201
|
-
shutil.copy(defaults_dir / ".env.template", env_template_file)
|
202
|
-
logger.info(f"Created .env.template at {env_template_file}")
|
203
|
-
|
204
|
-
# Optionally create an empty .env file if it doesn't exist
|
205
|
-
env_file = CONFIG_DIR / ".env"
|
206
|
-
if not env_file.exists():
|
207
|
-
with open(env_file, "w") as f:
|
208
|
-
f.write("# Add your environment variables here\n")
|
209
|
-
logger.info(f"Created empty .env file at {env_file}")
|
210
|
-
secrets_file = CONFIG_DIR / ".secrets.toml"
|
211
|
-
if not secrets_file.exists():
|
212
|
-
with open(secrets_file, "w") as f:
|
213
|
-
f.write(
|
214
|
-
"""
|
215
|
-
# ANTHROPIC_API_KEY = "your-api-key-here"
|
216
|
-
# OPENAI_API_KEY = "your-openai-key-here"
|
217
|
-
# GOOGLE_API_KEY = "your-google-key-here"
|
218
|
-
# SERP_API_KEY = "your-api-key-here"
|
219
|
-
# GUARDIAN_API_KEY = "your-api-key-here"
|
220
|
-
# GOOGLE_PSE_API_KEY = "your-google-api-key-here"
|
221
|
-
# GOOGLE_PSE_ENGINE_ID = "your-programmable-search-engine-id-here"
|
222
|
-
"""
|
223
|
-
)
|
224
|
-
|
225
|
-
|
226
|
-
# Add a comment to explain the DB-first settings approach
|
227
|
-
logger.info(
|
228
|
-
"Using database-first settings approach. TOML files are used as fallback only."
|
229
|
-
)
|
230
|
-
|
231
|
-
settings = Dynaconf(
|
232
|
-
settings_files=[
|
233
|
-
str(SETTINGS_FILE),
|
234
|
-
str(LOCAL_COLLECTIONS_FILE),
|
235
|
-
str(SEARCH_ENGINES_FILE),
|
236
|
-
],
|
237
|
-
secrets=str(SECRETS_FILE),
|
238
|
-
env_prefix="LDR",
|
239
|
-
load_dotenv=True,
|
240
|
-
envvar_prefix="LDR",
|
241
|
-
env_file=str(CONFIG_DIR / ".env"),
|
242
|
-
)
|
243
|
-
|
244
|
-
# Initialize config files on import
|
245
|
-
init_config_files()
|