agentcrew-ai 0.9.0__tar.gz → 0.9.2__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.
- agentcrew_ai-0.9.2/AgentCrew/__init__.py +1 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/app.py +12 -1
- agentcrew_ai-0.9.2/AgentCrew/modules/a2a/common/client/card_resolver.py +39 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/a2a/server.py +5 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/a2a/task_manager.py +1 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/chat/message/conversation.py +18 -1
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/code_analysis/service.py +50 -7
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/code_analysis/tool.py +9 -8
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/console/completers.py +4 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/console/console_ui.py +17 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/console/display_handlers.py +4 -0
- agentcrew_ai-0.9.2/AgentCrew/modules/console/visual_mode/__init__.py +5 -0
- agentcrew_ai-0.9.2/AgentCrew/modules/console/visual_mode/viewer.py +41 -0
- agentcrew_ai-0.9.2/AgentCrew/modules/console/visual_mode/viewer_input_handler.py +315 -0
- agentcrew_ai-0.9.2/AgentCrew/modules/console/visual_mode/viewer_ui.py +608 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/gui/components/menu_components.py +8 -7
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/gui/themes/style_provider.py +3 -1
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/gui/widgets/configs/global_settings.py +1 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/gui/widgets/history_sidebar.py +8 -1
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/llm/constants.py +15 -5
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/mcpclient/service.py +0 -1
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/memory/base_service.py +13 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/memory/chroma_service.py +50 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/PKG-INFO +1 -1
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/agentcrew_ai.egg-info/PKG-INFO +1 -1
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/agentcrew_ai.egg-info/SOURCES.txt +4 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/pyproject.toml +1 -1
- agentcrew_ai-0.9.0/AgentCrew/__init__.py +0 -1
- agentcrew_ai-0.9.0/AgentCrew/modules/a2a/common/client/card_resolver.py +0 -20
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/assets/agentcrew_logo.png +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/main.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/main_docker.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/__init__.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/a2a/__init__.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/a2a/adapters.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/a2a/agent_cards.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/a2a/common/__init__.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/a2a/common/client/__init__.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/a2a/common/client/client.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/a2a/common/server/__init__.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/a2a/common/server/auth_middleware.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/a2a/common/server/task_manager.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/a2a/common/server/utils.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/a2a/errors.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/a2a/registry.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/agents/__init__.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/agents/base.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/agents/example.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/agents/local_agent.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/agents/manager.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/agents/remote_agent.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/agents/tools/__init__.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/agents/tools/ask.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/agents/tools/delegate.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/agents/tools/transfer.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/anthropic/__init__.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/anthropic/service.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/browser_automation/__init__.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/browser_automation/chrome_manager.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/browser_automation/element_extractor.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/browser_automation/js/click_element.js +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/browser_automation/js/draw_element_boxes.js +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/browser_automation/js/extract_clickable_elements.js +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/browser_automation/js/extract_elements_by_text.js +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/browser_automation/js/extract_input_elements.js +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/browser_automation/js/extract_scrollable_elements.js +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/browser_automation/js/filter_hidden_elements.js +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/browser_automation/js/focus_and_clear_element.js +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/browser_automation/js/remove_element_boxes.js +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/browser_automation/js/scroll_to_element.js +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/browser_automation/js/trigger_input_events.js +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/browser_automation/js_loader.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/browser_automation/service.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/browser_automation/tool.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/chat/__init__.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/chat/consolidation.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/chat/file_handler.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/chat/history.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/chat/message/__init__.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/chat/message/base.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/chat/message/command_processor.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/chat/message/handler.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/chat/message/tool_manager.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/chat/message_handler.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/clipboard/__init__.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/clipboard/service.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/clipboard/tool.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/code_analysis/__init__.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/code_analysis/file_search_service.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/code_analysis/grep_service.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/code_analysis/parsers/__init__.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/code_analysis/parsers/base.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/code_analysis/parsers/cpp_parser.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/code_analysis/parsers/csharp_parser.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/code_analysis/parsers/generic_parser.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/code_analysis/parsers/go_parser.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/code_analysis/parsers/java_parser.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/code_analysis/parsers/javascript_parser.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/code_analysis/parsers/kotlin_parser.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/code_analysis/parsers/php_parser.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/code_analysis/parsers/python_parser.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/code_analysis/parsers/ruby_parser.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/code_analysis/parsers/rust_parser.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/command_execution/__init__.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/command_execution/constants.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/command_execution/service.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/command_execution/tool.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/command_execution/types.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/config/__init__.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/config/config_management.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/console/__init__.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/console/command_handlers.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/console/confirmation_handler.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/console/constants.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/console/conversation_browser/__init__.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/console/conversation_browser/browser.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/console/conversation_browser/browser_input_handler.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/console/conversation_browser/browser_ui.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/console/conversation_handler.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/console/diff_display.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/console/input_handler.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/console/tool_display.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/console/ui_effects.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/console/utils.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/custom_llm/__init__.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/custom_llm/copilot_response_service.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/custom_llm/deepinfra_service.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/custom_llm/github_copilot_service.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/custom_llm/service.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/file_editing/__init__.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/file_editing/safety_validator.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/file_editing/search_replace_engine.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/file_editing/service.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/file_editing/tool.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/file_editing/tree_sitter_checker.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/google/__init__.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/google/native_service.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/google/service.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/groq/__init__.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/groq/service.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/gui/__init__.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/gui/components/__init__.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/gui/components/chat_components.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/gui/components/command_handler.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/gui/components/completers.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/gui/components/conversation_components.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/gui/components/input_components.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/gui/components/keyboard_handler.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/gui/components/message_handlers.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/gui/components/tool_handlers.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/gui/components/ui_state_manager.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/gui/qt_ui.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/gui/themes/README.md +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/gui/themes/__init__.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/gui/themes/atom_light.yaml +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/gui/themes/catppuccin.yaml +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/gui/themes/dracula.yaml +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/gui/themes/nord.yaml +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/gui/themes/saigontech.yaml +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/gui/themes/theme_loader.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/gui/themes/unicorn.yaml +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/gui/utils/__init__.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/gui/utils/macos_clipboard.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/gui/utils/strings.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/gui/utils/wins_clipboard.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/gui/widgets/__init__.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/gui/widgets/config_window.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/gui/widgets/configs/__init__.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/gui/widgets/configs/agent_config.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/gui/widgets/configs/custom_llm_provider.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/gui/widgets/configs/mcp_config.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/gui/widgets/configs/save_worker.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/gui/widgets/diff_widget.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/gui/widgets/json_editor.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/gui/widgets/loading_overlay.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/gui/widgets/markdown_editor.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/gui/widgets/message_bubble.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/gui/widgets/paste_aware_textedit.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/gui/widgets/system_message.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/gui/widgets/token_usage.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/gui/widgets/tool_widget.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/gui/worker.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/image_generation/__init__.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/image_generation/service.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/image_generation/tool.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/llm/__init__.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/llm/base.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/llm/model_registry.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/llm/service_manager.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/llm/types.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/mcpclient/__init__.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/mcpclient/auth.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/mcpclient/config.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/mcpclient/manager.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/mcpclient/tool.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/memory/__init__.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/memory/context_persistent.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/memory/github_copilot_ef.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/memory/google_genai_ef.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/memory/tool.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/memory/voyageai_ef.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/openai/__init__.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/openai/response_service.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/openai/service.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/prompts/__init__.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/prompts/constants.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/tools/README.md +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/tools/registration.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/tools/registry.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/voice/__init__.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/voice/audio_handler.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/voice/base.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/voice/deepinfra_service.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/voice/elevenlabs_service.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/voice/text_cleaner.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/web_search/__init__.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/web_search/service.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/modules/web_search/tool.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/AgentCrew/setup.py +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/CONTRIBUTING.md +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/LICENSE +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/MANIFEST.in +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/README.md +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/agentcrew_ai.egg-info/dependency_links.txt +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/agentcrew_ai.egg-info/entry_points.txt +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/agentcrew_ai.egg-info/requires.txt +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/agentcrew_ai.egg-info/top_level.txt +0 -0
- {agentcrew_ai-0.9.0 → agentcrew_ai-0.9.2}/setup.cfg +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.9.2"
|
|
@@ -246,13 +246,24 @@ class AgentCrewApplication:
|
|
|
246
246
|
except Exception as e:
|
|
247
247
|
raise ValueError(f"Failed to load output schema: {e}")
|
|
248
248
|
|
|
249
|
+
def _clean_json_response(self, response: str) -> str:
|
|
250
|
+
import re
|
|
251
|
+
|
|
252
|
+
cleaned = response.strip()
|
|
253
|
+
pattern = r"^```(?:json)?\s*\n?(.*?)\n?```$"
|
|
254
|
+
match = re.match(pattern, cleaned, re.DOTALL)
|
|
255
|
+
if match:
|
|
256
|
+
cleaned = match.group(1).strip()
|
|
257
|
+
return cleaned
|
|
258
|
+
|
|
249
259
|
def _validate_response_against_schema(
|
|
250
260
|
self, response: str, schema_dict: Dict[str, Any]
|
|
251
261
|
) -> tuple[bool, Optional[str]]:
|
|
252
262
|
from jsonschema import validate, ValidationError
|
|
253
263
|
|
|
254
264
|
try:
|
|
255
|
-
|
|
265
|
+
cleaned_response = self._clean_json_response(response)
|
|
266
|
+
response_json = json.loads(cleaned_response)
|
|
256
267
|
except json.JSONDecodeError as e:
|
|
257
268
|
return (
|
|
258
269
|
False,
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import json
|
|
2
|
+
|
|
3
|
+
import httpx
|
|
4
|
+
|
|
5
|
+
from a2a.types import AgentCard
|
|
6
|
+
|
|
7
|
+
DEFAULT_AGENT_CARD_PATHS = [
|
|
8
|
+
"/.well-known/agent-card.json",
|
|
9
|
+
"/.well-known/agent.json",
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class A2ACardResolver:
|
|
14
|
+
def __init__(self, base_url, agent_card_path: str | None = None):
|
|
15
|
+
self.base_url = base_url.rstrip("/")
|
|
16
|
+
self.agent_card_path = agent_card_path.lstrip("/") if agent_card_path else None
|
|
17
|
+
|
|
18
|
+
def get_agent_card(self) -> AgentCard:
|
|
19
|
+
with httpx.Client() as client:
|
|
20
|
+
if self.agent_card_path:
|
|
21
|
+
return self._fetch_agent_card(client, self.agent_card_path)
|
|
22
|
+
|
|
23
|
+
for path in DEFAULT_AGENT_CARD_PATHS:
|
|
24
|
+
try:
|
|
25
|
+
return self._fetch_agent_card(client, path.lstrip("/"))
|
|
26
|
+
except httpx.HTTPStatusError:
|
|
27
|
+
continue
|
|
28
|
+
|
|
29
|
+
raise httpx.RequestError(
|
|
30
|
+
f"Agent card not found at any of the default paths: {DEFAULT_AGENT_CARD_PATHS}"
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
def _fetch_agent_card(self, client: httpx.Client, path: str) -> AgentCard:
|
|
34
|
+
response = client.get(self.base_url + "/" + path)
|
|
35
|
+
response.raise_for_status()
|
|
36
|
+
try:
|
|
37
|
+
return AgentCard(**response.json())
|
|
38
|
+
except json.JSONDecodeError as e:
|
|
39
|
+
raise httpx.RequestError(str(e)) from e
|
|
@@ -82,6 +82,11 @@ class A2AServer:
|
|
|
82
82
|
agent_routes = Mount(
|
|
83
83
|
f"/{agent_name}",
|
|
84
84
|
routes=[
|
|
85
|
+
Route(
|
|
86
|
+
"/.well-known/agent-card.json",
|
|
87
|
+
self._get_agent_card_factory(agent_name),
|
|
88
|
+
methods=["GET"],
|
|
89
|
+
),
|
|
85
90
|
Route(
|
|
86
91
|
"/.well-known/agent.json",
|
|
87
92
|
self._get_agent_card_factory(agent_name),
|
|
@@ -608,6 +608,7 @@ class AgentTaskManager(TaskManager):
|
|
|
608
608
|
|
|
609
609
|
except Exception as e:
|
|
610
610
|
logger.error(str(e))
|
|
611
|
+
logger.debug(self.task_history[task.context_id])
|
|
611
612
|
# Handle errors
|
|
612
613
|
task.status.state = TaskState.failed
|
|
613
614
|
task.status.timestamp = datetime.now().isoformat()
|
|
@@ -198,6 +198,7 @@ class ConversationManager:
|
|
|
198
198
|
def delete_conversation_by_id(self, conversation_id: str) -> bool:
|
|
199
199
|
"""
|
|
200
200
|
Deletes a conversation by its ID, handling file deletion and UI updates.
|
|
201
|
+
Also deletes associated memory data.
|
|
201
202
|
|
|
202
203
|
Args:
|
|
203
204
|
conversation_id: The ID of the conversation to delete.
|
|
@@ -215,6 +216,22 @@ class ConversationManager:
|
|
|
215
216
|
logger.info(
|
|
216
217
|
f"INFO: Successfully deleted conversation file for ID: {conversation_id}"
|
|
217
218
|
)
|
|
219
|
+
|
|
220
|
+
if self.message_handler.memory_service:
|
|
221
|
+
memory_result = (
|
|
222
|
+
self.message_handler.memory_service.delete_by_conversation_id(
|
|
223
|
+
conversation_id
|
|
224
|
+
)
|
|
225
|
+
)
|
|
226
|
+
if memory_result.get("success"):
|
|
227
|
+
logger.info(
|
|
228
|
+
f"INFO: Deleted {memory_result.get('count', 0)} memories for conversation {conversation_id}"
|
|
229
|
+
)
|
|
230
|
+
else:
|
|
231
|
+
logger.warning(
|
|
232
|
+
f"WARNING: Failed to delete memories for conversation {conversation_id}: {memory_result.get('message')}"
|
|
233
|
+
)
|
|
234
|
+
|
|
218
235
|
self.message_handler._notify("conversations_changed", None)
|
|
219
236
|
self.message_handler._notify(
|
|
220
237
|
"system_message", f"Conversation {conversation_id[:8]}... deleted."
|
|
@@ -224,7 +241,7 @@ class ConversationManager:
|
|
|
224
241
|
logger.info(
|
|
225
242
|
f"INFO: Deleted conversation {conversation_id} was the current one. Starting new conversation."
|
|
226
243
|
)
|
|
227
|
-
self.start_new_conversation()
|
|
244
|
+
self.start_new_conversation()
|
|
228
245
|
return True
|
|
229
246
|
else:
|
|
230
247
|
error_msg = f"Failed to delete conversation {conversation_id[:8]}..."
|
|
@@ -3,13 +3,22 @@ import fnmatch
|
|
|
3
3
|
import subprocess
|
|
4
4
|
import json
|
|
5
5
|
import asyncio
|
|
6
|
-
|
|
6
|
+
import base64
|
|
7
|
+
from typing import Any, Dict, List, Optional, Tuple, Union, TYPE_CHECKING
|
|
7
8
|
from loguru import logger
|
|
8
9
|
|
|
9
10
|
from tree_sitter_language_pack import get_parser
|
|
10
11
|
from tree_sitter import Parser
|
|
11
12
|
|
|
12
13
|
from .parsers import get_parser_for_language, BaseLanguageParser
|
|
14
|
+
import mimetypes
|
|
15
|
+
|
|
16
|
+
IMAGE_MIME_TYPES = [
|
|
17
|
+
"image/jpeg",
|
|
18
|
+
"image/png",
|
|
19
|
+
"image/gif",
|
|
20
|
+
"image/webp",
|
|
21
|
+
]
|
|
13
22
|
|
|
14
23
|
if TYPE_CHECKING:
|
|
15
24
|
from AgentCrew.modules.llm.base import BaseLLMService
|
|
@@ -59,6 +68,7 @@ class CodeAnalysisService:
|
|
|
59
68
|
analyzing large repositories (>500 files).
|
|
60
69
|
"""
|
|
61
70
|
self.llm_service = llm_service
|
|
71
|
+
self.file_handler = None
|
|
62
72
|
if self.llm_service:
|
|
63
73
|
if self.llm_service.provider_name == "google":
|
|
64
74
|
self.llm_service.model = "gemini-2.5-flash-lite"
|
|
@@ -666,18 +676,49 @@ Example response format:
|
|
|
666
676
|
file_path,
|
|
667
677
|
start_line=None,
|
|
668
678
|
end_line=None,
|
|
669
|
-
) ->
|
|
679
|
+
) -> Union[Tuple[str, str], Tuple[str, Dict[str, Any]]]:
|
|
670
680
|
"""
|
|
671
681
|
Return the content of a file, optionally reading only a specific line range.
|
|
682
|
+
For document files (PDF, DOCX, XLSX, PPTX), uses Docling to convert
|
|
683
|
+
to text/markdown and ignores start_line/end_line parameters.
|
|
684
|
+
For image files, returns base64 encoded data in image_url format.
|
|
672
685
|
|
|
673
686
|
Args:
|
|
674
687
|
file_path: Path to the file to read
|
|
675
|
-
start_line: Optional starting line number (1-indexed)
|
|
676
|
-
end_line: Optional ending line number (1-indexed, inclusive)
|
|
688
|
+
start_line: Optional starting line number (1-indexed) - ignored for document files
|
|
689
|
+
end_line: Optional ending line number (1-indexed, inclusive) - ignored for document files
|
|
677
690
|
|
|
678
691
|
Returns:
|
|
679
|
-
|
|
692
|
+
Tuple of (file_path, content) where content is either:
|
|
693
|
+
- str: text content for text/document files
|
|
694
|
+
- dict: {"type": "image_url", "image_url": {"url": "data:mime;base64,..."}} for images
|
|
680
695
|
"""
|
|
696
|
+
|
|
697
|
+
from AgentCrew.modules.chat.file_handler import (
|
|
698
|
+
FileHandler,
|
|
699
|
+
ALLOWED_MIME_TYPES,
|
|
700
|
+
)
|
|
701
|
+
|
|
702
|
+
mime_type, _ = mimetypes.guess_type(file_path)
|
|
703
|
+
|
|
704
|
+
if mime_type and mime_type in IMAGE_MIME_TYPES:
|
|
705
|
+
with open(file_path, "rb") as file:
|
|
706
|
+
binary_data = file.read()
|
|
707
|
+
base64_data = base64.b64encode(binary_data).decode("utf-8")
|
|
708
|
+
return file_path, {
|
|
709
|
+
"type": "image_url",
|
|
710
|
+
"image_url": {"url": f"data:{mime_type};base64,{base64_data}"},
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
if mime_type and mime_type in ALLOWED_MIME_TYPES:
|
|
714
|
+
if self.file_handler is None:
|
|
715
|
+
self.file_handler = FileHandler()
|
|
716
|
+
result = self.file_handler.process_file(file_path)
|
|
717
|
+
if result and "text" in result:
|
|
718
|
+
return file_path, result["text"]
|
|
719
|
+
elif result is None:
|
|
720
|
+
raise ValueError(f"Failed to process document file: {file_path}")
|
|
721
|
+
|
|
681
722
|
with open(file_path, "rb") as file:
|
|
682
723
|
content = file.read()
|
|
683
724
|
|
|
@@ -700,9 +741,11 @@ Example response format:
|
|
|
700
741
|
end_line = total_lines
|
|
701
742
|
|
|
702
743
|
selected_lines = lines[start_line - 1 : end_line]
|
|
703
|
-
return
|
|
744
|
+
return file_path, "\n".join(selected_lines)
|
|
745
|
+
|
|
746
|
+
return file_path, decoded_content
|
|
704
747
|
|
|
705
|
-
return
|
|
748
|
+
return file_path, decoded_content
|
|
706
749
|
|
|
707
750
|
def _build_file_tree(self, file_paths: List[str]) -> Dict[str, Any]:
|
|
708
751
|
"""Build a hierarchical tree structure from flat file paths.
|
|
@@ -109,7 +109,7 @@ def get_file_content_tool_definition(provider="claude"):
|
|
|
109
109
|
Returns:
|
|
110
110
|
Dict containing the tool definition
|
|
111
111
|
"""
|
|
112
|
-
tool_description = "Gets the content of a file, or a specific lines within that file (function or class body). Use this to examine the logic of specific functions, the structure of classes, or the overall content of a file."
|
|
112
|
+
tool_description = "Gets the content of a file, or a specific lines within that file (function or class body). Use this to examine the logic of specific functions, the structure of classes, or the overall content of a file. Also supports reading document files (PDF, DOCX, XLSX, PPTX, images) which will be converted to text/markdown - for document files, start_line and end_line parameters are ignored."
|
|
113
113
|
|
|
114
114
|
tool_arguments = {
|
|
115
115
|
"file_path": {
|
|
@@ -157,7 +157,7 @@ def get_file_content_tool_handler(
|
|
|
157
157
|
):
|
|
158
158
|
"""Returns a function that handles the get_file_content tool."""
|
|
159
159
|
|
|
160
|
-
def handler(**params)
|
|
160
|
+
def handler(**params):
|
|
161
161
|
file_path = params.get("file_path", "./")
|
|
162
162
|
start_line = params.get("start_line")
|
|
163
163
|
end_line = params.get("end_line")
|
|
@@ -168,16 +168,17 @@ def get_file_content_tool_handler(
|
|
|
168
168
|
if not os.path.isabs(file_path):
|
|
169
169
|
file_path = os.path.abspath(file_path)
|
|
170
170
|
|
|
171
|
-
|
|
171
|
+
path, file_content = code_analysis_service.get_file_content(
|
|
172
172
|
file_path, start_line=start_line, end_line=end_line
|
|
173
173
|
)
|
|
174
174
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
175
|
+
if isinstance(file_content, dict) and file_content.get("type") == "image_url":
|
|
176
|
+
return [
|
|
177
|
+
{"type": "text", "text": f"Image file: {path}"},
|
|
178
|
+
file_content,
|
|
179
|
+
]
|
|
179
180
|
|
|
180
|
-
return
|
|
181
|
+
return f"`{path}`: {file_content}"
|
|
181
182
|
|
|
182
183
|
return handler
|
|
183
184
|
|
|
@@ -233,6 +233,10 @@ class ChatCompleter(Completer):
|
|
|
233
233
|
"/delete_behavior",
|
|
234
234
|
"Delete an adaptive behavior (usage: /delete_behavior <id>)",
|
|
235
235
|
),
|
|
236
|
+
(
|
|
237
|
+
"/visual",
|
|
238
|
+
"Open visual mode to view raw message content with vim-like navigation",
|
|
239
|
+
),
|
|
236
240
|
("/exit", "Exit the application"),
|
|
237
241
|
("/quit", "Exit the application"),
|
|
238
242
|
]
|
|
@@ -494,6 +494,23 @@ class ConsoleUI(Observer):
|
|
|
494
494
|
self.print_welcome_message()
|
|
495
495
|
continue
|
|
496
496
|
|
|
497
|
+
elif user_input.strip() == "/visual":
|
|
498
|
+
self.input_handler._stop_input_thread()
|
|
499
|
+
try:
|
|
500
|
+
from .visual_mode import VisualModeViewer
|
|
501
|
+
|
|
502
|
+
viewer = VisualModeViewer(
|
|
503
|
+
console=self.console,
|
|
504
|
+
on_copy=self.copy_to_clipboard,
|
|
505
|
+
)
|
|
506
|
+
viewer.set_messages(
|
|
507
|
+
self.message_handler.streamline_messages
|
|
508
|
+
)
|
|
509
|
+
viewer.show()
|
|
510
|
+
finally:
|
|
511
|
+
self.input_handler._start_input_thread()
|
|
512
|
+
continue
|
|
513
|
+
|
|
497
514
|
# Handle toggle_session_yolo command directly (console only, session-based)
|
|
498
515
|
elif user_input.strip() == "/toggle_session_yolo":
|
|
499
516
|
self.command_handlers.handle_toggle_session_yolo_command()
|
|
@@ -494,6 +494,10 @@ class DisplayHandlers:
|
|
|
494
494
|
"Use '/unconsolidate' undo last consolidated.",
|
|
495
495
|
style=RICH_STYLE_YELLOW,
|
|
496
496
|
),
|
|
497
|
+
Text(
|
|
498
|
+
"Use '/visual' to view raw message content with vim-like navigation and copy.",
|
|
499
|
+
style=RICH_STYLE_YELLOW,
|
|
500
|
+
),
|
|
497
501
|
Text(
|
|
498
502
|
"Tool calls require confirmation before execution.",
|
|
499
503
|
style=RICH_STYLE_BLUE,
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"""Visual mode viewer for raw message content."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import TYPE_CHECKING, List, Dict, Any, Optional, Callable
|
|
6
|
+
|
|
7
|
+
from rich.console import Console
|
|
8
|
+
from rich.text import Text
|
|
9
|
+
|
|
10
|
+
from .viewer_ui import VisualModeUI
|
|
11
|
+
from .viewer_input_handler import VisualModeInputHandler
|
|
12
|
+
from ..constants import RICH_STYLE_YELLOW
|
|
13
|
+
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
pass
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class VisualModeViewer:
|
|
19
|
+
"""Main class for visual mode viewing of raw message content."""
|
|
20
|
+
|
|
21
|
+
def __init__(
|
|
22
|
+
self,
|
|
23
|
+
console: Console,
|
|
24
|
+
on_copy: Optional[Callable[[str], None]] = None,
|
|
25
|
+
):
|
|
26
|
+
self._console = console
|
|
27
|
+
self._on_copy = on_copy
|
|
28
|
+
self._ui = VisualModeUI(console)
|
|
29
|
+
self._input_handler = VisualModeInputHandler(self._ui, on_copy=on_copy)
|
|
30
|
+
|
|
31
|
+
def set_messages(self, messages: List[Dict[str, Any]]):
|
|
32
|
+
self._ui.set_messages(messages)
|
|
33
|
+
|
|
34
|
+
def show(self):
|
|
35
|
+
if not self._ui._messages:
|
|
36
|
+
self._console.print(
|
|
37
|
+
Text("No messages to display in visual mode.", style=RICH_STYLE_YELLOW)
|
|
38
|
+
)
|
|
39
|
+
return
|
|
40
|
+
|
|
41
|
+
self._input_handler.run()
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
"""Input handler for visual mode viewer."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import TYPE_CHECKING, Optional, Callable
|
|
6
|
+
|
|
7
|
+
from prompt_toolkit import PromptSession
|
|
8
|
+
from prompt_toolkit.key_binding import KeyBindings
|
|
9
|
+
from prompt_toolkit.keys import Keys
|
|
10
|
+
|
|
11
|
+
from loguru import logger
|
|
12
|
+
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
from .viewer_ui import VisualModeUI
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class VisualModeInputHandler:
|
|
18
|
+
"""Handles keyboard input for the visual mode viewer."""
|
|
19
|
+
|
|
20
|
+
def __init__(
|
|
21
|
+
self,
|
|
22
|
+
ui: VisualModeUI,
|
|
23
|
+
on_copy: Optional[Callable[[str], None]] = None,
|
|
24
|
+
):
|
|
25
|
+
self._ui = ui
|
|
26
|
+
self._running = False
|
|
27
|
+
self._g_pressed = False
|
|
28
|
+
self._on_copy = on_copy
|
|
29
|
+
|
|
30
|
+
def _create_key_bindings(self) -> KeyBindings:
|
|
31
|
+
kb = KeyBindings()
|
|
32
|
+
|
|
33
|
+
@kb.add(Keys.Up)
|
|
34
|
+
@kb.add("k")
|
|
35
|
+
def _(event):
|
|
36
|
+
if self._ui._search_mode:
|
|
37
|
+
return
|
|
38
|
+
self._g_pressed = False
|
|
39
|
+
if self._ui.move_cursor("up"):
|
|
40
|
+
self._ui.render()
|
|
41
|
+
|
|
42
|
+
@kb.add(Keys.Down)
|
|
43
|
+
@kb.add("j")
|
|
44
|
+
def _(event):
|
|
45
|
+
if self._ui._search_mode:
|
|
46
|
+
return
|
|
47
|
+
self._g_pressed = False
|
|
48
|
+
if self._ui.move_cursor("down"):
|
|
49
|
+
self._ui.render()
|
|
50
|
+
|
|
51
|
+
@kb.add(Keys.Left)
|
|
52
|
+
@kb.add("h")
|
|
53
|
+
def _(event):
|
|
54
|
+
if self._ui._search_mode:
|
|
55
|
+
return
|
|
56
|
+
self._g_pressed = False
|
|
57
|
+
if self._ui.move_cursor("left"):
|
|
58
|
+
self._ui.render()
|
|
59
|
+
|
|
60
|
+
@kb.add(Keys.Right)
|
|
61
|
+
@kb.add("l")
|
|
62
|
+
def _(event):
|
|
63
|
+
if self._ui._search_mode:
|
|
64
|
+
return
|
|
65
|
+
self._g_pressed = False
|
|
66
|
+
if self._ui.move_cursor("right"):
|
|
67
|
+
self._ui.render()
|
|
68
|
+
|
|
69
|
+
@kb.add("w")
|
|
70
|
+
def _(event):
|
|
71
|
+
if self._ui._search_mode:
|
|
72
|
+
self._ui.append_search_char("w")
|
|
73
|
+
self._ui.render()
|
|
74
|
+
return
|
|
75
|
+
self._g_pressed = False
|
|
76
|
+
if self._ui.move_cursor("word_forward"):
|
|
77
|
+
self._ui.render()
|
|
78
|
+
|
|
79
|
+
@kb.add("b")
|
|
80
|
+
def _(event):
|
|
81
|
+
if self._ui._search_mode:
|
|
82
|
+
self._ui.append_search_char("b")
|
|
83
|
+
self._ui.render()
|
|
84
|
+
return
|
|
85
|
+
self._g_pressed = False
|
|
86
|
+
if self._ui.move_cursor("word_backward"):
|
|
87
|
+
self._ui.render()
|
|
88
|
+
|
|
89
|
+
@kb.add("0")
|
|
90
|
+
def _(event):
|
|
91
|
+
if self._ui._search_mode:
|
|
92
|
+
self._ui.append_search_char("0")
|
|
93
|
+
self._ui.render()
|
|
94
|
+
return
|
|
95
|
+
self._g_pressed = False
|
|
96
|
+
if self._ui.move_cursor("line_start"):
|
|
97
|
+
self._ui.render()
|
|
98
|
+
|
|
99
|
+
@kb.add("$")
|
|
100
|
+
def _(event):
|
|
101
|
+
if self._ui._search_mode:
|
|
102
|
+
self._ui.append_search_char("$")
|
|
103
|
+
self._ui.render()
|
|
104
|
+
return
|
|
105
|
+
self._g_pressed = False
|
|
106
|
+
if self._ui.move_cursor("line_end"):
|
|
107
|
+
self._ui.render()
|
|
108
|
+
|
|
109
|
+
@kb.add("g")
|
|
110
|
+
def _(event):
|
|
111
|
+
if self._ui._search_mode:
|
|
112
|
+
self._ui.append_search_char("g")
|
|
113
|
+
self._ui.render()
|
|
114
|
+
return
|
|
115
|
+
if self._g_pressed:
|
|
116
|
+
self._g_pressed = False
|
|
117
|
+
if self._ui.move_cursor("top"):
|
|
118
|
+
self._ui.render()
|
|
119
|
+
else:
|
|
120
|
+
self._g_pressed = True
|
|
121
|
+
|
|
122
|
+
@kb.add("G")
|
|
123
|
+
def _(event):
|
|
124
|
+
if self._ui._search_mode:
|
|
125
|
+
self._ui.append_search_char("G")
|
|
126
|
+
self._ui.render()
|
|
127
|
+
return
|
|
128
|
+
self._g_pressed = False
|
|
129
|
+
if self._ui.move_cursor("bottom"):
|
|
130
|
+
self._ui.render()
|
|
131
|
+
|
|
132
|
+
@kb.add(Keys.ControlU)
|
|
133
|
+
def _(event):
|
|
134
|
+
if self._ui._search_mode:
|
|
135
|
+
return
|
|
136
|
+
self._g_pressed = False
|
|
137
|
+
if self._ui.move_cursor("half_up"):
|
|
138
|
+
self._ui.render()
|
|
139
|
+
|
|
140
|
+
@kb.add(Keys.ControlD)
|
|
141
|
+
def _(event):
|
|
142
|
+
if self._ui._search_mode:
|
|
143
|
+
return
|
|
144
|
+
self._g_pressed = False
|
|
145
|
+
if self._ui.move_cursor("half_down"):
|
|
146
|
+
self._ui.render()
|
|
147
|
+
|
|
148
|
+
@kb.add(Keys.PageUp)
|
|
149
|
+
def _(event):
|
|
150
|
+
if self._ui._search_mode:
|
|
151
|
+
return
|
|
152
|
+
self._g_pressed = False
|
|
153
|
+
if self._ui.move_cursor("page_up"):
|
|
154
|
+
self._ui.render()
|
|
155
|
+
|
|
156
|
+
@kb.add(Keys.PageDown)
|
|
157
|
+
def _(event):
|
|
158
|
+
if self._ui._search_mode:
|
|
159
|
+
return
|
|
160
|
+
self._g_pressed = False
|
|
161
|
+
if self._ui.move_cursor("page_down"):
|
|
162
|
+
self._ui.render()
|
|
163
|
+
|
|
164
|
+
@kb.add("v")
|
|
165
|
+
def _(event):
|
|
166
|
+
if self._ui._search_mode:
|
|
167
|
+
self._ui.append_search_char("v")
|
|
168
|
+
self._ui.render()
|
|
169
|
+
return
|
|
170
|
+
self._g_pressed = False
|
|
171
|
+
self._ui.toggle_visual_mode()
|
|
172
|
+
self._ui.render()
|
|
173
|
+
|
|
174
|
+
@kb.add("y")
|
|
175
|
+
def _(event):
|
|
176
|
+
if self._ui._search_mode:
|
|
177
|
+
self._ui.append_search_char("y")
|
|
178
|
+
self._ui.render()
|
|
179
|
+
return
|
|
180
|
+
self._g_pressed = False
|
|
181
|
+
text = self._ui.get_selected_text()
|
|
182
|
+
if text and self._on_copy:
|
|
183
|
+
self._on_copy(text)
|
|
184
|
+
if self._ui._visual_mode:
|
|
185
|
+
self._ui.toggle_visual_mode()
|
|
186
|
+
self._ui.render()
|
|
187
|
+
|
|
188
|
+
@kb.add("Y")
|
|
189
|
+
def _(event):
|
|
190
|
+
if self._ui._search_mode:
|
|
191
|
+
self._ui.append_search_char("Y")
|
|
192
|
+
self._ui.render()
|
|
193
|
+
return
|
|
194
|
+
self._g_pressed = False
|
|
195
|
+
if 0 <= self._ui._cursor_line < len(self._ui._lines):
|
|
196
|
+
line_text = self._ui._lines[self._ui._cursor_line][0]
|
|
197
|
+
if self._on_copy:
|
|
198
|
+
self._on_copy(line_text)
|
|
199
|
+
|
|
200
|
+
@kb.add("/")
|
|
201
|
+
def _(event):
|
|
202
|
+
if self._ui._search_mode:
|
|
203
|
+
self._ui.append_search_char("/")
|
|
204
|
+
self._ui.render()
|
|
205
|
+
return
|
|
206
|
+
self._g_pressed = False
|
|
207
|
+
self._ui.start_search_mode()
|
|
208
|
+
self._ui.render()
|
|
209
|
+
|
|
210
|
+
@kb.add("n")
|
|
211
|
+
def _(event):
|
|
212
|
+
if self._ui._search_mode:
|
|
213
|
+
self._ui.append_search_char("n")
|
|
214
|
+
self._ui.render()
|
|
215
|
+
return
|
|
216
|
+
self._g_pressed = False
|
|
217
|
+
self._ui.next_search_match()
|
|
218
|
+
self._ui.render()
|
|
219
|
+
|
|
220
|
+
@kb.add("N")
|
|
221
|
+
def _(event):
|
|
222
|
+
if self._ui._search_mode:
|
|
223
|
+
self._ui.append_search_char("N")
|
|
224
|
+
self._ui.render()
|
|
225
|
+
return
|
|
226
|
+
self._g_pressed = False
|
|
227
|
+
self._ui.prev_search_match()
|
|
228
|
+
self._ui.render()
|
|
229
|
+
|
|
230
|
+
@kb.add(Keys.Enter)
|
|
231
|
+
def _(event):
|
|
232
|
+
if self._ui._search_mode:
|
|
233
|
+
self._ui.exit_search_mode(clear_results=False)
|
|
234
|
+
self._ui.render()
|
|
235
|
+
|
|
236
|
+
@kb.add(Keys.Backspace)
|
|
237
|
+
def _(event):
|
|
238
|
+
if self._ui._search_mode:
|
|
239
|
+
self._ui.backspace_search()
|
|
240
|
+
self._ui.render()
|
|
241
|
+
|
|
242
|
+
@kb.add(Keys.Escape)
|
|
243
|
+
def _(event):
|
|
244
|
+
self._g_pressed = False
|
|
245
|
+
if self._ui._visual_mode:
|
|
246
|
+
self._ui.toggle_visual_mode()
|
|
247
|
+
self._ui.render()
|
|
248
|
+
elif self._ui._search_mode:
|
|
249
|
+
self._ui.exit_search_mode(clear_results=True)
|
|
250
|
+
self._ui.render()
|
|
251
|
+
else:
|
|
252
|
+
event.app.exit()
|
|
253
|
+
|
|
254
|
+
@kb.add("q")
|
|
255
|
+
def _(event):
|
|
256
|
+
if self._ui._search_mode:
|
|
257
|
+
self._ui.append_search_char("q")
|
|
258
|
+
self._ui.render()
|
|
259
|
+
return
|
|
260
|
+
self._g_pressed = False
|
|
261
|
+
event.app.exit()
|
|
262
|
+
|
|
263
|
+
@kb.add(Keys.ControlC)
|
|
264
|
+
def _(event):
|
|
265
|
+
self._g_pressed = False
|
|
266
|
+
if self._ui._visual_mode:
|
|
267
|
+
text = self._ui.get_selected_text()
|
|
268
|
+
if text and self._on_copy:
|
|
269
|
+
self._on_copy(text)
|
|
270
|
+
self._ui.toggle_visual_mode()
|
|
271
|
+
self._ui.render()
|
|
272
|
+
elif self._ui._search_mode:
|
|
273
|
+
self._ui.exit_search_mode(clear_results=True)
|
|
274
|
+
self._ui.render()
|
|
275
|
+
else:
|
|
276
|
+
event.app.exit()
|
|
277
|
+
|
|
278
|
+
@kb.add(Keys.Any)
|
|
279
|
+
def _(event):
|
|
280
|
+
if self._ui._search_mode:
|
|
281
|
+
char = event.data
|
|
282
|
+
if char and char.isprintable():
|
|
283
|
+
self._ui.append_search_char(char)
|
|
284
|
+
self._ui.render()
|
|
285
|
+
return
|
|
286
|
+
self._g_pressed = False
|
|
287
|
+
|
|
288
|
+
return kb
|
|
289
|
+
|
|
290
|
+
def run(self):
|
|
291
|
+
self._running = True
|
|
292
|
+
self._g_pressed = False
|
|
293
|
+
|
|
294
|
+
self._ui.start_live()
|
|
295
|
+
|
|
296
|
+
kb = self._create_key_bindings()
|
|
297
|
+
|
|
298
|
+
try:
|
|
299
|
+
session = PromptSession(key_bindings=kb)
|
|
300
|
+
session.prompt("")
|
|
301
|
+
except (KeyboardInterrupt, EOFError):
|
|
302
|
+
pass
|
|
303
|
+
except Exception as e:
|
|
304
|
+
logger.error(f"Error in visual mode input handler: {e}")
|
|
305
|
+
finally:
|
|
306
|
+
self._ui.stop_live()
|
|
307
|
+
|
|
308
|
+
self._running = False
|
|
309
|
+
|
|
310
|
+
@property
|
|
311
|
+
def is_running(self) -> bool:
|
|
312
|
+
return self._running
|
|
313
|
+
|
|
314
|
+
def stop(self):
|
|
315
|
+
self._running = False
|