autobyteus 1.2.1__py3-none-any.whl → 1.2.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (466) hide show
  1. autobyteus/agent/agent.py +15 -5
  2. autobyteus/agent/bootstrap_steps/__init__.py +1 -3
  3. autobyteus/agent/bootstrap_steps/agent_bootstrapper.py +3 -59
  4. autobyteus/agent/bootstrap_steps/base_bootstrap_step.py +1 -4
  5. autobyteus/agent/bootstrap_steps/mcp_server_prewarming_step.py +1 -3
  6. autobyteus/agent/bootstrap_steps/system_prompt_processing_step.py +16 -13
  7. autobyteus/agent/bootstrap_steps/workspace_context_initialization_step.py +2 -4
  8. autobyteus/agent/context/agent_config.py +43 -20
  9. autobyteus/agent/context/agent_context.py +23 -18
  10. autobyteus/agent/context/agent_runtime_state.py +19 -19
  11. autobyteus/agent/events/__init__.py +16 -1
  12. autobyteus/agent/events/agent_events.py +43 -3
  13. autobyteus/agent/events/agent_input_event_queue_manager.py +79 -26
  14. autobyteus/agent/events/event_store.py +57 -0
  15. autobyteus/agent/events/notifiers.py +69 -59
  16. autobyteus/agent/events/worker_event_dispatcher.py +21 -64
  17. autobyteus/agent/factory/agent_factory.py +52 -0
  18. autobyteus/agent/handlers/__init__.py +2 -0
  19. autobyteus/agent/handlers/approved_tool_invocation_event_handler.py +51 -34
  20. autobyteus/agent/handlers/bootstrap_event_handler.py +155 -0
  21. autobyteus/agent/handlers/inter_agent_message_event_handler.py +10 -0
  22. autobyteus/agent/handlers/lifecycle_event_logger.py +19 -11
  23. autobyteus/agent/handlers/llm_complete_response_received_event_handler.py +10 -15
  24. autobyteus/agent/handlers/llm_user_message_ready_event_handler.py +188 -48
  25. autobyteus/agent/handlers/tool_execution_approval_event_handler.py +0 -10
  26. autobyteus/agent/handlers/tool_invocation_request_event_handler.py +53 -48
  27. autobyteus/agent/handlers/tool_result_event_handler.py +7 -8
  28. autobyteus/agent/handlers/user_input_message_event_handler.py +10 -3
  29. autobyteus/agent/input_processor/memory_ingest_input_processor.py +40 -0
  30. autobyteus/agent/lifecycle/__init__.py +12 -0
  31. autobyteus/agent/lifecycle/base_processor.py +109 -0
  32. autobyteus/agent/lifecycle/events.py +35 -0
  33. autobyteus/agent/lifecycle/processor_definition.py +36 -0
  34. autobyteus/agent/lifecycle/processor_registry.py +106 -0
  35. autobyteus/agent/llm_request_assembler.py +98 -0
  36. autobyteus/agent/llm_response_processor/__init__.py +1 -8
  37. autobyteus/agent/message/context_file_type.py +1 -1
  38. autobyteus/agent/runtime/agent_runtime.py +29 -21
  39. autobyteus/agent/runtime/agent_worker.py +98 -19
  40. autobyteus/agent/shutdown_steps/__init__.py +2 -0
  41. autobyteus/agent/shutdown_steps/agent_shutdown_orchestrator.py +2 -0
  42. autobyteus/agent/shutdown_steps/tool_cleanup_step.py +58 -0
  43. autobyteus/agent/status/__init__.py +14 -0
  44. autobyteus/agent/status/manager.py +93 -0
  45. autobyteus/agent/status/status_deriver.py +96 -0
  46. autobyteus/agent/{phases/phase_enum.py → status/status_enum.py} +16 -16
  47. autobyteus/agent/status/status_update_utils.py +73 -0
  48. autobyteus/agent/streaming/__init__.py +52 -5
  49. autobyteus/agent/streaming/adapters/__init__.py +18 -0
  50. autobyteus/agent/streaming/adapters/invocation_adapter.py +184 -0
  51. autobyteus/agent/streaming/adapters/tool_call_parsing.py +163 -0
  52. autobyteus/agent/streaming/adapters/tool_syntax_registry.py +67 -0
  53. autobyteus/agent/streaming/agent_event_stream.py +3 -183
  54. autobyteus/agent/streaming/api_tool_call/__init__.py +16 -0
  55. autobyteus/agent/streaming/api_tool_call/file_content_streamer.py +56 -0
  56. autobyteus/agent/streaming/api_tool_call/json_string_field_extractor.py +175 -0
  57. autobyteus/agent/streaming/api_tool_call_streaming_response_handler.py +4 -0
  58. autobyteus/agent/streaming/events/__init__.py +6 -0
  59. autobyteus/agent/streaming/events/stream_event_payloads.py +284 -0
  60. autobyteus/agent/streaming/events/stream_events.py +141 -0
  61. autobyteus/agent/streaming/handlers/__init__.py +15 -0
  62. autobyteus/agent/streaming/handlers/api_tool_call_streaming_response_handler.py +303 -0
  63. autobyteus/agent/streaming/handlers/parsing_streaming_response_handler.py +107 -0
  64. autobyteus/agent/streaming/handlers/pass_through_streaming_response_handler.py +107 -0
  65. autobyteus/agent/streaming/handlers/streaming_handler_factory.py +177 -0
  66. autobyteus/agent/streaming/handlers/streaming_response_handler.py +58 -0
  67. autobyteus/agent/streaming/parser/__init__.py +61 -0
  68. autobyteus/agent/streaming/parser/event_emitter.py +181 -0
  69. autobyteus/agent/streaming/parser/events.py +4 -0
  70. autobyteus/agent/streaming/parser/invocation_adapter.py +4 -0
  71. autobyteus/agent/streaming/parser/json_parsing_strategies/__init__.py +19 -0
  72. autobyteus/agent/streaming/parser/json_parsing_strategies/base.py +32 -0
  73. autobyteus/agent/streaming/parser/json_parsing_strategies/default.py +34 -0
  74. autobyteus/agent/streaming/parser/json_parsing_strategies/gemini.py +31 -0
  75. autobyteus/agent/streaming/parser/json_parsing_strategies/openai.py +64 -0
  76. autobyteus/agent/streaming/parser/json_parsing_strategies/registry.py +75 -0
  77. autobyteus/agent/streaming/parser/parser_context.py +227 -0
  78. autobyteus/agent/streaming/parser/parser_factory.py +132 -0
  79. autobyteus/agent/streaming/parser/sentinel_format.py +7 -0
  80. autobyteus/agent/streaming/parser/state_factory.py +62 -0
  81. autobyteus/agent/streaming/parser/states/__init__.py +1 -0
  82. autobyteus/agent/streaming/parser/states/base_state.py +60 -0
  83. autobyteus/agent/streaming/parser/states/custom_xml_tag_run_bash_parsing_state.py +38 -0
  84. autobyteus/agent/streaming/parser/states/custom_xml_tag_write_file_parsing_state.py +55 -0
  85. autobyteus/agent/streaming/parser/states/delimited_content_state.py +146 -0
  86. autobyteus/agent/streaming/parser/states/json_initialization_state.py +144 -0
  87. autobyteus/agent/streaming/parser/states/json_tool_parsing_state.py +137 -0
  88. autobyteus/agent/streaming/parser/states/sentinel_content_state.py +30 -0
  89. autobyteus/agent/streaming/parser/states/sentinel_initialization_state.py +117 -0
  90. autobyteus/agent/streaming/parser/states/text_state.py +78 -0
  91. autobyteus/agent/streaming/parser/states/xml_patch_file_tool_parsing_state.py +328 -0
  92. autobyteus/agent/streaming/parser/states/xml_run_bash_tool_parsing_state.py +129 -0
  93. autobyteus/agent/streaming/parser/states/xml_tag_initialization_state.py +151 -0
  94. autobyteus/agent/streaming/parser/states/xml_tool_parsing_state.py +63 -0
  95. autobyteus/agent/streaming/parser/states/xml_write_file_tool_parsing_state.py +343 -0
  96. autobyteus/agent/streaming/parser/strategies/__init__.py +17 -0
  97. autobyteus/agent/streaming/parser/strategies/base.py +24 -0
  98. autobyteus/agent/streaming/parser/strategies/json_tool_strategy.py +26 -0
  99. autobyteus/agent/streaming/parser/strategies/registry.py +28 -0
  100. autobyteus/agent/streaming/parser/strategies/sentinel_strategy.py +23 -0
  101. autobyteus/agent/streaming/parser/strategies/xml_tag_strategy.py +21 -0
  102. autobyteus/agent/streaming/parser/stream_scanner.py +167 -0
  103. autobyteus/agent/streaming/parser/streaming_parser.py +212 -0
  104. autobyteus/agent/streaming/parser/tool_call_parsing.py +4 -0
  105. autobyteus/agent/streaming/parser/tool_constants.py +7 -0
  106. autobyteus/agent/streaming/parser/tool_syntax_registry.py +4 -0
  107. autobyteus/agent/streaming/parser/xml_tool_parsing_state_registry.py +55 -0
  108. autobyteus/agent/streaming/parsing_streaming_response_handler.py +4 -0
  109. autobyteus/agent/streaming/pass_through_streaming_response_handler.py +4 -0
  110. autobyteus/agent/streaming/queue_streamer.py +3 -57
  111. autobyteus/agent/streaming/segments/__init__.py +5 -0
  112. autobyteus/agent/streaming/segments/segment_events.py +81 -0
  113. autobyteus/agent/streaming/stream_event_payloads.py +2 -223
  114. autobyteus/agent/streaming/stream_events.py +3 -140
  115. autobyteus/agent/streaming/streaming_handler_factory.py +4 -0
  116. autobyteus/agent/streaming/streaming_response_handler.py +4 -0
  117. autobyteus/agent/streaming/streams/__init__.py +5 -0
  118. autobyteus/agent/streaming/streams/agent_event_stream.py +197 -0
  119. autobyteus/agent/streaming/utils/__init__.py +5 -0
  120. autobyteus/agent/streaming/utils/queue_streamer.py +59 -0
  121. autobyteus/agent/system_prompt_processor/__init__.py +2 -0
  122. autobyteus/agent/system_prompt_processor/available_skills_processor.py +96 -0
  123. autobyteus/agent/system_prompt_processor/base_processor.py +1 -1
  124. autobyteus/agent/system_prompt_processor/processor_meta.py +15 -2
  125. autobyteus/agent/system_prompt_processor/tool_manifest_injector_processor.py +39 -58
  126. autobyteus/agent/token_budget.py +56 -0
  127. autobyteus/agent/tool_execution_result_processor/memory_ingest_tool_result_processor.py +29 -0
  128. autobyteus/agent/tool_invocation.py +16 -40
  129. autobyteus/agent/tool_invocation_preprocessor/__init__.py +9 -0
  130. autobyteus/agent/tool_invocation_preprocessor/base_preprocessor.py +45 -0
  131. autobyteus/agent/tool_invocation_preprocessor/processor_definition.py +15 -0
  132. autobyteus/agent/tool_invocation_preprocessor/processor_meta.py +33 -0
  133. autobyteus/agent/tool_invocation_preprocessor/processor_registry.py +60 -0
  134. autobyteus/agent/utils/wait_for_idle.py +12 -14
  135. autobyteus/agent/workspace/base_workspace.py +6 -27
  136. autobyteus/agent_team/agent_team.py +3 -3
  137. autobyteus/agent_team/agent_team_builder.py +1 -41
  138. autobyteus/agent_team/bootstrap_steps/__init__.py +0 -4
  139. autobyteus/agent_team/bootstrap_steps/agent_configuration_preparation_step.py +8 -18
  140. autobyteus/agent_team/bootstrap_steps/agent_team_bootstrapper.py +4 -16
  141. autobyteus/agent_team/bootstrap_steps/base_agent_team_bootstrap_step.py +1 -2
  142. autobyteus/agent_team/bootstrap_steps/coordinator_initialization_step.py +1 -2
  143. autobyteus/agent_team/bootstrap_steps/task_notifier_initialization_step.py +1 -2
  144. autobyteus/agent_team/bootstrap_steps/team_context_initialization_step.py +4 -4
  145. autobyteus/agent_team/context/agent_team_config.py +6 -3
  146. autobyteus/agent_team/context/agent_team_context.py +25 -3
  147. autobyteus/agent_team/context/agent_team_runtime_state.py +9 -6
  148. autobyteus/agent_team/events/__init__.py +11 -0
  149. autobyteus/agent_team/events/agent_team_event_dispatcher.py +22 -9
  150. autobyteus/agent_team/events/agent_team_events.py +16 -0
  151. autobyteus/agent_team/events/event_store.py +57 -0
  152. autobyteus/agent_team/factory/agent_team_factory.py +8 -0
  153. autobyteus/agent_team/handlers/inter_agent_message_request_event_handler.py +18 -2
  154. autobyteus/agent_team/handlers/lifecycle_agent_team_event_handler.py +21 -5
  155. autobyteus/agent_team/handlers/process_user_message_event_handler.py +17 -8
  156. autobyteus/agent_team/handlers/tool_approval_team_event_handler.py +19 -4
  157. autobyteus/agent_team/runtime/agent_team_runtime.py +41 -10
  158. autobyteus/agent_team/runtime/agent_team_worker.py +69 -5
  159. autobyteus/agent_team/status/__init__.py +14 -0
  160. autobyteus/agent_team/status/agent_team_status.py +18 -0
  161. autobyteus/agent_team/status/agent_team_status_manager.py +33 -0
  162. autobyteus/agent_team/status/status_deriver.py +62 -0
  163. autobyteus/agent_team/status/status_update_utils.py +42 -0
  164. autobyteus/agent_team/streaming/__init__.py +2 -2
  165. autobyteus/agent_team/streaming/agent_team_event_notifier.py +6 -6
  166. autobyteus/agent_team/streaming/agent_team_stream_event_payloads.py +4 -4
  167. autobyteus/agent_team/streaming/agent_team_stream_events.py +3 -3
  168. autobyteus/agent_team/system_prompt_processor/__init__.py +6 -0
  169. autobyteus/agent_team/system_prompt_processor/team_manifest_injector_processor.py +76 -0
  170. autobyteus/agent_team/task_notification/task_notification_mode.py +19 -0
  171. autobyteus/agent_team/utils/wait_for_idle.py +4 -4
  172. autobyteus/cli/agent_cli.py +18 -10
  173. autobyteus/cli/agent_team_tui/app.py +14 -11
  174. autobyteus/cli/agent_team_tui/state.py +13 -15
  175. autobyteus/cli/agent_team_tui/widgets/agent_list_sidebar.py +15 -15
  176. autobyteus/cli/agent_team_tui/widgets/focus_pane.py +143 -36
  177. autobyteus/cli/agent_team_tui/widgets/renderables.py +1 -1
  178. autobyteus/cli/agent_team_tui/widgets/shared.py +25 -25
  179. autobyteus/cli/cli_display.py +193 -44
  180. autobyteus/cli/workflow_tui/app.py +9 -10
  181. autobyteus/cli/workflow_tui/state.py +14 -16
  182. autobyteus/cli/workflow_tui/widgets/agent_list_sidebar.py +15 -15
  183. autobyteus/cli/workflow_tui/widgets/focus_pane.py +137 -35
  184. autobyteus/cli/workflow_tui/widgets/renderables.py +1 -1
  185. autobyteus/cli/workflow_tui/widgets/shared.py +25 -25
  186. autobyteus/clients/autobyteus_client.py +94 -1
  187. autobyteus/events/event_types.py +11 -18
  188. autobyteus/llm/api/autobyteus_llm.py +33 -29
  189. autobyteus/llm/api/claude_llm.py +142 -36
  190. autobyteus/llm/api/gemini_llm.py +163 -59
  191. autobyteus/llm/api/grok_llm.py +1 -1
  192. autobyteus/llm/api/minimax_llm.py +26 -0
  193. autobyteus/llm/api/mistral_llm.py +113 -87
  194. autobyteus/llm/api/ollama_llm.py +9 -42
  195. autobyteus/llm/api/openai_compatible_llm.py +127 -91
  196. autobyteus/llm/api/openai_llm.py +3 -3
  197. autobyteus/llm/api/openai_responses_llm.py +324 -0
  198. autobyteus/llm/api/zhipu_llm.py +21 -2
  199. autobyteus/llm/autobyteus_provider.py +70 -60
  200. autobyteus/llm/base_llm.py +85 -81
  201. autobyteus/llm/converters/__init__.py +14 -0
  202. autobyteus/llm/converters/anthropic_tool_call_converter.py +37 -0
  203. autobyteus/llm/converters/gemini_tool_call_converter.py +57 -0
  204. autobyteus/llm/converters/mistral_tool_call_converter.py +37 -0
  205. autobyteus/llm/converters/openai_tool_call_converter.py +38 -0
  206. autobyteus/llm/extensions/base_extension.py +6 -12
  207. autobyteus/llm/extensions/token_usage_tracking_extension.py +45 -18
  208. autobyteus/llm/llm_factory.py +282 -204
  209. autobyteus/llm/lmstudio_provider.py +60 -49
  210. autobyteus/llm/models.py +35 -2
  211. autobyteus/llm/ollama_provider.py +60 -49
  212. autobyteus/llm/ollama_provider_resolver.py +0 -1
  213. autobyteus/llm/prompt_renderers/__init__.py +19 -0
  214. autobyteus/llm/prompt_renderers/anthropic_prompt_renderer.py +104 -0
  215. autobyteus/llm/prompt_renderers/autobyteus_prompt_renderer.py +19 -0
  216. autobyteus/llm/prompt_renderers/base_prompt_renderer.py +10 -0
  217. autobyteus/llm/prompt_renderers/gemini_prompt_renderer.py +63 -0
  218. autobyteus/llm/prompt_renderers/mistral_prompt_renderer.py +87 -0
  219. autobyteus/llm/prompt_renderers/ollama_prompt_renderer.py +51 -0
  220. autobyteus/llm/prompt_renderers/openai_chat_renderer.py +97 -0
  221. autobyteus/llm/prompt_renderers/openai_responses_renderer.py +101 -0
  222. autobyteus/llm/providers.py +1 -3
  223. autobyteus/llm/token_counter/claude_token_counter.py +56 -25
  224. autobyteus/llm/token_counter/mistral_token_counter.py +12 -8
  225. autobyteus/llm/token_counter/openai_token_counter.py +24 -5
  226. autobyteus/llm/token_counter/token_counter_factory.py +12 -5
  227. autobyteus/llm/utils/llm_config.py +6 -12
  228. autobyteus/llm/utils/media_payload_formatter.py +27 -20
  229. autobyteus/llm/utils/messages.py +55 -3
  230. autobyteus/llm/utils/response_types.py +3 -0
  231. autobyteus/llm/utils/tool_call_delta.py +31 -0
  232. autobyteus/memory/__init__.py +32 -0
  233. autobyteus/memory/active_transcript.py +69 -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 +183 -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/policies/__init__.py +5 -0
  247. autobyteus/memory/policies/compaction_policy.py +16 -0
  248. autobyteus/memory/retrieval/__init__.py +7 -0
  249. autobyteus/memory/retrieval/memory_bundle.py +11 -0
  250. autobyteus/memory/retrieval/retriever.py +13 -0
  251. autobyteus/memory/store/__init__.py +7 -0
  252. autobyteus/memory/store/base_store.py +14 -0
  253. autobyteus/memory/store/file_store.py +98 -0
  254. autobyteus/memory/tool_interaction_builder.py +46 -0
  255. autobyteus/memory/turn_tracker.py +9 -0
  256. autobyteus/multimedia/audio/api/autobyteus_audio_client.py +19 -5
  257. autobyteus/multimedia/audio/api/gemini_audio_client.py +108 -16
  258. autobyteus/multimedia/audio/audio_client_factory.py +47 -9
  259. autobyteus/multimedia/audio/audio_model.py +2 -1
  260. autobyteus/multimedia/image/api/autobyteus_image_client.py +19 -5
  261. autobyteus/multimedia/image/api/gemini_image_client.py +38 -17
  262. autobyteus/multimedia/image/api/openai_image_client.py +125 -43
  263. autobyteus/multimedia/image/autobyteus_image_provider.py +2 -1
  264. autobyteus/multimedia/image/image_client_factory.py +47 -15
  265. autobyteus/multimedia/image/image_model.py +5 -2
  266. autobyteus/multimedia/providers.py +3 -2
  267. autobyteus/skills/loader.py +71 -0
  268. autobyteus/skills/model.py +11 -0
  269. autobyteus/skills/registry.py +70 -0
  270. autobyteus/task_management/tools/todo_tools/add_todo.py +2 -2
  271. autobyteus/task_management/tools/todo_tools/create_todo_list.py +2 -2
  272. autobyteus/task_management/tools/todo_tools/update_todo_status.py +2 -2
  273. autobyteus/tools/__init__.py +34 -47
  274. autobyteus/tools/base_tool.py +7 -0
  275. autobyteus/tools/file/__init__.py +2 -6
  276. autobyteus/tools/file/patch_file.py +149 -0
  277. autobyteus/tools/file/read_file.py +36 -5
  278. autobyteus/tools/file/write_file.py +4 -1
  279. autobyteus/tools/functional_tool.py +43 -6
  280. autobyteus/tools/mcp/__init__.py +2 -0
  281. autobyteus/tools/mcp/config_service.py +5 -1
  282. autobyteus/tools/mcp/server/__init__.py +2 -0
  283. autobyteus/tools/mcp/server/http_managed_mcp_server.py +1 -1
  284. autobyteus/tools/mcp/server/websocket_managed_mcp_server.py +141 -0
  285. autobyteus/tools/mcp/server_instance_manager.py +8 -1
  286. autobyteus/tools/mcp/types.py +61 -0
  287. autobyteus/tools/multimedia/audio_tools.py +70 -17
  288. autobyteus/tools/multimedia/download_media_tool.py +18 -4
  289. autobyteus/tools/multimedia/image_tools.py +246 -62
  290. autobyteus/tools/operation_executor/journal_manager.py +107 -0
  291. autobyteus/tools/operation_executor/operation_event_buffer.py +57 -0
  292. autobyteus/tools/operation_executor/operation_event_producer.py +29 -0
  293. autobyteus/tools/operation_executor/operation_executor.py +58 -0
  294. autobyteus/tools/registry/tool_definition.py +43 -2
  295. autobyteus/tools/skill/load_skill.py +50 -0
  296. autobyteus/tools/terminal/__init__.py +45 -0
  297. autobyteus/tools/terminal/ansi_utils.py +32 -0
  298. autobyteus/tools/terminal/background_process_manager.py +233 -0
  299. autobyteus/tools/terminal/output_buffer.py +105 -0
  300. autobyteus/tools/terminal/prompt_detector.py +63 -0
  301. autobyteus/tools/terminal/pty_session.py +241 -0
  302. autobyteus/tools/terminal/session_factory.py +20 -0
  303. autobyteus/tools/terminal/terminal_session_manager.py +226 -0
  304. autobyteus/tools/terminal/tools/__init__.py +13 -0
  305. autobyteus/tools/terminal/tools/get_process_output.py +81 -0
  306. autobyteus/tools/terminal/tools/run_bash.py +109 -0
  307. autobyteus/tools/terminal/tools/start_background_process.py +104 -0
  308. autobyteus/tools/terminal/tools/stop_background_process.py +67 -0
  309. autobyteus/tools/terminal/types.py +54 -0
  310. autobyteus/tools/terminal/wsl_tmux_session.py +221 -0
  311. autobyteus/tools/terminal/wsl_utils.py +156 -0
  312. autobyteus/tools/transaction_management/backup_handler.py +48 -0
  313. autobyteus/tools/transaction_management/operation_lifecycle_manager.py +62 -0
  314. autobyteus/tools/usage/__init__.py +1 -2
  315. autobyteus/tools/usage/formatters/__init__.py +17 -1
  316. autobyteus/tools/usage/formatters/base_formatter.py +8 -0
  317. autobyteus/tools/usage/formatters/default_xml_schema_formatter.py +2 -2
  318. autobyteus/tools/usage/formatters/mistral_json_schema_formatter.py +18 -0
  319. autobyteus/tools/usage/formatters/patch_file_xml_example_formatter.py +64 -0
  320. autobyteus/tools/usage/formatters/patch_file_xml_schema_formatter.py +31 -0
  321. autobyteus/tools/usage/formatters/run_bash_xml_example_formatter.py +32 -0
  322. autobyteus/tools/usage/formatters/run_bash_xml_schema_formatter.py +36 -0
  323. autobyteus/tools/usage/formatters/write_file_xml_example_formatter.py +53 -0
  324. autobyteus/tools/usage/formatters/write_file_xml_schema_formatter.py +31 -0
  325. autobyteus/tools/usage/providers/tool_manifest_provider.py +10 -10
  326. autobyteus/tools/usage/registries/__init__.py +1 -3
  327. autobyteus/tools/usage/registries/tool_formatting_registry.py +115 -8
  328. autobyteus/tools/usage/tool_schema_provider.py +51 -0
  329. autobyteus/tools/web/__init__.py +4 -0
  330. autobyteus/tools/web/read_url_tool.py +80 -0
  331. autobyteus/utils/diff_utils.py +271 -0
  332. autobyteus/utils/download_utils.py +109 -0
  333. autobyteus/utils/file_utils.py +57 -2
  334. autobyteus/utils/gemini_helper.py +56 -0
  335. autobyteus/utils/gemini_model_mapping.py +71 -0
  336. autobyteus/utils/llm_output_formatter.py +75 -0
  337. autobyteus/utils/tool_call_format.py +36 -0
  338. autobyteus/workflow/agentic_workflow.py +3 -3
  339. autobyteus/workflow/bootstrap_steps/agent_tool_injection_step.py +2 -2
  340. autobyteus/workflow/bootstrap_steps/base_workflow_bootstrap_step.py +2 -2
  341. autobyteus/workflow/bootstrap_steps/coordinator_initialization_step.py +2 -2
  342. autobyteus/workflow/bootstrap_steps/coordinator_prompt_preparation_step.py +3 -9
  343. autobyteus/workflow/bootstrap_steps/workflow_bootstrapper.py +6 -6
  344. autobyteus/workflow/bootstrap_steps/workflow_runtime_queue_initialization_step.py +2 -2
  345. autobyteus/workflow/context/workflow_context.py +3 -3
  346. autobyteus/workflow/context/workflow_runtime_state.py +5 -5
  347. autobyteus/workflow/events/workflow_event_dispatcher.py +5 -5
  348. autobyteus/workflow/handlers/lifecycle_workflow_event_handler.py +3 -3
  349. autobyteus/workflow/handlers/process_user_message_event_handler.py +5 -5
  350. autobyteus/workflow/handlers/tool_approval_workflow_event_handler.py +2 -2
  351. autobyteus/workflow/runtime/workflow_runtime.py +8 -8
  352. autobyteus/workflow/runtime/workflow_worker.py +3 -3
  353. autobyteus/workflow/status/__init__.py +11 -0
  354. autobyteus/workflow/status/workflow_status.py +19 -0
  355. autobyteus/workflow/status/workflow_status_manager.py +48 -0
  356. autobyteus/workflow/streaming/__init__.py +2 -2
  357. autobyteus/workflow/streaming/workflow_event_notifier.py +7 -7
  358. autobyteus/workflow/streaming/workflow_stream_event_payloads.py +4 -4
  359. autobyteus/workflow/streaming/workflow_stream_events.py +3 -3
  360. autobyteus/workflow/utils/wait_for_idle.py +4 -4
  361. autobyteus-1.2.3.dist-info/METADATA +293 -0
  362. autobyteus-1.2.3.dist-info/RECORD +600 -0
  363. {autobyteus-1.2.1.dist-info → autobyteus-1.2.3.dist-info}/WHEEL +1 -1
  364. {autobyteus-1.2.1.dist-info → autobyteus-1.2.3.dist-info}/top_level.txt +0 -1
  365. autobyteus/agent/bootstrap_steps/agent_runtime_queue_initialization_step.py +0 -57
  366. autobyteus/agent/hooks/__init__.py +0 -16
  367. autobyteus/agent/hooks/base_phase_hook.py +0 -78
  368. autobyteus/agent/hooks/hook_definition.py +0 -36
  369. autobyteus/agent/hooks/hook_meta.py +0 -37
  370. autobyteus/agent/hooks/hook_registry.py +0 -106
  371. autobyteus/agent/llm_response_processor/provider_aware_tool_usage_processor.py +0 -103
  372. autobyteus/agent/phases/__init__.py +0 -18
  373. autobyteus/agent/phases/discover.py +0 -53
  374. autobyteus/agent/phases/manager.py +0 -265
  375. autobyteus/agent/phases/transition_decorator.py +0 -40
  376. autobyteus/agent/phases/transition_info.py +0 -33
  377. autobyteus/agent/remote_agent.py +0 -244
  378. autobyteus/agent/workspace/workspace_definition.py +0 -36
  379. autobyteus/agent/workspace/workspace_meta.py +0 -37
  380. autobyteus/agent/workspace/workspace_registry.py +0 -72
  381. autobyteus/agent_team/bootstrap_steps/agent_team_runtime_queue_initialization_step.py +0 -25
  382. autobyteus/agent_team/bootstrap_steps/coordinator_prompt_preparation_step.py +0 -85
  383. autobyteus/agent_team/phases/__init__.py +0 -11
  384. autobyteus/agent_team/phases/agent_team_operational_phase.py +0 -19
  385. autobyteus/agent_team/phases/agent_team_phase_manager.py +0 -48
  386. autobyteus/llm/api/bedrock_llm.py +0 -92
  387. autobyteus/llm/api/groq_llm.py +0 -94
  388. autobyteus/llm/api/nvidia_llm.py +0 -108
  389. autobyteus/llm/utils/token_pricing_config.py +0 -87
  390. autobyteus/rpc/__init__.py +0 -73
  391. autobyteus/rpc/client/__init__.py +0 -17
  392. autobyteus/rpc/client/abstract_client_connection.py +0 -124
  393. autobyteus/rpc/client/client_connection_manager.py +0 -153
  394. autobyteus/rpc/client/sse_client_connection.py +0 -306
  395. autobyteus/rpc/client/stdio_client_connection.py +0 -280
  396. autobyteus/rpc/config/__init__.py +0 -13
  397. autobyteus/rpc/config/agent_server_config.py +0 -153
  398. autobyteus/rpc/config/agent_server_registry.py +0 -152
  399. autobyteus/rpc/hosting.py +0 -244
  400. autobyteus/rpc/protocol.py +0 -244
  401. autobyteus/rpc/server/__init__.py +0 -20
  402. autobyteus/rpc/server/agent_server_endpoint.py +0 -181
  403. autobyteus/rpc/server/base_method_handler.py +0 -40
  404. autobyteus/rpc/server/method_handlers.py +0 -259
  405. autobyteus/rpc/server/sse_server_handler.py +0 -182
  406. autobyteus/rpc/server/stdio_server_handler.py +0 -151
  407. autobyteus/rpc/server_main.py +0 -198
  408. autobyteus/rpc/transport_type.py +0 -13
  409. autobyteus/tools/bash/__init__.py +0 -2
  410. autobyteus/tools/bash/bash_executor.py +0 -100
  411. autobyteus/tools/browser/__init__.py +0 -2
  412. autobyteus/tools/browser/session_aware/browser_session_aware_navigate_to.py +0 -75
  413. autobyteus/tools/browser/session_aware/browser_session_aware_tool.py +0 -30
  414. autobyteus/tools/browser/session_aware/browser_session_aware_web_element_trigger.py +0 -154
  415. autobyteus/tools/browser/session_aware/browser_session_aware_webpage_reader.py +0 -89
  416. autobyteus/tools/browser/session_aware/browser_session_aware_webpage_screenshot_taker.py +0 -107
  417. autobyteus/tools/browser/session_aware/factory/browser_session_aware_web_element_trigger_factory.py +0 -14
  418. autobyteus/tools/browser/session_aware/factory/browser_session_aware_webpage_reader_factory.py +0 -26
  419. autobyteus/tools/browser/session_aware/factory/browser_session_aware_webpage_screenshot_taker_factory.py +0 -14
  420. autobyteus/tools/browser/session_aware/shared_browser_session.py +0 -11
  421. autobyteus/tools/browser/session_aware/shared_browser_session_manager.py +0 -25
  422. autobyteus/tools/browser/session_aware/web_element_action.py +0 -20
  423. autobyteus/tools/browser/standalone/__init__.py +0 -6
  424. autobyteus/tools/browser/standalone/factory/__init__.py +0 -0
  425. autobyteus/tools/browser/standalone/factory/webpage_reader_factory.py +0 -25
  426. autobyteus/tools/browser/standalone/factory/webpage_screenshot_taker_factory.py +0 -14
  427. autobyteus/tools/browser/standalone/navigate_to.py +0 -84
  428. autobyteus/tools/browser/standalone/web_page_pdf_generator.py +0 -101
  429. autobyteus/tools/browser/standalone/webpage_image_downloader.py +0 -169
  430. autobyteus/tools/browser/standalone/webpage_reader.py +0 -105
  431. autobyteus/tools/browser/standalone/webpage_screenshot_taker.py +0 -105
  432. autobyteus/tools/file/edit_file.py +0 -200
  433. autobyteus/tools/file/list_directory.py +0 -168
  434. autobyteus/tools/file/search_files.py +0 -188
  435. autobyteus/tools/timer.py +0 -175
  436. autobyteus/tools/usage/parsers/__init__.py +0 -22
  437. autobyteus/tools/usage/parsers/_json_extractor.py +0 -99
  438. autobyteus/tools/usage/parsers/_string_decoders.py +0 -18
  439. autobyteus/tools/usage/parsers/anthropic_xml_tool_usage_parser.py +0 -10
  440. autobyteus/tools/usage/parsers/base_parser.py +0 -41
  441. autobyteus/tools/usage/parsers/default_json_tool_usage_parser.py +0 -83
  442. autobyteus/tools/usage/parsers/default_xml_tool_usage_parser.py +0 -316
  443. autobyteus/tools/usage/parsers/exceptions.py +0 -13
  444. autobyteus/tools/usage/parsers/gemini_json_tool_usage_parser.py +0 -77
  445. autobyteus/tools/usage/parsers/openai_json_tool_usage_parser.py +0 -149
  446. autobyteus/tools/usage/parsers/provider_aware_tool_usage_parser.py +0 -59
  447. autobyteus/tools/usage/registries/tool_usage_parser_registry.py +0 -62
  448. autobyteus/workflow/phases/__init__.py +0 -11
  449. autobyteus/workflow/phases/workflow_operational_phase.py +0 -19
  450. autobyteus/workflow/phases/workflow_phase_manager.py +0 -48
  451. autobyteus-1.2.1.dist-info/METADATA +0 -205
  452. autobyteus-1.2.1.dist-info/RECORD +0 -511
  453. examples/__init__.py +0 -1
  454. examples/agent_team/__init__.py +0 -1
  455. examples/discover_phase_transitions.py +0 -104
  456. examples/run_agentic_software_engineer.py +0 -239
  457. examples/run_browser_agent.py +0 -262
  458. examples/run_google_slides_agent.py +0 -287
  459. examples/run_mcp_browser_client.py +0 -174
  460. examples/run_mcp_google_slides_client.py +0 -270
  461. examples/run_mcp_list_tools.py +0 -189
  462. examples/run_poem_writer.py +0 -284
  463. examples/run_sqlite_agent.py +0 -295
  464. /autobyteus/{tools/browser/session_aware → skills}/__init__.py +0 -0
  465. /autobyteus/tools/{browser/session_aware/factory → skill}/__init__.py +0 -0
  466. {autobyteus-1.2.1.dist-info → autobyteus-1.2.3.dist-info}/licenses/LICENSE +0 -0
