jarvis-ai-assistant 0.7.16__py3-none-any.whl → 1.0.2__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 (279) hide show
  1. jarvis/__init__.py +1 -1
  2. jarvis/jarvis_agent/__init__.py +567 -222
  3. jarvis/jarvis_agent/agent_manager.py +19 -12
  4. jarvis/jarvis_agent/builtin_input_handler.py +79 -11
  5. jarvis/jarvis_agent/config_editor.py +7 -2
  6. jarvis/jarvis_agent/event_bus.py +24 -13
  7. jarvis/jarvis_agent/events.py +19 -1
  8. jarvis/jarvis_agent/file_context_handler.py +67 -64
  9. jarvis/jarvis_agent/file_methodology_manager.py +38 -24
  10. jarvis/jarvis_agent/jarvis.py +186 -114
  11. jarvis/jarvis_agent/language_extractors/__init__.py +8 -1
  12. jarvis/jarvis_agent/language_extractors/c_extractor.py +7 -4
  13. jarvis/jarvis_agent/language_extractors/cpp_extractor.py +9 -4
  14. jarvis/jarvis_agent/language_extractors/go_extractor.py +7 -4
  15. jarvis/jarvis_agent/language_extractors/java_extractor.py +27 -20
  16. jarvis/jarvis_agent/language_extractors/javascript_extractor.py +22 -17
  17. jarvis/jarvis_agent/language_extractors/python_extractor.py +7 -4
  18. jarvis/jarvis_agent/language_extractors/rust_extractor.py +7 -4
  19. jarvis/jarvis_agent/language_extractors/typescript_extractor.py +22 -17
  20. jarvis/jarvis_agent/language_support_info.py +250 -219
  21. jarvis/jarvis_agent/main.py +19 -23
  22. jarvis/jarvis_agent/memory_manager.py +9 -6
  23. jarvis/jarvis_agent/methodology_share_manager.py +21 -15
  24. jarvis/jarvis_agent/output_handler.py +4 -2
  25. jarvis/jarvis_agent/prompt_builder.py +7 -6
  26. jarvis/jarvis_agent/prompt_manager.py +113 -8
  27. jarvis/jarvis_agent/prompts.py +317 -85
  28. jarvis/jarvis_agent/protocols.py +5 -2
  29. jarvis/jarvis_agent/run_loop.py +192 -32
  30. jarvis/jarvis_agent/session_manager.py +7 -3
  31. jarvis/jarvis_agent/share_manager.py +23 -13
  32. jarvis/jarvis_agent/shell_input_handler.py +12 -8
  33. jarvis/jarvis_agent/stdio_redirect.py +25 -26
  34. jarvis/jarvis_agent/task_analyzer.py +29 -23
  35. jarvis/jarvis_agent/task_list.py +869 -0
  36. jarvis/jarvis_agent/task_manager.py +26 -23
  37. jarvis/jarvis_agent/tool_executor.py +6 -5
  38. jarvis/jarvis_agent/tool_share_manager.py +24 -14
  39. jarvis/jarvis_agent/user_interaction.py +3 -3
  40. jarvis/jarvis_agent/utils.py +9 -1
  41. jarvis/jarvis_agent/web_bridge.py +37 -17
  42. jarvis/jarvis_agent/web_output_sink.py +5 -2
  43. jarvis/jarvis_agent/web_server.py +165 -36
  44. jarvis/jarvis_c2rust/__init__.py +1 -1
  45. jarvis/jarvis_c2rust/cli.py +260 -141
  46. jarvis/jarvis_c2rust/collector.py +37 -18
  47. jarvis/jarvis_c2rust/constants.py +60 -0
  48. jarvis/jarvis_c2rust/library_replacer.py +242 -1010
  49. jarvis/jarvis_c2rust/library_replacer_checkpoint.py +133 -0
  50. jarvis/jarvis_c2rust/library_replacer_llm.py +287 -0
  51. jarvis/jarvis_c2rust/library_replacer_loader.py +191 -0
  52. jarvis/jarvis_c2rust/library_replacer_output.py +134 -0
  53. jarvis/jarvis_c2rust/library_replacer_prompts.py +124 -0
  54. jarvis/jarvis_c2rust/library_replacer_utils.py +188 -0
  55. jarvis/jarvis_c2rust/llm_module_agent.py +98 -1044
  56. jarvis/jarvis_c2rust/llm_module_agent_apply.py +170 -0
  57. jarvis/jarvis_c2rust/llm_module_agent_executor.py +288 -0
  58. jarvis/jarvis_c2rust/llm_module_agent_loader.py +170 -0
  59. jarvis/jarvis_c2rust/llm_module_agent_prompts.py +268 -0
  60. jarvis/jarvis_c2rust/llm_module_agent_types.py +57 -0
  61. jarvis/jarvis_c2rust/llm_module_agent_utils.py +150 -0
  62. jarvis/jarvis_c2rust/llm_module_agent_validator.py +119 -0
  63. jarvis/jarvis_c2rust/loaders.py +28 -10
  64. jarvis/jarvis_c2rust/models.py +5 -2
  65. jarvis/jarvis_c2rust/optimizer.py +192 -1974
  66. jarvis/jarvis_c2rust/optimizer_build_fix.py +286 -0
  67. jarvis/jarvis_c2rust/optimizer_clippy.py +766 -0
  68. jarvis/jarvis_c2rust/optimizer_config.py +49 -0
  69. jarvis/jarvis_c2rust/optimizer_docs.py +183 -0
  70. jarvis/jarvis_c2rust/optimizer_options.py +48 -0
  71. jarvis/jarvis_c2rust/optimizer_progress.py +469 -0
  72. jarvis/jarvis_c2rust/optimizer_report.py +52 -0
  73. jarvis/jarvis_c2rust/optimizer_unsafe.py +309 -0
  74. jarvis/jarvis_c2rust/optimizer_utils.py +469 -0
  75. jarvis/jarvis_c2rust/optimizer_visibility.py +185 -0
  76. jarvis/jarvis_c2rust/scanner.py +229 -166
  77. jarvis/jarvis_c2rust/transpiler.py +531 -2732
  78. jarvis/jarvis_c2rust/transpiler_agents.py +503 -0
  79. jarvis/jarvis_c2rust/transpiler_build.py +1294 -0
  80. jarvis/jarvis_c2rust/transpiler_codegen.py +204 -0
  81. jarvis/jarvis_c2rust/transpiler_compile.py +146 -0
  82. jarvis/jarvis_c2rust/transpiler_config.py +178 -0
  83. jarvis/jarvis_c2rust/transpiler_context.py +122 -0
  84. jarvis/jarvis_c2rust/transpiler_executor.py +516 -0
  85. jarvis/jarvis_c2rust/transpiler_generation.py +278 -0
  86. jarvis/jarvis_c2rust/transpiler_git.py +163 -0
  87. jarvis/jarvis_c2rust/transpiler_mod_utils.py +225 -0
  88. jarvis/jarvis_c2rust/transpiler_modules.py +336 -0
  89. jarvis/jarvis_c2rust/transpiler_planning.py +394 -0
  90. jarvis/jarvis_c2rust/transpiler_review.py +1196 -0
  91. jarvis/jarvis_c2rust/transpiler_symbols.py +176 -0
  92. jarvis/jarvis_c2rust/utils.py +269 -79
  93. jarvis/jarvis_code_agent/after_change.py +233 -0
  94. jarvis/jarvis_code_agent/build_validation_config.py +37 -30
  95. jarvis/jarvis_code_agent/builtin_rules.py +68 -0
  96. jarvis/jarvis_code_agent/code_agent.py +976 -1517
  97. jarvis/jarvis_code_agent/code_agent_build.py +227 -0
  98. jarvis/jarvis_code_agent/code_agent_diff.py +246 -0
  99. jarvis/jarvis_code_agent/code_agent_git.py +525 -0
  100. jarvis/jarvis_code_agent/code_agent_impact.py +177 -0
  101. jarvis/jarvis_code_agent/code_agent_lint.py +283 -0
  102. jarvis/jarvis_code_agent/code_agent_llm.py +159 -0
  103. jarvis/jarvis_code_agent/code_agent_postprocess.py +105 -0
  104. jarvis/jarvis_code_agent/code_agent_prompts.py +46 -0
  105. jarvis/jarvis_code_agent/code_agent_rules.py +305 -0
  106. jarvis/jarvis_code_agent/code_analyzer/__init__.py +52 -48
  107. jarvis/jarvis_code_agent/code_analyzer/base_language.py +12 -10
  108. jarvis/jarvis_code_agent/code_analyzer/build_validator/__init__.py +12 -11
  109. jarvis/jarvis_code_agent/code_analyzer/build_validator/base.py +16 -12
  110. jarvis/jarvis_code_agent/code_analyzer/build_validator/cmake.py +26 -17
  111. jarvis/jarvis_code_agent/code_analyzer/build_validator/detector.py +558 -104
  112. jarvis/jarvis_code_agent/code_analyzer/build_validator/fallback.py +27 -16
  113. jarvis/jarvis_code_agent/code_analyzer/build_validator/go.py +22 -18
  114. jarvis/jarvis_code_agent/code_analyzer/build_validator/java_gradle.py +21 -16
  115. jarvis/jarvis_code_agent/code_analyzer/build_validator/java_maven.py +20 -16
  116. jarvis/jarvis_code_agent/code_analyzer/build_validator/makefile.py +27 -16
  117. jarvis/jarvis_code_agent/code_analyzer/build_validator/nodejs.py +47 -23
  118. jarvis/jarvis_code_agent/code_analyzer/build_validator/python.py +71 -37
  119. jarvis/jarvis_code_agent/code_analyzer/build_validator/rust.py +162 -35
  120. jarvis/jarvis_code_agent/code_analyzer/build_validator/validator.py +111 -57
  121. jarvis/jarvis_code_agent/code_analyzer/build_validator.py +18 -12
  122. jarvis/jarvis_code_agent/code_analyzer/context_manager.py +185 -183
  123. jarvis/jarvis_code_agent/code_analyzer/context_recommender.py +2 -1
  124. jarvis/jarvis_code_agent/code_analyzer/dependency_analyzer.py +24 -15
  125. jarvis/jarvis_code_agent/code_analyzer/file_ignore.py +227 -141
  126. jarvis/jarvis_code_agent/code_analyzer/impact_analyzer.py +321 -247
  127. jarvis/jarvis_code_agent/code_analyzer/language_registry.py +37 -29
  128. jarvis/jarvis_code_agent/code_analyzer/language_support.py +21 -13
  129. jarvis/jarvis_code_agent/code_analyzer/languages/__init__.py +15 -9
  130. jarvis/jarvis_code_agent/code_analyzer/languages/c_cpp_language.py +75 -45
  131. jarvis/jarvis_code_agent/code_analyzer/languages/go_language.py +87 -52
  132. jarvis/jarvis_code_agent/code_analyzer/languages/java_language.py +84 -51
  133. jarvis/jarvis_code_agent/code_analyzer/languages/javascript_language.py +94 -64
  134. jarvis/jarvis_code_agent/code_analyzer/languages/python_language.py +109 -71
  135. jarvis/jarvis_code_agent/code_analyzer/languages/rust_language.py +97 -63
  136. jarvis/jarvis_code_agent/code_analyzer/languages/typescript_language.py +103 -69
  137. jarvis/jarvis_code_agent/code_analyzer/llm_context_recommender.py +271 -268
  138. jarvis/jarvis_code_agent/code_analyzer/symbol_extractor.py +76 -64
  139. jarvis/jarvis_code_agent/code_analyzer/tree_sitter_extractor.py +92 -19
  140. jarvis/jarvis_code_agent/diff_visualizer.py +998 -0
  141. jarvis/jarvis_code_agent/lint.py +223 -524
  142. jarvis/jarvis_code_agent/rule_share_manager.py +158 -0
  143. jarvis/jarvis_code_agent/rules/clean_code.md +144 -0
  144. jarvis/jarvis_code_agent/rules/code_review.md +115 -0
  145. jarvis/jarvis_code_agent/rules/documentation.md +165 -0
  146. jarvis/jarvis_code_agent/rules/generate_rules.md +52 -0
  147. jarvis/jarvis_code_agent/rules/performance.md +158 -0
  148. jarvis/jarvis_code_agent/rules/refactoring.md +139 -0
  149. jarvis/jarvis_code_agent/rules/security.md +160 -0
  150. jarvis/jarvis_code_agent/rules/tdd.md +78 -0
  151. jarvis/jarvis_code_agent/test_rules/cpp_test.md +118 -0
  152. jarvis/jarvis_code_agent/test_rules/go_test.md +98 -0
  153. jarvis/jarvis_code_agent/test_rules/java_test.md +99 -0
  154. jarvis/jarvis_code_agent/test_rules/javascript_test.md +113 -0
  155. jarvis/jarvis_code_agent/test_rules/php_test.md +117 -0
  156. jarvis/jarvis_code_agent/test_rules/python_test.md +91 -0
  157. jarvis/jarvis_code_agent/test_rules/ruby_test.md +102 -0
  158. jarvis/jarvis_code_agent/test_rules/rust_test.md +86 -0
  159. jarvis/jarvis_code_agent/utils.py +36 -26
  160. jarvis/jarvis_code_analysis/checklists/loader.py +21 -21
  161. jarvis/jarvis_code_analysis/code_review.py +64 -33
  162. jarvis/jarvis_data/config_schema.json +285 -192
  163. jarvis/jarvis_git_squash/main.py +8 -6
  164. jarvis/jarvis_git_utils/git_commiter.py +53 -76
  165. jarvis/jarvis_mcp/__init__.py +5 -2
  166. jarvis/jarvis_mcp/sse_mcp_client.py +40 -30
  167. jarvis/jarvis_mcp/stdio_mcp_client.py +27 -19
  168. jarvis/jarvis_mcp/streamable_mcp_client.py +35 -26
  169. jarvis/jarvis_memory_organizer/memory_organizer.py +78 -55
  170. jarvis/jarvis_methodology/main.py +48 -39
  171. jarvis/jarvis_multi_agent/__init__.py +56 -23
  172. jarvis/jarvis_multi_agent/main.py +15 -18
  173. jarvis/jarvis_platform/base.py +179 -111
  174. jarvis/jarvis_platform/human.py +27 -16
  175. jarvis/jarvis_platform/kimi.py +52 -45
  176. jarvis/jarvis_platform/openai.py +101 -40
  177. jarvis/jarvis_platform/registry.py +51 -33
  178. jarvis/jarvis_platform/tongyi.py +68 -38
  179. jarvis/jarvis_platform/yuanbao.py +59 -43
  180. jarvis/jarvis_platform_manager/main.py +68 -76
  181. jarvis/jarvis_platform_manager/service.py +24 -14
  182. jarvis/jarvis_rag/README_CONFIG.md +314 -0
  183. jarvis/jarvis_rag/README_DYNAMIC_LOADING.md +311 -0
  184. jarvis/jarvis_rag/README_ONLINE_MODELS.md +230 -0
  185. jarvis/jarvis_rag/__init__.py +57 -4
  186. jarvis/jarvis_rag/cache.py +3 -1
  187. jarvis/jarvis_rag/cli.py +48 -68
  188. jarvis/jarvis_rag/embedding_interface.py +39 -0
  189. jarvis/jarvis_rag/embedding_manager.py +7 -230
  190. jarvis/jarvis_rag/embeddings/__init__.py +41 -0
  191. jarvis/jarvis_rag/embeddings/base.py +114 -0
  192. jarvis/jarvis_rag/embeddings/cohere.py +66 -0
  193. jarvis/jarvis_rag/embeddings/edgefn.py +117 -0
  194. jarvis/jarvis_rag/embeddings/local.py +260 -0
  195. jarvis/jarvis_rag/embeddings/openai.py +62 -0
  196. jarvis/jarvis_rag/embeddings/registry.py +293 -0
  197. jarvis/jarvis_rag/llm_interface.py +8 -6
  198. jarvis/jarvis_rag/query_rewriter.py +8 -9
  199. jarvis/jarvis_rag/rag_pipeline.py +61 -52
  200. jarvis/jarvis_rag/reranker.py +7 -75
  201. jarvis/jarvis_rag/reranker_interface.py +32 -0
  202. jarvis/jarvis_rag/rerankers/__init__.py +41 -0
  203. jarvis/jarvis_rag/rerankers/base.py +109 -0
  204. jarvis/jarvis_rag/rerankers/cohere.py +67 -0
  205. jarvis/jarvis_rag/rerankers/edgefn.py +140 -0
  206. jarvis/jarvis_rag/rerankers/jina.py +79 -0
  207. jarvis/jarvis_rag/rerankers/local.py +89 -0
  208. jarvis/jarvis_rag/rerankers/registry.py +293 -0
  209. jarvis/jarvis_rag/retriever.py +58 -43
  210. jarvis/jarvis_sec/__init__.py +66 -141
  211. jarvis/jarvis_sec/agents.py +21 -17
  212. jarvis/jarvis_sec/analysis.py +80 -33
  213. jarvis/jarvis_sec/checkers/__init__.py +7 -13
  214. jarvis/jarvis_sec/checkers/c_checker.py +356 -164
  215. jarvis/jarvis_sec/checkers/rust_checker.py +47 -29
  216. jarvis/jarvis_sec/cli.py +43 -21
  217. jarvis/jarvis_sec/clustering.py +430 -272
  218. jarvis/jarvis_sec/file_manager.py +99 -55
  219. jarvis/jarvis_sec/parsers.py +9 -6
  220. jarvis/jarvis_sec/prompts.py +4 -3
  221. jarvis/jarvis_sec/report.py +44 -22
  222. jarvis/jarvis_sec/review.py +180 -107
  223. jarvis/jarvis_sec/status.py +50 -41
  224. jarvis/jarvis_sec/types.py +3 -0
  225. jarvis/jarvis_sec/utils.py +160 -83
  226. jarvis/jarvis_sec/verification.py +411 -181
  227. jarvis/jarvis_sec/workflow.py +132 -21
  228. jarvis/jarvis_smart_shell/main.py +28 -41
  229. jarvis/jarvis_stats/cli.py +14 -12
  230. jarvis/jarvis_stats/stats.py +28 -19
  231. jarvis/jarvis_stats/storage.py +14 -8
  232. jarvis/jarvis_stats/visualizer.py +12 -7
  233. jarvis/jarvis_tools/base.py +5 -2
  234. jarvis/jarvis_tools/clear_memory.py +13 -9
  235. jarvis/jarvis_tools/cli/main.py +23 -18
  236. jarvis/jarvis_tools/edit_file.py +572 -873
  237. jarvis/jarvis_tools/execute_script.py +10 -7
  238. jarvis/jarvis_tools/file_analyzer.py +7 -8
  239. jarvis/jarvis_tools/meta_agent.py +287 -0
  240. jarvis/jarvis_tools/methodology.py +5 -3
  241. jarvis/jarvis_tools/read_code.py +305 -1438
  242. jarvis/jarvis_tools/read_symbols.py +50 -17
  243. jarvis/jarvis_tools/read_webpage.py +19 -18
  244. jarvis/jarvis_tools/registry.py +435 -156
  245. jarvis/jarvis_tools/retrieve_memory.py +16 -11
  246. jarvis/jarvis_tools/save_memory.py +8 -6
  247. jarvis/jarvis_tools/search_web.py +31 -31
  248. jarvis/jarvis_tools/sub_agent.py +32 -28
  249. jarvis/jarvis_tools/sub_code_agent.py +44 -60
  250. jarvis/jarvis_tools/task_list_manager.py +1811 -0
  251. jarvis/jarvis_tools/virtual_tty.py +29 -19
  252. jarvis/jarvis_utils/__init__.py +4 -0
  253. jarvis/jarvis_utils/builtin_replace_map.py +2 -1
  254. jarvis/jarvis_utils/clipboard.py +9 -8
  255. jarvis/jarvis_utils/collections.py +331 -0
  256. jarvis/jarvis_utils/config.py +699 -194
  257. jarvis/jarvis_utils/dialogue_recorder.py +294 -0
  258. jarvis/jarvis_utils/embedding.py +6 -3
  259. jarvis/jarvis_utils/file_processors.py +7 -1
  260. jarvis/jarvis_utils/fzf.py +9 -3
  261. jarvis/jarvis_utils/git_utils.py +71 -42
  262. jarvis/jarvis_utils/globals.py +116 -32
  263. jarvis/jarvis_utils/http.py +6 -2
  264. jarvis/jarvis_utils/input.py +318 -83
  265. jarvis/jarvis_utils/jsonnet_compat.py +119 -104
  266. jarvis/jarvis_utils/methodology.py +37 -28
  267. jarvis/jarvis_utils/output.py +201 -44
  268. jarvis/jarvis_utils/utils.py +986 -628
  269. {jarvis_ai_assistant-0.7.16.dist-info → jarvis_ai_assistant-1.0.2.dist-info}/METADATA +49 -33
  270. jarvis_ai_assistant-1.0.2.dist-info/RECORD +304 -0
  271. jarvis/jarvis_code_agent/code_analyzer/structured_code.py +0 -556
  272. jarvis/jarvis_tools/generate_new_tool.py +0 -205
  273. jarvis/jarvis_tools/lsp_client.py +0 -1552
  274. jarvis/jarvis_tools/rewrite_file.py +0 -105
  275. jarvis_ai_assistant-0.7.16.dist-info/RECORD +0 -218
  276. {jarvis_ai_assistant-0.7.16.dist-info → jarvis_ai_assistant-1.0.2.dist-info}/WHEEL +0 -0
  277. {jarvis_ai_assistant-0.7.16.dist-info → jarvis_ai_assistant-1.0.2.dist-info}/entry_points.txt +0 -0
  278. {jarvis_ai_assistant-0.7.16.dist-info → jarvis_ai_assistant-1.0.2.dist-info}/licenses/LICENSE +0 -0
  279. {jarvis_ai_assistant-0.7.16.dist-info → jarvis_ai_assistant-1.0.2.dist-info}/top_level.txt +0 -0
