jarvis-ai-assistant 0.1.193__py3-none-any.whl → 0.1.195__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 (92) hide show
  1. jarvis/__init__.py +1 -1
  2. jarvis/jarvis_agent/__init__.py +45 -41
  3. jarvis/jarvis_agent/builtin_input_handler.py +26 -4
  4. jarvis/jarvis_agent/jarvis.py +30 -19
  5. jarvis/jarvis_agent/main.py +20 -12
  6. jarvis/jarvis_agent/output_handler.py +7 -7
  7. jarvis/jarvis_agent/shell_input_handler.py +14 -11
  8. jarvis/jarvis_code_agent/code_agent.py +81 -79
  9. jarvis/jarvis_code_agent/lint.py +92 -105
  10. jarvis/jarvis_code_analysis/checklists/__init__.py +1 -1
  11. jarvis/jarvis_code_analysis/checklists/c_cpp.py +1 -1
  12. jarvis/jarvis_code_analysis/checklists/csharp.py +1 -1
  13. jarvis/jarvis_code_analysis/checklists/data_format.py +1 -1
  14. jarvis/jarvis_code_analysis/checklists/devops.py +1 -1
  15. jarvis/jarvis_code_analysis/checklists/docs.py +1 -1
  16. jarvis/jarvis_code_analysis/checklists/go.py +1 -1
  17. jarvis/jarvis_code_analysis/checklists/infrastructure.py +1 -1
  18. jarvis/jarvis_code_analysis/checklists/java.py +1 -1
  19. jarvis/jarvis_code_analysis/checklists/javascript.py +1 -1
  20. jarvis/jarvis_code_analysis/checklists/kotlin.py +1 -1
  21. jarvis/jarvis_code_analysis/checklists/loader.py +31 -29
  22. jarvis/jarvis_code_analysis/checklists/php.py +1 -1
  23. jarvis/jarvis_code_analysis/checklists/python.py +1 -1
  24. jarvis/jarvis_code_analysis/checklists/ruby.py +1 -1
  25. jarvis/jarvis_code_analysis/checklists/rust.py +1 -1
  26. jarvis/jarvis_code_analysis/checklists/shell.py +1 -1
  27. jarvis/jarvis_code_analysis/checklists/sql.py +1 -1
  28. jarvis/jarvis_code_analysis/checklists/swift.py +1 -1
  29. jarvis/jarvis_code_analysis/checklists/web.py +1 -1
  30. jarvis/jarvis_code_analysis/code_review.py +292 -190
  31. jarvis/jarvis_dev/main.py +73 -56
  32. jarvis/jarvis_git_details/main.py +29 -33
  33. jarvis/jarvis_git_squash/main.py +13 -11
  34. jarvis/jarvis_git_utils/git_commiter.py +15 -5
  35. jarvis/jarvis_mcp/__init__.py +8 -10
  36. jarvis/jarvis_mcp/sse_mcp_client.py +182 -205
  37. jarvis/jarvis_mcp/stdio_mcp_client.py +93 -120
  38. jarvis/jarvis_mcp/streamable_mcp_client.py +117 -142
  39. jarvis/jarvis_methodology/main.py +71 -39
  40. jarvis/jarvis_multi_agent/__init__.py +24 -16
  41. jarvis/jarvis_multi_agent/main.py +10 -4
  42. jarvis/jarvis_platform/__init__.py +1 -1
  43. jarvis/jarvis_platform/base.py +44 -18
  44. jarvis/jarvis_platform/human.py +15 -3
  45. jarvis/jarvis_platform/kimi.py +117 -81
  46. jarvis/jarvis_platform/openai.py +23 -28
  47. jarvis/jarvis_platform/registry.py +43 -29
  48. jarvis/jarvis_platform/tongyi.py +16 -10
  49. jarvis/jarvis_platform/yuanbao.py +197 -144
  50. jarvis/jarvis_platform_manager/main.py +4 -2
  51. jarvis/jarvis_smart_shell/main.py +35 -30
  52. jarvis/jarvis_tools/ask_user.py +8 -16
  53. jarvis/jarvis_tools/base.py +3 -2
  54. jarvis/jarvis_tools/chdir.py +7 -19
  55. jarvis/jarvis_tools/cli/main.py +14 -10
  56. jarvis/jarvis_tools/code_plan.py +10 -31
  57. jarvis/jarvis_tools/create_code_agent.py +6 -11
  58. jarvis/jarvis_tools/create_sub_agent.py +10 -22
  59. jarvis/jarvis_tools/edit_file.py +98 -76
  60. jarvis/jarvis_tools/execute_script.py +46 -46
  61. jarvis/jarvis_tools/file_analyzer.py +22 -34
  62. jarvis/jarvis_tools/file_operation.py +69 -62
  63. jarvis/jarvis_tools/generate_new_tool.py +0 -2
  64. jarvis/jarvis_tools/methodology.py +19 -23
  65. jarvis/jarvis_tools/read_code.py +35 -35
  66. jarvis/jarvis_tools/read_webpage.py +7 -16
  67. jarvis/jarvis_tools/registry.py +63 -30
  68. jarvis/jarvis_tools/rewrite_file.py +26 -29
  69. jarvis/jarvis_tools/search_web.py +5 -8
  70. jarvis/jarvis_tools/virtual_tty.py +133 -122
  71. jarvis/jarvis_utils/__init__.py +0 -1
  72. jarvis/jarvis_utils/builtin_replace_map.py +9 -9
  73. jarvis/jarvis_utils/config.py +60 -37
  74. jarvis/jarvis_utils/embedding.py +24 -19
  75. jarvis/jarvis_utils/file_processors.py +16 -9
  76. jarvis/jarvis_utils/git_utils.py +157 -107
  77. jarvis/jarvis_utils/globals.py +1 -1
  78. jarvis/jarvis_utils/input.py +85 -52
  79. jarvis/jarvis_utils/jarvis_history.py +43 -0
  80. jarvis/jarvis_utils/methodology.py +31 -24
  81. jarvis/jarvis_utils/output.py +164 -80
  82. jarvis/jarvis_utils/tag.py +2 -1
  83. jarvis/jarvis_utils/utils.py +84 -52
  84. {jarvis_ai_assistant-0.1.193.dist-info → jarvis_ai_assistant-0.1.195.dist-info}/METADATA +362 -230
  85. jarvis_ai_assistant-0.1.195.dist-info/RECORD +98 -0
  86. jarvis/jarvis_agent/file_input_handler.py +0 -112
  87. jarvis/jarvis_event/__init__.py +0 -0
  88. jarvis_ai_assistant-0.1.193.dist-info/RECORD +0 -99
  89. {jarvis_ai_assistant-0.1.193.dist-info → jarvis_ai_assistant-0.1.195.dist-info}/WHEEL +0 -0
  90. {jarvis_ai_assistant-0.1.193.dist-info → jarvis_ai_assistant-0.1.195.dist-info}/entry_points.txt +0 -0
  91. {jarvis_ai_assistant-0.1.193.dist-info → jarvis_ai_assistant-0.1.195.dist-info}/licenses/LICENSE +0 -0
  92. {jarvis_ai_assistant-0.1.193.dist-info → jarvis_ai_assistant-0.1.195.dist-info}/top_level.txt +0 -0
