agentcrew-ai 0.8.3__tar.gz → 0.8.5__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.8.5/AgentCrew/__init__.py +1 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/main.py +3 -1
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/a2a/agent_cards.py +8 -2
- agentcrew_ai-0.8.5/AgentCrew/modules/a2a/errors.py +72 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/a2a/server.py +21 -2
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/a2a/task_manager.py +180 -39
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/agents/local_agent.py +1 -1
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/browser_automation/element_extractor.py +1 -1
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/browser_automation/js/extract_clickable_elements.js +2 -4
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/browser_automation/service.py +17 -7
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/chat/message/command_processor.py +9 -1
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/chat/message/conversation.py +1 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/chat/message/handler.py +3 -6
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/code_analysis/service.py +39 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/code_analysis/tool.py +10 -1
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/console/command_handlers.py +186 -1
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/console/completers.py +67 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/console/confirmation_handler.py +83 -38
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/console/console_ui.py +86 -28
- agentcrew_ai-0.8.5/AgentCrew/modules/console/diff_display.py +203 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/console/display_handlers.py +15 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/console/input_handler.py +1 -1
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/console/tool_display.py +35 -4
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/console/ui_effects.py +30 -14
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/custom_llm/deepinfra_service.py +20 -19
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/custom_llm/github_copilot_service.py +157 -2
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/custom_llm/service.py +1 -9
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/widgets/message_bubble.py +1 -6
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/llm/model_registry.py +1 -1
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/memory/chroma_service.py +0 -1
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/memory/context_persistent.py +10 -4
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/memory/tool.py +2 -3
- {agentcrew_ai-0.8.3/agentcrew_ai.egg-info → agentcrew_ai-0.8.5}/PKG-INFO +3 -3
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5/agentcrew_ai.egg-info}/PKG-INFO +3 -3
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/agentcrew_ai.egg-info/SOURCES.txt +2 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/agentcrew_ai.egg-info/requires.txt +2 -2
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/pyproject.toml +3 -3
- agentcrew_ai-0.8.3/AgentCrew/__init__.py +0 -1
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/app.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/assets/agentcrew_logo.png +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/main_docker.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/__init__.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/a2a/__init__.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/a2a/adapters.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/a2a/common/__init__.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/a2a/common/client/__init__.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/a2a/common/client/card_resolver.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/a2a/common/client/client.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/a2a/common/server/__init__.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/a2a/common/server/auth_middleware.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/a2a/common/server/task_manager.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/a2a/common/server/utils.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/a2a/registry.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/agents/__init__.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/agents/base.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/agents/example.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/agents/manager.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/agents/remote_agent.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/agents/tools/__init__.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/agents/tools/ask.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/agents/tools/delegate.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/agents/tools/transfer.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/anthropic/__init__.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/anthropic/service.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/browser_automation/__init__.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/browser_automation/chrome_manager.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/browser_automation/js/click_element.js +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/browser_automation/js/draw_element_boxes.js +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/browser_automation/js/extract_elements_by_text.js +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/browser_automation/js/extract_input_elements.js +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/browser_automation/js/extract_scrollable_elements.js +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/browser_automation/js/filter_hidden_elements.js +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/browser_automation/js/focus_and_clear_element.js +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/browser_automation/js/remove_element_boxes.js +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/browser_automation/js/scroll_page.js +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/browser_automation/js/trigger_input_events.js +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/browser_automation/js_loader.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/browser_automation/tool.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/chat/__init__.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/chat/consolidation.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/chat/file_handler.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/chat/history.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/chat/message/__init__.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/chat/message/base.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/chat/message/tool_manager.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/chat/message_handler.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/clipboard/__init__.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/clipboard/service.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/clipboard/tool.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/code_analysis/__init__.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/command_execution/__init__.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/command_execution/constants.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/command_execution/metric.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/command_execution/service.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/command_execution/tool.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/command_execution/types.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/config/__init__.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/config/config_management.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/console/__init__.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/console/constants.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/console/conversation_handler.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/console/utils.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/custom_llm/__init__.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/custom_llm/copilot_response_service.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/file_editing/__init__.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/file_editing/safety_validator.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/file_editing/search_replace_engine.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/file_editing/service.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/file_editing/tool.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/file_editing/tree_sitter_checker.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/google/__init__.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/google/native_service.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/google/service.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/groq/__init__.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/groq/service.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/__init__.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/components/__init__.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/components/chat_components.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/components/command_handler.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/components/completers.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/components/conversation_components.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/components/input_components.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/components/keyboard_handler.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/components/menu_components.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/components/message_handlers.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/components/tool_handlers.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/components/ui_state_manager.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/qt_ui.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/themes/README.md +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/themes/__init__.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/themes/atom_light.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/themes/catppuccin.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/themes/dracula.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/themes/nord.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/themes/saigontech.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/themes/style_provider.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/themes/unicorn.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/utils/__init__.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/utils/macos_clipboard.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/utils/strings.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/utils/wins_clipboard.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/widgets/__init__.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/widgets/config_window.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/widgets/configs/__init__.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/widgets/configs/agent_config.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/widgets/configs/custom_llm_provider.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/widgets/configs/global_settings.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/widgets/configs/mcp_config.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/widgets/configs/save_worker.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/widgets/history_sidebar.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/widgets/json_editor.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/widgets/loading_overlay.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/widgets/markdown_editor.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/widgets/paste_aware_textedit.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/widgets/system_message.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/widgets/token_usage.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/widgets/tool_widget.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/worker.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/image_generation/__init__.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/image_generation/service.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/image_generation/tool.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/llm/__init__.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/llm/base.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/llm/constants.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/llm/service_manager.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/llm/types.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/mcpclient/__init__.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/mcpclient/auth.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/mcpclient/config.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/mcpclient/manager.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/mcpclient/service.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/mcpclient/tool.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/memory/__init__.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/memory/base_service.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/memory/github_copilot_ef.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/memory/google_genai_ef.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/memory/voyageai_ef.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/openai/__init__.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/openai/response_service.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/openai/service.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/prompts/__init__.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/prompts/constants.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/tools/README.md +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/tools/registration.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/tools/registry.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/voice/__init__.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/voice/audio_handler.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/voice/base.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/voice/deepinfra_service.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/voice/elevenlabs_service.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/voice/text_cleaner.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/web_search/__init__.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/web_search/service.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/web_search/tool.py +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/CONTRIBUTING.md +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/LICENSE +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/MANIFEST.in +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/README.md +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/agentcrew_ai.egg-info/dependency_links.txt +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/agentcrew_ai.egg-info/entry_points.txt +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/agentcrew_ai.egg-info/top_level.txt +0 -0
- {agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/setup.cfg +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.8.5"
|
|
@@ -58,7 +58,9 @@ def common_options(func):
|
|
|
58
58
|
help="LLM provider to use (claude, groq, openai, google, github_copilot, or deepinfra)",
|
|
59
59
|
)
|
|
60
60
|
@click.option(
|
|
61
|
-
"--agent-config",
|
|
61
|
+
"--agent-config",
|
|
62
|
+
default=None,
|
|
63
|
+
help="Path/URL to the agent configuration file.",
|
|
62
64
|
)
|
|
63
65
|
@click.option(
|
|
64
66
|
"--mcp-config", default=None, help="Path to the mcp servers configuration file."
|
|
@@ -11,6 +11,8 @@ from a2a.types import (
|
|
|
11
11
|
SecurityScheme,
|
|
12
12
|
APIKeySecurityScheme,
|
|
13
13
|
AgentProvider,
|
|
14
|
+
AgentInterface,
|
|
15
|
+
TransportProtocol,
|
|
14
16
|
)
|
|
15
17
|
from AgentCrew import __version__
|
|
16
18
|
|
|
@@ -107,16 +109,20 @@ def create_agent_card(agent: LocalAgent, base_url: str) -> AgentCard:
|
|
|
107
109
|
)
|
|
108
110
|
|
|
109
111
|
return AgentCard(
|
|
112
|
+
protocol_version="0.3.0",
|
|
110
113
|
name=agent.name if hasattr(agent, "name") else "AgentCrew Assistant",
|
|
111
114
|
description=agent.description
|
|
112
115
|
if hasattr(agent, "description")
|
|
113
116
|
else "An AI assistant powered by AgentCrew",
|
|
114
117
|
url=base_url,
|
|
118
|
+
preferred_transport=TransportProtocol.jsonrpc,
|
|
119
|
+
additional_interfaces=[
|
|
120
|
+
AgentInterface(url=base_url, transport=TransportProtocol.jsonrpc)
|
|
121
|
+
],
|
|
115
122
|
provider=provider,
|
|
116
|
-
version=__version__,
|
|
123
|
+
version=__version__,
|
|
117
124
|
capabilities=capabilities,
|
|
118
125
|
skills=skills,
|
|
119
|
-
# Most SwissKnife agents work with text and files
|
|
120
126
|
default_input_modes=["text/plain", "application/octet-stream"],
|
|
121
127
|
default_output_modes=["text/plain", "application/octet-stream"],
|
|
122
128
|
security_schemes={"apiKey": security_schemes},
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"""
|
|
2
|
+
A2A-specific error code helpers for proper error handling.
|
|
3
|
+
|
|
4
|
+
This module provides convenience functions for creating A2A-specific errors
|
|
5
|
+
with contextual data according to the A2A protocol v0.3.0 specification.
|
|
6
|
+
|
|
7
|
+
Error Codes (Section 8.2):
|
|
8
|
+
- -32001: TaskNotFoundError
|
|
9
|
+
- -32002: TaskNotCancelableError
|
|
10
|
+
- -32003: PushNotificationNotSupportedError
|
|
11
|
+
- -32004: UnsupportedOperationError
|
|
12
|
+
- -32005: ContentTypeNotSupportedError
|
|
13
|
+
- -32006: InvalidAgentResponseError
|
|
14
|
+
- -32007: AuthenticatedExtendedCardNotConfiguredError
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from typing import Optional
|
|
18
|
+
from a2a.types import (
|
|
19
|
+
TaskNotFoundError,
|
|
20
|
+
TaskNotCancelableError,
|
|
21
|
+
PushNotificationNotSupportedError,
|
|
22
|
+
UnsupportedOperationError,
|
|
23
|
+
ContentTypeNotSupportedError,
|
|
24
|
+
InvalidAgentResponseError,
|
|
25
|
+
AuthenticatedExtendedCardNotConfiguredError,
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class A2AError:
|
|
30
|
+
@staticmethod
|
|
31
|
+
def task_not_found(task_id: str) -> TaskNotFoundError:
|
|
32
|
+
error = TaskNotFoundError()
|
|
33
|
+
error.data = {"task_id": task_id}
|
|
34
|
+
return error
|
|
35
|
+
|
|
36
|
+
@staticmethod
|
|
37
|
+
def task_not_cancelable(task_id: str, current_state: str) -> TaskNotCancelableError:
|
|
38
|
+
error = TaskNotCancelableError()
|
|
39
|
+
error.data = {"task_id": task_id, "state": current_state}
|
|
40
|
+
return error
|
|
41
|
+
|
|
42
|
+
@staticmethod
|
|
43
|
+
def push_notification_not_supported() -> PushNotificationNotSupportedError:
|
|
44
|
+
return PushNotificationNotSupportedError()
|
|
45
|
+
|
|
46
|
+
@staticmethod
|
|
47
|
+
def unsupported_operation(operation: str) -> UnsupportedOperationError:
|
|
48
|
+
error = UnsupportedOperationError()
|
|
49
|
+
error.data = {"operation": operation}
|
|
50
|
+
return error
|
|
51
|
+
|
|
52
|
+
@staticmethod
|
|
53
|
+
def content_type_not_supported(
|
|
54
|
+
mime_type: str, supported_types: Optional[list[str]] = None
|
|
55
|
+
) -> ContentTypeNotSupportedError:
|
|
56
|
+
error = ContentTypeNotSupportedError()
|
|
57
|
+
error.data = {"mime_type": mime_type}
|
|
58
|
+
if supported_types:
|
|
59
|
+
error.data["supported_types"] = supported_types
|
|
60
|
+
return error
|
|
61
|
+
|
|
62
|
+
@staticmethod
|
|
63
|
+
def invalid_agent_response(details: str) -> InvalidAgentResponseError:
|
|
64
|
+
error = InvalidAgentResponseError()
|
|
65
|
+
error.data = {"details": details}
|
|
66
|
+
return error
|
|
67
|
+
|
|
68
|
+
@staticmethod
|
|
69
|
+
def authenticated_extended_card_not_configured() -> (
|
|
70
|
+
AuthenticatedExtendedCardNotConfiguredError
|
|
71
|
+
):
|
|
72
|
+
return AuthenticatedExtendedCardNotConfiguredError()
|
|
@@ -20,7 +20,6 @@ from .registry import AgentRegistry
|
|
|
20
20
|
from .task_manager import MultiAgentTaskManager
|
|
21
21
|
from a2a.types import (
|
|
22
22
|
A2ARequest,
|
|
23
|
-
JSONRPCError,
|
|
24
23
|
JSONRPCResponse,
|
|
25
24
|
JSONRPCErrorResponse,
|
|
26
25
|
InvalidRequestError,
|
|
@@ -30,6 +29,8 @@ from a2a.types import (
|
|
|
30
29
|
SendStreamingMessageRequest,
|
|
31
30
|
GetTaskRequest,
|
|
32
31
|
CancelTaskRequest,
|
|
32
|
+
TaskResubscriptionRequest,
|
|
33
|
+
MethodNotFoundError,
|
|
33
34
|
)
|
|
34
35
|
|
|
35
36
|
|
|
@@ -228,13 +229,31 @@ class A2AServer:
|
|
|
228
229
|
result = await task_manager.on_cancel_task(json_rpc_request.root)
|
|
229
230
|
return JSONResponse(result.model_dump(exclude_none=True))
|
|
230
231
|
|
|
232
|
+
elif method == "tasks/resubscribe" and isinstance(
|
|
233
|
+
json_rpc_request.root, TaskResubscriptionRequest
|
|
234
|
+
):
|
|
235
|
+
result_stream = task_manager.on_resubscribe_to_task(
|
|
236
|
+
json_rpc_request.root
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
if isinstance(result_stream, JSONRPCResponse):
|
|
240
|
+
return JSONResponse(result_stream.model_dump(exclude_none=True))
|
|
241
|
+
|
|
242
|
+
async def event_generator():
|
|
243
|
+
async for item in result_stream: # type: ignore
|
|
244
|
+
yield {
|
|
245
|
+
"data": json.dumps(item.model_dump(exclude_none=True))
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
return EventSourceResponse(event_generator())
|
|
249
|
+
|
|
231
250
|
else:
|
|
232
251
|
logger.error(f"Invalid method requested: {method}")
|
|
233
252
|
logger.error(f"Request ID: {json_rpc_request.root.id}")
|
|
234
253
|
logger.error(f"Request params: {json_rpc_request.root.params}") # type: ignore
|
|
235
254
|
error = JSONRPCErrorResponse(
|
|
236
255
|
id=json_rpc_request.root.id,
|
|
237
|
-
error=
|
|
256
|
+
error=MethodNotFoundError(),
|
|
238
257
|
)
|
|
239
258
|
return JSONResponse(
|
|
240
259
|
error.model_dump(exclude_none=True), status_code=400
|
|
@@ -3,6 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
import asyncio
|
|
4
4
|
from datetime import datetime
|
|
5
5
|
from typing import TYPE_CHECKING
|
|
6
|
+
from collections import defaultdict
|
|
6
7
|
from AgentCrew.modules.agents.base import MessageType
|
|
7
8
|
from loguru import logger
|
|
8
9
|
import tempfile
|
|
@@ -26,8 +27,6 @@ from a2a.types import (
|
|
|
26
27
|
TaskState,
|
|
27
28
|
TaskStatusUpdateEvent,
|
|
28
29
|
TaskArtifactUpdateEvent,
|
|
29
|
-
TaskNotFoundError,
|
|
30
|
-
TaskNotCancelableError,
|
|
31
30
|
)
|
|
32
31
|
|
|
33
32
|
from AgentCrew.modules.agents import LocalAgent
|
|
@@ -37,12 +36,14 @@ from .adapters import (
|
|
|
37
36
|
convert_agent_message_to_a2a,
|
|
38
37
|
)
|
|
39
38
|
from .common.server.task_manager import TaskManager
|
|
39
|
+
from .errors import A2AError
|
|
40
40
|
|
|
41
41
|
if TYPE_CHECKING:
|
|
42
42
|
from typing import Any, AsyncIterable, Dict, Optional, Union
|
|
43
43
|
from AgentCrew.modules.agents import AgentManager
|
|
44
44
|
from a2a.types import (
|
|
45
45
|
CancelTaskRequest,
|
|
46
|
+
TaskNotCancelableError,
|
|
46
47
|
GetTaskPushNotificationConfigRequest,
|
|
47
48
|
GetTaskRequest,
|
|
48
49
|
SendMessageRequest,
|
|
@@ -56,6 +57,8 @@ if TYPE_CHECKING:
|
|
|
56
57
|
class AgentTaskManager(TaskManager):
|
|
57
58
|
"""Manages tasks for a specific agent"""
|
|
58
59
|
|
|
60
|
+
TERMINAL_STATES = {TaskState.completed, TaskState.canceled, TaskState.failed}
|
|
61
|
+
|
|
59
62
|
def __init__(self, agent_name: str, agent_manager: AgentManager):
|
|
60
63
|
self.agent_name = agent_name
|
|
61
64
|
self.agent_manager = agent_manager
|
|
@@ -64,12 +67,38 @@ class AgentTaskManager(TaskManager):
|
|
|
64
67
|
self.streaming_tasks: Dict[str, asyncio.Queue] = {}
|
|
65
68
|
self.file_handler = None
|
|
66
69
|
|
|
70
|
+
self.task_events: Dict[
|
|
71
|
+
str, list[Union[TaskStatusUpdateEvent, TaskArtifactUpdateEvent]]
|
|
72
|
+
] = defaultdict(list)
|
|
73
|
+
self.streaming_enabled_tasks: set[str] = set()
|
|
74
|
+
|
|
67
75
|
self.agent = self.agent_manager.get_agent(self.agent_name)
|
|
68
76
|
if self.agent is None or not isinstance(self.agent, LocalAgent):
|
|
69
77
|
raise ValueError(f"Agent {agent_name} not found or is not a LocalAgent")
|
|
70
78
|
|
|
71
79
|
self.memory_service = self.agent.services["memory"]
|
|
72
80
|
|
|
81
|
+
def _is_terminal_state(self, state: TaskState) -> bool:
|
|
82
|
+
"""Check if a state is terminal."""
|
|
83
|
+
return state in self.TERMINAL_STATES
|
|
84
|
+
|
|
85
|
+
def _validate_task_not_terminal(
|
|
86
|
+
self, task: Task, operation: str
|
|
87
|
+
) -> Optional[TaskNotCancelableError]:
|
|
88
|
+
"""
|
|
89
|
+
Validate that task is not in terminal state.
|
|
90
|
+
|
|
91
|
+
Args:
|
|
92
|
+
task: Task to check
|
|
93
|
+
operation: Operation being attempted
|
|
94
|
+
|
|
95
|
+
Returns:
|
|
96
|
+
JSONRPCError if invalid, None if valid
|
|
97
|
+
"""
|
|
98
|
+
if self._is_terminal_state(task.status.state):
|
|
99
|
+
return A2AError.task_not_cancelable(task.id, task.status.state.value)
|
|
100
|
+
return None
|
|
101
|
+
|
|
73
102
|
async def on_send_message(
|
|
74
103
|
self, request: SendMessageRequest | SendStreamingMessageRequest
|
|
75
104
|
) -> SendMessageResponse:
|
|
@@ -98,6 +127,14 @@ class AgentTaskManager(TaskManager):
|
|
|
98
127
|
or f"task_{request.params.message.message_id}"
|
|
99
128
|
)
|
|
100
129
|
|
|
130
|
+
if task_id in self.tasks:
|
|
131
|
+
existing_task = self.tasks[task_id]
|
|
132
|
+
error = self._validate_task_not_terminal(existing_task, "send message")
|
|
133
|
+
if error:
|
|
134
|
+
return SendMessageResponse(
|
|
135
|
+
root=JSONRPCErrorResponse(id=request.id, error=error)
|
|
136
|
+
)
|
|
137
|
+
|
|
101
138
|
if task_id not in self.tasks:
|
|
102
139
|
# Create task with initial state
|
|
103
140
|
task = Task(
|
|
@@ -176,6 +213,8 @@ class AgentTaskManager(TaskManager):
|
|
|
176
213
|
or f"task_{request.params.message.message_id}"
|
|
177
214
|
)
|
|
178
215
|
|
|
216
|
+
self.streaming_enabled_tasks.add(task_id)
|
|
217
|
+
|
|
179
218
|
# Create streaming queue
|
|
180
219
|
queue = asyncio.Queue()
|
|
181
220
|
self.streaming_tasks[task_id] = queue
|
|
@@ -204,6 +243,27 @@ class AgentTaskManager(TaskManager):
|
|
|
204
243
|
# Clean up
|
|
205
244
|
self.streaming_tasks.pop(task_id, None)
|
|
206
245
|
|
|
246
|
+
def _record_and_emit_event(
|
|
247
|
+
self, task_id: str, event: Union[TaskStatusUpdateEvent, TaskArtifactUpdateEvent]
|
|
248
|
+
):
|
|
249
|
+
"""
|
|
250
|
+
Record event for replay and broadcast to all active subscribers.
|
|
251
|
+
|
|
252
|
+
Args:
|
|
253
|
+
task_id: Task ID
|
|
254
|
+
event: Event to record and emit
|
|
255
|
+
"""
|
|
256
|
+
self.task_events[task_id].append(event)
|
|
257
|
+
|
|
258
|
+
for key, queue in list(self.streaming_tasks.items()):
|
|
259
|
+
if key.startswith(task_id):
|
|
260
|
+
try:
|
|
261
|
+
queue.put_nowait(event)
|
|
262
|
+
except asyncio.QueueFull:
|
|
263
|
+
logger.warning(f"Queue full for {key}")
|
|
264
|
+
except Exception as e:
|
|
265
|
+
logger.error(f"Error emitting event to {key}: {e}")
|
|
266
|
+
|
|
207
267
|
async def _process_agent_task(self, agent: LocalAgent, task: Task):
|
|
208
268
|
"""
|
|
209
269
|
Process a task with the agent (background task).
|
|
@@ -213,6 +273,12 @@ class AgentTaskManager(TaskManager):
|
|
|
213
273
|
message: The message to process
|
|
214
274
|
task: The task object to update
|
|
215
275
|
"""
|
|
276
|
+
if self._is_terminal_state(task.status.state):
|
|
277
|
+
logger.warning(
|
|
278
|
+
f"Attempted to process task {task.id} in terminal state {task.status.state}"
|
|
279
|
+
)
|
|
280
|
+
return
|
|
281
|
+
|
|
216
282
|
try:
|
|
217
283
|
artifacts = []
|
|
218
284
|
if task.id not in self.task_history:
|
|
@@ -253,15 +319,14 @@ class AgentTaskManager(TaskManager):
|
|
|
253
319
|
task.status.timestamp = datetime.now().isoformat()
|
|
254
320
|
|
|
255
321
|
# If this is a streaming task, send updates
|
|
256
|
-
if task.id in self.
|
|
257
|
-
queue = self.streaming_tasks[task.id]
|
|
258
|
-
|
|
322
|
+
if task.id in self.streaming_enabled_tasks:
|
|
259
323
|
# Send thinking update if available
|
|
260
324
|
if thinking_chunk:
|
|
261
325
|
think_text_chunk, signature = thinking_chunk
|
|
262
326
|
if think_text_chunk:
|
|
263
327
|
thinking_content += think_text_chunk
|
|
264
|
-
|
|
328
|
+
self._record_and_emit_event(
|
|
329
|
+
task.id,
|
|
265
330
|
TaskStatusUpdateEvent(
|
|
266
331
|
task_id=task.id,
|
|
267
332
|
context_id=task.context_id,
|
|
@@ -276,7 +341,7 @@ class AgentTaskManager(TaskManager):
|
|
|
276
341
|
),
|
|
277
342
|
),
|
|
278
343
|
final=False,
|
|
279
|
-
)
|
|
344
|
+
),
|
|
280
345
|
)
|
|
281
346
|
if signature:
|
|
282
347
|
thinking_signature += signature
|
|
@@ -287,30 +352,30 @@ class AgentTaskManager(TaskManager):
|
|
|
287
352
|
chunk_text,
|
|
288
353
|
artifact_id=f"artifact_{task.id}_{len(artifacts)}",
|
|
289
354
|
)
|
|
290
|
-
|
|
355
|
+
self._record_and_emit_event(
|
|
356
|
+
task.id,
|
|
291
357
|
TaskArtifactUpdateEvent(
|
|
292
358
|
task_id=task.id,
|
|
293
359
|
context_id=task.context_id,
|
|
294
360
|
artifact=artifact,
|
|
295
|
-
)
|
|
361
|
+
),
|
|
296
362
|
)
|
|
297
363
|
|
|
298
364
|
if tool_uses and len(tool_uses) > 0:
|
|
299
|
-
if task.id in self.
|
|
300
|
-
queue = self.streaming_tasks[task.id]
|
|
365
|
+
if task.id in self.streaming_enabled_tasks:
|
|
301
366
|
artifact = convert_agent_response_to_a2a_artifact(
|
|
302
367
|
"",
|
|
303
368
|
artifact_id=f"artifact_{task.id}_{len(artifacts)}",
|
|
304
369
|
tool_uses=tool_uses,
|
|
305
370
|
)
|
|
306
|
-
|
|
371
|
+
self._record_and_emit_event(
|
|
372
|
+
task.id,
|
|
307
373
|
TaskArtifactUpdateEvent(
|
|
308
374
|
task_id=task.id,
|
|
309
375
|
context_id=task.context_id,
|
|
310
376
|
artifact=artifact,
|
|
311
|
-
)
|
|
377
|
+
),
|
|
312
378
|
)
|
|
313
|
-
# prevent the execute_tool_call take the control of event loop before queue has been process
|
|
314
379
|
await asyncio.sleep(0.7)
|
|
315
380
|
|
|
316
381
|
# Add thinking content as a separate message if available
|
|
@@ -399,21 +464,21 @@ class AgentTaskManager(TaskManager):
|
|
|
399
464
|
task.artifacts = artifacts
|
|
400
465
|
|
|
401
466
|
# If this is a streaming task, send final update
|
|
402
|
-
if task.id in self.
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
# Send final status
|
|
406
|
-
await queue.put(
|
|
467
|
+
if task.id in self.streaming_enabled_tasks:
|
|
468
|
+
self._record_and_emit_event(
|
|
469
|
+
task.id,
|
|
407
470
|
TaskStatusUpdateEvent(
|
|
408
471
|
task_id=task.id,
|
|
409
472
|
context_id=task.context_id,
|
|
410
473
|
status=task.status,
|
|
411
474
|
final=True,
|
|
412
|
-
)
|
|
475
|
+
),
|
|
413
476
|
)
|
|
414
477
|
|
|
415
|
-
|
|
416
|
-
|
|
478
|
+
for key in list(self.streaming_tasks.keys()):
|
|
479
|
+
if key.startswith(task.id):
|
|
480
|
+
queue = self.streaming_tasks[key]
|
|
481
|
+
await queue.put(None)
|
|
417
482
|
|
|
418
483
|
except Exception as e:
|
|
419
484
|
logger.error(str(e))
|
|
@@ -422,17 +487,21 @@ class AgentTaskManager(TaskManager):
|
|
|
422
487
|
task.status.timestamp = datetime.now().isoformat()
|
|
423
488
|
|
|
424
489
|
# If this is a streaming task, send error
|
|
425
|
-
if task.id in self.
|
|
426
|
-
|
|
427
|
-
|
|
490
|
+
if task.id in self.streaming_enabled_tasks:
|
|
491
|
+
self._record_and_emit_event(
|
|
492
|
+
task.id,
|
|
428
493
|
TaskStatusUpdateEvent(
|
|
429
494
|
task_id=task.id,
|
|
430
495
|
context_id=task.context_id,
|
|
431
496
|
status=task.status,
|
|
432
497
|
final=True,
|
|
433
|
-
)
|
|
498
|
+
),
|
|
434
499
|
)
|
|
435
|
-
|
|
500
|
+
|
|
501
|
+
for key in list(self.streaming_tasks.keys()):
|
|
502
|
+
if key.startswith(task.id):
|
|
503
|
+
queue = self.streaming_tasks[key]
|
|
504
|
+
await queue.put(None)
|
|
436
505
|
|
|
437
506
|
async def on_get_task(self, request: GetTaskRequest) -> GetTaskResponse:
|
|
438
507
|
"""
|
|
@@ -447,7 +516,9 @@ class AgentTaskManager(TaskManager):
|
|
|
447
516
|
task_id = request.params.id
|
|
448
517
|
if task_id not in self.tasks:
|
|
449
518
|
return GetTaskResponse(
|
|
450
|
-
root=JSONRPCErrorResponse(
|
|
519
|
+
root=JSONRPCErrorResponse(
|
|
520
|
+
id=request.id, error=A2AError.task_not_found(task_id)
|
|
521
|
+
)
|
|
451
522
|
)
|
|
452
523
|
|
|
453
524
|
return GetTaskResponse(
|
|
@@ -467,19 +538,17 @@ class AgentTaskManager(TaskManager):
|
|
|
467
538
|
task_id = request.params.id
|
|
468
539
|
if task_id not in self.tasks:
|
|
469
540
|
return CancelTaskResponse(
|
|
470
|
-
root=JSONRPCErrorResponse(
|
|
541
|
+
root=JSONRPCErrorResponse(
|
|
542
|
+
id=request.id, error=A2AError.task_not_found(task_id)
|
|
543
|
+
)
|
|
471
544
|
)
|
|
472
545
|
|
|
473
546
|
task = self.tasks[task_id]
|
|
474
547
|
|
|
475
|
-
|
|
476
|
-
if
|
|
477
|
-
TaskState.completed,
|
|
478
|
-
TaskState.failed,
|
|
479
|
-
TaskState.canceled,
|
|
480
|
-
]:
|
|
548
|
+
error = self._validate_task_not_terminal(task, "cancel")
|
|
549
|
+
if error:
|
|
481
550
|
return CancelTaskResponse(
|
|
482
|
-
root=JSONRPCErrorResponse(id=request.id, error=
|
|
551
|
+
root=JSONRPCErrorResponse(id=request.id, error=error)
|
|
483
552
|
)
|
|
484
553
|
|
|
485
554
|
# Update task status
|
|
@@ -506,17 +575,89 @@ class AgentTaskManager(TaskManager):
|
|
|
506
575
|
async def on_set_task_push_notification(
|
|
507
576
|
self, request: SetTaskPushNotificationConfigRequest
|
|
508
577
|
) -> SetTaskPushNotificationConfigResponse:
|
|
509
|
-
|
|
578
|
+
return SetTaskPushNotificationConfigResponse(
|
|
579
|
+
root=JSONRPCErrorResponse(
|
|
580
|
+
id=request.id, error=A2AError.push_notification_not_supported()
|
|
581
|
+
)
|
|
582
|
+
)
|
|
510
583
|
|
|
511
584
|
async def on_get_task_push_notification(
|
|
512
585
|
self, request: GetTaskPushNotificationConfigRequest
|
|
513
586
|
) -> GetTaskPushNotificationConfigResponse:
|
|
514
|
-
|
|
587
|
+
return GetTaskPushNotificationConfigResponse(
|
|
588
|
+
root=JSONRPCErrorResponse(
|
|
589
|
+
id=request.id, error=A2AError.push_notification_not_supported()
|
|
590
|
+
)
|
|
591
|
+
)
|
|
515
592
|
|
|
516
593
|
async def on_resubscribe_to_task(
|
|
517
594
|
self, request: TaskResubscriptionRequest
|
|
518
595
|
) -> Union[AsyncIterable[SendStreamingMessageResponse], JSONRPCResponse]:
|
|
519
|
-
|
|
596
|
+
"""
|
|
597
|
+
Handle tasks/resubscribe request.
|
|
598
|
+
|
|
599
|
+
Replays all events from task creation and continues with live updates.
|
|
600
|
+
|
|
601
|
+
Args:
|
|
602
|
+
request: The resubscription request
|
|
603
|
+
|
|
604
|
+
Yields:
|
|
605
|
+
Streaming responses with task updates
|
|
606
|
+
"""
|
|
607
|
+
task_id = request.params.id
|
|
608
|
+
|
|
609
|
+
if task_id not in self.tasks:
|
|
610
|
+
error = A2AError.task_not_found(task_id)
|
|
611
|
+
yield SendStreamingMessageResponse(
|
|
612
|
+
root=JSONRPCErrorResponse(id=request.id, error=error)
|
|
613
|
+
)
|
|
614
|
+
return
|
|
615
|
+
|
|
616
|
+
if task_id not in self.streaming_enabled_tasks:
|
|
617
|
+
error = A2AError.unsupported_operation(
|
|
618
|
+
"Task was not created with streaming enabled"
|
|
619
|
+
)
|
|
620
|
+
yield SendStreamingMessageResponse(
|
|
621
|
+
root=JSONRPCErrorResponse(id=request.id, error=error)
|
|
622
|
+
)
|
|
623
|
+
return
|
|
624
|
+
|
|
625
|
+
task = self.tasks[task_id]
|
|
626
|
+
|
|
627
|
+
if task_id in self.task_events:
|
|
628
|
+
for event in self.task_events[task_id]:
|
|
629
|
+
yield SendStreamingMessageResponse(
|
|
630
|
+
root=SendStreamingMessageSuccessResponse(
|
|
631
|
+
id=request.id, result=event
|
|
632
|
+
)
|
|
633
|
+
)
|
|
634
|
+
|
|
635
|
+
if self._is_terminal_state(task.status.state):
|
|
636
|
+
return
|
|
637
|
+
|
|
638
|
+
queue = asyncio.Queue()
|
|
639
|
+
resubscribe_key = f"{task_id}_resub_{request.id}"
|
|
640
|
+
self.streaming_tasks[resubscribe_key] = queue
|
|
641
|
+
|
|
642
|
+
try:
|
|
643
|
+
while True:
|
|
644
|
+
event = await queue.get()
|
|
645
|
+
if event is None:
|
|
646
|
+
break
|
|
647
|
+
|
|
648
|
+
yield SendStreamingMessageResponse(
|
|
649
|
+
root=SendStreamingMessageSuccessResponse(
|
|
650
|
+
id=request.id, result=event
|
|
651
|
+
)
|
|
652
|
+
)
|
|
653
|
+
|
|
654
|
+
if isinstance(event, TaskStatusUpdateEvent):
|
|
655
|
+
if self._is_terminal_state(event.status.state):
|
|
656
|
+
break
|
|
657
|
+
|
|
658
|
+
finally:
|
|
659
|
+
if resubscribe_key in self.streaming_tasks:
|
|
660
|
+
del self.streaming_tasks[resubscribe_key]
|
|
520
661
|
|
|
521
662
|
# Legacy methods for backward compatibility
|
|
522
663
|
async def on_send_task(self, request: SendMessageRequest) -> SendMessageResponse:
|
|
@@ -642,7 +642,7 @@ Check if `when` condition in <Global_Behavior> or <Project_Behavior> matches, up
|
|
|
642
642
|
adaptive_messages["content"].append(
|
|
643
643
|
{
|
|
644
644
|
"type": "text",
|
|
645
|
-
"text": f"Here are conversations that we have discussed:\n- {'\n- '.join(memory_headers)}",
|
|
645
|
+
"text": f"Here are conversations that we have discussed from oldest to latest:\n - {'\n - '.join(memory_headers)}",
|
|
646
646
|
}
|
|
647
647
|
)
|
|
648
648
|
if len(adaptive_messages["content"]) > 0:
|
{agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/browser_automation/element_extractor.py
RENAMED
|
@@ -68,7 +68,7 @@ def clean_markdown_images(markdown_content: str) -> str:
|
|
|
68
68
|
Cleaned markdown content
|
|
69
69
|
"""
|
|
70
70
|
# Pattern for markdown images: 
|
|
71
|
-
markdown_img_pattern = r"
|
|
71
|
+
markdown_img_pattern = r"!?\[([^\]]*)\]\(([^)]+)\)"
|
|
72
72
|
|
|
73
73
|
def replace_markdown_img(match):
|
|
74
74
|
alt_text = match.group(1)
|
|
@@ -186,10 +186,8 @@
|
|
|
186
186
|
});
|
|
187
187
|
}
|
|
188
188
|
} else {
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
if (!seenElements.has(elementKey)) {
|
|
192
|
-
seenElements.add(elementKey);
|
|
189
|
+
if (!seenElements.has(xpath)) {
|
|
190
|
+
seenElements.add(xpath);
|
|
193
191
|
clickableElements.push({
|
|
194
192
|
type: elementType,
|
|
195
193
|
xpath: xpath,
|
|
@@ -7,7 +7,7 @@ scroll content, and extract page information using Chrome DevTools Protocol.
|
|
|
7
7
|
|
|
8
8
|
import time
|
|
9
9
|
from typing import Dict, Any, Optional, List
|
|
10
|
-
from html_to_markdown import
|
|
10
|
+
from html_to_markdown import convert, ConversionOptions, PreprocessingOptions
|
|
11
11
|
import urllib.parse
|
|
12
12
|
|
|
13
13
|
from html.parser import HTMLParser
|
|
@@ -344,13 +344,23 @@ class BrowserAutomationService:
|
|
|
344
344
|
filtered_html = self._filter_hidden_elements(raw_html)
|
|
345
345
|
|
|
346
346
|
# Convert HTML to markdown
|
|
347
|
-
raw_markdown_content = convert_to_markdown(
|
|
347
|
+
# raw_markdown_content = convert_to_markdown(
|
|
348
|
+
# filtered_html,
|
|
349
|
+
# source_encoding="utf-8",
|
|
350
|
+
# strip_newlines=True,
|
|
351
|
+
# extract_metadata=False,
|
|
352
|
+
# remove_forms=False,
|
|
353
|
+
# remove_navigation=False,
|
|
354
|
+
# )
|
|
355
|
+
raw_markdown_content = convert(
|
|
348
356
|
filtered_html,
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
357
|
+
ConversionOptions(
|
|
358
|
+
strip_newlines=True,
|
|
359
|
+
extract_metadata=False,
|
|
360
|
+
),
|
|
361
|
+
PreprocessingOptions(
|
|
362
|
+
remove_navigation=False, remove_forms=False, preset="minimal"
|
|
363
|
+
),
|
|
354
364
|
)
|
|
355
365
|
if not raw_markdown_content:
|
|
356
366
|
return {"success": False, "error": "Could not convert HTML to markdown"}
|
{agentcrew_ai-0.8.3 → agentcrew_ai-0.8.5}/AgentCrew/modules/chat/message/command_processor.py
RENAMED
|
@@ -101,12 +101,20 @@ class CommandProcessor:
|
|
|
101
101
|
|
|
102
102
|
async def _handle_copy_command(self, user_input: str) -> CommandResult:
|
|
103
103
|
copy_idx = user_input[5:].strip() or 1
|
|
104
|
+
user_input_idxs = [
|
|
105
|
+
turn.message_index for turn in self.message_handler.conversation_turns
|
|
106
|
+
]
|
|
104
107
|
|
|
105
108
|
asssistant_messages_iterator = reversed(
|
|
106
109
|
[
|
|
107
110
|
msg
|
|
108
|
-
for msg in self.message_handler.streamline_messages
|
|
111
|
+
for i, msg in enumerate(self.message_handler.streamline_messages)
|
|
109
112
|
if msg.get("role") == "assistant"
|
|
113
|
+
and (
|
|
114
|
+
i + 1 in user_input_idxs
|
|
115
|
+
if i + 1 < len(self.message_handler.streamline_messages)
|
|
116
|
+
else True
|
|
117
|
+
)
|
|
110
118
|
]
|
|
111
119
|
)
|
|
112
120
|
latest_assistant_blk = None
|