jarvis-ai-assistant 0.5.0__tar.gz → 0.6.0__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.6.0}/PKG-INFO +13 -1
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/pyproject.toml +15 -2
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/setup.py +11 -1
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/__init__.py +1 -1
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_agent/__init__.py +114 -6
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_agent/agent_manager.py +3 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_agent/jarvis.py +45 -9
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_agent/run_loop.py +6 -1
- jarvis_ai_assistant-0.6.0/src/jarvis/jarvis_agent/task_planner.py +219 -0
- jarvis_ai_assistant-0.6.0/src/jarvis/jarvis_c2rust/__init__.py +13 -0
- jarvis_ai_assistant-0.6.0/src/jarvis/jarvis_c2rust/cli.py +405 -0
- jarvis_ai_assistant-0.6.0/src/jarvis/jarvis_c2rust/collector.py +209 -0
- jarvis_ai_assistant-0.6.0/src/jarvis/jarvis_c2rust/library_replacer.py +933 -0
- jarvis_ai_assistant-0.6.0/src/jarvis/jarvis_c2rust/llm_module_agent.py +1265 -0
- jarvis_ai_assistant-0.6.0/src/jarvis/jarvis_c2rust/scanner.py +1671 -0
- jarvis_ai_assistant-0.6.0/src/jarvis/jarvis_c2rust/transpiler.py +1236 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_code_agent/code_agent.py +151 -18
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_data/config_schema.json +13 -3
- jarvis_ai_assistant-0.6.0/src/jarvis/jarvis_sec/README.md +180 -0
- jarvis_ai_assistant-0.6.0/src/jarvis/jarvis_sec/__init__.py +674 -0
- jarvis_ai_assistant-0.6.0/src/jarvis/jarvis_sec/checkers/__init__.py +33 -0
- jarvis_ai_assistant-0.6.0/src/jarvis/jarvis_sec/checkers/c_checker.py +1269 -0
- jarvis_ai_assistant-0.6.0/src/jarvis/jarvis_sec/checkers/rust_checker.py +367 -0
- jarvis_ai_assistant-0.6.0/src/jarvis/jarvis_sec/cli.py +110 -0
- jarvis_ai_assistant-0.6.0/src/jarvis/jarvis_sec/prompts.py +324 -0
- jarvis_ai_assistant-0.6.0/src/jarvis/jarvis_sec/report.py +260 -0
- jarvis_ai_assistant-0.6.0/src/jarvis/jarvis_sec/types.py +20 -0
- jarvis_ai_assistant-0.6.0/src/jarvis/jarvis_sec/workflow.py +513 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_tools/cli/main.py +1 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_tools/execute_script.py +1 -1
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_tools/read_code.py +11 -1
- jarvis_ai_assistant-0.6.0/src/jarvis/jarvis_tools/read_symbols.py +129 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_tools/registry.py +9 -1
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_tools/sub_agent.py +4 -3
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_tools/sub_code_agent.py +3 -3
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_utils/config.py +28 -6
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_utils/git_utils.py +39 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_utils/utils.py +150 -7
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0/src/jarvis_ai_assistant.egg-info}/PKG-INFO +13 -1
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis_ai_assistant.egg-info/SOURCES.txt +19 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis_ai_assistant.egg-info/entry_points.txt +4 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis_ai_assistant.egg-info/requires.txt +18 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/LICENSE +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/MANIFEST.in +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/README.md +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/setup.cfg +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_agent/builtin_input_handler.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_agent/config_editor.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_agent/edit_file_handler.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_agent/event_bus.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_agent/events.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_agent/file_context_handler.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_agent/file_methodology_manager.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_agent/main.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_agent/memory_manager.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_agent/methodology_share_manager.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_agent/output_handler.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_agent/prompt_builder.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_agent/prompt_manager.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_agent/prompts.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_agent/protocols.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_agent/rewrite_file_handler.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_agent/session_manager.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_agent/share_manager.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_agent/shell_input_handler.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_agent/stdio_redirect.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_agent/task_analyzer.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_agent/task_manager.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_agent/tool_executor.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_agent/tool_share_manager.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_agent/user_interaction.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_agent/utils.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_agent/web_bridge.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_agent/web_output_sink.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_agent/web_server.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_code_agent/__init__.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_code_agent/lint.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_code_analysis/checklists/__init__.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_code_analysis/checklists/c_cpp.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_code_analysis/checklists/csharp.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_code_analysis/checklists/data_format.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_code_analysis/checklists/devops.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_code_analysis/checklists/docs.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_code_analysis/checklists/go.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_code_analysis/checklists/infrastructure.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_code_analysis/checklists/java.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_code_analysis/checklists/javascript.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_code_analysis/checklists/kotlin.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_code_analysis/checklists/loader.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_code_analysis/checklists/php.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_code_analysis/checklists/python.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_code_analysis/checklists/ruby.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_code_analysis/checklists/rust.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_code_analysis/checklists/shell.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_code_analysis/checklists/sql.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_code_analysis/checklists/swift.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_code_analysis/checklists/web.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_code_analysis/code_review.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_data/tiktoken/9b5ad71b2ce5302211f9c61530b329a4922fc6a4 +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_git_squash/__init__.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_git_squash/main.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_git_utils/git_commiter.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_mcp/__init__.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_mcp/sse_mcp_client.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_mcp/stdio_mcp_client.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_mcp/streamable_mcp_client.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_memory_organizer/__init__.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_memory_organizer/memory_organizer.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_methodology/main.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_multi_agent/__init__.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_multi_agent/main.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_platform/__init__.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_platform/ai8.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_platform/base.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_platform/human.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_platform/kimi.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_platform/openai.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_platform/registry.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_platform/tongyi.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_platform/yuanbao.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_platform_manager/__init__.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_platform_manager/main.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_platform_manager/service.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_rag/__init__.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_rag/cache.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_rag/cli.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_rag/embedding_manager.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_rag/llm_interface.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_rag/query_rewriter.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_rag/rag_pipeline.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_rag/reranker.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_rag/retriever.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_smart_shell/__init__.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_smart_shell/main.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_stats/__init__.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_stats/cli.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_stats/stats.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_stats/storage.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_stats/visualizer.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_tools/__init__.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_tools/ask_user.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_tools/base.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_tools/clear_memory.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_tools/cli/__init__.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_tools/file_analyzer.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_tools/generate_new_tool.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_tools/methodology.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_tools/read_webpage.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_tools/retrieve_memory.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_tools/save_memory.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_tools/search_web.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_tools/virtual_tty.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_utils/__init__.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_utils/builtin_replace_map.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_utils/clipboard.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_utils/embedding.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_utils/file_processors.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_utils/fzf.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_utils/globals.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_utils/http.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_utils/input.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_utils/methodology.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_utils/output.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_utils/tag.py +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis_ai_assistant.egg-info/dependency_links.txt +0 -0
- {jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis_ai_assistant.egg-info/top_level.txt +0 -0
{jarvis_ai_assistant-0.5.0/src/jarvis_ai_assistant.egg-info → jarvis_ai_assistant-0.6.0}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: jarvis-ai-assistant
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6.0
|
|
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
|
|
@@ -78,6 +78,18 @@ Requires-Dist: sentence-transformers==2.7.0; extra == "rag"
|
|
|
78
78
|
Requires-Dist: torch>=2.6; extra == "rag"
|
|
79
79
|
Requires-Dist: unstructured[md]; extra == "rag"
|
|
80
80
|
Requires-Dist: rank-bm25; extra == "rag"
|
|
81
|
+
Provides-Extra: clang16
|
|
82
|
+
Requires-Dist: clang==16.*; extra == "clang16"
|
|
83
|
+
Provides-Extra: clang17
|
|
84
|
+
Requires-Dist: clang==17.*; extra == "clang17"
|
|
85
|
+
Provides-Extra: clang18
|
|
86
|
+
Requires-Dist: clang==18.*; extra == "clang18"
|
|
87
|
+
Provides-Extra: clang19
|
|
88
|
+
Requires-Dist: clang==19.*; extra == "clang19"
|
|
89
|
+
Provides-Extra: clang20
|
|
90
|
+
Requires-Dist: clang==20.*; extra == "clang20"
|
|
91
|
+
Provides-Extra: clang21
|
|
92
|
+
Requires-Dist: clang==21.*; extra == "clang21"
|
|
81
93
|
Dynamic: author
|
|
82
94
|
Dynamic: home-page
|
|
83
95
|
Dynamic: license-file
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "jarvis-ai-assistant"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.6.0"
|
|
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" }]
|
|
@@ -43,7 +43,7 @@ dependencies = [
|
|
|
43
43
|
"typer",
|
|
44
44
|
"pathspec",
|
|
45
45
|
"plotext==5.2.8",
|
|
46
|
-
"packaging>=24.2"
|
|
46
|
+
"packaging>=24.2"
|
|
47
47
|
]
|
|
48
48
|
requires-python = ">=3.9,<3.13"
|
|
49
49
|
|
|
@@ -60,6 +60,12 @@ rag = [
|
|
|
60
60
|
"unstructured[md]",
|
|
61
61
|
"rank-bm25",
|
|
62
62
|
]
|
|
63
|
+
clang16 = ["clang==16.*"]
|
|
64
|
+
clang17 = ["clang==17.*"]
|
|
65
|
+
clang18 = ["clang==18.*"]
|
|
66
|
+
clang19 = ["clang==19.*"]
|
|
67
|
+
clang20 = ["clang==20.*"]
|
|
68
|
+
clang21 = ["clang==21.*"]
|
|
63
69
|
|
|
64
70
|
[project.urls]
|
|
65
71
|
Homepage = "https://github.com/skyfireitdiy/Jarvis"
|
|
@@ -96,6 +102,13 @@ jarvis-rag = "jarvis.jarvis_rag.cli:main"
|
|
|
96
102
|
jrg = "jarvis.jarvis_rag.cli:main"
|
|
97
103
|
jarvis-stats = "jarvis.jarvis_stats.cli:main"
|
|
98
104
|
jst = "jarvis.jarvis_stats.cli:main"
|
|
105
|
+
jarvis-sec = "jarvis.jarvis_sec.cli:main"
|
|
106
|
+
jsec = "jarvis.jarvis_sec.cli:main"
|
|
107
|
+
jarvis-c2rust = "jarvis.jarvis_c2rust.cli:main"
|
|
108
|
+
jc2r = "jarvis.jarvis_c2rust.cli:main"
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
|
|
99
112
|
|
|
100
113
|
|
|
101
114
|
|
|
@@ -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.
|
|
6
|
+
version="0.6.0",
|
|
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",
|
|
@@ -53,6 +53,12 @@ setup(
|
|
|
53
53
|
"rank-bm25",
|
|
54
54
|
"pathspec",
|
|
55
55
|
],
|
|
56
|
+
"clang16": ["clang==16.*"],
|
|
57
|
+
"clang17": ["clang==17.*"],
|
|
58
|
+
"clang18": ["clang==18.*"],
|
|
59
|
+
"clang19": ["clang==19.*"],
|
|
60
|
+
"clang20": ["clang==20.*"],
|
|
61
|
+
"clang21": ["clang==21.*"],
|
|
56
62
|
},
|
|
57
63
|
entry_points={
|
|
58
64
|
"console_scripts": [
|
|
@@ -84,6 +90,10 @@ setup(
|
|
|
84
90
|
"jrg=jarvis.jarvis_rag.cli:main",
|
|
85
91
|
"jarvis-stats=jarvis.jarvis_stats.cli:main",
|
|
86
92
|
"jst=jarvis.jarvis_stats.cli:main",
|
|
93
|
+
"jarvis-sec=jarvis.jarvis_sec.cli:main",
|
|
94
|
+
"jsec=jarvis.jarvis_sec.cli:main",
|
|
95
|
+
"jarvis-c2rust=jarvis.jarvis_c2rust.cli:main",
|
|
96
|
+
"jc2r=jarvis.jarvis_c2rust.cli:main",
|
|
87
97
|
],
|
|
88
98
|
},
|
|
89
99
|
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,8 @@ 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
|
+
is_plan_enabled,
|
|
80
81
|
)
|
|
81
82
|
from jarvis.jarvis_utils.embedding import get_context_token_count
|
|
82
83
|
from jarvis.jarvis_utils.globals import (
|
|
@@ -285,6 +286,21 @@ class Agent:
|
|
|
285
286
|
"""获取工具使用提示"""
|
|
286
287
|
return build_action_prompt(self.output_handler) # type: ignore
|
|
287
288
|
|
|
289
|
+
def __new__(cls, *args, **kwargs):
|
|
290
|
+
if kwargs.get("agent_type") == "code":
|
|
291
|
+
try:
|
|
292
|
+
from jarvis.jarvis_code_agent.code_agent import CodeAgent
|
|
293
|
+
except ImportError as e:
|
|
294
|
+
raise RuntimeError(
|
|
295
|
+
"CodeAgent could not be imported. Please ensure jarvis_code_agent is installed correctly."
|
|
296
|
+
) from e
|
|
297
|
+
|
|
298
|
+
# 移除 agent_type 避免无限循环,并传递所有其他参数
|
|
299
|
+
kwargs.pop("agent_type", None)
|
|
300
|
+
return CodeAgent(**kwargs)
|
|
301
|
+
else:
|
|
302
|
+
return super().__new__(cls)
|
|
303
|
+
|
|
288
304
|
def __init__(
|
|
289
305
|
self,
|
|
290
306
|
system_prompt: str,
|
|
@@ -302,10 +318,15 @@ class Agent:
|
|
|
302
318
|
use_methodology: Optional[bool] = None,
|
|
303
319
|
use_analysis: Optional[bool] = None,
|
|
304
320
|
force_save_memory: Optional[bool] = None,
|
|
321
|
+
disable_file_edit: bool = False,
|
|
305
322
|
files: Optional[List[str]] = None,
|
|
306
323
|
confirm_callback: Optional[Callable[[str, bool], bool]] = None,
|
|
307
324
|
non_interactive: Optional[bool] = None,
|
|
308
325
|
in_multi_agent: Optional[bool] = None,
|
|
326
|
+
plan: Optional[bool] = None,
|
|
327
|
+
plan_max_depth: Optional[int] = None,
|
|
328
|
+
plan_depth: int = 0,
|
|
329
|
+
agent_type: str = "normal",
|
|
309
330
|
**kwargs,
|
|
310
331
|
):
|
|
311
332
|
"""初始化Jarvis Agent实例
|
|
@@ -325,6 +346,9 @@ class Agent:
|
|
|
325
346
|
force_save_memory: 是否强制保存记忆
|
|
326
347
|
confirm_callback: 用户确认回调函数,签名为 (tip: str, default: bool) -> bool;默认使用CLI的user_confirm
|
|
327
348
|
non_interactive: 是否以非交互模式运行(优先级最高,覆盖环境变量与配置)
|
|
349
|
+
plan: 是否启用任务规划与子任务拆分(默认从配置加载;启用后在进入主循环前评估是否需要将任务拆分为 <SUB_TASK> 列表,逐一由子Agent执行并汇总结果)
|
|
350
|
+
plan_max_depth: 任务规划的最大层数(默认3,可通过配置 JARVIS_PLAN_MAX_DEPTH 或入参覆盖)
|
|
351
|
+
plan_depth: 当前规划层数(内部用于递归控制,子Agent会在父基础上+1)
|
|
328
352
|
"""
|
|
329
353
|
# 基础属性初始化(仅根据入参设置原始值;实际生效的默认回退在 _init_config 中统一解析)
|
|
330
354
|
# 标识与描述
|
|
@@ -341,6 +365,7 @@ class Agent:
|
|
|
341
365
|
self.execute_tool_confirm = execute_tool_confirm
|
|
342
366
|
self.summary_prompt = summary_prompt
|
|
343
367
|
self.force_save_memory = force_save_memory
|
|
368
|
+
self.disable_file_edit = bool(disable_file_edit)
|
|
344
369
|
# 资源与环境
|
|
345
370
|
self.model_group = model_group
|
|
346
371
|
self.files = files or []
|
|
@@ -348,6 +373,19 @@ class Agent:
|
|
|
348
373
|
self.non_interactive = non_interactive
|
|
349
374
|
# 多智能体运行标志:用于控制非交互模式下的自动完成行为
|
|
350
375
|
self.in_multi_agent = bool(in_multi_agent)
|
|
376
|
+
# 任务规划:优先使用入参,否则回退到配置
|
|
377
|
+
self.plan = bool(plan) if plan is not None else is_plan_enabled()
|
|
378
|
+
# 规划深度与上限
|
|
379
|
+
try:
|
|
380
|
+
self.plan_max_depth = (
|
|
381
|
+
int(plan_max_depth) if plan_max_depth is not None else int(get_plan_max_depth())
|
|
382
|
+
)
|
|
383
|
+
except Exception:
|
|
384
|
+
self.plan_max_depth = 2
|
|
385
|
+
try:
|
|
386
|
+
self.plan_depth = int(plan_depth)
|
|
387
|
+
except Exception:
|
|
388
|
+
self.plan_depth = 0
|
|
351
389
|
# 运行时状态
|
|
352
390
|
self.first = True
|
|
353
391
|
self.run_input_handlers_next_turn = False
|
|
@@ -429,6 +467,8 @@ class Agent:
|
|
|
429
467
|
self.task_analyzer = TaskAnalyzer(self)
|
|
430
468
|
self.file_methodology_manager = FileMethodologyManager(self)
|
|
431
469
|
self.prompt_manager = PromptManager(self)
|
|
470
|
+
# 任务规划器:封装规划与子任务调度逻辑
|
|
471
|
+
self.task_planner = TaskPlanner(self, plan_depth=self.plan_depth, plan_max_depth=self.plan_max_depth)
|
|
432
472
|
|
|
433
473
|
# 设置系统提示词
|
|
434
474
|
self._setup_system_prompt()
|
|
@@ -475,7 +515,13 @@ class Agent:
|
|
|
475
515
|
use_tools: List[str],
|
|
476
516
|
):
|
|
477
517
|
"""初始化各种处理器"""
|
|
478
|
-
|
|
518
|
+
default_handlers = [ToolRegistry()]
|
|
519
|
+
if not getattr(self, "disable_file_edit", False):
|
|
520
|
+
default_handlers.extend([EditFileHandler(), RewriteFileHandler()])
|
|
521
|
+
handlers = output_handler or default_handlers
|
|
522
|
+
if getattr(self, "disable_file_edit", False):
|
|
523
|
+
handlers = [h for h in handlers if not isinstance(h, (EditFileHandler, RewriteFileHandler))]
|
|
524
|
+
self.output_handler = handlers
|
|
479
525
|
self.set_use_tools(use_tools)
|
|
480
526
|
self.input_handler = [
|
|
481
527
|
builtin_input_handler,
|
|
@@ -801,9 +847,14 @@ class Agent:
|
|
|
801
847
|
try:
|
|
802
848
|
if not self.model:
|
|
803
849
|
raise RuntimeError("Model not initialized")
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
)
|
|
850
|
+
# 优先使用外部传入的 summary_prompt;如为空则回退到默认的会话摘要请求
|
|
851
|
+
safe_summary_prompt = self.summary_prompt or ""
|
|
852
|
+
if isinstance(safe_summary_prompt, str) and safe_summary_prompt.strip() != "":
|
|
853
|
+
prompt_to_use = safe_summary_prompt
|
|
854
|
+
else:
|
|
855
|
+
prompt_to_use = self.session.prompt + "\n" + SUMMARY_REQUEST_PROMPT
|
|
856
|
+
|
|
857
|
+
summary = self.model.chat_until_success(prompt_to_use) # type: ignore
|
|
807
858
|
# 防御: 可能返回空响应(None或空字符串),统一为空字符串并告警
|
|
808
859
|
if not summary:
|
|
809
860
|
try:
|
|
@@ -1057,6 +1108,13 @@ class Agent:
|
|
|
1057
1108
|
)
|
|
1058
1109
|
except Exception:
|
|
1059
1110
|
pass
|
|
1111
|
+
# 如启用规划模式,先判断是否需要拆分并调度子任务
|
|
1112
|
+
if self.plan:
|
|
1113
|
+
try:
|
|
1114
|
+
self._maybe_plan_and_dispatch(self.session.prompt)
|
|
1115
|
+
except Exception:
|
|
1116
|
+
# 防御式处理,规划失败不影响主流程
|
|
1117
|
+
pass
|
|
1060
1118
|
return self._main_loop()
|
|
1061
1119
|
except Exception as e:
|
|
1062
1120
|
PrettyOutput.print(f"任务失败: {str(e)}", OutputType.ERROR)
|
|
@@ -1164,6 +1222,56 @@ class Agent:
|
|
|
1164
1222
|
temp_model.set_system_prompt(system_prompt)
|
|
1165
1223
|
return temp_model
|
|
1166
1224
|
|
|
1225
|
+
def _build_child_agent_params(self, name: str, description: str) -> Dict[str, Any]:
|
|
1226
|
+
"""构建子Agent参数,尽量继承父Agent配置,并确保子Agent非交互自动完成。"""
|
|
1227
|
+
use_tools_param: Optional[List[str]] = None
|
|
1228
|
+
try:
|
|
1229
|
+
tr = self.get_tool_registry()
|
|
1230
|
+
if isinstance(tr, ToolRegistry):
|
|
1231
|
+
selected_tools = tr.get_all_tools()
|
|
1232
|
+
use_tools_param = [t["name"] for t in selected_tools]
|
|
1233
|
+
except Exception:
|
|
1234
|
+
use_tools_param = None
|
|
1235
|
+
|
|
1236
|
+
return {
|
|
1237
|
+
"system_prompt": origin_agent_system_prompt,
|
|
1238
|
+
"name": name,
|
|
1239
|
+
"description": description,
|
|
1240
|
+
"model_group": self.model_group,
|
|
1241
|
+
"summary_prompt": self.summary_prompt,
|
|
1242
|
+
"auto_complete": True,
|
|
1243
|
+
"use_tools": use_tools_param,
|
|
1244
|
+
"execute_tool_confirm": self.execute_tool_confirm,
|
|
1245
|
+
"need_summary": self.need_summary,
|
|
1246
|
+
"auto_summary_rounds": self.auto_summary_rounds,
|
|
1247
|
+
"multiline_inputer": self.multiline_inputer,
|
|
1248
|
+
"use_methodology": self.use_methodology,
|
|
1249
|
+
"use_analysis": self.use_analysis,
|
|
1250
|
+
"force_save_memory": self.force_save_memory,
|
|
1251
|
+
"disable_file_edit": self.disable_file_edit,
|
|
1252
|
+
"files": self.files,
|
|
1253
|
+
"confirm_callback": self.confirm_callback,
|
|
1254
|
+
"non_interactive": True,
|
|
1255
|
+
"in_multi_agent": True,
|
|
1256
|
+
"plan": self.plan, # 继承父Agent的规划开关
|
|
1257
|
+
"plan_depth": self.plan_depth + 1, # 子Agent层数+1
|
|
1258
|
+
"plan_max_depth": self.plan_max_depth, # 继承上限
|
|
1259
|
+
}
|
|
1260
|
+
|
|
1261
|
+
def _maybe_plan_and_dispatch(self, task_text: str) -> None:
|
|
1262
|
+
"""委托给 TaskPlanner 执行任务规划与子任务调度,保持向后兼容。"""
|
|
1263
|
+
try:
|
|
1264
|
+
if hasattr(self, "task_planner") and self.task_planner:
|
|
1265
|
+
# 优先使用初始化时注入的规划器
|
|
1266
|
+
self.task_planner.maybe_plan_and_dispatch(task_text) # type: ignore[attr-defined]
|
|
1267
|
+
else:
|
|
1268
|
+
# 防御式回退:临时创建规划器以避免因未初始化导致的崩溃
|
|
1269
|
+
from jarvis.jarvis_agent.task_planner import TaskPlanner
|
|
1270
|
+
TaskPlanner(self, plan_depth=self.plan_depth, plan_max_depth=self.plan_max_depth).maybe_plan_and_dispatch(task_text)
|
|
1271
|
+
except Exception:
|
|
1272
|
+
# 规划失败不影响主流程
|
|
1273
|
+
pass
|
|
1274
|
+
|
|
1167
1275
|
def _filter_tools_if_needed(self, task: str):
|
|
1168
1276
|
"""如果工具数量超过阈值,使用大模型筛选相关工具"""
|
|
1169
1277
|
tool_registry = self.get_tool_registry()
|
{jarvis_ai_assistant-0.5.0 → jarvis_ai_assistant-0.6.0}/src/jarvis/jarvis_agent/agent_manager.py
RENAMED
|
@@ -32,6 +32,7 @@ class AgentManager:
|
|
|
32
32
|
multiline_inputer: Optional[Callable[[str], str]] = None,
|
|
33
33
|
confirm_callback: Optional[Callable[[str, bool], bool]] = None,
|
|
34
34
|
non_interactive: Optional[bool] = None,
|
|
35
|
+
plan: Optional[bool] = None,
|
|
35
36
|
):
|
|
36
37
|
self.model_group = model_group
|
|
37
38
|
self.tool_group = tool_group
|
|
@@ -43,6 +44,7 @@ class AgentManager:
|
|
|
43
44
|
self.multiline_inputer = multiline_inputer
|
|
44
45
|
self.confirm_callback = confirm_callback
|
|
45
46
|
self.non_interactive = non_interactive
|
|
47
|
+
self.plan = plan
|
|
46
48
|
|
|
47
49
|
def initialize(self) -> Agent:
|
|
48
50
|
"""初始化Agent"""
|
|
@@ -61,6 +63,7 @@ class AgentManager:
|
|
|
61
63
|
multiline_inputer=self.multiline_inputer,
|
|
62
64
|
confirm_callback=self.confirm_callback,
|
|
63
65
|
non_interactive=self.non_interactive,
|
|
66
|
+
plan=self.plan,
|
|
64
67
|
)
|
|
65
68
|
|
|
66
69
|
# 尝试恢复会话
|
|
@@ -370,10 +370,30 @@ def handle_builtin_config_selector(
|
|
|
370
370
|
"""在进入默认通用代理前,列出内置配置供选择(agent/multi_agent/roles)。"""
|
|
371
371
|
if is_enable_builtin_config_selector():
|
|
372
372
|
try:
|
|
373
|
-
#
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
373
|
+
# 查找可用的 builtin 目录(支持多候选)
|
|
374
|
+
builtin_dirs: List[Path] = []
|
|
375
|
+
try:
|
|
376
|
+
ancestors = list(Path(__file__).resolve().parents)
|
|
377
|
+
for anc in ancestors[:8]:
|
|
378
|
+
p = anc / "builtin"
|
|
379
|
+
if p.exists():
|
|
380
|
+
builtin_dirs.append(p)
|
|
381
|
+
except Exception:
|
|
382
|
+
pass
|
|
383
|
+
# 去重,保留顺序
|
|
384
|
+
_seen = set()
|
|
385
|
+
_unique: List[Path] = []
|
|
386
|
+
for d in builtin_dirs:
|
|
387
|
+
try:
|
|
388
|
+
key = str(d.resolve())
|
|
389
|
+
except Exception:
|
|
390
|
+
key = str(d)
|
|
391
|
+
if key not in _seen:
|
|
392
|
+
_seen.add(key)
|
|
393
|
+
_unique.append(d)
|
|
394
|
+
builtin_dirs = _unique
|
|
395
|
+
# 向后兼容:保留第一个候选作为 builtin_root
|
|
396
|
+
builtin_root = builtin_dirs[0] if builtin_dirs else None # type: ignore[assignment]
|
|
377
397
|
|
|
378
398
|
categories = [
|
|
379
399
|
("agent", "jarvis-agent", "*.yaml"),
|
|
@@ -414,8 +434,14 @@ def handle_builtin_config_selector(
|
|
|
414
434
|
# 忽略配置读取异常
|
|
415
435
|
pass
|
|
416
436
|
|
|
417
|
-
#
|
|
418
|
-
|
|
437
|
+
# 追加内置目录(支持多个候选)
|
|
438
|
+
try:
|
|
439
|
+
candidates = builtin_dirs if isinstance(builtin_dirs, list) and builtin_dirs else ([builtin_root] if builtin_root else [])
|
|
440
|
+
except Exception:
|
|
441
|
+
candidates = ([builtin_root] if builtin_root else [])
|
|
442
|
+
for _bd in candidates:
|
|
443
|
+
if _bd:
|
|
444
|
+
search_dirs.append(Path(_bd) / cat)
|
|
419
445
|
|
|
420
446
|
# 去重并保留顺序
|
|
421
447
|
unique_dirs = []
|
|
@@ -429,11 +455,14 @@ def handle_builtin_config_selector(
|
|
|
429
455
|
seen.add(key)
|
|
430
456
|
unique_dirs.append(Path(d))
|
|
431
457
|
|
|
432
|
-
#
|
|
458
|
+
# 可选调试输出:查看每类的搜索目录
|
|
433
459
|
try:
|
|
434
|
-
|
|
460
|
+
if os.environ.get("JARVIS_DEBUG_BUILTIN_SELECTOR") == "1":
|
|
461
|
+
PrettyOutput.print(
|
|
462
|
+
f"DEBUG: category={cat} search_dirs=" + ", ".join(str(p) for p in unique_dirs),
|
|
463
|
+
OutputType.INFO,
|
|
464
|
+
)
|
|
435
465
|
except Exception:
|
|
436
|
-
# 忽略更新过程中的所有异常,避免影响主流程
|
|
437
466
|
pass
|
|
438
467
|
|
|
439
468
|
for dir_path in unique_dirs:
|
|
@@ -681,6 +710,7 @@ def run_cli(
|
|
|
681
710
|
non_interactive: bool = typer.Option(
|
|
682
711
|
False, "-n", "--non-interactive", help="启用非交互模式:用户无法与命令交互,脚本执行超时限制为5分钟"
|
|
683
712
|
),
|
|
713
|
+
plan: Optional[bool] = typer.Option(None, "--plan/--no-plan", help="启用或禁用任务规划(不指定则从配置加载)"),
|
|
684
714
|
web: bool = typer.Option(False, "--web", help="以 Web 模式启动,通过浏览器 WebSocket 交互"),
|
|
685
715
|
web_host: str = typer.Option("127.0.0.1", "--web-host", help="Web 服务主机"),
|
|
686
716
|
web_port: int = typer.Option(8765, "--web-port", help="Web 服务端口"),
|
|
@@ -1022,6 +1052,12 @@ def run_cli(
|
|
|
1022
1052
|
**extra_kwargs,
|
|
1023
1053
|
)
|
|
1024
1054
|
agent = agent_manager.initialize()
|
|
1055
|
+
# CLI 开关:启用/禁用规划(不依赖 AgentManager 支持,直接设置 Agent 属性)
|
|
1056
|
+
if plan is not None:
|
|
1057
|
+
try:
|
|
1058
|
+
agent.plan = bool(plan)
|
|
1059
|
+
except Exception:
|
|
1060
|
+
pass
|
|
1025
1061
|
|
|
1026
1062
|
if web:
|
|
1027
1063
|
try:
|
|
@@ -125,7 +125,12 @@ class AgentRunLoop:
|
|
|
125
125
|
|
|
126
126
|
# 检查自动完成
|
|
127
127
|
if ag.auto_complete and is_auto_complete(current_response):
|
|
128
|
-
|
|
128
|
+
# 先运行_complete_task,触发记忆整理/事件等副作用,再决定返回值
|
|
129
|
+
result = ag._complete_task(auto_completed=True)
|
|
130
|
+
# 若不需要summary,则将最后一条LLM输出作为返回值
|
|
131
|
+
if not getattr(ag, "need_summary", True):
|
|
132
|
+
return current_response
|
|
133
|
+
return result
|
|
129
134
|
|
|
130
135
|
# 获取下一步用户输入
|
|
131
136
|
next_action = ag._get_next_user_action()
|
|
@@ -0,0 +1,219 @@
|
|
|
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
|
+
"注意:不要将步骤拆分太细,一般不要超过4个步骤。\n"
|
|
79
|
+
"要求:<PLAN> 内必须是有效 YAML 列表,仅包含字符串项;禁止输出任何额外解释。\n"
|
|
80
|
+
"当不需要拆分时,仅输出:\n<DONT_NEED/>\n"
|
|
81
|
+
"禁止输出任何额外解释。"
|
|
82
|
+
)
|
|
83
|
+
temp_model = self.agent._create_temp_model(planning_sys)
|
|
84
|
+
plan_prompt = f"任务:\n{task_text}\n\n请严格按要求只输出结构化标签块。"
|
|
85
|
+
plan_resp = temp_model.chat_until_success(plan_prompt) # type: ignore
|
|
86
|
+
if not plan_resp:
|
|
87
|
+
PrettyOutput.print("任务规划模型未返回有效响应。", OutputType.WARNING)
|
|
88
|
+
return
|
|
89
|
+
except Exception as e:
|
|
90
|
+
# 规划失败不影响主流程
|
|
91
|
+
PrettyOutput.print(f"任务规划失败: {e}", OutputType.ERROR)
|
|
92
|
+
return
|
|
93
|
+
|
|
94
|
+
text = str(plan_resp).strip()
|
|
95
|
+
# 不需要拆分
|
|
96
|
+
if re.search(r"<\s*DONT_NEED\s*/\s*>", text, re.IGNORECASE):
|
|
97
|
+
PrettyOutput.print("任务规划完成:无需拆分。", OutputType.SUCCESS)
|
|
98
|
+
return
|
|
99
|
+
|
|
100
|
+
# 解析 <SUB_TASK> 块
|
|
101
|
+
m = re.search(
|
|
102
|
+
r"<\s*PLAN\s*>\s*(.*?)\s*<\s*/\s*PLAN\s*>",
|
|
103
|
+
text,
|
|
104
|
+
re.IGNORECASE | re.DOTALL,
|
|
105
|
+
)
|
|
106
|
+
subtasks: List[str] = []
|
|
107
|
+
if m:
|
|
108
|
+
block = m.group(1)
|
|
109
|
+
try:
|
|
110
|
+
data = yaml.safe_load(block)
|
|
111
|
+
if isinstance(data, list):
|
|
112
|
+
for item in data:
|
|
113
|
+
if isinstance(item, str):
|
|
114
|
+
s = item.strip()
|
|
115
|
+
if s:
|
|
116
|
+
subtasks.append(s)
|
|
117
|
+
else:
|
|
118
|
+
PrettyOutput.print("任务规划提示:无需拆分。", OutputType.INFO)
|
|
119
|
+
except Exception as e:
|
|
120
|
+
PrettyOutput.print("任务规划提示:无需拆分。", OutputType.INFO)
|
|
121
|
+
else:
|
|
122
|
+
PrettyOutput.print("任务规划提示:无需拆分。", OutputType.INFO)
|
|
123
|
+
|
|
124
|
+
if not subtasks:
|
|
125
|
+
# 无有效子任务,直接返回
|
|
126
|
+
PrettyOutput.print("任务规划提示:无需拆分。", OutputType.INFO)
|
|
127
|
+
return
|
|
128
|
+
|
|
129
|
+
PrettyOutput.print(f"任务已拆分为 {len(subtasks)} 个子任务:", OutputType.SUCCESS)
|
|
130
|
+
for i, st in enumerate(subtasks, 1):
|
|
131
|
+
PrettyOutput.print(f" {i}. {st}", OutputType.INFO)
|
|
132
|
+
|
|
133
|
+
# 执行子任务
|
|
134
|
+
executed_subtask_block_lines: List[str] = ["<PLAN>"]
|
|
135
|
+
executed_subtask_block_lines += [f"- {t}" for t in subtasks]
|
|
136
|
+
executed_subtask_block_lines.append("</PLAN>")
|
|
137
|
+
|
|
138
|
+
results_lines: List[str] = []
|
|
139
|
+
for i, st in enumerate(subtasks, 1):
|
|
140
|
+
try:
|
|
141
|
+
PrettyOutput.print(f"开始执行子任务 {i}/{len(subtasks)}: {st}", OutputType.INFO)
|
|
142
|
+
child_kwargs = self.agent._build_child_agent_params(
|
|
143
|
+
name=f"{self.agent.name}-child-{i}",
|
|
144
|
+
description=f"子任务执行器: {st}",
|
|
145
|
+
)
|
|
146
|
+
# 使用父Agent的类创建子Agent,避免循环依赖
|
|
147
|
+
child = self.agent.__class__(**child_kwargs)
|
|
148
|
+
# 构造子任务执行提示,包含父任务与前置子任务结果,避免背景缺失
|
|
149
|
+
subtask_block_text = "\n".join(executed_subtask_block_lines)
|
|
150
|
+
if results_lines:
|
|
151
|
+
prev_results_block = "<PREVIOUS_SUB_TASK_RESULTS>\n" + "\n".join(results_lines) + "\n</PREVIOUS_SUB_TASK_RESULTS>"
|
|
152
|
+
else:
|
|
153
|
+
prev_results_block = "<PREVIOUS_SUB_TASK_RESULTS />"
|
|
154
|
+
child_prompt = join_prompts([
|
|
155
|
+
f"原始任务:\n{task_text}",
|
|
156
|
+
f"子任务规划:\n{subtask_block_text}",
|
|
157
|
+
f"前置子任务执行结果:\n{prev_results_block}",
|
|
158
|
+
f"当前子任务:{st}",
|
|
159
|
+
"请基于原始任务背景与前置结果执行当前子任务,避免重复工作;如需依赖前置产物请直接复用;如需为后续子任务提供数据,请妥善保存(可使用工具保存文件或记忆)。"
|
|
160
|
+
])
|
|
161
|
+
child_result = child.run(child_prompt)
|
|
162
|
+
result_text = "" if child_result is None else str(child_result)
|
|
163
|
+
# 防止极端长输出导致污染,这里不做截断,交由上层摘要策略控制
|
|
164
|
+
results_lines.append(f"- 子任务{i}: {st}\n 结果: {result_text}")
|
|
165
|
+
PrettyOutput.print(f"子任务 {i}/{len(subtasks)} 执行完成。", OutputType.SUCCESS)
|
|
166
|
+
except Exception as e:
|
|
167
|
+
results_lines.append(f"- 子任务{i}: {st}\n 结果: 执行失败,原因: {e}")
|
|
168
|
+
PrettyOutput.print(f"子任务 {i}/{len(subtasks)} 执行失败: {e}", OutputType.ERROR)
|
|
169
|
+
|
|
170
|
+
subtask_block = "\n".join(executed_subtask_block_lines)
|
|
171
|
+
results_block = "<SUB_TASK_RESULTS>\n" + "\n".join(results_lines) + "\n</SUB_TASK_RESULTS>"
|
|
172
|
+
|
|
173
|
+
PrettyOutput.print("所有子任务执行完毕,正在整合结果...", OutputType.INFO)
|
|
174
|
+
# 先对所有子任务结果进行简要自动汇总,便于父Agent继续整合
|
|
175
|
+
summary_block = "<RESULT_SUMMARY>\n无摘要(将直接使用结果详情继续)\n</RESULT_SUMMARY>"
|
|
176
|
+
try:
|
|
177
|
+
summarizing_sys = (
|
|
178
|
+
"你是一个任务结果整合助手。请根据提供的原始任务、子任务清单与子任务执行结果,"
|
|
179
|
+
"生成简明扼要的汇总与关键结论,突出已完成项、遗留风险与下一步建议。"
|
|
180
|
+
"严格仅输出以下结构:\n"
|
|
181
|
+
"<RESULT_SUMMARY>\n"
|
|
182
|
+
"…你的简要汇总…\n"
|
|
183
|
+
"</RESULT_SUMMARY>\n"
|
|
184
|
+
"不要输出其他任何解释。"
|
|
185
|
+
)
|
|
186
|
+
temp_model2 = self.agent._create_temp_model(summarizing_sys)
|
|
187
|
+
sum_prompt = (
|
|
188
|
+
f"原始任务:\n{task_text}\n\n"
|
|
189
|
+
f"子任务规划:\n{subtask_block}\n\n"
|
|
190
|
+
f"子任务执行结果:\n{results_block}\n\n"
|
|
191
|
+
"请按要求仅输出汇总块。"
|
|
192
|
+
)
|
|
193
|
+
sum_resp = temp_model2.chat_until_success(sum_prompt) # type: ignore
|
|
194
|
+
if isinstance(sum_resp, str) and sum_resp.strip():
|
|
195
|
+
s = sum_resp.strip()
|
|
196
|
+
if not re.search(r"<\s*RESULT_SUMMARY\s*>", s, re.IGNORECASE):
|
|
197
|
+
s = f"<RESULT_SUMMARY>\n{s}\n</RESULT_SUMMARY>"
|
|
198
|
+
summary_block = s
|
|
199
|
+
except Exception:
|
|
200
|
+
# 汇总失败不影响主流程,继续使用默认占位
|
|
201
|
+
pass
|
|
202
|
+
|
|
203
|
+
# 合并回父Agent的 prompt,父Agent将基于汇总与详情继续执行
|
|
204
|
+
try:
|
|
205
|
+
self.agent.session.prompt = join_prompts(
|
|
206
|
+
[
|
|
207
|
+
f"原始任务:\n{task_text}",
|
|
208
|
+
f"子任务规划:\n{subtask_block}",
|
|
209
|
+
f"子任务结果汇总:\n{summary_block}",
|
|
210
|
+
f"子任务执行结果:\n{results_block}",
|
|
211
|
+
"请基于上述子任务结果整合并完成最终输出。",
|
|
212
|
+
]
|
|
213
|
+
)
|
|
214
|
+
except Exception:
|
|
215
|
+
# 回退拼接
|
|
216
|
+
self.agent.session.prompt = (
|
|
217
|
+
f"{task_text}\n\n{subtask_block}\n\n{summary_block}\n\n{results_block}\n\n"
|
|
218
|
+
"请基于上述子任务结果整合并完成最终输出。"
|
|
219
|
+
)
|