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
@@ -39,6 +39,57 @@ class LMStudioModelProvider:
39
39
  except Exception:
40
40
  return False
41
41
 
42
+ @staticmethod
43
+ def get_models() -> List[LLMModel]:
44
+ """
45
+ Fetches models from all configured LM Studio instances and returns them as LLMModel objects.
46
+ """
47
+ hosts = LMStudioModelProvider._get_hosts()
48
+ all_models = []
49
+
50
+ for host_url in hosts:
51
+ if not LMStudioModelProvider.is_valid_url(host_url):
52
+ logger.error(f"Invalid LM Studio host URL: {host_url}, skipping.")
53
+ continue
54
+
55
+ logger.info(f"Discovering LM Studio models from host: {host_url}")
56
+ base_url = f"{host_url}/v1"
57
+ client = OpenAI(base_url=base_url, api_key="lm-studio") # Dummy key
58
+
59
+ try:
60
+ response = client.models.list()
61
+ models = response.data
62
+ except APIConnectionError:
63
+ logger.warning(f"Could not connect to LM Studio at {host_url}. Please ensure the server is running.")
64
+ continue
65
+ except OpenAIError as e:
66
+ logger.error(f"An error occurred fetching models from LM Studio at {host_url}: {e}")
67
+ continue
68
+
69
+ for model_info in models:
70
+ model_id = model_info.id
71
+ if not model_id:
72
+ continue
73
+
74
+ try:
75
+ llm_model = LLMModel(
76
+ name=model_id,
77
+ value=model_id,
78
+ provider=LLMProvider.LMSTUDIO, # LMStudio is both provider and runtime
79
+ llm_class=LMStudioLLM,
80
+ canonical_name=model_id,
81
+ runtime=LLMRuntime.LMSTUDIO,
82
+ host_url=host_url,
83
+ default_config=LLMConfig(
84
+ pricing_config=TokenPricingConfig(0.0, 0.0) # Local models are free
85
+ )
86
+ )
87
+ all_models.append(llm_model)
88
+ except Exception as e:
89
+ logger.warning(f"Failed to create LLMModel for '{model_id}' from {host_url}: {e}")
90
+
91
+ return all_models
92
+
42
93
  @staticmethod
43
94
  def discover_and_register():
