local-deep-research 0.1.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.
Files changed (56) hide show
  1. local_deep_research/__init__.py +24 -0
  2. local_deep_research/citation_handler.py +113 -0
  3. local_deep_research/config.py +166 -0
  4. local_deep_research/defaults/__init__.py +44 -0
  5. local_deep_research/defaults/llm_config.py +269 -0
  6. local_deep_research/defaults/local_collections.toml +47 -0
  7. local_deep_research/defaults/main.toml +57 -0
  8. local_deep_research/defaults/search_engines.toml +244 -0
  9. local_deep_research/local_collections.py +141 -0
  10. local_deep_research/main.py +113 -0
  11. local_deep_research/report_generator.py +206 -0
  12. local_deep_research/search_system.py +241 -0
  13. local_deep_research/utilties/__init__.py +0 -0
  14. local_deep_research/utilties/enums.py +9 -0
  15. local_deep_research/utilties/llm_utils.py +116 -0
  16. local_deep_research/utilties/search_utilities.py +115 -0
  17. local_deep_research/utilties/setup_utils.py +6 -0
  18. local_deep_research/web/__init__.py +2 -0
  19. local_deep_research/web/app.py +1209 -0
  20. local_deep_research/web/static/css/styles.css +1008 -0
  21. local_deep_research/web/static/js/app.js +2078 -0
  22. local_deep_research/web/templates/api_keys_config.html +82 -0
  23. local_deep_research/web/templates/collections_config.html +90 -0
  24. local_deep_research/web/templates/index.html +312 -0
  25. local_deep_research/web/templates/llm_config.html +120 -0
  26. local_deep_research/web/templates/main_config.html +89 -0
  27. local_deep_research/web/templates/search_engines_config.html +154 -0
  28. local_deep_research/web/templates/settings.html +519 -0
  29. local_deep_research/web/templates/settings_dashboard.html +207 -0
  30. local_deep_research/web_search_engines/__init__.py +0 -0
  31. local_deep_research/web_search_engines/engines/__init__.py +0 -0
  32. local_deep_research/web_search_engines/engines/full_search.py +128 -0
  33. local_deep_research/web_search_engines/engines/meta_search_engine.py +274 -0
  34. local_deep_research/web_search_engines/engines/search_engine_arxiv.py +367 -0
  35. local_deep_research/web_search_engines/engines/search_engine_brave.py +245 -0
  36. local_deep_research/web_search_engines/engines/search_engine_ddg.py +123 -0
  37. local_deep_research/web_search_engines/engines/search_engine_github.py +663 -0
  38. local_deep_research/web_search_engines/engines/search_engine_google_pse.py +283 -0
  39. local_deep_research/web_search_engines/engines/search_engine_guardian.py +337 -0
  40. local_deep_research/web_search_engines/engines/search_engine_local.py +901 -0
  41. local_deep_research/web_search_engines/engines/search_engine_local_all.py +153 -0
  42. local_deep_research/web_search_engines/engines/search_engine_medrxiv.py +623 -0
  43. local_deep_research/web_search_engines/engines/search_engine_pubmed.py +992 -0
  44. local_deep_research/web_search_engines/engines/search_engine_serpapi.py +230 -0
  45. local_deep_research/web_search_engines/engines/search_engine_wayback.py +474 -0
  46. local_deep_research/web_search_engines/engines/search_engine_wikipedia.py +242 -0
  47. local_deep_research/web_search_engines/full_search.py +254 -0
  48. local_deep_research/web_search_engines/search_engine_base.py +197 -0
  49. local_deep_research/web_search_engines/search_engine_factory.py +233 -0
  50. local_deep_research/web_search_engines/search_engines_config.py +54 -0
  51. local_deep_research-0.1.0.dist-info/LICENSE +21 -0
  52. local_deep_research-0.1.0.dist-info/METADATA +328 -0
  53. local_deep_research-0.1.0.dist-info/RECORD +56 -0
  54. local_deep_research-0.1.0.dist-info/WHEEL +5 -0
  55. local_deep_research-0.1.0.dist-info/entry_points.txt +3 -0
  56. local_deep_research-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,519 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Deep Research System - Settings</title>
