| 
                        12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879 | 
                        - import abc
 - from collections.abc import Mapping, Sequence
 - from typing import Any, Protocol
 - 
 - from core.variables import Variable
 - from core.workflow.entities.variable_pool import VariablePool
 - 
 - 
 - class VariableLoader(Protocol):
 -     """Interface for loading variables based on selectors.
 - 
 -     A `VariableLoader` is responsible for retrieving additional variables required during the execution
 -     of a single node, which are not provided as user inputs.
 - 
 -     NOTE(QuantumGhost): Typically, all variables loaded by a `VariableLoader` should belong to the same
 -     application and share the same `app_id`. However, this interface does not enforce that constraint,
 -     and the `app_id` parameter is intentionally omitted from `load_variables` to achieve separation of
 -     concern and allow for flexible implementations.
 - 
 -     Implementations of `VariableLoader` should almost always have an `app_id` parameter in
 -     their constructor.
 - 
 -     TODO(QuantumGhost): this is a temporally workaround. If we can move the creation of node instance into
 -     `WorkflowService.single_step_run`, we may get rid of this interface.
 -     """
 - 
 -     @abc.abstractmethod
 -     def load_variables(self, selectors: list[list[str]]) -> list[Variable]:
 -         """Load variables based on the provided selectors. If the selectors are empty,
 -         this method should return an empty list.
 - 
 -         The order of the returned variables is not guaranteed. If the caller wants to ensure
 -         a specific order, they should sort the returned list themselves.
 - 
 -         :param: selectors: a list of string list, each inner list should have at least two elements:
 -             - the first element is the node ID,
 -             - the second element is the variable name.
 -         :return: a list of Variable objects that match the provided selectors.
 -         """
 -         pass
 - 
 - 
 - class _DummyVariableLoader(VariableLoader):
 -     """A dummy implementation of VariableLoader that does not load any variables.
 -     Serves as a placeholder when no variable loading is needed.
 -     """
 - 
 -     def load_variables(self, selectors: list[list[str]]) -> list[Variable]:
 -         return []
 - 
 - 
 - DUMMY_VARIABLE_LOADER = _DummyVariableLoader()
 - 
 - 
 - def load_into_variable_pool(
 -     variable_loader: VariableLoader,
 -     variable_pool: VariablePool,
 -     variable_mapping: Mapping[str, Sequence[str]],
 -     user_inputs: Mapping[str, Any],
 - ):
 -     # Loading missing variable from draft var here, and set it into
 -     # variable_pool.
 -     variables_to_load: list[list[str]] = []
 -     for key, selector in variable_mapping.items():
 -         # NOTE(QuantumGhost): this logic needs to be in sync with
 -         # `WorkflowEntry.mapping_user_inputs_to_variable_pool`.
 -         node_variable_list = key.split(".")
 -         if len(node_variable_list) < 1:
 -             raise ValueError(f"Invalid variable key: {key}. It should have at least one element.")
 -         if key in user_inputs:
 -             continue
 -         node_variable_key = ".".join(node_variable_list[1:])
 -         if node_variable_key in user_inputs:
 -             continue
 -         if variable_pool.get(selector) is None:
 -             variables_to_load.append(list(selector))
 -     loaded = variable_loader.load_variables(variables_to_load)
 -     for var in loaded:
 -         variable_pool.add(var.selector, var)
 
 
  |