jarvis-ai-assistant 0.1.187__py3-none-any.whl → 0.1.189__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.
jarvis/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  """Jarvis AI Assistant"""
3
3
 
4
- __version__ = "0.1.187"
4
+ __version__ = "0.1.189"
@@ -4,8 +4,6 @@ import datetime
4
4
  import platform
5
5
  from typing import Any, Callable, Dict, List, Optional, Protocol, Tuple, Union
6
6
 
7
- from jarvis.jarvis_platform.base import BasePlatform
8
-
9
7
  # 第三方库导入
10
8
  from yaspin import yaspin # type: ignore
11
9
 
@@ -224,7 +222,11 @@ class Agent:
224
222
 
225
223
  # 如果有上传文件,自动禁用方法论
226
224
  self.use_methodology = (
227
- False if files else (use_methodology if use_methodology is not None else is_use_methodology())
225
+ False
226
+ if files
227
+ else (
228
+ use_methodology if use_methodology is not None else is_use_methodology()
229
+ )
228
230
  )
229
231
  self.use_analysis = (
230
232
  use_analysis if use_analysis is not None else is_use_analysis()
@@ -440,24 +442,15 @@ class Agent:
440
442
  self.conversation_length += get_context_token_count(response)
441
443
  return response
442
444
 
443
- def _summarize_and_clear_history(self) -> str:
444
- """总结当前对话并清理历史记录
445
-
446
- 该方法将:
447
- 1. 生成关键信息摘要
448
- 2. 清除对话历史
449
- 3. 保留系统消息
450
- 4. 添加摘要作为新上下文
451
- 5. 重置对话长度计数器
445
+ def generate_summary(self) -> str:
446
+ """生成对话历史摘要
452
447
 
453
448
  返回:
454
449
  str: 包含对话摘要的字符串
455
450
 
456
451
  注意:
457
- 当上下文长度超过最大值时使用
452
+ 仅生成摘要,不修改对话状态
458
453
  """
459
- # Create a new model instance to summarize, avoid affecting the main conversation
460
-
461
454
  with yaspin(text="正在总结对话历史...", color="cyan") as spinner:
462
455
  summary_prompt = """
463
456
  <summary_request>
@@ -482,36 +475,48 @@ class Agent:
482
475
  </summary_request>
483
476
  """
484
477
 
485
- try:
486
- with spinner.hidden():
487
- summary = self.model.chat_until_success(self.prompt + "\n" + summary_prompt) # type: ignore
478
+ try:
479
+ with spinner.hidden():
480
+ summary = self.model.chat_until_success(self.prompt + "\n" + summary_prompt) # type: ignore
481
+ spinner.text = "总结对话历史完成"
482
+ spinner.ok("✅")
483
+ return summary
484
+ except Exception as e:
485
+ spinner.text = "总结对话历史失败"
486
+ spinner.fail("❌")
487
+ return ""
488
+
489
+ def _summarize_and_clear_history(self) -> str:
490
+ """总结当前对话并清理历史记录
488
491
 
489
- self.model.reset() # type: ignore
492
+ 该方法将:
493
+ 1. 调用_generate_summary生成摘要
494
+ 2. 清除对话历史
495
+ 3. 保留系统消息
496
+ 4. 添加摘要作为新上下文
497
+ 5. 重置对话长度计数器
490
498
 
491
- # 清空当前对话历史,但保留系统消息
492
- self.conversation_length = 0 # Reset conversation length
499
+ 返回:
500
+ str: 包含对话摘要的字符串
493
501
 
494
- # 添加总结作为新的上下文
495
- spinner.text = "总结对话历史完成"
496
- spinner.ok("")
497
- return f"""<summary>
498
- <header>
502
+ 注意:
503
+ 当上下文长度超过最大值时使用
504
+ """
505
+ summary = self.generate_summary()
506
+ self.clear_history() # type: ignore
507
+
508
+ if not summary:
509
+ return ""
510
+
511
+ return f"""
499
512
  以下是之前对话的关键信息总结:
500
- </header>
501
513
 
502
514
  <content>
503
515
  {summary}
504
516
  </content>
505
517
 
506
- <instructions>
507
518
  请基于以上信息继续完成任务。请注意,这是之前对话的摘要,上下文长度已超过限制而被重置。请直接继续任务,无需重复已完成的步骤。如有需要,可以询问用户以获取更多信息。
508
- </instructions>
509
- </summary>
510
519
  """
511
- except Exception as e:
512
- spinner.text = "总结对话历史失败"
513
- spinner.fail("❌")
514
- return ""
515
520
 
516
521
  def _call_tools(self, response: str) -> Tuple[bool, Any]:
517
522
  """调用工具执行响应
@@ -770,32 +775,31 @@ arguments:
770
775
  3. 包含错误处理和恢复逻辑
771
776
  4. 自动加载相关方法论(如果是首次运行)
772
777
  """
778
+
779
+ self.prompt = f"{user_input}"
773
780
  try:
774
781
  set_agent(self.name, self)
775
782
 
776
- for handler in self.input_handler:
777
- user_input, _ = handler(user_input, self)
778
-
779
- self.prompt = f"{user_input}"
780
-
781
- if self.first:
782
- # 如果有上传文件,先上传文件
783
- if self.files and isinstance(self.model, BasePlatform) and hasattr(self.model, "upload_files"):
784
- self.model.upload_files(self.files)
785
- self.prompt = f"{user_input}"
786
-
787
- # 如果启用方法论且没有上传文件,上传方法论
788
- elif self.use_methodology:
789
- platform = self.model if hasattr(self.model, "upload_files") else None
790
- if platform and upload_methodology(platform):
791
- self.prompt = f"{user_input}"
792
- else:
793
- # 上传失败则回退到本地加载
794
- self.prompt = f"{user_input}\n\n以下是历史类似问题的执行经验,可参考:\n{load_methodology(user_input, self.get_tool_registry())}"
795
-
796
- self.first = False
797
-
798
783
  while True:
784
+ if self.first:
785
+ # 如果有上传文件,先上传文件
786
+ if (
787
+ self.files
788
+ and self.model
789
+ and self.model.support_upload_files()
790
+ ):
791
+ self.model.upload_files(self.files)
792
+
793
+ # 如果启用方法论且没有上传文件,上传方法论
794
+ elif self.use_methodology:
795
+ if not self.model or not upload_methodology(self.model):
796
+ # 上传失败则回退到本地加载
797
+ msg = self.prompt
798
+ for handler in self.input_handler:
799
+ msg, _ = handler(msg, self)
800
+ self.prompt = f"{self.prompt}\n\n以下是历史类似问题的执行经验,可参考:\n{load_methodology(msg, self.get_tool_registry())}"
801
+
802
+ self.first = False
799
803
  try:
800
804
  current_response = self._call_model(self.prompt, True)
801
805
  self.prompt = ""
@@ -836,7 +840,7 @@ arguments:
836
840
  PrettyOutput.print(f"任务失败: {str(e)}", OutputType.ERROR)
837
841
  return f"Task failed: {str(e)}"
838
842
 
839
- def _clear_history(self):
843
+ def clear_history(self):
840
844
  """清空对话历史但保留系统提示
841
845
 
842
846
  该方法将:
@@ -13,69 +13,69 @@ from jarvis.jarvis_utils.utils import is_context_overflow
13
13
 
14
14
 
15
15
  def file_input_handler(user_input: str, agent: Any) -> Tuple[str, bool]:
16
- """Process user input containing file references and read file contents.
16
+ """处理包含文件引用的用户输入并读取文件内容。
17
17
 
18
- Args:
19
- user_input: Input string that may contain file references in format:
20
- - 'file_path' (whole file)
21
- - 'file_path:start_line,end_line' (line range)
22
- - 'file_path:start_line:end_line' (alternative range format)
23
- agent: Agent object for further processing (currently unused)
18
+ 参数:
19
+ user_input: 可能包含文件引用的输入字符串,格式为:
20
+ - 'file_path' (整个文件)
21
+ - 'file_path:start_line,end_line' (行范围)
22
+ - 'file_path:start_line:end_line' (替代范围格式)
23
+ agent: 用于进一步处理的Agent对象(当前未使用)
24
24
 
25
- Returns:
25
+ 返回:
26
26
  Tuple[str, bool]:
27
- - Processed prompt string with file contents prepended
28
- - Boolean indicating if context overflow occurred
27
+ - 处理后的提示字符串,前面附加文件内容
28
+ - 布尔值,指示是否发生上下文溢出
29
29
  """
30
30
  prompt = user_input
31
31
  files = []
32
32
 
33
- file_refs = re.findall(r"'([^']+)'", user_input)
33
+ file_refs = re.findall(r"'([^'\n]+)'", user_input)
34
34
  for ref in file_refs:
35
- # Handle file:start,end or file:start:end format
35
+ # 处理 file:start,end file:start:end 格式
36
36
  if ':' in ref:
37
37
  file_path, line_range = ref.split(':', 1)
38
- # Initialize with default values
38
+ # 使用默认值初始化
39
39
  start_line = 1 # 1-based
40
40
  end_line = -1
41
41
 
42
- # Process line range if specified
42
+ # 如果指定了行范围则进行处理
43
43
  if ',' in line_range or ':' in line_range:
44
44
  try:
45
45
  raw_start, raw_end = map(int, re.split(r'[,:]', line_range))
46
46
 
47
- # Handle special values and Python-style negative indices
47
+ # 处理特殊值和Python风格的负索引
48
48
  try:
49
49
  with open(file_path, 'r', encoding='utf-8', errors="ignore") as f:
50
50
  total_lines = len(f.readlines())
51
51
  except FileNotFoundError:
52
52
  PrettyOutput.print(f"文件不存在: {file_path}", OutputType.WARNING)
53
53
  continue
54
- # Process start line (0 means whole file, negative means from end)
54
+ # 处理起始行(0表示整个文件,负数表示从末尾开始)
55
55
  if raw_start == 0: # 0表示整个文件
56
56
  start_line = 1
57
57
  end_line = total_lines
58
58
  else:
59
59
  start_line = raw_start if raw_start > 0 else total_lines + raw_start + 1
60
60
 
61
- # Process end line
61
+ # 处理结束行
62
62
  if raw_end == 0: # 0表示整个文件(如果start也是0)
63
63
  end_line = total_lines
64
64
  else:
65
65
  end_line = raw_end if raw_end > 0 else total_lines + raw_end + 1
66
66
 
67
- # Auto-correct ranges
67
+ # 自动校正范围
68
68
  start_line = max(1, min(start_line, total_lines))
69
69
  end_line = max(start_line, min(end_line, total_lines))
70
70
 
71
- # Final validation
71
+ # 最终验证
72
72
  if start_line < 1 or end_line > total_lines or start_line > end_line:
73
73
  raise ValueError
74
74
 
75
75
  except:
76
76
  continue
77
77
 
78
- # Add file if it exists
78
+ # 如果文件存在则添加
79
79
  if os.path.isfile(file_path):
80
80
  files.append({
81
81
  "path": file_path,
@@ -83,7 +83,7 @@ def file_input_handler(user_input: str, agent: Any) -> Tuple[str, bool]:
83
83
  "end_line": end_line
84
84
  })
85
85
  else:
86
- # Handle simple file path
86
+ # 处理简单文件路径
87
87
  if os.path.isfile(ref):
88
88
  files.append({
89
89
  "path": ref,
@@ -91,7 +91,7 @@ def file_input_handler(user_input: str, agent: Any) -> Tuple[str, bool]:
91
91
  "end_line": -1
92
92
  })
93
93
 
94
- # Read and process files if any were found
94
+ # 如果找到文件则读取并处理
95
95
  if files:
96
96
  with yaspin(text="正在读取文件...", color="cyan") as spinner:
97
97
  old_prompt = prompt
@@ -59,16 +59,15 @@ def main():
59
59
  agent.run(args.task)
60
60
  return 0
61
61
 
62
- # Enter interactive mode if no initial task
63
- while True:
64
- try:
65
- user_input = get_multiline_input("请输入你的任务(输入空行退出):")
66
- if not user_input:
67
- break
68
- agent.set_addon_prompt("如果有必要,请先指定出行动计划,然后根据计划一步步执行,如果任务过于复杂,可以拆分子Agent进行执行,拆的子Agent需要掌握所有必要的任务信息,否则无法执行")
69
- agent.run(user_input)
70
- except Exception as e:
71
- PrettyOutput.print(f"错误: {str(e)}", OutputType.ERROR)
62
+
63
+ try:
64
+ user_input = get_multiline_input("请输入你的任务(输入空行退出):")
65
+ if not user_input:
66
+ return 0
67
+ agent.set_addon_prompt("如果有必要,请先指定出行动计划,然后根据计划一步步执行,如果任务过于复杂,可以拆分子Agent进行执行,拆的子Agent需要掌握所有必要的任务信息,否则无法执行")
68
+ agent.run(user_input)
69
+ except Exception as e:
70
+ PrettyOutput.print(f"错误: {str(e)}", OutputType.ERROR)
72
71
 
73
72
  except Exception as e:
74
73
  PrettyOutput.print(f"初始化错误: {str(e)}", OutputType.ERROR)
@@ -588,25 +588,33 @@ class CodeReviewTool:
588
588
  temp_file.flush()
589
589
 
590
590
  try:
591
- upload_success = False
592
591
  # Check if content is too large
593
592
  is_large_content = is_context_overflow(diff_output)
594
593
 
595
594
  # Upload the file to the agent's model
596
- if is_large_content and agent.model and hasattr(agent.model, 'upload_files'):
595
+ if is_large_content:
596
+ if not agent.model or not agent.model.support_upload_files():
597
+ return {
598
+ "success": False,
599
+ "stdout": "",
600
+ "stderr": "代码差异太大,无法处理"
601
+ }
602
+
597
603
  with yaspin(text="正在上传代码差异文件...", color="cyan") as spinner:
598
604
  upload_success = agent.model.upload_files([temp_file_path])
599
605
  if upload_success:
600
606
  spinner.ok("✅")
601
607
  PrettyOutput.print(f"已成功上传代码差异文件", OutputType.SUCCESS)
602
608
  else:
603
- spinner.fail("❌")
604
- PrettyOutput.print(f"上传代码差异文件失败,将使用分块处理", OutputType.WARNING)
605
- else:
606
- upload_success = False
609
+ return {
610
+ "success": False,
611
+ "stdout": "",
612
+ "stderr": "上传代码差异文件失败"
613
+ }
614
+
607
615
 
608
616
  # Prepare the prompt based on upload status
609
- if upload_success:
617
+ if is_large_content:
610
618
  # When file is uploaded, reference it in the prompt
611
619
  complete_prompt = user_prompt + f"""
612
620
 
@@ -619,13 +627,6 @@ class CodeReviewTool:
619
627
  # Run the agent with the prompt
620
628
  result = agent.run(complete_prompt)
621
629
  else:
622
- if is_large_content:
623
- return {
624
- "success": False,
625
- "stdout": "",
626
- "stderr": "错误:上传代码差异文件失败"
627
- }
628
- # Include the diff directly in the prompt for smaller content
629
630
  complete_prompt = user_prompt + "\n\n代码差异内容:\n```diff\n" + diff_output + "\n```"
630
631
  result = agent.run(complete_prompt)
631
632
  finally:
@@ -179,7 +179,7 @@
179
179
  "JARVIS_MAX_BIG_CONTENT_SIZE": {
180
180
  "type": "number",
181
181
  "description": "最大大内容尺寸",
182
- "default": 1024000
182
+ "default": 160000
183
183
  },
184
184
  "JARVIS_PRETTY_OUTPUT": {
185
185
  "type": "boolean",
jarvis/jarvis_dev/main.py CHANGED
@@ -1160,42 +1160,42 @@ def create_dev_team() -> MultiAgent:
1160
1160
  description="Project Manager - Coordinates team and manages project delivery",
1161
1161
  system_prompt=PM_PROMPT_WITH_TOOLS,
1162
1162
  output_handler=[PM_output_handler],
1163
- platform=PlatformRegistry().get_thinking_platform(),
1163
+ platform=PlatformRegistry().get_normal_platform(),
1164
1164
  ),
1165
1165
  dict(
1166
1166
  name="BA",
1167
1167
  description="Business Analyst - Analyzes and documents requirements",
1168
1168
  system_prompt=BA_PROMPT_WITH_TOOLS,
1169
1169
  output_handler=[BA_output_handler],
1170
- platform=PlatformRegistry().get_thinking_platform(),
1170
+ platform=PlatformRegistry().get_normal_platform(),
1171
1171
  ),
1172
1172
  dict(
1173
1173
  name="SA",
1174
1174
  description="Solution Architect - Designs technical solutions",
1175
1175
  system_prompt=SA_PROMPT_WITH_TOOLS,
1176
1176
  output_handler=[SA_output_handler],
1177
- platform=PlatformRegistry().get_thinking_platform(),
1177
+ platform=PlatformRegistry().get_normal_platform(),
1178
1178
  ),
1179
1179
  dict(
1180
1180
  name="TL",
1181
1181
  description="Technical Lead - Leads development team and ensures technical quality",
1182
1182
  system_prompt=TL_PROMPT_WITH_TOOLS,
1183
1183
  output_handler=[TL_output_handler],
1184
- platform=PlatformRegistry().get_thinking_platform(),
1184
+ platform=PlatformRegistry().get_normal_platform(),
1185
1185
  ),
1186
1186
  dict(
1187
1187
  name="DEV",
1188
1188
  description="Developer - Implements features and writes code",
1189
1189
  system_prompt=DEV_PROMPT_WITH_TOOLS,
1190
1190
  output_handler=[DEV_output_handler],
1191
- platform=PlatformRegistry().get_thinking_platform(),
1191
+ platform=PlatformRegistry().get_normal_platform(),
1192
1192
  ),
1193
1193
  dict(
1194
1194
  name="QA",
1195
1195
  description="Quality Assurance - Ensures product quality through testing",
1196
1196
  system_prompt=QA_PROMPT_WITH_TOOLS,
1197
1197
  output_handler=[QA_output_handler],
1198
- platform=PlatformRegistry().get_thinking_platform(),
1198
+ platform=PlatformRegistry().get_normal_platform(),
1199
1199
  )
1200
1200
  ]
1201
1201
 
@@ -207,7 +207,7 @@ class GitCommitAnalyzer:
207
207
  [检查代码是否符合行业最佳实践和项目规范]
208
208
  {ct("REPORT")}""",
209
209
  output_handler=[tool_registry],
210
- platform=PlatformRegistry().get_thinking_platform(),
210
+ platform=PlatformRegistry().get_normal_platform(),
211
211
  auto_complete=True
212
212
  )
213
213