jarvis-ai-assistant 0.5.0__tar.gz → 0.5.1__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.5.0/src/jarvis_ai_assistant.egg-info → jarvis_ai_assistant-0.5.1}/PKG-INFO +1 -1
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/pyproject.toml +4 -1
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/setup.py +3 -1
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/__init__.py +1 -1
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_agent/__init__.py +102 -5
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_agent/jarvis.py +6 -0
- jarvis_ai_assistant-0.5.1/src/jarvis/jarvis_agent/task_planner.py +218 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_code_agent/code_agent.py +8 -1
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_data/config_schema.json +6 -1
- jarvis_ai_assistant-0.5.1/src/jarvis/jarvis_sec/README.md +180 -0
- jarvis_ai_assistant-0.5.1/src/jarvis/jarvis_sec/__init__.py +674 -0
- jarvis_ai_assistant-0.5.1/src/jarvis/jarvis_sec/checkers/__init__.py +33 -0
- jarvis_ai_assistant-0.5.1/src/jarvis/jarvis_sec/checkers/c_checker.py +1269 -0
- jarvis_ai_assistant-0.5.1/src/jarvis/jarvis_sec/checkers/rust_checker.py +367 -0
- jarvis_ai_assistant-0.5.1/src/jarvis/jarvis_sec/cli.py +110 -0
- jarvis_ai_assistant-0.5.1/src/jarvis/jarvis_sec/prompts.py +324 -0
- jarvis_ai_assistant-0.5.1/src/jarvis/jarvis_sec/report.py +260 -0
- jarvis_ai_assistant-0.5.1/src/jarvis/jarvis_sec/types.py +20 -0
- jarvis_ai_assistant-0.5.1/src/jarvis/jarvis_sec/workflow.py +513 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_tools/sub_agent.py +4 -3
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_tools/sub_code_agent.py +3 -3
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_utils/config.py +14 -2
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_utils/utils.py +137 -2
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1/src/jarvis_ai_assistant.egg-info}/PKG-INFO +1 -1
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis_ai_assistant.egg-info/SOURCES.txt +11 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis_ai_assistant.egg-info/entry_points.txt +2 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/LICENSE +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/MANIFEST.in +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/README.md +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/setup.cfg +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_agent/agent_manager.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_agent/builtin_input_handler.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_agent/config_editor.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_agent/edit_file_handler.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_agent/event_bus.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_agent/events.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_agent/file_context_handler.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_agent/file_methodology_manager.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_agent/main.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_agent/memory_manager.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_agent/methodology_share_manager.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_agent/output_handler.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_agent/prompt_builder.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_agent/prompt_manager.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_agent/prompts.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_agent/protocols.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_agent/rewrite_file_handler.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_agent/run_loop.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_agent/session_manager.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_agent/share_manager.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_agent/shell_input_handler.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_agent/stdio_redirect.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_agent/task_analyzer.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_agent/task_manager.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_agent/tool_executor.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_agent/tool_share_manager.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_agent/user_interaction.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_agent/utils.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_agent/web_bridge.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_agent/web_output_sink.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_agent/web_server.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_code_agent/__init__.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_code_agent/lint.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_code_analysis/checklists/__init__.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_code_analysis/checklists/c_cpp.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_code_analysis/checklists/csharp.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_code_analysis/checklists/data_format.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_code_analysis/checklists/devops.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_code_analysis/checklists/docs.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_code_analysis/checklists/go.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_code_analysis/checklists/infrastructure.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_code_analysis/checklists/java.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_code_analysis/checklists/javascript.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_code_analysis/checklists/kotlin.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_code_analysis/checklists/loader.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_code_analysis/checklists/php.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_code_analysis/checklists/python.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_code_analysis/checklists/ruby.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_code_analysis/checklists/rust.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_code_analysis/checklists/shell.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_code_analysis/checklists/sql.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_code_analysis/checklists/swift.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_code_analysis/checklists/web.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_code_analysis/code_review.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_data/tiktoken/9b5ad71b2ce5302211f9c61530b329a4922fc6a4 +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_git_squash/__init__.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_git_squash/main.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_git_utils/git_commiter.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_mcp/__init__.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_mcp/sse_mcp_client.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_mcp/stdio_mcp_client.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_mcp/streamable_mcp_client.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_memory_organizer/__init__.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_memory_organizer/memory_organizer.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_methodology/main.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_multi_agent/__init__.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_multi_agent/main.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_platform/__init__.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_platform/ai8.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_platform/base.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_platform/human.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_platform/kimi.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_platform/openai.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_platform/registry.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_platform/tongyi.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_platform/yuanbao.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_platform_manager/__init__.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_platform_manager/main.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_platform_manager/service.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_rag/__init__.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_rag/cache.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_rag/cli.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_rag/embedding_manager.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_rag/llm_interface.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_rag/query_rewriter.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_rag/rag_pipeline.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_rag/reranker.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_rag/retriever.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_smart_shell/__init__.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_smart_shell/main.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_stats/__init__.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_stats/cli.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_stats/stats.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_stats/storage.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_stats/visualizer.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_tools/__init__.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_tools/ask_user.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_tools/base.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_tools/clear_memory.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_tools/cli/__init__.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_tools/cli/main.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_tools/execute_script.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_tools/file_analyzer.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_tools/generate_new_tool.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_tools/methodology.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_tools/read_code.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_tools/read_webpage.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_tools/registry.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_tools/retrieve_memory.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_tools/save_memory.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_tools/search_web.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_tools/virtual_tty.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_utils/__init__.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_utils/builtin_replace_map.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_utils/clipboard.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_utils/embedding.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_utils/file_processors.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_utils/fzf.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_utils/git_utils.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_utils/globals.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_utils/http.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_utils/input.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_utils/methodology.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_utils/output.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_utils/tag.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis_ai_assistant.egg-info/dependency_links.txt +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis_ai_assistant.egg-info/requires.txt +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis_ai_assistant.egg-info/top_level.txt +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "jarvis-ai-assistant"
|
|
7
|
-
version = "0.5.
|
|
7
|
+
version = "0.5.1"
|
|
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" }]
|
|
@@ -96,6 +96,9 @@ jarvis-rag = "jarvis.jarvis_rag.cli:main"
|
|
|
96
96
|
jrg = "jarvis.jarvis_rag.cli:main"
|
|
97
97
|
jarvis-stats = "jarvis.jarvis_stats.cli:main"
|
|
98
98
|
jst = "jarvis.jarvis_stats.cli:main"
|
|
99
|
+
jarvis-sec = "jarvis.jarvis_sec.cli:main"
|
|
100
|
+
jsec = "jarvis.jarvis_sec.cli:main"
|
|
101
|
+
|
|
99
102
|
|
|
100
103
|
|
|
101
104
|
|
|
@@ -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.5.
|
|
6
|
+
version="0.5.1",
|
|
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",
|
|
@@ -84,6 +84,8 @@ setup(
|
|
|
84
84
|
"jrg=jarvis.jarvis_rag.cli:main",
|
|
85
85
|
"jarvis-stats=jarvis.jarvis_stats.cli:main",
|
|
86
86
|
"jst=jarvis.jarvis_stats.cli:main",
|
|
87
|
+
"jarvis-sec=jarvis.jarvis_sec.cli:main",
|
|
88
|
+
"jsec=jarvis.jarvis_sec.cli:main",
|
|
87
89
|
],
|
|
88
90
|
},
|
|
89
91
|
python_requires=">=3.9,<3.13",
|
|
@@ -25,6 +25,7 @@ from jarvis.jarvis_agent.tool_executor import execute_tool_call
|
|
|
25
25
|
from jarvis.jarvis_agent.memory_manager import MemoryManager
|
|
26
26
|
from jarvis.jarvis_memory_organizer.memory_organizer import MemoryOrganizer
|
|
27
27
|
from jarvis.jarvis_agent.task_analyzer import TaskAnalyzer
|
|
28
|
+
from jarvis.jarvis_agent.task_planner import TaskPlanner
|
|
28
29
|
from jarvis.jarvis_agent.file_methodology_manager import FileMethodologyManager
|
|
29
30
|
from jarvis.jarvis_agent.prompts import (
|
|
30
31
|
DEFAULT_SUMMARY_PROMPT,
|
|
@@ -75,8 +76,7 @@ from jarvis.jarvis_utils.config import (
|
|
|
75
76
|
is_use_methodology,
|
|
76
77
|
get_tool_filter_threshold,
|
|
77
78
|
get_after_tool_call_cb_dirs,
|
|
78
|
-
|
|
79
|
-
|
|
79
|
+
get_plan_max_depth,
|
|
80
80
|
)
|
|
81
81
|
from jarvis.jarvis_utils.embedding import get_context_token_count
|
|
82
82
|
from jarvis.jarvis_utils.globals import (
|
|
@@ -285,6 +285,21 @@ class Agent:
|
|
|
285
285
|
"""获取工具使用提示"""
|
|
286
286
|
return build_action_prompt(self.output_handler) # type: ignore
|
|
287
287
|
|
|
288
|
+
def __new__(cls, *args, **kwargs):
|
|
289
|
+
if kwargs.get("agent_type") == "code":
|
|
290
|
+
try:
|
|
291
|
+
from jarvis.jarvis_code_agent.code_agent import CodeAgent
|
|
292
|
+
except ImportError as e:
|
|
293
|
+
raise RuntimeError(
|
|
294
|
+
"CodeAgent could not be imported. Please ensure jarvis_code_agent is installed correctly."
|
|
295
|
+
) from e
|
|
296
|
+
|
|
297
|
+
# 移除 agent_type 避免无限循环,并传递所有其他参数
|
|
298
|
+
kwargs.pop("agent_type", None)
|
|
299
|
+
return CodeAgent(**kwargs)
|
|
300
|
+
else:
|
|
301
|
+
return super().__new__(cls)
|
|
302
|
+
|
|
288
303
|
def __init__(
|
|
289
304
|
self,
|
|
290
305
|
system_prompt: str,
|
|
@@ -306,6 +321,10 @@ class Agent:
|
|
|
306
321
|
confirm_callback: Optional[Callable[[str, bool], bool]] = None,
|
|
307
322
|
non_interactive: Optional[bool] = None,
|
|
308
323
|
in_multi_agent: Optional[bool] = None,
|
|
324
|
+
plan: bool = False,
|
|
325
|
+
plan_max_depth: Optional[int] = None,
|
|
326
|
+
plan_depth: int = 0,
|
|
327
|
+
agent_type: str = "normal",
|
|
309
328
|
**kwargs,
|
|
310
329
|
):
|
|
311
330
|
"""初始化Jarvis Agent实例
|
|
@@ -325,6 +344,9 @@ class Agent:
|
|
|
325
344
|
force_save_memory: 是否强制保存记忆
|
|
326
345
|
confirm_callback: 用户确认回调函数,签名为 (tip: str, default: bool) -> bool;默认使用CLI的user_confirm
|
|
327
346
|
non_interactive: 是否以非交互模式运行(优先级最高,覆盖环境变量与配置)
|
|
347
|
+
plan: 是否启用任务规划与子任务拆分(默认 False;启用后在进入主循环前评估是否需要将任务拆分为 <SUB_TASK> 列表,逐一由子Agent执行并汇总结果)
|
|
348
|
+
plan_max_depth: 任务规划的最大层数(默认3,可通过配置 JARVIS_PLAN_MAX_DEPTH 或入参覆盖)
|
|
349
|
+
plan_depth: 当前规划层数(内部用于递归控制,子Agent会在父基础上+1)
|
|
328
350
|
"""
|
|
329
351
|
# 基础属性初始化(仅根据入参设置原始值;实际生效的默认回退在 _init_config 中统一解析)
|
|
330
352
|
# 标识与描述
|
|
@@ -348,6 +370,18 @@ class Agent:
|
|
|
348
370
|
self.non_interactive = non_interactive
|
|
349
371
|
# 多智能体运行标志:用于控制非交互模式下的自动完成行为
|
|
350
372
|
self.in_multi_agent = bool(in_multi_agent)
|
|
373
|
+
self.plan = bool(plan)
|
|
374
|
+
# 规划深度与上限
|
|
375
|
+
try:
|
|
376
|
+
self.plan_max_depth = (
|
|
377
|
+
int(plan_max_depth) if plan_max_depth is not None else int(get_plan_max_depth())
|
|
378
|
+
)
|
|
379
|
+
except Exception:
|
|
380
|
+
self.plan_max_depth = 2
|
|
381
|
+
try:
|
|
382
|
+
self.plan_depth = int(plan_depth)
|
|
383
|
+
except Exception:
|
|
384
|
+
self.plan_depth = 0
|
|
351
385
|
# 运行时状态
|
|
352
386
|
self.first = True
|
|
353
387
|
self.run_input_handlers_next_turn = False
|
|
@@ -429,6 +463,8 @@ class Agent:
|
|
|
429
463
|
self.task_analyzer = TaskAnalyzer(self)
|
|
430
464
|
self.file_methodology_manager = FileMethodologyManager(self)
|
|
431
465
|
self.prompt_manager = PromptManager(self)
|
|
466
|
+
# 任务规划器:封装规划与子任务调度逻辑
|
|
467
|
+
self.task_planner = TaskPlanner(self, plan_depth=self.plan_depth, plan_max_depth=self.plan_max_depth)
|
|
432
468
|
|
|
433
469
|
# 设置系统提示词
|
|
434
470
|
self._setup_system_prompt()
|
|
@@ -801,9 +837,14 @@ class Agent:
|
|
|
801
837
|
try:
|
|
802
838
|
if not self.model:
|
|
803
839
|
raise RuntimeError("Model not initialized")
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
)
|
|
840
|
+
# 优先使用外部传入的 summary_prompt;如为空则回退到默认的会话摘要请求
|
|
841
|
+
safe_summary_prompt = self.summary_prompt or ""
|
|
842
|
+
if isinstance(safe_summary_prompt, str) and safe_summary_prompt.strip() != "":
|
|
843
|
+
prompt_to_use = safe_summary_prompt
|
|
844
|
+
else:
|
|
845
|
+
prompt_to_use = self.session.prompt + "\n" + SUMMARY_REQUEST_PROMPT
|
|
846
|
+
|
|
847
|
+
summary = self.model.chat_until_success(prompt_to_use) # type: ignore
|
|
807
848
|
# 防御: 可能返回空响应(None或空字符串),统一为空字符串并告警
|
|
808
849
|
if not summary:
|
|
809
850
|
try:
|
|
@@ -1057,6 +1098,13 @@ class Agent:
|
|
|
1057
1098
|
)
|
|
1058
1099
|
except Exception:
|
|
1059
1100
|
pass
|
|
1101
|
+
# 如启用规划模式,先判断是否需要拆分并调度子任务
|
|
1102
|
+
if self.plan:
|
|
1103
|
+
try:
|
|
1104
|
+
self._maybe_plan_and_dispatch(self.session.prompt)
|
|
1105
|
+
except Exception:
|
|
1106
|
+
# 防御式处理,规划失败不影响主流程
|
|
1107
|
+
pass
|
|
1060
1108
|
return self._main_loop()
|
|
1061
1109
|
except Exception as e:
|
|
1062
1110
|
PrettyOutput.print(f"任务失败: {str(e)}", OutputType.ERROR)
|
|
@@ -1164,6 +1212,55 @@ class Agent:
|
|
|
1164
1212
|
temp_model.set_system_prompt(system_prompt)
|
|
1165
1213
|
return temp_model
|
|
1166
1214
|
|
|
1215
|
+
def _build_child_agent_params(self, name: str, description: str) -> Dict[str, Any]:
|
|
1216
|
+
"""构建子Agent参数,尽量继承父Agent配置,并确保子Agent非交互自动完成。"""
|
|
1217
|
+
use_tools_param: Optional[List[str]] = None
|
|
1218
|
+
try:
|
|
1219
|
+
tr = self.get_tool_registry()
|
|
1220
|
+
if isinstance(tr, ToolRegistry):
|
|
1221
|
+
selected_tools = tr.get_all_tools()
|
|
1222
|
+
use_tools_param = [t["name"] for t in selected_tools]
|
|
1223
|
+
except Exception:
|
|
1224
|
+
use_tools_param = None
|
|
1225
|
+
|
|
1226
|
+
return {
|
|
1227
|
+
"system_prompt": origin_agent_system_prompt,
|
|
1228
|
+
"name": name,
|
|
1229
|
+
"description": description,
|
|
1230
|
+
"model_group": self.model_group,
|
|
1231
|
+
"summary_prompt": self.summary_prompt,
|
|
1232
|
+
"auto_complete": True,
|
|
1233
|
+
"use_tools": use_tools_param,
|
|
1234
|
+
"execute_tool_confirm": self.execute_tool_confirm,
|
|
1235
|
+
"need_summary": self.need_summary,
|
|
1236
|
+
"auto_summary_rounds": self.auto_summary_rounds,
|
|
1237
|
+
"multiline_inputer": self.multiline_inputer,
|
|
1238
|
+
"use_methodology": self.use_methodology,
|
|
1239
|
+
"use_analysis": self.use_analysis,
|
|
1240
|
+
"force_save_memory": self.force_save_memory,
|
|
1241
|
+
"files": self.files,
|
|
1242
|
+
"confirm_callback": self.confirm_callback,
|
|
1243
|
+
"non_interactive": True,
|
|
1244
|
+
"in_multi_agent": True,
|
|
1245
|
+
"plan": self.plan, # 继承父Agent的规划开关
|
|
1246
|
+
"plan_depth": self.plan_depth + 1, # 子Agent层数+1
|
|
1247
|
+
"plan_max_depth": self.plan_max_depth, # 继承上限
|
|
1248
|
+
}
|
|
1249
|
+
|
|
1250
|
+
def _maybe_plan_and_dispatch(self, task_text: str) -> None:
|
|
1251
|
+
"""委托给 TaskPlanner 执行任务规划与子任务调度,保持向后兼容。"""
|
|
1252
|
+
try:
|
|
1253
|
+
if hasattr(self, "task_planner") and self.task_planner:
|
|
1254
|
+
# 优先使用初始化时注入的规划器
|
|
1255
|
+
self.task_planner.maybe_plan_and_dispatch(task_text) # type: ignore[attr-defined]
|
|
1256
|
+
else:
|
|
1257
|
+
# 防御式回退:临时创建规划器以避免因未初始化导致的崩溃
|
|
1258
|
+
from jarvis.jarvis_agent.task_planner import TaskPlanner
|
|
1259
|
+
TaskPlanner(self, plan_depth=self.plan_depth, plan_max_depth=self.plan_max_depth).maybe_plan_and_dispatch(task_text)
|
|
1260
|
+
except Exception:
|
|
1261
|
+
# 规划失败不影响主流程
|
|
1262
|
+
pass
|
|
1263
|
+
|
|
1167
1264
|
def _filter_tools_if_needed(self, task: str):
|
|
1168
1265
|
"""如果工具数量超过阈值,使用大模型筛选相关工具"""
|
|
1169
1266
|
tool_registry = self.get_tool_registry()
|
|
@@ -681,6 +681,7 @@ def run_cli(
|
|
|
681
681
|
non_interactive: bool = typer.Option(
|
|
682
682
|
False, "-n", "--non-interactive", help="启用非交互模式:用户无法与命令交互,脚本执行超时限制为5分钟"
|
|
683
683
|
),
|
|
684
|
+
plan: bool = typer.Option(False, "--plan/--no-plan", help="启用或禁用任务规划(拆分子任务并汇总执行结果)"),
|
|
684
685
|
web: bool = typer.Option(False, "--web", help="以 Web 模式启动,通过浏览器 WebSocket 交互"),
|
|
685
686
|
web_host: str = typer.Option("127.0.0.1", "--web-host", help="Web 服务主机"),
|
|
686
687
|
web_port: int = typer.Option(8765, "--web-port", help="Web 服务端口"),
|
|
@@ -1022,6 +1023,11 @@ def run_cli(
|
|
|
1022
1023
|
**extra_kwargs,
|
|
1023
1024
|
)
|
|
1024
1025
|
agent = agent_manager.initialize()
|
|
1026
|
+
# CLI 开关:启用/禁用规划(不依赖 AgentManager 支持,直接设置 Agent 属性)
|
|
1027
|
+
try:
|
|
1028
|
+
agent.plan = bool(plan)
|
|
1029
|
+
except Exception:
|
|
1030
|
+
pass
|
|
1025
1031
|
|
|
1026
1032
|
if web:
|
|
1027
1033
|
try:
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
TaskPlanner: 任务规划与子任务调度器
|
|
4
|
+
|
|
5
|
+
职责:
|
|
6
|
+
- 判断是否需要拆分任务
|
|
7
|
+
- 解析 <PLAN> YAML 列表
|
|
8
|
+
- 为每个子任务创建子Agent并执行
|
|
9
|
+
- 汇总所有子任务执行结果并写回父Agent上下文(包含 <PLAN>/<SUB_TASK_RESULTS>/<RESULT_SUMMARY>)
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from typing import Any, List
|
|
13
|
+
import re
|
|
14
|
+
|
|
15
|
+
import yaml # type: ignore
|
|
16
|
+
|
|
17
|
+
from jarvis.jarvis_agent.utils import join_prompts
|
|
18
|
+
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class TaskPlanner:
|
|
22
|
+
"""将 Agent 的任务规划逻辑封装为独立类,便于维护与复用。"""
|
|
23
|
+
|
|
24
|
+
def __init__(self, agent: Any, plan_depth: int = 0, plan_max_depth: int = 2) -> None:
|
|
25
|
+
"""
|
|
26
|
+
参数:
|
|
27
|
+
agent: 父Agent实例(须提供以下能力)
|
|
28
|
+
- _create_temp_model(system_prompt: str) -> BasePlatform
|
|
29
|
+
- _build_child_agent_params(name: str, description: str) -> dict
|
|
30
|
+
- name, session, plan 等属性
|
|
31
|
+
plan_depth: 当前规划深度(由外部在构造时传入)
|
|
32
|
+
plan_max_depth: 规划最大深度(由外部在构造时传入)
|
|
33
|
+
"""
|
|
34
|
+
self.agent = agent
|
|
35
|
+
try:
|
|
36
|
+
self.plan_depth = int(plan_depth)
|
|
37
|
+
except Exception:
|
|
38
|
+
self.plan_depth = 0
|
|
39
|
+
try:
|
|
40
|
+
self.plan_max_depth = int(plan_max_depth)
|
|
41
|
+
except Exception:
|
|
42
|
+
self.plan_max_depth = 2
|
|
43
|
+
|
|
44
|
+
def maybe_plan_and_dispatch(self, task_text: str) -> None:
|
|
45
|
+
"""
|
|
46
|
+
当启用 agent.plan 时,调用临时模型评估是否需要拆分任务并执行子任务。
|
|
47
|
+
- 若模型返回 <DONT_NEED/>,则直接返回不做任何修改;
|
|
48
|
+
- 若返回 <SUB_TASK> 块,则解析每行以“- ”开头的子任务,逐个创建子Agent执行;
|
|
49
|
+
- 将子任务与结果以结构化块写回到 agent.session.prompt,随后由主循环继续处理。
|
|
50
|
+
"""
|
|
51
|
+
if not getattr(self.agent, "plan", False):
|
|
52
|
+
return
|
|
53
|
+
|
|
54
|
+
# 深度限制检查:当当前规划深度已达到或超过上限时,禁止继续规划
|
|
55
|
+
try:
|
|
56
|
+
current_depth = int(self.plan_depth)
|
|
57
|
+
except Exception:
|
|
58
|
+
current_depth = 0
|
|
59
|
+
try:
|
|
60
|
+
max_depth = int(self.plan_max_depth)
|
|
61
|
+
except Exception:
|
|
62
|
+
max_depth = 2
|
|
63
|
+
|
|
64
|
+
if current_depth >= max_depth:
|
|
65
|
+
PrettyOutput.print(
|
|
66
|
+
f"已达到任务规划最大深度({max_depth}),本层不再进行规划。", OutputType.INFO
|
|
67
|
+
)
|
|
68
|
+
return
|
|
69
|
+
|
|
70
|
+
try:
|
|
71
|
+
PrettyOutput.print("任务规划启动,评估是否需要拆分...", OutputType.INFO)
|
|
72
|
+
planning_sys = (
|
|
73
|
+
"你是一个任务规划助手。请判断是否需要拆分任务。\n"
|
|
74
|
+
"当需要拆分时,仅按以下结构输出:\n"
|
|
75
|
+
"<PLAN>\n- 子任务1\n- 子任务2\n</PLAN>\n"
|
|
76
|
+
"示例:\n"
|
|
77
|
+
"<PLAN>\n- 分析当前任务,提取需要修改的文件列表\n- 修改配置默认值并更新相关 schema\n- 更新文档中对该默认值的描述\n</PLAN>\n"
|
|
78
|
+
"要求:<PLAN> 内必须是有效 YAML 列表,仅包含字符串项;禁止输出任何额外解释。\n"
|
|
79
|
+
"当不需要拆分时,仅输出:\n<DONT_NEED/>\n"
|
|
80
|
+
"禁止输出任何额外解释。"
|
|
81
|
+
)
|
|
82
|
+
temp_model = self.agent._create_temp_model(planning_sys)
|
|
83
|
+
plan_prompt = f"任务:\n{task_text}\n\n请严格按要求只输出结构化标签块。"
|
|
84
|
+
plan_resp = temp_model.chat_until_success(plan_prompt) # type: ignore
|
|
85
|
+
if not plan_resp:
|
|
86
|
+
PrettyOutput.print("任务规划模型未返回有效响应。", OutputType.WARNING)
|
|
87
|
+
return
|
|
88
|
+
except Exception as e:
|
|
89
|
+
# 规划失败不影响主流程
|
|
90
|
+
PrettyOutput.print(f"任务规划失败: {e}", OutputType.ERROR)
|
|
91
|
+
return
|
|
92
|
+
|
|
93
|
+
text = str(plan_resp).strip()
|
|
94
|
+
# 不需要拆分
|
|
95
|
+
if re.search(r"<\s*DONT_NEED\s*/\s*>", text, re.IGNORECASE):
|
|
96
|
+
PrettyOutput.print("任务规划完成:无需拆分。", OutputType.SUCCESS)
|
|
97
|
+
return
|
|
98
|
+
|
|
99
|
+
# 解析 <SUB_TASK> 块
|
|
100
|
+
m = re.search(
|
|
101
|
+
r"<\s*PLAN\s*>\s*(.*?)\s*<\s*/\s*PLAN\s*>",
|
|
102
|
+
text,
|
|
103
|
+
re.IGNORECASE | re.DOTALL,
|
|
104
|
+
)
|
|
105
|
+
subtasks: List[str] = []
|
|
106
|
+
if m:
|
|
107
|
+
block = m.group(1)
|
|
108
|
+
try:
|
|
109
|
+
data = yaml.safe_load(block)
|
|
110
|
+
if isinstance(data, list):
|
|
111
|
+
for item in data:
|
|
112
|
+
if isinstance(item, str):
|
|
113
|
+
s = item.strip()
|
|
114
|
+
if s:
|
|
115
|
+
subtasks.append(s)
|
|
116
|
+
else:
|
|
117
|
+
PrettyOutput.print("任务规划提示:无需拆分。", OutputType.INFO)
|
|
118
|
+
except Exception as e:
|
|
119
|
+
PrettyOutput.print("任务规划提示:无需拆分。", OutputType.INFO)
|
|
120
|
+
else:
|
|
121
|
+
PrettyOutput.print("任务规划提示:无需拆分。", OutputType.INFO)
|
|
122
|
+
|
|
123
|
+
if not subtasks:
|
|
124
|
+
# 无有效子任务,直接返回
|
|
125
|
+
PrettyOutput.print("任务规划提示:无需拆分。", OutputType.INFO)
|
|
126
|
+
return
|
|
127
|
+
|
|
128
|
+
PrettyOutput.print(f"任务已拆分为 {len(subtasks)} 个子任务:", OutputType.SUCCESS)
|
|
129
|
+
for i, st in enumerate(subtasks, 1):
|
|
130
|
+
PrettyOutput.print(f" {i}. {st}", OutputType.INFO)
|
|
131
|
+
|
|
132
|
+
# 执行子任务
|
|
133
|
+
executed_subtask_block_lines: List[str] = ["<PLAN>"]
|
|
134
|
+
executed_subtask_block_lines += [f"- {t}" for t in subtasks]
|
|
135
|
+
executed_subtask_block_lines.append("</PLAN>")
|
|
136
|
+
|
|
137
|
+
results_lines: List[str] = []
|
|
138
|
+
for i, st in enumerate(subtasks, 1):
|
|
139
|
+
try:
|
|
140
|
+
PrettyOutput.print(f"开始执行子任务 {i}/{len(subtasks)}: {st}", OutputType.INFO)
|
|
141
|
+
child_kwargs = self.agent._build_child_agent_params(
|
|
142
|
+
name=f"{self.agent.name}-child-{i}",
|
|
143
|
+
description=f"子任务执行器: {st}",
|
|
144
|
+
)
|
|
145
|
+
# 使用父Agent的类创建子Agent,避免循环依赖
|
|
146
|
+
child = self.agent.__class__(**child_kwargs)
|
|
147
|
+
# 构造子任务执行提示,包含父任务与前置子任务结果,避免背景缺失
|
|
148
|
+
subtask_block_text = "\n".join(executed_subtask_block_lines)
|
|
149
|
+
if results_lines:
|
|
150
|
+
prev_results_block = "<PREVIOUS_SUB_TASK_RESULTS>\n" + "\n".join(results_lines) + "\n</PREVIOUS_SUB_TASK_RESULTS>"
|
|
151
|
+
else:
|
|
152
|
+
prev_results_block = "<PREVIOUS_SUB_TASK_RESULTS />"
|
|
153
|
+
child_prompt = join_prompts([
|
|
154
|
+
f"原始任务:\n{task_text}",
|
|
155
|
+
f"子任务规划:\n{subtask_block_text}",
|
|
156
|
+
f"前置子任务执行结果:\n{prev_results_block}",
|
|
157
|
+
f"当前子任务:{st}",
|
|
158
|
+
"请基于原始任务背景与前置结果执行当前子任务,避免重复工作;如需依赖前置产物请直接复用;如需为后续子任务提供数据,请妥善保存(可使用工具保存文件或记忆)。"
|
|
159
|
+
])
|
|
160
|
+
child_result = child.run(child_prompt)
|
|
161
|
+
result_text = "" if child_result is None else str(child_result)
|
|
162
|
+
# 防止极端长输出导致污染,这里不做截断,交由上层摘要策略控制
|
|
163
|
+
results_lines.append(f"- 子任务{i}: {st}\n 结果: {result_text}")
|
|
164
|
+
PrettyOutput.print(f"子任务 {i}/{len(subtasks)} 执行完成。", OutputType.SUCCESS)
|
|
165
|
+
except Exception as e:
|
|
166
|
+
results_lines.append(f"- 子任务{i}: {st}\n 结果: 执行失败,原因: {e}")
|
|
167
|
+
PrettyOutput.print(f"子任务 {i}/{len(subtasks)} 执行失败: {e}", OutputType.ERROR)
|
|
168
|
+
|
|
169
|
+
subtask_block = "\n".join(executed_subtask_block_lines)
|
|
170
|
+
results_block = "<SUB_TASK_RESULTS>\n" + "\n".join(results_lines) + "\n</SUB_TASK_RESULTS>"
|
|
171
|
+
|
|
172
|
+
PrettyOutput.print("所有子任务执行完毕,正在整合结果...", OutputType.INFO)
|
|
173
|
+
# 先对所有子任务结果进行简要自动汇总,便于父Agent继续整合
|
|
174
|
+
summary_block = "<RESULT_SUMMARY>\n无摘要(将直接使用结果详情继续)\n</RESULT_SUMMARY>"
|
|
175
|
+
try:
|
|
176
|
+
summarizing_sys = (
|
|
177
|
+
"你是一个任务结果整合助手。请根据提供的原始任务、子任务清单与子任务执行结果,"
|
|
178
|
+
"生成简明扼要的汇总与关键结论,突出已完成项、遗留风险与下一步建议。"
|
|
179
|
+
"严格仅输出以下结构:\n"
|
|
180
|
+
"<RESULT_SUMMARY>\n"
|
|
181
|
+
"…你的简要汇总…\n"
|
|
182
|
+
"</RESULT_SUMMARY>\n"
|
|
183
|
+
"不要输出其他任何解释。"
|
|
184
|
+
)
|
|
185
|
+
temp_model2 = self.agent._create_temp_model(summarizing_sys)
|
|
186
|
+
sum_prompt = (
|
|
187
|
+
f"原始任务:\n{task_text}\n\n"
|
|
188
|
+
f"子任务规划:\n{subtask_block}\n\n"
|
|
189
|
+
f"子任务执行结果:\n{results_block}\n\n"
|
|
190
|
+
"请按要求仅输出汇总块。"
|
|
191
|
+
)
|
|
192
|
+
sum_resp = temp_model2.chat_until_success(sum_prompt) # type: ignore
|
|
193
|
+
if isinstance(sum_resp, str) and sum_resp.strip():
|
|
194
|
+
s = sum_resp.strip()
|
|
195
|
+
if not re.search(r"<\s*RESULT_SUMMARY\s*>", s, re.IGNORECASE):
|
|
196
|
+
s = f"<RESULT_SUMMARY>\n{s}\n</RESULT_SUMMARY>"
|
|
197
|
+
summary_block = s
|
|
198
|
+
except Exception:
|
|
199
|
+
# 汇总失败不影响主流程,继续使用默认占位
|
|
200
|
+
pass
|
|
201
|
+
|
|
202
|
+
# 合并回父Agent的 prompt,父Agent将基于汇总与详情继续执行
|
|
203
|
+
try:
|
|
204
|
+
self.agent.session.prompt = join_prompts(
|
|
205
|
+
[
|
|
206
|
+
f"原始任务:\n{task_text}",
|
|
207
|
+
f"子任务规划:\n{subtask_block}",
|
|
208
|
+
f"子任务结果汇总:\n{summary_block}",
|
|
209
|
+
f"子任务执行结果:\n{results_block}",
|
|
210
|
+
"请基于上述子任务结果整合并完成最终输出。",
|
|
211
|
+
]
|
|
212
|
+
)
|
|
213
|
+
except Exception:
|
|
214
|
+
# 回退拼接
|
|
215
|
+
self.agent.session.prompt = (
|
|
216
|
+
f"{task_text}\n\n{subtask_block}\n\n{summary_block}\n\n{results_block}\n\n"
|
|
217
|
+
"请基于上述子任务结果整合并完成最终输出。"
|
|
218
|
+
)
|
{jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_code_agent/code_agent.py
RENAMED
|
@@ -40,7 +40,7 @@ from jarvis.jarvis_utils.git_utils import (
|
|
|
40
40
|
)
|
|
41
41
|
from jarvis.jarvis_utils.input import get_multiline_input, user_confirm
|
|
42
42
|
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
43
|
-
from jarvis.jarvis_utils.utils import get_loc_stats, init_env
|
|
43
|
+
from jarvis.jarvis_utils.utils import get_loc_stats, init_env, _acquire_single_instance_lock
|
|
44
44
|
|
|
45
45
|
app = typer.Typer(help="Jarvis 代码助手")
|
|
46
46
|
|
|
@@ -58,6 +58,8 @@ class CodeAgent:
|
|
|
58
58
|
append_tools: Optional[str] = None,
|
|
59
59
|
tool_group: Optional[str] = None,
|
|
60
60
|
non_interactive: Optional[bool] = None,
|
|
61
|
+
plan: Optional[bool] = None,
|
|
62
|
+
**kwargs,
|
|
61
63
|
):
|
|
62
64
|
self.root_dir = os.getcwd()
|
|
63
65
|
self.tool_group = tool_group
|
|
@@ -112,6 +114,7 @@ class CodeAgent:
|
|
|
112
114
|
use_methodology=False, # 禁用方法论
|
|
113
115
|
use_analysis=False, # 禁用分析
|
|
114
116
|
non_interactive=self.non_interactive,
|
|
117
|
+
plan=bool(plan) if plan is not None else False,
|
|
115
118
|
)
|
|
116
119
|
|
|
117
120
|
self.agent.event_bus.subscribe(AFTER_TOOL_CALL, self._on_after_tool_call)
|
|
@@ -894,6 +897,7 @@ def cli(
|
|
|
894
897
|
non_interactive: bool = typer.Option(
|
|
895
898
|
False, "-n", "--non-interactive", help="启用非交互模式:用户无法与命令交互,脚本执行超时限制为5分钟"
|
|
896
899
|
),
|
|
900
|
+
plan: bool = typer.Option(False, "--plan/--no-plan", help="启用或禁用任务规划(子任务拆分与汇总执行)"),
|
|
897
901
|
) -> None:
|
|
898
902
|
"""Jarvis主入口点。"""
|
|
899
903
|
# CLI 标志:非交互模式(不依赖配置文件)
|
|
@@ -914,6 +918,8 @@ def cli(
|
|
|
914
918
|
"欢迎使用 Jarvis-CodeAgent,您的代码工程助手已准备就绪!",
|
|
915
919
|
config_file=config_file,
|
|
916
920
|
)
|
|
921
|
+
# CodeAgent 单实例互斥:仅代码助手入口加锁,其他入口不受影响
|
|
922
|
+
_acquire_single_instance_lock(lock_name="code_agent.lock")
|
|
917
923
|
|
|
918
924
|
# 在初始化环境后同步 CLI 选项到全局配置,避免被 init_env 覆盖
|
|
919
925
|
try:
|
|
@@ -973,6 +979,7 @@ def cli(
|
|
|
973
979
|
append_tools=append_tools,
|
|
974
980
|
tool_group=tool_group,
|
|
975
981
|
non_interactive=non_interactive,
|
|
982
|
+
plan=plan,
|
|
976
983
|
)
|
|
977
984
|
|
|
978
985
|
# 尝试恢复会话
|
{jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.5.1}/src/jarvis/jarvis_data/config_schema.json
RENAMED
|
@@ -188,6 +188,11 @@
|
|
|
188
188
|
"description": "AI工具筛选阈值:当可用工具数量超过此值时触发AI筛选",
|
|
189
189
|
"default": 30
|
|
190
190
|
},
|
|
191
|
+
"JARVIS_PLAN_MAX_DEPTH": {
|
|
192
|
+
"type": "number",
|
|
193
|
+
"description": "任务规划的最大层数。用于限制 plan 模式的递归拆分深度。仅在启用规划时生效(通过 CLI --plan/--no-plan 控制),默认 3。",
|
|
194
|
+
"default": 2
|
|
195
|
+
},
|
|
191
196
|
"JARVIS_SCRIPT_EXECUTION_TIMEOUT": {
|
|
192
197
|
"type": "number",
|
|
193
198
|
"description": "脚本执行的超时时间(秒),仅在非交互模式下生效。",
|
|
@@ -196,7 +201,7 @@
|
|
|
196
201
|
"JARVIS_AUTO_SUMMARY_ROUNDS": {
|
|
197
202
|
"type": "number",
|
|
198
203
|
"description": "基于对话轮次的自动总结阈值(达到该轮次后自动总结并清理历史)",
|
|
199
|
-
"default":
|
|
204
|
+
"default": 50
|
|
200
205
|
},
|
|
201
206
|
"JARVIS_CONFIRM_BEFORE_APPLY_PATCH": {
|
|
202
207
|
"type": "boolean",
|