您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

variable_loader.py 3.2KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. import abc
  2. from collections.abc import Mapping, Sequence
  3. from typing import Any, Protocol
  4. from core.variables import Variable
  5. from core.workflow.entities.variable_pool import VariablePool
  6. class VariableLoader(Protocol):
  7. """Interface for loading variables based on selectors.
  8. A `VariableLoader` is responsible for retrieving additional variables required during the execution
  9. of a single node, which are not provided as user inputs.
  10. NOTE(QuantumGhost): Typically, all variables loaded by a `VariableLoader` should belong to the same
  11. application and share the same `app_id`. However, this interface does not enforce that constraint,
  12. and the `app_id` parameter is intentionally omitted from `load_variables` to achieve separation of
  13. concern and allow for flexible implementations.
  14. Implementations of `VariableLoader` should almost always have an `app_id` parameter in
  15. their constructor.
  16. TODO(QuantumGhost): this is a temporally workaround. If we can move the creation of node instance into
  17. `WorkflowService.single_step_run`, we may get rid of this interface.
  18. """
  19. @abc.abstractmethod
  20. def load_variables(self, selectors: list[list[str]]) -> list[Variable]:
  21. """Load variables based on the provided selectors. If the selectors are empty,
  22. this method should return an empty list.
  23. The order of the returned variables is not guaranteed. If the caller wants to ensure
  24. a specific order, they should sort the returned list themselves.
  25. :param: selectors: a list of string list, each inner list should have at least two elements:
  26. - the first element is the node ID,
  27. - the second element is the variable name.
  28. :return: a list of Variable objects that match the provided selectors.
  29. """
  30. pass
  31. class _DummyVariableLoader(VariableLoader):
  32. """A dummy implementation of VariableLoader that does not load any variables.
  33. Serves as a placeholder when no variable loading is needed.
  34. """
  35. def load_variables(self, selectors: list[list[str]]) -> list[Variable]:
  36. return []
  37. DUMMY_VARIABLE_LOADER = _DummyVariableLoader()
  38. def load_into_variable_pool(
  39. variable_loader: VariableLoader,
  40. variable_pool: VariablePool,
  41. variable_mapping: Mapping[str, Sequence[str]],
  42. user_inputs: Mapping[str, Any],
  43. ):
  44. # Loading missing variable from draft var here, and set it into
  45. # variable_pool.
  46. variables_to_load: list[list[str]] = []
  47. for key, selector in variable_mapping.items():
  48. # NOTE(QuantumGhost): this logic needs to be in sync with
  49. # `WorkflowEntry.mapping_user_inputs_to_variable_pool`.
  50. node_variable_list = key.split(".")
  51. if len(node_variable_list) < 1:
  52. raise ValueError(f"Invalid variable key: {key}. It should have at least one element.")
  53. if key in user_inputs:
  54. continue
  55. node_variable_key = ".".join(node_variable_list[1:])
  56. if node_variable_key in user_inputs:
  57. continue
  58. if variable_pool.get(selector) is None:
  59. variables_to_load.append(list(selector))
  60. loaded = variable_loader.load_variables(variables_to_load)
  61. for var in loaded:
  62. variable_pool.add(var.selector, var)