jarvis-ai-assistant 0.3.27__py3-none-any.whl → 0.3.28__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.
Files changed (51) hide show
  1. jarvis/__init__.py +1 -1
  2. jarvis/jarvis_agent/__init__.py +13 -4
  3. jarvis/jarvis_agent/agent_manager.py +6 -0
  4. jarvis/jarvis_agent/config_editor.py +1 -1
  5. jarvis/jarvis_agent/file_methodology_manager.py +1 -3
  6. jarvis/jarvis_agent/jarvis.py +8 -1
  7. jarvis/jarvis_agent/memory_manager.py +0 -1
  8. jarvis/jarvis_agent/shell_input_handler.py +1 -1
  9. jarvis/jarvis_agent/task_analyzer.py +1 -2
  10. jarvis/jarvis_agent/user_interaction.py +1 -1
  11. jarvis/jarvis_code_agent/code_agent.py +2 -2
  12. jarvis/jarvis_code_analysis/code_review.py +0 -1
  13. jarvis/jarvis_git_utils/git_commiter.py +13 -4
  14. jarvis/jarvis_mcp/stdio_mcp_client.py +1 -1
  15. jarvis/jarvis_memory_organizer/memory_organizer.py +2 -5
  16. jarvis/jarvis_methodology/main.py +0 -2
  17. jarvis/jarvis_multi_agent/__init__.py +3 -3
  18. jarvis/jarvis_platform/base.py +1 -1
  19. jarvis/jarvis_platform/registry.py +1 -1
  20. jarvis/jarvis_platform/yuanbao.py +0 -1
  21. jarvis/jarvis_platform_manager/service.py +1 -1
  22. jarvis/jarvis_rag/cli.py +1 -1
  23. jarvis/jarvis_rag/embedding_manager.py +0 -1
  24. jarvis/jarvis_rag/llm_interface.py +0 -3
  25. jarvis/jarvis_smart_shell/main.py +0 -1
  26. jarvis/jarvis_stats/cli.py +2 -3
  27. jarvis/jarvis_stats/stats.py +1 -2
  28. jarvis/jarvis_tools/clear_memory.py +1 -3
  29. jarvis/jarvis_tools/cli/main.py +0 -1
  30. jarvis/jarvis_tools/edit_file.py +0 -1
  31. jarvis/jarvis_tools/generate_new_tool.py +3 -5
  32. jarvis/jarvis_tools/registry.py +2 -3
  33. jarvis/jarvis_tools/retrieve_memory.py +2 -3
  34. jarvis/jarvis_tools/save_memory.py +3 -3
  35. jarvis/jarvis_tools/search_web.py +2 -2
  36. jarvis/jarvis_tools/sub_agent.py +20 -1
  37. jarvis/jarvis_tools/sub_code_agent.py +17 -1
  38. jarvis/jarvis_tools/virtual_tty.py +3 -14
  39. jarvis/jarvis_utils/builtin_replace_map.py +4 -4
  40. jarvis/jarvis_utils/config.py +30 -15
  41. jarvis/jarvis_utils/git_utils.py +1 -1
  42. jarvis/jarvis_utils/globals.py +1 -2
  43. jarvis/jarvis_utils/methodology.py +3 -5
  44. jarvis/jarvis_utils/output.py +1 -1
  45. jarvis/jarvis_utils/utils.py +64 -22
  46. {jarvis_ai_assistant-0.3.27.dist-info → jarvis_ai_assistant-0.3.28.dist-info}/METADATA +1 -1
  47. {jarvis_ai_assistant-0.3.27.dist-info → jarvis_ai_assistant-0.3.28.dist-info}/RECORD +51 -51
  48. {jarvis_ai_assistant-0.3.27.dist-info → jarvis_ai_assistant-0.3.28.dist-info}/WHEEL +0 -0
  49. {jarvis_ai_assistant-0.3.27.dist-info → jarvis_ai_assistant-0.3.28.dist-info}/entry_points.txt +0 -0
  50. {jarvis_ai_assistant-0.3.27.dist-info → jarvis_ai_assistant-0.3.28.dist-info}/licenses/LICENSE +0 -0
  51. {jarvis_ai_assistant-0.3.27.dist-info → jarvis_ai_assistant-0.3.28.dist-info}/top_level.txt +0 -0
