jarvis-ai-assistant 0.7.8__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.8.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.8.dist-info/RECORD +0 -218
  276. {jarvis_ai_assistant-0.7.8.dist-info → jarvis_ai_assistant-1.0.2.dist-info}/WHEEL +0 -0
  277. {jarvis_ai_assistant-0.7.8.dist-info → jarvis_ai_assistant-1.0.2.dist-info}/entry_points.txt +0 -0
  278. {jarvis_ai_assistant-0.7.8.dist-info → jarvis_ai_assistant-1.0.2.dist-info}/licenses/LICENSE +0 -0
  279. {jarvis_ai_assistant-0.7.8.dist-info → jarvis_ai_assistant-1.0.2.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,3 @@
1
- # -*- coding: utf-8 -*-
2
1
  """
3
2
  方法论导入导出命令行工具
4
3
 
@@ -10,23 +9,25 @@
10
9
 
11
10
  import hashlib
12
11
  import json
12
+
13
+ from jarvis.jarvis_utils.output import PrettyOutput
14
+
15
+ # -*- coding: utf-8 -*-
13
16
  import os
14
17
 
15
18
  import typer
16
- import yaml # type: ignore
19
+ import yaml
17
20
 
18
21
  from jarvis.jarvis_platform.registry import PlatformRegistry
19
- from jarvis.jarvis_utils.methodology import (
20
- _get_methodology_directory,
21
- _load_all_methodologies,
22
- )
22
+ from jarvis.jarvis_utils.methodology import _get_methodology_directory
23
+ from jarvis.jarvis_utils.methodology import _load_all_methodologies
23
24
 
24
25
  app = typer.Typer(help="方法论管理工具")
25
26
 
26
27
 
27
28
  @app.command("import")
28
29
  def import_methodology(
29
- input_file: str = typer.Argument(..., help="要导入的方法论文件路径")
30
+ input_file: str = typer.Argument(..., help="要导入的方法论文件路径"),
30
31
  ):
31
32
  """导入方法论文件(合并策略)"""
32
33
  try:
@@ -54,9 +55,11 @@ def import_methodology(
54
55
  indent=2,
55
56
  )
56
57
 
57
- print(f"✅ 成功导入 {len(import_data)} 个方法论(总计 {len(merged_data)} 个)")
58
+ PrettyOutput.auto_print(
59
+ f"✅ 成功导入 {len(import_data)} 个方法论(总计 {len(merged_data)} 个)"
60
+ )
58
61
  except (ValueError, OSError) as e:
59
- print(f"❌ 导入失败: {str(e)}")
62
+ PrettyOutput.auto_print(f"❌ 导入失败: {str(e)}")
60
63
  raise typer.Exit(code=1)
61
64
 
62
65
 
@@ -69,9 +72,11 @@ def export_methodology(output_file: str = typer.Argument(..., help="导出文件
69
72
  with open(output_file, "w", encoding="utf-8") as f:
70
73
  json.dump(methodologies, f, ensure_ascii=False, indent=2)
71
74
 
72
- print(f"✅ 成功导出 {len(methodologies)} 个方法论到 {output_file}")
75
+ PrettyOutput.auto_print(
76
+ f"✅ 成功导出 {len(methodologies)} 个方法论到 {output_file}"
77
+ )
73
78
  except (OSError, TypeError) as e:
74
- print(f"❌ 导出失败: {str(e)}")
79
+ PrettyOutput.auto_print(f"❌ 导出失败: {str(e)}")
75
80
  raise typer.Exit(code=1)
76
81
 
77
82
 
@@ -82,23 +87,23 @@ def list_methodologies():
82
87
  methodologies = _load_all_methodologies()
83
88
 
84
89
  if not methodologies:
85
- print("ℹ️ 没有找到方法论")
90
+ PrettyOutput.auto_print("ℹ️ 没有找到方法论")
86
91
  return
87
92
 
88
93
  # 先拼接再统一打印,避免在循环中逐条输出造成信息稀疏
89
94
  lines = ["可用方法论:"]
90
95
  for i, (problem_type, _) in enumerate(methodologies.items(), 1):
91
96
  lines.append(f"{i}. {problem_type}")
92
- joined_lines = '\n'.join(lines)
93
- print(f"ℹ️ {joined_lines}")
97
+ joined_lines = "\n".join(lines)
98
+ PrettyOutput.auto_print(f"ℹ️ {joined_lines}")
94
99
  except (OSError, ValueError) as e:
95
- print(f"❌ 列出方法论失败: {str(e)}")
100
+ PrettyOutput.auto_print(f"❌ 列出方法论失败: {str(e)}")
96
101
  raise typer.Exit(code=1)
97
102
 
98
103
 
99
104
  @app.command("extract")
100
105
  def extract_methodology(
101
- input_file: str = typer.Argument(..., help="要提取方法论的文本文件路径")
106
+ input_file: str = typer.Argument(..., help="要提取方法论的文本文件路径"),
102
107
  ):
103
108
  """从文本文件中提取方法论"""
104
109
  try:
@@ -138,20 +143,20 @@ def extract_methodology(
138
143
  """
139
144
 
140
145
  # 调用大模型平台提取方法论
141
- print("ℹ️ 正在提取方法论...")
146
+ PrettyOutput.auto_print("ℹ️ 正在提取方法论...")
142
147
  try:
143
148
  response = platform.chat_until_success(prompt)
144
149
  except Exception as e:
145
- print("❌ 提取失败")
146
- print(f"❌ 提取方法论失败: {str(e)}")
150
+ PrettyOutput.auto_print("❌ 提取失败")
151
+ PrettyOutput.auto_print(f"❌ 提取方法论失败: {str(e)}")
147
152
  raise typer.Exit(code=1)
148
153
 
149
154
  # 提取YAML部分
150
155
  methodologies_start = response.find("<methodologies>") + len("<methodologies>")
151
156
  methodologies_end = response.find("</methodologies>")
152
157
  if methodologies_start == -1 or methodologies_end == -1:
153
- print("❌ 响应格式无效")
154
- print("❌ 大模型未返回有效的<methodologies>格式")
158
+ PrettyOutput.auto_print("❌ 响应格式无效")
159
+ PrettyOutput.auto_print("❌ 大模型未返回有效的<methodologies>格式")
155
160
  raise typer.Exit(code=1)
156
161
 
157
162
  yaml_content = response[methodologies_start:methodologies_end].strip()
@@ -162,14 +167,14 @@ def extract_methodology(
162
167
  item["problem_type"]: item["content"] for item in data
163
168
  }
164
169
  except (yaml.YAMLError, KeyError, TypeError) as e:
165
- print("❌ YAML解析失败")
166
- print(f"❌ YAML解析错误: {str(e)}")
170
+ PrettyOutput.auto_print("❌ YAML解析失败")
171
+ PrettyOutput.auto_print(f"❌ YAML解析错误: {str(e)}")
167
172
  raise typer.Exit(code=1)
168
173
 
169
174
  if not extracted_methodologies:
170
- print("⚠️ 未提取到有效方法论")
175
+ PrettyOutput.auto_print("⚠️ 未提取到有效方法论")
171
176
  return
172
- print("✅ 提取到有效方法论")
177
+ PrettyOutput.auto_print("✅ 提取到有效方法论")
173
178
 
174
179
  # 加载现有方法论
175
180
  existing_methodologies = _load_all_methodologies()
@@ -191,15 +196,17 @@ def extract_methodology(
191
196
  indent=2,
192
197
  )
193
198
 
194
- print(f"✅ 成功从文件提取 {len(extracted_methodologies)} 个方法论(总计 {len(merged_data)} 个)")
199
+ PrettyOutput.auto_print(
200
+ f"✅ 成功从文件提取 {len(extracted_methodologies)} 个方法论(总计 {len(merged_data)} 个)"
201
+ )
195
202
  except Exception as e:
196
- print(f"❌ 提取失败: {str(e)}")
203
+ PrettyOutput.auto_print(f"❌ 提取失败: {str(e)}")
197
204
  raise typer.Exit(code=1)
198
205
 
199
206
 
200
207
  @app.command("extract-url")
201
208
  def extract_methodology_from_url(
202
- url: str = typer.Argument(..., help="要提取方法论的URL")
209
+ url: str = typer.Argument(..., help="要提取方法论的URL"),
203
210
  ):
204
211
  """从URL提取方法论"""
205
212
  try:
@@ -236,20 +243,20 @@ def extract_methodology_from_url(
236
243
  6. 内容字段使用|保留多行格式
237
244
  """
238
245
  # 调用大模型平台提取方法论
239
- print("ℹ️ 正在从URL提取方法论...")
246
+ PrettyOutput.auto_print("ℹ️ 正在从URL提取方法论...")
240
247
  try:
241
248
  response = platform.chat_until_success(prompt)
242
249
  except Exception as e:
243
- print("❌ 提取失败")
244
- print(f"❌ 提取方法论失败: {str(e)}")
250
+ PrettyOutput.auto_print("❌ 提取失败")
251
+ PrettyOutput.auto_print(f"❌ 提取方法论失败: {str(e)}")
245
252
  raise typer.Exit(code=1)
246
253
 
247
254
  # 提取YAML部分
248
255
  methodologies_start = response.find("<methodologies>") + len("<methodologies>")
249
256
  methodologies_end = response.find("</methodologies>")
250
257
  if methodologies_start == -1 or methodologies_end == -1:
251
- print("❌ 响应格式无效")
252
- print("❌ 大模型未返回有效的<methodologies>格式")
258
+ PrettyOutput.auto_print("❌ 响应格式无效")
259
+ PrettyOutput.auto_print("❌ 大模型未返回有效的<methodologies>格式")
253
260
  raise typer.Exit(code=1)
254
261
 
255
262
  yaml_content = response[methodologies_start:methodologies_end].strip()
@@ -260,14 +267,14 @@ def extract_methodology_from_url(
260
267
  item["problem_type"]: item["content"] for item in data
261
268
  }
262
269
  except (yaml.YAMLError, KeyError, TypeError) as e:
263
- print("❌ YAML解析失败")
264
- print(f"❌ YAML解析错误: {str(e)}")
270
+ PrettyOutput.auto_print("❌ YAML解析失败")
271
+ PrettyOutput.auto_print(f"❌ YAML解析错误: {str(e)}")
265
272
  raise typer.Exit(code=1)
266
273
 
267
274
  if not extracted_methodologies:
268
- print("⚠️ 未提取到有效方法论")
275
+ PrettyOutput.auto_print("⚠️ 未提取到有效方法论")
269
276
  return
270
- print("✅ 提取到有效方法论")
277
+ PrettyOutput.auto_print("✅ 提取到有效方法论")
271
278
 
272
279
  # 加载现有方法论
273
280
  existing_methodologies = _load_all_methodologies()
@@ -289,9 +296,11 @@ def extract_methodology_from_url(
289
296
  indent=2,
290
297
  )
291
298
 
292
- print(f"✅ 成功从URL提取 {len(extracted_methodologies)} 个方法论(总计 {len(merged_data)} 个)")
299
+ PrettyOutput.auto_print(
300
+ f"✅ 成功从URL提取 {len(extracted_methodologies)} 个方法论(总计 {len(merged_data)} 个)"
301
+ )
293
302
  except Exception as e:
294
- print(f"❌ 从URL提取失败: {str(e)}")
303
+ PrettyOutput.auto_print(f"❌ 从URL提取失败: {str(e)}")
295
304
  raise typer.Exit(code=1)
296
305
 
297
306
 
@@ -1,22 +1,37 @@
1
- # -*- coding: utf-8 -*-
2
- from jarvis.jarvis_utils.jsonnet_compat import loads as json_loads
3
1
  import re
4
- from typing import Any, Dict, List, Optional, Tuple, Union
2
+ from typing import Any
3
+ from typing import Dict
4
+ from typing import List
5
+ from typing import Optional
6
+ from typing import Tuple
7
+ from typing import Union
5
8
 
6
9
  from jarvis.jarvis_agent import Agent
7
10
  from jarvis.jarvis_agent.output_handler import OutputHandler
8
11
  from jarvis.jarvis_tools.registry import ToolRegistry
9
- from jarvis.jarvis_utils.tag import ct, ot
12
+
13
+ # -*- coding: utf-8 -*-
14
+ from jarvis.jarvis_utils.jsonnet_compat import loads as json_loads
15
+ from jarvis.jarvis_utils.output import PrettyOutput
16
+ from jarvis.jarvis_utils.tag import ct
17
+ from jarvis.jarvis_utils.tag import ot
10
18
 
11
19
 
12
20
  class MultiAgent(OutputHandler):
13
- def __init__(self, agents_config: List[Dict], main_agent_name: str, common_system_prompt: str = ""):
21
+ def __init__(
22
+ self,
23
+ agents_config: List[Dict],
24
+ main_agent_name: str,
25
+ common_system_prompt: str = "",
26
+ non_interactive: Optional[bool] = None,
27
+ ):
14
28
  self.agents_config = agents_config
15
29
  self.agents_config_map = {c["name"]: c for c in agents_config}
16
30
  self.agents: Dict[str, Agent] = {}
17
31
  self.main_agent_name = main_agent_name
18
32
  self.original_question: Optional[str] = None
19
33
  self.common_system_prompt: str = common_system_prompt
34
+ self.non_interactive = non_interactive
20
35
 
21
36
  def prompt(self) -> str:
22
37
  _multiline_example_msg = """ {
@@ -114,7 +129,9 @@ class MultiAgent(OutputHandler):
114
129
  missing = []
115
130
  if not to_val:
116
131
  missing.append("to")
117
- if content_val is None or (isinstance(content_val, str) and content_val.strip() == ""):
132
+ if content_val is None or (
133
+ isinstance(content_val, str) and content_val.strip() == ""
134
+ ):
118
135
  # 允许空格/空行被视为缺失
119
136
  missing.append("content")
120
137
  if missing:
@@ -133,9 +150,15 @@ class MultiAgent(OutputHandler):
133
150
  return False, guidance
134
151
  # 类型校验
135
152
  if not isinstance(to_val, str):
136
- return False, "SEND_MESSAGE 字段类型错误:to 必须为字符串。修复建议:将 to 改为字符串,如 to: ChapterPolisher"
153
+ return (
154
+ False,
155
+ "SEND_MESSAGE 字段类型错误:to 必须为字符串。修复建议:将 to 改为字符串,如 to: ChapterPolisher",
156
+ )
137
157
  if not isinstance(content_val, str):
138
- return False, "SEND_MESSAGE 字段类型错误:content 必须为字符串。修复建议:将 content 改为字符串"
158
+ return (
159
+ False,
160
+ "SEND_MESSAGE 字段类型错误:content 必须为字符串。修复建议:将 content 改为字符串",
161
+ )
139
162
  # 目标校验
140
163
  if to_val not in self.agents_config_map:
141
164
  available = ", ".join(self.agents_config_map.keys())
@@ -145,14 +168,14 @@ class MultiAgent(OutputHandler):
145
168
  f"可用智能体:[{available}]\n"
146
169
  "修复建议:\n"
147
170
  "- 将 to 修改为上述可用智能体之一\n"
148
- "- 或检查配置中是否遗漏了该智能体的定义"
171
+ "- 或检查配置中是否遗漏了该智能体的定义",
149
172
  )
150
173
  # 通过校验,交给上层发送
151
174
  return True, {"to": to_val, "content": content_val}
152
175
  elif len(parsed) > 1:
153
176
  return (
154
177
  False,
155
- "检测到多个 SEND_MESSAGE 块。一次只能发送一个消息。\n修复建议:合并消息或分多轮发送,每轮仅保留一个 SEND_MESSAGE 块。"
178
+ "检测到多个 SEND_MESSAGE 块。一次只能发送一个消息。\n修复建议:合并消息或分多轮发送,每轮仅保留一个 SEND_MESSAGE 块。",
156
179
  )
157
180
  # 未成功解析,进行诊断并返回可操作指导
158
181
  try:
@@ -173,10 +196,11 @@ class MultiAgent(OutputHandler):
173
196
  "to: 目标Agent名称\n"
174
197
  "content: |2\n"
175
198
  " 这里填写要发送的消息内容\n"
176
- f"{ct_tag}"
199
+ f"{ct_tag}",
177
200
  )
178
201
  # 尝试提取原始块并指出 JSON 问题
179
202
  import re as _re
203
+
180
204
  pattern = _re.compile(
181
205
  rf"{_re.escape(ot_tag)}[ \t]*\n(.*?)(?:\n)?[ \t]*{_re.escape(ct_tag)}",
182
206
  _re.DOTALL,
@@ -192,7 +216,7 @@ class MultiAgent(OutputHandler):
192
216
  return (
193
217
  False,
194
218
  "SEND_MESSAGE 格式错误:未能识别完整的消息块。\n"
195
- "修复建议:确保起止标签在单独行上,且中间内容为合法的 JSON,包含 to 与 content 字段。"
219
+ "修复建议:确保起止标签在单独行上,且中间内容为合法的 JSON,包含 to 与 content 字段。",
196
220
  )
197
221
  raw = blocks[0]
198
222
  try:
@@ -205,7 +229,7 @@ class MultiAgent(OutputHandler):
205
229
  "示例:\n"
206
230
  f"{ot('SEND_MESSAGE')}\n"
207
231
  '{{\n "to": "目标Agent名称",\n "content": "这里填写要发送的消息内容"\n}}\n'
208
- f"{ct('SEND_MESSAGE')}"
232
+ f"{ct('SEND_MESSAGE')}",
209
233
  )
210
234
  missing_keys = [k for k in ("to", "content") if k not in msg_obj]
211
235
  if missing_keys:
@@ -216,7 +240,7 @@ class MultiAgent(OutputHandler):
216
240
  "示例:\n"
217
241
  f"{ot('SEND_MESSAGE')}\n"
218
242
  '{{\n "to": "目标Agent名称",\n "content": "这里填写要发送的消息内容"\n}}\n'
219
- f"{ct('SEND_MESSAGE')}"
243
+ f"{ct('SEND_MESSAGE')}",
220
244
  )
