autobyteus 1.2.0__py3-none-any.whl → 1.2.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- autobyteus/agent/agent.py +15 -5
- autobyteus/agent/bootstrap_steps/__init__.py +1 -3
- autobyteus/agent/bootstrap_steps/agent_bootstrapper.py +3 -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/workspace_context_initialization_step.py +2 -4
- autobyteus/agent/context/agent_config.py +43 -20
- autobyteus/agent/context/agent_context.py +23 -18
- autobyteus/agent/context/agent_runtime_state.py +23 -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 +74 -60
- autobyteus/agent/events/worker_event_dispatcher.py +21 -64
- autobyteus/agent/factory/agent_factory.py +52 -0
- 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 +40 -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/message/send_message_to.py +5 -4
- 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 -178
- 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 +81 -0
- autobyteus/agent/streaming/stream_event_payloads.py +2 -198
- autobyteus/agent/streaming/stream_events.py +3 -128
- 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 +5 -6
- autobyteus/agent_team/bootstrap_steps/team_context_initialization_step.py +15 -15
- 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 +11 -8
- 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 +10 -10
- autobyteus/agent_team/streaming/agent_team_stream_event_payloads.py +7 -7
- autobyteus/agent_team/streaming/agent_team_stream_events.py +11 -11
- 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/activation_policy.py +1 -1
- autobyteus/agent_team/task_notification/system_event_driven_agent_task_notifier.py +22 -22
- autobyteus/agent_team/task_notification/task_notification_mode.py +20 -1
- autobyteus/agent_team/utils/wait_for_idle.py +4 -4
- autobyteus/cli/agent_cli.py +18 -10
- autobyteus/cli/agent_team_tui/app.py +18 -15
- autobyteus/cli/agent_team_tui/state.py +21 -23
- autobyteus/cli/agent_team_tui/widgets/agent_list_sidebar.py +15 -15
- autobyteus/cli/agent_team_tui/widgets/focus_pane.py +146 -39
- autobyteus/cli/agent_team_tui/widgets/renderables.py +1 -1
- autobyteus/cli/agent_team_tui/widgets/shared.py +26 -26
- autobyteus/cli/agent_team_tui/widgets/{task_board_panel.py → task_plan_panel.py} +5 -5
- 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 +15 -21
- 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 +32 -0
- autobyteus/memory/active_transcript.py +69 -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 +183 -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/policies/__init__.py +5 -0
- autobyteus/memory/policies/compaction_policy.py +16 -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 +7 -0
- autobyteus/memory/store/base_store.py +14 -0
- autobyteus/memory/store/file_store.py +98 -0
- autobyteus/memory/tool_interaction_builder.py +46 -0
- autobyteus/memory/turn_tracker.py +9 -0
- autobyteus/multimedia/audio/api/__init__.py +3 -2
- autobyteus/multimedia/audio/api/autobyteus_audio_client.py +19 -5
- autobyteus/multimedia/audio/api/gemini_audio_client.py +108 -16
- autobyteus/multimedia/audio/api/openai_audio_client.py +112 -0
- autobyteus/multimedia/audio/audio_client_factory.py +84 -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 +38 -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/__init__.py +43 -20
- autobyteus/task_management/{base_task_board.py → base_task_plan.py} +16 -13
- autobyteus/task_management/converters/__init__.py +2 -2
- autobyteus/task_management/converters/{task_board_converter.py → task_plan_converter.py} +13 -13
- autobyteus/task_management/events.py +7 -7
- autobyteus/task_management/{in_memory_task_board.py → in_memory_task_plan.py} +34 -22
- autobyteus/task_management/schemas/__init__.py +3 -0
- autobyteus/task_management/schemas/task_status_report.py +2 -2
- autobyteus/task_management/schemas/todo_definition.py +15 -0
- autobyteus/task_management/todo.py +29 -0
- autobyteus/task_management/todo_list.py +75 -0
- autobyteus/task_management/tools/__init__.py +24 -8
- autobyteus/task_management/tools/task_tools/__init__.py +19 -0
- autobyteus/task_management/tools/{assign_task_to.py → task_tools/assign_task_to.py} +18 -18
- autobyteus/task_management/tools/{publish_task.py → task_tools/create_task.py} +16 -18
- autobyteus/task_management/tools/{publish_tasks.py → task_tools/create_tasks.py} +19 -19
- autobyteus/task_management/tools/{get_my_tasks.py → task_tools/get_my_tasks.py} +15 -15
- autobyteus/task_management/tools/{get_task_board_status.py → task_tools/get_task_plan_status.py} +16 -16
- autobyteus/task_management/tools/{update_task_status.py → task_tools/update_task_status.py} +16 -16
- autobyteus/task_management/tools/todo_tools/__init__.py +18 -0
- autobyteus/task_management/tools/todo_tools/add_todo.py +78 -0
- autobyteus/task_management/tools/todo_tools/create_todo_list.py +79 -0
- autobyteus/task_management/tools/todo_tools/get_todo_list.py +55 -0
- autobyteus/task_management/tools/todo_tools/update_todo_status.py +85 -0
- autobyteus/tools/__init__.py +43 -52
- autobyteus/tools/base_tool.py +7 -0
- autobyteus/tools/file/__init__.py +9 -0
- autobyteus/tools/file/patch_file.py +149 -0
- autobyteus/tools/file/{file_reader.py → read_file.py} +38 -7
- autobyteus/tools/file/{file_writer.py → write_file.py} +7 -4
- autobyteus/tools/functional_tool.py +53 -14
- 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/tool.py +3 -3
- autobyteus/tools/mcp/tool_registrar.py +5 -2
- autobyteus/tools/mcp/types.py +61 -0
- autobyteus/tools/multimedia/__init__.py +2 -1
- autobyteus/tools/multimedia/audio_tools.py +72 -19
- autobyteus/tools/{download_media_tool.py → multimedia/download_media_tool.py} +21 -7
- autobyteus/tools/multimedia/image_tools.py +248 -64
- autobyteus/tools/multimedia/media_reader_tool.py +1 -1
- 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 +108 -14
- autobyteus/tools/registry/tool_registry.py +29 -0
- autobyteus/tools/search/__init__.py +17 -0
- autobyteus/tools/search/base_strategy.py +35 -0
- autobyteus/tools/search/client.py +24 -0
- autobyteus/tools/search/factory.py +81 -0
- autobyteus/tools/search/google_cse_strategy.py +68 -0
- autobyteus/tools/search/providers.py +10 -0
- autobyteus/tools/search/serpapi_strategy.py +65 -0
- autobyteus/tools/search/serper_strategy.py +87 -0
- autobyteus/tools/search_tool.py +83 -0
- 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/tool_meta.py +4 -24
- 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 +56 -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 +4 -11
- 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.2.3.dist-info/METADATA +293 -0
- autobyteus-1.2.3.dist-info/RECORD +600 -0
- {autobyteus-1.2.0.dist-info → autobyteus-1.2.3.dist-info}/WHEEL +1 -1
- {autobyteus-1.2.0.dist-info → autobyteus-1.2.3.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/person/examples/sample_persons.py +0 -14
- autobyteus/person/examples/sample_roles.py +0 -14
- autobyteus/person/person.py +0 -29
- autobyteus/person/role.py +0 -14
- 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/__init__.py +0 -0
- 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/__init__.py +0 -0
- 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 -80
- autobyteus/tools/browser/standalone/web_page_pdf_generator.py +0 -97
- autobyteus/tools/browser/standalone/webpage_image_downloader.py +0 -165
- autobyteus/tools/browser/standalone/webpage_reader.py +0 -101
- autobyteus/tools/browser/standalone/webpage_screenshot_taker.py +0 -101
- autobyteus/tools/file/file_editor.py +0 -200
- autobyteus/tools/google_search.py +0 -149
- autobyteus/tools/timer.py +0 -171
- 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.0.dist-info/METADATA +0 -205
- autobyteus-1.2.0.dist-info/RECORD +0 -496
- examples/__init__.py +0 -1
- examples/agent_team/__init__.py +0 -1
- examples/discover_phase_transitions.py +0 -104
- 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/{person → skills}/__init__.py +0 -0
- /autobyteus/{person/examples → tools/skill}/__init__.py +0 -0
- {autobyteus-1.2.0.dist-info → autobyteus-1.2.3.dist-info}/licenses/LICENSE +0 -0
autobyteus/utils/file_utils.py
CHANGED
|
@@ -2,8 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
import os
|
|
4
4
|
import platform
|
|
5
|
+
import tempfile
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from typing import Union
|
|
5
8
|
|
|
6
|
-
def get_default_download_folder():
|
|
9
|
+
def get_default_download_folder() -> str:
|
|
7
10
|
system = platform.system()
|
|
8
11
|
if system == "Windows":
|
|
9
12
|
return os.path.join(os.path.expanduser("~"), "Downloads")
|
|
@@ -12,4 +15,56 @@ def get_default_download_folder():
|
|
|
12
15
|
elif system == "Linux":
|
|
13
16
|
return os.path.join(os.path.expanduser("~"), "Downloads")
|
|
14
17
|
else:
|
|
15
|
-
return os.path.join(os.path.expanduser("~"), "Downloads") # Fallback
|
|
18
|
+
return os.path.join(os.path.expanduser("~"), "Downloads") # Fallback
|
|
19
|
+
|
|
20
|
+
def resolve_safe_path(user_path: str, workspace_root: Union[str, Path]) -> Path:
|
|
21
|
+
"""
|
|
22
|
+
Resolves a file path and ensures it is contained within allowed safe directories.
|
|
23
|
+
|
|
24
|
+
Allowed directories:
|
|
25
|
+
1. The Agent's Workspace (workspace_root)
|
|
26
|
+
2. The User's Downloads directory
|
|
27
|
+
3. The System Temporary directory
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
user_path: The relative or absolute path provided by the user/tool.
|
|
31
|
+
workspace_root: The root directory of the agent's workspace.
|
|
32
|
+
|
|
33
|
+
Returns:
|
|
34
|
+
The resolved absolute Path object.
|
|
35
|
+
|
|
36
|
+
Raises:
|
|
37
|
+
ValueError: If the path is outside the allowed directories.
|
|
38
|
+
"""
|
|
39
|
+
workspace = Path(workspace_root).resolve()
|
|
40
|
+
downloads = Path(get_default_download_folder()).resolve()
|
|
41
|
+
temp_dir = Path(tempfile.gettempdir()).resolve()
|
|
42
|
+
|
|
43
|
+
path_obj = Path(user_path)
|
|
44
|
+
|
|
45
|
+
# If absolute, check directly. If relative, resolve against workspace.
|
|
46
|
+
if path_obj.is_absolute():
|
|
47
|
+
target = path_obj.resolve()
|
|
48
|
+
else:
|
|
49
|
+
target = (workspace / path_obj).resolve()
|
|
50
|
+
|
|
51
|
+
# Allowed roots list
|
|
52
|
+
allowed_roots = [workspace, downloads, temp_dir]
|
|
53
|
+
|
|
54
|
+
is_safe = False
|
|
55
|
+
for root in allowed_roots:
|
|
56
|
+
# Check if target is equal to or a subpath of root
|
|
57
|
+
try:
|
|
58
|
+
target.relative_to(root)
|
|
59
|
+
is_safe = True
|
|
60
|
+
break
|
|
61
|
+
except ValueError:
|
|
62
|
+
continue
|
|
63
|
+
|
|
64
|
+
if not is_safe:
|
|
65
|
+
raise ValueError(
|
|
66
|
+
f"Security Violation: Path '{user_path}' is not within allowed directories "
|
|
67
|
+
f"(Workspace: {workspace}, Downloads: {downloads}, or Temp: {temp_dir})."
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
return target
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import logging
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from google import genai
|
|
5
|
+
|
|
6
|
+
logger = logging.getLogger(__name__)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@dataclass(frozen=True)
|
|
10
|
+
class GeminiRuntimeInfo:
|
|
11
|
+
runtime: str # "vertex" or "api_key"
|
|
12
|
+
project: str | None
|
|
13
|
+
location: str | None
|
|
14
|
+
|
|
15
|
+
def initialize_gemini_client_with_runtime() -> tuple[genai.Client, GeminiRuntimeInfo]:
|
|
16
|
+
"""
|
|
17
|
+
Initializes the Google GenAI Client based on available environment variables.
|
|
18
|
+
Supports both Vertex AI (GCP) and AI Studio (API Key) modes.
|
|
19
|
+
|
|
20
|
+
Priority:
|
|
21
|
+
1. Vertex AI (requires VERTEX_AI_PROJECT and VERTEX_AI_LOCATION)
|
|
22
|
+
2. AI Studio (requires GEMINI_API_KEY)
|
|
23
|
+
|
|
24
|
+
Returns:
|
|
25
|
+
(client, runtime_info)
|
|
26
|
+
|
|
27
|
+
Raises:
|
|
28
|
+
ValueError: If neither configuration set is found.
|
|
29
|
+
"""
|
|
30
|
+
# 1. Try Vertex AI Configuration
|
|
31
|
+
project = os.environ.get("VERTEX_AI_PROJECT")
|
|
32
|
+
location = os.environ.get("VERTEX_AI_LOCATION")
|
|
33
|
+
|
|
34
|
+
if project and location:
|
|
35
|
+
logger.info(
|
|
36
|
+
f"Initializing Gemini Client in Vertex AI mode (Project: {project}, Location: {location})"
|
|
37
|
+
)
|
|
38
|
+
client = genai.Client(vertexai=True, project=project, location=location)
|
|
39
|
+
return client, GeminiRuntimeInfo(runtime="vertex", project=project, location=location)
|
|
40
|
+
|
|
41
|
+
# 2. Try AI Studio Configuration (API Key)
|
|
42
|
+
api_key = os.environ.get("GEMINI_API_KEY")
|
|
43
|
+
if api_key:
|
|
44
|
+
logger.info("Initializing Gemini Client in AI Studio mode.")
|
|
45
|
+
client = genai.Client(api_key=api_key)
|
|
46
|
+
return client, GeminiRuntimeInfo(runtime="api_key", project=None, location=None)
|
|
47
|
+
|
|
48
|
+
# 3. Fallback / Error
|
|
49
|
+
error_msg = (
|
|
50
|
+
"Failed to initialize Gemini Client: Missing configuration. "
|
|
51
|
+
"Please set 'GEMINI_API_KEY' for AI Studio mode, OR set both "
|
|
52
|
+
"'VERTEX_AI_PROJECT' and 'VERTEX_AI_LOCATION' for Vertex AI mode."
|
|
53
|
+
)
|
|
54
|
+
logger.error(error_msg)
|
|
55
|
+
raise ValueError(error_msg)
|
|
56
|
+
|
|
@@ -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,9 +85,8 @@ 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
|
-
final_instruction = "### Your Task\nAnalyze the user's request, formulate a plan, and use the `
|
|
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)
|
|
96
91
|
else:
|
|
97
92
|
role_and_goal = (
|
|
@@ -100,9 +95,7 @@ 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
|
|
|
107
101
|
return "\n\n".join(prompt_parts)
|
|
108
|
-
|
|
@@ -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()
|