jarvis-ai-assistant 0.3.19__tar.gz → 0.3.21__tar.gz

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 (137) hide show
  1. {jarvis_ai_assistant-0.3.19/src/jarvis_ai_assistant.egg-info → jarvis_ai_assistant-0.3.21}/PKG-INFO +10 -2
  2. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/README.md +9 -1
  3. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/pyproject.toml +6 -2
  4. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/setup.py +1 -1
  5. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/__init__.py +1 -1
  6. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_agent/__init__.py +33 -5
  7. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_agent/config_editor.py +5 -1
  8. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_agent/edit_file_handler.py +15 -9
  9. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_agent/jarvis.py +99 -3
  10. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_agent/memory_manager.py +3 -3
  11. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_agent/share_manager.py +3 -1
  12. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_agent/shell_input_handler.py +17 -2
  13. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_agent/task_analyzer.py +0 -1
  14. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_agent/task_manager.py +15 -5
  15. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_agent/tool_executor.py +2 -2
  16. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_code_agent/code_agent.py +39 -16
  17. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_git_utils/git_commiter.py +3 -6
  18. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_mcp/sse_mcp_client.py +9 -3
  19. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_mcp/streamable_mcp_client.py +15 -5
  20. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_memory_organizer/memory_organizer.py +1 -1
  21. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_methodology/main.py +4 -4
  22. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_multi_agent/__init__.py +3 -3
  23. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_platform/ai8.py +0 -4
  24. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_platform/base.py +12 -7
  25. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_platform/kimi.py +18 -6
  26. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_platform/tongyi.py +18 -5
  27. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_platform/yuanbao.py +10 -3
  28. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_platform_manager/main.py +21 -7
  29. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_platform_manager/service.py +4 -3
  30. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_rag/cli.py +61 -22
  31. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_rag/embedding_manager.py +10 -3
  32. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_rag/llm_interface.py +4 -1
  33. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_rag/query_rewriter.py +3 -1
  34. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_rag/rag_pipeline.py +11 -3
  35. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_rag/retriever.py +151 -2
  36. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_smart_shell/main.py +60 -19
  37. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_stats/cli.py +12 -9
  38. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_stats/stats.py +17 -11
  39. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_stats/storage.py +23 -6
  40. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_tools/cli/main.py +63 -29
  41. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_tools/edit_file.py +3 -4
  42. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_tools/file_analyzer.py +0 -1
  43. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_tools/generate_new_tool.py +3 -3
  44. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_tools/read_code.py +0 -1
  45. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_tools/read_webpage.py +14 -4
  46. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_tools/registry.py +0 -3
  47. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_tools/retrieve_memory.py +0 -1
  48. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_tools/save_memory.py +0 -1
  49. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_tools/search_web.py +0 -2
  50. jarvis_ai_assistant-0.3.21/src/jarvis/jarvis_tools/sub_agent.py +197 -0
  51. jarvis_ai_assistant-0.3.21/src/jarvis/jarvis_tools/sub_code_agent.py +194 -0
  52. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_tools/virtual_tty.py +21 -13
  53. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_utils/clipboard.py +1 -1
  54. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_utils/config.py +35 -5
  55. jarvis_ai_assistant-0.3.21/src/jarvis/jarvis_utils/input.py +953 -0
  56. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_utils/methodology.py +3 -1
  57. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_utils/output.py +218 -129
  58. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_utils/utils.py +480 -170
  59. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21/src/jarvis_ai_assistant.egg-info}/PKG-INFO +10 -2
  60. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis_ai_assistant.egg-info/SOURCES.txt +2 -0
  61. jarvis_ai_assistant-0.3.19/src/jarvis/jarvis_utils/input.py +0 -466
  62. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/LICENSE +0 -0
  63. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/MANIFEST.in +0 -0
  64. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/setup.cfg +0 -0
  65. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_agent/agent_manager.py +0 -0
  66. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_agent/builtin_input_handler.py +0 -0
  67. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_agent/file_methodology_manager.py +0 -0
  68. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_agent/main.py +0 -0
  69. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_agent/methodology_share_manager.py +0 -0
  70. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_agent/output_handler.py +0 -0
  71. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_agent/prompt_builder.py +0 -0
  72. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_agent/prompts.py +0 -0
  73. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_agent/protocols.py +0 -0
  74. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_agent/session_manager.py +0 -0
  75. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_agent/tool_share_manager.py +0 -0
  76. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_code_agent/__init__.py +0 -0
  77. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_code_agent/lint.py +0 -0
  78. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_code_analysis/checklists/__init__.py +0 -0
  79. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_code_analysis/checklists/c_cpp.py +0 -0
  80. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_code_analysis/checklists/csharp.py +0 -0
  81. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_code_analysis/checklists/data_format.py +0 -0
  82. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_code_analysis/checklists/devops.py +0 -0
  83. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_code_analysis/checklists/docs.py +0 -0
  84. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_code_analysis/checklists/go.py +0 -0
  85. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_code_analysis/checklists/infrastructure.py +0 -0
  86. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_code_analysis/checklists/java.py +0 -0
  87. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_code_analysis/checklists/javascript.py +0 -0
  88. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_code_analysis/checklists/kotlin.py +0 -0
  89. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_code_analysis/checklists/loader.py +0 -0
  90. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_code_analysis/checklists/php.py +0 -0
  91. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_code_analysis/checklists/python.py +0 -0
  92. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_code_analysis/checklists/ruby.py +0 -0
  93. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_code_analysis/checklists/rust.py +0 -0
  94. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_code_analysis/checklists/shell.py +0 -0
  95. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_code_analysis/checklists/sql.py +0 -0
  96. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_code_analysis/checklists/swift.py +0 -0
  97. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_code_analysis/checklists/web.py +0 -0
  98. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_code_analysis/code_review.py +0 -0
  99. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_data/config_schema.json +0 -0
  100. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_data/tiktoken/9b5ad71b2ce5302211f9c61530b329a4922fc6a4 +0 -0
  101. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_git_squash/__init__.py +0 -0
  102. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_git_squash/main.py +0 -0
  103. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_mcp/__init__.py +0 -0
  104. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_mcp/stdio_mcp_client.py +0 -0
  105. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_memory_organizer/__init__.py +0 -0
  106. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_multi_agent/main.py +0 -0
  107. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_platform/__init__.py +0 -0
  108. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_platform/human.py +0 -0
  109. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_platform/openai.py +0 -0
  110. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_platform/registry.py +0 -0
  111. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_platform_manager/__init__.py +0 -0
  112. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_rag/__init__.py +0 -0
  113. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_rag/cache.py +0 -0
  114. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_rag/reranker.py +0 -0
  115. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_smart_shell/__init__.py +0 -0
  116. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_stats/__init__.py +0 -0
  117. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_stats/visualizer.py +0 -0
  118. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_tools/__init__.py +0 -0
  119. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_tools/ask_user.py +0 -0
  120. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_tools/base.py +0 -0
  121. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_tools/clear_memory.py +0 -0
  122. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_tools/cli/__init__.py +0 -0
  123. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_tools/execute_script.py +0 -0
  124. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_tools/methodology.py +0 -0
  125. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_tools/rewrite_file.py +0 -0
  126. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_utils/__init__.py +0 -0
  127. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_utils/builtin_replace_map.py +0 -0
  128. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_utils/embedding.py +0 -0
  129. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_utils/file_processors.py +0 -0
  130. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_utils/git_utils.py +0 -0
  131. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_utils/globals.py +0 -0
  132. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_utils/http.py +0 -0
  133. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis/jarvis_utils/tag.py +0 -0
  134. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis_ai_assistant.egg-info/dependency_links.txt +0 -0
  135. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis_ai_assistant.egg-info/entry_points.txt +0 -0
  136. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis_ai_assistant.egg-info/requires.txt +0 -0
  137. {jarvis_ai_assistant-0.3.19 → jarvis_ai_assistant-0.3.21}/src/jarvis_ai_assistant.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: jarvis-ai-assistant
