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,227 @@
|
|
|
1
|
+
"""
|
|
2
|
+
ParserContext: Holds the shared state for the streaming parser state machine.
|
|
3
|
+
|
|
4
|
+
This class manages the scanner, current state, and configuration.
|
|
5
|
+
Event emission is delegated to the EventEmitter.
|
|
6
|
+
States use this context to read characters, emit events, and transition.
|
|
7
|
+
"""
|
|
8
|
+
from typing import Optional, List, Dict, Any, TYPE_CHECKING
|
|
9
|
+
|
|
10
|
+
from .stream_scanner import StreamScanner
|
|
11
|
+
from .event_emitter import EventEmitter
|
|
12
|
+
from .events import SegmentEvent, SegmentType
|
|
13
|
+
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from .states.base_state import BaseState
|
|
16
|
+
from .json_parsing_strategies.base import JsonToolParsingStrategy
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class ParserConfig:
|
|
20
|
+
"""Configuration for the streaming parser."""
|
|
21
|
+
|
|
22
|
+
# Default patterns for JSON tool call detection
|
|
23
|
+
DEFAULT_JSON_PATTERNS = [
|
|
24
|
+
'{"tool"',
|
|
25
|
+
'{"tool_calls"',
|
|
26
|
+
'{"tools"',
|
|
27
|
+
'{"function"',
|
|
28
|
+
'{"name"',
|
|
29
|
+
'[{"tool"',
|
|
30
|
+
'[{"function"',
|
|
31
|
+
'[{"name"'
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
def __init__(
|
|
35
|
+
self,
|
|
36
|
+
parse_tool_calls: bool = True,
|
|
37
|
+
json_tool_patterns: Optional[List[str]] = None,
|
|
38
|
+
json_tool_parser: Optional["JsonToolParsingStrategy"] = None,
|
|
39
|
+
strategy_order: Optional[List[str]] = None,
|
|
40
|
+
segment_id_prefix: Optional[str] = None,
|
|
41
|
+
):
|
|
42
|
+
self.parse_tool_calls = parse_tool_calls
|
|
43
|
+
self.json_tool_patterns = json_tool_patterns or self.DEFAULT_JSON_PATTERNS.copy()
|
|
44
|
+
self.json_tool_parser = json_tool_parser
|
|
45
|
+
self.strategy_order = strategy_order or ["xml_tag"]
|
|
46
|
+
self.segment_id_prefix = segment_id_prefix
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class ParserContext:
|
|
50
|
+
"""
|
|
51
|
+
Holds the shared state for the streaming parser state machine.
|
|
52
|
+
|
|
53
|
+
This context provides:
|
|
54
|
+
- Scanner for reading the character stream
|
|
55
|
+
- EventEmitter for segment events
|
|
56
|
+
- State management for transitions
|
|
57
|
+
- Configuration access
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
def __init__(self, config: Optional[ParserConfig] = None):
|
|
61
|
+
"""
|
|
62
|
+
Initialize the parser context.
|
|
63
|
+
|
|
64
|
+
Args:
|
|
65
|
+
config: Parser configuration. Uses defaults if not provided.
|
|
66
|
+
"""
|
|
67
|
+
self._config = config or ParserConfig()
|
|
68
|
+
self._scanner = StreamScanner()
|
|
69
|
+
self._emitter = EventEmitter(segment_id_prefix=self._config.segment_id_prefix)
|
|
70
|
+
self._current_state: Optional["BaseState"] = None
|
|
71
|
+
from .strategies.registry import create_detection_strategies
|
|
72
|
+
self._strategies = create_detection_strategies(self._config.strategy_order)
|
|
73
|
+
|
|
74
|
+
@property
|
|
75
|
+
def config(self) -> ParserConfig:
|
|
76
|
+
"""Get the parser configuration."""
|
|
77
|
+
return self._config
|
|
78
|
+
|
|
79
|
+
@property
|
|
80
|
+
def parse_tool_calls(self) -> bool:
|
|
81
|
+
"""Whether to parse tool calls."""
|
|
82
|
+
return self._config.parse_tool_calls
|
|
83
|
+
|
|
84
|
+
@property
|
|
85
|
+
def json_tool_patterns(self) -> List[str]:
|
|
86
|
+
"""Get the JSON tool call patterns."""
|
|
87
|
+
return self._config.json_tool_patterns
|
|
88
|
+
|
|
89
|
+
@property
|
|
90
|
+
def json_tool_parser(self) -> Optional["JsonToolParsingStrategy"]:
|
|
91
|
+
"""Get the JSON tool parser strategy if configured."""
|
|
92
|
+
return self._config.json_tool_parser
|
|
93
|
+
|
|
94
|
+
@property
|
|
95
|
+
def detection_strategies(self):
|
|
96
|
+
"""Get the ordered detection strategies."""
|
|
97
|
+
return self._strategies
|
|
98
|
+
|
|
99
|
+
# --- State Management ---
|
|
100
|
+
|
|
101
|
+
@property
|
|
102
|
+
def current_state(self) -> "BaseState":
|
|
103
|
+
"""Get the current state."""
|
|
104
|
+
if self._current_state is None:
|
|
105
|
+
raise RuntimeError("No current state is set.")
|
|
106
|
+
return self._current_state
|
|
107
|
+
|
|
108
|
+
@current_state.setter
|
|
109
|
+
def current_state(self, state: "BaseState") -> None:
|
|
110
|
+
"""Set the current state."""
|
|
111
|
+
self._current_state = state
|
|
112
|
+
|
|
113
|
+
def transition_to(self, new_state: "BaseState") -> None:
|
|
114
|
+
"""Transition to a new state."""
|
|
115
|
+
self._current_state = new_state
|
|
116
|
+
|
|
117
|
+
# --- Scanner Delegation ---
|
|
118
|
+
|
|
119
|
+
def append(self, text: str) -> None:
|
|
120
|
+
"""Append text to the scanner buffer."""
|
|
121
|
+
self._scanner.append(text)
|
|
122
|
+
|
|
123
|
+
def peek_char(self) -> Optional[str]:
|
|
124
|
+
"""Peek at the current character without advancing."""
|
|
125
|
+
return self._scanner.peek()
|
|
126
|
+
|
|
127
|
+
def advance(self) -> None:
|
|
128
|
+
"""Advance the cursor by one position."""
|
|
129
|
+
self._scanner.advance()
|
|
130
|
+
|
|
131
|
+
def advance_by(self, count: int) -> None:
|
|
132
|
+
"""Advance the cursor by multiple positions."""
|
|
133
|
+
self._scanner.advance_by(count)
|
|
134
|
+
|
|
135
|
+
def has_more_chars(self) -> bool:
|
|
136
|
+
"""Check if there are more characters to read."""
|
|
137
|
+
return self._scanner.has_more_chars()
|
|
138
|
+
|
|
139
|
+
def get_position(self) -> int:
|
|
140
|
+
"""Get the current cursor position."""
|
|
141
|
+
return self._scanner.get_position()
|
|
142
|
+
|
|
143
|
+
def get_buffer_length(self) -> int:
|
|
144
|
+
"""Get the total buffer length."""
|
|
145
|
+
return self._scanner.get_buffer_length()
|
|
146
|
+
|
|
147
|
+
def set_position(self, position: int) -> None:
|
|
148
|
+
"""Set the cursor position."""
|
|
149
|
+
self._scanner.set_position(position)
|
|
150
|
+
|
|
151
|
+
def rewind_by(self, count: int) -> None:
|
|
152
|
+
"""
|
|
153
|
+
Rewind the cursor by a specified number of positions.
|
|
154
|
+
|
|
155
|
+
This is an explicit helper for the common rewind-and-transition pattern.
|
|
156
|
+
|
|
157
|
+
Args:
|
|
158
|
+
count: Number of positions to rewind.
|
|
159
|
+
"""
|
|
160
|
+
new_pos = max(0, self._scanner.get_position() - count)
|
|
161
|
+
self._scanner.set_position(new_pos)
|
|
162
|
+
|
|
163
|
+
def substring(self, start: int, end: Optional[int] = None) -> str:
|
|
164
|
+
"""Extract a substring from the buffer."""
|
|
165
|
+
return self._scanner.substring(start, end)
|
|
166
|
+
|
|
167
|
+
def find(self, sub: str, start: Optional[int] = None) -> int:
|
|
168
|
+
"""Find a substring in the buffer."""
|
|
169
|
+
return self._scanner.find(sub, start)
|
|
170
|
+
|
|
171
|
+
def consume(self, count: int) -> str:
|
|
172
|
+
"""Consume a number of characters from the buffer."""
|
|
173
|
+
return self._scanner.consume(count)
|
|
174
|
+
|
|
175
|
+
def consume_remaining(self) -> str:
|
|
176
|
+
"""Consume all remaining characters from the buffer."""
|
|
177
|
+
return self._scanner.consume_remaining()
|
|
178
|
+
|
|
179
|
+
def compact(self, min_prefix: int = 65536) -> None:
|
|
180
|
+
"""Compact the scanner buffer."""
|
|
181
|
+
self._scanner.compact(min_prefix=min_prefix)
|
|
182
|
+
|
|
183
|
+
# --- Event Emission (Delegated to EventEmitter) ---
|
|
184
|
+
|
|
185
|
+
def emit_segment_start(self, segment_type: SegmentType, **metadata) -> str:
|
|
186
|
+
"""Emit a SEGMENT_START event."""
|
|
187
|
+
return self._emitter.emit_segment_start(segment_type, **metadata)
|
|
188
|
+
|
|
189
|
+
def emit_segment_content(self, delta: Any) -> None:
|
|
190
|
+
"""Emit a SEGMENT_CONTENT event."""
|
|
191
|
+
self._emitter.emit_segment_content(delta)
|
|
192
|
+
|
|
193
|
+
def emit_segment_end(self) -> Optional[str]:
|
|
194
|
+
"""Emit a SEGMENT_END event."""
|
|
195
|
+
return self._emitter.emit_segment_end()
|
|
196
|
+
|
|
197
|
+
def get_current_segment_id(self) -> Optional[str]:
|
|
198
|
+
"""Get the ID of the currently active segment."""
|
|
199
|
+
return self._emitter.get_current_segment_id()
|
|
200
|
+
|
|
201
|
+
def get_current_segment_type(self) -> Optional[SegmentType]:
|
|
202
|
+
"""Get the type of the currently active segment."""
|
|
203
|
+
return self._emitter.get_current_segment_type()
|
|
204
|
+
|
|
205
|
+
def get_current_segment_content(self) -> str:
|
|
206
|
+
"""Get the accumulated content of the current segment."""
|
|
207
|
+
return self._emitter.get_current_segment_content()
|
|
208
|
+
|
|
209
|
+
def get_current_segment_metadata(self) -> Dict[str, Any]:
|
|
210
|
+
"""Get the metadata of the current segment."""
|
|
211
|
+
return self._emitter.get_current_segment_metadata()
|
|
212
|
+
|
|
213
|
+
def update_current_segment_metadata(self, **metadata) -> None:
|
|
214
|
+
"""Update metadata for the current segment."""
|
|
215
|
+
self._emitter.update_current_segment_metadata(**metadata)
|
|
216
|
+
|
|
217
|
+
def get_and_clear_events(self) -> List[SegmentEvent]:
|
|
218
|
+
"""Get all queued events and clear the queue."""
|
|
219
|
+
return self._emitter.get_and_clear_events()
|
|
220
|
+
|
|
221
|
+
def get_events(self) -> List[SegmentEvent]:
|
|
222
|
+
"""Get all queued events without clearing."""
|
|
223
|
+
return self._emitter.get_events()
|
|
224
|
+
|
|
225
|
+
def append_text_segment(self, text: str) -> None:
|
|
226
|
+
"""Append text content to the current text segment, starting one if needed."""
|
|
227
|
+
self._emitter.append_text_segment(text)
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Parser factory and strategy selection for streaming parsers.
|
|
3
|
+
|
|
4
|
+
Selects a parser implementation based on configuration or environment.
|
|
5
|
+
"""
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
import os
|
|
9
|
+
from typing import Callable, Dict, List, Optional, Protocol, TYPE_CHECKING
|
|
10
|
+
|
|
11
|
+
from .events import SegmentEvent
|
|
12
|
+
from .parser_context import ParserConfig
|
|
13
|
+
from .streaming_parser import StreamingParser
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class StreamingParserProtocol(Protocol):
|
|
17
|
+
"""Protocol for streaming parsers used by the response handler."""
|
|
18
|
+
|
|
19
|
+
@property
|
|
20
|
+
def config(self) -> ParserConfig:
|
|
21
|
+
...
|
|
22
|
+
|
|
23
|
+
def feed(self, chunk: str) -> List[SegmentEvent]:
|
|
24
|
+
...
|
|
25
|
+
|
|
26
|
+
def finalize(self) -> List[SegmentEvent]:
|
|
27
|
+
...
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
ENV_PARSER_NAME = "AUTOBYTEUS_STREAM_PARSER"
|
|
31
|
+
DEFAULT_PARSER_NAME = "xml"
|
|
32
|
+
|
|
33
|
+
if TYPE_CHECKING:
|
|
34
|
+
from .json_parsing_strategies.base import JsonToolParsingStrategy
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def _clone_config(
|
|
38
|
+
config: Optional[ParserConfig],
|
|
39
|
+
*,
|
|
40
|
+
parse_tool_calls: Optional[bool] = None,
|
|
41
|
+
json_tool_patterns: Optional[List[str]] = None,
|
|
42
|
+
json_tool_parser: Optional["JsonToolParsingStrategy"] = None,
|
|
43
|
+
strategy_order: Optional[List[str]] = None,
|
|
44
|
+
segment_id_prefix: Optional[str] = None,
|
|
45
|
+
) -> ParserConfig:
|
|
46
|
+
base = config or ParserConfig()
|
|
47
|
+
return ParserConfig(
|
|
48
|
+
parse_tool_calls=base.parse_tool_calls if parse_tool_calls is None else parse_tool_calls,
|
|
49
|
+
json_tool_patterns=(
|
|
50
|
+
base.json_tool_patterns.copy()
|
|
51
|
+
if json_tool_patterns is None
|
|
52
|
+
else json_tool_patterns
|
|
53
|
+
),
|
|
54
|
+
json_tool_parser=(
|
|
55
|
+
base.json_tool_parser
|
|
56
|
+
if json_tool_parser is None
|
|
57
|
+
else json_tool_parser
|
|
58
|
+
),
|
|
59
|
+
strategy_order=(
|
|
60
|
+
base.strategy_order.copy()
|
|
61
|
+
if strategy_order is None
|
|
62
|
+
else strategy_order
|
|
63
|
+
),
|
|
64
|
+
segment_id_prefix=(
|
|
65
|
+
base.segment_id_prefix
|
|
66
|
+
if segment_id_prefix is None
|
|
67
|
+
else segment_id_prefix
|
|
68
|
+
),
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def _build_xml(config: Optional[ParserConfig]) -> StreamingParserProtocol:
|
|
73
|
+
xml_config = _clone_config(
|
|
74
|
+
config,
|
|
75
|
+
parse_tool_calls=True,
|
|
76
|
+
strategy_order=["xml_tag"],
|
|
77
|
+
)
|
|
78
|
+
return StreamingParser(config=xml_config)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def _build_json(config: Optional[ParserConfig]) -> StreamingParserProtocol:
|
|
82
|
+
json_config = _clone_config(
|
|
83
|
+
config,
|
|
84
|
+
parse_tool_calls=True,
|
|
85
|
+
strategy_order=["json_tool"],
|
|
86
|
+
)
|
|
87
|
+
return StreamingParser(config=json_config)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def _build_api_tool_call(config: Optional[ParserConfig]) -> StreamingParserProtocol:
|
|
91
|
+
# API tool calls handled elsewhere; keep tag parsing but disable tool parsing.
|
|
92
|
+
api_tool_call_config = _clone_config(config, parse_tool_calls=False)
|
|
93
|
+
return StreamingParser(config=api_tool_call_config)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def _build_sentinel(config: Optional[ParserConfig]) -> StreamingParserProtocol:
|
|
97
|
+
sentinel_config = _clone_config(
|
|
98
|
+
config,
|
|
99
|
+
strategy_order=["sentinel"],
|
|
100
|
+
parse_tool_calls=True,
|
|
101
|
+
)
|
|
102
|
+
return StreamingParser(config=sentinel_config)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
PARSER_REGISTRY: Dict[str, Callable[[Optional[ParserConfig]], StreamingParserProtocol]] = {
|
|
106
|
+
"xml": _build_xml,
|
|
107
|
+
"json": _build_json,
|
|
108
|
+
"api_tool_call": _build_api_tool_call,
|
|
109
|
+
"sentinel": _build_sentinel,
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def resolve_parser_name(explicit_name: Optional[str] = None) -> str:
|
|
114
|
+
"""Resolve parser name from explicit value or environment."""
|
|
115
|
+
name = explicit_name or os.getenv(ENV_PARSER_NAME, DEFAULT_PARSER_NAME)
|
|
116
|
+
return name.strip().lower()
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def create_streaming_parser(
|
|
120
|
+
config: Optional[ParserConfig] = None,
|
|
121
|
+
*,
|
|
122
|
+
parser_name: Optional[str] = None,
|
|
123
|
+
) -> StreamingParserProtocol:
|
|
124
|
+
"""Create a streaming parser based on configuration or environment."""
|
|
125
|
+
name = resolve_parser_name(parser_name)
|
|
126
|
+
builder = PARSER_REGISTRY.get(name)
|
|
127
|
+
if builder is None:
|
|
128
|
+
raise ValueError(
|
|
129
|
+
f"Unknown parser strategy '{name}'. "
|
|
130
|
+
f"Supported: {', '.join(sorted(PARSER_REGISTRY))}."
|
|
131
|
+
)
|
|
132
|
+
return builder(config)
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"""
|
|
2
|
+
StateFactory: Factory for creating parser states.
|
|
3
|
+
|
|
4
|
+
This pattern helps avoid circular imports between states by providing
|
|
5
|
+
a central location for state instantiation.
|
|
6
|
+
"""
|
|
7
|
+
from typing import TYPE_CHECKING
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from .parser_context import ParserContext
|
|
11
|
+
from .states.base_state import BaseState
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class StateFactory:
|
|
15
|
+
"""
|
|
16
|
+
Factory for creating parser state instances.
|
|
17
|
+
|
|
18
|
+
This avoids circular imports between state classes by providing
|
|
19
|
+
lazy imports at the point of creation.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
@staticmethod
|
|
23
|
+
def text_state(context: "ParserContext") -> "BaseState":
|
|
24
|
+
"""Create a TextState instance."""
|
|
25
|
+
from .states.text_state import TextState
|
|
26
|
+
return TextState(context)
|
|
27
|
+
|
|
28
|
+
@staticmethod
|
|
29
|
+
def xml_tag_init_state(context: "ParserContext") -> "BaseState":
|
|
30
|
+
"""Create an XmlTagInitializationState instance."""
|
|
31
|
+
from .states.xml_tag_initialization_state import XmlTagInitializationState
|
|
32
|
+
return XmlTagInitializationState(context)
|
|
33
|
+
|
|
34
|
+
@staticmethod
|
|
35
|
+
def write_file_parsing_state(context: "ParserContext", opening_tag: str) -> "BaseState":
|
|
36
|
+
"""Create a CustomXmlTagWriteFileParsingState instance."""
|
|
37
|
+
from .states.custom_xml_tag_write_file_parsing_state import CustomXmlTagWriteFileParsingState
|
|
38
|
+
return CustomXmlTagWriteFileParsingState(context, opening_tag)
|
|
39
|
+
|
|
40
|
+
@staticmethod
|
|
41
|
+
def run_bash_parsing_state(context: "ParserContext", opening_tag: str) -> "BaseState":
|
|
42
|
+
"""Create a CustomXmlTagRunBashParsingState instance."""
|
|
43
|
+
from .states.custom_xml_tag_run_bash_parsing_state import CustomXmlTagRunBashParsingState
|
|
44
|
+
return CustomXmlTagRunBashParsingState(context, opening_tag)
|
|
45
|
+
|
|
46
|
+
@staticmethod
|
|
47
|
+
def xml_tool_parsing_state(context: "ParserContext", signature_buffer: str) -> "BaseState":
|
|
48
|
+
"""Create a XmlToolParsingState instance."""
|
|
49
|
+
from .states.xml_tool_parsing_state import XmlToolParsingState
|
|
50
|
+
return XmlToolParsingState(context, signature_buffer)
|
|
51
|
+
|
|
52
|
+
@staticmethod
|
|
53
|
+
def json_init_state(context: "ParserContext") -> "BaseState":
|
|
54
|
+
"""Create a JsonInitializationState instance."""
|
|
55
|
+
from .states.json_initialization_state import JsonInitializationState
|
|
56
|
+
return JsonInitializationState(context)
|
|
57
|
+
|
|
58
|
+
@staticmethod
|
|
59
|
+
def json_tool_parsing_state(context: "ParserContext", signature_buffer: str) -> "BaseState":
|
|
60
|
+
"""Create a JsonToolParsingState instance."""
|
|
61
|
+
from .states.json_tool_parsing_state import JsonToolParsingState
|
|
62
|
+
return JsonToolParsingState(context, signature_buffer)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# States subpackage
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"""
|
|
2
|
+
BaseState: Abstract base class for parser state machine states.
|
|
3
|
+
|
|
4
|
+
All states in the streaming parser inherit from this class and implement
|
|
5
|
+
the run() and finalize() methods.
|
|
6
|
+
"""
|
|
7
|
+
from abc import ABC, abstractmethod
|
|
8
|
+
from typing import TYPE_CHECKING
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from ..parser_context import ParserContext
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class BaseState(ABC):
|
|
15
|
+
"""
|
|
16
|
+
Abstract base class for all parser states.
|
|
17
|
+
|
|
18
|
+
Each state is responsible for:
|
|
19
|
+
1. Processing characters from the context's scanner
|
|
20
|
+
2. Emitting appropriate SegmentEvents
|
|
21
|
+
3. Transitioning to other states when triggers are detected
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
def __init__(self, context: "ParserContext"):
|
|
25
|
+
"""
|
|
26
|
+
Initialize the state with a reference to the parser context.
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
context: The shared parser context.
|
|
30
|
+
"""
|
|
31
|
+
self._context = context
|
|
32
|
+
|
|
33
|
+
@property
|
|
34
|
+
def context(self) -> "ParserContext":
|
|
35
|
+
"""Get the parser context."""
|
|
36
|
+
return self._context
|
|
37
|
+
|
|
38
|
+
@abstractmethod
|
|
39
|
+
def run(self) -> None:
|
|
40
|
+
"""
|
|
41
|
+
Main processing loop for this state.
|
|
42
|
+
|
|
43
|
+
This method should:
|
|
44
|
+
- Read characters from context.peek_char()
|
|
45
|
+
- Emit events via context.emit_segment_*()
|
|
46
|
+
- Transition to other states via context.transition_to()
|
|
47
|
+
- Return when no more characters or when transitioning
|
|
48
|
+
"""
|
|
49
|
+
pass
|
|
50
|
+
|
|
51
|
+
def finalize(self) -> None:
|
|
52
|
+
"""
|
|
53
|
+
Called when the stream ends while in this state.
|
|
54
|
+
|
|
55
|
+
This method should clean up any pending buffers and ensure
|
|
56
|
+
all accumulated content is properly emitted as events.
|
|
57
|
+
|
|
58
|
+
Default implementation does nothing. Override if needed.
|
|
59
|
+
"""
|
|
60
|
+
pass
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"""
|
|
2
|
+
RunBashParsingState: Parses <run_bash>...</run_bash> blocks.
|
|
3
|
+
|
|
4
|
+
Simplified implementation that parses terminal commands.
|
|
5
|
+
"""
|
|
6
|
+
from typing import TYPE_CHECKING
|
|
7
|
+
|
|
8
|
+
from .delimited_content_state import DelimitedContentState
|
|
9
|
+
from ..events import SegmentType
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from ..parser_context import ParserContext
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class CustomXmlTagRunBashParsingState(DelimitedContentState):
|
|
16
|
+
"""
|
|
17
|
+
Parses terminal command blocks.
|
|
18
|
+
|
|
19
|
+
Supported format: <run_bash>command</run_bash>
|
|
20
|
+
|
|
21
|
+
The state:
|
|
22
|
+
1. Emits SEGMENT_START (no metadata)
|
|
23
|
+
2. Streams command content as SEGMENT_CONTENT events
|
|
24
|
+
3. Emits SEGMENT_END when </run_bash> is found
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
CLOSING_TAG = "</run_bash>"
|
|
28
|
+
SEGMENT_TYPE = SegmentType.RUN_BASH
|
|
29
|
+
|
|
30
|
+
def __init__(self, context: "ParserContext", opening_tag: str):
|
|
31
|
+
"""
|
|
32
|
+
Initialize the run_bash parsing state.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
context: The parser context.
|
|
36
|
+
opening_tag: The opening tag (e.g., '<run_bash>').
|
|
37
|
+
"""
|
|
38
|
+
super().__init__(context, opening_tag)
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"""
|
|
2
|
+
WriteFileParsingState: Parses <write_file path="...">...</write_file> blocks.
|
|
3
|
+
|
|
4
|
+
This state handles the extraction of file path from the tag attributes
|
|
5
|
+
and streams the file content until the closing </write_file> tag is found.
|
|
6
|
+
"""
|
|
7
|
+
import re
|
|
8
|
+
from typing import TYPE_CHECKING, Optional
|
|
9
|
+
|
|
10
|
+
from .delimited_content_state import DelimitedContentState
|
|
11
|
+
from ..events import SegmentType
|
|
12
|
+
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
from ..parser_context import ParserContext
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class CustomXmlTagWriteFileParsingState(DelimitedContentState):
|
|
18
|
+
"""
|
|
19
|
+
Parses write_file content blocks.
|
|
20
|
+
|
|
21
|
+
Expected format: <write_file path="...">content</write_file>
|
|
22
|
+
|
|
23
|
+
The state:
|
|
24
|
+
1. Extracts the path attribute from the opening tag
|
|
25
|
+
2. Emits SEGMENT_START with path metadata
|
|
26
|
+
3. Streams content characters as SEGMENT_CONTENT events
|
|
27
|
+
4. Emits SEGMENT_END when </write_file> is found
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
# Pattern to extract path from <write_file path="..."> or <write_file path='...'>
|
|
31
|
+
PATH_PATTERN = re.compile(r'path\s*=\s*["\']([^"\']+)["\']', re.IGNORECASE)
|
|
32
|
+
CLOSING_TAG = "</write_file>"
|
|
33
|
+
SEGMENT_TYPE = SegmentType.WRITE_FILE
|
|
34
|
+
|
|
35
|
+
def __init__(self, context: "ParserContext", opening_tag: str):
|
|
36
|
+
"""
|
|
37
|
+
Initialize the write_file parsing state.
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
context: The parser context.
|
|
41
|
+
opening_tag: The complete opening tag (e.g., '<write_file path="/a.py">').
|
|
42
|
+
"""
|
|
43
|
+
super().__init__(context, opening_tag)
|
|
44
|
+
self._file_path: Optional[str] = None
|
|
45
|
+
|
|
46
|
+
# Extract file path from opening tag
|
|
47
|
+
match = self.PATH_PATTERN.search(opening_tag)
|
|
48
|
+
if match:
|
|
49
|
+
self._file_path = match.group(1)
|
|
50
|
+
|
|
51
|
+
def _can_start_segment(self) -> bool:
|
|
52
|
+
return self._file_path is not None
|
|
53
|
+
|
|
54
|
+
def _get_start_metadata(self) -> dict:
|
|
55
|
+
return {"path": self._file_path} if self._file_path else {}
|