autobyteus 1.2.1__py3-none-any.whl → 1.2.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- autobyteus/agent/agent.py +15 -5
- autobyteus/agent/bootstrap_steps/__init__.py +1 -3
- autobyteus/agent/bootstrap_steps/agent_bootstrapper.py +3 -59
- autobyteus/agent/bootstrap_steps/base_bootstrap_step.py +1 -4
- autobyteus/agent/bootstrap_steps/mcp_server_prewarming_step.py +1 -3
- autobyteus/agent/bootstrap_steps/system_prompt_processing_step.py +16 -13
- autobyteus/agent/bootstrap_steps/workspace_context_initialization_step.py +2 -4
- autobyteus/agent/context/agent_config.py +43 -20
- autobyteus/agent/context/agent_context.py +23 -18
- autobyteus/agent/context/agent_runtime_state.py +19 -19
- autobyteus/agent/events/__init__.py +16 -1
- autobyteus/agent/events/agent_events.py +43 -3
- autobyteus/agent/events/agent_input_event_queue_manager.py +79 -26
- autobyteus/agent/events/event_store.py +57 -0
- autobyteus/agent/events/notifiers.py +69 -59
- autobyteus/agent/events/worker_event_dispatcher.py +21 -64
- autobyteus/agent/factory/agent_factory.py +52 -0
- autobyteus/agent/handlers/__init__.py +2 -0
- autobyteus/agent/handlers/approved_tool_invocation_event_handler.py +51 -34
- autobyteus/agent/handlers/bootstrap_event_handler.py +155 -0
- autobyteus/agent/handlers/inter_agent_message_event_handler.py +10 -0
- autobyteus/agent/handlers/lifecycle_event_logger.py +19 -11
- autobyteus/agent/handlers/llm_complete_response_received_event_handler.py +10 -15
- autobyteus/agent/handlers/llm_user_message_ready_event_handler.py +188 -48
- autobyteus/agent/handlers/tool_execution_approval_event_handler.py +0 -10
- autobyteus/agent/handlers/tool_invocation_request_event_handler.py +53 -48
- autobyteus/agent/handlers/tool_result_event_handler.py +7 -8
- autobyteus/agent/handlers/user_input_message_event_handler.py +10 -3
- autobyteus/agent/input_processor/memory_ingest_input_processor.py +40 -0
- autobyteus/agent/lifecycle/__init__.py +12 -0
- autobyteus/agent/lifecycle/base_processor.py +109 -0
- autobyteus/agent/lifecycle/events.py +35 -0
- autobyteus/agent/lifecycle/processor_definition.py +36 -0
- autobyteus/agent/lifecycle/processor_registry.py +106 -0
- autobyteus/agent/llm_request_assembler.py +98 -0
- autobyteus/agent/llm_response_processor/__init__.py +1 -8
- autobyteus/agent/message/context_file_type.py +1 -1
- autobyteus/agent/runtime/agent_runtime.py +29 -21
- autobyteus/agent/runtime/agent_worker.py +98 -19
- autobyteus/agent/shutdown_steps/__init__.py +2 -0
- autobyteus/agent/shutdown_steps/agent_shutdown_orchestrator.py +2 -0
- autobyteus/agent/shutdown_steps/tool_cleanup_step.py +58 -0
- autobyteus/agent/status/__init__.py +14 -0
- autobyteus/agent/status/manager.py +93 -0
- autobyteus/agent/status/status_deriver.py +96 -0
- autobyteus/agent/{phases/phase_enum.py → status/status_enum.py} +16 -16
- autobyteus/agent/status/status_update_utils.py +73 -0
- autobyteus/agent/streaming/__init__.py +52 -5
- autobyteus/agent/streaming/adapters/__init__.py +18 -0
- autobyteus/agent/streaming/adapters/invocation_adapter.py +184 -0
- autobyteus/agent/streaming/adapters/tool_call_parsing.py +163 -0
- autobyteus/agent/streaming/adapters/tool_syntax_registry.py +67 -0
- autobyteus/agent/streaming/agent_event_stream.py +3 -183
- autobyteus/agent/streaming/api_tool_call/__init__.py +16 -0
- autobyteus/agent/streaming/api_tool_call/file_content_streamer.py +56 -0
- autobyteus/agent/streaming/api_tool_call/json_string_field_extractor.py +175 -0
- autobyteus/agent/streaming/api_tool_call_streaming_response_handler.py +4 -0
- autobyteus/agent/streaming/events/__init__.py +6 -0
- autobyteus/agent/streaming/events/stream_event_payloads.py +284 -0
- autobyteus/agent/streaming/events/stream_events.py +141 -0
- autobyteus/agent/streaming/handlers/__init__.py +15 -0
- autobyteus/agent/streaming/handlers/api_tool_call_streaming_response_handler.py +303 -0
- autobyteus/agent/streaming/handlers/parsing_streaming_response_handler.py +107 -0
- autobyteus/agent/streaming/handlers/pass_through_streaming_response_handler.py +107 -0
- autobyteus/agent/streaming/handlers/streaming_handler_factory.py +177 -0
- autobyteus/agent/streaming/handlers/streaming_response_handler.py +58 -0
- autobyteus/agent/streaming/parser/__init__.py +61 -0
- autobyteus/agent/streaming/parser/event_emitter.py +181 -0
- autobyteus/agent/streaming/parser/events.py +4 -0
- autobyteus/agent/streaming/parser/invocation_adapter.py +4 -0
- autobyteus/agent/streaming/parser/json_parsing_strategies/__init__.py +19 -0
- autobyteus/agent/streaming/parser/json_parsing_strategies/base.py +32 -0
- autobyteus/agent/streaming/parser/json_parsing_strategies/default.py +34 -0
- autobyteus/agent/streaming/parser/json_parsing_strategies/gemini.py +31 -0
- autobyteus/agent/streaming/parser/json_parsing_strategies/openai.py +64 -0
- autobyteus/agent/streaming/parser/json_parsing_strategies/registry.py +75 -0
- autobyteus/agent/streaming/parser/parser_context.py +227 -0
- autobyteus/agent/streaming/parser/parser_factory.py +132 -0
- autobyteus/agent/streaming/parser/sentinel_format.py +7 -0
- autobyteus/agent/streaming/parser/state_factory.py +62 -0
- autobyteus/agent/streaming/parser/states/__init__.py +1 -0
- autobyteus/agent/streaming/parser/states/base_state.py +60 -0
- autobyteus/agent/streaming/parser/states/custom_xml_tag_run_bash_parsing_state.py +38 -0
- autobyteus/agent/streaming/parser/states/custom_xml_tag_write_file_parsing_state.py +55 -0
- autobyteus/agent/streaming/parser/states/delimited_content_state.py +146 -0
- autobyteus/agent/streaming/parser/states/json_initialization_state.py +144 -0
- autobyteus/agent/streaming/parser/states/json_tool_parsing_state.py +137 -0
- autobyteus/agent/streaming/parser/states/sentinel_content_state.py +30 -0
- autobyteus/agent/streaming/parser/states/sentinel_initialization_state.py +117 -0
- autobyteus/agent/streaming/parser/states/text_state.py +78 -0
- autobyteus/agent/streaming/parser/states/xml_patch_file_tool_parsing_state.py +328 -0
- autobyteus/agent/streaming/parser/states/xml_run_bash_tool_parsing_state.py +129 -0
- autobyteus/agent/streaming/parser/states/xml_tag_initialization_state.py +151 -0
- autobyteus/agent/streaming/parser/states/xml_tool_parsing_state.py +63 -0
- autobyteus/agent/streaming/parser/states/xml_write_file_tool_parsing_state.py +343 -0
- autobyteus/agent/streaming/parser/strategies/__init__.py +17 -0
- autobyteus/agent/streaming/parser/strategies/base.py +24 -0
- autobyteus/agent/streaming/parser/strategies/json_tool_strategy.py +26 -0
- autobyteus/agent/streaming/parser/strategies/registry.py +28 -0
- autobyteus/agent/streaming/parser/strategies/sentinel_strategy.py +23 -0
- autobyteus/agent/streaming/parser/strategies/xml_tag_strategy.py +21 -0
- autobyteus/agent/streaming/parser/stream_scanner.py +167 -0
- autobyteus/agent/streaming/parser/streaming_parser.py +212 -0
- autobyteus/agent/streaming/parser/tool_call_parsing.py +4 -0
- autobyteus/agent/streaming/parser/tool_constants.py +7 -0
- autobyteus/agent/streaming/parser/tool_syntax_registry.py +4 -0
- autobyteus/agent/streaming/parser/xml_tool_parsing_state_registry.py +55 -0
- autobyteus/agent/streaming/parsing_streaming_response_handler.py +4 -0
- autobyteus/agent/streaming/pass_through_streaming_response_handler.py +4 -0
- autobyteus/agent/streaming/queue_streamer.py +3 -57
- autobyteus/agent/streaming/segments/__init__.py +5 -0
- autobyteus/agent/streaming/segments/segment_events.py +81 -0
- autobyteus/agent/streaming/stream_event_payloads.py +2 -223
- autobyteus/agent/streaming/stream_events.py +3 -140
- autobyteus/agent/streaming/streaming_handler_factory.py +4 -0
- autobyteus/agent/streaming/streaming_response_handler.py +4 -0
- autobyteus/agent/streaming/streams/__init__.py +5 -0
- autobyteus/agent/streaming/streams/agent_event_stream.py +197 -0
- autobyteus/agent/streaming/utils/__init__.py +5 -0
- autobyteus/agent/streaming/utils/queue_streamer.py +59 -0
- autobyteus/agent/system_prompt_processor/__init__.py +2 -0
- autobyteus/agent/system_prompt_processor/available_skills_processor.py +96 -0
- autobyteus/agent/system_prompt_processor/base_processor.py +1 -1
- autobyteus/agent/system_prompt_processor/processor_meta.py +15 -2
- autobyteus/agent/system_prompt_processor/tool_manifest_injector_processor.py +39 -58
- autobyteus/agent/token_budget.py +56 -0
- autobyteus/agent/tool_execution_result_processor/memory_ingest_tool_result_processor.py +29 -0
- autobyteus/agent/tool_invocation.py +16 -40
- autobyteus/agent/tool_invocation_preprocessor/__init__.py +9 -0
- autobyteus/agent/tool_invocation_preprocessor/base_preprocessor.py +45 -0
- autobyteus/agent/tool_invocation_preprocessor/processor_definition.py +15 -0
- autobyteus/agent/tool_invocation_preprocessor/processor_meta.py +33 -0
- autobyteus/agent/tool_invocation_preprocessor/processor_registry.py +60 -0
- autobyteus/agent/utils/wait_for_idle.py +12 -14
- autobyteus/agent/workspace/base_workspace.py +6 -27
- autobyteus/agent_team/agent_team.py +3 -3
- autobyteus/agent_team/agent_team_builder.py +1 -41
- autobyteus/agent_team/bootstrap_steps/__init__.py +0 -4
- autobyteus/agent_team/bootstrap_steps/agent_configuration_preparation_step.py +8 -18
- autobyteus/agent_team/bootstrap_steps/agent_team_bootstrapper.py +4 -16
- autobyteus/agent_team/bootstrap_steps/base_agent_team_bootstrap_step.py +1 -2
- autobyteus/agent_team/bootstrap_steps/coordinator_initialization_step.py +1 -2
- autobyteus/agent_team/bootstrap_steps/task_notifier_initialization_step.py +1 -2
- autobyteus/agent_team/bootstrap_steps/team_context_initialization_step.py +4 -4
- autobyteus/agent_team/context/agent_team_config.py +6 -3
- autobyteus/agent_team/context/agent_team_context.py +25 -3
- autobyteus/agent_team/context/agent_team_runtime_state.py +9 -6
- autobyteus/agent_team/events/__init__.py +11 -0
- autobyteus/agent_team/events/agent_team_event_dispatcher.py +22 -9
- autobyteus/agent_team/events/agent_team_events.py +16 -0
- autobyteus/agent_team/events/event_store.py +57 -0
- autobyteus/agent_team/factory/agent_team_factory.py +8 -0
- autobyteus/agent_team/handlers/inter_agent_message_request_event_handler.py +18 -2
- autobyteus/agent_team/handlers/lifecycle_agent_team_event_handler.py +21 -5
- autobyteus/agent_team/handlers/process_user_message_event_handler.py +17 -8
- autobyteus/agent_team/handlers/tool_approval_team_event_handler.py +19 -4
- autobyteus/agent_team/runtime/agent_team_runtime.py +41 -10
- autobyteus/agent_team/runtime/agent_team_worker.py +69 -5
- autobyteus/agent_team/status/__init__.py +14 -0
- autobyteus/agent_team/status/agent_team_status.py +18 -0
- autobyteus/agent_team/status/agent_team_status_manager.py +33 -0
- autobyteus/agent_team/status/status_deriver.py +62 -0
- autobyteus/agent_team/status/status_update_utils.py +42 -0
- autobyteus/agent_team/streaming/__init__.py +2 -2
- autobyteus/agent_team/streaming/agent_team_event_notifier.py +6 -6
- autobyteus/agent_team/streaming/agent_team_stream_event_payloads.py +4 -4
- autobyteus/agent_team/streaming/agent_team_stream_events.py +3 -3
- autobyteus/agent_team/system_prompt_processor/__init__.py +6 -0
- autobyteus/agent_team/system_prompt_processor/team_manifest_injector_processor.py +76 -0
- autobyteus/agent_team/task_notification/task_notification_mode.py +19 -0
- autobyteus/agent_team/utils/wait_for_idle.py +4 -4
- autobyteus/cli/agent_cli.py +18 -10
- autobyteus/cli/agent_team_tui/app.py +14 -11
- autobyteus/cli/agent_team_tui/state.py +13 -15
- autobyteus/cli/agent_team_tui/widgets/agent_list_sidebar.py +15 -15
- autobyteus/cli/agent_team_tui/widgets/focus_pane.py +143 -36
- autobyteus/cli/agent_team_tui/widgets/renderables.py +1 -1
- autobyteus/cli/agent_team_tui/widgets/shared.py +25 -25
- autobyteus/cli/cli_display.py +193 -44
- autobyteus/cli/workflow_tui/app.py +9 -10
- autobyteus/cli/workflow_tui/state.py +14 -16
- autobyteus/cli/workflow_tui/widgets/agent_list_sidebar.py +15 -15
- autobyteus/cli/workflow_tui/widgets/focus_pane.py +137 -35
- autobyteus/cli/workflow_tui/widgets/renderables.py +1 -1
- autobyteus/cli/workflow_tui/widgets/shared.py +25 -25
- autobyteus/clients/autobyteus_client.py +94 -1
- autobyteus/events/event_types.py +11 -18
- autobyteus/llm/api/autobyteus_llm.py +33 -29
- autobyteus/llm/api/claude_llm.py +142 -36
- autobyteus/llm/api/gemini_llm.py +163 -59
- autobyteus/llm/api/grok_llm.py +1 -1
- autobyteus/llm/api/minimax_llm.py +26 -0
- autobyteus/llm/api/mistral_llm.py +113 -87
- autobyteus/llm/api/ollama_llm.py +9 -42
- autobyteus/llm/api/openai_compatible_llm.py +127 -91
- autobyteus/llm/api/openai_llm.py +3 -3
- autobyteus/llm/api/openai_responses_llm.py +324 -0
- autobyteus/llm/api/zhipu_llm.py +21 -2
- autobyteus/llm/autobyteus_provider.py +70 -60
- autobyteus/llm/base_llm.py +85 -81
- autobyteus/llm/converters/__init__.py +14 -0
- autobyteus/llm/converters/anthropic_tool_call_converter.py +37 -0
- autobyteus/llm/converters/gemini_tool_call_converter.py +57 -0
- autobyteus/llm/converters/mistral_tool_call_converter.py +37 -0
- autobyteus/llm/converters/openai_tool_call_converter.py +38 -0
- autobyteus/llm/extensions/base_extension.py +6 -12
- autobyteus/llm/extensions/token_usage_tracking_extension.py +45 -18
- autobyteus/llm/llm_factory.py +282 -204
- autobyteus/llm/lmstudio_provider.py +60 -49
- autobyteus/llm/models.py +35 -2
- autobyteus/llm/ollama_provider.py +60 -49
- autobyteus/llm/ollama_provider_resolver.py +0 -1
- autobyteus/llm/prompt_renderers/__init__.py +19 -0
- autobyteus/llm/prompt_renderers/anthropic_prompt_renderer.py +104 -0
- autobyteus/llm/prompt_renderers/autobyteus_prompt_renderer.py +19 -0
- autobyteus/llm/prompt_renderers/base_prompt_renderer.py +10 -0
- autobyteus/llm/prompt_renderers/gemini_prompt_renderer.py +63 -0
- autobyteus/llm/prompt_renderers/mistral_prompt_renderer.py +87 -0
- autobyteus/llm/prompt_renderers/ollama_prompt_renderer.py +51 -0
- autobyteus/llm/prompt_renderers/openai_chat_renderer.py +97 -0
- autobyteus/llm/prompt_renderers/openai_responses_renderer.py +101 -0
- autobyteus/llm/providers.py +1 -3
- autobyteus/llm/token_counter/claude_token_counter.py +56 -25
- autobyteus/llm/token_counter/mistral_token_counter.py +12 -8
- autobyteus/llm/token_counter/openai_token_counter.py +24 -5
- autobyteus/llm/token_counter/token_counter_factory.py +12 -5
- autobyteus/llm/utils/llm_config.py +6 -12
- autobyteus/llm/utils/media_payload_formatter.py +27 -20
- autobyteus/llm/utils/messages.py +55 -3
- autobyteus/llm/utils/response_types.py +3 -0
- autobyteus/llm/utils/tool_call_delta.py +31 -0
- autobyteus/memory/__init__.py +32 -0
- autobyteus/memory/active_transcript.py +69 -0
- autobyteus/memory/compaction/__init__.py +9 -0
- autobyteus/memory/compaction/compaction_result.py +8 -0
- autobyteus/memory/compaction/compactor.py +89 -0
- autobyteus/memory/compaction/summarizer.py +11 -0
- autobyteus/memory/compaction_snapshot_builder.py +84 -0
- autobyteus/memory/memory_manager.py +183 -0
- autobyteus/memory/models/__init__.py +14 -0
- autobyteus/memory/models/episodic_item.py +41 -0
- autobyteus/memory/models/memory_types.py +7 -0
- autobyteus/memory/models/raw_trace_item.py +79 -0
- autobyteus/memory/models/semantic_item.py +41 -0
- autobyteus/memory/models/tool_interaction.py +20 -0
- autobyteus/memory/policies/__init__.py +5 -0
- autobyteus/memory/policies/compaction_policy.py +16 -0
- autobyteus/memory/retrieval/__init__.py +7 -0
- autobyteus/memory/retrieval/memory_bundle.py +11 -0
- autobyteus/memory/retrieval/retriever.py +13 -0
- autobyteus/memory/store/__init__.py +7 -0
- autobyteus/memory/store/base_store.py +14 -0
- autobyteus/memory/store/file_store.py +98 -0
- autobyteus/memory/tool_interaction_builder.py +46 -0
- autobyteus/memory/turn_tracker.py +9 -0
- autobyteus/multimedia/audio/api/autobyteus_audio_client.py +19 -5
- autobyteus/multimedia/audio/api/gemini_audio_client.py +108 -16
- autobyteus/multimedia/audio/audio_client_factory.py +47 -9
- autobyteus/multimedia/audio/audio_model.py +2 -1
- autobyteus/multimedia/image/api/autobyteus_image_client.py +19 -5
- autobyteus/multimedia/image/api/gemini_image_client.py +38 -17
- autobyteus/multimedia/image/api/openai_image_client.py +125 -43
- autobyteus/multimedia/image/autobyteus_image_provider.py +2 -1
- autobyteus/multimedia/image/image_client_factory.py +47 -15
- autobyteus/multimedia/image/image_model.py +5 -2
- autobyteus/multimedia/providers.py +3 -2
- autobyteus/skills/loader.py +71 -0
- autobyteus/skills/model.py +11 -0
- autobyteus/skills/registry.py +70 -0
- autobyteus/task_management/tools/todo_tools/add_todo.py +2 -2
- autobyteus/task_management/tools/todo_tools/create_todo_list.py +2 -2
- autobyteus/task_management/tools/todo_tools/update_todo_status.py +2 -2
- autobyteus/tools/__init__.py +34 -47
- autobyteus/tools/base_tool.py +7 -0
- autobyteus/tools/file/__init__.py +2 -6
- autobyteus/tools/file/patch_file.py +149 -0
- autobyteus/tools/file/read_file.py +36 -5
- autobyteus/tools/file/write_file.py +4 -1
- autobyteus/tools/functional_tool.py +43 -6
- autobyteus/tools/mcp/__init__.py +2 -0
- autobyteus/tools/mcp/config_service.py +5 -1
- autobyteus/tools/mcp/server/__init__.py +2 -0
- autobyteus/tools/mcp/server/http_managed_mcp_server.py +1 -1
- autobyteus/tools/mcp/server/websocket_managed_mcp_server.py +141 -0
- autobyteus/tools/mcp/server_instance_manager.py +8 -1
- autobyteus/tools/mcp/types.py +61 -0
- autobyteus/tools/multimedia/audio_tools.py +70 -17
- autobyteus/tools/multimedia/download_media_tool.py +18 -4
- autobyteus/tools/multimedia/image_tools.py +246 -62
- autobyteus/tools/operation_executor/journal_manager.py +107 -0
- autobyteus/tools/operation_executor/operation_event_buffer.py +57 -0
- autobyteus/tools/operation_executor/operation_event_producer.py +29 -0
- autobyteus/tools/operation_executor/operation_executor.py +58 -0
- autobyteus/tools/registry/tool_definition.py +43 -2
- autobyteus/tools/skill/load_skill.py +50 -0
- autobyteus/tools/terminal/__init__.py +45 -0
- autobyteus/tools/terminal/ansi_utils.py +32 -0
- autobyteus/tools/terminal/background_process_manager.py +233 -0
- autobyteus/tools/terminal/output_buffer.py +105 -0
- autobyteus/tools/terminal/prompt_detector.py +63 -0
- autobyteus/tools/terminal/pty_session.py +241 -0
- autobyteus/tools/terminal/session_factory.py +20 -0
- autobyteus/tools/terminal/terminal_session_manager.py +226 -0
- autobyteus/tools/terminal/tools/__init__.py +13 -0
- autobyteus/tools/terminal/tools/get_process_output.py +81 -0
- autobyteus/tools/terminal/tools/run_bash.py +109 -0
- autobyteus/tools/terminal/tools/start_background_process.py +104 -0
- autobyteus/tools/terminal/tools/stop_background_process.py +67 -0
- autobyteus/tools/terminal/types.py +54 -0
- autobyteus/tools/terminal/wsl_tmux_session.py +221 -0
- autobyteus/tools/terminal/wsl_utils.py +156 -0
- autobyteus/tools/transaction_management/backup_handler.py +48 -0
- autobyteus/tools/transaction_management/operation_lifecycle_manager.py +62 -0
- autobyteus/tools/usage/__init__.py +1 -2
- autobyteus/tools/usage/formatters/__init__.py +17 -1
- autobyteus/tools/usage/formatters/base_formatter.py +8 -0
- autobyteus/tools/usage/formatters/default_xml_schema_formatter.py +2 -2
- autobyteus/tools/usage/formatters/mistral_json_schema_formatter.py +18 -0
- autobyteus/tools/usage/formatters/patch_file_xml_example_formatter.py +64 -0
- autobyteus/tools/usage/formatters/patch_file_xml_schema_formatter.py +31 -0
- autobyteus/tools/usage/formatters/run_bash_xml_example_formatter.py +32 -0
- autobyteus/tools/usage/formatters/run_bash_xml_schema_formatter.py +36 -0
- autobyteus/tools/usage/formatters/write_file_xml_example_formatter.py +53 -0
- autobyteus/tools/usage/formatters/write_file_xml_schema_formatter.py +31 -0
- autobyteus/tools/usage/providers/tool_manifest_provider.py +10 -10
- autobyteus/tools/usage/registries/__init__.py +1 -3
- autobyteus/tools/usage/registries/tool_formatting_registry.py +115 -8
- autobyteus/tools/usage/tool_schema_provider.py +51 -0
- autobyteus/tools/web/__init__.py +4 -0
- autobyteus/tools/web/read_url_tool.py +80 -0
- autobyteus/utils/diff_utils.py +271 -0
- autobyteus/utils/download_utils.py +109 -0
- autobyteus/utils/file_utils.py +57 -2
- autobyteus/utils/gemini_helper.py +56 -0
- autobyteus/utils/gemini_model_mapping.py +71 -0
- autobyteus/utils/llm_output_formatter.py +75 -0
- autobyteus/utils/tool_call_format.py +36 -0
- autobyteus/workflow/agentic_workflow.py +3 -3
- autobyteus/workflow/bootstrap_steps/agent_tool_injection_step.py +2 -2
- autobyteus/workflow/bootstrap_steps/base_workflow_bootstrap_step.py +2 -2
- autobyteus/workflow/bootstrap_steps/coordinator_initialization_step.py +2 -2
- autobyteus/workflow/bootstrap_steps/coordinator_prompt_preparation_step.py +3 -9
- autobyteus/workflow/bootstrap_steps/workflow_bootstrapper.py +6 -6
- autobyteus/workflow/bootstrap_steps/workflow_runtime_queue_initialization_step.py +2 -2
- autobyteus/workflow/context/workflow_context.py +3 -3
- autobyteus/workflow/context/workflow_runtime_state.py +5 -5
- autobyteus/workflow/events/workflow_event_dispatcher.py +5 -5
- autobyteus/workflow/handlers/lifecycle_workflow_event_handler.py +3 -3
- autobyteus/workflow/handlers/process_user_message_event_handler.py +5 -5
- autobyteus/workflow/handlers/tool_approval_workflow_event_handler.py +2 -2
- autobyteus/workflow/runtime/workflow_runtime.py +8 -8
- autobyteus/workflow/runtime/workflow_worker.py +3 -3
- autobyteus/workflow/status/__init__.py +11 -0
- autobyteus/workflow/status/workflow_status.py +19 -0
- autobyteus/workflow/status/workflow_status_manager.py +48 -0
- autobyteus/workflow/streaming/__init__.py +2 -2
- autobyteus/workflow/streaming/workflow_event_notifier.py +7 -7
- autobyteus/workflow/streaming/workflow_stream_event_payloads.py +4 -4
- autobyteus/workflow/streaming/workflow_stream_events.py +3 -3
- autobyteus/workflow/utils/wait_for_idle.py +4 -4
- autobyteus-1.2.3.dist-info/METADATA +293 -0
- autobyteus-1.2.3.dist-info/RECORD +600 -0
- {autobyteus-1.2.1.dist-info → autobyteus-1.2.3.dist-info}/WHEEL +1 -1
- {autobyteus-1.2.1.dist-info → autobyteus-1.2.3.dist-info}/top_level.txt +0 -1
- autobyteus/agent/bootstrap_steps/agent_runtime_queue_initialization_step.py +0 -57
- autobyteus/agent/hooks/__init__.py +0 -16
- autobyteus/agent/hooks/base_phase_hook.py +0 -78
- autobyteus/agent/hooks/hook_definition.py +0 -36
- autobyteus/agent/hooks/hook_meta.py +0 -37
- autobyteus/agent/hooks/hook_registry.py +0 -106
- autobyteus/agent/llm_response_processor/provider_aware_tool_usage_processor.py +0 -103
- autobyteus/agent/phases/__init__.py +0 -18
- autobyteus/agent/phases/discover.py +0 -53
- autobyteus/agent/phases/manager.py +0 -265
- autobyteus/agent/phases/transition_decorator.py +0 -40
- autobyteus/agent/phases/transition_info.py +0 -33
- autobyteus/agent/remote_agent.py +0 -244
- autobyteus/agent/workspace/workspace_definition.py +0 -36
- autobyteus/agent/workspace/workspace_meta.py +0 -37
- autobyteus/agent/workspace/workspace_registry.py +0 -72
- autobyteus/agent_team/bootstrap_steps/agent_team_runtime_queue_initialization_step.py +0 -25
- autobyteus/agent_team/bootstrap_steps/coordinator_prompt_preparation_step.py +0 -85
- autobyteus/agent_team/phases/__init__.py +0 -11
- autobyteus/agent_team/phases/agent_team_operational_phase.py +0 -19
- autobyteus/agent_team/phases/agent_team_phase_manager.py +0 -48
- autobyteus/llm/api/bedrock_llm.py +0 -92
- autobyteus/llm/api/groq_llm.py +0 -94
- autobyteus/llm/api/nvidia_llm.py +0 -108
- autobyteus/llm/utils/token_pricing_config.py +0 -87
- autobyteus/rpc/__init__.py +0 -73
- autobyteus/rpc/client/__init__.py +0 -17
- autobyteus/rpc/client/abstract_client_connection.py +0 -124
- autobyteus/rpc/client/client_connection_manager.py +0 -153
- autobyteus/rpc/client/sse_client_connection.py +0 -306
- autobyteus/rpc/client/stdio_client_connection.py +0 -280
- autobyteus/rpc/config/__init__.py +0 -13
- autobyteus/rpc/config/agent_server_config.py +0 -153
- autobyteus/rpc/config/agent_server_registry.py +0 -152
- autobyteus/rpc/hosting.py +0 -244
- autobyteus/rpc/protocol.py +0 -244
- autobyteus/rpc/server/__init__.py +0 -20
- autobyteus/rpc/server/agent_server_endpoint.py +0 -181
- autobyteus/rpc/server/base_method_handler.py +0 -40
- autobyteus/rpc/server/method_handlers.py +0 -259
- autobyteus/rpc/server/sse_server_handler.py +0 -182
- autobyteus/rpc/server/stdio_server_handler.py +0 -151
- autobyteus/rpc/server_main.py +0 -198
- autobyteus/rpc/transport_type.py +0 -13
- autobyteus/tools/bash/__init__.py +0 -2
- autobyteus/tools/bash/bash_executor.py +0 -100
- autobyteus/tools/browser/__init__.py +0 -2
- autobyteus/tools/browser/session_aware/browser_session_aware_navigate_to.py +0 -75
- autobyteus/tools/browser/session_aware/browser_session_aware_tool.py +0 -30
- autobyteus/tools/browser/session_aware/browser_session_aware_web_element_trigger.py +0 -154
- autobyteus/tools/browser/session_aware/browser_session_aware_webpage_reader.py +0 -89
- autobyteus/tools/browser/session_aware/browser_session_aware_webpage_screenshot_taker.py +0 -107
- autobyteus/tools/browser/session_aware/factory/browser_session_aware_web_element_trigger_factory.py +0 -14
- autobyteus/tools/browser/session_aware/factory/browser_session_aware_webpage_reader_factory.py +0 -26
- autobyteus/tools/browser/session_aware/factory/browser_session_aware_webpage_screenshot_taker_factory.py +0 -14
- autobyteus/tools/browser/session_aware/shared_browser_session.py +0 -11
- autobyteus/tools/browser/session_aware/shared_browser_session_manager.py +0 -25
- autobyteus/tools/browser/session_aware/web_element_action.py +0 -20
- autobyteus/tools/browser/standalone/__init__.py +0 -6
- autobyteus/tools/browser/standalone/factory/__init__.py +0 -0
- autobyteus/tools/browser/standalone/factory/webpage_reader_factory.py +0 -25
- autobyteus/tools/browser/standalone/factory/webpage_screenshot_taker_factory.py +0 -14
- autobyteus/tools/browser/standalone/navigate_to.py +0 -84
- autobyteus/tools/browser/standalone/web_page_pdf_generator.py +0 -101
- autobyteus/tools/browser/standalone/webpage_image_downloader.py +0 -169
- autobyteus/tools/browser/standalone/webpage_reader.py +0 -105
- autobyteus/tools/browser/standalone/webpage_screenshot_taker.py +0 -105
- autobyteus/tools/file/edit_file.py +0 -200
- autobyteus/tools/file/list_directory.py +0 -168
- autobyteus/tools/file/search_files.py +0 -188
- autobyteus/tools/timer.py +0 -175
- autobyteus/tools/usage/parsers/__init__.py +0 -22
- autobyteus/tools/usage/parsers/_json_extractor.py +0 -99
- autobyteus/tools/usage/parsers/_string_decoders.py +0 -18
- autobyteus/tools/usage/parsers/anthropic_xml_tool_usage_parser.py +0 -10
- autobyteus/tools/usage/parsers/base_parser.py +0 -41
- autobyteus/tools/usage/parsers/default_json_tool_usage_parser.py +0 -83
- autobyteus/tools/usage/parsers/default_xml_tool_usage_parser.py +0 -316
- autobyteus/tools/usage/parsers/exceptions.py +0 -13
- autobyteus/tools/usage/parsers/gemini_json_tool_usage_parser.py +0 -77
- autobyteus/tools/usage/parsers/openai_json_tool_usage_parser.py +0 -149
- autobyteus/tools/usage/parsers/provider_aware_tool_usage_parser.py +0 -59
- autobyteus/tools/usage/registries/tool_usage_parser_registry.py +0 -62
- autobyteus/workflow/phases/__init__.py +0 -11
- autobyteus/workflow/phases/workflow_operational_phase.py +0 -19
- autobyteus/workflow/phases/workflow_phase_manager.py +0 -48
- autobyteus-1.2.1.dist-info/METADATA +0 -205
- autobyteus-1.2.1.dist-info/RECORD +0 -511
- examples/__init__.py +0 -1
- examples/agent_team/__init__.py +0 -1
- examples/discover_phase_transitions.py +0 -104
- examples/run_agentic_software_engineer.py +0 -239
- examples/run_browser_agent.py +0 -262
- examples/run_google_slides_agent.py +0 -287
- examples/run_mcp_browser_client.py +0 -174
- examples/run_mcp_google_slides_client.py +0 -270
- examples/run_mcp_list_tools.py +0 -189
- examples/run_poem_writer.py +0 -284
- examples/run_sqlite_agent.py +0 -295
- /autobyteus/{tools/browser/session_aware → skills}/__init__.py +0 -0
- /autobyteus/tools/{browser/session_aware/factory → skill}/__init__.py +0 -0
- {autobyteus-1.2.1.dist-info → autobyteus-1.2.3.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
from dataclasses import dataclass, field
|
|
2
|
+
from typing import Any, Dict, List, Optional
|
|
3
|
+
|
|
4
|
+
from .memory_types import MemoryType
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@dataclass
|
|
8
|
+
class RawTraceItem:
|
|
9
|
+
id: str
|
|
10
|
+
ts: float
|
|
11
|
+
turn_id: str
|
|
12
|
+
seq: int
|
|
13
|
+
trace_type: str
|
|
14
|
+
content: str
|
|
15
|
+
source_event: str
|
|
16
|
+
media: Optional[Dict[str, List[str]]] = None
|
|
17
|
+
tool_name: Optional[str] = None
|
|
18
|
+
tool_call_id: Optional[str] = None
|
|
19
|
+
tool_args: Optional[Dict[str, Any]] = None
|
|
20
|
+
tool_result: Optional[Any] = None
|
|
21
|
+
tool_error: Optional[str] = None
|
|
22
|
+
correlation_id: Optional[str] = None
|
|
23
|
+
tags: List[str] = field(default_factory=list)
|
|
24
|
+
tool_result_ref: Optional[str] = None
|
|
25
|
+
|
|
26
|
+
@property
|
|
27
|
+
def memory_type(self) -> MemoryType:
|
|
28
|
+
return MemoryType.RAW_TRACE
|
|
29
|
+
|
|
30
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
31
|
+
data: Dict[str, Any] = {
|
|
32
|
+
"id": self.id,
|
|
33
|
+
"ts": self.ts,
|
|
34
|
+
"turn_id": self.turn_id,
|
|
35
|
+
"seq": self.seq,
|
|
36
|
+
"trace_type": self.trace_type,
|
|
37
|
+
"content": self.content,
|
|
38
|
+
"source_event": self.source_event,
|
|
39
|
+
}
|
|
40
|
+
if self.media is not None:
|
|
41
|
+
data["media"] = self.media
|
|
42
|
+
if self.tool_name is not None:
|
|
43
|
+
data["tool_name"] = self.tool_name
|
|
44
|
+
if self.tool_call_id is not None:
|
|
45
|
+
data["tool_call_id"] = self.tool_call_id
|
|
46
|
+
if self.tool_args is not None:
|
|
47
|
+
data["tool_args"] = self.tool_args
|
|
48
|
+
if self.tool_result is not None:
|
|
49
|
+
data["tool_result"] = self.tool_result
|
|
50
|
+
if self.tool_error is not None:
|
|
51
|
+
data["tool_error"] = self.tool_error
|
|
52
|
+
if self.correlation_id is not None:
|
|
53
|
+
data["correlation_id"] = self.correlation_id
|
|
54
|
+
if self.tags:
|
|
55
|
+
data["tags"] = self.tags
|
|
56
|
+
if self.tool_result_ref is not None:
|
|
57
|
+
data["tool_result_ref"] = self.tool_result_ref
|
|
58
|
+
return data
|
|
59
|
+
|
|
60
|
+
@classmethod
|
|
61
|
+
def from_dict(cls, data: Dict[str, Any]) -> "RawTraceItem":
|
|
62
|
+
return cls(
|
|
63
|
+
id=data["id"],
|
|
64
|
+
ts=data["ts"],
|
|
65
|
+
turn_id=data["turn_id"],
|
|
66
|
+
seq=data["seq"],
|
|
67
|
+
trace_type=data["trace_type"],
|
|
68
|
+
content=data.get("content", ""),
|
|
69
|
+
source_event=data["source_event"],
|
|
70
|
+
media=data.get("media"),
|
|
71
|
+
tool_name=data.get("tool_name"),
|
|
72
|
+
tool_call_id=data.get("tool_call_id"),
|
|
73
|
+
tool_args=data.get("tool_args"),
|
|
74
|
+
tool_result=data.get("tool_result"),
|
|
75
|
+
tool_error=data.get("tool_error"),
|
|
76
|
+
correlation_id=data.get("correlation_id"),
|
|
77
|
+
tags=data.get("tags", []),
|
|
78
|
+
tool_result_ref=data.get("tool_result_ref"),
|
|
79
|
+
)
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
from dataclasses import dataclass, field
|
|
2
|
+
from typing import Any, Dict, List
|
|
3
|
+
|
|
4
|
+
from .memory_types import MemoryType
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@dataclass
|
|
8
|
+
class SemanticItem:
|
|
9
|
+
id: str
|
|
10
|
+
ts: float
|
|
11
|
+
fact: str
|
|
12
|
+
tags: List[str] = field(default_factory=list)
|
|
13
|
+
confidence: float = 0.0
|
|
14
|
+
salience: float = 0.0
|
|
15
|
+
|
|
16
|
+
@property
|
|
17
|
+
def memory_type(self) -> MemoryType:
|
|
18
|
+
return MemoryType.SEMANTIC
|
|
19
|
+
|
|
20
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
21
|
+
data: Dict[str, Any] = {
|
|
22
|
+
"id": self.id,
|
|
23
|
+
"ts": self.ts,
|
|
24
|
+
"fact": self.fact,
|
|
25
|
+
"confidence": self.confidence,
|
|
26
|
+
"salience": self.salience,
|
|
27
|
+
}
|
|
28
|
+
if self.tags:
|
|
29
|
+
data["tags"] = self.tags
|
|
30
|
+
return data
|
|
31
|
+
|
|
32
|
+
@classmethod
|
|
33
|
+
def from_dict(cls, data: Dict[str, Any]) -> "SemanticItem":
|
|
34
|
+
return cls(
|
|
35
|
+
id=data["id"],
|
|
36
|
+
ts=data["ts"],
|
|
37
|
+
fact=data.get("fact", ""),
|
|
38
|
+
tags=data.get("tags", []),
|
|
39
|
+
confidence=data.get("confidence", 0.0),
|
|
40
|
+
salience=data.get("salience", 0.0),
|
|
41
|
+
)
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from enum import Enum
|
|
3
|
+
from typing import Any, Optional, Dict
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ToolInteractionStatus(Enum):
|
|
7
|
+
PENDING = "pending"
|
|
8
|
+
SUCCESS = "success"
|
|
9
|
+
ERROR = "error"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass
|
|
13
|
+
class ToolInteraction:
|
|
14
|
+
tool_call_id: str
|
|
15
|
+
turn_id: Optional[str]
|
|
16
|
+
tool_name: Optional[str]
|
|
17
|
+
arguments: Optional[Dict[str, Any]]
|
|
18
|
+
result: Optional[Any]
|
|
19
|
+
error: Optional[str]
|
|
20
|
+
status: ToolInteractionStatus
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
@dataclass
|
|
5
|
+
class CompactionPolicy:
|
|
6
|
+
trigger_ratio: float = 0.8
|
|
7
|
+
raw_tail_turns: int = 4
|
|
8
|
+
max_item_chars: int = 2000
|
|
9
|
+
safety_margin_tokens: int = 256
|
|
10
|
+
|
|
11
|
+
def should_compact(self, prompt_tokens: int, input_budget: int) -> bool:
|
|
12
|
+
if input_budget <= 0:
|
|
13
|
+
return True
|
|
14
|
+
if prompt_tokens >= input_budget:
|
|
15
|
+
return True
|
|
16
|
+
return prompt_tokens >= int(self.trigger_ratio * input_budget)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
from dataclasses import dataclass, field
|
|
2
|
+
from typing import List
|
|
3
|
+
|
|
4
|
+
from autobyteus.memory.models.episodic_item import EpisodicItem
|
|
5
|
+
from autobyteus.memory.models.semantic_item import SemanticItem
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@dataclass
|
|
9
|
+
class MemoryBundle:
|
|
10
|
+
episodic: List[EpisodicItem] = field(default_factory=list)
|
|
11
|
+
semantic: List[SemanticItem] = field(default_factory=list)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from autobyteus.memory.models.memory_types import MemoryType
|
|
2
|
+
from autobyteus.memory.retrieval.memory_bundle import MemoryBundle
|
|
3
|
+
from autobyteus.memory.store.base_store import MemoryStore
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Retriever:
|
|
7
|
+
def __init__(self, store: MemoryStore):
|
|
8
|
+
self.store = store
|
|
9
|
+
|
|
10
|
+
def retrieve(self, max_episodic: int, max_semantic: int) -> MemoryBundle:
|
|
11
|
+
episodic = self.store.list(MemoryType.EPISODIC, limit=max_episodic)
|
|
12
|
+
semantic = self.store.list(MemoryType.SEMANTIC, limit=max_semantic)
|
|
13
|
+
return MemoryBundle(episodic=episodic, semantic=semantic)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
from typing import Iterable, List, Optional
|
|
3
|
+
|
|
4
|
+
from autobyteus.memory.models.memory_types import MemoryType
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class MemoryStore(ABC):
|
|
8
|
+
@abstractmethod
|
|
9
|
+
def add(self, items: Iterable[object]) -> None:
|
|
10
|
+
raise NotImplementedError
|
|
11
|
+
|
|
12
|
+
@abstractmethod
|
|
13
|
+
def list(self, memory_type: MemoryType, limit: Optional[int] = None) -> List[object]:
|
|
14
|
+
raise NotImplementedError
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from typing import Iterable, List, Optional, Union
|
|
4
|
+
|
|
5
|
+
from autobyteus.memory.models.memory_types import MemoryType
|
|
6
|
+
from autobyteus.memory.models.raw_trace_item import RawTraceItem
|
|
7
|
+
from autobyteus.memory.models.episodic_item import EpisodicItem
|
|
8
|
+
from autobyteus.memory.models.semantic_item import SemanticItem
|
|
9
|
+
from autobyteus.memory.store.base_store import MemoryStore
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class FileMemoryStore(MemoryStore):
|
|
13
|
+
def __init__(self, base_dir: Union[str, Path], agent_id: str):
|
|
14
|
+
self.base_dir = Path(base_dir)
|
|
15
|
+
self.agent_id = agent_id
|
|
16
|
+
self.agent_dir = self.base_dir / "agents" / agent_id
|
|
17
|
+
self.agent_dir.mkdir(parents=True, exist_ok=True)
|
|
18
|
+
|
|
19
|
+
def add(self, items: Iterable[object]) -> None:
|
|
20
|
+
for item in items:
|
|
21
|
+
memory_type = getattr(item, "memory_type", None)
|
|
22
|
+
if memory_type is None:
|
|
23
|
+
raise ValueError("Memory item missing memory_type")
|
|
24
|
+
path = self._get_file_path(memory_type)
|
|
25
|
+
record = item.to_dict() if hasattr(item, "to_dict") else item
|
|
26
|
+
with path.open("a", encoding="utf-8") as handle:
|
|
27
|
+
handle.write(json.dumps(record) + "\n")
|
|
28
|
+
|
|
29
|
+
def list(self, memory_type: MemoryType, limit: Optional[int] = None) -> List[object]:
|
|
30
|
+
path = self._get_file_path(memory_type)
|
|
31
|
+
if not path.exists():
|
|
32
|
+
return []
|
|
33
|
+
with path.open("r", encoding="utf-8") as handle:
|
|
34
|
+
lines = [line.strip() for line in handle.readlines() if line.strip()]
|
|
35
|
+
if limit is not None:
|
|
36
|
+
lines = lines[-limit:]
|
|
37
|
+
return [self._deserialize(memory_type, json.loads(line)) for line in lines]
|
|
38
|
+
|
|
39
|
+
def list_raw_trace_dicts(self) -> List[dict]:
|
|
40
|
+
path = self._get_file_path(MemoryType.RAW_TRACE)
|
|
41
|
+
if not path.exists():
|
|
42
|
+
return []
|
|
43
|
+
with path.open("r", encoding="utf-8") as handle:
|
|
44
|
+
return [json.loads(line) for line in handle if line.strip()]
|
|
45
|
+
|
|
46
|
+
def read_archive_raw_traces(self) -> List[dict]:
|
|
47
|
+
path = self._get_archive_path()
|
|
48
|
+
if not path.exists():
|
|
49
|
+
return []
|
|
50
|
+
with path.open("r", encoding="utf-8") as handle:
|
|
51
|
+
return [json.loads(line) for line in handle if line.strip()]
|
|
52
|
+
|
|
53
|
+
def prune_raw_traces(self, keep_turn_ids: set[str], archive: bool = True) -> None:
|
|
54
|
+
raw_items = self.list_raw_trace_dicts()
|
|
55
|
+
if not raw_items:
|
|
56
|
+
return
|
|
57
|
+
|
|
58
|
+
keep = []
|
|
59
|
+
removed = []
|
|
60
|
+
for item in raw_items:
|
|
61
|
+
if item.get("turn_id") in keep_turn_ids:
|
|
62
|
+
keep.append(item)
|
|
63
|
+
else:
|
|
64
|
+
removed.append(item)
|
|
65
|
+
|
|
66
|
+
raw_path = self._get_file_path(MemoryType.RAW_TRACE)
|
|
67
|
+
tmp_path = raw_path.with_suffix(".jsonl.tmp")
|
|
68
|
+
with tmp_path.open("w", encoding="utf-8") as handle:
|
|
69
|
+
for item in keep:
|
|
70
|
+
handle.write(json.dumps(item) + "\n")
|
|
71
|
+
tmp_path.replace(raw_path)
|
|
72
|
+
|
|
73
|
+
if archive and removed:
|
|
74
|
+
archive_path = self._get_archive_path()
|
|
75
|
+
with archive_path.open("a", encoding="utf-8") as handle:
|
|
76
|
+
for item in removed:
|
|
77
|
+
handle.write(json.dumps(item) + "\n")
|
|
78
|
+
|
|
79
|
+
def _get_file_path(self, memory_type: MemoryType) -> Path:
|
|
80
|
+
if memory_type == MemoryType.RAW_TRACE:
|
|
81
|
+
return self.agent_dir / "raw_traces.jsonl"
|
|
82
|
+
if memory_type == MemoryType.EPISODIC:
|
|
83
|
+
return self.agent_dir / "episodic.jsonl"
|
|
84
|
+
if memory_type == MemoryType.SEMANTIC:
|
|
85
|
+
return self.agent_dir / "semantic.jsonl"
|
|
86
|
+
raise ValueError(f"Unknown memory type: {memory_type}")
|
|
87
|
+
|
|
88
|
+
def _deserialize(self, memory_type: MemoryType, data: dict) -> object:
|
|
89
|
+
if memory_type == MemoryType.RAW_TRACE:
|
|
90
|
+
return RawTraceItem.from_dict(data)
|
|
91
|
+
if memory_type == MemoryType.EPISODIC:
|
|
92
|
+
return EpisodicItem.from_dict(data)
|
|
93
|
+
if memory_type == MemoryType.SEMANTIC:
|
|
94
|
+
return SemanticItem.from_dict(data)
|
|
95
|
+
raise ValueError(f"Unknown memory type: {memory_type}")
|
|
96
|
+
|
|
97
|
+
def _get_archive_path(self) -> Path:
|
|
98
|
+
return self.agent_dir / "raw_traces_archive.jsonl"
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
from typing import Dict, List
|
|
2
|
+
|
|
3
|
+
from autobyteus.memory.models.raw_trace_item import RawTraceItem
|
|
4
|
+
from autobyteus.memory.models.tool_interaction import ToolInteraction, ToolInteractionStatus
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def build_tool_interactions(raw_traces: List[RawTraceItem]) -> List[ToolInteraction]:
|
|
8
|
+
interactions: Dict[str, ToolInteraction] = {}
|
|
9
|
+
|
|
10
|
+
for trace in raw_traces:
|
|
11
|
+
if trace.trace_type not in {"tool_call", "tool_result"}:
|
|
12
|
+
continue
|
|
13
|
+
|
|
14
|
+
tool_call_id = trace.tool_call_id
|
|
15
|
+
if not tool_call_id:
|
|
16
|
+
continue
|
|
17
|
+
|
|
18
|
+
interaction = interactions.get(tool_call_id)
|
|
19
|
+
if interaction is None:
|
|
20
|
+
interaction = ToolInteraction(
|
|
21
|
+
tool_call_id=tool_call_id,
|
|
22
|
+
turn_id=trace.turn_id,
|
|
23
|
+
tool_name=trace.tool_name,
|
|
24
|
+
arguments=None,
|
|
25
|
+
result=None,
|
|
26
|
+
error=None,
|
|
27
|
+
status=ToolInteractionStatus.PENDING,
|
|
28
|
+
)
|
|
29
|
+
interactions[tool_call_id] = interaction
|
|
30
|
+
|
|
31
|
+
if trace.trace_type == "tool_call":
|
|
32
|
+
interaction.tool_name = trace.tool_name
|
|
33
|
+
interaction.arguments = trace.tool_args
|
|
34
|
+
if interaction.status == ToolInteractionStatus.PENDING and interaction.error:
|
|
35
|
+
interaction.status = ToolInteractionStatus.ERROR
|
|
36
|
+
continue
|
|
37
|
+
|
|
38
|
+
if trace.trace_type == "tool_result":
|
|
39
|
+
interaction.tool_name = trace.tool_name or interaction.tool_name
|
|
40
|
+
interaction.result = trace.tool_result
|
|
41
|
+
interaction.error = trace.tool_error
|
|
42
|
+
interaction.status = (
|
|
43
|
+
ToolInteractionStatus.ERROR if trace.tool_error else ToolInteractionStatus.SUCCESS
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
return list(interactions.values())
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import logging
|
|
2
|
+
import uuid
|
|
2
3
|
from typing import Optional, List, Dict, Any, TYPE_CHECKING
|
|
3
4
|
from autobyteus.clients import AutobyteusClient
|
|
4
5
|
from autobyteus.multimedia.audio.base_audio_client import BaseAudioClient
|
|
@@ -13,6 +14,7 @@ logger = logging.getLogger(__name__)
|
|
|
13
14
|
class AutobyteusAudioClient(BaseAudioClient):
|
|
14
15
|
"""
|
|
15
16
|
An audio client that connects to an Autobyteus server instance for audio tasks.
|
|
17
|
+
Maintains a persistent session ID for stateful interactions.
|
|
16
18
|
"""
|
|
17
19
|
|
|
18
20
|
def __init__(self, model: "AudioModel", config: "MultimediaConfig"):
|
|
@@ -21,7 +23,9 @@ class AutobyteusAudioClient(BaseAudioClient):
|
|
|
21
23
|
raise ValueError("AutobyteusAudioClient requires a host_url in its AudioModel.")
|
|
22
24
|
|
|
23
25
|
self.autobyteus_client = AutobyteusClient(server_url=model.host_url)
|
|
24
|
-
|
|
26
|
+
self.session_id = str(uuid.uuid4())
|
|
27
|
+
logger.info(f"AutobyteusAudioClient initialized for model '{model.name}' "
|
|
28
|
+
f"on host '{model.host_url}' with session_id '{self.session_id}'.")
|
|
25
29
|
|
|
26
30
|
async def generate_speech(
|
|
27
31
|
self,
|
|
@@ -33,7 +37,7 @@ class AutobyteusAudioClient(BaseAudioClient):
|
|
|
33
37
|
Generates speech by calling the generate_speech endpoint on the remote Autobyteus server.
|
|
34
38
|
"""
|
|
35
39
|
try:
|
|
36
|
-
logger.info(f"Sending speech generation request for model '{self.model.name}' to {self.model.host_url}")
|
|
40
|
+
logger.info(f"Sending speech generation request for model '{self.model.name}' to {self.model.host_url} (Session: {self.session_id})")
|
|
37
41
|
|
|
38
42
|
model_name_for_server = self.model.name
|
|
39
43
|
|
|
@@ -42,7 +46,8 @@ class AutobyteusAudioClient(BaseAudioClient):
|
|
|
42
46
|
response_data = await self.autobyteus_client.generate_speech(
|
|
43
47
|
model_name=model_name_for_server,
|
|
44
48
|
prompt=prompt,
|
|
45
|
-
generation_config=generation_config
|
|
49
|
+
generation_config=generation_config,
|
|
50
|
+
session_id=self.session_id
|
|
46
51
|
)
|
|
47
52
|
|
|
48
53
|
audio_urls = response_data.get("audio_urls", [])
|
|
@@ -56,7 +61,16 @@ class AutobyteusAudioClient(BaseAudioClient):
|
|
|
56
61
|
raise
|
|
57
62
|
|
|
58
63
|
async def cleanup(self):
|
|
59
|
-
"""
|
|
64
|
+
"""
|
|
65
|
+
Notifies the server to cleanup the session, then closes the underlying HTTP client.
|
|
66
|
+
"""
|
|
60
67
|
if self.autobyteus_client:
|
|
61
|
-
|
|
68
|
+
try:
|
|
69
|
+
logger.info(f"Notifying server to cleanup audio session '{self.session_id}'...")
|
|
70
|
+
await self.autobyteus_client.cleanup_audio_session(self.session_id)
|
|
71
|
+
except Exception as e:
|
|
72
|
+
logger.error(f"Failed to cleanup remote audio session '{self.session_id}': {e}")
|
|
73
|
+
finally:
|
|
74
|
+
await self.autobyteus_client.close()
|
|
75
|
+
|
|
62
76
|
logger.debug("AutobyteusAudioClient cleaned up.")
|
|
@@ -9,6 +9,8 @@ from google.genai import types as genai_types
|
|
|
9
9
|
|
|
10
10
|
from autobyteus.multimedia.audio.base_audio_client import BaseAudioClient
|
|
11
11
|
from autobyteus.multimedia.utils.response_types import SpeechGenerationResponse
|
|
12
|
+
from autobyteus.utils.gemini_helper import initialize_gemini_client_with_runtime
|
|
13
|
+
from autobyteus.utils.gemini_model_mapping import resolve_model_for_runtime
|
|
12
14
|
|
|
13
15
|
if TYPE_CHECKING:
|
|
14
16
|
from autobyteus.multimedia.audio.audio_model import AudioModel
|
|
@@ -17,11 +19,22 @@ if TYPE_CHECKING:
|
|
|
17
19
|
logger = logging.getLogger(__name__)
|
|
18
20
|
|
|
19
21
|
|
|
22
|
+
_AUDIO_TEMP_DIR = "/tmp/autobyteus_audio"
|
|
23
|
+
|
|
24
|
+
_AUDIO_MIME_EXTENSION_MAP = {
|
|
25
|
+
"audio/wav": "wav",
|
|
26
|
+
"audio/x-wav": "wav",
|
|
27
|
+
"audio/mpeg": "mp3",
|
|
28
|
+
"audio/mp3": "mp3",
|
|
29
|
+
"audio/ogg": "ogg",
|
|
30
|
+
"audio/webm": "webm",
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
|
|
20
34
|
def _save_audio_bytes_to_wav(pcm_bytes: bytes, channels=1, rate=24000, sample_width=2) -> str:
|
|
21
35
|
"""Saves PCM audio bytes to a temporary WAV file and returns the path."""
|
|
22
|
-
|
|
23
|
-
os.
|
|
24
|
-
file_path = os.path.join(temp_dir, f"{uuid.uuid4()}.wav")
|
|
36
|
+
os.makedirs(_AUDIO_TEMP_DIR, exist_ok=True)
|
|
37
|
+
file_path = os.path.join(_AUDIO_TEMP_DIR, f"{uuid.uuid4()}.wav")
|
|
25
38
|
|
|
26
39
|
try:
|
|
27
40
|
with wave.open(file_path, "wb") as wf:
|
|
@@ -36,22 +49,62 @@ def _save_audio_bytes_to_wav(pcm_bytes: bytes, channels=1, rate=24000, sample_wi
|
|
|
36
49
|
raise
|
|
37
50
|
|
|
38
51
|
|
|
52
|
+
def _save_audio_bytes(audio_bytes: bytes, extension: Optional[str]) -> str:
|
|
53
|
+
"""Saves audio bytes to a temporary file and returns the path."""
|
|
54
|
+
os.makedirs(_AUDIO_TEMP_DIR, exist_ok=True)
|
|
55
|
+
suffix = (extension or "bin").lstrip(".")
|
|
56
|
+
file_path = os.path.join(_AUDIO_TEMP_DIR, f"{uuid.uuid4()}.{suffix}")
|
|
57
|
+
try:
|
|
58
|
+
with open(file_path, "wb") as audio_file:
|
|
59
|
+
audio_file.write(audio_bytes)
|
|
60
|
+
logger.info(f"Successfully saved generated audio to {file_path}")
|
|
61
|
+
return file_path
|
|
62
|
+
except Exception as e:
|
|
63
|
+
logger.error(f"Failed to save audio to file at {file_path}: {e}")
|
|
64
|
+
raise
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def _parse_mime_type(mime_type: Optional[str]) -> tuple[str, Dict[str, str]]:
|
|
68
|
+
if not mime_type:
|
|
69
|
+
return "", {}
|
|
70
|
+
parts = [part.strip() for part in mime_type.split(";") if part.strip()]
|
|
71
|
+
base = parts[0].lower() if parts else ""
|
|
72
|
+
params: Dict[str, str] = {}
|
|
73
|
+
for part in parts[1:]:
|
|
74
|
+
if "=" in part:
|
|
75
|
+
key, value = part.split("=", 1)
|
|
76
|
+
params[key.strip().lower()] = value.strip()
|
|
77
|
+
return base, params
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def _coerce_audio_bytes(audio_data: Any) -> bytes:
|
|
81
|
+
if audio_data is None:
|
|
82
|
+
return b""
|
|
83
|
+
if isinstance(audio_data, bytes):
|
|
84
|
+
return audio_data
|
|
85
|
+
if isinstance(audio_data, bytearray):
|
|
86
|
+
return bytes(audio_data)
|
|
87
|
+
if isinstance(audio_data, memoryview):
|
|
88
|
+
return audio_data.tobytes()
|
|
89
|
+
if isinstance(audio_data, str):
|
|
90
|
+
return base64.b64decode(audio_data)
|
|
91
|
+
return bytes(audio_data)
|
|
92
|
+
|
|
93
|
+
|
|
39
94
|
class GeminiAudioClient(BaseAudioClient):
|
|
40
95
|
"""
|
|
41
96
|
An audio client that uses Google's Gemini models for audio tasks.
|
|
42
97
|
|
|
43
98
|
**Setup Requirements:**
|
|
44
|
-
1. **
|
|
99
|
+
1. **AI Studio Mode:** Set `GEMINI_API_KEY`.
|
|
100
|
+
2. **Vertex AI Mode:** Set `VERTEX_AI_PROJECT` and `VERTEX_AI_LOCATION`.
|
|
45
101
|
"""
|
|
46
102
|
|
|
47
103
|
def __init__(self, model: "AudioModel", config: "MultimediaConfig"):
|
|
48
104
|
super().__init__(model, config)
|
|
49
|
-
|
|
50
|
-
if not api_key:
|
|
51
|
-
raise ValueError("Please set the GEMINI_API_KEY environment variable.")
|
|
52
|
-
|
|
105
|
+
|
|
53
106
|
try:
|
|
54
|
-
self.client =
|
|
107
|
+
self.client, self.runtime_info = initialize_gemini_client_with_runtime()
|
|
55
108
|
self.async_client = self.client.aio
|
|
56
109
|
logger.info(f"GeminiAudioClient initialized for model '{self.model.name}'.")
|
|
57
110
|
except Exception as e:
|
|
@@ -70,8 +123,6 @@ class GeminiAudioClient(BaseAudioClient):
|
|
|
70
123
|
multi-speaker, and style-controlled generation.
|
|
71
124
|
"""
|
|
72
125
|
try:
|
|
73
|
-
logger.info(f"Generating speech with Gemini TTS model '{self.model.value}'...")
|
|
74
|
-
|
|
75
126
|
final_config = self.config.to_dict().copy()
|
|
76
127
|
if generation_config:
|
|
77
128
|
final_config.update(generation_config)
|
|
@@ -126,8 +177,19 @@ class GeminiAudioClient(BaseAudioClient):
|
|
|
126
177
|
)
|
|
127
178
|
|
|
128
179
|
# The google-genai library's TTS endpoint uses a synchronous call.
|
|
180
|
+
# FIX: Ensure no 'models/' prefix is used here.
|
|
181
|
+
runtime_adjusted_model = resolve_model_for_runtime(
|
|
182
|
+
self.model.value,
|
|
183
|
+
modality="tts",
|
|
184
|
+
runtime=getattr(self, "runtime_info", None) and self.runtime_info.runtime,
|
|
185
|
+
)
|
|
186
|
+
logger.info(
|
|
187
|
+
"Generating speech with Gemini TTS model '%s' (requested '%s').",
|
|
188
|
+
runtime_adjusted_model,
|
|
189
|
+
self.model.value,
|
|
190
|
+
)
|
|
129
191
|
resp = self.client.models.generate_content(
|
|
130
|
-
model=
|
|
192
|
+
model=runtime_adjusted_model,
|
|
131
193
|
contents=final_prompt,
|
|
132
194
|
config=genai_types.GenerateContentConfig(
|
|
133
195
|
response_modalities=["AUDIO"],
|
|
@@ -135,10 +197,40 @@ class GeminiAudioClient(BaseAudioClient):
|
|
|
135
197
|
),
|
|
136
198
|
)
|
|
137
199
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
200
|
+
part = resp.candidates[0].content.parts[0]
|
|
201
|
+
inline_data = part.inline_data
|
|
202
|
+
if not inline_data or not inline_data.data:
|
|
203
|
+
raise ValueError("Gemini TTS response did not include audio data.")
|
|
204
|
+
|
|
205
|
+
mime_type, mime_params = _parse_mime_type(inline_data.mime_type)
|
|
206
|
+
audio_bytes = _coerce_audio_bytes(inline_data.data)
|
|
207
|
+
if not audio_bytes:
|
|
208
|
+
raise ValueError("Gemini TTS returned empty audio data.")
|
|
209
|
+
|
|
210
|
+
logger.info(
|
|
211
|
+
"Received Gemini TTS audio payload (mime_type='%s', bytes=%d).",
|
|
212
|
+
mime_type or "unknown",
|
|
213
|
+
len(audio_bytes),
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
if not mime_type or mime_type.startswith("audio/pcm") or mime_type == "audio/l16":
|
|
217
|
+
rate = 24000
|
|
218
|
+
channels = 1
|
|
219
|
+
if "rate" in mime_params:
|
|
220
|
+
try:
|
|
221
|
+
rate = int(mime_params["rate"])
|
|
222
|
+
except ValueError:
|
|
223
|
+
logger.warning("Invalid sample rate in mime_type '%s'; using default 24000.", inline_data.mime_type)
|
|
224
|
+
if "channels" in mime_params:
|
|
225
|
+
try:
|
|
226
|
+
channels = int(mime_params["channels"])
|
|
227
|
+
except ValueError:
|
|
228
|
+
logger.warning("Invalid channel count in mime_type '%s'; using default 1.", inline_data.mime_type)
|
|
229
|
+
|
|
230
|
+
audio_path = _save_audio_bytes_to_wav(audio_bytes, channels=channels, rate=rate, sample_width=2)
|
|
231
|
+
else:
|
|
232
|
+
extension = _AUDIO_MIME_EXTENSION_MAP.get(mime_type, "bin")
|
|
233
|
+
audio_path = _save_audio_bytes(audio_bytes, extension)
|
|
142
234
|
|
|
143
235
|
return SpeechGenerationResponse(audio_urls=[audio_path])
|
|
144
236
|
|