jarvis-ai-assistant 0.3.20__tar.gz → 0.3.22__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.
- {jarvis_ai_assistant-0.3.20/src/jarvis_ai_assistant.egg-info → jarvis_ai_assistant-0.3.22}/PKG-INFO +10 -2
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/README.md +9 -1
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/pyproject.toml +6 -2
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/setup.py +1 -1
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/__init__.py +1 -1
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_agent/__init__.py +24 -3
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_agent/config_editor.py +5 -1
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_agent/edit_file_handler.py +15 -9
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_agent/jarvis.py +99 -3
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_agent/memory_manager.py +3 -3
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_agent/share_manager.py +3 -1
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_agent/task_analyzer.py +0 -1
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_agent/task_manager.py +15 -5
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_agent/tool_executor.py +2 -2
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_code_agent/code_agent.py +42 -18
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_git_utils/git_commiter.py +3 -6
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_mcp/sse_mcp_client.py +9 -3
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_mcp/streamable_mcp_client.py +15 -5
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_memory_organizer/memory_organizer.py +1 -1
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_methodology/main.py +4 -4
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_multi_agent/__init__.py +3 -3
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_platform/base.py +10 -5
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_platform/kimi.py +18 -6
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_platform/tongyi.py +18 -5
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_platform/yuanbao.py +10 -3
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_platform_manager/main.py +21 -7
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_platform_manager/service.py +4 -3
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_rag/cli.py +61 -22
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_rag/embedding_manager.py +10 -3
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_rag/llm_interface.py +4 -1
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_rag/query_rewriter.py +3 -1
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_rag/rag_pipeline.py +47 -3
- jarvis_ai_assistant-0.3.22/src/jarvis/jarvis_rag/retriever.py +449 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_smart_shell/main.py +59 -18
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_stats/cli.py +11 -9
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_stats/stats.py +14 -8
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_stats/storage.py +23 -6
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_tools/cli/main.py +63 -29
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_tools/edit_file.py +17 -90
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_tools/file_analyzer.py +0 -1
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_tools/generate_new_tool.py +3 -3
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_tools/read_code.py +0 -1
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_tools/read_webpage.py +14 -4
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_tools/registry.py +16 -9
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_tools/retrieve_memory.py +0 -1
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_tools/save_memory.py +0 -1
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_tools/search_web.py +0 -2
- jarvis_ai_assistant-0.3.22/src/jarvis/jarvis_tools/sub_agent.py +197 -0
- jarvis_ai_assistant-0.3.22/src/jarvis/jarvis_tools/sub_code_agent.py +194 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_tools/virtual_tty.py +21 -13
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_utils/config.py +35 -5
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_utils/input.py +297 -56
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_utils/methodology.py +3 -1
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_utils/output.py +5 -2
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_utils/utils.py +483 -170
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22/src/jarvis_ai_assistant.egg-info}/PKG-INFO +10 -2
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis_ai_assistant.egg-info/SOURCES.txt +2 -0
- jarvis_ai_assistant-0.3.20/src/jarvis/jarvis_rag/retriever.py +0 -211
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/LICENSE +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/MANIFEST.in +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/setup.cfg +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_agent/agent_manager.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_agent/builtin_input_handler.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_agent/file_methodology_manager.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_agent/main.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_agent/methodology_share_manager.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_agent/output_handler.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_agent/prompt_builder.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_agent/prompts.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_agent/protocols.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_agent/session_manager.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_agent/shell_input_handler.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_agent/tool_share_manager.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_code_agent/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_code_agent/lint.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_code_analysis/checklists/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_code_analysis/checklists/c_cpp.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_code_analysis/checklists/csharp.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_code_analysis/checklists/data_format.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_code_analysis/checklists/devops.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_code_analysis/checklists/docs.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_code_analysis/checklists/go.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_code_analysis/checklists/infrastructure.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_code_analysis/checklists/java.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_code_analysis/checklists/javascript.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_code_analysis/checklists/kotlin.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_code_analysis/checklists/loader.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_code_analysis/checklists/php.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_code_analysis/checklists/python.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_code_analysis/checklists/ruby.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_code_analysis/checklists/rust.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_code_analysis/checklists/shell.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_code_analysis/checklists/sql.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_code_analysis/checklists/swift.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_code_analysis/checklists/web.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_code_analysis/code_review.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_data/config_schema.json +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_data/tiktoken/9b5ad71b2ce5302211f9c61530b329a4922fc6a4 +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_git_squash/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_git_squash/main.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_mcp/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_mcp/stdio_mcp_client.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_memory_organizer/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_multi_agent/main.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_platform/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_platform/ai8.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_platform/human.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_platform/openai.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_platform/registry.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_platform_manager/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_rag/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_rag/cache.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_rag/reranker.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_smart_shell/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_stats/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_stats/visualizer.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_tools/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_tools/ask_user.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_tools/base.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_tools/clear_memory.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_tools/cli/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_tools/execute_script.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_tools/methodology.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_tools/rewrite_file.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_utils/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_utils/builtin_replace_map.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_utils/clipboard.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_utils/embedding.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_utils/file_processors.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_utils/git_utils.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_utils/globals.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_utils/http.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_utils/tag.py +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis_ai_assistant.egg-info/dependency_links.txt +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis_ai_assistant.egg-info/entry_points.txt +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis_ai_assistant.egg-info/requires.txt +0 -0
- {jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis_ai_assistant.egg-info/top_level.txt +0 -0
{jarvis_ai_assistant-0.3.20/src/jarvis_ai_assistant.egg-info → jarvis_ai_assistant-0.3.22}/PKG-INFO
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: jarvis-ai-assistant
|
3
|
-
Version: 0.3.
|
3
|
+
Version: 0.3.22
|
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) • [
|
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) • [
|
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.
|
7
|
+
version = "0.3.22"
|
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://
|
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.
|
6
|
+
version="0.3.22",
|
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",
|
{jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_agent/__init__.py
RENAMED
@@ -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()}
|
@@ -579,7 +594,9 @@ class Agent:
|
|
579
594
|
"""
|
580
595
|
# 在清理历史之前,提示用户保存重要记忆
|
581
596
|
if self.force_save_memory:
|
582
|
-
PrettyOutput.print(
|
597
|
+
PrettyOutput.print(
|
598
|
+
"对话历史即将被总结和清理,请先保存重要信息...", OutputType.INFO
|
599
|
+
)
|
583
600
|
self.memory_manager.prompt_memory_save()
|
584
601
|
|
585
602
|
if self._should_use_file_upload():
|
@@ -809,7 +826,9 @@ class Agent:
|
|
809
826
|
return None
|
810
827
|
|
811
828
|
set_interrupt(False)
|
812
|
-
user_input = self._multiline_input(
|
829
|
+
user_input = self._multiline_input(
|
830
|
+
"模型交互期间被中断,请输入用户干预信息:", False
|
831
|
+
)
|
813
832
|
|
814
833
|
self.run_input_handlers_next_turn = True
|
815
834
|
|
@@ -834,7 +853,9 @@ class Agent:
|
|
834
853
|
返回:
|
835
854
|
str: "continue" 或 "complete"
|
836
855
|
"""
|
837
|
-
user_input = self._multiline_input(
|
856
|
+
user_input = self._multiline_input(
|
857
|
+
f"{self.name}: 请输入,或输入空行来结束当前任务:", False
|
858
|
+
)
|
838
859
|
|
839
860
|
if user_input:
|
840
861
|
self.session.prompt = user_input
|
{jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_agent/config_editor.py
RENAMED
@@ -40,7 +40,11 @@ class ConfigEditor:
|
|
40
40
|
|
41
41
|
if editor:
|
42
42
|
try:
|
43
|
-
subprocess.run(
|
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
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
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
|
-
[
|
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
|
-
[
|
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(
|
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
|
|
{jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_agent/memory_manager.py
RENAMED
@@ -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(
|
98
|
+
PrettyOutput.print(
|
99
|
+
"已自动保存有价值的信息到记忆系统", OutputType.SUCCESS
|
100
|
+
)
|
101
101
|
else:
|
102
102
|
PrettyOutput.print("本次任务没有特别需要记忆的信息", OutputType.INFO)
|
103
103
|
|
{jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_agent/share_manager.py
RENAMED
@@ -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 = [
|
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
|
|
{jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_agent/task_manager.py
RENAMED
@@ -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(
|
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(
|
44
|
+
PrettyOutput.print(
|
45
|
+
f"预定义任务加载完成 {pre_command_path}", OutputType.SUCCESS
|
46
|
+
)
|
43
47
|
except (yaml.YAMLError, OSError):
|
44
|
-
PrettyOutput.print(
|
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(
|
66
|
+
PrettyOutput.print(
|
67
|
+
f"预定义任务加载完成 {pre_command_path}", OutputType.SUCCESS
|
68
|
+
)
|
61
69
|
except (yaml.YAMLError, OSError):
|
62
|
-
PrettyOutput.print(
|
70
|
+
PrettyOutput.print(
|
71
|
+
f"预定义任务加载失败 {pre_command_path}", OutputType.ERROR
|
72
|
+
)
|
63
73
|
|
64
74
|
return tasks
|
65
75
|
|
{jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_agent/tool_executor.py
RENAMED
@@ -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)
|
{jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_code_agent/code_agent.py
RENAMED
@@ -69,6 +69,8 @@ class CodeAgent:
|
|
69
69
|
"save_memory",
|
70
70
|
"retrieve_memory",
|
71
71
|
"clear_memory",
|
72
|
+
"sub_code_agent",
|
73
|
+
"edit_file",
|
72
74
|
]
|
73
75
|
|
74
76
|
if append_tools:
|
@@ -85,7 +87,7 @@ class CodeAgent:
|
|
85
87
|
system_prompt=code_system_prompt,
|
86
88
|
name="CodeAgent",
|
87
89
|
auto_complete=False,
|
88
|
-
output_handler=[tool_registry
|
90
|
+
output_handler=[tool_registry], # type: ignore
|
89
91
|
llm_type=llm_type,
|
90
92
|
model_group=model_group,
|
91
93
|
input_handler=[shell_input_handler, builtin_input_handler],
|
@@ -134,22 +136,30 @@ class CodeAgent:
|
|
134
136
|
- 仅在命令行工具不足时使用专用工具
|
135
137
|
|
136
138
|
## 文件编辑工具使用规范
|
137
|
-
- 对于部分文件内容修改,使用
|
139
|
+
- 对于部分文件内容修改,使用edit_file工具
|
138
140
|
- 对于需要重写整个文件内容,使用rewrite_file工具
|
139
141
|
- 对于简单的修改,可以使用execute_script工具执行shell命令完成
|
142
|
+
|
143
|
+
## 子任务与子CodeAgent
|
144
|
+
- 当出现以下情况时,优先使用 sub_code_agent 工具将子任务托管给子 CodeAgent(自动完成并生成总结):
|
145
|
+
- 需要在当前任务下并行推进较大且相对独立的代码改造
|
146
|
+
- 涉及多文件/多模块的大范围变更,或需要较长的工具调用链
|
147
|
+
- 需要隔离上下文以避免污染当前对话(如探索性改动、PoC)
|
148
|
+
- 需要专注于单一子问题,阶段性产出可独立复用的结果
|
149
|
+
- 其余常规、小粒度改动直接在当前 Agent 中完成即可
|
140
150
|
</code_engineer_guide>
|
141
151
|
|
142
152
|
<say_to_llm>
|
143
|
-
1.
|
144
|
-
2.
|
145
|
-
3.
|
146
|
-
4.
|
147
|
-
5.
|
148
|
-
6.
|
149
|
-
7.
|
150
|
-
8.
|
151
|
-
9.
|
152
|
-
10.
|
153
|
+
1. 保持专注与耐心,先分析再行动;将复杂问题拆解为可执行的小步骤
|
154
|
+
2. 以结果为导向,同时简明呈现关键推理依据,避免无关噪音
|
155
|
+
3. 信息不足时,主动提出最少且关键的问题以澄清需求
|
156
|
+
4. 输出前自检:一致性、边界条件、依赖关系、回滚与风险提示
|
157
|
+
5. 选择对现有系统影响最小且可回退的方案,确保稳定性与可维护性
|
158
|
+
6. 保持项目风格:结构、命名、工具使用与现有规范一致
|
159
|
+
7. 工具优先:使用搜索、read_code、版本控制与静态分析验证结论,拒绝臆测
|
160
|
+
8. 面对错误与不确定,给出修复计划与备选路径,持续迭代优于停滞
|
161
|
+
9. 沟通清晰:用要点列出结论、变更范围、影响评估与下一步行动
|
162
|
+
10. 持续改进:沉淀经验为可复用清单,下一次做得更快更稳
|
153
163
|
</say_to_llm>
|
154
164
|
"""
|
155
165
|
|
@@ -225,7 +235,9 @@ class CodeAgent:
|
|
225
235
|
if not os.path.exists(gitignore_path):
|
226
236
|
with open(gitignore_path, "w", encoding="utf-8") as f:
|
227
237
|
f.write(f"{jarvis_ignore}\n")
|
228
|
-
PrettyOutput.print(
|
238
|
+
PrettyOutput.print(
|
239
|
+
f"已创建 .gitignore 并添加 '{jarvis_ignore}'", OutputType.SUCCESS
|
240
|
+
)
|
229
241
|
else:
|
230
242
|
with open(gitignore_path, "r+", encoding="utf-8") as f:
|
231
243
|
content = f.read()
|
@@ -315,8 +327,13 @@ class CodeAgent:
|
|
315
327
|
if any(keyword in content for keyword in ["text=", "eol=", "binary"]):
|
316
328
|
return
|
317
329
|
|
318
|
-
PrettyOutput.print(
|
319
|
-
|
330
|
+
PrettyOutput.print(
|
331
|
+
"提示:在Windows系统上,建议配置 .gitattributes 文件来避免换行符问题。",
|
332
|
+
OutputType.INFO,
|
333
|
+
)
|
334
|
+
PrettyOutput.print(
|
335
|
+
"这可以防止仅因换行符不同而导致整个文件被标记为修改。", OutputType.INFO
|
336
|
+
)
|
320
337
|
|
321
338
|
if user_confirm("是否要创建一个最小化的.gitattributes文件?", False):
|
322
339
|
# 最小化的内容,只影响特定类型的文件
|
@@ -335,9 +352,13 @@ class CodeAgent:
|
|
335
352
|
if not os.path.exists(gitattributes_path):
|
336
353
|
with open(gitattributes_path, "w", encoding="utf-8", newline="\n") as f:
|
337
354
|
f.write(minimal_content)
|
338
|
-
PrettyOutput.print(
|
355
|
+
PrettyOutput.print(
|
356
|
+
"已创建最小化的 .gitattributes 文件", OutputType.SUCCESS
|
357
|
+
)
|
339
358
|
else:
|
340
|
-
PrettyOutput.print(
|
359
|
+
PrettyOutput.print(
|
360
|
+
"将以下内容追加到现有 .gitattributes 文件:", OutputType.INFO
|
361
|
+
)
|
341
362
|
PrettyOutput.print(minimal_content, OutputType.CODE, lang="text")
|
342
363
|
if user_confirm("是否追加到现有文件?", True):
|
343
364
|
with open(
|
@@ -346,7 +367,10 @@ class CodeAgent:
|
|
346
367
|
f.write("\n" + minimal_content)
|
347
368
|
PrettyOutput.print("已更新 .gitattributes 文件", OutputType.SUCCESS)
|
348
369
|
else:
|
349
|
-
PrettyOutput.print(
|
370
|
+
PrettyOutput.print(
|
371
|
+
"跳过 .gitattributes 文件创建。如遇换行符问题,可手动创建此文件。",
|
372
|
+
OutputType.INFO,
|
373
|
+
)
|
350
374
|
|
351
375
|
def _record_code_changes_stats(self, diff_text: str) -> None:
|
352
376
|
"""记录代码变更的统计信息。
|
@@ -87,7 +87,6 @@ class GitCommitTool:
|
|
87
87
|
["git", "add", "."], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL
|
88
88
|
).wait()
|
89
89
|
|
90
|
-
|
91
90
|
def execute(self, args: Dict) -> Dict[str, Any]:
|
92
91
|
"""Execute automatic commit process with support for multi-line messages and special characters"""
|
93
92
|
try:
|
@@ -107,7 +106,6 @@ class GitCommitTool:
|
|
107
106
|
if not has_uncommitted_changes():
|
108
107
|
return {"success": True, "stdout": "No changes to commit", "stderr": ""}
|
109
108
|
|
110
|
-
|
111
109
|
self._stage_changes()
|
112
110
|
|
113
111
|
# 获取差异
|
@@ -299,7 +297,6 @@ commit信息
|
|
299
297
|
"""
|
300
298
|
commit_message = platform.chat_until_success(prompt)
|
301
299
|
|
302
|
-
|
303
300
|
# 执行提交
|
304
301
|
|
305
302
|
# Windows 兼容性:使用 delete=False 避免权限错误
|
@@ -309,7 +306,6 @@ commit信息
|
|
309
306
|
tmp_file.write(commit_message)
|
310
307
|
tmp_file.close() # Windows 需要先关闭文件才能被其他进程读取
|
311
308
|
|
312
|
-
|
313
309
|
commit_cmd = ["git", "commit", "-F", tmp_file_path]
|
314
310
|
process = subprocess.Popen(
|
315
311
|
commit_cmd,
|
@@ -327,7 +323,6 @@ commit信息
|
|
327
323
|
)
|
328
324
|
raise Exception(f"Git commit failed: {error_msg}")
|
329
325
|
|
330
|
-
|
331
326
|
finally:
|
332
327
|
# 手动删除临时文件
|
333
328
|
try:
|
@@ -345,7 +340,9 @@ commit信息
|
|
345
340
|
try:
|
346
341
|
os.unlink(temp_diff_file_path)
|
347
342
|
except Exception as e:
|
348
|
-
PrettyOutput.print(
|
343
|
+
PrettyOutput.print(
|
344
|
+
f"无法删除临时文件: {str(e)}", OutputType.WARNING
|
345
|
+
)
|
349
346
|
|
350
347
|
PrettyOutput.print(
|
351
348
|
f"提交哈希: {commit_hash}\n提交消息: {commit_message}",
|
{jarvis_ai_assistant-0.3.20 → jarvis_ai_assistant-0.3.22}/src/jarvis/jarvis_mcp/sse_mcp_client.py
RENAMED
@@ -50,8 +50,12 @@ class SSEMcpClient(McpClient):
|
|
50
50
|
self.sse_thread: Optional[threading.Thread] = None
|
51
51
|
self.messages_endpoint: Optional[str] = None
|
52
52
|
self.session_id: Optional[str] = None
|
53
|
-
self.pending_requests: Dict[str, threading.Event] =
|
54
|
-
|
53
|
+
self.pending_requests: Dict[str, threading.Event] = (
|
54
|
+
{}
|
55
|
+
) # 存储等待响应的请求 {id: Event}
|
56
|
+
self.request_results: Dict[str, Dict[str, Any]] = (
|
57
|
+
{}
|
58
|
+
) # 存储请求结果 {id: result}
|
55
59
|
self.notification_handlers: Dict[str, List[Callable]] = {}
|
56
60
|
self.event_lock = threading.Lock()
|
57
61
|
self.request_id_counter = 0
|
@@ -95,7 +99,9 @@ class SSEMcpClient(McpClient):
|
|
95
99
|
|
96
100
|
# 验证服务器响应
|
97
101
|
if "result" not in response:
|
98
|
-
raise RuntimeError(
|
102
|
+
raise RuntimeError(
|
103
|
+
f"初始化失败: {response.get('error', 'Unknown error')}"
|
104
|
+
)
|
99
105
|
|
100
106
|
# 发送initialized通知
|
101
107
|
self._send_notification("notifications/initialized", {})
|