44
95
  """
@@ -47,58 +98,18 @@ class LMStudioModelProvider:
47
98
  try:
48
99
  from autobyteus.llm.llm_factory import LLMFactory
49
100
 
50
- hosts = LMStudioModelProvider._get_hosts()
51
- total_registered_count = 0
52
-
53
- for host_url in hosts:
54
- if not LMStudioModelProvider.is_valid_url(host_url):
55
- logger.error(f"Invalid LM Studio host URL: {host_url}, skipping.")
56
- continue
57
-
58
- logger.info(f"Discovering LM Studio models from host: {host_url}")
59
- base_url = f"{host_url}/v1"
60
- client = OpenAI(base_url=base_url, api_key="lm-studio") # Dummy key
101
+ discovered_models = LMStudioModelProvider.get_models()
102
+ registered_count = 0
61
103
 
104
+ for model in discovered_models:
62
105
  try:
63
- response = client.models.list()
64
- models = response.data
65
- except APIConnectionError:
66
- logger.warning(f"Could not connect to LM Studio at {host_url}. Please ensure the server is running.")
67
- continue
68
- except OpenAIError as e:
69
- logger.error(f"An error occurred fetching models from LM Studio at {host_url}: {e}")
70
- continue
71
-
72
- host_registered_count = 0
73
- for model_info in models:
74
- model_id = model_info.id
75
- if not model_id:
76
- continue
77
-
78
- try:
79
- llm_model = LLMModel(
80
- name=model_id,
81
- value=model_id,
82
- provider=LLMProvider.LMSTUDIO, # LMStudio is both provider and runtime
83
- llm_class=LMStudioLLM,
84
- canonical_name=model_id,
85
- runtime=LLMRuntime.LMSTUDIO,
86
- host_url=host_url,
87
- default_config=LLMConfig(
88
- pricing_config=TokenPricingConfig(0.0, 0.0) # Local models are free
89
- )
90
- )
91
- LLMFactory.register_model(llm_model)
92
- host_registered_count += 1
93
- except Exception as e:
94
- logger.warning(f"Failed to register LM Studio model '{model_id}' from {host_url}: {e}")
95
-
96
- if host_registered_count > 0:
97
- logger.info(f"Registered {host_registered_count} models from LM Studio host {host_url}")
98
- total_registered_count += host_registered_count
106
+ LLMFactory.register_model(model)
107
+ registered_count += 1
108
+ except Exception as e:
109
+ logger.warning(f"Failed to register LM Studio model '{model.name}': {e}")
99
110
 
100
- if total_registered_count > 0:
101
- logger.info(f"Finished LM Studio discovery. Total models registered: {total_registered_count}")
111
+ if registered_count > 0:
112
+ logger.info(f"Finished LM Studio discovery. Total models registered: {registered_count}")
102
113
 
103
114
  except Exception as e:
104
115
  logger.error(f"An unexpected error occurred during LM Studio model discovery: {e}")
autobyteus/llm/models.py CHANGED
@@ -1,17 +1,19 @@
1
1
  import logging
2
- from typing import TYPE_CHECKING, Type, Optional, List, Iterator
2
+ from typing import TYPE_CHECKING, Type, Optional, List, Iterator, Dict, Any
3
3
  from dataclasses import dataclass
4
4
  from urllib.parse import urlparse
5
5
 
6
6
  from autobyteus.llm.providers import LLMProvider
7
7
  from autobyteus.llm.runtimes import LLMRuntime
8
8
  from autobyteus.llm.utils.llm_config import LLMConfig
9
+ from autobyteus.utils.parameter_schema import ParameterSchema
9
10
 
10
11
  if TYPE_CHECKING:
11
12
  from autobyteus.llm.base_llm import BaseLLM
12
13
  from autobyteus.llm.llm_factory import LLMFactory
13
14
 
14
15
  logger = logging.getLogger(__name__)
16
+ DEFAULT_MAX_CONTEXT_TOKENS = 200000
15
17
 
16
18
  @dataclass
17
19
  class ModelInfo:
@@ -23,6 +25,7 @@ class ModelInfo:
23
25
  provider: str
24
26
  runtime: str
25
27
  host_url: Optional[str] = None
28
+ config_schema: Optional[Dict[str, Any]] = None # Serialized ParameterSchema
26
29
 
27
30
  @dataclass
28
31
  class ProviderModelGroup:
@@ -101,7 +104,11 @@ class LLMModel(metaclass=LLMModelMeta):
101
104
  canonical_name: str,
102
105
  default_config: Optional[LLMConfig] = None,
103
106
  runtime: LLMRuntime = LLMRuntime.API,
104
- host_url: Optional[str] = None
107
+ host_url: Optional[str] = None,
108
+ config_schema: Optional[ParameterSchema] = None,
109
+ max_context_tokens: Optional[int] = None,
110
+ default_compaction_ratio: float = 0.8,
111
+ default_safety_margin_tokens: int = 256,
105
112
  ):
106
113
  self._name = name
107
114
  self._value = value
@@ -109,8 +116,18 @@ class LLMModel(metaclass=LLMModelMeta):
109
116
  self.provider = provider
110
117
  self.llm_class = llm_class
111
118
  self.default_config = default_config if default_config else LLMConfig()
119
+ if max_context_tokens is None:
120
+ max_context_tokens = (
121
+ self.default_config.token_limit
122
+ if self.default_config.token_limit is not None
123
+ else DEFAULT_MAX_CONTEXT_TOKENS
124
+ )
125
+ self.max_context_tokens = max_context_tokens
126
+ self.default_compaction_ratio = default_compaction_ratio
127
+ self.default_safety_margin_tokens = default_safety_margin_tokens
112
128
  self.runtime = runtime
113
129
  self.host_url = host_url
130
+ self.config_schema = config_schema
114
131
  self._model_identifier = self._generate_identifier()
115
132
 
116
133
  def _generate_identifier(self) -> str:
@@ -183,6 +200,22 @@ class LLMModel(metaclass=LLMModelMeta):
183
200
 
184
201
  return self.llm_class(model=self, llm_config=config_to_use)
185
202
 
203
+ def to_model_info(self) -> ModelInfo:
204
+ """
205
+ Converts this LLMModel to a ModelInfo data structure for API responses.
206
+ Serializes the config_schema if present.
207
+ """
208
+ return ModelInfo(
209
+ model_identifier=self.model_identifier,
210
+ display_name=self.name,
211
+ value=self.value,
212
+ canonical_name=self.canonical_name,
213
+ provider=self.provider.value,
214
+ runtime=self.runtime.value,
215
+ host_url=self.host_url,
216
+ config_schema=self.config_schema.to_dict() if self.config_schema else None
217
+ )
218
+
186
219
  def __repr__(self):
187
220
  return (
188
221
  f"LLMModel(identifier='{self.model_identifier}', name='{self.name}', "
@@ -44,6 +44,58 @@ class OllamaModelProvider:
44
44
  except Exception:
45
45
  return False
46
46
 
47
+ @staticmethod
48
+ def get_models() -> List[LLMModel]:
49
+ """
50
+ Fetches models from all configured Ollama hosts and returns them as LLMModel objects.
51
+ """
52
+ hosts = OllamaModelProvider._get_hosts()
53
+ all_models = []
54
+
55
+ for host_url in hosts:
56
+ if not OllamaModelProvider.is_valid_url(host_url):
57
+ logger.error(f"Invalid Ollama host URL provided: '{host_url}', skipping.")
58
+ continue
59
+
60
+ logger.info(f"Discovering Ollama models from host: {host_url}")
61
+ client = Client(host=host_url)
62
+
63
+ try:
64
+ response = client.list()
65
+ models = response.get('models', [])
66
+ except httpx.ConnectError:
67
+ logger.warning(f"Could not connect to Ollama server at {host_url}. Please ensure it's running.")
68
+ continue
69
+ except Exception as e:
70
+ logger.error(f"Failed to fetch models from {host_url}: {e}")
71
+ continue
72
+
73
+ for model_info in models:
74
+ model_name = model_info.get('model')
75
+ if not model_name:
76
+ continue
77
+
78
+ try:
79
+ provider = OllamaProviderResolver.resolve(model_name)
80
+
81
+ llm_model = LLMModel(
82
+ name=model_name,
83
+ value=model_name,
84
+ provider=provider,
85
+ llm_class=OllamaLLM,
86
+ canonical_name=model_name,
87
+ runtime=LLMRuntime.OLLAMA,
88
+ host_url=host_url,
89
+ default_config=LLMConfig(
90
+ pricing_config=TokenPricingConfig(0.0, 0.0) # Local models are free
91
+ )
92
+ )
93
+ all_models.append(llm_model)
94
+ except Exception as e:
95
+ logger.warning(f"Failed to create LLMModel for '{model_name}' from host {host_url}: {e}")
96
+
97
+ return all_models
98
+
47
99
  @staticmethod
48
100
  def discover_and_register():
49
101
  """