@@ -8,12 +8,13 @@ sub_code_agent 工具
8
8
  - 不依赖父 Agent,所有配置使用系统默认与全局变量
9
9
  - 子Agent必须自动完成(auto_complete=True)且需要summary(need_summary=True)
10
10
  """
11
- from typing import Any, Dict, Optional
11
+ from typing import Any, Dict
12
12
  import json
13
13
 
14
14
  from jarvis.jarvis_code_agent.code_agent import CodeAgent
15
15
  from jarvis.jarvis_utils.globals import delete_agent
16
16
  from jarvis.jarvis_utils.config import set_config, get_git_check_mode
17
+ from jarvis.jarvis_utils.output import OutputType, PrettyOutput
17
18
 
18
19
 
19
20
  class SubCodeAgentTool:
@@ -171,6 +172,21 @@ class SubCodeAgentTool:
171
172
  model_obj: Any = getattr(code_agent.agent, "model", None)
172
173
  if model_obj is not None:
173
174
  model_obj.set_model_name(parent_model_name)
175
+ # 模型有效性校验与回退,确保父Agent模型在子Agent平台上可用
176
+ try:
177
+ available_models = model_obj.get_model_list()
178
+ if available_models:
179
+ available_names = [m for m, _ in available_models]
180
+ current_model_name = model_obj.name()
181
+ if current_model_name not in available_names:
182
+ PrettyOutput.print(
183
+ f"检测到子CodeAgent模型 {current_model_name} 不存在于平台 {model_obj.platform_name()} 的可用模型列表,将回退到 {available_names[0]}",
184
+ OutputType.WARNING,
185
+ )
186
+ model_obj.set_model_name(available_names[0])
187
+ except Exception:
188
+ # 获取模型列表或设置模型失败时,保持原设置并继续,交由底层报错处理
189
+ pass
174
190
  except Exception:
175
191
  pass
176
192
  except Exception:
@@ -7,25 +7,14 @@ from jarvis.jarvis_utils.output import OutputType, PrettyOutput
7
7
 
8
8
  # 为了类型检查,总是导入这些模块
9
9
  if TYPE_CHECKING:
10
- import fcntl
11
- import pty
12
- import select
13
- import signal
14
- import subprocess
15
- import threading
16
- import queue
10
+ pass
17
11
 
18
12
  # 平台相关的导入
19
13
  if sys.platform != "win32":
20
- import fcntl
21
- import pty
22
- import select
23
- import signal
14
+ pass
24
15
  else:
25
16
  # Windows平台的导入
26
- import subprocess
27
- import threading
28
- import queue
17
+ pass
29
18
 
30
19
 
31
20
  class VirtualTTYTool:
@@ -31,25 +31,25 @@ arguments:
31
31
  },
32
32
  "FindRelatedFiles": {
33
33
  "append": False,
34
- "template": f"""
34
+ "template": """
35
35
  请使用工具在当前目录下查找与以下功能相关的文件:
36
36
  """,
37
37
  },
38
38
  "Dev": {
39
39
  "append": False,
40
- "template": f"""
40
+ "template": """
41
41
  请调用create_code_agent开发以下需求:
42
42
  """,
43
43
  },
44
44
  "Fix": {
45
45
  "append": False,
46
- "template": f"""
46
+ "template": """
47
47
  请修复以下问题:
48
48
  """,
49
49
  },
