{"id":1264,"date":"2025-12-03T10:50:37","date_gmt":"2025-12-03T02:50:37","guid":{"rendered":"http:\/\/www.preluna.xyz\/?p=1264"},"modified":"2025-12-03T23:13:18","modified_gmt":"2025-12-03T15:13:18","slug":"nagaagent-agentserver","status":"publish","type":"post","link":"http:\/\/www.preluna.xyz\/index.php\/2025\/12\/03\/nagaagent-agentserver\/preluna\/text\/","title":{"rendered":"NagaAgent\/agentserver"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">1<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">agent_server.py<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>#!\/usr\/bin\/env python3\n# -*- coding: utf-8 -*-\n\"\"\"\n\u7b2c\u4e00\u884c\uff1a\u544a\u8bc9\u7535\u8111\u201c\u8bf7\u7528python3\u6765\u8fd0\u884c\u8fd9\u4e2a\u6587\u4ef6\u201d\n\u7b2c\u4e8c\u884c\uff1a\u544a\u8bc9\u7535\u8111\u201c\u8fd9\u4e2a\u6587\u4ef6\u7528\u7684\u662fUTF-8\u7f16\u7801\u201d\uff08\u8fd9\u6837\u5c31\u80fd\u663e\u793a\u4e2d\u6587\u4e86\uff09\nNagaAgent\u72ec\u7acb\u670d\u52a1 - \u57fa\u4e8e\u535a\u5f08\u8bba\u7684\u7535\u8111\u63a7\u5236\u667a\u80fd\u4f53\n\u63d0\u4f9b\u610f\u56fe\u8bc6\u522b\u548c\u7535\u8111\u63a7\u5236\u4efb\u52a1\u6267\u884c\u529f\u80fd\n\"\"\"\n\nimport asyncio   # \u5904\u7406\u201c\u5f02\u6b65\u201d\u4efb\u52a1\uff08\u53ef\u4ee5\u540c\u65f6\u505a\u591a\u4ef6\u4e8b\uff09\nimport uuid      # \u751f\u6210\u552f\u4e00\u7684ID\u53f7\u7801\uff08\u50cf\u8eab\u4efd\u8bc1\u53f7\u4e00\u6837\uff09\nimport logging    # \u8bb0\u5f55\u7a0b\u5e8f\u8fd0\u884c\u65e5\u5fd7\uff08\u5c31\u50cf\u5199\u65e5\u8bb0\uff09\nfrom typing import Dict, Any, Optional, List   # \u5b9a\u4e49\u6570\u636e\u7c7b\u578b\nfrom datetime import datetime\n\nfrom fastapi import FastAPI, HTTPException  # \u521b\u5efaWeb\u670d\u52a1\u7684\u5de5\u5177\nfrom fastapi.responses import JSONResponse  # \u8fd4\u56deJSON\u683c\u5f0f\u6570\u636e\nfrom contextlib import asynccontextmanager  # \u7ba1\u7406\u7a0b\u5e8f\u542f\u52a8\u548c\u5173\u95ed\n\nfrom system.config import config            # \u914d\u7f6e\u6587\u4ef6\nfrom system.background_analyzer import get_background_analyzer   # \u610f\u56fe\u5206\u6790\u5668\nfrom agentserver.agent_computer_control import ComputerControlAgent   # \u7535\u8111\u63a7\u5236\u6838\u5fc3\nfrom agentserver.task_scheduler import get_task_scheduler, TaskStep   # \u4efb\u52a1\u5b89\u6392\u5668\nfrom agentserver.toolkit_manager import toolkit_manager         # \u5de5\u5177\u7ba1\u7406\u5668\n\n# \u914d\u7f6e\u65e5\u5fd7\n#\u683c\u5f0f\u89e3\u91ca\uff1a\u65f6\u95f4 - \u540d\u5b57 - \u7b49\u7ea7 - \u6d88\u606f\uff0c2024-01-01 10:00:00 - __main__ - INFO - \u670d\u52a1\u542f\u52a8\u6210\u529f\nlogger = logging.getLogger(__name__)     # \u521b\u5efa\u4e00\u4e2a\u201c\u65e5\u8bb0\u672c\u201d\nlogger.setLevel(logging.INFO)            # \u8bbe\u7f6e\u8bb0\u5f55\u7ea7\u522b\uff08INFO\u7ea7\uff09\nif not logger.handlers:                  # \u5982\u679c\u8fd8\u6ca1\u6709\u5199\u65e5\u8bb0\u7684\u5de5\u5177\uff0c\u5c31\u521b\u5efa\u4e00\u4e2a\n    handler = logging.StreamHandler()    # \u521b\u5efa\u4e00\u4e2a\u5f80\u63a7\u5236\u53f0\u8f93\u51fa\u7684\u5de5\u5177\n    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')   # \u65e5\u8bb0\u683c\u5f0f\n    handler.setFormatter(formatter)      # \u5e94\u7528\u683c\u5f0f\n    logger.addHandler(handler)           # \u628a\u5de5\u5177\u7ed9\u65e5\u8bb0\u672c\n\n@asynccontextmanager\nasync def lifespan(app: FastAPI):\n    \"\"\"FastAPI\u5e94\u7528\u751f\u547d\u5468\u671f\"\"\"\n    # startup\n    try:\n        # \u521d\u59cb\u5316\u610f\u56fe\u5206\u6790\u5668\uff08\u7406\u89e3\u4f60\u60f3\u505a\u4ec0\u4e48\uff09\n        Modules.analyzer = get_background_analyzer()\n        # \u521d\u59cb\u5316\u7535\u8111\u63a7\u5236\u667a\u80fd\u4f53 \uff08\u5b9e\u9645\u63a7\u5236\u7535\u8111\uff09\n        Modules.computer_control = ComputerControlAgent()\n        # \u521d\u59cb\u5316\u4efb\u52a1\u8c03\u5ea6\u5668 \uff08\u5b89\u6392\u4efb\u52a1\u987a\u5e8f\uff09\n        Modules.task_scheduler = get_task_scheduler()\n        \n        # \u8bbe\u7f6eLLM\u914d\u7f6e\u7528\u4e8e\u667a\u80fd\u538b\u7f29\uff0c\u8bbe\u7f6eAI\u5927\u8111\u914d\u7f6e\n        if hasattr(config, 'api') and config.api:\n            llm_config = {\n                \"model\": config.api.model,       # AI\u6a21\u578b\u540d\u5b57\n                \"api_key\": config.api.api_key,   # \u94a5\u5319\n                \"api_base\": config.api.base_url  # \u670d\u52a1\u5668\u5730\u5740\n            }\n            Modules.task_scheduler.set_llm_config(llm_config)\n        \n        logger.info(\"NagaAgent\u7535\u8111\u63a7\u5236\u670d\u52a1\u521d\u59cb\u5316\u5b8c\u6210\")\n    except Exception as e:\n        logger.error(f\"\u670d\u52a1\u521d\u59cb\u5316\u5931\u8d25: {e}\")\n        raise\n\n    # \u8fd0\u884c\u671f\n    yield   # \u7a0b\u5e8f\u6b63\u5e38\u8fd0\u884c\u4e2d\n\n    # shutdown\n    try:\n        logger.info(\"NagaAgent\u7535\u8111\u63a7\u5236\u670d\u52a1\u5df2\u5173\u95ed\")\n    except Exception as e:\n        logger.error(f\"\u670d\u52a1\u5173\u95ed\u5931\u8d25: {e}\")\n\n#\u521b\u5efaWeb\u670d\u52a1\uff0c\u521b\u5efa\u4e00\u4e2a\u53ebapp\u7684Web\u670d\u52a1\u5668\uff0c\u540d\u5b57\uff1aNagaAgent Computer Control Server\uff0c\u7248\u672c\uff1a1.0.0\uff0c\u4f7f\u7528\u521a\u624d\u5b9a\u4e49\u7684lifespan\u7ba1\u7406\u5f00\u5173\u673a\napp = FastAPI(title=\"NagaAgent Computer Control Server\", version=\"1.0.0\", lifespan=lifespan)\n\nclass Modules:\n    \"\"\"\u5168\u5c40\u6a21\u5757\u7ba1\u7406\u5668\"\"\"\n    analyzer = None             # \u610f\u56fe\u5206\u6790\u5668\uff08\u7406\u89e3\u4f60\u8981\u4ec0\u4e48\uff09\n    computer_control = None     # \u7535\u8111\u63a7\u5236\u5668\uff08\u5b9e\u9645\u5e72\u6d3b\uff09\n    task_scheduler = None       # \u4efb\u52a1\u5b89\u6392\u5668\uff08\u5b89\u6392\u987a\u5e8f\uff09\n\n#\u4f5c\u7528\uff1a\u83b7\u53d6\u73b0\u5728\u7684\u65f6\u95f4\uff0c\u683c\u5f0f\u5316\u6210\u6807\u51c6\u5b57\u7b26\u4e32\uff0c\u4f8b\u5b50\uff1a\"2024-01-01T10:00:00.123456\"\ndef _now_iso() -> str:\n    \"\"\"\u83b7\u53d6\u5f53\u524d\u65f6\u95f4ISO\u683c\u5f0f\"\"\"\n    return datetime.now().isoformat()\n\n#\u5904\u7406\u7535\u8111\u63a7\u5236\u4efb\u52a1\uff08\u6838\u5fc3\u529f\u80fd\uff09\uff0c\u8fd9\u4e2a\u51fd\u6570\u662f\u6838\u5fc3\uff0c\u5b83\uff1a\n#1.\u63a5\u6536\u4e00\u4e2a\u6307\u4ee4\uff08\u6bd4\u5982\u201c\u6253\u5f00\u8bb0\u4e8b\u672c\u201d\uff092.\u8c03\u7528\u7535\u8111\u63a7\u5236\u667a\u80fd\u4f53\u6267\u884c3.\u8fd4\u56de\u6267\u884c\u7ed3\u679c\nasync def _process_computer_control_task(instruction: str, session_id: Optional&#91;str] = None) -> Dict&#91;str, Any]:\n    \"\"\"\u5904\u7406\u7535\u8111\u63a7\u5236\u4efb\u52a1\"\"\"\n    try:    # 1. \u8bb0\u5f55\u5f00\u59cb\u6267\u884c\n        logger.info(f\"\u5f00\u59cb\u5904\u7406\u7535\u8111\u63a7\u5236\u4efb\u52a1: {instruction}\")\n        \n        #  2. \u76f4\u63a5\u8c03\u7528\u7535\u8111\u63a7\u5236\u667a\u80fd\u4f53\n        result = await Modules.computer_control.handle_handoff({\n            \"action\": \"automate_task\",   # \u52a8\u4f5c\uff1a\u81ea\u52a8\u6267\u884c\u4efb\u52a1\n            \"target\": instruction,       # \u76ee\u6807\uff1a\u7528\u6237\u7ed9\u7684\u6307\u4ee4\n            \"parameters\": {}             # \u989d\u5916\u53c2\u6570\uff08\u8fd9\u91cc\u4e3a\u7a7a\uff09\n        })\n\n        # 3. \u8bb0\u5f55\u5b8c\u6210\uff0c\u8fd4\u56de\u6210\u529f\u7ed3\u679c\n        logger.info(f\"\u7535\u8111\u63a7\u5236\u4efb\u52a1\u5b8c\u6210: {instruction}\")\n        return {\n            \"success\": True,            # \u6210\u529f\u4e86\u5417\uff1fTrue=\u6210\u529f\n            \"result\": result,           # \u5177\u4f53\u7ed3\u679c\n            \"task_type\": \"computer_control\",     # \u4efb\u52a1\u7c7b\u578b\n            \"instruction\": instruction   # \u539f\u6307\u4ee4\n        }\n        \n    except Exception as e:       # \u5982\u679c\u51fa\u9519\u4e86\n        # 4. \u8bb0\u5f55\u9519\u8bef\uff0c\u8fd4\u56de\u5931\u8d25\u7ed3\u679c\n        logger.error(f\"\u7535\u8111\u63a7\u5236\u4efb\u52a1\u5931\u8d25: {e}\")\n        return {\n            \"success\": False,        # \u6210\u529f\u4e86\u5417\uff1fFalse=\u5931\u8d25\n            \"error\": str(e),         # \u9519\u8bef\u4fe1\u606f\n            \"task_type\": \"computer_control\",\n            \"instruction\": instruction\n        }\n\n# \u5f02\u6b65\u6267\u884c\u591a\u4e2a\u4efb\u52a1\uff0c\u8fd9\u4e2a\u51fd\u6570\u5904\u7406\u591a\u4e2a\u4efb\u52a1\uff1a\n#agent_calls: \u4efb\u52a1\u5217\u8868\uff08\u591a\u4e2a\u8981\u6267\u884c\u7684\u4efb\u52a1\uff09\uff0csession_id: \u4f1a\u8bddID\uff08\u533a\u5206\u4e0d\u540c\u7528\u6237\uff09\n#analysis_session_id: \u5206\u6790\u4f1a\u8bddID\uff0crequest_id: \u8bf7\u6c42ID\uff08\u6bcf\u4e2a\u8bf7\u6c42\u552f\u4e00\u7f16\u53f7\uff09\uff0ccallback_url: \u56de\u8c03\u5730\u5740\uff08\u5b8c\u6210\u540e\u901a\u77e5\u8c01\uff09\nasync def _execute_agent_tasks_async(agent_calls: List&#91;Dict&#91;str, Any]], session_id: str, \n                                   analysis_session_id: str, request_id: str, callback_url: Optional&#91;str] = None):\n    \"\"\"\u5f02\u6b65\u6267\u884cAgent\u4efb\u52a1 - \u5e94\u7528\u4e0eMCP\u670d\u52a1\u5668\u76f8\u540c\u7684\u4f1a\u8bdd\u7ba1\u7406\u903b\u8f91\"\"\"\n    try:\n        logger.info(f\"&#91;\u5f02\u6b65\u6267\u884c] \u5f00\u59cb\u6267\u884c {len(agent_calls)} \u4e2aAgent\u4efb\u52a1\")\n        \n        # \u5904\u7406\u6bcf\u4e2aAgent\u4efb\u52a1\n        results = &#91;]\n        # 1. \u5faa\u73af\u5904\u7406\u6bcf\u4e2a\u4efb\u52a1\n        for i, agent_call in enumerate(agent_calls):  # \u53d6\u51fa\u4efb\u52a1\u4fe1\u606f\n            try:\n                instruction = agent_call.get(\"instruction\", \"\")      # \u6307\u4ee4\n                tool_name = agent_call.get(\"tool_name\", \"\u672a\u77e5\u5de5\u5177\")   # \u5de5\u5177\u540d\n                service_name = agent_call.get(\"service_name\", \"\u672a\u77e5\u670d\u52a1\")   # \u670d\u52a1\u540d\n                \n                logger.info(f\"&#91;\u5f02\u6b65\u6267\u884c] \u6267\u884c\u4efb\u52a1 {i+1}\/{len(agent_calls)}: {tool_name} - {instruction}\")\n                \n                # \u6dfb\u52a0\u4efb\u52a1\u6b65\u9aa4\u5230\u8c03\u5ea6\u5668\n                # 2. \u8bb0\u5f55\u6b65\u9aa4\u5230\u4efb\u52a1\u8c03\u5ea6\u5668\uff08\u5c31\u50cf\u5199\u5f85\u529e\u4e8b\u9879\uff09\n                await Modules.task_scheduler.add_task_step(request_id, TaskStep(\n                    step_id=f\"step_{i+1}\",\n                    task_id=request_id,\n                    purpose=f\"\u6267\u884cAgent\u4efb\u52a1: {tool_name}\",\n                    content=instruction,\n                    output=\"\",\n                    analysis=None,\n                    success=True\n                ))\n                \n                #3.\u6267\u884c\u7535\u8111\u63a7\u5236\u4efb\u52a1\n                result = await _process_computer_control_task(instruction, session_id)\n                results.append({\n                    \"agent_call\": agent_call,\n                    \"result\": result,\n                    \"step_index\": i\n                })\n                \n                # 4.\u66f4\u65b0\u4efb\u52a1\u6b65\u9aa4\u7ed3\u679c\n                await Modules.task_scheduler.add_task_step(request_id, TaskStep(\n                    step_id=f\"step_{i+1}_result\",\n                    task_id=request_id,\n                    purpose=f\"\u4efb\u52a1\u7ed3\u679c: {tool_name}\",\n                    content=f\"\u6267\u884c\u7ed3\u679c: {result.get('success', False)}\",\n                    output=str(result.get('result', '')),\n                    analysis={\"analysis\": f\"\u4efb\u52a1\u7c7b\u578b: {result.get('task_type', 'unknown')}, \u5de5\u5177: {tool_name}, \u670d\u52a1: {service_name}\"},\n                    success=result.get('success', False),\n                    error=result.get('error')\n                ))\n\n                \n                logger.info(f\"&#91;\u5f02\u6b65\u6267\u884c] \u4efb\u52a1 {i+1} \u5b8c\u6210: {result.get('success', False)}\")\n                \n            except Exception as e:\n                logger.error(f\"&#91;\u5f02\u6b65\u6267\u884c] \u4efb\u52a1 {i+1} \u6267\u884c\u5931\u8d25: {e}\")\n                results.append({\n                    \"agent_call\": agent_call,\n                    \"result\": {\"success\": False, \"error\": str(e)},\n                    \"step_index\": i\n                })\n                '''\u5faa\u73af\u8fc7\u7a0b\uff1a\n                    \u4efb\u52a11: \"\u6253\u5f00\u6d4f\u89c8\u5668\" \u2192 \u6267\u884c \u2192 \u8bb0\u5f55\u7ed3\u679c\n                    \u4efb\u52a12: \"\u641c\u7d22Python\u6559\u7a0b\" \u2192 \u6267\u884c \u2192 \u8bb0\u5f55\u7ed3\u679c\n                    \u4efb\u52a13: \"\u4fdd\u5b58\u7f51\u9875\" \u2192 \u6267\u884c \u2192 \u8bb0\u5f55\u7ed3\u679c\n                '''\n        \n        # \u53d1\u9001\u56de\u8c03\u901a\u77e5\uff08\u5982\u679c\u63d0\u4f9b\u4e86\u56de\u8c03URL\uff09\n        if callback_url:\n            await _send_callback_notification(callback_url, request_id, session_id, analysis_session_id, results)\n        \n        logger.info(f\"&#91;\u5f02\u6b65\u6267\u884c] \u6240\u6709Agent\u4efb\u52a1\u6267\u884c\u5b8c\u6210: {len(results)} \u4e2a\u4efb\u52a1\")\n        \n    except Exception as e:\n        logger.error(f\"&#91;\u5f02\u6b65\u6267\u884c] Agent\u4efb\u52a1\u6267\u884c\u5931\u8d25: {e}\")\n        # \u53d1\u9001\u9519\u8bef\u56de\u8c03\n        if callback_url:\n            await _send_callback_notification(callback_url, request_id, session_id, analysis_session_id, &#91;], str(e))\n\n# \u53d1\u9001\u56de\u8c03\u901a\u77e5,\u8fd9\u4e2a\u51fd\u6570\u5728\u4efb\u52a1\u5b8c\u6210\u540e\u901a\u77e5\u522b\u4eba\uff1a\n'''\n\u53d1\u9001\u7684\u5185\u5bb9\uff1a\n{\n  \"request_id\": \"123\",          \/\/ \u8bf7\u6c42ID\n  \"session_id\": \"abc\",          \/\/ \u4f1a\u8bddID\n  \"analysis_session_id\": \"xyz\", \/\/ \u5206\u6790\u4f1a\u8bddID\n  \"success\": true,             \/\/ \u662f\u5426\u6210\u529f\n  \"error\": null,               \/\/ \u9519\u8bef\u4fe1\u606f\uff08\u5982\u679c\u6ca1\u6709\u5c31\u662fnull\uff09\n  \"results\": &#91;...],            \/\/ \u6240\u6709\u4efb\u52a1\u7ed3\u679c\n  \"completed_at\": \"2024-01-01T10:00:00\"  \/\/ \u5b8c\u6210\u65f6\u95f4\n}\n'''\nasync def _send_callback_notification(callback_url: str, request_id: str, session_id: str, \n                                    analysis_session_id: str, results: List&#91;Dict&#91;str, Any]], error: Optional&#91;str] = None):\n    \"\"\"\u53d1\u9001\u56de\u8c03\u901a\u77e5 - \u5e94\u7528\u4e0eMCP\u670d\u52a1\u5668\u76f8\u540c\u7684\u56de\u8c03\u673a\u5236\"\"\"\n    try:\n        import httpx\n        \n        callback_payload = {\n            \"request_id\": request_id,\n            \"session_id\": session_id,\n            \"analysis_session_id\": analysis_session_id,\n            \"success\": error is None,\n            \"error\": error,\n            \"results\": results,\n            \"completed_at\": _now_iso()\n        }\n        \n        async with httpx.AsyncClient(timeout=10.0) as client:\n            response = await client.post(callback_url, json=callback_payload)\n            if response.status_code == 200:\n                logger.info(f\"&#91;\u56de\u8c03\u901a\u77e5] Agent\u4efb\u52a1\u7ed3\u679c\u56de\u8c03\u6210\u529f: {request_id}\")\n            else:\n                logger.error(f\"&#91;\u56de\u8c03\u901a\u77e5] Agent\u4efb\u52a1\u7ed3\u679c\u56de\u8c03\u5931\u8d25: {response.status_code}\")\n                \n    except Exception as e:\n        logger.error(f\"&#91;\u56de\u8c03\u901a\u77e5] \u53d1\u9001Agent\u4efb\u52a1\u56de\u8c03\u5931\u8d25: {e}\")\n\n# ============ API\u7aef\u70b9 ============\n\n@app.get(\"\/health\")\nasync def health_check():\n    \"\"\"\u5065\u5eb7\u68c0\u67e5\"\"\"\n    return {\n        \"status\": \"healthy\",    # \u72b6\u6001\uff1a\u5065\u5eb7\n        \"timestamp\": _now_iso(),   # \u5f53\u524d\u65f6\u95f4\n        \"modules\": {          # \u5404\u4e2a\u5de5\u5177\u662f\u5426\u51c6\u5907\u597d\n            \"analyzer\": Modules.analyzer is not None,   # \u5206\u6790\u5668\u51c6\u5907\u597d\u4e86\u5417\uff1f\n            \"computer_control\": Modules.computer_control is not None   # \u7535\u8111\u63a7\u5236\u5668\u51c6\u5907\u597d\u4e86\u5417\uff1f\n        }\n    }\n'''\n\u8bbf\u95ee\u65b9\u5f0f\uff1a\n\u7f51\u5740\uff1ahttp:\/\/\u670d\u52a1\u5668\u5730\u5740\/health\n\u65b9\u6cd5\uff1aGET\uff08\u67e5\u770b\uff09\n\u8fd4\u56de\u793a\u4f8b:\n{\n  \"status\": \"healthy\",\n  \"timestamp\": \"2024-01-01T10:00:00\",\n  \"modules\": {\n    \"analyzer\": true,      \/\/ true\u8868\u793a\u51c6\u5907\u597d\u4e86\n    \"computer_control\": true\n  }\n}\n'''\n\n@app.post(\"\/schedule\")\nasync def schedule_agent_tasks(payload: Dict&#91;str, Any]):\n    \"\"\"\u7edf\u4e00\u7684\u4efb\u52a1\u8c03\u5ea6\u7aef\u70b9\uff08\u4e3b\u8981\u5165\u53e3\uff09 - \u5e94\u7528\u4e0eMCP\u670d\u52a1\u5668\u76f8\u540c\u7684\u4f1a\u8bdd\u7ba1\u7406\u903b\u8f91\"\"\"\n    # 1. \u5148\u68c0\u67e5\u5de5\u5177\u662f\u5426\u51c6\u5907\u597d\n    if not Modules.computer_control or not Modules.task_scheduler:\n        raise HTTPException(503, \"\u7535\u8111\u63a7\u5236\u667a\u80fd\u4f53\u6216\u4efb\u52a1\u8c03\u5ea6\u5668\u672a\u5c31\u7eea\")\n    \n    # \u63d0\u53d6\u65b0\u7684\u8bf7\u6c42\u683c\u5f0f\u53c2\u6570\n    query = payload.get(\"query\", \"\")   # \u67e5\u8be2\u5185\u5bb9\n    agent_calls = payload.get(\"agent_calls\", &#91;])   # \u8981\u6267\u884c\u7684\u4efb\u52a1\u5217\u8868\n    session_id = payload.get(\"session_id\")         # \u4f1a\u8bddID\uff08\u54ea\u4e2a\u987e\u5ba2\uff09\n    analysis_session_id = payload.get(\"analysis_session_id\")   # \u5206\u6790\u4f1a\u8bddID\n    request_id = payload.get(\"request_id\", str(uuid.uuid4()))  # \u8bf7\u6c42ID\uff0c\u5982\u679c\u6ca1\u6709\u5c31\u751f\u6210\u4e00\u4e2a\n    callback_url = payload.get(\"callback_url\")     # \u5b8c\u6210\u540e\u901a\u77e5\u7684\u5730\u5740\n    \n    try:\n        logger.info(f\"&#91;\u7edf\u4e00\u8c03\u5ea6] \u63a5\u6536Agent\u4efb\u52a1\u8c03\u5ea6\u8bf7\u6c42: {query}\")\n        logger.info(f\"&#91;\u7edf\u4e00\u8c03\u5ea6] \u4f1a\u8bddID: {session_id}, \u5206\u6790\u4f1a\u8bddID: {analysis_session_id}, \u8bf7\u6c42ID: {request_id}\")\n        \n        if not agent_calls:   # \u5982\u679c\u4efb\u52a1\u5217\u8868\u662f\u7a7a\u7684\n            return {\n                \"success\": True,\n                \"status\": \"no_tasks\",    # \u72b6\u6001\uff1a\u6ca1\u6709\u4efb\u52a1\n                \"message\": \"\u672a\u53d1\u73b0\u53ef\u6267\u884c\u7684Agent\u4efb\u52a1\",\n                \"task_id\": request_id,\n                \"accepted_at\": _now_iso(),\n                \"session_id\": session_id,\n                \"analysis_session_id\": analysis_session_id\n            }\n\n        logger.info(f\"&#91;\u7edf\u4e00\u8c03\u5ea6] \u4f1a\u8bdd {session_id} \u53d1\u73b0 {len(agent_calls)} \u4e2aAgent\u4efb\u52a1\")\n\n        # 1.\u6709\u4efb\u52a1,\u521b\u5efa\u4efb\u52a1\u8c03\u5ea6\u5668\u4efb\u52a1\n        task_id = await Modules.task_scheduler.create_task(\n            task_id=request_id,      # \u4efb\u52a1ID\n            purpose=f\"\u6267\u884cAgent\u4efb\u52a1: {query}\",   # \u4efb\u52a1\u76ee\u7684\n            session_id=session_id,   # \u4f1a\u8bddID\n            analysis_session_id=analysis_session_id    # \u5206\u6790\u4f1a\u8bddID\n        )\n\n        # 2.\u5f02\u6b65\u6267\u884c\u4efb\u52a1\uff08\u4e0d\u963b\u585e\u54cd\u5e94\uff09\n        asyncio.create_task(_execute_agent_tasks_async(   #asyncio.create_task()\uff1a\u521b\u5efa\u540e\u53f0\u4efb\u52a1\uff0c\u4e0d\u963b\u585e\u5f53\u524d\u8bf7\u6c42\n            agent_calls, session_id, analysis_session_id, request_id, callback_url\n        ))\n\n        #3.\u7acb\u5373\u8fd4\u56de\u7ed3\u679c\n        return {\n            \"success\": True,\n            \"status\": \"scheduled\",   # \u72b6\u6001\uff1a\u5df2\u5b89\u6392\n            \"task_id\": request_id,\n            \"message\": f\"\u5df2\u8c03\u5ea6 {len(agent_calls)} \u4e2aAgent\u4efb\u52a1\",\n            \"accepted_at\": _now_iso(),\n            \"session_id\": session_id,\n            \"analysis_session_id\": analysis_session_id\n        }\n        \n    except Exception as e:\n        logger.error(f\"&#91;\u7edf\u4e00\u8c03\u5ea6] Agent\u4efb\u52a1\u8c03\u5ea6\u5931\u8d25: {e}\")\n        raise HTTPException(500, f\"\u8c03\u5ea6\u5931\u8d25: {e}\")\n\n@app.post(\"\/analyze_and_execute\")\nasync def analyze_and_execute(payload: Dict&#91;str, Any]):\n    \"\"\"\u610f\u56fe\u5206\u6790\u548c\u7535\u8111\u63a7\u5236\u4efb\u52a1\u6267\u884c - \u4fdd\u6301\u5411\u540e\u517c\u5bb9\n    \u4e3a\u4ec0\u4e48\u9700\u8981\u8fd9\u4e2a\uff1f\n    \u4e3a\u4e86\u517c\u5bb9\u65e7\u7248\u672c\u7684\u7a0b\u5e8f,\u65b0\u7248\u672c\u7528\/schedule\uff0c\u65e7\u7248\u672c\u8fd8\u7528\u8fd9\u4e2a\n    \"\"\"\n    if not Modules.analyzer or not Modules.computer_control:\n        raise HTTPException(503, \"\u5206\u6790\u5668\u6216\u7535\u8111\u63a7\u5236\u667a\u80fd\u4f53\u672a\u5c31\u7eea\")\n    \n    messages = (payload or {}).get(\"messages\", &#91;])\n    if not isinstance(messages, list):\n        raise HTTPException(400, \"messages\u5fc5\u987b\u662f{role, content}\u683c\u5f0f\u7684\u5217\u8868\")\n    \n    session_id = (payload or {}).get(\"session_id\")\n    \n    try:\n        # \u76f4\u63a5\u6267\u884c\u7535\u8111\u63a7\u5236\u4efb\u52a1\uff0c\u4e0d\u8fdb\u884c\u610f\u56fe\u5206\u6790\n        # \u610f\u56fe\u5206\u6790\u5df2\u5728API\u670d\u52a1\u5668\u4e2d\u5b8c\u6210\uff0c\u8fd9\u91cc\u53ea\u8d1f\u8d23\u6267\u884c\u5177\u4f53\u7684Agent\u4efb\u52a1\n\n        # \u4ece\u6d88\u606f\u4e2d\u63d0\u53d6\u4efb\u52a1\u6307\u4ee4\n        tasks = &#91;]\n        for msg in messages:\n            if msg.get(\"role\") == \"user\":   # \u5982\u679c\u662f\u7528\u6237\u6d88\u606f\n                content = msg.get(\"content\", \"\")\n                if \"\u6267\u884cAgent\u4efb\u52a1:\" in content:   # \u5982\u679c\u5305\u542b\u7279\u5b9a\u5173\u952e\u8bcd\n                    # \u63d0\u53d6\u4efb\u52a1\u6307\u4ee4\n                    instruction = content.replace(\"\u6267\u884cAgent\u4efb\u52a1:\", \"\").strip()   # \u63d0\u53d6\u6307\u4ee4\n                    tasks.append({\n                        \"instruction\": instruction\n                    })\n                    '''\n                    \u793a\u4f8b\u6d88\u606f\u683c\u5f0f\uff1a\n                    {\n                      \"messages\": &#91;\n                          {\"role\": \"user\", \"content\": \"\u6267\u884cAgent\u4efb\u52a1: \u6253\u5f00\u8bb0\u4e8b\u672c\"},\n                          {\"role\": \"user\", \"content\": \"\u6267\u884cAgent\u4efb\u52a1: \u8f93\u5165Hello World\"}\n                      ]\n                    }\n                    '''\n'''\u4e0e\/schedule\u7684\u533a\u522b\uff1a\n\/schedule\uff1a\u5f02\u6b65\u6267\u884c\uff0c\u7acb\u5373\u8fd4\u56de\n\/analyze_and_execute\uff1a\u540c\u6b65\u6267\u884c\uff0c\u7b49\u6240\u6709\u4efb\u52a1\u5b8c\u6210\u624d\u8fd4\u56de\n\u5c31\u50cf\u5feb\u9910\u548c\u5802\u98df\u7684\u533a\u522b'''\n\n        if not tasks:\n            return {\n                \"success\": True,\n                \"status\": \"no_tasks\",\n                \"message\": \"\u672a\u53d1\u73b0\u53ef\u6267\u884c\u7684\u7535\u8111\u63a7\u5236\u4efb\u52a1\",\n                \"accepted_at\": _now_iso(),\n                \"session_id\": session_id\n            }\n\n        logger.info(f\"\u4f1a\u8bdd {session_id} \u53d1\u73b0 {len(tasks)} \u4e2a\u7535\u8111\u63a7\u5236\u4efb\u52a1\")\n\n        # \u5904\u7406\u6bcf\u4e2a\u4efb\u52a1\n        results = &#91;]\n        for task_instruction in tasks:\n            result = await _process_computer_control_task(task_instruction, session_id)\n            results.append(result)\n\n        return {\n            \"success\": True,\n            \"status\": \"completed\",\n            \"tasks_processed\": len(tasks),\n            \"results\": results,\n            \"accepted_at\": _now_iso(),\n            \"session_id\": session_id\n        }\n        \n    except Exception as e:\n        logger.error(f\"\u610f\u56fe\u5206\u6790\u548c\u4efb\u52a1\u6267\u884c\u5931\u8d25: {e}\")\n        raise HTTPException(500, f\"\u5904\u7406\u5931\u8d25: {e}\")\n\n@app.get(\"\/computer_control\/availability\")\nasync def get_computer_control_availability():\n    \"\"\"\u83b7\u53d6\u7535\u8111\u63a7\u5236\u53ef\u7528\u6027\uff08\u68c0\u67e5\u5de5\u5177\uff09\"\"\"\n    try:\n        if not Modules.computer_control:    # \u5982\u679c\u7535\u8111\u63a7\u5236\u5668\u4e0d\u5b58\u5728\n            return {\"ready\": False, \"reasons\": &#91;\"\u7535\u8111\u63a7\u5236\u667a\u80fd\u4f53\u672a\u521d\u59cb\u5316\"]}\n        \n        # \u68c0\u67e5\u7535\u8111\u63a7\u5236\u80fd\u529b\n        capabilities = Modules.computer_control.get_capabilities()\n        return {\n            \"ready\": capabilities.get(\"enabled\", False),   # \u662f\u5426\u53ef\u7528\n            \"capabilities\": capabilities,                  # \u5177\u4f53\u80fd\u529b\n            \"timestamp\": _now_iso()\n        }\n'''\n{\n  \"ready\": true,\n  \"capabilities\": {\n    \"enabled\": true,\n    \"tools\": &#91;\"\u9f20\u6807\u63a7\u5236\", \"\u952e\u76d8\u8f93\u5165\", \"\u622a\u56fe\"],\n    \"platform\": \"Windows\"\n  },\n  \"timestamp\": \"2024-01-01T10:00:00\"\n}\n'''\n    except Exception as e:\n        logger.error(f\"\u68c0\u67e5\u7535\u8111\u63a7\u5236\u53ef\u7528\u6027\u5931\u8d25: {e}\")\n        return {\"ready\": False, \"reasons\": &#91;f\"\u68c0\u67e5\u5931\u8d25: {e}\"]}\n\n@app.post(\"\/computer_control\/execute\")\nasync def execute_computer_control_task(payload: Dict&#91;str, Any]):\n    \"\"\"\u76f4\u63a5\u6267\u884c\u7535\u8111\u63a7\u5236\u4efb\u52a1\uff08\u5355\u70b9\u6267\u884c\uff09\"\"\"\n    if not Modules.computer_control:\n        raise HTTPException(503, \"\u7535\u8111\u63a7\u5236\u667a\u80fd\u4f53\u672a\u5c31\u7eea\")\n    \n    instruction = payload.get(\"instruction\", \"\")\n    if not instruction:    # \u5982\u679c\u6307\u4ee4\u4e3a\u7a7a\n        raise HTTPException(400, \"instruction\u4e0d\u80fd\u4e3a\u7a7a\")\n    \n    try:\n        result = await _process_computer_control_task(instruction)\n        return {\n            \"success\": result.get(\"success\", False),\n            \"result\": result.get(\"result\"),\n            \"error\": result.get(\"error\"),\n            \"instruction\": instruction\n        }\n    except Exception as e:\n        logger.error(f\"\u6267\u884c\u7535\u8111\u63a7\u5236\u4efb\u52a1\u5931\u8d25: {e}\")\n        raise HTTPException(500, f\"\u6267\u884c\u5931\u8d25: {e}\")\n'''\n\u4f7f\u7528\u573a\u666f\uff1a\n  \u53ea\u6267\u884c\u4e00\u4e2a\u7b80\u5355\u4efb\u52a1\n  \u9700\u8981\u7acb\u5373\u77e5\u9053\u7ed3\u679c\n  \u4e0d\u9700\u8981\u590d\u6742\u8c03\u5ea6\n\u793a\u4f8b\u8bf7\u6c42\uff1a  \n{\n  \"instruction\": \"\u6253\u5f00\u6d4f\u89c8\u5668\"\n}\n\u793a\u4f8b\u54cd\u5e94\uff1a\n{\n  \"success\": true,\n  \"result\": \"\u5df2\u6253\u5f00Chrome\u6d4f\u89c8\u5668\",\n  \"error\": null,\n  \"instruction\": \"\u6253\u5f00\u6d4f\u89c8\u5668\"\n}\n\u603b\u7ed3\u6240\u6709API\u7aef\u70b9 \n\u7aef\u70b9                              | \u65b9\u6cd5   |   \u7528\u9014           |  \u7279\u70b9\n\/health                          | GET    |  \u5065\u5eb7\u68c0\u67e5        |  \u5feb\u901f\u68c0\u67e5\u670d\u52a1\u72b6\u6001\n\/schedule                        | POST   |  \u7edf\u4e00\u4efb\u52a1\u8c03\u5ea6     |  \u4e3b\u8981\u5165\u53e3\uff0c\u5f02\u6b65\u6267\u884c\uff0c\u652f\u6301\u591a\u4e2a\u4efb\u52a1\n\/analyze_and_execute             | POST   |  \u610f\u56fe\u5206\u6790\u548c\u6267\u884c   |   \u517c\u5bb9\u65e7\u7248\u672c\uff0c\u540c\u6b65\u6267\u884c\n\/computer_control\/availability   | GET    |  \u83b7\u53d6\u53ef\u7528\u6027      |   \u68c0\u67e5\u7535\u8111\u63a7\u5236\u80fd\u529b\n\/computer_control\/execute        | POST\t  |  \u76f4\u63a5\u6267\u884c\u4efb\u52a1     |  \u5355\u4efb\u52a1\uff0c\u540c\u6b65\u6267\u884c\n'''\n# ============ \u4efb\u52a1\u8bb0\u5fc6\u7ba1\u7406API ============\n\n@app.get(\"\/tasks\")\nasync def get_tasks(session_id: Optional&#91;str] = None):\n    \"\"\"\u83b7\u53d6\u4efb\u52a1\u5217\u8868\uff08\u770b\u770b\u73b0\u5728\u5728\u5fd9\u4ec0\u4e48\uff09\"\"\"\n    # 1. \u68c0\u67e5\u5de5\u5177\u662f\u5426\u51c6\u5907\u597d\n    if not Modules.task_scheduler:\n        raise HTTPException(503, \"\u4efb\u52a1\u8c03\u5ea6\u5668\u672a\u5c31\u7eea\")\n    \n    try:\n        # 2. \u4ece\u8c03\u5ea6\u5668\u83b7\u53d6\u6b63\u5728\u8fd0\u884c\u7684\u4efb\u52a1\n        running_tasks = await Modules.task_scheduler.get_running_tasks()\n        return {\n            \"success\": True,\n            \"running_tasks\": running_tasks, # \u6b63\u5728\u8fd0\u884c\u7684\u4efb\u52a1\n            \"session_id\": session_id\n        }\n    except Exception as e:\n        logger.error(f\"\u83b7\u53d6\u4efb\u52a1\u5217\u8868\u5931\u8d25: {e}\")\n        raise HTTPException(500, f\"\u83b7\u53d6\u5931\u8d25: {e}\")\n'''\u4f7f\u7528\u793a\u4f8b\uff1a\nGET http:\/\/localhost:8000\/tasks\n\u53ef\u80fd\u8fd4\u56de\uff1a\n{\n  \"success\": true,\n  \"running_tasks\": &#91;\n    {\n      \"task_id\": \"task001\",\n      \"purpose\": \"\u6253\u5f00\u8bb0\u4e8b\u672c\u5e76\u8bb0\u5f55\",\n      \"status\": \"running\",\n      \"started_at\": \"2024-01-01T10:00:00\"\n    },\n    {\n      \"task_id\": \"task002\", \n      \"purpose\": \"\u4fdd\u5b58\u6587\u4ef6\",\n      \"status\": \"completed\",\n      \"started_at\": \"2024-01-01T09:30:00\"\n    }\n  ]\n}\n'''\n\n@app.get(\"\/tasks\/{task_id}\")\nasync def get_task_status(task_id: str):\n    \"\"\"\u83b7\u53d6\u6307\u5b9a\u4efb\u52a1\u72b6\u6001\uff08\u67e5\u770b\u5177\u4f53\u4efb\u52a1\uff09\"\"\"\n    if not Modules.task_scheduler:\n        raise HTTPException(503, \"\u4efb\u52a1\u8c03\u5ea6\u5668\u672a\u5c31\u7eea\")\n    \n    try:  # \u83b7\u53d6\u4efb\u52a1\u72b6\u6001\n        task_status = await Modules.task_scheduler.get_task_status(task_id)\n        # \u5982\u679c\u6ca1\u627e\u5230\uff0c\u8fd4\u56de404\u9519\u8bef\n        if not task_status:\n            raise HTTPException(404, f\"\u4efb\u52a1 {task_id} \u4e0d\u5b58\u5728\")\n        \n        return {\n            \"success\": True,\n            \"task\": task_status\n        }\n    except HTTPException:    # \u5982\u679c\u662f\u6211\u4eec\u4e3b\u52a8\u629b\u51fa\u7684\u9519\u8bef\uff0c\u76f4\u63a5\u4f20\u9012\n        raise\n    except Exception as e:   # \u5176\u4ed6\u672a\u77e5\u9519\u8bef\n        logger.error(f\"\u83b7\u53d6\u4efb\u52a1\u72b6\u6001\u5931\u8d25: {e}\")\n        raise HTTPException(500, f\"\u83b7\u53d6\u5931\u8d25: {e}\")\n'''\n\u8def\u5f84\u53c2\u6570\uff1a{task_id}\n\u4eceURL\u4e2d\u63d0\u53d6\u4efb\u52a1ID\n\u4f8b\u5b50\uff1a\/tasks\/abc123 \u2192 task_id = \"abc123\"\n\u9519\u8bef\u5904\u7406\u4e24\u79cd\u65b9\u5f0f\uff1a\n1.HTTPException\uff1a\u4e3b\u52a8\u629b\u51fa\u7684\u5df2\u77e5\u9519\u8bef\uff08\u5982404\uff09\n2.Exception\uff1a\u672a\u77e5\u7684\u610f\u5916\u9519\u8bef\n'''\n\n@app.get(\"\/tasks\/{task_id}\/memory\")\nasync def get_task_memory(task_id: str, include_key_facts: bool = True):\n    \"\"\"\u83b7\u53d6\u4efb\u52a1\u8bb0\u5fc6\u6458\u8981\uff08\u770b\u770b\u4efb\u52a1\u7ecf\u5386\u4e86\u4ec0\u4e48\uff09\"\"\"\n    # \u67e5\u8be2\u53c2\u6570\uff1ainclude_key_facts\uff0c\u9ed8\u8ba4\u4e3atrue\n    # \u4f8b\u5b50\uff1a\/tasks\/abc123\/memory?include_key_facts=false\n '''\n \u67e5\u8be2\u53c2\u6570 vs \u8def\u5f84\u53c2\u6570\uff1a\n# \u8def\u5f84\u53c2\u6570\uff08\u5fc5\u987b\u7684\uff09\n@app.get(\"\/tasks\/{task_id}\/memory\")\n# \u67e5\u8be2\u53c2\u6570\uff08\u53ef\u9009\u7684\uff09\nasync def get_task_memory(task_id: str, include_key_facts: bool = True):\n\u4f7f\u7528\u793a\u4f8b\uff1aGET http:\/\/localhost:8000\/tasks\/abc123\/memory?include_key_facts=true\n '''\n    if not Modules.task_scheduler:\n        raise HTTPException(503, \"\u4efb\u52a1\u8c03\u5ea6\u5668\u672a\u5c31\u7eea\")\n    \n    try:\n        memory_summary = await Modules.task_scheduler.get_task_memory_summary(task_id, include_key_facts)\n        return {\n            \"success\": True,\n            \"task_id\": task_id,\n            \"memory_summary\": memory_summary\n        }\n    except Exception as e:\n        logger.error(f\"\u83b7\u53d6\u4efb\u52a1\u8bb0\u5fc6\u5931\u8d25: {e}\")\n        raise HTTPException(500, f\"\u83b7\u53d6\u5931\u8d25: {e}\")\n\n@app.get(\"\/memory\/global\")\nasync def get_global_memory():\n    \"\"\"\u83b7\u53d6\u5168\u5c40\u8bb0\u5fc6\u6458\u8981\uff08\u770b\u770b\u6574\u4e2a\u7cfb\u7edf\u7684\u8bb0\u5fc6\uff09\"\"\"\n    if not Modules.task_scheduler:\n        raise HTTPException(503, \"\u4efb\u52a1\u8c03\u5ea6\u5668\u672a\u5c31\u7eea\")\n    \n    try:\n        # \u83b7\u53d6\u5168\u5c40\u6458\u8981\n        global_summary = await Modules.task_scheduler.get_global_memory_summary()\n        # \u83b7\u53d6\u5931\u8d25\u5c1d\u8bd5\u7684\u6458\u8981\n        failed_attempts = await Modules.task_scheduler.get_failed_attempts_summary()\n'''\u4e3a\u4ec0\u4e48\u9700\u8981\u5168\u5c40\u8bb0\u5fc6\uff1f\n\u770b\u770b\u6574\u4e2a\u7cfb\u7edf\u6267\u884c\u4e86\u591a\u5c11\u4efb\u52a1\n\u54ea\u4e9b\u4efb\u52a1\u7ecf\u5e38\u5931\u8d25\n\u603b\u7ed3\u7ecf\u9a8c\uff0c\u6539\u8fdb\u672a\u6765\u6267\u884c\n'''\n\n        return {\n            \"success\": True,\n            \"global_summary\": global_summary,\n            \"failed_attempts\": failed_attempts\n        }\n    except Exception as e:\n        logger.error(f\"\u83b7\u53d6\u5168\u5c40\u8bb0\u5fc6\u5931\u8d25: {e}\")\n        raise HTTPException(500, f\"\u83b7\u53d6\u5931\u8d25: {e}\")\n\n@app.post(\"\/tasks\/{task_id}\/steps\")\nasync def add_task_step(task_id: str, payload: Dict&#91;str, Any]):\n    \"\"\"\u6dfb\u52a0\u4efb\u52a1\u6b65\u9aa4\uff08\u624b\u52a8\u6dfb\u52a0\u6b65\u9aa4\u8bb0\u5f55\uff09\"\"\"\n    if not Modules.task_scheduler:\n        raise HTTPException(503, \"\u4efb\u52a1\u8c03\u5ea6\u5668\u672a\u5c31\u7eea\")\n    \n    try:  # \u521b\u5efa\u4e00\u4e2aTaskStep\u5bf9\u8c61\n        step = TaskStep(\n            step_id=payload.get(\"step_id\", str(uuid.uuid4())),   # \u6b65\u9aa4ID\uff0c\u6ca1\u6709\u5c31\u751f\u6210\n            task_id=task_id,                                     # \u5c5e\u4e8e\u54ea\u4e2a\u4efb\u52a1\n            purpose=payload.get(\"purpose\", \"\u6267\u884c\u6b65\u9aa4\"),            # \u6b65\u9aa4\u76ee\u7684\n            content=payload.get(\"content\", \"\"),                  # \u6b65\u9aa4\u5185\u5bb9\n            output=payload.get(\"output\", \"\"),                    # \u6b65\u9aa4\u8f93\u51fa\n            analysis=payload.get(\"analysis\"),                    # \u5206\u6790\u7ed3\u679c\n            success=payload.get(\"success\", True),                # \u662f\u5426\u6210\u529f\n            error=payload.get(\"error\")                           # \u9519\u8bef\u4fe1\u606f\n        )\n\n        # \u6dfb\u52a0\u5230\u8c03\u5ea6\u5668\n        await Modules.task_scheduler.add_task_step(task_id, step)\n        \n        return {\n            \"success\": True,\n            \"message\": \"\u6b65\u9aa4\u6dfb\u52a0\u6210\u529f\",\n            \"step_id\": step.step_id\n        }\n    except Exception as e:\n        logger.error(f\"\u6dfb\u52a0\u4efb\u52a1\u6b65\u9aa4\u5931\u8d25: {e}\")\n        raise HTTPException(500, f\"\u6dfb\u52a0\u5931\u8d25: {e}\")\n\n#DELETE\u65b9\u6cd5\uff1a\u7528\u4e8e\u5220\u9664\u8d44\u6e90,\u8fd9\u91cc\u662f\u5220\u9664\u4efb\u52a1\u7684\u8bb0\u5fc6\n@app.delete(\"\/tasks\/{task_id}\/memory\")\nasync def clear_task_memory(task_id: str):\n    \"\"\"\u6e05\u9664\u4efb\u52a1\u8bb0\u5fc6\uff08\u5220\u9664\u5355\u4e2a\u4efb\u52a1\u7684\u8bb0\u5fc6\uff09\"\"\"\n    if not Modules.task_scheduler:\n        raise HTTPException(503, \"\u4efb\u52a1\u8c03\u5ea6\u5668\u672a\u5c31\u7eea\")\n    \n    try:# \u8c03\u7528\u8c03\u5ea6\u5668\u6e05\u9664\u8bb0\u5fc6\n        success = await Modules.task_scheduler.clear_task_memory(task_id)\n        if not success:  # \u8c03\u7528\u8c03\u5ea6\u5668\u6e05\u9664\u8bb0\u5fc6\n            raise HTTPException(404, f\"\u4efb\u52a1 {task_id} \u4e0d\u5b58\u5728\")\n        \n        return {\n            \"success\": True,\n            \"message\": f\"\u4efb\u52a1 {task_id} \u7684\u8bb0\u5fc6\u5df2\u6e05\u9664\"\n        }\n    except HTTPException:\n        raise\n    except Exception as e:\n        logger.error(f\"\u6e05\u9664\u4efb\u52a1\u8bb0\u5fc6\u5931\u8d25: {e}\")\n        raise HTTPException(500, f\"\u6e05\u9664\u5931\u8d25: {e}\")\n\n@app.delete(\"\/memory\/global\")\nasync def clear_global_memory():\n    \"\"\"\u6e05\u9664\u5168\u5c40\u8bb0\u5fc6\uff08\u6e05\u7a7a\u6240\u6709\u8bb0\u5fc6\uff09\"\"\"\n    if not Modules.task_scheduler:\n        raise HTTPException(503, \"\u4efb\u52a1\u8c03\u5ea6\u5668\u672a\u5c31\u7eea\")\n    \n    try:\n        await Modules.task_scheduler.clear_all_memory()\n        return {\n            \"success\": True,\n            \"message\": \"\u5168\u5c40\u8bb0\u5fc6\u5df2\u6e05\u9664\"\n        }\n    except Exception as e:\n        logger.error(f\"\u6e05\u9664\u5168\u5c40\u8bb0\u5fc6\u5931\u8d25: {e}\")\n        raise HTTPException(500, f\"\u6e05\u9664\u5931\u8d25: {e}\")\n#\u5371\u9669\u64cd\u4f5c\uff1a\u4f1a\u5220\u9664\u6240\u6709\u4efb\u52a1\u7684\u8bb0\u5fc6\uff0c\u5c31\u50cf\u683c\u5f0f\u5316\u786c\u76d8\u4e00\u6837\u3002\n# ============ \u4f1a\u8bdd\u7ea7\u522b\u7684\u8bb0\u5fc6\u7ba1\u7406API ============\n\n@app.get(\"\/sessions\")\nasync def get_all_sessions():\n    \"\"\"\u83b7\u53d6\u6240\u6709\u4f1a\u8bdd\u7684\u6458\u8981\u4fe1\u606f\uff08\u770b\u770b\u6709\u54ea\u4e9b\u5bf9\u8bdd\uff09\"\"\"\n    if not Modules.task_scheduler:\n        raise HTTPException(503, \"\u4efb\u52a1\u8c03\u5ea6\u5668\u672a\u5c31\u7eea\")\n    \n    try: # \u83b7\u53d6\u6240\u6709\u4f1a\u8bdd\n        sessions = await Modules.task_scheduler.get_all_sessions()\n        return {\n            \"success\": True,\n            \"sessions\": sessions,            # \u4f1a\u8bdd\u5217\u8868\n            \"total_sessions\": len(sessions)  # \u4f1a\u8bdd\u603b\u6570\n        }\n    except Exception as e:\n        logger.error(f\"\u83b7\u53d6\u4f1a\u8bdd\u5217\u8868\u5931\u8d25: {e}\")\n        raise HTTPException(500, f\"\u83b7\u53d6\u5931\u8d25: {e}\")\n\n@app.get(\"\/sessions\/{session_id}\/memory\")\nasync def get_session_memory_summary(session_id: str):\n    \"\"\"\u83b7\u53d6\u4f1a\u8bdd\u8bb0\u5fc6\u6458\u8981\uff08\u67e5\u770b\u4e00\u6b21\u5bf9\u8bdd\u7684\u6574\u4f53\u60c5\u51b5\uff09\"\"\"\n    if not Modules.task_scheduler:\n        raise HTTPException(503, \"\u4efb\u52a1\u8c03\u5ea6\u5668\u672a\u5c31\u7eea\")\n    \n    try:    #\uff08\u67e5\u770b\u4e00\u6b21\u5bf9\u8bdd\u7684\u6574\u4f53\u60c5\u51b5\uff09\n        summary = await Modules.task_scheduler.get_session_memory_summary(session_id)\n        # \u5982\u679c\u6458\u8981\u4e2d\u5305\u542berror\uff0c\u8bf4\u660e\u4f1a\u8bdd\u4e0d\u5b58\u5728\n        if \"error\" in summary:\n            raise HTTPException(404, summary&#91;\"error\"])\n        \n        return {\n            \"success\": True,\n            \"session_id\": session_id,\n            \"memory_summary\": summary\n        }\n    except HTTPException:\n        raise\n    except Exception as e:\n        logger.error(f\"\u83b7\u53d6\u4f1a\u8bdd\u8bb0\u5fc6\u6458\u8981\u5931\u8d25: {e}\")\n        raise HTTPException(500, f\"\u83b7\u53d6\u5931\u8d25: {e}\")\n\n@app.get(\"\/sessions\/{session_id}\/compressed_memories\")\nasync def get_session_compressed_memories(session_id: str):\n    \"\"\"\u83b7\u53d6\u4f1a\u8bdd\u7684\u538b\u7f29\u8bb0\u5fc6\uff08\u7cbe\u7b80\u7248\u8bb0\u5fc6\uff09\"\"\"\n    if not Modules.task_scheduler:\n        raise HTTPException(503, \"\u4efb\u52a1\u8c03\u5ea6\u5668\u672a\u5c31\u7eea\")\n    \n    try:  # \u83b7\u53d6\u538b\u7f29\u540e\u7684\u8bb0\u5fc6\n        memories = await Modules.task_scheduler.get_session_compressed_memories(session_id)\n        return {\n            \"success\": True,\n            \"session_id\": session_id,\n            \"compressed_memories\": memories,    # \u538b\u7f29\u8bb0\u5fc6\u5217\u8868\n            \"count\": len(memories)              # \u6709\u591a\u5c11\u6761\u538b\u7f29\u8bb0\u5fc6\n        }\n    except Exception as e:\n        logger.error(f\"\u83b7\u53d6\u4f1a\u8bdd\u538b\u7f29\u8bb0\u5fc6\u5931\u8d25: {e}\")\n        raise HTTPException(500, f\"\u83b7\u53d6\u5931\u8d25: {e}\")\n'''\u4ec0\u4e48\u662f\u538b\u7f29\u8bb0\u5fc6\uff1f\n\u628a\u5f88\u591a\u7ec6\u8282\u538b\u7f29\u6210\u5173\u952e\u4fe1\u606f,\u4f8b\u5b50\uff1a\u628a\"\u6253\u5f00\u8bb0\u4e8b\u672c\u2192\u8f93\u5165\u6587\u5b57\u2192\u4fdd\u5b58\u6587\u4ef6\"\u538b\u7f29\u6210\"\u521b\u5efa\u4e86\u4e00\u4e2a\u6587\u672c\u6587\u4ef6\"\n'''\n\n@app.get(\"\/sessions\/{session_id}\/key_facts\")\nasync def get_session_key_facts(session_id: str):\n    \"\"\"\u83b7\u53d6\u4f1a\u8bdd\u7684\u5173\u952e\u4e8b\u5b9e\uff08\u6700\u91cd\u8981\u7684\u4fe1\u606f\uff09\"\"\"\n    if not Modules.task_scheduler:\n        raise HTTPException(503, \"\u4efb\u52a1\u8c03\u5ea6\u5668\u672a\u5c31\u7eea\")\n    \n    try:   # \u83b7\u53d6\u5173\u952e\u4e8b\u5b9e\n        key_facts = await Modules.task_scheduler.get_session_key_facts(session_id)\n        return {\n            \"success\": True,\n            \"session_id\": session_id,\n            \"key_facts\": key_facts,    # \u5173\u952e\u4e8b\u5b9e\u5217\u8868\n            \"count\": len(key_facts)    # \u6709\u591a\u5c11\u4e2a\u5173\u952e\u4e8b\u5b9e\n        }\n    except Exception as e:\n        logger.error(f\"\u83b7\u53d6\u4f1a\u8bdd\u5173\u952e\u4e8b\u5b9e\u5931\u8d25: {e}\")\n        raise HTTPException(500, f\"\u83b7\u53d6\u5931\u8d25: {e}\")\n'''\n\u5173\u952e\u4e8b\u5b9e\u793a\u4f8b\uff1a\n{\n  \"key_facts\": &#91;\n    \"\u7528\u6237\u9700\u8981\u521b\u5efa\u4e00\u4e2a\u4f1a\u8bae\u8bb0\u5f55\u6587\u6863\",\n    \"\u7528\u6237\u504f\u597d\u4f7f\u7528\u8bb0\u4e8b\u672c\u800c\u4e0d\u662fWord\",\n    \"\u7528\u6237\u7ecf\u5e38\u5728\u4e0b\u53483\u70b9\u5f00\u4f1a\"\n  ]\n}\n'''\n\n@app.get(\"\/sessions\/{session_id}\/failed_attempts\")\nasync def get_session_failed_attempts(session_id: str):\n    \"\"\"\u83b7\u53d6\u4f1a\u8bdd\u7684\u5931\u8d25\u5c1d\u8bd5\uff08\u770b\u770b\u54ea\u91cc\u51fa\u9519\u4e86\uff09\"\"\"\n    if not Modules.task_scheduler:\n        raise HTTPException(503, \"\u4efb\u52a1\u8c03\u5ea6\u5668\u672a\u5c31\u7eea\")\n    \n    try:    # \u83b7\u53d6\u5931\u8d25\u5c1d\u8bd5\u8bb0\u5f55\n        failed_attempts = await Modules.task_scheduler.get_session_failed_attempts(session_id)\n        return {\n            \"success\": True,\n            \"session_id\": session_id,\n            \"failed_attempts\": failed_attempts,   # \u5931\u8d25\u8bb0\u5f55\n            \"count\": len(failed_attempts)        # \u5931\u8d25\u6b21\u6570\n        }\n    except Exception as e:\n        logger.error(f\"\u83b7\u53d6\u4f1a\u8bdd\u5931\u8d25\u5c1d\u8bd5\u5931\u8d25: {e}\")\n        raise HTTPException(500, f\"\u83b7\u53d6\u5931\u8d25: {e}\")\n#\u5b66\u4e60\u4ef7\u503c\uff1a\u4ece\u5931\u8d25\u4e2d\u5b66\u4e60\uff0c\u907f\u514d\u91cd\u590d\u9519\u8bef\n\n@app.get(\"\/sessions\/{session_id}\/tasks\")\nasync def get_session_tasks(session_id: str):\n    \"\"\"\u83b7\u53d6\u4f1a\u8bdd\u7684\u6240\u6709\u4efb\u52a1\uff08\u770b\u770b\u8fd9\u6b21\u5bf9\u8bdd\u505a\u4e86\u54ea\u4e9b\u4e8b\uff09\"\"\"\n    if not Modules.task_scheduler:\n        raise HTTPException(503, \"\u4efb\u52a1\u8c03\u5ea6\u5668\u672a\u5c31\u7eea\")\n    \n    try:   # \u83b7\u53d6\u4f1a\u8bdd\u7684\u6240\u6709\u4efb\u52a1\n        tasks = await Modules.task_scheduler.get_session_tasks(session_id)\n        return {\n            \"success\": True,\n            \"session_id\": session_id,\n            \"tasks\": tasks,                # \u4efb\u52a1\u5217\u8868\n            \"count\": len(tasks)            # \u4efb\u52a1\u6570\u91cf\n        }\n    except Exception as e:\n        logger.error(f\"\u83b7\u53d6\u4f1a\u8bdd\u4efb\u52a1\u5931\u8d25: {e}\")\n        raise HTTPException(500, f\"\u83b7\u53d6\u5931\u8d25: {e}\")\n\n@app.delete(\"\/sessions\/{session_id}\/memory\")\nasync def clear_session_memory(session_id: str):\n    \"\"\"\u6e05\u9664\u6307\u5b9a\u4f1a\u8bdd\u7684\u8bb0\u5fc6\uff08\u5220\u9664\u4e00\u6b21\u5bf9\u8bdd\u7684\u6240\u6709\u8bb0\u5fc6\uff09\"\"\"\n    if not Modules.task_scheduler:\n        raise HTTPException(503, \"\u4efb\u52a1\u8c03\u5ea6\u5668\u672a\u5c31\u7eea\")\n    \n    try:     # \u6e05\u9664\u4f1a\u8bdd\u8bb0\u5fc6\n        success = await Modules.task_scheduler.clear_session_memory(session_id)\n        if not success:    # \u5982\u679c\u8fd4\u56defalse\uff0c\u8bf4\u660e\u4f1a\u8bdd\u4e0d\u5b58\u5728\n            raise HTTPException(404, f\"\u4f1a\u8bdd {session_id} \u4e0d\u5b58\u5728\")\n        \n        return {\n            \"success\": True,\n            \"message\": f\"\u4f1a\u8bdd {session_id} \u7684\u8bb0\u5fc6\u5df2\u6e05\u9664\"\n        }\n    except HTTPException:\n        raise\n    except Exception as e:\n        logger.error(f\"\u6e05\u9664\u4f1a\u8bdd\u8bb0\u5fc6\u5931\u8d25: {e}\")\n        raise HTTPException(500, f\"\u6e05\u9664\u5931\u8d25: {e}\")\n\n# ============ \u6587\u4ef6\u7f16\u8f91\u5de5\u5177\u5305API ============\n\n@app.get(\"\/tools\")\nasync def list_tools():\n    \"\"\"\u5217\u51fa\u6240\u6709\u53ef\u7528\u7684\u5de5\u5177 \uff08\u770b\u770b\u6709\u4ec0\u4e48\u5de5\u5177\uff09\"\"\"\n    try:  # \u4ece\u5de5\u5177\u7ba1\u7406\u5668\u4e2d\u83b7\u53d6\u6240\u6709\u5de5\u5177\n        tools = toolkit_manager.get_all_tools()\n        return {\n            \"success\": True,\n            \"tools\": tools,        # \u5de5\u5177\u5217\u8868\n            \"count\": len(tools)    # \u5de5\u5177\u603b\u6570\n        }\n    except Exception as e:\n        logger.error(f\"\u83b7\u53d6\u5de5\u5177\u5217\u8868\u5931\u8d25: {e}\")\n        raise HTTPException(500, f\"\u83b7\u53d6\u5931\u8d25: {e}\")\n'''\n\u4ec0\u4e48\u662f\u5de5\u5177\uff1f\n\u5de5\u5177 = \u4e00\u4e2a\u5177\u4f53\u7684\u529f\u80fd,\u6bd4\u5982\uff1a\"\u6253\u5f00\u6d4f\u89c8\u5668\"\u3001\"\u590d\u5236\u6587\u4ef6\"\u3001\"\u53d1\u9001\u90ae\u4ef6\"\n\u793a\u4f8b\u8fd4\u56de\uff1a\n{\n  \"success\": true,\n  \"tools\": &#91;\n    {\"name\": \"open_browser\", \"description\": \"\u6253\u5f00\u6d4f\u89c8\u5668\"},\n    {\"name\": \"copy_file\", \"description\": \"\u590d\u5236\u6587\u4ef6\"},\n    {\"name\": \"send_email\", \"description\": \"\u53d1\u9001\u90ae\u4ef6\"}\n  ],\n  \"count\": 3\n}\n'''\n\n@app.get(\"\/toolkits\")\nasync def list_toolkits():\n    \"\"\"\u5217\u51fa\u6240\u6709\u53ef\u7528\u7684\u5de5\u5177\u5305\uff08\u770b\u770b\u6709\u54ea\u4e9b\u5de5\u5177\u7bb1\uff09\"\"\"\n    try:    # \u83b7\u53d6\u6240\u6709\u5de5\u5177\u5305\n        toolkits = toolkit_manager.list_toolkits()\n        return {\n            \"success\": True,\n            \"toolkits\": toolkits,\n            \"count\": len(toolkits)\n        }\n    except Exception as e:\n        logger.error(f\"\u83b7\u53d6\u5de5\u5177\u5305\u5217\u8868\u5931\u8d25: {e}\")\n        raise HTTPException(500, f\"\u83b7\u53d6\u5931\u8d25: {e}\")\n'''\n\u5de5\u5177\u5305 vs \u5de5\u5177\uff1a\n\u5de5\u5177\u5305\uff1a\u4e00\u7ec4\u76f8\u5173\u5de5\u5177\u7684\u96c6\u5408\uff08\u50cf\u5de5\u5177\u7bb1\uff09,\u5de5\u5177\uff1a\u5355\u4e2a\u5177\u4f53\u7684\u529f\u80fd\uff08\u50cf\u6273\u624b\u3001\u9524\u5b50\uff09\n\u793a\u4f8b\uff1a\n\u5de5\u5177\u5305\uff1afile_edit\uff08\u6587\u4ef6\u7f16\u8f91\u5de5\u5177\u5305\uff09\n\u251c\u2500\u2500 \u5de5\u51771\uff1aread_file\uff08\u8bfb\u6587\u4ef6\uff09\n\u251c\u2500\u2500 \u5de5\u51772\uff1awrite_file\uff08\u5199\u6587\u4ef6\uff09\n\u2514\u2500\u2500 \u5de5\u51773\uff1aedit_file\uff08\u7f16\u8f91\u6587\u4ef6\uff09\n'''\n\n@app.get(\"\/toolkits\/{toolkit_name}\")\nasync def get_toolkit_info(toolkit_name: str):\n    \"\"\"\u83b7\u53d6\u5de5\u5177\u5305\u8be6\u7ec6\u4fe1\u606f\uff08\u6253\u5f00\u5de5\u5177\u7bb1\u770b\u770b\u91cc\u9762\u6709\u4ec0\u4e48\uff09\"\"\"\n    try:      # \u83b7\u53d6\u6307\u5b9a\u5de5\u5177\u5305\u7684\u4fe1\u606f\n        info = toolkit_manager.get_toolkit_info(toolkit_name)\n        if not info:    # \u5982\u679c\u6ca1\u627e\u5230\uff0c\u8fd4\u56de404\n            raise HTTPException(404, f\"\u5de5\u5177\u5305\u4e0d\u5b58\u5728: {toolkit_name}\")\n        \n        return {\n            \"success\": True,\n            \"toolkit\": info\n        }\n    except HTTPException:      # \u5df2\u77e5\u9519\u8bef\uff08\u5982404\uff09\n        raise\n    except Exception as e:     # \u672a\u77e5\u9519\u8bef\n        logger.error(f\"\u83b7\u53d6\u5de5\u5177\u5305\u4fe1\u606f\u5931\u8d25: {e}\")\n        raise HTTPException(500, f\"\u83b7\u53d6\u5931\u8d25: {e}\")\n'''\n\u8def\u5f84\u53c2\u6570\uff1a{toolkit_name}\n\u4eceURL\u4e2d\u63d0\u53d6\u5de5\u5177\u5305\u540d\u79f0,\u4f8b\u5b50\uff1a\/toolkits\/file_edit \u2192 toolkit_name = \"file_edit\"\n'''\n\n@app.post(\"\/tools\/{toolkit_name}\/{tool_name}\")\nasync def call_tool(toolkit_name: str, tool_name: str, arguments: Dict&#91;str, Any]):\n    \"\"\"\u8c03\u7528\u5de5\u5177\uff08\u4f7f\u7528\u5177\u4f53\u5de5\u5177\u5e72\u6d3b\uff09\"\"\"\n    try:    # \u8c03\u7528\u5de5\u5177\uff1a\u6307\u5b9a\u5de5\u5177\u5305\u3001\u5de5\u5177\u540d\u548c\u53c2\u6570\n        result = await toolkit_manager.call_tool(toolkit_name, tool_name, arguments)\n        return {\n            \"success\": True,\n            \"toolkit\": toolkit_name,\n            \"tool\": tool_name,\n            \"result\": result\n        }\n    except Exception as e:\n        logger.error(f\"\u8c03\u7528\u5de5\u5177\u5931\u8d25 {toolkit_name}.{tool_name}: {e}\")\n        raise HTTPException(500, f\"\u8c03\u7528\u5931\u8d25: {e}\")\n'''\nURL\u7ed3\u6784\u5206\u6790\uff1a\nPOST \/tools\/{\u5de5\u5177\u7bb1}\/{\u5de5\u5177\u540d}\n\u4f8b\u5b50\uff1aPOST \/tools\/file_edit\/read_file\n\u53c2\u6570\u4f20\u9012\uff1a\n{\n  \"path\": \"\/home\/user\/test.txt\"\n}\n\u5b8c\u6574\u8c03\u7528\u793a\u4f8b\uff1a\nPOST http:\/\/localhost:8000\/tools\/file_edit\/read_file\nContent-Type: application\/json\n\n{\n  \"path\": \"\/home\/user\/test.txt\"\n}\n'''\n\n# ============ \u6587\u4ef6\u7f16\u8f91\u4e13\u7528API ============\n\n@app.post(\"\/file\/edit\")\nasync def edit_file(request: Dict&#91;str, str]):\n    \"\"\"\u7f16\u8f91\u6587\u4ef6 - \u4f7f\u7528SEARCH\/REPLACE\u683c\u5f0f\"\"\"\n    try:\n        path = request.get(\"path\")     # \u6587\u4ef6\u8def\u5f84\n        diff = request.get(\"diff\")     # \u5dee\u5f02\u5185\u5bb9\uff08\u8981\u4fee\u6539\u7684\u90e8\u5206\uff09\n\n        # \u68c0\u67e5\u5fc5\u8981\u53c2\u6570\n        if not path or not diff:\n            raise HTTPException(400, \"\u7f3a\u5c11\u5fc5\u8981\u53c2\u6570: path \u548c diff\")\n\n        # \u8c03\u7528\u6587\u4ef6\u7f16\u8f91\u5de5\u5177\n        result = await toolkit_manager.call_tool(\"file_edit\", \"edit_file\", {\n            \"path\": path,\n            \"diff\": diff\n        })\n        \n        return {\n            \"success\": True,\n            \"result\": result\n        }\n    except HTTPException:\n        raise\n    except Exception as e:\n        logger.error(f\"\u7f16\u8f91\u6587\u4ef6\u5931\u8d25: {e}\")\n        raise HTTPException(500, f\"\u7f16\u8f91\u5931\u8d25: {e}\")\n'''\n\u4ec0\u4e48\u662fSEARCH\/REPLACE\u683c\u5f0f\uff1f\n\u8fd9\u662f\u4e00\u79cd\u8868\u793a\u6587\u4ef6\u4fee\u6539\u7684\u65b9\u5f0f\uff1a\n{\n  \"path\": \"test.py\",\n  \"diff\": \"&lt;&lt;&lt;&lt;&lt;&lt;&lt; SEARCH\\nprint('Hello')\\n=======\\nprint('Hello World')\\n>>>>>>> REPLACE\"\n}\n\u89e3\u91ca\uff1a\nSEARCH\u90e8\u5206\uff1a\u627e\u5230\u6587\u4ef6\u4e2d\u5339\u914d\u7684\u5185\u5bb9\nREPLACE\u90e8\u5206\uff1a\u66ff\u6362\u6210\u65b0\u5185\u5bb9\n\u5c31\u50cf\u5728Word\u91cc\u7528\u67e5\u627e\u66ff\u6362\u529f\u80fd\n'''\n\n@app.post(\"\/file\/write\")\nasync def write_file(request: Dict&#91;str, str]):\n    \"\"\"\u5199\u5165\u6587\u4ef6\uff08\u521b\u5efa\u6216\u8986\u76d6\u6587\u4ef6\uff09\"\"\"\n    try:\n        path = request.get(\"path\")              # \u6587\u4ef6\u8def\u5f84\n        content = request.get(\"content\")        # \u6587\u4ef6\u5185\u5bb9\n\n        # \u68c0\u67e5\u53c2\u6570\uff0c\u6ce8\u610fcontent\u53ef\u4ee5\u662f\u7a7a\u5b57\u7b26\u4e32\uff0c\u6240\u4ee5\u7528content is None\u5224\u65ad\n        if not path or content is None:\n            raise HTTPException(400, \"\u7f3a\u5c11\u5fc5\u8981\u53c2\u6570: path \u548c content\")\n\n        # \u8c03\u7528\u5199\u6587\u4ef6\u5de5\u5177\n        result = await toolkit_manager.call_tool(\"file_edit\", \"write_file\", {\n            \"path\": path,\n            \"file_text\": content    # \u6ce8\u610f\u53c2\u6570\u540d\u662ffile_text\n        })\n        \n        return {\n            \"success\": True,\n            \"result\": result\n        }\n    except HTTPException:\n        raise\n    except Exception as e:\n        logger.error(f\"\u5199\u5165\u6587\u4ef6\u5931\u8d25: {e}\")\n        raise HTTPException(500, f\"\u5199\u5165\u5931\u8d25: {e}\")\n'''\n\u6ce8\u610f\u7ec6\u8282\uff1a\nif not path or content is None:\n    # \u8fd9\u91cc\u7528content is None\u800c\u4e0d\u662fnot content\n    # \u56e0\u4e3acontent\u53ef\u4ee5\u662f\u7a7a\u5b57\u7b26\u4e32\"\"\uff0c\u8fd9\u4e5f\u662f\u6709\u6548\u7684\n\u4f7f\u7528\u573a\u666f\uff1a1.\u521b\u5efa\u65b0\u6587\u4ef6\n        2.\u8986\u76d6\u5df2\u6709\u6587\u4ef6\n        3.\u6e05\u7a7a\u6587\u4ef6\u5185\u5bb9\uff08\u4f20\u5165\u7a7a\u5b57\u7b26\u4e32\uff09\n'''\n\n@app.get(\"\/file\/read\")\nasync def read_file(path: str):\n    \"\"\"\u8bfb\u53d6\u6587\u4ef6\"\"\"\n    try:         # \u8c03\u7528\u8bfb\u6587\u4ef6\u5de5\u5177\n        result = await toolkit_manager.call_tool(\"file_edit\", \"read_file\", {\n            \"path\": path\n        })\n        \n        return {\n            \"success\": True,\n            \"content\": result            # \u6587\u4ef6\u5185\u5bb9\n        }\n    except Exception as e:\n        logger.error(f\"\u8bfb\u53d6\u6587\u4ef6\u5931\u8d25: {e}\")\n        raise HTTPException(500, f\"\u8bfb\u53d6\u5931\u8d25: {e}\")\n'''\n\u67e5\u8be2\u53c2\u6570:\npath\uff1a\u901a\u8fc7URL\u53c2\u6570\u4f20\u9012\n\u4f8b\u5b50\uff1a\/file\/read?path=\/home\/user\/test.txt\n\u8fd4\u56de\u793a\u4f8b\uff1a\n{\n  \"success\": true,\n  \"content\": \"Hello World!\\nThis is a test file.\"\n}\n'''\n\n@app.get(\"\/file\/list\")\nasync def list_files(directory: str = \".\"):\n    \"\"\"\u5217\u51fa\u76ee\u5f55\u6587\u4ef6\uff08\u67e5\u770b\u6587\u4ef6\u5939\u5185\u5bb9\uff09\"\"\"\n    try:\n        result = await toolkit_manager.call_tool(\"file_edit\", \"list_files\", {\n            \"directory\": directory      # \u76ee\u5f55\u8def\u5f84\uff0c\u9ed8\u8ba4\u4e3a\u5f53\u524d\u76ee\u5f55\".\"\n        })\n'''\n\u9ed8\u8ba4\u503c\uff1a\ndirectory: str = \".\"\n# \u5982\u679c\u4e0d\u4f20directory\u53c2\u6570\uff0c\u9ed8\u8ba4\u662f\u5f53\u524d\u76ee\u5f55\".\"\n\u4f7f\u7528\u793a\u4f8b\uff1a\nGET \/file\/list?directory=\/home\/user\n\u8fd4\u56de\u793a\u4f8b\uff1a\n{\n  \"success\": true,\n  \"result\": {\n    \"files\": &#91;\"test.txt\", \"photo.jpg\"],\n    \"directories\": &#91;\"Documents\", \"Downloads\"],\n    \"total\": 4\n  }\n}\n'''\n\n        return {\n            \"success\": True,\n            \"result\": result\n        }\n    except Exception as e:\n        logger.error(f\"\u5217\u51fa\u6587\u4ef6\u5931\u8d25: {e}\")\n        raise HTTPException(500, f\"\u5217\u51fa\u5931\u8d25: {e}\")\n\n#\u7a0b\u5e8f\u542f\u52a8,\u542f\u52a8FastAPI\u5e94\u7528\nif __name__ == \"__main__\":\n'''\nif __name__ == \"__main__\":\n\u8fd9\u662f\u4e00\u4e2a\u9b54\u6cd5\u5f00\u5173\n\u53ea\u6709\u5f53\u76f4\u63a5\u8fd0\u884c\u8fd9\u4e2a\u6587\u4ef6\u65f6\uff0c\u4e0b\u9762\u7684\u4ee3\u7801\u624d\u4f1a\u6267\u884c\n\u5982\u679c\u88ab\u522b\u4eba\u5bfc\u5165\uff0c\u5c31\u4e0d\u4f1a\u6267\u884c\n'''\n    import uvicorn\n    #Uvicorn\uff1a\u4e00\u4e2a\u5feb\u901f\u7684Web\u670d\u52a1\u5668\n    #\u4e13\u95e8\u7528\u6765\u8fd0\u884cFastAPI\u5e94\u7528\n    from agentserver.config import AGENT_SERVER_PORT\n    #\u4ece\u914d\u7f6e\u6587\u4ef6\u5bfc\u5165\u7aef\u53e3\u53f7\n    #\u8fd9\u6837\u53ef\u4ee5\u5728\u914d\u7f6e\u6587\u4ef6\u4e2d\u4fee\u6539\u7aef\u53e3\uff0c\u4e0d\u7528\u6539\u4ee3\u7801\n    uvicorn.run(app, host=\"0.0.0.0\", port=AGENT_SERVER_PORT)\n    #\u542f\u52a8Web\u670d\u52a1\u5668\n    #app\uff1a\u6211\u4eec\u521b\u5efa\u7684FastAPI\u5e94\u7528\n    #host=\"0.0.0.0\"\uff1a\u76d1\u542c\u6240\u6709\u7f51\u7edc\u63a5\u53e3\uff08\u53ef\u4ee5\u4ece\u4efb\u4f55IP\u8bbf\u95ee\uff09\n    #port\uff1a\u4f7f\u7528\u914d\u7f6e\u6587\u4ef6\u4e2d\u5b9a\u4e49\u7684\u7aef\u53e3\n'''\nhost\u53c2\u6570\u89e3\u91ca\uff1a\n\u503c                 |  \u542b\u4e49        |   \u8c01\u53ef\u4ee5\u8bbf\u95ee\n\"127.0.0.1\"       |  \u53ea\u76d1\u542c\u672c\u673a    |   \u53ea\u6709\u672c\u673a\u80fd\u8bbf\u95ee\n\"0.0.0.0\"         |  \u76d1\u542c\u6240\u6709IP    |  \u5176\u4ed6\u7535\u8111\u4e5f\u80fd\u8bbf\u95ee\n\"192.168.1.100\"   |  \u76d1\u542c\u6307\u5b9aIP    |  \u53ea\u6709\u8fd9\u4e2aIP\u80fd\u8bbf\u95ee\n\u6587\u4ef6\u64cd\u4f5cAPI\u6c47\u603b\uff1a\n\u7aef\u70b9           | \u65b9\u6cd5    | \u7528\u9014\t       |   \u53c2\u6570\n\/file\/edit    | POST   | \u7f16\u8f91\u6587\u4ef6       |  path, diff\n\/file\/write   | POST   | \u5199\u5165\/\u521b\u5efa\u6587\u4ef6   |  path, content\n\/file\/read    | GET    | \u8bfb\u53d6\u6587\u4ef6       |  path\uff08\u67e5\u8be2\u53c2\u6570\uff09\n\/file\/list    | GET    | \u5217\u51fa\u76ee\u5f55\u6587\u4ef6    |  directory\uff08\u67e5\u8be2\u53c2\u6570\uff09\n\u4e0e\u901a\u7528\u5de5\u5177\u8c03\u7528\u7684\u533a\u522b\uff1a\n\u65b9\u5f0f\u4e00\uff1a\u4f7f\u7528\u901a\u7528\u5de5\u5177\u8c03\u7528\nPOST \/tools\/file_edit\/read_file\n{\n  \"path\": \"\/home\/user\/test.txt\"\n}\n\u65b9\u5f0f\u4e8c\uff1a\u4f7f\u7528\u4e13\u7528\u6587\u4ef6API\nGET \/file\/read?path=\/home\/user\/test.txt\n\u533a\u522b\uff1a\n\u4e13\u7528API\uff1a\u66f4\u65b9\u4fbf\uff0c\u53c2\u6570\u76f4\u63a5\u5728URL\u6216\u56fa\u5b9a\u683c\u5f0f\u4e2d\n\u901a\u7528\u5de5\u5177\u8c03\u7528\uff1a\u66f4\u7075\u6d3b\uff0c\u53ef\u4ee5\u8c03\u7528\u4efb\u4f55\u5de5\u5177\u5305\u7684\u4efb\u4f55\u5de5\u5177\n'''\n\n# =========\u5b8c\u6574\u7684API\u603b\u89c8==========\n#\u73b0\u5728\u6211\u4eec\u5df2\u7ecf\u5206\u6790\u5b8c\u6240\u6709API\uff0c\u8ba9\u6211\u4eec\u603b\u7ed3\u4e00\u4e0b\uff1a\n''' \n1.\u7cfb\u7edf\u72b6\u6001\u7c7b\n\/health                                \u5065\u5eb7\u68c0\u67e5\n\/computer_control\/availability         \u68c0\u67e5\u7535\u8111\u63a7\u5236\u80fd\u529b\n2.\u4efb\u52a1\u6267\u884c\u7c7b\n\/schedule                        \u7edf\u4e00\u4efb\u52a1\u8c03\u5ea6\uff08\u4e3b\u8981\u5165\u53e3\uff09\n\/analyze_and_execute             \u610f\u56fe\u5206\u6790\u548c\u6267\u884c\uff08\u517c\u5bb9\u65e7\u7248\uff09\n\/computer_control\/execute        \u76f4\u63a5\u6267\u884c\u7535\u8111\u63a7\u5236\u4efb\u52a1\n3.\u8bb0\u5fc6\u7ba1\u7406\u7c7b\n\/tasks                             \u83b7\u53d6\u4efb\u52a1\u5217\u8868\n\/tasks\/{task_id}                   \u83b7\u53d6\u4efb\u52a1\u72b6\u6001\n\/tasks\/{task_id}\/memory            \u83b7\u53d6\u4efb\u52a1\u8bb0\u5fc6\n\/tasks\/{task_id}\/steps             \u6dfb\u52a0\u4efb\u52a1\u6b65\u9aa4\n\/memory\/global                     \u83b7\u53d6\u5168\u5c40\u8bb0\u5fc6\n\/sessions                          \u83b7\u53d6\u6240\u6709\u4f1a\u8bdd\n\/sessions\/{session_id}\/memory      \u83b7\u53d6\u4f1a\u8bdd\u8bb0\u5fc6\n4. \u5de5\u5177\u7ba1\u7406\u7c7b\n\/tools                      \u5217\u51fa\u6240\u6709\u5de5\u5177\n\/toolkits                   \u5217\u51fa\u6240\u6709\u5de5\u5177\u5305\n\/toolkits\/{toolkit_name}    \u83b7\u53d6\u5de5\u5177\u5305\u8be6\u60c5\n\/tools\/{toolkit}\/{tool}     \u8c03\u7528\u5de5\u5177\n5. \u6587\u4ef6\u64cd\u4f5c\u7c7b\n\/file\/edit             \u7f16\u8f91\u6587\u4ef6\n\/file\/write            \u5199\u5165\u6587\u4ef6\n\/file\/read             \u8bfb\u53d6\u6587\u4ef6\n\/file\/list             \u5217\u51fa\u76ee\u5f55\u6587\u4ef6\n'''\n#\u4e00\u3001\u6587\u4ef6\u67b6\u6784\n'''\nnaga_agent.py\uff08\u4e3b\u6587\u4ef6\uff09\n\u251c\u2500\u2500 \u5bfc\u5165\u90e8\u5206\uff0815\u4e2a\u5bfc\u5165\uff09\n\u251c\u2500\u2500 \u914d\u7f6e\u90e8\u5206\uff08\u65e5\u5fd7\u914d\u7f6e\uff09\n\u251c\u2500\u2500 \u6838\u5fc3\u7c7b\uff08Modules\uff09\n\u251c\u2500\u2500 \u751f\u547d\u5468\u671f\u7ba1\u7406\u5668\uff08lifespan\uff09\n\u251c\u2500\u2500 FastAPI\u5e94\u7528\u5b9e\u4f8b\uff08app\uff09\n\u251c\u2500\u2500 7\u4e2a\u6838\u5fc3\u529f\u80fd\u51fd\u6570\n\u251c\u2500\u2500 25\u4e2aAPI\u7aef\u70b9\u51fd\u6570\n\u2514\u2500\u2500 \u542f\u52a8\u4ee3\u7801\n'''\n#\u4e8c\u3001\u6838\u5fc3\u7c7b\u7ed3\u6784\n#1. Modules\u7c7b\uff08\u5168\u5c40\u5de5\u5177\u7bb1\uff09\n'''\nclass Modules:\n    analyzer = None          # \u610f\u56fe\u5206\u6790\u5668\n    computer_control = None  # \u7535\u8111\u63a7\u5236\u5668\n    task_scheduler = None    # \u4efb\u52a1\u8c03\u5ea6\u5668\n'''\n#\u4e09\u3001\u6838\u5fc3\u51fd\u6570\uff087\u4e2a\uff09\n#1. \u57fa\u7840\u5de5\u5177\u51fd\u6570\n#def _now_iso() -> str:\n    # \u83b7\u53d6\u5f53\u524d\u65f6\u95f4\uff08ISO\u683c\u5f0f\uff09\n#2. \u4efb\u52a1\u6267\u884c\u51fd\u6570\uff083\u4e2a\uff09\n'''\nasync def _process_computer_control_task(...):\n    # \u6267\u884c\u5355\u4e2a\u7535\u8111\u63a7\u5236\u4efb\u52a1\n\nasync def _execute_agent_tasks_async(...):\n    # \u5f02\u6b65\u6267\u884c\u591a\u4e2aAgent\u4efb\u52a1\n    \nasync def _send_callback_notification(...):\n    # \u53d1\u9001\u56de\u8c03\u901a\u77e5\n'''\n#3. \u751f\u547d\u5468\u671f\u51fd\u6570\uff081\u4e2a\uff09\n'''\n@asynccontextmanager\nasync def lifespan(app: FastAPI):\n    # \u7a0b\u5e8f\u542f\u52a8\u548c\u5173\u95ed\u7ba1\u7406\n'''\n#\u56db\u3001API\u7aef\u70b9\uff0825\u4e2a\uff0c\u6309\u529f\u80fd\u5206\u7ec4\uff09\n#\u7b2c1\u7ec4\uff1a\u7cfb\u7edf\u72b6\u6001\uff082\u4e2a\uff09\n'''\nGET  \/health                      # \u5065\u5eb7\u68c0\u67e5\nGET  \/computer_control\/availability  # \u68c0\u67e5\u7535\u8111\u63a7\u5236\u80fd\u529b\n'''\n#\u7b2c2\u7ec4\uff1a\u4efb\u52a1\u6267\u884c\uff083\u4e2a\uff09\n'''\nPOST \/schedule                    # \u7edf\u4e00\u4efb\u52a1\u8c03\u5ea6\uff08\u4e3b\u5165\u53e3\uff09\nPOST \/analyze_and_execute         # \u610f\u56fe\u5206\u6790\u548c\u6267\u884c\uff08\u517c\u5bb9\u65e7\u7248\uff09\nPOST \/computer_control\/execute    # \u76f4\u63a5\u6267\u884c\u7535\u8111\u4efb\u52a1\n'''\n#\u7b2c3\u7ec4\uff1a\u4efb\u52a1\u8bb0\u5fc6\u7ba1\u7406\uff086\u4e2a\uff09\n'''\nGET    \/tasks                     # \u83b7\u53d6\u6240\u6709\u4efb\u52a1\nGET    \/tasks\/{task_id}           # \u83b7\u53d6\u7279\u5b9a\u4efb\u52a1\u72b6\u6001\nGET    \/tasks\/{task_id}\/memory    # \u83b7\u53d6\u4efb\u52a1\u8bb0\u5fc6\nPOST   \/tasks\/{task_id}\/steps     # \u6dfb\u52a0\u4efb\u52a1\u6b65\u9aa4\nDELETE \/tasks\/{task_id}\/memory    # \u6e05\u9664\u4efb\u52a1\u8bb0\u5fc6\nDELETE \/memory\/global             # \u6e05\u9664\u5168\u5c40\u8bb0\u5fc6\n'''\n#\u7b2c4\u7ec4\uff1a\u4f1a\u8bdd\u8bb0\u5fc6\u7ba1\u7406\uff088\u4e2a\uff09\n'''\nGET    \/sessions                  # \u83b7\u53d6\u6240\u6709\u4f1a\u8bdd\nGET    \/sessions\/{session_id}\/memory      # \u83b7\u53d6\u4f1a\u8bdd\u8bb0\u5fc6\nGET    \/sessions\/{session_id}\/compressed_memories  # \u538b\u7f29\u8bb0\u5fc6\nGET    \/sessions\/{session_id}\/key_facts   # \u5173\u952e\u4e8b\u5b9e\nGET    \/sessions\/{session_id}\/failed_attempts  # \u5931\u8d25\u5c1d\u8bd5\nGET    \/sessions\/{session_id}\/tasks       # \u4f1a\u8bdd\u7684\u6240\u6709\u4efb\u52a1\nDELETE \/sessions\/{session_id}\/memory      # \u6e05\u9664\u4f1a\u8bdd\u8bb0\u5fc6\n'''\n#\u7b2c5\u7ec4\uff1a\u5de5\u5177\u7ba1\u7406\uff084\u4e2a\uff09\n'''\nGET  \/tools                      # \u5217\u51fa\u6240\u6709\u5de5\u5177\nGET  \/toolkits                   # \u5217\u51fa\u6240\u6709\u5de5\u5177\u5305\nGET  \/toolkits\/{toolkit_name}    # \u83b7\u53d6\u5de5\u5177\u5305\u8be6\u60c5\nPOST \/tools\/{toolkit}\/{tool}     # \u8c03\u7528\u5de5\u5177\n'''\n#\u7b2c6\u7ec4\uff1a\u6587\u4ef6\u64cd\u4f5c\uff084\u4e2a\uff09\n'''\nPOST \/file\/edit                  # \u7f16\u8f91\u6587\u4ef6\nPOST \/file\/write                 # \u5199\u5165\u6587\u4ef6\nGET  \/file\/read                  # \u8bfb\u53d6\u6587\u4ef6\nGET  \/file\/list                  # \u5217\u51fa\u76ee\u5f55\n'''\n#\u4e94\u3001\u6570\u636e\u7ed3\u6784\u5c42\u7ea7\n#1. \u6700\u9ad8\u5c42\uff1a\u7a0b\u5e8f\n'''\nNagaAgent\u670d\u52a1\n    \u2193\n\u4f1a\u8bdd\uff08Session\uff09\n    \u2193\n\u4efb\u52a1\uff08Task\uff09\n    \u2193\n\u6b65\u9aa4\uff08Step\uff09\n'''\n#2. \u4f1a\u8bdd\uff08Session\uff09\u7ed3\u6784\n'''\n\u4f1a\u8bdd = {\n    \"session_id\": \"\u7528\u6237123\",           # \u4f1a\u8bddID\n    \"tasks\": &#91;\u4efb\u52a11, \u4efb\u52a12, ...],      # \u5305\u542b\u7684\u4efb\u52a1\n    \"memory\": \u8bb0\u5fc6\u6570\u636e,               # \u4f1a\u8bdd\u8bb0\u5fc6\n    \"key_facts\": \u5173\u952e\u4e8b\u5b9e\u5217\u8868         # \u91cd\u8981\u4fe1\u606f\n}\n'''\n#3. \u4efb\u52a1\uff08Task\uff09\u7ed3\u6784\n'''\n\u4efb\u52a1 = {\n    \"task_id\": \"\u4efb\u52a1001\",             # \u4efb\u52a1ID\n    \"purpose\": \"\u6253\u5f00\u8bb0\u4e8b\u672c\",           # \u4efb\u52a1\u76ee\u7684\n    \"status\": \"running\",              # \u4efb\u52a1\u72b6\u6001\n    \"steps\": &#91;\u6b65\u9aa41, \u6b65\u9aa42, ...],     # \u4efb\u52a1\u6b65\u9aa4\n    \"memory\": \u4efb\u52a1\u8bb0\u5fc6                 # \u4efb\u52a1\u8bb0\u5fc6\n}\n'''\n#4. \u6b65\u9aa4\uff08Step\uff09\u7ed3\u6784\n'''\n\u6b65\u9aa4 = {\n    \"step_id\": \"\u6b65\u9aa4001\",             # \u6b65\u9aa4ID\n    \"purpose\": \"\u6253\u5f00\u8bb0\u4e8b\u672c\",           # \u6b65\u9aa4\u76ee\u7684\n    \"content\": \"\u8c03\u7528\u8bb0\u4e8b\u672c\u7a0b\u5e8f\",       # \u6b65\u9aa4\u5185\u5bb9\n    \"output\": \"\u8bb0\u4e8b\u672c\u5df2\u6253\u5f00\",          # \u6b65\u9aa4\u8f93\u51fa\n    \"success\": True,                  # \u662f\u5426\u6210\u529f\n    \"error\": None                     # \u9519\u8bef\u4fe1\u606f\n}\n'''\n#\u516d\u3001\u6267\u884c\u6d41\u7a0b\n#\u5b8c\u6574\u4efb\u52a1\u6267\u884c\u6d41\u7a0b\uff1a\n#\u7528\u6237\u8bf7\u6c42 \u2192 \/schedule\u7aef\u70b9 \u2192 \u521b\u5efa\u4efb\u52a1 \u2192 \u5f02\u6b65\u6267\u884c \u2192 \u5904\u7406\u6bcf\u4e2aAgent\u4efb\u52a1 \u2192 \u8c03\u7528\u7535\u8111\u63a7\u5236\u5668 \u2192 \u8bb0\u5f55\u6b65\u9aa4 \u2192 \u53d1\u9001\u56de\u8c03 \u2192 \u66f4\u65b0\u8bb0\u5fc6\n#1. \u7a0b\u5e8f\u5143\u4fe1\u606f\n'''\n\u7a0b\u5e8f\u5143\u4fe1\u606f\n\u251c\u2500\u2500 \u89e3\u91ca\u5668\u58f0\u660e\uff1a#!\/usr\/bin\/env python3\n\u2514\u2500\u2500 \u7f16\u7801\u58f0\u660e\uff1a# -*- coding: utf-8 -*-\n'''\n#2. \u5bfc\u5165\u6a21\u5757\u7cfb\u7edf\n'''\n\u5bfc\u5165\u6a21\u5757\u7cfb\u7edf\n\u251c\u2500\u2500 Python\u6807\u51c6\u5e93\uff085\u4e2a\uff09\n\u2502   \u251c\u2500\u2500 asyncio     # \u5f02\u6b65\u5904\u7406\n\u2502   \u251c\u2500\u2500 uuid        # \u751f\u6210\u552f\u4e00ID\n\u2502   \u251c\u2500\u2500 logging     # \u65e5\u5fd7\u8bb0\u5f55\n\u2502   \u251c\u2500\u2500 typing      # \u7c7b\u578b\u6ce8\u89e3\n\u2502   \u2514\u2500\u2500 datetime    # \u65f6\u95f4\u5904\u7406\n\u2502\n\u251c\u2500\u2500 Web\u6846\u67b6\uff082\u4e2a\uff09\n\u2502   \u251c\u2500\u2500 fastapi.FastAPI        # Web\u5e94\u7528\u6846\u67b6\n\u2502   \u2514\u2500\u2500 fastapi.HTTPException  # HTTP\u5f02\u5e38\n\u2502\n\u251c\u2500\u2500 \u8f85\u52a9\u5de5\u5177\uff082\u4e2a\uff09\n\u2502   \u251c\u2500\u2500 fastapi.responses.JSONResponse  # JSON\u54cd\u5e94\n\u2502   \u2514\u2500\u2500 contextlib.asynccontextmanager  # \u5f02\u6b65\u4e0a\u4e0b\u6587\u7ba1\u7406\u5668\n\u2502\n\u2514\u2500\u2500 \u81ea\u5b9a\u4e49\u6a21\u5757\uff086\u4e2a\uff09\n    \u251c\u2500\u2500 system.config                    # \u914d\u7f6e\u6587\u4ef6\n    \u251c\u2500\u2500 system.background_analyzer       # \u610f\u56fe\u5206\u6790\u5668\n    \u251c\u2500\u2500 agentserver.agent_computer_control  # \u7535\u8111\u63a7\u5236\u667a\u80fd\u4f53\n    \u251c\u2500\u2500 agentserver.task_scheduler       # \u4efb\u52a1\u8c03\u5ea6\u5668\n    \u251c\u2500\u2500 agentserver.toolkit_manager      # \u5de5\u5177\u7ba1\u7406\u5668\n    \u2514\u2500\u2500 agentserver.config               # \u670d\u52a1\u5668\u914d\u7f6e\n'''\n#3. \u65e5\u5fd7\u914d\u7f6e\u7cfb\u7edf\n'''\n\u65e5\u5fd7\u914d\u7f6e\u7cfb\u7edf\n\u251c\u2500\u2500 \u521b\u5efa\u65e5\u5fd7\u5668\uff1alogging.getLogger(__name__)\n\u251c\u2500\u2500 \u8bbe\u7f6e\u65e5\u5fd7\u7ea7\u522b\uff1alogger.setLevel(logging.INFO)\n\u2514\u2500\u2500 \u914d\u7f6e\u5904\u7406\u5668\uff08\u5982\u679c\u6ca1\u6709\u7684\u8bdd\uff09\n    \u251c\u2500\u2500 \u521b\u5efa\u63a7\u5236\u53f0\u5904\u7406\u5668\uff1alogging.StreamHandler()\n    \u251c\u2500\u2500 \u8bbe\u7f6e\u65e5\u5fd7\u683c\u5f0f\uff1a\u65f6\u95f4-\u540d\u79f0-\u7ea7\u522b-\u6d88\u606f\n    \u2514\u2500\u2500 \u6dfb\u52a0\u5904\u7406\u5668\uff1alogger.addHandler(handler)\n'''\n#4. \u751f\u547d\u5468\u671f\u7ba1\u7406\u5668\n'''\n\u751f\u547d\u5468\u671f\u7ba1\u7406\u5668\uff08lifespan\u51fd\u6570\uff09\n\u251c\u2500\u2500 \u542f\u52a8\u9636\u6bb5\uff08startup\uff09\n\u2502   \u251c\u2500\u2500 \u521d\u59cb\u5316\u610f\u56fe\u5206\u6790\u5668\uff1aget_background_analyzer()\n\u2502   \u251c\u2500\u2500 \u521d\u59cb\u5316\u7535\u8111\u63a7\u5236\u667a\u80fd\u4f53\uff1aComputerControlAgent()\n\u2502   \u251c\u2500\u2500 \u521d\u59cb\u5316\u4efb\u52a1\u8c03\u5ea6\u5668\uff1aget_task_scheduler()\n\u2502   \u2514\u2500\u2500 \u8bbe\u7f6eLLM\u914d\u7f6e\uff08\u5982\u679c\u5b58\u5728\uff09\n\u2502\n\u251c\u2500\u2500 \u8fd0\u884c\u9636\u6bb5\uff08yield\uff09\n\u2514\u2500\u2500 \u5173\u95ed\u9636\u6bb5\uff08shutdown\uff09\n    \u2514\u2500\u2500 \u8bb0\u5f55\u5173\u95ed\u65e5\u5fd7\n'''\n#5. \u5168\u5c40\u6a21\u5757\u7ba1\u7406\u5668\n'''\n\u5168\u5c40\u6a21\u5757\u7ba1\u7406\u5668\uff08Modules\u7c7b\uff09\n\u251c\u2500\u2500 \u610f\u56fe\u5206\u6790\u5668\uff1aanalyzer = None\n\u251c\u2500\u2500 \u7535\u8111\u63a7\u5236\u5668\uff1acomputer_control = None\n\u2514\u2500\u2500 \u4efb\u52a1\u8c03\u5ea6\u5668\uff1atask_scheduler = None\n'''\n# 6.\u5185\u90e8\u5de5\u5177\u51fd\u6570\n'''\n\u5185\u90e8\u5de5\u5177\u51fd\u6570\n\u2514\u2500\u2500 \u65f6\u95f4\u5de5\u5177\n    \u2514\u2500\u2500 def _now_iso() -> str\n        \u251c\u2500\u2500 \u529f\u80fd\uff1a\u83b7\u53d6\u5f53\u524dISO\u683c\u5f0f\u65f6\u95f4\n        \u2514\u2500\u2500 \u8fd4\u56de\uff1aYYYY-MM-DDTHH:MM:SS\u683c\u5f0f\u5b57\u7b26\u4e32\n'''\n#7. \u6838\u5fc3\u5904\u7406\u51fd\u6570\n'''\n\u6838\u5fc3\u5904\u7406\u51fd\u6570\n\u251c\u2500\u2500 \u5355\u4e2a\u4efb\u52a1\u5904\u7406\u5668\n\u2502   \u2514\u2500\u2500 async def _process_computer_control_task(...)\n\u2502       \u251c\u2500\u2500 \u529f\u80fd\uff1a\u5904\u7406\u5355\u4e2a\u7535\u8111\u63a7\u5236\u4efb\u52a1\n\u2502       \u251c\u2500\u2500 \u8f93\u5165\uff1a\u6307\u4ee4\u548c\u4f1a\u8bddID\n\u2502       \u251c\u2500\u2500 \u6d41\u7a0b\uff1a\n\u2502       \u2502   \u251c\u2500\u2500 \u8bb0\u5f55\u5f00\u59cb\u65e5\u5fd7\n\u2502       \u2502   \u251c\u2500\u2500 \u8c03\u7528\u7535\u8111\u63a7\u5236\u5668\u6267\u884c\n\u2502       \u2502   \u251c\u2500\u2500 \u8bb0\u5f55\u5b8c\u6210\u65e5\u5fd7\n\u2502       \u2502   \u2514\u2500\u2500 \u8fd4\u56de\u7ed3\u679c\n\u2502       \u2514\u2500\u2500 \u8f93\u51fa\uff1a\u6210\u529f\/\u5931\u8d25\u7ed3\u679c\n\u2502\n\u251c\u2500\u2500 \u6279\u91cf\u4efb\u52a1\u6267\u884c\u5668\n\u2502   \u2514\u2500\u2500 async def _execute_agent_tasks_async(...)\n\u2502       \u251c\u2500\u2500 \u529f\u80fd\uff1a\u5f02\u6b65\u6267\u884c\u591a\u4e2aAgent\u4efb\u52a1\n\u2502       \u251c\u2500\u2500 \u8f93\u5165\uff1a\u4efb\u52a1\u5217\u8868\u3001\u4f1a\u8bdd\u4fe1\u606f\u7b49\n\u2502       \u251c\u2500\u2500 \u6d41\u7a0b\uff1a\n\u2502       \u2502   \u251c\u2500\u2500 \u5faa\u73af\u5904\u7406\u6bcf\u4e2a\u4efb\u52a1\n\u2502       \u2502   \u251c\u2500\u2500 \u4e3a\u6bcf\u4e2a\u4efb\u52a1\u6dfb\u52a0\u6b65\u9aa4\u8bb0\u5f55\n\u2502       \u2502   \u251c\u2500\u2500 \u6267\u884c\u7535\u8111\u63a7\u5236\u4efb\u52a1\n\u2502       \u2502   \u251c\u2500\u2500 \u66f4\u65b0\u6b65\u9aa4\u7ed3\u679c\n\u2502       \u2502   \u2514\u2500\u2500 \u53d1\u9001\u56de\u8c03\u901a\u77e5\n\u2502       \u2514\u2500\u2500 \u8f93\u51fa\uff1a\u65e0\uff08\u5f02\u6b65\u6267\u884c\uff09\n\u2502\n\u2514\u2500\u2500 \u56de\u8c03\u901a\u77e5\u5668\n    \u2514\u2500\u2500 async def _send_callback_notification(...)\n        \u251c\u2500\u2500 \u529f\u80fd\uff1a\u53d1\u9001\u4efb\u52a1\u5b8c\u6210\u56de\u8c03\u901a\u77e5\n        \u251c\u2500\u2500 \u8f93\u5165\uff1a\u56de\u8c03URL\u3001\u4efb\u52a1\u7ed3\u679c\u7b49\n        \u251c\u2500\u2500 \u6d41\u7a0b\uff1a\n        \u2502   \u251c\u2500\u2500 \u6784\u5efa\u56de\u8c03\u6570\u636e\n        \u2502   \u251c\u2500\u2500 \u53d1\u9001HTTP POST\u8bf7\u6c42\n        \u2502   \u2514\u2500\u2500 \u5904\u7406\u54cd\u5e94\n        \u2514\u2500\u2500 \u8f93\u51fa\uff1a\u65e0\n'''\n#8. API\u7aef\u70b9\u7cfb\u7edf\uff0825\u4e2a\u7aef\u70b9\uff09\n#8.1 \u7cfb\u7edf\u72b6\u6001\u68c0\u67e5\n'''\n\u7cfb\u7edf\u72b6\u6001\u68c0\u67e5\n\u251c\u2500\u2500 GET \/health\n\u2502   \u251c\u2500\u2500 \u529f\u80fd\uff1a\u5065\u5eb7\u68c0\u67e5\n\u2502   \u2514\u2500\u2500 \u8fd4\u56de\uff1a\u670d\u52a1\u72b6\u6001\u548c\u5404\u6a21\u5757\u5c31\u7eea\u60c5\u51b5\n\u2502\n\u2514\u2500\u2500 GET \/computer_control\/availability\n    \u251c\u2500\u2500 \u529f\u80fd\uff1a\u83b7\u53d6\u7535\u8111\u63a7\u5236\u53ef\u7528\u6027\n    \u2514\u2500\u2500 \u8fd4\u56de\uff1a\u7535\u8111\u63a7\u5236\u80fd\u529b\u548c\u72b6\u6001\n'''\n#8.2 \u4efb\u52a1\u6267\u884c\u7aef\u70b9\n'''\n\u4efb\u52a1\u6267\u884c\u7aef\u70b9\n\u251c\u2500\u2500 POST \/schedule\n\u2502   \u251c\u2500\u2500 \u529f\u80fd\uff1a\u7edf\u4e00\u4efb\u52a1\u8c03\u5ea6\uff08\u4e3b\u5165\u53e3\uff09\n\u2502   \u251c\u2500\u2500 \u8f93\u5165\uff1a\u67e5\u8be2\u3001\u4efb\u52a1\u5217\u8868\u3001\u4f1a\u8bdd\u4fe1\u606f\u7b49\n\u2502   \u251c\u2500\u2500 \u6d41\u7a0b\uff1a\n\u2502   \u2502   \u251c\u2500\u2500 \u68c0\u67e5\u8c03\u5ea6\u5668\u5c31\u7eea\n\u2502   \u2502   \u251c\u2500\u2500 \u521b\u5efa\u4efb\u52a1\u8bb0\u5f55\n\u2502   \u2502   \u251c\u2500\u2500 \u5f02\u6b65\u6267\u884c\u4efb\u52a1\n\u2502   \u2502   \u2514\u2500\u2500 \u7acb\u5373\u8fd4\u56de\u63a5\u53d7\u54cd\u5e94\n\u2502   \u2514\u2500\u2500 \u8fd4\u56de\uff1a\u4efb\u52a1ID\u548c\u8c03\u5ea6\u72b6\u6001\n\u2502\n\u251c\u2500\u2500 POST \/analyze_and_execute\n\u2502   \u251c\u2500\u2500 \u529f\u80fd\uff1a\u610f\u56fe\u5206\u6790\u548c\u6267\u884c\uff08\u517c\u5bb9\u65e7\u7248\uff09\n\u2502   \u251c\u2500\u2500 \u8f93\u5165\uff1a\u6d88\u606f\u5217\u8868\u548c\u4f1a\u8bddID\n\u2502   \u251c\u2500\u2500 \u6d41\u7a0b\uff1a\n\u2502   \u2502   \u251c\u2500\u2500 \u4ece\u6d88\u606f\u4e2d\u63d0\u53d6\u4efb\u52a1\u6307\u4ee4\n\u2502   \u2502   \u251c\u2500\u2500 \u540c\u6b65\u6267\u884c\u6bcf\u4e2a\u4efb\u52a1\n\u2502   \u2502   \u2514\u2500\u2500 \u7b49\u5f85\u6240\u6709\u4efb\u52a1\u5b8c\u6210\n\u2502   \u2514\u2500\u2500 \u8fd4\u56de\uff1a\u6267\u884c\u7ed3\u679c\u5217\u8868\n\u2502\n\u2514\u2500\u2500 POST \/computer_control\/execute\n    \u251c\u2500\u2500 \u529f\u80fd\uff1a\u76f4\u63a5\u6267\u884c\u7535\u8111\u63a7\u5236\u4efb\u52a1\n    \u251c\u2500\u2500 \u8f93\u5165\uff1a\u6307\u4ee4\u5b57\u7b26\u4e32\n    \u2514\u2500\u2500 \u8fd4\u56de\uff1a\u6267\u884c\u7ed3\u679c\n'''\n#8.3 \u4efb\u52a1\u8bb0\u5fc6\u7ba1\u7406\n'''\n\u4efb\u52a1\u8bb0\u5fc6\u7ba1\u7406\n\u251c\u2500\u2500 \u4efb\u52a1\u7ea7\u522b\uff08Task Level\uff09\n\u2502   \u251c\u2500\u2500 GET \/tasks\n\u2502   \u2502   \u251c\u2500\u2500 \u529f\u80fd\uff1a\u83b7\u53d6\u6240\u6709\u4efb\u52a1\u5217\u8868\n\u2502   \u2502   \u2514\u2500\u2500 \u8fd4\u56de\uff1a\u6b63\u5728\u8fd0\u884c\u7684\u4efb\u52a1\u5217\u8868\n\u2502   \u2502\n\u2502   \u251c\u2500\u2500 GET \/tasks\/{task_id}\n\u2502   \u2502   \u251c\u2500\u2500 \u529f\u80fd\uff1a\u83b7\u53d6\u6307\u5b9a\u4efb\u52a1\u72b6\u6001\n\u2502   \u2502   \u2514\u2500\u2500 \u8fd4\u56de\uff1a\u4efb\u52a1\u8be6\u7ec6\u72b6\u6001\n\u2502   \u2502\n\u2502   \u251c\u2500\u2500 GET \/tasks\/{task_id}\/memory\n\u2502   \u2502   \u251c\u2500\u2500 \u529f\u80fd\uff1a\u83b7\u53d6\u4efb\u52a1\u8bb0\u5fc6\u6458\u8981\n\u2502   \u2502   \u2514\u2500\u2500 \u8fd4\u56de\uff1a\u4efb\u52a1\u8bb0\u5fc6\u4fe1\u606f\n\u2502   \u2502\n\u2502   \u251c\u2500\u2500 POST \/tasks\/{task_id}\/steps\n\u2502   \u2502   \u251c\u2500\u2500 \u529f\u80fd\uff1a\u6dfb\u52a0\u4efb\u52a1\u6b65\u9aa4\n\u2502   \u2502   \u2514\u2500\u2500 \u8fd4\u56de\uff1a\u6b65\u9aa4\u6dfb\u52a0\u7ed3\u679c\n\u2502   \u2502\n\u2502   \u2514\u2500\u2500 DELETE \/tasks\/{task_id}\/memory\n\u2502       \u251c\u2500\u2500 \u529f\u80fd\uff1a\u6e05\u9664\u4efb\u52a1\u8bb0\u5fc6\n\u2502       \u2514\u2500\u2500 \u8fd4\u56de\uff1a\u6e05\u9664\u7ed3\u679c\n\u2502\n\u251c\u2500\u2500 \u4f1a\u8bdd\u7ea7\u522b\uff08Session Level\uff09\n\u2502   \u251c\u2500\u2500 GET \/sessions\n\u2502   \u2502   \u251c\u2500\u2500 \u529f\u80fd\uff1a\u83b7\u53d6\u6240\u6709\u4f1a\u8bdd\u6458\u8981\n\u2502   \u2502   \u2514\u2500\u2500 \u8fd4\u56de\uff1a\u4f1a\u8bdd\u5217\u8868\u548c\u603b\u6570\n\u2502   \u2502\n\u2502   \u251c\u2500\u2500 GET \/sessions\/{session_id}\/memory\n\u2502   \u2502   \u251c\u2500\u2500 \u529f\u80fd\uff1a\u83b7\u53d6\u4f1a\u8bdd\u8bb0\u5fc6\u6458\u8981\n\u2502   \u2502   \u2514\u2500\u2500 \u8fd4\u56de\uff1a\u4f1a\u8bdd\u8bb0\u5fc6\u4fe1\u606f\n\u2502   \u2502\n\u2502   \u251c\u2500\u2500 GET \/sessions\/{session_id}\/compressed_memories\n\u2502   \u2502   \u251c\u2500\u2500 \u529f\u80fd\uff1a\u83b7\u53d6\u4f1a\u8bdd\u538b\u7f29\u8bb0\u5fc6\n\u2502   \u2502   \u2514\u2500\u2500 \u8fd4\u56de\uff1a\u538b\u7f29\u8bb0\u5fc6\u5217\u8868\n\u2502   \u2502\n\u2502   \u251c\u2500\u2500 GET \/sessions\/{session_id}\/key_facts\n\u2502   \u2502   \u251c\u2500\u2500 \u529f\u80fd\uff1a\u83b7\u53d6\u4f1a\u8bdd\u5173\u952e\u4e8b\u5b9e\n\u2502   \u2502   \u2514\u2500\u2500 \u8fd4\u56de\uff1a\u5173\u952e\u4e8b\u5b9e\u5217\u8868\n\u2502   \u2502\n\u2502   \u251c\u2500\u2500 GET \/sessions\/{session_id}\/failed_attempts\n\u2502   \u2502   \u251c\u2500\u2500 \u529f\u80fd\uff1a\u83b7\u53d6\u4f1a\u8bdd\u5931\u8d25\u5c1d\u8bd5\n\u2502   \u2502   \u2514\u2500\u2500 \u8fd4\u56de\uff1a\u5931\u8d25\u8bb0\u5f55\u5217\u8868\n\u2502   \u2502\n\u2502   \u251c\u2500\u2500 GET \/sessions\/{session_id}\/tasks\n\u2502   \u2502   \u251c\u2500\u2500 \u529f\u80fd\uff1a\u83b7\u53d6\u4f1a\u8bdd\u7684\u6240\u6709\u4efb\u52a1\n\u2502   \u2502   \u2514\u2500\u2500 \u8fd4\u56de\uff1a\u4efb\u52a1\u5217\u8868\n\u2502   \u2502\n\u2502   \u2514\u2500\u2500 DELETE \/sessions\/{session_id}\/memory\n\u2502       \u251c\u2500\u2500 \u529f\u80fd\uff1a\u6e05\u9664\u6307\u5b9a\u4f1a\u8bdd\u8bb0\u5fc6\n\u2502       \u2514\u2500\u2500 \u8fd4\u56de\uff1a\u6e05\u9664\u7ed3\u679c\n\u2502\n\u2514\u2500\u2500 \u5168\u5c40\u7ea7\u522b\uff08Global Level\uff09\n    \u251c\u2500\u2500 GET \/memory\/global\n    \u2502   \u251c\u2500\u2500 \u529f\u80fd\uff1a\u83b7\u53d6\u5168\u5c40\u8bb0\u5fc6\u6458\u8981\n    \u2502   \u2514\u2500\u2500 \u8fd4\u56de\uff1a\u5168\u5c40\u8bb0\u5fc6\u548c\u5931\u8d25\u5c1d\u8bd5\u6458\u8981\n    \u2502\n    \u2514\u2500\u2500 DELETE \/memory\/global\n        \u251c\u2500\u2500 \u529f\u80fd\uff1a\u6e05\u9664\u5168\u5c40\u8bb0\u5fc6\n        \u2514\u2500\u2500 \u8fd4\u56de\uff1a\u6e05\u9664\u7ed3\u679c\n'''\n#8.4 \u5de5\u5177\u7ba1\u7406\u7cfb\u7edf\n'''\n\u5de5\u5177\u7ba1\u7406\u7cfb\u7edf\n\u251c\u2500\u2500 GET \/tools\n\u2502   \u251c\u2500\u2500 \u529f\u80fd\uff1a\u5217\u51fa\u6240\u6709\u53ef\u7528\u5de5\u5177\n\u2502   \u2514\u2500\u2500 \u8fd4\u56de\uff1a\u5de5\u5177\u5217\u8868\u548c\u603b\u6570\n\u2502\n\u251c\u2500\u2500 GET \/toolkits\n\u2502   \u251c\u2500\u2500 \u529f\u80fd\uff1a\u5217\u51fa\u6240\u6709\u53ef\u7528\u5de5\u5177\u5305\n\u2502   \u2514\u2500\u2500 \u8fd4\u56de\uff1a\u5de5\u5177\u5305\u5217\u8868\u548c\u603b\u6570\n\u2502\n\u251c\u2500\u2500 GET \/toolkits\/{toolkit_name}\n\u2502   \u251c\u2500\u2500 \u529f\u80fd\uff1a\u83b7\u53d6\u5de5\u5177\u5305\u8be6\u7ec6\u4fe1\u606f\n\u2502   \u2514\u2500\u2500 \u8fd4\u56de\uff1a\u5de5\u5177\u5305\u8be6\u60c5\n\u2502\n\u2514\u2500\u2500 POST \/tools\/{toolkit_name}\/{tool_name}\n    \u251c\u2500\u2500 \u529f\u80fd\uff1a\u8c03\u7528\u6307\u5b9a\u5de5\u5177\n    \u2514\u2500\u2500 \u8fd4\u56de\uff1a\u5de5\u5177\u6267\u884c\u7ed3\u679c\n'''\n#8.5 \u6587\u4ef6\u64cd\u4f5c\u7cfb\u7edf\n'''\n\u6587\u4ef6\u64cd\u4f5c\u7cfb\u7edf\n\u251c\u2500\u2500 POST \/file\/edit\n\u2502   \u251c\u2500\u2500 \u529f\u80fd\uff1a\u7f16\u8f91\u6587\u4ef6\uff08SEARCH\/REPLACE\u683c\u5f0f\uff09\n\u2502   \u2514\u2500\u2500 \u8fd4\u56de\uff1a\u7f16\u8f91\u7ed3\u679c\n\u2502\n\u251c\u2500\u2500 POST \/file\/write\n\u2502   \u251c\u2500\u2500 \u529f\u80fd\uff1a\u5199\u5165\u6587\u4ef6\n\u2502   \u2514\u2500\u2500 \u8fd4\u56de\uff1a\u5199\u5165\u7ed3\u679c\n\u2502\n\u251c\u2500\u2500 GET \/file\/read\n\u2502   \u251c\u2500\u2500 \u529f\u80fd\uff1a\u8bfb\u53d6\u6587\u4ef6\n\u2502   \u2514\u2500\u2500 \u8fd4\u56de\uff1a\u6587\u4ef6\u5185\u5bb9\n\u2502\n\u2514\u2500\u2500 GET \/file\/list\n    \u251c\u2500\u2500 \u529f\u80fd\uff1a\u5217\u51fa\u76ee\u5f55\u6587\u4ef6\n    \u2514\u2500\u2500 \u8fd4\u56de\uff1a\u6587\u4ef6\u548c\u76ee\u5f55\u5217\u8868\n'''\n#9. \u7a0b\u5e8f\u542f\u52a8\u5165\u53e3\n'''\n\u7a0b\u5e8f\u542f\u52a8\u5165\u53e3\n\u251c\u2500\u2500 \u6761\u4ef6\u5224\u65ad\uff1aif __name__ == \"__main__\"\n\u251c\u2500\u2500 \u5bfc\u5165uvicorn\u670d\u52a1\u5668\n\u251c\u2500\u2500 \u5bfc\u5165\u7aef\u53e3\u914d\u7f6e\n\u2514\u2500\u2500 \u542f\u52a8Web\u670d\u52a1\u5668\n    \u251c\u2500\u2500 \u670d\u52a1\u5668\uff1auvicorn\n    \u251c\u2500\u2500 \u5e94\u7528\uff1aapp\n    \u251c\u2500\u2500 \u4e3b\u673a\uff1a0.0.0.0\uff08\u6240\u6709\u7f51\u7edc\u63a5\u53e3\uff09\n    \u2514\u2500\u2500 \u7aef\u53e3\uff1a\u4ece\u914d\u7f6e\u8bfb\u53d6\n'''\n#\u4e09\u3001\u6570\u636e\u6d41\u5c42\u7ea7\u7ed3\u6784\n#\u8bf7\u6c42\u5904\u7406\u6d41\u7a0b\n'''\n\u5916\u90e8\u8bf7\u6c42\n  \u2193\nFastAPI\u8def\u7531\n  \u2193\nAPI\u7aef\u70b9\u51fd\u6570\n  \u251c\u2500\u2500 \u53c2\u6570\u9a8c\u8bc1\n  \u251c\u2500\u2500 \u6743\u9650\u68c0\u67e5\n  \u251c\u2500\u2500 \u8c03\u7528\u5185\u90e8\u51fd\u6570\n  \u2514\u2500\u2500 \u8fd4\u56de\u54cd\u5e94\n    \u2193\n\u5185\u90e8\u5904\u7406\u51fd\u6570\n  \u251c\u2500\u2500 \u8c03\u7528\u5168\u5c40\u6a21\u5757\n  \u251c\u2500\u2500 \u6267\u884c\u5177\u4f53\u64cd\u4f5c\n  \u2514\u2500\u2500 \u8bb0\u5f55\u65e5\u5fd7\u548c\u8bb0\u5fc6\n    \u2193\n\u5168\u5c40\u6a21\u5757\n  \u251c\u2500\u2500 \u610f\u56fe\u5206\u6790\u5668\uff08\u7406\u89e3\u7528\u6237\u610f\u56fe\uff09\n  \u251c\u2500\u2500 \u7535\u8111\u63a7\u5236\u5668\uff08\u6267\u884c\u7535\u8111\u64cd\u4f5c\uff09\n  \u2514\u2500\u2500 \u4efb\u52a1\u8c03\u5ea6\u5668\uff08\u7ba1\u7406\u4efb\u52a1\u6d41\u7a0b\uff09\n    \u2193\n\u5e95\u5c42\u7cfb\u7edf\n  \u251c\u2500\u2500 \u6587\u4ef6\u7cfb\u7edf\uff08\u8bfb\u5199\u6587\u4ef6\uff09\n  \u251c\u2500\u2500 \u64cd\u4f5c\u7cfb\u7edf\uff08\u63a7\u5236\u7535\u8111\uff09\n  \u2514\u2500\u2500 \u7f51\u7edc\u7cfb\u7edf\uff08\u53d1\u9001\u56de\u8c03\uff09\n'''\n#\u8bb0\u5fc6\u7cfb\u7edf\u5c42\u7ea7\n'''\n\u8bb0\u5fc6\u7cfb\u7edf\u5c42\u7ea7\n\u251c\u2500\u2500 \u6b65\u9aa4\u7ea7\u522b\uff08Step Level\uff09\n\u2502   \u251c\u2500\u2500 \u5355\u4e2a\u64cd\u4f5c\u8bb0\u5f55\n\u2502   \u251c\u2500\u2500 \u6267\u884c\u7ed3\u679c\n\u2502   \u2514\u2500\u2500 \u9519\u8bef\u4fe1\u606f\n\u2502\n\u251c\u2500\u2500 \u4efb\u52a1\u7ea7\u522b\uff08Task Level\uff09\n\u2502   \u251c\u2500\u2500 \u4efb\u52a1\u76ee\u7684\n\u2502   \u251c\u2500\u2500 \u6240\u6709\u6b65\u9aa4\u8bb0\u5f55\n\u2502   \u251c\u2500\u2500 \u4efb\u52a1\u72b6\u6001\n\u2502   \u2514\u2500\u2500 \u4efb\u52a1\u7ed3\u679c\n\u2502\n\u251c\u2500\u2500 \u4f1a\u8bdd\u7ea7\u522b\uff08Session Level\uff09\n\u2502   \u251c\u2500\u2500 \u7528\u6237\u4f1a\u8bdd\u4e0a\u4e0b\u6587\n\u2502   \u251c\u2500\u2500 \u6240\u6709\u4efb\u52a1\u8bb0\u5f55\n\u2502   \u251c\u2500\u2500 \u538b\u7f29\u8bb0\u5fc6\uff08\u7cbe\u7b80\u7248\uff09\n\u2502   \u251c\u2500\u2500 \u5173\u952e\u4e8b\u5b9e\uff08\u91cd\u8981\u4fe1\u606f\uff09\n\u2502   \u2514\u2500\u2500 \u5931\u8d25\u5c1d\u8bd5\u8bb0\u5f55\n\u2502\n\u2514\u2500\u2500 \u5168\u5c40\u7ea7\u522b\uff08Global Level\uff09\n    \u251c\u2500\u2500 \u6240\u6709\u4f1a\u8bdd\u6458\u8981\n    \u251c\u2500\u2500 \u7cfb\u7edf\u603b\u4f53\u7edf\u8ba1\n    \u2514\u2500\u2500 \u5168\u5c40\u5931\u8d25\u8bb0\u5f55\n'''\n#\u56db\u3001\u9519\u8bef\u5904\u7406\u5c42\u7ea7\n'''\n\u9519\u8bef\u5904\u7406\u7ed3\u6784\n\u251c\u2500\u2500 HTTP\u5f02\u5e38\uff08HTTPException\uff09\n\u2502   \u251c\u2500\u2500 400 Bad Request\uff08\u5ba2\u6237\u7aef\u9519\u8bef\uff09\n\u2502   \u251c\u2500\u2500 404 Not Found\uff08\u8d44\u6e90\u4e0d\u5b58\u5728\uff09\n\u2502   \u251c\u2500\u2500 503 Service Unavailable\uff08\u670d\u52a1\u4e0d\u53ef\u7528\uff09\n\u2502   \u2514\u2500\u2500 500 Internal Server Error\uff08\u670d\u52a1\u5668\u5185\u90e8\u9519\u8bef\uff09\n\u2502\n\u251c\u2500\u2500 \u901a\u7528\u5f02\u5e38\u5904\u7406\n\u2502   \u251c\u2500\u2500 try-except\u5757\n\u2502   \u251c\u2500\u2500 \u8bb0\u5f55\u9519\u8bef\u65e5\u5fd7\n\u2502   \u2514\u2500\u2500 \u8fd4\u56de\u7edf\u4e00\u9519\u8bef\u683c\u5f0f\n\u2502\n\u2514\u2500\u2500 \u7279\u5b9a\u5f02\u5e38\u5904\u7406\n    \u251c\u2500\u2500 \u5df2\u77e5\u9519\u8bef\uff1a\u76f4\u63a5\u629b\u51faHTTPException\n    \u2514\u2500\u2500 \u672a\u77e5\u9519\u8bef\uff1a\u6355\u83b7\u5e76\u8f6c\u6362\u4e3a500\u9519\u8bef\n'''\n#\u4e94\u3001\u914d\u7f6e\u5c42\u7ea7\u7ed3\u6784\n'''\n\u914d\u7f6e\u7cfb\u7edf\n\u251c\u2500\u2500 \u65e5\u5fd7\u914d\u7f6e\n\u2502   \u251c\u2500\u2500 \u65e5\u5fd7\u7ea7\u522b\uff1aINFO\n\u2502   \u251c\u2500\u2500 \u8f93\u51fa\u683c\u5f0f\n\u2502   \u2514\u2500\u2500 \u8f93\u51fa\u76ee\u6807\n\u2502\n\u251c\u2500\u2500 \u670d\u52a1\u5668\u914d\u7f6e\n\u2502   \u2514\u2500\u2500 \u7aef\u53e3\u53f7\uff1a\u4eceagentserver.config\u5bfc\u5165\n\u2502\n\u251c\u2500\u2500 AI\u6a21\u578b\u914d\u7f6e\n\u2502   \u251c\u2500\u2500 \u6a21\u578b\u540d\u79f0\n\u2502   \u251c\u2500\u2500 API\u5bc6\u94a5\n\u2502   \u2514\u2500\u2500 \u57fa\u7840URL\n\u2502\n\u2514\u2500\u2500 \u6a21\u5757\u914d\u7f6e\n    \u251c\u2500\u2500 \u610f\u56fe\u5206\u6790\u5668\u914d\u7f6e\n    \u251c\u2500\u2500 \u7535\u8111\u63a7\u5236\u5668\u914d\u7f6e\n    \u2514\u2500\u2500 \u4efb\u52a1\u8c03\u5ea6\u5668\u914d\u7f6e\n'''<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">agent_manager.py<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>#!\/usr\/bin\/env python3\n# -*- coding: utf-8 -*-\n\"\"\"\nAgent\u7ba1\u7406\u5668 - \u72ec\u7acb\u7684Agent\u6ce8\u518c\u548c\u8c03\u7528\u7cfb\u7edf\n\u652f\u6301\u4ece\u914d\u7f6e\u6587\u4ef6\u52a8\u6001\u52a0\u8f7dAgent\u5b9a\u4e49\uff0c\u63d0\u4f9b\u7edf\u4e00\u7684\u8c03\u7528\u63a5\u53e3\n\u7b2c1\u884c\uff1a\u544a\u8bc9\u7535\u8111\"\u8fd9\u4e2a\u6587\u4ef6\u8981\u7528python3\u6765\u8fd0\u884c\"\n\u7b2c2\u884c\uff1a\u544a\u8bc9\u7535\u8111\"\u8fd9\u4e2a\u6587\u4ef6\u91cc\u7684\u6587\u5b57\u4f7f\u7528UTF-8\u7f16\u7801\"\uff08\u8fd9\u6837\u624d\u80fd\u6b63\u786e\u663e\u793a\u4e2d\u6587\uff09\n\"\"\"\n\nimport os          # \u7528\u6765\u64cd\u4f5c\u6587\u4ef6\u548c\u6587\u4ef6\u5939\nimport json        # \u7528\u6765\u5904\u7406JSON\u683c\u5f0f\u7684\u6570\u636e\nimport asyncio     # \u7528\u6765\u5904\u7406\"\u5f02\u6b65\"\u64cd\u4f5c\uff08\u53ef\u4ee5\u540c\u65f6\u505a\u591a\u4ef6\u4e8b\uff09\nimport logging     # \u7528\u6765\u8bb0\u5f55\u7a0b\u5e8f\u8fd0\u884c\u65f6\u7684\u4fe1\u606f\nimport time        # \u7528\u6765\u5904\u7406\u65f6\u95f4\u76f8\u5173\u7684\u64cd\u4f5c\nfrom pathlib import Path  # \u66f4\u597d\u7684\u5904\u7406\u6587\u4ef6\u8def\u5f84\nfrom typing import Dict, Any, Optional, List  # \u7ed9\u4ee3\u7801\u6dfb\u52a0\u7c7b\u578b\u63d0\u793a\uff0c\u8ba9\u4ee3\u7801\u66f4\u6e05\u6670\nfrom dataclasses import dataclass, field  # \u521b\u5efa\u6570\u636e\u7c7b\uff0c\u7b80\u5316\u4ee3\u7801\nfrom datetime import datetime, timedelta  # \u5904\u7406\u65e5\u671f\u548c\u65f6\u95f4\nimport re  # \u5904\u7406\u6587\u672c\u5339\u914d\uff08\u6b63\u5219\u8868\u8fbe\u5f0f\uff09\n#\u8fd9\u4e9b\u5c31\u50cf\u5de5\u5177\u7bb1\u91cc\u7684\u4e0d\u540c\u5de5\u5177\uff0c\u6bcf\u4e2a\u5de5\u5177\u90fd\u6709\u4e13\u95e8\u7684\u7528\u9014\u3002\n\n# \u914d\u7f6e\u65e5\u5fd7\nlogging.basicConfig(level=logging.INFO)    # \u8bbe\u7f6e\u8bb0\u5f55\"INFO\"\u7ea7\u522b\u53ca\u4ee5\u4e0a\u7684\u4fe1\u606f\nlogger = logging.getLogger(\"AgentManager\")   # \u521b\u5efa\u4e00\u4e2a\u53eb\"AgentManager\"\u7684\u65e5\u5fd7\u8bb0\u5f55\u5668\n\n# \u5c4f\u853dHTTP\u5e93\u7684DEBUG\u65e5\u5fd7\nlogging.getLogger(\"httpcore.http11\").setLevel(logging.WARNING)\nlogging.getLogger(\"httpx\").setLevel(logging.WARNING)\nlogging.getLogger(\"httpcore.connection\").setLevel(logging.WARNING)\n'''\n\u8fd9\u662f\u4ec0\u4e48\u610f\u601d\uff1f\n\u65e5\u5fd7\u5c31\u50cf\u662f\u7a0b\u5e8f\u7684\"\u65e5\u8bb0\u672c\"\n\u8fd9\u91cc\u8bbe\u7f6e\u53ea\u8bb0\u5f55\u91cd\u8981\u7a0b\u5ea6\u4e3a\"INFO\"\u53ca\u4ee5\u4e0a\u7684\u4fe1\u606f\n\u540e\u9762\u7684\u4e09\u884c\u662f\u544a\u8bc9\u7a0b\u5e8f\uff1a\"\u4e0d\u8981\u8bb0\u5f55HTTP\u7f51\u7edc\u8bf7\u6c42\u7684\u8be6\u7ec6\u4fe1\u606f\"\n'''\n\n'''\n@dataclass\u662f\u4e00\u4e2a\"\u88c5\u9970\u5668\"\uff0c\u5b83\u544a\u8bc9Python\uff1a\"\u8fd9\u4e2a\u7c7b\u662f\u7528\u6765\u5b58\u50a8\u6570\u636e\u7684\"\n\u52a0\u4e86@dataclass\u540e\uff0c\u8fd9\u4e2a\u7c7b\u4f1a\u81ea\u52a8\u751f\u6210\u4e00\u4e9b\u6709\u7528\u7684\u65b9\u6cd5\n\u8ba9\u4f60\u4e0d\u9700\u8981\u5199\u5f88\u591a\u91cd\u590d\u7684\u4ee3\u7801\n\ndataclass \u81ea\u52a8\u751f\u6210\u7684\u529f\u80fd\uff1a\n\u81ea\u52a8\u751f\u6210__init__()\u65b9\u6cd5\uff08\u521d\u59cb\u5316\u65b9\u6cd5\uff09\n\u81ea\u52a8\u751f\u6210__repr__()\u65b9\u6cd5\uff08\u6f02\u4eae\u7684\u6253\u5370\u683c\u5f0f\uff09\n\u81ea\u52a8\u751f\u6210\u6bd4\u8f83\u65b9\u6cd5\uff08\u6bd4\u5982==\u6bd4\u8f83\uff09\n'''\n@dataclass\nclass AgentConfig:\n    \"\"\"Agent\u914d\u7f6e\u7c7b\"\"\"\n    id: str  # \u6a21\u578bID\n    name: str  # Agent\u540d\u79f0\uff08\u4e2d\u6587\u540d\uff09\n    base_name: str  # \u57fa\u7840\u540d\u79f0\uff08\u82f1\u6587\uff09\n    system_prompt: str  # \u7cfb\u7edf\u63d0\u793a\u8bcd\n    max_output_tokens: int = 40000  # \u6700\u5927\u8f93\u51fatoken\u6570\n    temperature: float = 0.7  # \u6e29\u5ea6\u53c2\u6570 \n    description: str = \"\"  # \u63cf\u8ff0\u4fe1\u606f\n    model_provider: str = \"openai\"  # \u6a21\u578b\u63d0\u4f9b\u5546\n    api_base_url: str = \"\"  # API\u57fa\u7840URL\n    api_key: str = \"\"  # API\u5bc6\u94a5\n\n@dataclass\nclass AgentSession:\n    \"\"\"Agent\u4f1a\u8bdd\u7c7b\"\"\"\n    timestamp: float = field(default_factory=time.time)\n    #timestamp: float \u8868\u793a\u8fd9\u4e2a\u5b57\u6bb5\u662f\u6d6e\u70b9\u6570\uff08\u5e26\u5c0f\u6570\u70b9\u7684\u6570\u5b57\uff09,float\u662fPython\u4e2d\u7684\u6d6e\u70b9\u6570\u7c7b\u578b\n    '''\u9ed8\u8ba4\u503c\u8bbe\u7f6e\uff1a\n    = field(default_factory=time.time) \u8fd9\u662f\u7279\u6b8a\u7684\u8bbe\u7f6e\n    field()\u662fdataclasses\u6a21\u5757\u7684\u51fd\u6570\n    default_factory=time.time\u610f\u601d\u662f\uff1a\"\u5982\u679c\u4e0d\u6307\u5b9a\u503c\uff0c\u5c31\u8c03\u7528time.time()\u51fd\u6570\u6765\u83b7\u53d6\u5f53\u524d\u65f6\u95f4\"\n    \n    \u4e3a\u4ec0\u4e48\u7528 default_factory\uff1f\n    # \u5982\u679c\u7528\u666e\u901a\u7684\u9ed8\u8ba4\u503c\uff1a\n    timestamp: float = time.time()  # \u9519\u8bef\uff01\u8fd9\u6837\u4f1a\u5728\u5bfc\u5165\u65f6\u56fa\u5b9a\u65f6\u95f4\n\n     # \u7528 default_factory\uff1a\n    timestamp: float = field(default_factory=time.time)  # \u6b63\u786e\uff01\u6bcf\u6b21\u521b\u5efa\u5bf9\u8c61\u65f6\u624d\u8c03\u7528\n    '''\n    history: List&#91;Dict&#91;str, str]] = field(default_factory=list)\n    '''\n    \u7c7b\u578b\u6ce8\u89e3\u89e3\u91ca\uff1a\n    List&#91;Dict&#91;str, str]]\n    \u251c\u2500\u2500 List: \u5217\u8868\u7c7b\u578b\n    \u2514\u2500\u2500 Dict&#91;str, str]: \u5b57\u5178\u7c7b\u578b\uff0c\u952e\u548c\u503c\u90fd\u662f\u5b57\u7b26\u4e32\n    \u8fd9\u662f\u4ec0\u4e48\u610f\u601d\uff1f\n      \u8fd9\u662f\u4e00\u4e2a\u5217\u8868\n      \u5217\u8868\u91cc\u7684\u6bcf\u4e2a\u5143\u7d20\u90fd\u662f\u4e00\u4e2a\u5b57\u5178\n      \u5b57\u5178\u6709\u4e24\u4e2a\u5b57\u7b26\u4e32\u952e\u503c\u5bf9\n    '''\n    session_id: str = \"default_user_session\"   #\u7c7b\u578b\u662fstr\uff08\u5b57\u7b26\u4e32\uff09,\u9ed8\u8ba4\u503c\u662f\"default_user_session\"\n\nclass AgentManager:\n    \"\"\"Agent\u7ba1\u7406\u5668 - \u589e\u5f3a\u7248\uff0c\u652f\u6301\u4efb\u52a1\u89c4\u5212\u548c\u591a\u667a\u80fd\u4f53\u534f\u4f5c\"\"\"\n    \n    def __init__(self, config_dir: str = None):\n        \"\"\"\n        \u521d\u59cb\u5316Agent\u7ba1\u7406\u5668\n        \n        Args:\n            config_dir: Agent\u914d\u7f6e\u6587\u4ef6\u76ee\u5f55\uff08\u53ef\u9009\uff0cMCP\u67b6\u6784\u4e0b\u901a\u5e38\u4e0d\u9700\u8981\uff09\n        \"\"\"\n        self.config_dir = Path(config_dir) if config_dir else None\n        self.agents: Dict&#91;str, AgentConfig] = {}\n        self.agent_sessions: Dict&#91;str, Dict&#91;str, AgentSession]] = {}\n        '''\n        \u521d\u59cb\u5316\u4e86\u4ec0\u4e48\uff1f\n            config_dir: \u914d\u7f6e\u6587\u4ef6\u7684\u4f4d\u7f6e\uff08\u53ef\u80fd\u6ca1\u6709\uff09\n            agents: \u7a7a\u7684\u5b57\u5178\uff0c\u7528\u6765\u5b58\u653e\u6240\u6709\u52a9\u624b\u7684\u914d\u7f6e\u4fe1\u606f\n            agent_sessions: \u7a7a\u7684\u5b57\u5178\uff0c\u7528\u6765\u5b58\u653e\u6240\u6709\u52a9\u624b\u7684\u5bf9\u8bdd\u8bb0\u5f55\n        \n        \u91cd\u8981\uff1a\n          AgentSession\u5728\u540e\u9762\u4f1a\u5b9a\u4e49\uff0c\u7528\u6765\u8bb0\u5f55\u5bf9\u8bdd\u5386\u53f2\n          \u8fd9\u662f\u4e09\u5c42\u5d4c\u5957\u7684\u5b57\u5178\uff1a\n             \u7b2c\u4e00\u5c42\uff1a\u52a9\u624b\u540d\u5b57 \u2192 \u7b2c\u4e8c\u5c42\u5b57\u5178\n             \u7b2c\u4e8c\u5c42\uff1a\u5bf9\u8bddID \u2192 \u5bf9\u8bdd\u8bb0\u5f55\n             \u7b2c\u4e09\u5c42\uff1a\u5177\u4f53\u7684\u5bf9\u8bdd\u8bb0\u5f55\n        '''\n        \n        # \u4efb\u52a1\u89c4\u5212\u76f8\u5173 - \u73b0\u5728\u901a\u8fc7agentserver\u7684task_scheduler\u5904\u7406\n        # self.task_planner = None  # \u5220\u9664\u91cd\u590d\u529f\u80fd\n        # self.task_executor = None  # \u5220\u9664\u91cd\u590d\u529f\u80fd\n        \n        # \u4ece\u914d\u7f6e\u6587\u4ef6\u8bfb\u53d6\u6700\u5927\u5386\u53f2\u8f6e\u6570\n        try:\n            from system.config import config, AI_NAME\n            self.max_history_rounds = config.api.max_history_rounds\n        except ImportError:\n            self.max_history_rounds = 10  # \u9ed8\u8ba4\u503c\n            logger.warning(\"\u65e0\u6cd5\u5bfc\u5165\u914d\u7f6e\uff0c\u4f7f\u7528\u9ed8\u8ba4\u5386\u53f2\u8f6e\u6570\u8bbe\u7f6e\")\n            '''\n            \u8fd9\u662f\u4ec0\u4e48\u610f\u601d\uff1f\n               \u5c1d\u8bd5\u4ece\u53e6\u4e00\u4e2a\u914d\u7f6e\u6587\u4ef6\u8bfb\u53d6\u8bbe\u7f6e\n               \u5982\u679c\u627e\u4e0d\u5230\u90a3\u4e2a\u6587\u4ef6\uff0c\u5c31\u7528\u9ed8\u8ba4\u503c\uff0810\u8f6e\u5bf9\u8bdd\u5386\u53f2\uff09\n               max_history_rounds\uff1a\u6700\u591a\u4fdd\u7559\u591a\u5c11\u8f6e\u5bf9\u8bdd\u8bb0\u5f55\n            '''\n        self.context_ttl_hours = 24  # \u4e0a\u4e0b\u6587TTL\uff08\u5c0f\u65f6\uff09  #context_ttl_hours = 24\uff1a\u5bf9\u8bdd\u8bb0\u5f55\u4fdd\u5b5824\u5c0f\u65f6\n        self.debug_mode = True    # debug_mode = True\uff1a\u5f00\u542f\u8c03\u8bd5\u6a21\u5f0f\uff08\u4f1a\u8bb0\u5f55\u66f4\u591a\u4fe1\u606f\uff09\n        \n        # \u6761\u4ef6\u52a0\u8f7d\u914d\u7f6e\n        # \u53ea\u5728\u6307\u5b9a\u4e86config_dir\u65f6\u624d\u521b\u5efa\u76ee\u5f55\u548c\u52a0\u8f7d\u914d\u7f6e\n        if self.config_dir:\n            # \u786e\u4fdd\u914d\u7f6e\u76ee\u5f55\u5b58\u5728\n            self.config_dir.mkdir(exist_ok=True)\n            # \u52a0\u8f7dAgent\u914d\u7f6e\n            self._load_agent_configs()\n        else:\n            logger.info(\"AgentManager\u4f7f\u7528MCP\u67b6\u6784\uff0c\u8df3\u8fc7\u5916\u90e8\u914d\u7f6e\u6587\u4ef6\u52a0\u8f7d\")\n            '''\n            \u903b\u8f91\u5224\u65ad\uff1a\n                \u5982\u679c\u63d0\u4f9b\u4e86\u914d\u7f6e\u6587\u4ef6\u76ee\u5f55\uff1a\u521b\u5efa\u76ee\u5f55\u5e76\u52a0\u8f7d\u914d\u7f6e\n                \u5426\u5219\uff1a\u8df3\u8fc7\u52a0\u8f7d\uff0c\u4f7f\u7528MCP\u67b6\u6784\uff08\u53e6\u4e00\u79cd\u7ba1\u7406\u65b9\u5f0f\uff09\n            '''\n            \n        \n        # \u542f\u52a8\u5b9a\u671f\u6e05\u7406\u4efb\u52a1\uff08\u53ea\u5728\u4e8b\u4ef6\u5faa\u73af\u4e2d\u542f\u52a8\uff09\n        try:\n            loop = asyncio.get_running_loop()\n            asyncio.create_task(self._periodic_cleanup())\n        except RuntimeError:\n            # \u6ca1\u6709\u8fd0\u884c\u7684\u4e8b\u4ef6\u5faa\u73af\uff0c\u8df3\u8fc7\u5b9a\u671f\u6e05\u7406\u4efb\u52a1\n            pass\n        '''\n        \u8fd9\u662f\u4ec0\u4e48\uff1f\n           \u542f\u52a8\u4e00\u4e2a\"\u81ea\u52a8\u6e05\u7406\u5de5\"\n           \u8fd9\u4e2a\u6e05\u7406\u5de5\u4f1a\u6bcf\u5c0f\u65f6\u68c0\u67e5\u4e00\u6b21\uff0c\u5220\u9664\u8d85\u8fc724\u5c0f\u65f6\u7684\u65e7\u5bf9\u8bdd\u8bb0\u5f55\n           try...except\uff1a\u5c1d\u8bd5\u542f\u52a8\uff0c\u5931\u8d25\u4e86\u4e5f\u6ca1\u5173\u7cfb\n        '''\n        \n        # \u4efb\u52a1\u89c4\u5212\u5668\u73b0\u5728\u901a\u8fc7agentserver\u7684task_scheduler\u5904\u7406\n        # self._init_task_planner()  # \u5220\u9664\u91cd\u590d\u529f\u80fd\n        \n        logger.info(f\"AgentManager\u521d\u59cb\u5316\u5b8c\u6210\uff0c\u5df2\u52a0\u8f7d {len(self.agents)} \u4e2aAgent\")\n    \n    def _load_agent_configs(self):  #\u4eceJSON\u914d\u7f6e\u6587\u4ef6\u4e2d\u52a0\u8f7d\u6240\u6709\u52a9\u624b\u7684\u8bbe\u7f6e\n        \"\"\"\u4ece\u914d\u7f6e\u6587\u4ef6\u52a0\u8f7dAgent\u5b9a\u4e49\"\"\"\n        # \u68c0\u67e5config_dir\u662f\u5426\u5b58\u5728\n        if not self.config_dir:    \n            logger.info(\"\u672a\u6307\u5b9a\u914d\u7f6e\u6587\u4ef6\u76ee\u5f55\uff0c\u8df3\u8fc7Agent\u914d\u7f6e\u52a0\u8f7d\")\n            return\n            \n        # \u626b\u63cf\u914d\u7f6e\u6587\u4ef6\u76ee\u5f55\n        config_files = list(self.config_dir.glob(\"*.json\")) #glob(\"*.json\")\uff1a\u627e\u51fa\u8fd9\u4e2a\u6587\u4ef6\u5939\u91cc\u6240\u6709.json\u6587\u4ef6\n        \n        for config_file in config_files:   #\u6253\u5f00\u4e00\u4e2aJSON\u6587\u4ef6\n            try:\n                with open(config_file, 'r', encoding='utf-8') as f:\n                    config_data = json.load(f)  #\u6253\u5f00\u4e00\u4e2aJSON\u6587\u4ef6,config_data\u91cc\u5c31\u4fdd\u5b58\u4e86\u6587\u4ef6\u7684\u6240\u6709\u5185\u5bb9\n                \n                # \u89e3\u6790Agent\u914d\u7f6e\n                for agent_key, agent_data in config_data.items():\n                    if self._validate_agent_config(agent_data):\n                        agent_config = AgentConfig(\n                            id=agent_data.get('model_id', ''),\n                            name=agent_data.get('name', agent_key),\n                            base_name=agent_data.get('base_name', agent_key),\n                            system_prompt=agent_data.get('system_prompt', f'You are a helpful AI assistant named {agent_data.get(\"name\", agent_key)}.'),\n                            max_output_tokens=agent_data.get('max_output_tokens', 40000),\n                            temperature=agent_data.get('temperature', 0.7),\n                            description=agent_data.get('description', f'Assistant {agent_data.get(\"name\", agent_key)}.'),\n                            model_provider=agent_data.get('model_provider', 'openai'),\n                            api_base_url=agent_data.get('api_base_url', ''),\n                            api_key=agent_data.get('api_key', '')\n                        )\n                        \n                        self.agents&#91;agent_key] = agent_config\n                        '''\n                        \u8fd9\u4e2a\u8fc7\u7a0b\uff1a\n                            \u68c0\u67e5\u914d\u7f6e\u662f\u5426\u6709\u6548\uff08_validate_agent_config\uff09\n                            \u7528\u914d\u7f6e\u6570\u636e\u521b\u5efaAgentConfig\u5bf9\u8c61\n                            \u628a\u8fd9\u4e2a\u5bf9\u8c61\u5b58\u5230self.agents\u5b57\u5178\u91cc\n                       .get()\u65b9\u6cd5\u7684\u597d\u5904\uff1a\n                            agent_data.get('name', agent_key)\u610f\u601d\u662f\uff1a\n                            \u5982\u679c\u914d\u7f6e\u91cc\u6709name\u5b57\u6bb5\uff0c\u5c31\u7528\u5b83\n                            \u5982\u679c\u6ca1\u6709\uff0c\u5c31\u7528agent_key\uff08\u952e\u540d\uff09\u4ee3\u66ff\n                        '''\n                        logger.info(f\"\u5df2\u52a0\u8f7dAgent: {agent_key} ({agent_config.name})\")\n                \n            except Exception as e:\n                logger.error(f\"\u52a0\u8f7d\u914d\u7f6e\u6587\u4ef6 {config_file} \u5931\u8d25: {e}\")\n    \n    #\u9a8c\u8bc1\u914d\u7f6e\u7684\u65b9\u6cd5\n    def _validate_agent_config(self, config: Dict&#91;str, Any]) -> bool:\n        \"\"\"\u9a8c\u8bc1Agent\u914d\u7f6e\"\"\"\n        required_fields = &#91;'model_id', 'name']#\u5fc5\u987b\u8981\u6709model_id\u548cname\u8fd9\u4e24\u4e2a\u5b57\u6bb5,\u5982\u679c\u7f3a\u5c11\u4efb\u4f55\u4e00\u4e2a\uff0c\u5c31\u8fd4\u56deFalse\uff08\u4e0d\u901a\u8fc7\uff09\n        for field in required_fields:\n            if field not in config or not config&#91;field]:\n                logger.warning(f\"Agent\u914d\u7f6e\u7f3a\u5c11\u5fc5\u9700\u5b57\u6bb5: {field}\")\n                return False\n        return True\n    \n    def get_agent_session_history(self, agent_name: str, session_id: str = 'default_user_session') -> List&#91;Dict&#91;str, str]]:\n        \"\"\"\u83b7\u53d6Agent\u4f1a\u8bdd\u5386\u53f2\"\"\"\n        if agent_name not in self.agent_sessions:\n            self.agent_sessions&#91;agent_name] = {}\n        \n        agent_sessions = self.agent_sessions&#91;agent_name]\n        if session_id not in agent_sessions or self._is_context_expired(agent_sessions&#91;session_id].timestamp):\n            agent_sessions&#91;session_id] = AgentSession(session_id=session_id)\n        \n        return agent_sessions&#91;session_id].history\n    '''\n    \u8fd9\u4e2a\u65b9\u6cd5\u505a\u4ec0\u4e48\uff1f\n         \u83b7\u53d6\u67d0\u4e2a\u52a9\u624b\u3001\u67d0\u4e2a\u5bf9\u8bdd\u7684\u5386\u53f2\u8bb0\u5f55\u3002\n    \u903b\u8f91\u6d41\u7a0b\uff1a\n        \u5982\u679c\u8fd9\u4e2a\u52a9\u624b\u6ca1\u6709\u5bf9\u8bdd\u8bb0\u5f55 \u2192 \u521b\u5efa\u4e00\u4e2a\u7a7a\u7684\u8bb0\u5f55\u5b57\u5178\n        \u5982\u679c\u5bf9\u8bdd\u8bb0\u5f55\u4e0d\u5b58\u5728\u6216\u5df2\u8fc7\u671f \u2192 \u521b\u5efa\u65b0\u7684\u5bf9\u8bdd\u8bb0\u5f55\n        \u8fd4\u56de\u5bf9\u8bdd\u5386\u53f2\n    '''\n    \n    def update_agent_session_history(self, agent_name: str, user_message: str, assistant_message: str, session_id: str = 'default_user_session'):\n        \"\"\"\u66f4\u65b0Agent\u4f1a\u8bdd\u5386\u53f2,\u628a\u65b0\u7684\u4e00\u8f6e\u5bf9\u8bdd\u6dfb\u52a0\u5230\u5386\u53f2\u8bb0\u5f55\u4e2d\u3002\"\"\"\n        if agent_name not in self.agent_sessions:\n            self.agent_sessions&#91;agent_name] = {}\n        \n        agent_sessions = self.agent_sessions&#91;agent_name]\n        if session_id not in agent_sessions or self._is_context_expired(agent_sessions&#91;session_id].timestamp):\n            agent_sessions&#91;session_id] = AgentSession(session_id=session_id)\n        \n        session_data = agent_sessions&#91;session_id]\n        session_data.history.extend(&#91;     #\u6bcf\u6b21\u5bf9\u8bdd\u5305\u542b\u4e24\u6761\u8bb0\u5f55\uff1a\n            {\"role\": \"user\", \"content\": user_message},         #\u7528\u6237\u8bf4\u7684\u8bdd\n            {\"role\": \"assistant\", \"content\": assistant_message}   #\u52a9\u624b\u8bf4\u7684\u8bdd\n        ])\n        session_data.timestamp = time.time()\n        \n        # \u9650\u5236\u5386\u53f2\u6d88\u606f\u6570\u91cf\n        max_messages = self.max_history_rounds * 2\n        if len(session_data.history) > max_messages:\n            session_data.history = session_data.history&#91;-max_messages:]  #&#91;-max_messages:]\uff1a\u53d6\u6700\u540emax_messages\u6761\u8bb0\u5f55\n    \n    def _is_context_expired(self, timestamp: float) -> bool:\n        \"\"\"\u68c0\u67e5\u4e0a\u4e0b\u6587\u662f\u5426\u8fc7\u671f\"\"\"\n        return (time.time() - timestamp) > (self.context_ttl_hours * 3600)\n    '''\n    \u8ba1\u7b97\u903b\u8f91\uff1a\n       time.time()\uff1a\u73b0\u5728\u7684\u65f6\u95f4\uff08\u79d2\u6570\uff09\n       timestamp\uff1a\u4e0a\u6b21\u5bf9\u8bdd\u7684\u65f6\u95f4\uff08\u79d2\u6570\uff09\n       \u4e24\u8005\u76f8\u51cf\u5f97\u5230\u8fc7\u4e86\u591a\u5c11\u79d2\n       \u5982\u679c\u8d85\u8fc724\u5c0f\u65f6\uff0824\u00d73600\u79d2\uff09\u2192 \u8fd4\u56deTrue\uff08\u5df2\u8fc7\u671f\uff09\n    '''\n    \n    async def _periodic_cleanup(self):\n        \"\"\"\u5b9a\u671f\u6e05\u7406\u8fc7\u671f\u7684\u4f1a\u8bdd\u4e0a\u4e0b\u6587\"\"\"\n        while True:\n            try:\n                await asyncio.sleep(3600)  # \u6bcf\u5c0f\u65f6\u6e05\u7406\u4e00\u6b21\n                \n                if self.debug_mode:\n                    logger.debug(\"\u6267\u884c\u5b9a\u671f\u4e0a\u4e0b\u6587\u6e05\u7406...\")\n                    '''\n                    \u8fd9\u662f\u4e00\u4e2a\u65e0\u9650\u5faa\u73af\uff1a\n                       \u7b49\u5f851\u5c0f\u65f6\uff083600\u79d2\uff09\n                       \u6267\u884c\u6e05\u7406\n                       \u56de\u5230\u7b2c1\u6b65\n                    '''\n                \n                for agent_name, sessions in list(self.agent_sessions.items()):#list()\u7684\u4f5c\u7528\uff1a\u521b\u5efa\u5217\u8868\u526f\u672c\uff0c\u907f\u514d\u5728\u5faa\u73af\u4e2d\u4fee\u6539\u5b57\u5178\u51fa\u9519\n                    for session_id, session_data in list(sessions.items()):\n                        if self._is_context_expired(session_data.timestamp):\n                            sessions.pop(session_id, None)\n                            if self.debug_mode:\n                                logger.debug(f\"\u6e05\u7406\u8fc7\u671f\u4e0a\u4e0b\u6587: {agent_name}, session {session_id}\")\n                    \n                    if not sessions:\n                        self.agent_sessions.pop(agent_name, None)\n                        \n            except Exception as e:\n                logger.error(f\"\u5b9a\u671f\u6e05\u7406\u4efb\u52a1\u51fa\u9519: {e}\")\n    \n    def _replace_placeholders(self, text: str, agent_config: AgentConfig) -> str:\n        \"\"\"\u66ff\u6362\u63d0\u793a\u8bcd\u4e2d\u7684\u5360\u4f4d\u7b26\uff0c\u652f\u6301Agent\u914d\u7f6e\u548c\u73af\u5883\u53d8\u91cf\"\"\"\n        if not text:\n            return \"\"\n        \n        processed_text = str(text)#\u628a\u6587\u672c\u4e2d\u7684\"\u6a21\u677f\u53d8\u91cf\"\u66ff\u6362\u6210\u771f\u5b9e\u7684\u503c,\u628a{{AgentName}} \u66ff\u6362\u6210 \"\u5c0f\u52a9\u624b\",\u628a{{CurrentTime}} \u66ff\u6362\u6210 \"14:30:00\"\n        \n        # Agent\u914d\u7f6e\u76f8\u5173\u7684\u5360\u4f4d\u7b26\u66ff\u6362\n        if agent_config:\n            # \u57fa\u7840Agent\u4fe1\u606f\n            processed_text = processed_text.replace(\"{{AgentName}}\", agent_config.name)\n            processed_text = processed_text.replace(\"{{MaidName}}\", agent_config.name)\n            processed_text = processed_text.replace(\"{{BaseName}}\", agent_config.base_name)\n            processed_text = processed_text.replace(\"{{Description}}\", agent_config.description)\n            processed_text = processed_text.replace(\"{{ModelId}}\", agent_config.id)\n            \n            # \u914d\u7f6e\u53c2\u6570\n            processed_text = processed_text.replace(\"{{Temperature}}\", str(agent_config.temperature))\n            processed_text = processed_text.replace(\"{{MaxTokens}}\", str(agent_config.max_output_tokens))\n            processed_text = processed_text.replace(\"{{ModelProvider}}\", agent_config.model_provider)\n            '''\n            \u53ef\u4ee5\u66ff\u6362\u7684\u5360\u4f4d\u7b26\uff1a\n               {{AgentName}} \/ {{MaidName}} \u2192 \u52a9\u624b\u7684\u4e2d\u6587\u540d\n               {{BaseName}} \u2192 \u52a9\u624b\u7684\u82f1\u6587\u540d\n               {{Description}} \u2192 \u52a9\u624b\u7684\u63cf\u8ff0\n               {{ModelId}} \u2192 \u6a21\u578bID\n               {{Temperature}} \u2192 \u6e29\u5ea6\u53c2\u6570\n               {{MaxTokens}} \u2192 \u6700\u5927\u8f93\u51fa\u5b57\u6570\n               {{ModelProvider}} \u2192 \u6a21\u578b\u63d0\u4f9b\u5546\n            '''\n        \n        # \u73af\u5883\u53d8\u91cf\u5360\u4f4d\u7b26\u66ff\u6362\n        import os\n        import re\n        \n        # \u5339\u914d {{ENV_VAR_NAME}} \u683c\u5f0f\u7684\u73af\u5883\u53d8\u91cf,\u73af\u5883\u53d8\u91cf\u662f\u7535\u8111\u7cfb\u7edf\u91cc\u7684\u8bbe\u7f6e\uff0c\u6bd4\u5982API_KEY=\"sk-abc123\",{{API_KEY}}\u4f1a\u88ab\u66ff\u6362\u6210\"sk-abc123\"\n        env_pattern = r'\\{\\{(&#91;A-Z_]&#91;A-Z0-9_]*)\\}\\}'  #r'\\{\\{(&#91;A-Z_]&#91;A-Z0-9_]*)\\}\\}' \u5339\u914d {{\u5927\u5199\u5b57\u6bcd_\u6570\u5b57}},\u6bd4\u5982\uff1a{{API_KEY}}\u3001{{DATABASE_URL}}\n        for match in re.finditer(env_pattern, processed_text):\n            env_var_name = match.group(1)\n            env_value = os.getenv(env_var_name, '')\n            processed_text = processed_text.replace(f\"{{{{{env_var_name}}}}}\", env_value)\n        \n        # \u65f6\u95f4\u76f8\u5173\u5360\u4f4d\u7b26\n        from datetime import datetime\n        now = datetime.now()\n        processed_text = processed_text.replace(\"{{CurrentTime}}\", now.strftime(\"%H:%M:%S\"))\n        processed_text = processed_text.replace(\"{{CurrentDate}}\", now.strftime(\"%Y-%m-%d\"))\n        processed_text = processed_text.replace(\"{{CurrentDateTime}}\", now.strftime(\"%Y-%m-%d %H:%M:%S\"))\n        '''\n        \u65f6\u95f4\u683c\u5f0f\uff1a\n          {{CurrentTime}} \u2192 \"14:30:00\"\uff08\u5c0f\u65f6:\u5206\u949f:\u79d2\uff09\n          {{CurrentDate}} \u2192 \"2024-01-01\"\uff08\u5e74-\u6708-\u65e5\uff09\n          {{CurrentDateTime}} \u2192 \"2024-01-01 14:30:00\"\uff08\u5b8c\u6574\u65f6\u95f4\uff09\n        '''\n        \n        return processed_text\n    \n    def _build_system_message(self, agent_config: AgentConfig) -> Dict&#91;str, str]:\n        \"\"\"\u6784\u5efa\u7cfb\u7edf\u6d88\u606f\uff0c\u5305\u542bAgent\u7684\u8eab\u4efd\u3001\u884c\u4e3a\u3001\u98ce\u683c\u7b49\"\"\"\n        # \u5904\u7406\u7cfb\u7edf\u63d0\u793a\u8bcd\u4e2d\u7684\u5360\u4f4d\u7b26\n        processed_system_prompt = self._replace_placeholders(agent_config.system_prompt, agent_config)\n        \n        return {\n            \"role\": \"system\",\n            \"content\": processed_system_prompt\n        }\n        '''\n        \u8fd9\u662f\u4ec0\u4e48\uff1f\u7cfb\u7edf\u6d88\u606f\u544a\u8bc9AI\u52a9\u624b\"\u4f60\u662f\u8c01\"\uff0c\u6bd4\u5982\uff1a\n        {\n              \"role\": \"system\",\n              \"content\": \"\u4f60\u662f\u4e00\u4e2a\u5e2e\u52a9\u4eba\u7684AI\u52a9\u624b\uff0c\u540d\u5b57\u53eb\u5c0f\u52a9\u624b\u3002\"\n        }\n        '''\n    \n    def _build_user_message(self, prompt: str, agent_config: AgentConfig) -> Dict&#91;str, str]:\n        \"\"\"\u6784\u5efa\u7528\u6237\u6d88\u606f\uff0c\u5904\u7406\u7528\u6237\u8f93\u5165\"\"\"\n        # \u5904\u7406\u7528\u6237\u63d0\u793a\u8bcd\u4e2d\u7684\u5360\u4f4d\u7b26\n        processed_prompt = self._replace_placeholders(prompt, agent_config)\n        \n        return {\n            \"role\": \"user\",\n            \"content\": processed_prompt\n        }\n        '''\n        \u7528\u6237\u6d88\u606f\u7684\u4f8b\u5b50\uff1a\n        {\n            \"role\": \"user\",\n            \"content\": \"\u4f60\u597d\uff0c\u73b0\u5728\u65f6\u95f4\u662f{{CurrentTime}}\"\n        }\n        '''\n    \n    def _build_assistant_message(self, content: str) -> Dict&#91;str, str]:\n        \"\"\"\u6784\u5efa\u52a9\u624b\u6d88\u606f\"\"\"\n        return {\n            \"role\": \"assistant\",\n            \"content\": content\n        }\n       '''\n       \u52a9\u624b\u6d88\u606f\u7684\u4f8b\u5b50\uff1a\n       {\n            \"role\": \"assistant\",\n            \"content\": \"\u4f60\u597d\uff01\u73b0\u5728\u662f14:30:00\u3002\"\n       }\n       '''\n    \n    def _validate_messages(self, messages: List&#91;Dict&#91;str, str]]) -> bool:\n        \"\"\"\u9a8c\u8bc1\u6d88\u606f\u5e8f\u5217\u7684\u6709\u6548\u6027\"\"\"\n        if not messages:  #\u68c0\u67e5\u6d88\u606f\u662f\u5426\u4e3a\u7a7a\n            return False\n        \n        # \u68c0\u67e5\u6d88\u606f\u683c\u5f0f\n        for msg in messages:\n            if not isinstance(msg, dict):\n                return False\n            if 'role' not in msg or 'content' not in msg:\n                return False\n            if msg&#91;'role'] not in &#91;'system', 'user', 'assistant']:\n                return False\n            if not isinstance(msg&#91;'content'], str):\n                return False\n        \n        # \u68c0\u67e5\u7cfb\u7edf\u6d88\u606f\u662f\u5426\u5728\u5f00\u5934\n        if messages&#91;0]&#91;'role'] != 'system':\n            return False\n        \n        return True\n       '''\n       \u4e3a\u4ec0\u4e48\u9700\u8981\u7cfb\u7edf\u6d88\u606f\u5728\u7b2c\u4e00\uff1f\n          \u8fd9\u662fOpenAI API\u7684\u8981\u6c42\n          \u7cfb\u7edf\u6d88\u606f\u6700\u5148\u544a\u8bc9AI\"\u4f60\u7684\u89d2\u8272\u662f\u4ec0\u4e48\"\n       '''\n \n  #call_agent \u65b9\u6cd5,\u8fd9\u662f\u6574\u4e2a\u6587\u4ef6\u6700\u91cd\u8981\u7684\u65b9\u6cd5,\u7528\u6765\u8c03\u7528AI\u52a9\u624b\u3002\n    async def call_agent(self, agent_name: str, prompt: str, session_id: str = None) -> Dict&#91;str, Any]:\n        \"\"\"\n        \u8c03\u7528\u6307\u5b9a\u7684Agent\n        \n        Args:\n            agent_name: Agent\u540d\u79f0\n            prompt: \u7528\u6237\u63d0\u793a\u8bcd\n            session_id: \u4f1a\u8bddID\n            \n        Returns:\n            Dict&#91;str, Any]: \u8c03\u7528\u7ed3\u679c\n        \"\"\"\n        # \u68c0\u67e5Agent\u662f\u5426\u5b58\u5728\n        if agent_name not in self.agents:\n            available_agents = list(self.agents.keys())\n            error_msg = f\"\u8bf7\u6c42\u7684Agent '{agent_name}' \u672a\u627e\u5230\u6216\u672a\u6b63\u786e\u914d\u7f6e\u3002\"  #\u5982\u679c\u8981\u627e\u7684\u52a9\u624b\u4e0d\u5b58\u5728 \u2192 \u8fd4\u56de\u9519\u8bef\u4fe1\u606f\n            if available_agents:  #\u9519\u8bef\u4fe1\u606f\u91cc\u4f1a\u544a\u8bc9\u4f60\u54ea\u4e9b\u52a9\u624b\u53ef\u7528\n                error_msg += f\" \u5f53\u524d\u5df2\u52a0\u8f7d\u7684Agent\u6709: {', '.join(available_agents)}\u3002\"\n            else:\n                error_msg += \" \u5f53\u524d\u6ca1\u6709\u52a0\u8f7d\u4efb\u4f55Agent\u3002\u8bf7\u68c0\u67e5\u914d\u7f6e\u6587\u4ef6\u3002\"\n            error_msg += \" \u8bf7\u786e\u8ba4\u60a8\u8bf7\u6c42\u7684Agent\u540d\u79f0\u662f\u5426\u51c6\u786e\u3002\"\n            \n            logger.error(f\"Agent\u8c03\u7528\u5931\u8d25: {error_msg}\")\n            return {\"status\": \"error\", \"error\": error_msg}\n        \n        agent_config = self.agents&#91;agent_name]\n        \n        # \u751f\u6210\u4f1a\u8bddID\n        if not session_id:\n            session_id = f\"agent_{agent_config.base_name}_default_user_session\"\n        \n        try:  #\u6784\u5efa\u5b8c\u6574\u7684\u6d88\u606f\u5e8f\u5217\n            # \u83b7\u53d6\u4f1a\u8bdd\u5386\u53f2\n            history = self.get_agent_session_history(agent_name, session_id)\n            \n            # \u6784\u5efa\u5b8c\u6574\u7684\u6d88\u606f\u5e8f\u5217\n            messages = &#91;]\n            \n            # 1. \u7cfb\u7edf\u6d88\u606f\uff1a\u8bbe\u5b9aAgent\u7684\u8eab\u4efd\u3001\u884c\u4e3a\u3001\u98ce\u683c\u7b49\n            system_message = self._build_system_message(agent_config)\n            messages.append(system_message)\n            \n            # 2. \u5386\u53f2\u6d88\u606f\uff1a\u4fdd\u7559\u591a\u8f6e\u5bf9\u8bdd\u7684\u4e0a\u4e0b\u6587\n            messages.extend(history)\n            \n            # 3. \u5f53\u524d\u7528\u6237\u8f93\u5165\uff1a\u672c\u6b21\u8981\u5904\u7406\u7684\u4efb\u52a1\u5185\u5bb9\n            user_message = self._build_user_message(prompt, agent_config)\n            messages.append(user_message)\n            '''\n            \u6d88\u606f\u5e8f\u5217\u7684\u7ec4\u6210\uff1a\n            &#91;\n                {\u7cfb\u7edf\u6d88\u606f: \"\u4f60\u662f\u52a9\u624bA\"},      # \u7b2c\u4e00\u6761\u5fc5\u987b\u662f\u7cfb\u7edf\u6d88\u606f\n                {\u7528\u6237: \"\u4f60\u597d\"},             # \u5386\u53f2\u5bf9\u8bdd\u7684\u7b2c\u4e00\u8f6e\n                {\u52a9\u624b: \"\u4f60\u597d\uff01\"},           # \u5386\u53f2\u5bf9\u8bdd\u7684\u7b2c\u4e00\u8f6e\n                {\u7528\u6237: \"\u4eca\u5929\u5929\u6c14\u600e\u4e48\u6837\"},    # \u5386\u53f2\u5bf9\u8bdd\u7684\u7b2c\u4e8c\u8f6e\n                {\u52a9\u624b: \"\u4eca\u5929\u6674\u5929\"},         # \u5386\u53f2\u5bf9\u8bdd\u7684\u7b2c\u4e8c\u8f6e\n                {\u7528\u6237: \"\u73b0\u5728\u662f\u4ec0\u4e48\u65f6\u95f4\"}     # \u5f53\u524d\u7684\u65b0\u95ee\u9898\n            ]\n            '''\n            \n            # \u9a8c\u8bc1\u6d88\u606f\u5e8f\u5217\n            if not self._validate_messages(messages):\n                return {\"status\": \"error\", \"error\": \"\u6d88\u606f\u5e8f\u5217\u683c\u5f0f\u65e0\u6548\"}\n            \n            # \u8bb0\u5f55\u8c03\u8bd5\u4fe1\u606f\n            if self.debug_mode:\n                logger.debug(f\"Agent\u8c03\u7528\u6d88\u606f\u5e8f\u5217:\")\n                for i, msg in enumerate(messages):\n                    logger.debug(f\"  &#91;{i}] {msg&#91;'role']}: {msg&#91;'content']&#91;:100]}...\")\n            \n            # \u8c03\u7528LLM API\n            response = await self._call_llm_api(agent_config, messages)\n            \n            if response.get(\"status\") == \"success\":\n                assistant_response = response.get(\"result\", \"\")\n                \n                # \u66f4\u65b0\u4f1a\u8bdd\u5386\u53f2\n                self.update_agent_session_history(\n                    agent_name, user_message&#91;'content'], assistant_response, session_id\n                )\n                \n                return {\"status\": \"success\", \"result\": assistant_response}\n            else:\n                return response\n            '''\n            \u5904\u7406\u6d41\u7a0b\uff1a\n               \u8c03\u7528AI\u6a21\u578bAPI\n               \u5982\u679c\u6210\u529f \u2192 \u4fdd\u5b58\u5bf9\u8bdd\u5386\u53f2 \u2192 \u8fd4\u56de\u7ed3\u679c\n               \u5982\u679c\u5931\u8d25 \u2192 \u76f4\u63a5\u8fd4\u56de\u9519\u8bef\n            '''\n                \n        except Exception as e:\n            error_msg = f\"\u8c03\u7528Agent '{agent_name}' \u65f6\u53d1\u751f\u9519\u8bef: {str(e)}\"\n            logger.error(f\"Agent\u8c03\u7528\u5f02\u5e38: {error_msg}\")\n            return {\"status\": \"error\", \"error\": error_msg}\n    \n    # \u8c03\u7528LLM API\u7684\u6838\u5fc3\u65b9\u6cd5\n    async def _call_llm_api(self, agent_config: AgentConfig, messages: List&#91;Dict&#91;str, str]]) -> Dict&#91;str, Any]:\n        \"\"\"\u8c03\u7528LLM API\uff0c\u4f7f\u7528Agent\u914d\u7f6e\u4e2d\u7684\u53c2\u6570\"\"\"\n        try:\n            # \u4f7f\u7528\u65b0\u7248\u672c\u7684OpenAI API\n            from openai import AsyncOpenAI\n            \n            # \u8bb0\u5f55\u8c03\u8bd5\u4fe1\u606f\n            if self.debug_mode:\n                logger.debug(f\"\u8c03\u7528LLM API - Agent: {agent_config.name}\")\n                logger.debug(f\"  \u6a21\u578b: {agent_config.id}\")\n                logger.debug(f\"  \u63d0\u4f9b\u5546: {agent_config.model_provider}\")\n                logger.debug(f\"  API URL: {agent_config.api_base_url}\")\n                logger.debug(f\"  \u6e29\u5ea6: {agent_config.temperature}\")\n                logger.debug(f\"  \u6700\u5927Token: {agent_config.max_output_tokens}\")\n                logger.debug(f\"  \u6d88\u606f\u6570\u91cf: {len(messages)}\")\n            \n            # \u9a8c\u8bc1\u5fc5\u8981\u7684\u914d\u7f6e\u53c2\u6570\n            if not agent_config.id:\n                return {\"status\": \"error\", \"error\": \"Agent\u914d\u7f6e\u7f3a\u5c11\u6a21\u578bID\"}\n            \n            if not agent_config.api_key:\n                return {\"status\": \"error\", \"error\": \"Agent\u914d\u7f6e\u7f3a\u5c11API\u5bc6\u94a5\"}\n            \n            # \u521b\u5efa\u5ba2\u6237\u7aef\uff0c\u4f7f\u7528Agent\u914d\u7f6e\u4e2d\u7684\u53c2\u6570\n            client = AsyncOpenAI(\n                api_key=agent_config.api_key,   #api_key: \u8bbf\u95eeAPI\u7684\u5bc6\u7801\n                #base_url: API\u7684\u7f51\u5740,\u5982\u679c\u6ca1\u914d\u7f6e\uff0c\u9ed8\u8ba4\u7528DeepSeek\u7684API\n                base_url=agent_config.api_base_url or \"https:\/\/api.deepseek.com\/v1\"\n            )\n            \n            # \u51c6\u5907API\u8c03\u7528\u53c2\u6570\n            api_params = {\n                \"model\": agent_config.id,  #model: \u4f7f\u7528\u54ea\u4e2aAI\u6a21\u578b\n                \"messages\": messages,     #messages: \u5bf9\u8bdd\u6d88\u606f\u5217\u8868\n                \"max_tokens\": agent_config.max_output_tokens,  #max_tokens: \u6700\u591a\u751f\u6210\u591a\u5c11\u5b57\n                \"temperature\": agent_config.temperature,   #temperature: \u521b\u9020\u529b\u53c2\u6570\uff080.7\u662f\u4e2d\u7b49\u521b\u9020\u529b\uff09\n                \"stream\": False   #stream: False: \u4e0d\u8981\u6d41\u5f0f\u4f20\u8f93\uff08\u4e00\u6b21\u6027\u8fd4\u56de\u7ed3\u679c\uff09\n            }\n            \n            # \u8bb0\u5f55API\u8c03\u7528\u53c2\u6570\uff08\u8c03\u8bd5\u6a21\u5f0f\uff09\n            if self.debug_mode:\n                logger.debug(f\"API\u8c03\u7528\u53c2\u6570: {api_params}\")\n            \n            # \u8c03\u7528API\n            response = await client.chat.completions.create(**api_params) \n            \n            # \u63d0\u53d6\u54cd\u5e94\u5185\u5bb9\n            assistant_content = response.choices&#91;0].message.content\n            #response.choices&#91;0].message.content \u5c31\u662fAI\u7684\u56de\u7b54\n            \n            # \u8bb0\u5f55\u54cd\u5e94\u4fe1\u606f\uff08\u8c03\u8bd5\u6a21\u5f0f\uff09\n            if self.debug_mode:\n                usage = response.usage\n                logger.debug(f\"API\u54cd\u5e94\u6210\u529f:\")\n                logger.debug(f\"  \u4f7f\u7528Token: {usage.prompt_tokens} (\u8f93\u5165) + {usage.completion_tokens} (\u8f93\u51fa) = {usage.total_tokens} (\u603b\u8ba1)\")\n                logger.debug(f\"  \u54cd\u5e94\u957f\u5ea6: {len(assistant_content)} \u5b57\u7b26\")\n            \n            return {\"status\": \"success\", \"result\": assistant_content}\n            \n        except Exception as e:\n            error_msg = f\"LLM API\u8c03\u7528\u5931\u8d25: {str(e)}\"\n            logger.error(f\"Agent '{agent_config.name}' API\u8c03\u7528\u5931\u8d25: {error_msg}\")\n            \n            # \u8bb0\u5f55\u8be6\u7ec6\u7684\u9519\u8bef\u4fe1\u606f\uff08\u8c03\u8bd5\u6a21\u5f0f\uff09\n            if self.debug_mode:\n                import traceback\n                logger.debug(f\"\u8be6\u7ec6\u9519\u8bef\u4fe1\u606f:\")\n                logger.debug(traceback.format_exc())\n            \n            return {\"status\": \"error\", \"error\": error_msg}\n \n#\u5176\u4ed6\u529f\u80fd\u65b9\u6cd5   \n    def get_available_agents(self) -> List&#91;Dict&#91;str, Any]]:\n        \"\"\"\u83b7\u53d6\u6240\u6709\u53ef\u7528\u7684Agent\u5217\u8868\"\"\"\n        return &#91;\n            {\n                \"name\": agent_config.name,\n                \"base_name\": agent_config.base_name,\n                \"description\": agent_config.description,\n                \"model_id\": agent_config.id,\n                \"temperature\": agent_config.temperature,\n                \"max_output_tokens\": agent_config.max_output_tokens\n            }\n            for agent_config in self.agents.values()\n        ]\n        '''\n        \u8fd4\u56de\u683c\u5f0f\uff1a\n        &#91;\n            {\n                \"name\": \"\u52a9\u624bA\",\n                \"base_name\": \"assistant_a\",\n                \"description\": \"\u8fd9\u662f\u4e00\u4e2a\u52a9\u624b\",\n                \"model_id\": \"gpt-4\",\n                \"temperature\": 0.7,\n                \"max_output_tokens\": 40000\n            }\n        ]\n        '''\n    \n    def get_agent_info(self, agent_name: str) -> Optional&#91;Dict&#91;str, Any]]:\n        \"\"\"\u83b7\u53d6\u6307\u5b9aAgent\u7684\u8be6\u7ec6\u4fe1\u606f\"\"\"\n        if agent_name not in self.agents:\n            return None\n        \n        agent_config = self.agents&#91;agent_name]\n        return {\n            \"name\": agent_config.name,\n            \"base_name\": agent_config.base_name,\n            \"description\": agent_config.description,\n            \"model_id\": agent_config.id,\n            \"temperature\": agent_config.temperature,\n            \"max_output_tokens\": agent_config.max_output_tokens,\n            \"system_prompt\": agent_config.system_prompt,\n            \"model_provider\": agent_config.model_provider\n        }\n    \n    def reload_configs(self):\n        \"\"\"\u91cd\u65b0\u52a0\u8f7dAgent\u914d\u7f6e,\u4fee\u6539\u914d\u7f6e\u6587\u4ef6\u540e\uff0c\u4e0d\u7528\u91cd\u542f\u7a0b\u5e8f\uff0c\u8c03\u7528\u8fd9\u4e2a\u65b9\u6cd5\u5c31\u80fd\u91cd\u65b0\u52a0\u8f7d\u3002\"\"\"\n        self.agents.clear()\n        self._load_agent_configs()\n        logger.info(\"Agent\u914d\u7f6e\u5df2\u91cd\u65b0\u52a0\u8f7d\")\n    \n    def _register_agent_from_manifest(self, agent_name: str, agent_config: Dict&#91;str, Any]):\n        \"\"\"\u4ecemanifest\u6ce8\u518cAgent\n        \n        Args:\n            agent_name: Agent\u540d\u79f0\n            agent_config: Agent\u914d\u7f6e\u5b57\u5178\n        \"\"\"\n        try:\n            # \u9a8c\u8bc1\u914d\u7f6e\n            if not self._validate_agent_config(agent_config):\n                logger.warning(f\"Agent\u914d\u7f6e\u9a8c\u8bc1\u5931\u8d25: {agent_name}\")\n                return False\n            \n            # \u521b\u5efaAgentConfig\u5bf9\u8c61\n            agent_config_obj = AgentConfig(\n                id=agent_config.get('model_id', ''),\n                name=agent_config.get('name', agent_name),\n                base_name=agent_config.get('base_name', agent_name),\n                system_prompt=agent_config.get('system_prompt', f'You are a helpful AI assistant named {agent_config.get(\"name\", agent_name)}.'),\n                max_output_tokens=agent_config.get('max_output_tokens', 8192),\n                temperature=agent_config.get('temperature', 0.7),\n                description=agent_config.get('description', f'Assistant {agent_config.get(\"name\", agent_name)}.'),\n                model_provider=agent_config.get('model_provider', 'openai'),\n                api_base_url=agent_config.get('api_base_url', ''),\n                api_key=agent_config.get('api_key', '')\n            )\n            \n            # \u6ce8\u518c\u5230agents\u5b57\u5178\n            self.agents&#91;agent_name] = agent_config_obj\n            logger.info(f\"\u5df2\u4ecemanifest\u6ce8\u518cAgent: {agent_name} ({agent_config_obj.name})\")\n            return True\n            \n        except Exception as e:\n            logger.error(f\"\u4ecemanifest\u6ce8\u518cAgent\u5931\u8d25 {agent_name}: {e}\")\n            return False\n    \n    async def call_agent_by_action(self, agent_name: str, action_args: Dict&#91;str, Any]) -> str:\n        \"\"\"\u6839\u636e\u52a8\u4f5c\u8c03\u7528Agent,\u4e0d\u76f4\u63a5\u7ed9\u63d0\u793a\u8bcd\uff0c\u800c\u662f\u7ed9\"\u52a8\u4f5c\"\uff0c\u6bd4\u5982\uff1a\n        \n        Args:\n            agent_name: Agent\u540d\u79f0\n            action_args: \u52a8\u4f5c\u53c2\u6570\uff0c\u5305\u542baction\u548c\u5177\u4f53\u53c2\u6570\n            \n        Returns:\n            str: Agent\u6267\u884c\u7ed3\u679c\n        \"\"\"\n        try:\n            # \u68c0\u67e5Agent\u662f\u5426\u5b58\u5728\n            if agent_name not in self.agents:\n                return f\"Agent '{agent_name}' \u672a\u627e\u5230\u6216\u672a\u6b63\u786e\u914d\u7f6e\"\n            \n            agent_config = self.agents&#91;agent_name]\n            action = action_args.get('action', '')\n            \n            # \u6784\u5efa\u7528\u6237\u63d0\u793a\u8bcd\n            user_prompt = self._build_action_prompt(action, action_args)\n            \n            # \u8c03\u7528Agent\n            result = await self.call_agent(agent_name, user_prompt)\n            \n            if result.get(\"status\") == \"success\":\n                return result.get(\"result\", \"\")\n            else:\n                return f\"Agent\u8c03\u7528\u5931\u8d25: {result.get('error', '\u672a\u77e5\u9519\u8bef')}\"\n                \n        except Exception as e:\n            logger.error(f\"Agent\u52a8\u4f5c\u8c03\u7528\u5931\u8d25 {agent_name}: {e}\")\n            return f\"Agent\u52a8\u4f5c\u8c03\u7528\u5f02\u5e38: {str(e)}\"\n    \n    def _build_action_prompt(self, action: str, action_args: Dict&#91;str, Any]) -> str:\n        \"\"\"\u6784\u5efa\u52a8\u4f5c\u63d0\u793a\u8bcd\n        \n        Args:\n            action: \u52a8\u4f5c\u540d\u79f0\n            action_args: \u52a8\u4f5c\u53c2\u6570\n            \n        Returns:\n            str: \u6784\u5efa\u7684\u63d0\u793a\u8bcd\n        \"\"\"\n        # \u79fb\u9664\u4e0d\u9700\u8981\u7684\u53c2\u6570\n        clean_args = {k: v for k, v in action_args.items() \n                     if k not in &#91;'service_name', 'action']}\n        \n        # \u6784\u5efa\u63d0\u793a\u8bcd\n        if clean_args:\n            args_str = \", \".join(&#91;f\"{k}: {v}\" for k, v in clean_args.items()])\n            return f\"\u8bf7\u6267\u884c\u52a8\u4f5c '{action}'\uff0c\u53c2\u6570: {args_str}\"\n        else:\n            return f\"\u8bf7\u6267\u884c\u52a8\u4f5c '{action}'\"\n    \n    # \u5220\u9664\u91cd\u590d\u7684\u4efb\u52a1\u89c4\u5212\u5668\u521d\u59cb\u5316\u65b9\u6cd5\n    # \u73b0\u5728\u901a\u8fc7agentserver\u7684task_scheduler\u5904\u7406\u4efb\u52a1\u89c4\u5212\n    \n    async def process_intelligent_task(self, query: str, context: Optional&#91;Dict&#91;str, Any]] = None) -> Dict&#91;str, Any]:\n        \"\"\"\n        \u667a\u80fd\u4efb\u52a1\u5904\u7406 - \u6838\u5fc3\u65b9\u6cd5\uff0c\u901a\u8fc7agentserver\u7684task_scheduler\u5904\u7406\n        \u5904\u7406\u66f4\u590d\u6742\u7684\u4efb\u52a1\uff0c\u53ef\u4ee5\u5206\u89e3\u6210\u591a\u4e2a\u6b65\u9aa4\u3002\n        Args:\n            query: \u7528\u6237\u67e5\u8be2\n            context: \u4e0a\u4e0b\u6587\u4fe1\u606f\n            \n        Returns:\n            Dict&#91;str, Any]: \u5904\u7406\u7ed3\u679c\n        \"\"\"\n        try:\n            # \u901a\u8fc7agentserver\u7684task_scheduler\u5904\u7406\u667a\u80fd\u4efb\u52a1\n            from agentserver.task_scheduler import get_task_scheduler\n            task_scheduler = get_task_scheduler()\n            \n            # \u521b\u5efa\u4efb\u52a1\u5e76\u8c03\u5ea6\n            import uuid  #\u7528\u6765\u6807\u8bc6\u8fd9\u4e2a\u4efb\u52a1\n            task_id = str(uuid.uuid4())\n            \n            # \u6ce8\u518c\u4efb\u52a1\u5230\u8c03\u5ea6\u5668\n            task_scheduler.task_registry&#91;task_id] = {\n                \"id\": task_id,\n                \"type\": \"processor\",\n                \"status\": \"queued\",\n                \"params\": {\"query\": query},\n                \"context\": context\n            }\n            \n            # \u8c03\u5ea6\u5e76\u884c\u6267\u884c,\u628a\u4efb\u52a1\u4ea4\u7ed9\"\u4efb\u52a1\u8c03\u5ea6\u5668\"\u53bb\u6267\u884c\uff0c\u53ef\u4ee5\u5e76\u884c\u5904\u7406\u591a\u4e2a\u4efb\u52a1\u3002\n            tasks = &#91;{\n                \"type\": \"processor\",\n                \"params\": {\"query\": query},\n                \"session_id\": context.get(\"session_id\") if context else None\n            }]\n            \n            results = await task_scheduler.schedule_parallel_execution(tasks)\n            \n            if results and len(results) > 0:\n                result = results&#91;0]\n                return {\n                    \"status\": \"success\" if result.get(\"success\") else \"error\",\n                    \"result\": result.get(\"result\"),\n                    \"error\": result.get(\"error\"),\n                    \"task_id\": task_id\n                }\n            else:\n                return {\n                    \"status\": \"error\",\n                    \"error\": \"\u4efb\u52a1\u8c03\u5ea6\u5931\u8d25\"\n                }\n            \n        except Exception as e:\n            logger.error(f\"\u667a\u80fd\u4efb\u52a1\u5904\u7406\u5931\u8d25: {e}\")\n            # \u964d\u7ea7\u5230\u4f20\u7edfAgent\u8c03\u7528,\u5982\u679c\u590d\u6742\u4efb\u52a1\u5904\u7406\u5931\u8d25,\u5c31\u6539\u7528\u7b80\u5355\u7684\u8c03\u7528\u65b9\u5f0f\n            return await self.call_agent(\"default\", query)\n\n# \u5168\u5c40Agent\u7ba1\u7406\u5668\u5b9e\u4f8b\n_AGENT_MANAGER = None\n'''\n\u8fd9\u662f\u4ec0\u4e48\uff1f\n\u521b\u5efa\u4e00\u4e2a\u5168\u5c40\u53d8\u91cf_AGENT_MANAGER\n\u521d\u59cb\u503c\u662fNone\uff08\u7a7a\uff09\n\u53d8\u91cf\u540d\u524d\u9762\u7684\u4e0b\u5212\u7ebf_\u662f\u7ea6\u5b9a\uff0c\u8868\u793a\"\u8fd9\u662f\u5185\u90e8\u53d8\u91cf\"\n'''\n\ndef get_agent_manager() -> AgentManager:\n    \"\"\"\u83b7\u53d6\u5168\u5c40Agent\u7ba1\u7406\u5668\u5b9e\u4f8b\"\"\"\n    global _AGENT_MANAGER\n    if _AGENT_MANAGER is None:\n        _AGENT_MANAGER = AgentManager()\n    return _AGENT_MANAGER\n'''\n\u8fd9\u662f\u4e00\u4e2a\"\u5355\u4f8b\u6a21\u5f0f\"\u7684\u8bbe\u8ba1\uff1a\n\u903b\u8f91\u6d41\u7a0b\uff1a\n\u7b2c\u4e00\u6b21\u8c03\u7528 get_agent_manager():\n    _AGENT_MANAGER \u662f None \u2192 \u521b\u5efa\u65b0\u7684 AgentManager \u2192 \u8fd4\u56de\u5b83\n\n\u7b2c\u4e8c\u6b21\u8c03\u7528 get_agent_manager():\n    _AGENT_MANAGER \u5df2\u7ecf\u6709\u503c\u4e86 \u2192 \u76f4\u63a5\u8fd4\u56de\u8fd9\u4e2a\u503c\n\n\u4e3a\u4ec0\u4e48\u8fd9\u6837\u8bbe\u8ba1\uff1f\n\u6574\u4e2a\u7a0b\u5e8f\u53ea\u9700\u8981\u4e00\u4e2aAgentManager\u5b9e\u4f8b\n\u907f\u514d\u4e86\u91cd\u590d\u521b\u5efa\uff0c\u8282\u7701\u5185\u5b58\n\u6240\u6709\u5730\u65b9\u90fd\u4f7f\u7528\u540c\u4e00\u4e2a\u5b9e\u4f8b\n'''\n\n# \u4fbf\u6377\u51fd\u6570\nasync def call_agent(agent_name: str, prompt: str, session_id: str = None) -> Dict&#91;str, Any]:\n    \"\"\"\u4fbf\u6377\u7684Agent\u8c03\u7528\u51fd\u6570,\u8fd9\u662f\u4e00\u4e2a\"\u5305\u88c5\u51fd\u6570\"\uff1a\n    \u5b83\u8ba9\u8c03\u7528AI\u52a9\u624b\u53d8\u5f97\u975e\u5e38\u7b80\u5355\uff1a\"\"\"\n    manager = get_agent_manager()\n    return await manager.call_agent(agent_name, prompt, session_id)\n\ndef list_agents() -> List&#91;Dict&#91;str, Any]]:\n    \"\"\"\u4fbf\u6377\u7684Agent\u5217\u8868\u83b7\u53d6\u51fd\u6570\"\"\"\n    manager = get_agent_manager()  #\u8fd4\u56de\u6240\u6709\u53ef\u7528\u52a9\u624b\u7684\u5217\u8868\uff0c\u6bd4\u5982\uff1a\n    return manager.get_available_agents()\n'''\nagents = list_agents()\n# agents \u4f1a\u662f\uff1a\n# &#91;\n#     {\"name\": \"\u52a9\u624bA\", \"description\": \"...\", ...},\n#     {\"name\": \"\u52a9\u624bB\", \"description\": \"...\", ...}\n# ]\n'''\n\ndef get_agent_info(agent_name: str) -> Optional&#91;Dict&#91;str, Any]]:\n    \"\"\"\u4fbf\u6377\u7684Agent\u4fe1\u606f\u83b7\u53d6\u51fd\u6570, \u83b7\u53d6\u52a9\u624b\u8be6\u7ec6\u4fe1\u606f\u7684\u51fd\u6570\"\"\"\n    manager = get_agent_manager()\n    return manager.get_agent_info(agent_name)\n'''\n\u83b7\u53d6\u67d0\u4e2a\u52a9\u624b\u7684\u8be6\u7ec6\u4fe1\u606f\uff0c\u6bd4\u5982\uff1a\ninfo = get_agent_info(\"\u52a9\u624bA\")\n# info \u4f1a\u662f\uff1a\n# {\n#     \"name\": \"\u52a9\u624bA\",\n#     \"base_name\": \"assistant_a\",\n#     \"description\": \"\u8fd9\u662f\u4e00\u4e2a\u52a9\u624b\",\n#     \"system_prompt\": \"\u4f60\u662f\u4e00\u4e2a\u52a9\u624b\",\n#     ...\n# }\n\u6ce8\u610f\uff1a\u5982\u679c\u52a9\u624b\u4e0d\u5b58\u5728\uff0c\u8fd4\u56deNone,Optional&#91;Dict&#91;str, Any]]\u8868\u793a\uff1a\u8981\u4e48\u8fd4\u56de\u5b57\u5178\uff0c\u8981\u4e48\u8fd4\u56deNone\n'''\n\n# \u667a\u80fd\u4efb\u52a1\u5904\u7406\u51fd\u6570 - \u901a\u8fc7agentserver\u5904\u7406\nasync def process_intelligent_task(query: str, context: Optional&#91;Dict&#91;str, Any]] = None) -> Dict&#91;str, Any]:\n    \"\"\"\u4fbf\u6377\u7684\u667a\u80fd\u4efb\u52a1\u5904\u7406\u51fd\u6570 - \u901a\u8fc7agentserver\u7684task_scheduler\u5904\u7406,\u8ba9\u590d\u6742\u7684\u4efb\u52a1\u5904\u7406\u53d8\u5f97\u7b80\u5355\u3002\"\"\"\n    manager = get_agent_manager()\n    return await manager.process_intelligent_task(query, context)\n\n# \u4efb\u52a1\u7ba1\u7406\u51fd\u6570 - \u901a\u8fc7agentserver\u7684task_scheduler\u5904\u7406\nasync def get_task_status(task_id: str) -> Optional&#91;Dict&#91;str, Any]]:\n    \"\"\"\u4fbf\u6377\u7684\u4efb\u52a1\u72b6\u6001\u83b7\u53d6\u51fd\u6570 - \u901a\u8fc7agentserver\u5904\u7406\"\"\"\n    try:\n        from agentserver.task_scheduler import get_task_scheduler\n        task_scheduler = get_task_scheduler()\n        return await task_scheduler.get_task_status(task_id)\n    except Exception as e:\n        logger.error(f\"\u83b7\u53d6\u4efb\u52a1\u72b6\u6001\u5931\u8d25: {e}\")\n        return None\n'''\n\u4f7f\u7528\u793a\u4f8b\uff1a\nstatus = await get_task_status(\"123e4567-e89b-12d3-a456-426614174000\")\n# status \u53ef\u80fd\u662f\uff1a\n# {\n#     \"id\": \"123e4567...\",\n#     \"status\": \"running\",  # \u8fd0\u884c\u4e2d\n#     \"progress\": 50,       # \u8fdb\u5ea650%\n#     \"result\": None\n# }\n'''\n\n#\u8fd9\u4e2a\u51fd\u6570\u5ffd\u7565\u4e86status_filter\u53c2\u6570\uff0c\u603b\u662f\u8fd4\u56de\u6240\u6709\u8fd0\u884c\u4e2d\u7684\u4efb\u52a1\u3002\nasync def get_task_list(status_filter: Optional&#91;str] = None) -> List&#91;Dict&#91;str, Any]]:\n    \"\"\"\u4fbf\u6377\u7684\u4efb\u52a1\u5217\u8868\u83b7\u53d6\u51fd\u6570 - \u901a\u8fc7agentserver\u5904\u7406\"\"\"\n    try:\n        from agentserver.task_scheduler import get_task_scheduler\n        task_scheduler = get_task_scheduler()\n        return await task_scheduler.get_running_tasks()\n    except Exception as e:\n        logger.error(f\"\u83b7\u53d6\u4efb\u52a1\u5217\u8868\u5931\u8d25: {e}\")\n        return &#91;]\n\nasync def get_execution_stats() -> Dict&#91;str, Any]:\n    \"\"\"\u4fbf\u6377\u7684\u6267\u884c\u7edf\u8ba1\u83b7\u53d6\u51fd\u6570 - \u901a\u8fc7agentserver\u5904\u7406\"\"\"\n    try:\n        from agentserver.task_scheduler import get_task_scheduler\n        task_scheduler = get_task_scheduler()\n        return {\n            \"total_tasks\": len(task_scheduler.task_registry),\n            \"running_tasks\": len(&#91;t for t in task_scheduler.task_registry.values() if t.get(\"status\") == \"running\"]),\n            \"queued_tasks\": len(&#91;t for t in task_scheduler.task_registry.values() if t.get(\"status\") == \"queued\"])\n        }\n    except Exception as e:\n        logger.error(f\"\u83b7\u53d6\u6267\u884c\u7edf\u8ba1\u5931\u8d25: {e}\")\n        return {}\n'''\n\u8fd9\u4e2a\u51fd\u6570\u8fd4\u56de\uff1a\n{\n    \"total_tasks\": 10,      \/\/ \u603b\u4efb\u52a1\u6570\n    \"running_tasks\": 3,     \/\/ \u8fd0\u884c\u4e2d\u7684\u4efb\u52a1\u6570\n    \"queued_tasks\": 7       \/\/ \u6392\u961f\u4e2d\u7684\u4efb\u52a1\u6570\n}\n\n\u7edf\u8ba1\u903b\u8f91\uff1a\n  total_tasks: \u4efb\u52a1\u6ce8\u518c\u8868\u4e2d\u6240\u6709\u4efb\u52a1\u7684\u6570\u91cf\n  running_tasks: \u72b6\u6001\u662f\"running\"\u7684\u4efb\u52a1\u6570\u91cf\n  queued_tasks: \u72b6\u6001\u662f\"queued\"\u7684\u4efb\u52a1\u6570\u91cf\n'''\n\nasync def cancel_task(task_id: str) -> bool:\n    \"\"\"\u4fbf\u6377\u7684\u4efb\u52a1\u53d6\u6d88\u51fd\u6570 - \u901a\u8fc7agentserver\u5904\u7406\"\"\"\n    try:\n        from agentserver.task_scheduler import get_task_scheduler\n        task_scheduler = get_task_scheduler()\n        if task_id in task_scheduler.task_registry:\n            task_scheduler.task_registry&#91;task_id]&#91;\"status\"] = \"cancelled\"\n            return True\n        return False\n    except Exception as e:\n        logger.error(f\"\u53d6\u6d88\u4efb\u52a1\u5931\u8d25: {e}\")\n        return False\n'''\n1. \u68c0\u67e5\u4efb\u52a1\u662f\u5426\u5b58\u5728\n2. \u5982\u679c\u5b58\u5728 \u2192 \u628a\u72b6\u6001\u6539\u6210\"cancelled\" \u2192 \u8fd4\u56deTrue\n3. \u5982\u679c\u4e0d\u5b58\u5728 \u2192 \u8fd4\u56deFalse'''\n\n\n# ==========\u4e3a\u4ec0\u4e48\u6ca1\u6709\u4e3b\u51fd\u6570\u5165\u53e3===========\n#1. \u8fd9\u662f\u6a21\u5757\uff08Module\uff09\uff0c\u4e0d\u662f\u811a\u672c\uff08Script\uff09\n#Python\u6587\u4ef6\u7684\u4e24\u79cd\u7c7b\u578b\uff1a\n'''\n\u7c7b\u578b  | \u7528\u9014             |  \u662f\u5426\u6709if __name__ == \"__main__\" | \u4f8b\u5b50\n\u6a21\u5757  | \u88ab\u5176\u4ed6\u6587\u4ef6\u5bfc\u5165\u4f7f\u7528  |  \u901a\u5e38\u6ca1\u6709                        | math.py, random.py, agent_manager.py\n\u811a\u672c  | \u76f4\u63a5\u8fd0\u884c\u6267\u884c\u4efb\u52a1   |  \u5fc5\u987b\u6709                          | main.py, run_server.py\n\u8fd9\u4e2aagent_manager.py\u662f\u6a21\u5757\uff1a\u5b83\u63d0\u4f9b\u529f\u80fd\uff0c\u4f46\u4e0d\u76f4\u63a5\u8fd0\u884c,\u5176\u4ed6\u6587\u4ef6\u5bfc\u5165\u5b83\uff0c\u4f7f\u7528\u5b83\u7684\u529f\u80fd\n'''\n#AgentManager \u6a21\u5757\u5b8c\u6574\u5c42\u7ea7\u7ed3\u6784\n'''\nagent_manager.py\n\u251c\u2500\u2500 \u6a21\u5757\u5934\u90e8\uff08\u6587\u4ef6\u914d\u7f6e\uff09\n\u2502   \u251c\u2500\u2500 #!\/usr\/bin\/env python3                     # \u6267\u884c\u73af\u5883\u58f0\u660e\n\u2502   \u251c\u2500\u2500 # -*- coding: utf-8 -*-                    # \u7f16\u7801\u58f0\u660e\n\u2502   \u2514\u2500\u2500 \"\"\"Agent\u7ba1\u7406\u5668 - \u72ec\u7acb\u7684Agent\u6ce8\u518c\u548c\u8c03\u7528\u7cfb\u7edf\"\"\"   # \u6a21\u5757\u6587\u6863\n\u2502\n\u251c\u2500\u2500 \u5bfc\u5165\u6a21\u5757\n\u2502   \u251c\u2500\u2500 \u7cfb\u7edf\u6a21\u5757\n\u2502   \u2502   \u251c\u2500\u2500 os                                     # \u64cd\u4f5c\u7cfb\u7edf\u4ea4\u4e92\n\u2502   \u2502   \u251c\u2500\u2500 json                                   # JSON\u6570\u636e\u5904\u7406\n\u2502   \u2502   \u251c\u2500\u2500 asyncio                                # \u5f02\u6b65\u7f16\u7a0b\u652f\u6301\n\u2502   \u2502   \u251c\u2500\u2500 logging                                # \u65e5\u5fd7\u8bb0\u5f55\n\u2502   \u2502   \u2514\u2500\u2500 time                                   # \u65f6\u95f4\u5904\u7406\n\u2502   \u2502\n\u2502   \u251c\u2500\u2500 \u8def\u5f84\u5904\u7406\n\u2502   \u2502   \u2514\u2500\u2500 from pathlib import Path               # \u73b0\u4ee3\u5316\u8def\u5f84\u64cd\u4f5c\n\u2502   \u2502\n\u2502   \u251c\u2500\u2500 \u7c7b\u578b\u63d0\u793a\n\u2502   \u2502   \u2514\u2500\u2500 from typing import Dict, Any, Optional, List  # \u7c7b\u578b\u6ce8\u89e3\n\u2502   \u2502\n\u2502   \u251c\u2500\u2500 \u6570\u636e\u7c7b\n\u2502   \u2502   \u2514\u2500\u2500 from dataclasses import dataclass, field     # \u7b80\u5316\u7c7b\u5b9a\u4e49\n\u2502   \u2502\n\u2502   \u251c\u2500\u2500 \u65e5\u671f\u65f6\u95f4\n\u2502   \u2502   \u2514\u2500\u2500 from datetime import datetime, timedelta     # \u65f6\u95f4\u65e5\u671f\u64cd\u4f5c\n\u2502   \u2502\n\u2502   \u2514\u2500\u2500 \u6b63\u5219\u8868\u8fbe\u5f0f\n\u2502       \u2514\u2500\u2500 import re                               # \u5b57\u7b26\u4e32\u6a21\u5f0f\u5339\u914d\n\u2502\n\u251c\u2500\u2500 \u65e5\u5fd7\u914d\u7f6e\n\u2502   \u251c\u2500\u2500 logging.basicConfig(level=logging.INFO)     # \u57fa\u7840\u65e5\u5fd7\u914d\u7f6e\n\u2502   \u251c\u2500\u2500 logger = logging.getLogger(\"AgentManager\")  # \u83b7\u53d6\u65e5\u5fd7\u8bb0\u5f55\u5668\n\u2502   \u2514\u2500\u2500 \u5c4f\u853dHTTP\u5e93DEBUG\u65e5\u5fd7\uff083\u884c\uff09                   # \u51cf\u5c11\u65e5\u5fd7\u566a\u97f3\n\u2502\n\u251c\u2500\u2500 \u6570\u636e\u7c7b\u5b9a\u4e49\uff08Data Classes\uff09\n\u2502   \u251c\u2500\u2500 AgentConfig\uff08Agent\u914d\u7f6e\u6a21\u677f\uff09\n\u2502   \u2502   \u251c\u2500\u2500 id: str                                 # \u6a21\u578bID\uff08\u5fc5\u9700\uff09\n\u2502   \u2502   \u251c\u2500\u2500 name: str                               # Agent\u540d\u79f0-\u4e2d\u6587\uff08\u5fc5\u9700\uff09\n\u2502   \u2502   \u251c\u2500\u2500 base_name: str                          # \u57fa\u7840\u540d\u79f0-\u82f1\u6587\uff08\u5fc5\u9700\uff09\n\u2502   \u2502   \u251c\u2500\u2500 system_prompt: str                      # \u7cfb\u7edf\u63d0\u793a\u8bcd\uff08\u5fc5\u9700\uff09\n\u2502   \u2502   \u251c\u2500\u2500 max_output_tokens: int = 40000          # \u6700\u5927\u8f93\u51fatoken\u6570\n\u2502   \u2502   \u251c\u2500\u2500 temperature: float = 0.7                # \u6e29\u5ea6\u53c2\u6570\n\u2502   \u2502   \u251c\u2500\u2500 description: str = \"\"                   # \u63cf\u8ff0\u4fe1\u606f\n\u2502   \u2502   \u251c\u2500\u2500 model_provider: str = \"openai\"          # \u6a21\u578b\u63d0\u4f9b\u5546\n\u2502   \u2502   \u251c\u2500\u2500 api_base_url: str = \"\"                  # API\u57fa\u7840URL\n\u2502   \u2502   \u2514\u2500\u2500 api_key: str = \"\"                       # API\u5bc6\u94a5\n\u2502   \u2502\n\u2502   \u2514\u2500\u2500 AgentSession\uff08Agent\u4f1a\u8bdd\u8bb0\u5f55\uff09\n\u2502       \u251c\u2500\u2500 timestamp: float = field(default_factory=time.time)    # \u65f6\u95f4\u6233\n\u2502       \u251c\u2500\u2500 history: List&#91;Dict&#91;str, str]] = field(default_factory=list)  # \u5386\u53f2\u8bb0\u5f55\n\u2502       \u2514\u2500\u2500 session_id: str = \"default_user_session\"              # \u4f1a\u8bddID\n\u2502\n\u251c\u2500\u2500 \u6838\u5fc3\u7ba1\u7406\u5668\u7c7b\uff08AgentManager\uff09\n\u2502   \u251c\u2500\u2500 \u521d\u59cb\u5316\u65b9\u6cd5 __init__\n\u2502   \u2502   \u251c\u2500\u2500 \u53c2\u6570: config_dir: str = None            # \u914d\u7f6e\u6587\u4ef6\u76ee\u5f55\uff08\u53ef\u9009\uff09\n\u2502   \u2502   \u251c\u2500\u2500 \u5c5e\u6027\u521d\u59cb\u5316\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 self.config_dir                     # \u914d\u7f6e\u76ee\u5f55\u8def\u5f84\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 self.agents                         # Agent\u914d\u7f6e\u5b57\u5178\n\u2502   \u2502   \u2502   \u2514\u2500\u2500 self.agent_sessions                 # Agent\u4f1a\u8bdd\u5b57\u5178\uff08\u4e09\u5c42\u5d4c\u5957\uff09\n\u2502   \u2502   \u2502\n\u2502   \u2502   \u251c\u2500\u2500 \u914d\u7f6e\u8bfb\u53d6\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 self.max_history_rounds             # \u6700\u5927\u5386\u53f2\u8f6e\u6570\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 self.context_ttl_hours = 24         # \u4e0a\u4e0b\u6587\u6709\u6548\u671f\uff08\u5c0f\u65f6\uff09\n\u2502   \u2502   \u2502   \u2514\u2500\u2500 self.debug_mode = True              # \u8c03\u8bd5\u6a21\u5f0f\u5f00\u5173\n\u2502   \u2502   \u2502\n\u2502   \u2502   \u251c\u2500\u2500 \u6761\u4ef6\u52a0\u8f7d\u914d\u7f6e\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 if self.config_dir                  # \u6709\u914d\u7f6e\u76ee\u5f55\u65f6\n\u2502   \u2502   \u2502   \u2502   \u251c\u2500\u2500 self.config_dir.mkdir()         # \u521b\u5efa\u76ee\u5f55\n\u2502   \u2502   \u2502   \u2502   \u2514\u2500\u2500 self._load_agent_configs()      # \u52a0\u8f7d\u914d\u7f6e\n\u2502   \u2502   \u2502   \u2514\u2500\u2500 else                                # \u65e0\u914d\u7f6e\u76ee\u5f55\u65f6\n\u2502   \u2502   \u2502       \u2514\u2500\u2500 logger.info()                   # \u8bb0\u5f55MCP\u67b6\u6784\u63d0\u793a\n\u2502   \u2502   \u2502\n\u2502   \u2502   \u251c\u2500\u2500 \u5b9a\u671f\u6e05\u7406\u4efb\u52a1\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 try: asyncio.get_running_loop()     # \u83b7\u53d6\u4e8b\u4ef6\u5faa\u73af\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 asyncio.create_task()               # \u521b\u5efa\u6e05\u7406\u4efb\u52a1\n\u2502   \u2502   \u2502   \u2514\u2500\u2500 except RuntimeError: pass           # \u65e0\u4e8b\u4ef6\u5faa\u73af\u65f6\u8df3\u8fc7\n\u2502   \u2502   \u2502\n\u2502   \u2502   \u2514\u2500\u2500 \u521d\u59cb\u5316\u5b8c\u6210\u65e5\u5fd7\n\u2502   \u2502\n\u2502   \u251c\u2500\u2500 \u914d\u7f6e\u7ba1\u7406\u65b9\u6cd5\n\u2502   \u2502   \u251c\u2500\u2500 _load_agent_configs()                   # \u52a0\u8f7dAgent\u914d\u7f6e\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 \u68c0\u67e5\u76ee\u5f55\u5b58\u5728\u6027\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 \u626b\u63cfJSON\u914d\u7f6e\u6587\u4ef6\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 \u8bfb\u53d6\u5e76\u89e3\u6790JSON\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 \u9a8c\u8bc1\u914d\u7f6e\u6709\u6548\u6027\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 \u521b\u5efaAgentConfig\u5bf9\u8c61\n\u2502   \u2502   \u2502   \u2514\u2500\u2500 \u6ce8\u518c\u5230agents\u5b57\u5178\n\u2502   \u2502   \u2502\n\u2502   \u2502   \u251c\u2500\u2500 _validate_agent_config()                # \u9a8c\u8bc1Agent\u914d\u7f6e\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 \u68c0\u67e5\u5fc5\u9700\u5b57\u6bb5: &#91;'model_id', 'name']\n\u2502   \u2502   \u2502   \u2514\u2500\u2500 \u8fd4\u56de\u9a8c\u8bc1\u7ed3\u679c: bool\n\u2502   \u2502   \u2502\n\u2502   \u2502   \u251c\u2500\u2500 _register_agent_from_manifest()         # \u4ecemanifest\u6ce8\u518cAgent\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 \u9a8c\u8bc1\u914d\u7f6e\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 \u521b\u5efaAgentConfig\u5bf9\u8c61\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 \u6ce8\u518c\u5230agents\u5b57\u5178\n\u2502   \u2502   \u2502   \u2514\u2500\u2500 \u8fd4\u56de\u6ce8\u518c\u7ed3\u679c: bool\n\u2502   \u2502   \u2502\n\u2502   \u2502   \u2514\u2500\u2500 reload_configs()                        # \u91cd\u65b0\u52a0\u8f7d\u914d\u7f6e\n\u2502   \u2502       \u251c\u2500\u2500 \u6e05\u7a7a\u73b0\u6709agents\n\u2502   \u2502       \u2514\u2500\u2500 \u91cd\u65b0\u52a0\u8f7d\u914d\u7f6e\n\u2502   \u2502\n\u2502   \u251c\u2500\u2500 \u4f1a\u8bdd\u7ba1\u7406\u65b9\u6cd5\n\u2502   \u2502   \u251c\u2500\u2500 get_agent_session_history()             # \u83b7\u53d6Agent\u4f1a\u8bdd\u5386\u53f2\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 \u68c0\u67e5Agent\u662f\u5426\u5b58\u5728\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 \u68c0\u67e5\u4f1a\u8bdd\u662f\u5426\u5b58\u5728\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 \u68c0\u67e5\u4f1a\u8bdd\u662f\u5426\u8fc7\u671f\n\u2502   \u2502   \u2502   \u2514\u2500\u2500 \u8fd4\u56de\u5386\u53f2\u8bb0\u5f55\u5217\u8868\n\u2502   \u2502   \u2502\n\u2502   \u2502   \u251c\u2500\u2500 update_agent_session_history()          # \u66f4\u65b0Agent\u4f1a\u8bdd\u5386\u53f2\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 \u6dfb\u52a0\u65b0\u5bf9\u8bdd\u8bb0\u5f55\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 \u66f4\u65b0\u65f6\u95f4\u6233\n\u2502   \u2502   \u2502   \u2514\u2500\u2500 \u9650\u5236\u5386\u53f2\u6d88\u606f\u6570\u91cf\n\u2502   \u2502   \u2502\n\u2502   \u2502   \u251c\u2500\u2500 _is_context_expired()                   # \u68c0\u67e5\u4e0a\u4e0b\u6587\u662f\u5426\u8fc7\u671f\n\u2502   \u2502   \u2502   \u2514\u2500\u2500 \u5224\u65ad\u65f6\u95f4\u5dee\u662f\u5426\u8d85\u8fc7TTL\n\u2502   \u2502   \u2502\n\u2502   \u2502   \u2514\u2500\u2500 _periodic_cleanup()                     # \u5b9a\u671f\u6e05\u7406\u8fc7\u671f\u7684\u4f1a\u8bdd\n\u2502   \u2502       \u251c\u2500\u2500 \u6bcf\u5c0f\u65f6\u6267\u884c\u4e00\u6b21\n\u2502   \u2502       \u251c\u2500\u2500 \u904d\u5386\u6240\u6709Agent\u4f1a\u8bdd\n\u2502   \u2502       \u251c\u2500\u2500 \u5220\u9664\u8fc7\u671f\u4f1a\u8bdd\n\u2502   \u2502       \u2514\u2500\u2500 \u6e05\u7406\u7a7a\u4f1a\u8bdd\u5b57\u5178\n\u2502   \u2502\n\u2502   \u251c\u2500\u2500 \u6d88\u606f\u6784\u5efa\u65b9\u6cd5\n\u2502   \u2502   \u251c\u2500\u2500 _replace_placeholders()                 # \u66ff\u6362\u63d0\u793a\u8bcd\u5360\u4f4d\u7b26\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 Agent\u914d\u7f6e\u66ff\u6362\uff089\u79cd\u5360\u4f4d\u7b26\uff09\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 \u73af\u5883\u53d8\u91cf\u66ff\u6362\uff08\u6b63\u5219\u5339\u914d\uff09\n\u2502   \u2502   \u2502   \u2514\u2500\u2500 \u65f6\u95f4\u76f8\u5173\u66ff\u6362\uff083\u79cd\u683c\u5f0f\uff09\n\u2502   \u2502   \u2502\n\u2502   \u2502   \u251c\u2500\u2500 _build_system_message()                 # \u6784\u5efa\u7cfb\u7edf\u6d88\u606f\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 \u5904\u7406\u7cfb\u7edf\u63d0\u793a\u8bcd\u5360\u4f4d\u7b26\n\u2502   \u2502   \u2502   \u2514\u2500\u2500 \u8fd4\u56de{\"role\": \"system\", \"content\": ...}\n\u2502   \u2502   \u2502\n\u2502   \u2502   \u251c\u2500\u2500 _build_user_message()                   # \u6784\u5efa\u7528\u6237\u6d88\u606f\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 \u5904\u7406\u7528\u6237\u63d0\u793a\u8bcd\u5360\u4f4d\u7b26\n\u2502   \u2502   \u2502   \u2514\u2500\u2500 \u8fd4\u56de{\"role\": \"user\", \"content\": ...}\n\u2502   \u2502   \u2502\n\u2502   \u2502   \u251c\u2500\u2500 _build_assistant_message()              # \u6784\u5efa\u52a9\u624b\u6d88\u606f\n\u2502   \u2502   \u2502   \u2514\u2500\u2500 \u8fd4\u56de{\"role\": \"assistant\", \"content\": ...}\n\u2502   \u2502   \u2502\n\u2502   \u2502   \u2514\u2500\u2500 _validate_messages()                    # \u9a8c\u8bc1\u6d88\u606f\u5e8f\u5217\n\u2502   \u2502       \u251c\u2500\u2500 \u68c0\u67e5\u6d88\u606f\u975e\u7a7a\n\u2502   \u2502       \u251c\u2500\u2500 \u68c0\u67e5\u6d88\u606f\u683c\u5f0f\u6b63\u786e\u6027\n\u2502   \u2502       \u251c\u2500\u2500 \u68c0\u67e5\u6d88\u606f\u89d2\u8272\u5408\u6cd5\u6027\n\u2502   \u2502       \u2514\u2500\u2500 \u68c0\u67e5\u7cfb\u7edf\u6d88\u606f\u5728\u9996\u4f4d\n\u2502   \u2502\n\u2502   \u251c\u2500\u2500 Agent\u8c03\u7528\u65b9\u6cd5\n\u2502   \u2502   \u251c\u2500\u2500 call_agent()                           # \u8c03\u7528\u6307\u5b9aAgent\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 \u68c0\u67e5Agent\u662f\u5426\u5b58\u5728\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 \u751f\u6210\u4f1a\u8bddID\uff08\u5982\u679c\u672a\u63d0\u4f9b\uff09\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 \u6784\u5efa\u5b8c\u6574\u6d88\u606f\u5e8f\u5217\uff08\u7cfb\u7edf+\u5386\u53f2+\u5f53\u524d\uff09\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 \u9a8c\u8bc1\u6d88\u606f\u5e8f\u5217\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 \u8bb0\u5f55\u8c03\u8bd5\u4fe1\u606f\uff08\u5982\u679cdebug\u6a21\u5f0f\uff09\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 \u8c03\u7528LLM API\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 \u66f4\u65b0\u4f1a\u8bdd\u5386\u53f2\uff08\u5982\u679c\u6210\u529f\uff09\n\u2502   \u2502   \u2502   \u2514\u2500\u2500 \u8fd4\u56de\u8c03\u7528\u7ed3\u679c\n\u2502   \u2502   \u2502\n\u2502   \u2502   \u251c\u2500\u2500 _call_llm_api()                        # \u8c03\u7528LLM API\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 \u5bfc\u5165AsyncOpenAI\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 \u8bb0\u5f55\u8c03\u8bd5\u4fe1\u606f\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 \u9a8c\u8bc1\u5fc5\u9700\u53c2\u6570\uff08model_id, api_key\uff09\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 \u521b\u5efaAPI\u5ba2\u6237\u7aef\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 \u51c6\u5907API\u53c2\u6570\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 \u8c03\u7528chat.completions.create()\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 \u63d0\u53d6\u54cd\u5e94\u5185\u5bb9\n\u2502   \u2502   \u2502   \u2514\u2500\u2500 \u8fd4\u56de\u6210\u529f\u7ed3\u679c\u6216\u9519\u8bef\n\u2502   \u2502   \u2502\n\u2502   \u2502   \u251c\u2500\u2500 call_agent_by_action()                 # \u6839\u636e\u52a8\u4f5c\u8c03\u7528Agent\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 \u68c0\u67e5Agent\u662f\u5426\u5b58\u5728\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 \u63d0\u53d6\u52a8\u4f5c\u53c2\u6570\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 \u6784\u5efa\u52a8\u4f5c\u63d0\u793a\u8bcd\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 \u8c03\u7528Agent\n\u2502   \u2502   \u2502   \u2514\u2500\u2500 \u8fd4\u56de\u6267\u884c\u7ed3\u679c\n\u2502   \u2502   \u2502\n\u2502   \u2502   \u2514\u2500\u2500 _build_action_prompt()                 # \u6784\u5efa\u52a8\u4f5c\u63d0\u793a\u8bcd\n\u2502   \u2502       \u251c\u2500\u2500 \u6e05\u7406\u4e0d\u9700\u8981\u7684\u53c2\u6570\n\u2502   \u2502       \u251c\u2500\u2500 \u683c\u5f0f\u5316\u53c2\u6570\u5b57\u7b26\u4e32\n\u2502   \u2502       \u2514\u2500\u2500 \u8fd4\u56de\u683c\u5f0f\u5316\u63d0\u793a\u8bcd\n\u2502   \u2502\n\u2502   \u251c\u2500\u2500 \u4fe1\u606f\u67e5\u8be2\u65b9\u6cd5\n\u2502   \u2502   \u251c\u2500\u2500 get_available_agents()                 # \u83b7\u53d6\u6240\u6709\u53ef\u7528Agent\u5217\u8868\n\u2502   \u2502   \u2502   \u2514\u2500\u2500 \u8fd4\u56de\u5305\u542b\u57fa\u672c\u4fe1\u606f\u7684\u5b57\u5178\u5217\u8868\n\u2502   \u2502   \u2502\n\u2502   \u2502   \u2514\u2500\u2500 get_agent_info()                       # \u83b7\u53d6\u6307\u5b9aAgent\u8be6\u7ec6\u4fe1\u606f\n\u2502   \u2502       \u251c\u2500\u2500 \u68c0\u67e5Agent\u662f\u5426\u5b58\u5728\n\u2502   \u2502       \u2514\u2500\u2500 \u8fd4\u56de\u5305\u542b\u5b8c\u6574\u4fe1\u606f\u7684\u5b57\u5178\n\u2502   \u2502\n\u2502   \u2514\u2500\u2500 \u667a\u80fd\u4efb\u52a1\u5904\u7406\u65b9\u6cd5\n\u2502       \u2514\u2500\u2500 process_intelligent_task()             # \u667a\u80fd\u4efb\u52a1\u5904\u7406\n\u2502           \u251c\u2500\u2500 \u901a\u8fc7agentserver.task_scheduler\u5904\u7406\n\u2502           \u251c\u2500\u2500 \u521b\u5efa\u552f\u4e00\u4efb\u52a1ID\uff08UUID\uff09\n\u2502           \u251c\u2500\u2500 \u6ce8\u518c\u4efb\u52a1\u5230\u8c03\u5ea6\u5668\n\u2502           \u251c\u2500\u2500 \u8c03\u5ea6\u5e76\u884c\u6267\u884c\n\u2502           \u251c\u2500\u2500 \u5904\u7406\u6267\u884c\u7ed3\u679c\n\u2502           \u2514\u2500\u2500 \u964d\u7ea7\u5904\u7406\uff08\u5931\u8d25\u65f6\u8c03\u7528\u9ed8\u8ba4Agent\uff09\n\u2502\n\u251c\u2500\u2500 \u5168\u5c40\u5b9e\u4f8b\u7ba1\u7406\n\u2502   \u251c\u2500\u2500 \u5168\u5c40\u53d8\u91cf: _AGENT_MANAGER = None            # \u5355\u4f8b\u5b9e\u4f8b\n\u2502   \u2502\n\u2502   \u2514\u2500\u2500 \u83b7\u53d6\u5b9e\u4f8b\u51fd\u6570: get_agent_manager()\n\u2502       \u251c\u2500\u2500 \u58f0\u660e\u4f7f\u7528\u5168\u5c40\u53d8\u91cf\n\u2502       \u251c\u2500\u2500 \u68c0\u67e5\u5b9e\u4f8b\u662f\u5426\u5b58\u5728\n\u2502       \u251c\u2500\u2500 \u4e0d\u5b58\u5728\u65f6\u521b\u5efa\u65b0\u5b9e\u4f8b\n\u2502       \u2514\u2500\u2500 \u8fd4\u56de\u5b9e\u4f8b\n\u2502\n\u2514\u2500\u2500 \u4fbf\u6377\u51fd\u6570\uff08Convenience Functions\uff09\n    \u251c\u2500\u2500 \u8c03\u7528\u76f8\u5173\n    \u2502   \u251c\u2500\u2500 call_agent()                           # \u4fbf\u6377\u8c03\u7528\u51fd\u6570\n    \u2502   \u251c\u2500\u2500 list_agents()                          # \u4fbf\u6377\u5217\u8868\u83b7\u53d6\u51fd\u6570\n    \u2502   \u251c\u2500\u2500 get_agent_info()                       # \u4fbf\u6377\u4fe1\u606f\u83b7\u53d6\u51fd\u6570\n    \u2502   \u2514\u2500\u2500 process_intelligent_task()             # \u4fbf\u6377\u667a\u80fd\u4efb\u52a1\u5904\u7406\u51fd\u6570\n    \u2502\n    \u2514\u2500\u2500 \u4efb\u52a1\u7ba1\u7406\u76f8\u5173\uff08\u901a\u8fc7agentserver.task_scheduler\uff09\n        \u251c\u2500\u2500 get_task_status()                      # \u83b7\u53d6\u4efb\u52a1\u72b6\u6001\n        \u251c\u2500\u2500 get_task_list()                        # \u83b7\u53d6\u4efb\u52a1\u5217\u8868\n        \u251c\u2500\u2500 get_execution_stats()                  # \u83b7\u53d6\u6267\u884c\u7edf\u8ba1\n        \u2514\u2500\u2500 cancel_task()                          # \u53d6\u6d88\u4efb\u52a1\n'''\n#\u6a21\u5757\u4f7f\u7528\u6d41\u7a0b\u603b\u7ed3\n'''\n\u4f7f\u7528\u6d41\u7a0b\uff1a\n1. \u5bfc\u5165\u6a21\u5757\u51fd\u6570\n   \u2192 from agent_manager import call_agent, list_agents\n   \n2. \u83b7\u53d6Agent\u5217\u8868\n   \u2192 agents = list_agents()\n   \n3. \u9009\u62e9\u5e76\u8c03\u7528Agent\n   \u2192 result = await call_agent(\"\u52a9\u624b\u540d\u79f0\", \"\u7528\u6237\u6d88\u606f\", \"session_id\")\n   \n4. \u5904\u7406\u7ed3\u679c\n   \u2192 if result&#91;\"status\"] == \"success\": \u4f7f\u7528 result&#91;\"result\"]\n   \u2192 else: \u5904\u7406\u9519\u8bef result&#91;\"error\"]'''<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">task_scheduler.py<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>#!\/usr\/bin\/env python3\n# -*- coding: utf-8 -*-\n\"\"\"\u901a\u7528\u4efb\u52a1\u8c03\u5ea6\u5668 - \u878d\u5408\u667a\u80fd\u8bb0\u5fc6\u7ba1\u7406\u7684\u4efb\u52a1\u8c03\u5ea6\u7cfb\u7edf\"\"\"\n\nimport asyncio  # \u5f02\u6b65\u652f\u6301 #\nimport uuid  # \u4efb\u52a1ID #\nimport json  # JSON\u5904\u7406 #\nimport logging  # \u65e5\u5fd7 #\nimport time  # \u65f6\u95f4\u5904\u7406 #\nfrom typing import Any, Dict, List, Optional, Union  # \u7c7b\u578b\u6807\u6ce8 #\nfrom dataclasses import dataclass, field  # \u6570\u636e\u7c7b #\nfrom datetime import datetime, timedelta  # \u65f6\u95f4\u5904\u7406 #\n\n# \u914d\u7f6e\u65e5\u5fd7\nlogger = logging.getLogger(__name__)\n#\u521b\u5efa\u4e86\u4e00\u4e2a\u201c\u65e5\u5fd7\u8bb0\u5f55\u5668\u201d\uff0c\u540d\u5b57\u662f\u5f53\u524d\u6a21\u5757\u7684\u540d\u5b57,\u60f3\u8c61\u6210\u4e00\u4e2a\u4e13\u95e8\u7684\u8bb0\u4e8b\u672c\uff0c\u7528\u6765\u8bb0\u5f55\u7a0b\u5e8f\u8fd0\u884c\u60c5\u51b5\n\n@dataclass\nclass TaskStep:\n    \"\"\"\u4efb\u52a1\u6b65\u9aa4\u6570\u636e\u7c7b\"\"\"\n    step_id: str  #step_id - \u6b65\u9aa4ID\uff08\u552f\u4e00\u7f16\u53f7\uff09\n    task_id: str  #task_id - \u5c5e\u4e8e\u54ea\u4e2a\u4efb\u52a1\n    purpose: str  # \u6b65\u9aa4\u76ee\u7684,\u8fd9\u6b65\u8981\u505a\u4ec0\u4e48\n    content: str  # \u6b65\u9aa4\u5185\u5bb9\n    output: str = \"\"  # \u6b65\u9aa4\u8f93\u51fa,\u8f93\u51fa\u7ed3\u679c\uff08\u9ed8\u8ba4\u662f\u7a7a\u5b57\u7b26\u4e32\uff09\n    analysis: Optional&#91;Dict&#91;str, Any]] = None  # \u5206\u6790\u7ed3\u679c\n    timestamp: float = field(default_factory=time.time) #\u65f6\u95f4\u6233\uff08\u81ea\u52a8\u8bb0\u5f55\u5f53\u524d\u65f6\u95f4\uff09\n    success: bool = True  # \u662f\u5426\u6210\u529f\n    error: Optional&#91;str] = None  # \u9519\u8bef\u4fe1\u606f\n\n@dataclass  #\u8fd9\u4e2a\u7c7b\u7528\u6765\u5b58\u50a8\u538b\u7f29\u540e\u7684\u8bb0\u5fc6\uff0c\u5c31\u50cf\u628a\u5f88\u591a\u7ecf\u9a8c\u603b\u7ed3\u6210\u51e0\u6761\u8981\u70b9\u3002\nclass CompressedMemory:\n    \"\"\"\u538b\u7f29\u8bb0\u5fc6\u6570\u636e\u7c7b\"\"\"\n    memory_id: str  #\u8bb0\u5fc6ID\n    key_findings: List&#91;str]  # \u5173\u952e\u53d1\u73b0\uff08\u5217\u8868\uff09\n    failed_attempts: List&#91;str]  # \u5931\u8d25\u5c1d\u8bd5\uff08\u5217\u8868\uff09\n    current_status: str  # \u5f53\u524d\u72b6\u6001\n    next_steps: List&#91;str]  # \u5efa\u8bae\u6b65\u9aa4\n    source_steps: int  # \u6765\u6e90\u6b65\u9aa4\u6570\n    timestamp: float = field(default_factory=time.time)\n\n#\u6ce8\u610f\uff1a\u7c7b\u540d\u4ee5 _ \u5f00\u5934\uff0c\u8fd9\u662f\u4e00\u4e2a\u7ea6\u5b9a\uff0c\u8868\u793a\"\u5185\u90e8\u7c7b\"\u6216\"\u79c1\u6709\u7c7b\"\nclass _TaskScheduler: #\u8d1f\u8d23\u7ba1\u7406\u548c\u534f\u8c03\u6240\u6709\u4efb\u52a1\n    \"\"\"\u901a\u7528\u4efb\u52a1\u8c03\u5ea6\u5668 - \u878d\u5408\u667a\u80fd\u8bb0\u5fc6\u7ba1\u7406\"\"\"\n\n    def __init__(self, config: Optional&#91;Any] = None) -> None:  #\u8fd9\u662f\u7c7b\u7684\"\u6784\u9020\u51fd\u6570\"\uff0c\u521b\u5efa\u5bf9\u8c61\u65f6\u4f1a\u81ea\u52a8\u8c03\u7528\uff1a\n        # \u5bfc\u5165\u914d\u7f6e\n        if config is None:  #\u5982\u679c\u6ca1\u4f20\u5165\u914d\u7f6e\uff0c\u5c31\u4ece agentserver.config \u83b7\u53d6,\u50cf\u8bbe\u5b9a\u6e38\u620f\u7684\u521d\u59cb\u53c2\u6570\u4e00\u6837\n            from agentserver.config import get_task_scheduler_config\n            config = get_task_scheduler_config()\n        \n        self.config = config\n        \n        # \u57fa\u7840\u4efb\u52a1\u7ba1\u7406\n        #task_registry\uff1a\u4e00\u4e2a\u5b57\u5178\uff0c\u8bb0\u5f55\u6240\u6709\u4efb\u52a1\uff08\u50cf\u82b1\u540d\u518c\uff09\n        self.task_registry: Dict&#91;str, Dict&#91;str, Any]] = {}  # \u4efb\u52a1\u6ce8\u518c\u8868\n        #_lock\uff1a\u4e00\u628a\"\u9501\"\uff0c\u9632\u6b62\u591a\u4e2a\u4efb\u52a1\u540c\u65f6\u4fee\u6539\u6570\u636e\uff08\u50cf\u5395\u6240\u7684\u95e8\u9501\uff09\n        self._lock = asyncio.Lock()  # \u5e76\u53d1\u9501\n        \n        # \u667a\u80fd\u8bb0\u5fc6\u7ba1\u7406\n        self.max_steps = config.max_steps  # max_steps\uff1a\u6700\u591a\u4fdd\u5b58\u591a\u5c11\u6b65\u9aa4\n        self.compression_threshold = config.compression_threshold  # \u538b\u7f29\u9608\u503c,compression_threshold\uff1a\u8fbe\u5230\u591a\u5c11\u6b65\u9aa4\u65f6\u538b\u7f29\n        self.keep_last_steps = config.keep_last_steps  # \u538b\u7f29\u540e\u4fdd\u7559\u6b65\u9aa4\u6570\n        #\u6570\u636e\u5b58\u50a8\u5bb9\u5668\n        self.task_steps: Dict&#91;str, List&#91;TaskStep]] = {}  # \u4efb\u52a1\u6b65\u9aa4\u5386\u53f2,task_steps\uff1a\u6bcf\u4e2a\u4efb\u52a1\u7684\u6240\u6709\u6b65\u9aa4\n        self.compressed_memories: List&#91;CompressedMemory] = &#91;]  # \u538b\u7f29\u8bb0\u5fc6,compressed_memories\uff1a\u538b\u7f29\u540e\u7684\u8bb0\u5fc6\n        self.key_facts: Dict&#91;str, str] = {}  # \u5173\u952e\u4e8b\u5b9e\u5b58\u50a8,key_facts\uff1a\u91cd\u8981\u7684\u53d1\u73b0\uff08\u50cf\u4e66\u7b7e\uff09\n        self.failed_attempts: Dict&#91;str, int] = {}  # \u5931\u8d25\u5c1d\u8bd5\u8ba1\u6570,failed_attempts\uff1a\u5931\u8d25\u7684\u6b21\u6570\u7edf\u8ba1\n        self.llm_config: Optional&#91;Dict&#91;str, Any]] = None  # LLM\u914d\u7f6e,llm_config\uff1aAI\u6a21\u578b\u914d\u7f6e\uff08\u8fd8\u6ca1\u8bbe\u7f6e\uff09\n        \n        # \u4f1a\u8bdd\u7ea7\u522b\u7684\u8bb0\u5fc6\u7ba1\u7406 - \u65b0\u589e\u529f\u80fd,\u8fd9\u662f\u6269\u5c55\u529f\u80fd\uff0c\u652f\u6301\"\u4f1a\u8bdd\"\u6982\u5ff5\uff1a\n        self.session_memories: Dict&#91;str, Dict&#91;str, Any]] = {}  # \u4f1a\u8bdd\u8bb0\u5fc6\uff1asession_id -> {tasks, compressed_memories, key_facts}\n        #session_memories\uff1a\u6309\u4f1a\u8bdd\u7ec4\u7ec7\u8bb0\u5fc6\uff08\u50cf\u6587\u4ef6\u5939\uff09\n        self.session_task_mapping: Dict&#91;str, str] = {}  # \u4efb\u52a1ID\u5230\u4f1a\u8bddID\u7684\u6620\u5c04\n        #session_task_mapping\uff1a\u4efb\u52a1\u5c5e\u4e8e\u54ea\u4e2a\u4f1a\u8bdd\n        self.analysis_session_mapping: Dict&#91;str, str] = {}  # \u5206\u6790\u4f1a\u8bddID\u5230\u539f\u59cb\u4f1a\u8bddID\u7684\u6620\u5c04\n        #analysis_session_mapping\uff1a\u5206\u6790\u4f1a\u8bdd\u548c\u539f\u4f1a\u8bdd\u7684\u5173\u7cfb\n\n    #\u8bbe\u7f6eLLM\u914d\u7f6e\u7684\u65b9\u6cd5,\u5f88\u7b80\u5355\uff0c\u5c31\u662f\u8bbe\u7f6eAI\u6a21\u578b\u914d\u7f6e\n    def set_llm_config(self, config: Dict&#91;str, Any]) -> None:\n        \"\"\"\u8bbe\u7f6eLLM\u914d\u7f6e\u7528\u4e8e\u667a\u80fd\u538b\u7f29\"\"\"\n        self.llm_config = config\n        \n   #\u521b\u5efa\u4efb\u52a1\u7684\u65b9\u6cd5 create_task,\u8fd9\u662f\u975e\u5e38\u91cd\u8981\u7684\u65b9\u6cd5\uff0c\u521b\u5efa\u4e00\u4e2a\u65b0\u4efb\u52a1\uff1a\n    async def create_task(self, task_id: str, purpose: str, session_id: Optional&#91;str] = None, \n                         analysis_session_id: Optional&#91;str] = None) -> str:\n        \"\"\"\u521b\u5efa\u65b0\u4efb\u52a1 - \u5e94\u7528\u4e0eMCP\u670d\u52a1\u5668\u76f8\u540c\u7684\u4f1a\u8bdd\u7ba1\u7406\u903b\u8f91\uff0c\u5e76\u5173\u8054\u4f1a\u8bdd\u8bb0\u5fc6\"\"\"\n        #\u4e0a\u9501\u548c\u6ce8\u518c\n        async with self._lock:   #async with self._lock:\uff1a\u5148\u9501\u4e0a\uff0c\u4fdd\u8bc1\u5b89\u5168\n            self.task_registry&#91;task_id] = {    #\u5728 task_registry \u4e2d\u6ce8\u518c\u65b0\u4efb\u52a1\uff0c\u5305\u542b\u57fa\u672c\u4fe1\u606f\n                \"id\": task_id,\n                \"purpose\": purpose,\n                \"session_id\": session_id,\n                \"analysis_session_id\": analysis_session_id,\n                \"status\": \"created\",\n                \"created_at\": time.time(),\n                \"steps_count\": 0\n            }\n            \n            # \u521d\u59cb\u5316\u4efb\u52a1\u6b65\u9aa4\u5217\u8868\n            if task_id not in self.task_steps:\n                self.task_steps&#91;task_id] = &#91;]   #\u4e3a\u8fd9\u4e2a\u4efb\u52a1\u521b\u5efa\u4e00\u4e2a\u7a7a\u6b65\u9aa4\u5217\u8868\n            \n            # \u4f1a\u8bdd\u7ea7\u522b\u7684\u8bb0\u5fc6\u7ba1\u7406,\u5982\u679c\u6709\u4f1a\u8bddID\uff0c\u5efa\u7acb\u5404\u79cd\u6620\u5c04\u5173\u7cfb\n            if session_id: \n                # \u5efa\u7acb\u4efb\u52a1\u5230\u4f1a\u8bdd\u7684\u6620\u5c04\n                self.session_task_mapping&#91;task_id] = session_id\n                \n                # \u5efa\u7acb\u5206\u6790\u4f1a\u8bdd\u5230\u539f\u59cb\u4f1a\u8bdd\u7684\u6620\u5c04\n                if analysis_session_id:\n                    self.analysis_session_mapping&#91;analysis_session_id] = session_id\n            \n                \n                # \u521d\u59cb\u5316\u4f1a\u8bdd\u8bb0\u5fc6\uff08\u5982\u679c\u4e0d\u5b58\u5728\uff09,\u5982\u679c\u8fd9\u4e2a\u4f1a\u8bdd\u662f\u65b0\u7684\uff0c\u5c31\u521d\u59cb\u5316\u5b83\u7684\u8bb0\u5fc6\u4ed3\u5e93\n                if session_id not in self.session_memories:\n                    self.session_memories&#91;session_id] = {\n                        \"tasks\": &#91;],\n                        \"compressed_memories\": &#91;],\n                        \"key_facts\": {},\n                        \"failed_attempts\": {},\n                        \"created_at\": time.time(),\n                        \"last_activity\": time.time()\n                    }\n                \n                # \u5c06\u4f1a\u8bdd\u8bb0\u5fc6\u4e0e\u4efb\u52a1\u5173\u8054\n                self.session_memories&#91;session_id]&#91;\"tasks\"].append(task_id)  #\u628a\u4efb\u52a1ID\u52a0\u5165\u4f1a\u8bdd\u7684\u4efb\u52a1\u5217\u8868\n                self.session_memories&#91;session_id]&#91;\"last_activity\"] = time.time()   #\u66f4\u65b0\u4f1a\u8bdd\u6700\u540e\u6d3b\u52a8\u65f6\u95f4\n            \n            logger.info(f\"&#91;\u4efb\u52a1\u521b\u5efa] \u521b\u5efa\u4efb\u52a1: {task_id}, \u76ee\u7684: {purpose}, \u4f1a\u8bdd: {session_id}, \u5206\u6790\u4f1a\u8bdd: {analysis_session_id}\")\n            return task_id\n\n    async def add_task_step(self, task_id: str, step: TaskStep) -> None:\n        \"\"\"\u6dfb\u52a0\u4efb\u52a1\u6b65\u9aa4\u5230\u5386\u53f2\u8bb0\u5f55\uff0c\u5e76\u66f4\u65b0\u4f1a\u8bdd\u7ea7\u522b\u7684\u8bb0\u5fc6\u7ba1\u7406\"\"\"\n        async with self._lock:\n            if task_id not in self.task_steps: #\u5b89\u5168\u68c0\u67e5\n                self.task_steps&#91;task_id] = &#91;]   #\u6dfb\u52a0\u6b65\u9aa4\u5230\u5bf9\u5e94\u4efb\u52a1\u7684\u6b65\u9aa4\u5217\u8868\n            \n            self.task_steps&#91;task_id].append(step)\n            \n            # \u63d0\u53d6\u5173\u952e\u4e8b\u5b9e,\u8c03\u7528\u4e0b\u9762\u7684 _extract_key_facts \u65b9\u6cd5\n            self._extract_key_facts(step)\n            \n            # \u8bb0\u5f55\u5931\u8d25\u5c1d\u8bd5\n            if not step.success:  #\u5982\u679c\u6b65\u9aa4\u5931\u8d25\uff0c\u8bb0\u5f55\u8fd9\u4e2a\u5931\u8d25\u5185\u5bb9\n                self.failed_attempts&#91;step.content] = self.failed_attempts.get(step.content, 0) + 1  #\u4f7f\u7528 .get() \u907f\u514d\u952e\u4e0d\u5b58\u5728\n            \n            # \u4f1a\u8bdd\u7ea7\u522b\u7684\u8bb0\u5fc6\u7ba1\u7406\n            session_id = self.session_task_mapping.get(task_id)\n            if session_id and session_id in self.session_memories: #\u83b7\u53d6\u4efb\u52a1\u6240\u5c5e\u4f1a\u8bdd,\u5982\u679c\u6709\u4f1a\u8bdd\uff0c\u66f4\u65b0\u8be5\u4f1a\u8bdd\u7684\u8bb0\u5fc6\n                # \u66f4\u65b0\u4f1a\u8bdd\u8bb0\u5fc6\u4e2d\u7684\u5173\u952e\u4e8b\u5b9e\n                fact_key = f\"task:{task_id}:step:{step.step_id}\"\n                if fact_key in self.key_facts:\n                    self.session_memories&#91;session_id]&#91;\"key_facts\"]&#91;fact_key] = self.key_facts&#91;fact_key]\n                \n                # \u66f4\u65b0\u4f1a\u8bdd\u8bb0\u5fc6\u4e2d\u7684\u5931\u8d25\u5c1d\u8bd5\n                if not step.success:\n                    session_failed = self.session_memories&#91;session_id]&#91;\"failed_attempts\"]\n                    session_failed&#91;step.content] = session_failed.get(step.content, 0) + 1\n                \n                # \u66f4\u65b0\u4f1a\u8bdd\u6d3b\u52a8\u65f6\u95f4\n                self.session_memories&#91;session_id]&#91;\"last_activity\"] = time.time()\n            \n            # \u68c0\u67e5\u662f\u5426\u9700\u8981\u538b\u7f29\u8bb0\u5fc6\n            if len(self.task_steps&#91;task_id]) >= self.compression_threshold: #\u5982\u679c\u6b65\u9aa4\u6570\u8fbe\u5230\u9608\u503c\uff0c\u5c31\u538b\u7f29\u8bb0\u5fc6\n                await self._compress_memory(task_id)\n\n    def _extract_key_facts(self, step: TaskStep) -> None:\n        \"\"\"\u4ece\u6b65\u9aa4\u4e2d\u63d0\u53d6\u5173\u952e\u4e8b\u5b9e\"\"\"\n        # \u63d0\u53d6\u5173\u952e\u547d\u4ee4\u548c\u7ed3\u679c\n        if step.content and step.output:\n            #\u5982\u679c\u6709\u5185\u5bb9\u548c\u8f93\u51fa\uff0c\u5c31\u63d0\u53d6,output_summary\uff1a\u622a\u65ad\u8f93\u51fa\uff0c\u53ea\u4fdd\u7559\u4e00\u90e8\u5206,\u751f\u6210\u683c\u5f0f\u5316\u7684\u5173\u952e\u4e8b\u5b9e\n            output_summary = step.output&#91;:self.config.output_summary_length] + (\"...\" if len(step.output) > self.config.output_summary_length else \"\")\n            fact_key = f\"task:{step.task_id}:step:{step.step_id}\"\n            self.key_facts&#91;fact_key] = f\"\u547d\u4ee4\uff1a{step.content}, \u7ed3\u679c: {output_summary}\"\n        \n        # \u63d0\u53d6\u5206\u6790\u7ed3\u8bba,\u5982\u679c\u6709\u5206\u6790\u7ed3\u679c\u4e14\u5305\u542b\u91cd\u8981\u8bcd\uff0c\u5c31\u4fdd\u5b58\n        if step.analysis and \"analysis\" in step.analysis:\n            analysis = step.analysis&#91;\"analysis\"]\n            if \"\u5173\u952e\u53d1\u73b0\" in analysis or \"\u91cd\u8981\" in analysis:\n                fact_key = f\"analysis:{hash(analysis)}\"\n                self.key_facts&#91;fact_key] = analysis\n\n    async def _compress_memory(self, task_id: str) -> None:\n        \"\"\"\u538b\u7f29\u4efb\u52a1\u8bb0\u5fc6,\u8fd9\u662f\u6700\u590d\u6742\u7684\u65b9\u6cd5\uff0c\u4f7f\u7528AI\u538b\u7f29\u8bb0\u5fc6\"\"\"\n        if not self.llm_config or task_id not in self.task_steps: #\u5fc5\u987b\u6709LLM\u914d\u7f6e\u548c\u4efb\u52a1\u6b65\u9aa4\n            return\n        \n        logger.info(f\"\u5f00\u59cb\u538b\u7f29\u4efb\u52a1 {task_id} \u7684\u8bb0\u5fc6...\")\n        \n        # \u6784\u5efa\u538b\u7f29\u63d0\u793a,\u8c03\u7528\u53e6\u4e00\u4e2a\u65b9\u6cd5\u6784\u5efa\u63d0\u793a\n        prompt = self._build_compression_prompt(task_id)\n        \n        try:\n            # \u8c03\u7528LLM\u8fdb\u884c\u538b\u7f29,\u8c03\u7528AI\u6a21\u578b\u538b\u7f29\u8bb0\u5fc6\n            compressed_data = await self._call_llm_compression(prompt)\n            \n            # \u521b\u5efa\u538b\u7f29\u8bb0\u5fc6\u5bf9\u8c61,\u7528AI\u8fd4\u56de\u7684\u6570\u636e\u521b\u5efa CompressedMemory \u5bf9\u8c61,uuid.uuid4() \u751f\u6210\u552f\u4e00ID\n            memory = CompressedMemory(\n                memory_id=str(uuid.uuid4()),\n                key_findings=compressed_data.get(\"key_findings\", &#91;]),\n                failed_attempts=compressed_data.get(\"failed_attempts\", &#91;]),\n                current_status=compressed_data.get(\"current_status\", \"\u672a\u77e5\u72b6\u6001\"),\n                next_steps=compressed_data.get(\"next_steps\", &#91;]),\n                source_steps=len(self.task_steps&#91;task_id])\n            )\n            \n            # \u66f4\u65b0\u5931\u8d25\u5c1d\u8bd5\u8bb0\u5f55,\u628a\u538b\u7f29\u540e\u7684\u5931\u8d25\u8bb0\u5f55\u52a0\u5165\u5168\u5c40\u5931\u8d25\u8bb0\u5f55\n            for attempt in memory.failed_attempts:\n                self.failed_attempts&#91;attempt] = self.failed_attempts.get(attempt, 0) + 1\n            \n            #\u52a0\u5165\u538b\u7f29\u8bb0\u5fc6\u5217\u8868\n            self.compressed_memories.append(memory)\n            \n            # \u4f1a\u8bdd\u7ea7\u522b\u7684\u538b\u7f29\u8bb0\u5fc6\u7ba1\u7406,\u5982\u679c\u6709\u4f1a\u8bdd\uff0c\u4e5f\u52a0\u5165\u4f1a\u8bdd\u7684\u8bb0\u5fc6\n            session_id = self.session_task_mapping.get(task_id)\n            if session_id and session_id in self.session_memories:\n                self.session_memories&#91;session_id]&#91;\"compressed_memories\"].append(memory)\n                logger.info(f\"&#91;\u4f1a\u8bdd\u8bb0\u5fc6] \u4f1a\u8bdd {session_id} \u6dfb\u52a0\u538b\u7f29\u8bb0\u5fc6: {len(memory.key_findings)}\u4e2a\u5173\u952e\u53d1\u73b0\")\n            \n            logger.info(f\"\u8bb0\u5fc6\u538b\u7f29\u6210\u529f: \u6dfb\u52a0\u4e86{len(memory.key_findings)}\u4e2a\u5173\u952e\u53d1\u73b0\")\n            \n        except Exception as e:\n            logger.error(f\"\u8bb0\u5fc6\u538b\u7f29\u5931\u8d25: {e}\")\n            # \u521b\u5efa\u9519\u8bef\u8bb0\u5fc6\n            error_memory = CompressedMemory(\n                memory_id=str(uuid.uuid4()),\n                key_findings=&#91;f\"\u538b\u7f29\u5931\u8d25: {str(e)}\"],\n                failed_attempts=&#91;],\n                current_status=\"\u538b\u7f29\u5931\u8d25\",\n                next_steps=&#91;\"\u91cd\u65b0\u5c1d\u8bd5\u538b\u7f29\"],\n                source_steps=len(self.task_steps&#91;task_id])\n            )\n            self.compressed_memories.append(error_memory)\n        \n        # \u6e05\u7a7a\u5386\u53f2\u8bb0\u5f55\uff0c\u4fdd\u7559\u6700\u540e\u51e0\u6b65\n        keep_last = min(self.keep_last_steps, len(self.task_steps&#91;task_id]))\n        self.task_steps&#91;task_id] = self.task_steps&#91;task_id]&#91;-keep_last:]\n\n    def _build_compression_prompt(self, task_id: str) -> str:\n        \"\"\"\u6784\u5efa\u538b\u7f29\u63d0\u793a\"\"\"\n        prompt = \"\"\"\n\u4f60\u662f\u4e00\u4e2a\u4e13\u4e1a\u7684\u4efb\u52a1\u6267\u884c\u52a9\u624b\uff0c\u9700\u8981\u538b\u7f29\u4efb\u52a1\u6267\u884c\u5386\u53f2\u8bb0\u5f55\u3002\u8bf7\u6267\u884c\u4ee5\u4e0b\u4efb\u52a1\uff1a\n1. \u8bc6\u522b\u5e76\u63d0\u53d6\u5173\u952e\u7684\u6280\u672f\u7ec6\u8282\u548c\u53d1\u73b0\n2. \u6807\u8bb0\u5df2\u5c1d\u8bd5\u4f46\u5931\u8d25\u7684\u89e3\u51b3\u65b9\u6848\n3. \u603b\u7ed3\u5f53\u524d\u4efb\u52a1\u72b6\u6001\u548c\u4e0b\u4e00\u6b65\u5efa\u8bae\n4. \u4ee5JSON\u683c\u5f0f\u8fd4\u56de\u4ee5\u4e0b\u7ed3\u6784\u7684\u6570\u636e\uff1a\n{\n  \"key_findings\": &#91;\"\u53d1\u73b01\", \"\u53d1\u73b02\"],\n  \"failed_attempts\": &#91;\"\u547d\u4ee41\", \"\u547d\u4ee42\"],\n  \"current_status\": \"\u5f53\u524d\u72b6\u6001\u63cf\u8ff0\",\n  \"next_steps\": &#91;\"\u5efa\u8bae1\", \"\u5efa\u8bae2\"]\n}\n\n\u4efb\u52a1ID: {task_id}\n\u5386\u53f2\u8bb0\u5f55:\n\"\"\".format(task_id=task_id)\n        \n        # \u6dfb\u52a0\u5173\u952e\u4e8b\u5b9e\n        prompt += \"\u5173\u952e\u4e8b\u5b9e\u6458\u8981:\\n\"\n        #list(self.key_facts.items())\uff1a\u628a\u5b57\u5178\u8f6c\u6362\u6210(\u952e,\u503c)\u7684\u5217\u8868\n        #&#91;-self.config.key_facts_compression_limit:]\uff1a\u53d6\u6700\u8fd1N\u4e2a\uff08\u914d\u7f6e\u51b3\u5b9a\uff09\n        #\u5faa\u73af\u6dfb\u52a0\u6bcf\u4e2a\u5173\u952e\u4e8b\u5b9e\u5230\u63d0\u793a\u4e2d\n        recent_facts = list(self.key_facts.items())&#91;-self.config.key_facts_compression_limit:]  # \u6700\u8fd1\u5173\u952e\u4e8b\u5b9e\n        for _, value in recent_facts:\n            prompt += f\"- {value}\\n\"\n        \n        # \u6dfb\u52a0\u5386\u53f2\u6b65\u9aa4\n        steps = self.task_steps&#91;task_id]&#91;-self.compression_threshold:]\n        for i, step in enumerate(steps): #\u83b7\u53d6\u6700\u8fd1N\u4e2a\u6b65\u9aa4\uff08\u538b\u7f29\u9608\u503c\u51b3\u5b9a\u6570\u91cf\uff09,enumerate(steps)\uff1a\u540c\u65f6\u83b7\u53d6\u7d22\u5f15\u548c\u6b65\u9aa4\u5bf9\u8c61,\u6dfb\u52a0\u6b65\u9aa4\u7684\u57fa\u672c\u4fe1\u606f\n            prompt += f\"\\n\u6b65\u9aa4 {i+1}:\\n\"\n            prompt += f\"- \u76ee\u7684: {step.purpose}\\n\"\n            prompt += f\"- \u547d\u4ee4: {step.content}\\n\"\n            if step.output:  #\u5904\u7406\u8f93\u51fa\u548c\u7ed3\u679c,\u5982\u679c\u6709\u8f93\u51fa\uff0c\u663e\u793a\u90e8\u5206\u8f93\u51fa\uff08\u622a\u65ad\u5230\u914d\u7f6e\u7684\u957f\u5ea6\uff09,\u4e09\u5143\u8868\u8fbe\u5f0f\uff1a\u5982\u679c\u8f93\u51fa\u592a\u957f\u5c31\u52a0...\uff0c\u5426\u5219\u4e0d\u52a0\n                prompt += f\"- \u8f93\u51fa: {step.output&#91;:self.config.step_output_display_length]}{'...' if len(step.output) > self.config.step_output_display_length else ''}\\n\"\n            if step.analysis: #\u5904\u7406\u5206\u6790\u548c\u5931\u8d25,.get(\"analysis\", \"\u65e0\u5206\u6790\")\uff1a\u5b89\u5168\u83b7\u53d6\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u8fd4\u56de\"\u65e0\u5206\u6790\",\u5982\u679c\u6b65\u9aa4\u5931\u8d25\uff0c\u663e\u793a\u9519\u8bef\u4fe1\u606f\n                analysis = step.analysis.get(\"analysis\", \"\u65e0\u5206\u6790\")\n                prompt += f\"- \u5206\u6790: {analysis}\\n\"\n            if not step.success:\n                prompt += f\"- \u72b6\u6001: \u5931\u8d25 - {step.error}\\n\"\n        \n        return prompt\n\n    #\u8c03\u7528LLM\u8fdb\u884c\u538b\u7f29\u7684\u65b9\u6cd5,\u8fd9\u4e2a\u65b9\u6cd5\u5b9e\u9645\u8c03\u7528AI\u6a21\u578b\u6765\u538b\u7f29\u8bb0\u5fc6\uff1a\n    async def _call_llm_compression(self, prompt: str) -> Dict&#91;str, Any]:\n        \"\"\"\u8c03\u7528LLM\u8fdb\u884c\u8bb0\u5fc6\u538b\u7f29\"\"\"\n        try:  #\u5bfc\u5165litellm\u5e93\n            import litellm    #litellm\uff1a\u4e00\u4e2a\u7edf\u4e00\u7684AI\u6a21\u578b\u8c03\u7528\u5e93\n            litellm.enable_json_schema_validation = True   #enable_json_schema_validation\uff1a\u542f\u7528JSON\u683c\u5f0f\u9a8c\u8bc1\n            \n            response = litellm.completion(   #\u4f7f\u7528 litellm.completion \u8c03\u7528AI,\u53c2\u6570\u5305\u62ec\uff1a\u6a21\u578b\u540d\u3001API\u5bc6\u94a5\u3001API\u5730\u5740\u3001\u6d88\u606f\u3001\u6700\u5927token\u6570\n                model=self.llm_config&#91;\"model\"],\n                api_key=self.llm_config&#91;\"api_key\"],\n                api_base=self.llm_config&#91;\"api_base\"],\n                messages=&#91;{\"role\": \"user\", \"content\": prompt}],\n                max_tokens=1024,\n            )\n            \n            #response.choices&#91;0].message.content\uff1a\u83b7\u53d6AI\u56de\u590d\u5185\u5bb9\n            json_str = response.choices&#91;0].message.content.strip()  #.strip()\uff1a\u53bb\u6389\u9996\u5c3e\u7a7a\u683c\n            return json.loads(json_str)   #json.loads()\uff1a\u628aJSON\u5b57\u7b26\u4e32\u8f6c\u6362\u6210Python\u5b57\u5178\n            \n        except Exception as e:   #\u9519\u8bef\u5904\u7406\n            logger.error(f\"LLM\u538b\u7f29\u8c03\u7528\u5931\u8d25: {e}\")\n            return {    #\u5982\u679c\u51fa\u9519\uff0c\u8fd4\u56de\u4e00\u4e2a\u9ed8\u8ba4\u7684\u9519\u8bef\u7ed3\u6784,\u4fdd\u8bc1\u65b9\u6cd5\u603b\u80fd\u8fd4\u56de\u6709\u6548\u7684\u5b57\u5178\n                \"key_findings\": &#91;f\"\u538b\u7f29\u5931\u8d25: {str(e)}\"],\n                \"failed_attempts\": &#91;],\n                \"current_status\": \"\u538b\u7f29\u5931\u8d25\",\n                \"next_steps\": &#91;\"\u68c0\u67e5LLM\u914d\u7f6e\"]\n            }\n    \n    #\u5e76\u884c\u6267\u884c\u8c03\u5ea6\u65b9\u6cd5 \n    async def schedule_parallel_execution(self, tasks: List&#91;Dict&#91;str, Any]]) -> List&#91;Dict&#91;str, Any]]:\n        \"\"\"\u5e76\u884c\u8c03\u5ea6\u6267\u884c\u7ed9\u5b9a\u4efb\u52a1\u5217\u8868\uff0c\u8fd4\u56de\u7ed3\u679c\u5217\u8868\"\"\"\n        if not tasks:    #\u7a7a\u68c0\u67e5\n            return &#91;]\n\n        # \u5b9a\u4e49\u5185\u90e8\u4efb\u52a1\u8fd0\u884c\u51fd\u6570\n        async def _run_task(task: Dict&#91;str, Any]) -> Dict&#91;str, Any]:    #\u5b9a\u4e49\u5f02\u6b65\u51fd\u6570\u6765\u5904\u7406\u5355\u4e2a\u4efb\u52a1\n            task_id = task.get(\"id\") or str(uuid.uuid4())               #\u5982\u679c\u6ca1\u6709\u63d0\u4f9b\u4efb\u52a1ID\uff0c\u5c31\u751f\u6210\u4e00\u4e2a\n            async with self._lock:                            # \u6ce8\u518c\u4efb\u52a1\n                self.task_registry&#91;task_id] = {\n                    \"id\": task_id,\n                    \"type\": task.get(\"type\") or \"processor\",\n                    \"status\": \"running\",\n                    \"params\": task.get(\"params\") or {},\n                    \"context\": task.get(\"context\"),\n                    \"created_at\": time.time()\n                }\n\n            try:\n                # \u521b\u5efa\u4efb\u52a1\u6b65\u9aa4\u8bb0\u5f55\n                step = TaskStep(\n                    step_id=str(uuid.uuid4()),\n                    task_id=task_id,\n                    purpose=task.get(\"purpose\", \"\u6267\u884c\u4efb\u52a1\"),\n                    content=str(task.get(\"params\", {})),\n                    success=True\n                )\n                \n                # \u5360\u4f4d\u6267\u884c\uff1a\u6b64\u5904\u53ef\u63a5\u5165\u771f\u5b9e\u6267\u884c\u5668\n                await asyncio.sleep(0) #await asyncio.sleep(0)\uff1a\u8ba9\u51fa\u63a7\u5236\u6743\uff0c\u4e0d\u5b9e\u9645\u7b49\u5f85,\u8fd9\u662f\u4e00\u4e2a\u5360\u4f4d\uff0c\u5b9e\u9645\u5e94\u8be5\u8c03\u7528\u771f\u6b63\u7684\u4efb\u52a1\u6267\u884c\u5668\n                result = {\n                    \"success\": True,\n                    \"result\": None,\n                    \"task_type\": self.task_registry&#91;task_id]&#91;\"type\"],\n                }\n                \n                step.output = str(result)\n                # \u8bb0\u5f55\u6b65\u9aa4\u548c\u7ed3\u679c\n                await self.add_task_step(task_id, step) \n                \n                return result\n            #\u9519\u8bef\u5904\u7406\n            except Exception as e:\n                # \u8bb0\u5f55\u5931\u8d25\u7684\u6b65\u9aa4\n                step = TaskStep(\n                    step_id=str(uuid.uuid4()),\n                    task_id=task_id,\n                    purpose=task.get(\"purpose\", \"\u6267\u884c\u4efb\u52a1\"),\n                    content=str(task.get(\"params\", {})),\n                    success=False,\n                    error=str(e)\n                )\n                await self.add_task_step(task_id, step)\n                \n                return {\"success\": False, \"error\": str(e)}\n            # \u6700\u7ec8\u72b6\u6001\u66f4\u65b0\n            finally:   #finally\uff1a\u65e0\u8bba\u6210\u529f\u5931\u8d25\u90fd\u4f1a\u6267\u884c,\u66f4\u65b0\u4efb\u52a1\u72b6\u6001\u4e3a\u5b8c\u6210\n                async with self._lock:\n                    entry = self.task_registry.get(task_id)\n                    if entry is not None:\n                        entry&#91;\"status\"] = \"completed\"\n                        entry&#91;\"completed_at\"] = time.time()\n        \n        #\u5e76\u884c\u6267\u884c\u6240\u6709\u4efb\u52a1,coros\uff1a\u534f\u7a0b\u5bf9\u8c61\u5217\u8868\uff08\u6bcf\u4e2a\u4efb\u52a1\u4e00\u4e2a\uff09\n        coros = &#91;_run_task(t) for t in tasks]\n        #asyncio.gather\uff1a\u540c\u65f6\u8fd0\u884c\u6240\u6709\u534f\u7a0b\n        return await asyncio.gather(*coros, return_exceptions=False) #return_exceptions=False\uff1a\u5982\u679c\u6709\u5f02\u5e38\u5c31\u629b\u51fa\uff0c\u4e0d\u8fd4\u56de\u5f02\u5e38\n\n    async def get_task_status(self, task_id: str) -> Optional&#91;Dict&#91;str, Any]]:\n        \"\"\"\u67e5\u8be2\u6307\u5b9a\u4efb\u52a1\u72b6\u6001\"\"\"\n        async with self._lock:\n            return self.task_registry.get(task_id)\n    \n    # \u83b7\u53d6\u4efb\u52a1\u72b6\u6001\u7684\u65b9\u6cd5\n    async def get_running_tasks(self) -> List&#91;Dict&#91;str, Any]]:  #\u7b80\u5355\u67e5\u8be2\u4efb\u52a1\u6ce8\u518c\u8868,\u4f7f\u7528 .get() \u65b9\u6cd5\u5b89\u5168\u83b7\u53d6\n        \"\"\"\u83b7\u53d6\u8fd0\u884c\u4e2d\u4efb\u52a1\u5217\u8868\"\"\"\n        async with self._lock:   #\u5217\u8868\u63a8\u5bfc\u5f0f\uff1a\u7b5b\u9009\u51fa\u72b6\u6001\u4e3a\"running\"\u7684\u4efb\u52a1,.values()\uff1a\u83b7\u53d6\u6240\u6709\u4efb\u52a1\u5b57\u5178\n            return &#91;t for t in self.task_registry.values() if t.get(\"status\") == \"running\"]\n\n    #\u83b7\u53d6\u4efb\u52a1\u8bb0\u5fc6\u6458\u8981\u7684\u65b9\u6cd5\n    #\u8fd9\u4e2a\u65b9\u6cd5\u751f\u6210\u4efb\u52a1\u7684\u8be6\u7ec6\u62a5\u544a\uff1a\n    async def get_task_memory_summary(self, task_id: str, include_key_facts: bool = True) -> str:\n        \"\"\"\u83b7\u53d6\u4efb\u52a1\u8bb0\u5fc6\u6458\u8981\"\"\"\n        async with self._lock:  \n            summary = \"\"\n            \n            # 1. \u5173\u952e\u4e8b\u5b9e\u6458\u8981\n            if include_key_facts and self.key_facts:\n                summary += \"\u5173\u952e\u4e8b\u5b9e:\\n\"\n                task_facts = &#91;v for k, v in self.key_facts.items() if f\"task:{task_id}\" in k]\n                for fact in task_facts&#91;-self.config.key_facts_summary_limit:]:  # \u663e\u793a\u6700\u8fd1\u5173\u952e\u4e8b\u5b9e\n                    summary += f\"- {fact}\\n\"\n                summary += \"\\n\"\n                #\u7b5b\u9009\u51fa\u8fd9\u4e2a\u4efb\u52a1\u7684\u5173\u952e\u4e8b\u5b9e\n                #if f\"task:{task_id}\" in k\uff1a\u68c0\u67e5\u952e\u662f\u5426\u5305\u542b\u4efb\u52a1ID\n            \n            # 2. \u538b\u7f29\u8bb0\u5fc6\u6458\u8981\n            if self.compressed_memories:\n                summary += \"\u538b\u7f29\u8bb0\u5fc6\u5757:\\n\"\n                for i, mem in enumerate(self.compressed_memories&#91;-self.config.compressed_memory_summary_limit:]):  # \u663e\u793a\u6700\u8fd1\u538b\u7f29\u5757\n                    summary += f\"\u8bb0\u5fc6\u5757 #{len(self.compressed_memories)-i}:\\n\"   #len(self.compressed_memories)-i\uff1a\u8ba1\u7b97\u5757\u7f16\u53f7\uff08\u4ece\u540e\u5f80\u524d\uff09\n                    summary += f\"- \u72b6\u6001: {mem.current_status}\\n\"\n                    #\u663e\u793a\u5173\u952e\u53d1\u73b0\n                    summary += f\"- \u5173\u952e\u53d1\u73b0: {', '.join(mem.key_findings&#91;:self.config.key_findings_display_limit])}\"  #', '.join()\uff1a\u7528\u9017\u53f7\u548c\u7a7a\u683c\u8fde\u63a5\u5217\u8868\u5143\u7d20\n                    if len(mem.key_findings) > self.config.key_findings_display_limit:  # \u5982\u679c\u53d1\u73b0\u592a\u591a\uff0c\u663e\u793a\"\u7b49X\u9879\"\n                        summary += f\" \u7b49{len(mem.key_findings)}\u9879\"\n                    summary += \"\\n\"\n                    \n                    if mem.failed_attempts:\n                        summary += f\"- \u5931\u8d25\u5c1d\u8bd5: {', '.join(mem.failed_attempts&#91;:self.config.failed_attempts_display_limit])}\" \n                        if len(mem.failed_attempts) > self.config.failed_attempts_display_limit:\n                            summary += f\" \u7b49{len(mem.failed_attempts)}\u9879\"\n                        summary += \"\\n\"\n                    \n                    if mem.next_steps:\n                        summary += f\"- \u5efa\u8bae\u6b65\u9aa4: {mem.next_steps&#91;0]}\\n\"\n                    \n                    summary += f\"- \u6765\u6e90: \u57fa\u4e8e{mem.source_steps}\u4e2a\u5386\u53f2\u6b65\u9aa4\\n\\n\"\n            \n            # 3. \u6700\u8fd1\u8be6\u7ec6\u6b65\u9aa4\n            if task_id in self.task_steps and self.task_steps&#91;task_id]:  #\u68c0\u67e5\u4efb\u52a1\u662f\u5426\u6709\u6b65\u9aa4,\u9006\u5e8f\u663e\u793a\u6b65\u9aa4\uff08\u6700\u65b0\u7684\u5728\u6700\u4e0a\u9762\uff09\n                summary += \"\u6700\u8fd1\u8be6\u7ec6\u6b65\u9aa4:\\n\"\n                for i, step in enumerate(self.task_steps&#91;task_id]):\n                    step_num = len(self.task_steps&#91;task_id]) - i\n                    summary += f\"\u6b65\u9aa4 {step_num}:\\n\"\n                    summary += f\"- \u76ee\u7684: {step.purpose}\\n\"\n                    summary += f\"- \u547d\u4ee4: {step.content}\\n\"\n                    \n                    if step.output:  \n                        summary += f\"- \u8f93\u51fa: {step.output&#91;:self.config.step_output_display_length]}{'...' if len(step.output) > self.config.step_output_display_length else ''}\\n\"\n                    \n                    if step.analysis:\n                        analysis = step.analysis.get(\"analysis\", \"\u65e0\u5206\u6790\")\n                        summary += f\"- \u5206\u6790: {analysis}\\n\"\n                    \n                    if not step.success:\n                        summary += f\"- \u72b6\u6001: \u5931\u8d25 - {step.error}\\n\"\n                    \n                    # \u663e\u793a\u5931\u8d25\u6b21\u6570\n                    if step.content in self.failed_attempts:   #\u68c0\u67e5\u8fd9\u4e2a\u547d\u4ee4\u662f\u5426\u5931\u8d25\u8fc7,\u663e\u793a\u603b\u5171\u5931\u8d25\u4e86\u591a\u5c11\u6b21\n                        summary += f\"- \u5386\u53f2\u5931\u8d25\u6b21\u6570: {self.failed_attempts&#91;step.content]}\\n\"\n                    \n                    summary += \"\\n\"\n            \n            return summary if summary else \"\u65e0\u5386\u53f2\u8bb0\u5f55\"\n\n    async def get_global_memory_summary(self) -> str:\n        \"\"\"\u83b7\u53d6\u5168\u5c40\u8bb0\u5fc6\u6458\u8981\"\"\"\n        async with self._lock:\n            summary = f\"\u5168\u5c40\u4efb\u52a1\u8bb0\u5fc6\u6458\u8981\\n\"\n            summary += f\"=\" * 50 + \"\\n\"\n            \n            # \u4efb\u52a1\u7edf\u8ba1\n            total_tasks = len(self.task_registry)\n            running_tasks = len(&#91;t for t in self.task_registry.values() if t.get(\"status\") == \"running\"])\n            completed_tasks = len(&#91;t for t in self.task_registry.values() if t.get(\"status\") == \"completed\"])\n            \n            summary += f\"\u4efb\u52a1\u7edf\u8ba1:\\n\"\n            summary += f\"- \u603b\u4efb\u52a1\u6570: {total_tasks}\\n\"\n            summary += f\"- \u8fd0\u884c\u4e2d: {running_tasks}\\n\"\n            summary += f\"- \u5df2\u5b8c\u6210: {completed_tasks}\\n\\n\"\n            \n            # \u8bb0\u5fc6\u7edf\u8ba1\n            total_steps = sum(len(steps) for steps in self.task_steps.values())  #sum()\uff1a\u8ba1\u7b97\u6240\u6709\u4efb\u52a1\u7684\u6b65\u9aa4\u603b\u6570\n            total_compressed = len(self.compressed_memories)\n            total_facts = len(self.key_facts)\n            total_failures = len(self.failed_attempts)\n            \n            summary += f\"\u8bb0\u5fc6\u7edf\u8ba1:\\n\"\n            summary += f\"- \u603b\u6b65\u9aa4\u6570: {total_steps}\\n\"\n            summary += f\"- \u538b\u7f29\u8bb0\u5fc6\u5757: {total_compressed}\\n\"\n            summary += f\"- \u5173\u952e\u4e8b\u5b9e: {total_facts}\\n\"\n            summary += f\"- \u5931\u8d25\u5c1d\u8bd5: {total_failures}\\n\\n\"\n            \n            # \u6700\u8fd1\u6d3b\u52a8\n            if self.compressed_memories:\n                summary += \"\u6700\u8fd1\u538b\u7f29\u8bb0\u5fc6:\\n\"\n                for mem in self.compressed_memories&#91;-self.config.compressed_memory_global_limit:]:  # \u6700\u8fd1\u538b\u7f29\u8bb0\u5fc6\n                    summary += f\"- {mem.current_status} (\u57fa\u4e8e{mem.source_steps}\u6b65\u9aa4)\\n\"\n                    if mem.key_findings:\n                        summary += f\"  \u5173\u952e\u53d1\u73b0: {mem.key_findings&#91;0]}\\n\"\n                summary += \"\\n\"\n            \n            return summary\n\n    async def get_failed_attempts_summary(self) -> Dict&#91;str, int]:   #\u8fd4\u56de\u5931\u8d25\u5c1d\u8bd5\u7684\u526f\u672c\uff08\u5b57\u5178\uff09\n        \"\"\"\u83b7\u53d6\u5931\u8d25\u5c1d\u8bd5\u6458\u8981\"\"\"\n        async with self._lock:\n            return self.failed_attempts.copy()   #.copy()\uff1a\u521b\u5efa\u526f\u672c\uff0c\u907f\u514d\u5916\u90e8\u4fee\u6539\u539f\u59cb\u6570\u636e\n            #\u8fd4\u56de\u683c\u5f0f\uff1a{\"\u547d\u4ee41\": \u5931\u8d25\u6b21\u6570, \"\u547d\u4ee42\": \u5931\u8d25\u6b21\u6570}\n\n    async def clear_task_memory(self, task_id: str) -> bool:\n        \"\"\"\u6e05\u9664\u6307\u5b9a\u4efb\u52a1\u7684\u8bb0\u5fc6\"\"\"\n        async with self._lock:\n            if task_id in self.task_steps:  #\u68c0\u67e5\u4efb\u52a1\u662f\u5426\u5b58\u5728\n                del self.task_steps&#91;task_id]   #del self.task_steps&#91;task_id]\uff1a\u5220\u9664\u8be5\u4efb\u52a1\u7684\u6b65\u9aa4\u5217\u8868\n                logger.info(f\"\u5df2\u6e05\u9664\u4efb\u52a1 {task_id} \u7684\u8bb0\u5fc6\")\n                return True\n            return False   #\u8fd4\u56de True \u8868\u793a\u6210\u529f\uff0cFalse \u8868\u793a\u4efb\u52a1\u4e0d\u5b58\u5728\n           #\u53ea\u6e05\u9664\u6b65\u9aa4\uff0c\u4e0d\u6e05\u9664\u5176\u4ed6\u8bb0\u5fc6\n\n    async def clear_all_memory(self) -> None:\n        \"\"\"\u6e05\u9664\u6240\u6709\u8bb0\u5fc6\"\"\"\n        async with self._lock:\n            self.task_steps.clear()  #.clear()\uff1a\u6e05\u7a7a\u6574\u4e2a\u5b57\u5178\/\u5217\u8868,\u6e05\u9664\u6240\u67097\u4e2a\u6570\u636e\u5b58\u50a8\u5bb9\u5668\n            self.compressed_memories.clear()\n            self.key_facts.clear()\n            self.failed_attempts.clear()\n            # \u6e05\u9664\u4f1a\u8bdd\u7ea7\u522b\u7684\u8bb0\u5fc6\n            self.session_memories.clear()\n            self.session_task_mapping.clear()\n            self.analysis_session_mapping.clear()\n            logger.info(\"\u5df2\u6e05\u9664\u6240\u6709\u8bb0\u5fc6\")\n            #\u76f8\u5f53\u4e8e\u91cd\u7f6e\u6574\u4e2a\u7cfb\u7edf\n\n    # ============ \u4f1a\u8bdd\u7ea7\u522b\u7684\u8bb0\u5fc6\u7ba1\u7406\u65b9\u6cd5 ============\n    \n    async def get_session_memory_summary(self, session_id: str) -> Dict&#91;str, Any]:\n        \"\"\"\u83b7\u53d6\u4f1a\u8bdd\u8bb0\u5fc6\u6458\u8981\"\"\"\n        async with self._lock:   #\u68c0\u67e5\u4f1a\u8bdd\u662f\u5426\u5b58\u5728\n            if session_id not in self.session_memories:\n                return {\"error\": f\"\u4f1a\u8bdd {session_id} \u4e0d\u5b58\u5728\"}\n            \n            session_memory = self.session_memories&#91;session_id]  #\u83b7\u53d6\u4f1a\u8bdd\u8bb0\u5fc6\n            \n            # \u6784\u5efa\u4f1a\u8bdd\u6458\u8981\n            summary = {    #\u5305\u542b\u4f1a\u8bdd\u7684\u57fa\u672c\u4fe1\u606f\u548c\u7edf\u8ba1\n                \"session_id\": session_id,\n                \"created_at\": session_memory&#91;\"created_at\"],\n                \"last_activity\": session_memory&#91;\"last_activity\"],\n                \"tasks_count\": len(session_memory&#91;\"tasks\"]),\n                \"compressed_memories_count\": len(session_memory&#91;\"compressed_memories\"]),\n                \"key_facts_count\": len(session_memory&#91;\"key_facts\"]),\n                \"failed_attempts_count\": len(session_memory&#91;\"failed_attempts\"]),\n                \"tasks\": session_memory&#91;\"tasks\"],\n                \"recent_key_facts\": list(session_memory&#91;\"key_facts\"].values())&#91;-5:],  # list(...)&#91;-5:]\uff1a\u53d6\u6700\u540e5\u4e2a\u503c,\u6700\u8fd15\u4e2a\u5173\u952e\u4e8b\u5b9e\n                \"recent_compressed_memories\": &#91;   # \u6700\u8fd1\u538b\u7f29\u8bb0\u5fc6\n                    {\n                        \"memory_id\": mem.memory_id,\n                        \"key_findings\": mem.key_findings&#91;:3],  # \u524d3\u4e2a\u5173\u952e\u53d1\u73b0,\u5217\u8868\u63a8\u5bfc\u5f0f\u751f\u6210\u6700\u8fd13\u4e2a\u538b\u7f29\u8bb0\u5fc6\u7684\u7b80\u5316\u4fe1\u606f\n                        \"current_status\": mem.current_status,\n                        \"source_steps\": mem.source_steps\n                    }\n                    for mem in session_memory&#91;\"compressed_memories\"]&#91;-3:]  # \u6700\u8fd13\u4e2a\u538b\u7f29\u8bb0\u5fc6\n                ],\n                \"failed_attempts\": dict(list(session_memory&#91;\"failed_attempts\"].items())&#91;-5:])  # dict(list(...)&#91;-5:])\uff1a\u53d6\u6700\u540e5\u4e2a\u952e\u503c\u5bf9\u8f6c\u56de\u5b57\u5178,\u6700\u8fd15\u4e2a\u5931\u8d25\u5c1d\u8bd5\n            }\n            \n            return summary\n    \n    async def get_session_compressed_memories(self, session_id: str) -> List&#91;Dict&#91;str, Any]]:\n        \"\"\"\u83b7\u53d6\u4f1a\u8bdd\u7684\u538b\u7f29\u8bb0\u5fc6\"\"\"\n        async with self._lock:  #\u5b89\u5168\u68c0\u67e5\n            if session_id not in self.session_memories:\n                return &#91;]\n            \n            session_memory = self.session_memories&#91;session_id]  #\u8fd4\u56de\u6240\u6709\u538b\u7f29\u8bb0\u5fc6\u7684\u8be6\u7ec6\u4fe1\u606f\n            return &#91; \n                {\n                    \"memory_id\": mem.memory_id,\n                    \"key_findings\": mem.key_findings,\n                    \"failed_attempts\": mem.failed_attempts,\n                    \"current_status\": mem.current_status,\n                    \"next_steps\": mem.next_steps,\n                    \"source_steps\": mem.source_steps\n                }\n                for mem in session_memory&#91;\"compressed_memories\"]\n            ]\n        #\u8fd4\u56de\u5b8c\u6574\u7684\u538b\u7f29\u8bb0\u5fc6\u4fe1\u606f\n        #\u6ce8\u610f\uff1a\u8fd9\u91cc\u6ca1\u6709\u9650\u5236\u6570\u91cf\uff0c\u8fd4\u56de\u6240\u6709\n    \n    async def get_session_key_facts(self, session_id: str) -> Dict&#91;str, str]:\n        \"\"\"\u83b7\u53d6\u4f1a\u8bdd\u7684\u5173\u952e\u4e8b\u5b9e\"\"\"\n        async with self._lock:\n            if session_id not in self.session_memories:\n                return {}\n            \n            return self.session_memories&#91;session_id]&#91;\"key_facts\"].copy()\\\n        #\u7b80\u5355\u8fd4\u56de\u4f1a\u8bdd\u5173\u952e\u4e8b\u5b9e\u7684\u526f\u672c,\u683c\u5f0f\uff1a{\"\u4e8b\u5b9e\u952e\": \"\u4e8b\u5b9e\u5185\u5bb9\"}\n    \n    async def get_session_failed_attempts(self, session_id: str) -> Dict&#91;str, int]:\n        \"\"\"\u83b7\u53d6\u4f1a\u8bdd\u7684\u5931\u8d25\u5c1d\u8bd5\"\"\"\n        async with self._lock:\n            if session_id not in self.session_memories:\n                return {}\n            \n            return self.session_memories&#91;session_id]&#91;\"failed_attempts\"].copy()\n        #\u8fd4\u56de\u683c\u5f0f\uff1a{\"\u547d\u4ee4\": \u5931\u8d25\u6b21\u6570}\n    \n    async def get_session_tasks(self, session_id: str) -> List&#91;Dict&#91;str, Any]]:\n        \"\"\"\u83b7\u53d6\u4f1a\u8bdd\u7684\u6240\u6709\u4efb\u52a1\"\"\"\n        async with self._lock:  # \u5b89\u5168\u68c0\u67e5\n            if session_id not in self.session_memories:\n                return &#91;]\n            \n            tasks = &#91;]  \n            for task_id in self.session_memories&#91;session_id]&#91;\"tasks\"]:  #\u904d\u5386\u4f1a\u8bdd\u7684\u6240\u6709\u4efb\u52a1\n                if task_id in self.task_registry:  #\u68c0\u67e5\u6bcf\u4e2a\u4efb\u52a1\u662f\u5426\u8fd8\u5728\u6ce8\u518c\u8868\u4e2d\n                    task_info = self.task_registry&#91;task_id].copy()  #\u6dfb\u52a0\u6b65\u9aa4\u8ba1\u6570\uff1alen(self.task_steps.get(task_id, &#91;]))\n                    task_info&#91;\"steps_count\"] = len(self.task_steps.get(task_id, &#91;]))  #.get(task_id, &#91;])\uff1a\u5b89\u5168\u83b7\u53d6\uff0c\u5982\u679c\u4e0d\u5b58\u5728\u8fd4\u56de\u7a7a\u5217\u8868\n                    tasks.append(task_info)\n            \n            return tasks\n    \n    async def clear_session_memory(self, session_id: str) -> bool:\n        \"\"\"\u6e05\u9664\u6307\u5b9a\u4f1a\u8bdd\u7684\u8bb0\u5fc6\"\"\"\n        async with self._lock:\n            if session_id not in self.session_memories:\n                return False\n            \n            # \u6e05\u9664\u4f1a\u8bdd\u76f8\u5173\u7684\u4efb\u52a1\n            for task_id in self.session_memories&#91;session_id]&#91;\"tasks\"]:\n                if task_id in self.task_steps:\n                    del self.task_steps&#91;task_id]\n                if task_id in self.task_registry:\n                    del self.task_registry&#91;task_id]\n                if task_id in self.session_task_mapping:\n                    del self.session_task_mapping&#91;task_id]\n            \n            # \u6e05\u9664\u4f1a\u8bdd\u8bb0\u5fc6\n            del self.session_memories&#91;session_id]\n            \n            # \u6e05\u9664\u5206\u6790\u4f1a\u8bdd\u6620\u5c04\n            analysis_sessions_to_remove = &#91;\n                analysis_id for analysis_id, orig_session_id in self.analysis_session_mapping.items()\n                if orig_session_id == session_id\n            ]\n            for analysis_id in analysis_sessions_to_remove:\n                del self.analysis_session_mapping&#91;analysis_id]\n            \n            logger.info(f\"\u5df2\u6e05\u9664\u4f1a\u8bdd {session_id} \u7684\u6240\u6709\u8bb0\u5fc6\")\n            return True\n    \n    async def get_all_sessions(self) -> List&#91;Dict&#91;str, Any]]:\n        \"\"\"\u83b7\u53d6\u6240\u6709\u4f1a\u8bdd\u7684\u6458\u8981\u4fe1\u606f\"\"\"\n        async with self._lock:\n            sessions = &#91;]\n            for session_id, session_memory in self.session_memories.items():\n                sessions.append({\n                    \"session_id\": session_id,\n                    \"created_at\": session_memory&#91;\"created_at\"],\n                    \"last_activity\": session_memory&#91;\"last_activity\"],\n                    \"tasks_count\": len(session_memory&#91;\"tasks\"]),\n                    \"compressed_memories_count\": len(session_memory&#91;\"compressed_memories\"]),\n                    \"key_facts_count\": len(session_memory&#91;\"key_facts\"]),\n                    \"failed_attempts_count\": len(session_memory&#91;\"failed_attempts\"])\n                })\n            \n            # \u6309\u6700\u540e\u6d3b\u52a8\u65f6\u95f4\u6392\u5e8f\n            sessions.sort(key=lambda x: x&#91;\"last_activity\"], reverse=True) #sessions.sort()\uff1a\u539f\u5730\u6392\u5e8f\n            #key=lambda x: x&#91;\"last_activity\"]\uff1a\u6309\u6700\u540e\u6d3b\u52a8\u65f6\u95f4\u6392\u5e8f,reverse=True\uff1a\u964d\u5e8f\uff08\u6700\u65b0\u7684\u5728\u524d\uff09,lambda\uff1a\u533f\u540d\u51fd\u6570\uff0c\u7b80\u5355\u51fd\u6570\u7684\u4e00\u79cd\u5199\u6cd5\n            return sessions\n\n#\u5168\u5c40\u53d8\u91cf _SCHEDULER\n_SCHEDULER: Optional&#91;_TaskScheduler] = None\n'''\n\u521b\u5efa\u4e00\u4e2a\u5168\u5c40\u53d8\u91cf\uff0c\u7c7b\u578b\u662fOptional&#91;_TaskScheduler]\nOptional \u8868\u793a\u53ef\u4ee5\u662f _TaskScheduler \u6216 None\n\u521d\u59cb\u5316\u4e3a None\uff08\u8fd8\u6ca1\u521b\u5efa\u5b9e\u4f8b\uff09\n\u8fd9\u662f\u5355\u4f8b\u6a21\u5f0f\u7684\u8bbe\u8ba1\uff1a\u6574\u4e2a\u7a0b\u5e8f\u53ea\u6709\u4e00\u4e2a\u8c03\u5ea6\u5668\u5b9e\u4f8b\n'''\n\n\n\ndef get_task_scheduler(config: Optional&#91;Any] = None) -> _TaskScheduler:\n    \"\"\"\u83b7\u53d6\u5168\u5c40\u4efb\u52a1\u8c03\u5ea6\u5668\u5355\u4f8b\"\"\"\n    global _SCHEDULER\n    if _SCHEDULER is None:\n        _SCHEDULER = _TaskScheduler(config)\n    return _SCHEDULER\n\n\n# ========\u9501\uff08Lock\uff09\u7684\u8be6\u7ec6\u89e3\u91ca=========\n'''\n1.\u4ec0\u4e48\u662f\u5e76\u53d1\u95ee\u9898\uff1f\n\u60f3\u8c61\u4e00\u4e0b\u8fd9\u4e2a\u573a\u666f\uff1a\n\u4f60\u6709\u4e24\u4e2a\u670b\u53cb\u540c\u65f6\u5728\u4e00\u4e2aExcel\u8868\u683c\u4e0a\u586b\u5199\u6570\u636e\n\u670b\u53cbA\u5728B1\u5355\u5143\u683c\u5199\u4e86\"100\"\n\u670b\u53cbB\u4e5f\u5728B1\u5355\u5143\u683c\u5199\u4e86\"200\"\n\u6700\u540eB1\u5355\u5143\u683c\u91cc\u7684\u503c\u662f\u4ec0\u4e48\uff1f\u53ef\u80fd\u662f100\uff0c\u4e5f\u53ef\u80fd\u662f200\uff0c\u751a\u81f3\u53ef\u80fd\u662f\u4e71\u7801\n\u8fd9\u5c31\u662f\u5e76\u53d1\u51b2\u7a81\uff1a\u591a\u4e2a\u64cd\u4f5c\u540c\u65f6\u4fee\u6539\u540c\u4e00\u4efd\u6570\u636e\uff0c\u7ed3\u679c\u4e0d\u53ef\u9884\u6d4b\u3002\n\n2. \u9501\u7684\u7c7b\u6bd4\n\u9501\u5c31\u50cf\u5395\u6240\u7684\u95e8\u9501\uff1a\n\u4e00\u4e2a\u4eba\u8fdb\u53bb\u540e\uff0c\u628a\u95e8\u9501\u4e0a\n\u5176\u4ed6\u4eba\u60f3\u7528\u5395\u6240\uff0c\u53ea\u80fd\u5728\u95e8\u5916\u7b49\n\u91cc\u9762\u7684\u4eba\u7528\u5b8c\u4e86\uff0c\u5f00\u95e8\u51fa\u6765\n\u4e0b\u4e00\u4e2a\u4eba\u624d\u80fd\u8fdb\u53bb\n\u5728\u4ee3\u7801\u4e2d\uff0c\u9501\u4fdd\u62a4\u5171\u4eab\u8d44\u6e90\uff08\u6bd4\u5982\u5b57\u5178\u3001\u5217\u8868\uff09\uff1a\nself._lock = asyncio.Lock()  # \u521b\u5efa\u4e00\u4e2a\u9501\uff0c\u5c31\u50cf\u88c5\u4e86\u4e00\u628a\u95e8\u9501\n\nasync with self._lock:  # 1. \u68c0\u67e5\u9501\u662f\u5426\u5f00\u7740 2. \u5982\u679c\u5f00\u7740\uff0c\u8fdb\u53bb\u5e76\u9501\u4e0a\u95e8\n    # \u5728\u8fd9\u91cc\u5b89\u5168\u5730\u4fee\u6539\u5171\u4eab\u6570\u636e\n    self.task_registry&#91;task_id] = {...}  # \u53ea\u6709\u6211\u80fd\u6539\u8fd9\u4e2a\u5b57\u5178\n# 3. \u81ea\u52a8\u5f00\u95e8\uff08\u91ca\u653e\u9501\uff09\n\n3. \u5982\u679c\u6ca1\u6709\u9501\u4f1a\u53d1\u751f\u4ec0\u4e48\uff1f\n\u770b\u8fd9\u4e2a\u4f8b\u5b50\uff1a\n# \u4e24\u4e2a\u534f\u7a0b\u540c\u65f6\u6267\u884c\u8fd9\u4e2a\u51fd\u6570\nasync def add_task(self, task_id):\n    # \u6ca1\u6709\u9501\u4fdd\u62a4\n    if task_id not in self.task_registry:\n        # \u5047\u8bbe\u6267\u884c\u5230\u8fd9\u91cc\u65f6\uff0c\u53e6\u4e00\u4e2a\u534f\u7a0b\u4e5f\u6267\u884c\u5230\u4e86\u8fd9\u91cc\n        # \u4e24\u4e2a\u534f\u7a0b\u90fd\u8ba4\u4e3atask_id\u4e0d\u5b58\u5728\n        self.task_registry&#91;task_id] = {\"status\": \"created\"}\n        # \u7ed3\u679c\uff1a\u540c\u4e00\u4e2atask_id\u88ab\u521b\u5efa\u4e86\u4e24\u6b21\uff01\u6570\u636e\u6df7\u4e71\uff01\n        \n4. \u9501\u7684\u5b9e\u9645\u5de5\u4f5c\u6d41\u7a0b\nasync def create_task(self, task_id, purpose):\n    async with self._lock:  # \u2460 \u83b7\u53d6\u9501\uff08\u5982\u679c\u9501\u88ab\u5360\u7528\u5c31\u7b49\u5f85\uff09\n        # \u2461 \u8fdb\u5165\u4e34\u754c\u533a\uff08\u53ea\u6709\u6301\u6709\u9501\u7684\u534f\u7a0b\u80fd\u6267\u884c\u8fd9\u91cc\uff09\n        self.task_registry&#91;task_id] = {\n            \"id\": task_id,\n            \"purpose\": purpose,\n            \"status\": \"created\"\n        }\n        # \u2462 \u64cd\u4f5c\u5b8c\u6210\n    # \u2463 \u81ea\u52a8\u91ca\u653e\u9501\uff0c\u5176\u4ed6\u7b49\u5f85\u7684\u534f\u7a0b\u53ef\u4ee5\u7ee7\u7eed  \n\u65f6\u95f4\u7ebf\u793a\u4f8b\uff1a \n\u65f6\u95f4\u70b91: \u534f\u7a0bA\u83b7\u5f97\u9501\uff0c\u5f00\u59cb\u4fee\u6539\u6570\u636e\n\u65f6\u95f4\u70b92: \u534f\u7a0bB\u5c1d\u8bd5\u83b7\u53d6\u9501\uff0c\u53d1\u73b0\u9501\u88ab\u5360\u7528\uff0c\u8fdb\u5165\u7b49\u5f85\u72b6\u6001\n\u65f6\u95f4\u70b93: \u534f\u7a0bA\u5b8c\u6210\u64cd\u4f5c\uff0c\u91ca\u653e\u9501\n\u65f6\u95f4\u70b94: \u534f\u7a0bB\u83b7\u5f97\u9501\uff0c\u5f00\u59cb\u6267\u884c   \n\n5. \u4e3a\u4ec0\u4e48\u7528 async with\uff1f\nasync with \u662f\u5f02\u6b65\u4e0a\u4e0b\u6587\u7ba1\u7406\u5668\n\u5b83\u786e\u4fdd\uff1a\n\u8fdb\u5165\u65f6\u81ea\u52a8\u83b7\u53d6\u9501\n\u9000\u51fa\u65f6\u81ea\u52a8\u91ca\u653e\u9501\n\u5373\u4f7f\u51fa\u73b0\u5f02\u5e38\u4e5f\u4f1a\u91ca\u653e\u9501\n\u76f8\u5f53\u4e8e\uff1a\n# async with self._lock: \u7b49\u4ef7\u4e8e\uff1a\nawait self._lock.acquire()  # \u83b7\u53d6\u9501\ntry:\n    # \u6267\u884c\u4ee3\u7801\nfinally:\n    self._lock.release()    # \u65e0\u8bba\u5982\u4f55\u90fd\u91ca\u653e\u9501\n'''\n# ========\u5b89\u5168\u68c0\u67e5\u7684\u8be6\u7ec6\u89e3\u91ca==========\n'''\n1. \u4ec0\u4e48\u662f\u5b89\u5168\u68c0\u67e5\uff1f\n\u5b89\u5168\u68c0\u67e5\u5c31\u662f\u5728\u6267\u884c\u64cd\u4f5c\u524d\u5148\u68c0\u67e5\u6761\u4ef6\u662f\u5426\u6ee1\u8db3\uff0c\u9632\u6b62\u51fa\u9519\u3002\n\n2. \u5e38\u89c1\u7684\u9700\u8981\u5b89\u5168\u68c0\u67e5\u7684\u60c5\u51b5\n\u60c5\u51b51\uff1a\u8bbf\u95ee\u4e0d\u5b58\u5728\u7684\u952e\n# \u9519\u8bef\u7684\u5199\u6cd5\uff1a\nvalue = self.task_registry&#91;task_id]  # \u5982\u679ctask_id\u4e0d\u5b58\u5728\uff0c\u4f1a\u629b\u51faKeyError\n\n# \u6b63\u786e\u7684\u5199\u6cd5\uff08\u5b89\u5168\u68c0\u67e5\uff09\uff1a\nif task_id in self.task_registry:  # \u5148\u68c0\u67e5\n    value = self.task_registry&#91;task_id]  # \u518d\u8bbf\u95ee\nelse:\n    value = None  # \u6216\u8005\u8fd4\u56de\u9519\u8bef\u4fe1\u606f\n\u60c5\u51b52\uff1a\u9664\u96f6\u9519\u8bef\n# \u9519\u8bef\u7684\u5199\u6cd5\uff1a\nresult = a \/ b  # \u5982\u679cb=0\uff0c\u4f1a\u629b\u51faZeroDivisionError\n\n# \u6b63\u786e\u7684\u5199\u6cd5\uff08\u5b89\u5168\u68c0\u67e5\uff09\uff1a\nif b != 0:  # \u5148\u68c0\u67e5\n    result = a \/ b  # \u518d\u8ba1\u7b97\nelse:\n    result = None\n\n3. \u4ee3\u7801\u4e2d\u7684\u5177\u4f53\u4f8b\u5b50\nclear_task_memory \u65b9\u6cd5:\nasync def clear_task_memory(self, task_id: str) -> bool:\n    async with self._lock:  # \u2460 \u5148\u83b7\u53d6\u9501\uff08\u4fdd\u8bc1\u5b89\u5168\u8bbf\u95ee\uff09\n        if task_id in self.task_steps:  # \u2461 \u5b89\u5168\u68c0\u67e5\uff1a\u4efb\u52a1\u662f\u5426\u5b58\u5728\uff1f\n            del self.task_steps&#91;task_id]  # \u2462 \u5b89\u5168\u64cd\u4f5c\n            return True\n        return False  # \u2463 \u5982\u679c\u4e0d\u5b58\u5728\uff0c\u8fd4\u56deFalse\n\u4e3a\u4ec0\u4e48\u9700\u8981\u5b89\u5168\u68c0\u67e5\uff1f\n\u5982\u679c\u6709\u4eba\u8bd5\u56fe\u5220\u9664\u4e00\u4e2a\u4e0d\u5b58\u5728\u7684\u4efb\u52a1\n\u6ca1\u6709\u68c0\u67e5\uff1adel self.task_steps&#91;task_id] \u4f1a\u629b\u51fa KeyError\n\u6709\u68c0\u67e5\uff1a\u4f18\u96c5\u5730\u8fd4\u56de False\uff0c\u544a\u8bc9\u8c03\u7528\u8005\"\u5220\u9664\u5931\u8d25\uff0c\u56e0\u4e3a\u4efb\u52a1\u4e0d\u5b58\u5728\"\nget_session_memory_summary \u65b9\u6cd5:\nasync def get_session_memory_summary(self, session_id: str) -> Dict&#91;str, Any]:\n    async with self._lock:\n        if session_id not in self.session_memories:  # \u5b89\u5168\u68c0\u67e5\n            return {\"error\": f\"\u4f1a\u8bdd {session_id} \u4e0d\u5b58\u5728\"}  # \u53cb\u597d\u9519\u8bef\u4fe1\u606f\n        \n        # \u5b89\u5168\u68c0\u67e5\u901a\u8fc7\uff0c\u7ee7\u7eed\u6267\u884c\n        session_memory = self.session_memories&#91;session_id]\n        # ... \u6784\u5efa\u6458\u8981\n   \n4. \u5b89\u5168\u68c0\u67e5\u7684\u5c42\u6b21\n\u7b2c\u4e00\u5c42\uff1a\u5b58\u5728\u6027\u68c0\u67e5: if key in dictionary:  # \u952e\u662f\u5426\u5b58\u5728\uff1f\n\u7b2c\u4e8c\u5c42\uff1a\u7c7b\u578b\u68c0\u67e5:  if isinstance(value, dict):  # \u503c\u662f\u4e0d\u662f\u5b57\u5178\u7c7b\u578b\uff1f\n\u7b2c\u4e09\u5c42\uff1a\u503c\u57df\u68c0\u67e5   if 0 &lt;= index &lt; len(list):  # \u7d22\u5f15\u662f\u5426\u5728\u6709\u6548\u8303\u56f4\u5185\uff1f  \n\u7b2c\u56db\u5c42\uff1a\u4e1a\u52a1\u903b\u8f91\u68c0\u67e5:   if user.has_permission(\"delete\"):  # \u7528\u6237\u662f\u5426\u6709\u5220\u9664\u6743\u9650\uff1f\n\n5. \u4e3a\u4ec0\u4e48\u8981\u5728\u9501\u5185\u505a\u5b89\u5168\u68c0\u67e5\uff1f\n\u8fd9\u662f\u4e00\u4e2a\u975e\u5e38\u91cd\u8981\u7684\u70b9\uff01\u770b\u8fd9\u4e2a\u4f8b\u5b50\uff1a\n# \u274c \u9519\u8bef\u7684\u5199\u6cd5\uff08\u6709\u7ade\u4e89\u6761\u4ef6\uff09\uff1a\nasync def wrong_method(self, task_id):\n    if task_id in self.task_steps:  # \u2460 \u68c0\u67e5\uff08\u6ca1\u6709\u9501\u4fdd\u62a4\uff09\n        # \u2461 \u8fd9\u91cc\u53ef\u80fd\u6709\u5176\u4ed6\u534f\u7a0b\u5220\u9664\u4e86task_id\uff01\n        await asyncio.sleep(0.1)  # \u6a21\u62df\u8017\u65f6\u64cd\u4f5c\n        del self.task_steps&#91;task_id]  # \u2462 \u53ef\u80fd\u629b\u51faKeyError\uff01\n\n# \u2705 \u6b63\u786e\u7684\u5199\u6cd5\uff1a\nasync def correct_method(self, task_id):\n    async with self._lock:  # \u83b7\u53d6\u9501\n        if task_id in self.task_steps:  # \u5728\u9501\u7684\u4fdd\u62a4\u4e0b\u68c0\u67e5\n            # \u5176\u4ed6\u534f\u7a0b\u4e0d\u80fd\u4fee\u6539task_steps\uff0c\u6240\u4ee5\u8fd9\u91cc\u5b89\u5168\n            del self.task_steps&#91;task_id]\n\u5173\u952e\u70b9\uff1a\u4ece\"\u68c0\u67e5\"\u5230\"\u64cd\u4f5c\"\u8fd9\u6bb5\u65f6\u95f4\uff0c\u6570\u636e\u4e0d\u80fd\u88ab\u522b\u4eba\u4fee\u6539\u3002\u9501\u4fdd\u8bc1\u4e86\u8fd9\u6bb5\u65f6\u95f4\u7684\u72ec\u5360\u8bbf\u95ee\u3002\n'''\n# ========\u4e3a\u4ec0\u4e48\u6211\u4eec\u4f1a\u611f\u89c9\u5b89\u5168\u68c0\u67e5\u4e0e\u5f02\u5e38\u5904\u7406\u5f88\u50cf==========\n#\u5b89\u5168\u68c0\u67e5\u548c\u5f02\u5e38\u5904\u7406\u786e\u5b9e\u6709\u76f8\u4f3c\u4e4b\u5904\uff0c\u4f46\u5b83\u4eec\u672c\u8d28\u4e0a\u662f\u4e0d\u540c\u7684\u7f16\u7a0b\u601d\u60f3\u3002\n'''\n\u5b89\u5168\u68c0\u67e5\uff08\u4e3b\u52a8\u9632\u5fa1\uff09\n# \u4e3b\u52a8\uff1a\u5728\u9519\u8bef\u53d1\u751f\u524d\u963b\u6b62\u5b83\nif task_id in self.task_steps:  # \u4e3b\u52a8\u68c0\u67e5\n    del self.task_steps&#91;task_id]  # \u5b89\u5168\u6267\u884c\nelse:\n    print(\"\u4efb\u52a1\u4e0d\u5b58\u5728\")  # \u4f18\u96c5\u5904\u7406\n    \n\u5f02\u5e38\u5904\u7406\uff08\u88ab\u52a8\u54cd\u5e94\uff09\n# \u88ab\u52a8\uff1a\u7b49\u9519\u8bef\u53d1\u751f\u540e\u518d\u5904\u7406\ntry:\n    del self.task_steps&#91;task_id]  # \u53ef\u80fd\u51fa\u9519\nexcept KeyError:  # \u9519\u8bef\u53d1\u751f\u4e86\n    print(\"\u4efb\u52a1\u4e0d\u5b58\u5728\")  # \u5904\u7406\u9519\u8bef\n'''\n#\u4f8b1\uff1a\u8bbf\u95ee\u5b57\u5178\n'''\n\u5b89\u5168\u68c0\u67e5\u65b9\u5f0f\uff1a\n# \u65b9\u5f0f1\uff1a\u5148\u68c0\u67e5\u518d\u8bbf\u95ee\nif key in my_dict:\n    value = my_dict&#91;key]\nelse:\n    value = None\n\n# \u65b9\u5f0f2\uff1a\u4f7f\u7528get\u65b9\u6cd5\uff08\u4e5f\u662f\u4e00\u79cd\u5b89\u5168\u68c0\u67e5\uff09\nvalue = my_dict.get(key, None)  # \u5982\u679ckey\u4e0d\u5b58\u5728\uff0c\u8fd4\u56deNone\n\n\u5f02\u5e38\u5904\u7406\u65b9\u5f0f\uff1a\ntry:\n    value = my_dict&#91;key]\nexcept KeyError:\n    value = None\n'''\n#\u4f8b2\uff1a\u9664\u96f6\u64cd\u4f5c\n'''\n\u5b89\u5168\u68c0\u67e5\uff1a\nif denominator != 0:  # \u4e3b\u52a8\u68c0\u67e5\n    result = numerator \/ denominator\nelse:\n    result = None\n    \n\u5f02\u5e38\u5904\u7406\uff1a\ntry:\n    result = numerator \/ denominator\nexcept ZeroDivisionError:\n    result = None\n'''\n#\u4e3a\u4ec0\u4e48\u5728\u5e76\u53d1\u4ee3\u7801\u4e2d\u591a\u7528\u5b89\u5168\u68c0\u67e5\uff1f\n#1. \u6027\u80fd\u8003\u8651\n'''\n\u5f02\u5e38\u5904\u7406\u6709\u989d\u5916\u5f00\u9500\uff1a\n# Python\u4e2d\u5f02\u5e38\u5904\u7406\u7684\u4ee3\u4ef7\nimport time\n\ndef test_safety_check():\n    start = time.time()\n    for i in range(1000000):\n        if i &lt; 1000000:  # \u603b\u662f\u4e3a\u771f\n            pass\n    return time.time() - start\n\ndef test_exception():\n    start = time.time()\n    for i in range(1000000):\n        try:\n            if i >= 1000000:  # \u6c38\u8fdc\u4e0d\u4f1a\u4e3a\u771f\n                raise IndexError\n        except IndexError:\n            pass\n    return time.time() - start\n\nprint(f\"\u5b89\u5168\u68c0\u67e5: {test_safety_check():.4f}\u79d2\")\nprint(f\"\u5f02\u5e38\u5904\u7406: {test_exception():.4f}\u79d2\")\n# \u5f02\u5e38\u5904\u7406\u901a\u5e38\u61622-10\u500d\n'''\n#2. \u4ee3\u7801\u6e05\u6670\u6027\n'''\n# \u5e76\u53d1\u4ee3\u7801\u4e2d\uff0c\u5b89\u5168\u68c0\u67e5\u66f4\u6e05\u6670\nasync def process(self, task_id):\n    async with self._lock:\n        # \u4e00\u7cfb\u5217\u5b89\u5168\u68c0\u67e5\n        if not self._validate_task(task_id):\n            return {\"error\": \"\u4efb\u52a1\u65e0\u6548\"}\n        if not self._has_permission():\n            return {\"error\": \"\u65e0\u6743\u9650\"}\n        if not self._check_resources():\n            return {\"error\": \"\u8d44\u6e90\u4e0d\u8db3\"}\n        \n        # \u6267\u884c\u64cd\u4f5c\n        return await self._execute(task_id)\n        \n#\u5982\u679c\u7528\u5f02\u5e38\u5904\u7406\uff1a\nasync def process(self, task_id):\n    async with self._lock:\n        try:\n            self._validate_task(task_id)  # \u53ef\u80fd\u629b\u5f02\u5e38\n            self._check_permission()      # \u53ef\u80fd\u629b\u5f02\u5e38\n            self._check_resources()       # \u53ef\u80fd\u629b\u5f02\u5e38\n            return await self._execute(task_id)\n        except ValidationError:\n            return {\"error\": \"\u4efb\u52a1\u65e0\u6548\"}\n        except PermissionError:\n            return {\"error\": \"\u65e0\u6743\u9650\"}\n        except ResourceError:\n            return {\"error\": \"\u8d44\u6e90\u4e0d\u8db3\"}\n'''\n#3. \u63a7\u5236\u6d41\u66f4\u7b80\u5355\n'''\n\u5728\u5e76\u53d1\u4ee3\u7801\u4e2d\uff0c\u5f02\u5e38\u53ef\u80fd\u5bfc\u81f4\u9501\u7684\u91ca\u653e\u95ee\u9898\uff1a\nasync def risky_method(self):\n    await self._lock.acquire()  # \u624b\u52a8\u83b7\u53d6\u9501\n    try:\n        # \u5982\u679c\u8fd9\u91cc\u629b\u5f02\u5e38\uff0c\u53ef\u80fd\u65e0\u6cd5\u6b63\u786e\u91ca\u653e\u9501\n        result = await self._do_something()\n        return result\n    except Exception as e:\n        # \u5904\u7406\u5f02\u5e38\n        raise\n    finally:\n        self._lock.release()  # \u4f46finally\u5757\u53ef\u80fd\u4f1a\u6267\u884c\n\n# \u4f7f\u7528async with\u66f4\u5b89\u5168\uff0c\u4f46\u5b83\u5185\u90e8\u4e5f\u662f\u5f02\u5e38\u5904\u7406\nasync def safe_method(self):\n    async with self._lock:  # \u81ea\u52a8\u7ba1\u7406\u9501\n        return await self._do_something()  # \u4efb\u4f55\u5f02\u5e38\u90fd\u4f1a\u6b63\u786e\u91ca\u653e\u9501\n'''\n#\u60f3\u8c61\u4f60\u5728\u5f00\u8f66\uff1a\n'''\n\u5b89\u5168\u68c0\u67e5\u5c31\u50cf\uff1a\n\u51fa\u53d1\u524d\u68c0\u67e5\u6cb9\u91cf\u3001\u8f6e\u80ce\u3001\u5239\u8f66 \n\u770b\u5230\u7ea2\u706f\u5c31\u505c\u4e0b \n\u9650\u901f\u724c\u524d\u51cf\u901f \n\u4f60\u5728\u4e3b\u52a8\u907f\u514d\u4e8b\u6545\n\n\u5f02\u5e38\u5904\u7406\u5c31\u50cf\uff1a\n\u7a81\u7136\u7206\u80ce\u4e86 \u2192 \u63a7\u5236\u65b9\u5411\u76d8 \u2192 \u6162\u6162\u9760\u8fb9\u505c\u8f66 \n\u5239\u8f66\u5931\u7075\u4e86 \u2192 \u6362\u4f4e\u901f\u6321 \u2192 \u62c9\u624b\u5239 \n\u53d1\u52a8\u673a\u6545\u969c\u706f\u4eae\u4e86 \u2192 \u627e\u6700\u8fd1\u7684\u7ef4\u4fee\u5382 \n\u4f60\u5728\u88ab\u52a8\u5e94\u5bf9\u4e8b\u6545\n\n\u4e24\u8005\u7684\u5173\u7cfb\uff1a\n\u597d\u7684\u53f8\u673a\u4f1a\u540c\u65f6\u4f7f\u7528\u4e24\u79cd\u7b56\u7565\n\u51fa\u53d1\u524d\u5b89\u5168\u68c0\u67e5\uff08\u9884\u9632\uff09\n\u4f46\u4e5f\u8981\u77e5\u9053\u5982\u4f55\u5e94\u5bf9\u7a81\u53d1\u60c5\u51b5\uff08\u5904\u7406\uff09\n'''\n#\u5e76\u53d1\u7f16\u7a0b\u4e2d\u591a\u7528\u5b89\u5168\u68c0\u67e5\n\n#=====\u901a\u7528\u4efb\u52a1\u8c03\u5ea6\u5668 - \u5b8c\u6574\u5c42\u7ea7\u7ed3\u6784========\n'''\n\u901a\u7528\u4efb\u52a1\u8c03\u5ea6\u5668\u7cfb\u7edf\uff08\u5185\u90e8\u89c6\u89d2\uff09\n\u251c\u2500\u2500 \u7b2c1\u5c42\uff1a\u6838\u5fc3\u6570\u636e\u6a21\u578b\uff08Data Models\uff09\n\u2502   \u251c\u2500\u2500 TaskStep\uff08\u4efb\u52a1\u6b65\u9aa4\uff09\n\u2502   \u2502   \u251c\u2500\u2500 step_id: str           # \u6b65\u9aa4\u552f\u4e00\u6807\u8bc6\n\u2502   \u2502   \u251c\u2500\u2500 task_id: str           # \u6240\u5c5e\u4efb\u52a1ID\n\u2502   \u2502   \u251c\u2500\u2500 purpose: str           # \u6b65\u9aa4\u76ee\u7684\n\u2502   \u2502   \u251c\u2500\u2500 content: str           # \u6b65\u9aa4\u5185\u5bb9\n\u2502   \u2502   \u251c\u2500\u2500 output: str            # \u6b65\u9aa4\u8f93\u51fa\n\u2502   \u2502   \u251c\u2500\u2500 analysis: Dict         # \u5206\u6790\u7ed3\u679c\n\u2502   \u2502   \u251c\u2500\u2500 timestamp: float       # \u65f6\u95f4\u6233\n\u2502   \u2502   \u251c\u2500\u2500 success: bool          # \u662f\u5426\u6210\u529f\n\u2502   \u2502   \u2514\u2500\u2500 error: Optional&#91;str]   # \u9519\u8bef\u4fe1\u606f\n\u2502   \u2502\n\u2502   \u2514\u2500\u2500 CompressedMemory\uff08\u538b\u7f29\u8bb0\u5fc6\uff09\n\u2502       \u251c\u2500\u2500 memory_id: str         # \u8bb0\u5fc6\u552f\u4e00\u6807\u8bc6\n\u2502       \u251c\u2500\u2500 key_findings: List&#91;str] # \u5173\u952e\u53d1\u73b0\n\u2502       \u251c\u2500\u2500 failed_attempts: List&#91;str] # \u5931\u8d25\u5c1d\u8bd5\n\u2502       \u251c\u2500\u2500 current_status: str    # \u5f53\u524d\u72b6\u6001\n\u2502       \u251c\u2500\u2500 next_steps: List&#91;str]  # \u5efa\u8bae\u6b65\u9aa4\n\u2502       \u251c\u2500\u2500 source_steps: int      # \u6765\u6e90\u6b65\u9aa4\u6570\n\u2502       \u2514\u2500\u2500 timestamp: float       # \u65f6\u95f4\u6233\n\u2502\n\u251c\u2500\u2500 \u7b2c2\u5c42\uff1a\u6838\u5fc3\u8c03\u5ea6\u5f15\u64ce\uff08_TaskScheduler\uff09\n\u2502   \u251c\u2500\u2500 \u521d\u59cb\u5316\u6a21\u5757\n\u2502   \u2502   \u251c\u2500\u2500 __init__(config)       # \u521d\u59cb\u5316\u914d\u7f6e\u548c\u6570\u636e\u5b58\u50a8\n\u2502   \u2502   \u2514\u2500\u2500 set_llm_config(config) # \u8bbe\u7f6eAI\u6a21\u578b\u914d\u7f6e\n\u2502   \u2502\n\u2502   \u251c\u2500\u2500 \u4efb\u52a1\u751f\u547d\u5468\u671f\u7ba1\u7406\n\u2502   \u2502   \u251c\u2500\u2500 create_task()          # \u521b\u5efa\u65b0\u4efb\u52a1\uff08\u5165\u53e3\u70b9\uff09\n\u2502   \u2502   \u251c\u2500\u2500 add_task_step()        # \u6dfb\u52a0\u4efb\u52a1\u6b65\u9aa4\uff08\u6838\u5fc3\u8bb0\u5f55\uff09\n\u2502   \u2502   \u251c\u2500\u2500 get_task_status()      # \u67e5\u8be2\u4efb\u52a1\u72b6\u6001\n\u2502   \u2502   \u251c\u2500\u2500 get_running_tasks()    # \u83b7\u53d6\u8fd0\u884c\u4e2d\u4efb\u52a1\n\u2502   \u2502   \u251c\u2500\u2500 schedule_parallel_execution() # \u5e76\u884c\u6267\u884c\u8c03\u5ea6\n\u2502   \u2502   \u251c\u2500\u2500 clear_task_memory()    # \u6e05\u9664\u5355\u4e2a\u4efb\u52a1\u8bb0\u5fc6\n\u2502   \u2502   \u2514\u2500\u2500 clear_all_memory()     # \u6e05\u9664\u6240\u6709\u8bb0\u5fc6\n\u2502   \u2502\n\u2502   \u251c\u2500\u2500 \u667a\u80fd\u8bb0\u5fc6\u538b\u7f29\u6a21\u5757\n\u2502   \u2502   \u251c\u2500\u2500 _extract_key_facts()   # \u63d0\u53d6\u5173\u952e\u4e8b\u5b9e\uff08\u9884\u5904\u7406\uff09\n\u2502   \u2502   \u251c\u2500\u2500 _compress_memory()     # \u538b\u7f29\u8bb0\u5fc6\uff08\u4e3b\u6d41\u7a0b\uff09\n\u2502   \u2502   \u251c\u2500\u2500 _build_compression_prompt() # \u6784\u5efaAI\u63d0\u793a\n\u2502   \u2502   \u2514\u2500\u2500 _call_llm_compression() # \u8c03\u7528AI\u6a21\u578b\n\u2502   \u2502\n\u2502   \u251c\u2500\u2500 \u67e5\u8be2\u4e0e\u6458\u8981\u6a21\u5757\n\u2502   \u2502   \u251c\u2500\u2500 get_task_memory_summary()  # \u83b7\u53d6\u4efb\u52a1\u8bb0\u5fc6\u6458\u8981\n\u2502   \u2502   \u251c\u2500\u2500 get_global_memory_summary() # \u83b7\u53d6\u5168\u5c40\u8bb0\u5fc6\u6458\u8981\n\u2502   \u2502   \u2514\u2500\u2500 get_failed_attempts_summary() # \u83b7\u53d6\u5931\u8d25\u5c1d\u8bd5\u6458\u8981\n\u2502   \u2502\n\u2502   \u2514\u2500\u2500 \u4f1a\u8bdd\u7ea7\u522b\u8bb0\u5fc6\u7ba1\u7406\uff08\u6269\u5c55\u5c42\uff09\n\u2502       \u251c\u2500\u2500 get_session_memory_summary()    # \u83b7\u53d6\u4f1a\u8bdd\u8bb0\u5fc6\u6458\u8981\n\u2502       \u251c\u2500\u2500 get_session_compressed_memories() # \u83b7\u53d6\u4f1a\u8bdd\u538b\u7f29\u8bb0\u5fc6\n\u2502       \u251c\u2500\u2500 get_session_key_facts()         # \u83b7\u53d6\u4f1a\u8bdd\u5173\u952e\u4e8b\u5b9e\n\u2502       \u251c\u2500\u2500 get_session_failed_attempts()   # \u83b7\u53d6\u4f1a\u8bdd\u5931\u8d25\u5c1d\u8bd5\n\u2502       \u251c\u2500\u2500 get_session_tasks()             # \u83b7\u53d6\u4f1a\u8bdd\u6240\u6709\u4efb\u52a1\n\u2502       \u251c\u2500\u2500 clear_session_memory()          # \u6e05\u9664\u4f1a\u8bdd\u8bb0\u5fc6\n\u2502       \u2514\u2500\u2500 get_all_sessions()              # \u83b7\u53d6\u6240\u6709\u4f1a\u8bdd\n\u2502\n\u251c\u2500\u2500 \u7b2c3\u5c42\uff1a\u6570\u636e\u5b58\u50a8\u7ed3\u6784\n\u2502   \u251c\u2500\u2500 \u4efb\u52a1\u6ce8\u518c\u8868\uff08task_registry\uff09\n\u2502   \u2502   \u251c\u2500\u2500 \u7ed3\u6784\uff1aDict&#91;str, Dict]\n\u2502   \u2502   \u251c\u2500\u2500 \u952e\uff1atask_id\n\u2502   \u2502   \u2514\u2500\u2500 \u503c\uff1a\u4efb\u52a1\u5143\u6570\u636e\uff08id, purpose, status\u7b49\uff09\n\u2502   \u2502\n\u2502   \u251c\u2500\u2500 \u4efb\u52a1\u6b65\u9aa4\u5386\u53f2\uff08task_steps\uff09\n\u2502   \u2502   \u251c\u2500\u2500 \u7ed3\u6784\uff1aDict&#91;str, List&#91;TaskStep]]\n\u2502   \u2502   \u251c\u2500\u2500 \u952e\uff1atask_id\n\u2502   \u2502   \u2514\u2500\u2500 \u503c\uff1a\u8be5\u4efb\u52a1\u7684\u6240\u6709\u6b65\u9aa4\u5217\u8868\n\u2502   \u2502\n\u2502   \u251c\u2500\u2500 \u538b\u7f29\u8bb0\u5fc6\u5e93\uff08compressed_memories\uff09\n\u2502   \u2502   \u251c\u2500\u2500 \u7ed3\u6784\uff1aList&#91;CompressedMemory]\n\u2502   \u2502   \u2514\u2500\u2500 \u5185\u5bb9\uff1a\u6240\u6709\u538b\u7f29\u540e\u7684\u8bb0\u5fc6\u5757\n\u2502   \u2502\n\u2502   \u251c\u2500\u2500 \u5173\u952e\u4e8b\u5b9e\u5b58\u50a8\uff08key_facts\uff09\n\u2502   \u2502   \u251c\u2500\u2500 \u7ed3\u6784\uff1aDict&#91;str, str]\n\u2502   \u2502   \u251c\u2500\u2500 \u952e\uff1a\u683c\u5f0f\u5316\u7684\u4e8b\u5b9e\u952e\n\u2502   \u2502   \u2514\u2500\u2500 \u503c\uff1a\u4e8b\u5b9e\u5185\u5bb9\n\u2502   \u2502\n\u2502   \u251c\u2500\u2500 \u5931\u8d25\u5c1d\u8bd5\u8ba1\u6570\uff08failed_attempts\uff09\n\u2502   \u2502   \u251c\u2500\u2500 \u7ed3\u6784\uff1aDict&#91;str, int]\n\u2502   \u2502   \u251c\u2500\u2500 \u952e\uff1a\u5931\u8d25\u7684\u64cd\u4f5c\u5185\u5bb9\n\u2502   \u2502   \u2514\u2500\u2500 \u503c\uff1a\u5931\u8d25\u6b21\u6570\n\u2502   \u2502\n\u2502   \u2514\u2500\u2500 \u4f1a\u8bdd\u7ea7\u522b\u5b58\u50a8\uff08\u6269\u5c55\uff09\n\u2502       \u251c\u2500\u2500 session_memories       # \u4f1a\u8bdd\u8bb0\u5fc6\uff1asession_id -> \u8bb0\u5fc6\u6570\u636e\n\u2502       \u251c\u2500\u2500 session_task_mapping   # \u4efb\u52a1\u5230\u4f1a\u8bdd\u7684\u6620\u5c04\n\u2502       \u2514\u2500\u2500 analysis_session_mapping # \u5206\u6790\u4f1a\u8bdd\u5230\u539f\u59cb\u4f1a\u8bdd\u7684\u6620\u5c04\n\u2502\n\u251c\u2500\u2500 \u7b2c4\u5c42\uff1a\u914d\u7f6e\u7cfb\u7edf\n\u2502   \u251c\u2500\u2500 \u6765\u6e90\uff1a\u5916\u90e8\u914d\u7f6e\u6a21\u5757\n\u2502   \u251c\u2500\u2500 \u914d\u7f6e\u53c2\u6570\uff1a\n\u2502   \u2502   \u251c\u2500\u2500 max_steps: int          # \u6700\u5927\u4fdd\u5b58\u6b65\u9aa4\u6570\n\u2502   \u2502   \u251c\u2500\u2500 compression_threshold: int # \u538b\u7f29\u89e6\u53d1\u9608\u503c\n\u2502   \u2502   \u251c\u2500\u2500 keep_last_steps: int    # \u538b\u7f29\u540e\u4fdd\u7559\u6b65\u9aa4\u6570\n\u2502   \u2502   \u251c\u2500\u2500 output_summary_length: int # \u8f93\u51fa\u6458\u8981\u957f\u5ea6\n\u2502   \u2502   \u251c\u2500\u2500 step_output_display_length: int # \u6b65\u9aa4\u8f93\u51fa\u663e\u793a\u957f\u5ea6\n\u2502   \u2502   \u251c\u2500\u2500 key_facts_compression_limit: int # \u5173\u952e\u4e8b\u5b9e\u538b\u7f29\u9650\u5236\n\u2502   \u2502   \u251c\u2500\u2500 key_facts_summary_limit: int # \u5173\u952e\u4e8b\u5b9e\u6458\u8981\u9650\u5236\n\u2502   \u2502   \u251c\u2500\u2500 compressed_memory_summary_limit: int # \u538b\u7f29\u8bb0\u5fc6\u6458\u8981\u9650\u5236\n\u2502   \u2502   \u251c\u2500\u2500 key_findings_display_limit: int # \u5173\u952e\u53d1\u73b0\u663e\u793a\u9650\u5236\n\u2502   \u2502   \u251c\u2500\u2500 failed_attempts_display_limit: int # \u5931\u8d25\u5c1d\u8bd5\u663e\u793a\u9650\u5236\n\u2502   \u2502   \u2514\u2500\u2500 compressed_memory_global_limit: int # \u5168\u5c40\u538b\u7f29\u8bb0\u5fc6\u9650\u5236\n\u2502   \u2502\n\u2502   \u2514\u2500\u2500 LLM\u914d\u7f6e\uff08\u53ef\u9009\uff09\uff1a\n\u2502       \u251c\u2500\u2500 model: str              # AI\u6a21\u578b\u540d\u79f0\n\u2502       \u251c\u2500\u2500 api_key: str           # API\u5bc6\u94a5\n\u2502       \u2514\u2500\u2500 api_base: str          # API\u57fa\u7840\u5730\u5740\n\u2502\n\u251c\u2500\u2500 \u7b2c5\u5c42\uff1a\u5e76\u53d1\u5b89\u5168\u673a\u5236\n\u2502   \u251c\u2500\u2500 \u9501\u673a\u5236\uff08_lock: asyncio.Lock\uff09\n\u2502   \u2502   \u251c\u2500\u2500 \u4f5c\u7528\u8303\u56f4\uff1a\u6240\u6709\u4fee\u6539\u5171\u4eab\u6570\u636e\u7684\u65b9\u6cd5\n\u2502   \u2502   \u251c\u2500\u2500 \u4f7f\u7528\u65b9\u5f0f\uff1aasync with self._lock:\n\u2502   \u2502   \u2514\u2500\u2500 \u4fdd\u62a4\u7684\u6570\u636e\uff1a\n\u2502   \u2502       \u251c\u2500\u2500 task_registry\n\u2502   \u2502       \u251c\u2500\u2500 task_steps\n\u2502   \u2502       \u251c\u2500\u2500 compressed_memories\n\u2502   \u2502       \u251c\u2500\u2500 key_facts\n\u2502   \u2502       \u251c\u2500\u2500 failed_attempts\n\u2502   \u2502       \u2514\u2500\u2500 \u6240\u6709\u4f1a\u8bdd\u76f8\u5173\u6570\u636e\n\u2502   \u2502\n\u2502   \u2514\u2500\u2500 \u5b89\u5168\u68c0\u67e5\u7b56\u7565\n\u2502       \u251c\u2500\u2500 \u5b58\u5728\u6027\u68c0\u67e5\uff1aif key in dictionary\n\u2502       \u251c\u2500\u2500 \u7c7b\u578b\u68c0\u67e5\uff1aisinstance()\n\u2502       \u251c\u2500\u2500 \u8fb9\u754c\u68c0\u67e5\uff1alen()\u548c\u7d22\u5f15\u8303\u56f4\n\u2502       \u2514\u2500\u2500 \u4e1a\u52a1\u903b\u8f91\u68c0\u67e5\uff1a\u81ea\u5b9a\u4e49\u9a8c\u8bc1\n\u2502\n\u251c\u2500\u2500 \u7b2c6\u5c42\uff1a\u65e5\u5fd7\u4e0e\u76d1\u63a7\n\u2502   \u251c\u2500\u2500 \u65e5\u5fd7\u8bb0\u5f55\u5668\uff08logger\uff09\n\u2502   \u251c\u2500\u2500 \u5173\u952e\u65e5\u5fd7\u70b9\uff1a\n\u2502   \u2502   \u251c\u2500\u2500 \u4efb\u52a1\u521b\u5efa\/\u5b8c\u6210\n\u2502   \u2502   \u251c\u2500\u2500 \u8bb0\u5fc6\u538b\u7f29\u5f00\u59cb\/\u7ed3\u675f\n\u2502   \u2502   \u251c\u2500\u2500 AI\u8c03\u7528\u6210\u529f\/\u5931\u8d25\n\u2502   \u2502   \u251c\u2500\u2500 \u6e05\u7406\u64cd\u4f5c\n\u2502   \u2502   \u2514\u2500\u2500 \u9519\u8bef\u548c\u5f02\u5e38\n\u2502   \u2502\n\u2502   \u2514\u2500\u2500 \u76d1\u63a7\u6307\u6807\uff1a\n\u2502       \u251c\u2500\u2500 \u4efb\u52a1\u6570\u91cf\u7edf\u8ba1\n\u2502       \u251c\u2500\u2500 \u6b65\u9aa4\u603b\u6570\n\u2502       \u251c\u2500\u2500 \u538b\u7f29\u8bb0\u5fc6\u5757\u6570\n\u2502       \u251c\u2500\u2500 \u5173\u952e\u4e8b\u5b9e\u6570\n\u2502       \u2514\u2500\u2500 \u5931\u8d25\u5c1d\u8bd5\u6570\n\u2502\n\u2514\u2500\u2500 \u7b2c7\u5c42\uff1a\u5916\u90e8\u4f9d\u8d56\u4e0e\u96c6\u6210\n    \u251c\u2500\u2500 \u5f02\u6b65\u8fd0\u884c\u65f6\uff1aasyncio\n    \u251c\u2500\u2500 AI\u6a21\u578b\u8c03\u7528\uff1alitellm\uff08\u6216\u7c7b\u4f3c\u5e93\uff09\n    \u251c\u2500\u2500 \u552f\u4e00\u6807\u8bc6\u751f\u6210\uff1auuid\n    \u251c\u2500\u2500 \u65f6\u95f4\u5904\u7406\uff1atime, datetime\n    \u251c\u2500\u2500 \u6570\u636e\u5e8f\u5217\u5316\uff1ajson\n    \u2514\u2500\u2500 \u7c7b\u578b\u6ce8\u89e3\u652f\u6301\uff1atyping\n'''\n\n# ========API\u63a5\u53e3\u6620\u5c04\uff08\u5916\u90e8\u89c6\u89d2\uff09=========\n'''\nAPI\u5c42\uff08\u5047\u8bbe\u6709Web\u5c01\u88c5\uff09\n\u251c\u2500\u2500 \u4efb\u52a1\u7ea7\u522b\u63a5\u53e3\n\u2502   \u251c\u2500\u2500 POST \/tasks                      \u2192 create_task()\n\u2502   \u251c\u2500\u2500 GET \/tasks                       \u2192 \u83b7\u53d6\u6240\u6709\u4efb\u52a1\uff08\u9700\u8981\u989d\u5916\u5b9e\u73b0\uff09\n\u2502   \u251c\u2500\u2500 GET \/tasks\/{task_id}             \u2192 get_task_status()\n\u2502   \u251c\u2500\u2500 GET \/tasks\/{task_id}\/memory      \u2192 get_task_memory_summary()\n\u2502   \u251c\u2500\u2500 POST \/tasks\/{task_id}\/steps      \u2192 add_task_step()\n\u2502   \u2514\u2500\u2500 DELETE \/tasks\/{task_id}\/memory   \u2192 clear_task_memory()\n\u2502\n\u251c\u2500\u2500 \u5e76\u884c\u6267\u884c\u63a5\u53e3\n\u2502   \u2514\u2500\u2500 POST \/tasks\/parallel             \u2192 schedule_parallel_execution()\n\u2502\n\u251c\u2500\u2500 \u4f1a\u8bdd\u7ea7\u522b\u63a5\u53e3\n\u2502   \u251c\u2500\u2500 GET \/sessions                    \u2192 get_all_sessions()\n\u2502   \u251c\u2500\u2500 GET \/sessions\/{session_id}       \u2192 get_session_memory_summary()\n\u2502   \u251c\u2500\u2500 GET \/sessions\/{session_id}\/compressed_memories \u2192 get_session_compressed_memories()\n\u2502   \u251c\u2500\u2500 GET \/sessions\/{session_id}\/key_facts \u2192 get_session_key_facts()\n\u2502   \u251c\u2500\u2500 GET \/sessions\/{session_id}\/failed_attempts \u2192 get_session_failed_attempts()\n\u2502   \u251c\u2500\u2500 GET \/sessions\/{session_id}\/tasks \u2192 get_session_tasks()\n\u2502   \u2514\u2500\u2500 DELETE \/sessions\/{session_id}    \u2192 clear_session_memory()\n\u2502\n\u2514\u2500\u2500 \u5168\u5c40\u7ea7\u522b\u63a5\u53e3\n    \u251c\u2500\u2500 GET \/memory\/global               \u2192 get_global_memory_summary()\n    \u251c\u2500\u2500 GET \/memory\/failed-attempts      \u2192 get_failed_attempts_summary()\n    \u251c\u2500\u2500 GET \/memory\/running-tasks        \u2192 get_running_tasks()\n    \u2514\u2500\u2500 DELETE \/memory\/global            \u2192 clear_all_memory()\n'''\n\n# ========\u6620\u5c04\u5173\u7cfb\uff1a\u4ece\u4ee3\u7801\u5230API==========\n# \u8ba9\u6211\u5c55\u793a\u5b83\u4eec\u4e4b\u95f4\u7684\u6620\u5c04\u5173\u7cfb\uff1a\n'''\n\u4ee3\u7801\u65b9\u6cd5                                 \u2192 RESTful\u63a5\u53e3\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\ncreate_task(task_id, purpose)            \u2192 POST \/tasks\n                                           Body: {task_id, purpose}\n                                           \nget_task_status(task_id)                 \u2192 GET \/tasks\/{task_id}\n                                           \nadd_task_step(task_id, step)             \u2192 POST \/tasks\/{task_id}\/steps\n                                           Body: {step\u6570\u636e}\n                                           \nget_task_memory_summary(task_id)         \u2192 GET \/tasks\/{task_id}\/memory\n                                           \nschedule_parallel_execution(tasks)       \u2192 POST \/tasks\/parallel\n                                           Body: {\u4efb\u52a1\u5217\u8868}\n                                           \nget_all_sessions()                       \u2192 GET \/sessions\n                                           \nget_session_memory_summary(session_id)   \u2192 GET \/sessions\/{session_id}\n                                           \nclear_all_memory()                       \u2192 DELETE \/memory\/global\n'''<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">toolkit_manager.py<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>#!\/usr\/bin\/env python3\n# -*- coding: utf-8 -*-\n\"\"\"\n#!\/usr\/bin\/env python3 - \u544a\u8bc9\u7535\u8111\u7528python3\u6765\u8fd0\u884c\u8fd9\u4e2a\u6587\u4ef6\n# -*- coding: utf-8 -*- - \u544a\u8bc9\u7535\u8111\u8fd9\u4e2a\u6587\u4ef6\u4f7f\u7528UTF-8\u7f16\u7801\uff08\u53ef\u4ee5\u652f\u6301\u4e2d\u6587\uff09\n\u5de5\u5177\u5305\u7ba1\u7406\u5668 - \u7ba1\u7406agentserver\u7684\u5de5\u5177\u5305\n\"\"\"\n\nimport yaml\nimport logging\nfrom pathlib import Path\nfrom typing import Dict, Any, List, Optional\n\nfrom .tools import FileEditToolkit, AsyncBaseToolkit, ToolkitConfig\n'''\n\u8fd9\u4e9b\u5bfc\u5165\u90fd\u662f\u4ec0\u4e48\uff1a\n  yaml - \u7528\u6765\u8bfb\u53d6YAML\u683c\u5f0f\u7684\u914d\u7f6e\u6587\u4ef6\uff08YAML\u662f\u4e00\u79cd\u5199\u914d\u7f6e\u6587\u4ef6\u7684\u683c\u5f0f\uff09\n  logging - \u7528\u6765\u8bb0\u5f55\u7a0b\u5e8f\u8fd0\u884c\u65f6\u7684\u4fe1\u606f\uff08\u6bd4\u5982\u9519\u8bef\u3001\u8b66\u544a\uff09\n  Path - \u7528\u6765\u5904\u7406\u6587\u4ef6\u8def\u5f84\uff08\u6bd4\u5982\u627e\u5230\u67d0\u4e2a\u6587\u4ef6\u5939\uff09\n  typing \u91cc\u7684\u4e1c\u897f - \u53ea\u662f\u7528\u6765\u544a\u8bc9\u7535\u8111\u6570\u636e\u7c7b\u578b\uff0c\u4e0d\u4f1a\u771f\u7684\u505a\u4ec0\u4e48\n  \u4ece\u5f53\u524d\u6587\u4ef6\u5939\u7684tools\u6587\u4ef6\u91cc\u5bfc\u5165\u4e09\u4e2a\u4e1c\u897f\uff1a\n     FileEditToolkit - \u6587\u4ef6\u7f16\u8f91\u5de5\u5177\u5305\n     AsyncBaseToolkit - \u6240\u6709\u5de5\u5177\u5305\u7684\u57fa\u7840\u7c7b\n     ToolkitConfig - \u5de5\u5177\u5305\u7684\u914d\u7f6e\n'''\n\n#\u65e5\u5fd7\u8bb0\u5f55\u5668\nlogger = logging.getLogger(__name__)\n#\u8fd9\u662f\u4ec0\u4e48\uff1a\u521b\u5efa\u4e00\u4e2alogger\uff08\u8bb0\u5f55\u5668\uff09\uff0c\u7528\u6765\u5199\u65e5\u5fd7,__name__ \u4f1a\u81ea\u52a8\u53d8\u6210\u8fd9\u4e2a\u6587\u4ef6\u7684\u540d\u5b57\n\nclass ToolkitManager:\n    \"\"\"\u5de5\u5177\u5305\u7ba1\u7406\u5668\"\"\"\n    \n    #1. \u521d\u59cb\u5316\u65b9\u6cd5 __init__\n    def __init__(self, config_dir: str = \"agentserver\/configs\"):\n        self.config_dir = Path(config_dir)\n        self.toolkits: Dict&#91;str, AsyncBaseToolkit] = {}\n        self.toolkit_configs: Dict&#91;str, Dict&#91;str, Any]] = {}\n        \n        # \u6ce8\u518c\u53ef\u7528\u7684\u5de5\u5177\u5305\u7c7b\u578b\n        self.toolkit_types = {\n            \"file_edit\": FileEditToolkit,\n        }\n        \n        # \u52a0\u8f7d\u914d\u7f6e\n        self._load_configs()\n        '''\n        \u8fd9\u4e2a\u65b9\u6cd5\u662f\u505a\u4ec0\u4e48\u7684\uff1a\n             \u5f53\u521b\u5efa\u4e00\u4e2aToolkitManager\u5bf9\u8c61\u65f6\uff0c\u8fd9\u4e2a\u65b9\u6cd5\u4f1a\u81ea\u52a8\u8fd0\u884c\n            \u5b83\u505a\u4e864\u4ef6\u4e8b\uff1a\n               1.\u8bbe\u7f6e\u914d\u7f6e\u6587\u4ef6\u5939\u8def\u5f84\n               2.\u521b\u5efa\u4e24\u4e2a\u7a7a\u5b57\u5178\uff08\u5c31\u50cf\u4e24\u4e2a\u7a7a\u76d2\u5b50\uff09\uff1a\n                    toolkits\uff1a\u653e\u5df2\u7ecf\u521b\u5efa\u597d\u7684\u5de5\u5177\u5305\n                    toolkit_configs\uff1a\u653e\u4ece\u914d\u7f6e\u6587\u4ef6\u8bfb\u53d6\u7684\u914d\u7f6e\u4fe1\u606f\n               3.\u6ce8\u518c\u53ef\u7528\u7684\u5de5\u5177\u5305\u7c7b\u578b\uff08\u73b0\u5728\u53ea\u6709\u4e00\u79cd\uff1afile_edit\uff09\n               4.\u8c03\u7528_load_configs()\u65b9\u6cd5\u52a0\u8f7d\u914d\u7f6e\n        '''\n    #\u52a0\u8f7d\u914d\u7f6e\u65b9\u6cd5\n    def _load_configs(self):\n        \"\"\"\u52a0\u8f7d\u5de5\u5177\u5305\u914d\u7f6e\"\"\"\n        #1.\u68c0\u67e5\u6587\u4ef6\u5939\u662f\u5426\u5b58\u5728\n        if not self.config_dir.exists():  #\u5148\u68c0\u67e5\u914d\u7f6e\u6587\u4ef6\u5939\u662f\u5426\u5b58\u5728\n            logger.warning(f\"\u914d\u7f6e\u76ee\u5f55\u4e0d\u5b58\u5728: {self.config_dir}\")  #\u5982\u679c\u4e0d\u5b58\u5728\uff0c\u8bb0\u5f55\u8b66\u544a\u4fe1\u606f\uff0c\u7136\u540e\u76f4\u63a5\u8fd4\u56de\uff08\u4e0d\u7ee7\u7eed\u6267\u884c\uff09\n            return\n         \n         #2.\u904d\u5386\u6240\u6709YAML\u6587\u4ef6   \n        for config_file in self.config_dir.glob(\"*.yaml\"):  #\u627e\u5230\u6587\u4ef6\u5939\u91cc\u6240\u6709\u4ee5.yaml\u7ed3\u5c3e\u7684\u6587\u4ef6,\u5bf9\u6bcf\u4e2a\u6587\u4ef6\u90fd\u505a\u4e0b\u9762\u7684\u64cd\u4f5c\n            try:\n                #3.\u8bfb\u53d6\u6587\u4ef6\u5185\u5bb9\n                with open(config_file, 'r', encoding='utf-8') as f: #\u6253\u5f00\u6587\u4ef6\uff08'r'\u8868\u793a\u53ea\u8bfb\uff09\n                    config = yaml.safe_load(f)                      #\u7528yaml\u5e93\u8bfb\u53d6\u5185\u5bb9\uff0c\u8f6c\u6210Python\u80fd\u7406\u89e3\u7684\u6570\u636e\n                #\u4fdd\u5b58\u914d\u7f6e\u4fe1\u606f\n                toolkit_name = config.get('name', config_file.stem)  #\u83b7\u53d6\u914d\u7f6e\u91cc\u7684\u540d\u5b57\uff0c\u5982\u679c\u6ca1\u6709\u5c31\u7528\u6587\u4ef6\u540d\uff08\u53bb\u6389.yaml\u7684\u90e8\u5206\uff09\n                self.toolkit_configs&#91;toolkit_name] = config          #\u628a\u914d\u7f6e\u4fdd\u5b58\u5230toolkit_configs\u5b57\u5178\u91cc\n                logger.info(f\"\u52a0\u8f7d\u5de5\u5177\u5305\u914d\u7f6e: {toolkit_name}\")\n            #5.\u9519\u8bef\u5904\u7406\n            except Exception as e:\n                logger.error(f\"\u52a0\u8f7d\u914d\u7f6e\u6587\u4ef6\u5931\u8d25 {config_file}: {e}\")   #\u5982\u679c\u4e0a\u9762\u4efb\u4f55\u4e00\u6b65\u51fa\u9519\u4e86\uff0c\u5c31\u8bb0\u5f55\u9519\u8bef\u4fe1\u606f\uff0c\u4f46\u7a0b\u5e8f\u4e0d\u4f1a\u5d29\u6e83\n'''\n\u8fd9\u4e2a\u4ee3\u7801\u6587\u4ef6\u521b\u5efa\u4e86\u4e00\u4e2a\u5de5\u5177\u5305\u7ba1\u7406\u5668\uff0c\u5b83\uff1a\u4ece\u6307\u5b9a\u6587\u4ef6\u5939\u8bfb\u53d6\u914d\u7f6e\u6587\u4ef6\uff08YAML\u683c\u5f0f\uff09,\u7ba1\u7406\u4e0d\u540c\u7c7b\u578b\u7684\u5de5\u5177\u5305,\u76ee\u524d\u53ea\u652f\u6301\u4e00\u79cd\u5de5\u5177\u5305\uff1a\u6587\u4ef6\u7f16\u8f91\u5de5\u5177\u5305\n\u5b83\u91cc\u9762\u6709\u54ea\u4e9b\u51fd\u6570\uff1a__init__ - \u521d\u59cb\u5316\u51fd\u6570\uff08\u81ea\u52a8\u8fd0\u884c\uff09,_load_configs - \u79c1\u6709\u65b9\u6cd5\uff08\u5185\u90e8\u4f7f\u7528\uff09\uff0c\u52a0\u8f7d\u914d\u7f6e\n\u7528\u4e86\u54ea\u4e9b\u5916\u90e8\u51fd\u6570\uff1aPath.exists() - \u68c0\u67e5\u8def\u5f84\u662f\u5426\u5b58\u5728,Path.glob() - \u67e5\u627e\u5339\u914d\u7684\u6587\u4ef6,open() - \u6253\u5f00\u6587\u4ef6,yaml.safe_load() - \u5b89\u5168\u5730\u8bfb\u53d6YAML\u6587\u4ef6,\u5404\u79cd\u65e5\u5fd7\u51fd\u6570\uff1awarning(), info(), error()\n'''\n    \n    def get_toolkit(self, name: str) -> Optional&#91;AsyncBaseToolkit]:\n        #\u8fd9\u4e2a\u65b9\u6cd5\u662f\u505a\u4ec0\u4e48\u7684\uff1a\u6839\u636e\u540d\u5b57\u83b7\u53d6\u4e00\u4e2a\u5de5\u5177\u5305,\u5982\u679c\u5de5\u5177\u5305\u5df2\u7ecf\u5b58\u5728\uff0c\u76f4\u63a5\u8fd4\u56de,\u5982\u679c\u4e0d\u5b58\u5728\uff0c\u6839\u636e\u914d\u7f6e\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\n        \"\"\"\u83b7\u53d6\u5de5\u5177\u5305\u5b9e\u4f8b\"\"\"\n        #1.\u68c0\u67e5\u662f\u5426\u5df2\u7ecf\u521b\u5efa\u8fc7\n        if name in self.toolkits:         #\u5148\u68c0\u67e5self.toolkits\u5b57\u5178\u91cc\u6709\u6ca1\u6709\u8fd9\u4e2a\u5de5\u5177\u5305\n            return self.toolkits&#91;name]    #\u5982\u679c\u6709\uff0c\u76f4\u63a5\u8fd4\u56de\uff08\u4e0d\u518d\u521b\u5efa\u65b0\u7684\uff09\n        \n        #\u68c0\u67e5\u914d\u7f6e\u662f\u5426\u5b58\u5728    \n        if name not in self.toolkit_configs:   #\u5982\u679c\u914d\u7f6e\u91cc\u4e5f\u6ca1\u6709\u8fd9\u4e2a\u5de5\u5177\u5305\uff0c\u8bb0\u5f55\u9519\u8bef\u5e76\u8fd4\u56deNone\n            logger.error(f\"\u5de5\u5177\u5305\u914d\u7f6e\u4e0d\u5b58\u5728: {name}\")  \n            return None   \n            \n        #3.\u83b7\u53d6\u914d\u7f6e\u4fe1\u606f\n        config_data = self.toolkit_configs&#91;name]             #\u4ece\u914d\u7f6e\u5b57\u5178\u91cc\u53d6\u51fa\u8fd9\u4e2a\u5de5\u5177\u5305\u7684\u914d\u7f6e\n        toolkit_type = config_data.get('mode', 'builtin')    #\u83b7\u53d6\u5de5\u5177\u5305\u7684\u6a21\u5f0f\uff08\u9ed8\u8ba4\u662f'builtin'\uff0c\u4e5f\u5c31\u662f\u5185\u7f6e\u7684\uff09\n        \n        #4.\u521b\u5efa\u5185\u7f6e\u5de5\u5177\u5305\n        if toolkit_type == 'builtin':                       #\u5982\u679c\u662f\u5185\u7f6e\u6a21\u5f0f\uff0c\u4ecetoolkit_types\u5b57\u5178\u91cc\u627e\u5230\u5bf9\u5e94\u7684\u7c7b\n            toolkit_class = self.toolkit_types.get(name)\n            if not toolkit_class:                           #\u5982\u679c\u627e\u4e0d\u5230\uff0c\u8bb0\u5f55\u9519\u8bef\u5e76\u8fd4\u56de\n                logger.error(f\"\u672a\u627e\u5230\u5de5\u5177\u5305\u7c7b\u578b: {name}\")\n                return None\n             \n            #5.\u521b\u5efa\u914d\u7f6e\u5bf9\u8c61   \n            toolkit_config = ToolkitConfig(                #\u521b\u5efa\u4e00\u4e2aToolkitConfig\u914d\u7f6e\u5bf9\u8c61\n                config=config_data.get('config', {}),      #\u521b\u5efa\u4e00\u4e2aToolkitConfig\u914d\u7f6e\u5bf9\u8c61\n                name=name\n            )\n            #\u8bbe\u7f6e\u6fc0\u6d3b\u7684\u5de5\u5177\u5217\u8868\n            toolkit_config.activated_tools = config_data.get('activated_tools')\n            \n            #6.\u521b\u5efa\u5de5\u5177\u5305\u5e76\u4fdd\u5b58\n            toolkit = toolkit_class(toolkit_config)       #\u7528\u914d\u7f6e\u5bf9\u8c61\u521b\u5efa\u5de5\u5177\u5305\u5b9e\u4f8b\n            self.toolkits&#91;name] = toolkit                 #\u4fdd\u5b58\u5230self.toolkits\u5b57\u5178\u91cc\uff08\u4e0b\u6b21\u5c31\u4e0d\u7528\u518d\u521b\u5efa\u4e86\uff09\n            logger.info(f\"\u521b\u5efa\u5de5\u5177\u5305\u5b9e\u4f8b: {name}\")           #\u8bb0\u5f55\u65e5\u5fd7\u5e76\u8fd4\u56de\n            return toolkit\n        #\u5904\u7406\u5176\u4ed6\u6a21\u5f0f\n        else:\n            logger.error(f\"\u4e0d\u652f\u6301\u7684\u5de5\u5177\u5305\u6a21\u5f0f: {toolkit_type}\")   #\u5982\u679c\u4e0d\u662f\u5185\u7f6e\u6a21\u5f0f\uff0c\u8bb0\u5f55\u9519\u8bef\u5e76\u8fd4\u56de\n            return None\n    \n    def get_all_tools(self) -> List&#91;Dict&#91;str, Any]]:     #\u83b7\u53d6\u6240\u6709\u5de5\u5177\u5305\u4e2d\u7684\u6240\u6709\u5de5\u5177\n        \"\"\"\u83b7\u53d6\u6240\u6709\u5de5\u5177\u5305\u7684\u5de5\u5177\u5217\u8868\"\"\"\n        all_tools = &#91;]             #\u521b\u5efa\u4e00\u4e2a\u7a7a\u5217\u8868\n        for toolkit_name in self.toolkit_configs.keys():        #\u904d\u5386\u6240\u6709\u5de5\u5177\u5305,\u904d\u5386\u914d\u7f6e\u5b57\u5178\u4e2d\u7684\u6240\u6709\u5de5\u5177\u5305\u540d\u5b57\n            toolkit = self.get_toolkit(toolkit_name)     #\u83b7\u53d6\u5de5\u5177\u5305\u5b9e\u4f8b,\u7528\u521a\u624d\u7684get_toolkit\u65b9\u6cd5\u83b7\u53d6\u5de5\u5177\u5305,\u5982\u679c\u83b7\u53d6\u6210\u529f\uff0c\u7ee7\u7eed\u6267\u884c\n            if toolkit:\n                tools = toolkit.get_tools_list()      #\u8c03\u7528\u5de5\u5177\u5305\u7684get_tools_list()\u65b9\u6cd5\u83b7\u53d6\u5de5\u5177\u5217\u8868\n                for tool in tools:\n                    tool&#91;'toolkit'] = toolkit_name    #\u7ed9\u6bcf\u4e2a\u5de5\u5177\u6dfb\u52a0\u4e00\u4e2atoolkit\u5b57\u6bb5\uff0c\u8bb0\u5f55\u5b83\u662f\u54ea\u4e2a\u5de5\u5177\u5305\u7684\n                all_tools.extend(tools)               #\u628a\u8fd9\u4e9b\u5de5\u5177\u6dfb\u52a0\u5230\u603b\u5217\u8868\u4e2d\n        return all_tools              #\u8fd4\u56de\u4e00\u4e2a\u5305\u542b\u6240\u6709\u5de5\u5177\u7684\u5217\u8868\n    \n    async def call_tool(self, toolkit_name: str, tool_name: str, arguments: Dict&#91;str, Any]) -> str:\n        #\u8fd9\u4e2a\u65b9\u6cd5\u505a\u4ec0\u4e48\uff1a\u8c03\u7528\u4e00\u4e2a\u5177\u4f53\u7684\u5de5\u5177,\u8fd9\u662f\u4e00\u4e2a\u5f02\u6b65\u65b9\u6cd5\uff08\u6ce8\u610fasync\u548cawait\uff09\n        \"\"\"\u8c03\u7528\u5de5\u5177\uff08\u5f02\u6b65\u65b9\u6cd5\uff09\"\"\"\n        #1.\u83b7\u53d6\u5de5\u5177\u5305\n        toolkit = self.get_toolkit(toolkit_name)   #\u5148\u83b7\u53d6\u5de5\u5177\u5305\u5b9e\u4f8b\n        if not toolkit:\n            return f\"\u5de5\u5177\u5305\u4e0d\u5b58\u5728: {toolkit_name}\"   #\u5982\u679c\u6ca1\u6709\uff0c\u8fd4\u56de\u9519\u8bef\u4fe1\u606f\n         \n        #\u5c1d\u8bd5\u8c03\u7528\u5de5\u5177   \n        try:\n            return await toolkit.call_tool(tool_name, arguments)   #\u5c1d\u8bd5\u5f02\u6b65\u8c03\u7528\u5de5\u5177\u5305\u7684call_tool\u65b9\u6cd5,\u4f20\u5165\u5de5\u5177\u540d\u5b57\u548c\u53c2\u6570\n        #3.\u9519\u8bef\u5904\u7406\n        except Exception as e:   #\u5982\u679c\u8c03\u7528\u5931\u8d25\uff0c\u8bb0\u5f55\u9519\u8bef\u65e5\u5fd7\n            logger.error(f\"\u8c03\u7528\u5de5\u5177\u5931\u8d25 {toolkit_name}.{tool_name}: {e}\")  \n            return f\"\u8c03\u7528\u5de5\u5177\u5931\u8d25: {str(e)}\"   #\u8fd4\u56de\u9519\u8bef\u4fe1\u606f\n    \n    def list_toolkits(self) -> List&#91;str]:\n        #\u8fd9\u4e2a\u65b9\u6cd5\u505a\u4ec0\u4e48\uff1a\u5217\u51fa\u6240\u6709\u53ef\u7528\u7684\u5de5\u5177\u5305\u540d\u5b57\uff0c\u975e\u5e38\u7b80\u5355\uff0c\u5c31\u662f\u628a\u914d\u7f6e\u5b57\u5178\u7684\u6240\u6709\u952e\uff08key\uff09\u8f6c\u6210\u5217\u8868\n        \"\"\"\u5217\u51fa\u6240\u6709\u53ef\u7528\u7684\u5de5\u5177\u5305\"\"\"\n        return list(self.toolkit_configs.keys())\n    \n    def get_toolkit_info(self, name: str) -> Optional&#91;Dict&#91;str, Any]]:\n        \"\"\"\u83b7\u53d6\u5de5\u5177\u5305\u8be6\u7ec6\u4fe1\u606f\"\"\"\n        #1.\u68c0\u67e5\u914d\u7f6e\u662f\u5426\u5b58\u5728\n        if name not in self.toolkit_configs:\n            return None    #\u5982\u679c\u914d\u7f6e\u91cc\u6ca1\u6709\u8fd9\u4e2a\u5de5\u5177\u5305\uff0c\u8fd4\u56deNone\n            \n        #2.\u83b7\u53d6\u914d\u7f6e\u548c\u5de5\u5177\u5305\n        config = self.toolkit_configs&#91;name]\n        toolkit = self.get_toolkit(name)\n        \n        #3.\u521b\u5efa\u57fa\u672c\u4fe1\u606f\u5b57\u5178\n        info = {\n            \"name\": name,\n            \"mode\": config.get('mode', 'builtin'),\n            \"config\": config.get('config', {}),\n            \"tools\": &#91;]\n        }\n        \n        #4.\u6dfb\u52a0\u5de5\u5177\u5217\u8868\uff08\u5982\u679c\u6709\uff09\n        if toolkit:\n            info&#91;\"tools\"] = toolkit.get_tools_list()\n        \n        #5.\u8fd4\u56de\u4fe1\u606f    \n        return info\n\n\n# \u5168\u5c40\u5de5\u5177\u5305\u7ba1\u7406\u5668\u5b9e\u4f8b\ntoolkit_manager = ToolkitManager()\n\n# =====\u5b8c\u6574\u7684\u5c42\u7ea7\u7ed3\u6784\u56fe=====\n'''\n\u5de5\u5177\u5305\u7ba1\u7406\u5668 (ToolkitManager)\n\u251c\u2500\u2500 \u521d\u59cb\u5316\u914d\u7f6e\n\u2502   \u251c\u2500\u2500 \u8bbe\u7f6e\u914d\u7f6e\u76ee\u5f55\u8def\u5f84\n\u2502   \u251c\u2500\u2500 \u521d\u59cb\u5316\u5b58\u50a8\u5bb9\u5668\n\u2502   \u2502   \u251c\u2500\u2500 \u5de5\u5177\u5305\u5b9e\u4f8b\u5b57\u5178 (toolkits)\n\u2502   \u2502   \u2514\u2500\u2500 \u5de5\u5177\u5305\u914d\u7f6e\u5b57\u5178 (toolkit_configs)\n\u2502   \u251c\u2500\u2500 \u6ce8\u518c\u53ef\u7528\u5de5\u5177\u5305\u7c7b\u578b\n\u2502   \u2502   \u2514\u2500\u2500 file_edit \u2192 FileEditToolkit\n\u2502   \u2514\u2500\u2500 \u81ea\u52a8\u52a0\u8f7d\u914d\u7f6e (_load_configs)\n\u2502       \u251c\u2500\u2500 \u68c0\u67e5\u914d\u7f6e\u76ee\u5f55\u662f\u5426\u5b58\u5728\n\u2502       \u251c\u2500\u2500 \u904d\u5386\u6240\u6709YAML\u914d\u7f6e\u6587\u4ef6\n\u2502       \u251c\u2500\u2500 \u8bfb\u53d6\u5e76\u89e3\u6790YAML\u6587\u4ef6\n\u2502       \u2514\u2500\u2500 \u5b58\u50a8\u914d\u7f6e\u5230\u5b57\u5178\n\u2502\n\u251c\u2500\u2500 \u5de5\u5177\u5305\u5b9e\u4f8b\u7ba1\u7406\n\u2502   \u251c\u2500\u2500 \u83b7\u53d6\u5de5\u5177\u5305 (get_toolkit)\n\u2502   \u2502   \u251c\u2500\u2500 \u68c0\u67e5\u662f\u5426\u5df2\u5b9e\u4f8b\u5316 (\u7f13\u5b58\u68c0\u67e5)\n\u2502   \u2502   \u251c\u2500\u2500 \u68c0\u67e5\u914d\u7f6e\u662f\u5426\u5b58\u5728\n\u2502   \u2502   \u251c\u2500\u2500 \u521b\u5efa\u5de5\u5177\u5305\u6d41\u7a0b\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 \u83b7\u53d6\u914d\u7f6e\u6570\u636e\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 \u786e\u5b9a\u5de5\u5177\u5305\u7c7b\u578b\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 \u521b\u5efa\u914d\u7f6e\u5bf9\u8c61 (ToolkitConfig)\n\u2502   \u2502   \u2502   \u2502   \u251c\u2500\u2500 \u8bbe\u7f6e\u57fa\u7840\u914d\u7f6e\n\u2502   \u2502   \u2502   \u2502   \u2514\u2500\u2500 \u8bbe\u7f6e\u6fc0\u6d3b\u5de5\u5177\u5217\u8868\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 \u5b9e\u4f8b\u5316\u5de5\u5177\u5305\u7c7b\n\u2502   \u2502   \u2502   \u2514\u2500\u2500 \u7f13\u5b58\u5b9e\u4f8b\u4f9b\u4e0b\u6b21\u4f7f\u7528\n\u2502   \u2502   \u2514\u2500\u2500 \u9519\u8bef\u5904\u7406\n\u2502   \u2502       \u251c\u2500\u2500 \u914d\u7f6e\u4e0d\u5b58\u5728\u9519\u8bef\n\u2502   \u2502       \u251c\u2500\u2500 \u7c7b\u578b\u672a\u627e\u5230\u9519\u8bef\n\u2502   \u2502       \u2514\u2500\u2500 \u6a21\u5f0f\u4e0d\u652f\u6301\u9519\u8bef\n\u2502   \u2502\n\u2502   \u251c\u2500\u2500 \u5217\u51fa\u6240\u6709\u5de5\u5177\u5305 (list_toolkits)\n\u2502   \u2502   \u2514\u2500\u2500 \u8fd4\u56de\u914d\u7f6e\u5b57\u5178\u7684\u6240\u6709\u952e\n\u2502   \u2502\n\u2502   \u2514\u2500\u2500 \u83b7\u53d6\u5de5\u5177\u5305\u4fe1\u606f (get_toolkit_info)\n\u2502       \u251c\u2500\u2500 \u68c0\u67e5\u914d\u7f6e\u5b58\u5728\u6027\n\u2502       \u251c\u2500\u2500 \u6784\u5efa\u4fe1\u606f\u5b57\u5178\n\u2502       \u2502   \u251c\u2500\u2500 \u57fa\u672c\u4fe1\u606f\n\u2502       \u2502   \u2502   \u251c\u2500\u2500 \u540d\u79f0 (name)\n\u2502       \u2502   \u2502   \u251c\u2500\u2500 \u6a21\u5f0f (mode)\n\u2502       \u2502   \u2502   \u2514\u2500\u2500 \u914d\u7f6e (config)\n\u2502       \u2502   \u2514\u2500\u2500 \u5de5\u5177\u5217\u8868\n\u2502       \u2502       \u2514\u2500\u2500 \u4ece\u5de5\u5177\u5305\u5b9e\u4f8b\u83b7\u53d6\u5de5\u5177\u5217\u8868\n\u2502       \u2514\u2500\u2500 \u8fd4\u56de\u5b8c\u6574\u4fe1\u606f\n\u2502\n\u251c\u2500\u2500 \u5de5\u5177\u7ba1\u7406\n\u2502   \u251c\u2500\u2500 \u83b7\u53d6\u6240\u6709\u5de5\u5177 (get_all_tools)\n\u2502   \u2502   \u251c\u2500\u2500 \u904d\u5386\u6240\u6709\u5de5\u5177\u5305\u914d\u7f6e\n\u2502   \u2502   \u251c\u2500\u2500 \u83b7\u53d6\u6bcf\u4e2a\u5de5\u5177\u5305\u7684\u5de5\u5177\u5217\u8868\n\u2502   \u2502   \u251c\u2500\u2500 \u6807\u8bb0\u5de5\u5177\u6240\u5c5e\u5de5\u5177\u5305\n\u2502   \u2502   \u2502   \u2514\u2500\u2500 \u6dfb\u52a0 toolkit \u5b57\u6bb5\n\u2502   \u2502   \u2514\u2500\u2500 \u5408\u5e76\u6240\u6709\u5de5\u5177\u5230\u5217\u8868\n\u2502   \u2502\n\u2502   \u2514\u2500\u2500 \u8c03\u7528\u5de5\u5177 (call_tool) &#91;\u5f02\u6b65]\n\u2502       \u251c\u2500\u2500 \u83b7\u53d6\u5de5\u5177\u5305\u5b9e\u4f8b\n\u2502       \u251c\u2500\u2500 \u8c03\u7528\u5177\u4f53\u5de5\u5177\n\u2502       \u2502   \u251c\u2500\u2500 \u5f02\u6b65\u8c03\u7528\u5de5\u5177\u5305\u65b9\u6cd5\n\u2502       \u2502   \u2502   \u2514\u2500\u2500 await toolkit.call_tool()\n\u2502       \u2502   \u2514\u2500\u2500 \u4f20\u5165\u53c2\u6570\n\u2502       \u2502       \u251c\u2500\u2500 \u5de5\u5177\u540d\u79f0 (tool_name)\n\u2502       \u2502       \u2514\u2500\u2500 \u53c2\u6570\u5b57\u5178 (arguments)\n\u2502       \u2514\u2500\u2500 \u9519\u8bef\u5904\u7406\n\u2502           \u251c\u2500\u2500 \u5de5\u5177\u5305\u4e0d\u5b58\u5728\u9519\u8bef\n\u2502           \u2514\u2500\u2500 \u8c03\u7528\u5931\u8d25\u9519\u8bef\n\u2502\n\u251c\u2500\u2500 \u5916\u90e8\u4f9d\u8d56\n\u2502   \u251c\u2500\u2500 \u6587\u4ef6\u64cd\u4f5c\n\u2502   \u2502   \u251c\u2500\u2500 Path (\u8def\u5f84\u5904\u7406)\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 exists() - \u68c0\u67e5\u5b58\u5728\n\u2502   \u2502   \u2502   \u2514\u2500\u2500 glob() - \u6a21\u5f0f\u5339\u914d\u6587\u4ef6\n\u2502   \u2502   \u2514\u2500\u2500 open() - \u6587\u4ef6\u8bfb\u53d6\n\u2502   \u2502\n\u2502   \u251c\u2500\u2500 \u914d\u7f6e\u89e3\u6790\n\u2502   \u2502   \u2514\u2500\u2500 yaml.safe_load() - YAML\u89e3\u6790\n\u2502   \u2502\n\u2502   \u251c\u2500\u2500 \u65e5\u5fd7\u7cfb\u7edf\n\u2502   \u2502   \u251c\u2500\u2500 logger.info() - \u4fe1\u606f\u8bb0\u5f55\n\u2502   \u2502   \u251c\u2500\u2500 logger.warning() - \u8b66\u544a\u8bb0\u5f55\n\u2502   \u2502   \u2514\u2500\u2500 logger.error() - \u9519\u8bef\u8bb0\u5f55\n\u2502   \u2502\n\u2502   \u2514\u2500\u2500 \u7c7b\u578b\u7cfb\u7edf\n\u2502       \u251c\u2500\u2500 Dict - \u5b57\u5178\u7c7b\u578b\n\u2502       \u251c\u2500\u2500 List - \u5217\u8868\u7c7b\u578b\n\u2502       \u251c\u2500\u2500 Any - \u4efb\u610f\u7c7b\u578b\n\u2502       \u2514\u2500\u2500 Optional - \u53ef\u9009\u7c7b\u578b\n\u2502\n\u2514\u2500\u2500 \u5168\u5c40\u8bbf\u95ee\n    \u2514\u2500\u2500 \u5168\u5c40\u7ba1\u7406\u5668\u5b9e\u4f8b (toolkit_manager)\n        \u2514\u2500\u2500 \u5355\u4f8b\u6a21\u5f0f\uff0c\u4f9b\u5176\u4ed6\u6a21\u5757\u5bfc\u5165\u4f7f\u7528\n'''<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">config.py<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>#!\/usr\/bin\/env python3\n# -*- coding: utf-8 -*-\n\"\"\"\nAgent Server\u914d\u7f6e\u6587\u4ef6 - \u91cd\u6784\u7248\n\u63d0\u4f9b\u5ba2\u89c2\u3001\u5b9e\u7528\u7684\u914d\u7f6e\u7ba1\u7406\n\"\"\"\n\nfrom dataclasses import dataclass   #dataclass\uff1a\u4e00\u4e2a\u65b9\u4fbf\u7684\u5de5\u5177\uff0c\u53ef\u4ee5\u5feb\u901f\u521b\u5efa\u6570\u636e\u7c7b\nfrom typing import Optional         #typing.Optional\uff1a\u4e00\u4e2a\u7c7b\u578b\u63d0\u793a\u5de5\u5177\uff08\u8fd9\u91cc\u5b9e\u9645\u6ca1\u7528\u5230\uff09\n\n# ============ \u670d\u52a1\u5668\u914d\u7f6e ============\n\n# \u4ece\u4e3b\u914d\u7f6e\u8bfb\u53d6\u7aef\u53e3\ntry:       #try-except\uff1a\u903b\u8f91\u5224\u65ad\uff0c\u610f\u601d\u662f\u201c\u8bd5\u8bd5\u770b\uff0c\u4e0d\u884c\u5c31\u7528\u5907\u9009\u65b9\u6848\u201d\n    from system.config import get_server_port             #\u5148\u5c1d\u8bd5\u4ece\u5176\u4ed6\u5730\u65b9\u83b7\u53d6\u7aef\u53e3\u53f7\n    AGENT_SERVER_PORT = get_server_port(\"agent_server\")\nexcept ImportError:\n    AGENT_SERVER_PORT = 8001  # \u56de\u9000\u9ed8\u8ba4\u503c                 #\u5982\u679c\u627e\u4e0d\u5230\uff08ImportError\uff09\uff0c\u5c31\u7528\u9ed8\u8ba4\u7684 8001\n\n# ============ \u4efb\u52a1\u8c03\u5ea6\u5668\u914d\u7f6e ============\n\n@dataclass\nclass TaskSchedulerConfig:          #\u521b\u5efa\u4e86\u4e00\u4e2a\u53eb\u201c\u4efb\u52a1\u8c03\u5ea6\u5668\u914d\u7f6e\u201d\u7684\u8bbe\u7f6e\u7c7b\n    \"\"\"\u4efb\u52a1\u8c03\u5ea6\u5668\u914d\u7f6e\"\"\"\n    # \u8bb0\u5fc6\u7ba1\u7406\u9608\u503c\n    max_steps: int = 15                    # \u6700\u5927\u4fdd\u5b58\u6b65\u9aa4\u6570\n    compression_threshold: int = 7          # \u538b\u7f29\u89e6\u53d1\u9608\u503c\n    keep_last_steps: int = 4               # \u538b\u7f29\u540e\u4fdd\u7559\u7684\u8be6\u7ec6\u6b65\u9aa4\u6570\n    \n    # \u663e\u793a\u76f8\u5173\u9608\u503c\n    key_facts_compression_limit: int = 5    # \u538b\u7f29\u63d0\u793a\u4e2d\u7684\u5173\u952e\u4e8b\u5b9e\u6570\u91cf\n    key_facts_summary_limit: int = 10       # \u6458\u8981\u4e2d\u7684\u5173\u952e\u4e8b\u5b9e\u6570\u91cf\n    compressed_memory_summary_limit: int = 3 # \u4efb\u52a1\u6458\u8981\u4e2d\u7684\u538b\u7f29\u8bb0\u5fc6\u6570\u91cf\n    compressed_memory_global_limit: int = 2  # \u5168\u5c40\u6458\u8981\u4e2d\u7684\u538b\u7f29\u8bb0\u5fc6\u6570\u91cf\n    key_findings_display_limit: int = 3     # \u5173\u952e\u53d1\u73b0\u663e\u793a\u6570\u91cf\n    failed_attempts_display_limit: int = 3  # \u5931\u8d25\u5c1d\u8bd5\u663e\u793a\u6570\u91cf\n    \n    # \u8f93\u51fa\u957f\u5ea6\u9650\u5236\n    output_summary_length: int = 256        # \u5173\u952e\u4e8b\u5b9e\u4e2d\u7684\u8f93\u51fa\u6458\u8981\u957f\u5ea6\n    step_output_display_length: int = 512   # \u6b65\u9aa4\u663e\u793a\u4e2d\u7684\u8f93\u51fa\u957f\u5ea6\n    \n    # \u6027\u80fd\u914d\u7f6e\n    enable_auto_compression: bool = True    # \u662f\u5426\u542f\u7528\u81ea\u52a8\u538b\u7f29\n    compression_timeout: int = 30           # \u538b\u7f29\u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09\n    max_compression_retries: int = 3        # \u6700\u5927\u538b\u7f29\u91cd\u8bd5\u6b21\u6570\n\n# \u9ed8\u8ba4\u4efb\u52a1\u8c03\u5ea6\u5668\u914d\u7f6e\u5b9e\u4f8b\nDEFAULT_TASK_SCHEDULER_CONFIG = TaskSchedulerConfig()\n#\u7528\u4e0a\u9762\u7684\u914d\u7f6e\u7c7b\u521b\u5efa\u4e86\u4e00\u4e2a\u5b9e\u9645\u53ef\u7528\u7684\u914d\u7f6e\u5bf9\u8c61,\u5c31\u50cf\u7528\u6a21\u5177\u505a\u4e86\u4e00\u4e2a\u5177\u4f53\u7684\u86cb\u7cd5\n\n# ============ Agent\u7ba1\u7406\u5668\u914d\u7f6e ============\n\n@dataclass\nclass AgentManagerConfig:                   #AgentManagerConfig\uff1a\u7ba1\u7406\u4ee3\u7406\uff08agent\uff09\u7684\u8bbe\u7f6e\n    \"\"\"Agent\u7ba1\u7406\u5668\u914d\u7f6e\"\"\"\n    # \u4f1a\u8bdd\u7ba1\u7406\n    default_session_timeout: int = 3600     # \u9ed8\u8ba4\u4f1a\u8bdd\u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09\n    max_session_history: int = 100          # \u6700\u5927\u4f1a\u8bdd\u5386\u53f2\u8bb0\u5f55\u6570\n    \n    # \u4efb\u52a1\u6267\u884c\n    max_concurrent_agents: int = 5          # \u6700\u5927\u5e76\u53d1Agent\u6570\n    agent_timeout: int = 300                # Agent\u6267\u884c\u8d85\u65f6\u65f6\u95f4\uff08\u79d2\uff09\n    \n    # \u7f13\u5b58\u914d\u7f6e\n    enable_agent_cache: bool = True         # \u662f\u5426\u542f\u7528Agent\u7f13\u5b58\n    cache_ttl: int = 1800                   # \u7f13\u5b58\u751f\u5b58\u65f6\u95f4\uff08\u79d2\uff09\n\n# \u9ed8\u8ba4Agent\u7ba1\u7406\u5668\u914d\u7f6e\u5b9e\u4f8b\nDEFAULT_AGENT_MANAGER_CONFIG = AgentManagerConfig()\n\n# ============ \u7535\u8111\u63a7\u5236Agent\u914d\u7f6e ============\n\n@dataclass  \nclass ComputerControlConfig:                #ComputerControlConfig\uff1a\u63a7\u5236\u7535\u8111\u7684\u8bbe\u7f6e\n    \"\"\"\u7535\u8111\u63a7\u5236Agent\u914d\u7f6e\"\"\"\n    # \u6267\u884c\u914d\u7f6e\n    max_execution_time: int = 60            # \u6700\u5927\u6267\u884c\u65f6\u95f4\uff08\u79d2\uff09\n    enable_screenshot: bool = True          # \u662f\u5426\u542f\u7528\u622a\u56fe\u529f\u80fd\n    screenshot_quality: int = 80            # \u622a\u56fe\u8d28\u91cf\uff081-100\uff09\n    \n    # \u5b89\u5168\u914d\u7f6e\n    enable_safety_checks: bool = True       # \u662f\u5426\u542f\u7528\u5b89\u5168\u68c0\u67e5\n    blocked_commands: list = None           # \u88ab\u963b\u6b62\u7684\u547d\u4ee4\u5217\u8868\n    \n    def __post_init__(self):\n        if self.blocked_commands is None:\n            self.blocked_commands = &#91;\n                \"rm -rf \/\", \"format c:\", \"del \/f \/s \/q c:\\\\\",\n                \"shutdown\", \"reboot\", \"halt\"\n            ]\n\n# \u9ed8\u8ba4\u7535\u8111\u63a7\u5236\u914d\u7f6e\u5b9e\u4f8b\nDEFAULT_COMPUTER_CONTROL_CONFIG = ComputerControlConfig()\n\n# ============ \u5168\u5c40\u914d\u7f6e\u7ba1\u7406 ============\n\n@dataclass\nclass AgentServerConfig:        #\u8fd9\u662f\u603b\u7684\u914d\u7f6e\uff0c\u5305\u542b\u6240\u6709\u5b50\u914d\u7f6e\n    \"\"\"Agent\u670d\u52a1\u5668\u5168\u5c40\u914d\u7f6e\"\"\"\n    # \u670d\u52a1\u5668\u914d\u7f6e\n    host: str = \"0.0.0.0\"\n    port: int = None\n    \n    # \u5b50\u6a21\u5757\u914d\u7f6e\n    task_scheduler: TaskSchedulerConfig = None\n    agent_manager: AgentManagerConfig = None\n    computer_control: ComputerControlConfig = None\n    \n    # \u65e5\u5fd7\u914d\u7f6e\n    log_level: str = \"INFO\"\n    enable_debug_logs: bool = False\n    \n    def __post_init__(self):            #\u8fd9\u662f\u4e00\u4e2a\u7279\u6b8a\u51fd\u6570\uff0c\u4f1a\u5728\u7c7b\u521b\u5efa\u540e\u81ea\u52a8\u8fd0\u884c\n        # \u8bbe\u7f6e\u9ed8\u8ba4\u7aef\u53e3\n        if self.port is None:\n            self.port = AGENT_SERVER_PORT\n        \n        # \u8bbe\u7f6e\u9ed8\u8ba4\u5b50\u914d\u7f6e\n        if self.task_scheduler is None:\n            self.task_scheduler = DEFAULT_TASK_SCHEDULER_CONFIG\n        if self.agent_manager is None:\n            self.agent_manager = DEFAULT_AGENT_MANAGER_CONFIG\n        if self.computer_control is None:\n            self.computer_control = DEFAULT_COMPUTER_CONTROL_CONFIG\n\n# \u5168\u5c40\u914d\u7f6e\u5b9e\u4f8b\nconfig = AgentServerConfig()\n\n# ============ \u914d\u7f6e\u8bbf\u95ee\u51fd\u6570 ============\n\ndef get_task_scheduler_config() -> TaskSchedulerConfig:\n    \"\"\"\u83b7\u53d6\u4efb\u52a1\u8c03\u5ea6\u5668\u914d\u7f6e\"\"\"\n    return config.task_scheduler\n\ndef get_agent_manager_config() -> AgentManagerConfig:\n    \"\"\"\u83b7\u53d6Agent\u7ba1\u7406\u5668\u914d\u7f6e\"\"\"\n    return config.agent_manager\n\ndef get_computer_control_config() -> ComputerControlConfig:\n    \"\"\"\u83b7\u53d6\u7535\u8111\u63a7\u5236\u914d\u7f6e\"\"\"\n    return config.computer_control\n\ndef update_config(**kwargs):\n    \"\"\"\u66f4\u65b0\u914d\u7f6e\"\"\"\n    for key, value in kwargs.items():\n        if hasattr(config, key):\n            setattr(config, key, value)\n        else:\n            raise ValueError(f\"\u672a\u77e5\u914d\u7f6e\u9879: {key}\")\n\n# ============ \u5411\u540e\u517c\u5bb9 ============\n\n# \u4fdd\u6301\u5411\u540e\u517c\u5bb9\u7684\u914d\u7f6e\u5e38\u91cf\nAGENT_SERVER_HOST = config.host\nAGENT_SERVER_PORT = config.port\n'''\n\u4ee3\u7801\u6700\u540e\u521b\u5efa\u4e86\u51e0\u4e2a\u51fd\u6570\uff1a\n  get_task_scheduler_config()\uff1a\u83b7\u53d6\u4efb\u52a1\u8c03\u5ea6\u5668\u7684\u914d\u7f6e\n  get_agent_manager_config()\uff1a\u83b7\u53d6\u4ee3\u7406\u7ba1\u7406\u5668\u7684\u914d\u7f6e\n  get_computer_control_config()\uff1a\u83b7\u53d6\u7535\u8111\u63a7\u5236\u7684\u914d\u7f6e\n  update_config(**kwargs)\uff1a\u66f4\u65b0\u914d\u7f6e\u7684\u51fd\u6570\uff0c\u53ef\u4ee5\u4fee\u6539\u8bbe\u7f6e\n'''<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">README.md<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">\u4e00\u3001 \u4e8c\u6b21\u5f00\u53d1\u6838\u5fc3\u5165\u53e3<\/h4>\n\n\n\n<h3 class=\"wp-block-heading\">1.&nbsp;<strong>\u6dfb\u52a0\u65b0\u7684\u610f\u56fe\u5904\u7406\u903b\u8f91<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u4fee\u6539\u6587\u4ef6<\/strong>\uff1a<code>task_planner.py<\/code><\/li>\n\n\n\n<li><strong>\u5173\u952e\u51fd\u6570<\/strong>\uff1a<code>evaluate_and_plan()<\/code><\/li>\n\n\n\n<li><strong>\u6dfb\u52a0\u65b0\u4efb\u52a1\u7c7b\u578b<\/strong>\uff1a<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code># \u5728task_planner.py\u4e2d\u6dfb\u52a0\u65b0\u4efb\u52a1\u7c7b\u578b\u5224\u65ad\nif \"\u4f60\u7684\u65b0\u610f\u56fe\u5173\u952e\u8bcd\" in user_query:\n    return {\n        \"type\": \"your_new_processor\",\n        \"params\": {...},\n        \"executor\": \"agent\"  # \u6216 \"mcp\"\n    }<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">2.&nbsp;<strong>\u6269\u5c55\u4efb\u52a1\u6267\u884c\u5668<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u4fee\u6539\u6587\u4ef6<\/strong>\uff1a<code>task_scheduler.py<\/code><\/li>\n\n\n\n<li><strong>\u6dfb\u52a0\u65b0\u7684processor<\/strong>\uff1a<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>async def _execute_task(self, task):\n    if task&#91;\"type\"] == \"your_new_processor\":\n        return await self._execute_your_processor(task&#91;\"params\"])\n    \nasync def _execute_your_processor(self, params):\n    # \u5b9e\u73b0\u4f60\u7684\u4e1a\u52a1\u903b\u8f91\n    pass<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">3.&nbsp;<strong>\u81ea\u5b9a\u4e49API\u63a5\u53e3<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u4fee\u6539\u6587\u4ef6<\/strong>\uff1a<code>agent_server.py<\/code><\/li>\n\n\n\n<li><strong>\u6dfb\u52a0\u65b0\u7aef\u70b9<\/strong>\uff1a<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>@app.post(\"\/your_custom_endpoint\")\nasync def custom_handler(request_data: dict):\n    # \u76f4\u63a5\u8c03\u7528\u4efb\u52a1\u89c4\u5212\u5668\n    plan = await task_planner.evaluate_and_plan(request_data&#91;\"query\"])\n    # \u8c03\u5ea6\u6267\u884c\n    result = await task_scheduler.schedule_execution(plan)\n    return result<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">\u4e8c\u3001 \u5355\u72ec\u8c03\u8bd5\u6b65\u9aa4<\/h4>\n\n\n\n<p>1.\u00a0<strong>\u542f\u52a8\u72ec\u7acb\u6d4b\u8bd5\u670d\u52a1<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># \u8fdb\u5165\u9879\u76ee\u76ee\u5f55\ncd agentserver\n\n# \u65b9\u5f0f1\uff1a\u76f4\u63a5\u8fd0\u884c\uff08\u67e5\u770b\u8be6\u7ec6\u65e5\u5fd7\uff09\npython -m uvicorn agent_server:app --reload --port 8001 --log-level debug\n\n# \u65b9\u5f0f2\uff1a\u4f7f\u7528\u63d0\u4f9b\u7684\u811a\u672c\uff08\u5982\u679c\u6709\uff09\npython dev_server.py<\/code><\/pre>\n\n\n\n<p>2.\u00a0<strong>\u6d4b\u8bd5API\u63a5\u53e3<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># \u6d4b\u8bd5\u610f\u56fe\u5206\u6790\uff08\u4f7f\u7528curl\uff09\ncurl -X POST http:\/\/localhost:8001\/analyze_and_execute \\\n  -H \"Content-Type: application\/json\" \\\n  -d '{\n    \"messages\": &#91;{\"role\": \"user\", \"content\": \"\u5e2e\u6211\u6253\u5f00\u8ba1\u7b97\u5668\"}],\n    \"session_id\": \"test_session\"\n  }'\n\n# \u67e5\u770b\u4efb\u52a1\u72b6\u6001\ncurl http:\/\/localhost:8001\/tasks?session_id=test_session<\/code><\/pre>\n\n\n\n<p>3.\u00a0<strong>\u5355\u5143\u8c03\u8bd5\u6a21\u5757<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># \u521b\u5efa\u6d4b\u8bd5\u811a\u672c test_debug.py\nimport asyncio\nfrom task_planner import TaskPlanner\nfrom task_scheduler import TaskScheduler\n\nasync def test_planner():\n    planner = TaskPlanner()\n    # \u76f4\u63a5\u6d4b\u8bd5\u89c4\u5212\u5668\n    plan = await planner.evaluate_and_plan(\"\u6253\u5f00\u8bb0\u4e8b\u672c\u548c\u6d4f\u89c8\u5668\")\n    print(\"\u751f\u6210\u7684\u8ba1\u5212:\", plan)\n    \nasync def test_scheduler():\n    scheduler = TaskScheduler()\n    # \u6d4b\u8bd5\u76f4\u63a5\u8c03\u5ea6\n    task = {\"type\": \"processor\", \"params\": {\"query\": \"\u6d4b\u8bd5\"}}\n    result = await scheduler.schedule_execution(task)\n    print(\"\u6267\u884c\u7ed3\u679c:\", result)\n\nif __name__ == \"__main__\":\n    asyncio.run(test_planner())<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">4.&nbsp;<strong>\u4fee\u6539\u914d\u7f6e\u5feb\u901f\u751f\u6548<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u914d\u7f6e\u6587\u4ef6<\/strong>\uff1a<code>config.py<\/code><\/li>\n\n\n\n<li><strong>\u5e38\u7528\u4fee\u6539\u9879<\/strong>\uff1a<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code># \u5173\u95ed\u67d0\u4e9b\u529f\u80fd\u8fdb\u884c\u8c03\u8bd5\nINTENT_ANALYSIS_ENABLED = False  # \u8df3\u8fc7\u610f\u56fe\u5206\u6790\u76f4\u63a5\u6d4b\u8bd5\nTASK_TIMEOUT = 30  # \u8c03\u5c0f\u8d85\u65f6\u65f6\u95f4\u5feb\u901f\u5931\u8d25\nMAX_CONCURRENT_TASKS = 1  # \u9650\u5236\u5e76\u53d1\u6570\u4fbf\u4e8e\u8c03\u8bd5<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">\u4e09\u3001 \u6838\u5fc3\u5f00\u53d1\u573a\u666f<\/h4>\n\n\n\n<p>\u573a\u666f1\uff1a\u6dfb\u52a0\u65b0\u7684\u7535\u8111\u63a7\u5236\u80fd\u529b<\/p>\n\n\n\n<ol start=\"1\" class=\"wp-block-list\">\n<li><strong>\u5728\u00a0<code>task_scheduler.py<\/code>\u00a0\u4e2d\u6dfb\u52a0\u6267\u884c\u51fd\u6570<\/strong><\/li>\n\n\n\n<li><strong>\u5728\u00a0<code>task_planner.py<\/code>\u00a0\u4e2d\u6ce8\u518c\u610f\u56fe\u6620\u5c04<\/strong><\/li>\n\n\n\n<li><strong>\u6d4b\u8bd5\uff1a\u76f4\u63a5\u8c03\u7528\u65b0\u51fd\u6570\u9a8c\u8bc1\u529f\u80fd<\/strong><\/li>\n<\/ol>\n\n\n\n<p>\u573a\u666f2\uff1a\u4fee\u6539\u4efb\u52a1\u8c03\u5ea6\u7b56\u7565<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># \u4fee\u6539\u8c03\u5ea6\u903b\u8f91\uff08task_scheduler.py\uff09\nclass CustomTaskScheduler(TaskScheduler):\n    async def schedule_parallel_execution(self, tasks):\n        # \u91cd\u5199\u5e76\u53d1\u7b56\u7565\n        # \u4f8b\u5982\uff1a\u6309\u4f18\u5148\u7ea7\u6392\u5e8f\u3001\u4f9d\u8d56\u5173\u7cfb\u5904\u7406\n        pass<\/code><\/pre>\n\n\n\n<p>\u573a\u666f3\uff1a\u96c6\u6210\u65b0\u7684AI\u6a21\u578b<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># \u66ff\u6362\u6216\u6269\u5c55\u610f\u56fe\u5206\u6790\u6a21\u578b\n# \u5728task_planner.py\u4e2d\u4fee\u6539\nasync def analyze_intent(self, query):\n    # \u4f7f\u7528\u65b0\u7684LLM API\n    response = await call_your_llm_api(query)\n    return self._parse_to_task(response)<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">\u56db\u3001 \u8c03\u8bd5\u6280\u5de7<\/h4>\n\n\n\n<p>1.\u00a0<strong>\u65e5\u5fd7\u8ffd\u8e2a<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># \u5728\u4ee3\u7801\u4e2d\u6dfb\u52a0\u8c03\u8bd5\u65e5\u5fd7\nimport logging\nlogger = logging.getLogger(__name__)\n\nlogger.debug(f\"\u4efb\u52a1\u53c2\u6570: {params}\")  # \u5f00\u53d1\u65f6\u7528debug\u7ea7\u522b\nlogger.info(f\"\u5f00\u59cb\u6267\u884c\u4efb\u52a1: {task_id}\")<\/code><\/pre>\n\n\n\n<p>2.\u00a0<strong>\u65ad\u70b9\u8c03\u8bd5<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># \u4f7f\u7528debugpy\u8fdb\u884c\u8fdc\u7a0b\u8c03\u8bd5\npython -m debugpy --listen 0.0.0.0:5678 --wait-for-client agent_server.py<\/code><\/pre>\n\n\n\n<p>3.\u00a0<strong>\u6d4b\u8bd5\u6570\u636e\u6a21\u62df<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># \u521b\u5efa\u6a21\u62df\u8bf7\u6c42\u8fdb\u884c\u6d4b\u8bd5\ntest_data = {\n    \"messages\": &#91;{\"role\": \"user\", \"content\": \"\u6d4b\u8bd5\u6307\u4ee4\"}],\n    \"session_id\": \"debug_\" + str(uuid.uuid4())\n}\n# \u76f4\u63a5\u8c03\u7528\u5185\u90e8\u51fd\u6570\uff0c\u7ed5\u8fc7HTTP\u5c42\nresult = await app.state.planner.evaluate_and_plan(test_data&#91;\"messages\"]&#91;0]&#91;\"content\"])<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">\u4e94\u3001 \u5feb\u901f\u9a8c\u8bc1\u6e05\u5355<\/h4>\n\n\n\n<ol start=\"1\" class=\"wp-block-list\">\n<li><strong>\u4fee\u6539\u751f\u6548\u4e86\u5417\uff1f<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u91cd\u542f\u670d\u52a1\uff1a<code>Ctrl+C<\/code>\u00a0\u7136\u540e\u91cd\u65b0\u542f\u52a8<\/li>\n\n\n\n<li>\u68c0\u67e5\u65e5\u5fd7\uff1a\u786e\u8ba4\u6ca1\u6709\u5bfc\u5165\u9519\u8bef<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u63a5\u53e3\u5de5\u4f5c\u6b63\u5e38\u5417\uff1f<\/strong>\n<ul class=\"wp-block-list\">\n<li># \u5065\u5eb7\u68c0\u67e5\uff1acurl http:\/\/localhost:8001\/health<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u4efb\u52a1\u6267\u884c\u6210\u529f\u5417\uff1f<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u67e5\u770b\u4efb\u52a1\u72b6\u6001\u63a5\u53e3<\/li>\n\n\n\n<li>\u68c0\u67e5\u4efb\u52a1\u6ce8\u518c\u8868\uff1a<code>task_scheduler.task_registry<\/code><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u9700\u8981\u56de\u6eda\u5417\uff1f<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u5907\u4efd\u539f\u6587\u4ef6\uff1a<code>cp agent_server.py agent_server.py.bak<\/code><\/li>\n\n\n\n<li>\u4f7f\u7528Git\u4e34\u65f6\u63d0\u4ea4\uff1a<code>git stash<\/code><\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<h4 class=\"wp-block-heading\">\u516d\u3001 \u91cd\u8981\u63d0\u9192<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u70ed\u91cd\u8f7d<\/strong>\uff1a\u542f\u52a8\u65f6\u52a0\u00a0<code>--reload<\/code>\u00a0\u53c2\u6570\uff0c\u4fee\u6539\u4ee3\u7801\u81ea\u52a8\u91cd\u542f<\/li>\n\n\n\n<li><strong>\u7aef\u53e3\u51b2\u7a81<\/strong>\uff1a\u786e\u4fdd8001\u7aef\u53e3\u672a\u88ab\u5360\u7528\uff0c\u6216\u4fee\u6539\u00a0<code>config.py<\/code>\u00a0\u4e2d\u7684\u7aef\u53e3<\/li>\n\n\n\n<li><strong>\u4f9d\u8d56\u5b89\u88c5<\/strong>\uff1a\u5982\u679c\u6dfb\u52a0\u65b0\u4f9d\u8d56\uff0c\u66f4\u65b0\u00a0<code>requirements.txt<\/code><\/li>\n\n\n\n<li><strong>\u5e76\u53d1\u5b89\u5168<\/strong>\uff1a\u4fee\u6539\u8c03\u5ea6\u5668\u65f6\u6ce8\u610f\u7ebf\u7a0b\/\u534f\u7a0b\u5b89\u5168\u95ee\u9898<\/li>\n<\/ul>\n\n\n\n<p><strong>\u6700\u7b80\u5f00\u53d1\u5faa\u73af<\/strong>\uff1a<\/p>\n\n\n\n<ol start=\"1\" class=\"wp-block-list\">\n<li>\u4fee\u6539\u00a0<code>task_planner.py<\/code>\u00a0\u6216\u00a0<code>task_scheduler.py<\/code><\/li>\n\n\n\n<li>\u91cd\u542f\u670d\u52a1\uff1a<code>python -m uvicorn agent_server:app --reload --port 8001<\/code><\/li>\n\n\n\n<li>\u53d1\u9001\u6d4b\u8bd5\u8bf7\u6c42\uff1a<code>curl -X POST ...<\/code><\/li>\n\n\n\n<li>\u67e5\u770b\u65e5\u5fd7\u786e\u8ba4\u7ed3\u679c<\/li>\n<\/ol>\n\n\n\n<p>\u76f4\u63a5\u6539\u8fd9\u51e0\u4e2a\u6838\u5fc3\u6587\u4ef6\uff0c\u5c31\u80fd\u5b9e\u73b0\u5927\u90e8\u5206\u4e8c\u6b21\u5f00\u53d1\u9700\u6c42\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>1 agent_server.py agent_manager.py task_scheduler.py to [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[54],"tags":[],"class_list":["post-1264","post","type-post","status-publish","format-standard","hentry","category-text"],"_links":{"self":[{"href":"http:\/\/www.preluna.xyz\/index.php\/wp-json\/wp\/v2\/posts\/1264","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.preluna.xyz\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.preluna.xyz\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.preluna.xyz\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.preluna.xyz\/index.php\/wp-json\/wp\/v2\/comments?post=1264"}],"version-history":[{"count":7,"href":"http:\/\/www.preluna.xyz\/index.php\/wp-json\/wp\/v2\/posts\/1264\/revisions"}],"predecessor-version":[{"id":1276,"href":"http:\/\/www.preluna.xyz\/index.php\/wp-json\/wp\/v2\/posts\/1264\/revisions\/1276"}],"wp:attachment":[{"href":"http:\/\/www.preluna.xyz\/index.php\/wp-json\/wp\/v2\/media?parent=1264"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.preluna.xyz\/index.php\/wp-json\/wp\/v2\/categories?post=1264"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.preluna.xyz\/index.php\/wp-json\/wp\/v2\/tags?post=1264"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}