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
@@ -2,7 +2,11 @@
2
2
  import os
3
3
  import sys
4
4
  import time
5
- from typing import Any, Dict, TYPE_CHECKING
5
+ from typing import TYPE_CHECKING
6
+ from typing import Any
7
+ from typing import Dict
8
+
9
+ from jarvis.jarvis_utils.output import PrettyOutput
6
10
 
7
11
  # 为了类型检查,总是导入这些模块
8
12
  if TYPE_CHECKING:
@@ -112,7 +116,7 @@ class VirtualTTYTool:
112
116
  try:
113
117
  if action == "launch":
114
118
  if args.get("keys", "") != "":
115
- print("❌ 启动虚拟终端时,不能同时指定 keys 参数")
119
+ PrettyOutput.auto_print("❌ 启动虚拟终端时,不能同时指定 keys 参数")
116
120
  return {
117
121
  "success": False,
118
122
  "stdout": "",
@@ -121,7 +125,7 @@ class VirtualTTYTool:
121
125
 
122
126
  result = self._launch_tty(agent, tty_id)
123
127
  if not result["success"]:
124
- print(f"❌ 启动虚拟终端 [{tty_id}] 失败")
128
+ PrettyOutput.auto_print(f"❌ 启动虚拟终端 [{tty_id}] 失败")
125
129
  return result
126
130
  elif action == "send_keys":
127
131
  keys = args.get("keys", "").strip()
@@ -130,32 +134,29 @@ class VirtualTTYTool:
130
134
 
131
135
  result = self._input_command(agent, tty_id, keys, timeout, add_enter)
132
136
  if not result["success"]:
133
- print(f"❌ 发送按键序列到终端 [{tty_id}] 失败")
137
+ PrettyOutput.auto_print(f"❌ 发送按键序列到终端 [{tty_id}] 失败")
134
138
  return result
135
139
  elif action == "output":
136
140
  timeout = args.get("timeout", 5.0) # 默认5秒超时
137
141
 
138
142
  result = self._get_output(agent, tty_id, timeout)
139
143
  if not result["success"]:
140
- print(f"❌ 获取终端 [{tty_id}] 输出失败")
144
+ PrettyOutput.auto_print(f"❌ 获取终端 [{tty_id}] 输出失败")
141
145
  return result
142
146
  elif action == "close":
143
-
144
147
  result = self._close_tty(agent, tty_id)
145
148
  if not result["success"]:
146
- print(f"❌ 关闭虚拟终端 [{tty_id}] 失败")
149
+ PrettyOutput.auto_print(f"❌ 关闭虚拟终端 [{tty_id}] 失败")
147
150
  return result
148
151
  elif action == "get_screen":
149
-
150
152
  result = self._get_screen(agent, tty_id)
151
153
  if not result["success"]:
152
- print(f"❌ 获取终端 [{tty_id}] 屏幕内容失败")
154
+ PrettyOutput.auto_print(f"❌ 获取终端 [{tty_id}] 屏幕内容失败")
153
155
  return result
154
156
  elif action == "list":
155
-
156
157
  result = self._list_ttys(agent)
157
158
  if not result["success"]:
158
- print("❌ 获取虚拟终端列表失败")
159
+ PrettyOutput.auto_print("❌ 获取虚拟终端列表失败")
159
160
  return result
160
161
  return {"success": False, "stdout": "", "stderr": "不支持的操作"}
161
162
 
@@ -181,8 +182,8 @@ class VirtualTTYTool:
181
182
  self._close_tty(agent, tty_id)
182
183
 
183
184
  # 在Unix平台上导入需要的模块
184
- import pty as _pty # pylint: disable=import-outside-toplevel
185
185
  import fcntl as _fcntl # pylint: disable=import-outside-toplevel
186
+ import pty as _pty # pylint: disable=import-outside-toplevel
186
187
  import select as _select # pylint: disable=import-outside-toplevel
187
188
 
188
189
  # 创建伪终端
@@ -216,7 +217,9 @@ class VirtualTTYTool:
216
217
  continue
217
218
 
218
219
  if output:
219
- print(f"📥 启动终端时的初始输出 [{tty_id}]:\n{output}")
220
+ PrettyOutput.auto_print(
221
+ f"📥 启动终端时的初始输出 [{tty_id}]:\n{output}"
222
+ )
220
223
  return {"success": True, "stdout": output, "stderr": ""}
221
224
 
222
225
  except Exception as e:
@@ -234,9 +237,9 @@ class VirtualTTYTool:
234
237
  self._close_tty(agent, tty_id)
235
238
 
236
239
  # 在Windows平台上导入需要的模块
240
+ import queue as _queue # pylint: disable=import-outside-toplevel
237
241
  import subprocess as _subprocess # pylint: disable=import-outside-toplevel
238
242
  import threading as _threading # pylint: disable=import-outside-toplevel
239
- import queue as _queue # pylint: disable=import-outside-toplevel
240
243
 
241
244
  # 创建子进程
242
245
  process = _subprocess.Popen(
@@ -283,7 +286,9 @@ class VirtualTTYTool:
283
286
  continue
284
287
 
285
288
  if output:
286
- print(f"📥 启动终端时的初始输出 [{tty_id}]:\n{output}")
289
+ PrettyOutput.auto_print(
290
+ f"📥 启动终端时的初始输出 [{tty_id}]:\n{output}"
291
+ )
287
292
  return {"success": True, "stdout": output, "stderr": ""}
288
293
 
289
294
  except Exception as e:
@@ -361,7 +366,9 @@ class VirtualTTYTool:
361
366
  except BlockingIOError:
362
367
  continue
363
368
  if output:
364
- print(f"📥 命令执行后的输出内容 [{tty_id}]:\n{output}")
369
+ PrettyOutput.auto_print(
370
+ f"📥 命令执行后的输出内容 [{tty_id}]:\n{output}"
371
+ )
365
372
  return {"success": True, "stdout": output, "stderr": ""}
366
373
 
367
374
  except Exception as e:
@@ -411,7 +418,9 @@ class VirtualTTYTool:
411
418
  continue
412
419
 
413
420
  if output:
414
- print(f"📥 命令执行后的输出内容 [{tty_id}]:\n{output}")
421
+ PrettyOutput.auto_print(
422
+ f"📥 命令执行后的输出内容 [{tty_id}]:\n{output}"
423
+ )
415
424
  return {"success": True, "stdout": output, "stderr": ""}
416
425
 
417
426
  except Exception as e:
@@ -465,7 +474,7 @@ class VirtualTTYTool:
465
474
  except BlockingIOError:
466
475
  break
467
476
  if output:
468
- print(f"📥 获取到的输出内容 [{tty_id}]:\n{output}")
477
+ PrettyOutput.auto_print(f"📥 获取到的输出内容 [{tty_id}]:\n{output}")
469
478
  return {"success": True, "stdout": output, "stderr": ""}
470
479
 
471
480
  except Exception as e:
@@ -498,7 +507,7 @@ class VirtualTTYTool:
498
507
  continue
499
508
 
500
509
  if output:
501
- print(f"📥 获取到的输出内容 [{tty_id}]:\n{output}")
510
+ PrettyOutput.auto_print(f"📥 获取到的输出内容 [{tty_id}]:\n{output}")
502
511
  return {"success": True, "stdout": output, "stderr": ""}
503
512
 
504
513
  except Exception as e:
@@ -568,6 +577,7 @@ class VirtualTTYTool:
568
577
  # 终止进程
569
578
  try:
570
579
  import subprocess as _subprocess # pylint: disable=import-outside-toplevel
580
+
571
581
  process.terminate()
572
582
  process.wait(timeout=2)
573
583
  except _subprocess.TimeoutExpired:
@@ -5,6 +5,7 @@ Jarvis工具模块
5
5
  包含多种辅助函数、配置管理和常见操作。
6
6
  该模块组织为以下几个子模块:
7
7
  - config: 配置管理
8
+ - dialogue_recorder: 对话记录器
8
9
  - embedding: 文本嵌入工具
9
10
  - git_utils: Git仓库操作
10
11
  - input: 用户输入处理
@@ -12,6 +13,7 @@ Jarvis工具模块
12
13
  - output: 输出格式化
13
14
  - utils: 通用工具
14
15
  """
16
+
15
17
  import os
16
18
 
17
19
  import colorama
@@ -19,6 +21,8 @@ from rich.traceback import install as install_rich_traceback
19
21
 
20
22
  # 从新模块重新导出
21
23
  # 这些导入是项目功能所必需的,可能会被动态使用
24
+ from .dialogue_recorder import DialogueRecorder as DialogueRecorder
25
+
22
26
  # 初始化colorama以支持跨平台的彩色文本
23
27
  colorama.init()
24
28
  # 禁用tokenizers并行以避免多进程问题
@@ -5,7 +5,8 @@
5
5
  格式: {"标记名": {"template": "替换模板", "description": "描述信息"}}
6
6
  """
7
7
 
8
- from jarvis.jarvis_utils.tag import ct, ot
8
+ from jarvis.jarvis_utils.tag import ct
9
+ from jarvis.jarvis_utils.tag import ot
9
10
 
10
11
  BUILTIN_REPLACE_MAP = {
11
12
  "Web": {
@@ -2,6 +2,7 @@
2
2
  import platform
3
3
  import subprocess
4
4
 
5
+ from jarvis.jarvis_utils.output import PrettyOutput
5
6
 
6
7
 
7
8
  def copy_to_clipboard(text: str) -> None:
@@ -10,9 +11,9 @@ def copy_to_clipboard(text: str) -> None:
10
11
  参数:
11
12
  text: 要复制的文本
12
13
  """
13
- print("ℹ️ --- 剪贴板内容开始 ---")
14
- print(text)
15
- print("ℹ️ --- 剪贴板内容结束 ---")
14
+ PrettyOutput.auto_print("ℹ️ --- 剪贴板内容开始 ---")
15
+ PrettyOutput.auto_print(text)
16
+ PrettyOutput.auto_print("ℹ️ --- 剪贴板内容结束 ---")
16
17
 
17
18
  system = platform.system()
18
19
 
@@ -32,7 +33,7 @@ def copy_to_clipboard(text: str) -> None:
32
33
  process.stdin.close()
33
34
  return
34
35
  except Exception as e:
35
- print(f"⚠️ 使用Windows clip命令时出错: {e}")
36
+ PrettyOutput.auto_print(f"⚠️ 使用Windows clip命令时出错: {e}")
36
37
 
37
38
  # macOS系统
38
39
  elif system == "Darwin":
@@ -48,7 +49,7 @@ def copy_to_clipboard(text: str) -> None:
48
49
  process.stdin.close()
49
50
  return
50
51
  except Exception as e:
51
- print(f"⚠️ 使用macOS pbcopy命令时出错: {e}")
52
+ PrettyOutput.auto_print(f"⚠️ 使用macOS pbcopy命令时出错: {e}")
52
53
 
53
54
  # Linux系统
54
55
  else:
@@ -67,7 +68,7 @@ def copy_to_clipboard(text: str) -> None:
67
68
  except FileNotFoundError:
68
69
  pass # xsel 未安装,继续尝试下一个
69
70
  except Exception as e:
70
- print(f"⚠️ 使用xsel时出错: {e}")
71
+ PrettyOutput.auto_print(f"⚠️ 使用xsel时出错: {e}")
71
72
 
72
73
  # 尝试使用 xclip
73
74
  try:
@@ -82,6 +83,6 @@ def copy_to_clipboard(text: str) -> None:
82
83
  process.stdin.close()
83
84
  return
84
85
  except FileNotFoundError:
85
- print("⚠️ xsel 和 xclip 均未安装, 无法复制到剪贴板")
86
+ PrettyOutput.auto_print("⚠️ xsel 和 xclip 均未安装, 无法复制到剪贴板")
86
87
  except Exception as e:
87
- print(f"⚠️ 使用xclip时出错: {e}")
88
+ PrettyOutput.auto_print(f"⚠️ 使用xclip时出错: {e}")
@@ -0,0 +1,331 @@
1
+ """
2
+ 大小写不敏感的字典和其他集合工具类。
3
+
4
+ 这个模块提供了大小写不敏感的字典实现,用于处理配置键的访问,
5
+ 确保无论在何种大小写形式下都能正确访问相同的键值。
6
+ """
7
+
8
+ from typing import Any
9
+ from typing import Dict
10
+ from typing import Iterator
11
+ from typing import Mapping
12
+ from typing import Optional
13
+ from typing import Tuple
14
+ from typing import Union
15
+
16
+
17
+ class CaseInsensitiveDict(Mapping[str, Any]):
18
+ """
19
+ 大小写不敏感的字典类。
20
+
21
+ 这个字典类允许使用任意大小写形式的键来访问相同的值。
22
+ 内部使用小写形式存储键,但保留了原始的键名用于迭代和显示。
23
+
24
+ 示例:
25
+ >>> d = CaseInsensitiveDict({'Content-Type': 'text/plain'})
26
+ >>> d['content-type']
27
+ 'text/plain'
28
+ >>> d['CONTENT-TYPE']
29
+ 'text/plain'
30
+ >>> d['Content-Type']
31
+ 'text/plain'
32
+ >>> list(d.keys())
33
+ ['Content-Type']
34
+ """
35
+
36
+ def __init__(
37
+ self, data: Optional[Union[Dict[str, Any], "CaseInsensitiveDict"]] = None
38
+ ) -> None:
39
+ """
40
+ 初始化CaseInsensitiveDict。
41
+
42
+ Args:
43
+ data: 可选的初始数据,可以是字典或另一个CaseInsensitiveDict
44
+ """
45
+ self._data: Dict[str, Any] = {}
46
+ self._case_map: Dict[str, str] = {} # 小写键 -> 原始键的映射
47
+
48
+ if data is not None:
49
+ if isinstance(data, CaseInsensitiveDict):
50
+ # 从另一个CaseInsensitiveDict复制
51
+ self._data = data._data.copy()
52
+ self._case_map = data._case_map.copy()
53
+ elif hasattr(data, "items"):
54
+ # 从普通字典或其他映射类型初始化
55
+ for key, value in data.items():
56
+ self[key] = value
57
+
58
+ def __getitem__(self, key: str) -> Any:
59
+ """
60
+ 通过键获取值,大小写不敏感。
61
+
62
+ Args:
63
+ key: 要查找的键
64
+
65
+ Returns:
66
+ 对应的值
67
+
68
+ Raises:
69
+ KeyError: 如果键不存在
70
+ """
71
+ if not isinstance(key, str):
72
+ raise TypeError(f"键必须是字符串类型,得到 {type(key).__name__}")
73
+
74
+ lower_key = key.lower()
75
+ if lower_key not in self._case_map:
76
+ raise KeyError(key)
77
+
78
+ return self._data[lower_key]
79
+
80
+ def __setitem__(self, key: str, value: Any) -> None:
81
+ """
82
+ 设置键值对,大小写不敏感。
83
+
84
+ Args:
85
+ key: 要设置的键
86
+ value: 要设置的值
87
+ """
88
+ if not isinstance(key, str):
89
+ raise TypeError(f"键必须是字符串类型,得到 {type(key).__name__}")
90
+
91
+ lower_key = key.lower()
92
+ # 如果键已存在,保持原有的原始键名;否则使用新的键名
93
+ if lower_key not in self._case_map:
94
+ self._case_map[lower_key] = key # 保留原始键名
95
+ self._data[lower_key] = value
96
+
97
+ def __delitem__(self, key: str) -> None:
98
+ """
99
+ 删除键值对,大小写不敏感。
100
+
101
+ Args:
102
+ key: 要删除的键
103
+
104
+ Raises:
105
+ KeyError: 如果键不存在
106
+ """
107
+ if not isinstance(key, str):
108
+ raise TypeError(f"键必须是字符串类型,得到 {type(key).__name__}")
109
+
110
+ lower_key = key.lower()
111
+ if lower_key not in self._case_map:
112
+ raise KeyError(key)
113
+
114
+ del self._case_map[lower_key]
115
+ del self._data[lower_key]
116
+
117
+ def __contains__(self, key: object) -> bool:
118
+ """
119
+ 检查键是否存在,大小写不敏感。
120
+
121
+ Args:
122
+ key: 要检查的键
123
+
124
+ Returns:
125
+ 如果键存在返回True,否则返回False
126
+ """
127
+ if not isinstance(key, str):
128
+ return False
129
+ return key.lower() in self._case_map
130
+
131
+ def __iter__(self) -> Iterator[str]:
132
+ """
133
+ 返回键的迭代器,保持原始大小写。
134
+
135
+ Returns:
136
+ 键的迭代器
137
+ """
138
+ return iter(self._case_map.values())
139
+
140
+ def __len__(self) -> int:
141
+ """
142
+ 返回字典中的键值对数量。
143
+
144
+ Returns:
145
+ 键值对的数量
146
+ """
147
+ return len(self._data)
148
+
149
+ def __repr__(self) -> str:
150
+ """
151
+ 返回字典的字符串表示。
152
+
153
+ Returns:
154
+ 字符串表示
155
+ """
156
+ items = []
157
+ for original_key in self._case_map.values():
158
+ value = self._data[original_key.lower()]
159
+ items.append(f"{original_key!r}: {value!r}")
160
+ return f"CaseInsensitiveDict({{{', '.join(items)}}})"
161
+
162
+ def __eq__(self, other: object) -> bool:
163
+ """
164
+ 比较两个字典是否相等。
165
+
166
+ Args:
167
+ other: 要比较的对象
168
+
169
+ Returns:
170
+ 如果相等返回True,否则返回False
171
+ """
172
+ if not isinstance(other, CaseInsensitiveDict):
173
+ return NotImplemented
174
+ return self._data == other._data
175
+
176
+ def copy(self) -> "CaseInsensitiveDict":
177
+ """
178
+ 创建字典的浅拷贝。
179
+
180
+ Returns:
181
+ 新的CaseInsensitiveDict实例
182
+ """
183
+ return CaseInsensitiveDict(self)
184
+
185
+ def get(self, key: str, default: Any = None) -> Any:
186
+ """
187
+ 获取键对应的值,如果键不存在返回默认值。
188
+
189
+ Args:
190
+ key: 要查找的键
191
+ default: 如果键不存在时返回的默认值
192
+
193
+ Returns:
194
+ 键对应的值或默认值
195
+ """
196
+ try:
197
+ return self[key]
198
+ except KeyError:
199
+ return default
200
+
201
+ def keys(self):
202
+ """
203
+ 返回所有键的视图,保持原始大小写。
204
+
205
+ Returns:
206
+ 键的视图对象
207
+ """
208
+ from collections.abc import KeysView
209
+
210
+ return KeysView(self)
211
+
212
+ def values(self):
213
+ """
214
+ 返回所有值的视图。
215
+
216
+ Returns:
217
+ 值的视图对象
218
+ """
219
+ from collections.abc import ValuesView
220
+
221
+ return ValuesView(self)
222
+
223
+ def items(self):
224
+ """
225
+ 返回所有键值对的视图,键保持原始大小写。
226
+
227
+ Returns:
228
+ 键值对的视图对象
229
+ """
230
+ from collections.abc import ItemsView
231
+
232
+ return ItemsView(self)
233
+
234
+ def pop(self, key: str, *args: Any) -> Any:
235
+ """
236
+ 移除并返回指定键的值。
237
+
238
+ Args:
239
+ key: 要移除的键
240
+ *args: 如果键不存在时的默认值(可选)
241
+
242
+ Returns:
243
+ 键对应的值
244
+
245
+ Raises:
246
+ KeyError: 如果键不存在且没有提供默认值
247
+ """
248
+ if not isinstance(key, str):
249
+ raise TypeError(f"键必须是字符串类型,得到 {type(key).__name__}")
250
+
251
+ lower_key = key.lower()
252
+ if lower_key not in self._case_map:
253
+ if args:
254
+ return args[0]
255
+ raise KeyError(key)
256
+
257
+ self._case_map.pop(lower_key)
258
+ value = self._data.pop(lower_key)
259
+ return value
260
+
261
+ def popitem(self) -> Tuple[str, Any]:
262
+ """
263
+ 移除并返回最后一个键值对。
264
+
265
+ Returns:
266
+ 键值对
267
+
268
+ Raises:
269
+ KeyError: 如果字典为空
270
+ """
271
+ if not self._data:
272
+ raise KeyError("字典为空")
273
+
274
+ lower_key, value = self._data.popitem()
275
+ original_key = self._case_map.pop(lower_key)
276
+ return original_key, value
277
+
278
+ def setdefault(self, key: str, default: Any = None) -> Any:
279
+ """
280
+ 如果键存在返回对应的值,否则设置键的值为默认值并返回默认值。
281
+
282
+ Args:
283
+ key: 要查找的键
284
+ default: 默认值
285
+
286
+ Returns:
287
+ 键对应的值或默认值
288
+ """
289
+ try:
290
+ return self[key]
291
+ except KeyError:
292
+ self[key] = default
293
+ return default
294
+
295
+ def update(self, *args: Any, **kwargs: Any) -> None:
296
+ """
297
+ 更新字典。
298
+
299
+ Args:
300
+ *args: 可以是另一个字典或键值对的可迭代对象
301
+ **kwargs: 关键字参数形式的键值对(下划线会被转换为连字符)
302
+ """
303
+ if args:
304
+ other = args[0]
305
+ if hasattr(other, "items"):
306
+ for key, value in other.items():
307
+ self[key] = value
308
+ else:
309
+ for key, value in other:
310
+ self[key] = value
311
+
312
+ for key, value in kwargs.items():
313
+ # 将关键字参数中的下划线转换为连字符(用于HTTP头部等场景)
314
+ normalized_key = key.replace("_", "-")
315
+ self[normalized_key] = value
316
+
317
+ def clear(self) -> None:
318
+ """
319
+ 清空字典。
320
+ """
321
+ self._data.clear()
322
+ self._case_map.clear()
323
+
324
+ def lower_keys(self) -> Iterator[str]:
325
+ """
326
+ 返回所有键的小写形式的迭代器。
327
+
328
+ Returns:
329
+ 小写键的迭代器
330
+ """
331
+ return iter(self._case_map.keys())