jarvis-ai-assistant 0.1.125__py3-none-any.whl → 0.1.128__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of jarvis-ai-assistant might be problematic. Click here for more details.

Files changed (49) hide show
  1. jarvis/__init__.py +1 -1
  2. jarvis/jarvis_agent/__init__.py +205 -187
  3. jarvis/jarvis_code_agent/code_agent.py +116 -109
  4. jarvis/jarvis_code_agent/patch.py +157 -138
  5. jarvis/jarvis_code_agent/shell_input_handler.py +22 -0
  6. jarvis/jarvis_codebase/main.py +314 -288
  7. jarvis/jarvis_dev/main.py +695 -716
  8. jarvis/jarvis_lsp/base.py +0 -12
  9. jarvis/jarvis_lsp/cpp.py +0 -9
  10. jarvis/jarvis_lsp/go.py +0 -9
  11. jarvis/jarvis_lsp/python.py +0 -28
  12. jarvis/jarvis_lsp/registry.py +0 -1
  13. jarvis/jarvis_lsp/rust.py +0 -9
  14. jarvis/jarvis_multi_agent/__init__.py +52 -52
  15. jarvis/jarvis_platform/base.py +6 -5
  16. jarvis/jarvis_platform_manager/main.py +1 -1
  17. jarvis/jarvis_rag/main.py +250 -186
  18. jarvis/jarvis_smart_shell/main.py +0 -1
  19. jarvis/jarvis_tools/ask_codebase.py +10 -9
  20. jarvis/jarvis_tools/ask_user.py +2 -2
  21. jarvis/jarvis_tools/base.py +4 -4
  22. jarvis/jarvis_tools/chdir.py +28 -28
  23. jarvis/jarvis_tools/code_review.py +44 -39
  24. jarvis/jarvis_tools/create_code_agent.py +4 -4
  25. jarvis/jarvis_tools/create_sub_agent.py +7 -7
  26. jarvis/jarvis_tools/execute_shell.py +53 -23
  27. jarvis/jarvis_tools/execute_shell_script.py +3 -3
  28. jarvis/jarvis_tools/file_operation.py +70 -41
  29. jarvis/jarvis_tools/git_commiter.py +61 -51
  30. jarvis/jarvis_tools/lsp_find_definition.py +7 -7
  31. jarvis/jarvis_tools/lsp_prepare_rename.py +7 -7
  32. jarvis/jarvis_tools/methodology.py +6 -6
  33. jarvis/jarvis_tools/rag.py +5 -5
  34. jarvis/jarvis_tools/read_webpage.py +52 -32
  35. jarvis/jarvis_tools/registry.py +167 -180
  36. jarvis/jarvis_tools/search_web.py +66 -41
  37. jarvis/jarvis_tools/select_code_files.py +3 -3
  38. jarvis/jarvis_tools/tool_generator.py +68 -55
  39. jarvis/jarvis_utils/methodology.py +77 -59
  40. jarvis/jarvis_utils/output.py +1 -0
  41. {jarvis_ai_assistant-0.1.125.dist-info → jarvis_ai_assistant-0.1.128.dist-info}/METADATA +31 -17
  42. jarvis_ai_assistant-0.1.128.dist-info/RECORD +74 -0
  43. {jarvis_ai_assistant-0.1.125.dist-info → jarvis_ai_assistant-0.1.128.dist-info}/WHEEL +1 -1
  44. jarvis/jarvis_tools/lsp_validate_edit.py +0 -141
  45. jarvis/jarvis_tools/read_code.py +0 -192
  46. jarvis_ai_assistant-0.1.125.dist-info/RECORD +0 -75
  47. {jarvis_ai_assistant-0.1.125.dist-info → jarvis_ai_assistant-0.1.128.dist-info}/LICENSE +0 -0
  48. {jarvis_ai_assistant-0.1.125.dist-info → jarvis_ai_assistant-0.1.128.dist-info}/entry_points.txt +0 -0
  49. {jarvis_ai_assistant-0.1.125.dist-info → jarvis_ai_assistant-0.1.128.dist-info}/top_level.txt +0 -0
@@ -5,6 +5,7 @@ import sys
5
5
  from typing import Any, Callable, Dict, List, Optional, Tuple
6
6
 
7
7
  import yaml
8
+ from yaspin import yaspin
8
9
 
9
10
  from jarvis.jarvis_agent.output_handler import OutputHandler
10
11
  from jarvis.jarvis_platform.registry import PlatformRegistry
