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
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"""Content streamers for file tools in API tool call mode."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
from typing import Optional
|
|
6
|
+
|
|
7
|
+
from .json_string_field_extractor import JsonStringFieldExtractor
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@dataclass
|
|
11
|
+
class FileContentStreamUpdate:
|
|
12
|
+
"""Incremental update from a file content streamer."""
|
|
13
|
+
|
|
14
|
+
content_delta: str = ""
|
|
15
|
+
path: Optional[str] = None
|
|
16
|
+
content_complete: Optional[str] = None
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class _BaseFileContentStreamer:
|
|
20
|
+
def __init__(self, content_key: str):
|
|
21
|
+
self._content_key = content_key
|
|
22
|
+
self._extractor = JsonStringFieldExtractor(
|
|
23
|
+
stream_fields={content_key},
|
|
24
|
+
final_fields={"path", content_key},
|
|
25
|
+
)
|
|
26
|
+
self.path: Optional[str] = None
|
|
27
|
+
self.content: Optional[str] = None
|
|
28
|
+
|
|
29
|
+
def feed(self, json_delta: str) -> FileContentStreamUpdate:
|
|
30
|
+
result = self._extractor.feed(json_delta)
|
|
31
|
+
|
|
32
|
+
if "path" in result.completed and self.path is None:
|
|
33
|
+
self.path = result.completed["path"]
|
|
34
|
+
|
|
35
|
+
if self._content_key in result.completed:
|
|
36
|
+
self.content = result.completed[self._content_key]
|
|
37
|
+
|
|
38
|
+
return FileContentStreamUpdate(
|
|
39
|
+
content_delta=result.deltas.get(self._content_key, ""),
|
|
40
|
+
path=result.completed.get("path"),
|
|
41
|
+
content_complete=result.completed.get(self._content_key),
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class WriteFileContentStreamer(_BaseFileContentStreamer):
|
|
46
|
+
"""Streams decoded write_file content from JSON argument deltas."""
|
|
47
|
+
|
|
48
|
+
def __init__(self):
|
|
49
|
+
super().__init__(content_key="content")
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class PatchFileContentStreamer(_BaseFileContentStreamer):
|
|
53
|
+
"""Streams decoded patch_file content from JSON argument deltas."""
|
|
54
|
+
|
|
55
|
+
def __init__(self):
|
|
56
|
+
super().__init__(content_key="patch")
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Incremental JSON string field extractor for API tool call argument deltas.
|
|
3
|
+
|
|
4
|
+
This parser is intentionally small and focused: it streams specific string
|
|
5
|
+
fields (e.g., path/content/patch) from a JSON object as deltas arrive.
|
|
6
|
+
"""
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from dataclasses import dataclass, field
|
|
10
|
+
from typing import Dict, Iterable, Optional
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass
|
|
14
|
+
class FieldExtractionResult:
|
|
15
|
+
"""Holds incremental deltas and completed values for extracted fields."""
|
|
16
|
+
|
|
17
|
+
deltas: Dict[str, str] = field(default_factory=dict)
|
|
18
|
+
completed: Dict[str, str] = field(default_factory=dict)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class JsonStringFieldExtractor:
|
|
22
|
+
"""
|
|
23
|
+
Incrementally extracts specified string fields from a JSON object.
|
|
24
|
+
|
|
25
|
+
The extractor consumes raw JSON fragments and yields decoded string deltas
|
|
26
|
+
for configured fields. It is resilient to chunk boundaries and handles
|
|
27
|
+
common JSON escapes.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
def __init__(
|
|
31
|
+
self,
|
|
32
|
+
stream_fields: Iterable[str],
|
|
33
|
+
final_fields: Optional[Iterable[str]] = None,
|
|
34
|
+
):
|
|
35
|
+
self._stream_fields = set(stream_fields)
|
|
36
|
+
self._final_fields = set(final_fields) if final_fields is not None else set(stream_fields)
|
|
37
|
+
self._targets = self._stream_fields | self._final_fields
|
|
38
|
+
self._mode = "scan"
|
|
39
|
+
self._escape = False
|
|
40
|
+
self._unicode_escape: Optional[str] = None
|
|
41
|
+
self._current_key: Optional[str] = None
|
|
42
|
+
self._current_value_key: Optional[str] = None
|
|
43
|
+
self._string_buffer: str = ""
|
|
44
|
+
self._values: Dict[str, str] = {}
|
|
45
|
+
self._pending_delta: Dict[str, str] = {}
|
|
46
|
+
|
|
47
|
+
def feed(self, chunk: str) -> FieldExtractionResult:
|
|
48
|
+
"""Process a chunk and return any new deltas or completed values."""
|
|
49
|
+
if not chunk:
|
|
50
|
+
return FieldExtractionResult()
|
|
51
|
+
|
|
52
|
+
self._pending_delta = {}
|
|
53
|
+
completed: Dict[str, str] = {}
|
|
54
|
+
|
|
55
|
+
for char in chunk:
|
|
56
|
+
self._step(char, completed)
|
|
57
|
+
|
|
58
|
+
return FieldExtractionResult(deltas=self._pending_delta.copy(), completed=completed)
|
|
59
|
+
|
|
60
|
+
def _step(self, char: str, completed: Dict[str, str]) -> None:
|
|
61
|
+
if self._mode == "scan":
|
|
62
|
+
if char == '"':
|
|
63
|
+
self._string_buffer = ""
|
|
64
|
+
self._mode = "key"
|
|
65
|
+
return
|
|
66
|
+
|
|
67
|
+
if self._mode == "key":
|
|
68
|
+
if self._escape:
|
|
69
|
+
self._string_buffer += self._decode_escape(char)
|
|
70
|
+
return
|
|
71
|
+
if char == "\\":
|
|
72
|
+
self._escape = True
|
|
73
|
+
return
|
|
74
|
+
if char == '"':
|
|
75
|
+
self._current_key = self._string_buffer
|
|
76
|
+
self._string_buffer = ""
|
|
77
|
+
self._mode = "post_key"
|
|
78
|
+
return
|
|
79
|
+
self._string_buffer += char
|
|
80
|
+
return
|
|
81
|
+
|
|
82
|
+
if self._mode == "post_key":
|
|
83
|
+
if char.isspace():
|
|
84
|
+
return
|
|
85
|
+
if char == ":":
|
|
86
|
+
self._mode = "post_colon"
|
|
87
|
+
return
|
|
88
|
+
# Unexpected token; reset
|
|
89
|
+
self._reset_string_state()
|
|
90
|
+
self._mode = "scan"
|
|
91
|
+
return
|
|
92
|
+
|
|
93
|
+
if self._mode == "post_colon":
|
|
94
|
+
if char.isspace():
|
|
95
|
+
return
|
|
96
|
+
if char == '"':
|
|
97
|
+
self._mode = "value"
|
|
98
|
+
self._current_value_key = self._current_key
|
|
99
|
+
self._string_buffer = ""
|
|
100
|
+
return
|
|
101
|
+
# Non-string value; ignore and reset
|
|
102
|
+
self._current_key = None
|
|
103
|
+
self._mode = "scan"
|
|
104
|
+
return
|
|
105
|
+
|
|
106
|
+
if self._mode == "value":
|
|
107
|
+
if self._escape:
|
|
108
|
+
decoded = self._decode_escape(char)
|
|
109
|
+
self._append_value(decoded, completed)
|
|
110
|
+
return
|
|
111
|
+
if char == "\\":
|
|
112
|
+
self._escape = True
|
|
113
|
+
return
|
|
114
|
+
if char == '"':
|
|
115
|
+
self._finalize_value(completed)
|
|
116
|
+
self._mode = "scan"
|
|
117
|
+
return
|
|
118
|
+
self._append_value(char, completed)
|
|
119
|
+
|
|
120
|
+
def _append_value(self, decoded_char: str, completed: Dict[str, str]) -> None:
|
|
121
|
+
key = self._current_value_key
|
|
122
|
+
if not key:
|
|
123
|
+
return
|
|
124
|
+
if key in self._targets:
|
|
125
|
+
if key in self._stream_fields:
|
|
126
|
+
self._pending_delta[key] = self._pending_delta.get(key, "") + decoded_char
|
|
127
|
+
self._values[key] = self._values.get(key, "") + decoded_char
|
|
128
|
+
|
|
129
|
+
def _finalize_value(self, completed: Dict[str, str]) -> None:
|
|
130
|
+
key = self._current_value_key
|
|
131
|
+
if key in self._final_fields and key in self._values:
|
|
132
|
+
completed[key] = self._values[key]
|
|
133
|
+
self._current_key = None
|
|
134
|
+
self._current_value_key = None
|
|
135
|
+
self._string_buffer = ""
|
|
136
|
+
self._escape = False
|
|
137
|
+
self._unicode_escape = None
|
|
138
|
+
|
|
139
|
+
def _reset_string_state(self) -> None:
|
|
140
|
+
self._current_key = None
|
|
141
|
+
self._current_value_key = None
|
|
142
|
+
self._string_buffer = ""
|
|
143
|
+
self._escape = False
|
|
144
|
+
self._unicode_escape = None
|
|
145
|
+
|
|
146
|
+
def _decode_escape(self, char: str) -> str:
|
|
147
|
+
"""Decode common JSON escapes, tracking state for unicode if needed."""
|
|
148
|
+
if self._unicode_escape is not None:
|
|
149
|
+
self._unicode_escape += char
|
|
150
|
+
if len(self._unicode_escape) == 4:
|
|
151
|
+
try:
|
|
152
|
+
decoded = chr(int(self._unicode_escape, 16))
|
|
153
|
+
except ValueError:
|
|
154
|
+
decoded = ""
|
|
155
|
+
self._unicode_escape = None
|
|
156
|
+
self._escape = False
|
|
157
|
+
return decoded
|
|
158
|
+
return ""
|
|
159
|
+
|
|
160
|
+
self._escape = False
|
|
161
|
+
|
|
162
|
+
if char == "n":
|
|
163
|
+
return "\n"
|
|
164
|
+
if char == "t":
|
|
165
|
+
return "\t"
|
|
166
|
+
if char == "r":
|
|
167
|
+
return "\r"
|
|
168
|
+
if char == "\\":
|
|
169
|
+
return "\\"
|
|
170
|
+
if char == '"':
|
|
171
|
+
return '"'
|
|
172
|
+
if char == "u":
|
|
173
|
+
self._unicode_escape = ""
|
|
174
|
+
return ""
|
|
175
|
+
return char
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from typing import Dict, Any, Optional, List, Union
|
|
3
|
+
from pydantic import BaseModel, Field
|
|
4
|
+
|
|
5
|
+
from autobyteus.llm.utils.token_usage import TokenUsage
|
|
6
|
+
from autobyteus.agent.status.status_enum import AgentStatus
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
logger = logging.getLogger(__name__)
|
|
10
|
+
|
|
11
|
+
# --- Base Payload Model (Optional, for common fields if any) ---
|
|
12
|
+
class BaseStreamPayload(BaseModel):
|
|
13
|
+
class Config:
|
|
14
|
+
extra = "allow"
|
|
15
|
+
|
|
16
|
+
# --- Specific Payload Models for each StreamEventType ---
|
|
17
|
+
|
|
18
|
+
class AssistantChunkData(BaseStreamPayload):
|
|
19
|
+
content: str
|
|
20
|
+
reasoning: Optional[str] = None
|
|
21
|
+
is_complete: bool
|
|
22
|
+
usage: Optional[TokenUsage] = None
|
|
23
|
+
image_urls: Optional[List[str]] = None
|
|
24
|
+
audio_urls: Optional[List[str]] = None
|
|
25
|
+
video_urls: Optional[List[str]] = None
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class AssistantCompleteResponseData(BaseStreamPayload):
|
|
29
|
+
content: str
|
|
30
|
+
reasoning: Optional[str] = None
|
|
31
|
+
usage: Optional[TokenUsage] = None
|
|
32
|
+
image_urls: Optional[List[str]] = None
|
|
33
|
+
audio_urls: Optional[List[str]] = None
|
|
34
|
+
video_urls: Optional[List[str]] = None
|
|
35
|
+
|
|
36
|
+
class ToolInteractionLogEntryData(BaseStreamPayload):
|
|
37
|
+
log_entry: str
|
|
38
|
+
tool_invocation_id: str
|
|
39
|
+
tool_name: str
|
|
40
|
+
|
|
41
|
+
class AgentStatusUpdateData(BaseStreamPayload):
|
|
42
|
+
new_status: AgentStatus
|
|
43
|
+
old_status: Optional[AgentStatus] = None
|
|
44
|
+
trigger: Optional[str] = None
|
|
45
|
+
tool_name: Optional[str] = None
|
|
46
|
+
error_message: Optional[str] = None
|
|
47
|
+
error_details: Optional[str] = None
|
|
48
|
+
|
|
49
|
+
class ErrorEventData(BaseStreamPayload):
|
|
50
|
+
source: str
|
|
51
|
+
message: str
|
|
52
|
+
details: Optional[str] = None
|
|
53
|
+
|
|
54
|
+
class ToolInvocationApprovalRequestedData(BaseStreamPayload):
|
|
55
|
+
invocation_id: str
|
|
56
|
+
tool_name: str
|
|
57
|
+
arguments: Dict[str, Any]
|
|
58
|
+
|
|
59
|
+
class ToolInvocationAutoExecutingData(BaseStreamPayload):
|
|
60
|
+
invocation_id: str
|
|
61
|
+
tool_name: str
|
|
62
|
+
arguments: Dict[str, Any]
|
|
63
|
+
|
|
64
|
+
class SegmentEventData(BaseStreamPayload):
|
|
65
|
+
event_type: str = Field(alias="type")
|
|
66
|
+
segment_id: str
|
|
67
|
+
segment_type: Optional[str] = None
|
|
68
|
+
payload: Dict[str, Any] = Field(default_factory=dict)
|
|
69
|
+
|
|
70
|
+
class Config:
|
|
71
|
+
populate_by_name = True
|
|
72
|
+
|
|
73
|
+
# NEW PAYLOAD
|
|
74
|
+
class SystemTaskNotificationData(BaseStreamPayload):
|
|
75
|
+
sender_id: str
|
|
76
|
+
content: str
|
|
77
|
+
|
|
78
|
+
# NEW PAYLOAD: Inter-agent message surfaced to UI
|
|
79
|
+
class InterAgentMessageData(BaseStreamPayload):
|
|
80
|
+
sender_agent_id: str
|
|
81
|
+
recipient_role_name: str
|
|
82
|
+
content: str
|
|
83
|
+
message_type: str
|
|
84
|
+
|
|
85
|
+
class ToDoItemData(BaseStreamPayload):
|
|
86
|
+
description: str
|
|
87
|
+
todo_id: str
|
|
88
|
+
status: str
|
|
89
|
+
|
|
90
|
+
class ToDoListUpdateData(BaseStreamPayload):
|
|
91
|
+
todos: List[ToDoItemData]
|
|
92
|
+
|
|
93
|
+
class ArtifactPersistedData(BaseStreamPayload):
|
|
94
|
+
artifact_id: str
|
|
95
|
+
path: str
|
|
96
|
+
agent_id: str
|
|
97
|
+
type: str
|
|
98
|
+
workspace_root: Optional[str] = None
|
|
99
|
+
url: Optional[str] = None
|
|
100
|
+
|
|
101
|
+
class ArtifactUpdatedData(BaseStreamPayload):
|
|
102
|
+
artifact_id: Optional[str] = None
|
|
103
|
+
path: str
|
|
104
|
+
agent_id: str
|
|
105
|
+
type: str
|
|
106
|
+
workspace_root: Optional[str] = None
|
|
107
|
+
|
|
108
|
+
class EmptyData(BaseStreamPayload):
|
|
109
|
+
pass
|
|
110
|
+
|
|
111
|
+
# Union of all possible data payload types
|
|
112
|
+
StreamDataPayload = Union[
|
|
113
|
+
AssistantChunkData,
|
|
114
|
+
AssistantCompleteResponseData,
|
|
115
|
+
ToolInteractionLogEntryData,
|
|
116
|
+
AgentStatusUpdateData,
|
|
117
|
+
ErrorEventData,
|
|
118
|
+
ToolInvocationApprovalRequestedData,
|
|
119
|
+
ToolInvocationAutoExecutingData,
|
|
120
|
+
SegmentEventData,
|
|
121
|
+
SystemTaskNotificationData,
|
|
122
|
+
InterAgentMessageData,
|
|
123
|
+
ToDoListUpdateData,
|
|
124
|
+
ArtifactPersistedData,
|
|
125
|
+
ArtifactUpdatedData,
|
|
126
|
+
EmptyData
|
|
127
|
+
]
|
|
128
|
+
|
|
129
|
+
# Factory functions to create payload models from various inputs
|
|
130
|
+
|
|
131
|
+
def create_assistant_chunk_data(chunk_obj: Any) -> AssistantChunkData:
|
|
132
|
+
"""Factory function to create AssistantChunkData from a chunk object."""
|
|
133
|
+
usage_data = None
|
|
134
|
+
if hasattr(chunk_obj, 'usage'):
|
|
135
|
+
usage_data = getattr(chunk_obj, 'usage')
|
|
136
|
+
elif isinstance(chunk_obj, dict) and 'usage' in chunk_obj:
|
|
137
|
+
usage_data = chunk_obj.get('usage')
|
|
138
|
+
|
|
139
|
+
parsed_usage = None
|
|
140
|
+
if usage_data:
|
|
141
|
+
if isinstance(usage_data, TokenUsage):
|
|
142
|
+
parsed_usage = usage_data
|
|
143
|
+
elif isinstance(usage_data, dict):
|
|
144
|
+
try:
|
|
145
|
+
parsed_usage = TokenUsage(**usage_data)
|
|
146
|
+
except Exception as e:
|
|
147
|
+
logger.warning(f"Could not parse usage dict into TokenUsage for AssistantChunkData: {e}. Usage dict: {usage_data}")
|
|
148
|
+
else:
|
|
149
|
+
logger.warning(f"Unsupported usage type {type(usage_data)} for AssistantChunkData.")
|
|
150
|
+
|
|
151
|
+
if hasattr(chunk_obj, 'content') and hasattr(chunk_obj, 'is_complete'):
|
|
152
|
+
return AssistantChunkData(
|
|
153
|
+
content=str(getattr(chunk_obj, 'content', '')),
|
|
154
|
+
reasoning=getattr(chunk_obj, 'reasoning', None),
|
|
155
|
+
is_complete=bool(getattr(chunk_obj, 'is_complete', False)),
|
|
156
|
+
usage=parsed_usage,
|
|
157
|
+
image_urls=getattr(chunk_obj, 'image_urls', None),
|
|
158
|
+
audio_urls=getattr(chunk_obj, 'audio_urls', None),
|
|
159
|
+
video_urls=getattr(chunk_obj, 'video_urls', None)
|
|
160
|
+
)
|
|
161
|
+
elif isinstance(chunk_obj, dict):
|
|
162
|
+
return AssistantChunkData(
|
|
163
|
+
content=str(chunk_obj.get('content', '')),
|
|
164
|
+
reasoning=chunk_obj.get('reasoning', None),
|
|
165
|
+
is_complete=bool(chunk_obj.get('is_complete', False)),
|
|
166
|
+
usage=parsed_usage,
|
|
167
|
+
image_urls=chunk_obj.get('image_urls', None),
|
|
168
|
+
audio_urls=chunk_obj.get('audio_urls', None),
|
|
169
|
+
video_urls=chunk_obj.get('video_urls', None)
|
|
170
|
+
)
|
|
171
|
+
raise ValueError(f"Cannot create AssistantChunkData from {type(chunk_obj)}")
|
|
172
|
+
|
|
173
|
+
def create_assistant_complete_response_data(complete_resp_obj: Any) -> AssistantCompleteResponseData:
|
|
174
|
+
usage_data = None
|
|
175
|
+
if hasattr(complete_resp_obj, 'usage'):
|
|
176
|
+
usage_data = getattr(complete_resp_obj, 'usage')
|
|
177
|
+
elif isinstance(complete_resp_obj, dict) and 'usage' in complete_resp_obj:
|
|
178
|
+
usage_data = complete_resp_obj.get('usage')
|
|
179
|
+
|
|
180
|
+
parsed_usage = None
|
|
181
|
+
if usage_data:
|
|
182
|
+
if isinstance(usage_data, TokenUsage):
|
|
183
|
+
parsed_usage = usage_data
|
|
184
|
+
elif isinstance(usage_data, dict):
|
|
185
|
+
try:
|
|
186
|
+
parsed_usage = TokenUsage(**usage_data)
|
|
187
|
+
except Exception as e: # pragma: no cover
|
|
188
|
+
logger.warning(f"Could not parse usage dict into TokenUsage for AssistantCompleteResponseData: {e}. Usage dict: {usage_data}")
|
|
189
|
+
else: # pragma: no cover
|
|
190
|
+
logger.warning(f"Unsupported usage type {type(usage_data)} for AssistantCompleteResponseData.")
|
|
191
|
+
|
|
192
|
+
if hasattr(complete_resp_obj, 'content'):
|
|
193
|
+
return AssistantCompleteResponseData(
|
|
194
|
+
content=str(getattr(complete_resp_obj, 'content', '')),
|
|
195
|
+
reasoning=getattr(complete_resp_obj, 'reasoning', None),
|
|
196
|
+
usage=parsed_usage,
|
|
197
|
+
image_urls=getattr(complete_resp_obj, 'image_urls', None),
|
|
198
|
+
audio_urls=getattr(complete_resp_obj, 'audio_urls', None),
|
|
199
|
+
video_urls=getattr(complete_resp_obj, 'video_urls', None)
|
|
200
|
+
)
|
|
201
|
+
elif isinstance(complete_resp_obj, dict):
|
|
202
|
+
return AssistantCompleteResponseData(
|
|
203
|
+
content=str(complete_resp_obj.get('content', '')),
|
|
204
|
+
reasoning=complete_resp_obj.get('reasoning', None),
|
|
205
|
+
usage=parsed_usage,
|
|
206
|
+
image_urls=complete_resp_obj.get('image_urls', None),
|
|
207
|
+
audio_urls=complete_resp_obj.get('audio_urls', None),
|
|
208
|
+
video_urls=complete_resp_obj.get('video_urls', None)
|
|
209
|
+
)
|
|
210
|
+
raise ValueError(f"Cannot create AssistantCompleteResponseData from {type(complete_resp_obj)}")
|
|
211
|
+
|
|
212
|
+
def create_tool_interaction_log_entry_data(log_data: Any) -> ToolInteractionLogEntryData:
|
|
213
|
+
if isinstance(log_data, dict):
|
|
214
|
+
if all(k in log_data for k in ['log_entry', 'tool_invocation_id', 'tool_name']):
|
|
215
|
+
return ToolInteractionLogEntryData(**log_data)
|
|
216
|
+
raise ValueError(f"Cannot create ToolInteractionLogEntryData from {type(log_data)}. Expected dict with 'log_entry', 'tool_invocation_id', and 'tool_name' keys.")
|
|
217
|
+
|
|
218
|
+
def create_agent_status_update_data(status_data_dict: Any) -> AgentStatusUpdateData:
|
|
219
|
+
if isinstance(status_data_dict, dict):
|
|
220
|
+
return AgentStatusUpdateData(**status_data_dict)
|
|
221
|
+
raise ValueError(f"Cannot create AgentStatusUpdateData from {type(status_data_dict)}")
|
|
222
|
+
|
|
223
|
+
def create_error_event_data(error_data_dict: Any) -> ErrorEventData:
|
|
224
|
+
if isinstance(error_data_dict, dict):
|
|
225
|
+
return ErrorEventData(**error_data_dict)
|
|
226
|
+
raise ValueError(f"Cannot create ErrorEventData from {type(error_data_dict)}")
|
|
227
|
+
|
|
228
|
+
def create_tool_invocation_approval_requested_data(approval_data_dict: Any) -> ToolInvocationApprovalRequestedData:
|
|
229
|
+
if isinstance(approval_data_dict, dict):
|
|
230
|
+
return ToolInvocationApprovalRequestedData(**approval_data_dict)
|
|
231
|
+
raise ValueError(f"Cannot create ToolInvocationApprovalRequestedData from {type(approval_data_dict)}")
|
|
232
|
+
|
|
233
|
+
def create_tool_invocation_auto_executing_data(auto_exec_data_dict: Any) -> ToolInvocationAutoExecutingData:
|
|
234
|
+
if isinstance(auto_exec_data_dict, dict):
|
|
235
|
+
return ToolInvocationAutoExecutingData(**auto_exec_data_dict)
|
|
236
|
+
raise ValueError(f"Cannot create ToolInvocationAutoExecutingData from {type(auto_exec_data_dict)}")
|
|
237
|
+
|
|
238
|
+
def create_segment_event_data(event_data: Any) -> SegmentEventData:
|
|
239
|
+
if isinstance(event_data, SegmentEventData):
|
|
240
|
+
return event_data
|
|
241
|
+
if isinstance(event_data, dict):
|
|
242
|
+
return SegmentEventData(**event_data)
|
|
243
|
+
raise ValueError(f"Cannot create SegmentEventData from {type(event_data)}")
|
|
244
|
+
|
|
245
|
+
def create_inter_agent_message_data(msg_data: Any) -> InterAgentMessageData:
|
|
246
|
+
if isinstance(msg_data, dict):
|
|
247
|
+
required_keys = ["sender_agent_id", "recipient_role_name", "content", "message_type"]
|
|
248
|
+
missing = [k for k in required_keys if k not in msg_data]
|
|
249
|
+
if missing:
|
|
250
|
+
raise ValueError(f"InterAgentMessageData missing keys: {missing}")
|
|
251
|
+
return InterAgentMessageData(**msg_data)
|
|
252
|
+
raise ValueError(f"Cannot create InterAgentMessageData from {type(msg_data)}")
|
|
253
|
+
|
|
254
|
+
def create_system_task_notification_data(notification_data_dict: Any) -> SystemTaskNotificationData:
|
|
255
|
+
if isinstance(notification_data_dict, dict):
|
|
256
|
+
return SystemTaskNotificationData(**notification_data_dict)
|
|
257
|
+
raise ValueError(f"Cannot create SystemTaskNotificationData from {type(notification_data_dict)}")
|
|
258
|
+
|
|
259
|
+
def create_todo_list_update_data(todo_data_dict: Any) -> ToDoListUpdateData:
|
|
260
|
+
if isinstance(todo_data_dict, dict):
|
|
261
|
+
todos_payload = todo_data_dict.get('todos', [])
|
|
262
|
+
if not isinstance(todos_payload, list):
|
|
263
|
+
raise ValueError("Expected 'todos' to be a list when creating ToDoListUpdateData.")
|
|
264
|
+
todo_items = []
|
|
265
|
+
for todo_entry in todos_payload:
|
|
266
|
+
if not isinstance(todo_entry, dict):
|
|
267
|
+
logger.warning(f"Skipping non-dict todo entry when creating ToDoListUpdateData: {todo_entry!r}")
|
|
268
|
+
continue
|
|
269
|
+
try:
|
|
270
|
+
todo_items.append(ToDoItemData(**todo_entry))
|
|
271
|
+
except Exception as exc:
|
|
272
|
+
logger.warning(f"Failed to parse todo entry into ToDoItemData: {todo_entry!r}; error: {exc}")
|
|
273
|
+
return ToDoListUpdateData(todos=todo_items)
|
|
274
|
+
raise ValueError(f"Cannot create ToDoListUpdateData from {type(todo_data_dict)}")
|
|
275
|
+
|
|
276
|
+
def create_artifact_persisted_data(data_dict: Any) -> ArtifactPersistedData:
|
|
277
|
+
if isinstance(data_dict, dict):
|
|
278
|
+
return ArtifactPersistedData(**data_dict)
|
|
279
|
+
raise ValueError(f"Cannot create ArtifactPersistedData from {type(data_dict)}")
|
|
280
|
+
|
|
281
|
+
def create_artifact_updated_data(data_dict: Any) -> ArtifactUpdatedData:
|
|
282
|
+
if isinstance(data_dict, dict):
|
|
283
|
+
return ArtifactUpdatedData(**data_dict)
|
|
284
|
+
raise ValueError(f"Cannot create ArtifactUpdatedData from {type(data_dict)}")
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# file: autobyteus/autobyteus/agent/streaming/stream_events.py
|
|
2
|
+
import logging
|
|
3
|
+
from enum import Enum
|
|
4
|
+
from typing import Dict, Any, Optional, Union, Type
|
|
5
|
+
from pydantic import BaseModel, Field, AwareDatetime, field_validator, ValidationInfo
|
|
6
|
+
import datetime
|
|
7
|
+
import uuid
|
|
8
|
+
|
|
9
|
+
# Import the payload models
|
|
10
|
+
from .stream_event_payloads import (
|
|
11
|
+
StreamDataPayload,
|
|
12
|
+
AssistantChunkData,
|
|
13
|
+
AssistantCompleteResponseData,
|
|
14
|
+
ToolInteractionLogEntryData,
|
|
15
|
+
AgentStatusUpdateData,
|
|
16
|
+
ErrorEventData,
|
|
17
|
+
ToolInvocationApprovalRequestedData,
|
|
18
|
+
ToolInvocationAutoExecutingData,
|
|
19
|
+
SegmentEventData,
|
|
20
|
+
SystemTaskNotificationData, # NEW
|
|
21
|
+
InterAgentMessageData, # NEW
|
|
22
|
+
ToDoListUpdateData,
|
|
23
|
+
ArtifactPersistedData, # NEW
|
|
24
|
+
ArtifactUpdatedData, # NEW
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
logger = logging.getLogger(__name__)
|
|
28
|
+
|
|
29
|
+
class StreamEventType(str, Enum):
|
|
30
|
+
"""
|
|
31
|
+
Defines the types of events that can appear in a unified agent output stream
|
|
32
|
+
provided by AgentEventStream.
|
|
33
|
+
"""
|
|
34
|
+
ASSISTANT_CHUNK = "assistant_chunk"
|
|
35
|
+
ASSISTANT_COMPLETE_RESPONSE = "assistant_complete_response"
|
|
36
|
+
TOOL_INTERACTION_LOG_ENTRY = "tool_interaction_log_entry"
|
|
37
|
+
AGENT_STATUS_UPDATED = "agent_status_updated"
|
|
38
|
+
ERROR_EVENT = "error_event"
|
|
39
|
+
TOOL_INVOCATION_APPROVAL_REQUESTED = "tool_invocation_approval_requested"
|
|
40
|
+
TOOL_INVOCATION_AUTO_EXECUTING = "tool_invocation_auto_executing"
|
|
41
|
+
SEGMENT_EVENT = "segment_event"
|
|
42
|
+
SYSTEM_TASK_NOTIFICATION = "system_task_notification" # NEW
|
|
43
|
+
INTER_AGENT_MESSAGE = "inter_agent_message" # NEW
|
|
44
|
+
AGENT_TODO_LIST_UPDATE = "agent_todo_list_updated"
|
|
45
|
+
ARTIFACT_PERSISTED = "artifact_persisted" # NEW
|
|
46
|
+
ARTIFACT_UPDATED = "artifact_updated" # NEW
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
_STREAM_EVENT_TYPE_TO_PAYLOAD_CLASS: Dict[StreamEventType, Type[BaseModel]] = {
|
|
50
|
+
StreamEventType.ASSISTANT_CHUNK: AssistantChunkData,
|
|
51
|
+
StreamEventType.ASSISTANT_COMPLETE_RESPONSE: AssistantCompleteResponseData,
|
|
52
|
+
StreamEventType.TOOL_INTERACTION_LOG_ENTRY: ToolInteractionLogEntryData,
|
|
53
|
+
StreamEventType.AGENT_STATUS_UPDATED: AgentStatusUpdateData,
|
|
54
|
+
StreamEventType.ERROR_EVENT: ErrorEventData,
|
|
55
|
+
StreamEventType.TOOL_INVOCATION_APPROVAL_REQUESTED: ToolInvocationApprovalRequestedData,
|
|
56
|
+
StreamEventType.TOOL_INVOCATION_AUTO_EXECUTING: ToolInvocationAutoExecutingData,
|
|
57
|
+
StreamEventType.SEGMENT_EVENT: SegmentEventData,
|
|
58
|
+
StreamEventType.SYSTEM_TASK_NOTIFICATION: SystemTaskNotificationData, # NEW
|
|
59
|
+
StreamEventType.INTER_AGENT_MESSAGE: InterAgentMessageData, # NEW
|
|
60
|
+
StreamEventType.AGENT_TODO_LIST_UPDATE: ToDoListUpdateData,
|
|
61
|
+
StreamEventType.ARTIFACT_PERSISTED: ArtifactPersistedData, # NEW
|
|
62
|
+
StreamEventType.ARTIFACT_UPDATED: ArtifactUpdatedData, # NEW
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class StreamEvent(BaseModel):
|
|
67
|
+
"""
|
|
68
|
+
Pydantic model for a unified, typed event in an agent's output stream.
|
|
69
|
+
The 'data' field is now a discriminated union of specific payload models
|
|
70
|
+
based on 'event_type'.
|
|
71
|
+
"""
|
|
72
|
+
event_id: str = Field(
|
|
73
|
+
default_factory=lambda: str(uuid.uuid4()),
|
|
74
|
+
description="Unique identifier for the event."
|
|
75
|
+
)
|
|
76
|
+
timestamp: AwareDatetime = Field(
|
|
77
|
+
default_factory=lambda: datetime.datetime.now(datetime.timezone.utc),
|
|
78
|
+
description="Timestamp of when the event was created (UTC)."
|
|
79
|
+
)
|
|
80
|
+
event_type: StreamEventType = Field(
|
|
81
|
+
...,
|
|
82
|
+
description="The type of the event. This acts as the discriminator."
|
|
83
|
+
)
|
|
84
|
+
data: StreamDataPayload = Field(
|
|
85
|
+
...,
|
|
86
|
+
description="Payload of the event, specific to the event_type."
|
|
87
|
+
)
|
|
88
|
+
agent_id: Optional[str] = Field(
|
|
89
|
+
default=None,
|
|
90
|
+
description="Optional ID of the agent that originated this event."
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
@field_validator('data', mode='before')
|
|
94
|
+
def validate_data_based_on_event_type(cls, v, info: ValidationInfo):
|
|
95
|
+
event_type_value = info.data.get('event_type')
|
|
96
|
+
if not event_type_value:
|
|
97
|
+
return v
|
|
98
|
+
|
|
99
|
+
if isinstance(event_type_value, str):
|
|
100
|
+
try:
|
|
101
|
+
event_type = StreamEventType(event_type_value)
|
|
102
|
+
except ValueError: # pragma: no cover
|
|
103
|
+
logger.error(f"Invalid event_type string '{event_type_value}' for validation.")
|
|
104
|
+
raise ValueError(f"Invalid event_type string '{event_type_value}'")
|
|
105
|
+
elif isinstance(event_type_value, StreamEventType):
|
|
106
|
+
event_type = event_type_value
|
|
107
|
+
else: # pragma: no cover
|
|
108
|
+
logger.error(f"event_type is of unexpected type {type(event_type_value)} during validation.")
|
|
109
|
+
raise TypeError(f"event_type is of unexpected type {type(event_type_value)}")
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
payload_class = _STREAM_EVENT_TYPE_TO_PAYLOAD_CLASS.get(event_type)
|
|
113
|
+
|
|
114
|
+
if payload_class:
|
|
115
|
+
if isinstance(v, payload_class):
|
|
116
|
+
return v
|
|
117
|
+
if isinstance(v, dict):
|
|
118
|
+
try:
|
|
119
|
+
return payload_class(**v)
|
|
120
|
+
except Exception as e:
|
|
121
|
+
logger.error(f"Failed to parse dict into {payload_class.__name__} for event_type {event_type.value}: {e}. Dict was: {v}")
|
|
122
|
+
raise ValueError(f"Data for event type {event_type.value} does not match expected model {payload_class.__name__}.") from e
|
|
123
|
+
logger.error(f"Data for event type {event_type.value} is of unexpected type {type(v)}. Expected dict or {payload_class.__name__}.")
|
|
124
|
+
raise ValueError(f"Data for event type {event_type.value} is of unexpected type {type(v)}.")
|
|
125
|
+
|
|
126
|
+
logger.warning(f"No specific payload class mapped for event_type: {event_type.value}. Raw data: {v}")
|
|
127
|
+
if isinstance(v, dict):
|
|
128
|
+
return v
|
|
129
|
+
return v
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
class Config:
|
|
133
|
+
populate_by_name = True
|
|
134
|
+
|
|
135
|
+
def __repr__(self) -> str:
|
|
136
|
+
return (f"<StreamEvent event_id='{self.event_id}', agent_id='{self.agent_id}', "
|
|
137
|
+
f"type='{self.event_type.value}', timestamp='{self.timestamp.isoformat()}', data_type='{type(self.data).__name__}'>")
|
|
138
|
+
|
|
139
|
+
def __str__(self) -> str:
|
|
140
|
+
return (f"StreamEvent[{self.event_type.value}] (ID: {self.event_id}, Agent: {self.agent_id or 'N/A'}): "
|
|
141
|
+
f"Data: {self.data!r}")
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"""Streaming response handlers."""
|
|
2
|
+
|
|
3
|
+
from .streaming_response_handler import StreamingResponseHandler
|
|
4
|
+
from .streaming_handler_factory import StreamingResponseHandlerFactory
|
|
5
|
+
from .parsing_streaming_response_handler import ParsingStreamingResponseHandler
|
|
6
|
+
from .pass_through_streaming_response_handler import PassThroughStreamingResponseHandler
|
|
7
|
+
from .api_tool_call_streaming_response_handler import ApiToolCallStreamingResponseHandler
|
|
8
|
+
|
|
9
|
+
__all__ = [
|
|
10
|
+
"StreamingResponseHandler",
|
|
11
|
+
"StreamingResponseHandlerFactory",
|
|
12
|
+
"ParsingStreamingResponseHandler",
|
|
13
|
+
"PassThroughStreamingResponseHandler",
|
|
14
|
+
"ApiToolCallStreamingResponseHandler",
|
|
15
|
+
]
|