code-first-helpers

star 0

Use when authoring Python scripts via the code.read_file/edit_file/write_file/run quartet to do data profiling, cleaning, modeling, BigQuery, or Kaggle work — documents the `autonoml.helpers` API so the script doesn't have to introspect it.

whanyu1212 By whanyu1212 schedule Updated 5/17/2026

name: code-first-helpers description: Use when authoring Python scripts via the code.read_file/edit_file/write_file/run quartet to do data profiling, cleaning, modeling, BigQuery, or Kaggle work — documents the autonoml.helpers API so the script doesn't have to introspect it. priority: 92 tool-prefixes: - code. triggers: - autonoml.helpers - profile - clean - feature engineering - baseline - workflow script - python script - run_dir - register_artifact tags: - code_first - helpers

Code-First Helpers

Use this skill whenever you plan to write Python files under scripts/ and run them with code.run. The autonoml.helpers package is the script-friendly API surface — it wraps the runtime's typed services so a script can call eda.summarize(df) or tabular.baseline_pipeline(df, target=...) instead of orchestrating tool calls.

Do not introspect the package via dir(), inspect, or one-off probe scripts. Every helper signature, return shape, and constraint is documented below. Trust the contract.

Contract

  • Use when authoring scripts under <run>/scripts/ and running them with code.run for profiling, cleaning, feature engineering, baselining, or any custom Python work that the typed tools don't cover directly.
  • Do not introspect the helper package at runtime. Do not run python -c, dir(ah), or write inspect_*.py probes — every signature and return field is documented here.
  • Do not call code.edit_file on a path that has not just been read with code.read_file (Read-before-Edit invariant).
  • Required inputs are the active run directory (autonoml.helpers.run_dir()), pandas DataFrames or pre-staged CSV/Parquet files, and an explicit target column for any modeling step.
  • Expected outputs are registered artifacts in the conventional dirs: data/processed/<name>_cleaned.csv (kind=data), models/<name>_baseline.joblib (kind=model), reports/<name>_*.md|csv (kind=report), metadata/<name>_*.json (kind=metadata) — each accompanied by register_artifact(...) so the runtime's scorecard and planner see them.
  • Common failures are: introspection storms eating the turn budget; cleaned-dataset paths the planner can't recognize (must contain one of clean, cleaned, prepared, processed, transformed, encoded, ml_ready); writing the same step under multiple script names instead of editing one; calling code.edit_file without a prior read on the same path.

The four code tools (quartet)

Tool Required arg Returns
code.read_file path: "scripts/foo.py" numbered lines plus content_hash (must read before edit)
code.edit_file path, old_string, new_string surgical replace; fails if not unique, unread, or stale
code.write_file path, content create-only; fails if path exists
code.run argv: ["python", "scripts/foo.py"] stdout/stderr; auto-registers files in data/, models/, reports/, metadata/, scripts/

argv for code.run is run-relative. The cwd is the active run directory, and the runtime rewrites python scripts/<name>.py to the active run's script path automatically.

autonoml.helpers API (authoritative)

paths

from autonoml.helpers import run_dir  # -> pathlib.Path of active run directory

Reads AUTONOML_RUN_DIR. Raises RuntimeError if unset.

registry

from autonoml.helpers import register_artifact, ArtifactRegistration

register_artifact(
    path,                                  # str | Path; absolute or run-relative
    kind=Literal["data","model","report","metadata","script","other"],
    metadata: dict | None = None,
    supersedes: str | None = None,
) -> ArtifactRegistration

Appends to <run>/.autonoml_artifact_registrations.jsonl. The runtime ingests this file after code.run exits. Explicit registrations override auto-registration kind/metadata for the same path. The file does not need to exist when you register — the runtime checks existence at ingest time.

dataframe

from autonoml.helpers import dataframe

dataframe.read(path, *, max_rows=None) -> pd.DataFrame
dataframe.profile(df) -> ProfileResult
    # ProfileResult: row_count, sampled_row_count, columns: dict[str, dict], warnings
dataframe.sample(df, n, *, stratify_by=None, random_state=42) -> pd.DataFrame
dataframe.validate(df, schema: dict[str, str]) -> ValidationResult
    # schema maps column -> dtype name; ValidationResult.valid: bool,
    # columns, missing_columns, extra_columns, dtype_mismatches
dataframe.transform(df, operations: list[TransformOp]) -> pd.DataFrame
    # ops: {"op":"drop_columns","columns":[...]}, {"op":"cast_dtype","columns": {"col": "dtype"}},
    #      {"op":"replace_values","column":...,"mapping":{...}},
    #      {"op":"filter_rows","column":...,"op_kind":"eq|ne|gt|lt|ge|le|isin|notin|isnull|notnull","value":...},
    #      {"op":"rename_columns","mapping":{old:new,...}}

Do not use nonexistent fields: ProfileResult.column_count, ProfileResult.duplicate_rows, ProfileResult.payload, ValidationResult.passed, or ValidationResult.issues.

eda

All functions take a pd.DataFrame (some take extra kwargs) and return a structured dataclass:

from autonoml.helpers import eda

eda.summarize(df, *, target_column=None) -> SummaryResult
eda.missingness(df) -> MissingnessResult
eda.leakage_check(df, *, target) -> LeakageResult
eda.target_associations(df, *, target, method="auto") -> AssociationsResult
eda.correlations(df, *, columns=None, method="pearson") -> CorrelationsResult
eda.grouped_stats(df, *, group_by, metrics) -> GroupedStatsResult
eda.compare_segments(df, *, group_by, metrics) -> GroupedStatsResult
eda.outliers(df, *, method="iqr", columns=None) -> OutliersResult
eda.statistical_test(df, *, test="auto", columns=None, target) -> TestResult

