jarvis-ai-assistant 0.7.0__py3-none-any.whl → 0.7.6__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 (159) hide show
  1. jarvis/__init__.py +1 -1
  2. jarvis/jarvis_agent/__init__.py +243 -139
  3. jarvis/jarvis_agent/agent_manager.py +5 -10
  4. jarvis/jarvis_agent/builtin_input_handler.py +2 -6
  5. jarvis/jarvis_agent/config_editor.py +2 -7
  6. jarvis/jarvis_agent/event_bus.py +82 -12
  7. jarvis/jarvis_agent/file_context_handler.py +265 -15
  8. jarvis/jarvis_agent/file_methodology_manager.py +3 -4
  9. jarvis/jarvis_agent/jarvis.py +113 -98
  10. jarvis/jarvis_agent/language_extractors/__init__.py +57 -0
  11. jarvis/jarvis_agent/language_extractors/c_extractor.py +21 -0
  12. jarvis/jarvis_agent/language_extractors/cpp_extractor.py +21 -0
  13. jarvis/jarvis_agent/language_extractors/go_extractor.py +21 -0
  14. jarvis/jarvis_agent/language_extractors/java_extractor.py +84 -0
  15. jarvis/jarvis_agent/language_extractors/javascript_extractor.py +79 -0
  16. jarvis/jarvis_agent/language_extractors/python_extractor.py +21 -0
  17. jarvis/jarvis_agent/language_extractors/rust_extractor.py +21 -0
  18. jarvis/jarvis_agent/language_extractors/typescript_extractor.py +84 -0
  19. jarvis/jarvis_agent/language_support_info.py +486 -0
  20. jarvis/jarvis_agent/main.py +6 -12
  21. jarvis/jarvis_agent/memory_manager.py +7 -16
  22. jarvis/jarvis_agent/methodology_share_manager.py +10 -16
  23. jarvis/jarvis_agent/prompt_manager.py +1 -1
  24. jarvis/jarvis_agent/prompts.py +193 -171
  25. jarvis/jarvis_agent/protocols.py +8 -12
  26. jarvis/jarvis_agent/run_loop.py +77 -14
  27. jarvis/jarvis_agent/session_manager.py +2 -3
  28. jarvis/jarvis_agent/share_manager.py +12 -21
  29. jarvis/jarvis_agent/shell_input_handler.py +1 -2
  30. jarvis/jarvis_agent/task_analyzer.py +26 -4
  31. jarvis/jarvis_agent/task_manager.py +11 -27
  32. jarvis/jarvis_agent/tool_executor.py +2 -3
  33. jarvis/jarvis_agent/tool_share_manager.py +12 -24
  34. jarvis/jarvis_agent/web_server.py +55 -20
  35. jarvis/jarvis_c2rust/__init__.py +5 -5
  36. jarvis/jarvis_c2rust/cli.py +461 -499
  37. jarvis/jarvis_c2rust/collector.py +45 -53
  38. jarvis/jarvis_c2rust/constants.py +26 -0
  39. jarvis/jarvis_c2rust/library_replacer.py +264 -132
  40. jarvis/jarvis_c2rust/llm_module_agent.py +162 -190
  41. jarvis/jarvis_c2rust/loaders.py +207 -0
  42. jarvis/jarvis_c2rust/models.py +28 -0
  43. jarvis/jarvis_c2rust/optimizer.py +1592 -395
  44. jarvis/jarvis_c2rust/transpiler.py +1722 -1064
  45. jarvis/jarvis_c2rust/utils.py +385 -0
  46. jarvis/jarvis_code_agent/build_validation_config.py +2 -3
  47. jarvis/jarvis_code_agent/code_agent.py +394 -320
  48. jarvis/jarvis_code_agent/code_analyzer/__init__.py +3 -0
  49. jarvis/jarvis_code_agent/code_analyzer/build_validator/base.py +4 -0
  50. jarvis/jarvis_code_agent/code_analyzer/build_validator/cmake.py +17 -2
  51. jarvis/jarvis_code_agent/code_analyzer/build_validator/fallback.py +3 -0
  52. jarvis/jarvis_code_agent/code_analyzer/build_validator/go.py +36 -4
  53. jarvis/jarvis_code_agent/code_analyzer/build_validator/java_gradle.py +9 -0
  54. jarvis/jarvis_code_agent/code_analyzer/build_validator/java_maven.py +9 -0
  55. jarvis/jarvis_code_agent/code_analyzer/build_validator/makefile.py +12 -1
  56. jarvis/jarvis_code_agent/code_analyzer/build_validator/nodejs.py +22 -5
  57. jarvis/jarvis_code_agent/code_analyzer/build_validator/python.py +57 -32
  58. jarvis/jarvis_code_agent/code_analyzer/build_validator/rust.py +62 -6
  59. jarvis/jarvis_code_agent/code_analyzer/build_validator/validator.py +8 -9
  60. jarvis/jarvis_code_agent/code_analyzer/context_manager.py +290 -5
  61. jarvis/jarvis_code_agent/code_analyzer/language_support.py +21 -0
  62. jarvis/jarvis_code_agent/code_analyzer/languages/__init__.py +21 -3
  63. jarvis/jarvis_code_agent/code_analyzer/languages/c_cpp_language.py +72 -4
  64. jarvis/jarvis_code_agent/code_analyzer/languages/go_language.py +35 -3
  65. jarvis/jarvis_code_agent/code_analyzer/languages/java_language.py +212 -0
  66. jarvis/jarvis_code_agent/code_analyzer/languages/javascript_language.py +254 -0
  67. jarvis/jarvis_code_agent/code_analyzer/languages/python_language.py +52 -2
  68. jarvis/jarvis_code_agent/code_analyzer/languages/rust_language.py +73 -1
  69. jarvis/jarvis_code_agent/code_analyzer/languages/typescript_language.py +280 -0
  70. jarvis/jarvis_code_agent/code_analyzer/llm_context_recommender.py +306 -152
  71. jarvis/jarvis_code_agent/code_analyzer/structured_code.py +556 -0
  72. jarvis/jarvis_code_agent/code_analyzer/symbol_extractor.py +193 -18
  73. jarvis/jarvis_code_agent/code_analyzer/tree_sitter_extractor.py +18 -8
  74. jarvis/jarvis_code_agent/lint.py +258 -27
  75. jarvis/jarvis_code_agent/utils.py +0 -1
  76. jarvis/jarvis_code_analysis/code_review.py +19 -24
  77. jarvis/jarvis_data/config_schema.json +53 -26
  78. jarvis/jarvis_git_squash/main.py +4 -5
  79. jarvis/jarvis_git_utils/git_commiter.py +44 -49
  80. jarvis/jarvis_mcp/sse_mcp_client.py +20 -27
  81. jarvis/jarvis_mcp/stdio_mcp_client.py +11 -12
  82. jarvis/jarvis_mcp/streamable_mcp_client.py +15 -14
  83. jarvis/jarvis_memory_organizer/memory_organizer.py +55 -74
  84. jarvis/jarvis_methodology/main.py +32 -48
  85. jarvis/jarvis_multi_agent/__init__.py +79 -61
  86. jarvis/jarvis_multi_agent/main.py +3 -7
  87. jarvis/jarvis_platform/base.py +469 -199
  88. jarvis/jarvis_platform/human.py +7 -8
  89. jarvis/jarvis_platform/kimi.py +30 -36
  90. jarvis/jarvis_platform/openai.py +65 -27
  91. jarvis/jarvis_platform/registry.py +26 -10
  92. jarvis/jarvis_platform/tongyi.py +24 -25
  93. jarvis/jarvis_platform/yuanbao.py +31 -42
  94. jarvis/jarvis_platform_manager/main.py +66 -77
  95. jarvis/jarvis_platform_manager/service.py +8 -13
  96. jarvis/jarvis_rag/cli.py +49 -51
  97. jarvis/jarvis_rag/embedding_manager.py +13 -18
  98. jarvis/jarvis_rag/llm_interface.py +8 -9
  99. jarvis/jarvis_rag/query_rewriter.py +10 -21
  100. jarvis/jarvis_rag/rag_pipeline.py +24 -27
  101. jarvis/jarvis_rag/reranker.py +4 -5
  102. jarvis/jarvis_rag/retriever.py +28 -30
  103. jarvis/jarvis_sec/__init__.py +220 -3520
  104. jarvis/jarvis_sec/agents.py +143 -0
  105. jarvis/jarvis_sec/analysis.py +276 -0
  106. jarvis/jarvis_sec/cli.py +29 -6
  107. jarvis/jarvis_sec/clustering.py +1439 -0
  108. jarvis/jarvis_sec/file_manager.py +427 -0
  109. jarvis/jarvis_sec/parsers.py +73 -0
  110. jarvis/jarvis_sec/prompts.py +268 -0
  111. jarvis/jarvis_sec/report.py +83 -4
  112. jarvis/jarvis_sec/review.py +453 -0
  113. jarvis/jarvis_sec/utils.py +499 -0
  114. jarvis/jarvis_sec/verification.py +848 -0
  115. jarvis/jarvis_sec/workflow.py +7 -0
  116. jarvis/jarvis_smart_shell/main.py +38 -87
  117. jarvis/jarvis_stats/cli.py +1 -1
  118. jarvis/jarvis_stats/stats.py +7 -7
  119. jarvis/jarvis_stats/storage.py +15 -21
  120. jarvis/jarvis_tools/clear_memory.py +3 -20
  121. jarvis/jarvis_tools/cli/main.py +20 -23
  122. jarvis/jarvis_tools/edit_file.py +1066 -0
  123. jarvis/jarvis_tools/execute_script.py +42 -21
  124. jarvis/jarvis_tools/file_analyzer.py +6 -9
  125. jarvis/jarvis_tools/generate_new_tool.py +11 -20
  126. jarvis/jarvis_tools/lsp_client.py +1552 -0
  127. jarvis/jarvis_tools/methodology.py +2 -3
  128. jarvis/jarvis_tools/read_code.py +1525 -87
  129. jarvis/jarvis_tools/read_symbols.py +2 -3
  130. jarvis/jarvis_tools/read_webpage.py +7 -10
  131. jarvis/jarvis_tools/registry.py +370 -181
  132. jarvis/jarvis_tools/retrieve_memory.py +20 -19
  133. jarvis/jarvis_tools/rewrite_file.py +105 -0
  134. jarvis/jarvis_tools/save_memory.py +3 -15
  135. jarvis/jarvis_tools/search_web.py +3 -7
  136. jarvis/jarvis_tools/sub_agent.py +17 -6
  137. jarvis/jarvis_tools/sub_code_agent.py +14 -16
  138. jarvis/jarvis_tools/virtual_tty.py +54 -32
  139. jarvis/jarvis_utils/clipboard.py +7 -10
  140. jarvis/jarvis_utils/config.py +98 -63
  141. jarvis/jarvis_utils/embedding.py +5 -5
  142. jarvis/jarvis_utils/fzf.py +8 -8
  143. jarvis/jarvis_utils/git_utils.py +81 -67
  144. jarvis/jarvis_utils/input.py +24 -49
  145. jarvis/jarvis_utils/jsonnet_compat.py +465 -0
  146. jarvis/jarvis_utils/methodology.py +33 -35
  147. jarvis/jarvis_utils/utils.py +245 -202
  148. {jarvis_ai_assistant-0.7.0.dist-info → jarvis_ai_assistant-0.7.6.dist-info}/METADATA +205 -70
  149. jarvis_ai_assistant-0.7.6.dist-info/RECORD +218 -0
  150. jarvis/jarvis_agent/edit_file_handler.py +0 -584
  151. jarvis/jarvis_agent/rewrite_file_handler.py +0 -141
  152. jarvis/jarvis_agent/task_planner.py +0 -496
  153. jarvis/jarvis_platform/ai8.py +0 -332
  154. jarvis/jarvis_tools/ask_user.py +0 -54
  155. jarvis_ai_assistant-0.7.0.dist-info/RECORD +0 -192
  156. {jarvis_ai_assistant-0.7.0.dist-info → jarvis_ai_assistant-0.7.6.dist-info}/WHEEL +0 -0
  157. {jarvis_ai_assistant-0.7.0.dist-info → jarvis_ai_assistant-0.7.6.dist-info}/entry_points.txt +0 -0
  158. {jarvis_ai_assistant-0.7.0.dist-info → jarvis_ai_assistant-0.7.6.dist-info}/licenses/LICENSE +0 -0
  159. {jarvis_ai_assistant-0.7.0.dist-info → jarvis_ai_assistant-0.7.6.dist-info}/top_level.txt +0 -0
