Doiiars

1. 修复论坛通信问题,基于日志块增加容错

2. 使用ERROR层级来避免json解析错误导致的连环问题
@@ -70,6 +70,7 @@ class LogMonitor: @@ -70,6 +70,7 @@ class LogMonitor:
70 self.capturing_json = {} # 每个app的JSON捕获状态 70 self.capturing_json = {} # 每个app的JSON捕获状态
71 self.json_buffer = {} # 每个app的JSON缓冲区 71 self.json_buffer = {} # 每个app的JSON缓冲区
72 self.json_start_line = {} # 每个app的JSON开始行 72 self.json_start_line = {} # 每个app的JSON开始行
  73 + self.in_error_block = {} # 每个app是否在ERROR块中
73 74
74 # 确保logs目录存在 75 # 确保logs目录存在
75 self.log_dir.mkdir(exist_ok=True) 76 self.log_dir.mkdir(exist_ok=True)
@@ -93,6 +94,7 @@ class LogMonitor: @@ -93,6 +94,7 @@ class LogMonitor:
93 self.capturing_json = {} 94 self.capturing_json = {}
94 self.json_buffer = {} 95 self.json_buffer = {}
95 self.json_start_line = {} 96 self.json_start_line = {}
  97 + self.in_error_block = {}
96 98
97 # 重置主持人相关状态 99 # 重置主持人相关状态
98 self.agent_speeches_buffer = [] 100 self.agent_speeches_buffer = []
@@ -118,6 +120,21 @@ class LogMonitor: @@ -118,6 +120,21 @@ class LogMonitor:
118 except Exception as e: 120 except Exception as e:
119 logger.exception(f"ForumEngine: 写入forum.log失败: {e}") 121 logger.exception(f"ForumEngine: 写入forum.log失败: {e}")
120 122
  123 + def get_log_level(self, line: str) -> Optional[str]:
  124 + """检测日志行的级别(INFO/ERROR/WARNING/DEBUG等)
  125 +
  126 + 支持loguru格式:YYYY-MM-DD HH:mm:ss.SSS | LEVEL | ...
  127 +
  128 + Returns:
  129 + 'INFO', 'ERROR', 'WARNING', 'DEBUG' 或 None(无法识别)
  130 + """
  131 + # 检查loguru格式:YYYY-MM-DD HH:mm:ss.SSS | LEVEL | ...
  132 + # 匹配模式:| LEVEL | 或 | LEVEL |
  133 + match = re.search(r'\|\s*(INFO|ERROR|WARNING|DEBUG|TRACE|CRITICAL)\s*\|', line)
  134 + if match:
  135 + return match.group(1)
  136 + return None
  137 +
121 def is_target_log_line(self, line: str) -> bool: 138 def is_target_log_line(self, line: str) -> bool:
122 """检查是否是目标日志行(SummaryNode) 139 """检查是否是目标日志行(SummaryNode)
123 140
@@ -132,6 +149,11 @@ class LogMonitor: @@ -132,6 +149,11 @@ class LogMonitor:
132 - 包含错误关键词的日志(JSON解析失败、JSON修复失败等) 149 - 包含错误关键词的日志(JSON解析失败、JSON修复失败等)
133 """ 150 """
134 # 排除 ERROR 级别的日志 151 # 排除 ERROR 级别的日志
  152 + log_level = self.get_log_level(line)
  153 + if log_level == 'ERROR':
  154 + return False
  155 +
  156 + # 兼容旧检查方式
135 if "| ERROR" in line or "| ERROR |" in line: 157 if "| ERROR" in line or "| ERROR |" in line:
136 return False 158 return False
137 159
@@ -381,6 +403,7 @@ class LogMonitor: @@ -381,6 +403,7 @@ class LogMonitor:
381 # 重置JSON捕获状态 403 # 重置JSON捕获状态
382 self.capturing_json[app_name] = False 404 self.capturing_json[app_name] = False
383 self.json_buffer[app_name] = [] 405 self.json_buffer[app_name] = []
  406 + self.in_error_block[app_name] = False