@@ -52,59 +104,18 @@ class OllamaModelProvider:
52
104
  try:
53
105
  from autobyteus.llm.llm_factory import LLMFactory
54
106
 
55
- hosts = OllamaModelProvider._get_hosts()
56
- total_registered_count = 0
107
+ discovered_models = OllamaModelProvider.get_models()
108
+ registered_count = 0
57
109
 
58
- for host_url in hosts:
59
- if not OllamaModelProvider.is_valid_url(host_url):
60
- logger.error(f"Invalid Ollama host URL provided: '{host_url}', skipping.")
61
- continue
62
-
63
- logger.info(f"Discovering Ollama models from host: {host_url}")
64
- client = Client(host=host_url)
65
-
110
+ for model in discovered_models:
66
111
  try:
67
- response = client.list()
68
- models = response.get('models', [])
69
- except httpx.ConnectError:
70
- logger.warning(f"Could not connect to Ollama server at {host_url}. Please ensure it's running.")
71
- continue
112
+ LLMFactory.register_model(model)
113
+ registered_count += 1
72
114
  except Exception as e:
73
- logger.error(f"Failed to fetch models from {host_url}: {e}")
74
- continue
75
-
76
- host_registered_count = 0
77
- for model_info in models:
78
- model_name = model_info.get('model')
79
- if not model_name:
80
- continue
81
-
82
- try:
83
- provider = OllamaProviderResolver.resolve(model_name)
84
-
85
- llm_model = LLMModel(
86
- name=model_name,
87
- value=model_name,
88
- provider=provider,
89
- llm_class=OllamaLLM,
90
- canonical_name=model_name,
91
- runtime=LLMRuntime.OLLAMA,
92
- host_url=host_url,
93
- default_config=LLMConfig(
94
- pricing_config=TokenPricingConfig(0.0, 0.0) # Local models are free
95
- )
96
- )
97
- LLMFactory.register_model(llm_model)
98
- host_registered_count += 1
99
- except Exception as e:
100
- logger.warning(f"Failed to register model '{model_name}' from host {host_url}: {e}")
101
-
102
- if host_registered_count > 0:
103
- logger.info(f"Registered {host_registered_count} models from Ollama host {host_url}")
104
- total_registered_count += host_registered_count
115
+ logger.warning(f"Failed to register Ollama model '{model.name}': {e}")
105
116
 