@@ -1,12 +1,17 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  import json
3
3
  import threading
4
- from typing import Any, Callable, Dict, List
4
+ from typing import Any
5
+ from typing import Callable
6
+ from typing import Dict
7
+ from typing import List
8
+ from typing import cast
5
9
  from urllib.parse import urljoin
6
10
 
7
- import requests # type: ignore[import-untyped]
11
+ import requests
8
12
 
9
13
  from jarvis.jarvis_mcp import McpClient
14
+ from jarvis.jarvis_utils.output import PrettyOutput
10
15
 
11
16
 
12
17
  class StreamableMcpClient(McpClient):
@@ -48,12 +53,12 @@ class StreamableMcpClient(McpClient):
48
53
  self.timeout = config.get("timeout", (10, 300))
49
54
 
50
55
  # 请求相关属性
51
- self.pending_requests: Dict[str, threading.Event] = (
52
- {}
53
- ) # 存储等待响应的请求 {id: Event}
54
- self.request_results: Dict[str, Dict[str, Any]] = (
55
- {}
56
- ) # 存储请求结果 {id: result}
56
+ self.pending_requests: Dict[
57
+ str, threading.Event
58
+ ] = {} # 存储等待响应的请求 {id: Event}
59
+ self.request_results: Dict[
60
+ str, Dict[str, Any]
61
+ ] = {} # 存储请求结果 {id: result}
57
62
  self.notification_handlers: Dict[str, List[Callable]] = {}
