autobyteus 1.1.3__py3-none-any.whl → 1.1.5__py3-none-any.whl

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 (284) hide show
  1. autobyteus/agent/agent.py +1 -1
  2. autobyteus/agent/bootstrap_steps/system_prompt_processing_step.py +4 -2
  3. autobyteus/agent/context/__init__.py +4 -2
  4. autobyteus/agent/context/agent_config.py +35 -8
  5. autobyteus/agent/context/agent_context_registry.py +73 -0
  6. autobyteus/agent/events/notifiers.py +4 -0
  7. autobyteus/agent/events/worker_event_dispatcher.py +1 -2
  8. autobyteus/agent/handlers/inter_agent_message_event_handler.py +8 -3
  9. autobyteus/agent/handlers/llm_complete_response_received_event_handler.py +19 -19
  10. autobyteus/agent/handlers/llm_user_message_ready_event_handler.py +2 -2
  11. autobyteus/agent/handlers/tool_result_event_handler.py +48 -20
  12. autobyteus/agent/handlers/user_input_message_event_handler.py +16 -1
  13. autobyteus/agent/input_processor/__init__.py +1 -7
  14. autobyteus/agent/message/context_file_type.py +6 -0
  15. autobyteus/agent/message/send_message_to.py +74 -99
  16. autobyteus/agent/phases/discover.py +2 -1
  17. autobyteus/agent/runtime/agent_runtime.py +10 -2
  18. autobyteus/agent/runtime/agent_worker.py +1 -0
  19. autobyteus/agent/sender_type.py +15 -0
  20. autobyteus/agent/streaming/agent_event_stream.py +6 -0
  21. autobyteus/agent/streaming/stream_event_payloads.py +12 -0
  22. autobyteus/agent/streaming/stream_events.py +3 -0
  23. autobyteus/agent/system_prompt_processor/tool_manifest_injector_processor.py +7 -4
  24. autobyteus/agent/tool_execution_result_processor/__init__.py +9 -0
  25. autobyteus/agent/tool_execution_result_processor/base_processor.py +46 -0
  26. autobyteus/agent/tool_execution_result_processor/processor_definition.py +36 -0
  27. autobyteus/agent/tool_execution_result_processor/processor_meta.py +36 -0
  28. autobyteus/agent/tool_execution_result_processor/processor_registry.py +70 -0
  29. autobyteus/agent/workspace/base_workspace.py +17 -2
  30. autobyteus/agent_team/__init__.py +1 -0
  31. autobyteus/agent_team/agent_team.py +93 -0
  32. autobyteus/agent_team/agent_team_builder.py +184 -0
  33. autobyteus/agent_team/base_agent_team.py +86 -0
  34. autobyteus/agent_team/bootstrap_steps/__init__.py +24 -0
  35. autobyteus/agent_team/bootstrap_steps/agent_configuration_preparation_step.py +73 -0
  36. autobyteus/agent_team/bootstrap_steps/agent_team_bootstrapper.py +54 -0
  37. autobyteus/agent_team/bootstrap_steps/agent_team_runtime_queue_initialization_step.py +25 -0
  38. autobyteus/agent_team/bootstrap_steps/base_agent_team_bootstrap_step.py +23 -0
  39. autobyteus/agent_team/bootstrap_steps/coordinator_initialization_step.py +41 -0
  40. autobyteus/agent_team/bootstrap_steps/coordinator_prompt_preparation_step.py +85 -0
  41. autobyteus/agent_team/bootstrap_steps/task_notifier_initialization_step.py +51 -0
  42. autobyteus/agent_team/bootstrap_steps/team_context_initialization_step.py +45 -0
  43. autobyteus/agent_team/context/__init__.py +17 -0
  44. autobyteus/agent_team/context/agent_team_config.py +33 -0
  45. autobyteus/agent_team/context/agent_team_context.py +61 -0
  46. autobyteus/agent_team/context/agent_team_runtime_state.py +56 -0
  47. autobyteus/agent_team/context/team_manager.py +147 -0
  48. autobyteus/agent_team/context/team_node_config.py +76 -0
  49. autobyteus/agent_team/events/__init__.py +29 -0
  50. autobyteus/agent_team/events/agent_team_event_dispatcher.py +39 -0
  51. autobyteus/agent_team/events/agent_team_events.py +53 -0
  52. autobyteus/agent_team/events/agent_team_input_event_queue_manager.py +21 -0
  53. autobyteus/agent_team/exceptions.py +8 -0
  54. autobyteus/agent_team/factory/__init__.py +9 -0
  55. autobyteus/agent_team/factory/agent_team_factory.py +99 -0
  56. autobyteus/agent_team/handlers/__init__.py +19 -0
  57. autobyteus/agent_team/handlers/agent_team_event_handler_registry.py +23 -0
  58. autobyteus/agent_team/handlers/base_agent_team_event_handler.py +16 -0
  59. autobyteus/agent_team/handlers/inter_agent_message_request_event_handler.py +61 -0
  60. autobyteus/agent_team/handlers/lifecycle_agent_team_event_handler.py +27 -0
  61. autobyteus/agent_team/handlers/process_user_message_event_handler.py +46 -0
  62. autobyteus/agent_team/handlers/tool_approval_team_event_handler.py +48 -0
  63. autobyteus/agent_team/phases/__init__.py +11 -0
  64. autobyteus/agent_team/phases/agent_team_operational_phase.py +19 -0
  65. autobyteus/agent_team/phases/agent_team_phase_manager.py +48 -0
  66. autobyteus/agent_team/runtime/__init__.py +13 -0
  67. autobyteus/agent_team/runtime/agent_team_runtime.py +82 -0
  68. autobyteus/agent_team/runtime/agent_team_worker.py +117 -0
  69. autobyteus/agent_team/shutdown_steps/__init__.py +17 -0
  70. autobyteus/agent_team/shutdown_steps/agent_team_shutdown_orchestrator.py +35 -0
  71. autobyteus/agent_team/shutdown_steps/agent_team_shutdown_step.py +42 -0
  72. autobyteus/agent_team/shutdown_steps/base_agent_team_shutdown_step.py +16 -0
  73. autobyteus/agent_team/shutdown_steps/bridge_cleanup_step.py +28 -0
  74. autobyteus/agent_team/shutdown_steps/sub_team_shutdown_step.py +41 -0
  75. autobyteus/agent_team/streaming/__init__.py +26 -0
  76. autobyteus/agent_team/streaming/agent_event_bridge.py +48 -0
  77. autobyteus/agent_team/streaming/agent_event_multiplexer.py +70 -0
  78. autobyteus/agent_team/streaming/agent_team_event_notifier.py +64 -0
  79. autobyteus/agent_team/streaming/agent_team_event_stream.py +33 -0
  80. autobyteus/agent_team/streaming/agent_team_stream_event_payloads.py +32 -0
  81. autobyteus/agent_team/streaming/agent_team_stream_events.py +56 -0
  82. autobyteus/agent_team/streaming/team_event_bridge.py +50 -0
  83. autobyteus/agent_team/task_notification/__init__.py +11 -0
  84. autobyteus/agent_team/task_notification/system_event_driven_agent_task_notifier.py +164 -0
  85. autobyteus/agent_team/task_notification/task_notification_mode.py +24 -0
  86. autobyteus/agent_team/utils/__init__.py +9 -0
  87. autobyteus/agent_team/utils/wait_for_idle.py +46 -0
  88. autobyteus/cli/__init__.py +1 -1
  89. autobyteus/cli/agent_team_tui/__init__.py +4 -0
  90. autobyteus/cli/agent_team_tui/app.py +210 -0
  91. autobyteus/cli/agent_team_tui/state.py +180 -0
  92. autobyteus/cli/agent_team_tui/widgets/__init__.py +6 -0
  93. autobyteus/cli/agent_team_tui/widgets/agent_list_sidebar.py +149 -0
  94. autobyteus/cli/agent_team_tui/widgets/focus_pane.py +320 -0
  95. autobyteus/cli/agent_team_tui/widgets/logo.py +20 -0
  96. autobyteus/cli/agent_team_tui/widgets/renderables.py +77 -0
  97. autobyteus/cli/agent_team_tui/widgets/shared.py +60 -0
  98. autobyteus/cli/agent_team_tui/widgets/status_bar.py +14 -0
  99. autobyteus/cli/agent_team_tui/widgets/task_board_panel.py +82 -0
  100. autobyteus/cli/cli_display.py +1 -1
  101. autobyteus/cli/workflow_tui/__init__.py +4 -0
  102. autobyteus/cli/workflow_tui/app.py +210 -0
  103. autobyteus/cli/workflow_tui/state.py +189 -0
  104. autobyteus/cli/workflow_tui/widgets/__init__.py +6 -0
  105. autobyteus/cli/workflow_tui/widgets/agent_list_sidebar.py +149 -0
  106. autobyteus/cli/workflow_tui/widgets/focus_pane.py +335 -0
  107. autobyteus/cli/workflow_tui/widgets/logo.py +27 -0
  108. autobyteus/cli/workflow_tui/widgets/renderables.py +70 -0
  109. autobyteus/cli/workflow_tui/widgets/shared.py +51 -0
  110. autobyteus/cli/workflow_tui/widgets/status_bar.py +14 -0
  111. autobyteus/events/event_types.py +8 -0
  112. autobyteus/llm/api/autobyteus_llm.py +11 -12
  113. autobyteus/llm/api/lmstudio_llm.py +34 -0
  114. autobyteus/llm/api/ollama_llm.py +8 -13
  115. autobyteus/llm/api/openai_compatible_llm.py +20 -3
  116. autobyteus/llm/autobyteus_provider.py +73 -46
  117. autobyteus/llm/llm_factory.py +103 -139
  118. autobyteus/llm/lmstudio_provider.py +104 -0
  119. autobyteus/llm/models.py +83 -53
  120. autobyteus/llm/ollama_provider.py +69 -61
  121. autobyteus/llm/ollama_provider_resolver.py +1 -0
  122. autobyteus/llm/providers.py +13 -12
  123. autobyteus/llm/runtimes.py +11 -0
  124. autobyteus/llm/token_counter/token_counter_factory.py +2 -0
  125. autobyteus/task_management/__init__.py +43 -0
  126. autobyteus/task_management/base_task_board.py +68 -0
  127. autobyteus/task_management/converters/__init__.py +11 -0
  128. autobyteus/task_management/converters/task_board_converter.py +64 -0
  129. autobyteus/task_management/converters/task_plan_converter.py +48 -0
  130. autobyteus/task_management/deliverable.py +16 -0
  131. autobyteus/task_management/deliverables/__init__.py +8 -0
  132. autobyteus/task_management/deliverables/file_deliverable.py +15 -0
  133. autobyteus/task_management/events.py +27 -0
  134. autobyteus/task_management/in_memory_task_board.py +126 -0
  135. autobyteus/task_management/schemas/__init__.py +15 -0
  136. autobyteus/task_management/schemas/deliverable_schema.py +13 -0
  137. autobyteus/task_management/schemas/plan_definition.py +35 -0
  138. autobyteus/task_management/schemas/task_status_report.py +27 -0
  139. autobyteus/task_management/task_plan.py +110 -0
  140. autobyteus/task_management/tools/__init__.py +14 -0
  141. autobyteus/task_management/tools/get_task_board_status.py +68 -0
  142. autobyteus/task_management/tools/publish_task_plan.py +113 -0
  143. autobyteus/task_management/tools/update_task_status.py +135 -0
  144. autobyteus/tools/__init__.py +2 -0
  145. autobyteus/tools/ask_user_input.py +2 -1
  146. autobyteus/tools/bash/bash_executor.py +61 -15
  147. autobyteus/tools/browser/session_aware/browser_session_aware_navigate_to.py +2 -0
  148. autobyteus/tools/browser/session_aware/browser_session_aware_web_element_trigger.py +3 -0
  149. autobyteus/tools/browser/session_aware/browser_session_aware_webpage_reader.py +3 -0
  150. autobyteus/tools/browser/session_aware/browser_session_aware_webpage_screenshot_taker.py +3 -0
  151. autobyteus/tools/browser/standalone/google_search_ui.py +2 -0
  152. autobyteus/tools/browser/standalone/navigate_to.py +2 -0
  153. autobyteus/tools/browser/standalone/web_page_pdf_generator.py +3 -0
  154. autobyteus/tools/browser/standalone/webpage_image_downloader.py +3 -0
  155. autobyteus/tools/browser/standalone/webpage_reader.py +2 -0
  156. autobyteus/tools/browser/standalone/webpage_screenshot_taker.py +3 -0
  157. autobyteus/tools/file/file_reader.py +36 -9
  158. autobyteus/tools/file/file_writer.py +37 -9
  159. autobyteus/tools/functional_tool.py +5 -4
  160. autobyteus/tools/image_downloader.py +2 -0
  161. autobyteus/tools/mcp/config_service.py +63 -58
  162. autobyteus/tools/mcp/server/http_managed_mcp_server.py +14 -2
  163. autobyteus/tools/mcp/server/stdio_managed_mcp_server.py +14 -2
  164. autobyteus/tools/mcp/server_instance_manager.py +30 -4
  165. autobyteus/tools/mcp/tool_registrar.py +106 -51
  166. autobyteus/tools/parameter_schema.py +17 -11
  167. autobyteus/tools/pdf_downloader.py +2 -1
  168. autobyteus/tools/registry/tool_definition.py +36 -37
  169. autobyteus/tools/registry/tool_registry.py +50 -2
  170. autobyteus/tools/timer.py +2 -0
  171. autobyteus/tools/tool_category.py +15 -4
  172. autobyteus/tools/tool_meta.py +6 -1
  173. autobyteus/tools/tool_origin.py +10 -0
  174. autobyteus/tools/usage/formatters/default_json_example_formatter.py +78 -3
  175. autobyteus/tools/usage/formatters/default_xml_example_formatter.py +23 -3
  176. autobyteus/tools/usage/formatters/gemini_json_example_formatter.py +6 -0
  177. autobyteus/tools/usage/formatters/google_json_example_formatter.py +7 -0
  178. autobyteus/tools/usage/formatters/openai_json_example_formatter.py +6 -4
  179. autobyteus/tools/usage/parsers/gemini_json_tool_usage_parser.py +23 -7
  180. autobyteus/tools/usage/parsers/provider_aware_tool_usage_parser.py +14 -25
  181. autobyteus/tools/usage/providers/__init__.py +2 -12
  182. autobyteus/tools/usage/providers/tool_manifest_provider.py +36 -29
  183. autobyteus/tools/usage/registries/__init__.py +7 -12
  184. autobyteus/tools/usage/registries/tool_formatter_pair.py +15 -0
  185. autobyteus/tools/usage/registries/tool_formatting_registry.py +58 -0
  186. autobyteus/tools/usage/registries/tool_usage_parser_registry.py +55 -0
  187. autobyteus/workflow/agentic_workflow.py +93 -0
  188. autobyteus/{agent/workflow → workflow}/base_agentic_workflow.py +19 -27
  189. autobyteus/workflow/bootstrap_steps/__init__.py +20 -0
  190. autobyteus/workflow/bootstrap_steps/agent_tool_injection_step.py +34 -0
  191. autobyteus/workflow/bootstrap_steps/base_workflow_bootstrap_step.py +23 -0
  192. autobyteus/workflow/bootstrap_steps/coordinator_initialization_step.py +41 -0
  193. autobyteus/workflow/bootstrap_steps/coordinator_prompt_preparation_step.py +108 -0
  194. autobyteus/workflow/bootstrap_steps/workflow_bootstrapper.py +50 -0
  195. autobyteus/workflow/bootstrap_steps/workflow_runtime_queue_initialization_step.py +25 -0
  196. autobyteus/workflow/context/__init__.py +17 -0
  197. autobyteus/workflow/context/team_manager.py +147 -0
  198. autobyteus/workflow/context/workflow_config.py +30 -0
  199. autobyteus/workflow/context/workflow_context.py +61 -0
  200. autobyteus/workflow/context/workflow_node_config.py +76 -0
  201. autobyteus/workflow/context/workflow_runtime_state.py +53 -0
  202. autobyteus/workflow/events/__init__.py +29 -0
  203. autobyteus/workflow/events/workflow_event_dispatcher.py +39 -0
  204. autobyteus/workflow/events/workflow_events.py +53 -0
  205. autobyteus/workflow/events/workflow_input_event_queue_manager.py +21 -0
  206. autobyteus/workflow/exceptions.py +8 -0
  207. autobyteus/workflow/factory/__init__.py +9 -0
  208. autobyteus/workflow/factory/workflow_factory.py +99 -0
  209. autobyteus/workflow/handlers/__init__.py +19 -0
  210. autobyteus/workflow/handlers/base_workflow_event_handler.py +16 -0
  211. autobyteus/workflow/handlers/inter_agent_message_request_event_handler.py +61 -0
  212. autobyteus/workflow/handlers/lifecycle_workflow_event_handler.py +27 -0
  213. autobyteus/workflow/handlers/process_user_message_event_handler.py +46 -0
  214. autobyteus/workflow/handlers/tool_approval_workflow_event_handler.py +39 -0
  215. autobyteus/workflow/handlers/workflow_event_handler_registry.py +23 -0
  216. autobyteus/workflow/phases/__init__.py +11 -0
  217. autobyteus/workflow/phases/workflow_operational_phase.py +19 -0
  218. autobyteus/workflow/phases/workflow_phase_manager.py +48 -0
  219. autobyteus/workflow/runtime/__init__.py +13 -0
  220. autobyteus/workflow/runtime/workflow_runtime.py +82 -0
  221. autobyteus/workflow/runtime/workflow_worker.py +117 -0
  222. autobyteus/workflow/shutdown_steps/__init__.py +17 -0
  223. autobyteus/workflow/shutdown_steps/agent_team_shutdown_step.py +42 -0
  224. autobyteus/workflow/shutdown_steps/base_workflow_shutdown_step.py +16 -0
  225. autobyteus/workflow/shutdown_steps/bridge_cleanup_step.py +28 -0
  226. autobyteus/workflow/shutdown_steps/sub_workflow_shutdown_step.py +41 -0
  227. autobyteus/workflow/shutdown_steps/workflow_shutdown_orchestrator.py +35 -0
  228. autobyteus/workflow/streaming/__init__.py +26 -0
  229. autobyteus/workflow/streaming/agent_event_bridge.py +48 -0
  230. autobyteus/workflow/streaming/agent_event_multiplexer.py +70 -0
  231. autobyteus/workflow/streaming/workflow_event_bridge.py +50 -0
  232. autobyteus/workflow/streaming/workflow_event_notifier.py +83 -0
  233. autobyteus/workflow/streaming/workflow_event_stream.py +33 -0
  234. autobyteus/workflow/streaming/workflow_stream_event_payloads.py +28 -0
  235. autobyteus/workflow/streaming/workflow_stream_events.py +45 -0
  236. autobyteus/workflow/utils/__init__.py +9 -0
  237. autobyteus/workflow/utils/wait_for_idle.py +46 -0
  238. autobyteus/workflow/workflow_builder.py +151 -0
  239. {autobyteus-1.1.3.dist-info → autobyteus-1.1.5.dist-info}/METADATA +16 -14
  240. autobyteus-1.1.5.dist-info/RECORD +455 -0
  241. {autobyteus-1.1.3.dist-info → autobyteus-1.1.5.dist-info}/top_level.txt +1 -0
  242. examples/__init__.py +1 -0
  243. examples/agent_team/__init__.py +1 -0
  244. examples/discover_phase_transitions.py +104 -0
  245. examples/run_browser_agent.py +262 -0
  246. examples/run_google_slides_agent.py +287 -0
  247. examples/run_mcp_browser_client.py +174 -0
  248. examples/run_mcp_google_slides_client.py +270 -0
  249. examples/run_mcp_list_tools.py +189 -0
  250. examples/run_poem_writer.py +284 -0
  251. examples/run_sqlite_agent.py +295 -0
  252. autobyteus/agent/context/agent_phase_manager.py +0 -264
  253. autobyteus/agent/context/phases.py +0 -49
  254. autobyteus/agent/group/__init__.py +0 -0
  255. autobyteus/agent/group/agent_group.py +0 -164
  256. autobyteus/agent/group/agent_group_context.py +0 -81
  257. autobyteus/agent/input_processor/content_prefixing_input_processor.py +0 -41
  258. autobyteus/agent/input_processor/metadata_appending_input_processor.py +0 -34
  259. autobyteus/agent/input_processor/passthrough_input_processor.py +0 -33
  260. autobyteus/agent/workflow/__init__.py +0 -11
  261. autobyteus/agent/workflow/agentic_workflow.py +0 -89
  262. autobyteus/tools/mcp/call_handlers/__init__.py +0 -16
  263. autobyteus/tools/mcp/call_handlers/base_handler.py +0 -40
  264. autobyteus/tools/mcp/call_handlers/stdio_handler.py +0 -76
  265. autobyteus/tools/mcp/call_handlers/streamable_http_handler.py +0 -55
  266. autobyteus/tools/mcp/registrar.py +0 -202
  267. autobyteus/tools/usage/providers/json_example_provider.py +0 -32
  268. autobyteus/tools/usage/providers/json_schema_provider.py +0 -35
  269. autobyteus/tools/usage/providers/json_tool_usage_parser_provider.py +0 -28
  270. autobyteus/tools/usage/providers/xml_example_provider.py +0 -28
  271. autobyteus/tools/usage/providers/xml_schema_provider.py +0 -29
  272. autobyteus/tools/usage/providers/xml_tool_usage_parser_provider.py +0 -26
  273. autobyteus/tools/usage/registries/json_example_formatter_registry.py +0 -51
  274. autobyteus/tools/usage/registries/json_schema_formatter_registry.py +0 -51
  275. autobyteus/tools/usage/registries/json_tool_usage_parser_registry.py +0 -42
  276. autobyteus/tools/usage/registries/xml_example_formatter_registry.py +0 -30
  277. autobyteus/tools/usage/registries/xml_schema_formatter_registry.py +0 -33
  278. autobyteus/tools/usage/registries/xml_tool_usage_parser_registry.py +0 -30
  279. autobyteus/workflow/simple_task.py +0 -98
  280. autobyteus/workflow/task.py +0 -147
  281. autobyteus/workflow/workflow.py +0 -49
  282. autobyteus-1.1.3.dist-info/RECORD +0 -312
  283. {autobyteus-1.1.3.dist-info → autobyteus-1.1.5.dist-info}/WHEEL +0 -0
  284. {autobyteus-1.1.3.dist-info → autobyteus-1.1.5.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,53 @@
1
+ # file: autobyteus/autobyteus/agent_team/events/agent_team_events.py
2
+ from dataclasses import dataclass
3
+ from typing import Dict, Any, Optional
4
+
5
+ from autobyteus.agent.message.agent_input_user_message import AgentInputUserMessage
6
+
7
+ @dataclass
8
+ class BaseAgentTeamEvent:
9
+ """Base class for all agent team events."""
10
+
11
+ @dataclass
12
+ class LifecycleAgentTeamEvent(BaseAgentTeamEvent):
13
+ """Base class for events related to the agent team's lifecycle."""
14
+
15
+ @dataclass
16
+ class OperationalAgentTeamEvent(BaseAgentTeamEvent):
17
+ """Base class for events related to the agent team's operational logic."""
18
+
19
+ # Specific Events
20
+ @dataclass
21
+ class AgentTeamReadyEvent(LifecycleAgentTeamEvent):
22
+ """Indicates the agent team has completed bootstrapping and is ready for tasks."""
23
+
24
+ @dataclass
25
+ class AgentTeamErrorEvent(LifecycleAgentTeamEvent):
26
+ """Indicates a significant error occurred within the agent team."""
27
+ error_message: str
28
+ exception_details: Optional[str] = None
29
+
30
+ @dataclass
31
+ class ProcessUserMessageEvent(OperationalAgentTeamEvent):
32
+ """Carries a user's message to be processed by a specific agent in the team."""
33
+ user_message: AgentInputUserMessage
34
+ target_agent_name: str
35
+
36
+ @dataclass
37
+ class InterAgentMessageRequestEvent(OperationalAgentTeamEvent):
38
+ """
39
+ An internal request within the agent team to post a message from one agent to another.
40
+ This triggers on-demand startup logic if needed.
41
+ """
42
+ sender_agent_id: str
43
+ recipient_name: str
44
+ content: str
45
+ message_type: str
46
+
47
+ @dataclass
48
+ class ToolApprovalTeamEvent(OperationalAgentTeamEvent):
49
+ """Carries a user's approval/denial for a tool execution to a specific agent."""
50
+ agent_name: str
51
+ tool_invocation_id: str
52
+ is_approved: bool
53
+ reason: Optional[str] = None
@@ -0,0 +1,21 @@
1
+ # file: autobyteus/autobyteus/agent_team/events/agent_team_input_event_queue_manager.py
2
+ import asyncio
3
+ import logging
4
+ from typing import Any
5
+
6
+ from autobyteus.agent_team.events.agent_team_events import ProcessUserMessageEvent
7
+
8
+ logger = logging.getLogger(__name__)
9
+
10
+ class AgentTeamInputEventQueueManager:
11
+ """Manages asyncio.Queue instances for events consumed by the AgentTeamWorker."""
12
+ def __init__(self, queue_size: int = 0):
13
+ self.user_message_queue: asyncio.Queue[ProcessUserMessageEvent] = asyncio.Queue(maxsize=queue_size)
14
+ self.internal_system_event_queue: asyncio.Queue[Any] = asyncio.Queue(maxsize=queue_size)
15
+ logger.info("AgentTeamInputEventQueueManager initialized.")
16
+
17
+ async def enqueue_user_message(self, event: ProcessUserMessageEvent):
18
+ await self.user_message_queue.put(event)
19
+
20
+ async def enqueue_internal_system_event(self, event: Any):
21
+ await self.internal_system_event_queue.put(event)
@@ -0,0 +1,8 @@
1
+ # file: autobyteus/autobyteus/agent_team/exceptions.py
2
+
3
+ class TeamNodeNotFoundException(Exception):
4
+ """Raised when a node (agent or sub-team) cannot be found in the agent team."""
5
+ def __init__(self, node_name: str, team_id: str):
6
+ super().__init__(f"Node '{node_name}' not found in agent team '{team_id}'.")
7
+ self.node_name = node_name
8
+ self.team_id = team_id
@@ -0,0 +1,9 @@
1
+ # file: autobyteus/autobyteus/agent_team/factory/__init__.py
2
+ """
3
+ Agent team factory for creating AgentTeam instances.
4
+ """
5
+ from autobyteus.agent_team.factory.agent_team_factory import AgentTeamFactory
6
+
7
+ __all__ = [
8
+ "AgentTeamFactory",
9
+ ]
@@ -0,0 +1,99 @@
1
+ # file: autobyteus/autobyteus/agent_team/factory/agent_team_factory.py
2
+ import logging
3
+ import uuid
4
+ from typing import Optional, Dict, List
5
+
6
+ from autobyteus.utils.singleton import SingletonMeta
7
+ from autobyteus.agent_team.agent_team import AgentTeam
8
+ from autobyteus.agent_team.context.agent_team_config import AgentTeamConfig
9
+ from autobyteus.agent_team.context.agent_team_context import AgentTeamContext
10
+ from autobyteus.agent_team.context.agent_team_runtime_state import AgentTeamRuntimeState
11
+ from autobyteus.agent_team.context.team_manager import TeamManager
12
+ from autobyteus.agent_team.runtime.agent_team_runtime import AgentTeamRuntime
13
+ from autobyteus.agent_team.handlers.agent_team_event_handler_registry import AgentTeamEventHandlerRegistry
14
+ from autobyteus.agent_team.handlers.process_user_message_event_handler import ProcessUserMessageEventHandler
15
+ from autobyteus.agent_team.handlers.lifecycle_agent_team_event_handler import LifecycleAgentTeamEventHandler
16
+ from autobyteus.agent_team.handlers.inter_agent_message_request_event_handler import InterAgentMessageRequestEventHandler
17
+ from autobyteus.agent_team.handlers.tool_approval_team_event_handler import ToolApprovalTeamEventHandler
18
+ from autobyteus.agent_team.events.agent_team_events import (
19
+ ProcessUserMessageEvent,
20
+ AgentTeamReadyEvent,
21
+ AgentTeamErrorEvent,
22
+ InterAgentMessageRequestEvent,
23
+ ToolApprovalTeamEvent
24
+ )
25
+
26
+ logger = logging.getLogger(__name__)
27
+
28
+ class AgentTeamFactory(metaclass=SingletonMeta):
29
+ """
30
+ A singleton factory for creating and managing AgentTeam instances.
31
+ It orchestrates the assembly of all core agent team components.
32
+ """
33
+ def __init__(self):
34
+ self._active_teams: Dict[str, AgentTeam] = {}
35
+ logger.info("AgentTeamFactory (Singleton) initialized.")
36
+
37
+ def _get_default_event_handler_registry(self) -> AgentTeamEventHandlerRegistry:
38
+ """Returns a registry with default handlers for a new agent team."""
39
+ registry = AgentTeamEventHandlerRegistry()
40
+ registry.register(ProcessUserMessageEvent, ProcessUserMessageEventHandler())
41
+ registry.register(InterAgentMessageRequestEvent, InterAgentMessageRequestEventHandler())
42
+ registry.register(ToolApprovalTeamEvent, ToolApprovalTeamEventHandler())
43
+ lifecycle_handler = LifecycleAgentTeamEventHandler()
44
+ registry.register(AgentTeamReadyEvent, lifecycle_handler)
45
+ registry.register(AgentTeamErrorEvent, lifecycle_handler)
46
+ return registry
47
+
48
+ def create_team(self, config: AgentTeamConfig) -> AgentTeam:
49
+ """
50
+ Creates a new agent team based on the provided AgentTeamConfig, stores it,
51
+ and returns its facade (AgentTeam).
52
+ """
53
+ if not isinstance(config, AgentTeamConfig):
54
+ raise TypeError(f"Expected AgentTeamConfig instance, got {type(config).__name__}.")
55
+
56
+ team_id = f"team_{uuid.uuid4().hex[:8]}"
57
+ while team_id in self._active_teams:
58
+ team_id = f"team_{uuid.uuid4().hex[:8]}"
59
+
60
+ # --- Component Assembly as per new architecture ---
61
+ state = AgentTeamRuntimeState(team_id=team_id)
62
+ context = AgentTeamContext(team_id=team_id, config=config, state=state)
63
+
64
+ handler_registry = self._get_default_event_handler_registry()
65
+ runtime = AgentTeamRuntime(context=context, event_handler_registry=handler_registry)
66
+
67
+ team_manager = TeamManager(
68
+ team_id=team_id,
69
+ runtime=runtime,
70
+ multiplexer=runtime.multiplexer # Pass multiplexer created in runtime
71
+ )
72
+
73
+ context.state.team_manager = team_manager
74
+
75
+ team = AgentTeam(runtime=runtime)
76
+
77
+ self._active_teams[team_id] = team
78
+ logger.info(f"Agent Team '{team_id}' created and stored successfully.")
79
+ return team
80
+
81
+ def get_team(self, team_id: str) -> Optional[AgentTeam]:
82
+ """Retrieves an active agent team instance by its ID."""
83
+ return self._active_teams.get(team_id)
84
+
85
+ async def remove_team(self, team_id: str, shutdown_timeout: float = 10.0) -> bool:
86
+ """
87
+ Removes an agent team from the factory's management and gracefully stops it.
88
+ """
89
+ team = self._active_teams.pop(team_id, None)
90
+ if team:
91
+ logger.info(f"Removing agent team '{team_id}'. Attempting graceful shutdown.")
92
+ await team.stop(timeout=shutdown_timeout)
93
+ return True
94
+ logger.warning(f"Agent team with ID '{team_id}' not found for removal.")
95
+ return False
96
+
97
+ def list_active_team_ids(self) -> List[str]:
98
+ """Returns a list of IDs of all active agent teams managed by this factory."""
99
+ return list(self._active_teams.keys())
@@ -0,0 +1,19 @@
1
+ # file: autobyteus/autobyteus/agent_team/handlers/__init__.py
2
+ """
3
+ Event handlers for the agent team runtime.
4
+ """
5
+ from autobyteus.agent_team.handlers.base_agent_team_event_handler import BaseAgentTeamEventHandler
6
+ from autobyteus.agent_team.handlers.lifecycle_agent_team_event_handler import LifecycleAgentTeamEventHandler
7
+ from autobyteus.agent_team.handlers.inter_agent_message_request_event_handler import InterAgentMessageRequestEventHandler
8
+ from autobyteus.agent_team.handlers.process_user_message_event_handler import ProcessUserMessageEventHandler
9
+ from autobyteus.agent_team.handlers.tool_approval_team_event_handler import ToolApprovalTeamEventHandler
10
+ from autobyteus.agent_team.handlers.agent_team_event_handler_registry import AgentTeamEventHandlerRegistry
11
+
12
+ __all__ = [
13
+ "BaseAgentTeamEventHandler",
14
+ "LifecycleAgentTeamEventHandler",
15
+ "InterAgentMessageRequestEventHandler",
16
+ "ProcessUserMessageEventHandler",
17
+ "ToolApprovalTeamEventHandler",
18
+ "AgentTeamEventHandlerRegistry",
19
+ ]
@@ -0,0 +1,23 @@
1
+ # file: autobyteus/autobyteus/agent_team/handlers/agent_team_event_handler_registry.py
2
+ import logging
3
+ from typing import Dict, Type, Optional
4
+
5
+ from autobyteus.agent_team.handlers.base_agent_team_event_handler import BaseAgentTeamEventHandler
6
+ from autobyteus.agent_team.events.agent_team_events import BaseAgentTeamEvent
7
+
8
+ logger = logging.getLogger(__name__)
9
+
10
+ class AgentTeamEventHandlerRegistry:
11
+ """Manages registration and retrieval of agent team event handlers."""
12
+ def __init__(self):
13
+ self._handlers: Dict[Type[BaseAgentTeamEvent], BaseAgentTeamEventHandler] = {}
14
+ logger.info("AgentTeamEventHandlerRegistry initialized.")
15
+
16
+ def register(self, event_class: Type[BaseAgentTeamEvent], handler_instance: BaseAgentTeamEventHandler):
17
+ if not issubclass(event_class, BaseAgentTeamEvent):
18
+ raise TypeError("Can only register handlers for BaseAgentTeamEvent subclasses.")
19
+ self._handlers[event_class] = handler_instance
20
+ logger.info(f"Handler '{type(handler_instance).__name__}' registered for event '{event_class.__name__}'.")
21
+
22
+ def get_handler(self, event_class: Type[BaseAgentTeamEvent]) -> Optional[BaseAgentTeamEventHandler]:
23
+ return self._handlers.get(event_class)
@@ -0,0 +1,16 @@
1
+ # file: autobyteus/autobyteus/agent_team/handlers/base_agent_team_event_handler.py
2
+ import logging
3
+ from abc import ABC, abstractmethod
4
+ from typing import Any, TYPE_CHECKING
5
+
6
+ if TYPE_CHECKING:
7
+ from autobyteus.agent_team.context.agent_team_context import AgentTeamContext
8
+
9
+ logger = logging.getLogger(__name__)
10
+
11
+ class BaseAgentTeamEventHandler(ABC):
12
+ """Abstract base class for agent team event handlers."""
13
+
14
+ @abstractmethod
15
+ async def handle(self, event: Any, context: 'AgentTeamContext') -> None:
16
+ raise NotImplementedError("Subclasses must implement the 'handle' method.")
@@ -0,0 +1,61 @@
1
+ # file: autobyteus/autobyteus/agent_team/handlers/inter_agent_message_request_event_handler.py
2
+ import logging
3
+ from typing import TYPE_CHECKING
4
+
5
+ from autobyteus.agent_team.handlers.base_agent_team_event_handler import BaseAgentTeamEventHandler
6
+ from autobyteus.agent_team.events.agent_team_events import InterAgentMessageRequestEvent
7
+ from autobyteus.agent.message.inter_agent_message import InterAgentMessage
8
+ from autobyteus.agent.message.agent_input_user_message import AgentInputUserMessage
9
+ from autobyteus.agent_team.agent_team import AgentTeam
10
+ from autobyteus.agent.agent import Agent
11
+
12
+ if TYPE_CHECKING:
13
+ from autobyteus.agent_team.context.agent_team_context import AgentTeamContext
14
+
15
+ logger = logging.getLogger(__name__)
16
+
17
+ class InterAgentMessageRequestEventHandler(BaseAgentTeamEventHandler):
18
+ """
19
+ Handles requests to send messages between nodes (agents or sub-teams).
20
+ It relies on the TeamManager to handle on-demand startup of the recipient.
21
+ """
22
+ async def handle(self, event: InterAgentMessageRequestEvent, context: 'AgentTeamContext') -> None:
23
+ team_id = context.team_id
24
+ team_manager = context.team_manager
25
+
26
+ if not team_manager:
27
+ logger.error(f"Team '{team_id}': TeamManager not found. Cannot route message from '{event.sender_agent_id}' to '{event.recipient_name}'.")
28
+ return
29
+
30
+ try:
31
+ target_node = await team_manager.ensure_node_is_ready(name_or_agent_id=event.recipient_name)
32
+ except Exception as e:
33
+ msg = f"Recipient node '{event.recipient_name}' not found or failed to start for message from '{event.sender_agent_id}'. Error: {e}"
34
+ logger.error(f"Team '{team_id}': {msg}", exc_info=True)
35
+ return
36
+
37
+ try:
38
+ if isinstance(target_node, AgentTeam):
39
+ # If target is a sub-team, post a user message to it.
40
+ # The sub-team will route it to its own coordinator.
41
+ message_for_team = AgentInputUserMessage(content=event.content)
42
+ await target_node.post_message(message_for_team)
43
+ logger.info(f"Team '{team_id}': Successfully posted message from '{event.sender_agent_id}' to sub-team '{event.recipient_name}'.")
44
+
45
+ elif isinstance(target_node, Agent):
46
+ # If target is a regular agent, create and post an InterAgentMessage.
47
+ message_for_agent = InterAgentMessage.create_with_dynamic_message_type(
48
+ recipient_role_name=target_node.context.config.role,
49
+ recipient_agent_id=target_node.agent_id,
50
+ content=event.content,
51
+ message_type=event.message_type,
52
+ sender_agent_id=event.sender_agent_id
53
+ )
54
+ await target_node.post_inter_agent_message(message_for_agent)
55
+ logger.info(f"Team '{team_id}': Successfully posted message from '{event.sender_agent_id}' to agent '{event.recipient_name}'.")
56
+ else:
57
+ raise TypeError(f"Target node '{event.recipient_name}' is of an unsupported type: {type(target_node).__name__}")
58
+
59
+ except Exception as e:
60
+ msg = f"Error posting message to node '{event.recipient_name}': {e}"
61
+ logger.error(f"Team '{team_id}': {msg}", exc_info=True)
@@ -0,0 +1,27 @@
1
+ # file: autobyteus/autobyteus/agent_team/handlers/lifecycle_agent_team_event_handler.py
2
+ import logging
3
+ from typing import TYPE_CHECKING
4
+
5
+ from autobyteus.agent_team.handlers.base_agent_team_event_handler import BaseAgentTeamEventHandler
6
+ from autobyteus.agent_team.events.agent_team_events import BaseAgentTeamEvent, AgentTeamReadyEvent, AgentTeamErrorEvent
7
+
8
+ if TYPE_CHECKING:
9
+ from autobyteus.agent_team.context.agent_team_context import AgentTeamContext
10
+
11
+ logger = logging.getLogger(__name__)
12
+
13
+ class LifecycleAgentTeamEventHandler(BaseAgentTeamEventHandler):
14
+ """Logs various lifecycle events for an agent team."""
15
+ async def handle(self, event: BaseAgentTeamEvent, context: 'AgentTeamContext') -> None:
16
+ team_id = context.team_id
17
+ current_phase = context.state.current_phase.value
18
+
19
+ if isinstance(event, AgentTeamReadyEvent):
20
+ logger.info(f"Team '{team_id}' Logged AgentTeamReadyEvent. Current phase: {current_phase}")
21
+ elif isinstance(event, AgentTeamErrorEvent):
22
+ logger.error(
23
+ f"Team '{team_id}' Logged AgentTeamErrorEvent: {event.error_message}. "
24
+ f"Details: {event.exception_details}. Current phase: {current_phase}"
25
+ )
26
+ else:
27
+ logger.warning(f"LifecycleAgentTeamEventHandler received unhandled event type: {type(event).__name__}")
@@ -0,0 +1,46 @@
1
+ # file: autobyteus/autobyteus/agent_team/handlers/process_user_message_event_handler.py
2
+ import logging
3
+ from typing import TYPE_CHECKING
4
+ from autobyteus.agent_team.handlers.base_agent_team_event_handler import BaseAgentTeamEventHandler
5
+ from autobyteus.agent_team.events.agent_team_events import ProcessUserMessageEvent
6
+ from autobyteus.agent.agent import Agent
7
+ from autobyteus.agent_team.agent_team import AgentTeam
8
+ from autobyteus.agent.message.agent_input_user_message import AgentInputUserMessage
9
+
10
+ if TYPE_CHECKING:
11
+ from autobyteus.agent_team.context.agent_team_context import AgentTeamContext
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+ class ProcessUserMessageEventHandler(BaseAgentTeamEventHandler):
16
+ """Handles user messages by routing them to the specified target agent or sub-team."""
17
+ async def handle(self, event: ProcessUserMessageEvent, context: 'AgentTeamContext') -> None:
18
+ await context.phase_manager.notify_processing_started()
19
+
20
+ team_manager = context.team_manager
21
+ if not team_manager:
22
+ msg = f"Team '{context.team_id}': TeamManager not found. Cannot route message."
23
+ logger.error(msg)
24
+ await context.phase_manager.notify_error_occurred(msg, "TeamManager is not initialized.")
25
+ return
26
+
27
+ try:
28
+ target_node = await team_manager.ensure_node_is_ready(name_or_agent_id=event.target_agent_name)
29
+ except Exception as e:
30
+ msg = f"Team '{context.team_id}': Node '{event.target_agent_name}' not found or failed to start. Cannot route message. Error: {e}"
31
+ logger.error(msg, exc_info=True)
32
+ await context.phase_manager.notify_error_occurred(msg, f"Node '{event.target_agent_name}' not found or failed to start.")
33
+ return
34
+
35
+ if isinstance(target_node, Agent):
36
+ await target_node.post_user_message(event.user_message)
37
+ logger.info(f"Team '{context.team_id}': Routed user message to agent node '{event.target_agent_name}'.")
38
+ elif isinstance(target_node, AgentTeam):
39
+ await target_node.post_message(event.user_message)
40
+ logger.info(f"Team '{context.team_id}': Routed user message to sub-team node '{event.target_agent_name}'.")
41
+ else:
42
+ msg = f"Target node '{event.target_agent_name}' is of an unsupported type: {type(target_node).__name__}"
43
+ logger.error(f"Team '{context.team_id}': {msg}")
44
+ await context.phase_manager.notify_error_occurred(msg, "")
45
+
46
+ await context.phase_manager.notify_processing_complete_and_idle()
@@ -0,0 +1,48 @@
1
+ # file: autobyteus/autobyteus/agent_team/handlers/tool_approval_team_event_handler.py
2
+ import logging
3
+ from typing import TYPE_CHECKING
4
+
5
+ from autobyteus.agent_team.handlers.base_agent_team_event_handler import BaseAgentTeamEventHandler
6
+ from autobyteus.agent_team.events.agent_team_events import ToolApprovalTeamEvent
7
+
8
+ if TYPE_CHECKING:
9
+ from autobyteus.agent_team.context.agent_team_context import AgentTeamContext
10
+
11
+ logger = logging.getLogger(__name__)
12
+
13
+ class ToolApprovalTeamEventHandler(BaseAgentTeamEventHandler):
14
+ """
15
+ Handles tool approval events by routing them to the correct agent.
16
+ """
17
+ async def handle(self, event: ToolApprovalTeamEvent, context: 'AgentTeamContext') -> None:
18
+ team_id = context.team_id
19
+ team_manager = context.team_manager
20
+
21
+ if not team_manager:
22
+ msg = f"Team '{team_id}': TeamManager not found. Cannot route approval for agent '{event.agent_name}'."
23
+ logger.error(msg)
24
+ await context.phase_manager.notify_error_occurred(msg, "TeamManager is not initialized.")
25
+ return
26
+
27
+ from autobyteus.agent.agent import Agent
28
+ target_node = await team_manager.ensure_node_is_ready(name_or_agent_id=event.agent_name)
29
+ if not isinstance(target_node, Agent):
30
+ msg = f"Team '{team_id}': Target node '{event.agent_name}' for approval is not an agent."
31
+ logger.error(msg)
32
+ await context.phase_manager.notify_error_occurred(msg, f"Node '{event.agent_name}' is not an agent.")
33
+ return
34
+
35
+ target_agent = target_node
36
+
37
+ if not target_agent:
38
+ msg = f"Team '{team_id}': Target agent '{event.agent_name}' for approval not found or failed to start."
39
+ logger.error(msg)
40
+ await context.phase_manager.notify_error_occurred(msg, f"Agent '{event.agent_name}' not found or failed to start.")
41
+ return
42
+
43
+ logger.info(f"Team '{team_id}': Posting tool approval (Approved: {event.is_approved}) to agent '{event.agent_name}' for invocation '{event.tool_invocation_id}'.")
44
+ await target_agent.post_tool_execution_approval(
45
+ tool_invocation_id=event.tool_invocation_id,
46
+ is_approved=event.is_approved,
47
+ reason=event.reason
48
+ )
@@ -0,0 +1,11 @@
1
+ # file: autobyteus/autobyteus/agent_team/phases/__init__.py
2
+ """
3
+ This package contains components for defining and managing agent team operational phases.
4
+ """
5
+ from autobyteus.agent_team.phases.agent_team_operational_phase import AgentTeamOperationalPhase
6
+ from autobyteus.agent_team.phases.agent_team_phase_manager import AgentTeamPhaseManager
7
+
8
+ __all__ = [
9
+ "AgentTeamOperationalPhase",
10
+ "AgentTeamPhaseManager",
11
+ ]
@@ -0,0 +1,19 @@
1
+ # file: autobyteus/autobyteus/agent_team/phases/agent_team_operational_phase.py
2
+ from enum import Enum
3
+
4
+ class AgentTeamOperationalPhase(str, Enum):
5
+ """Defines the operational phases of an AgentTeam."""
6
+ UNINITIALIZED = "uninitialized"
7
+ BOOTSTRAPPING = "bootstrapping"
8
+ IDLE = "idle"
9
+ PROCESSING = "processing"
10
+ SHUTTING_DOWN = "shutting_down"
11
+ SHUTDOWN_COMPLETE = "shutdown_complete"
12
+ ERROR = "error"
13
+
14
+ def is_terminal(self) -> bool:
15
+ """Checks if the phase is a terminal state."""
16
+ return self in [AgentTeamOperationalPhase.SHUTDOWN_COMPLETE, AgentTeamOperationalPhase.ERROR]
17
+
18
+ def __str__(self) -> str:
19
+ return self.value
@@ -0,0 +1,48 @@
1
+ # file: autobyteus/autobyteus/agent_team/phases/agent_team_phase_manager.py
2
+ import logging
3
+ from typing import TYPE_CHECKING, Optional
4
+
5
+ from autobyteus.agent_team.phases.agent_team_operational_phase import AgentTeamOperationalPhase
6
+
7
+ if TYPE_CHECKING:
8
+ from autobyteus.agent_team.context.agent_team_context import AgentTeamContext
9
+ from autobyteus.agent_team.streaming.agent_team_event_notifier import AgentTeamExternalEventNotifier
10
+
11
+ logger = logging.getLogger(__name__)
12
+
13
+ class AgentTeamPhaseManager:
14
+ """Manages the operational phase of an agent team."""
15
+ def __init__(self, context: 'AgentTeamContext', notifier: 'AgentTeamExternalEventNotifier'):
16
+ self.context = context
17
+ self.notifier = notifier
18
+ self.context.state.current_phase = AgentTeamOperationalPhase.UNINITIALIZED
19
+ logger.debug(f"AgentTeamPhaseManager initialized for team '{context.team_id}'.")
20
+
21
+ async def _transition_phase(self, new_phase: AgentTeamOperationalPhase, extra_data: Optional[dict] = None):
22
+ old_phase = self.context.state.current_phase
23
+ if old_phase == new_phase:
24
+ return
25
+ logger.info(f"Team '{self.context.team_id}' transitioning from {old_phase.value} to {new_phase.value}.")
26
+ self.context.state.current_phase = new_phase
27
+ self.notifier.notify_phase_change(new_phase, old_phase, extra_data)
28
+
29
+ async def notify_bootstrapping_started(self):
30
+ await self._transition_phase(AgentTeamOperationalPhase.BOOTSTRAPPING)
31
+
32
+ async def notify_initialization_complete(self):
33
+ await self._transition_phase(AgentTeamOperationalPhase.IDLE)
34
+
35
+ async def notify_processing_started(self):
36
+ await self._transition_phase(AgentTeamOperationalPhase.PROCESSING)
37
+
38
+ async def notify_processing_complete_and_idle(self):
39
+ await self._transition_phase(AgentTeamOperationalPhase.IDLE)
40
+
41
+ async def notify_error_occurred(self, error_message: str, error_details: Optional[str] = None):
42
+ await self._transition_phase(AgentTeamOperationalPhase.ERROR, {"error_message": error_message, "error_details": error_details})
43
+
44
+ async def notify_shutdown_initiated(self):
45
+ await self._transition_phase(AgentTeamOperationalPhase.SHUTTING_DOWN)
46
+
47
+ async def notify_final_shutdown_complete(self):
48
+ await self._transition_phase(AgentTeamOperationalPhase.SHUTDOWN_COMPLETE)
@@ -0,0 +1,13 @@
1
+ # file: autobyteus/autobyteus/agent_team/runtime/__init__.py
2
+ """
3
+ The agent team runtime contains the active execution components for a team,
4
+ including the main AgentTeamRuntime controller and the AgentTeamWorker that runs
5
+ in a dedicated thread.
6
+ """
7
+ from autobyteus.agent_team.runtime.agent_team_runtime import AgentTeamRuntime
8
+ from autobyteus.agent_team.runtime.agent_team_worker import AgentTeamWorker
9
+
10
+ __all__ = [
11
+ "AgentTeamRuntime",
12
+ "AgentTeamWorker",
13
+ ]
@@ -0,0 +1,82 @@
1
+ # file: autobyteus/autobyteus/agent_team/runtime/agent_team_runtime.py
2
+ import asyncio
3
+ import logging
4
+ from typing import TYPE_CHECKING, Callable, Optional
5
+
6
+ from autobyteus.agent_team.context.agent_team_context import AgentTeamContext
7
+ from autobyteus.agent_team.phases.agent_team_phase_manager import AgentTeamPhaseManager
8
+ from autobyteus.agent_team.runtime.agent_team_worker import AgentTeamWorker
9
+ from autobyteus.agent_team.events.agent_team_events import BaseAgentTeamEvent
10
+ from autobyteus.agent_team.streaming.agent_team_event_notifier import AgentTeamExternalEventNotifier
11
+ from autobyteus.agent_team.streaming.agent_event_multiplexer import AgentEventMultiplexer
12
+
13
+ if TYPE_CHECKING:
14
+ from autobyteus.agent_team.handlers.agent_team_event_handler_registry import AgentTeamEventHandlerRegistry
15
+
16
+ logger = logging.getLogger(__name__)
17
+
18
+ class AgentTeamRuntime:
19
+ """The active execution engine for an agent team, managing the worker."""
20
+ def __init__(self, context: AgentTeamContext, event_handler_registry: 'AgentTeamEventHandlerRegistry'):
21
+ self.context = context
22
+ self.notifier = AgentTeamExternalEventNotifier(team_id=self.context.team_id, runtime_ref=self)
23
+ self.phase_manager = AgentTeamPhaseManager(context=self.context, notifier=self.notifier)
24
+
25
+ # --- FIX: Set the phase_manager_ref on the context's state BEFORE creating the worker ---
26
+ self.context.state.phase_manager_ref = self.phase_manager
27
+
28
+ self._worker = AgentTeamWorker(self.context, event_handler_registry)
29
+
30
+ self.multiplexer = AgentEventMultiplexer(
31
+ team_id=self.context.team_id,
32
+ notifier=self.notifier,
33
+ worker_ref=self._worker
34
+ )
35
+
36
+ # Set other references on the context's state object for access by other components
37
+ self.context.state.multiplexer_ref = self.multiplexer
38
+
39
+ self._worker.add_done_callback(self._handle_worker_completion)
40
+ logger.info(f"AgentTeamRuntime initialized for team '{self.context.team_id}'.")
41
+
42
+ def get_worker_loop(self) -> Optional[asyncio.AbstractEventLoop]:
43
+ """Returns the worker's event loop if it's running."""
44
+ return self._worker.get_worker_loop()
45
+
46
+ def _handle_worker_completion(self, future: asyncio.Future):
47
+ team_id = self.context.team_id
48
+ try:
49
+ future.result()
50
+ logger.info(f"AgentTeamRuntime '{team_id}': Worker thread completed.")
51
+ except Exception as e:
52
+ logger.error(f"AgentTeamRuntime '{team_id}': Worker thread terminated with exception: {e}", exc_info=True)
53
+ if not self.context.state.current_phase.is_terminal():
54
+ asyncio.run(self.phase_manager.notify_final_shutdown_complete())
55
+
56
+ def start(self):
57
+ if self._worker.is_alive:
58
+ return
59
+ self._worker.start()
60
+
61
+ async def stop(self, timeout: float = 10.0):
62
+ await self.phase_manager.notify_shutdown_initiated()
63
+ await self._worker.stop(timeout=timeout)
64
+ await self.phase_manager.notify_final_shutdown_complete()
65
+
66
+ async def submit_event(self, event: BaseAgentTeamEvent):
67
+ if not self._worker.is_alive:
68
+ raise RuntimeError("Agent team worker is not active.")
69
+ def _coro_factory():
70
+ async def _enqueue():
71
+ from autobyteus.agent_team.events.agent_team_events import ProcessUserMessageEvent
72
+ if isinstance(event, ProcessUserMessageEvent):
73
+ await self.context.state.input_event_queues.enqueue_user_message(event)
74
+ else:
75
+ await self.context.state.input_event_queues.enqueue_internal_system_event(event)
76
+ return _enqueue()
77
+ future = self._worker.schedule_coroutine(_coro_factory)
78
+ await asyncio.wrap_future(future)
79
+
80
+ @property
81
+ def is_running(self) -> bool:
82
+ return self._worker.is_alive