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,11 +1,16 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  import json
3
3
  from pathlib import Path
4
- from typing import Any, Dict, List, Optional
4
+ from typing import Any
5
+ from typing import Dict
6
+ from typing import List
7
+ from typing import Optional
5
8
 
6
- from jarvis.jarvis_utils.config import get_data_dir, get_max_input_token_count
7
- from jarvis.jarvis_utils.globals import get_short_term_memories
9
+ from jarvis.jarvis_utils.config import get_data_dir
10
+ from jarvis.jarvis_utils.config import get_max_input_token_count
8
11
  from jarvis.jarvis_utils.embedding import get_context_token_count
12
+ from jarvis.jarvis_utils.globals import get_short_term_memories
13
+ from jarvis.jarvis_utils.output import PrettyOutput
9
14
 
10
15
 
11
16
  class RetrieveMemoryTool:
@@ -52,9 +57,9 @@ class RetrieveMemoryTool:
52
57
  def _get_memory_dir(self, memory_type: str) -> Path:
53
58
  """根据记忆类型获取存储目录"""
54
59
  if memory_type == "project_long_term":
55
- return self.project_memory_dir
60
+ return Path(self.project_memory_dir)
56
61
  elif memory_type in ["global_long_term", "short_term"]:
57
- return self.global_memory_dir / memory_type
62
+ return Path(self.global_memory_dir) / memory_type
58
63
  else:
59
64
  raise ValueError(f"未知的记忆类型: {memory_type}")
60
65
 
@@ -88,7 +93,9 @@ class RetrieveMemoryTool:
88
93
 
89
94
  memories.append(memory_data)
90
95
  except Exception as e:
91
- print(f"⚠️ 读取记忆文件 {memory_file} 失败: {str(e)}")
96
+ PrettyOutput.auto_print(
97
+ f"⚠️ 读取记忆文件 {memory_file} 失败: {str(e)}"
98
+ )
92
99
 
93
100
  return memories
94
101
 
@@ -130,7 +137,7 @@ class RetrieveMemoryTool:
130
137
  memory_token_limit = None
131
138
  except Exception:
132
139
  pass
133
-
140
+
134
141
  # 回退方案:使用输入窗口的2/3
135
142
  if memory_token_limit is None:
136
143
  max_input_tokens = get_max_input_token_count()
@@ -147,12 +154,10 @@ class RetrieveMemoryTool:
147
154
 
148
155
  # 检查是否超过token限制
149
156
  if total_tokens + memory_tokens > memory_token_limit:
150
-
151
157
  break
152
158
 
153
159
  # 检查是否超过50条限制
154
160
  if len(filtered_memories) >= 50:
155
-
156
161
  break
157
162
 
158
163
  filtered_memories.append(memory)
@@ -182,7 +187,7 @@ class RetrieveMemoryTool:
182
187
 
183
188
  # 输出所有记忆
184
189
  for i, memory in enumerate(all_memories):
185
- markdown_output += f"## {i+1}. {memory.get('id', '未知ID')}\n\n"
190
+ markdown_output += f"## {i + 1}. {memory.get('id', '未知ID')}\n\n"
186
191
  markdown_output += f"**类型**: {memory.get('type', '未知类型')}\n\n"
187
192
  markdown_output += f"**标签**: {', '.join(memory.get('tags', []))}\n\n"
