local-deep-research 0.5.7__py3-none-any.whl → 0.6.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/__version__.py +1 -1
- local_deep_research/advanced_search_system/candidate_exploration/progressive_explorer.py +11 -1
- local_deep_research/advanced_search_system/questions/browsecomp_question.py +32 -6
- local_deep_research/advanced_search_system/strategies/focused_iteration_strategy.py +33 -8
- local_deep_research/advanced_search_system/strategies/source_based_strategy.py +2 -0
- local_deep_research/api/__init__.py +2 -0
- local_deep_research/api/research_functions.py +177 -3
- local_deep_research/benchmarks/graders.py +150 -5
- local_deep_research/benchmarks/models/__init__.py +19 -0
- local_deep_research/benchmarks/models/benchmark_models.py +283 -0
- local_deep_research/benchmarks/ui/__init__.py +1 -0
- local_deep_research/benchmarks/web_api/__init__.py +6 -0
- local_deep_research/benchmarks/web_api/benchmark_routes.py +862 -0
- local_deep_research/benchmarks/web_api/benchmark_service.py +920 -0
- local_deep_research/config/llm_config.py +106 -21
- local_deep_research/defaults/default_settings.json +448 -3
- local_deep_research/error_handling/report_generator.py +10 -0
- local_deep_research/llm/__init__.py +19 -0
- local_deep_research/llm/llm_registry.py +155 -0
- local_deep_research/metrics/db_models.py +3 -7
- local_deep_research/metrics/search_tracker.py +25 -11
- local_deep_research/report_generator.py +3 -2
- local_deep_research/search_system.py +12 -9
- local_deep_research/utilities/log_utils.py +23 -10
- local_deep_research/utilities/thread_context.py +99 -0
- local_deep_research/web/app_factory.py +32 -8
- local_deep_research/web/database/benchmark_schema.py +230 -0
- local_deep_research/web/database/convert_research_id_to_string.py +161 -0
- local_deep_research/web/database/models.py +55 -1
- local_deep_research/web/database/schema_upgrade.py +397 -2
- local_deep_research/web/database/uuid_migration.py +265 -0
- local_deep_research/web/routes/api_routes.py +62 -31
- local_deep_research/web/routes/history_routes.py +13 -6
- local_deep_research/web/routes/metrics_routes.py +264 -4
- local_deep_research/web/routes/research_routes.py +45 -18
- local_deep_research/web/routes/route_registry.py +352 -0
- local_deep_research/web/routes/settings_routes.py +382 -22
- local_deep_research/web/services/research_service.py +22 -29
- local_deep_research/web/services/settings_manager.py +53 -0
- local_deep_research/web/services/settings_service.py +2 -0
- local_deep_research/web/static/css/styles.css +8 -0
- local_deep_research/web/static/js/components/detail.js +7 -14
- local_deep_research/web/static/js/components/details.js +8 -10
- local_deep_research/web/static/js/components/fallback/ui.js +4 -4
- local_deep_research/web/static/js/components/history.js +6 -6
- local_deep_research/web/static/js/components/logpanel.js +14 -11
- local_deep_research/web/static/js/components/progress.js +51 -46
- local_deep_research/web/static/js/components/research.js +250 -89
- local_deep_research/web/static/js/components/results.js +5 -7
- local_deep_research/web/static/js/components/settings.js +32 -26
- local_deep_research/web/static/js/components/settings_sync.js +24 -23
- local_deep_research/web/static/js/config/urls.js +285 -0
- local_deep_research/web/static/js/main.js +8 -8
- local_deep_research/web/static/js/research_form.js +267 -12
- local_deep_research/web/static/js/services/api.js +18 -18
- local_deep_research/web/static/js/services/keyboard.js +8 -8
- local_deep_research/web/static/js/services/socket.js +53 -35
- local_deep_research/web/static/js/services/ui.js +1 -1
- local_deep_research/web/templates/base.html +4 -1
- local_deep_research/web/templates/components/custom_dropdown.html +5 -3
- local_deep_research/web/templates/components/mobile_nav.html +3 -3
- local_deep_research/web/templates/components/sidebar.html +9 -3
- local_deep_research/web/templates/pages/benchmark.html +2697 -0
- local_deep_research/web/templates/pages/benchmark_results.html +1136 -0
- local_deep_research/web/templates/pages/benchmark_simple.html +453 -0
- local_deep_research/web/templates/pages/cost_analytics.html +1 -1
- local_deep_research/web/templates/pages/metrics.html +212 -39
- local_deep_research/web/templates/pages/research.html +8 -6
- local_deep_research/web/templates/pages/star_reviews.html +1 -1
- local_deep_research/web_search_engines/engines/search_engine_arxiv.py +14 -1
- local_deep_research/web_search_engines/engines/search_engine_brave.py +15 -1
- local_deep_research/web_search_engines/engines/search_engine_ddg.py +20 -1
- local_deep_research/web_search_engines/engines/search_engine_google_pse.py +26 -2
- local_deep_research/web_search_engines/engines/search_engine_pubmed.py +15 -1
- local_deep_research/web_search_engines/engines/search_engine_retriever.py +192 -0
- local_deep_research/web_search_engines/engines/search_engine_tavily.py +307 -0
- local_deep_research/web_search_engines/rate_limiting/__init__.py +14 -0
- local_deep_research/web_search_engines/rate_limiting/__main__.py +9 -0
- local_deep_research/web_search_engines/rate_limiting/cli.py +209 -0
- local_deep_research/web_search_engines/rate_limiting/exceptions.py +21 -0
- local_deep_research/web_search_engines/rate_limiting/tracker.py +506 -0
- local_deep_research/web_search_engines/retriever_registry.py +108 -0
- local_deep_research/web_search_engines/search_engine_base.py +161 -43
- local_deep_research/web_search_engines/search_engine_factory.py +14 -0
- local_deep_research/web_search_engines/search_engines_config.py +20 -0
- local_deep_research-0.6.0.dist-info/METADATA +374 -0
- {local_deep_research-0.5.7.dist-info → local_deep_research-0.6.0.dist-info}/RECORD +90 -65
- local_deep_research-0.5.7.dist-info/METADATA +0 -420
- {local_deep_research-0.5.7.dist-info → local_deep_research-0.6.0.dist-info}/WHEEL +0 -0
- {local_deep_research-0.5.7.dist-info → local_deep_research-0.6.0.dist-info}/entry_points.txt +0 -0
- {local_deep_research-0.5.7.dist-info → local_deep_research-0.6.0.dist-info}/licenses/LICENSE +0 -0
@@ -32,7 +32,7 @@ window.socket = (function() {
|
|
32
32
|
try {
|
33
33
|
// Use polling only to avoid WebSocket issues
|
34
34
|
socket = io(baseUrl, {
|
35
|
-
path: '/
|
35
|
+
path: '/socket.io',
|
36
36
|
reconnection: true,
|
37
37
|
reconnectionDelay: 1000,
|
38
38
|
reconnectionAttempts: 5,
|
@@ -249,16 +249,8 @@ window.socket = (function() {
|
|
249
249
|
}
|
250
250
|
|
251
251
|
// Continue with normal progress update handling
|
252
|
-
//
|
253
|
-
|
254
|
-
researchEventHandlers[researchId].forEach(handler => {
|
255
|
-
try {
|
256
|
-
handler(data);
|
257
|
-
} catch (error) {
|
258
|
-
console.error('Error in progress update handler:', error);
|
259
|
-
}
|
260
|
-
});
|
261
|
-
}
|
252
|
+
// NOTE: We defer calling handlers until after we've processed log_entry data
|
253
|
+
// so that handlers can see the complete data including any log entries
|
262
254
|
|
263
255
|
// Handle special engine selection events
|
264
256
|
if (data.event === 'search_engine_selected' || (data.engine && data.result_count !== undefined)) {
|
@@ -319,8 +311,9 @@ window.socket = (function() {
|
|
319
311
|
logItem.metadata.phase === 'complete' ||
|
320
312
|
logItem.metadata.phase === 'search_complete' ||
|
321
313
|
logItem.metadata.is_milestone === true ||
|
322
|
-
logItem.metadata.type === 'milestone'
|
323
|
-
|
314
|
+
logItem.metadata.type === 'milestone' ||
|
315
|
+
logItem.metadata.type === 'MILESTONE') {
|
316
|
+
logType = 'MILESTONE';
|
324
317
|
} else if (logItem.metadata.phase === 'error' ||
|
325
318
|
logItem.metadata.type === 'error') {
|
326
319
|
logType = 'error';
|
@@ -375,6 +368,11 @@ window.socket = (function() {
|
|
375
368
|
if (data.log_entry) {
|
376
369
|
console.log('Adding log entry from socket event:', data.log_entry);
|
377
370
|
|
371
|
+
// Debug: Check if this is a milestone
|
372
|
+
if (data.log_entry.type === 'milestone' || data.log_entry.type === 'MILESTONE') {
|
373
|
+
console.log('MILESTONE LOG received:', data.log_entry.message);
|
374
|
+
}
|
375
|
+
|
378
376
|
// Make sure global tracking is initialized
|
379
377
|
window._processedSocketMessages = window._processedSocketMessages || new Map();
|
380
378
|
|
@@ -384,24 +382,25 @@ window.socket = (function() {
|
|
384
382
|
// Skip if we've seen this message before
|
385
383
|
if (window._processedSocketMessages.has(messageKey)) {
|
386
384
|
console.log('Skipping duplicate individual log entry:', data.log_entry.message);
|
387
|
-
return
|
388
|
-
|
389
|
-
|
390
|
-
// Record that we've processed this message
|
391
|
-
window._processedSocketMessages.set(messageKey, Date.now());
|
392
|
-
|
393
|
-
if (typeof window.addConsoleLog === 'function') {
|
394
|
-
window.addConsoleLog(
|
395
|
-
data.log_entry.message,
|
396
|
-
data.log_entry.type ||
|
397
|
-
(data.log_entry.metadata && data.log_entry.metadata.type) ||
|
398
|
-
'info',
|
399
|
-
data.log_entry.metadata
|
400
|
-
);
|
401
|
-
} else if (typeof window._socketAddLogEntry === 'function') {
|
402
|
-
window._socketAddLogEntry(data.log_entry);
|
385
|
+
// Don't return here - we still need to call handlers in case this is a milestone
|
386
|
+
// that should update the current task
|
403
387
|
} else {
|
404
|
-
|
388
|
+
// Record that we've processed this message
|
389
|
+
window._processedSocketMessages.set(messageKey, Date.now());
|
390
|
+
|
391
|
+
if (typeof window.addConsoleLog === 'function') {
|
392
|
+
window.addConsoleLog(
|
393
|
+
data.log_entry.message,
|
394
|
+
data.log_entry.type ||
|
395
|
+
(data.log_entry.metadata && data.log_entry.metadata.type) ||
|
396
|
+
'info',
|
397
|
+
data.log_entry.metadata
|
398
|
+
);
|
399
|
+
} else if (typeof window._socketAddLogEntry === 'function') {
|
400
|
+
window._socketAddLogEntry(data.log_entry);
|
401
|
+
} else {
|
402
|
+
console.warn('No log handler function available for direct log entry');
|
403
|
+
}
|
405
404
|
}
|
406
405
|
} else if (data.message && typeof window.addConsoleLog === 'function') {
|
407
406
|
// Use the message field if no specific log entry
|
@@ -411,13 +410,32 @@ window.socket = (function() {
|
|
411
410
|
const messageKey = `${new Date().toISOString()}-${data.message}`;
|
412
411
|
if (window._processedSocketMessages.has(messageKey)) {
|
413
412
|
console.log('Skipping duplicate message:', data.message);
|
414
|
-
return
|
415
|
-
}
|
413
|
+
// Don't return - still call handlers
|
414
|
+
} else {
|
415
|
+
// Record this message
|
416
|
+
window._processedSocketMessages.set(messageKey, Date.now());
|
416
417
|
|
417
|
-
|
418
|
-
|
418
|
+
window.addConsoleLog(data.message, determineLogLevel(data.status));
|
419
|
+
}
|
420
|
+
}
|
419
421
|
|
420
|
-
|
422
|
+
// Call all registered event handlers for this research AFTER processing all data
|
423
|
+
// This ensures handlers see the complete data including any log entries
|
424
|
+
if (researchEventHandlers[researchId]) {
|
425
|
+
console.log(`Calling ${researchEventHandlers[researchId].length} handlers for research ${researchId} with data:`, {
|
426
|
+
hasLogEntry: !!data.log_entry,
|
427
|
+
logType: data.log_entry?.type,
|
428
|
+
message: data.log_entry?.message?.substring(0, 50) + '...'
|
429
|
+
});
|
430
|
+
researchEventHandlers[researchId].forEach(handler => {
|
431
|
+
try {
|
432
|
+
handler(data);
|
433
|
+
} catch (error) {
|
434
|
+
console.error('Error in progress update handler:', error);
|
435
|
+
}
|
436
|
+
});
|
437
|
+
} else {
|
438
|
+
console.log(`No handlers registered for research ${researchId}`);
|
421
439
|
}
|
422
440
|
}
|
423
441
|
|
@@ -215,7 +215,7 @@ function processSpecialMarkdown(html) {
|
|
215
215
|
// Check if this is a reference to a generated image
|
216
216
|
if (ref.startsWith('image-')) {
|
217
217
|
return `<div class="generated-image" data-image-id="${ref}">
|
218
|
-
<img src="/
|
218
|
+
<img src="/static/img/generated/${ref}.png"
|
219
219
|
alt="Generated image ${ref}"
|
220
220
|
class="img-fluid"
|
221
221
|
loading="lazy" />
|
@@ -36,6 +36,9 @@
|
|
36
36
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
|
37
37
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js" integrity="sha512-BNaRQnYJYiPSqHHDb58B0yaPfCu+Wgds8Gp/gU33kqBtgNS4tSPHuGibyoeqMV/TJlSKda6FXzoEyYGjTe+vXA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
38
38
|
|
39
|
+
<!-- URL Configuration (must load first) -->
|
40
|
+
<script src="{{ url_for('research.serve_static', path='js/config/urls.js') }}"></script>
|
41
|
+
|
39
42
|
<!-- Core JS -->
|
40
43
|
<script src="{{ url_for('research.serve_static', path='js/services/formatting.js') }}"></script>
|
41
44
|
<script src="{{ url_for('research.serve_static', path='js/services/ui.js') }}"></script>
|
@@ -68,6 +71,6 @@
|
|
68
71
|
}
|
69
72
|
</script>
|
70
73
|
|
71
|
-
<script src="
|
74
|
+
<script src="{{ url_for('research.serve_static', path='js/components/settings_sync.js') }}"></script>
|
72
75
|
</body>
|
73
76
|
</html>
|
@@ -1,4 +1,4 @@
|
|
1
|
-
{% macro render_dropdown(input_id, dropdown_id, placeholder, label=None, help_text=None, allow_custom=False, show_refresh=False, refresh_aria_label="Refresh options", data_setting_key=None) %}
|
1
|
+
{% macro render_dropdown(input_id, dropdown_id, placeholder, label=None, help_text=None, allow_custom=False, show_refresh=False, refresh_aria_label="Refresh options", data_setting_key=None, data_initial_value=None) %}
|
2
2
|
<div class="form-group">
|
3
3
|
{% if label %}
|
4
4
|
<label for="{{ input_id }}">{{ label }}</label>
|
@@ -10,12 +10,13 @@
|
|
10
10
|
<input type="text"
|
11
11
|
id="{{ input_id }}"
|
12
12
|
data-key="{{ data_setting_key or input_id }}"
|
13
|
+
{% if data_initial_value %}data-initial-value="{{ data_initial_value }}"{% endif %}
|
13
14
|
class="custom-dropdown-input"
|
14
15
|
placeholder="{{ placeholder }}"
|
15
16
|
autocomplete="off"
|
16
17
|
aria-haspopup="listbox">
|
17
18
|
<!-- Hidden input that will be included in form submission -->
|
18
|
-
<input type="hidden" name="{{ input_id }}" id="{{ input_id }}_hidden" value="">
|
19
|
+
<input type="hidden" name="{{ input_id }}" id="{{ input_id }}_hidden" value="{{ data_initial_value or '' }}">
|
19
20
|
<div class="custom-dropdown-list" id="{{ dropdown_id }}-list"></div>
|
20
21
|
</div>
|
21
22
|
<button type="button"
|
@@ -30,12 +31,13 @@
|
|
30
31
|
<input type="text"
|
31
32
|
id="{{ input_id }}"
|
32
33
|
data-key="{{ data_setting_key or input_id }}"
|
34
|
+
{% if data_initial_value %}data-initial-value="{{ data_initial_value }}"{% endif %}
|
33
35
|
class="custom-dropdown-input"
|
34
36
|
placeholder="{{ placeholder }}"
|
35
37
|
autocomplete="off"
|
36
38
|
aria-haspopup="listbox">
|
37
39
|
<!-- Hidden input that will be included in form submission -->
|
38
|
-
<input type="hidden" name="{{ input_id }}" id="{{ input_id }}_hidden" value="">
|
40
|
+
<input type="hidden" name="{{ input_id }}" id="{{ input_id }}_hidden" value="{{ data_initial_value or '' }}">
|
39
41
|
<div class="custom-dropdown-list" id="{{ dropdown_id }}-list"></div>
|
40
42
|
</div>
|
41
43
|
{% endif %}
|
@@ -1,19 +1,19 @@
|
|
1
1
|
<nav class="mobile-tab-bar">
|
2
2
|
<ul>
|
3
3
|
<li {% if active_page == 'new-research' %}class="active"{% endif %} data-page="new-research">
|
4
|
-
<a href="
|
4
|
+
<a href="/">
|
5
5
|
<i class="fas fa-search"></i>
|
6
6
|
<span>Research</span>
|
7
7
|
</a>
|
8
8
|
</li>
|
9
9
|
<li {% if active_page == 'history' %}class="active"{% endif %} data-page="history">
|
10
|
-
<a href="{{ url_for('
|
10
|
+
<a href="{{ url_for('history.history_page') }}">
|
11
11
|
<i class="fas fa-history"></i>
|
12
12
|
<span>History</span>
|
13
13
|
</a>
|
14
14
|
</li>
|
15
15
|
<li {% if active_page == 'settings' %}class="active"{% endif %} data-page="settings">
|
16
|
-
<a href="{{ url_for('
|
16
|
+
<a href="{{ url_for('settings.settings_page') }}">
|
17
17
|
<i class="fas fa-cog"></i>
|
18
18
|
<span>Settings</span>
|
19
19
|
</a>
|
@@ -5,16 +5,22 @@
|
|
5
5
|
<nav class="sidebar-nav">
|
6
6
|
<ul>
|
7
7
|
<li {% if active_page == 'new-research' %}class="active"{% endif %} data-page="new-research">
|
8
|
-
<a href="
|
8
|
+
<a href="/"><i class="fas fa-search"></i> New Research</a>
|
9
9
|
</li>
|
10
10
|
<li {% if active_page == 'history' %}class="active"{% endif %} data-page="history">
|
11
|
-
<a href="{{ url_for('
|
11
|
+
<a href="{{ url_for('history.history_page') }}"><i class="fas fa-history"></i> History</a>
|
12
|
+
</li>
|
13
|
+
<li {% if active_page == 'benchmark' %}class="active"{% endif %} data-page="benchmark">
|
14
|
+
<a href="{{ url_for('benchmark.index') }}"><i class="fas fa-tachometer-alt"></i> Benchmark</a>
|
15
|
+
</li>
|
16
|
+
<li {% if active_page == 'benchmark-results' %}class="active"{% endif %} data-page="benchmark-results">
|
17
|
+
<a href="{{ url_for('benchmark.results') }}"><i class="fas fa-chart-line"></i> Benchmark Results</a>
|
12
18
|
</li>
|
13
19
|
<li {% if active_page == 'metrics' %}class="active"{% endif %} data-page="metrics">
|
14
20
|
<a href="{{ url_for('metrics.metrics_dashboard') }}"><i class="fas fa-chart-bar"></i> Metrics</a>
|
15
21
|
</li>
|
16
22
|
<li {% if active_page == 'settings' %}class="active"{% endif %} data-page="settings">
|
17
|
-
<a href="{{ url_for('
|
23
|
+
<a href="{{ url_for('settings.settings_page') }}"><i class="fas fa-cog"></i> Settings</a>
|
18
24
|
</li>
|
19
25
|
</ul>
|
20
26
|
</nav>
|