autobyteus 1.2.0__py3-none-any.whl → 1.2.3__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 (512) hide show
  1. autobyteus/agent/agent.py +15 -5
  2. autobyteus/agent/bootstrap_steps/__init__.py +1 -3
  3. autobyteus/agent/bootstrap_steps/agent_bootstrapper.py +3 -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/workspace_context_initialization_step.py +2 -4
  8. autobyteus/agent/context/agent_config.py +43 -20
  9. autobyteus/agent/context/agent_context.py +23 -18
  10. autobyteus/agent/context/agent_runtime_state.py +23 -19
  11. autobyteus/agent/events/__init__.py +16 -1
  12. autobyteus/agent/events/agent_events.py +43 -3
  13. autobyteus/agent/events/agent_input_event_queue_manager.py +79 -26
  14. autobyteus/agent/events/event_store.py +57 -0
  15. autobyteus/agent/events/notifiers.py +74 -60
  16. autobyteus/agent/events/worker_event_dispatcher.py +21 -64
  17. autobyteus/agent/factory/agent_factory.py +52 -0
  18. autobyteus/agent/handlers/__init__.py +2 -0
  19. autobyteus/agent/handlers/approved_tool_invocation_event_handler.py +51 -34
  20. autobyteus/agent/handlers/bootstrap_event_handler.py +155 -0
  21. autobyteus/agent/handlers/inter_agent_message_event_handler.py +10 -0
  22. autobyteus/agent/handlers/lifecycle_event_logger.py +19 -11
  23. autobyteus/agent/handlers/llm_complete_response_received_event_handler.py +10 -15
  24. autobyteus/agent/handlers/llm_user_message_ready_event_handler.py +188 -48
  25. autobyteus/agent/handlers/tool_execution_approval_event_handler.py +0 -10
  26. autobyteus/agent/handlers/tool_invocation_request_event_handler.py +53 -48
  27. autobyteus/agent/handlers/tool_result_event_handler.py +7 -8
  28. autobyteus/agent/handlers/user_input_message_event_handler.py +10 -3
  29. autobyteus/agent/input_processor/memory_ingest_input_processor.py +40 -0
  30. autobyteus/agent/lifecycle/__init__.py +12 -0
  31. autobyteus/agent/lifecycle/base_processor.py +109 -0
  32. autobyteus/agent/lifecycle/events.py +35 -0
  33. autobyteus/agent/lifecycle/processor_definition.py +36 -0
  34. autobyteus/agent/lifecycle/processor_registry.py +106 -0
  35. autobyteus/agent/llm_request_assembler.py +98 -0
  36. autobyteus/agent/llm_response_processor/__init__.py +1 -8
  37. autobyteus/agent/message/context_file_type.py +1 -1
  38. autobyteus/agent/message/send_message_to.py +5 -4
  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 -178
  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 +81 -0
  114. autobyteus/agent/streaming/stream_event_payloads.py +2 -198
  115. autobyteus/agent/streaming/stream_events.py +3 -128
  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 +5 -6
  145. autobyteus/agent_team/bootstrap_steps/team_context_initialization_step.py +15 -15
  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 +11 -8
  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 +10 -10
  167. autobyteus/agent_team/streaming/agent_team_stream_event_payloads.py +7 -7
  168. autobyteus/agent_team/streaming/agent_team_stream_events.py +11 -11
  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/activation_policy.py +1 -1
  172. autobyteus/agent_team/task_notification/system_event_driven_agent_task_notifier.py +22 -22
  173. autobyteus/agent_team/task_notification/task_notification_mode.py +20 -1
  174. autobyteus/agent_team/utils/wait_for_idle.py +4 -4
  175. autobyteus/cli/agent_cli.py +18 -10
  176. autobyteus/cli/agent_team_tui/app.py +18 -15
  177. autobyteus/cli/agent_team_tui/state.py +21 -23
  178. autobyteus/cli/agent_team_tui/widgets/agent_list_sidebar.py +15 -15
  179. autobyteus/cli/agent_team_tui/widgets/focus_pane.py +146 -39
  180. autobyteus/cli/agent_team_tui/widgets/renderables.py +1 -1
  181. autobyteus/cli/agent_team_tui/widgets/shared.py +26 -26
  182. autobyteus/cli/agent_team_tui/widgets/{task_board_panel.py → task_plan_panel.py} +5 -5
  183. autobyteus/cli/cli_display.py +193 -44
  184. autobyteus/cli/workflow_tui/app.py +9 -10
  185. autobyteus/cli/workflow_tui/state.py +14 -16
  186. autobyteus/cli/workflow_tui/widgets/agent_list_sidebar.py +15 -15
  187. autobyteus/cli/workflow_tui/widgets/focus_pane.py +137 -35
  188. autobyteus/cli/workflow_tui/widgets/renderables.py +1 -1
  189. autobyteus/cli/workflow_tui/widgets/shared.py +25 -25
  190. autobyteus/clients/autobyteus_client.py +94 -1
  191. autobyteus/events/event_types.py +15 -21
  192. autobyteus/llm/api/autobyteus_llm.py +33 -29
  193. autobyteus/llm/api/claude_llm.py +142 -36
  194. autobyteus/llm/api/gemini_llm.py +163 -59
  195. autobyteus/llm/api/grok_llm.py +1 -1
  196. autobyteus/llm/api/minimax_llm.py +26 -0
  197. autobyteus/llm/api/mistral_llm.py +113 -87
  198. autobyteus/llm/api/ollama_llm.py +9 -42
  199. autobyteus/llm/api/openai_compatible_llm.py +127 -91
  200. autobyteus/llm/api/openai_llm.py +3 -3
  201. autobyteus/llm/api/openai_responses_llm.py +324 -0
  202. autobyteus/llm/api/zhipu_llm.py +21 -2
  203. autobyteus/llm/autobyteus_provider.py +70 -60
  204. autobyteus/llm/base_llm.py +85 -81
  205. autobyteus/llm/converters/__init__.py +14 -0
  206. autobyteus/llm/converters/anthropic_tool_call_converter.py +37 -0
  207. autobyteus/llm/converters/gemini_tool_call_converter.py +57 -0
  208. autobyteus/llm/converters/mistral_tool_call_converter.py +37 -0
  209. autobyteus/llm/converters/openai_tool_call_converter.py +38 -0
  210. autobyteus/llm/extensions/base_extension.py +6 -12
  211. autobyteus/llm/extensions/token_usage_tracking_extension.py +45 -18
  212. autobyteus/llm/llm_factory.py +282 -204
  213. autobyteus/llm/lmstudio_provider.py +60 -49
  214. autobyteus/llm/models.py +35 -2
  215. autobyteus/llm/ollama_provider.py +60 -49
  216. autobyteus/llm/ollama_provider_resolver.py +0 -1
  217. autobyteus/llm/prompt_renderers/__init__.py +19 -0
  218. autobyteus/llm/prompt_renderers/anthropic_prompt_renderer.py +104 -0
  219. autobyteus/llm/prompt_renderers/autobyteus_prompt_renderer.py +19 -0
  220. autobyteus/llm/prompt_renderers/base_prompt_renderer.py +10 -0
  221. autobyteus/llm/prompt_renderers/gemini_prompt_renderer.py +63 -0
  222. autobyteus/llm/prompt_renderers/mistral_prompt_renderer.py +87 -0
  223. autobyteus/llm/prompt_renderers/ollama_prompt_renderer.py +51 -0
  224. autobyteus/llm/prompt_renderers/openai_chat_renderer.py +97 -0
  225. autobyteus/llm/prompt_renderers/openai_responses_renderer.py +101 -0
  226. autobyteus/llm/providers.py +1 -3
  227. autobyteus/llm/token_counter/claude_token_counter.py +56 -25
  228. autobyteus/llm/token_counter/mistral_token_counter.py +12 -8
  229. autobyteus/llm/token_counter/openai_token_counter.py +24 -5
  230. autobyteus/llm/token_counter/token_counter_factory.py +12 -5
  231. autobyteus/llm/utils/llm_config.py +6 -12
  232. autobyteus/llm/utils/media_payload_formatter.py +27 -20
  233. autobyteus/llm/utils/messages.py +55 -3
  234. autobyteus/llm/utils/response_types.py +3 -0
  235. autobyteus/llm/utils/tool_call_delta.py +31 -0
  236. autobyteus/memory/__init__.py +32 -0
  237. autobyteus/memory/active_transcript.py +69 -0
  238. autobyteus/memory/compaction/__init__.py +9 -0
  239. autobyteus/memory/compaction/compaction_result.py +8 -0
  240. autobyteus/memory/compaction/compactor.py +89 -0
  241. autobyteus/memory/compaction/summarizer.py +11 -0
  242. autobyteus/memory/compaction_snapshot_builder.py +84 -0
  243. autobyteus/memory/memory_manager.py +183 -0
  244. autobyteus/memory/models/__init__.py +14 -0
  245. autobyteus/memory/models/episodic_item.py +41 -0
  246. autobyteus/memory/models/memory_types.py +7 -0
  247. autobyteus/memory/models/raw_trace_item.py +79 -0
  248. autobyteus/memory/models/semantic_item.py +41 -0
  249. autobyteus/memory/models/tool_interaction.py +20 -0
  250. autobyteus/memory/policies/__init__.py +5 -0
  251. autobyteus/memory/policies/compaction_policy.py +16 -0
  252. autobyteus/memory/retrieval/__init__.py +7 -0
  253. autobyteus/memory/retrieval/memory_bundle.py +11 -0
  254. autobyteus/memory/retrieval/retriever.py +13 -0
  255. autobyteus/memory/store/__init__.py +7 -0
  256. autobyteus/memory/store/base_store.py +14 -0
  257. autobyteus/memory/store/file_store.py +98 -0
  258. autobyteus/memory/tool_interaction_builder.py +46 -0
  259. autobyteus/memory/turn_tracker.py +9 -0
  260. autobyteus/multimedia/audio/api/__init__.py +3 -2
  261. autobyteus/multimedia/audio/api/autobyteus_audio_client.py +19 -5
  262. autobyteus/multimedia/audio/api/gemini_audio_client.py +108 -16
  263. autobyteus/multimedia/audio/api/openai_audio_client.py +112 -0
  264. autobyteus/multimedia/audio/audio_client_factory.py +84 -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 +38 -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/__init__.py +43 -20
  277. autobyteus/task_management/{base_task_board.py → base_task_plan.py} +16 -13
  278. autobyteus/task_management/converters/__init__.py +2 -2
  279. autobyteus/task_management/converters/{task_board_converter.py → task_plan_converter.py} +13 -13
  280. autobyteus/task_management/events.py +7 -7
  281. autobyteus/task_management/{in_memory_task_board.py → in_memory_task_plan.py} +34 -22
  282. autobyteus/task_management/schemas/__init__.py +3 -0
  283. autobyteus/task_management/schemas/task_status_report.py +2 -2
  284. autobyteus/task_management/schemas/todo_definition.py +15 -0
  285. autobyteus/task_management/todo.py +29 -0
  286. autobyteus/task_management/todo_list.py +75 -0
  287. autobyteus/task_management/tools/__init__.py +24 -8
  288. autobyteus/task_management/tools/task_tools/__init__.py +19 -0
  289. autobyteus/task_management/tools/{assign_task_to.py → task_tools/assign_task_to.py} +18 -18
  290. autobyteus/task_management/tools/{publish_task.py → task_tools/create_task.py} +16 -18
  291. autobyteus/task_management/tools/{publish_tasks.py → task_tools/create_tasks.py} +19 -19
  292. autobyteus/task_management/tools/{get_my_tasks.py → task_tools/get_my_tasks.py} +15 -15
  293. autobyteus/task_management/tools/{get_task_board_status.py → task_tools/get_task_plan_status.py} +16 -16
  294. autobyteus/task_management/tools/{update_task_status.py → task_tools/update_task_status.py} +16 -16
  295. autobyteus/task_management/tools/todo_tools/__init__.py +18 -0
  296. autobyteus/task_management/tools/todo_tools/add_todo.py +78 -0
  297. autobyteus/task_management/tools/todo_tools/create_todo_list.py +79 -0
  298. autobyteus/task_management/tools/todo_tools/get_todo_list.py +55 -0
  299. autobyteus/task_management/tools/todo_tools/update_todo_status.py +85 -0
  300. autobyteus/tools/__init__.py +43 -52
  301. autobyteus/tools/base_tool.py +7 -0
  302. autobyteus/tools/file/__init__.py +9 -0
  303. autobyteus/tools/file/patch_file.py +149 -0
  304. autobyteus/tools/file/{file_reader.py → read_file.py} +38 -7
  305. autobyteus/tools/file/{file_writer.py → write_file.py} +7 -4
  306. autobyteus/tools/functional_tool.py +53 -14
  307. autobyteus/tools/mcp/__init__.py +2 -0
  308. autobyteus/tools/mcp/config_service.py +5 -1
  309. autobyteus/tools/mcp/server/__init__.py +2 -0
  310. autobyteus/tools/mcp/server/http_managed_mcp_server.py +1 -1
  311. autobyteus/tools/mcp/server/websocket_managed_mcp_server.py +141 -0
  312. autobyteus/tools/mcp/server_instance_manager.py +8 -1
  313. autobyteus/tools/mcp/tool.py +3 -3
  314. autobyteus/tools/mcp/tool_registrar.py +5 -2
  315. autobyteus/tools/mcp/types.py +61 -0
  316. autobyteus/tools/multimedia/__init__.py +2 -1
  317. autobyteus/tools/multimedia/audio_tools.py +72 -19
  318. autobyteus/tools/{download_media_tool.py → multimedia/download_media_tool.py} +21 -7
  319. autobyteus/tools/multimedia/image_tools.py +248 -64
  320. autobyteus/tools/multimedia/media_reader_tool.py +1 -1
  321. autobyteus/tools/operation_executor/journal_manager.py +107 -0
  322. autobyteus/tools/operation_executor/operation_event_buffer.py +57 -0
  323. autobyteus/tools/operation_executor/operation_event_producer.py +29 -0
  324. autobyteus/tools/operation_executor/operation_executor.py +58 -0
  325. autobyteus/tools/registry/tool_definition.py +108 -14
  326. autobyteus/tools/registry/tool_registry.py +29 -0
  327. autobyteus/tools/search/__init__.py +17 -0
  328. autobyteus/tools/search/base_strategy.py +35 -0
  329. autobyteus/tools/search/client.py +24 -0
  330. autobyteus/tools/search/factory.py +81 -0
  331. autobyteus/tools/search/google_cse_strategy.py +68 -0
  332. autobyteus/tools/search/providers.py +10 -0
  333. autobyteus/tools/search/serpapi_strategy.py +65 -0
  334. autobyteus/tools/search/serper_strategy.py +87 -0
  335. autobyteus/tools/search_tool.py +83 -0
  336. autobyteus/tools/skill/load_skill.py +50 -0
  337. autobyteus/tools/terminal/__init__.py +45 -0
  338. autobyteus/tools/terminal/ansi_utils.py +32 -0
  339. autobyteus/tools/terminal/background_process_manager.py +233 -0
  340. autobyteus/tools/terminal/output_buffer.py +105 -0
  341. autobyteus/tools/terminal/prompt_detector.py +63 -0
  342. autobyteus/tools/terminal/pty_session.py +241 -0
  343. autobyteus/tools/terminal/session_factory.py +20 -0
  344. autobyteus/tools/terminal/terminal_session_manager.py +226 -0
  345. autobyteus/tools/terminal/tools/__init__.py +13 -0
  346. autobyteus/tools/terminal/tools/get_process_output.py +81 -0
  347. autobyteus/tools/terminal/tools/run_bash.py +109 -0
  348. autobyteus/tools/terminal/tools/start_background_process.py +104 -0
  349. autobyteus/tools/terminal/tools/stop_background_process.py +67 -0
  350. autobyteus/tools/terminal/types.py +54 -0
  351. autobyteus/tools/terminal/wsl_tmux_session.py +221 -0
  352. autobyteus/tools/terminal/wsl_utils.py +156 -0
  353. autobyteus/tools/tool_meta.py +4 -24
  354. autobyteus/tools/transaction_management/backup_handler.py +48 -0
  355. autobyteus/tools/transaction_management/operation_lifecycle_manager.py +62 -0
  356. autobyteus/tools/usage/__init__.py +1 -2
  357. autobyteus/tools/usage/formatters/__init__.py +17 -1
  358. autobyteus/tools/usage/formatters/base_formatter.py +8 -0
  359. autobyteus/tools/usage/formatters/default_xml_schema_formatter.py +2 -2
  360. autobyteus/tools/usage/formatters/mistral_json_schema_formatter.py +18 -0
  361. autobyteus/tools/usage/formatters/patch_file_xml_example_formatter.py +64 -0
  362. autobyteus/tools/usage/formatters/patch_file_xml_schema_formatter.py +31 -0
  363. autobyteus/tools/usage/formatters/run_bash_xml_example_formatter.py +32 -0
  364. autobyteus/tools/usage/formatters/run_bash_xml_schema_formatter.py +36 -0
  365. autobyteus/tools/usage/formatters/write_file_xml_example_formatter.py +53 -0
  366. autobyteus/tools/usage/formatters/write_file_xml_schema_formatter.py +31 -0
  367. autobyteus/tools/usage/providers/tool_manifest_provider.py +10 -10
  368. autobyteus/tools/usage/registries/__init__.py +1 -3
  369. autobyteus/tools/usage/registries/tool_formatting_registry.py +115 -8
  370. autobyteus/tools/usage/tool_schema_provider.py +51 -0
  371. autobyteus/tools/web/__init__.py +4 -0
  372. autobyteus/tools/web/read_url_tool.py +80 -0
  373. autobyteus/utils/diff_utils.py +271 -0
  374. autobyteus/utils/download_utils.py +109 -0
  375. autobyteus/utils/file_utils.py +57 -2
  376. autobyteus/utils/gemini_helper.py +56 -0
  377. autobyteus/utils/gemini_model_mapping.py +71 -0
  378. autobyteus/utils/llm_output_formatter.py +75 -0
  379. autobyteus/utils/tool_call_format.py +36 -0
  380. autobyteus/workflow/agentic_workflow.py +3 -3
  381. autobyteus/workflow/bootstrap_steps/agent_tool_injection_step.py +2 -2
  382. autobyteus/workflow/bootstrap_steps/base_workflow_bootstrap_step.py +2 -2
  383. autobyteus/workflow/bootstrap_steps/coordinator_initialization_step.py +2 -2
  384. autobyteus/workflow/bootstrap_steps/coordinator_prompt_preparation_step.py +4 -11
  385. autobyteus/workflow/bootstrap_steps/workflow_bootstrapper.py +6 -6
  386. autobyteus/workflow/bootstrap_steps/workflow_runtime_queue_initialization_step.py +2 -2
  387. autobyteus/workflow/context/workflow_context.py +3 -3
  388. autobyteus/workflow/context/workflow_runtime_state.py +5 -5
  389. autobyteus/workflow/events/workflow_event_dispatcher.py +5 -5
  390. autobyteus/workflow/handlers/lifecycle_workflow_event_handler.py +3 -3
  391. autobyteus/workflow/handlers/process_user_message_event_handler.py +5 -5
  392. autobyteus/workflow/handlers/tool_approval_workflow_event_handler.py +2 -2
  393. autobyteus/workflow/runtime/workflow_runtime.py +8 -8
  394. autobyteus/workflow/runtime/workflow_worker.py +3 -3
  395. autobyteus/workflow/status/__init__.py +11 -0
  396. autobyteus/workflow/status/workflow_status.py +19 -0
  397. autobyteus/workflow/status/workflow_status_manager.py +48 -0
  398. autobyteus/workflow/streaming/__init__.py +2 -2
  399. autobyteus/workflow/streaming/workflow_event_notifier.py +7 -7
  400. autobyteus/workflow/streaming/workflow_stream_event_payloads.py +4 -4
  401. autobyteus/workflow/streaming/workflow_stream_events.py +3 -3
  402. autobyteus/workflow/utils/wait_for_idle.py +4 -4
  403. autobyteus-1.2.3.dist-info/METADATA +293 -0
  404. autobyteus-1.2.3.dist-info/RECORD +600 -0
  405. {autobyteus-1.2.0.dist-info → autobyteus-1.2.3.dist-info}/WHEEL +1 -1
  406. {autobyteus-1.2.0.dist-info → autobyteus-1.2.3.dist-info}/top_level.txt +0 -1
  407. autobyteus/agent/bootstrap_steps/agent_runtime_queue_initialization_step.py +0 -57
  408. autobyteus/agent/hooks/__init__.py +0 -16
  409. autobyteus/agent/hooks/base_phase_hook.py +0 -78
  410. autobyteus/agent/hooks/hook_definition.py +0 -36
  411. autobyteus/agent/hooks/hook_meta.py +0 -37
  412. autobyteus/agent/hooks/hook_registry.py +0 -106
  413. autobyteus/agent/llm_response_processor/provider_aware_tool_usage_processor.py +0 -103
  414. autobyteus/agent/phases/__init__.py +0 -18
  415. autobyteus/agent/phases/discover.py +0 -53
  416. autobyteus/agent/phases/manager.py +0 -265
  417. autobyteus/agent/phases/transition_decorator.py +0 -40
  418. autobyteus/agent/phases/transition_info.py +0 -33
  419. autobyteus/agent/remote_agent.py +0 -244
  420. autobyteus/agent/workspace/workspace_definition.py +0 -36
  421. autobyteus/agent/workspace/workspace_meta.py +0 -37
  422. autobyteus/agent/workspace/workspace_registry.py +0 -72
  423. autobyteus/agent_team/bootstrap_steps/agent_team_runtime_queue_initialization_step.py +0 -25
  424. autobyteus/agent_team/bootstrap_steps/coordinator_prompt_preparation_step.py +0 -85
  425. autobyteus/agent_team/phases/__init__.py +0 -11
  426. autobyteus/agent_team/phases/agent_team_operational_phase.py +0 -19
  427. autobyteus/agent_team/phases/agent_team_phase_manager.py +0 -48
  428. autobyteus/llm/api/bedrock_llm.py +0 -92
  429. autobyteus/llm/api/groq_llm.py +0 -94
  430. autobyteus/llm/api/nvidia_llm.py +0 -108
  431. autobyteus/llm/utils/token_pricing_config.py +0 -87
  432. autobyteus/person/examples/sample_persons.py +0 -14
  433. autobyteus/person/examples/sample_roles.py +0 -14
  434. autobyteus/person/person.py +0 -29
  435. autobyteus/person/role.py +0 -14
  436. autobyteus/rpc/__init__.py +0 -73
  437. autobyteus/rpc/client/__init__.py +0 -17
  438. autobyteus/rpc/client/abstract_client_connection.py +0 -124
  439. autobyteus/rpc/client/client_connection_manager.py +0 -153
  440. autobyteus/rpc/client/sse_client_connection.py +0 -306
  441. autobyteus/rpc/client/stdio_client_connection.py +0 -280
  442. autobyteus/rpc/config/__init__.py +0 -13
  443. autobyteus/rpc/config/agent_server_config.py +0 -153
  444. autobyteus/rpc/config/agent_server_registry.py +0 -152
  445. autobyteus/rpc/hosting.py +0 -244
  446. autobyteus/rpc/protocol.py +0 -244
  447. autobyteus/rpc/server/__init__.py +0 -20
  448. autobyteus/rpc/server/agent_server_endpoint.py +0 -181
  449. autobyteus/rpc/server/base_method_handler.py +0 -40
  450. autobyteus/rpc/server/method_handlers.py +0 -259
  451. autobyteus/rpc/server/sse_server_handler.py +0 -182
  452. autobyteus/rpc/server/stdio_server_handler.py +0 -151
  453. autobyteus/rpc/server_main.py +0 -198
  454. autobyteus/rpc/transport_type.py +0 -13
  455. autobyteus/tools/bash/__init__.py +0 -2
  456. autobyteus/tools/bash/bash_executor.py +0 -100
  457. autobyteus/tools/browser/__init__.py +0 -2
  458. autobyteus/tools/browser/session_aware/__init__.py +0 -0
  459. autobyteus/tools/browser/session_aware/browser_session_aware_navigate_to.py +0 -75
  460. autobyteus/tools/browser/session_aware/browser_session_aware_tool.py +0 -30
  461. autobyteus/tools/browser/session_aware/browser_session_aware_web_element_trigger.py +0 -154
  462. autobyteus/tools/browser/session_aware/browser_session_aware_webpage_reader.py +0 -89
  463. autobyteus/tools/browser/session_aware/browser_session_aware_webpage_screenshot_taker.py +0 -107
  464. autobyteus/tools/browser/session_aware/factory/__init__.py +0 -0
  465. autobyteus/tools/browser/session_aware/factory/browser_session_aware_web_element_trigger_factory.py +0 -14
  466. autobyteus/tools/browser/session_aware/factory/browser_session_aware_webpage_reader_factory.py +0 -26
  467. autobyteus/tools/browser/session_aware/factory/browser_session_aware_webpage_screenshot_taker_factory.py +0 -14
  468. autobyteus/tools/browser/session_aware/shared_browser_session.py +0 -11
  469. autobyteus/tools/browser/session_aware/shared_browser_session_manager.py +0 -25
  470. autobyteus/tools/browser/session_aware/web_element_action.py +0 -20
  471. autobyteus/tools/browser/standalone/__init__.py +0 -6
  472. autobyteus/tools/browser/standalone/factory/__init__.py +0 -0
  473. autobyteus/tools/browser/standalone/factory/webpage_reader_factory.py +0 -25
  474. autobyteus/tools/browser/standalone/factory/webpage_screenshot_taker_factory.py +0 -14
  475. autobyteus/tools/browser/standalone/navigate_to.py +0 -80
  476. autobyteus/tools/browser/standalone/web_page_pdf_generator.py +0 -97
  477. autobyteus/tools/browser/standalone/webpage_image_downloader.py +0 -165
  478. autobyteus/tools/browser/standalone/webpage_reader.py +0 -101
  479. autobyteus/tools/browser/standalone/webpage_screenshot_taker.py +0 -101
  480. autobyteus/tools/file/file_editor.py +0 -200
  481. autobyteus/tools/google_search.py +0 -149
  482. autobyteus/tools/timer.py +0 -171
  483. autobyteus/tools/usage/parsers/__init__.py +0 -22
  484. autobyteus/tools/usage/parsers/_json_extractor.py +0 -99
  485. autobyteus/tools/usage/parsers/_string_decoders.py +0 -18
  486. autobyteus/tools/usage/parsers/anthropic_xml_tool_usage_parser.py +0 -10
  487. autobyteus/tools/usage/parsers/base_parser.py +0 -41
  488. autobyteus/tools/usage/parsers/default_json_tool_usage_parser.py +0 -83
  489. autobyteus/tools/usage/parsers/default_xml_tool_usage_parser.py +0 -316
  490. autobyteus/tools/usage/parsers/exceptions.py +0 -13
  491. autobyteus/tools/usage/parsers/gemini_json_tool_usage_parser.py +0 -77
  492. autobyteus/tools/usage/parsers/openai_json_tool_usage_parser.py +0 -149
  493. autobyteus/tools/usage/parsers/provider_aware_tool_usage_parser.py +0 -59
  494. autobyteus/tools/usage/registries/tool_usage_parser_registry.py +0 -62
  495. autobyteus/workflow/phases/__init__.py +0 -11
  496. autobyteus/workflow/phases/workflow_operational_phase.py +0 -19
  497. autobyteus/workflow/phases/workflow_phase_manager.py +0 -48
  498. autobyteus-1.2.0.dist-info/METADATA +0 -205
  499. autobyteus-1.2.0.dist-info/RECORD +0 -496
  500. examples/__init__.py +0 -1
  501. examples/agent_team/__init__.py +0 -1
  502. examples/discover_phase_transitions.py +0 -104
  503. examples/run_browser_agent.py +0 -262
  504. examples/run_google_slides_agent.py +0 -287
  505. examples/run_mcp_browser_client.py +0 -174
  506. examples/run_mcp_google_slides_client.py +0 -270
  507. examples/run_mcp_list_tools.py +0 -189
  508. examples/run_poem_writer.py +0 -284
  509. examples/run_sqlite_agent.py +0 -295
  510. /autobyteus/{person → skills}/__init__.py +0 -0
  511. /autobyteus/{person/examples → tools/skill}/__init__.py +0 -0
  512. {autobyteus-1.2.0.dist-info → autobyteus-1.2.3.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,18 @@
1
+ """Shared adapters for streaming output."""
2
+
3
+ from .invocation_adapter import ToolInvocationAdapter
4
+ from .tool_syntax_registry import (
5
+ ToolSyntaxSpec,
6
+ get_tool_syntax_spec,
7
+ tool_syntax_registry_items,
8
+ )
9
+ from .tool_call_parsing import parse_json_tool_call, parse_xml_arguments
10
+
11
+ __all__ = [
12
+ "ToolInvocationAdapter",
13
+ "ToolSyntaxSpec",
14
+ "get_tool_syntax_spec",
15
+ "tool_syntax_registry_items",
16
+ "parse_json_tool_call",
17
+ "parse_xml_arguments",
18
+ ]
@@ -0,0 +1,184 @@
1
+ """
2
+ ToolInvocation Adapter: Converts tool SegmentEvents into ToolInvocation objects.
3
+
4
+ This adapter serves as the bridge between the streaming parser (which emits SegmentEvents)
5
+ and the agent's tool execution system (which expects ToolInvocation objects).
6
+
7
+ Key Design: The segment_id from the parser becomes the invocationId, ensuring
8
+ consistent ID tracking from parse time through approval and execution.
9
+ """
10
+ from typing import Optional, List, Dict, Any, TYPE_CHECKING
11
+ import logging
12
+
13
+ from ..segments.segment_events import SegmentEvent, SegmentType, SegmentEventType
14
+ from .tool_syntax_registry import get_tool_syntax_spec
15
+ from .tool_call_parsing import parse_json_tool_call, parse_xml_arguments
16
+ from autobyteus.agent.tool_invocation import ToolInvocation
17
+
18
+ logger = logging.getLogger(__name__)
19
+
20
+ if TYPE_CHECKING:
21
+ from ..parser.json_parsing_strategies.base import JsonToolParsingStrategy
22
+
23
+
24
+ class ToolInvocationAdapter:
25
+ """
26
+ Converts tool call SegmentEvents into ToolInvocation objects.
27
+
28
+ Usage:
29
+ adapter = ToolInvocationAdapter()
30
+
31
+ for event in parser.feed(chunk):
32
+ result = adapter.process_event(event)
33
+ if result:
34
+ # Got a complete ToolInvocation
35
+ enqueue_tool_invocation(result)
36
+ """
37
+
38
+ def __init__(self, json_tool_parser: Optional["JsonToolParsingStrategy"] = None):
39
+ # Track active tool segments: segment_id -> accumulated data
40
+ self._active_segments: Dict[str, Dict[str, Any]] = {}
41
+ self._json_tool_parser = json_tool_parser
42
+
43
+ def process_event(self, event: SegmentEvent) -> Optional[ToolInvocation]:
44
+ """
45
+ Process a SegmentEvent and return a ToolInvocation if complete.
46
+
47
+ Args:
48
+ event: A SegmentEvent from the streaming parser.
49
+
50
+ Returns:
51
+ ToolInvocation if a tool segment just completed, None otherwise.
52
+ """
53
+ if event.event_type == SegmentEventType.START:
54
+ return self._handle_start(event)
55
+ elif event.event_type == SegmentEventType.CONTENT:
56
+ return self._handle_content(event)
57
+ elif event.event_type == SegmentEventType.END:
58
+ return self._handle_end(event)
59
+ return None
60
+
61
+ def _handle_start(self, event: SegmentEvent) -> None:
62
+ """Handle SEGMENT_START events."""
63
+ if event.segment_type != SegmentType.TOOL_CALL and get_tool_syntax_spec(event.segment_type) is None:
64
+ return None
65
+
66
+ # Initialize tracking for this tool segment
67
+ metadata = event.payload.get("metadata", {})
68
+ tool_name = metadata.get("tool_name")
69
+ syntax_spec = get_tool_syntax_spec(event.segment_type)
70
+ if syntax_spec:
71
+ tool_name = syntax_spec.tool_name
72
+
73
+ self._active_segments[event.segment_id] = {
74
+ "segment_type": event.segment_type,
75
+ "tool_name": tool_name,
76
+ "content_buffer": "",
77
+ "arguments": {},
78
+ "syntax_spec": syntax_spec,
79
+ "metadata": metadata,
80
+ }
81
+
82
+ logger.debug(f"ToolInvocationAdapter: Started tracking segment {event.segment_id}")
83
+ return None
84
+
85
+ def _handle_content(self, event: SegmentEvent) -> None:
86
+ """Handle SEGMENT_CONTENT events."""
87
+ if event.segment_id not in self._active_segments:
88
+ return None
89
+
90
+ # Accumulate content (for display purposes)
91
+ delta = event.payload.get("delta", "")
92
+ self._active_segments[event.segment_id]["content_buffer"] += delta
93
+ return None
94
+
95
+ def _handle_end(self, event: SegmentEvent) -> Optional[ToolInvocation]:
96
+ """
97
+ Handle SEGMENT_END events.
98
+
99
+ When a tool segment ends, create and return a ToolInvocation.
100
+ """
101
+ if event.segment_id not in self._active_segments:
102
+ return None
103
+
104
+ segment_data = self._active_segments.pop(event.segment_id)
105
+
106
+ # Extract metadata from END event (display metadata only)
107
+ metadata = event.payload.get("metadata", {})
108
+ segment_type = segment_data.get("segment_type")
109
+ tool_name = metadata.get("tool_name") or segment_data.get("tool_name")
110
+ arguments: Dict[str, Any] = segment_data.get("arguments", {})
111
+ content_buffer = segment_data.get("content_buffer", "")
112
+ start_metadata = segment_data.get("metadata", {})
113
+ syntax_spec = segment_data.get("syntax_spec")
114
+
115
+ if syntax_spec:
116
+ tool_name = syntax_spec.tool_name
117
+ args = syntax_spec.build_arguments(
118
+ {**start_metadata, **metadata},
119
+ content_buffer,
120
+ )
121
+ if args is None:
122
+ logger.warning(
123
+ f"Tool segment {event.segment_id} ended without required arguments for {tool_name}"
124
+ )
125
+ return None
126
+ arguments = args
127
+ elif segment_type == SegmentType.TOOL_CALL:
128
+ content = content_buffer
129
+ stripped = content.lstrip()
130
+ parsed_call = None
131
+
132
+ # Check if arguments were provided in metadata (e.g. Sentinel parser)
133
+ # First check start_metadata, then end metadata
134
+ if start_metadata.get("arguments"):
135
+ arguments = start_metadata["arguments"]
136
+ elif metadata.get("arguments"):
137
+ arguments = metadata["arguments"]
138
+ elif stripped.startswith("{") or stripped.startswith("["):
139
+ parsed_call = parse_json_tool_call(stripped, self._json_tool_parser)
140
+ else:
141
+ arguments = parse_xml_arguments(content)
142
+
143
+ if parsed_call:
144
+ tool_name = tool_name or parsed_call.get("name")
145
+ arguments = parsed_call.get("arguments") or {}
146
+
147
+ if not tool_name:
148
+ logger.warning(f"Tool segment {event.segment_id} ended without tool_name")
149
+ return None
150
+
151
+ # Create ToolInvocation with segment_id as the invocation id
152
+ invocation = ToolInvocation(
153
+ name=tool_name,
154
+ arguments=arguments,
155
+ id=event.segment_id # Key: segment_id becomes invocationId
156
+ )
157
+
158
+ logger.info(f"ToolInvocationAdapter: Created invocation {invocation.id} for tool {tool_name}")
159
+ return invocation
160
+
161
+ def process_events(self, events: List[SegmentEvent]) -> List[ToolInvocation]:
162
+ """
163
+ Process multiple events and return all completed ToolInvocations.
164
+
165
+ Args:
166
+ events: List of SegmentEvents from the parser.
167
+
168
+ Returns:
169
+ List of ToolInvocations for any completed tool segments.
170
+ """
171
+ invocations = []
172
+ for event in events:
173
+ result = self.process_event(event)
174
+ if result:
175
+ invocations.append(result)
176
+ return invocations
177
+
178
+ def reset(self) -> None:
179
+ """Clear all tracking state."""
180
+ self._active_segments.clear()
181
+
182
+ def get_active_segment_ids(self) -> List[str]:
183
+ """Get IDs of currently tracked tool segments."""
184
+ return list(self._active_segments.keys())
@@ -0,0 +1,163 @@
1
+ """
2
+ Utility parsers for tool call argument extraction.
3
+
4
+ These functions are intentionally decoupled from streaming states so the
5
+ ToolInvocationAdapter can be the single source of truth for arguments.
6
+ """
7
+ from __future__ import annotations
8
+
9
+ import json
10
+ import re
11
+ import xml.etree.ElementTree as ET
12
+ from typing import Any, Dict, Optional
13
+
14
+ from ..parser.json_parsing_strategies.base import JsonToolParsingStrategy
15
+
16
+ _ARGS_OPEN = "<arguments>"
17
+ _ARGS_CLOSE = "</arguments>"
18
+ _TAG_SPLIT_PATTERN = re.compile(r"(<[A-Za-z!/][^>]*>)")
19
+ _ENTITY_PATTERN = re.compile(r"&(?!(?:amp|lt|gt|quot|apos|#\d+|#x[0-9a-fA-F]+);)")
20
+
21
+
22
+ def parse_xml_arguments(content: str) -> Dict[str, Any]:
23
+ """
24
+ Parse XML tool arguments from a tool-call content body.
25
+
26
+ Supports:
27
+ 1) <arguments><arg name="x">...</arg></arguments>
28
+ 2) <arguments><path>...</path></arguments>
29
+ 3) Direct content without <arguments> wrapper
30
+ """
31
+ args_match = re.search(
32
+ rf"{_ARGS_OPEN}(.*?){_ARGS_CLOSE}",
33
+ content,
34
+ re.IGNORECASE | re.DOTALL,
35
+ )
36
+ if args_match:
37
+ args_content = args_match.group(1)
38
+ else:
39
+ args_content = content.strip()
40
+
41
+ if not args_content:
42
+ return {}
43
+
44
+ try:
45
+ root = ET.fromstring(f"<root>{args_content}</root>")
46
+ return _parse_xml_children(root)
47
+ except ET.ParseError:
48
+ sanitized = _sanitize_xml_fragment(args_content)
49
+ try:
50
+ root = ET.fromstring(f"<root>{sanitized}</root>")
51
+ return _parse_xml_children(root)
52
+ except ET.ParseError:
53
+ return _parse_legacy_arguments(args_content)
54
+
55
+
56
+ def parse_json_tool_call(
57
+ json_str: str,
58
+ parser: Optional[JsonToolParsingStrategy] = None,
59
+ ) -> Optional[Dict[str, Any]]:
60
+ """
61
+ Parse a JSON string into tool call info.
62
+
63
+ Returns dict with 'name' and 'arguments', or None if invalid.
64
+ """
65
+ if parser is not None:
66
+ parsed_calls = parser.parse(json_str)
67
+ if parsed_calls:
68
+ return parsed_calls[0]
69
+ return None
70
+
71
+ try:
72
+ data = json.loads(json_str)
73
+
74
+ if isinstance(data, list) and data:
75
+ data = data[0]
76
+
77
+ if isinstance(data, dict):
78
+ name = (
79
+ data.get("name")
80
+ or data.get("tool")
81
+ or data.get("function", {}).get("name")
82
+ or "unknown"
83
+ )
84
+ arguments = (
85
+ data.get("arguments")
86
+ or data.get("parameters")
87
+ or data.get("function", {}).get("arguments")
88
+ or {}
89
+ )
90
+ if isinstance(arguments, str):
91
+ try:
92
+ arguments = json.loads(arguments)
93
+ except json.JSONDecodeError:
94
+ pass
95
+ return {"name": name, "arguments": arguments}
96
+ except json.JSONDecodeError:
97
+ return None
98
+
99
+ return None
100
+
101
+
102
+ def _parse_xml_children(element: ET.Element) -> Dict[str, Any]:
103
+ arguments: Dict[str, Any] = {}
104
+ for child in element:
105
+ name = child.attrib.get("name") or child.tag
106
+ if not name:
107
+ continue
108
+ arguments[name] = _parse_xml_value(child)
109
+ return arguments
110
+
111
+
112
+ def _parse_xml_value(element: ET.Element) -> Any:
113
+ items = [child for child in element if child.tag == "item"]
114
+ if items:
115
+ return [_parse_item_value(item) for item in items]
116
+
117
+ arg_children = [child for child in element if child.tag == "arg"]
118
+ if arg_children:
119
+ return _parse_xml_children(element)
120
+
121
+ other_children = [child for child in element if child.tag not in {"arg", "item"}]
122
+ if other_children:
123
+ return _parse_xml_children(element)
124
+
125
+ text = element.text or ""
126
+ return text.strip()
127
+
128
+
129
+ def _parse_item_value(element: ET.Element) -> Any:
130
+ arg_children = [child for child in element if child.tag == "arg"]
131
+ if arg_children:
132
+ return _parse_xml_children(element)
133
+ other_children = [child for child in element if child.tag not in {"arg", "item"}]
134
+ if other_children:
135
+ return _parse_xml_children(element)
136
+ text = element.text or ""
137
+ return text.strip()
138
+
139
+
140
+ def _parse_legacy_arguments(args_content: str) -> Dict[str, Any]:
141
+ arguments: Dict[str, Any] = {}
142
+ arg_pattern = re.compile(r"<(\\w+)>(.*?)</\\1>", re.DOTALL)
143
+ for match in arg_pattern.finditer(args_content):
144
+ arg_name = match.group(1)
145
+ arg_value = match.group(2).strip()
146
+ arguments[arg_name] = arg_value
147
+ return arguments
148
+
149
+
150
+ def _sanitize_xml_fragment(fragment: str) -> str:
151
+ """Escape raw text to make fragment XML-safe without touching tags."""
152
+ parts = _TAG_SPLIT_PATTERN.split(fragment)
153
+ sanitized_parts = []
154
+ for part in parts:
155
+ if not part:
156
+ continue
157
+ if part.startswith("<") and part.endswith(">"):
158
+ sanitized_parts.append(part)
159
+ continue
160
+ escaped = _ENTITY_PATTERN.sub("&amp;", part)
161
+ escaped = escaped.replace("<", "&lt;")
162
+ sanitized_parts.append(escaped)
163
+ return "".join(sanitized_parts)
@@ -0,0 +1,67 @@
1
+ """
2
+ Registry for mapping segment syntaxes to tool invocations.
3
+ """
4
+ from __future__ import annotations
5
+
6
+ from dataclasses import dataclass
7
+ from typing import Callable, Dict, Optional, Tuple
8
+
9
+ from ..segments.segment_events import SegmentType
10
+
11
+ ToolArgsBuilder = Callable[[dict, str], Optional[dict]]
12
+
13
+
14
+ @dataclass(frozen=True)
15
+ class ToolSyntaxSpec:
16
+ """Defines how a segment type maps to a tool invocation."""
17
+
18
+ tool_name: str
19
+ build_arguments: ToolArgsBuilder
20
+
21
+
22
+ def _build_write_file_args(metadata: dict, content: str) -> Optional[dict]:
23
+ path = metadata.get("path")
24
+ if not path:
25
+ return None
26
+ return {"path": path, "content": content}
27
+
28
+
29
+ def _build_run_bash_args(metadata: dict, content: str) -> Optional[dict]:
30
+ command = content or metadata.get("cmd") or ""
31
+ if not command:
32
+ return None
33
+ return {"command": command}
34
+
35
+
36
+ def _build_patch_file_args(metadata: dict, content: str) -> Optional[dict]:
37
+ path = metadata.get("path")
38
+ if not path:
39
+ return None
40
+ # 'content' here is the accumulated patch delta from the stream
41
+ return {"path": path, "patch": content}
42
+
43
+
44
+ _TOOL_SYNTAX_REGISTRY: Dict[SegmentType, ToolSyntaxSpec] = {
45
+ SegmentType.WRITE_FILE: ToolSyntaxSpec(
46
+ tool_name="write_file",
47
+ build_arguments=_build_write_file_args,
48
+ ),
49
+ SegmentType.RUN_BASH: ToolSyntaxSpec(
50
+ tool_name="run_bash",
51
+ build_arguments=_build_run_bash_args,
52
+ ),
53
+ SegmentType.PATCH_FILE: ToolSyntaxSpec(
54
+ tool_name="patch_file",
55
+ build_arguments=_build_patch_file_args,
56
+ ),
57
+ }
58
+
59
+
60
+ def get_tool_syntax_spec(segment_type: SegmentType) -> Optional[ToolSyntaxSpec]:
61
+ """Return tool syntax spec for a segment type if registered."""
62
+ return _TOOL_SYNTAX_REGISTRY.get(segment_type)
63
+
64
+
65
+ def tool_syntax_registry_items() -> Tuple[Tuple[SegmentType, ToolSyntaxSpec], ...]:
66
+ """Expose registry items for inspection/testing."""
67
+ return tuple(_TOOL_SYNTAX_REGISTRY.items())
@@ -1,179 +1,4 @@
1
- # file: autobyteus/autobyteus/agent/streaming/agent_event_stream.py
2
- import asyncio
3
- import logging
4
- import traceback
5
- import functools
6
- import queue as standard_queue
7
- from typing import AsyncIterator, Dict, Any, TYPE_CHECKING, List, Optional, Callable, Union
1
+ """Compatibility shim for AgentEventStream."""
2
+ from .streams.agent_event_stream import AgentEventStream
8
3
 
9
- from autobyteus.llm.utils.response_types import ChunkResponse, CompleteResponse
10
- from autobyteus.agent.streaming.stream_events import StreamEvent, StreamEventType
11
- from autobyteus.agent.streaming.stream_event_payloads import (
12
- create_assistant_chunk_data,
13
- create_assistant_complete_response_data,
14
- create_tool_interaction_log_entry_data,
15
- create_agent_operational_phase_transition_data,
16
- create_error_event_data,
17
- create_tool_invocation_approval_requested_data,
18
- create_tool_invocation_auto_executing_data,
19
- create_system_task_notification_data, # NEW
20
- AssistantChunkData,
21
- AssistantCompleteResponseData,
22
- ToolInteractionLogEntryData,
23
- AgentOperationalPhaseTransitionData,
24
- ToolInvocationApprovalRequestedData,
25
- ToolInvocationAutoExecutingData,
26
- ErrorEventData,
27
- SystemTaskNotificationData, # NEW
28
- EmptyData,
29
- StreamDataPayload,
30
- )
31
- from .queue_streamer import stream_queue_items
32
- from autobyteus.events.event_types import EventType
33
- from autobyteus.events.event_emitter import EventEmitter
34
-
35
- if TYPE_CHECKING:
36
- from autobyteus.agent.agent import Agent
37
- from autobyteus.agent.events.notifiers import AgentExternalEventNotifier
38
-
39
- logger = logging.getLogger(__name__)
40
-
41
- _AES_INTERNAL_SENTINEL = object()
42
-
43
- class AgentEventStream(EventEmitter):
44
- def __init__(self, agent: 'Agent'):
45
- super().__init__()
46
-
47
- from autobyteus.agent.agent import Agent as ConcreteAgent
48
- if not isinstance(agent, ConcreteAgent):
49
- raise TypeError(f"AgentEventStream requires an Agent instance, got {type(agent).__name__}.")
50
-
51
- self.agent_id: str = agent.agent_id
52
-
53
- self._loop = asyncio.get_event_loop()
54
- self._generic_stream_event_internal_q: standard_queue.Queue[Union[StreamEvent, object]] = standard_queue.Queue()
55
-
56
- self._notifier: Optional['AgentExternalEventNotifier'] = None
57
- if agent.context and agent.context.phase_manager:
58
- self._notifier = agent.context.phase_manager.notifier
59
-
60
- if not self._notifier:
61
- logger.error(f"AgentEventStream for '{self.agent_id}': Notifier not available. No events will be streamed.")
62
- return
63
-
64
- self._register_listeners()
65
-
66
- logger.info(f"AgentEventStream (ID: {self.object_id}) initialized for agent_id '{self.agent_id}'. Subscribed to notifier.")
67
-
68
- def _register_listeners(self):
69
- """Subscribes this instance's handler to all relevant events from the notifier."""
70
- all_agent_event_types = [et for et in EventType if et.name.startswith("AGENT_")]
71
-
72
- for event_type in all_agent_event_types:
73
- self.subscribe_from(self._notifier, event_type, self._handle_notifier_event_sync)
74
-
75
- def _handle_notifier_event_sync(self, event_type: EventType, payload: Optional[Any] = None, object_id: Optional[str] = None, **kwargs):
76
- event_agent_id = kwargs.get("agent_id", self.agent_id)
77
-
78
- typed_payload_for_stream_event: Optional[StreamDataPayload] = None
79
- stream_event_type_for_generic_stream: Optional[StreamEventType] = None
80
-
81
- try:
82
- if event_type == EventType.AGENT_PHASE_IDLE_ENTERED:
83
- typed_payload_for_stream_event = create_agent_operational_phase_transition_data(payload)
84
- stream_event_type_for_generic_stream = StreamEventType.AGENT_IDLE
85
- elif event_type.name.startswith("AGENT_PHASE_"):
86
- typed_payload_for_stream_event = create_agent_operational_phase_transition_data(payload)
87
- stream_event_type_for_generic_stream = StreamEventType.AGENT_OPERATIONAL_PHASE_TRANSITION
88
- elif event_type == EventType.AGENT_DATA_ASSISTANT_CHUNK:
89
- typed_payload_for_stream_event = create_assistant_chunk_data(payload)
90
- stream_event_type_for_generic_stream = StreamEventType.ASSISTANT_CHUNK
91
- elif event_type == EventType.AGENT_DATA_ASSISTANT_COMPLETE_RESPONSE:
92
- typed_payload_for_stream_event = create_assistant_complete_response_data(payload)
93
- stream_event_type_for_generic_stream = StreamEventType.ASSISTANT_COMPLETE_RESPONSE
94
- elif event_type == EventType.AGENT_DATA_TOOL_LOG:
95
- typed_payload_for_stream_event = create_tool_interaction_log_entry_data(payload)
96
- stream_event_type_for_generic_stream = StreamEventType.TOOL_INTERACTION_LOG_ENTRY
97
- elif event_type == EventType.AGENT_REQUEST_TOOL_INVOCATION_APPROVAL:
98
- typed_payload_for_stream_event = create_tool_invocation_approval_requested_data(payload)
99
- stream_event_type_for_generic_stream = StreamEventType.TOOL_INVOCATION_APPROVAL_REQUESTED
100
- elif event_type == EventType.AGENT_TOOL_INVOCATION_AUTO_EXECUTING:
101
- typed_payload_for_stream_event = create_tool_invocation_auto_executing_data(payload)
102
- stream_event_type_for_generic_stream = StreamEventType.TOOL_INVOCATION_AUTO_EXECUTING
103
- elif event_type == EventType.AGENT_ERROR_OUTPUT_GENERATION:
104
- typed_payload_for_stream_event = create_error_event_data(payload)
105
- stream_event_type_for_generic_stream = StreamEventType.ERROR_EVENT
106
- # NEW MAPPING
107
- elif event_type == EventType.AGENT_DATA_SYSTEM_TASK_NOTIFICATION_RECEIVED:
108
- typed_payload_for_stream_event = create_system_task_notification_data(payload)
109
- stream_event_type_for_generic_stream = StreamEventType.SYSTEM_TASK_NOTIFICATION
110
-
111
- elif event_type in [EventType.AGENT_DATA_ASSISTANT_CHUNK_STREAM_END, EventType.AGENT_DATA_TOOL_LOG_STREAM_END]:
112
- pass
113
- else:
114
- logger.debug(f"AgentEventStream received internal event '{event_type.name}' with no direct stream mapping.")
115
-
116
- except Exception as e:
117
- logger.error(f"AgentEventStream error processing payload for event '{event_type.name}': {e}", exc_info=True)
118
-
119
- if typed_payload_for_stream_event and stream_event_type_for_generic_stream:
120
- stream_event = StreamEvent(
121
- agent_id=event_agent_id,
122
- event_type=stream_event_type_for_generic_stream,
123
- data=typed_payload_for_stream_event
124
- )
125
- self._generic_stream_event_internal_q.put(stream_event)
126
-
127
- async def close(self):
128
- logger.info(f"AgentEventStream (ID: {self.object_id}) for '{self.agent_id}': close() called. Unsubscribing all listeners and signaling.")
129
- self.unsubscribe_all_listeners()
130
- await self._loop.run_in_executor(None, self._generic_stream_event_internal_q.put, _AES_INTERNAL_SENTINEL)
131
-
132
- async def all_events(self) -> AsyncIterator[StreamEvent]:
133
- """The primary method to consume all structured events from the agent."""
134
- async for event in stream_queue_items(self._generic_stream_event_internal_q, _AES_INTERNAL_SENTINEL, f"agent_{self.agent_id}_all_events"):
135
- yield event
136
-
137
- # --- Convenience Stream Methods ---
138
-
139
- async def stream_assistant_chunks(self) -> AsyncIterator[AssistantChunkData]:
140
- """A convenience async generator that yields only assistant content/reasoning chunks."""
141
- async for event in self.all_events():
142
- if event.event_type == StreamEventType.ASSISTANT_CHUNK and isinstance(event.data, AssistantChunkData):
143
- yield event.data
144
-
145
- async def stream_assistant_final_response(self) -> AsyncIterator[AssistantCompleteResponseData]:
146
- """A convenience async generator that yields only the final, complete assistant responses."""
147
- async for event in self.all_events():
148
- if event.event_type == StreamEventType.ASSISTANT_COMPLETE_RESPONSE and isinstance(event.data, AssistantCompleteResponseData):
149
- yield event.data
150
-
151
- async def stream_tool_logs(self) -> AsyncIterator[ToolInteractionLogEntryData]:
152
- """A convenience async generator that yields only tool interaction log entries."""
153
- async for event in self.all_events():
154
- if event.event_type == StreamEventType.TOOL_INTERACTION_LOG_ENTRY and isinstance(event.data, ToolInteractionLogEntryData):
155
- yield event.data
156
-
157
- async def stream_phase_transitions(self) -> AsyncIterator[AgentOperationalPhaseTransitionData]:
158
- """A convenience async generator that yields only agent phase transition data."""
159
- async for event in self.all_events():
160
- if event.event_type == StreamEventType.AGENT_OPERATIONAL_PHASE_TRANSITION and isinstance(event.data, AgentOperationalPhaseTransitionData):
161
- yield event.data
162
-
163
- async def stream_tool_approval_requests(self) -> AsyncIterator[ToolInvocationApprovalRequestedData]:
164
- """A convenience async generator that yields only requests for tool invocation approval."""
165
- async for event in self.all_events():
166
- if event.event_type == StreamEventType.TOOL_INVOCATION_APPROVAL_REQUESTED and isinstance(event.data, ToolInvocationApprovalRequestedData):
167
- yield event.data
168
-
169
- async def stream_tool_auto_executing(self) -> AsyncIterator[ToolInvocationAutoExecutingData]:
170
- """A convenience async generator that yields only events for tools being auto-executed."""
171
- async for event in self.all_events():
172
- if event.event_type == StreamEventType.TOOL_INVOCATION_AUTO_EXECUTING and isinstance(event.data, ToolInvocationAutoExecutingData):
173
- yield event.data
174
-
175
- async def stream_errors(self) -> AsyncIterator[ErrorEventData]:
176
- """A convenience async generator that yields only error events."""
177
- async for event in self.all_events():
178
- if event.event_type == StreamEventType.ERROR_EVENT and isinstance(event.data, ErrorEventData):
179
- yield event.data
4
+ __all__ = ["AgentEventStream"]
@@ -0,0 +1,16 @@
1
+ """API tool call streaming helpers."""
2
+
3
+ from .json_string_field_extractor import JsonStringFieldExtractor, FieldExtractionResult
4
+ from .file_content_streamer import (
5
+ FileContentStreamUpdate,
6
+ WriteFileContentStreamer,
7
+ PatchFileContentStreamer,
8
+ )
9
+
10
+ __all__ = [
11
+ "JsonStringFieldExtractor",
12
+ "FieldExtractionResult",
13
+ "FileContentStreamUpdate",
14
+ "WriteFileContentStreamer",
15
+ "PatchFileContentStreamer",
16
+ ]