58
63
  self.event_lock = threading.Lock()
59
64
  self.request_id_counter = 0
@@ -85,7 +90,7 @@ class StreamableMcpClient(McpClient):
85
90
  self._send_notification("notifications/initialized", {})
86
91
 
87
92
  except Exception as e:
88
- print(f"❌ MCP初始化失败: {str(e)}")
93
+ PrettyOutput.auto_print(f"❌ MCP初始化失败: {str(e)}")
89
94
  raise
90
95
 
91
96
  def register_notification_handler(self, method: str, handler: Callable) -> None:
@@ -176,30 +181,34 @@ class StreamableMcpClient(McpClient):
176
181
  notify_method = data.get("method", "")
177
182
  params = data.get("params", {})
178
183
  if notify_method in self.notification_handlers:
179
- for handler in self.notification_handlers[notify_method]:
184
+ for handler in self.notification_handlers[
185
+ notify_method
186
+ ]:
180
187
  try:
181
188
  handler(params)
182
189
  except Exception as e:
183
- error_lines.append(f"处理通知时出错 ({notify_method}): {e}")
190
+ error_lines.append(
191
+ f"处理通知时出错 ({notify_method}): {e}"
192
+ )
184
193
  except Exception:
185
194
  warning_lines.append(f"无法解析响应: {line}")
