diff --git a/services/process_monitor.py b/services/process_monitor.py index 5ec41fb..1779db6 100644 --- a/services/process_monitor.py +++ b/services/process_monitor.py @@ -341,6 +341,9 @@ class ProcessMonitor: except Exception as e: logger.error(f"处理会话异常: {session_id} - {e}") db.update_session_status(session_id, 'failed') + # 确保清理 + if session_id in self.active_sessions: + del self.active_sessions[session_id] return {'success': False, 'message': str(e)} def _start_step(self, session_id, product_name, step_num, step_name): @@ -466,36 +469,65 @@ class ProcessMonitor: def _call_agent(self, task_text): """调用智能体执行任务""" + import signal + try: cmd = [ 'openclaw', 'agent', '--agent', 'hz4th_editor', - '--message', task_text + '--message', task_text, + '--json' # 输出JSON格式以便解析 ] - logger.info(f"调用智能体命令: openclaw agent --agent hz4th_editor --message '[任务文本 {len(task_text)} 字符]'") + logger.info(f"调用智能体命令: openclaw agent --agent hz4th_editor --message '[任务文本 {len(task_text)} 字符]' --json") - result = subprocess.run( + # 使用Popen以便更好地控制超时和进程杀死 + proc = subprocess.Popen( cmd, - capture_output=True, - text=True, - timeout=300 # 5分钟超时 + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + preexec_fn=os.setsid # 创建新进程组,方便杀死所有子进程 ) - if result.returncode == 0: - output = result.stdout.strip() - logger.info(f"智能体返回: {output[:500]}...") - return {'success': True, 'output': output} - else: - error = result.stderr.strip() or result.stdout.strip() - logger.error(f"智能体调用失败: {error}") - return {'success': False, 'error': error} + try: + stdout, stderr = proc.communicate(timeout=180) # 3分钟超时 + raw_output = stdout.decode('utf-8', errors='replace').strip() + + if proc.returncode == 0: + # 解析JSON输出 + try: + data = json.loads(raw_output) + # 提取实际回复文本: result.payloads[0].text + payloads = data.get('result', {}).get('payloads', []) + if payloads and isinstance(payloads[0], dict): + output = payloads[0].get('text', '') + else: + output = raw_output + + logger.info(f"智能体返回: {output[:500]}...") + return {'success': True, 'output': output} + except json.JSONDecodeError as e: + logger.warning(f"JSON解析失败,使用原始输出: {e}") + return {'success': True, 'output': raw_output} + else: + error = stderr.decode('utf-8', errors='replace').strip() or raw_output + logger.error(f"智能体调用失败(returncode={proc.returncode}): {error}") + return {'success': False, 'error': error} + + except subprocess.TimeoutExpired: + # 超时,杀死整个进程组 + logger.error(f"智能体执行超时(>3分钟),杀死进程组") + try: + os.killpg(os.getpgid(proc.pid), signal.SIGKILL) + except Exception: + proc.kill() + proc.wait() + return {'success': False, 'error': '智能体执行超时(>3分钟)'} - except subprocess.TimeoutExpired: - return {'success': False, 'error': '智能体执行超时(>5分钟)'} except FileNotFoundError: return {'success': False, 'error': 'openclaw命令未找到'} except Exception as e: + logger.error(f"智能体调用异常: {e}") return {'success': False, 'error': str(e)} def _parse_agent_response(self, output):