autobyteus 1.2.1__py3-none-any.whl → 1.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- autobyteus/agent/agent.py +15 -5
- autobyteus/agent/bootstrap_steps/__init__.py +3 -3
- autobyteus/agent/bootstrap_steps/agent_bootstrapper.py +5 -59
- autobyteus/agent/bootstrap_steps/base_bootstrap_step.py +1 -4
- autobyteus/agent/bootstrap_steps/mcp_server_prewarming_step.py +1 -3
- autobyteus/agent/bootstrap_steps/system_prompt_processing_step.py +16 -13
- autobyteus/agent/bootstrap_steps/working_context_snapshot_restore_step.py +38 -0
- autobyteus/agent/bootstrap_steps/workspace_context_initialization_step.py +2 -4
- autobyteus/agent/context/agent_config.py +47 -20
- autobyteus/agent/context/agent_context.py +23 -18
- autobyteus/agent/context/agent_runtime_state.py +21 -19
- autobyteus/agent/events/__init__.py +16 -1
- autobyteus/agent/events/agent_events.py +43 -3
- autobyteus/agent/events/agent_input_event_queue_manager.py +79 -26
- autobyteus/agent/events/event_store.py +57 -0
- autobyteus/agent/events/notifiers.py +69 -59
- autobyteus/agent/events/worker_event_dispatcher.py +21 -64
- autobyteus/agent/factory/agent_factory.py +83 -6
- autobyteus/agent/handlers/__init__.py +2 -0
- autobyteus/agent/handlers/approved_tool_invocation_event_handler.py +51 -34
- autobyteus/agent/handlers/bootstrap_event_handler.py +155 -0
- autobyteus/agent/handlers/inter_agent_message_event_handler.py +10 -0
- autobyteus/agent/handlers/lifecycle_event_logger.py +19 -11
- autobyteus/agent/handlers/llm_complete_response_received_event_handler.py +10 -15
- autobyteus/agent/handlers/llm_user_message_ready_event_handler.py +188 -48
- autobyteus/agent/handlers/tool_execution_approval_event_handler.py +0 -10
- autobyteus/agent/handlers/tool_invocation_request_event_handler.py +53 -48
- autobyteus/agent/handlers/tool_result_event_handler.py +7 -8
- autobyteus/agent/handlers/user_input_message_event_handler.py +10 -3
- autobyteus/agent/input_processor/memory_ingest_input_processor.py +44 -0
- autobyteus/agent/lifecycle/__init__.py +12 -0
- autobyteus/agent/lifecycle/base_processor.py +109 -0
- autobyteus/agent/lifecycle/events.py +35 -0
- autobyteus/agent/lifecycle/processor_definition.py +36 -0
- autobyteus/agent/lifecycle/processor_registry.py +106 -0
- autobyteus/agent/llm_request_assembler.py +98 -0
- autobyteus/agent/llm_response_processor/__init__.py +1 -8
- autobyteus/agent/message/context_file_type.py +1 -1
- autobyteus/agent/runtime/agent_runtime.py +29 -21
- autobyteus/agent/runtime/agent_worker.py +98 -19
- autobyteus/agent/shutdown_steps/__init__.py +2 -0
- autobyteus/agent/shutdown_steps/agent_shutdown_orchestrator.py +2 -0
- autobyteus/agent/shutdown_steps/tool_cleanup_step.py +58 -0
- autobyteus/agent/status/__init__.py +14 -0
- autobyteus/agent/status/manager.py +93 -0
- autobyteus/agent/status/status_deriver.py +96 -0
- autobyteus/agent/{phases/phase_enum.py → status/status_enum.py} +16 -16
- autobyteus/agent/status/status_update_utils.py +73 -0
- autobyteus/agent/streaming/__init__.py +52 -5
- autobyteus/agent/streaming/adapters/__init__.py +18 -0
- autobyteus/agent/streaming/adapters/invocation_adapter.py +184 -0
- autobyteus/agent/streaming/adapters/tool_call_parsing.py +163 -0
- autobyteus/agent/streaming/adapters/tool_syntax_registry.py +67 -0
- autobyteus/agent/streaming/agent_event_stream.py +3 -183
- autobyteus/agent/streaming/api_tool_call/__init__.py +16 -0
- autobyteus/agent/streaming/api_tool_call/file_content_streamer.py +56 -0
- autobyteus/agent/streaming/api_tool_call/json_string_field_extractor.py +175 -0
- autobyteus/agent/streaming/api_tool_call_streaming_response_handler.py +4 -0
- autobyteus/agent/streaming/events/__init__.py +6 -0
- autobyteus/agent/streaming/events/stream_event_payloads.py +284 -0
- autobyteus/agent/streaming/events/stream_events.py +141 -0
- autobyteus/agent/streaming/handlers/__init__.py +15 -0
- autobyteus/agent/streaming/handlers/api_tool_call_streaming_response_handler.py +303 -0
- autobyteus/agent/streaming/handlers/parsing_streaming_response_handler.py +107 -0
- autobyteus/agent/streaming/handlers/pass_through_streaming_response_handler.py +107 -0
- autobyteus/agent/streaming/handlers/streaming_handler_factory.py +177 -0
- autobyteus/agent/streaming/handlers/streaming_response_handler.py +58 -0
- autobyteus/agent/streaming/parser/__init__.py +61 -0
- autobyteus/agent/streaming/parser/event_emitter.py +181 -0
- autobyteus/agent/streaming/parser/events.py +4 -0
- autobyteus/agent/streaming/parser/invocation_adapter.py +4 -0
- autobyteus/agent/streaming/parser/json_parsing_strategies/__init__.py +19 -0
- autobyteus/agent/streaming/parser/json_parsing_strategies/base.py +32 -0
- autobyteus/agent/streaming/parser/json_parsing_strategies/default.py +34 -0
- autobyteus/agent/streaming/parser/json_parsing_strategies/gemini.py +31 -0
- autobyteus/agent/streaming/parser/json_parsing_strategies/openai.py +64 -0
- autobyteus/agent/streaming/parser/json_parsing_strategies/registry.py +75 -0
- autobyteus/agent/streaming/parser/parser_context.py +227 -0
- autobyteus/agent/streaming/parser/parser_factory.py +132 -0
- autobyteus/agent/streaming/parser/sentinel_format.py +7 -0
- autobyteus/agent/streaming/parser/state_factory.py +62 -0
- autobyteus/agent/streaming/parser/states/__init__.py +1 -0
- autobyteus/agent/streaming/parser/states/base_state.py +60 -0
- autobyteus/agent/streaming/parser/states/custom_xml_tag_run_bash_parsing_state.py +38 -0
- autobyteus/agent/streaming/parser/states/custom_xml_tag_write_file_parsing_state.py +55 -0
- autobyteus/agent/streaming/parser/states/delimited_content_state.py +146 -0
- autobyteus/agent/streaming/parser/states/json_initialization_state.py +144 -0
- autobyteus/agent/streaming/parser/states/json_tool_parsing_state.py +137 -0
- autobyteus/agent/streaming/parser/states/sentinel_content_state.py +30 -0
- autobyteus/agent/streaming/parser/states/sentinel_initialization_state.py +117 -0
- autobyteus/agent/streaming/parser/states/text_state.py +78 -0
- autobyteus/agent/streaming/parser/states/xml_patch_file_tool_parsing_state.py +328 -0
- autobyteus/agent/streaming/parser/states/xml_run_bash_tool_parsing_state.py +129 -0
- autobyteus/agent/streaming/parser/states/xml_tag_initialization_state.py +151 -0
- autobyteus/agent/streaming/parser/states/xml_tool_parsing_state.py +63 -0
- autobyteus/agent/streaming/parser/states/xml_write_file_tool_parsing_state.py +343 -0
- autobyteus/agent/streaming/parser/strategies/__init__.py +17 -0
- autobyteus/agent/streaming/parser/strategies/base.py +24 -0
- autobyteus/agent/streaming/parser/strategies/json_tool_strategy.py +26 -0
- autobyteus/agent/streaming/parser/strategies/registry.py +28 -0
- autobyteus/agent/streaming/parser/strategies/sentinel_strategy.py +23 -0
- autobyteus/agent/streaming/parser/strategies/xml_tag_strategy.py +21 -0
- autobyteus/agent/streaming/parser/stream_scanner.py +167 -0
- autobyteus/agent/streaming/parser/streaming_parser.py +212 -0
- autobyteus/agent/streaming/parser/tool_call_parsing.py +4 -0
- autobyteus/agent/streaming/parser/tool_constants.py +7 -0
- autobyteus/agent/streaming/parser/tool_syntax_registry.py +4 -0
- autobyteus/agent/streaming/parser/xml_tool_parsing_state_registry.py +55 -0
- autobyteus/agent/streaming/parsing_streaming_response_handler.py +4 -0
- autobyteus/agent/streaming/pass_through_streaming_response_handler.py +4 -0
- autobyteus/agent/streaming/queue_streamer.py +3 -57
- autobyteus/agent/streaming/segments/__init__.py +5 -0
- autobyteus/agent/streaming/segments/segment_events.py +82 -0
- autobyteus/agent/streaming/stream_event_payloads.py +2 -223
- autobyteus/agent/streaming/stream_events.py +3 -140
- autobyteus/agent/streaming/streaming_handler_factory.py +4 -0
- autobyteus/agent/streaming/streaming_response_handler.py +4 -0
- autobyteus/agent/streaming/streams/__init__.py +5 -0
- autobyteus/agent/streaming/streams/agent_event_stream.py +197 -0
- autobyteus/agent/streaming/utils/__init__.py +5 -0
- autobyteus/agent/streaming/utils/queue_streamer.py +59 -0
- autobyteus/agent/system_prompt_processor/__init__.py +2 -0
- autobyteus/agent/system_prompt_processor/available_skills_processor.py +96 -0
- autobyteus/agent/system_prompt_processor/base_processor.py +1 -1
- autobyteus/agent/system_prompt_processor/processor_meta.py +15 -2
- autobyteus/agent/system_prompt_processor/tool_manifest_injector_processor.py +39 -58
- autobyteus/agent/token_budget.py +56 -0
- autobyteus/agent/tool_execution_result_processor/memory_ingest_tool_result_processor.py +29 -0
- autobyteus/agent/tool_invocation.py +16 -40
- autobyteus/agent/tool_invocation_preprocessor/__init__.py +9 -0
- autobyteus/agent/tool_invocation_preprocessor/base_preprocessor.py +45 -0
- autobyteus/agent/tool_invocation_preprocessor/processor_definition.py +15 -0
- autobyteus/agent/tool_invocation_preprocessor/processor_meta.py +33 -0
- autobyteus/agent/tool_invocation_preprocessor/processor_registry.py +60 -0
- autobyteus/agent/utils/wait_for_idle.py +12 -14
- autobyteus/agent/workspace/base_workspace.py +6 -27
- autobyteus/agent_team/agent_team.py +3 -3
- autobyteus/agent_team/agent_team_builder.py +1 -41
- autobyteus/agent_team/bootstrap_steps/__init__.py +0 -4
- autobyteus/agent_team/bootstrap_steps/agent_configuration_preparation_step.py +8 -18
- autobyteus/agent_team/bootstrap_steps/agent_team_bootstrapper.py +4 -16
- autobyteus/agent_team/bootstrap_steps/base_agent_team_bootstrap_step.py +1 -2
- autobyteus/agent_team/bootstrap_steps/coordinator_initialization_step.py +1 -2
- autobyteus/agent_team/bootstrap_steps/task_notifier_initialization_step.py +1 -2
- autobyteus/agent_team/bootstrap_steps/team_context_initialization_step.py +4 -4
- autobyteus/agent_team/context/agent_team_config.py +6 -3
- autobyteus/agent_team/context/agent_team_context.py +25 -3
- autobyteus/agent_team/context/agent_team_runtime_state.py +9 -6
- autobyteus/agent_team/events/__init__.py +11 -0
- autobyteus/agent_team/events/agent_team_event_dispatcher.py +22 -9
- autobyteus/agent_team/events/agent_team_events.py +16 -0
- autobyteus/agent_team/events/event_store.py +57 -0
- autobyteus/agent_team/factory/agent_team_factory.py +8 -0
- autobyteus/agent_team/handlers/inter_agent_message_request_event_handler.py +18 -2
- autobyteus/agent_team/handlers/lifecycle_agent_team_event_handler.py +21 -5
- autobyteus/agent_team/handlers/process_user_message_event_handler.py +17 -8
- autobyteus/agent_team/handlers/tool_approval_team_event_handler.py +19 -4
- autobyteus/agent_team/runtime/agent_team_runtime.py +41 -10
- autobyteus/agent_team/runtime/agent_team_worker.py +69 -5
- autobyteus/agent_team/status/__init__.py +14 -0
- autobyteus/agent_team/status/agent_team_status.py +18 -0
- autobyteus/agent_team/status/agent_team_status_manager.py +33 -0
- autobyteus/agent_team/status/status_deriver.py +62 -0
- autobyteus/agent_team/status/status_update_utils.py +42 -0
- autobyteus/agent_team/streaming/__init__.py +2 -2
- autobyteus/agent_team/streaming/agent_team_event_notifier.py +6 -6
- autobyteus/agent_team/streaming/agent_team_stream_event_payloads.py +4 -4
- autobyteus/agent_team/streaming/agent_team_stream_events.py +3 -3
- autobyteus/agent_team/system_prompt_processor/__init__.py +6 -0
- autobyteus/agent_team/system_prompt_processor/team_manifest_injector_processor.py +76 -0
- autobyteus/agent_team/task_notification/task_notification_mode.py +19 -0
- autobyteus/agent_team/utils/wait_for_idle.py +4 -4
- autobyteus/cli/agent_cli.py +18 -10
- autobyteus/cli/agent_team_tui/app.py +14 -11
- autobyteus/cli/agent_team_tui/state.py +13 -15
- autobyteus/cli/agent_team_tui/widgets/agent_list_sidebar.py +15 -15
- autobyteus/cli/agent_team_tui/widgets/focus_pane.py +143 -36
- autobyteus/cli/agent_team_tui/widgets/renderables.py +1 -1
- autobyteus/cli/agent_team_tui/widgets/shared.py +25 -25
- autobyteus/cli/cli_display.py +193 -44
- autobyteus/cli/workflow_tui/app.py +9 -10
- autobyteus/cli/workflow_tui/state.py +14 -16
- autobyteus/cli/workflow_tui/widgets/agent_list_sidebar.py +15 -15
- autobyteus/cli/workflow_tui/widgets/focus_pane.py +137 -35
- autobyteus/cli/workflow_tui/widgets/renderables.py +1 -1
- autobyteus/cli/workflow_tui/widgets/shared.py +25 -25
- autobyteus/clients/autobyteus_client.py +94 -1
- autobyteus/events/event_types.py +11 -18
- autobyteus/llm/api/autobyteus_llm.py +33 -29
- autobyteus/llm/api/claude_llm.py +142 -36
- autobyteus/llm/api/gemini_llm.py +163 -59
- autobyteus/llm/api/grok_llm.py +1 -1
- autobyteus/llm/api/minimax_llm.py +26 -0
- autobyteus/llm/api/mistral_llm.py +113 -87
- autobyteus/llm/api/ollama_llm.py +9 -42
- autobyteus/llm/api/openai_compatible_llm.py +127 -91
- autobyteus/llm/api/openai_llm.py +3 -3
- autobyteus/llm/api/openai_responses_llm.py +324 -0
- autobyteus/llm/api/zhipu_llm.py +21 -2
- autobyteus/llm/autobyteus_provider.py +70 -60
- autobyteus/llm/base_llm.py +85 -81
- autobyteus/llm/converters/__init__.py +14 -0
- autobyteus/llm/converters/anthropic_tool_call_converter.py +37 -0
- autobyteus/llm/converters/gemini_tool_call_converter.py +57 -0
- autobyteus/llm/converters/mistral_tool_call_converter.py +37 -0
- autobyteus/llm/converters/openai_tool_call_converter.py +38 -0
- autobyteus/llm/extensions/base_extension.py +6 -12
- autobyteus/llm/extensions/token_usage_tracking_extension.py +45 -18
- autobyteus/llm/llm_factory.py +282 -204
- autobyteus/llm/lmstudio_provider.py +60 -49
- autobyteus/llm/models.py +35 -2
- autobyteus/llm/ollama_provider.py +60 -49
- autobyteus/llm/ollama_provider_resolver.py +0 -1
- autobyteus/llm/prompt_renderers/__init__.py +19 -0
- autobyteus/llm/prompt_renderers/anthropic_prompt_renderer.py +104 -0
- autobyteus/llm/prompt_renderers/autobyteus_prompt_renderer.py +19 -0
- autobyteus/llm/prompt_renderers/base_prompt_renderer.py +10 -0
- autobyteus/llm/prompt_renderers/gemini_prompt_renderer.py +63 -0
- autobyteus/llm/prompt_renderers/mistral_prompt_renderer.py +87 -0
- autobyteus/llm/prompt_renderers/ollama_prompt_renderer.py +51 -0
- autobyteus/llm/prompt_renderers/openai_chat_renderer.py +97 -0
- autobyteus/llm/prompt_renderers/openai_responses_renderer.py +101 -0
- autobyteus/llm/providers.py +1 -3
- autobyteus/llm/token_counter/claude_token_counter.py +56 -25
- autobyteus/llm/token_counter/mistral_token_counter.py +12 -8
- autobyteus/llm/token_counter/openai_token_counter.py +24 -5
- autobyteus/llm/token_counter/token_counter_factory.py +12 -5
- autobyteus/llm/utils/llm_config.py +6 -12
- autobyteus/llm/utils/media_payload_formatter.py +27 -20
- autobyteus/llm/utils/messages.py +55 -3
- autobyteus/llm/utils/response_types.py +3 -0
- autobyteus/llm/utils/tool_call_delta.py +31 -0
- autobyteus/memory/__init__.py +35 -0
- autobyteus/memory/compaction/__init__.py +9 -0
- autobyteus/memory/compaction/compaction_result.py +8 -0
- autobyteus/memory/compaction/compactor.py +89 -0
- autobyteus/memory/compaction/summarizer.py +11 -0
- autobyteus/memory/compaction_snapshot_builder.py +84 -0
- autobyteus/memory/memory_manager.py +205 -0
- autobyteus/memory/models/__init__.py +14 -0
- autobyteus/memory/models/episodic_item.py +41 -0
- autobyteus/memory/models/memory_types.py +7 -0
- autobyteus/memory/models/raw_trace_item.py +79 -0
- autobyteus/memory/models/semantic_item.py +41 -0
- autobyteus/memory/models/tool_interaction.py +20 -0
- autobyteus/memory/path_resolver.py +27 -0
- autobyteus/memory/policies/__init__.py +5 -0
- autobyteus/memory/policies/compaction_policy.py +16 -0
- autobyteus/memory/restore/__init__.py +1 -0
- autobyteus/memory/restore/working_context_snapshot_bootstrapper.py +61 -0
- autobyteus/memory/retrieval/__init__.py +7 -0
- autobyteus/memory/retrieval/memory_bundle.py +11 -0
- autobyteus/memory/retrieval/retriever.py +13 -0
- autobyteus/memory/store/__init__.py +9 -0
- autobyteus/memory/store/base_store.py +14 -0
- autobyteus/memory/store/file_store.py +98 -0
- autobyteus/memory/store/working_context_snapshot_store.py +28 -0
- autobyteus/memory/tool_interaction_builder.py +46 -0
- autobyteus/memory/turn_tracker.py +9 -0
- autobyteus/memory/working_context_snapshot.py +69 -0
- autobyteus/memory/working_context_snapshot_serializer.py +135 -0
- autobyteus/multimedia/audio/api/autobyteus_audio_client.py +19 -5
- autobyteus/multimedia/audio/api/gemini_audio_client.py +109 -16
- autobyteus/multimedia/audio/audio_client_factory.py +47 -9
- autobyteus/multimedia/audio/audio_model.py +2 -1
- autobyteus/multimedia/image/api/autobyteus_image_client.py +19 -5
- autobyteus/multimedia/image/api/gemini_image_client.py +39 -17
- autobyteus/multimedia/image/api/openai_image_client.py +125 -43
- autobyteus/multimedia/image/autobyteus_image_provider.py +2 -1
- autobyteus/multimedia/image/image_client_factory.py +47 -15
- autobyteus/multimedia/image/image_model.py +5 -2
- autobyteus/multimedia/providers.py +3 -2
- autobyteus/skills/loader.py +71 -0
- autobyteus/skills/model.py +11 -0
- autobyteus/skills/registry.py +70 -0
- autobyteus/task_management/tools/todo_tools/add_todo.py +2 -2
- autobyteus/task_management/tools/todo_tools/create_todo_list.py +2 -2
- autobyteus/task_management/tools/todo_tools/update_todo_status.py +2 -2
- autobyteus/tools/__init__.py +34 -47
- autobyteus/tools/base_tool.py +7 -0
- autobyteus/tools/file/__init__.py +2 -6
- autobyteus/tools/file/patch_file.py +149 -0
- autobyteus/tools/file/read_file.py +36 -5
- autobyteus/tools/file/write_file.py +4 -1
- autobyteus/tools/functional_tool.py +43 -6
- autobyteus/tools/mcp/__init__.py +2 -0
- autobyteus/tools/mcp/config_service.py +5 -1
- autobyteus/tools/mcp/server/__init__.py +2 -0
- autobyteus/tools/mcp/server/http_managed_mcp_server.py +1 -1
- autobyteus/tools/mcp/server/websocket_managed_mcp_server.py +141 -0
- autobyteus/tools/mcp/server_instance_manager.py +8 -1
- autobyteus/tools/mcp/types.py +61 -0
- autobyteus/tools/multimedia/audio_tools.py +70 -17
- autobyteus/tools/multimedia/download_media_tool.py +18 -4
- autobyteus/tools/multimedia/image_tools.py +246 -62
- autobyteus/tools/operation_executor/journal_manager.py +107 -0
- autobyteus/tools/operation_executor/operation_event_buffer.py +57 -0
- autobyteus/tools/operation_executor/operation_event_producer.py +29 -0
- autobyteus/tools/operation_executor/operation_executor.py +58 -0
- autobyteus/tools/registry/tool_definition.py +43 -2
- autobyteus/tools/skill/load_skill.py +50 -0
- autobyteus/tools/terminal/__init__.py +45 -0
- autobyteus/tools/terminal/ansi_utils.py +32 -0
- autobyteus/tools/terminal/background_process_manager.py +233 -0
- autobyteus/tools/terminal/output_buffer.py +105 -0
- autobyteus/tools/terminal/prompt_detector.py +63 -0
- autobyteus/tools/terminal/pty_session.py +241 -0
- autobyteus/tools/terminal/session_factory.py +20 -0
- autobyteus/tools/terminal/terminal_session_manager.py +226 -0
- autobyteus/tools/terminal/tools/__init__.py +13 -0
- autobyteus/tools/terminal/tools/get_process_output.py +81 -0
- autobyteus/tools/terminal/tools/run_bash.py +109 -0
- autobyteus/tools/terminal/tools/start_background_process.py +104 -0
- autobyteus/tools/terminal/tools/stop_background_process.py +67 -0
- autobyteus/tools/terminal/types.py +54 -0
- autobyteus/tools/terminal/wsl_tmux_session.py +221 -0
- autobyteus/tools/terminal/wsl_utils.py +156 -0
- autobyteus/tools/transaction_management/backup_handler.py +48 -0
- autobyteus/tools/transaction_management/operation_lifecycle_manager.py +62 -0
- autobyteus/tools/usage/__init__.py +1 -2
- autobyteus/tools/usage/formatters/__init__.py +17 -1
- autobyteus/tools/usage/formatters/base_formatter.py +8 -0
- autobyteus/tools/usage/formatters/default_xml_schema_formatter.py +2 -2
- autobyteus/tools/usage/formatters/mistral_json_schema_formatter.py +18 -0
- autobyteus/tools/usage/formatters/patch_file_xml_example_formatter.py +64 -0
- autobyteus/tools/usage/formatters/patch_file_xml_schema_formatter.py +31 -0
- autobyteus/tools/usage/formatters/run_bash_xml_example_formatter.py +32 -0
- autobyteus/tools/usage/formatters/run_bash_xml_schema_formatter.py +36 -0
- autobyteus/tools/usage/formatters/write_file_xml_example_formatter.py +53 -0
- autobyteus/tools/usage/formatters/write_file_xml_schema_formatter.py +31 -0
- autobyteus/tools/usage/providers/tool_manifest_provider.py +10 -10
- autobyteus/tools/usage/registries/__init__.py +1 -3
- autobyteus/tools/usage/registries/tool_formatting_registry.py +115 -8
- autobyteus/tools/usage/tool_schema_provider.py +51 -0
- autobyteus/tools/web/__init__.py +4 -0
- autobyteus/tools/web/read_url_tool.py +80 -0
- autobyteus/utils/diff_utils.py +271 -0
- autobyteus/utils/download_utils.py +109 -0
- autobyteus/utils/file_utils.py +57 -2
- autobyteus/utils/gemini_helper.py +64 -0
- autobyteus/utils/gemini_model_mapping.py +71 -0
- autobyteus/utils/llm_output_formatter.py +75 -0
- autobyteus/utils/tool_call_format.py +36 -0
- autobyteus/workflow/agentic_workflow.py +3 -3
- autobyteus/workflow/bootstrap_steps/agent_tool_injection_step.py +2 -2
- autobyteus/workflow/bootstrap_steps/base_workflow_bootstrap_step.py +2 -2
- autobyteus/workflow/bootstrap_steps/coordinator_initialization_step.py +2 -2
- autobyteus/workflow/bootstrap_steps/coordinator_prompt_preparation_step.py +3 -9
- autobyteus/workflow/bootstrap_steps/workflow_bootstrapper.py +6 -6
- autobyteus/workflow/bootstrap_steps/workflow_runtime_queue_initialization_step.py +2 -2
- autobyteus/workflow/context/workflow_context.py +3 -3
- autobyteus/workflow/context/workflow_runtime_state.py +5 -5
- autobyteus/workflow/events/workflow_event_dispatcher.py +5 -5
- autobyteus/workflow/handlers/lifecycle_workflow_event_handler.py +3 -3
- autobyteus/workflow/handlers/process_user_message_event_handler.py +5 -5
- autobyteus/workflow/handlers/tool_approval_workflow_event_handler.py +2 -2
- autobyteus/workflow/runtime/workflow_runtime.py +8 -8
- autobyteus/workflow/runtime/workflow_worker.py +3 -3
- autobyteus/workflow/status/__init__.py +11 -0
- autobyteus/workflow/status/workflow_status.py +19 -0
- autobyteus/workflow/status/workflow_status_manager.py +48 -0
- autobyteus/workflow/streaming/__init__.py +2 -2
- autobyteus/workflow/streaming/workflow_event_notifier.py +7 -7
- autobyteus/workflow/streaming/workflow_stream_event_payloads.py +4 -4
- autobyteus/workflow/streaming/workflow_stream_events.py +3 -3
- autobyteus/workflow/utils/wait_for_idle.py +4 -4
- autobyteus-1.3.0.dist-info/METADATA +293 -0
- autobyteus-1.3.0.dist-info/RECORD +606 -0
- {autobyteus-1.2.1.dist-info → autobyteus-1.3.0.dist-info}/WHEEL +1 -1
- {autobyteus-1.2.1.dist-info → autobyteus-1.3.0.dist-info}/top_level.txt +0 -1
- autobyteus/agent/bootstrap_steps/agent_runtime_queue_initialization_step.py +0 -57
- autobyteus/agent/hooks/__init__.py +0 -16
- autobyteus/agent/hooks/base_phase_hook.py +0 -78
- autobyteus/agent/hooks/hook_definition.py +0 -36
- autobyteus/agent/hooks/hook_meta.py +0 -37
- autobyteus/agent/hooks/hook_registry.py +0 -106
- autobyteus/agent/llm_response_processor/provider_aware_tool_usage_processor.py +0 -103
- autobyteus/agent/phases/__init__.py +0 -18
- autobyteus/agent/phases/discover.py +0 -53
- autobyteus/agent/phases/manager.py +0 -265
- autobyteus/agent/phases/transition_decorator.py +0 -40
- autobyteus/agent/phases/transition_info.py +0 -33
- autobyteus/agent/remote_agent.py +0 -244
- autobyteus/agent/workspace/workspace_definition.py +0 -36
- autobyteus/agent/workspace/workspace_meta.py +0 -37
- autobyteus/agent/workspace/workspace_registry.py +0 -72
- autobyteus/agent_team/bootstrap_steps/agent_team_runtime_queue_initialization_step.py +0 -25
- autobyteus/agent_team/bootstrap_steps/coordinator_prompt_preparation_step.py +0 -85
- autobyteus/agent_team/phases/__init__.py +0 -11
- autobyteus/agent_team/phases/agent_team_operational_phase.py +0 -19
- autobyteus/agent_team/phases/agent_team_phase_manager.py +0 -48
- autobyteus/llm/api/bedrock_llm.py +0 -92
- autobyteus/llm/api/groq_llm.py +0 -94
- autobyteus/llm/api/nvidia_llm.py +0 -108
- autobyteus/llm/utils/token_pricing_config.py +0 -87
- autobyteus/rpc/__init__.py +0 -73
- autobyteus/rpc/client/__init__.py +0 -17
- autobyteus/rpc/client/abstract_client_connection.py +0 -124
- autobyteus/rpc/client/client_connection_manager.py +0 -153
- autobyteus/rpc/client/sse_client_connection.py +0 -306
- autobyteus/rpc/client/stdio_client_connection.py +0 -280
- autobyteus/rpc/config/__init__.py +0 -13
- autobyteus/rpc/config/agent_server_config.py +0 -153
- autobyteus/rpc/config/agent_server_registry.py +0 -152
- autobyteus/rpc/hosting.py +0 -244
- autobyteus/rpc/protocol.py +0 -244
- autobyteus/rpc/server/__init__.py +0 -20
- autobyteus/rpc/server/agent_server_endpoint.py +0 -181
- autobyteus/rpc/server/base_method_handler.py +0 -40
- autobyteus/rpc/server/method_handlers.py +0 -259
- autobyteus/rpc/server/sse_server_handler.py +0 -182
- autobyteus/rpc/server/stdio_server_handler.py +0 -151
- autobyteus/rpc/server_main.py +0 -198
- autobyteus/rpc/transport_type.py +0 -13
- autobyteus/tools/bash/__init__.py +0 -2
- autobyteus/tools/bash/bash_executor.py +0 -100
- autobyteus/tools/browser/__init__.py +0 -2
- autobyteus/tools/browser/session_aware/browser_session_aware_navigate_to.py +0 -75
- autobyteus/tools/browser/session_aware/browser_session_aware_tool.py +0 -30
- autobyteus/tools/browser/session_aware/browser_session_aware_web_element_trigger.py +0 -154
- autobyteus/tools/browser/session_aware/browser_session_aware_webpage_reader.py +0 -89
- autobyteus/tools/browser/session_aware/browser_session_aware_webpage_screenshot_taker.py +0 -107
- autobyteus/tools/browser/session_aware/factory/browser_session_aware_web_element_trigger_factory.py +0 -14
- autobyteus/tools/browser/session_aware/factory/browser_session_aware_webpage_reader_factory.py +0 -26
- autobyteus/tools/browser/session_aware/factory/browser_session_aware_webpage_screenshot_taker_factory.py +0 -14
- autobyteus/tools/browser/session_aware/shared_browser_session.py +0 -11
- autobyteus/tools/browser/session_aware/shared_browser_session_manager.py +0 -25
- autobyteus/tools/browser/session_aware/web_element_action.py +0 -20
- autobyteus/tools/browser/standalone/__init__.py +0 -6
- autobyteus/tools/browser/standalone/factory/__init__.py +0 -0
- autobyteus/tools/browser/standalone/factory/webpage_reader_factory.py +0 -25
- autobyteus/tools/browser/standalone/factory/webpage_screenshot_taker_factory.py +0 -14
- autobyteus/tools/browser/standalone/navigate_to.py +0 -84
- autobyteus/tools/browser/standalone/web_page_pdf_generator.py +0 -101
- autobyteus/tools/browser/standalone/webpage_image_downloader.py +0 -169
- autobyteus/tools/browser/standalone/webpage_reader.py +0 -105
- autobyteus/tools/browser/standalone/webpage_screenshot_taker.py +0 -105
- autobyteus/tools/file/edit_file.py +0 -200
- autobyteus/tools/file/list_directory.py +0 -168
- autobyteus/tools/file/search_files.py +0 -188
- autobyteus/tools/timer.py +0 -175
- autobyteus/tools/usage/parsers/__init__.py +0 -22
- autobyteus/tools/usage/parsers/_json_extractor.py +0 -99
- autobyteus/tools/usage/parsers/_string_decoders.py +0 -18
- autobyteus/tools/usage/parsers/anthropic_xml_tool_usage_parser.py +0 -10
- autobyteus/tools/usage/parsers/base_parser.py +0 -41
- autobyteus/tools/usage/parsers/default_json_tool_usage_parser.py +0 -83
- autobyteus/tools/usage/parsers/default_xml_tool_usage_parser.py +0 -316
- autobyteus/tools/usage/parsers/exceptions.py +0 -13
- autobyteus/tools/usage/parsers/gemini_json_tool_usage_parser.py +0 -77
- autobyteus/tools/usage/parsers/openai_json_tool_usage_parser.py +0 -149
- autobyteus/tools/usage/parsers/provider_aware_tool_usage_parser.py +0 -59
- autobyteus/tools/usage/registries/tool_usage_parser_registry.py +0 -62
- autobyteus/workflow/phases/__init__.py +0 -11
- autobyteus/workflow/phases/workflow_operational_phase.py +0 -19
- autobyteus/workflow/phases/workflow_phase_manager.py +0 -48
- autobyteus-1.2.1.dist-info/METADATA +0 -205
- autobyteus-1.2.1.dist-info/RECORD +0 -511
- examples/__init__.py +0 -1
- examples/agent_team/__init__.py +0 -1
- examples/discover_phase_transitions.py +0 -104
- examples/run_agentic_software_engineer.py +0 -239
- examples/run_browser_agent.py +0 -262
- examples/run_google_slides_agent.py +0 -287
- examples/run_mcp_browser_client.py +0 -174
- examples/run_mcp_google_slides_client.py +0 -270
- examples/run_mcp_list_tools.py +0 -189
- examples/run_poem_writer.py +0 -284
- examples/run_sqlite_agent.py +0 -295
- /autobyteus/{tools/browser/session_aware → skills}/__init__.py +0 -0
- /autobyteus/tools/{browser/session_aware/factory → skill}/__init__.py +0 -0
- {autobyteus-1.2.1.dist-info → autobyteus-1.3.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
import os
|
|
3
|
+
import tempfile
|
|
4
|
+
from pathlib import Path
|
|
3
5
|
from typing import Optional, List, Dict, Any, TYPE_CHECKING
|
|
6
|
+
|
|
4
7
|
from openai import OpenAI
|
|
8
|
+
|
|
5
9
|
from autobyteus.multimedia.image.base_image_client import BaseImageClient
|
|
6
10
|
from autobyteus.multimedia.utils.response_types import ImageGenerationResponse
|
|
11
|
+
from autobyteus.utils.download_utils import download_file_from_url
|
|
7
12
|
|
|
8
13
|
if TYPE_CHECKING:
|
|
9
14
|
from autobyteus.multimedia.image.image_model import ImageModel
|
|
@@ -11,9 +16,19 @@ if TYPE_CHECKING:
|
|
|
11
16
|
|
|
12
17
|
logger = logging.getLogger(__name__)
|
|
13
18
|
|
|
19
|
+
|
|
20
|
+
def _mime_type_from_format(output_format: str) -> str:
|
|
21
|
+
fmt = (output_format or "png").lower()
|
|
22
|
+
if fmt in {"jpg", "jpeg"}:
|
|
23
|
+
return "image/jpeg"
|
|
24
|
+
if fmt == "webp":
|
|
25
|
+
return "image/webp"
|
|
26
|
+
return "image/png"
|
|
27
|
+
|
|
28
|
+
|
|
14
29
|
class OpenAIImageClient(BaseImageClient):
|
|
15
30
|
"""
|
|
16
|
-
An image client that uses OpenAI's
|
|
31
|
+
An image client that uses OpenAI's gpt-image series via the images API.
|
|
17
32
|
"""
|
|
18
33
|
|
|
19
34
|
def __init__(self, model: "ImageModel", config: "MultimediaConfig"):
|
|
@@ -34,49 +49,68 @@ class OpenAIImageClient(BaseImageClient):
|
|
|
34
49
|
**kwargs
|
|
35
50
|
) -> ImageGenerationResponse:
|
|
36
51
|
"""
|
|
37
|
-
Generates an image using
|
|
38
|
-
Note: This endpoint does not support image inputs
|
|
52
|
+
Generates an image using OpenAI's images generation endpoint.
|
|
53
|
+
Note: This endpoint does not support image inputs.
|
|
39
54
|
"""
|
|
40
55
|
if input_image_urls:
|
|
41
56
|
logger.warning(
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
57
|
+
"The OpenAI `images.generate` API used by this client does not support input images. "
|
|
58
|
+
"The images provided for model '%s' will be ignored. "
|
|
59
|
+
"To use image inputs, a client based on the Chat Completions API is required.",
|
|
60
|
+
self.model.value,
|
|
45
61
|
)
|
|
46
62
|
|
|
47
63
|
try:
|
|
48
64
|
image_model = self.model.value
|
|
49
|
-
logger.info(
|
|
65
|
+
logger.info("Generating image with OpenAI model '%s' and prompt: '%s...'", image_model, prompt[:50])
|
|
50
66
|
|
|
51
67
|
# Combine default config with any overrides
|
|
52
68
|
final_config = self.config.to_dict().copy()
|
|
53
69
|
if generation_config:
|
|
54
70
|
final_config.update(generation_config)
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
71
|
+
# Always request a single image for simplicity
|
|
72
|
+
final_config["n"] = 1
|
|
73
|
+
|
|
74
|
+
request_kwargs = {
|
|
75
|
+
"model": image_model,
|
|
76
|
+
"prompt": prompt,
|
|
77
|
+
"n": 1,
|
|
78
|
+
"size": final_config.get("size", "1024x1024"),
|
|
79
|
+
"quality": final_config.get("quality", "standard"),
|
|
80
|
+
}
|
|
81
|
+
if "output_format" in final_config:
|
|
82
|
+
request_kwargs["output_format"] = final_config["output_format"]
|
|
83
|
+
if "output_compression" in final_config:
|
|
84
|
+
request_kwargs["output_compression"] = final_config["output_compression"]
|
|
85
|
+
|
|
86
|
+
response = self.client.images.generate(**request_kwargs)
|
|
87
|
+
|
|
88
|
+
output_format = final_config.get("output_format", "png")
|
|
89
|
+
mime_type = _mime_type_from_format(output_format)
|
|
90
|
+
image_urls_list: List[str] = []
|
|
91
|
+
for img in response.data:
|
|
92
|
+
if getattr(img, "url", None):
|
|
93
|
+
image_urls_list.append(img.url)
|
|
94
|
+
elif getattr(img, "b64_json", None):
|
|
95
|
+
image_urls_list.append(f"data:{mime_type};base64,{img.b64_json}")
|
|
96
|
+
|
|
97
|
+
revised_prompt: Optional[str] = (
|
|
98
|
+
response.data[0].revised_prompt
|
|
99
|
+
if response.data and hasattr(response.data[0], "revised_prompt")
|
|
100
|
+
else None
|
|
64
101
|
)
|
|
65
102
|
|
|
66
|
-
image_urls_list: List[str] = [img.url for img in response.data if img.url]
|
|
67
|
-
revised_prompt: Optional[str] = response.data[0].revised_prompt if response.data and hasattr(response.data[0], 'revised_prompt') else None
|
|
68
|
-
|
|
69
103
|
if not image_urls_list:
|
|
70
|
-
raise ValueError("OpenAI API did not return any image
|
|
104
|
+
raise ValueError("OpenAI API did not return any image data.")
|
|
71
105
|
|
|
72
|
-
logger.info(
|
|
106
|
+
logger.info("Successfully generated %s image(s).", len(image_urls_list))
|
|
73
107
|
|
|
74
108
|
return ImageGenerationResponse(
|
|
75
109
|
image_urls=image_urls_list,
|
|
76
110
|
revised_prompt=revised_prompt
|
|
77
111
|
)
|
|
78
112
|
except Exception as e:
|
|
79
|
-
logger.error(
|
|
113
|
+
logger.error("Error during OpenAI image generation: %s", str(e))
|
|
80
114
|
raise ValueError(f"OpenAI image generation failed: {str(e)}")
|
|
81
115
|
|
|
82
116
|
async def edit_image(
|
|
@@ -95,49 +129,97 @@ class OpenAIImageClient(BaseImageClient):
|
|
|
95
129
|
|
|
96
130
|
source_image_url = input_image_urls[0]
|
|
97
131
|
if len(input_image_urls) > 1:
|
|
98
|
-
logger.warning(
|
|
132
|
+
logger.warning(
|
|
133
|
+
"OpenAI edit endpoint only supports one input image. Using '%s' and ignoring the rest.",
|
|
134
|
+
source_image_url,
|
|
135
|
+
)
|
|
99
136
|
|
|
137
|
+
temp_image_path: Optional[Path] = None
|
|
138
|
+
temp_mask_path: Optional[Path] = None
|
|
100
139
|
try:
|
|
101
|
-
logger.info(
|
|
140
|
+
logger.info("Editing image '%s' with prompt: '%s...'", source_image_url, prompt[:50])
|
|
102
141
|
|
|
103
142
|
# Combine default config with any overrides
|
|
104
143
|
final_config = self.config.to_dict().copy()
|
|
105
144
|
if generation_config:
|
|
106
145
|
final_config.update(generation_config)
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
146
|
+
# Always request a single edited image
|
|
147
|
+
final_config["n"] = 1
|
|
148
|
+
|
|
149
|
+
source_path = Path(source_image_url)
|
|
150
|
+
if not source_path.exists():
|
|
151
|
+
temp_image_file = tempfile.NamedTemporaryFile(delete=False, suffix=".png")
|
|
152
|
+
temp_image_file.close()
|
|
153
|
+
temp_image_path = Path(temp_image_file.name)
|
|
154
|
+
await download_file_from_url(source_image_url, temp_image_path)
|
|
155
|
+
source_path = temp_image_path
|
|
156
|
+
|
|
157
|
+
if mask_url:
|
|
158
|
+
mask_path = Path(mask_url)
|
|
159
|
+
if not mask_path.exists():
|
|
160
|
+
temp_mask_file = tempfile.NamedTemporaryFile(delete=False, suffix=".png")
|
|
161
|
+
temp_mask_file.close()
|
|
162
|
+
temp_mask_path = Path(temp_mask_file.name)
|
|
163
|
+
await download_file_from_url(mask_url, temp_mask_path)
|
|
164
|
+
mask_path = temp_mask_path
|
|
165
|
+
else:
|
|
166
|
+
mask_path = None
|
|
167
|
+
|
|
168
|
+
with open(source_path, "rb") as image_file:
|
|
169
|
+
mask_file = open(mask_path, "rb") if mask_path else None
|
|
110
170
|
try:
|
|
111
|
-
|
|
112
|
-
image
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
171
|
+
request_kwargs = {
|
|
172
|
+
"image": image_file,
|
|
173
|
+
"prompt": prompt,
|
|
174
|
+
"model": self.model.value,
|
|
175
|
+
"n": final_config.get("n", 1),
|
|
176
|
+
"size": final_config.get("size", "1024x1024"),
|
|
177
|
+
}
|
|
178
|
+
if mask_file:
|
|
179
|
+
request_kwargs["mask"] = mask_file
|
|
180
|
+
if "output_format" in final_config:
|
|
181
|
+
request_kwargs["output_format"] = final_config["output_format"]
|
|
182
|
+
if "output_compression" in final_config:
|
|
183
|
+
request_kwargs["output_compression"] = final_config["output_compression"]
|
|
184
|
+
response = self.client.images.edit(**request_kwargs)
|
|
120
185
|
finally:
|
|
121
186
|
if mask_file:
|
|
122
187
|
mask_file.close()
|
|
123
188
|
|
|
124
|
-
|
|
189
|
+
output_format = final_config.get("output_format", "png")
|
|
190
|
+
mime_type = _mime_type_from_format(output_format)
|
|
191
|
+
image_urls_list: List[str] = []
|
|
192
|
+
for img in response.data:
|
|
193
|
+
if getattr(img, "url", None):
|
|
194
|
+
image_urls_list.append(img.url)
|
|
195
|
+
elif getattr(img, "b64_json", None):
|
|
196
|
+
image_urls_list.append(f"data:{mime_type};base64,{img.b64_json}")
|
|
197
|
+
|
|
125
198
|
if not image_urls_list:
|
|
126
|
-
raise ValueError("OpenAI API did not return any edited image
|
|
199
|
+
raise ValueError("OpenAI API did not return any edited image data.")
|
|
127
200
|
|
|
128
|
-
logger.info(
|
|
201
|
+
logger.info("Successfully edited image, generated %s version(s).", len(image_urls_list))
|
|
129
202
|
return ImageGenerationResponse(image_urls=image_urls_list)
|
|
130
203
|
|
|
131
204
|
except FileNotFoundError as e:
|
|
132
|
-
logger.error(
|
|
205
|
+
logger.error("Image file not found for editing: %s", e.filename)
|
|
133
206
|
raise
|
|
134
207
|
except Exception as e:
|
|
135
|
-
logger.error(
|
|
136
|
-
# The API might return a 400 Bad Request if the model doesn't support edits
|
|
208
|
+
logger.error("Error during OpenAI image editing: %s", str(e))
|
|
137
209
|
if "does not support image editing" in str(e):
|
|
138
210
|
raise ValueError(f"The model '{self.model.value}' does not support the image editing endpoint.")
|
|
139
211
|
raise ValueError(f"OpenAI image editing failed: {str(e)}")
|
|
140
|
-
|
|
212
|
+
finally:
|
|
213
|
+
if temp_image_path and temp_image_path.exists():
|
|
214
|
+
try:
|
|
215
|
+
temp_image_path.unlink()
|
|
216
|
+
except OSError:
|
|
217
|
+
logger.warning("Failed to clean up temp image file: %s", temp_image_path)
|
|
218
|
+
if temp_mask_path and temp_mask_path.exists():
|
|
219
|
+
try:
|
|
220
|
+
temp_mask_path.unlink()
|
|
221
|
+
except OSError:
|
|
222
|
+
logger.warning("Failed to clean up temp mask file: %s", temp_mask_path)
|
|
141
223
|
|
|
142
224
|
async def cleanup(self):
|
|
143
225
|
# The OpenAI client does not require explicit cleanup of a session.
|
|
@@ -86,7 +86,8 @@ class AutobyteusImageModelProvider:
|
|
|
86
86
|
client_class=AutobyteusImageClient,
|
|
87
87
|
runtime=MultimediaRuntime.AUTOBYTEUS,
|
|
88
88
|
host_url=host_url,
|
|
89
|
-
parameter_schema=model_info.get("parameter_schema")
|
|
89
|
+
parameter_schema=model_info.get("parameter_schema"),
|
|
90
|
+
description=model_info.get("description")
|
|
90
91
|
)
|
|
91
92
|
|
|
92
93
|
ImageClientFactory.register_model(image_model)
|
|
@@ -40,43 +40,75 @@ class ImageClientFactory(metaclass=SingletonMeta):
|
|
|
40
40
|
"""Initializes the registry with built-in image models and discovers remote ones."""
|
|
41
41
|
|
|
42
42
|
# OpenAI Models
|
|
43
|
-
|
|
43
|
+
gpt_image_15_schema = ParameterSchema(parameters=[
|
|
44
44
|
ParameterDefinition(name="n", param_type=ParameterType.INTEGER, default_value=1, enum_values=[1], description="The number of images to generate."),
|
|
45
45
|
ParameterDefinition(name="size", param_type=ParameterType.ENUM, default_value="1024x1024", enum_values=["1024x1024", "1792x1024", "1024x1792"], description="The size of the generated images."),
|
|
46
|
-
ParameterDefinition(name="quality", param_type=ParameterType.ENUM, default_value="
|
|
47
|
-
ParameterDefinition(name="style", param_type=ParameterType.ENUM, default_value="vivid", enum_values=["vivid", "natural"], description="The style of the generated images.")
|
|
46
|
+
ParameterDefinition(name="quality", param_type=ParameterType.ENUM, default_value="auto", enum_values=["auto", "low", "medium", "high"], description="The quality of the image that will be generated.")
|
|
48
47
|
])
|
|
49
48
|
|
|
50
|
-
|
|
51
|
-
name="
|
|
52
|
-
|
|
49
|
+
gemini_image_schema = ParameterSchema(parameters=[
|
|
50
|
+
ParameterDefinition(name="n", param_type=ParameterType.INTEGER, default_value=1, enum_values=[1], description="The number of images to generate."),
|
|
51
|
+
ParameterDefinition(name="size", param_type=ParameterType.ENUM, default_value="1024x1024", enum_values=["1024x1024", "1792x1024", "1024x1792"], description="The size of the generated images."),
|
|
52
|
+
ParameterDefinition(name="quality", param_type=ParameterType.ENUM, default_value="auto", enum_values=["auto", "low", "medium", "high"], description="The quality of the image that will be generated.")
|
|
53
|
+
])
|
|
54
|
+
|
|
55
|
+
gpt_image_15_model = ImageModel(
|
|
56
|
+
name="gpt-image-1.5",
|
|
57
|
+
value="gpt-image-1.5",
|
|
53
58
|
provider=MultimediaProvider.OPENAI,
|
|
54
59
|
client_class=OpenAIImageClient,
|
|
55
|
-
parameter_schema=
|
|
60
|
+
parameter_schema=gpt_image_15_schema,
|
|
61
|
+
description=(
|
|
62
|
+
"OpenAI's latest **stateless (single-turn)** image model with faster renders, improved text rendering, "
|
|
63
|
+
"and higher fidelity edits. Same API surface as gpt-image-1."
|
|
64
|
+
)
|
|
56
65
|
)
|
|
57
66
|
|
|
58
67
|
# Google Imagen Models (via Gemini API)
|
|
59
68
|
imagen_model = ImageModel(
|
|
60
69
|
name="imagen-4",
|
|
61
70
|
value="imagen-4.0-generate-001",
|
|
62
|
-
provider=MultimediaProvider.
|
|
71
|
+
provider=MultimediaProvider.GEMINI,
|
|
63
72
|
client_class=GeminiImageClient,
|
|
64
|
-
parameter_schema=None # The genai library doesn't expose these as simple params
|
|
73
|
+
parameter_schema=None, # The genai library doesn't expose these as simple params
|
|
74
|
+
description=(
|
|
75
|
+
"A high-fidelity **stateless (single-turn)** model. "
|
|
76
|
+
"Does **NOT** support input images (text-to-image only). "
|
|
77
|
+
"Any provided input images will be ignored."
|
|
78
|
+
)
|
|
65
79
|
)
|
|
66
80
|
|
|
67
|
-
# Google Gemini Flash Image
|
|
81
|
+
# Google Gemini 2.5 Flash Image (legacy, still widely available)
|
|
68
82
|
gemini_flash_image_model = ImageModel(
|
|
69
|
-
name="gemini-2.5-flash-image
|
|
70
|
-
value="gemini-2.5-flash-image
|
|
71
|
-
provider=MultimediaProvider.
|
|
83
|
+
name="gemini-2.5-flash-image",
|
|
84
|
+
value="gemini-2.5-flash-image",
|
|
85
|
+
provider=MultimediaProvider.GEMINI,
|
|
86
|
+
client_class=GeminiImageClient,
|
|
87
|
+
parameter_schema=None, # Parameters handled by genai library
|
|
88
|
+
description=(
|
|
89
|
+
"Fast **conversational (multi-turn)** multimodal image model. "
|
|
90
|
+
"Supports context retention and input images for edits/variations."
|
|
91
|
+
)
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
# Google Gemini 3 Pro Image (aka "Nano Banana Pro")
|
|
95
|
+
gemini_pro_image_model = ImageModel(
|
|
96
|
+
name="gemini-3-pro-image-preview",
|
|
97
|
+
value="gemini-3-pro-image-preview",
|
|
98
|
+
provider=MultimediaProvider.GEMINI,
|
|
72
99
|
client_class=GeminiImageClient,
|
|
73
|
-
parameter_schema=None
|
|
100
|
+
parameter_schema=None, # genai library handles options internally
|
|
101
|
+
description=(
|
|
102
|
+
"High-quality **conversational (multi-turn)** image model for complex edits and 4K renders. "
|
|
103
|
+
"Supports up to 14 reference images, advanced text rendering, and thinking mode."
|
|
104
|
+
)
|
|
74
105
|
)
|
|
75
106
|
|
|
76
107
|
models_to_register = [
|
|
77
|
-
|
|
108
|
+
gpt_image_15_model,
|
|
78
109
|
imagen_model,
|
|
79
110
|
gemini_flash_image_model,
|
|
111
|
+
gemini_pro_image_model,
|
|
80
112
|
]
|
|
81
113
|
|
|
82
114
|
for model in models_to_register:
|
|
@@ -50,7 +50,8 @@ class ImageModel(metaclass=ImageModelMeta):
|
|
|
50
50
|
client_class: Type["BaseImageClient"],
|
|
51
51
|
parameter_schema: Optional[Union[Dict[str, Any], ParameterSchema]] = None,
|
|
52
52
|
runtime: MultimediaRuntime = MultimediaRuntime.API,
|
|
53
|
-
host_url: Optional[str] = None
|
|
53
|
+
host_url: Optional[str] = None,
|
|
54
|
+
description: Optional[str] = None
|
|
54
55
|
):
|
|
55
56
|
self.name = name
|
|
56
57
|
self.value = value
|
|
@@ -58,6 +59,7 @@ class ImageModel(metaclass=ImageModelMeta):
|
|
|
58
59
|
self.client_class = client_class
|
|
59
60
|
self.runtime = runtime
|
|
60
61
|
self.host_url = host_url
|
|
62
|
+
self.description = description
|
|
61
63
|
|
|
62
64
|
if isinstance(parameter_schema, dict):
|
|
63
65
|
self.parameter_schema = ParameterSchema.from_dict(parameter_schema)
|
|
@@ -79,7 +81,8 @@ class ImageModel(metaclass=ImageModelMeta):
|
|
|
79
81
|
"""Returns the unique identifier for the model."""
|
|
80
82
|
if self.runtime == MultimediaRuntime.AUTOBYTEUS and self.host_url:
|
|
81
83
|
try:
|
|
82
|
-
|
|
84
|
+
parsed = urlparse(self.host_url)
|
|
85
|
+
host = parsed.netloc or parsed.hostname or self.host_url
|
|
83
86
|
return f"{self.name}@{host}"
|
|
84
87
|
except Exception:
|
|
85
88
|
return f"{self.name}@{self.host_url}" # Fallback
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import logging
|
|
3
|
+
import re
|
|
4
|
+
from typing import Optional
|
|
5
|
+
from autobyteus.skills.model import Skill
|
|
6
|
+
|
|
7
|
+
logger = logging.getLogger(__name__)
|
|
8
|
+
|
|
9
|
+
class SkillLoader:
|
|
10
|
+
"""
|
|
11
|
+
Responsible for loading and parsing SKILL.md files.
|
|
12
|
+
Designed to be forgiving of minor formatting variations in LLM-generated content.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
@staticmethod
|
|
16
|
+
def load_skill(path: str) -> Skill:
|
|
17
|
+
"""
|
|
18
|
+
Loads a skill from a given directory path.
|
|
19
|
+
"""
|
|
20
|
+
if not os.path.isdir(path):
|
|
21
|
+
raise FileNotFoundError(f"Skill directory not found: {path}")
|
|
22
|
+
|
|
23
|
+
skill_file = os.path.join(path, "SKILL.md")
|
|
24
|
+
if not os.path.exists(skill_file):
|
|
25
|
+
raise FileNotFoundError(f"SKILL.md not found in {path}")
|
|
26
|
+
|
|
27
|
+
try:
|
|
28
|
+
with open(skill_file, 'r', encoding='utf-8') as f:
|
|
29
|
+
raw_content = f.read()
|
|
30
|
+
except Exception as e:
|
|
31
|
+
raise IOError(f"Failed to read SKILL.md at {skill_file}: {e}")
|
|
32
|
+
|
|
33
|
+
return SkillLoader._parse_skill(raw_content, path)
|
|
34
|
+
|
|
35
|
+
@staticmethod
|
|
36
|
+
def _parse_skill(raw_content: str, root_path: str) -> Skill:
|
|
37
|
+
"""
|
|
38
|
+
Parses the content of a SKILL.md file.
|
|
39
|
+
Extracts metadata from the frontmatter block (delimited by ---).
|
|
40
|
+
"""
|
|
41
|
+
# Extract the frontmatter block
|
|
42
|
+
# Using a regex that is forgiving of whitespace around delimiters
|
|
43
|
+
match = re.search(r'^\s*---\s*\n(.*?)\n\s*---\s*\n(.*)', raw_content, re.DOTALL | re.MULTILINE)
|
|
44
|
+
|
|
45
|
+
if not match:
|
|
46
|
+
raise ValueError("Invalid SKILL.md format: Could not find frontmatter block delimited by '---'")
|
|
47
|
+
|
|
48
|
+
frontmatter_text = match.group(1)
|
|
49
|
+
body_content = match.group(2).strip()
|
|
50
|
+
|
|
51
|
+
# Parse frontmatter lines (Key: Value)
|
|
52
|
+
metadata = {}
|
|
53
|
+
for line in frontmatter_text.splitlines():
|
|
54
|
+
if ":" in line:
|
|
55
|
+
key, value = line.split(":", 1)
|
|
56
|
+
metadata[key.strip().lower()] = value.strip()
|
|
57
|
+
|
|
58
|
+
name = metadata.get("name")
|
|
59
|
+
description = metadata.get("description")
|
|
60
|
+
|
|
61
|
+
if not name:
|
|
62
|
+
raise ValueError("Missing 'name' in SKILL.md metadata")
|
|
63
|
+
if not description:
|
|
64
|
+
raise ValueError("Missing 'description' in SKILL.md metadata")
|
|
65
|
+
|
|
66
|
+
return Skill(
|
|
67
|
+
name=name,
|
|
68
|
+
description=description,
|
|
69
|
+
content=body_content,
|
|
70
|
+
root_path=root_path
|
|
71
|
+
)
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import logging
|
|
3
|
+
from typing import Dict, List, Optional
|
|
4
|
+
from autobyteus.utils.singleton import SingletonMeta
|
|
5
|
+
from autobyteus.skills.model import Skill
|
|
6
|
+
from autobyteus.skills.loader import SkillLoader
|
|
7
|
+
|
|
8
|
+
logger = logging.getLogger(__name__)
|
|
9
|
+
|
|
10
|
+
class SkillRegistry(metaclass=SingletonMeta):
|
|
11
|
+
"""
|
|
12
|
+
A singleton registry for managing and discovering agent skills.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
def __init__(self):
|
|
16
|
+
self._skills: Dict[str, Skill] = {}
|
|
17
|
+
logger.info("SkillRegistry initialized.")
|
|
18
|
+
|
|
19
|
+
def register_skill_from_path(self, path: str) -> Skill:
|
|
20
|
+
"""
|
|
21
|
+
Loads a skill from the given path and registers it.
|
|
22
|
+
If a skill with the same name already exists, it will be overwritten.
|
|
23
|
+
"""
|
|
24
|
+
try:
|
|
25
|
+
skill = SkillLoader.load_skill(path)
|
|
26
|
+
self._skills[skill.name] = skill
|
|
27
|
+
logger.info(f"Skill '{skill.name}' registered from path: {path}")
|
|
28
|
+
return skill
|
|
29
|
+
except Exception as e:
|
|
30
|
+
logger.error(f"Failed to register skill from path '{path}': {e}")
|
|
31
|
+
raise
|
|
32
|
+
|
|
33
|
+
def discover_skills(self, directory_path: str):
|
|
34
|
+
"""
|
|
35
|
+
Scans a directory for skill subdirectories (those containing SKILL.md)
|
|
36
|
+
and registers them.
|
|
37
|
+
"""
|
|
38
|
+
if not os.path.isdir(directory_path):
|
|
39
|
+
logger.warning(f"Discovery directory not found: {directory_path}")
|
|
40
|
+
return
|
|
41
|
+
|
|
42
|
+
logger.debug(f"Discovering skills in: {directory_path}")
|
|
43
|
+
for entry in os.scandir(directory_path):
|
|
44
|
+
if entry.is_dir():
|
|
45
|
+
skill_md_path = os.path.join(entry.path, "SKILL.md")
|
|
46
|
+
if os.path.exists(skill_md_path):
|
|
47
|
+
try:
|
|
48
|
+
self.register_skill_from_path(entry.path)
|
|
49
|
+
except Exception:
|
|
50
|
+
# Continue discovering other skills even if one fails
|
|
51
|
+
continue
|
|
52
|
+
|
|
53
|
+
def get_skill(self, name: str) -> Optional[Skill]:
|
|
54
|
+
"""
|
|
55
|
+
Retrieves a skill by its name.
|
|
56
|
+
"""
|
|
57
|
+
return self._skills.get(name)
|
|
58
|
+
|
|
59
|
+
def list_skills(self) -> List[Skill]:
|
|
60
|
+
"""
|
|
61
|
+
Returns a list of all registered skills.
|
|
62
|
+
"""
|
|
63
|
+
return list(self._skills.values())
|
|
64
|
+
|
|
65
|
+
def clear(self):
|
|
66
|
+
"""
|
|
67
|
+
Clears all registered skills. Primarily for testing.
|
|
68
|
+
"""
|
|
69
|
+
self._skills.clear()
|
|
70
|
+
logger.debug("SkillRegistry cleared.")
|
|
@@ -16,11 +16,11 @@ if TYPE_CHECKING:
|
|
|
16
16
|
logger = logging.getLogger(__name__)
|
|
17
17
|
|
|
18
18
|
def _notify_todo_update(context: 'AgentContext'):
|
|
19
|
-
if context.
|
|
19
|
+
if context.status_manager and context.status_manager.notifier:
|
|
20
20
|
todo_list = context.state.todo_list
|
|
21
21
|
if todo_list:
|
|
22
22
|
todos_for_llm = [todo.model_dump(mode='json') for todo in todo_list.get_all_todos()]
|
|
23
|
-
context.
|
|
23
|
+
context.status_manager.notifier.notify_agent_data_todo_list_updated(todos_for_llm)
|
|
24
24
|
logger.debug(f"Agent '{context.agent_id}': Notified ToDo list update with {len(todos_for_llm)} items.")
|
|
25
25
|
|
|
26
26
|
class AddToDo(BaseTool):
|
|
@@ -17,11 +17,11 @@ if TYPE_CHECKING:
|
|
|
17
17
|
logger = logging.getLogger(__name__)
|
|
18
18
|
|
|
19
19
|
def _notify_todo_update(context: 'AgentContext'):
|
|
20
|
-
if context.
|
|
20
|
+
if context.status_manager and context.status_manager.notifier:
|
|
21
21
|
todo_list = context.state.todo_list
|
|
22
22
|
if todo_list:
|
|
23
23
|
todos_for_llm = [todo.model_dump(mode='json') for todo in todo_list.get_all_todos()]
|
|
24
|
-
context.
|
|
24
|
+
context.status_manager.notifier.notify_agent_data_todo_list_updated(todos_for_llm)
|
|
25
25
|
logger.debug(f"Agent '{context.agent_id}': Notified ToDo list update with {len(todos_for_llm)} items.")
|
|
26
26
|
|
|
27
27
|
class CreateToDoList(BaseTool):
|
|
@@ -13,11 +13,11 @@ if TYPE_CHECKING:
|
|
|
13
13
|
logger = logging.getLogger(__name__)
|
|
14
14
|
|
|
15
15
|
def _notify_todo_update(context: 'AgentContext'):
|
|
16
|
-
if context.
|
|
16
|
+
if context.status_manager and context.status_manager.notifier:
|
|
17
17
|
todo_list = context.state.todo_list
|
|
18
18
|
if todo_list:
|
|
19
19
|
todos_for_llm = [todo.model_dump(mode='json') for todo in todo_list.get_all_todos()]
|
|
20
|
-
context.
|
|
20
|
+
context.status_manager.notifier.notify_agent_data_todo_list_updated(todos_for_llm)
|
|
21
21
|
logger.debug(f"Agent '{context.agent_id}': Notified ToDo list update with {len(todos_for_llm)} items.")
|
|
22
22
|
|
|
23
23
|
class UpdateToDoStatus(BaseTool):
|