186
195
  continue
187
196
 
188
197
  if warning_lines:
189
- joined_warnings = '\n'.join(warning_lines)
190
- print(f"⚠️ {joined_warnings}")
198
+ joined_warnings = "\n".join(warning_lines)
199
+ PrettyOutput.auto_print(f"⚠️ {joined_warnings}")
191
200
  if error_lines:
192
- joined_errors = '\n'.join(error_lines)
193
- print(f"❌ {joined_errors}")
201
+ joined_errors = "\n".join(error_lines)
202
+ PrettyOutput.auto_print(f"❌ {joined_errors}")
194
203
  # Ensure response is closed after streaming
195
204
  response.close()
196
205
  if result is None:
197
206
  raise RuntimeError(f"未收到响应: {method}")
198
207
 
199
- return result
208
+ return cast(Dict[str, Any], result)
200
209
 
201
210
  except Exception as e:
202
- print(f"❌ 发送请求失败: {str(e)}")
211
+ PrettyOutput.auto_print(f"❌ 发送请求失败: {str(e)}")
203
212
  raise
204
213
  finally:
205
214
  # 清理请求状态
@@ -227,7 +236,7 @@ class StreamableMcpClient(McpClient):
227
236
  response.close()
228
237
 
229
238
  except Exception as e:
