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
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
File: autobyteus/tools/browser/standalone/webpage_reader.py
|
|
3
|
-
This module provides a WebPageReader tool for reading and cleaning HTML content from webpages.
|
|
4
|
-
"""
|
|
5
|
-
|
|
6
|
-
import logging
|
|
7
|
-
from typing import Optional, TYPE_CHECKING, Any
|
|
8
|
-
from autobyteus.tools.base_tool import BaseTool
|
|
9
|
-
from autobyteus.tools.tool_config import ToolConfig
|
|
10
|
-
from autobyteus.utils.parameter_schema import ParameterSchema, ParameterDefinition, ParameterType
|
|
11
|
-
from autobyteus.tools.tool_category import ToolCategory
|
|
12
|
-
from brui_core.ui_integrator import UIIntegrator
|
|
13
|
-
from autobyteus.utils.html_cleaner import clean, CleaningMode
|
|
14
|
-
|
|
15
|
-
if TYPE_CHECKING:
|
|
16
|
-
from autobyteus.agent.context import AgentContext
|
|
17
|
-
|
|
18
|
-
logger = logging.getLogger(__name__)
|
|
19
|
-
|
|
20
|
-
class WebPageReader(BaseTool, UIIntegrator):
|
|
21
|
-
"""
|
|
22
|
-
A class that reads and cleans the HTML content from a given webpage using Playwright.
|
|
23
|
-
"""
|
|
24
|
-
CATEGORY = ToolCategory.WEB
|
|
25
|
-
|
|
26
|
-
def __init__(self, config: Optional[ToolConfig] = None):
|
|
27
|
-
BaseTool.__init__(self, config=config)
|
|
28
|
-
UIIntegrator.__init__(self)
|
|
29
|
-
|
|
30
|
-
cleaning_mode_to_use = CleaningMode.THOROUGH
|
|
31
|
-
if config:
|
|
32
|
-
cleaning_mode_value = config.get('cleaning_mode')
|
|
33
|
-
if cleaning_mode_value:
|
|
34
|
-
if isinstance(cleaning_mode_value, str):
|
|
35
|
-
try:
|
|
36
|
-
cleaning_mode_to_use = CleaningMode(cleaning_mode_value.upper())
|
|
37
|
-
except ValueError:
|
|
38
|
-
logger.warning(f"Invalid cleaning_mode string '{cleaning_mode_value}' in config for WebPageReader. Using THOROUGH.")
|
|
39
|
-
cleaning_mode_to_use = CleaningMode.THOROUGH
|
|
40
|
-
elif isinstance(cleaning_mode_value, CleaningMode):
|
|
41
|
-
cleaning_mode_to_use = cleaning_mode_value
|
|
42
|
-
else:
|
|
43
|
-
logger.warning(f"Invalid type for cleaning_mode in config for WebPageReader. Using THOROUGH.")
|
|
44
|
-
|
|
45
|
-
self.cleaning_mode = cleaning_mode_to_use
|
|
46
|
-
logger.debug(f"WebPageReader initialized with cleaning_mode: {self.cleaning_mode}")
|
|
47
|
-
|
|
48
|
-
@classmethod
|
|
49
|
-
def get_description(cls) -> str:
|
|
50
|
-
return "Reads and cleans the HTML content from a given webpage URL using Playwright."
|
|
51
|
-
|
|
52
|
-
@classmethod
|
|
53
|
-
def get_argument_schema(cls) -> Optional[ParameterSchema]:
|
|
54
|
-
"""Schema for arguments passed to the execute method."""
|
|
55
|
-
schema = ParameterSchema()
|
|
56
|
-
schema.add_parameter(ParameterDefinition(
|
|
57
|
-
name="url",
|
|
58
|
-
param_type=ParameterType.STRING,
|
|
59
|
-
description="The URL of the webpage to read content from.",
|
|
60
|
-
required=True
|
|
61
|
-
))
|
|
62
|
-
return schema
|
|
63
|
-
|
|
64
|
-
@classmethod
|
|
65
|
-
def get_config_schema(cls) -> Optional[ParameterSchema]:
|
|
66
|
-
"""Schema for parameters to configure the WebPageReader instance itself."""
|
|
67
|
-
schema = ParameterSchema()
|
|
68
|
-
schema.add_parameter(ParameterDefinition(
|
|
69
|
-
name="cleaning_mode",
|
|
70
|
-
param_type=ParameterType.ENUM,
|
|
71
|
-
description="Level of HTML content cleanup for webpage content. BASIC or THOROUGH.",
|
|
72
|
-
required=False,
|
|
73
|
-
default_value="THOROUGH",
|
|
74
|
-
enum_values=[mode.name for mode in CleaningMode]
|
|
75
|
-
))
|
|
76
|
-
return schema
|
|
77
|
-
|
|
78
|
-
async def _execute(self, context: 'AgentContext', url: str) -> str:
|
|
79
|
-
logger.info(f"WebPageReader executing for agent {context.agent_id} with URL: '{url}'")
|
|
80
|
-
|
|
81
|
-
try:
|
|
82
|
-
await self.initialize()
|
|
83
|
-
if not self.page:
|
|
84
|
-
logger.error("Playwright page not initialized in WebPageReader.")
|
|
85
|
-
raise RuntimeError("Playwright page not available for WebPageReader.")
|
|
86
|
-
|
|
87
|
-
await self.page.goto(url, timeout=60000, wait_until="domcontentloaded")
|
|
88
|
-
page_content = await self.page.content()
|
|
89
|
-
|
|
90
|
-
cleaned_content = clean(page_content, mode=self.cleaning_mode)
|
|
91
|
-
|
|
92
|
-
return f'''here is the html of the web page
|
|
93
|
-
<WebPageContentStart>
|
|
94
|
-
{cleaned_content}
|
|
95
|
-
</WebPageContentEnd>
|
|
96
|
-
'''
|
|
97
|
-
except Exception as e:
|
|
98
|
-
logger.error(f"Error reading webpage at URL '{url}': {e}", exc_info=True)
|
|
99
|
-
raise RuntimeError(f"WebPageReader failed for URL '{url}': {str(e)}")
|
|
100
|
-
finally:
|
|
101
|
-
await self.close()
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
from typing import Optional, TYPE_CHECKING, Any
|
|
2
|
-
from autobyteus.tools.base_tool import BaseTool
|
|
3
|
-
from autobyteus.tools.tool_config import ToolConfig
|
|
4
|
-
from autobyteus.utils.parameter_schema import ParameterSchema, ParameterDefinition, ParameterType
|
|
5
|
-
from autobyteus.tools.tool_category import ToolCategory
|
|
6
|
-
from brui_core.ui_integrator import UIIntegrator
|
|
7
|
-
import logging
|
|
8
|
-
import os
|
|
9
|
-
|
|
10
|
-
if TYPE_CHECKING:
|
|
11
|
-
from autobyteus.agent.context import AgentContext
|
|
12
|
-
|
|
13
|
-
logger = logging.getLogger(__name__)
|
|
14
|
-
|
|
15
|
-
class WebPageScreenshotTaker(BaseTool, UIIntegrator):
|
|
16
|
-
"""
|
|
17
|
-
A class that takes a screenshot of a given webpage using Playwright and saves it.
|
|
18
|
-
"""
|
|
19
|
-
CATEGORY = ToolCategory.WEB
|
|
20
|
-
|
|
21
|
-
def __init__(self, config: Optional[ToolConfig] = None):
|
|
22
|
-
BaseTool.__init__(self, config=config)
|
|
23
|
-
UIIntegrator.__init__(self)
|
|
24
|
-
|
|
25
|
-
self.full_page: bool = True
|
|
26
|
-
self.image_format: str = "png"
|
|
27
|
-
|
|
28
|
-
if config:
|
|
29
|
-
self.full_page = config.get('full_page', True)
|
|
30
|
-
self.image_format = str(config.get('image_format', 'png')).lower()
|
|
31
|
-
if self.image_format not in ["png", "jpeg"]:
|
|
32
|
-
logger.warning(f"Invalid image_format '{self.image_format}' in config. Defaulting to 'png'.")
|
|
33
|
-
self.image_format = "png"
|
|
34
|
-
logger.debug(f"WebPageScreenshotTaker initialized. Full page: {self.full_page}, Format: {self.image_format}")
|
|
35
|
-
|
|
36
|
-
@classmethod
|
|
37
|
-
def get_description(cls) -> str:
|
|
38
|
-
return "Takes a screenshot of a given webpage URL using Playwright and saves it to the specified file path. Returns the absolute path of the saved screenshot."
|
|
39
|
-
|
|
40
|
-
@classmethod
|
|
41
|
-
def get_argument_schema(cls) -> Optional[ParameterSchema]:
|
|
42
|
-
schema = ParameterSchema()
|
|
43
|
-
schema.add_parameter(ParameterDefinition(
|
|
44
|
-
name="url",
|
|
45
|
-
param_type=ParameterType.STRING,
|
|
46
|
-
description="The URL of the webpage to take a screenshot of.",
|
|
47
|
-
required=True
|
|
48
|
-
))
|
|
49
|
-
schema.add_parameter(ParameterDefinition(
|
|
50
|
-
name="file_path",
|
|
51
|
-
param_type=ParameterType.STRING,
|
|
52
|
-
description="The local file path (including filename and extension, e.g., 'screenshots/page.png') where the screenshot will be saved.",
|
|
53
|
-
required=True
|
|
54
|
-
))
|
|
55
|
-
return schema
|
|
56
|
-
|
|
57
|
-
@classmethod
|
|
58
|
-
def get_config_schema(cls) -> Optional[ParameterSchema]:
|
|
59
|
-
schema = ParameterSchema()
|
|
60
|
-
schema.add_parameter(ParameterDefinition(
|
|
61
|
-
name="full_page",
|
|
62
|
-
param_type=ParameterType.BOOLEAN,
|
|
63
|
-
description="Whether to capture the full scrollable page content or just the visible viewport by default for this instance.",
|
|
64
|
-
required=False,
|
|
65
|
-
default_value=True
|
|
66
|
-
))
|
|
67
|
-
schema.add_parameter(ParameterDefinition(
|
|
68
|
-
name="image_format",
|
|
69
|
-
param_type=ParameterType.ENUM,
|
|
70
|
-
description="Default image format for screenshots taken by this instance (png or jpeg).",
|
|
71
|
-
required=False,
|
|
72
|
-
default_value="png",
|
|
73
|
-
enum_values=["png", "jpeg"]
|
|
74
|
-
))
|
|
75
|
-
return schema
|
|
76
|
-
|
|
77
|
-
async def _execute(self, context: 'AgentContext', url: str, file_path: str) -> str:
|
|
78
|
-
logger.info(f"WebPageScreenshotTaker for agent {context.agent_id} taking screenshot of '{url}', saving to '{file_path}'.")
|
|
79
|
-
|
|
80
|
-
output_dir = os.path.dirname(file_path)
|
|
81
|
-
if output_dir:
|
|
82
|
-
os.makedirs(output_dir, exist_ok=True)
|
|
83
|
-
|
|
84
|
-
try:
|
|
85
|
-
await self.initialize()
|
|
86
|
-
if not self.page:
|
|
87
|
-
logger.error("Playwright page not initialized in WebPageScreenshotTaker.")
|
|
88
|
-
raise RuntimeError("Playwright page not available for WebPageScreenshotTaker.")
|
|
89
|
-
|
|
90
|
-
await self.page.goto(url, wait_until="networkidle", timeout=60000)
|
|
91
|
-
|
|
92
|
-
await self.page.screenshot(path=file_path, full_page=self.full_page, type=self.image_format) # type: ignore
|
|
93
|
-
|
|
94
|
-
absolute_file_path = os.path.abspath(file_path)
|
|
95
|
-
logger.info(f"Screenshot saved successfully to {absolute_file_path}")
|
|
96
|
-
return absolute_file_path
|
|
97
|
-
except Exception as e:
|
|
98
|
-
logger.error(f"Error taking screenshot of URL '{url}': {e}", exc_info=True)
|
|
99
|
-
raise RuntimeError(f"WebPageScreenshotTaker failed for URL '{url}': {str(e)}")
|
|
100
|
-
finally:
|
|
101
|
-
await self.close()
|
|
@@ -1,200 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
import re
|
|
3
|
-
import logging
|
|
4
|
-
from typing import TYPE_CHECKING, List
|
|
5
|
-
|
|
6
|
-
from autobyteus.tools.functional_tool import tool
|
|
7
|
-
from autobyteus.tools.tool_category import ToolCategory
|
|
8
|
-
|
|
9
|
-
if TYPE_CHECKING:
|
|
10
|
-
from autobyteus.agent.context import AgentContext
|
|
11
|
-
|
|
12
|
-
logger = logging.getLogger(__name__)
|
|
13
|
-
|
|
14
|
-
_HUNK_HEADER_RE = re.compile(r"^@@ -(?P<old_start>\d+)(?:,(?P<old_count>\d+))? \+(?P<new_start>\d+)(?:,(?P<new_count>\d+))? @@")
|
|
15
|
-
|
|
16
|
-
class PatchApplicationError(ValueError):
|
|
17
|
-
"""Raised when a unified diff patch cannot be applied to the target file."""
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
def _resolve_file_path(context: 'AgentContext', path: str) -> str:
|
|
21
|
-
"""Resolves an absolute path for the given input, using the agent workspace when needed."""
|
|
22
|
-
if os.path.isabs(path):
|
|
23
|
-
final_path = path
|
|
24
|
-
logger.debug("FileEdit: provided path '%s' is absolute.", path)
|
|
25
|
-
else:
|
|
26
|
-
if not context.workspace:
|
|
27
|
-
error_msg = ("Relative path '%s' provided, but no workspace is configured for agent '%s'. "
|
|
28
|
-
"A workspace is required to resolve relative paths.")
|
|
29
|
-
logger.error(error_msg, path, context.agent_id)
|
|
30
|
-
raise ValueError(error_msg % (path, context.agent_id))
|
|
31
|
-
base_path = context.workspace.get_base_path()
|
|
32
|
-
if not base_path or not isinstance(base_path, str):
|
|
33
|
-
error_msg = ("Agent '%s' has a configured workspace, but it provided an invalid base path ('%s'). "
|
|
34
|
-
"Cannot resolve relative path '%s'.")
|
|
35
|
-
logger.error(error_msg, context.agent_id, base_path, path)
|
|
36
|
-
raise ValueError(error_msg % (context.agent_id, base_path, path))
|
|
37
|
-
final_path = os.path.join(base_path, path)
|
|
38
|
-
logger.debug("FileEdit: resolved relative path '%s' against workspace base '%s' to '%s'.", path, base_path, final_path)
|
|
39
|
-
|
|
40
|
-
normalized_path = os.path.normpath(final_path)
|
|
41
|
-
logger.debug("FileEdit: normalized path to '%s'.", normalized_path)
|
|
42
|
-
return normalized_path
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
def _apply_unified_diff(original_lines: List[str], patch: str) -> List[str]:
|
|
46
|
-
"""Applies a unified diff patch to the provided original lines and returns the patched lines."""
|
|
47
|
-
if not patch or not patch.strip():
|
|
48
|
-
raise PatchApplicationError("Patch content is empty; nothing to apply.")
|
|
49
|
-
|
|
50
|
-
patched_lines: List[str] = []
|
|
51
|
-
orig_idx = 0
|
|
52
|
-
patch_lines = patch.splitlines(keepends=True)
|
|
53
|
-
line_idx = 0
|
|
54
|
-
|
|
55
|
-
while line_idx < len(patch_lines):
|
|
56
|
-
line = patch_lines[line_idx]
|
|
57
|
-
|
|
58
|
-
if line.startswith('---') or line.startswith('+++'):
|
|
59
|
-
logger.debug("FileEdit: skipping diff header line '%s'.", line.strip())
|
|
60
|
-
line_idx += 1
|
|
61
|
-
continue
|
|
62
|
-
|
|
63
|
-
if not line.startswith('@@'):
|
|
64
|
-
stripped = line.strip()
|
|
65
|
-
if stripped == '':
|
|
66
|
-
line_idx += 1
|
|
67
|
-
continue
|
|
68
|
-
raise PatchApplicationError(f"Unexpected content outside of hunk header: '{stripped}'.")
|
|
69
|
-
|
|
70
|
-
match = _HUNK_HEADER_RE.match(line)
|
|
71
|
-
if not match:
|
|
72
|
-
raise PatchApplicationError(f"Malformed hunk header: '{line.strip()}'.")
|
|
73
|
-
|
|
74
|
-
old_start = int(match.group('old_start'))
|
|
75
|
-
old_count = int(match.group('old_count') or '1')
|
|
76
|
-
new_start = int(match.group('new_start'))
|
|
77
|
-
new_count = int(match.group('new_count') or '1')
|
|
78
|
-
logger.debug("FileEdit: processing hunk old_start=%s old_count=%s new_start=%s new_count=%s.",
|
|
79
|
-
old_start, old_count, new_start, new_count)
|
|
80
|
-
|
|
81
|
-
target_idx = old_start - 1 if old_start > 0 else 0
|
|
82
|
-
if target_idx > len(original_lines):
|
|
83
|
-
raise PatchApplicationError("Patch hunk starts beyond end of file.")
|
|
84
|
-
if target_idx < orig_idx:
|
|
85
|
-
raise PatchApplicationError("Patch hunks overlap or are out of order.")
|
|
86
|
-
|
|
87
|
-
patched_lines.extend(original_lines[orig_idx:target_idx])
|
|
88
|
-
orig_idx = target_idx
|
|
89
|
-
|
|
90
|
-
line_idx += 1
|
|
91
|
-
hunk_consumed = 0
|
|
92
|
-
removed = 0
|
|
93
|
-
added = 0
|
|
94
|
-
|
|
95
|
-
while line_idx < len(patch_lines):
|
|
96
|
-
hunk_line = patch_lines[line_idx]
|
|
97
|
-
if hunk_line.startswith('@@'):
|
|
98
|
-
break
|
|
99
|
-
|
|
100
|
-
if hunk_line.startswith('-'):
|
|
101
|
-
if orig_idx >= len(original_lines):
|
|
102
|
-
raise PatchApplicationError("Patch attempts to remove lines beyond file length.")
|
|
103
|
-
if original_lines[orig_idx] != hunk_line[1:]:
|
|
104
|
-
raise PatchApplicationError("Patch removal does not match file content.")
|
|
105
|
-
orig_idx += 1
|
|
106
|
-
hunk_consumed += 1
|
|
107
|
-
removed += 1
|
|
108
|
-
elif hunk_line.startswith('+'):
|
|
109
|
-
patched_lines.append(hunk_line[1:])
|
|
110
|
-
added += 1
|
|
111
|
-
elif hunk_line.startswith(' '):
|
|
112
|
-
if orig_idx >= len(original_lines):
|
|
113
|
-
raise PatchApplicationError("Patch context exceeds file length.")
|
|
114
|
-
if original_lines[orig_idx] != hunk_line[1:]:
|
|
115
|
-
raise PatchApplicationError("Patch context does not match file content.")
|
|
116
|
-
patched_lines.append(original_lines[orig_idx])
|
|
117
|
-
orig_idx += 1
|
|
118
|
-
hunk_consumed += 1
|
|
119
|
-
elif hunk_line.startswith('\\'):
|
|
120
|
-
if hunk_line.strip() == '\':
|
|
121
|
-
if patched_lines:
|
|
122
|
-
patched_lines[-1] = patched_lines[-1].rstrip('\n')
|
|
123
|
-
else:
|
|
124
|
-
raise PatchApplicationError(f"Unsupported patch directive: '{hunk_line.strip()}'.")
|
|
125
|
-
elif hunk_line.strip() == '':
|
|
126
|
-
patched_lines.append(hunk_line)
|
|
127
|
-
else:
|
|
128
|
-
raise PatchApplicationError(f"Unsupported patch line: '{hunk_line.strip()}'.")
|
|
129
|
-
|
|
130
|
-
line_idx += 1
|
|
131
|
-
|
|
132
|
-
consumed_total = hunk_consumed
|
|
133
|
-
if old_count == 0:
|
|
134
|
-
if consumed_total != 0:
|
|
135
|
-
raise PatchApplicationError("Patch expects zero original lines but consumed some context.")
|
|
136
|
-
else:
|
|
137
|
-
if consumed_total != old_count:
|
|
138
|
-
raise PatchApplicationError(
|
|
139
|
-
f"Patch expected to consume {old_count} original lines but consumed {consumed_total}.")
|
|
140
|
-
|
|
141
|
-
context_lines = consumed_total - removed
|
|
142
|
-
expected_new_lines = context_lines + added
|
|
143
|
-
if new_count == 0:
|
|
144
|
-
if expected_new_lines != 0:
|
|
145
|
-
raise PatchApplicationError("Patch declares zero new lines but produced changes.")
|
|
146
|
-
else:
|
|
147
|
-
if expected_new_lines != new_count:
|
|
148
|
-
raise PatchApplicationError(
|
|
149
|
-
f"Patch expected to produce {new_count} new lines but produced {expected_new_lines}.")
|
|
150
|
-
|
|
151
|
-
patched_lines.extend(original_lines[orig_idx:])
|
|
152
|
-
return patched_lines
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
@tool(name="FileEdit", category=ToolCategory.FILE_SYSTEM)
|
|
156
|
-
async def file_edit(context: 'AgentContext', path: str, patch: str, create_if_missing: bool = False) -> str:
|
|
157
|
-
"""Applies a unified diff patch to update a text file without overwriting unrelated content.
|
|
158
|
-
|
|
159
|
-
Args:
|
|
160
|
-
path: Path to the target file. Relative paths are resolved against the agent workspace when available.
|
|
161
|
-
patch: Unified diff patch describing the edits to apply.
|
|
162
|
-
create_if_missing: When True, allows applying a patch that introduces content to a non-existent file.
|
|
163
|
-
|
|
164
|
-
Raises:
|
|
165
|
-
FileNotFoundError: If the file does not exist and create_if_missing is False.
|
|
166
|
-
PatchApplicationError: If the patch content cannot be applied cleanly.
|
|
167
|
-
IOError: If file reading or writing fails.
|
|
168
|
-
"""
|
|
169
|
-
logger.debug("FileEdit: requested edit for agent '%s' on path '%s'.", context.agent_id, path)
|
|
170
|
-
final_path = _resolve_file_path(context, path)
|
|
171
|
-
|
|
172
|
-
dir_path = os.path.dirname(final_path)
|
|
173
|
-
if dir_path and not os.path.exists(dir_path) and create_if_missing:
|
|
174
|
-
os.makedirs(dir_path, exist_ok=True)
|
|
175
|
-
|
|
176
|
-
file_exists = os.path.exists(final_path)
|
|
177
|
-
if not file_exists and not create_if_missing:
|
|
178
|
-
raise FileNotFoundError(f"The file at resolved path {final_path} does not exist.")
|
|
179
|
-
|
|
180
|
-
try:
|
|
181
|
-
original_lines: List[str]
|
|
182
|
-
if file_exists:
|
|
183
|
-
with open(final_path, 'r', encoding='utf-8') as source:
|
|
184
|
-
original_lines = source.read().splitlines(keepends=True)
|
|
185
|
-
else:
|
|
186
|
-
original_lines = []
|
|
187
|
-
|
|
188
|
-
patched_lines = _apply_unified_diff(original_lines, patch)
|
|
189
|
-
|
|
190
|
-
with open(final_path, 'w', encoding='utf-8') as destination:
|
|
191
|
-
destination.writelines(patched_lines)
|
|
192
|
-
|
|
193
|
-
logger.info("FileEdit: successfully applied patch to '%s'.", final_path)
|
|
194
|
-
return f"File edited successfully at {final_path}"
|
|
195
|
-
except PatchApplicationError as patch_err:
|
|
196
|
-
logger.error("FileEdit: failed to apply patch to '%s': %s", final_path, patch_err, exc_info=True)
|
|
197
|
-
raise patch_err
|
|
198
|
-
except Exception as exc: # pragma: no cover - general safeguard
|
|
199
|
-
logger.error("FileEdit: unexpected error while editing '%s': %s", final_path, exc, exc_info=True)
|
|
200
|
-
raise IOError(f"Could not edit file at '{final_path}': {exc}")
|
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
import json
|
|
3
|
-
import logging
|
|
4
|
-
import aiohttp
|
|
5
|
-
from typing import Optional, TYPE_CHECKING, Any, Dict, List
|
|
6
|
-
|
|
7
|
-
from autobyteus.tools.base_tool import BaseTool
|
|
8
|
-
from autobyteus.tools.tool_config import ToolConfig
|
|
9
|
-
from autobyteus.utils.parameter_schema import ParameterSchema, ParameterDefinition, ParameterType
|
|
10
|
-
from autobyteus.tools.tool_category import ToolCategory
|
|
11
|
-
|
|
12
|
-
if TYPE_CHECKING:
|
|
13
|
-
from autobyteus.agent.context import AgentContext
|
|
14
|
-
|
|
15
|
-
logger = logging.getLogger(__name__)
|
|
16
|
-
|
|
17
|
-
class GoogleSearch(BaseTool):
|
|
18
|
-
"""
|
|
19
|
-
Performs a Google search using the Serper.dev API and returns a structured summary of the results.
|
|
20
|
-
This tool requires a Serper API key, which should be set in the SERPER_API_KEY environment variable.
|
|
21
|
-
"""
|
|
22
|
-
CATEGORY = ToolCategory.WEB
|
|
23
|
-
API_URL = "https://google.serper.dev/search"
|
|
24
|
-
|
|
25
|
-
def __init__(self, config: Optional[ToolConfig] = None):
|
|
26
|
-
super().__init__(config=config)
|
|
27
|
-
self.api_key: Optional[str] = None
|
|
28
|
-
|
|
29
|
-
if config:
|
|
30
|
-
self.api_key = config.get('api_key')
|
|
31
|
-
|
|
32
|
-
if not self.api_key:
|
|
33
|
-
self.api_key = os.getenv("SERPER_API_KEY")
|
|
34
|
-
|
|
35
|
-
if not self.api_key:
|
|
36
|
-
raise ValueError(
|
|
37
|
-
"GoogleSearch tool requires a Serper API key. "
|
|
38
|
-
"Please provide it via the 'api_key' config parameter or set the 'SERPER_API_KEY' environment variable."
|
|
39
|
-
)
|
|
40
|
-
logger.debug("GoogleSearch (API-based) tool initialized.")
|
|
41
|
-
|
|
42
|
-
@classmethod
|
|
43
|
-
def get_name(cls) -> str:
|
|
44
|
-
return "GoogleSearch"
|
|
45
|
-
|
|
46
|
-
@classmethod
|
|
47
|
-
def get_description(cls) -> str:
|
|
48
|
-
return (
|
|
49
|
-
"Searches Google for a given query using the Serper API. "
|
|
50
|
-
"Returns a concise, structured summary of search results, including direct answers and top organic links."
|
|
51
|
-
)
|
|
52
|
-
|
|
53
|
-
@classmethod
|
|
54
|
-
def get_argument_schema(cls) -> Optional[ParameterSchema]:
|
|
55
|
-
schema = ParameterSchema()
|
|
56
|
-
schema.add_parameter(ParameterDefinition(
|
|
57
|
-
name="query",
|
|
58
|
-
param_type=ParameterType.STRING,
|
|
59
|
-
description="The search query string.",
|
|
60
|
-
required=True
|
|
61
|
-
))
|
|
62
|
-
schema.add_parameter(ParameterDefinition(
|
|
63
|
-
name="num_results",
|
|
64
|
-
param_type=ParameterType.INTEGER,
|
|
65
|
-
description="The number of organic search results to return.",
|
|
66
|
-
required=False,
|
|
67
|
-
default_value=5,
|
|
68
|
-
min_value=1,
|
|
69
|
-
max_value=10
|
|
70
|
-
))
|
|
71
|
-
return schema
|
|
72
|
-
|
|
73
|
-
@classmethod
|
|
74
|
-
def get_config_schema(cls) -> Optional[ParameterSchema]:
|
|
75
|
-
schema = ParameterSchema()
|
|
76
|
-
schema.add_parameter(ParameterDefinition(
|
|
77
|
-
name="api_key",
|
|
78
|
-
param_type=ParameterType.STRING,
|
|
79
|
-
description="The API key for the Serper.dev service. Overrides the SERPER_API_KEY environment variable.",
|
|
80
|
-
required=False
|
|
81
|
-
))
|
|
82
|
-
return schema
|
|
83
|
-
|
|
84
|
-
def _format_results(self, data: Dict[str, Any]) -> str:
|
|
85
|
-
"""Formats the JSON response from Serper into a clean string for an LLM."""
|
|
86
|
-
summary_parts = []
|
|
87
|
-
|
|
88
|
-
# 1. Answer Box (most important for direct questions)
|
|
89
|
-
if "answerBox" in data:
|
|
90
|
-
answer_box = data["answerBox"]
|
|
91
|
-
title = answer_box.get("title", "")
|
|
92
|
-
snippet = answer_box.get("snippet") or answer_box.get("answer")
|
|
93
|
-
summary_parts.append(f"Direct Answer for '{title}':\n{snippet}")
|
|
94
|
-
|
|
95
|
-
# 2. Knowledge Graph (for entity information)
|
|
96
|
-
if "knowledgeGraph" in data:
|
|
97
|
-
kg = data["knowledgeGraph"]
|
|
98
|
-
title = kg.get("title", "")
|
|
99
|
-
description = kg.get("description")
|
|
100
|
-
summary_parts.append(f"Summary for '{title}':\n{description}")
|
|
101
|
-
|
|
102
|
-
# 3. Organic Results (the main search links)
|
|
103
|
-
if "organic" in data and data["organic"]:
|
|
104
|
-
organic_results = data["organic"]
|
|
105
|
-
results_str = "\n".join(
|
|
106
|
-
f"{i+1}. {result.get('title', 'No Title')}\n"
|
|
107
|
-
f" Link: {result.get('link', 'No Link')}\n"
|
|
108
|
-
f" Snippet: {result.get('snippet', 'No Snippet')}"
|
|
109
|
-
for i, result in enumerate(organic_results)
|
|
110
|
-
)
|
|
111
|
-
summary_parts.append(f"Search Results:\n{results_str}")
|
|
112
|
-
|
|
113
|
-
if not summary_parts:
|
|
114
|
-
return "No relevant information found for the query."
|
|
115
|
-
|
|
116
|
-
return "\n\n---\n\n".join(summary_parts)
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
async def _execute(self, context: 'AgentContext', query: str, num_results: int = 5) -> str:
|
|
120
|
-
logger.info(f"Executing GoogleSearch (API) for agent {context.agent_id} with query: '{query}'")
|
|
121
|
-
|
|
122
|
-
headers = {
|
|
123
|
-
'X-API-KEY': self.api_key,
|
|
124
|
-
'Content-Type': 'application/json'
|
|
125
|
-
}
|
|
126
|
-
payload = json.dumps({
|
|
127
|
-
"q": query,
|
|
128
|
-
"num": num_results
|
|
129
|
-
})
|
|
130
|
-
|
|
131
|
-
try:
|
|
132
|
-
async with aiohttp.ClientSession() as session:
|
|
133
|
-
async with session.post(self.API_URL, headers=headers, data=payload) as response:
|
|
134
|
-
if response.status == 200:
|
|
135
|
-
data = await response.json()
|
|
136
|
-
return self._format_results(data)
|
|
137
|
-
else:
|
|
138
|
-
error_text = await response.text()
|
|
139
|
-
logger.error(
|
|
140
|
-
f"Serper API returned a non-200 status code: {response.status}. "
|
|
141
|
-
f"Response: {error_text}"
|
|
142
|
-
)
|
|
143
|
-
raise RuntimeError(f"API request failed with status {response.status}: {error_text}")
|
|
144
|
-
except aiohttp.ClientError as e:
|
|
145
|
-
logger.error(f"Network error during GoogleSearch API call: {e}", exc_info=True)
|
|
146
|
-
raise RuntimeError(f"A network error occurred: {e}")
|
|
147
|
-
except Exception as e:
|
|
148
|
-
logger.error(f"An unexpected error occurred in GoogleSearch tool: {e}", exc_info=True)
|
|
149
|
-
raise
|