jarvis-ai-assistant 0.1.44__py3-none-any.whl → 0.1.46__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. jarvis/__init__.py +1 -1
  2. jarvis/agent.py +47 -32
  3. jarvis/main.py +52 -30
  4. jarvis/models/__init__.py +1 -1
  5. jarvis/models/ai8.py +88 -58
  6. jarvis/models/base.py +6 -6
  7. jarvis/models/kimi.py +171 -80
  8. jarvis/models/openai.py +43 -23
  9. jarvis/models/oyi.py +93 -65
  10. jarvis/models/registry.py +63 -44
  11. jarvis/tools/__init__.py +1 -1
  12. jarvis/tools/base.py +2 -2
  13. jarvis/tools/file_ops.py +19 -15
  14. jarvis/tools/generator.py +15 -12
  15. jarvis/tools/methodology.py +20 -20
  16. jarvis/tools/registry.py +44 -30
  17. jarvis/tools/shell.py +12 -11
  18. jarvis/tools/sub_agent.py +1 -2
  19. jarvis/utils.py +47 -27
  20. {jarvis_ai_assistant-0.1.44.dist-info → jarvis_ai_assistant-0.1.46.dist-info}/METADATA +1 -1
  21. jarvis_ai_assistant-0.1.46.dist-info/RECORD +25 -0
  22. jarvis/__pycache__/__init__.cpython-313.pyc +0 -0
  23. jarvis/__pycache__/agent.cpython-313.pyc +0 -0
  24. jarvis/__pycache__/main.cpython-313.pyc +0 -0
  25. jarvis/__pycache__/models.cpython-313.pyc +0 -0
  26. jarvis/__pycache__/tools.cpython-313.pyc +0 -0
  27. jarvis/__pycache__/utils.cpython-313.pyc +0 -0
  28. jarvis/__pycache__/zte_llm.cpython-313.pyc +0 -0
  29. jarvis/models/__pycache__/__init__.cpython-313.pyc +0 -0
  30. jarvis/models/__pycache__/ai8.cpython-313.pyc +0 -0
  31. jarvis/models/__pycache__/base.cpython-313.pyc +0 -0
  32. jarvis/models/__pycache__/kimi.cpython-313.pyc +0 -0
  33. jarvis/models/__pycache__/openai.cpython-313.pyc +0 -0
  34. jarvis/models/__pycache__/oyi.cpython-313.pyc +0 -0
  35. jarvis/models/__pycache__/registry.cpython-313.pyc +0 -0
  36. jarvis/tools/__pycache__/__init__.cpython-313.pyc +0 -0
  37. jarvis/tools/__pycache__/base.cpython-313.pyc +0 -0
  38. jarvis/tools/__pycache__/bing_search.cpython-313.pyc +0 -0
  39. jarvis/tools/__pycache__/calculator.cpython-313.pyc +0 -0
  40. jarvis/tools/__pycache__/calculator_tool.cpython-313.pyc +0 -0
  41. jarvis/tools/__pycache__/file_ops.cpython-313.pyc +0 -0
  42. jarvis/tools/__pycache__/generator.cpython-313.pyc +0 -0
  43. jarvis/tools/__pycache__/methodology.cpython-313.pyc +0 -0
  44. jarvis/tools/__pycache__/python_script.cpython-313.pyc +0 -0
  45. jarvis/tools/__pycache__/rag.cpython-313.pyc +0 -0
  46. jarvis/tools/__pycache__/registry.cpython-313.pyc +0 -0
  47. jarvis/tools/__pycache__/search.cpython-313.pyc +0 -0
  48. jarvis/tools/__pycache__/shell.cpython-313.pyc +0 -0
  49. jarvis/tools/__pycache__/sub_agent.cpython-313.pyc +0 -0
  50. jarvis/tools/__pycache__/user_confirmation.cpython-313.pyc +0 -0
  51. jarvis/tools/__pycache__/user_input.cpython-313.pyc +0 -0
  52. jarvis/tools/__pycache__/user_interaction.cpython-313.pyc +0 -0
  53. jarvis/tools/__pycache__/webpage.cpython-313.pyc +0 -0
  54. jarvis_ai_assistant-0.1.44.dist-info/RECORD +0 -57
  55. {jarvis_ai_assistant-0.1.44.dist-info → jarvis_ai_assistant-0.1.46.dist-info}/LICENSE +0 -0
  56. {jarvis_ai_assistant-0.1.44.dist-info → jarvis_ai_assistant-0.1.46.dist-info}/WHEEL +0 -0
  57. {jarvis_ai_assistant-0.1.44.dist-info → jarvis_ai_assistant-0.1.46.dist-info}/entry_points.txt +0 -0
  58. {jarvis_ai_assistant-0.1.44.dist-info → jarvis_ai_assistant-0.1.46.dist-info}/top_level.txt +0 -0