106
- if total_registered_count > 0:
107
- logger.info(f"Finished Ollama discovery. Total models registered: {total_registered_count}")
117
+ if registered_count > 0:
118
+ logger.info(f"Finished Ollama discovery. Total models registered: {registered_count}")
108
119
 
109
120
  except Exception as e:
110
121
  logger.error(f"An unexpected error occurred during Ollama model discovery: {e}")
@@ -15,7 +15,6 @@ class OllamaProviderResolver:
15
15
  KEYWORD_PROVIDER_MAP = [
16
16
  (['gpt'], LLMProvider.OPENAI),
17
17
  (['gemma', 'gemini'], LLMProvider.GEMINI),
18
- (['llama'], LLMProvider.GROQ),
19
18
  (['mistral'], LLMProvider.MISTRAL),
20
19
  (['deepseek'], LLMProvider.DEEPSEEK),
21
20
  (['qwen'], LLMProvider.QWEN),
@@ -0,0 +1,19 @@
1
+ from autobyteus.llm.prompt_renderers.base_prompt_renderer import BasePromptRenderer
2
+ from autobyteus.llm.prompt_renderers.openai_responses_renderer import OpenAIResponsesRenderer
3
+ from autobyteus.llm.prompt_renderers.openai_chat_renderer import OpenAIChatRenderer
4
+ from autobyteus.llm.prompt_renderers.anthropic_prompt_renderer import AnthropicPromptRenderer
5
+ from autobyteus.llm.prompt_renderers.gemini_prompt_renderer import GeminiPromptRenderer
6
+ from autobyteus.llm.prompt_renderers.mistral_prompt_renderer import MistralPromptRenderer
7
+ from autobyteus.llm.prompt_renderers.ollama_prompt_renderer import OllamaPromptRenderer
8
+ from autobyteus.llm.prompt_renderers.autobyteus_prompt_renderer import AutobyteusPromptRenderer
9
+
10
+ __all__ = [
11
+ "BasePromptRenderer",
12
+ "OpenAIResponsesRenderer",
13
+ "OpenAIChatRenderer",
14
+ "AnthropicPromptRenderer",
15
+ "GeminiPromptRenderer",
16
+ "MistralPromptRenderer",
17
+ "OllamaPromptRenderer",
18
+ "AutobyteusPromptRenderer",
19
+ ]
@@ -0,0 +1,104 @@
1
+ import asyncio
2
+ import json
3
+ import logging
4
+ from typing import List, Dict, Any
5
+
6
+ from autobyteus.llm.prompt_renderers.base_prompt_renderer import BasePromptRenderer
7
+ from autobyteus.llm.utils.media_payload_formatter import (
8
+ media_source_to_base64,
9
+ get_mime_type,
10
+ is_valid_media_path,
11
+ )
12
+ from autobyteus.llm.utils.messages import Message, MessageRole, ToolCallPayload, ToolResultPayload
13
+
14
+ logger = logging.getLogger(__name__)
15
+
16
+
17
+ class AnthropicPromptRenderer(BasePromptRenderer):
18
+ async def render(self, messages: List[Message]) -> List[Dict[str, Any]]:
19
+ formatted_messages: List[Dict[str, Any]] = []
20
+ valid_image_mimes = {"image/jpeg", "image/png", "image/gif", "image/webp"}
21
+
22
+ for msg in messages:
23
+ role = msg.role.value
24
+ if msg.tool_payload or msg.role == MessageRole.TOOL:
25
+ payload_text = _format_tool_payload(msg)
26
+ role = (
27
+ MessageRole.USER.value
28
+ if msg.role == MessageRole.TOOL
29
+ else MessageRole.ASSISTANT.value
30
+ )
31
+ msg = Message(
32
+ role=MessageRole.USER
33
+ if role == MessageRole.USER.value
34
+ else MessageRole.ASSISTANT,
35
+ content=payload_text or "",
36
+ )
37
+
38
+ if msg.image_urls:
39
+ content_blocks: List[Dict[str, Any]] = []
40
+
41
+ image_tasks = [media_source_to_base64(url) for url in msg.image_urls]
42
+ try:
43
+ base64_images = await asyncio.gather(*image_tasks)
44
+
45
+ for i, b64_data in enumerate(base64_images):
46
+ original_url = msg.image_urls[i]
47
+ mime_type = get_mime_type(original_url)
48
+
49
+ if mime_type not in valid_image_mimes:
50
+ logger.warning(
51
+ "Unsupported image MIME type '%s' for %s. "
52
+ "Anthropic supports: %s. Defaulting to image/jpeg.",
53
+ mime_type,
54
+ original_url,
55
+ valid_image_mimes,
56
+ )
57
+ mime_type = "image/jpeg"
58
+
59
+ content_blocks.append(
60
+ {
61
+ "type": "image",
62
+ "source": {
63
+ "type": "base64",
64
+ "media_type": mime_type,
65
+ "data": b64_data,
66
+ },
67
+ }
68
+ )
69
+ except Exception as e:
70
+ logger.error("Error processing images for Claude: %s", e)
71
+
72
+ if msg.content:
73
+ content_blocks.append({"type": "text", "text": msg.content})
74
+
75
+ formatted_messages.append({"role": role, "content": content_blocks})
76
+ else:
77
+ formatted_messages.append(
78
+ {
79
+ "role": role,
80
+ "content": msg.content or "",
81
+ }
82
+ )
83
+
84
+ return formatted_messages
85
+
86
+
87
+ def _format_tool_payload(message: Message) -> str:
88
+ payload = message.tool_payload
89
+ if isinstance(payload, ToolCallPayload):
90
+ lines = []
91
+ for call in payload.tool_calls:
92
+ args = call.arguments
93
+ if isinstance(args, (dict, list)):
94
+ args = json.dumps(args, ensure_ascii=True)
95
+ lines.append(f"[TOOL_CALL] {call.name} {args}")
96
+ return "\n".join(lines)
97
+ if isinstance(payload, ToolResultPayload):
98
+ if payload.tool_error:
99
+ return f"[TOOL_ERROR] {payload.tool_name} {payload.tool_error}"
100
+ result = payload.tool_result
101
+ if isinstance(result, (dict, list)):
102
+ result = json.dumps(result, ensure_ascii=True)
103
+ return f"[TOOL_RESULT] {payload.tool_name} {result}"
104
+ return message.content or ""
@@ -0,0 +1,19 @@
1
+ from typing import List, Dict, Any
2
+
3
+ from autobyteus.llm.prompt_renderers.base_prompt_renderer import BasePromptRenderer
4
+ from autobyteus.llm.utils.messages import Message, MessageRole
5
+
6
+
7
+ class AutobyteusPromptRenderer(BasePromptRenderer):
8
+ async def render(self, messages: List[Message]) -> List[Dict[str, Any]]:
9
+ for msg in reversed(messages):
10
+ if msg.role == MessageRole.USER:
11
+ return [
12
+ {
13
+ "content": msg.content or "",
14
+ "image_urls": list(msg.image_urls),
15
+ "audio_urls": list(msg.audio_urls),
16
+ "video_urls": list(msg.video_urls),
17
+ }
18
+ ]
19
+ raise ValueError("AutobyteusPromptRenderer requires at least one user message.")
@@ -0,0 +1,10 @@
1
+ from abc import ABC, abstractmethod
2
+ from typing import List, Dict, Any
3
+
4
+ from autobyteus.llm.utils.messages import Message
5
+
6
+
7
+ class BasePromptRenderer(ABC):
8
+ @abstractmethod
9
+ async def render(self, messages: List[Message]) -> List[Dict[str, Any]]:
10
+ raise NotImplementedError
@@ -0,0 +1,63 @@
1
+ import base64
2
+ import mimetypes
3
+ import logging
4
+ from typing import Dict, List, Any, Optional
5
+
6
+ from google.genai import types as genai_types
7
+
8
+ from autobyteus.llm.prompt_renderers.base_prompt_renderer import BasePromptRenderer
9
+ from autobyteus.llm.utils.messages import Message, MessageRole, ToolCallPayload, ToolResultPayload
10
+ from autobyteus.llm.utils.media_payload_formatter import media_source_to_base64, get_mime_type
11
+
12
+ logger = logging.getLogger(__name__)
13
+
14
+
15
+ class GeminiPromptRenderer(BasePromptRenderer):
16
+ async def render(self, messages: List[Message]) -> List[Dict[str, Any]]:
17
+ history: List[Dict[str, Any]] = []
18
+ for msg in messages:
19
+ role = None
20
+ content_text = msg.content
21
+ if msg.tool_payload or msg.role == MessageRole.TOOL:
22
+ content_text = _format_tool_payload(msg)
23
+ role = "model" if msg.role == MessageRole.ASSISTANT else "user"
24
+ elif msg.role in (MessageRole.USER, MessageRole.ASSISTANT):
25
+ role = "model" if msg.role == MessageRole.ASSISTANT else "user"
26
+ else:
27
+ continue
28
+
29
+ if role is None:
30
+ continue
31
+
32
+ parts: List[Any] = []
33
+ if content_text:
34
+ parts.append({"text": content_text})
35
+
36
+ media_urls = msg.image_urls + msg.audio_urls + msg.video_urls
37
+ for url in media_urls:
38
+ try:
39
+ b64_data = await media_source_to_base64(url)
40
+ data_bytes = base64.b64decode(b64_data)
41
+ mime_type, _ = mimetypes.guess_type(url)
42
+ if not mime_type:
43
+ mime_type = get_mime_type(url)
44
+ parts.append(genai_types.Part.from_bytes(data=data_bytes, mime_type=mime_type))
45
+ except Exception as exc:
46
+ logger.error("Failed to process media content %s: %s", url, exc)
47
+
48
+ if parts:
49
+ history.append({"role": role, "parts": parts})
50
+
51
+ return history
52
+
53
+
54
+ def _format_tool_payload(message: Message) -> Optional[str]:
55
+ payload = message.tool_payload
56
+ if isinstance(payload, ToolCallPayload):
57
+ lines = [f"[TOOL_CALL] {call.name} {call.arguments}" for call in payload.tool_calls]
58
+ return "\n".join(lines)
59
+ if isinstance(payload, ToolResultPayload):
60
+ if payload.tool_error:
61
+ return f"[TOOL_ERROR] {payload.tool_name} {payload.tool_error}"
62
+ return f"[TOOL_RESULT] {payload.tool_name} {payload.tool_result}"
63
+ return None
@@ -0,0 +1,87 @@
1
+ import asyncio
2
+ import logging
3
+ from typing import Dict, List, Any, Optional, Union
4
+
5
+ from autobyteus.llm.prompt_renderers.base_prompt_renderer import BasePromptRenderer
6
+ from autobyteus.llm.utils.messages import Message, MessageRole, ToolCallPayload, ToolResultPayload
7
+ from autobyteus.llm.utils.media_payload_formatter import (
8
+ media_source_to_base64,
9
+ get_mime_type,
10
+ is_valid_media_path,
11
+ )
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+
16
+ class MistralPromptRenderer(BasePromptRenderer):
17
+ async def render(self, messages: List[Message]) -> List[Dict[str, Any]]:
18
+ mistral_messages: List[Dict[str, Any]] = []
19
+ for msg in messages:
20
+ role = msg.role.value
21
+ if msg.tool_payload or msg.role == MessageRole.TOOL:
22
+ content_text = _format_tool_payload(msg) or ""
23
+ role = (
24
+ MessageRole.USER.value
25
+ if msg.role == MessageRole.TOOL
26
+ else MessageRole.ASSISTANT.value
27
+ )
28
+ msg = Message(
29
+ role=MessageRole.USER
30
+ if role == MessageRole.USER.value
31
+ else MessageRole.ASSISTANT,
32
+ content=content_text,
33
+ )
34
+
35
+ if not msg.content and not msg.image_urls and msg.role != MessageRole.SYSTEM:
36
+ continue
37
+
38
+ content: Union[str, List[Dict[str, Any]]]
39
+ if msg.image_urls:
40
+ content_parts: List[Dict[str, Any]] = []
41
+ if msg.content:
42
+ content_parts.append({"type": "text", "text": msg.content})
43
+
44
+ image_tasks = [media_source_to_base64(url) for url in msg.image_urls]
45
+ try:
46
+ base64_images = await asyncio.gather(*image_tasks)
47
+ for i, b64_image in enumerate(base64_images):
48
+ original_url = msg.image_urls[i]
49
+ mime_type = (
50
+ get_mime_type(original_url)
51
+ if is_valid_media_path(original_url)
52
+ else "image/jpeg"
53
+ )
54
+ data_uri = f"data:{mime_type};base64,{b64_image}"
55
+ content_parts.append(
56
+ {
57
+ "type": "image_url",
58
+ "image_url": {"url": data_uri},
59
+ }
60
+ )
61
+ except Exception as exc:
62
+ logger.error("Error processing images for Mistral: %s", exc)
63
+
64
+ if msg.audio_urls:
65
+ logger.warning("MistralLLM does not yet support audio; skipping.")
66
+ if msg.video_urls:
67
+ logger.warning("MistralLLM does not yet support video; skipping.")
68
+
69
+ content = content_parts
70
+ else:
71
+ content = msg.content or ""
72
+
73
+ mistral_messages.append({"role": role, "content": content})
74
+
75
+ return mistral_messages
76
+
77
+
78
+ def _format_tool_payload(message: Message) -> Optional[str]:
79
+ payload = message.tool_payload
80
+ if isinstance(payload, ToolCallPayload):
81
+ lines = [f"[TOOL_CALL] {call.name} {call.arguments}" for call in payload.tool_calls]
82
+ return "\n".join(lines)
83
+ if isinstance(payload, ToolResultPayload):
84
+ if payload.tool_error:
85
+ return f"[TOOL_ERROR] {payload.tool_name} {payload.tool_error}"
86
+ return f"[TOOL_RESULT] {payload.tool_name} {payload.tool_result}"
87
+ return None