50
50
  "Check": {
51
51
  "append": True,
52
- "template": f"""
52
+ "template": """
53
53
  请使用静态检查工具检查当前代码,必须严格遵守工具调用格式。
54
54
 
55
55
  检查要求:
@@ -130,9 +130,14 @@ def _get_resolved_model_config(
130
130
  解析并合并模型配置,处理模型组。
131
131
 
132
132
  优先级顺序:
133
- 1. 单独的环境变量 (JARVIS_PLATFORM, JARVIS_MODEL, etc.)
134
- 2. JARVIS_LLM_GROUP 中定义的组配置
135
- 3. 代码中的默认值
133
+ - 当通过 model_group_override(例如命令行 -g/--llm-group)指定组时:
134
+ 1. JARVIS_LLM_GROUP 中定义的组配置
135
+ 2. 仅当组未提供对应键时,回退到顶层环境变量 (JARVIS_PLATFORM, JARVIS_MODEL, JARVIS_MAX_INPUT_TOKEN_COUNT)
136
+ 3. 代码中的默认值
137
+ - 当未显式指定组时(使用默认组或未设置):
138
+ 1. 顶层环境变量 (JARVIS_PLATFORM, JARVIS_MODEL, JARVIS_MAX_INPUT_TOKEN_COUNT)
139
+ 2. JARVIS_LLM_GROUP 中定义的组配置
140
+ 3. 代码中的默认值
136
141
 
137
142
  返回:
138
143
  Dict[str, Any]: 解析后的模型配置字典
@@ -155,14 +160,24 @@ def _get_resolved_model_config(
155
160
  # Start with group config
156
161
  resolved_config = group_config.copy()
157
162
 
158
- # Override with specific settings from GLOBAL_CONFIG_DATA
159
- for key in [
163
+ # 覆盖策略:
164
+ # - 若通过 CLI 传入了 model_group_override,则优先使用组内配置;
165
+ # 仅当组未提供对应键时,才回落到顶层 GLOBAL_CONFIG_DATA。
166
+ # - 若未传入 override(即使用默认组),保持原有行为:由顶层键覆盖组配置。
167
+ override_keys = [
160
168
  "JARVIS_PLATFORM",
161
169
  "JARVIS_MODEL",
162
170
  "JARVIS_MAX_INPUT_TOKEN_COUNT",
163
- ]:
171
+ ]
172
+ for key in override_keys:
164
173
  if key in GLOBAL_CONFIG_DATA:
165
- resolved_config[key] = GLOBAL_CONFIG_DATA[key]
174
+ if model_group_override is None:
175
+ # 未显式指定组:顶层覆盖组
176
+ resolved_config[key] = GLOBAL_CONFIG_DATA[key]
177
+ else:
178
+ # 显式指定组:仅在组未定义该键时回退到顶层
179
+ if key not in resolved_config:
180
+ resolved_config[key] = GLOBAL_CONFIG_DATA[key]
166
181
 
167
182
  return resolved_config
168
183
 
@@ -196,7 +211,7 @@ def _deprecated_platform_name_v1(model_group_override: Optional[str] = None) ->
196
211
  返回:
197
212
  str: 平台名称,默认为正常操作平台
198
213
  """
199
- config = _get_resolved_model_config(model_group_override)
214
+ _get_resolved_model_config(model_group_override)
200
215
  # Fallback to normal platform if thinking platform is not specified
201
216
  return get_normal_platform_name(model_group_override)
202
217
 
@@ -208,7 +223,7 @@ def _deprecated_model_name_v1(model_group_override: Optional[str] = None) -> str
208
223
  返回:
209
224
  str: 模型名称,默认为正常操作模型
210
225
  """
211
- config = _get_resolved_model_config(model_group_override)
226
+ _get_resolved_model_config(model_group_override)
212
227
  # Fallback to normal model if thinking model is not specified
213
228
  return get_normal_model_name(model_group_override)
214
229
 
@@ -220,7 +235,7 @@ def is_execute_tool_confirm() -> bool:
220
235
  返回:
221
236
  bool: 如果需要确认则返回True,默认为False
222
237
  """
223
- return GLOBAL_CONFIG_DATA.get("JARVIS_EXECUTE_TOOL_CONFIRM", False) == True
238
+ return GLOBAL_CONFIG_DATA.get("JARVIS_EXECUTE_TOOL_CONFIRM", False)
224
239
 
225
240
 
226
241
  def is_confirm_before_apply_patch() -> bool:
@@ -230,7 +245,7 @@ def is_confirm_before_apply_patch() -> bool:
230
245
  返回:
231
246
  bool: 如果需要确认则返回True,默认为False
232
247
  """
233
- return GLOBAL_CONFIG_DATA.get("JARVIS_CONFIRM_BEFORE_APPLY_PATCH", False) == True
248
+ return GLOBAL_CONFIG_DATA.get("JARVIS_CONFIRM_BEFORE_APPLY_PATCH", False)
234
249
 
235
250
 
236
251
  def get_data_dir() -> str:
@@ -270,7 +285,7 @@ def get_pretty_output() -> bool:
270
285
  if platform.system() == "Windows":
271
286
  return False
272
287
 
273
- return GLOBAL_CONFIG_DATA.get("JARVIS_PRETTY_OUTPUT", False) == True
288
+ return GLOBAL_CONFIG_DATA.get("JARVIS_PRETTY_OUTPUT", False)
274
289
 
275
290
 
276
291
  def is_use_methodology() -> bool:
@@ -280,7 +295,7 @@ def is_use_methodology() -> bool:
280
295
  返回:
281
296
  bool: 如果启用方法论则返回True,默认为True
282
297
  """
283
- return GLOBAL_CONFIG_DATA.get("JARVIS_USE_METHODOLOGY", True) == True
298
+ return GLOBAL_CONFIG_DATA.get("JARVIS_USE_METHODOLOGY", True)
284
299
 
285
300
 
286
301
  def is_use_analysis() -> bool:
@@ -290,7 +305,7 @@ def is_use_analysis() -> bool:
290
305
  返回:
291
306
  bool: 如果启用任务分析则返回True,默认为True
292
307
  """
293
- return GLOBAL_CONFIG_DATA.get("JARVIS_USE_ANALYSIS", True) == True
308
+ return GLOBAL_CONFIG_DATA.get("JARVIS_USE_ANALYSIS", True)
294
309
 
295
310
 
296
311
  def get_tool_load_dirs() -> List[str]:
@@ -390,7 +405,7 @@ def is_print_prompt() -> bool:
390
405
  返回:
391
406
  bool: 如果打印提示则返回True,默认为True
392
407
  """
393
- return GLOBAL_CONFIG_DATA.get("JARVIS_PRINT_PROMPT", False) == True
408
+ return GLOBAL_CONFIG_DATA.get("JARVIS_PRINT_PROMPT", False)
394
409
 
395
410
 
396
411
  def is_print_error_traceback() -> bool:
@@ -246,7 +246,7 @@ def handle_commit_workflow() -> bool:
246
246
  ["git", "commit", "-m", f"CheckPoint #{commit_count + 1}"], check=True
247
247
  )
248
248
  return True
249
- except subprocess.CalledProcessError as e:
249
+ except subprocess.CalledProcessError:
250
250
  return False
251
251
 
252
252
 
@@ -10,8 +10,7 @@
10
10
  import os
11
11
 
12
12
  # 全局变量:保存消息历史
13
- from typing import Any, Dict, Set, List, Optional
14
- from datetime import datetime
13
+ from typing import Any, Dict, List, Optional
15
14
 
16
15
  message_history: List[str] = []
17
16
  MAX_HISTORY_SIZE = 50
@@ -10,7 +10,6 @@
10
10
  import json
11
11
  import os
12
12
  import tempfile
13
- from pathlib import Path
14
13
  from typing import Any, Dict, List, Optional
15
14
 
16
15
  from jarvis.jarvis_platform.base import BasePlatform
@@ -21,9 +20,8 @@ from jarvis.jarvis_utils.config import (
21
20
  get_central_methodology_repo,
22
21
  get_max_input_token_count,
23
22
  )
24
- from jarvis.jarvis_utils.globals import get_agent, current_agent_name
25
23
  from jarvis.jarvis_utils.output import OutputType, PrettyOutput
26
- from jarvis.jarvis_utils.utils import is_context_overflow, daily_check_git_updates
24
+ from jarvis.jarvis_utils.utils import daily_check_git_updates
27
25
  from jarvis.jarvis_utils.embedding import get_context_token_count
28
26
 
29
27
 
@@ -234,7 +232,7 @@ def load_methodology(
234
232
  methodology_titles = list(methodologies.keys())
235
233
 
236
234
  # 步骤2:让大模型选择相关性高的方法论
237
- selection_prompt = f"""以下是所有可用的方法论标题:
235
+ selection_prompt = """以下是所有可用的方法论标题:
238
236
 
239
237
  """
240
238
  for i, title in enumerate(methodology_titles, 1):
@@ -305,7 +303,7 @@ def load_methodology(
305
303
 
306
304
  # 步骤3:将选择出来的方法论内容提供给大模型生成步骤
307
305
  # 首先构建基础提示词部分
308
- base_prompt = f"""以下是与用户需求相关的方法论内容:
306
+ base_prompt = """以下是与用户需求相关的方法论内容:
309
307
 
310
308
  """
311
309
  suffix_prompt = f"""以下是所有可用的工具内容:
@@ -193,7 +193,7 @@ class ConsoleOutputSink(OutputSink):
193
193
  ),
194
194
  }
195
195
 
196
- header = Text(
196
+ Text(
197
197
  PrettyOutput._format(event.output_type, event.timestamp),
198
198
  style=header_styles[event.output_type],
199
199
  )
@@ -2,7 +2,6 @@
2
2
  import hashlib
3
3
  import json
4
4
  import os
5
- import platform
6
5
  import signal
7
6
  import subprocess
8
7
  import sys
@@ -13,10 +12,7 @@ from datetime import datetime, date
13
12
 
14
13
  import yaml # type: ignore
15
14
  from rich.align import Align
16
- from rich.console import Group, RenderableType
17
- from rich.panel import Panel
18
- from rich.table import Table
19
- from rich.text import Text
15
+ from rich.console import RenderableType
20
16
 
21
17
  from jarvis import __version__
22
18
  from jarvis.jarvis_utils.config import (
@@ -121,7 +117,7 @@ def _check_pip_updates() -> bool:
121
117
  """检查pip安装的Jarvis是否有更新
122
118
 
123
119
  返回:
124
- bool: 是否执行了更新(总是返回False,因为pip更新需要用户手动执行)
120
+ bool: 是否执行了更新(成功更新返回True以触发重启)
125
121
  """
126
122
  import urllib.request
127
123
  import urllib.error
@@ -146,7 +142,7 @@ def _check_pip_updates() -> bool:
146
142
  with urllib.request.urlopen(url, timeout=5) as response:
147
143
  data = json.loads(response.read().decode())
148
144
  latest_version = data["info"]["version"]
149
- except (urllib.error.URLError, KeyError, json.JSONDecodeError) as e:
145
+ except (urllib.error.URLError, KeyError, json.JSONDecodeError):
150
146
  return False
151
147
 
152
148
  # 比较版本
@@ -166,6 +162,7 @@ def _check_pip_updates() -> bool:
166
162
 
167
163
  # 检测是否使用uv
168
164
  is_uv_env = False
165
+ uv_executable: Optional[str] = None
169
166
  if in_venv:
170
167
  if sys.platform == "win32":
171
168
  uv_path = Path(sys.prefix) / "Scripts" / "uv.exe"
@@ -173,6 +170,7 @@ def _check_pip_updates() -> bool:
173
170
  uv_path = Path(sys.prefix) / "bin" / "uv"
174
171
  if uv_path.exists():
175
172
  is_uv_env = True
173
+ uv_executable = str(uv_path)
176
174
 
177
175
  # 检测是否安装了 RAG 特性(更精确)
178
176
  from jarvis.jarvis_utils.utils import (
@@ -180,21 +178,60 @@ def _check_pip_updates() -> bool:
180
178
  ) # 延迟导入避免潜在循环依赖
181
179
  rag_installed = _is_rag_installed()
182
180
 
183
- # 提供更新命令
181
+ # 更新命令
184
182
  package_spec = (
185
183
  "jarvis-ai-assistant[rag]" if rag_installed else "jarvis-ai-assistant"
186
184
  )
187
- if is_uv_env:
185
+ if is_uv_env and uv_executable:
186
+ cmd_list = [uv_executable, "pip", "install", "--upgrade", package_spec]
188
187
  update_cmd = f"uv pip install --upgrade {package_spec}"
189
188
  else:
189
+ cmd_list = [
190
+ sys.executable,
191
+ "-m",
192
+ "pip",
193
+ "install",
194
+ "--upgrade",
195
+ package_spec,
196
+ ]
190
197
  update_cmd = f"{sys.executable} -m pip install --upgrade {package_spec}"
191
198
 
192
- PrettyOutput.print(f"请手动执行以下命令更新: {update_cmd}", OutputType.INFO)
199
+ # 自动尝试升级(失败时提供手动命令)
200
+ try:
201
+ PrettyOutput.print("正在自动更新 Jarvis,请稍候...", OutputType.INFO)
202
+ result = subprocess.run(
203
+ cmd_list,
204
+ capture_output=True,
205
+ text=True,
206
+ encoding="utf-8",
207
+ errors="replace",
208
+ timeout=600,
209
+ )
210
+ if result.returncode == 0:
211
+ PrettyOutput.print("更新成功,正在重启以应用新版本...", OutputType.SUCCESS)
212
+ # 更新检查日期,避免重复触发
213
+ last_check_file.write_text(today_str)
214
+ return True
215
+ else:
216
+ err = (result.stderr or result.stdout or "").strip()
217
+ if err:
218
+ PrettyOutput.print(
219
+ f"自动更新失败,错误信息(已截断): {err[:500]}",
220
+ OutputType.WARNING,
221
+ )
222
+ PrettyOutput.print(
223
+ f"请手动执行以下命令更新: {update_cmd}", OutputType.INFO
224
+ )
225
+ except Exception:
226
+ PrettyOutput.print("自动更新出现异常,已切换为手动更新方式。", OutputType.WARNING)
227
+ PrettyOutput.print(
228
+ f"请手动执行以下命令更新: {update_cmd}", OutputType.INFO
229
+ )
193
230
 
194
231
  # 更新检查日期
195
232
  last_check_file.write_text(today_str)
196
233
 
197
- except Exception as e:
234
+ except Exception:
198
235
  # 静默处理错误,不影响正常使用
199
236
  pass
200
237
 
@@ -225,7 +262,6 @@ def _show_usage_stats(welcome_str: str) -> None:
225
262
  from jarvis.jarvis_utils.output import OutputType, PrettyOutput
226
263
 
227
264
  try:
228
- from datetime import datetime
229
265
 
230
266
  from rich.console import Console, Group
231
267
  from rich.panel import Panel
@@ -709,7 +745,7 @@ def _interactive_config_setup(config_file_path: Path):
709
745
  guide_lines = ["", "配置获取方法:"]
710
746
  for key in required_keys:
711
747
  if key in config_guide and config_guide[key]:
712
- guide_lines.append(f"")
748
+ guide_lines.append("")
713
749
  guide_lines.append(f"{key} 获取方法:")
714
750
  guide_lines.append(str(config_guide[key]))
715
751
  PrettyOutput.print("\n".join(guide_lines), OutputType.INFO)
@@ -833,8 +869,6 @@ def load_config():
833
869
 
834
870
  from typing import Tuple
835
871
 
836
- from typing import Tuple
837
-
838
872
 
839
873
  def _load_config_file(config_file: str) -> Tuple[str, dict]:
840
874
  """读取并解析YAML格式的配置文件
@@ -1207,7 +1241,10 @@ def _collect_optional_config_interactively(
1207
1241
  except ValueError:
1208
1242
  default_index = 0 # 默认为第一个选项
1209
1243
 
1210
- new_mode = get_choice(tip, choices, default_index)
1244
+ new_mode = get_choice(
1245
+ tip,
1246
+ choices,
1247
+ )
1211
1248
 
1212
1249
  if new_mode == current_mode:
1213
1250
  return False
@@ -1329,7 +1366,6 @@ def _load_and_process_config(jarvis_dir: str, config_file: str) -> None:
1329
1366
  config_file: 配置文件路径
1330
1367
  """
1331
1368
  from jarvis.jarvis_utils.input import user_confirm as get_yes_no
1332
- from jarvis.jarvis_utils.input import get_single_line_input
1333
1369
 
1334
1370
  try:
1335
1371
  content, config_data = _load_config_file(config_file)
@@ -1533,7 +1569,7 @@ def _read_old_config_file(config_file):
1533
1569
  )
1534
1570
  set_global_env_data(config_data)
1535
1571
  PrettyOutput.print(
1536
- f"检测到旧格式配置文件,旧格式以后将不再支持,请尽快迁移到新格式",
1572
+ "检测到旧格式配置文件,旧格式以后将不再支持,请尽快迁移到新格式",
1537
1573
  OutputType.WARNING,
1538
1574
  )
1539
1575
 
@@ -1558,7 +1594,10 @@ def while_success(func: Callable[[], Any], sleep_time: float = 0.1, max_retries:
1558
1594
  except Exception:
1559
1595
  retry_count += 1
1560
1596
  if retry_count < max_retries:
1561
- PrettyOutput.print(f"重试中 ({retry_count}/{max_retries}),等待 {sleep_time}s...", OutputType.WARNING)
1597
+ PrettyOutput.print(
1598
+ f"发生异常,重试中 ({retry_count}/{max_retries}),等待 {sleep_time}s...",
1599
+ OutputType.WARNING,
1600
+ )
1562
1601
  time.sleep(sleep_time)
1563
1602
  continue
1564
1603
  return result
@@ -1587,7 +1626,10 @@ def while_true(func: Callable[[], bool], sleep_time: float = 0.1, max_retries: i
1587
1626
  break
1588
1627
  retry_count += 1
1589
1628
  if retry_count < max_retries:
1590
- PrettyOutput.print(f"重试中 ({retry_count}/{max_retries}),等待 {sleep_time}s...", OutputType.WARNING)
1629
+ PrettyOutput.print(
1630
+ f"返回空值,重试中 ({retry_count}/{max_retries}),等待 {sleep_time}s...",
1631
+ OutputType.WARNING,
1632
+ )
1591
1633
  time.sleep(sleep_time)
1592
1634
  return ret
1593
1635
 
@@ -1615,7 +1657,7 @@ def get_file_line_count(filename: str) -> int:
1615
1657
  """
1616
1658
  try:
1617
1659
  return len(open(filename, "r", encoding="utf-8", errors="ignore").readlines())
1618
- except Exception as e:
1660
+ except Exception:
1619
1661
  return 0
1620
1662
 
1621
1663
 
@@ -1756,7 +1798,7 @@ def _pull_git_repo(repo_path: Path, repo_type: str):
1756
1798
  return
1757
1799
 
1758
1800
  # 执行 git pull
1759
- pull_result = subprocess.run(
1801
+ subprocess.run(
1760
1802
  ["git", "pull"],
1761
1803
  cwd=repo_path,
1762
1804
  capture_output=True,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: jarvis-ai-assistant
3
- Version: 0.3.27
3
+ Version: 0.3.28
4
4
  Summary: Jarvis: An AI assistant that uses tools to interact with the system
5
5
  Home-page: https://github.com/skyfireitdiy/Jarvis
6
6
  Author: skyfire