jarvis/tools/file_ops.py CHANGED
@@ -34,18 +34,19 @@ class FileOperationTool:
34
34
  "required": ["operation", "filepath"]
35
35
  }
36
36
 
37
-
38
37
  def execute(self, args: Dict) -> Dict[str, Any]:
39
38
  """执行文件操作"""
40
39
  try:
41
40
  operation = args["operation"]
42
41
  filepath = args["filepath"]
43
42
  encoding = args.get("encoding", "utf-8")
44
-
43
+
45
44
  # 记录操作和完整路径
46
45
  abs_path = os.path.abspath(filepath)
47
- PrettyOutput.print(f"文件操作: {operation} - {abs_path}", OutputType.INFO)
48
-
46
+ PrettyOutput.print(
47
+ f"文件操作: {operation} - {abs_path}",
48
+ OutputType.INFO)
49
+
49
50
  if operation == "exists":
50
51
  exists = os.path.exists(filepath)
51
52
  return {
@@ -53,21 +54,21 @@ class FileOperationTool:
53
54
  "stdout": str(exists),
54
55
  "stderr": ""
55
56
  }
56
-
57
+
57
58
  elif operation == "read":
58
59
  if not os.path.exists(filepath):
59
60
  return {
60
61
  "success": False,
61
62
  "error": f"文件不存在: {filepath}"
62
63
  }
63
-
64
+
64
65
  # 检查文件大小
65
66
  if os.path.getsize(filepath) > 10 * 1024 * 1024: # 10MB
66
67
  return {
67
68
  "success": False,
68
69
  "error": "文件过大 (>10MB)"
69
70
  }
70
-
71
+
71
72
  with open(filepath, 'r', encoding=encoding) as f:
72
73
  content = f.read()
73
74
  return {
@@ -75,36 +76,39 @@ class FileOperationTool:
75
76
  "stdout": content,
76
77
  "stderr": ""
77
78
  }
78
-
79
+
79
80
  elif operation in ["write", "append"]:
80
81
  if not args.get("content"):
81
82
  return {
82
83
  "success": False,
83
84
  "error": "写入/追加操作需要提供content参数"
84
85
  }
85
-
86
+
86
87
  # 创建目录(如果不存在)
87
- os.makedirs(os.path.dirname(os.path.abspath(filepath)), exist_ok=True)
88
-
88
+ os.makedirs(
89
+ os.path.dirname(
90
+ os.path.abspath(filepath)),
91
+ exist_ok=True)
92
+
89
93
  mode = 'a' if operation == "append" else 'w'
90
94
  with open(filepath, mode, encoding=encoding) as f:
91
95
  f.write(args["content"])
92
-
96
+
93
97
  return {
94
98
  "success": True,
95
99
  "stdout": f"成功{operation}内容到 {filepath}",
96
100
  "stderr": ""
97
101
  }
98
-
102
+
99
103
  else:
100
104
  return {
101
105
  "success": False,
102
106
  "error": f"未知操作: {operation}"
103
107
  }
104
-
108
+
105
109
  except Exception as e:
106
110
  PrettyOutput.print(str(e), OutputType.ERROR)
107
111
  return {
108
112
  "success": False,
109
113
  "error": f"文件操作失败: {str(e)}"
110
- }
114
+ }
jarvis/tools/generator.py CHANGED
@@ -5,6 +5,7 @@ from jarvis.models.registry import PlatformRegistry
5
5
  from jarvis.tools.registry import ToolRegistry
6
6
  from jarvis.utils import OutputType, PrettyOutput
7
7
 
8
+
8
9
  class ToolGeneratorTool:
9
10
  name = "generate_tool"
10
11
  description = "生成新的工具代码并自动注册到Jarvis,自动扩充Jarvis的能力"
