autobyteus 1.2.0__py3-none-any.whl → 1.2.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- autobyteus/agent/agent.py +15 -5
- autobyteus/agent/bootstrap_steps/__init__.py +1 -3
- autobyteus/agent/bootstrap_steps/agent_bootstrapper.py +3 -59
- autobyteus/agent/bootstrap_steps/base_bootstrap_step.py +1 -4
- autobyteus/agent/bootstrap_steps/mcp_server_prewarming_step.py +1 -3
- autobyteus/agent/bootstrap_steps/system_prompt_processing_step.py +16 -13
- autobyteus/agent/bootstrap_steps/workspace_context_initialization_step.py +2 -4
- autobyteus/agent/context/agent_config.py +43 -20
- autobyteus/agent/context/agent_context.py +23 -18
- autobyteus/agent/context/agent_runtime_state.py +23 -19
- autobyteus/agent/events/__init__.py +16 -1
- autobyteus/agent/events/agent_events.py +43 -3
- autobyteus/agent/events/agent_input_event_queue_manager.py +79 -26
- autobyteus/agent/events/event_store.py +57 -0
- autobyteus/agent/events/notifiers.py +74 -60
- autobyteus/agent/events/worker_event_dispatcher.py +21 -64
- autobyteus/agent/factory/agent_factory.py +52 -0
- autobyteus/agent/handlers/__init__.py +2 -0
- autobyteus/agent/handlers/approved_tool_invocation_event_handler.py +51 -34
- autobyteus/agent/handlers/bootstrap_event_handler.py +155 -0
- autobyteus/agent/handlers/inter_agent_message_event_handler.py +10 -0
- autobyteus/agent/handlers/lifecycle_event_logger.py +19 -11
- autobyteus/agent/handlers/llm_complete_response_received_event_handler.py +10 -15
- autobyteus/agent/handlers/llm_user_message_ready_event_handler.py +188 -48
- autobyteus/agent/handlers/tool_execution_approval_event_handler.py +0 -10
- autobyteus/agent/handlers/tool_invocation_request_event_handler.py +53 -48
- autobyteus/agent/handlers/tool_result_event_handler.py +7 -8
- autobyteus/agent/handlers/user_input_message_event_handler.py +10 -3
- autobyteus/agent/input_processor/memory_ingest_input_processor.py +40 -0
- autobyteus/agent/lifecycle/__init__.py +12 -0
- autobyteus/agent/lifecycle/base_processor.py +109 -0
- autobyteus/agent/lifecycle/events.py +35 -0
- autobyteus/agent/lifecycle/processor_definition.py +36 -0
- autobyteus/agent/lifecycle/processor_registry.py +106 -0
- autobyteus/agent/llm_request_assembler.py +98 -0
- autobyteus/agent/llm_response_processor/__init__.py +1 -8
- autobyteus/agent/message/context_file_type.py +1 -1
- autobyteus/agent/message/send_message_to.py +5 -4
- autobyteus/agent/runtime/agent_runtime.py +29 -21
- autobyteus/agent/runtime/agent_worker.py +98 -19
- autobyteus/agent/shutdown_steps/__init__.py +2 -0
- autobyteus/agent/shutdown_steps/agent_shutdown_orchestrator.py +2 -0
- autobyteus/agent/shutdown_steps/tool_cleanup_step.py +58 -0
- autobyteus/agent/status/__init__.py +14 -0
- autobyteus/agent/status/manager.py +93 -0
- autobyteus/agent/status/status_deriver.py +96 -0
- autobyteus/agent/{phases/phase_enum.py → status/status_enum.py} +16 -16
- autobyteus/agent/status/status_update_utils.py +73 -0
- autobyteus/agent/streaming/__init__.py +52 -5
- autobyteus/agent/streaming/adapters/__init__.py +18 -0
- autobyteus/agent/streaming/adapters/invocation_adapter.py +184 -0
- autobyteus/agent/streaming/adapters/tool_call_parsing.py +163 -0
- autobyteus/agent/streaming/adapters/tool_syntax_registry.py +67 -0
- autobyteus/agent/streaming/agent_event_stream.py +3 -178
- autobyteus/agent/streaming/api_tool_call/__init__.py +16 -0
- autobyteus/agent/streaming/api_tool_call/file_content_streamer.py +56 -0
- autobyteus/agent/streaming/api_tool_call/json_string_field_extractor.py +175 -0
- autobyteus/agent/streaming/api_tool_call_streaming_response_handler.py +4 -0
- autobyteus/agent/streaming/events/__init__.py +6 -0
- autobyteus/agent/streaming/events/stream_event_payloads.py +284 -0
- autobyteus/agent/streaming/events/stream_events.py +141 -0
- autobyteus/agent/streaming/handlers/__init__.py +15 -0
- autobyteus/agent/streaming/handlers/api_tool_call_streaming_response_handler.py +303 -0
- autobyteus/agent/streaming/handlers/parsing_streaming_response_handler.py +107 -0
- autobyteus/agent/streaming/handlers/pass_through_streaming_response_handler.py +107 -0
- autobyteus/agent/streaming/handlers/streaming_handler_factory.py +177 -0
- autobyteus/agent/streaming/handlers/streaming_response_handler.py +58 -0
- autobyteus/agent/streaming/parser/__init__.py +61 -0
- autobyteus/agent/streaming/parser/event_emitter.py +181 -0
- autobyteus/agent/streaming/parser/events.py +4 -0
- autobyteus/agent/streaming/parser/invocation_adapter.py +4 -0
- autobyteus/agent/streaming/parser/json_parsing_strategies/__init__.py +19 -0
- autobyteus/agent/streaming/parser/json_parsing_strategies/base.py +32 -0
- autobyteus/agent/streaming/parser/json_parsing_strategies/default.py +34 -0
- autobyteus/agent/streaming/parser/json_parsing_strategies/gemini.py +31 -0
- autobyteus/agent/streaming/parser/json_parsing_strategies/openai.py +64 -0
- autobyteus/agent/streaming/parser/json_parsing_strategies/registry.py +75 -0
- autobyteus/agent/streaming/parser/parser_context.py +227 -0
- autobyteus/agent/streaming/parser/parser_factory.py +132 -0
- autobyteus/agent/streaming/parser/sentinel_format.py +7 -0
- autobyteus/agent/streaming/parser/state_factory.py +62 -0
- autobyteus/agent/streaming/parser/states/__init__.py +1 -0
- autobyteus/agent/streaming/parser/states/base_state.py +60 -0
- autobyteus/agent/streaming/parser/states/custom_xml_tag_run_bash_parsing_state.py +38 -0
- autobyteus/agent/streaming/parser/states/custom_xml_tag_write_file_parsing_state.py +55 -0
- autobyteus/agent/streaming/parser/states/delimited_content_state.py +146 -0
- autobyteus/agent/streaming/parser/states/json_initialization_state.py +144 -0
- autobyteus/agent/streaming/parser/states/json_tool_parsing_state.py +137 -0
- autobyteus/agent/streaming/parser/states/sentinel_content_state.py +30 -0
- autobyteus/agent/streaming/parser/states/sentinel_initialization_state.py +117 -0
- autobyteus/agent/streaming/parser/states/text_state.py +78 -0
- autobyteus/agent/streaming/parser/states/xml_patch_file_tool_parsing_state.py +328 -0
- autobyteus/agent/streaming/parser/states/xml_run_bash_tool_parsing_state.py +129 -0
- autobyteus/agent/streaming/parser/states/xml_tag_initialization_state.py +151 -0
- autobyteus/agent/streaming/parser/states/xml_tool_parsing_state.py +63 -0
- autobyteus/agent/streaming/parser/states/xml_write_file_tool_parsing_state.py +343 -0
- autobyteus/agent/streaming/parser/strategies/__init__.py +17 -0
- autobyteus/agent/streaming/parser/strategies/base.py +24 -0
- autobyteus/agent/streaming/parser/strategies/json_tool_strategy.py +26 -0
- autobyteus/agent/streaming/parser/strategies/registry.py +28 -0
- autobyteus/agent/streaming/parser/strategies/sentinel_strategy.py +23 -0
- autobyteus/agent/streaming/parser/strategies/xml_tag_strategy.py +21 -0
- autobyteus/agent/streaming/parser/stream_scanner.py +167 -0
- autobyteus/agent/streaming/parser/streaming_parser.py +212 -0
- autobyteus/agent/streaming/parser/tool_call_parsing.py +4 -0
- autobyteus/agent/streaming/parser/tool_constants.py +7 -0
- autobyteus/agent/streaming/parser/tool_syntax_registry.py +4 -0
- autobyteus/agent/streaming/parser/xml_tool_parsing_state_registry.py +55 -0
- autobyteus/agent/streaming/parsing_streaming_response_handler.py +4 -0
- autobyteus/agent/streaming/pass_through_streaming_response_handler.py +4 -0
- autobyteus/agent/streaming/queue_streamer.py +3 -57
- autobyteus/agent/streaming/segments/__init__.py +5 -0
- autobyteus/agent/streaming/segments/segment_events.py +81 -0
- autobyteus/agent/streaming/stream_event_payloads.py +2 -198
- autobyteus/agent/streaming/stream_events.py +3 -128
- autobyteus/agent/streaming/streaming_handler_factory.py +4 -0
- autobyteus/agent/streaming/streaming_response_handler.py +4 -0
- autobyteus/agent/streaming/streams/__init__.py +5 -0
- autobyteus/agent/streaming/streams/agent_event_stream.py +197 -0
- autobyteus/agent/streaming/utils/__init__.py +5 -0
- autobyteus/agent/streaming/utils/queue_streamer.py +59 -0
- autobyteus/agent/system_prompt_processor/__init__.py +2 -0
- autobyteus/agent/system_prompt_processor/available_skills_processor.py +96 -0
- autobyteus/agent/system_prompt_processor/base_processor.py +1 -1
- autobyteus/agent/system_prompt_processor/processor_meta.py +15 -2
- autobyteus/agent/system_prompt_processor/tool_manifest_injector_processor.py +39 -58
- autobyteus/agent/token_budget.py +56 -0
- autobyteus/agent/tool_execution_result_processor/memory_ingest_tool_result_processor.py +29 -0
- autobyteus/agent/tool_invocation.py +16 -40
- autobyteus/agent/tool_invocation_preprocessor/__init__.py +9 -0
- autobyteus/agent/tool_invocation_preprocessor/base_preprocessor.py +45 -0
- autobyteus/agent/tool_invocation_preprocessor/processor_definition.py +15 -0
- autobyteus/agent/tool_invocation_preprocessor/processor_meta.py +33 -0
- autobyteus/agent/tool_invocation_preprocessor/processor_registry.py +60 -0
- autobyteus/agent/utils/wait_for_idle.py +12 -14
- autobyteus/agent/workspace/base_workspace.py +6 -27
- autobyteus/agent_team/agent_team.py +3 -3
- autobyteus/agent_team/agent_team_builder.py +1 -41
- autobyteus/agent_team/bootstrap_steps/__init__.py +0 -4
- autobyteus/agent_team/bootstrap_steps/agent_configuration_preparation_step.py +8 -18
- autobyteus/agent_team/bootstrap_steps/agent_team_bootstrapper.py +4 -16
- autobyteus/agent_team/bootstrap_steps/base_agent_team_bootstrap_step.py +1 -2
- autobyteus/agent_team/bootstrap_steps/coordinator_initialization_step.py +1 -2
- autobyteus/agent_team/bootstrap_steps/task_notifier_initialization_step.py +5 -6
- autobyteus/agent_team/bootstrap_steps/team_context_initialization_step.py +15 -15
- autobyteus/agent_team/context/agent_team_config.py +6 -3
- autobyteus/agent_team/context/agent_team_context.py +25 -3
- autobyteus/agent_team/context/agent_team_runtime_state.py +11 -8
- autobyteus/agent_team/events/__init__.py +11 -0
- autobyteus/agent_team/events/agent_team_event_dispatcher.py +22 -9
- autobyteus/agent_team/events/agent_team_events.py +16 -0
- autobyteus/agent_team/events/event_store.py +57 -0
- autobyteus/agent_team/factory/agent_team_factory.py +8 -0
- autobyteus/agent_team/handlers/inter_agent_message_request_event_handler.py +18 -2
- autobyteus/agent_team/handlers/lifecycle_agent_team_event_handler.py +21 -5
- autobyteus/agent_team/handlers/process_user_message_event_handler.py +17 -8
- autobyteus/agent_team/handlers/tool_approval_team_event_handler.py +19 -4
- autobyteus/agent_team/runtime/agent_team_runtime.py +41 -10
- autobyteus/agent_team/runtime/agent_team_worker.py +69 -5
- autobyteus/agent_team/status/__init__.py +14 -0
- autobyteus/agent_team/status/agent_team_status.py +18 -0
- autobyteus/agent_team/status/agent_team_status_manager.py +33 -0
- autobyteus/agent_team/status/status_deriver.py +62 -0
- autobyteus/agent_team/status/status_update_utils.py +42 -0
- autobyteus/agent_team/streaming/__init__.py +2 -2
- autobyteus/agent_team/streaming/agent_team_event_notifier.py +10 -10
- autobyteus/agent_team/streaming/agent_team_stream_event_payloads.py +7 -7
- autobyteus/agent_team/streaming/agent_team_stream_events.py +11 -11
- autobyteus/agent_team/system_prompt_processor/__init__.py +6 -0
- autobyteus/agent_team/system_prompt_processor/team_manifest_injector_processor.py +76 -0
- autobyteus/agent_team/task_notification/activation_policy.py +1 -1
- autobyteus/agent_team/task_notification/system_event_driven_agent_task_notifier.py +22 -22
- autobyteus/agent_team/task_notification/task_notification_mode.py +20 -1
- autobyteus/agent_team/utils/wait_for_idle.py +4 -4
- autobyteus/cli/agent_cli.py +18 -10
- autobyteus/cli/agent_team_tui/app.py +18 -15
- autobyteus/cli/agent_team_tui/state.py +21 -23
- autobyteus/cli/agent_team_tui/widgets/agent_list_sidebar.py +15 -15
- autobyteus/cli/agent_team_tui/widgets/focus_pane.py +146 -39
- autobyteus/cli/agent_team_tui/widgets/renderables.py +1 -1
- autobyteus/cli/agent_team_tui/widgets/shared.py +26 -26
- autobyteus/cli/agent_team_tui/widgets/{task_board_panel.py → task_plan_panel.py} +5 -5
- autobyteus/cli/cli_display.py +193 -44
- autobyteus/cli/workflow_tui/app.py +9 -10
- autobyteus/cli/workflow_tui/state.py +14 -16
- autobyteus/cli/workflow_tui/widgets/agent_list_sidebar.py +15 -15
- autobyteus/cli/workflow_tui/widgets/focus_pane.py +137 -35
- autobyteus/cli/workflow_tui/widgets/renderables.py +1 -1
- autobyteus/cli/workflow_tui/widgets/shared.py +25 -25
- autobyteus/clients/autobyteus_client.py +94 -1
- autobyteus/events/event_types.py +15 -21
- autobyteus/llm/api/autobyteus_llm.py +33 -29
- autobyteus/llm/api/claude_llm.py +142 -36
- autobyteus/llm/api/gemini_llm.py +163 -59
- autobyteus/llm/api/grok_llm.py +1 -1
- autobyteus/llm/api/minimax_llm.py +26 -0
- autobyteus/llm/api/mistral_llm.py +113 -87
- autobyteus/llm/api/ollama_llm.py +9 -42
- autobyteus/llm/api/openai_compatible_llm.py +127 -91
- autobyteus/llm/api/openai_llm.py +3 -3
- autobyteus/llm/api/openai_responses_llm.py +324 -0
- autobyteus/llm/api/zhipu_llm.py +21 -2
- autobyteus/llm/autobyteus_provider.py +70 -60
- autobyteus/llm/base_llm.py +85 -81
- autobyteus/llm/converters/__init__.py +14 -0
- autobyteus/llm/converters/anthropic_tool_call_converter.py +37 -0
- autobyteus/llm/converters/gemini_tool_call_converter.py +57 -0
- autobyteus/llm/converters/mistral_tool_call_converter.py +37 -0
- autobyteus/llm/converters/openai_tool_call_converter.py +38 -0
- autobyteus/llm/extensions/base_extension.py +6 -12
- autobyteus/llm/extensions/token_usage_tracking_extension.py +45 -18
- autobyteus/llm/llm_factory.py +282 -204
- autobyteus/llm/lmstudio_provider.py +60 -49
- autobyteus/llm/models.py +35 -2
- autobyteus/llm/ollama_provider.py +60 -49
- autobyteus/llm/ollama_provider_resolver.py +0 -1
- autobyteus/llm/prompt_renderers/__init__.py +19 -0
- autobyteus/llm/prompt_renderers/anthropic_prompt_renderer.py +104 -0
- autobyteus/llm/prompt_renderers/autobyteus_prompt_renderer.py +19 -0
- autobyteus/llm/prompt_renderers/base_prompt_renderer.py +10 -0
- autobyteus/llm/prompt_renderers/gemini_prompt_renderer.py +63 -0
- autobyteus/llm/prompt_renderers/mistral_prompt_renderer.py +87 -0
- autobyteus/llm/prompt_renderers/ollama_prompt_renderer.py +51 -0
- autobyteus/llm/prompt_renderers/openai_chat_renderer.py +97 -0
- autobyteus/llm/prompt_renderers/openai_responses_renderer.py +101 -0
- autobyteus/llm/providers.py +1 -3
- autobyteus/llm/token_counter/claude_token_counter.py +56 -25
- autobyteus/llm/token_counter/mistral_token_counter.py +12 -8
- autobyteus/llm/token_counter/openai_token_counter.py +24 -5
- autobyteus/llm/token_counter/token_counter_factory.py +12 -5
- autobyteus/llm/utils/llm_config.py +6 -12
- autobyteus/llm/utils/media_payload_formatter.py +27 -20
- autobyteus/llm/utils/messages.py +55 -3
- autobyteus/llm/utils/response_types.py +3 -0
- autobyteus/llm/utils/tool_call_delta.py +31 -0
- autobyteus/memory/__init__.py +32 -0
- autobyteus/memory/active_transcript.py +69 -0
- autobyteus/memory/compaction/__init__.py +9 -0
- autobyteus/memory/compaction/compaction_result.py +8 -0
- autobyteus/memory/compaction/compactor.py +89 -0
- autobyteus/memory/compaction/summarizer.py +11 -0
- autobyteus/memory/compaction_snapshot_builder.py +84 -0
- autobyteus/memory/memory_manager.py +183 -0
- autobyteus/memory/models/__init__.py +14 -0
- autobyteus/memory/models/episodic_item.py +41 -0
- autobyteus/memory/models/memory_types.py +7 -0
- autobyteus/memory/models/raw_trace_item.py +79 -0
- autobyteus/memory/models/semantic_item.py +41 -0
- autobyteus/memory/models/tool_interaction.py +20 -0
- autobyteus/memory/policies/__init__.py +5 -0
- autobyteus/memory/policies/compaction_policy.py +16 -0
- autobyteus/memory/retrieval/__init__.py +7 -0
- autobyteus/memory/retrieval/memory_bundle.py +11 -0
- autobyteus/memory/retrieval/retriever.py +13 -0
- autobyteus/memory/store/__init__.py +7 -0
- autobyteus/memory/store/base_store.py +14 -0
- autobyteus/memory/store/file_store.py +98 -0
- autobyteus/memory/tool_interaction_builder.py +46 -0
- autobyteus/memory/turn_tracker.py +9 -0
- autobyteus/multimedia/audio/api/__init__.py +3 -2
- autobyteus/multimedia/audio/api/autobyteus_audio_client.py +19 -5
- autobyteus/multimedia/audio/api/gemini_audio_client.py +108 -16
- autobyteus/multimedia/audio/api/openai_audio_client.py +112 -0
- autobyteus/multimedia/audio/audio_client_factory.py +84 -9
- autobyteus/multimedia/audio/audio_model.py +2 -1
- autobyteus/multimedia/image/api/autobyteus_image_client.py +19 -5
- autobyteus/multimedia/image/api/gemini_image_client.py +38 -17
- autobyteus/multimedia/image/api/openai_image_client.py +125 -43
- autobyteus/multimedia/image/autobyteus_image_provider.py +2 -1
- autobyteus/multimedia/image/image_client_factory.py +47 -15
- autobyteus/multimedia/image/image_model.py +5 -2
- autobyteus/multimedia/providers.py +3 -2
- autobyteus/skills/loader.py +71 -0
- autobyteus/skills/model.py +11 -0
- autobyteus/skills/registry.py +70 -0
- autobyteus/task_management/__init__.py +43 -20
- autobyteus/task_management/{base_task_board.py → base_task_plan.py} +16 -13
- autobyteus/task_management/converters/__init__.py +2 -2
- autobyteus/task_management/converters/{task_board_converter.py → task_plan_converter.py} +13 -13
- autobyteus/task_management/events.py +7 -7
- autobyteus/task_management/{in_memory_task_board.py → in_memory_task_plan.py} +34 -22
- autobyteus/task_management/schemas/__init__.py +3 -0
- autobyteus/task_management/schemas/task_status_report.py +2 -2
- autobyteus/task_management/schemas/todo_definition.py +15 -0
- autobyteus/task_management/todo.py +29 -0
- autobyteus/task_management/todo_list.py +75 -0
- autobyteus/task_management/tools/__init__.py +24 -8
- autobyteus/task_management/tools/task_tools/__init__.py +19 -0
- autobyteus/task_management/tools/{assign_task_to.py → task_tools/assign_task_to.py} +18 -18
- autobyteus/task_management/tools/{publish_task.py → task_tools/create_task.py} +16 -18
- autobyteus/task_management/tools/{publish_tasks.py → task_tools/create_tasks.py} +19 -19
- autobyteus/task_management/tools/{get_my_tasks.py → task_tools/get_my_tasks.py} +15 -15
- autobyteus/task_management/tools/{get_task_board_status.py → task_tools/get_task_plan_status.py} +16 -16
- autobyteus/task_management/tools/{update_task_status.py → task_tools/update_task_status.py} +16 -16
- autobyteus/task_management/tools/todo_tools/__init__.py +18 -0
- autobyteus/task_management/tools/todo_tools/add_todo.py +78 -0
- autobyteus/task_management/tools/todo_tools/create_todo_list.py +79 -0
- autobyteus/task_management/tools/todo_tools/get_todo_list.py +55 -0
- autobyteus/task_management/tools/todo_tools/update_todo_status.py +85 -0
- autobyteus/tools/__init__.py +43 -52
- autobyteus/tools/base_tool.py +7 -0
- autobyteus/tools/file/__init__.py +9 -0
- autobyteus/tools/file/patch_file.py +149 -0
- autobyteus/tools/file/{file_reader.py → read_file.py} +38 -7
- autobyteus/tools/file/{file_writer.py → write_file.py} +7 -4
- autobyteus/tools/functional_tool.py +53 -14
- autobyteus/tools/mcp/__init__.py +2 -0
- autobyteus/tools/mcp/config_service.py +5 -1
- autobyteus/tools/mcp/server/__init__.py +2 -0
- autobyteus/tools/mcp/server/http_managed_mcp_server.py +1 -1
- autobyteus/tools/mcp/server/websocket_managed_mcp_server.py +141 -0
- autobyteus/tools/mcp/server_instance_manager.py +8 -1
- autobyteus/tools/mcp/tool.py +3 -3
- autobyteus/tools/mcp/tool_registrar.py +5 -2
- autobyteus/tools/mcp/types.py +61 -0
- autobyteus/tools/multimedia/__init__.py +2 -1
- autobyteus/tools/multimedia/audio_tools.py +72 -19
- autobyteus/tools/{download_media_tool.py → multimedia/download_media_tool.py} +21 -7
- autobyteus/tools/multimedia/image_tools.py +248 -64
- autobyteus/tools/multimedia/media_reader_tool.py +1 -1
- autobyteus/tools/operation_executor/journal_manager.py +107 -0
- autobyteus/tools/operation_executor/operation_event_buffer.py +57 -0
- autobyteus/tools/operation_executor/operation_event_producer.py +29 -0
- autobyteus/tools/operation_executor/operation_executor.py +58 -0
- autobyteus/tools/registry/tool_definition.py +108 -14
- autobyteus/tools/registry/tool_registry.py +29 -0
- autobyteus/tools/search/__init__.py +17 -0
- autobyteus/tools/search/base_strategy.py +35 -0
- autobyteus/tools/search/client.py +24 -0
- autobyteus/tools/search/factory.py +81 -0
- autobyteus/tools/search/google_cse_strategy.py +68 -0
- autobyteus/tools/search/providers.py +10 -0
- autobyteus/tools/search/serpapi_strategy.py +65 -0
- autobyteus/tools/search/serper_strategy.py +87 -0
- autobyteus/tools/search_tool.py +83 -0
- autobyteus/tools/skill/load_skill.py +50 -0
- autobyteus/tools/terminal/__init__.py +45 -0
- autobyteus/tools/terminal/ansi_utils.py +32 -0
- autobyteus/tools/terminal/background_process_manager.py +233 -0
- autobyteus/tools/terminal/output_buffer.py +105 -0
- autobyteus/tools/terminal/prompt_detector.py +63 -0
- autobyteus/tools/terminal/pty_session.py +241 -0
- autobyteus/tools/terminal/session_factory.py +20 -0
- autobyteus/tools/terminal/terminal_session_manager.py +226 -0
- autobyteus/tools/terminal/tools/__init__.py +13 -0
- autobyteus/tools/terminal/tools/get_process_output.py +81 -0
- autobyteus/tools/terminal/tools/run_bash.py +109 -0
- autobyteus/tools/terminal/tools/start_background_process.py +104 -0
- autobyteus/tools/terminal/tools/stop_background_process.py +67 -0
- autobyteus/tools/terminal/types.py +54 -0
- autobyteus/tools/terminal/wsl_tmux_session.py +221 -0
- autobyteus/tools/terminal/wsl_utils.py +156 -0
- autobyteus/tools/tool_meta.py +4 -24
- autobyteus/tools/transaction_management/backup_handler.py +48 -0
- autobyteus/tools/transaction_management/operation_lifecycle_manager.py +62 -0
- autobyteus/tools/usage/__init__.py +1 -2
- autobyteus/tools/usage/formatters/__init__.py +17 -1
- autobyteus/tools/usage/formatters/base_formatter.py +8 -0
- autobyteus/tools/usage/formatters/default_xml_schema_formatter.py +2 -2
- autobyteus/tools/usage/formatters/mistral_json_schema_formatter.py +18 -0
- autobyteus/tools/usage/formatters/patch_file_xml_example_formatter.py +64 -0
- autobyteus/tools/usage/formatters/patch_file_xml_schema_formatter.py +31 -0
- autobyteus/tools/usage/formatters/run_bash_xml_example_formatter.py +32 -0
- autobyteus/tools/usage/formatters/run_bash_xml_schema_formatter.py +36 -0
- autobyteus/tools/usage/formatters/write_file_xml_example_formatter.py +53 -0
- autobyteus/tools/usage/formatters/write_file_xml_schema_formatter.py +31 -0
- autobyteus/tools/usage/providers/tool_manifest_provider.py +10 -10
- autobyteus/tools/usage/registries/__init__.py +1 -3
- autobyteus/tools/usage/registries/tool_formatting_registry.py +115 -8
- autobyteus/tools/usage/tool_schema_provider.py +51 -0
- autobyteus/tools/web/__init__.py +4 -0
- autobyteus/tools/web/read_url_tool.py +80 -0
- autobyteus/utils/diff_utils.py +271 -0
- autobyteus/utils/download_utils.py +109 -0
- autobyteus/utils/file_utils.py +57 -2
- autobyteus/utils/gemini_helper.py +56 -0
- autobyteus/utils/gemini_model_mapping.py +71 -0
- autobyteus/utils/llm_output_formatter.py +75 -0
- autobyteus/utils/tool_call_format.py +36 -0
- autobyteus/workflow/agentic_workflow.py +3 -3
- autobyteus/workflow/bootstrap_steps/agent_tool_injection_step.py +2 -2
- autobyteus/workflow/bootstrap_steps/base_workflow_bootstrap_step.py +2 -2
- autobyteus/workflow/bootstrap_steps/coordinator_initialization_step.py +2 -2
- autobyteus/workflow/bootstrap_steps/coordinator_prompt_preparation_step.py +4 -11
- autobyteus/workflow/bootstrap_steps/workflow_bootstrapper.py +6 -6
- autobyteus/workflow/bootstrap_steps/workflow_runtime_queue_initialization_step.py +2 -2
- autobyteus/workflow/context/workflow_context.py +3 -3
- autobyteus/workflow/context/workflow_runtime_state.py +5 -5
- autobyteus/workflow/events/workflow_event_dispatcher.py +5 -5
- autobyteus/workflow/handlers/lifecycle_workflow_event_handler.py +3 -3
- autobyteus/workflow/handlers/process_user_message_event_handler.py +5 -5
- autobyteus/workflow/handlers/tool_approval_workflow_event_handler.py +2 -2
- autobyteus/workflow/runtime/workflow_runtime.py +8 -8
- autobyteus/workflow/runtime/workflow_worker.py +3 -3
- autobyteus/workflow/status/__init__.py +11 -0
- autobyteus/workflow/status/workflow_status.py +19 -0
- autobyteus/workflow/status/workflow_status_manager.py +48 -0
- autobyteus/workflow/streaming/__init__.py +2 -2
- autobyteus/workflow/streaming/workflow_event_notifier.py +7 -7
- autobyteus/workflow/streaming/workflow_stream_event_payloads.py +4 -4
- autobyteus/workflow/streaming/workflow_stream_events.py +3 -3
- autobyteus/workflow/utils/wait_for_idle.py +4 -4
- autobyteus-1.2.3.dist-info/METADATA +293 -0
- autobyteus-1.2.3.dist-info/RECORD +600 -0
- {autobyteus-1.2.0.dist-info → autobyteus-1.2.3.dist-info}/WHEEL +1 -1
- {autobyteus-1.2.0.dist-info → autobyteus-1.2.3.dist-info}/top_level.txt +0 -1
- autobyteus/agent/bootstrap_steps/agent_runtime_queue_initialization_step.py +0 -57
- autobyteus/agent/hooks/__init__.py +0 -16
- autobyteus/agent/hooks/base_phase_hook.py +0 -78
- autobyteus/agent/hooks/hook_definition.py +0 -36
- autobyteus/agent/hooks/hook_meta.py +0 -37
- autobyteus/agent/hooks/hook_registry.py +0 -106
- autobyteus/agent/llm_response_processor/provider_aware_tool_usage_processor.py +0 -103
- autobyteus/agent/phases/__init__.py +0 -18
- autobyteus/agent/phases/discover.py +0 -53
- autobyteus/agent/phases/manager.py +0 -265
- autobyteus/agent/phases/transition_decorator.py +0 -40
- autobyteus/agent/phases/transition_info.py +0 -33
- autobyteus/agent/remote_agent.py +0 -244
- autobyteus/agent/workspace/workspace_definition.py +0 -36
- autobyteus/agent/workspace/workspace_meta.py +0 -37
- autobyteus/agent/workspace/workspace_registry.py +0 -72
- autobyteus/agent_team/bootstrap_steps/agent_team_runtime_queue_initialization_step.py +0 -25
- autobyteus/agent_team/bootstrap_steps/coordinator_prompt_preparation_step.py +0 -85
- autobyteus/agent_team/phases/__init__.py +0 -11
- autobyteus/agent_team/phases/agent_team_operational_phase.py +0 -19
- autobyteus/agent_team/phases/agent_team_phase_manager.py +0 -48
- autobyteus/llm/api/bedrock_llm.py +0 -92
- autobyteus/llm/api/groq_llm.py +0 -94
- autobyteus/llm/api/nvidia_llm.py +0 -108
- autobyteus/llm/utils/token_pricing_config.py +0 -87
- autobyteus/person/examples/sample_persons.py +0 -14
- autobyteus/person/examples/sample_roles.py +0 -14
- autobyteus/person/person.py +0 -29
- autobyteus/person/role.py +0 -14
- autobyteus/rpc/__init__.py +0 -73
- autobyteus/rpc/client/__init__.py +0 -17
- autobyteus/rpc/client/abstract_client_connection.py +0 -124
- autobyteus/rpc/client/client_connection_manager.py +0 -153
- autobyteus/rpc/client/sse_client_connection.py +0 -306
- autobyteus/rpc/client/stdio_client_connection.py +0 -280
- autobyteus/rpc/config/__init__.py +0 -13
- autobyteus/rpc/config/agent_server_config.py +0 -153
- autobyteus/rpc/config/agent_server_registry.py +0 -152
- autobyteus/rpc/hosting.py +0 -244
- autobyteus/rpc/protocol.py +0 -244
- autobyteus/rpc/server/__init__.py +0 -20
- autobyteus/rpc/server/agent_server_endpoint.py +0 -181
- autobyteus/rpc/server/base_method_handler.py +0 -40
- autobyteus/rpc/server/method_handlers.py +0 -259
- autobyteus/rpc/server/sse_server_handler.py +0 -182
- autobyteus/rpc/server/stdio_server_handler.py +0 -151
- autobyteus/rpc/server_main.py +0 -198
- autobyteus/rpc/transport_type.py +0 -13
- autobyteus/tools/bash/__init__.py +0 -2
- autobyteus/tools/bash/bash_executor.py +0 -100
- autobyteus/tools/browser/__init__.py +0 -2
- autobyteus/tools/browser/session_aware/__init__.py +0 -0
- autobyteus/tools/browser/session_aware/browser_session_aware_navigate_to.py +0 -75
- autobyteus/tools/browser/session_aware/browser_session_aware_tool.py +0 -30
- autobyteus/tools/browser/session_aware/browser_session_aware_web_element_trigger.py +0 -154
- autobyteus/tools/browser/session_aware/browser_session_aware_webpage_reader.py +0 -89
- autobyteus/tools/browser/session_aware/browser_session_aware_webpage_screenshot_taker.py +0 -107
- autobyteus/tools/browser/session_aware/factory/__init__.py +0 -0
- autobyteus/tools/browser/session_aware/factory/browser_session_aware_web_element_trigger_factory.py +0 -14
- autobyteus/tools/browser/session_aware/factory/browser_session_aware_webpage_reader_factory.py +0 -26
- autobyteus/tools/browser/session_aware/factory/browser_session_aware_webpage_screenshot_taker_factory.py +0 -14
- autobyteus/tools/browser/session_aware/shared_browser_session.py +0 -11
- autobyteus/tools/browser/session_aware/shared_browser_session_manager.py +0 -25
- autobyteus/tools/browser/session_aware/web_element_action.py +0 -20
- autobyteus/tools/browser/standalone/__init__.py +0 -6
- autobyteus/tools/browser/standalone/factory/__init__.py +0 -0
- autobyteus/tools/browser/standalone/factory/webpage_reader_factory.py +0 -25
- autobyteus/tools/browser/standalone/factory/webpage_screenshot_taker_factory.py +0 -14
- autobyteus/tools/browser/standalone/navigate_to.py +0 -80
- autobyteus/tools/browser/standalone/web_page_pdf_generator.py +0 -97
- autobyteus/tools/browser/standalone/webpage_image_downloader.py +0 -165
- autobyteus/tools/browser/standalone/webpage_reader.py +0 -101
- autobyteus/tools/browser/standalone/webpage_screenshot_taker.py +0 -101
- autobyteus/tools/file/file_editor.py +0 -200
- autobyteus/tools/google_search.py +0 -149
- autobyteus/tools/timer.py +0 -171
- autobyteus/tools/usage/parsers/__init__.py +0 -22
- autobyteus/tools/usage/parsers/_json_extractor.py +0 -99
- autobyteus/tools/usage/parsers/_string_decoders.py +0 -18
- autobyteus/tools/usage/parsers/anthropic_xml_tool_usage_parser.py +0 -10
- autobyteus/tools/usage/parsers/base_parser.py +0 -41
- autobyteus/tools/usage/parsers/default_json_tool_usage_parser.py +0 -83
- autobyteus/tools/usage/parsers/default_xml_tool_usage_parser.py +0 -316
- autobyteus/tools/usage/parsers/exceptions.py +0 -13
- autobyteus/tools/usage/parsers/gemini_json_tool_usage_parser.py +0 -77
- autobyteus/tools/usage/parsers/openai_json_tool_usage_parser.py +0 -149
- autobyteus/tools/usage/parsers/provider_aware_tool_usage_parser.py +0 -59
- autobyteus/tools/usage/registries/tool_usage_parser_registry.py +0 -62
- autobyteus/workflow/phases/__init__.py +0 -11
- autobyteus/workflow/phases/workflow_operational_phase.py +0 -19
- autobyteus/workflow/phases/workflow_phase_manager.py +0 -48
- autobyteus-1.2.0.dist-info/METADATA +0 -205
- autobyteus-1.2.0.dist-info/RECORD +0 -496
- examples/__init__.py +0 -1
- examples/agent_team/__init__.py +0 -1
- examples/discover_phase_transitions.py +0 -104
- examples/run_browser_agent.py +0 -262
- examples/run_google_slides_agent.py +0 -287
- examples/run_mcp_browser_client.py +0 -174
- examples/run_mcp_google_slides_client.py +0 -270
- examples/run_mcp_list_tools.py +0 -189
- examples/run_poem_writer.py +0 -284
- examples/run_sqlite_agent.py +0 -295
- /autobyteus/{person → skills}/__init__.py +0 -0
- /autobyteus/{person/examples → tools/skill}/__init__.py +0 -0
- {autobyteus-1.2.0.dist-info → autobyteus-1.2.3.dist-info}/licenses/LICENSE +0 -0
|
@@ -6,7 +6,6 @@ from autobyteus.agent.handlers.base_event_handler import AgentEventHandler
|
|
|
6
6
|
from autobyteus.agent.events import LLMCompleteResponseReceivedEvent
|
|
7
7
|
from autobyteus.llm.utils.response_types import CompleteResponse
|
|
8
8
|
from autobyteus.agent.llm_response_processor import BaseLLMResponseProcessor
|
|
9
|
-
from autobyteus.tools.usage.parsers.exceptions import ToolUsageParseException
|
|
10
9
|
|
|
11
10
|
|
|
12
11
|
if TYPE_CHECKING:
|
|
@@ -49,8 +48,8 @@ class LLMCompleteResponseReceivedEventHandler(AgentEventHandler):
|
|
|
49
48
|
any_processor_took_action = False
|
|
50
49
|
|
|
51
50
|
notifier: Optional['AgentExternalEventNotifier'] = None
|
|
52
|
-
if context.
|
|
53
|
-
notifier = context.
|
|
51
|
+
if context.status_manager:
|
|
52
|
+
notifier = context.status_manager.notifier
|
|
54
53
|
|
|
55
54
|
if not notifier: # pragma: no cover
|
|
56
55
|
logger.error(f"Agent '{agent_id}': Notifier not available in LLMCompleteResponseReceivedEventHandler. Cannot emit complete response event.")
|
|
@@ -63,8 +62,15 @@ class LLMCompleteResponseReceivedEventHandler(AgentEventHandler):
|
|
|
63
62
|
f"Proceeding to treat LLM response as output for this leg."
|
|
64
63
|
)
|
|
65
64
|
else:
|
|
65
|
+
valid_processors = []
|
|
66
|
+
for p in processor_instances_to_try:
|
|
67
|
+
if isinstance(p, BaseLLMResponseProcessor):
|
|
68
|
+
valid_processors.append(p)
|
|
69
|
+
else:
|
|
70
|
+
logger.error(f"Agent '{agent_id}': Invalid LLM response processor type in config: {type(p)}. Skipping.")
|
|
71
|
+
|
|
66
72
|
# Sort processors by their order attribute
|
|
67
|
-
sorted_processors = sorted(
|
|
73
|
+
sorted_processors = sorted(valid_processors, key=lambda p: p.get_order())
|
|
68
74
|
processor_names = [p.get_name() for p in sorted_processors]
|
|
69
75
|
logger.debug(f"Agent '{agent_id}': Attempting LLM response processing in order: {processor_names}")
|
|
70
76
|
|
|
@@ -94,17 +100,6 @@ class LLMCompleteResponseReceivedEventHandler(AgentEventHandler):
|
|
|
94
100
|
else:
|
|
95
101
|
logger.debug(f"Agent '{agent_id}': LLMResponseProcessor '{processor_name_for_log}' did not handle the response.")
|
|
96
102
|
|
|
97
|
-
except ToolUsageParseException as e_parse:
|
|
98
|
-
# This is the key change: Catch the specific parsing exception
|
|
99
|
-
logger.warning(f"Agent '{agent_id}': LLMResponseProcessor '{processor_name_for_log}' failed to parse tool usage: {e_parse}")
|
|
100
|
-
if notifier:
|
|
101
|
-
notifier.notify_agent_error_output_generation(
|
|
102
|
-
error_source=f"LLMResponseProcessor.{processor_name_for_log}",
|
|
103
|
-
error_message="The model's response contained a malformed tool call that could not be understood.",
|
|
104
|
-
error_details=str(e_parse)
|
|
105
|
-
)
|
|
106
|
-
# A parsing failure should not prevent other processors from running.
|
|
107
|
-
|
|
108
103
|
except Exception as e: # pragma: no cover
|
|
109
104
|
logger.error(f"Agent '{agent_id}': Error while using LLMResponseProcessor '{processor_name_for_log}': {e}. This processor is skipped.", exc_info=True)
|
|
110
105
|
if notifier:
|
|
@@ -1,13 +1,21 @@
|
|
|
1
1
|
# file: autobyteus/autobyteus/agent/handlers/llm_user_message_ready_event_handler.py
|
|
2
2
|
import logging
|
|
3
3
|
import traceback
|
|
4
|
-
|
|
4
|
+
import uuid
|
|
5
|
+
from typing import TYPE_CHECKING, Optional, List
|
|
5
6
|
|
|
6
7
|
from autobyteus.agent.handlers.base_event_handler import AgentEventHandler
|
|
7
|
-
from autobyteus.agent.events import LLMUserMessageReadyEvent, LLMCompleteResponseReceivedEvent
|
|
8
|
+
from autobyteus.agent.events import LLMUserMessageReadyEvent, LLMCompleteResponseReceivedEvent, PendingToolInvocationEvent
|
|
8
9
|
from autobyteus.llm.user_message import LLMUserMessage
|
|
9
10
|
from autobyteus.llm.utils.response_types import ChunkResponse, CompleteResponse
|
|
10
11
|
from autobyteus.llm.utils.token_usage import TokenUsage
|
|
12
|
+
from autobyteus.agent.streaming.streaming_response_handler import StreamingResponseHandler
|
|
13
|
+
from autobyteus.agent.streaming.streaming_handler_factory import StreamingResponseHandlerFactory
|
|
14
|
+
from autobyteus.agent.streaming.parser.events import SegmentEvent, SegmentType
|
|
15
|
+
from autobyteus.agent.tool_invocation import ToolInvocationTurn
|
|
16
|
+
from autobyteus.agent.llm_request_assembler import LLMRequestAssembler
|
|
17
|
+
from autobyteus.agent.token_budget import apply_compaction_policy, resolve_token_budget
|
|
18
|
+
from autobyteus.llm.prompt_renderers.openai_chat_renderer import OpenAIChatRenderer
|
|
11
19
|
|
|
12
20
|
if TYPE_CHECKING:
|
|
13
21
|
from autobyteus.agent.context import AgentContext
|
|
@@ -18,9 +26,8 @@ logger = logging.getLogger(__name__)
|
|
|
18
26
|
class LLMUserMessageReadyEventHandler(AgentEventHandler):
|
|
19
27
|
"""
|
|
20
28
|
Handles LLMUserMessageReadyEvents by sending the prepared LLMUserMessage
|
|
21
|
-
to the LLM,
|
|
22
|
-
|
|
23
|
-
and then enqueuing an LLMCompleteResponseReceivedEvent with the full aggregated response.
|
|
29
|
+
to the LLM, passing the stream through StreamingResponseHandler for safe parsing,
|
|
30
|
+
emitting filtered chunks via the notifier, and finally enqueuing the complete response.
|
|
24
31
|
"""
|
|
25
32
|
|
|
26
33
|
def __init__(self):
|
|
@@ -37,8 +44,8 @@ class LLMUserMessageReadyEventHandler(AgentEventHandler):
|
|
|
37
44
|
if context.state.llm_instance is None:
|
|
38
45
|
error_msg = f"Agent '{agent_id}' received LLMUserMessageReadyEvent but LLM instance is not yet initialized."
|
|
39
46
|
logger.critical(error_msg)
|
|
40
|
-
if context.
|
|
41
|
-
context.
|
|
47
|
+
if context.status_manager and context.status_manager.notifier:
|
|
48
|
+
context.status_manager.notifier.notify_agent_error_output_generation(
|
|
42
49
|
error_source="LLMUserMessageReadyEventHandler.pre_llm_check",
|
|
43
50
|
error_message=error_msg
|
|
44
51
|
)
|
|
@@ -48,8 +55,13 @@ class LLMUserMessageReadyEventHandler(AgentEventHandler):
|
|
|
48
55
|
logger.info(f"Agent '{agent_id}' handling LLMUserMessageReadyEvent: '{llm_user_message.content}'")
|
|
49
56
|
logger.debug(f"Agent '{agent_id}' preparing to send full message to LLM:\n---\n{llm_user_message.content}\n---")
|
|
50
57
|
|
|
51
|
-
context.state
|
|
58
|
+
memory_manager = getattr(context.state, "memory_manager", None)
|
|
59
|
+
active_turn_id = getattr(context.state, "active_turn_id", None)
|
|
60
|
+
if memory_manager and not active_turn_id:
|
|
61
|
+
active_turn_id = memory_manager.start_turn()
|
|
62
|
+
context.state.active_turn_id = active_turn_id
|
|
52
63
|
|
|
64
|
+
# Initialize aggregators
|
|
53
65
|
complete_response_text = ""
|
|
54
66
|
complete_reasoning_text = ""
|
|
55
67
|
token_usage: Optional[TokenUsage] = None
|
|
@@ -57,66 +69,192 @@ class LLMUserMessageReadyEventHandler(AgentEventHandler):
|
|
|
57
69
|
complete_audio_urls: List[str] = []
|
|
58
70
|
complete_video_urls: List[str] = []
|
|
59
71
|
|
|
72
|
+
# Get notifier for emitting events
|
|
60
73
|
notifier: Optional['AgentExternalEventNotifier'] = None
|
|
61
|
-
if context.
|
|
62
|
-
notifier = context.
|
|
74
|
+
if context.status_manager:
|
|
75
|
+
notifier = context.status_manager.notifier
|
|
63
76
|
|
|
64
77
|
if not notifier: # pragma: no cover
|
|
65
78
|
logger.error(f"Agent '{agent_id}': Notifier not available in LLMUserMessageReadyEventHandler. Cannot emit chunk events.")
|
|
66
79
|
|
|
80
|
+
# Callback for segment events from streaming parser
|
|
81
|
+
def emit_segment_event(event: SegmentEvent):
|
|
82
|
+
if notifier:
|
|
83
|
+
try:
|
|
84
|
+
notifier.notify_agent_segment_event(event.to_dict())
|
|
85
|
+
except Exception as e:
|
|
86
|
+
logger.error(f"Agent '{agent_id}': Error notifying segment event: {e}", exc_info=True)
|
|
87
|
+
|
|
88
|
+
# Collect tool names from agent state/config
|
|
89
|
+
tool_names: List[str] = []
|
|
90
|
+
if context.state.tool_instances:
|
|
91
|
+
tool_names = list(context.state.tool_instances.keys())
|
|
92
|
+
elif context.config.tools:
|
|
93
|
+
for tool in context.config.tools:
|
|
94
|
+
if isinstance(tool, str):
|
|
95
|
+
tool_names.append(tool)
|
|
96
|
+
elif hasattr(tool, "get_name"):
|
|
97
|
+
try:
|
|
98
|
+
tool_names.append(tool.get_name())
|
|
99
|
+
except Exception: # pragma: no cover - defensive
|
|
100
|
+
logger.warning(
|
|
101
|
+
"Agent '%s': Failed to resolve tool name from %s.",
|
|
102
|
+
agent_id,
|
|
103
|
+
type(tool),
|
|
104
|
+
)
|
|
105
|
+
else: # pragma: no cover - defensive
|
|
106
|
+
logger.warning(
|
|
107
|
+
"Agent '%s': Unsupported tool entry in config: %s.",
|
|
108
|
+
agent_id,
|
|
109
|
+
type(tool),
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
# Get provider from LLM instance
|
|
113
|
+
provider = context.state.llm_instance.model.provider if context.state.llm_instance else None
|
|
114
|
+
|
|
115
|
+
# Create streaming handler via factory (all configuration encapsulated)
|
|
116
|
+
handler_result = StreamingResponseHandlerFactory.create(
|
|
117
|
+
tool_names=tool_names,
|
|
118
|
+
provider=provider,
|
|
119
|
+
on_segment_event=emit_segment_event,
|
|
120
|
+
agent_id=agent_id,
|
|
121
|
+
)
|
|
122
|
+
streaming_handler = handler_result.handler
|
|
123
|
+
|
|
124
|
+
logger.info(
|
|
125
|
+
"Agent '%s': Streaming handler selected: %s",
|
|
126
|
+
agent_id,
|
|
127
|
+
streaming_handler.__class__.__name__,
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
# Prepare arguments for stream_user_message
|
|
131
|
+
stream_kwargs = {}
|
|
132
|
+
if handler_result.tool_schemas:
|
|
133
|
+
stream_kwargs["tools"] = handler_result.tool_schemas
|
|
134
|
+
logger.info(
|
|
135
|
+
"Agent '%s': Passing %d tool schemas to LLM API (Provider: %s)",
|
|
136
|
+
agent_id,
|
|
137
|
+
len(handler_result.tool_schemas),
|
|
138
|
+
provider,
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
if not memory_manager:
|
|
142
|
+
raise RuntimeError(f"Agent '{agent_id}' requires a memory manager to assemble LLM requests.")
|
|
143
|
+
|
|
144
|
+
llm_config = getattr(context.state.llm_instance, "config", None)
|
|
145
|
+
llm_model = getattr(context.state.llm_instance, "model", None)
|
|
146
|
+
|
|
147
|
+
renderer = getattr(context.state.llm_instance, "_renderer", None) or OpenAIChatRenderer()
|
|
148
|
+
assembler = LLMRequestAssembler(
|
|
149
|
+
memory_manager=memory_manager,
|
|
150
|
+
renderer=renderer,
|
|
151
|
+
)
|
|
152
|
+
system_prompt = (
|
|
153
|
+
context.state.processed_system_prompt
|
|
154
|
+
or context.state.llm_instance.config.system_message
|
|
155
|
+
)
|
|
156
|
+
request = await assembler.prepare_request(
|
|
157
|
+
processed_user_input=llm_user_message,
|
|
158
|
+
current_turn_id=active_turn_id,
|
|
159
|
+
system_prompt=system_prompt,
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
# State for manual reasoning parts (since they might come from outside the parser)
|
|
163
|
+
segment_id_prefix = f"turn_{uuid.uuid4().hex}:"
|
|
164
|
+
current_reasoning_part_id = None
|
|
165
|
+
|
|
67
166
|
try:
|
|
68
|
-
async for chunk_response in context.state.llm_instance.
|
|
167
|
+
async for chunk_response in context.state.llm_instance.stream_messages(
|
|
168
|
+
request.messages,
|
|
169
|
+
rendered_payload=request.rendered_payload,
|
|
170
|
+
**stream_kwargs,
|
|
171
|
+
):
|
|
69
172
|
if not isinstance(chunk_response, ChunkResponse):
|
|
70
173
|
logger.warning(f"Agent '{agent_id}' received unexpected chunk type: {type(chunk_response)} during LLM stream. Expected ChunkResponse.")
|
|
71
174
|
continue
|
|
72
175
|
|
|
176
|
+
# Aggregate full raw content
|
|
73
177
|
if chunk_response.content:
|
|
74
178
|
complete_response_text += chunk_response.content
|
|
75
179
|
if chunk_response.reasoning:
|
|
76
180
|
complete_reasoning_text += chunk_response.reasoning
|
|
77
181
|
|
|
182
|
+
# Collect usage and media from final chunks
|
|
78
183
|
if chunk_response.is_complete:
|
|
79
184
|
if chunk_response.usage:
|
|
80
185
|
token_usage = chunk_response.usage
|
|
81
186
|
logger.debug(f"Agent '{agent_id}' received final chunk with token usage: {token_usage}")
|
|
82
187
|
if chunk_response.image_urls:
|
|
83
188
|
complete_image_urls.extend(chunk_response.image_urls)
|
|
84
|
-
logger.debug(f"Agent '{agent_id}' received final chunk with {len(chunk_response.image_urls)} image URLs.")
|
|
85
189
|
if chunk_response.audio_urls:
|
|
86
190
|
complete_audio_urls.extend(chunk_response.audio_urls)
|
|
87
|
-
logger.debug(f"Agent '{agent_id}' received final chunk with {len(chunk_response.audio_urls)} audio URLs.")
|
|
88
191
|
if chunk_response.video_urls:
|
|
89
192
|
complete_video_urls.extend(chunk_response.video_urls)
|
|
90
|
-
logger.debug(f"Agent '{agent_id}' received final chunk with {len(chunk_response.video_urls)} video URLs.")
|
|
91
193
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
194
|
+
# Handle Reasoning (Manual Segment Management)
|
|
195
|
+
if chunk_response.reasoning:
|
|
196
|
+
if current_reasoning_part_id is None:
|
|
197
|
+
current_reasoning_part_id = f"{segment_id_prefix}reasoning_{uuid.uuid4().hex}"
|
|
198
|
+
# Emit SEGMENT_START for reasoning
|
|
199
|
+
start_event = SegmentEvent.start(
|
|
200
|
+
segment_id=current_reasoning_part_id,
|
|
201
|
+
segment_type=SegmentType.REASONING
|
|
202
|
+
)
|
|
203
|
+
emit_segment_event(start_event)
|
|
204
|
+
|
|
205
|
+
# Emit SEGMENT_CONTENT for reasoning delta
|
|
206
|
+
content_event = SegmentEvent.content(
|
|
207
|
+
segment_id=current_reasoning_part_id,
|
|
208
|
+
delta=chunk_response.reasoning
|
|
209
|
+
)
|
|
210
|
+
emit_segment_event(content_event)
|
|
104
211
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
212
|
+
# Handle Content & Tool Calls (Through Handler)
|
|
213
|
+
# Pass the full ChunkResponse object to support both text and tool call streams
|
|
214
|
+
streaming_handler.feed(chunk_response)
|
|
215
|
+
|
|
216
|
+
# End of stream loop
|
|
109
217
|
|
|
218
|
+
# Finalize the stream parser to get any held-back content
|
|
219
|
+
streaming_handler.finalize()
|
|
220
|
+
|
|
221
|
+
# After finalization, enqueue any parsed tool invocations.
|
|
222
|
+
if tool_names:
|
|
223
|
+
tool_invocations = streaming_handler.get_all_invocations()
|
|
224
|
+
if tool_invocations:
|
|
225
|
+
context.state.active_multi_tool_call_turn = ToolInvocationTurn(
|
|
226
|
+
invocations=tool_invocations
|
|
227
|
+
)
|
|
228
|
+
logger.info(
|
|
229
|
+
"Agent '%s': Parsed %d tool invocations from streaming parser.",
|
|
230
|
+
agent_id,
|
|
231
|
+
len(tool_invocations),
|
|
232
|
+
)
|
|
233
|
+
for invocation in tool_invocations:
|
|
234
|
+
if active_turn_id and not invocation.turn_id:
|
|
235
|
+
invocation.turn_id = active_turn_id
|
|
236
|
+
if memory_manager:
|
|
237
|
+
memory_manager.ingest_tool_intent(invocation, turn_id=active_turn_id)
|
|
238
|
+
await context.input_event_queues.enqueue_tool_invocation_request(
|
|
239
|
+
PendingToolInvocationEvent(tool_invocation=invocation)
|
|
240
|
+
)
|
|
241
|
+
|
|
242
|
+
# Close any open reasoning segment
|
|
243
|
+
if current_reasoning_part_id:
|
|
244
|
+
end_event = SegmentEvent.end(segment_id=current_reasoning_part_id)
|
|
245
|
+
emit_segment_event(end_event)
|
|
246
|
+
|
|
247
|
+
logger.debug(f"Agent '{agent_id}' LLM stream completed. Full response length: {len(complete_response_text)}.")
|
|
248
|
+
if complete_reasoning_text:
|
|
249
|
+
logger.debug(f"Agent '{agent_id}' aggregated full LLM reasoning.")
|
|
250
|
+
|
|
110
251
|
except Exception as e:
|
|
111
252
|
logger.error(f"Agent '{agent_id}' error during LLM stream: {e}", exc_info=True)
|
|
112
253
|
error_message_for_output = f"Error processing your request with the LLM: {str(e)}"
|
|
113
254
|
|
|
114
255
|
logger.warning(f"Agent '{agent_id}' LLM stream error. Error message for output: {error_message_for_output}")
|
|
115
|
-
context.state.add_message_to_history({"role": "assistant", "content": error_message_for_output, "is_error": True})
|
|
116
|
-
|
|
117
256
|
if notifier:
|
|
118
257
|
try:
|
|
119
|
-
notifier.notify_agent_data_assistant_chunk_stream_end()
|
|
120
258
|
notifier.notify_agent_error_output_generation(
|
|
121
259
|
error_source="LLMUserMessageReadyEventHandler.stream_user_message",
|
|
122
260
|
error_message=error_message_for_output,
|
|
@@ -131,22 +269,10 @@ class LLMUserMessageReadyEventHandler(AgentEventHandler):
|
|
|
131
269
|
is_error=True
|
|
132
270
|
)
|
|
133
271
|
await context.input_event_queues.enqueue_internal_system_event(llm_complete_event_on_error)
|
|
134
|
-
logger.info(f"Agent '{agent_id}' enqueued LLMCompleteResponseReceivedEvent with error details
|
|
272
|
+
logger.info(f"Agent '{agent_id}' enqueued LLMCompleteResponseReceivedEvent with error details.")
|
|
135
273
|
return
|
|
136
274
|
|
|
137
|
-
#
|
|
138
|
-
history_entry = {"role": "assistant", "content": complete_response_text}
|
|
139
|
-
if complete_reasoning_text:
|
|
140
|
-
history_entry["reasoning"] = complete_reasoning_text
|
|
141
|
-
if complete_image_urls:
|
|
142
|
-
history_entry["image_urls"] = complete_image_urls
|
|
143
|
-
if complete_audio_urls:
|
|
144
|
-
history_entry["audio_urls"] = complete_audio_urls
|
|
145
|
-
if complete_video_urls:
|
|
146
|
-
history_entry["video_urls"] = complete_video_urls
|
|
147
|
-
context.state.add_message_to_history(history_entry)
|
|
148
|
-
|
|
149
|
-
# Create complete response with reasoning and multimodal data
|
|
275
|
+
# Create complete response
|
|
150
276
|
complete_response_obj = CompleteResponse(
|
|
151
277
|
content=complete_response_text,
|
|
152
278
|
reasoning=complete_reasoning_text,
|
|
@@ -155,9 +281,23 @@ class LLMUserMessageReadyEventHandler(AgentEventHandler):
|
|
|
155
281
|
audio_urls=complete_audio_urls,
|
|
156
282
|
video_urls=complete_video_urls
|
|
157
283
|
)
|
|
284
|
+
if memory_manager and active_turn_id:
|
|
285
|
+
memory_manager.ingest_assistant_response(
|
|
286
|
+
complete_response_obj,
|
|
287
|
+
turn_id=active_turn_id,
|
|
288
|
+
source_event="LLMCompleteResponseReceivedEvent",
|
|
289
|
+
)
|
|
290
|
+
if token_usage and llm_config and llm_model:
|
|
291
|
+
budget = resolve_token_budget(llm_model, llm_config, memory_manager.compaction_policy)
|
|
292
|
+
if budget:
|
|
293
|
+
apply_compaction_policy(memory_manager.compaction_policy, budget)
|
|
294
|
+
if memory_manager.compactor and memory_manager.compaction_policy.should_compact(
|
|
295
|
+
token_usage.prompt_tokens,
|
|
296
|
+
budget.input_budget,
|
|
297
|
+
):
|
|
298
|
+
memory_manager.request_compaction()
|
|
158
299
|
llm_complete_event = LLMCompleteResponseReceivedEvent(
|
|
159
300
|
complete_response=complete_response_obj
|
|
160
301
|
)
|
|
161
302
|
await context.input_event_queues.enqueue_internal_system_event(llm_complete_event)
|
|
162
303
|
logger.info(f"Agent '{agent_id}' enqueued LLMCompleteResponseReceivedEvent from LLMUserMessageReadyEventHandler.")
|
|
163
|
-
|
|
@@ -62,16 +62,6 @@ class ToolExecutionApprovalEventHandler(AgentEventHandler):
|
|
|
62
62
|
)
|
|
63
63
|
|
|
64
64
|
denial_reason_str = event.reason or "No specific reason provided."
|
|
65
|
-
denial_content_for_history = f"Tool execution denied by user/system. Reason: {denial_reason_str}"
|
|
66
|
-
|
|
67
|
-
context.state.add_message_to_history({
|
|
68
|
-
"role": "tool",
|
|
69
|
-
"tool_call_id": event.tool_invocation_id,
|
|
70
|
-
"name": retrieved_invocation.name,
|
|
71
|
-
"content": denial_content_for_history,
|
|
72
|
-
})
|
|
73
|
-
logger.debug(f"Agent '{context.agent_id}': Added 'tool' role denial message to history for '{retrieved_invocation.name}' (ID: {event.tool_invocation_id}).")
|
|
74
|
-
|
|
75
65
|
prompt_content_for_llm = (
|
|
76
66
|
f"The request to use the tool '{retrieved_invocation.name}' "
|
|
77
67
|
f"(with arguments: {json.dumps(retrieved_invocation.arguments or {})}) was denied. "
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# file: autobyteus/autobyteus/agent/handlers/tool_invocation_request_event_handler.py
|
|
2
2
|
import logging
|
|
3
|
-
import json
|
|
4
3
|
import traceback
|
|
5
4
|
from typing import TYPE_CHECKING, Optional
|
|
6
5
|
|
|
7
6
|
from autobyteus.agent.handlers.base_event_handler import AgentEventHandler
|
|
8
7
|
from autobyteus.agent.events import PendingToolInvocationEvent, ToolResultEvent
|
|
9
8
|
from autobyteus.agent.tool_invocation import ToolInvocation
|
|
9
|
+
from autobyteus.utils.llm_output_formatter import format_to_clean_string
|
|
10
10
|
|
|
11
11
|
if TYPE_CHECKING:
|
|
12
12
|
from autobyteus.agent.context import AgentContext
|
|
@@ -46,10 +46,35 @@ class ToolInvocationRequestEventHandler(AgentEventHandler):
|
|
|
46
46
|
except Exception as e_notify:
|
|
47
47
|
logger.error(f"Agent '{agent_id}': Error notifying tool auto-execution: {e_notify}", exc_info=True)
|
|
48
48
|
|
|
49
|
+
# Run tool invocation preprocessors (if any) before execution
|
|
50
|
+
processors = context.config.tool_invocation_preprocessors
|
|
51
|
+
if processors:
|
|
52
|
+
# Filter valid processors first to avoid sorting crashes (checking for get_order attribute)
|
|
53
|
+
valid_processors = [p for p in processors if hasattr(p, 'get_order')]
|
|
54
|
+
sorted_processors = sorted(valid_processors, key=lambda p: p.get_order())
|
|
55
|
+
for processor in sorted_processors:
|
|
56
|
+
try:
|
|
57
|
+
tool_invocation = await processor.process(tool_invocation, context)
|
|
58
|
+
tool_name = tool_invocation.name
|
|
59
|
+
arguments = tool_invocation.arguments
|
|
60
|
+
invocation_id = tool_invocation.id
|
|
61
|
+
except Exception as e:
|
|
62
|
+
error_message = f"Error in tool invocation preprocessor '{processor.get_name()}' for tool '{tool_name}': {e}"
|
|
63
|
+
logger.error(f"Agent '{agent_id}': {error_message}", exc_info=True)
|
|
64
|
+
result_event = ToolResultEvent(
|
|
65
|
+
tool_name=tool_name,
|
|
66
|
+
result=None,
|
|
67
|
+
error=error_message,
|
|
68
|
+
tool_invocation_id=invocation_id,
|
|
69
|
+
turn_id=tool_invocation.turn_id,
|
|
70
|
+
)
|
|
71
|
+
await context.input_event_queues.enqueue_tool_result(result_event)
|
|
72
|
+
return
|
|
73
|
+
|
|
49
74
|
logger.info(f"Agent '{agent_id}' executing tool directly: '{tool_name}' (ID: {invocation_id}) with args: {arguments}")
|
|
50
75
|
|
|
51
76
|
try:
|
|
52
|
-
args_str =
|
|
77
|
+
args_str = format_to_clean_string(arguments)
|
|
53
78
|
except TypeError:
|
|
54
79
|
args_str = str(arguments)
|
|
55
80
|
|
|
@@ -71,13 +96,13 @@ class ToolInvocationRequestEventHandler(AgentEventHandler):
|
|
|
71
96
|
if not tool_instance:
|
|
72
97
|
error_message = f"Tool '{tool_name}' not found or configured for agent '{agent_id}'."
|
|
73
98
|
logger.error(error_message)
|
|
74
|
-
result_event = ToolResultEvent(
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
99
|
+
result_event = ToolResultEvent(
|
|
100
|
+
tool_name=tool_name,
|
|
101
|
+
result=None,
|
|
102
|
+
error=error_message,
|
|
103
|
+
tool_invocation_id=invocation_id,
|
|
104
|
+
turn_id=tool_invocation.turn_id,
|
|
105
|
+
)
|
|
81
106
|
log_msg_error = f"[TOOL_ERROR_DIRECT] {error_message}"
|
|
82
107
|
if notifier:
|
|
83
108
|
try:
|
|
@@ -97,20 +122,19 @@ class ToolInvocationRequestEventHandler(AgentEventHandler):
|
|
|
97
122
|
execution_result = await tool_instance.execute(context=context, **arguments)
|
|
98
123
|
|
|
99
124
|
try:
|
|
100
|
-
result_json_for_log =
|
|
125
|
+
result_json_for_log = format_to_clean_string(execution_result)
|
|
101
126
|
except (TypeError, ValueError):
|
|
102
|
-
result_json_for_log =
|
|
127
|
+
result_json_for_log = format_to_clean_string(str(execution_result))
|
|
103
128
|
|
|
104
129
|
logger.info(f"Tool '{tool_name}' (ID: {invocation_id}) executed by agent '{agent_id}'.")
|
|
105
|
-
result_event = ToolResultEvent(
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
})
|
|
130
|
+
result_event = ToolResultEvent(
|
|
131
|
+
tool_name=tool_name,
|
|
132
|
+
result=execution_result,
|
|
133
|
+
error=None,
|
|
134
|
+
tool_invocation_id=invocation_id,
|
|
135
|
+
tool_args=arguments,
|
|
136
|
+
turn_id=tool_invocation.turn_id,
|
|
137
|
+
)
|
|
114
138
|
log_msg_result = f"[TOOL_RESULT_DIRECT] {result_json_for_log}"
|
|
115
139
|
if notifier:
|
|
116
140
|
try:
|
|
@@ -124,13 +148,13 @@ class ToolInvocationRequestEventHandler(AgentEventHandler):
|
|
|
124
148
|
error_message = f"Error executing tool '{tool_name}' (ID: {invocation_id}): {str(e)}"
|
|
125
149
|
error_details = traceback.format_exc()
|
|
126
150
|
logger.error(f"Agent '{agent_id}' {error_message}", exc_info=True)
|
|
127
|
-
result_event = ToolResultEvent(
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
151
|
+
result_event = ToolResultEvent(
|
|
152
|
+
tool_name=tool_name,
|
|
153
|
+
result=None,
|
|
154
|
+
error=error_message,
|
|
155
|
+
tool_invocation_id=invocation_id,
|
|
156
|
+
turn_id=tool_invocation.turn_id,
|
|
157
|
+
)
|
|
134
158
|
log_msg_exception = f"[TOOL_EXCEPTION_DIRECT] {error_message}\nDetails:\n{error_details}"
|
|
135
159
|
if notifier:
|
|
136
160
|
try:
|
|
@@ -161,8 +185,8 @@ class ToolInvocationRequestEventHandler(AgentEventHandler):
|
|
|
161
185
|
agent_id = context.agent_id
|
|
162
186
|
|
|
163
187
|
notifier: Optional['AgentExternalEventNotifier'] = None
|
|
164
|
-
if context.
|
|
165
|
-
notifier = context.
|
|
188
|
+
if context.status_manager:
|
|
189
|
+
notifier = context.status_manager.notifier
|
|
166
190
|
|
|
167
191
|
if not notifier:
|
|
168
192
|
logger.error(f"Agent '{agent_id}': Notifier not available in ToolInvocationRequestEventHandler. Output events for tool approval/logging will be lost.")
|
|
@@ -175,25 +199,6 @@ class ToolInvocationRequestEventHandler(AgentEventHandler):
|
|
|
175
199
|
|
|
176
200
|
context.store_pending_tool_invocation(tool_invocation)
|
|
177
201
|
|
|
178
|
-
try:
|
|
179
|
-
arguments_json_str = json.dumps(tool_invocation.arguments or {})
|
|
180
|
-
except TypeError:
|
|
181
|
-
logger.warning(f"Could not serialize args for history tool_call for '{tool_invocation.name}'. Using empty dict string.")
|
|
182
|
-
arguments_json_str = "{}"
|
|
183
|
-
|
|
184
|
-
context.add_message_to_history({
|
|
185
|
-
"role": "assistant",
|
|
186
|
-
"content": None,
|
|
187
|
-
"tool_calls": [{
|
|
188
|
-
"id": tool_invocation.id,
|
|
189
|
-
"type": "function",
|
|
190
|
-
"function": {
|
|
191
|
-
"name": tool_invocation.name,
|
|
192
|
-
"arguments": arguments_json_str
|
|
193
|
-
}
|
|
194
|
-
}]
|
|
195
|
-
})
|
|
196
|
-
|
|
197
202
|
approval_data = {
|
|
198
203
|
"invocation_id": tool_invocation.id,
|
|
199
204
|
"tool_name": tool_invocation.name,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# file: autobyteus/autobyteus/agent/handlers/tool_result_event_handler.py
|
|
2
2
|
import logging
|
|
3
|
-
|
|
3
|
+
|
|
4
4
|
from typing import TYPE_CHECKING, Optional, List
|
|
5
5
|
|
|
6
6
|
from autobyteus.agent.handlers.base_event_handler import AgentEventHandler
|
|
@@ -9,6 +9,7 @@ from autobyteus.agent.tool_execution_result_processor import BaseToolExecutionRe
|
|
|
9
9
|
from autobyteus.agent.message.context_file import ContextFile
|
|
10
10
|
from autobyteus.agent.message import AgentInputUserMessage
|
|
11
11
|
from autobyteus.agent.sender_type import SenderType
|
|
12
|
+
from autobyteus.utils.llm_output_formatter import format_to_clean_string
|
|
12
13
|
|
|
13
14
|
if TYPE_CHECKING:
|
|
14
15
|
from autobyteus.agent.context import AgentContext
|
|
@@ -81,10 +82,7 @@ class ToolResultEventHandler(AgentEventHandler):
|
|
|
81
82
|
aggregated_content_parts.append(content_part)
|
|
82
83
|
# Handle standard text/JSON results
|
|
83
84
|
else:
|
|
84
|
-
|
|
85
|
-
result_str = json.dumps(p_event.result, indent=2) if not isinstance(p_event.result, str) else p_event.result
|
|
86
|
-
except TypeError: # pragma: no cover
|
|
87
|
-
result_str = str(p_event.result)
|
|
85
|
+
result_str = format_to_clean_string(p_event.result)
|
|
88
86
|
content_part = (
|
|
89
87
|
f"Tool: {p_event.tool_name} (ID: {tool_invocation_id})\n"
|
|
90
88
|
f"Status: Success\n"
|
|
@@ -120,7 +118,7 @@ class ToolResultEventHandler(AgentEventHandler):
|
|
|
120
118
|
return
|
|
121
119
|
|
|
122
120
|
agent_id = context.agent_id
|
|
123
|
-
notifier: Optional['AgentExternalEventNotifier'] = context.
|
|
121
|
+
notifier: Optional['AgentExternalEventNotifier'] = context.status_manager.notifier if context.status_manager else None
|
|
124
122
|
|
|
125
123
|
# --- Step 1: Immediately process the incoming event ---
|
|
126
124
|
processed_event = event
|
|
@@ -144,7 +142,7 @@ class ToolResultEventHandler(AgentEventHandler):
|
|
|
144
142
|
if processed_event.error:
|
|
145
143
|
log_message = f"[TOOL_RESULT_ERROR_PROCESSED] Agent_ID: {agent_id}, Tool: {processed_event.tool_name}, Invocation_ID: {tool_invocation_id}, Error: {processed_event.error}"
|
|
146
144
|
else:
|
|
147
|
-
log_message = f"[TOOL_RESULT_SUCCESS_PROCESSED] Agent_ID: {agent_id}, Tool: {processed_event.tool_name}, Invocation_ID: {tool_invocation_id}, Result: {
|
|
145
|
+
log_message = f"[TOOL_RESULT_SUCCESS_PROCESSED] Agent_ID: {agent_id}, Tool: {processed_event.tool_name}, Invocation_ID: {tool_invocation_id}, Result: {format_to_clean_string(processed_event.result)}"
|
|
148
146
|
|
|
149
147
|
try:
|
|
150
148
|
log_data = {
|
|
@@ -195,7 +193,8 @@ class ToolResultEventHandler(AgentEventHandler):
|
|
|
195
193
|
tool_name=original_invocation.name,
|
|
196
194
|
result=None,
|
|
197
195
|
error=f"Critical Error: Result for this tool call was lost.",
|
|
198
|
-
tool_invocation_id=original_invocation.id
|
|
196
|
+
tool_invocation_id=original_invocation.id,
|
|
197
|
+
turn_id=original_invocation.turn_id,
|
|
199
198
|
))
|
|
200
199
|
|
|
201
200
|
await self._dispatch_results_to_input_pipeline(sorted_results, context)
|
|
@@ -39,8 +39,8 @@ class UserInputMessageEventHandler(AgentEventHandler):
|
|
|
39
39
|
|
|
40
40
|
# --- UPDATED LOGIC: Check sender_type for system-generated tasks and notify TUI ---
|
|
41
41
|
if original_agent_input_user_msg.sender_type == SenderType.SYSTEM:
|
|
42
|
-
if context.
|
|
43
|
-
notifier: 'AgentExternalEventNotifier' = context.
|
|
42
|
+
if context.status_manager:
|
|
43
|
+
notifier: 'AgentExternalEventNotifier' = context.status_manager.notifier
|
|
44
44
|
notification_data = {
|
|
45
45
|
"sender_id": original_agent_input_user_msg.metadata.get("sender_id", "system"),
|
|
46
46
|
"content": original_agent_input_user_msg.content,
|
|
@@ -59,8 +59,15 @@ class UserInputMessageEventHandler(AgentEventHandler):
|
|
|
59
59
|
|
|
60
60
|
processor_instances = context.config.input_processors
|
|
61
61
|
if processor_instances:
|
|
62
|
+
valid_processors = []
|
|
63
|
+
for p in processor_instances:
|
|
64
|
+
if isinstance(p, BaseAgentUserInputMessageProcessor):
|
|
65
|
+
valid_processors.append(p)
|
|
66
|
+
else:
|
|
67
|
+
logger.error(f"Agent '{context.agent_id}': Invalid input processor type in config: {type(p)}. Skipping.")
|
|
68
|
+
|
|
62
69
|
# Sort processors by their order attribute
|
|
63
|
-
sorted_processors = sorted(
|
|
70
|
+
sorted_processors = sorted(valid_processors, key=lambda p: p.get_order())
|
|
64
71
|
processor_names = [p.get_name() for p in sorted_processors]
|
|
65
72
|
logger.debug(f"Agent '{context.agent_id}': Applying input processors in order: {processor_names}")
|
|
66
73
|
|