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.
- autobyteus/agent/agent.py +15 -5
- autobyteus/agent/bootstrap_steps/__init__.py +3 -3
- autobyteus/agent/bootstrap_steps/agent_bootstrapper.py +5 -59
- autobyteus/agent/bootstrap_steps/base_bootstrap_step.py +1 -4
- autobyteus/agent/bootstrap_steps/mcp_server_prewarming_step.py +1 -3
- autobyteus/agent/bootstrap_steps/system_prompt_processing_step.py +16 -13
- autobyteus/agent/bootstrap_steps/working_context_snapshot_restore_step.py +38 -0
- autobyteus/agent/bootstrap_steps/workspace_context_initialization_step.py +2 -4
- autobyteus/agent/context/agent_config.py +47 -20
- autobyteus/agent/context/agent_context.py +23 -18
- autobyteus/agent/context/agent_runtime_state.py +21 -19
- autobyteus/agent/events/__init__.py +16 -1
- autobyteus/agent/events/agent_events.py +43 -3
- autobyteus/agent/events/agent_input_event_queue_manager.py +79 -26
- autobyteus/agent/events/event_store.py +57 -0
- autobyteus/agent/events/notifiers.py +69 -59
- autobyteus/agent/events/worker_event_dispatcher.py +21 -64
- autobyteus/agent/factory/agent_factory.py +83 -6
- autobyteus/agent/handlers/__init__.py +2 -0
- autobyteus/agent/handlers/approved_tool_invocation_event_handler.py +51 -34
- autobyteus/agent/handlers/bootstrap_event_handler.py +155 -0
- autobyteus/agent/handlers/inter_agent_message_event_handler.py +10 -0
- autobyteus/agent/handlers/lifecycle_event_logger.py +19 -11
- autobyteus/agent/handlers/llm_complete_response_received_event_handler.py +10 -15
- autobyteus/agent/handlers/llm_user_message_ready_event_handler.py +188 -48
- autobyteus/agent/handlers/tool_execution_approval_event_handler.py +0 -10
- autobyteus/agent/handlers/tool_invocation_request_event_handler.py +53 -48
- autobyteus/agent/handlers/tool_result_event_handler.py +7 -8
- autobyteus/agent/handlers/user_input_message_event_handler.py +10 -3
- autobyteus/agent/input_processor/memory_ingest_input_processor.py +44 -0
- autobyteus/agent/lifecycle/__init__.py +12 -0
- autobyteus/agent/lifecycle/base_processor.py +109 -0
- autobyteus/agent/lifecycle/events.py +35 -0
- autobyteus/agent/lifecycle/processor_definition.py +36 -0
- autobyteus/agent/lifecycle/processor_registry.py +106 -0
- autobyteus/agent/llm_request_assembler.py +98 -0
- autobyteus/agent/llm_response_processor/__init__.py +1 -8
- autobyteus/agent/message/context_file_type.py +1 -1
- autobyteus/agent/runtime/agent_runtime.py +29 -21
- autobyteus/agent/runtime/agent_worker.py +98 -19
- autobyteus/agent/shutdown_steps/__init__.py +2 -0
- autobyteus/agent/shutdown_steps/agent_shutdown_orchestrator.py +2 -0
- autobyteus/agent/shutdown_steps/tool_cleanup_step.py +58 -0
- autobyteus/agent/status/__init__.py +14 -0
- autobyteus/agent/status/manager.py +93 -0
- autobyteus/agent/status/status_deriver.py +96 -0
- autobyteus/agent/{phases/phase_enum.py → status/status_enum.py} +16 -16
- autobyteus/agent/status/status_update_utils.py +73 -0
- autobyteus/agent/streaming/__init__.py +52 -5
- autobyteus/agent/streaming/adapters/__init__.py +18 -0
- autobyteus/agent/streaming/adapters/invocation_adapter.py +184 -0
- autobyteus/agent/streaming/adapters/tool_call_parsing.py +163 -0
- autobyteus/agent/streaming/adapters/tool_syntax_registry.py +67 -0
- autobyteus/agent/streaming/agent_event_stream.py +3 -183
- autobyteus/agent/streaming/api_tool_call/__init__.py +16 -0
- autobyteus/agent/streaming/api_tool_call/file_content_streamer.py +56 -0
- autobyteus/agent/streaming/api_tool_call/json_string_field_extractor.py +175 -0
- autobyteus/agent/streaming/api_tool_call_streaming_response_handler.py +4 -0
- autobyteus/agent/streaming/events/__init__.py +6 -0
- autobyteus/agent/streaming/events/stream_event_payloads.py +284 -0
- autobyteus/agent/streaming/events/stream_events.py +141 -0
- autobyteus/agent/streaming/handlers/__init__.py +15 -0
- autobyteus/agent/streaming/handlers/api_tool_call_streaming_response_handler.py +303 -0
- autobyteus/agent/streaming/handlers/parsing_streaming_response_handler.py +107 -0
- autobyteus/agent/streaming/handlers/pass_through_streaming_response_handler.py +107 -0
- autobyteus/agent/streaming/handlers/streaming_handler_factory.py +177 -0
- autobyteus/agent/streaming/handlers/streaming_response_handler.py +58 -0
- autobyteus/agent/streaming/parser/__init__.py +61 -0
- autobyteus/agent/streaming/parser/event_emitter.py +181 -0
- autobyteus/agent/streaming/parser/events.py +4 -0
- autobyteus/agent/streaming/parser/invocation_adapter.py +4 -0
- autobyteus/agent/streaming/parser/json_parsing_strategies/__init__.py +19 -0
- autobyteus/agent/streaming/parser/json_parsing_strategies/base.py +32 -0
- autobyteus/agent/streaming/parser/json_parsing_strategies/default.py +34 -0
- autobyteus/agent/streaming/parser/json_parsing_strategies/gemini.py +31 -0
- autobyteus/agent/streaming/parser/json_parsing_strategies/openai.py +64 -0
- autobyteus/agent/streaming/parser/json_parsing_strategies/registry.py +75 -0
- autobyteus/agent/streaming/parser/parser_context.py +227 -0
- autobyteus/agent/streaming/parser/parser_factory.py +132 -0
- autobyteus/agent/streaming/parser/sentinel_format.py +7 -0
- autobyteus/agent/streaming/parser/state_factory.py +62 -0
- autobyteus/agent/streaming/parser/states/__init__.py +1 -0
- autobyteus/agent/streaming/parser/states/base_state.py +60 -0
- autobyteus/agent/streaming/parser/states/custom_xml_tag_run_bash_parsing_state.py +38 -0
- autobyteus/agent/streaming/parser/states/custom_xml_tag_write_file_parsing_state.py +55 -0
- autobyteus/agent/streaming/parser/states/delimited_content_state.py +146 -0
- autobyteus/agent/streaming/parser/states/json_initialization_state.py +144 -0
- autobyteus/agent/streaming/parser/states/json_tool_parsing_state.py +137 -0
- autobyteus/agent/streaming/parser/states/sentinel_content_state.py +30 -0
- autobyteus/agent/streaming/parser/states/sentinel_initialization_state.py +117 -0
- autobyteus/agent/streaming/parser/states/text_state.py +78 -0
- autobyteus/agent/streaming/parser/states/xml_patch_file_tool_parsing_state.py +328 -0
- autobyteus/agent/streaming/parser/states/xml_run_bash_tool_parsing_state.py +129 -0
- autobyteus/agent/streaming/parser/states/xml_tag_initialization_state.py +151 -0
- autobyteus/agent/streaming/parser/states/xml_tool_parsing_state.py +63 -0
- autobyteus/agent/streaming/parser/states/xml_write_file_tool_parsing_state.py +343 -0
- autobyteus/agent/streaming/parser/strategies/__init__.py +17 -0
- autobyteus/agent/streaming/parser/strategies/base.py +24 -0
- autobyteus/agent/streaming/parser/strategies/json_tool_strategy.py +26 -0
- autobyteus/agent/streaming/parser/strategies/registry.py +28 -0
- autobyteus/agent/streaming/parser/strategies/sentinel_strategy.py +23 -0
- autobyteus/agent/streaming/parser/strategies/xml_tag_strategy.py +21 -0
- autobyteus/agent/streaming/parser/stream_scanner.py +167 -0
- autobyteus/agent/streaming/parser/streaming_parser.py +212 -0
- autobyteus/agent/streaming/parser/tool_call_parsing.py +4 -0
- autobyteus/agent/streaming/parser/tool_constants.py +7 -0
- autobyteus/agent/streaming/parser/tool_syntax_registry.py +4 -0
- autobyteus/agent/streaming/parser/xml_tool_parsing_state_registry.py +55 -0
- autobyteus/agent/streaming/parsing_streaming_response_handler.py +4 -0
- autobyteus/agent/streaming/pass_through_streaming_response_handler.py +4 -0
- autobyteus/agent/streaming/queue_streamer.py +3 -57
- autobyteus/agent/streaming/segments/__init__.py +5 -0
- autobyteus/agent/streaming/segments/segment_events.py +82 -0
- autobyteus/agent/streaming/stream_event_payloads.py +2 -223
- autobyteus/agent/streaming/stream_events.py +3 -140
- autobyteus/agent/streaming/streaming_handler_factory.py +4 -0
- autobyteus/agent/streaming/streaming_response_handler.py +4 -0
- autobyteus/agent/streaming/streams/__init__.py +5 -0
- autobyteus/agent/streaming/streams/agent_event_stream.py +197 -0
- autobyteus/agent/streaming/utils/__init__.py +5 -0
- autobyteus/agent/streaming/utils/queue_streamer.py +59 -0
- autobyteus/agent/system_prompt_processor/__init__.py +2 -0
- autobyteus/agent/system_prompt_processor/available_skills_processor.py +96 -0
- autobyteus/agent/system_prompt_processor/base_processor.py +1 -1
- autobyteus/agent/system_prompt_processor/processor_meta.py +15 -2
- autobyteus/agent/system_prompt_processor/tool_manifest_injector_processor.py +39 -58
- autobyteus/agent/token_budget.py +56 -0
- autobyteus/agent/tool_execution_result_processor/memory_ingest_tool_result_processor.py +29 -0
- autobyteus/agent/tool_invocation.py +16 -40
- autobyteus/agent/tool_invocation_preprocessor/__init__.py +9 -0
- autobyteus/agent/tool_invocation_preprocessor/base_preprocessor.py +45 -0
- autobyteus/agent/tool_invocation_preprocessor/processor_definition.py +15 -0
- autobyteus/agent/tool_invocation_preprocessor/processor_meta.py +33 -0
- autobyteus/agent/tool_invocation_preprocessor/processor_registry.py +60 -0
- autobyteus/agent/utils/wait_for_idle.py +12 -14
- autobyteus/agent/workspace/base_workspace.py +6 -27
- autobyteus/agent_team/agent_team.py +3 -3
- autobyteus/agent_team/agent_team_builder.py +1 -41
- autobyteus/agent_team/bootstrap_steps/__init__.py +0 -4
- autobyteus/agent_team/bootstrap_steps/agent_configuration_preparation_step.py +8 -18
- autobyteus/agent_team/bootstrap_steps/agent_team_bootstrapper.py +4 -16
- autobyteus/agent_team/bootstrap_steps/base_agent_team_bootstrap_step.py +1 -2
- autobyteus/agent_team/bootstrap_steps/coordinator_initialization_step.py +1 -2
- autobyteus/agent_team/bootstrap_steps/task_notifier_initialization_step.py +1 -2
- autobyteus/agent_team/bootstrap_steps/team_context_initialization_step.py +4 -4
- autobyteus/agent_team/context/agent_team_config.py +6 -3
- autobyteus/agent_team/context/agent_team_context.py +25 -3
- autobyteus/agent_team/context/agent_team_runtime_state.py +9 -6
- autobyteus/agent_team/events/__init__.py +11 -0
- autobyteus/agent_team/events/agent_team_event_dispatcher.py +22 -9
- autobyteus/agent_team/events/agent_team_events.py +16 -0
- autobyteus/agent_team/events/event_store.py +57 -0
- autobyteus/agent_team/factory/agent_team_factory.py +8 -0
- autobyteus/agent_team/handlers/inter_agent_message_request_event_handler.py +18 -2
- autobyteus/agent_team/handlers/lifecycle_agent_team_event_handler.py +21 -5
- autobyteus/agent_team/handlers/process_user_message_event_handler.py +17 -8
- autobyteus/agent_team/handlers/tool_approval_team_event_handler.py +19 -4
- autobyteus/agent_team/runtime/agent_team_runtime.py +41 -10
- autobyteus/agent_team/runtime/agent_team_worker.py +69 -5
- autobyteus/agent_team/status/__init__.py +14 -0
- autobyteus/agent_team/status/agent_team_status.py +18 -0
- autobyteus/agent_team/status/agent_team_status_manager.py +33 -0
- autobyteus/agent_team/status/status_deriver.py +62 -0
- autobyteus/agent_team/status/status_update_utils.py +42 -0
- autobyteus/agent_team/streaming/__init__.py +2 -2
- autobyteus/agent_team/streaming/agent_team_event_notifier.py +6 -6
- autobyteus/agent_team/streaming/agent_team_stream_event_payloads.py +4 -4
- autobyteus/agent_team/streaming/agent_team_stream_events.py +3 -3
- autobyteus/agent_team/system_prompt_processor/__init__.py +6 -0
- autobyteus/agent_team/system_prompt_processor/team_manifest_injector_processor.py +76 -0
- autobyteus/agent_team/task_notification/task_notification_mode.py +19 -0
- autobyteus/agent_team/utils/wait_for_idle.py +4 -4
- autobyteus/cli/agent_cli.py +18 -10
- autobyteus/cli/agent_team_tui/app.py +14 -11
- autobyteus/cli/agent_team_tui/state.py +13 -15
- autobyteus/cli/agent_team_tui/widgets/agent_list_sidebar.py +15 -15
- autobyteus/cli/agent_team_tui/widgets/focus_pane.py +143 -36
- autobyteus/cli/agent_team_tui/widgets/renderables.py +1 -1
- autobyteus/cli/agent_team_tui/widgets/shared.py +25 -25
- autobyteus/cli/cli_display.py +193 -44
- autobyteus/cli/workflow_tui/app.py +9 -10
- autobyteus/cli/workflow_tui/state.py +14 -16
- autobyteus/cli/workflow_tui/widgets/agent_list_sidebar.py +15 -15
- autobyteus/cli/workflow_tui/widgets/focus_pane.py +137 -35
- autobyteus/cli/workflow_tui/widgets/renderables.py +1 -1
- autobyteus/cli/workflow_tui/widgets/shared.py +25 -25
- autobyteus/clients/autobyteus_client.py +94 -1
- autobyteus/events/event_types.py +11 -18
- autobyteus/llm/api/autobyteus_llm.py +33 -29
- autobyteus/llm/api/claude_llm.py +142 -36
- autobyteus/llm/api/gemini_llm.py +163 -59
- autobyteus/llm/api/grok_llm.py +1 -1
- autobyteus/llm/api/minimax_llm.py +26 -0
- autobyteus/llm/api/mistral_llm.py +113 -87
- autobyteus/llm/api/ollama_llm.py +9 -42
- autobyteus/llm/api/openai_compatible_llm.py +127 -91
- autobyteus/llm/api/openai_llm.py +3 -3
- autobyteus/llm/api/openai_responses_llm.py +324 -0
- autobyteus/llm/api/zhipu_llm.py +21 -2
- autobyteus/llm/autobyteus_provider.py +70 -60
- autobyteus/llm/base_llm.py +85 -81
- autobyteus/llm/converters/__init__.py +14 -0
- autobyteus/llm/converters/anthropic_tool_call_converter.py +37 -0
- autobyteus/llm/converters/gemini_tool_call_converter.py +57 -0
- autobyteus/llm/converters/mistral_tool_call_converter.py +37 -0
- autobyteus/llm/converters/openai_tool_call_converter.py +38 -0
- autobyteus/llm/extensions/base_extension.py +6 -12
- autobyteus/llm/extensions/token_usage_tracking_extension.py +45 -18
- autobyteus/llm/llm_factory.py +282 -204
- autobyteus/llm/lmstudio_provider.py +60 -49
- autobyteus/llm/models.py +35 -2
- autobyteus/llm/ollama_provider.py +60 -49
- autobyteus/llm/ollama_provider_resolver.py +0 -1
- autobyteus/llm/prompt_renderers/__init__.py +19 -0
- autobyteus/llm/prompt_renderers/anthropic_prompt_renderer.py +104 -0
- autobyteus/llm/prompt_renderers/autobyteus_prompt_renderer.py +19 -0
- autobyteus/llm/prompt_renderers/base_prompt_renderer.py +10 -0
- autobyteus/llm/prompt_renderers/gemini_prompt_renderer.py +63 -0
- autobyteus/llm/prompt_renderers/mistral_prompt_renderer.py +87 -0
- autobyteus/llm/prompt_renderers/ollama_prompt_renderer.py +51 -0
- autobyteus/llm/prompt_renderers/openai_chat_renderer.py +97 -0
- autobyteus/llm/prompt_renderers/openai_responses_renderer.py +101 -0
- autobyteus/llm/providers.py +1 -3
- autobyteus/llm/token_counter/claude_token_counter.py +56 -25
- autobyteus/llm/token_counter/mistral_token_counter.py +12 -8
- autobyteus/llm/token_counter/openai_token_counter.py +24 -5
- autobyteus/llm/token_counter/token_counter_factory.py +12 -5
- autobyteus/llm/utils/llm_config.py +6 -12
- autobyteus/llm/utils/media_payload_formatter.py +27 -20
- autobyteus/llm/utils/messages.py +55 -3
- autobyteus/llm/utils/response_types.py +3 -0
- autobyteus/llm/utils/tool_call_delta.py +31 -0
- autobyteus/memory/__init__.py +35 -0
- autobyteus/memory/compaction/__init__.py +9 -0
- autobyteus/memory/compaction/compaction_result.py +8 -0
- autobyteus/memory/compaction/compactor.py +89 -0
- autobyteus/memory/compaction/summarizer.py +11 -0
- autobyteus/memory/compaction_snapshot_builder.py +84 -0
- autobyteus/memory/memory_manager.py +205 -0
- autobyteus/memory/models/__init__.py +14 -0
- autobyteus/memory/models/episodic_item.py +41 -0
- autobyteus/memory/models/memory_types.py +7 -0
- autobyteus/memory/models/raw_trace_item.py +79 -0
- autobyteus/memory/models/semantic_item.py +41 -0
- autobyteus/memory/models/tool_interaction.py +20 -0
- autobyteus/memory/path_resolver.py +27 -0
- autobyteus/memory/policies/__init__.py +5 -0
- autobyteus/memory/policies/compaction_policy.py +16 -0
- autobyteus/memory/restore/__init__.py +1 -0
- autobyteus/memory/restore/working_context_snapshot_bootstrapper.py +61 -0
- autobyteus/memory/retrieval/__init__.py +7 -0
- autobyteus/memory/retrieval/memory_bundle.py +11 -0
- autobyteus/memory/retrieval/retriever.py +13 -0
- autobyteus/memory/store/__init__.py +9 -0
- autobyteus/memory/store/base_store.py +14 -0
- autobyteus/memory/store/file_store.py +98 -0
- autobyteus/memory/store/working_context_snapshot_store.py +28 -0
- autobyteus/memory/tool_interaction_builder.py +46 -0
- autobyteus/memory/turn_tracker.py +9 -0
- autobyteus/memory/working_context_snapshot.py +69 -0
- autobyteus/memory/working_context_snapshot_serializer.py +135 -0
- autobyteus/multimedia/audio/api/autobyteus_audio_client.py +19 -5
- autobyteus/multimedia/audio/api/gemini_audio_client.py +109 -16
- autobyteus/multimedia/audio/audio_client_factory.py +47 -9
- autobyteus/multimedia/audio/audio_model.py +2 -1
- autobyteus/multimedia/image/api/autobyteus_image_client.py +19 -5
- autobyteus/multimedia/image/api/gemini_image_client.py +39 -17
- autobyteus/multimedia/image/api/openai_image_client.py +125 -43
- autobyteus/multimedia/image/autobyteus_image_provider.py +2 -1
- autobyteus/multimedia/image/image_client_factory.py +47 -15
- autobyteus/multimedia/image/image_model.py +5 -2
- autobyteus/multimedia/providers.py +3 -2
- autobyteus/skills/loader.py +71 -0
- autobyteus/skills/model.py +11 -0
- autobyteus/skills/registry.py +70 -0
- autobyteus/task_management/tools/todo_tools/add_todo.py +2 -2
- autobyteus/task_management/tools/todo_tools/create_todo_list.py +2 -2
- autobyteus/task_management/tools/todo_tools/update_todo_status.py +2 -2
- autobyteus/tools/__init__.py +34 -47
- autobyteus/tools/base_tool.py +7 -0
- autobyteus/tools/file/__init__.py +2 -6
- autobyteus/tools/file/patch_file.py +149 -0
- autobyteus/tools/file/read_file.py +36 -5
- autobyteus/tools/file/write_file.py +4 -1
- autobyteus/tools/functional_tool.py +43 -6
- autobyteus/tools/mcp/__init__.py +2 -0
- autobyteus/tools/mcp/config_service.py +5 -1
- autobyteus/tools/mcp/server/__init__.py +2 -0
- autobyteus/tools/mcp/server/http_managed_mcp_server.py +1 -1
- autobyteus/tools/mcp/server/websocket_managed_mcp_server.py +141 -0
- autobyteus/tools/mcp/server_instance_manager.py +8 -1
- autobyteus/tools/mcp/types.py +61 -0
- autobyteus/tools/multimedia/audio_tools.py +70 -17
- autobyteus/tools/multimedia/download_media_tool.py +18 -4
- autobyteus/tools/multimedia/image_tools.py +246 -62
- autobyteus/tools/operation_executor/journal_manager.py +107 -0
- autobyteus/tools/operation_executor/operation_event_buffer.py +57 -0
- autobyteus/tools/operation_executor/operation_event_producer.py +29 -0
- autobyteus/tools/operation_executor/operation_executor.py +58 -0
- autobyteus/tools/registry/tool_definition.py +43 -2
- autobyteus/tools/skill/load_skill.py +50 -0
- autobyteus/tools/terminal/__init__.py +45 -0
- autobyteus/tools/terminal/ansi_utils.py +32 -0
- autobyteus/tools/terminal/background_process_manager.py +233 -0
- autobyteus/tools/terminal/output_buffer.py +105 -0
- autobyteus/tools/terminal/prompt_detector.py +63 -0
- autobyteus/tools/terminal/pty_session.py +241 -0
- autobyteus/tools/terminal/session_factory.py +20 -0
- autobyteus/tools/terminal/terminal_session_manager.py +226 -0
- autobyteus/tools/terminal/tools/__init__.py +13 -0
- autobyteus/tools/terminal/tools/get_process_output.py +81 -0
- autobyteus/tools/terminal/tools/run_bash.py +109 -0
- autobyteus/tools/terminal/tools/start_background_process.py +104 -0
- autobyteus/tools/terminal/tools/stop_background_process.py +67 -0
- autobyteus/tools/terminal/types.py +54 -0
- autobyteus/tools/terminal/wsl_tmux_session.py +221 -0
- autobyteus/tools/terminal/wsl_utils.py +156 -0
- autobyteus/tools/transaction_management/backup_handler.py +48 -0
- autobyteus/tools/transaction_management/operation_lifecycle_manager.py +62 -0
- autobyteus/tools/usage/__init__.py +1 -2
- autobyteus/tools/usage/formatters/__init__.py +17 -1
- autobyteus/tools/usage/formatters/base_formatter.py +8 -0
- autobyteus/tools/usage/formatters/default_xml_schema_formatter.py +2 -2
- autobyteus/tools/usage/formatters/mistral_json_schema_formatter.py +18 -0
- autobyteus/tools/usage/formatters/patch_file_xml_example_formatter.py +64 -0
- autobyteus/tools/usage/formatters/patch_file_xml_schema_formatter.py +31 -0
- autobyteus/tools/usage/formatters/run_bash_xml_example_formatter.py +32 -0
- autobyteus/tools/usage/formatters/run_bash_xml_schema_formatter.py +36 -0
- autobyteus/tools/usage/formatters/write_file_xml_example_formatter.py +53 -0
- autobyteus/tools/usage/formatters/write_file_xml_schema_formatter.py +31 -0
- autobyteus/tools/usage/providers/tool_manifest_provider.py +10 -10
- autobyteus/tools/usage/registries/__init__.py +1 -3
- autobyteus/tools/usage/registries/tool_formatting_registry.py +115 -8
- autobyteus/tools/usage/tool_schema_provider.py +51 -0
- autobyteus/tools/web/__init__.py +4 -0
- autobyteus/tools/web/read_url_tool.py +80 -0
- autobyteus/utils/diff_utils.py +271 -0
- autobyteus/utils/download_utils.py +109 -0
- autobyteus/utils/file_utils.py +57 -2
- autobyteus/utils/gemini_helper.py +64 -0
- autobyteus/utils/gemini_model_mapping.py +71 -0
- autobyteus/utils/llm_output_formatter.py +75 -0
- autobyteus/utils/tool_call_format.py +36 -0
- autobyteus/workflow/agentic_workflow.py +3 -3
- autobyteus/workflow/bootstrap_steps/agent_tool_injection_step.py +2 -2
- autobyteus/workflow/bootstrap_steps/base_workflow_bootstrap_step.py +2 -2
- autobyteus/workflow/bootstrap_steps/coordinator_initialization_step.py +2 -2
- autobyteus/workflow/bootstrap_steps/coordinator_prompt_preparation_step.py +3 -9
- autobyteus/workflow/bootstrap_steps/workflow_bootstrapper.py +6 -6
- autobyteus/workflow/bootstrap_steps/workflow_runtime_queue_initialization_step.py +2 -2
- autobyteus/workflow/context/workflow_context.py +3 -3
- autobyteus/workflow/context/workflow_runtime_state.py +5 -5
- autobyteus/workflow/events/workflow_event_dispatcher.py +5 -5
- autobyteus/workflow/handlers/lifecycle_workflow_event_handler.py +3 -3
- autobyteus/workflow/handlers/process_user_message_event_handler.py +5 -5
- autobyteus/workflow/handlers/tool_approval_workflow_event_handler.py +2 -2
- autobyteus/workflow/runtime/workflow_runtime.py +8 -8
- autobyteus/workflow/runtime/workflow_worker.py +3 -3
- autobyteus/workflow/status/__init__.py +11 -0
- autobyteus/workflow/status/workflow_status.py +19 -0
- autobyteus/workflow/status/workflow_status_manager.py +48 -0
- autobyteus/workflow/streaming/__init__.py +2 -2
- autobyteus/workflow/streaming/workflow_event_notifier.py +7 -7
- autobyteus/workflow/streaming/workflow_stream_event_payloads.py +4 -4
- autobyteus/workflow/streaming/workflow_stream_events.py +3 -3
- autobyteus/workflow/utils/wait_for_idle.py +4 -4
- autobyteus-1.3.0.dist-info/METADATA +293 -0
- autobyteus-1.3.0.dist-info/RECORD +606 -0
- {autobyteus-1.2.1.dist-info → autobyteus-1.3.0.dist-info}/WHEEL +1 -1
- {autobyteus-1.2.1.dist-info → autobyteus-1.3.0.dist-info}/top_level.txt +0 -1
- autobyteus/agent/bootstrap_steps/agent_runtime_queue_initialization_step.py +0 -57
- autobyteus/agent/hooks/__init__.py +0 -16
- autobyteus/agent/hooks/base_phase_hook.py +0 -78
- autobyteus/agent/hooks/hook_definition.py +0 -36
- autobyteus/agent/hooks/hook_meta.py +0 -37
- autobyteus/agent/hooks/hook_registry.py +0 -106
- autobyteus/agent/llm_response_processor/provider_aware_tool_usage_processor.py +0 -103
- autobyteus/agent/phases/__init__.py +0 -18
- autobyteus/agent/phases/discover.py +0 -53
- autobyteus/agent/phases/manager.py +0 -265
- autobyteus/agent/phases/transition_decorator.py +0 -40
- autobyteus/agent/phases/transition_info.py +0 -33
- autobyteus/agent/remote_agent.py +0 -244
- autobyteus/agent/workspace/workspace_definition.py +0 -36
- autobyteus/agent/workspace/workspace_meta.py +0 -37
- autobyteus/agent/workspace/workspace_registry.py +0 -72
- autobyteus/agent_team/bootstrap_steps/agent_team_runtime_queue_initialization_step.py +0 -25
- autobyteus/agent_team/bootstrap_steps/coordinator_prompt_preparation_step.py +0 -85
- autobyteus/agent_team/phases/__init__.py +0 -11
- autobyteus/agent_team/phases/agent_team_operational_phase.py +0 -19
- autobyteus/agent_team/phases/agent_team_phase_manager.py +0 -48
- autobyteus/llm/api/bedrock_llm.py +0 -92
- autobyteus/llm/api/groq_llm.py +0 -94
- autobyteus/llm/api/nvidia_llm.py +0 -108
- autobyteus/llm/utils/token_pricing_config.py +0 -87
- autobyteus/rpc/__init__.py +0 -73
- autobyteus/rpc/client/__init__.py +0 -17
- autobyteus/rpc/client/abstract_client_connection.py +0 -124
- autobyteus/rpc/client/client_connection_manager.py +0 -153
- autobyteus/rpc/client/sse_client_connection.py +0 -306
- autobyteus/rpc/client/stdio_client_connection.py +0 -280
- autobyteus/rpc/config/__init__.py +0 -13
- autobyteus/rpc/config/agent_server_config.py +0 -153
- autobyteus/rpc/config/agent_server_registry.py +0 -152
- autobyteus/rpc/hosting.py +0 -244
- autobyteus/rpc/protocol.py +0 -244
- autobyteus/rpc/server/__init__.py +0 -20
- autobyteus/rpc/server/agent_server_endpoint.py +0 -181
- autobyteus/rpc/server/base_method_handler.py +0 -40
- autobyteus/rpc/server/method_handlers.py +0 -259
- autobyteus/rpc/server/sse_server_handler.py +0 -182
- autobyteus/rpc/server/stdio_server_handler.py +0 -151
- autobyteus/rpc/server_main.py +0 -198
- autobyteus/rpc/transport_type.py +0 -13
- autobyteus/tools/bash/__init__.py +0 -2
- autobyteus/tools/bash/bash_executor.py +0 -100
- autobyteus/tools/browser/__init__.py +0 -2
- autobyteus/tools/browser/session_aware/browser_session_aware_navigate_to.py +0 -75
- autobyteus/tools/browser/session_aware/browser_session_aware_tool.py +0 -30
- autobyteus/tools/browser/session_aware/browser_session_aware_web_element_trigger.py +0 -154
- autobyteus/tools/browser/session_aware/browser_session_aware_webpage_reader.py +0 -89
- autobyteus/tools/browser/session_aware/browser_session_aware_webpage_screenshot_taker.py +0 -107
- autobyteus/tools/browser/session_aware/factory/browser_session_aware_web_element_trigger_factory.py +0 -14
- autobyteus/tools/browser/session_aware/factory/browser_session_aware_webpage_reader_factory.py +0 -26
- autobyteus/tools/browser/session_aware/factory/browser_session_aware_webpage_screenshot_taker_factory.py +0 -14
- autobyteus/tools/browser/session_aware/shared_browser_session.py +0 -11
- autobyteus/tools/browser/session_aware/shared_browser_session_manager.py +0 -25
- autobyteus/tools/browser/session_aware/web_element_action.py +0 -20
- autobyteus/tools/browser/standalone/__init__.py +0 -6
- autobyteus/tools/browser/standalone/factory/__init__.py +0 -0
- autobyteus/tools/browser/standalone/factory/webpage_reader_factory.py +0 -25
- autobyteus/tools/browser/standalone/factory/webpage_screenshot_taker_factory.py +0 -14
- autobyteus/tools/browser/standalone/navigate_to.py +0 -84
- autobyteus/tools/browser/standalone/web_page_pdf_generator.py +0 -101
- autobyteus/tools/browser/standalone/webpage_image_downloader.py +0 -169
- autobyteus/tools/browser/standalone/webpage_reader.py +0 -105
- autobyteus/tools/browser/standalone/webpage_screenshot_taker.py +0 -105
- autobyteus/tools/file/edit_file.py +0 -200
- autobyteus/tools/file/list_directory.py +0 -168
- autobyteus/tools/file/search_files.py +0 -188
- autobyteus/tools/timer.py +0 -175
- autobyteus/tools/usage/parsers/__init__.py +0 -22
- autobyteus/tools/usage/parsers/_json_extractor.py +0 -99
- autobyteus/tools/usage/parsers/_string_decoders.py +0 -18
- autobyteus/tools/usage/parsers/anthropic_xml_tool_usage_parser.py +0 -10
- autobyteus/tools/usage/parsers/base_parser.py +0 -41
- autobyteus/tools/usage/parsers/default_json_tool_usage_parser.py +0 -83
- autobyteus/tools/usage/parsers/default_xml_tool_usage_parser.py +0 -316
- autobyteus/tools/usage/parsers/exceptions.py +0 -13
- autobyteus/tools/usage/parsers/gemini_json_tool_usage_parser.py +0 -77
- autobyteus/tools/usage/parsers/openai_json_tool_usage_parser.py +0 -149
- autobyteus/tools/usage/parsers/provider_aware_tool_usage_parser.py +0 -59
- autobyteus/tools/usage/registries/tool_usage_parser_registry.py +0 -62
- autobyteus/workflow/phases/__init__.py +0 -11
- autobyteus/workflow/phases/workflow_operational_phase.py +0 -19
- autobyteus/workflow/phases/workflow_phase_manager.py +0 -48
- autobyteus-1.2.1.dist-info/METADATA +0 -205
- autobyteus-1.2.1.dist-info/RECORD +0 -511
- examples/__init__.py +0 -1
- examples/agent_team/__init__.py +0 -1
- examples/discover_phase_transitions.py +0 -104
- examples/run_agentic_software_engineer.py +0 -239
- examples/run_browser_agent.py +0 -262
- examples/run_google_slides_agent.py +0 -287
- examples/run_mcp_browser_client.py +0 -174
- examples/run_mcp_google_slides_client.py +0 -270
- examples/run_mcp_list_tools.py +0 -189
- examples/run_poem_writer.py +0 -284
- examples/run_sqlite_agent.py +0 -295
- /autobyteus/{tools/browser/session_aware → skills}/__init__.py +0 -0
- /autobyteus/tools/{browser/session_aware/factory → skill}/__init__.py +0 -0
- {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
|
|
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
|
|
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.
|
|
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
|
-
|
|
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
|
|
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
|
|
97
|
-
self,
|
|
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
|
|
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
|
|
127
|
-
self,
|
|
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
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
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
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
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()
|
autobyteus/llm/api/ollama_llm.py
CHANGED
|
@@ -1,16 +1,13 @@
|
|
|
1
|
-
from typing import
|
|
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.
|
|
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
|
|
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.
|
|
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
|
|
98
|
-
self,
|
|
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.
|
|
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}")
|