LegoFlow

BlocksTracerUsage

Configuration Guide

Tracer config controls rollout jobs: which tasks to run, which agent scaffold to use, how many jobs to launch, and whether to convert trajectories for SFT. Most runs only need a few runtime_info.input fields. Leave meta_info, repository pins, environment paths, and output declarations alone unless you are changing the block contract itself.

Common fields

AreaEdit whenMain fields
Model endpointYou want Tracer to call a different model or gateway.llm_api.api_key, api_base_url, model
Task sourceYou are receiving Curator output or using a dataset from Hugging Face.task_source.provider, dataset_name, split
Rollout scaleYou are doing a smoke run, a batch run, or a full production run.harbor_job.n_tasks, n_concurrent, max_retries, timeout_multiplier
Agent scaffoldYou switch between Claude Code, OpenCode, or OpenHands SDK.agent.name, version, runtime_image, runtime_host_path
Remote machineYou want Tracer to run rollouts on another Docker server.meta_info.resources.ip, user, pwd, directory
Trainer handoffYou need training-ready data after rollout.sft_conversion.enabled, scaffold, tokenizer_name, out_dir

An example reference

Start with local Curator output, a small task cap, Claude Code, and SFT conversion enabled. This gives you a complete mini-run that can hand data to Trainer.

blocks/tracer/config.yaml
runtime_info:  input:    llm_api:      api_key: <YOUR_API_KEY>      api_base_url: https://your-openai-compatible-endpoint/v1      model: openai/Qwen3.6-35B-A3B    task_source:      provider: local      dataset_name: ../curator/artifacts/merged_swe_tasks      split: train    harbor_job:      jobs_dir: artifacts/jobs      n_concurrent: 4      n_tasks: 10      max_retries: 2      timeout_multiplier: 5    agent:      name: custom-claude-code      version: 2.1.118      runtime_image: docker.io/jierun/c-cc-2.1.118:v0.1      runtime_host_path: artifacts/agent-runtime/claude-code      max_turns: 80      temperature: 0.7    sft_conversion:      enabled: true      scaffold: auto      tokenizer_name: Qwen/Qwen3.5-35B-A3B-Base      out_dir: artifacts/sft_data

Use /tracer:check after editing. It catches missing task sources, bad model endpoints, unavailable Docker/runtime images, and conversion config mistakes before /tracer:run spends tokens.

Configuration breakdown

Remote execution

Tracer runs locally by default. If you want rollouts to happen on a remote CPU/Docker node, fill meta_info.resources so the operating skill knows where to log in and which block directory to use.

blocks/tracer/config.yaml
meta_info:  resources:    ip: 203.0.113.12              # local = current machine; otherwise SSH target    user: ubuntu               # SSH user for the remote server    pwd: null                  # prefer SSH keys or your private secret channel    directory: /home/ubuntu/LegoFlow/blocks/tracer    public_storage: null

Use a remote node when local Docker capacity, network placement, or long-running rollouts make the current machine inconvenient. The remote directory should point at the Tracer block checkout, not just the repository root.

Task source

Tracer receives valid tasks to produce trajectories either from the Curator, or open-sourced tasks from Huggingface.

  • From Curator Tasks:
blocks/tracer/config.yaml
runtime_info:  input:    task_source:      provider: local      dataset_name: ../curator/artifacts/merged_swe_tasks      split: train
  • From Hugging Face Task Dataset:
blocks/tracer/config.yaml
runtime_info:  input:    task_source:      provider: huggingface      dataset_name: Lego-X/<dataset-name>      split: train

Smoke run

Use a small n_tasks and low concurrency when checking a new endpoint, runtime image, or task source. This is usually helpful for debugging or getting familiar with the whole pipeline.

blocks/tracer/config.yaml
runtime_info:  input:    harbor_job:      n_concurrent: 1      n_tasks: 5      max_retries: 0      timeout_multiplier: 5

Production rollout

For production, raise concurrency only after /tracer:check passes and a smoke run has produced valid trajectories.

blocks/tracer/config.yaml
runtime_info:  input:    harbor_job:      n_concurrent: 8      n_tasks: null             # run every staged task      max_retries: 2      timeout_multiplier: 5

Agent version presets

The agent fields move as a set. Pick one row and keep agent.name, agent.version, agent.runtime_image, agent.runtime_host_path, and sft_conversion.scaffold aligned.