188
193
  markdown_output += (
@@ -224,5 +229,5 @@ class RetrieveMemoryTool:
224
229
 
225
230
  except Exception as e:
226
231
  error_msg = f"检索记忆失败: {str(e)}"
227
- print(f"❌ {error_msg}")
232
+ PrettyOutput.auto_print(f"❌ {error_msg}")
228
233
  return {"success": False, "stdout": "", "stderr": error_msg}
@@ -3,10 +3,12 @@ import json
3
3
  import time
4
4
  from datetime import datetime
5
5
  from pathlib import Path
6
- from typing import Any, Dict
6
+ from typing import Any
7
+ from typing import Dict
7
8
 
8
9
  from jarvis.jarvis_utils.config import get_data_dir
9
10
  from jarvis.jarvis_utils.globals import add_short_term_memory
11
+ from jarvis.jarvis_utils.output import PrettyOutput
10
12
 
11
13
 
12
14
  class SaveMemoryTool:
@@ -58,9 +60,9 @@ class SaveMemoryTool:
58
60
  def _get_memory_dir(self, memory_type: str) -> Path:
59
61
  """根据记忆类型获取存储目录"""
60
62
  if memory_type == "project_long_term":
61
- return self.project_memory_dir
63
+ return Path(self.project_memory_dir)
62
64
  elif memory_type in ["global_long_term", "short_term"]:
63
- return self.global_memory_dir / memory_type
65
+ return Path(self.global_memory_dir) / memory_type
64
66
  else:
65
67
  raise ValueError(f"未知的记忆类型: {memory_type}")
66
68
 
@@ -150,8 +152,8 @@ class SaveMemoryTool:
150
152
 
151
153
  except Exception as e:
152
154
  failed_count += 1
153
- error_msg = f"保存第 {i+1} 条记忆失败: {str(e)}"
154
- print(f"❌ {error_msg}")
155
+ error_msg = f"保存第 {i + 1} 条记忆失败: {str(e)}"
156
+ PrettyOutput.auto_print(f"❌ {error_msg}")
155
157
  results.append(
156
158
  {
157
159
  "error": error_msg,
@@ -178,5 +180,5 @@ class SaveMemoryTool:
178
180
 
179
181
  except Exception as e:
180
182
  error_msg = f"保存记忆失败: {str(e)}"
181
- print(f"❌ {error_msg}")
183
+ PrettyOutput.auto_print(f"❌ {error_msg}")
182
184
  return {"success": False, "stdout": "", "stderr": error_msg}
@@ -1,23 +1,28 @@
1
- # -*- coding: utf-8 -*-
2
1
  """网络搜索工具。"""
3
- from typing import Any, Dict
4
2
 
5
- import requests # type: ignore[import-untyped]
6
- from markdownify import markdownify as md # type: ignore
3
+ from typing import Any
4
+ from typing import Dict
5
+ from jarvis.jarvis_utils.output import PrettyOutput
6
+
7
+ # -*- coding: utf-8 -*-
8
+
9
+ import requests
7
10
 
8
11
  # pylint: disable=import-error,missing-module-docstring
9
12
  # fmt: off
10
- from ddgs import DDGS # type: ignore[import-not-found]
11
- # fmt: on
13
+ from ddgs import DDGS
14
+ from markdownify import markdownify as md
12
15
 
13
16
  from jarvis.jarvis_agent import Agent
14
17
  from jarvis.jarvis_platform.registry import PlatformRegistry
15
- from jarvis.jarvis_utils.config import (
16
- get_web_search_platform_name,
17
- get_web_search_model_name,
18
- )
18
+ from jarvis.jarvis_utils.config import get_normal_model_name
19
+ from jarvis.jarvis_utils.config import get_normal_platform_name
20
+ from jarvis.jarvis_utils.config import get_web_search_model_name
21
+ from jarvis.jarvis_utils.config import get_web_search_platform_name
19
22
  from jarvis.jarvis_utils.http import get as http_get
20
23
 
24
+ # fmt: on
25
+
21
26
 
22
27
  class SearchWebTool:
23
28
  """处理网络搜索的类。"""
@@ -33,7 +38,6 @@ class SearchWebTool:
33
38
  # pylint: disable=too-many-locals, broad-except
34
39
  """执行网络搜索、抓取内容并总结结果。"""
35
40
  try:
36
-
37
41
  results = list(DDGS().text(query, max_results=50, page=3))
38
42
 
39
43
  if not results:
@@ -49,14 +53,12 @@ class SearchWebTool:
49
53
 
50
54
  for r in results:
51
55
  if visited_count >= 10:
52
-
53
56
  break
54
57
 
55
58
  url = r["href"]
56
59
  r.get("title", url)
57
60
 
58
61
  try:
59
-
60
62
  response = http_get(url, timeout=10.0, allow_redirects=True)
61
63
  content = md(response.text, strip=["script", "style"])
62
64
  if content:
@@ -64,9 +66,11 @@ class SearchWebTool:
64
66
  visited_urls.append(url)
65
67
  visited_count += 1
66
68
  except requests.exceptions.HTTPError as e:
67
- print(f"⚠️ HTTP错误 {e.response.status_code} 访问 {url}")
69
+ PrettyOutput.auto_print(
70
+ f"⚠️ HTTP错误 {e.response.status_code} 访问 {url}"
71
+ )
68
72
  except requests.exceptions.RequestException as e:
69
- print(f"⚠️ 请求错误: {e}")
73
+ PrettyOutput.auto_print(f"⚠️ 请求错误: {e}")
70
74
 
71
75
  if not full_content.strip():
72
76
  return {
@@ -79,15 +83,9 @@ class SearchWebTool:
79
83
 
80
84
  summary_prompt = f"请为查询“{query}”总结以下内容:\n\n{full_content}"
81
85
 
82
- if not agent.model:
83
- return {
84
- "stdout": "",
85
- "stderr": "用于总结的Agent模型未找到。",
86
- "success": False,
87
- }
88
-
89
- platform_name = agent.model.platform_name()
90
- model_name = agent.model.name()
86
+ # 使用normal模型进行总结
87
+ platform_name = get_normal_platform_name(None)
88
+ model_name = get_normal_model_name(None)
91
89
 
92
90
  model = PlatformRegistry().create_platform(platform_name)
93
91
  if not model:
@@ -104,7 +102,7 @@ class SearchWebTool:
104
102
  return {"stdout": summary, "stderr": "", "success": True}
105
103
 
106
104
  except Exception as e:
107
- print(f"❌ 网页搜索过程中发生错误: {e}")
105
+ PrettyOutput.auto_print(f"❌ 网页搜索过程中发生错误: {e}")
108
106
  return {
109
107
  "stdout": "",
110
108
  "stderr": f"网页搜索过程中发生错误: {e}",
@@ -151,12 +149,14 @@ class SearchWebTool:
151
149
  "success": True,
152
150
  }
153
151
 
154
- # 否则使用现有的模型选择流程
155
- if agent.model.support_web():
156
- model = PlatformRegistry().create_platform(agent.model.platform_name())
157
- if not model:
158
- return {"stdout": "", "stderr": "无法创建模型。", "success": False}
159
- model.set_model_name(agent.model.name())
152
+ # 否则使用normal模型进行web搜索(正常操作)
153
+ normal_platform = get_normal_platform_name(None)
154
+ normal_model = get_normal_model_name(None)
155
+ model = PlatformRegistry().create_platform(normal_platform)
156
+ if not model:
157
+ return {"stdout": "", "stderr": "无法创建模型。", "success": False}
158
+ model.set_model_name(normal_model)
159
+ if model.support_web():
160
160
  model.set_web(True)
161
161
  model.set_suppress_output(False)
162
162
  response = model.chat_until_success(query)
@@ -1,4 +1,3 @@
1
- # -*- coding: utf-8 -*-
2
1
  """
3
2
  sub_agent 工具
4
3
  将子任务交给通用 Agent 执行,并返回执行结果。
@@ -10,11 +9,17 @@ sub_agent 工具
10
9
  - 继承父 Agent 的部分配置:model_group、input_handler、execute_tool_confirm、multiline_inputer、non_interactive、use_methodology、use_analysis;其他参数需显式提供
11
10
  - 子Agent必须自动完成(auto_complete=True)且需要summary(need_summary=True)
12
11
  """
13
- from typing import Any, Dict
12
+
14
13
  import json
14
+ from typing import Any
15
+
16
+ from jarvis.jarvis_utils.output import PrettyOutput
17
+
18
+ # -*- coding: utf-8 -*-
19
+ from typing import Dict
15
20
 
16
21
  from jarvis.jarvis_agent import Agent
17
- from jarvis.jarvis_utils.globals import delete_agent
22
+ from jarvis.jarvis_utils.globals import get_global_model_group
18
23
 
19
24
 
20
25
  class SubAgentTool:
@@ -89,7 +94,6 @@ class SubAgentTool:
89
94
 
90
95
  # 不继承父Agent,所有关键参数必须由调用方显式提供
91
96
  need_summary = True
92
- auto_complete = True
93
97
 
94
98
  # 读取并校验必填参数
95
99
  system_prompt = str(args.get("system_prompt", "")).strip()
@@ -115,37 +119,35 @@ class SubAgentTool:
115
119
 
116
120
  # 基于父Agent(如有)继承部分配置后创建子Agent
117
121
  parent_agent = args.get("agent", None)
118
- parent_model_group = None
122
+ # 使用全局模型组(不再从 parent_agent 继承)
123
+ parent_model_group = get_global_model_group()
119
124
  parent_execute_tool_confirm = None
120
125
  parent_multiline_inputer = None
121
- parent_non_interactive = None
122
126
  parent_use_methodology = None
123
127
  parent_use_analysis = None
124
128
  try:
125
129
  if parent_agent is not None:
126
- if getattr(parent_agent, "model", None):
127
- parent_model_group = getattr(parent_agent.model, "model_group", None)
128
- parent_execute_tool_confirm = getattr(parent_agent, "execute_tool_confirm", None)
129
- parent_multiline_inputer = getattr(parent_agent, "multiline_inputer", None)
130
- parent_non_interactive = getattr(parent_agent, "non_interactive", None)
131
- parent_use_methodology = getattr(parent_agent, "use_methodology", None)
130
+ parent_execute_tool_confirm = getattr(
131
+ parent_agent, "execute_tool_confirm", None
132
+ )
133
+ parent_multiline_inputer = getattr(
134
+ parent_agent, "multiline_inputer", None
135
+ )
136
+ parent_use_methodology = getattr(
137
+ parent_agent, "use_methodology", None
138
+ )
132
139
  parent_use_analysis = getattr(parent_agent, "use_analysis", None)
133
140
  except Exception:
134
141
  # 安全兜底:无法从父Agent获取配置则保持为None,使用系统默认
135
142
  pass
136
143
 
137
- # 可选参数:允许显式覆盖无交互模式
138
- explicit_non_interactive = args.get("non_interactive", None)
139
- if explicit_non_interactive is not None:
140
- parent_non_interactive = bool(explicit_non_interactive)
141
-
142
144
  agent = Agent(
143
145
  system_prompt=system_prompt,
144
146
  name=agent_name,
145
147
  description="Temporary sub agent for executing a subtask",
146
148
  model_group=parent_model_group,
147
149
  summary_prompt=summary_prompt,
148
- auto_complete=auto_complete,
150
+ auto_complete=True,
149
151
  use_tools=None,
150
152
  execute_tool_confirm=parent_execute_tool_confirm,
151
153
  need_summary=need_summary,
@@ -154,7 +156,7 @@ class SubAgentTool:
154
156
  use_analysis=parent_use_analysis,
155
157
  force_save_memory=None,
156
158
  files=None,
157
- non_interactive=parent_non_interactive,
159
+ non_interactive=True,
158
160
  )
159
161
 
160
162
  # 禁用 sub_agent 和 sub_code_agent,避免无限递归
@@ -162,10 +164,16 @@ class SubAgentTool:
162
164
  # 获取当前启用的工具列表
163
165
  tool_registry = agent.get_tool_registry()
164
166
  if tool_registry:
165
- current_tools = [t.get("name") for t in tool_registry.get_all_tools() if isinstance(t, dict) and t.get("name")]
167
+ current_tools = [
168
+ t.get("name")
169
+ for t in tool_registry.get_all_tools()
170
+ if isinstance(t, dict) and t.get("name")
171
+ ]
166
172
  # 过滤掉禁止的工具
167
173
  forbidden_tools = {"sub_agent", "sub_code_agent"}
168
- filtered_tools = [t for t in current_tools if t not in forbidden_tools]
174
+ filtered_tools = [
175
+ t for t in current_tools if t not in forbidden_tools
176
+ ]
169
177
  if filtered_tools:
170
178
  agent.set_use_tools(filtered_tools)
171
179
  except Exception:
@@ -181,7 +189,9 @@ class SubAgentTool:
181
189
  available_names = [m for m, _ in available_models]
182
190
  current_model_name = platform.name()
183
191
  if current_model_name not in available_names:
184
- print(f"⚠️ 检测到子Agent模型 {current_model_name} 不存在于平台 {platform.platform_name()} 的可用模型列表,将回退到 {available_names[0]}")
192
+ PrettyOutput.auto_print(
193
+ f"⚠️ 检测到子Agent模型 {current_model_name} 不存在于平台 {platform.platform_name()} 的可用模型列表,将回退到 {available_names[0]}"
194
+ )
185
195
  platform.set_model_name(available_names[0])
186
196
  except Exception:
187
197
  # 获取模型列表或设置模型失败时,保持原设置并继续,交由底层报错处理
@@ -190,12 +200,6 @@ class SubAgentTool:
190
200
  # 执行任务
191
201
  result = agent.run(enhanced_task)
192
202
 
193
- # 主动清理,避免污染父 Agent 的全局状态
194
- try:
195
- delete_agent(agent.name)
196
- except Exception:
197
- pass
198
-
199
203
  # 规范化输出
200
204
  if isinstance(result, (dict, list)):
201
205
  stdout = json.dumps(result, ensure_ascii=False, indent=2)
@@ -9,11 +9,13 @@ sub_code_agent 工具
9
9
  - 不依赖父 Agent,所有配置使用系统默认与全局变量
10
10
  - 子Agent必须自动完成(auto_complete=True)且需要summary(need_summary=True)
11
11
  """
12
- from typing import Any, Dict, List
12
+
13
+ from typing import Any
14
+ from typing import Dict
15
+ from typing import List
13
16
 
14
17
  from jarvis.jarvis_code_agent.code_agent import CodeAgent
15
- from jarvis.jarvis_utils.globals import delete_agent
16
- from jarvis.jarvis_utils.config import set_config, get_git_check_mode
18
+ from jarvis.jarvis_utils.globals import get_global_model_group
17
19
 
18
20
 
19
21
  class SubCodeAgentTool:
@@ -38,6 +40,10 @@ class SubCodeAgentTool:
38
40
  "type": "string",
39
41
  "description": "任务背景与已知信息(可选,将与任务一并提供给子Agent)",
40
42
  },
43
+ "name": {
44
+ "type": "string",
45
+ "description": "子Agent的名称(可选,用于标识和区分不同的子Agent)",
46
+ },
41
47
  },
42
48
  "required": ["task"],
43
49
  }
@@ -59,13 +65,15 @@ class SubCodeAgentTool:
59
65
  "stderr": "task 不能为空",
60
66
  }
61
67
 
62
-
63
68
  # 读取背景信息并组合任务
64
69
  background: str = str(args.get("background", "")).strip()
65
70
  enhanced_task = (
66
71
  f"背景信息:\n{background}\n\n任务:\n{task}" if background else task
67
72
  )
68
73
 
74
+ # 读取子Agent名称(可选)
75
+ agent_name: str = str(args.get("name", "")).strip()
76
+
69
77
  # 继承父Agent的模型组与工具使用集(用于覆盖默认值)
70
78
  parent_agent = args.get("agent")
71
79
  # 如未注入父Agent,尝试从全局获取当前或任一已注册Agent
@@ -73,7 +81,7 @@ class SubCodeAgentTool:
73
81
  try:
74
82
  from jarvis.jarvis_utils import globals as G # 延迟导入避免循环
75
83
 
76
- curr = getattr(G, "current_agent_name", "")
84
+ curr = G.get_current_agent_name()
77
85
  if curr:
78
86
  parent_agent = getattr(G, "global_agents", {}).get(curr)
79
87
  if parent_agent is None and getattr(G, "global_agents", {}):
@@ -83,13 +91,16 @@ class SubCodeAgentTool:
83
91
  parent_agent = None
84
92
  except Exception:
85
93
  parent_agent = None
86
- parent_non_interactive = getattr(parent_agent, "non_interactive", None) if parent_agent is not None else None
87
- model_group = None
94
+ (
95
+ getattr(parent_agent, "non_interactive", None)
96
+ if parent_agent is not None
97
+ else None
98
+ )
99
+ # 使用全局模型组(不再从 parent_agent 继承)
100
+ model_group = get_global_model_group()
88
101
  use_tools: List[str] = []
89
102
  try:
90
103
  if parent_agent is not None:
91
- if getattr(parent_agent, "model", None):
92
- model_group = getattr(parent_agent.model, "model_group", None)
93
104
  parent_registry = parent_agent.get_tool_registry()
94
105
  if parent_registry:
95
106
  for t in parent_registry.get_all_tools():
@@ -116,29 +127,42 @@ class SubCodeAgentTool:
116
127
  "execute_script",
117
128
  "read_code",
118
129
  "edit_file",
119
- "rewrite_file",
120
- "lsp_client",
121
130
  ]
122
131
  if use_tools:
123
132
  # 过滤掉基础工具和禁止的工具
124
- extras = [t for t in use_tools if t not in base_tools and t not in forbidden_tools]
133
+ extras = [
134
+ t
135
+ for t in use_tools
136
+ if t not in base_tools and t not in forbidden_tools
137
+ ]
125
138
  append_tools = ",".join(extras) if extras else None
126
139
  except Exception:
127
140
  append_tools = None
128
141
 
129
- # 在子Agent中放宽 Git 配置校验,避免因严格校验导致进程退出
130
- # 使用配置项将校验模式临时切换为 warn,构造完成后恢复原值
131
- old_mode = None
142
+ # 获取父代理的规则名称列表用于继承
143
+ rule_names = None
144
+ try:
145
+ if parent_agent is not None and hasattr(
146
+ parent_agent, "loaded_rule_names"
147
+ ):
148
+ parent_rules = getattr(parent_agent, "loaded_rule_names", [])
149
+ if parent_rules:
150
+ rule_names = ",".join(parent_rules)
151
+ except Exception:
152
+ rule_names = None
153
+
154
+ # 创建 CodeAgent,捕获 SystemExit 异常(如 git 配置不完整)
132
155
  try:
133
- old_mode = get_git_check_mode()
134
- set_config("JARVIS_GIT_CHECK_MODE", "warn")
135
156
  code_agent = CodeAgent(
157
+ name=agent_name,
136
158
  model_group=model_group,
137
159
  need_summary=True,
138
160
  append_tools=append_tools,
139
161
  tool_group=tool_group,
140
- non_interactive=parent_non_interactive,
141
- )
162
+ non_interactive=True,
163
+ rule_names=rule_names,
164
+ auto_complete=True,
165
+ ) # type: ignore[arg-type]
142
166
  except SystemExit as se:
143
167
  # 将底层 sys.exit 转换为工具错误,避免终止进程
144
168
  return {
@@ -146,62 +170,22 @@ class SubCodeAgentTool:
146
170
  "stdout": "",
147
171
  "stderr": f"初始化 CodeAgent 失败(可能未配置 git 或当前非 git 仓库): {se}",
148
172
  }
149
- finally:
150
- if old_mode is not None:
151
- try:
152
- set_config("JARVIS_GIT_CHECK_MODE", old_mode)
153
- except Exception:
154
- pass
155
173
 
156
174
  # 子Agent需要自动完成
157
175
  try:
158
- code_agent.auto_complete = True
159
176
  # 同步父Agent工具使用集(如可用),但禁用 sub_agent 和 sub_code_agent 避免无限递归
160
177
  if use_tools:
161
178
  forbidden_tools = {"sub_agent", "sub_code_agent"}
162
179
  filtered_tools = [t for t in use_tools if t not in forbidden_tools]
163
180
  if filtered_tools:
164
181
  code_agent.set_use_tools(filtered_tools)
165
- # 同步父Agent的模型名称(如可用),以尽量保持平台与模型一致
166
- if (
167
- parent_agent is not None
168
- and getattr(parent_agent, "model", None)
169
- and getattr(code_agent, "model", None)
170
- ):
171
- try:
172
- parent_model_name = parent_agent.model.name() # type: ignore[attr-defined]
173
- if parent_model_name:
174
- from typing import Any
175
- model_obj: Any = getattr(code_agent, "model", None)
176
- if model_obj is not None:
177
- model_obj.set_model_name(parent_model_name)
178
- # 模型有效性校验与回退,确保父Agent模型在子Agent平台上可用
179
- try:
180
- available_models = model_obj.get_model_list()
181
- if available_models:
182
- available_names = [m for m, _ in available_models]
183
- current_model_name = model_obj.name()
184
- if current_model_name not in available_names:
185
- print(f"⚠️ 检测到子CodeAgent模型 {current_model_name} 不存在于平台 {model_obj.platform_name()} 的可用模型列表,将回退到 {available_names[0]}")
186
- model_obj.set_model_name(available_names[0])
187
- except Exception:
188
- # 获取模型列表或设置模型失败时,保持原设置并继续,交由底层报错处理
189
- pass
190
- except Exception:
191
- pass
182
+ # 不再从父Agent获取模型名,使用系统默认配置(符合"不依赖父 Agent"的约定)
192
183
  except Exception:
193
184
  pass
194
185
 
195
186
  # 执行子任务(无提交信息前后缀)
196
187
  ret = code_agent.run(enhanced_task, prefix="", suffix="")
197
188
 
198
- # 主动清理 CodeAgent 实例,避免污染父Agent的全局状态
199
- try:
200
- # CodeAgent 现在直接继承 Agent,所以直接使用 code_agent
201
- delete_agent(code_agent.name)
202
- except Exception:
203
- pass
204
-
205
189
  return {
206
190
  "success": True,
207
191
  "stdout": ret,