Everything the CLI does is also available as a Python API, for scripting runs or embedding LeWRON in another framework.
from lewron import (
run_pipeline,
run_stage,
revise_stage,
reset_stage,
reset_substep,
regenerate_report,
run_explorer,
install_claude_skill,
uninstall_claude_skill,
)These names are LeWRON's stable public surface.
Every function accepts an optional models= argument (a ModelConfig) and, where a checkpoint can fire, an optional checkpoint_handler= (a CheckpointHandler).
run_pipeline(
input_file: str | Path,
run_dir: str | Path | None = None,
checkpoint_handler: CheckpointHandler | None = None,
models: ModelConfig | None = None,
) -> NoneRuns the full toolbox pipeline. input_file may be a path to an input file or an inline prompt string. Bootstrap infers the mode, the build preset, and the project id from the input; run_dir defaults to a directory named after the model. When the build includes thermal analysis, the Explorer runs automatically at the end.
Returns None — results are written to state.json and artifacts/ in run_dir, which you then read.
run_pipeline("examples/ALP.md", run_dir="examples/alp")run_stage(
stage: str,
run_dir: str | Path,
checkpoint_handler: CheckpointHandler | None = None,
models: ModelConfig | None = None,
) -> AnyRuns a single toolbox stage in an existing run directory, and returns that stage's Pydantic artifact model. Requires state.json and all prior stages to already be in place. Raises KeyError for an unknown stage key and FileNotFoundError if state.json is missing.
artifact = run_stage("1b", run_dir="examples/alp")revise_stage(
stage: str,
run_dir: str | Path,
feedback: str,
*,
run: bool = False,
checkpoint_handler: CheckpointHandler | None = None,
models: ModelConfig | None = None,
) -> NoneResets stage and downstream stages, then attaches feedback. With run=False (the default) it only queues the feedback for the next resume; with run=True it immediately resumes the pipeline from the reset stage. Tree-level feedback is scoped automatically to the targeted part of the derivation plus its dependents. Raises KeyError for an unknown or non-revisable stage.
revise_stage("1b", "examples/alp", "Use the paper's Higgs-basis convention.", run=True)reset_stage(
stage: str,
run_dir: str | Path,
) -> NoneThe programmatic, non-interactive twin of the lewron reset command: resets stage and every downstream stage — restoring artifacts to a consistent pre-stage state, clearing the affected model_spec.json fields and the conventions the stage set, and rewinding the last-completed marker. Bootstrap ("0") is not resettable. Unlike the CLI command it never prompts for confirmation, so use revise_stage instead when you also want to queue feedback.
reset_stage("2a", "examples/alp")reset_substep(
substep: str,
run_dir: str | Path,
) -> list[str]Resets one Stage 1b substep and every later substep: deletes their sidecars, the compute JSON, and the assembled SymPy script, then rewinds the generation progress to the chunks before substep. Returns the run-relative paths of the files it changed. This is a testing / scripted-re-derivation entry point with no CLI command — the user-facing reset granularity is the whole stage. Raises KeyError for an unknown substep name.
changed = reset_substep("scalar_spectrum", "examples/alp")regenerate_report(
stage: str | None = None,
run_dir: str | Path = ".",
models: ModelConfig | None = None,
) -> NoneRewrites notes/report.md from the current artifacts without rerunning any stage — the recovery path for an interrupted report write. stage defaults to the run's last completed stage. Raises FileNotFoundError if state.json is missing and KeyError if there is no completed stage to report on.
run_explorer(
run_dir: str | Path,
checkpoint_handler: CheckpointHandler | None = None,
models: ModelConfig | None = None,
) -> NoneOpens the Explorer on an existing run whose toolbox stages are complete. Raises FileNotFoundError if run_dir/state.json is absent. (The Explorer is a free-form conversation, so checkpoint_handler is accepted only for interface symmetry and is not used.)
install_claude_skill() -> Path
uninstall_claude_skill() -> Path | NoneInstall or remove the physics priors as a global lewron-physics Claude Code skill under ~/.claude/skills/, the programmatic twin of lewron install-skill. install_claude_skill builds the skill from your effective experience library and returns its directory (re-run to refresh after editing priors). uninstall_claude_skill removes it and returns the removed path, or None if it was not installed. See Installation → Customize the physics priors.
from lewron.llm import ModelConfig
ModelConfig(
reasoning: str = "claude-sonnet-4-6",
coding: str = "claude-sonnet-4-6",
thinking_budget: int | None = None,
)Selects the model for each role in a run, and is also the record (in state.json) of which models a run used. Pass it to any pipeline function:
from lewron import run_pipeline
from lewron.llm import ModelConfig
run_pipeline(
"examples/Z2ssb.md",
run_dir="examples/z2ssb",
models=ModelConfig(reasoning="claude-opus-4-8", coding="claude-sonnet-4-6"),
)There are two roles. reasoning covers the auditor, physics reasoning, the report writer, and bootstrap intake. coding covers code generation. Both default to Sonnet. Per-run selection is the public API; per-step overrides exist internally via lewron.llm.create_message(model=...).
A checkpoint is a human-approval gate the orchestrator runs after a stage in discovery mode. A CheckpointHandler routes that request to a human (or to any surface you like) and returns their response. The protocol is one method:
class CheckpointHandler(Protocol):
def request(self, stage: str, field: str, run_dir: Path) -> str: ...The return value follows a uniform convention: an empty (or whitespace-only) string means confirm the proposal; any other text is free-form conversation that the orchestrator interprets (accept / discuss / revise / reaudit).
Three implementations ship in lewron.io:
| Handler | Construct with | Use |
|---|---|---|
StdinHandler |
StdinHandler() |
Interactive terminal — the CLI default. Renders a framed prompt and reads one line of stdin. |
ScriptedHandler |
ScriptedHandler(responses: list[str]) |
Tests. Replays a fixed list of responses; an exhausted queue returns "" (confirm). |
CallbackHandler |
CallbackHandler(fn) |
Embedding. Wraps any fn(stage, field, run_dir) -> str so checkpoints can be routed to a GUI, Slack, another LLM, etc. |
Example — route checkpoints through your own function:
from lewron import run_pipeline
from lewron.io import CallbackHandler
def my_router(stage: str, field: str, run_dir) -> str:
# Return "" to accept, or any text to steer.
return ""
run_pipeline("examples/ALP.md", run_dir="examples/alp",
checkpoint_handler=CallbackHandler(my_router))Imported from lewron.exceptions:
| Exception | Raised when |
|---|---|
PhysicsFailure |
A stage ran but produced a physics or numerical problem after its retry budget. Carries .substep (the Stage 1b substep that failed, when known). |
MechanicalRepairExhausted |
(subclass of PhysicsFailure) Generated code kept failing to even execute (SyntaxError, NameError, …) after the self-repair loop. Carries .history of the failure signatures seen. |
AuditFailure |
The auditor returned a non-continuable verdict — it escalated, or the regeneration budget was exhausted without reaching ok. |
from lewron import run_pipeline
from lewron.exceptions import PhysicsFailure, AuditFailure
try:
run_pipeline("examples/ALP.md", run_dir="examples/alp")
except (PhysicsFailure, AuditFailure) as exc:
print("Run needs attention:", exc)