Scaffoldagent.nameagent.versionagent.runtime_imageagent.runtime_host_pathsft_conversion.scaffold
Claude Codecustom-claude-code2.1.118docker.io/jierun/c-cc-2.1.118:v0.1artifacts/agent-runtime/claude-codeclaude_code or auto
OpenCodecustom-opencode1.18.7docker.io/jierun/c-oc-1.18.7:v0.1artifacts/agent-runtime/opencodeopen_code or auto
OpenHands SDKcustom-openhands-sdk1.33.0docker.io/jierun/c-oh-sdk-1.33.0:v0.1artifacts/agent-runtime/openhands-sdkopenhands_sdk or auto

Use auto for a fresh run that uses the same agent.name in the current config. Use an explicit scaffold key when reconverting an older job whose scaffold may differ from the current config.

Handoff with neighboring blocks

Tracer normally receives tasks from Curator and sends converted LF data to Trainer.

Receive Curator tasks

task_source.dataset_name is the path Tracer actually reads. The dependency entry documents that this value comes from Curator's merged_tasks_dir, so root-level checks can validate the handoff.

blocks/tracer/config.yaml
meta_info:  dependencies:    from:      task_source.dataset_name:        from: curator.output.merged_tasks_dir        when: {task_source.provider: local}runtime_info:  input:    task_source:      provider: local      dataset_name: ../curator/artifacts/merged_swe_tasks

Produce Trainer-ready data

Trainer usually reads artifacts/sft_data/<job>/lf.json. Keep conversion on when Tracer should produce that file after rollout.

blocks/tracer/config.yaml
runtime_info:  input:    sft_conversion:      enabled: true      scaffold: auto      tokenizer_name: Qwen/Qwen3.5-35B-A3B-Base      out_dir: artifacts/sft_data  output:    sft_data_dir:      path: artifacts/sft_data      trajectory_format: artifacts/sft_data/<job>/lf.json

Field reference

FieldRequired?DefaultWhen to change
llm_api.api_keyYeshumanPut the real key in env/private config before rollout. Never commit it.
llm_api.api_base_urlYeshumanPoint Tracer at your OpenAI-compatible endpoint.
llm_api.modelYesopenai/Qwen3.6-35B-A3BChange when testing a different teacher model.
litellm_proxy.portYes4003Change only if the local port is already occupied.
task_source.providerYeslocalUse local for Curator output; use huggingface for a published dataset.
task_source.dataset_nameYes../curator/artifacts/merged_swe_tasksChange to another local task directory or dataset id.
harbor_job.n_concurrentYes8Tune for endpoint capacity, Docker capacity, and API rate limits.
harbor_job.n_tasksNo40Use 5 or 10 for smoke runs; use null to run all staged tasks.
harbor_job.max_retriesYes2Lower for fast checks; raise only for unstable infrastructure.
harbor_job.timeout_multiplierYes5Increase when agents time out on valid tasks. This is a multiplier, not seconds.
agent.nameYescustom-claude-codeSwitch coding scaffold. Change the full agent row together.
agent.versionYes2.1.118Must match the selected scaffold and runtime image tag.
agent.runtime_imageYesdocker.io/jierun/c-cc-2.1.118:v0.1Must match the selected scaffold and version.
agent.runtime_host_pathRecommendedartifacts/agent-runtime/claude-codeUse the pre-extracted runtime path when available.
sft_conversion.enabledYestrueKeep true when Trainer will consume Tracer output.
sft_conversion.scaffoldYesautoKeep auto for fresh runs; set explicit key when reconverting old jobs.
sft_conversion.tokenizer_nameYesQwen/Qwen3.5-35B-A3B-BaseAlign with the Trainer base model.
sft_conversion.max_instancesNonullCap conversion for quick checks; null converts all successful rollouts.
env_extra.HARBOR_EXCLUDE_TASKSNoexcluded_tasks.txt artifacts/processed_tasks.yamlAdd task ids or files to skip known-bad or already processed tasks.
meta_info.resources.ipNolocalSet a host/IP when Tracer should run on a remote Docker node.
meta_info.resources.userFor remotenullSSH user for the remote node.
meta_info.resources.directoryFor remotenullTracer block working directory on the remote node.
meta_info.resources.public_storageNonullOptional public artifact location for dashboards or sharing.

