autobyteus 1.1.3__py3-none-any.whl → 1.1.5__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 +1 -1
- autobyteus/agent/bootstrap_steps/system_prompt_processing_step.py +4 -2
- autobyteus/agent/context/__init__.py +4 -2
- autobyteus/agent/context/agent_config.py +35 -8
- autobyteus/agent/context/agent_context_registry.py +73 -0
- autobyteus/agent/events/notifiers.py +4 -0
- autobyteus/agent/events/worker_event_dispatcher.py +1 -2
- autobyteus/agent/handlers/inter_agent_message_event_handler.py +8 -3
- autobyteus/agent/handlers/llm_complete_response_received_event_handler.py +19 -19
- autobyteus/agent/handlers/llm_user_message_ready_event_handler.py +2 -2
- autobyteus/agent/handlers/tool_result_event_handler.py +48 -20
- autobyteus/agent/handlers/user_input_message_event_handler.py +16 -1
- autobyteus/agent/input_processor/__init__.py +1 -7
- autobyteus/agent/message/context_file_type.py +6 -0
- autobyteus/agent/message/send_message_to.py +74 -99
- autobyteus/agent/phases/discover.py +2 -1
- autobyteus/agent/runtime/agent_runtime.py +10 -2
- autobyteus/agent/runtime/agent_worker.py +1 -0
- autobyteus/agent/sender_type.py +15 -0
- autobyteus/agent/streaming/agent_event_stream.py +6 -0
- autobyteus/agent/streaming/stream_event_payloads.py +12 -0
- autobyteus/agent/streaming/stream_events.py +3 -0
- autobyteus/agent/system_prompt_processor/tool_manifest_injector_processor.py +7 -4
- autobyteus/agent/tool_execution_result_processor/__init__.py +9 -0
- autobyteus/agent/tool_execution_result_processor/base_processor.py +46 -0
- autobyteus/agent/tool_execution_result_processor/processor_definition.py +36 -0
- autobyteus/agent/tool_execution_result_processor/processor_meta.py +36 -0
- autobyteus/agent/tool_execution_result_processor/processor_registry.py +70 -0
- autobyteus/agent/workspace/base_workspace.py +17 -2
- autobyteus/agent_team/__init__.py +1 -0
- autobyteus/agent_team/agent_team.py +93 -0
- autobyteus/agent_team/agent_team_builder.py +184 -0
- autobyteus/agent_team/base_agent_team.py +86 -0
- autobyteus/agent_team/bootstrap_steps/__init__.py +24 -0
- autobyteus/agent_team/bootstrap_steps/agent_configuration_preparation_step.py +73 -0
- autobyteus/agent_team/bootstrap_steps/agent_team_bootstrapper.py +54 -0
- autobyteus/agent_team/bootstrap_steps/agent_team_runtime_queue_initialization_step.py +25 -0
- autobyteus/agent_team/bootstrap_steps/base_agent_team_bootstrap_step.py +23 -0
- autobyteus/agent_team/bootstrap_steps/coordinator_initialization_step.py +41 -0
- autobyteus/agent_team/bootstrap_steps/coordinator_prompt_preparation_step.py +85 -0
- autobyteus/agent_team/bootstrap_steps/task_notifier_initialization_step.py +51 -0
- autobyteus/agent_team/bootstrap_steps/team_context_initialization_step.py +45 -0
- autobyteus/agent_team/context/__init__.py +17 -0
- autobyteus/agent_team/context/agent_team_config.py +33 -0
- autobyteus/agent_team/context/agent_team_context.py +61 -0
- autobyteus/agent_team/context/agent_team_runtime_state.py +56 -0
- autobyteus/agent_team/context/team_manager.py +147 -0
- autobyteus/agent_team/context/team_node_config.py +76 -0
- autobyteus/agent_team/events/__init__.py +29 -0
- autobyteus/agent_team/events/agent_team_event_dispatcher.py +39 -0
- autobyteus/agent_team/events/agent_team_events.py +53 -0
- autobyteus/agent_team/events/agent_team_input_event_queue_manager.py +21 -0
- autobyteus/agent_team/exceptions.py +8 -0
- autobyteus/agent_team/factory/__init__.py +9 -0
- autobyteus/agent_team/factory/agent_team_factory.py +99 -0
- autobyteus/agent_team/handlers/__init__.py +19 -0
- autobyteus/agent_team/handlers/agent_team_event_handler_registry.py +23 -0
- autobyteus/agent_team/handlers/base_agent_team_event_handler.py +16 -0
- autobyteus/agent_team/handlers/inter_agent_message_request_event_handler.py +61 -0
- autobyteus/agent_team/handlers/lifecycle_agent_team_event_handler.py +27 -0
- autobyteus/agent_team/handlers/process_user_message_event_handler.py +46 -0
- autobyteus/agent_team/handlers/tool_approval_team_event_handler.py +48 -0
- autobyteus/agent_team/phases/__init__.py +11 -0
- autobyteus/agent_team/phases/agent_team_operational_phase.py +19 -0
- autobyteus/agent_team/phases/agent_team_phase_manager.py +48 -0
- autobyteus/agent_team/runtime/__init__.py +13 -0
- autobyteus/agent_team/runtime/agent_team_runtime.py +82 -0
- autobyteus/agent_team/runtime/agent_team_worker.py +117 -0
- autobyteus/agent_team/shutdown_steps/__init__.py +17 -0
- autobyteus/agent_team/shutdown_steps/agent_team_shutdown_orchestrator.py +35 -0
- autobyteus/agent_team/shutdown_steps/agent_team_shutdown_step.py +42 -0
- autobyteus/agent_team/shutdown_steps/base_agent_team_shutdown_step.py +16 -0
- autobyteus/agent_team/shutdown_steps/bridge_cleanup_step.py +28 -0
- autobyteus/agent_team/shutdown_steps/sub_team_shutdown_step.py +41 -0
- autobyteus/agent_team/streaming/__init__.py +26 -0
- autobyteus/agent_team/streaming/agent_event_bridge.py +48 -0
- autobyteus/agent_team/streaming/agent_event_multiplexer.py +70 -0
- autobyteus/agent_team/streaming/agent_team_event_notifier.py +64 -0
- autobyteus/agent_team/streaming/agent_team_event_stream.py +33 -0
- autobyteus/agent_team/streaming/agent_team_stream_event_payloads.py +32 -0
- autobyteus/agent_team/streaming/agent_team_stream_events.py +56 -0
- autobyteus/agent_team/streaming/team_event_bridge.py +50 -0
- autobyteus/agent_team/task_notification/__init__.py +11 -0
- autobyteus/agent_team/task_notification/system_event_driven_agent_task_notifier.py +164 -0
- autobyteus/agent_team/task_notification/task_notification_mode.py +24 -0
- autobyteus/agent_team/utils/__init__.py +9 -0
- autobyteus/agent_team/utils/wait_for_idle.py +46 -0
- autobyteus/cli/__init__.py +1 -1
- autobyteus/cli/agent_team_tui/__init__.py +4 -0
- autobyteus/cli/agent_team_tui/app.py +210 -0
- autobyteus/cli/agent_team_tui/state.py +180 -0
- autobyteus/cli/agent_team_tui/widgets/__init__.py +6 -0
- autobyteus/cli/agent_team_tui/widgets/agent_list_sidebar.py +149 -0
- autobyteus/cli/agent_team_tui/widgets/focus_pane.py +320 -0
- autobyteus/cli/agent_team_tui/widgets/logo.py +20 -0
- autobyteus/cli/agent_team_tui/widgets/renderables.py +77 -0
- autobyteus/cli/agent_team_tui/widgets/shared.py +60 -0
- autobyteus/cli/agent_team_tui/widgets/status_bar.py +14 -0
- autobyteus/cli/agent_team_tui/widgets/task_board_panel.py +82 -0
- autobyteus/cli/cli_display.py +1 -1
- autobyteus/cli/workflow_tui/__init__.py +4 -0
- autobyteus/cli/workflow_tui/app.py +210 -0
- autobyteus/cli/workflow_tui/state.py +189 -0
- autobyteus/cli/workflow_tui/widgets/__init__.py +6 -0
- autobyteus/cli/workflow_tui/widgets/agent_list_sidebar.py +149 -0
- autobyteus/cli/workflow_tui/widgets/focus_pane.py +335 -0
- autobyteus/cli/workflow_tui/widgets/logo.py +27 -0
- autobyteus/cli/workflow_tui/widgets/renderables.py +70 -0
- autobyteus/cli/workflow_tui/widgets/shared.py +51 -0
- autobyteus/cli/workflow_tui/widgets/status_bar.py +14 -0
- autobyteus/events/event_types.py +8 -0
- autobyteus/llm/api/autobyteus_llm.py +11 -12
- autobyteus/llm/api/lmstudio_llm.py +34 -0
- autobyteus/llm/api/ollama_llm.py +8 -13
- autobyteus/llm/api/openai_compatible_llm.py +20 -3
- autobyteus/llm/autobyteus_provider.py +73 -46
- autobyteus/llm/llm_factory.py +103 -139
- autobyteus/llm/lmstudio_provider.py +104 -0
- autobyteus/llm/models.py +83 -53
- autobyteus/llm/ollama_provider.py +69 -61
- autobyteus/llm/ollama_provider_resolver.py +1 -0
- autobyteus/llm/providers.py +13 -12
- autobyteus/llm/runtimes.py +11 -0
- autobyteus/llm/token_counter/token_counter_factory.py +2 -0
- autobyteus/task_management/__init__.py +43 -0
- autobyteus/task_management/base_task_board.py +68 -0
- autobyteus/task_management/converters/__init__.py +11 -0
- autobyteus/task_management/converters/task_board_converter.py +64 -0
- autobyteus/task_management/converters/task_plan_converter.py +48 -0
- autobyteus/task_management/deliverable.py +16 -0
- autobyteus/task_management/deliverables/__init__.py +8 -0
- autobyteus/task_management/deliverables/file_deliverable.py +15 -0
- autobyteus/task_management/events.py +27 -0
- autobyteus/task_management/in_memory_task_board.py +126 -0
- autobyteus/task_management/schemas/__init__.py +15 -0
- autobyteus/task_management/schemas/deliverable_schema.py +13 -0
- autobyteus/task_management/schemas/plan_definition.py +35 -0
- autobyteus/task_management/schemas/task_status_report.py +27 -0
- autobyteus/task_management/task_plan.py +110 -0
- autobyteus/task_management/tools/__init__.py +14 -0
- autobyteus/task_management/tools/get_task_board_status.py +68 -0
- autobyteus/task_management/tools/publish_task_plan.py +113 -0
- autobyteus/task_management/tools/update_task_status.py +135 -0
- autobyteus/tools/__init__.py +2 -0
- autobyteus/tools/ask_user_input.py +2 -1
- autobyteus/tools/bash/bash_executor.py +61 -15
- autobyteus/tools/browser/session_aware/browser_session_aware_navigate_to.py +2 -0
- autobyteus/tools/browser/session_aware/browser_session_aware_web_element_trigger.py +3 -0
- autobyteus/tools/browser/session_aware/browser_session_aware_webpage_reader.py +3 -0
- autobyteus/tools/browser/session_aware/browser_session_aware_webpage_screenshot_taker.py +3 -0
- autobyteus/tools/browser/standalone/google_search_ui.py +2 -0
- autobyteus/tools/browser/standalone/navigate_to.py +2 -0
- autobyteus/tools/browser/standalone/web_page_pdf_generator.py +3 -0
- autobyteus/tools/browser/standalone/webpage_image_downloader.py +3 -0
- autobyteus/tools/browser/standalone/webpage_reader.py +2 -0
- autobyteus/tools/browser/standalone/webpage_screenshot_taker.py +3 -0
- autobyteus/tools/file/file_reader.py +36 -9
- autobyteus/tools/file/file_writer.py +37 -9
- autobyteus/tools/functional_tool.py +5 -4
- autobyteus/tools/image_downloader.py +2 -0
- autobyteus/tools/mcp/config_service.py +63 -58
- autobyteus/tools/mcp/server/http_managed_mcp_server.py +14 -2
- autobyteus/tools/mcp/server/stdio_managed_mcp_server.py +14 -2
- autobyteus/tools/mcp/server_instance_manager.py +30 -4
- autobyteus/tools/mcp/tool_registrar.py +106 -51
- autobyteus/tools/parameter_schema.py +17 -11
- autobyteus/tools/pdf_downloader.py +2 -1
- autobyteus/tools/registry/tool_definition.py +36 -37
- autobyteus/tools/registry/tool_registry.py +50 -2
- autobyteus/tools/timer.py +2 -0
- autobyteus/tools/tool_category.py +15 -4
- autobyteus/tools/tool_meta.py +6 -1
- autobyteus/tools/tool_origin.py +10 -0
- autobyteus/tools/usage/formatters/default_json_example_formatter.py +78 -3
- autobyteus/tools/usage/formatters/default_xml_example_formatter.py +23 -3
- autobyteus/tools/usage/formatters/gemini_json_example_formatter.py +6 -0
- autobyteus/tools/usage/formatters/google_json_example_formatter.py +7 -0
- autobyteus/tools/usage/formatters/openai_json_example_formatter.py +6 -4
- autobyteus/tools/usage/parsers/gemini_json_tool_usage_parser.py +23 -7
- autobyteus/tools/usage/parsers/provider_aware_tool_usage_parser.py +14 -25
- autobyteus/tools/usage/providers/__init__.py +2 -12
- autobyteus/tools/usage/providers/tool_manifest_provider.py +36 -29
- autobyteus/tools/usage/registries/__init__.py +7 -12
- autobyteus/tools/usage/registries/tool_formatter_pair.py +15 -0
- autobyteus/tools/usage/registries/tool_formatting_registry.py +58 -0
- autobyteus/tools/usage/registries/tool_usage_parser_registry.py +55 -0
- autobyteus/workflow/agentic_workflow.py +93 -0
- autobyteus/{agent/workflow → workflow}/base_agentic_workflow.py +19 -27
- autobyteus/workflow/bootstrap_steps/__init__.py +20 -0
- autobyteus/workflow/bootstrap_steps/agent_tool_injection_step.py +34 -0
- autobyteus/workflow/bootstrap_steps/base_workflow_bootstrap_step.py +23 -0
- autobyteus/workflow/bootstrap_steps/coordinator_initialization_step.py +41 -0
- autobyteus/workflow/bootstrap_steps/coordinator_prompt_preparation_step.py +108 -0
- autobyteus/workflow/bootstrap_steps/workflow_bootstrapper.py +50 -0
- autobyteus/workflow/bootstrap_steps/workflow_runtime_queue_initialization_step.py +25 -0
- autobyteus/workflow/context/__init__.py +17 -0
- autobyteus/workflow/context/team_manager.py +147 -0
- autobyteus/workflow/context/workflow_config.py +30 -0
- autobyteus/workflow/context/workflow_context.py +61 -0
- autobyteus/workflow/context/workflow_node_config.py +76 -0
- autobyteus/workflow/context/workflow_runtime_state.py +53 -0
- autobyteus/workflow/events/__init__.py +29 -0
- autobyteus/workflow/events/workflow_event_dispatcher.py +39 -0
- autobyteus/workflow/events/workflow_events.py +53 -0
- autobyteus/workflow/events/workflow_input_event_queue_manager.py +21 -0
- autobyteus/workflow/exceptions.py +8 -0
- autobyteus/workflow/factory/__init__.py +9 -0
- autobyteus/workflow/factory/workflow_factory.py +99 -0
- autobyteus/workflow/handlers/__init__.py +19 -0
- autobyteus/workflow/handlers/base_workflow_event_handler.py +16 -0
- autobyteus/workflow/handlers/inter_agent_message_request_event_handler.py +61 -0
- autobyteus/workflow/handlers/lifecycle_workflow_event_handler.py +27 -0
- autobyteus/workflow/handlers/process_user_message_event_handler.py +46 -0
- autobyteus/workflow/handlers/tool_approval_workflow_event_handler.py +39 -0
- autobyteus/workflow/handlers/workflow_event_handler_registry.py +23 -0
- autobyteus/workflow/phases/__init__.py +11 -0
- autobyteus/workflow/phases/workflow_operational_phase.py +19 -0
- autobyteus/workflow/phases/workflow_phase_manager.py +48 -0
- autobyteus/workflow/runtime/__init__.py +13 -0
- autobyteus/workflow/runtime/workflow_runtime.py +82 -0
- autobyteus/workflow/runtime/workflow_worker.py +117 -0
- autobyteus/workflow/shutdown_steps/__init__.py +17 -0
- autobyteus/workflow/shutdown_steps/agent_team_shutdown_step.py +42 -0
- autobyteus/workflow/shutdown_steps/base_workflow_shutdown_step.py +16 -0
- autobyteus/workflow/shutdown_steps/bridge_cleanup_step.py +28 -0
- autobyteus/workflow/shutdown_steps/sub_workflow_shutdown_step.py +41 -0
- autobyteus/workflow/shutdown_steps/workflow_shutdown_orchestrator.py +35 -0
- autobyteus/workflow/streaming/__init__.py +26 -0
- autobyteus/workflow/streaming/agent_event_bridge.py +48 -0
- autobyteus/workflow/streaming/agent_event_multiplexer.py +70 -0
- autobyteus/workflow/streaming/workflow_event_bridge.py +50 -0
- autobyteus/workflow/streaming/workflow_event_notifier.py +83 -0
- autobyteus/workflow/streaming/workflow_event_stream.py +33 -0
- autobyteus/workflow/streaming/workflow_stream_event_payloads.py +28 -0
- autobyteus/workflow/streaming/workflow_stream_events.py +45 -0
- autobyteus/workflow/utils/__init__.py +9 -0
- autobyteus/workflow/utils/wait_for_idle.py +46 -0
- autobyteus/workflow/workflow_builder.py +151 -0
- {autobyteus-1.1.3.dist-info → autobyteus-1.1.5.dist-info}/METADATA +16 -14
- autobyteus-1.1.5.dist-info/RECORD +455 -0
- {autobyteus-1.1.3.dist-info → autobyteus-1.1.5.dist-info}/top_level.txt +1 -0
- examples/__init__.py +1 -0
- examples/agent_team/__init__.py +1 -0
- examples/discover_phase_transitions.py +104 -0
- examples/run_browser_agent.py +262 -0
- examples/run_google_slides_agent.py +287 -0
- examples/run_mcp_browser_client.py +174 -0
- examples/run_mcp_google_slides_client.py +270 -0
- examples/run_mcp_list_tools.py +189 -0
- examples/run_poem_writer.py +284 -0
- examples/run_sqlite_agent.py +295 -0
- autobyteus/agent/context/agent_phase_manager.py +0 -264
- autobyteus/agent/context/phases.py +0 -49
- autobyteus/agent/group/__init__.py +0 -0
- autobyteus/agent/group/agent_group.py +0 -164
- autobyteus/agent/group/agent_group_context.py +0 -81
- autobyteus/agent/input_processor/content_prefixing_input_processor.py +0 -41
- autobyteus/agent/input_processor/metadata_appending_input_processor.py +0 -34
- autobyteus/agent/input_processor/passthrough_input_processor.py +0 -33
- autobyteus/agent/workflow/__init__.py +0 -11
- autobyteus/agent/workflow/agentic_workflow.py +0 -89
- autobyteus/tools/mcp/call_handlers/__init__.py +0 -16
- autobyteus/tools/mcp/call_handlers/base_handler.py +0 -40
- autobyteus/tools/mcp/call_handlers/stdio_handler.py +0 -76
- autobyteus/tools/mcp/call_handlers/streamable_http_handler.py +0 -55
- autobyteus/tools/mcp/registrar.py +0 -202
- autobyteus/tools/usage/providers/json_example_provider.py +0 -32
- autobyteus/tools/usage/providers/json_schema_provider.py +0 -35
- autobyteus/tools/usage/providers/json_tool_usage_parser_provider.py +0 -28
- autobyteus/tools/usage/providers/xml_example_provider.py +0 -28
- autobyteus/tools/usage/providers/xml_schema_provider.py +0 -29
- autobyteus/tools/usage/providers/xml_tool_usage_parser_provider.py +0 -26
- autobyteus/tools/usage/registries/json_example_formatter_registry.py +0 -51
- autobyteus/tools/usage/registries/json_schema_formatter_registry.py +0 -51
- autobyteus/tools/usage/registries/json_tool_usage_parser_registry.py +0 -42
- autobyteus/tools/usage/registries/xml_example_formatter_registry.py +0 -30
- autobyteus/tools/usage/registries/xml_schema_formatter_registry.py +0 -33
- autobyteus/tools/usage/registries/xml_tool_usage_parser_registry.py +0 -30
- autobyteus/workflow/simple_task.py +0 -98
- autobyteus/workflow/task.py +0 -147
- autobyteus/workflow/workflow.py +0 -49
- autobyteus-1.1.3.dist-info/RECORD +0 -312
- {autobyteus-1.1.3.dist-info → autobyteus-1.1.5.dist-info}/WHEEL +0 -0
- {autobyteus-1.1.3.dist-info → autobyteus-1.1.5.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# file: autobyteus/autobyteus/workflow/streaming/workflow_event_stream.py
|
|
2
|
+
import asyncio
|
|
3
|
+
import queue
|
|
4
|
+
from typing import AsyncIterator, TYPE_CHECKING
|
|
5
|
+
|
|
6
|
+
from autobyteus.events.event_types import EventType
|
|
7
|
+
from autobyteus.workflow.streaming.workflow_stream_events import WorkflowStreamEvent
|
|
8
|
+
from autobyteus.agent.streaming.queue_streamer import stream_queue_items
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from autobyteus.workflow.agentic_workflow import AgenticWorkflow
|
|
12
|
+
|
|
13
|
+
_SENTINEL = object()
|
|
14
|
+
|
|
15
|
+
class WorkflowEventStream:
|
|
16
|
+
"""Consumes events from a WorkflowExternalEventNotifier for a specific workflow."""
|
|
17
|
+
def __init__(self, workflow: 'AgenticWorkflow'):
|
|
18
|
+
self.workflow_id = workflow.workflow_id
|
|
19
|
+
self._internal_q = queue.Queue()
|
|
20
|
+
self._notifier = workflow._runtime.notifier
|
|
21
|
+
self._notifier.subscribe(EventType.WORKFLOW_STREAM_EVENT, self._handle_event)
|
|
22
|
+
|
|
23
|
+
def _handle_event(self, payload: WorkflowStreamEvent, **kwargs):
|
|
24
|
+
if isinstance(payload, WorkflowStreamEvent) and payload.workflow_id == self.workflow_id:
|
|
25
|
+
self._internal_q.put(payload)
|
|
26
|
+
|
|
27
|
+
async def close(self):
|
|
28
|
+
self._notifier.unsubscribe(EventType.WORKFLOW_STREAM_EVENT, self._handle_event)
|
|
29
|
+
await asyncio.get_running_loop().run_in_executor(None, self._internal_q.put, _SENTINEL)
|
|
30
|
+
|
|
31
|
+
def all_events(self) -> AsyncIterator[WorkflowStreamEvent]:
|
|
32
|
+
"""The primary method to consume all structured events from the workflow."""
|
|
33
|
+
return stream_queue_items(self._internal_q, _SENTINEL, f"workflow_{self.workflow_id}_stream")
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# file: autobyteus/autobyteus/workflow/streaming/workflow_stream_event_payloads.py
|
|
2
|
+
from typing import Optional, Any
|
|
3
|
+
from pydantic import BaseModel, Field
|
|
4
|
+
from autobyteus.workflow.phases.workflow_operational_phase import WorkflowOperationalPhase
|
|
5
|
+
from autobyteus.agent.streaming.stream_events import StreamEvent as AgentStreamEvent
|
|
6
|
+
# Need to use a forward reference string to avoid circular import at runtime
|
|
7
|
+
from typing import TYPE_CHECKING
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
from autobyteus.workflow.streaming.workflow_stream_events import WorkflowStreamEvent
|
|
10
|
+
|
|
11
|
+
# --- Payloads for events originating from the "WORKFLOW" source ---
|
|
12
|
+
class BaseWorkflowSpecificPayload(BaseModel):
|
|
13
|
+
pass
|
|
14
|
+
|
|
15
|
+
class WorkflowPhaseTransitionData(BaseWorkflowSpecificPayload):
|
|
16
|
+
new_phase: WorkflowOperationalPhase
|
|
17
|
+
old_phase: Optional[WorkflowOperationalPhase] = None
|
|
18
|
+
error_message: Optional[str] = None
|
|
19
|
+
|
|
20
|
+
# --- Payload for events originating from the "AGENT" source ---
|
|
21
|
+
class AgentEventRebroadcastPayload(BaseModel):
|
|
22
|
+
agent_name: str # The friendly name, e.g., "Researcher_1"
|
|
23
|
+
agent_event: AgentStreamEvent # The original, unmodified event from the agent
|
|
24
|
+
|
|
25
|
+
# --- Payload for events originating from the "SUB_WORKFLOW" source ---
|
|
26
|
+
class SubWorkflowEventRebroadcastPayload(BaseModel):
|
|
27
|
+
sub_workflow_node_name: str # The friendly name of the sub-workflow node
|
|
28
|
+
sub_workflow_event: "WorkflowStreamEvent" = Field(..., description="The original, unmodified event from the sub-workflow's stream")
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# file: autobyteus/autobyteus/workflow/streaming/workflow_stream_events.py
|
|
2
|
+
import datetime
|
|
3
|
+
import uuid
|
|
4
|
+
from typing import Literal, Union
|
|
5
|
+
from pydantic import BaseModel, Field, model_validator
|
|
6
|
+
|
|
7
|
+
from .workflow_stream_event_payloads import WorkflowPhaseTransitionData, AgentEventRebroadcastPayload, SubWorkflowEventRebroadcastPayload
|
|
8
|
+
|
|
9
|
+
# A union of all possible payloads for a "WORKFLOW" sourced event.
|
|
10
|
+
WorkflowSpecificPayload = Union[WorkflowPhaseTransitionData]
|
|
11
|
+
|
|
12
|
+
# The top-level discriminated union for the main event stream's payload.
|
|
13
|
+
WorkflowStreamDataPayload = Union[WorkflowSpecificPayload, AgentEventRebroadcastPayload, SubWorkflowEventRebroadcastPayload]
|
|
14
|
+
|
|
15
|
+
class WorkflowStreamEvent(BaseModel):
|
|
16
|
+
event_id: str = Field(default_factory=lambda: str(uuid.uuid4()))
|
|
17
|
+
timestamp: datetime.datetime = Field(default_factory=datetime.datetime.utcnow)
|
|
18
|
+
workflow_id: str
|
|
19
|
+
event_source_type: Literal["WORKFLOW", "AGENT", "SUB_WORKFLOW"]
|
|
20
|
+
data: WorkflowStreamDataPayload
|
|
21
|
+
|
|
22
|
+
@model_validator(mode='after')
|
|
23
|
+
def check_data_matches_source_type(self) -> 'WorkflowStreamEvent':
|
|
24
|
+
is_agent_event = self.event_source_type == "AGENT"
|
|
25
|
+
is_agent_payload = isinstance(self.data, AgentEventRebroadcastPayload)
|
|
26
|
+
|
|
27
|
+
is_sub_workflow_event = self.event_source_type == "SUB_WORKFLOW"
|
|
28
|
+
is_sub_workflow_payload = isinstance(self.data, SubWorkflowEventRebroadcastPayload)
|
|
29
|
+
|
|
30
|
+
is_workflow_event = self.event_source_type == "WORKFLOW"
|
|
31
|
+
is_workflow_payload = isinstance(self.data, WorkflowPhaseTransitionData)
|
|
32
|
+
|
|
33
|
+
if is_agent_event and not is_agent_payload:
|
|
34
|
+
raise ValueError("event_source_type is 'AGENT' but data is not an AgentEventRebroadcastPayload")
|
|
35
|
+
|
|
36
|
+
if is_sub_workflow_event and not is_sub_workflow_payload:
|
|
37
|
+
raise ValueError("event_source_type is 'SUB_WORKFLOW' but data is not a SubWorkflowEventRebroadcastPayload")
|
|
38
|
+
|
|
39
|
+
if is_workflow_event and not is_workflow_payload:
|
|
40
|
+
raise ValueError("event_source_type is 'WORKFLOW' but data is not a valid workflow-specific payload")
|
|
41
|
+
|
|
42
|
+
return self
|
|
43
|
+
|
|
44
|
+
# This is necessary for Pydantic v2 to correctly handle the recursive model
|
|
45
|
+
SubWorkflowEventRebroadcastPayload.model_rebuild()
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# file: autobyteus/autobyteus/workflow/utils/wait_for_idle.py
|
|
2
|
+
import asyncio
|
|
3
|
+
import logging
|
|
4
|
+
from typing import TYPE_CHECKING
|
|
5
|
+
|
|
6
|
+
from autobyteus.workflow.streaming.workflow_event_stream import WorkflowEventStream
|
|
7
|
+
from autobyteus.workflow.phases.workflow_operational_phase import WorkflowOperationalPhase
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from autobyteus.workflow.agentic_workflow import AgenticWorkflow
|
|
11
|
+
|
|
12
|
+
logger = logging.getLogger(__name__)
|
|
13
|
+
|
|
14
|
+
async def _wait_loop(streamer: WorkflowEventStream, workflow_id: str):
|
|
15
|
+
"""Internal helper to listen for the IDLE or ERROR event."""
|
|
16
|
+
async for event in streamer.all_events():
|
|
17
|
+
if event.event_source_type == "WORKFLOW" and event.data.new_phase == WorkflowOperationalPhase.IDLE:
|
|
18
|
+
logger.info(f"Workflow '{workflow_id}' has become idle.")
|
|
19
|
+
return
|
|
20
|
+
if event.event_source_type == "WORKFLOW" and event.data.new_phase == WorkflowOperationalPhase.ERROR:
|
|
21
|
+
error_message = f"Workflow '{workflow_id}' entered an error state while waiting for idle: {event.data.error_message}"
|
|
22
|
+
logger.error(error_message)
|
|
23
|
+
raise RuntimeError(error_message)
|
|
24
|
+
|
|
25
|
+
async def wait_for_workflow_to_be_idle(workflow: 'AgenticWorkflow', timeout: float = 60.0):
|
|
26
|
+
"""
|
|
27
|
+
Waits for a workflow to complete its bootstrapping and enter the IDLE state.
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
workflow: The workflow instance to monitor.
|
|
31
|
+
timeout: The maximum time in seconds to wait.
|
|
32
|
+
|
|
33
|
+
Raises:
|
|
34
|
+
asyncio.TimeoutError: If the workflow does not become idle within the timeout period.
|
|
35
|
+
RuntimeError: If the workflow enters an error state.
|
|
36
|
+
"""
|
|
37
|
+
if workflow.get_current_phase() == WorkflowOperationalPhase.IDLE:
|
|
38
|
+
return
|
|
39
|
+
|
|
40
|
+
logger.info(f"Waiting for workflow '{workflow.workflow_id}' to become idle (timeout: {timeout}s)...")
|
|
41
|
+
|
|
42
|
+
streamer = WorkflowEventStream(workflow)
|
|
43
|
+
try:
|
|
44
|
+
await asyncio.wait_for(_wait_loop(streamer, workflow.workflow_id), timeout=timeout)
|
|
45
|
+
finally:
|
|
46
|
+
await streamer.close()
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# file: autobyteus/autobyteus/workflow/workflow_builder.py
|
|
2
|
+
import logging
|
|
3
|
+
from typing import List, Optional, Dict, Union
|
|
4
|
+
|
|
5
|
+
from autobyteus.workflow.agentic_workflow import AgenticWorkflow
|
|
6
|
+
from autobyteus.workflow.context.workflow_config import WorkflowConfig
|
|
7
|
+
from autobyteus.workflow.context.workflow_node_config import WorkflowNodeConfig
|
|
8
|
+
from autobyteus.agent.context.agent_config import AgentConfig
|
|
9
|
+
from autobyteus.workflow.factory.workflow_factory import WorkflowFactory
|
|
10
|
+
|
|
11
|
+
logger = logging.getLogger(__name__)
|
|
12
|
+
|
|
13
|
+
# Define a type hint for the possible definition types for clarity
|
|
14
|
+
NodeDefinition = Union[AgentConfig, WorkflowConfig]
|
|
15
|
+
|
|
16
|
+
class WorkflowBuilder:
|
|
17
|
+
"""
|
|
18
|
+
A fluent API for constructing and configuring an AgenticWorkflow.
|
|
19
|
+
|
|
20
|
+
This builder simplifies creating a workflow by abstracting away the manual
|
|
21
|
+
creation of config objects and providing an intuitive way to define the
|
|
22
|
+
agent and sub-workflow graph.
|
|
23
|
+
"""
|
|
24
|
+
def __init__(self, name: str, description: str, role: Optional[str] = None):
|
|
25
|
+
"""
|
|
26
|
+
Initializes the WorkflowBuilder.
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
name: A unique name for the workflow.
|
|
30
|
+
description: A high-level description of the workflow's goal.
|
|
31
|
+
role: An optional role description for when this workflow is used
|
|
32
|
+
as a sub-workflow within a parent.
|
|
33
|
+
"""
|
|
34
|
+
if not name or not isinstance(name, str):
|
|
35
|
+
raise ValueError("Workflow name must be a non-empty string.")
|
|
36
|
+
if not description or not isinstance(description, str):
|
|
37
|
+
raise ValueError("Workflow description must be a non-empty string.")
|
|
38
|
+
|
|
39
|
+
self._name = name
|
|
40
|
+
self._description = description
|
|
41
|
+
self._role = role
|
|
42
|
+
self._nodes: Dict[NodeDefinition, List[NodeDefinition]] = {}
|
|
43
|
+
self._coordinator_config: Optional[AgentConfig] = None
|
|
44
|
+
logger.info(f"WorkflowBuilder initialized for workflow: '{self._name}'.")
|
|
45
|
+
|
|
46
|
+
def add_agent_node(self, agent_config: AgentConfig, dependencies: Optional[List[NodeDefinition]] = None) -> 'WorkflowBuilder':
|
|
47
|
+
"""
|
|
48
|
+
Adds a regular agent node to the workflow.
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
agent_config: The configuration for the agent at this node.
|
|
52
|
+
dependencies: A list of AgentConfig or WorkflowConfig objects for nodes
|
|
53
|
+
that this node depends on. These must have been added previously.
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
The builder instance for fluent chaining.
|
|
57
|
+
"""
|
|
58
|
+
self._add_node_internal(agent_config, dependencies)
|
|
59
|
+
return self
|
|
60
|
+
|
|
61
|
+
def add_workflow_node(self, workflow_config: WorkflowConfig, dependencies: Optional[List[NodeDefinition]] = None) -> 'WorkflowBuilder':
|
|
62
|
+
"""
|
|
63
|
+
Adds a sub-workflow node to the workflow.
|
|
64
|
+
|
|
65
|
+
Args:
|
|
66
|
+
workflow_config: The configuration for the sub-workflow.
|
|
67
|
+
dependencies: A list of AgentConfig or WorkflowConfig objects for nodes
|
|
68
|
+
that this node depends on. These must have been added previously.
|
|
69
|
+
|
|
70
|
+
Returns:
|
|
71
|
+
The builder instance for fluent chaining.
|
|
72
|
+
"""
|
|
73
|
+
self._add_node_internal(workflow_config, dependencies)
|
|
74
|
+
return self
|
|
75
|
+
|
|
76
|
+
def _add_node_internal(self, node_definition: NodeDefinition, dependencies: Optional[List[NodeDefinition]]):
|
|
77
|
+
"""Internal helper to add a node of any type."""
|
|
78
|
+
if not isinstance(node_definition, (AgentConfig, WorkflowConfig)):
|
|
79
|
+
raise TypeError("node_definition must be an instance of AgentConfig or WorkflowConfig.")
|
|
80
|
+
|
|
81
|
+
if node_definition in self._nodes or node_definition == self._coordinator_config:
|
|
82
|
+
raise ValueError(f"Node definition for '{node_definition.name}' has already been added to the workflow.")
|
|
83
|
+
|
|
84
|
+
if dependencies:
|
|
85
|
+
for dep_config in dependencies:
|
|
86
|
+
if dep_config not in self._nodes and dep_config != self._coordinator_config:
|
|
87
|
+
raise ValueError(f"Dependency node '{dep_config.name}' must be added to the builder before being used as a dependency.")
|
|
88
|
+
|
|
89
|
+
self._nodes[node_definition] = dependencies or []
|
|
90
|
+
node_type = "Sub-workflow" if isinstance(node_definition, WorkflowConfig) else "Agent"
|
|
91
|
+
logger.debug(f"Added {node_type} node '{node_definition.name}' to builder with {len(dependencies or [])} dependencies.")
|
|
92
|
+
|
|
93
|
+
def set_coordinator(self, agent_config: AgentConfig) -> 'WorkflowBuilder':
|
|
94
|
+
"""
|
|
95
|
+
Sets the coordinator agent for the workflow. A coordinator must be an agent.
|
|
96
|
+
|
|
97
|
+
Args:
|
|
98
|
+
agent_config: The configuration for the coordinator agent.
|
|
99
|
+
|
|
100
|
+
Returns:
|
|
101
|
+
The builder instance for fluent chaining.
|
|
102
|
+
"""
|
|
103
|
+
if self._coordinator_config is not None:
|
|
104
|
+
raise ValueError("A coordinator has already been set for this workflow.")
|
|
105
|
+
|
|
106
|
+
if not isinstance(agent_config, AgentConfig):
|
|
107
|
+
raise TypeError("Coordinator must be an instance of AgentConfig.")
|
|
108
|
+
|
|
109
|
+
self._coordinator_config = agent_config
|
|
110
|
+
logger.debug(f"Set coordinator for workflow to '{agent_config.name}'.")
|
|
111
|
+
return self
|
|
112
|
+
|
|
113
|
+
def build(self) -> AgenticWorkflow:
|
|
114
|
+
"""
|
|
115
|
+
Constructs and returns the final AgenticWorkflow instance using the
|
|
116
|
+
singleton WorkflowFactory.
|
|
117
|
+
"""
|
|
118
|
+
logger.info("Building AgenticWorkflow from builder...")
|
|
119
|
+
if self._coordinator_config is None:
|
|
120
|
+
raise ValueError("Cannot build workflow: A coordinator must be set.")
|
|
121
|
+
|
|
122
|
+
node_map: Dict[NodeDefinition, WorkflowNodeConfig] = {}
|
|
123
|
+
all_definitions = list(self._nodes.keys()) + [self._coordinator_config]
|
|
124
|
+
|
|
125
|
+
for definition in all_definitions:
|
|
126
|
+
node_map[definition] = WorkflowNodeConfig(node_definition=definition)
|
|
127
|
+
|
|
128
|
+
all_nodes_with_deps = self._nodes.copy()
|
|
129
|
+
all_nodes_with_deps[self._coordinator_config] = [] # Coordinator has no explicit deps in this model
|
|
130
|
+
|
|
131
|
+
for node_def, dep_defs in all_nodes_with_deps.items():
|
|
132
|
+
if node_def in node_map and dep_defs:
|
|
133
|
+
current_node = node_map[node_def]
|
|
134
|
+
dependency_nodes = [node_map[dep_def] for dep_def in dep_defs]
|
|
135
|
+
current_node.dependencies = tuple(dependency_nodes)
|
|
136
|
+
|
|
137
|
+
final_nodes = list(node_map.values())
|
|
138
|
+
coordinator_node_instance = node_map[self._coordinator_config]
|
|
139
|
+
|
|
140
|
+
workflow_config = WorkflowConfig(
|
|
141
|
+
name=self._name,
|
|
142
|
+
description=self._description,
|
|
143
|
+
role=self._role,
|
|
144
|
+
nodes=tuple(final_nodes),
|
|
145
|
+
coordinator_node=coordinator_node_instance
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
logger.info(f"WorkflowConfig created successfully. Name: '{workflow_config.name}'. Total nodes: {len(final_nodes)}. Coordinator: '{coordinator_node_instance.name}'.")
|
|
149
|
+
|
|
150
|
+
factory = WorkflowFactory()
|
|
151
|
+
return factory.create_workflow(config=workflow_config)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: autobyteus
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.5
|
|
4
4
|
Summary: Multi-Agent framework
|
|
5
5
|
Home-page: https://github.com/AutoByteus/autobyteus
|
|
6
6
|
Author: Ryan Zheng
|
|
@@ -14,26 +14,28 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
14
14
|
Requires-Python: >=3.8
|
|
15
15
|
Description-Content-Type: text/markdown
|
|
16
16
|
License-File: LICENSE
|
|
17
|
+
Requires-Dist: aiohttp
|
|
18
|
+
Requires-Dist: anthropic==0.37.1
|
|
19
|
+
Requires-Dist: autobyteus-llm-client==1.1.2
|
|
17
20
|
Requires-Dist: beautifulsoup4>=4.12.2
|
|
18
|
-
Requires-Dist: openai
|
|
19
|
-
Requires-Dist: requests
|
|
20
|
-
Requires-Dist: tiktoken==0.7.0
|
|
21
|
-
Requires-Dist: google-api-python-client
|
|
22
|
-
Requires-Dist: google-generativeai
|
|
23
|
-
Requires-Dist: mistralai
|
|
24
21
|
Requires-Dist: boto3
|
|
25
22
|
Requires-Dist: botocore
|
|
26
|
-
Requires-Dist:
|
|
23
|
+
Requires-Dist: brui-core==1.0.9
|
|
24
|
+
Requires-Dist: certifi==2025.4.26
|
|
25
|
+
Requires-Dist: google-api-python-client
|
|
26
|
+
Requires-Dist: google-generativeai
|
|
27
27
|
Requires-Dist: Jinja2
|
|
28
|
-
Requires-Dist:
|
|
28
|
+
Requires-Dist: mcp[cli]==1.9.1
|
|
29
29
|
Requires-Dist: mistral_common==1.6.3
|
|
30
|
+
Requires-Dist: mistralai
|
|
30
31
|
Requires-Dist: mistralai==1.5.2
|
|
31
|
-
Requires-Dist: certifi==2025.4.26
|
|
32
32
|
Requires-Dist: numpy==2.2.5
|
|
33
|
-
Requires-Dist:
|
|
34
|
-
Requires-Dist:
|
|
35
|
-
Requires-Dist:
|
|
36
|
-
Requires-Dist:
|
|
33
|
+
Requires-Dist: ollama
|
|
34
|
+
Requires-Dist: openai
|
|
35
|
+
Requires-Dist: requests
|
|
36
|
+
Requires-Dist: rich
|
|
37
|
+
Requires-Dist: textual
|
|
38
|
+
Requires-Dist: tiktoken==0.7.0
|
|
37
39
|
Provides-Extra: dev
|
|
38
40
|
Requires-Dist: coverage; extra == "dev"
|
|
39
41
|
Requires-Dist: flake8; extra == "dev"
|