autobyteus 1.2.1__py3-none-any.whl → 1.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- autobyteus/agent/agent.py +15 -5
- autobyteus/agent/bootstrap_steps/__init__.py +3 -3
- autobyteus/agent/bootstrap_steps/agent_bootstrapper.py +5 -59
- autobyteus/agent/bootstrap_steps/base_bootstrap_step.py +1 -4
- autobyteus/agent/bootstrap_steps/mcp_server_prewarming_step.py +1 -3
- autobyteus/agent/bootstrap_steps/system_prompt_processing_step.py +16 -13
- autobyteus/agent/bootstrap_steps/working_context_snapshot_restore_step.py +38 -0
- autobyteus/agent/bootstrap_steps/workspace_context_initialization_step.py +2 -4
- autobyteus/agent/context/agent_config.py +47 -20
- autobyteus/agent/context/agent_context.py +23 -18
- autobyteus/agent/context/agent_runtime_state.py +21 -19
- autobyteus/agent/events/__init__.py +16 -1
- autobyteus/agent/events/agent_events.py +43 -3
- autobyteus/agent/events/agent_input_event_queue_manager.py +79 -26
- autobyteus/agent/events/event_store.py +57 -0
- autobyteus/agent/events/notifiers.py +69 -59
- autobyteus/agent/events/worker_event_dispatcher.py +21 -64
- autobyteus/agent/factory/agent_factory.py +83 -6
- autobyteus/agent/handlers/__init__.py +2 -0
- autobyteus/agent/handlers/approved_tool_invocation_event_handler.py +51 -34
- autobyteus/agent/handlers/bootstrap_event_handler.py +155 -0
- autobyteus/agent/handlers/inter_agent_message_event_handler.py +10 -0
- autobyteus/agent/handlers/lifecycle_event_logger.py +19 -11
- autobyteus/agent/handlers/llm_complete_response_received_event_handler.py +10 -15
- autobyteus/agent/handlers/llm_user_message_ready_event_handler.py +188 -48
- autobyteus/agent/handlers/tool_execution_approval_event_handler.py +0 -10
- autobyteus/agent/handlers/tool_invocation_request_event_handler.py +53 -48
- autobyteus/agent/handlers/tool_result_event_handler.py +7 -8
- autobyteus/agent/handlers/user_input_message_event_handler.py +10 -3
- autobyteus/agent/input_processor/memory_ingest_input_processor.py +44 -0
- autobyteus/agent/lifecycle/__init__.py +12 -0
- autobyteus/agent/lifecycle/base_processor.py +109 -0
- autobyteus/agent/lifecycle/events.py +35 -0
- autobyteus/agent/lifecycle/processor_definition.py +36 -0
- autobyteus/agent/lifecycle/processor_registry.py +106 -0
- autobyteus/agent/llm_request_assembler.py +98 -0
- autobyteus/agent/llm_response_processor/__init__.py +1 -8
- autobyteus/agent/message/context_file_type.py +1 -1
- autobyteus/agent/runtime/agent_runtime.py +29 -21
- autobyteus/agent/runtime/agent_worker.py +98 -19
- autobyteus/agent/shutdown_steps/__init__.py +2 -0
- autobyteus/agent/shutdown_steps/agent_shutdown_orchestrator.py +2 -0
- autobyteus/agent/shutdown_steps/tool_cleanup_step.py +58 -0
- autobyteus/agent/status/__init__.py +14 -0
- autobyteus/agent/status/manager.py +93 -0
- autobyteus/agent/status/status_deriver.py +96 -0
- autobyteus/agent/{phases/phase_enum.py → status/status_enum.py} +16 -16
- autobyteus/agent/status/status_update_utils.py +73 -0
- autobyteus/agent/streaming/__init__.py +52 -5
- autobyteus/agent/streaming/adapters/__init__.py +18 -0
- autobyteus/agent/streaming/adapters/invocation_adapter.py +184 -0
- autobyteus/agent/streaming/adapters/tool_call_parsing.py +163 -0
- autobyteus/agent/streaming/adapters/tool_syntax_registry.py +67 -0
- autobyteus/agent/streaming/agent_event_stream.py +3 -183
- autobyteus/agent/streaming/api_tool_call/__init__.py +16 -0
- autobyteus/agent/streaming/api_tool_call/file_content_streamer.py +56 -0
- autobyteus/agent/streaming/api_tool_call/json_string_field_extractor.py +175 -0
- autobyteus/agent/streaming/api_tool_call_streaming_response_handler.py +4 -0
- autobyteus/agent/streaming/events/__init__.py +6 -0
- autobyteus/agent/streaming/events/stream_event_payloads.py +284 -0
- autobyteus/agent/streaming/events/stream_events.py +141 -0
- autobyteus/agent/streaming/handlers/__init__.py +15 -0
- autobyteus/agent/streaming/handlers/api_tool_call_streaming_response_handler.py +303 -0
- autobyteus/agent/streaming/handlers/parsing_streaming_response_handler.py +107 -0
- autobyteus/agent/streaming/handlers/pass_through_streaming_response_handler.py +107 -0
- autobyteus/agent/streaming/handlers/streaming_handler_factory.py +177 -0
- autobyteus/agent/streaming/handlers/streaming_response_handler.py +58 -0
- autobyteus/agent/streaming/parser/__init__.py +61 -0
- autobyteus/agent/streaming/parser/event_emitter.py +181 -0
- autobyteus/agent/streaming/parser/events.py +4 -0
- autobyteus/agent/streaming/parser/invocation_adapter.py +4 -0
- autobyteus/agent/streaming/parser/json_parsing_strategies/__init__.py +19 -0
- autobyteus/agent/streaming/parser/json_parsing_strategies/base.py +32 -0
- autobyteus/agent/streaming/parser/json_parsing_strategies/default.py +34 -0
- autobyteus/agent/streaming/parser/json_parsing_strategies/gemini.py +31 -0
- autobyteus/agent/streaming/parser/json_parsing_strategies/openai.py +64 -0
- autobyteus/agent/streaming/parser/json_parsing_strategies/registry.py +75 -0
- autobyteus/agent/streaming/parser/parser_context.py +227 -0
- autobyteus/agent/streaming/parser/parser_factory.py +132 -0
- autobyteus/agent/streaming/parser/sentinel_format.py +7 -0
- autobyteus/agent/streaming/parser/state_factory.py +62 -0
- autobyteus/agent/streaming/parser/states/__init__.py +1 -0
- autobyteus/agent/streaming/parser/states/base_state.py +60 -0
- autobyteus/agent/streaming/parser/states/custom_xml_tag_run_bash_parsing_state.py +38 -0
- autobyteus/agent/streaming/parser/states/custom_xml_tag_write_file_parsing_state.py +55 -0
- autobyteus/agent/streaming/parser/states/delimited_content_state.py +146 -0
- autobyteus/agent/streaming/parser/states/json_initialization_state.py +144 -0
- autobyteus/agent/streaming/parser/states/json_tool_parsing_state.py +137 -0
- autobyteus/agent/streaming/parser/states/sentinel_content_state.py +30 -0
- autobyteus/agent/streaming/parser/states/sentinel_initialization_state.py +117 -0
- autobyteus/agent/streaming/parser/states/text_state.py +78 -0
- autobyteus/agent/streaming/parser/states/xml_patch_file_tool_parsing_state.py +328 -0
- autobyteus/agent/streaming/parser/states/xml_run_bash_tool_parsing_state.py +129 -0
- autobyteus/agent/streaming/parser/states/xml_tag_initialization_state.py +151 -0
- autobyteus/agent/streaming/parser/states/xml_tool_parsing_state.py +63 -0
- autobyteus/agent/streaming/parser/states/xml_write_file_tool_parsing_state.py +343 -0
- autobyteus/agent/streaming/parser/strategies/__init__.py +17 -0
- autobyteus/agent/streaming/parser/strategies/base.py +24 -0
- autobyteus/agent/streaming/parser/strategies/json_tool_strategy.py +26 -0
- autobyteus/agent/streaming/parser/strategies/registry.py +28 -0
- autobyteus/agent/streaming/parser/strategies/sentinel_strategy.py +23 -0
- autobyteus/agent/streaming/parser/strategies/xml_tag_strategy.py +21 -0
- autobyteus/agent/streaming/parser/stream_scanner.py +167 -0
- autobyteus/agent/streaming/parser/streaming_parser.py +212 -0
- autobyteus/agent/streaming/parser/tool_call_parsing.py +4 -0
- autobyteus/agent/streaming/parser/tool_constants.py +7 -0
- autobyteus/agent/streaming/parser/tool_syntax_registry.py +4 -0
- autobyteus/agent/streaming/parser/xml_tool_parsing_state_registry.py +55 -0
- autobyteus/agent/streaming/parsing_streaming_response_handler.py +4 -0
- autobyteus/agent/streaming/pass_through_streaming_response_handler.py +4 -0
- autobyteus/agent/streaming/queue_streamer.py +3 -57
- autobyteus/agent/streaming/segments/__init__.py +5 -0
- autobyteus/agent/streaming/segments/segment_events.py +82 -0
- autobyteus/agent/streaming/stream_event_payloads.py +2 -223
- autobyteus/agent/streaming/stream_events.py +3 -140
- autobyteus/agent/streaming/streaming_handler_factory.py +4 -0
- autobyteus/agent/streaming/streaming_response_handler.py +4 -0
- autobyteus/agent/streaming/streams/__init__.py +5 -0
- autobyteus/agent/streaming/streams/agent_event_stream.py +197 -0
- autobyteus/agent/streaming/utils/__init__.py +5 -0
- autobyteus/agent/streaming/utils/queue_streamer.py +59 -0
- autobyteus/agent/system_prompt_processor/__init__.py +2 -0
- autobyteus/agent/system_prompt_processor/available_skills_processor.py +96 -0
- autobyteus/agent/system_prompt_processor/base_processor.py +1 -1
- autobyteus/agent/system_prompt_processor/processor_meta.py +15 -2
- autobyteus/agent/system_prompt_processor/tool_manifest_injector_processor.py +39 -58
- autobyteus/agent/token_budget.py +56 -0
- autobyteus/agent/tool_execution_result_processor/memory_ingest_tool_result_processor.py +29 -0
- autobyteus/agent/tool_invocation.py +16 -40
- autobyteus/agent/tool_invocation_preprocessor/__init__.py +9 -0
- autobyteus/agent/tool_invocation_preprocessor/base_preprocessor.py +45 -0
- autobyteus/agent/tool_invocation_preprocessor/processor_definition.py +15 -0
- autobyteus/agent/tool_invocation_preprocessor/processor_meta.py +33 -0
- autobyteus/agent/tool_invocation_preprocessor/processor_registry.py +60 -0
- autobyteus/agent/utils/wait_for_idle.py +12 -14
- autobyteus/agent/workspace/base_workspace.py +6 -27
- autobyteus/agent_team/agent_team.py +3 -3
- autobyteus/agent_team/agent_team_builder.py +1 -41
- autobyteus/agent_team/bootstrap_steps/__init__.py +0 -4
- autobyteus/agent_team/bootstrap_steps/agent_configuration_preparation_step.py +8 -18
- autobyteus/agent_team/bootstrap_steps/agent_team_bootstrapper.py +4 -16
- autobyteus/agent_team/bootstrap_steps/base_agent_team_bootstrap_step.py +1 -2
- autobyteus/agent_team/bootstrap_steps/coordinator_initialization_step.py +1 -2
- autobyteus/agent_team/bootstrap_steps/task_notifier_initialization_step.py +1 -2
- autobyteus/agent_team/bootstrap_steps/team_context_initialization_step.py +4 -4
- autobyteus/agent_team/context/agent_team_config.py +6 -3
- autobyteus/agent_team/context/agent_team_context.py +25 -3
- autobyteus/agent_team/context/agent_team_runtime_state.py +9 -6
- autobyteus/agent_team/events/__init__.py +11 -0
- autobyteus/agent_team/events/agent_team_event_dispatcher.py +22 -9
- autobyteus/agent_team/events/agent_team_events.py +16 -0
- autobyteus/agent_team/events/event_store.py +57 -0
- autobyteus/agent_team/factory/agent_team_factory.py +8 -0
- autobyteus/agent_team/handlers/inter_agent_message_request_event_handler.py +18 -2
- autobyteus/agent_team/handlers/lifecycle_agent_team_event_handler.py +21 -5
- autobyteus/agent_team/handlers/process_user_message_event_handler.py +17 -8
- autobyteus/agent_team/handlers/tool_approval_team_event_handler.py +19 -4
- autobyteus/agent_team/runtime/agent_team_runtime.py +41 -10
- autobyteus/agent_team/runtime/agent_team_worker.py +69 -5
- autobyteus/agent_team/status/__init__.py +14 -0
- autobyteus/agent_team/status/agent_team_status.py +18 -0
- autobyteus/agent_team/status/agent_team_status_manager.py +33 -0
- autobyteus/agent_team/status/status_deriver.py +62 -0
- autobyteus/agent_team/status/status_update_utils.py +42 -0
- autobyteus/agent_team/streaming/__init__.py +2 -2
- autobyteus/agent_team/streaming/agent_team_event_notifier.py +6 -6
- autobyteus/agent_team/streaming/agent_team_stream_event_payloads.py +4 -4
- autobyteus/agent_team/streaming/agent_team_stream_events.py +3 -3
- autobyteus/agent_team/system_prompt_processor/__init__.py +6 -0
- autobyteus/agent_team/system_prompt_processor/team_manifest_injector_processor.py +76 -0
- autobyteus/agent_team/task_notification/task_notification_mode.py +19 -0
- autobyteus/agent_team/utils/wait_for_idle.py +4 -4
- autobyteus/cli/agent_cli.py +18 -10
- autobyteus/cli/agent_team_tui/app.py +14 -11
- autobyteus/cli/agent_team_tui/state.py +13 -15
- autobyteus/cli/agent_team_tui/widgets/agent_list_sidebar.py +15 -15
- autobyteus/cli/agent_team_tui/widgets/focus_pane.py +143 -36
- autobyteus/cli/agent_team_tui/widgets/renderables.py +1 -1
- autobyteus/cli/agent_team_tui/widgets/shared.py +25 -25
- autobyteus/cli/cli_display.py +193 -44
- autobyteus/cli/workflow_tui/app.py +9 -10
- autobyteus/cli/workflow_tui/state.py +14 -16
- autobyteus/cli/workflow_tui/widgets/agent_list_sidebar.py +15 -15
- autobyteus/cli/workflow_tui/widgets/focus_pane.py +137 -35
- autobyteus/cli/workflow_tui/widgets/renderables.py +1 -1
- autobyteus/cli/workflow_tui/widgets/shared.py +25 -25
- autobyteus/clients/autobyteus_client.py +94 -1
- autobyteus/events/event_types.py +11 -18
- autobyteus/llm/api/autobyteus_llm.py +33 -29
- autobyteus/llm/api/claude_llm.py +142 -36
- autobyteus/llm/api/gemini_llm.py +163 -59
- autobyteus/llm/api/grok_llm.py +1 -1
- autobyteus/llm/api/minimax_llm.py +26 -0
- autobyteus/llm/api/mistral_llm.py +113 -87
- autobyteus/llm/api/ollama_llm.py +9 -42
- autobyteus/llm/api/openai_compatible_llm.py +127 -91
- autobyteus/llm/api/openai_llm.py +3 -3
- autobyteus/llm/api/openai_responses_llm.py +324 -0
- autobyteus/llm/api/zhipu_llm.py +21 -2
- autobyteus/llm/autobyteus_provider.py +70 -60
- autobyteus/llm/base_llm.py +85 -81
- autobyteus/llm/converters/__init__.py +14 -0
- autobyteus/llm/converters/anthropic_tool_call_converter.py +37 -0
- autobyteus/llm/converters/gemini_tool_call_converter.py +57 -0
- autobyteus/llm/converters/mistral_tool_call_converter.py +37 -0
- autobyteus/llm/converters/openai_tool_call_converter.py +38 -0
- autobyteus/llm/extensions/base_extension.py +6 -12
- autobyteus/llm/extensions/token_usage_tracking_extension.py +45 -18
- autobyteus/llm/llm_factory.py +282 -204
- autobyteus/llm/lmstudio_provider.py +60 -49
- autobyteus/llm/models.py +35 -2
- autobyteus/llm/ollama_provider.py +60 -49
- autobyteus/llm/ollama_provider_resolver.py +0 -1
- autobyteus/llm/prompt_renderers/__init__.py +19 -0
- autobyteus/llm/prompt_renderers/anthropic_prompt_renderer.py +104 -0
- autobyteus/llm/prompt_renderers/autobyteus_prompt_renderer.py +19 -0
- autobyteus/llm/prompt_renderers/base_prompt_renderer.py +10 -0
- autobyteus/llm/prompt_renderers/gemini_prompt_renderer.py +63 -0
- autobyteus/llm/prompt_renderers/mistral_prompt_renderer.py +87 -0
- autobyteus/llm/prompt_renderers/ollama_prompt_renderer.py +51 -0
- autobyteus/llm/prompt_renderers/openai_chat_renderer.py +97 -0
- autobyteus/llm/prompt_renderers/openai_responses_renderer.py +101 -0
- autobyteus/llm/providers.py +1 -3
- autobyteus/llm/token_counter/claude_token_counter.py +56 -25
- autobyteus/llm/token_counter/mistral_token_counter.py +12 -8
- autobyteus/llm/token_counter/openai_token_counter.py +24 -5
- autobyteus/llm/token_counter/token_counter_factory.py +12 -5
- autobyteus/llm/utils/llm_config.py +6 -12
- autobyteus/llm/utils/media_payload_formatter.py +27 -20
- autobyteus/llm/utils/messages.py +55 -3
- autobyteus/llm/utils/response_types.py +3 -0
- autobyteus/llm/utils/tool_call_delta.py +31 -0
- autobyteus/memory/__init__.py +35 -0
- autobyteus/memory/compaction/__init__.py +9 -0
- autobyteus/memory/compaction/compaction_result.py +8 -0
- autobyteus/memory/compaction/compactor.py +89 -0
- autobyteus/memory/compaction/summarizer.py +11 -0
- autobyteus/memory/compaction_snapshot_builder.py +84 -0
- autobyteus/memory/memory_manager.py +205 -0
- autobyteus/memory/models/__init__.py +14 -0
- autobyteus/memory/models/episodic_item.py +41 -0
- autobyteus/memory/models/memory_types.py +7 -0
- autobyteus/memory/models/raw_trace_item.py +79 -0
- autobyteus/memory/models/semantic_item.py +41 -0
- autobyteus/memory/models/tool_interaction.py +20 -0
- autobyteus/memory/path_resolver.py +27 -0
- autobyteus/memory/policies/__init__.py +5 -0
- autobyteus/memory/policies/compaction_policy.py +16 -0
- autobyteus/memory/restore/__init__.py +1 -0
- autobyteus/memory/restore/working_context_snapshot_bootstrapper.py +61 -0
- autobyteus/memory/retrieval/__init__.py +7 -0
- autobyteus/memory/retrieval/memory_bundle.py +11 -0
- autobyteus/memory/retrieval/retriever.py +13 -0
- autobyteus/memory/store/__init__.py +9 -0
- autobyteus/memory/store/base_store.py +14 -0
- autobyteus/memory/store/file_store.py +98 -0
- autobyteus/memory/store/working_context_snapshot_store.py +28 -0
- autobyteus/memory/tool_interaction_builder.py +46 -0
- autobyteus/memory/turn_tracker.py +9 -0
- autobyteus/memory/working_context_snapshot.py +69 -0
- autobyteus/memory/working_context_snapshot_serializer.py +135 -0
- autobyteus/multimedia/audio/api/autobyteus_audio_client.py +19 -5
- autobyteus/multimedia/audio/api/gemini_audio_client.py +109 -16
- autobyteus/multimedia/audio/audio_client_factory.py +47 -9
- autobyteus/multimedia/audio/audio_model.py +2 -1
- autobyteus/multimedia/image/api/autobyteus_image_client.py +19 -5
- autobyteus/multimedia/image/api/gemini_image_client.py +39 -17
- autobyteus/multimedia/image/api/openai_image_client.py +125 -43
- autobyteus/multimedia/image/autobyteus_image_provider.py +2 -1
- autobyteus/multimedia/image/image_client_factory.py +47 -15
- autobyteus/multimedia/image/image_model.py +5 -2
- autobyteus/multimedia/providers.py +3 -2
- autobyteus/skills/loader.py +71 -0
- autobyteus/skills/model.py +11 -0
- autobyteus/skills/registry.py +70 -0
- autobyteus/task_management/tools/todo_tools/add_todo.py +2 -2
- autobyteus/task_management/tools/todo_tools/create_todo_list.py +2 -2
- autobyteus/task_management/tools/todo_tools/update_todo_status.py +2 -2
- autobyteus/tools/__init__.py +34 -47
- autobyteus/tools/base_tool.py +7 -0
- autobyteus/tools/file/__init__.py +2 -6
- autobyteus/tools/file/patch_file.py +149 -0
- autobyteus/tools/file/read_file.py +36 -5
- autobyteus/tools/file/write_file.py +4 -1
- autobyteus/tools/functional_tool.py +43 -6
- autobyteus/tools/mcp/__init__.py +2 -0
- autobyteus/tools/mcp/config_service.py +5 -1
- autobyteus/tools/mcp/server/__init__.py +2 -0
- autobyteus/tools/mcp/server/http_managed_mcp_server.py +1 -1
- autobyteus/tools/mcp/server/websocket_managed_mcp_server.py +141 -0
- autobyteus/tools/mcp/server_instance_manager.py +8 -1
- autobyteus/tools/mcp/types.py +61 -0
- autobyteus/tools/multimedia/audio_tools.py +70 -17
- autobyteus/tools/multimedia/download_media_tool.py +18 -4
- autobyteus/tools/multimedia/image_tools.py +246 -62
- autobyteus/tools/operation_executor/journal_manager.py +107 -0
- autobyteus/tools/operation_executor/operation_event_buffer.py +57 -0
- autobyteus/tools/operation_executor/operation_event_producer.py +29 -0
- autobyteus/tools/operation_executor/operation_executor.py +58 -0
- autobyteus/tools/registry/tool_definition.py +43 -2
- autobyteus/tools/skill/load_skill.py +50 -0
- autobyteus/tools/terminal/__init__.py +45 -0
- autobyteus/tools/terminal/ansi_utils.py +32 -0
- autobyteus/tools/terminal/background_process_manager.py +233 -0
- autobyteus/tools/terminal/output_buffer.py +105 -0
- autobyteus/tools/terminal/prompt_detector.py +63 -0
- autobyteus/tools/terminal/pty_session.py +241 -0
- autobyteus/tools/terminal/session_factory.py +20 -0
- autobyteus/tools/terminal/terminal_session_manager.py +226 -0
- autobyteus/tools/terminal/tools/__init__.py +13 -0
- autobyteus/tools/terminal/tools/get_process_output.py +81 -0
- autobyteus/tools/terminal/tools/run_bash.py +109 -0
- autobyteus/tools/terminal/tools/start_background_process.py +104 -0
- autobyteus/tools/terminal/tools/stop_background_process.py +67 -0
- autobyteus/tools/terminal/types.py +54 -0
- autobyteus/tools/terminal/wsl_tmux_session.py +221 -0
- autobyteus/tools/terminal/wsl_utils.py +156 -0
- autobyteus/tools/transaction_management/backup_handler.py +48 -0
- autobyteus/tools/transaction_management/operation_lifecycle_manager.py +62 -0
- autobyteus/tools/usage/__init__.py +1 -2
- autobyteus/tools/usage/formatters/__init__.py +17 -1
- autobyteus/tools/usage/formatters/base_formatter.py +8 -0
- autobyteus/tools/usage/formatters/default_xml_schema_formatter.py +2 -2
- autobyteus/tools/usage/formatters/mistral_json_schema_formatter.py +18 -0
- autobyteus/tools/usage/formatters/patch_file_xml_example_formatter.py +64 -0
- autobyteus/tools/usage/formatters/patch_file_xml_schema_formatter.py +31 -0
- autobyteus/tools/usage/formatters/run_bash_xml_example_formatter.py +32 -0
- autobyteus/tools/usage/formatters/run_bash_xml_schema_formatter.py +36 -0
- autobyteus/tools/usage/formatters/write_file_xml_example_formatter.py +53 -0
- autobyteus/tools/usage/formatters/write_file_xml_schema_formatter.py +31 -0
- autobyteus/tools/usage/providers/tool_manifest_provider.py +10 -10
- autobyteus/tools/usage/registries/__init__.py +1 -3
- autobyteus/tools/usage/registries/tool_formatting_registry.py +115 -8
- autobyteus/tools/usage/tool_schema_provider.py +51 -0
- autobyteus/tools/web/__init__.py +4 -0
- autobyteus/tools/web/read_url_tool.py +80 -0
- autobyteus/utils/diff_utils.py +271 -0
- autobyteus/utils/download_utils.py +109 -0
- autobyteus/utils/file_utils.py +57 -2
- autobyteus/utils/gemini_helper.py +64 -0
- autobyteus/utils/gemini_model_mapping.py +71 -0
- autobyteus/utils/llm_output_formatter.py +75 -0
- autobyteus/utils/tool_call_format.py +36 -0
- autobyteus/workflow/agentic_workflow.py +3 -3
- autobyteus/workflow/bootstrap_steps/agent_tool_injection_step.py +2 -2
- autobyteus/workflow/bootstrap_steps/base_workflow_bootstrap_step.py +2 -2
- autobyteus/workflow/bootstrap_steps/coordinator_initialization_step.py +2 -2
- autobyteus/workflow/bootstrap_steps/coordinator_prompt_preparation_step.py +3 -9
- autobyteus/workflow/bootstrap_steps/workflow_bootstrapper.py +6 -6
- autobyteus/workflow/bootstrap_steps/workflow_runtime_queue_initialization_step.py +2 -2
- autobyteus/workflow/context/workflow_context.py +3 -3
- autobyteus/workflow/context/workflow_runtime_state.py +5 -5
- autobyteus/workflow/events/workflow_event_dispatcher.py +5 -5
- autobyteus/workflow/handlers/lifecycle_workflow_event_handler.py +3 -3
- autobyteus/workflow/handlers/process_user_message_event_handler.py +5 -5
- autobyteus/workflow/handlers/tool_approval_workflow_event_handler.py +2 -2
- autobyteus/workflow/runtime/workflow_runtime.py +8 -8
- autobyteus/workflow/runtime/workflow_worker.py +3 -3
- autobyteus/workflow/status/__init__.py +11 -0
- autobyteus/workflow/status/workflow_status.py +19 -0
- autobyteus/workflow/status/workflow_status_manager.py +48 -0
- autobyteus/workflow/streaming/__init__.py +2 -2
- autobyteus/workflow/streaming/workflow_event_notifier.py +7 -7
- autobyteus/workflow/streaming/workflow_stream_event_payloads.py +4 -4
- autobyteus/workflow/streaming/workflow_stream_events.py +3 -3
- autobyteus/workflow/utils/wait_for_idle.py +4 -4
- autobyteus-1.3.0.dist-info/METADATA +293 -0
- autobyteus-1.3.0.dist-info/RECORD +606 -0
- {autobyteus-1.2.1.dist-info → autobyteus-1.3.0.dist-info}/WHEEL +1 -1
- {autobyteus-1.2.1.dist-info → autobyteus-1.3.0.dist-info}/top_level.txt +0 -1
- autobyteus/agent/bootstrap_steps/agent_runtime_queue_initialization_step.py +0 -57
- autobyteus/agent/hooks/__init__.py +0 -16
- autobyteus/agent/hooks/base_phase_hook.py +0 -78
- autobyteus/agent/hooks/hook_definition.py +0 -36
- autobyteus/agent/hooks/hook_meta.py +0 -37
- autobyteus/agent/hooks/hook_registry.py +0 -106
- autobyteus/agent/llm_response_processor/provider_aware_tool_usage_processor.py +0 -103
- autobyteus/agent/phases/__init__.py +0 -18
- autobyteus/agent/phases/discover.py +0 -53
- autobyteus/agent/phases/manager.py +0 -265
- autobyteus/agent/phases/transition_decorator.py +0 -40
- autobyteus/agent/phases/transition_info.py +0 -33
- autobyteus/agent/remote_agent.py +0 -244
- autobyteus/agent/workspace/workspace_definition.py +0 -36
- autobyteus/agent/workspace/workspace_meta.py +0 -37
- autobyteus/agent/workspace/workspace_registry.py +0 -72
- autobyteus/agent_team/bootstrap_steps/agent_team_runtime_queue_initialization_step.py +0 -25
- autobyteus/agent_team/bootstrap_steps/coordinator_prompt_preparation_step.py +0 -85
- autobyteus/agent_team/phases/__init__.py +0 -11
- autobyteus/agent_team/phases/agent_team_operational_phase.py +0 -19
- autobyteus/agent_team/phases/agent_team_phase_manager.py +0 -48
- autobyteus/llm/api/bedrock_llm.py +0 -92
- autobyteus/llm/api/groq_llm.py +0 -94
- autobyteus/llm/api/nvidia_llm.py +0 -108
- autobyteus/llm/utils/token_pricing_config.py +0 -87
- autobyteus/rpc/__init__.py +0 -73
- autobyteus/rpc/client/__init__.py +0 -17
- autobyteus/rpc/client/abstract_client_connection.py +0 -124
- autobyteus/rpc/client/client_connection_manager.py +0 -153
- autobyteus/rpc/client/sse_client_connection.py +0 -306
- autobyteus/rpc/client/stdio_client_connection.py +0 -280
- autobyteus/rpc/config/__init__.py +0 -13
- autobyteus/rpc/config/agent_server_config.py +0 -153
- autobyteus/rpc/config/agent_server_registry.py +0 -152
- autobyteus/rpc/hosting.py +0 -244
- autobyteus/rpc/protocol.py +0 -244
- autobyteus/rpc/server/__init__.py +0 -20
- autobyteus/rpc/server/agent_server_endpoint.py +0 -181
- autobyteus/rpc/server/base_method_handler.py +0 -40
- autobyteus/rpc/server/method_handlers.py +0 -259
- autobyteus/rpc/server/sse_server_handler.py +0 -182
- autobyteus/rpc/server/stdio_server_handler.py +0 -151
- autobyteus/rpc/server_main.py +0 -198
- autobyteus/rpc/transport_type.py +0 -13
- autobyteus/tools/bash/__init__.py +0 -2
- autobyteus/tools/bash/bash_executor.py +0 -100
- autobyteus/tools/browser/__init__.py +0 -2
- autobyteus/tools/browser/session_aware/browser_session_aware_navigate_to.py +0 -75
- autobyteus/tools/browser/session_aware/browser_session_aware_tool.py +0 -30
- autobyteus/tools/browser/session_aware/browser_session_aware_web_element_trigger.py +0 -154
- autobyteus/tools/browser/session_aware/browser_session_aware_webpage_reader.py +0 -89
- autobyteus/tools/browser/session_aware/browser_session_aware_webpage_screenshot_taker.py +0 -107
- autobyteus/tools/browser/session_aware/factory/browser_session_aware_web_element_trigger_factory.py +0 -14
- autobyteus/tools/browser/session_aware/factory/browser_session_aware_webpage_reader_factory.py +0 -26
- autobyteus/tools/browser/session_aware/factory/browser_session_aware_webpage_screenshot_taker_factory.py +0 -14
- autobyteus/tools/browser/session_aware/shared_browser_session.py +0 -11
- autobyteus/tools/browser/session_aware/shared_browser_session_manager.py +0 -25
- autobyteus/tools/browser/session_aware/web_element_action.py +0 -20
- autobyteus/tools/browser/standalone/__init__.py +0 -6
- autobyteus/tools/browser/standalone/factory/__init__.py +0 -0
- autobyteus/tools/browser/standalone/factory/webpage_reader_factory.py +0 -25
- autobyteus/tools/browser/standalone/factory/webpage_screenshot_taker_factory.py +0 -14
- autobyteus/tools/browser/standalone/navigate_to.py +0 -84
- autobyteus/tools/browser/standalone/web_page_pdf_generator.py +0 -101
- autobyteus/tools/browser/standalone/webpage_image_downloader.py +0 -169
- autobyteus/tools/browser/standalone/webpage_reader.py +0 -105
- autobyteus/tools/browser/standalone/webpage_screenshot_taker.py +0 -105
- autobyteus/tools/file/edit_file.py +0 -200
- autobyteus/tools/file/list_directory.py +0 -168
- autobyteus/tools/file/search_files.py +0 -188
- autobyteus/tools/timer.py +0 -175
- autobyteus/tools/usage/parsers/__init__.py +0 -22
- autobyteus/tools/usage/parsers/_json_extractor.py +0 -99
- autobyteus/tools/usage/parsers/_string_decoders.py +0 -18
- autobyteus/tools/usage/parsers/anthropic_xml_tool_usage_parser.py +0 -10
- autobyteus/tools/usage/parsers/base_parser.py +0 -41
- autobyteus/tools/usage/parsers/default_json_tool_usage_parser.py +0 -83
- autobyteus/tools/usage/parsers/default_xml_tool_usage_parser.py +0 -316
- autobyteus/tools/usage/parsers/exceptions.py +0 -13
- autobyteus/tools/usage/parsers/gemini_json_tool_usage_parser.py +0 -77
- autobyteus/tools/usage/parsers/openai_json_tool_usage_parser.py +0 -149
- autobyteus/tools/usage/parsers/provider_aware_tool_usage_parser.py +0 -59
- autobyteus/tools/usage/registries/tool_usage_parser_registry.py +0 -62
- autobyteus/workflow/phases/__init__.py +0 -11
- autobyteus/workflow/phases/workflow_operational_phase.py +0 -19
- autobyteus/workflow/phases/workflow_phase_manager.py +0 -48
- autobyteus-1.2.1.dist-info/METADATA +0 -205
- autobyteus-1.2.1.dist-info/RECORD +0 -511
- examples/__init__.py +0 -1
- examples/agent_team/__init__.py +0 -1
- examples/discover_phase_transitions.py +0 -104
- examples/run_agentic_software_engineer.py +0 -239
- examples/run_browser_agent.py +0 -262
- examples/run_google_slides_agent.py +0 -287
- examples/run_mcp_browser_client.py +0 -174
- examples/run_mcp_google_slides_client.py +0 -270
- examples/run_mcp_list_tools.py +0 -189
- examples/run_poem_writer.py +0 -284
- examples/run_sqlite_agent.py +0 -295
- /autobyteus/{tools/browser/session_aware → skills}/__init__.py +0 -0
- /autobyteus/tools/{browser/session_aware/factory → skill}/__init__.py +0 -0
- {autobyteus-1.2.1.dist-info → autobyteus-1.3.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,117 +1,74 @@
|
|
|
1
1
|
# file: autobyteus/autobyteus/agent/events/worker_event_dispatcher.py
|
|
2
|
-
import asyncio
|
|
3
2
|
import logging
|
|
4
3
|
import traceback
|
|
5
|
-
from typing import TYPE_CHECKING
|
|
4
|
+
from typing import TYPE_CHECKING
|
|
6
5
|
|
|
7
|
-
from autobyteus.agent.
|
|
6
|
+
from autobyteus.agent.status.status_enum import AgentStatus
|
|
7
|
+
from autobyteus.agent.status.status_update_utils import apply_event_and_derive_status
|
|
8
8
|
from autobyteus.agent.events.agent_events import ( # Updated relative import path if needed, but BaseEvent is fine
|
|
9
9
|
BaseEvent,
|
|
10
|
-
AgentReadyEvent,
|
|
11
10
|
AgentErrorEvent,
|
|
12
|
-
|
|
13
|
-
PendingToolInvocationEvent,
|
|
14
|
-
ToolExecutionApprovalEvent,
|
|
15
|
-
ToolResultEvent,
|
|
11
|
+
AgentIdleEvent,
|
|
16
12
|
LLMCompleteResponseReceivedEvent,
|
|
17
|
-
UserMessageReceivedEvent,
|
|
18
|
-
InterAgentMessageReceivedEvent,
|
|
19
13
|
)
|
|
20
14
|
|
|
21
15
|
if TYPE_CHECKING:
|
|
22
16
|
from autobyteus.agent.context import AgentContext
|
|
23
17
|
from autobyteus.agent.handlers import EventHandlerRegistry
|
|
24
|
-
from autobyteus.agent.phases import AgentPhaseManager
|
|
25
18
|
logger = logging.getLogger(__name__)
|
|
26
19
|
|
|
27
20
|
class WorkerEventDispatcher:
|
|
28
21
|
"""
|
|
29
22
|
Responsible for dispatching events to their appropriate handlers within an AgentWorker.
|
|
30
|
-
It also manages related
|
|
23
|
+
It also manages related status updates that occur immediately before or after
|
|
31
24
|
an event is handled. This component is part of the agent's event system.
|
|
32
25
|
"""
|
|
33
26
|
|
|
34
27
|
def __init__(self,
|
|
35
|
-
event_handler_registry: 'EventHandlerRegistry'
|
|
36
|
-
phase_manager: 'AgentPhaseManager'):
|
|
28
|
+
event_handler_registry: 'EventHandlerRegistry'):
|
|
37
29
|
"""
|
|
38
30
|
Initializes the WorkerEventDispatcher.
|
|
39
31
|
|
|
40
32
|
Args:
|
|
41
33
|
event_handler_registry: The registry for event handlers.
|
|
42
|
-
phase_manager: The agent's phase manager.
|
|
43
34
|
"""
|
|
44
35
|
self.event_handler_registry: 'EventHandlerRegistry' = event_handler_registry
|
|
45
|
-
self.phase_manager: 'AgentPhaseManager' = phase_manager
|
|
46
36
|
logger.debug("WorkerEventDispatcher initialized.")
|
|
47
37
|
|
|
48
38
|
async def dispatch(self, event: BaseEvent, context: 'AgentContext') -> None: # pragma: no cover
|
|
49
39
|
"""
|
|
50
|
-
Dispatches an event to its registered handler and manages
|
|
40
|
+
Dispatches an event to its registered handler and manages status updates.
|
|
51
41
|
"""
|
|
52
42
|
event_class = type(event)
|
|
53
43
|
handler = self.event_handler_registry.get_handler(event_class)
|
|
54
44
|
agent_id = context.agent_id
|
|
55
45
|
|
|
46
|
+
try:
|
|
47
|
+
await apply_event_and_derive_status(event, context)
|
|
48
|
+
except Exception as e: # pragma: no cover
|
|
49
|
+
logger.error(f"WorkerEventDispatcher '{agent_id}': Status projection failed: {e}", exc_info=True)
|
|
50
|
+
|
|
56
51
|
if handler:
|
|
57
52
|
event_class_name = event_class.__name__
|
|
58
53
|
handler_class_name = type(handler).__name__
|
|
59
54
|
|
|
60
|
-
current_phase_before_dispatch = context.current_phase
|
|
61
|
-
|
|
62
|
-
if current_phase_before_dispatch == AgentOperationalPhase.IDLE:
|
|
63
|
-
if isinstance(event, (UserMessageReceivedEvent, InterAgentMessageReceivedEvent)):
|
|
64
|
-
await self.phase_manager.notify_processing_input_started(trigger_info=type(event).__name__)
|
|
65
|
-
|
|
66
|
-
if isinstance(event, LLMUserMessageReadyEvent):
|
|
67
|
-
if current_phase_before_dispatch not in [AgentOperationalPhase.AWAITING_LLM_RESPONSE, AgentOperationalPhase.ERROR]:
|
|
68
|
-
await self.phase_manager.notify_awaiting_llm_response()
|
|
69
|
-
elif isinstance(event, PendingToolInvocationEvent):
|
|
70
|
-
if not context.auto_execute_tools:
|
|
71
|
-
await self.phase_manager.notify_tool_execution_pending_approval(event.tool_invocation)
|
|
72
|
-
else:
|
|
73
|
-
await self.phase_manager.notify_tool_execution_started(event.tool_invocation.name)
|
|
74
|
-
elif isinstance(event, ToolExecutionApprovalEvent):
|
|
75
|
-
tool_name_for_approval: Optional[str] = None
|
|
76
|
-
pending_invocation = context.state.pending_tool_approvals.get(event.tool_invocation_id)
|
|
77
|
-
if pending_invocation:
|
|
78
|
-
tool_name_for_approval = pending_invocation.name
|
|
79
|
-
else:
|
|
80
|
-
logger.warning(f"WorkerEventDispatcher '{agent_id}': Could not find pending invocation for ID '{event.tool_invocation_id}' to get tool name for phase notification.")
|
|
81
|
-
tool_name_for_approval = "unknown_tool"
|
|
82
|
-
|
|
83
|
-
await self.phase_manager.notify_tool_execution_resumed_after_approval(
|
|
84
|
-
approved=event.is_approved,
|
|
85
|
-
tool_name=tool_name_for_approval
|
|
86
|
-
)
|
|
87
|
-
elif isinstance(event, ToolResultEvent):
|
|
88
|
-
if context.current_phase == AgentOperationalPhase.EXECUTING_TOOL:
|
|
89
|
-
await self.phase_manager.notify_processing_tool_result(event.tool_name)
|
|
90
|
-
elif isinstance(event, LLMCompleteResponseReceivedEvent):
|
|
91
|
-
if context.current_phase == AgentOperationalPhase.AWAITING_LLM_RESPONSE:
|
|
92
|
-
await self.phase_manager.notify_analyzing_llm_response()
|
|
93
|
-
|
|
94
55
|
try:
|
|
95
|
-
logger.debug(f"WorkerEventDispatcher '{agent_id}' (
|
|
56
|
+
logger.debug(f"WorkerEventDispatcher '{agent_id}' (Status: {context.current_status.value}) dispatching '{event_class_name}' to {handler_class_name}.")
|
|
96
57
|
await handler.handle(event, context)
|
|
97
|
-
logger.debug(f"WorkerEventDispatcher '{agent_id}' (
|
|
98
|
-
|
|
99
|
-
if isinstance(event, AgentReadyEvent):
|
|
100
|
-
await self.phase_manager.notify_initialization_complete()
|
|
101
|
-
|
|
102
|
-
if isinstance(event, LLMCompleteResponseReceivedEvent):
|
|
103
|
-
if context.current_phase == AgentOperationalPhase.ANALYZING_LLM_RESPONSE and \
|
|
104
|
-
not context.state.pending_tool_approvals and \
|
|
105
|
-
context.input_event_queues.tool_invocation_request_queue.empty():
|
|
106
|
-
await self.phase_manager.notify_processing_complete_and_idle()
|
|
58
|
+
logger.debug(f"WorkerEventDispatcher '{agent_id}' (Status: {context.current_status.value}) event '{event_class_name}' handled by {handler_class_name}.")
|
|
107
59
|
|
|
108
60
|
except Exception as e:
|
|
109
61
|
error_details = traceback.format_exc()
|
|
110
62
|
error_msg = f"WorkerEventDispatcher '{agent_id}' error handling '{event_class_name}' with {handler_class_name}: {e}"
|
|
111
63
|
logger.error(error_msg, exc_info=True)
|
|
112
|
-
await self.phase_manager.notify_error_occurred(error_msg, error_details)
|
|
113
64
|
await context.input_event_queues.enqueue_internal_system_event(
|
|
114
65
|
AgentErrorEvent(error_message=error_msg, exception_details=error_details)
|
|
115
66
|
)
|
|
67
|
+
else:
|
|
68
|
+
if isinstance(event, LLMCompleteResponseReceivedEvent):
|
|
69
|
+
if context.current_status == AgentStatus.ANALYZING_LLM_RESPONSE and \
|
|
70
|
+
not context.state.pending_tool_approvals and \
|
|
71
|
+
context.input_event_queues.tool_invocation_request_queue.empty():
|
|
72
|
+
await context.input_event_queues.enqueue_internal_system_event(AgentIdleEvent())
|
|
116
73
|
else:
|
|
117
|
-
logger.warning(f"WorkerEventDispatcher '{agent_id}' (
|
|
74
|
+
logger.warning(f"WorkerEventDispatcher '{agent_id}' (Status: {context.current_status.value}) No handler for '{event_class.__name__}'. Event: {event}")
|
|
@@ -13,6 +13,13 @@ from autobyteus.agent.workspace.base_workspace import BaseAgentWorkspace
|
|
|
13
13
|
from autobyteus.agent.handlers import *
|
|
14
14
|
from autobyteus.utils.singleton import SingletonMeta
|
|
15
15
|
from autobyteus.tools.base_tool import BaseTool
|
|
16
|
+
from autobyteus.memory import FileMemoryStore, MemoryManager, resolve_memory_base_dir
|
|
17
|
+
from autobyteus.memory.store.working_context_snapshot_store import WorkingContextSnapshotStore
|
|
18
|
+
from autobyteus.memory.restore.working_context_snapshot_bootstrapper import WorkingContextSnapshotBootstrapOptions
|
|
19
|
+
from autobyteus.agent.input_processor.memory_ingest_input_processor import MemoryIngestInputProcessor
|
|
20
|
+
from autobyteus.agent.tool_execution_result_processor.memory_ingest_tool_result_processor import (
|
|
21
|
+
MemoryIngestToolResultProcessor,
|
|
22
|
+
)
|
|
16
23
|
|
|
17
24
|
if TYPE_CHECKING:
|
|
18
25
|
from autobyteus.agent.runtime.agent_runtime import AgentRuntime
|
|
@@ -41,9 +48,16 @@ class AgentFactory(metaclass=SingletonMeta):
|
|
|
41
48
|
registry.register(ToolExecutionApprovalEvent, ToolExecutionApprovalEventHandler())
|
|
42
49
|
registry.register(LLMUserMessageReadyEvent, LLMUserMessageReadyEventHandler())
|
|
43
50
|
registry.register(ApprovedToolInvocationEvent, ApprovedToolInvocationEventHandler())
|
|
51
|
+
bootstrap_handler = BootstrapEventHandler()
|
|
52
|
+
registry.register(BootstrapStartedEvent, bootstrap_handler)
|
|
53
|
+
registry.register(BootstrapStepRequestedEvent, bootstrap_handler)
|
|
54
|
+
registry.register(BootstrapStepCompletedEvent, bootstrap_handler)
|
|
55
|
+
registry.register(BootstrapCompletedEvent, bootstrap_handler)
|
|
44
56
|
lifecycle_logger_instance = LifecycleEventLogger()
|
|
45
57
|
registry.register(AgentReadyEvent, lifecycle_logger_instance)
|
|
46
58
|
registry.register(AgentStoppedEvent, lifecycle_logger_instance)
|
|
59
|
+
registry.register(AgentIdleEvent, lifecycle_logger_instance)
|
|
60
|
+
registry.register(ShutdownRequestedEvent, lifecycle_logger_instance)
|
|
47
61
|
registry.register(AgentErrorEvent, lifecycle_logger_instance)
|
|
48
62
|
return registry
|
|
49
63
|
|
|
@@ -69,18 +83,58 @@ class AgentFactory(metaclass=SingletonMeta):
|
|
|
69
83
|
|
|
70
84
|
return tool_instances_dict
|
|
71
85
|
|
|
72
|
-
def
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
86
|
+
def _prepare_skills(self, agent_id: str, config: AgentConfig):
|
|
87
|
+
"""
|
|
88
|
+
Registers skills from paths and ensures all skill names are valid.
|
|
89
|
+
"""
|
|
90
|
+
from autobyteus.skills.registry import SkillRegistry
|
|
91
|
+
import os
|
|
92
|
+
|
|
93
|
+
registry = SkillRegistry()
|
|
94
|
+
updated_skills = []
|
|
95
|
+
for skill_item in config.skills:
|
|
96
|
+
# Check if it's a path (absolute or relative to current working directory)
|
|
97
|
+
if os.path.isabs(skill_item) or os.path.exists(skill_item):
|
|
98
|
+
try:
|
|
99
|
+
skill = registry.register_skill_from_path(skill_item)
|
|
100
|
+
updated_skills.append(skill.name)
|
|
101
|
+
except Exception as e:
|
|
102
|
+
logger.error(f"Agent '{agent_id}': Failed to register skill from path '{skill_item}': {e}")
|
|
103
|
+
else:
|
|
104
|
+
updated_skills.append(skill_item)
|
|
105
|
+
|
|
106
|
+
config.skills = updated_skills
|
|
107
|
+
|
|
108
|
+
def _create_runtime_with_id(self,
|
|
109
|
+
agent_id: str,
|
|
110
|
+
config: AgentConfig,
|
|
111
|
+
memory_dir_override: Optional[str] = None,
|
|
112
|
+
restore_options: Optional[WorkingContextSnapshotBootstrapOptions] = None
|
|
113
|
+
) -> 'AgentRuntime':
|
|
76
114
|
from autobyteus.agent.runtime.agent_runtime import AgentRuntime
|
|
77
115
|
|
|
116
|
+
# Prepare skills (resolve paths to names and register them)
|
|
117
|
+
self._prepare_skills(agent_id, config)
|
|
118
|
+
|
|
78
119
|
# The workspace and initial custom data are now passed directly from the config to the state.
|
|
79
120
|
runtime_state = AgentRuntimeState(
|
|
80
121
|
agent_id=agent_id,
|
|
81
122
|
workspace=config.workspace,
|
|
82
123
|
custom_data=config.initial_custom_data
|
|
83
124
|
)
|
|
125
|
+
|
|
126
|
+
# Memory manager (file-backed) initialization
|
|
127
|
+
memory_dir = resolve_memory_base_dir(override_dir=memory_dir_override or config.memory_dir)
|
|
128
|
+
memory_store = FileMemoryStore(base_dir=memory_dir, agent_id=agent_id)
|
|
129
|
+
working_context_snapshot_store = WorkingContextSnapshotStore(base_dir=memory_dir, agent_id=agent_id)
|
|
130
|
+
runtime_state.memory_manager = MemoryManager(store=memory_store, working_context_snapshot_store=working_context_snapshot_store)
|
|
131
|
+
runtime_state.restore_options = restore_options
|
|
132
|
+
|
|
133
|
+
# Ensure memory ingest processors are present
|
|
134
|
+
if not any(isinstance(p, MemoryIngestInputProcessor) for p in config.input_processors):
|
|
135
|
+
config.input_processors.append(MemoryIngestInputProcessor())
|
|
136
|
+
if not any(isinstance(p, MemoryIngestToolResultProcessor) for p in config.tool_execution_result_processors):
|
|
137
|
+
config.tool_execution_result_processors.append(MemoryIngestToolResultProcessor())
|
|
84
138
|
|
|
85
139
|
# --- Set pre-initialized instances on the state ---
|
|
86
140
|
runtime_state.llm_instance = config.llm_instance
|
|
@@ -94,7 +148,7 @@ class AgentFactory(metaclass=SingletonMeta):
|
|
|
94
148
|
logger.info(f"Instantiating AgentRuntime for agent_id: '{agent_id}' with config: '{config.name}'.")
|
|
95
149
|
|
|
96
150
|
return AgentRuntime(
|
|
97
|
-
context=context,
|
|
151
|
+
context=context,
|
|
98
152
|
event_handler_registry=event_handler_registry
|
|
99
153
|
)
|
|
100
154
|
|
|
@@ -114,7 +168,7 @@ class AgentFactory(metaclass=SingletonMeta):
|
|
|
114
168
|
while agent_id in self._active_agents:
|
|
115
169
|
agent_id = f"{config.name}_{config.role}_{random.randint(1000, 9999)}"
|
|
116
170
|
|
|
117
|
-
runtime = self.
|
|
171
|
+
runtime = self._create_runtime_with_id(
|
|
118
172
|
agent_id=agent_id,
|
|
119
173
|
config=config,
|
|
120
174
|
)
|
|
@@ -124,6 +178,29 @@ class AgentFactory(metaclass=SingletonMeta):
|
|
|
124
178
|
logger.info(f"Agent '{agent_id}' created and stored successfully.")
|
|
125
179
|
return agent
|
|
126
180
|
|
|
181
|
+
def restore_agent(
|
|
182
|
+
self,
|
|
183
|
+
agent_id: str,
|
|
184
|
+
config: AgentConfig,
|
|
185
|
+
memory_dir: Optional[str] = None,
|
|
186
|
+
) -> Agent:
|
|
187
|
+
if not agent_id or not isinstance(agent_id, str):
|
|
188
|
+
raise ValueError("restore_agent requires a non-empty string agent_id.")
|
|
189
|
+
if agent_id in self._active_agents:
|
|
190
|
+
raise ValueError(f"Agent '{agent_id}' is already active.")
|
|
191
|
+
|
|
192
|
+
restore_options = WorkingContextSnapshotBootstrapOptions()
|
|
193
|
+
runtime = self._create_runtime_with_id(
|
|
194
|
+
agent_id=agent_id,
|
|
195
|
+
config=config,
|
|
196
|
+
memory_dir_override=memory_dir,
|
|
197
|
+
restore_options=restore_options,
|
|
198
|
+
)
|
|
199
|
+
agent = Agent(runtime=runtime)
|
|
200
|
+
self._active_agents[agent_id] = agent
|
|
201
|
+
logger.info(f"Agent '{agent_id}' restored and stored successfully.")
|
|
202
|
+
return agent
|
|
203
|
+
|
|
127
204
|
def get_agent(self, agent_id: str) -> Optional[Agent]:
|
|
128
205
|
"""Retrieves an active agent instance by its ID."""
|
|
129
206
|
return self._active_agents.get(agent_id)
|
|
@@ -14,6 +14,7 @@ from .tool_invocation_request_event_handler import ToolInvocationRequestEventHan
|
|
|
14
14
|
from .tool_result_event_handler import ToolResultEventHandler
|
|
15
15
|
from .approved_tool_invocation_event_handler import ApprovedToolInvocationEventHandler
|
|
16
16
|
from .tool_execution_approval_event_handler import ToolExecutionApprovalEventHandler
|
|
17
|
+
from .bootstrap_event_handler import BootstrapEventHandler
|
|
17
18
|
|
|
18
19
|
# General Purpose and Lifecycle Handlers
|
|
19
20
|
from .generic_event_handler import GenericEventHandler
|
|
@@ -31,6 +32,7 @@ __all__ = [
|
|
|
31
32
|
"ToolResultEventHandler",
|
|
32
33
|
"ApprovedToolInvocationEventHandler",
|
|
33
34
|
"ToolExecutionApprovalEventHandler",
|
|
35
|
+
"BootstrapEventHandler",
|
|
34
36
|
"GenericEventHandler",
|
|
35
37
|
"LifecycleEventLogger",
|
|
36
38
|
]
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
# file: autobyteus/autobyteus/agent/handlers/approved_tool_invocation_event_handler.py
|
|
2
2
|
import logging
|
|
3
|
-
|
|
3
|
+
|
|
4
4
|
import traceback
|
|
5
5
|
from typing import TYPE_CHECKING, Optional
|
|
6
6
|
|
|
7
7
|
from autobyteus.agent.handlers.base_event_handler import AgentEventHandler
|
|
8
8
|
from autobyteus.agent.events import ApprovedToolInvocationEvent, ToolResultEvent
|
|
9
9
|
from autobyteus.agent.tool_invocation import ToolInvocation
|
|
10
|
+
from autobyteus.utils.llm_output_formatter import format_to_clean_string
|
|
10
11
|
|
|
11
12
|
if TYPE_CHECKING:
|
|
12
13
|
from autobyteus.agent.context import AgentContext
|
|
@@ -38,18 +39,38 @@ class ApprovedToolInvocationEventHandler(AgentEventHandler):
|
|
|
38
39
|
agent_id = context.agent_id
|
|
39
40
|
|
|
40
41
|
notifier: Optional['AgentExternalEventNotifier'] = None
|
|
41
|
-
if context.
|
|
42
|
-
notifier = context.
|
|
42
|
+
if context.status_manager:
|
|
43
|
+
notifier = context.status_manager.notifier
|
|
43
44
|
|
|
44
45
|
if not notifier: # pragma: no cover
|
|
45
46
|
logger.error(f"Agent '{agent_id}': Notifier not available in ApprovedToolInvocationEventHandler. Tool interaction logs will not be emitted.")
|
|
46
47
|
|
|
47
48
|
logger.info(f"Agent '{agent_id}' handling ApprovedToolInvocationEvent for tool: '{tool_name}' (ID: {invocation_id}) with args: {arguments}")
|
|
48
49
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
# Run tool invocation preprocessors before execution
|
|
51
|
+
processors = context.config.tool_invocation_preprocessors
|
|
52
|
+
if processors:
|
|
53
|
+
sorted_processors = sorted(processors, key=lambda p: p.get_order())
|
|
54
|
+
for processor in sorted_processors:
|
|
55
|
+
try:
|
|
56
|
+
tool_invocation = await processor.process(tool_invocation, context)
|
|
57
|
+
tool_name = tool_invocation.name
|
|
58
|
+
arguments = tool_invocation.arguments
|
|
59
|
+
invocation_id = tool_invocation.id
|
|
60
|
+
except Exception as e:
|
|
61
|
+
error_message = f"Error in tool invocation preprocessor '{processor.get_name()}' for tool '{tool_name}': {e}"
|
|
62
|
+
logger.error(f"Agent '{agent_id}': {error_message}", exc_info=True)
|
|
63
|
+
result_event = ToolResultEvent(
|
|
64
|
+
tool_name=tool_name,
|
|
65
|
+
result=None,
|
|
66
|
+
error=error_message,
|
|
67
|
+
tool_invocation_id=invocation_id,
|
|
68
|
+
turn_id=tool_invocation.turn_id,
|
|
69
|
+
)
|
|
70
|
+
await context.input_event_queues.enqueue_tool_result(result_event)
|
|
71
|
+
return
|
|
72
|
+
|
|
73
|
+
args_str = format_to_clean_string(arguments)
|
|
53
74
|
log_msg_call = f"[APPROVED_TOOL_CALL] Agent_ID: {agent_id}, Tool: {tool_name}, Invocation_ID: {invocation_id}, Arguments: {args_str}"
|
|
54
75
|
|
|
55
76
|
if notifier:
|
|
@@ -69,13 +90,13 @@ class ApprovedToolInvocationEventHandler(AgentEventHandler):
|
|
|
69
90
|
if not tool_instance:
|
|
70
91
|
error_message = f"Tool '{tool_name}' not found or configured for agent '{agent_id}'."
|
|
71
92
|
logger.error(error_message)
|
|
72
|
-
result_event = ToolResultEvent(
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
93
|
+
result_event = ToolResultEvent(
|
|
94
|
+
tool_name=tool_name,
|
|
95
|
+
result=None,
|
|
96
|
+
error=error_message,
|
|
97
|
+
tool_invocation_id=invocation_id,
|
|
98
|
+
turn_id=tool_invocation.turn_id,
|
|
99
|
+
)
|
|
79
100
|
log_msg_error = f"[APPROVED_TOOL_ERROR] {error_message}"
|
|
80
101
|
if notifier:
|
|
81
102
|
try:
|
|
@@ -94,21 +115,17 @@ class ApprovedToolInvocationEventHandler(AgentEventHandler):
|
|
|
94
115
|
logger.debug(f"Executing approved tool '{tool_name}' for agent '{agent_id}'. Invocation ID: {invocation_id}")
|
|
95
116
|
execution_result = await tool_instance.execute(context=context, **arguments)
|
|
96
117
|
|
|
97
|
-
|
|
98
|
-
result_json_for_log = json.dumps(execution_result)
|
|
99
|
-
except (TypeError, ValueError):
|
|
100
|
-
result_json_for_log = json.dumps(str(execution_result))
|
|
118
|
+
result_json_for_log = format_to_clean_string(execution_result)
|
|
101
119
|
|
|
102
120
|
logger.info(f"Approved tool '{tool_name}' (ID: {invocation_id}) executed successfully by agent '{agent_id}'.")
|
|
103
|
-
result_event = ToolResultEvent(
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
})
|
|
121
|
+
result_event = ToolResultEvent(
|
|
122
|
+
tool_name=tool_name,
|
|
123
|
+
result=execution_result,
|
|
124
|
+
error=None,
|
|
125
|
+
tool_invocation_id=invocation_id,
|
|
126
|
+
tool_args=arguments,
|
|
127
|
+
turn_id=tool_invocation.turn_id,
|
|
128
|
+
)
|
|
112
129
|
log_msg_result = f"[APPROVED_TOOL_RESULT] {result_json_for_log}"
|
|
113
130
|
if notifier:
|
|
114
131
|
try:
|
|
@@ -122,13 +139,13 @@ class ApprovedToolInvocationEventHandler(AgentEventHandler):
|
|
|
122
139
|
error_message = f"Error executing approved tool '{tool_name}' (ID: {invocation_id}): {str(e)}"
|
|
123
140
|
error_details = traceback.format_exc()
|
|
124
141
|
logger.error(f"Agent '{agent_id}' {error_message}", exc_info=True)
|
|
125
|
-
result_event = ToolResultEvent(
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
142
|
+
result_event = ToolResultEvent(
|
|
143
|
+
tool_name=tool_name,
|
|
144
|
+
result=None,
|
|
145
|
+
error=error_message,
|
|
146
|
+
tool_invocation_id=invocation_id,
|
|
147
|
+
turn_id=tool_invocation.turn_id,
|
|
148
|
+
)
|
|
132
149
|
log_msg_exception = f"[APPROVED_TOOL_EXCEPTION] {error_message}\nDetails:\n{error_details}"
|
|
133
150
|
if notifier:
|
|
134
151
|
try:
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# file: autobyteus/autobyteus/agent/handlers/bootstrap_event_handler.py
|
|
2
|
+
import logging
|
|
3
|
+
from typing import List, Optional, TYPE_CHECKING
|
|
4
|
+
|
|
5
|
+
from autobyteus.agent.bootstrap_steps.agent_bootstrapper import AgentBootstrapper
|
|
6
|
+
from autobyteus.agent.bootstrap_steps.base_bootstrap_step import BaseBootstrapStep
|
|
7
|
+
from autobyteus.agent.events import (
|
|
8
|
+
AgentErrorEvent,
|
|
9
|
+
AgentReadyEvent,
|
|
10
|
+
BootstrapStartedEvent,
|
|
11
|
+
BootstrapStepRequestedEvent,
|
|
12
|
+
BootstrapStepCompletedEvent,
|
|
13
|
+
BootstrapCompletedEvent,
|
|
14
|
+
)
|
|
15
|
+
from autobyteus.agent.handlers.base_event_handler import AgentEventHandler
|
|
16
|
+
|
|
17
|
+
if TYPE_CHECKING:
|
|
18
|
+
from autobyteus.agent.context import AgentContext
|
|
19
|
+
|
|
20
|
+
logger = logging.getLogger(__name__)
|
|
21
|
+
|
|
22
|
+
_BOOTSTRAP_STEPS_KEY = "_bootstrap_steps"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class BootstrapEventHandler(AgentEventHandler):
|
|
26
|
+
"""
|
|
27
|
+
Orchestrates the agent bootstrap sequence using internal lifecycle events.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
def __init__(self, steps: Optional[List[BaseBootstrapStep]] = None) -> None:
|
|
31
|
+
self._bootstrapper = AgentBootstrapper(steps=steps)
|
|
32
|
+
|
|
33
|
+
async def handle(self, event: object, context: 'AgentContext') -> None:
|
|
34
|
+
if isinstance(event, BootstrapStartedEvent):
|
|
35
|
+
await self._handle_bootstrap_started(context)
|
|
36
|
+
return
|
|
37
|
+
|
|
38
|
+
if isinstance(event, BootstrapStepRequestedEvent):
|
|
39
|
+
await self._handle_bootstrap_step_requested(event, context)
|
|
40
|
+
return
|
|
41
|
+
|
|
42
|
+
if isinstance(event, BootstrapStepCompletedEvent):
|
|
43
|
+
await self._handle_bootstrap_step_completed(event, context)
|
|
44
|
+
return
|
|
45
|
+
|
|
46
|
+
if isinstance(event, BootstrapCompletedEvent):
|
|
47
|
+
await self._handle_bootstrap_completed(event, context)
|
|
48
|
+
return
|
|
49
|
+
|
|
50
|
+
logger.warning(f"BootstrapEventHandler received unexpected event type: {type(event).__name__}")
|
|
51
|
+
|
|
52
|
+
async def _handle_bootstrap_started(self, context: 'AgentContext') -> None:
|
|
53
|
+
steps = list(self._bootstrapper.bootstrap_steps)
|
|
54
|
+
context.state.custom_data[_BOOTSTRAP_STEPS_KEY] = steps
|
|
55
|
+
|
|
56
|
+
if not steps:
|
|
57
|
+
logger.info(f"Agent '{context.agent_id}': No bootstrap steps configured. Marking bootstrap complete.")
|
|
58
|
+
await context.input_event_queues.enqueue_internal_system_event(
|
|
59
|
+
BootstrapCompletedEvent(success=True)
|
|
60
|
+
)
|
|
61
|
+
return
|
|
62
|
+
|
|
63
|
+
logger.info(f"Agent '{context.agent_id}': Bootstrap started with {len(steps)} steps.")
|
|
64
|
+
await context.input_event_queues.enqueue_internal_system_event(
|
|
65
|
+
BootstrapStepRequestedEvent(step_index=0)
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
async def _handle_bootstrap_step_requested(self, event: BootstrapStepRequestedEvent, context: 'AgentContext') -> None:
|
|
69
|
+
steps: Optional[List[BaseBootstrapStep]] = context.state.custom_data.get(_BOOTSTRAP_STEPS_KEY)
|
|
70
|
+
if not steps:
|
|
71
|
+
error_message = "Bootstrap steps list missing from context during step request."
|
|
72
|
+
logger.error(f"Agent '{context.agent_id}': {error_message}")
|
|
73
|
+
await self._notify_bootstrap_error(context, error_message)
|
|
74
|
+
await context.input_event_queues.enqueue_internal_system_event(
|
|
75
|
+
BootstrapCompletedEvent(success=False, error_message=error_message)
|
|
76
|
+
)
|
|
77
|
+
return
|
|
78
|
+
|
|
79
|
+
step_index = event.step_index
|
|
80
|
+
if step_index < 0 or step_index >= len(steps):
|
|
81
|
+
error_message = f"Invalid bootstrap step index {step_index}."
|
|
82
|
+
logger.error(f"Agent '{context.agent_id}': {error_message}")
|
|
83
|
+
await self._notify_bootstrap_error(context, error_message)
|
|
84
|
+
await context.input_event_queues.enqueue_internal_system_event(
|
|
85
|
+
BootstrapCompletedEvent(success=False, error_message=error_message)
|
|
86
|
+
)
|
|
87
|
+
return
|
|
88
|
+
|
|
89
|
+
step = steps[step_index]
|
|
90
|
+
step_name = step.__class__.__name__
|
|
91
|
+
logger.debug(f"Agent '{context.agent_id}': Executing bootstrap step {step_index + 1}/{len(steps)}: {step_name}")
|
|
92
|
+
|
|
93
|
+
try:
|
|
94
|
+
success = await step.execute(context)
|
|
95
|
+
except Exception as e: # pragma: no cover
|
|
96
|
+
error_message = f"Exception during bootstrap step '{step_name}': {e}"
|
|
97
|
+
logger.error(f"Agent '{context.agent_id}': {error_message}", exc_info=True)
|
|
98
|
+
success = False
|
|
99
|
+
if not success:
|
|
100
|
+
error_message = f"Bootstrap step '{step_name}' failed."
|
|
101
|
+
await self._notify_bootstrap_error(context, error_message)
|
|
102
|
+
|
|
103
|
+
await context.input_event_queues.enqueue_internal_system_event(
|
|
104
|
+
BootstrapStepCompletedEvent(
|
|
105
|
+
step_index=step_index,
|
|
106
|
+
step_name=step_name,
|
|
107
|
+
success=success,
|
|
108
|
+
error_message=None if success else f"Step '{step_name}' failed",
|
|
109
|
+
)
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
async def _handle_bootstrap_step_completed(self, event: BootstrapStepCompletedEvent, context: 'AgentContext') -> None:
|
|
113
|
+
if not event.success:
|
|
114
|
+
await context.input_event_queues.enqueue_internal_system_event(
|
|
115
|
+
BootstrapCompletedEvent(success=False, error_message=event.error_message)
|
|
116
|
+
)
|
|
117
|
+
return
|
|
118
|
+
|
|
119
|
+
steps: Optional[List[BaseBootstrapStep]] = context.state.custom_data.get(_BOOTSTRAP_STEPS_KEY)
|
|
120
|
+
if not steps:
|
|
121
|
+
error_message = "Bootstrap steps list missing during step completion."
|
|
122
|
+
logger.error(f"Agent '{context.agent_id}': {error_message}")
|
|
123
|
+
await self._notify_bootstrap_error(context, error_message)
|
|
124
|
+
await context.input_event_queues.enqueue_internal_system_event(
|
|
125
|
+
BootstrapCompletedEvent(success=False, error_message=error_message)
|
|
126
|
+
)
|
|
127
|
+
return
|
|
128
|
+
|
|
129
|
+
next_index = event.step_index + 1
|
|
130
|
+
if next_index < len(steps):
|
|
131
|
+
await context.input_event_queues.enqueue_internal_system_event(
|
|
132
|
+
BootstrapStepRequestedEvent(step_index=next_index)
|
|
133
|
+
)
|
|
134
|
+
return
|
|
135
|
+
|
|
136
|
+
await context.input_event_queues.enqueue_internal_system_event(
|
|
137
|
+
BootstrapCompletedEvent(success=True)
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
async def _handle_bootstrap_completed(self, event: BootstrapCompletedEvent, context: 'AgentContext') -> None:
|
|
141
|
+
if not event.success:
|
|
142
|
+
logger.error(
|
|
143
|
+
f"Agent '{context.agent_id}': Bootstrap completed with failure. "
|
|
144
|
+
f"Error: {event.error_message}"
|
|
145
|
+
)
|
|
146
|
+
await self._notify_bootstrap_error(context, event.error_message or "Bootstrap failed.")
|
|
147
|
+
return
|
|
148
|
+
|
|
149
|
+
logger.info(f"Agent '{context.agent_id}': Bootstrap completed successfully. Emitting AgentReadyEvent.")
|
|
150
|
+
await context.input_event_queues.enqueue_internal_system_event(AgentReadyEvent())
|
|
151
|
+
|
|
152
|
+
async def _notify_bootstrap_error(self, context: 'AgentContext', error_message: str) -> None:
|
|
153
|
+
await context.input_event_queues.enqueue_internal_system_event(
|
|
154
|
+
AgentErrorEvent(error_message=error_message, exception_details=error_message)
|
|
155
|
+
)
|
|
@@ -48,6 +48,16 @@ class InterAgentMessageReceivedEventHandler(AgentEventHandler):
|
|
|
48
48
|
f"'{inter_agent_msg.sender_agent_id}', type '{inter_agent_msg.message_type.value}'. "
|
|
49
49
|
f"Content: '{inter_agent_msg.content}'"
|
|
50
50
|
)
|
|
51
|
+
|
|
52
|
+
# Surface this inter-agent message to external subscribers (UI, etc.)
|
|
53
|
+
if context.status_manager and context.status_manager.notifier:
|
|
54
|
+
notifier: 'AgentExternalEventNotifier' = context.status_manager.notifier
|
|
55
|
+
notifier.notify_agent_data_inter_agent_message_received({
|
|
56
|
+
"sender_agent_id": inter_agent_msg.sender_agent_id,
|
|
57
|
+
"recipient_role_name": inter_agent_msg.recipient_role_name,
|
|
58
|
+
"content": inter_agent_msg.content,
|
|
59
|
+
"message_type": inter_agent_msg.message_type.value,
|
|
60
|
+
})
|
|
51
61
|
|
|
52
62
|
content_for_llm = (
|
|
53
63
|
f"You have received a message from another agent.\n"
|