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,71 @@
|
|
|
1
|
+
"""Runtime-aware Gemini model name resolution (API key vs Vertex AI).
|
|
2
|
+
|
|
3
|
+
Gemini uses different public names for some models between the Developer API
|
|
4
|
+
(`gemini-*-*-preview` suffixes) and Vertex AI (no `-preview`). Keeping this
|
|
5
|
+
logic separate lets clients stay focused on I/O while we centralize naming
|
|
6
|
+
quirks.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import logging
|
|
10
|
+
|
|
11
|
+
logger = logging.getLogger(__name__)
|
|
12
|
+
|
|
13
|
+
# Maps Developer API model names to their Vertex AI equivalents by modality.
|
|
14
|
+
# As of Dec 18, 2025 the public LLM and image IDs are aligned across runtimes,
|
|
15
|
+
# while some TTS variants still differ.
|
|
16
|
+
_MODEL_RUNTIME_MAP = {
|
|
17
|
+
"tts": {
|
|
18
|
+
"gemini-2.5-flash-preview-tts": {
|
|
19
|
+
"vertex": "gemini-2.5-flash-tts",
|
|
20
|
+
"api_key": "gemini-2.5-flash-preview-tts",
|
|
21
|
+
},
|
|
22
|
+
"gemini-2.5-pro-preview-tts": {
|
|
23
|
+
"vertex": "gemini-2.5-pro-tts",
|
|
24
|
+
"api_key": "gemini-2.5-pro-preview-tts",
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
# For LLM & image the names are currently uniform across runtimes,
|
|
28
|
+
# but the structure is ready should Google introduce divergent aliases.
|
|
29
|
+
"llm": {
|
|
30
|
+
"gemini-3-pro-preview": {
|
|
31
|
+
"vertex": "gemini-3-pro-preview",
|
|
32
|
+
"api_key": "gemini-3-pro-preview",
|
|
33
|
+
},
|
|
34
|
+
"gemini-3-flash-preview": {
|
|
35
|
+
"vertex": "gemini-3-flash-preview",
|
|
36
|
+
"api_key": "gemini-3-flash-preview",
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
"image": {
|
|
40
|
+
"gemini-3-pro-image-preview": {
|
|
41
|
+
"vertex": "gemini-3-pro-image-preview",
|
|
42
|
+
"api_key": "gemini-3-pro-image-preview",
|
|
43
|
+
},
|
|
44
|
+
"gemini-2.5-flash-image": {
|
|
45
|
+
"vertex": "gemini-2.5-flash-image",
|
|
46
|
+
"api_key": "gemini-2.5-flash-image",
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def resolve_model_for_runtime(model_value: str, modality: str, *, runtime: str | None = None) -> str:
|
|
53
|
+
"""Return the correct model name for the active Gemini runtime.
|
|
54
|
+
|
|
55
|
+
Args:
|
|
56
|
+
model_value: The requested model name (usually from AudioModel.value).
|
|
57
|
+
modality: One of "tts", "llm", "image".
|
|
58
|
+
runtime: Explicit runtime identifier ("vertex" or "api_key").
|
|
59
|
+
"""
|
|
60
|
+
if not runtime:
|
|
61
|
+
return model_value
|
|
62
|
+
|
|
63
|
+
modality_map = _MODEL_RUNTIME_MAP.get(modality, {})
|
|
64
|
+
runtime_map = modality_map.get(model_value)
|
|
65
|
+
if runtime_map and runtime in runtime_map:
|
|
66
|
+
mapped = runtime_map[runtime]
|
|
67
|
+
if mapped != model_value:
|
|
68
|
+
logger.info("Adjusting Gemini model for runtime '%s': '%s' -> '%s'", runtime, model_value, mapped)
|
|
69
|
+
return mapped
|
|
70
|
+
|
|
71
|
+
return model_value
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
from typing import Any, Dict, List
|
|
2
|
+
import dataclasses
|
|
3
|
+
|
|
4
|
+
def format_to_clean_string(data: Any, indent: int = 0) -> str:
|
|
5
|
+
"""
|
|
6
|
+
Formats complex data structures into a clean, human-readable string optimized for LLM consumption.
|
|
7
|
+
Avoids JSON syntax noise (braces, quotes) and YAML markers.
|
|
8
|
+
Supports Dicts, Lists, Dataclasses, and Pydantic models.
|
|
9
|
+
|
|
10
|
+
Args:
|
|
11
|
+
data: The data to format.
|
|
12
|
+
indent: Current indentation level (spaces).
|
|
13
|
+
|
|
14
|
+
Returns:
|
|
15
|
+
A formatted string representation of the data.
|
|
16
|
+
"""
|
|
17
|
+
indent_str = " " * indent
|
|
18
|
+
|
|
19
|
+
# Handle Dataclasses
|
|
20
|
+
if dataclasses.is_dataclass(data) and not isinstance(data, type):
|
|
21
|
+
data = dataclasses.asdict(data)
|
|
22
|
+
|
|
23
|
+
# Handle Pydantic Models (v1: dict(), v2: model_dump())
|
|
24
|
+
elif hasattr(data, 'model_dump'):
|
|
25
|
+
data = data.model_dump()
|
|
26
|
+
elif hasattr(data, 'dict') and callable(getattr(data, 'dict')):
|
|
27
|
+
# Fallback for Pydantic V1 or similar
|
|
28
|
+
data = data.dict()
|
|
29
|
+
|
|
30
|
+
if isinstance(data, dict):
|
|
31
|
+
if not data:
|
|
32
|
+
return f"{indent_str}(empty dict)"
|
|
33
|
+
|
|
34
|
+
lines = []
|
|
35
|
+
for key, value in data.items():
|
|
36
|
+
value_str = format_to_clean_string(value, indent + 2)
|
|
37
|
+
|
|
38
|
+
if isinstance(value, (dict, list)) and value:
|
|
39
|
+
lines.append(f"{indent_str}{key}:\n{value_str}")
|
|
40
|
+
elif dataclasses.is_dataclass(value) or hasattr(value, 'model_dump') or hasattr(value, 'dict'):
|
|
41
|
+
# Treat complex objects similarly to nested dicts
|
|
42
|
+
lines.append(f"{indent_str}{key}:\n{value_str}")
|
|
43
|
+
elif isinstance(value, str) and '\n' in value:
|
|
44
|
+
# Multiline strings should also be on a new line for readability
|
|
45
|
+
lines.append(f"{indent_str}{key}:\n{value_str}")
|
|
46
|
+
else:
|
|
47
|
+
lines.append(f"{indent_str}{key}: {value_str.lstrip()}")
|
|
48
|
+
return "\n".join(lines)
|
|
49
|
+
|
|
50
|
+
elif isinstance(data, list):
|
|
51
|
+
if not data:
|
|
52
|
+
return f"{indent_str}(empty list)"
|
|
53
|
+
|
|
54
|
+
lines = []
|
|
55
|
+
for item in data:
|
|
56
|
+
item_str = format_to_clean_string(item, indent + 2)
|
|
57
|
+
if isinstance(item, (dict, list)) or dataclasses.is_dataclass(item) or hasattr(item, 'model_dump'):
|
|
58
|
+
lines.append(f"{indent_str}- \n{item_str}")
|
|
59
|
+
else:
|
|
60
|
+
lines.append(f"{indent_str}- {item_str.lstrip()}")
|
|
61
|
+
return "\n".join(lines)
|
|
62
|
+
|
|
63
|
+
elif isinstance(data, str):
|
|
64
|
+
lines = data.splitlines()
|
|
65
|
+
if not lines:
|
|
66
|
+
return f"{indent_str}\"\"" # Represent empty string explicitely or just empty? Let's use empty quotes for clarity if needed, or just nothing.
|
|
67
|
+
# Actually, user wants clean text. Empty string usually implies no content.
|
|
68
|
+
# Let's return "" if empty, but if it has content, indent it.
|
|
69
|
+
return ""
|
|
70
|
+
|
|
71
|
+
formatted_lines = [f"{indent_str}{line}" for line in lines]
|
|
72
|
+
return "\n".join(formatted_lines)
|
|
73
|
+
|
|
74
|
+
else:
|
|
75
|
+
return f"{indent_str}{str(data)}"
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Helpers for resolving tool-call format selection.
|
|
3
|
+
"""
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
import os
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
ENV_TOOL_CALL_FORMAT = "AUTOBYTEUS_STREAM_PARSER"
|
|
10
|
+
_VALID_FORMATS = {"xml", "json", "sentinel", "api_tool_call"}
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def resolve_tool_call_format() -> str:
|
|
14
|
+
"""
|
|
15
|
+
Resolve the tool-call format from environment.
|
|
16
|
+
|
|
17
|
+
Returns one of: "xml", "json", "sentinel", "api_tool_call".
|
|
18
|
+
Defaults to "api_tool_call" when unset/invalid.
|
|
19
|
+
"""
|
|
20
|
+
value = os.getenv(ENV_TOOL_CALL_FORMAT)
|
|
21
|
+
if not value:
|
|
22
|
+
return "api_tool_call"
|
|
23
|
+
value = value.strip().lower()
|
|
24
|
+
if value in _VALID_FORMATS:
|
|
25
|
+
return value
|
|
26
|
+
return "api_tool_call"
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def is_xml_tool_format() -> bool:
|
|
30
|
+
"""Return True if tool-call format is forced to XML by environment."""
|
|
31
|
+
return resolve_tool_call_format() == "xml"
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def is_json_tool_format() -> bool:
|
|
35
|
+
"""Return True if tool-call format is forced to JSON by environment."""
|
|
36
|
+
return resolve_tool_call_format() == "json"
|
|
@@ -5,7 +5,7 @@ from typing import Optional
|
|
|
5
5
|
from autobyteus.workflow.runtime.workflow_runtime import WorkflowRuntime
|
|
6
6
|
from autobyteus.workflow.events.workflow_events import ProcessUserMessageEvent, ToolApprovalWorkflowEvent
|
|
7
7
|
from autobyteus.agent.message.agent_input_user_message import AgentInputUserMessage
|
|
8
|
-
from autobyteus.workflow.
|
|
8
|
+
from autobyteus.workflow.status.workflow_status import WorkflowStatus
|
|
9
9
|
|
|
10
10
|
logger = logging.getLogger(__name__)
|
|
11
11
|
|
|
@@ -89,5 +89,5 @@ class AgenticWorkflow:
|
|
|
89
89
|
"""Checks if the workflow's worker is running."""
|
|
90
90
|
return self._runtime.is_running
|
|
91
91
|
|
|
92
|
-
def
|
|
93
|
-
return self._runtime.context.state.
|
|
92
|
+
def get_current_status(self) -> WorkflowStatus:
|
|
93
|
+
return self._runtime.context.state.current_status
|
|
@@ -10,7 +10,7 @@ from autobyteus.tools.registry import default_tool_registry
|
|
|
10
10
|
|
|
11
11
|
if TYPE_CHECKING:
|
|
12
12
|
from autobyteus.workflow.context.workflow_context import WorkflowContext
|
|
13
|
-
from autobyteus.workflow.
|
|
13
|
+
from autobyteus.workflow.status.workflow_status_manager import WorkflowStatusManager
|
|
14
14
|
|
|
15
15
|
logger = logging.getLogger(__name__)
|
|
16
16
|
|
|
@@ -23,7 +23,7 @@ class AgentToolInjectionStep(BaseWorkflowBootstrapStep):
|
|
|
23
23
|
The primary logic of applying the coordinator prompt has been moved to the TeamManager
|
|
24
24
|
to ensure it happens just before the coordinator is created.
|
|
25
25
|
"""
|
|
26
|
-
async def execute(self, context: 'WorkflowContext',
|
|
26
|
+
async def execute(self, context: 'WorkflowContext', status_manager: 'WorkflowStatusManager') -> bool:
|
|
27
27
|
workflow_id = context.workflow_id
|
|
28
28
|
logger.info(f"Workflow '{workflow_id}': Executing AgentToolInjectionStep (now a placeholder).")
|
|
29
29
|
# The logic for injecting SendMessageTo and setting the coordinator prompt is now
|
|
@@ -5,7 +5,7 @@ from typing import TYPE_CHECKING
|
|
|
5
5
|
|
|
6
6
|
if TYPE_CHECKING:
|
|
7
7
|
from autobyteus.workflow.context.workflow_context import WorkflowContext
|
|
8
|
-
from autobyteus.workflow.
|
|
8
|
+
from autobyteus.workflow.status.workflow_status_manager import WorkflowStatusManager
|
|
9
9
|
|
|
10
10
|
logger = logging.getLogger(__name__)
|
|
11
11
|
|
|
@@ -13,7 +13,7 @@ class BaseWorkflowBootstrapStep(ABC):
|
|
|
13
13
|
"""Abstract base class for individual steps in the workflow bootstrapping process."""
|
|
14
14
|
|
|
15
15
|
@abstractmethod
|
|
16
|
-
async def execute(self, context: 'WorkflowContext',
|
|
16
|
+
async def execute(self, context: 'WorkflowContext', status_manager: 'WorkflowStatusManager') -> bool:
|
|
17
17
|
"""
|
|
18
18
|
Executes the bootstrap step.
|
|
19
19
|
|
|
@@ -6,7 +6,7 @@ from autobyteus.workflow.bootstrap_steps.base_workflow_bootstrap_step import Bas
|
|
|
6
6
|
|
|
7
7
|
if TYPE_CHECKING:
|
|
8
8
|
from autobyteus.workflow.context.workflow_context import WorkflowContext
|
|
9
|
-
from autobyteus.workflow.
|
|
9
|
+
from autobyteus.workflow.status.workflow_status_manager import WorkflowStatusManager
|
|
10
10
|
|
|
11
11
|
logger = logging.getLogger(__name__)
|
|
12
12
|
|
|
@@ -16,7 +16,7 @@ class CoordinatorInitializationStep(BaseWorkflowBootstrapStep):
|
|
|
16
16
|
using the TeamManager. This ensures the coordinator is ready before the
|
|
17
17
|
workflow becomes idle.
|
|
18
18
|
"""
|
|
19
|
-
async def execute(self, context: 'WorkflowContext',
|
|
19
|
+
async def execute(self, context: 'WorkflowContext', status_manager: 'WorkflowStatusManager') -> bool:
|
|
20
20
|
workflow_id = context.workflow_id
|
|
21
21
|
logger.info(f"Workflow '{workflow_id}': Executing CoordinatorInitializationStep.")
|
|
22
22
|
|
|
@@ -9,7 +9,7 @@ from autobyteus.workflow.context.workflow_config import WorkflowConfig
|
|
|
9
9
|
|
|
10
10
|
if TYPE_CHECKING:
|
|
11
11
|
from autobyteus.workflow.context.workflow_context import WorkflowContext
|
|
12
|
-
from autobyteus.workflow.
|
|
12
|
+
from autobyteus.workflow.status.workflow_status_manager import WorkflowStatusManager
|
|
13
13
|
|
|
14
14
|
logger = logging.getLogger(__name__)
|
|
15
15
|
|
|
@@ -18,7 +18,7 @@ class CoordinatorPromptPreparationStep(BaseWorkflowBootstrapStep):
|
|
|
18
18
|
Bootstrap step to dynamically generate the coordinator's system prompt
|
|
19
19
|
based on the workflow's structure and store it in the workflow's state.
|
|
20
20
|
"""
|
|
21
|
-
async def execute(self, context: 'WorkflowContext',
|
|
21
|
+
async def execute(self, context: 'WorkflowContext', status_manager: 'WorkflowStatusManager') -> bool:
|
|
22
22
|
workflow_id = context.workflow_id
|
|
23
23
|
logger.info(f"Workflow '{workflow_id}': Executing CoordinatorPromptPreparationStep.")
|
|
24
24
|
try:
|
|
@@ -51,11 +51,7 @@ class CoordinatorPromptPreparationStep(BaseWorkflowBootstrapStep):
|
|
|
51
51
|
def _generate_prompt(self, context: 'WorkflowContext', member_node_ids: Dict[WorkflowNodeConfig, str]) -> str:
|
|
52
52
|
prompt_parts: List[str] = []
|
|
53
53
|
|
|
54
|
-
|
|
55
|
-
"### Your Tools\n"
|
|
56
|
-
"To accomplish your goal, you have access to the following tools. You should use them as needed.\n"
|
|
57
|
-
"{{tools}}"
|
|
58
|
-
)
|
|
54
|
+
|
|
59
55
|
|
|
60
56
|
if member_node_ids:
|
|
61
57
|
role_and_goal = (
|
|
@@ -89,7 +85,6 @@ class CoordinatorPromptPreparationStep(BaseWorkflowBootstrapStep):
|
|
|
89
85
|
rules_section = "### Execution Rules\n" + "\n".join(rules_list)
|
|
90
86
|
prompt_parts.append(rules_section)
|
|
91
87
|
|
|
92
|
-
prompt_parts.append(tools_section)
|
|
93
88
|
|
|
94
89
|
final_instruction = "### Your Task\nAnalyze the user's request, formulate a plan, and use the `send_message_to` tool to delegate tasks to your team. Address team members by their unique ID as listed under 'Your Team'."
|
|
95
90
|
prompt_parts.append(final_instruction)
|
|
@@ -100,7 +95,6 @@ class CoordinatorPromptPreparationStep(BaseWorkflowBootstrapStep):
|
|
|
100
95
|
)
|
|
101
96
|
prompt_parts.append(role_and_goal)
|
|
102
97
|
prompt_parts.append("### Your Team\nYou are working alone on this task.")
|
|
103
|
-
prompt_parts.append(tools_section)
|
|
104
98
|
final_instruction = "### Your Task\nAnalyze the user's request, formulate a plan, and use your available tools to achieve the goal."
|
|
105
99
|
prompt_parts.append(final_instruction)
|
|
106
100
|
|
|
@@ -11,7 +11,7 @@ from autobyteus.workflow.events.workflow_events import WorkflowReadyEvent
|
|
|
11
11
|
|
|
12
12
|
if TYPE_CHECKING:
|
|
13
13
|
from autobyteus.workflow.context.workflow_context import WorkflowContext
|
|
14
|
-
from autobyteus.workflow.
|
|
14
|
+
from autobyteus.workflow.status.workflow_status_manager import WorkflowStatusManager
|
|
15
15
|
|
|
16
16
|
logger = logging.getLogger(__name__)
|
|
17
17
|
|
|
@@ -25,18 +25,18 @@ class WorkflowBootstrapper:
|
|
|
25
25
|
CoordinatorInitializationStep(),
|
|
26
26
|
]
|
|
27
27
|
|
|
28
|
-
async def run(self, context: 'WorkflowContext',
|
|
28
|
+
async def run(self, context: 'WorkflowContext', status_manager: 'WorkflowStatusManager') -> bool:
|
|
29
29
|
workflow_id = context.workflow_id
|
|
30
|
-
await
|
|
30
|
+
await status_manager.notify_bootstrapping_started()
|
|
31
31
|
logger.info(f"Workflow '{workflow_id}': Bootstrapper starting.")
|
|
32
32
|
|
|
33
33
|
for step in self.bootstrap_steps:
|
|
34
34
|
step_name = step.__class__.__name__
|
|
35
35
|
logger.debug(f"Workflow '{workflow_id}': Executing bootstrap step: {step_name}")
|
|
36
|
-
if not await step.execute(context,
|
|
36
|
+
if not await step.execute(context, status_manager):
|
|
37
37
|
error_message = f"Bootstrap step {step_name} failed."
|
|
38
38
|
logger.error(f"Workflow '{workflow_id}': {error_message}")
|
|
39
|
-
await
|
|
39
|
+
await status_manager.notify_error_occurred(error_message, f"Failed during bootstrap step '{step_name}'.")
|
|
40
40
|
return False
|
|
41
41
|
|
|
42
42
|
logger.info(f"Workflow '{workflow_id}': All bootstrap steps completed successfully.")
|
|
@@ -44,7 +44,7 @@ class WorkflowBootstrapper:
|
|
|
44
44
|
await context.state.input_event_queues.enqueue_internal_system_event(WorkflowReadyEvent())
|
|
45
45
|
else:
|
|
46
46
|
logger.critical(f"Workflow '{workflow_id}': Bootstrap succeeded but queues not available.")
|
|
47
|
-
await
|
|
47
|
+
await status_manager.notify_error_occurred("Queues unavailable after bootstrap.", "")
|
|
48
48
|
return False
|
|
49
49
|
|
|
50
50
|
return True
|
|
@@ -7,13 +7,13 @@ from autobyteus.workflow.events.workflow_input_event_queue_manager import Workfl
|
|
|
7
7
|
|
|
8
8
|
if TYPE_CHECKING:
|
|
9
9
|
from autobyteus.workflow.context.workflow_context import WorkflowContext
|
|
10
|
-
from autobyteus.workflow.
|
|
10
|
+
from autobyteus.workflow.status.workflow_status_manager import WorkflowStatusManager
|
|
11
11
|
|
|
12
12
|
logger = logging.getLogger(__name__)
|
|
13
13
|
|
|
14
14
|
class WorkflowRuntimeQueueInitializationStep(BaseWorkflowBootstrapStep):
|
|
15
15
|
"""Bootstrap step for initializing the workflow's runtime event queues."""
|
|
16
|
-
async def execute(self, context: 'WorkflowContext',
|
|
16
|
+
async def execute(self, context: 'WorkflowContext', status_manager: 'WorkflowStatusManager') -> bool:
|
|
17
17
|
workflow_id = context.workflow_id
|
|
18
18
|
logger.info(f"Workflow '{workflow_id}': Executing WorkflowRuntimeQueueInitializationStep.")
|
|
19
19
|
try:
|
|
@@ -6,7 +6,7 @@ if TYPE_CHECKING:
|
|
|
6
6
|
from autobyteus.workflow.context.workflow_config import WorkflowConfig
|
|
7
7
|
from autobyteus.workflow.context.workflow_runtime_state import WorkflowRuntimeState
|
|
8
8
|
from autobyteus.agent.agent import Agent
|
|
9
|
-
from autobyteus.workflow.
|
|
9
|
+
from autobyteus.workflow.status.workflow_status_manager import WorkflowStatusManager
|
|
10
10
|
from autobyteus.workflow.context.team_manager import TeamManager
|
|
11
11
|
from autobyteus.workflow.streaming.agent_event_multiplexer import AgentEventMultiplexer
|
|
12
12
|
from autobyteus.agent.context import AgentConfig
|
|
@@ -49,8 +49,8 @@ class WorkflowContext:
|
|
|
49
49
|
return None
|
|
50
50
|
|
|
51
51
|
@property
|
|
52
|
-
def
|
|
53
|
-
return self.state.
|
|
52
|
+
def status_manager(self) -> Optional['WorkflowStatusManager']:
|
|
53
|
+
return self.state.status_manager_ref
|
|
54
54
|
|
|
55
55
|
@property
|
|
56
56
|
def team_manager(self) -> Optional['TeamManager']:
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
import logging
|
|
3
3
|
from typing import List, Optional, TYPE_CHECKING, Dict
|
|
4
4
|
|
|
5
|
-
from autobyteus.workflow.
|
|
5
|
+
from autobyteus.workflow.status.workflow_status import WorkflowStatus
|
|
6
6
|
from autobyteus.agent.context import AgentConfig
|
|
7
7
|
|
|
8
8
|
if TYPE_CHECKING:
|
|
9
9
|
from autobyteus.agent.agent import Agent
|
|
10
10
|
from autobyteus.workflow.events.workflow_input_event_queue_manager import WorkflowInputEventQueueManager
|
|
11
|
-
from autobyteus.workflow.
|
|
11
|
+
from autobyteus.workflow.status.workflow_status_manager import WorkflowStatusManager
|
|
12
12
|
from autobyteus.workflow.context.workflow_node_config import WorkflowNodeConfig
|
|
13
13
|
from autobyteus.workflow.context.team_manager import TeamManager
|
|
14
14
|
from autobyteus.workflow.streaming.agent_event_multiplexer import AgentEventMultiplexer
|
|
@@ -22,7 +22,7 @@ class WorkflowRuntimeState:
|
|
|
22
22
|
raise ValueError("WorkflowRuntimeState requires a non-empty string 'workflow_id'.")
|
|
23
23
|
|
|
24
24
|
self.workflow_id: str = workflow_id
|
|
25
|
-
self.
|
|
25
|
+
self.current_status: WorkflowStatus = WorkflowStatus.UNINITIALIZED
|
|
26
26
|
|
|
27
27
|
# State populated by bootstrap steps
|
|
28
28
|
self.prepared_coordinator_prompt: Optional[str] = None
|
|
@@ -34,7 +34,7 @@ class WorkflowRuntimeState:
|
|
|
34
34
|
|
|
35
35
|
# Runtime components and references
|
|
36
36
|
self.input_event_queues: Optional['WorkflowInputEventQueueManager'] = None
|
|
37
|
-
self.
|
|
37
|
+
self.status_manager_ref: Optional['WorkflowStatusManager'] = None
|
|
38
38
|
self.multiplexer_ref: Optional['AgentEventMultiplexer'] = None
|
|
39
39
|
|
|
40
40
|
logger.info(f"WorkflowRuntimeState initialized for workflow_id '{self.workflow_id}'.")
|
|
@@ -48,6 +48,6 @@ class WorkflowRuntimeState:
|
|
|
48
48
|
def __repr__(self) -> str:
|
|
49
49
|
agents_count = len(self.team_manager.get_all_agents()) if self.team_manager else 0
|
|
50
50
|
coordinator_set = self.team_manager.coordinator_agent is not None if self.team_manager else False
|
|
51
|
-
return (f"<WorkflowRuntimeState id='{self.workflow_id}',
|
|
51
|
+
return (f"<WorkflowRuntimeState id='{self.workflow_id}', status='{self.current_status.value}', "
|
|
52
52
|
f"agents_count={agents_count}, coordinator_set={coordinator_set}, "
|
|
53
53
|
f"team_manager_set={self.team_manager is not None}>")
|
|
@@ -8,7 +8,7 @@ from autobyteus.workflow.events.workflow_events import BaseWorkflowEvent, Workfl
|
|
|
8
8
|
if TYPE_CHECKING:
|
|
9
9
|
from autobyteus.workflow.context.workflow_context import WorkflowContext
|
|
10
10
|
from autobyteus.workflow.handlers.workflow_event_handler_registry import WorkflowEventHandlerRegistry
|
|
11
|
-
from autobyteus.workflow.
|
|
11
|
+
from autobyteus.workflow.status.workflow_status_manager import WorkflowStatusManager
|
|
12
12
|
|
|
13
13
|
logger = logging.getLogger(__name__)
|
|
14
14
|
|
|
@@ -17,9 +17,9 @@ class WorkflowEventDispatcher:
|
|
|
17
17
|
|
|
18
18
|
def __init__(self,
|
|
19
19
|
event_handler_registry: 'WorkflowEventHandlerRegistry',
|
|
20
|
-
|
|
20
|
+
status_manager: 'WorkflowStatusManager'):
|
|
21
21
|
self.registry = event_handler_registry
|
|
22
|
-
self.
|
|
22
|
+
self.status_manager = status_manager
|
|
23
23
|
|
|
24
24
|
async def dispatch(self, event: BaseWorkflowEvent, context: 'WorkflowContext'):
|
|
25
25
|
handler = self.registry.get_handler(type(event))
|
|
@@ -32,8 +32,8 @@ class WorkflowEventDispatcher:
|
|
|
32
32
|
try:
|
|
33
33
|
await handler.handle(event, context)
|
|
34
34
|
if isinstance(event, WorkflowReadyEvent):
|
|
35
|
-
await self.
|
|
35
|
+
await self.status_manager.notify_initialization_complete()
|
|
36
36
|
except Exception as e:
|
|
37
37
|
error_msg = f"Error handling '{type(event).__name__}' in workflow '{workflow_id}': {e}"
|
|
38
38
|
logger.error(error_msg, exc_info=True)
|
|
39
|
-
await self.
|
|
39
|
+
await self.status_manager.notify_error_occurred(error_msg, traceback.format_exc())
|
|
@@ -14,14 +14,14 @@ class LifecycleWorkflowEventHandler(BaseWorkflowEventHandler):
|
|
|
14
14
|
"""Logs various lifecycle events for a workflow."""
|
|
15
15
|
async def handle(self, event: BaseWorkflowEvent, context: 'WorkflowContext') -> None:
|
|
16
16
|
workflow_id = context.workflow_id
|
|
17
|
-
|
|
17
|
+
current_status = context.state.current_status.value
|
|
18
18
|
|
|
19
19
|
if isinstance(event, WorkflowReadyEvent):
|
|
20
|
-
logger.info(f"Workflow '{workflow_id}' Logged WorkflowReadyEvent. Current
|
|
20
|
+
logger.info(f"Workflow '{workflow_id}' Logged WorkflowReadyEvent. Current status: {current_status}")
|
|
21
21
|
elif isinstance(event, WorkflowErrorEvent):
|
|
22
22
|
logger.error(
|
|
23
23
|
f"Workflow '{workflow_id}' Logged WorkflowErrorEvent: {event.error_message}. "
|
|
24
|
-
f"Details: {event.exception_details}. Current
|
|
24
|
+
f"Details: {event.exception_details}. Current status: {current_status}"
|
|
25
25
|
)
|
|
26
26
|
else:
|
|
27
27
|
logger.warning(f"LifecycleWorkflowEventHandler received unhandled event type: {type(event).__name__}")
|
|
@@ -15,13 +15,13 @@ logger = logging.getLogger(__name__)
|
|
|
15
15
|
class ProcessUserMessageEventHandler(BaseWorkflowEventHandler):
|
|
16
16
|
"""Handles user messages by routing them to the specified target agent or sub-workflow."""
|
|
17
17
|
async def handle(self, event: ProcessUserMessageEvent, context: 'WorkflowContext') -> None:
|
|
18
|
-
await context.
|
|
18
|
+
await context.status_manager.notify_processing_started()
|
|
19
19
|
|
|
20
20
|
team_manager = context.team_manager
|
|
21
21
|
if not team_manager:
|
|
22
22
|
msg = f"Workflow '{context.workflow_id}': TeamManager not found. Cannot route message."
|
|
23
23
|
logger.error(msg)
|
|
24
|
-
await context.
|
|
24
|
+
await context.status_manager.notify_error_occurred(msg, "TeamManager is not initialized.")
|
|
25
25
|
return
|
|
26
26
|
|
|
27
27
|
try:
|
|
@@ -29,7 +29,7 @@ class ProcessUserMessageEventHandler(BaseWorkflowEventHandler):
|
|
|
29
29
|
except Exception as e:
|
|
30
30
|
msg = f"Workflow '{context.workflow_id}': Node '{event.target_agent_name}' not found or failed to start. Cannot route message. Error: {e}"
|
|
31
31
|
logger.error(msg, exc_info=True)
|
|
32
|
-
await context.
|
|
32
|
+
await context.status_manager.notify_error_occurred(msg, f"Node '{event.target_agent_name}' not found or failed to start.")
|
|
33
33
|
return
|
|
34
34
|
|
|
35
35
|
if isinstance(target_node, Agent):
|
|
@@ -41,6 +41,6 @@ class ProcessUserMessageEventHandler(BaseWorkflowEventHandler):
|
|
|
41
41
|
else:
|
|
42
42
|
msg = f"Target node '{event.target_agent_name}' is of an unsupported type: {type(target_node).__name__}"
|
|
43
43
|
logger.error(f"Workflow '{context.workflow_id}': {msg}")
|
|
44
|
-
await context.
|
|
44
|
+
await context.status_manager.notify_error_occurred(msg, "")
|
|
45
45
|
|
|
46
|
-
await context.
|
|
46
|
+
await context.status_manager.notify_processing_complete_and_idle()
|
|
@@ -21,14 +21,14 @@ class ToolApprovalWorkflowEventHandler(BaseWorkflowEventHandler):
|
|
|
21
21
|
if not team_manager:
|
|
22
22
|
msg = f"Workflow '{workflow_id}': TeamManager not found. Cannot route approval for agent '{event.agent_name}'."
|
|
23
23
|
logger.error(msg)
|
|
24
|
-
await context.
|
|
24
|
+
await context.status_manager.notify_error_occurred(msg, "TeamManager is not initialized.")
|
|
25
25
|
return
|
|
26
26
|
|
|
27
27
|
target_agent = await team_manager.ensure_agent_is_ready(event.agent_name)
|
|
28
28
|
if not target_agent:
|
|
29
29
|
msg = f"Workflow '{workflow_id}': Target agent '{event.agent_name}' for approval not found or failed to start."
|
|
30
30
|
logger.error(msg)
|
|
31
|
-
await context.
|
|
31
|
+
await context.status_manager.notify_error_occurred(msg, f"Agent '{event.agent_name}' not found or failed to start.")
|
|
32
32
|
return
|
|
33
33
|
|
|
34
34
|
logger.info(f"Workflow '{workflow_id}': Posting tool approval (Approved: {event.is_approved}) to agent '{event.agent_name}' for invocation '{event.tool_invocation_id}'.")
|
|
@@ -4,7 +4,7 @@ import logging
|
|
|
4
4
|
from typing import TYPE_CHECKING, Callable, Optional
|
|
5
5
|
|
|
6
6
|
from autobyteus.workflow.context.workflow_context import WorkflowContext
|
|
7
|
-
from autobyteus.workflow.
|
|
7
|
+
from autobyteus.workflow.status.workflow_status_manager import WorkflowStatusManager
|
|
8
8
|
from autobyteus.workflow.runtime.workflow_worker import WorkflowWorker
|
|
9
9
|
from autobyteus.workflow.events.workflow_events import BaseWorkflowEvent
|
|
10
10
|
from autobyteus.workflow.streaming.workflow_event_notifier import WorkflowExternalEventNotifier
|
|
@@ -20,10 +20,10 @@ class WorkflowRuntime:
|
|
|
20
20
|
def __init__(self, context: WorkflowContext, event_handler_registry: 'WorkflowEventHandlerRegistry'):
|
|
21
21
|
self.context = context
|
|
22
22
|
self.notifier = WorkflowExternalEventNotifier(workflow_id=self.context.workflow_id, runtime_ref=self)
|
|
23
|
-
self.
|
|
23
|
+
self.status_manager = WorkflowStatusManager(context=self.context, notifier=self.notifier)
|
|
24
24
|
|
|
25
|
-
# --- FIX: Set the
|
|
26
|
-
self.context.state.
|
|
25
|
+
# --- FIX: Set the status_manager_ref on the context's state BEFORE creating the worker ---
|
|
26
|
+
self.context.state.status_manager_ref = self.status_manager
|
|
27
27
|
|
|
28
28
|
self._worker = WorkflowWorker(self.context, event_handler_registry)
|
|
29
29
|
|
|
@@ -50,8 +50,8 @@ class WorkflowRuntime:
|
|
|
50
50
|
logger.info(f"WorkflowRuntime '{workflow_id}': Worker thread completed.")
|
|
51
51
|
except Exception as e:
|
|
52
52
|
logger.error(f"WorkflowRuntime '{workflow_id}': Worker thread terminated with exception: {e}", exc_info=True)
|
|
53
|
-
if not self.context.state.
|
|
54
|
-
asyncio.run(self.
|
|
53
|
+
if not self.context.state.current_status.is_terminal():
|
|
54
|
+
asyncio.run(self.status_manager.notify_final_shutdown_complete())
|
|
55
55
|
|
|
56
56
|
def start(self):
|
|
57
57
|
if self._worker.is_alive:
|
|
@@ -59,9 +59,9 @@ class WorkflowRuntime:
|
|
|
59
59
|
self._worker.start()
|
|
60
60
|
|
|
61
61
|
async def stop(self, timeout: float = 10.0):
|
|
62
|
-
await self.
|
|
62
|
+
await self.status_manager.notify_shutdown_initiated()
|
|
63
63
|
await self._worker.stop(timeout=timeout)
|
|
64
|
-
await self.
|
|
64
|
+
await self.status_manager.notify_final_shutdown_complete()
|
|
65
65
|
|
|
66
66
|
async def submit_event(self, event: BaseWorkflowEvent):
|
|
67
67
|
if not self._worker.is_alive:
|
|
@@ -19,8 +19,8 @@ class WorkflowWorker:
|
|
|
19
19
|
"""Encapsulates the core event processing loop for a workflow."""
|
|
20
20
|
def __init__(self, context: 'WorkflowContext', event_handler_registry: 'WorkflowEventHandlerRegistry'):
|
|
21
21
|
self.context = context
|
|
22
|
-
self.
|
|
23
|
-
self.event_dispatcher = WorkflowEventDispatcher(event_handler_registry, self.
|
|
22
|
+
self.status_manager = self.context.status_manager
|
|
23
|
+
self.event_dispatcher = WorkflowEventDispatcher(event_handler_registry, self.status_manager)
|
|
24
24
|
|
|
25
25
|
self._thread_pool_manager = AgentThreadPoolManager()
|
|
26
26
|
self._thread_future: Optional[concurrent.futures.Future] = None
|
|
@@ -70,7 +70,7 @@ class WorkflowWorker:
|
|
|
70
70
|
|
|
71
71
|
async def async_run(self):
|
|
72
72
|
bootstrapper = WorkflowBootstrapper()
|
|
73
|
-
if not await bootstrapper.run(self.context, self.
|
|
73
|
+
if not await bootstrapper.run(self.context, self.status_manager):
|
|
74
74
|
logger.critical(f"Workflow '{self.context.workflow_id}' failed to initialize. Shutting down.")
|
|
75
75
|
return
|
|
76
76
|
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# file: autobyteus/autobyteus/workflow/status/__init__.py
|
|
2
|
+
"""
|
|
3
|
+
This package contains components for defining and managing workflow operational statuses.
|
|
4
|
+
"""
|
|
5
|
+
from autobyteus.workflow.status.workflow_status import WorkflowStatus
|
|
6
|
+
from autobyteus.workflow.status.workflow_status_manager import WorkflowStatusManager
|
|
7
|
+
|
|
8
|
+
__all__ = [
|
|
9
|
+
"WorkflowStatus",
|
|
10
|
+
"WorkflowStatusManager",
|
|
11
|
+
]
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# file: autobyteus/autobyteus/workflow/status/workflow_status.py
|
|
2
|
+
from enum import Enum
|
|
3
|
+
|
|
4
|
+
class WorkflowStatus(str, Enum):
|
|
5
|
+
"""Defines the operational status of an AgenticWorkflow."""
|
|
6
|
+
UNINITIALIZED = "uninitialized"
|
|
7
|
+
BOOTSTRAPPING = "bootstrapping"
|
|
8
|
+
IDLE = "idle"
|
|
9
|
+
PROCESSING = "processing"
|
|
10
|
+
SHUTTING_DOWN = "shutting_down"
|
|
11
|
+
SHUTDOWN_COMPLETE = "shutdown_complete"
|
|
12
|
+
ERROR = "error"
|
|
13
|
+
|
|
14
|
+
def is_terminal(self) -> bool:
|
|
15
|
+
"""Checks if the status is a terminal state."""
|
|
16
|
+
return self in [WorkflowStatus.SHUTDOWN_COMPLETE, WorkflowStatus.ERROR]
|
|
17
|
+
|
|
18
|
+
def __str__(self) -> str:
|
|
19
|
+
return self.value
|