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
@@ -15,17 +15,28 @@ from .tool_config import ToolConfig # Configuration data object, primarily for c
15
15
  from .tool_origin import ToolOrigin
16
16
  from .tool_category import ToolCategory
17
17
 
18
+ # Tool Formatting Registration Support
19
+ # Tool Formatting Registration Support
20
+ from autobyteus.tools.usage.registries.tool_formatting_registry import ToolFormattingRegistry, register_tool_formatter
21
+ from autobyteus.tools.usage.registries.tool_formatter_pair import ToolFormatterPair
22
+ from autobyteus.tools.usage.formatters.base_formatter import BaseSchemaFormatter, BaseExampleFormatter
23
+
24
+
18
25
  logger = logging.getLogger(__name__)
19
26
 
20
27
  # --- Re-export specific tools for easier access ---
21
28
 
22
29
  # Functional tools (decorated functions are now instances)
23
- from .bash.bash_executor import bash_executor
24
30
  from .file.read_file import read_file
25
31
  from .file.write_file import write_file
26
- from .file.edit_file import edit_file
27
- from .file.search_files import search_files
28
- from .file.list_directory import list_directory
32
+ from .file.patch_file import patch_file
33
+ from .skill.load_skill import load_skill
34
+
35
+ # Terminal tools (PTY-based stateful terminal)
36
+ from .terminal.tools.run_bash import run_bash
37
+ from .terminal.tools.start_background_process import start_background_process
38
+ from .terminal.tools.get_process_output import get_process_output
39
+ from .terminal.tools.stop_background_process import stop_background_process
29
40
 
30
41
  # General Class-based tools
31
42
  try:
@@ -33,7 +44,6 @@ try:
33
44
  except ModuleNotFoundError as import_err:
34
45
  logger.warning("Search tool not available: %s", import_err)
35
46
  Search = None
36
- from .timer import Timer
37
47
  try:
38
48
  from .multimedia.image_tools import GenerateImageTool, EditImageTool
39
49
  except ModuleNotFoundError as import_err:
@@ -51,33 +61,14 @@ except ModuleNotFoundError as import_err:
51
61
  logger.warning("Download media tool not available: %s", import_err)
52
62
  DownloadMediaTool = None
53
63
 
54
- # Standalone Browser tools
55
- try:
56
- from .browser.standalone.navigate_to import NavigateTo as StandaloneNavigateTo # Alias to avoid name clash
57
- from .browser.standalone.webpage_reader import WebPageReader as StandaloneWebPageReader # Alias
58
- from .browser.standalone.webpage_screenshot_taker import WebPageScreenshotTaker as StandaloneWebPageScreenshotTaker # Alias
59
- from .browser.standalone.webpage_image_downloader import WebPageImageDownloader
60
- from .browser.standalone.web_page_pdf_generator import WebPagePDFGenerator
61
- except ModuleNotFoundError as import_err:
62
- logger.warning('Standalone browser tools not available: %s', import_err)
63
- StandaloneNavigateTo = None
64
- StandaloneWebPageReader = None
65
- StandaloneWebPageScreenshotTaker = None
66
- WebPageImageDownloader = None
67
- WebPagePDFGenerator = None
68
-
69
- # Session-Aware Browser tools
64
+ # Web tools
70
65
  try:
71
- from .browser.session_aware.browser_session_aware_navigate_to import BrowserSessionAwareNavigateTo
72
- from .browser.session_aware.browser_session_aware_web_element_trigger import BrowserSessionAwareWebElementTrigger
73
- from .browser.session_aware.browser_session_aware_webpage_reader import BrowserSessionAwareWebPageReader
74
- from .browser.session_aware.browser_session_aware_webpage_screenshot_taker import BrowserSessionAwareWebPageScreenshotTaker
66
+ from .web.read_url_tool import ReadUrl
75
67
  except ModuleNotFoundError as import_err:
76
- logger.warning('Session-aware browser tools not available: %s', import_err)
77
- BrowserSessionAwareNavigateTo = None
78
- BrowserSessionAwareWebElementTrigger = None
79
- BrowserSessionAwareWebPageReader = None
80
- BrowserSessionAwareWebPageScreenshotTaker = None
68
+ logger.warning("ReadUrl tool not available: %s", import_err)
69
+ ReadUrl = None
70
+
71
+
81
72
 
82
73
 