@@ -1,280 +0,0 @@
1
- # file: autobyteus/autobyteus/rpc/client/stdio_client_connection.py
2
- import asyncio
3
- import logging
4
- import json
5
- from typing import List, Optional, Dict, Any, AsyncIterator # Added Any, AsyncIterator
6
-
7
- from autobyteus.rpc.protocol import ProtocolMessage, MessageType, ErrorCode
8
- from .abstract_client_connection import AbstractClientConnection
9
- from autobyteus.rpc.config import AgentServerConfig, TransportType # Added TransportType
10
-
11
- logger = logging.getLogger(__name__)
12
-
13
- DEFAULT_STDIO_TIMEOUT = 10.0 # seconds for a response
14
-
15
- class StdioClientConnection(AbstractClientConnection):
16
- """
17
- Client connection implementation for stdio-based Agent Servers.
18
- Manages a subprocess and communicates via its stdin/stdout using
19
- newline-delimited JSON ProtocolMessages.
20
- """
21
-
22
- def __init__(self, server_config: AgentServerConfig):
23
- """
24
- Initializes the StdioClientConnection.
25
-
26
- Args:
27
- server_config: The configuration for the stdio server.
28
-
29
- Raises:
30
- ValueError: If server_config is not for stdio or stdio_command is missing.
31
- """
32
- if server_config.transport_type != TransportType.STDIO: # Using Enum member
33
- raise ValueError("StdioClientConnection requires an AgentServerConfig with transport_type 'stdio'.")
34
- if not server_config.stdio_command:
35
- raise ValueError("AgentServerConfig for stdio transport must have a stdio_command.")
36
-
37
- super().__init__(server_id=server_config.server_id)
38
- self.server_config: AgentServerConfig = server_config
39
- self._process: Optional[asyncio.subprocess.Process] = None
40
- self._response_futures: Dict[str, asyncio.Future] = {}
41
- self._reader_task: Optional[asyncio.Task] = None
42
- self._lock = asyncio.Lock() # For managing access to _response_futures
43
-
44
- async def connect(self) -> None:
45
- """
46
- Starts the stdio server subprocess and establishes communication.
47
- """
48
- async with self._connection_lock:
49
- if self._is_connected:
50
- logger.debug(f"StdioClientConnection to '{self.server_id}' already connected.")
51
- return
52
-
53
- try:
54
- logger.info(f"Connecting StdioClientConnection to '{self.server_id}' using command: {' '.join(self.server_config.stdio_command)}")
55
- self._process = await asyncio.create_subprocess_exec(
56
- *self.server_config.stdio_command,
57
- stdin=asyncio.subprocess.PIPE,
58
- stdout=asyncio.subprocess.PIPE,
59
- stderr=asyncio.subprocess.PIPE
60
- )
61
- self._is_connected = True
62
- self._reader_task = asyncio.create_task(self._read_loop(), name=f"stdio_reader_{self.server_id}")
63
- asyncio.create_task(self._log_stderr(), name=f"stdio_stderr_logger_{self.server_id}")
64
- logger.info(f"StdioClientConnection to '{self.server_id}' connected successfully (PID: {self._process.pid}).")
65
- except Exception as e:
66
- logger.error(f"Failed to connect StdioClientConnection to '{self.server_id}': {e}", exc_info=True)
67
- self._is_connected = False
68
- if self._process and self._process.returncode is None:
69
- self._process.terminate()
70
- await self._process.wait()
71
- self._process = None
72
- raise ConnectionError(f"Failed to start or connect to stdio server '{self.server_id}': {e}") from e
73
-
74
- async def _log_stderr(self) -> None:
75
- """Logs stderr from the subprocess."""
76
- if not self._process or not self._process.stderr:
77
- return
78
-
79
- try:
80
- while self._process.returncode is None:
81
- line_bytes = await self._process.stderr.readline()
82
- if not line_bytes:
83
- if self._process.returncode is not None:
84
- break
85
- await asyncio.sleep(0.01)
86
- continue
87
-
88
- line_str = line_bytes.decode(errors='replace').strip()
89
- if line_str:
90
- logger.warning(f"StdioServer '{self.server_id}' stderr: {line_str}")
91
-
92
- if self._process.returncode is not None and self._process.stderr.at_eof():
93
- break
94
-
95
- except asyncio.CancelledError:
96
- logger.info(f"Stderr logging for '{self.server_id}' cancelled.")
97
- except Exception as e:
98
- logger.error(f"Error in stderr logging for '{self.server_id}': {e}", exc_info=True)
99
- finally:
100
- logger.debug(f"Stderr logging task for '{self.server_id}' finished.")
101
-
102
-
103
- async def _read_loop(self) -> None:
104
- """Reads messages from stdout and dispatches them."""
105
- if not self._process or not self._process.stdout:
106
- logger.error(f"StdioClientConnection '{self.server_id}' read_loop: Process or stdout not available.")
107
- return
108
-
109
- try:
110
- while self._is_connected and self._process.returncode is None:
111
- line_bytes = await self._process.stdout.readline()
112
- if not line_bytes:
113
- logger.info(f"StdioServer '{self.server_id}' stdout EOF reached. Process likely terminated.")
114
- if self._is_connected:
115
- await self._handle_unexpected_disconnect()
116
- break
117
-
118
- line_str = line_bytes.decode().strip()
119
- if not line_str:
120
- continue
121
-
122
- try:
123
- message = ProtocolMessage.from_json_str(line_str)
124
- if message.id and message.id in self._response_futures:
125
- future = self._response_futures.pop(message.id, None)
126
- if future and not future.done():
127
- future.set_result(message)
128
- elif future and future.done():
129
- logger.warning(f"Future for response ID '{message.id}' was already done. Duplicate response or late arrival?")
130
- elif message.type == MessageType.EVENT:
131
- logger.info(f"Received EVENT message via stdio (unexpected for this model): {message}")
132
- else:
133
- logger.warning(f"Received stdio message with no matching future or unhandled type: {message}")
134
- except (json.JSONDecodeError, ValueError) as e:
135
- logger.error(f"Failed to parse ProtocolMessage from stdio server '{self.server_id}': {e}. Line: '{line_str[:200]}'")
136
- except Exception as e:
137
- logger.error(f"Unexpected error processing message from stdio server '{self.server_id}': {e}. Line: '{line_str[:200]}'", exc_info=True)
138
-
139
- except asyncio.CancelledError:
140
- logger.info(f"Stdio read_loop for '{self.server_id}' cancelled.")
141
- except Exception as e:
142
- logger.error(f"Fatal error in stdio read_loop for '{self.server_id}': {e}", exc_info=True)
143
- if self._is_connected:
144
- self._handle_unexpected_disconnect()
145
- finally:
146
- logger.info(f"Stdio read_loop for '{self.server_id}' exiting.")
147
- if self._is_connected:
148
- await self._handle_unexpected_disconnect(log_warning=False)
149
-
150
- async def _handle_unexpected_disconnect(self, log_warning=True):
151
- """Handles unexpected disconnection by failing pending futures."""
152
- if log_warning:
153
- logger.warning(f"StdioClientConnection to '{self.server_id}' unexpectedly disconnected or process terminated.")
154
- self._is_connected = False
155
-
156
- # Error response is not used here, futures are set with specific errors
157
- # error_response = ProtocolMessage.create_error_response(...)
158
- async with self._lock:
159
- for msg_id, future in list(self._response_futures.items()):
160
- if not future.done():
161
- custom_error = ProtocolMessage.create_error_response(
162
- id=msg_id, code=ErrorCode.INTERNAL_ERROR,
163
- message=f"Connection lost before response for request ID {msg_id} was received."
164
- )
165
- future.set_result(custom_error)
166
- self._response_futures.pop(msg_id, None)
167
-
168
-
169
- async def close(self) -> None:
170
- """Closes the connection and terminates the subprocess."""
171
- async with self._connection_lock:
172
- if not self._is_connected and not self._process:
173
- logger.debug(f"StdioClientConnection to '{self.server_id}' already closed or never connected.")
174
- return
175
-
176
- self._is_connected = False
177
-
178
- if self._reader_task and not self._reader_task.done():
179
- self._reader_task.cancel()
180
- try:
181
- await self._reader_task
182
- except asyncio.CancelledError:
183
- pass
184
- self._reader_task = None
185
-
186
- error_on_close = ProtocolMessage.create_error_response(
187
- id=None, code=ErrorCode.INTERNAL_ERROR, message="Connection closed by client while request was pending."
188
- )
189
- for msg_id, future in list(self._response_futures.items()):
190
- if not future.done():
191
- custom_error = ProtocolMessage.create_error_response(
192
- id=msg_id, code=ErrorCode.INTERNAL_ERROR,
193
- message=f"Connection closed for request ID {msg_id} before response."
194
- )
195
- future.set_result(custom_error)
196
- self._response_futures.pop(msg_id, None)
197
-
198
-
199
- if self._process:
200
- if self._process.returncode is None:
201
- logger.info(f"Terminating stdio server process for '{self.server_id}' (PID: {self._process.pid}).")
202
- try:
203
- self._process.terminate()
204
- await asyncio.wait_for(self._process.wait(), timeout=DEFAULT_STDIO_TIMEOUT / 2)
205
- except asyncio.TimeoutError:
206
- logger.warning(f"Timeout terminating stdio server '{self.server_id}'. Killing process.")
207
- if self._process.returncode is None: self._process.kill() # Check again before kill
208
- await self._process.wait()
209
- except Exception as e:
210
- logger.error(f"Error during stdio server termination for '{self.server_id}': {e}")
211
- else:
212
- logger.info(f"Stdio server process for '{self.server_id}' (PID: {self._process.pid}) already exited with code {self._process.returncode}.")
213
- self._process = None
214
-
215
- logger.info(f"StdioClientConnection to '{self.server_id}' closed.")
216
-
217
- async def send_request(self, request_message: ProtocolMessage) -> ProtocolMessage:
218
- """Sends a request and waits for a response."""
219
- if not self._is_connected or not self._process or not self._process.stdin:
220
- # Attempt to reconnect if not connected
221
- logger.info(f"StdioClientConnection '{self.server_id}' not connected. Attempting to connect before send_request.")
222
- await self.connect()
223
- if not self._is_connected or not self._process or not self._process.stdin:
224
- raise ConnectionError(f"Failed to connect to stdio server '{self.server_id}' for send_request.")
225
-
226
- if request_message.type != MessageType.REQUEST:
227
- raise ValueError("ProtocolMessage must be of type REQUEST to be sent via send_request.")
228
- if not request_message.id:
229
- raise ValueError("Request ProtocolMessage must have an ID.")
230
-
231
- future: asyncio.Future[ProtocolMessage] = asyncio.Future()
232
- async with self._lock:
233
- self._response_futures[request_message.id] = future
234
-
235
- try:
236
- json_str = request_message.to_json_str()
237
- logger.debug(f"StdioClient '{self.server_id}' sending: {json_str}")
238
- self._process.stdin.write(json_str.encode() + b'\n')
239
- await self._process.stdin.drain()
240
- except Exception as e:
241
- async with self._lock:
242
- self._response_futures.pop(request_message.id, None)
243
- # Don't cancel future, let it timeout or be resolved by _handle_unexpected_disconnect
244
- logger.error(f"Error sending request to stdio server '{self.server_id}': {e}", exc_info=True)
245
- # If send fails, connection is likely broken. Mark as such and try to close.
246
- await self.close()
247
- raise ConnectionError(f"Failed to send request to stdio server '{self.server_id}': {e}") from e
248
-
249
- try:
250
- response = await asyncio.wait_for(future, timeout=DEFAULT_STDIO_TIMEOUT)
251
- return response
252
- except asyncio.TimeoutError:
253
- logger.warning(f"Timeout waiting for response to request ID '{request_message.id}' from stdio server '{self.server_id}'.")
254
- async with self._lock:
255
- if request_message.id in self._response_futures:
256
- self._response_futures.pop(request_message.id, None)
257
- return ProtocolMessage.create_error_response(
258
- id=request_message.id,
259
- code=ErrorCode.SERVER_ERROR_TIMEOUT,
260
- message=f"Timeout waiting for response to request ID '{request_message.id}'."
261
- )
262
- except asyncio.CancelledError:
263
- logger.info(f"Request ID '{request_message.id}' was cancelled while awaiting response.")
264
- return ProtocolMessage.create_error_response(
265
- id=request_message.id,
266
- code=ErrorCode.INTERNAL_ERROR,
267
- message=f"Request ID '{request_message.id}' cancelled."
268
- )
269
-
270
- async def request_and_download_stream(
271
- self,
272
- stream_request_params: Dict[str, Any],
273
- target_agent_id: str
274
- ) -> AsyncIterator[bytes]:
275
- logger.warning(f"StdioClientConnection does not support HTTP stream downloads for target_agent_id '{target_agent_id}'.")
276
- raise NotImplementedError("StdioClientConnection does not support HTTP stream downloads.")
277
- # This construct makes it an async generator that immediately raises
278
- if False: # pragma: no cover
279
- yield b''
280
-
@@ -1,13 +0,0 @@
1
- # file: autobyteus/autobyteus/rpc/config/__init__.py
2
- """
3
- Configuration components for the AutoByteUs RPC framework.
4
- """
5
- from .agent_server_config import AgentServerConfig
6
- from .agent_server_registry import AgentServerRegistry, default_agent_server_registry
7
-
8
- __all__ = [
9
- "AgentServerConfig",
10
- "AgentServerRegistry",
11
- "default_agent_server_registry",
12
- ]
13
-
@@ -1,153 +0,0 @@
1
- # file: autobyteus/autobyteus/rpc/config/agent_server_config.py
2
- import logging
3
- from typing import Optional, Dict, Any, List # List was missing
4
- from pydantic import BaseModel, Field, validator, HttpUrl
5
-
6
- from autobyteus.rpc.transport_type import TransportType
7
-
8
- logger = logging.getLogger(__name__)
9
-
10
- class AgentServerConfig(BaseModel):
11
- """
12
- Configuration for an Agent Server, specifying how it can be connected to.
13
- """
14
- server_id: str = Field(..., description="Unique identifier for this server configuration.")
15
- transport_type: TransportType = Field(..., description="The transport mechanism (e.g., stdio, sse).")
16
-
17
- # For stdio transport
18
- stdio_command: Optional[List[str]] = Field(default=None, description="Command and arguments to launch the agent server process for stdio.")
19
-
20
- # For sse transport
21
- sse_base_url: Optional[HttpUrl] = Field(default=None, description="Base URL for the agent server's HTTP/SSE endpoints.")
22
- sse_request_endpoint: str = Field(default="/invoke", description="Relative path for synchronous requests (e.g., invoke_method).")
23
- sse_events_endpoint: str = Field(default="/events", description="Relative path for the Server-Sent Events stream.")
24
- # New field for HTTP stream downloads
25
- sse_stream_download_path_prefix: str = Field(default="/streams", description="Base relative path for HTTP stream downloads. Full path will be {base_url}{prefix}/{agent_id_on_server}/{stream_id}.")
26
-
27
-
28
- # Optional metadata
29
- metadata: Dict[str, Any] = Field(default_factory=dict, description="Optional metadata for the server configuration.")
30
-
31
- class Config:
32
- use_enum_values = True # Serialize enums to their values
33
- validate_assignment = True
34
-
35
- @validator('stdio_command')
36
- def _check_stdio_command(cls, v, values):
37
- if values.get('transport_type') == TransportType.STDIO and not v:
38
- raise ValueError("stdio_command is required for stdio transport type.")
39
- if values.get('transport_type') != TransportType.STDIO and v:
40
- logger.warning("stdio_command is provided but transport_type is not stdio. It will be ignored.")
41
- return v
42
-
43
- @validator('sse_base_url')
44
- def _check_sse_base_url(cls, v, values):
45
- if values.get('transport_type') == TransportType.SSE and not v:
46
- raise ValueError("sse_base_url is required for sse transport type.")
47
- if values.get('transport_type') != TransportType.SSE and v:
48
- logger.warning("sse_base_url is provided but transport_type is not sse. It will be ignored.")
49
- return v
50
-
51
- @validator('sse_stream_download_path_prefix')
52
- def _check_sse_stream_download_path_prefix(cls, v, values):
53
- if not v.startswith('/'):
54
- raise ValueError("sse_stream_download_path_prefix must start with a '/'.")
55
- if values.get('transport_type') != TransportType.SSE and v != "/streams": # if not default and not SSE
56
- logger.warning("sse_stream_download_path_prefix is customized but transport_type is not sse. It might be ignored.")
57
- return v
58
-
59
-
60
- def get_sse_full_request_url(self) -> Optional[str]:
61
- """Returns the full URL for SSE synchronous requests if applicable."""
62
- if self.transport_type == TransportType.SSE and self.sse_base_url:
63
- # Pydantic's HttpUrl converts to string automatically when concatenated this way
64
- return str(self.sse_base_url).rstrip('/') + self.sse_request_endpoint
65
- return None
66
-
67
- def get_sse_full_events_url(self) -> Optional[str]:
68
- """Returns the full URL for the SSE event stream if applicable."""
69
- if self.transport_type == TransportType.SSE and self.sse_base_url:
70
- return str(self.sse_base_url).rstrip('/') + self.sse_events_endpoint
71
- return None
72
-
73
- def get_sse_full_stream_download_url_prefix_for_agent(self, agent_id_on_server: str) -> Optional[str]:
74
- """
75
- Returns the full URL prefix for HTTP stream downloads for a specific agent,
76
- up to the point where stream_id should be appended.
77
- e.g., http://host:port/streams/{agent_id_on_server}
78
- """
79
- if self.transport_type == TransportType.SSE and self.sse_base_url:
80
- base = str(self.sse_base_url).rstrip('/')
81
- prefix = self.sse_stream_download_path_prefix.rstrip('/')
82
- return f"{base}{prefix}/{agent_id_on_server}"
83
- return None
84
-
85
-
86
- def __repr__(self) -> str:
87
- return f"<AgentServerConfig server_id='{self.server_id}', transport='{self.transport_type.value}'>"
88
-
89
- if __name__ == "__main__": # pragma: no cover
90
- logging.basicConfig(level=logging.DEBUG)
91
-
92
- # Stdio Example
93
- try:
94
- stdio_config_data = {
95
- "server_id": "local_agent_stdio",
96
- "transport_type": "stdio",
97
- "stdio_command": ["python", "-m", "autobyteus.agent.server_main", "--config-id", "local_agent_stdio"]
98
- }
99
- stdio_config = AgentServerConfig(**stdio_config_data)
100
- logger.info(f"Stdio Config: {stdio_config!r}")
101
- logger.info(f"Stdio Config (dict): {stdio_config.model_dump_json(indent=2)}")
102
- except ValueError as e:
103
- logger.error(f"Error creating stdio_config: {e}")
104
-
105
- # SSE Example
106
- try:
107
- sse_config_data = {
108
- "server_id": "remote_agent_sse",
109
- "transport_type": "sse",
110
- "sse_base_url": "http://localhost:8000/agent1",
111
- "sse_request_endpoint": "/api/request",
112
- "sse_events_endpoint": "/api/events",
113
- "sse_stream_download_path_prefix": "/downloadable_content" # Custom prefix
114
- }
115
- sse_config = AgentServerConfig(**sse_config_data)
116
- logger.info(f"SSE Config: {sse_config!r}")
117
- logger.info(f"SSE Config (dict): {sse_config.model_dump_json(indent=2)}")
118
- logger.info(f"SSE Request URL: {sse_config.get_sse_full_request_url()}")
119
- logger.info(f"SSE Events URL: {sse_config.get_sse_full_events_url()}")
120
- logger.info(f"SSE Stream Download URL prefix for agent 'test_agent': {sse_config.get_sse_full_stream_download_url_prefix_for_agent('test_agent')}")
121
-
122
- # Test HttpUrl string conversion
123
- assert isinstance(sse_config.sse_base_url, HttpUrl)
124
- logger.info(f"SSE base URL type: {type(sse_config.sse_base_url)}, value: {sse_config.sse_base_url}")
125
-
126
- except ValueError as e:
127
- logger.error(f"Error creating sse_config: {e}")
128
-
129
- # Validation error examples
130
- try:
131
- invalid_stdio_data = {"server_id": "invalid_stdio", "transport_type": "stdio"} # Missing stdio_command
132
- AgentServerConfig(**invalid_stdio_data)
133
- except ValueError as e:
134
- logger.error(f"Expected validation error (stdio): {e}")
135
-
136
- try:
137
- invalid_sse_data = {"server_id": "invalid_sse", "transport_type": "sse"} # Missing sse_base_url
138
- AgentServerConfig(**invalid_sse_data)
139
- except ValueError as e:
140
- logger.error(f"Expected validation error (sse): {e}")
141
-
142
- try:
143
- invalid_url_sse_data = {"server_id": "invalid_url_sse", "transport_type": "sse", "sse_base_url": "not_a_url"}
144
- AgentServerConfig(**invalid_url_sse_data)
145
- except ValueError as e:
146
- logger.error(f"Expected validation error (invalid sse_base_url): {e}")
147
-
148
- try:
149
- invalid_stream_prefix = {"server_id": "invalid_stream_prefix", "transport_type": "sse", "sse_base_url":"http://foo.com", "sse_stream_download_path_prefix": "no_slash_prefix"}
150
- AgentServerConfig(**invalid_stream_prefix)
151
- except ValueError as e:
152
- logger.error(f"Expected validation error (invalid sse_stream_download_path_prefix): {e}")
153
-
@@ -1,152 +0,0 @@
1
- # file: autobyteus/autobyteus/rpc/config/agent_server_registry.py
2
- import logging
3
- from typing import Dict, Optional, List
4
-
5
- from autobyteus.utils.singleton import SingletonMeta
6
- from .agent_server_config import AgentServerConfig
7
-
8
- logger = logging.getLogger(__name__)
9
-
10
- class AgentServerRegistry(metaclass=SingletonMeta):
11
- """
12
- A singleton registry for storing and managing AgentServerConfig objects.
13
- This allows different parts of the system to retrieve server connection
14
- details by a server_id.
15
- """
16
-
17
- def __init__(self):
18
- """Initializes the AgentServerRegistry with an empty store."""
19
- self._configs: Dict[str, AgentServerConfig] = {}
20
- logger.info("AgentServerRegistry initialized.")
21
-
22
- def register_config(self, config: AgentServerConfig) -> None:
23
- """
24
- Registers an agent server configuration.
25
- If a configuration with the same server_id already exists, it will be
26
- overwritten, and a warning will be logged.
27
-
28
- Args:
29
- config: The AgentServerConfig object to register.
30
-
31
- Raises:
32
- TypeError: If the provided config is not an AgentServerConfig instance.
33
- """
34
- if not isinstance(config, AgentServerConfig):
35
- raise TypeError(f"Expected AgentServerConfig instance, got {type(config).__name__}.")
36
-
37
- if config.server_id in self._configs:
38
- logger.warning(f"Overwriting existing agent server configuration for server_id: '{config.server_id}'.")
39
-
40
- self._configs[config.server_id] = config
41
- logger.info(f"AgentServerConfig for server_id '{config.server_id}' (transport: {config.transport_type.value}) registered.")
42
-
43
- def get_config(self, server_id: str) -> Optional[AgentServerConfig]:
44
- """
45
- Retrieves an agent server configuration by its server_id.
46
-
47
- Args:
48
- server_id: The unique identifier of the server configuration.
49
-
50
- Returns:
51
- The AgentServerConfig object if found, otherwise None.
52
- """
53
- if not isinstance(server_id, str):
54
- logger.warning(f"Attempted to retrieve agent server config with non-string server_id: {type(server_id).__name__}.")
55
- return None
56
-
57
- config = self._configs.get(server_id)
58
- if not config:
59
- logger.debug(f"AgentServerConfig with server_id '{server_id}' not found in registry.")
60
- return config
61
-
62
- def unregister_config(self, server_id: str) -> bool:
63
- """
64
- Removes an agent server configuration from the registry.
65
-
66
- Args:
67
- server_id: The server_id of the configuration to remove.
68
-
69
- Returns:
70
- True if the configuration was found and removed, False otherwise.
71
- """
72
- if not isinstance(server_id, str):
73
- logger.warning(f"Attempted to unregister agent server config with non-string server_id: {type(server_id).__name__}.")
74
- return False
75
-
76
- if server_id in self._configs:
77
- removed_config = self._configs.pop(server_id)
78
- logger.info(f"AgentServerConfig for server_id '{removed_config.server_id}' unregistered successfully.")
79
- return True
80
- else:
81
- logger.warning(f"AgentServerConfig with server_id '{server_id}' not found for unregistration.")
82
- return False
83
-
84
- def list_server_ids(self) -> List[str]:
85
- """Returns a list of all registered server_ids."""
86
- return list(self._configs.keys())
87
-
88
- def get_all_configs(self) -> Dict[str, AgentServerConfig]:
89
- """Returns a shallow copy of all registered configurations."""
90
- return dict(self._configs)
91
-
92
- def clear(self) -> None:
93
- """Removes all configurations from the registry."""
94
- count = len(self._configs)
95
- self._configs.clear()
96
- logger.info(f"Cleared {count} configurations from the AgentServerRegistry.")
97
-
98
- def __len__(self) -> int:
99
- return len(self._configs)
100
-
101
- def __contains__(self, server_id: str) -> bool:
102
- if isinstance(server_id, str):
103
- return server_id in self._configs
104
- return False
105
-
106
- # Default global instance of the registry
107
- default_agent_server_registry = AgentServerRegistry()
108
-
109
- if __name__ == "__main__": # pragma: no cover
110
- logging.basicConfig(level=logging.DEBUG)
111
-
112
- registry = default_agent_server_registry # Use the default instance
113
-
114
- # Stdio Config
115
- stdio_config_data = {
116
- "server_id": "local_agent_stdio_main",
117
- "transport_type": "stdio",
118
- "stdio_command": ["python", "-m", "some_module"]
119
- }
120
- stdio_conf = AgentServerConfig(**stdio_config_data)
121
- registry.register_config(stdio_conf)
122
-
123
- # SSE Config
124
- sse_config_data = {
125
- "server_id": "remote_agent_sse_main",
126
- "transport_type": "sse",
127
- "sse_base_url": "http://localhost:8080"
128
- }
129
- sse_conf = AgentServerConfig(**sse_config_data)
130
- registry.register_config(sse_conf)
131
-
132
- logger.info(f"Registered server IDs: {registry.list_server_ids()}")
133
-
134
- retrieved_stdio = registry.get_config("local_agent_stdio_main")
135
- if retrieved_stdio:
136
- logger.info(f"Retrieved Stdio Config: {retrieved_stdio.stdio_command}")
137
-
138
- retrieved_sse = registry.get_config("remote_agent_sse_main")
139
- if retrieved_sse:
140
- logger.info(f"Retrieved SSE Config URL: {retrieved_sse.get_sse_full_request_url()}")
141
-
142
- assert "local_agent_stdio_main" in registry
143
- assert len(registry) == 2
144
-
145
- registry.unregister_config("local_agent_stdio_main")
146
- assert "local_agent_stdio_main" not in registry
147
- logger.info(f"After unregistering, server IDs: {registry.list_server_ids()}")
148
-
149
- registry.clear()
150
- assert len(registry) == 0
151
- logger.info(f"After clearing, server IDs: {registry.list_server_ids()}")
152
-