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/workflow/context/workflow_runtime_state.py
2
+ import logging
3
+ from typing import List, Optional, TYPE_CHECKING, Dict
4
+
5
+ from autobyteus.workflow.phases.workflow_operational_phase import WorkflowOperationalPhase
6
+ from autobyteus.agent.context import AgentConfig
7
+
8
+ if TYPE_CHECKING:
9
+ from autobyteus.agent.agent import Agent
10
+ from autobyteus.workflow.events.workflow_input_event_queue_manager import WorkflowInputEventQueueManager
11
+ from autobyteus.workflow.phases.workflow_phase_manager import WorkflowPhaseManager
12
+ from autobyteus.workflow.context.workflow_node_config import WorkflowNodeConfig
13
+ from autobyteus.workflow.context.team_manager import TeamManager
14
+ from autobyteus.workflow.streaming.agent_event_multiplexer import AgentEventMultiplexer
15
+
16
+ logger = logging.getLogger(__name__)
17
+
18
+ class WorkflowRuntimeState:
19
+ """Encapsulates the dynamic, stateful data of a running workflow instance."""
20
+ def __init__(self, workflow_id: str):
21
+ if not workflow_id or not isinstance(workflow_id, str):
22
+ raise ValueError("WorkflowRuntimeState requires a non-empty string 'workflow_id'.")
23
+
24
+ self.workflow_id: str = workflow_id
25
+ self.current_phase: WorkflowOperationalPhase = WorkflowOperationalPhase.UNINITIALIZED
26
+
27
+ # State populated by bootstrap steps
28
+ self.prepared_coordinator_prompt: Optional[str] = None
29
+ # This is now deprecated in favor of just-in-time resolution by TeamManager
30
+ # self.resolved_agent_configs: Optional[Dict[str, 'AgentConfig']] = None
31
+
32
+ # Core services
33
+ self.team_manager: Optional['TeamManager'] = None
34
+
35
+ # Runtime components and references
36
+ self.input_event_queues: Optional['WorkflowInputEventQueueManager'] = None
37
+ self.phase_manager_ref: Optional['WorkflowPhaseManager'] = None
38
+ self.multiplexer_ref: Optional['AgentEventMultiplexer'] = None
39
+
40
+ logger.info(f"WorkflowRuntimeState initialized for workflow_id '{self.workflow_id}'.")
41
+
42
+ @property
43
+ def resolved_agent_configs(self) -> Optional[Dict[str, 'AgentConfig']]:
44
+ """This property is now DEPRECATED as configs are resolved just-in-time."""
45
+ logger.warning("'resolved_agent_configs' is deprecated. Node configs are resolved by TeamManager as needed.")
46
+ return None
47
+
48
+ def __repr__(self) -> str:
49
+ agents_count = len(self.team_manager.get_all_agents()) if self.team_manager else 0
50
+ coordinator_set = self.team_manager.coordinator_agent is not None if self.team_manager else False
51
+ return (f"<WorkflowRuntimeState id='{self.workflow_id}', phase='{self.current_phase.value}', "
52
+ f"agents_count={agents_count}, coordinator_set={coordinator_set}, "
53
+ f"team_manager_set={self.team_manager is not None}>")
@@ -0,0 +1,29 @@
1
+ # file: autobyteus/autobyteus/workflow/events/__init__.py
2
+ """
3
+ This package contains event definitions and dispatchers for the workflow runtime.
4
+ """
5
+ from autobyteus.workflow.events.workflow_events import (
6
+ BaseWorkflowEvent,
7
+ LifecycleWorkflowEvent,
8
+ OperationalWorkflowEvent,
9
+ WorkflowReadyEvent,
10
+ WorkflowErrorEvent,
11
+ ProcessUserMessageEvent,
12
+ InterAgentMessageRequestEvent,
13
+ ToolApprovalWorkflowEvent,
14
+ )
15
+ from autobyteus.workflow.events.workflow_event_dispatcher import WorkflowEventDispatcher
16
+ from autobyteus.workflow.events.workflow_input_event_queue_manager import WorkflowInputEventQueueManager
17
+
18
+ __all__ = [
19
+ "BaseWorkflowEvent",
20
+ "LifecycleWorkflowEvent",
21
+ "OperationalWorkflowEvent",
22
+ "WorkflowReadyEvent",
23
+ "WorkflowErrorEvent",
24
+ "ProcessUserMessageEvent",
25
+ "InterAgentMessageRequestEvent",
26
+ "ToolApprovalWorkflowEvent",
27
+ "WorkflowEventDispatcher",
28
+ "WorkflowInputEventQueueManager",
29
+ ]
@@ -0,0 +1,39 @@
1
+ # file: autobyteus/autobyteus/workflow/events/workflow_event_dispatcher.py
2
+ import logging
3
+ import traceback
4
+ from typing import TYPE_CHECKING
5
+
6
+ from autobyteus.workflow.events.workflow_events import BaseWorkflowEvent, WorkflowReadyEvent, ProcessUserMessageEvent
7
+
8
+ if TYPE_CHECKING:
9
+ from autobyteus.workflow.context.workflow_context import WorkflowContext
10
+ from autobyteus.workflow.handlers.workflow_event_handler_registry import WorkflowEventHandlerRegistry
11
+ from autobyteus.workflow.phases.workflow_phase_manager import WorkflowPhaseManager
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+ class WorkflowEventDispatcher:
16
+ """Dispatches workflow events to their appropriate handlers."""
17
+
18
+ def __init__(self,
19
+ event_handler_registry: 'WorkflowEventHandlerRegistry',
20
+ phase_manager: 'WorkflowPhaseManager'):
21
+ self.registry = event_handler_registry
22
+ self.phase_manager = phase_manager
23
+
24
+ async def dispatch(self, event: BaseWorkflowEvent, context: 'WorkflowContext'):
25
+ handler = self.registry.get_handler(type(event))
26
+ workflow_id = context.workflow_id
27
+
28
+ if not handler:
29
+ logger.warning(f"Workflow '{workflow_id}': No handler for event '{type(event).__name__}'.")
30
+ return
31
+
32
+ try:
33
+ await handler.handle(event, context)
34
+ if isinstance(event, WorkflowReadyEvent):
35
+ await self.phase_manager.notify_initialization_complete()
36
+ except Exception as e:
37
+ error_msg = f"Error handling '{type(event).__name__}' in workflow '{workflow_id}': {e}"
38
+ logger.error(error_msg, exc_info=True)
39
+ await self.phase_manager.notify_error_occurred(error_msg, traceback.format_exc())
@@ -0,0 +1,53 @@
1
+ # file: autobyteus/autobyteus/workflow/events/workflow_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 BaseWorkflowEvent:
9
+ """Base class for all workflow events."""
10
+
11
+ @dataclass
12
+ class LifecycleWorkflowEvent(BaseWorkflowEvent):
13
+ """Base class for events related to the workflow's lifecycle."""
14
+
15
+ @dataclass
16
+ class OperationalWorkflowEvent(BaseWorkflowEvent):
17
+ """Base class for events related to the workflow's operational logic."""
18
+
19
+ # Specific Events
20
+ @dataclass
21
+ class WorkflowReadyEvent(LifecycleWorkflowEvent):
22
+ """Indicates the workflow has completed bootstrapping and is ready for tasks."""
23
+
24
+ @dataclass
25
+ class WorkflowErrorEvent(LifecycleWorkflowEvent):
26
+ """Indicates a significant error occurred within the workflow."""
27
+ error_message: str
28
+ exception_details: Optional[str] = None
29
+
30
+ @dataclass
31
+ class ProcessUserMessageEvent(OperationalWorkflowEvent):
32
+ """Carries a user's message to be processed by a specific agent in the workflow."""
33
+ user_message: AgentInputUserMessage
34
+ target_agent_name: str
35
+
36
+ @dataclass
37
+ class InterAgentMessageRequestEvent(OperationalWorkflowEvent):
38
+ """
39
+ An internal request within the workflow 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 ToolApprovalWorkflowEvent(OperationalWorkflowEvent):
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/workflow/events/workflow_input_event_queue_manager.py
2
+ import asyncio
3
+ import logging
4
+ from typing import Any
5
+
6
+ from autobyteus.workflow.events.workflow_events import ProcessUserMessageEvent
7
+
8
+ logger = logging.getLogger(__name__)
9
+
10
+ class WorkflowInputEventQueueManager:
11
+ """Manages asyncio.Queue instances for events consumed by the WorkflowWorker."""
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("WorkflowInputEventQueueManager 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/workflow/exceptions.py
2
+
3
+ class WorkflowNodeNotFoundException(Exception):
4
+ """Raised when a node (agent or sub-workflow) cannot be found in the workflow."""
5
+ def __init__(self, node_name: str, workflow_id: str):
6
+ super().__init__(f"Node '{node_name}' not found in workflow '{workflow_id}'.")
7
+ self.node_name = node_name
8
+ self.workflow_id = workflow_id
@@ -0,0 +1,9 @@
1
+ # file: autobyteus/autobyteus/workflow/factory/__init__.py
2
+ """
3
+ Workflow factory for creating AgenticWorkflow instances.
4
+ """
5
+ from autobyteus.workflow.factory.workflow_factory import WorkflowFactory
6
+
7
+ __all__ = [
8
+ "WorkflowFactory",
9
+ ]
@@ -0,0 +1,99 @@
1
+ # file: autobyteus/autobyteus/workflow/factory/workflow_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.workflow.agentic_workflow import AgenticWorkflow
8
+ from autobyteus.workflow.context.workflow_config import WorkflowConfig
9
+ from autobyteus.workflow.context.workflow_context import WorkflowContext
10
+ from autobyteus.workflow.context.workflow_runtime_state import WorkflowRuntimeState
11
+ from autobyteus.workflow.context.team_manager import TeamManager
12
+ from autobyteus.workflow.runtime.workflow_runtime import WorkflowRuntime
13
+ from autobyteus.workflow.handlers.workflow_event_handler_registry import WorkflowEventHandlerRegistry
14
+ from autobyteus.workflow.handlers.process_user_message_event_handler import ProcessUserMessageEventHandler
15
+ from autobyteus.workflow.handlers.lifecycle_workflow_event_handler import LifecycleWorkflowEventHandler
16
+ from autobyteus.workflow.handlers.inter_agent_message_request_event_handler import InterAgentMessageRequestEventHandler
17
+ from autobyteus.workflow.handlers.tool_approval_workflow_event_handler import ToolApprovalWorkflowEventHandler
18
+ from autobyteus.workflow.events.workflow_events import (
19
+ ProcessUserMessageEvent,
20
+ WorkflowReadyEvent,
21
+ WorkflowErrorEvent,
22
+ InterAgentMessageRequestEvent,
23
+ ToolApprovalWorkflowEvent
24
+ )
25
+
26
+ logger = logging.getLogger(__name__)
27
+
28
+ class WorkflowFactory(metaclass=SingletonMeta):
29
+ """
30
+ A singleton factory for creating and managing AgenticWorkflow instances.
31
+ It orchestrates the assembly of all core workflow components.
32
+ """
33
+ def __init__(self):
34
+ self._active_workflows: Dict[str, AgenticWorkflow] = {}
35
+ logger.info("WorkflowFactory (Singleton) initialized.")
36
+
37
+ def _get_default_event_handler_registry(self) -> WorkflowEventHandlerRegistry:
38
+ """Returns a registry with default handlers for a new workflow."""
39
+ registry = WorkflowEventHandlerRegistry()
40
+ registry.register(ProcessUserMessageEvent, ProcessUserMessageEventHandler())
41
+ registry.register(InterAgentMessageRequestEvent, InterAgentMessageRequestEventHandler())
42
+ registry.register(ToolApprovalWorkflowEvent, ToolApprovalWorkflowEventHandler())
43
+ lifecycle_handler = LifecycleWorkflowEventHandler()
44
+ registry.register(WorkflowReadyEvent, lifecycle_handler)
45
+ registry.register(WorkflowErrorEvent, lifecycle_handler)
46
+ return registry
47
+
48
+ def create_workflow(self, config: WorkflowConfig) -> AgenticWorkflow:
49
+ """
50
+ Creates a new workflow based on the provided WorkflowConfig, stores it,
51
+ and returns its facade (AgenticWorkflow).
52
+ """
53
+ if not isinstance(config, WorkflowConfig):
54
+ raise TypeError(f"Expected WorkflowConfig instance, got {type(config).__name__}.")
55
+
56
+ workflow_id = f"workflow_{uuid.uuid4().hex[:8]}"
57
+ while workflow_id in self._active_workflows:
58
+ workflow_id = f"workflow_{uuid.uuid4().hex[:8]}"
59
+
60
+ # --- Component Assembly as per new architecture ---
61
+ state = WorkflowRuntimeState(workflow_id=workflow_id)
62
+ context = WorkflowContext(workflow_id=workflow_id, config=config, state=state)
63
+
64
+ handler_registry = self._get_default_event_handler_registry()
65
+ runtime = WorkflowRuntime(context=context, event_handler_registry=handler_registry)
66
+
67
+ team_manager = TeamManager(
68
+ workflow_id=workflow_id,
69
+ runtime=runtime,
70
+ multiplexer=runtime.multiplexer # Pass multiplexer created in runtime
71
+ )
72
+
73
+ context.state.team_manager = team_manager
74
+
75
+ workflow = AgenticWorkflow(runtime=runtime)
76
+
77
+ self._active_workflows[workflow_id] = workflow
78
+ logger.info(f"Workflow '{workflow_id}' created and stored successfully.")
79
+ return workflow
80
+
81
+ def get_workflow(self, workflow_id: str) -> Optional[AgenticWorkflow]:
82
+ """Retrieves an active workflow instance by its ID."""
83
+ return self._active_workflows.get(workflow_id)
84
+
85
+ async def remove_workflow(self, workflow_id: str, shutdown_timeout: float = 10.0) -> bool:
86
+ """
87
+ Removes a workflow from the factory's management and gracefully stops it.
88
+ """
89
+ workflow = self._active_workflows.pop(workflow_id, None)
90
+ if workflow:
91
+ logger.info(f"Removing workflow '{workflow_id}'. Attempting graceful shutdown.")
92
+ await workflow.stop(timeout=shutdown_timeout)
93
+ return True
94
+ logger.warning(f"Workflow with ID '{workflow_id}' not found for removal.")
95
+ return False
96
+
97
+ def list_active_workflow_ids(self) -> List[str]:
98
+ """Returns a list of IDs of all active workflows managed by this factory."""
99
+ return list(self._active_workflows.keys())
@@ -0,0 +1,19 @@
1
+ # file: autobyteus/autobyteus/workflow/handlers/__init__.py
2
+ """
3
+ Event handlers for the workflow runtime.
4
+ """
5
+ from autobyteus.workflow.handlers.base_workflow_event_handler import BaseWorkflowEventHandler
6
+ from autobyteus.workflow.handlers.lifecycle_workflow_event_handler import LifecycleWorkflowEventHandler
7
+ from autobyteus.workflow.handlers.inter_agent_message_request_event_handler import InterAgentMessageRequestEventHandler
8
+ from autobyteus.workflow.handlers.process_user_message_event_handler import ProcessUserMessageEventHandler
9
+ from autobyteus.workflow.handlers.tool_approval_workflow_event_handler import ToolApprovalWorkflowEventHandler
10
+ from autobyteus.workflow.handlers.workflow_event_handler_registry import WorkflowEventHandlerRegistry
11
+
12
+ __all__ = [
13
+ "BaseWorkflowEventHandler",
14
+ "LifecycleWorkflowEventHandler",
15
+ "InterAgentMessageRequestEventHandler",
16
+ "ProcessUserMessageEventHandler",
17
+ "ToolApprovalWorkflowEventHandler",
18
+ "WorkflowEventHandlerRegistry",
19
+ ]
@@ -0,0 +1,16 @@
1
+ # file: autobyteus/autobyteus/workflow/handlers/base_workflow_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.workflow.context.workflow_context import WorkflowContext
8
+
9
+ logger = logging.getLogger(__name__)
10
+
11
+ class BaseWorkflowEventHandler(ABC):
12
+ """Abstract base class for workflow event handlers."""
13
+
14
+ @abstractmethod
15
+ async def handle(self, event: Any, context: 'WorkflowContext') -> None:
16
+ raise NotImplementedError("Subclasses must implement the 'handle' method.")
@@ -0,0 +1,61 @@
1
+ # file: autobyteus/autobyteus/workflow/handlers/inter_agent_message_request_event_handler.py
2
+ import logging
3
+ from typing import TYPE_CHECKING
4
+
5
+ from autobyteus.workflow.handlers.base_workflow_event_handler import BaseWorkflowEventHandler
6
+ from autobyteus.workflow.events.workflow_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.workflow.agentic_workflow import AgenticWorkflow
10
+ from autobyteus.agent.agent import Agent
11
+
12
+ if TYPE_CHECKING:
13
+ from autobyteus.workflow.context.workflow_context import WorkflowContext
14
+
15
+ logger = logging.getLogger(__name__)
16
+
17
+ class InterAgentMessageRequestEventHandler(BaseWorkflowEventHandler):
18
+ """
19
+ Handles requests to send messages between nodes (agents or sub-workflows).
20
+ It relies on the TeamManager to handle on-demand startup of the recipient.
21
+ """
22
+ async def handle(self, event: InterAgentMessageRequestEvent, context: 'WorkflowContext') -> None:
23
+ workflow_id = context.workflow_id
24
+ team_manager = context.team_manager
25
+
26
+ if not team_manager:
27
+ logger.error(f"Workflow '{workflow_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(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"Workflow '{workflow_id}': {msg}", exc_info=True)
35
+ return
36
+
37
+ try:
38
+ if isinstance(target_node, AgenticWorkflow):
39
+ # If target is a sub-workflow, post a user message to it.
40
+ # The sub-workflow will route it to its own coordinator.
41
+ message_for_workflow = AgentInputUserMessage(content=event.content)
42
+ await target_node.post_message(message_for_workflow)
43
+ logger.info(f"Workflow '{workflow_id}': Successfully posted message from '{event.sender_agent_id}' to sub-workflow '{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"Workflow '{workflow_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"Workflow '{workflow_id}': {msg}", exc_info=True)
@@ -0,0 +1,27 @@
1
+ # file: autobyteus/autobyteus/workflow/handlers/lifecycle_workflow_event_handler.py
2
+ import logging
3
+ from typing import TYPE_CHECKING
4
+
5
+ from autobyteus.workflow.handlers.base_workflow_event_handler import BaseWorkflowEventHandler
6
+ from autobyteus.workflow.events.workflow_events import BaseWorkflowEvent, WorkflowReadyEvent, WorkflowErrorEvent
7
+
8
+ if TYPE_CHECKING:
9
+ from autobyteus.workflow.context.workflow_context import WorkflowContext
10
+
11
+ logger = logging.getLogger(__name__)
12
+
13
+ class LifecycleWorkflowEventHandler(BaseWorkflowEventHandler):
14
+ """Logs various lifecycle events for a workflow."""
15
+ async def handle(self, event: BaseWorkflowEvent, context: 'WorkflowContext') -> None:
16
+ workflow_id = context.workflow_id
17
+ current_phase = context.state.current_phase.value
18
+
19
+ if isinstance(event, WorkflowReadyEvent):
20
+ logger.info(f"Workflow '{workflow_id}' Logged WorkflowReadyEvent. Current phase: {current_phase}")
21
+ elif isinstance(event, WorkflowErrorEvent):
22
+ logger.error(
23
+ f"Workflow '{workflow_id}' Logged WorkflowErrorEvent: {event.error_message}. "
24
+ f"Details: {event.exception_details}. Current phase: {current_phase}"
25
+ )
26
+ else:
27
+ logger.warning(f"LifecycleWorkflowEventHandler received unhandled event type: {type(event).__name__}")
@@ -0,0 +1,46 @@
1
+ # file: autobyteus/autobyteus/workflow/handlers/process_user_message_event_handler.py
2
+ import logging
3
+ from typing import TYPE_CHECKING
4
+ from autobyteus.workflow.handlers.base_workflow_event_handler import BaseWorkflowEventHandler
5
+ from autobyteus.workflow.events.workflow_events import ProcessUserMessageEvent
6
+ from autobyteus.agent.agent import Agent
7
+ from autobyteus.workflow.agentic_workflow import AgenticWorkflow
8
+ from autobyteus.agent.message.agent_input_user_message import AgentInputUserMessage
9
+
10
+ if TYPE_CHECKING:
11
+ from autobyteus.workflow.context.workflow_context import WorkflowContext
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+ class ProcessUserMessageEventHandler(BaseWorkflowEventHandler):
16
+ """Handles user messages by routing them to the specified target agent or sub-workflow."""
17
+ async def handle(self, event: ProcessUserMessageEvent, context: 'WorkflowContext') -> None:
18
+ await context.phase_manager.notify_processing_started()
19
+
20
+ team_manager = context.team_manager
21
+ if not team_manager:
22
+ msg = f"Workflow '{context.workflow_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(event.target_agent_name)
29
+ except Exception as e:
30
+ msg = f"Workflow '{context.workflow_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"Workflow '{context.workflow_id}': Routed user message to agent node '{event.target_agent_name}'.")
38
+ elif isinstance(target_node, AgenticWorkflow):
39
+ await target_node.post_message(event.user_message)
40
+ logger.info(f"Workflow '{context.workflow_id}': Routed user message to sub-workflow 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"Workflow '{context.workflow_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,39 @@
1
+ # file: autobyteus/autobyteus/workflow/handlers/tool_approval_workflow_event_handler.py
2
+ import logging
3
+ from typing import TYPE_CHECKING
4
+
5
+ from autobyteus.workflow.handlers.base_workflow_event_handler import BaseWorkflowEventHandler
6
+ from autobyteus.workflow.events.workflow_events import ToolApprovalWorkflowEvent
7
+
8
+ if TYPE_CHECKING:
9
+ from autobyteus.workflow.context.workflow_context import WorkflowContext
10
+
11
+ logger = logging.getLogger(__name__)
12
+
13
+ class ToolApprovalWorkflowEventHandler(BaseWorkflowEventHandler):
14
+ """
15
+ Handles tool approval events by routing them to the correct agent.
16
+ """
17
+ async def handle(self, event: ToolApprovalWorkflowEvent, context: 'WorkflowContext') -> None:
18
+ workflow_id = context.workflow_id
19
+ team_manager = context.team_manager
20
+
21
+ if not team_manager:
22
+ msg = f"Workflow '{workflow_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
+ target_agent = await team_manager.ensure_agent_is_ready(event.agent_name)
28
+ if not target_agent:
29
+ msg = f"Workflow '{workflow_id}': Target agent '{event.agent_name}' for approval not found or failed to start."
30
+ logger.error(msg)
31
+ await context.phase_manager.notify_error_occurred(msg, f"Agent '{event.agent_name}' not found or failed to start.")
32
+ return
33
+
34
+ logger.info(f"Workflow '{workflow_id}': Posting tool approval (Approved: {event.is_approved}) to agent '{event.agent_name}' for invocation '{event.tool_invocation_id}'.")
35
+ await target_agent.post_tool_execution_approval(
36
+ tool_invocation_id=event.tool_invocation_id,
37
+ is_approved=event.is_approved,
38
+ reason=event.reason
39
+ )
@@ -0,0 +1,23 @@
1
+ # file: autobyteus/autobyteus/workflow/handlers/workflow_event_handler_registry.py
2
+ import logging
3
+ from typing import Dict, Type, Optional
4
+
5
+ from autobyteus.workflow.handlers.base_workflow_event_handler import BaseWorkflowEventHandler
6
+ from autobyteus.workflow.events.workflow_events import BaseWorkflowEvent
7
+
8
+ logger = logging.getLogger(__name__)
9
+
10
+ class WorkflowEventHandlerRegistry:
11
+ """Manages registration and retrieval of workflow event handlers."""
12
+ def __init__(self):
13
+ self._handlers: Dict[Type[BaseWorkflowEvent], BaseWorkflowEventHandler] = {}
14
+ logger.info("WorkflowEventHandlerRegistry initialized.")
15
+
16
+ def register(self, event_class: Type[BaseWorkflowEvent], handler_instance: BaseWorkflowEventHandler):
17
+ if not issubclass(event_class, BaseWorkflowEvent):
18
+ raise TypeError("Can only register handlers for BaseWorkflowEvent 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[BaseWorkflowEvent]) -> Optional[BaseWorkflowEventHandler]:
23
+ return self._handlers.get(event_class)
@@ -0,0 +1,11 @@
1
+ # file: autobyteus/autobyteus/workflow/phases/__init__.py
2
+ """
3
+ This package contains components for defining and managing workflow operational phases.
4
+ """
5
+ from autobyteus.workflow.phases.workflow_operational_phase import WorkflowOperationalPhase
6
+ from autobyteus.workflow.phases.workflow_phase_manager import WorkflowPhaseManager
7
+
8
+ __all__ = [
9
+ "WorkflowOperationalPhase",
10
+ "WorkflowPhaseManager",
11
+ ]
@@ -0,0 +1,19 @@
1
+ # file: autobyteus/autobyteus/workflow/phases/workflow_operational_phase.py
2
+ from enum import Enum
3
+
4
+ class WorkflowOperationalPhase(str, Enum):
5
+ """Defines the operational phases of an AgenticWorkflow."""
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 [WorkflowOperationalPhase.SHUTDOWN_COMPLETE, WorkflowOperationalPhase.ERROR]
17
+
18
+ def __str__(self) -> str:
19
+ return self.value
@@ -0,0 +1,48 @@
1
+ # file: autobyteus/autobyteus/workflow/phases/workflow_phase_manager.py
2
+ import logging
3
+ from typing import TYPE_CHECKING, Optional
4
+
5
+ from autobyteus.workflow.phases.workflow_operational_phase import WorkflowOperationalPhase
6
+
7
+ if TYPE_CHECKING:
8
+ from autobyteus.workflow.context.workflow_context import WorkflowContext
9
+ from autobyteus.workflow.streaming.workflow_event_notifier import WorkflowExternalEventNotifier
10
+
11
+ logger = logging.getLogger(__name__)
12
+
13
+ class WorkflowPhaseManager:
14
+ """Manages the operational phase of a workflow."""
15
+ def __init__(self, context: 'WorkflowContext', notifier: 'WorkflowExternalEventNotifier'):
16
+ self.context = context
17
+ self.notifier = notifier
18
+ self.context.state.current_phase = WorkflowOperationalPhase.UNINITIALIZED
19
+ logger.debug(f"WorkflowPhaseManager initialized for workflow '{context.workflow_id}'.")
20
+
21
+ async def _transition_phase(self, new_phase: WorkflowOperationalPhase, 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"Workflow '{self.context.workflow_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(WorkflowOperationalPhase.BOOTSTRAPPING)
31
+
32
+ async def notify_initialization_complete(self):
33
+ await self._transition_phase(WorkflowOperationalPhase.IDLE)
34
+
35
+ async def notify_processing_started(self):
36
+ await self._transition_phase(WorkflowOperationalPhase.PROCESSING)
37
+
38
+ async def notify_processing_complete_and_idle(self):
39
+ await self._transition_phase(WorkflowOperationalPhase.IDLE)
40
+
41
+ async def notify_error_occurred(self, error_message: str, error_details: Optional[str] = None):
42
+ await self._transition_phase(WorkflowOperationalPhase.ERROR, {"error_message": error_message, "error_details": error_details})
43
+
44
+ async def notify_shutdown_initiated(self):
45
+ await self._transition_phase(WorkflowOperationalPhase.SHUTTING_DOWN)
46
+
47
+ async def notify_final_shutdown_complete(self):
48
+ await self._transition_phase(WorkflowOperationalPhase.SHUTDOWN_COMPLETE)
@@ -0,0 +1,13 @@
1
+ # file: autobyteus/autobyteus/workflow/runtime/__init__.py
2
+ """
3
+ The workflow runtime contains the active execution components for a workflow,
4
+ including the main WorkflowRuntime controller and the WorkflowWorker that runs
5
+ in a dedicated thread.
6
+ """
7
+ from autobyteus.workflow.runtime.workflow_runtime import WorkflowRuntime
8
+ from autobyteus.workflow.runtime.workflow_worker import WorkflowWorker
9
+
10
+ __all__ = [
11
+ "WorkflowRuntime",
12
+ "WorkflowWorker",
13
+ ]