> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cirron.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Template generation

> How the CLI generates template code, and authoring custom templates.

# Template Generation System

The Cirron CLI uses a modular template generation system that produces framework-specific project code based on your chosen template and model type. This page covers how the system works internally and how to extend it. For per-framework details, see [PyTorch](/cli/templates/pytorch), [TensorFlow](/cli/templates/tensorflow), and [scikit-learn](/cli/templates/sklearn).

## Available templates

| Template           | Description                  |
| ------------------ | ---------------------------- |
| `pytorch`          | PyTorch inference            |
| `pytorch-train`    | PyTorch training pipeline    |
| `tensorflow`       | TensorFlow inference         |
| `tensorflow-train` | TensorFlow training pipeline |
| `sklearn`          | Basic scikit-learn model     |
| `sklearn-pipeline` | Full scikit-learn pipeline   |
| `custom`           | Blank Python project         |

```bash theme={null}
cirron init my-project --template pytorch
```

The model type (classification, regression, computer vision) is selected interactively after the template choice.

## How generation works

When you run `cirron init`, the CLI:

1. Selects the template you specified.
2. Calls `createCommonMLFiles()` to write the shared scaffolding (Dockerfile, requirements.txt, README, `cirron.yaml`, tests, `.gitignore`, `.env.example`). See [Common files](/cli/templates/common).
3. Calls the framework-specific generator (e.g. `createPyTorchFiles()`) to write `src/model.py`, `src/data_loader.py`, `src/inference.py`, and, for `*-train` templates, `src/train.py`.
4. Resolves the model architecture and data loader bodies via two helpers:
   * `getModelCode(framework, modelType)`: returns the source for `src/model.py`.
   * `getDataLoaderCode(framework, modelType)`: returns the source for `src/data_loader.py`.
5. Writes everything to disk and prints next steps.

## File layout in the CLI source

Template generation lives under `src/commands/files/` in the CLI repo:

```
src/commands/files/
├── common.ts              # createCommonMLFiles()
├── pytorch.ts             # createPyTorchFiles, createPyTorchTrainingFiles
├── tensorflow.ts          # createTensorFlowFiles, createTensorFlowTrainingFiles
├── sklearn.ts             # createSklearnFiles, createSklearnPipelineFiles
├── data.ts                # getDataLoaderCode()
└── model.ts               # getModelCode()
```

Each generator is a pure function: `(projectPath, projectName, options) => Promise<void>`. They write files to disk and return nothing, making them easy to test and compose.

## Model types

`getModelCode()` and `getDataLoaderCode()` switch on `modelType`:

* **`classification`**: Cross-entropy loss, softmax output. PyTorch/TensorFlow generate a small MLP or CNN; sklearn uses `RandomForestClassifier`.
* **`regression`**: MSE loss, linear output. PyTorch/TensorFlow generate an MLP; sklearn uses `RandomForestRegressor`.
* **`computer_vision`**: Conv-based architecture (PyTorch `nn.Conv2d` stack, TensorFlow `Conv2D` stack).
* **`custom`**: Skipped; you write `src/model.py` yourself.

## Extending the system

### Adding a new model type

1. Add a branch in `getModelCode()`:

```typescript theme={null}
export function getPyTorchModelCode(modelType: string): string {
  if (modelType === 'nlp') {
    return generateNLPModel();
  }
  // ... existing branches
}
```

2. Add the matching branch in `getDataLoaderCode()`.
3. Add the model type to the interactive prompt list in `src/commands/init.ts`.

### Adding a new framework

1. Create `src/commands/files/<framework>.ts` exporting a `create<Framework>Files()` function.
2. Add framework-specific branches in `getModelCode()` and `getDataLoaderCode()`.
3. Register the template name(s) in the `init` command's template registry.
4. Add a docs page under `apps/docs/cli/templates/`.

## Generation entry point

The high-level call looks like:

```typescript theme={null}
await createCommonMLFiles(projectPath, projectName, options);

if (template === 'pytorch-train') {
  await createPyTorchTrainingFiles(projectPath, projectName, options);
} else if (template === 'pytorch') {
  await createPyTorchFiles(projectPath, projectName, options);
}
// ... etc.
```

## Best practices for authoring templates

* **Match the runtime contract**: generated `src/inference.py` must expose a `ModelInference` class with `predict(input)`. The Cirron runtime imports it by name.
* **Wire the SDK**: generated training and inference code should import `cirron as ci` and call `ci.profile()` once at module top so traces flow to `cirron traces`. Use `ci.scope("name")` for explicit regions and `ci.wrap(estimator)` for scikit-learn models.
* **Provide sensible defaults**: model hyperparameters, batch size, learning rate should work on the bundled sample data without tweaking.
* **Fail soft on missing data**: fall back to `data/sample/sample_data.csv` if the user's data path is empty.
* **Pin loose dependency versions**: `>=X.Y.0` for the framework, exact for security-sensitive libs.

## Next Steps

<CardGroup cols={2}>
  <Card title="PyTorch Template" href="/cli/templates/pytorch">
    Deep learning with PyTorch
  </Card>

  <Card title="TensorFlow Template" href="/cli/templates/tensorflow">
    Deep learning with TensorFlow
  </Card>

  <Card title="scikit-learn Template" href="/cli/templates/sklearn">
    Traditional ML algorithms
  </Card>

  <Card title="Common files" href="/cli/templates/common">
    Shared scaffolding for every template
  </Card>
</CardGroup>