83
74
  __all__ = [
@@ -92,31 +83,27 @@ __all__ = [
92
83
  "ToolCategory",
93
84
 
94
85
  # Re-exported functional tool instances
95
- "bash_executor",
86
+ "run_bash",
87
+ "start_background_process",
88
+ "get_process_output",
89
+ "stop_background_process",
96
90
  "read_file",
97
91
  "write_file",
98
- "edit_file",
99
- "search_files",
100
- "list_directory",
92
+ "patch_file",
93
+ "load_skill",
101
94
 
102
95
  # Re-exported general class-based tools
103
96
  "Search",
104
- "Timer",
105
97
  "GenerateImageTool",
106
98
  "EditImageTool",
107
99
  "ReadMediaFile",
108
100
  "DownloadMediaTool",
109
101
 
110
- # Re-exported Standalone Browser tools
111
- "StandaloneNavigateTo",
112
- "StandaloneWebPageReader",
113
- "StandaloneWebPageScreenshotTaker",
114
- "WebPageImageDownloader",
115
- "WebPagePDFGenerator",
116
-
117
- # Re-exported Session-Aware Browser tools
118
- "BrowserSessionAwareNavigateTo",
119
- "BrowserSessionAwareWebElementTrigger",
120
- "BrowserSessionAwareWebPageReader",
121
- "BrowserSessionAwareWebPageScreenshotTaker",
102
+ # Re-exported Web tools
103
+ "ReadUrl",
104
+
105
+ # Tool Formatting
106
+ "register_tool_formatter",
107
+ "BaseSchemaFormatter",
108
+ "BaseExampleFormatter",
122
109
  ]
@@ -174,6 +174,13 @@ class BaseTool(ABC, EventEmitter, metaclass=ToolMeta):
174
174
  async def _execute(self, context: 'AgentContext', **kwargs) -> Any:
175
175
  raise NotImplementedError("Subclasses must implement the '_execute' method.")
176
176
 
177
+ async def cleanup(self) -> None:
178
+ """
179
+ Lifecycle hook invoked during agent shutdown to release resources held by the tool.
180
+ Default implementation is a no-op.
181
+ """
182
+ return None
183
+
177
184
  @classmethod
178
185
  def tool_usage(cls) -> str:
179
186
  logger.warning("BaseTool.tool_usage() is deprecated. Tool usage is now generated by formatters.")
@@ -1,13 +1,9 @@
1
- from .edit_file import edit_file
1
+ from .patch_file import patch_file
2
2
  from .read_file import read_file
3
3
  from .write_file import write_file
4
- from .search_files import search_files
5
- from .list_directory import list_directory
6
4
 
7
5
  __all__ = [
8
- "edit_file",
6
+ "patch_file",
9
7
  "read_file",
10
8
  "write_file",
11
- "search_files",
12
- "list_directory",
13
9
  ]
@@ -0,0 +1,149 @@
1
+ import os
2
+ import logging
3
+ from typing import TYPE_CHECKING, List
4
+
5
+ from pydantic import Field
6
+
7
+ from autobyteus.tools.functional_tool import tool
8
+ from autobyteus.tools.tool_category import ToolCategory
9
+ from autobyteus.utils.diff_utils import apply_unified_diff, PatchApplicationError
10
+
11
+ if TYPE_CHECKING:
12
+ from autobyteus.agent.context import AgentContext
13
+
14
+ logger = logging.getLogger(__name__)
15
+
16
+
17
+ def _resolve_file_path(context: 'AgentContext', path: str) -> str:
18
+ """Resolves an absolute path for the given input, using the agent workspace when needed."""
19
+ if os.path.isabs(path):
20
+ final_path = path
21
+ logger.debug("patch_file: provided path '%s' is absolute.", path)
22
+ else:
23
+ if not context.workspace:
24
+ error_msg = ("Relative path '%s' provided, but no workspace is configured for agent '%s'. "
25
+ "A workspace is required to resolve relative paths.")
26
+ logger.error(error_msg, path, context.agent_id)
27
+ raise ValueError(error_msg % (path, context.agent_id))
28
+ base_path = context.workspace.get_base_path()
29
+ if not base_path or not isinstance(base_path, str):
30
+ error_msg = ("Agent '%s' has a configured workspace, but it provided an invalid base path ('%s'). "
31
+ "Cannot resolve relative path '%s'.")
32
+ logger.error(error_msg, context.agent_id, base_path, path)
33
+ raise ValueError(error_msg % (context.agent_id, base_path, path))
34
+ final_path = os.path.join(base_path, path)
35
+ logger.debug("patch_file: resolved relative path '%s' against workspace base '%s' to '%s'.", path, base_path, final_path)
36
+
37
+ normalized_path = os.path.normpath(final_path)
38
+ logger.debug("patch_file: normalized path to '%s'.", normalized_path)
39
+ return normalized_path
40
+
41
+
42
+ @tool(name="patch_file", category=ToolCategory.FILE_SYSTEM)
43
+ async def patch_file(
44
+ context: 'AgentContext',
45
+ path: str = Field(..., description="Path to the target file."),
46
+ patch: str = Field(
47
+ ...,
48
+ description=(
49
+ "Unified diff hunks describing edits to apply. "
50
+ "Example:\n"
51
+ "--- a/sample.txt\n"
52
+ "+++ b/sample.txt\n"
53
+ "@@ -1,2 +1,2 @@\n"
54
+ "-old line\n"
55
+ "+new line\n"
56
+ " unchanged line"
57
+ ),
58
+ ),
59
+ ) -> str:
60
+ """Applies a unified diff patch to update a text file without overwriting unrelated content.
61
+
62
+ Args:
63
+ path: Path to the target file. Relative paths are resolved against the agent workspace when available.
64
+ patch: Unified diff patch describing the edits to apply.
65
+
66
+ Raises:
67
+ FileNotFoundError: If the file does not exist.
68
+ PatchApplicationError: If the patch content cannot be applied cleanly.
69
+ IOError: If file reading or writing fails.
70
+ """
71
+ logger.debug("patch_file: requested patch for agent '%s' on path '%s'.", context.agent_id, path)
72
+ return_path = os.path.normpath(path)
73
+
74
+ # Detailed logging for debugging patch content
75
+ logger.info("patch_file: ===== PATCH ARGUMENT DEBUG START =====")
76
+ logger.info("patch_file: raw patch repr: %r", patch)
77
+ logger.info("patch_file: patch length: %d chars", len(patch) if patch else 0)
78
+ patch_lines = patch.splitlines(keepends=True) if patch else []
79
+ for i, line in enumerate(patch_lines, 1):
80
+ prefix = line[0] if line else '<empty>'
81
+ logger.info("patch_file: line %d: prefix=%r content=%r", i, prefix, line)
82
+ logger.info("patch_file: ===== PATCH ARGUMENT DEBUG END =====")
83
+
84
+ final_path = _resolve_file_path(context, path)
85
+
86
+ file_exists = os.path.exists(final_path)
87
+ if not file_exists:
88
+ raise FileNotFoundError(f"The file at resolved path {final_path} does not exist.")
89
+
90
+ try:
91
+ original_lines: List[str]
92
+ if file_exists:
93
+ with open(final_path, 'r', encoding='utf-8') as source:
94
+ original_lines = source.read().splitlines(keepends=True)
95
+ else:
96
+ original_lines = []
97
+
98
+ # Log original file content for comparison
99
+ logger.info("patch_file: ===== ORIGINAL FILE DEBUG START =====")
100
+ for i, line in enumerate(original_lines, 1):
101
+ logger.info("patch_file: original line %d: %r", i, line)
102
+ logger.info("patch_file: ===== ORIGINAL FILE DEBUG END =====")
103
+
104
+ patched_lines = None
105
+ patch_error = None
106
+ retry_strategies = [
107
+ (0, False),
108
+ (1, False),
109
+ (1, True),
110
+ (2, True),
111
+ ]
112
+ for fuzz_factor, ignore_whitespace in retry_strategies:
113
+ try:
114
+ patched_lines = apply_unified_diff(
115
+ original_lines,
116
+ patch,
117
+ fuzz_factor=fuzz_factor,
118
+ ignore_whitespace=ignore_whitespace,
119
+ )
120
+ if (fuzz_factor, ignore_whitespace) != (0, False):
121
+ logger.info(
122
+ "patch_file: applied with fuzz=%d ignore_whitespace=%s.",
123
+ fuzz_factor,
124
+ ignore_whitespace,
125
+ )
126
+ break
127
+ except PatchApplicationError as patch_err:
128
+ patch_error = patch_err
129
+ logger.warning(
130
+ "patch_file: patch failed with fuzz=%d ignore_whitespace=%s: %s",
131
+ fuzz_factor,
132
+ ignore_whitespace,
133
+ patch_err,
134
+ )
135
+ continue
136
+ if patched_lines is None:
137
+ raise patch_error or PatchApplicationError("Patch could not be applied.")
138
+
139
+ with open(final_path, 'w', encoding='utf-8') as destination:
140
+ destination.writelines(patched_lines)
141
+
142
+ logger.info("patch_file: successfully applied patch to '%s'.", final_path)
143
+ return f"File patched successfully at {return_path}"
144
+ except PatchApplicationError as patch_err:
145
+ logger.error("patch_file: failed to apply patch to '%s': %s", final_path, patch_err, exc_info=True)
146
+ raise patch_err
147
+ except Exception as exc: # pragma: no cover - general safeguard
148
+ logger.error("patch_file: unexpected error while patching '%s': %s", final_path, exc, exc_info=True)
149
+ raise IOError(f"Could not patch file at '{final_path}': {exc}")
@@ -1,6 +1,8 @@
1
1
  import os
2
2
  import logging
3
- from typing import TYPE_CHECKING
3
+ from typing import TYPE_CHECKING, Optional
4
+
5
+ from pydantic import Field
4
6
 
5
7
  from autobyteus.tools import tool
6
8
  from autobyteus.tools.tool_category import ToolCategory
@@ -11,15 +13,32 @@ if TYPE_CHECKING:
11
13
  logger = logging.getLogger(__name__)
12
14
 
13
15
  @tool(name="read_file", category=ToolCategory.FILE_SYSTEM)
14
- async def read_file(context: 'AgentContext', path: str) -> str:
16
+ async def read_file(
17
+ context: 'AgentContext',
18
+ path: str,
19
+ start_line: Optional[int] = None,
20
+ end_line: Optional[int] = None,
21
+ include_line_numbers: bool = Field(
22
+ True,
23
+ description="If true, prefix each returned line with its line number (default).",
24
+ ),
25
+ ) -> str:
15
26
  """
16
- Reads content from a specified file.
27
+ Reads content from a specified file. Supports optional 1-based inclusive line ranges via start_line/end_line.
28
+ Each returned line is prefixed with its line number when include_line_numbers is true.
17
29
  'path' is the path to the file. If relative, it must be resolved against a configured agent workspace.
18
- Raises ValueError if a relative path is given without a valid workspace.
30
+ Raises ValueError if a relative path is given without a valid workspace or if line range arguments are invalid.
19
31
  Raises FileNotFoundError if the file does not exist.
20
32
  Raises IOError if file reading fails for other reasons.
21
33
  """
22
34
  logger.debug(f"Functional read_file tool for agent {context.agent_id}, initial path: {path}")
35
+
36
+ if start_line is not None and start_line < 1:
37
+ raise ValueError(f"start_line must be >= 1 when provided; got {start_line}.")
38
+ if end_line is not None and end_line < 1:
39
+ raise ValueError(f"end_line must be >= 1 when provided; got {end_line}.")
40
+ if start_line is not None and end_line is not None and end_line < start_line:
41
+ raise ValueError(f"end_line ({end_line}) must be >= start_line ({start_line}).")
23
42
 
24
43
  final_path: str
25
44
  if os.path.isabs(path):
@@ -48,7 +67,19 @@ async def read_file(context: 'AgentContext', path: str) -> str:
48
67
 
49
68
  try:
50
69
  with open(final_path, 'r', encoding='utf-8') as file:
51
- content = file.read()
70
+ selected_lines = []
71
+ for line_no, line in enumerate(file, start=1):
72
+ if start_line is not None and line_no < start_line:
73
+ continue
74
+ if end_line is not None and line_no > end_line:
75
+ break
76
+ if include_line_numbers:
77
+ line_text = line.rstrip('\n')
78
+ line_suffix = '\n' if line.endswith('\n') else ''
79
+ selected_lines.append(f"{line_no}: {line_text}{line_suffix}")
80
+ else:
81
+ selected_lines.append(line)
82
+ content = ''.join(selected_lines)
52
83
  logger.info(f"File successfully read from '{final_path}' for agent '{context.agent_id}'.")
53
84
  return content
54
85
  except Exception as e:
@@ -23,8 +23,10 @@ async def write_file(context: 'AgentContext', path: str, content: str) -> str:
23
23
  logger.debug(f"Functional write_file tool for agent {context.agent_id}, initial path: {path}")
24
24
 
25
25
  final_path: str
26
+ return_path: str
26
27
  if os.path.isabs(path):
27
28
  final_path = path
29
+ return_path = final_path
28
30
  logger.debug(f"Path '{path}' is absolute. Using it directly.")
29
31
  else:
30
32
  if not context.workspace:
@@ -39,6 +41,7 @@ async def write_file(context: 'AgentContext', path: str, content: str) -> str:
39
41
  raise ValueError(error_msg)
40
42
 
41
43
  final_path = os.path.join(base_path, path)
44
+ return_path = os.path.normpath(path)
42
45
  logger.debug(f"Path '{path}' is relative. Resolved to '{final_path}' using workspace base path '{base_path}'.")
43
46
 
44
47
  try:
@@ -53,7 +56,7 @@ async def write_file(context: 'AgentContext', path: str, content: str) -> str:
53
56
  file.write(content)
54
57
 
55
58
  logger.info(f"File successfully written to '{final_path}' for agent '{context.agent_id}'.")
56
- return f"File created/updated at {final_path}"
59
+ return f"File created/updated at {return_path}"
57
60
  except Exception as e:
58
61
  logger.error(f"Error writing file to final path '{final_path}' for agent {context.agent_id}: {e}", exc_info=True)
59
62
  raise IOError(f"Could not write file at '{final_path}': {str(e)}")
@@ -155,6 +155,12 @@ def _get_parameter_type_from_hint(py_type: Any, param_name: str) -> Tuple[Parame
155
155
  logger.warning(f"Unmapped type hint {py_type} (actual_type: {actual_type}) for param '{param_name}'. Defaulting to ParameterType.STRING.")
156
156
  return ParameterType.STRING, None
157
157
 
158
+
159
+ try:
160
+ from pydantic.fields import FieldInfo
161
+ except ImportError:
162
+ FieldInfo = None # type: ignore
163
+
158
164
  def _parse_signature(sig: inspect.Signature, tool_name: str) -> Tuple[TypingList[str], bool, bool, ParameterSchema]:
159
165
  func_param_names = []
160
166
  expects_context = False
@@ -175,26 +181,51 @@ def _parse_signature(sig: inspect.Signature, tool_name: str) -> Tuple[TypingList
175
181
  param_type_enum, item_schema = _get_parameter_type_from_hint(param_type_hint, param_name)
176
182
 
177
183
  is_required = param_obj.default == inspect.Parameter.empty
178
- if get_origin(param_type_hint) is Union and type(None) in get_args(param_type_hint):
179
- is_required = False
180
-
184
+ default_val = param_obj.default if param_obj.default != inspect.Parameter.empty else None
185
+
186
+ # --- Pydantic Field Extraction Logic ---
181
187
  param_desc = f"Parameter '{param_name}' for tool '{tool_name}'."
182
188
  param_name_lower = param_name.lower()
183
189
  if "path" in param_name_lower or "file" in param_name_lower or "dir" in param_name_lower or "folder" in param_name_lower:
184
- param_desc += " This is expected to be a path."
190
+ param_desc += " This is expected to be a path."
191
+
192
+ if FieldInfo and isinstance(param_obj.default, FieldInfo):
193
+ field_info = param_obj.default
194
+
195
+ # 1. Description
196
+ if field_info.description:
197
+ param_desc = field_info.description
185
198
 
199
+ # 2. Default Value & Requiredness
200
+ # If PydanticUndefined (or similar sentinel), it means required.
201
+ # Otherwise, use the default value from Field.
202
+ # Note: Pydantic v1 uses Undefined, v2 uses PydanticUndefined.
203
+ # We check if it is the special undefined value via representation or direct check.
204
+
205
+ # Simple heuristic for "Undefined" without importing the specific sentinel
206
+ if str(field_info.default) == "PydanticUndefined" or field_info.default == ...:
207
+ is_required = True
208
+ default_val = None
209
+ else:
210
+ is_required = False
211
+ default_val = field_info.default
212
+
213
+ if get_origin(param_type_hint) is Union and type(None) in get_args(param_type_hint):
214
+ is_required = False
215
+
186
216
  schema_param = ParameterDefinition(
187
217
  name=param_name,
188
218
  param_type=param_type_enum,
189
219
  description=param_desc,
190
220
  required=is_required,
191
- default_value=param_obj.default if param_obj.default != inspect.Parameter.empty else None,
221
+ default_value=default_val,
192
222
  array_item_schema=item_schema
193
223
  )
194
224
  generated_arg_schema.add_parameter(schema_param)
195
225
 
196
226
  return func_param_names, expects_context, expects_tool_state, generated_arg_schema
197
227
 
228
+
198
229
  # --- The refactored @tool decorator ---
199
230
 
200
231
  def tool(
@@ -217,6 +248,11 @@ def tool(
217
248
 
218
249
  final_arg_schema = argument_schema if argument_schema is not None else gen_arg_schema
219
250
 
251
+ def _current_description() -> str:
252
+ """Recompute the description from the latest docstring/override."""
253
+ latest_doc = inspect.getdoc(func)
254
+ return description or (latest_doc.split('\n\n')[0] if latest_doc else f"Functional tool: {tool_name}")
255
+
220
256
  def factory(inst_config: Optional[ToolConfig] = None) -> FunctionalTool:
221
257
  return FunctionalTool(
222
258
  original_func=func,
@@ -239,7 +275,8 @@ def tool(
239
275
  custom_factory=factory,
240
276
  tool_class=None,
241
277
  origin=ToolOrigin.LOCAL,
242
- category=category
278
+ category=category,
279
+ description_provider=_current_description
243
280
  )
244
281
  default_tool_registry.register_tool(tool_def)
245
282
 
@@ -19,6 +19,7 @@ from .types import (
19
19
  BaseMcpConfig,
20
20
  StdioMcpServerConfig,
21
21
  StreamableHttpMcpServerConfig,
22
+ WebsocketMcpServerConfig,
22
23
  McpTransportType,
23
24
  McpServerInstanceKey,
24
25
  )
@@ -37,6 +38,7 @@ __all__ = [
37
38
  "BaseMcpConfig",
38
39
  "StdioMcpServerConfig",
39
40
  "StreamableHttpMcpServerConfig",
41
+ "WebsocketMcpServerConfig",
40
42
  "McpTransportType",
41
43
  "McpServerInstanceKey",
42
44
  # Services and Managers
@@ -9,6 +9,7 @@ from .types import (
9
9
  BaseMcpConfig,
10
10
  StdioMcpServerConfig,
11
11
  StreamableHttpMcpServerConfig,
12
+ WebsocketMcpServerConfig,
12
13
  McpTransportType
13
14
  )
14
15
  from autobyteus.utils.singleton import SingletonMeta
@@ -49,7 +50,8 @@ class McpConfigService(metaclass=SingletonMeta):
49
50
 
50
51
  transport_specific_params_key_map = {
51
52
  McpTransportType.STDIO: "stdio_params",
52
- McpTransportType.STREAMABLE_HTTP: "streamable_http_params"
53
+ McpTransportType.STREAMABLE_HTTP: "streamable_http_params",
54
+ McpTransportType.WEBSOCKET: "websocket_params",
53
55
  }
54
56
 
55
57
  if transport_type in transport_specific_params_key_map:
@@ -74,6 +76,8 @@ class McpConfigService(metaclass=SingletonMeta):
74
76
  return StdioMcpServerConfig(**constructor_params)
75
77
  elif transport_type == McpTransportType.STREAMABLE_HTTP:
76
78
  return StreamableHttpMcpServerConfig(**constructor_params)
79
+ elif transport_type == McpTransportType.WEBSOCKET:
80
+ return WebsocketMcpServerConfig(**constructor_params)
77
81
  else:
78
82
  raise ValueError(f"Unsupported McpTransportType '{transport_type}' for server '{server_id}'.")
79
83
  except TypeError as e:
@@ -5,6 +5,7 @@ This package contains the core abstractions for managing connections to remote M
5
5
  from .base_managed_mcp_server import BaseManagedMcpServer, ServerState
6
6
  from .stdio_managed_mcp_server import StdioManagedMcpServer
7
7
  from .http_managed_mcp_server import HttpManagedMcpServer
8
+ from .websocket_managed_mcp_server import WebsocketManagedMcpServer
8
9
  from .proxy import McpServerProxy
9
10
 
10
11
  __all__ = [
@@ -12,5 +13,6 @@ __all__ = [
12
13
  "ServerState",
13
14
  "StdioManagedMcpServer",
14
15
  "HttpManagedMcpServer",
16
+ "WebsocketManagedMcpServer",
15
17
  "McpServerProxy",
16
18
  ]
@@ -23,7 +23,7 @@ class HttpManagedMcpServer(BaseManagedMcpServer):
23
23
  config = cast(StreamableHttpMcpServerConfig, self._config)
24
24
 
25
25
  logger.debug(f"Establishing HTTP connection for server '{self.server_id}' to URL: {config.url}")
26
- read_stream, write_stream = await self._exit_stack.enter_async_context(
26
+ read_stream, write_stream, _ = await self._exit_stack.enter_async_context(
27
27
  streamablehttp_client(config.url, headers=config.headers)
28
28
  )
29
29
  session = await self._exit_stack.enter_async_context(ClientSession(read_stream, write_stream))