221
245
  # 针对值类型的提示(更细)
222
246
  if not isinstance(msg_obj.get("to"), str):
@@ -234,7 +258,7 @@ class MultiAgent(OutputHandler):
234
258
  "示例:\n"
235
259
  f"{ot('SEND_MESSAGE')}\n"
236
260
  '{{\n "to": "目标Agent名称",\n "content": "这里填写要发送的消息内容"\n}}\n'
237
- f"{ct('SEND_MESSAGE')}"
261
+ f"{ct('SEND_MESSAGE')}",
238
262
  )
239
263
  except Exception as e:
240
264
  return (
@@ -251,7 +275,7 @@ class MultiAgent(OutputHandler):
251
275
  "或使用多行字符串(推荐使用 ||| 或 ``` 分隔符):\n"
252
276
  f"{ot('SEND_MESSAGE')}\n"
253
277
  '{{\n "to": "目标Agent名称",\n "content": |||\n多行消息内容\n可以包含换行\n包含"双引号"和\'单引号\'都无需转义\n更清晰易读\n |||\n}}\n'
254
- f"{ct('SEND_MESSAGE')}"
278
+ f"{ct('SEND_MESSAGE')}",
255
279
  )
256
280
 
257
281
  def name(self) -> str:
@@ -314,6 +338,9 @@ class MultiAgent(OutputHandler):
314
338
  # 非主智能体统一禁用自动补全,防止多智能体并行时误触发自动交互
