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
|
@@ -7,18 +7,18 @@ import copy
|
|
|
7
7
|
|
|
8
8
|
from autobyteus.agent.context import AgentConfig
|
|
9
9
|
from autobyteus.agent_team.agent_team import AgentTeam
|
|
10
|
-
from autobyteus.agent.
|
|
11
|
-
from autobyteus.agent_team.
|
|
10
|
+
from autobyteus.agent.status.status_enum import AgentStatus
|
|
11
|
+
from autobyteus.agent_team.status.agent_team_status import AgentTeamStatus
|
|
12
12
|
from autobyteus.agent.streaming.stream_events import StreamEvent as AgentStreamEvent, StreamEventType as AgentStreamEventType
|
|
13
13
|
from autobyteus.agent.streaming.stream_event_payloads import (
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
AgentStatusUpdateData, ToolInvocationApprovalRequestedData,
|
|
15
|
+
AssistantCompleteResponseData
|
|
16
16
|
)
|
|
17
17
|
from autobyteus.agent_team.streaming.agent_team_stream_events import AgentTeamStreamEvent
|
|
18
|
-
from autobyteus.agent_team.streaming.agent_team_stream_event_payloads import AgentEventRebroadcastPayload, SubTeamEventRebroadcastPayload,
|
|
18
|
+
from autobyteus.agent_team.streaming.agent_team_stream_event_payloads import AgentEventRebroadcastPayload, SubTeamEventRebroadcastPayload, AgentTeamStatusUpdateData
|
|
19
19
|
from autobyteus.task_management.task import Task
|
|
20
|
-
from autobyteus.task_management.events import
|
|
21
|
-
from autobyteus.task_management.
|
|
20
|
+
from autobyteus.task_management.events import TasksCreatedEvent, TaskStatusUpdatedEvent
|
|
21
|
+
from autobyteus.task_management.base_task_plan import TaskStatus
|
|
22
22
|
|
|
23
23
|
logger = logging.getLogger(__name__)
|
|
24
24
|
|
|
@@ -39,14 +39,14 @@ class TUIStateStore:
|
|
|
39
39
|
|
|
40
40
|
self._node_roles: Dict[str, str] = self._extract_node_roles(team)
|
|
41
41
|
self._nodes: Dict[str, Any] = self._initialize_root_node()
|
|
42
|
-
self.
|
|
43
|
-
self.
|
|
42
|
+
self._agent_statuses: Dict[str, AgentStatus] = {}
|
|
43
|
+
self._team_statuses: Dict[str, AgentTeamStatus] = {self.team_name: AgentTeamStatus.UNINITIALIZED}
|
|
44
44
|
self._agent_event_history: Dict[str, List[AgentStreamEvent]] = {}
|
|
45
45
|
self._team_event_history: Dict[str, List[AgentTeamStreamEvent]] = {self.team_name: []}
|
|
46
46
|
self._pending_approvals: Dict[str, ToolInvocationApprovalRequestedData] = {}
|
|
47
47
|
self._speaking_agents: Dict[str, bool] = {}
|
|
48
48
|
|
|
49
|
-
# State for task
|
|
49
|
+
# State for task plans
|
|
50
50
|
self._task_plans: Dict[str, List[Task]] = {} # team_name -> List[Task]
|
|
51
51
|
self._task_statuses: Dict[str, Dict[str, TaskStatus]] = {} # team_name -> {task_id: status}
|
|
52
52
|
|
|
@@ -75,8 +75,8 @@ class TUIStateStore:
|
|
|
75
75
|
def process_event(self, event: AgentTeamStreamEvent):
|
|
76
76
|
self.version += 1 # Increment on any event to signal a change
|
|
77
77
|
|
|
78
|
-
if event.event_source_type == "TEAM" and isinstance(event.data,
|
|
79
|
-
self.
|
|
78
|
+
if event.event_source_type == "TEAM" and isinstance(event.data, AgentTeamStatusUpdateData):
|
|
79
|
+
self._team_statuses[self.team_name] = event.data.new_status
|
|
80
80
|
|
|
81
81
|
self._process_event_recursively(event, self.team_name)
|
|
82
82
|
|
|
@@ -85,15 +85,15 @@ class TUIStateStore:
|
|
|
85
85
|
self._team_event_history[parent_name] = []
|
|
86
86
|
self._team_event_history[parent_name].append(event)
|
|
87
87
|
|
|
88
|
-
if event.event_source_type == "
|
|
88
|
+
if event.event_source_type == "TASK_PLAN":
|
|
89
89
|
team_name_key = parent_name
|
|
90
|
-
if isinstance(event.data,
|
|
90
|
+
if isinstance(event.data, TasksCreatedEvent):
|
|
91
91
|
if team_name_key not in self._task_plans: self._task_plans[team_name_key] = []
|
|
92
92
|
if team_name_key not in self._task_statuses: self._task_statuses[team_name_key] = {}
|
|
93
93
|
self._task_plans[team_name_key].extend(event.data.tasks)
|
|
94
94
|
for task in event.data.tasks:
|
|
95
95
|
self._task_statuses[team_name_key][task.task_id] = TaskStatus.NOT_STARTED
|
|
96
|
-
logger.debug(f"TUI State:
|
|
96
|
+
logger.debug(f"TUI State: Created {len(event.data.tasks)} tasks in plan for '{team_name_key}'.")
|
|
97
97
|
|
|
98
98
|
elif isinstance(event.data, TaskStatusUpdatedEvent):
|
|
99
99
|
if team_name_key not in self._task_statuses: self._task_statuses[team_name_key] = {}
|
|
@@ -121,11 +121,9 @@ class TUIStateStore:
|
|
|
121
121
|
else: logger.error(f"Cannot add agent node '{agent_name}': parent '{parent_name}' not found.")
|
|
122
122
|
self._agent_event_history[agent_name].append(agent_event)
|
|
123
123
|
|
|
124
|
-
if agent_event.event_type == AgentStreamEventType.
|
|
125
|
-
self.
|
|
124
|
+
if agent_event.event_type == AgentStreamEventType.AGENT_STATUS_UPDATED:
|
|
125
|
+
self._agent_statuses[agent_name] = agent_event.data.new_status
|
|
126
126
|
if agent_name in self._pending_approvals: del self._pending_approvals[agent_name]
|
|
127
|
-
elif agent_event.event_type == AgentStreamEventType.AGENT_IDLE:
|
|
128
|
-
self._agent_phases[agent_name] = AgentOperationalPhase.IDLE
|
|
129
127
|
elif agent_event.event_type == AgentStreamEventType.TOOL_INVOCATION_APPROVAL_REQUESTED:
|
|
130
128
|
self._pending_approvals[agent_name] = agent_event.data
|
|
131
129
|
|
|
@@ -136,8 +134,8 @@ class TUIStateStore:
|
|
|
136
134
|
if not self._find_node(sub_team_name):
|
|
137
135
|
role = self._node_roles.get(sub_team_name, "Sub-Team")
|
|
138
136
|
self._add_node(sub_team_name, {"type": "subteam", "name": sub_team_name, "role": role, "children": {}}, parent_name)
|
|
139
|
-
if sub_team_event.event_source_type == "TEAM" and isinstance(sub_team_event.data,
|
|
140
|
-
self.
|
|
137
|
+
if sub_team_event.event_source_type == "TEAM" and isinstance(sub_team_event.data, AgentTeamStatusUpdateData):
|
|
138
|
+
self._team_statuses[sub_team_name] = sub_team_event.data.new_status
|
|
141
139
|
self._process_event_recursively(sub_team_event, parent_name=sub_team_name)
|
|
142
140
|
|
|
143
141
|
def _add_node(self, node_name: str, node_data: Dict, parent_name: str):
|
|
@@ -164,10 +162,10 @@ class TUIStateStore:
|
|
|
164
162
|
def get_pending_approval_for_agent(self, agent_name: str) -> Optional[ToolInvocationApprovalRequestedData]:
|
|
165
163
|
return self._pending_approvals.get(agent_name)
|
|
166
164
|
|
|
167
|
-
def
|
|
165
|
+
def get_task_plan_tasks(self, team_name: str) -> Optional[List[Task]]:
|
|
168
166
|
return self._task_plans.get(team_name)
|
|
169
167
|
|
|
170
|
-
def
|
|
168
|
+
def get_task_plan_statuses(self, team_name: str) -> Optional[Dict[str, TaskStatus]]:
|
|
171
169
|
return self._task_statuses.get(team_name)
|
|
172
170
|
|
|
173
171
|
def clear_pending_approval(self, agent_name: str):
|
|
@@ -10,10 +10,10 @@ from textual.widgets import Static, Tree
|
|
|
10
10
|
from textual.widgets.tree import TreeNode
|
|
11
11
|
from textual.containers import Vertical
|
|
12
12
|
|
|
13
|
-
from autobyteus.agent.
|
|
14
|
-
from autobyteus.agent_team.
|
|
13
|
+
from autobyteus.agent.status.status_enum import AgentStatus
|
|
14
|
+
from autobyteus.agent_team.status.agent_team_status import AgentTeamStatus
|
|
15
15
|
from .shared import (
|
|
16
|
-
|
|
16
|
+
AGENT_STATUS_ICONS, TEAM_STATUS_ICONS, SUB_TEAM_ICON,
|
|
17
17
|
TEAM_ICON, SPEAKING_ICON, DEFAULT_ICON
|
|
18
18
|
)
|
|
19
19
|
from .logo import Logo
|
|
@@ -45,19 +45,19 @@ class AgentListSidebar(Static):
|
|
|
45
45
|
self.post_message(self.NodeSelected(event.node.data))
|
|
46
46
|
event.stop()
|
|
47
47
|
|
|
48
|
-
def _build_label(self, name: str, node_data: Dict,
|
|
48
|
+
def _build_label(self, name: str, node_data: Dict, agent_statuses: Dict, team_statuses: Dict, speaking_agents: Dict) -> str:
|
|
49
49
|
"""Constructs the display label for a tree node."""
|
|
50
50
|
node_type = node_data["type"]
|
|
51
51
|
icon = DEFAULT_ICON
|
|
52
52
|
|
|
53
53
|
if node_type == "agent":
|
|
54
|
-
|
|
55
|
-
icon = SPEAKING_ICON if speaking_agents.get(name) else
|
|
54
|
+
status = agent_statuses.get(name, AgentStatus.UNINITIALIZED)
|
|
55
|
+
icon = SPEAKING_ICON if speaking_agents.get(name) else AGENT_STATUS_ICONS.get(status, DEFAULT_ICON)
|
|
56
56
|
label = f"{icon} {name}"
|
|
57
57
|
elif node_type in ["team", "subteam"]:
|
|
58
|
-
|
|
58
|
+
status = team_statuses.get(name, AgentTeamStatus.UNINITIALIZED)
|
|
59
59
|
default_icon = TEAM_ICON if node_type == "team" else SUB_TEAM_ICON
|
|
60
|
-
icon =
|
|
60
|
+
icon = TEAM_STATUS_ICONS.get(status, default_icon)
|
|
61
61
|
role = node_data.get("role")
|
|
62
62
|
label = f"{icon} {role or name}"
|
|
63
63
|
if role and role != name:
|
|
@@ -67,7 +67,7 @@ class AgentListSidebar(Static):
|
|
|
67
67
|
|
|
68
68
|
return label
|
|
69
69
|
|
|
70
|
-
def update_tree(self, tree_data: Dict,
|
|
70
|
+
def update_tree(self, tree_data: Dict, agent_statuses: Dict[str, AgentStatus], team_statuses: Dict[str, AgentTeamStatus], speaking_agents: Dict[str, bool]):
|
|
71
71
|
"""
|
|
72
72
|
Performs an in-place update of the tree to reflect the new state,
|
|
73
73
|
avoiding a full rebuild for better performance and preserving UI state like expansion.
|
|
@@ -82,17 +82,17 @@ class AgentListSidebar(Static):
|
|
|
82
82
|
root_node_data = tree_data[root_name]
|
|
83
83
|
|
|
84
84
|
# Kick off the recursive update from the root.
|
|
85
|
-
self._update_node_recursively(tree.root, root_node_data,
|
|
85
|
+
self._update_node_recursively(tree.root, root_node_data, agent_statuses, team_statuses, speaking_agents)
|
|
86
86
|
|
|
87
87
|
# Ensure the root is expanded on the first run.
|
|
88
88
|
if not tree.root.is_expanded:
|
|
89
89
|
tree.root.expand()
|
|
90
90
|
|
|
91
|
-
def _update_node_recursively(self, ui_node: TreeNode, node_data: Dict,
|
|
91
|
+
def _update_node_recursively(self, ui_node: TreeNode, node_data: Dict, agent_statuses: Dict, team_statuses: Dict, speaking_agents: Dict):
|
|
92
92
|
"""Recursively updates a node and reconciles its children."""
|
|
93
93
|
# 1. Update the current node's label and data
|
|
94
94
|
name = node_data['name']
|
|
95
|
-
label = self._build_label(name, node_data,
|
|
95
|
+
label = self._build_label(name, node_data, agent_statuses, team_statuses, speaking_agents)
|
|
96
96
|
ui_node.set_label(label)
|
|
97
97
|
ui_node.data = node_data
|
|
98
98
|
self._node_map[name] = ui_node # Ensure map is always up-to-date
|
|
@@ -106,10 +106,10 @@ class AgentListSidebar(Static):
|
|
|
106
106
|
if child_name in existing_ui_children_by_name:
|
|
107
107
|
# Node exists, so we recursively update it
|
|
108
108
|
child_ui_node = existing_ui_children_by_name[child_name]
|
|
109
|
-
self._update_node_recursively(child_ui_node, child_data,
|
|
109
|
+
self._update_node_recursively(child_ui_node, child_data, agent_statuses, team_statuses, speaking_agents)
|
|
110
110
|
else:
|
|
111
111
|
# Node is new, so we add it
|
|
112
|
-
new_child_label = self._build_label(child_name, child_data,
|
|
112
|
+
new_child_label = self._build_label(child_name, child_data, agent_statuses, team_statuses, speaking_agents)
|
|
113
113
|
is_leaf = child_data.get("children", {}) == {} and child_data['type'] == 'agent'
|
|
114
114
|
|
|
115
115
|
if is_leaf:
|
|
@@ -117,7 +117,7 @@ class AgentListSidebar(Static):
|
|
|
117
117
|
else:
|
|
118
118
|
new_ui_node = ui_node.add(new_child_label, data=child_data)
|
|
119
119
|
# Since this is a new branch, we must build its children too
|
|
120
|
-
self._update_node_recursively(new_ui_node, child_data,
|
|
120
|
+
self._update_node_recursively(new_ui_node, child_data, agent_statuses, team_statuses, speaking_agents)
|
|
121
121
|
|
|
122
122
|
self._node_map[child_name] = new_ui_node
|
|
123
123
|
|
|
@@ -12,22 +12,23 @@ from textual.message import Message
|
|
|
12
12
|
from textual.widgets import Input, Static, Button
|
|
13
13
|
from textual.containers import VerticalScroll, Horizontal
|
|
14
14
|
|
|
15
|
-
from autobyteus.agent.
|
|
16
|
-
from autobyteus.agent_team.
|
|
17
|
-
from autobyteus.task_management.
|
|
15
|
+
from autobyteus.agent.status.status_enum import AgentStatus
|
|
16
|
+
from autobyteus.agent_team.status.agent_team_status import AgentTeamStatus
|
|
17
|
+
from autobyteus.task_management.base_task_plan import TaskStatus
|
|
18
18
|
from autobyteus.task_management.task import Task
|
|
19
19
|
from autobyteus.agent.streaming.stream_events import StreamEvent as AgentStreamEvent, StreamEventType as AgentStreamEventType
|
|
20
20
|
from autobyteus.agent.streaming.stream_event_payloads import (
|
|
21
|
-
|
|
21
|
+
AgentStatusUpdateData, AssistantChunkData, AssistantCompleteResponseData,
|
|
22
22
|
ErrorEventData, ToolInteractionLogEntryData, ToolInvocationApprovalRequestedData, ToolInvocationAutoExecutingData,
|
|
23
|
-
SystemTaskNotificationData
|
|
23
|
+
SystemTaskNotificationData, SegmentEventData
|
|
24
24
|
)
|
|
25
|
+
from autobyteus.agent.streaming.parser.events import SegmentEventType, SegmentType
|
|
25
26
|
from .shared import (
|
|
26
|
-
|
|
27
|
+
AGENT_STATUS_ICONS, TEAM_STATUS_ICONS, SUB_TEAM_ICON, DEFAULT_ICON,
|
|
27
28
|
USER_ICON, ASSISTANT_ICON, TEAM_ICON, AGENT_ICON, SYSTEM_TASK_ICON
|
|
28
29
|
)
|
|
29
30
|
from . import renderables
|
|
30
|
-
from .
|
|
31
|
+
from .task_plan_panel import TaskPlanPanel
|
|
31
32
|
|
|
32
33
|
logger = logging.getLogger(__name__)
|
|
33
34
|
|
|
@@ -65,6 +66,8 @@ class FocusPane(Static):
|
|
|
65
66
|
# Buffers for batched UI updates to improve performance
|
|
66
67
|
self._reasoning_buffer: str = ""
|
|
67
68
|
self._content_buffer: str = ""
|
|
69
|
+
self._segment_types_by_id: Dict[str, SegmentType] = {}
|
|
70
|
+
self._saw_segment_event: bool = False
|
|
68
71
|
|
|
69
72
|
def compose(self):
|
|
70
73
|
yield Static("Select a node from the sidebar", id="focus-pane-title")
|
|
@@ -89,7 +92,15 @@ class FocusPane(Static):
|
|
|
89
92
|
return
|
|
90
93
|
|
|
91
94
|
is_approved = event.button.id == "approve-btn"
|
|
92
|
-
|
|
95
|
+
|
|
96
|
+
info_input = self.query_one(Input)
|
|
97
|
+
user_reason = info_input.value.strip()
|
|
98
|
+
info_input.value = "" # Clear the input
|
|
99
|
+
|
|
100
|
+
if user_reason:
|
|
101
|
+
reason = user_reason
|
|
102
|
+
else:
|
|
103
|
+
reason = "User approved via TUI." if is_approved else "User denied via TUI."
|
|
93
104
|
|
|
94
105
|
log_container = self.query_one("#focus-pane-log-container")
|
|
95
106
|
approval_text = "APPROVED" if is_approved else "DENIED"
|
|
@@ -121,8 +132,8 @@ class FocusPane(Static):
|
|
|
121
132
|
async def _show_approval_prompt(self):
|
|
122
133
|
if not self._pending_approval_data: return
|
|
123
134
|
input_widget = self.query_one(Input)
|
|
124
|
-
input_widget.placeholder = "
|
|
125
|
-
input_widget.disabled =
|
|
135
|
+
input_widget.placeholder = "Optional: Enter a reason for your decision..."
|
|
136
|
+
input_widget.disabled = False
|
|
126
137
|
button_container = self.query_one("#approval-buttons")
|
|
127
138
|
await button_container.remove_children()
|
|
128
139
|
await button_container.mount(
|
|
@@ -130,7 +141,7 @@ class FocusPane(Static):
|
|
|
130
141
|
Button("Deny", variant="error", id="deny-btn")
|
|
131
142
|
)
|
|
132
143
|
|
|
133
|
-
def _update_title(self,
|
|
144
|
+
def _update_title(self, agent_statuses: Dict[str, AgentStatus], team_statuses: Dict[str, AgentTeamStatus]):
|
|
134
145
|
"""Renders the title of the focus pane with the node's current status."""
|
|
135
146
|
if not self._focused_node_data:
|
|
136
147
|
self.query_one("#focus-pane-title").update("Select a node from the sidebar")
|
|
@@ -141,31 +152,31 @@ class FocusPane(Static):
|
|
|
141
152
|
node_type_str = node_type.replace("_", " ").capitalize()
|
|
142
153
|
|
|
143
154
|
title_icon = DEFAULT_ICON
|
|
144
|
-
|
|
155
|
+
status_str = ""
|
|
145
156
|
|
|
146
157
|
if node_type == 'agent':
|
|
147
158
|
title_icon = AGENT_ICON
|
|
148
|
-
|
|
149
|
-
|
|
159
|
+
status = agent_statuses.get(node_name, AgentStatus.UNINITIALIZED)
|
|
160
|
+
status_str = f" (Status: {status.value})"
|
|
150
161
|
elif node_type == 'subteam':
|
|
151
162
|
title_icon = SUB_TEAM_ICON
|
|
152
|
-
|
|
153
|
-
|
|
163
|
+
status = team_statuses.get(node_name, AgentTeamStatus.UNINITIALIZED)
|
|
164
|
+
status_str = f" (Status: {status.value})"
|
|
154
165
|
elif node_type == 'team':
|
|
155
166
|
title_icon = TEAM_ICON
|
|
156
|
-
|
|
157
|
-
|
|
167
|
+
status = team_statuses.get(node_name, AgentTeamStatus.UNINITIALIZED)
|
|
168
|
+
status_str = f" (Status: {status.value})"
|
|
158
169
|
|
|
159
|
-
self.query_one("#focus-pane-title").update(f"{title_icon} {node_type_str}: [bold]{node_name}[/bold]{
|
|
170
|
+
self.query_one("#focus-pane-title").update(f"{title_icon} {node_type_str}: [bold]{node_name}[/bold]{status_str}")
|
|
160
171
|
|
|
161
|
-
def update_current_node_status(self,
|
|
172
|
+
def update_current_node_status(self, all_agent_statuses: Dict, all_team_statuses: Dict):
|
|
162
173
|
"""A lightweight method to only update the title with the latest status."""
|
|
163
|
-
self._update_title(
|
|
174
|
+
self._update_title(all_agent_statuses, all_team_statuses)
|
|
164
175
|
|
|
165
176
|
async def update_content(self, node_data: Dict[str, Any], history: List[Any],
|
|
166
177
|
pending_approval: Optional[ToolInvocationApprovalRequestedData],
|
|
167
|
-
|
|
168
|
-
|
|
178
|
+
all_agent_statuses: Dict[str, AgentStatus],
|
|
179
|
+
all_team_statuses: Dict[str, AgentTeamStatus],
|
|
169
180
|
task_plan: Optional[List[Task]],
|
|
170
181
|
task_statuses: Optional[Dict[str, TaskStatus]]):
|
|
171
182
|
"""The main method to update the entire pane based on new state."""
|
|
@@ -174,7 +185,7 @@ class FocusPane(Static):
|
|
|
174
185
|
self._focused_node_data = node_data
|
|
175
186
|
self._pending_approval_data = pending_approval
|
|
176
187
|
|
|
177
|
-
self._update_title(
|
|
188
|
+
self._update_title(all_agent_statuses, all_team_statuses)
|
|
178
189
|
|
|
179
190
|
log_container = self.query_one("#focus-pane-log-container")
|
|
180
191
|
await log_container.remove_children()
|
|
@@ -192,39 +203,39 @@ class FocusPane(Static):
|
|
|
192
203
|
if self._pending_approval_data:
|
|
193
204
|
await self._show_approval_prompt()
|
|
194
205
|
elif self._focused_node_data.get("type") in ['team', 'subteam']:
|
|
195
|
-
await self._render_team_dashboard(node_data,
|
|
206
|
+
await self._render_team_dashboard(node_data, all_agent_statuses, all_team_statuses, task_plan, task_statuses)
|
|
196
207
|
|
|
197
|
-
async def _render_team_dashboard(self, node_data: Dict[str, Any],
|
|
198
|
-
|
|
199
|
-
|
|
208
|
+
async def _render_team_dashboard(self, node_data: Dict[str, Any],
|
|
209
|
+
all_agent_statuses: Dict[str, AgentStatus],
|
|
210
|
+
all_team_statuses: Dict[str, AgentTeamStatus],
|
|
200
211
|
task_plan: Optional[List[Task]],
|
|
201
212
|
task_statuses: Optional[Dict[str, TaskStatus]]):
|
|
202
213
|
"""Renders a static summary dashboard for a team or sub-team."""
|
|
203
214
|
log_container = self.query_one("#focus-pane-log-container")
|
|
204
215
|
|
|
205
|
-
|
|
206
|
-
|
|
216
|
+
status = all_team_statuses.get(node_data['name'], AgentTeamStatus.UNINITIALIZED)
|
|
217
|
+
status_icon = TEAM_STATUS_ICONS.get(status, DEFAULT_ICON)
|
|
207
218
|
info_text = Text()
|
|
208
219
|
info_text.append(f"Name: {node_data['name']}\n", style="bold")
|
|
209
220
|
if node_data.get('role'):
|
|
210
221
|
info_text.append(f"Role: {node_data['role']}\n")
|
|
211
|
-
info_text.append(f"Status: {
|
|
222
|
+
info_text.append(f"Status: {status_icon} {status.value}")
|
|
212
223
|
await log_container.mount(Static(Panel(info_text, title="Team Info", border_style="green", title_align="left")))
|
|
213
224
|
|
|
214
|
-
await log_container.mount(
|
|
225
|
+
await log_container.mount(TaskPlanPanel(tasks=task_plan, statuses=task_statuses, team_name=node_data['name']))
|
|
215
226
|
|
|
216
227
|
children_data = node_data.get("children", {})
|
|
217
228
|
if children_data:
|
|
218
229
|
team_text = Text()
|
|
219
230
|
for name, child_node in children_data.items():
|
|
220
231
|
if child_node['type'] == 'agent':
|
|
221
|
-
|
|
222
|
-
agent_icon =
|
|
223
|
-
team_text.append(f" ▪ {agent_icon} {name} (Agent): {
|
|
232
|
+
agent_status = all_agent_statuses.get(name, AgentStatus.UNINITIALIZED)
|
|
233
|
+
agent_icon = AGENT_STATUS_ICONS.get(agent_status, DEFAULT_ICON)
|
|
234
|
+
team_text.append(f" ▪ {agent_icon} {name} (Agent): {agent_status.value}\n")
|
|
224
235
|
elif child_node['type'] == 'subteam':
|
|
225
|
-
|
|
226
|
-
wf_icon =
|
|
227
|
-
team_text.append(f" ▪ {wf_icon} {name} (Sub-Team): {
|
|
236
|
+
wf_status = all_team_statuses.get(name, AgentTeamStatus.UNINITIALIZED)
|
|
237
|
+
wf_icon = TEAM_STATUS_ICONS.get(wf_status, SUB_TEAM_ICON)
|
|
238
|
+
team_text.append(f" ▪ {wf_icon} {name} (Sub-Team): {wf_status.value}\n")
|
|
228
239
|
await log_container.mount(Static(Panel(team_text, title="Team Status", border_style="blue", title_align="left")))
|
|
229
240
|
|
|
230
241
|
async def _close_thinking_block(self, scroll: bool = True):
|
|
@@ -252,10 +263,105 @@ class FocusPane(Static):
|
|
|
252
263
|
if scrolled:
|
|
253
264
|
self.query_one("#focus-pane-log-container").scroll_end(animate=False)
|
|
254
265
|
|
|
266
|
+
async def _ensure_thinking_widget(self, log_container: VerticalScroll) -> None:
|
|
267
|
+
if self._thinking_widget is None:
|
|
268
|
+
self.flush_stream_buffers()
|
|
269
|
+
await log_container.mount(Static(""))
|
|
270
|
+
self._thinking_text = Text("<Thinking>\n", style="dim italic cyan")
|
|
271
|
+
self._thinking_widget = Static(self._thinking_text)
|
|
272
|
+
await log_container.mount(self._thinking_widget)
|
|
273
|
+
|
|
274
|
+
async def _ensure_assistant_content_widget(self, log_container: VerticalScroll) -> None:
|
|
275
|
+
if self._assistant_content_widget is None:
|
|
276
|
+
await log_container.mount(Static(""))
|
|
277
|
+
self._assistant_content_text = Text(f"{ASSISTANT_ICON} assistant: ", style="bold green")
|
|
278
|
+
self._assistant_content_widget = Static(self._assistant_content_text)
|
|
279
|
+
await log_container.mount(self._assistant_content_widget)
|
|
280
|
+
|
|
281
|
+
async def _handle_segment_event(self, data: SegmentEventData) -> None:
|
|
282
|
+
log_container = self.query_one("#focus-pane-log-container")
|
|
283
|
+
self._saw_segment_event = True
|
|
284
|
+
try:
|
|
285
|
+
event_type = SegmentEventType(data.event_type)
|
|
286
|
+
except ValueError:
|
|
287
|
+
logger.debug(f"TUI FocusPane: Unknown segment event type '{data.event_type}'.")
|
|
288
|
+
return
|
|
289
|
+
|
|
290
|
+
segment_type = None
|
|
291
|
+
if data.segment_type:
|
|
292
|
+
try:
|
|
293
|
+
segment_type = SegmentType(data.segment_type)
|
|
294
|
+
except ValueError:
|
|
295
|
+
logger.debug(f"TUI FocusPane: Unknown segment type '{data.segment_type}'.")
|
|
296
|
+
|
|
297
|
+
if segment_type is None and data.segment_id in self._segment_types_by_id:
|
|
298
|
+
segment_type = self._segment_types_by_id.get(data.segment_id)
|
|
299
|
+
|
|
300
|
+
metadata = {}
|
|
301
|
+
if isinstance(data.payload, dict):
|
|
302
|
+
metadata = data.payload.get("metadata", {}) or {}
|
|
303
|
+
|
|
304
|
+
if event_type == SegmentEventType.START:
|
|
305
|
+
if segment_type is not None:
|
|
306
|
+
self._segment_types_by_id[data.segment_id] = segment_type
|
|
307
|
+
|
|
308
|
+
if segment_type != SegmentType.REASONING:
|
|
309
|
+
await self._close_thinking_block(scroll=False)
|
|
310
|
+
|
|
311
|
+
if segment_type == SegmentType.REASONING:
|
|
312
|
+
await self._ensure_thinking_widget(log_container)
|
|
313
|
+
return
|
|
314
|
+
|
|
315
|
+
await self._ensure_assistant_content_widget(log_container)
|
|
316
|
+
|
|
317
|
+
if segment_type == SegmentType.WRITE_FILE:
|
|
318
|
+
path = metadata.get("path", "")
|
|
319
|
+
header = f"<write_file path=\"{path}\">" if path else "<write_file>"
|
|
320
|
+
self._content_buffer += f"{header}\n"
|
|
321
|
+
elif segment_type == SegmentType.RUN_BASH:
|
|
322
|
+
self._content_buffer += "<run_bash>\n"
|
|
323
|
+
elif segment_type == SegmentType.TOOL_CALL:
|
|
324
|
+
tool_name = metadata.get("tool_name", "")
|
|
325
|
+
header = f"<tool name=\"{tool_name}\">" if tool_name else "<tool>"
|
|
326
|
+
self._content_buffer += f"{header}\n"
|
|
327
|
+
return
|
|
328
|
+
|
|
329
|
+
if event_type == SegmentEventType.CONTENT:
|
|
330
|
+
delta = ""
|
|
331
|
+
if isinstance(data.payload, dict):
|
|
332
|
+
delta = data.payload.get("delta", "")
|
|
333
|
+
|
|
334
|
+
if segment_type == SegmentType.REASONING:
|
|
335
|
+
await self._ensure_thinking_widget(log_container)
|
|
336
|
+
self._reasoning_buffer += str(delta)
|
|
337
|
+
else:
|
|
338
|
+
await self._ensure_assistant_content_widget(log_container)
|
|
339
|
+
self._content_buffer += str(delta)
|
|
340
|
+
return
|
|
341
|
+
|
|
342
|
+
if event_type == SegmentEventType.END:
|
|
343
|
+
if segment_type == SegmentType.REASONING:
|
|
344
|
+
await self._close_thinking_block()
|
|
345
|
+
self._segment_types_by_id.pop(data.segment_id, None)
|
|
346
|
+
return
|
|
347
|
+
|
|
348
|
+
if segment_type in {SegmentType.WRITE_FILE, SegmentType.RUN_BASH, SegmentType.TOOL_CALL}:
|
|
349
|
+
tag = "write_file" if segment_type == SegmentType.WRITE_FILE else (
|
|
350
|
+
"run_bash" if segment_type == SegmentType.RUN_BASH else "tool"
|
|
351
|
+
)
|
|
352
|
+
self._content_buffer += f"\n</{tag}>\n"
|
|
353
|
+
|
|
354
|
+
self._segment_types_by_id.pop(data.segment_id, None)
|
|
355
|
+
return
|
|
356
|
+
|
|
255
357
|
async def add_agent_event(self, event: AgentStreamEvent):
|
|
256
358
|
log_container = self.query_one("#focus-pane-log-container")
|
|
257
359
|
event_type = event.event_type
|
|
258
360
|
|
|
361
|
+
if event_type == AgentStreamEventType.SEGMENT_EVENT and isinstance(event.data, SegmentEventData):
|
|
362
|
+
await self._handle_segment_event(event.data)
|
|
363
|
+
return
|
|
364
|
+
|
|
259
365
|
if event_type == AgentStreamEventType.ASSISTANT_CHUNK:
|
|
260
366
|
data: AssistantChunkData = event.data
|
|
261
367
|
if data.reasoning:
|
|
@@ -282,12 +388,13 @@ class FocusPane(Static):
|
|
|
282
388
|
await self._close_thinking_block()
|
|
283
389
|
self._assistant_content_widget = None
|
|
284
390
|
self._assistant_content_text = None
|
|
285
|
-
if not was_streaming_content:
|
|
391
|
+
if not self._saw_segment_event and not was_streaming_content:
|
|
286
392
|
renderables_list = renderables.render_assistant_complete_response(event.data)
|
|
287
393
|
if renderables_list:
|
|
288
394
|
await log_container.mount(Static(""))
|
|
289
395
|
for item in renderables_list: await log_container.mount(Static(item))
|
|
290
396
|
log_container.scroll_end(animate=False)
|
|
397
|
+
self._saw_segment_event = False
|
|
291
398
|
return
|
|
292
399
|
|
|
293
400
|
is_stream_breaking_event = event_type in [
|
|
@@ -10,7 +10,7 @@ from rich.text import Text
|
|
|
10
10
|
from rich.panel import Panel
|
|
11
11
|
|
|
12
12
|
from autobyteus.agent.streaming.stream_event_payloads import (
|
|
13
|
-
|
|
13
|
+
AgentStatusUpdateData, AssistantCompleteResponseData,
|
|
14
14
|
ErrorEventData, ToolInteractionLogEntryData, ToolInvocationApprovalRequestedData,
|
|
15
15
|
ToolInvocationAutoExecutingData, SystemTaskNotificationData
|
|
16
16
|
)
|
|
@@ -2,34 +2,34 @@
|
|
|
2
2
|
Shared constants and data for TUI widgets.
|
|
3
3
|
"""
|
|
4
4
|
from typing import Dict
|
|
5
|
-
from autobyteus.agent.
|
|
6
|
-
from autobyteus.agent_team.
|
|
7
|
-
from autobyteus.task_management.
|
|
5
|
+
from autobyteus.agent.status.status_enum import AgentStatus
|
|
6
|
+
from autobyteus.agent_team.status.agent_team_status import AgentTeamStatus
|
|
7
|
+
from autobyteus.task_management.base_task_plan import TaskStatus
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
9
|
+
AGENT_STATUS_ICONS: Dict[AgentStatus, str] = {
|
|
10
|
+
AgentStatus.UNINITIALIZED: "⚪",
|
|
11
|
+
AgentStatus.BOOTSTRAPPING: "⏳",
|
|
12
|
+
AgentStatus.IDLE: "🟢",
|
|
13
|
+
AgentStatus.PROCESSING_USER_INPUT: "💭",
|
|
14
|
+
AgentStatus.AWAITING_LLM_RESPONSE: "💭",
|
|
15
|
+
AgentStatus.ANALYZING_LLM_RESPONSE: "🤔",
|
|
16
|
+
AgentStatus.AWAITING_TOOL_APPROVAL: "❓",
|
|
17
|
+
AgentStatus.TOOL_DENIED: "❌",
|
|
18
|
+
AgentStatus.EXECUTING_TOOL: "🛠️",
|
|
19
|
+
AgentStatus.PROCESSING_TOOL_RESULT: "⚙️",
|
|
20
|
+
AgentStatus.SHUTTING_DOWN: "🌙",
|
|
21
|
+
AgentStatus.SHUTDOWN_COMPLETE: "⚫",
|
|
22
|
+
AgentStatus.ERROR: "❗",
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
25
|
+
TEAM_STATUS_ICONS: Dict[AgentTeamStatus, str] = {
|
|
26
|
+
AgentTeamStatus.UNINITIALIZED: "⚪",
|
|
27
|
+
AgentTeamStatus.BOOTSTRAPPING: "⏳",
|
|
28
|
+
AgentTeamStatus.IDLE: "🟢",
|
|
29
|
+
AgentTeamStatus.PROCESSING: "⚙️",
|
|
30
|
+
AgentTeamStatus.SHUTTING_DOWN: "🌙",
|
|
31
|
+
AgentTeamStatus.SHUTDOWN_COMPLETE: "⚫",
|
|
32
|
+
AgentTeamStatus.ERROR: "❗",
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
TASK_STATUS_ICONS: Dict[TaskStatus, str] = {
|
|
@@ -55,6 +55,6 @@ ASSISTANT_ICON = "🤖"
|
|
|
55
55
|
TOOL_ICON = "🛠️"
|
|
56
56
|
PROMPT_ICON = "❓"
|
|
57
57
|
ERROR_ICON = "💥"
|
|
58
|
-
|
|
58
|
+
STATUS_ICON = "🔄"
|
|
59
59
|
LOG_ICON = "📄"
|
|
60
60
|
SYSTEM_TASK_ICON = "📥" # NEW
|
|
@@ -7,13 +7,13 @@ from rich.text import Text
|
|
|
7
7
|
from textual.widgets import Static
|
|
8
8
|
|
|
9
9
|
from autobyteus.task_management.task import Task
|
|
10
|
-
from autobyteus.task_management.
|
|
10
|
+
from autobyteus.task_management.base_task_plan import TaskStatus
|
|
11
11
|
from .shared import TASK_STATUS_ICONS, LOG_ICON
|
|
12
12
|
|
|
13
13
|
logger = logging.getLogger(__name__)
|
|
14
14
|
|
|
15
|
-
class
|
|
16
|
-
"""A widget to display the team's task
|
|
15
|
+
class TaskPlanPanel(Static):
|
|
16
|
+
"""A widget to display the team's task plan."""
|
|
17
17
|
|
|
18
18
|
def __init__(self, tasks: Optional[List[Task]], statuses: Dict[str, TaskStatus], team_name: str, **kwargs) -> None:
|
|
19
19
|
super().__init__(**kwargs)
|
|
@@ -23,7 +23,7 @@ class TaskBoardPanel(Static):
|
|
|
23
23
|
|
|
24
24
|
def compose(self) -> None:
|
|
25
25
|
if not self.tasks:
|
|
26
|
-
yield Static(Panel("No task plan has been published yet.", title="Task
|
|
26
|
+
yield Static(Panel("No task plan has been published yet.", title="Task Plan", border_style="yellow", title_align="left"))
|
|
27
27
|
return
|
|
28
28
|
|
|
29
29
|
table = Table(
|
|
@@ -79,4 +79,4 @@ class TaskBoardPanel(Static):
|
|
|
79
79
|
", ".join(dep_names)
|
|
80
80
|
)
|
|
81
81
|
|
|
82
|
-
yield Static(Panel(table, title="Task
|
|
82
|
+
yield Static(Panel(table, title="Task Plan", border_style="blue", title_align="left"))
|