@@ -16,41 +17,41 @@ from jarvis.jarvis_utils.output import OutputType, PrettyOutput
16
17
 
17
18
 
18
19
  tool_call_help = """
19
- # 🛠️ Tool Usage System
20
- You are using a tool execution system that requires precise formatting and strict rules.
20
+ # 🛠️ 工具使用系统
21
+ 您正在使用一个需要精确格式和严格规则的工具执行系统。
21
22
 
22
- # 📋 Tool Call Format
23
+ # 📋 工具调用格式
23
24
  <TOOL_CALL>
24
- name: tool_name
25
+ name: 工具名称
25
26
  arguments:
26
- param1: value1
27
- param2: value2
27
+ param1: 值1
28
+ param2: 值2
28
29
  </TOOL_CALL>
29
30
 
30
- # ❗ Critical Rules
31
- 1. ONE Tool Per Turn
32
- - Execute only ONE tool at a time
33
- - Wait for results before next action
31
+ # ❗ 关键规则
32
+ 1. 每次只使用一个工具
33
+ - 一次只执行一个工具
34
+ - 等待结果后再进行下一步
34
35
 
35
- 2. Strict Format Adherence
36
- - Follow exact format shown above
37
- - Use proper YAML indentation
38
- - Include all required parameters
36
+ 2. 严格遵守格式
37
+ - 完全按照上述格式
38
+ - 使用正确的YAML缩进
39
+ - 包含所有必需参数
39
40
 
40
- 3. Result Handling
41
- - Wait for execution results
42
- - Never assume outcomes
43
- - Don't create fake responses
44
- - Don't imagine dialogues
41
+ 3. 结果处理
42
+ - 等待执行结果
43
+ - 不要假设结果
44
+ - 不要创建虚假响应
45
+ - 不要想象对话
45
46
 
46
- 4. Information Management
47
- - Ask user if info is insufficient
48
- - Skip unnecessary steps
49
- - Request guidance if stuck
50
- - Don't proceed with incomplete info
47
+ 4. 信息管理
48
+ - 如果信息不足,询问用户
49
+ - 跳过不必要的步骤
50
+ - 如果卡住,请求指导
51
+ - 不要在没有完整信息的情况下继续
51
52
 
52
- # 📝 String Parameter Format
53
- ALWAYS use | syntax for string parameters:
53
+ # 📝 字符串参数格式
54
+ 始终使用 | 语法表示字符串参数:
54
55
 
55
56
  <TOOL_CALL>
56
57
  name: execute_shell
@@ -59,19 +60,19 @@ arguments:
59
60
  git status --porcelain
60
61
  </TOOL_CALL>
61
62
 
62
- # 💡 Best Practices
63
- - Start execution immediately when ready
64
- - No need to ask for permission to begin
65
- - Use proper string formatting
66
- - Monitor progress and adjust
67
- - Request help when stuck
68
-
69
- # ⚠️ Common Mistakes to Avoid
70
- - Multiple tool calls at once
71
- - Missing | for string parameters
72
- - Assuming tool results
73
- - Creating fictional dialogues
74
- - Proceeding without required info
63
+ # 💡 最佳实践
64
+ - 准备好后立即开始执行
65
+ - 无需请求许可即可开始
66
+ - 使用正确的字符串格式
67
+ - 监控进度并调整
68
+ - 遇到困难时请求帮助
69
+
70
+ # ⚠️ 常见错误
71
+ - 同时调用多个工具
72
+ - 字符串参数缺少 |
73
+ - 假设工具结果
74
+ - 创建虚构对话
75
+ - 在没有所需信息的情况下继续
75
76
  """
76
77
 
77
78
  class ToolRegistry(OutputHandler):
@@ -85,14 +86,14 @@ class ToolRegistry(OutputHandler):
85
86
  return False
86
87
 
87
88
  def prompt(self) -> str:
88
- """Load tools"""
89
+ """加载工具"""
89
90
  tools = self.get_all_tools()
90
91
  if tools:
91
- tools_prompt = "## Available tools:\n"
92
+ tools_prompt = "## 可用工具:\n"
92
93
  for tool in tools:
93
- tools_prompt += f"- Name: {tool['name']}\n"
94
- tools_prompt += f" Description: {tool['description']}\n"
95
- tools_prompt += f" Parameters: {tool['parameters']}\n"
94
+ tools_prompt += f"- 名称: {tool['name']}\n"
95
+ tools_prompt += f" 描述: {tool['description']}\n"
96
+ tools_prompt += f" 参数: {tool['parameters']}\n"
96
97
  tools_prompt += tool_call_help