230
- print(f"❌ 发送通知失败: {str(e)}")
239
+ PrettyOutput.auto_print(f"❌ 发送通知失败: {str(e)}")
231
240
  raise
232
241
 
233
242
  def get_tool_list(self) -> List[Dict[str, Any]]:
@@ -270,10 +279,10 @@ class StreamableMcpClient(McpClient):
270
279
  else:
271
280
  error_msg += ": 未知错误"
272
281
 
273
- print(f"❌ {error_msg}")
282
+ PrettyOutput.auto_print(f"❌ {error_msg}")
274
283
  return []
275
284
  except Exception as e:
276
- print(f"❌ 获取工具列表失败: {str(e)}")
285
+ PrettyOutput.auto_print(f"❌ 获取工具列表失败: {str(e)}")
277
286
  return []
278
287
 
279
288
  def execute(self, tool_name: str, arguments: Dict[str, Any]) -> Dict[str, Any]:
@@ -312,7 +321,7 @@ class StreamableMcpClient(McpClient):
312
321
  "stderr": response.get("error", "Unknown error"),
313
322
  }
314
323
  except Exception as e:
315
- print(f"❌ 执行工具失败: {str(e)}")
324
+ PrettyOutput.auto_print(f"❌ 执行工具失败: {str(e)}")
316
325
  return {"success": False, "stdout": "", "stderr": str(e)}
317
326
 
318
327
  def get_resource_list(self) -> List[Dict[str, Any]]:
@@ -328,17 +337,17 @@ class StreamableMcpClient(McpClient):
328
337
  try:
329
338
  response = self._send_request("resources/list", {})
330
339
  if "result" in response and "resources" in response["result"]:
331
- return response["result"]["resources"]
340
+ return cast(List[Dict[str, Any]], response["result"]["resources"])
332
341
  else:
333
342
  error_msg = "获取资源列表失败"
334
343
  if "error" in response:
335
344
  error_msg += f": {response['error']}"
336
345
  else:
337
346
  error_msg += ": 未知错误"
338
- print(f"❌ {error_msg}")
347
+ PrettyOutput.auto_print(f"❌ {error_msg}")
339
348
  return []
340
349
  except Exception as e:
341
- print(f"❌ 获取资源列表失败: {str(e)}")
350
+ PrettyOutput.auto_print(f"❌ 获取资源列表失败: {str(e)}")
342
351
  return []
343
352
 
344
353
  def get_resource(self, uri: str) -> Dict[str, Any]:
@@ -379,11 +388,11 @@ class StreamableMcpClient(McpClient):
379
388
  error_msg += f": {response['error']}"
380
389
  else:
381
390
  error_msg += ": 未知错误"
