local-deep-research 0.4.1__py3-none-any.whl → 0.4.3__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/__version__.py +1 -1
- local_deep_research/config/llm_config.py +1 -1
- local_deep_research/defaults/default_settings.json +1 -1
- local_deep_research/web/services/settings_manager.py +72 -19
- local_deep_research/web_search_engines/engines/search_engine_searxng.py +1 -1
- local_deep_research/web_search_engines/search_engines_config.py +3 -11
- {local_deep_research-0.4.1.dist-info → local_deep_research-0.4.3.dist-info}/METADATA +1 -1
- {local_deep_research-0.4.1.dist-info → local_deep_research-0.4.3.dist-info}/RECORD +11 -11
- {local_deep_research-0.4.1.dist-info → local_deep_research-0.4.3.dist-info}/WHEEL +0 -0
- {local_deep_research-0.4.1.dist-info → local_deep_research-0.4.3.dist-info}/entry_points.txt +0 -0
- {local_deep_research-0.4.1.dist-info → local_deep_research-0.4.3.dist-info}/licenses/LICENSE +0 -0
@@ -1 +1 @@
|
|
1
|
-
__version__ = "0.4.
|
1
|
+
__version__ = "0.4.3"
|
@@ -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
|
|
@@ -1,10 +1,10 @@
|
|
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
|
-
from sqlalchemy import func
|
7
|
+
from sqlalchemy import func, or_
|
8
8
|
from sqlalchemy.exc import SQLAlchemyError
|
9
9
|
from sqlalchemy.orm import Session
|
10
10
|
|
@@ -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,37 +132,29 @@ 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:
|
83
138
|
settings = (
|
84
139
|
self.db_session.query(Setting)
|
85
140
|
# This will find exact matches and any subkeys.
|
86
|
-
.filter(
|
141
|
+
.filter(
|
142
|
+
or_(Setting.key == key, Setting.key.startswith(f"{key}."))
|
143
|
+
).all()
|
87
144
|
)
|
88
145
|
if len(settings) == 1:
|
89
146
|
# This is a bottom-level key.
|
90
|
-
|
91
|
-
|
147
|
+
return self.__get_typed_setting_value(
|
148
|
+
settings[0], default, check_env
|
149
|
+
)
|
92
150
|
elif len(settings) > 1:
|
93
151
|
# This is a higher-level key.
|
94
152
|
settings_map = {}
|
95
153
|
for setting in settings:
|
96
154
|
output_key = setting.key.removeprefix(f"{key}.")
|
97
|
-
|
98
|
-
|
99
|
-
|
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
|
155
|
+
settings_map[output_key] = self.__get_typed_setting_value(
|
156
|
+
setting, default, check_env
|
157
|
+
)
|
106
158
|
return settings_map
|
107
159
|
except SQLAlchemyError as e:
|
108
160
|
logger.error(f"Error retrieving setting {key} from database: {e}")
|
@@ -149,6 +201,7 @@ class SettingsManager:
|
|
149
201
|
value=value,
|
150
202
|
type=setting_type,
|
151
203
|
name=key.split(".")[-1].replace("_", " ").title(),
|
204
|
+
ui_element="text",
|
152
205
|
description=f"Setting for {key}",
|
153
206
|
)
|
154
207
|
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
|
101
|
+
except KeyError:
|
102
102
|
logger.error(
|
103
103
|
"'{}' is not a valid safe search setting. Disabling safe search",
|
104
104
|
safe_search,
|
@@ -4,20 +4,12 @@ Loads search engine definitions from the user's configuration.
|
|
4
4
|
"""
|
5
5
|
|
6
6
|
import json
|
7
|
-
|
8
|
-
import logging
|
9
|
-
from typing import Any, Dict, List
|
10
|
-
|
11
|
-
from ..utilities.db_utils import get_db_setting
|
12
|
-
from .default_search_engines import get_default_elasticsearch_config
|
13
|
-
|
14
|
-
from functools import cache
|
15
7
|
from typing import Any, Dict, List
|
16
8
|
|
17
9
|
from loguru import logger
|
18
10
|
|
19
|
-
|
20
11
|
from ..utilities.db_utils import get_db_setting
|
12
|
+
from .default_search_engines import get_default_elasticsearch_config
|
21
13
|
|
22
14
|
|
23
15
|
def _extract_per_engine_config(raw_config: Dict[str, Any]) -> Dict[str, Dict[str, Any]]:
|
@@ -69,7 +61,7 @@ def search_config() -> Dict[str, Any]:
|
|
69
61
|
# Add alias for 'auto' if it exists
|
70
62
|
if "auto" in search_engines and "meta" not in search_engines:
|
71
63
|
search_engines["meta"] = search_engines["auto"]
|
72
|
-
|
64
|
+
|
73
65
|
# Add Elasticsearch search engine if not already present
|
74
66
|
if "elasticsearch" not in search_engines:
|
75
67
|
logger.info("Adding default Elasticsearch search engine configuration")
|
@@ -91,7 +83,7 @@ def search_config() -> Dict[str, Any]:
|
|
91
83
|
config["paths"] = json.loads(config["paths"])
|
92
84
|
except json.decoder.JSONDecodeError:
|
93
85
|
logger.error(
|
94
|
-
f"
|
86
|
+
f"Path for local collection '{collection}' is not a valid JSON array: "
|
95
87
|
f"{config['paths']}"
|
96
88
|
)
|
97
89
|
config["paths"] = []
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: local-deep-research
|
3
|
-
Version: 0.4.
|
3
|
+
Version: 0.4.3
|
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
|
@@ -1,9 +1,9 @@
|
|
1
|
-
local_deep_research-0.4.
|
2
|
-
local_deep_research-0.4.
|
3
|
-
local_deep_research-0.4.
|
4
|
-
local_deep_research-0.4.
|
1
|
+
local_deep_research-0.4.3.dist-info/METADATA,sha256=8xlBwQ1wxZeZkbPKoHikLxTfWk2fkRoGdkCgX4e50l8,17352
|
2
|
+
local_deep_research-0.4.3.dist-info/WHEEL,sha256=tSfRZzRHthuv7vxpI4aehrdN9scLjk-dCJkPLzkHxGg,90
|
3
|
+
local_deep_research-0.4.3.dist-info/entry_points.txt,sha256=GcXS501Rjh-P80S8db7hnrQ23mS_Jg27PwpVQVO77as,113
|
4
|
+
local_deep_research-0.4.3.dist-info/licenses/LICENSE,sha256=Qg2CaTdu6SWnSqk1_JtgBPp_Da-LdqJDhT1Vt1MUc5s,1072
|
5
5
|
local_deep_research/__init__.py,sha256=BPWOE6L1vBgBshHlyzrrp0gYo6uR3ljiNBFDRK_3aIw,911
|
6
|
-
local_deep_research/__version__.py,sha256=
|
6
|
+
local_deep_research/__version__.py,sha256=Nyg0pmk5ea9-SLCAFEIF96ByFx4-TJFtrqYPN-Zn6g4,22
|
7
7
|
local_deep_research/advanced_search_system/__init__.py,sha256=sGusMj4eFIrhXR6QbOM16UDKB6aI-iS4IFivKWpMlh0,234
|
8
8
|
local_deep_research/advanced_search_system/filters/__init__.py,sha256=2dXrV4skcVHI2Lb3BSL2Ajq0rnLeSw7kc1MbIynMxa4,190
|
9
9
|
local_deep_research/advanced_search_system/filters/base_filter.py,sha256=58Ux0ppXafL8Vy2qbWioUBMqGtK1dgtSF5A68BP8M8Y,1010
|
@@ -72,11 +72,11 @@ local_deep_research/benchmarks/runners.py,sha256=ktdEYgoVoQtToCJSKPMB7rF2fOzimFR
|
|
72
72
|
local_deep_research/benchmarks/templates.py,sha256=ooRYTbFmSQCKxHVuXAYofTDTXAQ9yDaAUtKGqRaHy2E,2276
|
73
73
|
local_deep_research/citation_handler.py,sha256=MZVd6xl7g3xrWauFBPuVIC36z8onc-zQb8xI4dQXxsU,4307
|
74
74
|
local_deep_research/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
75
|
-
local_deep_research/config/llm_config.py,sha256=
|
75
|
+
local_deep_research/config/llm_config.py,sha256=31F-nlloP_N30HYZqnJ2sCNMZXlJVB9AMwz99UctHi4,16027
|
76
76
|
local_deep_research/config/search_config.py,sha256=-m4BkHHMvzNkIuZmximmE3T5_H-JU4UZubEc_cDpWH0,2130
|
77
77
|
local_deep_research/defaults/.env.template,sha256=_eVCy4d_XwpGXy8n50CG3wH9xx2oqJCFKS7IbqgInDk,491
|
78
78
|
local_deep_research/defaults/__init__.py,sha256=C_0t0uZmtrVB4rM9NM9Wx8PJU5kFcT-qOHvws5W2iOg,1352
|
79
|
-
local_deep_research/defaults/default_settings.json,sha256=
|
79
|
+
local_deep_research/defaults/default_settings.json,sha256=UTzWrOONlvR6UELT7remAN5qLLMLYvjnQXNMd0cH87w,124256
|
80
80
|
local_deep_research/migrate_db.py,sha256=S1h6Bv0OJdRW4BaH7MIMrUXBRV_yqgH2T6LVOZKTQjI,4634
|
81
81
|
local_deep_research/report_generator.py,sha256=-G3KDEbsuU3PdxDfuo5v28DIX7RE1yJCCBU2KgRbNzI,9084
|
82
82
|
local_deep_research/search_system.py,sha256=DCBSLSUyLqPuHrgOuTlDizT_cnWRBICYKH-haMWWoDo,8412
|
@@ -108,7 +108,7 @@ local_deep_research/web/routes/research_routes.py,sha256=RkuT6VA5BlKzfeFzp3HvoEQ
|
|
108
108
|
local_deep_research/web/routes/settings_routes.py,sha256=Yt4xVt6XcGPSEFuAkcQ4zlZ2r5dIbV3VNsWIXoGeflw,58606
|
109
109
|
local_deep_research/web/services/research_service.py,sha256=kHdonXtGDTSU2_jBlCP_deqMdydhxA_p7EabsR5kBkE,38812
|
110
110
|
local_deep_research/web/services/resource_service.py,sha256=yKgOC6GEOmHqRoGzwf52e19UaGCCS1DbDbOIXgWGvGc,4378
|
111
|
-
local_deep_research/web/services/settings_manager.py,sha256=
|
111
|
+
local_deep_research/web/services/settings_manager.py,sha256=FKW8LKVsBGr_vgWHn1lZZRwiqRQ98ZrNicLOwf6vjPw,19058
|
112
112
|
local_deep_research/web/services/settings_service.py,sha256=-ZG78JR14GuhsaXIF4OQOqfRfrw2QIqYEKwTOFhsuFo,3497
|
113
113
|
local_deep_research/web/services/socket_service.py,sha256=jZGXk6kesBOf4bAdLiT3V4Ofod12pGKTsvxr3ml8ydY,7272
|
114
114
|
local_deep_research/web/static/css/custom_dropdown.css,sha256=-pCx6oazWVgwqFAGq_eZ8OrTKMVQlgkKYCM6w-bACLs,7949
|
@@ -166,12 +166,12 @@ local_deep_research/web_search_engines/engines/search_engine_guardian.py,sha256=
|
|
166
166
|
local_deep_research/web_search_engines/engines/search_engine_local.py,sha256=RJEXb6wTPgTfQoOyuLYLZwqx0JU7yukehHiu4C0Zel4,41221
|
167
167
|
local_deep_research/web_search_engines/engines/search_engine_local_all.py,sha256=8hAYhacU15Vi13pjo0LRVt2tI5SqcONDwYwvdtg1HyY,5620
|
168
168
|
local_deep_research/web_search_engines/engines/search_engine_pubmed.py,sha256=O99qfbSz7RHqinAP_C0iod-ZaEGE5tyBbh1DJi2-VhQ,38495
|
169
|
-
local_deep_research/web_search_engines/engines/search_engine_searxng.py,sha256=
|
169
|
+
local_deep_research/web_search_engines/engines/search_engine_searxng.py,sha256=gS-GjjLzjZvlaQB-E0u-IADzJmLRGZaLmNQ7DpdqMw4,17865
|
170
170
|
local_deep_research/web_search_engines/engines/search_engine_semantic_scholar.py,sha256=jYs_TRM0izMfldsZ8NkCQsP-o6vCPXUjyxt0nIsxOVI,22799
|
171
171
|
local_deep_research/web_search_engines/engines/search_engine_serpapi.py,sha256=_afKJVFV0xpdrO3vL71aORMIGmbe0y8o7Ly0_xXryDQ,8920
|
172
172
|
local_deep_research/web_search_engines/engines/search_engine_wayback.py,sha256=rfRs7WJxa-H1DXSyduFHBMfpFwWEVRXLd8s_78iU8gU,17894
|
173
173
|
local_deep_research/web_search_engines/engines/search_engine_wikipedia.py,sha256=UxYBSGD-XZGQantq_AdgtBA8FCKV0C6mEr6GS_vleQQ,10092
|
174
174
|
local_deep_research/web_search_engines/search_engine_base.py,sha256=TFmkIGgzIkXFsk9jhGn2PYyxveOWzKQLrhpZy5qaggE,10803
|
175
175
|
local_deep_research/web_search_engines/search_engine_factory.py,sha256=73lwSenv7tK7eGIBOPh13hPdn0oZ9FC0EMjZx5YRPg4,11865
|
176
|
-
local_deep_research/web_search_engines/search_engines_config.py,sha256=
|
177
|
-
local_deep_research-0.4.
|
176
|
+
local_deep_research/web_search_engines/search_engines_config.py,sha256=qfmrTZjjVeMfdZQ9WIAEWKdPPEtZhTAJ5KjCdgsz_ww,5259
|
177
|
+
local_deep_research-0.4.3.dist-info/RECORD,,
|
File without changes
|
{local_deep_research-0.4.1.dist-info → local_deep_research-0.4.3.dist-info}/entry_points.txt
RENAMED
File without changes
|
{local_deep_research-0.4.1.dist-info → local_deep_research-0.4.3.dist-info}/licenses/LICENSE
RENAMED
File without changes
|