97
98
  return tools_prompt
98
99
  return ""
@@ -101,87 +102,87 @@ class ToolRegistry(OutputHandler):
101
102
  tool_calls = self._extract_tool_calls(response)
102
103
  if len(tool_calls) > 1:
103
104
  PrettyOutput.print(f"操作失败:检测到多个操作。一次只能执行一个操作。尝试执行的操作:{', '.join([tool_call['name'] for tool_call in tool_calls])}", OutputType.WARNING)
104
- return False, f"Call failed: Handle multiple tool calls, please ONLY handle one tool call at a time."
105
+ return False, f"调用失败:请一次只处理一个工具调用。"
105
106
  if len(tool_calls) == 0:
106
107
  return False, ""
107
108
  tool_call = tool_calls[0]
108
109
  return False, self.handle_tool_calls(tool_call)
109
110
 
110
111
  def __init__(self):
111
- """Initialize tool registry"""
112
+ """初始化工具注册表"""
112
113
  self.tools: Dict[str, Tool] = {}
113
- # Load built-in tools and external tools
114
+ # 加载内置工具和外部工具
114
115
  self._load_builtin_tools()
115
116
  self._load_external_tools()
116
- # Ensure max_token_count is an integer
117
+ # 确保max_token_count是整数
117
118
  self.max_token_count = int(get_max_token_count() * 0.8)
118
119
 
119
120
  def use_tools(self, name: List[str]):
120
- """Use specified tools"""
121
+ """使用指定工具"""
121
122
  missing_tools = [tool_name for tool_name in name if tool_name not in self.tools]
122
123
  if missing_tools:
123
124
  PrettyOutput.print(f"工具 {missing_tools} 不存在,可用的工具有: {', '.join(self.tools.keys())}", OutputType.WARNING)
124
125
  self.tools = {tool_name: self.tools[tool_name] for tool_name in name}
125
126
 
126
127
  def dont_use_tools(self, names: List[str]):
127
- """Remove specified tools from the registry"""
128
+ """从注册表中移除指定工具"""
128
129
  self.tools = {name: tool for name, tool in self.tools.items() if name not in names}
129
130
 
130
131
  def _load_builtin_tools(self):
131
- """Load tools from the built-in tools directory"""
132
+ """从内置工具目录加载工具"""
132
133
  tools_dir = Path(__file__).parent
133
134
 
134
- # Iterate through all .py files in the directory
135
+ # 遍历目录中的所有.py文件
135
136
  for file_path in tools_dir.glob("*.py"):
136
- # Skip base.py and __init__.py
137
+ # 跳过base.py__init__.py
137
138
  if file_path.name in ["base.py", "__init__.py", "registry.py"]:
138
139
  continue
139
140
 
140
141
  self.register_tool_by_file(str(file_path))
141
142
 
142
143
  def _load_external_tools(self):
143
- """Load external tools from ~/.jarvis/tools"""
144
+ """从~/.jarvis/tools加载外部工具"""
144
145
  external_tools_dir = Path.home() / '.jarvis/tools'
145
146
  if not external_tools_dir.exists():
146
147
  return
147
148
 
148
- # Iterate through all .py files in the directory
149
+ # 遍历目录中的所有.py文件
149
150
  for file_path in external_tools_dir.glob("*.py"):
150
- # Skip __init__.py
151
+ # 跳过__init__.py
151
152
  if file_path.name == "__init__.py":
152
153
  continue
153
154
 
154
155
  self.register_tool_by_file(str(file_path))
155
156
 
156
157
  def register_tool_by_file(self, file_path: str):
157
- """Load and register tools from a specified file
158
+ """从指定文件加载并注册工具
158
159
 
159
- Args:
160
- file_path: The path of the tool file
160
+ 参数:
161
+ file_path: 工具文件的路径
161
162
 