382
- print(f"❌ {error_msg}")
391
+ PrettyOutput.auto_print(f"❌ {error_msg}")
383
392
  return {"success": False, "stdout": "", "stderr": error_msg}
384
393
  except Exception as e:
385
394
  error_msg = f"获取资源内容失败: {str(e)}"
386
- print(f"❌ {error_msg}")
395
+ PrettyOutput.auto_print(f"❌ {error_msg}")
387
396
  return {"success": False, "stdout": "", "stderr": error_msg}
388
397
 
389
398
  def __del__(self):
@@ -1,5 +1,3 @@
1
- #!/usr/bin/env python3
2
- # -*- coding: utf-8 -*-
3
1
  """
4
2
  记忆整理工具 - 用于合并具有相似标签的记忆
5
3
 
@@ -9,16 +7,23 @@
9
7
  import json
10
8
  from collections import defaultdict
11
9
  from pathlib import Path
12
- from typing import Dict, List, Set, Any, Optional
10
+
11
+ from jarvis.jarvis_utils.output import PrettyOutput
12
+
13
+ #!/usr/bin/env python3
14
+ # -*- coding: utf-8 -*-
15
+ from typing import Any
16
+ from typing import Dict
17
+ from typing import List
18
+ from typing import Optional
19
+ from typing import Set
13
20
 
14
21
  import typer
15
22
 
16
- from jarvis.jarvis_utils.config import (
17
- get_data_dir,
18
- get_normal_platform_name,
19
- get_normal_model_name,
20
- )
21
23
  from jarvis.jarvis_platform.registry import PlatformRegistry
24
+ from jarvis.jarvis_utils.config import get_data_dir
25
+ from jarvis.jarvis_utils.config import get_normal_model_name
26
+ from jarvis.jarvis_utils.config import get_normal_platform_name
22
27
  from jarvis.jarvis_utils.utils import init_env
23
28
 
24
29
 
@@ -74,8 +79,8 @@ class MemoryOrganizer:
74
79
  error_lines.append(f"读取记忆文件 {memory_file} 失败: {str(e)}")
75
80
 
76
81
  if error_lines:
77
- joined_errors = '\n'.join(error_lines)
78
- print(f"⚠️ {joined_errors}")
82
+ joined_errors = "\n".join(error_lines)
83
+ PrettyOutput.auto_print(f"⚠️ {joined_errors}")
79
84
 
80
85
  return memories
81
86
 
@@ -161,11 +166,11 @@ class MemoryOrganizer:
161
166
  prompt = f"""请将以下{len(memories)}个相关记忆合并成一个综合性的记忆。
162
167
 
163
168
  原始记忆(按时间从新到旧排序):
164
- {"="*50}
169
+ {"=" * 50}
165
170
  {memory_contents_str}
166
- {"="*50}
171
+ {"=" * 50}
167
172
 
168
- 原始标签集合:{', '.join(sorted(all_tags))}
173
+ 原始标签集合:{", ".join(sorted(all_tags))}
169
174
 
170
175
  请完成以下任务:
171
176
  1. 分析这些记忆的共同主题和关键信息
@@ -193,14 +198,18 @@ class MemoryOrganizer:
193
198
  """
194
199
 
195
200
  try:
201
+ if self.platform is None:
202
+ raise ValueError("Platform is not initialized")
203
+
196
204
  # 调用大模型 - 收集完整响应
197
205
  response_parts = []
198
- for chunk in self.platform.chat(prompt): # type: ignore
206
+ for chunk in self.platform.chat(prompt):
199
207
  response_parts.append(chunk)
200
208
  response = "".join(response_parts)
201
209
 
202
210
  # 解析响应
203
211
  import re
212
+
204
213
  from jarvis.jarvis_utils.jsonnet_compat import loads as json5_loads
205
214
 
206
215
  # 提取 <merged_memory> 标签内的内容
@@ -226,7 +235,7 @@ class MemoryOrganizer:
226
235
  raise ValueError("无法从模型响应中提取 <merged_memory> 标签内容")
227
236
 
228
237
  except Exception as e:
229
- print(f"⚠️ 调用大模型合并记忆失败: {str(e)}")
238
+ PrettyOutput.auto_print(f"⚠️ 调用大模型合并记忆失败: {str(e)}")
230
239
  # 返回 None 表示合并失败,跳过这组记忆
231
240
  return None
232
241
 
@@ -247,15 +256,17 @@ class MemoryOrganizer:
247
256
  返回:
248
257
  整理结果统计
249
258
  """
250
- print(f"ℹ️ 开始整理{memory_type}类型的记忆,最小重叠标签数: {min_overlap}")
259
+ PrettyOutput.auto_print(
260
+ f"ℹ️ 开始整理{memory_type}类型的记忆,最小重叠标签数: {min_overlap}"
261
+ )
251
262
 
252
263
  # 加载记忆
253
264
  memories = self._load_memories(memory_type)
254
265
  if not memories:
255
- print("ℹ️ 没有找到需要整理的记忆")
266
+ PrettyOutput.auto_print("ℹ️ 没有找到需要整理的记忆")
256
267
  return {"processed": 0, "merged": 0}
257
268
 
258
- print(f"ℹ️ 加载了 {len(memories)} 个记忆")
269
+ PrettyOutput.auto_print(f"ℹ️ 加载了 {len(memories)} 个记忆")
259
270
 
260
271
  # 统计信息
261
272
  stats = {
@@ -288,7 +299,9 @@ class MemoryOrganizer:
288
299
 
289
300
  if overlap_count in overlap_groups:
290
301
  groups = overlap_groups[overlap_count]
291
- print(f"\nℹ️ 发现 {len(groups)} 个具有 {overlap_count} 个重叠标签的记忆组")
302
+ PrettyOutput.auto_print(
303
+ f"\nℹ️ 发现 {len(groups)} 个具有 {overlap_count} 个重叠标签的记忆组"
304
+ )
292
305
 
293
306
  for group in groups:
294
307
  # 将活跃索引转换回原始索引
@@ -306,8 +319,8 @@ class MemoryOrganizer:
306
319
  f" - ID: {mem.get('id', '未知')}, "
307
320
  f"标签: {', '.join(mem.get('tags', []))[:50]}..."
308
321
  )