@@ -36,13 +37,15 @@ class ToolGeneratorTool:
36
37
  """
37
38
  # 设置工具目录
38
39
  self.tools_dir = Path.home() / '.jarvis_tools'
39
-
40
+
40
41
  # 确保工具目录存在
41
42
  self.tools_dir.mkdir(parents=True, exist_ok=True)
42
43
 
43
- def _generate_tool_code(self, tool_name: str, class_name: str, description: str, parameters: Dict) -> str:
44
+ def _generate_tool_code(self, tool_name: str, class_name: str,
45
+ description: str, parameters: Dict) -> str:
44
46
  """使用大模型生成工具代码"""
45
- platform_name = os.getenv("JARVIS_CODEGEN_PLATFORM") or PlatformRegistry.get_global_platform_name()
47
+ platform_name = os.getenv(
48
+ "JARVIS_CODEGEN_PLATFORM") or PlatformRegistry.get_global_platform_name()
46
49
  model = PlatformRegistry.create_platform(platform_name)
47
50
  model_name = os.getenv("JARVIS_CODEGEN_MODEL")
48
51
  if model_name:
@@ -81,16 +84,16 @@ class ExampleTool:
81
84
  # 验证参数示例
82
85
  if "param1" not in args:
83
86
  return {{"success": False, "error": "缺少必需参数: param1"}}
84
-
87
+
85
88
  # 记录操作示例
86
89
  PrettyOutput.print(f"处理参数: {{args['param1']}}", OutputType.INFO)
87
90
 
88
91
  # 使用大模型示例
89
92
  response = self.model.chat("prompt")
90
-
93
+
91
94
  # 实现具体功能
92
95
  result = "处理结果"
93
-
96
+
94
97
  return {{
95
98
  "success": True,
96
99
  "stdout": result,
@@ -111,11 +114,11 @@ class ExampleTool:
111
114
  # 提取代码块
112
115
  code_start = response.find("```python")
113
116
  code_end = response.find("```", code_start + 9)
114
-
117
+
115
118
  if code_start == -1 or code_end == -1:
116
119
  # 如果没有找到代码块标记,假设整个响应都是代码
117
120
  return response
118
-
121
+
119
122
  # 提取代码块内容(去掉```python和```标记)
120
123
  code = response[code_start + 9:code_end].strip()
121
124
  return code
@@ -162,10 +165,10 @@ class ExampleTool:
162
165
  return {
163
166
  "success": True,
164
167
  "stdout": f"工具已生成并注册到Jarvis\n"
165
- f"工具目录: {self.tools_dir}\n"
166
- f"工具名称: {tool_name}\n"
167
- f"工具描述: {description}\n"
168
- f"工具参数: {parameters}",
168
+ f"工具目录: {self.tools_dir}\n"
169
+ f"工具名称: {tool_name}\n"
170
+ f"工具描述: {description}\n"
171
+ f"工具参数: {parameters}",
169
172
  "stderr": ""
170
173
  }
171
174
 
@@ -6,7 +6,7 @@ from jarvis.utils import OutputType, PrettyOutput
6
6
 
7
7
  class MethodologyTool:
8
8
  """经验管理工具"""
9
-
9
+
10
10
  name = "methodology"
11
11
  description = "管理问题处理经验总结,支持添加、更新、删除操作"
12
12
  parameters = {
@@ -29,12 +29,12 @@ class MethodologyTool:
29
29
  },
30
30
  "required": ["operation", "problem_type"]
31
31
  }
32
-
32
+
33
33
  def __init__(self):
34
34
  """初始化经验管理工具"""
35
35
  self.methodology_file = os.path.expanduser("~/.jarvis_methodology")
36
36
  self._ensure_file_exists()
37
-
37
+
38
38
  def _ensure_file_exists(self):
39
39
  """确保经验总结文件存在"""
40
40
  if not os.path.exists(self.methodology_file):
@@ -43,7 +43,7 @@ class MethodologyTool:
43
43
  yaml.safe_dump({}, f, allow_unicode=True)
44
44
  except Exception as e:
45
45
  PrettyOutput.print(f"创建经验总结文件失败: {str(e)}", OutputType.ERROR)
46
-
46
+
47
47
  def _load_methodologies(self) -> Dict:
48
48
  """加载所有经验总结"""
49
49
  try:
@@ -52,7 +52,7 @@ class MethodologyTool:
52
52
  except Exception as e:
53
53
  PrettyOutput.print(f"加载经验总结失败: {str(e)}", OutputType.ERROR)
54
54
  return {}
55
-
55
+
56
56
  def _save_methodologies(self, methodologies: Dict):
57
57
  """保存所有经验总结"""
58
58
  try:
@@ -60,31 +60,31 @@ class MethodologyTool:
60
60
  yaml.safe_dump(methodologies, f, allow_unicode=True)
61
61
  except Exception as e:
62
62
  PrettyOutput.print(f"保存经验总结失败: {str(e)}", OutputType.ERROR)
63
-
63
+
64
64
  def execute(self, args: Dict[str, Any]) -> Dict[str, Any]:
65
65
  """执行经验总结管理操作
