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,58 @@
|
|
|
1
|
+
"""
|
|
2
|
+
StreamingResponseHandler: Abstract Base Class for response handlers.
|
|
3
|
+
"""
|
|
4
|
+
from abc import ABC, abstractmethod
|
|
5
|
+
from typing import List, Optional, Callable, Union
|
|
6
|
+
from autobyteus.agent.tool_invocation import ToolInvocation
|
|
7
|
+
from autobyteus.llm.utils.response_types import ChunkResponse
|
|
8
|
+
from ..segments.segment_events import SegmentEvent
|
|
9
|
+
|
|
10
|
+
class StreamingResponseHandler(ABC):
|
|
11
|
+
"""
|
|
12
|
+
Abstract base class for handling streaming LLM responses.
|
|
13
|
+
|
|
14
|
+
Handlers receive the full ChunkResponse object and decide which fields to use:
|
|
15
|
+
- Text parsers use chunk.content
|
|
16
|
+
- API tool call handlers use chunk.tool_calls
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
@abstractmethod
|
|
20
|
+
def feed(self, chunk: ChunkResponse) -> List[SegmentEvent]:
|
|
21
|
+
"""
|
|
22
|
+
Process a chunk of LLM response.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
chunk: The full ChunkResponse containing text, tool calls, etc.
|
|
26
|
+
|
|
27
|
+
Returns:
|
|
28
|
+
List of SegmentEvents emitted while processing this chunk.
|
|
29
|
+
"""
|
|
30
|
+
pass
|
|
31
|
+
|
|
32
|
+
@abstractmethod
|
|
33
|
+
def finalize(self) -> List[SegmentEvent]:
|
|
34
|
+
"""
|
|
35
|
+
Finalize parsing and emit any remaining segments.
|
|
36
|
+
"""
|
|
37
|
+
pass
|
|
38
|
+
|
|
39
|
+
@abstractmethod
|
|
40
|
+
def get_all_invocations(self) -> List[ToolInvocation]:
|
|
41
|
+
"""
|
|
42
|
+
Get all ToolInvocations created so far.
|
|
43
|
+
"""
|
|
44
|
+
pass
|
|
45
|
+
|
|
46
|
+
@abstractmethod
|
|
47
|
+
def get_all_events(self) -> List[SegmentEvent]:
|
|
48
|
+
"""
|
|
49
|
+
Get all SegmentEvents emitted so far.
|
|
50
|
+
"""
|
|
51
|
+
pass
|
|
52
|
+
|
|
53
|
+
@abstractmethod
|
|
54
|
+
def reset(self) -> None:
|
|
55
|
+
"""
|
|
56
|
+
Reset the handler for reuse.
|
|
57
|
+
"""
|
|
58
|
+
pass
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Parser package
|
|
2
|
+
"""
|
|
3
|
+
Streaming Parser: Character-by-character LLM response parser.
|
|
4
|
+
|
|
5
|
+
Main components:
|
|
6
|
+
- StreamingParser: Main entry point for parsing
|
|
7
|
+
- StreamingResponseHandler: High-level handler with callbacks
|
|
8
|
+
- ToolInvocationAdapter: Converts tool segments to ToolInvocations
|
|
9
|
+
- SegmentEvent: Structured events emitted during parsing
|
|
10
|
+
"""
|
|
11
|
+
from .streaming_parser import StreamingParser, parse_complete_response, extract_segments
|
|
12
|
+
from .parser_factory import (
|
|
13
|
+
create_streaming_parser,
|
|
14
|
+
resolve_parser_name,
|
|
15
|
+
StreamingParserProtocol,
|
|
16
|
+
)
|
|
17
|
+
from .events import SegmentEvent, SegmentType, SegmentEventType
|
|
18
|
+
from .invocation_adapter import ToolInvocationAdapter
|
|
19
|
+
from .parser_context import ParserConfig
|
|
20
|
+
from .xml_tool_parsing_state_registry import XmlToolParsingStateRegistry
|
|
21
|
+
from .states.xml_tool_parsing_state import XmlToolParsingState
|
|
22
|
+
from .states.xml_write_file_tool_parsing_state import XmlWriteFileToolParsingState
|
|
23
|
+
from .states.xml_patch_file_tool_parsing_state import XmlPatchFileToolParsingState
|
|
24
|
+
|
|
25
|
+
def register_xml_tool_parsing_state(tool_name: str, state_class):
|
|
26
|
+
"""
|
|
27
|
+
Public API to register a custom parsing state for a specific tool.
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
tool_name: The name of the tool (e.g., 'patch_prompt').
|
|
31
|
+
state_class: The parsing state class (must inherit from XmlToolParsingState or BaseState).
|
|
32
|
+
"""
|
|
33
|
+
XmlToolParsingStateRegistry().register_tool_state(tool_name, state_class)
|
|
34
|
+
|
|
35
|
+
__all__ = [
|
|
36
|
+
# Main classes
|
|
37
|
+
"StreamingParser",
|
|
38
|
+
"ToolInvocationAdapter",
|
|
39
|
+
"ParserConfig",
|
|
40
|
+
"StreamingParserProtocol",
|
|
41
|
+
"create_streaming_parser",
|
|
42
|
+
"resolve_parser_name",
|
|
43
|
+
|
|
44
|
+
# Event types
|
|
45
|
+
"SegmentEvent",
|
|
46
|
+
"SegmentType",
|
|
47
|
+
"SegmentEventType",
|
|
48
|
+
|
|
49
|
+
# Convenience functions
|
|
50
|
+
"parse_complete_response",
|
|
51
|
+
"extract_segments",
|
|
52
|
+
|
|
53
|
+
# Public Registry API
|
|
54
|
+
"register_xml_tool_parsing_state",
|
|
55
|
+
"XmlToolParsingStateRegistry",
|
|
56
|
+
|
|
57
|
+
# Base States for inheritance
|
|
58
|
+
"XmlToolParsingState",
|
|
59
|
+
"XmlWriteFileToolParsingState",
|
|
60
|
+
"XmlPatchFileToolParsingState",
|
|
61
|
+
]
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
"""
|
|
2
|
+
EventEmitter: Manages segment event emission for the streaming parser.
|
|
3
|
+
|
|
4
|
+
This class is responsible for:
|
|
5
|
+
- Generating unique segment IDs
|
|
6
|
+
- Tracking the current active segment
|
|
7
|
+
- Building and queuing SegmentEvents
|
|
8
|
+
- Managing the event queue
|
|
9
|
+
"""
|
|
10
|
+
from typing import Optional, List, Dict, Any
|
|
11
|
+
import logging
|
|
12
|
+
|
|
13
|
+
from .events import SegmentEvent, SegmentType, SegmentEventType
|
|
14
|
+
|
|
15
|
+
logger = logging.getLogger(__name__)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class EventEmitter:
|
|
19
|
+
"""
|
|
20
|
+
Manages segment event emission for the streaming parser.
|
|
21
|
+
|
|
22
|
+
Extracted from ParserContext to improve single responsibility.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
def __init__(self, segment_id_prefix: Optional[str] = None):
|
|
26
|
+
self._event_queue: List[SegmentEvent] = []
|
|
27
|
+
self._segment_counter: int = 0
|
|
28
|
+
self._current_segment_id: Optional[str] = None
|
|
29
|
+
self._current_segment_type: Optional[SegmentType] = None
|
|
30
|
+
self._current_segment_content: str = ""
|
|
31
|
+
self._current_segment_metadata: Dict[str, Any] = {}
|
|
32
|
+
self._segment_id_prefix: Optional[str] = segment_id_prefix
|
|
33
|
+
|
|
34
|
+
def _generate_segment_id(self) -> str:
|
|
35
|
+
"""Generate a unique segment ID."""
|
|
36
|
+
self._segment_counter += 1
|
|
37
|
+
base_id = f"seg_{self._segment_counter}"
|
|
38
|
+
if self._segment_id_prefix:
|
|
39
|
+
return f"{self._segment_id_prefix}{base_id}"
|
|
40
|
+
return base_id
|
|
41
|
+
|
|
42
|
+
def emit_segment_start(
|
|
43
|
+
self,
|
|
44
|
+
segment_type: SegmentType,
|
|
45
|
+
**metadata
|
|
46
|
+
) -> str:
|
|
47
|
+
"""
|
|
48
|
+
Emit a SEGMENT_START event and begin tracking a new segment.
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
segment_type: The type of segment starting.
|
|
52
|
+
**metadata: Additional metadata for the segment.
|
|
53
|
+
|
|
54
|
+
Returns:
|
|
55
|
+
The generated segment ID.
|
|
56
|
+
"""
|
|
57
|
+
segment_id = self._generate_segment_id()
|
|
58
|
+
self._current_segment_id = segment_id
|
|
59
|
+
self._current_segment_type = segment_type
|
|
60
|
+
self._current_segment_content = ""
|
|
61
|
+
self._current_segment_metadata = dict(metadata)
|
|
62
|
+
|
|
63
|
+
event = SegmentEvent.start(segment_id, segment_type, **metadata)
|
|
64
|
+
self._event_queue.append(event)
|
|
65
|
+
return segment_id
|
|
66
|
+
|
|
67
|
+
def emit_segment_content(self, delta: Any) -> None:
|
|
68
|
+
"""
|
|
69
|
+
Emit a SEGMENT_CONTENT event for the current segment.
|
|
70
|
+
|
|
71
|
+
Args:
|
|
72
|
+
delta: The content delta to emit.
|
|
73
|
+
|
|
74
|
+
Raises:
|
|
75
|
+
RuntimeError: If no segment is active.
|
|
76
|
+
"""
|
|
77
|
+
if self._current_segment_id is None:
|
|
78
|
+
raise RuntimeError("Cannot emit content without an active segment.")
|
|
79
|
+
|
|
80
|
+
# Accumulate string content
|
|
81
|
+
if isinstance(delta, str):
|
|
82
|
+
self._current_segment_content += delta
|
|
83
|
+
|
|
84
|
+
event = SegmentEvent.content(self._current_segment_id, delta)
|
|
85
|
+
self._event_queue.append(event)
|
|
86
|
+
|
|
87
|
+
def emit_segment_end(self) -> Optional[str]:
|
|
88
|
+
"""
|
|
89
|
+
Emit a SEGMENT_END event and stop tracking the current segment.
|
|
90
|
+
|
|
91
|
+
The END event includes the current segment metadata for downstream
|
|
92
|
+
processing (e.g., tool invocation creation).
|
|
93
|
+
|
|
94
|
+
Returns:
|
|
95
|
+
The segment ID that was ended, or None if no active segment.
|
|
96
|
+
"""
|
|
97
|
+
if self._current_segment_id is None:
|
|
98
|
+
return None
|
|
99
|
+
|
|
100
|
+
segment_id = self._current_segment_id
|
|
101
|
+
|
|
102
|
+
# Include metadata in END event for downstream processing
|
|
103
|
+
event = SegmentEvent(
|
|
104
|
+
event_type=SegmentEventType.END,
|
|
105
|
+
segment_id=segment_id,
|
|
106
|
+
payload={"metadata": self._current_segment_metadata.copy()} if self._current_segment_metadata else {}
|
|
107
|
+
)
|
|
108
|
+
self._event_queue.append(event)
|
|
109
|
+
|
|
110
|
+
# Clear tracking
|
|
111
|
+
self._current_segment_id = None
|
|
112
|
+
self._current_segment_type = None
|
|
113
|
+
|
|
114
|
+
return segment_id
|
|
115
|
+
|
|
116
|
+
# --- Query Methods ---
|
|
117
|
+
|
|
118
|
+
def get_current_segment_id(self) -> Optional[str]:
|
|
119
|
+
"""Get the ID of the currently active segment."""
|
|
120
|
+
return self._current_segment_id
|
|
121
|
+
|
|
122
|
+
def get_current_segment_type(self) -> Optional[SegmentType]:
|
|
123
|
+
"""Get the type of the currently active segment."""
|
|
124
|
+
return self._current_segment_type
|
|
125
|
+
|
|
126
|
+
def get_current_segment_content(self) -> str:
|
|
127
|
+
"""Get the accumulated content of the current segment."""
|
|
128
|
+
return self._current_segment_content
|
|
129
|
+
|
|
130
|
+
def get_current_segment_metadata(self) -> Dict[str, Any]:
|
|
131
|
+
"""Get the metadata of the current segment."""
|
|
132
|
+
return self._current_segment_metadata.copy()
|
|
133
|
+
|
|
134
|
+
def update_current_segment_metadata(self, **metadata) -> None:
|
|
135
|
+
"""Update metadata for the current segment."""
|
|
136
|
+
self._current_segment_metadata.update(metadata)
|
|
137
|
+
|
|
138
|
+
# --- Event Queue Management ---
|
|
139
|
+
|
|
140
|
+
def get_and_clear_events(self) -> List[SegmentEvent]:
|
|
141
|
+
"""
|
|
142
|
+
Get all queued events and clear the queue.
|
|
143
|
+
|
|
144
|
+
Returns:
|
|
145
|
+
List of SegmentEvents that were queued.
|
|
146
|
+
"""
|
|
147
|
+
events = self._event_queue.copy()
|
|
148
|
+
self._event_queue.clear()
|
|
149
|
+
return events
|
|
150
|
+
|
|
151
|
+
def get_events(self) -> List[SegmentEvent]:
|
|
152
|
+
"""Get all queued events without clearing."""
|
|
153
|
+
return self._event_queue.copy()
|
|
154
|
+
|
|
155
|
+
# --- Convenience Methods ---
|
|
156
|
+
|
|
157
|
+
def append_text_segment(self, text: str) -> None:
|
|
158
|
+
"""
|
|
159
|
+
Convenience method to emit a complete text segment.
|
|
160
|
+
|
|
161
|
+
Emits START (if needed) and CONTENT events for a text segment.
|
|
162
|
+
The segment remains open until explicitly ended by the caller.
|
|
163
|
+
|
|
164
|
+
Args:
|
|
165
|
+
text: The text content to emit.
|
|
166
|
+
"""
|
|
167
|
+
if not text:
|
|
168
|
+
return
|
|
169
|
+
|
|
170
|
+
if self._current_segment_type != SegmentType.TEXT:
|
|
171
|
+
if self._current_segment_id is not None:
|
|
172
|
+
logger.warning(
|
|
173
|
+
"append_text_segment called while non-text segment is active (%s); "
|
|
174
|
+
"ending it before starting a text segment.",
|
|
175
|
+
self._current_segment_type,
|
|
176
|
+
)
|
|
177
|
+
self.emit_segment_end()
|
|
178
|
+
|
|
179
|
+
self.emit_segment_start(SegmentType.TEXT)
|
|
180
|
+
|
|
181
|
+
self.emit_segment_content(text)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""JSON tool parsing strategies and registry."""
|
|
2
|
+
from .base import JsonToolParsingStrategy, ToolCallData
|
|
3
|
+
from .default import DefaultJsonToolParsingStrategy
|
|
4
|
+
from .gemini import GeminiJsonToolParsingStrategy
|
|
5
|
+
from .openai import OpenAiJsonToolParsingStrategy
|
|
6
|
+
from .registry import (
|
|
7
|
+
JsonToolParsingProfile,
|
|
8
|
+
get_json_tool_parsing_profile,
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
__all__ = [
|
|
12
|
+
"JsonToolParsingStrategy",
|
|
13
|
+
"ToolCallData",
|
|
14
|
+
"DefaultJsonToolParsingStrategy",
|
|
15
|
+
"GeminiJsonToolParsingStrategy",
|
|
16
|
+
"OpenAiJsonToolParsingStrategy",
|
|
17
|
+
"JsonToolParsingProfile",
|
|
18
|
+
"get_json_tool_parsing_profile",
|
|
19
|
+
]
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Shared types and helpers for JSON tool-call parsing strategies.
|
|
3
|
+
"""
|
|
4
|
+
from typing import Protocol, List, Dict, Any, TypedDict
|
|
5
|
+
import json
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class ToolCallData(TypedDict):
|
|
9
|
+
name: str
|
|
10
|
+
arguments: Dict[str, Any]
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class JsonToolParsingStrategy(Protocol):
|
|
14
|
+
"""Interface for provider-aware JSON tool parsing."""
|
|
15
|
+
|
|
16
|
+
def parse(self, raw_json: str) -> List[ToolCallData]:
|
|
17
|
+
"""Parse JSON string into zero or more tool calls."""
|
|
18
|
+
...
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def coerce_arguments(value: Any) -> Dict[str, Any]:
|
|
22
|
+
"""Normalize argument payload into a dict when possible."""
|
|
23
|
+
if isinstance(value, dict):
|
|
24
|
+
return value
|
|
25
|
+
if isinstance(value, str):
|
|
26
|
+
try:
|
|
27
|
+
parsed = json.loads(value)
|
|
28
|
+
if isinstance(parsed, dict):
|
|
29
|
+
return parsed
|
|
30
|
+
except json.JSONDecodeError:
|
|
31
|
+
return {}
|
|
32
|
+
return {}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"""Default JSON tool-call parsing for generic formats."""
|
|
2
|
+
from typing import Any, List
|
|
3
|
+
import json
|
|
4
|
+
|
|
5
|
+
from .base import ToolCallData, coerce_arguments
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class DefaultJsonToolParsingStrategy:
|
|
9
|
+
"""Parses the default Autobyteus JSON tool call format."""
|
|
10
|
+
|
|
11
|
+
def parse(self, raw_json: str) -> List[ToolCallData]:
|
|
12
|
+
try:
|
|
13
|
+
data = json.loads(raw_json)
|
|
14
|
+
except json.JSONDecodeError:
|
|
15
|
+
return []
|
|
16
|
+
|
|
17
|
+
tool = None
|
|
18
|
+
if isinstance(data, dict):
|
|
19
|
+
tool = data.get("tool")
|
|
20
|
+
if not isinstance(tool, dict):
|
|
21
|
+
return []
|
|
22
|
+
|
|
23
|
+
name = tool.get("function")
|
|
24
|
+
if isinstance(name, dict):
|
|
25
|
+
name = name.get("name")
|
|
26
|
+
if not isinstance(name, str) or not name:
|
|
27
|
+
return []
|
|
28
|
+
|
|
29
|
+
args = tool.get("parameters")
|
|
30
|
+
if args is None:
|
|
31
|
+
args = tool.get("arguments")
|
|
32
|
+
arguments = coerce_arguments(args)
|
|
33
|
+
|
|
34
|
+
return [{"name": name, "arguments": arguments}]
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"""Gemini-style JSON tool-call parsing."""
|
|
2
|
+
from typing import Any, List
|
|
3
|
+
import json
|
|
4
|
+
|
|
5
|
+
from .base import ToolCallData, coerce_arguments
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class GeminiJsonToolParsingStrategy:
|
|
9
|
+
"""Parses Gemini tool call JSON formats (name + args)."""
|
|
10
|
+
|
|
11
|
+
def parse(self, raw_json: str) -> List[ToolCallData]:
|
|
12
|
+
try:
|
|
13
|
+
data = json.loads(raw_json)
|
|
14
|
+
except json.JSONDecodeError:
|
|
15
|
+
return []
|
|
16
|
+
|
|
17
|
+
calls: List[Any] = data if isinstance(data, list) else [data]
|
|
18
|
+
parsed: List[ToolCallData] = []
|
|
19
|
+
|
|
20
|
+
for call in calls:
|
|
21
|
+
if not isinstance(call, dict):
|
|
22
|
+
continue
|
|
23
|
+
|
|
24
|
+
name = call.get("name")
|
|
25
|
+
if not isinstance(name, str) or not name:
|
|
26
|
+
continue
|
|
27
|
+
|
|
28
|
+
arguments = coerce_arguments(call.get("args"))
|
|
29
|
+
parsed.append({"name": name, "arguments": arguments})
|
|
30
|
+
|
|
31
|
+
return parsed
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"""OpenAI-style JSON tool-call parsing."""
|
|
2
|
+
from typing import Any, Dict, List
|
|
3
|
+
import json
|
|
4
|
+
|
|
5
|
+
from .base import ToolCallData, coerce_arguments
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class OpenAiJsonToolParsingStrategy:
|
|
9
|
+
"""Parses OpenAI-compatible tool call JSON formats."""
|
|
10
|
+
|
|
11
|
+
def parse(self, raw_json: str) -> List[ToolCallData]:
|
|
12
|
+
try:
|
|
13
|
+
data = json.loads(raw_json)
|
|
14
|
+
except json.JSONDecodeError:
|
|
15
|
+
return []
|
|
16
|
+
|
|
17
|
+
tool_calls = self._extract_tool_calls(data)
|
|
18
|
+
parsed: List[ToolCallData] = []
|
|
19
|
+
|
|
20
|
+
for call in tool_calls:
|
|
21
|
+
if not isinstance(call, dict):
|
|
22
|
+
continue
|
|
23
|
+
|
|
24
|
+
# Unwrap if nested under "tool"
|
|
25
|
+
if isinstance(call.get("tool"), dict):
|
|
26
|
+
call = call.get("tool")
|
|
27
|
+
if not isinstance(call, dict):
|
|
28
|
+
continue
|
|
29
|
+
|
|
30
|
+
function_data: Dict[str, Any] = {}
|
|
31
|
+
function_value = call.get("function")
|
|
32
|
+
if isinstance(function_value, dict):
|
|
33
|
+
function_data = function_value
|
|
34
|
+
elif isinstance(function_value, str):
|
|
35
|
+
# Default JSON format uses function as a string tool name.
|
|
36
|
+
function_data = call
|
|
37
|
+
elif "name" in call or "arguments" in call or "parameters" in call:
|
|
38
|
+
function_data = call
|
|
39
|
+
|
|
40
|
+
name = function_data.get("name") or function_data.get("function")
|
|
41
|
+
if not isinstance(name, str) or not name:
|
|
42
|
+
continue
|
|
43
|
+
|
|
44
|
+
args = function_data.get("arguments")
|
|
45
|
+
if args is None:
|
|
46
|
+
args = function_data.get("parameters")
|
|
47
|
+
arguments = coerce_arguments(args)
|
|
48
|
+
|
|
49
|
+
parsed.append({"name": name, "arguments": arguments})
|
|
50
|
+
|
|
51
|
+
return parsed
|
|
52
|
+
|
|
53
|
+
def _extract_tool_calls(self, data: Any) -> List[Any]:
|
|
54
|
+
if isinstance(data, dict):
|
|
55
|
+
if isinstance(data.get("tool_calls"), list):
|
|
56
|
+
return data.get("tool_calls")
|
|
57
|
+
if isinstance(data.get("tools"), list):
|
|
58
|
+
return data.get("tools")
|
|
59
|
+
if isinstance(data.get("tool"), dict):
|
|
60
|
+
return [data.get("tool")]
|
|
61
|
+
return [data]
|
|
62
|
+
if isinstance(data, list):
|
|
63
|
+
return data
|
|
64
|
+
return []
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"""Provider-aware JSON tool parsing profiles."""
|
|
2
|
+
from dataclasses import dataclass
|
|
3
|
+
from typing import List, Optional
|
|
4
|
+
|
|
5
|
+
from autobyteus.llm.providers import LLMProvider
|
|
6
|
+
from autobyteus.utils.tool_call_format import resolve_tool_call_format
|
|
7
|
+
|
|
8
|
+
from .base import JsonToolParsingStrategy
|
|
9
|
+
from .default import DefaultJsonToolParsingStrategy
|
|
10
|
+
from .gemini import GeminiJsonToolParsingStrategy
|
|
11
|
+
from .openai import OpenAiJsonToolParsingStrategy
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@dataclass(frozen=True)
|
|
15
|
+
class JsonToolParsingProfile:
|
|
16
|
+
parser: JsonToolParsingStrategy
|
|
17
|
+
signature_patterns: List[str]
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
OPENAI_JSON_PATTERNS = [
|
|
21
|
+
'{"tool":',
|
|
22
|
+
'{"tool_calls":',
|
|
23
|
+
'{"tools":',
|
|
24
|
+
'{"function":',
|
|
25
|
+
'[{"tool":',
|
|
26
|
+
'[{"function":',
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
GEMINI_JSON_PATTERNS = [
|
|
30
|
+
'{"name":',
|
|
31
|
+
'[{"name":',
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
DEFAULT_JSON_PATTERNS = [
|
|
35
|
+
'{"tool":',
|
|
36
|
+
'{"function":',
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
OPENAI_PROFILE = JsonToolParsingProfile(
|
|
41
|
+
parser=OpenAiJsonToolParsingStrategy(),
|
|
42
|
+
signature_patterns=OPENAI_JSON_PATTERNS,
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
GEMINI_PROFILE = JsonToolParsingProfile(
|
|
46
|
+
parser=GeminiJsonToolParsingStrategy(),
|
|
47
|
+
signature_patterns=GEMINI_JSON_PATTERNS,
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
DEFAULT_PROFILE = JsonToolParsingProfile(
|
|
51
|
+
parser=DefaultJsonToolParsingStrategy(),
|
|
52
|
+
signature_patterns=DEFAULT_JSON_PATTERNS,
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
OPENAI_LIKE_PROVIDERS = {
|
|
57
|
+
LLMProvider.OPENAI,
|
|
58
|
+
LLMProvider.MISTRAL,
|
|
59
|
+
LLMProvider.DEEPSEEK,
|
|
60
|
+
LLMProvider.GROK,
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def get_json_tool_parsing_profile(provider: Optional[LLMProvider]) -> JsonToolParsingProfile:
|
|
65
|
+
"""Return the JSON tool parsing profile for a provider, honoring overrides."""
|
|
66
|
+
override = resolve_tool_call_format()
|
|
67
|
+
if override == "json":
|
|
68
|
+
return DEFAULT_PROFILE
|
|
69
|
+
|
|
70
|
+
if provider == LLMProvider.GEMINI:
|
|
71
|
+
return GEMINI_PROFILE
|
|
72
|
+
if provider in OPENAI_LIKE_PROVIDERS:
|
|
73
|
+
return OPENAI_PROFILE
|
|
74
|
+
|
|
75
|
+
return DEFAULT_PROFILE
|