309
- joined_lines = '\n'.join(lines)
310
- print(f"ℹ️ {joined_lines}")
322
+ joined_lines = "\n".join(lines)
323
+ PrettyOutput.auto_print(f"ℹ️ {joined_lines}")
311
324
 
312
325
  if not dry_run:
313
326
  # 合并记忆
@@ -315,7 +328,7 @@ class MemoryOrganizer:
315
328
 
316
329
  # 如果合并失败,跳过这组
317
330
  if merged_memory is None:
318
- print(" ⚠️ 跳过这组记忆的合并")
331
+ PrettyOutput.auto_print(" ⚠️ 跳过这组记忆的合并")
319
332
  continue
320
333
 
321
334
  # 保存新记忆
@@ -332,14 +345,14 @@ class MemoryOrganizer:
332
345
  # 标记这些记忆已被删除
333
346
  deleted_indices.update(original_indices)
334
347
  else:
335
- print(" ℹ️ [模拟运行] 跳过实际合并")
348
+ PrettyOutput.auto_print(" ℹ️ [模拟运行] 跳过实际合并")
336
349
 
337
350
  # 显示统计信息
338
- print("\n✅ 整理完成!")
339
- print(f"ℹ️ 总记忆数: {stats['total_memories']}")
340
- print(f"ℹ️ 处理的组数: {stats['processed_groups']}")
341
- print(f"ℹ️ 合并的记忆数: {stats['merged_memories']}")
342
- print(f"ℹ️ 创建的新记忆数: {stats['created_memories']}")
351
+ PrettyOutput.auto_print("\n✅ 整理完成!")
352
+ PrettyOutput.auto_print(f"ℹ️ 总记忆数: {stats['total_memories']}")
353
+ PrettyOutput.auto_print(f"ℹ️ 处理的组数: {stats['processed_groups']}")
354
+ PrettyOutput.auto_print(f"ℹ️ 合并的记忆数: {stats['merged_memories']}")
355
+ PrettyOutput.auto_print(f"ℹ️ 创建的新记忆数: {stats['created_memories']}")
343
356
 
344
357
  return stats
345
358
 
@@ -371,7 +384,9 @@ class MemoryOrganizer:
371
384
  with open(new_file, "w", encoding="utf-8") as f:
372
385
  json.dump(memory, f, ensure_ascii=False, indent=2)
373
386
 
374
- print(f"✅ 创建新记忆: {memory['id']} (标签: {', '.join(memory['tags'][:3])}...)")
387
+ PrettyOutput.auto_print(
388
+ f"✅ 创建新记忆: {memory['id']} (标签: {', '.join(memory['tags'][:3])}...)"
389
+ )
375
390
 
376
391
  # 删除原始记忆文件(先汇总日志,最后统一打印)
377
392
  info_lines: List[str] = []
@@ -382,7 +397,9 @@ class MemoryOrganizer:
382
397
  file_path = Path(orig_memory["file_path"])
383
398
  if file_path.exists():
384
399
  file_path.unlink()
385
- info_lines.append(f"删除原始记忆: {orig_memory.get('id', '未知')}")
400
+ info_lines.append(
401
+ f"删除原始记忆: {orig_memory.get('id', '未知')}"
402
+ )
386
403
  else:
387
404
  info_lines.append(
388
405
  f"原始记忆文件已不存在,跳过删除: {orig_memory.get('id', '未知')}"
@@ -392,11 +409,11 @@ class MemoryOrganizer:
392
409
  f"删除记忆文件失败 {orig_memory.get('file_path', '')}: {str(e)}"
393
410
  )
394
411
  if info_lines:
395
- joined_info = '\n'.join(info_lines)
396
- print(f"ℹ️ {joined_info}")
412
+ joined_info = "\n".join(info_lines)
413
+ PrettyOutput.auto_print(f"ℹ️ {joined_info}")
397
414
  if warn_lines:
398
- joined_warn = '\n'.join(warn_lines)
399
- print(f"⚠️ {joined_warn}")
415
+ joined_warn = "\n".join(warn_lines)
416
+ PrettyOutput.auto_print(f"⚠️ {joined_warn}")
400
417
 
