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,316 +0,0 @@
1
- import logging
2
- import re
3
- import html
4
- from typing import TYPE_CHECKING, Dict, Any, List
5
- from dataclasses import dataclass, field
6
-
7
- from autobyteus.agent.tool_invocation import ToolInvocation
8
- from .base_parser import BaseToolUsageParser
9
-
10
- if TYPE_CHECKING:
11
- from autobyteus.llm.utils.response_types import CompleteResponse
12
-
13
- logger = logging.getLogger(__name__)
14
-
15
- # A unique UUID to use as an internal key for storing text content.
16
- # This prevents any potential collision with user-provided argument names.
17
- _INTERNAL_TEXT_KEY_UUID = "4e1a3b1e-3b2a-4d3c-9a8b-2a1c2b3d4e5f"
18
-
19
- # --- Internal Arguments Parser with State Machine ---
20
- # This entire section is now encapsulated in its own class for clarity.
21
-
22
- class _XmlArgumentsParser:
23
- """
24
- A dedicated parser for the XML content within an <arguments> tag.
25
- It encapsulates the state machine and all related logic, separating it
26
- from the higher-level tool-finding logic.
27
- """
28
-
29
- # --- Nested State Machine Components ---
30
-
31
- @dataclass
32
- class _ParsingContext:
33
- """Holds the shared state for the parsing process."""
34
- parser: '_XmlArgumentsParser'
35
- input_string: str
36
- cursor: int = 0
37
- stack: List[Any] = field(default_factory=list)
38
- content_buffer: str = ""
39
-
40
- def __post_init__(self):
41
- self.stack.append({}) # Root of arguments is a dictionary
42
-
43
- def is_eof(self) -> bool:
44
- return self.cursor >= len(self.input_string)
45
-
46
- def append_to_buffer(self, text: str):
47
- self.content_buffer += text
48
-
49
- def commit_content_buffer(self):
50
- if self.content_buffer:
51
- self.parser._commit_content(self.stack, self.content_buffer)
52
- self.content_buffer = ""
53
-
54
- class _ParserState:
55
- """Abstract base class for a state in our parser's state machine."""
56
- def handle(self, context: '_XmlArgumentsParser._ParsingContext') -> '_XmlArgumentsParser._ParserState':
57
- raise NotImplementedError
58
-
59
- class _ParsingContentState(_ParserState):
60
- """Handles accumulation of character data between tags."""
61
- def handle(self, context: '_XmlArgumentsParser._ParsingContext') -> '_XmlArgumentsParser._ParserState':
62
- if context.is_eof():
63
- return None
64
-
65
- next_tag_start = context.input_string.find('<', context.cursor)
66
-
67
- if next_tag_start == -1:
68
- context.append_to_buffer(context.input_string[context.cursor:])
69
- context.cursor = len(context.input_string)
70
- return self
71
-
72
- is_valid_tag = False
73
- if next_tag_start + 1 < len(context.input_string):
74
- next_char = context.input_string[next_tag_start + 1]
75
- if next_char.isalpha() or next_char == '/':
76
- is_valid_tag = True
77
-
78
- if is_valid_tag:
79
- content_before_tag = context.input_string[context.cursor:next_tag_start]
80
- context.append_to_buffer(content_before_tag)
81
- context.commit_content_buffer()
82
- context.cursor = next_tag_start
83
- return self.parser._ParsingTagState(self.parser)
84
- else:
85
- content_with_char = context.input_string[context.cursor : next_tag_start + 1]
86
- context.append_to_buffer(content_with_char)
87
- context.cursor = next_tag_start + 1
88
- return self
89
-
90
- def __init__(self, parser: '_XmlArgumentsParser'):
91
- self.parser = parser
92
-
93
- class _ParsingTagState(_ParserState):
94
- """Handles parsing of a tag, from '<' to '>'."""
95
- def handle(self, context: '_XmlArgumentsParser._ParsingContext') -> '_XmlArgumentsParser._ParserState':
96
- tag_content_end = context.input_string.find('>', context.cursor)
97
- if tag_content_end == -1:
98
- context.append_to_buffer(context.input_string[context.cursor:])
99
- context.cursor = len(context.input_string)
100
- return self.parser._ParsingContentState(self.parser)
101
-
102
- tag_content = context.input_string[context.cursor + 1 : tag_content_end]
103
- context.parser.process_tag(tag_content, context)
104
-
105
- context.cursor = tag_content_end + 1
106
- return self.parser._ParsingContentState(self.parser)
107
-
108
- def __init__(self, parser: '_XmlArgumentsParser'):
109
- self.parser = parser
110
-
111
- # --- Parser Implementation ---
112
-
113
- def __init__(self, xml_string: str):
114
- self.xml_string = xml_string
115
-
116
- def parse(self) -> Dict[str, Any]:
117
- """Drives the state machine to parse the XML string."""
118
- context = self._ParsingContext(parser=self, input_string=self.xml_string)
119
- state = self._ParsingContentState(self)
120
-
121
- while state and not context.is_eof():
122
- state = state.handle(context)
123
-
124
- context.commit_content_buffer()
125
-
126
- final_args = context.stack[0]
127
- self._cleanup_internal_keys(final_args)
128
- final_args = self._decode_entities_inplace(final_args)
129
- return final_args
130
-
131
- def process_tag(self, tag_content: str, context: '_ParsingContext'):
132
- STRUCTURAL_TAGS = {'arg', 'item'}
133
- stripped_content = tag_content.strip()
134
- if not stripped_content:
135
- context.append_to_buffer(f"<{tag_content}>")
136
- return
137
-
138
- is_closing = stripped_content.startswith('/')
139
- tag_name = (stripped_content[1:] if is_closing else stripped_content).split(' ')[0]
140
-
141
- if tag_name in STRUCTURAL_TAGS:
142
- if is_closing:
143
- self._handle_closing_tag(context.stack)
144
- else:
145
- self._handle_opening_tag(context.stack, tag_content)
146
- else:
147
- context.append_to_buffer(f"<{tag_content}>")
148
-
149
- def _commit_content(self, stack: List[Any], content: str):
150
- trimmed_content = content.strip()
151
- if not trimmed_content and '<' not in content and '>' not in content:
152
- return
153
-
154
- top = stack[-1]
155
- if isinstance(top, dict):
156
- top[_INTERNAL_TEXT_KEY_UUID] = top.get(_INTERNAL_TEXT_KEY_UUID, '') + content
157
-
158
- def _handle_opening_tag(self, stack: List[Any], tag_content: str):
159
- parent = stack[-1]
160
-
161
- if tag_content.strip().startswith('arg'):
162
- name_match = re.search(r'name="([^"]+)"', tag_content)
163
- if name_match and isinstance(parent, dict):
164
- arg_name = name_match.group(1)
165
- new_container = {}
166
- parent[arg_name] = new_container
167
- stack.append(new_container)
168
-
169
- elif tag_content.strip().startswith('item'):
170
- if isinstance(parent, dict):
171
- grandparent = stack[-2]
172
- parent_key = next((k for k, v in grandparent.items() if v is parent), None)
173
- if parent_key:
174
- new_list = []
175
- grandparent[parent_key] = new_list
176
- stack[-1] = new_list
177
- parent = new_list
178
-
179
- if isinstance(parent, list):
180
- new_item_container = {}
181
- parent.append(new_item_container)
182
- stack.append(new_item_container)
183
-
184
- def _handle_closing_tag(self, stack: List[Any]):
185
- if len(stack) > 1:
186
- top = stack.pop()
187
- parent = stack[-1]
188
-
189
- is_primitive = False
190
- if isinstance(top, dict):
191
- keys = top.keys()
192
- if not keys or (len(keys) == 1 and _INTERNAL_TEXT_KEY_UUID in keys):
193
- is_primitive = True
194
-
195
- if is_primitive:
196
- value = top.get(_INTERNAL_TEXT_KEY_UUID, '')
197
- if isinstance(parent, list):
198
- try:
199
- idx = parent.index(top)
200
- parent[idx] = value
201
- except ValueError:
202
- logger.warning("Could not find item to collapse in parent list.")
203
- elif isinstance(parent, dict):
204
- parent_key = next((k for k, v in parent.items() if v is top), None)
205
- if parent_key:
206
- parent[parent_key] = value
207
-
208
- def _cleanup_internal_keys(self, data: Any):
209
- if isinstance(data, dict):
210
- if _INTERNAL_TEXT_KEY_UUID in data and len(data) > 1:
211
- del data[_INTERNAL_TEXT_KEY_UUID]
212
- for value in data.values():
213
- self._cleanup_internal_keys(value)
214
- elif isinstance(data, list):
215
- for item in data:
216
- self._cleanup_internal_keys(item)
217
-
218
- def _decode_entities_inplace(self, data: Any):
219
- if isinstance(data, dict):
220
- for key, value in list(data.items()):
221
- data[key] = self._decode_entities_inplace(value)
222
- return data
223
- if isinstance(data, list):
224
- for index, item in enumerate(data):
225
- data[index] = self._decode_entities_inplace(item)
226
- return data
227
- if isinstance(data, str):
228
- return html.unescape(data)
229
- return data
230
-
231
-
232
- # --- Main Parser Class ---
233
-
234
- class DefaultXmlToolUsageParser(BaseToolUsageParser):
235
- """
236
- Parses LLM responses for tool usage commands formatted as XML.
237
- This class is responsible for finding <tool> blocks and delegating the
238
- parsing of their arguments to the specialized _XmlArgumentsParser.
239
- """
240
-
241
- def get_name(self) -> str:
242
- return "default_xml_tool_usage_parser"
243
-
244
- def parse(self, response: 'CompleteResponse') -> List[ToolInvocation]:
245
- text = response.content
246
- invocations: List[ToolInvocation] = []
247
- i = 0
248
-
249
- while i < len(text):
250
- try:
251
- i = text.index('<tool', i)
252
- except ValueError:
253
- break
254
-
255
- open_tag_end = text.find('>', i)
256
- if open_tag_end == -1: break
257
-
258
- open_tag_content = text[i:open_tag_end+1]
259
- name_match = re.search(r'name="([^"]+)"', open_tag_content)
260
- if not name_match:
261
- i = open_tag_end + 1
262
- continue
263
-
264
- tool_name = name_match.group(1)
265
- logger.debug(f"--- Found tool '{tool_name}' at index {i} ---")
266
-
267
- cursor = open_tag_end + 1
268
- nesting_level = 1
269
- content_end = -1
270
-
271
- while cursor < len(text):
272
- next_open = text.find('<tool', cursor)
273
- next_close = text.find('</tool>', cursor)
274
-
275
- if next_close == -1: break
276
-
277
- if next_open != -1 and next_open < next_close:
278
- nesting_level += 1
279
- end_of_nested_open = text.find('>', next_open)
280
- if end_of_nested_open == -1: break
281
- cursor = end_of_nested_open + 1
282
- else:
283
- nesting_level -= 1
284
- if nesting_level == 0:
285
- content_end = next_close
286
- break
287
- cursor = next_close + len('</tool>')
288
-
289
- if content_end == -1:
290
- logger.warning(f"Malformed XML for tool '{tool_name}': could not find matching </tool> tag.")
291
- i = open_tag_end + 1
292
- continue
293
-
294
- tool_content = text[open_tag_end+1:content_end]
295
- args_match = re.search(r'<arguments>(.*)</arguments>', tool_content, re.DOTALL)
296
-
297
- arguments = {}
298
- if args_match:
299
- arguments_xml = args_match.group(1)
300
- try:
301
- # Delegate parsing to the specialized class
302
- arguments = self._parse_arguments(arguments_xml)
303
- except Exception as e:
304
- logger.error(f"Arguments parser failed for tool '{tool_name}': {e}", exc_info=True)
305
-
306
- invocations.append(ToolInvocation(name=tool_name, arguments=arguments))
307
- i = content_end + len('</tool>')
308
-
309
- return invocations
310
-
311
- def _parse_arguments(self, xml_string: str) -> Dict[str, Any]:
312
- """
313
- Delegates parsing of an arguments XML string to the dedicated parser class.
314
- """
315
- parser = _XmlArgumentsParser(xml_string)
316
- return parser.parse()
@@ -1,13 +0,0 @@
1
- # file: autobyteus/autobyteus/tools/usage/parsers/exceptions.py
2
- """
3
- Custom exceptions for the tool usage parsing module.
4
- """
5
-
6
- class ToolUsageParseException(Exception):
7
- """
8
- Raised when a tool usage parser fails to parse an LLM response due to
9
- malformed content or other parsing errors.
10
- """
11
- def __init__(self, message: str, original_exception: Exception = None):
12
- super().__init__(message)
13
- self.original_exception = original_exception
@@ -1,77 +0,0 @@
1
- # file: autobyteus/autobyteus/tools/usage/parsers/gemini_json_tool_usage_parser.py
2
- import json
3
- import logging
4
- from typing import TYPE_CHECKING, List, Dict
5
-
6
- from autobyteus.agent.tool_invocation import ToolInvocation
7
- from .base_parser import BaseToolUsageParser
8
- from .exceptions import ToolUsageParseException
9
- from ._json_extractor import _find_json_blobs
10
- from ._string_decoders import decode_html_entities
11
-
12
- if TYPE_CHECKING:
13
- from autobyteus.llm.utils.response_types import CompleteResponse
14
-
15
- logger = logging.getLogger(__name__)
16
-
17
- class GeminiJsonToolUsageParser(BaseToolUsageParser):
18
- """
19
- Parses LLM responses for tool usage commands formatted in the Google Gemini style.
20
- It expects a JSON object with "name" and "args" keys. It robustly extracts
21
- all potential JSON objects from the response and can handle both a single
22
- tool call object or a list of tool call objects.
23
- """
24
- def get_name(self) -> str:
25
- return "gemini_json_tool_usage_parser"
26
-
27
- def parse(self, response: 'CompleteResponse') -> List[ToolInvocation]:
28
- response_text = response.content
29
- json_blobs = _find_json_blobs(response_text)
30
- if not json_blobs:
31
- return []
32
-
33
- invocations: List[ToolInvocation] = []
34
- for blob in json_blobs:
35
- try:
36
- data = json.loads(blob)
37
-
38
- tool_call_list: List[Dict] = []
39
- if isinstance(data, list):
40
- # The blob is a list of tool calls, e.g., [{"name": ..., "args": ...}]
41
- tool_call_list = data
42
- elif isinstance(data, dict) and "name" in data and "args" in data:
43
- # The blob is a single tool call object, e.g., {"name": ..., "args": ...}
44
- tool_call_list = [data]
45
- else:
46
- # Not a recognized format, skip this blob.
47
- logger.debug(f"JSON blob is not in a recognized Gemini tool call format: {blob[:200]}")
48
- continue
49
-
50
- for call_data in tool_call_list:
51
- if not (isinstance(call_data, dict) and "name" in call_data and "args" in call_data):
52
- logger.debug(f"Skipping malformed item in Gemini tool call list: {call_data}")
53
- continue
54
-
55
- tool_name = call_data.get("name")
56
- arguments = call_data.get("args")
57
-
58
- if tool_name and isinstance(tool_name, str) and isinstance(arguments, dict):
59
- decoded_tool_name = decode_html_entities(tool_name)
60
- decoded_arguments = decode_html_entities(arguments)
61
- # Pass id=None to trigger deterministic ID generation in ToolInvocation
62
- tool_invocation = ToolInvocation(name=decoded_tool_name, arguments=decoded_arguments)
63
- invocations.append(tool_invocation)
64
- logger.info(f"Successfully parsed Gemini JSON tool invocation for '{tool_name}'.")
65
- else:
66
- logger.debug(f"Skipping malformed Gemini tool call data: {call_data}")
67
-
68
- except json.JSONDecodeError:
69
- logger.debug(f"Could not parse extracted text as JSON in {self.get_name()}. Blob: {blob[:200]}")
70
- # Not a tool call, ignore.
71
- continue
72
- except Exception as e:
73
- error_msg = f"Unexpected error while parsing JSON blob in {self.get_name()}: {e}. Blob: {blob[:200]}"
74
- logger.error(error_msg, exc_info=True)
75
- raise ToolUsageParseException(error_msg, original_exception=e)
76
-
77
- return invocations
@@ -1,149 +0,0 @@
1
- # file: autobyteus/autobyteus/tools/usage/parsers/openai_json_tool_usage_parser.py
2
- import json
3
- import logging
4
- from typing import TYPE_CHECKING, List, Optional, Any, Dict
5
-
6
- from autobyteus.agent.tool_invocation import ToolInvocation
7
- from .base_parser import BaseToolUsageParser
8
- from .exceptions import ToolUsageParseException
9
- from ._json_extractor import _find_json_blobs
10
- from ._string_decoders import decode_html_entities
11
-
12
- if TYPE_CHECKING:
13
- from autobyteus.llm.utils.response_types import CompleteResponse
14
-
15
- logger = logging.getLogger(__name__)
16
-
17
- class OpenAiJsonToolUsageParser(BaseToolUsageParser):
18
- """
19
- Parses LLM responses for tool usage commands formatted in various JSON
20
- styles commonly produced by OpenAI and similar models.
21
-
22
- This parser is highly flexible and robustly handles multiple formats:
23
- - A root object with a "tool_calls" or "tools" key containing a list of tool calls.
24
- - A root object with a single "tool" key.
25
- - A root object that is itself a single tool call.
26
- - A raw list of tool calls.
27
- - Tool call arguments can be either a JSON object or a stringified JSON.
28
- """
29
- def get_name(self) -> str:
30
- return "openai_json_tool_usage_parser"
31
-
32
- def parse(self, response: 'CompleteResponse') -> List[ToolInvocation]:
33
- response_text = response.content
34
- invocations: List[ToolInvocation] = []
35
-
36
- # Use a robust method to find all potential JSON blobs in the text
37
- json_blobs = _find_json_blobs(response_text)
38
- if not json_blobs:
39
- logger.debug("No valid JSON object could be extracted from the response content.")
40
- return invocations
41
-
42
- for blob in json_blobs:
43
- try:
44
- data = json.loads(blob)
45
-
46
- # Determine the structure of the JSON data
47
- tool_calls_data: List[Dict[str, Any]] = []
48
- if isinstance(data, list):
49
- # Format: [{"function":...}, {"function":...}]
50
- tool_calls_data = data
51
- elif isinstance(data, dict):
52
- # Format: {"tool_calls": [...]} or {"tools": [...]}
53
- if "tool_calls" in data and isinstance(data["tool_calls"], list):
54
- tool_calls_data = data["tool_calls"]
55
- elif "tools" in data and isinstance(data["tools"], list):
56
- tool_calls_data = data["tools"]
57
- # Format: {"tool": {...}}
58
- elif "tool" in data and isinstance(data["tool"], dict):
59
- tool_calls_data = [data["tool"]]
60
- # Format: {"function": ...}
61
- else:
62
- tool_calls_data = [data]
63
-
64
- if not tool_calls_data:
65
- logger.debug(f"JSON response does not match any expected tool call format. Content: {blob[:200]}")
66
- continue
67
-
68
- for call_data in tool_calls_data:
69
- invocation = self._parse_tool_call_object(call_data)
70
- if invocation:
71
- invocations.append(invocation)
72
-
73
- except json.JSONDecodeError:
74
- # This can happen if a blob is not a tool call (e.g., just example JSON).
75
- # We can safely ignore these.
76
- logger.debug(f"Could not parse extracted text as JSON in {self.get_name()}. Blob: {blob[:200]}")
77
- continue
78
- except Exception as e:
79
- # If we're here, it's likely a valid JSON but with unexpected structure.
80
- # It's safer to raise this for upstream handling.
81
- error_msg = f"Unexpected error while parsing JSON blob: {e}. Blob: {blob[:200]}"
82
- logger.error(error_msg, exc_info=True)
83
- raise ToolUsageParseException(error_msg, original_exception=e)
84
-
85
- return invocations
86
-
87
- def _parse_tool_call_object(self, call_data: Dict[str, Any]) -> Optional[ToolInvocation]:
88
- """
89
- Parses a single tool call object, which can have various structures.
90
- - {"function": {"name": str, "arguments": str_json_or_dict}}
91
- - {"name": str, "arguments": dict}
92
- """
93
- if not isinstance(call_data, dict):
94
- logger.debug(f"Skipping non-dictionary item in tool call list: {call_data}")
95
- return None
96
-
97
- function_data: Optional[Dict] = call_data.get("function")
98
- if isinstance(function_data, dict):
99
- # Standard OpenAI format: {"function": {"name": ..., "arguments": ...}}
100
- tool_name = function_data.get("name")
101
- arguments_raw = function_data.get("arguments")
102
- else:
103
- # Handle flattened format: {"name": ..., "arguments": ...}
104
- tool_name = call_data.get("name")
105
- arguments_raw = call_data.get("arguments")
106
-
107
- if not tool_name or not isinstance(tool_name, str):
108
- logger.debug(f"Skipping malformed tool call (missing or invalid 'name'): {call_data}")
109
- return None
110
-
111
- arguments: Dict[str, Any]
112
- if arguments_raw is None:
113
- arguments = {}
114
- elif isinstance(arguments_raw, dict):
115
- # Arguments are already a dictionary
116
- arguments = arguments_raw
117
- elif isinstance(arguments_raw, str):
118
- # Arguments are a stringified JSON
119
- arg_string = arguments_raw.strip()
120
- if not arg_string:
121
- arguments = {}
122
- else:
123
- try:
124
- parsed_args = json.loads(arg_string)
125
- if not isinstance(parsed_args, dict):
126
- logger.error(f"Parsed 'arguments' string for tool '{tool_name}' must be a dictionary, but got {type(parsed_args)}.")
127
- return None
128
- arguments = parsed_args
129
- except json.JSONDecodeError as e:
130
- # If it's a string but not valid JSON, it's a hard error.
131
- raise ToolUsageParseException(
132
- f"Failed to parse 'arguments' string for tool '{tool_name}': {arguments_raw}",
133
- original_exception=e
134
- )
135
- else:
136
- # Any other type for arguments is invalid
137
- logger.error(f"Skipping tool call with invalid 'arguments' type. Expected dict or string, got {type(arguments_raw)}: {call_data}")
138
- return None
139
-
140
- try:
141
- # The ToolInvocation constructor will generate a deterministic ID if 'id' is None.
142
- decoded_tool_name = decode_html_entities(tool_name)
143
- decoded_arguments = decode_html_entities(arguments)
144
- tool_invocation = ToolInvocation(name=decoded_tool_name, arguments=decoded_arguments, id=None)
145
- logger.info(f"Successfully parsed OpenAI-style JSON tool invocation for '{tool_name}'.")
146
- return tool_invocation
147
- except Exception as e:
148
- logger.error(f"Unexpected error creating ToolInvocation for tool '{tool_name}': {e}", exc_info=True)
149
- return None
@@ -1,59 +0,0 @@
1
- # file: autobyteus/autobyteus/tools/usage/parsers/provider_aware_tool_usage_parser.py
2
- import logging
3
- from typing import TYPE_CHECKING, List
4
-
5
- from .exceptions import ToolUsageParseException
6
-
7
- # The import of ToolUsageParserRegistry is deferred to break the circular dependency.
8
- # It is imported at the top level only for static type analysis.
9
- if TYPE_CHECKING:
10
- from autobyteus.agent.context import AgentContext
11
- from autobyteus.llm.utils.response_types import CompleteResponse
12
- from autobyteus.agent.tool_invocation import ToolInvocation
13
- from autobyteus.tools.usage.registries.tool_usage_parser_registry import ToolUsageParserRegistry
14
-
15
- logger = logging.getLogger(__name__)
16
-
17
- class ProviderAwareToolUsageParser:
18
- """
19
- A high-level orchestrator that selects and uses the correct tool usage parser
20
- based on the agent's LLM provider by consulting the central ToolUsageParserRegistry.
21
- """
22
- def __init__(self):
23
- # Local import to break the circular dependency at module load time.
24
- from autobyteus.tools.usage.registries.tool_usage_parser_registry import ToolUsageParserRegistry
25
- self._parser_registry: 'ToolUsageParserRegistry' = ToolUsageParserRegistry()
26
- logger.debug("ProviderAwareToolUsageParser initialized.")
27
-
28
- def parse(self, response: 'CompleteResponse', context: 'AgentContext') -> List['ToolInvocation']:
29
- """
30
- Selects the correct underlying parser from the registry, parses the response,
31
- and returns a list of tool invocations.
32
-
33
- Args:
34
- response: The CompleteResponse object from the LLM.
35
- context: The agent's context, used to determine configuration.
36
-
37
- Returns:
38
- A list of ToolInvocation objects. Returns an empty list if no
39
- valid tool calls are found.
40
- """
41
- llm_provider = None
42
- if context.llm_instance and context.llm_instance.model:
43
- llm_provider = context.llm_instance.model.provider
44
- else:
45
- logger.warning(f"Agent '{context.agent_id}': LLM instance or model not available. Cannot determine provider for tool response parsing.")
46
-
47
- # Retrieve the override flag from the agent's configuration.
48
- use_xml_tool_format = context.config.use_xml_tool_format
49
-
50
- # Get the correct parser from the registry, passing the override flag.
51
- parser = self._parser_registry.get_parser(llm_provider, use_xml_tool_format=use_xml_tool_format)
52
-
53
- logger.debug(f"ProviderAwareToolUsageParser selected delegate parser '{parser.get_name()}' for LLM provider '{llm_provider.name if llm_provider else 'Unknown'}'.")
54
-
55
- try:
56
- return parser.parse(response)
57
- except ToolUsageParseException:
58
- # Propagate the exception upwards to be handled by the caller.
59
- raise
@@ -1,62 +0,0 @@
1
- # file: autobyteus/autobyteus/tools/usage/registries/tool_usage_parser_registry.py
2
- import logging
3
- from typing import Dict, Optional
4
-
5
- from autobyteus.llm.providers import LLMProvider
6
- from autobyteus.utils.singleton import SingletonMeta
7
- from autobyteus.tools.usage.parsers import (
8
- BaseToolUsageParser,
9
- DefaultJsonToolUsageParser,
10
- OpenAiJsonToolUsageParser,
11
- GeminiJsonToolUsageParser,
12
- DefaultXmlToolUsageParser
13
- )
14
-
15
- logger = logging.getLogger(__name__)
16
-
17
- class ToolUsageParserRegistry(metaclass=SingletonMeta):
18
- """
19
- A consolidated registry that maps an LLMProvider directly to its required
20
- tool usage parser, encapsulating the logic of which provider uses which format.
21
- """
22
-
23
- def __init__(self):
24
- self._parsers: Dict[LLMProvider, BaseToolUsageParser] = {
25
- # JSON-based providers
26
- LLMProvider.OPENAI: OpenAiJsonToolUsageParser(),
27
- LLMProvider.MISTRAL: OpenAiJsonToolUsageParser(),
28
- LLMProvider.DEEPSEEK: OpenAiJsonToolUsageParser(),
29
- LLMProvider.GROK: OpenAiJsonToolUsageParser(),
30
- LLMProvider.GEMINI: GeminiJsonToolUsageParser(),
31
-
32
- # XML-based providers
33
- LLMProvider.ANTHROPIC: DefaultXmlToolUsageParser(),
34
- }
35
- # A default parser for any provider not explicitly listed (defaults to JSON)
36
- self._default_parser = DefaultJsonToolUsageParser()
37
- # A specific parser for the XML override
38
- self._xml_override_parser = DefaultXmlToolUsageParser()
39
- logger.info("ToolUsageParserRegistry initialized with direct provider-to-parser mappings.")
40
-
41
- def get_parser(self, provider: Optional[LLMProvider], use_xml_tool_format: bool = False) -> BaseToolUsageParser:
42
- """
43
- Retrieves the appropriate tool usage parser for a given provider, honoring the XML override.
44
-
45
- Args:
46
- provider: The LLMProvider enum member.
47
- use_xml_tool_format: If True, forces the use of the XML parser.
48
-
49
- Returns:
50
- The corresponding BaseToolUsageParser instance.
51
- """
52
- if use_xml_tool_format:
53
- logger.debug("XML tool format is forced by configuration. Returning XML parser.")
54
- return self._xml_override_parser
55
-
56
- if provider and provider in self._parsers:
57
- parser = self._parsers[provider]
58
- logger.debug(f"Found specific tool usage parser for provider {provider.name}: {parser.get_name()}")
59
- return parser
60
-
61
- logger.debug(f"No specific tool usage parser for provider {provider.name if provider else 'Unknown'}. Returning default parser.")
62
- return self._default_parser