autobyteus 1.2.1__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 +19 -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 +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/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 +81 -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 +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/autobyteus_audio_client.py +19 -5
- autobyteus/multimedia/audio/api/gemini_audio_client.py +108 -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 +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/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 +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 +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.2.3.dist-info/METADATA +293 -0
- autobyteus-1.2.3.dist-info/RECORD +600 -0
- {autobyteus-1.2.1.dist-info → autobyteus-1.2.3.dist-info}/WHEEL +1 -1
- {autobyteus-1.2.1.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/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.2.3.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
# file: autobyteus/autobyteus/rpc/server/agent_server_endpoint.py
|
|
2
|
-
import asyncio
|
|
3
|
-
import logging
|
|
4
|
-
from typing import Optional, Dict, Union
|
|
5
|
-
|
|
6
|
-
from autobyteus.rpc.config import AgentServerConfig
|
|
7
|
-
from autobyteus.rpc.transport_type import TransportType
|
|
8
|
-
from autobyteus.rpc.protocol import RequestType
|
|
9
|
-
from autobyteus.agent.agent import Agent
|
|
10
|
-
from .base_method_handler import BaseMethodHandler
|
|
11
|
-
from .method_handlers import DiscoverCapabilitiesHandler, InvokeMethodHandler, InitiateStreamDownloadHandler # Added InitiateStreamDownloadHandler
|
|
12
|
-
from .stdio_server_handler import StdioServerHandler
|
|
13
|
-
from .sse_server_handler import SseServerHandler
|
|
14
|
-
|
|
15
|
-
logger = logging.getLogger(__name__)
|
|
16
|
-
|
|
17
|
-
class AgentServerEndpoint:
|
|
18
|
-
"""
|
|
19
|
-
Manages the server-side RPC endpoint.
|
|
20
|
-
It can serve a single Agent or a dictionary of multiple Agents (for SSE).
|
|
21
|
-
It initializes and controls transport-specific handlers.
|
|
22
|
-
"""
|
|
23
|
-
|
|
24
|
-
def __init__(self, agent_or_agents: Union[Agent, Dict[str, Agent]]):
|
|
25
|
-
"""
|
|
26
|
-
Initializes the AgentServerEndpoint.
|
|
27
|
-
|
|
28
|
-
Args:
|
|
29
|
-
agent_or_agents: Either a single Agent instance to serve, or a dictionary
|
|
30
|
-
mapping server-routable agent IDs to Agent instances
|
|
31
|
-
(primarily for multi-agent SSE hosting).
|
|
32
|
-
"""
|
|
33
|
-
if not isinstance(agent_or_agents, (Agent, dict)):
|
|
34
|
-
raise TypeError("AgentServerEndpoint requires an Agent instance or a Dict[str, Agent].")
|
|
35
|
-
if isinstance(agent_or_agents, dict) and not all(isinstance(k, str) and isinstance(v, Agent) for k, v in agent_or_agents.items()):
|
|
36
|
-
raise TypeError("If agent_or_agents is a dict, keys must be strings and values must be Agent instances.")
|
|
37
|
-
|
|
38
|
-
self._served_entity: Union[Agent, Dict[str, Agent]] = agent_or_agents
|
|
39
|
-
self._config: Optional[AgentServerConfig] = None
|
|
40
|
-
|
|
41
|
-
# Initialize method handlers
|
|
42
|
-
# These handlers are stateless and can be reused.
|
|
43
|
-
# For stateful handlers, they might need to be instantiated per request or per agent context.
|
|
44
|
-
self._method_handlers: Dict[Union[RequestType, str], BaseMethodHandler] = {
|
|
45
|
-
RequestType.DISCOVER_CAPABILITIES: DiscoverCapabilitiesHandler(),
|
|
46
|
-
RequestType.INVOKE_METHOD: InvokeMethodHandler(),
|
|
47
|
-
RequestType.REQUEST_STREAM_DOWNLOAD: InitiateStreamDownloadHandler(), # Added handler for stream download
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
self._stdio_handler: Optional[StdioServerHandler] = None
|
|
51
|
-
self._stdio_task: Optional[asyncio.Task] = None
|
|
52
|
-
|
|
53
|
-
self._sse_handler: Optional[SseServerHandler] = None
|
|
54
|
-
self._sse_server_task: Optional[asyncio.Task] = None # For the aiohttp server itself
|
|
55
|
-
|
|
56
|
-
self._is_running: bool = False
|
|
57
|
-
|
|
58
|
-
if isinstance(self._served_entity, Agent):
|
|
59
|
-
logger.info(f"AgentServerEndpoint initialized for single agent '{self._served_entity.agent_id}'.")
|
|
60
|
-
else: # Dict[str, Agent]
|
|
61
|
-
agent_ids_served = list(self._served_entity.keys())
|
|
62
|
-
logger.info(f"AgentServerEndpoint initialized to serve multiple agents: {agent_ids_served}.")
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
@property
|
|
66
|
-
def is_running(self) -> bool:
|
|
67
|
-
return self._is_running
|
|
68
|
-
|
|
69
|
-
async def start(self, config: AgentServerConfig) -> None:
|
|
70
|
-
if self._is_running:
|
|
71
|
-
served_id = self._served_entity.agent_id if isinstance(self._served_entity, Agent) else "multiple agents"
|
|
72
|
-
logger.warning(f"AgentServerEndpoint for '{served_id}' is already running. Ignoring start request.")
|
|
73
|
-
return
|
|
74
|
-
|
|
75
|
-
if not isinstance(config, AgentServerConfig):
|
|
76
|
-
raise TypeError("AgentServerConfig instance required to start AgentServerEndpoint.")
|
|
77
|
-
|
|
78
|
-
self._config = config
|
|
79
|
-
served_id_log = self._served_entity.agent_id if isinstance(self._served_entity, Agent) else f"multiple agents ({list(self._served_entity.keys())})" # type: ignore
|
|
80
|
-
logger.info(f"AgentServerEndpoint for '{served_id_log}' starting with config '{config.server_id}' (Transport: {config.transport_type.value}).")
|
|
81
|
-
|
|
82
|
-
if self._config.transport_type == TransportType.STDIO:
|
|
83
|
-
if not isinstance(self._served_entity, Agent):
|
|
84
|
-
raise ValueError("STDIO transport currently supports serving only a single Agent instance.")
|
|
85
|
-
single_agent_for_stdio: Agent = self._served_entity
|
|
86
|
-
|
|
87
|
-
if not self._stdio_handler: # Create handler if it doesn't exist
|
|
88
|
-
self._stdio_handler = StdioServerHandler(single_agent_for_stdio, self._method_handlers)
|
|
89
|
-
|
|
90
|
-
# Ensure task is not already running or is completed
|
|
91
|
-
if self._stdio_task and not self._stdio_task.done():
|
|
92
|
-
logger.warning(f"Stdio task for agent '{single_agent_for_stdio.agent_id}' seems to be already running. Not restarting.")
|
|
93
|
-
else:
|
|
94
|
-
self._stdio_task = asyncio.create_task(
|
|
95
|
-
self._stdio_handler.listen_and_dispatch(),
|
|
96
|
-
name=f"stdio_server_endpoint_{single_agent_for_stdio.agent_id}"
|
|
97
|
-
)
|
|
98
|
-
logger.info(f"Stdio transport for agent '{single_agent_for_stdio.agent_id}' started via StdioServerHandler.")
|
|
99
|
-
|
|
100
|
-
elif self._config.transport_type == TransportType.SSE:
|
|
101
|
-
agents_for_sse: Dict[str, Agent]
|
|
102
|
-
if isinstance(self._served_entity, Agent):
|
|
103
|
-
agents_for_sse = {self._served_entity.agent_id: self._served_entity}
|
|
104
|
-
logger.info(f"Serving single agent '{self._served_entity.agent_id}' via SSE under its own agent_id as the server key.")
|
|
105
|
-
elif isinstance(self._served_entity, dict):
|
|
106
|
-
agents_for_sse = self._served_entity
|
|
107
|
-
else:
|
|
108
|
-
raise ValueError("Invalid _served_entity type for SSE transport.")
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
if not self._sse_handler: # Create handler if it doesn't exist
|
|
112
|
-
self._sse_handler = SseServerHandler(agents_for_sse, self._method_handlers)
|
|
113
|
-
|
|
114
|
-
if self._sse_server_task and not self._sse_server_task.done():
|
|
115
|
-
logger.warning("SSE server task seems to be already running. Not restarting.")
|
|
116
|
-
else:
|
|
117
|
-
# SseServerHandler.start_server is a blocking call that runs the aiohttp server.
|
|
118
|
-
# It should be run in a task that this endpoint manages.
|
|
119
|
-
self._sse_server_task = asyncio.create_task(
|
|
120
|
-
self._sse_handler.start_server(config),
|
|
121
|
-
name=f"sse_server_endpoint_manager"
|
|
122
|
-
)
|
|
123
|
-
logger.info(f"SSE transport starting via SseServerHandler for agents: {list(agents_for_sse.keys())}.")
|
|
124
|
-
|
|
125
|
-
else:
|
|
126
|
-
logger.error(f"Unsupported transport type '{self._config.transport_type}' in AgentServerEndpoint.")
|
|
127
|
-
self._config = None # Reset config if start fails for this reason
|
|
128
|
-
raise NotImplementedError(f"Transport type '{self._config.transport_type}' not implemented.")
|
|
129
|
-
|
|
130
|
-
self._is_running = True
|
|
131
|
-
logger.info(f"AgentServerEndpoint for '{served_id_log}' started successfully.")
|
|
132
|
-
|
|
133
|
-
async def stop(self) -> None:
|
|
134
|
-
served_id_log = self._served_entity.agent_id if isinstance(self._served_entity, Agent) else f"multiple agents ({list(self._served_entity.keys())})" # type: ignore
|
|
135
|
-
if not self._is_running:
|
|
136
|
-
logger.warning(f"AgentServerEndpoint for '{served_id_log}' is not running. Ignoring stop request.")
|
|
137
|
-
return
|
|
138
|
-
|
|
139
|
-
logger.info(f"AgentServerEndpoint for '{served_id_log}' stopping...")
|
|
140
|
-
|
|
141
|
-
# Stop transport-specific handlers/tasks
|
|
142
|
-
if self._config and self._config.transport_type == TransportType.STDIO:
|
|
143
|
-
if self._stdio_handler: # StdioServerHandler manages its own _running flag
|
|
144
|
-
self._stdio_handler.stop() # Signal handler to stop listening
|
|
145
|
-
if self._stdio_task and not self._stdio_task.done():
|
|
146
|
-
self._stdio_task.cancel() # Cancel the listen_and_dispatch task
|
|
147
|
-
try: await self._stdio_task
|
|
148
|
-
except asyncio.CancelledError: logger.info(f"Stdio task for endpoint for '{served_id_log}' cancelled.")
|
|
149
|
-
except Exception as e: logger.error(f"Error awaiting stdio_task during stop: {e}", exc_info=True)
|
|
150
|
-
self._stdio_task = None
|
|
151
|
-
# self._stdio_handler = None # Handler can be reused if started again
|
|
152
|
-
logger.info(f"Stdio transport for endpoint '{served_id_log}' stopped.")
|
|
153
|
-
|
|
154
|
-
elif self._config and self._config.transport_type == TransportType.SSE:
|
|
155
|
-
if self._sse_handler: # SseServerHandler has its own stop_server method
|
|
156
|
-
await self._sse_handler.stop_server()
|
|
157
|
-
if self._sse_server_task and not self._sse_server_task.done():
|
|
158
|
-
# The sse_handler.stop_server() should ideally cause the task awaiting sse_handler.start_server() to complete.
|
|
159
|
-
# If start_server is not designed to unblock on stop_server, cancellation might be needed.
|
|
160
|
-
# Assuming start_server will handle cleanup and exit gracefully when stop_server is called.
|
|
161
|
-
# If not, explicit cancellation might be required here.
|
|
162
|
-
try:
|
|
163
|
-
# Give some time for graceful shutdown initiated by stop_server()
|
|
164
|
-
await asyncio.wait_for(self._sse_server_task, timeout=5.0)
|
|
165
|
-
except asyncio.TimeoutError:
|
|
166
|
-
logger.warning(f"Timeout waiting for SSE server task for '{served_id_log}' to complete. Cancelling.")
|
|
167
|
-
self._sse_server_task.cancel()
|
|
168
|
-
try: await self._sse_server_task
|
|
169
|
-
except asyncio.CancelledError: logger.info(f"SSE server task for endpoint '{served_id_log}' cancelled.")
|
|
170
|
-
except asyncio.CancelledError: # If already cancelled by internal logic
|
|
171
|
-
logger.info(f"SSE server task for endpoint '{served_id_log}' was already cancelled.")
|
|
172
|
-
except Exception as e: logger.error(f"Error awaiting sse_server_task during stop: {e}", exc_info=True)
|
|
173
|
-
|
|
174
|
-
self._sse_server_task = None
|
|
175
|
-
# self._sse_handler = None # Handler can be reused
|
|
176
|
-
logger.info(f"SSE transport for endpoint '{served_id_log}' stopped.")
|
|
177
|
-
|
|
178
|
-
self._is_running = False
|
|
179
|
-
self._config = None # Clear current config
|
|
180
|
-
logger.info(f"AgentServerEndpoint for '{served_id_log}' stopped successfully.")
|
|
181
|
-
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
# file: autobyteus/autobyteus/rpc/server/base_method_handler.py
|
|
2
|
-
import logging
|
|
3
|
-
from abc import ABC, abstractmethod
|
|
4
|
-
from typing import Optional, Dict, Any, TYPE_CHECKING
|
|
5
|
-
|
|
6
|
-
from autobyteus.rpc.protocol import ProtocolMessage
|
|
7
|
-
|
|
8
|
-
if TYPE_CHECKING:
|
|
9
|
-
from autobyteus.agent.agent import Agent # Changed from AgentRuntime to Agent
|
|
10
|
-
|
|
11
|
-
logger = logging.getLogger(__name__)
|
|
12
|
-
|
|
13
|
-
class BaseMethodHandler(ABC):
|
|
14
|
-
"""
|
|
15
|
-
Abstract base class for handlers of specific RPC methods on the Agent Server.
|
|
16
|
-
"""
|
|
17
|
-
|
|
18
|
-
@abstractmethod
|
|
19
|
-
async def handle(self,
|
|
20
|
-
request_id: Optional[str],
|
|
21
|
-
params: Optional[Dict[str, Any]],
|
|
22
|
-
agent: 'Agent') -> ProtocolMessage: # Changed from runtime: AgentRuntime to agent: Agent
|
|
23
|
-
"""
|
|
24
|
-
Handles an RPC method call.
|
|
25
|
-
|
|
26
|
-
Args:
|
|
27
|
-
request_id: The ID of the incoming request message. Used for the response.
|
|
28
|
-
params: The parameters provided with the RPC method call.
|
|
29
|
-
agent: The Agent instance being served. This provides access to the
|
|
30
|
-
agent's public API, context, queues, status, etc.
|
|
31
|
-
|
|
32
|
-
Returns:
|
|
33
|
-
A ProtocolMessage representing the response (success or error) to be sent
|
|
34
|
-
back to the client.
|
|
35
|
-
"""
|
|
36
|
-
raise NotImplementedError
|
|
37
|
-
|
|
38
|
-
def __repr__(self) -> str:
|
|
39
|
-
return f"<{self.__class__.__name__}>"
|
|
40
|
-
|
|
@@ -1,259 +0,0 @@
|
|
|
1
|
-
# file: autobyteus/autobyteus/rpc/server/method_handlers.py
|
|
2
|
-
import logging
|
|
3
|
-
from typing import Optional, Dict, Any, List, Callable, Awaitable, Tuple
|
|
4
|
-
|
|
5
|
-
from autobyteus.rpc.protocol import ProtocolMessage, MessageType, RequestType, ResponseType, ErrorCode
|
|
6
|
-
from autobyteus.rpc.server.base_method_handler import BaseMethodHandler
|
|
7
|
-
from autobyteus.agent.agent import Agent
|
|
8
|
-
from autobyteus.agent.message.agent_input_user_message import AgentInputUserMessage
|
|
9
|
-
from autobyteus.agent.message.inter_agent_message import InterAgentMessage
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
logger = logging.getLogger(__name__)
|
|
13
|
-
|
|
14
|
-
class DiscoverCapabilitiesHandler(BaseMethodHandler):
|
|
15
|
-
"""
|
|
16
|
-
Handles the 'discover_capabilities' RPC method.
|
|
17
|
-
Responds with the agent's ID, definition details, supported methods, and status,
|
|
18
|
-
obtained via the Agent's public interface/context.
|
|
19
|
-
"""
|
|
20
|
-
async def handle(self,
|
|
21
|
-
request_id: Optional[str],
|
|
22
|
-
params: Optional[Dict[str, Any]],
|
|
23
|
-
agent: Agent) -> ProtocolMessage:
|
|
24
|
-
logger.debug(f"DiscoverCapabilitiesHandler: Handling request_id '{request_id}' for agent '{agent.agent_id}'.")
|
|
25
|
-
try:
|
|
26
|
-
# Define capabilities, including the new stream download initiation method
|
|
27
|
-
capabilities = {
|
|
28
|
-
"post_user_message": {
|
|
29
|
-
"description": "Posts a message from an external user to the agent.",
|
|
30
|
-
"params": {"agent_input_user_message": "dict (serialized AgentInputUserMessage)"}
|
|
31
|
-
},
|
|
32
|
-
"post_inter_agent_message": {
|
|
33
|
-
"description": "Posts a message from another agent.",
|
|
34
|
-
"params": {"inter_agent_message": "dict (serialized InterAgentMessage)"}
|
|
35
|
-
},
|
|
36
|
-
"post_tool_execution_approval": {
|
|
37
|
-
"description": "Provides approval or denial for a pending tool execution.",
|
|
38
|
-
"params": {"tool_invocation_id": "str", "is_approved": "bool", "reason": "Optional[str]"}
|
|
39
|
-
},
|
|
40
|
-
"get_status": {
|
|
41
|
-
"description": "Gets the current operational status of the agent.",
|
|
42
|
-
"params": None
|
|
43
|
-
},
|
|
44
|
-
# No specific invoke method for REQUEST_STREAM_DOWNLOAD, it's a top-level RequestType handled by its own handler.
|
|
45
|
-
# However, if it were invoked via InvokeMethod, it would be listed here.
|
|
46
|
-
# For clarity, methods invokable via InvokeMethodHandler are listed.
|
|
47
|
-
# REQUEST_STREAM_DOWNLOAD will be handled by InitiateStreamDownloadHandler directly.
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
if not agent.context:
|
|
51
|
-
logger.error(f"Agent '{agent.agent_id}' context is None. Cannot discover capabilities.")
|
|
52
|
-
return ProtocolMessage.create_error_response(
|
|
53
|
-
id=request_id,
|
|
54
|
-
code=ErrorCode.SERVER_ERROR_CAPABILITY_DISCOVERY_FAILED,
|
|
55
|
-
message="Agent context not available."
|
|
56
|
-
)
|
|
57
|
-
|
|
58
|
-
# Explicitly list RequestTypes that this server (potentially) handles
|
|
59
|
-
# This part of discover_capabilities might need to be more dynamic or list top-level RPC methods
|
|
60
|
-
# rather than just methods invokable via InvokeMethodHandler.
|
|
61
|
-
# For now, assume InvokeMethodHandler is the primary way to call agent functions.
|
|
62
|
-
# The fact that REQUEST_STREAM_DOWNLOAD exists is a server capability.
|
|
63
|
-
supported_rpc_request_types = [rt.value for rt in RequestType]
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
result_data = {
|
|
67
|
-
"agent_id": agent.agent_id,
|
|
68
|
-
"agent_name": agent.context.definition.name,
|
|
69
|
-
"agent_role": agent.context.definition.role,
|
|
70
|
-
"agent_description": agent.context.definition.description,
|
|
71
|
-
"supported_rpc_request_types": supported_rpc_request_types, # Top-level RPC methods
|
|
72
|
-
"invokable_methods_details": capabilities, # Methods callable via 'invoke_method'
|
|
73
|
-
"status": agent.get_status().value,
|
|
74
|
-
"system_prompt_summary": agent.context.definition.system_prompt[:200] + "..." if len(agent.context.definition.system_prompt) > 200 else agent.context.definition.system_prompt,
|
|
75
|
-
"tool_names": agent.context.definition.tool_names,
|
|
76
|
-
}
|
|
77
|
-
return ProtocolMessage.create_response(
|
|
78
|
-
id=request_id,
|
|
79
|
-
result=result_data,
|
|
80
|
-
response_type=ResponseType.CAPABILITIES_RESPONSE
|
|
81
|
-
)
|
|
82
|
-
except Exception as e:
|
|
83
|
-
logger.error(f"Error in DiscoverCapabilitiesHandler for agent '{agent.agent_id}': {e}", exc_info=True)
|
|
84
|
-
return ProtocolMessage.create_error_response(
|
|
85
|
-
id=request_id,
|
|
86
|
-
code=ErrorCode.SERVER_ERROR_CAPABILITY_DISCOVERY_FAILED,
|
|
87
|
-
message=f"Failed to discover capabilities: {e}"
|
|
88
|
-
)
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
class InvokeMethodHandler(BaseMethodHandler):
|
|
92
|
-
"""
|
|
93
|
-
Handles the 'invoke_method' RPC method.
|
|
94
|
-
It dispatches to public methods of the Agent instance based on 'method_name'.
|
|
95
|
-
"""
|
|
96
|
-
|
|
97
|
-
def __init__(self):
|
|
98
|
-
# Map method names to Agent's public API methods (or wrappers around them)
|
|
99
|
-
self._method_map: Dict[str, Callable[[Optional[str], Dict[str, Any], Agent], Awaitable[ProtocolMessage]]] = {
|
|
100
|
-
"post_user_message": self._handle_post_user_message,
|
|
101
|
-
"post_inter_agent_message": self._handle_post_inter_agent_message,
|
|
102
|
-
"post_tool_execution_approval": self._handle_post_tool_execution_approval,
|
|
103
|
-
"get_status": self._handle_get_status,
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
async def handle(self,
|
|
107
|
-
request_id: Optional[str],
|
|
108
|
-
params: Optional[Dict[str, Any]],
|
|
109
|
-
agent: Agent) -> ProtocolMessage:
|
|
110
|
-
if not params or "method_name" not in params:
|
|
111
|
-
return ProtocolMessage.create_error_response(
|
|
112
|
-
id=request_id,
|
|
113
|
-
code=ErrorCode.INVALID_PARAMS,
|
|
114
|
-
message="'method_name' is required in params for invoke_method."
|
|
115
|
-
)
|
|
116
|
-
|
|
117
|
-
method_name = params["method_name"]
|
|
118
|
-
method_params = params.get("method_params", {})
|
|
119
|
-
|
|
120
|
-
logger.debug(f"InvokeMethodHandler: Handling method '{method_name}' for agent '{agent.agent_id}' with request_id '{request_id}'.")
|
|
121
|
-
|
|
122
|
-
handler_func = self._method_map.get(method_name)
|
|
123
|
-
if not handler_func:
|
|
124
|
-
return ProtocolMessage.create_error_response(
|
|
125
|
-
id=request_id,
|
|
126
|
-
code=ErrorCode.METHOD_NOT_FOUND,
|
|
127
|
-
message=f"Method '{method_name}' is not supported by this agent server for invocation via InvokeMethodHandler."
|
|
128
|
-
)
|
|
129
|
-
|
|
130
|
-
try:
|
|
131
|
-
return await handler_func(request_id, method_params, agent)
|
|
132
|
-
except Exception as e:
|
|
133
|
-
logger.error(f"Error invoking method '{method_name}' on agent '{agent.agent_id}': {e}", exc_info=True)
|
|
134
|
-
return ProtocolMessage.create_error_response(
|
|
135
|
-
id=request_id,
|
|
136
|
-
code=ErrorCode.SERVER_ERROR_AGENT_PROCESSING_FAILED,
|
|
137
|
-
message=f"Error processing method '{method_name}': {e}"
|
|
138
|
-
)
|
|
139
|
-
|
|
140
|
-
async def _handle_post_user_message(self, request_id: Optional[str], params: Dict[str, Any], agent: Agent) -> ProtocolMessage:
|
|
141
|
-
serialized_msg = params.get("agent_input_user_message")
|
|
142
|
-
if not isinstance(serialized_msg, dict):
|
|
143
|
-
return ProtocolMessage.create_error_response(request_id, ErrorCode.INVALID_PARAMS, "'agent_input_user_message' (dict) parameter is required.")
|
|
144
|
-
|
|
145
|
-
try:
|
|
146
|
-
user_message = AgentInputUserMessage.from_dict(serialized_msg)
|
|
147
|
-
except (ValueError, TypeError) as e:
|
|
148
|
-
return ProtocolMessage.create_error_response(request_id, ErrorCode.INVALID_PARAMS, f"Invalid 'agent_input_user_message' structure: {e}")
|
|
149
|
-
|
|
150
|
-
await agent.post_user_message(user_message)
|
|
151
|
-
logger.info(f"Agent '{agent.agent_id}' (via RPC): Called agent.post_user_message().")
|
|
152
|
-
return ProtocolMessage.create_response(request_id, {"status": "User message posted to agent"}, ResponseType.ACKNOWLEDGEMENT)
|
|
153
|
-
|
|
154
|
-
async def _handle_post_inter_agent_message(self, request_id: Optional[str], params: Dict[str, Any], agent: Agent) -> ProtocolMessage:
|
|
155
|
-
serialized_msg = params.get("inter_agent_message")
|
|
156
|
-
if not isinstance(serialized_msg, dict):
|
|
157
|
-
return ProtocolMessage.create_error_response(request_id, ErrorCode.INVALID_PARAMS, "'inter_agent_message' (dict) parameter is required.")
|
|
158
|
-
|
|
159
|
-
try:
|
|
160
|
-
msg_type_str = serialized_msg.get("message_type")
|
|
161
|
-
if not msg_type_str: raise ValueError("message_type missing")
|
|
162
|
-
|
|
163
|
-
inter_agent_msg = InterAgentMessage.create_with_dynamic_message_type(
|
|
164
|
-
recipient_role_name=serialized_msg.get("recipient_role_name"),
|
|
165
|
-
recipient_agent_id=serialized_msg.get("recipient_agent_id"),
|
|
166
|
-
content=serialized_msg.get("content"),
|
|
167
|
-
message_type=msg_type_str,
|
|
168
|
-
sender_agent_id=serialized_msg.get("sender_agent_id")
|
|
169
|
-
)
|
|
170
|
-
except (ValueError, TypeError) as e:
|
|
171
|
-
return ProtocolMessage.create_error_response(request_id, ErrorCode.INVALID_PARAMS, f"Invalid 'inter_agent_message' structure: {e}")
|
|
172
|
-
|
|
173
|
-
await agent.post_inter_agent_message(inter_agent_msg)
|
|
174
|
-
logger.info(f"Agent '{agent.agent_id}' (via RPC): Called agent.post_inter_agent_message() from '{inter_agent_msg.sender_agent_id}'.")
|
|
175
|
-
return ProtocolMessage.create_response(request_id, {"status": "Inter-agent message posted to agent"}, ResponseType.ACKNOWLEDGEMENT)
|
|
176
|
-
|
|
177
|
-
async def _handle_post_tool_execution_approval(self, request_id: Optional[str], params: Dict[str, Any], agent: Agent) -> ProtocolMessage:
|
|
178
|
-
tool_invocation_id = params.get("tool_invocation_id")
|
|
179
|
-
is_approved = params.get("is_approved")
|
|
180
|
-
reason = params.get("reason")
|
|
181
|
-
|
|
182
|
-
if not isinstance(tool_invocation_id, str) or not tool_invocation_id:
|
|
183
|
-
return ProtocolMessage.create_error_response(request_id, ErrorCode.INVALID_PARAMS, "'tool_invocation_id' (str) is required.")
|
|
184
|
-
if not isinstance(is_approved, bool):
|
|
185
|
-
return ProtocolMessage.create_error_response(request_id, ErrorCode.INVALID_PARAMS, "'is_approved' (bool) is required.")
|
|
186
|
-
if reason is not None and not isinstance(reason, str):
|
|
187
|
-
return ProtocolMessage.create_error_response(request_id, ErrorCode.INVALID_PARAMS, "'reason' must be a string if provided.")
|
|
188
|
-
|
|
189
|
-
await agent.post_tool_execution_approval(tool_invocation_id, is_approved, reason)
|
|
190
|
-
status_str = "approved" if is_approved else "denied"
|
|
191
|
-
logger.info(f"Agent '{agent.agent_id}' (via RPC): Called agent.post_tool_execution_approval() for id '{tool_invocation_id}' ({status_str}).")
|
|
192
|
-
return ProtocolMessage.create_response(request_id, {"status": f"Tool approval ({status_str}) posted to agent"}, ResponseType.ACKNOWLEDGEMENT)
|
|
193
|
-
|
|
194
|
-
async def _handle_get_status(self, request_id: Optional[str], params: Dict[str, Any], agent: Agent) -> ProtocolMessage:
|
|
195
|
-
status_value = agent.get_status().value
|
|
196
|
-
logger.debug(f"Agent '{agent.agent_id}' (via RPC): Current status is '{status_value}'.")
|
|
197
|
-
return ProtocolMessage.create_response(request_id, {"status": status_value, "agent_id": agent.agent_id})
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
class InitiateStreamDownloadHandler(BaseMethodHandler):
|
|
201
|
-
"""
|
|
202
|
-
Handles the 'request_stream_download' RPC method.
|
|
203
|
-
Interacts with the agent to prepare a streamable resource and returns
|
|
204
|
-
information required by the client to download it, including a stream_id.
|
|
205
|
-
The SseServerHandler will augment this response with the full download URL.
|
|
206
|
-
"""
|
|
207
|
-
async def handle(self,
|
|
208
|
-
request_id: Optional[str],
|
|
209
|
-
params: Optional[Dict[str, Any]],
|
|
210
|
-
agent: Agent) -> ProtocolMessage:
|
|
211
|
-
logger.debug(f"InitiateStreamDownloadHandler: Handling request_id '{request_id}' for agent '{agent.agent_id}' with params: {params}.")
|
|
212
|
-
if not params:
|
|
213
|
-
return ProtocolMessage.create_error_response(
|
|
214
|
-
id=request_id,
|
|
215
|
-
code=ErrorCode.INVALID_PARAMS,
|
|
216
|
-
message="Parameters are required for requesting a stream download (e.g., resource identifier)."
|
|
217
|
-
)
|
|
218
|
-
|
|
219
|
-
try:
|
|
220
|
-
# Agent must implement `prepare_resource_for_streaming`
|
|
221
|
-
# This method is conceptual; actual signature might vary.
|
|
222
|
-
# It should return (stream_id: str, metadata: Dict[str, Any])
|
|
223
|
-
# The agent becomes responsible for managing the lifecycle of this stream_id
|
|
224
|
-
# and providing data when get_stream_data(stream_id) is called by SseServerHandler.
|
|
225
|
-
if not hasattr(agent, "prepare_resource_for_streaming"):
|
|
226
|
-
logger.error(f"Agent '{agent.agent_id}' does not support 'prepare_resource_for_streaming'.")
|
|
227
|
-
return ProtocolMessage.create_error_response(
|
|
228
|
-
id=request_id,
|
|
229
|
-
code=ErrorCode.METHOD_NOT_FOUND,
|
|
230
|
-
message=f"Agent '{agent.agent_id}' cannot prepare streamable resources."
|
|
231
|
-
)
|
|
232
|
-
|
|
233
|
-
# Type hint for clarity if agent method is known
|
|
234
|
-
# stream_id, metadata = await agent.prepare_resource_for_streaming(params)
|
|
235
|
-
stream_preparation_result: Tuple[str, Dict[str, Any]] = await agent.prepare_resource_for_streaming(params)
|
|
236
|
-
stream_id, metadata = stream_preparation_result
|
|
237
|
-
|
|
238
|
-
logger.info(f"Agent '{agent.agent_id}' prepared stream_id '{stream_id}' for request_id '{request_id}'.")
|
|
239
|
-
|
|
240
|
-
# The SseServerHandler will add the 'download_url' to this result later
|
|
241
|
-
# agent_id_on_server is also added by SseServerHandler for constructing the URL
|
|
242
|
-
result_payload = {
|
|
243
|
-
"stream_id": stream_id,
|
|
244
|
-
"metadata": metadata,
|
|
245
|
-
# "agent_id_on_server": agent.agent_id # Or the server_key if different. SseServerHandler knows this.
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
return ProtocolMessage.create_response(
|
|
249
|
-
id=request_id,
|
|
250
|
-
result=result_payload,
|
|
251
|
-
response_type=ResponseType.STREAM_DOWNLOAD_READY
|
|
252
|
-
)
|
|
253
|
-
except Exception as e:
|
|
254
|
-
logger.error(f"Error in InitiateStreamDownloadHandler for agent '{agent.agent_id}': {e}", exc_info=True)
|
|
255
|
-
return ProtocolMessage.create_error_response(
|
|
256
|
-
id=request_id,
|
|
257
|
-
code=ErrorCode.SERVER_ERROR_STREAM_PREPARATION_FAILED,
|
|
258
|
-
message=f"Agent failed to prepare stream: {e}"
|
|
259
|
-
)
|