162
- Returns:
163
- bool: Whether the tool is loaded successfully
163
+ 返回:
164
+ bool: 工具是否加载成功
164
165
  """
165
166
  try:
166
- p_file_path = Path(file_path).resolve() # Get the absolute path
167
+ p_file_path = Path(file_path).resolve() # 获取绝对路径
167
168
  if not p_file_path.exists() or not p_file_path.is_file():
168
169
  PrettyOutput.print(f"文件不存在: {p_file_path}", OutputType.ERROR)
169
170
  return False
170
171
 
171
- # Add the parent directory to sys.path temporarily
172
+ # 临时将父目录添加到sys.path
172
173
  parent_dir = str(p_file_path.parent)
173
174
  sys.path.insert(0, parent_dir)
174
175
 
175
176
  try:
176
- # Import the module using standard import mechanism
177
+ # 使用标准导入机制导入模块
177
178
  module_name = p_file_path.stem
178
179
  module = __import__(module_name)
179
180
 
180
- # Find the tool class in the module
181
+ # 在模块中查找工具类
181
182
  tool_found = False
182
183
  for item_name in dir(module):
183
184
  item = getattr(module, item_name)
184
- # Check if it is a class and has the necessary attributes
185
+ # 检查是否是类并具有必要属性
185
186
  if (isinstance(item, type) and
186
187
  hasattr(item, 'name') and
187
188
  hasattr(item, 'description') and
@@ -193,10 +194,10 @@ class ToolRegistry(OutputHandler):
193
194
  if not item.check():
194
195
  continue
195
196
 
196
- # Instantiate the tool class
197
+ # 实例化工具类
197
198
  tool_instance = item()
198
199
 
199
- # Register the tool
200
+ # 注册工具
200
201
  self.register_tool(
201
202
  name=tool_instance.name,
202
203
  description=tool_instance.description,
@@ -212,7 +213,7 @@ class ToolRegistry(OutputHandler):
212
213
  return True
213
214
 
214
215
  finally:
215
- # Remove the directory from sys.path
216
+ # sys.path中移除目录
216
217
  sys.path.remove(parent_dir)
217
218
 
218
219
  except Exception as e:
@@ -220,18 +221,18 @@ class ToolRegistry(OutputHandler):
220
221
  return False
221
222
  @staticmethod
222
223
  def _extract_tool_calls(content: str) -> List[Dict]:
223
- """Extract tool calls from content.
224
+ """从内容中提取工具调用。
224
225
 
225
- Args:
226
- content: The content containing tool calls
226
+ 参数:
227
+ content: 包含工具调用的内容
227
228
 
228
- Returns:
229
- List[Dict]: List of extracted tool calls with name and arguments
229
+ 返回:
230
+ List[Dict]: 包含名称和参数的提取工具调用列表
230
231
 
231
- Raises:
232
- Exception: If tool call is missing necessary fields
232
+ 异常:
233
+ Exception: 如果工具调用缺少必要字段
233
234
  """
234
- # Split content into lines
235
+ # 将内容拆分为行
235
236
  data = re.findall(r'<TOOL_CALL>(.*?)</TOOL_CALL>', content, re.DOTALL)
236
237
  ret = []
237
238
  for item in data:
@@ -244,68 +245,68 @@ class ToolRegistry(OutputHandler):
244
245
  return ret
245
246
 
246
247
  def register_tool(self, name: str, description: str, parameters: Dict, func: Callable):
247
- """Register a new tool"""
248
+ """注册新工具"""
248
249
  self.tools[name] = Tool(name, description, parameters, func)
249
250
 
250
251
  def get_tool(self, name: str) -> Optional[Tool]:
251
- """Get a tool"""
252
+ """获取工具"""
252
253
  return self.tools.get(name)
253
254
 
254
255
  def get_all_tools(self) -> List[Dict]:
255
- """Get all tools in Ollama format definition"""
256
+ """获取所有工具(Ollama格式定义)"""
256
257
  return [tool.to_dict() for tool in self.tools.values()]
257
258
 
258
259
  def execute_tool(self, name: str, arguments: Dict) -> Dict[str, Any]:
259
- """Execute a specified tool"""
260
+ """执行指定工具"""
260
261
  tool = self.get_tool(name)
261
262
  if tool is None:
262
- return {"success": False, "stderr": f"Tool {name} does not exist, available tools: {', '.join(self.tools.keys())}", "stdout": ""}
263
+ return {"success": False, "stderr": f"工具 {name} 不存在,可用的工具有: {', '.join(self.tools.keys())}", "stdout": ""}
263
264
  return tool.execute(arguments)
264
265
 
265
266
  def handle_tool_calls(self, tool_call: Dict) -> str:
266
- """Handle tool calls, only process the first tool"""
267
+ """处理工具调用,只处理第一个工具"""
267
268
  try:
268
- # Only process the first tool call
269
+ # 只处理第一个工具调用
269
270
  name = tool_call["name"]
270
271
  args = tool_call["arguments"]
271
272
 
