How to Use the Generation Status API for Tracking CAD Artifact Creation in Text-to-CAD
The generation status API provides a lightweight, file-based mechanism for monitoring long-running CAD generation steps through JSON lock files that update every second during active processing.
The earthtojake/text-to-cad repository implements a robust generation status API in packages/cadpy/src/cadpy/generation_status.py to track the creation of CAD artifacts without requiring a central service. This side-effect-free system uses atomic file operations to report progress on conversions like STEP to GLB or mesh sampling, enabling downstream tools to monitor pipeline status in real-time.
Core Architecture of the Generation Status API
The API centers on two primary components: the GenerationOutput dataclass and the track_generation_run context manager.
GenerationOutput Dataclass
Defined at lines 21-25 in generation_status.py, the GenerationOutput dataclass encapsulates a single output artifact with its path and kind:
@dataclass
class GenerationOutput:
path: Path
kind: str # e.g., "step", "glb"
track_generation_run Context Manager
The track_generation_run function (lines 32-45) returns a context manager that initializes the tracking infrastructure. When entered, it instantiates _GenerationStatusTracker and invokes its run() method (lines 74-89) to handle nesting, start the heartbeat thread, and guarantee cleanup upon exit.
Lock File Mechanism and Heartbeat System
The generation status API creates hidden lock files alongside each declared output to communicate runtime state.
Atomic File Writing
The _write_status function (lines 14-28) serializes a JSON payload containing the schema version, run ID, PID, timestamps, generator name, source path, and output list. It writes to a temporary file first, then atomically renames it to the final lock file path to prevent corruption during concurrent access.
File Naming Convention
Lock files follow the pattern .{output_name}.{run_id}.generation.lock.json and reside in the same directory as their associated outputs. For example, generating models/part.step creates .part.step.12345-abcdef.generation.lock.json.
Heartbeat Interval
A background thread calls _write_status every _HEARTBEAT_INTERVAL_SEC (defaulting to 1 second) to refresh the updatedAt timestamp. This heartbeat signals that the generation process remains active.
Practical Implementation Examples
Tracking a Single CAD Output
from pathlib import Path
from cadpy.generation_status import GenerationOutput, track_generation_run
source = Path("models/part.py")
step = Path("models/part.step")
with track_generation_run(
source_path=source,
generator="gen_step",
outputs=[GenerationOutput(step, "step")],
repo_root=Path.cwd(),
):
# Long-running STEP generation logic here
generate_step_file(source, step)
Monitoring Multiple Artifacts
from pathlib import Path
from cadpy.generation_status import GenerationOutput, track_generation_run
step = Path("models/part.step")
glb = Path("models/part.glb")
with track_generation_run(
source_path=None,
generator="step_to_glb",
outputs=[
GenerationOutput(step, "step"),
GenerationOutput(glb, "glb"),
],
):
convert_step_to_glb(step, glb)
Inspecting Lock File Contents
During active generation, the lock file contains:
{
"schemaVersion": 1,
"id": "12345-abcdef...",
"status": "running",
"pid": 5678,
"startedAt": "2026-08-01T12:34:56Z",
"updatedAt": "2026-08-01T12:34:57Z",
"sourcePath": "models/part.py",
"generator": "gen_step",
"outputs": [
{ "path": "models/part.step", "kind": "step" }
]
}
Cleanup and Failure Handling
When the context manager exits successfully, the tracker removes all lock files. If removal fails due to race conditions or permissions, it writes a final payload with "status": "finished" before terminating. This ensures that downstream tooling can always discover the final state, even when file system operations encounter errors.
Integration Across the Codebase
The generation status API appears in several locations within the repository:
packages/cadpy/src/cadpy/generation_status.py- Core implementation containingtrack_generation_runand_GenerationStatusTrackertests/python/packages/cadpy/test_generation_status.py- Unit tests demonstrating heartbeat and cleanup behaviorviewer/packages/cadpy/src/cadpy/generation.py- High-level pipeline integrationskills/*/scripts/*/generation_status.py- Symlinked copies for individual skill runtimes
Summary
- The generation status API in
cadpy/generation_status.pyprovides file-based progress tracking without central services. - The
track_generation_runcontext manager creates JSON lock files that update every second via a background heartbeat thread. - Lock files use atomic writes and follow the naming convention
.{output_name}.{run_id}.generation.lock.json. - The system gracefully handles failures by writing a final "finished" status if lock file removal fails.
- Multiple outputs can be tracked simultaneously using the
GenerationOutputdataclass.
Frequently Asked Questions
Where is the generation status API implemented?
The generation status API is implemented in packages/cadpy/src/cadpy/generation_status.py within the earthtojake/text-to-cad repository. This module contains the track_generation_run context manager, GenerationOutput dataclass, and the internal _GenerationStatusTracker class that manages the heartbeat mechanism.
How does the heartbeat mechanism work?
The heartbeat mechanism runs in a background thread started by _GenerationStatusTracker.run(). It calls _write_status every _HEARTBEAT_INTERVAL_SEC (default 1 second) to update the updatedAt timestamp in the JSON lock file. This allows external monitoring tools to verify that the generation process is still active and has not stalled or crashed.
What happens if the generation process crashes?
If the process crashes or is killed, the heartbeat thread terminates and the lock file remains on disk with its last updated timestamp. Downstream tools can detect this by comparing the updatedAt field against the current time. If the difference exceeds the expected heartbeat interval, the generation is likely dead. The file will not be automatically cleaned up, providing forensic evidence of the failure point.
Can I track multiple CAD outputs simultaneously?
Yes. Pass a list of GenerationOutput objects to the outputs parameter of track_generation_run. The API creates separate lock files for each output following the pattern .{output_name}.{run_id}.generation.lock.json. This allows independent monitoring of each artifact's generation status, useful for complex pipelines producing STEP files, GLB conversions, and mesh samples from a single source.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →