autobyteus 1.2.1__py3-none-any.whl → 1.3.0__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 (472) hide show
  1. autobyteus/agent/agent.py +15 -5
  2. autobyteus/agent/bootstrap_steps/__init__.py +3 -3
  3. autobyteus/agent/bootstrap_steps/agent_bootstrapper.py +5 -59
  4. autobyteus/agent/bootstrap_steps/base_bootstrap_step.py +1 -4
  5. autobyteus/agent/bootstrap_steps/mcp_server_prewarming_step.py +1 -3
  6. autobyteus/agent/bootstrap_steps/system_prompt_processing_step.py +16 -13
  7. autobyteus/agent/bootstrap_steps/working_context_snapshot_restore_step.py +38 -0
  8. autobyteus/agent/bootstrap_steps/workspace_context_initialization_step.py +2 -4
  9. autobyteus/agent/context/agent_config.py +47 -20
  10. autobyteus/agent/context/agent_context.py +23 -18
  11. autobyteus/agent/context/agent_runtime_state.py +21 -19
  12. autobyteus/agent/events/__init__.py +16 -1
  13. autobyteus/agent/events/agent_events.py +43 -3
  14. autobyteus/agent/events/agent_input_event_queue_manager.py +79 -26
  15. autobyteus/agent/events/event_store.py +57 -0
  16. autobyteus/agent/events/notifiers.py +69 -59
  17. autobyteus/agent/events/worker_event_dispatcher.py +21 -64
  18. autobyteus/agent/factory/agent_factory.py +83 -6
  19. autobyteus/agent/handlers/__init__.py +2 -0
  20. autobyteus/agent/handlers/approved_tool_invocation_event_handler.py +51 -34
  21. autobyteus/agent/handlers/bootstrap_event_handler.py +155 -0
  22. autobyteus/agent/handlers/inter_agent_message_event_handler.py +10 -0
  23. autobyteus/agent/handlers/lifecycle_event_logger.py +19 -11
  24. autobyteus/agent/handlers/llm_complete_response_received_event_handler.py +10 -15
  25. autobyteus/agent/handlers/llm_user_message_ready_event_handler.py +188 -48
  26. autobyteus/agent/handlers/tool_execution_approval_event_handler.py +0 -10
  27. autobyteus/agent/handlers/tool_invocation_request_event_handler.py +53 -48
  28. autobyteus/agent/handlers/tool_result_event_handler.py +7 -8
  29. autobyteus/agent/handlers/user_input_message_event_handler.py +10 -3
  30. autobyteus/agent/input_processor/memory_ingest_input_processor.py +44 -0
  31. autobyteus/agent/lifecycle/__init__.py +12 -0
  32. autobyteus/agent/lifecycle/base_processor.py +109 -0
  33. autobyteus/agent/lifecycle/events.py +35 -0
  34. autobyteus/agent/lifecycle/processor_definition.py +36 -0
  35. autobyteus/agent/lifecycle/processor_registry.py +106 -0
  36. autobyteus/agent/llm_request_assembler.py +98 -0
  37. autobyteus/agent/llm_response_processor/__init__.py +1 -8
  38. autobyteus/agent/message/context_file_type.py +1 -1
  39. autobyteus/agent/runtime/agent_runtime.py +29 -21
  40. autobyteus/agent/runtime/agent_worker.py +98 -19
  41. autobyteus/agent/shutdown_steps/__init__.py +2 -0
  42. autobyteus/agent/shutdown_steps/agent_shutdown_orchestrator.py +2 -0
  43. autobyteus/agent/shutdown_steps/tool_cleanup_step.py +58 -0
  44. autobyteus/agent/status/__init__.py +14 -0
  45. autobyteus/agent/status/manager.py +93 -0
  46. autobyteus/agent/status/status_deriver.py +96 -0
  47. autobyteus/agent/{phases/phase_enum.py → status/status_enum.py} +16 -16
  48. autobyteus/agent/status/status_update_utils.py +73 -0
  49. autobyteus/agent/streaming/__init__.py +52 -5
  50. autobyteus/agent/streaming/adapters/__init__.py +18 -0
  51. autobyteus/agent/streaming/adapters/invocation_adapter.py +184 -0
  52. autobyteus/agent/streaming/adapters/tool_call_parsing.py +163 -0
  53. autobyteus/agent/streaming/adapters/tool_syntax_registry.py +67 -0
  54. autobyteus/agent/streaming/agent_event_stream.py +3 -183
  55. autobyteus/agent/streaming/api_tool_call/__init__.py +16 -0
  56. autobyteus/agent/streaming/api_tool_call/file_content_streamer.py +56 -0
  57. autobyteus/agent/streaming/api_tool_call/json_string_field_extractor.py +175 -0
  58. autobyteus/agent/streaming/api_tool_call_streaming_response_handler.py +4 -0
  59. autobyteus/agent/streaming/events/__init__.py +6 -0
  60. autobyteus/agent/streaming/events/stream_event_payloads.py +284 -0
  61. autobyteus/agent/streaming/events/stream_events.py +141 -0
  62. autobyteus/agent/streaming/handlers/__init__.py +15 -0
  63. autobyteus/agent/streaming/handlers/api_tool_call_streaming_response_handler.py +303 -0
  64. autobyteus/agent/streaming/handlers/parsing_streaming_response_handler.py +107 -0
  65. autobyteus/agent/streaming/handlers/pass_through_streaming_response_handler.py +107 -0
  66. autobyteus/agent/streaming/handlers/streaming_handler_factory.py +177 -0
  67. autobyteus/agent/streaming/handlers/streaming_response_handler.py +58 -0
  68. autobyteus/agent/streaming/parser/__init__.py +61 -0
  69. autobyteus/agent/streaming/parser/event_emitter.py +181 -0
  70. autobyteus/agent/streaming/parser/events.py +4 -0
  71. autobyteus/agent/streaming/parser/invocation_adapter.py +4 -0
  72. autobyteus/agent/streaming/parser/json_parsing_strategies/__init__.py +19 -0
  73. autobyteus/agent/streaming/parser/json_parsing_strategies/base.py +32 -0
  74. autobyteus/agent/streaming/parser/json_parsing_strategies/default.py +34 -0
  75. autobyteus/agent/streaming/parser/json_parsing_strategies/gemini.py +31 -0
  76. autobyteus/agent/streaming/parser/json_parsing_strategies/openai.py +64 -0
  77. autobyteus/agent/streaming/parser/json_parsing_strategies/registry.py +75 -0
  78. autobyteus/agent/streaming/parser/parser_context.py +227 -0
  79. autobyteus/agent/streaming/parser/parser_factory.py +132 -0
  80. autobyteus/agent/streaming/parser/sentinel_format.py +7 -0
  81. autobyteus/agent/streaming/parser/state_factory.py +62 -0
  82. autobyteus/agent/streaming/parser/states/__init__.py +1 -0
  83. autobyteus/agent/streaming/parser/states/base_state.py +60 -0
  84. autobyteus/agent/streaming/parser/states/custom_xml_tag_run_bash_parsing_state.py +38 -0
  85. autobyteus/agent/streaming/parser/states/custom_xml_tag_write_file_parsing_state.py +55 -0
  86. autobyteus/agent/streaming/parser/states/delimited_content_state.py +146 -0
  87. autobyteus/agent/streaming/parser/states/json_initialization_state.py +144 -0
  88. autobyteus/agent/streaming/parser/states/json_tool_parsing_state.py +137 -0
  89. autobyteus/agent/streaming/parser/states/sentinel_content_state.py +30 -0
  90. autobyteus/agent/streaming/parser/states/sentinel_initialization_state.py +117 -0
  91. autobyteus/agent/streaming/parser/states/text_state.py +78 -0
  92. autobyteus/agent/streaming/parser/states/xml_patch_file_tool_parsing_state.py +328 -0
  93. autobyteus/agent/streaming/parser/states/xml_run_bash_tool_parsing_state.py +129 -0
  94. autobyteus/agent/streaming/parser/states/xml_tag_initialization_state.py +151 -0
  95. autobyteus/agent/streaming/parser/states/xml_tool_parsing_state.py +63 -0
  96. autobyteus/agent/streaming/parser/states/xml_write_file_tool_parsing_state.py +343 -0
  97. autobyteus/agent/streaming/parser/strategies/__init__.py +17 -0
  98. autobyteus/agent/streaming/parser/strategies/base.py +24 -0
  99. autobyteus/agent/streaming/parser/strategies/json_tool_strategy.py +26 -0
  100. autobyteus/agent/streaming/parser/strategies/registry.py +28 -0
  101. autobyteus/agent/streaming/parser/strategies/sentinel_strategy.py +23 -0
  102. autobyteus/agent/streaming/parser/strategies/xml_tag_strategy.py +21 -0
  103. autobyteus/agent/streaming/parser/stream_scanner.py +167 -0
  104. autobyteus/agent/streaming/parser/streaming_parser.py +212 -0
  105. autobyteus/agent/streaming/parser/tool_call_parsing.py +4 -0
  106. autobyteus/agent/streaming/parser/tool_constants.py +7 -0
  107. autobyteus/agent/streaming/parser/tool_syntax_registry.py +4 -0
  108. autobyteus/agent/streaming/parser/xml_tool_parsing_state_registry.py +55 -0
  109. autobyteus/agent/streaming/parsing_streaming_response_handler.py +4 -0
  110. autobyteus/agent/streaming/pass_through_streaming_response_handler.py +4 -0
  111. autobyteus/agent/streaming/queue_streamer.py +3 -57
  112. autobyteus/agent/streaming/segments/__init__.py +5 -0
  113. autobyteus/agent/streaming/segments/segment_events.py +82 -0
  114. autobyteus/agent/streaming/stream_event_payloads.py +2 -223
  115. autobyteus/agent/streaming/stream_events.py +3 -140
  116. autobyteus/agent/streaming/streaming_handler_factory.py +4 -0
  117. autobyteus/agent/streaming/streaming_response_handler.py +4 -0
  118. autobyteus/agent/streaming/streams/__init__.py +5 -0
  119. autobyteus/agent/streaming/streams/agent_event_stream.py +197 -0
  120. autobyteus/agent/streaming/utils/__init__.py +5 -0
  121. autobyteus/agent/streaming/utils/queue_streamer.py +59 -0
  122. autobyteus/agent/system_prompt_processor/__init__.py +2 -0
  123. autobyteus/agent/system_prompt_processor/available_skills_processor.py +96 -0
  124. autobyteus/agent/system_prompt_processor/base_processor.py +1 -1
  125. autobyteus/agent/system_prompt_processor/processor_meta.py +15 -2
  126. autobyteus/agent/system_prompt_processor/tool_manifest_injector_processor.py +39 -58
  127. autobyteus/agent/token_budget.py +56 -0
  128. autobyteus/agent/tool_execution_result_processor/memory_ingest_tool_result_processor.py +29 -0
  129. autobyteus/agent/tool_invocation.py +16 -40
  130. autobyteus/agent/tool_invocation_preprocessor/__init__.py +9 -0
  131. autobyteus/agent/tool_invocation_preprocessor/base_preprocessor.py +45 -0
  132. autobyteus/agent/tool_invocation_preprocessor/processor_definition.py +15 -0
  133. autobyteus/agent/tool_invocation_preprocessor/processor_meta.py +33 -0
  134. autobyteus/agent/tool_invocation_preprocessor/processor_registry.py +60 -0
  135. autobyteus/agent/utils/wait_for_idle.py +12 -14
  136. autobyteus/agent/workspace/base_workspace.py +6 -27
  137. autobyteus/agent_team/agent_team.py +3 -3
  138. autobyteus/agent_team/agent_team_builder.py +1 -41
  139. autobyteus/agent_team/bootstrap_steps/__init__.py +0 -4
  140. autobyteus/agent_team/bootstrap_steps/agent_configuration_preparation_step.py +8 -18
  141. autobyteus/agent_team/bootstrap_steps/agent_team_bootstrapper.py +4 -16
  142. autobyteus/agent_team/bootstrap_steps/base_agent_team_bootstrap_step.py +1 -2
  143. autobyteus/agent_team/bootstrap_steps/coordinator_initialization_step.py +1 -2
  144. autobyteus/agent_team/bootstrap_steps/task_notifier_initialization_step.py +1 -2
  145. autobyteus/agent_team/bootstrap_steps/team_context_initialization_step.py +4 -4
  146. autobyteus/agent_team/context/agent_team_config.py +6 -3
  147. autobyteus/agent_team/context/agent_team_context.py +25 -3
  148. autobyteus/agent_team/context/agent_team_runtime_state.py +9 -6
  149. autobyteus/agent_team/events/__init__.py +11 -0
  150. autobyteus/agent_team/events/agent_team_event_dispatcher.py +22 -9
  151. autobyteus/agent_team/events/agent_team_events.py +16 -0
  152. autobyteus/agent_team/events/event_store.py +57 -0
  153. autobyteus/agent_team/factory/agent_team_factory.py +8 -0
  154. autobyteus/agent_team/handlers/inter_agent_message_request_event_handler.py +18 -2
  155. autobyteus/agent_team/handlers/lifecycle_agent_team_event_handler.py +21 -5
  156. autobyteus/agent_team/handlers/process_user_message_event_handler.py +17 -8
  157. autobyteus/agent_team/handlers/tool_approval_team_event_handler.py +19 -4
  158. autobyteus/agent_team/runtime/agent_team_runtime.py +41 -10
  159. autobyteus/agent_team/runtime/agent_team_worker.py +69 -5
  160. autobyteus/agent_team/status/__init__.py +14 -0
  161. autobyteus/agent_team/status/agent_team_status.py +18 -0
  162. autobyteus/agent_team/status/agent_team_status_manager.py +33 -0
  163. autobyteus/agent_team/status/status_deriver.py +62 -0
  164. autobyteus/agent_team/status/status_update_utils.py +42 -0
  165. autobyteus/agent_team/streaming/__init__.py +2 -2
  166. autobyteus/agent_team/streaming/agent_team_event_notifier.py +6 -6
  167. autobyteus/agent_team/streaming/agent_team_stream_event_payloads.py +4 -4
  168. autobyteus/agent_team/streaming/agent_team_stream_events.py +3 -3
  169. autobyteus/agent_team/system_prompt_processor/__init__.py +6 -0
  170. autobyteus/agent_team/system_prompt_processor/team_manifest_injector_processor.py +76 -0
  171. autobyteus/agent_team/task_notification/task_notification_mode.py +19 -0
  172. autobyteus/agent_team/utils/wait_for_idle.py +4 -4
  173. autobyteus/cli/agent_cli.py +18 -10
  174. autobyteus/cli/agent_team_tui/app.py +14 -11
  175. autobyteus/cli/agent_team_tui/state.py +13 -15
  176. autobyteus/cli/agent_team_tui/widgets/agent_list_sidebar.py +15 -15
  177. autobyteus/cli/agent_team_tui/widgets/focus_pane.py +143 -36
  178. autobyteus/cli/agent_team_tui/widgets/renderables.py +1 -1
  179. autobyteus/cli/agent_team_tui/widgets/shared.py +25 -25
  180. autobyteus/cli/cli_display.py +193 -44
  181. autobyteus/cli/workflow_tui/app.py +9 -10
  182. autobyteus/cli/workflow_tui/state.py +14 -16
  183. autobyteus/cli/workflow_tui/widgets/agent_list_sidebar.py +15 -15
  184. autobyteus/cli/workflow_tui/widgets/focus_pane.py +137 -35
  185. autobyteus/cli/workflow_tui/widgets/renderables.py +1 -1
  186. autobyteus/cli/workflow_tui/widgets/shared.py +25 -25
  187. autobyteus/clients/autobyteus_client.py +94 -1
  188. autobyteus/events/event_types.py +11 -18
  189. autobyteus/llm/api/autobyteus_llm.py +33 -29
  190. autobyteus/llm/api/claude_llm.py +142 -36
  191. autobyteus/llm/api/gemini_llm.py +163 -59
  192. autobyteus/llm/api/grok_llm.py +1 -1
  193. autobyteus/llm/api/minimax_llm.py +26 -0
  194. autobyteus/llm/api/mistral_llm.py +113 -87
  195. autobyteus/llm/api/ollama_llm.py +9 -42
  196. autobyteus/llm/api/openai_compatible_llm.py +127 -91
  197. autobyteus/llm/api/openai_llm.py +3 -3
  198. autobyteus/llm/api/openai_responses_llm.py +324 -0
  199. autobyteus/llm/api/zhipu_llm.py +21 -2
  200. autobyteus/llm/autobyteus_provider.py +70 -60
  201. autobyteus/llm/base_llm.py +85 -81
  202. autobyteus/llm/converters/__init__.py +14 -0
  203. autobyteus/llm/converters/anthropic_tool_call_converter.py +37 -0
  204. autobyteus/llm/converters/gemini_tool_call_converter.py +57 -0
  205. autobyteus/llm/converters/mistral_tool_call_converter.py +37 -0
  206. autobyteus/llm/converters/openai_tool_call_converter.py +38 -0
  207. autobyteus/llm/extensions/base_extension.py +6 -12
  208. autobyteus/llm/extensions/token_usage_tracking_extension.py +45 -18
  209. autobyteus/llm/llm_factory.py +282 -204
  210. autobyteus/llm/lmstudio_provider.py +60 -49
  211. autobyteus/llm/models.py +35 -2
  212. autobyteus/llm/ollama_provider.py +60 -49
  213. autobyteus/llm/ollama_provider_resolver.py +0 -1
  214. autobyteus/llm/prompt_renderers/__init__.py +19 -0
  215. autobyteus/llm/prompt_renderers/anthropic_prompt_renderer.py +104 -0
  216. autobyteus/llm/prompt_renderers/autobyteus_prompt_renderer.py +19 -0
  217. autobyteus/llm/prompt_renderers/base_prompt_renderer.py +10 -0
  218. autobyteus/llm/prompt_renderers/gemini_prompt_renderer.py +63 -0
  219. autobyteus/llm/prompt_renderers/mistral_prompt_renderer.py +87 -0
  220. autobyteus/llm/prompt_renderers/ollama_prompt_renderer.py +51 -0
  221. autobyteus/llm/prompt_renderers/openai_chat_renderer.py +97 -0
  222. autobyteus/llm/prompt_renderers/openai_responses_renderer.py +101 -0
  223. autobyteus/llm/providers.py +1 -3
  224. autobyteus/llm/token_counter/claude_token_counter.py +56 -25
  225. autobyteus/llm/token_counter/mistral_token_counter.py +12 -8
  226. autobyteus/llm/token_counter/openai_token_counter.py +24 -5
  227. autobyteus/llm/token_counter/token_counter_factory.py +12 -5
  228. autobyteus/llm/utils/llm_config.py +6 -12
  229. autobyteus/llm/utils/media_payload_formatter.py +27 -20
  230. autobyteus/llm/utils/messages.py +55 -3
  231. autobyteus/llm/utils/response_types.py +3 -0
  232. autobyteus/llm/utils/tool_call_delta.py +31 -0
  233. autobyteus/memory/__init__.py +35 -0
  234. autobyteus/memory/compaction/__init__.py +9 -0
  235. autobyteus/memory/compaction/compaction_result.py +8 -0
  236. autobyteus/memory/compaction/compactor.py +89 -0
  237. autobyteus/memory/compaction/summarizer.py +11 -0
  238. autobyteus/memory/compaction_snapshot_builder.py +84 -0
  239. autobyteus/memory/memory_manager.py +205 -0
  240. autobyteus/memory/models/__init__.py +14 -0
  241. autobyteus/memory/models/episodic_item.py +41 -0
  242. autobyteus/memory/models/memory_types.py +7 -0
  243. autobyteus/memory/models/raw_trace_item.py +79 -0
  244. autobyteus/memory/models/semantic_item.py +41 -0
  245. autobyteus/memory/models/tool_interaction.py +20 -0
  246. autobyteus/memory/path_resolver.py +27 -0
  247. autobyteus/memory/policies/__init__.py +5 -0
  248. autobyteus/memory/policies/compaction_policy.py +16 -0
  249. autobyteus/memory/restore/__init__.py +1 -0
  250. autobyteus/memory/restore/working_context_snapshot_bootstrapper.py +61 -0
  251. autobyteus/memory/retrieval/__init__.py +7 -0
  252. autobyteus/memory/retrieval/memory_bundle.py +11 -0
  253. autobyteus/memory/retrieval/retriever.py +13 -0
  254. autobyteus/memory/store/__init__.py +9 -0
  255. autobyteus/memory/store/base_store.py +14 -0
  256. autobyteus/memory/store/file_store.py +98 -0
  257. autobyteus/memory/store/working_context_snapshot_store.py +28 -0
  258. autobyteus/memory/tool_interaction_builder.py +46 -0
  259. autobyteus/memory/turn_tracker.py +9 -0
  260. autobyteus/memory/working_context_snapshot.py +69 -0
  261. autobyteus/memory/working_context_snapshot_serializer.py +135 -0
  262. autobyteus/multimedia/audio/api/autobyteus_audio_client.py +19 -5
  263. autobyteus/multimedia/audio/api/gemini_audio_client.py +109 -16
  264. autobyteus/multimedia/audio/audio_client_factory.py +47 -9
  265. autobyteus/multimedia/audio/audio_model.py +2 -1
  266. autobyteus/multimedia/image/api/autobyteus_image_client.py +19 -5
  267. autobyteus/multimedia/image/api/gemini_image_client.py +39 -17
  268. autobyteus/multimedia/image/api/openai_image_client.py +125 -43
  269. autobyteus/multimedia/image/autobyteus_image_provider.py +2 -1
  270. autobyteus/multimedia/image/image_client_factory.py +47 -15
  271. autobyteus/multimedia/image/image_model.py +5 -2
  272. autobyteus/multimedia/providers.py +3 -2
  273. autobyteus/skills/loader.py +71 -0
  274. autobyteus/skills/model.py +11 -0
  275. autobyteus/skills/registry.py +70 -0
  276. autobyteus/task_management/tools/todo_tools/add_todo.py +2 -2
  277. autobyteus/task_management/tools/todo_tools/create_todo_list.py +2 -2
  278. autobyteus/task_management/tools/todo_tools/update_todo_status.py +2 -2
  279. autobyteus/tools/__init__.py +34 -47
  280. autobyteus/tools/base_tool.py +7 -0
  281. autobyteus/tools/file/__init__.py +2 -6
  282. autobyteus/tools/file/patch_file.py +149 -0
  283. autobyteus/tools/file/read_file.py +36 -5
  284. autobyteus/tools/file/write_file.py +4 -1
  285. autobyteus/tools/functional_tool.py +43 -6
  286. autobyteus/tools/mcp/__init__.py +2 -0
  287. autobyteus/tools/mcp/config_service.py +5 -1
  288. autobyteus/tools/mcp/server/__init__.py +2 -0
  289. autobyteus/tools/mcp/server/http_managed_mcp_server.py +1 -1
  290. autobyteus/tools/mcp/server/websocket_managed_mcp_server.py +141 -0
  291. autobyteus/tools/mcp/server_instance_manager.py +8 -1
  292. autobyteus/tools/mcp/types.py +61 -0
  293. autobyteus/tools/multimedia/audio_tools.py +70 -17
  294. autobyteus/tools/multimedia/download_media_tool.py +18 -4
  295. autobyteus/tools/multimedia/image_tools.py +246 -62
  296. autobyteus/tools/operation_executor/journal_manager.py +107 -0
  297. autobyteus/tools/operation_executor/operation_event_buffer.py +57 -0
  298. autobyteus/tools/operation_executor/operation_event_producer.py +29 -0
  299. autobyteus/tools/operation_executor/operation_executor.py +58 -0
  300. autobyteus/tools/registry/tool_definition.py +43 -2
  301. autobyteus/tools/skill/load_skill.py +50 -0
  302. autobyteus/tools/terminal/__init__.py +45 -0
  303. autobyteus/tools/terminal/ansi_utils.py +32 -0
  304. autobyteus/tools/terminal/background_process_manager.py +233 -0
  305. autobyteus/tools/terminal/output_buffer.py +105 -0
  306. autobyteus/tools/terminal/prompt_detector.py +63 -0
  307. autobyteus/tools/terminal/pty_session.py +241 -0
  308. autobyteus/tools/terminal/session_factory.py +20 -0
  309. autobyteus/tools/terminal/terminal_session_manager.py +226 -0
  310. autobyteus/tools/terminal/tools/__init__.py +13 -0
  311. autobyteus/tools/terminal/tools/get_process_output.py +81 -0
  312. autobyteus/tools/terminal/tools/run_bash.py +109 -0
  313. autobyteus/tools/terminal/tools/start_background_process.py +104 -0
  314. autobyteus/tools/terminal/tools/stop_background_process.py +67 -0
  315. autobyteus/tools/terminal/types.py +54 -0
  316. autobyteus/tools/terminal/wsl_tmux_session.py +221 -0
  317. autobyteus/tools/terminal/wsl_utils.py +156 -0
  318. autobyteus/tools/transaction_management/backup_handler.py +48 -0
  319. autobyteus/tools/transaction_management/operation_lifecycle_manager.py +62 -0
  320. autobyteus/tools/usage/__init__.py +1 -2
  321. autobyteus/tools/usage/formatters/__init__.py +17 -1
  322. autobyteus/tools/usage/formatters/base_formatter.py +8 -0
  323. autobyteus/tools/usage/formatters/default_xml_schema_formatter.py +2 -2
  324. autobyteus/tools/usage/formatters/mistral_json_schema_formatter.py +18 -0
  325. autobyteus/tools/usage/formatters/patch_file_xml_example_formatter.py +64 -0
  326. autobyteus/tools/usage/formatters/patch_file_xml_schema_formatter.py +31 -0
  327. autobyteus/tools/usage/formatters/run_bash_xml_example_formatter.py +32 -0
  328. autobyteus/tools/usage/formatters/run_bash_xml_schema_formatter.py +36 -0
  329. autobyteus/tools/usage/formatters/write_file_xml_example_formatter.py +53 -0
  330. autobyteus/tools/usage/formatters/write_file_xml_schema_formatter.py +31 -0
  331. autobyteus/tools/usage/providers/tool_manifest_provider.py +10 -10
  332. autobyteus/tools/usage/registries/__init__.py +1 -3
  333. autobyteus/tools/usage/registries/tool_formatting_registry.py +115 -8
  334. autobyteus/tools/usage/tool_schema_provider.py +51 -0
  335. autobyteus/tools/web/__init__.py +4 -0
  336. autobyteus/tools/web/read_url_tool.py +80 -0
  337. autobyteus/utils/diff_utils.py +271 -0
  338. autobyteus/utils/download_utils.py +109 -0
  339. autobyteus/utils/file_utils.py +57 -2
  340. autobyteus/utils/gemini_helper.py +64 -0
  341. autobyteus/utils/gemini_model_mapping.py +71 -0
  342. autobyteus/utils/llm_output_formatter.py +75 -0
  343. autobyteus/utils/tool_call_format.py +36 -0
  344. autobyteus/workflow/agentic_workflow.py +3 -3
  345. autobyteus/workflow/bootstrap_steps/agent_tool_injection_step.py +2 -2
  346. autobyteus/workflow/bootstrap_steps/base_workflow_bootstrap_step.py +2 -2
  347. autobyteus/workflow/bootstrap_steps/coordinator_initialization_step.py +2 -2
  348. autobyteus/workflow/bootstrap_steps/coordinator_prompt_preparation_step.py +3 -9
  349. autobyteus/workflow/bootstrap_steps/workflow_bootstrapper.py +6 -6
  350. autobyteus/workflow/bootstrap_steps/workflow_runtime_queue_initialization_step.py +2 -2
  351. autobyteus/workflow/context/workflow_context.py +3 -3
  352. autobyteus/workflow/context/workflow_runtime_state.py +5 -5
  353. autobyteus/workflow/events/workflow_event_dispatcher.py +5 -5
  354. autobyteus/workflow/handlers/lifecycle_workflow_event_handler.py +3 -3
  355. autobyteus/workflow/handlers/process_user_message_event_handler.py +5 -5
  356. autobyteus/workflow/handlers/tool_approval_workflow_event_handler.py +2 -2
  357. autobyteus/workflow/runtime/workflow_runtime.py +8 -8
  358. autobyteus/workflow/runtime/workflow_worker.py +3 -3
  359. autobyteus/workflow/status/__init__.py +11 -0
  360. autobyteus/workflow/status/workflow_status.py +19 -0
  361. autobyteus/workflow/status/workflow_status_manager.py +48 -0
  362. autobyteus/workflow/streaming/__init__.py +2 -2
  363. autobyteus/workflow/streaming/workflow_event_notifier.py +7 -7
  364. autobyteus/workflow/streaming/workflow_stream_event_payloads.py +4 -4
  365. autobyteus/workflow/streaming/workflow_stream_events.py +3 -3
  366. autobyteus/workflow/utils/wait_for_idle.py +4 -4
  367. autobyteus-1.3.0.dist-info/METADATA +293 -0
  368. autobyteus-1.3.0.dist-info/RECORD +606 -0
  369. {autobyteus-1.2.1.dist-info → autobyteus-1.3.0.dist-info}/WHEEL +1 -1
  370. {autobyteus-1.2.1.dist-info → autobyteus-1.3.0.dist-info}/top_level.txt +0 -1
  371. autobyteus/agent/bootstrap_steps/agent_runtime_queue_initialization_step.py +0 -57
  372. autobyteus/agent/hooks/__init__.py +0 -16
  373. autobyteus/agent/hooks/base_phase_hook.py +0 -78
  374. autobyteus/agent/hooks/hook_definition.py +0 -36
  375. autobyteus/agent/hooks/hook_meta.py +0 -37
  376. autobyteus/agent/hooks/hook_registry.py +0 -106
  377. autobyteus/agent/llm_response_processor/provider_aware_tool_usage_processor.py +0 -103
  378. autobyteus/agent/phases/__init__.py +0 -18
  379. autobyteus/agent/phases/discover.py +0 -53
  380. autobyteus/agent/phases/manager.py +0 -265
  381. autobyteus/agent/phases/transition_decorator.py +0 -40
  382. autobyteus/agent/phases/transition_info.py +0 -33
  383. autobyteus/agent/remote_agent.py +0 -244
  384. autobyteus/agent/workspace/workspace_definition.py +0 -36
  385. autobyteus/agent/workspace/workspace_meta.py +0 -37
  386. autobyteus/agent/workspace/workspace_registry.py +0 -72
  387. autobyteus/agent_team/bootstrap_steps/agent_team_runtime_queue_initialization_step.py +0 -25
  388. autobyteus/agent_team/bootstrap_steps/coordinator_prompt_preparation_step.py +0 -85
  389. autobyteus/agent_team/phases/__init__.py +0 -11
  390. autobyteus/agent_team/phases/agent_team_operational_phase.py +0 -19
  391. autobyteus/agent_team/phases/agent_team_phase_manager.py +0 -48
  392. autobyteus/llm/api/bedrock_llm.py +0 -92
  393. autobyteus/llm/api/groq_llm.py +0 -94
  394. autobyteus/llm/api/nvidia_llm.py +0 -108
  395. autobyteus/llm/utils/token_pricing_config.py +0 -87
  396. autobyteus/rpc/__init__.py +0 -73
  397. autobyteus/rpc/client/__init__.py +0 -17
  398. autobyteus/rpc/client/abstract_client_connection.py +0 -124
  399. autobyteus/rpc/client/client_connection_manager.py +0 -153
  400. autobyteus/rpc/client/sse_client_connection.py +0 -306
  401. autobyteus/rpc/client/stdio_client_connection.py +0 -280
  402. autobyteus/rpc/config/__init__.py +0 -13
  403. autobyteus/rpc/config/agent_server_config.py +0 -153
  404. autobyteus/rpc/config/agent_server_registry.py +0 -152
  405. autobyteus/rpc/hosting.py +0 -244
  406. autobyteus/rpc/protocol.py +0 -244
  407. autobyteus/rpc/server/__init__.py +0 -20
  408. autobyteus/rpc/server/agent_server_endpoint.py +0 -181
  409. autobyteus/rpc/server/base_method_handler.py +0 -40
  410. autobyteus/rpc/server/method_handlers.py +0 -259
  411. autobyteus/rpc/server/sse_server_handler.py +0 -182
  412. autobyteus/rpc/server/stdio_server_handler.py +0 -151
  413. autobyteus/rpc/server_main.py +0 -198
  414. autobyteus/rpc/transport_type.py +0 -13
  415. autobyteus/tools/bash/__init__.py +0 -2
  416. autobyteus/tools/bash/bash_executor.py +0 -100
  417. autobyteus/tools/browser/__init__.py +0 -2
  418. autobyteus/tools/browser/session_aware/browser_session_aware_navigate_to.py +0 -75
  419. autobyteus/tools/browser/session_aware/browser_session_aware_tool.py +0 -30
  420. autobyteus/tools/browser/session_aware/browser_session_aware_web_element_trigger.py +0 -154
  421. autobyteus/tools/browser/session_aware/browser_session_aware_webpage_reader.py +0 -89
  422. autobyteus/tools/browser/session_aware/browser_session_aware_webpage_screenshot_taker.py +0 -107
  423. autobyteus/tools/browser/session_aware/factory/browser_session_aware_web_element_trigger_factory.py +0 -14
  424. autobyteus/tools/browser/session_aware/factory/browser_session_aware_webpage_reader_factory.py +0 -26
  425. autobyteus/tools/browser/session_aware/factory/browser_session_aware_webpage_screenshot_taker_factory.py +0 -14
  426. autobyteus/tools/browser/session_aware/shared_browser_session.py +0 -11
  427. autobyteus/tools/browser/session_aware/shared_browser_session_manager.py +0 -25
  428. autobyteus/tools/browser/session_aware/web_element_action.py +0 -20
  429. autobyteus/tools/browser/standalone/__init__.py +0 -6
  430. autobyteus/tools/browser/standalone/factory/__init__.py +0 -0
  431. autobyteus/tools/browser/standalone/factory/webpage_reader_factory.py +0 -25
  432. autobyteus/tools/browser/standalone/factory/webpage_screenshot_taker_factory.py +0 -14
  433. autobyteus/tools/browser/standalone/navigate_to.py +0 -84
  434. autobyteus/tools/browser/standalone/web_page_pdf_generator.py +0 -101
  435. autobyteus/tools/browser/standalone/webpage_image_downloader.py +0 -169
  436. autobyteus/tools/browser/standalone/webpage_reader.py +0 -105
  437. autobyteus/tools/browser/standalone/webpage_screenshot_taker.py +0 -105
  438. autobyteus/tools/file/edit_file.py +0 -200
  439. autobyteus/tools/file/list_directory.py +0 -168
  440. autobyteus/tools/file/search_files.py +0 -188
  441. autobyteus/tools/timer.py +0 -175
  442. autobyteus/tools/usage/parsers/__init__.py +0 -22
  443. autobyteus/tools/usage/parsers/_json_extractor.py +0 -99
  444. autobyteus/tools/usage/parsers/_string_decoders.py +0 -18
  445. autobyteus/tools/usage/parsers/anthropic_xml_tool_usage_parser.py +0 -10
  446. autobyteus/tools/usage/parsers/base_parser.py +0 -41
  447. autobyteus/tools/usage/parsers/default_json_tool_usage_parser.py +0 -83
  448. autobyteus/tools/usage/parsers/default_xml_tool_usage_parser.py +0 -316
  449. autobyteus/tools/usage/parsers/exceptions.py +0 -13
  450. autobyteus/tools/usage/parsers/gemini_json_tool_usage_parser.py +0 -77
  451. autobyteus/tools/usage/parsers/openai_json_tool_usage_parser.py +0 -149
  452. autobyteus/tools/usage/parsers/provider_aware_tool_usage_parser.py +0 -59
  453. autobyteus/tools/usage/registries/tool_usage_parser_registry.py +0 -62
  454. autobyteus/workflow/phases/__init__.py +0 -11
  455. autobyteus/workflow/phases/workflow_operational_phase.py +0 -19
  456. autobyteus/workflow/phases/workflow_phase_manager.py +0 -48
  457. autobyteus-1.2.1.dist-info/METADATA +0 -205
  458. autobyteus-1.2.1.dist-info/RECORD +0 -511
  459. examples/__init__.py +0 -1
  460. examples/agent_team/__init__.py +0 -1
  461. examples/discover_phase_transitions.py +0 -104
  462. examples/run_agentic_software_engineer.py +0 -239
  463. examples/run_browser_agent.py +0 -262
  464. examples/run_google_slides_agent.py +0 -287
  465. examples/run_mcp_browser_client.py +0 -174
  466. examples/run_mcp_google_slides_client.py +0 -270
  467. examples/run_mcp_list_tools.py +0 -189
  468. examples/run_poem_writer.py +0 -284
  469. examples/run_sqlite_agent.py +0 -295
  470. /autobyteus/{tools/browser/session_aware → skills}/__init__.py +0 -0
  471. /autobyteus/tools/{browser/session_aware/factory → skill}/__init__.py +0 -0
  472. {autobyteus-1.2.1.dist-info → autobyteus-1.3.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,13 +1,15 @@
1
1
  # file: autobyteus/autobyteus/agent/context/agent_runtime_state.py
2
2
  import logging
3
- from typing import List, Dict, Any, Optional, TYPE_CHECKING
3
+ from typing import Dict, Any, Optional, TYPE_CHECKING
4
4
 
5
5
  from autobyteus.agent.events.agent_input_event_queue_manager import AgentInputEventQueueManager
6
+ from autobyteus.agent.events.event_store import AgentEventStore
7
+ from autobyteus.agent.status.status_deriver import AgentStatusDeriver
6
8
  # AgentOutputDataManager is no longer part of AgentRuntimeState
7
9
  # from autobyteus.agent.events.agent_output_data_manager import AgentOutputDataManager
8
10
 
9
11
  from autobyteus.llm.base_llm import BaseLLM
10
- from autobyteus.agent.phases import AgentOperationalPhase
12
+ from autobyteus.agent.status.status_enum import AgentStatus
11
13
  from autobyteus.agent.workspace.base_workspace import BaseAgentWorkspace
12
14
  from autobyteus.agent.tool_invocation import ToolInvocation
13
15
  # LLMConfig is no longer needed here
@@ -15,22 +17,23 @@ from autobyteus.agent.tool_invocation import ToolInvocation
15
17
  from autobyteus.task_management.todo_list import ToDoList
16
18
 
17
19
  if TYPE_CHECKING:
18
- from autobyteus.agent.phases import AgentPhaseManager
20
+ from autobyteus.agent.status.manager import AgentStatusManager
19
21
  from autobyteus.tools.base_tool import BaseTool
20
22
  from autobyteus.agent.tool_invocation import ToolInvocationTurn
23
+ from autobyteus.memory.memory_manager import MemoryManager
24
+ from autobyteus.memory.restore.working_context_snapshot_bootstrapper import WorkingContextSnapshotBootstrapOptions
21
25
 
22
26
  logger = logging.getLogger(__name__)
23
27
 
24
28
  class AgentRuntimeState:
25
29
  """
26
30
  Encapsulates the dynamic, stateful data of an agent instance.
27
- Input event queues are initialized by the AgentWorker via a bootstrap step.
31
+ Input event queues are initialized by the AgentWorker during minimal runtime init.
28
32
  Output data is now handled by emitting events via AgentExternalEventNotifier.
29
33
  """
30
34
  def __init__(self,
31
35
  agent_id: str,
32
36
  workspace: Optional[BaseAgentWorkspace] = None,
33
- conversation_history: Optional[List[Dict[str, Any]]] = None,
34
37
  custom_data: Optional[Dict[str, Any]] = None):
35
38
  if not agent_id or not isinstance(agent_id, str):
36
39
  raise ValueError("AgentRuntimeState requires a non-empty string 'agent_id'.")
@@ -38,15 +41,16 @@ class AgentRuntimeState:
38
41
  raise TypeError(f"AgentRuntimeState 'workspace' must be a BaseAgentWorkspace or None. Got {type(workspace)}")
39
42
 
40
43
  self.agent_id: str = agent_id
41
- self.current_phase: AgentOperationalPhase = AgentOperationalPhase.UNINITIALIZED
44
+ self.current_status: AgentStatus = AgentStatus.UNINITIALIZED
42
45
  self.llm_instance: Optional[BaseLLM] = None
43
46
  self.tool_instances: Optional[Dict[str, 'BaseTool']] = None
44
47
 
45
48
  self.input_event_queues: Optional[AgentInputEventQueueManager] = None
49
+ self.event_store: Optional[AgentEventStore] = None
50
+ self.status_deriver: Optional[AgentStatusDeriver] = None
46
51
  # REMOVED: self.output_data_queues attribute
47
52
 
48
53
  self.workspace: Optional[BaseAgentWorkspace] = workspace
49
- self.conversation_history: List[Dict[str, Any]] = conversation_history or []
50
54
  self.pending_tool_approvals: Dict[str, ToolInvocation] = {}
51
55
  self.custom_data: Dict[str, Any] = custom_data or {}
52
56
 
@@ -55,20 +59,18 @@ class AgentRuntimeState:
55
59
 
56
60
  # NEW: State for the agent's personal ToDoList
57
61
  self.todo_list: Optional[ToDoList] = None
62
+
63
+ # NEW: Memory manager and active turn tracking
64
+ self.memory_manager: Optional["MemoryManager"] = None
65
+ self.active_turn_id: Optional[str] = None
66
+ self.restore_options: Optional["WorkingContextSnapshotBootstrapOptions"] = None
58
67
 
59
68
  self.processed_system_prompt: Optional[str] = None
60
69
  # self.final_llm_config_for_creation removed
61
70
 
62
- self.phase_manager_ref: Optional['AgentPhaseManager'] = None
71
+ self.status_manager_ref: Optional['AgentStatusManager'] = None
63
72
 
64
- logger.info(f"AgentRuntimeState initialized for agent_id '{self.agent_id}'. Initial phase: {self.current_phase.value}. Workspace linked. InputQueues pending initialization. Output data via notifier.")
65
-
66
- def add_message_to_history(self, message: Dict[str, Any]) -> None:
67
- if not isinstance(message, dict) or "role" not in message: # pragma: no cover
68
- logger.warning(f"Attempted to add malformed message to history for agent '{self.agent_id}': {message}")
69
- return
70
- self.conversation_history.append(message)
71
- logger.debug(f"Message added to history for agent '{self.agent_id}': role={message['role']}")
73
+ logger.info(f"AgentRuntimeState initialized for agent_id '{self.agent_id}'. Initial status: {self.current_status.value}. Workspace linked. InputQueues pending initialization. Output data via notifier.")
72
74
 
73
75
  def store_pending_tool_invocation(self, invocation: ToolInvocation) -> None:
74
76
  if not isinstance(invocation, ToolInvocation) or not invocation.id: # pragma: no cover
@@ -86,14 +88,14 @@ class AgentRuntimeState:
86
88
  return invocation
87
89
 
88
90
  def __repr__(self) -> str:
89
- phase_repr = self.current_phase.value
91
+ # status_repr removed or renamed
90
92
  llm_status = "Initialized" if self.llm_instance else "Not Initialized"
91
93
  tools_status = f"{len(self.tool_instances)} Initialized" if self.tool_instances is not None else "Not Initialized"
92
94
  input_queues_status = "Initialized" if self.input_event_queues else "Not Initialized"
93
95
  # REMOVED output_queues_status from repr
94
96
  active_turn_status = "Active" if self.active_multi_tool_call_turn else "Inactive"
95
- return (f"AgentRuntimeState(agent_id='{self.agent_id}', current_phase='{phase_repr}', "
97
+ return (f"AgentRuntimeState(agent_id='{self.agent_id}', current_status='{self.current_status.value}', "
96
98
  f"llm_status='{llm_status}', tools_status='{tools_status}', "
97
99
  f"input_queues_status='{input_queues_status}', "
98
- f"pending_approvals={len(self.pending_tool_approvals)}, history_len={len(self.conversation_history)}, "
100
+ f"pending_approvals={len(self.pending_tool_approvals)}, "
99
101
  f"multi_tool_call_turn='{active_turn_status}')")
@@ -5,18 +5,25 @@ Also includes the WorkerEventDispatcher for routing events within an agent's wor
5
5
  """
6
6
  from .agent_input_event_queue_manager import AgentInputEventQueueManager
7
7
  from .worker_event_dispatcher import WorkerEventDispatcher
8
+ from .event_store import AgentEventStore, EventEnvelope
8
9
 
9
10
  from .agent_events import (
10
11
  BaseEvent,
11
12
  # Categorical Base Events
12
13
  LifecycleEvent,
13
14
  AgentProcessingEvent,
14
- # Agent Phase-Specific Base Events
15
+ # Agent Status-Specific Base Events
15
16
  AgentOperationalEvent,
16
17
  # Specific Lifecycle Events
17
18
  AgentReadyEvent,
18
19
  AgentStoppedEvent,
19
20
  AgentErrorEvent,
21
+ AgentIdleEvent,
22
+ ShutdownRequestedEvent,
23
+ BootstrapStartedEvent,
24
+ BootstrapStepRequestedEvent,
25
+ BootstrapStepCompletedEvent,
26
+ BootstrapCompletedEvent,
20
27
  # Regular Agent Processing Events
21
28
  UserMessageReceivedEvent,
22
29
  InterAgentMessageReceivedEvent,
@@ -33,6 +40,8 @@ from .agent_events import (
33
40
  __all__ = [
34
41
  "AgentInputEventQueueManager",
35
42
  "WorkerEventDispatcher",
43
+ "AgentEventStore",
44
+ "EventEnvelope",
36
45
  "BaseEvent",
37
46
  "LifecycleEvent",
38
47
  "AgentProcessingEvent",
@@ -40,6 +49,12 @@ __all__ = [
40
49
  "AgentReadyEvent",
41
50
  "AgentStoppedEvent",
42
51
  "AgentErrorEvent",
52
+ "AgentIdleEvent",
53
+ "ShutdownRequestedEvent",
54
+ "BootstrapStartedEvent",
55
+ "BootstrapStepRequestedEvent",
56
+ "BootstrapStepCompletedEvent",
57
+ "BootstrapCompletedEvent",
43
58
  "UserMessageReceivedEvent",
44
59
  "InterAgentMessageReceivedEvent",
45
60
  "LLMUserMessageReadyEvent",
@@ -1,10 +1,12 @@
1
+
1
2
  # file: autobyteus/autobyteus/agent/events/agent_events.py
2
3
  from dataclasses import dataclass, field
3
4
  from typing import Any, Dict, Optional
4
5
 
5
6
  from autobyteus.agent.message.agent_input_user_message import AgentInputUserMessage
6
- from autobyteus.agent.tool_invocation import ToolInvocation
7
7
  from autobyteus.agent.message.inter_agent_message import InterAgentMessage
8
+ from autobyteus.agent.status.status_enum import AgentStatus
9
+ from autobyteus.agent.tool_invocation import ToolInvocation
8
10
  from autobyteus.llm.user_message import LLMUserMessage
9
11
  from autobyteus.llm.utils.response_types import CompleteResponse
10
12
 
@@ -25,10 +27,10 @@ class AgentProcessingEvent(BaseEvent):
25
27
  """Base class for events related to the agent's internal data processing and task execution logic."""
26
28
 
27
29
 
28
- # --- Agent Operational Phase Events ---
30
+ # --- Agent Operational Status Events ---
29
31
  @dataclass
30
32
  class AgentOperationalEvent(AgentProcessingEvent):
31
- """Base class for events that occur during the agent's active operational phase (post-preparation)."""
33
+ """Base class for events that occur during the agent's active operational status (post-preparation)."""
32
34
  pass
33
35
 
34
36
 
@@ -50,6 +52,42 @@ class AgentErrorEvent(LifecycleEvent):
50
52
  error_message: str
51
53
  exception_details: Optional[str] = None
52
54
 
55
+ @dataclass
56
+ class AgentIdleEvent(LifecycleEvent):
57
+ """Event indicating the agent has completed a processing cycle and is idle."""
58
+ pass
59
+
60
+ @dataclass
61
+ class ShutdownRequestedEvent(LifecycleEvent):
62
+ """Event indicating a shutdown has been requested."""
63
+ pass
64
+
65
+ # --- Bootstrap Lifecycle Events ---
66
+
67
+ @dataclass
68
+ class BootstrapStartedEvent(LifecycleEvent):
69
+ """Event indicating the bootstrap orchestration has begun."""
70
+ pass
71
+
72
+ @dataclass
73
+ class BootstrapStepRequestedEvent(LifecycleEvent):
74
+ """Event requesting execution of a specific bootstrap step."""
75
+ step_index: int
76
+
77
+ @dataclass
78
+ class BootstrapStepCompletedEvent(LifecycleEvent):
79
+ """Event indicating a bootstrap step has completed."""
80
+ step_index: int
81
+ step_name: str
82
+ success: bool
83
+ error_message: Optional[str] = None
84
+
85
+ @dataclass
86
+ class BootstrapCompletedEvent(LifecycleEvent):
87
+ """Event indicating the bootstrap sequence has completed."""
88
+ success: bool
89
+ error_message: Optional[str] = None
90
+
53
91
 
54
92
  # --- Regular Agent Processing Events (now Operational) ---
55
93
 
@@ -85,7 +123,9 @@ class ToolResultEvent(AgentOperationalEvent):
85
123
  tool_name: str
86
124
  result: Any
87
125
  tool_invocation_id: Optional[str] = None
126
+ turn_id: Optional[str] = None
88
127
  error: Optional[str] = None
128
+ tool_args: Optional[Dict[str, Any]] = None # Carries original arguments for internal processing (e.g. artifacts)
89
129
 
90
130
  @dataclass
91
131
  class ToolExecutionApprovalEvent(AgentOperationalEvent):
@@ -2,6 +2,7 @@
2
2
  import asyncio
3
3
  import logging
4
4
  from typing import Any, AsyncIterator, Union, Tuple, Optional, List, TYPE_CHECKING, Dict, Set
5
+ from collections import deque
5
6
 
6
7
  # Import specific event types for queue annotations where possible
7
8
  if TYPE_CHECKING:
@@ -20,7 +21,9 @@ logger = logging.getLogger(__name__)
20
21
  class AgentInputEventQueueManager:
21
22
  """
22
23
  Manages asyncio.Queue instances for events consumed by the AgentRuntime's
23
- main event loop. This class focuses solely on queues for internal agent processing.
24
+ main event loop. Uses per-queue ready buffers plus a deterministic priority
25
+ order to avoid requeue-induced reordering when multiple queues are ready at
26
+ the same time.
24
27
  """
25
28
  def __init__(self, queue_size: int = 0):
26
29
  self.user_message_input_queue: asyncio.Queue['UserMessageReceivedEvent'] = asyncio.Queue(maxsize=queue_size)
@@ -38,6 +41,21 @@ class AgentInputEventQueueManager:
38
41
  ("tool_execution_approval_queue", self.tool_execution_approval_queue),
39
42
  ("internal_system_event_queue", self.internal_system_event_queue),
40
43
  ]
44
+
45
+ # Buffer of ready items per queue to avoid requeue-induced reordering.
46
+ self._ready_buffers: Dict[str, deque[Any]] = {
47
+ name: deque() for name, _ in self._input_queues
48
+ }
49
+
50
+ # Deterministic priority order when multiple queues are ready.
51
+ self._queue_priority: List[str] = [
52
+ "user_message_input_queue",
53
+ "inter_agent_message_input_queue",
54
+ "tool_invocation_request_queue",
55
+ "tool_result_input_queue",
56
+ "tool_execution_approval_queue",
57
+ "internal_system_event_queue",
58
+ ]
41
59
  logger.info("AgentInputEventQueueManager initialized.")
42
60
 
43
61
  async def enqueue_user_message(self, event: 'UserMessageReceivedEvent') -> None:
@@ -65,7 +83,27 @@ class AgentInputEventQueueManager:
65
83
  logger.debug(f"Enqueued internal system event: {type(event).__name__}")
66
84
 
67
85
  async def get_next_input_event(self) -> Optional[Tuple[str, 'BaseEvent']]: # type: ignore[type-var]
68
- # Logger messages will be updated in subsequent steps if needed
86
+ """
87
+ Returns the next available event along with its originating queue name.
88
+
89
+ Algorithm:
90
+ 1. Serve any buffered items first (buffers keep FIFO per queue).
91
+ 2. If none buffered, await one get() per queue with FIRST_COMPLETED,
92
+ buffer all completed results (no requeue to the tail), cancel the rest.
93
+ 3. Return the highest-priority buffered item.
94
+
95
+ This preserves intra-queue order and avoids the previous bug where
96
+ re-inserting a ready item to the queue tail could invert tool call order.
97
+ """
98
+ # 1) Serve any buffered items first (deterministic priority).
99
+ for qname in self._queue_priority:
100
+ buf = self._ready_buffers.get(qname)
101
+ if buf and buf:
102
+ event = buf.popleft()
103
+ logger.debug(f"get_next_input_event: Returning buffered event from {qname}: {type(event).__name__}")
104
+ return (qname, event)
105
+
106
+ # 2) No buffered items; proceed to gather one from live queues.
69
107
  logger.debug(f"get_next_input_event: Checking queue sizes before creating tasks...")
70
108
  for name, q_obj in self._input_queues:
71
109
  if q_obj is not None: # pragma: no cover
@@ -82,9 +120,6 @@ class AgentInputEventQueueManager:
82
120
 
83
121
  logger.debug(f"get_next_input_event: Created {len(created_tasks)} tasks for queues: {[t.get_name() for t in created_tasks]}. Awaiting asyncio.wait...")
84
122
 
85
- event_tuple: Optional[Tuple[str, 'BaseEvent']] = None # type: ignore[type-var]
86
- done_tasks_from_wait: Set[asyncio.Task] = set()
87
-
88
123
  try:
89
124
  done_tasks_from_wait, pending_tasks_from_wait = await asyncio.wait(
90
125
  created_tasks, return_when=asyncio.FIRST_COMPLETED
@@ -92,37 +127,27 @@ class AgentInputEventQueueManager:
92
127
 
93
128
  logger.debug(f"get_next_input_event: asyncio.wait returned. Done tasks: {len(done_tasks_from_wait)}, Pending tasks: {len(pending_tasks_from_wait)}.")
94
129
 
95
- if done_tasks_from_wait: # pragma: no branch
96
- for i, task_in_done in enumerate(done_tasks_from_wait): # pragma: no cover
97
- logger.debug(f"get_next_input_event: Processing done task #{i+1} (name: {task_in_done.get_name()})")
98
-
130
+ # Collect all done results into buffers without requeueing
99
131
  for task in done_tasks_from_wait:
100
132
  queue_name = task.get_name()
101
133
  try:
102
- event_result: Any = task.result()
134
+ event_result: Any = task.result()
103
135
  logger.debug(f"get_next_input_event: Task for queue '{queue_name}' completed. Result type: {type(event_result).__name__}, Result: {str(event_result)[:100]}")
104
136
 
105
- # Avoid circular import for BaseEvent, assuming it's correctly imported in TYPE_CHECKING context
106
- from autobyteus.agent.events.agent_events import BaseEvent as AgentBaseEvent
137
+ from autobyteus.agent.events.agent_events import BaseEvent as AgentBaseEvent
107
138
  if isinstance(event_result, AgentBaseEvent):
108
- event: 'BaseEvent' = event_result # type: ignore[type-var]
109
- if event_tuple is None:
110
- event_tuple = (queue_name, event)
111
- logger.debug(f"get_next_input_event: Dequeued event from {queue_name}: {type(event).__name__}")
112
- else: # pragma: no cover
113
- original_queue = next((q for n, q in self._input_queues if n == queue_name), None)
114
- if original_queue:
115
- original_queue.put_nowait(event)
116
- logger.warning(f"get_next_input_event: Re-queued event from {queue_name} (type {type(event).__name__}) as another event was processed first in the same wait cycle.")
139
+ self._ready_buffers[queue_name].append(event_result)
140
+ logger.debug(f"get_next_input_event: Buffered event from {queue_name}: {type(event_result).__name__}")
117
141
  else: # pragma: no cover
118
142
  logger.error(f"get_next_input_event: Dequeued item from {queue_name} is not a BaseEvent subclass: {type(event_result)}. Event: {event_result!r}")
119
143
 
120
144
  except asyncio.CancelledError: # pragma: no cover
121
- logger.info(f"get_next_input_event: Task for queue {queue_name} (from done set) was cancelled during result processing.")
145
+ logger.info(f"get_next_input_event: Task for queue {queue_name} (from done set) was cancelled during result processing.")
122
146
  except Exception as e: # pragma: no cover
123
147
  logger.error(f"get_next_input_event: Error processing result from task for queue {queue_name} (from done set): {e}", exc_info=True)
124
148
 
125
- if pending_tasks_from_wait: # pragma: no branch
149
+ # Cancel pending tasks
150
+ if pending_tasks_from_wait:
126
151
  logger.debug(f"get_next_input_event: Cancelling {len(pending_tasks_from_wait)} pending tasks from asyncio.wait.")
127
152
  for task_in_pending in pending_tasks_from_wait: # pragma: no cover
128
153
  if not task_in_pending.done():
@@ -160,9 +185,37 @@ class AgentInputEventQueueManager:
160
185
 
161
186
  logger.debug(f"get_next_input_event: Finished finally block task cleanup.")
162
187
 
163
- if event_tuple:
164
- logger.debug(f"get_next_input_event: Returning event_tuple: {type(event_tuple[1]).__name__ if event_tuple else 'None'}")
165
- return event_tuple
188
+ # After buffering, return the highest-priority ready item (if any)
189
+ for qname in self._queue_priority:
190
+ buf = self._ready_buffers.get(qname)
191
+ if buf and buf:
192
+ event = buf.popleft()
193
+ logger.debug(f"get_next_input_event: Returning buffered event from {qname}: {type(event).__name__}")
194
+ return (qname, event)
195
+
196
+ logger.debug("get_next_input_event: No events available after buffering.")
197
+ return None
198
+
199
+ async def get_next_internal_event(self) -> Optional[Tuple[str, 'BaseEvent']]: # type: ignore[type-var]
200
+ """
201
+ Returns the next available internal system event only.
202
+ Intended for bootstrapping phases where non-internal queues should be gated.
203
+ """
204
+ qname = "internal_system_event_queue"
205
+ buf = self._ready_buffers.get(qname)
206
+ if buf and buf:
207
+ event = buf.popleft()
208
+ logger.debug(f"get_next_internal_event: Returning buffered event from {qname}: {type(event).__name__}")
209
+ return (qname, event)
210
+
211
+ event_result: Any = await self.internal_system_event_queue.get()
212
+ from autobyteus.agent.events.agent_events import BaseEvent as AgentBaseEvent
213
+ if isinstance(event_result, AgentBaseEvent):
214
+ logger.debug(f"get_next_internal_event: Dequeued event from {qname}: {type(event_result).__name__}")
215
+ return (qname, event_result)
216
+
217
+ logger.error(f"get_next_internal_event: Dequeued item is not a BaseEvent subclass: {type(event_result)}. Event: {event_result!r}")
218
+ return None
166
219
 
167
220
  def log_remaining_items_at_shutdown(self): # pragma: no cover
168
221
  """Logs remaining items in input queues, typically called during shutdown."""
@@ -0,0 +1,57 @@
1
+ # file: autobyteus/autobyteus/agent/events/event_store.py
2
+ from __future__ import annotations
3
+
4
+ import logging
5
+ import time
6
+ import uuid
7
+ from dataclasses import dataclass
8
+ from typing import List, Optional
9
+
10
+ from autobyteus.agent.events.agent_events import BaseEvent
11
+
12
+ logger = logging.getLogger(__name__)
13
+
14
+
15
+ @dataclass(frozen=True)
16
+ class EventEnvelope:
17
+ event_id: str
18
+ event_type: str
19
+ timestamp: float
20
+ agent_id: str
21
+ event: BaseEvent
22
+ correlation_id: Optional[str] = None
23
+ caused_by_event_id: Optional[str] = None
24
+ sequence: int = 0
25
+
26
+
27
+ class AgentEventStore:
28
+ """
29
+ Simple in-memory event store for agent events.
30
+ """
31
+ def __init__(self, agent_id: str):
32
+ self._agent_id = agent_id
33
+ self._events: List[EventEnvelope] = []
34
+ self._sequence: int = 0
35
+ logger.debug(f"AgentEventStore initialized for agent_id '{agent_id}'.")
36
+
37
+ def append(self,
38
+ event: BaseEvent,
39
+ correlation_id: Optional[str] = None,
40
+ caused_by_event_id: Optional[str] = None) -> EventEnvelope:
41
+ envelope = EventEnvelope(
42
+ event_id=str(uuid.uuid4()),
43
+ event_type=type(event).__name__,
44
+ timestamp=time.time(),
45
+ agent_id=self._agent_id,
46
+ event=event,
47
+ correlation_id=correlation_id,
48
+ caused_by_event_id=caused_by_event_id,
49
+ sequence=self._sequence,
50
+ )
51
+ self._sequence += 1
52
+ self._events.append(envelope)
53
+ logger.debug(f"Appended event '{envelope.event_type}' to store for agent '{self._agent_id}'.")
54
+ return envelope
55
+
56
+ def all_events(self) -> List[EventEnvelope]:
57
+ return list(self._events)
@@ -4,7 +4,7 @@ from typing import Optional, Dict, Any, TYPE_CHECKING, List
4
4
 
5
5
  from autobyteus.events.event_emitter import EventEmitter
6
6
  from autobyteus.events.event_types import EventType
7
- from autobyteus.agent.phases import AgentOperationalPhase
7
+ from autobyteus.agent.status.status_enum import AgentStatus
8
8
 
9
9
  if TYPE_CHECKING:
10
10
  from autobyteus.llm.utils.response_types import ChunkResponse, CompleteResponse
@@ -13,7 +13,7 @@ logger = logging.getLogger(__name__)
13
13
 
14
14
  class AgentExternalEventNotifier(EventEmitter):
15
15
  """
16
- Responsible for emitting external events related to agent phase transitions
16
+ Responsible for emitting external events related to agent status updates
17
17
  and data outputs.
18
18
  """
19
19
  def __init__(self, agent_id: str):
@@ -31,75 +31,73 @@ class AgentExternalEventNotifier(EventEmitter):
31
31
  f"AgentExternalEventNotifier (NotifierID: {self.object_id}, AgentID: {self.agent_id}) "
32
32
  f"emitted {event_type.name}. Kwarg keys for emit: {list(emit_kwargs.keys())}"
33
33
  )
34
- # Reduce log level for high-frequency events like streaming chunks
35
- if event_type == EventType.AGENT_DATA_ASSISTANT_CHUNK:
36
- logger.debug(log_message)
34
+ # Reduce log level for high-frequency events like streaming chunks/segments
35
+ if event_type in {EventType.AGENT_DATA_ASSISTANT_CHUNK, EventType.AGENT_DATA_SEGMENT_EVENT}:
36
+ summary = self._summarize_payload(event_type, payload_content)
37
+ if summary:
38
+ logger.debug(f"{log_message} | {summary}")
39
+ else:
40
+ logger.debug(log_message)
37
41
  else:
38
42
  logger.info(log_message)
39
43
 
40
-
41
- def _emit_phase_change(self,
42
- event_type: EventType,
43
- new_phase: AgentOperationalPhase,
44
- old_phase: Optional[AgentOperationalPhase] = None,
45
- additional_data: Optional[Dict[str, Any]] = None):
46
- phase_payload_dict = {
47
- "new_phase": new_phase.value,
48
- "old_phase": old_phase.value if old_phase else None,
44
+ def _summarize_payload(self, event_type: EventType, payload_content: Optional[Any]) -> Optional[str]:
45
+ """Return a compact, non-sensitive payload summary for debug logs."""
46
+ if payload_content is None:
47
+ return None
48
+
49
+ if event_type == EventType.AGENT_DATA_SEGMENT_EVENT and isinstance(payload_content, dict):
50
+ seg_type = payload_content.get("segment_type")
51
+ seg_id = payload_content.get("segment_id")
52
+ seg_event_type = payload_content.get("type")
53
+ payload = payload_content.get("payload") or {}
54
+ summary_parts = [f"segment_id={seg_id}", f"segment_type={seg_type}", f"event_type={seg_event_type}"]
55
+ if isinstance(payload, dict):
56
+ if "delta" in payload:
57
+ delta = payload.get("delta", "")
58
+ summary_parts.append(f"delta_len={len(str(delta))}")
59
+ if "metadata" in payload and isinstance(payload.get("metadata"), dict):
60
+ meta_keys = list(payload.get("metadata").keys())
61
+ if meta_keys:
62
+ summary_parts.append(f"metadata_keys={meta_keys}")
63
+ return " ".join(summary_parts)
64
+
65
+ if event_type == EventType.AGENT_DATA_ASSISTANT_CHUNK and hasattr(payload_content, "content"):
66
+ content = getattr(payload_content, "content", "") or ""
67
+ reasoning = getattr(payload_content, "reasoning", "") or ""
68
+ return f"content_len={len(str(content))} reasoning_len={len(str(reasoning))}"
69
+
70
+ return None
71
+
72
+
73
+ def _emit_status_update(self,
74
+ new_status: AgentStatus,
75
+ old_status: Optional[AgentStatus] = None,
76
+ additional_data: Optional[Dict[str, Any]] = None):
77
+ status_payload_dict = {
78
+ "new_status": new_status.value,
79
+ "old_status": old_status.value if old_status else None,
49
80
  }
50
81
  if additional_data:
51
- phase_payload_dict.update(additional_data)
52
- self._emit_event(event_type, payload_content=phase_payload_dict)
53
-
54
- def notify_phase_uninitialized_entered(self, old_phase: Optional[AgentOperationalPhase]):
55
- self._emit_phase_change(EventType.AGENT_PHASE_UNINITIALIZED_ENTERED, AgentOperationalPhase.UNINITIALIZED, old_phase)
56
-
57
- def notify_phase_bootstrapping_started(self, old_phase: Optional[AgentOperationalPhase]):
58
- self._emit_phase_change(EventType.AGENT_PHASE_BOOTSTRAPPING_STARTED, AgentOperationalPhase.BOOTSTRAPPING, old_phase)
59
-
60
- def notify_phase_idle_entered(self, old_phase: Optional[AgentOperationalPhase]):
61
- self._emit_phase_change(EventType.AGENT_PHASE_IDLE_ENTERED, AgentOperationalPhase.IDLE, old_phase)
62
-
63
- def notify_phase_processing_user_input_started(self, old_phase: Optional[AgentOperationalPhase], trigger_info: Optional[str] = None):
64
- data = {"trigger": trigger_info} if trigger_info else {}
65
- self._emit_phase_change(EventType.AGENT_PHASE_PROCESSING_USER_INPUT_STARTED, AgentOperationalPhase.PROCESSING_USER_INPUT, old_phase, additional_data=data)
66
- def notify_phase_awaiting_llm_response_started(self, old_phase: Optional[AgentOperationalPhase]):
67
- self._emit_phase_change(EventType.AGENT_PHASE_AWAITING_LLM_RESPONSE_STARTED, AgentOperationalPhase.AWAITING_LLM_RESPONSE, old_phase)
68
-
69
- def notify_phase_analyzing_llm_response_started(self, old_phase: Optional[AgentOperationalPhase]):
70
- self._emit_phase_change(EventType.AGENT_PHASE_ANALYZING_LLM_RESPONSE_STARTED, AgentOperationalPhase.ANALYZING_LLM_RESPONSE, old_phase)
71
-
72
- def notify_phase_awaiting_tool_approval_started(self, old_phase: Optional[AgentOperationalPhase]):
73
- self._emit_phase_change(EventType.AGENT_PHASE_AWAITING_TOOL_APPROVAL_STARTED, AgentOperationalPhase.AWAITING_TOOL_APPROVAL, old_phase)
74
-
75
- def notify_phase_tool_denied_started(self, old_phase: Optional[AgentOperationalPhase], tool_name: Optional[str], denial_for_tool: Optional[str]):
76
- data = {"tool_name": tool_name, "denial_for_tool": denial_for_tool}
77
- # Assuming EventType.AGENT_PHASE_TOOL_DENIED_STARTED exists in the main EventType enum
78
- self._emit_phase_change(EventType.AGENT_PHASE_TOOL_DENIED_STARTED, AgentOperationalPhase.TOOL_DENIED, old_phase, additional_data=data)
79
-
80
- def notify_phase_executing_tool_started(self, old_phase: Optional[AgentOperationalPhase], tool_name: str):
81
- data = {"tool_name": tool_name}
82
- self._emit_phase_change(EventType.AGENT_PHASE_EXECUTING_TOOL_STARTED, AgentOperationalPhase.EXECUTING_TOOL, old_phase, additional_data=data)
83
- def notify_phase_processing_tool_result_started(self, old_phase: Optional[AgentOperationalPhase], tool_name: str):
84
- data = {"tool_name": tool_name}
85
- self._emit_phase_change(EventType.AGENT_PHASE_PROCESSING_TOOL_RESULT_STARTED, AgentOperationalPhase.PROCESSING_TOOL_RESULT, old_phase, additional_data=data)
86
- def notify_phase_shutting_down_started(self, old_phase: Optional[AgentOperationalPhase]):
87
- self._emit_phase_change(EventType.AGENT_PHASE_SHUTTING_DOWN_STARTED, AgentOperationalPhase.SHUTTING_DOWN, old_phase)
88
- def notify_phase_shutdown_completed(self, old_phase: Optional[AgentOperationalPhase]):
89
- self._emit_phase_change(EventType.AGENT_PHASE_SHUTDOWN_COMPLETED, AgentOperationalPhase.SHUTDOWN_COMPLETE, old_phase)
90
- def notify_phase_error_entered(self, old_phase: Optional[AgentOperationalPhase], error_message: str, error_details: Optional[str] = None):
91
- data = {"error_message": error_message, "error_details": error_details}
92
- self._emit_phase_change(EventType.AGENT_PHASE_ERROR_ENTERED, AgentOperationalPhase.ERROR, old_phase, additional_data=data)
82
+ status_payload_dict.update(additional_data)
83
+ self._emit_event(EventType.AGENT_STATUS_UPDATED, payload_content=status_payload_dict)
84
+
85
+ def notify_status_updated(self,
86
+ new_status: AgentStatus,
87
+ old_status: Optional[AgentStatus] = None,
88
+ additional_data: Optional[Dict[str, Any]] = None):
89
+ self._emit_status_update(new_status, old_status, additional_data)
93
90
 
94
91
  def notify_agent_data_assistant_chunk(self, chunk: 'ChunkResponse'):
95
92
  self._emit_event(EventType.AGENT_DATA_ASSISTANT_CHUNK, payload_content=chunk)
96
93
 
97
- def notify_agent_data_assistant_chunk_stream_end(self):
98
- self._emit_event(EventType.AGENT_DATA_ASSISTANT_CHUNK_STREAM_END)
99
-
100
94
  def notify_agent_data_assistant_complete_response(self, complete_response: 'CompleteResponse'):
101
95
  self._emit_event(EventType.AGENT_DATA_ASSISTANT_COMPLETE_RESPONSE, payload_content=complete_response)
102
96
 
97
+ def notify_agent_segment_event(self, event_dict: Dict[str, Any]):
98
+ """Notify a streaming parser segment event (START, CONTENT, END)."""
99
+ self._emit_event(EventType.AGENT_DATA_SEGMENT_EVENT, payload_content=event_dict)
100
+
103
101
  def notify_agent_data_tool_log(self, log_data: Dict[str, Any]):
104
102
  self._emit_event(EventType.AGENT_DATA_TOOL_LOG, payload_content=log_data)
105
103
 
@@ -117,6 +115,10 @@ class AgentExternalEventNotifier(EventEmitter):
117
115
  """Notifies that the agent has received a system-generated task notification."""
118
116
  self._emit_event(EventType.AGENT_DATA_SYSTEM_TASK_NOTIFICATION_RECEIVED, payload_content=notification_data)
119
117
 
118
+ def notify_agent_data_inter_agent_message_received(self, message_data: Dict[str, Any]):
119
+ """Notifies that the agent has received a message from another agent."""
120
+ self._emit_event(EventType.AGENT_DATA_INTER_AGENT_MESSAGE_RECEIVED, payload_content=message_data)
121
+
120
122
  def notify_agent_data_todo_list_updated(self, todo_list: List[Dict[str, Any]]):
121
123
  """Notifies that the agent's ToDo list has been updated."""
122
124
  self._emit_event(EventType.AGENT_DATA_TODO_LIST_UPDATED, payload_content={"todos": todo_list})
@@ -128,3 +130,11 @@ class AgentExternalEventNotifier(EventEmitter):
128
130
  "details": error_details
129
131
  }
130
132
  self._emit_event(EventType.AGENT_ERROR_OUTPUT_GENERATION, payload_content=payload_dict)
133
+
134
+ def notify_agent_artifact_persisted(self, artifact_data: Dict[str, Any]):
135
+ """Notifies that an artifact has been successfully persisted to the database."""
136
+ self._emit_event(EventType.AGENT_ARTIFACT_PERSISTED, payload_content=artifact_data)
137
+
138
+ def notify_agent_artifact_updated(self, artifact_data: Dict[str, Any]):
139
+ """Notifies that an artifact has been updated (e.g., via patch_file)."""
140
+ self._emit_event(EventType.AGENT_ARTIFACT_UPDATED, payload_content=artifact_data)