272
273
  tool_call_help = """
273
- # 🛠️ Tool Usage System
274
- You are using a tool execution system that requires precise formatting and strict rules.
274
+ # 🛠️ 工具使用系统
275
+ 您正在使用一个需要精确格式和严格规则的工具执行系统。
275
276
 
276
- # 📋 Tool Call Format
277
+ # 📋 工具调用格式
277
278
 
278
279
  <TOOL_CALL>
279
- name: tool_name
280
+ name: 工具名称
280
281
  arguments:
281
- param1: value1
282
- param2: value2
282
+ param1: 值1
283
+ param2: 值2
283
284
  </TOOL_CALL>
284
285
 
285
- # ❗ Critical Rules
286
- 1. ONE Tool Per Turn
287
- - Execute only ONE tool at a time
288
- - Wait for results before next action
286
+ # ❗ 关键规则
287
+ 1. 每次只使用一个工具
288
+ - 一次只执行一个工具
289
+ - 等待结果后再进行下一步
289
290
 
290
- 2. Strict Format Adherence
291
- - Follow exact format shown above
292
- - Use proper YAML indentation
293
- - Include all required parameters
291
+ 2. 严格遵守格式
292
+ - 完全按照上述格式
293
+ - 使用正确的YAML缩进
294
+ - 包含所有必需参数
294
295
 
295
- 3. Result Handling
296
- - Wait for execution results
297
- - Never assume outcomes
298
- - Don't create fake responses
299
- - Don't imagine dialogues
296
+ 3. 结果处理
297
+ - 等待执行结果
298
+ - 不要假设结果
299
+ - 不要创建虚假响应
300
+ - 不要想象对话
300
301
 
301
- 4. Information Management
302
- - Ask user if info is insufficient
303
- - Skip unnecessary steps
304
- - Request guidance if stuck
305
- - Don't proceed with incomplete info
302
+ 4. 信息管理
303
+ - 如果信息不足,询问用户
304
+ - 跳过不必要的步骤
305
+ - 如果卡住,请求指导
306
+ - 不要在没有完整信息的情况下继续
306
307
 
307
- # 📝 String Parameter Format
308
- ALWAYS use | syntax for string parameters:
308
+ # 📝 字符串参数格式
309
+ 始终使用 | 语法表示字符串参数:
309
310
 
310
311
  <TOOL_CALL>
311
312
  name: execute_shell
@@ -314,19 +315,19 @@ arguments:
314
315
  git status --porcelain
315
316
  </TOOL_CALL>
316
317
 
317
- # 💡 Best Practices
318
- - Start execution immediately when ready
319
- - No need to ask for permission to begin
320
- - Use proper string formatting
321
- - Monitor progress and adjust
322
- - Request help when stuck
323
-
324
- # ⚠️ Common Mistakes to Avoid
325
- - Multiple tool calls at once
326
- - Missing | for string parameters
327
- - Assuming tool results
328
- - Creating fictional dialogues
329
- - Proceeding without required info
318
+ # 💡 最佳实践
319
+ - 准备好后立即开始执行
320
+ - 无需请求许可即可开始
321
+ - 使用正确的字符串格式
322
+ - 监控进度并调整
323
+ - 遇到困难时请求帮助
324
+
325
+ # ⚠️ 常见错误
326
+ - 同时调用多个工具
327
+ - 字符串参数缺少 |
328
+ - 假设工具结果
329
+ - 创建虚构对话
330
+ - 在没有所需信息的情况下继续
330
331
  """
331
332
 
332
333
  if isinstance(args, str):
@@ -335,17 +336,6 @@ arguments:
335
336
  except json.JSONDecodeError:
336
337
  PrettyOutput.print(f"工具参数格式无效: {name} {tool_call_help}", OutputType.ERROR)
337
338
  return ""
338
-
339
- # Display tool call information
340
- PrettyOutput.section(f"执行工具: {name}", OutputType.TOOL)
341
- params = "参数:\n"
342
- if isinstance(args, dict):
343
- for key, value in args.items():
344
- params += f"{key} = {value}\n"
345
- else:
346
- params += f"{args}"
347
-
348
- PrettyOutput.print(params, OutputType.INFO)
349
339
 
350
340
  # Execute tool call
351
341
  result = self.execute_tool(name, args)
@@ -354,60 +344,57 @@ arguments:
354
344
  stderr = result.get("stderr", "")
355
345
  output_parts = []
356
346
  if stdout:
