MCPcopy Create free account
hub / github.com/ScaleML/AgentSPEX / _collect_submodule_paths

Function _collect_submodule_paths

src/harness/utils/reproducibility.py:154–243  ·  view source on GitHub ↗

Recursively collect all submodule/module YAML paths referenced by a workflow. This currently supports: - Formal `submodules` declarations (via normalize_submodule_declarations) - Workflow modules referenced via `module: "modules/xxx.yaml"` in the YAML

(root_plan: Path)

Source from the content-addressed store, hash-verified

152
153
154def _collect_submodule_paths(root_plan: Path) -> Set[Path]:
155 """Recursively collect all submodule/module YAML paths referenced by a workflow.
156
157 This currently supports:
158 - Formal `submodules` declarations (via normalize_submodule_declarations)
159 - Workflow modules referenced via `module: "modules/xxx.yaml"` in the YAML
160 """
161 parser = YAMLTaskParser()
162 visited: Set[Path] = set()
163 stack = [root_plan]
164 root_base = root_plan.parent
165
166 while stack:
167 current = stack.pop()
168 try:
169 yaml_data = parser.load_task(str(current))
170 except Exception:
171 # If we can't parse a submodule, skip it but continue with others
172 continue
173 # 1) Collect submodules declared via the `submodules` field
174 try:
175 submodules = normalize_submodule_declarations(yaml_data, str(current))
176 except Exception:
177 # If submodule declarations are invalid, skip but continue with other mechanisms
178 submodules = []
179
180 for entry in submodules:
181 path_str = entry.get("path")
182 if not path_str:
183 continue
184 sub_path = Path(path_str).resolve()
185 if sub_path.exists() and sub_path not in visited:
186 visited.add(sub_path)
187 stack.append(sub_path)
188
189 # 2) Collect workflow modules referenced via `module: "modules/xxx.yaml"`
190
191 def _iter_module_paths(node):
192 if isinstance(node, dict):
193 for k, v in node.items():
194 if k == "module" and isinstance(v, str):
195 yield v
196 else:
197 yield from _iter_module_paths(v)
198 elif isinstance(node, list):
199 for item in node:
200 yield from _iter_module_paths(item)
201
202 for module_rel in _iter_module_paths(yaml_data):
203 # Resolve module path using the same semantics as runtime:
204 # - absolute paths are used as-is
205 # - relative paths may be resolved using multiple strategies:
206 # * relative to the current file directory
207 # * relative to the root plan directory
208 # * under any sibling "<root_stem>_modules/**" directory (used by UI)
209 rel_obj = Path(module_rel)
210 candidates: Set[Path] = set()
211 if os.path.isabs(module_rel):

Callers 1

Calls 6

load_taskMethod · 0.95
_iter_module_pathsFunction · 0.85
getMethod · 0.80
resolveMethod · 0.80
YAMLTaskParserClass · 0.50

Tested by

no test coverage detected