384 407
385 if current_size > last_position: 408 if current_size > last_position:
386 with open(file_path, 'r', encoding='utf-8') as f: 409 with open(file_path, 'r', encoding='utf-8') as f:
@@ -400,17 +423,47 @@ class LogMonitor: @@ -400,17 +423,47 @@ class LogMonitor:
400 return new_lines 423 return new_lines
401 424
402 def process_lines_for_json(self, lines: List[str], app_name: str) -> List[str]: 425 def process_lines_for_json(self, lines: List[str], app_name: str) -> List[str]:
403 - """处理行以捕获多行JSON内容""" 426 + """处理行以捕获多行JSON内容
  427 +
  428 + 实现ERROR块过滤:如果遇到ERROR级别的日志,拒绝处理直到遇到下一个INFO级别的日志
  429 + """
404 captured_contents = [] 430 captured_contents = []
405 431
406 # 初始化状态 432 # 初始化状态
407 if app_name not in self.capturing_json: 433 if app_name not in self.capturing_json:
408 self.capturing_json[app_name] = False 434 self.capturing_json[app_name] = False
409 self.json_buffer[app_name] = [] 435 self.json_buffer[app_name] = []
  436 + if app_name not in self.in_error_block:
  437 + self.in_error_block[app_name] = False
410 438
411 for line in lines: 439 for line in lines:
412 if not line.strip(): 440 if not line.strip():
413 continue 441 continue
  442 +
  443 + # 首先检查日志级别,更新ERROR块状态
  444 + log_level = self.get_log_level(line)
  445 + if log_level == 'ERROR':
  446 + # 遇到ERROR,进入ERROR块状态
  447 + self.in_error_block[app_name] = True
  448 + # 如果正在捕获JSON,立即停止并清空缓冲区
  449 + if self.capturing_json[app_name]:
  450 + self.capturing_json[app_name] = False
  451 + self.json_buffer[app_name] = []
  452 + # 跳过当前行,不处理
  453 + continue
  454 + elif log_level == 'INFO':
  455 + # 遇到INFO,退出ERROR块状态
  456 + self.in_error_block[app_name] = False
  457 + # 其他级别(WARNING、DEBUG等)保持当前状态
  458 +
  459 + # 如果在ERROR块中,拒绝处理所有内容
  460 + if self.in_error_block[app_name]:
  461 + # 如果正在捕获JSON,立即停止并清空缓冲区
  462 + if self.capturing_json[app_name]:
  463 + self.capturing_json[app_name] = False
  464 + self.json_buffer[app_name] = []
  465 + # 跳过当前行,不处理
  466 + continue
414 467
415 # 检查是否是目标节点行和JSON开始标记 468 # 检查是否是目标节点行和JSON开始标记
416 is_target = self.is_target_log_line(line) 469 is_target = self.is_target_log_line(line)
@@ -538,6 +591,7 @@ class LogMonitor: @@ -538,6 +591,7 @@ class LogMonitor:
538 self.file_positions[app_name] = self.get_file_size(log_file) 591 self.file_positions[app_name] = self.get_file_size(log_file)
539 self.capturing_json[app_name] = False 592 self.capturing_json[app_name] = False
540 self.json_buffer[app_name] = [] 593 self.json_buffer[app_name] = []
  594 + self.in_error_block[app_name] = False
541 # logger.info(f"ForumEngine: {app_name} 基线行数: {self.file_line_counts[app_name]}") 595 # logger.info(f"ForumEngine: {app_name} 基线行数: {self.file_line_counts[app_name]}")
542 596
543 while self.is_monitoring: 597 while self.is_monitoring:
@@ -601,6 +655,7 @@ class LogMonitor: @@ -601,6 +655,7 @@ class LogMonitor:
601 # 重置JSON捕获状态 655 # 重置JSON捕获状态
602 self.capturing_json[app_name] = False 656 self.capturing_json[app_name] = False
603 self.json_buffer[app_name] = [] 657 self.json_buffer[app_name] = []
  658 + self.in_error_block[app_name] = False