357
- output_parts.append(f"Output:\n{stdout}")
347
+ output_parts.append(f"输出:\n{stdout}")
358
348
  if stderr:
359
- output_parts.append(f"Error:\n{stderr}")
349
+ output_parts.append(f"错误:\n{stderr}")
360
350
  output = "\n\n".join(output_parts)
361
- output = "no output and error" if not output else output
351
+ output = "无输出和错误" if not output else output
362
352
 
363
353
  # Process the result
364
354
  if result["success"]:
365
-
366
- PrettyOutput.section("执行成功", OutputType.SUCCESS)
367
-
368
355
  # If the output exceeds 4k characters, use a large model to summarize
369
356
  if get_context_token_count(output) > self.max_token_count:
370
- try:
371
- PrettyOutput.print("输出过长,正在总结...", OutputType.PROGRESS)
372
- model = PlatformRegistry.get_global_platform_registry().get_normal_platform()
373
-
374
- # If the output exceeds the maximum context length, only take the last part
375
- max_count = self.max_token_count
376
- if get_context_token_count(output) > max_count:
377
- output_to_summarize = output[-max_count:]
378
- truncation_notice = f"\n(Note: Due to the length of the output, only the last {max_count} characters are summarized)"
379
- else:
380
- output_to_summarize = output
381
- truncation_notice = ""
382
-
383
- prompt = f"""Please summarize the execution result of the following tool, extracting key information and important results. Note:
384
- 1. Keep all important numerical values, paths, error information, etc.
385
- 2. Maintain the accuracy of the results
386
- 3. Describe the main content in concise language
387
- 4. If there is error information, ensure it is included in the summary
388
-
389
- Tool name: {name}
390
- Execution result:
391
- {output_to_summarize}
392
-
393
- Please provide a summary:"""
394
-
395
- summary = model.chat_until_success(prompt)
396
- output = f"""--- Original output is too long, here is the summary ---{truncation_notice}
397
-
398
- {summary}
399
-
400
- --- Summary ends ---"""
401
-
402
- except Exception as e:
403
- PrettyOutput.print(f"总结失败: {str(e)}", OutputType.ERROR)
404
- output = f"Output is too long ({len(output)} characters), it is recommended to view the original output.\nPreview of the first 300 characters:\n{output[:300]}..."
405
-
406
- else:
407
- PrettyOutput.section("执行失败", OutputType.WARNING)
408
- PrettyOutput.print(result["stderr"], OutputType.WARNING)
357
+ with yaspin(text="正在总结输出...", color="yellow") as spinner:
358
+ try:
359
+
360
+ model = PlatformRegistry.get_global_platform_registry().get_normal_platform()
361
+
362
+ # If the output exceeds the maximum context length, only take the last part
363
+ max_count = self.max_token_count
364
+ if get_context_token_count(output) > max_count:
365
+ output_to_summarize = output[-max_count:]
366
+ truncation_notice = f"\n(注意:由于输出过长,仅总结最后 {max_count} 个字符)"
367
+ else:
368
+ output_to_summarize = output
369
+ truncation_notice = ""
370
+
371
+ prompt = f"""请总结以下工具的执行结果,提取关键信息和重要结果。注意:
372
+ 1. 保留所有重要的数值、路径、错误信息等
373
+ 2. 保持结果的准确性
374
+ 3. 用简洁的语言描述主要内容
375
+ 4. 如果有错误信息,确保包含在总结中
376
+
377
+ 工具名称: {name}
378
+ 执行结果:
379
+ {output_to_summarize}
380
+
381
+ 请提供总结:"""
382
+
383
+ summary = model.chat_until_success(prompt)
384
+ output = f"""--- 原始输出过长,以下是总结 ---{truncation_notice}
385
+
386
+ {summary}
387
+
388
+ --- 总结结束 ---"""
389
+ spinner.text = "总结完成"
390
+ spinner.ok("")
391
+ except Exception as e:
392
+ spinner.text = "总结失败"
393
+ spinner.fail("❌")
394
+ PrettyOutput.print(f"总结失败: {str(e)}", OutputType.ERROR)
395
+ output = f"输出过长 ({len(output)} 字符),建议查看原始输出。\n前300字符预览:\n{output[:300]}..."
409
396
  return output
410
397
 
411
398
  except Exception as e:
412
399
  PrettyOutput.print(f"工具执行失败:{str(e)}", OutputType.ERROR)
413
- return f"Tool call failed: {str(e)}"
400
+ return f"工具调用失败: {str(e)}"