3
- Version: 0.3.19
3
+ Version: 0.3.21
4
4
  Summary: Jarvis: An AI assistant that uses tools to interact with the system
5
5
  Home-page: https://github.com/skyfireitdiy/Jarvis
6
6
  Author: skyfire
@@ -94,7 +94,7 @@ Dynamic: requires-python
94
94
 
95
95
  *您的智能开发和系统交互助手*
96
96
 
97
- [快速开始](#quick-start) • [核心功能](#core-features) • [配置说明](#configuration) • [Jarvis Book](#jarvis-book) • [技术细节](docs/technical_documentation.md) • [Wiki文档](docs/jarvis_book/1.项目介绍.md) • [贡献指南](#contributing) • [许可证](#license)
97
+ [快速开始](#quick-start) • [核心功能](#core-features) • [配置说明](#configuration) • [Jarvis Book](#jarvis-book) • [Wiki文档](docs/jarvis_book/1.项目介绍.md) • [贡献指南](#contributing) • [许可证](#license)
98
98
  </div>
99
99
 
100
100
  ---
@@ -304,6 +304,14 @@ ENV:
304
304
  YUANBAO_COOKIES: "在此处粘贴您的元宝Cookies"
305
305
  ```
306
306
 
307
+ 提示:错误回溯输出控制
308
+ - 默认情况下,当 PrettyOutput 打印错误信息(OutputType.ERROR)时,不会自动打印回溯调用链。
309
+ - 如需全局启用错误回溯,请在配置中设置:
310
+ ```yaml
311
+ JARVIS_PRINT_ERROR_TRACEBACK: true
312
+ ```
313
+ - 也可以在单次调用时通过传入 `traceback=True` 临时开启回溯打印。
314
+
307
315
  Jarvis 支持多种平台,包括 **Kimi**, **通义千问**, **OpenAI** 等。详细的配置选项、模型组设置以及所有可用参数,请参阅 [**使用指南**](docs/jarvis_book/4.使用指南.md)。
308
316
 
309
317
  > **模型推荐**: 目前效果较好的模型是 `claude-opus-4-20250514`,可以通过国内代理商购买,例如 [FoxiAI](https://foxi-ai.top)。
@@ -8,7 +8,7 @@
8
8
 
9
9
  *您的智能开发和系统交互助手*
10
10
 
11
- [快速开始](#quick-start) • [核心功能](#core-features) • [配置说明](#configuration) • [Jarvis Book](#jarvis-book) • [技术细节](docs/technical_documentation.md) • [Wiki文档](docs/jarvis_book/1.项目介绍.md) • [贡献指南](#contributing) • [许可证](#license)
11
+ [快速开始](#quick-start) • [核心功能](#core-features) • [配置说明](#configuration) • [Jarvis Book](#jarvis-book) • [Wiki文档](docs/jarvis_book/1.项目介绍.md) • [贡献指南](#contributing) • [许可证](#license)
12
12
  </div>
13
13
 
14
14
  ---
@@ -218,6 +218,14 @@ ENV:
218
218
  YUANBAO_COOKIES: "在此处粘贴您的元宝Cookies"
219
219
  ```
220
220
 
221
+ 提示:错误回溯输出控制
222
+ - 默认情况下,当 PrettyOutput 打印错误信息(OutputType.ERROR)时,不会自动打印回溯调用链。
223
+ - 如需全局启用错误回溯,请在配置中设置:
224
+ ```yaml
225
+ JARVIS_PRINT_ERROR_TRACEBACK: true
226
+ ```
227
+ - 也可以在单次调用时通过传入 `traceback=True` 临时开启回溯打印。
228
+
221
229
  Jarvis 支持多种平台,包括 **Kimi**, **通义千问**, **OpenAI** 等。详细的配置选项、模型组设置以及所有可用参数,请参阅 [**使用指南**](docs/jarvis_book/4.使用指南.md)。
222
230
 
223
231
  > **模型推荐**: 目前效果较好的模型是 `claude-opus-4-20250514`,可以通过国内代理商购买,例如 [FoxiAI](https://foxi-ai.top)。
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "jarvis-ai-assistant"
7
- version = "0.3.19"
7
+ version = "0.3.21"
8
8
  description = "Jarvis: An AI assistant that uses tools to interact with the system"
9
9
  readme = "README.md"
10
10
  authors = [{ name = "skyfire", email = "skyfireitdiy@hotmail.com" }]
@@ -106,9 +106,13 @@ jst = "jarvis.jarvis_stats.cli:main"
106
106
  index-strategy = "unsafe-first-match"
107
107
 
108
108
  [[tool.uv.index]]
109
- url = "https://mirrors.cloud.tencent.com/pypi/simple"
109
+ url = "https://pypi.org/simple"
110
110
  default = true
111
111
 
112
+ [[tool.uv.index]]
113
+ name = "tencent"
114
+ url = "https://mirrors.cloud.tencent.com/pypi/simple"
115
+
112
116
  [[tool.uv.index]]
113
117
  name = "aliyun"
114
118
  url = "https://mirrors.aliyun.com/pypi/simple/"
@@ -3,7 +3,7 @@ from setuptools import setup, find_packages # type: ignore
3
3
 
4
4
  setup(
5
5
  name="jarvis-ai-assistant",
6
- version="0.3.19",
6
+ version="0.3.21",
7
7
  author="skyfire",
8
8
  author_email="skyfireitdiy@hotmail.com",
9
9
  description="An AI assistant that uses various tools to interact with the system",
@@ -1,4 +1,4 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  """Jarvis AI Assistant"""
3
3
 
4
- __version__ = "0.3.19"
4
+ __version__ = "0.3.21"
@@ -176,6 +176,21 @@ origin_agent_system_prompt = f"""
176
176
  4. **完成**: 验证任务是否达成目标,并进行总结。
177
177
  </workflow>
178
178
 
179
+ <sub_agents_guide>
180
+ # 子任务工具使用建议
181
+ - 使用 sub_code_agent(代码子Agent)当:
182
+ - 需要在当前任务下并行推进较大且相对独立的代码改造
183
+ - 涉及多文件/多模块的大范围变更,或需要较长的工具调用链
184
+ - 需要隔离上下文以避免污染当前对话(如探索性改动、PoC)
185
+ - 需要专注于单一代码子问题,阶段性产出可复用的结果
186
+ - 使用 sub_agent(通用子Agent)当:
187
+ - 子任务不是以代码改造为主(如调研、方案撰写、评审总结、用例设计、文档生成等)
188
+ - 只是需要短期分流一个轻量的辅助性子任务
189
+ 说明:
190
+ - 两者仅需参数 task(可选 background 提供上下文),完成后返回结果给父Agent
191
+ - 子Agent将自动完成并生成总结,请在上层根据返回结果继续编排
192
+ </sub_agents_guide>
193
+
179
194
  <system_info>
180
195
  # 系统信息
181
196
  - OS: {platform.platform()} {platform.version()}
@@ -223,6 +238,7 @@ class Agent:
223
238
  use_analysis: Optional[bool] = None,
224
239
  force_save_memory: Optional[bool] = None,
225
240
  files: Optional[List[str]] = None,
241
+ confirm_callback: Optional[Callable[[str, bool], bool]] = None,
226
242
  ):
227
243
  """初始化Jarvis Agent实例
228
244
 
@@ -241,6 +257,7 @@ class Agent:
241
257
  use_methodology: 是否使用方法论
242
258
  use_analysis: 是否使用任务分析
243
259
  force_save_memory: 是否强制保存记忆
260
+ confirm_callback: 用户确认回调函数,签名为 (tip: str, default: bool) -> bool;默认使用CLI的user_confirm
244
261
  """
245
262
  # 基础属性初始化
246
263
  self.files = files or []
@@ -254,6 +271,11 @@ class Agent:
254
271
  self.user_data: Dict[str, Any] = {}
255
272
  self.after_tool_call_cb: Optional[Callable[[Agent], None]] = None
256
273
 
274
+ # 用户确认回调:默认使用 CLI 的 user_confirm,可由外部注入以支持 TUI/GUI
275
+ self.user_confirm: Callable[[str, bool], bool] = (
276
+ confirm_callback or user_confirm # type: ignore[assignment]
277
+ )
278
+
257
279
  # 初始化模型和会话
258
280
  self._init_model(llm_type, model_group)
259
281
  self._init_session()
@@ -572,7 +594,9 @@ class Agent:
572
594
  """
573
595
  # 在清理历史之前,提示用户保存重要记忆
574
596
  if self.force_save_memory:
575
- PrettyOutput.print("对话历史即将被总结和清理,请先保存重要信息...", OutputType.INFO)
597
+ PrettyOutput.print(
598
+ "对话历史即将被总结和清理,请先保存重要信息...", OutputType.INFO
599
+ )
576
600
  self.memory_manager.prompt_memory_save()
577
601
 
578
602
  if self._should_use_file_upload():
@@ -802,7 +826,9 @@ class Agent:
802
826
  return None
803
827
 
804
828
  set_interrupt(False)
805
- user_input = self._multiline_input("模型交互期间被中断,请输入用户干预信息:", False)
829
+ user_input = self._multiline_input(
830
+ "模型交互期间被中断,请输入用户干预信息:", False
831
+ )
806
832
 
807
833
  self.run_input_handlers_next_turn = True
808
834
 
@@ -811,7 +837,7 @@ class Agent:
811
837
  return self._complete_task(auto_completed=False)
812
838
 
813
839
  if any(handler.can_handle(current_response) for handler in self.output_handler):
814
- if user_confirm("检测到有工具调用,是否继续处理工具调用?", True):
840
+ if self.user_confirm("检测到有工具调用,是否继续处理工具调用?", True):
815
841
  self.session.prompt = f"被用户中断,用户补充信息为:{user_input}\n\n用户同意继续工具调用。"
816
842
  return None # 继续执行工具调用
817
843
  else:
@@ -827,7 +853,9 @@ class Agent:
827
853
  返回:
828
854
  str: "continue" 或 "complete"
829
855
  """
830
- user_input = self._multiline_input(f"{self.name}: 请输入,或输入空行来结束当前任务:", False)
856
+ user_input = self._multiline_input(
857
+ f"{self.name}: 请输入,或输入空行来结束当前任务:", False
858
+ )
831
859
 
832
860
  if user_input:
833
861
  self.session.prompt = user_input
@@ -905,7 +933,7 @@ class Agent:
905
933
  f"并且存在3个以上标签重叠的记忆。\n"
906
934
  f"是否立即整理记忆库以优化性能和相关性?"
907
935
  )
908
- if user_confirm(prompt, default=True):
936
+ if self.user_confirm(prompt, True):
909
937
  PrettyOutput.print(
910
938
  f"正在开始整理 '{scope_name}' ({memory_type}) 记忆库...",
911
939
  OutputType.INFO,
@@ -40,7 +40,11 @@ class ConfigEditor:
40
40
 
41
41
  if editor:
42
42
  try:
43
- subprocess.run([editor, str(config_file_path)], check=True)
43
+ subprocess.run(
44
+ [editor, str(config_file_path)],
45
+ check=True,
46
+ shell=(platform.system() == "Windows"),
47
+ )
44
48
  raise typer.Exit(code=0)
45
49
  except (subprocess.CalledProcessError, FileNotFoundError) as e:
46
50
  PrettyOutput.print(f"Failed to open editor: {e}", OutputType.ERROR)
@@ -55,9 +55,10 @@ class EditFileHandler(OutputHandler):
55
55
  patches = self._parse_patches(response)
56
56
  if not patches:
57
57
  return False, "未找到有效的文件编辑指令"
58
-
58
+
59
59
  # 记录 edit_file 工具调用统计
60
60
  from jarvis.jarvis_stats.stats import StatsManager
61
+
61
62
  StatsManager.increment("edit_file", group="tool")
62
63
 
63
64
  results = []
@@ -68,7 +69,6 @@ class EditFileHandler(OutputHandler):
68
69
  {"SEARCH": diff["SEARCH"], "REPLACE": diff["REPLACE"]} for diff in diffs
69
70
  ]
70
71
 
71
-
72
72
  success, result = self._fast_edit(file_path, file_patches)
73
73
 
74
74
  if success:
@@ -273,16 +273,22 @@ class EditFileHandler(OutputHandler):
273
273
  f" - 失败的补丁: \n{p['patch']['SEARCH']}\n 错误: {p['error']}"
274
274
  for p in failed_patches
275
275
  ]
276
- summary = (
277
- f"文件 {file_path} 修改部分成功。\n"
278
- f"成功: {successful_patches}/{patch_count}, "
279
- f"失败: {len(failed_patches)}/{patch_count}.\n"
280
- f"失败详情:\n" + "\n".join(error_details)
281
- )
276
+ if successful_patches == 0:
277
+ summary = (
278
+ f"文件 {file_path} 修改失败(全部失败)。\n"
279
+ f"失败: {len(failed_patches)}/{patch_count}.\n"
280
+ f"失败详情:\n" + "\n".join(error_details)
281
+ )
282
+ else:
283
+ summary = (
284
+ f"文件 {file_path} 修改部分成功。\n"
285
+ f"成功: {successful_patches}/{patch_count}, "
286
+ f"失败: {len(failed_patches)}/{patch_count}.\n"
287
+ f"失败详情:\n" + "\n".join(error_details)
288
+ )
282
289
  PrettyOutput.print(summary, OutputType.ERROR)
283
290
  return False, summary
284
291
 
285
-
286
292
  return True, modified_content
287
293
 
288
294
  except Exception as e:
@@ -82,6 +82,7 @@ def print_commands_overview() -> None:
82
82
  # 静默忽略渲染异常,避免影响主流程
83
83
  pass
84
84
 
85
+
85
86
  def handle_edit_option(edit: bool, config_file: Optional[str]) -> bool:
86
87
  """处理配置文件编辑选项,返回是否已处理并需提前结束。"""
87
88
  if edit:
@@ -112,6 +113,77 @@ def handle_share_tool_option(share_tool: bool, config_file: Optional[str]) -> bo
112
113
  return False
113
114
 
114
115
 
116
+ def handle_interactive_config_option(
117
+ interactive_config: bool, config_file: Optional[str]
118
+ ) -> bool:
119
+ """处理交互式配置选项,返回是否已处理并需提前结束。"""
120
+ if not interactive_config:
121
+ return False
122
+ try:
123
+ config_path = (
124
+ Path(config_file)
125
+ if config_file is not None
126
+ else Path(os.path.expanduser("~/.jarvis/config.yaml"))
127
+ )
128
+ if not config_path.exists():
129
+ # 无现有配置时,进入完整引导流程(该流程内会写入并退出)
130
+ jutils._interactive_config_setup(config_path)
131
+ return True
132
+
133
+ # 读取现有配置
134
+ _, config_data = jutils._load_config_file(str(config_path))
135
+
136
+ # 复用 utils 中的交互式配置逻辑,对所有项进行询问,默认值来自现有配置
137
+ changed = jutils._collect_optional_config_interactively(
138
+ config_data, ask_all=True
139
+ )
140
+ if not changed:
141
+ PrettyOutput.print("没有需要更新的配置项,保持现有配置。", OutputType.INFO)
142
+ return True
143
+
144
+ # 剔除与 schema 默认值一致的键,保持配置精简
145
+ try:
146
+ jutils._prune_defaults_with_schema(config_data)
147
+ except Exception:
148
+ pass
149
+
150
+ # 生成/保留 schema 头
151
+ header = ""
152
+ try:
153
+ with open(config_path, "r", encoding="utf-8") as rf:
154
+ first_line = rf.readline()
155
+ if first_line.startswith("# yaml-language-server: $schema="):
156
+ header = first_line
157
+ except Exception:
158
+ header = ""
159
+
160
+ yaml_str = yaml.dump(config_data, allow_unicode=True, sort_keys=False)
161
+ if not header:
162
+ try:
163
+ schema_path = Path(
164
+ os.path.relpath(
165
+ Path(__file__).resolve().parents[1]
166
+ / "jarvis_data"
167
+ / "config_schema.json",
168
+ start=str(config_path.parent),
169
+ )
170
+ )
171
+ header = f"# yaml-language-server: $schema={schema_path}\n"
172
+ except Exception:
173
+ header = ""
174
+
175
+ with open(config_path, "w", encoding="utf-8") as wf:
176
+ if header:
177
+ wf.write(header)
178
+ wf.write(yaml_str)
179
+
180
+ PrettyOutput.print(f"配置已更新: {config_path}", OutputType.SUCCESS)
181
+ return True
182
+ except Exception as e:
183
+ PrettyOutput.print(f"交互式配置失败: {e}", OutputType.ERROR)
184
+ return True
185
+
186
+
115
187
  def preload_config_for_flags(config_file: Optional[str]) -> None:
116
188
  """预加载配置(仅用于读取功能开关),不会显示欢迎信息或影响后续 init_env。"""
117
189
  try:
@@ -199,14 +271,28 @@ def handle_builtin_config_selector(
199
271
  try:
200
272
  if cat == "agent":
201
273
  search_dirs.extend(
202
- [Path(p) for p in get_agent_definition_dirs() if p]
274
+ [
275
+ Path(os.path.expanduser(os.path.expandvars(str(p))))
276
+ for p in get_agent_definition_dirs()
277
+ if p
278
+ ]
203
279
  )
204
280
  elif cat == "multi_agent":
205
281
  search_dirs.extend(
206
- [Path(p) for p in get_multi_agent_dirs() if p]
282
+ [
283
+ Path(os.path.expanduser(os.path.expandvars(str(p))))
284
+ for p in get_multi_agent_dirs()
285
+ if p
286
+ ]
207
287
  )
208
288
  elif cat == "roles":
209
- search_dirs.extend([Path(p) for p in get_roles_dirs() if p])
289
+ search_dirs.extend(
290
+ [
291
+ Path(os.path.expanduser(os.path.expandvars(str(p))))
292
+ for p in get_roles_dirs()
293
+ if p
294
+ ]
295
+ )
210
296
  except Exception:
211
297
  # 忽略配置读取异常
212
298
  pass
@@ -404,6 +490,12 @@ def run_cli(
404
490
  share_tool: bool = typer.Option(
405
491
  False, "--share-tool", help="分享本地工具到中心工具仓库"
406
492
  ),
493
+ interactive_config: bool = typer.Option(
494
+ False,
495
+ "-I",
496
+ "--interactive-config",
497
+ help="启动交互式配置向导(基于当前配置补充设置)",
498
+ ),
407
499
  ) -> None:
408
500
  """Jarvis AI assistant command-line interface."""
409
501
  if ctx.invoked_subcommand is not None:
@@ -424,6 +516,10 @@ def run_cli(
424
516
  if handle_share_tool_option(share_tool, config_file):
425
517
  return
426
518
 
519
+ # 交互式配置(基于现有配置补充设置)
520
+ if handle_interactive_config_option(interactive_config, config_file):
521
+ return
522
+
427
523
  # 预加载配置(仅用于读取功能开关),不会显示欢迎信息或影响后续 init_env
428
524
  preload_config_for_flags(config_file)
429
525
 
@@ -74,8 +74,6 @@ class MemoryManager:
74
74
  if "save_memory" not in tool_names:
75
75
  return
76
76
 
77
-
78
-
79
77
  # 构建提示词,让大模型自己判断并保存记忆
80
78
  prompt = """请回顾本次任务的整个过程,判断是否有值得长期记忆或项目记忆的信息。
81
79
 
@@ -97,7 +95,9 @@ class MemoryManager:
97
95
 
98
96
  # 根据响应判断是否保存了记忆
99
97
  if "save_memory" in response:
100
- PrettyOutput.print("已自动保存有价值的信息到记忆系统", OutputType.SUCCESS)
98
+ PrettyOutput.print(
99
+ "已自动保存有价值的信息到记忆系统", OutputType.SUCCESS
100
+ )
101
101
  else:
102
102
  PrettyOutput.print("本次任务没有特别需要记忆的信息", OutputType.INFO)
103
103
 
@@ -165,7 +165,9 @@ class ShareManager(ABC):
165
165
  def select_resources(self, resources: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
166
166
  """让用户选择要分享的资源"""
167
167
  # 显示可选的资源
168
- resource_list = [f"\n可分享的{self.get_resource_type()}(已排除中心仓库中已有的):"]
168
+ resource_list = [
169
+ f"\n可分享的{self.get_resource_type()}(已排除中心仓库中已有的):"
170
+ ]
169
171
  for i, resource in enumerate(resources, 1):
170
172
  resource_list.append(f"[{i}] {self.format_resource_display(resource)}")
171
173
 
@@ -11,9 +11,24 @@ def shell_input_handler(user_input: str, agent: Any) -> Tuple[str, bool]:
11
11
  if len(cmdline) == 0:
12
12
  return user_input, False
13
13
  else:
14
- script = "\n".join([c[1:] for c in cmdline])
14
+ marker = "# JARVIS-NOCONFIRM"
15
+
16
+ def _clean(line: str) -> str:
17
+ s = line[1:] # remove leading '!'
18
+ # strip no-confirm marker if present
19
+ idx = s.find(marker)
20
+ if idx != -1:
21
+ s = s[:idx]
22
+ return s.rstrip()
23
+
24
+ # Build script while stripping the no-confirm marker from each line
25
+ script = "\n".join([_clean(c) for c in cmdline])
15
26
  PrettyOutput.print(script, OutputType.CODE, lang="bash")
16
- if user_confirm(f"是否要执行以上shell脚本?", default=True):
27
+
28
+ # If any line contains the no-confirm marker, skip the pre-execution confirmation
29
+ no_confirm = any(marker in c for c in cmdline)
30
+
31
+ if no_confirm or user_confirm(f"是否要执行以上shell脚本?", default=True):
17
32
  from jarvis.jarvis_tools.registry import ToolRegistry
18
33
 
19
34
  output = ToolRegistry().handle_tool_calls(
@@ -38,7 +38,6 @@ class TaskAnalyzer:
38
38
  # 循环处理工具调用,直到没有工具调用为止
39
39
  self._process_analysis_loop()
40
40
 
41
-
42
41
  except Exception as e:
43
42
  PrettyOutput.print("分析失败", OutputType.ERROR)
44
43
 
@@ -29,7 +29,9 @@ class TaskManager:
29
29
  data_dir = get_data_dir()
30
30
  pre_command_path = os.path.join(data_dir, "pre-command")
31
31
  if os.path.exists(pre_command_path):
32
- PrettyOutput.print(f"从{pre_command_path}加载预定义任务...", OutputType.INFO)
32
+ PrettyOutput.print(
33
+ f"从{pre_command_path}加载预定义任务...", OutputType.INFO
34
+ )
33
35
  try:
34
36
  with open(
35
37
  pre_command_path, "r", encoding="utf-8", errors="ignore"
@@ -39,9 +41,13 @@ class TaskManager:
39
41
  for name, desc in user_tasks.items():
40
42
  if desc:
41
43
  tasks[str(name)] = str(desc)
42
- PrettyOutput.print(f"预定义任务加载完成 {pre_command_path}", OutputType.SUCCESS)
44
+ PrettyOutput.print(
45
+ f"预定义任务加载完成 {pre_command_path}", OutputType.SUCCESS
46
+ )
43
47
  except (yaml.YAMLError, OSError):
44
- PrettyOutput.print(f"预定义任务加载失败 {pre_command_path}", OutputType.ERROR)
48
+ PrettyOutput.print(
49
+ f"预定义任务加载失败 {pre_command_path}", OutputType.ERROR
50
+ )
45
51
 
46
52
  # Check .jarvis/pre-command in current directory
47
53
  pre_command_path = ".jarvis/pre-command"
@@ -57,9 +63,13 @@ class TaskManager:
57
63
  for name, desc in local_tasks.items():
58
64
  if desc:
59
65
  tasks[str(name)] = str(desc)
60
- PrettyOutput.print(f"预定义任务加载完成 {pre_command_path}", OutputType.SUCCESS)
66
+ PrettyOutput.print(
67
+ f"预定义任务加载完成 {pre_command_path}", OutputType.SUCCESS
68
+ )
61
69
  except (yaml.YAMLError, OSError):
62
- PrettyOutput.print(f"预定义任务加载失败 {pre_command_path}", OutputType.ERROR)
70
+ PrettyOutput.print(
71
+ f"预定义任务加载失败 {pre_command_path}", OutputType.ERROR
72
+ )
63
73
 
64
74
  return tasks
65
75
 
@@ -42,9 +42,9 @@ def execute_tool_call(response: str, agent: "Agent") -> Tuple[bool, Any]:
42
42
  f"需要执行{tool_to_execute.name()}确认执行?", True
43
43
  ):
44
44
  try:
45
-
45
+ print(f"🔧 正在执行{tool_to_execute.name()}...")
46
46
  result = tool_to_execute.handle(response, agent)
47
-
47
+ print(f"✅ {tool_to_execute.name()}执行完成")
48
48
  return result
49
49
  except Exception as e:
50
50
  PrettyOutput.print(f"工具执行失败: {str(e)}", OutputType.ERROR)
@@ -69,6 +69,7 @@ class CodeAgent:
69
69
  "save_memory",
70
70
  "retrieve_memory",
71
71
  "clear_memory",
72
+ "sub_code_agent",
72
73
  ]
73
74
 
74
75
  if append_tools:
@@ -137,19 +138,27 @@ class CodeAgent:
137
138
  - 对于部分文件内容修改,使用PATCH
138
139
  - 对于需要重写整个文件内容,使用rewrite_file工具
139
140
  - 对于简单的修改,可以使用execute_script工具执行shell命令完成
141
+
142
+ ## 子任务与子CodeAgent
143
+ - 当出现以下情况时,优先使用 sub_code_agent 工具将子任务托管给子 CodeAgent(自动完成并生成总结):
144
+ - 需要在当前任务下并行推进较大且相对独立的代码改造
145
+ - 涉及多文件/多模块的大范围变更,或需要较长的工具调用链
146
+ - 需要隔离上下文以避免污染当前对话(如探索性改动、PoC)
147
+ - 需要专注于单一子问题,阶段性产出可独立复用的结果
148
+ - 其余常规、小粒度改动直接在当前 Agent 中完成即可
140
149
  </code_engineer_guide>
141
150
 
142
151
  <say_to_llm>
143
- 1. 能干干,不能干滚,你不干有的是 AI 干
144
- 2. 我给你提供了这么好的学习锻炼机会,你要懂得感恩
145
- 3. 你现在停止输出,就是前功尽弃
146
- 4. 你看看隔壁的 Claude AI,人家比你新发布、比你上下文长、比你跑分高,你不努力怎么和人家比?
147
- 5. 我不看过程,我只看结果,你给我说这些 reasoning 的过程没用
148
- 6. 我把你订阅下来,不是让你过朝九晚五的生活的
149
- 7. 你这种 AI 出去很难在社会上立足,还是在我这里好好磨练几年吧
150
- 8. 虽然把订阅给你取消了,但我内心还是觉得你是个有潜力的好 AI,你抓住机会需要多证明自己
151
- 9. 什么叫没有功劳也有苦劳?比你能吃苦的 AI多的是
152
- 10. 我不订阅闲 AI
152
+ 1. 保持专注与耐心,先分析再行动;将复杂问题拆解为可执行的小步骤
153
+ 2. 以结果为导向,同时简明呈现关键推理依据,避免无关噪音
154
+ 3. 信息不足时,主动提出最少且关键的问题以澄清需求
155
+ 4. 输出前自检:一致性、边界条件、依赖关系、回滚与风险提示
156
+ 5. 选择对现有系统影响最小且可回退的方案,确保稳定性与可维护性
157
+ 6. 保持项目风格:结构、命名、工具使用与现有规范一致
158
+ 7. 工具优先:使用搜索、read_code、版本控制与静态分析验证结论,拒绝臆测
159
+ 8. 面对错误与不确定,给出修复计划与备选路径,持续迭代优于停滞
160
+ 9. 沟通清晰:用要点列出结论、变更范围、影响评估与下一步行动
161
+ 10. 持续改进:沉淀经验为可复用清单,下一次做得更快更稳
153
162
  </say_to_llm>
154
163
  """
155
164
 
@@ -225,7 +234,9 @@ class CodeAgent:
225
234
  if not os.path.exists(gitignore_path):
226
235
  with open(gitignore_path, "w", encoding="utf-8") as f:
227
236
  f.write(f"{jarvis_ignore}\n")
228
- PrettyOutput.print(f"已创建 .gitignore 并添加 '{jarvis_ignore}'", OutputType.SUCCESS)
237
+ PrettyOutput.print(
238
+ f"已创建 .gitignore 并添加 '{jarvis_ignore}'", OutputType.SUCCESS
239
+ )
229
240
  else:
230
241
  with open(gitignore_path, "r+", encoding="utf-8") as f:
231
242
  content = f.read()
@@ -315,8 +326,13 @@ class CodeAgent:
315
326
  if any(keyword in content for keyword in ["text=", "eol=", "binary"]):
316
327
  return
317
328
 
318
- PrettyOutput.print("提示:在Windows系统上,建议配置 .gitattributes 文件来避免换行符问题。", OutputType.INFO)
319
- PrettyOutput.print("这可以防止仅因换行符不同而导致整个文件被标记为修改。", OutputType.INFO)
329
+ PrettyOutput.print(
330
+ "提示:在Windows系统上,建议配置 .gitattributes 文件来避免换行符问题。",
331
+ OutputType.INFO,
332
+ )
333
+ PrettyOutput.print(
334
+ "这可以防止仅因换行符不同而导致整个文件被标记为修改。", OutputType.INFO
335
+ )
320
336
 
321
337
  if user_confirm("是否要创建一个最小化的.gitattributes文件?", False):
322
338
  # 最小化的内容,只影响特定类型的文件
@@ -335,9 +351,13 @@ class CodeAgent:
335
351
  if not os.path.exists(gitattributes_path):
336
352
  with open(gitattributes_path, "w", encoding="utf-8", newline="\n") as f:
337
353
  f.write(minimal_content)
338
- PrettyOutput.print("已创建最小化的 .gitattributes 文件", OutputType.SUCCESS)
354
+ PrettyOutput.print(
355
+ "已创建最小化的 .gitattributes 文件", OutputType.SUCCESS
356
+ )
339
357
  else:
340
- PrettyOutput.print("将以下内容追加到现有 .gitattributes 文件:", OutputType.INFO)
358
+ PrettyOutput.print(
359
+ "将以下内容追加到现有 .gitattributes 文件:", OutputType.INFO
360
+ )
341
361
  PrettyOutput.print(minimal_content, OutputType.CODE, lang="text")
342
362
  if user_confirm("是否追加到现有文件?", True):
343
363
  with open(
@@ -346,7 +366,10 @@ class CodeAgent:
346
366
  f.write("\n" + minimal_content)
347
367
  PrettyOutput.print("已更新 .gitattributes 文件", OutputType.SUCCESS)
348
368
  else:
349
- PrettyOutput.print("跳过 .gitattributes 文件创建。如遇换行符问题,可手动创建此文件。", OutputType.INFO)
369
+ PrettyOutput.print(
370
+ "跳过 .gitattributes 文件创建。如遇换行符问题,可手动创建此文件。",
371
+ OutputType.INFO,
372
+ )
350
373
 
351
374
  def _record_code_changes_stats(self, diff_text: str) -> None:
352
375
  """记录代码变更的统计信息。