@@ -5,7 +5,6 @@ from typing import Dict
5
5
  import typer
6
6
 
7
7
  from jarvis.jarvis_git_utils.git_commiter import GitCommitTool
8
- from jarvis.jarvis_utils.output import OutputType, PrettyOutput
9
8
  from jarvis.jarvis_utils.utils import init_env
10
9
  from jarvis.jarvis_utils.input import user_confirm
11
10
  from jarvis.jarvis_utils.globals import get_agent, current_agent_name
@@ -38,11 +37,11 @@ class GitSquashTool:
38
37
  """Execute the squash operation"""
39
38
  try:
40
39
  if not self._confirm_squash():
41
- PrettyOutput.print("操作已取消", OutputType.WARNING)
40
+ print("⚠️ 操作已取消")
42
41
  return
43
42
 
44
43
  if not self._reset_to_commit(args["commit_hash"]):
45
- PrettyOutput.print("重置到指定提交失败", OutputType.WARNING)
44
+ print("⚠️ 重置到指定提交失败")
46
45
  return
47
46
 
48
47
  # Use existing GitCommitTool for new commit
@@ -53,7 +52,7 @@ class GitSquashTool:
53
52
  exec_args["agent"] = agent
54
53
  commit_tool.execute(exec_args)
55
54
  except Exception as e:
