From a0e0e8306f5f74765f564edcfde00872381ea20c Mon Sep 17 00:00:00 2001 From: Dimos Tzimotoudis Date: Mon, 13 Jul 2026 02:18:45 +0000 Subject: [PATCH 1/2] Make mini-train split symlink setup retry-safe --- src/agentomics/agents/steps/data_split.py | 8 ++++++-- src/agentomics/runtime/filesystem.py | 20 +++++++++++++++++++- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/agentomics/agents/steps/data_split.py b/src/agentomics/agents/steps/data_split.py index d5619962..8462cfb2 100644 --- a/src/agentomics/agents/steps/data_split.py +++ b/src/agentomics/agents/steps/data_split.py @@ -15,6 +15,7 @@ from agentomics.runtime.filesystem import ( chown_tree_to_root, create_absolute_symlink, + remove_path, rewrite_symlinks_to_absolute, validate_symlinks_targets_in, ) @@ -197,7 +198,9 @@ async def validate_split_dataset(ctx: RunContext[dict], result: AgenticStepOutpu if is_mini_train_only: step_dir = self.config.current_step_dir for split_name in [TRAIN_SPLIT, VALIDATION_SPLIT]: - create_absolute_symlink(self.config.dataset_dir / split_name, step_dir / split_name) + split_link = step_dir / split_name + remove_path(split_link) + create_absolute_symlink(self.config.dataset_dir / split_name, split_link) result.train_path = str(step_dir / TRAIN_SPLIT) result.val_path = str(step_dir / VALIDATION_SPLIT) train_path = Path(result.train_path) @@ -206,7 +209,8 @@ async def validate_split_dataset(ctx: RunContext[dict], result: AgenticStepOutpu if train_path.parent != val_path.parent or train_path.parent != mini_train_path.parent: raise ModelRetry("Train, validation, and mini_train split folders must be in the same directory.") if not train_path.is_relative_to(self.config.splits_dir) or not val_path.is_relative_to(self.config.splits_dir) or not mini_train_path.is_relative_to(self.config.splits_dir): - for split_path in [train_path, val_path, mini_train_path]: + split_paths_to_validate = [mini_train_path] if is_mini_train_only else [train_path, val_path, mini_train_path] + for split_path in split_paths_to_validate: try: validate_symlinks_targets_in(split_path, self.config.dataset_dir) except ValueError as e: diff --git a/src/agentomics/runtime/filesystem.py b/src/agentomics/runtime/filesystem.py index 797c69a3..c8cb3591 100644 --- a/src/agentomics/runtime/filesystem.py +++ b/src/agentomics/runtime/filesystem.py @@ -57,7 +57,25 @@ def remove_path(path: Path) -> None: def create_absolute_symlink(target: Path, link: Path) -> None: """Create a symlink at link pointing at the resolved absolute path of target.""" - os.symlink(Path(target).resolve(), link) + absolute_target = Path(target).resolve() + link.parent.mkdir(parents=True, exist_ok=True) + + try: + os.symlink(absolute_target, link) + return + except FileExistsError: + pass + + if not link.is_symlink(): + raise FileExistsError( + f"Cannot create symlink {link} -> {absolute_target}: path exists and is not a symlink" + ) + + if link.resolve(strict=False) == absolute_target: + return + + link.unlink() + os.symlink(absolute_target, link) def find_symlinks_in_dir(root: Path, include_root: bool = False) -> list[Path]: root = Path(root) From 641e3d41c0a25c315c7664d9333d2ca5be3862c4 Mon Sep 17 00:00:00 2001 From: Dimos Tzimotoudis Date: Fri, 31 Jul 2026 12:54:50 +0000 Subject: [PATCH 2/2] remove redundant symlink cleanup --- src/agentomics/agents/steps/data_split.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/agentomics/agents/steps/data_split.py b/src/agentomics/agents/steps/data_split.py index 8462cfb2..d2538b37 100644 --- a/src/agentomics/agents/steps/data_split.py +++ b/src/agentomics/agents/steps/data_split.py @@ -15,7 +15,6 @@ from agentomics.runtime.filesystem import ( chown_tree_to_root, create_absolute_symlink, - remove_path, rewrite_symlinks_to_absolute, validate_symlinks_targets_in, ) @@ -199,7 +198,6 @@ async def validate_split_dataset(ctx: RunContext[dict], result: AgenticStepOutpu step_dir = self.config.current_step_dir for split_name in [TRAIN_SPLIT, VALIDATION_SPLIT]: split_link = step_dir / split_name - remove_path(split_link) create_absolute_symlink(self.config.dataset_dir / split_name, split_link) result.train_path = str(step_dir / TRAIN_SPLIT) result.val_path = str(step_dir / VALIDATION_SPLIT)