66
-
66
+
67
67
  Args:
68
68
  args: 包含操作参数的字典
69
69
  - operation: 操作类型 (delete/update/add)
70
70
  - problem_type: 问题类型
71
71
  - content: 经验总结内容 (update/add 时必需)
72
-
72
+
73
73
  Returns:
74
74
  Dict[str, Any]: 包含执行结果的字典
75
75
  """
76
76
  operation = args.get("operation")
77
77
  problem_type = args.get("problem_type")
78
78
  content = args.get("content")
79
-
79
+
80
80
  if not operation or not problem_type:
81
81
  return {
82
82
  "success": False,
83
83
  "error": "缺少必要参数: operation 和 problem_type"
84
84
  }
85
-
85
+
86
86
  methodologies = self._load_methodologies()
87
-
87
+
88
88
  try:
89
89
  if operation == "delete":
90
90
  if problem_type in methodologies:
@@ -99,43 +99,43 @@ class MethodologyTool:
99
99
  "success": False,
100
100
  "error": f"未找到问题类型 '{problem_type}' 的经验总结"
101
101
  }
102
-
102
+
103
103
  elif operation in ["update", "add"]:
104
104
  if not content:
105
105
  return {
106
106
  "success": False,
107
107
  "error": "需要提供经验总结内容"
108
108
  }
109
-
109
+
110
110
  methodologies[problem_type] = content
111
111
  self._save_methodologies(methodologies)
112
-
112
+
113
113
  action = "更新" if problem_type in methodologies else "添加"
114
114
  return {
115
115
  "success": True,
116
116
  "stdout": f"已{action}问题类型 '{problem_type}' 的经验总结"
117
117
  }
118
-
118
+
119
119
  else:
120
120
  return {
121
121
  "success": False,
122
122
  "error": f"不支持的操作类型: {operation}"
123
123
  }
124
-
124
+
125
125
  except Exception as e:
126
126
  return {
127
127
  "success": False,
128
128
  "error": f"执行失败: {str(e)}"
129
129
  }
130
-
130
+
131
131
  def get_methodology(self, problem_type: str) -> Optional[str]:
132
132
  """获取指定问题类型的经验总结
133
-
133
+
134
134
  Args:
135
135
  problem_type: 问题类型
136
-
136
+
137
137
  Returns:
138
138
  Optional[str]: 经验总结内容,如果不存在则返回 None
139
139
  """
140
140
  methodologies = self._load_methodologies()
141
- return methodologies.get(problem_type)
141
+ return methodologies.get(problem_type)
jarvis/tools/registry.py CHANGED
@@ -11,7 +11,8 @@ from jarvis.utils import OutputType, PrettyOutput
11
11
 
12
12
 
13
13
  class ToolRegistry:
14
- global_tool_registry = None # type: ignore
14
+ global_tool_registry = None # type: ignore
15
+
15
16
  def __init__(self):
16
17
  """初始化工具注册器
