local-deep-research 0.5.0__py3-none-any.whl → 0.5.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- local_deep_research/__version__.py +1 -1
- local_deep_research/config/llm_config.py +61 -1
- local_deep_research/error_handling/__init__.py +13 -0
- local_deep_research/error_handling/error_reporter.py +236 -0
- local_deep_research/error_handling/report_generator.py +403 -0
- local_deep_research/web/database/migrations.py +16 -1
- local_deep_research/web/database/models.py +31 -31
- local_deep_research/web/models/database.py +13 -23
- local_deep_research/web/routes/history_routes.py +1 -1
- local_deep_research/web/routes/research_routes.py +65 -113
- local_deep_research/web/services/research_service.py +218 -160
- local_deep_research/web/static/js/components/progress.js +19 -13
- local_deep_research/web/static/js/components/results.js +1 -1
- local_deep_research/web/templates/pages/research.html +2 -2
- {local_deep_research-0.5.0.dist-info → local_deep_research-0.5.3.dist-info}/METADATA +1 -1
- {local_deep_research-0.5.0.dist-info → local_deep_research-0.5.3.dist-info}/RECORD +19 -17
- local_deep_research/test_migration.py +0 -188
- {local_deep_research-0.5.0.dist-info → local_deep_research-0.5.3.dist-info}/WHEEL +0 -0
- {local_deep_research-0.5.0.dist-info → local_deep_research-0.5.3.dist-info}/entry_points.txt +0 -0
- {local_deep_research-0.5.0.dist-info → local_deep_research-0.5.3.dist-info}/licenses/LICENSE +0 -0
@@ -15,13 +15,18 @@ from flask import (
|
|
15
15
|
)
|
16
16
|
from loguru import logger
|
17
17
|
|
18
|
-
from ..models.database import
|
18
|
+
from ..models.database import (
|
19
|
+
calculate_duration,
|
20
|
+
get_db_connection,
|
21
|
+
)
|
19
22
|
from ..services.research_service import (
|
20
23
|
run_research_process,
|
21
24
|
start_research_process,
|
22
25
|
)
|
23
26
|
from ..utils.templates import render_template_with_defaults
|
24
27
|
from .globals import active_research, termination_flags
|
28
|
+
from ..database.models import ResearchHistory, ResearchLog
|
29
|
+
from ...utilities.db_utils import get_db_session
|
25
30
|
|
26
31
|
# Create a Blueprint for the research application
|
27
32
|
research_bp = Blueprint("research", __name__, url_prefix="/research")
|
@@ -220,20 +225,19 @@ def start_research():
|
|
220
225
|
"questions_per_iteration": questions_per_iteration,
|
221
226
|
}
|
222
227
|
|
223
|
-
|
224
|
-
|
225
|
-
(
|
226
|
-
query,
|
227
|
-
mode,
|
228
|
-
"in_progress",
|
229
|
-
created_at,
|
230
|
-
|
231
|
-
|
232
|
-
)
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
conn.close()
|
228
|
+
db_session = get_db_session()
|
229
|
+
with db_session:
|
230
|
+
research = ResearchHistory(
|
231
|
+
query=query,
|
232
|
+
mode=mode,
|
233
|
+
status="in_progress",
|
234
|
+
created_at=created_at,
|
235
|
+
progress_log=[{"time": created_at, "progress": 0}],
|
236
|
+
research_meta=research_settings,
|
237
|
+
)
|
238
|
+
db_session.add(research)
|
239
|
+
db_session.commit()
|
240
|
+
research_id = research.id
|
237
241
|
|
238
242
|
# Start the research process with the selected parameters
|
239
243
|
research_thread = start_research_process(
|
@@ -612,59 +616,30 @@ def get_history():
|
|
612
616
|
|
613
617
|
@research_bp.route("/api/research/<int:research_id>")
|
614
618
|
def get_research_details(research_id):
|
615
|
-
"""Get full details of a research"""
|
619
|
+
"""Get full details of a research using ORM"""
|
616
620
|
try:
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
FROM research_history WHERE id = ?""",
|
623
|
-
(research_id,),
|
621
|
+
db_session = get_db_session()
|
622
|
+
research = (
|
623
|
+
db_session.query(ResearchHistory)
|
624
|
+
.filter(ResearchHistory.id == research_id)
|
625
|
+
.first()
|
624
626
|
)
|
625
|
-
result = cursor.fetchone()
|
626
627
|
|
627
|
-
if
|
628
|
-
conn.close()
|
628
|
+
if not research:
|
629
629
|
return jsonify({"error": "Research not found"}), 404
|
630
630
|
|
631
|
-
# Unpack the result
|
632
|
-
(
|
633
|
-
research_id,
|
634
|
-
query,
|
635
|
-
status,
|
636
|
-
progress,
|
637
|
-
mode,
|
638
|
-
created_at,
|
639
|
-
completed_at,
|
640
|
-
report_path,
|
641
|
-
metadata_str,
|
642
|
-
) = result
|
643
|
-
|
644
|
-
# Parse metadata if it exists
|
645
|
-
metadata = {}
|
646
|
-
if metadata_str:
|
647
|
-
try:
|
648
|
-
metadata = json.loads(metadata_str)
|
649
|
-
except json.JSONDecodeError:
|
650
|
-
logger.warning(
|
651
|
-
f"Invalid JSON in metadata for research {research_id}"
|
652
|
-
)
|
653
|
-
|
654
|
-
conn.close()
|
655
|
-
|
656
631
|
return jsonify(
|
657
632
|
{
|
658
|
-
"id":
|
659
|
-
"query": query,
|
660
|
-
"status": status,
|
661
|
-
"progress": progress,
|
662
|
-
"progress_percentage": progress or 0,
|
663
|
-
"mode": mode,
|
664
|
-
"created_at": created_at,
|
665
|
-
"completed_at": completed_at,
|
666
|
-
"report_path": report_path,
|
667
|
-
"metadata":
|
633
|
+
"id": research.id,
|
634
|
+
"query": research.query,
|
635
|
+
"status": research.status,
|
636
|
+
"progress": research.progress,
|
637
|
+
"progress_percentage": research.progress or 0,
|
638
|
+
"mode": research.mode,
|
639
|
+
"created_at": research.created_at,
|
640
|
+
"completed_at": research.completed_at,
|
641
|
+
"report_path": research.report_path,
|
642
|
+
"metadata": research.research_meta,
|
668
643
|
}
|
669
644
|
)
|
670
645
|
except Exception as e:
|
@@ -676,50 +651,36 @@ def get_research_details(research_id):
|
|
676
651
|
def get_research_logs(research_id):
|
677
652
|
"""Get logs for a specific research"""
|
678
653
|
try:
|
679
|
-
conn = get_db_connection()
|
680
|
-
cursor = conn.cursor()
|
681
|
-
|
682
654
|
# First check if the research exists
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
655
|
+
db_session = get_db_session()
|
656
|
+
with db_session:
|
657
|
+
research = (
|
658
|
+
db_session.query(ResearchHistory)
|
659
|
+
.filter_by(id=research_id)
|
660
|
+
.first()
|
661
|
+
)
|
662
|
+
if not research:
|
663
|
+
return jsonify({"error": "Research not found"}), 404
|
664
|
+
|
665
|
+
# Get logs from research_logs table
|
666
|
+
log_results = (
|
667
|
+
db_session.query(ResearchLog)
|
668
|
+
.filter_by(research_id=research_id)
|
669
|
+
.order_by(ResearchLog.timestamp)
|
670
|
+
.all()
|
671
|
+
)
|
698
672
|
|
699
673
|
logs = []
|
700
|
-
for row in
|
701
|
-
log_id, message, timestamp, log_type, progress, metadata_str = row
|
702
|
-
|
703
|
-
# Parse metadata if it exists
|
704
|
-
metadata = {}
|
705
|
-
if metadata_str:
|
706
|
-
try:
|
707
|
-
metadata = json.loads(metadata_str)
|
708
|
-
except json.JSONDecodeError:
|
709
|
-
pass
|
710
|
-
|
674
|
+
for row in log_results:
|
711
675
|
logs.append(
|
712
676
|
{
|
713
|
-
"id":
|
714
|
-
"message": message,
|
715
|
-
"timestamp": timestamp,
|
716
|
-
"log_type":
|
717
|
-
"progress": progress,
|
718
|
-
"metadata": metadata,
|
677
|
+
"id": row.id,
|
678
|
+
"message": row.message,
|
679
|
+
"timestamp": row.timestamp,
|
680
|
+
"log_type": row.level,
|
719
681
|
}
|
720
682
|
)
|
721
683
|
|
722
|
-
conn.close()
|
723
684
|
return jsonify(logs)
|
724
685
|
|
725
686
|
except Exception as e:
|
@@ -730,27 +691,18 @@ def get_research_logs(research_id):
|
|
730
691
|
@research_bp.route("/api/report/<int:research_id>")
|
731
692
|
def get_research_report(research_id):
|
732
693
|
"""Get the research report content"""
|
733
|
-
from ..database.models import Research
|
734
|
-
from ...utilities.db_utils import get_db_session
|
735
|
-
|
736
694
|
session = get_db_session()
|
737
695
|
try:
|
738
696
|
# Query using ORM
|
739
|
-
research =
|
697
|
+
research = (
|
698
|
+
session.query(ResearchHistory).filter_by(id=research_id).first()
|
699
|
+
)
|
740
700
|
|
741
701
|
if research is None:
|
742
702
|
return jsonify({"error": "Research not found"}), 404
|
743
703
|
|
744
704
|
# Parse metadata if it exists
|
745
|
-
metadata =
|
746
|
-
if research.metadata:
|
747
|
-
try:
|
748
|
-
metadata = json.loads(research.metadata)
|
749
|
-
except json.JSONDecodeError:
|
750
|
-
logger.warning(
|
751
|
-
f"Invalid JSON in metadata for research {research_id}"
|
752
|
-
)
|
753
|
-
|
705
|
+
metadata = research.research_meta
|
754
706
|
# Check if report file exists
|
755
707
|
if not research.report_path or not os.path.exists(research.report_path):
|
756
708
|
return jsonify({"error": "Report file not found"}), 404
|
@@ -771,11 +723,11 @@ def get_research_report(research_id):
|
|
771
723
|
"content": content,
|
772
724
|
"metadata": {
|
773
725
|
"query": research.query,
|
774
|
-
"mode": research.mode
|
775
|
-
"created_at": research.created_at
|
726
|
+
"mode": research.mode if research.mode else None,
|
727
|
+
"created_at": research.created_at
|
776
728
|
if research.created_at
|
777
729
|
else None,
|
778
|
-
"completed_at": research.completed_at
|
730
|
+
"completed_at": research.completed_at
|
779
731
|
if research.completed_at
|
780
732
|
else None,
|
781
733
|
"report_path": research.report_path,
|