LegoFlow

BlocksTracer

Getting Started

This page gets Tracer from verified tasks to agent trajectories. The path is: fill config.yaml, run setup, check the block, launch rollouts, then open the dashboard.

You can read it as a concrete walkthrough: follow the example config snippets and commands in order, and you will see how a Tracer run is put together.

Prerequisites

Before starting, make sure these are available:

  • Claude Code with the Tracer plugin loaded.
  • Docker, used by Harbor to run task containers.
  • uv and Python, used to build the Harbor, LiteLLM, and conversion envs.
  • An OpenAI-compatible LLM endpoint and API key.
  • A task source, usually Curator's artifacts/merged_swe_tasks/ output.
  • Optional Cloudflare credentials, only needed if you want to publish the dashboard.

If the Tracer slash commands are not visible in Claude Code, see FAQ.

Setup

Most Tracer issues come from a mismatch between the task source, model endpoint, agent scaffold, and conversion settings. Once config.yaml is aligned, the skills handle the environment and launch details.

For a first run, leave meta_info and runtime_info.output alone. Fill the runtime_info.input pieces below. For every field, see the Configuration Guide.

LLM API config

Tracer starts a per-job LiteLLM proxy in front of your model. Point llm_api at the raw upstream endpoint:

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                  # upstream model called by the agent      protocols: [openai_compatible, anthropic_compatible]      served_via: per_job_litellm_proxy    litellm_proxy:      port: 4003                                     # local proxy port for this Tracer job      master_key: dummy-key-cf                       # functional dummy key for the proxy

Never commit real API keys or private endpoints to config.yaml.

Receive Curator output

For the full LegoFlow path, Tracer reads Curator's merged verified tasks:

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                                # receive Curator output from the local filesystem      dataset_name: ../curator/artifacts/merged_swe_tasks # Curator's merged verified task directory      split: train

The runtime_info.input.task_source.dataset_name field is the path Tracer actually reads. The meta_info.dependencies.from entry explains where that value comes from in the block graph, so root-level checks can catch a broken Curator -> Tracer connection before rollout starts.

During /tracer:run, Tracer stages this source into its own artifacts/tasks/<dataset>/ area before Harbor starts, by symlinking one entry per task rather than copying. If verifiable_tasks.txt exists, only those verified task IDs are staged.

Rollout config

Start with a small task cap and modest concurrency:

blocks/tracer/config.yaml
runtime_info:  input:    harbor_job:      jobs_dir: artifacts/jobs              # Harbor jobs and trajectories land here      n_concurrent: 4                       # keep small for the first run      n_tasks: 10                           # null = all prepared tasks      max_retries: 2      timeout_multiplier: 5

Agent config

Choose one scaffold and keep its runtime image, version, and conversion scaffold aligned. Do not change only version: the runtime image tag and runtime_host_path must point to the same agent runtime.

Tracer currently uses these pinned scaffold versions:

Scaffoldagent.nameagent.versionRuntime image
Claude Codecustom-claude-code2.1.118docker.io/jierun/c-cc-2.1.118:v0.1
OpenCodecustom-opencode1.18.7docker.io/jierun/c-oc-1.18.7:v0.1
OpenHands SDKcustom-openhands-sdk1.33.0docker.io/jierun/c-oh-sdk-1.33.0:v0.1

The default Claude Code profile looks like this:

blocks/tracer/config.yaml
runtime_info:  input:    agent:      name: custom-claude-code              # custom-claude-code | custom-openhands-sdk | custom-opencode      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

If you switch scaffolds, keep the names and paths consistent. For example, OpenCode should use the OpenCode version, image, host path, and conversion key together:

blocks/tracer/config.yaml
runtime_info:  input:    agent:      name: custom-opencode      version: 1.18.7      runtime_image: docker.io/jierun/c-oc-1.18.7:v0.1      runtime_host_path: artifacts/agent-runtime/opencode    sft_conversion:      scaffold: open_code                    # or keep auto for a new matching run

SFT conversion config

If you want Trainer-ready LF data after rollout, enable conversion. Otherwise leave it off and use raw trajectories only.