jarvis/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  """Jarvis AI Assistant"""
3
3
 
4
- __version__ = "0.1.193"
4
+ __version__ = "0.1.195"
@@ -1,6 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # 标准库导入
3
3
  import datetime
4
+ from pathlib import Path
4
5
  import platform
5
6
  from typing import Any, Callable, Dict, List, Optional, Protocol, Tuple, Union
6
7
 
@@ -13,15 +14,17 @@ from yaspin import yaspin # type: ignore
13
14
  from jarvis.jarvis_platform.base import BasePlatform
14
15
  from jarvis.jarvis_platform.registry import PlatformRegistry
15
16
  # jarvis_utils 相关
16
- from jarvis.jarvis_utils.config import (get_max_token_count,
17
+ from jarvis.jarvis_utils.config import (get_data_dir, get_max_token_count,
17
18
  get_max_tool_call_count,
18
19
  is_auto_complete,
19
20
  is_execute_tool_confirm,
20
21
  is_use_analysis, is_use_methodology)
21
22
  from jarvis.jarvis_utils.embedding import get_context_token_count
22
- from jarvis.jarvis_utils.globals import (delete_agent, get_interrupt, make_agent_name,
23
- set_agent, set_interrupt)
23
+ from jarvis.jarvis_utils.globals import (delete_agent, get_interrupt,
24
+ make_agent_name, set_agent,
25
+ set_interrupt)
24
26
  from jarvis.jarvis_utils.input import get_multiline_input
27
+ from jarvis.jarvis_utils.jarvis_history import JarvisHistory
25
28
  from jarvis.jarvis_utils.methodology import (load_methodology,
26
29
  upload_methodology)
27
30
  from jarvis.jarvis_utils.output import OutputType, PrettyOutput
@@ -112,28 +115,16 @@ origin_agent_system_prompt = f"""
112
115
 
113
116
 
114
117
  class OutputHandlerProtocol(Protocol):
115
- def name(self) -> str:
116
- ...
118
+ def name(self) -> str: ...
117
119
 
118
- def can_handle(self, response: str) -> bool:
119
- ...
120
+ def can_handle(self, response: str) -> bool: ...
120
121
 
121
- def prompt(self) -> str:
122
- ...
122
+ def prompt(self) -> str: ...
123
123
 
124
- def handle(self, response: str, agent: Any) -> Tuple[bool, Any]:
125
- ...
124
+ def handle(self, response: str, agent: Any) -> Tuple[bool, Any]: ...
126
125
 
127
126
 
128
127
  class Agent:
129
- def set_summary_prompt(self, summary_prompt: str):
130
- """设置任务完成时的总结提示模板。
131
-
132
- 参数:
133
- summary_prompt: 用于生成任务总结的提示模板
134
- """
135
- self.summary_prompt = summary_prompt
136
-
137
128
  def clear(self):
138
129
  """清除当前对话历史,保留系统消息。
139
130
 
@@ -147,6 +138,7 @@ class Agent:
147
138
  self.prompt = ""
148
139
 
149
140
  def __del__(self):
141
+ self.history.stop_record()
150
142
  delete_agent(self.name)
151
143
 
152
144
  def __init__(
@@ -195,7 +187,9 @@ class Agent:
195
187
  if isinstance(platform, str):
196
188
  self.model = PlatformRegistry().create_platform(platform)
197
189
  if self.model is None:
198
- PrettyOutput.print(f"平台 {platform} 不存在,将使用普通模型", OutputType.WARNING)
190
+ PrettyOutput.print(
191
+ f"平台 {platform} 不存在,将使用普通模型", OutputType.WARNING
192
+ )
199
193
  self.model = PlatformRegistry().get_normal_platform()
200
194
  else:
201
195
  self.model = platform
@@ -243,6 +237,9 @@ class Agent:
243
237
  self.max_tool_call_count = get_max_tool_call_count()
244
238
  self.after_tool_call_cb: Optional[Callable[[Agent], None]] = None
245
239
 
240
+ self.history = JarvisHistory()
241
+ self.history.start_record(str(Path(get_data_dir())/"history"))
242
+
246
243
  self.execute_tool_confirm = (
247
244
  execute_tool_confirm
248
245
  if execute_tool_confirm is not None
@@ -404,8 +401,10 @@ class Agent:
404
401
  if self.conversation_length > self.max_token_count:
405
402
  message = self._summarize_and_clear_history() + "\n\n" + message
406
403
  self.conversation_length += get_context_token_count(message)
404
+ self.history.append_msg("user", message)
407
405
  response = self.model.chat_until_success(message) # type: ignore
408
406
  self.conversation_length += get_context_token_count(response)
407
+ self.history.append_msg("assistant", response)
409
408
  return response
410
409
 
411
410
  def generate_summary(self) -> str:
@@ -528,7 +527,9 @@ class Agent:
528
527
  if not self.execute_tool_confirm or user_confirm(
529
528
  f"需要执行{tool_list[0].name()}确认执行?", True
530
529
  ):
531
- with yaspin(text=f"正在执行{tool_list[0].name()}...", color="cyan") as spinner:
530
+ with yaspin(
531
+ text=f"正在执行{tool_list[0].name()}...", color="cyan"
532
+ ) as spinner:
532
533
  with spinner.hidden():
533
534
  result = tool_list[0].handle(response, self)
534
535
  spinner.text = f"{tool_list[0].name()}执行完成"
@@ -726,7 +727,6 @@ arguments:
726
727
  spinner.text = "分析失败"
727
728
  spinner.fail("❌")
728
729
 
729
-
730
730
  def make_default_addon_prompt(self, need_complete: bool) -> str:
731
731
  """生成附加提示。
732
732
 
@@ -734,7 +734,6 @@ arguments:
734
734
  need_complete: 是否需要完成任务
735
735
 
736
736
  """
737
- return ""
738
737
  # 结构化系统指令
739
738
  action_handlers = ", ".join([handler.name() for handler in self.output_handler])
740
739
 
@@ -762,7 +761,6 @@ arguments:
762
761
 
763
762
  return addon_prompt
764
763
 
765
-
766
764
  def run(self, user_input: str) -> Any:
767
765
  """处理用户输入并执行任务
768
766
 
@@ -786,17 +784,23 @@ arguments:
786
784
  while True:
787
785
  if self.first:
788
786
  # 如果有上传文件,先上传文件
789
- if (
790
- self.files
791
- and self.model
792
- and self.model.support_upload_files()
793
- ):
794
- self.model.upload_files(self.files)
795
-
796
- # 如果启用方法论且没有上传文件,上传方法论
797
- elif self.use_methodology:
798
- if not self.model or not upload_methodology(self.model):
799
- # 上传失败则回退到本地加载
787
+ if self.model and self.model.support_upload_files():
788
+ if self.use_methodology:
789
+ if not upload_methodology(self.model, other_files=self.files):
790
+ if self.files:
791
+ PrettyOutput.print("文件上传失败,将忽略文件列表", OutputType.WARNING)
792
+ # 上传失败则回退到本地加载
793
+ msg = self.prompt
794
+ for handler in self.input_handler:
795
+ msg, _ = handler(msg, self)
796
+ self.prompt = f"{self.prompt}\n\n以下是历史类似问题的执行经验,可参考:\n{load_methodology(msg, self.get_tool_registry())}"
797
+ elif self.files:
798
+ if not self.model.upload_files(self.files):
799
+ PrettyOutput.print("文件上传失败,将忽略文件列表", OutputType.WARNING)
800
+ else:
801
+ if self.files:
802
+ PrettyOutput.print("不支持上传文件,将忽略文件列表", OutputType.WARNING)
803
+ if self.use_methodology:
800
804
  msg = self.prompt
801
805
  for handler in self.input_handler:
802
806
  msg, _ = handler(msg, self)
@@ -807,20 +811,20 @@ arguments:
807
811
  current_response = self._call_model(self.prompt, True)
808
812
  self.prompt = ""
809
813
 
810
- need_return, self.prompt = self._call_tools(current_response)
811
-
812
- if need_return:
813
- return self.prompt
814
-
815
814
  if get_interrupt():
816
815
  set_interrupt(False)
817
816
  user_input = self.multiline_inputer(
818
817
  f"模型交互期间被中断,请输入用户干预信息:"
819
818
  )
820
819
  if user_input:
821
- self.prompt += f"\n\n{user_input}"
820
+ self.prompt += f"{user_input}"
822
821
  continue
823
822
 
823
+ need_return, self.prompt = self._call_tools(current_response)
824
+
825
+ if need_return:
826
+ return self.prompt
827
+
824
828
  if self.after_tool_call_cb:
825
829
  self.after_tool_call_cb(self)
826
830
 
@@ -5,7 +5,7 @@ from typing import Any, Tuple
5
5
  from jarvis.jarvis_utils.config import get_replace_map
6
6
 
7
7
 
8
- def builtin_input_handler(user_input: str, agent: Any) -> Tuple[str, bool]:
8
+ def builtin_input_handler(user_input: str, agent_: Any) -> Tuple[str, bool]:
9
9
  """
10
10
  处理内置的特殊输入标记,并追加相应的提示词
11
11
 
@@ -16,6 +16,9 @@ def builtin_input_handler(user_input: str, agent: Any) -> Tuple[str, bool]:
16
16
  返回:
17
17
  Tuple[str, bool]: 处理后的输入和是否需要进一步处理
18
18
  """
19
+ from jarvis.jarvis_agent import Agent
20
+
21
+ agent: Agent = agent_
19
22
  # 查找特殊标记
20
23
  special_tags = re.findall(r"'<([^>]+)>'", user_input)
21
24
 
@@ -34,18 +37,37 @@ def builtin_input_handler(user_input: str, agent: Any) -> Tuple[str, bool]:
34
37
  elif tag == "Clear":
35
38
  agent.clear()
36
39
  return "", True
37
-
40
+ elif tag == "ToolUsage":
41
+ from jarvis.jarvis_tools.registry import ToolRegistry
42
+
43
+ tool_registry_ = agent.get_tool_registry()
44
+ tool_registry: ToolRegistry = (
45
+ tool_registry_ if tool_registry_ else ToolRegistry()
46
+ )
47
+ agent.set_addon_prompt(tool_registry.prompt())
48
+ elif tag == "ReloadConfig":
49
+ from jarvis.jarvis_utils.utils import load_config
50
+
51
+ load_config()
52
+ return "", True
53
+
38
54
  processed_tag = set()
39
55
  add_on_prompt = ""
40
56
 
41
57
  # 处理普通替换标记
42
58
  if tag in replace_map:
43
59
  processed_tag.add(tag)
44
- if "append" in replace_map[tag] and replace_map[tag]["append"] and tag not in processed_tag:
60
+ if (
61
+ "append" in replace_map[tag]
62
+ and replace_map[tag]["append"]
63
+ and tag not in processed_tag
64
+ ):
45
65
  user_input = user_input.replace(f"'<{tag}>'", "")
46
66
  add_on_prompt += replace_map[tag]["template"] + "\n"
47
67
  else:
48
- user_input = user_input.replace(f"'<{tag}>'", replace_map[tag]["template"])
68
+ user_input = user_input.replace(
69
+ f"'<{tag}>'", replace_map[tag]["template"]
70
+ )
49
71
 
50
72
  agent.set_addon_prompt(add_on_prompt)
51
73
 
@@ -29,7 +29,9 @@ def _load_tasks() -> Dict[str, str]:
29
29
  spinner_text = f"从{pre_command_path}加载预定义任务..."
30
30
  with yaspin(text=spinner_text, color="cyan") as spinner:
31
31
  try:
32
- with open(pre_command_path, "r", encoding="utf-8", errors="ignore") as f:
32
+ with open(
33
+ pre_command_path, "r", encoding="utf-8", errors="ignore"
34
+ ) as f:
33
35
  user_tasks = yaml.safe_load(f)
34
36
  if isinstance(user_tasks, dict):
35
37
  for name, desc in user_tasks.items():
@@ -48,7 +50,9 @@ def _load_tasks() -> Dict[str, str]:
48
50
  spinner_text = f"从{abs_path}加载预定义任务..."
49
51
  with yaspin(text=spinner_text, color="cyan") as spinner:
50
52
  try:
51
- with open(pre_command_path, "r", encoding="utf-8", errors="ignore") as f:
53
+ with open(
54
+ pre_command_path, "r", encoding="utf-8", errors="ignore"
55
+ ) as f:
52
56
  local_tasks = yaml.safe_load(f)
53
57
  if isinstance(local_tasks, dict):
54
58
  for name, desc in local_tasks.items():
@@ -62,11 +66,12 @@ def _load_tasks() -> Dict[str, str]:
62
66
 
63
67
  return tasks
64
68
 
69
+
65
70
  def _select_task(tasks: Dict[str, str]) -> str:
66
71
  """Let user select a task from the list or skip. Returns task description if selected."""
67
72
  if not tasks:
68
73
  return ""
69
-
74
+
70
75
  task_names = list(tasks.keys())
71
76
  task_list = ["可用任务:"]
72
77
  for i, name in enumerate(task_names, 1):
@@ -74,7 +79,6 @@ def _select_task(tasks: Dict[str, str]) -> str:
74
79
  task_list.append("[0] 跳过预定义任务")
75
80
  PrettyOutput.print("\n".join(task_list), OutputType.INFO)
76
81
 
77
-
78
82
  while True:
79
83
  try:
80
84
  choice_str = prompt("\n请选择一个任务编号(0 跳过预定义任务):").strip()
@@ -88,13 +92,19 @@ def _select_task(tasks: Dict[str, str]) -> str:
88
92
  selected_task = tasks[task_names[choice - 1]]
89
93
  PrettyOutput.print(f"将要执行任务:\n {selected_task}", OutputType.INFO)
90
94
  # 询问是否需要补充信息
91
- need_additional = user_confirm("需要为此任务添加补充信息吗?", default=False)
95
+ need_additional = user_confirm(
96
+ "需要为此任务添加补充信息吗?", default=False
97
+ )
92
98
  if need_additional:
93
99
  additional_input = get_multiline_input("请输入补充信息:")
94
100
  if additional_input:
95
- selected_task = f"{selected_task}\n\n补充信息:\n{additional_input}"
101
+ selected_task = (
102
+ f"{selected_task}\n\n补充信息:\n{additional_input}"
103
+ )
96
104
  return selected_task
97
- PrettyOutput.print("无效的选择。请选择列表中的一个号码。", OutputType.WARNING)
105
+ PrettyOutput.print(
106
+ "无效的选择。请选择列表中的一个号码。", OutputType.WARNING
107
+ )
98
108
 
99
109
  except (KeyboardInterrupt, EOFError):
100
110
  return ""
@@ -104,26 +114,26 @@ def _select_task(tasks: Dict[str, str]) -> str:
104
114
 
105
115
  def main() -> None:
106
116
 
107
-
108
- parser = argparse.ArgumentParser(description='Jarvis AI assistant')
109
- parser.add_argument('-p', '--platform', type=str, help='Platform to use')
110
- parser.add_argument('-m', '--model', type=str, help='Model to use')
111
- parser.add_argument('-t', '--task', type=str, help='Directly input task content from command line')
112
- parser.add_argument('-f', '--config', type=str, help='Path to custom config file')
117
+ parser = argparse.ArgumentParser(description="Jarvis AI assistant")
118
+ parser.add_argument("-p", "--platform", type=str, help="Platform to use")
119
+ parser.add_argument("-m", "--model", type=str, help="Model to use")
120
+ parser.add_argument(
121
+ "-t", "--task", type=str, help="Directly input task content from command line"
122
+ )
123
+ parser.add_argument("-f", "--config", type=str, help="Path to custom config file")
113
124
  args = parser.parse_args()
114
- init_env("欢迎使用 Jarvis AI 助手,您的智能助理已准备就绪!", config_file=args.config)
125
+ init_env(
126
+ "欢迎使用 Jarvis AI 助手,您的智能助理已准备就绪!", config_file=args.config
127
+ )
115
128
 
116
129
  try:
117
130
  agent = Agent(
118
131
  system_prompt=origin_agent_system_prompt,
119
132
  platform=args.platform,
120
133
  model_name=args.model,
121
- input_handler=[
122
- shell_input_handler,
123
- builtin_input_handler
124
- ],
134
+ input_handler=[shell_input_handler, builtin_input_handler],
125
135
  output_handler=[ToolRegistry()],
126
- need_summary=False
136
+ need_summary=False,
127
137
  )
128
138
 
129
139
  # 优先处理命令行直接传入的任务
@@ -146,5 +156,6 @@ def main() -> None:
146
156
  PrettyOutput.print(f"初始化错误: {str(err)}", OutputType.ERROR)
147
157
  sys.exit(1)
148
158
 
159
+
149
160
  if __name__ == "__main__":
150
161
  main()
@@ -20,10 +20,12 @@ def load_config(config_path: str) -> dict:
20
20
  dict: 配置字典
21
21
  """
22
22
  if not os.path.exists(config_path):
23
- PrettyOutput.print(f"配置文件 {config_path} 不存在,使用默认配置", OutputType.WARNING)
23
+ PrettyOutput.print(
24
+ f"配置文件 {config_path} 不存在,使用默认配置", OutputType.WARNING
25
+ )
24
26
  return {}
25
27
 
26
- with open(config_path, 'r', encoding='utf-8', errors="ignore") as f:
28
+ with open(config_path, "r", encoding="utf-8", errors="ignore") as f:
27
29
  try:
28
30
  config = yaml.safe_load(f)
29
31
  return config if config else {}
@@ -31,20 +33,24 @@ def load_config(config_path: str) -> dict:
31
33
  PrettyOutput.print(f"配置文件解析失败: {str(e)}", OutputType.ERROR)
32
34
  return {}
33
35
 
36
+
34
37
  def main():
35
38
  """Main entry point for Jarvis agent"""
36
39
  # Set up argument parser
37
- parser = argparse.ArgumentParser(description='Jarvis AI assistant')
38
- parser.add_argument('-f', '--config', type=str, required=False,
39
- help='Path to agent config file')
40
- parser.add_argument('-c', '--agent_definition', type=str,
41
- help='Path to agent definition file')
42
- parser.add_argument('-t', '--task', type=str,
43
- help='Initial task to execute')
40
+ parser = argparse.ArgumentParser(description="Jarvis AI assistant")
41
+ parser.add_argument(
42
+ "-f", "--config", type=str, required=False, help="Path to agent config file"
43
+ )
44
+ parser.add_argument(
45
+ "-c", "--agent_definition", type=str, help="Path to agent definition file"
46
+ )
47
+ parser.add_argument("-t", "--task", type=str, help="Initial task to execute")
44
48
  args = parser.parse_args()
45
49
 
46
50
  # Initialize environment
47
- init_env("欢迎使用 Jarvis AI 助手,您的智能助理已准备就绪!", config_file=args.config)
51
+ init_env(
52
+ "欢迎使用 Jarvis AI 助手,您的智能助理已准备就绪!", config_file=args.config
53
+ )
48
54
 
49
55
  # Load configuration
50
56
  config = load_config(args.agent_definition) if args.agent_definition else {}
@@ -59,12 +65,13 @@ def main():
59
65
  agent.run(args.task)
60
66
  return 0
61
67
 
62
-
63
68
  try:
64
69
  user_input = get_multiline_input("请输入你的任务(输入空行退出):")
65
70
  if not user_input:
66
71
  return 0
67
- agent.set_addon_prompt("如果有必要,请先指定出行动计划,然后根据计划一步步执行,如果任务过于复杂,可以拆分子Agent进行执行,拆的子Agent需要掌握所有必要的任务信息,否则无法执行")
72
+ agent.set_addon_prompt(
73
+ "如果有必要,请先指定出行动计划,然后根据计划一步步执行,如果任务过于复杂,可以拆分子Agent进行执行,拆的子Agent需要掌握所有必要的任务信息,否则无法执行"
74
+ )
68
75
  agent.run(user_input)
69
76
  except Exception as e:
70
77
  PrettyOutput.print(f"错误: {str(e)}", OutputType.ERROR)
@@ -75,5 +82,6 @@ def main():
75
82
 
76
83
  return 0
77
84
 
85
+
78
86
  if __name__ == "__main__":
79
87
  exit(main())
@@ -7,11 +7,11 @@ class OutputHandler(ABC):
7
7
  @abstractmethod
8
8
  def handle(self, response: str, agent: Any) -> Tuple[bool, Any]:
9
9
  """处理响应数据
10
-
10
+
11
11
  Args:
12
12
  response: 需要处理的响应字符串
13
13
  agent: 执行处理的agent实例
14
-
14
+
15
15
  Returns:
16
16
  Tuple[bool, Any]: 返回处理结果元组,第一个元素表示是否处理成功,第二个元素为处理后的数据
17
17
  """
@@ -20,10 +20,10 @@ class OutputHandler(ABC):
20
20
  @abstractmethod
21
21
  def can_handle(self, response: str) -> bool:
22
22
  """判断是否能处理给定的响应
23
-
23
+
24
24
  Args:
25
25
  response: 需要判断的响应字符串
26
-
26
+
27
27
  Returns:
28
28
  bool: 返回是否能处理该响应
29
29
  """
@@ -32,7 +32,7 @@ class OutputHandler(ABC):
32
32
  @abstractmethod
33
33
  def prompt(self) -> str:
34
34
  """获取处理器的提示信息
35
-
35
+
36
36
  Returns:
37
37
  str: 返回处理器的提示字符串
38
38
  """
@@ -41,8 +41,8 @@ class OutputHandler(ABC):
41
41
  @abstractmethod
42
42
  def name(self) -> str:
43
43
  """获取处理器的名称
44
-
44
+
45
45
  Returns:
46
46
  str: 返回处理器的名称字符串
47
47
  """
48
- pass
48
+ pass
@@ -11,20 +11,23 @@ def shell_input_handler(user_input: str, agent: Any) -> Tuple[str, bool]:
11
11
  if len(cmdline) == 0:
12
12
  return user_input, False
13
13
  else:
14
- script = '\n'.join([c[1:] for c in cmdline])
14
+ script = "\n".join([c[1:] for c in cmdline])
15
15
  PrettyOutput.print(script, OutputType.CODE, lang="bash")
16
16
  if user_confirm(f"是否要执行以上shell脚本?", default=True):
17
17
  from jarvis.jarvis_tools.registry import ToolRegistry
18
- output = ToolRegistry().handle_tool_calls({
19
- "name": "execute_script",
20
- "want": "提取命令执行结果关键信息",
21
- "arguments": {
22
- "interpreter": "bash",
23
- "script_content": script
24
- }
25
- }, agent)
18
+
19
+ output = ToolRegistry().handle_tool_calls(
20
+ {
21
+ "name": "execute_script",
22
+ "want": "提取命令执行结果关键信息",
23
+ "arguments": {"interpreter": "bash", "script_content": script},
24
+ },
25
+ agent,
26
+ )
26
27
  if user_confirm("是否将执行结果反馈给Agent?", default=True):
27
- return f"{user_input}\n\n用户执行以下脚本:\n{script}\n\n执行结果:\n{output}", False
28
+ return (
29
+ f"{user_input}\n\n用户执行以下脚本:\n{script}\n\n执行结果:\n{output}",
30
+ False,
31
+ )
28
32
  return "", True
29
33
  return user_input, False
30
-