# Copyright (c) Microsoft. All rights reserved. from typing import TYPE_CHECKING from semantic_kernel.exceptions.process_exceptions import ProcessInvalidConfigurationException from semantic_kernel.processes.kernel_process.kernel_process_edge import KernelProcessEdge from semantic_kernel.processes.process_end_step import EndStep from semantic_kernel.processes.process_function_target_builder import ProcessFunctionTargetBuilder from semantic_kernel.utils.feature_stage_decorator import experimental if TYPE_CHECKING: from semantic_kernel.processes.process_step_builder import ProcessStepBuilder @experimental class ProcessStepEdgeBuilder: """A builder for a process step edge.""" source: "ProcessStepBuilder" target: ProcessFunctionTargetBuilder | None = None event_id: str def __init__(self, source: "ProcessStepBuilder", event_id: str): """Initializes a new instance of ProcessStepEdgeBuilder.""" self.source = source self.event_id = event_id def send_event_to( self, target: "ProcessFunctionTargetBuilder | ProcessStepBuilder", **kwargs ) -> "ProcessStepEdgeBuilder": """Sends the event to the target. Args: target: The target to send the event to. **kwargs: Additional keyword arguments. Returns: ProcessStepEdgeBuilder: The ProcessStepEdgeBuilder instance. """ from semantic_kernel.processes.process_step_builder import ProcessStepBuilder if self.target is not None: raise ProcessInvalidConfigurationException( "An output target has already been set part of the ProcessStepEdgeBuilder." ) if isinstance(target, ProcessStepBuilder): target = ProcessFunctionTargetBuilder( step=target, parameter_name=kwargs.get("parameter_name"), function_name=kwargs.get("function_name") ) self.target = target self.source.link_to(self.event_id, self) return ProcessStepEdgeBuilder(source=self.source, event_id=self.event_id) def stop_process(self): """Stops the process.""" if self.target is not None: raise ProcessInvalidConfigurationException( "An output target has already been set part of the ProcessStepEdgeBuilder." ) output_target = ProcessFunctionTargetBuilder(EndStep.get_instance()) self.target = output_target self.source.link_to("END", self) def build(self) -> KernelProcessEdge: """Builds the KernelProcessEdge.""" if not self.source.name: raise ValueError("Source step must have a valid name") if self.target is None: raise ValueError("Target must be provided") return KernelProcessEdge(source_step_id=self.source.id, output_target=self.target.build())