56
- PrettyOutput.print(f"压缩提交失败: {str(e)}", OutputType.WARNING)
55
+ print(f"⚠️ 压缩提交失败: {str(e)}")
57
56
 
58
57
 
59
58
  @app.command()
@@ -61,7 +60,7 @@ def cli(
61
60
  commit_hash: str = typer.Argument(..., help="要压缩的基础提交哈希"),
62
61
  lang: str = typer.Option("Chinese", "--lang", help="提交信息的语言"),
63
62
  ):
64
- init_env("欢迎使用 Jarvis-GitSquash,您的Git压缩助手已准备就绪!")
63
+ init_env()
65
64
  tool = GitSquashTool()
66
65
  tool.execute({"commit_hash": commit_hash, "lang": lang})
67
66
 
@@ -75,7 +75,7 @@ class GitCommitTool:
75
75
  os.chdir(root_dir)
76
76
  find_git_root_and_cd()
77
77
  if not has_uncommitted_changes():
78
- PrettyOutput.print("没有未提交的更改", OutputType.SUCCESS)
78
+ print("没有未提交的更改")
79
79
  return None
80
80
  return original_dir
81
81
 
@@ -129,42 +129,7 @@ class GitCommitTool:
129
129
 
130
130
  try:
131
131
  temp_diff_file_path = None
