agentcrew-ai 0.8.4__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.
Files changed (202) hide show
  1. agentcrew_ai-0.8.5/AgentCrew/__init__.py +1 -0
  2. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/a2a/task_manager.py +1 -1
  3. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/agents/local_agent.py +1 -1
  4. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/browser_automation/element_extractor.py +1 -1
  5. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/browser_automation/service.py +17 -7
  6. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/chat/message/command_processor.py +4 -2
  7. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/chat/message/conversation.py +1 -0
  8. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/chat/message/handler.py +3 -6
  9. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/console/command_handlers.py +2 -2
  10. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/console/confirmation_handler.py +83 -38
  11. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/console/console_ui.py +27 -23
  12. agentcrew_ai-0.8.5/AgentCrew/modules/console/diff_display.py +203 -0
  13. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/console/display_handlers.py +3 -0
  14. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/console/input_handler.py +1 -1
  15. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/console/tool_display.py +35 -4
  16. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/console/ui_effects.py +30 -14
  17. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/custom_llm/deepinfra_service.py +20 -19
  18. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/custom_llm/github_copilot_service.py +157 -2
  19. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/custom_llm/service.py +1 -9
  20. {agentcrew_ai-0.8.4/agentcrew_ai.egg-info → agentcrew_ai-0.8.5}/PKG-INFO +2 -2
  21. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5/agentcrew_ai.egg-info}/PKG-INFO +2 -2
  22. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/agentcrew_ai.egg-info/SOURCES.txt +1 -0
  23. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/agentcrew_ai.egg-info/requires.txt +1 -1
  24. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/pyproject.toml +2 -2
  25. agentcrew_ai-0.8.4/AgentCrew/__init__.py +0 -1
  26. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/app.py +0 -0
  27. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/assets/agentcrew_logo.png +0 -0
  28. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/main.py +0 -0
  29. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/main_docker.py +0 -0
  30. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/__init__.py +0 -0
  31. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/a2a/__init__.py +0 -0
  32. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/a2a/adapters.py +0 -0
  33. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/a2a/agent_cards.py +0 -0
  34. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/a2a/common/__init__.py +0 -0
  35. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/a2a/common/client/__init__.py +0 -0
  36. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/a2a/common/client/card_resolver.py +0 -0
  37. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/a2a/common/client/client.py +0 -0
  38. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/a2a/common/server/__init__.py +0 -0
  39. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/a2a/common/server/auth_middleware.py +0 -0
  40. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/a2a/common/server/task_manager.py +0 -0
  41. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/a2a/common/server/utils.py +0 -0
  42. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/a2a/errors.py +0 -0
  43. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/a2a/registry.py +0 -0
  44. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/a2a/server.py +0 -0
  45. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/agents/__init__.py +0 -0
  46. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/agents/base.py +0 -0
  47. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/agents/example.py +0 -0
  48. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/agents/manager.py +0 -0
  49. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/agents/remote_agent.py +0 -0
  50. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/agents/tools/__init__.py +0 -0
  51. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/agents/tools/ask.py +0 -0
  52. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/agents/tools/delegate.py +0 -0
  53. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/agents/tools/transfer.py +0 -0
  54. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/anthropic/__init__.py +0 -0
  55. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/anthropic/service.py +0 -0
  56. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/browser_automation/__init__.py +0 -0
  57. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/browser_automation/chrome_manager.py +0 -0
  58. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/browser_automation/js/click_element.js +0 -0
  59. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/browser_automation/js/draw_element_boxes.js +0 -0
  60. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/browser_automation/js/extract_clickable_elements.js +0 -0
  61. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/browser_automation/js/extract_elements_by_text.js +0 -0
  62. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/browser_automation/js/extract_input_elements.js +0 -0
  63. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/browser_automation/js/extract_scrollable_elements.js +0 -0
  64. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/browser_automation/js/filter_hidden_elements.js +0 -0
  65. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/browser_automation/js/focus_and_clear_element.js +0 -0
  66. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/browser_automation/js/remove_element_boxes.js +0 -0
  67. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/browser_automation/js/scroll_page.js +0 -0
  68. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/browser_automation/js/trigger_input_events.js +0 -0
  69. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/browser_automation/js_loader.py +0 -0
  70. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/browser_automation/tool.py +0 -0
  71. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/chat/__init__.py +0 -0
  72. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/chat/consolidation.py +0 -0
  73. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/chat/file_handler.py +0 -0
  74. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/chat/history.py +0 -0
  75. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/chat/message/__init__.py +0 -0
  76. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/chat/message/base.py +0 -0
  77. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/chat/message/tool_manager.py +0 -0
  78. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/chat/message_handler.py +0 -0
  79. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/clipboard/__init__.py +0 -0
  80. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/clipboard/service.py +0 -0
  81. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/clipboard/tool.py +0 -0
  82. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/code_analysis/__init__.py +0 -0
  83. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/code_analysis/service.py +0 -0
  84. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/code_analysis/tool.py +0 -0
  85. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/command_execution/__init__.py +0 -0
  86. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/command_execution/constants.py +0 -0
  87. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/command_execution/metric.py +0 -0
  88. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/command_execution/service.py +0 -0
  89. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/command_execution/tool.py +0 -0
  90. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/command_execution/types.py +0 -0
  91. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/config/__init__.py +0 -0
  92. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/config/config_management.py +0 -0
  93. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/console/__init__.py +0 -0
  94. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/console/completers.py +0 -0
  95. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/console/constants.py +0 -0
  96. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/console/conversation_handler.py +0 -0
  97. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/console/utils.py +0 -0
  98. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/custom_llm/__init__.py +0 -0
  99. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/custom_llm/copilot_response_service.py +0 -0
  100. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/file_editing/__init__.py +0 -0
  101. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/file_editing/safety_validator.py +0 -0
  102. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/file_editing/search_replace_engine.py +0 -0
  103. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/file_editing/service.py +0 -0
  104. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/file_editing/tool.py +0 -0
  105. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/file_editing/tree_sitter_checker.py +0 -0
  106. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/google/__init__.py +0 -0
  107. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/google/native_service.py +0 -0
  108. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/google/service.py +0 -0
  109. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/groq/__init__.py +0 -0
  110. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/groq/service.py +0 -0
  111. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/__init__.py +0 -0
  112. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/components/__init__.py +0 -0
  113. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/components/chat_components.py +0 -0
  114. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/components/command_handler.py +0 -0
  115. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/components/completers.py +0 -0
  116. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/components/conversation_components.py +0 -0
  117. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/components/input_components.py +0 -0
  118. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/components/keyboard_handler.py +0 -0
  119. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/components/menu_components.py +0 -0
  120. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/components/message_handlers.py +0 -0
  121. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/components/tool_handlers.py +0 -0
  122. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/components/ui_state_manager.py +0 -0
  123. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/qt_ui.py +0 -0
  124. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/themes/README.md +0 -0
  125. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/themes/__init__.py +0 -0
  126. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/themes/atom_light.py +0 -0
  127. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/themes/catppuccin.py +0 -0
  128. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/themes/dracula.py +0 -0
  129. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/themes/nord.py +0 -0
  130. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/themes/saigontech.py +0 -0
  131. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/themes/style_provider.py +0 -0
  132. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/themes/unicorn.py +0 -0
  133. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/utils/__init__.py +0 -0
  134. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/utils/macos_clipboard.py +0 -0
  135. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/utils/strings.py +0 -0
  136. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/utils/wins_clipboard.py +0 -0
  137. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/widgets/__init__.py +0 -0
  138. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/widgets/config_window.py +0 -0
  139. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/widgets/configs/__init__.py +0 -0
  140. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/widgets/configs/agent_config.py +0 -0
  141. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/widgets/configs/custom_llm_provider.py +0 -0
  142. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/widgets/configs/global_settings.py +0 -0
  143. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/widgets/configs/mcp_config.py +0 -0
  144. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/widgets/configs/save_worker.py +0 -0
  145. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/widgets/history_sidebar.py +0 -0
  146. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/widgets/json_editor.py +0 -0
  147. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/widgets/loading_overlay.py +0 -0
  148. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/widgets/markdown_editor.py +0 -0
  149. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/widgets/message_bubble.py +0 -0
  150. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/widgets/paste_aware_textedit.py +0 -0
  151. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/widgets/system_message.py +0 -0
  152. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/widgets/token_usage.py +0 -0
  153. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/widgets/tool_widget.py +0 -0
  154. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/gui/worker.py +0 -0
  155. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/image_generation/__init__.py +0 -0
  156. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/image_generation/service.py +0 -0
  157. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/image_generation/tool.py +0 -0
  158. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/llm/__init__.py +0 -0
  159. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/llm/base.py +0 -0
  160. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/llm/constants.py +0 -0
  161. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/llm/model_registry.py +0 -0
  162. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/llm/service_manager.py +0 -0
  163. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/llm/types.py +0 -0
  164. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/mcpclient/__init__.py +0 -0
  165. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/mcpclient/auth.py +0 -0
  166. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/mcpclient/config.py +0 -0
  167. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/mcpclient/manager.py +0 -0
  168. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/mcpclient/service.py +0 -0
  169. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/mcpclient/tool.py +0 -0
  170. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/memory/__init__.py +0 -0
  171. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/memory/base_service.py +0 -0
  172. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/memory/chroma_service.py +0 -0
  173. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/memory/context_persistent.py +0 -0
  174. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/memory/github_copilot_ef.py +0 -0
  175. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/memory/google_genai_ef.py +0 -0
  176. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/memory/tool.py +0 -0
  177. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/memory/voyageai_ef.py +0 -0
  178. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/openai/__init__.py +0 -0
  179. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/openai/response_service.py +0 -0
  180. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/openai/service.py +0 -0
  181. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/prompts/__init__.py +0 -0
  182. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/prompts/constants.py +0 -0
  183. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/tools/README.md +0 -0
  184. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/tools/registration.py +0 -0
  185. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/tools/registry.py +0 -0
  186. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/voice/__init__.py +0 -0
  187. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/voice/audio_handler.py +0 -0
  188. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/voice/base.py +0 -0
  189. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/voice/deepinfra_service.py +0 -0
  190. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/voice/elevenlabs_service.py +0 -0
  191. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/voice/text_cleaner.py +0 -0
  192. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/web_search/__init__.py +0 -0
  193. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/web_search/service.py +0 -0
  194. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/AgentCrew/modules/web_search/tool.py +0 -0
  195. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/CONTRIBUTING.md +0 -0
  196. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/LICENSE +0 -0
  197. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/MANIFEST.in +0 -0
  198. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/README.md +0 -0
  199. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/agentcrew_ai.egg-info/dependency_links.txt +0 -0
  200. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/agentcrew_ai.egg-info/entry_points.txt +0 -0
  201. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/agentcrew_ai.egg-info/top_level.txt +0 -0
  202. {agentcrew_ai-0.8.4 → agentcrew_ai-0.8.5}/setup.cfg +0 -0