Complete config.yaml

Use this as the complete reference after you understand the few fields above.

blocks/tracer/config.yaml
meta_info:  name: tracer  label: "Tracer"  description: Generates raw agent trajectories with Harbor for downstream SFT data conversion.  parent: legoflow  blocks: {}  dependencies:    from:      task_source.dataset_name:        from: curator.output.merged_tasks_dir        when: {task_source.provider: local}    to:      raw_trajectories_dir:        to: trainer.input.source.job_dir        when: {trainer.input.source.type: harbor_job}  resources:    ip: local        # CPU-only; runs on any node with Docker available    user: null    pwd: null    directory: null    description: Local CPU/Docker node. Remote SSH fields are ignored when ip is local.    public_storage: null  repositories:    harbor:      url: https://github.com/LegoX/harbor.git      branch: main      commit: 73fd120e731217b38f31667932ea26a28cdd4fff      path: repos/harbor      readonly: true    swe_data_process:      url: https://github.com/LegoX/swe_data_process.git      branch: main      commit: dda92c581a0c0eaba74bb469d92ddda767e5f1b3   # origin/main HEAD (verified 2026-07-28), defaults reasoning-check-mode to adaptive      path: repos/swe_data_process      readonly: true  environment:    harbor_uv: artifacts/env/harbor-uv    litellm_uv: artifacts/env/litellm-venv    # separate venv; harbor env resets to litellm 1.83.0    swe_data_process_uv: artifacts/env/swe-data-process-uv    swe_data_process_extras: [llm]    litellm:      python_version: "3.13"      litellm_version: "1.83.14"runtime_info:  input:    llm_api:      api_key: human                          # fill in a private local copy before running; never commit a real key      api_base_url: human                     # fill in a private local copy before running; keep gateway URLs out of git      model: "openai/Qwen3.6-35B-A3B"      description: Raw upstream model API used to configure per-job LiteLLM proxy startup.      protocols: [openai_compatible, anthropic_compatible]      served_via: per_job_litellm_proxy      input_cost_per_token: 0.0000021      output_cost_per_token: 0.0000084    litellm_proxy:      config_template: scripts/serve_llm/litellm_config.example.yaml      port: 4003      master_key: dummy-key-cf         # functional dummy    task_source:      provider: local                  # local (curator) | huggingface — see /tracer:setup reference      dataset_name: ../curator/artifacts/merged_swe_tasks      split: train    harbor_job:      jobs_dir: artifacts/jobs         # exported by start.sh as TRAJGEN_HARBOR_JOBS_DIR      n_concurrent: 8      n_tasks: 40                      # null = all manifest tasks      max_retries: 2      timeout_multiplier: 5    agent:      name: custom-claude-code   # Supported pinned versions: custom-claude-code=2.1.118, custom-opencode=1.18.7, custom-openhands-sdk=1.33.0.      version: 2.1.118      runtime_image: docker.io/jierun/c-cc-2.1.118:v0.1      runtime_host_path: artifacts/agent-runtime/claude-code   # pre-extracted; see /tracer:check reference      max_turns: 80      temperature: 0.7    sft_conversion:      enabled: true                    # true = start.sh runs convert step after the Harbor job      scaffold: auto                   # auto derives from agent.name; explicit choices: claude_code | open_code | openhands_sdk | terminus2      tokenizer_name: Qwen/Qwen3.5-35B-A3B-Base  # align conversion with trainer.model.model_name_or_path      out_dir: artifacts/sft_data      max_instances: null      exclude_repos_file: ""           # "" = repo default artifacts/excluded_repos.txt      reasoning_check_mode: adaptive      reasoning_content_ratio_threshold: 0.2    env_extra:      HARBOR_EXCLUDE_TASKS: excluded_tasks.txt artifacts/processed_tasks.yaml   # exclusion sources; literal ids also accepted  output:    raw_trajectories_dir:      description: Harbor job directories with LiteLLM trajectory logs      path: artifacts/jobs      trajectory_format: "artifacts/jobs/<job>/<task>/agent/litellm-trajectory.jsonl"    sft_data_dir:      description: LF-format JSON arrays converted from Harbor trajectories, ready for LLaMA-Factory SFT.      path: artifacts/sft_data      format: llamafactory_lf_v0.1      trajectory_format: "artifacts/sft_data/<job>/lf.json"

On this page