315
339
  if name != self.main_agent_name:
316
340
  config["auto_complete"] = False
341
+ # 继承 MultiAgent 的 non_interactive 设置(如果配置中未显式指定)
342
+ if self.non_interactive is not None and "non_interactive" not in config:
343
+ config["non_interactive"] = self.non_interactive
317
344
 
318
345
  # Prepend common system prompt if configured
319
346
  common_sp = getattr(self, "common_system_prompt", "")
@@ -351,7 +378,7 @@ class MultiAgent(OutputHandler):
351
378
 
352
379
  if not isinstance(msg, Dict):
353
380
  # Should not happen if agent.run() returns str or Dict
354
- print(f"⚠️ 未知消息类型: {type(msg)}")
381
+ PrettyOutput.auto_print(f"⚠️ 未知消息类型: {type(msg)}")
355
382
  break
356
383
 
357
384
  # Generate a brief summary via direct model call to avoid run-loop recursion
@@ -373,24 +400,26 @@ class MultiAgent(OutputHandler):
373
400
  - 仅输出纯文本,不包含任何指令或工具调用
374
401
  - 使用简洁的要点式表述
375
402
  """.strip()
376
- summary_any: Any = agent.model.chat_until_success( # type: ignore[attr-defined]
403
+ summary_any: Any = agent.model.chat_until_success(
377
404
  f"{agent.session.prompt}\n{multi_agent_summary_prompt}"
378
405
  )
379
- summary_text = summary_any.strip() if isinstance(summary_any, str) else ""
406
+ summary_text = (
407
+ summary_any.strip() if isinstance(summary_any, str) else ""
408
+ )
380
409
  except Exception:
381
410
  summary_text = ""
382
411
  prompt = f"""