@@ -0,0 +1 @@
1
+ __version__ = "0.8.5"
@@ -604,7 +604,7 @@ class AgentTaskManager(TaskManager):
604
604
  Yields:
605
605
  Streaming responses with task updates
606
606
  """
607
- task_id = request.params.task_id
607
+ task_id = request.params.id
608
608
 
609
609
  if task_id not in self.tasks:
610
610
  error = A2AError.task_not_found(task_id)
@@ -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:
@@ -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: ![alt](url)
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)
@@ -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 convert_to_markdown
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
- source_encoding="utf-8",
350
- strip_newlines=True,
351
- extract_metadata=False,
352
- remove_forms=False,
353
- remove_navigation=False,
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"}
@@ -101,6 +101,9 @@ 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
  [
@@ -108,8 +111,7 @@ class CommandProcessor:
108
111
  for i, msg in enumerate(self.message_handler.streamline_messages)
109
112
  if msg.get("role") == "assistant"
110
113
  and (
111
- self.message_handler.streamline_messages[i + 1].get("role")
112
- == "user"
114
+ i + 1 in user_input_idxs
113
115
  if i + 1 < len(self.message_handler.streamline_messages)
114
116
  else True
115
117
  )
@@ -162,6 +162,7 @@ class ConversationManager:
162
162
  "Memories related to the user request:"
163
163
  )
164
164
  and not message_content.startswith("Content of ")
165
+ and not message_content.startswith("<Transfer_Tool>")
165
166
  ):
166
167
  self.store_conversation_turn(message_content, i)
167
168
 
@@ -279,7 +279,7 @@ class MessageHandler(Observable):
279
279
  # Notify about response progress
280
280
  if not self.agent.is_streaming():
281
281
  # Delays it a bit when using without stream
282
- time.sleep(0.5)
282
+ time.sleep(0.3)
283
283
  self._notify("response_chunk", (chunk_text, assistant_response))
284
284
  if voice_sentence is not None:
285
285
  if (
@@ -321,6 +321,8 @@ class MessageHandler(Observable):
321
321
  .lstrip("\n")
322
322
  )
323
323
 
324
+ self.stream_generator = None
325
+
324
326
  # End thinking when break the response stream
325
327
  if not end_thinking and start_thinking:
326
328
  self._notify("thinking_completed", thinking_content)
@@ -386,11 +388,6 @@ class MessageHandler(Observable):
386
388
 
387
389
  return await self.get_assistant_response()
388
390
 
389
- self.stream_generator = None
390
-
391
- if thinking_content:
392
- self._notify("agent_continue", self.agent.name)
393
-
394
391
  # Add assistant response to messages
395
392
  if assistant_response.strip():
396
393
  self._messages_append(
@@ -346,8 +346,8 @@ class CommandHandlers:
346
346
  for behavior_id, behavior_text in project_behaviors.items():
347
347
  project_table.add_row(behavior_id, behavior_text)
348
348
 
349
- self.console.print(project_table)
350
- self.console.print()
349
+ self.console.print(project_table)
350
+ self.console.print()
351
351
 
352
352
  def handle_update_behavior_command(
353
353
  self, behavior_id: str, behavior_text: str, scope: str = "global"
@@ -11,6 +11,8 @@ from rich.box import HORIZONTALS
11
11
  from rich.console import Group
12
12
  import time
13
13
 
14
+ from .diff_display import DiffDisplay
15
+
14
16
  from .constants import (
15
17
  RICH_STYLE_BLUE,
16
18
  RICH_STYLE_BLUE_BOLD,
@@ -45,6 +47,20 @@ class ConfirmationHandler:
45
47
  self._handle_ask_tool(tool_use, confirmation_id, message_handler)
46
48
  return
47
49
 
50
+ # Special handling for 'write_or_edit_file' tool with search/replace blocks
51
+ if tool_use["name"] == "write_or_edit_file":
52
+ file_path = tool_use["input"].get("file_path", "")
53
+ text_or_blocks = tool_use["input"].get("text_or_search_replace_blocks", "")
54
+
55
+ if DiffDisplay.has_search_replace_blocks(text_or_blocks):
56
+ self._display_write_or_edit_file_diff(
57
+ tool_use, file_path, text_or_blocks
58
+ )
59
+ self._get_and_handle_tool_response(
60
+ tool_use, confirmation_id, message_handler
61
+ )
62
+ return
63
+
48
64
  tool_texts_group = []
49
65
  header = Text("🔧 Tool ", style=RICH_STYLE_YELLOW)
50
66
  header.append(tool_use["name"], style=RICH_STYLE_BLUE_BOLD)
@@ -72,8 +88,71 @@ class ConfirmationHandler:
72
88
  )
73
89
  )
74
90
 
75
- # Get user response
91
+ self._get_and_handle_tool_response(tool_use, confirmation_id, message_handler)
92
+
93
+ def _handle_ask_tool(self, tool_use, confirmation_id, message_handler):
94
+ """Handle the ask tool - display question and guided answers."""
95
+ question = tool_use["input"].get("question", "")
96
+ guided_answers = tool_use["input"].get("guided_answers", [])
97
+ if isinstance(guided_answers, str):
98
+ guided_answers = guided_answers.strip("\n ").splitlines()
99
+
100
+ guided_answers.append("Custom your answer")
101
+
102
+ self.input_handler._stop_input_thread()
103
+ # Display the question
104
+ self.console.print(
105
+ Text("\n❓ Agent is asking for clarification:", style=RICH_STYLE_BLUE_BOLD)
106
+ )
107
+ response = self.input_handler.get_choice_input(f"{question}", guided_answers)
108
+
109
+ if response == "Custom your answer":
110
+ custom_answer = self.input_handler.get_prompt_input("Input your answer:")
111
+ message_handler.resolve_tool_confirmation(
112
+ confirmation_id, {"action": "answer", "answer": custom_answer}
113
+ )
114
+ elif response:
115
+ message_handler.resolve_tool_confirmation(
116
+ confirmation_id, {"action": "answer", "answer": response}
117
+ )
118
+
119
+ else:
120
+ message_handler.resolve_tool_confirmation(
121
+ confirmation_id, {"action": "answer", "answer": "Cancelled by user"}
122
+ )
123
+
124
+ self._ui.start_loading_animation()
125
+
126
+ self.input_handler._start_input_thread()
127
+
128
+ def _display_write_or_edit_file_diff(self, tool_use, file_path, blocks_text):
129
+ """Display split diff view for write_or_edit_file tool."""
130
+ header = Text("📝 File Edit ", style=RICH_STYLE_YELLOW)
131
+ header.append(file_path, style=RICH_STYLE_BLUE_BOLD)
132
+ header.append(" - Search/Replace Blocks", style=RICH_STYLE_YELLOW)
133
+
134
+ self.console.print(
135
+ Panel(header, box=HORIZONTALS, border_style=RICH_STYLE_YELLOW)
136
+ )
137
+
138
+ blocks = DiffDisplay.parse_search_replace_blocks(blocks_text)
139
+
140
+ if not blocks:
141
+ self.console.print(
142
+ Text("No valid search/replace blocks found", style=RICH_STYLE_RED)
143
+ )
144
+ return
145
+
146
+ for block in blocks:
147
+ diff_table = DiffDisplay.create_split_diff_table(
148
+ block["search"], block["replace"], max_width=self.console.width - 4
149
+ )
150
+ self.console.print(diff_table)
151
+
152
+ def _get_and_handle_tool_response(self, tool_use, confirmation_id, message_handler):
153
+ """Get user response for tool confirmation and handle it."""
76
154
  self.input_handler._stop_input_thread()
155
+
77
156
  choices = [
78
157
  "yes",
79
158
  "no",
@@ -91,11 +170,11 @@ class ConfirmationHandler:
91
170
  confirmation_id, {"action": "approve"}
92
171
  )
93
172
  elif response == choices[1]:
94
- response = self.input_handler.get_prompt_input(
173
+ deny_reason = self.input_handler.get_prompt_input(
95
174
  "Please tell me why you are denying this tool: "
96
175
  )
97
176
  message_handler.resolve_tool_confirmation(
98
- confirmation_id, {"action": "deny", "reason": response}
177
+ confirmation_id, {"action": "deny", "reason": deny_reason}
99
178
  )
100
179
  elif response == choices[2]:
101
180
  message_handler.resolve_tool_confirmation(
@@ -120,44 +199,10 @@ class ConfirmationHandler:
120
199
  style=RICH_STYLE_YELLOW,
121
200
  )
122
201
  self.console.print(saved_text)
123
- self._ui.start_loading_animation()
124
- self.input_handler._start_input_thread()
125
- time.sleep(0.2) # Small delay to between tool calls
126
-
127
- def _handle_ask_tool(self, tool_use, confirmation_id, message_handler):
128
- """Handle the ask tool - display question and guided answers."""
129
- question = tool_use["input"].get("question", "")
130
- guided_answers = tool_use["input"].get("guided_answers", [])
131
- if isinstance(guided_answers, str):
132
- guided_answers = guided_answers.strip("\n ").splitlines()
133
-
134
- guided_answers.append("Custom your answer")
135
-
136
- self.input_handler._stop_input_thread()
137
- # Display the question
138
- self.console.print(
139
- Text("\n❓ Agent is asking for clarification:", style=RICH_STYLE_BLUE_BOLD)
140
- )
141
- response = self.input_handler.get_choice_input(f"{question}", guided_answers)
142
-
143
- if response == "Custom your answer":
144
- custom_answer = self.input_handler.get_prompt_input("Input your answer:")
145
- message_handler.resolve_tool_confirmation(
146
- confirmation_id, {"action": "answer", "answer": custom_answer}
147
- )
148
- elif response:
149
- message_handler.resolve_tool_confirmation(
150
- confirmation_id, {"action": "answer", "answer": response}
151
- )
152
-
153
- else:
154
- message_handler.resolve_tool_confirmation(
155
- confirmation_id, {"action": "answer", "answer": "Cancelled by user"}
156
- )
157
202
 
158
203
  self._ui.start_loading_animation()
159
-
160
204
  self.input_handler._start_input_thread()
205
+ time.sleep(0.2)
161
206
 
162
207
  def display_mcp_prompt_confirmation(self, prompt_data, input_queue):
163
208
  """Display MCP prompt confirmation request and get user response."""
@@ -20,7 +20,6 @@ from .constants import (
20
20
  RICH_STYLE_GREEN,
21
21
  RICH_STYLE_BLUE,
22
22
  RICH_STYLE_YELLOW,
23
- RICH_STYLE_GREEN_BOLD,
24
23
  RICH_STYLE_YELLOW_BOLD,
25
24
  PROMPT_CHAR,
26
25
  )
@@ -83,11 +82,17 @@ class ConsoleUI(Observer):
83
82
 
84
83
  if event == "thinking_started":
85
84
  self.ui_effects.stop_loading_animation() # Stop loading on first chunk
86
- self.display_handlers.display_thinking_started(data) # data is agent_name
85
+ # self.display_handlers.display_thinking_started(data) # data is agent_name
87
86
  elif event == "thinking_chunk":
88
- self.display_handlers.display_thinking_chunk(
89
- data
90
- ) # data is the thinking chunk
87
+ self.ui_effects.update_live_display(data, is_thinking=True)
88
+ # self.display_handlers.display_thinking_chunk(
89
+ # data
90
+ # ) # data is the thinking chunk
91
+ #
92
+ elif event == "thinking_completed":
93
+ self.ui_effects.finish_response(
94
+ self.ui_effects.updated_text, is_thinking=True
95
+ )
91
96
  elif event == "user_message_created":
92
97
  pass
93
98
  elif event == "response_chunk":
@@ -178,10 +183,6 @@ class ConsoleUI(Observer):
178
183
  f"{data['agent_name'] if 'agent_name' in data else 'other'} agent"
179
184
  )
180
185
  self.display_handlers.display_message(transfer_text)
181
- elif event == "agent_continue":
182
- self.display_handlers.display_message(
183
- Text(f"\n🤖 {data.upper()}:", style=RICH_STYLE_GREEN_BOLD)
184
- )
185
186
  elif event == "jump_performed":
186
187
  jump_text = Text(
187
188
  f"🕰️ Jumping to turn {data['turn_number']}...\n",
@@ -189,12 +190,11 @@ class ConsoleUI(Observer):
189
190
  )
190
191
  preview_text = Text("Conversation rewound to: ", style=RICH_STYLE_YELLOW)
191
192
  preview_text.append(data["preview"])
193
+ self._clean_and_reprint_chat()
192
194
 
193
195
  self.display_handlers.display_message(jump_text)
194
196
  self.display_handlers.display_message(preview_text)
195
197
  self.input_handler.set_current_buffer(data["message"])
196
- elif event == "thinking_completed":
197
- self.display_handlers.display_divider()
198
198
  elif event == "file_processing":
199
199
  self.ui_effects.stop_loading_animation() # Stop loading on first chunk
200
200
  self.display_handlers.add_file(data["file_path"])
@@ -286,25 +286,14 @@ class ConsoleUI(Observer):
286
286
  Signal handler for SIGWINCH.
287
287
  This function is called when the terminal window is resized.
288
288
  """
