local-deep-research 0.1.26__py3-none-any.whl → 0.2.0__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 +23 -22
- local_deep_research/__main__.py +16 -0
- local_deep_research/advanced_search_system/__init__.py +7 -0
- local_deep_research/advanced_search_system/filters/__init__.py +8 -0
- local_deep_research/advanced_search_system/filters/base_filter.py +38 -0
- local_deep_research/advanced_search_system/filters/cross_engine_filter.py +200 -0
- local_deep_research/advanced_search_system/findings/base_findings.py +81 -0
- local_deep_research/advanced_search_system/findings/repository.py +452 -0
- local_deep_research/advanced_search_system/knowledge/__init__.py +1 -0
- local_deep_research/advanced_search_system/knowledge/base_knowledge.py +151 -0
- local_deep_research/advanced_search_system/knowledge/standard_knowledge.py +159 -0
- local_deep_research/advanced_search_system/questions/__init__.py +1 -0
- local_deep_research/advanced_search_system/questions/base_question.py +64 -0
- local_deep_research/advanced_search_system/questions/decomposition_question.py +445 -0
- local_deep_research/advanced_search_system/questions/standard_question.py +119 -0
- local_deep_research/advanced_search_system/repositories/__init__.py +7 -0
- local_deep_research/advanced_search_system/strategies/__init__.py +1 -0
- local_deep_research/advanced_search_system/strategies/base_strategy.py +118 -0
- local_deep_research/advanced_search_system/strategies/iterdrag_strategy.py +450 -0
- local_deep_research/advanced_search_system/strategies/parallel_search_strategy.py +312 -0
- local_deep_research/advanced_search_system/strategies/rapid_search_strategy.py +270 -0
- local_deep_research/advanced_search_system/strategies/standard_strategy.py +300 -0
- local_deep_research/advanced_search_system/tools/__init__.py +1 -0
- local_deep_research/advanced_search_system/tools/base_tool.py +100 -0
- local_deep_research/advanced_search_system/tools/knowledge_tools/__init__.py +1 -0
- local_deep_research/advanced_search_system/tools/question_tools/__init__.py +1 -0
- local_deep_research/advanced_search_system/tools/search_tools/__init__.py +1 -0
- local_deep_research/api/__init__.py +5 -5
- local_deep_research/api/research_functions.py +96 -84
- local_deep_research/app.py +8 -0
- local_deep_research/citation_handler.py +25 -16
- local_deep_research/{config.py → config/config_files.py} +102 -110
- local_deep_research/config/llm_config.py +472 -0
- local_deep_research/config/search_config.py +77 -0
- local_deep_research/defaults/__init__.py +10 -5
- local_deep_research/defaults/main.toml +2 -2
- local_deep_research/defaults/search_engines.toml +60 -34
- local_deep_research/main.py +121 -19
- local_deep_research/migrate_db.py +147 -0
- local_deep_research/report_generator.py +72 -44
- local_deep_research/search_system.py +147 -283
- local_deep_research/setup_data_dir.py +35 -0
- local_deep_research/test_migration.py +178 -0
- local_deep_research/utilities/__init__.py +0 -0
- local_deep_research/utilities/db_utils.py +49 -0
- local_deep_research/{utilties → utilities}/enums.py +2 -2
- local_deep_research/{utilties → utilities}/llm_utils.py +63 -29
- local_deep_research/utilities/search_utilities.py +242 -0
- local_deep_research/{utilties → utilities}/setup_utils.py +4 -2
- local_deep_research/web/__init__.py +0 -1
- local_deep_research/web/app.py +86 -1709
- local_deep_research/web/app_factory.py +289 -0
- local_deep_research/web/database/README.md +70 -0
- local_deep_research/web/database/migrate_to_ldr_db.py +289 -0
- local_deep_research/web/database/migrations.py +447 -0
- local_deep_research/web/database/models.py +117 -0
- local_deep_research/web/database/schema_upgrade.py +107 -0
- local_deep_research/web/models/database.py +294 -0
- local_deep_research/web/models/settings.py +94 -0
- local_deep_research/web/routes/api_routes.py +559 -0
- local_deep_research/web/routes/history_routes.py +354 -0
- local_deep_research/web/routes/research_routes.py +715 -0
- local_deep_research/web/routes/settings_routes.py +1592 -0
- local_deep_research/web/services/research_service.py +947 -0
- local_deep_research/web/services/resource_service.py +149 -0
- local_deep_research/web/services/settings_manager.py +669 -0
- local_deep_research/web/services/settings_service.py +187 -0
- local_deep_research/web/services/socket_service.py +210 -0
- local_deep_research/web/static/css/custom_dropdown.css +277 -0
- local_deep_research/web/static/css/settings.css +1223 -0
- local_deep_research/web/static/css/styles.css +525 -48
- local_deep_research/web/static/js/components/custom_dropdown.js +428 -0
- local_deep_research/web/static/js/components/detail.js +348 -0
- local_deep_research/web/static/js/components/fallback/formatting.js +122 -0
- local_deep_research/web/static/js/components/fallback/ui.js +215 -0
- local_deep_research/web/static/js/components/history.js +487 -0
- local_deep_research/web/static/js/components/logpanel.js +949 -0
- local_deep_research/web/static/js/components/progress.js +1107 -0
- local_deep_research/web/static/js/components/research.js +1865 -0
- local_deep_research/web/static/js/components/results.js +766 -0
- local_deep_research/web/static/js/components/settings.js +3981 -0
- local_deep_research/web/static/js/components/settings_sync.js +106 -0
- local_deep_research/web/static/js/main.js +226 -0
- local_deep_research/web/static/js/services/api.js +253 -0
- local_deep_research/web/static/js/services/audio.js +31 -0
- local_deep_research/web/static/js/services/formatting.js +119 -0
- local_deep_research/web/static/js/services/pdf.js +622 -0
- local_deep_research/web/static/js/services/socket.js +882 -0
- local_deep_research/web/static/js/services/ui.js +546 -0
- local_deep_research/web/templates/base.html +72 -0
- local_deep_research/web/templates/components/custom_dropdown.html +47 -0
- local_deep_research/web/templates/components/log_panel.html +32 -0
- local_deep_research/web/templates/components/mobile_nav.html +22 -0
- local_deep_research/web/templates/components/settings_form.html +299 -0
- local_deep_research/web/templates/components/sidebar.html +21 -0
- local_deep_research/web/templates/pages/details.html +73 -0
- local_deep_research/web/templates/pages/history.html +51 -0
- local_deep_research/web/templates/pages/progress.html +57 -0
- local_deep_research/web/templates/pages/research.html +139 -0
- local_deep_research/web/templates/pages/results.html +59 -0
- local_deep_research/web/templates/settings_dashboard.html +78 -192
- local_deep_research/web/utils/__init__.py +0 -0
- local_deep_research/web/utils/formatters.py +76 -0
- local_deep_research/web_search_engines/engines/full_search.py +18 -16
- local_deep_research/web_search_engines/engines/meta_search_engine.py +182 -131
- local_deep_research/web_search_engines/engines/search_engine_arxiv.py +224 -139
- local_deep_research/web_search_engines/engines/search_engine_brave.py +88 -71
- local_deep_research/web_search_engines/engines/search_engine_ddg.py +48 -39
- local_deep_research/web_search_engines/engines/search_engine_github.py +415 -204
- local_deep_research/web_search_engines/engines/search_engine_google_pse.py +123 -90
- local_deep_research/web_search_engines/engines/search_engine_guardian.py +210 -157
- local_deep_research/web_search_engines/engines/search_engine_local.py +532 -369
- local_deep_research/web_search_engines/engines/search_engine_local_all.py +42 -36
- local_deep_research/web_search_engines/engines/search_engine_pubmed.py +358 -266
- local_deep_research/web_search_engines/engines/search_engine_searxng.py +211 -159
- local_deep_research/web_search_engines/engines/search_engine_semantic_scholar.py +213 -170
- local_deep_research/web_search_engines/engines/search_engine_serpapi.py +84 -68
- local_deep_research/web_search_engines/engines/search_engine_wayback.py +186 -154
- local_deep_research/web_search_engines/engines/search_engine_wikipedia.py +115 -77
- local_deep_research/web_search_engines/search_engine_base.py +174 -99
- local_deep_research/web_search_engines/search_engine_factory.py +192 -102
- local_deep_research/web_search_engines/search_engines_config.py +22 -15
- {local_deep_research-0.1.26.dist-info → local_deep_research-0.2.0.dist-info}/METADATA +177 -97
- local_deep_research-0.2.0.dist-info/RECORD +135 -0
- {local_deep_research-0.1.26.dist-info → local_deep_research-0.2.0.dist-info}/WHEEL +1 -2
- {local_deep_research-0.1.26.dist-info → local_deep_research-0.2.0.dist-info}/entry_points.txt +3 -0
- local_deep_research/defaults/llm_config.py +0 -338
- local_deep_research/utilties/search_utilities.py +0 -114
- local_deep_research/web/static/js/app.js +0 -3763
- local_deep_research/web/templates/api_keys_config.html +0 -82
- local_deep_research/web/templates/collections_config.html +0 -90
- local_deep_research/web/templates/index.html +0 -348
- local_deep_research/web/templates/llm_config.html +0 -120
- local_deep_research/web/templates/main_config.html +0 -89
- local_deep_research/web/templates/search_engines_config.html +0 -154
- local_deep_research/web/templates/settings.html +0 -519
- local_deep_research-0.1.26.dist-info/RECORD +0 -61
- local_deep_research-0.1.26.dist-info/top_level.txt +0 -1
- /local_deep_research/{utilties → config}/__init__.py +0 -0
- {local_deep_research-0.1.26.dist-info → local_deep_research-0.2.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,22 @@
|
|
1
|
+
<nav class="mobile-tab-bar">
|
2
|
+
<ul>
|
3
|
+
<li {% if active_page == 'new-research' %}class="active"{% endif %} data-page="new-research">
|
4
|
+
<a href="{{ url_for('research.index') }}">
|
5
|
+
<i class="fas fa-search"></i>
|
6
|
+
<span>Research</span>
|
7
|
+
</a>
|
8
|
+
</li>
|
9
|
+
<li {% if active_page == 'history' %}class="active"{% endif %} data-page="history">
|
10
|
+
<a href="{{ url_for('research.history_page') }}">
|
11
|
+
<i class="fas fa-history"></i>
|
12
|
+
<span>History</span>
|
13
|
+
</a>
|
14
|
+
</li>
|
15
|
+
<li {% if active_page == 'settings' %}class="active"{% endif %} data-page="settings">
|
16
|
+
<a href="{{ url_for('research.settings_page') }}">
|
17
|
+
<i class="fas fa-cog"></i>
|
18
|
+
<span>Settings</span>
|
19
|
+
</a>
|
20
|
+
</li>
|
21
|
+
</ul>
|
22
|
+
</nav>
|
@@ -0,0 +1,299 @@
|
|
1
|
+
{% macro render_setting(setting, id_prefix="") %}
|
2
|
+
{% set setting_id = (id_prefix ~ "-" if id_prefix else "") ~ setting.key|replace(".", "-") %}
|
3
|
+
|
4
|
+
<div class="settings-item form-group" data-key="{{ setting.key }}">
|
5
|
+
<div class="settings-item-header">
|
6
|
+
<label for="{{ setting_id }}">{{ setting.name }}</label>
|
7
|
+
{% if setting.description %}
|
8
|
+
<span class="settings-tooltip" title="{{ setting.description }}">
|
9
|
+
<i class="fas fa-info-circle"></i>
|
10
|
+
</span>
|
11
|
+
{% endif %}
|
12
|
+
</div>
|
13
|
+
|
14
|
+
{% if setting.ui_element == "textarea" %}
|
15
|
+
{# Check if this is JSON content that should be expanded into controls #}
|
16
|
+
{% if setting.value is mapping or (setting.value is string and (setting.value.startswith('{') and setting.value.endswith('}'))) %}
|
17
|
+
<div class="json-expanded-controls">
|
18
|
+
{% if setting.value is string %}
|
19
|
+
{% set json_value = setting.value|tojson %}
|
20
|
+
{% else %}
|
21
|
+
{% set json_value = setting.value %}
|
22
|
+
{% endif %}
|
23
|
+
|
24
|
+
{# Store the original JSON in a hidden field #}
|
25
|
+
<input type="hidden" id="{{ setting_id }}_original" name="{{ setting.key }}_original" value="{{ setting.value|tojson }}">
|
26
|
+
|
27
|
+
{# Create individual form controls for each JSON property #}
|
28
|
+
<div class="json-property-controls">
|
29
|
+
{% for key, value in json_value.items() %}
|
30
|
+
<div class="json-property-item">
|
31
|
+
<label for="{{ setting_id }}_{{ key }}">{{ key|replace("_", " ")|title }}</label>
|
32
|
+
|
33
|
+
{% if value is boolean %}
|
34
|
+
<div class="checkbox-label">
|
35
|
+
<input type="checkbox"
|
36
|
+
id="{{ setting_id }}_{{ key }}"
|
37
|
+
name="{{ setting.key }}_{{ key }}"
|
38
|
+
class="json-property-control"
|
39
|
+
data-property="{{ key }}"
|
40
|
+
data-parent-key="{{ setting.key }}"
|
41
|
+
{% if value %}checked{% endif %}
|
42
|
+
{% if not setting.editable %}disabled{% endif %}>
|
43
|
+
<span class="checkbox-text">{{ key|replace("_", " ")|title }}</span>
|
44
|
+
</div>
|
45
|
+
{% elif value is number %}
|
46
|
+
<input type="number"
|
47
|
+
id="{{ setting_id }}_{{ key }}"
|
48
|
+
name="{{ setting.key }}_{{ key }}"
|
49
|
+
class="settings-input form-control json-property-control"
|
50
|
+
data-property="{{ key }}"
|
51
|
+
data-parent-key="{{ setting.key }}"
|
52
|
+
value="{{ value }}"
|
53
|
+
{% if not setting.editable %}disabled{% endif %}>
|
54
|
+
{% elif value is string and value in ["ITERATION", "NONE"] %}
|
55
|
+
<select id="{{ setting_id }}_{{ key }}"
|
56
|
+
name="{{ setting.key }}_{{ key }}"
|
57
|
+
class="settings-select form-control json-property-control"
|
58
|
+
data-property="{{ key }}"
|
59
|
+
data-parent-key="{{ setting.key }}"
|
60
|
+
{% if not setting.editable %}disabled{% endif %}>
|
61
|
+
<option value="ITERATION" {% if value == "ITERATION" %}selected{% endif %}>Iteration</option>
|
62
|
+
<option value="NONE" {% if value == "NONE" %}selected{% endif %}>None</option>
|
63
|
+
</select>
|
64
|
+
{% else %}
|
65
|
+
<input type="text"
|
66
|
+
id="{{ setting_id }}_{{ key }}"
|
67
|
+
name="{{ setting.key }}_{{ key }}"
|
68
|
+
class="settings-input form-control json-property-control"
|
69
|
+
data-property="{{ key }}"
|
70
|
+
data-parent-key="{{ setting.key }}"
|
71
|
+
value="{{ value }}"
|
72
|
+
{% if not setting.editable %}disabled{% endif %}>
|
73
|
+
{% endif %}
|
74
|
+
|
75
|
+
<div class="input-help">{{ key|replace("_", " ")|title }}</div>
|
76
|
+
</div>
|
77
|
+
{% endfor %}
|
78
|
+
</div>
|
79
|
+
</div>
|
80
|
+
{% else %}
|
81
|
+
<textarea
|
82
|
+
id="{{ setting_id }}"
|
83
|
+
name="{{ setting.key }}"
|
84
|
+
class="settings-textarea form-control"
|
85
|
+
{% if not setting.editable %}disabled{% endif %}
|
86
|
+
>{{ setting.value if setting.value is not none else "" }}</textarea>
|
87
|
+
{% endif %}
|
88
|
+
|
89
|
+
{% elif setting.ui_element == "select" %}
|
90
|
+
{% if setting.key == "llm.provider" %}
|
91
|
+
{% from "components/custom_dropdown.html" import render_dropdown %}
|
92
|
+
{{ render_dropdown(
|
93
|
+
input_id=setting.key,
|
94
|
+
dropdown_id=setting_id + "-dropdown",
|
95
|
+
placeholder="Select a provider",
|
96
|
+
label=None,
|
97
|
+
help_text=setting.description if setting.description else None,
|
98
|
+
allow_custom=False,
|
99
|
+
show_refresh=True,
|
100
|
+
data_setting_key=setting.key
|
101
|
+
) }}
|
102
|
+
{% else %}
|
103
|
+
<select
|
104
|
+
id="{{ setting_id }}"
|
105
|
+
name="{{ setting.key }}"
|
106
|
+
class="settings-select form-control"
|
107
|
+
{% if not setting.editable %}disabled{% endif %}
|
108
|
+
>
|
109
|
+
{% for option in setting.options %}
|
110
|
+
<option
|
111
|
+
value="{{ option.value }}"
|
112
|
+
{% if option.value == setting.value %}selected{% endif %}
|
113
|
+
>
|
114
|
+
{{ option.label if option.label else option.value }}
|
115
|
+
</option>
|
116
|
+
{% endfor %}
|
117
|
+
</select>
|
118
|
+
{% endif %}
|
119
|
+
|
120
|
+
{% elif setting.ui_element == "checkbox" %}
|
121
|
+
<div class="checkbox-label">
|
122
|
+
<input
|
123
|
+
type="checkbox"
|
124
|
+
id="{{ setting_id }}"
|
125
|
+
name="{{ setting.key }}"
|
126
|
+
{% if setting.value == true or setting.value == "true" %}checked{% endif %}
|
127
|
+
{% if not setting.editable %}disabled{% endif %}
|
128
|
+
>
|
129
|
+
<span class="checkbox-text">{{ setting.name }}</span>
|
130
|
+
</div>
|
131
|
+
|
132
|
+
{% elif setting.ui_element == "slider" or setting.ui_element == "range" %}
|
133
|
+
{% set min_value = setting.min_value if setting.min_value is not none else 0 %}
|
134
|
+
{% set max_value = setting.max_value if setting.max_value is not none else 100 %}
|
135
|
+
{% set step = setting.step if setting.step is not none else 1 %}
|
136
|
+
|
137
|
+
<div class="settings-range-container">
|
138
|
+
<input
|
139
|
+
type="range"
|
140
|
+
id="{{ setting_id }}"
|
141
|
+
name="{{ setting.key }}"
|
142
|
+
class="settings-range form-control"
|
143
|
+
value="{{ setting.value if setting.value is not none else min_value }}"
|
144
|
+
min="{{ min_value }}"
|
145
|
+
max="{{ max_value }}"
|
146
|
+
step="{{ step }}"
|
147
|
+
{% if not setting.editable %}disabled{% endif %}
|
148
|
+
>
|
149
|
+
<span class="settings-range-value" id="{{ setting_id }}-value">{{ setting.value if setting.value is not none else min_value }}</span>
|
150
|
+
</div>
|
151
|
+
|
152
|
+
{% elif setting.ui_element == "number" %}
|
153
|
+
{% set min_value = setting.min_value if setting.min_value is not none else "" %}
|
154
|
+
{% set max_value = setting.max_value if setting.max_value is not none else "" %}
|
155
|
+
{% set step = setting.step if setting.step is not none else 1 %}
|
156
|
+
|
157
|
+
<input
|
158
|
+
type="number"
|
159
|
+
id="{{ setting_id }}"
|
160
|
+
name="{{ setting.key }}"
|
161
|
+
class="settings-input form-control"
|
162
|
+
value="{{ setting.value if setting.value is not none else '' }}"
|
163
|
+
min="{{ min_value }}"
|
164
|
+
max="{{ max_value }}"
|
165
|
+
step="{{ step }}"
|
166
|
+
{% if not setting.editable %}disabled{% endif %}
|
167
|
+
>
|
168
|
+
|
169
|
+
{% elif setting.ui_element == "password" %}
|
170
|
+
<input
|
171
|
+
type="password"
|
172
|
+
id="{{ setting_id }}"
|
173
|
+
name="{{ setting.key }}"
|
174
|
+
class="settings-input form-control"
|
175
|
+
value="{{ setting.value if setting.value is not none else '' }}"
|
176
|
+
{% if not setting.editable %}disabled{% endif %}
|
177
|
+
>
|
178
|
+
|
179
|
+
{% elif setting.key == "llm.model" or setting.key == "search.tool" %}
|
180
|
+
{% from "components/custom_dropdown.html" import render_dropdown %}
|
181
|
+
{{ render_dropdown(
|
182
|
+
input_id=setting.key,
|
183
|
+
dropdown_id=setting_id + "-dropdown",
|
184
|
+
placeholder="Select or enter a value",
|
185
|
+
label=None,
|
186
|
+
help_text=setting.description if setting.description else None,
|
187
|
+
allow_custom=setting.key == "llm.model",
|
188
|
+
show_refresh=True,
|
189
|
+
refresh_aria_label="Refresh model list" if setting.key == "llm.model" else "Refresh search engine list",
|
190
|
+
data_setting_key=setting.key
|
191
|
+
) }}
|
192
|
+
|
193
|
+
{% else %}
|
194
|
+
{% if setting.value is mapping or (setting.value is string and (setting.value.startswith('{') and setting.value.endswith('}'))) %}
|
195
|
+
<div class="json-expanded-controls">
|
196
|
+
{% if setting.value is string %}
|
197
|
+
{% set json_value = setting.value|tojson %}
|
198
|
+
{% else %}
|
199
|
+
{% set json_value = setting.value %}
|
200
|
+
{% endif %}
|
201
|
+
|
202
|
+
{# Store the original JSON in a hidden field #}
|
203
|
+
<input type="hidden" id="{{ setting_id }}_original" name="{{ setting.key }}_original" value="{{ setting.value|tojson }}">
|
204
|
+
|
205
|
+
{# Create individual form controls for each JSON property #}
|
206
|
+
<div class="json-property-controls">
|
207
|
+
{% for key, value in json_value.items() %}
|
208
|
+
<div class="json-property-item">
|
209
|
+
<label for="{{ setting_id }}_{{ key }}">{{ key|replace("_", " ")|title }}</label>
|
210
|
+
|
211
|
+
{% if value is boolean %}
|
212
|
+
<div class="checkbox-label">
|
213
|
+
<input type="checkbox"
|
214
|
+
id="{{ setting_id }}_{{ key }}"
|
215
|
+
name="{{ setting.key }}_{{ key }}"
|
216
|
+
class="json-property-control"
|
217
|
+
data-property="{{ key }}"
|
218
|
+
data-parent-key="{{ setting.key }}"
|
219
|
+
{% if value %}checked{% endif %}
|
220
|
+
{% if not setting.editable %}disabled{% endif %}>
|
221
|
+
<span class="checkbox-text">{{ key|replace("_", " ")|title }}</span>
|
222
|
+
</div>
|
223
|
+
{% elif value is number %}
|
224
|
+
<input type="number"
|
225
|
+
id="{{ setting_id }}_{{ key }}"
|
226
|
+
name="{{ setting.key }}_{{ key }}"
|
227
|
+
class="settings-input form-control json-property-control"
|
228
|
+
data-property="{{ key }}"
|
229
|
+
data-parent-key="{{ setting.key }}"
|
230
|
+
value="{{ value }}"
|
231
|
+
{% if not setting.editable %}disabled{% endif %}>
|
232
|
+
{% else %}
|
233
|
+
<input type="text"
|
234
|
+
id="{{ setting_id }}_{{ key }}"
|
235
|
+
name="{{ setting.key }}_{{ key }}"
|
236
|
+
class="settings-input form-control json-property-control"
|
237
|
+
data-property="{{ key }}"
|
238
|
+
data-parent-key="{{ setting.key }}"
|
239
|
+
value="{{ value }}"
|
240
|
+
{% if not setting.editable %}disabled{% endif %}>
|
241
|
+
{% endif %}
|
242
|
+
|
243
|
+
<div class="input-help">{{ key|replace("_", " ")|title }}</div>
|
244
|
+
</div>
|
245
|
+
{% endfor %}
|
246
|
+
</div>
|
247
|
+
</div>
|
248
|
+
{% else %}
|
249
|
+
<input
|
250
|
+
type="text"
|
251
|
+
id="{{ setting_id }}"
|
252
|
+
name="{{ setting.key }}"
|
253
|
+
class="settings-input form-control"
|
254
|
+
value="{{ setting.value if setting.value is not none else '' }}"
|
255
|
+
{% if not setting.editable %}disabled{% endif %}
|
256
|
+
>
|
257
|
+
{% endif %}
|
258
|
+
{% endif %}
|
259
|
+
|
260
|
+
{% if setting.description and setting.key != "llm.model" and setting.key != "search.tool" and setting.key != "llm.provider" %}
|
261
|
+
<div class="input-help">{{ setting.description }}</div>
|
262
|
+
{% endif %}
|
263
|
+
</div>
|
264
|
+
{% endmacro %}
|
265
|
+
|
266
|
+
{% macro render_settings_section(section_title, section_id, settings, form_id='settings-form') %}
|
267
|
+
<div class="settings-section">
|
268
|
+
<div class="settings-section-header" data-target="{{ section_id }}">
|
269
|
+
<div class="settings-section-title">
|
270
|
+
{{ section_title }}
|
271
|
+
</div>
|
272
|
+
<div class="settings-toggle-icon">
|
273
|
+
<i class="fas fa-chevron-down"></i>
|
274
|
+
</div>
|
275
|
+
</div>
|
276
|
+
<div id="{{ section_id }}" class="settings-section-body">
|
277
|
+
{% for setting in settings %}
|
278
|
+
{{ render_setting(setting, form_id) }}
|
279
|
+
{% endfor %}
|
280
|
+
</div>
|
281
|
+
</div>
|
282
|
+
{% endmacro %}
|
283
|
+
|
284
|
+
{% macro render_settings_form(settings_by_category, form_id, form_action) %}
|
285
|
+
<form id="{{ form_id }}" action="{{ form_action }}" method="POST" class="settings-form">
|
286
|
+
{% for category, settings in settings_by_category.items() %}
|
287
|
+
{{ render_settings_section(category, category|lower|replace(' ', '-'), settings, form_id) }}
|
288
|
+
{% endfor %}
|
289
|
+
|
290
|
+
<div class="form-actions">
|
291
|
+
<button type="reset" class="btn btn-outline">
|
292
|
+
<i class="fas fa-undo"></i> Reset Changes
|
293
|
+
</button>
|
294
|
+
<button type="submit" class="btn btn-primary">
|
295
|
+
<i class="fas fa-save"></i> Save Changes
|
296
|
+
</button>
|
297
|
+
</div>
|
298
|
+
</form>
|
299
|
+
{% endmacro %}
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<aside class="sidebar">
|
2
|
+
<div class="sidebar-header">
|
3
|
+
<h2 id="logo-link" style="cursor: pointer;"><i class="fas fa-atom"></i> Deep Research</h2>
|
4
|
+
</div>
|
5
|
+
<nav class="sidebar-nav">
|
6
|
+
<ul>
|
7
|
+
<li {% if active_page == 'new-research' %}class="active"{% endif %} data-page="new-research">
|
8
|
+
<a href="{{ url_for('research.index') }}"><i class="fas fa-search"></i> New Research</a>
|
9
|
+
</li>
|
10
|
+
<li {% if active_page == 'history' %}class="active"{% endif %} data-page="history">
|
11
|
+
<a href="{{ url_for('research.history_page') }}"><i class="fas fa-history"></i> History</a>
|
12
|
+
</li>
|
13
|
+
<li {% if active_page == 'settings' %}class="active"{% endif %} data-page="settings">
|
14
|
+
<a href="{{ url_for('research.settings_page') }}"><i class="fas fa-cog"></i> Settings</a>
|
15
|
+
</li>
|
16
|
+
</ul>
|
17
|
+
</nav>
|
18
|
+
<div class="sidebar-footer">
|
19
|
+
<p>v0.2.0 | <i class="fas fa-brain"></i></p>
|
20
|
+
</div>
|
21
|
+
</aside>
|
@@ -0,0 +1,73 @@
|
|
1
|
+
{% extends "base.html" %}
|
2
|
+
|
3
|
+
{% block title %}Research Details - Deep Research System{% endblock %}
|
4
|
+
|
5
|
+
{% block content %}
|
6
|
+
<div class="page active" id="research-details">
|
7
|
+
<div class="page-header">
|
8
|
+
<div class="results-header">
|
9
|
+
<h1>Research Details</h1>
|
10
|
+
<div class="results-actions">
|
11
|
+
<button class="btn btn-outline" id="back-to-history-from-details"><i class="fas fa-arrow-left"></i> Back to History</button>
|
12
|
+
</div>
|
13
|
+
</div>
|
14
|
+
</div>
|
15
|
+
<div class="card">
|
16
|
+
<div class="card-content">
|
17
|
+
<div class="research-metadata">
|
18
|
+
<div class="metadata-item">
|
19
|
+
<span class="metadata-label">Query:</span>
|
20
|
+
<span id="detail-query" class="metadata-value"></span>
|
21
|
+
</div>
|
22
|
+
<div class="metadata-item">
|
23
|
+
<span class="metadata-label">Status:</span>
|
24
|
+
<span id="detail-status" class="metadata-value"></span>
|
25
|
+
</div>
|
26
|
+
<div class="metadata-item">
|
27
|
+
<span class="metadata-label">Mode:</span>
|
28
|
+
<span id="detail-mode" class="metadata-value"></span>
|
29
|
+
</div>
|
30
|
+
<div class="metadata-item">
|
31
|
+
<span class="metadata-label">Progress:</span>
|
32
|
+
<div class="detail-progress-container">
|
33
|
+
<div class="detail-progress-bar">
|
34
|
+
<div class="detail-progress-fill" id="detail-progress-fill"></div>
|
35
|
+
</div>
|
36
|
+
<span id="detail-progress-percentage">0%</span>
|
37
|
+
</div>
|
38
|
+
</div>
|
39
|
+
</div>
|
40
|
+
|
41
|
+
<div class="research-log-container">
|
42
|
+
<h3>Research Progress Log</h3>
|
43
|
+
<div class="research-log" id="research-log">
|
44
|
+
<!-- Will be populated dynamically -->
|
45
|
+
<div class="loading-spinner centered">
|
46
|
+
<div class="spinner"></div>
|
47
|
+
</div>
|
48
|
+
</div>
|
49
|
+
</div>
|
50
|
+
|
51
|
+
<div class="detail-actions" id="detail-actions">
|
52
|
+
<!-- Conditionally shown based on research status -->
|
53
|
+
</div>
|
54
|
+
</div>
|
55
|
+
</div>
|
56
|
+
</div>
|
57
|
+
{% endblock %}
|
58
|
+
|
59
|
+
{% block templates %}
|
60
|
+
<template id="log-entry-template">
|
61
|
+
<div class="log-entry">
|
62
|
+
<div class="log-entry-time"></div>
|
63
|
+
<div class="log-entry-content">
|
64
|
+
<div class="log-entry-message"></div>
|
65
|
+
<div class="log-entry-progress"></div>
|
66
|
+
</div>
|
67
|
+
</div>
|
68
|
+
</template>
|
69
|
+
{% endblock %}
|
70
|
+
|
71
|
+
{% block page_scripts %}
|
72
|
+
<script src="{{ url_for('research.serve_static', path='js/components/details.js') }}"></script>
|
73
|
+
{% endblock %}
|
@@ -0,0 +1,51 @@
|
|
1
|
+
{% extends "base.html" %}
|
2
|
+
|
3
|
+
{% set active_page = 'history' %}
|
4
|
+
|
5
|
+
{% block title %}Research History - Deep Research System{% endblock %}
|
6
|
+
|
7
|
+
{% block styles %}
|
8
|
+
{{ super() }}
|
9
|
+
<link rel="stylesheet" href="{{ url_for('research.serve_static', path='css/components/history.css') }}">
|
10
|
+
{% endblock %}
|
11
|
+
|
12
|
+
{% block content %}
|
13
|
+
<div class="page active" id="history">
|
14
|
+
<div class="page-header">
|
15
|
+
<h1>Research History</h1>
|
16
|
+
</div>
|
17
|
+
<div class="card">
|
18
|
+
<div class="card-content">
|
19
|
+
<div class="search-controls" style="margin-bottom: 1rem;">
|
20
|
+
<input type="text" id="history-search" placeholder="Search history..." class="search-input">
|
21
|
+
<button id="clear-history-btn" class="btn btn-danger" style="display: none;">
|
22
|
+
<i class="fas fa-trash-alt"></i> Clear All
|
23
|
+
</button>
|
24
|
+
</div>
|
25
|
+
<div class="history-list" id="history-items">
|
26
|
+
<!-- Will be populated dynamically -->
|
27
|
+
<div class="loading-spinner centered">
|
28
|
+
<div class="spinner"></div>
|
29
|
+
</div>
|
30
|
+
</div>
|
31
|
+
<div id="history-empty-message" class="empty-state" style="display: none;">
|
32
|
+
<i class="fas fa-history empty-icon"></i>
|
33
|
+
<p>No research history found.</p>
|
34
|
+
</div>
|
35
|
+
</div>
|
36
|
+
</div>
|
37
|
+
</div>
|
38
|
+
{% endblock %}
|
39
|
+
|
40
|
+
{% block templates %}
|
41
|
+
<!-- Template is no longer needed since we build items dynamically in JavaScript -->
|
42
|
+
{% endblock %}
|
43
|
+
|
44
|
+
{% block page_scripts %}
|
45
|
+
<!-- Load utilities first -->
|
46
|
+
<script src="{{ url_for('research.serve_static', path='js/services/ui.js') }}"></script>
|
47
|
+
<script src="{{ url_for('research.serve_static', path='js/services/formatting.js') }}"></script>
|
48
|
+
<script src="{{ url_for('research.serve_static', path='js/services/api.js') }}"></script>
|
49
|
+
<!-- Then load the component -->
|
50
|
+
<script src="{{ url_for('research.serve_static', path='js/components/history.js') }}"></script>
|
51
|
+
{% endblock %}
|
@@ -0,0 +1,57 @@
|
|
1
|
+
{% extends "base.html" %}
|
2
|
+
|
3
|
+
{% block title %}Research in Progress - Deep Research System{% endblock %}
|
4
|
+
|
5
|
+
{% block content %}
|
6
|
+
<div class="page active" id="research-progress">
|
7
|
+
<div class="page-header">
|
8
|
+
<h1>Research in Progress</h1>
|
9
|
+
</div>
|
10
|
+
<div class="card">
|
11
|
+
<div class="card-content">
|
12
|
+
<div class="progress-info">
|
13
|
+
<div class="current-query-container">
|
14
|
+
<div class="current-query-label">Current Query:</div>
|
15
|
+
<div id="current-query" class="current-query"></div>
|
16
|
+
</div>
|
17
|
+
<div class="progress-container">
|
18
|
+
<div class="progress-bar">
|
19
|
+
<div id="progress-bar" class="progress-fill"></div>
|
20
|
+
</div>
|
21
|
+
<div id="progress-percentage" class="progress-percentage">0%</div>
|
22
|
+
</div>
|
23
|
+
<div class="status-container">
|
24
|
+
<div class="status-label">Status:</div>
|
25
|
+
<div id="status-text" class="status-indicator">Initializing</div>
|
26
|
+
</div>
|
27
|
+
<div class="task-container">
|
28
|
+
<div class="task-label">Current Task:</div>
|
29
|
+
<div id="current-task" class="task-text">Starting research...</div>
|
30
|
+
</div>
|
31
|
+
<div class="progress-actions">
|
32
|
+
<button id="cancel-research-btn" class="btn btn-outline terminate-btn">
|
33
|
+
<i class="fas fa-stop-circle"></i> Cancel Research
|
34
|
+
</button>
|
35
|
+
<a id="view-results-btn" class="btn btn-primary" style="display: none;">
|
36
|
+
<i class="fas fa-eye"></i> View Results
|
37
|
+
</a>
|
38
|
+
</div>
|
39
|
+
</div>
|
40
|
+
</div>
|
41
|
+
</div>
|
42
|
+
|
43
|
+
{% include "components/log_panel.html" %}
|
44
|
+
</div>
|
45
|
+
{% endblock %}
|
46
|
+
|
47
|
+
{% block page_scripts %}
|
48
|
+
<!-- Load required services -->
|
49
|
+
<script src="{{ url_for('research.serve_static', path='js/services/audio.js') }}"></script>
|
50
|
+
<script src="{{ url_for('research.serve_static', path='js/services/ui.js') }}"></script>
|
51
|
+
<script src="{{ url_for('research.serve_static', path='js/services/formatting.js') }}"></script>
|
52
|
+
<script src="{{ url_for('research.serve_static', path='js/services/api.js') }}"></script>
|
53
|
+
<script src="{{ url_for('research.serve_static', path='js/services/socket.js') }}"></script>
|
54
|
+
|
55
|
+
<!-- Then load the component -->
|
56
|
+
<script src="{{ url_for('research.serve_static', path='js/components/progress.js') }}"></script>
|
57
|
+
{% endblock %}
|