383
412
  Please handle this message:
384
413
  from: {last_agent_name}
385
414
  summary_of_sender_work: {summary_text}
386
- content: {msg['content']}
415
+ content: {msg["content"]}
387
416
  """
388
417
  to_agent_name = msg.get("to")
389
418
  if not to_agent_name:
390
419
  return "消息中未指定 `to` 字段"
391
420
 
392
421
  if to_agent_name not in self.agents_config_map:
393
- print(f"⚠️ 未找到智能体 {to_agent_name},正在重试...")
422
+ PrettyOutput.auto_print(f"⚠️ 未找到智能体 {to_agent_name},正在重试...")
394
423
  agent = self._get_agent(last_agent_name)
395
424
  if not agent:
396
425
  return f"智能体 {last_agent_name} 未找到"
@@ -399,7 +428,9 @@ content: {msg['content']}
399
428
  )
400
429
  continue
401
430
 
402
- print(f"ℹ️ {last_agent_name} 正在向 {to_agent_name} 发送消息...")
431
+ PrettyOutput.auto_print(
432
+ f"ℹ️ {last_agent_name} 正在向 {to_agent_name} 发送消息..."
433
+ )
403
434
 
404
435
  # Keep a reference to the sender before switching to the receiver
405
436
  sender_agent = agent
@@ -412,7 +443,9 @@ content: {msg['content']}
412
443
  sender_config = self.agents_config_map.get(last_agent_name, {})
413
444
  if sender_config.get("clear_after_send_message"):
414
445
  if sender_agent:
415
- print(f"ℹ️ 清除智能体 {last_agent_name} 在发送消息后的历史记录...")
446
+ PrettyOutput.auto_print(
447
+ f"ℹ️ 清除智能体 {last_agent_name} 在发送消息后的历史记录..."
448
+ )
416
449
  sender_agent.clear_history()
417
450
 
418
451
  last_agent_name = agent.name
@@ -2,13 +2,13 @@
2
2
  from typing import Optional
3
3
 
4
4
  import typer
5
- import yaml # type: ignore[import-untyped]
6
- import os
5
+ import yaml
7
6
 
8
7
  from jarvis.jarvis_multi_agent import MultiAgent
8
+ from jarvis.jarvis_utils.config import set_config
9
9
  from jarvis.jarvis_utils.input import get_multiline_input
10
+ from jarvis.jarvis_utils.output import PrettyOutput
10
11
  from jarvis.jarvis_utils.utils import init_env
11
- from jarvis.jarvis_utils.config import set_config
12
12
 
13
13
  app = typer.Typer(help="多智能体系统启动器")
14
14
 
@@ -23,29 +23,25 @@ def cli(
23
23
  None, "-g", "--llm-group", help="使用的模型组,覆盖配置文件中的设置"
24
24
  ),
25
25
  non_interactive: bool = typer.Option(
26
- False, "-n", "--non-interactive", help="启用非交互模式:用户无法与命令交互,脚本执行超时限制为5分钟"
26
+ False,
27
+ "-n",
28
+ "--non-interactive",
29
+ help="启用非交互模式:用户无法与命令交互,脚本执行超时限制为5分钟",
27
30
  ),
28
31
  ):
29
32
  """从YAML配置文件初始化并运行多智能体系统"""
30
- # CLI 标志:非交互模式(不依赖配置文件)
31
- if non_interactive:
32
- try:
33
- os.environ["JARVIS_NON_INTERACTIVE"] = "true"
34
- except Exception:
35
- pass
36
- # 注意:全局配置同步在 init_env 之后执行,避免被覆盖
37
33
  # 非交互模式要求从命令行传入任务
38
34
  if non_interactive and not (user_input and str(user_input).strip()):
39
- print("❌ 非交互模式已启用:必须使用 --input 传入任务内容,因多行输入不可用。")
35
+ PrettyOutput.auto_print(
36
+ "❌ 非交互模式已启用:必须使用 --input 传入任务内容,因多行输入不可用。"
37
+ )
40
38
  raise typer.Exit(code=2)
41
39
  init_env()
42
-
40
+
43
41
  # 在初始化环境后同步 CLI 选项到全局配置,避免被 init_env 覆盖
44
42
  try:
45
- if non_interactive:
46
- set_config("JARVIS_NON_INTERACTIVE", True)
47
43
  if model_group:
48
- set_config("JARVIS_LLM_GROUP", str(model_group))
44
+ set_config("llm_group", str(model_group))
49
45
  except Exception:
50
46
  # 静默忽略同步异常,不影响主流程
51
47
  pass
@@ -65,7 +61,8 @@ def cli(
65
61
  multi_agent = MultiAgent(
66
62
  agents_config,
67
63
  main_agent_name,
68
- common_system_prompt=str(config_data.get("common_system_prompt", "") or "")
64
+ common_system_prompt=str(config_data.get("common_system_prompt", "") or ""),
65
+ non_interactive=non_interactive if non_interactive else None,
69
66
  )
70
67
  final_input = (
71
68
  user_input
@@ -81,7 +78,7 @@ def cli(
81
78
  except typer.Exit:
82
79
  return
83
80
  except (ValueError, RuntimeError, yaml.YAMLError) as e:
84
- print(f"❌ 错误: {str(e)}")
81
+ PrettyOutput.auto_print(f"❌ 错误: {str(e)}")
85
82
  raise typer.Exit(code=1)
86
83
 
87
84