132
- # 生成提交信息
133
- PrettyOutput.print("正在生成提交消息...", OutputType.INFO)
134
-
135
- # 准备提示信息
136
- custom_prompt = get_git_commit_prompt()
137
- base_prompt = (
138
- custom_prompt
139
- if custom_prompt
140
- else """根据代码差异生成提交信息:
141
- 提交信息应使用中文书写
142
- # 格式模板
143
- 必须使用以下格式:
144
-
145
- <类型>(<范围>): <主题>
146
-
147
- [可选] 详细描述变更内容和原因
148
-
149
- # 格式规则
150
- 1. 类型: fix(修复bug), feat(新功能), docs(文档), style(格式), refactor(重构), test(测试), chore(其他)
151
- 2. 范围表示变更的模块或组件 (例如: auth, database, ui)
152
- 3. 主题行不超过72个字符,不以句号结尾,使用祈使语气
153
- 4. 如有详细描述,使用空行分隔主题和详细描述
154
- 5. 详细描述部分应解释"是什么"和"为什么",而非"如何"
155
- 6. 仅输出提交信息,不要输出其他内容
156
- """
157
- )
158
- base_prompt += f"""
159
- # 输出格式
160
- {ot("COMMIT_MESSAGE")}
161
- commit信息
162
- {ct("COMMIT_MESSAGE")}
163
- """
164
-
165
- # 优先从调用方传入的 agent 获取平台与模型
166
- agent_from_args = args.get("agent")
167
-
132
+
168
133
  # Get model_group from args
169
134
  model_group = args.get("model_group")
170
135
 
@@ -184,6 +149,7 @@ commit信息
184
149
  model_name = get_normal_model_name(model_group)
185
150
  else:
186
151
  # 如果没有提供 model_group,尝试从传入的 agent 获取
