local-deep-research 0.5.9__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 +32 -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 +447 -2
- 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/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.9.dist-info → local_deep_research-0.6.0.dist-info}/RECORD +89 -64
- local_deep_research-0.5.9.dist-info/METADATA +0 -420
- {local_deep_research-0.5.9.dist-info → local_deep_research-0.6.0.dist-info}/WHEEL +0 -0
- {local_deep_research-0.5.9.dist-info → local_deep_research-0.6.0.dist-info}/entry_points.txt +0 -0
- {local_deep_research-0.5.9.dist-info → local_deep_research-0.6.0.dist-info}/licenses/LICENSE +0 -0
@@ -63,14 +63,7 @@
|
|
63
63
|
* @returns {string|null} Research ID or null if not found
|
64
64
|
*/
|
65
65
|
function getResearchIdFromUrl() {
|
66
|
-
|
67
|
-
const detailsIndex = pathParts.indexOf('details');
|
68
|
-
|
69
|
-
if (detailsIndex > 0 && detailsIndex + 1 < pathParts.length) {
|
70
|
-
return pathParts[detailsIndex + 1];
|
71
|
-
}
|
72
|
-
|
73
|
-
return null;
|
66
|
+
return URLBuilder.extractResearchIdFromPattern('details');
|
74
67
|
}
|
75
68
|
|
76
69
|
/**
|
@@ -80,14 +73,14 @@
|
|
80
73
|
const viewResultsButton = document.getElementById('view-results-btn');
|
81
74
|
if (viewResultsButton) {
|
82
75
|
viewResultsButton.addEventListener('click', function() {
|
83
|
-
window.location.href =
|
76
|
+
window.location.href = URLBuilder.resultsPage(currentResearchId);
|
84
77
|
});
|
85
78
|
}
|
86
79
|
|
87
80
|
const backButton = document.getElementById('back-to-history-from-details');
|
88
81
|
if (backButton) {
|
89
82
|
backButton.addEventListener('click', function() {
|
90
|
-
window.location.href =
|
83
|
+
window.location.href = URLS.PAGES.HISTORY;
|
91
84
|
});
|
92
85
|
}
|
93
86
|
}
|
@@ -99,7 +92,7 @@
|
|
99
92
|
console.log('Loading basic research details...');
|
100
93
|
|
101
94
|
try {
|
102
|
-
const response = await fetch(
|
95
|
+
const response = await fetch(URLBuilder.researchDetails(currentResearchId), {
|
103
96
|
headers: {
|
104
97
|
'Accept': 'application/json'
|
105
98
|
}
|
@@ -130,7 +123,7 @@
|
|
130
123
|
|
131
124
|
try {
|
132
125
|
// Fetch research details
|
133
|
-
const response = await fetch(
|
126
|
+
const response = await fetch(URLBuilder.researchDetails(currentResearchId), {
|
134
127
|
headers: {
|
135
128
|
'Accept': 'application/json'
|
136
129
|
}
|
@@ -202,7 +195,7 @@
|
|
202
195
|
console.log('Loading search metrics...');
|
203
196
|
|
204
197
|
try {
|
205
|
-
const response = await fetch(
|
198
|
+
const response = await fetch(URLBuilder.build(URLS.METRICS_API.RESEARCH_SEARCH, currentResearchId), {
|
206
199
|
headers: {
|
207
200
|
'Accept': 'application/json'
|
208
201
|
}
|
@@ -354,7 +347,7 @@
|
|
354
347
|
console.log('Loading token metrics...');
|
355
348
|
|
356
349
|
try {
|
357
|
-
const response = await fetch(
|
350
|
+
const response = await fetch(URLBuilder.build(URLS.METRICS_API.RESEARCH_TIMELINE, currentResearchId), {
|
358
351
|
headers: {
|
359
352
|
'Accept': 'application/json'
|
360
353
|
}
|
@@ -28,9 +28,7 @@
|
|
28
28
|
|
29
29
|
// Get research ID from URL
|
30
30
|
function getResearchIdFromUrl() {
|
31
|
-
|
32
|
-
const match = path.match(/\/research\/details\/(\d+)/);
|
33
|
-
return match ? parseInt(match[1]) : null;
|
31
|
+
return URLBuilder.extractResearchIdFromPattern('details');
|
34
32
|
}
|
35
33
|
|
36
34
|
// Load research metrics data
|
@@ -45,7 +43,7 @@
|
|
45
43
|
|
46
44
|
// Load research details (includes strategy)
|
47
45
|
console.log('Fetching research details...');
|
48
|
-
const detailsResponse = await fetch(
|
46
|
+
const detailsResponse = await fetch(URLBuilder.historyDetails(researchId));
|
49
47
|
console.log('Details response status:', detailsResponse.status);
|
50
48
|
|
51
49
|
let researchDetails = null;
|
@@ -56,7 +54,7 @@
|
|
56
54
|
|
57
55
|
// Load research metrics
|
58
56
|
console.log('Fetching research metrics...');
|
59
|
-
const metricsResponse = await fetch(
|
57
|
+
const metricsResponse = await fetch(URLBuilder.build(URLS.METRICS_API.RESEARCH, researchId));
|
60
58
|
console.log('Metrics response status:', metricsResponse.status);
|
61
59
|
|
62
60
|
if (!metricsResponse.ok) {
|
@@ -80,7 +78,7 @@
|
|
80
78
|
|
81
79
|
// Load timeline metrics
|
82
80
|
console.log('Fetching timeline metrics...');
|
83
|
-
const timelineResponse = await fetch(
|
81
|
+
const timelineResponse = await fetch(URLBuilder.build(URLS.METRICS_API.RESEARCH_TIMELINE, researchId));
|
84
82
|
console.log('Timeline response status:', timelineResponse.status);
|
85
83
|
|
86
84
|
let timelineData = null;
|
@@ -94,7 +92,7 @@
|
|
94
92
|
|
95
93
|
// Load search metrics
|
96
94
|
console.log('Fetching search metrics...');
|
97
|
-
const searchResponse = await fetch(
|
95
|
+
const searchResponse = await fetch(URLBuilder.build(URLS.METRICS_API.RESEARCH_SEARCH, researchId));
|
98
96
|
console.log('Search response status:', searchResponse.status);
|
99
97
|
|
100
98
|
let searchData = null;
|
@@ -662,7 +660,7 @@
|
|
662
660
|
document.getElementById('total-cost').textContent = '-';
|
663
661
|
return;
|
664
662
|
|
665
|
-
const response = await fetch(
|
663
|
+
const response = await fetch(URLBuilder.build(URLS.METRICS_API.RESEARCH_COSTS, researchId));
|
666
664
|
if (response.ok) {
|
667
665
|
const data = await response.json();
|
668
666
|
if (data.status === 'success') {
|
@@ -735,7 +733,7 @@
|
|
735
733
|
const viewResultsBtn = document.getElementById('view-results-btn');
|
736
734
|
if (viewResultsBtn) {
|
737
735
|
viewResultsBtn.addEventListener('click', () => {
|
738
|
-
window.location.href =
|
736
|
+
window.location.href = URLBuilder.resultsPage(researchId);
|
739
737
|
});
|
740
738
|
}
|
741
739
|
|
@@ -743,7 +741,7 @@
|
|
743
741
|
const backBtn = document.getElementById('back-to-history');
|
744
742
|
if (backBtn) {
|
745
743
|
backBtn.addEventListener('click', () => {
|
746
|
-
window.location.href =
|
744
|
+
window.location.href = URLS.PAGES.HISTORY;
|
747
745
|
});
|
748
746
|
}
|
749
747
|
});
|
@@ -183,16 +183,16 @@
|
|
183
183
|
let iconPath;
|
184
184
|
switch (status) {
|
185
185
|
case 'active':
|
186
|
-
iconPath = '/
|
186
|
+
iconPath = '/static/img/favicon-active.ico';
|
187
187
|
break;
|
188
188
|
case 'complete':
|
189
|
-
iconPath = '/
|
189
|
+
iconPath = '/static/img/favicon-complete.ico';
|
190
190
|
break;
|
191
191
|
case 'error':
|
192
|
-
iconPath = '/
|
192
|
+
iconPath = '/static/img/favicon-error.ico';
|
193
193
|
break;
|
194
194
|
default:
|
195
|
-
iconPath = '/
|
195
|
+
iconPath = '/static/img/favicon.ico';
|
196
196
|
}
|
197
197
|
|
198
198
|
// Add cache busting parameter to force reload
|
@@ -74,7 +74,7 @@
|
|
74
74
|
|
75
75
|
// Fallback implementation
|
76
76
|
try {
|
77
|
-
const response = await fetch(
|
77
|
+
const response = await fetch(URLS.API.HISTORY);
|
78
78
|
if (!response.ok) {
|
79
79
|
throw new Error(`API Error: ${response.status} ${response.statusText}`);
|
80
80
|
}
|
@@ -92,7 +92,7 @@
|
|
92
92
|
|
93
93
|
// Fallback implementation
|
94
94
|
try {
|
95
|
-
const response = await fetch(`/
|
95
|
+
const response = await fetch(`/api/delete/${researchId}`, {
|
96
96
|
method: 'DELETE'
|
97
97
|
});
|
98
98
|
if (!response.ok) {
|
@@ -112,7 +112,7 @@
|
|
112
112
|
|
113
113
|
// Fallback implementation
|
114
114
|
try {
|
115
|
-
const response = await fetch(
|
115
|
+
const response = await fetch(URLS.API.CLEAR_HISTORY, {
|
116
116
|
method: 'POST',
|
117
117
|
headers: {
|
118
118
|
'Content-Type': 'application/json'
|
@@ -352,7 +352,7 @@
|
|
352
352
|
if (viewBtn) {
|
353
353
|
viewBtn.addEventListener('click', (e) => {
|
354
354
|
e.stopPropagation(); // Prevent item click
|
355
|
-
window.location.href =
|
355
|
+
window.location.href = URLBuilder.resultsPage(item.id);
|
356
356
|
});
|
357
357
|
}
|
358
358
|
|
@@ -367,9 +367,9 @@
|
|
367
367
|
// Add click event to the whole item
|
368
368
|
itemEl.addEventListener('click', () => {
|
369
369
|
if (item.status === 'completed') {
|
370
|
-
window.location.href =
|
370
|
+
window.location.href = URLBuilder.resultsPage(item.id);
|
371
371
|
} else {
|
372
|
-
window.location.href =
|
372
|
+
window.location.href = URLBuilder.progressPage(item.id);
|
373
373
|
}
|
374
374
|
});
|
375
375
|
|
@@ -43,8 +43,8 @@
|
|
43
43
|
console.log('Initializing shared log panel, research ID:', researchId);
|
44
44
|
|
45
45
|
// Check if we're on a research-specific page (progress, results)
|
46
|
-
const isResearchPage = window.location.pathname.includes('/
|
47
|
-
window.location.pathname.includes('/
|
46
|
+
const isResearchPage = window.location.pathname.includes('/progress/') ||
|
47
|
+
window.location.pathname.includes('/results/') ||
|
48
48
|
document.getElementById('research-progress') ||
|
49
49
|
document.getElementById('research-results');
|
50
50
|
|
@@ -199,7 +199,7 @@
|
|
199
199
|
});
|
200
200
|
|
201
201
|
// Fetch the log count from the API and update the indicators
|
202
|
-
fetch(`/
|
202
|
+
fetch(`/history/log_count/${researchId}`)
|
203
203
|
.then(response => response.json())
|
204
204
|
.then(data => {
|
205
205
|
console.log('Log count data:', data);
|
@@ -299,7 +299,7 @@
|
|
299
299
|
*/
|
300
300
|
async function fetchLogsForResearch(researchId) {
|
301
301
|
// Fetch logs from API
|
302
|
-
const response = await fetch(
|
302
|
+
const response = await fetch(URLBuilder.researchLogs(researchId));
|
303
303
|
return await response.json();
|
304
304
|
}
|
305
305
|
|
@@ -407,11 +407,14 @@
|
|
407
407
|
}
|
408
408
|
|
409
409
|
// Standard logs array processing
|
410
|
-
if
|
411
|
-
|
410
|
+
// Check if data is directly an array (new format) or has a logs property (old format)
|
411
|
+
const logsArray = Array.isArray(data) ? data : (data && data.logs);
|
412
|
+
|
413
|
+
if (logsArray && Array.isArray(logsArray)) {
|
414
|
+
console.log(`Processing ${logsArray.length} standard logs`);
|
412
415
|
|
413
416
|
// Process each standard log
|
414
|
-
|
417
|
+
logsArray.forEach(log => {
|
415
418
|
if (!log.timestamp && !log.time) return; // Skip invalid logs
|
416
419
|
|
417
420
|
// Skip duplicates based on message content
|
@@ -437,7 +440,7 @@
|
|
437
440
|
id: `${log.timestamp || log.time}-${hashString(log.message || log.content || '')}`,
|
438
441
|
time: log.timestamp || log.time,
|
439
442
|
message: log.message || log.content || 'No message',
|
440
|
-
type: log.type || log.level || 'info',
|
443
|
+
type: log.log_type || log.type || log.level || 'info',
|
441
444
|
metadata: log.metadata || {},
|
442
445
|
source: 'standard_logs'
|
443
446
|
};
|
@@ -972,7 +975,7 @@
|
|
972
975
|
|
973
976
|
// Find research ID from URL if available
|
974
977
|
let researchId = null;
|
975
|
-
const urlMatch = window.location.pathname.match(/\/
|
978
|
+
const urlMatch = window.location.pathname.match(/\/(progress|results)\/(\d+)/);
|
976
979
|
if (urlMatch && urlMatch[2]) {
|
977
980
|
researchId = urlMatch[2];
|
978
981
|
console.log('Found research ID in URL:', researchId);
|
@@ -982,8 +985,8 @@
|
|
982
985
|
}
|
983
986
|
|
984
987
|
// Check for research page elements
|
985
|
-
const isResearchPage = window.location.pathname.includes('/
|
986
|
-
window.location.pathname.includes('/
|
988
|
+
const isResearchPage = window.location.pathname.includes('/progress/') ||
|
989
|
+
window.location.pathname.includes('/results/') ||
|
987
990
|
document.getElementById('research-progress') ||
|
988
991
|
document.getElementById('research-results');
|
989
992
|
|
@@ -35,7 +35,7 @@
|
|
35
35
|
*/
|
36
36
|
function initializeProgress() {
|
37
37
|
// Get research ID from URL or localStorage
|
38
|
-
currentResearchId = getResearchIdFromUrl()
|
38
|
+
currentResearchId = getResearchIdFromUrl(); // Only from URL, not localStorage
|
39
39
|
|
40
40
|
if (!currentResearchId) {
|
41
41
|
console.error('No research ID found');
|
@@ -105,7 +105,7 @@
|
|
105
105
|
console.log('Progress component initialized for research ID:', currentResearchId);
|
106
106
|
|
107
107
|
// Get notification preference
|
108
|
-
notificationsEnabled =
|
108
|
+
notificationsEnabled = true; // Default to enabled
|
109
109
|
|
110
110
|
// Get initial research status
|
111
111
|
getInitialStatus();
|
@@ -202,14 +202,7 @@
|
|
202
202
|
* @returns {string|null} The research ID or null if not found
|
203
203
|
*/
|
204
204
|
function getResearchIdFromUrl() {
|
205
|
-
|
206
|
-
const idIndex = pathParts.indexOf('progress') + 1;
|
207
|
-
|
208
|
-
if (idIndex > 0 && idIndex < pathParts.length) {
|
209
|
-
return pathParts[idIndex];
|
210
|
-
}
|
211
|
-
|
212
|
-
return null;
|
205
|
+
return URLBuilder.extractResearchIdFromPattern('progress');
|
213
206
|
}
|
214
207
|
|
215
208
|
/**
|
@@ -284,6 +277,15 @@
|
|
284
277
|
function handleProgressUpdate(data) {
|
285
278
|
console.log('Received progress update:', data);
|
286
279
|
|
280
|
+
// Debug: Log if this is a log_entry update
|
281
|
+
if (data && data.log_entry) {
|
282
|
+
console.log('Progress update contains log_entry:', {
|
283
|
+
type: data.log_entry.type,
|
284
|
+
message: data.log_entry.message,
|
285
|
+
hasOtherFields: Object.keys(data).filter(k => k !== 'log_entry').length > 0
|
286
|
+
});
|
287
|
+
}
|
288
|
+
|
287
289
|
if (!data) return;
|
288
290
|
|
289
291
|
// Process progress_log if available and add to logs
|
@@ -310,9 +312,25 @@
|
|
310
312
|
}
|
311
313
|
}
|
312
314
|
|
313
|
-
//
|
315
|
+
// Check if this is a milestone log that should update the current task
|
316
|
+
let milestoneTask = null;
|
317
|
+
if (data.log_entry && (data.log_entry.type === 'milestone' || data.log_entry.type === 'MILESTONE') && data.log_entry.message) {
|
318
|
+
// Milestone logs should always update the current task
|
319
|
+
milestoneTask = data.log_entry.message;
|
320
|
+
console.log('Milestone task detected:', milestoneTask);
|
321
|
+
}
|
322
|
+
|
323
|
+
// Update progress UI (but preserve milestone task)
|
314
324
|
updateProgressUI(data);
|
315
325
|
|
326
|
+
// If we have a milestone task, make sure it's set after updateProgressUI
|
327
|
+
if (milestoneTask && currentTaskText) {
|
328
|
+
console.log('Setting milestone task:', milestoneTask);
|
329
|
+
currentTaskText.textContent = milestoneTask;
|
330
|
+
currentTaskText.dataset.lastMessage = milestoneTask;
|
331
|
+
currentTaskText.dataset.isMilestone = 'true';
|
332
|
+
}
|
333
|
+
|
316
334
|
// Check if research is completed
|
317
335
|
if (data.status === 'completed' || data.status === 'failed' || data.status === 'cancelled') {
|
318
336
|
handleResearchCompletion(data);
|
@@ -320,29 +338,8 @@
|
|
320
338
|
|
321
339
|
// Update the current query text if available
|
322
340
|
const currentQueryEl = document.getElementById('current-query');
|
323
|
-
if (currentQueryEl &&
|
324
|
-
currentQueryEl.textContent =
|
325
|
-
}
|
326
|
-
|
327
|
-
// Check for task message updates with better fallbacks
|
328
|
-
let taskUpdated = false;
|
329
|
-
|
330
|
-
if (data.task_message && data.task_message.trim() !== '') {
|
331
|
-
// Direct task message is highest priority
|
332
|
-
setCurrentTask(data.task_message);
|
333
|
-
taskUpdated = true;
|
334
|
-
} else if (data.current_task && data.current_task.trim() !== '') {
|
335
|
-
// Then try current_task field
|
336
|
-
setCurrentTask(data.current_task);
|
337
|
-
taskUpdated = true;
|
338
|
-
} else if (data.message && data.message.trim() !== '') {
|
339
|
-
// Finally fall back to general message
|
340
|
-
// But only if it's informative (not just a status update)
|
341
|
-
const msg = data.message.toLowerCase();
|
342
|
-
if (!msg.includes('in progress') && !msg.includes('status update')) {
|
343
|
-
setCurrentTask(data.message);
|
344
|
-
taskUpdated = true;
|
345
|
-
}
|
341
|
+
if (currentQueryEl && data.query) {
|
342
|
+
currentQueryEl.textContent = data.query;
|
346
343
|
}
|
347
344
|
|
348
345
|
// If no task info was provided, leave the current task as is
|
@@ -457,7 +454,8 @@
|
|
457
454
|
switch (data.status) {
|
458
455
|
case 'in_progress':
|
459
456
|
// Don't show "In Progress" at all in status text
|
460
|
-
|
457
|
+
formattedStatus = null; // Don't update status text for in_progress
|
458
|
+
break;
|
461
459
|
case 'completed':
|
462
460
|
formattedStatus = 'Completed';
|
463
461
|
break;
|
@@ -510,19 +508,25 @@
|
|
510
508
|
|
511
509
|
// Check various fields that might contain the current task message
|
512
510
|
if (!taskMessage) {
|
513
|
-
|
514
|
-
if (data.
|
511
|
+
// First check for milestone in log_entry
|
512
|
+
if (data.log_entry && data.log_entry.message && (data.log_entry.type === "milestone" || data.log_entry.type === "MILESTONE")) {
|
513
|
+
taskMessage = data.log_entry.message;
|
514
|
+
specificProgressMessage = true;
|
515
|
+
} else if (data.current_task) {
|
515
516
|
taskMessage = data.current_task;
|
517
|
+
specificProgressMessage = true;
|
516
518
|
} else if (data.message) {
|
517
519
|
taskMessage = data.message;
|
520
|
+
specificProgressMessage = true;
|
518
521
|
} else if (data.task) {
|
519
522
|
taskMessage = data.task;
|
523
|
+
specificProgressMessage = true;
|
520
524
|
} else if (data.step) {
|
521
525
|
taskMessage = data.step;
|
526
|
+
specificProgressMessage = true;
|
522
527
|
} else if (data.phase) {
|
523
528
|
taskMessage = `Phase: ${data.phase}`;
|
524
|
-
|
525
|
-
taskMessage = data.log_entry.message;
|
529
|
+
specificProgressMessage = true;
|
526
530
|
} else {
|
527
531
|
specificProgressMessage = false;
|
528
532
|
}
|
@@ -538,7 +542,8 @@
|
|
538
542
|
|
539
543
|
// If no message but we have a status, generate a more descriptive message
|
540
544
|
// BUT ONLY if we don't already have a meaningful message displayed
|
541
|
-
if (!specificProgressMessage && data.status &&
|
545
|
+
if (!specificProgressMessage && data.status &&
|
546
|
+
(!currentTaskText.dataset.lastMessage || currentTaskText.textContent === 'In Progress')) {
|
542
547
|
let statusMsg;
|
543
548
|
switch (data.status) {
|
544
549
|
case 'starting':
|
@@ -592,7 +597,7 @@
|
|
592
597
|
}
|
593
598
|
|
594
599
|
// Show notification if enabled
|
595
|
-
if (data.status === 'completed' &&
|
600
|
+
if (data.status === 'completed' && notificationsEnabled) {
|
596
601
|
showNotification('Research Completed', 'Your research has been completed successfully.');
|
597
602
|
}
|
598
603
|
|
@@ -622,7 +627,7 @@
|
|
622
627
|
// Show view results button
|
623
628
|
if (viewResultsButton) {
|
624
629
|
viewResultsButton.style.display = 'inline-block';
|
625
|
-
viewResultsButton.href =
|
630
|
+
viewResultsButton.href = URLBuilder.resultsPage(currentResearchId);
|
626
631
|
}
|
627
632
|
|
628
633
|
// Hide cancel button
|
@@ -634,7 +639,7 @@
|
|
634
639
|
if (data.status === 'failed') {
|
635
640
|
if (viewResultsButton) {
|
636
641
|
viewResultsButton.textContent = 'View Error Report';
|
637
|
-
viewResultsButton.href =
|
642
|
+
viewResultsButton.href = URLBuilder.resultsPage(currentResearchId);
|
638
643
|
viewResultsButton.style.display = 'inline-block';
|
639
644
|
}
|
640
645
|
} else {
|
@@ -731,7 +736,7 @@
|
|
731
736
|
try {
|
732
737
|
const notification = new Notification(title, {
|
733
738
|
body: message,
|
734
|
-
icon: type === 'error' ? '/
|
739
|
+
icon: type === 'error' ? '/static/img/error-icon.png' : '/static/img/favicon.png'
|
735
740
|
});
|
736
741
|
|
737
742
|
// Auto-close after 10 seconds
|
@@ -746,7 +751,7 @@
|
|
746
751
|
if (permission === 'granted') {
|
747
752
|
new Notification(title, {
|
748
753
|
body: message,
|
749
|
-
icon: type === 'error' ? '/
|
754
|
+
icon: type === 'error' ? '/static/img/error-icon.png' : '/static/img/favicon.png'
|
750
755
|
});
|
751
756
|
}
|
752
757
|
});
|
@@ -922,7 +927,7 @@
|
|
922
927
|
// Show error report button
|
923
928
|
if (viewResultsButton) {
|
924
929
|
viewResultsButton.textContent = 'View Error Report';
|
925
|
-
viewResultsButton.href =
|
930
|
+
viewResultsButton.href = URLBuilder.resultsPage(currentResearchId);
|
926
931
|
viewResultsButton.style.display = 'inline-block';
|
927
932
|
}
|
928
933
|
|