604 659
605 # 更新行数记录 660 # 更新行数记录
606 self.file_line_counts[app_name] = current_lines 661 self.file_line_counts[app_name] = current_lines
@@ -779,5 +779,5 @@ def create_agent(config_file: Optional[str] = None) -> DeepSearchAgent: @@ -779,5 +779,5 @@ def create_agent(config_file: Optional[str] = None) -> DeepSearchAgent:
779 Returns: 779 Returns:
780 DeepSearchAgent实例 780 DeepSearchAgent实例
781 """ 781 """
782 - config = settings 782 + config = Settings() # 以空配置初始化,而从从环境变量初始化
783 return DeepSearchAgent(config) 783 return DeepSearchAgent(config)
@@ -87,11 +87,11 @@ class ReportStructureNode(StateMutationNode): @@ -87,11 +87,11 @@ class ReportStructureNode(StateMutationNode):
87 report_structure = json.loads(cleaned_output) 87 report_structure = json.loads(cleaned_output)
88 logger.info("JSON解析成功") 88 logger.info("JSON解析成功")
89 except JSONDecodeError as e: 89 except JSONDecodeError as e:
90 - logger.exception(f"JSON解析失败: {str(e)}") 90 + logger.error(f"JSON解析失败: {str(e)}")
91 # 使用更强大的提取方法 91 # 使用更强大的提取方法
92 report_structure = extract_clean_response(cleaned_output) 92 report_structure = extract_clean_response(cleaned_output)
93 if "error" in report_structure: 93 if "error" in report_structure:
94 - logger.exception("JSON解析失败,尝试修复...") 94 + logger.error("JSON解析失败,尝试修复...")
95 # 尝试修复JSON 95 # 尝试修复JSON
96 fixed_json = fix_incomplete_json(cleaned_output) 96 fixed_json = fix_incomplete_json(cleaned_output)
97 if fixed_json: 97 if fixed_json:
@@ -99,11 +99,11 @@ class ReportStructureNode(StateMutationNode): @@ -99,11 +99,11 @@ class ReportStructureNode(StateMutationNode):
99 report_structure = json.loads(fixed_json) 99 report_structure = json.loads(fixed_json)
100 logger.info("JSON修复成功") 100 logger.info("JSON修复成功")
101 except JSONDecodeError: 101 except JSONDecodeError:
102 - logger.exception("JSON修复失败") 102 + logger.error("JSON修复失败")
103 # 返回默认结构 103 # 返回默认结构
104 return self._generate_default_structure() 104 return self._generate_default_structure()
105 else: 105 else:
106 - logger.exception("无法修复JSON,使用默认结构") 106 + logger.error("无法修复JSON,使用默认结构")
107 return self._generate_default_structure() 107 return self._generate_default_structure()
108 108
109 # 验证结构 109 # 验证结构
@@ -101,7 +101,7 @@ class FirstSearchNode(BaseNode): @@ -101,7 +101,7 @@ class FirstSearchNode(BaseNode):
101 result = json.loads(cleaned_output) 101 result = json.loads(cleaned_output)
102 logger.info("JSON解析成功") 102 logger.info("JSON解析成功")
103 except JSONDecodeError as e: 103 except JSONDecodeError as e:
104 - logger.exception(f"JSON解析失败: {str(e)}") 104 + logger.error(f"JSON解析失败: {str(e)}")
105 # 使用更强大的提取方法 105 # 使用更强大的提取方法
106 result = extract_clean_response(cleaned_output) 106 result = extract_clean_response(cleaned_output)
107 if "error" in result: 107 if "error" in result:
@@ -236,7 +236,7 @@ class ReflectionNode(BaseNode): @@ -236,7 +236,7 @@ class ReflectionNode(BaseNode):
236 result = json.loads(cleaned_output) 236 result = json.loads(cleaned_output)
237 logger.info("JSON解析成功") 237 logger.info("JSON解析成功")
238 except JSONDecodeError as e: 238 except JSONDecodeError as e:
239 - logger.exception(f"JSON解析失败: {str(e)}") 239 + logger.error(f"JSON解析失败: {str(e)}")
240 # 使用更强大的提取方法 240 # 使用更强大的提取方法
241 result = extract_clean_response(cleaned_output) 241 result = extract_clean_response(cleaned_output)
242 if "error" in result: 242 if "error" in result:
@@ -135,7 +135,7 @@ class FirstSummaryNode(StateMutationNode): @@ -135,7 +135,7 @@ class FirstSummaryNode(StateMutationNode):
135 result = json.loads(cleaned_output) 135 result = json.loads(cleaned_output)
136 logger.info("JSON解析成功") 136 logger.info("JSON解析成功")
137 except JSONDecodeError as e: 137 except JSONDecodeError as e:
138 - logger.exception(f"JSON解析失败: {str(e)}") 138 + logger.error(f"JSON解析失败: {str(e)}")
139 # 尝试修复JSON 139 # 尝试修复JSON
140 fixed_json = fix_incomplete_json(cleaned_output) 140 fixed_json = fix_incomplete_json(cleaned_output)
141 if fixed_json: 141 if fixed_json:
@@ -300,7 +300,7 @@ class ReflectionSummaryNode(StateMutationNode): @@ -300,7 +300,7 @@ class ReflectionSummaryNode(StateMutationNode):
300 result = json.loads(cleaned_output) 300 result = json.loads(cleaned_output)
301 logger.info("JSON解析成功") 301 logger.info("JSON解析成功")
302 except JSONDecodeError as e: 302 except JSONDecodeError as e:
303 - logger.exception(f"JSON解析失败: {str(e)}") 303 + logger.error(f"JSON解析失败: {str(e)}")
304 # 尝试修复JSON 304 # 尝试修复JSON
305 fixed_json = fix_incomplete_json(cleaned_output) 305 fixed_json = fix_incomplete_json(cleaned_output)
306 if fixed_json: 306 if fixed_json:
@@ -308,11 +308,11 @@ class ReflectionSummaryNode(StateMutationNode): @@ -308,11 +308,11 @@ class ReflectionSummaryNode(StateMutationNode):
308 result = json.loads(fixed_json) 308 result = json.loads(fixed_json)
309 logger.info("JSON修复成功") 309 logger.info("JSON修复成功")
310 except JSONDecodeError: 310 except JSONDecodeError:
311 - logger.info("JSON修复失败,直接使用清理后的文本") 311 + logger.error("JSON修复失败,直接使用清理后的文本")
312 # 如果不是JSON格式,直接返回清理后的文本 312 # 如果不是JSON格式,直接返回清理后的文本
313 return cleaned_output 313 return cleaned_output
314 else: 314 else:
315 - logger.info("无法修复JSON,直接使用清理后的文本") 315 + logger.error("无法修复JSON,直接使用清理后的文本")
316 # 如果不是JSON格式,直接返回清理后的文本 316 # 如果不是JSON格式,直接返回清理后的文本
317 return cleaned_output 317 return cleaned_output
318 318
@@ -87,7 +87,7 @@ class ReportStructureNode(StateMutationNode): @@ -87,7 +87,7 @@ class ReportStructureNode(StateMutationNode):
87 report_structure = json.loads(cleaned_output) 87 report_structure = json.loads(cleaned_output)
88 logger.info("JSON解析成功") 88 logger.info("JSON解析成功")
89 except JSONDecodeError as e: 89 except JSONDecodeError as e:
90 - logger.exception(f"JSON解析失败: {str(e)}") 90 + logger.error(f"JSON解析失败: {str(e)}")
91 # 使用更强大的提取方法 91 # 使用更强大的提取方法
92 report_structure = extract_clean_response(cleaned_output) 92 report_structure = extract_clean_response(cleaned_output)
93 if "error" in report_structure: 93 if "error" in report_structure:
@@ -101,7 +101,7 @@ class FirstSearchNode(BaseNode): @@ -101,7 +101,7 @@ class FirstSearchNode(BaseNode):
101 result = json.loads(cleaned_output) 101 result = json.loads(cleaned_output)
102 logger.info("JSON解析成功") 102 logger.info("JSON解析成功")
103 except JSONDecodeError as e: 103 except JSONDecodeError as e:
104 - logger.exception(f"JSON解析失败: {str(e)}") 104 + logger.error(f"JSON解析失败: {str(e)}")
105 # 使用更强大的提取方法 105 # 使用更强大的提取方法
106 result = extract_clean_response(cleaned_output) 106 result = extract_clean_response(cleaned_output)
107 if "error" in result: 107 if "error" in result:
@@ -236,7 +236,7 @@ class ReflectionNode(BaseNode): @@ -236,7 +236,7 @@ class ReflectionNode(BaseNode):
236 result = json.loads(cleaned_output) 236 result = json.loads(cleaned_output)
237 logger.info("JSON解析成功") 237 logger.info("JSON解析成功")
238 except JSONDecodeError as e: 238 except JSONDecodeError as e:
239 - logger.exception(f"JSON解析失败: {str(e)}") 239 + logger.error(f"JSON解析失败: {str(e)}")
240 # 使用更强大的提取方法 240 # 使用更强大的提取方法
241 result = extract_clean_response(cleaned_output) 241 result = extract_clean_response(cleaned_output)
242 if "error" in result: 242 if "error" in result:
@@ -138,7 +138,7 @@ class FirstSummaryNode(StateMutationNode): @@ -138,7 +138,7 @@ class FirstSummaryNode(StateMutationNode):
138 result = json.loads(cleaned_output) 138 result = json.loads(cleaned_output)
139 logger.info("JSON解析成功") 139 logger.info("JSON解析成功")
140 except JSONDecodeError as e: 140 except JSONDecodeError as e:
141 - logger.exception(f"JSON解析失败: {str(e)}") 141 + logger.error(f"JSON解析失败: {str(e)}")
142 # 尝试修复JSON 142 # 尝试修复JSON
143 fixed_json = fix_incomplete_json(cleaned_output) 143 fixed_json = fix_incomplete_json(cleaned_output)
144 if fixed_json: 144 if fixed_json:
@@ -306,7 +306,7 @@ class ReflectionSummaryNode(StateMutationNode): @@ -306,7 +306,7 @@ class ReflectionSummaryNode(StateMutationNode):
306 result = json.loads(cleaned_output) 306 result = json.loads(cleaned_output)
307 logger.info("JSON解析成功") 307 logger.info("JSON解析成功")
308 except JSONDecodeError as e: 308 except JSONDecodeError as e:
309 - logger.exception(f"JSON解析失败: {str(e)}") 309 + logger.error(f"JSON解析失败: {str(e)}")
310 # 尝试修复JSON 310 # 尝试修复JSON
311 fixed_json = fix_incomplete_json(cleaned_output) 311 fixed_json = fix_incomplete_json(cleaned_output)
312 if fixed_json: 312 if fixed_json:
@@ -314,11 +314,11 @@ class ReflectionSummaryNode(StateMutationNode): @@ -314,11 +314,11 @@ class ReflectionSummaryNode(StateMutationNode):
314 result = json.loads(fixed_json) 314 result = json.loads(fixed_json)
315 logger.info("JSON修复成功") 315 logger.info("JSON修复成功")
316 except JSONDecodeError: 316 except JSONDecodeError:
317 - logger.exception("JSON修复失败,直接使用清理后的文本") 317 + logger.error("JSON修复失败,直接使用清理后的文本")
318 # 如果不是JSON格式,直接返回清理后的文本 318 # 如果不是JSON格式,直接返回清理后的文本
319 return cleaned_output 319 return cleaned_output
320 else: 320 else:
321 - logger.exception("无法修复JSON,直接使用清理后的文本") 321 + logger.error("无法修复JSON,直接使用清理后的文本")
322 # 如果不是JSON格式,直接返回清理后的文本 322 # 如果不是JSON格式,直接返回清理后的文本
323 return cleaned_output 323 return cleaned_output
324 324
@@ -87,7 +87,7 @@ class ReportStructureNode(StateMutationNode): @@ -87,7 +87,7 @@ class ReportStructureNode(StateMutationNode):
87 report_structure = json.loads(cleaned_output) 87 report_structure = json.loads(cleaned_output)
88 logger.info("JSON解析成功") 88 logger.info("JSON解析成功")
89 except JSONDecodeError as e: 89 except JSONDecodeError as e:
90 - logger.exception(f"JSON解析失败: {str(e)}") 90 + logger.error(f"JSON解析失败: {str(e)}")
91 # 使用更强大的提取方法 91 # 使用更强大的提取方法
92 report_structure = extract_clean_response(cleaned_output) 92 report_structure = extract_clean_response(cleaned_output)
93 if "error" in report_structure: 93 if "error" in report_structure:
@@ -101,7 +101,7 @@ class FirstSearchNode(BaseNode): @@ -101,7 +101,7 @@ class FirstSearchNode(BaseNode):
101 result = json.loads(cleaned_output) 101 result = json.loads(cleaned_output)
102 logger.info("JSON解析成功") 102 logger.info("JSON解析成功")
103 except JSONDecodeError as e: 103 except JSONDecodeError as e:
104 - logger.exception(f"JSON解析失败: {str(e)}") 104 + logger.error(f"JSON解析失败: {str(e)}")
105 # 使用更强大的提取方法 105 # 使用更强大的提取方法
106 result = extract_clean_response(cleaned_output) 106 result = extract_clean_response(cleaned_output)
107 if "error" in result: 107 if "error" in result:
@@ -236,7 +236,7 @@ class ReflectionNode(BaseNode): @@ -236,7 +236,7 @@ class ReflectionNode(BaseNode):
236 result = json.loads(cleaned_output) 236 result = json.loads(cleaned_output)
237 logger.info("JSON解析成功") 237 logger.info("JSON解析成功")
238 except JSONDecodeError as e: 238 except JSONDecodeError as e:
239 - logger.exception(f"JSON解析失败: {str(e)}") 239 + logger.error(f"JSON解析失败: {str(e)}")
240 # 使用更强大的提取方法 240 # 使用更强大的提取方法
241 result = extract_clean_response(cleaned_output) 241 result = extract_clean_response(cleaned_output)
242 if "error" in result: 242 if "error" in result:
@@ -138,7 +138,7 @@ class FirstSummaryNode(StateMutationNode): @@ -138,7 +138,7 @@ class FirstSummaryNode(StateMutationNode):
138 result = json.loads(cleaned_output) 138 result = json.loads(cleaned_output)
139 logger.info("JSON解析成功") 139 logger.info("JSON解析成功")
140 except JSONDecodeError as e: 140 except JSONDecodeError as e:
141 - logger.exception(f"JSON解析失败: {str(e)}") 141 + logger.error(f"JSON解析失败: {str(e)}")
142 # 尝试修复JSON 142 # 尝试修复JSON
143 fixed_json = fix_incomplete_json(cleaned_output) 143 fixed_json = fix_incomplete_json(cleaned_output)
144 if fixed_json: 144 if fixed_json:
@@ -146,11 +146,11 @@ class FirstSummaryNode(StateMutationNode): @@ -146,11 +146,11 @@ class FirstSummaryNode(StateMutationNode):
146 result = json.loads(fixed_json) 146 result = json.loads(fixed_json)
147 logger.info("JSON修复成功") 147 logger.info("JSON修复成功")
148 except JSONDecodeError: 148 except JSONDecodeError:
149 - logger.exception("JSON修复失败,直接使用清理后的文本") 149 + logger.error("JSON修复失败,直接使用清理后的文本")
150 # 如果不是JSON格式,直接返回清理后的文本 150 # 如果不是JSON格式,直接返回清理后的文本
151 return cleaned_output 151 return cleaned_output
152 else: 152 else:
153 - logger.exception("无法修复JSON,直接使用清理后的文本") 153 + logger.error("无法修复JSON,直接使用清理后的文本")
154 # 如果不是JSON格式,直接返回清理后的文本 154 # 如果不是JSON格式,直接返回清理后的文本
155 return cleaned_output 155 return cleaned_output
156 156
@@ -306,7 +306,7 @@ class ReflectionSummaryNode(StateMutationNode): @@ -306,7 +306,7 @@ class ReflectionSummaryNode(StateMutationNode):
306 result = json.loads(cleaned_output) 306 result = json.loads(cleaned_output)
307 logger.info("JSON解析成功") 307 logger.info("JSON解析成功")
308 except JSONDecodeError as e: 308 except JSONDecodeError as e:
309 - logger.exception(f"JSON解析失败: {str(e)}") 309 + logger.error(f"JSON解析失败: {str(e)}")
310 # 尝试修复JSON 310 # 尝试修复JSON
311 fixed_json = fix_incomplete_json(cleaned_output) 311 fixed_json = fix_incomplete_json(cleaned_output)
312 if fixed_json: 312 if fixed_json:
@@ -314,11 +314,11 @@ class ReflectionSummaryNode(StateMutationNode): @@ -314,11 +314,11 @@ class ReflectionSummaryNode(StateMutationNode):
314 result = json.loads(fixed_json) 314 result = json.loads(fixed_json)
315 logger.info("JSON修复成功") 315 logger.info("JSON修复成功")
316 except JSONDecodeError: 316 except JSONDecodeError:
317 - logger.exception("JSON修复失败,直接使用清理后的文本") 317 + logger.error("JSON修复失败,直接使用清理后的文本")
318 # 如果不是JSON格式,直接返回清理后的文本 318 # 如果不是JSON格式,直接返回清理后的文本
319 return cleaned_output 319 return cleaned_output
320 else: 320 else:
321 - logger.exception("无法修复JSON,直接使用清理后的文本") 321 + logger.error("无法修复JSON,直接使用清理后的文本")
322 # 如果不是JSON格式,直接返回清理后的文本 322 # 如果不是JSON格式,直接返回清理后的文本
323 return cleaned_output 323 return cleaned_output
324 324
@@ -138,7 +138,7 @@ class ReportAgent: @@ -138,7 +138,7 @@ class ReportAgent:
138 self.state = ReportState() 138 self.state = ReportState()
139 139
140 # 确保输出目录存在 140 # 确保输出目录存在
141 - os.makedirs(settings.OUTPUT_DIR, exist_ok=True) 141 + os.makedirs(self.config.OUTPUT_DIR, exist_ok=True)
142 142
143 logger.info("Report Agent已初始化") 143 logger.info("Report Agent已初始化")
144 logger.info(f"使用LLM: {self.llm_client.get_model_info()}") 144 logger.info(f"使用LLM: {self.llm_client.get_model_info()}")
@@ -146,11 +146,11 @@ class ReportAgent: @@ -146,11 +146,11 @@ class ReportAgent:
146 def _setup_logging(self): 146 def _setup_logging(self):
147 """设置日志""" 147 """设置日志"""
148 # 确保日志目录存在 148 # 确保日志目录存在
149 - log_dir = os.path.dirname(settings.LOG_FILE) 149 + log_dir = os.path.dirname(self.config.LOG_FILE)
150 os.makedirs(log_dir, exist_ok=True) 150 os.makedirs(log_dir, exist_ok=True)
151 151
152 # 创建专用的logger,避免与其他模块冲突 152 # 创建专用的logger,避免与其他模块冲突
153 - logger.add(settings.LOG_FILE, level="INFO") 153 + logger.add(self.config.LOG_FILE, level="INFO")
154 154
155 def _initialize_file_baseline(self): 155 def _initialize_file_baseline(self):
156 """初始化文件数量基准""" 156 """初始化文件数量基准"""
@@ -164,9 +164,9 @@ class ReportAgent: @@ -164,9 +164,9 @@ class ReportAgent:
164 def _initialize_llm(self) -> LLMClient: 164 def _initialize_llm(self) -> LLMClient:
165 """初始化LLM客户端""" 165 """初始化LLM客户端"""
166 return LLMClient( 166 return LLMClient(
167 - api_key=settings.REPORT_ENGINE_API_KEY,  
168 - model_name=settings.REPORT_ENGINE_MODEL_NAME,  
169 - base_url=settings.REPORT_ENGINE_BASE_URL, 167 + api_key=self.config.REPORT_ENGINE_API_KEY,
  168 + model_name=self.config.REPORT_ENGINE_MODEL_NAME,
  169 + base_url=self.config.REPORT_ENGINE_BASE_URL,
170 ) 170 )
171 171
172 def _initialize_nodes(self): 172 def _initialize_nodes(self):
@@ -351,7 +351,7 @@ class ReportAgent: @@ -351,7 +351,7 @@ class ReportAgent:
351 query_safe = query_safe.replace(' ', '_')[:30] 351 query_safe = query_safe.replace(' ', '_')[:30]
352 352
353 filename = f"final_report_{query_safe}_{timestamp}.html" 353 filename = f"final_report_{query_safe}_{timestamp}.html"
354 - filepath = os.path.join(settings.OUTPUT_DIR, filename) 354 + filepath = os.path.join(self.config.OUTPUT_DIR, filename)
355 355
356 # 保存HTML报告 356 # 保存HTML报告
357 with open(filepath, 'w', encoding='utf-8') as f: 357 with open(filepath, 'w', encoding='utf-8') as f:
@@ -361,7 +361,7 @@ class ReportAgent: @@ -361,7 +361,7 @@ class ReportAgent:
361 361
362 # 保存状态 362 # 保存状态
363 state_filename = f"report_state_{query_safe}_{timestamp}.json" 363 state_filename = f"report_state_{query_safe}_{timestamp}.json"
364 - state_filepath = os.path.join(settings.OUTPUT_DIR, state_filename) 364 + state_filepath = os.path.join(self.config.OUTPUT_DIR, state_filename)
365 self.state.save_to_file(state_filepath) 365 self.state.save_to_file(state_filepath)
366 logger.info(f"状态已保存到: {state_filepath}") 366 logger.info(f"状态已保存到: {state_filepath}")
367 367
@@ -145,7 +145,7 @@ class TemplateSelectionNode(BaseNode): @@ -145,7 +145,7 @@ class TemplateSelectionNode(BaseNode):
145 return None 145 return None
146 146
147 except json.JSONDecodeError as e: 147 except json.JSONDecodeError as e:
148 - logger.exception(f"JSON解析失败: {str(e)}") 148 + logger.error(f"JSON解析失败: {str(e)}")
149 # 尝试从文本响应中提取模板信息 149 # 尝试从文本响应中提取模板信息
150 return self._extract_template_from_text(response, available_templates) 150 return self._extract_template_from_text(response, available_templates)
151 151