17
18
  """
@@ -30,13 +31,13 @@ class ToolRegistry:
30
31
  def _load_builtin_tools(self):
31
32
  """从内置tools目录加载工具"""
32
33
  tools_dir = Path(__file__).parent
33
-
34
+
34
35
  # 遍历目录下的所有.py文件
35
36
  for file_path in tools_dir.glob("*.py"):
36
37
  # 跳过基础文件和__init__.py
37
38
  if file_path.name in ["base.py", "__init__.py", "registry.py"]:
38
39
  continue
39
-
40
+
40
41
  self.register_tool_by_file(file_path)
41
42
 
42
43
  def _load_external_tools(self):
@@ -44,21 +45,21 @@ class ToolRegistry:
44
45
  external_tools_dir = Path.home() / '.jarvis_tools'
45
46
  if not external_tools_dir.exists():
46
47
  return
47
-
48
+
48
49
  # 遍历目录下的所有.py文件
49
50
  for file_path in external_tools_dir.glob("*.py"):
50
51
  # 跳过__init__.py
51
52
  if file_path.name == "__init__.py":
52
53
  continue
53
-
54
+
54
55
  self.register_tool_by_file(file_path)
55
56
 
56
57
  def register_tool_by_file(self, file_path: str):
57
58
  """从指定文件加载并注册工具
58
-
59
+
59
60
  Args:
60
61
  file_path: 工具文件的路径
61
-
62
+
62
63
  Returns:
63
64
  bool: 是否成功加载工具