289
- import os
290
289
  import time
291
290
 
292
291
  if self.input_handler.is_message_processing or self._is_resizing:
293
292
  return # Ignore resize during message processing
294
293
  self._is_resizing = True
295
294
  time.sleep(0.5) # brief pause to allow resize to complete
296
- os.system("cls" if os.name == "nt" else "printf '\033c'")
297
- self.display_handlers.display_loaded_conversation(
298
- self.message_handler.streamline_messages, self.message_handler.agent.name
299
- )
300
- self.display_handlers.print_prompt_prefix(
301
- self.message_handler.agent.name,
302
- self.message_handler.agent.get_model(),
303
- self.message_handler.tool_manager.get_effective_yolo_mode(),
304
- )
305
-
295
+ self._clean_and_reprint_chat()
306
296
  self.display_handlers.print_divider("👤 YOU: ", with_time=True)
307
-
308
297
  prompt = Text(
309
298
  PROMPT_CHAR,
310
299
  style=RICH_STYLE_BLUE,
@@ -318,6 +307,21 @@ class ConsoleUI(Observer):
318
307
  self.console.print(prompt, end="")
319
308
  self._is_resizing = False
320
309
 
310
+ def _clean_and_reprint_chat(self):
311
+ """Clear and reprint the chat display."""
312
+
313
+ import os
314
+
315
+ os.system("cls" if os.name == "nt" else "printf '\033c'")
316
+ self.display_handlers.display_loaded_conversation(
317
+ self.message_handler.streamline_messages, self.message_handler.agent.name
318
+ )
319
+ self.display_handlers.print_prompt_prefix(
320
+ self.message_handler.agent.name,
321
+ self.message_handler.agent.get_model(),
322
+ self.message_handler.tool_manager.get_effective_yolo_mode(),
323
+ )
324
+
321
325
  def start_streaming_response(self, agent_name: str):
322
326
  """Start streaming the assistant's response."""
323
327
  self.ui_effects.start_streaming_response(agent_name)
@@ -0,0 +1,203 @@
1
+ """
2
+ Diff display helper for showing file changes in console UI.
3
+ Provides split view diff display with syntax highlighting.
4
+ """
5
+
6
+ import difflib
7
+ from rich.text import Text
8
+ from rich.table import Table
9
+ from rich.box import SIMPLE_HEAD
10
+ from .constants import (
11
+ RICH_STYLE_BLUE_BOLD,
12
+ )
13
+
14
+
15
+ class DiffDisplay:
16
+ """Helper class for creating split diff views."""
17
+
18
+ @staticmethod
19
+ def has_search_replace_blocks(text: str) -> bool:
20
+ """Check if text contains search/replace blocks."""
21
+ return (
22
+ "<<<<<<< SEARCH" in text and "=======" in text and ">>>>>>> REPLACE" in text
23
+ )
24
+
25
+ @staticmethod
26
+ def parse_search_replace_blocks(blocks_text: str) -> list:
27
+ """
28
+ Parse search/replace blocks from text.
29
+
30
+ Args:
31
+ blocks_text: Text containing search/replace blocks
32
+
33
+ Returns:
34
+ List of dicts with 'index', 'search', and 'replace' keys
35
+ """
36
+ blocks = []
37
+ lines = blocks_text.split("\n")
38
+ i = 0
39
+ block_index = 0
40
+
41
+ while i < len(lines):
42
+ if lines[i].strip() == "<<<<<<< SEARCH":
43
+ search_lines = []
44
+ i += 1
45
+
46
+ while i < len(lines) and lines[i].strip() != "=======":
47
+ search_lines.append(lines[i])
48
+ i += 1
49
+
50
+ if i >= len(lines):
51
+ break
52
+
53
+ i += 1
54
+ replace_lines = []
55
+
56
+ while (
57
+ i < len(lines)
58
+ and lines[i].strip() != ">>>>>>> REPLACE"
59
+ and lines[i].strip() != "======="
60
+ ):
61
+ replace_lines.append(lines[i])
62
+ i += 1
63
+
64
+ if i >= len(lines):
65
+ break
66
+
67
+ blocks.append(
68
+ {
69
+ "index": block_index,
70
+ "search": "\n".join(search_lines),
71
+ "replace": "\n".join(replace_lines),
72
+ }
73
+ )
74
+ block_index += 1
75
+ i += 1
76
+ else:
77
+ i += 1
78
+
79
+ return blocks
80
+
81
+ @staticmethod
82
+ def create_split_diff_table(
83
+ original: str, modified: str, max_width: int = 60
84
+ ) -> Table:
85
+ """
86
+ Create a split diff display table using difflib for intelligent comparison.
87
+
88
+ Args:
89
+ original: Original text content
90
+ modified: Modified text content
91
+ max_width: Maximum width for each column
92
+
93
+ Returns:
94
+ Rich Table object with split diff view
95
+ """
96
+ table = Table(
97
+ show_header=True,
98
+ header_style=RICH_STYLE_BLUE_BOLD,
99
+ box=SIMPLE_HEAD,
100
+ expand=False,
101
+ padding=(0, 1),
102
+ )
103
+ table.add_column("Original", style="", width=max_width, no_wrap=False)
104
+ table.add_column("Modified", style="", width=max_width, no_wrap=False)
105
+
106
+ original_lines = original.split("\n")
107
+ modified_lines = modified.split("\n")
108
+
109
+ matcher = difflib.SequenceMatcher(None, original_lines, modified_lines)
110
+
111
+ for tag, i1, i2, j1, j2 in matcher.get_opcodes():
112
+ if tag == "equal":
113
+ for i, j in zip(range(i1, i2), range(j1, j2)):
114
+ orig_text = Text(original_lines[i], style="dim")
115
+ mod_text = Text(modified_lines[j], style="dim")
116
+ table.add_row(orig_text, mod_text)
117
+
118
+ elif tag == "delete":
119
+ for i in range(i1, i2):
120
+ orig_text = Text(original_lines[i], style="strike red")
121
+ mod_text = Text("", style="dim")
122
+ table.add_row(orig_text, mod_text)
123
+
124
+ elif tag == "insert":
125
+ for j in range(j1, j2):
126
+ orig_text = Text("", style="dim")
127
+ mod_text = Text(modified_lines[j], style="bold green")
128
+ table.add_row(orig_text, mod_text)
129
+
130
+ elif tag == "replace":
131
+ max_lines = max(i2 - i1, j2 - j1)
132
+
133
+ for offset in range(max_lines):
134
+ orig_idx = i1 + offset
135
+ mod_idx = j1 + offset
136
+
137
+ if orig_idx < i2 and mod_idx < j2:
138
+ orig_line = original_lines[orig_idx]
139
+ mod_line = modified_lines[mod_idx]
140
+
141
+ char_matcher = difflib.SequenceMatcher(
142
+ None, orig_line, mod_line
143
+ )
144
+ if char_matcher.ratio() > 0.5:
145
+ orig_text = DiffDisplay._highlight_char_diff(
146
+ orig_line, mod_line, is_original=True
147
+ )
148
+ mod_text = DiffDisplay._highlight_char_diff(
149
+ orig_line, mod_line, is_original=False
150
+ )
151
+ else:
152
+ orig_text = Text(orig_line, style="strike red")
153
+ mod_text = Text(mod_line, style="bold green")
154
+
155
+ table.add_row(orig_text, mod_text)
156
+
157
+ elif orig_idx < i2:
158
+ orig_text = Text(original_lines[orig_idx], style="strike red")
159
+ mod_text = Text("", style="dim")
160
+ table.add_row(orig_text, mod_text)
161
+
162
+ elif mod_idx < j2:
163
+ orig_text = Text("", style="dim")
164
+ mod_text = Text(modified_lines[mod_idx], style="bold green")
165
+ table.add_row(orig_text, mod_text)
166
+
167
+ return table
168
+
169
+ @staticmethod
170
+ def _highlight_char_diff(orig_line: str, mod_line: str, is_original: bool) -> Text:
171
+ """
172
+ Highlight character-level differences within a line.
173
+
174
+ Args:
175
+ orig_line: Original line text
176
+ mod_line: Modified line text
177
+ is_original: True to highlight original, False for modified
178
+
179
+ Returns:
180
+ Rich Text with character-level highlighting
181
+ """
182
+ result = Text()
183
+ matcher = difflib.SequenceMatcher(None, orig_line, mod_line)
184
+
185
+ for tag, i1, i2, j1, j2 in matcher.get_opcodes():
186
+ if is_original:
187
+ segment = orig_line[i1:i2]
188
+ if tag == "equal":
189
+ result.append(segment, style="dim")
190
+ elif tag == "delete":
191
+ result.append(segment, style="bold red on #3d0000")
192
+ elif tag == "replace":
193
+ result.append(segment, style="bold red on #3d0000")
194
+ else:
195
+ segment = mod_line[j1:j2]
196
+ if tag == "equal":
197
+ result.append(segment, style="dim")
198
+ elif tag == "insert":
199
+ result.append(segment, style="bold green on #003d00")
200
+ elif tag == "replace":
201
+ result.append(segment, style="bold green on #003d00")
202
+
203
+ return result
@@ -217,6 +217,9 @@ class DisplayHandlers:
217
217
  transfer_text.append(f"{msg.get('agent', 'unknown')} agent")
218
218
  self.display_message(transfer_text)
219
219
  continue
220
+
221
+ elif content.startswith("Content of "):
222
+ continue
220
223
  self.display_user_message(content)
221
224
  elif role == "assistant":
222
225
  agent_name = msg.get("agent") or default_agent_name
@@ -163,7 +163,7 @@ class InputHandler:
163
163
  else:
164
164
  if (
165
165
  hasattr(self.message_handler, "stream_generator")
166
- and self.message_handler.stream_generator
166
+ and not self.message_handler.stop_streaming
167
167
  ):
168
168
  try:
169
169
  self.message_handler.stop_streaming = True