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.
Files changed (140) hide show
  1. local_deep_research/__init__.py +23 -22
  2. local_deep_research/__main__.py +16 -0
  3. local_deep_research/advanced_search_system/__init__.py +7 -0
  4. local_deep_research/advanced_search_system/filters/__init__.py +8 -0
  5. local_deep_research/advanced_search_system/filters/base_filter.py +38 -0
  6. local_deep_research/advanced_search_system/filters/cross_engine_filter.py +200 -0
  7. local_deep_research/advanced_search_system/findings/base_findings.py +81 -0
  8. local_deep_research/advanced_search_system/findings/repository.py +452 -0
  9. local_deep_research/advanced_search_system/knowledge/__init__.py +1 -0
  10. local_deep_research/advanced_search_system/knowledge/base_knowledge.py +151 -0
  11. local_deep_research/advanced_search_system/knowledge/standard_knowledge.py +159 -0
  12. local_deep_research/advanced_search_system/questions/__init__.py +1 -0
  13. local_deep_research/advanced_search_system/questions/base_question.py +64 -0
  14. local_deep_research/advanced_search_system/questions/decomposition_question.py +445 -0
  15. local_deep_research/advanced_search_system/questions/standard_question.py +119 -0
  16. local_deep_research/advanced_search_system/repositories/__init__.py +7 -0
  17. local_deep_research/advanced_search_system/strategies/__init__.py +1 -0
  18. local_deep_research/advanced_search_system/strategies/base_strategy.py +118 -0
  19. local_deep_research/advanced_search_system/strategies/iterdrag_strategy.py +450 -0
  20. local_deep_research/advanced_search_system/strategies/parallel_search_strategy.py +312 -0
  21. local_deep_research/advanced_search_system/strategies/rapid_search_strategy.py +270 -0
  22. local_deep_research/advanced_search_system/strategies/standard_strategy.py +300 -0
  23. local_deep_research/advanced_search_system/tools/__init__.py +1 -0
  24. local_deep_research/advanced_search_system/tools/base_tool.py +100 -0
  25. local_deep_research/advanced_search_system/tools/knowledge_tools/__init__.py +1 -0
  26. local_deep_research/advanced_search_system/tools/question_tools/__init__.py +1 -0
  27. local_deep_research/advanced_search_system/tools/search_tools/__init__.py +1 -0
  28. local_deep_research/api/__init__.py +5 -5
  29. local_deep_research/api/research_functions.py +96 -84
  30. local_deep_research/app.py +8 -0
  31. local_deep_research/citation_handler.py +25 -16
  32. local_deep_research/{config.py → config/config_files.py} +102 -110
  33. local_deep_research/config/llm_config.py +472 -0
  34. local_deep_research/config/search_config.py +77 -0
  35. local_deep_research/defaults/__init__.py +10 -5
  36. local_deep_research/defaults/main.toml +2 -2
  37. local_deep_research/defaults/search_engines.toml +60 -34
  38. local_deep_research/main.py +121 -19
  39. local_deep_research/migrate_db.py +147 -0
  40. local_deep_research/report_generator.py +72 -44
  41. local_deep_research/search_system.py +147 -283
  42. local_deep_research/setup_data_dir.py +35 -0
  43. local_deep_research/test_migration.py +178 -0
  44. local_deep_research/utilities/__init__.py +0 -0
  45. local_deep_research/utilities/db_utils.py +49 -0
  46. local_deep_research/{utilties → utilities}/enums.py +2 -2
  47. local_deep_research/{utilties → utilities}/llm_utils.py +63 -29
  48. local_deep_research/utilities/search_utilities.py +242 -0
  49. local_deep_research/{utilties → utilities}/setup_utils.py +4 -2
  50. local_deep_research/web/__init__.py +0 -1
  51. local_deep_research/web/app.py +86 -1709
  52. local_deep_research/web/app_factory.py +289 -0
  53. local_deep_research/web/database/README.md +70 -0
  54. local_deep_research/web/database/migrate_to_ldr_db.py +289 -0
  55. local_deep_research/web/database/migrations.py +447 -0
  56. local_deep_research/web/database/models.py +117 -0
  57. local_deep_research/web/database/schema_upgrade.py +107 -0
  58. local_deep_research/web/models/database.py +294 -0
  59. local_deep_research/web/models/settings.py +94 -0
  60. local_deep_research/web/routes/api_routes.py +559 -0
  61. local_deep_research/web/routes/history_routes.py +354 -0
  62. local_deep_research/web/routes/research_routes.py +715 -0
  63. local_deep_research/web/routes/settings_routes.py +1592 -0
  64. local_deep_research/web/services/research_service.py +947 -0
  65. local_deep_research/web/services/resource_service.py +149 -0
  66. local_deep_research/web/services/settings_manager.py +669 -0
  67. local_deep_research/web/services/settings_service.py +187 -0
  68. local_deep_research/web/services/socket_service.py +210 -0
  69. local_deep_research/web/static/css/custom_dropdown.css +277 -0
  70. local_deep_research/web/static/css/settings.css +1223 -0
  71. local_deep_research/web/static/css/styles.css +525 -48
  72. local_deep_research/web/static/js/components/custom_dropdown.js +428 -0
  73. local_deep_research/web/static/js/components/detail.js +348 -0
  74. local_deep_research/web/static/js/components/fallback/formatting.js +122 -0
  75. local_deep_research/web/static/js/components/fallback/ui.js +215 -0
  76. local_deep_research/web/static/js/components/history.js +487 -0
  77. local_deep_research/web/static/js/components/logpanel.js +949 -0
  78. local_deep_research/web/static/js/components/progress.js +1107 -0
  79. local_deep_research/web/static/js/components/research.js +1865 -0
  80. local_deep_research/web/static/js/components/results.js +766 -0
  81. local_deep_research/web/static/js/components/settings.js +3981 -0
  82. local_deep_research/web/static/js/components/settings_sync.js +106 -0
  83. local_deep_research/web/static/js/main.js +226 -0
  84. local_deep_research/web/static/js/services/api.js +253 -0
  85. local_deep_research/web/static/js/services/audio.js +31 -0
  86. local_deep_research/web/static/js/services/formatting.js +119 -0
  87. local_deep_research/web/static/js/services/pdf.js +622 -0
  88. local_deep_research/web/static/js/services/socket.js +882 -0
  89. local_deep_research/web/static/js/services/ui.js +546 -0
  90. local_deep_research/web/templates/base.html +72 -0
  91. local_deep_research/web/templates/components/custom_dropdown.html +47 -0
  92. local_deep_research/web/templates/components/log_panel.html +32 -0
  93. local_deep_research/web/templates/components/mobile_nav.html +22 -0
  94. local_deep_research/web/templates/components/settings_form.html +299 -0
  95. local_deep_research/web/templates/components/sidebar.html +21 -0
  96. local_deep_research/web/templates/pages/details.html +73 -0
  97. local_deep_research/web/templates/pages/history.html +51 -0
  98. local_deep_research/web/templates/pages/progress.html +57 -0
  99. local_deep_research/web/templates/pages/research.html +139 -0
  100. local_deep_research/web/templates/pages/results.html +59 -0
  101. local_deep_research/web/templates/settings_dashboard.html +78 -192
  102. local_deep_research/web/utils/__init__.py +0 -0
  103. local_deep_research/web/utils/formatters.py +76 -0
  104. local_deep_research/web_search_engines/engines/full_search.py +18 -16
  105. local_deep_research/web_search_engines/engines/meta_search_engine.py +182 -131
  106. local_deep_research/web_search_engines/engines/search_engine_arxiv.py +224 -139
  107. local_deep_research/web_search_engines/engines/search_engine_brave.py +88 -71
  108. local_deep_research/web_search_engines/engines/search_engine_ddg.py +48 -39
  109. local_deep_research/web_search_engines/engines/search_engine_github.py +415 -204
  110. local_deep_research/web_search_engines/engines/search_engine_google_pse.py +123 -90
  111. local_deep_research/web_search_engines/engines/search_engine_guardian.py +210 -157
  112. local_deep_research/web_search_engines/engines/search_engine_local.py +532 -369
  113. local_deep_research/web_search_engines/engines/search_engine_local_all.py +42 -36
  114. local_deep_research/web_search_engines/engines/search_engine_pubmed.py +358 -266
  115. local_deep_research/web_search_engines/engines/search_engine_searxng.py +211 -159
  116. local_deep_research/web_search_engines/engines/search_engine_semantic_scholar.py +213 -170
  117. local_deep_research/web_search_engines/engines/search_engine_serpapi.py +84 -68
  118. local_deep_research/web_search_engines/engines/search_engine_wayback.py +186 -154
  119. local_deep_research/web_search_engines/engines/search_engine_wikipedia.py +115 -77
  120. local_deep_research/web_search_engines/search_engine_base.py +174 -99
  121. local_deep_research/web_search_engines/search_engine_factory.py +192 -102
  122. local_deep_research/web_search_engines/search_engines_config.py +22 -15
  123. {local_deep_research-0.1.26.dist-info → local_deep_research-0.2.0.dist-info}/METADATA +177 -97
  124. local_deep_research-0.2.0.dist-info/RECORD +135 -0
  125. {local_deep_research-0.1.26.dist-info → local_deep_research-0.2.0.dist-info}/WHEEL +1 -2
  126. {local_deep_research-0.1.26.dist-info → local_deep_research-0.2.0.dist-info}/entry_points.txt +3 -0
  127. local_deep_research/defaults/llm_config.py +0 -338
  128. local_deep_research/utilties/search_utilities.py +0 -114
  129. local_deep_research/web/static/js/app.js +0 -3763
  130. local_deep_research/web/templates/api_keys_config.html +0 -82
  131. local_deep_research/web/templates/collections_config.html +0 -90
  132. local_deep_research/web/templates/index.html +0 -348
  133. local_deep_research/web/templates/llm_config.html +0 -120
  134. local_deep_research/web/templates/main_config.html +0 -89
  135. local_deep_research/web/templates/search_engines_config.html +0 -154
  136. local_deep_research/web/templates/settings.html +0 -519
  137. local_deep_research-0.1.26.dist-info/RECORD +0 -61
  138. local_deep_research-0.1.26.dist-info/top_level.txt +0 -1
  139. /local_deep_research/{utilties → config}/__init__.py +0 -0
  140. {local_deep_research-0.1.26.dist-info → local_deep_research-0.2.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,139 @@
1
+ {% extends "base.html" %}
2
+ {% from "components/custom_dropdown.html" import render_dropdown %}
3
+
4
+ {% set active_page = 'new-research' %}
5
+
6
+ {% block title %}New Research - Deep Research System{% endblock %}
7
+
8
+ {% block extra_head %}
9
+ <meta name="csrf-token" content="{{ csrf_token() }}">
10
+ <link rel="stylesheet" href="{{ url_for('research.serve_static', path='css/custom_dropdown.css') }}">
11
+ {% endblock %}
12
+
13
+ {% block content %}
14
+ <div class="page active" id="new-research">
15
+ <div class="page-header">
16
+ <h1>Start New Research</h1>
17
+ </div>
18
+ <!-- Add the alert container -->
19
+ <div id="research-alert" class="settings-alert-container" style="display:none"></div>
20
+ <div class="card research-card">
21
+ <div class="card-content">
22
+ <form id="research-form">
23
+ <div class="form-group">
24
+ <label for="query">Research Query</label>
25
+ <textarea id="query" name="query" rows="3" placeholder="Enter your research topic or question..."></textarea>
26
+ </div>
27
+ <div class="form-group">
28
+ <label>Research Mode</label>
29
+ <div class="mode-selection">
30
+ <div class="mode-option active" data-mode="quick">
31
+ <div class="mode-icon"><i class="fas fa-bolt"></i></div>
32
+ <div class="mode-info">
33
+ <h3>Quick Summary</h3>
34
+ <p>Generated in a few minutes</p>
35
+ </div>
36
+ </div>
37
+ <div class="mode-option" data-mode="detailed">
38
+ <div class="mode-icon"><i class="fas fa-microscope"></i></div>
39
+ <div class="mode-info">
40
+ <h3>Detailed Report</h3>
41
+ <p>In-depth analysis (takes longer)</p>
42
+ </div>
43
+ </div>
44
+ </div>
45
+ </div>
46
+
47
+ <!-- Advanced Options -->
48
+ <div class="advanced-options-toggle">
49
+ <span class="toggle-text">Advanced Options</span>
50
+ <i class="fas fa-chevron-down"></i>
51
+ </div>
52
+
53
+ <div class="advanced-options-panel">
54
+ <div class="form-row">
55
+ <!-- Model Provider Selection -->
56
+ <div class="form-group half">
57
+ <label for="model_provider">Model Provider</label>
58
+ <select id="model_provider" name="model_provider" class="form-control">
59
+ <!-- Will be populated dynamically -->
60
+ <option value="">Loading providers...</option>
61
+ </select>
62
+ <span class="input-help">Select the LLM provider to use</span>
63
+ </div>
64
+
65
+ <!-- Custom Endpoint (hidden by default) -->
66
+ <div class="form-group half" id="endpoint_container" style="display: none;">
67
+ <label for="custom_endpoint">Custom Endpoint</label>
68
+ <input type="text" id="custom_endpoint" name="custom_endpoint" class="form-control" placeholder="https://your-endpoint-url/v1">
69
+ <span class="input-help">Enter the OpenAI-compatible API endpoint URL</span>
70
+ </div>
71
+ </div>
72
+
73
+ <div class="form-row">
74
+ <!-- Model Selection -->
75
+ <div class="form-group half">
76
+ {{ render_dropdown(
77
+ input_id="model",
78
+ dropdown_id="model-dropdown",
79
+ placeholder="Enter or select a model",
80
+ label="Language Model",
81
+ help_text="Select or enter a custom model name",
82
+ show_refresh=True,
83
+ refresh_aria_label="Refresh model list"
84
+ ) }}
85
+ </div>
86
+
87
+ <!-- Search Engine Selection -->
88
+ <div class="form-group half">
89
+ {{ render_dropdown(
90
+ input_id="search_engine",
91
+ dropdown_id="search-engine-dropdown",
92
+ placeholder="Select a search engine",
93
+ label="Search Engine",
94
+ help_text="Select the search engine to use for research",
95
+ show_refresh=True,
96
+ refresh_aria_label="Refresh search engine list"
97
+ ) }}
98
+ </div>
99
+ </div>
100
+
101
+ <div class="form-row">
102
+ <!-- Research Iterations -->
103
+ <div class="form-group half">
104
+ <label for="iterations">Research Iterations</label>
105
+ <input type="number" id="iterations" name="iterations" class="form-control" min="1" max="5" value="2">
106
+ <span class="input-help">Number of research cycles to perform</span>
107
+ </div>
108
+
109
+ <!-- Questions Per Iteration -->
110
+ <div class="form-group half">
111
+ <label for="questions_per_iteration">Questions Per Iteration</label>
112
+ <input type="number" id="questions_per_iteration" name="questions_per_iteration" class="form-control" min="1" max="10" value="3">
113
+ <span class="input-help">Follow-up questions in each cycle</span>
114
+ </div>
115
+ </div>
116
+ </div>
117
+
118
+ <div class="form-options">
119
+ <div class="form-option">
120
+ <label for="notification-toggle" class="checkbox-label">
121
+ <input type="checkbox" id="notification-toggle" checked>
122
+ <span class="checkbox-text">Sound notifications when complete</span>
123
+ </label>
124
+ </div>
125
+ </div>
126
+
127
+ <div class="form-actions">
128
+ <button type="submit" class="btn btn-primary" id="start-research-btn"><i class="fas fa-rocket"></i> Start Research</button>
129
+ </div>
130
+ </form>
131
+ </div>
132
+ </div>
133
+ </div>
134
+ {% endblock %}
135
+
136
+ {% block component_scripts %}
137
+ <script src="{{ url_for('research.serve_static', path='js/components/custom_dropdown.js') }}"></script>
138
+ <script src="{{ url_for('research.serve_static', path='js/components/research.js') }}"></script>
139
+ {% endblock %}
@@ -0,0 +1,59 @@
1
+ {% extends "base.html" %}
2
+
3
+ {% block title %}Research Results - Deep Research System{% endblock %}
4
+
5
+ {% block content %}
6
+ <div class="page active" id="research-results">
7
+ <div class="page-header">
8
+ <div class="results-header">
9
+ <h1 class="page-title">Research Results</h1>
10
+ <div class="results-actions">
11
+ <button class="btn btn-outline" id="download-pdf-btn"><i class="fas fa-file-pdf"></i> Download PDF</button>
12
+ <button class="btn btn-outline" id="export-markdown-btn"><i class="fas fa-file-alt"></i> Export Markdown</button>
13
+ <button class="btn btn-outline" id="back-to-history"><i class="fas fa-arrow-left"></i> Back to History</button>
14
+ </div>
15
+ </div>
16
+ </div>
17
+ <div class="card results-card">
18
+ <div class="card-content">
19
+ <div class="results-metadata" id="research-metadata">
20
+ <div class="metadata-item">
21
+ <span class="metadata-label">Query:</span>
22
+ <span id="result-query" class="metadata-value"></span>
23
+ </div>
24
+ <div class="metadata-item">
25
+ <span class="metadata-label">Generated:</span>
26
+ <span id="result-date" class="metadata-value"></span>
27
+ </div>
28
+ <div class="metadata-item">
29
+ <span class="metadata-label">Mode:</span>
30
+ <span id="result-mode" class="metadata-value"></span>
31
+ </div>
32
+ </div>
33
+ <div class="results-content" id="results-content">
34
+ <!-- Will be populated dynamically -->
35
+ <div class="loading-spinner centered">
36
+ <div class="spinner"></div>
37
+ </div>
38
+ </div>
39
+ </div>
40
+ </div>
41
+
42
+ {% include "components/log_panel.html" %}
43
+ </div>
44
+ {% endblock %}
45
+
46
+ {% block page_scripts %}
47
+ <!-- Fallback utilities in case main services are not available -->
48
+ <script src="{{ url_for('research.serve_static', path='js/components/fallback/ui.js') }}"></script>
49
+ <script src="{{ url_for('research.serve_static', path='js/components/fallback/formatting.js') }}"></script>
50
+
51
+ <!-- Main services -->
52
+ <script src="{{ url_for('research.serve_static', path='js/services/ui.js') }}"></script>
53
+ <script src="{{ url_for('research.serve_static', path='js/services/formatting.js') }}"></script>
54
+ <script src="{{ url_for('research.serve_static', path='js/services/api.js') }}"></script>
55
+ <script src="{{ url_for('research.serve_static', path='js/services/pdf.js') }}"></script>
56
+
57
+ <!-- Results component -->
58
+ <script src="{{ url_for('research.serve_static', path='js/components/results.js') }}"></script>
59
+ {% endblock %}
@@ -1,207 +1,93 @@
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="icon" type="image/png" href="{{ url_for('static', filename='favicon.ico') }}">
10
- <style>
11
- .settings-cards {
12
- display: grid;
13
- grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
14
- gap: 1.5rem;
15
- margin-top: 1.5rem;
16
- }
17
- .settings-card {
18
- display: flex;
19
- flex-direction: column;
20
- height: 100%;
21
- }
22
- .settings-card .card-content {
23
- display: flex;
24
- flex-direction: column;
25
- flex: 1;
26
- }
27
- .settings-icon {
28
- font-size: 2rem;
29
- color: var(--accent-primary);
30
- margin-bottom: 1rem;
31
- text-align: center;
32
- }
33
- .settings-title {
34
- font-size: 1.25rem;
35
- font-weight: 600;
36
- margin-bottom: 0.75rem;
37
- color: var(--text-primary);
38
- }
39
- .settings-description {
40
- color: var(--text-secondary);
41
- margin-bottom: 1.5rem;
42
- flex: 1;
43
- }
44
- .card-actions {
45
- margin-top: auto;
46
- text-align: center;
47
- }
48
- </style>
49
- </head>
50
- <body>
51
- <div class="app-container">
52
- <!-- Sidebar -->
53
- <aside class="sidebar">
54
- <div class="sidebar-header">
55
- <h2 id="logo-link" style="cursor: pointer;"><i class="fas fa-atom"></i> Deep Research</h2>
56
- </div>
57
- <nav class="sidebar-nav">
58
- <ul>
59
- <li data-page="new-research"><i class="fas fa-search"></i> <a href="{{ url_for('research.index') }}">New Research</a></li>
60
- <li data-page="history"><i class="fas fa-history"></i> <a href="{{ url_for('research.index') }}#history">History</a></li>
61
- <li class="active" data-page="settings"><i class="fas fa-cog"></i> Settings</li>
62
- </ul>
63
- </nav>
64
- <div class="sidebar-footer">
65
- <p>v0.1.0 | <i class="fas fa-brain"></i></p>
66
- </div>
67
- </aside>
1
+ {% extends "base.html" %}
2
+ {% from "components/settings_form.html" import render_setting %}
3
+ {% from "components/custom_dropdown.html" import render_dropdown %}
68
4
 
69
- <!-- Main Content -->
70
- <main class="main-content">
71
- <div class="page active" id="settings">
72
- <div class="page-header">
73
- <h1>Settings</h1>
74
- </div>
75
-
76
- {% with messages = get_flashed_messages(with_categories=true) %}
77
- {% if messages %}
78
- {% for category, message in messages %}
79
- <div class="alert alert-{{ category }}">
80
- {{ message }}
81
- </div>
82
- {% endfor %}
83
- {% endif %}
84
- {% endwith %}
85
-
86
- <div class="settings-cards">
87
- <!-- Main Configuration Card -->
88
- <div class="card settings-card">
89
- <div class="card-content">
90
- <div class="settings-icon">
91
- <i class="fas fa-search"></i>
92
- </div>
93
- <h3 class="settings-title">Search Settings</h3>
94
- <p class="settings-description">
95
- Configure search parameters, results limits, general behavior, and output settings for the research system.
96
- </p>
97
- <div class="card-actions">
98
- <a href="{{ url_for('research.main_config_page') }}" class="btn btn-primary">
99
- <i class="fas fa-cog"></i> Configure
100
- </a>
101
- </div>
102
- </div>
5
+ {% set active_page = 'settings' %}
6
+
7
+ {% block title %}Settings - Deep Research System{% endblock %}
8
+
9
+ {% block extra_head %}
10
+ <meta name="csrf-token" content="{{ csrf_token() }}">
11
+ <link rel="stylesheet" href="{{ url_for('research.serve_static', path='css/settings.css') }}">
12
+ <link rel="stylesheet" href="{{ url_for('research.serve_static', path='css/custom_dropdown.css') }}">
13
+ {% endblock %}
14
+
15
+ {% block content %}
16
+ <div class="page active" id="settings">
17
+ <div class="settings-container">
18
+ <div class="page-header">
19
+ <h1>Settings</h1>
20
+ <p class="settings-description">
21
+ Configure your research environment by adjusting the settings below. All settings are automatically saved when you make changes.
22
+ </p>
23
+ </div>
24
+
25
+ {% with messages = get_flashed_messages(with_categories=true) %}
26
+ {% if messages %}
27
+ {% for category, message in messages %}
28
+ <div class="alert alert-{{ category }}">
29
+ <i class="fas {% if category == 'success' %}fa-check-circle{% else %}fa-exclamation-circle{% endif %}"></i> {{ message }}
103
30
  </div>
31
+ {% endfor %}
32
+ {% endif %}
33
+ {% endwith %}
104
34
 
105
- <!-- LLM Configuration Card -->
106
- <div class="card settings-card">
107
- <div class="card-content">
108
- <div class="settings-icon">
109
- <i class="fas fa-brain"></i>
110
- </div>
111
- <h3 class="settings-title">Language Model Settings</h3>
112
- <p class="settings-description">
113
- Set up the language models used for research, including model selection, parameters, and API settings.
114
- </p>
115
- <div class="card-actions">
116
- <a href="{{ url_for('research.llm_config_page') }}" class="btn btn-primary">
117
- <i class="fas fa-code"></i> Edit Configuration
118
- </a>
119
- </div>
35
+ <div id="settings-alert" style="display:none"></div>
36
+
37
+ <div class="card">
38
+ <div class="card-content">
39
+ <div class="search-controls">
40
+ <input type="text" id="settings-search" class="search-input" placeholder="Search settings by name, description or category...">
41
+ </div>
42
+
43
+ <div class="settings-tabs">
44
+ <div class="settings-tab active" data-tab="all">All Settings</div>
45
+ <div class="settings-tab" data-tab="llm">Language Models</div>
46
+ <div class="settings-tab" data-tab="search">Search Engines</div>
47
+ <div class="settings-tab" data-tab="report">Reports</div>
48
+ <div class="settings-tab" data-tab="app">Application</div>
49
+ </div>
50
+
51
+ <form id="settings-form" class="settings-form">
52
+ <div id="settings-content">
53
+ <div class="loading-spinner centered">
54
+ <div class="spinner"></div>
55
+ <p>Loading settings...</p>
120
56
  </div>
121
57
  </div>
122
58
 
123
- <!-- Local Collections Card -->
124
- <div class="card settings-card">
125
- <div class="card-content">
126
- <div class="settings-icon">
127
- <i class="fas fa-folder"></i>
128
- </div>
129
- <h3 class="settings-title">Local Document Collections</h3>
130
- <p class="settings-description">
131
- Configure local document collections to search through your own files, papers, and research materials.
132
- </p>
133
- <div class="card-actions">
134
- <a href="{{ url_for('research.collections_config_page') }}" class="btn btn-primary">
135
- <i class="fas fa-code"></i> Edit Configuration
136
- </a>
137
- </div>
138
- </div>
59
+ <div class="toggle-raw-config" id="toggle-raw-config">
60
+ <i class="fas fa-code"></i> <span id="toggle-text">Show JSON Configuration</span>
139
61
  </div>
140
62
 
141
- <div class="card settings-card">
142
- <div class="card-content">
143
- <div class="settings-icon">
144
- <i class="fas fa-key"></i>
145
- </div>
146
- <h3 class="settings-title">API Keys</h3>
147
- <p class="settings-description">
148
- Configure API keys for external services like OpenAI, Anthropic, and search providers.
63
+ <div id="raw-config" class="raw-config-section" style="display: none;">
64
+ <div class="section-header">
65
+ <h3>Advanced JSON Configuration</h3>
66
+ <p class="section-description">
67
+ Use this editor to directly modify configuration values. You can add new parameters not shown in the UI, and they will be preserved across saves. Changes here override the UI settings.
149
68
  </p>
150
- <div class="card-actions">
151
- <a href="{{ url_for('research.api_keys_config_page') }}" class="btn btn-primary">
152
- <i class="fas fa-cog"></i> Configure
153
- </a>
154
- </div>
155
69
  </div>
156
- </div>
157
- <div class="card settings-card">
158
- <div class="card-content">
159
- <div class="settings-icon">
160
- <i class="fas fa-search-plus"></i>
161
- </div>
162
- <h3 class="settings-title">Search Engines Settings</h3>
163
- <p class="settings-description">
164
- Configure search engines, their parameters, and specify which search engines to use for different types of queries.
165
- </p>
166
- <div class="card-actions">
167
- <a href="{{ url_for('research.search_engines_config_page') }}" class="btn btn-primary">
168
- <i class="fas fa-cog"></i> Configure
169
- </a>
170
- </div>
70
+ <div id="json-editor-container">
71
+ <textarea id="raw_config_editor" class="json-editor"></textarea>
171
72
  </div>
172
73
  </div>
173
- </div>
74
+
75
+ <div class="form-actions">
76
+ <button type="button" id="reset-to-defaults-button" class="btn btn-warning">
77
+ <i class="fas fa-sync-alt"></i> Reset to Defaults
78
+ </button>
79
+ <button type="submit" class="btn btn-primary">
80
+ <i class="fas fa-save"></i> Save All Settings
81
+ </button>
82
+ </div>
83
+ </form>
174
84
  </div>
175
- </main>
85
+ </div>
176
86
  </div>
87
+ </div>
88
+ {% endblock %}
177
89
 
178
- <!-- Mobile Tab Bar -->
179
- <nav class="mobile-tab-bar">
180
- <ul>
181
- <li data-page="new-research">
182
- <a href="{{ url_for('research.index') }}">
183
- <i class="fas fa-search"></i>
184
- <span>Research</span>
185
- </a>
186
- </li>
187
- <li data-page="history">
188
- <a href="{{ url_for('research.index') }}#history">
189
- <i class="fas fa-history"></i>
190
- <span>History</span>
191
- </a>
192
- </li>
193
- <li class="active" data-page="settings">
194
- <i class="fas fa-cog"></i>
195
- <span>Settings</span>
196
- </li>
197
- </ul>
198
- </nav>
199
-
200
- <script>
201
- // Make the logo clickable to go back to home
202
- document.getElementById('logo-link').addEventListener('click', function() {
203
- window.location.href = "{{ url_for('research.index') }}";
204
- });
205
- </script>
206
- </body>
207
- </html>
90
+ {% block page_scripts %}
91
+ <script src="{{ url_for('research.serve_static', path='js/components/custom_dropdown.js') }}"></script>
92
+ <script src="{{ url_for('research.serve_static', path='js/components/settings.js') }}"></script>
93
+ {% endblock %}
File without changes
@@ -0,0 +1,76 @@
1
+ import logging
2
+ import traceback
3
+
4
+ # Initialize logger
5
+ logger = logging.getLogger(__name__)
6
+
7
+
8
+ def convert_debug_to_markdown(raw_text, query):
9
+ """
10
+ Convert the debug-formatted text to clean markdown.
11
+
12
+ Args:
13
+ raw_text: The raw formatted findings with debug symbols
14
+ query: Original research query
15
+
16
+ Returns:
17
+ Clean markdown formatted text
18
+ """
19
+ try:
20
+ logger.info(f"Starting markdown conversion for query: {query}")
21
+ logger.info(f"Raw text type: {type(raw_text)}")
22
+
23
+ # Handle None or empty input
24
+ if not raw_text:
25
+ logger.warning("WARNING: raw_text is empty or None")
26
+ return f"No detailed findings available for '{query}'."
27
+
28
+ # If there's a "DETAILED FINDINGS:" section, extract everything after it
29
+ if "DETAILED FINDINGS:" in raw_text:
30
+ logger.info("Found DETAILED FINDINGS section")
31
+ detailed_index = raw_text.index("DETAILED FINDINGS:")
32
+ content = raw_text[detailed_index + len("DETAILED FINDINGS:") :].strip()
33
+ else:
34
+ logger.info("No DETAILED FINDINGS section found, using full text")
35
+ content = raw_text
36
+
37
+ # Remove divider lines with === symbols
38
+ lines_before = len(content.split("\n"))
39
+ content = "\n".join(
40
+ [
41
+ line
42
+ for line in content.split("\n")
43
+ if not line.strip().startswith("===") and not line.strip() == "=" * 80
44
+ ]
45
+ )
46
+ lines_after = len(content.split("\n"))
47
+ logger.info(f"Removed {lines_before - lines_after} divider lines")
48
+
49
+ # Remove SEARCH QUESTIONS BY ITERATION section
50
+ if "SEARCH QUESTIONS BY ITERATION:" in content:
51
+ logger.info("Found SEARCH QUESTIONS BY ITERATION section")
52
+ search_index = content.index("SEARCH QUESTIONS BY ITERATION:")
53
+ next_major_section = -1
54
+ for marker in ["DETAILED FINDINGS:", "COMPLETE RESEARCH:"]:
55
+ if marker in content[search_index:]:
56
+ marker_pos = content.index(marker, search_index)
57
+ if next_major_section == -1 or marker_pos < next_major_section:
58
+ next_major_section = marker_pos
59
+
60
+ if next_major_section != -1:
61
+ logger.info(
62
+ f"Removing section from index {search_index} to {next_major_section}"
63
+ )
64
+ content = content[:search_index] + content[next_major_section:]
65
+ else:
66
+ # If no later section, just remove everything from SEARCH QUESTIONS onwards
67
+ logger.info(f"Removing everything after index {search_index}")
68
+ content = content[:search_index].strip()
69
+
70
+ logger.info(f"Final markdown length: {len(content.strip())}")
71
+ return content.strip()
72
+ except Exception as e:
73
+ logger.error(f"Error in convert_debug_to_markdown: {str(e)}")
74
+ logger.error(traceback.format_exc())
75
+ # Return a basic message with the original query as fallback
76
+ return f"# Research on {query}\n\nThere was an error formatting the research results."