64
65
  """
@@ -67,31 +68,32 @@ class ToolRegistry:
67
68
  if not file_path.exists() or not file_path.is_file():
68
69
  PrettyOutput.print(f"文件不存在: {file_path}", OutputType.ERROR)
69
70
  return False
70
-
71
+
71
72
  # 动态导入模块
72
73
  module_name = file_path.stem
73
- spec = importlib.util.spec_from_file_location(module_name, file_path)
74
+ spec = importlib.util.spec_from_file_location(
75
+ module_name, file_path)
74
76
  if not spec or not spec.loader:
75
77
  PrettyOutput.print(f"无法加载模块: {file_path}", OutputType.ERROR)
76
78
  return False
77
-
79
+
78
80
  module = importlib.util.module_from_spec(spec)
79
81
  sys.modules[module_name] = module # 添加到 sys.modules 以支持相对导入
80
82
  spec.loader.exec_module(module)
81
-
83
+
82
84
  # 查找模块中的工具类
83
85
  tool_found = False
84
86
  for item_name in dir(module):
85
87
  item = getattr(module, item_name)
86
88
  # 检查是否是类,并且有必要的属性
87
- if (isinstance(item, type) and
88
- hasattr(item, 'name') and
89
- hasattr(item, 'description') and
90
- hasattr(item, 'parameters')):
91
-
89
+ if (isinstance(item, type) and
90
+ hasattr(item, 'name') and
91
+ hasattr(item, 'description') and
92
+ hasattr(item, 'parameters')):
93
+
92
94
  # 实例化工具类,传入模型和输出处理器
93
95
  tool_instance = item()
94
-
96
+
95
97
  # 注册工具
96
98
  self.register_tool(
97
99
  name=tool_instance.name,
@@ -99,20 +101,31 @@ class ToolRegistry:
99
101
  parameters=tool_instance.parameters,
100
102
  func=tool_instance.execute
101
103
  )
102
- PrettyOutput.print(f"从 {file_path} 加载工具: {tool_instance.name}: {tool_instance.description}", OutputType.INFO)
104
+ PrettyOutput.print(
105
+ f"从 {file_path} 加载工具: {
106
+ tool_instance.name}: {
107
+ tool_instance.description}",
108
+ OutputType.INFO)
103
109
  tool_found = True
104
-
110
+
105
111
  if not tool_found:
106
- PrettyOutput.print(f"文件中未找到有效的工具类: {file_path}", OutputType.WARNING)
112
+ PrettyOutput.print(
113
+ f"文件中未找到有效的工具类: {file_path}",
114
+ OutputType.WARNING)
107
115
  return False
108
-
116
+
109
117
  return True
110
-
118
+
111
119
  except Exception as e:
112
- PrettyOutput.print(f"加载工具失败 {file_path.name}: {str(e)}", OutputType.ERROR)
120
+ PrettyOutput.print(
121
+ f"加载工具失败 {
122
+ file_path.name}: {
123
+ str(e)}",
124
+ OutputType.ERROR)
113
125
  return False
114
126
 
115
- def register_tool(self, name: str, description: str, parameters: Dict, func: Callable):
127
+ def register_tool(self, name: str, description: str,
128
+ parameters: Dict, func: Callable):
116
129
  """注册新工具"""
117
130
  self.tools[name] = Tool(name, description, parameters, func)
118
131
 
@@ -136,12 +149,12 @@ class ToolRegistry:
136
149
  try:
137
150
  if not tool_calls:
138
151
  return ""
139
-
152
+
140
153
  # 只处理第一个工具调用
141
154
  tool_call = tool_calls[0]
142
155
  name = tool_call["name"]
143
156
  args = tool_call["arguments"]
144
-
157
+
145
158
  if isinstance(args, str):
146
159
  try:
147
160
  args = json.loads(args)
@@ -153,13 +166,14 @@ class ToolRegistry:
153
166
  PrettyOutput.section(f"执行工具: {name}", OutputType.TOOL)
154
167
  if isinstance(args, dict):
155
168
  for key, value in args.items():
156
- PrettyOutput.print(f"参数: {key} = {value}", OutputType.DEBUG)
169
+ PrettyOutput.print(
170
+ f"参数: {key} = {value}", OutputType.DEBUG)
157
171
  else:
158
172
  PrettyOutput.print(f"参数: {args}", OutputType.DEBUG)
159
-
173
+
160
174
  # 执行工具调用
161
175
  result = self.execute_tool(name, args)
162
-
176
+
163
177
  # 处理结果
164
178
  if result["success"]:
165
179
  stdout = result["stdout"]
@@ -176,7 +190,7 @@ class ToolRegistry:
176
190
  error_msg = result["error"]
177
191
  output = f"执行失败: {error_msg}"
178
192
  PrettyOutput.section("执行失败", OutputType.ERROR)
179
-
193
+
180
194
  return output
181
195
  except Exception as e:
182
196
  PrettyOutput.print(f"执行工具失败: {str(e)}", OutputType.ERROR)
jarvis/tools/shell.py CHANGED
@@ -21,7 +21,6 @@ class ShellTool:
21
21
  "required": ["command"]
22
22
  }
23
23
 
24
-
25
24
  def _escape_command(self, cmd: str) -> str:
26
25
  """转义命令中的特殊字符"""
27
26
  return cmd.replace("'", "'\"'\"'")
@@ -30,21 +29,23 @@ class ShellTool:
30
29
  """执行shell命令"""
31
30
  try:
32
31
  command = args["command"]
33
-
32
+
34
33
  # 生成临时文件名
35
- output_file = os.path.join(tempfile.gettempdir(), f"jarvis_shell_{os.getpid()}.log")
36
-
34
+ output_file = os.path.join(
35
+ tempfile.gettempdir(), f"jarvis_shell_{
36
+ os.getpid()}.log")
37
+
37
38
  # 转义命令中的特殊字符
38
39
  escaped_command = self._escape_command(command)
39
-
40
+
40
41
  # 修改命令以使用script
41
42
  tee_command = f"script -q -c '{escaped_command}' {output_file}"
42
-
43
+
43
44
  PrettyOutput.print(f"执行命令: {command}", OutputType.INFO)
44
-
45
+
45
46
  # 执行命令
46
47
  return_code = os.system(tee_command)
47
-
48
+
48
49
  # 读取输出文件
49
50
  try:
50
51
  with open(output_file, 'r', encoding='utf-8', errors='replace') as f:
@@ -59,14 +60,14 @@ class ShellTool:
59
60
  finally:
60
61
  # 清理临时文件
61
62
  Path(output_file).unlink(missing_ok=True)
62
-
63
+
63
64
  return {
64
65
  "success": return_code == 0,
65
66
  "stdout": output,
66
67
  "stderr": "",
67
68
  "return_code": return_code
68
69
  }
69
-
70
+
70
71
  except Exception as e:
71
72
  # 确保清理临时文件
72
73
  if 'output_file' in locals():
@@ -75,4 +76,4 @@ class ShellTool:
75
76
  return {
76
77
  "success": False,
77
78
  "error": str(e)
78
- }
79
+ }
jarvis/tools/sub_agent.py CHANGED
@@ -39,7 +39,6 @@ class SubAgentTool:
39
39
  "required": ["agent_name", "task", "context", "goal"]
40
40
  }
41
41
 
42
-
43
42
  def execute(self, args: Dict) -> Dict[str, Any]:
44
43
  """创建并运行子代理"""
45
44
  try:
@@ -79,4 +78,4 @@ class SubAgentTool:
79
78
  return {
80
79
  "success": False,
81
80
  "error": f"子代理执行失败: {str(e)}"
82
- }
81
+ }