152
+ agent_from_args = args.get("agent")
187
153
  if (
188
154
  agent_from_args
189
155
  and hasattr(agent_from_args, "model")
@@ -239,6 +205,40 @@ commit信息
239
205
  else:
240
206
  platform = PlatformRegistry().get_normal_platform()
241
207
 
208
+ # 生成提交信息
209
+ model_display_name = model_name or (platform.name() if platform else "AI")
210
+ print(f"ℹ️ 正在使用{model_display_name}生成提交消息...")
211
+
212
+ # 准备提示信息
213
+ custom_prompt = get_git_commit_prompt()
214
+ base_prompt = (
215
+ custom_prompt
216
+ if custom_prompt
217
+ else """根据代码差异生成提交信息:
218
+ 提交信息应使用中文书写
219
+ # 格式模板
220
+ 必须使用以下格式:
221
+
222
+ <类型>(<范围>): <主题>
223
+
224
+ [可选] 详细描述变更内容和原因
225
+
226
+ # 格式规则
227
+ 1. 类型: fix(修复bug), feat(新功能), docs(文档), style(格式), refactor(重构), test(测试), chore(其他)
228
+ 2. 范围表示变更的模块或组件 (例如: auth, database, ui)
229
+ 3. 主题行不超过72个字符,不以句号结尾,使用祈使语气
230
+ 4. 如有详细描述,使用空行分隔主题和详细描述
231
+ 5. 详细描述部分应解释"是什么"和"为什么",而非"如何"
232
+ 6. 仅输出提交信息,不要输出其他内容
233
+ """
234
+ )
235
+ base_prompt += f"""
236
+ # 输出格式
237
+ {ot("COMMIT_MESSAGE")}
238
+ commit信息
239
+ {ct("COMMIT_MESSAGE")}
240
+ """
241
+
242
242
  # 跳过模型可用性校验:
243
243
  # 为避免某些平台/代理不支持 get_model_list 接口导致的噪音日志(如 404),
244
244
  # 这里默认不调用 platform.get_model_list() 进行模型可用性校验。
@@ -256,11 +256,11 @@ commit信息
256
256
  upload_success = False
257
257
 
258
258
  # Check if content is too large
259
- is_large_content = is_context_overflow(diff, model_group)
259
+ is_large_content = is_context_overflow(diff, model_group, platform)
260
260
 
261
261
  if is_large_content:
262
262
  if not platform.support_upload_files():
263
- PrettyOutput.print("差异文件太大,无法处理", OutputType.ERROR)
263
+ print("差异文件太大,无法处理")
264
264
  return {
265
265
  "success": False,
266
266
  "stdout": "",
@@ -279,7 +279,7 @@ commit信息
279
279
  if upload_success:
280
280
  pass
281
281
  else:
282
- PrettyOutput.print("上传代码差异文件失败", OutputType.ERROR)
282
+ print("上传代码差异文件失败")
283
283
  return {
284
284
  "success": False,
285
285
  "stdout": "",
@@ -378,14 +378,9 @@ commit信息
378
378
  try:
379
379
  os.unlink(temp_diff_file_path)
380
380
  except Exception as e:
381
- PrettyOutput.print(
382
- f"无法删除临时文件: {str(e)}", OutputType.WARNING
383
- )
381
+ print(f"⚠️ 无法删除临时文件: {str(e)}")
384
382
 
385
- PrettyOutput.print(
386
- f"提交哈希: {commit_hash}\n提交消息: {commit_message}",
387
- OutputType.SUCCESS,
388
- )
383
+ PrettyOutput.print(f"提交哈希: {commit_hash}\n提交消息: {commit_message}", OutputType.SUCCESS)
389
384
 
390
385
  return {
391
386
  "success": True,
@@ -396,7 +391,7 @@ commit信息
396
391
  "stderr": "",
397
392
  }
398
393
  except Exception as e:
399
- PrettyOutput.print(f"提交失败: {str(e)}", OutputType.ERROR)
394
+ print(f"提交失败: {str(e)}")
400
395
  return {
401
396
  "success": False,
402
397
  "stdout": "",
@@ -425,7 +420,7 @@ def cli(
425
420
  None, "-g", "--llm-group", help="使用的模型组,覆盖配置文件中的设置"
426
421
  ),
427
422
  ):
428
- init_env("欢迎使用 Jarvis-GitCommitTool,您的Git提交助手已准备就绪!")
423
+ init_env()
429
424
  tool = GitCommitTool()
430
425
  tool.execute(
431
426
  {
@@ -8,7 +8,6 @@ from urllib.parse import parse_qs, urlencode, urljoin
8
8
  import requests # type: ignore[import-untyped]
9
9
 
10
10
  from jarvis.jarvis_mcp import McpClient
11
- from jarvis.jarvis_utils.output import OutputType, PrettyOutput
12
11
 
13
12
 
14
13
  class SSEMcpClient(McpClient):
@@ -78,13 +77,10 @@ class SSEMcpClient(McpClient):
78
77
 
79
78
  if not self.messages_endpoint:
80
79
  self.messages_endpoint = "/messages" # 默认端点
81
- PrettyOutput.print(
82
- f"未获取到消息端点,使用默认值: {self.messages_endpoint}",
83
- OutputType.WARNING,
84
- )
80
+ print(f"⚠️ 未获取到消息端点,使用默认值: {self.messages_endpoint}")
85
81
 
86
82
  if not self.session_id:
87
- PrettyOutput.print("未获取到会话ID", OutputType.WARNING)
83
+ print("⚠️ 未获取到会话ID")
88
84
 
89
85
  # 发送初始化请求
90
86
  response = self._send_request(
@@ -107,7 +103,7 @@ class SSEMcpClient(McpClient):
107
103
  self._send_notification("notifications/initialized", {})
108
104
 
109
105
  except Exception as e:
110
- PrettyOutput.print(f"MCP初始化失败: {str(e)}", OutputType.ERROR)
106
+ print(f"MCP初始化失败: {str(e)}")
111
107
  raise
112
108
 
113
109
  def _start_sse_connection(self) -> None:
@@ -138,7 +134,7 @@ class SSEMcpClient(McpClient):
138
134
  self.sse_thread.start()
139
135
 
140
136
  except Exception as e:
141
- PrettyOutput.print(f"SSE连接失败: {str(e)}", OutputType.ERROR)
137
+ print(f"SSE连接失败: {str(e)}")
142
138
  raise
143
139
 
144
140
  def _process_sse_events(self) -> None:
@@ -166,9 +162,7 @@ class SSEMcpClient(McpClient):
166
162
  if "session_id" in query_params:
167
163
  self.session_id = query_params["session_id"][0]
168
164
  except Exception as e:
169
- PrettyOutput.print(
170
- f"解析消息端点或会话ID失败: {e}", OutputType.WARNING
171
- )
165
+ print(f"⚠️ 解析消息端点或会话ID失败: {e}")
172
166
  else:
173
167
  buffer += data
174
168
  elif line.startswith(":"): # 忽略注释行
@@ -184,10 +178,10 @@ class SSEMcpClient(McpClient):
184
178
  try:
185
179
  self._handle_sse_event(buffer)
186
180
  except Exception as e:
187
- PrettyOutput.print(f"处理SSE事件出错: {e}", OutputType.ERROR)
181
+ print(f"处理SSE事件出错: {e}")
188
182
  buffer = ""
189
183
 
190
- PrettyOutput.print("SSE连接已关闭", OutputType.WARNING)
184
+ print("⚠️ SSE连接已关闭")
191
185
 
192
186
  def _handle_sse_event(self, data: str) -> None:
193
187
  """处理单个SSE事件数据"""
@@ -217,11 +211,10 @@ class SSEMcpClient(McpClient):
217
211
  except Exception as e:
218
212
  error_lines.append(f"处理通知时出错 ({method}): {e}")
219
213
  if error_lines:
220
- PrettyOutput.print("\n".join(error_lines), OutputType.ERROR)
221
- except json.JSONDecodeError:
222
- PrettyOutput.print(f"无法解析SSE事件: {data}", OutputType.WARNING)
223
- except Exception as e:
224
- PrettyOutput.print(f"处理SSE事件时出错: {e}", OutputType.ERROR)
214
+ joined_errors = '\n'.join(error_lines)
215
+ print(f"❌ {joined_errors}")
216
+ except Exception:
217
+ print(f"⚠️ 无法解析SSE事件: {data}")
225
218
 
226
219
  def register_notification_handler(self, method: str, handler: Callable) -> None:
227
220
  """注册通知处理器
@@ -341,7 +334,7 @@ class SSEMcpClient(McpClient):
341
334
  self.pending_requests.pop(req_id, None)
342
335
  self.request_results.pop(req_id, None)
343
336
 
344
- PrettyOutput.print(f"发送请求失败: {str(e)}", OutputType.ERROR)
337
+ print(f"发送请求失败: {str(e)}")
345
338
  raise
346
339
 
347
340
  def _send_notification(self, method: str, params: Dict[str, Any]) -> None:
@@ -396,7 +389,7 @@ class SSEMcpClient(McpClient):
396
389
  post_response.raise_for_status()
397
390
 
398
391
  except Exception as e:
399
- PrettyOutput.print(f"发送通知失败: {str(e)}", OutputType.ERROR)
392
+ print(f"发送通知失败: {str(e)}")
400
393
  raise
401
394
 
402
395
  def get_tool_list(self) -> List[Dict[str, Any]]:
@@ -439,10 +432,10 @@ class SSEMcpClient(McpClient):
439
432
  else:
440
433
  error_msg += ": 未知错误"
441
434
 
442
- PrettyOutput.print(error_msg, OutputType.ERROR)
435
+ print(f"❌ {error_msg}")
443
436
  return []
444
437
  except Exception as e:
445
- PrettyOutput.print(f"获取工具列表失败: {str(e)}", OutputType.ERROR)
438
+ print(f"获取工具列表失败: {str(e)}")
446
439
  return []
447
440
 
448
441
  def execute(self, tool_name: str, arguments: Dict[str, Any]) -> Dict[str, Any]:
@@ -481,7 +474,7 @@ class SSEMcpClient(McpClient):
481
474
  "stderr": response.get("error", "Unknown error"),
482
475
  }
483
476
  except Exception as e:
484
- PrettyOutput.print(f"执行工具失败: {str(e)}", OutputType.ERROR)
477
+ print(f"执行工具失败: {str(e)}")
485
478
  return {"success": False, "stdout": "", "stderr": str(e)}
486
479
 
487
480
  def get_resource_list(self) -> List[Dict[str, Any]]:
@@ -504,10 +497,10 @@ class SSEMcpClient(McpClient):
504
497
  error_msg += f": {response['error']}"
505
498
  else:
506
499
  error_msg += ": 未知错误"
507
- PrettyOutput.print(error_msg, OutputType.ERROR)
500
+ print(f"❌ {error_msg}")
508
501
  return []
509
502
  except Exception as e:
510
- PrettyOutput.print(f"获取资源列表失败: {str(e)}", OutputType.ERROR)
503
+ print(f"获取资源列表失败: {str(e)}")
511
504
  return []
512
505
 
513
506
  def get_resource(self, uri: str) -> Dict[str, Any]:
@@ -548,11 +541,11 @@ class SSEMcpClient(McpClient):
548
541
  error_msg += f": {response['error']}"
549
542
  else:
550
543
  error_msg += ": 未知错误"
551
- PrettyOutput.print(error_msg, OutputType.ERROR)
544
+ print(f"❌ {error_msg}")
552
545
  return {"success": False, "stdout": "", "stderr": error_msg}
553
546
  except Exception as e:
554
547
  error_msg = f"获取资源内容失败: {str(e)}"
555
- PrettyOutput.print(error_msg, OutputType.ERROR)
548
+ print(f"❌ {error_msg}")
556
549
  return {"success": False, "stdout": "", "stderr": error_msg}
557
550
 
558
551
  def __del__(self):
@@ -5,7 +5,6 @@ import subprocess
5
5
  from typing import Any, Dict, List, Optional
6
6
 
7
7
  from jarvis.jarvis_mcp import McpClient
8
- from jarvis.jarvis_utils.output import OutputType, PrettyOutput
9
8
 
10
9
 
11
10
  class StdioMcpClient(McpClient):
@@ -50,7 +49,7 @@ class StdioMcpClient(McpClient):
50
49
  )
51
50
 
52
51
  except Exception as e:
53
- PrettyOutput.print(f"启动MCP进程失败: {str(e)}", OutputType.ERROR)
52
+ print(f"启动MCP进程失败: {str(e)}")
54
53
  raise
55
54
 
56
55
  def _initialize(self) -> None:
@@ -79,7 +78,7 @@ class StdioMcpClient(McpClient):
79
78
  self._send_notification("notifications/initialized", {})
80
79
 
81
80
  except Exception as e:
82
- PrettyOutput.print(f"MCP初始化失败: {str(e)}", OutputType.ERROR)
81
+ print(f"MCP初始化失败: {str(e)}")
83
82
  raise
84
83
 
85
84
  def _send_request(self, method: str, params: Dict[str, Any]) -> Dict[str, Any]:
@@ -108,7 +107,7 @@ class StdioMcpClient(McpClient):
108
107
  return json.loads(response)
109
108
 
110
109
  except Exception as e:
111
- PrettyOutput.print(f"发送请求失败: {str(e)}", OutputType.ERROR)
110
+ print(f"发送请求失败: {str(e)}")
112
111
  raise
113
112
 
114
113
  def _send_notification(self, method: str, params: Dict[str, Any]) -> None:
@@ -129,7 +128,7 @@ class StdioMcpClient(McpClient):
129
128
  self.process.stdin.flush() # type: ignore
130
129
 
131
130
  except Exception as e:
132
- PrettyOutput.print(f"发送通知失败: {str(e)}", OutputType.ERROR)
131
+ print(f"发送通知失败: {str(e)}")
133
132
  raise
134
133
 
135
134
  def get_tool_list(self) -> List[Dict[str, Any]]:
@@ -172,10 +171,10 @@ class StdioMcpClient(McpClient):
172
171
  else:
173
172
  error_msg += ": 未知错误"
174
173
 
175
- PrettyOutput.print(error_msg, OutputType.ERROR)
174
+ print(f"❌ {error_msg}")
176
175
  return []
177
176
  except Exception as e:
178
- PrettyOutput.print(f"获取工具列表失败: {str(e)}", OutputType.ERROR)
177
+ print(f"获取工具列表失败: {str(e)}")
179
178
  return []
180
179
 
181
180
  def execute(self, tool_name: str, arguments: Dict[str, Any]) -> Dict[str, Any]:
@@ -214,7 +213,7 @@ class StdioMcpClient(McpClient):
214
213
  "stderr": response.get("error", "Unknown error"),
215
214
  }
216
215
  except Exception as e:
217
- PrettyOutput.print(f"执行工具失败: {str(e)}", OutputType.ERROR)
216
+ print(f"执行工具失败: {str(e)}")
218
217
  return {"success": False, "stdout": "", "stderr": str(e)}
219
218
 
220
219
  def get_resource_list(self) -> List[Dict[str, Any]]:
@@ -237,10 +236,10 @@ class StdioMcpClient(McpClient):
237
236
  error_msg += f": {response['error']}"
238
237
  else:
239
238
  error_msg += ": 未知错误"
240
- PrettyOutput.print(error_msg, OutputType.ERROR)
239
+ print(f"❌ {error_msg}")
241
240
  return []
242
241
  except Exception as e:
243
- PrettyOutput.print(f"获取资源列表失败: {str(e)}", OutputType.ERROR)
242
+ print(f"获取资源列表失败: {str(e)}")
244
243
  return []
245
244
 
246
245
  def get_resource(self, uri: str) -> Dict[str, Any]:
@@ -281,11 +280,11 @@ class StdioMcpClient(McpClient):
281
280
  error_msg += f": {response['error']}"
282
281
  else:
283
282
  error_msg += ": 未知错误"
284
- PrettyOutput.print(error_msg, OutputType.ERROR)
283
+ print(f"❌ {error_msg}")
285
284
  return {"success": False, "stdout": "", "stderr": error_msg}
286
285
  except Exception as e:
287
286
  error_msg = f"获取资源内容失败: {str(e)}"
288
- PrettyOutput.print(error_msg, OutputType.ERROR)
287
+ print(f"❌ {error_msg}")
289
288
  return {"success": False, "stdout": "", "stderr": error_msg}
290
289
 
291
290
  def __del__(self):
@@ -7,7 +7,6 @@ from urllib.parse import urljoin
7
7
  import requests # type: ignore[import-untyped]
8
8
 
9
9
  from jarvis.jarvis_mcp import McpClient
10
- from jarvis.jarvis_utils.output import OutputType, PrettyOutput
11
10
 
12
11
 
13
12
  class StreamableMcpClient(McpClient):
@@ -86,7 +85,7 @@ class StreamableMcpClient(McpClient):
86
85
  self._send_notification("notifications/initialized", {})
87
86
 
88
87
  except Exception as e:
89
- PrettyOutput.print(f"MCP初始化失败: {str(e)}", OutputType.ERROR)
88
+ print(f"MCP初始化失败: {str(e)}")
90
89
  raise
91
90
 
92
91
  def register_notification_handler(self, method: str, handler: Callable) -> None:
@@ -182,14 +181,16 @@ class StreamableMcpClient(McpClient):
182
181
  handler(params)
183
182
  except Exception as e:
184
183
  error_lines.append(f"处理通知时出错 ({notify_method}): {e}")
185
- except json.JSONDecodeError:
184
+ except Exception:
186
185
  warning_lines.append(f"无法解析响应: {line}")
187
186
  continue
188
187
 
189
188
  if warning_lines:
190
- PrettyOutput.print("\n".join(warning_lines), OutputType.WARNING)
189
+ joined_warnings = '\n'.join(warning_lines)
190
+ print(f"⚠️ {joined_warnings}")
191
191
  if error_lines:
192
- PrettyOutput.print("\n".join(error_lines), OutputType.ERROR)
192
+ joined_errors = '\n'.join(error_lines)
193
+ print(f"❌ {joined_errors}")
193
194
  # Ensure response is closed after streaming
194
195
  response.close()
195
196
  if result is None:
@@ -198,7 +199,7 @@ class StreamableMcpClient(McpClient):
198
199
  return result
199
200
 
200
201
  except Exception as e:
201
- PrettyOutput.print(f"发送请求失败: {str(e)}", OutputType.ERROR)
202
+ print(f"发送请求失败: {str(e)}")
202
203
  raise
203
204
  finally:
204
205
  # 清理请求状态
@@ -226,7 +227,7 @@ class StreamableMcpClient(McpClient):
226
227
  response.close()
227
228
 
228
229
  except Exception as e:
229
- PrettyOutput.print(f"发送通知失败: {str(e)}", OutputType.ERROR)
230
+ print(f"发送通知失败: {str(e)}")
230
231
  raise
231
232
 
232
233
  def get_tool_list(self) -> List[Dict[str, Any]]:
@@ -269,10 +270,10 @@ class StreamableMcpClient(McpClient):
269
270
  else:
270
271
  error_msg += ": 未知错误"
271
272
 
272
- PrettyOutput.print(error_msg, OutputType.ERROR)
273
+ print(f"❌ {error_msg}")
273
274
  return []
274
275
  except Exception as e:
275
- PrettyOutput.print(f"获取工具列表失败: {str(e)}", OutputType.ERROR)
276
+ print(f"获取工具列表失败: {str(e)}")
276
277
  return []
277
278
 
278
279
  def execute(self, tool_name: str, arguments: Dict[str, Any]) -> Dict[str, Any]:
@@ -311,7 +312,7 @@ class StreamableMcpClient(McpClient):
311
312
  "stderr": response.get("error", "Unknown error"),
312
313
  }
313
314
  except Exception as e:
314
- PrettyOutput.print(f"执行工具失败: {str(e)}", OutputType.ERROR)
315
+ print(f"执行工具失败: {str(e)}")
315
316
  return {"success": False, "stdout": "", "stderr": str(e)}
316
317
 
317
318
  def get_resource_list(self) -> List[Dict[str, Any]]:
@@ -334,10 +335,10 @@ class StreamableMcpClient(McpClient):
334
335
  error_msg += f": {response['error']}"
335
336
  else:
336
337
  error_msg += ": 未知错误"
337
- PrettyOutput.print(error_msg, OutputType.ERROR)
338
+ print(f"❌ {error_msg}")
338
339
  return []
339
340
  except Exception as e:
340
- PrettyOutput.print(f"获取资源列表失败: {str(e)}", OutputType.ERROR)
341
+ print(f"获取资源列表失败: {str(e)}")
341
342
  return []
342
343
 
343
344
  def get_resource(self, uri: str) -> Dict[str, Any]:
@@ -378,11 +379,11 @@ class StreamableMcpClient(McpClient):
378
379
  error_msg += f": {response['error']}"
379
380
  else:
380
381
  error_msg += ": 未知错误"
381
- PrettyOutput.print(error_msg, OutputType.ERROR)
382
+ print(f"❌ {error_msg}")
382
383
  return {"success": False, "stdout": "", "stderr": error_msg}
383
384
  except Exception as e:
384
385
  error_msg = f"获取资源内容失败: {str(e)}"
385
- PrettyOutput.print(error_msg, OutputType.ERROR)
386
+ print(f"❌ {error_msg}")
386
387
  return {"success": False, "stdout": "", "stderr": error_msg}
387
388
 
388
389
  def __del__(self):