blocks/tracer/config.yaml
runtime_info:  input:    sft_conversion:      enabled: true                         # false = skip conversion after rollout      scaffold: auto                        # auto infers from agent.name; use an explicit key for old jobs      tokenizer_name: Qwen/Qwen3.5-35B-A3B-Base      out_dir: artifacts/sft_data      max_instances: null                   # null = convert all successful trajectories

Now run setup:

/tracer:setup

This prepares the pinned repos/harbor and repos/swe_data_process checkouts, builds the Harbor/LiteLLM/conversion environments, and checks the local runtime paths. Re-running it is fine.

Check

Before launching containers or spending model tokens, run:

/tracer:check

This is read-only. It checks config, repo pins, environments, task source, model endpoint, proxy port, Docker, agent runtime, and conversion settings. For exact pass conditions, see Validation Checks. A healthy report should leave you ready for task preparation and rollout.

Fix required failures before continuing.

Run trajectories

Launch the rollout job:

/tracer:run

Tracer starts the per-job LiteLLM proxy, builds the Harbor command from config.yaml, stages tasks under artifacts/tasks/<dataset>/, excludes already processed or manually retired tasks, captures trajectories, optionally converts SFT data, and archives the run.

Task preparation happens as part of the run path. For local Curator output, Tracer trusts verifiable_tasks.txt when it exists and stages only verified tasks, as symlinks into the pool. Hugging Face sources are downloaded and unpacked into the same artifacts/tasks/<dataset>/ layout. Tracer also skips tasks already recorded in artifacts/processed_tasks.yaml or manually listed in excluded_tasks.txt, so ordinary follow-up runs continue from the remaining work.

The main outputs are:

artifacts/jobs/<job>/result.json
artifacts/jobs/<job>/<task>/agent/litellm-trajectory.jsonl
artifacts/sft_data/<job>/lf.json      # only when sft_conversion.enabled: true

For the artifact layout and handoff contract, see Output Format.

Trajectory conversion

Raw rollout trajectories are useful for inspection, but Trainer usually needs clean SFT data. If sft_conversion.enabled: true, Tracer converts successful rollouts after /tracer:run. You can also ask /tracer:dashboard to refresh conversion and stats for a finished job.

The conversion path has three layers:

LayerFormatPurpose
Raw trajectoryScaffold-specific Harbor/LiteLLM logs from Claude Code, OpenCode, OpenHands SDK, or Terminus-2.Preserve the exact rollout trace for debugging and analysis.
IMIntermediate JSONL with OpenAI-style messages and normalized tool_calls.Give all scaffolds one shared trajectory schema for scoring and filtering.
LFLLaMA-Factory ShareGPT JSON array.The Trainer-ready SFT format; this is the usual downstream handoff.

The converted files live under:

artifacts/sft_data/<job>/
├── im.jsonl       # scored intermediate message records
├── lf.json        # Trainer-ready LLaMA-Factory / ShareGPT data
└── lf.stats.json  # token, turn, and score statistics for the dashboard

For the full conversion flow and supported scaffold keys, see Trajectory Conversion and Supported Scaffolds.

Output for Trainer

For most training runs, Tracer hands over the converted LF file rather than raw trajectories. After /tracer:run, choose the finished job directory under artifacts/sft_data/:

artifacts/sft_data/<job>/lf.json

Tracer's checked-in dependency contract currently declares the raw Harbor-job handoff for source.type: harbor_job:

blocks/tracer/config.yaml
meta_info:  dependencies:    to:      raw_trajectories_dir:        to: trainer.input.source.job_dir        when: {trainer.input.source.type: harbor_job}runtime_info:  output:    raw_trajectories_dir:      path: artifacts/jobs    sft_data_dir:      path: artifacts/sft_data

In the common SFT path, Trainer usually consumes sft_data_dir manually through source.type: local_lf. Continue with Trainer Getting Started to see that downstream config.

Dashboard visualization

After a job starts or finishes, open the dashboard:

/tracer:dashboard

The dashboard helps inspect job progress, per-task trajectories, rewards, failure patterns, and converted SFT data. It reads artifacts/ directly; if a run is still active, keep watching the job log and artifacts/jobs/<job>/ too.

For the internal rollout mechanism, see Design.

On this page