401
418
  def export_memories(
402
419
  self,
@@ -441,15 +458,17 @@ class MemoryOrganizer:
441
458
 
442
459
  # 统一展示导出进度日志
443
460
  if progress_lines:
444
- joined_progress = '\n'.join(progress_lines)
445
- print(f"ℹ️ {joined_progress}")
461
+ joined_progress = "\n".join(progress_lines)
462
+ PrettyOutput.auto_print(f"ℹ️ {joined_progress}")
446
463
 
447
464
  # 保存到文件
448
465
  output_file.parent.mkdir(parents=True, exist_ok=True)
449
466
  with open(output_file, "w", encoding="utf-8") as f:
450
467
  json.dump(all_memories, f, ensure_ascii=False, indent=2)
451
468
 
452
- print(f"✅ 成功导出 {len(all_memories)} 个记忆到 {output_file}")
469
+ PrettyOutput.auto_print(
470
+ f"✅ 成功导出 {len(all_memories)} 个记忆到 {output_file}"
471
+ )
453
472
 
454
473
  return len(all_memories)
455
474
 
@@ -478,7 +497,7 @@ class MemoryOrganizer:
478
497
  if not isinstance(memories, list):
479
498
  raise ValueError("导入文件格式错误,应为记忆列表")
480
499
 
481
- print(f"ℹ️ 准备导入 {len(memories)} 个记忆")
500
+ PrettyOutput.auto_print(f"ℹ️ 准备导入 {len(memories)} 个记忆")
482
501
 
483
502
  # 统计导入结果
484
503
  import_stats: Dict[str, int] = defaultdict(int)
@@ -496,7 +515,7 @@ class MemoryOrganizer:
496
515
  elif memory_type == "global_long_term":
497
516
  memory_dir = self.global_memory_dir / memory_type
498
517
  else:
499
- print(f"⚠️ 跳过不支持的记忆类型: {memory_type}")
518
+ PrettyOutput.auto_print(f"⚠️ 跳过不支持的记忆类型: {memory_type}")
500
519
  skipped_count += 1
501
520
  continue
502
521
 
@@ -513,7 +532,7 @@ class MemoryOrganizer:
513
532
  memory_file = memory_dir / f"{memory_id}.json"
514
533
 
515
534
  if memory_file.exists() and not overwrite:
516
- print(f"ℹ️ 跳过已存在的记忆: {memory_id}")
535
+ PrettyOutput.auto_print(f"ℹ️ 跳过已存在的记忆: {memory_id}")
517
536
  skipped_count += 1
518
537
  continue
519
538
 
@@ -535,14 +554,17 @@ class MemoryOrganizer:
535
554
  import_stats[memory_type] += 1
536
555
 
537
556
  # 显示导入结果
538
- print("\n✅ 导入完成!")
557
+ PrettyOutput.auto_print("\n✅ 导入完成!")
539
558
  if import_stats:
540
- lines = [f"{memory_type}: 导入了 {count} 个记忆" for memory_type, count in import_stats.items()]
541
- joined_lines = '\n'.join(lines)
542
- print(f"ℹ️ {joined_lines}")
559
+ lines = [
560
+ f"{memory_type}: 导入了 {count} 个记忆"
561
+ for memory_type, count in import_stats.items()
562
+ ]
563
+ joined_lines = "\n".join(lines)
564
+ PrettyOutput.auto_print(f"ℹ️ {joined_lines}")
543
565
 
544
566
  if skipped_count > 0:
545
- print(f"⚠️ 跳过了 {skipped_count} 个记忆")
567
+ PrettyOutput.auto_print(f"⚠️ 跳过了 {skipped_count} 个记忆")
546
568
 
547
569
  return dict(import_stats)
548
570
 
@@ -570,7 +592,6 @@ def organize(
570
592
  llm_group: Optional[str] = typer.Option(
571
593
  None, "-g", "--llm-group", help="使用的模型组,覆盖配置文件中的设置"
572
594
  ),
573
-
574
595
  ):
575
596
  """
576
597
  整理和合并具有相似标签的记忆。
@@ -588,11 +609,13 @@ def organize(
588
609
  """
589
610
  # 验证参数
590
611
  if memory_type not in ["project_long_term", "global_long_term"]:
591
- print(f"❌ 错误:不支持的记忆类型 '{memory_type}',请选择 'project_long_term' 或 'global_long_term'")
612
+ PrettyOutput.auto_print(
613
+ f"❌ 错误:不支持的记忆类型 '{memory_type}',请选择 'project_long_term' 或 'global_long_term'"
614
+ )
592
615
  raise typer.Exit(1)
593
616
 
594
617
  if min_overlap < 2:
595
- print("❌ 错误:最小重叠数必须大于等于2")
618
+ PrettyOutput.auto_print("❌ 错误:最小重叠数必须大于等于2")
596
619
  raise typer.Exit(1)
597
620
 
598
621
  # 创建整理器并执行
@@ -612,7 +635,7 @@ def organize(
612
635
  # typer.Exit 是正常的退出方式,直接传播
613
636
  raise
614
637
  except Exception as e:
615
- print(f"❌ 记忆整理失败: {str(e)}")
638
+ PrettyOutput.auto_print(f"❌ 记忆整理失败: {str(e)}")
616
639
  raise typer.Exit(1)
617
640
 
618
641
 
@@ -656,7 +679,7 @@ def export(
656
679
  invalid_types = [mt for mt in memory_types if mt not in valid_types]
657
680
  if invalid_types:
658
681
  invalid_str = ", ".join(f"'{mt}'" for mt in invalid_types)
659
- print(f"❌ 错误:不支持的记忆类型: {invalid_str}")
682
+ PrettyOutput.auto_print(f"❌ 错误:不支持的记忆类型: {invalid_str}")
660
683
  raise typer.Exit(1)
661
684
 
662
685
  count = organizer.export_memories(
@@ -668,11 +691,11 @@ def export(
668
691
  if count > 0:
669
692
  raise typer.Exit(0)
670
693
  else:
671
- print("⚠️ 没有找到要导出的记忆")
694
+ PrettyOutput.auto_print("⚠️ 没有找到要导出的记忆")
672
695
  raise typer.Exit(0)
673
696
 
674
697
  except Exception as e:
675
- print(f"❌ 导出失败: {str(e)}")
698
+ PrettyOutput.auto_print(f"❌ 导出失败: {str(e)}")
676
699
  raise typer.Exit(1)
677
700
 
678
701
 
@@ -712,14 +735,14 @@ def import_memories(
712
735
  if total_imported > 0:
713
736
  raise typer.Exit(0)
714
737
  else:
715
- print("⚠️ 没有导入任何记忆")
738
+ PrettyOutput.auto_print("⚠️ 没有导入任何记忆")
716
739
  raise typer.Exit(0)
717
740
 
718
741
  except FileNotFoundError as e:
719
- print(f"❌ {str(e)}")
742
+ PrettyOutput.auto_print(f"❌ {str(e)}")
720
743
  raise typer.Exit(1)
721
744
  except Exception as e:
722
- print(f"❌ 导入失败: {str(e)}")
745
+ PrettyOutput.auto_print(f"❌ 导入失败: {str(e)}")
723
746
  raise typer.Exit(1)
724
747
 
725
748