Browse Source

添加前端输出

main
tanxing 2 weeks ago
parent
commit
a62c8ed495
  1. 65
      deepsearcher/backend/templates/index.html
  2. 62
      deepsearcher/utils/log.py
  3. 21
      main.py

65
deepsearcher/backend/templates/index.html

@ -14,6 +14,7 @@
--success-color: #10b981;
--error-color: #ef4444;
--warning-color: #f59e0b;
--info-color: #3b82f6;
}
* {
@ -191,6 +192,29 @@
line-height: 1.6;
}
/* 进度日志样式 */
.progress-log {
background-color: #1e1e1e;
color: #d4d4d4;
border-radius: 6px;
padding: 16px;
font-family: 'Courier New', monospace;
font-size: 14px;
margin: 16px 0;
max-height: 300px;
overflow-y: auto;
display: none;
}
.progress-log.visible {
display: block;
}
.progress-log-entry {
margin: 4px 0;
line-height: 1.4;
}
footer {
text-align: center;
margin-top: 30px;
@ -266,6 +290,10 @@
</div>
<button id="queryBtn">执行查询</button>
<div id="queryStatus" class="status"></div>
<!-- 进度日志显示区域 -->
<div id="progressLog" class="progress-log"></div>
<div id="queryResult" class="result-container">
<h3>查询结果:</h3>
<div class="query-result" id="resultText"></div>
@ -319,6 +347,37 @@
resultElement.classList.remove('visible');
}
// 工具函数:显示进度日志
function showProgressLog(messages) {
const logElement = document.getElementById('progressLog');
if (messages && messages.length > 0) {
logElement.innerHTML = messages.map(msg =>
`<div class="progress-log-entry">${escapeHtml(msg)}</div>`
).join('');
logElement.classList.add('visible');
} else {
logElement.classList.remove('visible');
}
}
// 工具函数:隐藏进度日志
function hideProgressLog() {
const logElement = document.getElementById('progressLog');
logElement.classList.remove('visible');
}
// 工具函数:转义HTML特殊字符
function escapeHtml(text) {
const map = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
"'": '&#039;'
};
return text.replace(/[&<>"']/g, function(m) { return map[m]; });
}
// 工具函数:设置按钮加载状态
function setButtonLoading(button, loading) {
if (loading) {
@ -347,6 +406,7 @@
setButtonLoading(button, true);
showStatus('loadStatus', '正在加载文件...', 'loading');
hideResult();
hideProgressLog();
try {
const response = await fetch('/load-files/', {
@ -392,6 +452,7 @@
setButtonLoading(button, true);
showStatus('webLoadStatus', '正在加载网站内容...', 'loading');
hideResult();
hideProgressLog();
try {
const response = await fetch('/load-website/', {
@ -439,6 +500,7 @@
setButtonLoading(button, true);
showStatus('queryStatus', '正在处理查询...', 'loading');
hideResult();
hideProgressLog();
try {
const response = await fetch(`/query/?original_query=${encodeURIComponent(queryText)}&max_iter=${maxIter}`, {
@ -455,6 +517,9 @@
document.getElementById('resultText').textContent = data.result;
document.getElementById('tokenInfo').textContent = `消耗Token数: ${data.consume_token}`;
showResult();
// 显示进度日志
showProgressLog(data.progress_messages);
} else {
showStatus('queryStatus', `查询失败: ${data.detail}`, 'error');
}

62
deepsearcher/utils/log.py

@ -1,5 +1,6 @@
import logging
import io
from typing import List
from termcolor import colored
@ -50,6 +51,44 @@ class ColoredFormatter(logging.Formatter):
# return super().format(record)
class StreamCaptureHandler(logging.Handler):
"""
A custom logging handler that captures log messages in a list.
This handler stores log messages in memory so they can be retrieved later,
which is useful for sending log messages to a frontend.
"""
def __init__(self):
super().__init__()
self.messages: List[str] = []
def emit(self, record):
"""
Emit a log record by storing it in the messages list.
Args:
record: The log record to emit.
"""
log_entry = self.format(record)
self.messages.append(log_entry)
def get_messages(self) -> List[str]:
"""
Get all captured log messages.
Returns:
A list of captured log messages.
"""
return self.messages.copy()
def clear_messages(self):
"""
Clear all captured log messages.
"""
self.messages.clear()
# config log
dev_logger = logging.getLogger("dev")
dev_formatter = ColoredFormatter("%(asctime)s - %(levelname)s - %(message)s")
@ -60,8 +99,11 @@ dev_logger.setLevel(logging.INFO)
progress_logger = logging.getLogger("progress")
progress_handler = logging.StreamHandler()
progress_capture_handler = StreamCaptureHandler()
progress_handler.setFormatter(ColoredFormatter("%(message)s"))
progress_capture_handler.setFormatter(logging.Formatter("%(message)s"))
progress_logger.addHandler(progress_handler)
progress_logger.addHandler(progress_capture_handler)
progress_logger.setLevel(logging.INFO)
dev_mode = False
@ -158,3 +200,21 @@ def color_print(message, **kwargs):
**kwargs: Additional keyword arguments to pass to the logger.
"""
progress_logger.info(message)
progress_handler.flush()
def get_progress_messages() -> List[str]:
"""
Get all captured progress messages.
Returns:
A list of captured progress messages.
"""
return progress_capture_handler.get_messages()
def clear_progress_messages():
"""
Clear all captured progress messages.
"""
progress_capture_handler.clear_messages()

21
main.py

@ -155,11 +155,12 @@ def load_files(
HTTPException: If loading files fails.
"""
try:
# 修复batch_size为None时的问题
load_from_local_files(
paths_or_directory=paths,
collection_name=collection_name,
collection_description=collection_description,
batch_size=batch_size,
batch_size=batch_size if batch_size is not None else 256, # 提供默认值
)
return {"message": "Files loaded successfully."}
except Exception as e:
@ -205,11 +206,12 @@ def load_website(
HTTPException: If loading website content fails.
"""
try:
# 修复batch_size为None时的问题
load_from_website(
urls=urls,
collection_name=collection_name,
collection_description=collection_description,
batch_size=batch_size,
batch_size=batch_size if batch_size is not None else 256, # 提供默认值
)
return {"message": "Website loaded successfully."}
except Exception as e:
@ -244,8 +246,21 @@ def perform_query(
HTTPException: If the query fails.
"""
try:
# 清除之前的进度消息
from deepsearcher.utils.log import clear_progress_messages
clear_progress_messages()
result_text, _, consume_token = query(original_query, max_iter)
return {"result": result_text, "consume_token": consume_token}
# 获取进度消息
from deepsearcher.utils.log import get_progress_messages
progress_messages = get_progress_messages()
return {
"result": result_text,
"consume_token": consume_token,
"progress_messages": progress_messages
}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))

Loading…
Cancel
Save