Skip to content

Reproducible export

Any session exports to a self-contained .ipynb whose cells run in a plain Jupyter kernel — with no HelioAI installed, no agent, and no sandbox.

helioai export           # most recent session
helioai export a3f9      # by session id prefix
%helioai_export          # in Jupyter

What gets rewritten, and why

The code the agent runs is not the code you want to keep. Inside the sandbox it uses helpers that only exist there, so a raw dump would be a notebook that cannot run. The export rewrites the boundary:

Sandbox Exported
load_data('bz') fetch_series('amda/imf_bz', '2005-01-16', '2005-01-18')
load_data('bz_events') fetch_events(id, [[s1,e1], [s2,e2], ...]) over the OK events
export('name', arr, units=) print(...) of the same summary, dicts summarised key by key
clean(arr), magnitude(v), interp_to(...) the same helpers, inlined
param_card(...), document_method(...) stripped — agent-only UI helpers

fetch_series and fetch_events wrap spz.get_data rather than being it. Inside the session, get_timeseries blanked the dataset's declared FILLVAL to NaN before the sandbox ever saw the array. A bare spz.get_data() hands the raw sentinel — 99999.9 for Wind/SWE — to the very same arithmetic: the same code gave a mean of 5.0 in the session and 50002 exported, with no error either way. The wrappers redo that blanking and mirror the attributes load_data exposed (.units, .param_id, .missing_pct).

The rewrite is possible because datastore.py records the param_id, start and stop behind every dataset key in a manifest, so a load_data call can be turned back into the speasy call that produced it. Imports are added at the top, and anything the export cannot resolve is left untouched rather than guessed at.

This came out of the first external demo. The reviewer's objection was blunt and correct: the code shown was not code he could take away and re-run. Rewriting the boundary was the answer.

What the notebook contains

  1. Setup — imports and any shims still required.
  2. One cell per analysis step, in order, as standalone code. A step that ran a shipped recipe through run_recipe is exported as its own lines only — the input bindings and the call — and the recipe's source sits once, in a collapsed cell just before its first use, with a line saying whether it is identical to the recipe shipped with the helioai installed now (sha256 of the text as it ran). run_recipe(name, inputs, call) in the setup cell executes that source the way the sandbox did, on a copy of the notebook's namespace with __name__ set so a recipe's demo stays off. A session that ran superposed_epoch five times used to export the same 385 lines five times; it now exports them once, and each run is a dozen lines.
  3. Methods & data acknowledgements — every recipe and reference used, assembled by scanning the session's tool calls and the sub-agents' results, plus the data-provider acknowledgements.
  4. Attempts that did not run — scripts the session reported as failed, kept as fenced prose rather than executable cells. code_N.py is written before it runs, so a raised attempt exported as a cell used to stop Run All before its fix.

Verifying it really runs

The claim is only worth something if it is checked. The repository ships verify_export.sh, which copies a notebook into a temporary directory without the data/ tree and executes it with nbconvert:

uv pip install nbconvert ipykernel
./verify_export.sh path/to/session.ipynb

Running it outside the repo is the whole point — it proves the notebook depends on speasy and public data, not on your local workspace.

Getting the code without leaving the session

The web UI's code panel shows the same standalone rewrite for each step, and the /code endpoint returns it directly. You do not have to export the whole session just to copy one analysis.

Why this matters beyond convenience

An agent that produces a number and a plot is a black box you have to trust. An agent that produces the script, the method citation and a runnable notebook is a tool a reviewer can check. That is the difference this project is built around — see Recipes and provenance for the other half.