7
+ <link rel="stylesheet" href="{{ url_for('research.serve_static', path='css/styles.css') }}">
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
9
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/github-dark.min.css">
10
+ <link rel="icon" type="image/png" href="{{ url_for('static', filename='favicon.ico') }}">
11
+ <style>
12
+ .settings-section {
13
+ margin-bottom: 2rem;
14
+ padding-bottom: 1.5rem;
15
+ border-bottom: 1px solid #333;
16
+ }
17
+ .settings-section h2 {
18
+ margin-bottom: 1rem;
19
+ color: #4a6cf7;
20
+ font-size: 1.3rem;
21
+ }
22
+ .form-group {
23
+ margin-bottom: 1rem;
24
+ }
25
+ .form-group label {
26
+ display: block;
27
+ margin-bottom: 0.5rem;
28
+ font-weight: 500;
29
+ }
30
+ .form-control {
31
+ width: 100%;
32
+ padding: 0.5rem;
33
+ border: 1px solid #333;
34
+ border-radius: 4px;
35
+ background-color: #1a1a1a;
36
+ color: #f8f9fa;
37
+ }
38
+ .form-row {
39
+ display: flex;
40
+ gap: 1rem;
41
+ }
42
+ .form-group.half {
43
+ flex: 1;
44
+ }
45
+ .input-help {
46
+ display: block;
47
+ font-size: 0.8rem;
48
+ color: #8a8a8a;
49
+ margin-top: 0.25rem;
50
+ }
51
+ .checkbox-group {
52
+ display: flex;
53
+ align-items: center;
54
+ gap: 0.5rem;
55
+ }
56
+ .checkbox-group input {
57
+ margin: 0;
58
+ }
59
+ .checkbox-group label {
60
+ margin: 0;
61
+ }
62
+ .form-actions {
63
+ margin-top: 2rem;
64
+ display: flex;
65
+ gap: 1rem;
66
+ }
67
+ .range-value {
68
+ display: inline-block;
69
+ margin-left: 0.5rem;
70
+ }
71
+ .config-raw {
72
+ margin-top: 2rem;
73
+ background-color: #0a0a0a;
74
+ padding: 1rem;
75
+ border-radius: 4px;
76
+ overflow: auto;
77
+ font-family: monospace;
78
+ font-size: 0.9rem;
79
+ color: #e6e6e6;
80
+ white-space: pre;
81
+ min-height: 200px;
82
+ max-height: 600px;
83
+ border: 1px solid #333;
84
+ }
85
+ .toggle-raw-config {
86
+ cursor: pointer;
87
+ display: flex;
88
+ align-items: center;
89
+ gap: 0.5rem;
90
+ margin-top: 2rem;
91
+ margin-bottom: 1rem;
92
+ color: #4a6cf7;
93
+ font-weight: 500;
94
+ padding: 0.5rem 1rem;
95
+ background-color: rgba(74, 108, 247, 0.1);
96
+ border-radius: 4px;
97
+ width: fit-content;
98
+ }
99
+ .toggle-raw-config:hover {
100
+ background-color: rgba(74, 108, 247, 0.2);
101
+ }
102
+ .config-raw-editor {
103
+ background-color: #0a0a0a;
104
+ color: #e6e6e6;
105
+ font-family: monospace;
106
+ font-size: 0.9rem;
107
+ padding: 1rem;
108
+ border: 1px solid #333;
109
+ border-radius: 4px;
110
+ width: 100%;
111
+ min-height: 400px;
112
+ resize: vertical;
113
+ display: block !important;
114
+ }
115
+ .alert {
116
+ padding: 0.75rem 1.25rem;
117
+ margin-bottom: 1rem;
118
+ border: 1px solid transparent;
119
+ border-radius: 0.25rem;
120
+ }
121
+ .alert-success {
122
+ color: #d4edda;
123
+ background-color: #1e462e;
124
+ border-color: #c3e6cb;
125
+ }
126
+ .alert-error {
127
+ color: #f8d7da;
128
+ background-color: #462c2e;
129
+ border-color: #f5c6cb;
130
+ }
131
+ .editor-header {
132
+ background-color: var(--bg-tertiary);
133
+ padding: 0.75rem 1rem;
134
+ border-bottom: 1px solid var(--border-color);
135
+ display: flex;
136
+ justify-content: space-between;
137
+ align-items: center;
138
+ }
139
+ .editor-header h3 {
140
+ margin: 0;
141
+ font-size: 1rem;
142
+ color: var(--text-primary);
143
+ }
144
+ .editor-lang {
145
+ background-color: var(--accent-primary);
146
+ font-size: 0.8rem;
147
+ padding: 0.25rem 0.5rem;
148
+ border-radius: 4px;
149
+ }
150
+ </style>
151
+ </head>
152
+ <body>
153
+ <div class="app-container">
154
+ <!-- Sidebar -->
155
+ <aside class="sidebar">
156
+ <div class="sidebar-header">
157
+ <h2 id="logo-link" style="cursor: pointer;"><i class="fas fa-atom"></i> Deep Research</h2>
158
+ </div>
159
+ <nav class="sidebar-nav">
160
+ <ul>
161
+ <li data-page="new-research"><i class="fas fa-search"></i> <a href="{{ url_for('research.index') }}">New Research</a></li>
162
+ <li data-page="history"><i class="fas fa-history"></i> <a href="{{ url_for('research.index') }}#history">History</a></li>
163
+ <li class="active" data-page="settings"><i class="fas fa-cog"></i> Settings</li>
164
+ </ul>
165
+ </nav>
166
+ <div class="sidebar-footer">
167
+ <p>v0.0.1 | <i class="fas fa-brain"></i></p>
168
+ </div>
169
+ </aside>
170
+
171
+ <!-- Main Content -->
172
+ <main class="main-content">
173
+ <div class="page active" id="settings">
174
+ <div class="page-header">
175
+ <h1>Settings</h1>
176
+ </div>
177
+
178
+ {% with messages = get_flashed_messages(with_categories=true) %}
179
+ {% if messages %}
180
+ {% for category, message in messages %}
181
+ <div class="alert alert-{{ category }}">
182
+ {{ message }}
183
+ </div>
184
+ {% endfor %}
185
+ {% endif %}
186
+ {% endwith %}
187
+
188
+ <div class="card">
189
+ <div class="card-content">
190
+ <form method="POST" action="{{ url_for('research.settings_page') }}">
191
+ <!-- LLM Settings Section -->
192
+ <div class="settings-section">
193
+ <h2><i class="fas fa-brain"></i> LLM Settings</h2>
194
+ <div class="form-group">
195
+ <label for="DEFAULT_MODEL">Default Model</label>
196
+ <select id="DEFAULT_MODEL" name="DEFAULT_MODEL" class="form-control">
197
+ <option value="mistral" {% if config.DEFAULT_MODEL == "mistral" %}selected{% endif %}>Mistral (Default)</option>
198
+ <option value="llama3" {% if config.DEFAULT_MODEL == "llama3" %}selected{% endif %}>Llama3</option>
199
+ <option value="mixtral" {% if config.DEFAULT_MODEL == "mixtral" %}selected{% endif %}>Mixtral</option>
200
+ <option value="mpt-7b" {% if config.DEFAULT_MODEL == "mpt-7b" %}selected{% endif %}>MPT-7B</option>
201
+ <option value="gpt-4o" {% if config.DEFAULT_MODEL == "gpt-4o" %}selected{% endif %}>GPT-4o (requires API key)</option>
202
+ <option value="gpt-3.5-turbo" {% if config.DEFAULT_MODEL == "gpt-3.5-turbo" %}selected{% endif %}>GPT-3.5 Turbo (requires API key)</option>
203
+ <option value="claude-3-5-sonnet-latest" {% if config.DEFAULT_MODEL == "claude-3-5-sonnet-latest" %}selected{% endif %}>Claude (requires API key)</option>
204
+ </select>
205
+ <span class="input-help">Select the default language model to use for analysis</span>
206
+ </div>
207
+ <div class="form-group">
208
+ <label for="DEFAULT_TEMPERATURE">Temperature</label>
209
+ <input type="range" min="0" max="1" step="0.1" class="form-control" id="DEFAULT_TEMPERATURE" name="DEFAULT_TEMPERATURE" value="{{ config.DEFAULT_TEMPERATURE }}">
210
+ <span class="range-value" id="temp-value">{{ config.DEFAULT_TEMPERATURE }}</span>
211
+ <span class="input-help">Higher values = more creative, lower values = more deterministic</span>
212
+ </div>
213
+ <div class="form-group">
214
+ <label for="MAX_TOKENS">Max Tokens</label>
215
+ <input type="number" min="1000" max="100000" step="1000" class="form-control" id="MAX_TOKENS" name="MAX_TOKENS" value="{{ config.MAX_TOKENS }}">
216
+ <span class="input-help">Maximum tokens for model output</span>
217
+ </div>
218
+
219
+ <div class="form-group checkbox-group">
220
+ <input type="checkbox" id="OPENAIENDPOINT" name="OPENAIENDPOINT" {% if config.OPENAIENDPOINT %}checked{% endif %}>
221
+ <label for="OPENAIENDPOINT">Use OpenAI endpoint</label>
222
+ </div>
223
+
224
+ <div class="form-group">
225
+ <label for="OPENROUTER_BASE_URL">OpenRouter Base URL</label>
226
+ <input type="text" class="form-control" id="OPENROUTER_BASE_URL" name="OPENROUTER_BASE_URL" value="{{ config.OPENROUTER_BASE_URL }}">
227
+ <span class="input-help">Base URL for OpenRouter API</span>
228
+ </div>
229
+ </div>
230
+
231
+ <!-- VLLM Settings Section -->
232
+ <div class="settings-section">
233
+ <h2><i class="fas fa-server"></i> VLLM Configuration</h2>
234
+ <div class="form-row">
235
+ <div class="form-group half">
236
+ <label for="VLLM_MAX_NEW_TOKENS">Max New Tokens</label>
237
+ <input type="number" min="1" max="1000" class="form-control" id="VLLM_MAX_NEW_TOKENS" name="VLLM_MAX_NEW_TOKENS" value="{{ config.VLLM_MAX_NEW_TOKENS }}">
238
+ <span class="input-help">Maximum new tokens for VLLM models</span>
239
+ </div>
240
+ <div class="form-group half">
241
+ <label for="VLLM_TOP_K">Top K</label>
242
+ <input type="number" min="1" max="100" class="form-control" id="VLLM_TOP_K" name="VLLM_TOP_K" value="{{ config.VLLM_TOP_K }}">
243
+ <span class="input-help">Top K sampling parameter</span>
244
+ </div>
245
+ </div>
246
+ <div class="form-row">
247
+ <div class="form-group half">
248
+ <label for="VLLM_TOP_P">Top P</label>
249
+ <input type="range" min="0" max="1" step="0.01" class="form-control" id="VLLM_TOP_P" name="VLLM_TOP_P" value="{{ config.VLLM_TOP_P }}">
250
+ <span class="range-value" id="top-p-value">{{ config.VLLM_TOP_P }}</span>
251
+ <span class="input-help">Top P sampling parameter</span>
252
+ </div>
253
+ <div class="form-group half">
254
+ <label for="VLLM_TEMPERATURE">VLLM Temperature</label>
255
+ <input type="range" min="0" max="1" step="0.1" class="form-control" id="VLLM_TEMPERATURE" name="VLLM_TEMPERATURE" value="{{ config.VLLM_TEMPERATURE }}">
256
+ <span class="range-value" id="vllm-temp-value">{{ config.VLLM_TEMPERATURE }}</span>
257
+ <span class="input-help">Temperature for VLLM models</span>
258
+ </div>
259
+ </div>
260
+ </div>
261
+
262
+ <!-- Search Settings Section -->
263
+ <div class="settings-section">
264
+ <h2><i class="fas fa-search"></i> Search Settings</h2>
265
+ <div class="form-group">
266
+ <label for="search_tool">Default Search Engine</label>
267
+ <select id="search_tool" name="search_tool" class="form-control">
268
+ <option value="auto" {% if config.search_tool == "auto" %}selected{% endif %}>Auto (Intelligent selection)</option>
269
+ <option value="wikipedia" {% if config.search_tool == "wikipedia" %}selected{% endif %}>Wikipedia</option>
270
+ <option value="arxiv" {% if config.search_tool == "arxiv" %}selected{% endif %}>arXiv (scientific papers)</option>
271
+ <option value="pubmed" {% if config.search_tool == "pubmed" %}selected{% endif %}>PubMed (medical research)</option>
272
+ <option value="duckduckgo" {% if config.search_tool == "duckduckgo" %}selected{% endif %}>DuckDuckGo (web search)</option>
273
+ <option value="serp" {% if config.search_tool == "serp" %}selected{% endif %}>SerpAPI (Google, requires API key)</option>
274
+ <option value="google_pse" {% if config.search_tool == "google_pse" %}selected{% endif %}>Google PSE (requires API key)</option>
275
+ <option value="guardian" {% if config.search_tool == "guardian" %}selected{% endif %}>Guardian (news, requires API key)</option>
276
+ <option value="local_all" {% if config.search_tool == "local_all" %}selected{% endif %}>Local Documents</option>
277
+ </select>
278
+ <span class="input-help">Choose your primary search and research source</span>
279
+ </div>
280
+
281
+ <div class="form-row">
282
+ <div class="form-group half">
283
+ <label for="SEARCH_ITERATIONS">Search Iterations</label>
284
+ <input type="number" min="1" max="5" class="form-control" id="SEARCH_ITERATIONS" name="SEARCH_ITERATIONS" value="{{ config.SEARCH_ITERATIONS }}">
285
+ <span class="input-help">Number of research cycles to perform</span>
286
+ </div>
287
+ <div class="form-group half">
288
+ <label for="QUESTIONS_PER_ITERATION">Questions Per Iteration</label>
289
+ <input type="number" min="1" max="10" class="form-control" id="QUESTIONS_PER_ITERATION" name="QUESTIONS_PER_ITERATION" value="{{ config.QUESTIONS_PER_ITERATION }}">
290
+ <span class="input-help">Follow-up questions in each cycle</span>
291
+ </div>
292
+ </div>
293
+
294
+ <div class="form-row">
295
+ <div class="form-group half">
296
+ <label for="MAX_SEARCH_RESULTS">Maximum Search Results</label>
297
+ <input type="number" min="5" max="100" class="form-control" id="MAX_SEARCH_RESULTS" name="MAX_SEARCH_RESULTS" value="{{ config.MAX_SEARCH_RESULTS }}">
298
+ <span class="input-help">Higher values give more comprehensive research but take longer</span>
299
+ </div>
300
+
301
+ <div class="form-group half">
302
+ <label for="MAX_FILTERED_RESULTS">Maximum Filtered Results</label>
303
+ <input type="number" min="1" max="20" class="form-control" id="MAX_FILTERED_RESULTS" name="MAX_FILTERED_RESULTS" value="{{ config.MAX_FILTERED_RESULTS }}">
304
+ <span class="input-help">Results kept after relevance filtering</span>
305
+ </div>
306
+ </div>
307
+
308
+ <div class="form-group">
309
+ <label for="KNOWLEDGE_ACCUMULATION">Knowledge Accumulation</label>
310
+ <select id="KNOWLEDGE_ACCUMULATION" name="KNOWLEDGE_ACCUMULATION" class="form-control">
311
+ <option value="ITERATION" {% if config.KNOWLEDGE_ACCUMULATION == "ITERATION" %}selected{% endif %}>Iteration-based</option>
312
+ <option value="NONE" {% if config.KNOWLEDGE_ACCUMULATION == "NONE" %}selected{% endif %}>None</option>
313
+ </select>
314
+ <span class="input-help">How to accumulate knowledge during research</span>
315
+ </div>
316
+
317
+ <div class="form-group">
318
+ <label for="KNOWLEDGE_ACCUMULATION_CONTEXT_LIMIT">Knowledge Accumulation Context Limit</label>
319
+ <input type="number" class="form-control" id="KNOWLEDGE_ACCUMULATION_CONTEXT_LIMIT" name="KNOWLEDGE_ACCUMULATION_CONTEXT_LIMIT" value="{{ config.KNOWLEDGE_ACCUMULATION_CONTEXT_LIMIT }}">
320
+ <span class="input-help">Maximum context size for knowledge accumulation</span>
321
+ </div>
322
+
323
+ <div class="form-row">
324
+ <div class="form-group half">
325
+ <label for="SEARCH_REGION">Search Region</label>
326
+ <input type="text" class="form-control" id="SEARCH_REGION" name="SEARCH_REGION" value="{{ config.SEARCH_REGION }}">
327
+ <span class="input-help">Region code for search (e.g., us, uk, de)</span>
328
+ </div>
329
+ <div class="form-group half">
330
+ <label for="TIME_PERIOD">Time Period</label>
331
+ <select id="TIME_PERIOD" name="TIME_PERIOD" class="form-control">
332
+ <option value="d" {% if config.TIME_PERIOD == "d" %}selected{% endif %}>Past day</option>
333
+ <option value="w" {% if config.TIME_PERIOD == "w" %}selected{% endif %}>Past week</option>
334
+ <option value="m" {% if config.TIME_PERIOD == "m" %}selected{% endif %}>Past month</option>
335
+ <option value="y" {% if config.TIME_PERIOD == "y" %}selected{% endif %}>Past year</option>
336
+ <option value="a" {% if config.TIME_PERIOD == "a" %}selected{% endif %}>All time</option>
337
+ </select>
338
+ <span class="input-help">Time period for search results</span>
339
+ </div>
340
+ </div>
341
+
342
+ <div class="form-group">
343
+ <label for="SEARCH_LANGUAGE">Search Language</label>
344
+ <input type="text" class="form-control" id="SEARCH_LANGUAGE" name="SEARCH_LANGUAGE" value="{{ config.SEARCH_LANGUAGE }}">
345
+ <span class="input-help">Language for search results</span>
346
+ </div>
347
+
348
+ <div class="form-group checkbox-group">
349
+ <input type="checkbox" id="SAFE_SEARCH" name="SAFE_SEARCH" {% if config.SAFE_SEARCH %}checked{% endif %}>
350
+ <label for="SAFE_SEARCH">Safe Search</label>
351
+ </div>
352
+
353
+ <div class="form-group checkbox-group">
354
+ <input type="checkbox" id="QUALITY_CHECK_DDG_URLS" name="QUALITY_CHECK_DDG_URLS" {% if config.QUALITY_CHECK_DDG_URLS %}checked{% endif %}>
355
+ <label for="QUALITY_CHECK_DDG_URLS">Quality check URLs</label>
356
+ <span class="input-help">Enable quality filtering for search results</span>
357
+ </div>
358
+
359
+ <div class="form-group checkbox-group">
360
+ <input type="checkbox" id="SEARCH_SNIPPETS_ONLY" name="SEARCH_SNIPPETS_ONLY" {% if config.SEARCH_SNIPPETS_ONLY %}checked{% endif %}>
361
+ <label for="SEARCH_SNIPPETS_ONLY">Use search snippets only (faster but less detailed)</label>
362
+ </div>
363
+
364
+ <div class="form-group checkbox-group">
365
+ <input type="checkbox" id="SKIP_RELEVANCE_FILTER" name="SKIP_RELEVANCE_FILTER" {% if config.SKIP_RELEVANCE_FILTER %}checked{% endif %}>
366
+ <label for="SKIP_RELEVANCE_FILTER">Skip relevance filtering (return all results)</label>
367
+ </div>
368
+ </div>
369
+
370
+ <!-- Report Settings Section -->
371
+ <div class="settings-section">
372
+ <h2><i class="fas fa-file-alt"></i> Report Settings</h2>
373
+ <div class="form-group">
374
+ <label for="SEARCHES_PER_SECTION">Searches Per Report Section</label>
375
+ <input type="number" min="1" max="5" class="form-control" id="SEARCHES_PER_SECTION" name="SEARCHES_PER_SECTION" value="{{ config.SEARCHES_PER_SECTION }}">
376
+ <span class="input-help">Number of searches to run per report section</span>
377
+ </div>
378
+
379
+ <div class="form-group checkbox-group">
380
+ <input type="checkbox" id="ENABLE_FACT_CHECKING" name="ENABLE_FACT_CHECKING" {% if config.ENABLE_FACT_CHECKING %}checked{% endif %}>
381
+ <label for="ENABLE_FACT_CHECKING">Enable fact checking (may work better with large LLMs)</label>
382
+ </div>
383
+
384
+ <div class="form-group">
385
+ <label for="OUTPUT_DIR">Output Directory</label>
386
+ <input type="text" class="form-control" id="OUTPUT_DIR" name="OUTPUT_DIR" value="{{ config.OUTPUT_DIR }}">
387
+ <span class="input-help">Directory to save research outputs</span>
388
+ </div>
389
+ </div>
390
+
391
+ <div class="form-actions">
392
+ <button type="submit" class="btn btn-primary"><i class="fas fa-save"></i> Save Settings</button>
393
+ <a href="{{ url_for('research.index') }}" class="btn btn-outline"><i class="fas fa-times"></i> Cancel</a>
394
+ </div>
395
+ </form>
396
+
397
+ <div class="toggle-raw-config" onclick="toggleRawConfig()">
398
+ <i class="fas fa-code"></i> <span id="toggle-text">Show Raw Configuration</span>
399
+ </div>
400
+
401
+ <div id="raw-config" class="config-raw" style="display: none;">
402
+ {{ raw_config|safe }}
403
+ </div>
404
+
405
+ <!-- Raw Configuration Editing -->
406
+ <div id="raw-config-editor-container" style="display: none; margin-top: 1rem;">
407
+ <div class="editor-header">
408
+ <h3>Edit Raw Configuration</h3>
409
+ <span class="editor-lang">TOML</span>
410
+ </div>
411
+ <textarea id="raw_config_editor" name="raw_config_editor" class="config-raw-editor" rows="20">{{ raw_config|safe }}</textarea>
412
+ <div class="form-actions">
413
+ <button type="button" class="btn btn-primary" onclick="saveRawConfig()"><i class="fas fa-save"></i> Save Raw Configuration</button>
414
+ <button type="button" class="btn btn-outline" onclick="cancelRawEdit()"><i class="fas fa-times"></i> Cancel</button>
415
+ </div>
416
+ </div>
417
+ </div>
418
+ </div>
419
+ </div>
420
+ </main>
421
+ </div>
422
+
423
+ <!-- Mobile Tab Bar -->
424
+ <nav class="mobile-tab-bar">
425
+ <ul>
426
+ <li data-page="new-research">
427
+ <a href="{{ url_for('research.index') }}">
428
+ <i class="fas fa-search"></i>
429
+ <span>Research</span>
430
+ </a>
431
+ </li>
432
+ <li data-page="history">
433
+ <a href="{{ url_for('research.index') }}#history">
434
+ <i class="fas fa-history"></i>
435
+ <span>History</span>
436
+ </a>
437
+ </li>
438
+ <li class="active" data-page="settings">
439
+ <i class="fas fa-cog"></i>
440
+ <span>Settings</span>
441
+ </li>
442
+ </ul>
443
+ </nav>
444
+
445
+ <script>
446
+ // Update temperature display value
447
+ document.getElementById('DEFAULT_TEMPERATURE').addEventListener('input', function() {
448
+ document.getElementById('temp-value').textContent = this.value;
449
+ });
450
+
451
+ // Update VLLM temperature display value
452
+ document.getElementById('VLLM_TEMPERATURE').addEventListener('input', function() {
453
+ document.getElementById('vllm-temp-value').textContent = this.value;
454
+ });
455
+
456
+ // Update Top P display value
457
+ document.getElementById('VLLM_TOP_P').addEventListener('input', function() {
458
+ document.getElementById('top-p-value').textContent = this.value;
459
+ });
460
+
461
+ // Make the logo clickable to go back to home
462
+ document.getElementById('logo-link').addEventListener('click', function() {
463
+ window.location.href = "{{ url_for('research.index') }}";
464
+ });
465
+
466
+ // Toggle raw configuration display
467
+ function toggleRawConfig() {
468
+ const rawConfig = document.getElementById('raw-config');
469
+ const editorContainer = document.getElementById('raw-config-editor-container');
470
+ const toggleText = document.getElementById('toggle-text');
471
+
472
+ if (rawConfig.style.display === 'none') {
473
+ rawConfig.style.display = 'block';
474
+ editorContainer.style.display = 'block';
475
+ toggleText.textContent = 'Hide Raw Configuration';
476
+ } else {
477
+ rawConfig.style.display = 'none';
478
+ editorContainer.style.display = 'none';
479
+ toggleText.textContent = 'Show Raw Configuration';
480
+ }
481
+ }
482
+
483
+ function cancelRawEdit() {
484
+ const rawConfig = document.getElementById('raw-config');
485
+ const editorContainer = document.getElementById('raw-config-editor-container');
486
+ const toggleText = document.getElementById('toggle-text');
487
+
488
+ rawConfig.style.display = 'none';
489
+ editorContainer.style.display = 'none';
490
+ toggleText.textContent = 'Show Raw Configuration';
491
+ }
492
+
493
+ function saveRawConfig() {
494
+ const rawConfig = document.getElementById('raw_config_editor').value;
495
+
496
+ fetch('{{ url_for("research.save_raw_config") }}', {
497
+ method: 'POST',
498
+ headers: {
499
+ 'Content-Type': 'application/json',
500
+ },
501
+ body: JSON.stringify({ raw_config: rawConfig }),
502
+ })
503
+ .then(response => response.json())
504
+ .then(data => {
505
+ if (data.success) {
506
+ alert('Configuration saved successfully. You may need to restart the application for changes to take effect.');
507
+ // Reload the page to show updated values
508
+ window.location.reload();
509
+ } else {
510
+ alert('Error saving configuration: ' + data.error);
511
+ }
512
+ })
513
+ .catch(error => {
514
+ alert('Error saving configuration: ' + error);
515
+ });
516
+ }
517
+ </script>
518
+ </body>
519
+ </html>