EDA results are dataclasses. They do not carry .payload. For JSON metadata, use:

from dataclasses import asdict
json.dumps(asdict(result), indent=2, default=str)

Do not pass top_k to target_associations or correlations; those helpers do not accept it. Common EDA fields:

  • MissingnessResult.columns: list of dicts with column, null_count, null_rate, non_null_count.
  • LeakageResult.findings: list of LeakageFinding(column, risk_level, reason, evidence).
  • AssociationsResult.associations: list of TargetAssociation(column, method, score, n, details).
  • CorrelationsResult.correlations: list of CorrelationPair(column_a, column_b, correlation, abs_correlation, method, n).

tabular

from autonoml.helpers import tabular

tabular.baseline_pipeline(
    df,
    *,
    target: str,
    lightweight: bool = True,    # True skips deep search / heavy SHAP
    cv_folds: int = 5,
    test_size: float = 0.2,
    random_state: int = 42,
) -> BaselineResult
    # BaselineResult fields:
    #   leaderboard: pd.DataFrame  (ranked candidates)
    #   best_model: Any            (fitted estimator, joblib-loaded)
    #   best_model_name: str
    #   best_model_family: str
    #   primary_metric_name: str   (e.g. "balanced_accuracy", "rmse")
    #   primary_metric_value: float
    #   predictions: pd.DataFrame | None
    #   feature_importance: pd.DataFrame | None
    #   config: dict[str, Any]
    #   warnings: list[str]

Does prepare + run inside a throwaway workspace; raises KeyError if target not in df.columns.

bigquery

from autonoml.helpers import bigquery

bigquery.client().query(
    sql: str,
    *,
    max_bytes_billed: int,        # MANDATORY (no default)
    destination: Path | None = None,
) -> pd.DataFrame

max_bytes_billed is fail-loud — a missing or zero value raises with the dry-run estimate in the error message so you can pick a real cap.

kaggle

from autonoml.helpers import kaggle

kaggle.check_setup() -> dict
kaggle.search_datasets(query, *, limit=20) -> list[KaggleDataset]
kaggle.list_dataset_files(handle) -> list[KaggleFile]
kaggle.download_dataset(
    handle: str,
    *,
    max_bytes: int,               # MANDATORY (no default)
    destination: Path | None = None,
    overwrite: bool = False,
) -> Path

Post-download size check with cleanup on overrun.

Read-before-Edit Invariant

code.edit_file rejects edits to a path you have not just read with code.read_file. The runtime tracks the path and full-file content hash. If a write or external change happens between the read and the edit, the edit fails; read again before editing. This mirrors Claude Code's edit contract and prevents whole-file rewrites disguised as edits.

Standard Workflow Pattern

For a typical "load → profile → clean → baseline → report" cycle, the agent writes one script per step and runs it with code.run. Each script ends by calling register_artifact(...) for every output that should show up in the run's artifact list.

# scripts/profile_<dataset>.py
from dataclasses import asdict
from pathlib import Path
import pandas as pd
from autonoml.helpers import run_dir, register_artifact, dataframe, eda

df = pd.read_csv(run_dir() / "data" / "raw" / "<file>.csv")
summary = eda.summarize(df, target_column="<target>")

report_path = run_dir() / "reports" / "<dataset>_profile.md"
report_path.parent.mkdir(parents=True, exist_ok=True)
report_path.write_text("# Profile\n\n" + str(summary))
register_artifact(report_path, kind="report",
                  metadata={"section": "profile"})

profile_json = run_dir() / "metadata" / "<dataset>_profile.json"
profile_json.parent.mkdir(parents=True, exist_ok=True)
profile_json.write_text(__import__("json").dumps({
    "profile": asdict(dataframe.profile(df)),
    "summary": asdict(summary),
}, indent=2, default=str))
register_artifact(profile_json, kind="metadata")

Hard Rules

  • Do not run ad-hoc python -c "..." to introspect helpers. The API above is the contract.
  • Do not write probe scripts (inspect_helpers.py, inspect_*_fields.py, …) — every signature is in this skill.
  • Do not use code.edit_file without a prior code.read_file on the same path.
  • Do not invent helper functions. If you need behaviour outside this surface, write it inline with pandas / numpy directly in your script.
  • Do not skip register_artifact for outputs that must appear in the run's artifact list (cleaned datasets, models, reports, metrics JSON). The auto-registration covers basic files in conventional dirs but loses the metadata={"section": ...} hints the scorecard uses.
  • Do not name a cleaned dataset something the planner won't recognize. Use a path containing one of: clean, cleaned, prepared, processed, transformed, encoded, ml_ready.
  • Do not write multiple scripts that do the same step. One profile script, one clean script, one baseline script — replace via code.edit_file, not re-create with a new name.

When NOT to Use This Skill

  • For pure typed-tool work (dataframe.profile_file, tabular.run_experiment, bigquery.query_to_file), use the corresponding skill. The code-first surface is for cases the typed tools don't cover or when you specifically want script-level control.
  • For BigQuery or Kaggle source acquisition, prefer the dedicated skills' warehouse/dataset workflows first; drop into this skill only when you need post-fetch custom processing.

References

  • references/quickstart.md — three minimal end-to-end script patterns (profile, clean, baseline). This is an optional prompt reference, not a run-workspace file; do not call code.read_file on it.
Install via CLI
npx skills add https://github.com/whanyu1212/autonoml --skill code-first-helpers
Repository Details
star Stars 0
call_split Forks 0
navigation Branch main
article Path SKILL.md
More from Creator