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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (472) hide show
  1. autobyteus/agent/agent.py +15 -5
  2. autobyteus/agent/bootstrap_steps/__init__.py +3 -3
  3. autobyteus/agent/bootstrap_steps/agent_bootstrapper.py +5 -59
  4. autobyteus/agent/bootstrap_steps/base_bootstrap_step.py +1 -4
  5. autobyteus/agent/bootstrap_steps/mcp_server_prewarming_step.py +1 -3
  6. autobyteus/agent/bootstrap_steps/system_prompt_processing_step.py +16 -13
  7. autobyteus/agent/bootstrap_steps/working_context_snapshot_restore_step.py +38 -0
  8. autobyteus/agent/bootstrap_steps/workspace_context_initialization_step.py +2 -4
  9. autobyteus/agent/context/agent_config.py +47 -20
  10. autobyteus/agent/context/agent_context.py +23 -18
  11. autobyteus/agent/context/agent_runtime_state.py +21 -19
  12. autobyteus/agent/events/__init__.py +16 -1
  13. autobyteus/agent/events/agent_events.py +43 -3
  14. autobyteus/agent/events/agent_input_event_queue_manager.py +79 -26
  15. autobyteus/agent/events/event_store.py +57 -0
  16. autobyteus/agent/events/notifiers.py +69 -59
  17. autobyteus/agent/events/worker_event_dispatcher.py +21 -64
  18. autobyteus/agent/factory/agent_factory.py +83 -6
  19. autobyteus/agent/handlers/__init__.py +2 -0
  20. autobyteus/agent/handlers/approved_tool_invocation_event_handler.py +51 -34
  21. autobyteus/agent/handlers/bootstrap_event_handler.py +155 -0
  22. autobyteus/agent/handlers/inter_agent_message_event_handler.py +10 -0
  23. autobyteus/agent/handlers/lifecycle_event_logger.py +19 -11
  24. autobyteus/agent/handlers/llm_complete_response_received_event_handler.py +10 -15
  25. autobyteus/agent/handlers/llm_user_message_ready_event_handler.py +188 -48
  26. autobyteus/agent/handlers/tool_execution_approval_event_handler.py +0 -10
  27. autobyteus/agent/handlers/tool_invocation_request_event_handler.py +53 -48
  28. autobyteus/agent/handlers/tool_result_event_handler.py +7 -8
  29. autobyteus/agent/handlers/user_input_message_event_handler.py +10 -3
  30. autobyteus/agent/input_processor/memory_ingest_input_processor.py +44 -0
  31. autobyteus/agent/lifecycle/__init__.py +12 -0
  32. autobyteus/agent/lifecycle/base_processor.py +109 -0
  33. autobyteus/agent/lifecycle/events.py +35 -0
  34. autobyteus/agent/lifecycle/processor_definition.py +36 -0
  35. autobyteus/agent/lifecycle/processor_registry.py +106 -0
  36. autobyteus/agent/llm_request_assembler.py +98 -0
  37. autobyteus/agent/llm_response_processor/__init__.py +1 -8
  38. autobyteus/agent/message/context_file_type.py +1 -1
  39. autobyteus/agent/runtime/agent_runtime.py +29 -21
  40. autobyteus/agent/runtime/agent_worker.py +98 -19
  41. autobyteus/agent/shutdown_steps/__init__.py +2 -0
  42. autobyteus/agent/shutdown_steps/agent_shutdown_orchestrator.py +2 -0
  43. autobyteus/agent/shutdown_steps/tool_cleanup_step.py +58 -0
  44. autobyteus/agent/status/__init__.py +14 -0
  45. autobyteus/agent/status/manager.py +93 -0
  46. autobyteus/agent/status/status_deriver.py +96 -0
  47. autobyteus/agent/{phases/phase_enum.py → status/status_enum.py} +16 -16
  48. autobyteus/agent/status/status_update_utils.py +73 -0
  49. autobyteus/agent/streaming/__init__.py +52 -5
  50. autobyteus/agent/streaming/adapters/__init__.py +18 -0
  51. autobyteus/agent/streaming/adapters/invocation_adapter.py +184 -0
  52. autobyteus/agent/streaming/adapters/tool_call_parsing.py +163 -0
  53. autobyteus/agent/streaming/adapters/tool_syntax_registry.py +67 -0
  54. autobyteus/agent/streaming/agent_event_stream.py +3 -183
  55. autobyteus/agent/streaming/api_tool_call/__init__.py +16 -0
  56. autobyteus/agent/streaming/api_tool_call/file_content_streamer.py +56 -0
  57. autobyteus/agent/streaming/api_tool_call/json_string_field_extractor.py +175 -0
  58. autobyteus/agent/streaming/api_tool_call_streaming_response_handler.py +4 -0
  59. autobyteus/agent/streaming/events/__init__.py +6 -0
  60. autobyteus/agent/streaming/events/stream_event_payloads.py +284 -0
  61. autobyteus/agent/streaming/events/stream_events.py +141 -0
  62. autobyteus/agent/streaming/handlers/__init__.py +15 -0
  63. autobyteus/agent/streaming/handlers/api_tool_call_streaming_response_handler.py +303 -0
  64. autobyteus/agent/streaming/handlers/parsing_streaming_response_handler.py +107 -0
  65. autobyteus/agent/streaming/handlers/pass_through_streaming_response_handler.py +107 -0
  66. autobyteus/agent/streaming/handlers/streaming_handler_factory.py +177 -0
  67. autobyteus/agent/streaming/handlers/streaming_response_handler.py +58 -0
  68. autobyteus/agent/streaming/parser/__init__.py +61 -0
  69. autobyteus/agent/streaming/parser/event_emitter.py +181 -0
  70. autobyteus/agent/streaming/parser/events.py +4 -0
  71. autobyteus/agent/streaming/parser/invocation_adapter.py +4 -0
  72. autobyteus/agent/streaming/parser/json_parsing_strategies/__init__.py +19 -0
  73. autobyteus/agent/streaming/parser/json_parsing_strategies/base.py +32 -0
  74. autobyteus/agent/streaming/parser/json_parsing_strategies/default.py +34 -0
  75. autobyteus/agent/streaming/parser/json_parsing_strategies/gemini.py +31 -0
  76. autobyteus/agent/streaming/parser/json_parsing_strategies/openai.py +64 -0
  77. autobyteus/agent/streaming/parser/json_parsing_strategies/registry.py +75 -0
  78. autobyteus/agent/streaming/parser/parser_context.py +227 -0
  79. autobyteus/agent/streaming/parser/parser_factory.py +132 -0
  80. autobyteus/agent/streaming/parser/sentinel_format.py +7 -0
  81. autobyteus/agent/streaming/parser/state_factory.py +62 -0
  82. autobyteus/agent/streaming/parser/states/__init__.py +1 -0
  83. autobyteus/agent/streaming/parser/states/base_state.py +60 -0
  84. autobyteus/agent/streaming/parser/states/custom_xml_tag_run_bash_parsing_state.py +38 -0
  85. autobyteus/agent/streaming/parser/states/custom_xml_tag_write_file_parsing_state.py +55 -0
  86. autobyteus/agent/streaming/parser/states/delimited_content_state.py +146 -0
  87. autobyteus/agent/streaming/parser/states/json_initialization_state.py +144 -0
  88. autobyteus/agent/streaming/parser/states/json_tool_parsing_state.py +137 -0
  89. autobyteus/agent/streaming/parser/states/sentinel_content_state.py +30 -0
  90. autobyteus/agent/streaming/parser/states/sentinel_initialization_state.py +117 -0
  91. autobyteus/agent/streaming/parser/states/text_state.py +78 -0
  92. autobyteus/agent/streaming/parser/states/xml_patch_file_tool_parsing_state.py +328 -0
  93. autobyteus/agent/streaming/parser/states/xml_run_bash_tool_parsing_state.py +129 -0
  94. autobyteus/agent/streaming/parser/states/xml_tag_initialization_state.py +151 -0
  95. autobyteus/agent/streaming/parser/states/xml_tool_parsing_state.py +63 -0
  96. autobyteus/agent/streaming/parser/states/xml_write_file_tool_parsing_state.py +343 -0
  97. autobyteus/agent/streaming/parser/strategies/__init__.py +17 -0
  98. autobyteus/agent/streaming/parser/strategies/base.py +24 -0
  99. autobyteus/agent/streaming/parser/strategies/json_tool_strategy.py +26 -0
  100. autobyteus/agent/streaming/parser/strategies/registry.py +28 -0
  101. autobyteus/agent/streaming/parser/strategies/sentinel_strategy.py +23 -0
  102. autobyteus/agent/streaming/parser/strategies/xml_tag_strategy.py +21 -0
  103. autobyteus/agent/streaming/parser/stream_scanner.py +167 -0
  104. autobyteus/agent/streaming/parser/streaming_parser.py +212 -0
  105. autobyteus/agent/streaming/parser/tool_call_parsing.py +4 -0
  106. autobyteus/agent/streaming/parser/tool_constants.py +7 -0
  107. autobyteus/agent/streaming/parser/tool_syntax_registry.py +4 -0
  108. autobyteus/agent/streaming/parser/xml_tool_parsing_state_registry.py +55 -0
  109. autobyteus/agent/streaming/parsing_streaming_response_handler.py +4 -0
  110. autobyteus/agent/streaming/pass_through_streaming_response_handler.py +4 -0
  111. autobyteus/agent/streaming/queue_streamer.py +3 -57
  112. autobyteus/agent/streaming/segments/__init__.py +5 -0
  113. autobyteus/agent/streaming/segments/segment_events.py +82 -0
  114. autobyteus/agent/streaming/stream_event_payloads.py +2 -223
  115. autobyteus/agent/streaming/stream_events.py +3 -140
  116. autobyteus/agent/streaming/streaming_handler_factory.py +4 -0
  117. autobyteus/agent/streaming/streaming_response_handler.py +4 -0
  118. autobyteus/agent/streaming/streams/__init__.py +5 -0
  119. autobyteus/agent/streaming/streams/agent_event_stream.py +197 -0
  120. autobyteus/agent/streaming/utils/__init__.py +5 -0
  121. autobyteus/agent/streaming/utils/queue_streamer.py +59 -0
  122. autobyteus/agent/system_prompt_processor/__init__.py +2 -0
  123. autobyteus/agent/system_prompt_processor/available_skills_processor.py +96 -0
  124. autobyteus/agent/system_prompt_processor/base_processor.py +1 -1
  125. autobyteus/agent/system_prompt_processor/processor_meta.py +15 -2
  126. autobyteus/agent/system_prompt_processor/tool_manifest_injector_processor.py +39 -58
  127. autobyteus/agent/token_budget.py +56 -0
  128. autobyteus/agent/tool_execution_result_processor/memory_ingest_tool_result_processor.py +29 -0
  129. autobyteus/agent/tool_invocation.py +16 -40
  130. autobyteus/agent/tool_invocation_preprocessor/__init__.py +9 -0
  131. autobyteus/agent/tool_invocation_preprocessor/base_preprocessor.py +45 -0
  132. autobyteus/agent/tool_invocation_preprocessor/processor_definition.py +15 -0
  133. autobyteus/agent/tool_invocation_preprocessor/processor_meta.py +33 -0
  134. autobyteus/agent/tool_invocation_preprocessor/processor_registry.py +60 -0
  135. autobyteus/agent/utils/wait_for_idle.py +12 -14
  136. autobyteus/agent/workspace/base_workspace.py +6 -27
  137. autobyteus/agent_team/agent_team.py +3 -3
  138. autobyteus/agent_team/agent_team_builder.py +1 -41
  139. autobyteus/agent_team/bootstrap_steps/__init__.py +0 -4
  140. autobyteus/agent_team/bootstrap_steps/agent_configuration_preparation_step.py +8 -18
  141. autobyteus/agent_team/bootstrap_steps/agent_team_bootstrapper.py +4 -16
  142. autobyteus/agent_team/bootstrap_steps/base_agent_team_bootstrap_step.py +1 -2
  143. autobyteus/agent_team/bootstrap_steps/coordinator_initialization_step.py +1 -2
  144. autobyteus/agent_team/bootstrap_steps/task_notifier_initialization_step.py +1 -2
  145. autobyteus/agent_team/bootstrap_steps/team_context_initialization_step.py +4 -4
  146. autobyteus/agent_team/context/agent_team_config.py +6 -3
  147. autobyteus/agent_team/context/agent_team_context.py +25 -3
  148. autobyteus/agent_team/context/agent_team_runtime_state.py +9 -6
  149. autobyteus/agent_team/events/__init__.py +11 -0
  150. autobyteus/agent_team/events/agent_team_event_dispatcher.py +22 -9
  151. autobyteus/agent_team/events/agent_team_events.py +16 -0
  152. autobyteus/agent_team/events/event_store.py +57 -0
  153. autobyteus/agent_team/factory/agent_team_factory.py +8 -0
  154. autobyteus/agent_team/handlers/inter_agent_message_request_event_handler.py +18 -2
  155. autobyteus/agent_team/handlers/lifecycle_agent_team_event_handler.py +21 -5
  156. autobyteus/agent_team/handlers/process_user_message_event_handler.py +17 -8
  157. autobyteus/agent_team/handlers/tool_approval_team_event_handler.py +19 -4
  158. autobyteus/agent_team/runtime/agent_team_runtime.py +41 -10
  159. autobyteus/agent_team/runtime/agent_team_worker.py +69 -5
  160. autobyteus/agent_team/status/__init__.py +14 -0
  161. autobyteus/agent_team/status/agent_team_status.py +18 -0
  162. autobyteus/agent_team/status/agent_team_status_manager.py +33 -0
  163. autobyteus/agent_team/status/status_deriver.py +62 -0
  164. autobyteus/agent_team/status/status_update_utils.py +42 -0
  165. autobyteus/agent_team/streaming/__init__.py +2 -2
  166. autobyteus/agent_team/streaming/agent_team_event_notifier.py +6 -6
  167. autobyteus/agent_team/streaming/agent_team_stream_event_payloads.py +4 -4
  168. autobyteus/agent_team/streaming/agent_team_stream_events.py +3 -3
  169. autobyteus/agent_team/system_prompt_processor/__init__.py +6 -0
  170. autobyteus/agent_team/system_prompt_processor/team_manifest_injector_processor.py +76 -0
  171. autobyteus/agent_team/task_notification/task_notification_mode.py +19 -0
  172. autobyteus/agent_team/utils/wait_for_idle.py +4 -4
  173. autobyteus/cli/agent_cli.py +18 -10
  174. autobyteus/cli/agent_team_tui/app.py +14 -11
  175. autobyteus/cli/agent_team_tui/state.py +13 -15
  176. autobyteus/cli/agent_team_tui/widgets/agent_list_sidebar.py +15 -15
  177. autobyteus/cli/agent_team_tui/widgets/focus_pane.py +143 -36
  178. autobyteus/cli/agent_team_tui/widgets/renderables.py +1 -1
  179. autobyteus/cli/agent_team_tui/widgets/shared.py +25 -25
  180. autobyteus/cli/cli_display.py +193 -44
  181. autobyteus/cli/workflow_tui/app.py +9 -10
  182. autobyteus/cli/workflow_tui/state.py +14 -16
  183. autobyteus/cli/workflow_tui/widgets/agent_list_sidebar.py +15 -15
  184. autobyteus/cli/workflow_tui/widgets/focus_pane.py +137 -35
  185. autobyteus/cli/workflow_tui/widgets/renderables.py +1 -1
  186. autobyteus/cli/workflow_tui/widgets/shared.py +25 -25
  187. autobyteus/clients/autobyteus_client.py +94 -1
  188. autobyteus/events/event_types.py +11 -18
  189. autobyteus/llm/api/autobyteus_llm.py +33 -29
  190. autobyteus/llm/api/claude_llm.py +142 -36
  191. autobyteus/llm/api/gemini_llm.py +163 -59
  192. autobyteus/llm/api/grok_llm.py +1 -1
  193. autobyteus/llm/api/minimax_llm.py +26 -0
  194. autobyteus/llm/api/mistral_llm.py +113 -87
  195. autobyteus/llm/api/ollama_llm.py +9 -42
  196. autobyteus/llm/api/openai_compatible_llm.py +127 -91
  197. autobyteus/llm/api/openai_llm.py +3 -3
  198. autobyteus/llm/api/openai_responses_llm.py +324 -0
  199. autobyteus/llm/api/zhipu_llm.py +21 -2
  200. autobyteus/llm/autobyteus_provider.py +70 -60
  201. autobyteus/llm/base_llm.py +85 -81
  202. autobyteus/llm/converters/__init__.py +14 -0
  203. autobyteus/llm/converters/anthropic_tool_call_converter.py +37 -0
  204. autobyteus/llm/converters/gemini_tool_call_converter.py +57 -0
  205. autobyteus/llm/converters/mistral_tool_call_converter.py +37 -0
  206. autobyteus/llm/converters/openai_tool_call_converter.py +38 -0
  207. autobyteus/llm/extensions/base_extension.py +6 -12
  208. autobyteus/llm/extensions/token_usage_tracking_extension.py +45 -18
  209. autobyteus/llm/llm_factory.py +282 -204
  210. autobyteus/llm/lmstudio_provider.py +60 -49
  211. autobyteus/llm/models.py +35 -2
  212. autobyteus/llm/ollama_provider.py +60 -49
  213. autobyteus/llm/ollama_provider_resolver.py +0 -1
  214. autobyteus/llm/prompt_renderers/__init__.py +19 -0
  215. autobyteus/llm/prompt_renderers/anthropic_prompt_renderer.py +104 -0
  216. autobyteus/llm/prompt_renderers/autobyteus_prompt_renderer.py +19 -0
  217. autobyteus/llm/prompt_renderers/base_prompt_renderer.py +10 -0
  218. autobyteus/llm/prompt_renderers/gemini_prompt_renderer.py +63 -0
  219. autobyteus/llm/prompt_renderers/mistral_prompt_renderer.py +87 -0
  220. autobyteus/llm/prompt_renderers/ollama_prompt_renderer.py +51 -0
  221. autobyteus/llm/prompt_renderers/openai_chat_renderer.py +97 -0
  222. autobyteus/llm/prompt_renderers/openai_responses_renderer.py +101 -0
  223. autobyteus/llm/providers.py +1 -3
  224. autobyteus/llm/token_counter/claude_token_counter.py +56 -25
  225. autobyteus/llm/token_counter/mistral_token_counter.py +12 -8
  226. autobyteus/llm/token_counter/openai_token_counter.py +24 -5
  227. autobyteus/llm/token_counter/token_counter_factory.py +12 -5
  228. autobyteus/llm/utils/llm_config.py +6 -12
  229. autobyteus/llm/utils/media_payload_formatter.py +27 -20
  230. autobyteus/llm/utils/messages.py +55 -3
  231. autobyteus/llm/utils/response_types.py +3 -0
  232. autobyteus/llm/utils/tool_call_delta.py +31 -0
  233. autobyteus/memory/__init__.py +35 -0
  234. autobyteus/memory/compaction/__init__.py +9 -0
  235. autobyteus/memory/compaction/compaction_result.py +8 -0
  236. autobyteus/memory/compaction/compactor.py +89 -0
  237. autobyteus/memory/compaction/summarizer.py +11 -0
  238. autobyteus/memory/compaction_snapshot_builder.py +84 -0
  239. autobyteus/memory/memory_manager.py +205 -0
  240. autobyteus/memory/models/__init__.py +14 -0
  241. autobyteus/memory/models/episodic_item.py +41 -0
  242. autobyteus/memory/models/memory_types.py +7 -0
  243. autobyteus/memory/models/raw_trace_item.py +79 -0
  244. autobyteus/memory/models/semantic_item.py +41 -0
  245. autobyteus/memory/models/tool_interaction.py +20 -0
  246. autobyteus/memory/path_resolver.py +27 -0
  247. autobyteus/memory/policies/__init__.py +5 -0
  248. autobyteus/memory/policies/compaction_policy.py +16 -0
  249. autobyteus/memory/restore/__init__.py +1 -0
  250. autobyteus/memory/restore/working_context_snapshot_bootstrapper.py +61 -0
  251. autobyteus/memory/retrieval/__init__.py +7 -0
  252. autobyteus/memory/retrieval/memory_bundle.py +11 -0
  253. autobyteus/memory/retrieval/retriever.py +13 -0
  254. autobyteus/memory/store/__init__.py +9 -0
  255. autobyteus/memory/store/base_store.py +14 -0
  256. autobyteus/memory/store/file_store.py +98 -0
  257. autobyteus/memory/store/working_context_snapshot_store.py +28 -0
  258. autobyteus/memory/tool_interaction_builder.py +46 -0
  259. autobyteus/memory/turn_tracker.py +9 -0
  260. autobyteus/memory/working_context_snapshot.py +69 -0
  261. autobyteus/memory/working_context_snapshot_serializer.py +135 -0
  262. autobyteus/multimedia/audio/api/autobyteus_audio_client.py +19 -5
  263. autobyteus/multimedia/audio/api/gemini_audio_client.py +109 -16
  264. autobyteus/multimedia/audio/audio_client_factory.py +47 -9
  265. autobyteus/multimedia/audio/audio_model.py +2 -1
  266. autobyteus/multimedia/image/api/autobyteus_image_client.py +19 -5
  267. autobyteus/multimedia/image/api/gemini_image_client.py +39 -17
  268. autobyteus/multimedia/image/api/openai_image_client.py +125 -43
  269. autobyteus/multimedia/image/autobyteus_image_provider.py +2 -1
  270. autobyteus/multimedia/image/image_client_factory.py +47 -15
  271. autobyteus/multimedia/image/image_model.py +5 -2
  272. autobyteus/multimedia/providers.py +3 -2
  273. autobyteus/skills/loader.py +71 -0
  274. autobyteus/skills/model.py +11 -0
  275. autobyteus/skills/registry.py +70 -0
  276. autobyteus/task_management/tools/todo_tools/add_todo.py +2 -2
  277. autobyteus/task_management/tools/todo_tools/create_todo_list.py +2 -2
  278. autobyteus/task_management/tools/todo_tools/update_todo_status.py +2 -2
  279. autobyteus/tools/__init__.py +34 -47
  280. autobyteus/tools/base_tool.py +7 -0
  281. autobyteus/tools/file/__init__.py +2 -6
  282. autobyteus/tools/file/patch_file.py +149 -0
  283. autobyteus/tools/file/read_file.py +36 -5
  284. autobyteus/tools/file/write_file.py +4 -1
  285. autobyteus/tools/functional_tool.py +43 -6
  286. autobyteus/tools/mcp/__init__.py +2 -0
  287. autobyteus/tools/mcp/config_service.py +5 -1
  288. autobyteus/tools/mcp/server/__init__.py +2 -0
  289. autobyteus/tools/mcp/server/http_managed_mcp_server.py +1 -1
  290. autobyteus/tools/mcp/server/websocket_managed_mcp_server.py +141 -0
  291. autobyteus/tools/mcp/server_instance_manager.py +8 -1
  292. autobyteus/tools/mcp/types.py +61 -0
  293. autobyteus/tools/multimedia/audio_tools.py +70 -17
  294. autobyteus/tools/multimedia/download_media_tool.py +18 -4
  295. autobyteus/tools/multimedia/image_tools.py +246 -62
  296. autobyteus/tools/operation_executor/journal_manager.py +107 -0
  297. autobyteus/tools/operation_executor/operation_event_buffer.py +57 -0
  298. autobyteus/tools/operation_executor/operation_event_producer.py +29 -0
  299. autobyteus/tools/operation_executor/operation_executor.py +58 -0
  300. autobyteus/tools/registry/tool_definition.py +43 -2
  301. autobyteus/tools/skill/load_skill.py +50 -0
  302. autobyteus/tools/terminal/__init__.py +45 -0
  303. autobyteus/tools/terminal/ansi_utils.py +32 -0
  304. autobyteus/tools/terminal/background_process_manager.py +233 -0
  305. autobyteus/tools/terminal/output_buffer.py +105 -0
  306. autobyteus/tools/terminal/prompt_detector.py +63 -0
  307. autobyteus/tools/terminal/pty_session.py +241 -0
  308. autobyteus/tools/terminal/session_factory.py +20 -0
  309. autobyteus/tools/terminal/terminal_session_manager.py +226 -0
  310. autobyteus/tools/terminal/tools/__init__.py +13 -0
  311. autobyteus/tools/terminal/tools/get_process_output.py +81 -0
  312. autobyteus/tools/terminal/tools/run_bash.py +109 -0
  313. autobyteus/tools/terminal/tools/start_background_process.py +104 -0
  314. autobyteus/tools/terminal/tools/stop_background_process.py +67 -0
  315. autobyteus/tools/terminal/types.py +54 -0
  316. autobyteus/tools/terminal/wsl_tmux_session.py +221 -0
  317. autobyteus/tools/terminal/wsl_utils.py +156 -0
  318. autobyteus/tools/transaction_management/backup_handler.py +48 -0
  319. autobyteus/tools/transaction_management/operation_lifecycle_manager.py +62 -0
  320. autobyteus/tools/usage/__init__.py +1 -2
  321. autobyteus/tools/usage/formatters/__init__.py +17 -1
  322. autobyteus/tools/usage/formatters/base_formatter.py +8 -0
  323. autobyteus/tools/usage/formatters/default_xml_schema_formatter.py +2 -2
  324. autobyteus/tools/usage/formatters/mistral_json_schema_formatter.py +18 -0
  325. autobyteus/tools/usage/formatters/patch_file_xml_example_formatter.py +64 -0
  326. autobyteus/tools/usage/formatters/patch_file_xml_schema_formatter.py +31 -0
  327. autobyteus/tools/usage/formatters/run_bash_xml_example_formatter.py +32 -0
  328. autobyteus/tools/usage/formatters/run_bash_xml_schema_formatter.py +36 -0
  329. autobyteus/tools/usage/formatters/write_file_xml_example_formatter.py +53 -0
  330. autobyteus/tools/usage/formatters/write_file_xml_schema_formatter.py +31 -0
  331. autobyteus/tools/usage/providers/tool_manifest_provider.py +10 -10
  332. autobyteus/tools/usage/registries/__init__.py +1 -3
  333. autobyteus/tools/usage/registries/tool_formatting_registry.py +115 -8
  334. autobyteus/tools/usage/tool_schema_provider.py +51 -0
  335. autobyteus/tools/web/__init__.py +4 -0
  336. autobyteus/tools/web/read_url_tool.py +80 -0
  337. autobyteus/utils/diff_utils.py +271 -0
  338. autobyteus/utils/download_utils.py +109 -0
  339. autobyteus/utils/file_utils.py +57 -2
  340. autobyteus/utils/gemini_helper.py +64 -0
  341. autobyteus/utils/gemini_model_mapping.py +71 -0
  342. autobyteus/utils/llm_output_formatter.py +75 -0
  343. autobyteus/utils/tool_call_format.py +36 -0
  344. autobyteus/workflow/agentic_workflow.py +3 -3
  345. autobyteus/workflow/bootstrap_steps/agent_tool_injection_step.py +2 -2
  346. autobyteus/workflow/bootstrap_steps/base_workflow_bootstrap_step.py +2 -2
  347. autobyteus/workflow/bootstrap_steps/coordinator_initialization_step.py +2 -2
  348. autobyteus/workflow/bootstrap_steps/coordinator_prompt_preparation_step.py +3 -9
  349. autobyteus/workflow/bootstrap_steps/workflow_bootstrapper.py +6 -6
  350. autobyteus/workflow/bootstrap_steps/workflow_runtime_queue_initialization_step.py +2 -2
  351. autobyteus/workflow/context/workflow_context.py +3 -3
  352. autobyteus/workflow/context/workflow_runtime_state.py +5 -5
  353. autobyteus/workflow/events/workflow_event_dispatcher.py +5 -5
  354. autobyteus/workflow/handlers/lifecycle_workflow_event_handler.py +3 -3
  355. autobyteus/workflow/handlers/process_user_message_event_handler.py +5 -5
  356. autobyteus/workflow/handlers/tool_approval_workflow_event_handler.py +2 -2
  357. autobyteus/workflow/runtime/workflow_runtime.py +8 -8
  358. autobyteus/workflow/runtime/workflow_worker.py +3 -3
  359. autobyteus/workflow/status/__init__.py +11 -0
  360. autobyteus/workflow/status/workflow_status.py +19 -0
  361. autobyteus/workflow/status/workflow_status_manager.py +48 -0
  362. autobyteus/workflow/streaming/__init__.py +2 -2
  363. autobyteus/workflow/streaming/workflow_event_notifier.py +7 -7
  364. autobyteus/workflow/streaming/workflow_stream_event_payloads.py +4 -4
  365. autobyteus/workflow/streaming/workflow_stream_events.py +3 -3
  366. autobyteus/workflow/utils/wait_for_idle.py +4 -4
  367. autobyteus-1.3.0.dist-info/METADATA +293 -0
  368. autobyteus-1.3.0.dist-info/RECORD +606 -0
  369. {autobyteus-1.2.1.dist-info → autobyteus-1.3.0.dist-info}/WHEEL +1 -1
  370. {autobyteus-1.2.1.dist-info → autobyteus-1.3.0.dist-info}/top_level.txt +0 -1
  371. autobyteus/agent/bootstrap_steps/agent_runtime_queue_initialization_step.py +0 -57
  372. autobyteus/agent/hooks/__init__.py +0 -16
  373. autobyteus/agent/hooks/base_phase_hook.py +0 -78
  374. autobyteus/agent/hooks/hook_definition.py +0 -36
  375. autobyteus/agent/hooks/hook_meta.py +0 -37
  376. autobyteus/agent/hooks/hook_registry.py +0 -106
  377. autobyteus/agent/llm_response_processor/provider_aware_tool_usage_processor.py +0 -103
  378. autobyteus/agent/phases/__init__.py +0 -18
  379. autobyteus/agent/phases/discover.py +0 -53
  380. autobyteus/agent/phases/manager.py +0 -265
  381. autobyteus/agent/phases/transition_decorator.py +0 -40
  382. autobyteus/agent/phases/transition_info.py +0 -33
  383. autobyteus/agent/remote_agent.py +0 -244
  384. autobyteus/agent/workspace/workspace_definition.py +0 -36
  385. autobyteus/agent/workspace/workspace_meta.py +0 -37
  386. autobyteus/agent/workspace/workspace_registry.py +0 -72
  387. autobyteus/agent_team/bootstrap_steps/agent_team_runtime_queue_initialization_step.py +0 -25
  388. autobyteus/agent_team/bootstrap_steps/coordinator_prompt_preparation_step.py +0 -85
  389. autobyteus/agent_team/phases/__init__.py +0 -11
  390. autobyteus/agent_team/phases/agent_team_operational_phase.py +0 -19
  391. autobyteus/agent_team/phases/agent_team_phase_manager.py +0 -48
  392. autobyteus/llm/api/bedrock_llm.py +0 -92
  393. autobyteus/llm/api/groq_llm.py +0 -94
  394. autobyteus/llm/api/nvidia_llm.py +0 -108
  395. autobyteus/llm/utils/token_pricing_config.py +0 -87
  396. autobyteus/rpc/__init__.py +0 -73
  397. autobyteus/rpc/client/__init__.py +0 -17
  398. autobyteus/rpc/client/abstract_client_connection.py +0 -124
  399. autobyteus/rpc/client/client_connection_manager.py +0 -153
  400. autobyteus/rpc/client/sse_client_connection.py +0 -306
  401. autobyteus/rpc/client/stdio_client_connection.py +0 -280
  402. autobyteus/rpc/config/__init__.py +0 -13
  403. autobyteus/rpc/config/agent_server_config.py +0 -153
  404. autobyteus/rpc/config/agent_server_registry.py +0 -152
  405. autobyteus/rpc/hosting.py +0 -244
  406. autobyteus/rpc/protocol.py +0 -244
  407. autobyteus/rpc/server/__init__.py +0 -20
  408. autobyteus/rpc/server/agent_server_endpoint.py +0 -181
  409. autobyteus/rpc/server/base_method_handler.py +0 -40
  410. autobyteus/rpc/server/method_handlers.py +0 -259
  411. autobyteus/rpc/server/sse_server_handler.py +0 -182
  412. autobyteus/rpc/server/stdio_server_handler.py +0 -151
  413. autobyteus/rpc/server_main.py +0 -198
  414. autobyteus/rpc/transport_type.py +0 -13
  415. autobyteus/tools/bash/__init__.py +0 -2
  416. autobyteus/tools/bash/bash_executor.py +0 -100
  417. autobyteus/tools/browser/__init__.py +0 -2
  418. autobyteus/tools/browser/session_aware/browser_session_aware_navigate_to.py +0 -75
  419. autobyteus/tools/browser/session_aware/browser_session_aware_tool.py +0 -30
  420. autobyteus/tools/browser/session_aware/browser_session_aware_web_element_trigger.py +0 -154
  421. autobyteus/tools/browser/session_aware/browser_session_aware_webpage_reader.py +0 -89
  422. autobyteus/tools/browser/session_aware/browser_session_aware_webpage_screenshot_taker.py +0 -107
  423. autobyteus/tools/browser/session_aware/factory/browser_session_aware_web_element_trigger_factory.py +0 -14
  424. autobyteus/tools/browser/session_aware/factory/browser_session_aware_webpage_reader_factory.py +0 -26
  425. autobyteus/tools/browser/session_aware/factory/browser_session_aware_webpage_screenshot_taker_factory.py +0 -14
  426. autobyteus/tools/browser/session_aware/shared_browser_session.py +0 -11
  427. autobyteus/tools/browser/session_aware/shared_browser_session_manager.py +0 -25
  428. autobyteus/tools/browser/session_aware/web_element_action.py +0 -20
  429. autobyteus/tools/browser/standalone/__init__.py +0 -6
  430. autobyteus/tools/browser/standalone/factory/__init__.py +0 -0
  431. autobyteus/tools/browser/standalone/factory/webpage_reader_factory.py +0 -25
  432. autobyteus/tools/browser/standalone/factory/webpage_screenshot_taker_factory.py +0 -14
  433. autobyteus/tools/browser/standalone/navigate_to.py +0 -84
  434. autobyteus/tools/browser/standalone/web_page_pdf_generator.py +0 -101
  435. autobyteus/tools/browser/standalone/webpage_image_downloader.py +0 -169
  436. autobyteus/tools/browser/standalone/webpage_reader.py +0 -105
  437. autobyteus/tools/browser/standalone/webpage_screenshot_taker.py +0 -105
  438. autobyteus/tools/file/edit_file.py +0 -200
  439. autobyteus/tools/file/list_directory.py +0 -168
  440. autobyteus/tools/file/search_files.py +0 -188
  441. autobyteus/tools/timer.py +0 -175
  442. autobyteus/tools/usage/parsers/__init__.py +0 -22
  443. autobyteus/tools/usage/parsers/_json_extractor.py +0 -99
  444. autobyteus/tools/usage/parsers/_string_decoders.py +0 -18
  445. autobyteus/tools/usage/parsers/anthropic_xml_tool_usage_parser.py +0 -10
  446. autobyteus/tools/usage/parsers/base_parser.py +0 -41
  447. autobyteus/tools/usage/parsers/default_json_tool_usage_parser.py +0 -83
  448. autobyteus/tools/usage/parsers/default_xml_tool_usage_parser.py +0 -316
  449. autobyteus/tools/usage/parsers/exceptions.py +0 -13
  450. autobyteus/tools/usage/parsers/gemini_json_tool_usage_parser.py +0 -77
  451. autobyteus/tools/usage/parsers/openai_json_tool_usage_parser.py +0 -149
  452. autobyteus/tools/usage/parsers/provider_aware_tool_usage_parser.py +0 -59
  453. autobyteus/tools/usage/registries/tool_usage_parser_registry.py +0 -62
  454. autobyteus/workflow/phases/__init__.py +0 -11
  455. autobyteus/workflow/phases/workflow_operational_phase.py +0 -19
  456. autobyteus/workflow/phases/workflow_phase_manager.py +0 -48
  457. autobyteus-1.2.1.dist-info/METADATA +0 -205
  458. autobyteus-1.2.1.dist-info/RECORD +0 -511
  459. examples/__init__.py +0 -1
  460. examples/agent_team/__init__.py +0 -1
  461. examples/discover_phase_transitions.py +0 -104
  462. examples/run_agentic_software_engineer.py +0 -239
  463. examples/run_browser_agent.py +0 -262
  464. examples/run_google_slides_agent.py +0 -287
  465. examples/run_mcp_browser_client.py +0 -174
  466. examples/run_mcp_google_slides_client.py +0 -270
  467. examples/run_mcp_list_tools.py +0 -189
  468. examples/run_poem_writer.py +0 -284
  469. examples/run_sqlite_agent.py +0 -295
  470. /autobyteus/{tools/browser/session_aware → skills}/__init__.py +0 -0
  471. /autobyteus/tools/{browser/session_aware/factory → skill}/__init__.py +0 -0
  472. {autobyteus-1.2.1.dist-info → autobyteus-1.3.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,26 @@
1
+ import logging
2
+ from typing import Optional
3
+ from autobyteus.llm.models import LLMModel
4
+ from autobyteus.llm.utils.llm_config import LLMConfig
5
+ from autobyteus.llm.api.openai_compatible_llm import OpenAICompatibleLLM
6
+
7
+ logger = logging.getLogger(__name__)
8
+
9
+ class MinimaxLLM(OpenAICompatibleLLM):
10
+ def __init__(self, model: LLMModel = None, llm_config: LLMConfig = None):
11
+ # Provide defaults if not specified
12
+ if model is None:
13
+ model = LLMModel['minimax-m2.1']
14
+ if llm_config is None:
15
+ llm_config = LLMConfig()
16
+
17
+ super().__init__(
18
+ model=model,
19
+ llm_config=llm_config,
20
+ api_key_env_var="MINIMAX_API_KEY",
21
+ base_url="https://api.minimax.io/v1"
22
+ )
23
+ logger.info(f"MinimaxLLM initialized with model: {self.model}")
24
+
25
+ async def cleanup(self):
26
+ await super().cleanup()
@@ -1,67 +1,18 @@
1
- from typing import Dict, Optional, List, Any, AsyncGenerator, Union
1
+ from typing import List, Any, AsyncGenerator
2
2
  import os
3
3
  import logging
4
4
  import httpx
5
- import asyncio
6
5
  from autobyteus.llm.models import LLMModel
7
6
  from autobyteus.llm.base_llm import BaseLLM
8
7
  from mistralai import Mistral
9
- from autobyteus.llm.utils.messages import Message, MessageRole
8
+ from autobyteus.llm.utils.messages import Message
10
9
  from autobyteus.llm.utils.llm_config import LLMConfig
11
10
  from autobyteus.llm.utils.token_usage import TokenUsage
12
11
  from autobyteus.llm.utils.response_types import CompleteResponse, ChunkResponse
13
- from autobyteus.llm.user_message import LLMUserMessage
14
- from autobyteus.llm.utils.media_payload_formatter import image_source_to_base64, get_mime_type, is_valid_image_path
12
+ from autobyteus.llm.prompt_renderers.mistral_prompt_renderer import MistralPromptRenderer
15
13
 
16
14
  logger = logging.getLogger(__name__)
17
15
 
18
- async def _format_mistral_messages(messages: List[Message]) -> List[Dict[str, Any]]:
19
- """Formats a list of internal Message objects into a list of dictionaries for the Mistral API."""
20
- mistral_messages = []
21
- for msg in messages:
22
- # Skip empty messages from non-system roles as Mistral API may reject them
23
- if not msg.content and not msg.image_urls and msg.role != MessageRole.SYSTEM:
24
- continue
25
-
26
- content: Union[str, List[Dict[str, Any]]]
27
-
28
- if msg.image_urls:
29
- content_parts: List[Dict[str, Any]] = []
30
- if msg.content:
31
- content_parts.append({"type": "text", "text": msg.content})
32
-
33
- image_tasks = [image_source_to_base64(url) for url in msg.image_urls]
34
- try:
35
- base64_images = await asyncio.gather(*image_tasks)
36
- for i, b64_image in enumerate(base64_images):
37
- original_url = msg.image_urls[i]
38
- mime_type = get_mime_type(original_url) if is_valid_image_path(original_url) else "image/jpeg"
39
- data_uri = f"data:{mime_type};base64,{b64_image}"
40
-
41
- # Mistral's format for image parts
42
- content_parts.append({
43
- "type": "image_url",
44
- "image_url": {
45
- "url": data_uri
46
- }
47
- })
48
- except Exception as e:
49
- logger.error(f"Error processing images for Mistral: {e}")
50
-
51
- if msg.audio_urls:
52
- logger.warning("MistralLLM does not yet support audio; skipping.")
53
- if msg.video_urls:
54
- logger.warning("MistralLLM does not yet support video; skipping.")
55
-
56
- content = content_parts
57
- else:
58
- content = msg.content or ""
59
-
60
- mistral_messages.append({"role": msg.role.value, "content": content})
61
-
62
- return mistral_messages
63
-
64
-
65
16
  class MistralLLM(BaseLLM):
66
17
  def __init__(self, model: LLMModel = None, llm_config: LLMConfig = None):
67
18
  if model is None:
@@ -70,8 +21,12 @@ class MistralLLM(BaseLLM):
70
21
  llm_config = LLMConfig()
71
22
 
72
23
  super().__init__(model=model, llm_config=llm_config)
73
- self.http_client = httpx.AsyncClient()
24
+ # Let the SDK manage its own HTTP client. Passing a raw httpx client
25
+ # does not satisfy the SDK's HttpClient protocol and raises an
26
+ # AssertionError during construction (observed in tests). Rely on the
27
+ # internal client instead.
74
28
  self.client: Mistral = self._initialize()
29
+ self._renderer = MistralPromptRenderer()
75
30
  logger.info(f"MistralLLM initialized with model: {self.model}")
76
31
 
77
32
  def _initialize(self) -> Mistral:
@@ -80,7 +35,7 @@ class MistralLLM(BaseLLM):
80
35
  logger.error("MISTRAL_API_KEY environment variable is not set")
81
36
  raise ValueError("MISTRAL_API_KEY environment variable is not set.")
82
37
  try:
83
- return Mistral(api_key=mistral_api_key, client=self.http_client)
38
+ return Mistral(api_key=mistral_api_key)
84
39
  except Exception as e:
85
40
  logger.error(f"Failed to initialize Mistral client: {str(e)}")
86
41
  raise ValueError(f"Failed to initialize Mistral client: {str(e)}")
@@ -93,13 +48,11 @@ class MistralLLM(BaseLLM):
93
48
  total_tokens=usage_data.total_tokens
94
49
  )
