agentsclimarketplace

Yaml config with templated dynamic paths

Skill kjuhwa/skills-hub/skills/configuration/yaml-config-with-templated-dynamic-paths

Load experiment config from YAML, then auto-resolve dependent paths via templates like "{base}/{exp_name}/tokenizer/best_model" unless the user overrides.From its SKILL.md

Install
npx -y skills add kjuhwa/skills-hub --skill yaml-config-with-templated-dynamic-paths

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

3.5 KB, 704 tokens by cl100k_base, as published. Nobody here has run it

YAML config with auto-derived paths that stay overridable

When to use

  • You run many experiments, each with its own exp_name, where 90% of the output paths are {base_path}/{exp_name}/... and should just be derived automatically.
  • You still want to allow a specific experiment to override any single path to point at a shared artifact.
  • You want one config.yaml to capture data paths, training hyperparams, device, and distributed settings in one place — not scattered across a Python Config() class and CLI flags.

Pattern

After yaml.safe_load, walk a small path_templates dict and fill in each path by one of three rules: (1) template string if the user left the key empty ("" or None), (2) user's string if it contains {exp_name} (do a .format), (3) user's string verbatim. Expose flat getters (get_data_config, get_training_config, …) and a typed wrapper that bundles everything into one object.

# finetune_csv/config_loader.py
def _resolve_dynamic_paths(self, config):
    exp_name  = config.get('model_paths', {}).get('exp_name', '')
    if not exp_name: return config
    base_path = config.get('model_paths', {}).get('base_path', '')
    path_templates = {
        'base_save_path':       f"{base_path}/{exp_name}",
        'finetuned_tokenizer':  f"{base_path}/{exp_name}/tokenizer/best_model",
    }
    for key, template in path_templates.items():
        if key in config['model_paths']:
            current = config['model_paths'][key]
            if current in ("", None):
                config['model_paths'][key] = template
            elif isinstance(current, str) and '{exp_name}' in current:
                config['model_paths'][key] = current.format(exp_name=exp_name)
    return config

The YAML shows both escape hatches side by side:

# configs/config_ali09988_candle-5min.yaml
model_paths:
  exp_name:  "HK_ali_09988_kline_5min_all"
  base_path: "/xxx/Kronos/finetune_csv/finetuned/"
  base_save_path: ""                                          # way 1: auto-derived
  # finetuned_tokenizer: "/xxx/{exp_name}/tokenizer/best_model"   # way 2: template override

Why it works / tradeoffs

Writers default to the convention (empty string → templated path) but power users can point at someone else's checkpoint with a literal. Storing exp_name + base_path at the top keeps paths diffable across experiments. The "empty string means use template" choice is a small gotcha — an accidental null could silently generate a wrong path — so prefer explicit "" and document it. For deeper hierarchies, consider a library like Hydra, but this 50-line helper is often enough.

References

  • finetune_csv/config_loader.py in Kronos — ConfigLoader._resolve_dynamic_paths, CustomFinetuneConfig
  • finetune_csv/configs/config_ali09988_candle-5min.yaml — example with both override styles

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Keep looking

Skills are one crate of 326,871. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.