agentcrew-ai 0.8.2__tar.gz → 0.8.4__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.4/AgentCrew/__init__.py +1 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/main.py +3 -1
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/a2a/agent_cards.py +8 -2
- agentcrew_ai-0.8.4/AgentCrew/modules/a2a/errors.py +72 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/a2a/server.py +21 -2
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/a2a/task_manager.py +180 -39
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/agents/local_agent.py +11 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/browser_automation/element_extractor.py +4 -3
- agentcrew_ai-0.8.4/AgentCrew/modules/browser_automation/js/draw_element_boxes.js +200 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/browser_automation/js/extract_clickable_elements.js +58 -26
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/browser_automation/js/extract_elements_by_text.js +21 -19
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/browser_automation/js/extract_input_elements.js +22 -23
- agentcrew_ai-0.8.4/AgentCrew/modules/browser_automation/js/filter_hidden_elements.js +104 -0
- agentcrew_ai-0.8.4/AgentCrew/modules/browser_automation/js/remove_element_boxes.js +29 -0
- agentcrew_ai-0.8.4/AgentCrew/modules/browser_automation/js_loader.py +564 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/browser_automation/service.py +118 -347
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/browser_automation/tool.py +28 -29
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/chat/message/command_processor.py +7 -1
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/chat/message/conversation.py +9 -8
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/code_analysis/service.py +39 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/code_analysis/tool.py +10 -1
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/console/command_handlers.py +186 -1
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/console/completers.py +67 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/console/console_ui.py +59 -5
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/console/display_handlers.py +12 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/console/input_handler.py +2 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/console/ui_effects.py +3 -4
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/custom_llm/service.py +25 -3
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/file_editing/tool.py +9 -11
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/google/native_service.py +13 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/gui/widgets/message_bubble.py +1 -6
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/llm/constants.py +38 -1
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/llm/model_registry.py +9 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/llm/types.py +12 -1
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/memory/base_service.py +2 -2
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/memory/chroma_service.py +79 -138
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/memory/context_persistent.py +10 -4
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/memory/tool.py +17 -18
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/openai/response_service.py +19 -11
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/openai/service.py +15 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/prompts/constants.py +27 -14
- {agentcrew_ai-0.8.2/agentcrew_ai.egg-info → agentcrew_ai-0.8.4}/PKG-INFO +3 -3
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4/agentcrew_ai.egg-info}/PKG-INFO +3 -3
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/agentcrew_ai.egg-info/SOURCES.txt +4 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/agentcrew_ai.egg-info/requires.txt +2 -2
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/pyproject.toml +3 -3
- agentcrew_ai-0.8.2/AgentCrew/__init__.py +0 -1
- agentcrew_ai-0.8.2/AgentCrew/modules/browser_automation/js_loader.py +0 -271
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/app.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/assets/agentcrew_logo.png +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/main_docker.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/__init__.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/a2a/__init__.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/a2a/adapters.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/a2a/common/__init__.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/a2a/common/client/__init__.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/a2a/common/client/card_resolver.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/a2a/common/client/client.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/a2a/common/server/__init__.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/a2a/common/server/auth_middleware.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/a2a/common/server/task_manager.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/a2a/common/server/utils.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/a2a/registry.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/agents/__init__.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/agents/base.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/agents/example.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/agents/manager.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/agents/remote_agent.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/agents/tools/__init__.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/agents/tools/ask.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/agents/tools/delegate.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/agents/tools/transfer.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/anthropic/__init__.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/anthropic/service.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/browser_automation/__init__.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/browser_automation/chrome_manager.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/browser_automation/js/click_element.js +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/browser_automation/js/extract_scrollable_elements.js +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/browser_automation/js/focus_and_clear_element.js +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/browser_automation/js/scroll_page.js +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/browser_automation/js/trigger_input_events.js +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/chat/__init__.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/chat/consolidation.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/chat/file_handler.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/chat/history.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/chat/message/__init__.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/chat/message/base.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/chat/message/handler.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/chat/message/tool_manager.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/chat/message_handler.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/clipboard/__init__.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/clipboard/service.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/clipboard/tool.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/code_analysis/__init__.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/command_execution/__init__.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/command_execution/constants.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/command_execution/metric.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/command_execution/service.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/command_execution/tool.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/command_execution/types.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/config/__init__.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/config/config_management.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/console/__init__.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/console/confirmation_handler.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/console/constants.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/console/conversation_handler.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/console/tool_display.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/console/utils.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/custom_llm/__init__.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/custom_llm/copilot_response_service.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/custom_llm/deepinfra_service.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/custom_llm/github_copilot_service.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/file_editing/__init__.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/file_editing/safety_validator.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/file_editing/search_replace_engine.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/file_editing/service.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/file_editing/tree_sitter_checker.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/google/__init__.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/google/service.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/groq/__init__.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/groq/service.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/gui/__init__.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/gui/components/__init__.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/gui/components/chat_components.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/gui/components/command_handler.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/gui/components/completers.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/gui/components/conversation_components.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/gui/components/input_components.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/gui/components/keyboard_handler.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/gui/components/menu_components.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/gui/components/message_handlers.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/gui/components/tool_handlers.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/gui/components/ui_state_manager.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/gui/qt_ui.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/gui/themes/README.md +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/gui/themes/__init__.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/gui/themes/atom_light.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/gui/themes/catppuccin.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/gui/themes/dracula.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/gui/themes/nord.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/gui/themes/saigontech.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/gui/themes/style_provider.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/gui/themes/unicorn.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/gui/utils/__init__.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/gui/utils/macos_clipboard.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/gui/utils/strings.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/gui/utils/wins_clipboard.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/gui/widgets/__init__.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/gui/widgets/config_window.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/gui/widgets/configs/__init__.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/gui/widgets/configs/agent_config.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/gui/widgets/configs/custom_llm_provider.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/gui/widgets/configs/global_settings.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/gui/widgets/configs/mcp_config.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/gui/widgets/configs/save_worker.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/gui/widgets/history_sidebar.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/gui/widgets/json_editor.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/gui/widgets/loading_overlay.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/gui/widgets/markdown_editor.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/gui/widgets/paste_aware_textedit.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/gui/widgets/system_message.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/gui/widgets/token_usage.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/gui/widgets/tool_widget.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/gui/worker.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/image_generation/__init__.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/image_generation/service.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/image_generation/tool.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/llm/__init__.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/llm/base.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/llm/service_manager.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/mcpclient/__init__.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/mcpclient/auth.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/mcpclient/config.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/mcpclient/manager.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/mcpclient/service.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/mcpclient/tool.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/memory/__init__.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/memory/github_copilot_ef.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/memory/google_genai_ef.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/memory/voyageai_ef.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/openai/__init__.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/prompts/__init__.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/tools/README.md +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/tools/registration.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/tools/registry.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/voice/__init__.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/voice/audio_handler.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/voice/base.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/voice/deepinfra_service.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/voice/elevenlabs_service.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/voice/text_cleaner.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/web_search/__init__.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/web_search/service.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/web_search/tool.py +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/CONTRIBUTING.md +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/LICENSE +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/MANIFEST.in +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/README.md +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/agentcrew_ai.egg-info/dependency_links.txt +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/agentcrew_ai.egg-info/entry_points.txt +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/agentcrew_ai.egg-info/top_level.txt +0 -0
- {agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/setup.cfg +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.8.4"
|
|
@@ -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.task_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:
|
|
@@ -634,6 +634,17 @@ Check if `when` condition in <Global_Behavior> or <Project_Behavior> matches, up
|
|
|
634
634
|
- Skip agent evaluation if user request is when...,[action]... related to adaptive behaviors call `adapt` tool instead.""",
|
|
635
635
|
},
|
|
636
636
|
)
|
|
637
|
+
if self.services.get("memory"):
|
|
638
|
+
memory_headers = self.services["memory"].list_memory_headers(
|
|
639
|
+
agent_name=self.name
|
|
640
|
+
)
|
|
641
|
+
if memory_headers:
|
|
642
|
+
adaptive_messages["content"].append(
|
|
643
|
+
{
|
|
644
|
+
"type": "text",
|
|
645
|
+
"text": f"Here are conversations that we have discussed:\n- {'\n- '.join(memory_headers)}",
|
|
646
|
+
}
|
|
647
|
+
)
|
|
637
648
|
if len(adaptive_messages["content"]) > 0:
|
|
638
649
|
final_messages.insert(last_user_index, adaptive_messages)
|
|
639
650
|
|
{agentcrew_ai-0.8.2 → agentcrew_ai-0.8.4}/AgentCrew/modules/browser_automation/element_extractor.py
RENAMED
|
@@ -162,12 +162,13 @@ def extract_clickable_elements(chrome_interface, uuid_mapping: Dict[str, str]) -
|
|
|
162
162
|
markdown_output.append(
|
|
163
163
|
"\n\n## Clickable Elements\nUse browser_click with UUID to click elements.\n"
|
|
164
164
|
)
|
|
165
|
-
markdown_output.append("| UUID | Text/Alt |\n")
|
|
166
|
-
markdown_output.append("
|
|
165
|
+
markdown_output.append("| UUID | Type | Text/Alt |\n")
|
|
166
|
+
markdown_output.append("|------|------|-----------|\n")
|
|
167
167
|
|
|
168
168
|
for element in elements_data:
|
|
169
169
|
xpath = element.get("xpath", "")
|
|
170
170
|
text = element.get("text", "").strip()
|
|
171
|
+
element_type = element.get("type", "").strip()
|
|
171
172
|
|
|
172
173
|
# Skip empty text entries
|
|
173
174
|
if not text:
|
|
@@ -180,7 +181,7 @@ def extract_clickable_elements(chrome_interface, uuid_mapping: Dict[str, str]) -
|
|
|
180
181
|
# Escape pipe characters in text for markdown table
|
|
181
182
|
text = text.replace("|", "\\|")
|
|
182
183
|
|
|
183
|
-
markdown_output.append(f"| `{element_uuid}` | {text} |\n")
|
|
184
|
+
markdown_output.append(f"| `{element_uuid}` | {element_type} | {text} |\n")
|
|
184
185
|
|
|
185
186
|
return "".join(markdown_output)
|
|
186
187
|
|