95
50
 
96
- async def _send_user_message_to_llm(
97
- self, user_message: LLMUserMessage, **kwargs
51
+ async def _send_messages_to_llm(
52
+ self, messages: List[Message], **kwargs
98
53
  ) -> CompleteResponse:
99
- self.add_user_message(user_message)
100
-
101
54
  try:
102
- mistral_messages = await _format_mistral_messages(self.messages)
55
+ mistral_messages = await self._renderer.render(messages)
103
56
 
104
57
  chat_response = await self.client.chat.complete_async(
105
58
  model=self.model.value,
@@ -110,7 +63,6 @@ class MistralLLM(BaseLLM):
110
63
  )
111
64
 
112
65
  assistant_message = chat_response.choices[0].message.content
113
- self.add_assistant_message(assistant_message)
114
66
 
115
67
  token_usage = self._create_token_usage(chat_response.usage)
116
68
  logger.debug(f"Token usage recorded: {token_usage}")
@@ -123,49 +75,123 @@ class MistralLLM(BaseLLM):
123
75
  logger.error(f"Error in Mistral API call: {str(e)}")
124
76
  raise ValueError(f"Error in Mistral API call: {str(e)}")
125
77
 
126
- async def _stream_user_message_to_llm(
127
- self, user_message: LLMUserMessage, **kwargs
78
+ async def _stream_messages_to_llm(
79
+ self, messages: List[Message], **kwargs
128
80
  ) -> AsyncGenerator[ChunkResponse, None]:
129
- self.add_user_message(user_message)
130
-
131
81
  accumulated_message = ""
132
82
  final_usage = None
133
83
 
134
84
  try:
135
- mistral_messages = await _format_mistral_messages(self.messages)
136
-
137
- stream = self.client.chat.stream_async(
138
- model=self.model.value,
139
- messages=mistral_messages,
140
- temperature=self.config.temperature,
141
- max_tokens=self.config.max_tokens,
142
- top_p=self.config.top_p,
143
- )
144
-
145
- async for chunk in stream:
146
- if chunk.choices and chunk.choices[0].delta.content is not None:
147
- token = chunk.choices[0].delta.content
148
- accumulated_message += token
85
+ mistral_messages = await self._renderer.render(messages)
86
+
87
+ # Raw HTTP streaming to bypass SDK validation issues with tool calls
88
+ api_key = os.environ.get("MISTRAL_API_KEY")
89
+ if not api_key:
90
+ raise ValueError("MISTRAL_API_KEY not set")
91
+
92
+ headers = {
93
+ "Authorization": f"Bearer {api_key}",
94
+ "Content-Type": "application/json",
95
+ "Accept": "text/event-stream"
96
+ }
97
+
98
+ payload = {
99
+ "model": self.model.value,
100
+ "messages": mistral_messages,
101
+ "temperature": self.config.temperature,
102
+ "max_tokens": self.config.max_tokens,
103
+ "top_p": self.config.top_p,
104
+ "stream": True
105
+ }
106
+ # Filter None values
107
+ payload = {k: v for k, v in payload.items() if v is not None}
108
+
109
+ if kwargs.get("tools"):
110
+ payload["tools"] = kwargs.get("tools")
111
+ payload["tool_choice"] = "auto"
112
+
113
+ # Use internal httpx client logic or create new one context
114
+ async with httpx.AsyncClient() as client:
115
+ req = client.build_request("POST", "https://api.mistral.ai/v1/chat/completions", headers=headers, json=payload, timeout=60.0)
116
+ # Do not set stream=True for python client, let it buffer content automatically.
117
+ # The API will still stream SSE but client reads until close.
118
+ response = await client.send(req)
119
+
120
+ try:
121
+ if response.status_code != 200:
122
+ # response.read() is not needed if stream=False, it's already read
123
+ error_text = response.text
124
+ raise ValueError(f"Mistral API error: {response.status_code} - {error_text}")
125
+
126
+ buffer = ""
127
+ # Content is already in response.text
128
+ buffer = response.text
149
129
 
150
- yield ChunkResponse(content=token, is_complete=False)
151
-
152
- if hasattr(chunk, 'usage') and chunk.usage:
153
- final_usage = self._create_token_usage(chunk.usage)
154
-
155
- # Yield the final chunk with usage data
130
+ # Split buffer into lines and process like stream
131
+ lines = buffer.split('\n')
132
+ for line in lines:
133
+ line = line.strip()
134
+ if not line or line == "":
135
+ continue
136
+
137
+ if line.startswith("data: "):
138
+ data_str = line[6:]
139
+ if data_str.strip() == "[DONE]":
140
+ break
141
+
142
+ try:
143
+ import json
144
+ chunk_data = json.loads(data_str)
145
+
146
+ if "choices" in chunk_data and chunk_data["choices"]:
147
+ choice = chunk_data["choices"][0]
148
+ delta = choice.get("delta", {})
149
+
150
+ if "tool_calls" in delta and delta["tool_calls"]:
151
+ from autobyteus.llm.converters.mistral_tool_call_converter import convert_mistral_tool_calls
152
+ tool_calls = convert_mistral_tool_calls(delta["tool_calls"])
153
+ if tool_calls:
154
+ yield ChunkResponse(
155
+ content="",
156
+ tool_calls=tool_calls,
157
+ is_complete=False
158
+ )
159
+
160
+ content = delta.get("content")
161
+ if content:
162
+ accumulated_message += content
163
+ yield ChunkResponse(content=content, is_complete=False)
164
+
165
+ if chunk_data.get("usage"):
166
+ final_usage_data = chunk_data.get("usage")
167
+ from collections import namedtuple
168
+ UsageObj = namedtuple('UsageObj', ['prompt_tokens', 'completion_tokens', 'total_tokens'])
169
+ usage_obj = UsageObj(
170
+ prompt_tokens=final_usage_data.get('prompt_tokens', 0),
171
+ completion_tokens=final_usage_data.get('completion_tokens', 0),
172
+ total_tokens=final_usage_data.get('total_tokens', 0)
173
+ )
174
+ final_usage = self._create_token_usage(usage_obj)
175
+
176
+ except json.JSONDecodeError:
177
+ logger.warning(f"Failed to decode Mistral stream line: {line}")
178
+ continue
179
+ finally:
180
+ await response.aclose()
181
+
182
+ # Yield the final chunk
156
183
  yield ChunkResponse(
157
184
  content="",
158
185
  is_complete=True,
159
186
  usage=final_usage
160
187
  )
161
188
 
162
- self.add_assistant_message(accumulated_message)
163
189
  except Exception as e:
164
190
  logger.error(f"Error in Mistral API streaming call: {str(e)}")
191
+ import traceback
192
+ traceback.print_exc()
165
193
  raise ValueError(f"Error in Mistral API streaming call: {str(e)}")
166
194
 
167
195
  async def cleanup(self):
168
196
  logger.debug("Cleaning up MistralLLM instance")
169
- if self.http_client and not self.http_client.is_closed:
170
- await self.http_client.aclose()
171
197
  await super().cleanup()
@@ -1,16 +1,13 @@
1
- from typing import Dict, Optional, List, AsyncGenerator, Any
1
+ from typing import List, AsyncGenerator
2
2
  from ollama import AsyncClient, ChatResponse, ResponseError
3
- from ollama import Image # FIX: Import the Image type from the ollama library
4
3
  from autobyteus.llm.models import LLMModel
5
4
  from autobyteus.llm.base_llm import BaseLLM
6
5
  from autobyteus.llm.utils.llm_config import LLMConfig
7
- from autobyteus.llm.utils.messages import Message
6
+ from autobyteus.llm.utils.messages import Message, MessageRole
8
7
  from autobyteus.llm.utils.token_usage import TokenUsage
9
8
  from autobyteus.llm.utils.response_types import CompleteResponse, ChunkResponse
10
- from autobyteus.llm.user_message import LLMUserMessage
11
- from autobyteus.llm.utils.media_payload_formatter import image_source_to_base64
9
+ from autobyteus.llm.prompt_renderers.ollama_prompt_renderer import OllamaPromptRenderer
12
10
  import logging
13
- import asyncio
14
11
  import httpx
15
12
 
16
13
  logger = logging.getLogger(__name__)
@@ -25,37 +22,12 @@ class OllamaLLM(BaseLLM):
25
22
  self.client = AsyncClient(host=model.host_url)
26
23
 
27
24
  super().__init__(model=model, llm_config=llm_config)
25
+ self._renderer = OllamaPromptRenderer()
28
26
  logger.info(f"OllamaLLM initialized with model: {self.model.model_identifier}")
29
27
 
30
- async def _format_ollama_messages(self) -> List[Dict[str, Any]]:
31
- """
32
- Formats the conversation history for the Ollama API, including multimodal content.
33
- """
34
- formatted_messages = []
35
- for msg in self.messages:
36
- msg_dict = {
37
- "role": msg.role.value,
38
- "content": msg.content or ""
39
- }
40
- if msg.image_urls:
41
- try:
42
- # Concurrently process all images using the centralized utility
43
- image_tasks = [image_source_to_base64(url) for url in msg.image_urls]
44
- prepared_base64_images = await asyncio.gather(*image_tasks)
45
- if prepared_base64_images:
46
- # FIX: Wrap each base64 string in the official ollama.Image object
47
- msg_dict["images"] = [Image(value=b64_string) for b64_string in prepared_base64_images]
48
- except Exception as e:
49
- logger.error(f"Error processing images for Ollama, skipping them. Error: {e}")
50
-
51
- formatted_messages.append(msg_dict)
52
- return formatted_messages
53
-
54
- async def _send_user_message_to_llm(self, user_message: LLMUserMessage, **kwargs) -> CompleteResponse:
55
- self.add_user_message(user_message)
56
-
28
+ async def _send_messages_to_llm(self, messages: List[Message], **kwargs) -> CompleteResponse:
57
29
  try:
58
- formatted_messages = await self._format_ollama_messages()
30
+ formatted_messages = await self._renderer.render(messages)
59
31
  response: ChatResponse = await self.client.chat(
60
32
  model=self.model.value,
61
33
  messages=formatted_messages
@@ -71,8 +43,6 @@ class OllamaLLM(BaseLLM):
71
43
  reasoning_content = assistant_message[start_index + len("<think>"):end_index].strip()
72
44
  main_content = (assistant_message[:start_index] + assistant_message[end_index + len("</think>"):])
73
45
 
74
- self.add_assistant_message(main_content, reasoning_content=reasoning_content)
75
-
76
46
  token_usage = TokenUsage(
77
47
  prompt_tokens=response.get('prompt_eval_count', 0),
78
48
  completion_tokens=response.get('eval_count', 0),
@@ -94,17 +64,16 @@ class OllamaLLM(BaseLLM):
94
64
  logging.error(f"Unexpected error in Ollama call: {e}")
95
65
  raise
96
66
 
97
- async def _stream_user_message_to_llm(
98
- self, user_message: LLMUserMessage, **kwargs
67
+ async def _stream_messages_to_llm(
68
+ self, messages: List[Message], **kwargs
99
69
  ) -> AsyncGenerator[ChunkResponse, None]:
100
- self.add_user_message(user_message)
101
70
  accumulated_main = ""
102
71
  accumulated_reasoning = ""
103
72
  in_reasoning = False
104
73
  final_response = None
105
74
 
106
75
  try:
107
- formatted_messages = await self._format_ollama_messages()
76
+ formatted_messages = await self._renderer.render(messages)
108
77
  async for part in await self.client.chat(
109
78
  model=self.model.value,
110
79
  messages=formatted_messages,
@@ -141,8 +110,6 @@ class OllamaLLM(BaseLLM):
141
110
  )
142
111
 
143
112
  yield ChunkResponse(content="", reasoning=None, is_complete=True, usage=token_usage)
144
-
145
- self.add_assistant_message(accumulated_main, reasoning_content=accumulated_reasoning)
146
113
 
147
114
  except httpx.HTTPError as e:
148
115
  logging.error(f"HTTP Error in Ollama streaming: {e.response.status_code} - {e.response.text}")